svZeroDSolver
Loading...
Searching...
No Matches
Integrator.h
Go to the documentation of this file.
1// Copyright (c) Stanford University, The Regents of the University of
2// California, and others.
3//
4// All Rights Reserved.
5//
6// See Copyright-SimVascular.txt for additional details.
7//
8// Permission is hereby granted, free of charge, to any person obtaining
9// a copy of this software and associated documentation files (the
10// "Software"), to deal in the Software without restriction, including
11// without limitation the rights to use, copy, modify, merge, publish,
12// distribute, sublicense, and/or sell copies of the Software, and to
13// permit persons to whom the Software is furnished to do so, subject
14// to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included
17// in all copies or substantial portions of the Software.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30/**
31 * @file Integrator.h
32 * @brief Integrator source file
33 */
34#ifndef SVZERODSOLVER_ALGEBRA_INTEGRATOR_HPP_
35#define SVZERODSOLVER_ALGEBRA_INTEGRATOR_HPP_
36
37#include <Eigen/Dense>
38
39#include "Model.h"
40#include "State.h"
41
42/**
43 * @brief Generalized-alpha integrator
44 *
45 * This class handles the time integration scheme for solving 0D blood
46 * flow system using the generalized-\f$\alpha\f$ method \cite JANSEN2000305.
47 * The specific implementation in this solver is based on \cite bazilevs13
48 * (Section 4.6.2).
49 *
50 * We are interested in solving the DAE system defined in SparseSystem for the
51 * solutions, \f$\mathbf{y}_{n+1}\f$ and \f$\dot{\mathbf{y}}_{n+1}\f$, at the
52 * next time, \f$t_{n+1}\f$, using the known solutions, \f$\mathbf{y}_{n}\f$
53 * and \f$\dot{\mathbf{y}}_{n}\f$, at the current time, \f$t_{n}\f$. Note that
54 * \f$t_{n+1} = t_{n} + \Delta t\f$, where \f$\Delta t\f$ is the time step
55 * size.
56 *
57 * Using the generalized-\f$\alpha\f$ method, we launch a predictor step
58 * and a series of multi-corrector steps to solve for \f$\mathbf{y}_{n+1}\f$
59 * and \f$\dot{\mathbf{y}}_{n+1}\f$. Similar to other predictor-corrector
60 * schemes, we evaluate the solutions at intermediate times between \f$t_{n}\f$
61 * and \f$t_{n + 1}\f$. However, in the generalized-\f$\alpha\f$ method, we
62 * evaluate \f$\mathbf{y}\f$ and \f$\dot{\mathbf{y}}\f$ at different
63 * intermediate times. Specifically, we evaluate \f$\mathbf{y}\f$ at
64 * \f$t_{n+\alpha_{f}}\f$ and \f$\dot{\mathbf{y}}\f$ at
65 * \f$t_{n+\alpha_{m}}\f$, where \f$t_{n+\alpha_{f}} = t_{n} +
66 * \alpha_{f}\Delta t\f$ and \f$t_{n+\alpha_{m}} = t_{n} + \alpha_{m}\Delta
67 * t\f$. Here, \f$\alpha_{m}\f$ and \f$\alpha_{f}\f$ are the
68 * generalized-\f$\alpha\f$ parameters, where \f$\alpha_{m} = \frac{3 - \rho}{2
69 * + 2\rho}\f$ and \f$\alpha_{f} = \frac{1}{1 + \rho}\f$. We
70 * set the default spectral radius \f$\rho=0.5\f$, whereas \f$\rho=0.0\f$ equals
71 * the BDF2 scheme and \f$\rho=1.0\f$ equals the trapezoidal rule. For each time
72 * step \f$n\f$, the procedure works as follows.
73 *
74 * **Predict** the new time step based on the assumption of a constant
75 * solution \f$\mathbf{y}\f$ and consistent time derivative
76 * \f$\dot{\mathbf{y}}\f$: \f[ \dot{\mathbf y}_{n+1}^0 = \frac{\gamma-1}{\gamma}
77 * \dot{\mathbf y}_n, \f] \f[ \mathbf y_{n+1}^0 = \mathbf y_n. \f] with
78 * \f$\gamma = \frac{1}{2} + \alpha_m - \alpha_f\f$. We then iterate through
79 * Newton-Raphson iterations \f$i\f$ as follows, until the residual is smaller
80 * than an absolute error\f$||\mathbf r||_\infty < \epsilon_\text{abs}\f$:
81 *
82 * 1. **Initiate** the iterates at the intermediate time levels:
83 * \f[
84 * \dot{\mathbf y}_{n+\alpha_m}^i = \dot{\mathbf y}_n + \alpha_m \left(
85 * \dot{\mathbf y}_{n+1}^i - \dot{\mathbf y}_n \right),
86 * \f]
87 * \f[
88 * \mathbf y_{n+\alpha_f}^i= \mathbf y_n + \alpha_f \left( \mathbf y_{n+1}^i -
89 * \mathbf y_n \right).
90 * \f]
91 *
92 * 2. **Solve** for the increment \f$\Delta\dot{\mathbf{y}}\f$ in the linear
93 * system:
94 * \f[
95 * \mathbf K(\mathbf y_{n+\alpha_f}^i, \dot{\mathbf y}_{n+\alpha_m}^i) \cdot
96 * \Delta \dot{\mathbf y}_{n+1}^i = - \mathbf r(\mathbf y_{n+\alpha_f}^i,
97 * \dot{\mathbf y}_{n+\alpha_m}^i).
98 * \f]
99 *
100 * 3. **Update** the solution vectors:
101 * \f[
102 * \dot{\mathbf y}_{n+1}^{i+1} = \dot{\mathbf y}_{n+1}^i + \Delta
103 * \dot{\mathbf y}_{n+1}^i,
104 * \f]
105 * \f[
106 * \mathbf y_{n+1}^{i+1} = \mathbf y_{n+1}^i + \Delta \dot{\mathbf y}_{n+1}^i
107 * \gamma \Delta t_n.
108 * \f]
109 *
110 */
111
112// * 3. \f$\textbf{Multi-corrector step}\f$: Then, for \f$k \in \left[0,
113// N_{int}
114// * - 1\right]\f$, we iteratively update our guess of
115// * \f$\dot{\mathbf{y}}_{n+\alpha_{m}}^{k}\f$ and
116// * \f$\mathbf{y}_{n+\alpha_{f}}^{k}\f$. We desire the residual,
117// * \f$\textbf{r}\left(\dot{\mathbf{y}}_{n+\alpha_{m}}^{k + 1},
118// * \mathbf{y}_{n+\alpha_{f}}^{k + 1}, t_{n+\alpha_{f}}\right)\f$, to be
119// * \f$\textbf{0}\f$. We solve this system using Newton's method. For
120// details,see
121// * SparseSystem.
122// *
123// * where \f$\gamma = 0.5 + \alpha_{m} - \alpha_{f}\f$.
124// *
125// * 4. \f$\textbf{Update step}\f$: Finally, we update \f$\mathbf{y}_{n+1}\f$
126// and
127// * \f$\dot{\mathbf{y}}_{n+1}\f$ using our final value of
128// * \f$\dot{\mathbf{y}}_{n+\alpha_{m}}\f$ and
129// * \f$\mathbf{y}_{n+\alpha_{f}}\f$. \f[
130// * \mathbf{y}_{n+1} = \mathbf{y}_{n} +
131// * \frac{\mathbf{y}_{n+\alpha_{f}}^{N_{int}} -
132// * \mathbf{y}_{n}}{\alpha_{f}},\\ \dot{\mathbf{y}}_{n+1} =
133// * \dot{\mathbf{y}}_{n} + \frac{\dot{\mathbf{y}}_{n+\alpha_{m}}^{N_{int}} -
134// * \dot{\mathbf{y}}_{n}}{\alpha_{m}} \f]
135// *
136// */
137
139 private:
140 double alpha_m{0.0};
141 double alpha_f{0.0};
142 double gamma{0.0};
143 double time_step_size{0.0};
144 double ydot_init_coeff{0.0};
145 double y_coeff{0.0};
146 double y_coeff_jacobian{0.0};
147 double atol{0.0};
148 int max_iter{0};
149 int size{0};
150 int n_iter{0};
151 int n_nonlin_iter{0};
152 Eigen::Matrix<double, Eigen::Dynamic, 1> y_af;
153 Eigen::Matrix<double, Eigen::Dynamic, 1> ydot_am;
154 SparseSystem system;
155 Model* model{nullptr};
156
157 public:
158 /**
159 * @brief Construct a new Integrator object
160 *
161 * @param model The model to simulate
162 * @param time_step_size Time step size for generalized-alpha step
163 * @param rho Spectral radius for generalized-alpha step
164 * @param atol Absolut tolerance for non-linear iteration termination
165 * @param max_iter Maximum number of non-linear iterations
166 */
167 Integrator(Model* model, double time_step_size, double rho, double atol,
168 int max_iter);
169
170 /**
171 * @brief Construct a new Integrator object
172 *
173 */
174 Integrator();
175
176 /**
177 * @brief Destroy the Integrator object
178 *
179 */
180 ~Integrator();
181
182 /**
183 * @brief Delete dynamically allocated memory (in class member
184 * SparseSystem<double> system).
185 */
186 void clean();
187
188 /**
189 * @brief Update integrator parameter and system matrices with model parameter
190 * updates.
191 *
192 * @param time_step_size Time step size for 0D model
193 */
194 void update_params(double time_step_size);
195
196 /**
197 * @brief Perform a time step
198 *
199 * @param state Current state
200 * @param time Current time
201 * @return New state
202 */
203 State step(const State& state, double time);
204
205 /**
206 * @brief Get average number of nonlinear iterations in all step calls
207 *
208 * @return Average number of nonlinear iterations in all step calls
209 *
210 */
211 double avg_nonlin_iter();
212};
213
214#endif // SVZERODSOLVER_ALGEBRA_INTEGRATOR_HPP_
model::Model source file
State source file.
Generalized-alpha integrator.
Definition Integrator.h:138
State step(const State &state, double time)
Perform a time step.
Definition Integrator.cpp:76
void clean()
Delete dynamically allocated memory (in class member SparseSystem<double> system).
Definition Integrator.cpp:62
double avg_nonlin_iter()
Get average number of nonlinear iterations in all step calls.
Definition Integrator.cpp:136
Integrator()
Construct a new Integrator object.
Definition Integrator.cpp:59
~Integrator()
Destroy the Integrator object.
Definition Integrator.cpp:60
void update_params(double time_step_size)
Update integrator parameter and system matrices with model parameter updates.
Definition Integrator.cpp:68
Model of 0D elements.
Definition Model.h:75
Sparse system.
Definition SparseSystem.h:88
State of the system.
Definition State.h:46