Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 51 additions & 16 deletions edisgo/io/powermodels_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,22 @@ def from_powermodels(
# calculate relative error
df2 = deepcopy(df)
for flex in df2.columns:
abs_error = abs(df2[flex].values - hv_flex_dict[flex].values)
rel_error = [
abs_error[i] / hv_flex_dict[flex].iloc[i]
if ((abs_error > 0.01)[i] & (hv_flex_dict[flex].iloc[i] != 0))
else 0
for i in range(len(abs_error))
]
if type(hv_flex_dict[flex]) == pd.Series:
abs_error = abs(df2[flex].values - hv_flex_dict[flex].values)
rel_error = [
abs_error[i] / hv_flex_dict[flex].iloc[i]
if ((abs_error > 0.01)[i] & (hv_flex_dict[flex].iloc[i] != 0))
else 0
for i in range(len(abs_error))
]
else:
abs_error = abs(df2[flex].values - hv_flex_dict[flex].sum(axis=1).values)
rel_error = [
abs_error[i] / hv_flex_dict[flex].sum(axis=1).iloc[i]
if ((abs_error > 0.01)[i] & (hv_flex_dict[flex].sum(axis=1).iloc[i] != 0))
else 0
for i in range(len(abs_error))
]
df2[flex] = rel_error
# write results to edisgo object
edisgo_object.opf_results.overlying_grid = pd.DataFrame(
Expand Down Expand Up @@ -1015,8 +1024,22 @@ def _build_battery_storage(
"""
branches = pd.concat([psa_net.lines, psa_net.transformers])
if not edisgo_obj.overlying_grid.storage_units_soc.empty:
# Select relevant timesteps
timesteps = edisgo_obj.timeseries.timeindex.union(
[
edisgo_obj.timeseries.timeindex[-1]
+ edisgo_obj.timeseries.timeindex.freq
]
)

# If the overlying grid data uses another year in the timeindex then
# edisgo.timindex, unify them
og_year = edisgo_obj.overlying_grid.storage_units_soc.index[0].year
if og_year != edisgo_obj.timeseries.timeindex[0].year:
timesteps = timesteps.map(lambda t: t.replace(year=og_year))

data = pd.concat(
[edisgo_obj.overlying_grid.storage_units_soc]
[edisgo_obj.overlying_grid.storage_units_soc.loc[timesteps]]
* len(edisgo_obj.topology.storage_units_df),
axis=1,
).values
Expand Down Expand Up @@ -1593,11 +1616,18 @@ def _build_hv_requirements(
)

for i in np.arange(len(opf_flex)):
pm["HV_requirements"][str(i + 1)] = {
"P": hv_flex_dict[opf_flex[i]].iloc[0],
"name": opf_flex[i],
"count": count,
}
if type(hv_flex_dict[opf_flex[i]]) == pd.DataFrame:
pm["HV_requirements"][str(i + 1)] = {
"P": hv_flex_dict[opf_flex[i]].sum(axis=1).iloc[0],
"name": opf_flex[i],
"count": count,
}
else:
pm["HV_requirements"][str(i + 1)] = {
"P": hv_flex_dict[opf_flex[i]].iloc[0],
"name": opf_flex[i],
"count": count,
}


def _build_timeseries(
Expand Down Expand Up @@ -1923,9 +1953,14 @@ def _build_component_timeseries(

if (kind == "HV_requirements") & (pm["opf_version"] in [3, 4]):
for i in np.arange(len(opf_flex)):
pm_comp[(str(i + 1))] = {
"P": hv_flex_dict[opf_flex[i]].round(20).tolist(),
}
if type(hv_flex_dict[opf_flex[i]])==pd.DataFrame:
pm_comp[(str(i + 1))] = {
"P": hv_flex_dict[opf_flex[i]].sum(axis=1).round(20).tolist(),
}
else:
pm_comp[(str(i + 1))] = {
"P": hv_flex_dict[opf_flex[i]].round(20).tolist(),
}

pm["time_series"][kind] = pm_comp

Expand Down
14 changes: 14 additions & 0 deletions edisgo/network/overlying_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ def __init__(self, **kwargs):
"feedin_district_heating", pd.DataFrame(dtype="float64")
)

self.dispatchable_generators_active_power = kwargs.get(
"dispatchable_generators_active_power", pd.DataFrame(dtype="float64")
)

self.dispatchable_generators_reactive_power = kwargs.get(
"dispatchable_generators_reactive_power", pd.DataFrame(dtype="float64")
)

self.renewables_potential = kwargs.get(
"renewables_potential", pd.Series(dtype="float64")
)
@property
def _attributes(self):
return [
Expand All @@ -97,6 +108,9 @@ def _attributes(self):
"heat_pump_central_active_power",
"thermal_storage_units_central_soc",
"feedin_district_heating",
"dispatchable_generators_active_power",
"dispatchable_generators_reactive_power",
"renewables_potential",
]

def reduce_memory(self, attr_to_reduce=None, to_type="float32"):
Expand Down
107 changes: 63 additions & 44 deletions edisgo/run/tasks/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,30 @@ def task_import_overlying_grid_data(edisgo, ctx, *, overlying_grid_path=None):
for attr in edisgo.overlying_grid._attributes:
if attr in overlying_grid_data:
setattr(edisgo.overlying_grid, attr, overlying_grid_data[attr])

if not overlying_grid_data.get(
"dispatchable_generators_active_power"
).empty:
# set generator time series
edisgo.set_time_series_active_power_predefined(
dispatchable_generators_ts=overlying_grid_data.get(
"dispatchable_generators_active_power"
),
fluctuating_generators_ts=overlying_grid_data.get("renewables_potential"),
)
return edisgo
edisgo.set_time_series_active_power_predefined(
dispatchable_generators_ts=overlying_grid_data.get(
"dispatchable_generators_active_power"
),
)
if not overlying_grid_data.get("renewables_potential").empty:
pot_ts = overlying_grid_data.get("renewables_potential")
edisgo_ti = edisgo.timeseries.timeindex
csv_year = pot_ts.index[0].year
edisgo_year = edisgo_ti[0].year
if csv_year != edisgo_year:
pot_ts.index = pot_ts.index + pd.DateOffset(
years=edisgo_year - csv_year
)
pot_ts = pot_ts.reindex(edisgo_ti)

edisgo.set_time_series_active_power_predefined(
fluctuating_generators_ts=pot_ts,
)

# resolve path: explicit arg → runner config overlying_grid.path → skip
if overlying_grid_path is None:
Expand All @@ -255,8 +271,9 @@ def task_import_overlying_grid_data(edisgo, ctx, *, overlying_grid_path=None):
)
return edisgo

# load overlying-grid attributes from CSV directory
edisgo.overlying_grid.from_csv(overlying_grid_path)
if overlying_grid_data is None:
# load overlying-grid attributes from CSV directory
edisgo.overlying_grid.from_csv(overlying_grid_path)

# reindex overlying-grid attributes to match edisgo timeindex
# CSVs may use a different year — shift year then reindex
Expand All @@ -281,41 +298,43 @@ def task_import_overlying_grid_data(edisgo, ctx, *, overlying_grid_path=None):
target_ti = edisgo_ti_plus1 if attr in soc_attrs else edisgo_ti
setattr(edisgo.overlying_grid, attr, ts.reindex(target_ti))

# load dispatchable generator and renewables time series from the same dir
disp_path = os.path.join(
overlying_grid_path, "dispatchable_generators_active_power.csv"
)
if os.path.isfile(disp_path):
disp_ts = pd.read_csv(disp_path, index_col=0, parse_dates=True)
if not edisgo_ti.empty:
csv_year = disp_ts.index[0].year
edisgo_year = edisgo_ti[0].year
if csv_year != edisgo_year:
disp_ts.index = disp_ts.index + pd.DateOffset(
years=edisgo_year - csv_year
)
disp_ts = disp_ts.reindex(edisgo_ti)
else:
disp_ts = None

pot_path = os.path.join(overlying_grid_path, "renewables_potential.csv")
if os.path.isfile(pot_path):
pot_ts = pd.read_csv(pot_path, index_col=0, parse_dates=True)
if not edisgo_ti.empty:
csv_year = pot_ts.index[0].year
edisgo_year = edisgo_ti[0].year
if csv_year != edisgo_year:
pot_ts.index = pot_ts.index + pd.DateOffset(
years=edisgo_year - csv_year
)
pot_ts = pot_ts.reindex(edisgo_ti)
else:
pot_ts = None

if disp_ts is not None or pot_ts is not None:
edisgo.set_time_series_active_power_predefined(
dispatchable_generators_ts=disp_ts,
fluctuating_generators_ts=pot_ts,
if overlying_grid_data is None:
# load dispatchable generator and renewables time series from the same dir
disp_path = os.path.join(
overlying_grid_path, "dispatchable_generators_active_power.csv"
)
if os.path.isfile(disp_path):
disp_ts = pd.read_csv(disp_path, index_col=0, parse_dates=True)
if not edisgo_ti.empty:
csv_year = disp_ts.index[0].year
edisgo_year = edisgo_ti[0].year
if csv_year != edisgo_year:
disp_ts.index = disp_ts.index + pd.DateOffset(
years=edisgo_year - csv_year
)
disp_ts = disp_ts.reindex(edisgo_ti)
else:
disp_ts = None

pot_path = os.path.join(overlying_grid_path, "renewables_potential.csv")
if os.path.isfile(pot_path):
pot_ts = pd.read_csv(pot_path, index_col=0, parse_dates=True)
if not edisgo_ti.empty:
csv_year = pot_ts.index[0].year
edisgo_year = edisgo_ti[0].year
if csv_year != edisgo_year:
pot_ts.index = pot_ts.index + pd.DateOffset(
years=edisgo_year - csv_year
)
pot_ts = pot_ts.reindex(edisgo_ti)
else:
pot_ts = None


if disp_ts is not None or pot_ts is not None:
edisgo.set_time_series_active_power_predefined(
dispatchable_generators_ts=disp_ts,
fluctuating_generators_ts=pot_ts,
)

return edisgo
Loading