def test_add_constraints_net_zero_energy_requirement_is_false(self): """Checks that the nze constraint is not added if user provides the value False""" dict_values = self.dict_values.copy() dict_values.update({ CONSTRAINTS: { MAXIMUM_EMISSIONS: { VALUE: None }, MINIMAL_RENEWABLE_FACTOR: { VALUE: 0 }, MINIMAL_DEGREE_OF_AUTONOMY: { VALUE: 0 }, NET_ZERO_ENERGY: { VALUE: False }, } }) model = D2.add_constraints( local_energy_system=solph.Model(self.model), dict_values=dict_values, dict_model=self.dict_model, ) assert ( hasattr(model, "constraint_net_zero_energy") == False ), f"When the net_zero_energy constraint is deactivated (False), no constraint should be added"
def test_add_constraints_maximum_emissions_None(self): """Verifies if the max emissions constraint was not added, in case the user does not provide a value""" dict_values = self.dict_values.copy() dict_values.update({ CONSTRAINTS: { MAXIMUM_EMISSIONS: { VALUE: None }, MINIMAL_RENEWABLE_FACTOR: { VALUE: 0 }, MINIMAL_DEGREE_OF_AUTONOMY: { VALUE: 0 }, NET_ZERO_ENERGY: { VALUE: False }, } }) model = D2.add_constraints( local_energy_system=solph.Model(self.model), dict_values=dict_values, dict_model=self.dict_model, ) assert ( hasattr(model, "integral_limit_emission_factor") == False ), f"When maximum_emission is None, no emission constraint should be added to the ESM."
def test_add_constraints_minimal_renewable_share_is_0(self): """Checks that the minimal renewable share constraint is not added if user provides a minimal share of 0""" dict_values = self.dict_values.copy() dict_values.update({ CONSTRAINTS: { MAXIMUM_EMISSIONS: { VALUE: None }, MINIMAL_RENEWABLE_FACTOR: { VALUE: 0 }, MINIMAL_DEGREE_OF_AUTONOMY: { VALUE: 0 }, NET_ZERO_ENERGY: { VALUE: False }, } }) model = D2.add_constraints( local_energy_system=solph.Model(self.model), dict_values=dict_values, dict_model=self.dict_model, ) assert ( hasattr(model, "constraint_minimal_renewable_share") == False ), f"When the minimal_renewable_share is 0, no constraint should be added"
def test_prepare_demand_assets(): asset = "asset" demand_profiles = "demand" electricity = "Electricity" dict_values = { ENERGY_CONSUMPTION: { asset + AUTO_SINK: {}, asset + EXCESS: {}, asset + EXCESS_SINK_POSTFIX: {}, demand_profiles: { LABEL: demand_profiles, INFLOW_DIRECTION: electricity, ENERGY_VECTOR: electricity, }, }, } dict_model = { OEMOF_SINK: { demand_profiles: demand_profiles }, OEMOF_BUSSES: { electricity: electricity }, } oemof_solph_object_asset = "object" weighting_factor_energy_carrier = "weighting_factor_energy_carrier" oemof_solph_object_bus = "oemof_solph_object_bus" demands = D2.prepare_demand_assets( dict_values, dict_model, oemof_solph_object_asset, weighting_factor_energy_carrier, oemof_solph_object_bus, ) assert ( demand_profiles in demands ), f"Demand asset {demand_profiles} should be in the demands taken into account for the constraints, but is not included in it ({demands.keys()})." exp = { oemof_solph_object_asset: dict_model[OEMOF_SINK][dict_values[ENERGY_CONSUMPTION][demand_profiles] [LABEL]], oemof_solph_object_bus: dict_model[OEMOF_BUSSES][dict_values[ENERGY_CONSUMPTION] [demand_profiles][INFLOW_DIRECTION]], weighting_factor_energy_carrier: DEFAULT_WEIGHTS_ENERGY_CARRIERS[dict_values[ENERGY_CONSUMPTION][ demand_profiles][ENERGY_VECTOR]][VALUE], } for key in exp.keys(): assert ( key in demands[demand_profiles] ), f"The parameter {key} for demand {demand_profiles} not is not added for demand asset processing for the constraints." assert ( demands[demand_profiles][key] == exp[key] ), f"The expected value (exp[key]) of {key} for {demand_profiles} is not met, but is of value {demands[demand_profiles][key]}."
def test_add_constraints_minimal_renewable_share(self): """Checks if the constraint minimal renewable share value provided by the user is being applied or not""" model = D2.add_constraints( local_energy_system=solph.Model(self.model), dict_values=self.dict_values, dict_model=self.dict_model, ) assert ( hasattr(model, "constraint_minimal_renewable_share") == True ), f"The minimal renewable share has not been added, something has failed."
def test_constraint_maximum_emissions(self): """Checks if maximum emissions limit is properly added as a constraint""" # Create a solph model using the input values (especially the constraints setup as class variables above) model = D2.constraint_maximum_emissions( model=solph.Model(self.model), dict_values=self.dict_values, ) assert ( model.integral_limit_emission_factor.NoConstraint[0] == self.exp_emission_limit ), f"Either the maximum emission constraint has not been added or the wrong limit has been added; limit is {model.integral_limit_emission_factor.NoConstraint[0]}."
def run_oemof(dict_values, save_energy_system_graph=False): """ Creates and solves energy system model generated from excel template inputs. Each component is included by calling its constructor function in D1_model_components. Parameters ---------- dict values: dict Includes all dictionary values describing the whole project, including costs, technical parameters and components. In C0_data_processing, each component was attributed with a certain in/output bus. Returns ------- saves and returns oemof simulation results """ start = timer.initalize() model, dict_model = model_building.initialize(dict_values) model = model_building.adding_assets_to_energysystem_model( dict_values, dict_model, model) model_building.plot_networkx_graph( dict_values, model, save_energy_system_graph=save_energy_system_graph) logging.debug( "Creating oemof model based on created components and busses...") local_energy_system = solph.Model(model) logging.debug( "Created oemof model based on created components and busses.") local_energy_system = D2.add_constraints(local_energy_system, dict_values, dict_model) model_building.store_lp_file(dict_values, local_energy_system) model, results_main, results_meta = model_building.simulating( dict_values, model, local_energy_system) model_building.store_oemof_results(dict_values, model) timer.stop(dict_values, start) return results_meta, results_main
def test_add_constraints_maximum_emissions(self): """Checks if maximum emissions constraint works as intended""" dict_values = self.dict_values.copy() # Modify the minimum renewable factor constraint to be 0, otherwise this constraint will also be added dict_values.update({ MINIMAL_RENEWABLE_FACTOR: { VALUE: 0 }, MINIMAL_DEGREE_OF_AUTONOMY: { VALUE: 0 }, NET_ZERO_ENERGY: { VALUE: False }, }) model = D2.add_constraints( local_energy_system=solph.Model(self.model), dict_values=dict_values, dict_model=self.dict_model, ) assert ( model.integral_limit_emission_factor.NoConstraint[0] == self.exp_emission_limit ), f"Either the maximum emission constraint has not been added or the wrong limit has been added; limit is {model.integral_limit_emission_factor.NoConstraint[0]}."
def test_prepare_constraint_minimal_renewable_share(): pv_plant = "PV" diesel = "Diesel" electricity = "Electricity" fuel = "Fuel" dso_1 = "DSO_1" dso_2 = "DSO_2" dict_values = { ENERGY_PROVIDERS: { dso_1: { LABEL: dso_1, RENEWABLE_SHARE_DSO: { VALUE: 0.3 } }, dso_2: { LABEL: dso_2, RENEWABLE_SHARE_DSO: { VALUE: 0.7 } }, }, ENERGY_PRODUCTION: { pv_plant: { RENEWABLE_ASSET_BOOL: { VALUE: True }, LABEL: pv_plant, OUTPUT_BUS_NAME: electricity, ENERGY_VECTOR: electricity, }, diesel: { RENEWABLE_ASSET_BOOL: { VALUE: False }, LABEL: diesel, OUTPUT_BUS_NAME: fuel, ENERGY_VECTOR: electricity, }, dso_1 + DSO_CONSUMPTION: { LABEL: dso_1 + DSO_CONSUMPTION, OUTPUT_BUS_NAME: electricity, ENERGY_VECTOR: electricity, }, dso_2 + DSO_CONSUMPTION: { LABEL: dso_2 + DSO_CONSUMPTION, OUTPUT_BUS_NAME: electricity, ENERGY_VECTOR: electricity, }, }, } dict_model = { OEMOF_SOURCE: { pv_plant: pv_plant, diesel: diesel, dso_1 + DSO_CONSUMPTION: dso_1 + DSO_CONSUMPTION, dso_2 + DSO_CONSUMPTION: dso_2 + DSO_CONSUMPTION, }, OEMOF_BUSSES: { electricity: electricity, fuel: fuel }, } oemof_solph_object_asset = "object" weighting_factor_energy_carrier = "weighting_factor_energy_carrier" renewable_share_asset_flow = "renewable_share_asset_flow" oemof_solph_object_bus = "oemof_solph_object_bus" ( renewable_assets, non_renewable_assets, ) = D2.prepare_constraint_minimal_renewable_share( dict_values=dict_values, dict_model=dict_model, oemof_solph_object_asset=oemof_solph_object_asset, weighting_factor_energy_carrier=weighting_factor_energy_carrier, renewable_share_asset_flow=renewable_share_asset_flow, oemof_solph_object_bus=oemof_solph_object_bus, ) assert (pv_plant in renewable_assets ), f"The {pv_plant} is not added to the renewable assets." assert (pv_plant not in non_renewable_assets ), f"The {pv_plant} is not added to the renewable assets." assert (renewable_assets[pv_plant][renewable_share_asset_flow] == 1 ), f"The renewable share of asset {pv_plant} is added incorrectly." assert (diesel in non_renewable_assets ), f"The {diesel} is added to the renewable assets." assert (diesel not in renewable_assets ), f"The {diesel} is not added to the non-renewable assets." assert (non_renewable_assets[diesel][renewable_share_asset_flow] == 0 ), f"The renewable share of asset {diesel} is added incorrectly." assert ( dso_1 + DSO_CONSUMPTION in renewable_assets ), f"The {dso_1 + DSO_CONSUMPTION} is not added as a renewable source." assert ( renewable_assets[dso_1 + DSO_CONSUMPTION][renewable_share_asset_flow] == 0.3 ), f"The renewable share of asset {dso_1 + DSO_CONSUMPTION} is added incorrectly." assert ( dso_1 + DSO_CONSUMPTION in non_renewable_assets ), f"The {dso_1 + DSO_CONSUMPTION} is not added as a non-renewable source." assert ( non_renewable_assets[ dso_1 + DSO_CONSUMPTION][renewable_share_asset_flow] == 0.3 ), f"The renewable share of asset {dso_1 + DSO_CONSUMPTION} is added incorrectly." assert ( dso_2 + DSO_CONSUMPTION in renewable_assets ), f"The {dso_2 + DSO_CONSUMPTION} is not added as a renewable source." assert ( renewable_assets[dso_2 + DSO_CONSUMPTION][renewable_share_asset_flow] == 0.7 ), f"The renewable share of asset {dso_2 + DSO_CONSUMPTION} is added incorrectly." assert ( dso_2 + DSO_CONSUMPTION in non_renewable_assets ), f"The {dso_2 + DSO_CONSUMPTION} is not added as a non-renewable source." assert ( non_renewable_assets[ dso_2 + DSO_CONSUMPTION][renewable_share_asset_flow] == 0.7 ), f"The renewable share of asset {dso_2 + DSO_CONSUMPTION} is added incorrectly."
def test_prepare_energy_provider_feedin_sinks(): electricity = "Electricity" dso = "DSO" dict_values = { ENERGY_PROVIDERS: { dso: { LABEL: dso }, }, ENERGY_CONSUMPTION: { dso + DSO_FEEDIN + AUTO_SINK: { LABEL: dso + DSO_FEEDIN, INFLOW_DIRECTION: electricity, ENERGY_VECTOR: electricity, } }, } dict_model = { OEMOF_SINK: { dso + DSO_FEEDIN: dso + DSO_FEEDIN, }, OEMOF_BUSSES: { electricity: electricity }, } oemof_solph_object_asset = "object" weighting_factor_energy_carrier = "weighting_factor_energy_carrier" oemof_solph_object_bus = "oemof_solph_object_bus" energy_provider_feedin_sinks = D2.prepare_energy_provider_feedin_sinks( dict_values, dict_model, oemof_solph_object_asset, weighting_factor_energy_carrier, oemof_solph_object_bus, ) DSO_sink_name = dict_values[ENERGY_PROVIDERS][dso][ LABEL] + DSO_FEEDIN + AUTO_SINK assert ( DSO_sink_name in energy_provider_feedin_sinks ), f"DSO sink asset {DSO_sink_name} should be in the energy provider sink list taken into account for the constraints, but is not included in it ({energy_provider_feedin_sinks.keys()})." exp = { oemof_solph_object_asset: dict_model[OEMOF_SINK][dict_values[ENERGY_CONSUMPTION][DSO_sink_name] [LABEL]], oemof_solph_object_bus: dict_model[OEMOF_BUSSES][dict_values[ENERGY_CONSUMPTION][DSO_sink_name] [INFLOW_DIRECTION]], weighting_factor_energy_carrier: DEFAULT_WEIGHTS_ENERGY_CARRIERS[dict_values[ENERGY_CONSUMPTION] [DSO_sink_name][ENERGY_VECTOR]][VALUE], } for key in exp.keys(): assert ( key in energy_provider_feedin_sinks[DSO_sink_name] ), f"The parameter {key} for DSO {DSO_sink_name} not is not added for energy provider sinks processing for constraints." assert ( energy_provider_feedin_sinks[DSO_sink_name][key] == exp[key] ), f"The expected value (exp[key]) of {key} for {DSO_sink_name} is not met, but is of value {energy_provider_feedin_sinks[DSO_sink_name][key]}."