fram-core 0.0.0__py3-none-any.whl → 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fram_core-0.1.0.dist-info/METADATA +42 -0
- fram_core-0.1.0.dist-info/RECORD +100 -0
- {fram_core-0.0.0.dist-info → fram_core-0.1.0.dist-info}/WHEEL +1 -2
- fram_core-0.1.0.dist-info/licenses/LICENSE.md +8 -0
- framcore/Base.py +161 -0
- framcore/Model.py +90 -0
- framcore/__init__.py +10 -0
- framcore/aggregators/Aggregator.py +172 -0
- framcore/aggregators/HydroAggregator.py +849 -0
- framcore/aggregators/NodeAggregator.py +530 -0
- framcore/aggregators/WindSolarAggregator.py +315 -0
- framcore/aggregators/__init__.py +13 -0
- framcore/aggregators/_utils.py +184 -0
- framcore/attributes/Arrow.py +307 -0
- framcore/attributes/ElasticDemand.py +90 -0
- framcore/attributes/ReservoirCurve.py +23 -0
- framcore/attributes/SoftBound.py +16 -0
- framcore/attributes/StartUpCost.py +65 -0
- framcore/attributes/Storage.py +158 -0
- framcore/attributes/TargetBound.py +16 -0
- framcore/attributes/__init__.py +63 -0
- framcore/attributes/hydro/HydroBypass.py +49 -0
- framcore/attributes/hydro/HydroGenerator.py +100 -0
- framcore/attributes/hydro/HydroPump.py +178 -0
- framcore/attributes/hydro/HydroReservoir.py +27 -0
- framcore/attributes/hydro/__init__.py +13 -0
- framcore/attributes/level_profile_attributes.py +911 -0
- framcore/components/Component.py +136 -0
- framcore/components/Demand.py +144 -0
- framcore/components/Flow.py +189 -0
- framcore/components/HydroModule.py +371 -0
- framcore/components/Node.py +99 -0
- framcore/components/Thermal.py +208 -0
- framcore/components/Transmission.py +198 -0
- framcore/components/_PowerPlant.py +81 -0
- framcore/components/__init__.py +22 -0
- framcore/components/wind_solar.py +82 -0
- framcore/curves/Curve.py +44 -0
- framcore/curves/LoadedCurve.py +146 -0
- framcore/curves/__init__.py +9 -0
- framcore/events/__init__.py +21 -0
- framcore/events/events.py +51 -0
- framcore/expressions/Expr.py +591 -0
- framcore/expressions/__init__.py +30 -0
- framcore/expressions/_get_constant_from_expr.py +477 -0
- framcore/expressions/_utils.py +73 -0
- framcore/expressions/queries.py +416 -0
- framcore/expressions/units.py +227 -0
- framcore/fingerprints/__init__.py +11 -0
- framcore/fingerprints/fingerprint.py +292 -0
- framcore/juliamodels/JuliaModel.py +171 -0
- framcore/juliamodels/__init__.py +7 -0
- framcore/loaders/__init__.py +10 -0
- framcore/loaders/loaders.py +405 -0
- framcore/metadata/Div.py +73 -0
- framcore/metadata/ExprMeta.py +56 -0
- framcore/metadata/LevelExprMeta.py +32 -0
- framcore/metadata/Member.py +55 -0
- framcore/metadata/Meta.py +44 -0
- framcore/metadata/__init__.py +15 -0
- framcore/populators/Populator.py +108 -0
- framcore/populators/__init__.py +7 -0
- framcore/querydbs/CacheDB.py +50 -0
- framcore/querydbs/ModelDB.py +34 -0
- framcore/querydbs/QueryDB.py +45 -0
- framcore/querydbs/__init__.py +11 -0
- framcore/solvers/Solver.py +63 -0
- framcore/solvers/SolverConfig.py +272 -0
- framcore/solvers/__init__.py +9 -0
- framcore/timeindexes/AverageYearRange.py +27 -0
- framcore/timeindexes/ConstantTimeIndex.py +22 -0
- framcore/timeindexes/DailyIndex.py +33 -0
- framcore/timeindexes/FixedFrequencyTimeIndex.py +814 -0
- framcore/timeindexes/HourlyIndex.py +33 -0
- framcore/timeindexes/IsoCalendarDay.py +33 -0
- framcore/timeindexes/ListTimeIndex.py +277 -0
- framcore/timeindexes/ModelYear.py +23 -0
- framcore/timeindexes/ModelYears.py +27 -0
- framcore/timeindexes/OneYearProfileTimeIndex.py +29 -0
- framcore/timeindexes/ProfileTimeIndex.py +43 -0
- framcore/timeindexes/SinglePeriodTimeIndex.py +37 -0
- framcore/timeindexes/TimeIndex.py +103 -0
- framcore/timeindexes/WeeklyIndex.py +33 -0
- framcore/timeindexes/__init__.py +36 -0
- framcore/timeindexes/_time_vector_operations.py +689 -0
- framcore/timevectors/ConstantTimeVector.py +131 -0
- framcore/timevectors/LinearTransformTimeVector.py +131 -0
- framcore/timevectors/ListTimeVector.py +127 -0
- framcore/timevectors/LoadedTimeVector.py +97 -0
- framcore/timevectors/ReferencePeriod.py +51 -0
- framcore/timevectors/TimeVector.py +108 -0
- framcore/timevectors/__init__.py +17 -0
- framcore/utils/__init__.py +35 -0
- framcore/utils/get_regional_volumes.py +387 -0
- framcore/utils/get_supported_components.py +60 -0
- framcore/utils/global_energy_equivalent.py +63 -0
- framcore/utils/isolate_subnodes.py +172 -0
- framcore/utils/loaders.py +97 -0
- framcore/utils/node_flow_utils.py +236 -0
- framcore/utils/storage_subsystems.py +106 -0
- fram_core-0.0.0.dist-info/METADATA +0 -5
- fram_core-0.0.0.dist-info/RECORD +0 -4
- fram_core-0.0.0.dist-info/top_level.txt +0 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from framcore.attributes.level_profile_attributes import (
|
|
2
|
+
AvgFlowVolume,
|
|
3
|
+
Coefficient,
|
|
4
|
+
Conversion,
|
|
5
|
+
Cost,
|
|
6
|
+
Efficiency,
|
|
7
|
+
Elasticity,
|
|
8
|
+
FlowVolume,
|
|
9
|
+
Hours,
|
|
10
|
+
LevelProfile,
|
|
11
|
+
Loss,
|
|
12
|
+
MaxFlowVolume,
|
|
13
|
+
ObjectiveCoefficient,
|
|
14
|
+
Price,
|
|
15
|
+
Proportion,
|
|
16
|
+
ReservePrice,
|
|
17
|
+
ShadowPrice,
|
|
18
|
+
StockVolume,
|
|
19
|
+
WaterValue,
|
|
20
|
+
)
|
|
21
|
+
from framcore.attributes.Arrow import Arrow
|
|
22
|
+
from framcore.attributes.ElasticDemand import ElasticDemand
|
|
23
|
+
from framcore.attributes.ReservoirCurve import ReservoirCurve
|
|
24
|
+
from framcore.attributes.SoftBound import SoftBound
|
|
25
|
+
from framcore.attributes.StartUpCost import StartUpCost
|
|
26
|
+
from framcore.attributes.TargetBound import TargetBound
|
|
27
|
+
from framcore.attributes.Storage import Storage
|
|
28
|
+
from framcore.attributes.hydro.HydroBypass import HydroBypass
|
|
29
|
+
from framcore.attributes.hydro.HydroGenerator import HydroGenerator
|
|
30
|
+
from framcore.attributes.hydro.HydroPump import HydroPump
|
|
31
|
+
from framcore.attributes.hydro.HydroReservoir import HydroReservoir
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"Arrow",
|
|
35
|
+
"AvgFlowVolume",
|
|
36
|
+
"Coefficient",
|
|
37
|
+
"Conversion",
|
|
38
|
+
"Cost",
|
|
39
|
+
"Efficiency",
|
|
40
|
+
"ElasticDemand",
|
|
41
|
+
"Elasticity",
|
|
42
|
+
"FlowVolume",
|
|
43
|
+
"Hours",
|
|
44
|
+
"HydroBypass",
|
|
45
|
+
"HydroGenerator",
|
|
46
|
+
"HydroPump",
|
|
47
|
+
"HydroReservoir",
|
|
48
|
+
"LevelProfile",
|
|
49
|
+
"Loss",
|
|
50
|
+
"MaxFlowVolume",
|
|
51
|
+
"ObjectiveCoefficient",
|
|
52
|
+
"Price",
|
|
53
|
+
"Proportion",
|
|
54
|
+
"ReservePrice",
|
|
55
|
+
"ReservoirCurve",
|
|
56
|
+
"ShadowPrice",
|
|
57
|
+
"SoftBound",
|
|
58
|
+
"StartUpCost",
|
|
59
|
+
"StockVolume",
|
|
60
|
+
"Storage",
|
|
61
|
+
"TargetBound",
|
|
62
|
+
"WaterValue",
|
|
63
|
+
]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from framcore import Base
|
|
2
|
+
from framcore.attributes import AvgFlowVolume, FlowVolume
|
|
3
|
+
from framcore.fingerprints import Fingerprint
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class HydroBypass(Base):
|
|
7
|
+
"""HydroBypass represents a controlled water way from a HydroModule. Used to bypass main release of the HydroModule."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
to_module: str | None,
|
|
12
|
+
capacity: FlowVolume | None = None,
|
|
13
|
+
) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Initialize object.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
to_module (str | None): Name of the HydroModule the water is released to.
|
|
19
|
+
capacity (FlowVolume | None, optional): Restrictions on the volume of water which can pass through the bypass at a given moment. Defaults to None.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
super().__init__()
|
|
23
|
+
|
|
24
|
+
self._check_type(to_module, (str, type(None)))
|
|
25
|
+
self._check_type(capacity, (FlowVolume, type(None)))
|
|
26
|
+
|
|
27
|
+
self._to_module = to_module
|
|
28
|
+
self._capacity = capacity
|
|
29
|
+
self._volume = AvgFlowVolume()
|
|
30
|
+
|
|
31
|
+
def get_to_module(self) -> str | None:
|
|
32
|
+
"""Get the name of the module to which the bypass leads."""
|
|
33
|
+
return self._to_module
|
|
34
|
+
|
|
35
|
+
def set_to_module(self, to_module: str) -> None:
|
|
36
|
+
"""Set the name of the module to which the bypass leads."""
|
|
37
|
+
self._check_type(to_module, str)
|
|
38
|
+
self._to_module = to_module
|
|
39
|
+
|
|
40
|
+
def get_capacity(self) -> FlowVolume | None:
|
|
41
|
+
"""Get the capacity of the bypass."""
|
|
42
|
+
return self._capacity
|
|
43
|
+
|
|
44
|
+
def get_volume(self) -> AvgFlowVolume:
|
|
45
|
+
"""Get the volume of the bypass."""
|
|
46
|
+
return self._volume
|
|
47
|
+
|
|
48
|
+
def _get_fingerprint(self) -> Fingerprint:
|
|
49
|
+
return self.get_fingerprint_default(refs={"to_module": self._to_module})
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from framcore import Base
|
|
2
|
+
from framcore.attributes import AvgFlowVolume, Conversion, Cost
|
|
3
|
+
from framcore.curves import Curve
|
|
4
|
+
from framcore.expressions import Expr, ensure_expr
|
|
5
|
+
from framcore.fingerprints import Fingerprint
|
|
6
|
+
from framcore.timevectors import TimeVector
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HydroGenerator(Base):
|
|
10
|
+
"""
|
|
11
|
+
Produces power from the main release of a HydroModule.
|
|
12
|
+
|
|
13
|
+
Produces to a power node, and can have variable costs associated with operation. Other attributes are energy equivalent, PQ curve, nominal head
|
|
14
|
+
and tailwater elevation.
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
power_node: str,
|
|
21
|
+
energy_equivalent: Conversion, # energy equivalent
|
|
22
|
+
pq_curve: Expr | str | Curve | None = None,
|
|
23
|
+
nominal_head: Expr | str | TimeVector | None = None,
|
|
24
|
+
tailwater_elevation: Expr | str | TimeVector | None = None,
|
|
25
|
+
voc: Cost | None = None,
|
|
26
|
+
production: AvgFlowVolume | None = None,
|
|
27
|
+
) -> None:
|
|
28
|
+
"""
|
|
29
|
+
Initialize a HydroGenerator with parameters.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
power_node (str): Node to supply power to.
|
|
33
|
+
energy_equivalent (Conversion): Conversion factor of power produced to water released.
|
|
34
|
+
pq_curve (Expr | str | Curve | None, optional): Expression or curve describing the relationship produced power and water released. Defaults to None.
|
|
35
|
+
nominal_head (Expr | str | TimeVector | None, optional): Vertical distance between upstream and dowstream water level. Defaults to None.
|
|
36
|
+
tailwater_elevation (Expr | str | TimeVector | None, optional): Elevation at the surface where the water exits the turbine. Defaults to None.
|
|
37
|
+
voc (Cost | None, optional): Variable operational costs. Defaults to None.
|
|
38
|
+
production (AvgFlowVolume | None, optional): Result of power volume produced. Defaults to None.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
super().__init__()
|
|
42
|
+
|
|
43
|
+
self._check_type(power_node, str)
|
|
44
|
+
self._check_type(energy_equivalent, Conversion)
|
|
45
|
+
self._check_type(pq_curve, (Expr, str, Curve, type(None)))
|
|
46
|
+
self._check_type(nominal_head, (Expr, str, TimeVector, type(None)))
|
|
47
|
+
self._check_type(tailwater_elevation, (Expr, str, TimeVector, type(None)))
|
|
48
|
+
self._check_type(voc, (Cost, type(None)))
|
|
49
|
+
|
|
50
|
+
self._power_node = power_node
|
|
51
|
+
self._energy_eq = energy_equivalent
|
|
52
|
+
self._pq_curve = ensure_expr(pq_curve)
|
|
53
|
+
self._nominal_head = ensure_expr(nominal_head, is_level=True)
|
|
54
|
+
self._tailwater_elevation = ensure_expr(tailwater_elevation, is_level=True)
|
|
55
|
+
self._voc = voc
|
|
56
|
+
|
|
57
|
+
if production is None:
|
|
58
|
+
production = AvgFlowVolume()
|
|
59
|
+
self._production: AvgFlowVolume = production
|
|
60
|
+
|
|
61
|
+
def get_power_node(self) -> str:
|
|
62
|
+
"""Get the power node of the hydro generator."""
|
|
63
|
+
return self._power_node
|
|
64
|
+
|
|
65
|
+
def set_power_node(self, power_node: str) -> None:
|
|
66
|
+
"""Set the power node of the pump unit."""
|
|
67
|
+
self._check_type(power_node, str)
|
|
68
|
+
self._power_node = power_node
|
|
69
|
+
|
|
70
|
+
def get_energy_equivalent(self) -> Conversion:
|
|
71
|
+
"""Get the energy equivalent of the hydro generator."""
|
|
72
|
+
return self._energy_eq
|
|
73
|
+
|
|
74
|
+
def get_pq_curve(self) -> Expr | None:
|
|
75
|
+
"""Get the PQ curve of the hydro generator."""
|
|
76
|
+
return self._pq_curve
|
|
77
|
+
|
|
78
|
+
def get_nominal_head(self) -> Expr | None:
|
|
79
|
+
"""Get the nominal head of the hydro generator."""
|
|
80
|
+
return self._nominal_head
|
|
81
|
+
|
|
82
|
+
def get_tailwater_elevation(self) -> Expr | None:
|
|
83
|
+
"""Get the tailwater elevation of the hydro generator."""
|
|
84
|
+
return self._tailwater_elevation
|
|
85
|
+
|
|
86
|
+
def get_voc(self) -> Cost | None:
|
|
87
|
+
"""Get the variable operation and maintenance cost of the hydro generator."""
|
|
88
|
+
return self._voc
|
|
89
|
+
|
|
90
|
+
def set_voc(self, voc: Cost) -> None:
|
|
91
|
+
"""Set the variable operation and maintenance cost of the hydro generator."""
|
|
92
|
+
self._check_type(voc, Cost)
|
|
93
|
+
self._voc = voc
|
|
94
|
+
|
|
95
|
+
def get_production(self) -> AvgFlowVolume:
|
|
96
|
+
"""Get the generation of the hydro generator."""
|
|
97
|
+
return self._production
|
|
98
|
+
|
|
99
|
+
def _get_fingerprint(self) -> Fingerprint:
|
|
100
|
+
raise self.get_fingerprint_default(refs={"power_node": self._power_node})
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from framcore import Base
|
|
2
|
+
from framcore.attributes import AvgFlowVolume, Conversion, FlowVolume
|
|
3
|
+
from framcore.expressions import Expr, ensure_expr
|
|
4
|
+
from framcore.fingerprints import Fingerprint
|
|
5
|
+
from framcore.timevectors import TimeVector
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HydroPump(Base):
|
|
9
|
+
"""
|
|
10
|
+
Represent a pump associated with a HydroModule.
|
|
11
|
+
|
|
12
|
+
The HydroPump can consume power from a power Node to move water upstream between two HydroModules. It has a max power capacity, and mean energy
|
|
13
|
+
equivalent and water capacity. It can also describe the relationship between head and flow (Q), with min and max head and flow.
|
|
14
|
+
|
|
15
|
+
Results for water and power consumption are stored as AvgFlowVolume attributes.
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
power_node: str,
|
|
22
|
+
from_module: str,
|
|
23
|
+
to_module: str,
|
|
24
|
+
water_capacity: FlowVolume,
|
|
25
|
+
energy_equivalent: Conversion,
|
|
26
|
+
power_capacity: FlowVolume | None = None,
|
|
27
|
+
head_min: Expr | str | TimeVector | None = None,
|
|
28
|
+
head_max: Expr | str | TimeVector | None = None,
|
|
29
|
+
q_min: Expr | str | TimeVector | None = None,
|
|
30
|
+
q_max: Expr | str | TimeVector | None = None,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Initialize a HydroPump object parameters.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
power_node (str): Node to take power from when operating.
|
|
37
|
+
from_module (str): Source HydroModule to move water from.
|
|
38
|
+
to_module (str): Destination HydroModule to move water to.
|
|
39
|
+
water_capacity (FlowVolume): Max pumped water volume given the mean energy equivalent and power capacity.
|
|
40
|
+
energy_equivalent (Conversion): Mean conversion factor between power consumed and volume of water moved.
|
|
41
|
+
power_capacity (FlowVolume | None, optional): Max power consumed. Defaults to None.
|
|
42
|
+
head_min (Expr | str | TimeVector | None, optional): Minimum elevation difference between upstream and downstream water level. Defaults to None.
|
|
43
|
+
head_max (Expr | str | TimeVector | None, optional): Maximum elevation difference between upstream and downstream water level. Defaults to None.
|
|
44
|
+
q_min (Expr | str | TimeVector | None, optional): Maximum water flow at head_min. Defaults to None.
|
|
45
|
+
q_max (Expr | str | TimeVector | None, optional): Maximum water flow at head_max. Defaults to None.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
super().__init__()
|
|
49
|
+
self._check_type(power_node, str)
|
|
50
|
+
self._check_modules(from_module, to_module) # checks types and that they are not the same.
|
|
51
|
+
self._check_type(water_capacity, FlowVolume)
|
|
52
|
+
self._check_type(power_capacity, (FlowVolume, type(None)))
|
|
53
|
+
self._check_type(energy_equivalent, Conversion)
|
|
54
|
+
self._check_type(head_min, (Expr, str, TimeVector, type(None)))
|
|
55
|
+
self._check_type(head_max, (Expr, str, TimeVector, type(None)))
|
|
56
|
+
self._check_type(q_min, (Expr, str, TimeVector, type(None)))
|
|
57
|
+
self._check_type(q_max, (Expr, str, TimeVector, type(None)))
|
|
58
|
+
|
|
59
|
+
self._power_node = power_node
|
|
60
|
+
self._from_module = from_module
|
|
61
|
+
self._to_module = to_module
|
|
62
|
+
self._water_capacity = water_capacity
|
|
63
|
+
self._energy_eq = energy_equivalent
|
|
64
|
+
self._power_capacity = power_capacity
|
|
65
|
+
|
|
66
|
+
self._hmin = ensure_expr(head_min, is_level=True)
|
|
67
|
+
self._hmax = ensure_expr(head_max, is_level=True)
|
|
68
|
+
self._qmin = ensure_expr(q_min, is_flow=True, is_level=True)
|
|
69
|
+
self._qmax = ensure_expr(q_max, is_flow=True, is_level=True)
|
|
70
|
+
|
|
71
|
+
self._water_consumption = AvgFlowVolume()
|
|
72
|
+
self._power_consumption = AvgFlowVolume()
|
|
73
|
+
|
|
74
|
+
def get_water_capacity(self) -> FlowVolume:
|
|
75
|
+
"""Get the capacity of the pump unit."""
|
|
76
|
+
return self._water_capacity
|
|
77
|
+
|
|
78
|
+
def get_power_capacity(self) -> FlowVolume:
|
|
79
|
+
"""Get the capacity of the pump unit."""
|
|
80
|
+
return self._power_capacity
|
|
81
|
+
|
|
82
|
+
def get_power_node(self) -> str:
|
|
83
|
+
"""Get the power node of the pump unit."""
|
|
84
|
+
return self._power_node
|
|
85
|
+
|
|
86
|
+
def set_power_node(self, power_node: str) -> None:
|
|
87
|
+
"""Set the power node of the pump unit."""
|
|
88
|
+
self._check_type(power_node, str)
|
|
89
|
+
self._power_node = power_node
|
|
90
|
+
|
|
91
|
+
def get_from_module(self) -> str:
|
|
92
|
+
"""Get the module from which the pump unit is pumping."""
|
|
93
|
+
return self._from_module
|
|
94
|
+
|
|
95
|
+
def get_to_module(self) -> str:
|
|
96
|
+
"""Get the module to which the pump unit is pumping."""
|
|
97
|
+
return self._to_module
|
|
98
|
+
|
|
99
|
+
# TODO: should be split in two? Keep in mind we check that the to and from modules are not the same. So if we split this user might run into issues if
|
|
100
|
+
# trying to first set from_module to to_module then change to_module.
|
|
101
|
+
def set_modules(self, from_module: str, to_module: str) -> None:
|
|
102
|
+
"""Set the modules for the pump unit."""
|
|
103
|
+
self._check_modules(from_module, to_module)
|
|
104
|
+
self._from_module = from_module
|
|
105
|
+
self._to_module = to_module
|
|
106
|
+
|
|
107
|
+
def get_water_consumption(self) -> FlowVolume:
|
|
108
|
+
"""Get the water consumption of the pump unit."""
|
|
109
|
+
return self._water_consumption
|
|
110
|
+
|
|
111
|
+
def get_power_consumption(self) -> FlowVolume:
|
|
112
|
+
"""Get the power consumption of the pump unit."""
|
|
113
|
+
return self._power_consumption
|
|
114
|
+
|
|
115
|
+
def _check_modules(self, from_module: str, to_module: str) -> None:
|
|
116
|
+
self._check_type(from_module, str)
|
|
117
|
+
self._check_type(to_module, str)
|
|
118
|
+
if from_module == to_module:
|
|
119
|
+
message = f"{self} cannot pump to and from the same module. Got {from_module} for both from_module and to_module."
|
|
120
|
+
raise ValueError(message)
|
|
121
|
+
|
|
122
|
+
def _check_base_module_name(self, base_name: str) -> None:
|
|
123
|
+
if base_name not in (self._from_module, self._to_module):
|
|
124
|
+
message = (
|
|
125
|
+
f"Module {base_name} has not been coupled correctly to its pump {self}. Pump is coupled to modules {self._from_module} and {self._to_module}"
|
|
126
|
+
)
|
|
127
|
+
raise RuntimeError(message)
|
|
128
|
+
|
|
129
|
+
# other parameters
|
|
130
|
+
def get_energy_equivalent(self) -> Conversion:
|
|
131
|
+
"""Get the energy equivalent of hydro pump."""
|
|
132
|
+
return self._energy_eq
|
|
133
|
+
|
|
134
|
+
def set_energy_eq(self, energy_eq: Conversion) -> None:
|
|
135
|
+
"""Set the energy equivalent."""
|
|
136
|
+
self._check_type(energy_eq, Conversion)
|
|
137
|
+
self._energy_eq = energy_eq
|
|
138
|
+
|
|
139
|
+
def get_head_min(self) -> Expr:
|
|
140
|
+
"""Get min fall height of hydro pump."""
|
|
141
|
+
return self._head_min
|
|
142
|
+
|
|
143
|
+
def set_head_min(self, head_min: Expr | str | None) -> None:
|
|
144
|
+
"""Set min fall height."""
|
|
145
|
+
self._head_min = ensure_expr(head_min)
|
|
146
|
+
|
|
147
|
+
def get_head_max(self) -> Expr:
|
|
148
|
+
"""Get max fall height of hydro pump."""
|
|
149
|
+
return self._hmax
|
|
150
|
+
|
|
151
|
+
def set_head_max(self, hmax: Expr | str | None) -> None:
|
|
152
|
+
"""Set max fall height."""
|
|
153
|
+
self._hmax = ensure_expr(hmax)
|
|
154
|
+
|
|
155
|
+
def get_q_min(self) -> Expr:
|
|
156
|
+
"""Get Q min of hydro pump."""
|
|
157
|
+
return self._q_min
|
|
158
|
+
|
|
159
|
+
def set_qmin(self, q_min: Expr | str | None) -> None:
|
|
160
|
+
"""Set Q min."""
|
|
161
|
+
self._q_min = ensure_expr(q_min)
|
|
162
|
+
|
|
163
|
+
def get_q_max(self) -> Expr:
|
|
164
|
+
"""Get Q max of hydro pump."""
|
|
165
|
+
return self._q_max
|
|
166
|
+
|
|
167
|
+
def set_qmax(self, q_max: Expr | str | None) -> None:
|
|
168
|
+
"""Set Q max."""
|
|
169
|
+
self._q_max = ensure_expr(q_max)
|
|
170
|
+
|
|
171
|
+
def _get_fingerprint(self) -> Fingerprint:
|
|
172
|
+
return self.get_fingerprint_default(
|
|
173
|
+
refs={
|
|
174
|
+
"power_node": self._power_node,
|
|
175
|
+
"from_module": self._from_module,
|
|
176
|
+
"to_module": self._to_module,
|
|
177
|
+
},
|
|
178
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from framcore.attributes import ReservoirCurve, StockVolume
|
|
2
|
+
from framcore.attributes.Storage import Storage
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HydroReservoir(Storage):
|
|
6
|
+
"""Represent a hydro reservoir of a HydroModule."""
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
capacity: StockVolume,
|
|
11
|
+
reservoir_curve: ReservoirCurve = None,
|
|
12
|
+
volume: StockVolume | None = None,
|
|
13
|
+
) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Initialize a HydroReservoir instance.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
capacity (StockVolume): The maximum storage capacity of the reservoir.
|
|
19
|
+
reservoir_curve (ReservoirCurve, optional): The curve describing water level elevation to volume characteristics.
|
|
20
|
+
volume (StockVolume, optional): Volume of water in the reservoir.
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
super().__init__(
|
|
24
|
+
capacity=capacity,
|
|
25
|
+
reservoir_curve=reservoir_curve,
|
|
26
|
+
volume=volume,
|
|
27
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# from framcore.attributes.hydro.Bypass import Bypass
|
|
2
|
+
# from framcore.attributes.hydro.Generator import Generator
|
|
3
|
+
# from framcore.attributes.hydro.Inflow import Inflow
|
|
4
|
+
# from framcore.attributes.hydro.Pump import Pump
|
|
5
|
+
# from framcore.attributes.hydro.Reservoir import Reservoir
|
|
6
|
+
|
|
7
|
+
# __all__ = [
|
|
8
|
+
# "Bypass",
|
|
9
|
+
# "Generator",
|
|
10
|
+
# "Inflow",
|
|
11
|
+
# "Pump",
|
|
12
|
+
# "Reservoir",
|
|
13
|
+
# ]
|