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,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
|
+
Describe the configuration of the simulations objects
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# Import modules to access load / save functions
|
|
32
|
+
import physioblocks.configuration.simulation.simulations # noqa: F401
|
|
@@ -0,0 +1,280 @@
|
|
|
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 the configuration of simulations
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from collections.abc import Iterable
|
|
32
|
+
from os import linesep
|
|
33
|
+
from typing import Any
|
|
34
|
+
|
|
35
|
+
from physioblocks.configuration.base import Configuration, ConfigurationError
|
|
36
|
+
from physioblocks.configuration.constants import (
|
|
37
|
+
INIT_VARIABLES_ID,
|
|
38
|
+
MAGNITUDES,
|
|
39
|
+
NET_ID,
|
|
40
|
+
OUTPUTS_FUNCTIONS_ID,
|
|
41
|
+
PARAMETERS_ID,
|
|
42
|
+
SOLVER_ID,
|
|
43
|
+
TIME_MANAGER_ID,
|
|
44
|
+
VARIABLES_MAGNITUDES,
|
|
45
|
+
)
|
|
46
|
+
from physioblocks.configuration.functions import load, save
|
|
47
|
+
from physioblocks.registers.load_function_register import loads
|
|
48
|
+
from physioblocks.registers.save_function_register import saves
|
|
49
|
+
from physioblocks.registers.type_register import get_registered_type_id
|
|
50
|
+
from physioblocks.simulation import AbstractFunction
|
|
51
|
+
from physioblocks.simulation.functions import (
|
|
52
|
+
is_state_function,
|
|
53
|
+
is_time_function,
|
|
54
|
+
)
|
|
55
|
+
from physioblocks.simulation.runtime import AbstractSimulation
|
|
56
|
+
from physioblocks.simulation.setup import SimulationFactory
|
|
57
|
+
from physioblocks.simulation.state import STATE_NAME_ID
|
|
58
|
+
from physioblocks.simulation.time_manager import TIME_QUANTITY_ID
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@loads(AbstractSimulation) # type: ignore
|
|
62
|
+
def load_simulation_config(
|
|
63
|
+
config: Configuration,
|
|
64
|
+
configuration_type: type,
|
|
65
|
+
configuration_object: AbstractSimulation | None = None,
|
|
66
|
+
*args: Any,
|
|
67
|
+
**kwargs: Any,
|
|
68
|
+
) -> AbstractSimulation:
|
|
69
|
+
"""
|
|
70
|
+
Load a simulation from a configuration.
|
|
71
|
+
|
|
72
|
+
:param config: the configuration
|
|
73
|
+
:type config: Configuration
|
|
74
|
+
|
|
75
|
+
:return: the simulation
|
|
76
|
+
:rtype: AbstractSimulation
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
if configuration_object is None:
|
|
80
|
+
net = None
|
|
81
|
+
if NET_ID in config:
|
|
82
|
+
net = load(config[NET_ID])
|
|
83
|
+
|
|
84
|
+
# Solver
|
|
85
|
+
solver = None
|
|
86
|
+
if SOLVER_ID in config:
|
|
87
|
+
solver = load(config[SOLVER_ID])
|
|
88
|
+
|
|
89
|
+
# magnitudes
|
|
90
|
+
magnitudes = None
|
|
91
|
+
if VARIABLES_MAGNITUDES in config:
|
|
92
|
+
magnitudes = load(config[VARIABLES_MAGNITUDES])
|
|
93
|
+
|
|
94
|
+
sim_factory = SimulationFactory(
|
|
95
|
+
configuration_type,
|
|
96
|
+
solver,
|
|
97
|
+
net,
|
|
98
|
+
simulation_options={MAGNITUDES: magnitudes},
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
configuration_object = sim_factory.create_simulation()
|
|
102
|
+
|
|
103
|
+
_configure_simulation(config, configuration_object)
|
|
104
|
+
|
|
105
|
+
return configuration_object
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _save_sim_factory(factory: SimulationFactory) -> Configuration:
|
|
109
|
+
simulation_type_id = get_registered_type_id(factory.simulation_type)
|
|
110
|
+
sim_factory_config_item = Configuration(simulation_type_id)
|
|
111
|
+
sim_factory_config_item[NET_ID] = save(factory.net)
|
|
112
|
+
|
|
113
|
+
return sim_factory_config_item
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@saves(AbstractSimulation)
|
|
117
|
+
def save_simulation_config(
|
|
118
|
+
simulation: AbstractSimulation, *args: Any, **kwargs: Any
|
|
119
|
+
) -> Configuration:
|
|
120
|
+
"""
|
|
121
|
+
Save a simulation in a configuration.
|
|
122
|
+
|
|
123
|
+
:param sim: the simulation to save
|
|
124
|
+
:type sim: AbstractSimulation
|
|
125
|
+
|
|
126
|
+
:param simulation_type_id: the simulation type id
|
|
127
|
+
:type simulation_type_id: str
|
|
128
|
+
|
|
129
|
+
:return: the configuration
|
|
130
|
+
:rtype: Configuration
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
sim_config = _save_sim_factory(simulation.factory)
|
|
134
|
+
|
|
135
|
+
sim_config[TIME_MANAGER_ID] = save(simulation.time_manager)
|
|
136
|
+
sim_config[SOLVER_ID] = save(simulation.solver)
|
|
137
|
+
|
|
138
|
+
# State
|
|
139
|
+
variable_init_values = save(simulation.state.variables)
|
|
140
|
+
if isinstance(variable_init_values, dict):
|
|
141
|
+
sim_config[INIT_VARIABLES_ID] = variable_init_values
|
|
142
|
+
else:
|
|
143
|
+
raise ConfigurationError(
|
|
144
|
+
str.format(
|
|
145
|
+
"Expected a dict for {0} configuration, got {1}.",
|
|
146
|
+
INIT_VARIABLES_ID,
|
|
147
|
+
type(variable_init_values).__name__,
|
|
148
|
+
)
|
|
149
|
+
)
|
|
150
|
+
sim_config[VARIABLES_MAGNITUDES] = save(simulation.magnitudes)
|
|
151
|
+
|
|
152
|
+
# Parameters
|
|
153
|
+
# Get quantities
|
|
154
|
+
parameters: dict[str, Any] = {
|
|
155
|
+
key: qty
|
|
156
|
+
for key, qty in simulation.parameters.items()
|
|
157
|
+
if key not in simulation.update_functions
|
|
158
|
+
}
|
|
159
|
+
references: dict[str, Any] = simulation.models.copy()
|
|
160
|
+
parameters_config: dict[str, Any] = save(
|
|
161
|
+
parameters, configuration_references=references
|
|
162
|
+
)
|
|
163
|
+
references.update(parameters)
|
|
164
|
+
|
|
165
|
+
# update with fonctions
|
|
166
|
+
function_config = save(
|
|
167
|
+
simulation.update_functions, configuration_references=references
|
|
168
|
+
)
|
|
169
|
+
parameters_config.update(function_config)
|
|
170
|
+
sim_config[PARAMETERS_ID] = parameters_config
|
|
171
|
+
|
|
172
|
+
# All the quantities (with update function in the references)
|
|
173
|
+
references.update(simulation.parameters)
|
|
174
|
+
|
|
175
|
+
if len(simulation.outputs_functions) > 0:
|
|
176
|
+
sim_config[OUTPUTS_FUNCTIONS_ID] = save(
|
|
177
|
+
simulation.outputs_functions,
|
|
178
|
+
configuration_references=references,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return sim_config
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _configure_simulation(
|
|
185
|
+
config: Configuration, simulation: AbstractSimulation
|
|
186
|
+
) -> None:
|
|
187
|
+
# Set initial values
|
|
188
|
+
|
|
189
|
+
# ParameterRegister
|
|
190
|
+
_check_exising_config(PARAMETERS_ID, config)
|
|
191
|
+
_check_missing_keys(PARAMETERS_ID, config[PARAMETERS_ID], simulation.parameters)
|
|
192
|
+
|
|
193
|
+
constants_config = {
|
|
194
|
+
key: value
|
|
195
|
+
for key, value in config[PARAMETERS_ID].items()
|
|
196
|
+
if isinstance(value, Configuration) is False
|
|
197
|
+
}
|
|
198
|
+
functions_config = {
|
|
199
|
+
key: value
|
|
200
|
+
for key, value in config[PARAMETERS_ID].items()
|
|
201
|
+
if isinstance(value, Configuration) is True
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# first load the constants
|
|
205
|
+
load(constants_config, configuration_object=simulation.parameters)
|
|
206
|
+
|
|
207
|
+
# then load functions
|
|
208
|
+
references: dict[str, Any] = simulation.quantities
|
|
209
|
+
references.update(simulation.models)
|
|
210
|
+
loaded_functions = load(
|
|
211
|
+
functions_config, configuration_references=references, configuration_sort=True
|
|
212
|
+
)
|
|
213
|
+
__initialize_functions(simulation, loaded_functions)
|
|
214
|
+
|
|
215
|
+
# Time Manager
|
|
216
|
+
_check_exising_config(TIME_MANAGER_ID, config)
|
|
217
|
+
load(config[TIME_MANAGER_ID], configuration_object=simulation.time_manager)
|
|
218
|
+
|
|
219
|
+
# State
|
|
220
|
+
_check_exising_config(INIT_VARIABLES_ID, config)
|
|
221
|
+
_check_missing_keys(INIT_VARIABLES_ID, config[INIT_VARIABLES_ID], simulation.state)
|
|
222
|
+
|
|
223
|
+
load(
|
|
224
|
+
config[INIT_VARIABLES_ID],
|
|
225
|
+
configuration_object=simulation.state,
|
|
226
|
+
configuration_references=simulation.quantities,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
references.update(simulation.quantities)
|
|
230
|
+
references.update(simulation.models)
|
|
231
|
+
|
|
232
|
+
if OUTPUTS_FUNCTIONS_ID in config:
|
|
233
|
+
outputs = load(
|
|
234
|
+
config[OUTPUTS_FUNCTIONS_ID], configuration_references=references
|
|
235
|
+
)
|
|
236
|
+
__configure_outputs(simulation, outputs)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def __initialize_functions(
|
|
240
|
+
sim: AbstractSimulation, functions_parameters: dict[str, AbstractFunction]
|
|
241
|
+
) -> None:
|
|
242
|
+
for param_id, param_value in functions_parameters.items():
|
|
243
|
+
if param_id in sim.parameters:
|
|
244
|
+
arguments: dict[str, Any] = {}
|
|
245
|
+
if is_time_function(param_value):
|
|
246
|
+
sim.register_timed_parameter_update(param_id, param_value)
|
|
247
|
+
arguments[TIME_QUANTITY_ID] = sim.time_manager.time.current
|
|
248
|
+
if is_state_function(param_value):
|
|
249
|
+
arguments[STATE_NAME_ID] = sim.state
|
|
250
|
+
sim.parameters[param_id].initialize(param_value.eval(**arguments))
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def __configure_outputs(
|
|
254
|
+
sim: AbstractSimulation, config: dict[str, AbstractFunction]
|
|
255
|
+
) -> None:
|
|
256
|
+
for output_id, update_func in config.items():
|
|
257
|
+
sim.register_output_function(output_id, update_func)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def _check_exising_config(key: str, config: Configuration) -> None:
|
|
261
|
+
if key not in config:
|
|
262
|
+
raise ConfigurationError(
|
|
263
|
+
str.format(
|
|
264
|
+
"Missing key {0} in {1} configuration.",
|
|
265
|
+
key,
|
|
266
|
+
config.label,
|
|
267
|
+
)
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _check_missing_keys(
|
|
272
|
+
name: str, tested: Iterable[str], reference: Iterable[str]
|
|
273
|
+
) -> None:
|
|
274
|
+
missing_keys = [key for key in reference if key not in tested]
|
|
275
|
+
if len(missing_keys) > 0:
|
|
276
|
+
raise ConfigurationError(
|
|
277
|
+
str.format(
|
|
278
|
+
"Missing keys in {0} configuration:{2}{1}", name, missing_keys, linesep
|
|
279
|
+
)
|
|
280
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
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 object to describe Nets
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
__all__ = ["BlockDescription", "ModelComponentDescription", "Net", "Node"]
|
|
32
|
+
|
|
33
|
+
from physioblocks.description.blocks import BlockDescription, ModelComponentDescription
|
|
34
|
+
from physioblocks.description.nets import Net, Node
|