cardiac-geometriesx 0.1.2__tar.gz → 0.2.0__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.
Potentially problematic release.
This version of cardiac-geometriesx might be problematic. Click here for more details.
- cardiac_geometriesx-0.2.0/LICENSE +21 -0
- cardiac_geometriesx-0.2.0/PKG-INFO +94 -0
- cardiac_geometriesx-0.2.0/README.md +48 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/pyproject.toml +19 -2
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/cli.py +15 -1
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/fibers/lv_ellipsoid.py +10 -12
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/fibers/slab.py +10 -12
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/fibers/utils.py +13 -8
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/geometry.py +82 -32
- cardiac_geometriesx-0.2.0/src/cardiac_geometries/gui.py +272 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/mesh.py +45 -22
- cardiac_geometriesx-0.2.0/src/cardiac_geometries/utils.py +440 -0
- cardiac_geometriesx-0.2.0/src/cardiac_geometriesx.egg-info/PKG-INFO +94 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometriesx.egg-info/SOURCES.txt +4 -1
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometriesx.egg-info/requires.txt +15 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/tests/test_cli.py +8 -3
- cardiac_geometriesx-0.2.0/tests/test_save_load.py +146 -0
- cardiac_geometriesx-0.1.2/PKG-INFO +0 -51
- cardiac_geometriesx-0.1.2/README.md +0 -20
- cardiac_geometriesx-0.1.2/src/cardiac_geometries/utils.py +0 -122
- cardiac_geometriesx-0.1.2/src/cardiac_geometriesx.egg-info/PKG-INFO +0 -51
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/setup.cfg +0 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/__init__.py +0 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/fibers/__init__.py +0 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometriesx.egg-info/dependency_links.txt +0 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometriesx.egg-info/entry_points.txt +0 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometriesx.egg-info/not-zip-safe +0 -0
- {cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometriesx.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Computational Physiology at Simula Research Laboratory
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: cardiac-geometriesx
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A python library for cardiac geometries
|
|
5
|
+
Author-email: Henrik Finsberg <henriknf@simula.no>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/finsberg/cardiac-geometriesx
|
|
8
|
+
Keywords: cardiac,geometry
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: fenics-dolfinx>=0.8.0
|
|
16
|
+
Requires-Dist: structlog
|
|
17
|
+
Requires-Dist: cardiac-geometries-core
|
|
18
|
+
Requires-Dist: rich-click
|
|
19
|
+
Requires-Dist: adios4dolfinx
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: bump-my-version; extra == "dev"
|
|
22
|
+
Requires-Dist: ipython; extra == "dev"
|
|
23
|
+
Requires-Dist: pdbpp; extra == "dev"
|
|
24
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
25
|
+
Requires-Dist: twine; extra == "dev"
|
|
26
|
+
Requires-Dist: wheel; extra == "dev"
|
|
27
|
+
Provides-Extra: docs
|
|
28
|
+
Requires-Dist: jupyter-book; extra == "docs"
|
|
29
|
+
Requires-Dist: jupytext; extra == "docs"
|
|
30
|
+
Requires-Dist: jupyter; extra == "docs"
|
|
31
|
+
Requires-Dist: pyvista[all]>=0.43.0; extra == "docs"
|
|
32
|
+
Requires-Dist: trame-vuetify; extra == "docs"
|
|
33
|
+
Requires-Dist: ipywidgets; extra == "docs"
|
|
34
|
+
Requires-Dist: fenicsx-ldrb; extra == "docs"
|
|
35
|
+
Provides-Extra: test
|
|
36
|
+
Requires-Dist: pre-commit; extra == "test"
|
|
37
|
+
Requires-Dist: pytest; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
39
|
+
Provides-Extra: gui
|
|
40
|
+
Requires-Dist: streamlit; extra == "gui"
|
|
41
|
+
Requires-Dist: stpyvista; extra == "gui"
|
|
42
|
+
Requires-Dist: pyvista[all]>=0.43.0; extra == "gui"
|
|
43
|
+
Requires-Dist: trame-vuetify; extra == "gui"
|
|
44
|
+
Requires-Dist: ipywidgets; extra == "gui"
|
|
45
|
+
Requires-Dist: fenicsx-ldrb; extra == "gui"
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/docker-image.yml)
|
|
50
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/test.yml)
|
|
51
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/test-mpi.yml)
|
|
52
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/pre-commit.yml)
|
|
53
|
+
[](https://badge.fury.io/py/cardiac-geometriesx)
|
|
54
|
+
|
|
55
|
+
# Cardiac geometries
|
|
56
|
+
|
|
57
|
+
Cardiac geometries is a software package built on top of [`cariac-geometries-core`](https://github.com/ComputationalPhysiology/cardiac-geometries-core) that adds support for creating idealized cardiac geometries for dolfinx.
|
|
58
|
+
|
|
59
|
+
There are two ways you can use `cardiac-geomtries`, either using the command line interface, e.g
|
|
60
|
+
```
|
|
61
|
+
geox lv-ellipsoid --create-fibers lv-mesh --fiber-space P_2
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
or using the python API e.g
|
|
65
|
+
```python
|
|
66
|
+
geo = cardiac_geometries.mesh.lv_ellipsoid(outdir="lv-mesh", create_fibers=True, fiber_space="P_2")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Install
|
|
70
|
+
|
|
71
|
+
To install the package you can use `pip`
|
|
72
|
+
```
|
|
73
|
+
python3 -m pip install cardiac-geometriesx
|
|
74
|
+
```
|
|
75
|
+
however, this assumes that you already have `dolfinx` pre-installed. You can also use the provided docker image e.g
|
|
76
|
+
```
|
|
77
|
+
docker pull ghcr.io/computationalphysiology/cardiac-geometriesx:latest
|
|
78
|
+
```
|
|
79
|
+
To start a new container interactive you can do
|
|
80
|
+
```
|
|
81
|
+
docker run --name geox -v $PWD:/home/shared -w /home/shared -it ghcr.io/computationalphysiology/cardiac-geometriesx:latest
|
|
82
|
+
```
|
|
83
|
+
or if you just want to create a mesh and exit you can run the command line interface directly e.g
|
|
84
|
+
```
|
|
85
|
+
docker run --rm -v $PWD:/home/shared -w /home/shared -it ghcr.io/computationalphysiology/cardiac-geometriesx:latest geox lv-ellipsoid --create-fibers lv-mesh --fiber-space P_2
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Authors
|
|
89
|
+
Henrik Finsberg (henriknf@simula.no)
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
MIT
|
|
93
|
+
|
|
94
|
+
## Contributing
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/docker-image.yml)
|
|
4
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/test.yml)
|
|
5
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/test-mpi.yml)
|
|
6
|
+
[](https://github.com/ComputationalPhysiology/cardiac-geometriesx/actions/workflows/pre-commit.yml)
|
|
7
|
+
[](https://badge.fury.io/py/cardiac-geometriesx)
|
|
8
|
+
|
|
9
|
+
# Cardiac geometries
|
|
10
|
+
|
|
11
|
+
Cardiac geometries is a software package built on top of [`cariac-geometries-core`](https://github.com/ComputationalPhysiology/cardiac-geometries-core) that adds support for creating idealized cardiac geometries for dolfinx.
|
|
12
|
+
|
|
13
|
+
There are two ways you can use `cardiac-geomtries`, either using the command line interface, e.g
|
|
14
|
+
```
|
|
15
|
+
geox lv-ellipsoid --create-fibers lv-mesh --fiber-space P_2
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
or using the python API e.g
|
|
19
|
+
```python
|
|
20
|
+
geo = cardiac_geometries.mesh.lv_ellipsoid(outdir="lv-mesh", create_fibers=True, fiber_space="P_2")
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
To install the package you can use `pip`
|
|
26
|
+
```
|
|
27
|
+
python3 -m pip install cardiac-geometriesx
|
|
28
|
+
```
|
|
29
|
+
however, this assumes that you already have `dolfinx` pre-installed. You can also use the provided docker image e.g
|
|
30
|
+
```
|
|
31
|
+
docker pull ghcr.io/computationalphysiology/cardiac-geometriesx:latest
|
|
32
|
+
```
|
|
33
|
+
To start a new container interactive you can do
|
|
34
|
+
```
|
|
35
|
+
docker run --name geox -v $PWD:/home/shared -w /home/shared -it ghcr.io/computationalphysiology/cardiac-geometriesx:latest
|
|
36
|
+
```
|
|
37
|
+
or if you just want to create a mesh and exit you can run the command line interface directly e.g
|
|
38
|
+
```
|
|
39
|
+
docker run --rm -v $PWD:/home/shared -w /home/shared -it ghcr.io/computationalphysiology/cardiac-geometriesx:latest geox lv-ellipsoid --create-fibers lv-mesh --fiber-space P_2
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Authors
|
|
43
|
+
Henrik Finsberg (henriknf@simula.no)
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
MIT
|
|
47
|
+
|
|
48
|
+
## Contributing
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cardiac-geometriesx"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "A python library for cardiac geometries"
|
|
9
9
|
authors = [{name = "Henrik Finsberg", email = "henriknf@simula.no"}]
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -38,12 +38,28 @@ dev = [
|
|
|
38
38
|
"wheel",
|
|
39
39
|
]
|
|
40
40
|
docs = [
|
|
41
|
+
"jupyter-book",
|
|
42
|
+
"jupytext",
|
|
43
|
+
"jupyter",
|
|
44
|
+
"pyvista[all]>=0.43.0",
|
|
45
|
+
"trame-vuetify",
|
|
46
|
+
"ipywidgets",
|
|
47
|
+
"fenicsx-ldrb",
|
|
41
48
|
]
|
|
42
49
|
test = [
|
|
43
50
|
"pre-commit",
|
|
44
51
|
"pytest",
|
|
45
52
|
"pytest-cov",
|
|
46
53
|
]
|
|
54
|
+
gui = [
|
|
55
|
+
"streamlit",
|
|
56
|
+
"stpyvista",
|
|
57
|
+
"pyvista[all]>=0.43.0",
|
|
58
|
+
"trame-vuetify",
|
|
59
|
+
"ipywidgets",
|
|
60
|
+
"fenicsx-ldrb",
|
|
61
|
+
|
|
62
|
+
]
|
|
47
63
|
|
|
48
64
|
[project.scripts]
|
|
49
65
|
geox = "cardiac_geometries.cli:app"
|
|
@@ -80,6 +96,7 @@ exclude = [
|
|
|
80
96
|
|
|
81
97
|
# Exclude a variety of commonly ignored directories.
|
|
82
98
|
exclude = [
|
|
99
|
+
"demos/*.py",
|
|
83
100
|
".bzr",
|
|
84
101
|
".direnv",
|
|
85
102
|
".eggs",
|
|
@@ -156,7 +173,7 @@ tag = true
|
|
|
156
173
|
sign_tags = false
|
|
157
174
|
tag_name = "v{new_version}"
|
|
158
175
|
tag_message = "Bump version: {current_version} → {new_version}"
|
|
159
|
-
current_version = "0.
|
|
176
|
+
current_version = "0.2.0"
|
|
160
177
|
|
|
161
178
|
|
|
162
179
|
[[tool.bumpversion.files]]
|
|
@@ -8,8 +8,10 @@ from . import mesh
|
|
|
8
8
|
|
|
9
9
|
meta = metadata("cardiac-geometriesx")
|
|
10
10
|
__version__ = meta["Version"]
|
|
11
|
-
__author__ = meta["Author"]
|
|
11
|
+
__author__ = meta["Author-email"]
|
|
12
12
|
__license__ = meta["License"]
|
|
13
|
+
__email__ = meta["Author-email"]
|
|
14
|
+
__program_name__ = meta["Name"]
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
@click.group()
|
|
@@ -867,8 +869,20 @@ def slab_in_bath(
|
|
|
867
869
|
geo.save(outdir / "slab_in_bath.bp")
|
|
868
870
|
|
|
869
871
|
|
|
872
|
+
@click.command("gui")
|
|
873
|
+
def gui():
|
|
874
|
+
# Make sure we can import the required packages
|
|
875
|
+
from . import gui # noqa: F401
|
|
876
|
+
|
|
877
|
+
gui_path = Path(__file__).parent.joinpath("gui.py")
|
|
878
|
+
import subprocess as sp
|
|
879
|
+
|
|
880
|
+
sp.run(["streamlit", "run", gui_path.as_posix()])
|
|
881
|
+
|
|
882
|
+
|
|
870
883
|
app.add_command(lv_ellipsoid)
|
|
871
884
|
app.add_command(biv_ellipsoid)
|
|
872
885
|
app.add_command(biv_ellipsoid_torso)
|
|
873
886
|
app.add_command(slab)
|
|
874
887
|
app.add_command(slab_in_bath)
|
|
888
|
+
app.add_command(gui)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
import basix
|
|
4
3
|
import dolfinx
|
|
5
4
|
import numpy as np
|
|
6
5
|
|
|
6
|
+
from ..utils import space_from_string
|
|
7
7
|
from . import utils
|
|
8
8
|
|
|
9
9
|
|
|
@@ -82,14 +82,9 @@ def compute_system(
|
|
|
82
82
|
s0 = np.cross(f0, n0, axis=0)
|
|
83
83
|
s0 = utils.normalize(s0)
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
element.family_name,
|
|
87
|
-
mesh.ufl_cell().cellname(),
|
|
88
|
-
degree=element.degree,
|
|
89
|
-
discontinuous=element.discontinuous,
|
|
90
|
-
shape=(mesh.geometry.dim,),
|
|
85
|
+
Vv = space_from_string(
|
|
86
|
+
space_string=f"{element.family_name}_{element.degree}", mesh=mesh, dim=mesh.geometry.dim
|
|
91
87
|
)
|
|
92
|
-
Vv = dolfinx.fem.functionspace(mesh, el)
|
|
93
88
|
|
|
94
89
|
fiber = dolfinx.fem.Function(Vv)
|
|
95
90
|
norm_f = np.linalg.norm(f0, axis=0)
|
|
@@ -131,10 +126,13 @@ def create_microstructure(
|
|
|
131
126
|
)
|
|
132
127
|
|
|
133
128
|
if outdir is not None:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
file
|
|
129
|
+
try:
|
|
130
|
+
with dolfinx.io.VTXWriter(
|
|
131
|
+
mesh.comm, Path(outdir) / "laplace.bp", [t], engine="BP4"
|
|
132
|
+
) as file:
|
|
133
|
+
file.write(0.0)
|
|
134
|
+
except RuntimeError:
|
|
135
|
+
pass
|
|
138
136
|
|
|
139
137
|
system = compute_system(
|
|
140
138
|
t,
|
{cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/fibers/slab.py
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
import basix
|
|
4
3
|
import dolfinx
|
|
5
4
|
import numpy as np
|
|
6
5
|
|
|
6
|
+
from ..utils import space_from_string
|
|
7
7
|
from . import utils
|
|
8
8
|
|
|
9
9
|
|
|
@@ -59,14 +59,9 @@ def compute_system(
|
|
|
59
59
|
n0 = np.cross(f0, s0, axis=0)
|
|
60
60
|
n0 = utils.normalize(n0)
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
element.family_name,
|
|
64
|
-
mesh.ufl_cell().cellname(),
|
|
65
|
-
degree=element.degree,
|
|
66
|
-
discontinuous=element.discontinuous,
|
|
67
|
-
shape=(mesh.geometry.dim,),
|
|
62
|
+
Vv = space_from_string(
|
|
63
|
+
space_string=f"{element.family_name}_{element.degree}", mesh=mesh, dim=mesh.geometry.dim
|
|
68
64
|
)
|
|
69
|
-
Vv = dolfinx.fem.functionspace(mesh, el)
|
|
70
65
|
|
|
71
66
|
fiber = dolfinx.fem.Function(Vv)
|
|
72
67
|
norm_f = np.linalg.norm(f0, axis=0)
|
|
@@ -134,10 +129,13 @@ def create_microstructure(
|
|
|
134
129
|
function_space=function_space,
|
|
135
130
|
)
|
|
136
131
|
if outdir is not None:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
file
|
|
132
|
+
try:
|
|
133
|
+
with dolfinx.io.VTXWriter(
|
|
134
|
+
mesh.comm, Path(outdir) / "laplace.bp", [t], engine="BP4"
|
|
135
|
+
) as file:
|
|
136
|
+
file.write(0.0)
|
|
137
|
+
except RuntimeError:
|
|
138
|
+
pass
|
|
141
139
|
|
|
142
140
|
system = compute_system(
|
|
143
141
|
t,
|
{cardiac_geometriesx-0.1.2 → cardiac_geometriesx-0.2.0}/src/cardiac_geometries/fibers/utils.py
RENAMED
|
@@ -7,6 +7,8 @@ import numpy as np
|
|
|
7
7
|
import ufl
|
|
8
8
|
from dolfinx.fem.petsc import LinearProblem
|
|
9
9
|
|
|
10
|
+
from ..utils import space_from_string
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
class Microstructure(NamedTuple):
|
|
12
14
|
f0: dolfinx.fem.Function
|
|
@@ -20,17 +22,20 @@ def save_microstructure(
|
|
|
20
22
|
from ..utils import element2array
|
|
21
23
|
|
|
22
24
|
# Save for paraview visualization
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
file
|
|
25
|
+
try:
|
|
26
|
+
with dolfinx.io.VTXWriter(
|
|
27
|
+
mesh.comm, Path(outdir) / "microstructure-viz.bp", functions, engine="BP4"
|
|
28
|
+
) as file:
|
|
29
|
+
file.write(0.0)
|
|
30
|
+
except RuntimeError:
|
|
31
|
+
pass
|
|
27
32
|
|
|
28
33
|
# Save with proper function space
|
|
29
34
|
filename = Path(outdir) / "microstructure.bp"
|
|
30
35
|
for function in functions:
|
|
31
36
|
adios4dolfinx.write_function(u=function, filename=filename)
|
|
32
37
|
|
|
33
|
-
attributes = {f.name: element2array(f.ufl_element()
|
|
38
|
+
attributes = {f.name: element2array(f.ufl_element()) for f in functions}
|
|
34
39
|
adios4dolfinx.write_attributes(
|
|
35
40
|
comm=mesh.comm,
|
|
36
41
|
filename=filename,
|
|
@@ -73,10 +78,10 @@ def laplace(
|
|
|
73
78
|
uh = problem.solve()
|
|
74
79
|
|
|
75
80
|
if function_space != "P_1":
|
|
76
|
-
|
|
77
|
-
W = dolfinx.fem.functionspace(mesh, (family, int(degree)))
|
|
81
|
+
W = space_from_string(function_space, mesh, dim=1)
|
|
78
82
|
t = dolfinx.fem.Function(W)
|
|
79
|
-
|
|
83
|
+
expr = dolfinx.fem.Expression(uh, W.element.interpolation_points())
|
|
84
|
+
t.interpolate(expr)
|
|
80
85
|
else:
|
|
81
86
|
t = uh
|
|
82
87
|
|
|
@@ -15,9 +15,11 @@ from . import utils
|
|
|
15
15
|
@dataclass # (frozen=True, slots=True)
|
|
16
16
|
class Geometry:
|
|
17
17
|
mesh: dolfinx.mesh.Mesh
|
|
18
|
-
markers: dict[str, tuple[
|
|
19
|
-
ffun: dolfinx.mesh.MeshTags | None = None
|
|
18
|
+
markers: dict[str, tuple[int, int]] = field(default_factory=dict)
|
|
20
19
|
cfun: dolfinx.mesh.MeshTags | None = None
|
|
20
|
+
ffun: dolfinx.mesh.MeshTags | None = None
|
|
21
|
+
efun: dolfinx.mesh.MeshTags | None = None
|
|
22
|
+
vfun: dolfinx.mesh.MeshTags | None = None
|
|
21
23
|
f0: dolfinx.fem.Function | None = None
|
|
22
24
|
s0: dolfinx.fem.Function | None = None
|
|
23
25
|
n0: dolfinx.fem.Function | None = None
|
|
@@ -25,8 +27,7 @@ class Geometry:
|
|
|
25
27
|
def save(self, path: str | Path) -> None:
|
|
26
28
|
path = Path(path)
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
shutil.rmtree(path)
|
|
30
|
+
shutil.rmtree(path, ignore_errors=True)
|
|
30
31
|
self.mesh.comm.barrier()
|
|
31
32
|
adios4dolfinx.write_mesh(mesh=self.mesh, filename=path)
|
|
32
33
|
|
|
@@ -37,15 +38,37 @@ class Geometry:
|
|
|
37
38
|
attributes={k: np.array(v, dtype=np.uint8) for k, v in self.markers.items()},
|
|
38
39
|
)
|
|
39
40
|
|
|
41
|
+
if self.cfun is not None:
|
|
42
|
+
adios4dolfinx.write_meshtags(
|
|
43
|
+
meshtags=self.cfun,
|
|
44
|
+
mesh=self.mesh,
|
|
45
|
+
filename=path,
|
|
46
|
+
meshtag_name="Cell tags",
|
|
47
|
+
)
|
|
40
48
|
if self.ffun is not None:
|
|
41
49
|
adios4dolfinx.write_meshtags(
|
|
42
50
|
meshtags=self.ffun,
|
|
43
51
|
mesh=self.mesh,
|
|
44
52
|
filename=path,
|
|
53
|
+
meshtag_name="Facet tags",
|
|
54
|
+
)
|
|
55
|
+
if self.efun is not None:
|
|
56
|
+
adios4dolfinx.write_meshtags(
|
|
57
|
+
meshtags=self.efun,
|
|
58
|
+
mesh=self.mesh,
|
|
59
|
+
filename=path,
|
|
60
|
+
meshtag_name="Edge tags",
|
|
61
|
+
)
|
|
62
|
+
if self.vfun is not None:
|
|
63
|
+
adios4dolfinx.write_meshtags(
|
|
64
|
+
meshtags=self.vfun,
|
|
65
|
+
mesh=self.mesh,
|
|
66
|
+
filename=path,
|
|
67
|
+
meshtag_name="Vertex tags",
|
|
45
68
|
)
|
|
46
69
|
|
|
47
70
|
if self.f0 is not None:
|
|
48
|
-
el = self.f0.ufl_element()
|
|
71
|
+
el = self.f0.ufl_element()
|
|
49
72
|
arr = utils.element2array(el)
|
|
50
73
|
|
|
51
74
|
adios4dolfinx.write_attributes(
|
|
@@ -60,26 +83,49 @@ class Geometry:
|
|
|
60
83
|
if self.n0 is not None:
|
|
61
84
|
adios4dolfinx.write_function(u=self.n0, filename=path, name="n0")
|
|
62
85
|
|
|
86
|
+
self.mesh.comm.barrier()
|
|
87
|
+
|
|
63
88
|
@classmethod
|
|
64
89
|
def from_file(cls, comm: MPI.Intracomm, path: str | Path) -> "Geometry":
|
|
65
90
|
path = Path(path)
|
|
91
|
+
|
|
66
92
|
mesh = adios4dolfinx.read_mesh(comm=comm, filename=path)
|
|
67
93
|
markers = adios4dolfinx.read_attributes(comm=comm, filename=path, name="markers")
|
|
68
|
-
|
|
94
|
+
tags = {}
|
|
95
|
+
for name, meshtag_name in (
|
|
96
|
+
("cfun", "Cell tags"),
|
|
97
|
+
("ffun", "Facet tags"),
|
|
98
|
+
("efun", "Edge tags"),
|
|
99
|
+
("vfun", "Vertex tags"),
|
|
100
|
+
):
|
|
101
|
+
try:
|
|
102
|
+
tags[name] = adios4dolfinx.read_meshtags(
|
|
103
|
+
mesh=mesh, meshtag_name=meshtag_name, filename=path
|
|
104
|
+
)
|
|
105
|
+
except KeyError:
|
|
106
|
+
tags[name] = None
|
|
107
|
+
|
|
108
|
+
functions = {}
|
|
69
109
|
function_space = adios4dolfinx.read_attributes(
|
|
70
110
|
comm=comm, filename=path, name="function_space"
|
|
71
111
|
)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
112
|
+
for name, el in function_space.items():
|
|
113
|
+
element = utils.array2element(el)
|
|
114
|
+
V = dolfinx.fem.functionspace(mesh, element)
|
|
115
|
+
f = dolfinx.fem.Function(V, name=name)
|
|
116
|
+
try:
|
|
117
|
+
adios4dolfinx.read_function(u=f, filename=path, name=name)
|
|
118
|
+
except KeyError:
|
|
119
|
+
continue
|
|
120
|
+
else:
|
|
121
|
+
functions[name] = f
|
|
122
|
+
|
|
123
|
+
return cls(
|
|
124
|
+
mesh=mesh,
|
|
125
|
+
markers=markers,
|
|
126
|
+
**functions,
|
|
127
|
+
**tags,
|
|
128
|
+
)
|
|
83
129
|
|
|
84
130
|
@classmethod
|
|
85
131
|
def from_folder(cls, comm: MPI.Intracomm, folder: str | Path) -> "Geometry":
|
|
@@ -87,7 +133,7 @@ class Geometry:
|
|
|
87
133
|
|
|
88
134
|
# Read mesh
|
|
89
135
|
if (folder / "mesh.xdmf").exists():
|
|
90
|
-
mesh,
|
|
136
|
+
mesh, tags = utils.read_mesh(comm=comm, filename=folder / "mesh.xdmf")
|
|
91
137
|
else:
|
|
92
138
|
raise ValueError("No mesh file found")
|
|
93
139
|
|
|
@@ -101,22 +147,26 @@ class Geometry:
|
|
|
101
147
|
else:
|
|
102
148
|
markers = {}
|
|
103
149
|
|
|
150
|
+
functions = {}
|
|
104
151
|
microstructure_path = folder / "microstructure.bp"
|
|
105
152
|
if microstructure_path.exists():
|
|
106
153
|
function_space = adios4dolfinx.read_attributes(
|
|
107
154
|
comm=MPI.COMM_WORLD, filename=microstructure_path, name="function_space"
|
|
108
155
|
)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
156
|
+
for name, el in function_space.items():
|
|
157
|
+
element = utils.array2element(el)
|
|
158
|
+
V = dolfinx.fem.functionspace(mesh, element)
|
|
159
|
+
f = dolfinx.fem.Function(V, name=name)
|
|
160
|
+
try:
|
|
161
|
+
adios4dolfinx.read_function(u=f, filename=microstructure_path, name=name)
|
|
162
|
+
except KeyError:
|
|
163
|
+
continue
|
|
164
|
+
else:
|
|
165
|
+
functions[name] = f
|
|
166
|
+
|
|
167
|
+
return cls(
|
|
168
|
+
mesh=mesh,
|
|
169
|
+
markers=markers,
|
|
170
|
+
**functions,
|
|
171
|
+
**tags,
|
|
172
|
+
)
|