PurkinjeDiffusionForceField
Purkinje diffusion force field on a 1D Purkinje network (edge topology) PurkinjeDiffusionForceField ---------------------------- Electrical ForceField for a Purkinje network defined on an edge topology. At this stage, the component: - does not contribute any physical force (no diffusion yet), - only implements a draw() method that visualizes the 3D edges. Typical usage (Python): purk = meca_node.add_child("purkinje") purk_loader = purk + UnstructuredGridVTKLoader(...) topo_purk = purk + EdgeSetTopologyContainer(src=Link(purk_loader)) meca_purk = purk + MechanicalObject(src=Link(purk_loader)) purkinje_mesh = Mesh.load(params.purkinje_mesh) ini_cond = np.zeros((purkinje_mesh.nbPoints, 1)) elec_purk_node = elec_node.add_child("elec_purk_node") elec_purk_node + MechanicalObject(template="Vec1", position=ini_cond, name="u_purk_dof") elec_purk_node + UniformMass(vertexMass=1, topology=Link(topo_purk)) elec_purk_node + PurkinjeDiffusionForceField(topology=Link(topo_purk), mecaObj=Link(meca_purk))
The PurkinjeDiffusionForceField visualizes the 1D edge topology of a Purkinje network without contributing any physical forces to the simulation.
- module
- SofaMitchellSchaeffer
- namespace
- sofa_ff
- include
- PurkinjeDiffusionForceField.h
- inherits
-
- ForceField
- templates
-
- sofa::defaulttype::Vec1Types
- description
The PurkinjeDiffusionForceField is an electrical force field designed for simulating diffusion processes within the specialized cardiac conduction system, represented by a 1D Purkinje network. Despite its name and intended purpose, it currently does not contribute any physical forces to the simulation; instead, it focuses on visualizing the 3D edge topology of the Purkinje network.
Governing Equations and Operators:
-
Mass Matrix (M): Not explicitly computed or contributed by this component. Instead, a UniformMass element with
vertexMass=1is typically used to ensure the diffusion term can be interpreted as a direct force contribution $\frac{d u_i}{dt} = F(u)$. -
Stiffness Matrix (K): The stiffness matrix corresponds to the graph Laplacian for diffusion, represented by contributions from each edge. For an edge connecting nodes i and j:
$$ K_{ij} = -g_{ij}, \quad K_{ji} = g_{ij} $$where $g_{ij}$ is the conductance between nodes i and j, given by:
$$ g_{ij} = \frac{D}{L_{ij}} $$Here, D is the diffusion coefficient (in m^2/s), and $L_{ij}$ is the geometric edge length.
-
Internal Force (f_int): No physical forces are currently contributed by this component. The internal force vector f_int remains zero, as no actual diffusion forces are implemented yet.
Constitutive or Kinematic Laws:
-
Diffusion Term: While not implemented for force calculations, the future diffusion term would be based on a graph Laplacian approach where each node i experiences a flux from neighboring nodes j. The contribution to the internal force vector f_i is given by:
$$ F_i = -\sum_{j \in N(i)} g_{ij} (u_j - u_i) $$
Role in the Global FEM Pipeline:
-
Assembly Phase: Although the stiffness matrix construction is implemented, it currently does not contribute to any physical forces. The
buildStiffnessMatrixmethod would assemble contributions from each edge if diffusion were enabled. -
Time Integration: Implicit Euler or Newmark-type schemes can be used for time integration, but no force contribution is made by this component in the current implementation.
-
Nonlinear Solve and Linear Solve: The Jacobian-vector product (
addDForce) is implemented to handle potential future nonlinearities introduced by diffusion. However, since no forces are currently contributed, these methods do not perform any meaningful calculations.
Numerical Methods or Discretization Choices:
- Graph Laplacian Diffusion: The discretization approach uses a graph Laplacian formulation where each edge contributes to the stiffness matrix and force vector. This method is consistent with 1D diffusion on networks but currently not utilized for actual simulation forces.
Integration into Variational / Lagrangian Mechanics Framework:
-
Variational Consistency: Although this component does not contribute any physical forces, it adheres to the variational framework by defining a potential energy function that is identically zero (indicating no conservative mechanical potential).
-
Visualization Role: The
drawmethod enables visualization of the Purkinje network as straight line segments between nodes, using the linked MechanicalObject for node positions. This ensures consistency with the geometric representation used in other components.
Key Points:
- No actual diffusion force is currently implemented; only a visual representation and placeholder methods exist.
- Future implementations could extend this component to include graph Laplacian-based diffusion terms, contributing forces consistent with 1D diffusion along edges of the Purkinje network.
Data Fields
| Name | Type | Default | Help |
|---|---|---|---|
d_drawEdges |
bool | |
Enable or disable rendering of the Purkinje edges. |
d_diffusion |
Real | |
(effective 1D, in m^2/s). |
Methods
void
init
()
void
addForce
(const core::MechanicalParams * mparams, DataVecDeriv & dataF, const DataVecCoord & dataX, const DataVecDeriv & dataV)
void
addDForce
(const core::MechanicalParams * mparams, DataVecDeriv & dataDF, const DataVecDeriv & dataDX)
void
buildStiffnessMatrix
(core::behavior::StiffnessMatrix * matrix)
SReal
getPotentialEnergy
(const core::MechanicalParams * mparams, const DataVecCoord & dataX)
void
draw
(const core::visual::VisualParams * vparams)
{
"name": "PurkinjeDiffusionForceField",
"namespace": "sofa_ff",
"module": "SofaMitchellSchaeffer",
"include": "PurkinjeDiffusionForceField.h",
"doc": "Purkinje diffusion force field on a 1D Purkinje network (edge topology)\n\nPurkinjeDiffusionForceField\n----------------------------\nElectrical ForceField for a Purkinje network defined on an edge topology.\nAt this stage, the component:\n - does not contribute any physical force (no diffusion yet),\n - only implements a draw() method that visualizes the 3D edges.\nTypical usage (Python):\n purk = meca_node.add_child(\"purkinje\")\n purk_loader = purk + UnstructuredGridVTKLoader(...)\n topo_purk = purk + EdgeSetTopologyContainer(src=Link(purk_loader))\n meca_purk = purk + MechanicalObject(src=Link(purk_loader))\n purkinje_mesh = Mesh.load(params.purkinje_mesh)\n ini_cond = np.zeros((purkinje_mesh.nbPoints, 1))\n elec_purk_node = elec_node.add_child(\"elec_purk_node\")\n elec_purk_node + MechanicalObject(template=\"Vec1\", position=ini_cond, name=\"u_purk_dof\")\n elec_purk_node + UniformMass(vertexMass=1, topology=Link(topo_purk))\n elec_purk_node + PurkinjeDiffusionForceField(topology=Link(topo_purk),\n mecaObj=Link(meca_purk))",
"inherits": [
"ForceField"
],
"templates": [
"sofa::defaulttype::Vec1Types"
],
"data_fields": [
{
"name": "d_drawEdges",
"type": "bool",
"xmlname": "drawEdges",
"help": "Enable or disable rendering of the Purkinje edges."
},
{
"name": "d_diffusion",
"type": "Real",
"xmlname": "diffusion",
"help": "(effective 1D, in m^2/s)."
}
],
"links": [],
"methods": [
{
"name": "init",
"return_type": "void",
"params": [],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "addForce",
"return_type": "void",
"params": [
{
"name": "mparams",
"type": "const core::MechanicalParams *"
},
{
"name": "dataF",
"type": "DataVecDeriv &"
},
{
"name": "dataX",
"type": "const DataVecCoord &"
},
{
"name": "dataV",
"type": "const DataVecDeriv &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "addDForce",
"return_type": "void",
"params": [
{
"name": "mparams",
"type": "const core::MechanicalParams *"
},
{
"name": "dataDF",
"type": "DataVecDeriv &"
},
{
"name": "dataDX",
"type": "const DataVecDeriv &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "buildStiffnessMatrix",
"return_type": "void",
"params": [
{
"name": "matrix",
"type": "core::behavior::StiffnessMatrix *"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "getPotentialEnergy",
"return_type": "SReal",
"params": [
{
"name": "mparams",
"type": "const core::MechanicalParams *"
},
{
"name": "dataX",
"type": "const DataVecCoord &"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
},
{
"name": "draw",
"return_type": "void",
"params": [
{
"name": "vparams",
"type": "const core::visual::VisualParams *"
}
],
"is_virtual": false,
"is_pure_virtual": false,
"is_static": false,
"access": "public"
}
],
"description": "The PurkinjeDiffusionForceField is an electrical force field component specifically designed for simulating the diffusion process within a Purkinje network (a specialized cardiac conduction system). It operates on a 1D edge topology, representing the network's interconnections. Despite its name, it currently does not contribute any physical forces to the simulation and focuses primarily on visualizing the network through the `draw()` method.\n\n### Role in SOFA Ecosystem:\nThe component inherits from `ForceField` but does not yet implement diffusion dynamics. It is part of the SofaMitchellSchaeffer module and uses an EdgeSetTopologyContainer for topology management, linking to a MechanicalObject to obtain node positions.\n\n### Interactions with Other Components:\nPurkinjeDiffusionForceField interacts with other SOFA components via its API. Specifically, it requires links to `topology` (an EdgeSetTopologyContainer) and `mecaObj` (a MechanicalObject storing 3D Purkinje network node positions). It uses these links to access the geometric information necessary for rendering.\n\n### Practical Usage Guidance:\nThe component has two primary data fields: \n- `drawEdges`: A boolean flag that enables or disables the rendering of Purkinje edges in the visual representation.\n- `diffusion`: A scalar value representing the diffusion coefficient (in m^2/s) along the Purkinje edges. This is currently not used for force calculations but might be utilized in future implementations.\n\n### Methods:\nThe component provides methods that are part of the SOFA API, such as `addForce`, `addDForce`, and `buildStiffnessMatrix`. These methods are overridden to handle specific functionalities or warnings if diffusion is not yet implemented. The `draw` method renders 3D edges using the mechanical object's positions.\n\n### Usage:\nThe typical usage involves setting up a node with an EdgeSetTopologyContainer for the Purkinje network, linking it with MechanicalObjects for position data, and adding PurkinjeDiffusionForceField to visualize the network. No physical force contribution is made at this stage.",
"maths": "The PurkinjeDiffusionForceField is an electrical force field designed for simulating diffusion processes within the specialized cardiac conduction system, represented by a 1D Purkinje network. Despite its name and intended purpose, it currently does not contribute any physical forces to the simulation; instead, it focuses on visualizing the 3D edge topology of the Purkinje network.\n\n### Governing Equations and Operators:\n- **Mass Matrix (M):** Not explicitly computed or contributed by this component. Instead, a UniformMass element with `vertexMass=1` is typically used to ensure the diffusion term can be interpreted as a direct force contribution \\(\\frac{d u_i}{dt} = F(u)\\).\n\n- **Stiffness Matrix (K):** The stiffness matrix corresponds to the graph Laplacian for diffusion, represented by contributions from each edge. For an edge connecting nodes i and j:\n \n \\[ K_{ij} = -g_{ij}, \\quad K_{ji} = g_{ij} \\]\n\n where \\(g_{ij}\\) is the conductance between nodes i and j, given by:\n \n \\[ g_{ij} = \\frac{D}{L_{ij}} \\]\n \n Here, D is the diffusion coefficient (in m^2/s), and \\(L_{ij}\\) is the geometric edge length.\n\n- **Internal Force (f_int):** No physical forces are currently contributed by this component. The internal force vector f_int remains zero, as no actual diffusion forces are implemented yet.\n\n### Constitutive or Kinematic Laws:\n- **Diffusion Term:** While not implemented for force calculations, the future diffusion term would be based on a graph Laplacian approach where each node i experiences a flux from neighboring nodes j. The contribution to the internal force vector f_i is given by:\n \n \\[ F_i = -\\sum_{j \\in N(i)} g_{ij} (u_j - u_i) \\]\n\n### Role in the Global FEM Pipeline:\n- **Assembly Phase:** Although the stiffness matrix construction is implemented, it currently does not contribute to any physical forces. The `buildStiffnessMatrix` method would assemble contributions from each edge if diffusion were enabled.\n\n- **Time Integration:** Implicit Euler or Newmark-type schemes can be used for time integration, but no force contribution is made by this component in the current implementation.\n\n- **Nonlinear Solve and Linear Solve:** The Jacobian-vector product (`addDForce`) is implemented to handle potential future nonlinearities introduced by diffusion. However, since no forces are currently contributed, these methods do not perform any meaningful calculations.\n\n### Numerical Methods or Discretization Choices:\n- **Graph Laplacian Diffusion:** The discretization approach uses a graph Laplacian formulation where each edge contributes to the stiffness matrix and force vector. This method is consistent with 1D diffusion on networks but currently not utilized for actual simulation forces.\n\n### Integration into Variational / Lagrangian Mechanics Framework:\n- **Variational Consistency:** Although this component does not contribute any physical forces, it adheres to the variational framework by defining a potential energy function that is identically zero (indicating no conservative mechanical potential).\n\n- **Visualization Role:** The `draw` method enables visualization of the Purkinje network as straight line segments between nodes, using the linked MechanicalObject for node positions. This ensures consistency with the geometric representation used in other components.\n\n### Key Points:\n- No actual diffusion force is currently implemented; only a visual representation and placeholder methods exist.\n- Future implementations could extend this component to include graph Laplacian-based diffusion terms, contributing forces consistent with 1D diffusion along edges of the Purkinje network.",
"abstract": "The PurkinjeDiffusionForceField visualizes the 1D edge topology of a Purkinje network without contributing any physical forces to the simulation.",
"sheet": "# PurkinjeDiffusionForceField\n\n## Overview\nPurkinjeDiffusionForceField is an electrical force field component designed for simulating diffusion processes within a Purkinje network. It currently does not contribute any physical forces but focuses on visualizing the 3D edge topology of the network.\n\n## Parameters and Data\nThe significant data fields exposed by this component are:\n- **drawEdges**: A boolean flag that enables or disables rendering of the Purkinje edges (`default: false`).\n- **diffusion**: A scalar value representing the diffusion coefficient (in m^2/s), which is currently not used for force calculations but might be utilized in future implementations.\n\n## Practical Notes\nThis component primarily serves a visualization role and does not contribute any physical forces to the simulation. It requires links to `topology` (an EdgeSetTopologyContainer) and `mecaObj` (a MechanicalObject storing 3D Purkinje network node positions). Future extensions could include implementing diffusion dynamics, contributing forces consistent with 1D diffusion along edges of the Purkinje network."
}