foamlib 0.6.2__py3-none-any.whl → 0.6.4__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 +8 -4
- foamlib/_cases/__init__.py +6 -2
- foamlib/_cases/_async.py +46 -8
- foamlib/_cases/_base.py +5 -1
- foamlib/_cases/_run.py +58 -4
- foamlib/_cases/_slurm.py +69 -0
- foamlib/_cases/_sync.py +51 -19
- foamlib/_files/_io.py +2 -1
- {foamlib-0.6.2.dist-info → foamlib-0.6.4.dist-info}/METADATA +14 -2
- foamlib-0.6.4.dist-info/RECORD +22 -0
- foamlib-0.6.2.dist-info/RECORD +0 -21
- {foamlib-0.6.2.dist-info → foamlib-0.6.4.dist-info}/LICENSE.txt +0 -0
- {foamlib-0.6.2.dist-info → foamlib-0.6.4.dist-info}/WHEEL +0 -0
- {foamlib-0.6.2.dist-info → foamlib-0.6.4.dist-info}/top_level.txt +0 -0
foamlib/__init__.py
CHANGED
@@ -1,21 +1,25 @@
|
|
1
1
|
"""A Python interface for interacting with OpenFOAM."""
|
2
2
|
|
3
|
-
__version__ = "0.6.
|
3
|
+
__version__ = "0.6.4"
|
4
4
|
|
5
5
|
from ._cases import (
|
6
6
|
AsyncFoamCase,
|
7
|
+
AsyncSlurmFoamCase,
|
7
8
|
CalledProcessError,
|
8
9
|
FoamCase,
|
9
10
|
FoamCaseBase,
|
11
|
+
FoamCaseRunBase,
|
10
12
|
)
|
11
13
|
from ._files import FoamFieldFile, FoamFile, FoamFileBase
|
12
14
|
|
13
15
|
__all__ = [
|
14
|
-
"FoamCase",
|
15
16
|
"AsyncFoamCase",
|
16
|
-
"
|
17
|
+
"AsyncSlurmFoamCase",
|
18
|
+
"CalledProcessError",
|
17
19
|
"FoamFile",
|
20
|
+
"FoamCase",
|
21
|
+
"FoamCaseBase",
|
22
|
+
"FoamCaseRunBase",
|
18
23
|
"FoamFieldFile",
|
19
24
|
"FoamFileBase",
|
20
|
-
"CalledProcessError",
|
21
25
|
]
|
foamlib/_cases/__init__.py
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
from ._async import AsyncFoamCase
|
2
2
|
from ._base import FoamCaseBase
|
3
|
+
from ._run import FoamCaseRunBase
|
4
|
+
from ._slurm import AsyncSlurmFoamCase
|
3
5
|
from ._subprocess import CalledProcessError
|
4
6
|
from ._sync import FoamCase
|
5
7
|
|
6
8
|
__all__ = [
|
7
|
-
"FoamCaseBase",
|
8
|
-
"FoamCase",
|
9
9
|
"AsyncFoamCase",
|
10
|
+
"FoamCaseBase",
|
11
|
+
"FoamCaseRunBase",
|
12
|
+
"AsyncSlurmFoamCase",
|
10
13
|
"CalledProcessError",
|
14
|
+
"FoamCase",
|
11
15
|
]
|
foamlib/_cases/_async.py
CHANGED
@@ -3,7 +3,7 @@ import multiprocessing
|
|
3
3
|
import os
|
4
4
|
import sys
|
5
5
|
from contextlib import asynccontextmanager
|
6
|
-
from typing import Any, Callable, Optional, TypeVar, Union
|
6
|
+
from typing import Any, Callable, Optional, TypeVar, Union, overload
|
7
7
|
|
8
8
|
if sys.version_info >= (3, 9):
|
9
9
|
from collections.abc import (
|
@@ -23,6 +23,8 @@ else:
|
|
23
23
|
|
24
24
|
import aioshutil
|
25
25
|
|
26
|
+
from .._files import FoamFieldFile
|
27
|
+
from ._base import FoamCaseBase
|
26
28
|
from ._run import FoamCaseRunBase
|
27
29
|
from ._subprocess import run_async
|
28
30
|
from ._util import ValuedGenerator, awaitableasynccontextmanager
|
@@ -42,9 +44,25 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
42
44
|
:param path: The path to the case directory.
|
43
45
|
"""
|
44
46
|
|
47
|
+
class TimeDirectory(FoamCaseRunBase.TimeDirectory):
|
48
|
+
@property
|
49
|
+
def _case(self) -> "AsyncFoamCase":
|
50
|
+
return AsyncFoamCase(self.path.parent)
|
51
|
+
|
52
|
+
async def cell_centers(self) -> FoamFieldFile:
|
53
|
+
"""Write and return the cell centers."""
|
54
|
+
calls = ValuedGenerator(self._cell_centers_calls())
|
55
|
+
|
56
|
+
for coro in calls:
|
57
|
+
await coro
|
58
|
+
|
59
|
+
return calls.value
|
60
|
+
|
45
61
|
max_cpus = multiprocessing.cpu_count()
|
46
62
|
"""
|
47
|
-
Maximum number of CPUs to use for running `AsyncFoamCase`
|
63
|
+
Maximum number of CPUs to use for running instances of `AsyncFoamCase` concurrently.
|
64
|
+
|
65
|
+
Defaults to the number of CPUs on the system.
|
48
66
|
"""
|
49
67
|
|
50
68
|
_reserved_cpus = 0
|
@@ -106,6 +124,23 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
106
124
|
for coro in self._clean_calls(check=check):
|
107
125
|
await coro
|
108
126
|
|
127
|
+
@overload
|
128
|
+
def __getitem__(
|
129
|
+
self, index: Union[int, float, str]
|
130
|
+
) -> "AsyncFoamCase.TimeDirectory": ...
|
131
|
+
|
132
|
+
@overload
|
133
|
+
def __getitem__(self, index: slice) -> Sequence["AsyncFoamCase.TimeDirectory"]: ...
|
134
|
+
|
135
|
+
def __getitem__(
|
136
|
+
self, index: Union[int, slice, float, str]
|
137
|
+
) -> Union["AsyncFoamCase.TimeDirectory", Sequence["AsyncFoamCase.TimeDirectory"]]:
|
138
|
+
ret = super().__getitem__(index)
|
139
|
+
if isinstance(ret, FoamCaseBase.TimeDirectory):
|
140
|
+
return AsyncFoamCase.TimeDirectory(ret)
|
141
|
+
else:
|
142
|
+
return [AsyncFoamCase.TimeDirectory(r) for r in ret]
|
143
|
+
|
109
144
|
async def run(
|
110
145
|
self,
|
111
146
|
cmd: Optional[Union[Sequence[Union[str, "os.PathLike[str]"]], str]] = None,
|
@@ -129,17 +164,20 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
129
164
|
):
|
130
165
|
await coro
|
131
166
|
|
132
|
-
async def block_mesh(self, *, check: bool = True) -> None:
|
167
|
+
async def block_mesh(self, *, check: bool = True, log: bool = True) -> None:
|
133
168
|
"""Run blockMesh on this case."""
|
134
|
-
|
169
|
+
for coro in self._block_mesh_calls(check=check, log=log):
|
170
|
+
await coro
|
135
171
|
|
136
|
-
async def decompose_par(self, *, check: bool = True) -> None:
|
172
|
+
async def decompose_par(self, *, check: bool = True, log: bool = True) -> None:
|
137
173
|
"""Decompose this case for parallel running."""
|
138
|
-
|
174
|
+
for coro in self._decompose_par_calls(check=check, log=log):
|
175
|
+
await coro
|
139
176
|
|
140
|
-
async def reconstruct_par(self, *, check: bool = True) -> None:
|
177
|
+
async def reconstruct_par(self, *, check: bool = True, log: bool = True) -> None:
|
141
178
|
"""Reconstruct this case after parallel running."""
|
142
|
-
|
179
|
+
for coro in self._reconstruct_par_calls(check=check, log=log):
|
180
|
+
await coro
|
143
181
|
|
144
182
|
async def restore_0_dir(self) -> None:
|
145
183
|
"""Restore the 0 directory from the 0.orig directory."""
|
foamlib/_cases/_base.py
CHANGED
@@ -40,6 +40,10 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
40
40
|
def __init__(self, path: Union["os.PathLike[str]", str]):
|
41
41
|
self.path = Path(path).absolute()
|
42
42
|
|
43
|
+
@property
|
44
|
+
def _case(self) -> "FoamCaseBase":
|
45
|
+
return FoamCaseBase(self.path.parent)
|
46
|
+
|
43
47
|
@property
|
44
48
|
def time(self) -> float:
|
45
49
|
"""The time that corresponds to this directory."""
|
@@ -58,7 +62,7 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
58
62
|
|
59
63
|
def __contains__(self, obj: object) -> bool:
|
60
64
|
if isinstance(obj, FoamFieldFile):
|
61
|
-
return obj.path.parent == self.path
|
65
|
+
return obj.path.parent == self.path and obj.path.is_file()
|
62
66
|
elif isinstance(obj, str):
|
63
67
|
return (self.path / obj).is_file() or (
|
64
68
|
self.path / f"{obj}.gz"
|
foamlib/_cases/_run.py
CHANGED
@@ -40,11 +40,36 @@ if sys.version_info >= (3, 11):
|
|
40
40
|
else:
|
41
41
|
from typing_extensions import Self
|
42
42
|
|
43
|
+
from .._files import FoamFieldFile
|
43
44
|
from ._base import FoamCaseBase
|
44
45
|
from ._subprocess import DEVNULL, STDOUT
|
45
46
|
|
46
47
|
|
47
48
|
class FoamCaseRunBase(FoamCaseBase):
|
49
|
+
class TimeDirectory(FoamCaseBase.TimeDirectory):
|
50
|
+
@abstractmethod
|
51
|
+
def cell_centers(
|
52
|
+
self,
|
53
|
+
) -> Union[FoamFieldFile, Coroutine[None, None, FoamFieldFile]]:
|
54
|
+
raise NotImplementedError
|
55
|
+
|
56
|
+
@property
|
57
|
+
@abstractmethod
|
58
|
+
def _case(self) -> "FoamCaseRunBase":
|
59
|
+
raise NotImplementedError
|
60
|
+
|
61
|
+
def _cell_centers_calls(self) -> Generator[Any, None, FoamFieldFile]:
|
62
|
+
ret = self["C"]
|
63
|
+
|
64
|
+
if ret not in self:
|
65
|
+
yield self._case.run(
|
66
|
+
["postProcess", "-func", "writeCellCentres", "-time", self.name],
|
67
|
+
cpus=0,
|
68
|
+
log=False,
|
69
|
+
)
|
70
|
+
|
71
|
+
return ret
|
72
|
+
|
48
73
|
def __delitem__(self, key: Union[int, float, str]) -> None:
|
49
74
|
shutil.rmtree(self[key].path)
|
50
75
|
|
@@ -104,13 +129,19 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
104
129
|
|
105
130
|
@abstractmethod
|
106
131
|
def block_mesh(
|
107
|
-
self, *, check: bool = True
|
132
|
+
self, *, check: bool = True, log: bool = True
|
108
133
|
) -> Union[None, Coroutine[None, None, None]]:
|
109
134
|
raise NotImplementedError
|
110
135
|
|
111
136
|
@abstractmethod
|
112
137
|
def decompose_par(
|
113
|
-
self, *, check: bool = True
|
138
|
+
self, *, check: bool = True, log: bool = True
|
139
|
+
) -> Union[None, Coroutine[None, None, None]]:
|
140
|
+
raise NotImplementedError
|
141
|
+
|
142
|
+
@abstractmethod
|
143
|
+
def reconstruct_par(
|
144
|
+
self, *, check: bool = True, log: bool = True
|
114
145
|
) -> Union[None, Coroutine[None, None, None]]:
|
115
146
|
raise NotImplementedError
|
116
147
|
|
@@ -295,6 +326,21 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
295
326
|
yield self._rmtree(self.path / "0", ignore_errors=True)
|
296
327
|
yield self._copytree(self.path / "0.orig", self.path / "0", symlinks=True)
|
297
328
|
|
329
|
+
def _block_mesh_calls(
|
330
|
+
self, *, check: bool, log: bool
|
331
|
+
) -> Generator[Any, None, None]:
|
332
|
+
yield self.run(["blockMesh"], cpus=0, check=check, log=log)
|
333
|
+
|
334
|
+
def _decompose_par_calls(
|
335
|
+
self, *, check: bool, log: bool
|
336
|
+
) -> Generator[Any, None, None]:
|
337
|
+
yield self.run(["decomposePar"], cpus=0, check=check, log=log)
|
338
|
+
|
339
|
+
def _reconstruct_par_calls(
|
340
|
+
self, *, check: bool, log: bool
|
341
|
+
) -> Generator[Any, None, None]:
|
342
|
+
yield self.run(["reconstructPar"], cpus=0, check=check, log=log)
|
343
|
+
|
298
344
|
def _run_calls(
|
299
345
|
self,
|
300
346
|
cmd: Optional[Union[Sequence[Union[str, "os.PathLike[str]"]], str]] = None,
|
@@ -303,6 +349,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
303
349
|
cpus: Optional[int],
|
304
350
|
check: bool,
|
305
351
|
log: bool,
|
352
|
+
**kwargs: Any,
|
306
353
|
) -> Generator[Any, None, None]:
|
307
354
|
if cmd is not None:
|
308
355
|
if parallel:
|
@@ -335,6 +382,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
335
382
|
env=self.__env(shell=isinstance(cmd, str)),
|
336
383
|
stdout=stdout,
|
337
384
|
stderr=stderr,
|
385
|
+
**kwargs,
|
338
386
|
)
|
339
387
|
|
340
388
|
else:
|
@@ -353,7 +401,9 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
353
401
|
if cpus is None:
|
354
402
|
cpus = 1
|
355
403
|
|
356
|
-
yield self.run(
|
404
|
+
yield self.run(
|
405
|
+
[script_path], parallel=False, cpus=cpus, check=check, **kwargs
|
406
|
+
)
|
357
407
|
|
358
408
|
else:
|
359
409
|
if not self and (self.path / "0.orig").is_dir():
|
@@ -383,5 +433,9 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
383
433
|
cpus = 1
|
384
434
|
|
385
435
|
yield self.run(
|
386
|
-
[self.application],
|
436
|
+
[self.application],
|
437
|
+
parallel=parallel,
|
438
|
+
cpus=cpus,
|
439
|
+
check=check,
|
440
|
+
**kwargs,
|
387
441
|
)
|
foamlib/_cases/_slurm.py
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
import os
|
2
|
+
import shutil
|
3
|
+
import sys
|
4
|
+
from typing import Any, Optional, Union
|
5
|
+
|
6
|
+
if sys.version_info >= (3, 9):
|
7
|
+
from collections.abc import Sequence
|
8
|
+
else:
|
9
|
+
from typing import Sequence
|
10
|
+
|
11
|
+
from ._async import AsyncFoamCase
|
12
|
+
from ._subprocess import run_async
|
13
|
+
|
14
|
+
|
15
|
+
class AsyncSlurmFoamCase(AsyncFoamCase):
|
16
|
+
"""An asynchronous OpenFOAM case that launches jobs on a Slurm cluster."""
|
17
|
+
|
18
|
+
@staticmethod
|
19
|
+
async def _run(
|
20
|
+
cmd: Union[Sequence[Union[str, "os.PathLike[str]"]], str],
|
21
|
+
*,
|
22
|
+
cpus: int,
|
23
|
+
fallback: bool = False,
|
24
|
+
**kwargs: Any,
|
25
|
+
) -> None:
|
26
|
+
if fallback and shutil.which("salloc") is None:
|
27
|
+
await AsyncFoamCase._run(cmd, cpus=cpus, **kwargs)
|
28
|
+
return
|
29
|
+
|
30
|
+
if cpus >= 1:
|
31
|
+
if isinstance(cmd, str):
|
32
|
+
cmd = ["/bin/sh", "-c", cmd]
|
33
|
+
|
34
|
+
if cpus == 1:
|
35
|
+
cmd = ["srun", *cmd]
|
36
|
+
|
37
|
+
cmd = ["salloc", "-n", str(cpus), "--job-name", "foamlib", *cmd]
|
38
|
+
|
39
|
+
await run_async(cmd, **kwargs)
|
40
|
+
|
41
|
+
async def run(
|
42
|
+
self,
|
43
|
+
cmd: Optional[Union[Sequence[Union[str, "os.PathLike[str]"]], str]] = None,
|
44
|
+
*,
|
45
|
+
parallel: Optional[bool] = None,
|
46
|
+
cpus: Optional[int] = None,
|
47
|
+
check: bool = True,
|
48
|
+
log: bool = True,
|
49
|
+
fallback: bool = False,
|
50
|
+
) -> None:
|
51
|
+
"""
|
52
|
+
Run this case, or a specified command in the context of this case.
|
53
|
+
|
54
|
+
:param cmd: The command to run. If None, run the case. If a sequence, the first element is the command and the rest are arguments. If a string, `cmd` is executed in a shell.
|
55
|
+
:param parallel: If True, run in parallel using MPI. If None, autodetect whether to run in parallel.
|
56
|
+
:param cpus: The number of CPUs to use. If None, autodetect according to the case. If 0, run locally.
|
57
|
+
:param check: If True, raise a CalledProcessError if any command returns a non-zero exit code.
|
58
|
+
:param log: If True, log the command output to a file.
|
59
|
+
:param fallback: If True, fall back to running the command locally if Slurm is not available.
|
60
|
+
"""
|
61
|
+
for coro in self._run_calls(
|
62
|
+
cmd=cmd,
|
63
|
+
parallel=parallel,
|
64
|
+
cpus=cpus,
|
65
|
+
check=check,
|
66
|
+
log=log,
|
67
|
+
fallback=fallback,
|
68
|
+
):
|
69
|
+
await coro
|
foamlib/_cases/_sync.py
CHANGED
@@ -3,13 +3,7 @@ import shutil
|
|
3
3
|
import sys
|
4
4
|
from pathlib import Path
|
5
5
|
from types import TracebackType
|
6
|
-
from typing import
|
7
|
-
Any,
|
8
|
-
Callable,
|
9
|
-
Optional,
|
10
|
-
Type,
|
11
|
-
Union,
|
12
|
-
)
|
6
|
+
from typing import Any, Callable, Optional, Type, Union, overload
|
13
7
|
|
14
8
|
if sys.version_info >= (3, 9):
|
15
9
|
from collections.abc import Collection, Sequence
|
@@ -21,6 +15,8 @@ if sys.version_info >= (3, 11):
|
|
21
15
|
else:
|
22
16
|
from typing_extensions import Self
|
23
17
|
|
18
|
+
from .._files import FoamFieldFile
|
19
|
+
from ._base import FoamCaseBase
|
24
20
|
from ._run import FoamCaseRunBase
|
25
21
|
from ._subprocess import run_sync
|
26
22
|
from ._util import ValuedGenerator
|
@@ -37,6 +33,22 @@ class FoamCase(FoamCaseRunBase):
|
|
37
33
|
:param path: The path to the case directory.
|
38
34
|
"""
|
39
35
|
|
36
|
+
class TimeDirectory(FoamCaseRunBase.TimeDirectory):
|
37
|
+
@property
|
38
|
+
def _case(self) -> "FoamCase":
|
39
|
+
return FoamCase(self.path.parent)
|
40
|
+
|
41
|
+
def cell_centers(self) -> FoamFieldFile:
|
42
|
+
"""Write and return the cell centers."""
|
43
|
+
calls = ValuedGenerator(self._cell_centers_calls())
|
44
|
+
|
45
|
+
for _ in calls:
|
46
|
+
pass
|
47
|
+
|
48
|
+
print(calls.value)
|
49
|
+
|
50
|
+
return calls.value
|
51
|
+
|
40
52
|
def __init__(self, path: Union["os.PathLike[str]", str] = Path()):
|
41
53
|
super().__init__(path)
|
42
54
|
|
@@ -67,6 +79,23 @@ class FoamCase(FoamCaseRunBase):
|
|
67
79
|
) -> None:
|
68
80
|
shutil.copytree(src, dest, symlinks=symlinks, ignore=ignore)
|
69
81
|
|
82
|
+
@overload
|
83
|
+
def __getitem__(
|
84
|
+
self, index: Union[int, float, str]
|
85
|
+
) -> "FoamCase.TimeDirectory": ...
|
86
|
+
|
87
|
+
@overload
|
88
|
+
def __getitem__(self, index: slice) -> Sequence["FoamCase.TimeDirectory"]: ...
|
89
|
+
|
90
|
+
def __getitem__(
|
91
|
+
self, index: Union[int, slice, float, str]
|
92
|
+
) -> Union["FoamCase.TimeDirectory", Sequence["FoamCase.TimeDirectory"]]:
|
93
|
+
ret = super().__getitem__(index)
|
94
|
+
if isinstance(ret, FoamCaseBase.TimeDirectory):
|
95
|
+
return FoamCase.TimeDirectory(ret)
|
96
|
+
else:
|
97
|
+
return [FoamCase.TimeDirectory(r) for r in ret]
|
98
|
+
|
70
99
|
def __enter__(self) -> Self:
|
71
100
|
return self
|
72
101
|
|
@@ -110,17 +139,20 @@ class FoamCase(FoamCaseRunBase):
|
|
110
139
|
):
|
111
140
|
pass
|
112
141
|
|
113
|
-
def block_mesh(self, *, check: bool = True) -> None:
|
142
|
+
def block_mesh(self, *, check: bool = True, log: bool = True) -> None:
|
114
143
|
"""Run blockMesh on this case."""
|
115
|
-
self.
|
144
|
+
for _ in self._block_mesh_calls(check=check, log=log):
|
145
|
+
pass
|
116
146
|
|
117
|
-
def decompose_par(self, *, check: bool = True) -> None:
|
147
|
+
def decompose_par(self, *, check: bool = True, log: bool = True) -> None:
|
118
148
|
"""Decompose this case for parallel running."""
|
119
|
-
self.
|
149
|
+
for _ in self._decompose_par_calls(check=check, log=log):
|
150
|
+
pass
|
120
151
|
|
121
|
-
def reconstruct_par(self, *, check: bool = True) -> None:
|
152
|
+
def reconstruct_par(self, *, check: bool = True, log: bool = True) -> None:
|
122
153
|
"""Reconstruct this case after parallel running."""
|
123
|
-
self.
|
154
|
+
for _ in self._reconstruct_par_calls(check=check, log=log):
|
155
|
+
pass
|
124
156
|
|
125
157
|
def restore_0_dir(self) -> None:
|
126
158
|
"""Restore the 0 directory from the 0.orig directory."""
|
@@ -135,12 +167,12 @@ class FoamCase(FoamCaseRunBase):
|
|
135
167
|
|
136
168
|
:param dst: The destination path. If None, clone to `$FOAM_RUN/foamlib`.
|
137
169
|
"""
|
138
|
-
|
170
|
+
calls = ValuedGenerator(self._copy_calls(dst))
|
139
171
|
|
140
|
-
for _ in
|
172
|
+
for _ in calls:
|
141
173
|
pass
|
142
174
|
|
143
|
-
return
|
175
|
+
return calls.value
|
144
176
|
|
145
177
|
def clone(self, dst: Optional[Union["os.PathLike[str]", str]] = None) -> Self:
|
146
178
|
"""
|
@@ -150,9 +182,9 @@ class FoamCase(FoamCaseRunBase):
|
|
150
182
|
|
151
183
|
:param dst: The destination path. If None, clone to `$FOAM_RUN/foamlib`.
|
152
184
|
"""
|
153
|
-
|
185
|
+
calls = ValuedGenerator(self._clone_calls(dst))
|
154
186
|
|
155
|
-
for _ in
|
187
|
+
for _ in calls:
|
156
188
|
pass
|
157
189
|
|
158
|
-
return
|
190
|
+
return calls.value
|
foamlib/_files/_io.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import gzip
|
2
|
+
import os
|
2
3
|
import sys
|
3
4
|
from copy import deepcopy
|
4
5
|
from pathlib import Path
|
@@ -19,7 +20,7 @@ from ._parsing import Parsed
|
|
19
20
|
|
20
21
|
|
21
22
|
class FoamFileIO:
|
22
|
-
def __init__(self, path: Union[str,
|
23
|
+
def __init__(self, path: Union["os.PathLike[str]", str]) -> None:
|
23
24
|
self.path = Path(path).absolute()
|
24
25
|
|
25
26
|
self.__contents: Optional[bytes] = None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: foamlib
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.4
|
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
|
@@ -69,7 +69,7 @@ Requires-Dist: mypy <2,>=1 ; extra == 'typing'
|
|
69
69
|
It offers the following classes:
|
70
70
|
|
71
71
|
* [`FoamFile`](https://foamlib.readthedocs.io/en/stable/files.html#foamlib.FoamFile) (and [`FoamFieldFile`](https://foamlib.readthedocs.io/en/stable/files.html#foamlib.FoamFieldFile)): read-write access to OpenFOAM configuration and field files as if they were Python `dict`s, using `foamlib`'s own parser. Supports both ASCII and binary field formats.
|
72
|
-
* [`FoamCase`](https://foamlib.readthedocs.io/en/stable/cases.html#foamlib.FoamCase): a class for
|
72
|
+
* [`FoamCase`](https://foamlib.readthedocs.io/en/stable/cases.html#foamlib.FoamCase): a class for configuring, running, and accessing the results of OpenFOAM cases.
|
73
73
|
* [`AsyncFoamCase`](https://foamlib.readthedocs.io/en/stable/cases.html#foamlib.AsyncFoamCase): variant of `FoamCase` with asynchronous methods for running multiple cases at once.
|
74
74
|
|
75
75
|
## Get started
|
@@ -174,6 +174,18 @@ async def cost(x):
|
|
174
174
|
result = differential_evolution(cost, bounds=[(-1, 1)], workers=AsyncFoamCase.map, polish=False)
|
175
175
|
```
|
176
176
|
|
177
|
+
### Use it to create a `run` (or `clean`) script
|
178
|
+
|
179
|
+
```python
|
180
|
+
#!/usr/bin/env python3
|
181
|
+
from pathlib import Path
|
182
|
+
from foamlib import FoamCase
|
183
|
+
|
184
|
+
case = FoamCase(Path(__file__).parent)
|
185
|
+
# Any additional configuration here
|
186
|
+
case.run()
|
187
|
+
```
|
188
|
+
|
177
189
|
## Documentation
|
178
190
|
|
179
191
|
For more information, check out the [documentation](https://foamlib.readthedocs.io/).
|
@@ -0,0 +1,22 @@
|
|
1
|
+
foamlib/__init__.py,sha256=bmL3_3H-rn3OrCYQZeUZkDBGgYygbgZJ2pd8dAoAvig,486
|
2
|
+
foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
foamlib/_cases/__init__.py,sha256=wTUHcUgU1CBgpu0cUMtksQ5VKG6B8CFu9xc3dWwsQuo,358
|
4
|
+
foamlib/_cases/_async.py,sha256=PYODgIkRLHArMf3wtf34jMx7gBGi-K6hoLEhjYK9bOw,7753
|
5
|
+
foamlib/_cases/_base.py,sha256=4VWsu22VockyKgU_5tnSMeNrAkMgBKwZo2KGkV65rRQ,6739
|
6
|
+
foamlib/_cases/_run.py,sha256=SjA-Qux5NhnhcLz7qiph2DcGYpElAAl_PlTGk6kGeuU,13972
|
7
|
+
foamlib/_cases/_slurm.py,sha256=rhGSFJ-3g72TnAYlhECGfs7P7IkeaHL3ysjXfXLdCCc,2308
|
8
|
+
foamlib/_cases/_subprocess.py,sha256=GTmHWy1LRD9ujpXJfSTXU2bf87GncpIA0VOR1rQW2fg,3633
|
9
|
+
foamlib/_cases/_sync.py,sha256=L1Em9_32zd01RnMvksZ1GU-4okxhcwZgpLQf1c15uAs,6038
|
10
|
+
foamlib/_cases/_util.py,sha256=GNndpqw3Jg_S-Hxzl5vwRgD0czcTNb9NYHMhcfBoMBg,1493
|
11
|
+
foamlib/_files/__init__.py,sha256=-UqB9YTH6mrJfXCX00kPTAAY20XG64u1MGPw_1ewLVs,148
|
12
|
+
foamlib/_files/_base.py,sha256=zaFDjLE6jB7WtGWk8hfKusjLtlGu6CZV16AHJpRUibs,1929
|
13
|
+
foamlib/_files/_files.py,sha256=DxM5JmXv19PJrqlKNwuP6SsB0nye6aN1hiPwble7fFM,15657
|
14
|
+
foamlib/_files/_io.py,sha256=T8vTEmJDidL03qeX1PUJFND-_vaF0AuC_0lE_zxLz7Q,2447
|
15
|
+
foamlib/_files/_parsing.py,sha256=DzgJ53QnohRQyLXn2zOs52RIQ7bJ_fS_S2Z7rmRyVK4,9023
|
16
|
+
foamlib/_files/_serialization.py,sha256=pb8_cIVgRhGS_ZV2p3x8p5_lK1SS6xzQHscAYYuOgFY,3407
|
17
|
+
foamlib/_files/_util.py,sha256=UMzXmTFgvbp46w6k3oEZJoYC98pFgEK6LN5uLOwrlCg,397
|
18
|
+
foamlib-0.6.4.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
|
19
|
+
foamlib-0.6.4.dist-info/METADATA,sha256=VeyVZAbFPEiSVnWDZ4XNzGYOHuz04fhmNkiGvYQp8KY,6569
|
20
|
+
foamlib-0.6.4.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
21
|
+
foamlib-0.6.4.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
|
22
|
+
foamlib-0.6.4.dist-info/RECORD,,
|
foamlib-0.6.2.dist-info/RECORD
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
foamlib/__init__.py,sha256=7q60H9MQAusLbKMVlBGgR2FgYmGi08CcBEBJiCwAmf0,392
|
2
|
-
foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
foamlib/_cases/__init__.py,sha256=C0mpRu7c-X-4uVMKmVrZhwIyhBNyvUoCv0o-BQ72RC0,236
|
4
|
-
foamlib/_cases/_async.py,sha256=8x8Mkql6XPzMjH4t-NszAEDx4gpjNPnQiWxFkHrcFJU,6436
|
5
|
-
foamlib/_cases/_base.py,sha256=1CUkkK4afBxDgP79dmho97WJdj-GLgYhnrCSf_52Eao,6604
|
6
|
-
foamlib/_cases/_run.py,sha256=KV5n9eBOR7nAnW1IFfvoudX2IxsJuhpXHzN7XcHnblE,12264
|
7
|
-
foamlib/_cases/_subprocess.py,sha256=GTmHWy1LRD9ujpXJfSTXU2bf87GncpIA0VOR1rQW2fg,3633
|
8
|
-
foamlib/_cases/_sync.py,sha256=46cXS8ixIpWIJ76iPdnE3rqvHDjd4mF3QYH-jWbYszs,4794
|
9
|
-
foamlib/_cases/_util.py,sha256=GNndpqw3Jg_S-Hxzl5vwRgD0czcTNb9NYHMhcfBoMBg,1493
|
10
|
-
foamlib/_files/__init__.py,sha256=-UqB9YTH6mrJfXCX00kPTAAY20XG64u1MGPw_1ewLVs,148
|
11
|
-
foamlib/_files/_base.py,sha256=zaFDjLE6jB7WtGWk8hfKusjLtlGu6CZV16AHJpRUibs,1929
|
12
|
-
foamlib/_files/_files.py,sha256=DxM5JmXv19PJrqlKNwuP6SsB0nye6aN1hiPwble7fFM,15657
|
13
|
-
foamlib/_files/_io.py,sha256=uSh5XlgukwJkQSLELa4mshRD2aTajNk5vr_ZsBImSeU,2423
|
14
|
-
foamlib/_files/_parsing.py,sha256=DzgJ53QnohRQyLXn2zOs52RIQ7bJ_fS_S2Z7rmRyVK4,9023
|
15
|
-
foamlib/_files/_serialization.py,sha256=pb8_cIVgRhGS_ZV2p3x8p5_lK1SS6xzQHscAYYuOgFY,3407
|
16
|
-
foamlib/_files/_util.py,sha256=UMzXmTFgvbp46w6k3oEZJoYC98pFgEK6LN5uLOwrlCg,397
|
17
|
-
foamlib-0.6.2.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
|
18
|
-
foamlib-0.6.2.dist-info/METADATA,sha256=zoXLd6rEAjGbdJhQd9AMZ8oD5ME_1YqTuXYz2hGQXdE,6338
|
19
|
-
foamlib-0.6.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
20
|
-
foamlib-0.6.2.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
|
21
|
-
foamlib-0.6.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|