foamlib 0.1.6__tar.gz → 0.1.8__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.1.6 → foamlib-0.1.8}/PKG-INFO +4 -1
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib/__init__.py +1 -1
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib/_cases.py +0 -1
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib/_dictionaries.py +55 -117
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib.egg-info/PKG-INFO +4 -1
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib.egg-info/requires.txt +3 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/pyproject.toml +25 -1
- {foamlib-0.1.6 → foamlib-0.1.8}/tests/test_dictionaries.py +15 -3
- {foamlib-0.1.6 → foamlib-0.1.8}/LICENSE.txt +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/README.md +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib/_subprocesses.py +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib/py.typed +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib.egg-info/SOURCES.txt +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib.egg-info/dependency_links.txt +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/foamlib.egg-info/top_level.txt +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/setup.cfg +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/tests/test_basic.py +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/tests/test_flange.py +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/tests/test_flange_async.py +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/tests/test_pitz.py +0 -0
- {foamlib-0.1.6 → foamlib-0.1.8}/tests/test_pitz_async.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: foamlib
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.8
|
4
4
|
Summary: A Python interface for interacting with OpenFOAM
|
5
5
|
Author-email: "Gabriel S. Gerlero" <ggerlero@cimec.unl.edu.ar>
|
6
6
|
Project-URL: Homepage, https://github.com/gerlero/foamlib
|
@@ -26,12 +26,15 @@ Requires-Python: >=3.7
|
|
26
26
|
Description-Content-Type: text/markdown
|
27
27
|
License-File: LICENSE.txt
|
28
28
|
Requires-Dist: aioshutil<2,>=1
|
29
|
+
Requires-Dist: pyparsing<4,>=3
|
29
30
|
Provides-Extra: lint
|
30
31
|
Requires-Dist: mypy<2,>=1; extra == "lint"
|
31
32
|
Requires-Dist: pytest<9,>=7; extra == "lint"
|
32
33
|
Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "lint"
|
33
34
|
Requires-Dist: numpy<2,>=1; extra == "lint"
|
34
35
|
Requires-Dist: black; extra == "lint"
|
36
|
+
Requires-Dist: flake8; extra == "lint"
|
37
|
+
Requires-Dist: Flake8-pyproject; extra == "lint"
|
35
38
|
Provides-Extra: test
|
36
39
|
Requires-Dist: pytest<9,>=7; extra == "test"
|
37
40
|
Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "test"
|
@@ -23,6 +23,7 @@ except ModuleNotFoundError:
|
|
23
23
|
else:
|
24
24
|
numpy = True
|
25
25
|
|
26
|
+
from pyparsing import Group, Keyword, Opt, ZeroOrMore, Literal, Forward, common
|
26
27
|
|
27
28
|
FoamDimensionSet = namedtuple(
|
28
29
|
"FoamDimensionSet",
|
@@ -63,108 +64,46 @@ FoamValue = Union[
|
|
63
64
|
A value that can be stored in an OpenFOAM dictionary.
|
64
65
|
"""
|
65
66
|
|
67
|
+
_YES = Keyword("yes").set_parse_action(lambda s, loc, tks: True)
|
68
|
+
_NO = Keyword("no").set_parse_action(lambda s, loc, tks: False)
|
69
|
+
_VALUE = Forward()
|
70
|
+
_LIST = Opt(
|
71
|
+
Literal("List") + Literal("<") + common.identifier + Literal(">")
|
72
|
+
).suppress() + (
|
73
|
+
(
|
74
|
+
Opt(common.integer).suppress()
|
75
|
+
+ Literal("(").suppress()
|
76
|
+
+ Group(ZeroOrMore(_VALUE))
|
77
|
+
+ Literal(")").suppress()
|
78
|
+
)
|
79
|
+
| (
|
80
|
+
common.integer + Literal("{").suppress() + _VALUE + Literal("}").suppress()
|
81
|
+
).set_parse_action(lambda s, loc, tks: [tks[1]] * tks[0])
|
82
|
+
)
|
83
|
+
_FIELD = (Keyword("uniform").suppress() + _VALUE) | (
|
84
|
+
Keyword("nonuniform").suppress() + _LIST
|
85
|
+
)
|
86
|
+
_DIMENSIONS = (
|
87
|
+
Literal("[").suppress() + common.number * 7 + Literal("]").suppress()
|
88
|
+
).set_parse_action(lambda s, loc, tks: FoamDimensionSet(*tks))
|
89
|
+
_DIMENSIONED = (common.identifier + _DIMENSIONS + _VALUE).set_parse_action(
|
90
|
+
lambda s, loc, tks: FoamDimensioned(tks[0], tks[1], tks[2].as_list())
|
91
|
+
)
|
66
92
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
with suppress(ValueError):
|
78
|
-
return int(value)
|
79
|
-
with suppress(ValueError):
|
80
|
-
return float(value)
|
81
|
-
raise ValueError(f"Cannot parse '{value}' as a number")
|
82
|
-
|
83
|
-
|
84
|
-
def _parse_sequence(value: str) -> Sequence[FoamValue]:
|
85
|
-
start = value.find("(")
|
86
|
-
if start != -1:
|
87
|
-
assert value.endswith(")")
|
88
|
-
seq = []
|
89
|
-
nested = 0
|
90
|
-
start += 1
|
91
|
-
for i, c in enumerate(value[start:], start=start):
|
92
|
-
if c == "(":
|
93
|
-
nested += 1
|
94
|
-
elif c == ")":
|
95
|
-
nested -= 1
|
96
|
-
if c.isspace() and not nested:
|
97
|
-
v = value[start:i].strip()
|
98
|
-
if v:
|
99
|
-
seq.append(_parse(v))
|
100
|
-
start = i + 1
|
101
|
-
|
102
|
-
v = value[start:-1].strip()
|
103
|
-
if v:
|
104
|
-
seq.append(_parse(v))
|
105
|
-
|
106
|
-
return seq
|
107
|
-
|
108
|
-
else:
|
109
|
-
raise ValueError(f"Cannot parse '{value}' as a sequence")
|
110
|
-
|
111
|
-
|
112
|
-
def _parse_field(value: str) -> FoamValue:
|
113
|
-
if value.startswith("uniform "):
|
114
|
-
value = value[len("uniform ") :]
|
115
|
-
return _parse(value)
|
116
|
-
elif value.startswith("nonuniform "):
|
117
|
-
value = value[len("nonuniform ") :]
|
118
|
-
return _parse_sequence(value)
|
119
|
-
else:
|
120
|
-
raise ValueError(f"Cannot parse '{value}' as a field")
|
121
|
-
|
122
|
-
|
123
|
-
def _parse_dimensions(value: str) -> FoamDimensionSet:
|
124
|
-
if value.startswith("["):
|
125
|
-
assert value.endswith("]")
|
126
|
-
return FoamDimensionSet(*(_parse_number(v) for v in value[1:-1].split()))
|
127
|
-
else:
|
128
|
-
raise ValueError(f"Cannot parse '{value}' as a dimension set")
|
129
|
-
|
130
|
-
|
131
|
-
def _parse_dimensioned(value: str) -> FoamDimensioned:
|
132
|
-
start = value.find("[", 1)
|
133
|
-
if start != -1:
|
134
|
-
name = value[:start].strip()
|
135
|
-
end = value.find("]", start)
|
136
|
-
if end != -1:
|
137
|
-
dimensions = _parse_dimensions(value[start : end + 1])
|
138
|
-
value = value[end + 1 :].strip()
|
139
|
-
return FoamDimensioned(
|
140
|
-
name,
|
141
|
-
dimensions,
|
142
|
-
cast(Union[int, float, Sequence[Union[int, float]]], _parse(value)),
|
143
|
-
)
|
144
|
-
|
145
|
-
raise ValueError(f"Cannot parse '{value}' as a dimensioned value")
|
93
|
+
_VALUE << (
|
94
|
+
_FIELD
|
95
|
+
| _LIST
|
96
|
+
| _DIMENSIONED
|
97
|
+
| _DIMENSIONS
|
98
|
+
| common.number
|
99
|
+
| _YES
|
100
|
+
| _NO
|
101
|
+
| common.identifier
|
102
|
+
)
|
146
103
|
|
147
104
|
|
148
105
|
def _parse(value: str) -> FoamValue:
|
149
|
-
|
150
|
-
return _parse_bool(value)
|
151
|
-
|
152
|
-
with suppress(ValueError):
|
153
|
-
return _parse_field(value)
|
154
|
-
|
155
|
-
with suppress(ValueError):
|
156
|
-
return _parse_number(value)
|
157
|
-
|
158
|
-
with suppress(ValueError):
|
159
|
-
return _parse_dimensions(value)
|
160
|
-
|
161
|
-
with suppress(ValueError):
|
162
|
-
return _parse_dimensioned(value)
|
163
|
-
|
164
|
-
with suppress(ValueError):
|
165
|
-
return _parse_sequence(value)
|
166
|
-
|
167
|
-
return value
|
106
|
+
return cast(FoamValue, _VALUE.parse_string(value, parse_all=True).as_list()[0])
|
168
107
|
|
169
108
|
|
170
109
|
def _serialize_bool(value: Any) -> str:
|
@@ -176,24 +115,26 @@ def _serialize_bool(value: Any) -> str:
|
|
176
115
|
raise TypeError(f"Not a bool: {type(value)}")
|
177
116
|
|
178
117
|
|
179
|
-
def
|
180
|
-
|
181
|
-
isinstance(
|
182
|
-
and not isinstance(
|
118
|
+
def _is_sequence(value: Any) -> bool:
|
119
|
+
return (
|
120
|
+
isinstance(value, Sequence)
|
121
|
+
and not isinstance(value, str)
|
183
122
|
or numpy
|
184
|
-
and isinstance(
|
185
|
-
)
|
186
|
-
|
123
|
+
and isinstance(value, np.ndarray)
|
124
|
+
)
|
125
|
+
|
126
|
+
|
127
|
+
def _serialize_list(value: Any) -> str:
|
128
|
+
if _is_sequence(value):
|
129
|
+
return f"({' '.join(_serialize(v) for v in value)})"
|
187
130
|
else:
|
188
|
-
raise TypeError(f"Not a valid sequence: {type(
|
131
|
+
raise TypeError(f"Not a valid sequence: {type(value)}")
|
189
132
|
|
190
133
|
|
191
134
|
def _serialize_field(value: Any) -> str:
|
192
|
-
if
|
193
|
-
return f"uniform {value}"
|
194
|
-
else:
|
135
|
+
if _is_sequence(value):
|
195
136
|
try:
|
196
|
-
s =
|
137
|
+
s = _serialize_list(value)
|
197
138
|
except TypeError:
|
198
139
|
raise TypeError(f"Not a valid field: {type(value)}") from None
|
199
140
|
else:
|
@@ -213,15 +154,12 @@ def _serialize_field(value: Any) -> str:
|
|
213
154
|
f"Unsupported sequence length for field: {len(value[0])}"
|
214
155
|
)
|
215
156
|
return f"nonuniform List<{kind}> {len(value)}{s}"
|
157
|
+
else:
|
158
|
+
return f"uniform {value}"
|
216
159
|
|
217
160
|
|
218
161
|
def _serialize_dimensions(value: Any) -> str:
|
219
|
-
if (
|
220
|
-
isinstance(value, Sequence)
|
221
|
-
and not isinstance(value, str)
|
222
|
-
or numpy
|
223
|
-
and isinstance(value, np.ndarray)
|
224
|
-
) and len(value) == 7:
|
162
|
+
if _is_sequence(value) and len(value) == 7:
|
225
163
|
return f"[{' '.join(str(v) for v in value)}]"
|
226
164
|
else:
|
227
165
|
raise TypeError(f"Not a valid dimension set: {type(value)}")
|
@@ -249,7 +187,7 @@ def _serialize(
|
|
249
187
|
return _serialize_dimensioned(value)
|
250
188
|
|
251
189
|
with suppress(TypeError):
|
252
|
-
return
|
190
|
+
return _serialize_list(value)
|
253
191
|
|
254
192
|
with suppress(TypeError):
|
255
193
|
return _serialize_bool(value)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: foamlib
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.8
|
4
4
|
Summary: A Python interface for interacting with OpenFOAM
|
5
5
|
Author-email: "Gabriel S. Gerlero" <ggerlero@cimec.unl.edu.ar>
|
6
6
|
Project-URL: Homepage, https://github.com/gerlero/foamlib
|
@@ -26,12 +26,15 @@ Requires-Python: >=3.7
|
|
26
26
|
Description-Content-Type: text/markdown
|
27
27
|
License-File: LICENSE.txt
|
28
28
|
Requires-Dist: aioshutil<2,>=1
|
29
|
+
Requires-Dist: pyparsing<4,>=3
|
29
30
|
Provides-Extra: lint
|
30
31
|
Requires-Dist: mypy<2,>=1; extra == "lint"
|
31
32
|
Requires-Dist: pytest<9,>=7; extra == "lint"
|
32
33
|
Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "lint"
|
33
34
|
Requires-Dist: numpy<2,>=1; extra == "lint"
|
34
35
|
Requires-Dist: black; extra == "lint"
|
36
|
+
Requires-Dist: flake8; extra == "lint"
|
37
|
+
Requires-Dist: Flake8-pyproject; extra == "lint"
|
35
38
|
Provides-Extra: test
|
36
39
|
Requires-Dist: pytest<9,>=7; extra == "test"
|
37
40
|
Requires-Dist: pytest-asyncio<0.24,>=0.21; extra == "test"
|
@@ -27,7 +27,10 @@ classifiers = [
|
|
27
27
|
"Typing :: Typed",
|
28
28
|
]
|
29
29
|
|
30
|
-
dependencies = [
|
30
|
+
dependencies = [
|
31
|
+
"aioshutil>=1,<2",
|
32
|
+
"pyparsing>=3,<4",
|
33
|
+
]
|
31
34
|
|
32
35
|
dynamic = ["version"]
|
33
36
|
|
@@ -38,6 +41,8 @@ lint = [
|
|
38
41
|
"pytest-asyncio>=0.21,<0.24",
|
39
42
|
"numpy>=1,<2",
|
40
43
|
"black",
|
44
|
+
"flake8",
|
45
|
+
"Flake8-pyproject",
|
41
46
|
]
|
42
47
|
test = [
|
43
48
|
"pytest>=7,<9",
|
@@ -71,3 +76,22 @@ packages = [
|
|
71
76
|
"tests",
|
72
77
|
]
|
73
78
|
strict = true
|
79
|
+
|
80
|
+
[tool.flake8]
|
81
|
+
count = true
|
82
|
+
ignore = [
|
83
|
+
"E203", # whitespace before ':'
|
84
|
+
"E501", # line too long
|
85
|
+
"E704", # multiple statements on one line (def)
|
86
|
+
"F403", # 'from foamlib import *' used; unable to detect undefined names
|
87
|
+
"F405", # 'FoamDimensionSet' may be undefined, or defined from star imports: foamlib
|
88
|
+
"W503", # line break before binary operator
|
89
|
+
]
|
90
|
+
exclude = [
|
91
|
+
".git",
|
92
|
+
"__pycache__",
|
93
|
+
"docs/source/conf.py",
|
94
|
+
"build",
|
95
|
+
"dist",
|
96
|
+
"venv",
|
97
|
+
]
|
@@ -14,8 +14,8 @@ def test_parse() -> None:
|
|
14
14
|
assert _parse("1") == 1
|
15
15
|
assert _parse("1.0") == 1.0
|
16
16
|
assert _parse("1.0e-3") == 1.0e-3
|
17
|
-
assert _parse("yes")
|
18
|
-
assert _parse("no")
|
17
|
+
assert _parse("yes") is True
|
18
|
+
assert _parse("no") is False
|
19
19
|
assert _parse("uniform 1") == 1
|
20
20
|
assert _parse("uniform 1.0") == 1.0
|
21
21
|
assert _parse("uniform 1.0e-3") == 1.0e-3
|
@@ -137,6 +137,18 @@ def test_internal_field(pitz: FoamCase) -> None:
|
|
137
137
|
|
138
138
|
pitz.clean()
|
139
139
|
|
140
|
+
p_arr = np.zeros(size)
|
141
|
+
U_arr = np.zeros((size, 3))
|
142
|
+
|
143
|
+
pitz[0]["p"].internal_field = p_arr
|
144
|
+
pitz[0]["U"].internal_field = U_arr
|
145
|
+
|
146
|
+
assert pitz[0]["p"].internal_field == pytest.approx(p_arr)
|
147
|
+
U = pitz[0]["U"].internal_field
|
148
|
+
assert isinstance(U, Sequence)
|
149
|
+
for u, u_arr in zip(U, U_arr):
|
150
|
+
assert u == pytest.approx(u_arr)
|
151
|
+
|
140
152
|
p_arr = np.arange(size) * 1e-6
|
141
153
|
U_arr = np.full((size, 3), [-1e-6, 1e-6, 0]) * np.arange(size)[:, np.newaxis]
|
142
154
|
|
@@ -144,7 +156,7 @@ def test_internal_field(pitz: FoamCase) -> None:
|
|
144
156
|
pitz[0]["U"].internal_field = U_arr
|
145
157
|
|
146
158
|
assert pitz[0]["p"].internal_field == pytest.approx(p_arr)
|
147
|
-
U = pitz[
|
159
|
+
U = pitz[0]["U"].internal_field
|
148
160
|
assert isinstance(U, Sequence)
|
149
161
|
for u, u_arr in zip(U, U_arr):
|
150
162
|
assert u == pytest.approx(u_arr)
|
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
|
File without changes
|
File without changes
|