svZeroDSolver
|
svZeroDSolver is an application for performing simulations with 0D/lumped-parameter computer models for cardiovascular flows.
Some noteworthy features of svZeroDSolver are:
Zero-dimensional (0D) models are lightweight methods to simulate bulk hemodynamic quantities in the cardiovascular system. Unlike 3D and 1D models, 0D models are purely time-dependent; they are unable to simulate spatial patterns in the hemodynamics. 0D models are analogous to electrical circuits. The flow rate simulated by 0D models represents electrical current, while the pressure represents voltage. Three primary building blocks of 0D models are resistors, capacitors, and inductors. Resistance captures the viscous effects of blood flow, capacitance represents the compliance and distensibility of the vessel wall, and inductance represents the inertia of the blood flow. Different combinations of these building blocks, as well as others, can be formed to reflect the hemodynamics and physiology of different cardiovascular anatomies. These 0D models are governed by differential algebraic equations (DAEs).
The main categories of blocks implemented in svZeroDSolver are:
For an overview of available 0D elements (blocks) see: Block
You can find more details about governing equations in individual blocks in their respective documentation pages. For example:
For implementation details, have a look at the source code. Mathematics details can be found in the following classes:
More information about SimVascular
svZeroDSolver can be installed in two different ways. For using the Python API, an installation via pip is recommended.
For a pip installation, simply run the following command (cloning of the repository is not required):
If you want to build svZeroDSolver manually from source, clone the repository and run the following commands from the top directory of the project:
svZeroDSolver can be used to run zero-dimensional (0D) cardiovascular simulations based on a given configuration.
svZeroDSolver can be executed from the command line using a JSON configuration file.
The result will be written to a CSV file.
For some applications it is beneficial to run svZeroDSolver directly from within another program. For example, this can be useful when many simulations need to be performed (e.g. for calibration, uncertainty quantification, ...). It is also allows using svZeroDSolver with other solvers, for example as boundary conditions or forcing terms.
SvZeroDSolver needs to be built using CMake to use the shared library interface.
Detailed examples of interfacing with svZeroDSolver from C++ codes are available in the test cases at svZeroDSolver/tests/test_interface
.
Please make sure that you installed svZerodSolver via pip to enable this feature. We start by importing pysvzerod:
Next, we create a solver from our configuration. The configuration can be specified by either a path to a JSON file:
or as a Python dictionary:
To run the simulation we add:
The simulation result is now saved in the solver instance. We can obtain results for individual degrees-of-freedom (DOFs) as
The naming of the DOFs is similar to how results are written if the simulation option output_variable_based
is activated (see below). We can also obtain the mean result for a DOF over time with:
Or the result of the full simulation as a pandas data frame:
There is also a function to retrieve the full result directly based on a given configuration:
svZeroDSolver is configured using either a JSON file or a Python dictionary. The top-level structure of both is:
In the following sections, the individual categories are described in more detail.
The svZeroDSolver can be configured with the following options in the simulation_parameters
section of the input file. Parameters without a default value must be specified.
Parameter key | Description | Default value |
---|---|---|
number_of_cardiac_cycles | Number of cardiac cycles to simulate | - |
number_of_time_pts_per_cardiac_cycle | Number of time steps per cardiac cycle | - |
absolute_tolerance | Absolute tolerance for time integration | |
maximum_nonlinear_iterations | Maximum number of nonlinear iterations for time integration | |
steady_initial | Toggle whether to use the steady solution as the initial condition for the simulation | true |
output_variable_based | Output solution based on variables (i.e. flow+pressure at nodes and internal variables) | false |
output_interval | The frequency of writing timesteps to the output (1 means every time step is written to output) | |
output_mean_only | Write only the mean values over every timestep to output file | false |
output_derivative | Write time derivatives to output file | false |
output_all_cycles | Write all cardiac cycles to output file | false |
use_cycle_to_cycle_error | Use cycle-to-cycle error to determine number of cycles for convergence | false |
sim_cycle_to_cycle_percent_error | Percentage error threshold for cycle-to-cycle pressure and flow difference | 1.0 |
The option use_cycle_to_cycle_error
allows the solver to change the number of cardiac cycles it runs depending on the cycle-to-cycle convergence of the simulation. For simulations with no RCR boundary conditions, the simulation will add extra cardiac cycles until the difference between the mean pressure and flow in consecutive cycles is below the threshold set by sim_cycle_to_cycle_percent_error
at all inlets and outlets of the model. If there is at least one RCR boundary condition, the number of cycles is determined based on equation 21 of [7], using the RCR boundary condition with the largest time constant.
More information about the vessels can be found in their respective class references. Below is a template vessel block with boundary conditions, INFLOW
and OUT
, at its inlet and outlet respectively.
Description | Class | zero_d_element_type | zero_d_element_values |
---|---|---|---|
Blood vessel with optional stenosis | BloodVessel | BloodVessel | C : Capacity L : Inductance R_poiseuille : Poiseuille resistance stenosis_coefficient : Stenosis coefficient |
More information about the junctions can be found in their respective class references. Below is a template junction block that connects vessel ID 0 with vessel IDs 1 and 2.
Description | Class | junction_type | junction_values |
---|---|---|---|
Purely mass conserving junction | Junction | NORMAL_JUNCTION | - |
Resistive junction | ResistiveJunction | resistive_junction | R : Ordered list of resistances for all inlets and outlets |
Blood vessel junction | BloodVesselJunction | BloodVesselJunction | Same as for BloodVessel element but as ordered list for each inlet and outlet |
More information about the boundary conditions can be found in their respective class references. Below is a template FLOW
boundary condition.
Description | Class | bc_type | bc_values |
---|---|---|---|
Prescribed (transient) flow | FlowReferenceBC | FLOW | Q : Time-dependent flow values t : Time steps fn : Mathematical expression Note: Either specify Q and t together, or just fn |
Prescribed (transient) pressure | PressureReferenceBC | PRESSURE | P : Time-dependent pressure values t : Time steps fn : Mathematical expression Note: Either specify Q and t together, or just fn |
Resistance | ResistanceBC | RESISTANCE | R : Resistance Pd : Time-dependent distal pressure t : Time stamps |
Windkessel | WindkesselBC | RCR | Rp : Proximal resistance C : Capacitance Rd : Distal resistance Pd : Distal pressure |
Coronary outlet | OpenLoopCoronaryBC | CORONARY | Ra : Proximal resistance Ram : Microvascular resistance Rv : Venous resistance Ca : Small artery capacitance Cim : Intramyocardial capacitance Pim : Intramyocardial pressure Pv : Venous pressure |
The above table describes the most commonly used boundary conditions. In addition, svZeroDSolver includes various closed-loop boundary conditions. Examples can be found in svZeroDSolver/tests/cases
.
Note that the FLOW
and PRESSURE
boundary conditions accept mathematical expressions in bc_values
. For example, values of the boundary condition can be specified as a function of time as follow:
See svZeroDSolver/tests/cases/pulsatileFlow_R_RCR.json
for an example.
They can also be specified as a mathematica expression as follow:
For an example with a mathematical expression for the boundary condition, see svZeroDSolver/tests/cases/timeDep_Flow.json
.
The siumulation outputs will be saved in the specified CSV file (<name_of_output_file>.csv
) when running svZeroDSolver
from the command line as follows:
If the name of the CSV file is not specified, the default is output.csv
. The format of the file depends on the user-specified configuration within the simulation_parameters
block of the JSON configuration file.
If output_variable_based
is set to true
, the CSV file will contain all the degrees-of-freedom in the simulation. Otherwise, only the flow and pressure at the inlets and outlets of vessels is written.
The degrees-of-freedom (DOFs) follow the following naming scheme:
flow:<name_of_upstream_block>:<name_of_downstream_block>
.pressure:<name_of_upstream_block>:<name_of_downstream_block>
.<variable_name>:<block_name>
. The internal variables for each block are listed in the blocks' class documentation.When the outputs are written in the variable-based and vessel-based forms, the user can specify whether they want outputs written for all cardiac cycles or just the last cardiac cycle using the output_all_cycles
option. By default, only the last cycle is written. This makes the simulation more efficient.
The number of timesteps between each time the output is written is specified by output_interval
. By default, output is written at every time step.
The svZeroDSolver package includes two graphical interfaces - svZeroDVisualization and svZeroDGUI.
The svZeroDVisualization application allows users visualize the connectivity of 0D models and the simulated hemodynamics in each block. A user guide is available here.
The svZeroDGUI application allows users to create 0D models using an interactive drag-drop graphical interface. Details are available here.
svZeroDCalibrator can be used to calibrate cardiovascular 0D models (i.e. infer optimal parameters for the 0D elements) based on a given transient result (i.e. from a 3D simulation).
svZeroDCalibrator can be executed from the command line using a JSON configuration file.
The result will be written to a JSON file.
svZeroDCalibrator can also be called directly from Python. Please make sure that you installed svZerodSolver via pip to enable this feature. We start by importing pysvzerod:
In order to make svZeroDCalibrator easy to use, it is based on a similar configuration file than svZeroDSolver. Instead of the simulation_parameters
section, it has a section called calibration_parameters
. Additionally the optimization target (i.e. a given) 3D result is passed with the key y
and it's temporal derivative via dy
. See tests/cases/steadyFlow_calibration.json
for an example input file.
Here is a list of the parameters that can be specified in the calibration_parameters
section of the configuration file.
Parameter key | Description | Default value |
---|---|---|
tolerance_gradient | Gradient tolerance for calibration | |
tolerance_increment | Increment tolerance for calibration | |
maximum_iterations | Maximum calibration iterations | 100 |
calibrate_stenosis_coefficient | Toggle whether stenosis coefficient should be calibrated | True |
set_capacitance_to_zero | Toggle whether all capacitances should be manually set to zero | False |
initial_damping_factor | Initial damping factor for Levenberg-Marquardt optimization | 1.0 |
If you are a developer and want to contribute to svZeroDSolver, you can find more helpful information in our Developer Guide.