foamlib 0.9.0__tar.gz → 0.9.1__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.
Files changed (63) hide show
  1. {foamlib-0.9.0 → foamlib-0.9.1}/PKG-INFO +1 -1
  2. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/__init__.py +1 -1
  3. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_files/_parsing.py +99 -105
  4. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_files/_types.py +0 -34
  5. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_files.py +0 -1
  6. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_basic.py +9 -15
  7. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_decompose_par.py +1 -2
  8. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_intermediate.py +4 -39
  9. {foamlib-0.9.0 → foamlib-0.9.1}/.devcontainer.json +0 -0
  10. {foamlib-0.9.0 → foamlib-0.9.1}/.dockerignore +0 -0
  11. {foamlib-0.9.0 → foamlib-0.9.1}/.git-blame-ignore-revs +0 -0
  12. {foamlib-0.9.0 → foamlib-0.9.1}/.github/dependabot.yml +0 -0
  13. {foamlib-0.9.0 → foamlib-0.9.1}/.github/workflows/ci.yml +0 -0
  14. {foamlib-0.9.0 → foamlib-0.9.1}/.github/workflows/docker.yml +0 -0
  15. {foamlib-0.9.0 → foamlib-0.9.1}/.github/workflows/dockerhub-description.yml +0 -0
  16. {foamlib-0.9.0 → foamlib-0.9.1}/.github/workflows/pypi-publish.yml +0 -0
  17. {foamlib-0.9.0 → foamlib-0.9.1}/.gitignore +0 -0
  18. {foamlib-0.9.0 → foamlib-0.9.1}/.readthedocs.yaml +0 -0
  19. {foamlib-0.9.0 → foamlib-0.9.1}/CONTRIBUTING.md +0 -0
  20. {foamlib-0.9.0 → foamlib-0.9.1}/Dockerfile +0 -0
  21. {foamlib-0.9.0 → foamlib-0.9.1}/LICENSE.txt +0 -0
  22. {foamlib-0.9.0 → foamlib-0.9.1}/README.md +0 -0
  23. {foamlib-0.9.0 → foamlib-0.9.1}/benchmark/benchmark.png +0 -0
  24. {foamlib-0.9.0 → foamlib-0.9.1}/benchmark/benchmark.py +0 -0
  25. {foamlib-0.9.0 → foamlib-0.9.1}/benchmark/requirements.txt +0 -0
  26. {foamlib-0.9.0 → foamlib-0.9.1}/benchmark/ruff.toml +0 -0
  27. {foamlib-0.9.0 → foamlib-0.9.1}/docs/Makefile +0 -0
  28. {foamlib-0.9.0 → foamlib-0.9.1}/docs/cases.rst +0 -0
  29. {foamlib-0.9.0 → foamlib-0.9.1}/docs/conf.py +0 -0
  30. {foamlib-0.9.0 → foamlib-0.9.1}/docs/files.rst +0 -0
  31. {foamlib-0.9.0 → foamlib-0.9.1}/docs/index.rst +0 -0
  32. {foamlib-0.9.0 → foamlib-0.9.1}/docs/make.bat +0 -0
  33. {foamlib-0.9.0 → foamlib-0.9.1}/docs/ruff.toml +0 -0
  34. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/__init__.py +0 -0
  35. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_async.py +0 -0
  36. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_base.py +0 -0
  37. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_run.py +0 -0
  38. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_slurm.py +0 -0
  39. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_subprocess.py +0 -0
  40. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_sync.py +0 -0
  41. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_cases/_util.py +0 -0
  42. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_files/__init__.py +0 -0
  43. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_files/_files.py +0 -0
  44. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_files/_io.py +0 -0
  45. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/_files/_serialization.py +0 -0
  46. {foamlib-0.9.0 → foamlib-0.9.1}/foamlib/py.typed +0 -0
  47. {foamlib-0.9.0 → foamlib-0.9.1}/logo.png +0 -0
  48. {foamlib-0.9.0 → foamlib-0.9.1}/pyproject.toml +0 -0
  49. {foamlib-0.9.0 → foamlib-0.9.1}/tests/__init__.py +0 -0
  50. {foamlib-0.9.0 → foamlib-0.9.1}/tests/ruff.toml +0 -0
  51. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_cases/__init__.py +0 -0
  52. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_cases/test_cavity.py +0 -0
  53. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_cases/test_cavity_async.py +0 -0
  54. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_cases/test_flange.py +0 -0
  55. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_cases/test_flange_async.py +0 -0
  56. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_example.py +0 -0
  57. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/__init__.py +0 -0
  58. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_dumps.py +0 -0
  59. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/__init__.py +0 -0
  60. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_advanced.py +0 -0
  61. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_fields.py +0 -0
  62. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_fv_schemes.py +0 -0
  63. {foamlib-0.9.0 → foamlib-0.9.1}/tests/test_files/test_parsing/test_poly_mesh.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: foamlib
3
- Version: 0.9.0
3
+ Version: 0.9.1
4
4
  Summary: A Python interface for interacting with OpenFOAM
5
5
  Project-URL: Homepage, https://github.com/gerlero/foamlib
6
6
  Project-URL: Repository, https://github.com/gerlero/foamlib
@@ -1,6 +1,6 @@
1
1
  """A Python interface for interacting with OpenFOAM."""
2
2
 
3
- __version__ = "0.9.0"
3
+ __version__ = "0.9.1"
4
4
 
5
5
  from ._cases import (
6
6
  AsyncFoamCase,
@@ -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
- def _numeric_list(
45
- *, nested: int | None = None, ignore: Regex | None = None, force_float: bool = False
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
- if not force_float:
48
- int_pattern = r"(?:-?\d+)"
49
- float_pattern = r"(?i:[+-]?(?:(?:\d+\.?\d*(?:e[+-]?\d+)?)|nan|inf(?:inity)?))"
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"\s+"
67
+ rf"(?:(?:\s|{ignore.re.pattern})+)" if ignore is not None else r"(?:\s+)"
52
68
  )
53
69
 
54
- if nested is None:
55
- if not force_float:
56
- int_element_pattern = int_pattern
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
- if not force_float:
78
- int_list = Forward()
79
- float_list = Forward()
76
+ list_ = Forward()
80
77
 
81
78
  def process_count(tks: ParseResults) -> None:
82
- nonlocal int_list, float_list
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 force_float:
92
- int_list_pattern = rf"\({spacing_pattern}?(?:{int_element_pattern}{spacing_pattern})*{int_element_pattern}{spacing_pattern}?\)"
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
- float_list_pattern = rf"\({spacing_pattern}?(?:{float_element_pattern}{spacing_pattern})*{float_element_pattern}?{spacing_pattern}?\)"
91
+ list_pattern = rf"\({spacing_pattern}?(?:{element_pattern}{spacing_pattern})*{element_pattern}?{spacing_pattern}?\)"
96
92
 
97
93
  elif count == 0:
98
- if not force_float:
99
- int_list <<= NoMatch()
100
- float_list <<= NoMatch()
94
+ if not empty_ok:
95
+ list_ <<= NoMatch()
101
96
  else:
102
- float_list <<= (Literal("(") + Literal(")")).add_parse_action(
103
- lambda: np.empty((0, nested) if nested else 0, dtype=float)
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
- if not force_float:
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
- if not force_float:
113
- int_list <<= Regex(int_list_pattern).add_parse_action(
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: type
122
- ) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.int64 | np.float64]]:
110
+ tks: ParseResults, *, dtype: DTypeLike
111
+ ) -> np.ndarray[tuple[int] | tuple[int, int], np.dtype[np.integer | np.floating]]:
123
112
  (s,) = tks
124
- s = s.replace("(", "").replace(")", "")
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.int64 | np.float64]
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.int64 | np.float64]]:
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
- count = Opt(common.integer).add_parse_action(process_count)
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 _binary_field(*, nested: int | None = None) -> ParserElement:
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
- binary_field = Forward()
158
+ list_ = Forward()
179
159
 
180
160
  def process_count(tks: ParseResults) -> None:
181
- nonlocal binary_field
161
+ nonlocal list_
182
162
  (size,) = tks
183
163
  assert isinstance(size, int)
184
164
 
185
- binary_field <<= Regex(
186
- rf"\((?s:({'.' * 8 * elsize}|{'.' * 4 * elsize}){{{size}}})\)"
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.float64 | np.float32]]:
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
- count = common.integer.copy().add_parse_action(process_count)
211
-
212
- return (count + binary_field).add_parse_action(to_array)
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
- + (_numeric_list(force_float=True, ignore=_COMMENT) | _binary_field())
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
- _numeric_list(nested=3, force_float=True, ignore=_COMMENT)
348
- | _binary_field(nested=3)
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
- _numeric_list(
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
- | _binary_field(nested=6)
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
- _numeric_list(nested=9, force_float=True, ignore=_COMMENT)
370
- | _binary_field(nested=9)
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(Located(_DATA.copy().add_parse_action(lambda tks: ["", tks[0]])))
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)
@@ -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,
@@ -162,7 +162,6 @@ def test_internal_field(cavity: FoamCase) -> None:
162
162
  blocks = cavity.block_mesh_dict["blocks"]
163
163
  assert isinstance(blocks, list)
164
164
  sizes = blocks[2]
165
- assert isinstance(sizes, np.ndarray)
166
165
  size = np.prod(sizes)
167
166
 
168
167
  p_arr = np.zeros(size)
@@ -1,6 +1,7 @@
1
1
  import numpy as np
2
2
  from foamlib import FoamFile
3
3
  from foamlib._files._parsing import Parsed
4
+ from foamlib._files._types import is_sequence
4
5
 
5
6
 
6
7
  def test_parse_value() -> None:
@@ -18,13 +19,9 @@ def test_parse_value() -> None:
18
19
  assert Parsed(b"uniform 1.0e-3")[()] == 1.0e-3
19
20
  assert Parsed(b"(word word)")[()] == ["word", "word"]
20
21
  lst = Parsed(b"(1 2 3)")[()]
21
- assert isinstance(lst, np.ndarray)
22
- assert lst.dtype == np.int64
23
- assert np.array_equal(lst, [1, 2, 3])
22
+ assert np.array_equal(lst, [1, 2, 3]) # type: ignore[arg-type]
24
23
  lst = Parsed(b"(1.0 2 3)")[()]
25
- assert isinstance(lst, np.ndarray)
26
- assert lst.dtype == np.float64
27
- assert np.array_equal(lst, [1.0, 2.0, 3.0])
24
+ assert np.array_equal(lst, [1.0, 2.0, 3.0]) # type: ignore[arg-type]
28
25
  assert Parsed(b"()")[()] == []
29
26
  field = Parsed(b"uniform (1 2 3)")[()]
30
27
  assert isinstance(field, np.ndarray)
@@ -109,16 +106,13 @@ def test_parse_value() -> None:
109
106
  assert isinstance(tpl, tuple)
110
107
  assert len(tpl) == 5
111
108
  assert tpl[0] == "hex"
112
- assert isinstance(tpl[1], np.ndarray)
113
- assert tpl[1].dtype == np.int64
114
- assert np.array_equal(tpl[1], [0, 1, 2, 3, 4, 5, 6, 7])
115
- assert isinstance(tpl[2], np.ndarray)
116
- assert tpl[2].dtype == np.int64
117
- assert np.array_equal(tpl[2], [1, 1, 1])
109
+ assert is_sequence(tpl[1])
110
+ assert np.array_equal(tpl[1], [0, 1, 2, 3, 4, 5, 6, 7]) # type: ignore[arg-type]
111
+ assert is_sequence(tpl[2])
112
+ assert np.array_equal(tpl[2], [1, 1, 1]) # type: ignore[arg-type]
118
113
  assert tpl[3] == "simpleGrading"
119
- assert isinstance(tpl[4], np.ndarray)
120
- assert tpl[4].dtype == np.int64
121
- assert np.array_equal(tpl[4], [1, 1, 1])
114
+ assert is_sequence(tpl[4])
115
+ assert np.array_equal(tpl[4], [1, 1, 1]) # type: ignore[arg-type]
122
116
  assert Parsed(b"(a b; c d;)")[()] == [("a", "b"), ("c", "d")]
123
117
  assert Parsed(b"(a {b c;} d {e g;})")[()] == [
124
118
  ("a", {"b": "c"}),
@@ -44,8 +44,7 @@ def test_simple(tmp_path: Path) -> None:
44
44
 
45
45
  assert decompose_par_dict["numberOfSubdomains"] == 8
46
46
  assert decompose_par_dict["method"] == "simple"
47
- assert isinstance(decompose_par_dict["coeffs", "n"], np.ndarray)
48
- assert np.array_equal(decompose_par_dict["coeffs", "n"], [4, 2, 1])
47
+ assert np.array_equal(decompose_par_dict["coeffs", "n"], [4, 2, 1]) # type: ignore[arg-type]
49
48
  assert decompose_par_dict["coeffs", "order"] == "xyz"
50
49
  assert decompose_par_dict["coeffs", "delta"] == 0.001
51
50
 
@@ -69,9 +69,7 @@ def test_list_simple() -> None:
69
69
  (2 3 4 5)
70
70
  );
71
71
  """)[("faces",)]
72
-
73
- assert isinstance(faces, np.ndarray)
74
- assert np.array_equal(faces, [[1, 5, 4, 0], [2, 3, 4, 5]])
72
+ assert np.array_equal(faces, [[1, 5, 4, 0], [2, 3, 4, 5]]) # type: ignore[arg-type]
75
73
 
76
74
 
77
75
  def test_list_assignment() -> None:
@@ -84,8 +82,7 @@ def test_list_assignment() -> None:
84
82
  0
85
83
  );
86
84
  """)[("faces",)]
87
- assert isinstance(faces, np.ndarray)
88
- assert np.array_equal(faces, [1, 5, 4, 0])
85
+ assert np.array_equal(faces, [1, 5, 4, 0]) # type: ignore[arg-type]
89
86
 
90
87
 
91
88
  def test_dict_simple() -> None:
@@ -138,8 +135,7 @@ def test_dict_with_list() -> None:
138
135
  pRefValue 0;
139
136
  }
140
137
  """)
141
- assert isinstance(parsed[("PISO", "pRefPoint")], np.ndarray)
142
- assert np.array_equal(parsed[("PISO", "pRefPoint")], [0, 0, 0])
138
+ assert np.array_equal(parsed[("PISO", "pRefPoint")], [0, 0, 0]) # type: ignore[arg-type]
143
139
 
144
140
 
145
141
  def test_list_with_dict() -> None:
@@ -164,7 +160,6 @@ def test_list_with_dict() -> None:
164
160
  assert upper_boundary[0] == "upperBoundary"
165
161
  assert upper_boundary[1]["type"] == "cyclic"
166
162
  assert upper_boundary[1]["neighbourPatch"] == "lowerBoundary"
167
- assert isinstance(upper_boundary[1]["faces"], np.ndarray)
168
163
  assert np.array_equal(upper_boundary[1]["faces"], [[3, 7, 6, 2]])
169
164
 
170
165
 
@@ -179,12 +174,9 @@ def test_list_with_str() -> None:
179
174
  assert len(blocks) == 5
180
175
 
181
176
  assert blocks[0] == "hex"
182
- assert isinstance(blocks[1], np.ndarray)
183
177
  assert np.array_equal(blocks[1], [0, 1, 2, 3, 4, 5, 6, 7])
184
- assert isinstance(blocks[2], np.ndarray)
185
178
  assert np.array_equal(blocks[2], [40, 40, 40])
186
179
  assert blocks[3] == "simpleGrading"
187
- assert isinstance(blocks[4], np.ndarray)
188
180
  assert np.array_equal(blocks[4], [1, 1, 1])
189
181
 
190
182
 
@@ -238,8 +230,7 @@ def test_file() -> None:
238
230
  assert parsed[("a",)] == 1
239
231
  assert parsed[("b",)] == 2
240
232
  faces = parsed[("faces",)]
241
- assert isinstance(faces, np.ndarray)
242
- assert np.array_equal(faces, [[1, 5, 4, 0], [2, 3, 4, 5]])
233
+ assert np.array_equal(faces, [[1, 5, 4, 0], [2, 3, 4, 5]]) # type: ignore[arg-type]
243
234
  assert parsed[("my_dict", "a")] == 1
244
235
 
245
236
 
@@ -466,7 +457,6 @@ def test_for_blockmesh() -> None:
466
457
  assert len(blocks) == 4
467
458
 
468
459
  assert blocks[0] == "hex"
469
- assert isinstance(blocks[1], np.ndarray)
470
460
  assert np.array_equal(blocks[1], [4, 6, 14, 12, 0, 2, 10, 8])
471
461
  assert blocks[2] == [1, "$upstreamCells", "$cylinderBoxCells"]
472
462
  assert blocks[3] == "$expandBlock"
@@ -497,38 +487,26 @@ def test_blocks() -> None:
497
487
  assert len(blocks) == 22
498
488
 
499
489
  assert blocks[0] == "hex"
500
- assert isinstance(blocks[1], np.ndarray)
501
490
  assert np.array_equal(blocks[1], [0, 1, 2, 3, 4, 5, 6, 7])
502
491
  assert blocks[2] == "inletChannel"
503
- assert isinstance(blocks[3], np.ndarray)
504
492
  assert np.array_equal(blocks[3], [40, 1, 64])
505
493
  assert blocks[4] == "simpleGrading"
506
- assert isinstance(blocks[5], np.ndarray)
507
494
  assert np.array_equal(blocks[5], [1, 1, 1])
508
495
  assert blocks[6] == "hex"
509
- assert isinstance(blocks[7], np.ndarray)
510
496
  assert np.array_equal(blocks[7], [4, 5, 6, 7, 8, 9, 10, 11, 12])
511
497
  assert blocks[8] == "inletChannel"
512
- assert isinstance(blocks[9], np.ndarray)
513
498
  assert np.array_equal(blocks[9], [40, 1, 16])
514
499
  assert blocks[10] == "simpleGrading"
515
- assert isinstance(blocks[11], np.ndarray)
516
500
  assert np.array_equal(blocks[11], [1, 1, 1])
517
501
  assert blocks[12] == "hex"
518
- assert isinstance(blocks[13], np.ndarray)
519
502
  assert np.array_equal(blocks[13], [12, 13, 14, 15, 16, 17, 18, 19])
520
- assert isinstance(blocks[14], np.ndarray)
521
503
  assert np.array_equal(blocks[14], [96, 1, 8])
522
504
  assert blocks[15] == "simpleGrading"
523
- assert isinstance(blocks[16], np.ndarray)
524
505
  assert np.array_equal(blocks[16], [1, 1, 1])
525
506
  assert blocks[17] == "hex"
526
- assert isinstance(blocks[18], np.ndarray)
527
507
  assert np.array_equal(blocks[18], [16, 17, 18, 19, 20, 21, 22, 23])
528
- assert isinstance(blocks[19], np.ndarray)
529
508
  assert np.array_equal(blocks[19], [96, 1, 72])
530
509
  assert blocks[20] == "simpleGrading"
531
- assert isinstance(blocks[21], np.ndarray)
532
510
  assert np.array_equal(blocks[21], [1, 1, 1])
533
511
 
534
512
 
@@ -616,7 +594,6 @@ def test_list_edges() -> None:
616
594
  assert edges[0] == "spline"
617
595
  assert edges[1] == 1
618
596
  assert edges[2] == 2
619
- assert isinstance(edges[3], np.ndarray)
620
597
  assert np.array_equal(
621
598
  edges[3],
622
599
  [
@@ -634,7 +611,6 @@ def test_list_edges() -> None:
634
611
  assert edges[4] == "spline"
635
612
  assert edges[5] == 6
636
613
  assert edges[6] == 5
637
- assert isinstance(edges[7], np.ndarray)
638
614
  assert np.array_equal(
639
615
  edges[7],
640
616
  [
@@ -666,13 +642,11 @@ def test_list_edges_arcs() -> None:
666
642
  assert edges[1] == 0
667
643
  assert edges[2] == 5
668
644
  assert edges[3] == "origin"
669
- assert isinstance(edges[4], np.ndarray)
670
645
  assert np.array_equal(edges[4], [0, 0, 0])
671
646
  assert edges[5] == "arc"
672
647
  assert edges[6] == 5
673
648
  assert edges[7] == 10
674
649
  assert edges[8] == "origin"
675
- assert isinstance(edges[9], np.ndarray)
676
650
  assert np.array_equal(edges[9], [0, 0, 0])
677
651
 
678
652
 
@@ -691,39 +665,30 @@ def test_list_blocks() -> None:
691
665
  assert len(blocks) == 15
692
666
 
693
667
  assert blocks[0] == "hex"
694
- assert isinstance(blocks[1], np.ndarray)
695
668
  assert np.array_equal(blocks[1], [0, 1, 9, 8, 7, 6, 14, 15])
696
- assert isinstance(blocks[2], np.ndarray)
697
669
  assert np.array_equal(blocks[2], [50, 100, 1])
698
670
  assert blocks[3] == "simpleGrading"
699
671
  assert isinstance(blocks[4], list)
700
672
  assert len(blocks[4]) == 3
701
673
  assert blocks[4][0] == 1
702
- assert isinstance(blocks[4][1], np.ndarray)
703
674
  assert np.array_equal(blocks[4][1], [[0.1, 0.25, 41.9], [0.9, 0.75, 1]])
704
675
  assert blocks[4][2] == 1
705
676
  assert blocks[5] == "hex"
706
- assert isinstance(blocks[6], np.ndarray)
707
677
  assert np.array_equal(blocks[6], [1, 2, 10, 9, 6, 5, 13, 14])
708
- assert isinstance(blocks[7], np.ndarray)
709
678
  assert np.array_equal(blocks[7], [50, 100, 1])
710
679
  assert blocks[8] == "simpleGrading"
711
680
  assert isinstance(blocks[9], list)
712
681
  assert len(blocks[9]) == 3
713
682
  assert blocks[9][0] == 1
714
- assert isinstance(blocks[9][1], np.ndarray)
715
683
  assert np.array_equal(blocks[9][1], [[0.1, 0.25, 41.9], [0.9, 0.75, 1]])
716
684
  assert blocks[9][2] == 1
717
685
  assert blocks[10] == "hex"
718
- assert isinstance(blocks[11], np.ndarray)
719
686
  assert np.array_equal(blocks[11], [2, 3, 11, 10, 5, 4, 12, 13])
720
- assert isinstance(blocks[12], np.ndarray)
721
687
  assert np.array_equal(blocks[12], [225, 100, 1])
722
688
  assert blocks[13] == "simpleGrading"
723
689
  assert isinstance(blocks[14], list)
724
690
  assert len(blocks[14]) == 3
725
691
  assert blocks[14][0] == 1
726
- assert isinstance(blocks[14][1], np.ndarray)
727
692
  assert np.array_equal(blocks[14][1], [[0.1, 0.25, 41.9], [0.9, 0.75, 1]])
728
693
  assert blocks[14][2] == 1
729
694
 
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
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
File without changes
File without changes
File without changes
File without changes
File without changes