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