foamlib 0.8.7__tar.gz → 0.8.9__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.8.7 → foamlib-0.8.9}/.github/workflows/ci.yml +5 -5
- {foamlib-0.8.7 → foamlib-0.8.9}/.github/workflows/pypi-publish.yml +1 -1
- foamlib-0.8.9/CONTRIBUTING.md +93 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/PKG-INFO +179 -13
- foamlib-0.8.9/README.md +316 -0
- foamlib-0.8.9/benchmark/benchmark.py +17 -0
- foamlib-0.8.9/benchmark/requirements.txt +2 -0
- foamlib-0.8.9/benchmark/ruff.toml +4 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/__init__.py +1 -1
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_async.py +93 -12
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_base.py +21 -5
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_run.py +17 -12
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_slurm.py +10 -1
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_sync.py +94 -12
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_files/_files.py +110 -16
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_files/_parsing.py +8 -4
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_files/_serialization.py +20 -8
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_files/_types.py +43 -17
- {foamlib-0.8.7 → foamlib-0.8.9}/pyproject.toml +14 -7
- foamlib-0.8.9/tests/test_example.py +154 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_files/test_files.py +6 -1
- foamlib-0.8.9/tests/test_files/test_parsing/__init__.py +0 -0
- foamlib-0.8.9/tests/test_files/test_parsing/test_advanced.py +364 -0
- foamlib-0.8.7/tests/test_files/test_parsing.py → foamlib-0.8.9/tests/test_files/test_parsing/test_basic.py +1 -0
- foamlib-0.8.9/tests/test_files/test_parsing/test_decompose_par.py +74 -0
- foamlib-0.8.9/tests/test_files/test_parsing/test_fields.py +302 -0
- foamlib-0.8.9/tests/test_files/test_parsing/test_fv_schemes.py +72 -0
- foamlib-0.8.9/tests/test_files/test_parsing/test_intermediate.py +718 -0
- foamlib-0.8.9/tests/test_files/test_parsing/test_poly_mesh.py +66 -0
- foamlib-0.8.7/README.md +0 -156
- {foamlib-0.8.7 → foamlib-0.8.9}/.devcontainer.json +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.dockerignore +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.git-blame-ignore-revs +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.github/dependabot.yml +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.github/workflows/docker.yml +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.github/workflows/dockerhub-description.yml +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.gitignore +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/.readthedocs.yaml +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/Dockerfile +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/LICENSE.txt +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9/benchmark}/benchmark.png +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/Makefile +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/cases.rst +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/conf.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/files.rst +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/index.rst +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/make.bat +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/docs/ruff.toml +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/__init__.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_subprocess.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_cases/_util.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_files/__init__.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/_files/_io.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/foamlib/py.typed +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/logo.png +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/__init__.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/ruff.toml +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_cases/__init__.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_cases/test_cavity.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_cases/test_cavity_async.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_cases/test_flange.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_cases/test_flange_async.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_files/__init__.py +0 -0
- {foamlib-0.8.7 → foamlib-0.8.9}/tests/test_files/test_dumps.py +0 -0
@@ -28,14 +28,14 @@ jobs:
|
|
28
28
|
- name: Checkout
|
29
29
|
uses: actions/checkout@v4
|
30
30
|
- name: Install uv
|
31
|
-
uses: astral-sh/setup-uv@
|
31
|
+
uses: astral-sh/setup-uv@v6
|
32
32
|
- name: Set up Python
|
33
33
|
uses: actions/setup-python@v5
|
34
34
|
with:
|
35
35
|
python-version-file: pyproject.toml
|
36
36
|
- name: Check types with mypy
|
37
37
|
run: |
|
38
|
-
uv run
|
38
|
+
uv run mypy
|
39
39
|
|
40
40
|
test:
|
41
41
|
runs-on: ubuntu-22.04
|
@@ -74,7 +74,7 @@ jobs:
|
|
74
74
|
with:
|
75
75
|
openfoam-version: ${{ matrix.openfoam-version }}
|
76
76
|
- name: Install uv
|
77
|
-
uses: astral-sh/setup-uv@
|
77
|
+
uses: astral-sh/setup-uv@v6
|
78
78
|
- name: Set up Python ${{ matrix.python-version }}
|
79
79
|
uses: actions/setup-python@v5
|
80
80
|
with:
|
@@ -84,7 +84,7 @@ jobs:
|
|
84
84
|
uses: koesterlab/setup-slurm-action@v1
|
85
85
|
- name: Install test dependencies
|
86
86
|
run: |
|
87
|
-
uv sync
|
87
|
+
uv sync
|
88
88
|
- name: Test with pytest
|
89
89
|
run: |
|
90
90
|
uv run pytest --cov=foamlib --cov-report xml
|
@@ -103,7 +103,7 @@ jobs:
|
|
103
103
|
- name: Checkout
|
104
104
|
uses: actions/checkout@v4
|
105
105
|
- name: Install uv
|
106
|
-
uses: astral-sh/setup-uv@
|
106
|
+
uses: astral-sh/setup-uv@v6
|
107
107
|
- name: Check package build
|
108
108
|
run: |
|
109
109
|
uv build
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
## Setup
|
4
|
+
|
5
|
+
1. [Fork the repository on GitHub](https://github.com/gerlero/foamlib/fork)
|
6
|
+
|
7
|
+
1. Clone your fork locally
|
8
|
+
|
9
|
+
```bash
|
10
|
+
git clone https://github.com/<your_username>/foamlib.git
|
11
|
+
```
|
12
|
+
|
13
|
+
2. Install the project in editable mode in a virtual environment
|
14
|
+
|
15
|
+
```bash
|
16
|
+
cd foamlib
|
17
|
+
python3 -m venv .venv
|
18
|
+
source .venv/bin/activate
|
19
|
+
pip install -e .[dev]
|
20
|
+
```
|
21
|
+
|
22
|
+
## Contributing changes via a pull request
|
23
|
+
|
24
|
+
1. Create a new branch for your changes
|
25
|
+
|
26
|
+
```bash
|
27
|
+
git checkout -b my-new-feature
|
28
|
+
```
|
29
|
+
|
30
|
+
2. Make your changes
|
31
|
+
|
32
|
+
3. Test your changes (see below for instructions)
|
33
|
+
|
34
|
+
4. Commit your changes
|
35
|
+
|
36
|
+
```bash
|
37
|
+
git add .
|
38
|
+
git commit -m "Add some feature"
|
39
|
+
```
|
40
|
+
|
41
|
+
5. Push your changes to your fork
|
42
|
+
|
43
|
+
```bash
|
44
|
+
git push origin my-new-feature
|
45
|
+
```
|
46
|
+
|
47
|
+
6. [Open a pull request on GitHub](https://github.com/gerlero/foamlib/compare)
|
48
|
+
|
49
|
+
|
50
|
+
## Checks
|
51
|
+
|
52
|
+
The following checks will be run by the CI pipeline, so it is recommended to run them locally before opening a pull request.
|
53
|
+
|
54
|
+
### Testing
|
55
|
+
|
56
|
+
Run the tests with:
|
57
|
+
|
58
|
+
```bash
|
59
|
+
pytest
|
60
|
+
```
|
61
|
+
|
62
|
+
### Type checking
|
63
|
+
|
64
|
+
Type check the code with:
|
65
|
+
|
66
|
+
```bash
|
67
|
+
mypy
|
68
|
+
```
|
69
|
+
|
70
|
+
### Linting
|
71
|
+
|
72
|
+
Lint the code with:
|
73
|
+
|
74
|
+
```bash
|
75
|
+
ruff check
|
76
|
+
```
|
77
|
+
|
78
|
+
### Formatting
|
79
|
+
|
80
|
+
Format the code with:
|
81
|
+
|
82
|
+
```bash
|
83
|
+
ruff format
|
84
|
+
```
|
85
|
+
|
86
|
+
### Documentation
|
87
|
+
|
88
|
+
Generate the documentation locally with:
|
89
|
+
|
90
|
+
```bash
|
91
|
+
cd docs
|
92
|
+
make html
|
93
|
+
```
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: foamlib
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.9
|
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
|
@@ -27,32 +27,38 @@ Classifier: Typing :: Typed
|
|
27
27
|
Requires-Python: >=3.7
|
28
28
|
Requires-Dist: aioshutil<2,>=1
|
29
29
|
Requires-Dist: numpy<3,>=1
|
30
|
-
Requires-Dist: numpy<3,>=1.25.0; python_version >= '3.10'
|
31
30
|
Requires-Dist: pyparsing<4,>=3.1.2
|
32
|
-
Requires-Dist: rich<
|
31
|
+
Requires-Dist: rich<15,>=13
|
33
32
|
Requires-Dist: typing-extensions<5,>=4; python_version < '3.11'
|
34
33
|
Provides-Extra: dev
|
35
34
|
Requires-Dist: mypy<2,>=1; extra == 'dev'
|
36
|
-
Requires-Dist: pytest-asyncio<0.
|
35
|
+
Requires-Dist: pytest-asyncio<0.27,>=0.21; extra == 'dev'
|
37
36
|
Requires-Dist: pytest-cov; extra == 'dev'
|
38
37
|
Requires-Dist: pytest<9,>=7; extra == 'dev'
|
39
38
|
Requires-Dist: ruff; extra == 'dev'
|
39
|
+
Requires-Dist: scipy-stubs; (python_version >= '3.10') and extra == 'dev'
|
40
|
+
Requires-Dist: scipy<2,>=1; extra == 'dev'
|
40
41
|
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
|
41
42
|
Requires-Dist: sphinx<9,>=5; extra == 'dev'
|
42
43
|
Provides-Extra: docs
|
44
|
+
Requires-Dist: ruff; extra == 'docs'
|
43
45
|
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
|
44
46
|
Requires-Dist: sphinx<9,>=5; extra == 'docs'
|
45
47
|
Provides-Extra: lint
|
46
48
|
Requires-Dist: ruff; extra == 'lint'
|
47
49
|
Provides-Extra: test
|
48
|
-
Requires-Dist:
|
50
|
+
Requires-Dist: mypy<2,>=1; extra == 'test'
|
51
|
+
Requires-Dist: pytest-asyncio<0.27,>=0.21; extra == 'test'
|
49
52
|
Requires-Dist: pytest-cov; extra == 'test'
|
50
53
|
Requires-Dist: pytest<9,>=7; extra == 'test'
|
54
|
+
Requires-Dist: scipy<2,>=1; extra == 'test'
|
51
55
|
Provides-Extra: typing
|
52
56
|
Requires-Dist: mypy<2,>=1; extra == 'typing'
|
53
|
-
Requires-Dist: pytest-asyncio<0.
|
57
|
+
Requires-Dist: pytest-asyncio<0.27,>=0.21; extra == 'typing'
|
54
58
|
Requires-Dist: pytest-cov; extra == 'typing'
|
55
59
|
Requires-Dist: pytest<9,>=7; extra == 'typing'
|
60
|
+
Requires-Dist: scipy-stubs; (python_version >= '3.10') and extra == 'typing'
|
61
|
+
Requires-Dist: scipy<2,>=1; extra == 'typing'
|
56
62
|
Description-Content-Type: text/markdown
|
57
63
|
|
58
64
|
[<img alt="foamlib" src="https://github.com/gerlero/foamlib/raw/main/logo.png" height="65">](https://github.com/gerlero/foamlib)
|
@@ -73,11 +79,18 @@ Description-Content-Type: text/markdown
|
|
73
79
|
|
74
80
|
**foamlib** provides a simple, modern, ergonomic and fast Python interface for interacting with [OpenFOAM](https://www.openfoam.com).
|
75
81
|
|
76
|
-
<
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
</
|
82
|
+
<div align="center">
|
83
|
+
<img alt="benchmark" src="https://github.com/gerlero/foamlib/raw/main/benchmark/benchmark.png" height="250">
|
84
|
+
|
85
|
+
Parsing a volVectorField with 200k cells.<sup>[1](#benchmark)</sup>
|
86
|
+
</div>
|
87
|
+
|
88
|
+
|
89
|
+
## 🚀 Introduction
|
90
|
+
|
91
|
+
**foamlib** is a Python package designed to simplify the manipulation of OpenFOAM cases and files. Its standalone parser makes it easy to work with OpenFOAM’s input/output files from Python, while its case-handling capabilities facilitate various execution workflows—reducing boilerplate code and enabling efficient Python-based pre- and post-processing, as well as simulation management.
|
92
|
+
|
93
|
+
Compared to [PyFoam](https://openfoamwiki.net/index.php/Contrib/PyFoam) and other similar tools like [fluidfoam](https://github.com/fluiddyn/fluidfoam), [fluidsimfoam](https://foss.heptapod.net/fluiddyn/fluidsimfoam), and [Ofpp](https://github.com/xu-xianghua/ofpp), **foamlib** offers advantages such as modern Python compatibility, support for binary-formatted fields, a fully type-hinted API, and asynchronous operations; making OpenFOAM workflows more accessible and streamlined.
|
81
94
|
|
82
95
|
## 👋 Basics
|
83
96
|
|
@@ -208,6 +221,159 @@ case = FoamCase(Path(__file__).parent)
|
|
208
221
|
case.run()
|
209
222
|
```
|
210
223
|
|
211
|
-
##
|
224
|
+
## ▶️ A complete example
|
225
|
+
|
226
|
+
The following is a fully self-contained example that demonstrates how to create an OpenFOAM case from scratch, run it, and analyze the results.
|
227
|
+
|
228
|
+
<details>
|
229
|
+
|
230
|
+
<summary>Example</summary>
|
231
|
+
|
232
|
+
```python
|
233
|
+
#!/usr/bin/env python3
|
234
|
+
"""Check the diffusion of a scalar field in a scalarTransportFoam case."""
|
235
|
+
|
236
|
+
import shutil
|
237
|
+
from pathlib import Path
|
238
|
+
|
239
|
+
import numpy as np
|
240
|
+
from scipy.special import erfc
|
241
|
+
from foamlib import FoamCase
|
242
|
+
|
243
|
+
path = Path(__file__).parent / "diffusionCheck"
|
244
|
+
shutil.rmtree(path, ignore_errors=True)
|
245
|
+
path.mkdir(parents=True)
|
246
|
+
(path / "system").mkdir()
|
247
|
+
(path / "constant").mkdir()
|
248
|
+
(path / "0").mkdir()
|
249
|
+
|
250
|
+
case = FoamCase(path)
|
251
|
+
|
252
|
+
with case.control_dict as f:
|
253
|
+
f["application"] = "scalarTransportFoam"
|
254
|
+
f["startFrom"] = "latestTime"
|
255
|
+
f["stopAt"] = "endTime"
|
256
|
+
f["endTime"] = 5
|
257
|
+
f["deltaT"] = 1e-3
|
258
|
+
f["writeControl"] = "adjustableRunTime"
|
259
|
+
f["writeInterval"] = 1
|
260
|
+
f["purgeWrite"] = 0
|
261
|
+
f["writeFormat"] = "ascii"
|
262
|
+
f["writePrecision"] = 6
|
263
|
+
f["writeCompression"] = False
|
264
|
+
f["timeFormat"] = "general"
|
265
|
+
f["timePrecision"] = 6
|
266
|
+
f["adjustTimeStep"] = False
|
267
|
+
f["runTimeModifiable"] = False
|
268
|
+
|
269
|
+
with case.fv_schemes as f:
|
270
|
+
f["ddtSchemes"] = {"default": "Euler"}
|
271
|
+
f["gradSchemes"] = {"default": "Gauss linear"}
|
272
|
+
f["divSchemes"] = {"default": "none", "div(phi,U)": "Gauss linear", "div(phi,T)": "Gauss linear"}
|
273
|
+
f["laplacianSchemes"] = {"default": "Gauss linear corrected"}
|
274
|
+
|
275
|
+
with case.fv_solution as f:
|
276
|
+
f["solvers"] = {"T": {"solver": "PBiCG", "preconditioner": "DILU", "tolerance": 1e-6, "relTol": 0}}
|
277
|
+
|
278
|
+
with case.block_mesh_dict as f:
|
279
|
+
f["scale"] = 1
|
280
|
+
f["vertices"] = [
|
281
|
+
[0, 0, 0],
|
282
|
+
[1, 0, 0],
|
283
|
+
[1, 0.5, 0],
|
284
|
+
[1, 1, 0],
|
285
|
+
[0, 1, 0],
|
286
|
+
[0, 0.5, 0],
|
287
|
+
[0, 0, 0.1],
|
288
|
+
[1, 0, 0.1],
|
289
|
+
[1, 0.5, 0.1],
|
290
|
+
[1, 1, 0.1],
|
291
|
+
[0, 1, 0.1],
|
292
|
+
[0, 0.5, 0.1],
|
293
|
+
]
|
294
|
+
f["blocks"] = [
|
295
|
+
"hex", [0, 1, 2, 5, 6, 7, 8, 11], [400, 20, 1], "simpleGrading", [1, 1, 1],
|
296
|
+
"hex", [5, 2, 3, 4, 11, 8, 9, 10], [400, 20, 1], "simpleGrading", [1, 1, 1],
|
297
|
+
]
|
298
|
+
f["edges"] = []
|
299
|
+
f["boundary"] = [
|
300
|
+
("inletUp", {"type": "patch", "faces": [[5, 4, 10, 11]]}),
|
301
|
+
("inletDown", {"type": "patch", "faces": [[0, 5, 11, 6]]}),
|
302
|
+
("outletUp", {"type": "patch", "faces": [[2, 3, 9, 8]]}),
|
303
|
+
("outletDown", {"type": "patch", "faces": [[1, 2, 8, 7]]}),
|
304
|
+
("walls", {"type": "wall", "faces": [[4, 3, 9, 10], [0, 1, 7, 6]]}),
|
305
|
+
("frontAndBack", {"type": "empty", "faces": [[0, 1, 2, 5], [5, 2, 3, 4], [6, 7, 8, 11], [11, 8, 9, 10]]}),
|
306
|
+
]
|
307
|
+
f["mergePatchPairs"] = []
|
308
|
+
|
309
|
+
with case.transport_properties as f:
|
310
|
+
f["DT"] = f.Dimensioned(1e-3, f.DimensionSet(length=2, time=-1), "DT")
|
311
|
+
|
312
|
+
with case[0]["U"] as f:
|
313
|
+
f.dimensions = f.DimensionSet(length=1, time=-1)
|
314
|
+
f.internal_field = [1, 0, 0]
|
315
|
+
f.boundary_field = {
|
316
|
+
"inletUp": {"type": "fixedValue", "value": [1, 0, 0]},
|
317
|
+
"inletDown": {"type": "fixedValue", "value": [1, 0, 0]},
|
318
|
+
"outletUp": {"type": "zeroGradient"},
|
319
|
+
"outletDown": {"type": "zeroGradient"},
|
320
|
+
"walls": {"type": "zeroGradient"},
|
321
|
+
"frontAndBack": {"type": "empty"},
|
322
|
+
}
|
323
|
+
|
324
|
+
with case[0]["T"] as f:
|
325
|
+
f.dimensions = f.DimensionSet(temperature=1)
|
326
|
+
f.internal_field = 0
|
327
|
+
f.boundary_field = {
|
328
|
+
"inletUp": {"type": "fixedValue", "value": 0},
|
329
|
+
"inletDown": {"type": "fixedValue", "value": 1},
|
330
|
+
"outletUp": {"type": "zeroGradient"},
|
331
|
+
"outletDown": {"type": "zeroGradient"},
|
332
|
+
"walls": {"type": "zeroGradient"},
|
333
|
+
"frontAndBack": {"type": "empty"},
|
334
|
+
}
|
335
|
+
|
336
|
+
case.run()
|
337
|
+
|
338
|
+
x, y, z = case[0].cell_centers().internal_field.T
|
339
|
+
|
340
|
+
end = x == x.max()
|
341
|
+
x = x[end]
|
342
|
+
y = y[end]
|
343
|
+
z = z[end]
|
344
|
+
|
345
|
+
DT = case.transport_properties["DT"].value
|
346
|
+
U = case[0]["U"].internal_field[0]
|
347
|
+
|
348
|
+
for time in case[1:]:
|
349
|
+
if U*time.time < 2*x.max():
|
350
|
+
continue
|
351
|
+
|
352
|
+
T = time["T"].internal_field[end]
|
353
|
+
analytical = 0.5 * erfc((y - 0.5) / np.sqrt(4 * DT * x/U))
|
354
|
+
if np.allclose(T, analytical, atol=0.1):
|
355
|
+
print(f"Time {time.time}: OK")
|
356
|
+
else:
|
357
|
+
raise RuntimeError(f"Time {time.time}: {T} != {analytical}")
|
358
|
+
```
|
359
|
+
|
360
|
+
</details>
|
361
|
+
|
362
|
+
|
363
|
+
## 📘 API documentation
|
364
|
+
|
365
|
+
For more information on how to use **foamlibs**'s classes and methods, check out the [documentation](https://foamlib.readthedocs.io/).
|
366
|
+
|
367
|
+
## 🙋 Support
|
368
|
+
|
369
|
+
If you have any questions or need help, feel free to open a [discussion](https://github.com/gerlero/foamlib/discussions).
|
370
|
+
|
371
|
+
If you believe you have found a bug in **foamlib**, please open an [issue](https://github.com/gerlero/foamlib/issues).
|
372
|
+
|
373
|
+
## 🧑💻 Contributing
|
374
|
+
|
375
|
+
You're welcome to contribute to **foamlib**! Check out the [contributing guidelines](CONTRIBUTING.md) for more information.
|
376
|
+
|
377
|
+
## Footnotes
|
212
378
|
|
213
|
-
|
379
|
+
<a id="benchmark">[1]</a> foamlib 0.8.1 vs PyFoam 2023.7 on a MacBook Air (2020, M1) with 8 GB of RAM. [Benchmark script](benchmark/benchmark.py).
|