From 35f002b30fbcf3d7f220bb6dad0686a962dbf90a Mon Sep 17 00:00:00 2001 From: maartenbrinkerink <65602545+maartenbrinkerink@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:34:09 -0400 Subject: [PATCH] User_defined_capacity updates related to #173 -Added an efficiency parameter for both powerplants and transmission allowing for custom user entries. Overwrites any default input/output activity parameters. -Fixes in input/output activity parameters for user defined capacities for RES. -Removes "fixed/open" unused parameter. -Added example of RES technology in config file. -Added example of currently non existing transmission technology in config file. --- config/config.yaml | 14 +++-- .../osemosys_global/powerplant/constants.py | 5 -- .../osemosys_global/powerplant/main.py | 10 ++- .../powerplant/user_defined_capacity.py | 62 +++++++++++++------ .../osemosys_global/transmission/activity.py | 2 +- .../osemosys_global/transmission/constants.py | 5 -- .../osemosys_global/transmission/main.py | 12 +--- .../transmission/user_defined_capacity.py | 22 ++++--- 8 files changed, 73 insertions(+), 59 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index fbf8fe92..338b7282 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -51,20 +51,22 @@ solver: "cbc" # cbc, cplex, gurobi user_defined_capacity: # technology: [capacity, # first_year, - # "fixed/open", # first_year_of_expansion, # build_rate_per_year, - # cost] - PWRCOAINDWE01: [8, 2000, "open", 2025, 5, 1100] + # cost, + # efficiency] + PWRCOAINDWE01: [8, 2000, 2025, 5, 1100, 35] + PWRBIOINDWE01: [0, 2020, 2030, 2, 2000, 28] user_defined_capacity_transmission: # technology: [capacity, # first_year, - # "fixed/open", # first_year_of_expansion, # build_rate_per_year, - # cost] - TRNINDEAINDNE: [5, 1975, "open", 2030, 10, 861] + # cost, + # efficiency] + TRNINDEAINDNE: [5, 1975, 2030, 10, 861, 95] + TRNINDNOINDSO: [0, 2020, 2025, 2, 1800, 92] nodes_to_add: #- "AAAXX" where AAA is a 3-letter country code, diff --git a/workflow/scripts/osemosys_global/powerplant/constants.py b/workflow/scripts/osemosys_global/powerplant/constants.py index 82769a23..019eb820 100644 --- a/workflow/scripts/osemosys_global/powerplant/constants.py +++ b/workflow/scripts/osemosys_global/powerplant/constants.py @@ -109,11 +109,6 @@ NEW_IAR_COA = 0.33 NEW_IAR_DEFAULT = 1 -"""Set iar and oar values for custom transmission entries. I.e. oar of 0.9 -assumes 10% losses. Relevant for the user_defined_capacity function.""" -DF_IAR_CUSTOM_VAL = 1 -DF_OAR_CUSTOM_VAL = 0.9 - """Set column name dictionaries for different Global Energy Monitor (gem) input datasets""" GEM_COAL_COL = {'Country' : 'Country', 'Capacity (MW)' : 'VALUE', 'Status' : 'Status', 'Year' : 'Year_built', diff --git a/workflow/scripts/osemosys_global/powerplant/main.py b/workflow/scripts/osemosys_global/powerplant/main.py index 3be04f23..8a659baf 100644 --- a/workflow/scripts/osemosys_global/powerplant/main.py +++ b/workflow/scripts/osemosys_global/powerplant/main.py @@ -14,9 +14,7 @@ from constants import( DUPLICATE_TECHS, MODE_LIST, - RENEWABLES_LIST, - DF_IAR_CUSTOM_VAL, - DF_OAR_CUSTOM_VAL + RENEWABLES_LIST ) from data import( @@ -170,8 +168,7 @@ def main( start_year, end_year, region_name, - DF_IAR_CUSTOM_VAL, - DF_OAR_CUSTOM_VAL + RENEWABLES_LIST ) # Set availability factors. Occurs after set_user_defined_capacity as tech_set gets updated. @@ -253,7 +250,8 @@ def main( end_year = 2050 region_name = 'GLOBAL' custom_nodes = ["INDWE", "INDEA", "INDNE", "INDNO", "INDSO"] - tech_capacity = {'PWRCOAINDWE01': [8, 2000, "open", 2025, 5, 1100]} + tech_capacity = {'PWRCOAINDWE01': [8, 2000, 2025, 5, 1100, 35], + 'PWRBIOINDWE01': [0, 2020, 2030, 2, 2000, 28]} no_investment_techs = ["CSP", "WAV", "URN", "OTH", "WAS", "COG", "GEO", "BIO", "PET"] output_data_dir = 'results/data' diff --git a/workflow/scripts/osemosys_global/powerplant/user_defined_capacity.py b/workflow/scripts/osemosys_global/powerplant/user_defined_capacity.py index 9a1f2b48..564ab2ac 100644 --- a/workflow/scripts/osemosys_global/powerplant/user_defined_capacity.py +++ b/workflow/scripts/osemosys_global/powerplant/user_defined_capacity.py @@ -8,24 +8,24 @@ def set_user_defined_capacity(tech_capacity, op_life_dict, df_tech_set, df_min_cap_invest, df_max_cap_invest, df_res_cap, op_life_base, cap_act_base, cap_cost_base, df_iar_final, - df_oar_final, fuel_set, start_year, end_year, region_name, - DF_IAR_CUSTOM_VAL, DF_OAR_CUSTOM_VAL + df_oar_final, fuel_set, start_year, end_year, region_name, + RENEWABLES_LIST ): techCapacity = [] - tech_capacity_dict = {} first_year_dict = {} build_rate_dict = {} capex_dict = {} build_year_dict = {} + efficiency_dict = {} for tech, tech_params in tech_capacity.items(): techCapacity.append([tech, tech_params[0], tech_params[1]]) - tech_capacity_dict[tech] = tech_params[2] #UNUSED ENTRY build_year_dict[tech] = tech_params[1] - first_year_dict[tech] = tech_params[3] - build_rate_dict[tech] = tech_params[4] - capex_dict[tech] = tech_params[5] + first_year_dict[tech] = tech_params[2] + build_rate_dict[tech] = tech_params[3] + capex_dict[tech] = tech_params[4] + efficiency_dict[tech] = tech_params[5] tech_capacity_df = pd.DataFrame(techCapacity, columns=['TECHNOLOGY', 'VALUE', 'YEAR']) tech_capacity_df['REGION'] = region_name @@ -136,17 +136,39 @@ def set_user_defined_capacity(tech_capacity, op_life_dict, df_tech_set, 'YEAR'] ) - df_iar_custom.loc[df_iar_custom['MODE_OF_OPERATION']==1,'FUEL'] = ( - df_iar_custom['TECHNOLOGY'].str[3:9]) - df_iar_custom.loc[df_iar_custom['MODE_OF_OPERATION']==2,'FUEL'] = ( - df_iar_custom['TECHNOLOGY'].str[3:6] + "INT") - df_oar_custom.loc[df_oar_custom['MODE_OF_OPERATION']==1,'FUEL'] = ( - 'ELC' + df_oar_custom['TECHNOLOGY'].str[6:11] + '01') - df_oar_custom.loc[df_oar_custom['MODE_OF_OPERATION']==2,'FUEL'] = ( - 'ELC' + df_oar_custom['TECHNOLOGY'].str[6:11] + '01') - - df_iar_custom['VALUE'] = DF_IAR_CUSTOM_VAL - df_oar_custom['VALUE'] = DF_OAR_CUSTOM_VAL + for each_tech in tech_list: + if each_tech[3:6] in RENEWABLES_LIST: + + df_iar_custom.loc[(df_iar_custom['TECHNOLOGY'] == each_tech) & + (df_iar_custom['MODE_OF_OPERATION']==1),'FUEL'] = ( + df_iar_custom['TECHNOLOGY'].str[3:11]) + + df_oar_custom.loc[(df_oar_custom['TECHNOLOGY'] == each_tech) & + (df_oar_custom['MODE_OF_OPERATION']==1),'FUEL'] = ( + 'ELC' + df_oar_custom['TECHNOLOGY'].str[6:11] + '01') + + else: + + df_iar_custom.loc[(df_iar_custom['TECHNOLOGY'] == each_tech) & + (df_iar_custom['MODE_OF_OPERATION']==1),'FUEL'] = ( + df_iar_custom['TECHNOLOGY'].str[3:9]) + + df_iar_custom.loc[(df_iar_custom['TECHNOLOGY'] == each_tech) & + (df_iar_custom['MODE_OF_OPERATION']==2),'FUEL'] = ( + df_iar_custom['TECHNOLOGY'].str[3:6] + "INT") + + df_oar_custom.loc[(df_oar_custom['TECHNOLOGY'] == each_tech) & + (df_oar_custom['MODE_OF_OPERATION']==1),'FUEL'] = ( + 'ELC' + df_oar_custom['TECHNOLOGY'].str[6:11] + '01') + df_oar_custom.loc[(df_oar_custom['TECHNOLOGY'] == each_tech) & + (df_oar_custom['MODE_OF_OPERATION']==2),'FUEL'] = ( + 'ELC' + df_oar_custom['TECHNOLOGY'].str[6:11] + '01') + + for each_tech in tech_list: + df_iar_custom.loc[df_iar_custom['TECHNOLOGY'] == each_tech, + 'VALUE'] = round(1 / (efficiency_dict[each_tech] / 100), 3) + + df_oar_custom['VALUE'] = 1 df_iar_custom['REGION'] = region_name df_oar_custom['REGION'] = region_name @@ -163,6 +185,10 @@ def set_user_defined_capacity(tech_capacity, op_life_dict, df_tech_set, 'YEAR', 'VALUE',]] + # Drop mode 2 for renewable techs + df_iar_custom = df_iar_custom.loc[df_iar_custom['FUEL'] != 0] + df_oar_custom = df_oar_custom.loc[df_oar_custom['FUEL'] != 0] + df_iar = pd.concat([df_iar_final, df_iar_custom]) df_oar = pd.concat([df_oar_final, df_oar_custom]) diff --git a/workflow/scripts/osemosys_global/transmission/activity.py b/workflow/scripts/osemosys_global/transmission/activity.py index 97535f93..1969d728 100644 --- a/workflow/scripts/osemosys_global/transmission/activity.py +++ b/workflow/scripts/osemosys_global/transmission/activity.py @@ -22,7 +22,7 @@ def activity_transmission(df_iar_base, df_oar_base, df_pw_prop, df_trn_efficienc df_iar_trn.drop_duplicates(keep="first", inplace=True) # Only keep technologies linked to the correct fuel - df_iar_trn = df_iar_trn.loc[df_iar_trn['FUEL'].str.contains('ELC')] + df_iar_trn = df_iar_trn.loc[df_iar_trn['FUEL'].str.contains('ELC', na = False)] # OAR for transmission technologies is IAR, but the fuel is 02 instead of 01: df_oar_trn = df_iar_trn.copy() diff --git a/workflow/scripts/osemosys_global/transmission/constants.py b/workflow/scripts/osemosys_global/transmission/constants.py index a38ca4bf..ffcc1c50 100644 --- a/workflow/scripts/osemosys_global/transmission/constants.py +++ b/workflow/scripts/osemosys_global/transmission/constants.py @@ -1,10 +1,5 @@ """Constants for the transmission module""" -"""Set iar and oar values for custom transmission entries. I.e. oar of 0.9 -assumes 10% losses. Relevant for the user_defined_capacity function.""" -DF_IAR_CUSTOM_VAL = 1 -DF_OAR_CUSTOM_VAL = 0.9 - SET_DTYPES = { "DAILYTIMEBRACKET": int, "EMISSION":str, diff --git a/workflow/scripts/osemosys_global/transmission/main.py b/workflow/scripts/osemosys_global/transmission/main.py index c423c776..db511dcc 100644 --- a/workflow/scripts/osemosys_global/transmission/main.py +++ b/workflow/scripts/osemosys_global/transmission/main.py @@ -17,11 +17,6 @@ import_set_base ) -from constants import( - DF_IAR_CUSTOM_VAL, - DF_OAR_CUSTOM_VAL - ) - from activity import( activity_transmission, activity_transmission_limit, @@ -107,9 +102,7 @@ def main( df_cap_cost_trn_final, start_year, end_year, - region_name, - DF_IAR_CUSTOM_VAL, - DF_OAR_CUSTOM_VAL + region_name ) # get new additions to fuel and technology sets @@ -200,7 +193,8 @@ def main( end_year = 2050 region_name = 'GLOBAL' custom_nodes = ["INDWE", "INDEA", "INDNE", "INDNO", "INDSO"] - tech_capacity_trn = {'TRNINDEAINDNE': [5, 1975, "open", 2030, 10, 861]} + tech_capacity_trn = {'TRNINDEAINDNE': [5, 1975, 2030, 10, 861, 95], + 'TRNINDNOINDSO': [0, 2020, 2025, 5, 1800, 92]} no_investment_techs = ["CSP", "WAV", "URN", "OTH", "WAS", "COG", "GEO", "BIO", "PET"] cross_border_trade = True diff --git a/workflow/scripts/osemosys_global/transmission/user_defined_capacity.py b/workflow/scripts/osemosys_global/transmission/user_defined_capacity.py index cd7f9a0a..e4624f18 100644 --- a/workflow/scripts/osemosys_global/transmission/user_defined_capacity.py +++ b/workflow/scripts/osemosys_global/transmission/user_defined_capacity.py @@ -8,23 +8,22 @@ def set_user_defined_capacity_trn(tech_capacity_trn, op_life_dict, df_min_cap_invest, df_max_cap_invest, df_res_cap, df_iar_final, df_oar_final, op_life_base, - cap_cost_base, start_year, end_year, region_name, - df_iar_custom_val, df_oar_custom_val): + cap_cost_base, start_year, end_year, region_name): techCapacity_trn = [] - tech_capacity_trn_dict = {} first_year_dict = {} build_rate_dict = {} capex_dict = {} build_year_dict = {} + efficiency_dict = {} for tech, tech_params in tech_capacity_trn.items(): techCapacity_trn.append([tech, tech_params[0], tech_params[1]]) - tech_capacity_trn_dict[tech] = tech_params[2] #UNUSED ENTRY build_year_dict[tech] = tech_params[1] - first_year_dict[tech] = tech_params[3] - build_rate_dict[tech] = tech_params[4] - capex_dict[tech] = tech_params[5] + first_year_dict[tech] = tech_params[2] + build_rate_dict[tech] = tech_params[3] + capex_dict[tech] = tech_params[4] + efficiency_dict[tech] = tech_params[5] tech_capacity_trn_df = pd.DataFrame(techCapacity_trn, columns=['TECHNOLOGY', 'VALUE', 'YEAR']) tech_capacity_trn_df['REGION'] = region_name @@ -148,8 +147,13 @@ def set_user_defined_capacity_trn(tech_capacity_trn, op_life_dict, 'FUEL'] = ('ELC' + df_oar_custom['TECHNOLOGY'].str[3:8] + '01') - df_iar_custom['VALUE'] = df_iar_custom_val - df_oar_custom['VALUE'] = df_oar_custom_val + + df_iar_custom['VALUE'] = 1 + + for each_trn in tech_list: + df_oar_custom.loc[df_oar_custom['TECHNOLOGY'] == each_trn, + 'VALUE'] = efficiency_dict[each_trn] / 100 + df_iar_custom['REGION'] = region_name df_oar_custom['REGION'] = region_name