Skip to content

Commit

Permalink
Merge branch 'feature/powermodels_interface' into merge/powermodels_i…
Browse files Browse the repository at this point in the history
…nterface_split_grid
  • Loading branch information
birgits committed May 9, 2023
2 parents 413a47b + df3dbb4 commit 5db78e2
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 45 deletions.
2 changes: 2 additions & 0 deletions edisgo/edisgo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3237,6 +3237,8 @@ def _check_timeindex(check_df, param_name):
if len(self.heat_pump.cop_df.columns) > len(
self.heat_pump.heat_demand_df.columns
):
# If there are heat pumps with heat demand but no COP time series, or the
# other way around, a warning is raised in HeatPump.check_integrity
pass
else:
hp_cop = self.heat_pump.cop_df
Expand Down
19 changes: 17 additions & 2 deletions edisgo/io/powermodels_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,9 @@ def from_powermodels(
for flex in df2.columns:
abs_error = abs(df2[flex].values - hv_flex_dict[flex])
rel_error = [
abs_error[i] / hv_flex_dict[flex][i] if (abs_error > 0.01)[i] else 0
abs_error[i] / hv_flex_dict[flex][i]
if ((abs_error > 0.01)[i] & hv_flex_dict[flex][i] != 0)
else 0
for i in range(len(abs_error))
]
df2[flex] = rel_error
Expand Down Expand Up @@ -419,6 +421,15 @@ def from_powermodels(
s_base,
)
edisgo_object.opf_results.heat_storage_t.e = df
df = _result_df(
pm,
"heat_storage",
"phss",
timesteps,
edisgo_object.timeseries.timeindex,
s_base,
)
edisgo_object.opf_results.heat_storage_t.p_slack = df

if pm["nw"]["1"]["opf_version"] in [2, 4]:
slacks = [
Expand All @@ -427,6 +438,7 @@ def from_powermodels(
("load", "pds"),
("electromobility", "pcps"),
("heatpumps", "phps"),
("heatpumps", "phps2"),
]
for comp, var in slacks:
# save slacks to edisgo object
Expand All @@ -442,7 +454,10 @@ def from_powermodels(
elif comp == "electromobility":
edisgo_object.opf_results.grid_slacks_t.cp_load_shedding = df
elif comp == "heatpumps":
edisgo_object.opf_results.grid_slacks_t.hp_load_shedding = df
if var == "phps":
edisgo_object.opf_results.grid_slacks_t.hp_load_shedding = df
elif var == "phps2":
edisgo_object.opf_results.grid_slacks_t.hp_operation_slack = df

# save line flows and currents to edisgo object
for variable in ["pf", "qf", "ccm"]:
Expand Down
26 changes: 0 additions & 26 deletions edisgo/network/timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,32 +298,6 @@ def storage_units_reactive_power(self):
def storage_units_reactive_power(self, df):
self._storage_units_reactive_power = df

@property
def storage_units_state_of_charge(self):
"""
State of charge time series of storage units in MWh.
Parameters
----------
df : :pandas:`pandas.DataFrame<DataFrame>`
State of charge time series of all storage units in topology in MWh. Index
of the dataframe is a time index and column names are names of storage
units.
Returns
-------
:pandas:`pandas.DataFrame<DataFrame>`
Reactive power time series of all storage units in topology in MVA for time
steps given in :py:attr:`~timeindex`. For more information on the dataframe
see input parameter `df`.
"""
return self._internal_getter("storage_units_state_of_charge")

@storage_units_state_of_charge.setter
def storage_units_state_of_charge(self, df):
self._storage_units_state_of_charge = df

def reset(self):
"""
Resets all time series.
Expand Down
2 changes: 2 additions & 0 deletions edisgo/opf/results/opf_result_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,15 @@ def _get_matching_dict_of_attributes_and_file_names():
"heat_storage_t": {
"p": "heat_storage_t_p.csv",
"e": "heat_storage_t_e.csv",
"p_slack": "heat_storage_t_p_slack.csv",
},
"grid_slacks_t": {
"gen_d_crt": "dispatchable_gen_crt.csv",
"gen_nd_crt": "non_dispatchable_gen_crt.csv",
"load_shedding": "load_shedding.csv",
"cp_load_shedding": "cp_load_shedding.csv",
"hp_load_shedding": "hp_load_shedding.csv",
"hp_operation_slack": "hp_operation_slack.csv",
},
}

Expand Down
41 changes: 24 additions & 17 deletions edisgo/tools/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,6 @@ def _assign_to_busses(graph, station):
# `neighbor`
subgraph_neighbor = nx.dfs_tree(subgraph, source=neighbor)
for node in subgraph_neighbor.nodes():

edisgo_obj.topology.buses_df.at[node, mode] = neighbor

# in case of an LV station, assign feeder to all nodes in that
Expand Down Expand Up @@ -825,21 +824,29 @@ def add_line_susceptance(
return edisgo_obj


def aggregate_district_heating_components(edisgo_obj):
def aggregate_district_heating_components(edisgo_obj, feedin_district_heating):
"""
Aggregate components that feed into the same district heating grid.
Rated power of both components is added up and COP for combined
component is calculated from COP of all components weighed with their rated
power. Heat demand of district heating grid is then reduced by feedin from other
sources.
Aggregate PtH components that feed into the same district heating network.
Besides aggregating PtH components, feed-in from other heat supply sources can
be specified, which is subtracted from the heat demand in the district heating
network in order to determine the heat demand that needs to be covered by the PtH
units.
Concerning the aggregated components, rated power of the single components is added
up and COP for combined component is calculated from COP of all components weighed
with their rated power. If active and reactive power time series were previously
set for the PtH units they are overwritten.
Parameters
-----------
edisgo_obj : :class:`~.EDisGo`
feedin_district_heating : :pandas:`pandas.DataFrame<DataFrame>`
Other thermal feed-in into district heating per district heating area (in
columns) and time step (in index) in MW.
"""
if "district_heating_id" in edisgo_obj.topology.loads_df.columns:
feedin_district_heating = edisgo_obj.overlying_grid.feedin_district_heating
for (
district
) in edisgo_obj.topology.loads_df.district_heating_id.dropna().unique():
Expand All @@ -863,7 +870,7 @@ def aggregate_district_heating_components(edisgo_obj):
edisgo_obj.heat_pump.heat_demand_df[district_hp] = (
edisgo_obj.heat_pump.heat_demand_df[district_hp]
- feedin_district_heating[str(district)]
) # .clip(min=0)
)
else:
logger.info(
f"There are no other heat supply sources in district heating "
Expand Down Expand Up @@ -934,11 +941,13 @@ def aggregate_district_heating_components(edisgo_obj):
index={district_rh: district_hp}, inplace=True
)

# calculate power timeseries of aggregated components with reduced heat
# demand
edisgo_obj.apply_heat_pump_operating_strategy()
else:
edisgo_obj.apply_heat_pump_operating_strategy()
# if time series was previously set, overwrite time series in case
# components were aggregated components or heat demand reduced by feed-in
# from other components
if district_hp in edisgo_obj.timeseries.loads_active_power.columns:
edisgo_obj.apply_heat_pump_operating_strategy(
heat_pump_names=district_hp
)


def battery_storage_reference_operation(
Expand Down Expand Up @@ -986,7 +995,6 @@ def battery_storage_reference_operation(
# If the house would feed electricity into the grid, charge the storage first.
# No electricity exchange with grid as long as charger power is not exceeded
if (d.house_demand > 0) & (storage_charge < storage_max):

# Check if energy produced exceeds charger power
if d.house_demand < charger_power:
storage_charge = storage_charge + (
Expand All @@ -1012,7 +1020,6 @@ def battery_storage_reference_operation(
# No electricity exchange with grid as long as demand does not exceed charger
# power
elif (d.house_demand < 0) & (storage_charge > 0):

# Check if energy demand exceeds charger power
if d.house_demand / efficiency_discharge < (charger_power * -1):
storage_charge = storage_charge - (charger_power * time_base)
Expand Down Expand Up @@ -1083,7 +1090,7 @@ def create_storage_data(edisgo_obj):
soc_df = pd.concat([soc_df, storage_ts.storage_charge], axis=1)

soc_df.columns = edisgo_obj.topology.storage_units_df.index
edisgo_obj.timeseries.storage_units_state_of_charge = soc_df
edisgo_obj.overlying_grid.storage_units_soc = soc_df
edisgo_obj.set_time_series_reactive_power_control()


Expand Down

0 comments on commit 5db78e2

Please sign in to comment.