omotes-simulator-core 0.0.3.dev0__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 (59) hide show
  1. omotes_simulator_core-0.0.3.dev0.dist-info/LICENSE +621 -0
  2. omotes_simulator_core-0.0.3.dev0.dist-info/METADATA +55 -0
  3. omotes_simulator_core-0.0.3.dev0.dist-info/RECORD +59 -0
  4. omotes_simulator_core-0.0.3.dev0.dist-info/WHEEL +5 -0
  5. omotes_simulator_core-0.0.3.dev0.dist-info/top_level.txt +1 -0
  6. simulator_core/__init__.py +15 -0
  7. simulator_core/__main__.py +21 -0
  8. simulator_core/adapter/__init__.py +16 -0
  9. simulator_core/adapter/presentation/__init__.py +16 -0
  10. simulator_core/adapter/transforms/__init__.py +16 -0
  11. simulator_core/adapter/transforms/esdl_asset_mapper.py +53 -0
  12. simulator_core/adapter/transforms/mappers.py +226 -0
  13. simulator_core/adapter/transforms/string_to_esdl.py +66 -0
  14. simulator_core/adapter/transforms/transform_utils.py +34 -0
  15. simulator_core/entities/__init__.py +16 -0
  16. simulator_core/entities/assets/__init__.py +16 -0
  17. simulator_core/entities/assets/asset_abstract.py +116 -0
  18. simulator_core/entities/assets/asset_defaults.py +68 -0
  19. simulator_core/entities/assets/controller_classes.py +81 -0
  20. simulator_core/entities/assets/demand_cluster.py +117 -0
  21. simulator_core/entities/assets/esdl_asset_object.py +60 -0
  22. simulator_core/entities/assets/junction.py +64 -0
  23. simulator_core/entities/assets/pipe.py +174 -0
  24. simulator_core/entities/assets/production_cluster.py +222 -0
  25. simulator_core/entities/assets/utils.py +154 -0
  26. simulator_core/entities/esdl_object.py +90 -0
  27. simulator_core/entities/heat_network.py +82 -0
  28. simulator_core/entities/network_controller.py +67 -0
  29. simulator_core/entities/simulation_configuration.py +31 -0
  30. simulator_core/entities/utility/__init__.py +16 -0
  31. simulator_core/entities/utility/influxdb_reader.py +129 -0
  32. simulator_core/infrastructure/__init__.py +16 -0
  33. simulator_core/infrastructure/app.py +55 -0
  34. simulator_core/infrastructure/simulation_manager.py +55 -0
  35. simulator_core/infrastructure/utils.py +45 -0
  36. simulator_core/py.typed +0 -0
  37. simulator_core/simulation/__init__.py +18 -0
  38. simulator_core/simulation/mappers/__init__.py +16 -0
  39. simulator_core/simulation/mappers/mappers.py +35 -0
  40. simulator_core/simulation/networksimulation.py +63 -0
  41. simulator_core/solver/__init__.py +15 -0
  42. simulator_core/solver/matrix/__init__.py +15 -0
  43. simulator_core/solver/matrix/core_enum.py +26 -0
  44. simulator_core/solver/matrix/equation_object.py +56 -0
  45. simulator_core/solver/matrix/matrix.py +125 -0
  46. simulator_core/solver/matrix/utility.py +38 -0
  47. simulator_core/solver/network/__init__.py +15 -0
  48. simulator_core/solver/network/assets/__init__.py +15 -0
  49. simulator_core/solver/network/assets/base_asset.py +303 -0
  50. simulator_core/solver/network/assets/base_item.py +63 -0
  51. simulator_core/solver/network/assets/base_node_item.py +67 -0
  52. simulator_core/solver/network/assets/boundary.py +83 -0
  53. simulator_core/solver/network/assets/fall_type.py +225 -0
  54. simulator_core/solver/network/assets/node.py +274 -0
  55. simulator_core/solver/network/assets/production_asset.py +171 -0
  56. simulator_core/solver/network/assets/solver_pipe.py +541 -0
  57. simulator_core/solver/network/network.py +398 -0
  58. simulator_core/solver/solver.py +80 -0
  59. simulator_core/solver/utils/fluid_properties.py +173 -0
@@ -0,0 +1,125 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ """Module containing a matrix class to store the matrix and solve it using numpy."""
16
+ import numpy as np
17
+ import csv
18
+ from simulator_core.solver.matrix.equation_object import EquationObject
19
+ from simulator_core.solver.matrix.utility import absolute_difference, relative_difference
20
+
21
+
22
+ class Matrix:
23
+ """Class which stores the matrix and can be used to solve it."""
24
+
25
+ def __init__(self) -> None:
26
+ """Constructor of matrix class."""
27
+ self.num_unknowns: int = 0
28
+ self.mat: list[list[float]] = []
29
+ self.rhs: list[float] = []
30
+ self.sol_new: list[float] = []
31
+ self.sol_old: list[float] = []
32
+ self.relative_convergence: float = 1e-6
33
+ self.absolute_convergence: float = 1e-6
34
+
35
+ def add_unknowns(self, number_unknowns: int) -> int:
36
+ """Method to add unknowns to the matrix.
37
+
38
+ Adds unknowns to the matrix and returns the location of the unknowns in the solution.
39
+ :param int number_unknowns: Number of unknowns to add
40
+ :return: int Starting index of the added unknowns.
41
+ """
42
+ if number_unknowns < 1:
43
+ raise ValueError("Number of unknowns should be at least 1.")
44
+ self.num_unknowns += number_unknowns
45
+ self.sol_new += [1.0] * number_unknowns
46
+ self.sol_old += [0.0] * number_unknowns
47
+ return self.num_unknowns - number_unknowns
48
+
49
+ def add_equation(self, equation_object: EquationObject) -> None:
50
+ """Method to add an equation to the matrix.
51
+
52
+ Add equation to the matrix it returns a unique id to the equation for easy access.
53
+ :param EquationObject equation_object: Object containing all information of the equation
54
+ :return:
55
+ """
56
+ row = len(self.rhs)
57
+ self.rhs.append(0.0)
58
+ self.mat.append([])
59
+ self.mat[row] = equation_object.to_list(self.num_unknowns)
60
+ self.rhs[row] = equation_object.rhs
61
+
62
+ def solve(self, equations: list[EquationObject], dumb: bool = False) -> list[float]:
63
+ """Method to solve the system of equation given in the matrix.
64
+
65
+ Solves the system of equations and returns the solution. The numpy linalg
66
+ library solve method is used. For this the matrix is converted to np arrays.
67
+ :return: list containing the solution of the system of equations.
68
+ """
69
+ # TODO add checks if enough equations have been supplied.
70
+ # TODO check if matrix is solvable.
71
+ self.rhs = []
72
+ self.mat = []
73
+ for equation in equations:
74
+ self.add_equation(equation)
75
+ if dumb:
76
+ self.dump_matrix()
77
+ self.sol_old = self.sol_new
78
+ a = np.array(self.mat)
79
+ b = np.array(self.rhs)
80
+ self.sol_new = np.linalg.solve(a, b).tolist()
81
+ return self.sol_new
82
+
83
+ def is_converged(self) -> bool:
84
+ """Returns true when the solution has converged and false when not.
85
+
86
+ This method uses both the absolute difference and the relative difference to determine if
87
+ the solution has converged. If one of them is converged true is returned.
88
+ :return: Bool whether the solution has converged based on the given convergence criteria.
89
+ """
90
+ if self.num_unknowns == 0:
91
+ raise ValueError("No unknowns have been added to the matrix.")
92
+ rel_dif = max(
93
+ [relative_difference(old, new) for old, new in zip(self.sol_old, self.sol_new)])
94
+ abs_dif = max(
95
+ [absolute_difference(old, new) for old, new in zip(self.sol_old, self.sol_new)])
96
+ return rel_dif < self.relative_convergence or abs_dif < self.absolute_convergence
97
+
98
+ def get_solution(self, index: int, number_of_unknowns: int) -> list[float]:
99
+ """Method to get the solution of an asset.
100
+
101
+ Returns the solution starting at the given index and for the number of
102
+ unknowns supplied at the input.
103
+
104
+ :param int index:Start position for which to supply the solution
105
+ :param int number_of_unknowns: Number of elements for which the solution needs to
106
+ be provided
107
+ :return: list with teh solution
108
+ """
109
+ # TODO add checks if the index and number of unknowns are within the range of the solution.
110
+ return self.sol_new[index:index + number_of_unknowns]
111
+
112
+ def dump_matrix(self, file_name: str = 'dump.csv') -> None:
113
+ """Method to dump the matrix to a csv file.
114
+
115
+ :param str file_name: File name to dump the matrix in default=dump.csv
116
+ :return:
117
+ """
118
+ with open(file_name, 'w', newline='') as f:
119
+ write = csv.writer(f)
120
+ for row, rhs in zip(self.mat, self.rhs):
121
+ write.writerow(row + [rhs])
122
+
123
+ def reset_solution(self) -> None:
124
+ """Method to reset the solution to 1, so the new iteration can start."""
125
+ self.sol_new = [1.0] * len(self.sol_new)
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ """module containing utility functions for the matrix."""
16
+
17
+
18
+ def relative_difference(value_1: float, value_2: float) -> float:
19
+ """Calculates the relative difference between two points.
20
+
21
+ :param value_1: first value to be used
22
+ :param value_2: second value to be used
23
+ :return: Relative difference, return 0 when the difference is 0.
24
+ """
25
+ diff = absolute_difference(value_1, value_2)
26
+ if diff > 0.0:
27
+ return diff / max(abs(value_1), abs(value_2))
28
+ return 0.0
29
+
30
+
31
+ def absolute_difference(value_1: float, value_2: float) -> float:
32
+ """Calculates the absolute difference between two points.
33
+
34
+ :param value_1: first value to be used
35
+ :param value_2: second value to be used
36
+ :return: Absolute difference between value 1 and 2
37
+ """
38
+ return abs(value_1 - value_2)
@@ -0,0 +1,15 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ """__init__.py file for initialization code."""
@@ -0,0 +1,15 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ """__init__.py file for initialization code."""
@@ -0,0 +1,303 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+
16
+ """Module containing BaseAsset class."""
17
+ import math
18
+ import uuid
19
+ from typing import Dict
20
+
21
+ import numpy as np
22
+
23
+ from simulator_core.solver.matrix.core_enum import NUMBER_CORE_QUANTITIES, IndexEnum
24
+ from simulator_core.solver.matrix.equation_object import EquationObject
25
+ from simulator_core.solver.network.assets.base_item import BaseItem
26
+ from simulator_core.solver.network.assets.base_node_item import BaseNodeItem
27
+ from simulator_core.solver.utils.fluid_properties import fluid_props
28
+
29
+
30
+ class BaseAsset(BaseItem):
31
+ """A base class for assets in a network.
32
+
33
+ This class inherits from BaseItem and provides methods for connecting nodes, checking connection
34
+ status, and adding thermal and pressure equations.
35
+ """
36
+
37
+ connected_nodes: Dict[int, BaseNodeItem]
38
+
39
+ def __init__(
40
+ self,
41
+ name: uuid.UUID,
42
+ number_of_unknowns: int = 6,
43
+ number_connection_points: int = 2,
44
+ supply_temperature: float = 293.15,
45
+ ):
46
+ """Initializes the BaseAsset object with the given parameters.
47
+
48
+ :param uuid.UUID name: The unique identifier of the node.
49
+ :param int, optional number_of_unknowns: The number of unknown variables for the node.
50
+ The default is 3.
51
+ :param int, optional number_connection_points: The number of connection points for the
52
+ asset. The default is 2, which corresponds to the inlet and outlet.
53
+ """
54
+ super().__init__(
55
+ name=name,
56
+ number_of_unknowns=number_of_unknowns,
57
+ number_connection_points=number_connection_points,
58
+ )
59
+ self.supply_temperature = supply_temperature
60
+ self.connected_nodes = {}
61
+
62
+ def check_connection_point_valid(self, connection_point: int) -> bool:
63
+ """Checks if the connection point is valid for the asset.
64
+
65
+ :param connection_point: The index of the connection point to check.
66
+ :type connection_point: int
67
+ :return: True if the connection point is valid, otherwise raises an IndexError.
68
+ :rtype: bool
69
+ """
70
+ if connection_point > self.number_of_connection_point - 1:
71
+ raise IndexError(
72
+ f"Asset {self.name} only has {self.number_of_connection_point - 1}. "
73
+ f"{connection_point} is too high"
74
+ )
75
+ else:
76
+ return True
77
+
78
+ def connect_node(self, connection_point: int, node: BaseNodeItem) -> None:
79
+ """Connects a node to a connection point of the asset.
80
+
81
+ :param connection_point: The index of the connection point to connect.
82
+ :type connection_point: int
83
+ :param node: The node to connect.
84
+ :type node: Node
85
+ :raises ValueError: If the connection point is already connected to a node.
86
+ """
87
+ self.check_connection_point_valid(connection_point)
88
+ if connection_point in self.connected_nodes:
89
+ raise ValueError(
90
+ f" connection point {connection_point} of asset {self.name} "
91
+ f" already connected to a node"
92
+ )
93
+
94
+ self.connected_nodes[connection_point] = node
95
+
96
+ def disconnect_node(self, connection_point: int) -> None:
97
+ """Disconnects a node from a connection point of the asset.
98
+
99
+ :param connection_point: The index of the connection point to disconnect.
100
+ :type connection_point: int
101
+ :raises ValueError: If the connection point is not connected to a node.
102
+ """
103
+ self.check_connection_point_valid(connection_point)
104
+ del self.connected_nodes[connection_point]
105
+
106
+ def is_connected(self, connection_point: int) -> bool:
107
+ """Checks if a connection point is connected to a node.
108
+
109
+ :param connection_point: The index of the connection point to check.
110
+ :type connection_point: int
111
+ :return: True if the connection point is connected, False otherwise.
112
+ :rtype: bool
113
+ """
114
+ if self.check_connection_point_valid(connection_point):
115
+ return connection_point in self.connected_nodes
116
+ else:
117
+ return False
118
+
119
+ def get_connected_node(self, connection_point: int) -> BaseNodeItem:
120
+ """Checks if a connection point is connected to a node.
121
+
122
+ :param connection_point: The index of the connection point to check.
123
+ :type connection_point: int
124
+ :return: True if the connection point is connected, False otherwise.
125
+ :rtype: bool
126
+ """
127
+ self.check_connection_point_valid(connection_point)
128
+
129
+ if self.is_connected(connection_point):
130
+ return self.connected_nodes[connection_point]
131
+ raise ValueError(str(connection_point) + " is not connected")
132
+
133
+ def is_all_connected(self) -> bool:
134
+ """Checks if all connection points are connected to nodes.
135
+
136
+ :return: True if all connection points are connected, False otherwise.
137
+ :rtype: bool
138
+ """
139
+ result = [self.is_connected(i) for i in range(self.number_of_connection_point)]
140
+ return all(result)
141
+
142
+ def add_thermal_equations(self, connection_point: int) -> EquationObject:
143
+ """Adds a thermal equation for a connection point of the asset.
144
+
145
+ :param connection_point: The index of the connection point to add the equation for.
146
+ :type connection_point: int
147
+ :return: An equation object representing the thermal equation.
148
+ :rtype: EquationObject
149
+ """
150
+ if self.prev_sol[IndexEnum.discharge + connection_point * NUMBER_CORE_QUANTITIES] > 0:
151
+ return self.add_prescribe_temp(connection_point)
152
+ else:
153
+ return self.add_temp_to_node_equation(connection_point)
154
+
155
+ def add_prescribe_temp(self, connection_point: int) -> EquationObject:
156
+ """Adds a prescribed temperature equation for a connection point of the asset.
157
+
158
+ :param connection_point: The index of the connection point to add the equation for.
159
+ :type connection_point: int
160
+ :return: An equation object representing the prescribed temperature equation.
161
+ :rtype: EquationObject
162
+ """
163
+ if not self.is_connected(connection_point=connection_point):
164
+ raise ValueError(
165
+ f"Connection point {connection_point} of asset {self.name} is not connected to a"
166
+ + " node."
167
+ )
168
+ equation_object = EquationObject()
169
+ equation_object.indices = np.array(
170
+ [
171
+ self.matrix_index
172
+ + IndexEnum.internal_energy
173
+ + connection_point * NUMBER_CORE_QUANTITIES
174
+ ]
175
+ )
176
+ equation_object.coefficients = np.array([1.0])
177
+ equation_object.rhs = fluid_props.get_ie(self.supply_temperature)
178
+ return equation_object
179
+
180
+ def add_temp_to_node_equation(self, connection_point: int) -> EquationObject:
181
+ """Adds a temperature to node equation for a connection point of the asset.
182
+
183
+ :param connection_point: The index of the connection point to add the equation for.
184
+ :type connection_point: int
185
+ :return: An equation object representing the temperature to node equation.
186
+ :rtype: EquationObject
187
+ """
188
+ # Check if the connection point is connected to a node
189
+ if not self.is_connected(connection_point=connection_point):
190
+ raise ValueError(
191
+ f"Connection point {connection_point} of asset {self.name} is not connected to a"
192
+ + " node."
193
+ )
194
+
195
+ equation_object = EquationObject()
196
+ equation_object.indices = np.array(
197
+ [
198
+ self.matrix_index
199
+ + IndexEnum.internal_energy
200
+ + connection_point * NUMBER_CORE_QUANTITIES,
201
+ self.get_connected_node(connection_point).matrix_index + IndexEnum.internal_energy,
202
+ ]
203
+ )
204
+ equation_object.coefficients = np.array([1.0, -1.0])
205
+ equation_object.rhs = 0.0
206
+ return equation_object
207
+
208
+ def set_physical_properties(self, physical_properties: Dict[str, float]) -> None:
209
+ """Method to set the physical properties of the asset.
210
+
211
+ This method is implemented in the derived classes of this class.
212
+ """
213
+
214
+ def add_press_to_node_equation(self, connection_point: int) -> EquationObject:
215
+ """Adds a pressure to node equation for a connection point of the asset.
216
+
217
+ :param connection_point: The index of the connection point to add the equation for.
218
+ :type connection_point: int
219
+ :return: An equation object representing the pressure to node equation.
220
+ :rtype: EquationObject
221
+ """
222
+ # Check if the connection point is connected to a node
223
+ if not self.is_connected(connection_point=connection_point):
224
+ raise ValueError(
225
+ f"Connection point {connection_point} of asset {self.name} is not connected to a"
226
+ + " node."
227
+ )
228
+
229
+ equation_object = EquationObject()
230
+ equation_object.indices = np.array(
231
+ [
232
+ self.matrix_index + IndexEnum.pressure + connection_point * NUMBER_CORE_QUANTITIES,
233
+ self.connected_nodes[connection_point].matrix_index + IndexEnum.pressure,
234
+ ]
235
+ )
236
+ equation_object.coefficients = np.array([1.0, -1.0])
237
+ equation_object.rhs = 0.0
238
+ return equation_object
239
+
240
+ def get_result(self) -> list[float]:
241
+ """Method to get the result of the asset.
242
+
243
+ :return: a list of the unknowns which are solved.
244
+ """
245
+ results = []
246
+ for i in range(self.number_of_connection_point):
247
+ for j in range(math.floor(self.number_of_unknowns / self.number_of_connection_point)):
248
+ if j == 2:
249
+ results.append(
250
+ fluid_props.get_t(
251
+ self.prev_sol[
252
+ i
253
+ * math.floor(
254
+ self.number_of_unknowns / self.number_of_connection_point
255
+ )
256
+ + j
257
+ ]
258
+ )
259
+ )
260
+ else:
261
+ results.append(
262
+ self.prev_sol[
263
+ i
264
+ * math.floor(self.number_of_unknowns / self.number_of_connection_point)
265
+ + j
266
+ ]
267
+ )
268
+ return results
269
+
270
+ def get_equations(self) -> list[EquationObject]:
271
+ """Method to get the equations of the asset.
272
+
273
+ This method is implemented in the derived classes of this class.
274
+
275
+ :return: A list of equation objects representing the equations of the asset.
276
+ """
277
+ return []
278
+
279
+ def get_mass_flow_rate(self, connection_point: int) -> float:
280
+ """Method to get the mass flow rate of a connection point.
281
+
282
+ :param int connection_point: The connection point for which to get the mass flow rate.
283
+ :return: The mass flow rate of the connection point.
284
+ """
285
+ return self.prev_sol[IndexEnum.discharge + connection_point * NUMBER_CORE_QUANTITIES]
286
+
287
+ def get_pressure(self, connection_point: int) -> float:
288
+ """Method to get the pressure of a connection point.
289
+
290
+ :param int connection_point: The connection point for which to get the pressure.
291
+ :return: The pressure of the connection point.
292
+ """
293
+ return self.prev_sol[IndexEnum.pressure + connection_point * NUMBER_CORE_QUANTITIES]
294
+
295
+ def get_temperature(self, connection_point: int) -> float:
296
+ """Method to get the temperature of a connection point.
297
+
298
+ :param int connection_point: The connection point for which to get the temperature.
299
+ :return: The temperature of the connection point.
300
+ """
301
+ return fluid_props.get_t(
302
+ self.prev_sol[IndexEnum.internal_energy + connection_point * NUMBER_CORE_QUANTITIES]
303
+ )
@@ -0,0 +1,63 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+
16
+ """Module containing abstract BaseItem class."""
17
+ import uuid
18
+ from abc import ABC, abstractmethod
19
+
20
+ from simulator_core.solver.matrix.equation_object import EquationObject
21
+
22
+
23
+ class BaseItem(ABC):
24
+ """A base class for items in a network."""
25
+
26
+ def __init__(self, number_of_unknowns: int, name: uuid.UUID, number_connection_points: int):
27
+ """Initializes the BaseItem object with the given parameters.
28
+
29
+ :param int number_of_unknowns: The number of unknown variables for the item.
30
+ :param uuid.UUID name: The unique identifier of the item.
31
+ :param int number_connection_points: The number of connection points of the item.
32
+ """
33
+ self.name = name
34
+ self.number_of_unknowns = number_of_unknowns
35
+ self.number_of_connection_point = number_connection_points
36
+ self.matrix_index = 0
37
+ self.prev_sol: list[float] = [0.0] * self.number_of_unknowns
38
+
39
+ def __repr__(self) -> str:
40
+ """Returns the string representation of the item."""
41
+ return str(self.name)
42
+
43
+ def set_matrix_index(self, index: int) -> None:
44
+ """Sets the matrix index of the item.
45
+
46
+ :param int index: The index of the item in the matrix.
47
+ """
48
+ self.matrix_index = index
49
+
50
+ @abstractmethod
51
+ def get_equations(self) -> list[EquationObject]:
52
+ """Returns the equations for the item.
53
+
54
+ :return: The equations for the item.
55
+ :rtype: list[EquationObject]
56
+ """
57
+
58
+ @abstractmethod
59
+ def disconnect_node(self, connection_point: int) -> None:
60
+ """Disconnects a node from the item.
61
+
62
+ :param int connection_point: The connection point to disconnect.
63
+ """
@@ -0,0 +1,67 @@
1
+ # Copyright (c) 2023. Deltares & TNO
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+
16
+ """Module containing abstract BaseNodeItem class."""
17
+ import uuid
18
+ from abc import ABC, abstractmethod
19
+
20
+ from simulator_core.solver.matrix.equation_object import EquationObject
21
+ from simulator_core.solver.network.assets.base_item import BaseItem
22
+
23
+
24
+ class BaseNodeItem(ABC):
25
+ """A base class for node items in a network."""
26
+
27
+ def __init__(self, number_of_unknowns: int, name: uuid.UUID):
28
+ """Initializes the BaseNodeItem object with the given parameters.
29
+
30
+ :param int number_of_unknowns: The number of unknown variables for the item.
31
+ :param uuid.UUID name: The unique identifier of the item.
32
+ """
33
+ self.name = name
34
+ self.number_of_unknowns = number_of_unknowns
35
+ self.matrix_index = 0
36
+ self.prev_sol: list[float] = [0.0] * self.number_of_unknowns
37
+
38
+ def set_matrix_index(self, index: int) -> None:
39
+ """Sets the matrix index of the item.
40
+
41
+ :param int index: The index of the item in the matrix.
42
+ """
43
+ self.matrix_index = index
44
+
45
+ @abstractmethod
46
+ def get_equations(self) -> list[EquationObject]:
47
+ """Returns the equations for the item.
48
+
49
+ :return: The equations for the item.
50
+ :rtype: list[EquationObject]
51
+ """
52
+
53
+ @abstractmethod
54
+ def connect_asset(self, asset: BaseItem, connection_point: int) -> None:
55
+ """Connects the asset to the node item.
56
+
57
+ :param BaseItem asset: The asset to connect to the node item.
58
+ :param int connection_point: The connection point of the asset to connect to.
59
+ """
60
+
61
+ @abstractmethod
62
+ def get_connected_assets(self) -> list[tuple[BaseItem, int]]:
63
+ """Returns the connected assets of the node item.
64
+
65
+ :return: The connected assets of the node item.
66
+ :rtype: Tuple[BaseItem, int]
67
+ """