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