cardiac-geometriesx 0.0.1__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.

Potentially problematic release.


This version of cardiac-geometriesx might be problematic. Click here for more details.

@@ -0,0 +1,173 @@
1
+ from pathlib import Path
2
+ import tempfile
3
+ from typing import NamedTuple, Iterable
4
+ from enum import Enum
5
+
6
+ import numpy as np
7
+ from mpi4py import MPI
8
+ from structlog import get_logger
9
+ import basix
10
+ import dolfinx
11
+ import meshio
12
+
13
+
14
+ logger = get_logger()
15
+
16
+
17
+ def element2array(el: basix.finite_element.FiniteElement) -> np.ndarray:
18
+ return np.array(
19
+ [int(el.family), int(el.cell_type), int(el.degree), int(el.discontinuous)],
20
+ dtype=np.uint8,
21
+ )
22
+
23
+
24
+ def number2Enum(num: int, enum: Iterable) -> Enum:
25
+ for e in enum:
26
+ if int(e) == num:
27
+ return e
28
+ raise ValueError(f"Invalid value {num} for enum {enum}")
29
+
30
+
31
+ def array2element(arr: np.ndarray) -> basix.finite_element.FiniteElement:
32
+ family = number2Enum(arr[0], basix.ElementFamily)
33
+ cell_type = number2Enum(arr[1], basix.CellType)
34
+ degree = int(arr[2])
35
+ discontinuous = bool(arr[3])
36
+ # TODO: Shape is hardcoded to (3,) for now, but this should also be stored
37
+ return basix.ufl.element(
38
+ family=family,
39
+ cell=cell_type,
40
+ degree=degree,
41
+ discontinuous=discontinuous,
42
+ shape=(3,),
43
+ )
44
+
45
+
46
+ def handle_mesh_name(mesh_name: str = "") -> Path:
47
+ if mesh_name == "":
48
+ fd, mesh_name = tempfile.mkstemp(suffix=".msh")
49
+ return Path(mesh_name).with_suffix(".msh")
50
+
51
+
52
+ def json_serial(obj):
53
+ if isinstance(obj, (np.ndarray)):
54
+ return obj.tolist()
55
+ else:
56
+ try:
57
+ return str(obj)
58
+ except Exception:
59
+ raise TypeError("Type %s not serializable" % type(obj))
60
+
61
+
62
+ class GMshGeometry(NamedTuple):
63
+ mesh: dolfinx.mesh.Mesh
64
+ cfun: dolfinx.mesh.MeshTags | None
65
+ ffun: dolfinx.mesh.MeshTags | None
66
+ efun: dolfinx.mesh.MeshTags | None
67
+ vfun: dolfinx.mesh.MeshTags | None
68
+ markers: dict[str, tuple[int, int]]
69
+
70
+
71
+ def create_mesh(mesh, cell_type):
72
+ # From http://jsdokken.com/converted_files/tutorial_pygmsh.html
73
+ cells = mesh.get_cells_type(cell_type)
74
+ if cells.size == 0:
75
+ return None
76
+
77
+ cells = mesh.get_cells_type(cell_type)
78
+ cell_data = mesh.get_cell_data("gmsh:physical", cell_type)
79
+ out_mesh = meshio.Mesh(
80
+ points=mesh.points,
81
+ cells={cell_type: cells},
82
+ cell_data={"name_to_read": [cell_data]},
83
+ )
84
+ return out_mesh
85
+
86
+
87
+ def read_ffun(mesh, filename: str | Path) -> dolfinx.mesh.MeshTags | None:
88
+ mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim)
89
+ with dolfinx.io.XDMFFile(mesh.comm, filename, "r") as xdmf:
90
+ ffun = xdmf.read_meshtags(mesh, name="Grid")
91
+ ffun.name = "Facet tags"
92
+ return ffun
93
+
94
+
95
+ def read_mesh(comm, filename: str | Path) -> tuple[dolfinx.mesh.Mesh, dolfinx.mesh.MeshTags | None]:
96
+ with dolfinx.io.XDMFFile(comm, filename, "r") as xdmf:
97
+ mesh = xdmf.read_mesh(name="Grid")
98
+ cfun = xdmf.read_meshtags(mesh, name="Grid")
99
+ return mesh, cfun
100
+
101
+
102
+ def gmsh2dolfin(comm: MPI.Intracomm, msh_file, unlink: bool = False) -> GMshGeometry:
103
+ logger.debug(f"Convert file {msh_file} to dolfin")
104
+ outdir = Path(msh_file).parent
105
+
106
+ vertex_mesh_name = outdir / "vertex_mesh.xdmf"
107
+ line_mesh_name = outdir / "line_mesh.xdmf"
108
+ triangle_mesh_name = outdir / "triangle_mesh.xdmf"
109
+ tetra_mesh_name = outdir / "mesh.xdmf"
110
+
111
+ if comm.rank == 0:
112
+ msh = meshio.gmsh.read(msh_file)
113
+ vertex_mesh = create_mesh(msh, "vertex")
114
+ line_mesh = create_mesh(msh, "line")
115
+ triangle_mesh = create_mesh(msh, "triangle")
116
+ tetra_mesh = create_mesh(msh, "tetra")
117
+
118
+ if vertex_mesh is not None:
119
+ meshio.write(vertex_mesh_name, vertex_mesh)
120
+
121
+ if line_mesh is not None:
122
+ meshio.write(line_mesh_name, line_mesh)
123
+
124
+ if triangle_mesh is not None:
125
+ meshio.write(triangle_mesh_name, triangle_mesh)
126
+
127
+ if tetra_mesh is not None:
128
+ meshio.write(
129
+ tetra_mesh_name,
130
+ tetra_mesh,
131
+ )
132
+ markers = msh.field_data
133
+ else:
134
+ markers = {}
135
+ # Broadcast markers
136
+ markers = comm.bcast(markers, root=0)
137
+ comm.barrier()
138
+
139
+ mesh, cfun = read_mesh(comm, tetra_mesh_name)
140
+
141
+ if triangle_mesh_name.is_file():
142
+ ffun = read_ffun(mesh, triangle_mesh_name)
143
+ else:
144
+ ffun = None
145
+
146
+ if line_mesh_name.is_file():
147
+ mesh.topology.create_connectivity(mesh.topology.dim - 2, mesh.topology.dim)
148
+ with dolfinx.io.XDMFFile(comm, line_mesh_name, "r") as xdmf:
149
+ efun = xdmf.read_meshtags(mesh, name="Grid")
150
+ else:
151
+ efun = None
152
+
153
+ if vertex_mesh_name.is_file():
154
+ mesh.topology.create_connectivity(mesh.topology.dim - 3, mesh.topology.dim)
155
+ with dolfinx.io.XDMFFile(comm, vertex_mesh_name, "r") as xdmf:
156
+ vfun = xdmf.read_meshtags(mesh, name="Grid")
157
+ else:
158
+ vfun = None
159
+
160
+ if unlink:
161
+ # Wait for all processes to finish reading
162
+ comm.barrier()
163
+ if comm.rank == 0:
164
+ vertex_mesh_name.unlink(missing_ok=True)
165
+ line_mesh_name.unlink(missing_ok=True)
166
+ triangle_mesh_name.unlink(missing_ok=True)
167
+ tetra_mesh_name.unlink(missing_ok=True)
168
+ vertex_mesh_name.with_suffix(".h5").unlink(missing_ok=True)
169
+ line_mesh_name.with_suffix(".h5").unlink(missing_ok=True)
170
+ triangle_mesh_name.with_suffix(".h5").unlink(missing_ok=True)
171
+ tetra_mesh_name.with_suffix(".h5").unlink(missing_ok=True)
172
+
173
+ return GMshGeometry(mesh, cfun, ffun, efun, vfun, markers)
@@ -0,0 +1,52 @@
1
+ Metadata-Version: 2.1
2
+ Name: cardiac-geometriesx
3
+ Version: 0.0.1
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
+ Requires-Dist: fenics-dolfinx >=0.8.0
15
+ Requires-Dist: meshio
16
+ Requires-Dist: h5py
17
+ Requires-Dist: structlog
18
+ Requires-Dist: cardiac-geometries-core
19
+ Requires-Dist: rich-click
20
+ Requires-Dist: adios4dolfinx
21
+ Provides-Extra: dev
22
+ Requires-Dist: bump-my-version ; extra == 'dev'
23
+ Requires-Dist: ipython ; extra == 'dev'
24
+ Requires-Dist: pdbpp ; extra == 'dev'
25
+ Requires-Dist: pre-commit ; extra == 'dev'
26
+ Requires-Dist: twine ; extra == 'dev'
27
+ Requires-Dist: wheel ; extra == 'dev'
28
+ Provides-Extra: docs
29
+ Provides-Extra: test
30
+ Requires-Dist: pre-commit ; extra == 'test'
31
+ Requires-Dist: pytest ; extra == 'test'
32
+ Requires-Dist: pytest-cov ; extra == 'test'
33
+
34
+ # Cardiac geometries
35
+
36
+ Cardiac geometries for `dolfinx` (targeting v0.8).
37
+
38
+ Install
39
+ ```
40
+ python3 -m pip install git+https://github.com/ComputationalPhysiology/cardiac-geometriesx
41
+ ```
42
+
43
+ Example usage
44
+ ```
45
+ geox lv-ellipsoid --create-fibers lv-mesh
46
+ ```
47
+
48
+ ## Authors
49
+ Henrik Finsberg (henriknf@simula.no)
50
+
51
+ ## License
52
+ MIT
@@ -0,0 +1,14 @@
1
+ cardiac_geometries/__init__.py,sha256=-I-0nXbVFRgfZ-mbXeC-OMg2jh7WnTch6_DkBbAGnGg,202
2
+ cardiac_geometries/cli.py,sha256=nOI56WV1fXstL3vxhux90qPnmZ69y1r-PGDYgFMgNeA,19324
3
+ cardiac_geometries/geometry.py,sha256=MYF9diZl9igayAuptSyOsHf7-3zJHFd8UgfWtXJgrHk,4849
4
+ cardiac_geometries/mesh.py,sha256=K-EEJcJNgxubnLnMkPrysnKfNe7HCfLf26lxI1lCosA,25250
5
+ cardiac_geometries/utils.py,sha256=cg42PP56UIVoDyur0lp6nJ3dAuZiHQB9kvYShKti1Bk,5452
6
+ cardiac_geometries/fibers/__init__.py,sha256=p6d-3uql8pFailBcLPPGLfRDQs38wefnarS3aSQV0FE,151
7
+ cardiac_geometries/fibers/lv_ellipsoid.py,sha256=DWDUV0sGrsZH9O-EtN3veSkE96U6XuHko3WUW9Ce_uc,3695
8
+ cardiac_geometries/fibers/slab.py,sha256=sY9VXv-J1D2wSPTcB_6opRmGMLqUXb5ix7C3gJlSJOU,3867
9
+ cardiac_geometries/fibers/utils.py,sha256=iozqorgu2KcxbzR52b2Not2IyJ-DrPyqn2Ds-QX2QLE,2584
10
+ cardiac_geometriesx-0.0.1.dist-info/METADATA,sha256=MNi78FcH9sKYLiDVgW9J_y-A45MJ-XxMxNKv1iQaHlA,1437
11
+ cardiac_geometriesx-0.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
12
+ cardiac_geometriesx-0.0.1.dist-info/entry_points.txt,sha256=xOBnlc6W-H9oCDYLNz3kpki26OmpfYSoFSrmi_4V-Ec,52
13
+ cardiac_geometriesx-0.0.1.dist-info/top_level.txt,sha256=J0gQxkWR2my5Vf7Qt8buDY8ZOjYdVfIweVunCGXWKNE,19
14
+ cardiac_geometriesx-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.43.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ geox = cardiac_geometries.cli:app
@@ -0,0 +1 @@
1
+ cardiac_geometries