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,129 @@
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 to read the esdl profiles from an energy system."""
17
+ from esdl.profiles.influxdbprofilemanager import InfluxDBProfileManager
18
+ from esdl.units.conversion import ENERGY_IN_J, POWER_IN_W, convert_to_unit
19
+ import esdl
20
+ from esdl.esdl_handler import EnergySystemHandler
21
+ from typing import Dict, Tuple
22
+ import pandas as pd
23
+
24
+
25
+ def parse_esdl_profiles(esh: EnergySystemHandler) -> Dict[str, pd.DataFrame]:
26
+ """Method to parse the esdl profiles from an energy system.
27
+
28
+ This method tries to parse the esdl profiles from an energy system.
29
+ :param esh: EnergySystemHandler with the energy system
30
+ :param start_date: datetime.datetime with the start date
31
+ :param end_date: datetime.datetime with the end date
32
+ :return: dict with the parsed profiles
33
+ """
34
+ data_set = {}
35
+ for profile in esh.get_all_instances_of_type(esdl.InfluxDBProfile):
36
+ data_set[profile.id] = get_data_from_profile(profile)
37
+ return data_set
38
+
39
+
40
+ def get_data_from_profile(esdl_profile: esdl.InfluxDBProfile) -> pd.DataFrame:
41
+ """Method to get the data from the esdl influxdb profile.
42
+
43
+ This method tries to get the data from the esdl profile.
44
+ :param esdl_profile: esdl.Profile with the profile
45
+ :return: pandas.DataFrame with the data
46
+ """
47
+ influx_cred_map: Dict[str, Tuple[str, str]] = {}
48
+ profile_host = esdl_profile.host
49
+ ssl_setting = False
50
+ if "https" in profile_host:
51
+ profile_host = profile_host[8:]
52
+ ssl_setting = True
53
+ elif "http" in profile_host:
54
+ profile_host = profile_host[7:]
55
+ # why is this here?
56
+ if esdl_profile.port == 443:
57
+ ssl_setting = True
58
+
59
+ influx_host = "{}:{}".format(profile_host, esdl_profile.port)
60
+ if influx_host in influx_cred_map:
61
+ (username, password) = influx_cred_map[influx_host]
62
+ else:
63
+ username = None
64
+ password = None
65
+ time_series_data = InfluxDBProfileManager.create_esdl_influxdb_profile_manager(
66
+ esdl_profile,
67
+ username,
68
+ password,
69
+ ssl_setting,
70
+ ssl_setting,
71
+ )
72
+ # Error check start and end dates of profiles
73
+
74
+ # I do not thing this is required since you set it in mapeditor.
75
+ if time_series_data.end_datetime != esdl_profile.endDate:
76
+ raise RuntimeError(
77
+ f"The user input profile end datetime: {esdl_profile.endDate} does not match the end"
78
+ f" datetime in the datbase: {time_series_data.end_datetime} for variable: "
79
+ f"{esdl_profile.field}"
80
+ )
81
+ if time_series_data.start_datetime != esdl_profile.startDate:
82
+ raise RuntimeError(
83
+ f"The user input profile start datetime: {esdl_profile.startDate} does not match the"
84
+ f" start date in the datbase: {time_series_data.start_datetime} for variable: "
85
+ f"{esdl_profile.field}"
86
+ )
87
+ if time_series_data.start_datetime != time_series_data.profile_data_list[0][0]:
88
+ raise RuntimeError(
89
+ f"The profile's variable value for the start datetime: "
90
+ f"{time_series_data.start_datetime} does not match the start datetime of the"
91
+ f" profile data: {time_series_data.profile_data_list[0][0]}"
92
+ )
93
+ if time_series_data.end_datetime != time_series_data.profile_data_list[-1][0]:
94
+ raise RuntimeError(
95
+ f"The profile's variable value for the end datetime: "
96
+ f"{time_series_data.end_datetime} does not match the end datetime of the"
97
+ f" profile data: {time_series_data.profile_data_list[-1][0]}"
98
+ )
99
+
100
+ unit = get_unit(esdl_profile)
101
+ dates = [time_stamp for time_stamp, _ in
102
+ time_series_data.profile_data_list]
103
+ values = [convert_to_unit(value, esdl_profile.profileQuantityAndUnit, unit)
104
+ * esdl_profile.multiplier
105
+ for _, value in time_series_data.profile_data_list]
106
+ data_points = {"date": dates, "values": values}
107
+
108
+ return pd.DataFrame(data_points)
109
+
110
+
111
+ def get_unit(profile: esdl.InfluxDBProfile) -> esdl.PhysicalQuantityEnum:
112
+ """Method to get the SI unit of the profile.
113
+
114
+ This method tries to get the unit of the profile.
115
+ if the unit is not in the list the same unit as the profile is returned
116
+ :param profile: esdl.InfluxDBProfile with the profile
117
+ :return: esdl.PhysicalQuantityEnum with the unit
118
+ """
119
+ conversion_dict = {
120
+ esdl.PhysicalQuantityEnum.POWER: POWER_IN_W,
121
+ esdl.PhysicalQuantityEnum.ENERGY: ENERGY_IN_J
122
+ }
123
+ try:
124
+ profile_unit = profile.profileQuantityAndUnit.reference.physicalQuantity
125
+ except AttributeError:
126
+ profile_unit = profile.profileQuantityAndUnit.physicalQuantity
127
+ if profile_unit in conversion_dict:
128
+ return conversion_dict[profile_unit]
129
+ return profile_unit
@@ -0,0 +1,16 @@
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
+ """__init__.py file for initialization code."""
@@ -0,0 +1,55 @@
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
+ """Entry point for running simulator-core library from cmdline."""
17
+
18
+ import logging
19
+ import sys
20
+ import traceback
21
+ import uuid
22
+ from datetime import datetime
23
+
24
+ import pandas as pd
25
+
26
+ from simulator_core.entities.esdl_object import EsdlObject
27
+ from simulator_core.entities.simulation_configuration import SimulationConfiguration
28
+ from simulator_core.infrastructure.simulation_manager import SimulationManager
29
+ from simulator_core.infrastructure.utils import pyesdl_from_file
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+
34
+ def run(file_path: str | None = None) -> pd.DataFrame:
35
+ """Main run function for the heatnetwork simulator."""
36
+ config = SimulationConfiguration(
37
+ simulation_id=uuid.uuid1(),
38
+ name="test run",
39
+ timestep=3600,
40
+ start=datetime.strptime("2019-01-01T00:00:00", "%Y-%m-%dT%H:%M:%S"),
41
+ stop=datetime.strptime("2019-01-01T01:00:00", "%Y-%m-%dT%H:%M:%S"),
42
+ )
43
+
44
+ esdl_file_path = sys.argv[1] if file_path is None else file_path
45
+ try:
46
+ app = SimulationManager(EsdlObject(pyesdl_from_file(esdl_file_path)), config)
47
+ result = app.execute()
48
+ return result
49
+ except Exception as error:
50
+ logger.error(f"Error occured: {error} at: {traceback.format_exc(limit=-1)}")
51
+ logger.debug(traceback.format_exc())
52
+
53
+
54
+ if __name__ == "__main__":
55
+ print(run(r".\testdata\test1.esdl"))
@@ -0,0 +1,55 @@
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
+ """Simulation manager creates and controls the simulation objects."""
17
+
18
+ import pandas as pd
19
+
20
+ from simulator_core.adapter.transforms.mappers import EsdlControllerMapper, EsdlEnergySystemMapper
21
+ from simulator_core.entities.esdl_object import EsdlObject
22
+ from simulator_core.entities.heat_network import HeatNetwork
23
+ from simulator_core.entities.simulation_configuration import SimulationConfiguration
24
+ from simulator_core.simulation import NetworkSimulation
25
+
26
+
27
+ class SimulationManager:
28
+ """Manager class for managing the simulation."""
29
+
30
+ def __init__(self, esdl: EsdlObject, config: SimulationConfiguration):
31
+ """Constructor for SimulationManager class.
32
+
33
+ :param EsdlObject esdl: Esdlobject, which stores the network information
34
+ :param SimulationConfiguration config: Config object to hold the simulation start, stop, end
35
+ """
36
+ self.esdl = esdl
37
+ self.config = config
38
+
39
+ def execute(self) -> pd.DataFrame:
40
+ """Method to simulate the network.
41
+
42
+ First the network is converted to pandapipes and then the simulation is run.
43
+
44
+ :return: DataFrame with the result of the simulations
45
+ """
46
+ # convert ESDL to Heat Network, NetworkController
47
+ network = HeatNetwork(EsdlEnergySystemMapper(self.esdl).to_entity)
48
+ controller = EsdlControllerMapper().to_entity(self.esdl)
49
+
50
+ worker = NetworkSimulation(network, controller)
51
+ worker.run(self.config)
52
+
53
+ # Run output presenter that iterates over het network (/controller?) and
54
+ # gathers the output into a single data object
55
+ return worker.gather_output()
@@ -0,0 +1,45 @@
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 utility functions."""
17
+
18
+ from esdl.esdl_handler import EnergySystemHandler
19
+ from pathlib import Path
20
+
21
+
22
+ def pyesdl_from_file(file_path: str) -> EnergySystemHandler:
23
+ """
24
+ Loads esdl file into memory and returns a handle to be able to use this file.
25
+
26
+ Please note that it is not checked if the file is a valid esdl file.
27
+ :param file_path: string pointing to the esdl file to be loaded into memory
28
+ """
29
+ if not Path(file_path).is_file():
30
+ raise FileNotFoundError("Not a valid path to an ESDL file")
31
+ esh = EnergySystemHandler()
32
+ esh.load_file(file_path)
33
+ return esh
34
+
35
+
36
+ def pyesdl_from_string(input_str: str) -> EnergySystemHandler:
37
+ """
38
+ Loads esdl file from a string into memory.
39
+
40
+ Please note that it is not checked if the contents of the string is a valid esdl.
41
+ :param input_str: string containing the contents of an esdl file.
42
+ """
43
+ esh = EnergySystemHandler()
44
+ esh.load_from_string(input_str)
45
+ return esh
File without changes
@@ -0,0 +1,18 @@
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
+ """__init__.py file for initialization code."""
17
+
18
+ from .networksimulation import NetworkSimulation
@@ -0,0 +1,16 @@
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
+ """__init__.py file for initialization code."""
@@ -0,0 +1,35 @@
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 the abstract class for the mappers."""
17
+
18
+ from abc import ABC, abstractmethod
19
+ from typing import Generic, TypeVar
20
+
21
+
22
+ Entity = TypeVar("Entity")
23
+ EsdlAssetObject = TypeVar("EsdlAssetObject")
24
+
25
+
26
+ class EsdlMapperAbstract(ABC, Generic[Entity, EsdlAssetObject]):
27
+ """Abstract class to be used for deriving mapper classes from esdl to our own classes."""
28
+
29
+ @abstractmethod
30
+ def to_esdl(self, entity: Entity) -> EsdlAssetObject:
31
+ """Map an Entity to a EsdlAsset."""
32
+
33
+ @abstractmethod
34
+ def to_entity(self, model: EsdlAssetObject) -> Entity:
35
+ """Map am esdl asset to an Entity."""
@@ -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
+ """Simulates an heat network for the specified duration."""
17
+
18
+ from pandas import DataFrame
19
+ from simulator_core.entities.heat_network import HeatNetwork
20
+ from simulator_core.entities.network_controller import NetworkController
21
+ from simulator_core.entities.simulation_configuration import SimulationConfiguration
22
+ from datetime import timedelta, timezone
23
+
24
+ import logging
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ class NetworkSimulation:
30
+ """NetworkSimulation connects the controller and HeatNetwork (incl. assets)."""
31
+
32
+ def __init__(self, network: HeatNetwork, controller: NetworkController):
33
+ """Instantiate the NetworkSimulation object."""
34
+ self.network = network
35
+ self.controller = controller
36
+
37
+ def run(self, config: SimulationConfiguration) -> None:
38
+ """Run the simulation.
39
+
40
+ :param SimulationConfiguration config: Configuration to run the simulation with.
41
+ """
42
+ # time loop
43
+ number_of_time_steps = int((config.stop - config.start).total_seconds() / config.timestep)
44
+ for time_step in range(number_of_time_steps):
45
+ not_converged = True
46
+ time = (config.start + timedelta(seconds=time_step * config.timestep)
47
+ ).replace(tzinfo=timezone.utc)
48
+ controller_input = self.controller.run_time_step(time)
49
+
50
+ while not_converged:
51
+ not_converged = False # for the moment we do not check on convergence,
52
+ # to get stuff running. Also need to add break after 10 iteration.
53
+ logger.debug("Simulating for timestep " + str(time))
54
+ self.network.run_time_step(time, controller_input)
55
+ self.network.store_output()
56
+
57
+ def gather_output(self) -> DataFrame:
58
+ """Gathers all output and return a dict with this output.
59
+
60
+ :return: DataFrame with all the results for the simulation
61
+ """
62
+ result = self.network.gather_output()
63
+ return result
@@ -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,26 @@
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
+ """This file contains the enum for the core quantities of the matrix."""
16
+ from enum import IntEnum
17
+
18
+ NUMBER_CORE_QUANTITIES = 3
19
+
20
+
21
+ class IndexEnum(IntEnum):
22
+ """Enum for the index of the matrix."""
23
+
24
+ discharge = 0
25
+ pressure = 1
26
+ internal_energy = 2
@@ -0,0 +1,56 @@
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 class to store equations."""
16
+ import numpy as np
17
+
18
+
19
+ class EquationObject:
20
+ """Class to store equation objects.
21
+
22
+ Indices are the location in the matrix of the coefficients
23
+ rhs is the rhs of the matrix.
24
+ """
25
+
26
+ indices: np.ndarray
27
+ """Indices of the coefficients in the matrix."""
28
+
29
+ coefficients: np.ndarray
30
+ """Coefficients of the equation."""
31
+
32
+ rhs: float
33
+ """Right hand side of the equation."""
34
+
35
+ def __init__(self) -> None:
36
+ """Constructor of the EquationObject."""
37
+ self.indices = np.array([], dtype=int)
38
+ self.coefficients = np.array([], dtype=float)
39
+ self.rhs = 0.0
40
+
41
+ def to_list(self, length: int) -> list[float]:
42
+ """Method to change the equation object to list which can be stored in the matrix.
43
+
44
+ The method creates a list with zero of the length given in the input.
45
+ At the indices of the class the coefficients of the class are stored.
46
+ :param int length: Length of the list to be returned
47
+ :return: a list of the coefficient which can be used in the matrix.
48
+ """
49
+ if length < len(self.indices):
50
+ raise IndexError(f"Length of {length} smaller than the available number "
51
+ f"of coefficients {len(self.coefficients)}!")
52
+
53
+ coefficient_list: list[float] = [0.0] * length
54
+ for col, coefficient in zip(self.indices, self.coefficients):
55
+ coefficient_list[col] = coefficient
56
+ return coefficient_list