foamlib 0.6.14__py3-none-any.whl → 0.6.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
foamlib/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """A Python interface for interacting with OpenFOAM."""
2
2
 
3
- __version__ = "0.6.14"
3
+ __version__ = "0.6.15"
4
4
 
5
5
  from ._cases import (
6
6
  AsyncFoamCase,
foamlib/_files/_files.py CHANGED
@@ -189,6 +189,10 @@ class FoamFile(
189
189
  elif not isinstance(keywords, tuple):
190
190
  keywords = (keywords,)
191
191
 
192
+ if keywords and not isinstance(normalize(keywords[-1], kind=Kind.KEYWORD), str):
193
+ msg = f"Invalid keyword: {keywords[-1]}"
194
+ raise ValueError(msg)
195
+
192
196
  with self:
193
197
  try:
194
198
  write_header = (
@@ -293,7 +297,7 @@ class FoamFile(
293
297
  ...,
294
298
  before
295
299
  + indentation
296
- + dumps(keywords[-1])
300
+ + dumps(keywords[-1], kind=Kind.KEYWORD)
297
301
  + b"\n"
298
302
  + indentation
299
303
  + b"{\n"
@@ -311,7 +315,7 @@ class FoamFile(
311
315
  normalize(data, kind=kind),
312
316
  before
313
317
  + indentation
314
- + dumps(keywords[-1])
318
+ + dumps(keywords[-1], kind=Kind.KEYWORD)
315
319
  + b" "
316
320
  + dumps(data, kind=kind)
317
321
  + b";"
@@ -26,6 +26,7 @@ except ModuleNotFoundError:
26
26
 
27
27
  class Kind(Enum):
28
28
  DEFAULT = auto()
29
+ KEYWORD = auto()
29
30
  SINGLE_ENTRY = auto()
30
31
  ASCII_FIELD = auto()
31
32
  DOUBLE_PRECISION_BINARY_FIELD = auto()
@@ -56,11 +57,6 @@ def normalize(
56
57
  assert isinstance(ret, list)
57
58
  return ret
58
59
 
59
- if kind == Kind.SINGLE_ENTRY and isinstance(data, tuple):
60
- ret = normalize(list(data))
61
- assert isinstance(ret, list)
62
- return ret
63
-
64
60
  if isinstance(data, Mapping):
65
61
  return {k: normalize(v, kind=kind) for k, v in data.items()}
66
62
 
@@ -73,22 +69,43 @@ def normalize(
73
69
  data = cast(Sequence[float], data)
74
70
  return FoamFileBase.DimensionSet(*data)
75
71
 
76
- if is_sequence(data) and not isinstance(data, tuple):
72
+ if is_sequence(data) and (kind == Kind.SINGLE_ENTRY or not isinstance(data, tuple)):
77
73
  return [normalize(d, kind=Kind.SINGLE_ENTRY) for d in data]
78
74
 
79
75
  if isinstance(data, str):
76
+ data = data.strip()
77
+
78
+ if data.startswith("(") and data.endswith(")"):
79
+ data = data[1:-1].split()
80
+ if kind == Kind.KEYWORD:
81
+ return "(" + " ".join(data) + ")"
82
+ return [normalize(d, kind=Kind.SINGLE_ENTRY) for d in data]
83
+
84
+ if data.startswith("[") and data.endswith("]"):
85
+ data = data[1:-1].split()
86
+ return normalize(data, kind=Kind.DIMENSIONS)
87
+
80
88
  with contextlib.suppress(ValueError):
81
89
  return int(data)
82
90
 
83
91
  with contextlib.suppress(ValueError):
84
92
  return float(data)
85
93
 
94
+ if kind != Kind.KEYWORD:
95
+ if data in ("yes", "true", "on", "y", "t"):
96
+ return True
97
+ if data in ("no", "false", "off", "n", "f"):
98
+ return False
99
+
86
100
  tokens: list[str] = re.findall(_TOKENS, data)
87
101
 
88
102
  if len(tokens) == 1:
89
103
  return tokens[0]
90
104
 
91
- return tuple(tokens) if kind != Kind.SINGLE_ENTRY else " ".join(tokens)
105
+ if kind == Kind.KEYWORD:
106
+ return " ".join(tokens)
107
+
108
+ return tuple(tokens)
92
109
 
93
110
  if isinstance(data, FoamFileBase.Dimensioned):
94
111
  value = normalize(data.value, kind=Kind.SINGLE_ENTRY)
@@ -115,12 +132,15 @@ def dumps(
115
132
  if isinstance(data, Mapping):
116
133
  entries = []
117
134
  for k, v in data.items():
118
- if isinstance(v, Mapping):
119
- entries.append(dumps(k) + b" {" + dumps(v) + b"}")
120
- elif not v:
121
- entries.append(dumps(k) + b";")
135
+ value = normalize(v)
136
+ if isinstance(value, Mapping):
137
+ entries.append(
138
+ dumps(k, kind=Kind.KEYWORD) + b" {" + dumps(value) + b"}"
139
+ )
140
+ elif not value:
141
+ entries.append(dumps(k, kind=Kind.KEYWORD) + b";")
122
142
  else:
123
- entries.append(dumps(k) + b" " + dumps(v) + b";")
143
+ entries.append(dumps(k, kind=Kind.KEYWORD) + b" " + dumps(value) + b";")
124
144
 
125
145
  return b" ".join(entries)
126
146
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foamlib
3
- Version: 0.6.14
3
+ Version: 0.6.15
4
4
  Summary: A Python interface for interacting with OpenFOAM
5
5
  Author-email: "Gabriel S. Gerlero" <ggerlero@cimec.unl.edu.ar>
6
6
  Project-URL: Homepage, https://github.com/gerlero/foamlib
@@ -169,21 +169,20 @@ U = FoamFieldFile(Path(my_pitz) / "0/U")
169
169
  print(U.internal_field)
170
170
  ```
171
171
 
172
- ### 🔁 Run an optimization loop in parallel
172
+ ### 🔁 Run an optimization loop on a Slurm-based cluster
173
173
 
174
174
  ```python
175
175
  import os
176
176
  from pathlib import Path
177
- from foamlib import AsyncFoamCase
177
+ from foamlib import AsyncSlurmFoamCase
178
178
  from scipy.optimize import differential_evolution
179
179
 
180
- base = AsyncFoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")
181
- # Replace with `AsyncSlurmFoamCase` if on a cluster and you want cases to be run as Slurm jobs
180
+ base = AsyncSlurmFoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")
182
181
 
183
182
  async def cost(x):
184
183
  async with base.clone() as clone:
185
184
  clone[0]["U"].boundary_field["inlet"].value = [x[0], 0, 0]
186
- await clone.run()
185
+ await clone.run(fallback=True) # Run locally if Slurm is not available
187
186
  return abs(clone[-1]["U"].internal_field[0][0])
188
187
 
189
188
  result = differential_evolution(cost, bounds=[(-1, 1)], workers=AsyncFoamCase.map, polish=False)
@@ -1,4 +1,4 @@
1
- foamlib/__init__.py,sha256=2TB7NPVimWOf7GSEz5g_Gbguf3RJvD-eOWA0ykCCwLM,487
1
+ foamlib/__init__.py,sha256=xxPlBXMsaxIeBwjjYk7kczK-LfoxBgDNnCG96cQcYss,487
2
2
  foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  foamlib/_cases/__init__.py,sha256=wTUHcUgU1CBgpu0cUMtksQ5VKG6B8CFu9xc3dWwsQuo,358
4
4
  foamlib/_cases/_async.py,sha256=i6g4EBHqvI-1PkdrxsRto2ynW7sxsOga2bSYk1XVG1U,7795
@@ -10,13 +10,13 @@ foamlib/_cases/_sync.py,sha256=2BJXB7Nzldb4OgPukqupgYqdceUGkI2mYhhtGPWEBrc,5901
10
10
  foamlib/_cases/_util.py,sha256=lhVca3ERY0zwYjDam6W2QMROt0yX5vAF-9_DS5RuMbM,1547
11
11
  foamlib/_files/__init__.py,sha256=-UqB9YTH6mrJfXCX00kPTAAY20XG64u1MGPw_1ewLVs,148
12
12
  foamlib/_files/_base.py,sha256=ZY_6Zxr3LZHVzJEex6SUTi9Pgo7Oi7i3Jo-wre9G3yE,1968
13
- foamlib/_files/_files.py,sha256=oYRlMfCUH9oNeu-yf2HAPmLxLHteIe7gHhsWXdn7wU0,15767
13
+ foamlib/_files/_files.py,sha256=5BUOHGDPaa4naNVQtpnDyhDzjY6s4Pg726DQOFNuHjs,15982
14
14
  foamlib/_files/_io.py,sha256=IQLqoqnA1TpHf21NbUho2wsYWevyqC6MKo-wfpaObUU,2226
15
15
  foamlib/_files/_parsing.py,sha256=sJ7XadWFqmJTaL9TEYyaYEu3r-CQweruwPUNWIZt4i0,14165
16
- foamlib/_files/_serialization.py,sha256=p2yRpyyOAOKP7P6T7BLEgRVvORuzQEcv_P6dEsOZ9_8,5981
16
+ foamlib/_files/_serialization.py,sha256=vfvSZqg0QTaoTJlZ9NacQ2HqmjaMGdtoUPZvsgMt14o,6680
17
17
  foamlib/_files/_util.py,sha256=VXUTD0B3NbnlaE_KCqWzrFcWvBz_2JfnIWpNp3snX3Y,526
18
- foamlib-0.6.14.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
- foamlib-0.6.14.dist-info/METADATA,sha256=Um-3D8v1EnQPeX-pAySWkM-SWVBgTPIiLgKd4Ewq3RY,7742
20
- foamlib-0.6.14.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
21
- foamlib-0.6.14.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
- foamlib-0.6.14.dist-info/RECORD,,
18
+ foamlib-0.6.15.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
+ foamlib-0.6.15.dist-info/METADATA,sha256=eKZCMgAleMnArxpnqxN1eoepxqjBvA9yBhl1SBM8vE4,7723
20
+ foamlib-0.6.15.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
21
+ foamlib-0.6.15.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
+ foamlib-0.6.15.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5