foamlib 0.9.3__py3-none-any.whl → 0.9.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 +1 -1
- foamlib/_files/_files.py +23 -16
- foamlib/_files/_serialization.py +54 -22
- foamlib/_files/_types.py +27 -29
- {foamlib-0.9.3.dist-info → foamlib-0.9.4.dist-info}/METADATA +1 -1
- {foamlib-0.9.3.dist-info → foamlib-0.9.4.dist-info}/RECORD +8 -8
- {foamlib-0.9.3.dist-info → foamlib-0.9.4.dist-info}/WHEEL +0 -0
- {foamlib-0.9.3.dist-info → foamlib-0.9.4.dist-info}/licenses/LICENSE.txt +0 -0
foamlib/__init__.py
CHANGED
foamlib/_files/_files.py
CHANGED
@@ -22,14 +22,17 @@ from ._serialization import dumps, normalize_data, normalize_keyword
|
|
22
22
|
from ._types import (
|
23
23
|
Data,
|
24
24
|
DataLike,
|
25
|
-
Dict_,
|
26
25
|
Dimensioned,
|
27
26
|
DimensionSet,
|
28
|
-
EntryLike,
|
29
27
|
Field,
|
30
28
|
FieldLike,
|
31
29
|
File,
|
32
|
-
|
30
|
+
FileLike,
|
31
|
+
MutableSubDict,
|
32
|
+
StandaloneData,
|
33
|
+
StandaloneDataLike,
|
34
|
+
SubDict,
|
35
|
+
SubDictLike,
|
33
36
|
)
|
34
37
|
|
35
38
|
|
@@ -62,7 +65,7 @@ def _tensor_kind_for_field(
|
|
62
65
|
class FoamFile(
|
63
66
|
MutableMapping[
|
64
67
|
Optional[Union[str, Tuple[str, ...]]],
|
65
|
-
|
68
|
+
Union[Data, MutableSubDict],
|
66
69
|
],
|
67
70
|
FoamFileIO,
|
68
71
|
):
|
@@ -115,7 +118,7 @@ class FoamFile(
|
|
115
118
|
DimensionSet = DimensionSet
|
116
119
|
|
117
120
|
class SubDict(
|
118
|
-
MutableMapping[str,
|
121
|
+
MutableMapping[str, Union[Data, MutableSubDict]],
|
119
122
|
):
|
120
123
|
"""
|
121
124
|
An OpenFOAM sub-dictionary within a file.
|
@@ -154,7 +157,7 @@ class FoamFile(
|
|
154
157
|
def __setitem__(
|
155
158
|
self,
|
156
159
|
keyword: str,
|
157
|
-
data:
|
160
|
+
data: DataLike | SubDictLike,
|
158
161
|
) -> None:
|
159
162
|
self._file[(*self._keywords, keyword)] = data
|
160
163
|
|
@@ -183,7 +186,7 @@ class FoamFile(
|
|
183
186
|
def __repr__(self) -> str:
|
184
187
|
return f"{type(self).__qualname__}('{self._file}', {self._keywords})"
|
185
188
|
|
186
|
-
def as_dict(self) ->
|
189
|
+
def as_dict(self) -> SubDict:
|
187
190
|
"""Return a nested dict representation of the sub-dictionary."""
|
188
191
|
ret = self._file.as_dict(include_header=True)
|
189
192
|
|
@@ -193,7 +196,7 @@ class FoamFile(
|
|
193
196
|
assert isinstance(v, dict)
|
194
197
|
ret = cast("File", v)
|
195
198
|
|
196
|
-
return cast("
|
199
|
+
return cast("SubDict", ret)
|
197
200
|
|
198
201
|
@property
|
199
202
|
def version(self) -> float:
|
@@ -282,7 +285,7 @@ class FoamFile(
|
|
282
285
|
return deepcopy(value)
|
283
286
|
|
284
287
|
def __setitem__(
|
285
|
-
self, keywords: str | tuple[str, ...] | None, data:
|
288
|
+
self, keywords: str | tuple[str, ...] | None, data: DataLike | SubDictLike
|
286
289
|
) -> None:
|
287
290
|
if not keywords:
|
288
291
|
keywords = ()
|
@@ -463,7 +466,7 @@ class FoamFile(
|
|
463
466
|
s: bytes | str,
|
464
467
|
*,
|
465
468
|
include_header: bool = False,
|
466
|
-
) -> File |
|
469
|
+
) -> File | StandaloneData:
|
467
470
|
"""
|
468
471
|
Standalone deserializing function.
|
469
472
|
|
@@ -486,7 +489,9 @@ class FoamFile(
|
|
486
489
|
return ret
|
487
490
|
|
488
491
|
@staticmethod
|
489
|
-
def dumps(
|
492
|
+
def dumps(
|
493
|
+
file: FileLike | StandaloneDataLike, *, ensure_header: bool = True
|
494
|
+
) -> bytes:
|
490
495
|
"""
|
491
496
|
Standalone serializing function.
|
492
497
|
|
@@ -498,21 +503,23 @@ class FoamFile(
|
|
498
503
|
If `True`, a header will be included if it is not already present in the
|
499
504
|
input object.
|
500
505
|
"""
|
506
|
+
header: SubDict | None
|
501
507
|
if isinstance(file, Mapping):
|
502
|
-
header = file.get("FoamFile", None)
|
503
|
-
|
508
|
+
header = file.get("FoamFile", None) # type: ignore [assignment]
|
509
|
+
|
504
510
|
entries: list[bytes] = []
|
505
511
|
for k, v in file.items():
|
506
512
|
if k is not None:
|
507
513
|
entries.append(
|
508
|
-
dumps((k, v), keywords=(), header=header, tuple_is_entry=True)
|
514
|
+
dumps((k, v), keywords=(), header=header, tuple_is_entry=True) # type: ignore [arg-type]
|
509
515
|
)
|
510
516
|
else:
|
517
|
+
assert not isinstance(v, Mapping)
|
511
518
|
entries.append(dumps(v, keywords=(), header=header))
|
512
519
|
ret = b" ".join(entries)
|
513
520
|
else:
|
514
521
|
header = None
|
515
|
-
ret = dumps(file)
|
522
|
+
ret = dumps(file, keywords=(), header=header)
|
516
523
|
|
517
524
|
if header is None and ensure_header:
|
518
525
|
class_ = "dictionary"
|
@@ -670,5 +677,5 @@ class FoamFieldFile(FoamFile):
|
|
670
677
|
return ret
|
671
678
|
|
672
679
|
@boundary_field.setter
|
673
|
-
def boundary_field(self, value: Mapping[str,
|
680
|
+
def boundary_field(self, value: Mapping[str, SubDict]) -> None:
|
674
681
|
self["boundaryField"] = value
|
foamlib/_files/_serialization.py
CHANGED
@@ -16,8 +16,10 @@ from ._types import (
|
|
16
16
|
DataLike,
|
17
17
|
Dimensioned,
|
18
18
|
DimensionSet,
|
19
|
-
|
20
|
-
|
19
|
+
StandaloneData,
|
20
|
+
StandaloneDataLike,
|
21
|
+
SubDict,
|
22
|
+
SubDictLike,
|
21
23
|
is_sequence,
|
22
24
|
)
|
23
25
|
|
@@ -30,13 +32,37 @@ def normalize_data(
|
|
30
32
|
|
31
33
|
@overload
|
32
34
|
def normalize_data(
|
33
|
-
data:
|
34
|
-
) ->
|
35
|
+
data: StandaloneDataLike, *, keywords: tuple[str, ...] | None = None
|
36
|
+
) -> StandaloneData: ...
|
35
37
|
|
36
38
|
|
39
|
+
@overload
|
37
40
|
def normalize_data(
|
38
|
-
data:
|
39
|
-
) ->
|
41
|
+
data: SubDictLike, *, keywords: tuple[str, ...] | None = None
|
42
|
+
) -> SubDict: ...
|
43
|
+
|
44
|
+
|
45
|
+
def normalize_data(
|
46
|
+
data: DataLike | StandaloneDataLike | SubDictLike,
|
47
|
+
*,
|
48
|
+
keywords: tuple[str, ...] | None = None,
|
49
|
+
) -> Data | StandaloneData | SubDict:
|
50
|
+
if isinstance(data, Mapping):
|
51
|
+
return {normalize_keyword(k): normalize_data(v) for k, v in data.items()} # type: ignore [arg-type, misc]
|
52
|
+
|
53
|
+
if keywords == () and is_sequence(data) and not isinstance(data, tuple):
|
54
|
+
try:
|
55
|
+
arr = np.asarray(data)
|
56
|
+
except ValueError:
|
57
|
+
pass
|
58
|
+
else:
|
59
|
+
if np.issubdtype(arr.dtype, np.integer) and arr.ndim == 1:
|
60
|
+
return arr # type: ignore [return-value]
|
61
|
+
if arr.ndim == 2 and arr.shape[1] == 3:
|
62
|
+
if not np.issubdtype(arr.dtype, np.floating):
|
63
|
+
arr = arr.astype(float)
|
64
|
+
return arr # type: ignore [return-value]
|
65
|
+
|
40
66
|
if keywords is not None and (
|
41
67
|
keywords == ("internalField",)
|
42
68
|
or (
|
@@ -49,7 +75,7 @@ def normalize_data(
|
|
49
75
|
)
|
50
76
|
)
|
51
77
|
):
|
52
|
-
if is_sequence(data):
|
78
|
+
if is_sequence(data) and not isinstance(data, tuple):
|
53
79
|
try:
|
54
80
|
arr = np.asarray(data)
|
55
81
|
except ValueError:
|
@@ -61,20 +87,17 @@ def normalize_data(
|
|
61
87
|
if arr.ndim == 1 or (arr.ndim == 2 and arr.shape[1] in (3, 6, 9)):
|
62
88
|
return arr # type: ignore [return-value]
|
63
89
|
|
64
|
-
return [normalize_data(d) for d in data]
|
90
|
+
return [normalize_data(d) for d in data] # type: ignore [arg-type]
|
65
91
|
|
66
92
|
if isinstance(data, int):
|
67
93
|
return float(data)
|
68
94
|
|
69
95
|
return normalize_data(data)
|
70
96
|
|
71
|
-
if isinstance(data, Mapping):
|
72
|
-
return {normalize_keyword(k): normalize_data(v) for k, v in data.items()} # type: ignore [misc]
|
73
|
-
|
74
97
|
if isinstance(data, np.ndarray):
|
75
98
|
ret = data.tolist()
|
76
99
|
assert isinstance(ret, (int, float, list))
|
77
|
-
return ret
|
100
|
+
return ret # type: ignore [return-value]
|
78
101
|
|
79
102
|
if (
|
80
103
|
not isinstance(data, DimensionSet)
|
@@ -90,16 +113,19 @@ def normalize_data(
|
|
90
113
|
k, v = data
|
91
114
|
assert not isinstance(k, Mapping)
|
92
115
|
return (
|
93
|
-
normalize_keyword(k),
|
94
|
-
normalize_data(v) if not isinstance(v, Mapping) else v,
|
95
|
-
)
|
116
|
+
normalize_keyword(k), # type: ignore [arg-type]
|
117
|
+
normalize_data(v) if not isinstance(v, Mapping) else v, # type: ignore [arg-type, misc]
|
118
|
+
)
|
96
119
|
|
97
120
|
if (
|
98
121
|
is_sequence(data)
|
99
122
|
and not isinstance(data, DimensionSet)
|
100
|
-
and
|
123
|
+
and not isinstance(data, tuple)
|
101
124
|
):
|
102
|
-
return [normalize_data(d) for d in data]
|
125
|
+
return [normalize_data(d) for d in data] # type: ignore [arg-type]
|
126
|
+
|
127
|
+
if isinstance(data, tuple) and not isinstance(data, DimensionSet):
|
128
|
+
return tuple(normalize_data(d) for d in data)
|
103
129
|
|
104
130
|
if isinstance(data, str):
|
105
131
|
s = loads(data)
|
@@ -108,7 +134,7 @@ def normalize_data(
|
|
108
134
|
|
109
135
|
if isinstance(
|
110
136
|
data,
|
111
|
-
(int, float, bool,
|
137
|
+
(int, float, bool, DimensionSet, Dimensioned),
|
112
138
|
):
|
113
139
|
return data
|
114
140
|
|
@@ -126,13 +152,13 @@ def normalize_keyword(data: DataLike) -> Data:
|
|
126
152
|
|
127
153
|
|
128
154
|
def dumps(
|
129
|
-
data:
|
155
|
+
data: DataLike | StandaloneDataLike | SubDictLike,
|
130
156
|
*,
|
131
157
|
keywords: tuple[str, ...] | None = None,
|
132
|
-
header:
|
158
|
+
header: SubDictLike | None = None,
|
133
159
|
tuple_is_entry: bool = False,
|
134
160
|
) -> bytes:
|
135
|
-
data = normalize_data(data, keywords=keywords)
|
161
|
+
data = normalize_data(data, keywords=keywords) # type: ignore [arg-type, misc]
|
136
162
|
|
137
163
|
if isinstance(data, Mapping):
|
138
164
|
return (
|
@@ -148,6 +174,12 @@ def dumps(
|
|
148
174
|
+ b"}"
|
149
175
|
)
|
150
176
|
|
177
|
+
if keywords == () and isinstance(data, np.ndarray):
|
178
|
+
if (header.get("format", "") if header else "") == "binary":
|
179
|
+
return dumps(len(data)) + b"(" + data.tobytes() + b")"
|
180
|
+
|
181
|
+
return dumps(data.tolist())
|
182
|
+
|
151
183
|
if (
|
152
184
|
keywords is not None
|
153
185
|
and (
|
@@ -231,7 +263,7 @@ def dumps(
|
|
231
263
|
return b" ".join(dumps(v) for v in data)
|
232
264
|
|
233
265
|
if is_sequence(data):
|
234
|
-
return b"(" + b" ".join(dumps(v, tuple_is_entry=True) for v in data) + b")"
|
266
|
+
return b"(" + b" ".join(dumps(v, tuple_is_entry=True) for v in data) + b")" # type: ignore [arg-type]
|
235
267
|
|
236
268
|
if data is True:
|
237
269
|
return b"yes"
|
foamlib/_files/_types.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import sys
|
4
|
-
from typing import Any, Dict, NamedTuple, Optional, Union
|
4
|
+
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union
|
5
5
|
|
6
6
|
import numpy as np
|
7
7
|
|
@@ -76,9 +76,8 @@ Tensor = Union[
|
|
76
76
|
]
|
77
77
|
|
78
78
|
TensorLike = Union[
|
79
|
-
Sequence[float],
|
80
|
-
"np.ndarray[tuple[()], np.dtype[np.float64]]",
|
81
79
|
Tensor,
|
80
|
+
Sequence[float],
|
82
81
|
]
|
83
82
|
|
84
83
|
|
@@ -116,7 +115,7 @@ class Dimensioned:
|
|
116
115
|
return Dimensioned(
|
117
116
|
self.value + other.value, # type: ignore [arg-type]
|
118
117
|
self.dimensions + other.dimensions,
|
119
|
-
f"{self.name}
|
118
|
+
f"{self.name}+{other.name}"
|
120
119
|
if self.name is not None and other.name is not None
|
121
120
|
else None,
|
122
121
|
)
|
@@ -128,7 +127,7 @@ class Dimensioned:
|
|
128
127
|
return Dimensioned(
|
129
128
|
self.value - other.value, # type: ignore [arg-type]
|
130
129
|
self.dimensions - other.dimensions,
|
131
|
-
f"{self.name}
|
130
|
+
f"{self.name}-{other.name}"
|
132
131
|
if self.name is not None and other.name is not None
|
133
132
|
else None,
|
134
133
|
)
|
@@ -140,7 +139,7 @@ class Dimensioned:
|
|
140
139
|
return Dimensioned(
|
141
140
|
self.value * other.value, # type: ignore [arg-type]
|
142
141
|
self.dimensions * other.dimensions,
|
143
|
-
f"{self.name}
|
142
|
+
f"{self.name}*{other.name}"
|
144
143
|
if self.name is not None and other.name is not None
|
145
144
|
else None,
|
146
145
|
)
|
@@ -152,7 +151,7 @@ class Dimensioned:
|
|
152
151
|
return Dimensioned(
|
153
152
|
self.value / other.value, # type: ignore [arg-type]
|
154
153
|
self.dimensions / other.dimensions,
|
155
|
-
f"{self.name}
|
154
|
+
f"{self.name}/{other.name}"
|
156
155
|
if self.name is not None and other.name is not None
|
157
156
|
else None,
|
158
157
|
)
|
@@ -164,7 +163,7 @@ class Dimensioned:
|
|
164
163
|
return Dimensioned(
|
165
164
|
self.value**exponent, # type: ignore [arg-type]
|
166
165
|
self.dimensions**exponent,
|
167
|
-
f"{self.name}
|
166
|
+
f"pow({self.name},{exponent})" if self.name is not None else None,
|
168
167
|
)
|
169
168
|
|
170
169
|
def __float__(self) -> float:
|
@@ -194,10 +193,9 @@ Field = Union[
|
|
194
193
|
]
|
195
194
|
|
196
195
|
FieldLike = Union[
|
196
|
+
Field,
|
197
197
|
TensorLike,
|
198
198
|
Sequence[TensorLike],
|
199
|
-
Sequence[Sequence[TensorLike]],
|
200
|
-
Field,
|
201
199
|
]
|
202
200
|
|
203
201
|
|
@@ -208,34 +206,35 @@ Data = Union[
|
|
208
206
|
bool,
|
209
207
|
Dimensioned,
|
210
208
|
DimensionSet,
|
211
|
-
|
209
|
+
Tuple["Data", ...],
|
210
|
+
List[Union["Data", Tuple["Data", Union["Data", "SubDict"]]]],
|
212
211
|
Field,
|
213
212
|
]
|
214
213
|
|
215
|
-
|
214
|
+
DataLike = Union[
|
216
215
|
Data,
|
217
|
-
|
216
|
+
Tuple["DataLike", ...],
|
217
|
+
Sequence[Union["DataLike", Tuple["DataLike", Union["DataLike", "SubDictLike"]]]],
|
218
|
+
FieldLike,
|
218
219
|
]
|
219
|
-
"""
|
220
|
-
A value that can be stored in an OpenFOAM file.
|
221
|
-
"""
|
222
220
|
|
223
|
-
|
224
|
-
FieldLike,
|
225
|
-
Sequence["EntryLike"],
|
221
|
+
StandaloneData = Union[
|
226
222
|
Data,
|
223
|
+
"np.ndarray[tuple[int], np.dtype[np.int64 | np.int32]]",
|
224
|
+
"np.ndarray[tuple[int], np.dtype[np.float64 | np.float32]]",
|
227
225
|
]
|
228
226
|
|
229
|
-
|
227
|
+
StandaloneDataLike = Union[
|
230
228
|
DataLike,
|
231
|
-
|
229
|
+
"np.ndarray[tuple[int], np.dtype[np.int64 | np.int32]]",
|
230
|
+
"np.ndarray[tuple[int], np.dtype[np.float64 | np.float32]]",
|
232
231
|
]
|
233
232
|
|
234
233
|
|
235
234
|
def is_sequence(
|
236
|
-
value:
|
235
|
+
value: DataLike | StandaloneDataLike | SubDictLike,
|
237
236
|
) -> TypeGuard[
|
238
|
-
Sequence[
|
237
|
+
Sequence[DataLike | tuple[DataLike, DataLike | SubDictLike]]
|
239
238
|
| np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.float64 | np.float32]]
|
240
239
|
]:
|
241
240
|
return (isinstance(value, Sequence) and not isinstance(value, str)) or (
|
@@ -243,10 +242,9 @@ def is_sequence(
|
|
243
242
|
)
|
244
243
|
|
245
244
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
]
|
245
|
+
SubDict = Dict[str, Union[Data, "SubDict"]]
|
246
|
+
SubDictLike = Mapping[str, Union[DataLike, "SubDictLike"]]
|
247
|
+
MutableSubDict = MutableMapping[str, Union[Data, "MutableSubDict"]]
|
250
248
|
|
251
|
-
|
252
|
-
|
249
|
+
File = Dict[Optional[str], Union[StandaloneData, Data, "SubDict"]]
|
250
|
+
FileLike = Mapping[Optional[str], Union[StandaloneDataLike, DataLike, "FileLike"]]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
foamlib/__init__.py,sha256=
|
1
|
+
foamlib/__init__.py,sha256=LQALCtihE20dGUDWlQdYlr_X7vLFUhOExPzWqPtDDAY,452
|
2
2
|
foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
foamlib/_cases/__init__.py,sha256=_A1TTHuQfS9FH2_33lSEyLtOJZGFHZBco1tWJCVOHks,358
|
4
4
|
foamlib/_cases/_async.py,sha256=e4lGTcQBbFGwfG6SmJks5aa5LWd_0dy01kgKZWAgTGQ,11655
|
@@ -9,12 +9,12 @@ foamlib/_cases/_subprocess.py,sha256=VHV2SuOLqa711an6kCuvN6UlIkeh4qqFfdrpNoKzQps
|
|
9
9
|
foamlib/_cases/_sync.py,sha256=yhrkwStKri7u41YImYCGBH4REcKn8Ar-32VW_WPa40c,9641
|
10
10
|
foamlib/_cases/_util.py,sha256=QCizfbuJdOCeF9ogU2R-y-iWX5kfaOA4U2W68t6QlOM,2544
|
11
11
|
foamlib/_files/__init__.py,sha256=q1vkjXnjnSZvo45jPAICpWeF2LZv5V6xfzAR6S8fS5A,96
|
12
|
-
foamlib/_files/_files.py,sha256=
|
12
|
+
foamlib/_files/_files.py,sha256=nbf9SPGH4v4-H4mxiMtiD8YuBJJdGC8RFlV_KLFM6bA,22676
|
13
13
|
foamlib/_files/_io.py,sha256=BGbbm6HKxL2ka0YMCmHqZQZ1R4PPQlkvWWb4FHMAS8k,2217
|
14
14
|
foamlib/_files/_parsing.py,sha256=CWALQclNOXUlPylI98h2DxMNz5OE0KZf9Gioc9h3OWU,17659
|
15
|
-
foamlib/_files/_serialization.py,sha256=
|
16
|
-
foamlib/_files/_types.py,sha256=
|
17
|
-
foamlib-0.9.
|
18
|
-
foamlib-0.9.
|
19
|
-
foamlib-0.9.
|
20
|
-
foamlib-0.9.
|
15
|
+
foamlib/_files/_serialization.py,sha256=R7hnUNWH1McOnu4k7grfbJKvNGhADSSTIOIXrDDtw74,7800
|
16
|
+
foamlib/_files/_types.py,sha256=SmKA6I1l6Q7JHOlhLFV1s2cU3tkeBQmj13lW3ETlKU0,7710
|
17
|
+
foamlib-0.9.4.dist-info/METADATA,sha256=jRLgmp_A9dsqH2P_RzhESlkSBLlGB3XeC4xFljDzhRM,12906
|
18
|
+
foamlib-0.9.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
19
|
+
foamlib-0.9.4.dist-info/licenses/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
|
20
|
+
foamlib-0.9.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|