physioblocks 1.0.3__py3-none-any.whl → 1.1.1__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 +1 -1
- physioblocks/computing/models.py +313 -1
- physioblocks/launcher/__main__.py +10 -6
- physioblocks/library/blocks/capacitances.py +28 -80
- physioblocks/library/blocks/cavity.py +6 -24
- physioblocks/library/blocks/valves.py +10 -37
- physioblocks/library/model_components/active_law.py +37 -37
- physioblocks/simulation/runtime.py +70 -64
- {physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/METADATA +2 -1
- {physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/RECORD +13 -13
- {physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/WHEEL +0 -0
- {physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/licenses/licenses/GPL-3.0-only.txt +0 -0
- {physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/licenses/licenses/LGPL-3.0-only.txt +0 -0
physioblocks/__init__.py
CHANGED
physioblocks/computing/models.py
CHANGED
|
@@ -32,6 +32,7 @@ functions.
|
|
|
32
32
|
|
|
33
33
|
from __future__ import annotations
|
|
34
34
|
|
|
35
|
+
import functools
|
|
35
36
|
from collections.abc import Callable
|
|
36
37
|
from dataclasses import dataclass, field
|
|
37
38
|
from inspect import get_annotations
|
|
@@ -46,7 +47,7 @@ SystemFunction: TypeAlias = Callable[..., np.float64 | NDArray[np.float64]]
|
|
|
46
47
|
"""Type alias for functions composing the system"""
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
@dataclass
|
|
50
|
+
@dataclass
|
|
50
51
|
class Expression:
|
|
51
52
|
"""Expression(size:int, expr_func: SystemFunction, expr_gradients: Mapping[str, SystemFunction] = {})
|
|
52
53
|
Store function computing numerical values for terms in the models with the function
|
|
@@ -102,6 +103,223 @@ class Expression:
|
|
|
102
103
|
)
|
|
103
104
|
|
|
104
105
|
|
|
106
|
+
class ExpressionDecorator:
|
|
107
|
+
"""
|
|
108
|
+
Base class for expression decorators.
|
|
109
|
+
|
|
110
|
+
This is a helper that defines expressions decorating methods in a model or block
|
|
111
|
+
class.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
expression: Expression
|
|
115
|
+
"""The expression resulting from decorators declarations"""
|
|
116
|
+
|
|
117
|
+
def __init__(
|
|
118
|
+
self,
|
|
119
|
+
wrapped_function: Callable[..., Any],
|
|
120
|
+
):
|
|
121
|
+
"""
|
|
122
|
+
:param wrapped_function: The decorated expression function
|
|
123
|
+
:type wrapped_function: Callable
|
|
124
|
+
"""
|
|
125
|
+
self.expression = Expression(0, wrapped_function)
|
|
126
|
+
self._terms: list[tuple[str, int, int]] = []
|
|
127
|
+
functools.update_wrapper(self, wrapped_function)
|
|
128
|
+
|
|
129
|
+
def register_term(
|
|
130
|
+
self,
|
|
131
|
+
term_name: str,
|
|
132
|
+
term_size: int,
|
|
133
|
+
term_index: int,
|
|
134
|
+
) -> None:
|
|
135
|
+
"""
|
|
136
|
+
Register a new term to the expression decorator
|
|
137
|
+
|
|
138
|
+
:param term_name: the term local name.
|
|
139
|
+
:type term_name: str
|
|
140
|
+
|
|
141
|
+
:param term_size: The size of the term
|
|
142
|
+
:type term_size: int
|
|
143
|
+
|
|
144
|
+
:param term_index: The start index of the term in the expression
|
|
145
|
+
:type term_index: int
|
|
146
|
+
"""
|
|
147
|
+
self.expression.size += term_size
|
|
148
|
+
self._terms.append((term_name, term_size, term_index))
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def terms(self) -> list[tuple[str, int, int]]:
|
|
152
|
+
"""
|
|
153
|
+
Get the terms described by the expression.
|
|
154
|
+
|
|
155
|
+
:return: list of terms description
|
|
156
|
+
:rtype: list[[tuple[str, int, int]]]
|
|
157
|
+
"""
|
|
158
|
+
return self._terms.copy()
|
|
159
|
+
|
|
160
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
161
|
+
return self.expression.expr_func(*args, **kwargs)
|
|
162
|
+
|
|
163
|
+
def partial_derivative(
|
|
164
|
+
self, variable_name: str
|
|
165
|
+
) -> Callable[..., Callable[..., Any]]:
|
|
166
|
+
"""
|
|
167
|
+
Declares a flux partial derivative.
|
|
168
|
+
|
|
169
|
+
:param variable_name: the variable local name.
|
|
170
|
+
:type variable_name: str
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
def _register(wrapped: Callable[..., Any]) -> Callable[..., Any]:
|
|
174
|
+
self.expression.expr_gradients[variable_name] = wrapped
|
|
175
|
+
return wrapped
|
|
176
|
+
|
|
177
|
+
return _register
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _check_expression_decorator_type(
|
|
181
|
+
wrapped_function: Any, new_decorator_type: type[ExpressionDecorator]
|
|
182
|
+
) -> None:
|
|
183
|
+
if (
|
|
184
|
+
isinstance(wrapped_function, ExpressionDecorator) is True
|
|
185
|
+
and isinstance(wrapped_function, new_decorator_type) is False
|
|
186
|
+
):
|
|
187
|
+
raise ValueError(
|
|
188
|
+
str.format(
|
|
189
|
+
"Can not decorate a function of an other type. "
|
|
190
|
+
"Current type is {0}, new type is {1}.",
|
|
191
|
+
type(wrapped_function),
|
|
192
|
+
new_decorator_type,
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class InternalEquationDecorator(ExpressionDecorator):
|
|
198
|
+
"""
|
|
199
|
+
Define a decorator that identifies internal equation expressions.
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def declares_internal_equation(
|
|
206
|
+
variable_name: str, size: int = 1, starting_index: int = 0
|
|
207
|
+
) -> Callable[..., InternalEquationDecorator]:
|
|
208
|
+
"""
|
|
209
|
+
Declares a internal equation expression.
|
|
210
|
+
|
|
211
|
+
Once the internal equation function is declared, partial derivatives can be added
|
|
212
|
+
using the function name and the local variable name for the partial derivative.
|
|
213
|
+
|
|
214
|
+
:param variable_name: the variable name on which the expression provides a dynamic.
|
|
215
|
+
:type variable_name: str
|
|
216
|
+
|
|
217
|
+
:param size: the size of the equation. Default is 1
|
|
218
|
+
:type size: int
|
|
219
|
+
|
|
220
|
+
:param starting_index: the starting index of the equation line matching the
|
|
221
|
+
variable. Default is 0
|
|
222
|
+
:type starting_index: int
|
|
223
|
+
|
|
224
|
+
:raises ValueError: Raises a ValueError if the function is already decorated with
|
|
225
|
+
an expression decorator of an other type.
|
|
226
|
+
|
|
227
|
+
Example
|
|
228
|
+
^^^^^^^
|
|
229
|
+
|
|
230
|
+
.. code:: python
|
|
231
|
+
|
|
232
|
+
@dataclass
|
|
233
|
+
class SimpleModel(ModelComponent):
|
|
234
|
+
|
|
235
|
+
x: Quantity
|
|
236
|
+
a: Quantity
|
|
237
|
+
|
|
238
|
+
@declares_internal_equation("x")
|
|
239
|
+
def residual(self):
|
|
240
|
+
return x.new**2 - a.current
|
|
241
|
+
|
|
242
|
+
@flux_1.partial_derivative("x")
|
|
243
|
+
def dresidual_dx(self):
|
|
244
|
+
return 2.0 * x.new
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
def _create_internal_equation_decorator(
|
|
248
|
+
wrapped: Callable[..., Any],
|
|
249
|
+
) -> InternalEquationDecorator:
|
|
250
|
+
_check_expression_decorator_type(wrapped, InternalEquationDecorator)
|
|
251
|
+
|
|
252
|
+
decorated = (
|
|
253
|
+
wrapped
|
|
254
|
+
if isinstance(wrapped, InternalEquationDecorator)
|
|
255
|
+
else InternalEquationDecorator(wrapped)
|
|
256
|
+
)
|
|
257
|
+
decorated.register_term(variable_name, size, starting_index)
|
|
258
|
+
return decorated
|
|
259
|
+
|
|
260
|
+
return _create_internal_equation_decorator
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class SavedQuantityDecorator(ExpressionDecorator):
|
|
264
|
+
"""
|
|
265
|
+
Define a decorator that identifies saved quantities expressions.
|
|
266
|
+
"""
|
|
267
|
+
|
|
268
|
+
pass
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def declares_saved_quantity(
|
|
272
|
+
quantity_name: str, size: int = 1, starting_index: int = 0
|
|
273
|
+
) -> Callable[..., SavedQuantityDecorator]:
|
|
274
|
+
"""
|
|
275
|
+
Declares a saved quantity expression.
|
|
276
|
+
|
|
277
|
+
:param quantity_name: the local quantity name.
|
|
278
|
+
:type quantity_name: str
|
|
279
|
+
|
|
280
|
+
:param size: the size of the expression. Default is 1
|
|
281
|
+
:type size: int
|
|
282
|
+
|
|
283
|
+
:param starting_index: the starting index of the expression in the function.
|
|
284
|
+
Default is 0
|
|
285
|
+
:type starting_index: int
|
|
286
|
+
|
|
287
|
+
:raises ValueError: Raises a ValueError if the function is already decorated with
|
|
288
|
+
an expression decorator of an other type.
|
|
289
|
+
|
|
290
|
+
Example
|
|
291
|
+
^^^^^^^
|
|
292
|
+
|
|
293
|
+
.. code:: python
|
|
294
|
+
|
|
295
|
+
@dataclass
|
|
296
|
+
class SimpleModel(ModelComponent):
|
|
297
|
+
|
|
298
|
+
a: Quantity
|
|
299
|
+
b: Quantity
|
|
300
|
+
|
|
301
|
+
@declares_saved_quantity("a + b")
|
|
302
|
+
def sum(self):
|
|
303
|
+
return a.current + b.current
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
def _create_saved_quantity_decorator(
|
|
307
|
+
wrapped: Callable[..., Any],
|
|
308
|
+
) -> SavedQuantityDecorator:
|
|
309
|
+
_check_expression_decorator_type(wrapped, SavedQuantityDecorator)
|
|
310
|
+
|
|
311
|
+
decorator = (
|
|
312
|
+
wrapped
|
|
313
|
+
if isinstance(wrapped, SavedQuantityDecorator)
|
|
314
|
+
else SavedQuantityDecorator(wrapped)
|
|
315
|
+
)
|
|
316
|
+
decorator.register_term(quantity_name, size, starting_index)
|
|
317
|
+
|
|
318
|
+
return decorator
|
|
319
|
+
|
|
320
|
+
return _create_saved_quantity_decorator
|
|
321
|
+
|
|
322
|
+
|
|
105
323
|
@dataclass(frozen=True)
|
|
106
324
|
class TermDefinition:
|
|
107
325
|
"""Describe Terms defined in an :class:`~physioblocks.computing.models.Expression`.
|
|
@@ -303,6 +521,23 @@ class ModelComponentMetaClass(type):
|
|
|
303
521
|
cls.__INTERNAL_EXPRESSION_KEY: [],
|
|
304
522
|
cls.__SAVED_QUANTITIES_EXPRESSION_KEY: [],
|
|
305
523
|
}
|
|
524
|
+
for attr in cls.__dict__.values():
|
|
525
|
+
if isinstance(attr, InternalEquationDecorator):
|
|
526
|
+
for term_name, term_size, term_index in attr.terms:
|
|
527
|
+
cls.declares_internal_expression(
|
|
528
|
+
term_name,
|
|
529
|
+
attr.expression,
|
|
530
|
+
term_size,
|
|
531
|
+
term_index,
|
|
532
|
+
)
|
|
533
|
+
elif isinstance(attr, SavedQuantityDecorator):
|
|
534
|
+
for term_name, term_size, term_index in attr.terms:
|
|
535
|
+
cls.declares_saved_quantity_expression(
|
|
536
|
+
term_name,
|
|
537
|
+
attr.expression,
|
|
538
|
+
term_size,
|
|
539
|
+
term_index,
|
|
540
|
+
)
|
|
306
541
|
|
|
307
542
|
@staticmethod
|
|
308
543
|
def __is_quantity_type(type_to_test: Any) -> bool:
|
|
@@ -481,6 +716,7 @@ class ModelComponentMetaClass(type):
|
|
|
481
716
|
|
|
482
717
|
# Add the term definition to the expression definition
|
|
483
718
|
expression_def.terms.append(TermDefinition(term_id, size, index))
|
|
719
|
+
expression_def.terms.sort(key=lambda term: term.index)
|
|
484
720
|
|
|
485
721
|
def declares_internal_expression(
|
|
486
722
|
cls,
|
|
@@ -690,6 +926,78 @@ class ModelComponent(metaclass=ModelComponentMetaClass):
|
|
|
690
926
|
"""Override this method to define specific for model initialization."""
|
|
691
927
|
|
|
692
928
|
|
|
929
|
+
class FluxDecorator(ExpressionDecorator):
|
|
930
|
+
"""
|
|
931
|
+
Define a decorator that identifies flux functions
|
|
932
|
+
"""
|
|
933
|
+
|
|
934
|
+
pass
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
def declares_flux(
|
|
938
|
+
index: int, dof_name: str, size: int = 1
|
|
939
|
+
) -> Callable[..., FluxDecorator]:
|
|
940
|
+
"""
|
|
941
|
+
Declares a flux function.
|
|
942
|
+
|
|
943
|
+
Once the flux expression is declared, partial derivatives can be added using the
|
|
944
|
+
flux function name and the local variable name for the partial derivative.
|
|
945
|
+
|
|
946
|
+
:param index: the index of the flux in the block.
|
|
947
|
+
:type index: int
|
|
948
|
+
|
|
949
|
+
:param dof_name: the matching dof local name
|
|
950
|
+
:type dof_name: str
|
|
951
|
+
|
|
952
|
+
:param size: the size of the flux returned by the function
|
|
953
|
+
:type size: int
|
|
954
|
+
|
|
955
|
+
:raises ValueError: Raises a ValueError if the function is already decorated with
|
|
956
|
+
an expression decorator of an other type.
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
Example
|
|
960
|
+
^^^^^^^
|
|
961
|
+
|
|
962
|
+
.. code:: python
|
|
963
|
+
|
|
964
|
+
@dataclass
|
|
965
|
+
class SimpleBlock(Block):
|
|
966
|
+
|
|
967
|
+
q_1: Quantity
|
|
968
|
+
|
|
969
|
+
# declares a flux shared at local node 1, where the associated dof has the
|
|
970
|
+
# local name "potential_1"
|
|
971
|
+
@declares_flux(1, "potential_1")
|
|
972
|
+
def flux_1(self):
|
|
973
|
+
return q_1.new
|
|
974
|
+
|
|
975
|
+
# associate the following function as the partial derivative of "flux_1" for
|
|
976
|
+
# variable "q_1"
|
|
977
|
+
@flux_1.partial_derivative("q_1")
|
|
978
|
+
def dflux_1_dq_1(self):
|
|
979
|
+
return 1.0
|
|
980
|
+
|
|
981
|
+
"""
|
|
982
|
+
|
|
983
|
+
def _create_flux_decorator(wrapped: Callable[..., Any]) -> FluxDecorator:
|
|
984
|
+
if isinstance(wrapped, ExpressionDecorator) is True:
|
|
985
|
+
raise ValueError(
|
|
986
|
+
str.format(
|
|
987
|
+
"Function already declares an expression, it can not be a flux."
|
|
988
|
+
)
|
|
989
|
+
)
|
|
990
|
+
|
|
991
|
+
decorator = (
|
|
992
|
+
wrapped if isinstance(wrapped, FluxDecorator) else FluxDecorator(wrapped)
|
|
993
|
+
)
|
|
994
|
+
decorator.register_term(dof_name, size, index)
|
|
995
|
+
|
|
996
|
+
return decorator
|
|
997
|
+
|
|
998
|
+
return _create_flux_decorator
|
|
999
|
+
|
|
1000
|
+
|
|
693
1001
|
class BlockMetaClass(ModelComponentMetaClass):
|
|
694
1002
|
"""Meta-class for :class:`~physioblocks.computing.models.Block`.
|
|
695
1003
|
|
|
@@ -711,6 +1019,10 @@ class BlockMetaClass(ModelComponentMetaClass):
|
|
|
711
1019
|
def __init__(cls, *args: Any, **kwargs: Any) -> None:
|
|
712
1020
|
super().__init__(*args, **kwargs)
|
|
713
1021
|
cls._fluxes = {}
|
|
1022
|
+
for attr in cls.__dict__.values():
|
|
1023
|
+
if isinstance(attr, FluxDecorator):
|
|
1024
|
+
for term_name, _term_size, term_index in attr.terms:
|
|
1025
|
+
cls.declares_flux_expression(term_index, term_name, attr.expression)
|
|
714
1026
|
|
|
715
1027
|
def declares_flux_expression(
|
|
716
1028
|
cls, node_index: int, variable_id: str, expr: Expression
|
|
@@ -37,6 +37,7 @@ from pathlib import Path
|
|
|
37
37
|
from typing import Any
|
|
38
38
|
|
|
39
39
|
import pandas as pd
|
|
40
|
+
from rich.logging import RichHandler
|
|
40
41
|
|
|
41
42
|
import physioblocks.utils.exceptions_utils as exception_utils
|
|
42
43
|
from physioblocks.configuration import Configuration, load, unwrap_aliases
|
|
@@ -64,8 +65,9 @@ from physioblocks.simulation import AbstractSimulation, SimulationError
|
|
|
64
65
|
.. note:: When deleting a serie from the launcher folder, or a specific simulation from
|
|
65
66
|
a serie, the launchers logs are updated the next time any simulation is launched.
|
|
66
67
|
"""
|
|
68
|
+
FILE_LOG_FORMATTER = logging.Formatter(logging.BASIC_FORMAT)
|
|
69
|
+
RICH_LOG_FORMATTER = logging.Formatter("%(message)s", "[%X]")
|
|
67
70
|
|
|
68
|
-
SIMULATION_LOG_FORMATER = logging.Formatter(logging.BASIC_FORMAT)
|
|
69
71
|
_root_logger = logging.getLogger()
|
|
70
72
|
_root_logger.setLevel(logging.DEBUG)
|
|
71
73
|
|
|
@@ -90,8 +92,10 @@ def run_simulation(config: Configuration) -> pd.DataFrame:
|
|
|
90
92
|
return pd.DataFrame(results)
|
|
91
93
|
|
|
92
94
|
|
|
93
|
-
def add_log_handler(
|
|
94
|
-
handler.
|
|
95
|
+
def add_log_handler(
|
|
96
|
+
handler: logging.Handler, level: str | int, formatter: logging.Formatter
|
|
97
|
+
) -> None:
|
|
98
|
+
handler.setFormatter(formatter)
|
|
95
99
|
handler.setLevel(level)
|
|
96
100
|
_root_logger.addHandler(handler)
|
|
97
101
|
|
|
@@ -132,7 +136,7 @@ def main(
|
|
|
132
136
|
# configure the simulation log file (always in DEBUG)
|
|
133
137
|
log_file_path = sim_folder / str.join(".", [sim_info.reference, "log"])
|
|
134
138
|
file_handler = logging.FileHandler(log_file_path)
|
|
135
|
-
add_log_handler(file_handler, logging.DEBUG)
|
|
139
|
+
add_log_handler(file_handler, logging.DEBUG, FILE_LOG_FORMATTER)
|
|
136
140
|
|
|
137
141
|
# log the current simulation infos
|
|
138
142
|
_root_logger.info(str(sim_info))
|
|
@@ -260,8 +264,8 @@ if __name__ == "__main__":
|
|
|
260
264
|
|
|
261
265
|
# setup logger when verbose
|
|
262
266
|
if args.verbose is True:
|
|
263
|
-
stdout_handler = logging.StreamHandler(sys.stdout)
|
|
264
|
-
add_log_handler(
|
|
267
|
+
# stdout_handler = logging.StreamHandler(sys.stdout)
|
|
268
|
+
add_log_handler(RichHandler(), args.log_level, RICH_LOG_FORMATTER)
|
|
265
269
|
|
|
266
270
|
# create paths from arguments
|
|
267
271
|
root_folder_path = Path(args.launcher_directory).absolute()
|
|
@@ -31,7 +31,12 @@ from typing import Any
|
|
|
31
31
|
|
|
32
32
|
import numpy as np
|
|
33
33
|
|
|
34
|
-
from physioblocks.computing import Block,
|
|
34
|
+
from physioblocks.computing import Block, Quantity, diff, mid_point
|
|
35
|
+
from physioblocks.computing.models import (
|
|
36
|
+
declares_flux,
|
|
37
|
+
declares_internal_equation,
|
|
38
|
+
declares_saved_quantity,
|
|
39
|
+
)
|
|
35
40
|
from physioblocks.registers import register_type
|
|
36
41
|
from physioblocks.simulation import Time
|
|
37
42
|
|
|
@@ -41,8 +46,8 @@ from physioblocks.simulation import Time
|
|
|
41
46
|
# Constant for the c block type id
|
|
42
47
|
C_BLOCK_TYPE_ID = "c_block"
|
|
43
48
|
|
|
44
|
-
# Constant for the c block
|
|
45
|
-
|
|
49
|
+
# Constant for the c block pressure local id
|
|
50
|
+
C_BLOCK_PRESSURE_ID = "pressure"
|
|
46
51
|
|
|
47
52
|
|
|
48
53
|
@register_type(C_BLOCK_TYPE_ID)
|
|
@@ -77,6 +82,7 @@ class CBlock(Block):
|
|
|
77
82
|
time: Time
|
|
78
83
|
"""Simulation time"""
|
|
79
84
|
|
|
85
|
+
@declares_flux(1, C_BLOCK_PRESSURE_ID)
|
|
80
86
|
def flux(self) -> Any:
|
|
81
87
|
"""
|
|
82
88
|
Compute the flux at local node 1
|
|
@@ -86,6 +92,7 @@ class CBlock(Block):
|
|
|
86
92
|
"""
|
|
87
93
|
return -self.capacitance.current * diff(self.pressure) * self.time.inv_dt
|
|
88
94
|
|
|
95
|
+
@flux.partial_derivative(C_BLOCK_PRESSURE_ID)
|
|
89
96
|
def dflux_dpressure(self) -> Any:
|
|
90
97
|
"""
|
|
91
98
|
Compute the flux at local node 1 partial derivative for pressure
|
|
@@ -96,12 +103,6 @@ class CBlock(Block):
|
|
|
96
103
|
return -self.capacitance.current * self.time.inv_dt
|
|
97
104
|
|
|
98
105
|
|
|
99
|
-
_c_block_flux_expression = Expression(
|
|
100
|
-
1, CBlock.flux, {C_BLOCK_PRESSURE_DOF_ID: CBlock.dflux_dpressure}
|
|
101
|
-
)
|
|
102
|
-
CBlock.declares_flux_expression(1, C_BLOCK_PRESSURE_DOF_ID, _c_block_flux_expression)
|
|
103
|
-
|
|
104
|
-
|
|
105
106
|
# RC BLOCK Definition
|
|
106
107
|
|
|
107
108
|
# Constant for the rc block type id
|
|
@@ -164,6 +165,7 @@ class RCBlock(Block):
|
|
|
164
165
|
time: Time
|
|
165
166
|
"""The simulation time"""
|
|
166
167
|
|
|
168
|
+
@declares_flux(1, RC_BLOCK_PRESSURE_1_DOF_ID)
|
|
167
169
|
def flux_1(self) -> Any:
|
|
168
170
|
"""
|
|
169
171
|
Computes the outlet flux at local node 1.
|
|
@@ -175,6 +177,7 @@ class RCBlock(Block):
|
|
|
175
177
|
pressure_2 = mid_point(self.pressure_2)
|
|
176
178
|
return (pressure_2 - pressure_1) / self.resistance.current
|
|
177
179
|
|
|
180
|
+
@flux_1.partial_derivative(RC_BLOCK_PRESSURE_1_DOF_ID)
|
|
178
181
|
def dflux_1_dpressure_1(self) -> Any:
|
|
179
182
|
"""
|
|
180
183
|
Computes the outlet flux at node 1 derivative for pressure_1.
|
|
@@ -184,6 +187,7 @@ class RCBlock(Block):
|
|
|
184
187
|
"""
|
|
185
188
|
return -0.5 / self.resistance.current
|
|
186
189
|
|
|
190
|
+
@flux_1.partial_derivative(RC_BLOCK_PRESSURE_2_DOF_ID)
|
|
187
191
|
def dflux_1_dpressure_2(self) -> Any:
|
|
188
192
|
"""
|
|
189
193
|
Computes the outlet flux at node 1 derivative for pressure_2.
|
|
@@ -193,6 +197,7 @@ class RCBlock(Block):
|
|
|
193
197
|
"""
|
|
194
198
|
return 0.5 / self.resistance.current
|
|
195
199
|
|
|
200
|
+
@declares_flux(2, RC_BLOCK_PRESSURE_2_DOF_ID)
|
|
196
201
|
def flux_2(self) -> Any:
|
|
197
202
|
"""
|
|
198
203
|
Computes the outlet flux at node 2.
|
|
@@ -208,6 +213,7 @@ class RCBlock(Block):
|
|
|
208
213
|
- self.capacitance.current * self.time.inv_dt * dpressure_2
|
|
209
214
|
)
|
|
210
215
|
|
|
216
|
+
@flux_2.partial_derivative(RC_BLOCK_PRESSURE_1_DOF_ID)
|
|
211
217
|
def dflux_2_dpressure_1(self) -> Any:
|
|
212
218
|
"""
|
|
213
219
|
Computes the outlet flux at node 2 derivative for pressure_1.
|
|
@@ -217,6 +223,7 @@ class RCBlock(Block):
|
|
|
217
223
|
"""
|
|
218
224
|
return 0.5 / self.resistance.current
|
|
219
225
|
|
|
226
|
+
@flux_2.partial_derivative(RC_BLOCK_PRESSURE_2_DOF_ID)
|
|
220
227
|
def dflux_2_dpressure_2(self) -> Any:
|
|
221
228
|
"""
|
|
222
229
|
Computes the outlet flux at node 2 derivative for pressure_2.
|
|
@@ -229,29 +236,6 @@ class RCBlock(Block):
|
|
|
229
236
|
)
|
|
230
237
|
|
|
231
238
|
|
|
232
|
-
# Define the flux expression going in the input node for rc_block
|
|
233
|
-
_rc_block_flux_1_expr = Expression(
|
|
234
|
-
1,
|
|
235
|
-
RCBlock.flux_1,
|
|
236
|
-
{
|
|
237
|
-
RC_BLOCK_PRESSURE_1_DOF_ID: RCBlock.dflux_1_dpressure_1,
|
|
238
|
-
RC_BLOCK_PRESSURE_2_DOF_ID: RCBlock.dflux_1_dpressure_2,
|
|
239
|
-
},
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
# Define the flux expression going in the output node for rc_block
|
|
243
|
-
_rc_block_flux_2_expr = Expression(
|
|
244
|
-
1,
|
|
245
|
-
RCBlock.flux_2,
|
|
246
|
-
{
|
|
247
|
-
RC_BLOCK_PRESSURE_1_DOF_ID: RCBlock.dflux_2_dpressure_1,
|
|
248
|
-
RC_BLOCK_PRESSURE_2_DOF_ID: RCBlock.dflux_2_dpressure_2,
|
|
249
|
-
},
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
RCBlock.declares_flux_expression(1, RC_BLOCK_PRESSURE_1_DOF_ID, _rc_block_flux_1_expr)
|
|
253
|
-
RCBlock.declares_flux_expression(2, RC_BLOCK_PRESSURE_2_DOF_ID, _rc_block_flux_2_expr)
|
|
254
|
-
|
|
255
239
|
# RCR BLOCK Definition
|
|
256
240
|
|
|
257
241
|
# Constant for the rcr block type id
|
|
@@ -300,7 +284,7 @@ class RCRBlock(Block):
|
|
|
300
284
|
|
|
301
285
|
\frac{P_1 - P_{mid}}{R_1} + \frac{P_2 - P_{mid}}{R_2} - C\dot{P}_{mid} = 0
|
|
302
286
|
|
|
303
|
-
**
|
|
287
|
+
**Discretization:**
|
|
304
288
|
|
|
305
289
|
.. math::
|
|
306
290
|
|
|
@@ -341,6 +325,7 @@ class RCRBlock(Block):
|
|
|
341
325
|
time: Time
|
|
342
326
|
"""The simulation time"""
|
|
343
327
|
|
|
328
|
+
@declares_flux(1, RCR_BLOCK_PRESSURE_1_ID)
|
|
344
329
|
def flux_1(self) -> Any:
|
|
345
330
|
"""
|
|
346
331
|
Computes the outlet flux at node 1.
|
|
@@ -354,6 +339,7 @@ class RCRBlock(Block):
|
|
|
354
339
|
|
|
355
340
|
return (pressure_mid_discr - pressure_1_discr) / self.resistance_1.current
|
|
356
341
|
|
|
342
|
+
@flux_1.partial_derivative(RCR_BLOCK_PRESSURE_1_ID)
|
|
357
343
|
def dflux_1_dp_1(self) -> Any:
|
|
358
344
|
"""
|
|
359
345
|
Computes the outlet flux at node 1 derivative for pressure_1.
|
|
@@ -364,6 +350,7 @@ class RCRBlock(Block):
|
|
|
364
350
|
|
|
365
351
|
return -0.5 / self.resistance_1.current
|
|
366
352
|
|
|
353
|
+
@flux_1.partial_derivative(RCR_BLOCK_PRESSURE_MID_ID)
|
|
367
354
|
def dflux_1_dp_mid(self) -> Any:
|
|
368
355
|
"""
|
|
369
356
|
Computes the outlet flux at node 1 derivative for pressure_mid.
|
|
@@ -374,6 +361,7 @@ class RCRBlock(Block):
|
|
|
374
361
|
|
|
375
362
|
return 0.5 / self.resistance_1.current
|
|
376
363
|
|
|
364
|
+
@declares_flux(2, RCR_BLOCK_PRESSURE_2_ID)
|
|
377
365
|
def flux_2(self) -> Any:
|
|
378
366
|
"""
|
|
379
367
|
Computes the flux at node 2.
|
|
@@ -386,6 +374,7 @@ class RCRBlock(Block):
|
|
|
386
374
|
|
|
387
375
|
return (pressure_mid_discr - pressure_2_discr) / self.resistance_2.current
|
|
388
376
|
|
|
377
|
+
@flux_2.partial_derivative(RCR_BLOCK_PRESSURE_MID_ID)
|
|
389
378
|
def dflux_2_dp_mid(self) -> Any:
|
|
390
379
|
"""
|
|
391
380
|
Computes the outlet flux at node 2 derivative for pressure_mid.
|
|
@@ -396,6 +385,7 @@ class RCRBlock(Block):
|
|
|
396
385
|
|
|
397
386
|
return 0.5 / self.resistance_2.current
|
|
398
387
|
|
|
388
|
+
@flux_2.partial_derivative(RCR_BLOCK_PRESSURE_2_ID)
|
|
399
389
|
def dflux_2_dp_2(self) -> Any:
|
|
400
390
|
"""
|
|
401
391
|
Computes the outlet flux at node 2 derivative for pressure_2.
|
|
@@ -406,6 +396,7 @@ class RCRBlock(Block):
|
|
|
406
396
|
|
|
407
397
|
return -0.5 / self.resistance_2.current
|
|
408
398
|
|
|
399
|
+
@declares_internal_equation(RCR_BLOCK_PRESSURE_MID_ID)
|
|
409
400
|
def pressure_mid_residual(self) -> Any:
|
|
410
401
|
"""
|
|
411
402
|
Compute the residual representing dynamics of the mid node pressure.
|
|
@@ -424,6 +415,7 @@ class RCRBlock(Block):
|
|
|
424
415
|
- self.capacitance.current * self.time.inv_dt * diff(self.pressure_mid)
|
|
425
416
|
)
|
|
426
417
|
|
|
418
|
+
@pressure_mid_residual.partial_derivative(RCR_BLOCK_PRESSURE_1_ID)
|
|
427
419
|
def pressure_mid_residual_dp_1(self) -> Any:
|
|
428
420
|
"""
|
|
429
421
|
Compute the residual derivative for pressure_1
|
|
@@ -434,6 +426,7 @@ class RCRBlock(Block):
|
|
|
434
426
|
|
|
435
427
|
return 0.5 / self.resistance_1.current
|
|
436
428
|
|
|
429
|
+
@pressure_mid_residual.partial_derivative(RCR_BLOCK_PRESSURE_2_ID)
|
|
437
430
|
def pressure_mid_residual_dp_2(self) -> Any:
|
|
438
431
|
"""
|
|
439
432
|
Compute the residual derivative for pressure_2
|
|
@@ -444,6 +437,7 @@ class RCRBlock(Block):
|
|
|
444
437
|
|
|
445
438
|
return 0.5 / self.resistance_2.current
|
|
446
439
|
|
|
440
|
+
@pressure_mid_residual.partial_derivative(RCR_BLOCK_PRESSURE_MID_ID)
|
|
447
441
|
def pressure_mid_residual_dp_mid(self) -> Any:
|
|
448
442
|
"""
|
|
449
443
|
Compute the residual derivative for pressure_mid
|
|
@@ -458,6 +452,7 @@ class RCRBlock(Block):
|
|
|
458
452
|
- 0.5 / self.resistance_2.current
|
|
459
453
|
)
|
|
460
454
|
|
|
455
|
+
@declares_saved_quantity("volume")
|
|
461
456
|
def compute_volume_stored(self) -> Any:
|
|
462
457
|
"""
|
|
463
458
|
Computes volume stored in the capacitance.
|
|
@@ -467,50 +462,3 @@ class RCRBlock(Block):
|
|
|
467
462
|
"""
|
|
468
463
|
|
|
469
464
|
return self.capacitance.current * self.pressure_mid.current
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
# Define the flux expression going in node 1 for rcr block
|
|
473
|
-
_rcr_block_flux_1_expr = Expression(
|
|
474
|
-
1,
|
|
475
|
-
RCRBlock.flux_1,
|
|
476
|
-
{
|
|
477
|
-
RCR_BLOCK_PRESSURE_1_ID: RCRBlock.dflux_1_dp_1,
|
|
478
|
-
RCR_BLOCK_PRESSURE_MID_ID: RCRBlock.dflux_1_dp_mid,
|
|
479
|
-
},
|
|
480
|
-
)
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
# Define the flux expression going in node 2 for rcr block
|
|
484
|
-
_rcr_block_flux_2_expr = Expression(
|
|
485
|
-
1,
|
|
486
|
-
RCRBlock.flux_2,
|
|
487
|
-
{
|
|
488
|
-
RCR_BLOCK_PRESSURE_MID_ID: RCRBlock.dflux_2_dp_mid,
|
|
489
|
-
RCR_BLOCK_PRESSURE_2_ID: RCRBlock.dflux_2_dp_2,
|
|
490
|
-
},
|
|
491
|
-
)
|
|
492
|
-
|
|
493
|
-
# Define the residual expression giving the pressure at the mid node
|
|
494
|
-
_rcr_block_pressure_mid_residual_expr = Expression(
|
|
495
|
-
1,
|
|
496
|
-
RCRBlock.pressure_mid_residual,
|
|
497
|
-
{
|
|
498
|
-
RCR_BLOCK_PRESSURE_1_ID: RCRBlock.pressure_mid_residual_dp_1,
|
|
499
|
-
RCR_BLOCK_PRESSURE_MID_ID: RCRBlock.pressure_mid_residual_dp_mid,
|
|
500
|
-
RCR_BLOCK_PRESSURE_2_ID: RCRBlock.pressure_mid_residual_dp_2,
|
|
501
|
-
},
|
|
502
|
-
)
|
|
503
|
-
|
|
504
|
-
# Derfine the stored volume saved quantity expression.
|
|
505
|
-
_rcr_volume_stored_expr = Expression(1, RCRBlock.compute_volume_stored)
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
RCRBlock.declares_internal_expression(
|
|
509
|
-
RCR_BLOCK_PRESSURE_MID_ID, _rcr_block_pressure_mid_residual_expr
|
|
510
|
-
)
|
|
511
|
-
|
|
512
|
-
RCRBlock.declares_flux_expression(1, RCR_BLOCK_PRESSURE_1_ID, _rcr_block_flux_1_expr)
|
|
513
|
-
RCRBlock.declares_flux_expression(2, RCR_BLOCK_PRESSURE_2_ID, _rcr_block_flux_2_expr)
|
|
514
|
-
RCRBlock.declares_saved_quantity_expression(
|
|
515
|
-
RCR_BLOCK_VOLUME_OUTPUT_ID, _rcr_volume_stored_expr
|
|
516
|
-
)
|
|
@@ -33,7 +33,8 @@ from typing import Any
|
|
|
33
33
|
|
|
34
34
|
import numpy as np
|
|
35
35
|
|
|
36
|
-
from physioblocks.computing import Block,
|
|
36
|
+
from physioblocks.computing import Block, Quantity
|
|
37
|
+
from physioblocks.computing.models import declares_flux
|
|
37
38
|
from physioblocks.registers import register_type
|
|
38
39
|
from physioblocks.simulation import Time
|
|
39
40
|
|
|
@@ -74,7 +75,7 @@ class SphericalCavityBlock(Block):
|
|
|
74
75
|
|
|
75
76
|
:math:`Q = - \frac {dV(y)}{dt}`
|
|
76
77
|
|
|
77
|
-
**
|
|
78
|
+
**Discretized:**
|
|
78
79
|
|
|
79
80
|
:math:`Q^{n + \frac{1}{2}} = - \frac {V(y^{n + 1}) - V(y^{n})}{\Delta t^n}`
|
|
80
81
|
|
|
@@ -135,9 +136,10 @@ class SphericalCavityBlock(Block):
|
|
|
135
136
|
3,
|
|
136
137
|
)
|
|
137
138
|
|
|
139
|
+
@declares_flux(1, CAVITY_PRESSURE_LOCAL_ID)
|
|
138
140
|
def cavity_flux(self) -> Any:
|
|
139
141
|
"""
|
|
140
|
-
Compute the
|
|
142
|
+
Compute the cavity flux at local node 1.
|
|
141
143
|
|
|
142
144
|
:return: the flux
|
|
143
145
|
:rtype: np.float64
|
|
@@ -149,6 +151,7 @@ class SphericalCavityBlock(Block):
|
|
|
149
151
|
|
|
150
152
|
return cavity_flux
|
|
151
153
|
|
|
154
|
+
@cavity_flux.partial_derivative(CAVITY_DISP_LOCAL_ID)
|
|
152
155
|
def dcavity_flux_ddisp(self) -> Any:
|
|
153
156
|
"""
|
|
154
157
|
Compute the partial derivative of the cavity flux for ``disp``
|
|
@@ -169,24 +172,3 @@ class SphericalCavityBlock(Block):
|
|
|
169
172
|
)
|
|
170
173
|
* (1.0 + np.pow(disp_new_ratio, -3) * self.thickness_radius_ratio)
|
|
171
174
|
)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
# Define the cavity block flux expression.
|
|
175
|
-
_cavity_block_flux_expr = Expression(
|
|
176
|
-
1,
|
|
177
|
-
SphericalCavityBlock.cavity_flux,
|
|
178
|
-
{CAVITY_DISP_LOCAL_ID: SphericalCavityBlock.dcavity_flux_ddisp},
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
SphericalCavityBlock.declares_flux_expression(
|
|
182
|
-
1, CAVITY_PRESSURE_LOCAL_ID, _cavity_block_flux_expr
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
# Define the cavity block volume of fluid expression.
|
|
187
|
-
_cavity_block_fluid_volume_expr = Expression(
|
|
188
|
-
1, SphericalCavityBlock.fluid_volume_current
|
|
189
|
-
)
|
|
190
|
-
SphericalCavityBlock.declares_saved_quantity_expression(
|
|
191
|
-
CAVITY_VOLUME_LOCAL_ID, _cavity_block_fluid_volume_expr
|
|
192
|
-
)
|
|
@@ -35,12 +35,12 @@ import numpy as np
|
|
|
35
35
|
|
|
36
36
|
from physioblocks.computing import (
|
|
37
37
|
Block,
|
|
38
|
-
Expression,
|
|
39
38
|
Quantity,
|
|
40
39
|
diff,
|
|
41
40
|
mid_alpha,
|
|
42
41
|
mid_point,
|
|
43
42
|
)
|
|
43
|
+
from physioblocks.computing.models import declares_flux, declares_internal_equation
|
|
44
44
|
from physioblocks.registers import register_type
|
|
45
45
|
from physioblocks.simulation import Time
|
|
46
46
|
|
|
@@ -96,7 +96,7 @@ class ValveRLBlock(Block):
|
|
|
96
96
|
R_{\text{back}}Q \text{ else }
|
|
97
97
|
\end{cases} = 0
|
|
98
98
|
|
|
99
|
-
**
|
|
99
|
+
**Discretization:**
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
.. math:: Q_1^{{n + \frac{1}{2}}} = - Q^{{n + \frac{1}{2}}}
|
|
@@ -145,6 +145,7 @@ class ValveRLBlock(Block):
|
|
|
145
145
|
/ (self.conductance.current + self.backward_conductance.current)
|
|
146
146
|
)
|
|
147
147
|
|
|
148
|
+
@declares_internal_equation(VALVE_RL_BLOCK_FLUX_VAR_ID)
|
|
148
149
|
def flux_residual(self) -> Any:
|
|
149
150
|
"""
|
|
150
151
|
Compute the residual giving the dynamics on the flux in the valve.
|
|
@@ -168,6 +169,7 @@ class ValveRLBlock(Block):
|
|
|
168
169
|
+ q_mid_alpha / conductance
|
|
169
170
|
)
|
|
170
171
|
|
|
172
|
+
@flux_residual.partial_derivative(VALVE_RL_BLOCK_FLUX_VAR_ID)
|
|
171
173
|
def flux_residual_dflux(self) -> Any:
|
|
172
174
|
"""
|
|
173
175
|
Compute the residual partial derivative for ``flux``
|
|
@@ -187,6 +189,7 @@ class ValveRLBlock(Block):
|
|
|
187
189
|
+ (0.5 + self.scheme_ts_flux.current) / conductance
|
|
188
190
|
)
|
|
189
191
|
|
|
192
|
+
@flux_residual.partial_derivative(VALVE_RL_BLOCK_PRESSURE_1_DOF_ID)
|
|
190
193
|
def flux_residual_dp1(self) -> Any:
|
|
191
194
|
"""
|
|
192
195
|
Compute the residual partial derivative for ``pressure_1``
|
|
@@ -197,6 +200,7 @@ class ValveRLBlock(Block):
|
|
|
197
200
|
|
|
198
201
|
return -0.5
|
|
199
202
|
|
|
203
|
+
@flux_residual.partial_derivative(VALVE_RL_BLOCK_PRESSURE_2_DOF_ID)
|
|
200
204
|
def flux_residual_dp2(self) -> Any:
|
|
201
205
|
"""
|
|
202
206
|
Compute the residual partial derivative for ``pressure_2``
|
|
@@ -207,6 +211,7 @@ class ValveRLBlock(Block):
|
|
|
207
211
|
|
|
208
212
|
return 0.5
|
|
209
213
|
|
|
214
|
+
@declares_flux(1, VALVE_RL_BLOCK_PRESSURE_1_DOF_ID)
|
|
210
215
|
def flux_1(self) -> Any:
|
|
211
216
|
"""
|
|
212
217
|
Compute the block flux at node 1
|
|
@@ -217,6 +222,7 @@ class ValveRLBlock(Block):
|
|
|
217
222
|
"""
|
|
218
223
|
return -mid_point(self.flux)
|
|
219
224
|
|
|
225
|
+
@flux_1.partial_derivative(VALVE_RL_BLOCK_FLUX_VAR_ID)
|
|
220
226
|
def dflux_1_dflux(self) -> Any:
|
|
221
227
|
"""
|
|
222
228
|
Compute the block flux at node 1 partial derivative for ``flux``
|
|
@@ -227,6 +233,7 @@ class ValveRLBlock(Block):
|
|
|
227
233
|
"""
|
|
228
234
|
return -0.5
|
|
229
235
|
|
|
236
|
+
@declares_flux(2, VALVE_RL_BLOCK_PRESSURE_2_DOF_ID)
|
|
230
237
|
def flux_2(self) -> Any:
|
|
231
238
|
"""
|
|
232
239
|
Compute the block flux at node 2
|
|
@@ -236,6 +243,7 @@ class ValveRLBlock(Block):
|
|
|
236
243
|
"""
|
|
237
244
|
return mid_point(self.flux)
|
|
238
245
|
|
|
246
|
+
@flux_2.partial_derivative(VALVE_RL_BLOCK_FLUX_VAR_ID)
|
|
239
247
|
def dflux_2_dflux(self) -> Any:
|
|
240
248
|
"""
|
|
241
249
|
Compute the block flux at node 2 partial derivative for ``flux``
|
|
@@ -244,38 +252,3 @@ class ValveRLBlock(Block):
|
|
|
244
252
|
:rtype: np.float64
|
|
245
253
|
"""
|
|
246
254
|
return 0.5
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
# define the Valve RL internal variable residual expression
|
|
250
|
-
# giving the dynamics on the flux in the valve
|
|
251
|
-
_valve_rl_flux_residual_expr = Expression(
|
|
252
|
-
1,
|
|
253
|
-
ValveRLBlock.flux_residual,
|
|
254
|
-
{
|
|
255
|
-
VALVE_RL_BLOCK_FLUX_VAR_ID: ValveRLBlock.flux_residual_dflux,
|
|
256
|
-
VALVE_RL_BLOCK_PRESSURE_1_DOF_ID: ValveRLBlock.flux_residual_dp1,
|
|
257
|
-
VALVE_RL_BLOCK_PRESSURE_2_DOF_ID: ValveRLBlock.flux_residual_dp2,
|
|
258
|
-
},
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
# define the ValveRL flux expression at node 1.
|
|
262
|
-
_valve_rl_flux_1_expr = Expression(
|
|
263
|
-
1, ValveRLBlock.flux_1, {VALVE_RL_BLOCK_FLUX_VAR_ID: ValveRLBlock.dflux_1_dflux}
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
# define the ValveRL flux expression at node 2.
|
|
267
|
-
_valve_rl_flux_2_expr = Expression(
|
|
268
|
-
1,
|
|
269
|
-
ValveRLBlock.flux_2,
|
|
270
|
-
{VALVE_RL_BLOCK_FLUX_VAR_ID: ValveRLBlock.dflux_2_dflux},
|
|
271
|
-
)
|
|
272
|
-
|
|
273
|
-
ValveRLBlock.declares_internal_expression(
|
|
274
|
-
VALVE_RL_BLOCK_FLUX_VAR_ID, _valve_rl_flux_residual_expr
|
|
275
|
-
)
|
|
276
|
-
ValveRLBlock.declares_flux_expression(
|
|
277
|
-
1, VALVE_RL_BLOCK_PRESSURE_1_DOF_ID, _valve_rl_flux_1_expr
|
|
278
|
-
)
|
|
279
|
-
ValveRLBlock.declares_flux_expression(
|
|
280
|
-
2, VALVE_RL_BLOCK_PRESSURE_2_DOF_ID, _valve_rl_flux_2_expr
|
|
281
|
-
)
|
|
@@ -31,24 +31,36 @@ import numpy as np
|
|
|
31
31
|
from numpy.typing import NDArray
|
|
32
32
|
|
|
33
33
|
from physioblocks.computing import (
|
|
34
|
-
Expression,
|
|
35
34
|
ModelComponent,
|
|
36
35
|
Quantity,
|
|
37
36
|
diff,
|
|
38
37
|
mid_point,
|
|
39
38
|
)
|
|
39
|
+
from physioblocks.computing.models import declares_internal_equation
|
|
40
40
|
from physioblocks.registers import register_type
|
|
41
41
|
from physioblocks.simulation import Time
|
|
42
42
|
|
|
43
43
|
# Constant for the active law type id
|
|
44
44
|
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_TYPE_ID = "active_law_macro_huxley_two_moments"
|
|
45
45
|
|
|
46
|
+
# Constant for the active stiffness local id
|
|
47
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_STIFFNESS = "active_stiffness"
|
|
48
|
+
|
|
49
|
+
# Constant for the active energy sqrt local id
|
|
50
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_ENERGY_SQRT = "active_energy_sqrt"
|
|
51
|
+
|
|
52
|
+
# Constant for the active tension discretization local id
|
|
53
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_TENSION_DISCR = "active_tension_discr"
|
|
54
|
+
|
|
55
|
+
# Constant for the fiber deformation local id
|
|
56
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_FIB_DEFORM = "fib_deform"
|
|
57
|
+
|
|
46
58
|
|
|
47
59
|
@register_type(ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_TYPE_ID)
|
|
48
60
|
@dataclass
|
|
49
61
|
class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
50
62
|
r"""
|
|
51
|
-
Describes the Macroscopic Huxley Two Moment implementation of the
|
|
63
|
+
Describes the Macroscopic Huxley Two Moment implementation of the active law.
|
|
52
64
|
|
|
53
65
|
**Internal Equations:**
|
|
54
66
|
|
|
@@ -65,7 +77,7 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
65
77
|
|
|
66
78
|
\lambda_c - T_c/\sqrt{K_c} = 0
|
|
67
79
|
|
|
68
|
-
**
|
|
80
|
+
**Discretized:**
|
|
69
81
|
|
|
70
82
|
.. math::
|
|
71
83
|
|
|
@@ -90,7 +102,7 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
90
102
|
""":math:`\\lambda_c` the active energy sqrt"""
|
|
91
103
|
|
|
92
104
|
active_tension_discr: Quantity[np.float64]
|
|
93
|
-
""":math:`T_c^{n + \\frac{1}{2}\\sharp}` the active tension
|
|
105
|
+
""":math:`T_c^{n + \\frac{1}{2}\\sharp}` the active tension discretization"""
|
|
94
106
|
|
|
95
107
|
starling_abscissas: Quantity[NDArray[np.float64]]
|
|
96
108
|
"""Abscissas of :math:`n_0` the discretized starling function"""
|
|
@@ -113,6 +125,15 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
113
125
|
time: Time
|
|
114
126
|
""":math:`t` the simulation time"""
|
|
115
127
|
|
|
128
|
+
@declares_internal_equation(
|
|
129
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_STIFFNESS, 1, 0
|
|
130
|
+
)
|
|
131
|
+
@declares_internal_equation(
|
|
132
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_ENERGY_SQRT, 1, 1
|
|
133
|
+
)
|
|
134
|
+
@declares_internal_equation(
|
|
135
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_TENSION_DISCR, 1, 2
|
|
136
|
+
)
|
|
116
137
|
def active_law_residual(self) -> Any:
|
|
117
138
|
"""
|
|
118
139
|
Compute the residual of the active law.
|
|
@@ -166,6 +187,9 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
166
187
|
],
|
|
167
188
|
)
|
|
168
189
|
|
|
190
|
+
@active_law_residual.partial_derivative(
|
|
191
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_STIFFNESS
|
|
192
|
+
)
|
|
169
193
|
def active_law_residual_dactive_stiffness(self) -> Any:
|
|
170
194
|
"""
|
|
171
195
|
Compute the residual partial derivative for the active stiffness
|
|
@@ -219,6 +243,9 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
219
243
|
],
|
|
220
244
|
)
|
|
221
245
|
|
|
246
|
+
@active_law_residual.partial_derivative(
|
|
247
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_ENERGY_SQRT
|
|
248
|
+
)
|
|
222
249
|
def active_law_residual_dactive_energy_sqrt(self) -> Any:
|
|
223
250
|
"""
|
|
224
251
|
Compute the residual partial derivative for the active energy sqrt
|
|
@@ -264,6 +291,9 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
264
291
|
],
|
|
265
292
|
)
|
|
266
293
|
|
|
294
|
+
@active_law_residual.partial_derivative(
|
|
295
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_FIB_DEFORM
|
|
296
|
+
)
|
|
267
297
|
def active_law_residual_dfib_deform(self) -> Any:
|
|
268
298
|
"""
|
|
269
299
|
Compute the residual partial derivative for the fiber deformation
|
|
@@ -293,6 +323,9 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
293
323
|
],
|
|
294
324
|
)
|
|
295
325
|
|
|
326
|
+
@active_law_residual.partial_derivative(
|
|
327
|
+
ACTIVE_LAW_MACRO_HUXLEY_TWO_MOMENTS_ACTIVE_TENSION_DISCR
|
|
328
|
+
)
|
|
296
329
|
def active_law_residual_dactive_tension(self) -> Any:
|
|
297
330
|
"""
|
|
298
331
|
Compute the residual partial derivative for the active tension
|
|
@@ -310,36 +343,3 @@ class ActiveLawMacroscopicHuxleyTwoMoment(ModelComponent):
|
|
|
310
343
|
* np.fabs(diff(self.fib_deform))
|
|
311
344
|
* self.time.inv_dt
|
|
312
345
|
)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
# Define the expression for the residual of the ActiveLawMacroscopicHuxleyTwoMoment and
|
|
316
|
-
# its partial derivatives.
|
|
317
|
-
_active_law_macroscopic_huxley_two_moment_residual_expression = Expression(
|
|
318
|
-
3,
|
|
319
|
-
ActiveLawMacroscopicHuxleyTwoMoment.active_law_residual,
|
|
320
|
-
{
|
|
321
|
-
"active_stiffness": ActiveLawMacroscopicHuxleyTwoMoment.active_law_residual_dactive_stiffness, # noqa: E501
|
|
322
|
-
"active_energy_sqrt": ActiveLawMacroscopicHuxleyTwoMoment.active_law_residual_dactive_energy_sqrt, # noqa: E501
|
|
323
|
-
"active_tension_discr": ActiveLawMacroscopicHuxleyTwoMoment.active_law_residual_dactive_tension, # noqa: E501
|
|
324
|
-
"fib_deform": ActiveLawMacroscopicHuxleyTwoMoment.active_law_residual_dfib_deform, # noqa: E501
|
|
325
|
-
},
|
|
326
|
-
)
|
|
327
|
-
|
|
328
|
-
ActiveLawMacroscopicHuxleyTwoMoment.declares_internal_expression(
|
|
329
|
-
"active_stiffness",
|
|
330
|
-
_active_law_macroscopic_huxley_two_moment_residual_expression,
|
|
331
|
-
1,
|
|
332
|
-
0,
|
|
333
|
-
)
|
|
334
|
-
ActiveLawMacroscopicHuxleyTwoMoment.declares_internal_expression(
|
|
335
|
-
"active_energy_sqrt",
|
|
336
|
-
_active_law_macroscopic_huxley_two_moment_residual_expression,
|
|
337
|
-
1,
|
|
338
|
-
1,
|
|
339
|
-
)
|
|
340
|
-
ActiveLawMacroscopicHuxleyTwoMoment.declares_internal_expression(
|
|
341
|
-
"active_tension_discr",
|
|
342
|
-
_active_law_macroscopic_huxley_two_moment_residual_expression,
|
|
343
|
-
1,
|
|
344
|
-
2,
|
|
345
|
-
)
|
|
@@ -37,6 +37,7 @@ from typing import Any, TypeAlias
|
|
|
37
37
|
|
|
38
38
|
import numpy as np
|
|
39
39
|
from numpy.typing import NDArray
|
|
40
|
+
from rich.progress import Progress
|
|
40
41
|
|
|
41
42
|
from physioblocks.computing.assembling import EqSystem
|
|
42
43
|
from physioblocks.computing.models import ModelComponent
|
|
@@ -359,77 +360,82 @@ class ForwardSimulation(AbstractSimulation):
|
|
|
359
360
|
"""
|
|
360
361
|
# initialize the simulation and save the initial results
|
|
361
362
|
results = self._initialize()
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
363
|
+
progress_step_update = (
|
|
364
|
+
100.0 * self.time_manager.step_size / self.time_manager.duration
|
|
365
|
+
)
|
|
366
|
+
with Progress() as progress:
|
|
367
|
+
try:
|
|
368
|
+
sim_task = progress.add_task("Simulation in progress...")
|
|
369
|
+
while self.time_manager.ended is False:
|
|
370
|
+
next_step = self.time_manager.time.new
|
|
371
|
+
|
|
372
|
+
self._update_time()
|
|
373
|
+
|
|
374
|
+
while (
|
|
375
|
+
np.abs(next_step - self.time_manager.time.current)
|
|
376
|
+
> self.time_manager.min_step
|
|
377
|
+
):
|
|
378
|
+
self.state.reset_state_vector()
|
|
379
|
+
|
|
380
|
+
sol = self.solver.solve(self.state, self.eq_system)
|
|
381
|
+
|
|
382
|
+
if sol.converged is False:
|
|
383
|
+
inter_time = 0.5 * self.time_manager.current_step_size
|
|
384
|
+
if inter_time < self.time_manager.min_step:
|
|
385
|
+
raise ConvergenceError(
|
|
386
|
+
str.format(
|
|
387
|
+
"The solver did not converge at {0}s for "
|
|
388
|
+
"minimal time step {1}",
|
|
389
|
+
self.time_manager.time.current,
|
|
390
|
+
self.time_manager.min_step,
|
|
391
|
+
)
|
|
386
392
|
)
|
|
387
|
-
)
|
|
388
393
|
|
|
389
|
-
|
|
390
|
-
self.time_manager.time.update(
|
|
391
|
-
self.time_manager.time.current
|
|
392
|
-
+ self.time_manager.current_step_size
|
|
393
|
-
)
|
|
394
|
-
else:
|
|
395
|
-
self.state.set_state_vector(sol.x)
|
|
396
|
-
|
|
397
|
-
self.time_manager.update_time()
|
|
398
|
-
if (
|
|
399
|
-
np.abs(next_step - self.time_manager.time.current)
|
|
400
|
-
>= self.time_manager.min_step
|
|
401
|
-
):
|
|
402
|
-
self.time_manager.current_step_size = (
|
|
403
|
-
next_step - self.time_manager.time.current
|
|
404
|
-
)
|
|
405
|
-
self.time_manager.time.update(next_step)
|
|
406
|
-
else:
|
|
407
|
-
self.time_manager.time.initialize(next_step)
|
|
408
|
-
self.time_manager.current_step_size = (
|
|
409
|
-
self.time_manager.step_size
|
|
410
|
-
)
|
|
394
|
+
self.time_manager.current_step_size = inter_time
|
|
411
395
|
self.time_manager.time.update(
|
|
412
396
|
self.time_manager.time.current
|
|
413
397
|
+ self.time_manager.current_step_size
|
|
414
398
|
)
|
|
399
|
+
else:
|
|
400
|
+
self.state.set_state_vector(sol.x)
|
|
401
|
+
|
|
402
|
+
self.time_manager.update_time()
|
|
403
|
+
if (
|
|
404
|
+
np.abs(next_step - self.time_manager.time.current)
|
|
405
|
+
>= self.time_manager.min_step
|
|
406
|
+
):
|
|
407
|
+
self.time_manager.current_step_size = (
|
|
408
|
+
next_step - self.time_manager.time.current
|
|
409
|
+
)
|
|
410
|
+
self.time_manager.time.update(next_step)
|
|
411
|
+
else:
|
|
412
|
+
progress.update(sim_task, advance=progress_step_update)
|
|
413
|
+
self.time_manager.time.initialize(next_step)
|
|
414
|
+
self.time_manager.current_step_size = (
|
|
415
|
+
self.time_manager.step_size
|
|
416
|
+
)
|
|
417
|
+
self.time_manager.time.update(
|
|
418
|
+
self.time_manager.time.current
|
|
419
|
+
+ self.time_manager.current_step_size
|
|
420
|
+
)
|
|
415
421
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
422
|
+
self.state.set_state_vector(sol.x)
|
|
423
|
+
results.append(self._get_current_result())
|
|
424
|
+
except Exception as exception:
|
|
425
|
+
log_exception(
|
|
426
|
+
_logger,
|
|
427
|
+
type(exception),
|
|
428
|
+
exception,
|
|
429
|
+
exception.__traceback__,
|
|
430
|
+
logging.DEBUG,
|
|
431
|
+
)
|
|
432
|
+
raise SimulationError(
|
|
433
|
+
str.format(
|
|
434
|
+
"An error caused the simulation to stop prematurely",
|
|
435
|
+
intermediate_results=results,
|
|
436
|
+
),
|
|
437
|
+
results,
|
|
438
|
+
) from exception
|
|
433
439
|
|
|
434
440
|
self._finalize()
|
|
435
441
|
return results
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: physioblocks
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Dynamic: Author
|
|
5
5
|
Dynamic: Author-email
|
|
6
6
|
Dynamic: License
|
|
@@ -31,6 +31,7 @@ Requires-Dist: pandas
|
|
|
31
31
|
Requires-Dist: plotly
|
|
32
32
|
Requires-Dist: pyarrow
|
|
33
33
|
Requires-Dist: regex
|
|
34
|
+
Requires-Dist: rich
|
|
34
35
|
Requires-Dist: scipy
|
|
35
36
|
Provides-Extra: doc
|
|
36
37
|
Requires-Dist: sphinx; extra == 'doc'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
physioblocks/__init__.py,sha256=
|
|
1
|
+
physioblocks/__init__.py,sha256=NthjhG_G55GynSs5McIQOqRAVapELOh35oy3nf19u-E,1169
|
|
2
2
|
physioblocks/base/__init__.py,sha256=2h6bk0fe8pwQvJ15Buytg4SZzYOH-Ep7WqoD6pd1eOQ,986
|
|
3
3
|
physioblocks/base/operators.py,sha256=uUfswQZsaMNd2bd7wsaxSGFIYLAr1hQCQ6SQfYawdBc,5689
|
|
4
4
|
physioblocks/base/registers.py,sha256=Cd0hmy1XqojjPQgb_jn4mGeAMTyWWgDkl3qJHCVjCRU,3119
|
|
5
5
|
physioblocks/computing/__init__.py,sha256=rLjuzRCA0nVAnHcYsL0jhn2KQpl6MnC3DJLf3a0i6uw,1302
|
|
6
6
|
physioblocks/computing/assembling.py,sha256=2pKNA85PWJJ4fwSPRi7IitMdjlYTTiWQIgnKyhHja-8,9308
|
|
7
|
-
physioblocks/computing/models.py,sha256=
|
|
7
|
+
physioblocks/computing/models.py,sha256=3CbSsbvEvHg4dgHFF-I7UZSY3O9tg_SxYJcKjAAQdJs,33556
|
|
8
8
|
physioblocks/computing/quantities.py,sha256=f2wU0VDylJ8nuUtOsV0FsA1mJnqNy1AvoK6-w04Fctc,8934
|
|
9
9
|
physioblocks/configuration/__init__.py,sha256=XNeIev97Fc9DAy_mA3CAZ0kMif7Nkop9sCI38ZZ2wgM,1454
|
|
10
10
|
physioblocks/configuration/aliases.py,sha256=o7E54IYeW0NfmCX_r3zLKURVHsQoCmTlLD5085kY0eg,6302
|
|
@@ -25,7 +25,7 @@ physioblocks/description/nets.py,sha256=pKG2uB-4dABc-lvGswkybiho18bOkUwsVJYBdlX7
|
|
|
25
25
|
physioblocks/io/__init__.py,sha256=bOGWA0hAifT9wHxD4kWFQuAXpAx0GzDmGfmcgNDUCGo,990
|
|
26
26
|
physioblocks/io/aliases.py,sha256=d_Gqz0-8SVD6tA9N-T9xYL8SRhaSMmIOjqvOKHBb-Yo,2288
|
|
27
27
|
physioblocks/io/configuration.py,sha256=UY8whA_7KcMwi_gXPIt5h8_gD7TKO2Co5cyf9MHO0yg,3578
|
|
28
|
-
physioblocks/launcher/__main__.py,sha256=
|
|
28
|
+
physioblocks/launcher/__main__.py,sha256=BMErik5JIbCKmjZecQHMUUq5_GQeRQg8zLwYvHFelxk,8968
|
|
29
29
|
physioblocks/launcher/configuration.py,sha256=dqHCR_7PSDInA8NC3NFONqK3PPwSQYpLkZgYSyVU1vs,7959
|
|
30
30
|
physioblocks/launcher/constants.py,sha256=FIBKde1vJrUzMk9dSl4q8f8jqN7bFxYF05EIG2-V0zw,3033
|
|
31
31
|
physioblocks/launcher/files.py,sha256=zvif_8Woh3vEYCb_K3YnFFZYpgMhdlf4c2OSIVW4jC4,4950
|
|
@@ -51,9 +51,9 @@ physioblocks/library/aliases/simulations/newton_method_solver.json,sha256=p0jgVC
|
|
|
51
51
|
physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc,sha256=CXG5m8lRftbqYUchDedA_ggO81v1M0qiqyshRCMOl4E,5664
|
|
52
52
|
physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc,sha256=kCy065DN5Cau3d7ouuzdDAaLevBuzlnZkWtROG3DgtY,1542
|
|
53
53
|
physioblocks/library/blocks/__init__.py,sha256=EhnoyZYTooSd_cTfysnT-YR6Ylrn15dJsfWwALFV00I,991
|
|
54
|
-
physioblocks/library/blocks/capacitances.py,sha256
|
|
55
|
-
physioblocks/library/blocks/cavity.py,sha256=
|
|
56
|
-
physioblocks/library/blocks/valves.py,sha256=
|
|
54
|
+
physioblocks/library/blocks/capacitances.py,sha256=fMd-UXv4b4ggfOn1qjPj0xxR7q4Dk4-N7NKdIS_aVjc,13011
|
|
55
|
+
physioblocks/library/blocks/cavity.py,sha256=SgiBs4xeuIC1pXj_ZffEleA1Aw8AAvFdMKkf_I4IkCI,5632
|
|
56
|
+
physioblocks/library/blocks/valves.py,sha256=S-5uZ2jRE7r7zc24Lpl2ryNutH3OxPOHHI3AlDUpkgQ,7223
|
|
57
57
|
physioblocks/library/functions/__init__.py,sha256=k9cFPqrsApbeSkcnu-FbhonilTTeJS0Cp5EJCrfPeII,988
|
|
58
58
|
physioblocks/library/functions/base_operations.py,sha256=TpN7rabrX9Nojd2uu90j1Dw_7OpdjbBSuiM_HWzJH3M,3507
|
|
59
59
|
physioblocks/library/functions/first_order.py,sha256=oSkFyECA7ywgQCYKt-sEZmSu84QrRere_Ee736vk2Ik,3687
|
|
@@ -61,7 +61,7 @@ physioblocks/library/functions/piecewise.py,sha256=xpR22eP0Jkfuskc737uttenbpOOMX
|
|
|
61
61
|
physioblocks/library/functions/trigonometric.py,sha256=Y5UolXZTASEi4EH_GpLpUIxMZbXIVHc-THFEXg9vrtg,2126
|
|
62
62
|
physioblocks/library/functions/watchers.py,sha256=fY1SSPn-7R9cix0VMFP69H5-pmJzl4OXs1tgvjCetvM,3212
|
|
63
63
|
physioblocks/library/model_components/__init__.py,sha256=JcDL2PaPTrT9mTlDUbPjUsyFfsiGh5GgroJ7J3g2uwE,998
|
|
64
|
-
physioblocks/library/model_components/active_law.py,sha256=
|
|
64
|
+
physioblocks/library/model_components/active_law.py,sha256=EWVG6C13VxUydUKebDUqeKtEra0mbFwU0wfgIAEURmw,11692
|
|
65
65
|
physioblocks/library/model_components/dynamics.py,sha256=T-ZmfhTgtr1Tj6434GDYU-5XSztHx-dd6sf228c4cyo,35198
|
|
66
66
|
physioblocks/library/model_components/rheology.py,sha256=7x5RrB_0DXMWlm0mIrTxdLlsjXVa1WPuFYYifW4fKeg,4724
|
|
67
67
|
physioblocks/library/model_components/velocity_law.py,sha256=UYr9MywlLkRw0LszK0u_AamwThjobDMV9jYbaSbdDkU,5047
|
|
@@ -72,7 +72,7 @@ physioblocks/registers/type_register.py,sha256=JUlrPfP-X_TjIOHewSTkzf7Ck3L0ivVoH
|
|
|
72
72
|
physioblocks/simulation/__init__.py,sha256=wqKVI3OLLVWuQoUcWwKSs5ibdkTP3Da_5DOe36v1up4,1504
|
|
73
73
|
physioblocks/simulation/constants.py,sha256=w9CsB4V7YtvcdW4N1p7Iu6MeV4i-kazcEPAygE7mSx0,1075
|
|
74
74
|
physioblocks/simulation/functions.py,sha256=c6HFwXK8IAzH7gSkz9aMiXLqnWXn_4_9WsX4jrGN9pY,2307
|
|
75
|
-
physioblocks/simulation/runtime.py,sha256=
|
|
75
|
+
physioblocks/simulation/runtime.py,sha256=Moa6S1iR7oPuni8yvO7VwmBsubMcJMpIUeowk1BLaC0,16104
|
|
76
76
|
physioblocks/simulation/saved_quantities.py,sha256=fKWr1wScqxHPhuCE7aDNs8lpm9oWfyLN8NZDus2knPM,4111
|
|
77
77
|
physioblocks/simulation/setup.py,sha256=UmIklaHmfkxi_BIdYKOhorLoC9QT9D4oEXwC-Xfd6v0,18109
|
|
78
78
|
physioblocks/simulation/solvers.py,sha256=xztL-QboEO2mgtws13QE0-wHJ22vjQQzAQahYfxXVBQ,7226
|
|
@@ -86,8 +86,8 @@ physioblocks/utils/math_utils.py,sha256=w5MDs4cP5WiTPHe8WofFuNZZ20WDNLT0XmFGlbis
|
|
|
86
86
|
physioblocks/references/circulation_alone_sim.jsonc,sha256=qv27nzmK7jennhtCJ7wQ_f83mt9_YJSOTABjGCYMcZw,736
|
|
87
87
|
physioblocks/references/spherical_heart_respiration_sim.jsonc,sha256=kKq5xf94r90O1KpkCHk1qwgy6DJ37ePo3-8buEtcu5Y,1397
|
|
88
88
|
physioblocks/references/spherical_heart_sim.jsonc,sha256=kGGBqxY8dnmGKmpMv216kbneyJRGz_3VkcYn1OWavIA,1151
|
|
89
|
-
physioblocks-1.
|
|
90
|
-
physioblocks-1.
|
|
91
|
-
physioblocks-1.
|
|
92
|
-
physioblocks-1.
|
|
93
|
-
physioblocks-1.
|
|
89
|
+
physioblocks-1.1.1.dist-info/METADATA,sha256=eDM0OMOHOexQxV_g4XMTCVcr9eJQYFoHVkqzSZ4O5Hk,4728
|
|
90
|
+
physioblocks-1.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
91
|
+
physioblocks-1.1.1.dist-info/licenses/licenses/GPL-3.0-only.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
92
|
+
physioblocks-1.1.1.dist-info/licenses/licenses/LGPL-3.0-only.txt,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
93
|
+
physioblocks-1.1.1.dist-info/RECORD,,
|
|
File without changes
|
{physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/licenses/licenses/GPL-3.0-only.txt
RENAMED
|
File without changes
|
{physioblocks-1.0.3.dist-info → physioblocks-1.1.1.dist-info}/licenses/licenses/LGPL-3.0-only.txt
RENAMED
|
File without changes
|