Skip to content

Commit 64a53ac

Browse files
refactor: simplify default material models (#1256)
Co-authored-by: pyansys-ci-bot <[email protected]>
1 parent c05462a commit 64a53ac

File tree

16 files changed

+1329
-291
lines changed

16 files changed

+1329
-291
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Simplify default material models

src/ansys/health/heart/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,7 @@ class MissingMaterialError(ValueError):
8585

8686
def __init__(self, part_name: str, material_type: Literal["EP", "Mechanical"]):
8787
super().__init__(f"Part {part_name} has no {material_type} material assigned.")
88+
89+
90+
class PartAlreadyExistsError(ValueError):
91+
"""Exception raised when a part already exists."""

src/ansys/health/heart/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import yaml
3838

3939
from ansys.health.heart import LOG as LOGGER
40-
from ansys.health.heart.exceptions import InvalidHeartModelError
40+
from ansys.health.heart.exceptions import InvalidHeartModelError, PartAlreadyExistsError
4141
from ansys.health.heart.landmarks import LandMarks
4242
from ansys.health.heart.objects import (
4343
Cap,
@@ -409,7 +409,7 @@ def create_part_by_ids(
409409

410410
if name in [p.name for p in self.parts]:
411411
LOGGER.error(f"Failed to create {name}. Name already exists.")
412-
return None
412+
raise PartAlreadyExistsError(f"Part {name} already exists.")
413413

414414
new_part_id = self.mesh._unused_volume_id
415415

src/ansys/health/heart/settings/defaults/electrophysiology.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@
7777
"percent_mid": Quantity(0.41, "dimensionless"),
7878
}
7979
default_beam_material_eikonal = {
80-
"sigma": Quantity(1, "mm/ms"), # mm/ms in case of eikonal model
80+
"sigma_fiber": Quantity(1, "mm/ms"), # mm/ms in case of eikonal model
8181
"beta": Quantity(140, "1/mm"),
8282
"cm": Quantity(0.001, "uF/mm^2"), # uF/mm^2
8383
"lambda": Quantity(0.2, "dimensionless"),
8484
}
8585

8686
# Create monodomain defaults by copying eikonal and changing relevant fields
8787
default_beam_material_monodomain = default_beam_material_eikonal.copy()
88-
default_beam_material_monodomain["sigma"] = Quantity(1, "mS/mm") # mS/mm
88+
default_beam_material_monodomain["sigma_fiber"] = Quantity(1, "mS/mm") # mS/mm
8989
default_myocardium_material_monodomain = default_myocardium_material_eikonal.copy()
9090
default_myocardium_material_monodomain["sigma_fiber"] = Quantity(0.5, "mS/mm") # mS/mm
9191
default_myocardium_material_monodomain["sigma_sheet"] = Quantity(0.1, "mS/mm") # mS/mm

src/ansys/health/heart/settings/material/ep_material.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class EPSolverType(Enum):
3838
REACTION_EIKONAL = "ReactionEikonal"
3939

4040

41-
class EPMaterialModel(BaseModel): # EM MAT 003
41+
class EPMaterialModel(BaseModel):
4242
"""Base class for all EP material models."""
4343

4444
sigma_fiber: Optional[float] = None
@@ -59,38 +59,39 @@ def check_inputs(self):
5959
return self
6060

6161

62-
class Insulator(BaseModel): # EM MAT 001
62+
class Insulator(EPMaterialModel):
6363
"""Insulator material."""
6464

6565
sigma_fiber: float = 0.0
66+
sigma_sheet_normal: float = 0.0
67+
sigma_sheet: float = 0.0
6668
cm: float = 0.0
6769
beta: float = 0.0
6870

6971

70-
# solver type should be managed from global settings and not in material settings.
72+
class Passive(EPMaterialModel):
73+
"""Hold data for a passive EP material."""
74+
75+
7176
class Active(EPMaterialModel):
72-
"""Hold data for EP material."""
77+
"""Hold data for an active EP material."""
7378

74-
sigma_fiber: Optional[float] = None
75-
sigma_sheet: Optional[float] = None
76-
sigma_sheet_normal: Optional[float] = None
79+
# NOTE: an active EP material has a cell model associated with it.
7780

7881
cell_model: Tentusscher = Field(default_factory=lambda: Tentusscher())
7982

8083

8184
class ActiveBeam(Active):
8285
"""Hold data for beam active EP material."""
8386

84-
sigma_fiber: float = 1.0
8587
# TODO: replace by TentusscherEndo
8688
cell_model: Tentusscher = Tentusscher()
87-
pmjres: float = 0.001
8889

90+
@model_validator(mode="after")
91+
def check_inputs(self):
92+
"""Post init method."""
93+
# ActiveBeam is by definition isotropic, so remove sheet conductivities if set
94+
self.sigma_sheet is None
95+
self.sigma_sheet_normal is None
8996

90-
# A Passive material model is actually the same as the EPMaterialModel
91-
class Passive(EPMaterialModel):
92-
"""Hold data for EP passive material."""
93-
94-
# sigma_fiber: Optional[float] = None
95-
# sigma_sheet: Optional[float] = None
96-
# sigma_sheet_normal: Optional[float] = None
97+
return self

0 commit comments

Comments
 (0)