cardiac-geometriesx 0.0.1__py3-none-any.whl → 0.0.4__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.

@@ -1,8 +1,4 @@
1
- from . import fibers
2
- from . import geometry
1
+ from . import cli, fibers, geometry, mesh, utils
3
2
  from .geometry import Geometry
4
- from . import mesh
5
- from . import utils
6
- from . import cli
7
3
 
8
4
  __all__ = ["mesh", "fibers", "geometry", "Geometry", "utils", "cli"]
cardiac_geometries/cli.py CHANGED
@@ -6,7 +6,6 @@ import rich_click as click
6
6
 
7
7
  from . import mesh
8
8
 
9
-
10
9
  meta = metadata("cardiac-geometriesx")
11
10
  __version__ = meta["Version"]
12
11
  __author__ = meta["Author"]
@@ -1,6 +1,4 @@
1
- from . import lv_ellipsoid, slab
2
- from . import utils
3
-
1
+ from . import lv_ellipsoid, slab, utils
4
2
  from .utils import Microstructure
5
3
 
6
4
  __all__ = ["lv_ellipsoid", "slab", "utils", "Microstructure"]
@@ -1,8 +1,8 @@
1
1
  from pathlib import Path
2
+
3
+ import basix
2
4
  import dolfinx
3
5
  import numpy as np
4
- import basix
5
-
6
6
 
7
7
  from . import utils
8
8
 
@@ -1,8 +1,8 @@
1
1
  from pathlib import Path
2
2
 
3
+ import basix
3
4
  import dolfinx
4
5
  import numpy as np
5
- import basix
6
6
 
7
7
  from . import utils
8
8
 
@@ -1,11 +1,11 @@
1
- from typing import NamedTuple
2
1
  from pathlib import Path
2
+ from typing import NamedTuple
3
3
 
4
+ import adios4dolfinx
4
5
  import dolfinx
5
- from dolfinx.fem.petsc import LinearProblem
6
- import ufl
7
6
  import numpy as np
8
- import adios4dolfinx
7
+ import ufl
8
+ from dolfinx.fem.petsc import LinearProblem
9
9
 
10
10
 
11
11
  class Microstructure(NamedTuple):
@@ -1,10 +1,12 @@
1
- from dataclasses import dataclass, field
2
1
  import json
2
+ import shutil
3
+ from dataclasses import dataclass, field
3
4
  from pathlib import Path
4
- import dolfinx
5
+
5
6
  from mpi4py import MPI
6
- import shutil
7
+
7
8
  import adios4dolfinx
9
+ import dolfinx
8
10
  import numpy as np
9
11
 
10
12
  from . import utils
@@ -85,16 +87,10 @@ class Geometry:
85
87
 
86
88
  # Read mesh
87
89
  if (folder / "mesh.xdmf").exists():
88
- mesh, cfun = utils.read_mesh(comm=comm, filename=folder / "mesh.xdmf")
90
+ mesh, cfun, ffun = utils.read_mesh(comm=comm, filename=folder / "mesh.xdmf")
89
91
  else:
90
92
  raise ValueError("No mesh file found")
91
93
 
92
- # Read meshtags
93
- if (folder / "triangle_mesh.xdmf").exists():
94
- ffun = utils.read_ffun(mesh=mesh, filename=folder / "triangle_mesh.xdmf")
95
- else:
96
- ffun = None
97
-
98
94
  # Read markers
99
95
  if (folder / "markers.json").exists():
100
96
  if comm.rank == 0:
@@ -1,12 +1,13 @@
1
- from pathlib import Path
2
- import math
3
- import json
4
1
  import datetime
2
+ import json
3
+ import math
5
4
  from importlib.metadata import metadata
6
- from structlog import get_logger
5
+ from pathlib import Path
7
6
 
8
7
  from mpi4py import MPI
8
+
9
9
  import cardiac_geometries_core as cgc
10
+ from structlog import get_logger
10
11
 
11
12
  from . import utils
12
13
  from .geometry import Geometry
@@ -42,6 +43,7 @@ def biv_ellipsoid(
42
43
  fiber_angle_endo: float = -60,
43
44
  fiber_angle_epi: float = +60,
44
45
  fiber_space: str = "P_1",
46
+ verbose: bool = False,
45
47
  ) -> Geometry:
46
48
  """Create BiV ellipsoidal geometry
47
49
 
@@ -95,6 +97,8 @@ def biv_ellipsoid(
95
97
  Angle for the epicardium, by default +60
96
98
  fiber_space : str, optional
97
99
  Function space for fibers of the form family_degree, by default "P_1"
100
+ verbose : bool, optional
101
+ If True print information from gmsh, by default False
98
102
 
99
103
  Returns
100
104
  -------
@@ -164,9 +168,10 @@ def biv_ellipsoid(
164
168
  a_epi_rv=a_epi_rv,
165
169
  b_epi_rv=b_epi_rv,
166
170
  c_epi_rv=c_epi_rv,
171
+ verbose=verbose,
167
172
  )
168
173
  comm.barrier()
169
- geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name, unlink=False)
174
+ geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name)
170
175
 
171
176
  if comm.rank == 0:
172
177
  with open(outdir / "markers.json", "w") as f:
@@ -220,6 +225,7 @@ def biv_ellipsoid_torso(
220
225
  fiber_angle_endo: float = -60,
221
226
  fiber_angle_epi: float = +60,
222
227
  fiber_space: str = "P_1",
228
+ verbose: bool = False,
223
229
  ) -> Geometry:
224
230
  """Create BiV ellipsoidal geometry
225
231
 
@@ -285,6 +291,8 @@ def biv_ellipsoid_torso(
285
291
  Angle for the epicardium, by default +60
286
292
  fiber_space : str, optional
287
293
  Function space for fibers of the form family_degree, by default "P_1"
294
+ verbose : bool, optional
295
+ If True print information from gmsh, by default False
288
296
 
289
297
  Returns
290
298
  -------
@@ -364,10 +372,11 @@ def biv_ellipsoid_torso(
364
372
  a_epi_rv=a_epi_rv,
365
373
  b_epi_rv=b_epi_rv,
366
374
  c_epi_rv=c_epi_rv,
375
+ verbose=verbose,
367
376
  )
368
377
  comm.barrier()
369
378
 
370
- geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name, unlink=False)
379
+ geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name)
371
380
 
372
381
  if comm.rank == 0:
373
382
  with open(outdir / "markers.json", "w") as f:
@@ -412,6 +421,7 @@ def lv_ellipsoid(
412
421
  fiber_angle_epi: float = +60,
413
422
  fiber_space: str = "P_1",
414
423
  aha: bool = True,
424
+ verbose: bool = False,
415
425
  ) -> Geometry:
416
426
  """Create an LV ellipsoidal geometry
417
427
 
@@ -447,6 +457,8 @@ def lv_ellipsoid(
447
457
  Function space for fibers of the form family_degree, by default "P_1"
448
458
  aha : bool, optional
449
459
  If True create 17-segment AHA regions
460
+ verbose : bool, optional
461
+ If True print information from gmsh, by default False
450
462
 
451
463
  Returns
452
464
  -------
@@ -497,10 +509,11 @@ def lv_ellipsoid(
497
509
  mu_apex_endo=mu_apex_endo,
498
510
  mu_apex_epi=mu_apex_epi,
499
511
  psize_ref=psize_ref,
512
+ verbose=verbose,
500
513
  )
501
514
  comm.barrier()
502
515
 
503
- geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name, unlink=False)
516
+ geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name)
504
517
 
505
518
  # if aha:
506
519
  # from .aha import lv_aha
@@ -559,6 +572,7 @@ def slab(
559
572
  fiber_angle_endo: float = -60,
560
573
  fiber_angle_epi: float = +60,
561
574
  fiber_space: str = "P_1",
575
+ verbose: bool = False,
562
576
  ) -> Geometry:
563
577
  """Create slab geometry
564
578
 
@@ -582,6 +596,8 @@ def slab(
582
596
  Angle for the epicardium, by default +60
583
597
  fiber_space : str, optional
584
598
  Function space for fibers of the form family_degree, by default "P_1"
599
+ verbose : bool, optional
600
+ If True print information from gmsh, by default False
585
601
 
586
602
  Returns
587
603
  -------
@@ -615,10 +631,17 @@ def slab(
615
631
  default=utils.json_serial,
616
632
  )
617
633
 
618
- cgc.slab(mesh_name=mesh_name.as_posix(), lx=lx, ly=ly, lz=lz, dx=dx)
634
+ cgc.slab(
635
+ mesh_name=mesh_name.as_posix(),
636
+ lx=lx,
637
+ ly=ly,
638
+ lz=lz,
639
+ dx=dx,
640
+ verbose=verbose,
641
+ )
619
642
  comm.barrier()
620
643
 
621
- geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name, unlink=False)
644
+ geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name)
622
645
 
623
646
  if comm.rank == 0:
624
647
  with open(outdir / "markers.json", "w") as f:
@@ -651,6 +674,7 @@ def slab_in_bath(
651
674
  by: float = 0.0,
652
675
  bz: float = 0.1,
653
676
  dx: float = 0.001,
677
+ verbose: bool = False,
654
678
  ) -> Geometry:
655
679
  """Create slab geometry
656
680
 
@@ -672,6 +696,8 @@ def slab_in_bath(
672
696
  Thickness of bath the z-direction, by default 0.1
673
697
  dx : float, optional
674
698
  Element size, by default 0.001
699
+ verbose : bool, optional
700
+ If True print information from gmsh, by default False
675
701
 
676
702
  Returns
677
703
  -------
@@ -714,9 +740,10 @@ def slab_in_bath(
714
740
  by=by,
715
741
  bz=bz,
716
742
  dx=dx,
743
+ verbose=verbose,
717
744
  )
718
745
 
719
- geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name, unlink=False)
746
+ geometry = utils.gmsh2dolfin(comm=comm, msh_file=mesh_name)
720
747
 
721
748
  if comm.rank == 0:
722
749
  with open(outdir / "markers.json", "w") as f:
@@ -1,15 +1,14 @@
1
- from pathlib import Path
2
1
  import tempfile
3
- from typing import NamedTuple, Iterable
4
2
  from enum import Enum
3
+ from pathlib import Path
4
+ from typing import Iterable, NamedTuple
5
5
 
6
- import numpy as np
7
6
  from mpi4py import MPI
8
- from structlog import get_logger
7
+
9
8
  import basix
10
9
  import dolfinx
11
- import meshio
12
-
10
+ import numpy as np
11
+ from structlog import get_logger
13
12
 
14
13
  logger = get_logger()
15
14
 
@@ -68,106 +67,56 @@ class GMshGeometry(NamedTuple):
68
67
  markers: dict[str, tuple[int, int]]
69
68
 
70
69
 
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]:
70
+ def read_mesh(
71
+ comm, filename: str | Path
72
+ ) -> tuple[dolfinx.mesh.Mesh, dolfinx.mesh.MeshTags | None, dolfinx.mesh.MeshTags | None]:
96
73
  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
74
+ mesh = xdmf.read_mesh(name="Mesh")
75
+ cfun = xdmf.read_meshtags(mesh, name="Cell tags")
76
+ mesh.topology.create_connectivity(2, 3)
77
+ ffun = xdmf.read_meshtags(mesh, name="Facet tags")
78
+ return mesh, cfun, ffun
100
79
 
101
80
 
102
- def gmsh2dolfin(comm: MPI.Intracomm, msh_file, unlink: bool = False) -> GMshGeometry:
81
+ def gmsh2dolfin(comm: MPI.Intracomm, msh_file, rank: int = 0) -> GMshGeometry:
103
82
  logger.debug(f"Convert file {msh_file} to dolfin")
104
83
  outdir = Path(msh_file).parent
105
84
 
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)
85
+ import gmsh
140
86
 
141
- if triangle_mesh_name.is_file():
142
- ffun = read_ffun(mesh, triangle_mesh_name)
143
- else:
144
- ffun = None
87
+ # We could make this work in parallel in the future
145
88
 
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")
89
+ if comm.rank == rank:
90
+ gmsh.initialize()
91
+ gmsh.model.add("Mesh from file")
92
+ gmsh.merge(str(msh_file))
93
+ mesh, ct, ft = dolfinx.io.gmshio.model_to_mesh(gmsh.model, comm, 0)
94
+ markers = {
95
+ gmsh.model.getPhysicalName(*v): tuple(reversed(v))
96
+ for v in gmsh.model.getPhysicalGroups()
97
+ }
98
+ gmsh.finalize()
150
99
  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)
100
+ mesh, ct, ft = dolfinx.io.gmshio.model_to_mesh(gmsh.model, comm, 0)
101
+ markers = {}
102
+ mesh.name = "Mesh"
103
+ ct.name = "Cell tags"
104
+ ft.name = "Facet tags"
105
+
106
+ markers = comm.bcast(markers, root=rank)
107
+
108
+ # Save tags to xdmf
109
+ with dolfinx.io.XDMFFile(comm, outdir / "mesh.xdmf", "w") as xdmf:
110
+ xdmf.write_mesh(mesh)
111
+ mesh.topology.create_connectivity(2, 3)
112
+ xdmf.write_meshtags(
113
+ ct, mesh.geometry, geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{mesh.name}']/Geometry"
114
+ )
115
+ xdmf.write_meshtags(
116
+ ft, mesh.geometry, geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{mesh.name}']/Geometry"
117
+ )
118
+
119
+ vfun = None
120
+ efun = None
121
+
122
+ return GMshGeometry(mesh, ct, ft, efun, vfun, markers)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cardiac-geometriesx
3
- Version: 0.0.1
3
+ Version: 0.0.4
4
4
  Summary: A python library for cardiac geometries
5
5
  Author-email: Henrik Finsberg <henriknf@simula.no>
6
6
  License: MIT
@@ -12,8 +12,6 @@ Classifier: Programming Language :: Python :: 3 :: Only
12
12
  Requires-Python: >=3.8
13
13
  Description-Content-Type: text/markdown
14
14
  Requires-Dist: fenics-dolfinx >=0.8.0
15
- Requires-Dist: meshio
16
- Requires-Dist: h5py
17
15
  Requires-Dist: structlog
18
16
  Requires-Dist: cardiac-geometries-core
19
17
  Requires-Dist: rich-click
@@ -0,0 +1,14 @@
1
+ cardiac_geometries/__init__.py,sha256=2W_ywAeLjyRk5MqSPAodHa4UN2lOnW1h8tmGLQ3gaJ0,150
2
+ cardiac_geometries/cli.py,sha256=2-99xmcBltdotzxp4aDZLrh46gyA5U_PZc6lHen7LIM,19323
3
+ cardiac_geometries/geometry.py,sha256=XRacH519WbrLK0V_Ec6rbxAZFK-n39fUsEzdK3ulbJg,4655
4
+ cardiac_geometries/mesh.py,sha256=cJAcwdDaYmO8MlfocaxvV6pkBcfEWybMSBAaycr6q3s,25987
5
+ cardiac_geometries/utils.py,sha256=-fH13vimCYrirDZubQdxRpX-7I9iCFsOJ8Xo1NL5Nvc,3596
6
+ cardiac_geometries/fibers/__init__.py,sha256=WpRrn9Iakl-3m8IGtFkqP0LXGjw5EZHZ8Eg9JCnCdrg,137
7
+ cardiac_geometries/fibers/lv_ellipsoid.py,sha256=zcCTcst08-xcG5c2j8rPLFp0cgNjXt1Q0mVGhs5r5Ps,3695
8
+ cardiac_geometries/fibers/slab.py,sha256=-EWG4cHjtFYo4VyoFfVnsbHhfdf8qKWphYimJ1jB56o,3867
9
+ cardiac_geometries/fibers/utils.py,sha256=hra9OKKNJhhTkgx4Xs4Oc2FoX8kzY-Eyu6KjQ74FNh4,2584
10
+ cardiac_geometriesx-0.0.4.dist-info/METADATA,sha256=nSeHEbLKF9sIbjc18m0hYcMSAfy7db05NZaFyFioIRA,1395
11
+ cardiac_geometriesx-0.0.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
12
+ cardiac_geometriesx-0.0.4.dist-info/entry_points.txt,sha256=xOBnlc6W-H9oCDYLNz3kpki26OmpfYSoFSrmi_4V-Ec,52
13
+ cardiac_geometriesx-0.0.4.dist-info/top_level.txt,sha256=J0gQxkWR2my5Vf7Qt8buDY8ZOjYdVfIweVunCGXWKNE,19
14
+ cardiac_geometriesx-0.0.4.dist-info/RECORD,,
@@ -1,14 +0,0 @@
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,,