Skip to content

Commit

Permalink
112 utilize carrier cost in esdl for price profile in electricity (#131)
Browse files Browse the repository at this point in the history
Included costs of electricity for heat pumps.

Refactor to update the component type of the electric heatpump to reamin heat_pump and the subcomponent type to be heat_pump_elec. This prevents forgetting to add heat_pump_elec to specific loops

Added function to be used in future when extracting multiple assettypes, to prevent overlapping and thus duplicating constraints or assets in the objective function
  • Loading branch information
FJanssen-TNO authored Mar 12, 2024
1 parent f3671c5 commit d2e3d4c
Show file tree
Hide file tree
Showing 9 changed files with 14 additions and 19 deletions.
2 changes: 0 additions & 2 deletions src/rtctools_heat_network/asset_sizing_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,6 @@ def _make_max_size_var(name, lb, ub, nominal):
for asset_name in [
*self.energy_system_components.get("heat_exchanger", []),
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
ub = bounds[f"{asset_name}.Secondary_heat"][1]
lb = 0.0 if parameters[f"{asset_name}.state"] != 1 else ub
Expand Down Expand Up @@ -1802,7 +1801,6 @@ def __max_size_constraints(self, ensemble_member):
for hx in [
*self.energy_system_components.get("heat_exchanger", []),
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
max_var = self._asset_max_size_map[hx]
max_heat = self.extra_variable(max_var, ensemble_member)
Expand Down
7 changes: 7 additions & 0 deletions src/rtctools_heat_network/base_component_type_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ def energy_system_components(self) -> Dict[str, str]:
"""
raise NotImplementedError

def energy_system_components_get(self, list_types: list) -> list:
components = []
for component_type in list_types:
components.extend(self.energy_system_components.get(component_type))
components = list(set(components))
return components

@property
@abstractmethod
def energy_system_topology(self) -> Topology:
Expand Down
1 change: 0 additions & 1 deletion src/rtctools_heat_network/esdl/asset_to_component_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ def _is_disconnectable_pipe(self, asset: Asset) -> bool:
"ates",
"heat_exchanger",
"heat_pump",
"heat_pump_elec",
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ def read(self):
*self.energy_system_components.get("ates", []),
*self.energy_system_components.get("heat_buffer", []),
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
esdl_asset = self.esdl_assets[self.esdl_asset_name_to_id_map[asset]]
for constraint in esdl_asset.attributes.get("constraint", []):
Expand Down
6 changes: 4 additions & 2 deletions src/rtctools_heat_network/financial_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ def pre(self):
elif asset_name in [
*self.energy_system_components.get("heat_exchanger", []),
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
nominal_fixed_operational = self.variable_nominal(f"{asset_name}.Secondary_heat")
nominal_variable_operational = nominal_fixed_operational
Expand Down Expand Up @@ -802,7 +801,6 @@ def __variable_operational_cost_constraints(self, ensemble_member):

for hp in [
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
elec_consumption = self.__state_vector_scaled(f"{hp}.Power_elec", ensemble_member)
variable_operational_cost_var = self._asset_variable_operational_cost_map[hp]
Expand Down Expand Up @@ -835,6 +833,10 @@ def __variable_operational_cost_constraints(self, ensemble_member):
variable_operational_cost_coefficient * elec_consumption[i] * timesteps[i - 1]
)
sum += price_profile.values[i] * pump_power[i] * timesteps[i - 1] / eff
if hp not in self.energy_system_components.get("heat_pump_elec", []):
# assuming that if heatpump has electricity port, the cost for the electricity
# are already made by the electricity producer and transport
sum += price_profile.values[i] * elec_consumption[i] * timesteps[i - 1]

constraints.append(((variable_operational_cost - sum) / nominal, 0.0, 0.0))

Expand Down
3 changes: 0 additions & 3 deletions src/rtctools_heat_network/heat_physics_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,6 @@ def _get_min_bound(bound):
for hex in [
*self.energy_system_components.get("heat_exchanger", []),
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
disabeld_hex_var = f"{hex}__disabled"
self.__disabled_hex_map[hex] = disabeld_hex_var
Expand Down Expand Up @@ -1791,7 +1790,6 @@ def __heat_exchanger_heat_to_discharge_path_constraints(self, ensemble_member):
for heat_exchanger in [
*self.energy_system_components.get("heat_exchanger", []),
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
cp_prim = parameters[f"{heat_exchanger}.Primary.cp"]
rho_prim = parameters[f"{heat_exchanger}.Primary.rho"]
Expand Down Expand Up @@ -2505,7 +2503,6 @@ def __heat_pump_cop_constraints(self, ensemble_member):

for hp in [
*self.energy_system_components.get("heat_pump", []),
*self.energy_system_components.get("heat_pump_elec", []),
]:
sec_sup_carrier = parameters[f"{hp}.Secondary.T_supply_id"]
sec_ret_carrier = parameters[f"{hp}.Secondary.T_return_id"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
# where this is then placed.
class HeatPumpElec(HeatPump):
"""
The milp pump elec is to model a water-water heatpump where we explicitly model its connection
The heat pump elec is to model a water-water heatpump where we explicitly model its connection
to the electricity grid. This allows to potentially optimize for electricity network constraints
in the optimization of the milp network and vice-versa.
in the optimization of the heat network and vice-versa.
"""

def __init__(self, name, **modifiers):
Expand All @@ -22,9 +22,7 @@ def __init__(self, name, **modifiers):
),
)

# TODO: potentially we can keep the component type as heat_pump and set subcomponent to
# heat_pump_elec, first need to check if there wouldn't be anything conflicting then.
self.component_type = "heat_pump_elec"
self.component_subtype = "heat_pump_elec"
self.min_voltage = 1.0e4

self.add_variable(ElectricityPort, "ElectricityIn")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ def __init__(
"heat_source",
"ates",
"heat_pump",
"heat_pump_elec",
"pump",
"heat_exchanger",
"heat_buffer",
Expand Down
4 changes: 0 additions & 4 deletions tests/utils_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ def heat_to_discharge_test(solution, results):
for d in [
*solution.energy_system_components.get("heat_exchanger", []),
*solution.energy_system_components.get("heat_pump", []),
*solution.energy_system_components.get("heat_pump_elec", []),
]:
for p in ["Primary", "Secondary"]:
cp = solution.parameters(0)[f"{d}.{p}.cp"]
Expand Down Expand Up @@ -308,9 +307,6 @@ def energy_conservation_test(solution, results):
for d in solution.energy_system_components.get("heat_pump", []):
energy_sum += results[f"{d}.Power_elec"]

for d in solution.energy_system_components.get("heat_pump_elec", []):
energy_sum += results[f"{d}.Power_elec"]

for p in solution.energy_system_components.get("heat_pipe", []):
energy_sum -= abs(results[f"{p}.HeatIn.Heat"] - results[f"{p}.HeatOut.Heat"])
if f"{p}__is_disconnected" in results.keys():
Expand Down

0 comments on commit d2e3d4c

Please sign in to comment.