fram-core 0.0.0__py3-none-any.whl → 0.1.0a2__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 (103) hide show
  1. fram_core-0.1.0a2.dist-info/METADATA +42 -0
  2. fram_core-0.1.0a2.dist-info/RECORD +100 -0
  3. {fram_core-0.0.0.dist-info → fram_core-0.1.0a2.dist-info}/WHEEL +1 -2
  4. fram_core-0.1.0a2.dist-info/licenses/LICENSE.md +8 -0
  5. framcore/Base.py +142 -0
  6. framcore/Model.py +73 -0
  7. framcore/__init__.py +9 -0
  8. framcore/aggregators/Aggregator.py +153 -0
  9. framcore/aggregators/HydroAggregator.py +837 -0
  10. framcore/aggregators/NodeAggregator.py +495 -0
  11. framcore/aggregators/WindSolarAggregator.py +323 -0
  12. framcore/aggregators/__init__.py +13 -0
  13. framcore/aggregators/_utils.py +184 -0
  14. framcore/attributes/Arrow.py +305 -0
  15. framcore/attributes/ElasticDemand.py +90 -0
  16. framcore/attributes/ReservoirCurve.py +37 -0
  17. framcore/attributes/SoftBound.py +19 -0
  18. framcore/attributes/StartUpCost.py +54 -0
  19. framcore/attributes/Storage.py +146 -0
  20. framcore/attributes/TargetBound.py +18 -0
  21. framcore/attributes/__init__.py +65 -0
  22. framcore/attributes/hydro/HydroBypass.py +42 -0
  23. framcore/attributes/hydro/HydroGenerator.py +83 -0
  24. framcore/attributes/hydro/HydroPump.py +156 -0
  25. framcore/attributes/hydro/HydroReservoir.py +27 -0
  26. framcore/attributes/hydro/__init__.py +13 -0
  27. framcore/attributes/level_profile_attributes.py +714 -0
  28. framcore/components/Component.py +112 -0
  29. framcore/components/Demand.py +130 -0
  30. framcore/components/Flow.py +167 -0
  31. framcore/components/HydroModule.py +330 -0
  32. framcore/components/Node.py +76 -0
  33. framcore/components/Thermal.py +204 -0
  34. framcore/components/Transmission.py +183 -0
  35. framcore/components/_PowerPlant.py +81 -0
  36. framcore/components/__init__.py +22 -0
  37. framcore/components/wind_solar.py +67 -0
  38. framcore/curves/Curve.py +44 -0
  39. framcore/curves/LoadedCurve.py +155 -0
  40. framcore/curves/__init__.py +9 -0
  41. framcore/events/__init__.py +21 -0
  42. framcore/events/events.py +51 -0
  43. framcore/expressions/Expr.py +490 -0
  44. framcore/expressions/__init__.py +28 -0
  45. framcore/expressions/_get_constant_from_expr.py +483 -0
  46. framcore/expressions/_time_vector_operations.py +615 -0
  47. framcore/expressions/_utils.py +73 -0
  48. framcore/expressions/queries.py +423 -0
  49. framcore/expressions/units.py +207 -0
  50. framcore/fingerprints/__init__.py +11 -0
  51. framcore/fingerprints/fingerprint.py +293 -0
  52. framcore/juliamodels/JuliaModel.py +161 -0
  53. framcore/juliamodels/__init__.py +7 -0
  54. framcore/loaders/__init__.py +10 -0
  55. framcore/loaders/loaders.py +407 -0
  56. framcore/metadata/Div.py +73 -0
  57. framcore/metadata/ExprMeta.py +50 -0
  58. framcore/metadata/LevelExprMeta.py +17 -0
  59. framcore/metadata/Member.py +55 -0
  60. framcore/metadata/Meta.py +44 -0
  61. framcore/metadata/__init__.py +15 -0
  62. framcore/populators/Populator.py +108 -0
  63. framcore/populators/__init__.py +7 -0
  64. framcore/querydbs/CacheDB.py +50 -0
  65. framcore/querydbs/ModelDB.py +34 -0
  66. framcore/querydbs/QueryDB.py +45 -0
  67. framcore/querydbs/__init__.py +11 -0
  68. framcore/solvers/Solver.py +48 -0
  69. framcore/solvers/SolverConfig.py +272 -0
  70. framcore/solvers/__init__.py +9 -0
  71. framcore/timeindexes/AverageYearRange.py +20 -0
  72. framcore/timeindexes/ConstantTimeIndex.py +17 -0
  73. framcore/timeindexes/DailyIndex.py +21 -0
  74. framcore/timeindexes/FixedFrequencyTimeIndex.py +762 -0
  75. framcore/timeindexes/HourlyIndex.py +21 -0
  76. framcore/timeindexes/IsoCalendarDay.py +31 -0
  77. framcore/timeindexes/ListTimeIndex.py +197 -0
  78. framcore/timeindexes/ModelYear.py +17 -0
  79. framcore/timeindexes/ModelYears.py +18 -0
  80. framcore/timeindexes/OneYearProfileTimeIndex.py +21 -0
  81. framcore/timeindexes/ProfileTimeIndex.py +32 -0
  82. framcore/timeindexes/SinglePeriodTimeIndex.py +37 -0
  83. framcore/timeindexes/TimeIndex.py +90 -0
  84. framcore/timeindexes/WeeklyIndex.py +21 -0
  85. framcore/timeindexes/__init__.py +36 -0
  86. framcore/timevectors/ConstantTimeVector.py +135 -0
  87. framcore/timevectors/LinearTransformTimeVector.py +114 -0
  88. framcore/timevectors/ListTimeVector.py +123 -0
  89. framcore/timevectors/LoadedTimeVector.py +104 -0
  90. framcore/timevectors/ReferencePeriod.py +41 -0
  91. framcore/timevectors/TimeVector.py +94 -0
  92. framcore/timevectors/__init__.py +17 -0
  93. framcore/utils/__init__.py +36 -0
  94. framcore/utils/get_regional_volumes.py +369 -0
  95. framcore/utils/get_supported_components.py +60 -0
  96. framcore/utils/global_energy_equivalent.py +46 -0
  97. framcore/utils/isolate_subnodes.py +163 -0
  98. framcore/utils/loaders.py +97 -0
  99. framcore/utils/node_flow_utils.py +236 -0
  100. framcore/utils/storage_subsystems.py +107 -0
  101. fram_core-0.0.0.dist-info/METADATA +0 -5
  102. fram_core-0.0.0.dist-info/RECORD +0 -4
  103. fram_core-0.0.0.dist-info/top_level.txt +0 -1
@@ -0,0 +1,65 @@
1
+ # ruff: noqa: I001
2
+
3
+ from framcore.attributes.level_profile_attributes import (
4
+ AvgFlowVolume,
5
+ Coefficient,
6
+ Conversion,
7
+ Cost,
8
+ Efficiency,
9
+ Elasticity,
10
+ FlowVolume,
11
+ Hours,
12
+ LevelProfile,
13
+ Loss,
14
+ MaxFlowVolume,
15
+ ObjectiveCoefficient,
16
+ Price,
17
+ Proportion,
18
+ ReservePrice,
19
+ ShaddowPrice,
20
+ StockVolume,
21
+ WaterValue,
22
+ )
23
+ from framcore.attributes.Arrow import Arrow
24
+ from framcore.attributes.ElasticDemand import ElasticDemand
25
+ from framcore.attributes.ReservoirCurve import ReservoirCurve
26
+ from framcore.attributes.SoftBound import SoftBound
27
+ from framcore.attributes.StartUpCost import StartUpCost
28
+ from framcore.attributes.TargetBound import TargetBound
29
+ from framcore.attributes.Storage import Storage
30
+ from framcore.attributes.hydro.HydroBypass import HydroBypass
31
+ from framcore.attributes.hydro.HydroGenerator import HydroGenerator
32
+ from framcore.attributes.hydro.HydroPump import HydroPump
33
+ from framcore.attributes.hydro.HydroReservoir import HydroReservoir
34
+
35
+ __all__ = [
36
+ "Arrow",
37
+ "AvgFlowVolume",
38
+ "Coefficient",
39
+ "Conversion",
40
+ "Cost",
41
+ "Efficiency",
42
+ "ElasticDemand",
43
+ "Elasticity",
44
+ "FlowVolume",
45
+ "Hours",
46
+ "HydroBypass",
47
+ "HydroGenerator",
48
+ "HydroPump",
49
+ "HydroReservoir",
50
+ "LevelProfile",
51
+ "Loss",
52
+ "MaxFlowVolume",
53
+ "ObjectiveCoefficient",
54
+ "Price",
55
+ "Proportion",
56
+ "ReservePrice",
57
+ "ReservoirCurve",
58
+ "ShaddowPrice",
59
+ "SoftBound",
60
+ "StartUpCost",
61
+ "StockVolume",
62
+ "Storage",
63
+ "TargetBound",
64
+ "WaterValue",
65
+ ]
@@ -0,0 +1,42 @@
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
+ """Bypass class representing a hydro bypass attribute."""
8
+
9
+ def __init__(
10
+ self,
11
+ to_module: str | None,
12
+ capacity: FlowVolume | None = None,
13
+ ) -> None:
14
+ """Initialize Bypass."""
15
+ super().__init__()
16
+
17
+ self._check_type(to_module, (str, type(None)))
18
+ self._check_type(capacity, (FlowVolume, type(None)))
19
+
20
+ self._to_module = to_module
21
+ self._capacity = capacity
22
+ self._volume = AvgFlowVolume()
23
+
24
+ def get_to_module(self) -> str | None:
25
+ """Get the name of the module to which the bypass leads."""
26
+ return self._to_module
27
+
28
+ def set_to_module(self, to_module: str) -> None:
29
+ """Set the name of the module to which the bypass leads."""
30
+ self._check_type(to_module, str)
31
+ self._to_module = to_module
32
+
33
+ def get_capacity(self) -> FlowVolume | None:
34
+ """Get the capacity of the bypass."""
35
+ return self._capacity
36
+
37
+ def get_volume(self) -> AvgFlowVolume:
38
+ """Get the volume of the bypass."""
39
+ return self._volume
40
+
41
+ def _get_fingerprint(self) -> Fingerprint:
42
+ return self.get_fingerprint_default(refs={"to_module": self._to_module})
@@ -0,0 +1,83 @@
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
+ """Generator class representing a hydro generator component."""
11
+
12
+ def __init__(
13
+ self,
14
+ power_node: str,
15
+ energy_eq: Conversion, # energy equivalent
16
+ pq_curve: Expr | str | Curve | None = None,
17
+ nominal_head: Expr | str | TimeVector | None = None,
18
+ tailwater_elevation: Expr | str | TimeVector | None = None,
19
+ voc: Cost | None = None,
20
+ production: AvgFlowVolume | None = None,
21
+ ) -> None:
22
+ """Initialize a hydro generator with power node, energy equivalent, and optional parameters."""
23
+ super().__init__()
24
+
25
+ self._check_type(power_node, str)
26
+ self._check_type(energy_eq, Conversion)
27
+ self._check_type(pq_curve, (Expr, str, Curve, type(None)))
28
+ self._check_type(nominal_head, (Expr, str, TimeVector, type(None)))
29
+ self._check_type(tailwater_elevation, (Expr, str, TimeVector, type(None)))
30
+ self._check_type(voc, (Cost, type(None)))
31
+
32
+ self._power_node = power_node
33
+ self._energy_eq = energy_eq
34
+ self._pq_curve = ensure_expr(pq_curve)
35
+ self._nominal_head = ensure_expr(nominal_head, is_level=True)
36
+ self._tailwater_elevation = ensure_expr(tailwater_elevation, is_level=True)
37
+ self._voc = voc
38
+
39
+ if production is None:
40
+ production = AvgFlowVolume()
41
+ self._production: AvgFlowVolume = production
42
+
43
+ def get_power_node(self) -> str:
44
+ """Get the power node of the hydro generator."""
45
+ return self._power_node
46
+
47
+ def set_power_node(self, power_node: str) -> None:
48
+ """Set the power node of the pump unit."""
49
+ self._check_type(power_node, str)
50
+ self._power_node = power_node
51
+
52
+ # TODO: change from eq to equivalent
53
+ def get_energy_eq(self) -> Conversion:
54
+ """Get the energy equivalent of the hydro generator."""
55
+ return self._energy_eq
56
+
57
+ def get_pq_curve(self) -> Expr | None:
58
+ """Get the PQ curve of the hydro generator."""
59
+ return self._pq_curve
60
+
61
+ def get_nominal_head(self) -> Expr | None:
62
+ """Get the nominal head of the hydro generator."""
63
+ return self._nominal_head
64
+
65
+ def get_tailwater_elevation(self) -> Expr | None:
66
+ """Get the tailwater elevation of the hydro generator."""
67
+ return self._tailwater_elevation
68
+
69
+ def get_voc(self) -> Cost | None:
70
+ """Get the variable operation and maintenance cost of the hydro generator."""
71
+ return self._voc
72
+
73
+ def set_voc(self, voc: Cost) -> None:
74
+ """Set the variable operation and maintenance cost of the hydro generator."""
75
+ self._check_type(voc, Cost)
76
+ self._voc = voc
77
+
78
+ def get_production(self) -> AvgFlowVolume:
79
+ """Get the generation of the hydro generator."""
80
+ return self._production
81
+
82
+ def _get_fingerprint(self) -> Fingerprint:
83
+ raise self.get_fingerprint_default(refs={"power_node": self._power_node})
@@ -0,0 +1,156 @@
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
+ """Pump class representing a hydro pump component."""
10
+
11
+ def __init__(
12
+ self,
13
+ power_node: str,
14
+ from_module: str,
15
+ to_module: str,
16
+ water_capacity: FlowVolume,
17
+ energy_eq: Conversion,
18
+ power_capacity: FlowVolume | None = None,
19
+ head_min: Expr | str | TimeVector | None = None,
20
+ head_max: Expr | str | TimeVector | None = None,
21
+ q_min: Expr | str | TimeVector | None = None,
22
+ q_max: Expr | str | TimeVector | None = None,
23
+ ) -> None:
24
+ """Initialize a hydro pump with power node, modules, capacity, energy equivalent, and optional parameters."""
25
+ super().__init__()
26
+ self._check_type(power_node, str)
27
+ self._check_modules(from_module, to_module) # checks types and that they are not the same.
28
+ self._check_type(water_capacity, FlowVolume)
29
+ self._check_type(power_capacity, FlowVolume)
30
+ self._check_type(energy_eq, Conversion)
31
+ self._check_type(head_min, (Expr, str, TimeVector, type(None)))
32
+ self._check_type(head_max, (Expr, str, TimeVector, type(None)))
33
+ self._check_type(q_min, (Expr, str, TimeVector, type(None)))
34
+ self._check_type(q_max, (Expr, str, TimeVector, type(None)))
35
+
36
+ self._power_node = power_node
37
+ self._from_module = from_module
38
+ self._to_module = to_module
39
+ self._water_capacity = water_capacity
40
+ self._energy_eq = energy_eq
41
+ self._power_capacity = power_capacity
42
+
43
+ self._hmin = ensure_expr(head_min, is_level=True)
44
+ self._hmax = ensure_expr(head_max, is_level=True)
45
+ self._qmin = ensure_expr(q_min, is_flow=True, is_level=True)
46
+ self._qmax = ensure_expr(q_max, is_flow=True, is_level=True)
47
+
48
+ self._water_consumption = AvgFlowVolume()
49
+ self._power_consumption = AvgFlowVolume()
50
+
51
+ # TODO: change to water capacity
52
+ def get_water_capacity(self) -> FlowVolume:
53
+ """Get the capacity of the pump unit."""
54
+ return self._water_capacity
55
+
56
+ def get_power_capacity(self) -> FlowVolume:
57
+ """Get the capacity of the pump unit."""
58
+ return self._power_capacity
59
+
60
+ def get_power_node(self) -> str:
61
+ """Get the power node of the pump unit."""
62
+ return self._power_node
63
+
64
+ def set_power_node(self, power_node: str) -> None:
65
+ """Set the power node of the pump unit."""
66
+ self._check_type(power_node, str)
67
+ self._power_node = power_node
68
+
69
+ def get_from_module(self) -> str:
70
+ """Get the module from which the pump unit is pumping."""
71
+ return self._from_module
72
+
73
+ def get_to_module(self) -> str:
74
+ """Get the module to which the pump unit is pumping."""
75
+ return self._to_module
76
+
77
+ # TODO: should be split in two
78
+ def set_modules(self, from_module: str, to_module: str) -> None:
79
+ """Set the modules for the pump unit."""
80
+ self._check_modules(from_module, to_module)
81
+ self._from_module = from_module
82
+ self._to_module = to_module
83
+
84
+ def get_water_consumption(self) -> FlowVolume:
85
+ """Get the water consumption of the pump unit."""
86
+ return self._water_consumption
87
+
88
+ def get_power_consumption(self) -> FlowVolume:
89
+ """Get the power consumption of the pump unit."""
90
+ return self._power_consumption
91
+
92
+ def _check_modules(self, from_module: str, to_module: str) -> None:
93
+ self._check_type(from_module, str)
94
+ self._check_type(to_module, str)
95
+ if from_module == to_module:
96
+ message = f"{self} cannot pump to and from the same module. Got {from_module} for both from_module and to_module."
97
+ raise ValueError(message)
98
+
99
+ def _check_base_module_name(self, base_name: str) -> None:
100
+ if base_name not in (self._from_module, self._to_module):
101
+ message = (
102
+ 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}"
103
+ )
104
+ raise RuntimeError(message)
105
+
106
+ # other parameters
107
+ # TODO: change from eq to equivalent
108
+ def get_energy_eq(self) -> Conversion:
109
+ """Get the energy equivalent of hydro pump."""
110
+ return self._energy_eq
111
+
112
+ def set_energy_eq(self, energy_eq: Conversion) -> None:
113
+ """Set the energy equivalent."""
114
+ self._check_type(energy_eq, Conversion)
115
+ self._energy_eq = energy_eq
116
+
117
+ def get_head_min(self) -> Expr:
118
+ """Get min fall height of hydro pump."""
119
+ return self._head_min
120
+
121
+ def set_head_min(self, head_min: Expr | str | None) -> None:
122
+ """Set min fall height."""
123
+ self._head_min = ensure_expr(head_min)
124
+
125
+ def get_head_max(self) -> Expr:
126
+ """Get max fall height of hydro pump."""
127
+ return self._hmax
128
+
129
+ def set_head_max(self, hmax: Expr | str | None) -> None:
130
+ """Set max fall height."""
131
+ self._hmax = ensure_expr(hmax)
132
+
133
+ def get_q_min(self) -> Expr:
134
+ """Get Q min of hydro pump."""
135
+ return self._q_min
136
+
137
+ def set_qmin(self, q_min: Expr | str | None) -> None:
138
+ """Set Q min."""
139
+ self._q_min = ensure_expr(q_min)
140
+
141
+ def get_q_max(self) -> Expr:
142
+ """Get Q max of hydro pump."""
143
+ return self._q_max
144
+
145
+ def set_qmax(self, q_max: Expr | str | None) -> None:
146
+ """Set Q max."""
147
+ self._q_max = ensure_expr(q_max)
148
+
149
+ def _get_fingerprint(self) -> Fingerprint:
150
+ return self.get_fingerprint_default(
151
+ refs={
152
+ "power_node": self._power_node,
153
+ "from_module": self._from_module,
154
+ "to_module": self._to_module,
155
+ },
156
+ )
@@ -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
+ """Reservoir class representing a hydro reservoir attribute."""
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 total storage capacity of the reservoir.
19
+ reservoir_curve (ReservoirCurve, optional): The curve describing reservoir characteristics.
20
+ volume (StockVolume, optional): The current 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
+ # ]