From 7811ba980e65ff170b62776330142f11419bd69d Mon Sep 17 00:00:00 2001 From: Karthik Menon Date: Mon, 14 Oct 2024 15:01:16 -0700 Subject: [PATCH 1/2] removed redundant docs --- docs/pages/GUI.md | 27 +-- docs/pages/add_block.md | 6 + docs/pages/main.md | 468 +----------------------------------- docs/pages/visualization.md | 17 +- src/algebra/Integrator.h | 89 +------ src/algebra/SparseSystem.h | 37 +-- 6 files changed, 21 insertions(+), 623 deletions(-) diff --git a/docs/pages/GUI.md b/docs/pages/GUI.md index 7e4507285..86c6de8d3 100644 --- a/docs/pages/GUI.md +++ b/docs/pages/GUI.md @@ -27,29 +27,6 @@ interactive elements and graphical networks. This architecture supports an intuitive user experience for generating and managing 0D input files through a graphical interface. +# User guide -# How to Use -1. Create a virtual environment with the required `flask` dependency. If using `conda`, use the below commands: - ```bash - conda create -n svZeroDGUI python=3.10 flask - conda activate svZeroDGUI - ``` -2. Navigate to the `applications` folder and then to the `create_0dmodel` subdirectory. -3. Launch the `app.py` file. - ```bash - python applications/svZeroDGUI/app.py - ``` -4. Select a node type and name the node. - - For vessels, after drawing the node, click on it to open a form -where you can enter details such as vessel length, diameter, and more. - - For junctions, click the node to specify if it’s a Normal %Junction -or a Blood Vessel %Junction. -5. To draw edges between nodes, toggle the `Draw on` button on the right. -Once active, you can start connecting nodes by drawing edges between them. -6. When you wish to stop drawing edges and continue adding or moving nodes, -click the `Draw off` button. -7. Once you’ve completed the network, click `Export to JSON` on the right. -If there are any incorrect connections or patterns, an alert will prompt you -to make necessary changes so the network can be processed by svZeroDSolver. -8. Open the downloaded JSON file and add any additional information, -such as boundary condition data, before running it through svZeroDSolver. +A user guide is available on the [SimVascular website](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-gui). diff --git a/docs/pages/add_block.md b/docs/pages/add_block.md index cf6d4ca26..17828a5f9 100644 --- a/docs/pages/add_block.md +++ b/docs/pages/add_block.md @@ -156,3 +156,9 @@ system.dC_dy.coeffRef(global_eqn_ids[current_block_equation_id], global_var_ids[ * Add `MyNewBlock.h` and `MyNewBlock.cpp` to `src/model/CMakeLists.txt` +


+ +## 5. Add the new block to svZeroDVisualization. + +* Follow the instructions [here](@ref visualization) to make sure your new block can be visualized graphically. + diff --git a/docs/pages/main.md b/docs/pages/main.md index ce6a8a146..7715c00ab 100644 --- a/docs/pages/main.md +++ b/docs/pages/main.md @@ -2,468 +2,18 @@ [TOC] -svZeroDSolver is an application for performing simulations with 0D/lumped-parameter -computer models for cardiovascular flows. +svZeroDSolver is an application for performing simulations with 0D/lumped-parameter computer models for cardiovascular flows. -Some noteworthy features of svZeroDSolver are: -* It is completely modular. Users can create custom flow models by arranging -blocks corresponding to blood vessels, junctions, different types of -boundary conditions, etc. -* It is written in C++ to enable high-performance applications. -* svZeroDSolver offers both a Python API and a C++ shared library to interface with other -Python or C++-based applications. This allows it to be used in a fully coupled manner -with other multi-physics solvers, and for parameter estimation, uncertainty -quantification, etc. -* The svZeroDCalibrator application, which is included in svZeroDSolver, optimizes 0D -blood vessel parameters to recapitulate given time-varying flow and pressure measurements -(for example, from a high-fidelity 3D simulation). This allows users to build accurate -0D models that reflect observed hemodynamics. -* The svZeroDVisualization application enables users to visualize their 0D network and -interactively select nodes to view simulation results. -* The svZeroDGUI application allows users to generate input files for svZeroDSolver by -drawing the network on an easy-to-use GUI. This provides an alternative to manually -creating files and is useful for users without access to a 3D model. +An overview of svZeroDSolver, its features, and applications is available [on the SimVascular website](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver). +Below are links to important sections of the documentation: -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: -- Blood vessels -- Junctions -- Boundary conditions -- Heart chambers -- Heart valves - -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: -- BloodVessel -- BloodVesselJunction -- WindkesselBC - -For implementation details, have a look at the [source code](https://github.com/simvascular/svZeroDSolver). -Mathematics details can be found in the following classes: -- System of equations: SparseSystem -- Time integration: Integrator - -[More information about SimVascular](https://simvascular.github.io) - -# Installation - -svZeroDSolver can be installed in two different ways. For using the Python -API, an installation via pip is recommended. - -## Using pip - -For a pip installation, simply run the following command -(cloning of the repository is not required): - -```bash -pip install git+https://github.com/simvascular/svZeroDSolver.git -``` - -## Using CMake - -If you want to build svZeroDSolver manually from source, clone the repository -and run the following commands from the top directory of the project: - -```bash -mkdir Release -cd Release -cmake -DCMAKE_BUILD_TYPE=Release .. -cmake --build . -``` - - -@remark
- **Building on Sherlock** - -```bash -module load cmake/3.23.1 gcc/14.2.0 binutils/2.38 -mkdir Release -cd Release -cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=/share/software/user/open/gcc/14.2.0/bin/g++ -DCMAKE_C_COMPILER=/share/software/user/open/gcc/14.2.0/bin/gcc .. -cmake --build . -``` - -
- -# svZeroDSolver - Quick User Guide - -svZeroDSolver can be used to run zero-dimensional (0D) cardiovascular -simulations based on a given configuration. - -## Run svZeroDSolver from the command line - -svZeroDSolver can be executed from the command line using a JSON configuration -file. - -```bash -svzerodsolver tests/cases/steadyFlow_RLC_R.json result_steadyFlow_RLC_R.csv -``` - -The result will be written to a CSV file. - -## Run svZeroDSolver from other programs - -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. - -### In C++ - -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`. - -### In Python - -Please make sure that -you installed svZerodSolver via pip to enable this feature. We start by -importing pysvzerod: - -```python ->>> import pysvzerod -``` - -Next, we create a solver from our configuration. The configuration can -be specified by either a path to a JSON file: - -```python ->>> solver = pysvzerod.Solver("tests/cases/steadyFlow_RLC_R.json") -``` - -or as a Python dictionary: - -```python ->>> my_config = {...} ->>> solver = pysvzerod.Solver(my_config) -``` - -To run the simulation we add: - -```python ->>> solver.run() -``` - -The simulation result is now saved in the solver instance. We can obtain -results for individual degrees-of-freedom (DOFs) as -```python ->>> solver.get_single_result("flow:INFLOW:branch0_seg0") - -array([5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., - 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., - 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., - 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., - 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., - 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5.]) -``` -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: -```python ->>> solver.get_single_result_avg("flow:INFLOW:branch0_seg0") - -5.0 -``` - -Or the result of the full simulation as a pandas data frame: - -```python ->>> solver.get_full_result() - - name time flow_in flow_out pressure_in pressure_out -0 branch0_seg0 0.00 5.0 5.0 1100.0 600.0 -1 branch0_seg0 0.01 5.0 5.0 1100.0 600.0 -2 branch0_seg0 0.02 5.0 5.0 1100.0 600.0 -3 branch0_seg0 0.03 5.0 5.0 1100.0 600.0 -4 branch0_seg0 0.04 5.0 5.0 1100.0 600.0 -.. ... ... ... ... ... ... -96 branch0_seg0 0.96 5.0 5.0 1100.0 600.0 -97 branch0_seg0 0.97 5.0 5.0 1100.0 600.0 -98 branch0_seg0 0.98 5.0 5.0 1100.0 600.0 -99 branch0_seg0 0.99 5.0 5.0 1100.0 600.0 -100 branch0_seg0 1.00 5.0 5.0 1100.0 600.0 - -[101 rows x 6 columns] -``` - -There is also a function to retrieve the full result directly based on a given configuration: - -```python - ->>> my_config = {...} ->>> pysvzerod.simulate(my_config) - - name time flow_in flow_out pressure_in pressure_out -0 branch0_seg0 0.00 5.0 5.0 1100.0 600.0 -1 branch0_seg0 0.01 5.0 5.0 1100.0 600.0 -2 branch0_seg0 0.02 5.0 5.0 1100.0 600.0 -3 branch0_seg0 0.03 5.0 5.0 1100.0 600.0 -4 branch0_seg0 0.04 5.0 5.0 1100.0 600.0 -.. ... ... ... ... ... ... -96 branch0_seg0 0.96 5.0 5.0 1100.0 600.0 -97 branch0_seg0 0.97 5.0 5.0 1100.0 600.0 -98 branch0_seg0 0.98 5.0 5.0 1100.0 600.0 -99 branch0_seg0 0.99 5.0 5.0 1100.0 600.0 -100 branch0_seg0 1.00 5.0 5.0 1100.0 600.0 - -[101 rows x 6 columns] - -``` - -## Configuration - -svZeroDSolver is configured using either a JSON file or a Python -dictionary. The top-level structure of both is: - -```python -{ - "simulation_parameters": {...}, - "vessels": [...], - "junctions": [...], - "boundary_conditions": [...] -} -``` - -In the following sections, the individual categories are described in more -detail. - -### Simulation parameters - -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 | \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. - -### Vessels - -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. - -```python -{ - "boundary_conditions": { - "inlet": "INFLOW", # Optional: Name of inlet boundary condition - "outlet": "OUT", # Optional: Name of outlet boundary condition - }, - "vessel_id": 0, # ID of the vessel - "vessel_name": "branch0_seg0", # Name of vessel - "zero_d_element_type": "BloodVessel", # Type of vessel - "zero_d_element_values": {...} # Values for configuration parameters -} -``` - -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 - -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. - -```python -{ - "junction_name": "J0", # Name of the junction - "junction_type": "BloodVesselJunction", # Type of the junction - "inlet_vessels": [0], # List of vessel IDs connected to the inlet - "outlet_vessels": [1, 2], # List of vessel IDs connected to the inlet - "junction_values": {...} # Values for configuration parameters -} -``` - -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 - -More information about the boundary conditions can be found in their respective class references. Below is a template `FLOW` boundary condition. - -```python -{ - "bc_name": "INFLOW", # Name of the boundary condition - "bc_type": "FLOW", # Type of the boundary condition - "bc_values": {...} # Values for configuration parameters -}, -``` - -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`. - -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": [ ..., ..., ... ], # Comma-separated list of values - "t": [ ..., ..., ... ] # Comma-separated list of corresponding time stamps - } -}, -``` -See `svZeroDSolver/tests/cases/pulsatileFlow_R_RCR.json` for an example. - - - - - - - - - - - - - - -## Simulation Outputs - -The simulation outputs will be saved in the specified CSV file (`.csv`) when running `svZeroDSolver` from the command line as follows: -```bash -svzerodsolver .json .csv -``` -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 DOFs are labelled `flow::`. -- Pressure DOFs are labelled `pressure::`. -- Internal DOFs (i.e., variables internal to a block and not connected to upstream/downstream blocks) are labelled `:`. The internal variables for each block are listed in the blocks' [class documentation](https://simvascular.github.io/svZeroDSolver/annotated.html). - -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. - - -# Graphical User Interfaces - Quick User Guide - -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](@ref visualization). - -The svZeroDGUI application allows users to create 0D models using an interactive drag-drop graphical interface. Details are available [here](@ref GUI). - - -# svZeroDCalibrator - Quick User Guide - -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). - -## Run svZeroDCalibrator - -### From the command line -svZeroDCalibrator can be executed from the command line using a JSON configuration -file. - -```bash -svzerodcalibrator path/to/input_file.json path/to/output_file.json -``` - -The result will be written to a JSON file. - - -### In Python - -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: - -```python -import pysvzerod - -my_unoptimized_config = {...} -my_optimized_config = pysvzerod.calibrate(my_unoptimized_config) -``` - -## Configuration (file) - -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. - -```python -{ - "calibration_parameters": {...}, - "vessels": [...], - "junctions": [...], - "boundary_conditions": [...], - "y": { - "flow:INFLOW:branch0_seg0": [0.0, 0.1, ...], # Time series for DOF - "pressure:INFLOW:branch0_seg0": [0.0, 0.1, ...], # Time series for DOF - ... - }, - "dy": { - "flow:INFLOW:branch0_seg0": [0.0, 0.1, ...], # Time series for DOF - "pressure:INFLOW:branch0_seg0": [0.0, 0.1, ...], # Time series for DOF - ... - }, -} -``` - -### Calibration parameters - -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 | \f$10^{-5}\f$ -tolerance_increment | Increment tolerance for calibration | \f$10^{-10}\f$ -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 +* [Installing svZeroDSolver](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-install) +* [User guide for svZeroDSolver](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-user-guide) +* [User guide for svZeroDCalibrator](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-calibrator) +* [User guide for svZeroDVisualization](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-visualization) +* [User guide for svZeroDGUI](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-gui) # Developer Guide -If you are a developer and want to contribute to svZeroDSolver, you can find -more helpful information in our [Developer Guide](@ref developer_guide). +If you are a developer and want to contribute to svZeroDSolver, you can find more helpful information in our [Developer Guide](@ref developer_guide). diff --git a/docs/pages/visualization.md b/docs/pages/visualization.md index 3ef1269be..021fbd2fa 100644 --- a/docs/pages/visualization.md +++ b/docs/pages/visualization.md @@ -41,23 +41,8 @@ dependencies and avoid conflicts with other projects. # How to Use -Note: Files related to this application are in the `applications`folder, within the `dirgraph_visualization` subdirectory. - -1. Command line execution: Pass the file path to your input JSON file and the output directory where you want the visualization to be saved as command line arguments. - - Pass a third argument `export_csv` optionally if you want to save svZeroDSolver raw output. - - The program will execute svZeroDSolver, generate a directed graph visualization of your network, parse simulation results, and display the results along with the corresponding nodes on a local Flask server. - ```bash - python applications/svZeroDVisualization/visualize_simulation.py 'tests/cases/chamber_elastance_inductor.json' './output/circuit_img/dir_graph' - ``` - -2. Once the server is open, you can click on a node to inspect further. - - The data for that node will be displayed, including the simulation parameters input for that node, pressure/flow data, and any internal variables if present. - - Additional features include the ability to download figures and use the trace function - for more detailed inspection of network elements. The trace feature allows users to filter the - view by specific element types, such as isolating and examining only the blood vessels or - identifying the locations of the chambers within the network. This functionality enhances the - ability to focus on and analyze particular components of the network with precision. +A user guide is available on the [SimVascular website](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver-visualization). # How to Visualize a New Block 1. **Update JSON Parsing**: diff --git a/src/algebra/Integrator.h b/src/algebra/Integrator.h index 58bb96c17..71a206534 100644 --- a/src/algebra/Integrator.h +++ b/src/algebra/Integrator.h @@ -44,97 +44,10 @@ * * This class handles the time integration scheme for solving 0D blood * flow system using the generalized-\f$\alpha\f$ method \cite JANSEN2000305. - * The specific implementation in this solver is based on \cite bazilevs13 - * (Section 4.6.2). - * - * We are interested in solving the DAE system defined in SparseSystem for the - * solutions, \f$\mathbf{y}_{n+1}\f$ and \f$\dot{\mathbf{y}}_{n+1}\f$, at the - * next time, \f$t_{n+1}\f$, using the known solutions, \f$\mathbf{y}_{n}\f$ - * and \f$\dot{\mathbf{y}}_{n}\f$, at the current time, \f$t_{n}\f$. Note that - * \f$t_{n+1} = t_{n} + \Delta t\f$, where \f$\Delta t\f$ is the time step - * size. - * - * Using the generalized-\f$\alpha\f$ method, we launch a predictor step - * and a series of multi-corrector steps to solve for \f$\mathbf{y}_{n+1}\f$ - * and \f$\dot{\mathbf{y}}_{n+1}\f$. Similar to other predictor-corrector - * schemes, we evaluate the solutions at intermediate times between \f$t_{n}\f$ - * and \f$t_{n + 1}\f$. However, in the generalized-\f$\alpha\f$ method, we - * evaluate \f$\mathbf{y}\f$ and \f$\dot{\mathbf{y}}\f$ at different - * intermediate times. Specifically, we evaluate \f$\mathbf{y}\f$ at - * \f$t_{n+\alpha_{f}}\f$ and \f$\dot{\mathbf{y}}\f$ at - * \f$t_{n+\alpha_{m}}\f$, where \f$t_{n+\alpha_{f}} = t_{n} + - * \alpha_{f}\Delta t\f$ and \f$t_{n+\alpha_{m}} = t_{n} + \alpha_{m}\Delta - * t\f$. Here, \f$\alpha_{m}\f$ and \f$\alpha_{f}\f$ are the - * generalized-\f$\alpha\f$ parameters, where \f$\alpha_{m} = \frac{3 - \rho}{2 - * + 2\rho}\f$ and \f$\alpha_{f} = \frac{1}{1 + \rho}\f$. We - * set the default spectral radius \f$\rho=0.5\f$, whereas \f$\rho=0.0\f$ equals - * the BDF2 scheme and \f$\rho=1.0\f$ equals the trapezoidal rule. For each time - * step \f$n\f$, the procedure works as follows. - * - * **Predict** the new time step based on the assumption of a constant - * solution \f$\mathbf{y}\f$ and consistent time derivative - * \f$\dot{\mathbf{y}}\f$: \f[ \dot{\mathbf y}_{n+1}^0 = \frac{\gamma-1}{\gamma} - * \dot{\mathbf y}_n, \f] \f[ \mathbf y_{n+1}^0 = \mathbf y_n. \f] with - * \f$\gamma = \frac{1}{2} + \alpha_m - \alpha_f\f$. We then iterate through - * Newton-Raphson iterations \f$i\f$ as follows, until the residual is smaller - * than an absolute error\f$||\mathbf r||_\infty < \epsilon_\text{abs}\f$: - * - * 1. **Initiate** the iterates at the intermediate time levels: - * \f[ - * \dot{\mathbf y}_{n+\alpha_m}^i = \dot{\mathbf y}_n + \alpha_m \left( - * \dot{\mathbf y}_{n+1}^i - \dot{\mathbf y}_n \right), - * \f] - * \f[ - * \mathbf y_{n+\alpha_f}^i= \mathbf y_n + \alpha_f \left( \mathbf y_{n+1}^i - - * \mathbf y_n \right). - * \f] - * - * 2. **Solve** for the increment \f$\Delta\dot{\mathbf{y}}\f$ in the linear - * system: - * \f[ - * \mathbf K(\mathbf y_{n+\alpha_f}^i, \dot{\mathbf y}_{n+\alpha_m}^i) \cdot - * \Delta \dot{\mathbf y}_{n+1}^i = - \mathbf r(\mathbf y_{n+\alpha_f}^i, - * \dot{\mathbf y}_{n+\alpha_m}^i). - * \f] - * - * 3. **Update** the solution vectors: - * \f[ - * \dot{\mathbf y}_{n+1}^{i+1} = \dot{\mathbf y}_{n+1}^i + \Delta - * \dot{\mathbf y}_{n+1}^i, - * \f] - * \f[ - * \mathbf y_{n+1}^{i+1} = \mathbf y_{n+1}^i + \Delta \dot{\mathbf y}_{n+1}^i - * \gamma \Delta t_n. - * \f] * + * Mathematical details are available on the SimVascular documentation. */ -// * 3. \f$\textbf{Multi-corrector step}\f$: Then, for \f$k \in \left[0, -// N_{int} -// * - 1\right]\f$, we iteratively update our guess of -// * \f$\dot{\mathbf{y}}_{n+\alpha_{m}}^{k}\f$ and -// * \f$\mathbf{y}_{n+\alpha_{f}}^{k}\f$. We desire the residual, -// * \f$\textbf{r}\left(\dot{\mathbf{y}}_{n+\alpha_{m}}^{k + 1}, -// * \mathbf{y}_{n+\alpha_{f}}^{k + 1}, t_{n+\alpha_{f}}\right)\f$, to be -// * \f$\textbf{0}\f$. We solve this system using Newton's method. For -// details,see -// * SparseSystem. -// * -// * where \f$\gamma = 0.5 + \alpha_{m} - \alpha_{f}\f$. -// * -// * 4. \f$\textbf{Update step}\f$: Finally, we update \f$\mathbf{y}_{n+1}\f$ -// and -// * \f$\dot{\mathbf{y}}_{n+1}\f$ using our final value of -// * \f$\dot{\mathbf{y}}_{n+\alpha_{m}}\f$ and -// * \f$\mathbf{y}_{n+\alpha_{f}}\f$. \f[ -// * \mathbf{y}_{n+1} = \mathbf{y}_{n} + -// * \frac{\mathbf{y}_{n+\alpha_{f}}^{N_{int}} - -// * \mathbf{y}_{n}}{\alpha_{f}},\\ \dot{\mathbf{y}}_{n+1} = -// * \dot{\mathbf{y}}_{n} + \frac{\dot{\mathbf{y}}_{n+\alpha_{m}}^{N_{int}} - -// * \dot{\mathbf{y}}_{n}}{\alpha_{m}} \f] -// * -// */ - class Integrator { private: double alpha_m{0.0}; diff --git a/src/algebra/SparseSystem.h b/src/algebra/SparseSystem.h index df2893df6..099c2ff79 100644 --- a/src/algebra/SparseSystem.h +++ b/src/algebra/SparseSystem.h @@ -48,42 +48,9 @@ class Model; * This class contains all attributes and methods to create, modify, and * solve sparse systems. * - * Flow rate, pressure, and other hemodynamic quantities in 0D models of - * vascular anatomies are governed by a system of nonlinear - * differential-algebraic equations (DAEs): + * Mathematical details related to setting up the governing system of + * equations are available on the SimVascular documentation. * - * \f[ - * \mathbf{r}(\boldsymbol{\alpha}, \mathbf{y},\dot{\mathbf{y}}, t) = - * \mathbf{E}(\boldsymbol{\alpha}) \cdot \dot{\mathbf{y}} + - * \mathbf{F}(\boldsymbol{\alpha}) \cdot \mathbf{y} + - * \mathbf{c}(\mathbf{y},\dot{\mathbf{y}}, t) = \mathbf{0} - * \f] - * - * where \f$\mathbf{r},\textbf{y},\textbf{c} \in \mathbb{R}^{N}\f$ and - * \f$\textbf{E},\textbf{F} \in \mathbb{R}^{N \times N}\f$. Here, - * \f$\textbf{r}\f$ is the residual, \f$\textbf{y}\f$ is the vector of solution - * quantities and \f$\dot{\textbf{y}}\f$ is its time derivative. \f$N\f$ is the - * total number of equations and the total number of global unknowns. The DAE - * system is solved implicitly using the generalized-\f$\alpha\f$ method in - * Integrator. We then use the Newton-Raphson method to iteratively solve - * - * \f[ - * \mathbf{K}^{i} \cdot \Delta\dot{\mathbf{y}}^{i} = - \mathbf{r}^{i}, - * \f] - * - * with solution increment \f$\Delta\dot{\mathbf{y}}^{i}\f$ in iteration - * \f$i\f$. The linearization of the time-discretized system is - * - * \f[ - * \mathbf{K} = - * \frac{\partial \mathbf{r}}{\partial \mathbf{y}} = - * c_{\dot{\mathbf{y}}} \left( \mathbf{E} + \frac{\partial \mathbf{c}}{\partial - * \dot{\mathbf{y}}} \right) + - * c_{\mathbf{y}} \left( \mathbf{F} + \frac{\partial \mathbf{c}}{\partial - * \mathbf{y}} \right), \f] - * - * with time factors \f$c_{\dot{\mathbf{y}}}=\alpha_m\f$ and - * \f$c_{\mathbf{y}}=\alpha_f\gamma\Delta t\f$ provided by Integrator. */ class SparseSystem { public: From 3a4ed0f2492096f0d2849f7329d3e9d18d4ba159 Mon Sep 17 00:00:00 2001 From: Karthik Menon Date: Mon, 14 Oct 2024 15:15:44 -0700 Subject: [PATCH 2/2] clang format, removed TOC in main page --- docs/pages/main.md | 2 -- src/algebra/Integrator.h | 4 +++- src/algebra/SparseSystem.h | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/pages/main.md b/docs/pages/main.md index 7715c00ab..e001e6d0b 100644 --- a/docs/pages/main.md +++ b/docs/pages/main.md @@ -1,7 +1,5 @@ @mainpage svZeroDSolver -[TOC] - svZeroDSolver is an application for performing simulations with 0D/lumped-parameter computer models for cardiovascular flows. An overview of svZeroDSolver, its features, and applications is available [on the SimVascular website](https://simvascular.github.io/documentation/rom_simulation.html#0d-solver). diff --git a/src/algebra/Integrator.h b/src/algebra/Integrator.h index 71a206534..4c8c29275 100644 --- a/src/algebra/Integrator.h +++ b/src/algebra/Integrator.h @@ -45,7 +45,9 @@ * This class handles the time integration scheme for solving 0D blood * flow system using the generalized-\f$\alpha\f$ method \cite JANSEN2000305. * - * Mathematical details are available on the SimVascular documentation. + * Mathematical details are available on the SimVascular + * documentation. */ class Integrator { diff --git a/src/algebra/SparseSystem.h b/src/algebra/SparseSystem.h index 099c2ff79..c82063d5e 100644 --- a/src/algebra/SparseSystem.h +++ b/src/algebra/SparseSystem.h @@ -48,8 +48,10 @@ class Model; * This class contains all attributes and methods to create, modify, and * solve sparse systems. * - * Mathematical details related to setting up the governing system of - * equations are available on the SimVascular documentation. + * Mathematical details related to setting up the governing system of + * equations are available on the SimVascular + * documentation. * */ class SparseSystem {