foamlib 0.6.11__tar.gz → 0.6.12__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.
- {foamlib-0.6.11 → foamlib-0.6.12}/PKG-INFO +1 -1
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/__init__.py +1 -1
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_async.py +23 -23
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_base.py +25 -26
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_run.py +52 -58
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_slurm.py +7 -5
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_subprocess.py +15 -13
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_sync.py +25 -27
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/_util.py +13 -10
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/_base.py +5 -3
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/_files.py +116 -101
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/_io.py +9 -10
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/_parsing.py +21 -25
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/_serialization.py +19 -11
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/_util.py +8 -3
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib.egg-info/PKG-INFO +1 -1
- {foamlib-0.6.11 → foamlib-0.6.12}/pyproject.toml +18 -29
- {foamlib-0.6.11 → foamlib-0.6.12}/LICENSE.txt +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/README.md +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_cases/__init__.py +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/_files/__init__.py +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib/py.typed +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib.egg-info/SOURCES.txt +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib.egg-info/dependency_links.txt +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib.egg-info/requires.txt +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/foamlib.egg-info/top_level.txt +0 -0
- {foamlib-0.6.11 → foamlib-0.6.12}/setup.cfg +0 -0
@@ -1,8 +1,10 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import asyncio
|
2
4
|
import multiprocessing
|
3
5
|
import sys
|
4
6
|
from contextlib import asynccontextmanager
|
5
|
-
from typing import TYPE_CHECKING, Any, Callable,
|
7
|
+
from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
|
6
8
|
|
7
9
|
if sys.version_info >= (3, 9):
|
8
10
|
from collections.abc import (
|
@@ -22,7 +24,6 @@ else:
|
|
22
24
|
|
23
25
|
import aioshutil
|
24
26
|
|
25
|
-
from .._files import FoamFieldFile
|
26
27
|
from ._base import FoamCaseBase
|
27
28
|
from ._run import FoamCaseRunBase
|
28
29
|
from ._subprocess import run_async
|
@@ -31,6 +32,8 @@ from ._util import ValuedGenerator, awaitableasynccontextmanager
|
|
31
32
|
if TYPE_CHECKING:
|
32
33
|
import os
|
33
34
|
|
35
|
+
from .._files import FoamFieldFile
|
36
|
+
|
34
37
|
X = TypeVar("X")
|
35
38
|
Y = TypeVar("Y")
|
36
39
|
|
@@ -48,7 +51,7 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
48
51
|
|
49
52
|
class TimeDirectory(FoamCaseRunBase.TimeDirectory):
|
50
53
|
@property
|
51
|
-
def _case(self) ->
|
54
|
+
def _case(self) -> AsyncFoamCase:
|
52
55
|
return AsyncFoamCase(self.path.parent)
|
53
56
|
|
54
57
|
async def cell_centers(self) -> FoamFieldFile:
|
@@ -62,8 +65,8 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
62
65
|
|
63
66
|
max_cpus = multiprocessing.cpu_count()
|
64
67
|
"""
|
65
|
-
Maximum number of CPUs to use for running instances of `AsyncFoamCase` concurrently.
|
66
|
-
|
68
|
+
Maximum number of CPUs to use for running instances of `AsyncFoamCase` concurrently.
|
69
|
+
|
67
70
|
Defaults to the number of CPUs on the system.
|
68
71
|
"""
|
69
72
|
|
@@ -91,7 +94,7 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
91
94
|
|
92
95
|
@staticmethod
|
93
96
|
async def _run(
|
94
|
-
cmd:
|
97
|
+
cmd: Sequence[str | os.PathLike[str]] | str,
|
95
98
|
*,
|
96
99
|
cpus: int,
|
97
100
|
**kwargs: Any,
|
@@ -101,19 +104,18 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
101
104
|
|
102
105
|
@staticmethod
|
103
106
|
async def _rmtree(
|
104
|
-
path:
|
107
|
+
path: os.PathLike[str] | str, *, ignore_errors: bool = False
|
105
108
|
) -> None:
|
106
109
|
await aioshutil.rmtree(path, ignore_errors=ignore_errors)
|
107
110
|
|
108
111
|
@staticmethod
|
109
112
|
async def _copytree(
|
110
|
-
src:
|
111
|
-
dest:
|
113
|
+
src: os.PathLike[str] | str,
|
114
|
+
dest: os.PathLike[str] | str,
|
112
115
|
*,
|
113
116
|
symlinks: bool = False,
|
114
|
-
ignore:
|
115
|
-
|
116
|
-
] = None,
|
117
|
+
ignore: Callable[[os.PathLike[str] | str, Collection[str]], Collection[str]]
|
118
|
+
| None = None,
|
117
119
|
) -> None:
|
118
120
|
await aioshutil.copytree(src, dest, symlinks=symlinks, ignore=ignore)
|
119
121
|
|
@@ -127,16 +129,14 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
127
129
|
await coro
|
128
130
|
|
129
131
|
@overload
|
130
|
-
def __getitem__(
|
131
|
-
self, index: Union[int, float, str]
|
132
|
-
) -> "AsyncFoamCase.TimeDirectory": ...
|
132
|
+
def __getitem__(self, index: int | float | str) -> AsyncFoamCase.TimeDirectory: ...
|
133
133
|
|
134
134
|
@overload
|
135
|
-
def __getitem__(self, index: slice) -> Sequence[
|
135
|
+
def __getitem__(self, index: slice) -> Sequence[AsyncFoamCase.TimeDirectory]: ...
|
136
136
|
|
137
137
|
def __getitem__(
|
138
|
-
self, index:
|
139
|
-
) ->
|
138
|
+
self, index: int | slice | float | str
|
139
|
+
) -> AsyncFoamCase.TimeDirectory | Sequence[AsyncFoamCase.TimeDirectory]:
|
140
140
|
ret = super().__getitem__(index)
|
141
141
|
if isinstance(ret, FoamCaseBase.TimeDirectory):
|
142
142
|
return AsyncFoamCase.TimeDirectory(ret)
|
@@ -148,10 +148,10 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
148
148
|
|
149
149
|
async def run(
|
150
150
|
self,
|
151
|
-
cmd:
|
151
|
+
cmd: Sequence[str | os.PathLike[str]] | str | None = None,
|
152
152
|
*,
|
153
|
-
parallel:
|
154
|
-
cpus:
|
153
|
+
parallel: bool | None = None,
|
154
|
+
cpus: int | None = None,
|
155
155
|
check: bool = True,
|
156
156
|
log: bool = True,
|
157
157
|
) -> None:
|
@@ -192,7 +192,7 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
192
192
|
@awaitableasynccontextmanager
|
193
193
|
@asynccontextmanager
|
194
194
|
async def copy(
|
195
|
-
self, dst:
|
195
|
+
self, dst: os.PathLike[str] | str | None = None
|
196
196
|
) -> AsyncGenerator[Self, None]:
|
197
197
|
"""
|
198
198
|
Make a copy of this case.
|
@@ -213,7 +213,7 @@ class AsyncFoamCase(FoamCaseRunBase):
|
|
213
213
|
@awaitableasynccontextmanager
|
214
214
|
@asynccontextmanager
|
215
215
|
async def clone(
|
216
|
-
self, dst:
|
216
|
+
self, dst: os.PathLike[str] | str | None = None
|
217
217
|
) -> AsyncGenerator[Self, None]:
|
218
218
|
"""
|
219
219
|
Clone this case (make a clean copy).
|
@@ -1,22 +1,19 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import shutil
|
2
4
|
import sys
|
3
5
|
from pathlib import Path
|
4
|
-
from typing import
|
5
|
-
TYPE_CHECKING,
|
6
|
-
Optional,
|
7
|
-
Union,
|
8
|
-
overload,
|
9
|
-
)
|
6
|
+
from typing import TYPE_CHECKING, overload
|
10
7
|
|
11
8
|
if sys.version_info >= (3, 9):
|
12
9
|
from collections.abc import (
|
13
10
|
Iterator,
|
14
11
|
Sequence,
|
15
|
-
Set,
|
16
12
|
)
|
13
|
+
from collections.abc import Set as AbstractSet
|
17
14
|
else:
|
18
|
-
from typing import AbstractSet as Set
|
19
15
|
from typing import (
|
16
|
+
AbstractSet,
|
20
17
|
Iterator,
|
21
18
|
Sequence,
|
22
19
|
)
|
@@ -28,10 +25,10 @@ if TYPE_CHECKING:
|
|
28
25
|
|
29
26
|
|
30
27
|
class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
31
|
-
def __init__(self, path:
|
28
|
+
def __init__(self, path: os.PathLike[str] | str = Path()) -> None:
|
32
29
|
self.path = Path(path).absolute()
|
33
30
|
|
34
|
-
class TimeDirectory(
|
31
|
+
class TimeDirectory(AbstractSet[FoamFieldFile]):
|
35
32
|
"""
|
36
33
|
An OpenFOAM time directory in a case.
|
37
34
|
|
@@ -40,11 +37,11 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
40
37
|
:param path: The path to the time directory.
|
41
38
|
"""
|
42
39
|
|
43
|
-
def __init__(self, path:
|
40
|
+
def __init__(self, path: os.PathLike[str] | str) -> None:
|
44
41
|
self.path = Path(path).absolute()
|
45
42
|
|
46
43
|
@property
|
47
|
-
def _case(self) ->
|
44
|
+
def _case(self) -> FoamCaseBase:
|
48
45
|
return FoamCaseBase(self.path.parent)
|
49
46
|
|
50
47
|
@property
|
@@ -97,7 +94,7 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
97
94
|
return str(self.path)
|
98
95
|
|
99
96
|
@property
|
100
|
-
def _times(self) -> Sequence[
|
97
|
+
def _times(self) -> Sequence[FoamCaseBase.TimeDirectory]:
|
101
98
|
times = []
|
102
99
|
for p in self.path.iterdir():
|
103
100
|
if p.is_dir():
|
@@ -113,29 +110,28 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
113
110
|
return times
|
114
111
|
|
115
112
|
@overload
|
116
|
-
def __getitem__(
|
117
|
-
self, index: Union[int, float, str]
|
118
|
-
) -> "FoamCaseBase.TimeDirectory": ...
|
113
|
+
def __getitem__(self, index: int | float | str) -> FoamCaseBase.TimeDirectory: ...
|
119
114
|
|
120
115
|
@overload
|
121
|
-
def __getitem__(self, index: slice) -> Sequence[
|
116
|
+
def __getitem__(self, index: slice) -> Sequence[FoamCaseBase.TimeDirectory]: ...
|
122
117
|
|
123
118
|
def __getitem__(
|
124
|
-
self, index:
|
125
|
-
) ->
|
119
|
+
self, index: int | slice | float | str
|
120
|
+
) -> FoamCaseBase.TimeDirectory | Sequence[FoamCaseBase.TimeDirectory]:
|
126
121
|
if isinstance(index, str):
|
127
122
|
return FoamCaseBase.TimeDirectory(self.path / index)
|
128
123
|
if isinstance(index, float):
|
129
124
|
for time in self._times:
|
130
125
|
if time.time == index:
|
131
126
|
return time
|
132
|
-
|
127
|
+
msg = f"Time {index} not found"
|
128
|
+
raise IndexError(msg)
|
133
129
|
return self._times[index]
|
134
130
|
|
135
131
|
def __len__(self) -> int:
|
136
132
|
return len(self._times)
|
137
133
|
|
138
|
-
def __delitem__(self, key:
|
134
|
+
def __delitem__(self, key: int | float | str) -> None:
|
139
135
|
shutil.rmtree(self[key].path)
|
140
136
|
|
141
137
|
@property
|
@@ -143,22 +139,24 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
143
139
|
"""The name of the case."""
|
144
140
|
return self.path.name
|
145
141
|
|
146
|
-
def file(self, path:
|
142
|
+
def file(self, path: os.PathLike[str] | str) -> FoamFile:
|
147
143
|
"""Return a FoamFile object for the given path in the case."""
|
148
144
|
return FoamFile(self.path / path)
|
149
145
|
|
150
146
|
@property
|
151
|
-
def _nsubdomains(self) ->
|
147
|
+
def _nsubdomains(self) -> int | None:
|
152
148
|
"""Return the number of subdomains as set in the decomposeParDict, or None if no decomposeParDict is found."""
|
153
149
|
try:
|
154
150
|
nsubdomains = self.decompose_par_dict["numberOfSubdomains"]
|
155
151
|
if not isinstance(nsubdomains, int):
|
156
|
-
|
152
|
+
msg = (
|
157
153
|
f"numberOfSubdomains in {self.decompose_par_dict} is not an integer"
|
158
154
|
)
|
159
|
-
|
155
|
+
raise TypeError(msg)
|
160
156
|
except FileNotFoundError:
|
161
157
|
return None
|
158
|
+
else:
|
159
|
+
return nsubdomains
|
162
160
|
|
163
161
|
@property
|
164
162
|
def _nprocessors(self) -> int:
|
@@ -170,7 +168,8 @@ class FoamCaseBase(Sequence["FoamCaseBase.TimeDirectory"]):
|
|
170
168
|
"""The application name as set in the controlDict."""
|
171
169
|
application = self.control_dict["application"]
|
172
170
|
if not isinstance(application, str):
|
173
|
-
|
171
|
+
msg = f"application in {self.control_dict} is not a string"
|
172
|
+
raise TypeError(msg)
|
174
173
|
return application
|
175
174
|
|
176
175
|
@property
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os
|
2
4
|
import shlex
|
3
5
|
import shutil
|
@@ -6,13 +8,7 @@ import tempfile
|
|
6
8
|
from abc import abstractmethod
|
7
9
|
from contextlib import contextmanager
|
8
10
|
from pathlib import Path
|
9
|
-
from typing import
|
10
|
-
IO,
|
11
|
-
Any,
|
12
|
-
Optional,
|
13
|
-
Tuple,
|
14
|
-
Union,
|
15
|
-
)
|
11
|
+
from typing import IO, TYPE_CHECKING, Any
|
16
12
|
|
17
13
|
if sys.version_info >= (3, 9):
|
18
14
|
from collections.abc import (
|
@@ -22,11 +18,11 @@ if sys.version_info >= (3, 9):
|
|
22
18
|
Generator,
|
23
19
|
Mapping,
|
24
20
|
Sequence,
|
25
|
-
Set,
|
26
21
|
)
|
22
|
+
from collections.abc import Set as AbstractSet
|
27
23
|
else:
|
28
|
-
from typing import AbstractSet as Set
|
29
24
|
from typing import (
|
25
|
+
AbstractSet,
|
30
26
|
Callable,
|
31
27
|
Collection,
|
32
28
|
Coroutine,
|
@@ -40,22 +36,24 @@ if sys.version_info >= (3, 11):
|
|
40
36
|
else:
|
41
37
|
from typing_extensions import Self
|
42
38
|
|
43
|
-
from .._files import FoamFieldFile
|
44
39
|
from ._base import FoamCaseBase
|
45
40
|
from ._subprocess import DEVNULL, STDOUT
|
46
41
|
|
42
|
+
if TYPE_CHECKING:
|
43
|
+
from .._files import FoamFieldFile
|
44
|
+
|
47
45
|
|
48
46
|
class FoamCaseRunBase(FoamCaseBase):
|
49
47
|
class TimeDirectory(FoamCaseBase.TimeDirectory):
|
50
48
|
@abstractmethod
|
51
49
|
def cell_centers(
|
52
50
|
self,
|
53
|
-
) ->
|
51
|
+
) -> FoamFieldFile | Coroutine[None, None, FoamFieldFile]:
|
54
52
|
raise NotImplementedError
|
55
53
|
|
56
54
|
@property
|
57
55
|
@abstractmethod
|
58
|
-
def _case(self) ->
|
56
|
+
def _case(self) -> FoamCaseRunBase:
|
59
57
|
raise NotImplementedError
|
60
58
|
|
61
59
|
def _cell_centers_calls(self) -> Generator[Any, None, FoamFieldFile]:
|
@@ -70,92 +68,91 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
70
68
|
|
71
69
|
return ret
|
72
70
|
|
73
|
-
def __delitem__(self, key:
|
71
|
+
def __delitem__(self, key: int | float | str) -> None:
|
74
72
|
shutil.rmtree(self[key].path)
|
75
73
|
|
76
74
|
@staticmethod
|
77
75
|
@abstractmethod
|
78
76
|
def _run(
|
79
|
-
cmd:
|
77
|
+
cmd: Sequence[str | os.PathLike[str]] | str,
|
80
78
|
*,
|
81
79
|
cpus: int,
|
82
80
|
**kwargs: Any,
|
83
|
-
) ->
|
81
|
+
) -> None | Coroutine[None, None, None]:
|
84
82
|
raise NotImplementedError
|
85
83
|
|
86
84
|
@staticmethod
|
87
85
|
@abstractmethod
|
88
86
|
def _rmtree(
|
89
|
-
path:
|
90
|
-
) ->
|
87
|
+
path: os.PathLike[str] | str, *, ignore_errors: bool = False
|
88
|
+
) -> None | Coroutine[None, None, None]:
|
91
89
|
raise NotImplementedError
|
92
90
|
|
93
91
|
@staticmethod
|
94
92
|
@abstractmethod
|
95
93
|
def _copytree(
|
96
|
-
src:
|
97
|
-
dest:
|
94
|
+
src: os.PathLike[str] | str,
|
95
|
+
dest: os.PathLike[str] | str,
|
98
96
|
*,
|
99
97
|
symlinks: bool = False,
|
100
|
-
ignore:
|
101
|
-
|
102
|
-
|
103
|
-
) -> Union[None, Coroutine[None, None, None]]:
|
98
|
+
ignore: Callable[[os.PathLike[str] | str, Collection[str]], Collection[str]]
|
99
|
+
| None = None,
|
100
|
+
) -> None | Coroutine[None, None, None]:
|
104
101
|
raise NotImplementedError
|
105
102
|
|
106
103
|
@abstractmethod
|
107
|
-
def clean(self, *, check: bool = False) ->
|
104
|
+
def clean(self, *, check: bool = False) -> None | Coroutine[None, None, None]:
|
108
105
|
raise NotImplementedError
|
109
106
|
|
110
107
|
@abstractmethod
|
111
|
-
def copy(self, dst:
|
108
|
+
def copy(self, dst: os.PathLike[str] | str | None = None) -> Any:
|
112
109
|
raise NotImplementedError
|
113
110
|
|
114
111
|
@abstractmethod
|
115
|
-
def clone(self, dst:
|
112
|
+
def clone(self, dst: os.PathLike[str] | str | None = None) -> Any:
|
116
113
|
raise NotImplementedError
|
117
114
|
|
118
115
|
@abstractmethod
|
119
116
|
def _prepare(
|
120
117
|
self, *, check: bool = True, log: bool = True
|
121
|
-
) ->
|
118
|
+
) -> None | Coroutine[None, None, None]:
|
122
119
|
raise NotImplementedError
|
123
120
|
|
124
121
|
@abstractmethod
|
125
122
|
def run(
|
126
123
|
self,
|
127
|
-
cmd:
|
124
|
+
cmd: Sequence[str | os.PathLike[str]] | str | None = None,
|
128
125
|
*,
|
129
|
-
parallel:
|
130
|
-
cpus:
|
126
|
+
parallel: bool | None = None,
|
127
|
+
cpus: int | None = None,
|
131
128
|
check: bool = True,
|
132
129
|
log: bool = True,
|
133
|
-
) ->
|
130
|
+
) -> None | Coroutine[None, None, None]:
|
134
131
|
raise NotImplementedError
|
135
132
|
|
136
133
|
@abstractmethod
|
137
134
|
def block_mesh(
|
138
135
|
self, *, check: bool = True, log: bool = True
|
139
|
-
) ->
|
136
|
+
) -> None | Coroutine[None, None, None]:
|
140
137
|
raise NotImplementedError
|
141
138
|
|
142
139
|
@abstractmethod
|
143
140
|
def decompose_par(
|
144
141
|
self, *, check: bool = True, log: bool = True
|
145
|
-
) ->
|
142
|
+
) -> None | Coroutine[None, None, None]:
|
146
143
|
raise NotImplementedError
|
147
144
|
|
148
145
|
@abstractmethod
|
149
146
|
def reconstruct_par(
|
150
147
|
self, *, check: bool = True, log: bool = True
|
151
|
-
) ->
|
148
|
+
) -> None | Coroutine[None, None, None]:
|
152
149
|
raise NotImplementedError
|
153
150
|
|
154
151
|
@abstractmethod
|
155
|
-
def restore_0_dir(self) ->
|
152
|
+
def restore_0_dir(self) -> None | Coroutine[None, None, None]:
|
156
153
|
raise NotImplementedError
|
157
154
|
|
158
|
-
def __clean_paths(self) ->
|
155
|
+
def __clean_paths(self) -> AbstractSet[Path]:
|
159
156
|
has_decompose_par_dict = (self.path / "system" / "decomposeParDict").is_file()
|
160
157
|
has_block_mesh_dict = (self.path / "system" / "blockMeshDict").is_file()
|
161
158
|
|
@@ -186,18 +183,18 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
186
183
|
|
187
184
|
def __clone_ignore(
|
188
185
|
self,
|
189
|
-
) -> Callable[[
|
186
|
+
) -> Callable[[os.PathLike[str] | str, Collection[str]], Collection[str]]:
|
190
187
|
clean_paths = self.__clean_paths()
|
191
188
|
|
192
189
|
def ignore(
|
193
|
-
path:
|
190
|
+
path: os.PathLike[str] | str, names: Collection[str]
|
194
191
|
) -> Collection[str]:
|
195
192
|
paths = {Path(path) / name for name in names}
|
196
193
|
return {p.name for p in paths.intersection(clean_paths)}
|
197
194
|
|
198
195
|
return ignore
|
199
196
|
|
200
|
-
def __clean_script(self) ->
|
197
|
+
def __clean_script(self) -> Path | None:
|
201
198
|
"""Return the path to the (All)clean script, or None if no clean script is found."""
|
202
199
|
clean = self.path / "clean"
|
203
200
|
all_clean = self.path / "Allclean"
|
@@ -214,7 +211,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
214
211
|
|
215
212
|
return script
|
216
213
|
|
217
|
-
def __prepare_script(self) ->
|
214
|
+
def __prepare_script(self) -> Path | None:
|
218
215
|
"""Return the path to the Allrun.pre script, or None if no prepare script is found."""
|
219
216
|
script = self.path / "Allrun.pre"
|
220
217
|
|
@@ -226,7 +223,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
226
223
|
|
227
224
|
return script
|
228
225
|
|
229
|
-
def __run_script(self, *, parallel:
|
226
|
+
def __run_script(self, *, parallel: bool | None) -> Path | None:
|
230
227
|
"""Return the path to the (All)run script, or None if no run script is found."""
|
231
228
|
run = self.path / "run"
|
232
229
|
run_parallel = self.path / "run-parallel"
|
@@ -242,9 +239,8 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
242
239
|
elif parallel is False:
|
243
240
|
script = run if run.is_file() else all_run
|
244
241
|
else:
|
245
|
-
|
246
|
-
|
247
|
-
)
|
242
|
+
msg = "Both (All)run and (All)run-parallel scripts are present. Please specify parallel argument."
|
243
|
+
raise ValueError(msg)
|
248
244
|
else:
|
249
245
|
script = run if run.is_file() else all_run
|
250
246
|
elif parallel is not False and (
|
@@ -259,7 +255,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
259
255
|
|
260
256
|
return script
|
261
257
|
|
262
|
-
def __env(self, *, shell: bool) ->
|
258
|
+
def __env(self, *, shell: bool) -> Mapping[str, str] | None:
|
263
259
|
sip_workaround = os.environ.get(
|
264
260
|
"FOAM_LD_LIBRARY_PATH", ""
|
265
261
|
) and not os.environ.get("DYLD_LIBRARY_PATH", "")
|
@@ -278,8 +274,8 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
278
274
|
|
279
275
|
@contextmanager
|
280
276
|
def __output(
|
281
|
-
self, cmd:
|
282
|
-
) -> Generator[
|
277
|
+
self, cmd: Sequence[str | os.PathLike[str]] | str, *, log: bool
|
278
|
+
) -> Generator[tuple[int | IO[bytes], int | IO[bytes]], None, None]:
|
283
279
|
if log:
|
284
280
|
if isinstance(cmd, str):
|
285
281
|
name = shlex.split(cmd)[0]
|
@@ -299,7 +295,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
299
295
|
return ret
|
300
296
|
|
301
297
|
def _copy_calls(
|
302
|
-
self, dst:
|
298
|
+
self, dst: os.PathLike[str] | str | None
|
303
299
|
) -> Generator[Any, None, Self]:
|
304
300
|
if dst is None:
|
305
301
|
dst = self.__mkrundir()
|
@@ -321,7 +317,7 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
321
317
|
p.unlink()
|
322
318
|
|
323
319
|
def _clone_calls(
|
324
|
-
self, dst:
|
320
|
+
self, dst: os.PathLike[str] | str | None
|
325
321
|
) -> Generator[Any, None, Self]:
|
326
322
|
if dst is None:
|
327
323
|
dst = self.__mkrundir()
|
@@ -366,10 +362,10 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
366
362
|
|
367
363
|
def _run_calls(
|
368
364
|
self,
|
369
|
-
cmd:
|
365
|
+
cmd: Sequence[str | os.PathLike[str]] | str | None = None,
|
370
366
|
*,
|
371
|
-
parallel:
|
372
|
-
cpus:
|
367
|
+
parallel: bool | None,
|
368
|
+
cpus: int | None,
|
373
369
|
check: bool,
|
374
370
|
log: bool,
|
375
371
|
**kwargs: Any,
|
@@ -420,9 +416,8 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
420
416
|
cpus = self._nsubdomains
|
421
417
|
else:
|
422
418
|
cpus = 1
|
423
|
-
|
424
|
-
|
425
|
-
cpus = 1
|
419
|
+
elif cpus is None:
|
420
|
+
cpus = 1
|
426
421
|
|
427
422
|
yield self.run(
|
428
423
|
[script_path], parallel=False, cpus=cpus, check=check, **kwargs
|
@@ -450,9 +445,8 @@ class FoamCaseRunBase(FoamCaseBase):
|
|
450
445
|
|
451
446
|
if cpus is None:
|
452
447
|
cpus = max(self._nprocessors, 1)
|
453
|
-
|
454
|
-
|
455
|
-
cpus = 1
|
448
|
+
elif cpus is None:
|
449
|
+
cpus = 1
|
456
450
|
|
457
451
|
yield self.run(
|
458
452
|
[self.application],
|
@@ -1,6 +1,8 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import shutil
|
2
4
|
import sys
|
3
|
-
from typing import TYPE_CHECKING, Any
|
5
|
+
from typing import TYPE_CHECKING, Any
|
4
6
|
|
5
7
|
if sys.version_info >= (3, 9):
|
6
8
|
from collections.abc import Sequence
|
@@ -19,7 +21,7 @@ class AsyncSlurmFoamCase(AsyncFoamCase):
|
|
19
21
|
|
20
22
|
@staticmethod
|
21
23
|
async def _run(
|
22
|
-
cmd:
|
24
|
+
cmd: Sequence[str | os.PathLike[str]] | str,
|
23
25
|
*,
|
24
26
|
cpus: int,
|
25
27
|
fallback: bool = False,
|
@@ -42,10 +44,10 @@ class AsyncSlurmFoamCase(AsyncFoamCase):
|
|
42
44
|
|
43
45
|
async def run(
|
44
46
|
self,
|
45
|
-
cmd:
|
47
|
+
cmd: Sequence[str | os.PathLike[str]] | str | None = None,
|
46
48
|
*,
|
47
|
-
parallel:
|
48
|
-
cpus:
|
49
|
+
parallel: bool | None = None,
|
50
|
+
cpus: int | None = None,
|
49
51
|
check: bool = True,
|
50
52
|
log: bool = True,
|
51
53
|
fallback: bool = False,
|
@@ -1,8 +1,10 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import asyncio
|
2
4
|
import subprocess
|
3
5
|
import sys
|
4
6
|
from io import BytesIO
|
5
|
-
from typing import IO, TYPE_CHECKING
|
7
|
+
from typing import IO, TYPE_CHECKING
|
6
8
|
|
7
9
|
if TYPE_CHECKING:
|
8
10
|
import os
|
@@ -31,14 +33,14 @@ STDOUT = subprocess.STDOUT
|
|
31
33
|
|
32
34
|
|
33
35
|
def run_sync(
|
34
|
-
cmd:
|
36
|
+
cmd: Sequence[str | os.PathLike[str]] | str,
|
35
37
|
*,
|
36
38
|
check: bool = True,
|
37
|
-
cwd:
|
38
|
-
env:
|
39
|
-
stdout:
|
40
|
-
stderr:
|
41
|
-
) ->
|
39
|
+
cwd: os.PathLike[str] | None = None,
|
40
|
+
env: Mapping[str, str] | None = None,
|
41
|
+
stdout: int | IO[bytes] | None = None,
|
42
|
+
stderr: int | IO[bytes] | None = None,
|
43
|
+
) -> CompletedProcess[bytes]:
|
42
44
|
if not isinstance(cmd, str) and sys.version_info < (3, 8):
|
43
45
|
cmd = [str(arg) for arg in cmd]
|
44
46
|
|
@@ -87,14 +89,14 @@ def run_sync(
|
|
87
89
|
|
88
90
|
|
89
91
|
async def run_async(
|
90
|
-
cmd:
|
92
|
+
cmd: Sequence[str | os.PathLike[str]] | str,
|
91
93
|
*,
|
92
94
|
check: bool = True,
|
93
|
-
cwd:
|
94
|
-
env:
|
95
|
-
stdout:
|
96
|
-
stderr:
|
97
|
-
) ->
|
95
|
+
cwd: os.PathLike[str] | None = None,
|
96
|
+
env: Mapping[str, str] | None = None,
|
97
|
+
stdout: int | IO[bytes] | None = None,
|
98
|
+
stderr: int | IO[bytes] | None = None,
|
99
|
+
) -> CompletedProcess[bytes]:
|
98
100
|
if isinstance(cmd, str):
|
99
101
|
proc = await asyncio.create_subprocess_shell(
|
100
102
|
cmd,
|