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.
Files changed (93) hide show
  1. physioblocks/__init__.py +37 -0
  2. physioblocks/base/__init__.py +27 -0
  3. physioblocks/base/operators.py +176 -0
  4. physioblocks/base/registers.py +108 -0
  5. physioblocks/computing/__init__.py +47 -0
  6. physioblocks/computing/assembling.py +291 -0
  7. physioblocks/computing/models.py +811 -0
  8. physioblocks/computing/quantities.py +354 -0
  9. physioblocks/configuration/__init__.py +38 -0
  10. physioblocks/configuration/aliases.py +203 -0
  11. physioblocks/configuration/base.py +123 -0
  12. physioblocks/configuration/computing/__init__.py +27 -0
  13. physioblocks/configuration/computing/quantities.py +56 -0
  14. physioblocks/configuration/constants.py +121 -0
  15. physioblocks/configuration/description/__init__.py +33 -0
  16. physioblocks/configuration/description/blocks.py +239 -0
  17. physioblocks/configuration/description/nets.py +155 -0
  18. physioblocks/configuration/functions.py +695 -0
  19. physioblocks/configuration/simulation/__init__.py +32 -0
  20. physioblocks/configuration/simulation/simulations.py +280 -0
  21. physioblocks/description/__init__.py +34 -0
  22. physioblocks/description/blocks.py +418 -0
  23. physioblocks/description/flux.py +157 -0
  24. physioblocks/description/nets.py +746 -0
  25. physioblocks/io/__init__.py +29 -0
  26. physioblocks/io/aliases.py +73 -0
  27. physioblocks/io/configuration.py +125 -0
  28. physioblocks/launcher/__main__.py +285 -0
  29. physioblocks/launcher/configuration.py +231 -0
  30. physioblocks/launcher/configure/__main__.py +99 -0
  31. physioblocks/launcher/constants.py +105 -0
  32. physioblocks/launcher/files.py +150 -0
  33. physioblocks/launcher/series.py +165 -0
  34. physioblocks/library/__init__.py +27 -0
  35. physioblocks/library/aliases/blocks/c_block.json +5 -0
  36. physioblocks/library/aliases/blocks/rc_block.json +5 -0
  37. physioblocks/library/aliases/blocks/rcr_block.json +5 -0
  38. physioblocks/library/aliases/blocks/spherical_cavity_block.json +5 -0
  39. physioblocks/library/aliases/blocks/valve_rl_block.json +5 -0
  40. physioblocks/library/aliases/flux/heart_flux_dof_couples.jsonc +4 -0
  41. physioblocks/library/aliases/model_components/active_law_macro_huxley_two_moments.json +5 -0
  42. physioblocks/library/aliases/model_components/rheology_fiber_additive.json +5 -0
  43. physioblocks/library/aliases/model_components/spherical_dynamics.json +5 -0
  44. physioblocks/library/aliases/model_components/velocity_law_hht.json +5 -0
  45. physioblocks/library/aliases/nets/circulation_alone_net.json +31 -0
  46. physioblocks/library/aliases/nets/spherical_heart_net.json +93 -0
  47. physioblocks/library/aliases/simulations/circulation_alone_forward_simulation.jsonc +55 -0
  48. physioblocks/library/aliases/simulations/default_forward_simulation.jsonc +7 -0
  49. physioblocks/library/aliases/simulations/default_time.jsonc +8 -0
  50. physioblocks/library/aliases/simulations/newton_method_solver.json +5 -0
  51. physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc +157 -0
  52. physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc +45 -0
  53. physioblocks/library/blocks/__init__.py +27 -0
  54. physioblocks/library/blocks/capacitances.py +516 -0
  55. physioblocks/library/blocks/cavity.py +192 -0
  56. physioblocks/library/blocks/valves.py +281 -0
  57. physioblocks/library/functions/__init__.py +27 -0
  58. physioblocks/library/functions/base_operations.py +129 -0
  59. physioblocks/library/functions/first_order.py +113 -0
  60. physioblocks/library/functions/piecewise.py +271 -0
  61. physioblocks/library/functions/trigonometric.py +78 -0
  62. physioblocks/library/functions/watchers.py +113 -0
  63. physioblocks/library/model_components/__init__.py +27 -0
  64. physioblocks/library/model_components/active_law.py +345 -0
  65. physioblocks/library/model_components/dynamics.py +986 -0
  66. physioblocks/library/model_components/rheology.py +160 -0
  67. physioblocks/library/model_components/velocity_law.py +169 -0
  68. physioblocks/references/circulation_alone_sim.jsonc +24 -0
  69. physioblocks/references/spherical_heart_respiration_sim.jsonc +33 -0
  70. physioblocks/references/spherical_heart_sim.jsonc +29 -0
  71. physioblocks/registers/__init__.py +32 -0
  72. physioblocks/registers/load_function_register.py +93 -0
  73. physioblocks/registers/save_function_register.py +106 -0
  74. physioblocks/registers/type_register.py +97 -0
  75. physioblocks/simulation/__init__.py +48 -0
  76. physioblocks/simulation/constants.py +30 -0
  77. physioblocks/simulation/functions.py +71 -0
  78. physioblocks/simulation/runtime.py +484 -0
  79. physioblocks/simulation/saved_quantities.py +129 -0
  80. physioblocks/simulation/setup.py +576 -0
  81. physioblocks/simulation/solvers.py +235 -0
  82. physioblocks/simulation/state.py +340 -0
  83. physioblocks/simulation/time_manager.py +354 -0
  84. physioblocks/utils/__init__.py +27 -0
  85. physioblocks/utils/dynamic_import_utils.py +150 -0
  86. physioblocks/utils/exceptions_utils.py +115 -0
  87. physioblocks/utils/gradient_test_utils.py +337 -0
  88. physioblocks/utils/math_utils.py +109 -0
  89. physioblocks-1.0.0.dist-info/METADATA +127 -0
  90. physioblocks-1.0.0.dist-info/RECORD +93 -0
  91. physioblocks-1.0.0.dist-info/WHEEL +4 -0
  92. physioblocks-1.0.0.dist-info/licenses/licenses/GPL-3.0-only.txt +674 -0
  93. 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