foamlib 0.6.14__tar.gz → 0.6.15__tar.gz

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.
Files changed (27) hide show
  1. {foamlib-0.6.14 → foamlib-0.6.15}/PKG-INFO +5 -6
  2. {foamlib-0.6.14 → foamlib-0.6.15}/README.md +4 -5
  3. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/__init__.py +1 -1
  4. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/_files.py +6 -2
  5. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/_serialization.py +32 -12
  6. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib.egg-info/PKG-INFO +5 -6
  7. {foamlib-0.6.14 → foamlib-0.6.15}/LICENSE.txt +0 -0
  8. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/__init__.py +0 -0
  9. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_async.py +0 -0
  10. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_base.py +0 -0
  11. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_run.py +0 -0
  12. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_slurm.py +0 -0
  13. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_subprocess.py +0 -0
  14. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_sync.py +0 -0
  15. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_cases/_util.py +0 -0
  16. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/__init__.py +0 -0
  17. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/_base.py +0 -0
  18. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/_io.py +0 -0
  19. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/_parsing.py +0 -0
  20. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/_files/_util.py +0 -0
  21. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib/py.typed +0 -0
  22. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib.egg-info/SOURCES.txt +0 -0
  23. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib.egg-info/dependency_links.txt +0 -0
  24. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib.egg-info/requires.txt +0 -0
  25. {foamlib-0.6.14 → foamlib-0.6.15}/foamlib.egg-info/top_level.txt +0 -0
  26. {foamlib-0.6.14 → foamlib-0.6.15}/pyproject.toml +0 -0
  27. {foamlib-0.6.14 → foamlib-0.6.15}/setup.cfg +0 -0
@@ -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)
@@ -114,21 +114,20 @@ U = FoamFieldFile(Path(my_pitz) / "0/U")
114
114
  print(U.internal_field)
115
115
  ```
116
116
 
117
- ### 🔁 Run an optimization loop in parallel
117
+ ### 🔁 Run an optimization loop on a Slurm-based cluster
118
118
 
119
119
  ```python
120
120
  import os
121
121
  from pathlib import Path
122
- from foamlib import AsyncFoamCase
122
+ from foamlib import AsyncSlurmFoamCase
123
123
  from scipy.optimize import differential_evolution
124
124
 
125
- base = AsyncFoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")
126
- # Replace with `AsyncSlurmFoamCase` if on a cluster and you want cases to be run as Slurm jobs
125
+ base = AsyncSlurmFoamCase(Path(os.environ["FOAM_TUTORIALS"]) / "incompressible/simpleFoam/pitzDaily")
127
126
 
128
127
  async def cost(x):
129
128
  async with base.clone() as clone:
130
129
  clone[0]["U"].boundary_field["inlet"].value = [x[0], 0, 0]
131
- await clone.run()
130
+ await clone.run(fallback=True) # Run locally if Slurm is not available
132
131
  return abs(clone[-1]["U"].internal_field[0][0])
133
132
 
134
133
  result = differential_evolution(cost, bounds=[(-1, 1)], workers=AsyncFoamCase.map, polish=False)
@@ -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,
@@ -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)
File without changes
File without changes
File without changes
File without changes
File without changes