svZeroDSolver
Loading...
Searching...
No Matches
ActiveStress.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Stanford University, The Regents of the
2// University of California, and others. SPDX-License-Identifier: BSD-3-Clause
3
4/**
5 * @file ActiveStress.h
6 * @brief Active stress models for chamber blocks
7 */
8
9#ifndef SVZERODSOLVER_MODEL_ACTIVESTRESS_HPP_
10#define SVZERODSOLVER_MODEL_ACTIVESTRESS_HPP_
11
12#include <Eigen/Core>
13#include <list>
14#include <memory>
15#include <string>
16#include <vector>
17
18#include "ActivationFunction.h"
19#include "Parameter.h"
20#include "ParameterHolder.h"
21#include "SparseSystem.h"
22
23/**
24 * @brief Base class for chamber active stress models
25 *
26 * An ActiveStress owns the dynamics of a chamber's active stress \f$\tau\f$.
27 * Subclasses may introduce additional internal variables and equations
28 * beyond ChamberSphere's fixed core state, and write directly into the same
29 * global SparseSystem that ChamberSphere writes into, using indices that are
30 * a fixed offset into ChamberSphere's own \ref Block::global_var_ids and
31 * \ref Block::global_eqn_ids arrays (which are passed down unchanged).
32 *
33 * ChamberSphere::setup_dofs() always registers, in this order:
34 * internal variables `radius, velo, stress, tau, volume,
35 * <extra_var_names()...>` and equations `momentum, spherical_stress,
36 * volume_change, acceleration, mass_conservation, pressure_equality,
37 * <this model's equations...>`, so the offsets below are invariant across
38 * ActiveStress subclasses.
39 */
41 public:
42 /**
43 * @name Fixed layout of ChamberSphere's always-present ("core") state
44 *
45 * Indices into the full \ref Block::global_var_ids / \ref
46 * Block::global_eqn_ids arrays that ChamberSphere passes down unchanged.
47 */
48 ///@{
49 static constexpr int RADIUS_VAR =
50 4; ///< Radius position within ChamberSphere's own global_var_ids array
51 static constexpr int VELO_VAR =
52 5; ///< Radial velocity position within ChamberSphere's own
53 ///< global_var_ids array
54 ///<
55 static constexpr int STRESS_VAR =
56 6; ///< Total wall stress position within ChamberSphere's own
57 ///< global_var_ids array
58 ///<
59 static constexpr int TAU_VAR =
60 7; ///< Active stress \f$\tau\f$ position within ChamberSphere's own
61 ///< global_var_ids array
62 ///<
63 static constexpr int VOLUME_VAR =
64 8; ///< Volume position within ChamberSphere's own global_var_ids array
65 static constexpr int NUM_CORE_VARS =
66 9; ///< A subclass's own extra
67 ///< variables start at
68 ///< global_var_ids[NUM_CORE_VARS + i]
69 static constexpr int NUM_CORE_EQNS =
70 6; ///< A subclass's own extra
71 ///< equations start at
72 ///< global_eqn_ids[NUM_CORE_EQNS + i]
73 ///@}
74
75 /**
76 * @brief Construct an ActiveStress model
77 *
78 * @param props Parameter name/spec pairs for this active stress type
79 */
80 explicit ActiveStress(
81 const std::vector<std::pair<std::string, InputParameter>>& props);
82
83 /**
84 * @brief Number of internal variables this model owns beyond
85 * ChamberSphere's fixed 5 (radius, velo, stress, tau, volume)
86 *
87 * @return Number of extra internal variables
88 */
89 virtual int num_extra_vars() const { return 0; }
90
91 /**
92 * @brief Names of this model's extra internal variables, in registration
93 * order (appended immediately after "volume")
94 *
95 * @return List of extra internal variable names
96 */
97 virtual std::list<std::string> extra_var_names() const { return {}; }
98
99 /**
100 * @brief Number of equations this model owns beyond ChamberSphere's fixed
101 * 6 core equations. Every ActiveStress supplies at least the equation
102 * defining \f$\tau\f$.
103 *
104 * @return Number of extra equations
105 */
106 virtual int num_extra_equations() const = 0;
107
108 /**
109 * @brief Constant (time- and solution-independent) contributions
110 *
111 * @param system System to update contributions at
112 * @param global_eqn_ids ChamberSphere's global equation indices
113 * @param global_var_ids ChamberSphere's global variable indices
114 */
115 virtual void update_constant(SparseSystem& system,
116 const std::vector<int>& global_eqn_ids,
117 const std::vector<int>& global_var_ids) {
118 (void)system;
119 (void)global_eqn_ids;
120 (void)global_var_ids;
121 }
122
123 /**
124 * @brief Time-dependent contributions
125 *
126 * @param system System to update contributions at
127 * @param global_eqn_ids ChamberSphere's global equation indices
128 * @param global_var_ids ChamberSphere's global variable indices
129 * @param activation_signal The chamber's ActivationFunction evaluated at
130 * the current time
131 */
132 virtual void update_time(SparseSystem& system,
133 const std::vector<int>& global_eqn_ids,
134 const std::vector<int>& global_var_ids,
135 double activation_signal) {
136 (void)system;
137 (void)global_eqn_ids;
138 (void)global_var_ids;
139 (void)activation_signal;
140 }
141
142 /**
143 * @brief Solution-dependent contributions
144 *
145 * @param system System to update contributions at
146 * @param global_eqn_ids ChamberSphere's global equation indices
147 * @param global_var_ids ChamberSphere's global variable indices
148 * @param y Current solution
149 * @param dy Current derivative of the solution
150 * @param radius0 Reference radius \f$r_0\f$ of the chamber
151 * @param activation_signal The chamber's ActivationFunction evaluated at
152 * the current time
153 */
154 virtual void update_solution(
155 SparseSystem& system, const std::vector<int>& global_eqn_ids,
156 const std::vector<int>& global_var_ids,
157 const Eigen::Matrix<double, Eigen::Dynamic, 1>& y,
158 const Eigen::Matrix<double, Eigen::Dynamic, 1>& dy, double radius0,
159 double activation_signal) = 0;
160
161 /**
162 * @brief Type of activation signal this active stress model needs
163 *
164 * Checked against the chamber's ActivationFunction::signal_type in
165 * ChamberSphere::setup_dofs to catch mismatched pairings (e.g.
166 * strain_dependent active stress with a normalized activation function).
167 *
168 * @return The required ActivationSignalType
169 */
171
172 /**
173 * @brief Factory: create an active stress model from a type string
174 *
175 * @param type_str One of: "strain_independent", "strain_dependent"
176 * @return Unique pointer to the created active stress model
177 */
178 static std::unique_ptr<ActiveStress> create(const std::string& type_str);
179};
180
181/**
182 * @brief Strain-independent active stress model
183 *
184 * Owns 1 extra equation (the \f$\tau\f$ ODE) and 0 extra variables:
185 * \f[
186 * \dot{\tau} + |a| \tau - \sigma_\text{max} a_+ = 0, \quad a_+ = \max(a, 0),
187 * \quad a = f \alpha_\text{max} + (1 - f) \alpha_\text{min}
188 * \f]
189 * where \f$f \in [0, 1]\f$ is the activation function.
190 *
191 * Parameters: `alpha_max`, `alpha_min`, `sigma_max`
192 */
193class StrainIndependentActiveStress : public ActiveStress {
194 public:
195 StrainIndependentActiveStress()
196 : ActiveStress({{"alpha_max", InputParameter()},
197 {"alpha_min", InputParameter()},
198 {"sigma_max", InputParameter()}}) {}
199
200 int num_extra_equations() const override { return 1; }
201
205
206 void update_constant(SparseSystem& system,
207 const std::vector<int>& global_eqn_ids,
208 const std::vector<int>& global_var_ids) override;
209
210 void update_time(SparseSystem& system, const std::vector<int>& global_eqn_ids,
211 const std::vector<int>& global_var_ids,
212 double activation_signal) override;
213
214 void update_solution(SparseSystem& system,
215 const std::vector<int>& global_eqn_ids,
216 const std::vector<int>& global_var_ids,
217 const Eigen::Matrix<double, Eigen::Dynamic, 1>& y,
218 const Eigen::Matrix<double, Eigen::Dynamic, 1>& dy,
219 double radius0, double activation_signal) override;
220
221 private:
222 double act_ = 0.0; ///< Rate coefficient
223 double act_plus_ = 0.0; ///< Positive part of act_, act_plus_ = max(act_, 0)
224};
225
226/**
227 * @brief Strain-dependent active stress model from \cite caruel13
228 *
229 * Owns 5 extra equations and 4 extra variables (\f$e_c, \tau_c, k_c,
230 * \omega\f$, in that order):
231 * \f[
232 * \tau = E_s \frac{e_{1D} - e_c}{(1 + 2 e_c)^2}
233 * \f]
234 * with \f$e_{1D}\f$ the strain in fiber direction (a function of the
235 * chamber's radius), and evolution equations
236 * \f[
237 * \dot{\omega} = \frac{1}{\alpha_r}(m_0 - \omega)
238 * \f]
239 * \f[
240 * \dot{e}_c = \frac{1}{\mu}\left(E_s \frac{(e_{1D} - e_c)(1 + 2 e_{1D})}
241 * {(1 + 2 e_c)^3} - \tau_c\right)
242 * \f]
243 * \f[
244 * \dot{k}_c = -(|u|_+ + \omega |u|_- + \alpha |\dot{e}_c|) k_c + n_0 k_0 |u|_+
245 * \f]
246 * \f[
247 * \dot{\tau}_c = -(|u|_+ + \omega |u|_- + \alpha |\dot{e}_c|) \tau_c + n_0
248 * \sigma_0 |u|_+ + k_c \dot{e}_c
249 * \f]
250 * where \f$n_0\f$ (activation strain-dependence) and \f$m_0\f$ (relaxation
251 * strain-dependence) are piecewise-linear functions of \f$e_c\f$, given as
252 * break point tables (`n0_e_c`/`n0_values` and `m0_e_c`/`m0_values`) and
253 * evaluated with \ref linear_interpolate, and \f$u(t)\f$ is a reaction-rate
254 * signal supplied by the chamber's ActivationFunction (e.g. \ref
255 * PiecewiseRateActivation).
256 *
257 * Parameters: `E_s`, `mu`, `alpha_r`, `alpha`, `k_0`, `sigma_0`, `n0_e_c`,
258 * `n0_values`, `m0_e_c`, `m0_values`
259 */
260class StrainDependentActiveStress : public ActiveStress {
261 public:
262 StrainDependentActiveStress()
263 : ActiveStress({{"E_s", InputParameter()},
264 {"mu", InputParameter()},
265 {"alpha_r", InputParameter()},
266 {"alpha", InputParameter()},
267 {"k_0", InputParameter()},
268 {"sigma_0", InputParameter()},
269 {"n0_e_c", InputParameter(false, true)},
270 {"n0_values", InputParameter(false, true)},
271 {"m0_e_c", InputParameter(false, true)},
272 {"m0_values", InputParameter(false, true)}}) {}
273
274 int num_extra_vars() const override { return 4; }
275 std::list<std::string> extra_var_names() const override {
276 return {"e_c", "tau_c", "k_c", "omega"};
277 }
278 int num_extra_equations() const override { return 5; }
279
283
284 void update_constant(SparseSystem& system,
285 const std::vector<int>& global_eqn_ids,
286 const std::vector<int>& global_var_ids) override;
287
288 void update_time(SparseSystem& system, const std::vector<int>& global_eqn_ids,
289 const std::vector<int>& global_var_ids,
290 double activation_signal) override;
291
292 void update_solution(SparseSystem& system,
293 const std::vector<int>& global_eqn_ids,
294 const std::vector<int>& global_var_ids,
295 const Eigen::Matrix<double, Eigen::Dynamic, 1>& y,
296 const Eigen::Matrix<double, Eigen::Dynamic, 1>& dy,
297 double radius0, double activation_signal) override;
298
299 private:
300 /**
301 * @name Extra variable/equation positions within the full ChamberSphere
302 * global_var_ids/global_eqn_ids arrays
303 *
304 * Reproduce the exact global_var_ids/global_eqn_ids indices that the
305 * ChamberSphere used.
306 */
307 ///@{
308 static constexpr int E_C_VAR = NUM_CORE_VARS + 0; // 9
309 static constexpr int TAU_C_VAR = NUM_CORE_VARS + 1; // 10
310 static constexpr int K_C_VAR = NUM_CORE_VARS + 2; // 11
311 static constexpr int OMEGA_VAR = NUM_CORE_VARS + 3; // 12
312 static constexpr int TAU_EQN = NUM_CORE_EQNS + 0; // 6
313 static constexpr int OMEGA_EQN = NUM_CORE_EQNS + 1; // 7
314 static constexpr int E_C_EQN = NUM_CORE_EQNS + 2; // 8
315 static constexpr int K_C_EQN = NUM_CORE_EQNS + 3; // 9
316 static constexpr int TAU_C_EQN = NUM_CORE_EQNS + 4; // 10
317 ///@}
318
319 /**
320 * @brief Update the strain-dependent coefficients used across this
321 * model's equations
322 *
323 * @param e_c Current sarcomere element strain
324 */
325 void update_active_stress_values(double e_c);
326
327 double n_0_ = 0.0; // activation strain-dependence
328 double m_0_ = 0.0; // relaxation strain-dependence
329 double dn_0_de_c_ = 0.0; // d(n_0)/d(e_c), local slope of n0_e_c/n0_values
330 double dm_0_de_c_ = 0.0; // d(m_0)/d(e_c), local slope of m0_e_c/m0_values
331 double u_plus_ = 0.0; // positive part of the reaction-rate signal
332 double u_minus_ = 0.0; // negative part of the reaction-rate signal
333};
334
335#endif // SVZERODSOLVER_MODEL_ACTIVESTRESS_HPP_
Activation function classes for cardiac chamber models.
ActivationSignalType
Type of signal an ActivationFunction produces.
Definition ActivationFunction.h:27
@ normalized
f(t) in [0, 1], used by most activation functions
Definition ActivationFunction.h:28
@ rate
Definition ActivationFunction.h:29
model::Parameter source file
Common base for chamber sub-components configured from input parameters.
SparseSystem source file.
static constexpr int TAU_VAR
Definition ActiveStress.h:59
virtual int num_extra_equations() const =0
Number of equations this model owns beyond ChamberSphere's fixed 6 core equations....
static constexpr int VELO_VAR
Definition ActiveStress.h:51
virtual ActivationSignalType required_signal_type() const =0
Type of activation signal this active stress model needs.
virtual void update_constant(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids)
Constant (time- and solution-independent) contributions.
Definition ActiveStress.h:115
virtual int num_extra_vars() const
Number of internal variables this model owns beyond ChamberSphere's fixed 5 (radius,...
Definition ActiveStress.h:89
static std::unique_ptr< ActiveStress > create(const std::string &type_str)
Factory: create an active stress model from a type string.
Definition ActiveStress.cpp:14
static constexpr int NUM_CORE_VARS
Definition ActiveStress.h:65
virtual void update_time(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids, double activation_signal)
Time-dependent contributions.
Definition ActiveStress.h:132
ActiveStress(const std::vector< std::pair< std::string, InputParameter > > &props)
Construct an ActiveStress model.
Definition ActiveStress.cpp:10
virtual void update_solution(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &y, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &dy, double radius0, double activation_signal)=0
Solution-dependent contributions.
static constexpr int STRESS_VAR
Definition ActiveStress.h:55
static constexpr int RADIUS_VAR
Radius position within ChamberSphere's own global_var_ids array.
Definition ActiveStress.h:49
virtual std::list< std::string > extra_var_names() const
Names of this model's extra internal variables, in registration order (appended immediately after "vo...
Definition ActiveStress.h:97
static constexpr int VOLUME_VAR
Volume position within ChamberSphere's own global_var_ids array.
Definition ActiveStress.h:63
static constexpr int NUM_CORE_EQNS
Definition ActiveStress.h:69
ParameterHolder(const std::vector< std::pair< std::string, InputParameter > > &props)
Construct a ParameterHolder.
Definition ParameterHolder.cpp:5
Sparse system.
Definition SparseSystem.h:30
void update_time(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids, double activation_signal) override
Time-dependent contributions.
Definition ActiveStress.cpp:97
void update_solution(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &y, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &dy, double radius0, double activation_signal) override
Solution-dependent contributions.
Definition ActiveStress.cpp:128
ActivationSignalType required_signal_type() const override
Type of activation signal this active stress model needs.
Definition ActiveStress.h:280
std::list< std::string > extra_var_names() const override
Names of this model's extra internal variables, in registration order (appended immediately after "vo...
Definition ActiveStress.h:275
int num_extra_vars() const override
Number of internal variables this model owns beyond ChamberSphere's fixed 5 (radius,...
Definition ActiveStress.h:274
void update_constant(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids) override
Constant (time- and solution-independent) contributions.
Definition ActiveStress.cpp:72
int num_extra_equations() const override
Number of equations this model owns beyond ChamberSphere's fixed 6 core equations....
Definition ActiveStress.h:278
ActivationSignalType required_signal_type() const override
Type of activation signal this active stress model needs.
Definition ActiveStress.h:202
int num_extra_equations() const override
Number of equations this model owns beyond ChamberSphere's fixed 6 core equations....
Definition ActiveStress.h:200
void update_time(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids, double activation_signal) override
Time-dependent contributions.
Definition ActiveStress.cpp:37
void update_solution(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &y, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &dy, double radius0, double activation_signal) override
Solution-dependent contributions.
Definition ActiveStress.cpp:52
void update_constant(SparseSystem &system, const std::vector< int > &global_eqn_ids, const std::vector< int > &global_var_ids) override
Constant (time- and solution-independent) contributions.
Definition ActiveStress.cpp:31
InputParameter(bool is_optional=false, bool is_array=false, bool is_number=true, double default_val=0.0)
Handles input parameters.
Definition Parameter.h:114