foamlib 0.7.0__py3-none-any.whl → 0.7.2__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.7.0"
3
+ __version__ = "0.7.2"
4
4
 
5
5
  from ._cases import (
6
6
  AsyncFoamCase,
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import array
4
+ import re
4
5
  import sys
5
6
  from typing import Tuple, Union, cast
6
7
 
@@ -28,10 +29,10 @@ from pyparsing import (
28
29
  ParserElement,
29
30
  ParseResults,
30
31
  QuotedString,
32
+ Regex,
31
33
  Word,
32
34
  common,
33
35
  counted_array,
34
- cpp_style_comment,
35
36
  identchars,
36
37
  printables,
37
38
  )
@@ -40,7 +41,9 @@ from ._types import DataEntry, Dimensioned, DimensionSet, File
40
41
 
41
42
 
42
43
  def _list_of(entry: ParserElement) -> ParserElement:
43
- return (
44
+ return Opt(
45
+ Literal("List") + Literal("<") + _IDENTIFIER + Literal(">")
46
+ ).suppress() + (
44
47
  (
45
48
  counted_array(entry, common.integer + Literal("(").suppress())
46
49
  + Literal(")").suppress()
@@ -56,6 +59,58 @@ def _list_of(entry: ParserElement) -> ParserElement:
56
59
  )
57
60
 
58
61
 
62
+ def _counted_tensor_list(*, size: int, ignore: Regex) -> ParserElement:
63
+ float_pattern = r"[+-]?((\d+\.?\d*(e[+-]?\d+)?)|nan|inf(inity)?)"
64
+ ignore_pattern = rf"(?:\s|{ignore.re.pattern})+"
65
+
66
+ if size == 1:
67
+ tensor_pattern = float_pattern
68
+ tensor = common.ieee_float
69
+ else:
70
+ tensor_pattern = rf"\((?:{ignore_pattern})?(?:{float_pattern}{ignore_pattern}){{{size - 1}}}{float_pattern}(?:{ignore_pattern})?\)"
71
+ tensor = (
72
+ Literal("(").suppress()
73
+ + Group(common.ieee_float[size], aslist=True)
74
+ + Literal(")").suppress()
75
+ )
76
+
77
+ list_ = Forward()
78
+
79
+ def count_parse_action(tks: ParseResults) -> None:
80
+ nonlocal list_
81
+ length = tks[0]
82
+ assert isinstance(length, int)
83
+
84
+ list_ <<= Regex(
85
+ rf"\((?:{ignore_pattern})?(?:{tensor_pattern}{ignore_pattern}){{{length - 1}}}{tensor_pattern}(?:{ignore_pattern})?\)",
86
+ flags=re.IGNORECASE,
87
+ )
88
+
89
+ count = common.integer.add_parse_action(count_parse_action)
90
+
91
+ def list_parse_action(
92
+ tks: ParseResults,
93
+ ) -> list[list[float]] | list[list[list[float]]]:
94
+ values = [
95
+ float(v)
96
+ for v in re.sub(ignore.re, " ", tks[0])
97
+ .replace("(", " ")
98
+ .replace(")", " ")
99
+ .split()
100
+ ]
101
+
102
+ if size == 1:
103
+ return [values]
104
+
105
+ return [[values[i : i + size] for i in range(0, len(values), size)]]
106
+
107
+ list_.add_parse_action(list_parse_action)
108
+
109
+ return (count.suppress() + list_) | (
110
+ common.integer + Literal("{").suppress() + tensor + Literal("}").suppress()
111
+ ).set_parse_action(lambda tks: [[tks[1]] * tks[0]])
112
+
113
+
59
114
  def _keyword_entry_of(
60
115
  keyword: ParserElement,
61
116
  data_entries: ParserElement,
@@ -96,6 +151,9 @@ def _unpack_binary_field(
96
151
  return [values]
97
152
 
98
153
 
154
+ # https://github.com/pyparsing/pyparsing/pull/584
155
+ _COMMENT = Regex(r"(?:/\*(?:[^*]|\*(?!/))*\*/)|(?://(?:\\\n|[^\n])*)")
156
+
99
157
  _IDENTCHARS = identchars + "$"
100
158
  _IDENTBODYCHARS = (
101
159
  printables.replace(";", "")
@@ -124,7 +182,7 @@ _DIMENSIONS = (
124
182
  _TENSOR = common.ieee_float | (
125
183
  Literal("(").suppress()
126
184
  + Group(
127
- common.ieee_float[9] | common.ieee_float[6] | common.ieee_float[3], aslist=True
185
+ common.ieee_float[3] | common.ieee_float[6] | common.ieee_float[9], aslist=True
128
186
  )
129
187
  + Literal(")").suppress()
130
188
  )
@@ -145,7 +203,7 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
145
203
  Literal("scalar").suppress()
146
204
  + Literal(">").suppress()
147
205
  + (
148
- _list_of(common.ieee_float)
206
+ _counted_tensor_list(size=1, ignore=_COMMENT)
149
207
  | (
150
208
  (
151
209
  (
@@ -169,11 +227,7 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
169
227
  Literal("vector").suppress()
170
228
  + Literal(">").suppress()
171
229
  + (
172
- _list_of(
173
- Literal("(").suppress()
174
- + Group(common.ieee_float[3], aslist=True)
175
- + Literal(")").suppress()
176
- )
230
+ _counted_tensor_list(size=3, ignore=_COMMENT)
177
231
  | (
178
232
  (
179
233
  (
@@ -194,14 +248,10 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
194
248
  )
195
249
  )
196
250
  | (
197
- Literal("vector").suppress()
251
+ Literal("symmTensor").suppress()
198
252
  + Literal(">").suppress()
199
253
  + (
200
- _list_of(
201
- Literal("(").suppress()
202
- + Group(common.ieee_float[6], aslist=True)
203
- + Literal(")").suppress()
204
- )
254
+ _counted_tensor_list(size=6, ignore=_COMMENT)
205
255
  | (
206
256
  (
207
257
  (
@@ -225,11 +275,7 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
225
275
  Literal("tensor").suppress()
226
276
  + Literal(">").suppress()
227
277
  + (
228
- _list_of(
229
- Literal("(").suppress()
230
- + Group(common.ieee_float[9], aslist=True)
231
- + Literal(")").suppress()
232
- )
278
+ _counted_tensor_list(size=9, ignore=_COMMENT)
233
279
  | (
234
280
  (
235
281
  (
@@ -254,8 +300,12 @@ _FIELD = (Keyword("uniform", _IDENTBODYCHARS).suppress() + _TENSOR) | (
254
300
  )
255
301
  _TOKEN = QuotedString('"', unquote_results=False) | _IDENTIFIER
256
302
  DATA = Forward()
257
- KEYWORD = _TOKEN | _list_of(_IDENTIFIER).set_parse_action(
258
- lambda tks: "(" + " ".join(tks[0]) + ")"
303
+ KEYWORD = (
304
+ _TOKEN
305
+ | _list_of(_IDENTIFIER)
306
+ .set_parse_action(lambda tks: "(" + " ".join(tks[0]) + ")")
307
+ .ignore(_COMMENT)
308
+ .parse_with_tabs()
259
309
  )
260
310
  _KEYWORD_ENTRY = Dict(Group(_keyword_entry_of(KEYWORD, DATA)), asdict=True)
261
311
  _DATA_ENTRY = Forward()
@@ -264,25 +314,20 @@ _LIST = _list_of(_LIST_ENTRY)
264
314
  _NUMBER = common.signed_integer ^ common.ieee_float
265
315
  _DATA_ENTRY <<= _FIELD | _LIST | _DIMENSIONED | _DIMENSIONS | _NUMBER | _SWITCH | _TOKEN
266
316
 
267
- DATA <<= _DATA_ENTRY[1, ...].set_parse_action(
268
- lambda tks: tuple(tks) if len(tks) > 1 else [tks[0]]
317
+ DATA <<= (
318
+ _DATA_ENTRY[1, ...]
319
+ .set_parse_action(lambda tks: tuple(tks) if len(tks) > 1 else [tks[0]])
320
+ .ignore(_COMMENT)
321
+ .parse_with_tabs()
269
322
  )
270
323
 
271
324
  _FILE = (
272
325
  Dict(
273
326
  Group(_keyword_entry_of(KEYWORD, Opt(DATA, default=""), located=True))[...]
274
- + Opt(
275
- Group(
276
- Located(
277
- _DATA_ENTRY[1, ...].set_parse_action(
278
- lambda tks: [None, tuple(tks) if len(tks) > 1 else tks[0]]
279
- )
280
- )
281
- )
282
- )
327
+ + Opt(Group(Located(DATA.copy().add_parse_action(lambda tks: ["", tks[0]]))))
283
328
  + Group(_keyword_entry_of(KEYWORD, Opt(DATA, default=""), located=True))[...]
284
329
  )
285
- .ignore(cpp_style_comment)
330
+ .ignore(_COMMENT)
286
331
  .ignore(Literal("#include") + ... + LineEnd()) # type: ignore [no-untyped-call]
287
332
  .parse_with_tabs()
288
333
  )
@@ -317,7 +362,8 @@ class Parsed(Mapping[Tuple[str, ...], Union[DataEntry, EllipsisType]]):
317
362
  end = parse_result.locn_end
318
363
  assert isinstance(end, int)
319
364
  keyword, *data = item
320
- if keyword is None:
365
+ assert isinstance(keyword, str)
366
+ if not keyword:
321
367
  assert not _keywords
322
368
  assert len(data) == 1
323
369
  assert not isinstance(data[0], ParseResults)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: foamlib
3
- Version: 0.7.0
3
+ Version: 0.7.2
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
@@ -69,13 +69,19 @@ Requires-Dist: mypy <2,>=1 ; extra == 'typing'
69
69
  [![Docker](https://github.com/gerlero/foamlib/actions/workflows/docker.yml/badge.svg)](https://github.com/gerlero/foamlib/actions/workflows/docker.yml)
70
70
  [![Docker image](https://img.shields.io/badge/docker%20image-microfluidica%2Ffoamlib-0085a0)](https://hub.docker.com/r/microfluidica/foamlib/)
71
71
 
72
- ## 👋 Basics
72
+ **foamlib** provides a simple, modern, ergonomic and fast Python interface for interacting with [OpenFOAM](https://www.openfoam.com).
73
+
74
+ <p align="center">
75
+ <img alt="benchmark" src="https://github.com/gerlero/foamlib/raw/main/benchmark.png" height="250">
76
+ <br>
77
+ <i>Parsing a </i>volVectorField<i> with 200k cells.</i>
78
+ </p>
73
79
 
74
- **foamlib** provides a simple, modern and ergonomic Python interface for interacting with [OpenFOAM](https://www.openfoam.com).
80
+ ## 👋 Basics
75
81
 
76
- It offers the following Python classes:
82
+ **foamlib** offers the following Python classes:
77
83
 
78
- * [`FoamFile`](https://foamlib.readthedocs.io/en/stable/files.html#foamlib.FoamFile) (and [`FoamFieldFile`](https://foamlib.readthedocs.io/en/stable/files.html#foamlib.FoamFieldFile)): read-write access to OpenFOAM configuration and field files as if they were Python `dict`s, using `foamlib`'s own parser. Supports ASCII and binary field formats (with or without compression).
84
+ * [`FoamFile`](https://foamlib.readthedocs.io/en/stable/files.html#foamlib.FoamFile) (and [`FoamFieldFile`](https://foamlib.readthedocs.io/en/stable/files.html#foamlib.FoamFieldFile)): read-write access to OpenFOAM configuration and field files as if they were Python `dict`s, using `foamlib`'s own parser and in-place editor. Supports ASCII and binary field formats (with or without compression).
79
85
  * [`FoamCase`](https://foamlib.readthedocs.io/en/stable/cases.html#foamlib.FoamCase): a class for configuring, running, and accessing the results of OpenFOAM cases.
80
86
  * [`AsyncFoamCase`](https://foamlib.readthedocs.io/en/stable/cases.html#foamlib.AsyncFoamCase): variant of `FoamCase` with asynchronous methods for running multiple cases at once.
81
87
  * [`AsyncSlurmFoamCase`](https://foamlib.readthedocs.io/en/stable/cases.html#foamlib.AsyncSlurmFoamCase): subclass of `AsyncFoamCase` used for running cases on a Slurm cluster.
@@ -1,4 +1,4 @@
1
- foamlib/__init__.py,sha256=OHt58vUx0Dlrq-2Nblufg5Cww_FfaUxvVAHqFcJTAQ4,452
1
+ foamlib/__init__.py,sha256=YrFnCARXwvjW-QZzK9cS_ivto2gvTEJwdSVU5ZfCBkM,452
2
2
  foamlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  foamlib/_cases/__init__.py,sha256=wTUHcUgU1CBgpu0cUMtksQ5VKG6B8CFu9xc3dWwsQuo,358
4
4
  foamlib/_cases/_async.py,sha256=i6g4EBHqvI-1PkdrxsRto2ynW7sxsOga2bSYk1XVG1U,7795
@@ -11,12 +11,12 @@ foamlib/_cases/_util.py,sha256=lhVca3ERY0zwYjDam6W2QMROt0yX5vAF-9_DS5RuMbM,1547
11
11
  foamlib/_files/__init__.py,sha256=GDkYkF3F-ADhkCRT3j9dQQHPP5LyJJYb8TaBbZTQ6fo,96
12
12
  foamlib/_files/_files.py,sha256=LVLMeP9Zt9esuVGhntnjBA4_u_NhiX5xkm09Qemcle8,15846
13
13
  foamlib/_files/_io.py,sha256=IQLqoqnA1TpHf21NbUho2wsYWevyqC6MKo-wfpaObUU,2226
14
- foamlib/_files/_parsing.py,sha256=qEspHK6D4urT1qszfJcYptKg4xexfcA6pmcfw5uptCg,14007
14
+ foamlib/_files/_parsing.py,sha256=D1l7j_KldD6h-iJvFT6c0CiwctWvUxeGJxh-J93zDs8,15430
15
15
  foamlib/_files/_serialization.py,sha256=0vqJxltjscqp16mIvd0iKXbeRMbq3a7uLG2INWxzCBg,5861
16
16
  foamlib/_files/_types.py,sha256=eY06nox8cZe6FixUQigvZRV9Fc7gwehJxuQz_wCCnqo,1678
17
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,,
18
+ foamlib-0.7.2.dist-info/LICENSE.txt,sha256=5Dte9TUnLZzPRs4NQzl-Jc2-Ljd-t_v0ZR5Ng5r0UsY,35131
19
+ foamlib-0.7.2.dist-info/METADATA,sha256=dK_DN2ZLU49org-G_XI4kdNDg551I8b68d52Q4cAePU,7957
20
+ foamlib-0.7.2.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
21
+ foamlib-0.7.2.dist-info/top_level.txt,sha256=ZdVYtetXGwPwyfL-WhlhbTFQGAwKX5P_gXxtH9JYFPI,8
22
+ foamlib-0.7.2.dist-info/RECORD,,