foamlib 0.9.0__py3-none-any.whl → 0.9.1__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/_parsing.py +99 -105
- foamlib/_files/_types.py +0 -34
- {foamlib-0.9.0.dist-info → foamlib-0.9.1.dist-info}/METADATA +1 -1
- {foamlib-0.9.0.dist-info → foamlib-0.9.1.dist-info}/RECORD +7 -7
- {foamlib-0.9.0.dist-info → foamlib-0.9.1.dist-info}/WHEEL +0 -0
- {foamlib-0.9.0.dist-info → foamlib-0.9.1.dist-info}/licenses/LICENSE.txt +0 -0
foamlib/__init__.py
CHANGED
foamlib/_files/_parsing.py
CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import re
|
4
4
|
import sys
|
5
|
-
from typing import Tuple, Union, cast
|
5
|
+
from typing import TYPE_CHECKING, Tuple, Union, cast
|
6
6
|
|
7
7
|
if sys.version_info >= (3, 9):
|
8
8
|
from collections.abc import Iterator, Mapping, MutableMapping, Sequence
|
@@ -40,46 +40,43 @@ from pyparsing import (
|
|
40
40
|
|
41
41
|
from ._types import Data, Dimensioned, DimensionSet, File
|
42
42
|
|
43
|
+
if TYPE_CHECKING:
|
44
|
+
from numpy.typing import DTypeLike
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
|
47
|
+
def _ascii_numeric_list(
|
48
|
+
dtype: DTypeLike,
|
49
|
+
*,
|
50
|
+
nested: int | None = None,
|
51
|
+
ignore: Regex | None = None,
|
52
|
+
empty_ok: bool = False,
|
46
53
|
) -> ParserElement:
|
47
|
-
|
48
|
-
|
49
|
-
|
54
|
+
dtype = np.dtype(dtype)
|
55
|
+
|
56
|
+
if np.issubdtype(dtype, np.floating):
|
57
|
+
element = common.ieee_float
|
58
|
+
element_pattern = r"(?i:[+-]?(?:(?:\d+\.?\d*(?:e[+-]?\d+)?)|nan|inf(?:inity)?))"
|
59
|
+
elif np.issubdtype(dtype, np.integer):
|
60
|
+
element = common.integer
|
61
|
+
element_pattern = r"(?:-?\d+)"
|
62
|
+
else:
|
63
|
+
msg = f"Unsupported dtype: {dtype}"
|
64
|
+
raise TypeError(msg)
|
65
|
+
|
50
66
|
spacing_pattern = (
|
51
|
-
rf"(?:(?:\s|{ignore.re.pattern})+)" if ignore is not None else r"
|
67
|
+
rf"(?:(?:\s|{ignore.re.pattern})+)" if ignore is not None else r"(?:\s+)"
|
52
68
|
)
|
53
69
|
|
54
|
-
if nested is None:
|
55
|
-
|
56
|
-
|
57
|
-
int_element = common.integer
|
58
|
-
float_element_pattern = float_pattern
|
59
|
-
float_element = common.ieee_float
|
60
|
-
else:
|
61
|
-
if not force_float:
|
62
|
-
int_element_pattern = rf"(?:(?:{nested})?{spacing_pattern}?\({spacing_pattern}?(?:{int_pattern}{spacing_pattern}){{{nested - 1}}}{int_pattern}{spacing_pattern}?\))"
|
63
|
-
int_element = (
|
64
|
-
Opt(Literal(str(nested))).suppress()
|
65
|
-
+ Literal("(").suppress()
|
66
|
-
+ Group(common.integer[nested])
|
67
|
-
+ Literal(")").suppress()
|
68
|
-
)
|
69
|
-
float_element_pattern = rf"(?:(?:{nested})?{spacing_pattern}?\({spacing_pattern}?(?:{float_pattern}{spacing_pattern}){{{nested - 1}}}{float_pattern}{spacing_pattern}?\))"
|
70
|
-
float_element = (
|
71
|
-
Opt(Literal(str(nested))).suppress()
|
72
|
-
+ Literal("(").suppress()
|
73
|
-
+ Group(common.ieee_float[nested])
|
74
|
-
+ Literal(")").suppress()
|
70
|
+
if nested is not None:
|
71
|
+
element = (
|
72
|
+
Literal("(").suppress() + Group(element[nested]) + Literal(")").suppress()
|
75
73
|
)
|
74
|
+
element_pattern = rf"(?:{spacing_pattern}?\({element_pattern}?(?:{element_pattern}{spacing_pattern}){{{nested - 1}}}{element_pattern}{spacing_pattern}?\))"
|
76
75
|
|
77
|
-
|
78
|
-
int_list = Forward()
|
79
|
-
float_list = Forward()
|
76
|
+
list_ = Forward()
|
80
77
|
|
81
78
|
def process_count(tks: ParseResults) -> None:
|
82
|
-
nonlocal
|
79
|
+
nonlocal list_
|
83
80
|
|
84
81
|
if not tks:
|
85
82
|
count = None
|
@@ -88,46 +85,41 @@ def _numeric_list(
|
|
88
85
|
assert isinstance(count, int)
|
89
86
|
|
90
87
|
if count is None:
|
91
|
-
if not
|
92
|
-
|
93
|
-
float_list_pattern = rf"\({spacing_pattern}?(?:{float_element_pattern}{spacing_pattern})*{float_element_pattern}{spacing_pattern}?\)"
|
88
|
+
if not empty_ok:
|
89
|
+
list_pattern = rf"\({spacing_pattern}?(?:{element_pattern}{spacing_pattern})*{element_pattern}{spacing_pattern}?\)"
|
94
90
|
else:
|
95
|
-
|
91
|
+
list_pattern = rf"\({spacing_pattern}?(?:{element_pattern}{spacing_pattern})*{element_pattern}?{spacing_pattern}?\)"
|
96
92
|
|
97
93
|
elif count == 0:
|
98
|
-
if not
|
99
|
-
|
100
|
-
float_list <<= NoMatch()
|
94
|
+
if not empty_ok:
|
95
|
+
list_ <<= NoMatch()
|
101
96
|
else:
|
102
|
-
|
103
|
-
lambda: np.empty((0, nested) if nested else 0, dtype=
|
97
|
+
list_ <<= (Literal("(") + Literal(")")).add_parse_action(
|
98
|
+
lambda: np.empty((0, nested) if nested else 0, dtype=dtype)
|
104
99
|
)
|
105
100
|
return
|
106
101
|
|
107
102
|
else:
|
108
|
-
|
109
|
-
int_list_pattern = rf"\({spacing_pattern}?(?:{int_element_pattern}{spacing_pattern}){{{count - 1}}}{int_element_pattern}{spacing_pattern}?\)"
|
110
|
-
float_list_pattern = rf"\({spacing_pattern}?(?:{float_element_pattern}{spacing_pattern}){{{count - 1}}}{float_element_pattern}{spacing_pattern}?\)"
|
103
|
+
list_pattern = rf"\({spacing_pattern}?(?:{element_pattern}{spacing_pattern}){{{count - 1}}}{element_pattern}{spacing_pattern}?\)"
|
111
104
|
|
112
|
-
|
113
|
-
|
114
|
-
lambda tks: to_array(tks, dtype=int)
|
115
|
-
)
|
116
|
-
float_list <<= Regex(float_list_pattern).add_parse_action(
|
117
|
-
lambda tks: to_array(tks, dtype=float)
|
105
|
+
list_ <<= Regex(list_pattern).add_parse_action(
|
106
|
+
lambda tks: to_array(tks, dtype=dtype)
|
118
107
|
)
|
119
108
|
|
120
109
|
def to_array(
|
121
|
-
tks: ParseResults, *, dtype:
|
122
|
-
) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.
|
110
|
+
tks: ParseResults, *, dtype: DTypeLike
|
111
|
+
) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.integer | np.floating]]:
|
123
112
|
(s,) = tks
|
124
|
-
|
125
|
-
|
113
|
+
assert s.startswith("(")
|
114
|
+
assert s.endswith(")")
|
115
|
+
s = s[1:-1]
|
126
116
|
if ignore is not None:
|
127
117
|
s = re.sub(ignore.re, " ", s)
|
118
|
+
if nested is not None:
|
119
|
+
s = s.replace("(", " ").replace(")", " ")
|
128
120
|
|
129
121
|
ret: np.ndarray[
|
130
|
-
tuple[int] | tuple[int, int], np.dtype[np.
|
122
|
+
tuple[int] | tuple[int, int], np.dtype[np.integer | np.floating]
|
131
123
|
] = np.fromstring(s, sep=" ", dtype=dtype) # type: ignore[assignment]
|
132
124
|
|
133
125
|
if nested is not None:
|
@@ -137,7 +129,7 @@ def _numeric_list(
|
|
137
129
|
|
138
130
|
def to_full_array(
|
139
131
|
tks: ParseResults, *, dtype: type
|
140
|
-
) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.
|
132
|
+
) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.integer | np.floating]]:
|
141
133
|
count, lst = tks
|
142
134
|
assert isinstance(count, int)
|
143
135
|
|
@@ -146,24 +138,8 @@ def _numeric_list(
|
|
146
138
|
|
147
139
|
return np.full((count, nested), lst, dtype=dtype) # type: ignore[return-value]
|
148
140
|
|
149
|
-
|
150
|
-
|
151
|
-
ret = count.suppress() + (
|
152
|
-
(int_list | float_list) if not force_float else float_list
|
153
|
-
)
|
154
|
-
|
155
|
-
if not force_float:
|
156
|
-
ret |= (
|
157
|
-
common.integer
|
158
|
-
+ Literal("{").suppress()
|
159
|
-
+ int_element
|
160
|
-
+ Literal("}").suppress()
|
161
|
-
).add_parse_action(lambda tks: to_full_array(tks, dtype=int))
|
162
|
-
ret |= (
|
163
|
-
common.integer
|
164
|
-
+ Literal("{").suppress()
|
165
|
-
+ float_element
|
166
|
-
+ Literal("}").suppress()
|
141
|
+
ret = ((Opt(common.integer).add_parse_action(process_count)).suppress() + list_) | (
|
142
|
+
common.integer + Literal("{").suppress() + element + Literal("}").suppress()
|
167
143
|
).add_parse_action(lambda tks: to_full_array(tks, dtype=float))
|
168
144
|
|
169
145
|
if ignore is not None:
|
@@ -172,23 +148,29 @@ def _numeric_list(
|
|
172
148
|
return ret
|
173
149
|
|
174
150
|
|
175
|
-
def
|
151
|
+
def _binary_numeric_list(
|
152
|
+
dtype: DTypeLike, *, nested: int | None = None, empty_ok: bool = False
|
153
|
+
) -> ParserElement:
|
154
|
+
dtype = np.dtype(dtype)
|
155
|
+
|
176
156
|
elsize = nested if nested is not None else 1
|
177
157
|
|
178
|
-
|
158
|
+
list_ = Forward()
|
179
159
|
|
180
160
|
def process_count(tks: ParseResults) -> None:
|
181
|
-
nonlocal
|
161
|
+
nonlocal list_
|
182
162
|
(size,) = tks
|
183
163
|
assert isinstance(size, int)
|
184
164
|
|
185
|
-
|
186
|
-
|
187
|
-
|
165
|
+
if size == 0 and not empty_ok:
|
166
|
+
list_ <<= NoMatch()
|
167
|
+
return
|
168
|
+
|
169
|
+
list_ <<= Regex(rf"\((?s:{'.' * dtype.itemsize * elsize}){{{size}}}\)")
|
188
170
|
|
189
171
|
def to_array(
|
190
172
|
tks: ParseResults,
|
191
|
-
) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.
|
173
|
+
) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.integer | np.floating]]:
|
192
174
|
size, s = tks
|
193
175
|
assert isinstance(size, int)
|
194
176
|
assert isinstance(s, str)
|
@@ -196,10 +178,6 @@ def _binary_field(*, nested: int | None = None) -> ParserElement:
|
|
196
178
|
assert s[-1] == ")"
|
197
179
|
s = s[1:-1]
|
198
180
|
|
199
|
-
float_size = len(s) / elsize / size
|
200
|
-
assert float_size in (4, 8)
|
201
|
-
|
202
|
-
dtype = np.float32 if float_size == 4 else float
|
203
181
|
ret = np.frombuffer(s.encode("latin-1"), dtype=dtype)
|
204
182
|
|
205
183
|
if nested is not None:
|
@@ -207,9 +185,9 @@ def _binary_field(*, nested: int | None = None) -> ParserElement:
|
|
207
185
|
|
208
186
|
return ret # type: ignore[return-value]
|
209
187
|
|
210
|
-
|
211
|
-
|
212
|
-
|
188
|
+
return (
|
189
|
+
common.integer.copy().add_parse_action(process_count) + list_
|
190
|
+
).add_parse_action(to_array)
|
213
191
|
|
214
192
|
|
215
193
|
def _list_of(entry: ParserElement) -> ParserElement:
|
@@ -337,15 +315,22 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
|
|
337
315
|
Opt(
|
338
316
|
Literal("List") + Literal("<") + Literal("scalar") + Literal(">")
|
339
317
|
).suppress()
|
340
|
-
+ (
|
318
|
+
+ (
|
319
|
+
_ascii_numeric_list(dtype=float, ignore=_COMMENT, empty_ok=True)
|
320
|
+
| _binary_numeric_list(dtype=np.float64, empty_ok=True)
|
321
|
+
| _binary_numeric_list(dtype=np.float32, empty_ok=True)
|
322
|
+
)
|
341
323
|
)
|
342
324
|
| (
|
343
325
|
Opt(
|
344
326
|
Literal("List") + Literal("<") + Literal("vector") + Literal(">")
|
345
327
|
).suppress()
|
346
328
|
+ (
|
347
|
-
|
348
|
-
|
329
|
+
_ascii_numeric_list(
|
330
|
+
dtype=float, nested=3, ignore=_COMMENT, empty_ok=True
|
331
|
+
)
|
332
|
+
| _binary_numeric_list(np.float64, nested=3, empty_ok=True)
|
333
|
+
| _binary_numeric_list(np.float32, nested=3, empty_ok=True)
|
349
334
|
)
|
350
335
|
)
|
351
336
|
| (
|
@@ -353,12 +338,11 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
|
|
353
338
|
Literal("List") + Literal("<") + Literal("symmTensor") + Literal(">")
|
354
339
|
).suppress()
|
355
340
|
+ (
|
356
|
-
|
357
|
-
nested=6,
|
358
|
-
force_float=True,
|
359
|
-
ignore=_COMMENT,
|
341
|
+
_ascii_numeric_list(
|
342
|
+
dtype=float, nested=6, ignore=_COMMENT, empty_ok=True
|
360
343
|
)
|
361
|
-
|
|
344
|
+
| _binary_numeric_list(np.float64, nested=6, empty_ok=True)
|
345
|
+
| _binary_numeric_list(np.float32, nested=6, empty_ok=True)
|
362
346
|
)
|
363
347
|
)
|
364
348
|
| (
|
@@ -366,8 +350,11 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
|
|
366
350
|
Literal("List") + Literal("<") + Literal("tensor") + Literal(">")
|
367
351
|
).suppress()
|
368
352
|
+ (
|
369
|
-
|
370
|
-
|
353
|
+
_ascii_numeric_list(
|
354
|
+
dtype=float, nested=9, ignore=_COMMENT, empty_ok=True
|
355
|
+
)
|
356
|
+
| _binary_numeric_list(np.float64, nested=9, empty_ok=True)
|
357
|
+
| _binary_numeric_list(np.float32, nested=9, empty_ok=True)
|
371
358
|
)
|
372
359
|
)
|
373
360
|
)
|
@@ -380,12 +367,7 @@ _KEYWORD_ENTRY = _keyword_entry_of(_TOKEN | _list_of(_IDENTIFIER), _DATA)
|
|
380
367
|
_DICT = _dict_of(_TOKEN, _DATA)
|
381
368
|
_DATA_ENTRY = Forward()
|
382
369
|
_LIST_ENTRY = _DICT | _KEYWORD_ENTRY | _DATA_ENTRY
|
383
|
-
_LIST = (
|
384
|
-
_numeric_list(ignore=_COMMENT)
|
385
|
-
| _numeric_list(nested=3, ignore=_COMMENT)
|
386
|
-
| _numeric_list(nested=4, ignore=_COMMENT)
|
387
|
-
| _list_of(_LIST_ENTRY)
|
388
|
-
)
|
370
|
+
_LIST = _list_of(_LIST_ENTRY)
|
389
371
|
_NUMBER = (
|
390
372
|
common.number
|
391
373
|
| CaselessKeyword("nan").set_parse_action(lambda: np.nan)
|
@@ -421,7 +403,19 @@ _LOCATED_DICTIONARY = Group(
|
|
421
403
|
located=True,
|
422
404
|
)
|
423
405
|
)[...]
|
424
|
-
_LOCATED_DATA = Group(
|
406
|
+
_LOCATED_DATA = Group(
|
407
|
+
Located(
|
408
|
+
(
|
409
|
+
_ascii_numeric_list(dtype=int, ignore=_COMMENT)
|
410
|
+
| _binary_numeric_list(dtype=np.int64)
|
411
|
+
| _binary_numeric_list(dtype=np.int32)
|
412
|
+
| _ascii_numeric_list(dtype=float, nested=3, ignore=_COMMENT)
|
413
|
+
| _binary_numeric_list(dtype=np.float64, nested=3)
|
414
|
+
| _binary_numeric_list(dtype=np.float32, nested=3)
|
415
|
+
| _DATA
|
416
|
+
).add_parse_action(lambda tks: ["", tks[0]])
|
417
|
+
)
|
418
|
+
)
|
425
419
|
|
426
420
|
_FILE = (
|
427
421
|
Dict(_LOCATED_DICTIONARY + Opt(_LOCATED_DATA) + _LOCATED_DICTIONARY)
|
foamlib/_files/_types.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import sys
|
4
|
-
from enum import Enum
|
5
4
|
from typing import Dict, NamedTuple, Optional, Union
|
6
5
|
|
7
6
|
import numpy as np
|
@@ -42,39 +41,6 @@ TensorLike = Union[
|
|
42
41
|
]
|
43
42
|
|
44
43
|
|
45
|
-
class TensorKind(Enum):
|
46
|
-
SCALAR = ()
|
47
|
-
VECTOR = (3,)
|
48
|
-
SYMM_TENSOR = (6,)
|
49
|
-
TENSOR = (9,)
|
50
|
-
|
51
|
-
@property
|
52
|
-
def shape(self) -> tuple[()] | tuple[int]:
|
53
|
-
shape: tuple[()] | tuple[int] = self.value
|
54
|
-
return shape
|
55
|
-
|
56
|
-
@property
|
57
|
-
def size(self) -> int:
|
58
|
-
return int(np.prod(self.shape))
|
59
|
-
|
60
|
-
def __str__(self) -> str:
|
61
|
-
return {
|
62
|
-
TensorKind.SCALAR: "scalar",
|
63
|
-
TensorKind.VECTOR: "vector",
|
64
|
-
TensorKind.SYMM_TENSOR: "symmTensor",
|
65
|
-
TensorKind.TENSOR: "tensor",
|
66
|
-
}[self]
|
67
|
-
|
68
|
-
@staticmethod
|
69
|
-
def from_shape(shape: tuple[int, ...]) -> TensorKind:
|
70
|
-
for kind in TensorKind:
|
71
|
-
if kind.shape == shape:
|
72
|
-
return kind
|
73
|
-
|
74
|
-
msg = f"No tensor kind for shape {shape!r}"
|
75
|
-
raise ValueError(msg)
|
76
|
-
|
77
|
-
|
78
44
|
class Dimensioned:
|
79
45
|
def __init__(
|
80
46
|
self,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
foamlib/__init__.py,sha256=
|
1
|
+
foamlib/__init__.py,sha256=0HqaL6QRggvb5wLBXgC3aMmHL7gltD8K2njaeYZJezI,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
|
@@ -11,10 +11,10 @@ foamlib/_cases/_util.py,sha256=QCizfbuJdOCeF9ogU2R-y-iWX5kfaOA4U2W68t6QlOM,2544
|
|
11
11
|
foamlib/_files/__init__.py,sha256=q1vkjXnjnSZvo45jPAICpWeF2LZv5V6xfzAR6S8fS5A,96
|
12
12
|
foamlib/_files/_files.py,sha256=gSJQjvB1f7N2yJtCTx9kpivKqSSNjDj37qNMpned5CM,19505
|
13
13
|
foamlib/_files/_io.py,sha256=BGbbm6HKxL2ka0YMCmHqZQZ1R4PPQlkvWWb4FHMAS8k,2217
|
14
|
-
foamlib/_files/_parsing.py,sha256=
|
14
|
+
foamlib/_files/_parsing.py,sha256=Nhktc7RnF7QIydUFm1umgQKiIW0s8GoPmagWRqfvaLQ,17404
|
15
15
|
foamlib/_files/_serialization.py,sha256=QJ-F6BKizVe0gpjnpIfPxNGTqWwalY4PQtCKdDY9D70,5502
|
16
|
-
foamlib/_files/_types.py,sha256=
|
17
|
-
foamlib-0.9.
|
18
|
-
foamlib-0.9.
|
19
|
-
foamlib-0.9.
|
20
|
-
foamlib-0.9.
|
16
|
+
foamlib/_files/_types.py,sha256=q5O_x680XhGfvPHCNF_3objK1imUG2kgQYNRF2Z4qJ0,2918
|
17
|
+
foamlib-0.9.1.dist-info/METADATA,sha256=ZSdTaK1ejV7YBHJVoQX384eudRHxTIxfjRiK7kH0Bxk,12906
|
18
|
+
foamlib-0.9.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
19
|
+
foamlib-0.9.1.dist-info/licenses/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
|
20
|
+
foamlib-0.9.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|