foamlib 0.6.15__py3-none-any.whl → 0.7.0__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 CHANGED
@@ -1,6 +1,6 @@
1
1
  """A Python interface for interacting with OpenFOAM."""
2
2
 
3
- __version__ = "0.6.15"
3
+ __version__ = "0.7.0"
4
4
 
5
5
  from ._cases import (
6
6
  AsyncFoamCase,
@@ -10,7 +10,7 @@ from ._cases import (
10
10
  FoamCaseBase,
11
11
  FoamCaseRunBase,
12
12
  )
13
- from ._files import FoamFieldFile, FoamFile, FoamFileBase
13
+ from ._files import FoamFieldFile, FoamFile
14
14
 
15
15
  __all__ = [
16
16
  "AsyncFoamCase",
@@ -21,5 +21,4 @@ __all__ = [
21
21
  "FoamCaseBase",
22
22
  "FoamCaseRunBase",
23
23
  "FoamFieldFile",
24
- "FoamFileBase",
25
24
  ]
@@ -1,8 +1,6 @@
1
- from ._base import FoamFileBase
2
1
  from ._files import FoamFieldFile, FoamFile
3
2
 
4
3
  __all__ = [
5
4
  "FoamFile",
6
5
  "FoamFieldFile",
7
- "FoamFileBase",
8
6
  ]
foamlib/_files/_files.py CHANGED
@@ -15,17 +15,25 @@ if sys.version_info >= (3, 9):
15
15
  else:
16
16
  from typing import Iterator, Mapping, MutableMapping, Sequence
17
17
 
18
- from ._base import FoamFileBase
19
18
  from ._io import FoamFileIO
20
19
  from ._serialization import Kind, dumps, normalize
20
+ from ._types import (
21
+ Data,
22
+ DataEntry,
23
+ Dict_,
24
+ Dimensioned,
25
+ DimensionSet,
26
+ Field,
27
+ File,
28
+ MutableData,
29
+ )
21
30
  from ._util import is_sequence
22
31
 
23
32
 
24
33
  class FoamFile(
25
- FoamFileBase,
26
34
  MutableMapping[
27
35
  Optional[Union[str, Tuple[str, ...]]],
28
- FoamFileBase._MutableData,
36
+ MutableData,
29
37
  ],
30
38
  FoamFileIO,
31
39
  ):
@@ -37,8 +45,11 @@ class FoamFile(
37
45
  Use as a context manager to make multiple changes to the file while saving all changes only once at the end.
38
46
  """
39
47
 
48
+ Dimensioned = Dimensioned
49
+ DimensionSet = DimensionSet
50
+
40
51
  class SubDict(
41
- MutableMapping[str, FoamFileBase._MutableData],
52
+ MutableMapping[str, MutableData],
42
53
  ):
43
54
  """An OpenFOAM dictionary within a file as a mutable mapping."""
44
55
 
@@ -46,15 +57,13 @@ class FoamFile(
46
57
  self._file = _file
47
58
  self._keywords = _keywords
48
59
 
49
- def __getitem__(
50
- self, keyword: str
51
- ) -> FoamFileBase._DataEntry | FoamFile.SubDict:
60
+ def __getitem__(self, keyword: str) -> DataEntry | FoamFile.SubDict:
52
61
  return self._file[(*self._keywords, keyword)]
53
62
 
54
63
  def __setitem__(
55
64
  self,
56
65
  keyword: str,
57
- data: FoamFileBase.Data,
66
+ data: Data,
58
67
  ) -> None:
59
68
  self._file[(*self._keywords, keyword)] = data
60
69
 
@@ -83,7 +92,7 @@ class FoamFile(
83
92
  def __repr__(self) -> str:
84
93
  return f"{type(self).__qualname__}('{self._file}', {self._keywords})"
85
94
 
86
- def as_dict(self) -> FoamFileBase._Dict:
95
+ def as_dict(self) -> Dict_:
87
96
  """Return a nested dict representation of the dictionary."""
88
97
  ret = self._file.as_dict(include_header=True)
89
98
 
@@ -91,9 +100,9 @@ class FoamFile(
91
100
  assert isinstance(ret, dict)
92
101
  v = ret[k]
93
102
  assert isinstance(v, dict)
94
- ret = cast(FoamFileBase._File, v)
103
+ ret = cast(File, v)
95
104
 
96
- return cast(FoamFileBase._Dict, ret)
105
+ return cast(Dict_, ret)
97
106
 
98
107
  @property
99
108
  def version(self) -> float:
@@ -165,7 +174,7 @@ class FoamFile(
165
174
 
166
175
  def __getitem__(
167
176
  self, keywords: str | tuple[str, ...] | None
168
- ) -> FoamFileBase._DataEntry | FoamFile.SubDict:
177
+ ) -> DataEntry | FoamFile.SubDict:
169
178
  if not keywords:
170
179
  keywords = ()
171
180
  elif not isinstance(keywords, tuple):
@@ -181,9 +190,7 @@ class FoamFile(
181
190
  return FoamFile.SubDict(self, keywords)
182
191
  return deepcopy(value)
183
192
 
184
- def __setitem__(
185
- self, keywords: str | tuple[str, ...] | None, data: FoamFileBase.Data
186
- ) -> None:
193
+ def __setitem__(self, keywords: str | tuple[str, ...] | None, data: Data) -> None:
187
194
  if not keywords:
188
195
  keywords = ()
189
196
  elif not isinstance(keywords, tuple):
@@ -368,7 +375,7 @@ class FoamFile(
368
375
  def __fspath__(self) -> str:
369
376
  return str(self.path)
370
377
 
371
- def as_dict(self, *, include_header: bool = False) -> FoamFileBase._File:
378
+ def as_dict(self, *, include_header: bool = False) -> File:
372
379
  """
373
380
  Return a nested dict representation of the file.
374
381
 
@@ -411,17 +418,17 @@ class FoamFieldFile(FoamFile):
411
418
  @property
412
419
  def value(
413
420
  self,
414
- ) -> FoamFile._Field:
421
+ ) -> Field:
415
422
  """Alias of `self["value"]`."""
416
423
  return cast(
417
- FoamFile._Field,
424
+ Field,
418
425
  self["value"],
419
426
  )
420
427
 
421
428
  @value.setter
422
429
  def value(
423
430
  self,
424
- value: FoamFile._Field,
431
+ value: Field,
425
432
  ) -> None:
426
433
  self["value"] = value
427
434
 
@@ -431,7 +438,7 @@ class FoamFieldFile(FoamFile):
431
438
 
432
439
  def __getitem__(
433
440
  self, keywords: str | tuple[str, ...] | None
434
- ) -> FoamFileBase._DataEntry | FoamFile.SubDict:
441
+ ) -> DataEntry | FoamFile.SubDict:
435
442
  if not keywords:
436
443
  keywords = ()
437
444
  elif not isinstance(keywords, tuple):
@@ -446,29 +453,29 @@ class FoamFieldFile(FoamFile):
446
453
  return ret
447
454
 
448
455
  @property
449
- def dimensions(self) -> FoamFile.DimensionSet | Sequence[float]:
456
+ def dimensions(self) -> DimensionSet | Sequence[float]:
450
457
  """Alias of `self["dimensions"]`."""
451
458
  ret = self["dimensions"]
452
- if not isinstance(ret, FoamFile.DimensionSet):
459
+ if not isinstance(ret, DimensionSet):
453
460
  msg = "dimensions is not a DimensionSet"
454
461
  raise TypeError(msg)
455
462
  return ret
456
463
 
457
464
  @dimensions.setter
458
- def dimensions(self, value: FoamFile.DimensionSet | Sequence[float]) -> None:
465
+ def dimensions(self, value: DimensionSet | Sequence[float]) -> None:
459
466
  self["dimensions"] = value
460
467
 
461
468
  @property
462
469
  def internal_field(
463
470
  self,
464
- ) -> FoamFile._Field:
471
+ ) -> Field:
465
472
  """Alias of `self["internalField"]`."""
466
- return cast(FoamFile._Field, self["internalField"])
473
+ return cast(Field, self["internalField"])
467
474
 
468
475
  @internal_field.setter
469
476
  def internal_field(
470
477
  self,
471
- value: FoamFile._Field,
478
+ value: Field,
472
479
  ) -> None:
473
480
  self["internalField"] = value
474
481
 
@@ -483,5 +490,5 @@ class FoamFieldFile(FoamFile):
483
490
  return ret
484
491
 
485
492
  @boundary_field.setter
486
- def boundary_field(self, value: Mapping[str, FoamFile._Dict]) -> None:
493
+ def boundary_field(self, value: Mapping[str, Dict_]) -> None:
487
494
  self["boundaryField"] = value
@@ -36,7 +36,7 @@ from pyparsing import (
36
36
  printables,
37
37
  )
38
38
 
39
- from ._base import FoamFileBase
39
+ from ._types import DataEntry, Dimensioned, DimensionSet, File
40
40
 
41
41
 
42
42
  def _list_of(entry: ParserElement) -> ParserElement:
@@ -120,7 +120,7 @@ _SWITCH = (
120
120
  ).set_parse_action(lambda: False)
121
121
  _DIMENSIONS = (
122
122
  Literal("[").suppress() + common.number[0, 7] + Literal("]").suppress()
123
- ).set_parse_action(lambda tks: FoamFileBase.DimensionSet(*tks))
123
+ ).set_parse_action(lambda tks: DimensionSet(*tks))
124
124
  _TENSOR = common.ieee_float | (
125
125
  Literal("(").suppress()
126
126
  + Group(
@@ -133,7 +133,7 @@ _IDENTIFIER = Combine(
133
133
  + Opt(Literal("(") + Word(_IDENTBODYCHARS, exclude_chars="()") + Literal(")"))
134
134
  )
135
135
  _DIMENSIONED = (Opt(_IDENTIFIER) + _DIMENSIONS + _TENSOR).set_parse_action(
136
- lambda tks: FoamFileBase.Dimensioned(*reversed(tks.as_list()))
136
+ lambda tks: Dimensioned(*reversed(tks.as_list()))
137
137
  )
138
138
  _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
139
139
  Keyword("nonuniform", _IDENTBODYCHARS).suppress()
@@ -253,24 +253,24 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
253
253
  )
254
254
  )
255
255
  _TOKEN = QuotedString('"', unquote_results=False) | _IDENTIFIER
256
- _DATA = Forward()
257
- _KEYWORD = _TOKEN | _list_of(_IDENTIFIER).set_parse_action(
256
+ DATA = Forward()
257
+ KEYWORD = _TOKEN | _list_of(_IDENTIFIER).set_parse_action(
258
258
  lambda tks: "(" + " ".join(tks[0]) + ")"
259
259
  )
260
- _KEYWORD_ENTRY = Dict(Group(_keyword_entry_of(_KEYWORD, _DATA)), asdict=True)
260
+ _KEYWORD_ENTRY = Dict(Group(_keyword_entry_of(KEYWORD, DATA)), asdict=True)
261
261
  _DATA_ENTRY = Forward()
262
262
  _LIST_ENTRY = _KEYWORD_ENTRY | _DATA_ENTRY
263
263
  _LIST = _list_of(_LIST_ENTRY)
264
264
  _NUMBER = common.signed_integer ^ common.ieee_float
265
265
  _DATA_ENTRY <<= _FIELD | _LIST | _DIMENSIONED | _DIMENSIONS | _NUMBER | _SWITCH | _TOKEN
266
266
 
267
- _DATA <<= _DATA_ENTRY[1, ...].set_parse_action(
267
+ DATA <<= _DATA_ENTRY[1, ...].set_parse_action(
268
268
  lambda tks: tuple(tks) if len(tks) > 1 else [tks[0]]
269
269
  )
270
270
 
271
271
  _FILE = (
272
272
  Dict(
273
- Group(_keyword_entry_of(_KEYWORD, Opt(_DATA, default=""), located=True))[...]
273
+ Group(_keyword_entry_of(KEYWORD, Opt(DATA, default=""), located=True))[...]
274
274
  + Opt(
275
275
  Group(
276
276
  Located(
@@ -280,7 +280,7 @@ _FILE = (
280
280
  )
281
281
  )
282
282
  )
283
- + Group(_keyword_entry_of(_KEYWORD, Opt(_DATA, default=""), located=True))[...]
283
+ + Group(_keyword_entry_of(KEYWORD, Opt(DATA, default=""), located=True))[...]
284
284
  )
285
285
  .ignore(cpp_style_comment)
286
286
  .ignore(Literal("#include") + ... + LineEnd()) # type: ignore [no-untyped-call]
@@ -288,11 +288,11 @@ _FILE = (
288
288
  )
289
289
 
290
290
 
291
- class Parsed(Mapping[Tuple[str, ...], Union[FoamFileBase._DataEntry, EllipsisType]]):
291
+ class Parsed(Mapping[Tuple[str, ...], Union[DataEntry, EllipsisType]]):
292
292
  def __init__(self, contents: bytes) -> None:
293
293
  self._parsed: MutableMapping[
294
294
  tuple[str, ...],
295
- tuple[int, FoamFileBase._DataEntry | EllipsisType, int],
295
+ tuple[int, DataEntry | EllipsisType, int],
296
296
  ] = {}
297
297
  for parse_result in _FILE.parse_string(
298
298
  contents.decode("latin-1"), parse_all=True
@@ -305,12 +305,10 @@ class Parsed(Mapping[Tuple[str, ...], Union[FoamFileBase._DataEntry, EllipsisTyp
305
305
  @staticmethod
306
306
  def _flatten_result(
307
307
  parse_result: ParseResults, *, _keywords: tuple[str, ...] = ()
308
- ) -> Mapping[
309
- tuple[str, ...], tuple[int, FoamFileBase._DataEntry | EllipsisType, int]
310
- ]:
308
+ ) -> Mapping[tuple[str, ...], tuple[int, DataEntry | EllipsisType, int]]:
311
309
  ret: MutableMapping[
312
310
  tuple[str, ...],
313
- tuple[int, FoamFileBase._DataEntry | EllipsisType, int],
311
+ tuple[int, DataEntry | EllipsisType, int],
314
312
  ] = {}
315
313
  start = parse_result.locn_start
316
314
  assert isinstance(start, int)
@@ -336,16 +334,14 @@ class Parsed(Mapping[Tuple[str, ...], Union[FoamFileBase._DataEntry, EllipsisTyp
336
334
  ret[(*_keywords, keyword)] = (start, d, end)
337
335
  return ret
338
336
 
339
- def __getitem__(
340
- self, keywords: tuple[str, ...]
341
- ) -> FoamFileBase._DataEntry | EllipsisType:
337
+ def __getitem__(self, keywords: tuple[str, ...]) -> DataEntry | EllipsisType:
342
338
  _, data, _ = self._parsed[keywords]
343
339
  return data
344
340
 
345
341
  def put(
346
342
  self,
347
343
  keywords: tuple[str, ...],
348
- data: FoamFileBase._DataEntry | EllipsisType,
344
+ data: DataEntry | EllipsisType,
349
345
  content: bytes,
350
346
  ) -> None:
351
347
  start, end = self.entry_location(keywords, missing_ok=True)
@@ -413,14 +409,14 @@ class Parsed(Mapping[Tuple[str, ...], Union[FoamFileBase._DataEntry, EllipsisTyp
413
409
 
414
410
  return start, end
415
411
 
416
- def as_dict(self) -> FoamFileBase._File:
417
- ret: FoamFileBase._File = {}
412
+ def as_dict(self) -> File:
413
+ ret: File = {}
418
414
  for keywords, (_, data, _) in self._parsed.items():
419
415
  r = ret
420
416
  for k in keywords[:-1]:
421
417
  v = r[k]
422
418
  assert isinstance(v, dict)
423
- r = cast(FoamFileBase._File, v)
419
+ r = cast(File, v)
424
420
 
425
421
  assert isinstance(r, dict)
426
422
  if keywords:
@@ -1,9 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import array
4
- import contextlib
5
4
  import itertools
6
- import re
7
5
  import sys
8
6
  from enum import Enum, auto
9
7
  from typing import cast, overload
@@ -13,7 +11,8 @@ if sys.version_info >= (3, 9):
13
11
  else:
14
12
  from typing import Mapping, Sequence
15
13
 
16
- from ._base import FoamFileBase
14
+ from ._parsing import DATA, KEYWORD
15
+ from ._types import Data, DataEntry, Dimensioned, DimensionSet
17
16
  from ._util import is_sequence
18
17
 
19
18
  try:
@@ -34,24 +33,15 @@ class Kind(Enum):
34
33
  DIMENSIONS = auto()
35
34
 
36
35
 
37
- _TOKENS = re.compile(r'(?:[^\s"]|"(?:[^"])*")+')
38
-
39
-
40
36
  @overload
41
- def normalize(
42
- data: FoamFileBase._DataEntry, *, kind: Kind = Kind.DEFAULT
43
- ) -> FoamFileBase._DataEntry: ...
37
+ def normalize(data: DataEntry, *, kind: Kind = Kind.DEFAULT) -> DataEntry: ...
44
38
 
45
39
 
46
40
  @overload
47
- def normalize(
48
- data: FoamFileBase.Data, *, kind: Kind = Kind.DEFAULT
49
- ) -> FoamFileBase.Data: ...
41
+ def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data: ...
50
42
 
51
43
 
52
- def normalize(
53
- data: FoamFileBase.Data, *, kind: Kind = Kind.DEFAULT
54
- ) -> FoamFileBase.Data:
44
+ def normalize(data: Data, *, kind: Kind = Kind.DEFAULT) -> Data:
55
45
  if numpy and isinstance(data, np.ndarray):
56
46
  ret = data.tolist()
57
47
  assert isinstance(ret, list)
@@ -67,54 +57,30 @@ def normalize(
67
57
  and all(isinstance(d, (int, float)) for d in data)
68
58
  ):
69
59
  data = cast(Sequence[float], data)
70
- return FoamFileBase.DimensionSet(*data)
60
+ return DimensionSet(*data)
71
61
 
72
62
  if is_sequence(data) and (kind == Kind.SINGLE_ENTRY or not isinstance(data, tuple)):
73
- return [normalize(d, kind=Kind.SINGLE_ENTRY) for d in data]
74
-
75
- if isinstance(data, str):
76
- data = data.strip()
77
-
78
- if data.startswith("(") and data.endswith(")"):
79
- data = data[1:-1].split()
80
- if kind == Kind.KEYWORD:
81
- return "(" + " ".join(data) + ")"
82
- return [normalize(d, kind=Kind.SINGLE_ENTRY) for d in data]
83
-
84
- if data.startswith("[") and data.endswith("]"):
85
- data = data[1:-1].split()
86
- return normalize(data, kind=Kind.DIMENSIONS)
87
-
88
- with contextlib.suppress(ValueError):
89
- return int(data)
90
-
91
- with contextlib.suppress(ValueError):
92
- return float(data)
63
+ if len(data) == 1 and isinstance(data[0], Mapping) and len(data[0]) > 1:
64
+ return [normalize({k: v}) for k, v in data[0].items()]
93
65
 
94
- if kind != Kind.KEYWORD:
95
- if data in ("yes", "true", "on", "y", "t"):
96
- return True
97
- if data in ("no", "false", "off", "n", "f"):
98
- return False
99
-
100
- tokens: list[str] = re.findall(_TOKENS, data)
66
+ return [normalize(d, kind=Kind.SINGLE_ENTRY) for d in data]
101
67
 
102
- if len(tokens) == 1:
103
- return tokens[0]
68
+ if isinstance(data, Dimensioned):
69
+ value = normalize(data.value, kind=Kind.SINGLE_ENTRY)
70
+ assert isinstance(value, (int, float, list))
71
+ return Dimensioned(value, data.dimensions, data.name)
104
72
 
73
+ if isinstance(data, str):
105
74
  if kind == Kind.KEYWORD:
106
- return " ".join(tokens)
107
-
108
- return tuple(tokens)
75
+ data = KEYWORD.parse_string(data, parse_all=True)[0]
76
+ assert isinstance(data, str)
77
+ return data
109
78
 
110
- if isinstance(data, FoamFileBase.Dimensioned):
111
- value = normalize(data.value, kind=Kind.SINGLE_ENTRY)
112
- assert isinstance(value, (int, float, list))
113
- return FoamFileBase.Dimensioned(value, data.dimensions, data.name)
79
+ return cast(DataEntry, DATA.parse_string(data, parse_all=True)[0])
114
80
 
115
81
  if isinstance(
116
82
  data,
117
- (int, float, bool, tuple, FoamFileBase.DimensionSet),
83
+ (int, float, bool, tuple, DimensionSet),
118
84
  ):
119
85
  return data
120
86
 
@@ -123,7 +89,7 @@ def normalize(
123
89
 
124
90
 
125
91
  def dumps(
126
- data: FoamFileBase.Data,
92
+ data: Data,
127
93
  *,
128
94
  kind: Kind = Kind.DEFAULT,
129
95
  ) -> bytes:
@@ -144,7 +110,7 @@ def dumps(
144
110
 
145
111
  return b" ".join(entries)
146
112
 
147
- if isinstance(data, FoamFileBase.DimensionSet):
113
+ if isinstance(data, DimensionSet):
148
114
  return b"[" + b" ".join(dumps(v) for v in data) + b"]"
149
115
 
150
116
  if kind in (
@@ -201,7 +167,7 @@ def dumps(
201
167
 
202
168
  return b"nonuniform List<" + tensor_kind + b"> " + dumps(len(data)) + contents
203
169
 
204
- if isinstance(data, FoamFileBase.Dimensioned):
170
+ if isinstance(data, Dimensioned):
205
171
  if data.name is not None:
206
172
  return (
207
173
  dumps(data.name)
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from dataclasses import dataclass
5
+ from typing import TYPE_CHECKING, Dict, NamedTuple, Optional, Tuple, Union
6
+
7
+ if TYPE_CHECKING:
8
+ import numpy as np
9
+
10
+ if sys.version_info >= (3, 9):
11
+ from collections.abc import Mapping, MutableMapping, Sequence
12
+ else:
13
+ from typing import Mapping, MutableMapping, Sequence
14
+
15
+
16
+ class DimensionSet(NamedTuple):
17
+ mass: float = 0
18
+ length: float = 0
19
+ time: float = 0
20
+ temperature: float = 0
21
+ moles: float = 0
22
+ current: float = 0
23
+ luminous_intensity: float = 0
24
+
25
+ def __repr__(self) -> str:
26
+ return f"{type(self).__name__}({', '.join(f'{n}={v}' for n, v in zip(self._fields, self) if v != 0)})"
27
+
28
+
29
+ Tensor = Union[
30
+ float,
31
+ Sequence[float],
32
+ "np.ndarray[Tuple[()], np.dtype[np.generic]]",
33
+ "np.ndarray[Tuple[int], np.dtype[np.generic]]",
34
+ ]
35
+
36
+
37
+ @dataclass
38
+ class Dimensioned:
39
+ value: Tensor = 0
40
+ dimensions: DimensionSet | Sequence[float] = ()
41
+ name: str | None = None
42
+
43
+ def __post_init__(self) -> None:
44
+ if not isinstance(self.dimensions, DimensionSet):
45
+ self.dimensions = DimensionSet(*self.dimensions)
46
+
47
+
48
+ Field = Union[
49
+ Tensor, Sequence[Tensor], "np.ndarray[Tuple[int, int], np.dtype[np.generic]]"
50
+ ]
51
+
52
+ DataEntry = Union[
53
+ str,
54
+ int,
55
+ float,
56
+ bool,
57
+ Dimensioned,
58
+ DimensionSet,
59
+ Sequence["Data"],
60
+ Tensor,
61
+ Field,
62
+ ]
63
+
64
+ Data = Union[
65
+ DataEntry,
66
+ Mapping[str, "Data"],
67
+ ]
68
+ """
69
+ A value that can be stored in an OpenFOAM file.
70
+ """
71
+
72
+ MutableData = Union[
73
+ DataEntry,
74
+ MutableMapping[str, "MutableData"],
75
+ ]
76
+
77
+ Dict_ = Dict[str, Union["Data", "Dict_"]]
78
+ File = Dict[Optional[str], Union["Data", "Dict_"]]
foamlib/_files/_util.py CHANGED
@@ -14,10 +14,10 @@ else:
14
14
  from typing_extensions import TypeGuard
15
15
 
16
16
  if TYPE_CHECKING:
17
- from ._base import FoamFileBase
17
+ from ._types import Data
18
18
 
19
19
 
20
20
  def is_sequence(
21
- value: FoamFileBase.Data,
22
- ) -> TypeGuard[Sequence[FoamFileBase.Data]]:
21
+ value: Data,
22
+ ) -> TypeGuard[Sequence[Data]]:
23
23
  return isinstance(value, Sequence) and not isinstance(value, str)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foamlib
3
- Version: 0.6.15
3
+ Version: 0.7.0
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
@@ -185,7 +185,7 @@ async def cost(x):
185
185
  await clone.run(fallback=True) # Run locally if Slurm is not available
186
186
  return abs(clone[-1]["U"].internal_field[0][0])
187
187
 
188
- result = differential_evolution(cost, bounds=[(-1, 1)], workers=AsyncFoamCase.map, polish=False)
188
+ result = differential_evolution(cost, bounds=[(-1, 1)], workers=AsyncSlurmFoamCase.map, polish=False)
189
189
  ```
190
190
 
191
191
  ### 📄 Use it to create a `run` (or `clean`) script
@@ -0,0 +1,22 @@
1
+ foamlib/__init__.py,sha256=OHt58vUx0Dlrq-2Nblufg5Cww_FfaUxvVAHqFcJTAQ4,452
2
+ foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ foamlib/_cases/__init__.py,sha256=wTUHcUgU1CBgpu0cUMtksQ5VKG6B8CFu9xc3dWwsQuo,358
4
+ foamlib/_cases/_async.py,sha256=i6g4EBHqvI-1PkdrxsRto2ynW7sxsOga2bSYk1XVG1U,7795
5
+ foamlib/_cases/_base.py,sha256=FKfZxP7HspWfSswQ6yZ5bGJRdZUlupQxj2tDqngXPmc,6785
6
+ foamlib/_cases/_run.py,sha256=lveqKZium_qK_eTxYE8jOjwx0eiIoolCBbi56-zLw1o,14420
7
+ foamlib/_cases/_slurm.py,sha256=kj4wqgr3foMyAoUkoHOZODRBmVqH1B9KqAIEEjM8ZBg,2328
8
+ foamlib/_cases/_subprocess.py,sha256=6BlBRxknj2-BFcGkx7oVcuL63_utSaY1Axmsc1qV9j8,3887
9
+ foamlib/_cases/_sync.py,sha256=2BJXB7Nzldb4OgPukqupgYqdceUGkI2mYhhtGPWEBrc,5901
10
+ foamlib/_cases/_util.py,sha256=lhVca3ERY0zwYjDam6W2QMROt0yX5vAF-9_DS5RuMbM,1547
11
+ foamlib/_files/__init__.py,sha256=GDkYkF3F-ADhkCRT3j9dQQHPP5LyJJYb8TaBbZTQ6fo,96
12
+ foamlib/_files/_files.py,sha256=LVLMeP9Zt9esuVGhntnjBA4_u_NhiX5xkm09Qemcle8,15846
13
+ foamlib/_files/_io.py,sha256=IQLqoqnA1TpHf21NbUho2wsYWevyqC6MKo-wfpaObUU,2226
14
+ foamlib/_files/_parsing.py,sha256=qEspHK6D4urT1qszfJcYptKg4xexfcA6pmcfw5uptCg,14007
15
+ foamlib/_files/_serialization.py,sha256=0vqJxltjscqp16mIvd0iKXbeRMbq3a7uLG2INWxzCBg,5861
16
+ foamlib/_files/_types.py,sha256=eY06nox8cZe6FixUQigvZRV9Fc7gwehJxuQz_wCCnqo,1678
17
+ foamlib/_files/_util.py,sha256=O9t2W26XDs63cVLroW8rZ35Puas20NhnKr_gLMlZixI,493
18
+ foamlib-0.7.0.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
+ foamlib-0.7.0.dist-info/METADATA,sha256=UFLbuRZL2MCR1z5k-FNTtVpuhSRT6OLyWG_ohgDiIDI,7727
20
+ foamlib-0.7.0.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
21
+ foamlib-0.7.0.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
+ foamlib-0.7.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.4.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
foamlib/_files/_base.py DELETED
@@ -1,76 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from dataclasses import dataclass
5
- from typing import TYPE_CHECKING, Dict, NamedTuple, Optional, Tuple, Union
6
-
7
- if TYPE_CHECKING:
8
- import numpy as np
9
-
10
- if sys.version_info >= (3, 9):
11
- from collections.abc import Mapping, MutableMapping, Sequence
12
- else:
13
- from typing import Mapping, MutableMapping, Sequence
14
-
15
-
16
- class FoamFileBase:
17
- class DimensionSet(NamedTuple):
18
- mass: float = 0
19
- length: float = 0
20
- time: float = 0
21
- temperature: float = 0
22
- moles: float = 0
23
- current: float = 0
24
- luminous_intensity: float = 0
25
-
26
- def __repr__(self) -> str:
27
- return f"{type(self).__qualname__}({', '.join(f'{n}={v}' for n, v in zip(self._fields, self) if v != 0)})"
28
-
29
- _Tensor = Union[
30
- float,
31
- Sequence[float],
32
- "np.ndarray[Tuple[()], np.dtype[np.generic]]",
33
- "np.ndarray[Tuple[int], np.dtype[np.generic]]",
34
- ]
35
-
36
- @dataclass
37
- class Dimensioned:
38
- value: FoamFileBase._Tensor = 0
39
- dimensions: FoamFileBase.DimensionSet | Sequence[float] = ()
40
- name: str | None = None
41
-
42
- def __post_init__(self) -> None:
43
- if not isinstance(self.dimensions, FoamFileBase.DimensionSet):
44
- self.dimensions = FoamFileBase.DimensionSet(*self.dimensions)
45
-
46
- _Field = Union[
47
- _Tensor, Sequence[_Tensor], "np.ndarray[Tuple[int, int], np.dtype[np.generic]]"
48
- ]
49
-
50
- _DataEntry = Union[
51
- str,
52
- int,
53
- float,
54
- bool,
55
- Dimensioned,
56
- DimensionSet,
57
- Sequence["Data"],
58
- _Tensor,
59
- _Field,
60
- ]
61
-
62
- Data = Union[
63
- _DataEntry,
64
- Mapping[str, "Data"],
65
- ]
66
- """
67
- A value that can be stored in an OpenFOAM file.
68
- """
69
-
70
- _MutableData = Union[
71
- _DataEntry,
72
- MutableMapping[str, "_MutableData"],
73
- ]
74
-
75
- _Dict = Dict[str, Union["Data", "_Dict"]]
76
- _File = Dict[Optional[str], Union["Data", "_Dict"]]
@@ -1,22 +0,0 @@
1
- foamlib/__init__.py,sha256=xxPlBXMsaxIeBwjjYk7kczK-LfoxBgDNnCG96cQcYss,487
2
- foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- foamlib/_cases/__init__.py,sha256=wTUHcUgU1CBgpu0cUMtksQ5VKG6B8CFu9xc3dWwsQuo,358
4
- foamlib/_cases/_async.py,sha256=i6g4EBHqvI-1PkdrxsRto2ynW7sxsOga2bSYk1XVG1U,7795
5
- foamlib/_cases/_base.py,sha256=FKfZxP7HspWfSswQ6yZ5bGJRdZUlupQxj2tDqngXPmc,6785
6
- foamlib/_cases/_run.py,sha256=lveqKZium_qK_eTxYE8jOjwx0eiIoolCBbi56-zLw1o,14420
7
- foamlib/_cases/_slurm.py,sha256=kj4wqgr3foMyAoUkoHOZODRBmVqH1B9KqAIEEjM8ZBg,2328
8
- foamlib/_cases/_subprocess.py,sha256=6BlBRxknj2-BFcGkx7oVcuL63_utSaY1Axmsc1qV9j8,3887
9
- foamlib/_cases/_sync.py,sha256=2BJXB7Nzldb4OgPukqupgYqdceUGkI2mYhhtGPWEBrc,5901
10
- foamlib/_cases/_util.py,sha256=lhVca3ERY0zwYjDam6W2QMROt0yX5vAF-9_DS5RuMbM,1547
11
- foamlib/_files/__init__.py,sha256=-UqB9YTH6mrJfXCX00kPTAAY20XG64u1MGPw_1ewLVs,148
12
- foamlib/_files/_base.py,sha256=ZY_6Zxr3LZHVzJEex6SUTi9Pgo7Oi7i3Jo-wre9G3yE,1968
13
- foamlib/_files/_files.py,sha256=5BUOHGDPaa4naNVQtpnDyhDzjY6s4Pg726DQOFNuHjs,15982
14
- foamlib/_files/_io.py,sha256=IQLqoqnA1TpHf21NbUho2wsYWevyqC6MKo-wfpaObUU,2226
15
- foamlib/_files/_parsing.py,sha256=sJ7XadWFqmJTaL9TEYyaYEu3r-CQweruwPUNWIZt4i0,14165
16
- foamlib/_files/_serialization.py,sha256=vfvSZqg0QTaoTJlZ9NacQ2HqmjaMGdtoUPZvsgMt14o,6680
17
- foamlib/_files/_util.py,sha256=VXUTD0B3NbnlaE_KCqWzrFcWvBz_2JfnIWpNp3snX3Y,526
18
- foamlib-0.6.15.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
- foamlib-0.6.15.dist-info/METADATA,sha256=eKZCMgAleMnArxpnqxN1eoepxqjBvA9yBhl1SBM8vE4,7723
20
- foamlib-0.6.15.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
21
- foamlib-0.6.15.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
- foamlib-0.6.15.dist-info/RECORD,,