FEniCSx-LDRB#

ldrb.dolfinx_doste(mesh: Mesh, ffun: MeshTags, markers: dict[str, list[int]] | dict[str, tuple[int, ...]] | dict[str, int], fiber_space: str = 'P_1', apex_lv: Sequence[float] | None = None, apex_rv: Sequence[float] | None = None, alpha_endo_lv: float = 60, alpha_epi_lv: float = -60, beta_endo_lv: float = 20, beta_epi_lv: float = -20, alpha_endo_rv: float = 90, alpha_epi_rv: float = -25, beta_endo_rv: float = 0, beta_epi_rv: float = -20, alpha_endo_ot: float = 90, alpha_epi_ot: float = 0, beta_endo_ot: float = 0, beta_epi_ot: float = 0, petsc_options: dict[str, Any] | None = None) → DosteOutput[source]#

Create fiber, sheet and sheet-normal directions with the rule-based method for geometries with outflow tracts of Doste et al. (2019).

See ldrb.doste for the method and the convention of the angles.

Parameters:
  • mesh (dolfinx.mesh.Mesh) – The mesh

  • ffun (dolfinx.mesh.MeshTags) – A facet function containing markers for the boundaries.

  • markers (dict[str, int | list[int]]) – The markers of the boundaries in ffun: ‘lv’ (LV endocardium), ‘epi’ (epicardium), ‘mv’ (mitral valve) and ‘av’ (aortic valve), and for biventricular geometries also ‘rv’ (RV endocardium), ‘tv’ (tricuspid valve) and ‘pv’ (pulmonary valve). Other boundaries get zero Neumann conditions.

  • fiber_space (str) – A string on the form {family}_{degree} which determines the space of the fibers, by default “P_1”.

  • apex_lv (Sequence[float] (optional)) – The coordinates of the LV endocardial apex. The closest dof is used. If not provided, the point on the LV endocardium farthest from the centre of the mitral valve is used, see find_apex().

  • apex_rv (Sequence[float] (optional)) – The coordinates of the RV endocardial apex. If not provided, the point on the RV endocardium farthest from the centre of the tricuspid valve is used.

  • alpha_endo_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • alpha_epi_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • beta_endo_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • beta_epi_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • alpha_endo_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • alpha_epi_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • beta_endo_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • beta_epi_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • alpha_endo_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • alpha_epi_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • beta_endo_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • beta_epi_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

ldrb.dolfinx_ldrb(mesh: Mesh, fiber_space: str = 'P_1', ffun: MeshTags | None = None, markers: dict[str, list[int]] | dict[str, tuple[int, ...]] | dict[str, int] | None = None, alpha_endo_lv: float = 40, alpha_epi_lv: float = -50, alpha_endo_rv: float | None = None, alpha_epi_rv: float | None = None, alpha_endo_sept: float | None = None, alpha_epi_sept: float | None = None, beta_endo_lv: float = -65, beta_epi_lv: float = 25, beta_endo_rv: float | None = None, beta_epi_rv: float | None = None, beta_endo_sept: float | None = None, beta_epi_sept: float | None = None, epi_only: bool = False, petsc_options: dict[str, Any] | None = None, **kwargs) → LDRBOutput[source]#

Create fiber, cross fibers and sheet directions

Parameters:
  • mesh (dolfinx.mesh.Mesh) – The mesh

  • fiber_space (str) – A string on the form {family}_{degree} which determines for what space the fibers should be calculated for. If not provided, then a first order Lagrange space will be used, i.e Lagrange_1.

  • ffun (dolfinx.mesh.MeshTags) – A facet function containing markers for the boundaries.

  • markers (dict[str, int | list[int]] (optional)) – A dictionary with the markers for the different boundaries defined in the facet function or within the mesh itself. The following markers must be provided: ‘base’, ‘lv’, ‘epi, ‘rv’ (optional), ‘apex’ (optional). If ‘apex’ is given, those facets are the apex in the apex to base problem; otherwise the apex is the point farthest from the base. If the markers are not provided the following default vales will be used: base = 10, rv = 20, lv = 30, epi = 40

  • save_markers (bool) – If true save markings of the geometry. This is nice if you want to see that the LV, RV and Septum are marked correctly.

  • angles (kwargs) –

    Keyword arguments with the fiber and sheet angles. It is possible to set different angles on the LV, RV and septum, however it either the RV or septum angles are not provided, then the angles on the LV will be used. The default values are taken from the original paper, namely

    \[\begin{split}\alpha_{\text{endo}} &= 40 \\ \alpha_{\text{epi}} &= -50 \\ \beta_{\text{endo}} &= -65 \\ \beta_{\text{epi}} &= 25\end{split}\]

    The following keyword arguments are possible:

    alpha_endo_lvscalar

    Fiber angle at the LV endocardium.

    alpha_epi_lvscalar

    Fiber angle at the LV epicardium.

    beta_endo_lvscalar

    Sheet angle at the LV endocardium.

    beta_epi_lvscalar

    Sheet angle at the LV epicardium.

    alpha_endo_rvscalar

    Fiber angle at the RV endocardium.

    alpha_epi_rvscalar

    Fiber angle at the RV epicardium.

    beta_endo_rvscalar

    Sheet angle at the RV endocardium.

    beta_epi_rvscalar

    Sheet angle at the RV epicardium.

    alpha_endo_septscalar

    Fiber angle at the septum endocardium.

    alpha_epi_septscalar

    Fiber angle at the septum epicardium.

    beta_endo_septscalar

    Sheet angle at the septum endocardium.

    beta_epi_septscalar

    Sheet angle at the septum epicardium.

  • epi_only (bool) – If true, then only the angles on the epicardial surface will be used. This is a hack to make it possible to compute purely longitudinal fibers

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. This can be used to set the linear solver and preconditioner. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

ldrb.project_gradients(mesh: Mesh, scalar_solutions: dict[str, Function], fiber_space: str = 'P_1') → tuple[dict[str, ndarray], dict[str, Function]][source]#

Calculate the gradients from their L2 projection into the continuous vector space of the scalar solutions, evaluated in the fiber space (see _gradient)

Parameters:
  • mesh (dolfin.Mesh) – The mesh

  • fiber_space (str) – A string on the form {family}_{degree} which determines for what space the fibers should be calculated for.

  • scalar_solutions (dict) – A dictionary with the scalar solutions that you want to compute the gradients of.

ldrb.scalar_laplacians(mesh: Mesh, markers: dict[str, list[int]], ffun: MeshTags, petsc_options: dict[str, Any] | None = None) → dict[str, Function][source]#

Calculate the laplacians. The problems are solved with Lagrange elements of the same degree as the geometry.

Parameters:
  • mesh (dolfin.Mesh) – A dolfin mesh

  • markers (dict (optional)) – A dictionary with the markers for the different boundaries defined in the facet function or within the mesh itself. The following markers must be provided: ‘base’, ‘lv’, ‘epi, ‘rv’ (optional), ‘apex’ (optional). If ‘apex’ is given, those facets are the apex in the apex to base problem; otherwise the apex is the point farthest from the base. If the markers are not provided the following default vales will be used: base = 10, rv = 20, lv = 30, epi = 40.

  • ffun (dolfin.MeshFunctionSizet (optional)) – A facet function containing markers for the boundaries. If not provided, the markers stored within the mesh will be used.

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. This can be used to set the linear solver and preconditioner. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

ldrb.space_from_string(space_string: str, mesh: Mesh, dim: int) → FunctionSpace[source]#

Constructed a finite elements space from a string representation of the space

Parameters:
  • space_string (str) – A string on the form {family}_{degree} which determines the space. Example ‘Lagrange_1’.

  • mesh (df.Mesh) – The mesh

  • dim (int) – 1 for scalar space, 3 for vector space.

ldrb.calculus.axis(u: ndarray, v: ndarray) → ndarray[source]#

Construct the fiber orientation coordinate system.

Given two vectors \(u\) and \(v\) in the apicobasal and transmural direction respectively return a matrix that represents an orthonormal basis in the circumferential (first), apicobasal (second) and transmural (third) direction.

ldrb.calculus.bislerp(Qa: ndarray, Qb: ndarray, t: float) → ndarray[source]#

Linear interpolation of two orthogonal matrices. Assume that \(Q_a\) and \(Q_b\) refers to timepoint \(0\) and \(1\) respectively. Using spherical linear interpolation (slerp) find the orthogonal matrix at timepoint \(t\).

ldrb.calculus.normalize(u: ndarray) → ndarray[source]#

L2-Normalize vector with

Parameters:

u (np.ndarray) – Vector

Returns:

Normalized vector

Return type:

np.ndarray

ldrb.calculus.orient(Q: ndarray, alpha: float, beta: float) → ndarray[source]#

Define the orthotropic fiber orientations.

Given a coordinate system \(Q\), in the canonical basis, rotate it in order to align with the fiber, sheet and sheet-normal axis determine by the angles \(\alpha\) (fiber) and \(\beta\) (sheets).

ldrb.calculus.quat2rot(q: ndarray) → ndarray[source]#

Convert quaternion to rotation matrix

Parameters:

q (np.ndarray) – Quaternion

Returns:

Rotation matrix

Return type:

np.ndarray

ldrb.calculus.slerp(q1: ndarray, q2: ndarray, t: float) → ndarray[source]#

Spherical linear interpolation from q1 to q2 at t

Parameters:
  • q1 (np.ndarray) – Source quaternion

  • q2 (np.ndarray) – Target quaternion

  • t (float) – Interpolation factor, between 0 and 1

Returns:

The spherical linear interpolation between q1 and q2 at t

Return type:

np.ndarray

class ldrb.cli.Geometry(mesh: dolfinx.mesh.Mesh, ffun: dolfinx.mesh.MeshTags, markers: dict[str, list[int]])[source]#

Rule-based fibers for biventricular geometries with outflow tracts.

This is the outflow tract extended rule-based method (OT-RBM) from

Doste R, Soto-Iglesias D, Bernardino G, et al. A rule-based method to model myocardial fiber orientation in cardiac biventricular geometries with outflow tracts. Int J Numer Meth Biomed Engng. 2019;35:e3185. https://doi.org/10.1002/cnm.3185

Unlike the method of Bayer et al. in ldrb.dolfinx_ldrb(), the longitudinal direction is defined separately in each ventricle, as a blend of the direction from the apex to the inflow valve (mitral or tricuspid) and the direction from the apex to the outflow valve (aortic or pulmonary). The blend also interpolates the fiber angles between the values in the ventricle and in the outflow tract.

The angles follow the convention of ldrb.dolfinx_ldrb(): the longitudinal direction points from the apex towards the valves, the transmural direction points from the endocardium to the epicardium in both ventricles, and \(\alpha\) is the angle from the circumferential direction towards the longitudinal direction. In this convention the values in the paper are, with the opposite sign of the paper’s LV values,

\[\alpha_{\text{endo}} = 60, \alpha_{\text{epi}} = -60 \quad \text{(LV)}, \qquad \alpha_{\text{endo}} = 90, \alpha_{\text{epi}} = -25 \quad \text{(RV)}, \qquad \alpha_{\text{endo}} = 90, \alpha_{\text{epi}} = 0 \quad \text{(outflow tracts)}.\]

The transverse angle \(\beta\) rotates the fiber about the longitudinal direction, as in the paper, and its values here also have the opposite sign of the paper’s. The septal interpolation of the paper (Section 2.3.2) is not implemented.

ldrb.doste.compute_fiber_sheet_system(f0, s0, n0, marker_scalar, xdofs, ydofs, zdofs, sdofs, phi_scalar, phi_gradient, lv_rv_scalar, w_lv_scalar, psi_lv_basal_gradient, psi_lv_ot_gradient, w_rv_scalar, psi_rv_basal_gradient, psi_rv_ot_gradient, angles, has_rv)[source]#

Compute the fiber, sheet and sheet-normal directions at each dof.

angles has shape (2, 2, 4): ventricle (LV, RV), region (ventricle, outflow tract) and angle (alpha endo, alpha epi, beta endo, beta epi).

ldrb.doste.dolfinx_doste(mesh: Mesh, ffun: MeshTags, markers: dict[str, list[int]] | dict[str, tuple[int, ...]] | dict[str, int], fiber_space: str = 'P_1', apex_lv: Sequence[float] | None = None, apex_rv: Sequence[float] | None = None, alpha_endo_lv: float = 60, alpha_epi_lv: float = -60, beta_endo_lv: float = 20, beta_epi_lv: float = -20, alpha_endo_rv: float = 90, alpha_epi_rv: float = -25, beta_endo_rv: float = 0, beta_epi_rv: float = -20, alpha_endo_ot: float = 90, alpha_epi_ot: float = 0, beta_endo_ot: float = 0, beta_epi_ot: float = 0, petsc_options: dict[str, Any] | None = None) → DosteOutput[source]#

Create fiber, sheet and sheet-normal directions with the rule-based method for geometries with outflow tracts of Doste et al. (2019).

See ldrb.doste for the method and the convention of the angles.

Parameters:
  • mesh (dolfinx.mesh.Mesh) – The mesh

  • ffun (dolfinx.mesh.MeshTags) – A facet function containing markers for the boundaries.

  • markers (dict[str, int | list[int]]) – The markers of the boundaries in ffun: ‘lv’ (LV endocardium), ‘epi’ (epicardium), ‘mv’ (mitral valve) and ‘av’ (aortic valve), and for biventricular geometries also ‘rv’ (RV endocardium), ‘tv’ (tricuspid valve) and ‘pv’ (pulmonary valve). Other boundaries get zero Neumann conditions.

  • fiber_space (str) – A string on the form {family}_{degree} which determines the space of the fibers, by default “P_1”.

  • apex_lv (Sequence[float] (optional)) – The coordinates of the LV endocardial apex. The closest dof is used. If not provided, the point on the LV endocardium farthest from the centre of the mitral valve is used, see find_apex().

  • apex_rv (Sequence[float] (optional)) – The coordinates of the RV endocardial apex. If not provided, the point on the RV endocardium farthest from the centre of the tricuspid valve is used.

  • alpha_endo_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • alpha_epi_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • beta_endo_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • beta_epi_lv (float) – Fiber and transverse angles at the LV endocardium and epicardium.

  • alpha_endo_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • alpha_epi_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • beta_endo_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • beta_epi_rv (float) – Fiber and transverse angles at the RV endocardium and epicardium.

  • alpha_endo_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • alpha_epi_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • beta_endo_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • beta_epi_ot (float) – Fiber and transverse angles at the endocardium and epicardium of the outflow tracts.

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

ldrb.doste.find_apex(mesh: Mesh, ffun: MeshTags, endo_markers: list[int], valve_markers: list[int]) → ndarray[source]#

Find the apex as the point on the endocardium farthest from the centre of the valve.

Parameters:
  • mesh (dolfinx.mesh.Mesh) – The mesh

  • ffun (dolfinx.mesh.MeshTags) – A facet function containing markers for the boundaries.

  • endo_markers (list[int]) – The markers of the endocardium of the ventricle

  • valve_markers (list[int]) – The markers of the inflow valve of the ventricle (mitral or tricuspid)

Returns:

The coordinates of the apex

Return type:

np.ndarray

ldrb.doste.scalar_laplacians(mesh: Mesh, ffun: MeshTags, markers: dict[str, list[int]], apex_lv: Sequence[float] | ndarray, apex_rv: Sequence[float] | ndarray | None = None, petsc_options: dict[str, Any] | None = None) → dict[str, Function][source]#

Solve the Laplace problems of the method, with Lagrange elements of the same degree as the geometry.

Returns the transmural solution phi (-2 on the LV endocardium, 1 on the RV endocardium and 0 on the epicardium), and for each ventricle (lv and, if there is an RV, rv) the solutions psi_{ventricle}_basal and psi_{ventricle}_ot (0 at the apex and 1 at the inflow and outflow valve respectively) and the interpolation function w_{ventricle} (1 at the apex and the inflow valve, 0 at the outflow valve). For biventricular geometries it also returns lv_rv (1 on the LV endocardium and 0 on the RV endocardium), which decides the ventricle where phi is zero, i.e. on the epicardium.

class ldrb.io.DosteOutput(f0, s0, n0, markers_scalar, phi, psi_lv_basal, psi_lv_ot, w_lv, lv_rv, psi_rv_basal, psi_rv_ot, w_rv)[source]#
f0: Function#

Alias for field number 0

lv_rv: Function | None#

Alias for field number 8

markers_scalar: Function#

Alias for field number 3

n0: Function#

Alias for field number 2

phi: Function#

Alias for field number 4

psi_lv_basal: Function#

Alias for field number 5

psi_lv_ot: Function#

Alias for field number 6

psi_rv_basal: Function | None#

Alias for field number 9

psi_rv_ot: Function | None#

Alias for field number 10

s0: Function#

Alias for field number 1

w_lv: Function#

Alias for field number 7

w_rv: Function | None#

Alias for field number 11

class ldrb.io.FiberSheetSystem(f0, s0, n0)[source]#
f0: ndarray#

Alias for field number 0

n0: ndarray#

Alias for field number 2

s0: ndarray#

Alias for field number 1

class ldrb.io.LDRBOutput(f0, s0, n0, lv, rv, epi, lv_rv, apex, lv_scalar, rv_scalar, epi_scalar, lv_rv_scalar, apex_scalar, lv_gradient, rv_gradient, epi_gradient, lv_rv_gradient, apex_gradient, markers_scalar)[source]#
apex: Function | None#

Alias for field number 7

apex_gradient: Function | None#

Alias for field number 17

apex_scalar: Function | None#

Alias for field number 12

epi: Function | None#

Alias for field number 5

epi_gradient: Function | None#

Alias for field number 15

epi_scalar: Function | None#

Alias for field number 10

f0: Function#

Alias for field number 0

lv: Function | None#

Alias for field number 3

lv_gradient: Function | None#

Alias for field number 13

lv_rv: Function | None#

Alias for field number 6

lv_rv_gradient: Function | None#

Alias for field number 16

lv_rv_scalar: Function | None#

Alias for field number 11

lv_scalar: Function | None#

Alias for field number 8

markers_scalar: Function | None#

Alias for field number 18

n0: Function#

Alias for field number 2

rv: Function | None#

Alias for field number 4

rv_gradient: Function | None#

Alias for field number 14

rv_scalar: Function | None#

Alias for field number 9

s0: Function#

Alias for field number 1

ldrb.ldrb.apex_to_base(mesh: Mesh, base_marker: list[int], ffun: MeshTags, petsc_options: dict[str, Any] | None = None, apex_marker: list[int] | None = None) → Function[source]#

Compute the apex to base solution: the Laplace equation with 0 at the apex and 1 on the base.

By default the apex is a single point, found as the point farthest from the base. If apex_marker is given, the facets with those markers are the apex instead (Bayer et al. 2012 define the apex as a surface). Use this for geometries without a natural apex point, such as a slab or a cylinder.

Parameters:
  • mesh (dolfin.Mesh) – The mesh

  • base_marker (int) – The marker value for the basal facets

  • ffun (dolfin.MeshFunctionSizet (optional)) – A facet function containing markers for the boundaries. If not provided, the markers stored within the mesh will be used.

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. This can be used to set the linear solver and preconditioner. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

  • apex_marker (list[int] (optional)) – The marker values for the apical facets. If not provided, the apex is the point farthest from the base.

ldrb.ldrb.compute_fiber_sheet_system(lv_scalar: ndarray, lv_gradient: ndarray, epi_scalar: ndarray, epi_gradient: ndarray, apex_gradient: ndarray, dofs: ndarray | None = None, rv_scalar: ndarray | None = None, rv_gradient: ndarray | None = None, lv_rv_scalar: ndarray | None = None, marker_scalar: ndarray | None = None, alpha_endo_lv: float = 40, alpha_epi_lv: float = -50, alpha_endo_rv: float | None = None, alpha_epi_rv: float | None = None, alpha_endo_sept: float | None = None, alpha_epi_sept: float | None = None, beta_endo_lv: float = -65, beta_epi_lv: float = 25, beta_endo_rv: float | None = None, beta_epi_rv: float | None = None, beta_endo_sept: float | None = None, beta_epi_sept: float | None = None, epi_only: bool = False) → FiberSheetSystem[source]#

Compute the fiber-sheets system on all degrees of freedom.

ldrb.ldrb.dofs_from_function_space(mesh: Mesh, fiber_space: str) → ndarray[source]#

Get the dofs from a function spaces define in the fiber_space string.

ldrb.ldrb.dolfinx_ldrb(mesh: Mesh, fiber_space: str = 'P_1', ffun: MeshTags | None = None, markers: dict[str, list[int]] | dict[str, tuple[int, ...]] | dict[str, int] | None = None, alpha_endo_lv: float = 40, alpha_epi_lv: float = -50, alpha_endo_rv: float | None = None, alpha_epi_rv: float | None = None, alpha_endo_sept: float | None = None, alpha_epi_sept: float | None = None, beta_endo_lv: float = -65, beta_epi_lv: float = 25, beta_endo_rv: float | None = None, beta_epi_rv: float | None = None, beta_endo_sept: float | None = None, beta_epi_sept: float | None = None, epi_only: bool = False, petsc_options: dict[str, Any] | None = None, **kwargs) → LDRBOutput[source]#

Create fiber, cross fibers and sheet directions

Parameters:
  • mesh (dolfinx.mesh.Mesh) – The mesh

  • fiber_space (str) – A string on the form {family}_{degree} which determines for what space the fibers should be calculated for. If not provided, then a first order Lagrange space will be used, i.e Lagrange_1.

  • ffun (dolfinx.mesh.MeshTags) – A facet function containing markers for the boundaries.

  • markers (dict[str, int | list[int]] (optional)) – A dictionary with the markers for the different boundaries defined in the facet function or within the mesh itself. The following markers must be provided: ‘base’, ‘lv’, ‘epi, ‘rv’ (optional), ‘apex’ (optional). If ‘apex’ is given, those facets are the apex in the apex to base problem; otherwise the apex is the point farthest from the base. If the markers are not provided the following default vales will be used: base = 10, rv = 20, lv = 30, epi = 40

  • save_markers (bool) – If true save markings of the geometry. This is nice if you want to see that the LV, RV and Septum are marked correctly.

  • angles (kwargs) –

    Keyword arguments with the fiber and sheet angles. It is possible to set different angles on the LV, RV and septum, however it either the RV or septum angles are not provided, then the angles on the LV will be used. The default values are taken from the original paper, namely

    \[\begin{split}\alpha_{\text{endo}} &= 40 \\ \alpha_{\text{epi}} &= -50 \\ \beta_{\text{endo}} &= -65 \\ \beta_{\text{epi}} &= 25\end{split}\]

    The following keyword arguments are possible:

    alpha_endo_lvscalar

    Fiber angle at the LV endocardium.

    alpha_epi_lvscalar

    Fiber angle at the LV epicardium.

    beta_endo_lvscalar

    Sheet angle at the LV endocardium.

    beta_epi_lvscalar

    Sheet angle at the LV epicardium.

    alpha_endo_rvscalar

    Fiber angle at the RV endocardium.

    alpha_epi_rvscalar

    Fiber angle at the RV epicardium.

    beta_endo_rvscalar

    Sheet angle at the RV endocardium.

    beta_epi_rvscalar

    Sheet angle at the RV epicardium.

    alpha_endo_septscalar

    Fiber angle at the septum endocardium.

    alpha_epi_septscalar

    Fiber angle at the septum epicardium.

    beta_endo_septscalar

    Sheet angle at the septum endocardium.

    beta_epi_septscalar

    Sheet angle at the septum epicardium.

  • epi_only (bool) – If true, then only the angles on the epicardial surface will be used. This is a hack to make it possible to compute purely longitudinal fibers

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. This can be used to set the linear solver and preconditioner. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

ldrb.ldrb.project_gradients(mesh: Mesh, scalar_solutions: dict[str, Function], fiber_space: str = 'P_1') → tuple[dict[str, ndarray], dict[str, Function]][source]#

Calculate the gradients from their L2 projection into the continuous vector space of the scalar solutions, evaluated in the fiber space (see _gradient)

Parameters:
  • mesh (dolfin.Mesh) – The mesh

  • fiber_space (str) – A string on the form {family}_{degree} which determines for what space the fibers should be calculated for.

  • scalar_solutions (dict) – A dictionary with the scalar solutions that you want to compute the gradients of.

ldrb.ldrb.scalar_laplacians(mesh: Mesh, markers: dict[str, list[int]], ffun: MeshTags, petsc_options: dict[str, Any] | None = None) → dict[str, Function][source]#

Calculate the laplacians. The problems are solved with Lagrange elements of the same degree as the geometry.

Parameters:
  • mesh (dolfin.Mesh) – A dolfin mesh

  • markers (dict (optional)) – A dictionary with the markers for the different boundaries defined in the facet function or within the mesh itself. The following markers must be provided: ‘base’, ‘lv’, ‘epi, ‘rv’ (optional), ‘apex’ (optional). If ‘apex’ is given, those facets are the apex in the apex to base problem; otherwise the apex is the point farthest from the base. If the markers are not provided the following default vales will be used: base = 10, rv = 20, lv = 30, epi = 40.

  • ffun (dolfin.MeshFunctionSizet (optional)) – A facet function containing markers for the boundaries. If not provided, the markers stored within the mesh will be used.

  • petsc_options (dict (optional)) – A dictionary with petsc options to pass to the linear solvers. This can be used to set the linear solver and preconditioner. If not provided, the default options will be used, which are ksp_type = preonly and pc_type = lu.

ldrb.ldrb.standard_dofs(n: int) → ndarray[source]#

Get the standard list of dofs for a given length

ldrb.ldrb.transform_markers(markers: dict[str, list[int]]) → dict[str, list[int]][source]#

Convert markers generated with gmsh to format for ldrb

ldrb.utils.closest_dofs(V: FunctionSpace, point: Sequence[float] | ndarray) → ndarray[source]#

The local (owned and ghost) dofs of the node closest to point.

The node is chosen among the owned nodes of all processes and identified by its global index, so every process that has it, as owned or ghost, returns it. Matching by coordinates would miss ghost copies, whose tabulated coordinates can differ in the last bits.

ldrb.utils.default_markers() → dict[str, list[int]][source]#

Default markers for the mesh boundaries

ldrb.utils.geometry_degree(mesh: Mesh) → int[source]#

The degree of the coordinate element of the mesh

ldrb.utils.laplace_space(mesh: Mesh) → FunctionSpace[source]#

The space in which the Laplace problems are solved: Lagrange elements of the same degree as the geometry, so that the solutions are as accurate as the geometry.

ldrb.utils.parse_element(space_string: str, mesh: Mesh, dim: int) → _ElementBase[source]#

Parse a string representation of a basix element family

ldrb.utils.space_from_string(space_string: str, mesh: Mesh, dim: int) → FunctionSpace[source]#

Constructed a finite elements space from a string representation of the space

Parameters:
  • space_string (str) – A string on the form {family}_{degree} which determines the space. Example ‘Lagrange_1’.

  • mesh (df.Mesh) – The mesh

  • dim (int) – 1 for scalar space, 3 for vector space.