From 084f865d55926ea558f8236e70b5b84e48a97fa2 Mon Sep 17 00:00:00 2001 From: Karthik Menon Date: Mon, 8 Jul 2024 21:16:12 -0700 Subject: [PATCH] review comments --- docs/pages/add_block.md | 18 ++++----- docs/pages/main.md | 84 ++++++++++++++++++++++++++--------------- 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/docs/pages/add_block.md b/docs/pages/add_block.md index 1f4474007..c1e477a71 100644 --- a/docs/pages/add_block.md +++ b/docs/pages/add_block.md @@ -22,23 +22,23 @@ Below are details on the steps required to implement a new block in svZeroDSolve * The new class will be inherited from `Block`. Define a constructor of the form: ``` - GenericBlock(int id, Model *model) + MyNewBlock(int id, Model *model) : Block(id, model, BlockType::block_type, BlockClass::block_class, {{Param_1, InputParameter()}, {Param_2, InputParameter()}, ..., {Param_N, InputParameter()}}) {} ``` - * `GenericBlock` is the name of the new class + * `MyNewBlock` is the name of the new class * `block_type` and `block_class` are the same as what was added in Step 1 above. * The names of the input parameters of the block are `Param_1`, ... , `Param_N`. * The properties of each parameter are defined by `InputParameter`, which specifies whether it is optional, an array, a scalar, a function, and its default value. - * The names `Param_1`, ... , `Param_N` should be the same as the parameter names within the block definition in the `.json` configuration/input file. + * The names `Param_1`, ... , `Param_N` must be the same as the parameter names within the block definition in the `.json` configuration/input file.


### Set up the degrees of freedom -* The class should have a `setup_dofs(DOFHandler &dofhandler)` function. +* The class must have a `setup_dofs(DOFHandler &dofhandler)` function. * This function typically only includes a call to the following function: ``` Block::setup_dofs_(DOFHandler &dofhandler, int num_equations, const std::list &internal_var_names) @@ -99,7 +99,7 @@ a*dQ_in/dt + b*P_in + c*(dP_in/dt)*Q_in + d = 0 ``` e*dP_out/dt + f*Q_out*Q_out + g*P_out + h*I_1 = 0 ``` - * For this block, the `P_in` and `Q_in` are the pressure and flow at the inlet respectively, `P_out` and `Q_out` are the pressure and flow at the outlet, and `I_1` is an internal variable. + * For this block, the `P_in` and `Q_in` are the pressure and flow at the inlet respectively, `P_out` and `Q_out` are the pressure and flow at the outlet, and `I_1` is an internal variable. Test $dQ{in}/dt$. * The state vector is `[P_in, Q_in, P_out, Q_out, I_1]`. * The contributions to the local `F` matrix are `F[0,0] = b`, `F[1,2] = g` and `F[1,4] = h`. * The contributions to the local `E` matrix are `E[0,1] = a` and `E[1,2] = e`. @@ -113,9 +113,9 @@ e*dP_out/dt + f*Q_out*Q_out + g*P_out + h*I_1 = 0 ## 4. Implement the matrix equations for the block. * Implement the `update_constant`, `update_time` and `update_solution` functions. - * All matrix elements that are constant are specified in `update_constant`. - * Matrix elements that depend only on time (not the state variables) are specified in `update_time`. - * Matrix elements that change with the solution (i.e. depend on the state variables themselves) are specified in `update_solution`. + * All matrix elements that are constant must be specified in `update_constant`. + * Matrix elements that depend only on time (not the state variables) must be specified in `update_time`. + * Matrix elements that change with the solution (i.e. depend on the state variables themselves) must be specified in `update_solution`. * *Note: Not all blocks will require the `update_time` and `update_solution` functions.*


@@ -155,5 +155,5 @@ system.dC_dy.coeffRef(global_eqn_ids[current_block_equation_id], global_var_ids[ ## 4. Add the new block to the build system. -* Add `GenericBlock.h` and `GenericBlock.cpp` to `src/model/CMakeLists.txt` +* Add `MyNewBlock.h` and `MyNewBlock.cpp` to `src/model/CMakeLists.txt` diff --git a/docs/pages/main.md b/docs/pages/main.md index 7ada19813..4fefe7224 100644 --- a/docs/pages/main.md +++ b/docs/pages/main.md @@ -253,20 +253,20 @@ The svZeroDSolver can be configured with the following options in the 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 | \f$10^{-8}\f$ -maximum_nonlinear_iterations | Maximum number of nonlinear iterations for time integration | \f$30\f$ -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) | \f$1\f$ -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 +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 | \f$10^{-8}\f$ +`maximum_nonlinear_iterations` | Maximum number of nonlinear iterations for time integration | \f$30\f$ +`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) | \f$1\f$ +`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 \cite pfaller21, using the RCR boundary condition with the largest time constant. @@ -287,9 +287,9 @@ More information about the vessels can be found in their respective class refere } ``` -Description | Class | `zero_d_element_type` | `zero_d_element_values` -------------------------------------- | --------------------------- | --------------------- | ------------------------ -Blood vessel with \n optional stenosis | MODEL::BloodVessel | `BloodVessel` | `C`: Capacity \n `L`: Inductance \n `R_poiseuille`: Poiseuille resistance \n `stenosis_coefficient`: Stenosis coefficient +Description | Class | `zero_d_element_type` | `zero_d_element_values` +---------------------------------------- | --------------------------- | --------------------- | ------------------------ +Blood vessel with \n optional stenosis | BloodVessel | `BloodVessel` | `C`: Capacity \n `L`: Inductance \n `R_poiseuille`: Poiseuille resistance \n `stenosis_coefficient`: Stenosis coefficient ### Junctions @@ -306,11 +306,11 @@ More information about the junctions can be found in their respective class refe } ``` -Description | Class | `junction_type` | `junction_values` -------------------------------------- | --------------------------- | --------------------- | ----------- -Purely mass \n conserving \n junction | MODEL::Junction | `NORMAL_JUNCTION` | - -Resistive \n junction | MODEL::ResistiveJunction | `resistive_junction` | `R`: Ordered list of resistances for all inlets and outlets -Blood vessel \n junction | MODEL::BloodVesselJunction | `BloodVesselJunction` | Same as for `BloodVessel` element but \n as ordered list for each inlet and outlet +Description | Class | `junction_type` | `junction_values` +------------------------------------- | ---------------------| --------------------- | ----------- +Purely mass \n conserving \n junction | Junction | `NORMAL_JUNCTION` | - +Resistive \n junction | ResistiveJunction | `resistive_junction` | `R`: Ordered list of resistances for all inlets and outlets +Blood vessel \n junction | BloodVesselJunction | `BloodVesselJunction` | Same as for `BloodVessel` element but \n as ordered list for each inlet and outlet ### Boundary conditions @@ -324,17 +324,41 @@ More information about the boundary conditions can be found in their respective }, ``` -Description | Class | `bc_type` | `bc_values` -------------------------------------- | --------------------------- | --------------------- | ----------- -Prescribed (transient) flow | MODEL::FlowReferenceBC | `FLOW` | `Q`: Time-dependent flow values \n `t`: Time steps \n `fn`: Mathematical expression -Prescribed (transient) pressure | MODEL::PressureReferenceBC | `PRESSURE` | `P`: Time-dependent pressure values \n `t`: Time steps \n `fn`: Mathematical expression -Resistance | MODEL::ResistanceBC | `RESISTANCE` | `R`: Resistance \n `Pd`: Time-dependent distal pressure \n `t`: Time stamps -Windkessel | MODEL::WindkesselBC | `RCR` | `Rp`: Proximal resistance \n `C`: Capacitance \n `Rd`: Distal resistance \n `Pd`: Distal pressure -Coronary outlet | MODEL::OpenLoopCoronaryBC | `CORONARY` | `Ra`: Proximal resistance \n `Ram`: Microvascular resistance \n `Rv`: Venous resistance \n `Ca`: Small artery capacitance \n `Cim`: Intramyocardial capacitance \n `Pim`: Intramyocardial pressure \n `Pv`: Venous pressure +Description | Class | `bc_type` | `bc_values` +------------------------------------- | ---------------------- | --------------------- | ----------- +Prescribed (transient) flow | FlowReferenceBC | `FLOW` | `Q`: Time-dependent flow values \n `t`: Time steps \n `fn`: Mathematical expression \n Note: Either specify `Q` and `t` together, or just `fn` +Prescribed (transient) pressure | PressureReferenceBC | `PRESSURE` | `P`: Time-dependent pressure values \n `t`: Time steps \n `fn`: Mathematical expression \n Note: Either specify `Q` and `t` together, or just `fn` +Resistance | ResistanceBC | `RESISTANCE` | `R`: Resistance \n `Pd`: Time-dependent distal pressure \n `t`: Time stamps +Windkessel | WindkesselBC | `RCR` | `Rp`: Proximal resistance \n `C`: Capacitance \n `Rd`: Distal resistance \n `Pd`: Distal pressure +Coronary outlet | OpenLoopCoronaryBC | `CORONARY` | `Ra`: Proximal resistance \n `Ram`: Microvascular resistance \n `Rv`: Venous resistance \n `Ca`: Small artery capacitance \n `Cim`: Intramyocardial capacitance \n `Pim`: Intramyocardial pressure \n `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 an example where values of the boundary condition are specified as a function of time, see `svZeroDSolver/tests/cases/pulsatileFlow_R_RCR.json`. For an example with a mathematical expression for the boundary condition, see `svZeroDSolver/tests/cases/timeDep_Flow.json`. +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: +```python +{ + "bc_name": "INFLOW", # Name of the boundary condition + "bc_type": "FLOW", # Type of the boundary condition + "bc_values": { + "Q": [ ..., ..., ... ], + "t": [ ..., ..., ... ] + } +}, +``` +See `svZeroDSolver/tests/cases/pulsatileFlow_R_RCR.json` for an example. + +They can also be specified as a mathematica expression as follow: +```python +{ + "bc_name": "INFLOW", # Name of the boundary condition + "bc_type": "FLOW", # Type of the boundary condition + "bc_values": { + "fn": "2.0 * (4*atan(1.)) * cos(2.0 * (4*atan(1.)) * t)" + } +}, +``` +For an example with a mathematical expression for the boundary condition, see `svZeroDSolver/tests/cases/timeDep_Flow.json`. + # svZeroDCalibrator - Quick Guide