physioblocks 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- physioblocks/__init__.py +37 -0
- physioblocks/base/__init__.py +27 -0
- physioblocks/base/operators.py +176 -0
- physioblocks/base/registers.py +108 -0
- physioblocks/computing/__init__.py +47 -0
- physioblocks/computing/assembling.py +291 -0
- physioblocks/computing/models.py +811 -0
- physioblocks/computing/quantities.py +354 -0
- physioblocks/configuration/__init__.py +38 -0
- physioblocks/configuration/aliases.py +203 -0
- physioblocks/configuration/base.py +123 -0
- physioblocks/configuration/computing/__init__.py +27 -0
- physioblocks/configuration/computing/quantities.py +56 -0
- physioblocks/configuration/constants.py +121 -0
- physioblocks/configuration/description/__init__.py +33 -0
- physioblocks/configuration/description/blocks.py +239 -0
- physioblocks/configuration/description/nets.py +155 -0
- physioblocks/configuration/functions.py +695 -0
- physioblocks/configuration/simulation/__init__.py +32 -0
- physioblocks/configuration/simulation/simulations.py +280 -0
- physioblocks/description/__init__.py +34 -0
- physioblocks/description/blocks.py +418 -0
- physioblocks/description/flux.py +157 -0
- physioblocks/description/nets.py +746 -0
- physioblocks/io/__init__.py +29 -0
- physioblocks/io/aliases.py +73 -0
- physioblocks/io/configuration.py +125 -0
- physioblocks/launcher/__main__.py +285 -0
- physioblocks/launcher/configuration.py +231 -0
- physioblocks/launcher/configure/__main__.py +99 -0
- physioblocks/launcher/constants.py +105 -0
- physioblocks/launcher/files.py +150 -0
- physioblocks/launcher/series.py +165 -0
- physioblocks/library/__init__.py +27 -0
- physioblocks/library/aliases/blocks/c_block.json +5 -0
- physioblocks/library/aliases/blocks/rc_block.json +5 -0
- physioblocks/library/aliases/blocks/rcr_block.json +5 -0
- physioblocks/library/aliases/blocks/spherical_cavity_block.json +5 -0
- physioblocks/library/aliases/blocks/valve_rl_block.json +5 -0
- physioblocks/library/aliases/flux/heart_flux_dof_couples.jsonc +4 -0
- physioblocks/library/aliases/model_components/active_law_macro_huxley_two_moments.json +5 -0
- physioblocks/library/aliases/model_components/rheology_fiber_additive.json +5 -0
- physioblocks/library/aliases/model_components/spherical_dynamics.json +5 -0
- physioblocks/library/aliases/model_components/velocity_law_hht.json +5 -0
- physioblocks/library/aliases/nets/circulation_alone_net.json +31 -0
- physioblocks/library/aliases/nets/spherical_heart_net.json +93 -0
- physioblocks/library/aliases/simulations/circulation_alone_forward_simulation.jsonc +55 -0
- physioblocks/library/aliases/simulations/default_forward_simulation.jsonc +7 -0
- physioblocks/library/aliases/simulations/default_time.jsonc +8 -0
- physioblocks/library/aliases/simulations/newton_method_solver.json +5 -0
- physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc +157 -0
- physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc +45 -0
- physioblocks/library/blocks/__init__.py +27 -0
- physioblocks/library/blocks/capacitances.py +516 -0
- physioblocks/library/blocks/cavity.py +192 -0
- physioblocks/library/blocks/valves.py +281 -0
- physioblocks/library/functions/__init__.py +27 -0
- physioblocks/library/functions/base_operations.py +129 -0
- physioblocks/library/functions/first_order.py +113 -0
- physioblocks/library/functions/piecewise.py +271 -0
- physioblocks/library/functions/trigonometric.py +78 -0
- physioblocks/library/functions/watchers.py +113 -0
- physioblocks/library/model_components/__init__.py +27 -0
- physioblocks/library/model_components/active_law.py +345 -0
- physioblocks/library/model_components/dynamics.py +986 -0
- physioblocks/library/model_components/rheology.py +160 -0
- physioblocks/library/model_components/velocity_law.py +169 -0
- physioblocks/references/circulation_alone_sim.jsonc +24 -0
- physioblocks/references/spherical_heart_respiration_sim.jsonc +33 -0
- physioblocks/references/spherical_heart_sim.jsonc +29 -0
- physioblocks/registers/__init__.py +32 -0
- physioblocks/registers/load_function_register.py +93 -0
- physioblocks/registers/save_function_register.py +106 -0
- physioblocks/registers/type_register.py +97 -0
- physioblocks/simulation/__init__.py +48 -0
- physioblocks/simulation/constants.py +30 -0
- physioblocks/simulation/functions.py +71 -0
- physioblocks/simulation/runtime.py +484 -0
- physioblocks/simulation/saved_quantities.py +129 -0
- physioblocks/simulation/setup.py +576 -0
- physioblocks/simulation/solvers.py +235 -0
- physioblocks/simulation/state.py +340 -0
- physioblocks/simulation/time_manager.py +354 -0
- physioblocks/utils/__init__.py +27 -0
- physioblocks/utils/dynamic_import_utils.py +150 -0
- physioblocks/utils/exceptions_utils.py +115 -0
- physioblocks/utils/gradient_test_utils.py +337 -0
- physioblocks/utils/math_utils.py +109 -0
- physioblocks-1.0.0.dist-info/METADATA +127 -0
- physioblocks-1.0.0.dist-info/RECORD +93 -0
- physioblocks-1.0.0.dist-info/WHEEL +4 -0
- physioblocks-1.0.0.dist-info/licenses/licenses/GPL-3.0-only.txt +674 -0
- physioblocks-1.0.0.dist-info/licenses/licenses/LGPL-3.0-only.txt +165 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright INRIA
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: LGPL-3.0-only
|
|
4
|
+
#
|
|
5
|
+
# Copyright INRIA
|
|
6
|
+
#
|
|
7
|
+
# This file is part of PhysioBlocks, a library mostly developed by the
|
|
8
|
+
# [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
|
|
9
|
+
#
|
|
10
|
+
# Authors:
|
|
11
|
+
# - Colin Drieu
|
|
12
|
+
# - Dominique Chapelle
|
|
13
|
+
# - François Kimmig
|
|
14
|
+
# - Philippe Moireau
|
|
15
|
+
#
|
|
16
|
+
# PhysioBlocks is free software: you can redistribute it and/or modify it under the
|
|
17
|
+
# terms of the GNU Lesser General Public License as published by the Free Software
|
|
18
|
+
# Foundation, version 3 of the License.
|
|
19
|
+
#
|
|
20
|
+
# PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
21
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
22
|
+
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
23
|
+
#
|
|
24
|
+
# You should have received a copy of the GNU Lesser General Public License along with
|
|
25
|
+
# PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
Define functions to perform gradient tests to check the coherence between an
|
|
29
|
+
function and its gradient.
|
|
30
|
+
|
|
31
|
+
The gradient test principle is to compare the result of a **computed** and estimated
|
|
32
|
+
gradient from a :class:`~physioblocks.computing.assembling.EqSystem` object.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from __future__ import annotations
|
|
36
|
+
|
|
37
|
+
import logging
|
|
38
|
+
from os import linesep
|
|
39
|
+
from typing import Any
|
|
40
|
+
|
|
41
|
+
import numpy as np
|
|
42
|
+
from numpy.typing import NDArray
|
|
43
|
+
from scipy.optimize import approx_fprime
|
|
44
|
+
|
|
45
|
+
import physioblocks.simulation.setup as setup
|
|
46
|
+
from physioblocks.computing.assembling import EqSystem
|
|
47
|
+
from physioblocks.computing.models import Block, Expression, ModelComponent
|
|
48
|
+
from physioblocks.configuration.aliases import unwrap_aliases
|
|
49
|
+
from physioblocks.configuration.functions import load
|
|
50
|
+
from physioblocks.io.configuration import read_json
|
|
51
|
+
from physioblocks.simulation.runtime import AbstractSimulation
|
|
52
|
+
from physioblocks.simulation.state import State
|
|
53
|
+
|
|
54
|
+
_logger = logging.getLogger(__name__)
|
|
55
|
+
|
|
56
|
+
_ZERO = 1e-16
|
|
57
|
+
_REL_TOL = 1e-6
|
|
58
|
+
_NEW_STATE_SHIFT_FACTOR = 1e-3
|
|
59
|
+
_SHIFT_FACTOR = 1e-4
|
|
60
|
+
_CONVERGENCE_FACTOR = 0.1
|
|
61
|
+
_CONVERGENCE_TOL = 0.11
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def gradient_test_from_file(config_file_path: str) -> bool:
|
|
65
|
+
"""
|
|
66
|
+
Read the given configuration file and perform a gradient test on the full Net
|
|
67
|
+
with the provided parameters and variables.
|
|
68
|
+
|
|
69
|
+
.. warning::
|
|
70
|
+
|
|
71
|
+
Every type (especially **Blocks**, **ModelComponents** and **Functions**) and
|
|
72
|
+
alias used in the configuration file have to be loaded.
|
|
73
|
+
Follow this
|
|
74
|
+
:ref:`user guide section <user_guide_level_3_block_test_dynamic_import>`
|
|
75
|
+
to import libraries and aliases dynamically.
|
|
76
|
+
|
|
77
|
+
:param config_file_path: the file path to the simulation configuration file.
|
|
78
|
+
:type config_file_path: str
|
|
79
|
+
|
|
80
|
+
:return: True if the gradient test is successfull, false otherwise.
|
|
81
|
+
"""
|
|
82
|
+
configuration = read_json(config_file_path)
|
|
83
|
+
configuration = unwrap_aliases(configuration)
|
|
84
|
+
sim: AbstractSimulation = load(configuration)
|
|
85
|
+
sim._initialize() # noqa SLF001
|
|
86
|
+
return gradient_test(
|
|
87
|
+
sim.eq_system,
|
|
88
|
+
sim.state,
|
|
89
|
+
sim.solver._get_state_magnitude(sim.state, sim.magnitudes), # noqa: SLF001
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def gradient_test_from_model(
|
|
94
|
+
model: ModelComponent, state: State, state_magnitude: NDArray[np.float64]
|
|
95
|
+
) -> bool:
|
|
96
|
+
"""
|
|
97
|
+
Create an equation system for the given block only and perform a gradient test.
|
|
98
|
+
|
|
99
|
+
.. note::
|
|
100
|
+
|
|
101
|
+
It does not test the submodels of the model.
|
|
102
|
+
|
|
103
|
+
:param model: the model to test.
|
|
104
|
+
:type model: str
|
|
105
|
+
|
|
106
|
+
:param state: the state used to determine the variables in the model.
|
|
107
|
+
:type state: str
|
|
108
|
+
|
|
109
|
+
:param state_magnitude: the state variables magnitudes
|
|
110
|
+
:type state_magnitude: str
|
|
111
|
+
|
|
112
|
+
:return: True if the gradient test is successfull, false otherwise.
|
|
113
|
+
"""
|
|
114
|
+
line_index = 0
|
|
115
|
+
expressions = setup.SystemExpressions()
|
|
116
|
+
for internal_expr_def in type(model).internal_expressions:
|
|
117
|
+
expressions.append((line_index, internal_expr_def.expression, model))
|
|
118
|
+
line_index += internal_expr_def.expression.size
|
|
119
|
+
|
|
120
|
+
if isinstance(model, Block):
|
|
121
|
+
for fluxes_expr_def in type(model).fluxes_expressions.values():
|
|
122
|
+
expressions.append((line_index, fluxes_expr_def.expression, model))
|
|
123
|
+
line_index += fluxes_expr_def.expression.size
|
|
124
|
+
|
|
125
|
+
eq_system = setup.build_eq_system(expressions, state)
|
|
126
|
+
model.initialize()
|
|
127
|
+
return gradient_test(eq_system, state, state_magnitude)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def gradient_test_from_expression(
|
|
131
|
+
expr: Expression,
|
|
132
|
+
expr_params: Any,
|
|
133
|
+
state: State,
|
|
134
|
+
state_magnitude: NDArray[np.float64],
|
|
135
|
+
) -> bool:
|
|
136
|
+
"""
|
|
137
|
+
Create an equation system for the given expression only and perform a gradient test.
|
|
138
|
+
|
|
139
|
+
:param expr: the expression to test.
|
|
140
|
+
:type expr: Expression
|
|
141
|
+
|
|
142
|
+
:param expr_params: the parameters to pass to the expression
|
|
143
|
+
:type expr_params: Any
|
|
144
|
+
|
|
145
|
+
:param state: the state used to determine the variables in the expression.
|
|
146
|
+
:type state: str
|
|
147
|
+
|
|
148
|
+
:param state_magnitude: the state variables magnitudes
|
|
149
|
+
:type state_magnitude: str
|
|
150
|
+
|
|
151
|
+
:return: True if the gradient test is successfull, false otherwise.
|
|
152
|
+
:rtype: bool
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
eq_system = setup.build_eq_system([(0, expr, expr_params)], state)
|
|
156
|
+
return gradient_test(eq_system, state, state_magnitude)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def gradient_test(
|
|
160
|
+
eq_system: EqSystem, state: State, state_magnitude: NDArray[np.float64]
|
|
161
|
+
) -> bool:
|
|
162
|
+
"""
|
|
163
|
+
Test the computed gradient for the equation system by comparing it to
|
|
164
|
+
a gradient estimated with finite differences.
|
|
165
|
+
|
|
166
|
+
:param eq_system: the equation system providing method to compute a residual and a
|
|
167
|
+
gradient
|
|
168
|
+
:type eq_system: EqSystem
|
|
169
|
+
|
|
170
|
+
:param state: system state
|
|
171
|
+
:type state: State
|
|
172
|
+
|
|
173
|
+
:param state_magnitude: the state variables magnitudes
|
|
174
|
+
:type state_magnitude: str
|
|
175
|
+
|
|
176
|
+
:return: True if the estimated and computed gradient meet tolerance,
|
|
177
|
+
False otherwise.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
_logger.info(str.format("State:{0}{1}", linesep, state))
|
|
181
|
+
_logger.info(str.format("System:{0}{1}", linesep, eq_system))
|
|
182
|
+
|
|
183
|
+
new_state = state.state_vector + _NEW_STATE_SHIFT_FACTOR * state_magnitude
|
|
184
|
+
|
|
185
|
+
shift_1 = _SHIFT_FACTOR * state_magnitude
|
|
186
|
+
state.update_state_vector(new_state)
|
|
187
|
+
|
|
188
|
+
res = eq_system.compute_residual()
|
|
189
|
+
grad = eq_system.compute_gradient()
|
|
190
|
+
|
|
191
|
+
grad_estimated_1 = _estimate_gradient(eq_system, shift_1, state)
|
|
192
|
+
|
|
193
|
+
shift_2 = _CONVERGENCE_FACTOR * shift_1
|
|
194
|
+
state.update_state_vector(new_state)
|
|
195
|
+
grad_estimated_2 = _estimate_gradient(eq_system, shift_2, state)
|
|
196
|
+
|
|
197
|
+
state.update_state_vector(new_state)
|
|
198
|
+
|
|
199
|
+
with np.printoptions(precision=9, linewidth=10000, suppress=True):
|
|
200
|
+
_logger.debug(str.format("Residual:{0}{1}", linesep, res))
|
|
201
|
+
_logger.debug(str.format("Gradient{0}{1}", linesep, grad))
|
|
202
|
+
_logger.debug(
|
|
203
|
+
str.format("Gradient Estimated:{0}{1}", linesep, grad_estimated_1)
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
grad_error_pos = get_errors_gradient(grad, grad_estimated_1, grad_estimated_2)
|
|
207
|
+
|
|
208
|
+
error_message = str.format("State:{0}{1}", linesep, state)
|
|
209
|
+
error_message += str.format("System:{0}{1}{0}{0}", linesep, eq_system)
|
|
210
|
+
|
|
211
|
+
for line_error, col_error in grad_error_pos:
|
|
212
|
+
error_msg_line = str.format(
|
|
213
|
+
"Error in gradient at ({0},{1}).{2}", line_error, col_error, linesep
|
|
214
|
+
)
|
|
215
|
+
_logger.debug(error_msg_line)
|
|
216
|
+
error_message += error_msg_line
|
|
217
|
+
|
|
218
|
+
error_msg_line = str.format(
|
|
219
|
+
"Variable Id: {0}.{1}", state.get_variable_id(col_error), linesep
|
|
220
|
+
)
|
|
221
|
+
_logger.debug(error_msg_line)
|
|
222
|
+
|
|
223
|
+
error_msg_line = str.format("Residual Index: {0}.{1}{1}", line_error, linesep)
|
|
224
|
+
_logger.debug(error_msg_line)
|
|
225
|
+
|
|
226
|
+
if len(grad_error_pos) != 0:
|
|
227
|
+
raise GradientError(error_message)
|
|
228
|
+
|
|
229
|
+
return len(grad_error_pos) == 0
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _estimate_gradient(
|
|
233
|
+
eq_system: EqSystem, shift: NDArray[np.float64], state: State
|
|
234
|
+
) -> NDArray[np.float64]:
|
|
235
|
+
"""
|
|
236
|
+
Gradient finite difference estimation
|
|
237
|
+
|
|
238
|
+
:param eq_system: the equation system providing method to compute a residual
|
|
239
|
+
and a gradient
|
|
240
|
+
:type eq_system: EqSystem
|
|
241
|
+
|
|
242
|
+
:param shift_factor: the shift factor to apply on the state (can be 0).
|
|
243
|
+
It is multiplied with the variables magnitude then added to the state.
|
|
244
|
+
:type shift_factor: NDArray
|
|
245
|
+
|
|
246
|
+
:param state: system state
|
|
247
|
+
:type state: State
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
def residual(x: NDArray[np.float64]) -> NDArray[np.float64]:
|
|
251
|
+
state.update_state_vector(x)
|
|
252
|
+
res = eq_system.compute_residual()
|
|
253
|
+
|
|
254
|
+
return res
|
|
255
|
+
|
|
256
|
+
x0 = state.state_vector
|
|
257
|
+
grad_est = np.atleast_2d(approx_fprime(x0, residual, shift))
|
|
258
|
+
|
|
259
|
+
return grad_est
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def get_errors_gradient(
|
|
263
|
+
computed: NDArray[np.float64],
|
|
264
|
+
estimated_1: NDArray[np.float64],
|
|
265
|
+
estimated_2: NDArray[np.float64],
|
|
266
|
+
) -> list[tuple[int, int]]:
|
|
267
|
+
"""
|
|
268
|
+
Get the ``(line, column)`` positions of the errors in the gradient matrix.
|
|
269
|
+
|
|
270
|
+
:param computed: computed gradient
|
|
271
|
+
:type computed: NDArray[np.float64]
|
|
272
|
+
|
|
273
|
+
:param estimated_1: first gradient estimate
|
|
274
|
+
:type estimated_1: NDArray[np.float64]
|
|
275
|
+
|
|
276
|
+
:param estimated_2: second gradient estimate
|
|
277
|
+
:type estimated_2: NDArray[np.float64]
|
|
278
|
+
|
|
279
|
+
:return: the position of the errors in the gradient matrix
|
|
280
|
+
:rtype: list[tuple[int, int]]
|
|
281
|
+
"""
|
|
282
|
+
abs_computed = np.abs(computed)
|
|
283
|
+
|
|
284
|
+
error_1 = np.empty(computed.shape)
|
|
285
|
+
error_1[:] = np.inf
|
|
286
|
+
error_2 = error_1.copy()
|
|
287
|
+
|
|
288
|
+
for grad_line in range(0, computed.shape[0]):
|
|
289
|
+
for grad_col in range(0, computed.shape[1]):
|
|
290
|
+
if abs_computed[grad_line, grad_col] < _ZERO:
|
|
291
|
+
error_1[grad_line, grad_col] = (
|
|
292
|
+
np.abs(
|
|
293
|
+
computed[grad_line, grad_col] - estimated_1[grad_line, grad_col]
|
|
294
|
+
)
|
|
295
|
+
/ _ZERO
|
|
296
|
+
)
|
|
297
|
+
error_2[grad_line, grad_col] = (
|
|
298
|
+
np.abs(
|
|
299
|
+
computed[grad_line, grad_col] - estimated_2[grad_line, grad_col]
|
|
300
|
+
)
|
|
301
|
+
/ _ZERO
|
|
302
|
+
)
|
|
303
|
+
else:
|
|
304
|
+
error_1[grad_line, grad_col] = (
|
|
305
|
+
np.abs(
|
|
306
|
+
computed[grad_line, grad_col] - estimated_1[grad_line, grad_col]
|
|
307
|
+
)
|
|
308
|
+
/ abs_computed[grad_line, grad_col]
|
|
309
|
+
)
|
|
310
|
+
error_2[grad_line, grad_col] = (
|
|
311
|
+
np.abs(
|
|
312
|
+
computed[grad_line, grad_col] - estimated_2[grad_line, grad_col]
|
|
313
|
+
)
|
|
314
|
+
/ abs_computed[grad_line, grad_col]
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
with np.printoptions(precision=9, linewidth=10000, suppress=False):
|
|
318
|
+
_logger.debug(str.format("Error:{0}{1}", error_1, linesep))
|
|
319
|
+
|
|
320
|
+
error_positions = []
|
|
321
|
+
|
|
322
|
+
for grad_line in range(0, computed.shape[0]):
|
|
323
|
+
for grad_col in range(0, computed.shape[1]):
|
|
324
|
+
if error_1[grad_line, grad_col] > _REL_TOL:
|
|
325
|
+
err_div = error_2[grad_line, grad_col] / error_1[grad_line, grad_col]
|
|
326
|
+
if err_div > _CONVERGENCE_TOL:
|
|
327
|
+
error_positions.append((grad_line, grad_col))
|
|
328
|
+
elif np.isnan(error_1[grad_line, grad_col]):
|
|
329
|
+
error_positions.append((grad_line, grad_col))
|
|
330
|
+
|
|
331
|
+
return error_positions
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
class GradientError(Exception):
|
|
335
|
+
"""Error raised when the estimated and computed gradients do not match."""
|
|
336
|
+
|
|
337
|
+
pass
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright INRIA
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: LGPL-3.0-only
|
|
4
|
+
#
|
|
5
|
+
# Copyright INRIA
|
|
6
|
+
#
|
|
7
|
+
# This file is part of PhysioBlocks, a library mostly developed by the
|
|
8
|
+
# [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
|
|
9
|
+
#
|
|
10
|
+
# Authors:
|
|
11
|
+
# - Colin Drieu
|
|
12
|
+
# - Dominique Chapelle
|
|
13
|
+
# - François Kimmig
|
|
14
|
+
# - Philippe Moireau
|
|
15
|
+
#
|
|
16
|
+
# PhysioBlocks is free software: you can redistribute it and/or modify it under the
|
|
17
|
+
# terms of the GNU Lesser General Public License as published by the Free Software
|
|
18
|
+
# Foundation, version 3 of the License.
|
|
19
|
+
#
|
|
20
|
+
# PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
21
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
22
|
+
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
23
|
+
#
|
|
24
|
+
# You should have received a copy of the GNU Lesser General Public License along with
|
|
25
|
+
# PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
|
|
26
|
+
|
|
27
|
+
"""Defines some math functions to help compute quantities"""
|
|
28
|
+
|
|
29
|
+
from typing import Any
|
|
30
|
+
|
|
31
|
+
import numpy as np
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def exp_diff(a: float, b: float, diff: float) -> Any:
|
|
35
|
+
"""
|
|
36
|
+
Computes exponential differences with more numerical accuracy when a and b are close
|
|
37
|
+
using the relationship:
|
|
38
|
+
|
|
39
|
+
.. math::
|
|
40
|
+
|
|
41
|
+
e^a - e^b = 2\\ e^{\\frac{a + b}{2}}\\ \\text{sinh}(\\frac{a + b}{2})
|
|
42
|
+
|
|
43
|
+
:param a: value of a
|
|
44
|
+
:type a: np.float64
|
|
45
|
+
|
|
46
|
+
:param b: value of b
|
|
47
|
+
:type b: np.float64
|
|
48
|
+
|
|
49
|
+
:param diff: value of a - b
|
|
50
|
+
:type diff: np.float64
|
|
51
|
+
|
|
52
|
+
:return: exponential difference value
|
|
53
|
+
:rtype: np.float64
|
|
54
|
+
"""
|
|
55
|
+
return np.exp(0.5 * (a + b)) * 2.0 * np.sinh(0.5 * diff)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def power_diff(a: float, b: float, diff: float, n: int) -> Any:
|
|
59
|
+
"""
|
|
60
|
+
Computes the a and b power n difference with more numerical accuracy when a and
|
|
61
|
+
b are close by using the following relationship:
|
|
62
|
+
|
|
63
|
+
.. math::
|
|
64
|
+
|
|
65
|
+
a^n - b^n = (a-b) * \\sum_{i = 0}^{n -1}{a^i b^{n-1-i}}
|
|
66
|
+
|
|
67
|
+
When n is negative, the following transformation is used:
|
|
68
|
+
|
|
69
|
+
.. math::
|
|
70
|
+
|
|
71
|
+
\\frac{1}{a^n} - \\frac{1}{b^n} = -\\frac{a^n-b^n}{{ab}^n}
|
|
72
|
+
|
|
73
|
+
:param a: value of a
|
|
74
|
+
:type a: np.float64
|
|
75
|
+
|
|
76
|
+
:param b: value of b
|
|
77
|
+
:type b: np.float64
|
|
78
|
+
|
|
79
|
+
:param diff: value of a - b
|
|
80
|
+
:type diff: np.float64
|
|
81
|
+
|
|
82
|
+
:return: the a and b power n difference value
|
|
83
|
+
:rtype: np.float64
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
if n < 0:
|
|
87
|
+
return -power_diff(a, b, diff, -n) / np.pow(a * b, -n)
|
|
88
|
+
elif n > 0:
|
|
89
|
+
return diff * _power_dec(a, b, n - 1, 0)
|
|
90
|
+
else:
|
|
91
|
+
return 0.0
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _power_dec(a: float, b: float, n1: int, n2: int) -> Any:
|
|
95
|
+
"""
|
|
96
|
+
Helper recursive function used by :func:`power_diff` to compute the term:
|
|
97
|
+
|
|
98
|
+
.. math::
|
|
99
|
+
|
|
100
|
+
\\sum_{i = 0}^{n -1}{a^i b^{n-1-i}}
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
if n1 != 0 or n2 != 0:
|
|
104
|
+
if n1 != 0:
|
|
105
|
+
return np.pow(a, n1) * np.pow(b, n2) + _power_dec(a, b, n1 - 1, n2 + 1)
|
|
106
|
+
else:
|
|
107
|
+
return np.pow(b, n2)
|
|
108
|
+
|
|
109
|
+
return 1.0
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: physioblocks
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Dynamic: Author
|
|
5
|
+
Dynamic: Author-email
|
|
6
|
+
Dynamic: License
|
|
7
|
+
Dynamic: License-Expression
|
|
8
|
+
Summary: Physioblocks allows the simulation of dynamical models of physiological systems
|
|
9
|
+
Project-URL: Homepage, https://github.com/physioblocks/physioblocks
|
|
10
|
+
Project-URL: Documentation, https://physioblocks.gitlabpages.inria.fr/physioblocks/
|
|
11
|
+
Project-URL: Issues, https://github.com/physioblocks/physioblocks/issues
|
|
12
|
+
Project-URL: Discussions, https://github.com/physioblocks/physioblocks/discussions
|
|
13
|
+
License-File: licenses/GPL-3.0-only.txt
|
|
14
|
+
License-File: licenses/LGPL-3.0-only.txt
|
|
15
|
+
Keywords: block diagram,cardiovascular modeling,dynamical systems,physiology
|
|
16
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
17
|
+
Classifier: Intended Audience :: Science/Research
|
|
18
|
+
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
26
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
27
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Requires-Dist: numpy
|
|
30
|
+
Requires-Dist: pandas
|
|
31
|
+
Requires-Dist: plotly
|
|
32
|
+
Requires-Dist: pyarrow
|
|
33
|
+
Requires-Dist: regex
|
|
34
|
+
Requires-Dist: scipy
|
|
35
|
+
Provides-Extra: doc
|
|
36
|
+
Requires-Dist: sphinx; extra == 'doc'
|
|
37
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'doc'
|
|
38
|
+
Requires-Dist: sphinxcontrib-tikz; extra == 'doc'
|
|
39
|
+
Provides-Extra: quality
|
|
40
|
+
Requires-Dist: mypy; extra == 'quality'
|
|
41
|
+
Requires-Dist: ruff; extra == 'quality'
|
|
42
|
+
Provides-Extra: test
|
|
43
|
+
Requires-Dist: coverage; extra == 'test'
|
|
44
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
45
|
+
Provides-Extra: tox
|
|
46
|
+
Requires-Dist: tox>=4; extra == 'tox'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# PhysioBlocks
|
|
50
|
+
|
|
51
|
+
PhysioBlocks allows the simulation of dynamical models of physiological systems.
|
|
52
|
+
|
|
53
|
+
## User Levels
|
|
54
|
+
|
|
55
|
+
They are several use cases for PhysioBlocks depending on the user profile:
|
|
56
|
+
|
|
57
|
+
* __Level 1:__ Configure and run physiological systems simulation (for pre-existing systems)
|
|
58
|
+
* __Level 2:__ Create new systems with existing blocks without writing code
|
|
59
|
+
* __Level 3:__ Write and add new blocks to the library.
|
|
60
|
+
|
|
61
|
+
## Principle
|
|
62
|
+
|
|
63
|
+
* A __Net__ (system) is built from __Nodes__ and __Blocks__ connected by those nodes.
|
|
64
|
+
* At each node in the net, connected blocks share __Degrees of Freedom__ (ex: pressure) and send __Fluxes__ that verify Kirchhoff Law.
|
|
65
|
+
* __ModelComponents__ concatenate blocks equations to the global system (if necessary, for modularity purposes within the block)
|
|
66
|
+
|
|
67
|
+
## Interactions
|
|
68
|
+
|
|
69
|
+
__Level 1:__ Configure and run a simulation : JSON
|
|
70
|
+
* Update the model parameters
|
|
71
|
+
|
|
72
|
+
__Level 2:__ Create Nets : JSON
|
|
73
|
+
* Declare the nodes, the blocks, and the block - nodes connections
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
__Level 3:__ Write and add models to the library: Python
|
|
77
|
+
* Declare the quantities to use in the model
|
|
78
|
+
* Write the fluxes and equations
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
Here are the links to the sections of the [full documentation](https://physioblocks.gitlabpages.inria.fr/physioblocks/):
|
|
83
|
+
* [Installation](https://physioblocks.gitlabpages.inria.fr/physioblocks/installation.html)
|
|
84
|
+
* [User Guide](https://physioblocks.gitlabpages.inria.fr/physioblocks/user_guide.html)
|
|
85
|
+
* [Library](https://physioblocks.gitlabpages.inria.fr/physioblocks/library.html)
|
|
86
|
+
* [API Reference](https://physioblocks.gitlabpages.inria.fr/physioblocks/api_reference.html)
|
|
87
|
+
|
|
88
|
+
## Quick start
|
|
89
|
+
|
|
90
|
+
Complete instructions are available in the [documentation](https://physioblocks.gitlabpages.inria.fr/physioblocks/). This instructions will enable you to launch a reference simulation.
|
|
91
|
+
|
|
92
|
+
### Installation
|
|
93
|
+
|
|
94
|
+
This project requires a recent version of python installed.
|
|
95
|
+
Then:
|
|
96
|
+
```
|
|
97
|
+
pip install physioblocks
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Configuration
|
|
101
|
+
|
|
102
|
+
To configure PhysioBlocks Launcher:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
# Create an empty folder where you want to store simulations results.
|
|
106
|
+
mkdir $LAUNCHER_FOLDER_PATH$
|
|
107
|
+
|
|
108
|
+
# Configure the folder
|
|
109
|
+
python -m physioblocks.launcher.configure -d $LAUNCHER_FOLDER_PATH$ -v
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Launch a simulation
|
|
113
|
+
|
|
114
|
+
With a Launcher folder configured:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
# Move to your configured launcher folder
|
|
118
|
+
cd $LAUNCHER_FOLDER_PATH$
|
|
119
|
+
|
|
120
|
+
# Launch a reference simulation
|
|
121
|
+
python -m physioblocks.launcher references/spherical_heart_sim.jsonc -v -t -s QuickStart
|
|
122
|
+
|
|
123
|
+
# This can take some time.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
Results will be available in the `$LAUNCHER_FOLDER_PATH$/simulations/QuickStart` series folder.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
physioblocks/__init__.py,sha256=0ZHZb8nU30moO0pf0Z2UarcVWvhTPtI878IkQcpSDpc,1169
|
|
2
|
+
physioblocks/base/__init__.py,sha256=2h6bk0fe8pwQvJ15Buytg4SZzYOH-Ep7WqoD6pd1eOQ,986
|
|
3
|
+
physioblocks/base/operators.py,sha256=uUfswQZsaMNd2bd7wsaxSGFIYLAr1hQCQ6SQfYawdBc,5689
|
|
4
|
+
physioblocks/base/registers.py,sha256=Cd0hmy1XqojjPQgb_jn4mGeAMTyWWgDkl3qJHCVjCRU,3119
|
|
5
|
+
physioblocks/computing/__init__.py,sha256=rLjuzRCA0nVAnHcYsL0jhn2KQpl6MnC3DJLf3a0i6uw,1302
|
|
6
|
+
physioblocks/computing/assembling.py,sha256=2pKNA85PWJJ4fwSPRi7IitMdjlYTTiWQIgnKyhHja-8,9308
|
|
7
|
+
physioblocks/computing/models.py,sha256=2V5Xbsoy3jK_OcubTKxmTUa7nKBag0x-T4Zivcul7So,24489
|
|
8
|
+
physioblocks/computing/quantities.py,sha256=f2wU0VDylJ8nuUtOsV0FsA1mJnqNy1AvoK6-w04Fctc,8934
|
|
9
|
+
physioblocks/configuration/__init__.py,sha256=XNeIev97Fc9DAy_mA3CAZ0kMif7Nkop9sCI38ZZ2wgM,1454
|
|
10
|
+
physioblocks/configuration/aliases.py,sha256=o7E54IYeW0NfmCX_r3zLKURVHsQoCmTlLD5085kY0eg,6302
|
|
11
|
+
physioblocks/configuration/base.py,sha256=eLxZXZdc4QkSsA7TOA0-E5ckfMZZkdgPJ6JVrFwM4nY,3627
|
|
12
|
+
physioblocks/configuration/constants.py,sha256=JsXGcoxHXgaixpIIiYZDPNiKSeD7Y_4YswVm0Uaf-Hs,3056
|
|
13
|
+
physioblocks/configuration/functions.py,sha256=pJl5BkSwRoIydH3bSMNilu0wj7yOVJ_BVAPNS-yMl8k,23520
|
|
14
|
+
physioblocks/configuration/computing/__init__.py,sha256=duNJXdaHTZ9_V9XScNXjJgPsKSc6FbHGrwNDLrcYDg8,1012
|
|
15
|
+
physioblocks/configuration/computing/quantities.py,sha256=fM5L4YeeM1NQQjhbdU4e50yxZ9B2ogF0WzDIYqFDbgg,1721
|
|
16
|
+
physioblocks/configuration/description/__init__.py,sha256=-KyjKPheXzgKiVZ0jL-nl8H-uN9cYjXJkX6XL6q9oVg,1169
|
|
17
|
+
physioblocks/configuration/description/blocks.py,sha256=FGYFR5S15jGlZnIIfvZLdMr33bXabXMi9Vj9jETLeeM,8003
|
|
18
|
+
physioblocks/configuration/description/nets.py,sha256=wKAH1Qq_tQ65-bn17qV6c_n0dt__PtY9r8TnYtZsPTY,5124
|
|
19
|
+
physioblocks/configuration/simulation/__init__.py,sha256=RuRdBDvwqBcyghwh1D0ud3qwdUEcw2vgHPoB8drXp6w,1126
|
|
20
|
+
physioblocks/configuration/simulation/simulations.py,sha256=4W-pcSDIMBKRFYjkkHOePrcZfXiFdfCHdyI_qpFSZ_c,8795
|
|
21
|
+
physioblocks/description/__init__.py,sha256=o6G4LgLuSKSXOF6Uex-nua-8MyWsiwBd_G4dQLJsA6Y,1200
|
|
22
|
+
physioblocks/description/blocks.py,sha256=y0qLvdE4VBmdDmOeHFaRFsmPRg-7_JVSGs2thAAUzHc,13542
|
|
23
|
+
physioblocks/description/flux.py,sha256=aKs31bO1KyfAlHhmWUP9ZS7V7SryyVe_6MZG_Sp9jCQ,4858
|
|
24
|
+
physioblocks/description/nets.py,sha256=pKG2uB-4dABc-lvGswkybiho18bOkUwsVJYBdlX7p5s,23604
|
|
25
|
+
physioblocks/io/__init__.py,sha256=bOGWA0hAifT9wHxD4kWFQuAXpAx0GzDmGfmcgNDUCGo,990
|
|
26
|
+
physioblocks/io/aliases.py,sha256=d_Gqz0-8SVD6tA9N-T9xYL8SRhaSMmIOjqvOKHBb-Yo,2288
|
|
27
|
+
physioblocks/io/configuration.py,sha256=UY8whA_7KcMwi_gXPIt5h8_gD7TKO2Co5cyf9MHO0yg,3578
|
|
28
|
+
physioblocks/launcher/__main__.py,sha256=pLTJzaMZGN7elr8aAvgkjYOhnp6fbGouH5SWq_5bKIg,8811
|
|
29
|
+
physioblocks/launcher/configuration.py,sha256=dqHCR_7PSDInA8NC3NFONqK3PPwSQYpLkZgYSyVU1vs,7959
|
|
30
|
+
physioblocks/launcher/constants.py,sha256=FIBKde1vJrUzMk9dSl4q8f8jqN7bFxYF05EIG2-V0zw,3033
|
|
31
|
+
physioblocks/launcher/files.py,sha256=zvif_8Woh3vEYCb_K3YnFFZYpgMhdlf4c2OSIVW4jC4,4950
|
|
32
|
+
physioblocks/launcher/series.py,sha256=x2XazVzVT6Co8Nco92jdO8XlsjgCxFHkxGQZ5RSl4Ik,5048
|
|
33
|
+
physioblocks/launcher/configure/__main__.py,sha256=4RPUtUSBV2DlJeHmOf0fqRFAdud3Tx12M-nKQ3epRGc,2955
|
|
34
|
+
physioblocks/library/__init__.py,sha256=Yilh0uLw1Ac7xe9aLqCg-DFYQobzZJMk9B64cAuCUKk,1026
|
|
35
|
+
physioblocks/library/aliases/blocks/c_block.json,sha256=-63XyPEv7xhvMoHIF9ShLIz8jqDRWkOyRAyfF4VpIFY,84
|
|
36
|
+
physioblocks/library/aliases/blocks/rc_block.json,sha256=OesNIQadZainjoU7O0gXy2Tnd8LWoYsS6JM0XiwRacc,85
|
|
37
|
+
physioblocks/library/aliases/blocks/rcr_block.json,sha256=u9ILSfzn29y84jGX-CnNFQkoPloE6YDc4rtHWTsUplM,86
|
|
38
|
+
physioblocks/library/aliases/blocks/spherical_cavity_block.json,sha256=_cWeg4kHL2Cm9t6em3eoMUIZov04XgysRq3R6ZduSQM,99
|
|
39
|
+
physioblocks/library/aliases/blocks/valve_rl_block.json,sha256=cuNCgx88JkP7FfNH6mHHCxRB-jt8d3PySbkVGzIuLXQ,91
|
|
40
|
+
physioblocks/library/aliases/flux/heart_flux_dof_couples.jsonc,sha256=P09q70D-qIoj6l2IcwN3LQaPqZ8sJ_m7Fm2sf9H00Uw,83
|
|
41
|
+
physioblocks/library/aliases/model_components/active_law_macro_huxley_two_moments.json,sha256=Pw4ZupAKIDukUXCAXZ3ERNF7RoEzNtgUC-umuqGDnIw,112
|
|
42
|
+
physioblocks/library/aliases/model_components/rheology_fiber_additive.json,sha256=dw0zC8UFjIjNsNdl9l6P1nWQ0lRBe3QmYZ8vXCEkbZE,100
|
|
43
|
+
physioblocks/library/aliases/model_components/spherical_dynamics.json,sha256=Tcd1t6JSVO-ty-gfksTUl_oXX_l1GuwBFuvH-fujLus,95
|
|
44
|
+
physioblocks/library/aliases/model_components/velocity_law_hht.json,sha256=HKbc5_2hGuOiQKUvLGto6tBQI_Z5AbbhXp8Itwmo2ag,93
|
|
45
|
+
physioblocks/library/aliases/nets/circulation_alone_net.json,sha256=M3TiXIXgaXCsdwfyA5cm3fqspViiIl0Kyb6NKMiFsQ8,874
|
|
46
|
+
physioblocks/library/aliases/nets/spherical_heart_net.json,sha256=UnOSQslMJuvbT6dXXPWj-HEvqe6U4fG1CK17_sKTxM8,3057
|
|
47
|
+
physioblocks/library/aliases/simulations/circulation_alone_forward_simulation.jsonc,sha256=0l4dKEvmY6-3NLB70B4zVF_OJs-bzgxAsesgr3KZ7P0,1983
|
|
48
|
+
physioblocks/library/aliases/simulations/default_forward_simulation.jsonc,sha256=TE_82KWUYAQdMX4MpDGY-Hi_djpwYAhSB5uzYtzYqcA,136
|
|
49
|
+
physioblocks/library/aliases/simulations/default_time.jsonc,sha256=LM2_EU-GvOeGXJMvXXyJeWEOv-cfy25luhcaSMj5hkw,165
|
|
50
|
+
physioblocks/library/aliases/simulations/newton_method_solver.json,sha256=p0jgVCpySTR0Npo5iFZrUUys3SRcy4j_EesQw9SvoyA,79
|
|
51
|
+
physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc,sha256=CXG5m8lRftbqYUchDedA_ggO81v1M0qiqyshRCMOl4E,5664
|
|
52
|
+
physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc,sha256=kCy065DN5Cau3d7ouuzdDAaLevBuzlnZkWtROG3DgtY,1542
|
|
53
|
+
physioblocks/library/blocks/__init__.py,sha256=EhnoyZYTooSd_cTfysnT-YR6Ylrn15dJsfWwALFV00I,991
|
|
54
|
+
physioblocks/library/blocks/capacitances.py,sha256=-coa-Zb4rVHwZVM2ip3iAHKURlQ9Mzw4Q34eCc-DHKc,14175
|
|
55
|
+
physioblocks/library/blocks/cavity.py,sha256=JODm84TYz0Zuji3QXHb-bhQZlM_QZh6lTluf_8c0GL8,6064
|
|
56
|
+
physioblocks/library/blocks/valves.py,sha256=jMo5ZaBIONaiG-e2y-5zRnayOq7YhsG44zL6mn900Ag,7747
|
|
57
|
+
physioblocks/library/functions/__init__.py,sha256=k9cFPqrsApbeSkcnu-FbhonilTTeJS0Cp5EJCrfPeII,988
|
|
58
|
+
physioblocks/library/functions/base_operations.py,sha256=TpN7rabrX9Nojd2uu90j1Dw_7OpdjbBSuiM_HWzJH3M,3507
|
|
59
|
+
physioblocks/library/functions/first_order.py,sha256=oSkFyECA7ywgQCYKt-sEZmSu84QrRere_Ee736vk2Ik,3687
|
|
60
|
+
physioblocks/library/functions/piecewise.py,sha256=xpR22eP0Jkfuskc737uttenbpOOMXEfrOAyconAg_-4,8401
|
|
61
|
+
physioblocks/library/functions/trigonometric.py,sha256=Y5UolXZTASEi4EH_GpLpUIxMZbXIVHc-THFEXg9vrtg,2126
|
|
62
|
+
physioblocks/library/functions/watchers.py,sha256=fY1SSPn-7R9cix0VMFP69H5-pmJzl4OXs1tgvjCetvM,3212
|
|
63
|
+
physioblocks/library/model_components/__init__.py,sha256=JcDL2PaPTrT9mTlDUbPjUsyFfsiGh5GgroJ7J3g2uwE,998
|
|
64
|
+
physioblocks/library/model_components/active_law.py,sha256=97D3fC7Dmzw8jLqDALxUJgl48EZYOx39SYjZgGJx-Eo,11634
|
|
65
|
+
physioblocks/library/model_components/dynamics.py,sha256=SZaOU2_EFMRlqvJvsW9NXLTviN8NBAhy_9z_0EErPb0,35282
|
|
66
|
+
physioblocks/library/model_components/rheology.py,sha256=7x5RrB_0DXMWlm0mIrTxdLlsjXVa1WPuFYYifW4fKeg,4724
|
|
67
|
+
physioblocks/library/model_components/velocity_law.py,sha256=UYr9MywlLkRw0LszK0u_AamwThjobDMV9jYbaSbdDkU,5047
|
|
68
|
+
physioblocks/registers/__init__.py,sha256=trxT3MHDFX8cJ-IBX2cEIm8-uZBnfs2UkV8QDclq9so,1081
|
|
69
|
+
physioblocks/registers/load_function_register.py,sha256=z2iXShQCJHwSUJFNv2hJ19CLVSX5zlc2caxFg9x4-WE,2626
|
|
70
|
+
physioblocks/registers/save_function_register.py,sha256=mOK486hKsX3dqi5P_KBnH5DE0_xl3Uzvik9xE4N-SIM,2943
|
|
71
|
+
physioblocks/registers/type_register.py,sha256=JUlrPfP-X_TjIOHewSTkzf7Ck3L0ivVoHOvHQkyRpBM,2577
|
|
72
|
+
physioblocks/simulation/__init__.py,sha256=wqKVI3OLLVWuQoUcWwKSs5ibdkTP3Da_5DOe36v1up4,1504
|
|
73
|
+
physioblocks/simulation/constants.py,sha256=w9CsB4V7YtvcdW4N1p7Iu6MeV4i-kazcEPAygE7mSx0,1075
|
|
74
|
+
physioblocks/simulation/functions.py,sha256=c6HFwXK8IAzH7gSkz9aMiXLqnWXn_4_9WsX4jrGN9pY,2307
|
|
75
|
+
physioblocks/simulation/runtime.py,sha256=xMtUL07SSQYpskK_EnNi-qz2D1d4wlDAESWHPqMUHn8,16762
|
|
76
|
+
physioblocks/simulation/saved_quantities.py,sha256=fKWr1wScqxHPhuCE7aDNs8lpm9oWfyLN8NZDus2knPM,4111
|
|
77
|
+
physioblocks/simulation/setup.py,sha256=UmIklaHmfkxi_BIdYKOhorLoC9QT9D4oEXwC-Xfd6v0,18109
|
|
78
|
+
physioblocks/simulation/solvers.py,sha256=IrLHrsLJhM97SYzeygz2-UkkNbpp2hsixCuUi0Nis98,7353
|
|
79
|
+
physioblocks/simulation/state.py,sha256=jE6fTxzsnGKch1H6mErunpi7lwTb_9fvs2Hx77LIaMA,10310
|
|
80
|
+
physioblocks/simulation/time_manager.py,sha256=AbP_Y8mcG7-6x-3rGY5CHFQwKMqksO4HvdCJ-mU03d4,9381
|
|
81
|
+
physioblocks/utils/__init__.py,sha256=EMwPHVznBryA1uOEFfY_11L9Sd9bdCU_x_huNgIaZtQ,988
|
|
82
|
+
physioblocks/utils/dynamic_import_utils.py,sha256=AvGFRYPQcI2JSVpScXCgnYJDgF2uh8QI7xBewoe_9Ks,4862
|
|
83
|
+
physioblocks/utils/exceptions_utils.py,sha256=2w2q1XP-UDnxCXFu4XI2k1-jLUub24oYuwdUfd6tOkE,3421
|
|
84
|
+
physioblocks/utils/gradient_test_utils.py,sha256=41FVSrjzOLWmxvaiZI258QbmnQOA7M2tBm-Vd2GsEuo,11208
|
|
85
|
+
physioblocks/utils/math_utils.py,sha256=w5MDs4cP5WiTPHe8WofFuNZZ20WDNLT0XmFGlbisJJ0,2881
|
|
86
|
+
physioblocks/references/circulation_alone_sim.jsonc,sha256=qv27nzmK7jennhtCJ7wQ_f83mt9_YJSOTABjGCYMcZw,736
|
|
87
|
+
physioblocks/references/spherical_heart_respiration_sim.jsonc,sha256=kKq5xf94r90O1KpkCHk1qwgy6DJ37ePo3-8buEtcu5Y,1397
|
|
88
|
+
physioblocks/references/spherical_heart_sim.jsonc,sha256=kGGBqxY8dnmGKmpMv216kbneyJRGz_3VkcYn1OWavIA,1151
|
|
89
|
+
physioblocks-1.0.0.dist-info/METADATA,sha256=FcgqHhXq-C2RQKkG6t8WzxJ3-MvEoOGNHs_r5VGC_b0,4558
|
|
90
|
+
physioblocks-1.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
91
|
+
physioblocks-1.0.0.dist-info/licenses/licenses/GPL-3.0-only.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
92
|
+
physioblocks-1.0.0.dist-info/licenses/licenses/LGPL-3.0-only.txt,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
93
|
+
physioblocks-1.0.0.dist-info/RECORD,,
|