Skip to content

Commit 9c45c45

Browse files
committed
Add function to calculate inputs for old hydro formulation
1 parent 0a251f8 commit 9c45c45

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

CaseStudy.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,3 +859,87 @@ def shift_ks(self, shift: int, inplace: bool = False) -> Optional[Self]:
859859
setattr(case_study, df_name, df)
860860

861861
return None if inplace else case_study
862+
863+
def add_input_for_old_hydro_formulation(self, scenario_main, scenario_spin, spinup_hours, total_hours):
864+
# Identify hydro assets with outbound pump connections (TurbineOrPump == 1)
865+
pump_assets = set(self.dPower_HydroNetwork[self.dPower_HydroNetwork["TurbineOrPump"] == 1].reset_index()["i"].unique())
866+
867+
# Build network dictionaries
868+
pp_pre = {}
869+
pp_follow = {}
870+
for i, j in self.dPower_HydroNetwork.index:
871+
pp_follow.setdefault(i, []).append(j)
872+
pp_pre.setdefault(j, []).append(i)
873+
pp_pre.setdefault(i, [])
874+
875+
plants = list(pp_pre.keys())
876+
edges = list(self.dPower_HydroNetwork[self.dPower_HydroNetwork["TurbineOrPump"] == 0].index) # Only consider turbine connections for water flow
877+
878+
inflow_main = self.dPower_Inflows_WaterAmount[self.dPower_Inflows_WaterAmount["scenario"] == scenario_main]
879+
inflow_spin = self.dPower_Inflows_WaterAmount[self.dPower_Inflows_WaterAmount["scenario"] == scenario_spin]
880+
881+
# Add missing plants with zero inflow
882+
rp = inflow_main.index.get_level_values('rp').unique()
883+
k = inflow_main.index.get_level_values('k').unique()
884+
full_idx = pd.MultiIndex.from_product([rp, k, plants], names=['rp', 'k', 'g'])
885+
inflow_main = inflow_main.reindex(full_idx, fill_value=0)
886+
inflow_spin = inflow_spin.reindex(full_idx, fill_value=0)
887+
888+
# =========================
889+
# SIMULATION
890+
# =========================
891+
prod = {p: np.zeros(total_hours) for p in plants}
892+
893+
# Water amount that flowed through p in the PREVIOUS HOUR
894+
inflow_prev = {p: 0.0 for p in plants}
895+
896+
# Spin-up
897+
for t in range(spinup_hours):
898+
inflow_curr = {p: float(inflow_spin.loc[("rp01", f"k{t + 1 + total_hours - spinup_hours:04}", p), "value"]) for p in plants}
899+
for u, v in edges:
900+
inflow_curr[v] += inflow_prev[u]
901+
inflow_prev = inflow_curr
902+
903+
# Main calculation
904+
for t in range(total_hours):
905+
inflow_curr = {p: float(inflow_main.loc[("rp01", f"k{t + 1:04}", p), "value"]) for p in plants}
906+
for u, v in edges:
907+
inflow_curr[v] += inflow_prev[u]
908+
909+
for p in plants:
910+
prod[p][t] = inflow_curr[p] * self.dPower_HydroAssets.loc[p, "PowerFactorTurbine"]
911+
912+
inflow_prev = inflow_curr
913+
914+
# Save Excel file with production per plant
915+
df_energy = pd.DataFrame(prod)
916+
df_energy = df_energy.reset_index(names="k").melt(id_vars="k", var_name="g", value_name="value")
917+
df_energy["scenario"] = scenario_main
918+
df_energy["id"] = None
919+
df_energy["rp"] = "rp01"
920+
df_energy["k"] = (df_energy["k"] + 1).astype(str).str.zfill(4).radd("k")
921+
df_energy["dataPackage"] = "TO BE FILLED"
922+
df_energy["dataSource"] = "TO BE FILLED"
923+
924+
self.dPower_Inflows = df_energy.set_index(["rp", "k", "g"])
925+
926+
# Calculate MaxProd and MinProd in MWh by multiplying water amounts with PowerFactors
927+
self.dPower_HydroAssets['MaxProd'] = self.dPower_HydroAssets['MaxProdWater'] * self.dPower_HydroAssets['PowerFactorTurbine']
928+
self.dPower_HydroAssets['MinProd'] = 0.0 # MinProdWater not available in HydroAssets
929+
self.dPower_HydroAssets['MaxCons'] = self.dPower_HydroAssets['MaxPumpWater'] * self.dPower_HydroAssets['PowerFactorPump']
930+
931+
# Split hydro assets: those with pump connections go to Storage, others to VRES
932+
df_hydro_for_storage = self.dPower_HydroAssets[self.dPower_HydroAssets.index.isin(pump_assets)]
933+
df_hydro_for_vres = self.dPower_HydroAssets[~self.dPower_HydroAssets.index.isin(pump_assets)]
934+
935+
# Add hydro assets to Power_VRES
936+
if hasattr(self, "dPower_VRES") and self.dPower_VRES is not None:
937+
self.dPower_VRES = pd.concat([self.dPower_VRES, df_hydro_for_vres])
938+
else:
939+
self.dPower_VRES = df_hydro_for_vres
940+
941+
# Add hydro assets to Power_Storage
942+
if hasattr(self, "dPower_Storage") and self.dPower_Storage is not None:
943+
self.dPower_Storage = pd.concat([self.dPower_Storage, df_hydro_for_storage])
944+
else:
945+
self.dPower_Storage = df_hydro_for_storage

0 commit comments

Comments
 (0)