Coverage for physioblocks / simulation / saved_quantities.py: 82%
33 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-09 16:40 +0100
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-09 16:40 +0100
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/>.
27"""
28Define a register to hold **SavedQuantities** during the simulation.
29"""
31from __future__ import annotations
33from collections.abc import Generator
34from typing import Any
36from physioblocks.computing.models import Expression, ModelComponent
37from physioblocks.computing.quantities import Quantity
40class SavedQuantities:
41 """
42 Register holding saved quantities.
43 """
45 _saved_quantities: dict[str, Quantity[Any]]
46 _quantities_expressions: dict[str, tuple[Expression, ModelComponent, int, int]]
48 def __init__(self) -> None:
49 self._saved_quantities = {}
50 self._quantities_expressions = {}
52 def __contains__(self, quantity_id: str) -> bool:
53 return quantity_id in self._saved_quantities
55 def __getitem__(self, quantity_id: str) -> Quantity[Any]:
56 """
57 Get the saved quantity
59 :param quantity_id: the quantity global name.
60 :type quantity_id: str
62 :return: the saved quantity
63 :rtype: Quantity
64 """
65 return self._saved_quantities[quantity_id]
67 def items(self) -> Generator[tuple[str, Quantity[Any]], None, None]:
68 yield from self._saved_quantities.items()
70 def values(self) -> Generator[Quantity[Any], None, None]:
71 yield from self._saved_quantities.values()
73 def __iter__(self) -> Generator[str, None, None]:
74 yield from self._saved_quantities
76 def update(self) -> None:
77 """
78 Update all saved quantities using their
79 :class:`~physioblocks.computing.models.Expression` object.
80 """
81 for quantity_id, (
82 expression,
83 model,
84 size,
85 index,
86 ) in self._quantities_expressions.items():
87 if size == 1:
88 self._saved_quantities[quantity_id].initialize(
89 expression.expr_func(model)
90 )
91 else:
92 self._saved_quantities[quantity_id].initialize(
93 expression.expr_func(model)[index : index + size] # type: ignore
94 )
96 def register(
97 self,
98 quantity_id: str,
99 expression: Expression,
100 model: ModelComponent,
101 size: int,
102 index: int,
103 ) -> None:
104 """
105 Register a **Saved Quantity** with its expression and model.
107 :param quantity_id: the global saved quantity name
108 :type quantity_id: str
110 :param expression: the expression to use for the quantity
111 :type expression: Expression
113 :param model: the model declaring the expression
114 :type model: ModelComponent
115 """
116 self._quantities_expressions[quantity_id] = (expression, model, size, index)
117 # initialise quantity to 0
118 init_value = [0.0] * size if size > 1 else 0.0
119 self._saved_quantities[quantity_id] = Quantity(init_value)
121 def unregister(self, quantity_id: str) -> None:
122 """
123 Unregister a saved quantity
125 :param quantity_id: the quantity global name to unregister
126 :type quantity_id: str
127 """
128 self._saved_quantities.pop(quantity_id)
129 self._quantities_expressions.pop(quantity_id)