From 4bc12bdfb22d2555f7ca5807cc2b52eb74d72322 Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Mon, 4 May 2026 16:14:44 +0200 Subject: [PATCH 1/5] generalizing creation of max values --- src/mesido/asset_sizing_mixin.py | 210 +++++++++---------------------- 1 file changed, 62 insertions(+), 148 deletions(-) diff --git a/src/mesido/asset_sizing_mixin.py b/src/mesido/asset_sizing_mixin.py index 68889a003..9afe06490 100644 --- a/src/mesido/asset_sizing_mixin.py +++ b/src/mesido/asset_sizing_mixin.py @@ -800,166 +800,80 @@ def _make_max_size_var(name, lb, ub, nominal): self.__asset_max_size_bounds[asset_max_size_var] = (lb, ub) self.__asset_max_size_nominals[asset_max_size_var] = nominal - for asset_name in self.energy_system_components.get("heat_source", []): - ub = bounds[f"{asset_name}.Heat_source"][1] - + def _get_ub_profile_constraint(asset_name, profile_name, ub): # Update bound to account for profile constraint being used instead of 1 value - asset = self.esdl_assets[asset_name] asset_profile_constraints, qty_asset_profile_constraints = get_asset_contraints( self, asset, esdl.ProfileConstraint ) if ( - qty_asset_profile_constraints > 0 - and hasattr(asset_profile_constraints[0], "maximum") - and InfluxDBProfileReader._get_profile_quantity_and_unit( - asset_profile_constraints[0].maximum - ).unit - == esdl.UnitEnum.WATT - and parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL # Optional asset + qty_asset_profile_constraints > 0 + and hasattr(asset_profile_constraints[0], "maximum") + and InfluxDBProfileReader._get_profile_quantity_and_unit( + asset_profile_constraints[0].maximum + ).unit + == esdl.UnitEnum.WATT + and parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL # Optional asset ): - max_profile = max(self.get_timeseries(f"{asset_name}.maximum_heat_source").values) + max_profile = max(self.get_timeseries(f"{asset_name}.{profile_name}").values) if ub > max_profile: ub = max_profile - - lb = 0.0 if parameters[f"{asset_name}.state"] != AssetStateEnum.ENABLED else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("heat_demand", []): - ub = ( - bounds[f"{asset_name}.Heat_demand"][1] - if not np.isinf(bounds[f"{asset_name}.Heat_demand"][1]) - else bounds[f"{asset_name}.HeatIn.Heat"][1] + return ub + + def _scalar_upper_bound(bound_ub): + if isinstance(bound_ub, Timeseries): + return np.max(bound_ub.values) + return bound_ub if isinstance(bound_ub, float) else max(bound_ub.values) + + def _demand_ub(asset_name, primary_suffix, secondary_suffix): + demand_ub = bounds[f"{asset_name}.{primary_suffix}"][1] + return ( + demand_ub + if not np.isinf(demand_ub) + else bounds[f"{asset_name}.{secondary_suffix}"][1] ) - # Note that we only enforce the upper bound in state enabled if it was explicitly - # specified for the demand - lb = 0.0 if np.isinf(bounds[f"{asset_name}.Heat_demand"][1]) else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("airco", []): - ub = bounds[f"{asset_name}.Heat_airco"][1] - # Note that we only enforce the upper bound in state enabled if it was explicitly - # specified for the demand - lb = 0.0 if parameters[f"{asset_name}.state"] != 1 else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("cold_demand", []): - ub = ( - bounds[f"{asset_name}.Cold_demand"][1] - if not np.isinf(bounds[f"{asset_name}.Cold_demand"][1]) - else bounds[f"{asset_name}.HeatIn.Heat"][1] - ) - # Note that we only enforce the upper bound in state enabled if it was explicitly - # specified for the demand - lb = 0.0 if np.isinf(bounds[f"{asset_name}.Cold_demand"][1]) else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - for asset_name in [ - *self.energy_system_components.get("ates", []), - *self.energy_system_components.get("low_temperature_ates", []), - ]: - if asset_name in self.energy_system_components.get("ates", []): - ub = bounds[f"{asset_name}.Heat_ates"][1] - else: - ub = bounds[f"{asset_name}.Heat_low_temperature_ates"][1] - lb = 0.0 if parameters[f"{asset_name}.state"] != AssetStateEnum.ENABLED else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("heat_buffer", []): - ub = ( - max(bounds[f"{asset_name}.Stored_heat"][1].values) - if isinstance(bounds[f"{asset_name}.Stored_heat"][1], Timeseries) - else bounds[f"{asset_name}.Stored_heat"][1] - ) - lb = 0.0 if parameters[f"{asset_name}.state"] != AssetStateEnum.ENABLED else ub - _make_max_size_var( - name=asset_name, - lb=lb, - ub=ub, - nominal=self.variable_nominal(f"{asset_name}.Stored_heat"), - ) - - for asset_name in [ - *self.energy_system_components.get("heat_exchanger", []), - *self.energy_system_components.get("heat_pump", []), - ]: - ub = bounds[f"{asset_name}.Secondary_heat"][1] - lb = 0.0 if parameters[f"{asset_name}.state"] != AssetStateEnum.ENABLED else ub - _make_max_size_var( - name=asset_name, - lb=lb, - ub=ub, - nominal=self.variable_nominal(f"{asset_name}.Secondary_heat"), - ) + def _make_ass_max_size_vars(component_type, upper_bound_suffix=None, + upper_bound_suffix_sec=None, profile_constraint=None): + for asset_name in self.energy_system_components.get(component_type, []): + if upper_bound_suffix_sec is None: + ub_raw = bounds[f"{asset_name}.{upper_bound_suffix}"][1] + else: + ub_raw = _demand_ub(asset_name, upper_bound_suffix, upper_bound_suffix_sec) + ub = _scalar_upper_bound(ub_raw) + if profile_constraint: + ub = _get_ub_profile_constraint(asset_name, profile_constraint, ub) + lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub + _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) + + _make_ass_max_size_vars( + "heat_source", + upper_bound_suffix="Heat_source", + profile_constraint="maximum_heat_source", + ) - for asset_name in self.energy_system_components.get("gas_demand", []): - # TODO: add bound value for mass flow rate, used 1.0 for now instead of 0.0 which - # Note that we set the nominal to one to avoid division by zero - ub = 0.0 - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=1.0) - - for asset_name in self.energy_system_components.get("gas_source", []): - # TODO: add bound value for mass flow rate, used 1.0 for now instead of 0.0 which - # Note that we set the nominal to one to avoid division by zero - ub = 0.0 - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=1.0) - - for asset_name in self.energy_system_components.get("gas_tank_storage", []): - ub = bounds[f"{asset_name}.Stored_gas_mass"][1] - ub = ub if isinstance(ub, float) else max(ub.values) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("gas_substation", []): - ub = bounds[f"{asset_name}.GasIn.Q"][1] - ub = ub if isinstance(ub, float) else max(ub.values) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("compressor", []): - ub = bounds[f"{asset_name}.GasIn.Q"][1] - ub = ub if isinstance(ub, float) else max(ub.values) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("electrolyzer", []): - ub = bounds[f"{asset_name}.ElectricityIn.Power"][1] - ub = ub if isinstance(ub, float) else max(ub.values) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("electricity_demand", []): - v = bounds[f"{asset_name}.Electricity_demand"][1] - ub = v if not np.isinf(v) else bounds[f"{asset_name}.ElectricityIn.Power"][1] - ub = ub if isinstance(ub, float) else max(ub.values) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("transformer", []): - ub = bounds[f"{asset_name}.ElectricityIn.Power"][1] - ub = ub if isinstance(ub, float) else max(ub.values) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("electricity_source", []): - ub = ( - bounds[f"{asset_name}.Electricity_source"][1] - if not isinstance(bounds[f"{asset_name}.Electricity_source"][1], Timeseries) - else np.max(bounds[f"{asset_name}.Electricity_source"][1].values) - ) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - for asset_name in self.energy_system_components.get("electricity_storage", []): - ub = ( - bounds[f"{asset_name}.Stored_electricity"][1] - if not isinstance(bounds[f"{asset_name}.Stored_electricity"][1], Timeseries) - else np.max(bounds[f"{asset_name}.Stored_electricity"][1].values) - ) - lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub - _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) + _make_ass_max_size_vars("cold_demand", upper_bound_suffix="Cold_demand", + upper_bound_suffix_sec="HeatIn.Heat") + _make_ass_max_size_vars( + "heat_demand", upper_bound_suffix="Heat_demand", upper_bound_suffix_sec="HeatIn.Heat" + ) + _make_ass_max_size_vars("airco", "Heat_airco") + _make_ass_max_size_vars("ates", "Heat_ates") + _make_ass_max_size_vars("low_temperature_ates", "Heat_ates") + _make_ass_max_size_vars("heat_buffer", "Stored_heat") + _make_ass_max_size_vars("heat_exchanger", "Secondary_heat") + _make_ass_max_size_vars("heat_pump", "Secondary_heat") + _make_ass_max_size_vars("gas_tank_storage", "Stored_gas_mass") + _make_ass_max_size_vars("gas_substation", "GasIn.Q") + _make_ass_max_size_vars("gas_demand", "Gas_demand_mass_flow") + _make_ass_max_size_vars("gas_source", "Gas_source_mass_flow") + _make_ass_max_size_vars("compressor", "GasIn.Q") + _make_ass_max_size_vars("electrolyzer", "ElectricityIn.Power") + _make_ass_max_size_vars("electricity_demand", upper_bound_suffix="Electricity_demand", + upper_bound_suffix_sec="ElectricityIn.Power") + _make_ass_max_size_vars("transformer", "ElectricityIn.Power") + _make_ass_max_size_vars("electricity_source", "Electricity_source") + _make_ass_max_size_vars("electricity_storage", "Stored_electricity") # Making the __aggregation_count variable for each asset for asset_list in self.energy_system_components.values(): From eeefb3ea64f6c6911b670a6109b7fa8f0e59c8cb Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Mon, 4 May 2026 16:30:28 +0200 Subject: [PATCH 2/5] generalizing to create asset variables only based on map --- src/mesido/asset_sizing_mixin.py | 58 +++++++++++++++++--------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/mesido/asset_sizing_mixin.py b/src/mesido/asset_sizing_mixin.py index 9afe06490..e8ba9bb3c 100644 --- a/src/mesido/asset_sizing_mixin.py +++ b/src/mesido/asset_sizing_mixin.py @@ -846,37 +846,39 @@ def _make_ass_max_size_vars(component_type, upper_bound_suffix=None, lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - _make_ass_max_size_vars( - "heat_source", - upper_bound_suffix="Heat_source", - profile_constraint="maximum_heat_source", - ) - _make_ass_max_size_vars("cold_demand", upper_bound_suffix="Cold_demand", - upper_bound_suffix_sec="HeatIn.Heat") - _make_ass_max_size_vars( - "heat_demand", upper_bound_suffix="Heat_demand", upper_bound_suffix_sec="HeatIn.Heat" - ) - _make_ass_max_size_vars("airco", "Heat_airco") - _make_ass_max_size_vars("ates", "Heat_ates") - _make_ass_max_size_vars("low_temperature_ates", "Heat_ates") - _make_ass_max_size_vars("heat_buffer", "Stored_heat") - _make_ass_max_size_vars("heat_exchanger", "Secondary_heat") - _make_ass_max_size_vars("heat_pump", "Secondary_heat") - _make_ass_max_size_vars("gas_tank_storage", "Stored_gas_mass") - _make_ass_max_size_vars("gas_substation", "GasIn.Q") - _make_ass_max_size_vars("gas_demand", "Gas_demand_mass_flow") - _make_ass_max_size_vars("gas_source", "Gas_source_mass_flow") - _make_ass_max_size_vars("compressor", "GasIn.Q") - _make_ass_max_size_vars("electrolyzer", "ElectricityIn.Power") - _make_ass_max_size_vars("electricity_demand", upper_bound_suffix="Electricity_demand", - upper_bound_suffix_sec="ElectricityIn.Power") - _make_ass_max_size_vars("transformer", "ElectricityIn.Power") - _make_ass_max_size_vars("electricity_source", "Electricity_source") - _make_ass_max_size_vars("electricity_storage", "Stored_electricity") + map_variables_asset = { + "heat_source": {"upper_bound_suffix": "Heat_source", + "profile_constraint": "maximum_heat_source"}, + "heat_demand": {"upper_bound_suffix": "Heat_demand", + "upper_bound_suffix_sec": "HeatIn.Heat"}, + "cold_demand": {"upper_bound_suffix": "Cold_demand", + "upper_bound_suffix_sec": "HeatIn.Heat"}, + "airco": {"upper_bound_suffix": "Heat_airco"}, + "ates": {"upper_bound_suffix": "Heat_ates"}, + "low_temperature_ates": {"upper_bound_suffix": "Heat_ates"}, + "heat_buffer": {"upper_bound_suffix": "Stored_heat"}, + "heat_exchanger": {"upper_bound_suffix": "Secondary_heat"}, + "heat_pump": {"upper_bound_suffix": "Secondary_heat"}, + "gas_tank_storage": {"upper_bound_suffix": "Stored_gas_mass"}, + "gas_substation": {"upper_bound_suffix": "GasIn.Q"}, + "gas_demand": {"upper_bound_suffix": "Gas_demand_mass_flow"}, + "gas_source": {"upper_bound_suffix": "Gas_source_mass_flow"}, + "compressor": {"upper_bound_suffix": "GasIn.Q"}, + "electrolyzer": {"upper_bound_suffix": "ElectricityIn.Power"}, + "electricity_demand": {"upper_bound_suffix": "Electricity_demand", + "upper_bound_suffix_sec": "ElectricityIn.Power"}, + "transformer": {"upper_bound_suffix": "ElectricityIn.Power"}, + "electricity_source": {"upper_bound_suffix": "Electricity_source"}, + "electricity_storage": {"upper_bound_suffix": "Stored_electricity"}, + } # Making the __aggregation_count variable for each asset - for asset_list in self.energy_system_components.values(): + for asset_type, asset_list in self.energy_system_components.items(): + if asset_type in map_variables_asset: + _make_ass_max_size_vars(asset_type, **map_variables_asset[asset_type]) + else: + logger.warning(f"Assets of type {asset_type} is not supported for sizing") for asset in asset_list: aggr_count_var = f"{asset}_aggregation_count" self._asset_aggregation_count_var_map[asset] = aggr_count_var From eb273aca5d395305a9c77f2ebcdc498e44d07ce0 Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Mon, 4 May 2026 16:47:00 +0200 Subject: [PATCH 3/5] generalizing to create asset variables only based on map --- src/mesido/asset_sizing_mixin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesido/asset_sizing_mixin.py b/src/mesido/asset_sizing_mixin.py index e8ba9bb3c..3c02e74c1 100644 --- a/src/mesido/asset_sizing_mixin.py +++ b/src/mesido/asset_sizing_mixin.py @@ -877,8 +877,8 @@ def _make_ass_max_size_vars(component_type, upper_bound_suffix=None, for asset_type, asset_list in self.energy_system_components.items(): if asset_type in map_variables_asset: _make_ass_max_size_vars(asset_type, **map_variables_asset[asset_type]) - else: - logger.warning(f"Assets of type {asset_type} is not supported for sizing") + elif asset_type not in ["heat_pipe", "gas_pipe", "cable"]: + logger.warning(f"Assets of type {asset_type} is not supported for sizing, ") for asset in asset_list: aggr_count_var = f"{asset}_aggregation_count" self._asset_aggregation_count_var_map[asset] = aggr_count_var From 752ca176074002739631da320693c5f5b99a2adb Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Mon, 4 May 2026 16:48:58 +0200 Subject: [PATCH 4/5] fix typo --- src/mesido/asset_sizing_mixin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesido/asset_sizing_mixin.py b/src/mesido/asset_sizing_mixin.py index 3c02e74c1..c913b95ed 100644 --- a/src/mesido/asset_sizing_mixin.py +++ b/src/mesido/asset_sizing_mixin.py @@ -833,7 +833,7 @@ def _demand_ub(asset_name, primary_suffix, secondary_suffix): else bounds[f"{asset_name}.{secondary_suffix}"][1] ) - def _make_ass_max_size_vars(component_type, upper_bound_suffix=None, + def _make_asset_max_size_vars(component_type, upper_bound_suffix=None, upper_bound_suffix_sec=None, profile_constraint=None): for asset_name in self.energy_system_components.get(component_type, []): if upper_bound_suffix_sec is None: @@ -876,7 +876,7 @@ def _make_ass_max_size_vars(component_type, upper_bound_suffix=None, # Making the __aggregation_count variable for each asset for asset_type, asset_list in self.energy_system_components.items(): if asset_type in map_variables_asset: - _make_ass_max_size_vars(asset_type, **map_variables_asset[asset_type]) + _make_asset_max_size_vars(asset_type, **map_variables_asset[asset_type]) elif asset_type not in ["heat_pipe", "gas_pipe", "cable"]: logger.warning(f"Assets of type {asset_type} is not supported for sizing, ") for asset in asset_list: From 6c9f484e1ddfb54dc5bccd787ebf11b951e12c43 Mon Sep 17 00:00:00 2001 From: Femke Janssen Date: Tue, 9 Jun 2026 13:00:03 +0200 Subject: [PATCH 5/5] style, renaming and docstrings --- src/mesido/asset_sizing_mixin.py | 117 +++++++++++++++++++------------ 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/src/mesido/asset_sizing_mixin.py b/src/mesido/asset_sizing_mixin.py index a9ade6f8d..6f6bb1b32 100644 --- a/src/mesido/asset_sizing_mixin.py +++ b/src/mesido/asset_sizing_mixin.py @@ -794,91 +794,122 @@ def pre(self): # Making the variables for max size - def _make_max_size_var(name, lb, ub, nominal): + def _make_max_size_var(name: str, lb: float, ub: float, nominal: float) -> None: + """ + Creates max_size variables for the asset with the given lower and upper bound and the + nominal value. + + """ asset_max_size_var = f"{name}__max_size" self._asset_max_size_map[name] = asset_max_size_var self.__asset_max_size_var[asset_max_size_var] = ca.MX.sym(asset_max_size_var) self.__asset_max_size_bounds[asset_max_size_var] = (lb, ub) self.__asset_max_size_nominals[asset_max_size_var] = nominal - def _get_ub_profile_constraint(asset_name, profile_name, ub): - # Update bound to account for profile constraint being used instead of 1 value + def _get_ub_profile_constraint(asset_name: str, profile_name: str, ub: float) -> float: + """ + Returns upper bound to account for profile constraint being used instead of 1 value + """ asset = self.esdl_assets[asset_name] asset_profile_constraints, qty_asset_profile_constraints = get_asset_contraints( self, asset, esdl.ProfileConstraint ) if ( - qty_asset_profile_constraints > 0 - and hasattr(asset_profile_constraints[0], "maximum") - and InfluxDBProfileReader._get_profile_quantity_and_unit( - asset_profile_constraints[0].maximum - ).unit - == esdl.UnitEnum.WATT - and parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL # Optional asset + qty_asset_profile_constraints > 0 + and hasattr(asset_profile_constraints[0], "maximum") + and InfluxDBProfileReader._get_profile_quantity_and_unit( + asset_profile_constraints[0].maximum + ).unit + == esdl.UnitEnum.WATT + and parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL # Optional asset ): max_profile = max(self.get_timeseries(f"{asset_name}.{profile_name}").values) if ub > max_profile: ub = max_profile return ub - def _scalar_upper_bound(bound_ub): + def _scalarise_upper_bound(bound_ub): + """ + Scalarises the upperbound from timeserie to the maximum value of the timeserie. + """ if isinstance(bound_ub, Timeseries): return np.max(bound_ub.values) return bound_ub if isinstance(bound_ub, float) else max(bound_ub.values) - def _demand_ub(asset_name, primary_suffix, secondary_suffix): + def _demand_ub(asset_name: str, primary_suffix: str, secondary_suffix: str): + """ + Returns the upperbound of a variable with a backup variable name under which it might be + saved. + + """ demand_ub = bounds[f"{asset_name}.{primary_suffix}"][1] return ( demand_ub if not np.isinf(demand_ub) - else bounds[f"{asset_name}.{secondary_suffix}"][1]) + else bounds[f"{asset_name}.{secondary_suffix}"][1] + ) - def _make_asset_max_size_vars(component_type, upper_bound_suffix=None, - upper_bound_suffix_sec=None, profile_constraint=None): + def _make_asset_max_size_vars( + component_type: str, + upper_bound_suffix=None, + upper_bound_suffix_sec=None, + profile_constraint=None, + ): + """ + Creates max_size variables for all assets of the given component type with + upper bound suffixes and profile constraint information. + """ for asset_name in self.energy_system_components.get(component_type, []): if upper_bound_suffix_sec is None: ub_raw = bounds[f"{asset_name}.{upper_bound_suffix}"][1] else: ub_raw = _demand_ub(asset_name, upper_bound_suffix, upper_bound_suffix_sec) - ub = _scalar_upper_bound(ub_raw) + ub = _scalarise_upper_bound(ub_raw) if profile_constraint: ub = _get_ub_profile_constraint(asset_name, profile_constraint, ub) lb = 0.0 if parameters[f"{asset_name}.state"] == AssetStateEnum.OPTIONAL else ub _make_max_size_var(name=asset_name, lb=lb, ub=ub, nominal=ub / 2.0) - - map_variables_asset = { - "heat_source": {"upper_bound_suffix": "Heat_source", - "profile_constraint": "maximum_heat_source"}, - "heat_demand": {"upper_bound_suffix": "Heat_demand", - "upper_bound_suffix_sec": "HeatIn.Heat"}, - "cold_demand": {"upper_bound_suffix": "Cold_demand", - "upper_bound_suffix_sec": "HeatIn.Heat"}, - "airco": {"upper_bound_suffix": "Heat_airco"}, - "ates": {"upper_bound_suffix": "Heat_ates"}, + map_asset_type_to_bound_vars = { + "heat_source": { + "upper_bound_suffix": "Heat_source", + "profile_constraint": "maximum_heat_source", + }, + "heat_demand": { + "upper_bound_suffix": "Heat_demand", + "upper_bound_suffix_sec": "HeatIn.Heat", + }, + "cold_demand": { + "upper_bound_suffix": "Cold_demand", + "upper_bound_suffix_sec": "HeatIn.Heat", + }, + "airco": {"upper_bound_suffix": "Heat_airco"}, + "ates": {"upper_bound_suffix": "Heat_ates"}, "low_temperature_ates": {"upper_bound_suffix": "Heat_ates"}, - "heat_buffer": {"upper_bound_suffix": "Stored_heat"}, - "heat_exchanger": {"upper_bound_suffix": "Secondary_heat"}, - "heat_pump": {"upper_bound_suffix": "Secondary_heat"}, - "gas_tank_storage": {"upper_bound_suffix": "Stored_gas_mass"}, - "gas_substation": {"upper_bound_suffix": "GasIn.Q"}, - "gas_demand": {"upper_bound_suffix": "Gas_demand_mass_flow"}, - "gas_source": {"upper_bound_suffix": "Gas_source_mass_flow"}, - "compressor": {"upper_bound_suffix": "GasIn.Q"}, - "electrolyzer": {"upper_bound_suffix": "ElectricityIn.Power"}, - "electricity_demand": {"upper_bound_suffix": "Electricity_demand", - "upper_bound_suffix_sec": "ElectricityIn.Power"}, - "transformer": {"upper_bound_suffix": "ElectricityIn.Power"}, - "electricity_source": {"upper_bound_suffix": "Electricity_source"}, + "heat_buffer": {"upper_bound_suffix": "Stored_heat"}, + "heat_exchanger": {"upper_bound_suffix": "Secondary_heat"}, + "heat_pump": {"upper_bound_suffix": "Secondary_heat"}, + "gas_tank_storage": {"upper_bound_suffix": "Stored_gas_mass"}, + "gas_substation": {"upper_bound_suffix": "GasIn.Q"}, + "gas_demand": {"upper_bound_suffix": "Gas_demand_mass_flow"}, + "gas_source": {"upper_bound_suffix": "Gas_source_mass_flow"}, + "compressor": {"upper_bound_suffix": "GasIn.Q"}, + "electrolyzer": {"upper_bound_suffix": "ElectricityIn.Power"}, + "electricity_demand": { + "upper_bound_suffix": "Electricity_demand", + "upper_bound_suffix_sec": "ElectricityIn.Power", + }, + "transformer": {"upper_bound_suffix": "ElectricityIn.Power"}, + "electricity_source": {"upper_bound_suffix": "Electricity_source"}, "electricity_storage": {"upper_bound_suffix": "Stored_electricity"}, } - # Making the __aggregation_count variable for each asset + # Create the asset sizing variables for each asset. for asset_type, asset_list in self.energy_system_components.items(): - if asset_type in map_variables_asset: - _make_asset_max_size_vars(asset_type, **map_variables_asset[asset_type]) + if asset_type in map_asset_type_to_bound_vars: + _make_asset_max_size_vars(asset_type, **map_asset_type_to_bound_vars[asset_type]) elif asset_type not in ["heat_pipe", "gas_pipe", "cable"]: - logger.warning(f"Assets of type {asset_type} is not supported for sizing, ") + logger.warning(f"Assets of type {asset_type} is not supported for sizing.") for asset in asset_list: aggr_count_var = f"{asset}_aggregation_count" self._asset_aggregation_count_var_map[asset] = aggr_count_var