svZeroDSolver
Loading...
Searching...
No Matches
Model.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 * @file Model.h
5 * @brief model::Model source file
6 */
7
8#ifndef SVZERODSOLVER_MODEL_MODEL_HPP_
9#define SVZERODSOLVER_MODEL_MODEL_HPP_
10
11#include <algorithm>
12#include <list>
13#include <map>
14#include <memory>
15#include <string>
16#include <vector>
17
18#include "Block.h"
19#include "BlockFactory.h"
20#include "BloodVessel.h"
21#include "BloodVesselCRL.h"
22#include "BloodVesselJunction.h"
24#include "ChamberSphere.h"
28#include "ClosedLoopRCRBC.h"
29#include "DOFHandler.h"
30#include "FlowReferenceBC.h"
31#include "Junction.h"
33#include "Node.h"
34#include "OpenLoopCoronaryBC.h"
36#include "Parameter.h"
37#include "PiecewiseValve.h"
38#include "PressureReferenceBC.h"
39#include "ResistanceBC.h"
40#include "ResistiveJunction.h"
41#include "State.h"
42#include "ValveTanh.h"
43#include "WindkesselBC.h"
44#include "debug.h"
45
46/**
47 * @brief Model of 0D elements
48 *
49 * This class represents a full 0D model. It contains attributes and
50 * methods to store and modify 0D elements.
51 *
52 */
53class Model {
54 public:
55 /// Factory that holds all implemented blocks
56 std::map<std::string_view, BlockFactoryFunc> block_factory_map;
57
58 /**
59 * @brief Construct a new Model object
60 *
61 */
62 Model();
63
64 /**
65 * @brief Destroy the Model object
66 *
67 */
68 ~Model();
69
70 DOFHandler dofhandler; ///< Degree-of-freedom handler of the model
71
72 double cardiac_cycle_period = -1.0; ///< Cardiac cycle period
73 double time = 0.0; ///< Current time
74
75 /**
76 * @brief Create a new block
77 *
78 * @param block_name The block name (defined in block_factory_map)
79 * @return int Global ID of the block
80 */
81 Block* create_block(const std::string& block_name);
82
83 /**
84 * @brief Add a block to the model (without parameters)
85 *
86 * @param block The block to add
87 * @param name The name of the block
88 * @param block_param_ids Global IDs of the parameters of the block
89 * @param internal Toggle whether block is internal
90 * @return int Global ID of the block
91 */
92 int add_block(Block* block, const std::string_view& name,
93 const std::vector<int>& block_param_ids, bool internal = false);
94
95 /**
96 * @brief Add a block to the model (with parameters)
97 *
98 * @param block_name Type of the block
99 * @param block_param_ids Global IDs of the parameters of the block
100 * @param name The name of the block
101 * @param internal Toggle whether block is internal
102 * @return int Global ID of the block
103 */
104 int add_block(const std::string& block_name,
105 const std::vector<int>& block_param_ids,
106 const std::string_view& name, bool internal = false);
107
108 /**
109 * @brief Check if a block with given name exists
110 *
111 * @param name Name of the Block
112 * @return bool whether block exists
113 */
114 bool has_block(const std::string& name) const;
115
116 /**
117 * @brief Get a block by its name
118 *
119 * @param name Name of the Block
120 * @return Block* The block
121 */
122 Block* get_block(const std::string_view& name) const;
123
124 /**
125 * @brief Get a block by its global ID
126 *
127 * @param block_id Global ID of the Block
128 * @return Block* The block
129 */
130 Block* get_block(int block_id) const;
131
132 /**
133 * @brief Get a block type by its name
134 *
135 * @param name The name of the block
136 * @return BlockType The block type
137 */
138 BlockType get_block_type(const std::string_view& name) const;
139
140 /**
141 * @brief Get the name of a block by it's ID
142 *
143 * @param block_id Global ID of the block
144 * @return std::string Name of the block
145 */
146 std::string get_block_name(int block_id) const;
147
148 /**
149 * @brief Add a node to the model
150 *
151 * @param inlet_eles Inlet blocks of the node
152 * @param outlet_eles Outlet blocks of the node
153 * @param name Name of node
154 * @return int Global ID of the node
155 */
156 int add_node(const std::vector<Block*>& inlet_eles,
157 const std::vector<Block*>& outlet_eles,
158 const std::string_view& name);
159
160 /**
161 * @brief Get the name of a node by it's ID
162 *
163 * @param node_id Global ID of the node
164 * @return std::string Name of the node
165 */
166 std::string get_node_name(int node_id) const;
167
168 /**
169 * @brief Add a constant model parameter
170 *
171 * @param value Value of the parameter
172 * @return int Global ID of the parameter
173 */
174 int add_parameter(double value);
175
176 /**
177 * @brief Add a time-dependent model parameter
178 *
179 * @param times Times corresponding to the parameter values
180 * @param values Values of the parameter
181 * @param periodic Toggle whether parameter is periodic
182 * @return int Global ID of the parameter
183 */
184 int add_parameter(const std::vector<double>& times,
185 const std::vector<double>& values, bool periodic = true);
186
187 /**
188 * @brief Get a parameter by its global ID
189 *
190 * @param param_id Global ID of the parameter
191 * @return Parameter* The parameter
192 */
193 Parameter* get_parameter(int param_id);
194
195 /**
196 * @brief Get the current value of a parameter
197 *
198 * @param param_id Global ID of the parameter
199 * @return T Current value of the parameter
200 */
201 double get_parameter_value(int param_id) const;
202
203 /**
204 * @brief Update the current value of a parameter in the `parameter_values`
205 * vector. Note that this is different from updating the value within each
206 * parameter object, which is done in Parameter::update()
207 *
208 * @param param_id Global ID of the parameter
209 * @param param_value The new parameter value
210 */
211 void update_parameter_value(int param_id, double param_value);
212
213 /**
214 * @brief Finalize the model after all blocks, nodes and parameters have been
215 * added
216 *
217 */
218 void finalize();
219
220 /**
221 * @brief Update the constant contributions of all elements in a sparse system
222 *
223 * @param system System to update contributions at
224 */
225 void update_constant(SparseSystem& system);
226
227 /**
228 * @brief Update the time-dependent contributions of all elements in a sparse
229 * system
230 *
231 * @param system System to update contributions at
232 * @param time Current time
233 */
234 void update_time(SparseSystem& system, double time);
235
236 /**
237 * @brief Update the solution-dependent contributions of all elements in a
238 * sparse system
239 *
240 * @param system System to update contributions at
241 * @param y Current solution
242 * @param dy Current derivate of the solution
243 */
244 void update_solution(SparseSystem& system,
245 Eigen::Matrix<double, Eigen::Dynamic, 1>& y,
246 Eigen::Matrix<double, Eigen::Dynamic, 1>& dy);
247
248 /**
249 * @brief Modify the solution after solving it
250 *
251 * @param y Current solution
252 */
253 void post_solve(Eigen::Matrix<double, Eigen::Dynamic, 1>& y);
254
255 /**
256 * @brief Convert the blocks to a steady behavior
257 *
258 */
259 void to_steady();
260
261 /**
262 * @brief Convert the blocks to an unsteady behavior
263 *
264 */
265 void to_unsteady();
266
267 /**
268 * @brief Get number of triplets all elements
269 *
270 * Get the number of triplets the elements contribute to the global system
271 * (relevant for sparse memory reservation)
272 *
273 * @return Number of triplets that are used in each system matrix
274 */
275 // std::map<std::string, int> get_num_triplets();
277
278 /**
279 * @brief Get the number of blocks in the model
280 *
281 * @param internal Toggle whether to return internal/hidden blocks
282 *
283 * @return int Number of blocks
284 */
285 int get_num_blocks(bool internal = false) const;
286
287 /**
288 * @brief Specify if model has at least one Windkessel boundary condition
289 *
290 * @param has_windkessel Toggle if model has at least one Windkessel boundary
291 * condition
292 */
293 void update_has_windkessel_bc(bool has_windkessel);
294
295 /**
296 * @brief Update model with largest time constant among all Windkessel
297 * boundary conditions present in model
298 *
299 * @param time_constant Largest Windkessel time constant
300 */
301 void update_largest_windkessel_time_constant(double time_constant);
302
303 /**
304 * @brief Check if model has at least one Windkessel boundary condition
305 *
306 * @return bool True if model has at least one Windkessel boundary condition
307 */
309
310 /**
311 * @brief Get largest Windkessel time constant in model
312 *
313 * @return double Largest Windkessel time constant of model
314 */
316 /**
317 * @brief Setup model parameters that depend on the initial state
318 *
319 * @param initial_state The initial state vector
320 */
322
323 private:
324 int block_count = 0;
325 int node_count = 0;
326 int parameter_count = 0;
327 std::map<int, double> param_value_cache;
328
329 std::vector<std::shared_ptr<Block>> blocks; ///< Blocks of the model
330 std::vector<BlockType> block_types; ///< Types of the blocks
331 std::vector<std::string> block_names; ///< Names of the blocks
332 std::map<std::string, int>
333 block_index_map; ///< Map between block name and index
334
335 std::vector<std::shared_ptr<Block>>
336 hidden_blocks; ///< Hidden blocks of the model
337
338 std::vector<std::shared_ptr<Node>> nodes; ///< Nodes of the model
339 std::vector<std::string> node_names; ///< Names of the nodes
340
341 std::vector<Parameter>
342 parameters; ///< Parameters of the model. This vector stores the
343 ///< parameter objects and is primarily used to update
344 ///< `parameter_values` at each time-step for time-dependent
345 ///< parameters and also for steady initial conditions.
346 std::vector<double>
347 parameter_values; ///< Current values of the parameters. This is passed
348 ///< to blocks to set up the linear system in
349 ///< `update_constant`, `update_time` and
350 ///< `update_solution`.
351
352 bool has_windkessel_bc = false;
353 double largest_windkessel_time_constant = 0.0;
354};
355
356#endif // SVZERODSOLVER_MODEL_MODEL_HPP_
model::Block source file
Define the block factory functional.
BlockType
The types of blocks supported by the solver.
Definition BlockType.h:15
model::BloodVessel source file
model::BloodVesselCRL source file
model::BloodVesselJunction source file
model::ChamberElastanceInductor source file
model::ChamberSphere source file
Left side of ClosedLoopCoronaryBC.
Right side of ClosedLoopCoronaryBC.
model::ClosedLoopHeartPulmonary source file
model::ClosedLoopRCRBC source file
model::DOFHandler source file
model::FlowReferenceBC source file
model::Junction source file
model::LinearElastanceChamber source file
model::Node source file
model::OpenLoopCoronaryBC source file
model::OpenLoopCoronaryVarResBC source file
model::Parameter source file
model::PiecewiseValve source file
model::PressureReferenceBC source file
model::ResistanceBC source file
model::ResistiveJunction source file
State source file.
model::ValveTanh source file
model::WindkesselBC source file
Base class for 0D model components.
Definition Block.h:76
Degree-of-freedom handler.
Definition DOFHandler.h:21
int add_node(const std::vector< Block * > &inlet_eles, const std::vector< Block * > &outlet_eles, const std::string_view &name)
Add a node to the model.
Definition Model.cpp:120
void finalize()
Finalize the model after all blocks, nodes and parameters have been added.
Definition Model.cpp:168
void update_parameter_value(int param_id, double param_value)
Update the current value of a parameter in the parameter_values vector. Note that this is different f...
Definition Model.cpp:164
double get_parameter_value(int param_id) const
Get the current value of a parameter.
Definition Model.cpp:160
void update_largest_windkessel_time_constant(double time_constant)
Update model with largest time constant among all Windkessel boundary conditions present in model.
Definition Model.cpp:278
void setup_initial_state_dependent_parameters(State initial_state)
Setup model parameters that depend on the initial state.
Definition Model.cpp:266
void update_time(SparseSystem &system, double time)
Update the time-dependent contributions of all elements in a sparse system.
Definition Model.cpp:199
std::string get_node_name(int node_id) const
Get the name of a node by it's ID.
Definition Model.cpp:132
void update_constant(SparseSystem &system)
Update the constant contributions of all elements in a sparse system.
Definition Model.cpp:193
BlockType get_block_type(const std::string_view &name) const
Get a block type by its name.
Definition Model.cpp:106
double get_largest_windkessel_time_constant()
Get largest Windkessel time constant in model.
Definition Model.cpp:284
void update_has_windkessel_bc(bool has_windkessel)
Specify if model has at least one Windkessel boundary condition.
Definition Model.cpp:274
int add_block(Block *block, const std::string_view &name, const std::vector< int > &block_param_ids, bool internal=false)
Add a block to the model (without parameters).
Definition Model.cpp:50
void to_unsteady()
Convert the blocks to an unsteady behavior.
Definition Model.cpp:243
int add_parameter(double value)
Add a constant model parameter.
Definition Model.cpp:136
double cardiac_cycle_period
Cardiac cycle period.
Definition Model.h:72
Block * get_block(const std::string_view &name) const
Get a block by its name.
Definition Model.cpp:88
void post_solve(Eigen::Matrix< double, Eigen::Dynamic, 1 > &y)
Modify the solution after solving it.
Definition Model.cpp:219
TripletsContributions get_num_triplets() const
Get number of triplets all elements.
Definition Model.cpp:256
bool has_block(const std::string &name) const
Check if a block with given name exists.
Definition Model.cpp:80
double time
Current time.
Definition Model.h:73
void to_steady()
Convert the blocks to a steady behavior.
Definition Model.cpp:225
Block * create_block(const std::string &block_name)
Create a new block.
Definition Model.cpp:40
~Model()
Destroy the Model object.
Definition Model.cpp:38
Model()
Construct a new Model object.
Definition Model.cpp:12
void update_solution(SparseSystem &system, Eigen::Matrix< double, Eigen::Dynamic, 1 > &y, Eigen::Matrix< double, Eigen::Dynamic, 1 > &dy)
Update the solution-dependent contributions of all elements in a sparse system.
Definition Model.cpp:211
std::map< std::string_view, BlockFactoryFunc > block_factory_map
Factory that holds all implemented blocks.
Definition Model.h:56
std::string get_block_name(int block_id) const
Get the name of a block by it's ID.
Definition Model.cpp:116
int get_num_blocks(bool internal=false) const
Get the number of blocks in the model.
Definition Model.cpp:183
Parameter * get_parameter(int param_id)
Get a parameter by its global ID.
Definition Model.cpp:158
bool get_has_windkessel_bc()
Check if model has at least one Windkessel boundary condition.
Definition Model.cpp:282
DOFHandler dofhandler
Degree-of-freedom handler of the model.
Definition Model.h:70
Model Parameter.
Definition Parameter.h:25
Sparse system.
Definition SparseSystem.h:30
State of the system.
Definition State.h:19
DEBUG_MSG source file.
The number of triplets that the element contributes to the global system.
Definition Block.h:27