foamlib 0.2.8__tar.gz → 0.2.10__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.2.8 → foamlib-0.2.10}/PKG-INFO +1 -1
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib/__init__.py +2 -2
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib/_cases.py +2 -2
- {foamlib-0.2.8/foamlib/_dictionaries → foamlib-0.2.10/foamlib/_files}/__init__.py +2 -1
- foamlib-0.2.10/foamlib/_files/_fields.py +158 -0
- foamlib-0.2.10/foamlib/_files/_files.py +203 -0
- foamlib-0.2.10/foamlib/_files/_io.py +73 -0
- {foamlib-0.2.8/foamlib/_dictionaries → foamlib-0.2.10/foamlib/_files}/_parsing.py +90 -92
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib.egg-info/PKG-INFO +1 -1
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib.egg-info/SOURCES.txt +7 -5
- foamlib-0.2.8/foamlib/_dictionaries/_files.py +0 -418
- {foamlib-0.2.8 → foamlib-0.2.10}/LICENSE.txt +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/README.md +0 -0
- {foamlib-0.2.8/foamlib/_dictionaries → foamlib-0.2.10/foamlib/_files}/_base.py +0 -0
- {foamlib-0.2.8/foamlib/_dictionaries → foamlib-0.2.10/foamlib/_files}/_serialization.py +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib/_util.py +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib/py.typed +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib.egg-info/dependency_links.txt +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib.egg-info/requires.txt +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/foamlib.egg-info/top_level.txt +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/pyproject.toml +0 -0
- {foamlib-0.2.8 → foamlib-0.2.10}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
"""A Python interface for interacting with OpenFOAM."""
|
2
2
|
|
3
|
-
__version__ = "0.2.
|
3
|
+
__version__ = "0.2.10"
|
4
4
|
|
5
5
|
from ._cases import AsyncFoamCase, FoamCase, FoamCaseBase
|
6
|
-
from .
|
6
|
+
from ._files import FoamDictionaryBase, FoamFieldFile, FoamFile
|
7
7
|
|
8
8
|
__all__ = [
|
9
9
|
"FoamCase",
|
@@ -27,7 +27,7 @@ else:
|
|
27
27
|
|
28
28
|
import aioshutil
|
29
29
|
|
30
|
-
from .
|
30
|
+
from ._files import FoamFieldFile, FoamFile
|
31
31
|
from ._util import CalledProcessError, is_sequence, run_process, run_process_async
|
32
32
|
|
33
33
|
|
@@ -505,7 +505,7 @@ class AsyncFoamCase(FoamCaseBase):
|
|
505
505
|
check: bool = True,
|
506
506
|
) -> None:
|
507
507
|
"""
|
508
|
-
Run this case.
|
508
|
+
Run this case, or a specified command in the context of this case.
|
509
509
|
|
510
510
|
: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.
|
511
511
|
:param script: If True and `cmd` is None, use an (All)run(-parallel) script if it exists for running the case. If False or no run script is found, autodetermine the command(s) needed to run the case.
|
@@ -0,0 +1,158 @@
|
|
1
|
+
import sys
|
2
|
+
from typing import Any, Tuple, Union, cast
|
3
|
+
|
4
|
+
if sys.version_info >= (3, 9):
|
5
|
+
from collections.abc import Sequence
|
6
|
+
else:
|
7
|
+
from typing import Sequence
|
8
|
+
|
9
|
+
from ._files import FoamFile
|
10
|
+
|
11
|
+
try:
|
12
|
+
import numpy as np
|
13
|
+
from numpy.typing import NDArray
|
14
|
+
except ModuleNotFoundError:
|
15
|
+
pass
|
16
|
+
|
17
|
+
|
18
|
+
class FoamFieldFile(FoamFile):
|
19
|
+
"""An OpenFOAM dictionary file representing a field as a mutable mapping."""
|
20
|
+
|
21
|
+
class BoundariesDictionary(FoamFile.Dictionary):
|
22
|
+
def __getitem__(self, keyword: str) -> "FoamFieldFile.BoundaryDictionary":
|
23
|
+
value = super().__getitem__(keyword)
|
24
|
+
if not isinstance(value, FoamFieldFile.BoundaryDictionary):
|
25
|
+
assert not isinstance(value, FoamFile.Dictionary)
|
26
|
+
raise TypeError(f"boundary {keyword} is not a dictionary")
|
27
|
+
return value
|
28
|
+
|
29
|
+
class BoundaryDictionary(FoamFile.Dictionary):
|
30
|
+
"""An OpenFOAM dictionary representing a boundary condition as a mutable mapping."""
|
31
|
+
|
32
|
+
def __setitem__(
|
33
|
+
self,
|
34
|
+
key: str,
|
35
|
+
value: FoamFile._SetValue,
|
36
|
+
) -> None:
|
37
|
+
if key == "value":
|
38
|
+
self._setitem(key, value, assume_field=True)
|
39
|
+
else:
|
40
|
+
self._setitem(key, value)
|
41
|
+
|
42
|
+
@property
|
43
|
+
def type(self) -> str:
|
44
|
+
"""Alias of `self["type"]`."""
|
45
|
+
ret = self["type"]
|
46
|
+
if not isinstance(ret, str):
|
47
|
+
raise TypeError("type is not a string")
|
48
|
+
return ret
|
49
|
+
|
50
|
+
@type.setter
|
51
|
+
def type(self, value: str) -> None:
|
52
|
+
self["type"] = value
|
53
|
+
|
54
|
+
@property
|
55
|
+
def value(
|
56
|
+
self,
|
57
|
+
) -> Union[
|
58
|
+
int,
|
59
|
+
float,
|
60
|
+
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
61
|
+
"NDArray[np.generic]",
|
62
|
+
]:
|
63
|
+
"""Alias of `self["value"]`."""
|
64
|
+
ret = self["value"]
|
65
|
+
if not isinstance(ret, (int, float, Sequence)):
|
66
|
+
raise TypeError("value is not a field")
|
67
|
+
return cast(Union[int, float, Sequence[Union[int, float]]], ret)
|
68
|
+
|
69
|
+
@value.setter
|
70
|
+
def value(
|
71
|
+
self,
|
72
|
+
value: Union[
|
73
|
+
int,
|
74
|
+
float,
|
75
|
+
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
76
|
+
"NDArray[np.generic]",
|
77
|
+
],
|
78
|
+
) -> None:
|
79
|
+
self["value"] = value
|
80
|
+
|
81
|
+
@value.deleter
|
82
|
+
def value(self) -> None:
|
83
|
+
del self["value"]
|
84
|
+
|
85
|
+
def __getitem__(
|
86
|
+
self, keywords: Union[str, Tuple[str, ...]]
|
87
|
+
) -> Union[FoamFile.Value, FoamFile.Dictionary]:
|
88
|
+
if not isinstance(keywords, tuple):
|
89
|
+
keywords = (keywords,)
|
90
|
+
|
91
|
+
ret = super().__getitem__(keywords)
|
92
|
+
if keywords[0] == "boundaryField" and isinstance(ret, FoamFile.Dictionary):
|
93
|
+
if len(keywords) == 1:
|
94
|
+
ret = FoamFieldFile.BoundariesDictionary(self, keywords)
|
95
|
+
elif len(keywords) == 2:
|
96
|
+
ret = FoamFieldFile.BoundaryDictionary(self, keywords)
|
97
|
+
return ret
|
98
|
+
|
99
|
+
def __setitem__(self, keywords: Union[str, Tuple[str, ...]], value: Any) -> None:
|
100
|
+
if not isinstance(keywords, tuple):
|
101
|
+
keywords = (keywords,)
|
102
|
+
|
103
|
+
if keywords == ("internalField",):
|
104
|
+
self._setitem(keywords, value, assume_field=True)
|
105
|
+
elif keywords == ("dimensions",):
|
106
|
+
self._setitem(keywords, value, assume_dimensions=True)
|
107
|
+
else:
|
108
|
+
self._setitem(keywords, value)
|
109
|
+
|
110
|
+
@property
|
111
|
+
def dimensions(self) -> FoamFile.DimensionSet:
|
112
|
+
"""Alias of `self["dimensions"]`."""
|
113
|
+
ret = self["dimensions"]
|
114
|
+
if not isinstance(ret, FoamFile.DimensionSet):
|
115
|
+
raise TypeError("dimensions is not a DimensionSet")
|
116
|
+
return ret
|
117
|
+
|
118
|
+
@dimensions.setter
|
119
|
+
def dimensions(
|
120
|
+
self, value: Union[FoamFile.DimensionSet, Sequence[Union[int, float]]]
|
121
|
+
) -> None:
|
122
|
+
self["dimensions"] = value
|
123
|
+
|
124
|
+
@property
|
125
|
+
def internal_field(
|
126
|
+
self,
|
127
|
+
) -> Union[
|
128
|
+
int,
|
129
|
+
float,
|
130
|
+
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
131
|
+
"NDArray[np.generic]",
|
132
|
+
]:
|
133
|
+
"""Alias of `self["internalField"]`."""
|
134
|
+
ret = self["internalField"]
|
135
|
+
if not isinstance(ret, (int, float, Sequence)):
|
136
|
+
raise TypeError("internalField is not a field")
|
137
|
+
return cast(Union[int, float, Sequence[Union[int, float]]], ret)
|
138
|
+
|
139
|
+
@internal_field.setter
|
140
|
+
def internal_field(
|
141
|
+
self,
|
142
|
+
value: Union[
|
143
|
+
int,
|
144
|
+
float,
|
145
|
+
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
146
|
+
"NDArray[np.generic]",
|
147
|
+
],
|
148
|
+
) -> None:
|
149
|
+
self["internalField"] = value
|
150
|
+
|
151
|
+
@property
|
152
|
+
def boundary_field(self) -> "FoamFieldFile.BoundariesDictionary":
|
153
|
+
"""Alias of `self["boundaryField"]`."""
|
154
|
+
ret = self["boundaryField"]
|
155
|
+
if not isinstance(ret, FoamFieldFile.BoundariesDictionary):
|
156
|
+
assert not isinstance(ret, FoamFile.Dictionary)
|
157
|
+
raise TypeError("boundaryField is not a dictionary")
|
158
|
+
return ret
|
@@ -0,0 +1,203 @@
|
|
1
|
+
import sys
|
2
|
+
from typing import (
|
3
|
+
Any,
|
4
|
+
Tuple,
|
5
|
+
Union,
|
6
|
+
)
|
7
|
+
|
8
|
+
if sys.version_info >= (3, 9):
|
9
|
+
from collections.abc import Iterator, Mapping, MutableMapping
|
10
|
+
else:
|
11
|
+
from typing import Iterator, Mapping, MutableMapping
|
12
|
+
|
13
|
+
from ._base import FoamDictionaryBase
|
14
|
+
from ._io import FoamFileIO
|
15
|
+
from ._serialization import serialize_entry
|
16
|
+
|
17
|
+
|
18
|
+
class FoamFile(
|
19
|
+
FoamDictionaryBase,
|
20
|
+
MutableMapping[
|
21
|
+
Union[str, Tuple[str, ...]], Union["FoamFile.Value", "FoamFile.Dictionary"]
|
22
|
+
],
|
23
|
+
FoamFileIO,
|
24
|
+
):
|
25
|
+
"""
|
26
|
+
An OpenFOAM dictionary file.
|
27
|
+
|
28
|
+
Use as a mutable mapping (i.e., like a dict) to access and modify entries.
|
29
|
+
|
30
|
+
Use as a context manager to make multiple changes to the file while saving all changes only once at the end.
|
31
|
+
"""
|
32
|
+
|
33
|
+
class Dictionary(
|
34
|
+
FoamDictionaryBase,
|
35
|
+
MutableMapping[str, Union["FoamFile.Value", "FoamFile.Dictionary"]],
|
36
|
+
):
|
37
|
+
"""An OpenFOAM dictionary within a file as a mutable mapping."""
|
38
|
+
|
39
|
+
def __init__(self, _file: "FoamFile", _keywords: Tuple[str, ...]) -> None:
|
40
|
+
self._file = _file
|
41
|
+
self._keywords = _keywords
|
42
|
+
|
43
|
+
def __getitem__(
|
44
|
+
self, keyword: str
|
45
|
+
) -> Union["FoamFile.Value", "FoamFile.Dictionary"]:
|
46
|
+
return self._file[(*self._keywords, keyword)]
|
47
|
+
|
48
|
+
def _setitem(
|
49
|
+
self,
|
50
|
+
keyword: str,
|
51
|
+
value: Any,
|
52
|
+
*,
|
53
|
+
assume_field: bool = False,
|
54
|
+
assume_dimensions: bool = False,
|
55
|
+
) -> None:
|
56
|
+
self._file._setitem(
|
57
|
+
(*self._keywords, keyword),
|
58
|
+
value,
|
59
|
+
assume_field=assume_field,
|
60
|
+
assume_dimensions=assume_dimensions,
|
61
|
+
)
|
62
|
+
|
63
|
+
def __setitem__(self, keyword: str, value: "FoamFile._SetValue") -> None:
|
64
|
+
self._setitem(keyword, value)
|
65
|
+
|
66
|
+
def __delitem__(self, keyword: str) -> None:
|
67
|
+
del self._file[(*self._keywords, keyword)]
|
68
|
+
|
69
|
+
def __iter__(self) -> Iterator[str]:
|
70
|
+
return self._file._iter(self._keywords)
|
71
|
+
|
72
|
+
def __contains__(self, keyword: object) -> bool:
|
73
|
+
return (*self._keywords, keyword) in self._file
|
74
|
+
|
75
|
+
def __len__(self) -> int:
|
76
|
+
return len(list(iter(self)))
|
77
|
+
|
78
|
+
def update(self, *args: Any, **kwargs: Any) -> None:
|
79
|
+
with self._file:
|
80
|
+
super().update(*args, **kwargs)
|
81
|
+
|
82
|
+
def clear(self) -> None:
|
83
|
+
with self._file:
|
84
|
+
super().clear()
|
85
|
+
|
86
|
+
def __repr__(self) -> str:
|
87
|
+
return f"{type(self).__qualname__}({self._file}, {self._keywords})"
|
88
|
+
|
89
|
+
def as_dict(self) -> FoamDictionaryBase._Dict:
|
90
|
+
"""Return a nested dict representation of the dictionary."""
|
91
|
+
ret = self._file.as_dict()
|
92
|
+
|
93
|
+
for k in self._keywords:
|
94
|
+
assert isinstance(ret, dict)
|
95
|
+
v = ret[k]
|
96
|
+
assert isinstance(v, dict)
|
97
|
+
ret = v
|
98
|
+
|
99
|
+
return ret
|
100
|
+
|
101
|
+
def __getitem__(
|
102
|
+
self, keywords: Union[str, Tuple[str, ...]]
|
103
|
+
) -> Union["FoamFile.Value", "FoamFile.Dictionary"]:
|
104
|
+
if not isinstance(keywords, tuple):
|
105
|
+
keywords = (keywords,)
|
106
|
+
|
107
|
+
_, parsed = self._read()
|
108
|
+
|
109
|
+
value = parsed[keywords]
|
110
|
+
|
111
|
+
if value is ...:
|
112
|
+
return FoamFile.Dictionary(self, keywords)
|
113
|
+
else:
|
114
|
+
return value # type: ignore [return-value]
|
115
|
+
|
116
|
+
def _setitem(
|
117
|
+
self,
|
118
|
+
keywords: Union[str, Tuple[str, ...]],
|
119
|
+
value: "FoamFile._SetValue",
|
120
|
+
*,
|
121
|
+
assume_field: bool = False,
|
122
|
+
assume_dimensions: bool = False,
|
123
|
+
) -> None:
|
124
|
+
if not isinstance(keywords, tuple):
|
125
|
+
keywords = (keywords,)
|
126
|
+
|
127
|
+
contents, parsed = self._read()
|
128
|
+
|
129
|
+
if isinstance(value, Mapping):
|
130
|
+
with self:
|
131
|
+
if isinstance(value, FoamDictionaryBase):
|
132
|
+
value = value.as_dict()
|
133
|
+
|
134
|
+
start, end = parsed.entry_location(keywords, missing_ok=True)
|
135
|
+
|
136
|
+
self._write(
|
137
|
+
f"{contents[:start]}\n{serialize_entry(keywords[-1], {})}\n{contents[end:]}"
|
138
|
+
)
|
139
|
+
|
140
|
+
for k, v in value.items():
|
141
|
+
self[(*keywords, k)] = v
|
142
|
+
else:
|
143
|
+
start, end = parsed.entry_location(keywords, missing_ok=True)
|
144
|
+
|
145
|
+
self._write(
|
146
|
+
f"{contents[:start]}\n{serialize_entry(keywords[-1], value, assume_field=assume_field, assume_dimensions=assume_dimensions)}\n{contents[end:]}"
|
147
|
+
)
|
148
|
+
|
149
|
+
def __setitem__(
|
150
|
+
self,
|
151
|
+
keywords: Union[str, Tuple[str, ...]],
|
152
|
+
value: "FoamFile._SetValue",
|
153
|
+
) -> None:
|
154
|
+
self._setitem(keywords, value)
|
155
|
+
|
156
|
+
def __delitem__(self, keywords: Union[str, Tuple[str, ...]]) -> None:
|
157
|
+
if not isinstance(keywords, tuple):
|
158
|
+
keywords = (keywords,)
|
159
|
+
|
160
|
+
contents, parsed = self._read()
|
161
|
+
|
162
|
+
start, end = parsed.entry_location(keywords)
|
163
|
+
|
164
|
+
self._write(contents[:start] + contents[end:])
|
165
|
+
|
166
|
+
def _iter(self, keywords: Union[str, Tuple[str, ...]] = ()) -> Iterator[str]:
|
167
|
+
if not isinstance(keywords, tuple):
|
168
|
+
keywords = (keywords,)
|
169
|
+
|
170
|
+
_, parsed = self._read()
|
171
|
+
|
172
|
+
yield from (k[-1] for k in parsed if k[:-1] == keywords)
|
173
|
+
|
174
|
+
def __iter__(self) -> Iterator[str]:
|
175
|
+
return self._iter()
|
176
|
+
|
177
|
+
def __contains__(self, keywords: object) -> bool:
|
178
|
+
if not isinstance(keywords, tuple):
|
179
|
+
keywords = (keywords,)
|
180
|
+
_, parsed = self._read()
|
181
|
+
return keywords in parsed
|
182
|
+
|
183
|
+
def __len__(self) -> int:
|
184
|
+
return len(list(iter(self)))
|
185
|
+
|
186
|
+
def update(self, *args: Any, **kwargs: Any) -> None:
|
187
|
+
with self:
|
188
|
+
super().update(*args, **kwargs)
|
189
|
+
|
190
|
+
def clear(self) -> None:
|
191
|
+
with self:
|
192
|
+
super().clear()
|
193
|
+
|
194
|
+
def __fspath__(self) -> str:
|
195
|
+
return str(self.path)
|
196
|
+
|
197
|
+
def __repr__(self) -> str:
|
198
|
+
return f"{type(self).__name__}({self.path})"
|
199
|
+
|
200
|
+
def as_dict(self) -> FoamDictionaryBase._Dict:
|
201
|
+
"""Return a nested dict representation of the file."""
|
202
|
+
_, parsed = self._read()
|
203
|
+
return parsed.as_dict()
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import sys
|
2
|
+
from copy import deepcopy
|
3
|
+
from pathlib import Path
|
4
|
+
from types import TracebackType
|
5
|
+
from typing import (
|
6
|
+
Optional,
|
7
|
+
Tuple,
|
8
|
+
Type,
|
9
|
+
Union,
|
10
|
+
)
|
11
|
+
|
12
|
+
if sys.version_info >= (3, 11):
|
13
|
+
from typing import Self
|
14
|
+
else:
|
15
|
+
from typing_extensions import Self
|
16
|
+
|
17
|
+
from ._parsing import Parsed
|
18
|
+
|
19
|
+
|
20
|
+
class FoamFileIO:
|
21
|
+
def __init__(self, path: Union[str, Path]) -> None:
|
22
|
+
self.path = Path(path).absolute()
|
23
|
+
if self.path.is_dir():
|
24
|
+
raise IsADirectoryError(self.path)
|
25
|
+
elif not self.path.is_file():
|
26
|
+
raise FileNotFoundError(self.path)
|
27
|
+
|
28
|
+
self.__contents: Optional[str] = None
|
29
|
+
self.__parsed: Optional[Parsed] = None
|
30
|
+
self.__defer_io = 0
|
31
|
+
self.__dirty = False
|
32
|
+
|
33
|
+
def __enter__(self) -> Self:
|
34
|
+
if self.__defer_io == 0:
|
35
|
+
self._read()
|
36
|
+
self.__defer_io += 1
|
37
|
+
return self
|
38
|
+
|
39
|
+
def __exit__(
|
40
|
+
self,
|
41
|
+
exc_type: Optional[Type[BaseException]],
|
42
|
+
exc_val: Optional[BaseException],
|
43
|
+
exc_tb: Optional[TracebackType],
|
44
|
+
) -> None:
|
45
|
+
self.__defer_io -= 1
|
46
|
+
if self.__defer_io == 0 and self.__dirty:
|
47
|
+
assert self.__contents is not None
|
48
|
+
self._write(self.__contents)
|
49
|
+
assert not self.__dirty
|
50
|
+
|
51
|
+
def _read(self) -> Tuple[str, Parsed]:
|
52
|
+
if not self.__defer_io:
|
53
|
+
contents = self.path.read_text()
|
54
|
+
if contents != self.__contents:
|
55
|
+
self.__contents = contents
|
56
|
+
self.__parsed = None
|
57
|
+
|
58
|
+
assert self.__contents is not None
|
59
|
+
|
60
|
+
if self.__parsed is None:
|
61
|
+
parsed = Parsed(self.__contents)
|
62
|
+
self.__parsed = parsed
|
63
|
+
|
64
|
+
return self.__contents, deepcopy(self.__parsed)
|
65
|
+
|
66
|
+
def _write(self, contents: str) -> None:
|
67
|
+
self.__contents = contents
|
68
|
+
self.__parsed = None
|
69
|
+
if not self.__defer_io:
|
70
|
+
self.path.write_text(contents)
|
71
|
+
self.__dirty = False
|
72
|
+
else:
|
73
|
+
self.__dirty = True
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import sys
|
2
|
-
from typing import
|
2
|
+
from typing import Tuple, Union
|
3
3
|
|
4
4
|
if sys.version_info >= (3, 9):
|
5
|
-
from collections.abc import Mapping, MutableMapping, Sequence
|
5
|
+
from collections.abc import Iterator, Mapping, MutableMapping, Sequence
|
6
6
|
else:
|
7
|
-
from typing import Mapping, MutableMapping, Sequence
|
7
|
+
from typing import Iterator, Mapping, MutableMapping, Sequence
|
8
8
|
|
9
9
|
if sys.version_info >= (3, 10):
|
10
10
|
from types import EllipsisType
|
@@ -33,15 +33,6 @@ from pyparsing import (
|
|
33
33
|
|
34
34
|
from ._base import FoamDictionaryBase
|
35
35
|
|
36
|
-
_SWITCH = (
|
37
|
-
Keyword("yes") | Keyword("true") | Keyword("on") | Keyword("y") | Keyword("t")
|
38
|
-
).set_parse_action(lambda: True) | (
|
39
|
-
Keyword("no") | Keyword("false") | Keyword("off") | Keyword("n") | Keyword("f")
|
40
|
-
).set_parse_action(lambda: False)
|
41
|
-
_DIMENSIONS = (
|
42
|
-
Literal("[").suppress() + common.number * 7 + Literal("]").suppress()
|
43
|
-
).set_parse_action(lambda tks: FoamDictionaryBase.DimensionSet(*tks))
|
44
|
-
|
45
36
|
|
46
37
|
def _list_of(elem: ParserElement) -> ParserElement:
|
47
38
|
return Opt(
|
@@ -83,6 +74,15 @@ def _dictionary_of(
|
|
83
74
|
return Dict(Group(entry)[len], asdict=not located)
|
84
75
|
|
85
76
|
|
77
|
+
_SWITCH = (
|
78
|
+
Keyword("yes") | Keyword("true") | Keyword("on") | Keyword("y") | Keyword("t")
|
79
|
+
).set_parse_action(lambda: True) | (
|
80
|
+
Keyword("no") | Keyword("false") | Keyword("off") | Keyword("n") | Keyword("f")
|
81
|
+
).set_parse_action(lambda: False)
|
82
|
+
_DIMENSIONS = (
|
83
|
+
Literal("[").suppress() + common.number * 7 + Literal("]").suppress()
|
84
|
+
).set_parse_action(lambda tks: FoamDictionaryBase.DimensionSet(*tks))
|
85
|
+
|
86
86
|
_TENSOR = _list_of(common.number) | common.number
|
87
87
|
_IDENTIFIER = Word(identbodychars + "$", printables.replace(";", ""))
|
88
88
|
_DIMENSIONED = (Opt(_IDENTIFIER) + _DIMENSIONS + _TENSOR).set_parse_action(
|
@@ -110,89 +110,87 @@ _FILE = (
|
|
110
110
|
.ignore(Literal("#include") + ... + LineEnd()) # type: ignore [no-untyped-call]
|
111
111
|
)
|
112
112
|
|
113
|
-
Parsed = Mapping[Sequence[str], Tuple[int, Optional[FoamDictionaryBase.Value], int]]
|
114
|
-
|
115
|
-
|
116
|
-
def _flatten_result(
|
117
|
-
parse_result: ParseResults, *, _keywords: Sequence[str] = ()
|
118
|
-
) -> Parsed:
|
119
|
-
ret: MutableMapping[
|
120
|
-
Sequence[str], Tuple[int, Optional[FoamDictionaryBase.Value], int]
|
121
|
-
] = {}
|
122
|
-
start = parse_result.locn_start
|
123
|
-
assert isinstance(start, int)
|
124
|
-
item = parse_result.value
|
125
|
-
assert isinstance(item, Sequence)
|
126
|
-
end = parse_result.locn_end
|
127
|
-
assert isinstance(end, int)
|
128
|
-
key, *values = item
|
129
|
-
assert isinstance(key, str)
|
130
|
-
ret[(*_keywords, key)] = (start, None, end)
|
131
|
-
for value in values:
|
132
|
-
if isinstance(value, ParseResults):
|
133
|
-
ret.update(_flatten_result(value, _keywords=(*_keywords, key)))
|
134
|
-
else:
|
135
|
-
ret[(*_keywords, key)] = (start, value, end)
|
136
|
-
return ret
|
137
|
-
|
138
|
-
|
139
|
-
def parse(
|
140
|
-
contents: str,
|
141
|
-
) -> Parsed:
|
142
|
-
parse_results = _FILE.parse_string(contents, parse_all=True)
|
143
|
-
ret: MutableMapping[
|
144
|
-
Sequence[str], Tuple[int, Optional[FoamDictionaryBase.Value], int]
|
145
|
-
] = {}
|
146
|
-
for parse_result in parse_results:
|
147
|
-
ret.update(_flatten_result(parse_result))
|
148
|
-
return ret
|
149
|
-
|
150
|
-
|
151
|
-
def get_value(
|
152
|
-
parsed: Parsed,
|
153
|
-
keywords: Tuple[str, ...],
|
154
|
-
) -> Optional[FoamDictionaryBase.Value]:
|
155
|
-
"""Value of an entry."""
|
156
|
-
_, value, _ = parsed[keywords]
|
157
|
-
return value
|
158
|
-
|
159
|
-
|
160
|
-
def get_entry_locn(
|
161
|
-
parsed: Parsed,
|
162
|
-
keywords: Tuple[str, ...],
|
163
|
-
*,
|
164
|
-
missing_ok: bool = False,
|
165
|
-
) -> Tuple[int, int]:
|
166
|
-
"""Location of an entry or where it should be inserted."""
|
167
|
-
try:
|
168
|
-
start, _, end = parsed[keywords]
|
169
|
-
except KeyError:
|
170
|
-
if missing_ok:
|
171
|
-
if len(keywords) > 1:
|
172
|
-
_, _, end = parsed[keywords[:-1]]
|
173
|
-
end -= 1
|
174
|
-
else:
|
175
|
-
end = -1
|
176
113
|
|
177
|
-
|
178
|
-
|
179
|
-
|
114
|
+
class Parsed(Mapping[Tuple[str, ...], Union[FoamDictionaryBase.Value, EllipsisType]]):
|
115
|
+
def __init__(self, contents: str) -> None:
|
116
|
+
self._parsed: MutableMapping[
|
117
|
+
Tuple[str, ...],
|
118
|
+
Tuple[int, Union[FoamDictionaryBase.Value, EllipsisType], int],
|
119
|
+
] = {}
|
120
|
+
for parse_result in _FILE.parse_string(contents, parse_all=True):
|
121
|
+
self._parsed.update(self._flatten_result(parse_result))
|
122
|
+
|
123
|
+
@staticmethod
|
124
|
+
def _flatten_result(
|
125
|
+
parse_result: ParseResults, *, _keywords: Tuple[str, ...] = ()
|
126
|
+
) -> Mapping[
|
127
|
+
Tuple[str, ...], Tuple[int, Union[FoamDictionaryBase.Value, EllipsisType], int]
|
128
|
+
]:
|
129
|
+
ret: MutableMapping[
|
130
|
+
Tuple[str, ...],
|
131
|
+
Tuple[int, Union[FoamDictionaryBase.Value, EllipsisType], int],
|
132
|
+
] = {}
|
133
|
+
start = parse_result.locn_start
|
134
|
+
assert isinstance(start, int)
|
135
|
+
item = parse_result.value
|
136
|
+
assert isinstance(item, Sequence)
|
137
|
+
end = parse_result.locn_end
|
138
|
+
assert isinstance(end, int)
|
139
|
+
key, *values = item
|
140
|
+
assert isinstance(key, str)
|
141
|
+
ret[(*_keywords, key)] = (start, ..., end)
|
142
|
+
for value in values:
|
143
|
+
if isinstance(value, ParseResults):
|
144
|
+
ret.update(Parsed._flatten_result(value, _keywords=(*_keywords, key)))
|
145
|
+
else:
|
146
|
+
ret[(*_keywords, key)] = (start, value, end)
|
147
|
+
return ret
|
148
|
+
|
149
|
+
def __getitem__(
|
150
|
+
self, keywords: Tuple[str, ...]
|
151
|
+
) -> Union[FoamDictionaryBase.Value, EllipsisType]:
|
152
|
+
_, value, _ = self._parsed[keywords]
|
153
|
+
return value
|
154
|
+
|
155
|
+
def __contains__(self, keywords: object) -> bool:
|
156
|
+
return keywords in self._parsed
|
157
|
+
|
158
|
+
def __iter__(self) -> Iterator[Tuple[str, ...]]:
|
159
|
+
return iter(self._parsed)
|
160
|
+
|
161
|
+
def __len__(self) -> int:
|
162
|
+
return len(self._parsed)
|
163
|
+
|
164
|
+
def entry_location(
|
165
|
+
self, keywords: Tuple[str, ...], *, missing_ok: bool = False
|
166
|
+
) -> Tuple[int, int]:
|
167
|
+
try:
|
168
|
+
start, _, end = self._parsed[keywords]
|
169
|
+
except KeyError:
|
170
|
+
if missing_ok:
|
171
|
+
if len(keywords) > 1:
|
172
|
+
_, _, end = self._parsed[keywords[:-1]]
|
173
|
+
end -= 1
|
174
|
+
else:
|
175
|
+
end = -1
|
176
|
+
|
177
|
+
start = end
|
178
|
+
else:
|
179
|
+
raise
|
180
180
|
|
181
|
-
|
181
|
+
return start, end
|
182
182
|
|
183
|
+
def as_dict(self) -> FoamDictionaryBase._Dict:
|
184
|
+
ret: FoamDictionaryBase._Dict = {}
|
185
|
+
for keywords, (_, value, _) in self._parsed.items():
|
186
|
+
r = ret
|
187
|
+
for k in keywords[:-1]:
|
188
|
+
assert isinstance(r, dict)
|
189
|
+
v = r[k]
|
190
|
+
assert isinstance(v, dict)
|
191
|
+
r = v
|
183
192
|
|
184
|
-
def as_dict(parsed: Parsed) -> FoamDictionaryBase._Dict:
|
185
|
-
"""Return a nested dict representation of the file."""
|
186
|
-
ret: FoamDictionaryBase._Dict = {}
|
187
|
-
for keywords, (_, value, _) in parsed.items():
|
188
|
-
r = ret
|
189
|
-
for k in keywords[:-1]:
|
190
193
|
assert isinstance(r, dict)
|
191
|
-
|
192
|
-
assert isinstance(v, dict)
|
193
|
-
r = v
|
194
|
-
|
195
|
-
assert isinstance(r, dict)
|
196
|
-
r[keywords[-1]] = {} if value is None else value
|
194
|
+
r[keywords[-1]] = {} if value is ... else value # type: ignore [assignment]
|
197
195
|
|
198
|
-
|
196
|
+
return ret
|
@@ -10,8 +10,10 @@ foamlib.egg-info/SOURCES.txt
|
|
10
10
|
foamlib.egg-info/dependency_links.txt
|
11
11
|
foamlib.egg-info/requires.txt
|
12
12
|
foamlib.egg-info/top_level.txt
|
13
|
-
foamlib/
|
14
|
-
foamlib/
|
15
|
-
foamlib/
|
16
|
-
foamlib/
|
17
|
-
foamlib/
|
13
|
+
foamlib/_files/__init__.py
|
14
|
+
foamlib/_files/_base.py
|
15
|
+
foamlib/_files/_fields.py
|
16
|
+
foamlib/_files/_files.py
|
17
|
+
foamlib/_files/_io.py
|
18
|
+
foamlib/_files/_parsing.py
|
19
|
+
foamlib/_files/_serialization.py
|
@@ -1,418 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
from pathlib import Path
|
3
|
-
from types import TracebackType
|
4
|
-
from typing import (
|
5
|
-
Any,
|
6
|
-
Optional,
|
7
|
-
Tuple,
|
8
|
-
Type,
|
9
|
-
Union,
|
10
|
-
cast,
|
11
|
-
)
|
12
|
-
|
13
|
-
if sys.version_info >= (3, 9):
|
14
|
-
from collections.abc import Iterator, Mapping, MutableMapping, Sequence
|
15
|
-
else:
|
16
|
-
from typing import Iterator, Mapping, MutableMapping, Sequence
|
17
|
-
|
18
|
-
if sys.version_info >= (3, 11):
|
19
|
-
from typing import Self
|
20
|
-
else:
|
21
|
-
from typing_extensions import Self
|
22
|
-
|
23
|
-
try:
|
24
|
-
import numpy as np
|
25
|
-
from numpy.typing import NDArray
|
26
|
-
except ModuleNotFoundError:
|
27
|
-
pass
|
28
|
-
|
29
|
-
from ._base import FoamDictionaryBase
|
30
|
-
from ._parsing import Parsed, as_dict, get_entry_locn, get_value, parse
|
31
|
-
from ._serialization import serialize_entry
|
32
|
-
|
33
|
-
|
34
|
-
class _FoamFileBase:
|
35
|
-
def __init__(self, path: Union[str, Path]) -> None:
|
36
|
-
self.path = Path(path).absolute()
|
37
|
-
if self.path.is_dir():
|
38
|
-
raise IsADirectoryError(self.path)
|
39
|
-
elif not self.path.is_file():
|
40
|
-
raise FileNotFoundError(self.path)
|
41
|
-
|
42
|
-
self.__contents: Optional[str] = None
|
43
|
-
self.__parsed: Optional[Parsed] = None
|
44
|
-
self.__defer_io = 0
|
45
|
-
self.__dirty = False
|
46
|
-
|
47
|
-
def __enter__(self) -> Self:
|
48
|
-
if self.__defer_io == 0:
|
49
|
-
self._read()
|
50
|
-
self.__defer_io += 1
|
51
|
-
return self
|
52
|
-
|
53
|
-
def __exit__(
|
54
|
-
self,
|
55
|
-
exc_type: Optional[Type[BaseException]],
|
56
|
-
exc_val: Optional[BaseException],
|
57
|
-
exc_tb: Optional[TracebackType],
|
58
|
-
) -> None:
|
59
|
-
self.__defer_io -= 1
|
60
|
-
if self.__defer_io == 0 and self.__dirty:
|
61
|
-
assert self.__contents is not None
|
62
|
-
self._write(self.__contents)
|
63
|
-
assert not self.__dirty
|
64
|
-
|
65
|
-
def _read(self) -> Tuple[str, Parsed]:
|
66
|
-
if not self.__defer_io:
|
67
|
-
contents = self.path.read_text()
|
68
|
-
if contents != self.__contents:
|
69
|
-
self.__contents = contents
|
70
|
-
self.__parsed = None
|
71
|
-
|
72
|
-
assert self.__contents is not None
|
73
|
-
|
74
|
-
if self.__parsed is None:
|
75
|
-
self.__parsed = parse(self.__contents)
|
76
|
-
|
77
|
-
return self.__contents, self.__parsed
|
78
|
-
|
79
|
-
def _write(self, contents: str) -> None:
|
80
|
-
self.__contents = contents
|
81
|
-
self.__parsed = None
|
82
|
-
if not self.__defer_io:
|
83
|
-
self.path.write_text(contents)
|
84
|
-
self.__dirty = False
|
85
|
-
else:
|
86
|
-
self.__dirty = True
|
87
|
-
|
88
|
-
|
89
|
-
class FoamFile(
|
90
|
-
_FoamFileBase,
|
91
|
-
FoamDictionaryBase,
|
92
|
-
MutableMapping[
|
93
|
-
Union[str, Tuple[str, ...]], Union["FoamFile.Value", "FoamFile.Dictionary"]
|
94
|
-
],
|
95
|
-
):
|
96
|
-
"""
|
97
|
-
An OpenFOAM dictionary file.
|
98
|
-
|
99
|
-
Use as a mutable mapping (i.e., like a dict) to access and modify entries.
|
100
|
-
|
101
|
-
Use as a context manager to make multiple changes to the file while saving all changes only once at the end.
|
102
|
-
"""
|
103
|
-
|
104
|
-
class Dictionary(
|
105
|
-
FoamDictionaryBase,
|
106
|
-
MutableMapping[str, Union["FoamFile.Value", "FoamFile.Dictionary"]],
|
107
|
-
):
|
108
|
-
"""An OpenFOAM dictionary within a file as a mutable mapping."""
|
109
|
-
|
110
|
-
def __init__(self, _file: "FoamFile", _keywords: Sequence[str]) -> None:
|
111
|
-
self._file = _file
|
112
|
-
self._keywords = _keywords
|
113
|
-
|
114
|
-
def __getitem__(
|
115
|
-
self, keyword: str
|
116
|
-
) -> Union["FoamFile.Value", "FoamFile.Dictionary"]:
|
117
|
-
return self._file[(*self._keywords, keyword)]
|
118
|
-
|
119
|
-
def _setitem(
|
120
|
-
self,
|
121
|
-
keyword: str,
|
122
|
-
value: Any,
|
123
|
-
*,
|
124
|
-
assume_field: bool = False,
|
125
|
-
assume_dimensions: bool = False,
|
126
|
-
) -> None:
|
127
|
-
self._file._setitem(
|
128
|
-
(*self._keywords, keyword),
|
129
|
-
value,
|
130
|
-
assume_field=assume_field,
|
131
|
-
assume_dimensions=assume_dimensions,
|
132
|
-
)
|
133
|
-
|
134
|
-
def __setitem__(self, keyword: str, value: "FoamFile._SetValue") -> None:
|
135
|
-
self._setitem(keyword, value)
|
136
|
-
|
137
|
-
def __delitem__(self, keyword: str) -> None:
|
138
|
-
del self._file[(*self._keywords, keyword)]
|
139
|
-
|
140
|
-
def __iter__(self) -> Iterator[str]:
|
141
|
-
return self._file._iter(tuple(self._keywords))
|
142
|
-
|
143
|
-
def __contains__(self, keyword: object) -> bool:
|
144
|
-
return (*self._keywords, keyword) in self._file
|
145
|
-
|
146
|
-
def __len__(self) -> int:
|
147
|
-
return len(list(iter(self)))
|
148
|
-
|
149
|
-
def update(self, *args: Any, **kwargs: Any) -> None:
|
150
|
-
with self._file:
|
151
|
-
super().update(*args, **kwargs)
|
152
|
-
|
153
|
-
def clear(self) -> None:
|
154
|
-
with self._file:
|
155
|
-
super().clear()
|
156
|
-
|
157
|
-
def __repr__(self) -> str:
|
158
|
-
return f"{type(self).__qualname__}({self._file}, {self._keywords})"
|
159
|
-
|
160
|
-
def as_dict(self) -> FoamDictionaryBase._Dict:
|
161
|
-
"""Return a nested dict representation of the dictionary."""
|
162
|
-
ret = self._file.as_dict()
|
163
|
-
|
164
|
-
for k in self._keywords:
|
165
|
-
assert isinstance(ret, dict)
|
166
|
-
v = ret[k]
|
167
|
-
assert isinstance(v, dict)
|
168
|
-
ret = v
|
169
|
-
|
170
|
-
return ret
|
171
|
-
|
172
|
-
def __getitem__(
|
173
|
-
self, keywords: Union[str, Tuple[str, ...]]
|
174
|
-
) -> Union["FoamFile.Value", "FoamFile.Dictionary"]:
|
175
|
-
if not isinstance(keywords, tuple):
|
176
|
-
keywords = (keywords,)
|
177
|
-
|
178
|
-
_, parsed = self._read()
|
179
|
-
|
180
|
-
value = get_value(parsed, keywords)
|
181
|
-
|
182
|
-
if value is None:
|
183
|
-
return FoamFile.Dictionary(self, keywords)
|
184
|
-
else:
|
185
|
-
return value
|
186
|
-
|
187
|
-
def _setitem(
|
188
|
-
self,
|
189
|
-
keywords: Union[str, Tuple[str, ...]],
|
190
|
-
value: "FoamFile._SetValue",
|
191
|
-
*,
|
192
|
-
assume_field: bool = False,
|
193
|
-
assume_dimensions: bool = False,
|
194
|
-
) -> None:
|
195
|
-
if not isinstance(keywords, tuple):
|
196
|
-
keywords = (keywords,)
|
197
|
-
|
198
|
-
contents, parsed = self._read()
|
199
|
-
|
200
|
-
if isinstance(value, Mapping):
|
201
|
-
with self:
|
202
|
-
if isinstance(value, FoamDictionaryBase):
|
203
|
-
value = value.as_dict()
|
204
|
-
|
205
|
-
start, end = get_entry_locn(parsed, keywords, missing_ok=True)
|
206
|
-
|
207
|
-
self._write(
|
208
|
-
f"{contents[:start]}\n{serialize_entry(keywords[-1], {})}\n{contents[end:]}"
|
209
|
-
)
|
210
|
-
|
211
|
-
for k, v in value.items():
|
212
|
-
self[(*keywords, k)] = v
|
213
|
-
else:
|
214
|
-
start, end = get_entry_locn(parsed, keywords, missing_ok=True)
|
215
|
-
|
216
|
-
self._write(
|
217
|
-
f"{contents[:start]}\n{serialize_entry(keywords[-1], value, assume_field=assume_field, assume_dimensions=assume_dimensions)}\n{contents[end:]}"
|
218
|
-
)
|
219
|
-
|
220
|
-
def __setitem__(
|
221
|
-
self,
|
222
|
-
keywords: Union[str, Tuple[str, ...]],
|
223
|
-
value: "FoamFile._SetValue",
|
224
|
-
) -> None:
|
225
|
-
self._setitem(keywords, value)
|
226
|
-
|
227
|
-
def __delitem__(self, keywords: Union[str, Tuple[str, ...]]) -> None:
|
228
|
-
if not isinstance(keywords, tuple):
|
229
|
-
keywords = (keywords,)
|
230
|
-
|
231
|
-
contents, parsed = self._read()
|
232
|
-
|
233
|
-
start, end = get_entry_locn(parsed, keywords)
|
234
|
-
|
235
|
-
self._write(contents[:start] + contents[end:])
|
236
|
-
|
237
|
-
def _iter(self, keywords: Union[str, Tuple[str, ...]] = ()) -> Iterator[str]:
|
238
|
-
if not isinstance(keywords, tuple):
|
239
|
-
keywords = (keywords,)
|
240
|
-
|
241
|
-
contents = self.path.read_text()
|
242
|
-
parsed = parse(contents)
|
243
|
-
|
244
|
-
yield from (k[-1] for k in parsed if k[:-1] == keywords)
|
245
|
-
|
246
|
-
def __iter__(self) -> Iterator[str]:
|
247
|
-
return self._iter()
|
248
|
-
|
249
|
-
def __contains__(self, keywords: object) -> bool:
|
250
|
-
if not isinstance(keywords, tuple):
|
251
|
-
keywords = (keywords,)
|
252
|
-
_, parsed = self._read()
|
253
|
-
return keywords in parsed
|
254
|
-
|
255
|
-
def __len__(self) -> int:
|
256
|
-
return len(list(iter(self)))
|
257
|
-
|
258
|
-
def update(self, *args: Any, **kwargs: Any) -> None:
|
259
|
-
with self:
|
260
|
-
super().update(*args, **kwargs)
|
261
|
-
|
262
|
-
def clear(self) -> None:
|
263
|
-
with self:
|
264
|
-
super().clear()
|
265
|
-
|
266
|
-
def __fspath__(self) -> str:
|
267
|
-
return str(self.path)
|
268
|
-
|
269
|
-
def __repr__(self) -> str:
|
270
|
-
return f"{type(self).__name__}({self.path})"
|
271
|
-
|
272
|
-
def as_dict(self) -> FoamDictionaryBase._Dict:
|
273
|
-
"""Return a nested dict representation of the file."""
|
274
|
-
_, parsed = self._read()
|
275
|
-
return as_dict(parsed)
|
276
|
-
|
277
|
-
|
278
|
-
class FoamFieldFile(FoamFile):
|
279
|
-
"""An OpenFOAM dictionary file representing a field as a mutable mapping."""
|
280
|
-
|
281
|
-
class BoundariesDictionary(FoamFile.Dictionary):
|
282
|
-
def __getitem__(self, keyword: str) -> "FoamFieldFile.BoundaryDictionary":
|
283
|
-
value = super().__getitem__(keyword)
|
284
|
-
if not isinstance(value, FoamFieldFile.BoundaryDictionary):
|
285
|
-
assert not isinstance(value, FoamFile.Dictionary)
|
286
|
-
raise TypeError(f"boundary {keyword} is not a dictionary")
|
287
|
-
return value
|
288
|
-
|
289
|
-
class BoundaryDictionary(FoamFile.Dictionary):
|
290
|
-
"""An OpenFOAM dictionary representing a boundary condition as a mutable mapping."""
|
291
|
-
|
292
|
-
def __setitem__(
|
293
|
-
self,
|
294
|
-
key: str,
|
295
|
-
value: FoamFile._SetValue,
|
296
|
-
) -> None:
|
297
|
-
if key == "value":
|
298
|
-
self._setitem(key, value, assume_field=True)
|
299
|
-
else:
|
300
|
-
self._setitem(key, value)
|
301
|
-
|
302
|
-
@property
|
303
|
-
def type(self) -> str:
|
304
|
-
"""Alias of `self["type"]`."""
|
305
|
-
ret = self["type"]
|
306
|
-
if not isinstance(ret, str):
|
307
|
-
raise TypeError("type is not a string")
|
308
|
-
return ret
|
309
|
-
|
310
|
-
@type.setter
|
311
|
-
def type(self, value: str) -> None:
|
312
|
-
self["type"] = value
|
313
|
-
|
314
|
-
@property
|
315
|
-
def value(
|
316
|
-
self,
|
317
|
-
) -> Union[
|
318
|
-
int,
|
319
|
-
float,
|
320
|
-
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
321
|
-
"NDArray[np.generic]",
|
322
|
-
]:
|
323
|
-
"""Alias of `self["value"]`."""
|
324
|
-
ret = self["value"]
|
325
|
-
if not isinstance(ret, (int, float, Sequence)):
|
326
|
-
raise TypeError("value is not a field")
|
327
|
-
return cast(Union[int, float, Sequence[Union[int, float]]], ret)
|
328
|
-
|
329
|
-
@value.setter
|
330
|
-
def value(
|
331
|
-
self,
|
332
|
-
value: Union[
|
333
|
-
int,
|
334
|
-
float,
|
335
|
-
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
336
|
-
"NDArray[np.generic]",
|
337
|
-
],
|
338
|
-
) -> None:
|
339
|
-
self["value"] = value
|
340
|
-
|
341
|
-
@value.deleter
|
342
|
-
def value(self) -> None:
|
343
|
-
del self["value"]
|
344
|
-
|
345
|
-
def __getitem__(
|
346
|
-
self, keywords: Union[str, Tuple[str, ...]]
|
347
|
-
) -> Union[FoamFile.Value, FoamFile.Dictionary]:
|
348
|
-
if not isinstance(keywords, tuple):
|
349
|
-
keywords = (keywords,)
|
350
|
-
|
351
|
-
ret = super().__getitem__(keywords)
|
352
|
-
if keywords[0] == "boundaryField" and isinstance(ret, FoamFile.Dictionary):
|
353
|
-
if len(keywords) == 1:
|
354
|
-
ret = FoamFieldFile.BoundariesDictionary(self, keywords)
|
355
|
-
elif len(keywords) == 2:
|
356
|
-
ret = FoamFieldFile.BoundaryDictionary(self, keywords)
|
357
|
-
return ret
|
358
|
-
|
359
|
-
def __setitem__(self, keywords: Union[str, Tuple[str, ...]], value: Any) -> None:
|
360
|
-
if not isinstance(keywords, tuple):
|
361
|
-
keywords = (keywords,)
|
362
|
-
|
363
|
-
if keywords == ("internalField",):
|
364
|
-
self._setitem(keywords, value, assume_field=True)
|
365
|
-
elif keywords == ("dimensions",):
|
366
|
-
self._setitem(keywords, value, assume_dimensions=True)
|
367
|
-
else:
|
368
|
-
self._setitem(keywords, value)
|
369
|
-
|
370
|
-
@property
|
371
|
-
def dimensions(self) -> FoamFile.DimensionSet:
|
372
|
-
"""Alias of `self["dimensions"]`."""
|
373
|
-
ret = self["dimensions"]
|
374
|
-
if not isinstance(ret, FoamFile.DimensionSet):
|
375
|
-
raise TypeError("dimensions is not a DimensionSet")
|
376
|
-
return ret
|
377
|
-
|
378
|
-
@dimensions.setter
|
379
|
-
def dimensions(
|
380
|
-
self, value: Union[FoamFile.DimensionSet, Sequence[Union[int, float]]]
|
381
|
-
) -> None:
|
382
|
-
self["dimensions"] = value
|
383
|
-
|
384
|
-
@property
|
385
|
-
def internal_field(
|
386
|
-
self,
|
387
|
-
) -> Union[
|
388
|
-
int,
|
389
|
-
float,
|
390
|
-
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
391
|
-
"NDArray[np.generic]",
|
392
|
-
]:
|
393
|
-
"""Alias of `self["internalField"]`."""
|
394
|
-
ret = self["internalField"]
|
395
|
-
if not isinstance(ret, (int, float, Sequence)):
|
396
|
-
raise TypeError("internalField is not a field")
|
397
|
-
return cast(Union[int, float, Sequence[Union[int, float]]], ret)
|
398
|
-
|
399
|
-
@internal_field.setter
|
400
|
-
def internal_field(
|
401
|
-
self,
|
402
|
-
value: Union[
|
403
|
-
int,
|
404
|
-
float,
|
405
|
-
Sequence[Union[int, float, Sequence[Union[int, float]]]],
|
406
|
-
"NDArray[np.generic]",
|
407
|
-
],
|
408
|
-
) -> None:
|
409
|
-
self["internalField"] = value
|
410
|
-
|
411
|
-
@property
|
412
|
-
def boundary_field(self) -> "FoamFieldFile.BoundariesDictionary":
|
413
|
-
"""Alias of `self["boundaryField"]`."""
|
414
|
-
ret = self["boundaryField"]
|
415
|
-
if not isinstance(ret, FoamFieldFile.BoundariesDictionary):
|
416
|
-
assert not isinstance(ret, FoamFile.Dictionary)
|
417
|
-
raise TypeError("boundaryField is not a dictionary")
|
418
|
-
return ret
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|