diff --git a/.gitignore b/.gitignore index c71709a..0cf3b1f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /docs/_build/ /docs/_build/doctrees/ /docs/_build/html/ -/.idea/ \ No newline at end of file +/.idea/ +/inputs/ \ No newline at end of file diff --git a/src/B_read_from_files.py b/src/B_read_from_files.py index 07496dd..ed6419b 100644 --- a/src/B_read_from_files.py +++ b/src/B_read_from_files.py @@ -59,6 +59,7 @@ ELECTRICITY_MG_FOLDER, STORAGE_FOLDER, LP_FILES_FOLDER, + USE_BIDIRECTIONAL_INVERTER_CONSTRAINT, ) # requires xlrd @@ -414,6 +415,12 @@ def get_case_definitions(file, sheet_project_sites): f"Parameter {EVALUATION_PERSPECTIVE} has to be either {AC_SYSTEM} or {DC_SYSTEM}, but is {case_definitions[case][EVALUATION_PERSPECTIVE]}" ) + if USE_BIDIRECTIONAL_INVERTER_CONSTRAINT not in case_definitions[case]: + case_definitions[case][USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] = False + logging.error( + f"Parameter {USE_BIDIRECTIONAL_INVERTER_CONSTRAINT} was not defined in excel input sheet and thus set to False." + ) + case_definitions[case].update( { NUMBER_OF_EQUAL_GENERATORS: int( diff --git a/src/C_sensitivity_experiments.py b/src/C_sensitivity_experiments.py index a6fc14a..7a76a01 100644 --- a/src/C_sensitivity_experiments.py +++ b/src/C_sensitivity_experiments.py @@ -49,6 +49,7 @@ INVERTER_DC_AC_COST_VAR, INVERTER_DC_AC_EFFICIENCY, INVERTER_DC_AC_LIFETIME, + INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR, MAINGRID_DISTANCE, MAINGRID_ELECTRICITY_PRICE, MAINGRID_EXTENSION_COST_INVESTMENT, @@ -1112,6 +1113,7 @@ def test_techno_economical_parameters_complete(experiment): INVERTER_DC_AC_COST_VAR: 0, INVERTER_DC_AC_EFFICIENCY: 1, INVERTER_DC_AC_LIFETIME: 15, + INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR: 1, MAINGRID_DISTANCE: 0, MAINGRID_ELECTRICITY_PRICE: 0.15, MAINGRID_EXTENSION_COST_INVESTMENT: 0, diff --git a/src/F_case_definitions.py b/src/F_case_definitions.py index 71d9e32..68c8e1d 100644 --- a/src/F_case_definitions.py +++ b/src/F_case_definitions.py @@ -70,6 +70,7 @@ SHARE_USAGE, SHARE_HYBRID, DEFAULT, + USE_BIDIRECTIONAL_INVERTER_CONSTRAINT, ) # This is not really a necessary class, as the whole experiement could be given to the function, but it ensures, that @@ -278,6 +279,13 @@ def update_dict(capacities_oem, specific_case, experiment): experiment_case_dict[ENABLE_INVERTER_ONLY_AT_BLACKOUT] = specific_case[ ENABLE_INVERTER_ONLY_AT_BLACKOUT ] + + ################################################# + # Include use bidirectional inverter constraint # + ################################################# + + experiment_case_dict[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] = specific_case[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] + return experiment_case_dict diff --git a/src/G1_oemof_create_model.py b/src/G1_oemof_create_model.py index 684ae8c..522000d 100644 --- a/src/G1_oemof_create_model.py +++ b/src/G1_oemof_create_model.py @@ -25,7 +25,11 @@ STORAGE_FIXED_CAPACITY, STORAGE_FIXED_POWER, RECTIFIER_AC_DC_FIXED_CAPACITY, + RECTIFIER_AC_DC_COST_INVESTMENT, INVERTER_DC_AC_FIXED_CAPACITY, + INVERTER_DC_AC_COST_INVESTMENT, + INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR, + USE_BIDIRECTIONAL_INVERTER_CONSTRAINT, ALLOW_SHORTAGE, STABILITY_CONSTRAINT, SHARE_BACKUP, @@ -220,9 +224,9 @@ def build(experiment, case_dict): # ------------point of coupling (feedin)------------# if case_dict[PCC_FEEDIN_FIXED_CAPACITY] == None: pass - # pointofcoupling_feedin = None + pointofcoupling_feedin = None elif case_dict[PCC_FEEDIN_FIXED_CAPACITY] is False: - generate.pointofcoupling_feedin_oem( + pointofcoupling_feedin = generate.pointofcoupling_feedin_oem( micro_grid_system, bus_electricity_ac, bus_electricity_ng_feedin, @@ -231,7 +235,7 @@ def build(experiment, case_dict): ) elif isinstance(case_dict[PCC_FEEDIN_FIXED_CAPACITY], float): - generate.pointofcoupling_feedin_fix( + pointofcoupling_feedin = generate.pointofcoupling_feedin_fix( micro_grid_system, bus_electricity_ac, bus_electricity_ng_feedin, @@ -452,6 +456,45 @@ def build(experiment, case_dict): + " faulty at renewable_share_constraint. Value can only be True or False" ) + # ------------Link transformer station capacities constraint ------------# + if case_dict[PCC_CONSUMPTION_FIXED_CAPACITY] != None and case_dict[PCC_FEEDIN_FIXED_CAPACITY] != None: + logging.info("Added constraint: Linking transformer station capacities.") + constraints_custom.constraint_equate_bidirectional_transformer_capacities( + model, + case_dict, + bus_electricity_ng_feedin, + bus_electricity_ng_consumption, + pointofcoupling_feedin, + pointofcoupling_consumption, + PCC_FEEDIN_FIXED_CAPACITY, + PCC_CONSUMPTION_FIXED_CAPACITY + ) + + # ------------Link rectifier and inverter capacities constraint------------# + if case_dict[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] != None: + if case_dict[USE_BIDIRECTIONAL_INVERTER_CONSTRAINT] is True: + logging.info("Added constraint: Linking rectifier and inverter capacities.") + constraints_custom.constraint_equate_bidirectional_transformer_capacities( + model, + case_dict, + bus_electricity_dc, + bus_electricity_ac, + inverter, + rectifier, + INVERTER_DC_AC_FIXED_CAPACITY, + RECTIFIER_AC_DC_FIXED_CAPACITY, + experiment[INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR] + ) + if experiment[RECTIFIER_AC_DC_COST_INVESTMENT] != 0: + logging.warning( + "Case definition of " + + case_dict[CASE_NAME] + + ": Are you sure that you want to define both rectifier and inverter costs if " + + "you link the capacties to receive a biderectional inverter? " + + "This would result in effective investment costs of " + + str(float(experiment[RECTIFIER_AC_DC_COST_INVESTMENT])+float(case_dict[INVERTER_AC_DC_COST_INVESTMENT])) + + " currency/kW bidirectional inverter." + ) # ------------Force charge from maingrid------------# if case_dict[FORCE_CHARGE_FROM_MAINGRID] is False: pass @@ -497,6 +540,7 @@ def build(experiment, case_dict): + " faulty at enable_inverter_at_backout. Value can only be True or False" ) + """ # ------------Allow shortage only for certain percentage of demand in a timestep------------# if case_dict['allow_shortage'] is True: @@ -507,6 +551,7 @@ def build(experiment, case_dict): shortage_constraints.timestep(model, case_dict, experiment, sink_demand_dc, source_shortage, bus_electricity_dc) """ + return micro_grid_system, model diff --git a/src/G2b_constraints_custom.py b/src/G2b_constraints_custom.py index debfbff..9e5a0af 100644 --- a/src/G2b_constraints_custom.py +++ b/src/G2b_constraints_custom.py @@ -4,6 +4,7 @@ import pyomo.environ as po import logging import pandas as pd +import oemof.solph as solph from src.constants import ( SHORTAGE_LIMIT, NUMBER_OF_EQUAL_GENERATORS, @@ -954,6 +955,18 @@ def inverter_only_at_blackout_test(case_dict, oemof_results, e_flows_df): return +# equate bi-directional transformer capacities +def constraint_equate_bidirectional_transformer_capacities(model, case_dict, bus_transformer_in, bus_transformer_out, transformer_in, transformer_out, name_transformer_in, name_transformer_out, factor = 1): + CAP_inverter = 0 + CAP_rectifier = 0 + if case_dict[name_transformer_in] != None and case_dict[name_transformer_out] != None: + if case_dict[name_transformer_in] is False and case_dict[name_transformer_out] is False: + CAP_inverter += model.InvestmentFlow.invest[bus_transformer_in, transformer_in] + CAP_rectifier += model.InvestmentFlow.invest[bus_transformer_out, transformer_out] + solph.constraints.equate_variables(model,CAP_rectifier, CAP_inverter, factor) + + return model + # todo shortage constraint / stbaility constraint only relates to AC bus def timestep(model, case_dict, experiment, el_bus, sink_demand, source_shortage): diff --git a/src/constants.py b/src/constants.py index f76cce0..f7431d0 100644 --- a/src/constants.py +++ b/src/constants.py @@ -110,6 +110,7 @@ INVERTER_DC_AC_COST_VAR = "inverter_dc_ac_cost_var" INVERTER_DC_AC_EFFICIENCY = "inverter_dc_ac_efficiency" INVERTER_DC_AC_LIFETIME = "inverter_dc_ac_lifetime" +INVERTER_RECTIFIER_CAPACITY_RATIO_FACTOR = "inverter_rectifier_capactiy_ratio_factor" MAINGRID_DISTANCE = "maingrid_distance" MAINGRID_ELECTRICITY_PRICE = "maingrid_electricity_price" MAINGRID_EXTENSION_COST_INVESTMENT = "maingrid_extension_cost_investment" @@ -308,6 +309,7 @@ WIND_FIXED_CAPACITY = "wind_fixed_capacity" RECTIFIER_AC_DC_FIXED_CAPACITY = "rectifier_ac_dc_fixed_capacity" INVERTER_DC_AC_FIXED_CAPACITY = "inverter_dc_ac_fixed_capacity" +USE_BIDIRECTIONAL_INVERTER_CONSTRAINT = "use_bidirectional_inverter_constraint" ALLOW_SHORTAGE = "allow_shortage" STABILITY_CONSTRAINT = "stability_constraint" RENEWABLE_CONSTRAINT = "renewable_constraint"