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,160 @@
|
|
|
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
|
+
Describes rheology models
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from dataclasses import dataclass
|
|
32
|
+
from typing import Any
|
|
33
|
+
|
|
34
|
+
import numpy as np
|
|
35
|
+
|
|
36
|
+
from physioblocks.computing import Expression, ModelComponent, Quantity, diff, mid_point
|
|
37
|
+
from physioblocks.registers import register_type
|
|
38
|
+
from physioblocks.simulation import Time
|
|
39
|
+
|
|
40
|
+
# Constant for the rheology model type id
|
|
41
|
+
RHEOLOGY_FIBER_ADDITIVE_TYPE_ID = "rheology_fiber_additive"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@register_type(RHEOLOGY_FIBER_ADDITIVE_TYPE_ID)
|
|
45
|
+
@dataclass
|
|
46
|
+
class RheologyFiberAdditiveModelComponent(ModelComponent):
|
|
47
|
+
r"""
|
|
48
|
+
Describes a Fiber Additive Rheology model implementation.
|
|
49
|
+
|
|
50
|
+
**Internal Equation:**
|
|
51
|
+
|
|
52
|
+
.. math::
|
|
53
|
+
|
|
54
|
+
\dot{e}_c + T_c - k_s \Bigl( \frac{y}{R_0}-e_c \Bigr) = 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
**Discretised:**
|
|
58
|
+
|
|
59
|
+
.. math::
|
|
60
|
+
|
|
61
|
+
\mu \frac{e_c^{n+1}-e_c^n}{\Delta t^n}
|
|
62
|
+
- k_s \Bigl( \frac{y^{n + \frac{1}{2}}}{R_0}-e_c^{n + \frac{1}{2}} \Bigr)
|
|
63
|
+
+ T_c^{{n + \frac{1}{2}}\sharp} = 0
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
fib_deform: Quantity[np.float64]
|
|
68
|
+
""":math:`e_c` the fiber deformation"""
|
|
69
|
+
|
|
70
|
+
disp: Quantity[np.float64]
|
|
71
|
+
""":math:`y` the displacement"""
|
|
72
|
+
|
|
73
|
+
active_tension_discr: Quantity[np.float64]
|
|
74
|
+
""":math:`T_c^{{n + \frac{1}{2}}\\sharp}` the active tension discretisation"""
|
|
75
|
+
|
|
76
|
+
radius: Quantity[np.float64]
|
|
77
|
+
""":math:`R_0` sphere initial radius"""
|
|
78
|
+
|
|
79
|
+
damping_parallel: Quantity[np.float64]
|
|
80
|
+
""":math:`\\mu` the damping parallel"""
|
|
81
|
+
|
|
82
|
+
series_stiffness: Quantity[np.float64]
|
|
83
|
+
""":math:`k_s` the series stiffness"""
|
|
84
|
+
|
|
85
|
+
time: Time
|
|
86
|
+
""":math:`t` the simulation time"""
|
|
87
|
+
|
|
88
|
+
def initialize(self) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Initialize model's radius inverse
|
|
91
|
+
"""
|
|
92
|
+
self._inv_radius = 1 / self.radius.current
|
|
93
|
+
|
|
94
|
+
def fib_deform_equation(self) -> Any:
|
|
95
|
+
"""
|
|
96
|
+
Compute the equation representing the fiber deformation.
|
|
97
|
+
|
|
98
|
+
:return: the relation value
|
|
99
|
+
:rtype: np.float64
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
disp_mid_pt = mid_point(self.disp)
|
|
103
|
+
fib_deform_mid_pt = mid_point(self.fib_deform)
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
self.active_tension_discr.new
|
|
107
|
+
+ (self.damping_parallel.current * self.time.inv_dt * diff(self.fib_deform))
|
|
108
|
+
- (
|
|
109
|
+
self.series_stiffness.current
|
|
110
|
+
* (disp_mid_pt * self._inv_radius - fib_deform_mid_pt)
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def dfib_deform_equation_dfib_deform(self) -> Any:
|
|
115
|
+
"""
|
|
116
|
+
Compute the equation partial derivative for ``fib_deform``
|
|
117
|
+
|
|
118
|
+
:return: the partial derivative value
|
|
119
|
+
:rtype: np.float64
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
self.damping_parallel.current * self.time.inv_dt
|
|
124
|
+
+ self.series_stiffness.current * 0.5
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def dfib_deform_equation_ddisp(self) -> np.float64:
|
|
128
|
+
"""
|
|
129
|
+
Compute the equation partial derivative for ``disp``
|
|
130
|
+
|
|
131
|
+
:return: the partial derivative value
|
|
132
|
+
:rtype: np.float64
|
|
133
|
+
"""
|
|
134
|
+
return -self.series_stiffness.current * self._inv_radius * 0.5
|
|
135
|
+
|
|
136
|
+
def dfib_deform_equation_dactive_tension_discr(self) -> Any:
|
|
137
|
+
"""
|
|
138
|
+
Compute the equation partial derivative for the ``active_tension_discr``
|
|
139
|
+
|
|
140
|
+
:return: the partial derivative value
|
|
141
|
+
:rtype: np.float64
|
|
142
|
+
"""
|
|
143
|
+
return 1.0
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# Define the expression of the equation of the model.
|
|
147
|
+
_fib_deform_equation_expr = Expression(
|
|
148
|
+
1,
|
|
149
|
+
RheologyFiberAdditiveModelComponent.fib_deform_equation,
|
|
150
|
+
{
|
|
151
|
+
"fib_deform": RheologyFiberAdditiveModelComponent.dfib_deform_equation_dfib_deform, # noqa: E501
|
|
152
|
+
"disp": RheologyFiberAdditiveModelComponent.dfib_deform_equation_ddisp,
|
|
153
|
+
"active_tension_discr": RheologyFiberAdditiveModelComponent.dfib_deform_equation_dactive_tension_discr, # noqa: E501
|
|
154
|
+
},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
RheologyFiberAdditiveModelComponent.declares_internal_expression(
|
|
158
|
+
"fib_deform",
|
|
159
|
+
_fib_deform_equation_expr,
|
|
160
|
+
)
|
|
@@ -0,0 +1,169 @@
|
|
|
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
|
+
Module describing a discretized Velocity Law Block.
|
|
29
|
+
|
|
30
|
+
It defines two residual giving a dynamics on the velocity and acceleration.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from dataclasses import dataclass
|
|
34
|
+
|
|
35
|
+
import numpy as np
|
|
36
|
+
from numpy.typing import NDArray
|
|
37
|
+
|
|
38
|
+
from physioblocks.computing import (
|
|
39
|
+
Expression,
|
|
40
|
+
ModelComponent,
|
|
41
|
+
Quantity,
|
|
42
|
+
diff,
|
|
43
|
+
mid_alpha,
|
|
44
|
+
mid_point,
|
|
45
|
+
)
|
|
46
|
+
from physioblocks.registers import register_type
|
|
47
|
+
from physioblocks.simulation import Time
|
|
48
|
+
|
|
49
|
+
# Constant for the velocity law hht type name
|
|
50
|
+
VELOCITY_LAW_HHT_TYPE_ID = "velocity_law_hht"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass
|
|
54
|
+
@register_type(VELOCITY_LAW_HHT_TYPE_ID)
|
|
55
|
+
class VelocityLawHHTModelComponent(ModelComponent):
|
|
56
|
+
r"""
|
|
57
|
+
Velocity law HHT quantities and equation definitions
|
|
58
|
+
|
|
59
|
+
Implement the extended version of the **HHT time integration scheme**.
|
|
60
|
+
Velocity and acceleration unknowns are introduced and solved for by
|
|
61
|
+
|
|
62
|
+
**Discretised Internal Equations:**
|
|
63
|
+
|
|
64
|
+
.. math::
|
|
65
|
+
|
|
66
|
+
\frac{\dot{y}^{n+1}-\dot{y}^n}{\Delta t^n}
|
|
67
|
+
- (\tfrac{1}{2}+\alpha)\, \ddot{y}^{n+1}
|
|
68
|
+
- (\tfrac{1}{2}-\alpha)\, \ddot{y}^n = 0
|
|
69
|
+
|
|
70
|
+
.. math::
|
|
71
|
+
|
|
72
|
+
\frac{y^{n+1}-y^n}{\Delta t^n}
|
|
73
|
+
- \dot{y}^{n + \frac{1}{2}}
|
|
74
|
+
- \frac{\alpha^2}{4}\Delta t^n\, (\ddot{y}^{n+1}-\ddot{y}^n) = 0
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
scheme_ts_hht: Quantity[np.float64]
|
|
78
|
+
""":math:`\\alpha` the time shift scheme"""
|
|
79
|
+
|
|
80
|
+
accel: Quantity[np.float64]
|
|
81
|
+
""":math:`\\ddot{y}` the acceleration"""
|
|
82
|
+
|
|
83
|
+
vel: Quantity[np.float64]
|
|
84
|
+
""":math:`\\dot{y}` the velocity"""
|
|
85
|
+
|
|
86
|
+
disp: Quantity[np.float64]
|
|
87
|
+
""":math:`y` the displacement"""
|
|
88
|
+
|
|
89
|
+
time: Time
|
|
90
|
+
""":math:`t` the time"""
|
|
91
|
+
|
|
92
|
+
def velocity_law_residual(self) -> NDArray[np.float64]:
|
|
93
|
+
"""
|
|
94
|
+
Compute the velocity law residual
|
|
95
|
+
|
|
96
|
+
:return: the residual value
|
|
97
|
+
:rtype: NDArray[np.float64]
|
|
98
|
+
"""
|
|
99
|
+
accel_mid_alpha = mid_alpha(self.accel, self.scheme_ts_hht.current)
|
|
100
|
+
vel_mid_point = mid_point(self.vel)
|
|
101
|
+
|
|
102
|
+
return np.array(
|
|
103
|
+
[
|
|
104
|
+
(self.time.inv_dt * diff(self.vel) - accel_mid_alpha),
|
|
105
|
+
(
|
|
106
|
+
self.time.inv_dt * diff(self.disp)
|
|
107
|
+
- vel_mid_point
|
|
108
|
+
- np.power(self.scheme_ts_hht.current, 2)
|
|
109
|
+
* self.time.dt
|
|
110
|
+
/ 4.0
|
|
111
|
+
* diff(self.accel)
|
|
112
|
+
),
|
|
113
|
+
],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def velocity_law_residual_daccel(self) -> NDArray[np.float64]:
|
|
117
|
+
"""
|
|
118
|
+
Compute the velocity law residual partial derivative for ``accel``
|
|
119
|
+
|
|
120
|
+
:return: the partial derivative for accel
|
|
121
|
+
:rtype: NDArray[np.float64]
|
|
122
|
+
"""
|
|
123
|
+
return np.array(
|
|
124
|
+
[
|
|
125
|
+
-(0.5 + self.scheme_ts_hht.current),
|
|
126
|
+
-np.power(self.scheme_ts_hht.current, 2) * self.time.dt * 0.25,
|
|
127
|
+
],
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
def velocity_law_residual_dvel(self) -> NDArray[np.float64]:
|
|
131
|
+
"""
|
|
132
|
+
Compute the velocity law residual partial derivative for ``vel``
|
|
133
|
+
|
|
134
|
+
:return: the partial derivative for vel
|
|
135
|
+
:rtype: NDArray[np.float64]
|
|
136
|
+
"""
|
|
137
|
+
return np.array(
|
|
138
|
+
[self.time.inv_dt, -0.5],
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def velocity_law_residual_ddisp(self) -> NDArray[np.float64]:
|
|
142
|
+
"""
|
|
143
|
+
Compute the velocity law residual partial derivative for ``disp``
|
|
144
|
+
|
|
145
|
+
:return: the partial derivative for disp
|
|
146
|
+
:rtype: NDArray[np.float64]
|
|
147
|
+
"""
|
|
148
|
+
return np.array(
|
|
149
|
+
[0.0, self.time.inv_dt],
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# Define the residual expression of the velocity law and its partial derivatives
|
|
154
|
+
_velocity_law_hht_expression = Expression(
|
|
155
|
+
2,
|
|
156
|
+
VelocityLawHHTModelComponent.velocity_law_residual,
|
|
157
|
+
{
|
|
158
|
+
"accel": VelocityLawHHTModelComponent.velocity_law_residual_daccel,
|
|
159
|
+
"vel": VelocityLawHHTModelComponent.velocity_law_residual_dvel,
|
|
160
|
+
"disp": VelocityLawHHTModelComponent.velocity_law_residual_ddisp,
|
|
161
|
+
},
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
VelocityLawHHTModelComponent.declares_internal_expression(
|
|
165
|
+
"vel", _velocity_law_hht_expression, 1, 0
|
|
166
|
+
)
|
|
167
|
+
VelocityLawHHTModelComponent.declares_internal_expression(
|
|
168
|
+
"accel", _velocity_law_hht_expression, 1, 1
|
|
169
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "circulation_alone_forward_simulation",
|
|
3
|
+
"time": {
|
|
4
|
+
"start": 0.0,
|
|
5
|
+
"duration": 25.0
|
|
6
|
+
},
|
|
7
|
+
"variables_initialization": {
|
|
8
|
+
"aorta_proximal.blood_pressure": 10760.0,
|
|
9
|
+
"aorta_distal.blood_pressure": 10760.0
|
|
10
|
+
},
|
|
11
|
+
"parameters": {
|
|
12
|
+
"heart_rate": 60.0, // in beats / min
|
|
13
|
+
"aorta_proximal.resistance": 7.0e6,
|
|
14
|
+
"aorta_distal.resistance": 1.1e8,
|
|
15
|
+
"aorta_distal.time_constant": 2.0,
|
|
16
|
+
"venous.blood_pressure": 1600.0,
|
|
17
|
+
"aorta_proximal.blood_flow.min": 0.0,
|
|
18
|
+
"aorta_proximal.blood_flow.max": 0.5e-3
|
|
19
|
+
|
|
20
|
+
},
|
|
21
|
+
"output_functions":{
|
|
22
|
+
"aorta_proximal.blood_flow": {"type": "watch_quantity", "quantity": "aorta_proximal.blood_flow"}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "spherical_heart_with_respiration_forward_simulation",
|
|
3
|
+
"time": {
|
|
4
|
+
"start": 0.0,
|
|
5
|
+
"duration": 25.0
|
|
6
|
+
},
|
|
7
|
+
"variables_initialization": {
|
|
8
|
+
"cavity.blood_pressure": "atrial.blood_pressure.max", // Initialization with an open atrial valve
|
|
9
|
+
"aorta_proximal.blood_pressure": 10760.0,
|
|
10
|
+
"aorta_distal.blood_pressure": 10760.0
|
|
11
|
+
},
|
|
12
|
+
"parameters": {
|
|
13
|
+
"heart_radius": 0.0340, // in m
|
|
14
|
+
"heart_thickness": 0.0113, // in m
|
|
15
|
+
"heart_contractility": 90000.0,
|
|
16
|
+
"heart_rate": 60.0, // in beats / min
|
|
17
|
+
"respiration.period": 5.0, // in seconds
|
|
18
|
+
"venous.blood_pressure": 1600.0,
|
|
19
|
+
"atrial.blood_pressure.min": 450.0,
|
|
20
|
+
"atrial.blood_pressure.max": 900.0,
|
|
21
|
+
"pleural.pressure.min": 0.0,
|
|
22
|
+
"pleural.pressure.max": 300.0,
|
|
23
|
+
"circulation_aorta_proximal.resistance": 7.0e6,
|
|
24
|
+
"circulation_aorta_distal.resistance": 1.1e8,
|
|
25
|
+
"circulation_aorta_distal.time_constant": 2.0,
|
|
26
|
+
"cavity.dynamics.hyperelastic_cst": [444.0, 2.9, 69.0, 6.5]
|
|
27
|
+
},
|
|
28
|
+
"output_functions": {
|
|
29
|
+
"atrial.blood_pressure": {"type": "watch_quantity", "quantity": "atrial.blood_pressure"},
|
|
30
|
+
"active_law.activation": {"type": "watch_quantity", "quantity": "cavity.rheology.active_law.activation"},
|
|
31
|
+
"pleural.pressure": {"type": "watch_quantity", "quantity": "pleural.pressure"}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "spherical_heart_forward_simulation",
|
|
3
|
+
"time": {
|
|
4
|
+
"start": 0.0,
|
|
5
|
+
"duration": 25.0
|
|
6
|
+
},
|
|
7
|
+
"variables_initialization": {
|
|
8
|
+
"cavity.blood_pressure": "atrial.blood_pressure.max", // Initialization with an open atrial valve
|
|
9
|
+
"aorta_proximal.blood_pressure": 10760.0,
|
|
10
|
+
"aorta_distal.blood_pressure": 10760.0
|
|
11
|
+
},
|
|
12
|
+
"parameters": {
|
|
13
|
+
"heart_radius": 0.0340,
|
|
14
|
+
"heart_thickness": 0.0113,
|
|
15
|
+
"heart_contractility": 90000.0,
|
|
16
|
+
"heart_rate": 60.0, // in beats / min
|
|
17
|
+
"venous.blood_pressure": 1600.0,
|
|
18
|
+
"atrial.blood_pressure.min": 450.0,
|
|
19
|
+
"atrial.blood_pressure.max": 900.0,
|
|
20
|
+
"circulation_aorta_proximal.resistance": 7.0e6,
|
|
21
|
+
"circulation_aorta_distal.resistance": 1.1e8,
|
|
22
|
+
"circulation_aorta_distal.time_constant": 2.0,
|
|
23
|
+
"cavity.dynamics.hyperelastic_cst": [444.0, 2.9, 69.0, 6.5]
|
|
24
|
+
},
|
|
25
|
+
"output_functions": {
|
|
26
|
+
"atrial.blood_pressure": {"type": "watch_quantity", "quantity": "atrial.blood_pressure"},
|
|
27
|
+
"active_law.activation": {"type": "watch_quantity", "quantity": "cavity.rheology.active_law.activation"}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
Defines functions to access registers
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
__all__ = ["register_type"]
|
|
32
|
+
from physioblocks.registers.type_register import register_type
|
|
@@ -0,0 +1,93 @@
|
|
|
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 decorators to register any function as a specific load function
|
|
29
|
+
of a configuration object.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from collections.abc import Callable
|
|
33
|
+
from typing import Any, TypeVar
|
|
34
|
+
|
|
35
|
+
from physioblocks.base.registers import register
|
|
36
|
+
|
|
37
|
+
__load_functions_register: dict[type, Callable[..., Any]] = {}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
T = TypeVar("T")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def loads(
|
|
44
|
+
loaded_type: type[T],
|
|
45
|
+
) -> Callable[[Callable[..., T]], Callable[..., T]]:
|
|
46
|
+
"""
|
|
47
|
+
Decorator to register a method that loads a registered type.
|
|
48
|
+
|
|
49
|
+
:param loaded_type: the loaded type
|
|
50
|
+
:type loaded_type: str
|
|
51
|
+
|
|
52
|
+
:return: the class decorator
|
|
53
|
+
:rtype: Callable
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def register_decorator(load_function: Callable[..., T]) -> Callable[..., T]:
|
|
57
|
+
register(__load_functions_register, loaded_type, load_function)
|
|
58
|
+
return load_function
|
|
59
|
+
|
|
60
|
+
return register_decorator
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_load_function(loaded_type: type) -> Callable[..., Any]:
|
|
64
|
+
"""
|
|
65
|
+
Get a registered load function.
|
|
66
|
+
|
|
67
|
+
:param type_id: the registered type id
|
|
68
|
+
:type type_id: str
|
|
69
|
+
|
|
70
|
+
:raise KeyError: Raises a key error if the type is not registered.
|
|
71
|
+
|
|
72
|
+
:return: the registered type
|
|
73
|
+
:rtype: type
|
|
74
|
+
"""
|
|
75
|
+
key_type = _get_closest_type(loaded_type)
|
|
76
|
+
|
|
77
|
+
if key_type is None:
|
|
78
|
+
raise KeyError(
|
|
79
|
+
str.format(
|
|
80
|
+
"No load function registered for type {0}",
|
|
81
|
+
loaded_type.__name__,
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
return __load_functions_register[key_type]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _get_closest_type(searched_type: type | None) -> None | type:
|
|
88
|
+
if searched_type is None:
|
|
89
|
+
return None
|
|
90
|
+
elif searched_type in __load_functions_register:
|
|
91
|
+
return searched_type
|
|
92
|
+
else:
|
|
93
|
+
return _get_closest_type(searched_type.__base__)
|
|
@@ -0,0 +1,106 @@
|
|
|
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 decorators to register any function as a specific save function
|
|
29
|
+
of a configuration object.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from collections.abc import Callable
|
|
33
|
+
from typing import Any
|
|
34
|
+
|
|
35
|
+
from physioblocks.base.registers import register
|
|
36
|
+
|
|
37
|
+
__save_functions_register: dict[type, Callable[..., Any]] = {}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def saves(
|
|
41
|
+
saved_type: type,
|
|
42
|
+
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
43
|
+
"""
|
|
44
|
+
Decorator to register a method that saves a registered type.
|
|
45
|
+
|
|
46
|
+
:param saved_type: the saved type by the method
|
|
47
|
+
:type saved_type: str
|
|
48
|
+
|
|
49
|
+
:return: the class decorator
|
|
50
|
+
:rtype: Callable
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def register_decorator(
|
|
54
|
+
save_function: Callable[..., Any],
|
|
55
|
+
) -> Callable[..., Any]:
|
|
56
|
+
register(__save_functions_register, saved_type, save_function)
|
|
57
|
+
return save_function
|
|
58
|
+
|
|
59
|
+
return register_decorator
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def has_save_function(key: type) -> bool:
|
|
63
|
+
"""
|
|
64
|
+
Check if the type has a save function
|
|
65
|
+
|
|
66
|
+
:param key: the key to test
|
|
67
|
+
:type key: Any
|
|
68
|
+
|
|
69
|
+
:return: True if the key is registered, False otherwise
|
|
70
|
+
:rtype: bool
|
|
71
|
+
"""
|
|
72
|
+
key_type = _get_closest_type(key)
|
|
73
|
+
return key_type in __save_functions_register
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_save_function(saved_type: type) -> Callable[..., Any]:
|
|
77
|
+
"""
|
|
78
|
+
Get a registered save function.
|
|
79
|
+
|
|
80
|
+
:param type_id: the registered type id
|
|
81
|
+
:type type_id: str
|
|
82
|
+
|
|
83
|
+
:raise KeyError: Raises a key error if the type is not registered.
|
|
84
|
+
|
|
85
|
+
:return: the registered type
|
|
86
|
+
:rtype: type
|
|
87
|
+
"""
|
|
88
|
+
key_type = _get_closest_type(saved_type)
|
|
89
|
+
|
|
90
|
+
if key_type is None:
|
|
91
|
+
raise KeyError(
|
|
92
|
+
str.format(
|
|
93
|
+
"No save function registered for type {0}",
|
|
94
|
+
saved_type.__name__,
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
return __save_functions_register[key_type]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _get_closest_type(searched_type: type | None) -> None | type:
|
|
101
|
+
if searched_type is None:
|
|
102
|
+
return None
|
|
103
|
+
elif searched_type in __save_functions_register:
|
|
104
|
+
return searched_type
|
|
105
|
+
else:
|
|
106
|
+
return _get_closest_type(searched_type.__base__)
|