diff --git a/CHANGELOG.md b/CHANGELOG.md index 11fb1159f..15149fefd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### input data/calibration -- new input data rev6.84 [[#1757]] (https://github.com/remindmodel/remind/pull/1757) +- new input data rev6.84 [[#1757](https://github.com/remindmodel/remind/pull/1757)] - CES parameter and gdx files calibrated with new default diffLin2Lin for NPi [[#1747](https://github.com/remindmodel/remind/pull/1747)] and [[#1757](https://github.com/remindmodel/remind/pull/1757)] @@ -15,7 +15,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### changed - plastic waste by default does not lag plastics production by ten years anymore; can be re-activated using `cm_wastelag` -- moved to edgeTransport 2.0 version [[#1749](https://github.com/remindmodel/remind/pull/1749] +- moved to edgeTransport 2.0 version [[#1749](https://github.com/remindmodel/remind/pull/1749)] +- **scripts** in readCheckScenarioConfig(), do not automatically remove path_gdx_bau if allegedly 'not needed' + [[#1809](https://github.com/remindmodel/remind/pull/1809)] ### added - **50_damages**, **51_internalizeDamages** add KotzWenz realization based on Kotz & Wenz (2024) @@ -31,6 +33,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). [[#1773](https://github.com/remindmodel/remind/pull/1773)] - **scripts** add support for EDGE-Transport standalone results to cs2 [[#1780](https://github.com/remindmodel/remind/pull/1780)] +- **scripts** add option to use raw land-use change emissions variable in coupled runs + [[#1796](https://github.com/remindmodel/remind/pull/1796)] - **testthat** fail if manipulating main.gms with default cfg drops/changes switches and comments [[#1764](https://github.com/remindmodel/remind/pull/1764)] and [[#1767](https://github.com/remindmodel/remind/pull/1767)] @@ -38,6 +42,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). [[#1777](https://github.com/remindmodel/remind/pull/1777)] - **32_power** increase minimum required dispatchable back-up capacity for VRE integration [[#1789](https://github.com/remindmodel/remind/pull/1789)] +- **scripts** integrate automated scenario validation via piamValidation as output script + [[#1790](https://github.com/remindmodel/remind/pull/1790)] ### fixed - included CCS from plastic waste incineration in CCS mass flows so it is diff --git a/CITATION.cff b/CITATION.cff index 9fde44ecc..3f1f24a44 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -266,8 +266,8 @@ abstract: REMIND (REgional Model of Investment and Development) is a numerical technology, policy and climate constraints. It also accounts for regional trade characteristics on goods, energy fuels, and emissions allowances. All greenhouse gas emissions due to human activities are represented in the model. -version: "3.3.2.dev392" -date-released: 2024-08-22 +version: "3.3.2.dev501" +date-released: 2024-09-03 repository-code: https://github.com/remindmodel/remind keywords: - energy diff --git a/DESCRIPTION b/DESCRIPTION index 99ec97322..521bd2f52 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,7 +17,7 @@ Imports: data.table, devtools, dplyr, - edgeTransport (>= 2.0), + edgeTransport (>= 2.3.0), reporttransport (>= 0.0.11), flexdashboard, GDPuc, diff --git a/config/default.cfg b/config/default.cfg index 215a29c6c..29eda7838 100644 --- a/config/default.cfg +++ b/config/default.cfg @@ -71,7 +71,7 @@ cfg$validationmodel_name <- "VALIDATIONREMIND" #### model version of the overall model (used for run statistics only). # automatically generated for development versions, updated by hand for releases -cfg$model_version <- "3.3.2.dev392" +cfg$model_version <- "3.3.2.dev501" #### settings #### cfg$gms <- list() @@ -150,7 +150,8 @@ cfg$files2export$start <- c("config/conopt3.opt", "modules/35_transport/edge_esm/input/scenSpecEnIntensity.cs4r", "modules/35_transport/edge_esm/input/initialIncoCosts.cs4r", "modules/35_transport/edge_esm/input/annualMileage.cs4r", - "modules/35_transport/edge_esm/input/timeValueCosts.cs4r") + "modules/35_transport/edge_esm/input/timeValueCosts.cs4r", + "modules/29_CES_parameters/calibrate/input/f29_trpdemand.cs4r") # Files that should be copied after the REMIND run is finished cfg$files2export$end <- NULL diff --git a/config/scenario_config_21_EU11_ARIADNE.csv b/config/scenario_config_21_EU11_ARIADNE.csv index 3eeb79a18..6d18b2659 100755 --- a/config/scenario_config_21_EU11_ARIADNE.csv +++ b/config/scenario_config_21_EU11_ARIADNE.csv @@ -2,7 +2,7 @@ title;start;copyConfigFrom;.description;CES_parameters;c_keep_iteration_gdxes;cm # _____Reference Runs_____;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Calib_EU_NPi;0;;Calibration Run with National Policies Implemented (NPI);calibrate;;;;;;;;;se_trade;;;;;;;;;DEU 1.1, EU27_regi 7.5;;EU27_regi.pebiolc.worldPricemarkup 10;1;;EUR_regi, NEU_regi;;;;;;;;;;;;;;;;;;./config/regionmapping_21_EU11.csv;./config/extramapping_EU27.csv;rcp45;;;NPi;1;;;NPi2018;regiCarbonPrice;;;;on;on;Mix1;9;3;;;;2005;; NPi;0;Calib_EU_NPi;National Policies implemented;load;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Calib_EU_Npi_lowDem;0;Calib_EU_NPi;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;NAV_all;;;;gdp_SSP2EU;gdp_SSP2EU_NAV_all;;; +Calib_EU_Npi_lowDem;0;Calib_EU_NPi;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;NAV_all;;;;;gdp_SSP2EU_NAV_all;;; Npi_lowDem;0;Calib_EU_Npi_lowDem;;load;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ____ Standard Scenarios______;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CurrentPolicies;0;NPi;Current Policies Scenario for Germany including latest credible developments from Fit for 55 and Ampel government;;;;;;;;;;;2035.2045.FRA.DEU.seel 0.045, 2035.2045.ESW.DEU.seh2 0.091, 2035.2045.MEA.DEU.seliqsyn 0.091;;;;2;;high;0;DEU 1.1, EU27_regi 7.5;;EU27_regi.pebiolc.worldPricemarkup 10;1;;EUR_regi, NEU_regi;;off;;;fehob 1.75, enhb 0.5;;;ariadne_bal;;;manual; 2050 . GLO . (ue_cement, ue_steel_primary, ue_steel_secondary) 0.75, 2100 . GLO . (ue_chemicals, ue_otherInd) 0.90, 2100 . DEU . (ue_otherInd, ue_cement, ue_chemicals) 0.01;;;;;;;;;;;;;;;;;EU27_regi.(2025 65,2030 94,2035 124,2040 141,2045 162,2050 175,2055 175,2060 175,2070 175,2080 175,2090 175,2100 175,2110 175,2130 175,2150 175);;;;;Mix3;;;;;;2025;;NPi @@ -12,7 +12,7 @@ KN2045_H2_v4;0;KN2045_Bal_v4;Scenario with high H2 and synfuel use, high H2 and # ____ Energy Security Scenarios___;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; KN2045_EnSov;0;KN2045_Bal_v4;Energy security scenario with limits/taxes on PE gas consumption in Germany and reduced steel demand;;;;;;;;;;;;on;2;ensec;;;;;;;;;;EUR_regi, NEU_regi;;;;;feelhpb 1.4, fehob 1.75, enhb 0.5;;feelhth_otherInd 1.1, fega_steel 0.4;ariadne_lowDem;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # ____ low-demand/high-demand scenarios ____;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -KN2045plus_EasyRide;0;KN2045_Bal_v4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;feelhpb 1.4, fehob 1.75, enhb 0.5, feheb 0.01;;feelhth_otherInd 0.9, feh2_chemicals 0.43;ariadne_lowDem;;;;2050 . GLO . (ue_cement, ue_steel_primary, ue_steel_secondary) 0.75, 2100 . GLO . (ue_chemicals, ue_otherInd) 0.90;;;tdh2s 0.5, tdh2t 0.5;spv 0.5, storspv 0.5, wind 0.5, storwind 0.5, elh2 0.5;spv 2, storspv 2, wind 2, storwind 2, elh2 2;;;;;;;;;;;;;off;;;;NAV_all;;;;gdp_SSP2EU;gdp_SSP2EU_NAV_all;;;Npi_lowDem -KN2045plus_LowDemand;0;KN2045_Bal_v4;;;;;;;;;;;;2035.2045.FRA.DEU.seel 0.045, 2035.2045.ESW.DEU.seh2 0.091, 2035.2045.MEA.DEU.seliqsyn 0.091;;;;;;;;;;;;;;;;;;feelhpb 1.4, fehob 1.75, enhb 0.5, feheb 0.01;;feelhth_otherInd 0.9, feh2_chemicals 0.43;ariadne_bal;;;;2050 . GLO . (ue_cement, ue_steel_primary, ue_steel_secondary) 0.75, 2100 . GLO . (ue_chemicals, ue_otherInd) 0.90;;;tdh2s 3, tdh2t 3;spv 2, storspv 2, wind 2, storwind 2, elh2 2;spv 0.5, storspv 0.5, wind 0.5, storwind 0.5, elh2 0.5;;;;;;;;;;;;;off;;;;NAV_all;;;;gdp_SSP2EU;gdp_SSP2EU_NAV_all;;;Npi_lowDem +KN2045plus_EasyRide;0;KN2045_Bal_v4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;feelhpb 1.4, fehob 1.75, enhb 0.5, feheb 0.01;;feelhth_otherInd 0.9, feh2_chemicals 0.43;ariadne_lowDem;;;;2050 . GLO . (ue_cement, ue_steel_primary, ue_steel_secondary) 0.75, 2100 . GLO . (ue_chemicals, ue_otherInd) 0.90;;;tdh2s 0.5, tdh2t 0.5;spv 0.5, storspv 0.5, wind 0.5, storwind 0.5, elh2 0.5;spv 2, storspv 2, wind 2, storwind 2, elh2 2;;;;;;;;;;;;;off;;;;NAV_all;;;;;gdp_SSP2EU_NAV_all;;;Npi_lowDem +KN2045plus_LowDemand;0;KN2045_Bal_v4;;;;;;;;;;;;2035.2045.FRA.DEU.seel 0.045, 2035.2045.ESW.DEU.seh2 0.091, 2035.2045.MEA.DEU.seliqsyn 0.091;;;;;;;;;;;;;;;;;;feelhpb 1.4, fehob 1.75, enhb 0.5, feheb 0.01;;feelhth_otherInd 0.9, feh2_chemicals 0.43;ariadne_bal;;;;2050 . GLO . (ue_cement, ue_steel_primary, ue_steel_secondary) 0.75, 2100 . GLO . (ue_chemicals, ue_otherInd) 0.90;;;tdh2s 3, tdh2t 3;spv 2, storspv 2, wind 2, storwind 2, elh2 2;spv 0.5, storspv 0.5, wind 0.5, storwind 0.5, elh2 0.5;;;;;;;;;;;;;off;;;;NAV_all;;;;;gdp_SSP2EU_NAV_all;;;Npi_lowDem KN2045minus_WorstCase;0;KN2045_Bal_v4;;;;;;;;;;;;2035.2045.FRA.DEU.seel 0.045, 2035.2045.ESW.DEU.seh2 0.091, 2035.2045.MEA.DEU.seliqsyn 0.091;;;;;;;;;;;;;;;;;;feelhpb 2.3, feelrhb 0.87, fehob 1.75, enhb 0.5;;;ariadne_highDem;;;;;;;tdh2s 3, tdh2t 3;spv 2, storspv 2, wind 2, storwind 2, elh2 2;spv 0.5, storspv 0.5, wind 0.5, storwind 0.5, elh2 0.5;;;;;;;;;;;;;;;;;;;;;;;;; KN2045minus_SupplyFocus;0;KN2045_Bal_v4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ariadne_highDem;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/config/scenario_config_DeepEl.csv b/config/scenario_config_DeepEl.csv index f72f817fe..22fa0f660 100644 --- a/config/scenario_config_DeepEl.csv +++ b/config/scenario_config_DeepEl.csv @@ -3,7 +3,7 @@ testOneRegi-Base-DeepEl;0;;testOneRegi;8;;;;0;;;;;;;;;;;;;;;;;;;;;;;;testOneRegi # H12 SSP2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SSP2-NPi-calibrate-DeepEl;1;calibrate;;14;rcp45;;;0;;0;NPi;1;2100;;9;;;;NPi2018;regiCarbonPrice;on;on;3;;heat;Mix1;2005;;;;;SSP2-NPi-calibrate: This reference policy/baseline scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. SSP2-Base-DeepEl;1;;;1;;;;0;;0;;;2100;;;off;;;;;;;;;heat;Mix1;2005;;;;;SSP2-Base: This baseline calibration scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. -SSP2-NPi-DeepEl;1;;;1;rcp45;3;;0;;0;NPi;1;2100;;9;;;;NPi2018;regiCarbonPrice;on;on;3;;heat;Mix1;2005;;;;;SSP2-NPi: This National Policies Implemented (Npi) scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The NPi is identical to the NDC scenario until 2020 but assumes that policies fail to achieve NDC targets in 2030. Instead, carbon prices are assumed to grow and converge more slowly, leading to emissions trajectories in line with bottom-up studies on the effect of currently implemented policies. -SSP2-NDC-DeepEl;1;;;1;rcp45;3;globallyOptimal;0;;0;NDC;1;2100;;9;;;;NDC;regiCarbonPrice;on;on;3;;heat;Mix2;2025;;SSP2-NPi-DeepEl;SSP2-NPi-DeepEl;;SSP2-NDC: This Nationally Determined Contribution (NDC) scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The NDC includes all pledged policies even if not yet implemented. It assumes that the moderate and heterogeneous climate ambition reflected in the NDCs at the begining of 2021 continues over the 21st century. This scenario serves as reference for all other policy scenarios and The NPi scenario until 2020. -SSP2-PkBudg500-DeepEl;1;;;1;rcp20;9;globallyOptimal;1;2050.GLO 0.9;500;diffCurvPhaseIn2Lin;100;2080;;9;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.13, IND_regi.pc 0.13;100;5;NDC;regiCarbonPrice;on;on;2;1;heat;Mix4;2025;;SSP2-NPi-DeepEl;SSP2-NPi-DeepEl;;SSP2-PkBudg500: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. -SSP2-PkBudg1150-DeepEl;1;;;1;rcp26;9;globallyOptimal;1;2050.GLO 0.5;1150;diffCurvPhaseIn2Lin;60;2100;;9;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.13, IND_regi.pc 0.13;100;5;NDC;regiCarbonPrice;on;on;2;1;heat;Mix4;2025;;SSP2-NPi-DeepEl;SSP2-NPi-DeepEl;;SSP2-PkBudg1150: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 1150 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a weel below 2??C scenario, peak warming is allowed to be at or slightly above 2??C, at median climate sensitivity but returns to values below 2??C in at least 67?% of scenarios by the end of the century. +SSP2-NPi-DeepEl;1;;;1;rcp45;3;;0;;0;NPi;1;2100;;9;;;;NPi2018;regiCarbonPrice;on;on;3;;heat;Mix1;2005;;;;;SSP2-NPi: This National Policies Implemented (NPi) scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The NPi is identical to the NDC scenario until 2020 but assumes that policies fail to achieve NDC targets in 2030. Instead, carbon prices are assumed to grow and converge more slowly, leading to emissions trajectories in line with bottom-up studies on the effect of currently implemented policies. +SSP2-NDC-DeepEl;1;;;1;rcp45;3;globallyOptimal;0;;0;NDC;1;2100;;9;;;;NDC;regiCarbonPrice;on;on;3;;heat;Mix2;2025;;SSP2-NPi-DeepEl;SSP2-NPi-DeepEl;;SSP2-NDC: This Nationally Determined Contribution (NDC) scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The NDC includes all pledged policies even if not yet implemented. It assumes that the moderate and heterogeneous climate ambition reflected in the NDCs at the begining of 2021 continues over the 21st century. +SSP2-PkBudg500-DeepEl;1;;;1;rcp20;9;globallyOptimal;1;2050.GLO 0.9;500;diffCurvPhaseIn2Lin;100;2080;;9;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.13, IND_regi.pc 0.13;100;5;NDC;regiCarbonPrice;on;on;2;1;heat;Mix4;2025;;SSP2-NPi-DeepEl;;;SSP2-PkBudg500: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5 C scenario, peak warming is allowed to be at or slightly above 1.5 C, at median climate sensitivity but returns to values below 1.5 C in at least 67 % of scenarios by the end of the century. +SSP2-PkBudg1150-DeepEl;1;;;1;rcp26;9;globallyOptimal;1;2050.GLO 0.5;1150;diffCurvPhaseIn2Lin;60;2100;;9;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.13, IND_regi.pc 0.13;100;5;NDC;regiCarbonPrice;on;on;2;1;heat;Mix4;2025;;SSP2-NPi-DeepEl;;;SSP2-PkBudg1150: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 1150 Gt CO2 on total CO2 emissions from 2015 to 2100. This is a well below 2 C scenario, peak warming is allowed to be at or slightly above 2 C, at median climate sensitivity but returns to values below 2 C in at least 67 % of scenarios by the end of the century. diff --git a/config/scenario_config_IKEA.csv b/config/scenario_config_IKEA.csv index 10d99c8ec..284a2e11f 100644 --- a/config/scenario_config_IKEA.csv +++ b/config/scenario_config_IKEA.csv @@ -11,8 +11,8 @@ SSP2-NPi;0;;floor cost default;;;;;default;;1;5;;;rcp45;default;3;;0;0;;0;NPi;1; SSP2-NDC;0;;floor cost default;;;;;default;;1;5;;;rcp45;default;3;;0;0;globallyOptimal;0;NDC;1;2100;9;2;GLO 0.05, EUR_regi 0.15;CHA_regi.pc 0.001, IND_regi.pc 0.001, SSA_regi.pc 0.001, OAS_regi.pc 0.001, CHA_regi.coalchp 0.001, IND_regi.coalchp 0.001, SSA_regi.coalchp 0.001, OAS_regi.coalchp 0.001;;;;;;;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809;2020.2030.EUR_regi.all.year.netGHG_LULUCFGrassi 2.450;on;on;EUR_regi, NEU_regi;3;;heat;Mix2;2030;;SSP2-NPi;SSP2-NPi;;SSP2-NDC: This Nationally Determined Contribution (NDC) scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The NDC includes all pledged policies even if not yet implemented. It assumes that the moderate and heterogeneous climate ambition reflected in the NDCs at the begining of 2021 continues over the 21st century. This scenario serves as reference for all other policy scenarios and The NPi scenario until 2020. SSP2-PkBudg1150;0;;floor cost default;;;;;default;;1;5;;;rcp26;default;9;2100;1;1;globallyOptimal;1150;diffCurvPhaseIn2Lin;60;2100;9;2;GLO 0.06, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg1150: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 1150 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a weel below 2??C scenario, peak warming is allowed to be at or slightly above 2??C, at median climate sensitivity but returns to values below 2??C in at least 67?% of scenarios by the end of the century. SSP2-PkBudg650;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;650;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg650: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. -SSP2-PkBudg620;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;620;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2NPi;;SSP2PkBudg620: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. -SSP2PkBudg590;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;590;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg590: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. +SSP2-PkBudg620;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;620;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg620: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. +SSP2-PkBudg590;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;590;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg590: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. SSP2-PkBudg560;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;560;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg550: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. SSP2-PkBudg530;0;;floor cost default;;;2;;default;;1;5;;;rcp20;default;9;2100;1;1;globallyOptimal;530;diffCurvPhaseIn2Lin;100;2080;9;2;GLO 0.09, EUR_regi 0.15;GLO.(biodiesel 0.14, bioeths 0.14), EUR_regi.(biodiesel 0.15, bioeths 0.15), USA_regi.pc 0.13, REF_regi.pc 0.13, CHA_regi.pc 0.04, (IND_regi, SSA_regi, OAS_regi).pc 0.001, (IND_regi, SSA_regi, OAS_regi).coalchp 0.001;;;75;2;feelhpb 1.05, fehob 1.75, feheb 0.35;feh2_otherInd 1.05, feelhth_otherInd 0.43, feh2_cement 2.2, feelhth_chemicals 1.4, feh2_chemicals 1.05, fehos_cement 2.2;NDC;regiCarbonPrice;2030.EUR_regi.tax.t.FE_wo_b_wo_n_e.all 1.2809, 2050.GLO.tax.t.CCS.biomass 2000;;on;on;EUR_regi, NEU_regi;;1;heat;Mix4;2030;;SSP2-NPi;SSP2-NPi;;SSP2-PkBudg500: This climate policy scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The stylized climate policy scenario assumes a peak budget of 500 Gt?CO2 on total CO2 emissions from 2015 to 2100. This is a 1.5??C scenario, peak warming is allowed to be at or slightly above 1.5??C, at median climate sensitivity but returns to values below 1.5??C in at least 67?% of scenarios by the end of the century. SSP2-NPi_floor2;0;;floor cost preserves price structure;;;;;pricestruc;;1;5;;;rcp45;pricestruc;3;;0;0;;0;NPi;1;2100;9;2;GLO 0.04, EUR_regi 0.15;CHA_regi.pc 0.001, IND_regi.pc 0.001, SSA_regi.pc 0.001, OAS_regi.pc 0.001, CHA_regi.coalchp 0.001, IND_regi.coalchp 0.001, SSA_regi.coalchp 0.001, OAS_regi.coalchp 0.001;;;;;;;NPi2018;regiCarbonPrice;;;on;on;EUR_regi, NEU_regi;3;;heat;Mix1;2030;;;;;SSP2-NPi: This National Policies Implemented (Npi) scenario follows the Shared Socioeconomic Pathways 2 called Middle of the Road. The NPi is identical to the NDC scenario until 2020 but assumes that policies fail to achieve NDC targets in 2030. Instead, carbon prices are assumed to grow and converge more slowly, leading to emissions trajectories in line with bottom-up studies on the effect of currently implemented policies. diff --git a/config/tests/scenario_config_shortCascade.csv b/config/tests/scenario_config_shortCascade.csv index cc8b6b5e1..31901ef3b 100644 --- a/config/tests/scenario_config_shortCascade.csv +++ b/config/tests/scenario_config_shortCascade.csv @@ -1,4 +1,4 @@ -title;start;c_empty_model;path_gdx_ref;path_gdx_bau;output -TESTTHAT-SSP2-Base;1;on;;;reportingREMIND2MAgPIE -TESTTHAT-SSP2-NDC;1;on;TESTTHAT-SSP2-Base;TESTTHAT-SSP2-Base;reportingREMIND2MAgPIE -TESTTHAT-SSP2-Policy;2;on;TESTTHAT-SSP2-Base;TESTTHAT-SSP2-Base;reportingREMIND2MAgPIE +title;start;c_empty_model;path_gdx_ref;output +TESTTHAT-SSP2-Base;1;on;;reportingREMIND2MAgPIE +TESTTHAT-SSP2-NDC;1;on;TESTTHAT-SSP2-Base;reportingREMIND2MAgPIE +TESTTHAT-SSP2-Policy;2;on;TESTTHAT-SSP2-Base;reportingREMIND2MAgPIE diff --git a/core/bounds.gms b/core/bounds.gms index 4c32b68e6..f55d8de6a 100755 --- a/core/bounds.gms +++ b/core/bounds.gms @@ -43,16 +43,16 @@ loop(se2se(enty,enty2,te), loop(regi, loop(teRe2rlfDetail(te,rlf), if( (pm_dataren(regi,"maxprod",rlf,te) gt 0), - vm_capDistr.lo(t,regi,te,rlf)$(t.val gt 2011) = 1e-8; + v_capDistr.lo(t,regi,te,rlf)$(t.val gt 2011) = 1e-8; *cb* make sure that grade distribution in early time steps with capacity fixing is close to optimal one assumed for vm_capFac calibration, divide by p_aux_capacityFactorHistOverREMIND to correct for deviation of REMIND capacity factors from historic capacity factors - vm_capDistr.lo("2015",regi,te,rlf) = 0.90 / max(1, p_aux_capacityFactorHistOverREMIND(regi,te)) * p_aux_capThisGrade(regi,te,rlf); - vm_capDistr.lo("2020",regi,te,rlf) = 0.90 / max(1, p_aux_capacityFactorHistOverREMIND(regi,te)) * p_aux_capThisGrade(regi,te,rlf); + v_capDistr.lo("2015",regi,te,rlf) = 0.90 / max(1, p_aux_capacityFactorHistOverREMIND(regi,te)) * p_aux_capThisGrade(regi,te,rlf); + v_capDistr.lo("2020",regi,te,rlf) = 0.90 / max(1, p_aux_capacityFactorHistOverREMIND(regi,te)) * p_aux_capThisGrade(regi,te,rlf); ); ); ); *' Make sure no grades > 9 are used. Only cosmetic to avoid entries in lst file -vm_capDistr.fx(t,regi,te,rlf)$(rlf.val gt 9) = 0; +v_capDistr.fx(t,regi,te,rlf)$(rlf.val gt 9) = 0; *' No battery storage in 2010: vm_cap.up("2010",regi,teStor,"1") = 0; @@ -341,29 +341,36 @@ vm_deltaCap.fx(t,regi,te,rlf)$(t.val le 2025 AND pm_data(regi,"tech_stat",te) eq *CB allow for early retirement at the start of free model time *CB ------------------------------------------------------------ *** allow non zero early retirement for all technologies to avoid mathematical errors -vm_capEarlyReti.up(ttot,regi,te) = 1e-6; - +vm_capEarlyReti.up(t,regi,te) = 1e-6; ***generally allow full early retiremnt for all fossil technologies without CCS -vm_capEarlyReti.up(ttot,regi,te)$(teFosNoCCS(te)) = 1; -*** FS: allow nuclear early retirement (for nucscen 7) -vm_capEarlyReti.up(ttot,regi,"tnrs") = 1; +vm_capEarlyReti.up(t,regi,te)$(teFosNoCCS(te)) = 1; +*** allow nuclear early retirement +vm_capEarlyReti.up(t,regi,"tnrs") = 1; *** allow early retirement of biomass used in electricity -vm_capEarlyReti.up(ttot,regi,"bioigcc") = 1; +vm_capEarlyReti.up(t,regi,"bioigcc") = 1; +*** allow early retirement of biomass used for heat and power +vm_capEarlyReti.up(t,regi,"biohp") = 1; +vm_capEarlyReti.up(t,regi,"biochp") = 1; + +*** allow early retirement for techs added to the c_tech_earlyreti_rate switch +$ifthen.tech_earlyreti not "%c_tech_earlyreti_rate%" == "off" +loop((ext_regi,te)$p_techEarlyRetiRate(ext_regi,te), + vm_capEarlyReti.up(t,regi,te)$(regi_group(ext_regi,regi))= 1; +); +$endif.tech_earlyreti ***restrict early retirement to the modeling time frame (to reduce runtime, the early retirement equations are phased out after 2110) vm_capEarlyReti.up(ttot,regi,te)$(ttot.val lt 2009 or ttot.val gt 2111) = 0; -*cb 20120224 lower bound of 0.01% to help the model to be aware of the early retirement option -vm_capEarlyReti.lo(ttot,regi,te)$(teFosNoCCS(te) AND ttot.val gt 2011 AND ttot.val lt 2111) = 0.0001; -vm_capEarlyReti.lo(ttot,regi,"tnrs")$(ttot.val gt 2011 AND ttot.val lt 2111) = 0.0001; +* lower bound of 0.01% to help the model to be aware of the early retirement option +vm_capEarlyReti.lo(t,regi,te)$((vm_capEarlyReti.up(t,regi,te) ge 1) and (t.val gt 2010) and (t.val le 2100)) = 1e-4; *cb 20120301 no early retirement for dot, they are used despite their economic non-competitiveness for various reasons. -vm_capEarlyReti.fx(ttot,regi,"dot")=0; +vm_capEarlyReti.fx(t,regi,"dot")=0; *rp 20210118 no investment into oil turbines in Europe vm_deltaCap.up(t,regi,"dot","1")$( (t.val gt 2005) AND regi_group("EUR_regi",regi) ) = 1e-6; - *' @code{extrapage: "00_model_assumptions"} *** ----------------------------------------------------------------------------- *' #### Bound on maximum annual carbon storage by region @@ -406,13 +413,13 @@ $endif *** ------------------------------------------------------------------------------------------------------------- if ( (c_ccsinjecratescen gt 0) AND (NOT cm_emiscen eq 1), - vm_co2CCS.lo(t,regi,"cco2","ico2","ccsinje","1")$(t.val le 2030) = pm_boundCapCCS(t,regi,"low")$(t.val le 2030) * s_MtCO2_2_GtC; - vm_co2CCS.up(t,regi,"cco2","ico2","ccsinje","1")$(t.val le 2030) = (pm_boundCapCCS(t,regi,"low")$(t.val le 2030) + (pm_boundCapCCS(t,regi,"up")$(t.val le 2030) - pm_boundCapCCS(t,regi,"low")$(t.val le 2030)) * c_fracRealfromAnnouncedCCScap2030) * s_MtCO2_2_GtC; + vm_co2CCS.lo(t,regi,"cco2","ico2","ccsinje","1")$(t.val le 2030) = p_boundCapCCS(t,regi,"low")$(t.val le 2030) * s_MtCO2_2_GtC; + vm_co2CCS.up(t,regi,"cco2","ico2","ccsinje","1")$(t.val le 2030) = (p_boundCapCCS(t,regi,"low")$(t.val le 2030) + (p_boundCapCCS(t,regi,"up")$(t.val le 2030) - p_boundCapCCS(t,regi,"low")$(t.val le 2030)) * c_fracRealfromAnnouncedCCScap2030) * s_MtCO2_2_GtC; ); loop(regi, loop(t$(t.val le 2030), - if( ( pm_boundCapCCS(t,regi,"up") eq 0), + if( ( p_boundCapCCS(t,regi,"up") eq 0), vm_cap.fx(t,regi,teCCS,rlf) = 0; ); ); @@ -425,6 +432,13 @@ loop(regi, ); ); +*** ------------------------------------------------------------------------------------------------------------- +*AM* Limit REMINDs ability to vent captured CO2 to 1 MtCO2 per yr per region. This happens otherwise to a great extend in stringent climate +*AM* policy scenarios if CCS and CCU capacities are limited in early years, to lower overall adjustment costs of capture technologies. +*AM* In reality, people don't have perfect foresight and without storage or usage capacities, no capture facilities will be built. +v_co2capturevalve.up(t,regi) = 1 * s_MtCO2_2_GtC; + + *AL* fixing prodFE in 2005 to the value contained in pm_cesdata("2005",regi,in,"quantity"). This is done to ensure that the energy system will reproduce the 2005 calibration values. *** Fixing will produce clearly attributable errors (good for debugging) when using inconsistent data, as the GAMS accuracy when comparing fixed results is very high (< 1e-8). ***vm_prodFe.fx("2005",regi,se2fe(enty,enty2,te)) = sum(fe2ppfEn(enty2,in), pm_cesdata("2005",regi,in,"quantity") ); @@ -445,10 +459,11 @@ $if %c_SSP_forcing_adjust% == "forcing_SSP1" vm_deltaCap.up(t,regi,"coalgas" *** ------------------------------------------------------------- *** H2 Curtailment *** ------------------------------------------------------------- +*** RLDC removal ***Fixing h2curt value to zero to avoid the model to generate SE out of nothing. ***Models that have additional se production channels should release this variable (eg. RLDC power module). loop(prodSeOth2te(enty,te), - vm_prodSeOth.fx(t,regi,"seh2","h2curt") = 0; + v_prodSeOth.fx(t,regi,"seh2","h2curt") = 0; ); diff --git a/core/datainput.gms b/core/datainput.gms index d9331e02d..87fdad2f6 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -97,8 +97,9 @@ $offdelim ; pm_gdp(tall,all_regi) = f_gdp(tall,all_regi,"%cm_GDPscen%") * pm_shPPPMER(all_regi) / 1000000; !! rescale from million US$ to trillion US$ -*** load level of development -table f_developmentState(tall,all_regi,all_GDPpcScen) "level of development based on GDP per capita" +*** load level of development based on GDP PPP per capita: 0 is low income, 1 is high income. +*** Values in 2020 SSP2: SSA=0.1745, IND=0.3686, OAS=0.5136, MEA=0.6568, REF=0.836, LAM=0.8763, NEU=0.9962, EUR=1, CAZ=1, CHA=1, JPN=1, USA=1 +table f_developmentState(tall,all_regi,all_GDPpcScen) "level of development based on GDP PPP per capita" $ondelim $include "./core/input/f_developmentState.cs3r" $offdelim @@ -243,23 +244,23 @@ $if not "%cm_learnRate%" == "off" parameter p_new_learnRate(all_te) / %cm_learnR $if not "%cm_learnRate%" == "off" fm_dataglob("learn",te)$p_new_learnRate(te)=p_new_learnRate(te); *RP* the new cost data in generisdata_tech is now in $2015. As long as the model runs in $2005, these values have first to be converted to D2005 by dividing by 1.2 downwards -fm_dataglob("inco0",te) = s_D2015_2_D2005 * fm_dataglob("inco0",te); -fm_dataglob("incolearn",te) = s_D2015_2_D2005 * fm_dataglob("incolearn",te); -fm_dataglob("omv",te) = s_D2015_2_D2005 * fm_dataglob("omv",te); -p_inco0(ttot,regi,te) = s_D2015_2_D2005 * p_inco0(ttot,regi,te); +fm_dataglob("inco0",te) = s_D2015_2_D2005 * fm_dataglob("inco0",te); +fm_dataglob("incolearn",te) = s_D2015_2_D2005 * fm_dataglob("incolearn",te); +fm_dataglob("omv",te) = s_D2015_2_D2005 * fm_dataglob("omv",te); +p_inco0(ttot,regi,te) = s_D2015_2_D2005 * p_inco0(ttot,regi,te); *** inco0 (and incolearn) are given in $/kW (or $/(tC/a) for ccs-related tech or $/(t/a) for process-based industry) *** convert to REMIND units, i.e., T$/TW (or T$/(GtC/a) for ccs-related tech or T$/(Gt/a) for process-based industry) *** note that factor for $/kW -> T$/TW is the same as for $/(tC/a) -> T$/(GtC/a) -fm_dataglob("inco0",te) = s_DpKW_2_TDpTW * fm_dataglob("inco0",te); -fm_dataglob("incolearn",te) = s_DpKW_2_TDpTW * fm_dataglob("incolearn",te); -fm_dataglob("omv",te) = s_DpKWa_2_TDpTWa * fm_dataglob("omv",te); -p_inco0(ttot,regi,te) = s_DpKW_2_TDpTW * p_inco0(ttot,regi,te); +fm_dataglob("inco0",te) = s_DpKW_2_TDpTW * fm_dataglob("inco0",te); +fm_dataglob("incolearn",te) = s_DpKW_2_TDpTW * fm_dataglob("incolearn",te); +fm_dataglob("omv",te) = s_DpKWa_2_TDpTWa * fm_dataglob("omv",te); +p_inco0(ttot,regi,te) = s_DpKW_2_TDpTW * p_inco0(ttot,regi,te); *RP* rescale the global CSP investment costs in REMIND: Originally we assume a SM3/12h setup, while the cost data from IEA for the short term seems rather based on a SM2/6h setup (with 40% average CF) *** Accordingly, also decrease long-term costs in REMIND to 0.7 of the current values -fm_dataglob("inco0","csp") = 0.7 * fm_dataglob("inco0","csp"); -fm_dataglob("incolearn","csp") = 0.7 * fm_dataglob("incolearn","csp"); +fm_dataglob("inco0","csp") = 0.7 * fm_dataglob("inco0","csp"); +fm_dataglob("incolearn","csp") = 0.7 * fm_dataglob("incolearn","csp"); *KK* adjust costs for oae from USD/GtCaO to USD/GtC fm_dataglob("inco0", "oae_ng") = fm_dataglob("inco0", "oae_ng") / (cm_33_OAE_eff / sm_c_2_co2); @@ -370,16 +371,17 @@ $endif.REG_techcosts *** global exponent *** parameter calculation for global level, that regional values can gradually converge to -fm_dataglob("learnExp_wFC",teLearn(te)) = fm_dataglob("inco0",te)/fm_dataglob("incolearn",te) * log(1-fm_dataglob("learn", te))/log(2); +fm_dataglob("learnExp_woFC",teLearn(te)) = log(1 - fm_dataglob("learn",te)) / log(2); +*RP* adjust exponent parameter learnExp_woFC to take floor costs into account +fm_dataglob("learnExp_wFC",teLearn(te)) = fm_dataglob("inco0",te) / fm_dataglob("incolearn",te) * fm_dataglob("learnExp_woFC",te); *** regional exponent -pm_data(regi,"learnExp_woFC",teLearn(te)) = log(1-pm_data(regi,"learn", te))/log(2); -*RP* adjust exponent parameter learnExp_woFC to take floor costs into account -pm_data(regi,"learnExp_wFC",teLearn(te)) = pm_data(regi,"inco0",te) / pm_data(regi,"incolearn",te) * log(1-pm_data(regi,"learn", te))/log(2); +pm_data(regi,"learnExp_woFC",teLearn(te)) = log(1 - pm_data(regi,"learn",te)) / log(2); +pm_data(regi,"learnExp_wFC",teLearn(te)) = pm_data(regi,"inco0",te) / pm_data(regi,"incolearn",te) * pm_data(regi,"learnExp_woFC",te); *** global factor *** parameter calculation for global level, that regional values can gradually converge to -fm_dataglob("learnMult_wFC",teLearn(te)) = fm_dataglob("incolearn",te) / (fm_dataglob("ccap0",te) ** fm_dataglob("learnExp_wFC", te)); +fm_dataglob("learnMult_wFC",teLearn(te)) = fm_dataglob("incolearn",te) / (fm_dataglob("ccap0",te) ** fm_dataglob("learnExp_wFC", te)); *** regional factor *NB* read in vm_capCum(t0,regi,teLearn) from input.gdx to have info available for the recalibration of 2005 investment costs @@ -755,14 +757,14 @@ loop(ext_regi$pm_extRegiEarlyRetiRate(ext_regi), ); *Tech-specific* *RP*: reduce early retirement for technologies with additional characteristics that are difficult to represent in REMIND, eg. industries built around heating/CHP plants, or flexibility from ngt plants -pm_regiEarlyRetiRate(t,regi,"ngt") = 0.3 * pm_regiEarlyRetiRate(t,regi,"ngt") ; !! ngt should only be phased out very slowly, as they provide flexibility - which REMIND is not too good at capturing endogeneously -pm_regiEarlyRetiRate(t,regi,"gaschp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"gaschp") ; !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input -pm_regiEarlyRetiRate(t,regi,"coalchp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"coalchp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input -pm_regiEarlyRetiRate(t,regi,"biochp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"biochp") ; !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input -pm_regiEarlyRetiRate(t,regi,"gashp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"gashp") ; !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input -pm_regiEarlyRetiRate(t,regi,"coalhp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"coalhp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input -pm_regiEarlyRetiRate(t,regi,"biohp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"biohp") ; !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input -pm_regiEarlyRetiRate(t,regi,"bioigcc") = 0.25 * pm_regiEarlyRetiRate(t,regi,"bioigcc") ; !! reduce bio early retirement rate +pm_regiEarlyRetiRate(t,regi,"ngt") = 0.3 * pm_regiEarlyRetiRate(t,regi,"ngt"); !! ngt should only be phased out very slowly, as they provide flexibility - which REMIND is not too good at capturing endogeneously +pm_regiEarlyRetiRate(t,regi,"gaschp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"gaschp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input +pm_regiEarlyRetiRate(t,regi,"coalchp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"coalchp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input +pm_regiEarlyRetiRate(t,regi,"gashp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"gashp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input +pm_regiEarlyRetiRate(t,regi,"coalhp") = 0.5 * pm_regiEarlyRetiRate(t,regi,"coalhp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input +pm_regiEarlyRetiRate(t,regi,"biohp") = 0.25 * pm_regiEarlyRetiRate(t,regi,"biohp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input +pm_regiEarlyRetiRate(t,regi,"biochp") = 0.25 * pm_regiEarlyRetiRate(t,regi,"biochp"); !! chp should only be phased out slowly, as district heating networks/ industry uses are designed to a specific heat input +pm_regiEarlyRetiRate(t,regi,"bioigcc") = 0.25 * pm_regiEarlyRetiRate(t,regi,"bioigcc"); !! reduce bio early retirement rate $ifthen.tech_earlyreti not "%c_tech_earlyreti_rate%" == "off" loop((ext_regi,te)$p_techEarlyRetiRate(ext_regi,te), @@ -890,7 +892,7 @@ if(pm_NuclearConstraint("2020",regi,"tnrs")<0, ); *** read in data on CCS capacities and announced projects used as upper and lower bound on vm_co2CCS in 2025 and 2030 -parameter pm_boundCapCCS(ttot,all_regi,bounds) "installed and planned capacity of CCS" +parameter p_boundCapCCS(ttot,all_regi,bounds) "installed and planned capacity of CCS" / $ondelim $include "./core/input/p_boundCapCCS.cs4r" @@ -1605,10 +1607,19 @@ $include "./core/input/f_fedemand_build.cs4r" $offdelim /; -pm_fedemand(t,regi,cal_ppf_buildings_dyn36) = - f_fedemand_build(t,regi,"%cm_demScen%","%cm_rcp_scen_build%",cal_ppf_buildings_dyn36); +pm_fedemand(t,regi,cal_ppf_buildings_dyn36) = f_fedemand_build(t,regi,"%cm_demScen%","%cm_rcp_scen_build%",cal_ppf_buildings_dyn36); $endif.cm_rcp_scen_build + +*** Scale FE demand across industry and building sectors +$ifthen.scaleDemand not "%cm_scaleDemand%" == "off" + loop((tall,tall2,all_regi) $ pm_scaleDemand(tall,tall2,all_regi), +*FL* rescaled demand = normal demand * [ scaling factor + (1-scaling factor) * remaining phase-in, between zero and one ] + pm_fedemand(t,all_regi,all_in) = pm_fedemand(t,all_regi,all_in) * ( pm_scaleDemand(tall,tall2,all_regi) + (1-pm_scaleDemand(tall,tall2,all_regi)) * min(1, max(0, tall2.val-t.val) / (tall2.val-tall.val)) ); + ); +$endif.scaleDemand + + *** initialize global target deviation scalar sm_globalBudget_dev = 1; diff --git a/core/declarations.gms b/core/declarations.gms index d9589e508..1e98f91bd 100644 --- a/core/declarations.gms +++ b/core/declarations.gms @@ -185,11 +185,15 @@ $ifthen.VREPot_Factor not "%c_VREPot_Factor%" == "off" p_VREPot_Factor(all_te) "Rescale factor for renewable potentials" / %c_VREPot_Factor% / $endif.VREPot_Factor +$ifthen.scaleDemand not "%cm_scaleDemand%" == "off" + pm_scaleDemand(tall,tall,all_regi) "Rescaling factor on final energy and usable energy demand, for selected regions and over a phase-in window." / %cm_scaleDemand% / +$endif.scaleDemand + p_boundtmp(tall,all_regi,all_te,rlf) "read-in bound on capacities" p_bound_cap(tall,all_regi,all_te,rlf) "read-in bound on capacities" pm_data(all_regi,char,all_te) "Large array for most technical parameters of technologies; more detail on the individual technical parameters can be found in the declaration of the set 'char' " pm_cf(tall,all_regi,all_te) "Installed capacity availability - capacity factor (fraction of the year that a plant is running)" -p_tkpremused(all_regi,all_te) "turn-key cost premium used in the model (with a discount rate of 3+ pure rate of time preference); in comparison to overnight costs)" +p_tkpremused(all_regi,all_te) "turn-key cost premium used in the model (with a discount rate of 3+ pure rate of time preference); in comparison to overnight costs)" p_aux_tlt(all_te) "auxilliary parameter to determine maximal lifetime of a technology" p_aux_check_omeg(all_te) "auxiliary parameter for an automated check that no technology is erroneously entered with pm_omeg('1') value of 0" p_aux_check_tlt(all_te) "auxiliary parameter for an automated check that the pm_omeg calculation and filling of the opTimeYr2te mapping is in accordance" @@ -200,7 +204,7 @@ p_efFossilFuelExtrGlo(all_enty,all_enty) "global emission factor for pm_dataren(all_regi,char,rlf,all_te) "Array including both regional renewable potential and capacity factor" p_datapot(all_regi,char,rlf,all_enty) "Total land area usable for the solar technologies PV and CSP. [km^2]" p_adj_seed_reg(tall,all_regi) "market capacity that can be built from 0 and gives v_adjFactor=1" -p_adj_seed_te(ttot,all_regi,all_te) "technology-dependent multiplicative prefactor to the v_adjFactor seed value. Smaller means slower scale-up" +p_adj_seed_te(ttot,all_regi,all_te) "technology-dependent multiplicative prefactor to the v_adjFactor seed value. Smaller means slower scale-up" *** appears in q_esm2macro and q_balFeForCes. This energy category is 0 in LAM, IND and AFR in 2005, but a value > 0 is needed for the calculation of CES parameters. *** Accordingly, a value of sm_eps is inserted in pm_cesdata to allow calculation of the CES parameters. p_datacs(all_regi,all_enty) "fossil energy that is not oxidized (=carbon stored)" @@ -217,7 +221,7 @@ p_capCum(tall, all_regi,all_te) "vm_capCum from input.gdx f pm_capCumForeign(ttot,all_regi,all_te) "parameter for learning externality (cumulated capacity of other regions except regi)" pm_SolNonInfes(all_regi) "model status from last iteration. 1 means status 2 or 7, 0 for all other status codes" -pm_cintraw(all_enty) "carbon intensity of fossils [GtC per TWa]" +pm_cintraw(all_enty) "carbon intensity of fossils [GtC per TWa]" p_CapFixFromRWfix(ttot,all_regi,all_te) "parameter for fixing capacity variable to Real-World values in 2010/2015" p_deltaCapFromRWfix(ttot,all_regi,all_te) "parameter with resulting deltacap values resulting from fixing capacity to real-world values in 2010/2015" @@ -379,7 +383,7 @@ vm_esCapInv(ttot,all_regi,all_teEs) "investment for energy end vm_costEnergySys(ttot,all_regi) "energy system costs" vm_cap(tall,all_regi,all_te,rlf) "net total capacities" -vm_capDistr(tall,all_regi,all_te,rlf) "net capacities, distributed to the different grades for renewables" +v_capDistr(tall,all_regi,all_te,rlf) "net capacities, distributed to the different grades for renewables" vm_capTotal(ttot,all_regi,all_enty,all_enty) "total capacity without technology differentation for technologies where there exists differentation [TW]" vm_capFac(ttot,all_regi,all_te) "capacity factor of conversion technologies" vm_deltaCap(tall,all_regi,all_te,rlf) "capacity additions" @@ -412,8 +416,9 @@ v_prodUe (ttot,all_regi,all_enty,all_enty,all_te) "Useful energy production [ vm_capEarlyReti(tall,all_regi,all_te) "fraction of early retired capital" -vm_demSeOth(ttot,all_regi,all_enty,all_te) "other sety demand from certain technologies, have to calculated in additional equations [TWa]" -vm_prodSeOth(ttot,all_regi,all_enty,all_te) "other sety production from certain technologies, have to be calculated in additional equations [TWa]" +*** RLDC removal +v_demSeOth(ttot,all_regi,all_enty,all_te) "other sety demand from certain technologies, have to calculated in additional equations [TWa]" +v_prodSeOth(ttot,all_regi,all_enty,all_te) "other sety production from certain technologies, have to be calculated in additional equations [TWa]" v_shGreenH2(ttot,all_regi) "share of green hydrogen in all hydrogen by 2030 [0..1]" v_shBioTrans(ttot,all_regi) "Share of biofuels in transport liquids from 2025 onwards. Value between 0 and 1." diff --git a/core/equations.gms b/core/equations.gms index 1ade747b3..760828b25 100644 --- a/core/equations.gms +++ b/core/equations.gms @@ -156,12 +156,12 @@ q_balSe(t,regi,enty2)$( entySe(enty2) AND (NOT (sameas(enty2,"seel"))) ).. - vm_emiMacSector(t,regi,"ch4wstl") ) )$( sameas(enty2,"segabio") AND t.val gt 2005 ) - + sum(prodSeOth2te(enty2,te), vm_prodSeOth(t,regi,enty2,te) ) + + sum(prodSeOth2te(enty2,te), v_prodSeOth(t,regi,enty2,te) ) !! *** RLDC removal + vm_Mport(t,regi,enty2) =e= sum(se2fe(enty2,enty3,te), vm_demSe(t,regi,enty2,enty3,te)) + sum(se2se(enty2,enty3,te), vm_demSe(t,regi,enty2,enty3,te)) - + sum(demSeOth2te(enty2,te), vm_demSeOth(t,regi,enty2,te) ) + + sum(demSeOth2te(enty2,te), v_demSeOth(t,regi,enty2,te) ) !! *** RLDC removal + vm_Xport(t,regi,enty2) ; @@ -259,37 +259,34 @@ q_shFeCes(t,regi,entyFe,in,teEs)$feViaEs2ppfen(entyFe,in,teEs).. *' Definition of capacity constraints for primary energy to secondary energy transformation: ***-------------------------------------------------------------------------- q_limitCapSe(t,regi,pe2se(enty,enty2,te)).. - vm_prodSe(t,regi,enty,enty2,te) - =e= - sum(teSe2rlf(te,rlf), - vm_capFac(t,regi,te) * pm_dataren(regi,"nur",rlf,te) - * vm_cap(t,regi,te,rlf) - )$(NOT teReNoBio(te)) - + - sum(teRe2rlfDetail(te,rlf), - ( 1$teRLDCDisp(te) + pm_dataren(regi,"nur",rlf,te)$(NOT teRLDCDisp(te)) ) * vm_capFac(t,regi,te) - * vm_capDistr(t,regi,te,rlf) - )$(teReNoBio(te)) + vm_prodSe(t,regi,enty,enty2,te) + =e= + sum(teSe2rlf(te,rlf), + vm_capFac(t,regi,te) * pm_dataren(regi,"nur",rlf,te) * vm_cap(t,regi,te,rlf) + )$(NOT teReNoBio(te)) + + + sum(teRe2rlfDetail(te,rlf), + pm_dataren(regi,"nur",rlf,te) * vm_capFac(t,regi,te) * v_capDistr(t,regi,te,rlf) + )$(teReNoBio(te)) ; ***---------------------------------------------------------------------------- *' Definition of capacity constraints for secondary energy to secondary energy transformation: ***--------------------------------------------------------------------------- q_limitCapSe2se(t,regi,se2se(enty,enty2,te)).. - vm_prodSe(t,regi,enty,enty2,te) - =e= - sum(teSe2rlf(te,rlf), - vm_capFac(t,regi,te) * pm_dataren(regi,"nur",rlf,te) - * vm_cap(t,regi,te,rlf) - ); + vm_prodSe(t,regi,enty,enty2,te) + =e= + sum(teSe2rlf(te,rlf), + vm_capFac(t,regi,te) * pm_dataren(regi,"nur",rlf,te) * vm_cap(t,regi,te,rlf) + ); ***--------------------------------------------------------------------------- *' Definition of capacity constraints for secondary energy to final energy transformation: ***--------------------------------------------------------------------------- q_limitCapFe(t,regi,te).. - sum((entySe,entyFe)$(se2fe(entySe,entyFe,te)), vm_prodFe(t,regi,entySe,entyFe,te)) - =l= - sum(teFe2rlf(te,rlf), vm_capFac(t,regi,te) * vm_cap(t,regi,te,rlf)); + sum((entySe,entyFe)$(se2fe(entySe,entyFe,te)), vm_prodFe(t,regi,entySe,entyFe,te)) + =l= + sum(teFe2rlf(te,rlf), vm_capFac(t,regi,te) * vm_cap(t,regi,te,rlf)); ***--------------------------------------------------------------------------- *' Definition of capacity constraints for CCS technologies: @@ -327,7 +324,7 @@ q_cap(ttot,regi,te2rlf(te,rlf))$(ttot.val ge cm_startyear).. q_capDistr(t,regi,teReNoBio(te)).. - sum(teRe2rlfDetail(te,rlf), vm_capDistr(t,regi,te,rlf) ) + sum(teRe2rlfDetail(te,rlf), v_capDistr(t,regi,te,rlf) ) =e= vm_cap(t,regi,te,"1") ; @@ -398,9 +395,12 @@ q_capCumNet(t0,regi,teLearn)$(NOT (pm_data(regi,"tech_stat",teLearn) eq 4)).. qm_fuel2pe(t,regi,peRicardian(enty)).. vm_prodPe(t,regi,enty) =e= - sum(pe2rlf(enty,rlf2),vm_fuExtr(t,regi,enty,rlf2))-(vm_Xport(t,regi,enty)-(1-pm_costsPEtradeMp(regi,enty))*vm_Mport(t,regi,enty))$(tradePe(enty)) - - sum(pe2rlf(enty2,rlf2), (pm_fuExtrOwnCons(regi, enty, enty2) * vm_fuExtr(t,regi,enty2,rlf2))$(pm_fuExtrOwnCons(regi, enty, enty2) gt 0)); - + sum(pe2rlf(enty,rlf2), vm_fuExtr(t,regi,enty,rlf2)) + - (vm_Xport(t,regi,enty) - (1-pm_costsPEtradeMp(regi,enty)) * vm_Mport(t,regi,enty))$(tradePe(enty)) + - sum(pe2rlf(enty2,rlf2), + (pm_fuExtrOwnCons(regi, enty, enty2) * vm_fuExtr(t,regi,enty2,rlf2))$(pm_fuExtrOwnCons(regi, enty, enty2) gt 0) + ) +; ***--------------------------------------------------------------------------- *' Definition of resource constraints for renewable energy types: ***--------------------------------------------------------------------------- @@ -408,7 +408,7 @@ qm_fuel2pe(t,regi,peRicardian(enty)).. q_limitProd(t,regi,teRe2rlfDetail(teReNoBio(te),rlf)).. pm_dataren(regi,"maxprod",rlf,te) =g= - ( 1$teRLDCDisp(te) + pm_dataren(regi,"nur",rlf,te)$(NOT teRLDCDisp(te)) ) * vm_capFac(t,regi,te) * vm_capDistr(t,regi,te,rlf); + pm_dataren(regi,"nur",rlf,te) * vm_capFac(t,regi,te) * v_capDistr(t,regi,te,rlf); ***----------------------------------------------------------------------------- *' Definition of competition for geographical potential for renewable energy types: @@ -417,32 +417,34 @@ q_limitProd(t,regi,teRe2rlfDetail(teReNoBio(te),rlf)).. q_limitGeopot(t,regi,peReComp(enty),rlf).. p_datapot(regi,"limitGeopot",rlf,enty) =g= - sum(te$teReComp2pe(enty,te,rlf), (vm_capDistr(t,regi,te,rlf) / (pm_data(regi,"luse",te)/1000))); + sum(te$teReComp2pe(enty,te,rlf), (v_capDistr(t,regi,te,rlf) / (pm_data(regi,"luse",te)/1000))); -*** learning curve for investment costs -*** deactivate learning for tech_stat 4 technologies before 2025 as they are not built before +***--------------------------------------------------------------------------- +*' Learning curve for investment costs: +*' (deactivate learning for tech_stat 4 technologies before 2025 as they are not built before) +***--------------------------------------------------------------------------- q_costTeCapital(t,regi,teLearn)$(NOT (pm_data(regi,"tech_stat",teLearn) eq 4 AND t.val le 2020)) .. vm_costTeCapital(t,regi,teLearn) =e= -*** special treatment for first time steps: using global estimates better -*** matches historic values - ( fm_dataglob("learnMult_wFC",teLearn) +*** floor costs defined regionally + pm_data(regi,"floorcost",teLearn) +*** until 2005: using global estimates better matches historic values + + ( fm_dataglob("learnMult_wFC",teLearn) * ( ( sum(regi2, vm_capCum(t,regi2,teLearn)) + pm_capCumForeign(t,regi,teLearn) ) ** fm_dataglob("learnExp_wFC",teLearn) ) )$( t.val le 2005 ) -*** special treatment for 2010, 2015: start divergence of regional values by using a -*** t-split of global 2005 to regional 2020 in order to phase-in the observed 2020 regional -*** variation from input-data - + ( (2020 - t.val)/15 * fm_dataglob("learnMult_wFC",teLearn) +*** 2005 to 2020: linear transition from global 2005 to regional 2020 +*** to phase-in the observed 2020 regional variation from input-data + + ( (2020 - t.val) / (2020-2005) * fm_dataglob("learnMult_wFC",teLearn) * ( sum(regi2, vm_capCum(t,regi2,teLearn)) + pm_capCumForeign(t,regi,teLearn) ) ** fm_dataglob("learnExp_wFC",teLearn) - + (t.val - 2005)/15 * pm_data(regi,"learnMult_wFC",teLearn) + + (t.val - 2005) / (2020-2005) * pm_data(regi,"learnMult_wFC",teLearn) * ( sum(regi2, vm_capCum(t,regi2,teLearn)) + pm_capCumForeign(t,regi,teLearn) ) @@ -450,14 +452,14 @@ q_costTeCapital(t,regi,teLearn)$(NOT (pm_data(regi,"tech_stat",teLearn) eq 4 AND )$( (t.val gt 2005) AND (t.val lt 2020) ) $ifthen.floorscen %cm_floorCostScen% == "default" -*** assuming linear convergence of regional learning curves to global values until 2050 - + ( (pm_ttot_val(t) - 2020) / 30 * fm_dataglob("learnMult_wFC",teLearn) +*** 2020 to 2050: assuming linear convergence of regional learning curves to global values + + ( (pm_ttot_val(t) - 2020) / (2050-2020) * fm_dataglob("learnMult_wFC",teLearn) * ( sum(regi2, vm_capCum(t,regi2,teLearn)) + pm_capCumForeign(t,regi,teLearn) ) ** fm_dataglob("learnExp_wFC",teLearn) - + (2050 - pm_ttot_val(t)) / 30 * pm_data(regi,"learnMult_wFC",teLearn) + + (2050 - pm_ttot_val(t)) / (2050-2020) * pm_data(regi,"learnMult_wFC",teLearn) * ( sum(regi2, vm_capCum(t,regi2,teLearn)) + pm_capCumForeign(t,regi,teLearn) ) @@ -484,15 +486,12 @@ $ifthen.floorscen %cm_floorCostScen% == "techtrans" $endif.floorscen $ifthen.floorscen %cm_floorCostScen% == "default" -*** globally harmonized costs after 2050 +*** after 2050: globally harmonized costs + ( fm_dataglob("learnMult_wFC",teLearn) * (sum(regi2, vm_capCum(t,regi2,teLearn)) + pm_capCumForeign(t,regi,teLearn) ) **(fm_dataglob("learnExp_wFC",teLearn)) )$(t.val gt 2050) $endif.floorscen - -*** floor costs - + pm_data(regi,"floorcost",teLearn) ; @@ -1111,23 +1110,23 @@ q_limitCapFeH2BI(t,regi,sector)$(SAMEAS(sector,"build") OR SAMEAS(sector,"indst" ; ***--------------------------------------------------------------------------- -*' Enforce historical data biomass share per carrier in sector final energy for buildings and industry (+- 2%) +*' Enforce historical data biomass share per carrier in sector final energy for transport, buildings and industry (+- 2%) ***--------------------------------------------------------------------------- -q_shbiofe_up(t,regi,entyFe,sector,emiMkt)$((sameas(entyFe,"fegas") or sameas(entyFe,"fehos") or sameas(entyFe,"fesos")) and entyFe2Sector(entyFe,sector) and sector2emiMkt(sector,emiMkt) and (t.val le 2015)).. +q_shbiofe_up(t,regi,entyFe,sector,emiMkt)$(pm_secBioShare(t,regi,entyFe,sector) and sector2emiMkt(sector,emiMkt)).. (pm_secBioShare(t,regi,entyFe,sector) + 0.02) * - sum((entySe,te)$se2fe(entySe,entyFe,te), vm_demFeSector(t,regi,entySe,entyFe,sector,emiMkt)) + sum((entySe,te)$se2fe(entySe,entyFe,te), vm_demFeSector_afterTax(t,regi,entySe,entyFe,sector,emiMkt)) =g= - sum((entySeBio,te)$se2fe(entySeBio,entyFe,te), vm_demFeSector(t,regi,entySeBio,entyFe,sector,emiMkt)) + sum((entySeBio,te)$se2fe(entySeBio,entyFe,te), vm_demFeSector_afterTax(t,regi,entySeBio,entyFe,sector,emiMkt)) ; -q_shbiofe_lo(t,regi,entyFe,sector,emiMkt)$((sameas(entyFe,"fegas") or sameas(entyFe,"fehos") or sameas(entyFe,"fesos")) and entyFe2Sector(entyFe,sector) and sector2emiMkt(sector,emiMkt) and (t.val le 2015)).. +q_shbiofe_lo(t,regi,entyFe,sector,emiMkt)$(pm_secBioShare(t,regi,entyFe,sector) and sector2emiMkt(sector,emiMkt)).. (pm_secBioShare(t,regi,entyFe,sector) - 0.02) * - sum((entySe,te)$se2fe(entySe,entyFe,te), vm_demFeSector(t,regi,entySe,entyFe,sector,emiMkt)) + sum((entySe,te)$se2fe(entySe,entyFe,te), vm_demFeSector_afterTax(t,regi,entySe,entyFe,sector,emiMkt)) =l= - sum((entySeBio,te)$se2fe(entySeBio,entyFe,te), vm_demFeSector(t,regi,entySeBio,entyFe,sector,emiMkt)) + sum((entySeBio,te)$se2fe(entySeBio,entyFe,te), vm_demFeSector_afterTax(t,regi,entySeBio,entyFe,sector,emiMkt)) ; *** EOF ./core/equations.gms diff --git a/core/preloop.gms b/core/preloop.gms index 80270dd01..4a5f07e1f 100644 --- a/core/preloop.gms +++ b/core/preloop.gms @@ -28,7 +28,7 @@ vm_prodFe.l(ttot,regi,entyFe2,entyFe2,te) = 0; vm_prodSe.l(ttot,regi,enty,enty2,te) = 0; vm_demSe.l(ttot,regi,enty,enty2,te) = 0; vm_Xport.l(ttot,regi,tradePe) = 0; -vm_capDistr.l(t,regi,te,rlf) = 0; +v_capDistr.l(t,regi,te,rlf) = 0; vm_cap.l(t,regi,te,rlf) = 0; vm_fuExtr.l(ttot,regi,"pebiolc","1")$(ttot.val ge 2005) = 0; vm_pebiolc_price.l(ttot,regi)$(ttot.val ge 2005) = 0; diff --git a/core/sets.gms b/core/sets.gms index de5d6f865..a101a50c1 100755 --- a/core/sets.gms +++ b/core/sets.gms @@ -163,7 +163,7 @@ all_te "all energy technologies, including from modules" gash2c "gas to hydrogen with capture" gasftrec "gas based fischer-tropsch recycle" gasftcrec "gas based fischer-tropsch with capture recycle" - refliq "refinery oil to se liquids" + refliq "refinery oil to SE liquids" dot "diesel oil turbine" dhp "diesel oil heating plant" igcc "integrated coal gasification combined cycle" @@ -359,14 +359,14 @@ all_enty "all types of quantities" pebioil "PE biomass sunflowers, palm oil, etc" all_seso "all to SE solids" - sesofos "SE solids from fossil pe" + sesofos "SE solids from fossil PE" sesobio "SE solids from biomass" all_seliq "all to SE liquids" - seliqfos "SE liquids from fossil pe (ex. petrol and diesel)" + seliqfos "SE liquids from fossil PE (ex. petrol and diesel)" seliqbio "SE liquids from biomass (ex. ethanol)" seliqsyn "SE synthetic liquids from H2 (ex. petrol and diesel)" all_sega "all to SE gas" - segafos "SE gas from fossil pe" + segafos "SE gas from fossil PE" segabio "SE gas from biomass" segasyn "SE synthetic gas from H2" seh2 "SE hydrogen" @@ -406,7 +406,7 @@ all_enty "all types of quantities" fetf "FE transport fuels" fehoi_cs "final energy in industry diesel - carbon stored" fegai_cs "final energy in industry natural gas - carbon stored " - entydummy "dummy fe for process based industry implementation" + entydummy "dummy FE for process based industry implementation" ueHDVt "transport useful energy heavy duty vehicles" ueLDVt "transport useful energy light duty vehicles" @@ -1320,9 +1320,6 @@ $endif.cm_subsec_model_steel *** Definition of subsets of 'te': ***----------------------------------------------------------------------------- -teRLDCDisp(all_te) "RLDC Dispatchable technologies that produce seel" -/ -/ *** Note: technologies without endogenous learning can also have decreasing (or increasing) capital cost over time, due to for example convergence to global value teLearn(all_te) "Learning technologies (for which investment costs are reduced endogenously through capacity deployment)." / @@ -1620,7 +1617,7 @@ enty(all_enty) "all types of quantities" fetf "final energy transport fuels" feh2t "final energy hydrogen transport" fegat "final energy nat. gas for transport" - entydummy "dummy fe for process based industry implementation" + entydummy "dummy FE for process based industry implementation" co2 "carbon dioxide emissions" ch4 "methane emissions" @@ -1731,7 +1728,7 @@ peExPol(all_enty) "primary energy fuels with polynomial" peur "PE uranium" / -peExGrade(all_enty) "exhaustible pe with step as entyPe ex-peExPol - s.b." +peExGrade(all_enty) "exhaustible PE with step as entyPe ex-peExPol - s.b." peRicardian(all_enty) "Ricardian PE" @@ -2042,7 +2039,7 @@ ppfEn2Sector(all_in,emi_sectors) "primary energy production factors mapping to s fegai.cdr / -entyFeSec2entyFeDetail(all_enty,emi_sectors,all_enty) "final energy (stationary) and sector mapping to detailed final energy enty split by buildings and industry" +entyFeSec2entyFeDetail(all_enty,emi_sectors,all_enty) "final energy and sector mapping to detailed final energy enty split in IO" / fegas.build.fegab fegas.indst.fegai @@ -2056,6 +2053,16 @@ entyFeSec2entyFeDetail(all_enty,emi_sectors,all_enty) "final energy (stationary) fehes.indst.fehei *** feh2s.build.feh2b *** feh2s.indst.feh2i + fepet.trans.fepet + fedie.trans.fedie +*** feh2t.trans + feelt.trans.feelt + fegat.trans.fegat +*** feels.cdr +*** fehes.cdr +*** fegas.cdr +*** feh2s.cdr +*** fedie.cdr / all_emiMkt "emission markets" @@ -2439,7 +2446,7 @@ seAgg(all_enty) "secondary energy aggregations" all_sega / -seAgg2se(all_enty,all_enty) "map secondary energy aggregation to se" +seAgg2se(all_enty,all_enty) "map secondary energy aggregation to SE" / all_seliq.seliqbio all_seliq.seliqfos @@ -2451,6 +2458,8 @@ seAgg2se(all_enty,all_enty) "map secondary energy aggregation to se" all_sega.segasyn / +seAgg2fe(all_enty,all_enty) "map secondary energy aggregation to fe" + capTotal(all_enty,all_enty) "mapping of input to output carriers for calculating total capacities without technology differentiation vm_capTotal" / pecoal.seel @@ -2794,7 +2803,8 @@ teReComp2pe(all_enty,all_te,rlf) "map competing technologies to primary energy pesol.csp.(1*9) / -demSeOth2te(all_enty,all_te) "map other se demands not directly following the sedem-route through technologies" +*** RLDC removal: should we remove demSeOth like prodSeOth, although it's used in remind2? +demSeOth2te(all_enty,all_te) "map other SE demands not directly following the sedem-route through technologies" / seh2.csp segabio.csp @@ -2819,7 +2829,7 @@ $ENDIF.WindOff ) . 1 / -teRe2rlfDetail(all_te,rlf) "mapping for se techologies to grades" +teRe2rlfDetail(all_te,rlf) "mapping for SE techologies to grades" / wind.(1*9) $IFTHEN.WindOff %cm_wind_offshore% == "1" diff --git a/core/sets_calculations.gms b/core/sets_calculations.gms index 430a459e0..05505be58 100644 --- a/core/sets_calculations.gms +++ b/core/sets_calculations.gms @@ -150,6 +150,12 @@ fete(entyFe,te) = YES; sefe(entySe,entyFe) = YES; ); +loop(seAgg2se(seAgg,entySe), + loop(sefe(entySe,entyFe), + seAgg2fe(seAgg,entyFe) = YES; + ); +); + *** extended region group set regi_groupExt(ext_regi,all_regi)$regi_group(ext_regi,all_regi) = Yes; loop(all_regi, diff --git a/main.gms b/main.gms index 3e67a500d..f10dab332 100755 --- a/main.gms +++ b/main.gms @@ -317,10 +317,8 @@ $setglobal biomass magpie_40 !! def = magpie_40 *' * (MOFEX) : contains the standalone version of MOFEX (Model Of Fossil EXtraction), which minimizes the discounted extraction and trade costs of fossils while balancing trade for each time step. Not to be run within a REMIND run but instead through the standalone architecture or soft-linked with REMIND (not yet implemented) $setglobal fossil grades2poly !! def = grades2poly *'--------------------- 32_power ---------------------------------------- -*' +*' *' * (IntC) : Power sector formulation with Integration Cost (IntC) markups and curtailment for VRE integration - linearly increasing with VRE share -, and fixed capacity factors for dispatchable power plants -*' * (RLDC) : Power sector formulation with Residual Load Duration Curve (RLDC) formulation for VRE power integration, and flexible capacity factors for dispatchable power plants -*' * (DTcoup) : (currently not merged, only a copy of IntC) Power sector formulation with iterative coupling to hourly power-sector model DIETER: REMIND gives DIETER costs of technologies, power demand, CO2 price and capacity bounds; DIETER gives REMIND markups of generation, capacity factors, peak hourly residual demand $setglobal power IntC !! def = IntC *'--------------------- 33_CDR ---------------------------------------- *' @@ -1209,14 +1207,9 @@ $setglobal cm_MAgPIE_coupling off !! def = "off" !! regexp = off|on *' * (rcp85): RCP8.5 $setglobal cm_rcp_scen none !! def = "none" !! regexp = none|rcp20|rcp26|rcp37|rcp45|rcp60|rcp85 *' cm_NDC_version "choose version year of NDC targets as well as conditional vs. unconditional targets" -*' * (2023_cond): all NDCs conditional to international financial support published until February 24, 2023 -*' * (2023_uncond): all NDCs independent of international financial support published until February 24, 2023 -*' * (2022_cond): all NDCs conditional to international financial support published until December 31, 2022 -*' * (2022_uncond): all NDCs independent of international financial support published until December 31, 2022 -*' * (2021_cond): all NDCs conditional to international financial support published until December 31, 2021 -*' * (2021_uncond): all NDCs independent of international financial support published until December 31, 2021 -*' * (2018_cond): all NDCs conditional to international financial support published until December 31, 2018 -*' * (2018_uncond): all NDCs independent of international financial support published until December 31, 2018 +*' * (2023_cond): all NDCs conditional to international financial support published until December 31, 2023 +*' * (2023_uncond): all NDCs independent of international financial support published until December 31, 2023 +*' * Other supported years are 2022, 2021 and 2018, always containing NDCs published until December 31 of that year $setglobal cm_NDC_version 2023_cond !! def = "2023_cond" !! regexp = 20(18|2[1-3])_(un)?cond *' cm_netZeroScen "choose scenario of net zero targets of netZero realization of module 46_carbonpriceRegi" *' @@ -1326,6 +1319,10 @@ $setGlobal cm_emiMktTarget off !! def = off *** Example on how to use: *** cm_emiMktTarget_tolerance = 'GLO 0.004, DEU 0.01'. All regional emission targets will be considered converged if they have at most 0.4% of the target deviation, except for Germany that requires 1%. $setGlobal cm_emiMktTarget_tolerance GLO 0.01 !! def = GLO 0.01 +*** cm_scaleDemand - Rescaling factor on final energy and usable energy demand, for selected regions and over a phase-in window. +*** Example on how to use: +*** cm_scaleDemand = '2020.2040.(EUR,NEU,USA,JPN,CAZ) 0.75' applies a 25% demand reduction on those regions progressively between 2020 (100% demand) and 2040 (75% demand). +$setGlobal cm_scaleDemand off !! def = off *** cm_quantity_regiCO2target "emissions quantity upper bound from specific year for region group." *** Example on how to use: *** '2050.EUR_regi.netGHG 0.000001, obliges European GHG emissions to be approximately zero from 2050 onward" @@ -1525,7 +1522,9 @@ $setGlobal cm_indstExogScen off !! def off *** (off) default, no fixing *** (ariadne_bal) steel and cement production trajectories for Germany used in the Ariadne "Balanced" scenario *** (ariadne_ensec) steel and cement production trajectories for Germany used in the Ariadne "EnSec" (energy security) scenario -$setGLobal cm_exogDem_scen off !! def off +*** (ariadne_highDem) +*** (ariadne_lowDem) +$setGLobal cm_exogDem_scen off !! def off !! regexp = off|ariadne_(bal|ensec|highDem|lowDem) *** cm_Ger_Pol "switch for selecting different policies for Germany used in the ARIADNE scenarios" *** switch for Germany-specific policies *** (off) default diff --git a/modules/04_PE_FE_parameters/iea2014/datainput.gms b/modules/04_PE_FE_parameters/iea2014/datainput.gms index 7cd7f08ea..d90c718c0 100644 --- a/modules/04_PE_FE_parameters/iea2014/datainput.gms +++ b/modules/04_PE_FE_parameters/iea2014/datainput.gms @@ -164,8 +164,8 @@ $endif.subsectors f04_IO_input(ttot,regi,all_enty,all_enty2,all_te) = f04_IO_input(ttot,regi,all_enty,all_enty2,all_te) * sm_EJ_2_TWa; f04_IO_output(ttot,regi,all_enty,all_enty2,all_te) = f04_IO_output(ttot,regi,all_enty,all_enty2,all_te) * sm_EJ_2_TWa; -*** calculate bio share per carrier for buildings and industry (only for historically available years) -pm_secBioShare(ttot,regi,entyFe,sector)$((sameas(entyFe,"fegas") or sameas(entyFe,"fehos") or sameas(entyFe,"fesos")) and entyFe2Sector(entyFe,sector) and (ttot.val ge 2005 and ttot.val le 2015) and (sum((entySe,all_enty,all_te)$entyFeSec2entyFeDetail(entyFe,sector,all_enty), f04_IO_output(ttot,regi,entySe,all_enty,all_te) ) gt 0)) = +*** calculate bio share per fe carrier (only for historically available years) +pm_secBioShare(ttot,regi,entyFe,sector)$((seAgg2fe("all_seso",entyFe) OR seAgg2fe("all_seliq",entyFe) OR seAgg2fe("all_sega",entyFe)) AND entyFe2Sector(entyFe,sector) and (ttot.val ge 2005 and ttot.val le 2020) and (sum((entySe,all_enty,all_te)$entyFeSec2entyFeDetail(entyFe,sector,all_enty), f04_IO_output(ttot,regi,entySe,all_enty,all_te) ) gt 0)) = sum((entySeBio,all_enty,all_te)$entyFeSec2entyFeDetail(entyFe,sector,all_enty), f04_IO_output(ttot,regi,entySeBio,all_enty,all_te) ) / sum((entySe,all_enty,all_te)$entyFeSec2entyFeDetail(entyFe,sector,all_enty), f04_IO_output(ttot,regi,entySe,all_enty,all_te) ) diff --git a/modules/05_initialCap/on/declarations.gms b/modules/05_initialCap/on/declarations.gms index 57397d998..6bbd523d8 100644 --- a/modules/05_initialCap/on/declarations.gms +++ b/modules/05_initialCap/on/declarations.gms @@ -7,7 +7,7 @@ *** SOF ./modules/05_initialCap/on/declarations.gms Parameter - pm_cap0(all_regi,all_te) "standing capacity in 2005 as calculated by the initialization routine generisinical. Unit: TWa" + p05_cap0(all_regi,all_te) "standing capacity in 2005 as calculated by the initialization routine generisinical. Unit: TWa" p05_emi2005_from_initialcap2(all_regi,emiTe) "regional energy emissions 2005 resulting from the initialcap routine. Unit: GtC" p05_initial_capacity(all_regi,all_te) "capacitiy at t=2005, calculated from past deltacaps" p05_inital_input(all_regi,all_te) "input in 2005, calculated from past deltacaps and initial time-variable eta" diff --git a/modules/05_initialCap/on/preloop.gms b/modules/05_initialCap/on/preloop.gms index e3ddd5b7c..3e7c9be6c 100644 --- a/modules/05_initialCap/on/preloop.gms +++ b/modules/05_initialCap/on/preloop.gms @@ -119,15 +119,15 @@ solve initialcap2 using cns; display v05_INIdemEn0.l, v05_INIcap0.l; -pm_cap0(regi,te) = v05_INIcap0.l(regi,te); +p05_cap0(regi,te) = v05_INIcap0.l(regi,te); $ifthen.cm_subsec_model_steel "%cm_subsec_model_steel%" == "processes" -pm_cap0(regi,'bof') = pm_outflowPrcIni(regi,'bof','unheated') / pm_cf("2005",regi,'bof'); -pm_cap0(regi,'bf') = pm_outflowPrcIni(regi,'bf','standard') / pm_cf("2005",regi,'bf'); -pm_cap0(regi,'eaf') = pm_outflowPrcIni(regi,'eaf','sec') / pm_cf("2005",regi,'eaf'); -pm_cap0(regi,'idr') = 0.; -pm_cap0(regi,"bfcc") =0.; -pm_cap0(regi,"idrcc") =0.; +p05_cap0(regi,'bof') = pm_outflowPrcIni(regi,'bof','unheated') / pm_cf("2005",regi,'bof'); +p05_cap0(regi,'bf') = pm_outflowPrcIni(regi,'bf','standard') / pm_cf("2005",regi,'bf'); +p05_cap0(regi,'eaf') = pm_outflowPrcIni(regi,'eaf','sec') / pm_cf("2005",regi,'eaf'); +p05_cap0(regi,'idr') = 0.; +p05_cap0(regi,"bfcc") =0.; +p05_cap0(regi,"idrcc") =0.; $endif.cm_subsec_model_steel *RP keep energy demand for the Kyoto target calibration @@ -171,7 +171,7 @@ vm_deltaCap.fx("2005",regi,te,rlf)$(te2rlf(te,rlf)) = 0; loop(regi, loop(teReNoBio(te), s05_aux_tot_prod - = pm_cap0(regi,te) + = p05_cap0(regi,te) * pm_cf("2005",regi,te) * pm_dataren(regi,"nur","1",te); @@ -211,8 +211,8 @@ loop(regi, loop(regi, loop(opTimeYr2te(te,opTimeYr)$(NOT teReNoBio(te)), loop(tsu2opTime5(ttot,opTimeYr), - loop(pe2se(entyPe,entySe,te), o_INI_DirProdSeTe(regi,entySe,te) = pm_cap0(regi,te) * pm_cf("2005",regi,te) * pm_dataren(regi,"nur","1",te) ); - sm_tmp = 1 / pm_ts(ttot) * pm_cap0(regi,te) * p05_vintage(regi,opTimeYr,te); + loop(pe2se(entyPe,entySe,te), o_INI_DirProdSeTe(regi,entySe,te) = p05_cap0(regi,te) * pm_cf("2005",regi,te) * pm_dataren(regi,"nur","1",te) ); + sm_tmp = 1 / pm_ts(ttot) * p05_cap0(regi,te) * p05_vintage(regi,opTimeYr,te); vm_deltaCap.lo(ttot,regi,te,"1") = sm_tmp; vm_deltaCap.up(ttot,regi,te,"1") = sm_tmp; @@ -257,7 +257,7 @@ display pm_aux_capLowerLimit; ***--------------------------------------------------------------------------- loop(regi, - o_INI_TotalCap(regi) = sum(pe2se(enty,"seel",te), pm_cap0(regi,te) ); + o_INI_TotalCap(regi) = sum(pe2se(enty,"seel",te), p05_cap0(regi,te) ); o_INI_TotalDirProdSe(regi,entySe) = sum(pe2se(enty,entySe,te), o_INI_DirProdSeTe(regi,entySe,te) ); o_INI_AvCapFac(regi) = o_INI_TotalDirProdSe(regi,"seel") / o_INI_TotalCap(regi); ); @@ -267,7 +267,7 @@ o_INI_DirProdSeTe o_INI_TotalCap o_INI_TotalDirProdSe o_INI_AvCapFac -pm_cap0 +p05_cap0 ; ***--------------------------------------------------------------------------- @@ -293,7 +293,7 @@ display pm_dataeta; p05_eta_correct_factor(regi,te) = 1; loop(regi, - loop(te$((teEtaIncr(te)) AND (pm_cap0(regi,te) > 1.E-8)), + loop(te$((teEtaIncr(te)) AND (p05_cap0(regi,te) > 1.E-8)), p05_initial_capacity(regi,te) = sum(ttot$sameas(ttot,"2005"), sum(teSe2rlf(te,rlf), @@ -501,11 +501,11 @@ loop(regi, p05_emi2005_from_initialcap2(regi,emiTe) = sum(pe2se(enty,enty2,te), pm_emifac("2005",regi,enty,enty2,te,emiTe) - * 1/(pm_data(regi,"eta",te)) * pm_cf("2005",regi,te) * pm_cap0(regi,te) + * 1/(pm_data(regi,"eta",te)) * pm_cf("2005",regi,te) * p05_cap0(regi,te) ) + sum(se2fe(enty,enty2,te), - pm_emifac("2005",regi,enty,enty2,te,emiTe) * pm_cf("2005",regi,te) * pm_cap0(regi,te) + pm_emifac("2005",regi,enty,enty2,te,emiTe) * pm_cf("2005",regi,te) * p05_cap0(regi,te) ); *** no CCS leakage in the first time step ); diff --git a/modules/24_trade/standard/bounds.gms b/modules/24_trade/standard/bounds.gms index 5729d6fa3..1d9d4ee93 100644 --- a/modules/24_trade/standard/bounds.gms +++ b/modules/24_trade/standard/bounds.gms @@ -86,7 +86,7 @@ $ENDIF.fossil_realization *** bounds on oil, gas and coal trade in 2010 and 2015 (+-10% from historical IEA values) -loop( ttot$(ttot.val eq 2010 OR ttot.val eq 2015), +loop( ttot$(ttot.val eq 2010 OR ttot.val eq 2015 OR ttot.val eq 2020), loop( peFos, vm_Xport.lo(ttot,regi,peFos) = 0.9 * pm_IO_trade(ttot,regi,peFos,"Xport"); vm_Xport.up(ttot,regi,peFos) = 1.1 * pm_IO_trade(ttot,regi,peFos,"Xport"); diff --git a/modules/32_power/DTcoup/bounds.gms b/modules/32_power/DTcoup/bounds.gms deleted file mode 100644 index 05bae18a5..000000000 --- a/modules/32_power/DTcoup/bounds.gms +++ /dev/null @@ -1,59 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/bounds.gms - -***----------------------------------------------------------- -*** module specific bounds -***------------------------------------------------------------ - -*** Fix capacity factors to the standard value from data -vm_capFac.fx(t,regi,te) = pm_cf(t,regi,te); - -*** FS: if flexibility tax on, let capacity factor be endogenuously determined between 0.1 and 1 -*** for technologies that get flexibility tax/subsity (teFlexTax) -if ( cm_flex_tax eq 1, - if ( cm_FlexTaxFeedback eq 1, -*** if flexibility tax feedback is on, let model choose capacity factor of flexible technologies freely - vm_capFac.lo(t,regi,teFlexTax)$(t.val ge 2010) = 0.1; - vm_capFac.up(t,regi,teFlexTax)$(t.val ge 2010) = pm_cf(t,regi,teFlexTax); - else -*** if flexibility tax feedback is off, only flexibliity tax benefit for flexible technologies and 0.5 capacity factor - vm_capFac.fx(t,regi,teFlex)$(t.val ge 2010) = 0.5; -*** electricity price of inflexible technologies the same w/o feedback - v32_flexPriceShare.fx(t,regi,te)$(teFlexTax(te) AND NOT(teFlex(te))) = 1; - ); -); - -*** Lower bounds on VRE use (more than 0.01% of electricity demand) after 2015 to prevent the model from overlooking solar and wind -loop(regi, - loop(te$(teVRE(te)), - if ( (sum(rlf, pm_dataren(regi,"maxprod",rlf,te)) > 0.01 * pm_IO_input(regi,"seel","feels","tdels")) , - vm_shSeEl.lo(t,regi,te)$(t.val>2020) = 0.01; - ); - ); -); - -*RP* upper bound of 90% on share of electricity produced by a single VRE technology, and lower bound on usablese to prevent the solver from dividing by 0 -vm_shSeEl.up(t,regi,teVRE) = 90; - -vm_usableSe.lo(t,regi,"seel") = 1e-6; - -*** Fix capacity for h2curt technology (modeled only in RLDC) -vm_cap.fx(t,regi,"h2curt",rlf) = 0; - - -*RP To ensure that the REMIND model doesn't overlook CSP due to gdx effects, ensure some minimum use in regions with good solar insolation, here proxied from the csp storage factor: -loop(regi$(p32_factorStorage(regi,"csp") < 1), - vm_shSeEl.lo(t,regi,"csp")$(t.val > 2025) = 0.5; - vm_shSeEl.lo(t,regi,"csp")$(t.val > 2050) = 1; - vm_shSeEl.lo(t,regi,"csp")$(t.val > 2100) = 2; -); - -*** Fix capacity to 0 for elh2VRE now that the equation q32_elh2VREcapfromTestor pushes elh2, not anymore elh2VRE, and capital costs are 1 -vm_cap.fx(t,regi,"elh2VRE",rlf) = 0; - -*** EOF ./modules/32_power/DTcoup/bounds.gms diff --git a/modules/32_power/DTcoup/datainput.gms b/modules/32_power/DTcoup/datainput.gms deleted file mode 100644 index 0afd3e4a0..000000000 --- a/modules/32_power/DTcoup/datainput.gms +++ /dev/null @@ -1,97 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/datainput.gms - -*------------------------------------------------------------------------------------ -*** IntC specific data input -*------------------------------------------------------------------------------------ - -parameter f32_shCHP(ttot,all_regi) "upper boundary of chp electricity generation" -/ -$ondelim -$include "./modules/32_power/IntC/input/f32_shCHP.cs4r" -$offdelim -/ -; -p32_shCHP(ttot,all_regi) = f32_shCHP(ttot,all_regi) + 0.05; -p32_shCHP(ttot,all_regi)$(ttot.val ge 2050) = min(p32_shCHP("2020",all_regi) + 0.15, 0.75); -p32_shCHP(ttot,all_regi)$((ttot.val gt 2020) and (ttot.val lt 2050)) = p32_shCHP("2020",all_regi) + ((p32_shCHP("2050",all_regi) - p32_shCHP("2020",all_regi)) / 30 * (ttot.val - 2020)); - -***parameter p32_grid_factor(all_regi) - multiplicative factor that scales total grid requirements down in comparatively small or homogeneous regions like Japan, Europe or India -parameter p32_grid_factor(all_regi) "multiplicative factor that scales total grid requirements down in comparatively small or homogeneous regions like Japan, Europe or India" -/ -$ondelim -$include "./modules/32_power/IntC/input/p32_grid_factor.cs4r" -$offdelim -/ -; - -***parameter p32_factorStorage(all_regi,all_te) - multiplicative factor that scales total curtailment and storage requirements up or down in different regions for different technologies (e.g. down for PV in regions where high solar radiation coincides with high electricity demand) -parameter f32_factorStorage(all_regi,all_te) "multiplicative factor that scales total curtailment and storage requirements up or down in different regions for different technologies (e.g. down for PV in regions where high solar radiation coincides with high electricity demand)" -/ -$ondelim -$include "./modules/32_power/IntC/input/f32_factorStorage.cs4r" -$offdelim -/ -; -$IFTHEN.WindOff %cm_wind_offshore% == "1" -f32_factorStorage(all_regi,"windoff") = f32_factorStorage(all_regi,"wind"); -f32_factorStorage(all_regi,"wind") = 1.35 * f32_factorStorage(all_regi,"wind"); -$ENDIF.WindOff -p32_factorStorage(all_regi,all_te) = f32_factorStorage(all_regi,all_te); - -$if not "%cm_storageFactor%" == "off" p32_factorStorage(all_regi,all_te)=%cm_storageFactor%*p32_factorStorage(all_regi,all_te); - -***parameter p32_storexp(all_regi,all_te) - exponent that determines how curtailment and storage requirements per kW increase with market share of wind and solar. 1 means specific marginal costs increase linearly -p32_storexp(regi,"spv") = 1; -p32_storexp(regi,"csp") = 1; -p32_storexp(regi,"wind") = 1; -$IFTHEN.WindOff %cm_wind_offshore% == "1" -p32_storexp(regi,"windoff") = 1; -$ENDIF.WindOff - - -***parameter p32_gridexp(all_regi,all_te) - exponent that determines how grid requirement per kW increases with market share of wind and solar. 1 means specific marginal costs increase linearly -p32_gridexp(regi,"spv") = 1; -p32_gridexp(regi,"csp") = 1; -p32_gridexp(regi,"wind") = 1; - - -table f32_storageCap(char, all_te) "multiplicative factor between dummy seel<-->h2 technologies and storXXX technologies" -$include "./modules/32_power/IntC/input/f32_storageCap.prn" -; - -$IFTHEN.WindOff %cm_wind_offshore% == "1" -f32_storageCap(char,"windoff") = f32_storageCap(char,"wind"); -$ENDIF.WindOff - -p32_storageCap(te,char) = f32_storageCap(char,te); -display p32_storageCap; - -$ontext -parameter p32_flex_maxdiscount(all_regi,all_te) "maximum electricity price discount for flexible technologies reached at high VRE shares" -/ -$ondelim -$include "./modules/32_power/IntC/input/p32_flex_maxdiscount.cs4r" -$offdelim -/ -; -*** convert from USD2015/MWh to trUSD2005/TWa -p32_flex_maxdiscount(regi,te) = p32_flex_maxdiscount(regi,te) * sm_TWa_2_MWh * s_D2015_2_D2005 * 1e-12; -display p32_flex_maxdiscount; -$offtext - -*** initialize p32_PriceDurSlope parameter -parameter f32_cm_PriceDurSlope_elh2(ext_regi) "slope of price duration curve for electrolysis [#]" / %cm_PriceDurSlope_elh2% /; -p32_PriceDurSlope(regi,"elh2") = f32_cm_PriceDurSlope_elh2("GLO"); -loop(ext_regi$f32_cm_PriceDurSlope_elh2(ext_regi), - loop(regi$regi_groupExt(ext_regi,regi), - p32_PriceDurSlope(regi,"elh2") = f32_cm_PriceDurSlope_elh2(ext_regi); - ); -); - -*** EOF ./modules/32_power/DTcoup/datainput.gms diff --git a/modules/32_power/DTcoup/declarations.gms b/modules/32_power/DTcoup/declarations.gms deleted file mode 100644 index 7776e381a..000000000 --- a/modules/32_power/DTcoup/declarations.gms +++ /dev/null @@ -1,55 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/declarations.gms - -parameters - p32_grid_factor(all_regi) "multiplicative factor that scales total grid requirements down in comparatively small or homogeneous regions like Japan, Europe or India" - p32_gridexp(all_regi,all_te) "exponent that determines how grid requirement per kW increases with market share of wind and solar. 1 means specific marginal costs increase linearly" - p32_storexp(all_regi,all_te) "exponent that determines how curtailment and storage requirements per kW increase with market share of wind and solar. 1 means specific marginal costs increase linearly" - p32_shCHP(ttot,all_regi) "upper boundary of chp electricity generation" - p32_factorStorage(all_regi,all_te) "multiplicative factor that scales total curtailment and storage requirements up or down in different regions for different technologies (e.g. down for PV in regions where high solar radiation coincides with high electricity demand)" - f32_storageCap(char, all_te) "multiplicative factor between dummy seel<-->h2 technologies and storXXX technologies" - p32_storageCap(all_te,char) "multiplicative factor between dummy seel<-->h2 technologies and storXXX technologies" - p32_PriceDurSlope(all_regi,all_te) "slope of price duration curve used for calculation of electricity price for flexible technologies, determines how fast electricity price declines at lower capacity factors" -; - -scalars -s32_storlink "how strong is the influence of two similar renewable energies on each other's storage requirements (1= complete, 4= rather small)" /3/ -; - -positive variables - v32_shStor(ttot,all_regi,all_te) "share of seel production from renewables that needs to be stored, range 0..1 [0,1]" - v32_storloss(ttot,all_regi,all_te) "total energy loss from storage for a given technology [TWa]" - vm_shSeEl(ttot,all_regi,all_te) "new share of electricity production in % [%]" - v32_testdemSeShare(ttot,all_regi,all_te) "test variable for tech share of SE electricity demand" -; - -equations - q32_balSe(ttot,all_regi,all_enty) "balance equation for electricity secondary energy" - q32_usableSe(ttot,all_regi,all_enty) "calculate usable se before se2se and MP/XP (without storage)" - q32_usableSeTe(ttot,all_regi,entySe,all_te) "calculate usable se produced by one technology (vm_usableSeTe)" - q32_limitCapTeStor(ttot,all_regi,teStor) "calculate the storage capacity required by vm_storloss" - q32_limitCapTeChp(ttot,all_regi) "capacitiy constraint for chp electricity generation" - q32_limitCapTeGrid(ttot,all_regi) "calculate the additional grid capacity required by VRE" - q32_shSeEl(ttot,all_regi,all_te) "calculate share of electricity production of a technology (vm_shSeEl)" - q32_shStor(ttot,all_regi,all_te) "equation to calculate v32_shStor" - q32_storloss(ttot,all_regi,all_te) "equation to calculate vm_storloss" - q32_operatingReserve(ttot,all_regi) "operating reserve for necessary flexibility" - q32_h2turbVREcapfromTestor(tall,all_regi) "calculate capacities of dummy seel<--h2 technology from storXXX technologies" - q32_elh2VREcapfromTestor(tall,all_regi) "calculate capacities of dummy seel-->h2 technology from storXXX technologies" - q32_flexAdj(tall,all_regi,all_te) "calculate flexibility used in flexibility tax for technologies with electricity input" - q32_flexPriceShareMin "calculatae miniumum share of average electricity that flexible technologies can see" - q32_flexPriceShare(tall,all_regi,all_te) "calculate share of average electricity price that flexible technologies see" - q32_flexPriceBalance(tall,all_regi) "constraint such that flexible electricity prices balanance to average electricity price" -; - -variables -v32_flexPriceShare(tall,all_regi,all_te) "share of average electricity price that flexible technologies see [share: 0...1]" -v32_flexPriceShareMin(tall,all_regi,all_te) "possible minimum of share of average electricity price that flexible technologies see [share: 0...1]" -; - -*** EOF ./modules/32_power/DTcoup/declarations.gms diff --git a/modules/32_power/DTcoup/equations.gms b/modules/32_power/DTcoup/equations.gms deleted file mode 100644 index fcaa37f62..000000000 --- a/modules/32_power/DTcoup/equations.gms +++ /dev/null @@ -1,236 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/equations.gms - -*' @equations - -***--------------------------------------------------------------------------- -*' Balance equation for electricity secondary energy type: -***--------------------------------------------------------------------------- -q32_balSe(t,regi,enty2)$(sameas(enty2,"seel")).. - sum(pe2se(enty,enty2,te), vm_prodSe(t,regi,enty,enty2,te) ) - + sum(se2se(enty,enty2,te), vm_prodSe(t,regi,enty,enty2,te) ) - + sum(pc2te(enty,entySe(enty3),te,enty2), - pm_prodCouple(regi,enty,enty3,te,enty2) * vm_prodSe(t,regi,enty,enty3,te) ) - + sum(pc2te(enty4,entyFe(enty5),te,enty2), - pm_prodCouple(regi,enty4,enty5,te,enty2) * vm_prodFe(t,regi,enty4,enty5,te) ) - + sum(pc2te(enty,enty3,te,enty2), - sum(teCCS2rlf(te,rlf), - pm_prodCouple(regi,enty,enty3,te,enty2) * vm_co2CCS(t,regi,enty,enty3,te,rlf) ) ) - + vm_Mport(t,regi,enty2) - =e= - sum(se2fe(enty2,enty3,te), vm_demSe(t,regi,enty2,enty3,te) ) - + sum(se2se(enty2,enty3,te), vm_demSe(t,regi,enty2,enty3,te) ) - + sum(teVRE, v32_storloss(t,regi,teVRE) ) - + sum(pe2rlf(enty3,rlf2), (pm_fuExtrOwnCons(regi, enty2, enty3) * vm_fuExtr(t,regi,enty3,rlf2))$(pm_fuExtrOwnCons(regi, enty2, enty3) gt 0))$(t.val > 2005) !! do not use in 2005 because this demand is not contained in 05_initialCap - + vm_Xport(t,regi,enty2) -; - -q32_usableSe(t,regi,entySe)$(sameas(entySe,"seel")).. - vm_usableSe(t,regi,entySe) - =e= - sum(pe2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(se2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(pc2te(entyPe,entySe(enty3),te,entySe)$(pm_prodCouple(regi,entyPe,enty3,te,entySe) gt 0), - pm_prodCouple(regi,entyPe,enty3,te,entySe)*vm_prodSe(t,regi,entyPe,enty3,te) ) - - sum(teVRE, v32_storloss(t,regi,teVRE) ) -; - -q32_usableSeTe(t,regi,entySe,te)$(sameas(entySe,"seel") AND teVRE(te)).. - vm_usableSeTe(t,regi,entySe,te) - =e= - sum(pe2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(se2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(pc2te(enty,entySe(enty3),te,entySe)$(pm_prodCouple(regi,enty,enty3,te,entySe) gt 0), - pm_prodCouple(regi,enty,enty3,te,entySe) * vm_prodSe(t,regi,enty,enty3,te) ) - - sum(teVRE$sameas(te,teVRE), v32_storloss(t,regi,teVRE) ) -; - -***--------------------------------------------------------------------------- -*' Definition of capacity constraints for storage: -***--------------------------------------------------------------------------- -q32_limitCapTeStor(t,regi,teStor)$( t.val ge 2015 ) .. - ( 0.5$( cm_VRE_supply_assumptions eq 1 ) - + 1$( cm_VRE_supply_assumptions ne 1 ) - ) - * sum(VRE2teStor(teVRE,teStor), v32_storloss(t,regi,teVRE)) - * pm_eta_conv(t,regi,teStor) - / (1 - pm_eta_conv(t,regi,teStor)) - =l= - sum(te2rlf(teStor,rlf), - vm_capFac(t,regi,teStor) - * pm_dataren(regi,"nur",rlf,teStor) - * vm_cap(t,regi,teStor,rlf) - ) -; - - -*** H2 storage implementation: Storage technologies (storspv, storwind etc.) also -*** represent H2 storage. This is implemented by automatically scaling up capacities of -*** elh2VRE (electrolysis from VRE, seel -> seh2) and H2 turbines (h2turbVRE, seh2 -> seel) -*** with VRE capacities which require storage (according to q32_limitCapTeStor): - -*** build additional electrolysis capacities with stored VRE electricity -q32_elh2VREcapfromTestor(t,regi).. - vm_cap(t,regi,"elh2","1") - =g= - sum(te$teStor(te), p32_storageCap(te,"elh2VREcapratio") * vm_cap(t,regi,te,"1") ) -; - -*** build additional h2 to seel capacities to use stored hydrogen -q32_h2turbVREcapfromTestor(t,regi).. - vm_cap(t,regi,"h2turbVRE","1") - =e= - sum(te$teStor(te), p32_storageCap(te,"h2turbVREcapratio") * vm_cap(t,regi,te,"1") ) -; - -***--------------------------------------------------------------------------- -*' Definition of capacity constraints for CHP technologies: -***--------------------------------------------------------------------------- -q32_limitCapTeChp(t,regi).. - sum(pe2se(enty,"seel",teChp(te)), vm_prodSe(t,regi,enty,"seel",te) ) - =l= - p32_shCHP(t,regi) - * sum(pe2se(enty,"seel",te), vm_prodSe(t,regi,enty,"seel",te) ) -; - -***--------------------------------------------------------------------------- -*' Calculation of necessary grid installations for centralized renewables: -***--------------------------------------------------------------------------- -q32_limitCapTeGrid(t,regi)$( t.val ge 2015 ) .. - vm_cap(t,regi,"gridwind",'1') !! Technology is now parameterized to yield marginal costs of ~3.5$/MWh VRE electricity - / p32_grid_factor(regi) !! It is assumed that large regions require higher grid investment - =g= - vm_prodSe(t,regi,"pesol","seel","spv") - + vm_prodSe(t,regi,"pesol","seel","csp") - + 1.5 * vm_prodSe(t,regi,"pewin","seel","wind") !! wind has larger variations accross space, so adding grid is more important for wind (result of REMIX runs for ADVANCE project) -$IFTHEN.WindOff %cm_wind_offshore% == "1" - + 3 * vm_prodSe(t,regi,"pewin","seel","windoff") -$ENDIF.WindOff -; - -***--------------------------------------------------------------------------- -*' Calculation of share of electricity production of a technology: -***--------------------------------------------------------------------------- -q32_shSeEl(t,regi,teVRE).. - vm_shSeEl(t,regi,teVRE) / 100 * vm_usableSe(t,regi,"seel") - =e= - vm_usableSeTe(t,regi,"seel",teVRE) -; - -***--------------------------------------------------------------------------- -*' Calculation of necessary storage electricity production: -***--------------------------------------------------------------------------- -q32_shStor(t,regi,teVRE)$(t.val ge 2015).. - v32_shStor(t,regi,teVRE) - =g= - p32_factorStorage(regi,teVRE) * 100 - * ( - (1.e-10 + (vm_shSeEl(t,regi,teVRE)+ sum(VRE2teVRElinked(teVRE,teVRE2), vm_shSeEl(t,regi,teVRE2)) /s32_storlink)/100 ) ** p32_storexp(regi,teVRE) !! offset of 1.e-10 for numerical reasons: gams doesn't like 0 if the exponent is not integer - - (1.e-10 ** p32_storexp(regi,teVRE) ) !! offset correction - - 0.07 !! first 7% of VRE share bring no negative effects - ) -; - -q32_storloss(t,regi,teVRE)$(t.val ge 2015).. - v32_storloss(t,regi,teVRE) - =e= - v32_shStor(t,regi,teVRE) / 93 !! corrects for the 7%-shift in v32_shStor: at 100% the value is correct again - * sum(VRE2teStor(teVRE,teStor), (1 - pm_eta_conv(t,regi,teStor) ) / pm_eta_conv(t,regi,teStor) ) - * vm_usableSeTe(t,regi,"seel",teVRE) -; - -***--------------------------------------------------------------------------- -*' Operating reserve constraint -***--------------------------------------------------------------------------- -q32_operatingReserve(t,regi)$(t.val ge 2010).. -***1 is the chosen load coefficient - vm_usableSe(t,regi,"seel") - =l= -*** Variable renewable coefficients could be expected to be negative because they are variable. -*** However they are modeled positive because storage conditions make variable renewables controllable. - sum(pe2se(enty,"seel",te)$(NOT teVRE(te)), - pm_data(regi,"flexibility",te) * vm_prodSe(t,regi,enty,"seel",te) ) - + sum(se2se(enty,"seel",te)$(NOT teVRE(te)), - pm_data(regi,"flexibility",te) * vm_prodSe(t,regi,enty,"seel",te) ) - + sum(pe2se(enty,"seel",teVRE), - pm_data(regi,"flexibility",teVRE) * (vm_prodSe(t,regi,enty,"seel",teVRE)-v32_storloss(t,regi,teVRE)) ) - + - sum(pe2se(enty,"seel",teVRE), - sum(VRE2teStor(teVRE,teStor), - pm_data(regi,"flexibility",teStor) * (vm_prodSe(t,regi,enty,"seel",teVRE)-v32_storloss(t,regi,teVRE)) ) ) -; - -*** FS: calculate flexibility adjustment used in flexibility tax for technologies with electricity input -***---------------------------------------------------------------------------- - -*** This equation calculates the minimal flexible electricity price that flexible technologies (like elh2) can see. It is reached when the VRE share is 100%. -*** It depends on the capacity factor with a hyperbolic function. The equation ensures that by decreasing -*** capacity factor of flexible technologies (teFlex) these technologies see lower electricity prices given that there is a high VRE share in the power system. - -*** On the derivation of the equation: -*** The formulation assumes a cubic price duration curve. That is, the effective electricity price the flexible technologies sees -*** depends on the capacity factor (CF) with a cubic function centered at (0.5,1): -*** p32_PriceDurSlope * (CF-0.5)^3 + 1, -*** Hence, at CF = 0.5, the REMIND average price pm_SEPrice(t,regi,"seel") is paid. -*** To get the average electricity price that a flexible technology sees at a certain CF, -*** we need to integrate this function with respect to CF and divide by CF. This gives the formulation below: -*** v32_flexPriceShareMin = p32_PriceDurSlope * ((CF-0.5)^4-0.5^4) / (4*CF) + 1. -*** This is the new average electricity price a technology sees if it runs on (a possibly lower than one) capacity factor CF -*** and deliberately uses hours of low-cost electricity. - q32_flexPriceShareMin(t,regi,te)$(teFlex(te)).. - v32_flexPriceShareMin(t,regi,te) * 4 * vm_capFac(t,regi,te) - =e= - p32_PriceDurSlope(regi,te) * (power(vm_capFac(t,regi,te) - 0.5,4) - 0.5**4) + - 4 * vm_capFac(t,regi,te) -; - -*** Calculates the electricity price of flexible technologies: -*** The effective flexible price linearly decreases with VRE share -*** from 1 (at 0% VRE share) to v32_flexPriceShareMin (at 100% VRE). -q32_flexPriceShare(t,regi,te)$(teFlex(te)).. - v32_flexPriceShare(t,regi,te) - =e= - 1 - (1-v32_flexPriceShareMin(t,regi,te)) * sum(teVRE, vm_shSeEl(t,regi,teVRE))/100 -; - -*** This balance ensures that the lower electricity prices of flexible technologies are compensated -*** by higher electricity prices of inflexible technologies. Inflexible technologies are all technologies -*** which are part of teFlexTax but not of teFlex. The weighted sum of -*** flexible/inflexible electricity prices (v32_flexPriceShare) and electricity demand must be one. -*** Note: this is only on if cm_FlexTaxFeedback = 1. Otherwise, there is no change in electricity prices for inflexible technologies. -q32_flexPriceBalance(t,regi)$(cm_FlexTaxFeedback eq 1).. - sum(en2en(enty,enty2,te)$(teFlexTax(te)), - vm_demSe(t,regi,enty,enty2,te)) - =e= - sum(en2en(enty,enty2,te)$(teFlexTax(te)), - vm_demSe(t,regi,enty,enty2,te) * v32_flexPriceShare(t,regi,te)) -; - - -*** This calculates the flexibility benefit or cost per unit electricity input -*** of flexibile or inflexible technology. Flexible technologies benefit -*** (v32_flexPriceShare < 1), while inflexible technologies are penalized -*** (v32_flexPriceShare > 1). -*** In the tax module, vm_flexAdj is then deduced from the electricity price via -*** the flexibility tax formulation. -*** Below, pm_SEPrice(t,regi,"seel") is the (average) electricity price from the -*** last iteration, limited between 0 and 230 $/MWh (= 2 T$/TWa) to prevent -*** unreasonable FE prices caused by meaningless marginals in infeasible Nash -*** iterations from propagating through the model. -*** Fixed to 0 if cm_flex_tax != 1, and before 2025. -q32_flexAdj(t,regi,te)$(teFlexTax(te)).. - vm_flexAdj(t,regi,te) - =e= - ( (1 - v32_flexPriceShare(t,regi,te)) - * max(0, min(2, pm_SEPrice(t,regi,"seel"))) - )$( cm_flex_tax eq 1 AND t.val ge 2025 ) -; - -*' @stop - -*** EOF ./modules/32_power/DTcoup/equations.gms diff --git a/modules/32_power/DTcoup/not_used.txt b/modules/32_power/DTcoup/not_used.txt deleted file mode 100644 index 8ddfa6f74..000000000 --- a/modules/32_power/DTcoup/not_used.txt +++ /dev/null @@ -1,18 +0,0 @@ -# | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -# | authors, and contributors see CITATION.cff file. This file is part -# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -# | AGPL-3.0, you are granted additional permissions described in the -# | REMIND License Exception, version 1.0 (see LICENSE file). -# | Contact: remind@pik-potsdam.de -name,type,reason -vm_capDistr, variable, ??? -vm_demSeOth, variable, ??? -vm_prodSeOth, variable, ??? -pm_emifac, parameter, ??? -cm_nucscen, switch, ??? -vm_deltaCap,input,questionnaire -cm_emiscen,input,questionnaire -cm_ccapturescen,input,questionnaire -pm_boundCapCCS,input,questionnaire -pm_cap0,input,questionnaire -vm_shDemSeel,input,only used in IntC realization diff --git a/modules/32_power/DTcoup/postsolve.gms b/modules/32_power/DTcoup/postsolve.gms deleted file mode 100644 index 7ee28a95e..000000000 --- a/modules/32_power/DTcoup/postsolve.gms +++ /dev/null @@ -1,14 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/postsolve.gms - -*** calculation of SE electricity price (useful for internal use and reporting purposes) -pm_SEPrice(ttot,regi,entySe)$(abs (qm_budget.m(ttot,regi)) gt sm_eps AND sameas(entySe,"seel")) = - q32_balSe.m(ttot,regi,entySe) / qm_budget.m(ttot,regi); - -*** EOF ./modules/32_power/DTcoup/postsolve.gms - diff --git a/modules/32_power/DTcoup/preloop.gms b/modules/32_power/DTcoup/preloop.gms deleted file mode 100644 index d496d54cd..000000000 --- a/modules/32_power/DTcoup/preloop.gms +++ /dev/null @@ -1,15 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de - -*** SOF ./modules/32_power/DTcoup/preloop.gms - -*** read marginal of seel balance equation -Execute_Loadpoint 'input' q32_balSe.m = q32_balSe.m; - - - -*** EOF ./modules/32_power/DTcoup/preloop.gms diff --git a/modules/32_power/DTcoup/presolve.gms b/modules/32_power/DTcoup/presolve.gms deleted file mode 100644 index 054158db1..000000000 --- a/modules/32_power/DTcoup/presolve.gms +++ /dev/null @@ -1,14 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/presolve.gms - - -*** calculation of SE electricity price (useful for internal use and reporting purposes) -pm_SEPrice(t,regi,entySe)$(abs (qm_budget.m(t,regi)) gt sm_eps AND sameas(entySe,"seel")) = - q32_balSe.m(t,regi,entySe) / qm_budget.m(t,regi); - -*** EOF ./modules/32_power/DTcoup/presolve.gms diff --git a/modules/32_power/DTcoup/realization.gms b/modules/32_power/DTcoup/realization.gms deleted file mode 100644 index 47ac083a2..000000000 --- a/modules/32_power/DTcoup/realization.gms +++ /dev/null @@ -1,43 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/DTcoup/realization.gms - -*' @description -*' -*'The `IntC` realization (Integrated Costs) assumes a single electricity market balance. -*' -*'This module determines power system supply specific technology behavior, which sums up to the general core capacity equations to define the power sector operation and investment decisions. -*' -*'Contrary to other secondary energy types in REMIND, this requires to move the electricity secondary energy balance (supply = demand) from the core to the module code. -*' -*' -*'In summary, the specific power technology equations found in this module reflect the points below. -*' -*' -*'Storage requirements are based on intermittent renewables share, synergies between different renewables production profiles and curtailment. -*' -*'Additional grid capacities are calculated for high intermittent renewable capacity (solar and wind) and regional spatial differences. -*' -*'Combined heat and power technologies flexibility is limited to technology and spatial observed data. -*' -*'Operation reserve requirements are enforced to provide enough flexibility to the power system frequency regulation. -*' -*'Hydrogen can be used to reduce renewable power curtailment and provide flexibility to the system future generation. -*' -*' @authors Robert Pietzcker, Falko Ueckerdt, Renato Rodrigues - -*####################### R SECTION START (PHASES) ############################## -$Ifi "%phase%" == "declarations" $include "./modules/32_power/DTcoup/declarations.gms" -$Ifi "%phase%" == "datainput" $include "./modules/32_power/DTcoup/datainput.gms" -$Ifi "%phase%" == "equations" $include "./modules/32_power/DTcoup/equations.gms" -$Ifi "%phase%" == "preloop" $include "./modules/32_power/DTcoup/preloop.gms" -$Ifi "%phase%" == "bounds" $include "./modules/32_power/DTcoup/bounds.gms" -$Ifi "%phase%" == "presolve" $include "./modules/32_power/DTcoup/presolve.gms" -$Ifi "%phase%" == "postsolve" $include "./modules/32_power/DTcoup/postsolve.gms" -*######################## R SECTION END (PHASES) ############################### - -*** EOF ./modules/32_power/DTcoup/realization.gms diff --git a/modules/32_power/IntC/not_used.txt b/modules/32_power/IntC/not_used.txt index 9261eeb93..85ff9312e 100644 --- a/modules/32_power/IntC/not_used.txt +++ b/modules/32_power/IntC/not_used.txt @@ -5,13 +5,3 @@ # | REMIND License Exception, version 1.0 (see LICENSE file). # | Contact: remind@pik-potsdam.de name,type,reason -vm_capDistr, variable, ??? -vm_demSeOth, variable, ??? -vm_prodSeOth, variable, ??? -pm_emifac, parameter, ??? -cm_nucscen, switch, ??? -vm_deltaCap,input,questionnaire -cm_emiscen,input,questionnaire -cm_ccapturescen,input,questionnaire -pm_boundCapCCS,input,questionnaire -pm_cap0,input,questionnaire diff --git a/modules/32_power/RLDC/bounds.gms b/modules/32_power/RLDC/bounds.gms deleted file mode 100644 index 1babb500d..000000000 --- a/modules/32_power/RLDC/bounds.gms +++ /dev/null @@ -1,184 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/bounds.gms - -***----------------------------------------------------------- -*** module specific bounds -***------------------------------------------------------------ - -vm_usableSe.lo(t,regi,"seel") = 1e-6; - -v32_capLoB.up(t,regi,te,LoB) = 2; !! The total power system has maximum demand of 1 -v32_LoBheight.up(t,regi,LoB) = 2; !! The total power system has maximum demand of 1 -v32_LoBheightCum.up(t,regi,LoB) = 2; !! The total power system has maximum demand of 1.5 (should be one, but the reforming of the baseload band leads to -v32_shTh.up(t,regi,teVRE) = 2; !! Worlds with higher than twice the total energy demand coming from either wind or solar (before curtailment) are unrealistic - -v32_scaleCap.up(t,regi) = 100; !! no power system will be larger than 100 TW -v32_scaleCap.up(t,regi) = 20; -v32_scaleCap.lo(t,regi) = 1e-4; !! Make sure REMIND does not try to shrink a power system to zero -v32_scaleCap.lo(t,regi) = 0.01; - -loop(te$(NOT teRLDCDisp(te)), - vm_capFac.fx(t,regi,te) = pm_cf(t,regi,te); -); - -vm_capFac.up(t,regi,teRLDCDisp) = 1.00; -vm_capFac.l(t,regi,teRLDCDisp) = pm_cf("2005",regi,teRLDCDisp) * pm_dataren(regi,"nur","1",teRLDCDisp); - -v32_capLoB.lo(t,regi,teRLDCDisp,LoB)$(t.val>2015) = 1e-6; !!Lower bound to capacity to avoid infeasibility -*v32_capLoB.lo("2005",regi,"geohdr",LoB) = 1e-6; !!Necessary to avoid infeasibility due to geohdr being zero in all LoB except for the 4th LoB, making impossible to the vm_capFac to match the v32_capLoB sum, with the lack of v32_capER in the initial year and a p32_capFacLoB != 1 - -*RP* CCS technologies can make a problem if the caps are fixed to 0, but the capLoBs left free -loop(regi, - if ( (cm_ccapturescen eq 2) OR (cm_emiscen eq 1) , !! in no-CCS and BAU scenarios, no CCS is allowed - loop(emi2te(enty,"seel",te,"cco2")$( pm_emifac("2020",regi,enty,"seel",te,"cco2") >0 ), !! use 2020 as proxy - only limit the seel technologies - the others don't have a capFac and capLob and capER - loop(te2rlf(te,rlf), - vm_capFac.fx(ttot,regi,te) = 0; - v32_capLoB.fx(t,regi,te,LoB) = 0; - v32_capER.fx(t,regi,te) = 0; - ); - ); - elseif (cm_ccapturescen eq 5), !! noElecCCS - loop(emi2te(enty,"seel",te,"cco2")$( pm_emifac("2020",regi,enty,"seel",te,"cco2") >0 ), - loop(te2rlf(te,rlf), - vm_capFac.fx(ttot,regi,te) = 0; - v32_capLoB.fx(t,regi,te,LoB) = 0; - v32_capER.fx(t,regi,te) = 0; - ); - ); - ); -); - -*Avoiding infeasibilities from upper limit on CCS deployment in 2020 -loop(regi, - loop(t$(t.val le 2030), - if( ( pm_boundCapCCS(t,regi,"up") eq 0), - vm_capFac.fx(t,regi,teCCS) = 0; - v32_capLoB.fx(t,regi,teCCS,LoB) = 0; - v32_capER.fx(t,regi,teCCS) = 0; - ); - ); -); - - -*RP same for nuc: -if ( (cm_nucscen eq 5) , !! in no-Nuc scenarios, no tnrs is allowed - loop(pe2se("peur",enty,te), - vm_capFac.fx(t,regi,te)$(t.val > 2060) = 0; - v32_capLoB.fx(t,regi,te,LoB)$(t.val > 2060) = 0; - v32_capER.fx(t,regi,te)$(t.val > 2060) = 0; - ); -); - -vm_capFac.fx(t,regi,"fnrs")= 0; -v32_capLoB.fx(t,regi,"fnrs",LoB)= 0; -v32_capER.fx(t,regi,"fnrs")= 0; - -v32_curt.lo(t,regi)$(t.val>2010) = 0; - -*RP* CHP technologies should not have larger CFs than 0.6, as heat is not always needed. They can still contribute to -*** baseload, but then some other part of the total capacity needs to be underutilized - this could represent costs for thermal storage -loop(te$teChp(te), - vm_capFac.up(t,regi,te)$(t.val > 2005) = 0.6; -); - -***---------------------------------------------- -*RP: bounds to make the first runs more feasible -***---------------------------------------------- -loop(regi, - loop(te$( (teRLDCDisp(te)) ), - if( ( pm_cap0(regi,te) > 0 ) , - vm_capFac.up("2005",regi,te) = 1.01 * pm_cf("2005",regi,te); - vm_capFac.lo("2005",regi,te) = 0.98 * pm_cf("2005",regi,te); - vm_capFac.lo("2010",regi,te) = 0.009; - vm_capFac.lo("2015",regi,te) = 0.009; - if( teReNoBio(te), - vm_capFac.up("2005",regi,te) = 1.01 * pm_dataren(regi,"nur","1",te) * pm_cf("2005",regi,te); - vm_capFac.lo("2005",regi,te) = 0.4 * pm_dataren(regi,"nur","1",te) * pm_cf("2005",regi,te); - ); - else - vm_capFac.fx("2005",regi,te) = 0; - ); - ); -); - -vm_capFac.up(t,regi,"hydro")$(t.val > 2005) = 0.25; !! Japan has quite low hydro CFs, so the rule "0.4 * pm_dataren(regi,"nur","1",te)" produces infeasibilities - -vm_capFac.lo("2005",regi,"hydro") = 0.2; !! Japan has quite low hydro CFs, so the rule "0.4 * pm_dataren(regi,"nur","1",te)" produces infeasibilities. As the 2005 bounds are anyway only there to facilitate that the model finds an initial solution, set this limit for all regions - -***----------------------------------------------------- -*** -***----------------------------------------------------- - -***v32_LoBheightCum.lo(t,regi,LoB) = 0.01; -v32_LoBheightCum.lo("2010",regi,"1") = 0.82; -v32_LoBheightCum.lo("2010",regi,"2") = 0.48; -v32_LoBheightCum.lo("2010",regi,"3") = 0.38; -v32_LoBheightCum.lo("2010",regi,"4") = 0.26; - -v32_shTh.lo(t,regi,"spv")$(t.val > 2020) = 0.01; -v32_shTh.lo(t,regi,"wind")$(t.val > 2020) = 0.01; - -v32_curt.up(t,regi) = 100; -$if %cm_Full_Integration% == "on" v32_curt.fx(t,regi) = 0; - -*** Advanced technologies can't be build prior to 2015/2020 -loop(regi, - loop(teNoLearn(te), - if( (pm_data(regi,"tech_stat",te) eq 2), - v32_capLoB.fx("2010",regi,te,LoB) = 0; - elseif (pm_data(regi,"tech_stat",te) eq 3), - v32_capLoB.fx("2010",regi,te,LoB) = 0; - v32_capLoB.fx("2015",regi,te,LoB) = 0; - ); - ); -); - -*** nuclear only as baseload -v32_capLoB.fx(t,regi,"tnrs","1")$(t.val > 2010) = 0; -v32_capLoB.fx(t,regi,"tnrs","2")$(t.val > 2010) = 0; -v32_capLoB.fx(t,regi,"tnrs","3")$(t.val > 2010) = 0; - - -*** facilitiate finding sulutions in the ADVANCE Full_Integration run -$if %cm_Full_Integration% == "on" v32_capLoB.lo(t,regi,"spv",LoB)$(t.val > 2030) = 1e-6; -$if %cm_Full_Integration% == "on" v32_capLoB.lo(t,regi,"wind",LoB)$(t.val > 2030) = 1e-6; -$if %cm_Full_Integration% == "on" vm_cap.lo(t,regi,"spv",LoB)$(t.val > 2030) = 1e-3; -$if %cm_Full_Integration% == "on" vm_cap.lo(t,regi,"wind",LoB)$(t.val > 2030) = 1e-3; - -***No slow ramping technologies as peaking plants -v32_capLoB.fx(t,regi,te,"1")$teNotLoB1(te) = 0; -***Technologies that can not run for 7500 FLh, and therefore cannot be considered at baseload -v32_capLoB.fx(t,regi,te,"4")$teNotBase(te) = 0; - -***Make sure the model sees the h2-el connections -vm_cap.lo(t,regi,"h2turb","1")$(t.val > 2050) = 1e-6; -vm_cap.lo(t,regi,"elh2","1")$(t.val > 2050) = 1e-6; -vm_cap.lo(t,regi,"h2curt","1")$(t.val > 2090) = 1e-5; -$if %cm_Full_Integration% == "on" vm_cap.fx(t,regi,"h2curt","1") = 0; -$if %cm_Full_Integration% == "on" vm_deltaCap.fx(t,regi,"h2curt","1") = 0; - -*** Allow the curtailment->H2 channel: -vm_prodSeOth.up(t,regi,"seh2","h2curt") = 1e6; -vm_prodSeOth.lo(t,regi,"seh2","h2curt")$(t.val > 2090) = 1e-6; - -$if %cm_Full_Integration% == "on" vm_prodSeOth.fx(t,regi,"seh2","h2curt") = 0; !! no curtailment if all VRE are treated as dispatchable - -vm_cap.fx(t,regi,"gridspv","1")$(t.val > 2070) = 0; -vm_cap.fx(t,regi,"gridcsp","1")$(t.val > 2070) = 0; -vm_cap.fx(t,regi,"storcsp","1")$(t.val > 2070) = 0; -vm_cap.fx(t,regi,"storwind","1")$(t.val > 2070) = 0; -$IFTHEN.WindOff %cm_wind_offshore% == "1" -vm_cap.fx(t,regi,"storwindoff","1")$(t.val > 2070) = 0; -$ENDIF.WindOff - -$if %cm_Full_Integration% == "on" vm_cap.fx(t,regi,"storspv","1") = 0; -$if %cm_Full_Integration% == "on" vm_deltaCap.fx(t,regi,"storspv","1") = 0; - -vm_deltaCap.up(t,regi,"dot",rlf)$(t.val > 2040) = 1e-5; - -*** EOF ./modules/32_power/RLDC/bounds.gms diff --git a/modules/32_power/RLDC/datainput.gms b/modules/32_power/RLDC/datainput.gms deleted file mode 100644 index f9bcd8f2a..000000000 --- a/modules/32_power/RLDC/datainput.gms +++ /dev/null @@ -1,105 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/datainput.gms - -*------------------------------------------------------------------------------------ -*** RLDC specific data input -*------------------------------------------------------------------------------------ - -parameter f32_shCHP(ttot,all_regi) "upper boundary of chp electricity generation" -/ -$ondelim -$include "./modules/32_power/RLDC/input/f32_shCHP.cs4r" -$offdelim -/ -; -p32_shCHP(ttot,all_regi) = f32_shCHP(ttot,all_regi) + 0.05; -p32_shCHP(ttot,all_regi)$(ttot.val ge 2050) = min(p32_shCHP("2020",all_regi) + 0.15, 0.75); -p32_shCHP(ttot,all_regi)$((ttot.val gt 2020) and (ttot.val lt 2050)) = p32_shCHP("2020",all_regi) + ((p32_shCHP("2050",all_regi) - p32_shCHP("2020",all_regi)) / 30 * (ttot.val - 2020)); - - -***parameter p32_grid_factor(all_regi) - multiplicative factor that scales total grid requirements down in comparatively small or homogeneous regions like Japan, Europe or India -parameter p32_grid_factor(all_regi) "multiplicative factor that scales total grid requirements down in comparatively small or homogeneous regions like Japan, Europe or India" -/ -$ondelim -$include "./modules/32_power/RLDC/input/p32_grid_factor.cs4r" -$offdelim -/ -; - -***parameter p32_capFacLoB(LoB) - Capacity factor of a load band (Unit 0..1) -p32_capFacLoB("1") = 0.08; -p32_capFacLoB("2") = 0.25; -p32_capFacLoB("3") = 0.50; -p32_capFacLoB("4") = 0.86; !! no plant runs longer than 7500 hours - accordingly the height of the base load band is rescaled in q32_LoBheight - -***parameter p32_ResMarg(ttot,all_regi) - reserve margin as markup on actual peak capacity. Unit [0..1] -p32_ResMarg(ttot,regi) = 0.30; - -***parameter p32_RLDCcoeff(all_regi,PolyCoeff,RLDCbands) - Coefficients for the non-separable wind/solar-cross-product polynomial RLDC fit -table f32_RLDC_Coeff_LoB(all_regi,RLDCbands,PolyCoeff) "RLDC coefficients for combined Wind-Solar Polynomial" -$ondelim -$include "./modules/32_power/RLDC/input/f32_RLDC_Coeff_LoB.cs3r" -$offdelim -; -table f32_RLDC_Coeff_Peak(all_regi,RLDCbands,PolyCoeff) "RLDC coefficients for combined Wind-Solar Polynomial" -$ondelim -$include "./modules/32_power/RLDC/input/f32_RLDC_Coeff_Peak.cs3r" -$offdelim -; - -loop(regi, - loop(RLDCbands, - if( PeakDep(RLDCbands), - p32_RLDCcoeff(regi,PolyCoeff,RLDCbands) = (f32_RLDC_Coeff_LoB(regi,RLDCbands,PolyCoeff)+f32_RLDC_Coeff_Peak(regi,RLDCbands,PolyCoeff)) / f32_RLDC_Coeff_Peak(regi,"peak","p00"); - else - p32_RLDCcoeff(regi,PolyCoeff,RLDCbands) = (f32_RLDC_Coeff_LoB(regi,RLDCbands,PolyCoeff)+f32_RLDC_Coeff_Peak(regi,RLDCbands,PolyCoeff)) ; - ) - ); -); - -***parameter p32_LoBheight0(all_regi,LoB) - Load band heights at 0% VRE share (Unit 0..1) -loop(LoB, - p32_LoBheight0(regi,LoB) = p32_RLDCcoeff(regi,"p00",LoB) - p32_RLDCcoeff(regi,"p00",LoB+1)$( LoB.val < card(LoB) ); - if ( ( LoB.val eq card(LoB) ), - p32_LoBheight0(regi,LoB) = p32_LoBheight0(regi,LoB) * ( 1 / p32_capFacLoB(LoB) ); !! upscale the height of the base-load band to represent the fact that the fit was done with 8760 hours ( = 1), while no plant runs longer than 7500 hours (CF = 0.86) - ) -); - -***parameter p32_capFacDem(all_regi) - Average demand factor of a power sector (Unit 0..1) -p32_capFacDem(regi) = sum(LoB, p32_LoBheight0(regi,LoB) * p32_capFacLoB(LoB) ); - -loop(regi, - loop(te$(teReNoBio(te)), - p32_avCapFac(t,regi,te) = - sum(rlf, pm_dataren(regi,"nur",rlf,te) * pm_dataren(regi,"maxprod",rlf,te) ) - / ( sum(rlf, pm_dataren(regi,"maxprod",rlf,te) ) + 1e-8) - ; - ); -); - -$ontext -loop(regi, - loop(te$(teReNoBio(te)), - p32_avCapFac(t,regi,te) = -* sum(rlf$(UsedGrades2070(regi,te,rlf)), - sum(rlf, - pm_dataren(regi,"nur",rlf,te) * pm_dataren(regi,"maxprod",rlf,te) - ) -* / ( sum(rlf$UsedGrades2070(regi,te,rlf), pm_dataren(regi,"maxprod",rlf,te) ) - / ( sum(rlf, pm_dataren(regi,"maxprod",rlf,te) ) - + 1e-8) ; - ); -); -$offtext - -***parameter p32_curtOn(all_regi) - control variable for curtailment fitted from the DIMES-Results -p32_curtOn(regi) = 1; - -***display p32_capFacDem, p32_capFacLoB, p32_RLDCcoeff, p32_avCapFac, p32_ResMarg, p32_curtOn, p32_shCHP, p32_grid_factor; - -*** EOF ./modules/32_power/RLDC/datainput.gms diff --git a/modules/32_power/RLDC/declarations.gms b/modules/32_power/RLDC/declarations.gms deleted file mode 100644 index 5b3699993..000000000 --- a/modules/32_power/RLDC/declarations.gms +++ /dev/null @@ -1,78 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/declarations.gms - -parameters - p32_capFacDem(all_regi) "Average demand factor of a power sector [0,1]" - p32_capFacLoB(LoB) "Capacity factor of a load band [0,1]" - p32_RLDCcoeff(all_regi,PolyCoeff,RLDCbands) "Coefficients for the non-separable wind/solar-cross-product polynomial RLDC fit" - p32_avCapFac(ttot,all_regi,all_te) "Average load factor (Nur) of the first 5 grades of a technology" - p32_ResMarg(ttot,all_regi) "Reserve margin as markup on actual peak capacity [0,1]" - p32_curtOn(all_regi) "Control variable for curtailment fitted from the DIMES-Results" - p32_shCHP(ttot,all_regi) "Upper boundary of chp electricity generation" - p32_grid_factor(all_regi) "Multiplicative factor that scales total grid requirements down in comparatively small or homogeneous regions like Japan, Europe or India" - p32_LoBheight0(all_regi,LoB) "Load band heights at 0% VRE share (declared here, on the data input file, because it is only used for the p32_capFacDem definition) [0,1]" -; - -positive variables - v32_scaleCap(ttot,all_regi) "Scale Factor to scale the power capacitites from 'relative to Peak Demand' up to total system level [TW]" - v32_shTh(ttot,all_regi,all_te) "Theoretical share of variable renewable energies [0,1]" - v32_capLoB(ttot,all_regi,all_te,LoB) "Capacity of a technology within one load band relative to peak demand [0,1]" - v32_capER(ttot,all_regi,all_te) "Early retired capacities [0,1]" - v32_curt(ttot,all_regi) "Curtailment of power in the RLDC formulation of the power sector [TWa]" - v32_LoBheight(ttot,all_regi,LoB) "Height of each load band relative to Peak Demand [0,1]" - v32_overProdCF(ttot,all_regi,all_te) "Overproduction CF from dispatchable renewable energies (csp and hydro) [0,1]" - v32_CurtModelminusFit(ttot,all_regi) "Difference between model curtailment and fitted curtailment" - v32_LoBheightCum(ttot,all_regi,LoB) "Cumulative height of each load band relative to Peak Demand [0,1]" - v32_peakCap(ttot,all_regi) "Peak capacity after RLDC [0,1]" - v32_H2cof_PVsh(ttot,all_regi) "Amount of cofiring of gas/H2 to CSP needed due to correlation with PV" - v32_H2cof_Lob4(ttot,all_regi) "Amount of cofiring of gas/H2 to CSP needed due to use of CSP in LoB 4, which has a high CF" - v32_H2cof_Lob3(ttot,all_regi) "Amount of cofiring of gas/H2 to CSP needed due to use of CSP in LoB 3, which has a high CF" - v32_H2cof_CSPsh(ttot,all_regi) "Amount of cofiring of gas/H2 to CSP needed due to self-correlation of CSP" - v32_sqrtCurt(ttot,all_regi) "Helper variable: share of the year for which curtailment is higher than 1/3 of maximum curtailment - this is the amount that we assume we can use for producing H2. Because we assume a 1-to-3 ratio of time to capacity for curtailment, it is also used to calculate the curtailed capacity" - vm_shSeEl(ttot,all_regi,all_te) "new share of electricity production in % [%]" -; - -variables - v32_curtFit(ttot,all_regi) "Curtailment as fitted from the DIMES-Results" - v32_FullIntegrationSlack(ttot,all_regi) "Slack variable that allows implementation of the 'Full Integration' ADVANCE scenario variation, where we assume no integration challenges for wind and solar, thus no curtailment" - v32_LoBheightCumExact(ttot,all_regi,LoB) "Cumulative height of load bands, calculated from theoretical wind and solar share based on the DIMES fits " -; - -equations - q32_balSe(ttot,all_regi,all_enty) "Balance equation for electricity secondary energy" - q32_usableSe(ttot,all_regi,all_enty) "Calculate usable se before se2se and MP/XP (without storage)" - q32_usableSeTe(ttot,all_regi,entySe,all_te) "Calculate usable se produced by one technology (vm_usableSeTe)" - q32_shTheo(ttot,all_regi,all_te) "Calculate theoretical share of wind and solar in power production" - q32_scaleCapTe(ttot,all_regi,all_te) "Calculate upscaled power capacitites from 'relative to peak demand' up to total system level" - q32_curt(ttot,all_regi) "Calculate total curtailment" - q32_curtFit(ttot,all_regi) "Calculate curtailment from DIMES-fit" - q32_curtFitwCSP(ttot,all_regi) "Calculate curtailment from DIMES-fit, including 0.3 CSP" - q32_LoBheightCumExact(ttot,all_regi,LoB) "Calculate height of load bands from theoretical wind and solar share" - q32_LoBheightCumExactNEW(ttot,all_regi,LoB) "Calculate the model-used height of load bands, which need to have some slack (=g=) compared to the exact calulcation of v32_LoBheightCumExact to keep v32_LoBheightCum > 0" - q32_LoBheightExact(ttot,all_regi,LoB) "Calculate height of load bands from theoretical wind and solar share" - q32_fillLoB(ttot,all_regi,LoB) "Fill Load Bands with power production" - q32_capFac(ttot,all_regi,all_te) "Calculate resulting capacity factor for all power technologies" - q32_capFacTER(ttot,all_regi,all_te) "Make sure that the non-bio renewables observe the limited capacity Factor" - q32_stor_pv(ttot,all_regi) "Calculate the short term storage requirements due to renewables" - q32_peakCap(ttot,all_regi) "Calculate peak capacity after RLDC" - q32_capAdeq(ttot,all_regi) "Make sure dispatchable capacities > peak capacity" - q32_H2cofiring(ttot,all_regi) "Calculate co-firing needs" - q32_H2cof_PVsh(ttot,all_regi) "Cofiring CSP due to correlation with PV" - q32_H2cof_LoB4(ttot,all_regi) "Cofiring CSP due to use in LoB 4" - q32_H2cof_LoB3(ttot,all_regi) "Cofiring CSP due to use in LoB 3" - q32_H2cof_CSPsh(ttot,all_regi) "Cofiring CSP due to self-correlation with CSP" - q32_curtCapH2(ttot,all_regi) "Calculate the H2 capacity from curtailed electricity" - q32_curtProdH2(ttot,all_regi) "Calculate the H2 production from curtailed electricity" - q32_sqrtCurt(ttot,all_regi) "Calculate helper variable: share of the year for which curtailment is higher than 1/3 of maximum curtailment" - q32_hydroROR(ttot,all_regi) "Represent Run-Of-River Hydro by requiring that 20% of produced hydro electricity comes from baseload" - q32_limitCapTeChp(ttot,all_regi) "Capacitiy constraint for chp electricity generation" - q32_limitCapTeGrid(ttot,all_regi) "Calculate the additional grid capacity required by VRE" - q32_shSeEl(ttot,all_regi,all_te) "calculate share of electricity production of a technology (vm_shSeEl)" -; - -*** EOF ./modules/32_power/RLDC/declarations.gms diff --git a/modules/32_power/RLDC/equations.gms b/modules/32_power/RLDC/equations.gms deleted file mode 100644 index 428c83760..000000000 --- a/modules/32_power/RLDC/equations.gms +++ /dev/null @@ -1,343 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/equations.gms - -*' @equations - -***--------------------------------------------------------------------------- -*' Balance equation for electricity secondary energy type: -***--------------------------------------------------------------------------- -q32_balSe(t,regi,enty2)$(sameas(enty2,"seel")).. - v32_scaleCap(t,regi) * p32_capFacDem(regi) - + sum(pc2te(enty,entySe(enty3),te,enty2), - pm_prodCouple(regi,enty,enty3,te,enty2) * vm_prodSe(t,regi,enty,enty3,te) ) - + sum(pc2te(enty4,entyFe(enty5),te,enty2), - pm_prodCouple(regi,enty4,enty5,te,enty2) * vm_prodFe(t,regi,enty4,enty5,te) ) - + sum(pc2te(enty,enty3,te,enty2), - sum(teCCS2rlf(te,rlf), - pm_prodCouple(regi,enty,enty3,te,enty2) * vm_co2CCS(t,regi,enty,enty3,te,rlf) ) ) - + vm_Mport(t,regi,enty2) - =e= - sum(se2fe(enty2,enty3,te), vm_demSe(t,regi,enty2,enty3,te) ) - + sum(se2se(enty2,enty3,te), vm_demSe(t,regi,enty2,enty3,te) ) - + sum(pe2rlf(enty3,rlf2), (pm_fuExtrOwnCons(regi, enty2, enty3) * vm_fuExtr(t,regi,enty3,rlf2))$(pm_fuExtrOwnCons(regi, enty2, enty3) gt 0))$(t.val > 2005) !! do not use in 2005 because this demand is not contained in 05_initialCap - + vm_Xport(t,regi,enty2) - ; - -q32_usableSe(t,regi,entySe)$(sameas(entySe,"seel")).. - vm_usableSe(t,regi,entySe) - =e= - sum(pe2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(se2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(pc2te(entyPe,entySe(enty3),te,entySe)$(pm_prodCouple(regi,entyPe,enty3,te,entySe) gt 0), - pm_prodCouple(regi,entyPe,enty3,te,entySe)*vm_prodSe(t,regi,entyPe,enty3,te) ) -; - -q32_usableSeTe(t,regi,entySe,te)$(sameas(entySe,"seel") AND teVRE(te)).. - vm_usableSeTe(t,regi,entySe,te) - =e= - sum(pe2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(se2se(enty,entySe,te), vm_prodSe(t,regi,enty,entySe,te) ) - + sum(pc2te(enty,entySe(enty3),te,entySe)$(pm_prodCouple(regi,enty,enty3,te,entySe) gt 0), - pm_prodCouple(regi,enty,enty3,te,entySe) * vm_prodSe(t,regi,enty,enty3,te) ) -; - -***--------------------------------------------------------------------------- -*' VRE Shares - theoretical VRE shares: scale the total VRE production down to "RLDC level", then compare it to the size of the RLDC at 0% -***--------------------------------------------------------------------------- -q32_shTheo(t,regi,teVRE).. - v32_shTh(t,regi,teVRE) - =e= - sum(pe2se(entyPe,"seel",teVRE), vm_prodSe(t,regi,entyPe,"seel",teVRE) ) - / ( - v32_scaleCap(t,regi) * p32_capFacDem(regi) - + sum(pc2te(enty,entySe(enty3),te,enty2), - pm_prodCouple(regi,enty,enty3,te,enty2) * vm_prodSe(t,regi,enty,enty3,te) ) - + sum(pc2te(enty4,entyFe(enty5),te,enty2), - pm_prodCouple(regi,enty4,enty5,te,enty2) * vm_prodFe(t,regi,enty4,enty5,te) ) - + sum(pc2te(enty,enty3,te,enty2), - sum(teCCS2rlf(te,rlf), - pm_prodCouple(regi,enty,enty3,te,enty2) * vm_co2CCS(t,regi,enty,enty3,te,rlf) ) ) - ) -; - -***--------------------------------------------------------------------------- -*' Transform the RLDC normalized capacities (0-1) to real world magnitudes -***--------------------------------------------------------------------------- -q32_scaleCapTe(t,regi,te)$( (t.val > 2000) AND teRLDCDisp(te) ).. !! scale the capacities of all technologies explicitly represented in the RLDCs - sum(teSe2rlf(te,rlf), vm_cap(t,regi,te,rlf) ) - =e= - v32_scaleCap(t,regi) * ( sum(LoB, v32_capLoB(t,regi,te,LoB) ) + v32_capER(t,regi,te) ) -; - -***--------------------------------------------------------------------------- -*' Curtailment -***--------------------------------------------------------------------------- -q32_curt(t,regi).. - v32_curt(t,regi) - =e= - sum(pe2se(entyPe,"seel",teVRE), vm_prodSe(t,regi,entyPe,"seel",teVRE) ) !! total theoretical VRE production - - v32_scaleCap(t,regi) * ( p32_capFacDem(regi) - sum(LoB, p32_capFacLoB(LoB) * v32_LoBheight(t,regi,LoB) ) ) !! minus the actually used VRE production, namely the difference between a system without and a system with VRE - + v32_overProdCF(t,regi,"csp") * vm_cap(t,regi,"csp","1") !! add the unused CSP production that is not reflected in seprod -; - -q32_curtFit(t,regi).. !! calculate curtailment as fitted from the DIMES-Results - v32_curtFit(t,regi) !! v32_curtFit can go below 0 - =e= - p32_curtOn(regi) - * ( - p32_RLDCcoeff(regi,"p00","curtShVRE") - + p32_RLDCcoeff(regi,"p10","curtShVRE") * v32_shTh(t,regi,"wind")$teVRE("wind") - + p32_RLDCcoeff(regi,"p01","curtShVRE") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p20","curtShVRE") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 - + p32_RLDCcoeff(regi,"p11","curtShVRE") * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p02","curtShVRE") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p30","curtShVRE") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 3 - + p32_RLDCcoeff(regi,"p21","curtShVRE") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p12","curtShVRE") * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p03","curtShVRE") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 3 - ) -; - -q32_curtFitwCSP(t,regi).. - v32_curt(t,regi) - =e= - ( v32_curtFit(t,regi) + 0.02 ) * sum(pe2se(entyPe,"seel",teVRE), vm_prodSe(t,regi,entyPe,"seel",teVRE) ) !! add 2% of VRE prod. ot curtailment to represent grid losses - comes from the comparison with REMIX - + v32_overProdCF(t,regi,"csp") * vm_cap(t,regi,"csp","1") - + v32_CurtModelminusFit(t,regi) * sum(pe2se(entyPe,"seel",teVRE), vm_prodSe(t,regi,entyPe,"seel",teVRE) ) !! this is a positive slack variable that shows how much curtailment due to discretization of RLDC boxes is larger than fitted curtailment -> to move to ex-post -$if %cm_Full_Integration% == "on" + v32_FullIntegrationSlack(t,regi) -; - -***--------------------------------------------------------------------------- -*' Load Band -***--------------------------------------------------------------------------- -q32_LoBheightCumExact(t,regi,LoB).. - v32_LoBheightCumExact(t,regi,LoB) - =e= - p32_RLDCcoeff(regi,"p00",LoB) - + p32_RLDCcoeff(regi,"p10",LoB) * v32_shTh(t,regi,"wind")$teVRE("wind") - + p32_RLDCcoeff(regi,"p01",LoB) * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p20",LoB) * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 - + p32_RLDCcoeff(regi,"p11",LoB) * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p02",LoB) * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p30",LoB) * v32_shTh(t,regi,"wind")$teVRE("wind") ** 3 - + p32_RLDCcoeff(regi,"p21",LoB) * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p12",LoB) * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p03",LoB) * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 3 -; - -q32_LoBheightCumExactNEW(t,regi,LoB).. !! introduce slack so that v32_LoBheightCum stay > 0 - v32_LoBheightCum(t,regi,LoB) - =g= - v32_LoBheightCumExact(t,regi,LoB) -; - -q32_LoBheightExact(t,regi,LoB).. !! individual load band height - the difference between the cumulated heights - v32_LoBheight(t,regi,LoB) - =g= - ( v32_LoBheightCum(t,regi,LoB) - v32_LoBheightCum(t,regi,LoB+1)$(LoB.val < card(LoB)) ) - * ( 1$(LoB.val < card(LoB)) + ( 1 / p32_capFacLoB(LoB) )$(LoB.val = card(LoB)) ) !! upscale the height of the base-load band to represent the fact that the fit was done with 8760 hours, while no plant runs longer than 7500 hours (CF = 0.86) -; - -q32_fillLoB(t,regi,LoB)$(t.val > 2005).. - sum(teRLDCDisp, v32_capLoB(t,regi,teRLDCDisp,LoB) ) - =e= - v32_LoBheight(t,regi,LoB) -; - -***--------------------------------------------------------------------------- -*' Capacity factor for dispatchable power plants -***--------------------------------------------------------------------------- -q32_capFac(t,regi,te)$( teRLDCDisp(te) AND (t.val > 2000) ).. - vm_capFac(t,regi,te) - =e= - ( sum(LoB, - ( p32_capFacLoB(LoB)$( (LoB.val <> 4) OR NOT sameas(te,"csp") ) - + (4/3 * p32_avCapFac(t,regi,"csp"))$( (LoB.val eq 4) AND sameas(te,"csp") ) !! 4/3 is a factor for the upscaling from SM3/12h to SM4/16h storage - ) - * v32_capLoB(t,regi,te,LoB) - ) - + v32_capER(t,regi,te) * 0.01 !! the early retired capacities (v32_capER) are weighted with 1% to represent that they run at least 100h per year - ) - / (sum(LoB, v32_capLoB(t,regi,te,LoB) ) + v32_capER(t,regi,te) + 1e-9) -; - -q32_capFacTER(t,regi,te)$( teReNoBio(te) AND teRLDCDisp(te) AND t.val > 2000).. !! make sure that for dispatchable renewable plants, the average nur is larger than the resulting capFac - sum(teRe2rlfDetail(te,rlf), - pm_dataren(regi,"nur",rlf,te) * vm_capDistr(t,regi,te,rlf) ) - / ( vm_cap(t,regi,te,"1") + 1e-10 ) + 3e-5 !! the 1e-5 allows for slightly larger capacity factors, but does not have a large influence, and prevents some infeasibilities - =g= - vm_capFac(t,regi,te) - + v32_overProdCF(t,regi,te) -; - -***--------------------------------------------------------------------------- -*' Short Term Storage Requirements (from RLDC Fit) -***--------------------------------------------------------------------------- -q32_stor_pv(t,regi)$(t.val > 2010).. - vm_cap(t,regi,"storspv","1") - =g= - v32_scaleCap(t,regi) * - ( - p32_RLDCcoeff(regi,"p00","STScost") - + p32_RLDCcoeff(regi,"p10","STScost") * v32_shTh(t,regi,"wind")$teVRE("wind") - + p32_RLDCcoeff(regi,"p01","STScost") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p20","STScost") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 - + p32_RLDCcoeff(regi,"p11","STScost") * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p02","STScost") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p30","STScost") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 3 - + p32_RLDCcoeff(regi,"p21","STScost") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p12","STScost") * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p03","STScost") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 3 - ) -; - -***--------------------------------------------------------------------------- -*' Peak capacity equations -***--------------------------------------------------------------------------- - -q32_peakCap(t,regi).. - v32_peakCap(t,regi) - =e= - p32_RLDCcoeff(regi,"p00","peak") - + p32_RLDCcoeff(regi,"p10","peak") * v32_shTh(t,regi,"wind")$teVRE("wind") - + p32_RLDCcoeff(regi,"p01","peak") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p20","peak") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 - + p32_RLDCcoeff(regi,"p11","peak") * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p02","peak") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p30","peak") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 3 - + p32_RLDCcoeff(regi,"p21","peak") * v32_shTh(t,regi,"wind")$teVRE("wind") ** 2 * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) - + p32_RLDCcoeff(regi,"p12","peak") * v32_shTh(t,regi,"wind")$teVRE("wind") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 2 - + p32_RLDCcoeff(regi,"p03","peak") * ( v32_shTh(t,regi,"spv")$teVRE("spv") + v32_shTh(t,regi,"csp")$teVRE("csp") ) ** 3 -; - -q32_capAdeq(t,regi)$(t.val > 2005).. - sum(teRLDCDisp(te)$(NOT sameas(te,"hydro")), - sum(teSe2rlf(te,rlf), vm_cap(t,regi,te,rlf) ) - ) - + 0.8 * vm_cap(t,regi,"hydro","1") !! to represent that it is not fully dispatchable, hydro counts only with 80% of its installed capacity towards peak capacity - =g= - v32_scaleCap(t,regi) * ( v32_peakCap(t,regi) + p32_ResMarg(t,regi) ) -; - -***--------------------------------------------------------------------------- -*' CSP - including co-firing -***--------------------------------------------------------------------------- -q32_H2cofiring(t,regi)$(t.val > 2010).. - vm_demSeOth(t,regi,"seh2","csp") !! cofiring of h2 to csp - + vm_demSeOth(t,regi,"segabio","csp") !! cofiring of gas to csp - + vm_demSeOth(t,regi,"segafos","csp") -$if %cm_Full_Integration% == "on" + 1e6 - =g= - v32_H2cof_PVsh(t,regi) - + v32_H2cof_Lob4(t,regi) - + v32_H2cof_Lob3(t,regi) - + v32_H2cof_CSPsh(t,regi) -; - -q32_H2cof_LoB3(t,regi)$(t.val > 2005).. - v32_H2cof_Lob3(t,regi) - =g= - 1/0.4 !! 1/0.4 is the efficiency of the H2 turbine - to convert from produced electricity to used H2 - * v32_scaleCap(t,regi) !! all the later numbers are relative to peak, and need to be rescaled to full system size - * v32_capLoB(t,regi,"csp","3") !! each unit of csp in baseload needs H2 cofiring - * ( p32_capFacLoB("3") - p32_avCapFac(t,regi,"csp") ) !! the co-firing is only needed for the residual of baseload after avCapFac. CapLob * DiffCapfac = produced electricity -; - -q32_H2cof_LoB4(t,regi)$(t.val > 2005).. - v32_H2cof_Lob4(t,regi) - =g= - 1/0.4 !! 1/0.4 is the efficiency of the H2 turbine - to convert from produced electricity to used H2 - * v32_scaleCap(t,regi) - * v32_capLoB(t,regi,"csp","4") !! each unit of csp in baseload needs H2 cofiring - * ( p32_capFacLoB("4") - 4/3 * p32_avCapFac(t,regi,"csp") ) !! 4/3 is the factor for the upscaling from SM3/12h to SM4/16h storage -; - -q32_H2cof_PVsh(t,regi)$(t.val > 2005).. !! more CSP cofiring if lots of PV is used (correlation between PV and CSP) - v32_H2cof_PVsh(t,regi) - =e= - 1/0.4 !! 1/0.4 is the efficiency of the H2 turbine - to convert from produced electricity to used H2 - * v32_scaleCap(t,regi) - * 0.5 * vm_cap(t,regi,"csp","1") * (0.65 - p32_avCapFac(t,regi,"csp") ) * v32_shTh(t,regi,"spv") -; - -q32_H2cof_CSPsh(t,regi)$(t.val > 2005).. !! more CSP cofiring if lots of CSP is used (self-correlation of CSP) - v32_H2cof_CSPsh(t,regi) - =e= - 1/0.4 !! 1/0.4 is the efficiency of the H2 turbine - to convert from produced electricity to used H2 - * v32_scaleCap(t,regi) - * vm_cap(t,regi,"csp","1") * (0.65 - p32_avCapFac(t,regi,"csp") ) * v32_shTh(t,regi,"csp") -; - -***--------------------------------------------------------------------------- -*' produce H2 from curtailed electricity, using a curtailment-dependent load factor -***--------------------------------------------------------------------------- -q32_curtCapH2(t,regi)$(t.val > 2005).. - vm_cap(t,regi,"h2curt","1") / v32_scaleCap(t,regi) !! 0.5 for area of a triangle - =l= - v32_sqrtCurt(t,regi) !! 0.5 as only half of the curtailment can be used -; - -q32_curtProdH2(t,regi)$(t.val > 2005).. - pm_eta_conv(t,regi,"h2curt") * vm_cap(t,regi,"h2curt","1") * 2/3 * v32_sqrtCurt(t,regi) - =g= - vm_prodSeOth(t,regi,"seh2","h2curt") -; - -q32_sqrtCurt(t,regi)$(t.val > 2005).. - v32_sqrtCurt(t,regi) - =e= - sqrt( 2/3 * ( ( v32_curt(t,regi) ) / v32_scaleCap(t,regi) / p32_capFacDem(regi) + 1e-6 ) ) -; -!! Assuming curtailment has a triangle shape, 1x wide, 3x high => 3x^2 would be the area of the rectangle. The area of the triangle = 1/2 times this. -!! Area = 3/2 x^2 = curt. ==> x = 2/3 curt ^ 0.5 - -***--------------------------------------------------------------------------- -*' special constraints on hydropower to prevent hydro being completely flexibily only used for peaking -***--------------------------------------------------------------------------- -q32_hydroROR(t,regi)$(t.val > 2005).. !! require that at least 20% of the hydro are in baseload (counting as run-of-river). This may lead to Baseload being higher than required by the RLDC, and therefore (realistic) curtailment - p32_capFacLoB("4") * v32_capLoB(t,regi,"hydro","4") - =g= - 0.2 * sum(LoB, p32_capFacLoB(LoB) * v32_capLoB(t,regi,"hydro",LoB) ) -; - -***--------------------------------------------------------------------------- -*' Definition of capacity constraints for CHP technologies: -***--------------------------------------------------------------------------- -q32_limitCapTeChp(t,regi).. - sum(pe2se(enty,"seel",teChp(te)), vm_prodSe(t,regi,enty,"seel",te) ) - =l= - p32_shCHP(t,regi) - * sum(pe2se(enty,"seel",te), vm_prodSe(t,regi,enty,"seel",te) ); - -***--------------------------------------------------------------------------- -*' Calculation of necessary grid installations for centralized renewables: -***--------------------------------------------------------------------------- -q32_limitCapTeGrid(t,regi)$( t.val ge 2015 ) .. - vm_cap(t,regi,"gridwind",'1') !! Technology is now parameterized to yield marginal costs of ~3.5$/MWh VRE electricity - / p32_grid_factor(regi) !! It is assumed that large regions require higher grid investment - =g= - vm_prodSe(t,regi,"pesol","seel","spv") - + vm_prodSe(t,regi,"pesol","seel","csp") - + 1.5 * vm_prodSe(t,regi,"pewin","seel","wind") !! wind has larger variations accross space, so adding grid is more important for wind (result of REMIX runs for ADVANCE project) -$IFTHEN.WindOff %cm_wind_offshore% == "1" - + 1.5 * vm_prodSe(t,regi,"pewin","seel","windoff") -$ENDIF.WindOff -; - -***--------------------------------------------------------------------------- -*' Calculation of share of electricity production of a technology: -***--------------------------------------------------------------------------- -q32_shSeEl(t,regi,teVRE).. - vm_shSeEl(t,regi,teVRE) / 100 * vm_usableSe(t,regi,"seel") - =e= - vm_usableSeTe(t,regi,"seel",teVRE) -; - -*' @stop - -*** EOF ./modules/32_power/RLDC/equations.gms diff --git a/modules/32_power/RLDC/input/files b/modules/32_power/RLDC/input/files deleted file mode 100644 index 3af7a0dc8..000000000 --- a/modules/32_power/RLDC/input/files +++ /dev/null @@ -1,5 +0,0 @@ -f32_RLDC_Coeff_LoB.cs3r -f32_RLDC_Coeff_Peak.cs3r -f32_shCHP.cs4r -p32_grid_factor.cs4r - diff --git a/modules/32_power/RLDC/not_used.txt b/modules/32_power/RLDC/not_used.txt deleted file mode 100644 index ad39b9f13..000000000 --- a/modules/32_power/RLDC/not_used.txt +++ /dev/null @@ -1,13 +0,0 @@ -# | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -# | authors, and contributors see CITATION.cff file. This file is part -# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -# | AGPL-3.0, you are granted additional permissions described in the -# | REMIND License Exception, version 1.0 (see LICENSE file). -# | Contact: remind@pik-potsdam.de -name,type,reason -pm_IO_input,input,questionnaire -vm_flexAdj,input,questionnaire -cm_VRE_supply_assumptions,input,questionnaire -cm_flex_tax,input,questionnaire -cm_FlexTaxFeedback,input,questionnaire -vm_shDemSeel,input,only used in IntC realization diff --git a/modules/32_power/RLDC/postsolve.gms b/modules/32_power/RLDC/postsolve.gms deleted file mode 100644 index 5833c3662..000000000 --- a/modules/32_power/RLDC/postsolve.gms +++ /dev/null @@ -1,14 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/postsolve.gms - -*** calculation of SE electricity price (useful for internal use and reporting purposes) -pm_SEPrice(ttot,regi,entySe)$(abs (qm_budget.m(ttot,regi)) gt sm_eps AND sameas(entySe,"seel")) = - q32_balSe.m(ttot,regi,entySe) / qm_budget.m(ttot,regi); - -*** EOF ./modules/32_power/RLDC/postsolve.gms - diff --git a/modules/32_power/RLDC/preloop.gms b/modules/32_power/RLDC/preloop.gms deleted file mode 100644 index a6610c45b..000000000 --- a/modules/32_power/RLDC/preloop.gms +++ /dev/null @@ -1,15 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de - -*** SOF ./modules/32_power/RLDC/preloop.gms - -*** read marginal of seel balance equation -Execute_Loadpoint 'input' q32_balSe.m = q32_balSe.m; - - - -*** EOF ./modules/32_power/RLDC/preloop.gms diff --git a/modules/32_power/RLDC/presolve.gms b/modules/32_power/RLDC/presolve.gms deleted file mode 100644 index b4791358a..000000000 --- a/modules/32_power/RLDC/presolve.gms +++ /dev/null @@ -1,11 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/presolve.gms - - - -*** EOF ./modules/32_power/RLDC/presolve.gms diff --git a/modules/32_power/RLDC/realization.gms b/modules/32_power/RLDC/realization.gms deleted file mode 100644 index 788739c72..000000000 --- a/modules/32_power/RLDC/realization.gms +++ /dev/null @@ -1,55 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de - -*** SOF ./modules/32_power/RLDC/realization.gms - -*' @description -*' -*'The `RLDC` realization (Residual Load Duration Curve) distinguish different operation electricity supply decisions under four distinct load bands, plus additional peak capacity requirements. -*' -*'This module determine power system supply specific technology behavior, which summs up to the general core capacity equations to define the power sector operation and investment decisions. -*' -*'Contrary to other secondary energies in REMIND, this requires to move the electricity secondary energy balance (supply = demand) from the core to the module code. -*' -*' -*'The residual load duration curve is obtained after discounting intermittent renewables generation (solar and wind) from the total demand. -*' -*'An exogenous unit commitment model (DIMES) is used to estimate a third degree fitting curve for each load band representing the intermittent renewables generation contribution at different renewable penetration shares in the system. -*' -*'Curtailament is defined using the same process - a per load band third degree fitting curve that determines the curtailment based on the renewables share. -*' -*'Dispatchable power generation technologies have their capacity factor endogenously determined by the use in the distinct load bands. -*' -*'Short term storage is dependable of wind and solar penetration shares and estimated exogenously to a third degree fitting curve. -*' -*'A reserve margin capacity is required to be provided by dispatchable technologies only. The reserve margin size is determined by the peak capacity that is also estimated exogenously for different levels of renewables penetration in the system. -*' -*'CSP co-firing with H2 or other gases is included. Self-correlation and PV correlation inside each load bands are considered. -*' -*'Hydrogen can be used to reduce renewable power curtailment and provide flexibility to the system future generation. -*' -*'Hydropower load band flexibility is limited due to run-of-river power plants and water use regulation constraints. -*' -*'Combined heat and power technologies flexibility is limited to technology and spatial observed data. -*' -*'Additional grid capacities are calculated for high intermittent renewable capacity (solar and wind) and regional spatial differences. -*' -*' @authors Robert Pietzcker, Falko Ueckerdt, Renato Rodrigues - -*####################### R SECTION START (PHASES) ############################## -$Ifi "%phase%" == "sets" $include "./modules/32_power/RLDC/sets.gms" -$Ifi "%phase%" == "declarations" $include "./modules/32_power/RLDC/declarations.gms" -$Ifi "%phase%" == "datainput" $include "./modules/32_power/RLDC/datainput.gms" -$Ifi "%phase%" == "equations" $include "./modules/32_power/RLDC/equations.gms" -$Ifi "%phase%" == "preloop" $include "./modules/32_power/RLDC/preloop.gms" -$Ifi "%phase%" == "bounds" $include "./modules/32_power/RLDC/bounds.gms" -$Ifi "%phase%" == "presolve" $include "./modules/32_power/RLDC/presolve.gms" -$Ifi "%phase%" == "postsolve" $include "./modules/32_power/RLDC/postsolve.gms" -*######################## R SECTION END (PHASES) ############################### - -*** EOF ./modules/32_power/RLDC/realization.gms - diff --git a/modules/32_power/RLDC/sets.gms b/modules/32_power/RLDC/sets.gms deleted file mode 100644 index ed3a69439..000000000 --- a/modules/32_power/RLDC/sets.gms +++ /dev/null @@ -1,127 +0,0 @@ -*** | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) -*** | authors, and contributors see CITATION.cff file. This file is part -*** | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of -*** | AGPL-3.0, you are granted additional permissions described in the -*** | REMIND License Exception, version 1.0 (see LICENSE file). -*** | Contact: remind@pik-potsdam.de -*** SOF ./modules/32_power/RLDC/sets.gms - -***----------------------------------------------------------- -*** module specific sets -***------------------------------------------------------------ -SETS - PolyCoeff "Which coefficients exist for the RLDC formulation" - / - p00 - p10 "wind ^1, solar ^0" - p01 "wind ^0, solar ^1" - p20 - p11 - p02 - p30 - p21 - p12 - p03 - / - - RLDCbands "???" - / - 1*4, - curt - peak - curtShVRE - shtStor - STScost - STSRes2Cap - / - - LoB(RLDCbands) "Electricity load band" - /1 * 4/ -; - -teVRE(all_te) = no; - - -*RLDC dispatchable technologies -teRLDCDisp("ngcc") = yes; -teRLDCDisp("ngccc") = yes; -teRLDCDisp("ngt") = yes; -teRLDCDisp("gaschp") = yes; -teRLDCDisp("dot") = yes; -teRLDCDisp("igcc") = yes; -teRLDCDisp("igccc") = yes; -teRLDCDisp("pc") = yes; -teRLDCDisp("coalchp") = yes; -teRLDCDisp("tnrs") = yes; -teRLDCDisp("fnrs") = yes; -teRLDCDisp("biochp") = yes; -teRLDCDisp("bioigcc") = yes; -teRLDCDisp("bioigccc") = yes; -teRLDCDisp("geohdr") = yes; -teRLDCDisp("hydro") = yes; -teRLDCDisp("h2turb") = yes; -teRLDCDisp("csp") = yes; - - -*Sets used on data input assignments -SETS - PeakDep(RLDCbands) "RLDC elements that scale with peak (not curtailment, storage)" - / - 1 * 4 - peak - / - -$ontext - UsedGrades2070(all_regi,all_te,rlf) - / - ROW.csp.(1*2) - EUR.csp.(1*4) - CHN.csp.(1*3) - IND.csp.(1*6) - JPN.csp.(1*6) - RUS.csp.(1*2) - USA.csp.(1*4) - OAS.csp.(1*5) - MEA.csp.(1*2) - LAM.csp.(1*2) - AFR.csp.(1*3) - ROW.hydro.(1*4) - EUR.hydro.(1*4) - CHN.hydro.(1*4) - IND.hydro.(1*4) - JPN.hydro.(1*4) - RUS.hydro.(1*4) - USA.hydro.(1*4) - OAS.hydro.(1*4) - MEA.hydro.(1*4) - LAM.hydro.(1*4) - AFR.hydro.(1*4) - / -$offtext - - teNotLoB1(all_te) "Technologies that can't go into the first LoB as they are difficult to cycle continuously & quickly" - / - tnrs - pc - ngcc - ngccc - igccc - igcc - bioigcc - bioigccc - coalchp - gaschp - biochp - / - - teNotBase(all_te) "Technologies that can't go into the last LoB (baseload) as they can't run for 7500 FLh" - / -*** hydro -*** csp -*** coalchp -*** gaschp -*** biochp - / -; - -*** EOF ./modules/32_power/RLDC/sets.gms diff --git a/modules/32_power/module.gms b/modules/32_power/module.gms index 93972e180..31d19f4ef 100644 --- a/modules/32_power/module.gms +++ b/modules/32_power/module.gms @@ -10,18 +10,16 @@ *' *' @description The 32_power module determines the operation production decisions for the electricity supply. *' -*' *' The `IntC` realization (Integrated Costs) assumes a single electricity market balance. *' -*' The `RLDC` realization (Residual Load Duration Curve) distinguishes different operation electricity supply decisions under four distinct load bands, plus additional peak capacity requirements. -*' -*' The `DTcoup` realization (DIETER-coupled) soft-couples REMIND to DIETER (an hourly power sector model), and is currently only at conceptual stage and not merged (it is only a copy of IntC) *' *' @authors Robert Pietzcker, Falko Ueckerdt, Renato Rodrigues, Chen Chris Gong +*** Other realizations were removed in July 2024: +*** - The `RLDC` realization (Residual Load Duration Curve) distinguishes different operation electricity supply decisions under four distinct load bands, plus additional peak capacity requirements. +*** - The `DTcoup` realization (DIETER-coupled) soft-couples REMIND to DIETER (an hourly power sector model), and is currently only at conceptual stage and not merged (it is only a copy of IntC) + *###################### R SECTION START (MODULETYPES) ########################## -$Ifi "%power%" == "DTcoup" $include "./modules/32_power/DTcoup/realization.gms" $Ifi "%power%" == "IntC" $include "./modules/32_power/IntC/realization.gms" -$Ifi "%power%" == "RLDC" $include "./modules/32_power/RLDC/realization.gms" *###################### R SECTION END (MODULETYPES) ############################ *** EOF ./modules/32_power/module.gms diff --git a/modules/36_buildings/simple/datainput.gms b/modules/36_buildings/simple/datainput.gms index 7608e568a..a092646ac 100644 --- a/modules/36_buildings/simple/datainput.gms +++ b/modules/36_buildings/simple/datainput.gms @@ -57,6 +57,16 @@ $offdelim ; p36_uedemand_build(ttot,regi,in) = f36_uedemand_build(ttot,regi,"%cm_demScen%","%cm_rcp_scen_build%",in); +*** Scale UE demand and floor space in the building sector +$ifthen.scaleDemand not "%cm_scaleDemand%" == "off" + loop((tall,tall2,regi) $ pm_scaleDemand(tall,tall2,regi), +*FL* rescaled demand = normal demand * [ scaling factor + (1-scaling factor) * remaining phase-in, between zero and one ] + p36_uedemand_build(t,regi,in) = p36_uedemand_build(t,regi,in) * ( pm_scaleDemand(tall,tall2,regi) + (1-pm_scaleDemand(tall,tall2,regi)) * min(1, max(0, tall2.val-t.val) / (tall2.val-tall.val)) ); +*RH* We assume that the reduction in final energy demand is only partially driven by floor space reduction (exponent 0.3). + p36_floorspace(t,regi) = p36_floorspace(t,regi) * ( pm_scaleDemand(tall,tall2,regi)**0.3 + (1-pm_scaleDemand(tall,tall2,regi)**0.3) * min(1, max(0, tall2.val-t.val) / (tall2.val-tall.val)) ); + ); +$endif.scaleDemand + *** scale default elasticity of substitution on enb level $IFTHEN.cm_enb not "%cm_enb%" == "off" diff --git a/modules/45_carbonprice/diffExp2Lin/datainput.gms b/modules/45_carbonprice/diffExp2Lin/datainput.gms index 668f195f9..1405c4445 100644 --- a/modules/45_carbonprice/diffExp2Lin/datainput.gms +++ b/modules/45_carbonprice/diffExp2Lin/datainput.gms @@ -21,51 +21,53 @@ *** Step 1: Define regional multiplicative factors between regional CO2 price and CO2 price of the developed countries *** Warning regarding code changes: This first step also appears in diffLin2Lin and should be changed simultaneously. -*** Step 1.1: Define regional multiplicative CO2 price factors for 2025 +*** Step 1.1: Define initial regional multiplicative CO2 price factors *** based on GDP per capita (in 1e3 $ PPP 2005) in 2015 (benchmark year kept at 2015 since 2020 not suitable) p45_gdppcap2015_PPP(regi) = pm_gdp("2015",regi)/pm_shPPPMER(regi) / pm_pop("2015",regi); *** Selection of differentiation scheme via cm_co2_tax_spread if(cm_co2_tax_spread eq 1, -p45_phasein_2025ratio(regi) = 1; !! all regions +p45_phasein_ratio(regi) = 1; !! all regions ); if(cm_co2_tax_spread eq 10, -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.1; !! SSA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.2; !! IND -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.3; !! OAS -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.5; !! CHA, LAM, MEA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.7; !! REF -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.1; !! SSA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.2; !! IND +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.3; !! OAS +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.5; !! CHA, LAM, MEA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.7; !! REF +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU ); if(cm_co2_tax_spread eq 20, -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.05; !! SSA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.1; !! IND -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.2; !! OAS -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.4; !! CHA, LAM, MEA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.6; !! REF -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.05; !! SSA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.1; !! IND +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.2; !! OAS +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.4; !! CHA, LAM, MEA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.6; !! REF +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU ); -*** Step 1.2: Create regional multiplicative CO2 price factors from 2030 onward +*** Step 1.2: Create regional multiplicative CO2 price factors for quadratic convergence between s45_CO2priceRegConvStartYr and cm_CO2priceRegConvEndYr -*** Set regional CO2 price factor equal to p45_phasein_2025ratio until 2025: -p45_regCO2priceFactor(t,regi)$(t.val le 2025) = p45_phasein_2025ratio(regi); -*** Create quadratic phase-in until cm_CO2priceRegConvEndYr: -loop(t$((t.val gt 2025) and (t.val le cm_CO2priceRegConvEndYr)), +*** Set year until which initial ratios of CO2 prices are applied and after which convergence starts to 2030 +s45_CO2priceRegConvStartYr = 2030; +*** Set regional CO2 price factor equal to p45_phasein_ratio until s45_CO2priceRegConvStartYr: +p45_regCO2priceFactor(t,regi)$(t.val le s45_CO2priceRegConvStartYr) = p45_phasein_ratio(regi); +*** Create quadratic phase-in between s45_CO2priceRegConvStartYr and cm_CO2priceRegConvEndYr: +loop(t$((t.val gt s45_CO2priceRegConvStartYr) and (t.val le cm_CO2priceRegConvEndYr)), p45_regCO2priceFactor(t,regi) = min(1, max(0, - p45_phasein_2025ratio(regi) + (1 - p45_phasein_2025ratio(regi)) * Power( (t.val - 2025) / (cm_CO2priceRegConvEndYr - 2025), 2) + p45_phasein_ratio(regi) + (1 - p45_phasein_ratio(regi)) * Power( (t.val - s45_CO2priceRegConvStartYr) / (cm_CO2priceRegConvEndYr - s45_CO2priceRegConvStartYr), 2) ) ); ); *** Set regional CO2 price factor equal to 1 after cm_CO2priceRegConvEndYr: p45_regCO2priceFactor(t,regi)$(t.val gt cm_CO2priceRegConvEndYr) = 1; -display p45_gdppcap2015_PPP, p45_phasein_2025ratio, p45_regCO2priceFactor; +display p45_gdppcap2015_PPP, p45_phasein_ratio, p45_regCO2priceFactor; *** Step 2: Create CO2 price trajectory for developed countries diff --git a/modules/45_carbonprice/diffExp2Lin/declarations.gms b/modules/45_carbonprice/diffExp2Lin/declarations.gms index e9c9e1551..b3e187559 100644 --- a/modules/45_carbonprice/diffExp2Lin/declarations.gms +++ b/modules/45_carbonprice/diffExp2Lin/declarations.gms @@ -18,7 +18,7 @@ ***-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- parameters p45_gdppcap2015_PPP(all_regi) "2015 GDP per capita (k $ PPP 2005)" -p45_phasein_2025ratio(all_regi) "ratio of CO2 price to that of developed region in 2025" +p45_phasein_ratio(all_regi) "inital ratio of CO2 price to that of developed region" p45_regCO2priceFactor(ttot,all_regi) "regional multiplicative factor to the CO2 price of the developed countries" p45_CO2priceTrajDeveloped(ttot) "CO2 price trajectory for developed/rich countries" @@ -26,6 +26,7 @@ p45_CO2priceTrajDeveloped(ttot) "CO2 price trajectory for developed/ scalars s45_co2_tax_startyear "level of CO2 tax in start year converted from $/t CO2eq to T$/GtC" +s45_CO2priceRegConvStartYr "year until which initial ratios of CO2 prices are applied and after which convergence starts" ; *** EOF ./modules/45_carbonprice/diffExp2Lin/declarations.gms diff --git a/modules/45_carbonprice/diffLin2Lin/datainput.gms b/modules/45_carbonprice/diffLin2Lin/datainput.gms index 02f8eb48a..5fe0056b4 100644 --- a/modules/45_carbonprice/diffLin2Lin/datainput.gms +++ b/modules/45_carbonprice/diffLin2Lin/datainput.gms @@ -18,53 +18,55 @@ ***-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- *** Step 1: Define regional multiplicative factors between regional CO2 price and CO2 price of the developed countries -*** Warning regarding code changes: This first step also appears in diffExp2Lin and should be changed simultaneously. +*** Warning regarding code changes: This first step also appears in diffLin2Lin and should be changed simultaneously. -*** Step 1.1: Define regional multiplicative CO2 price factors for 2025 +*** Step 1.1: Define initial regional multiplicative CO2 price factors *** based on GDP per capita (in 1e3 $ PPP 2005) in 2015 (benchmark year kept at 2015 since 2020 not suitable) p45_gdppcap2015_PPP(regi) = pm_gdp("2015",regi)/pm_shPPPMER(regi) / pm_pop("2015",regi); *** Selection of differentiation scheme via cm_co2_tax_spread if(cm_co2_tax_spread eq 1, -p45_phasein_2025ratio(regi) = 1; !! all regions +p45_phasein_ratio(regi) = 1; !! all regions ); if(cm_co2_tax_spread eq 10, -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.1; !! SSA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.2; !! IND -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.3; !! OAS -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.5; !! CHA, LAM, MEA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.7; !! REF -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.1; !! SSA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.2; !! IND +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.3; !! OAS +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.5; !! CHA, LAM, MEA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.7; !! REF +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU ); if(cm_co2_tax_spread eq 20, -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.05; !! SSA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.1; !! IND -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.2; !! OAS -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.4; !! CHA, LAM, MEA -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.6; !! REF -p45_phasein_2025ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) le 3.5) = 0.05; !! SSA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 3.5 and p45_gdppcap2015_PPP(regi) le 5) = 0.1; !! IND +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 5 and p45_gdppcap2015_PPP(regi) le 10) = 0.2; !! OAS +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 10 and p45_gdppcap2015_PPP(regi) le 15) = 0.4; !! CHA, LAM, MEA +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 15 and p45_gdppcap2015_PPP(regi) le 20) = 0.6; !! REF +p45_phasein_ratio(regi)$(p45_gdppcap2015_PPP(regi) gt 20) = 1; !! EUR, JPN, USA, CAZ, NEU ); -*** Step 1.2: Create regional multiplicative CO2 price factors from 2030 onward +*** Step 1.2: Create regional multiplicative CO2 price factors for quadratic convergence between s45_CO2priceRegConvStartYr and cm_CO2priceRegConvEndYr -*** Set regional CO2 price factor equal to p45_phasein_2025ratio until 2025: -p45_regCO2priceFactor(t,regi)$(t.val le 2025) = p45_phasein_2025ratio(regi); -*** Create quadratic phase-in until cm_CO2priceRegConvEndYr: -loop(t$((t.val gt 2025) and (t.val le cm_CO2priceRegConvEndYr)), +*** Set year until which initial ratios of CO2 prices are applied and after which convergence starts to 2030 +s45_CO2priceRegConvStartYr = 2030; +*** Set regional CO2 price factor equal to p45_phasein_ratio until s45_CO2priceRegConvStartYr: +p45_regCO2priceFactor(t,regi)$(t.val le s45_CO2priceRegConvStartYr) = p45_phasein_ratio(regi); +*** Create quadratic phase-in between s45_CO2priceRegConvStartYr and cm_CO2priceRegConvEndYr: +loop(t$((t.val gt s45_CO2priceRegConvStartYr) and (t.val le cm_CO2priceRegConvEndYr)), p45_regCO2priceFactor(t,regi) = min(1, max(0, - p45_phasein_2025ratio(regi) + (1 - p45_phasein_2025ratio(regi)) * Power( (t.val - 2025) / (cm_CO2priceRegConvEndYr - 2025), 2) + p45_phasein_ratio(regi) + (1 - p45_phasein_ratio(regi)) * Power( (t.val - s45_CO2priceRegConvStartYr) / (cm_CO2priceRegConvEndYr - s45_CO2priceRegConvStartYr), 2) ) ); ); *** Set regional CO2 price factor equal to 1 after cm_CO2priceRegConvEndYr: p45_regCO2priceFactor(t,regi)$(t.val gt cm_CO2priceRegConvEndYr) = 1; -display p45_gdppcap2015_PPP, p45_phasein_2025ratio, p45_regCO2priceFactor; +display p45_gdppcap2015_PPP, p45_phasein_ratio, p45_regCO2priceFactor; *** Step 2: Define CO2 price trajectory for developed countries diff --git a/modules/45_carbonprice/diffLin2Lin/declarations.gms b/modules/45_carbonprice/diffLin2Lin/declarations.gms index b7afd516c..5f20c2004 100644 --- a/modules/45_carbonprice/diffLin2Lin/declarations.gms +++ b/modules/45_carbonprice/diffLin2Lin/declarations.gms @@ -19,7 +19,7 @@ parameters p45_gdppcap2015_PPP(all_regi) "2015 GDP per capita (k $ PPP 2005)" -p45_phasein_2025ratio(all_regi) "ratio of CO2 price to that of developed region in 2025" +p45_phasein_ratio(all_regi) "inital ratio of CO2 price to that of developed region" p45_regCO2priceFactor(ttot,all_regi) "regional multiplicative factor to the CO2 price of the developed countries" p45_CO2priceTrajDeveloped(ttot) "CO2 price trajectory for developed/rich countries" @@ -31,6 +31,7 @@ scalars s45_year_co2_tax_hist "year of s45_co2_tax_hist" s45_co2_tax_hist "historical level of CO2 tax converted from $/t CO2eq to T$/GtC" s45_co2_tax_startyear "level of CO2 tax in start year converted from $/t CO2eq to T$/GtC" +s45_CO2priceRegConvStartYr "year until which initial ratios of CO2 prices are applied and after which convergence starts" ; *** EOF ./modules/45_carbonprice/diffLin2Lin/declarations.gms diff --git a/modules/47_regipol/regiCarbonPrice/sets.gms b/modules/47_regipol/regiCarbonPrice/sets.gms index 41cd7eff9..81a39832f 100644 --- a/modules/47_regipol/regiCarbonPrice/sets.gms +++ b/modules/47_regipol/regiCarbonPrice/sets.gms @@ -153,6 +153,8 @@ exogDemScen "exogenuous FE and ES demand scenarios that can be activated b / ariadne_bal ariadne_ensec + ariadne_highDem + ariadne_lowDem / $endif.exogDemScen diff --git a/output.R b/output.R index 512bfef54..87de81adb 100755 --- a/output.R +++ b/output.R @@ -147,7 +147,8 @@ if (! exists("output")) { # Select output directories if not defined by readArgs if (! exists("outputdir")) { modulesNeedingMif <- c("compareScenarios2", "xlsx_IIASA", "policyCosts", "Ariadne_output", - "plot_compare_iterations", "varListHtml", "fixOnRef", "MAGICC7_AR6") + "plot_compare_iterations", "varListHtml", "fixOnRef", "MAGICC7_AR6", + "validateScenarios", "checkClimatePercentiles") needingMif <- any(modulesNeedingMif %in% output) && ! "reporting" %in% output[[1]] if (exists("remind_dir")) { dir_folder <- c(file.path(remind_dir, "output"), remind_dir) @@ -192,7 +193,7 @@ if (comp %in% c("comparison", "export")) { } # choose the slurm options. If you use command line arguments, use slurmConfig=priority or standby - modules_using_slurmConfig <- c("compareScenarios2") + modules_using_slurmConfig <- c("compareScenarios2", "validateScenarios") if (!exists("slurmConfig") && any(modules_using_slurmConfig %in% output)) { slurmConfig <- choose_slurmConfig_output(output = output) } @@ -248,7 +249,7 @@ if (comp %in% c("comparison", "export")) { slurmConfig <- "direct" } - # Execute outputscripts for all choosen folders + # Execute outputscripts for all chosen folders for (outputdir in outputdirs) { if (exists("cfg")) { diff --git a/scripts/input/climate_assessment_run.R b/scripts/input/climate_assessment_run.R index b49a70933..41e261fde 100644 --- a/scripts/input/climate_assessment_run.R +++ b/scripts/input/climate_assessment_run.R @@ -409,9 +409,21 @@ if (archiveClimateAssessmentData) { capture.output(cat(logMsg), file = logFile, append = TRUE) } timeStopArchive <- Sys.time() +logMsg <- paste0(date(), " Done writing GDX files\n") + +############################# CLEAN UP WORKERS FOLDER ########################## +# openscm_runner not remnove up temp dirs. Do this manually since we keep running into file ownership issues +workersFolder <- file.path(climateTempDir, "workers") # replace with your directory path +if (dir.exists(workersFolder)) { + # Check if directory is empty + if (length(list.files(workersFolder)) == 0) { + # Remove directory. Option recursive must be TRUE for some reason, otherwise unlink won't do its job + unlink(workersFolder, recursive = TRUE) + logMsg <- paste0(logMsg, date(), " Removed workers folder '", workersFolder, "'\n") + } +} -logMsg <- paste0( - date(), " Done writing GDX files\n", +logMsg <- paste0(logMsg, date(), " Runtime report: ", paste0("iteration_", timestamp, "\n"), "\tRuntime set_up_script: ", difftime(timeStopSetUpScript, timeStartSetUpScript, units = "secs"), "s\n", diff --git a/scripts/input/climate_assessment_temperatureImpulseResponse.R b/scripts/input/climate_assessment_temperatureImpulseResponse.R index c2e5940e3..2b06efddd 100644 --- a/scripts/input/climate_assessment_temperatureImpulseResponse.R +++ b/scripts/input/climate_assessment_temperatureImpulseResponse.R @@ -321,5 +321,19 @@ writeToGdx <- function(file = "pm_magicc_temperatureImpulseResponse", df) { # write to GDX: writeToGdx("pm_magicc_temperatureImpulseResponse", oupt) -print("...done.") - +logMsg <- paste0(date(), " Wrote results to 'pm_magicc_temperatureImpulseResponse.gdx'\n") + +############################# CLEAN UP WORKERS FOLDER ########################## +# openscm_runner not remnove up temp dirs. Do this manually since we keep running into file ownership issues +workersFolder <- file.path(climateTempDir, "workers") # replace with your directory path +if (dir.exists(workersFolder)) { + # Check if directory is empty + if (length(list.files(workersFolder)) == 0) { + # Remove directory. Option recursive must be TRUE for some reason, otherwise unlink won't do its job + unlink(workersFolder, recursive = TRUE) + logMsg <- paste0(logMsg, date(), " Removed workers folder '", workersFolder, "'\n") + } +} +logMsg <- paste0(logMsg, date(), " climate_assessment_temperatureImpulseResponse.R finished\n") +cat(logMsg) +capture.output(cat(logMsg), file = logFile, append = TRUE) diff --git a/scripts/input/create_input_for_45_carbonprice_exogenous.R b/scripts/input/create_input_for_45_carbonprice_exogenous.R index aaaa69309..30a97ce83 100644 --- a/scripts/input/create_input_for_45_carbonprice_exogenous.R +++ b/scripts/input/create_input_for_45_carbonprice_exogenous.R @@ -42,7 +42,7 @@ create_input_for_45_carbonprice_exogenous<-function(gdx){ cat("*= Exogenous CO2 tax level =*\n", file = p_fpath, append = TRUE) cat("*=============================================================*\n", file = p_fpath, append = TRUE) cat("*= author: dklein@pik-potsdam.de =*\n", file = p_fpath, append = TRUE) - cat(paste("*= date : ", Sys.time(), " =*\n", sep=""), file = p_fpath, append = TRUE) + cat(paste("*= date : ", round(Sys.time()), " =*\n", sep=""), file = p_fpath, append = TRUE) cat("*= generated with: =*\n", file = p_fpath, append = TRUE) cat("*= scripts/input/create_input_for_45_carbonprice_exogenous.R =*\n", file = p_fpath, append = TRUE) cat(paste0("*= from file: ", normalizePath(gdx), " =*\n"), file = p_fpath, append = TRUE) diff --git a/scripts/output/comparison/checkClimatePercentiles.R b/scripts/output/comparison/checkClimatePercentiles.R new file mode 100644 index 000000000..b60cf104e --- /dev/null +++ b/scripts/output/comparison/checkClimatePercentiles.R @@ -0,0 +1,97 @@ +# | (C) 2006-2023 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de +# +# This script is used to check the temperature outcomes of MAGICC when run inside REMIND +# +# The In-GAMS version of MAGICC can only run only one configuration (that is, parametrization) of MAGICC at a time, +# picked in cfg$climate_assessment_magicc_prob_file_iteration. The available configuration files were designed to +# roughly reproduce a certain quantile outcome of 2100 temperature for scenarios that are as similar as possible to +# an RCP (hence the nomenclature of the config files e.g. RCP20_50.json will be close to the 50th percentile outcome in +# a RCP2.0-like scenario). This quantile outcome is of course not guaranteed, so this script helps check the validity of +# the assumed quantile against the 600-member MAGICC7 AR6 assessment that is run by default at the end of each run. +# Therefore, for it to work, the output script MAGICC7_AR6.R must have already run and added the `MAGICC7 AR6|**` +# variables to `REMIND_generic_*.mif`. To verify the output, check the figures in `check_output_figures.pdf` and the +# table in `check_output_summary.csv` +# +require(tidyverse) +require(quitte) +require(gdx) +require(yaml) + +cat("===================== STARTING checkClimatePercentiles.R", "\n") +cat("===================== see output for final location of output files", "\n") +lucode2::readArgs("outputdirs") +cat("outputdirs: ",outputdirs) +runFolders <- normalizePath(outputdirs) # Remove trailing slashes +runFolders <- normalizePath(outputdirs) # Remove trailing slashes + +# checkscenarios <- basename(runFolders) +cat("Checking scenarios:\n\t", paste0(basename(runFolders), collapse = "\n\t"), "\n") + +# Extract RCP configuration from cfg.txt +usedRCPs <- map_dfr(runFolders, function(folder) { + cfg <- read_yaml(file.path(folder, "cfg.txt")) + tibble( + scenario = cfg$title, + rcp = basename(cfg$climate_assessment_magicc_prob_file_iteration) %>% str_remove(".json$") + ) +}) + +# Read pm_globalMeanTemperature from the MAGICC gdxs +gdxFiles <- file.path(runFolders, "p15_magicc_temp.gdx") +gdxAvailable <- file.exists(gdxFiles) +if (any(!gdxAvailable)) { + warning("Missing p15_magicc_temp.gdx files in ", paste(basename(runFolders[!gdxAvailable]), collapse = ", ")) + gdxFiles <- gdxFiles[gdxAvailable] +} +gdxData <- map_dfr(gdxFiles, function(gdxFn) { + cfg <- read_yaml(file.path(dirname(gdxFn), "cfg.txt")) + mutate(as.tibble(read.gdx(gdxFn, "pm_globalMeanTemperature")), scenario = cfg$title) + }) %>% + rename(period = tall) %>% + mutate(variable = "pm_globalMeanTemperature", region = "World", unit = "K", model = "MAGICC7 In-GAMS") + +# Read reporting data. Requires MAGICC7_AR6 to have been successfully run +mifFiles <- list.files(runFolders, pattern = ".mif", full.names = TRUE) +mifFiles <- mifFiles[str_detect(mifFiles, "REMIND_generic_.*") &! str_detect(mifFiles, "withoutPlus")] +mifData <- read.quitte(mifFiles) %>% + filter(region == "World", variable %in% c( + "MAGICC7 AR6|Surface Temperature (GSAT)|10.0th Percentile", + "MAGICC7 AR6|Surface Temperature (GSAT)|33.0th Percentile", + "MAGICC7 AR6|Surface Temperature (GSAT)|50.0th Percentile", + "MAGICC7 AR6|Surface Temperature (GSAT)|67.0th Percentile", + "MAGICC7 AR6|Surface Temperature (GSAT)|90.0th Percentile" + )) %>% + mutate(model = "MAGICC7 AR6", variable = str_split_i(variable,"\\|",3)) + +# Join GDX & MIF data and filter to only the relevant scenarios +joinedData <- bind_rows( + right_join(usedRCPs, mifData, by=join_by(scenario)), + right_join(usedRCPs, gdxData, by=join_by(scenario)) +) + +# Generate and write basic comparison plot +joinedData %>% + ggplot(aes(x = period, y = value, color = variable, linetype = model)) + + geom_path() + + facet_wrap(~scenario + rcp, scales = "free") + + xlim(2000,2100) + + theme(legend.position = "bottom") +pdfFile <- file.path(getwd(), paste0("climate_percentile_plots_", format(Sys.time(), "%y%m%dT%H%M%S"), ".pdf")) +cat("===================== Writing comparison plots to: '", pdfFile, "'\n") +ggsave(pdfFile, width = 210, height = 297, units = "mm") + +# Generate and write summary table +summaryTable <- joinedData %>% + filter(period %in% c(2050,2100)) %>% + select(-model) %>% + pivot_wider(names_from = variable, values_from = value) +summaryFile <- file.path(getwd(), paste0("climate_percentile_summary_", format(Sys.time(), "%y%m%dT%H%M%S"), "csv")) +cat("===================== Writing comparison table to: '", summaryFile, "'\n") +write.table(summaryTable, summaryFile, row.names = FALSE) + +cat("===================== checkClimatePercentile.R done", "\n") diff --git a/scripts/output/comparison/validateScenarios.R b/scripts/output/comparison/validateScenarios.R new file mode 100644 index 000000000..8e5d025b9 --- /dev/null +++ b/scripts/output/comparison/validateScenarios.R @@ -0,0 +1,77 @@ +# | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de + + + source("./scripts/start/isSlurmAvailable.R") + + # This script expects a variable `outputdirs` to be defined. + # Variables `slurmConfig` and `filename_prefix` are used if they defined. + if (!exists("outputdirs")) { + stop( + "Variable outputdirs does not exist. ", + "Please call validateScenarios.R via output.R, which defines outputdirs.") + } + + # Start validateScenarios + startVal <- function(outputDirs, validationConfig) { + if (!exists("slurmConfig")) { + slurmConfig <- "--qos=standby" + } + jobName <- paste0( + "valScen", + "-", nameCore + ) + outFileName <- jobName + script <- "scripts/vs/run_validateScenarios.R" + cat("Starting ", jobName, "\n") + if (isSlurmAvailable() && ! identical(slurmConfig, "direct")) { + clcom <- paste0( + "sbatch ", slurmConfig, + " --job-name=", jobName, + " --comment=validateScenarios", + " --output=", jobName, ".out", + " --error=", jobName, ".out", + " --mail-type=END --time=200 --mem-per-cpu=8000", + " --wrap=\"Rscript ", script, + " outputDirs=", paste(outputDirs, collapse = ","), + " validationConfig=", validationConfig, + "\"") + cat(clcom, "\n") + system(clcom) + } else { + tmpEnv <- new.env() + tmpError <- try(sys.source(script, envir = tmpEnv)) + if (!is.null(tmpError)) + warning("Script ", script, + " was stopped by an error and not executed properly!") + rm(tmpEnv) + } + } + + # choose a config file either from the package or your own + if (! exists("validationConfig")) { + availableConfigs <- list.files( + piamutils::getSystemFile("config/", package = "piamValidation")) + config <- gms::chooseFromList(availableConfigs, + type = "a validation config", + multiple = FALSE) + if (config == "") { + q() + } else { + validationConfig <- config + } + } + + # Create core of file name / job name. + timeStamp <- format(Sys.time(), "%Y-%m-%d_%H.%M.%S") + valName <- gsub(".csv", "", gsub("validationConfig_", "", validationConfig)) + nameCore <- paste0(valName, "-", timeStamp) + + # Start the job + startVal( + outputDirs = outputdirs, + validationConfig = valName) diff --git a/scripts/output/single/MAGICC7_AR6.R b/scripts/output/single/MAGICC7_AR6.R index 2e275d707..42d6fc5bb 100644 --- a/scripts/output/single/MAGICC7_AR6.R +++ b/scripts/output/single/MAGICC7_AR6.R @@ -229,10 +229,20 @@ as.quitte(remindReportingFile) %>% write.mif(remindReportingFile) piamutils::deletePlus(remindReportingFile, writemif = TRUE) +logmsg <- paste0(date(), " postprocessing done! Results appended to REMIND mif '", remindReportingFile, "'\n") + +############################# CLEAN UP WORKERS FOLDER ########################## +# openscm_runner not remnove up temp dirs. Do this manually since we keep running into file ownership issues +workersFolder <- file.path(climateAssessmentFolder, "workers") # replace with your directory path +if (dir.exists(workersFolder)) { + # Check if directory is empty + if (length(list.files(workersFolder)) == 0) { + # Remove directory. Option recursive must be TRUE for some reason, otherwise unlink won't do its job + unlink(workersFolder, recursive = TRUE) + logmsg <- paste0(logmsg, date(), " Removed workers folder '", workersFolder, "'\n") + } +} -logmsg <- paste0( - date(), " postprocessing done! Results appended to REMIND mif '", remindReportingFile, "'\n", - "MAGICC7_AR6.R finished\n" -) +logmsg <- paste0(logmsg, date(), "MAGICC7_AR6.R finished\n") cat(logmsg) capture.output(cat(logmsg), file = logFile, append = TRUE) diff --git a/scripts/output/single/reporting.R b/scripts/output/single/reporting.R index 3c14e1bf9..36e5f1ede 100644 --- a/scripts/output/single/reporting.R +++ b/scripts/output/single/reporting.R @@ -47,7 +47,7 @@ if (length(remind_policy_reporting_file) > 0) { } # produce REMIND reporting *.mif based on gdx information -message("\n### start generation of mif files at ", Sys.time()) +message("\n### start generation of mif files at ", round(Sys.time())) convGDX2MIF(gdx, gdx_refpolicycost = gdx_refpolicycost, file = remind_reporting_file, scenario = scenario, gdx_ref = gdx_ref) # MAGICC code not working with REMIND-EU @@ -84,18 +84,24 @@ if(file.exists(edgetOutputDir)) { } message("start generation of EDGE-T reporting") EDGET_output <- reportEdgeTransport(edgetOutputDir, - isTransportExtendedReported = FALSE, + isTransportExtendedReported = FALSE, modelName = "REMIND", - scenarioName = scenario, + scenarioName = scenario, gdxPath = file.path(outputdir, "fulldata.gdx"), isStored = FALSE) + REMINDoutput <- as.data.table(read.quitte(file.path(outputdir, paste0("REMIND_generic_", scenario,"_withoutPlus.mif")))) + sharedVariables <- EDGET_output[variable %in% REMINDoutput$variable | grepl(".*edge", variable)] + EDGET_output <- EDGET_output[!(variable %in% REMINDoutput$variable | grepl(".*edge", variable))] + message("The following variables will be dropped from the EDGE-Transport reporting because + they are in the REMIND reporting: ", paste(unique(sharedVariables$variable), collapse = ", ")) + write.mif(EDGET_output, remind_reporting_file, append = TRUE) piamutils::deletePlus(remind_reporting_file, writemif = TRUE) #Generate transport extended mif reportEdgeTransport(edgetOutputDir, - isTransportExtendedReported = TRUE, + isTransportExtendedReported = TRUE, gdxPath = file.path(outputdir, "fulldata.gdx"), isStored = TRUE) @@ -128,20 +134,21 @@ if (! is.null(magpie_reporting_file) && file.exists(magpie_reporting_file)) { # warn if duplicates in mif reportDuplicates(read.quitte(sub("\\.mif$", "_withoutPlus.mif", remind_reporting_file), check.duplicates = FALSE)) -message("### end generation of mif files at ", Sys.time()) +message("### end generation of mif files at ", round(Sys.time())) ## produce REMIND LCOE reporting *.csv based on gdx information -message("### start generation of LCOE reporting at ", Sys.time()) +message("### start generation of LCOE reporting at ", round(Sys.time())) tmp <- try(convGDX2CSV_LCOE(gdx, file = LCOE_reporting_file, scen = scenario)) # execute convGDX2MIF_LCOE -message("### end generation of LCOE reporting at ", Sys.time()) +message("### end generation of LCOE reporting at ", round(Sys.time())) ## generate DIETER reporting if it is needed ## the reporting is appended to REMIND_generic_.MIF in "DIETER" Sub Directory DIETERGDX <- "report_DIETER.gdx" if(file.exists(file.path(outputdir, DIETERGDX))){ - message("### start generation of DIETER reporting at ", Sys.time()) + message("### start generation of DIETER reporting at ", round(Sys.time())) remind2::reportDIETER(DIETERGDX,outputdir) - message("### end generation of DIETER reporting at ", Sys.time()) + message("### end generation of DIETER reporting at ", round(Sys.time())) } message("### reporting finished.") + diff --git a/scripts/output/single/reportingREMIND2MAgPIE.R b/scripts/output/single/reportingREMIND2MAgPIE.R index 80674678b..f267eb8ed 100644 --- a/scripts/output/single/reportingREMIND2MAgPIE.R +++ b/scripts/output/single/reportingREMIND2MAgPIE.R @@ -32,7 +32,7 @@ load(configfile, envir = envir) remind_reporting_file <- file.path(outputdir,paste0("REMIND_generic_",scenario,".mif")) # produce REMIND reporting *.mif based on gdx information -message("\n### start generation of mif files at ", Sys.time()) +message("\n### start generation of mif files at ", round(Sys.time())) convGDX2MIF_REMIND2MAgPIE(gdx, file = remind_reporting_file, scenario = scenario) magpie_reporting_file <- envir$cfg$pathToMagpieReport @@ -53,5 +53,5 @@ if (! is.null(magpie_reporting_file) && file.exists(magpie_reporting_file)) { piamutils::deletePlus(remind_reporting_file, writemif = TRUE) } -message("### end generation of mif files at ", Sys.time()) +message("### end generation of mif files at ", round(Sys.time())) message("### reporting finished.") diff --git a/scripts/start/checkFixCfg.R b/scripts/start/checkFixCfg.R index 052324d38..f81f7aa37 100644 --- a/scripts/start/checkFixCfg.R +++ b/scripts/start/checkFixCfg.R @@ -19,7 +19,7 @@ checkFixCfg <- function(cfg, remindPath = ".", testmode = FALSE) { NC <- "\033[0m" # No Color refcfg <- gms::readDefaultConfig(remindPath) - remindextras <- c("backup", "remind_folder", "pathToMagpieReport", "cm_nash_autoconverge_lastrun", + remindextras <- c("backup", "remind_folder", "pathToMagpieReport", "cm_nash_autoconverge_lastrun", "var_luc", "gms$c_expname", "restart_subsequent_runs", "gms$c_GDPpcScen", "gms$cm_CES_configuration", "gms$c_description", "model", "renvLockFromPrecedingRun") fail <- tryCatch(gms::check_config(cfg, reference_file = refcfg, modulepath = file.path(remindPath, "modules"), @@ -107,9 +107,8 @@ checkFixCfg <- function(cfg, remindPath = ".", testmode = FALSE) { } } else { if (! is.na(cfg$files2export$start["input_bau.gdx"])) { - message("You have specified no realization that requires 'path_gdx_bau' but you have specified it. ", - "To avoid an unnecessary dependency to another run, setting 'path_gdx_bau' to NA.") - cfg$files2export$start["input_bau.gdx"] <- NA + message("According to 'scripts/start/needBau.R', you use no realization that requires 'path_gdx_bau' but you have specified it. ", + "To avoid an unnecessary dependency to another run, you can set 'path_gdx_bau' to NA.") } } diff --git a/scripts/start/getReportData.R b/scripts/start/getReportData.R index 1c89f50bd..d244c3d3c 100644 --- a/scripts/start/getReportData.R +++ b/scripts/start/getReportData.R @@ -5,7 +5,7 @@ # | REMIND License Exception, version 1.0 (see LICENSE file). # | Contact: remind@pik-potsdam.de -getReportData <- function(path_to_report,inputpath_mag="magpie_40",inputpath_acc="costs") { +getReportData <- function(path_to_report,inputpath_mag="magpie_40",inputpath_acc="costs",var_luc="smooth") { require(magclass, quietly = TRUE,warn.conflicts =FALSE) @@ -43,6 +43,15 @@ getReportData <- function(path_to_report,inputpath_mag="magpie_40",inputpath_acc } .emissions_mac <- function(mag) { + # Select the LUC variable according to setting. + if (var_luc == "smooth") { + emi_co2_luc <- "Emissions|CO2|Land|+|Land-use Change (Mt CO2/yr)" + } else if (var_luc == "raw") { + emi_co2_luc <- "Emissions|CO2|Land RAW|+|Land-use Change (Mt CO2/yr)" + } else { + stop(paste0("Unkown setting for 'var_luc': `", var_luc, "`. Only `smooth` or `raw` are allowed.")) + } + # define three columns of dataframe: # emirem (remind emission names) # emimag (magpie emission names) @@ -53,7 +62,7 @@ getReportData <- function(path_to_report,inputpath_mag="magpie_40",inputpath_acc map <- data.frame(emirem=NULL,emimag=NULL,factor_mag2rem=NULL,stringsAsFactors=FALSE) if("Emissions|N2O|Land|Agriculture|+|Animal Waste Management (Mt N2O/yr)" %in% getNames(mag)) { # MAgPIE 4 (up to date) - map <- rbind(map,data.frame(emimag="Emissions|CO2|Land|+|Land-use Change (Mt CO2/yr)", emirem="co2luc", factor_mag2rem=1/1000*12/44,stringsAsFactors=FALSE)) + map <- rbind(map,data.frame(emimag=emi_co2_luc, emirem="co2luc", factor_mag2rem=1/1000*12/44,stringsAsFactors=FALSE)) map <- rbind(map,data.frame(emimag="Emissions|N2O|Land|Agriculture|+|Animal Waste Management (Mt N2O/yr)", emirem="n2oanwstm", factor_mag2rem=28/44,stringsAsFactors=FALSE)) map <- rbind(map,data.frame(emimag="Emissions|N2O|Land|Agriculture|Agricultural Soils|+|Inorganic Fertilizers (Mt N2O/yr)", emirem="n2ofertin", factor_mag2rem=28/44,stringsAsFactors=FALSE)) map <- rbind(map,data.frame(emimag="Emissions|N2O|Land|Agriculture|Agricultural Soils|+|Manure applied to Croplands (Mt N2O/yr)", emirem="n2oanwstc", factor_mag2rem=28/44,stringsAsFactors=FALSE)) diff --git a/scripts/start/needBau.R b/scripts/start/needBau.R index 7c3003b9a..25af30586 100644 --- a/scripts/start/needBau.R +++ b/scripts/start/needBau.R @@ -8,6 +8,6 @@ # and the realizations that require a 'path_gdx_bau' as elements # This allows readCheckScenarioConfig and checkFixConfig to set it to NA # if not needed, and complain if it is missing. -needBau <- list(carbonprice = c("NDC"), +needBau <- list(carbonprice = "NDC", carbonpriceRegi = "NDC", emicapregi = "AbilityToPay") diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index 07d93af87..c35c79030 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -123,7 +123,12 @@ prepare <- function() { # If a path to a MAgPIE report is supplied use it as REMIND input (used for REMIND-MAgPIE coupling) # ATTENTION: modifying gms files if (!is.null(cfg$pathToMagpieReport)) { - getReportData(path_to_report = cfg$pathToMagpieReport,inputpath_mag=cfg$gms$biomass,inputpath_acc=cfg$gms$agCosts) + getReportData( + path_to_report = cfg$pathToMagpieReport, + inputpath_mag = cfg$gms$biomass, + inputpath_acc = cfg$gms$agCosts, + var_luc = cfg$var_luc + ) } # Update module paths in GAMS code diff --git a/scripts/start/readCheckScenarioConfig.R b/scripts/start/readCheckScenarioConfig.R index a6309199d..f738180a0 100644 --- a/scripts/start/readCheckScenarioConfig.R +++ b/scripts/start/readCheckScenarioConfig.R @@ -16,6 +16,7 @@ #' @author Oliver Richters #' @return list with scenario config content readCheckScenarioConfig <- function(filename, remindPath = ".", testmode = FALSE, fillWithDefault = FALSE) { + coupling <- if (grepl("scenario_config_coupled", filename)) "MAgPIE" else FALSE if (testmode) { cfg <- suppressWarnings(gms::readDefaultConfig(remindPath)) } else { @@ -96,45 +97,38 @@ readCheckScenarioConfig <- function(filename, remindPath = ".", testmode = FALSE ", no column path_gdx_refpolicycost for policy cost comparison found, using path_gdx_ref instead.") message(msg) } - if ("path_gdx_bau" %in% names(scenConf)) { - # fix if bau given despite not needed. needBau is defined in needBau.R - # initialize vector with FALSE everywhere and turn elements to TRUE if a scenario config row setting matches a needBau element - scenNeedsBau <- rep(FALSE, nrow(scenConf)) - for (n in intersect(names(needBau), names(scenConf))) { - scenNeedsBau <- scenNeedsBau | scenConf[[n]] %in% needBau[[n]] - } - BAUbutNotNeeded <- ! is.na(scenConf$path_gdx_bau) & ! (scenNeedsBau) - if (sum(BAUbutNotNeeded) > 0 && ! grepl("scenario_config_coupled", filename)) { - msg <- paste0("In ", sum(BAUbutNotNeeded), " scenarios, 'path_gdx_bau' is not empty although no realization is selected that needs it.\n", - "To avoid unnecessary dependencies to other runs, automatically setting 'path_gdx_bau' to NA for:\n", - paste(rownames(scenConf)[BAUbutNotNeeded], collapse = ", ")) - message(msg) - scenConf$path_gdx_bau[BAUbutNotNeeded] <- NA - } - # fail if bau not given but needed - noBAUbutNeeded <- is.na(scenConf$path_gdx_bau) & (scenNeedsBau) - if (sum(noBAUbutNeeded) > 0) { - pathgdxerrors <- pathgdxerrors + sum(noBAUbutNeeded) - warning("In ", sum(noBAUbutNeeded), " scenarios, a reference gdx in 'path_gdx_bau' is needed, but it is empty. ", - "These realizations need it: ", - paste0(names(needBau), ": ", sapply(needBau, paste, collapse = ", "), ".", collapse = " ")) - } - } + # make sure every path gdx column exists scenConf[, names(path_gdx_list)[! names(path_gdx_list) %in% names(scenConf)]] <- NA + # check if path_gdx_bau is needed, based on needBau.R + # initialize vector with FALSE everywhere and turn elements to TRUE if a scenario config row setting matches a needBau element + scenNeedsBau <- rep(FALSE, nrow(scenConf)) + for (n in intersect(names(needBau), names(scenConf))) { + scenNeedsBau <- scenNeedsBau | scenConf[[n]] %in% needBau[[n]] + } + # fail if bau not given but needed + noBAUbutNeeded <- is.na(scenConf$path_gdx_bau) & (scenNeedsBau) + if (sum(noBAUbutNeeded) > 0) { + pathgdxerrors <- pathgdxerrors + sum(noBAUbutNeeded) + warning("In ", sum(noBAUbutNeeded), " scenarios, a reference gdx in 'path_gdx_bau' is needed, but it is empty. ", + "These realizations need it: ", + paste0(names(needBau), ": ", sapply(needBau, paste, collapse = ", "), ".", collapse = " ")) + } + # collect errors errorsfound <- length(colduplicates) + sum(toolong) + sum(regionname) + sum(nameisNA) + sum(illegalchars) + whitespaceErrors + copyConfigFromErrors + pathgdxerrors + missingRealizations # check column names - knownColumnNames <- c(names(cfg$gms), setdiff(names(cfg), "gms"), names(path_gdx_list), - "start", "model", "copyConfigFrom") - if (grepl("scenario_config_coupled", filename)) { + knownColumnNames <- c(names(path_gdx_list), "start", "model", "copyConfigFrom") + if (coupling %in% "MAgPIE") { knownColumnNames <- c(knownColumnNames, "cm_nash_autoconverge_lastrun", "oldrun", "path_report", "magpie_scen", "no_ghgprices_land_until", "qos", "sbatch", "path_mif_ghgprice_land", "max_iterations", - "magpie_empty") + "magpie_empty", "var_luc") # identify MAgPIE switches by "cfg_mag" and "scenario_config" knownColumnNames <- c(knownColumnNames, grep("cfg_mag|scenario_config", names(scenConf), value = TRUE)) + } else { # not a coupling config + knownColumnNames <- c(knownColumnNames, names(cfg$gms), setdiff(names(cfg), "gms")) } unknownColumnNames <- names(scenConf)[! names(scenConf) %in% knownColumnNames] if (length(unknownColumnNames) > 0) { @@ -166,11 +160,8 @@ readCheckScenarioConfig <- function(filename, remindPath = ".", testmode = FALSE "cm_solwindenergyscen"= "Deleted, not used, see https://github.com/remindmodel/remind/pull/1532", NULL) for (i in intersect(names(forbiddenColumnNames), unknownColumnNames)) { - if (testmode) { - warning("Column name ", i, " in remind settings is outdated. ", forbiddenColumnNames[i]) - } else { - message("Column name ", i, " in remind settings is outdated. ", forbiddenColumnNames[i]) - } + msg <- paste0("Column name ", i, " in remind settings is outdated. ", forbiddenColumnNames[i]) + if (testmode) warning(msg) else message(msg) } if (any(names(forbiddenColumnNames) %in% unknownColumnNames)) { warning("Outdated column names found that must not be used.") @@ -179,11 +170,11 @@ readCheckScenarioConfig <- function(filename, remindPath = ".", testmode = FALSE # sort out known but forbidden names from unknown unknownColumnNames <- setdiff(unknownColumnNames, names(forbiddenColumnNames)) if (length(unknownColumnNames) > 0) { - message("\nAutomated checks did not find counterparts in main.gms and default.cfg for these columns in ", - basename(filename), ":") + message("\nAutomated checks did not understand these columns in ", basename(filename), ":") message(" ", paste(unknownColumnNames, collapse = ", ")) - message("This check was added Jan. 2022. ", - "If you find false positives, add them to knownColumnNames in scripts/start/readCheckScenarioConfig.R.\n") + if (isFALSE(coupling)) message("These are no cfg or cfg$gms switches found in main.gms and default.cfg.") + if (coupling %in% "MAgPIE") message("Maybe you specified REMIND switches in coupled config, which does not work.") + message("If you find false positives, add them to knownColumnNames in scripts/start/readCheckScenarioConfig.R.\n") unknownColumnNamesNoComments <- unknownColumnNames[! grepl("^\\.", unknownColumnNames)] if (length(unknownColumnNamesNoComments) > 0) { if (testmode) { diff --git a/scripts/vs/run_validateScenarios.R b/scripts/vs/run_validateScenarios.R new file mode 100644 index 000000000..ca07d277c --- /dev/null +++ b/scripts/vs/run_validateScenarios.R @@ -0,0 +1,27 @@ +# | (C) 2006-2024 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de + +library(piamValidation) + +lucode2::readArgs("outputDirs", "validationConfig") + +# working directory is assumed to be the remind directory +outputDirs <- normalizePath(outputDirs, mustWork = TRUE) +mifPath <- remind2::getMifScenPath(outputDirs, mustWork = TRUE) +histPath <- remind2::getMifHistPath(outputDirs[1], mustWork = TRUE) + +# option 1: HTML validation Report +piamValidation::validationReport(c(mifPath, histPath), validationConfig) + +# option 3: export data (TODO: file location + name) +valiData <- piamValidation::validateScenarios(c(mifPath, histPath), validationConfig) +cat(getwd()) + +# option 2: pass or fail? +piamValidation::validationPass(valiData) + + diff --git a/start_bundle_coupled.R b/start_bundle_coupled.R index 5c2266a3f..a864b4d15 100755 --- a/start_bundle_coupled.R +++ b/start_bundle_coupled.R @@ -368,6 +368,7 @@ for(scen in common){ cfg_rem <- cfg rm(cfg) cfg_rem$title <- scen + cfg_rem$files2export$start <- c(cfg_rem$files2export$start, path_settings_coupled, path_settings_remind) rem_filesstart <- cfg_rem$files2export$start # save to reset it to that later source(file.path(path_magpie, "config", "default.cfg")) # retrieve MAgPIE settings @@ -419,6 +420,17 @@ for(scen in common){ cfg_mag$mute_ghgprices_until <- scenarios_coupled[scen, "no_ghgprices_land_until"] } + # Write choice of land-use change variable to config. Use smoothed variable + # if not specified otherwise in coupled config, i.e. if the column is missing + # completely or if the row entry is empty. + if (! "var_luc" %in% names(scenarios_coupled) || is.na(scenarios_coupled[scen, "var_luc"])) { + cfg_rem$var_luc <- "smooth" + } else if (scenarios_coupled[scen, "var_luc"] %in% c("smooth", "raw")) { + cfg_rem$var_luc <- scenarios_coupled[scen, "var_luc"] + } else { + stop(paste0("Unkown setting in coupled config file for 'var_luc': `", scenarios_coupled[scen, "var_luc"], "`. Please chose either `smooth` or `raw`")) + } + # Edit remind main model file, region settings and input data revision based on scenarios table, if cell non-empty cfg_rem_options <- c("model", "regionmapping", "extramappings_historic", "inputRevision", setdiff(names(cfg_rem), c("gms", "output"))) for (switchname in intersect(cfg_rem_options, names(settings_remind))) { @@ -611,6 +623,7 @@ for(scen in common){ } message("path_report : ",ifelse(file.exists(path_report),green,red), path_report, NC) message("no_ghgprices_land_until: ", cfg_mag$gms$c56_mute_ghgprices_until) + message("var_luc: ", cfg_rem$var_luc) if ("--gamscompile" %in% flags) { message("Compiling ", fullrunname) diff --git a/tests/testthat/test_01-manipulateConfig.R b/tests/testthat/test_01-manipulateConfig.R index 566c5a722..7e3793a43 100644 --- a/tests/testthat/test_01-manipulateConfig.R +++ b/tests/testthat/test_01-manipulateConfig.R @@ -57,6 +57,6 @@ test_that("manipulate config with default configuration does not change main.gms # cleanup if no error found if (length(addedgms) + length(removedgms) + length(contentdiff) + length(diffresult) == 0) { - file.remove(list.files(pattern = "main-TESTTHAT.*gms")) + file.remove(list.files(path = "../..", pattern = "main-TESTTHAT.*gms", full.names = TRUE)) } }) diff --git a/tests/testthat/test_01-readCheckScenarioConfig.R b/tests/testthat/test_01-readCheckScenarioConfig.R index 5234ad302..e347f0e43 100644 --- a/tests/testthat/test_01-readCheckScenarioConfig.R +++ b/tests/testthat/test_01-readCheckScenarioConfig.R @@ -38,7 +38,6 @@ test_that("readCheckScenarioConfig fails on error-loaden config", { expect_match(w, "Do not use 'NA' as scenario name", all = FALSE, fixed = TRUE) expect_match(w, "For module carbonprice.*notNDC_but_has_path_gdx_bau", all = FALSE, fixed = FALSE) expect_match(m, "no column path_gdx_refpolicycost for policy cost comparison found, using path_gdx_ref instead", all = FALSE, fixed = TRUE) - expect_match(m, "is not empty although no realization is selected that needs it", all = FALSE, fixed = TRUE) copiedFromPBS <- c("c_budgetCO2", "path_gdx", "path_gdx_ref") expect_identical(unlist(scenConf["PBS", copiedFromPBS]), unlist(scenConf["PBScopy", copiedFromPBS])) diff --git a/tutorials/03_RunningBundleOfRuns.md b/tutorials/03_RunningBundleOfRuns.md index 8d38a610a..1f5292edc 100644 --- a/tutorials/03_RunningBundleOfRuns.md +++ b/tutorials/03_RunningBundleOfRuns.md @@ -47,7 +47,7 @@ Example with comments and different ways to specify subsequent runs. The columns to implement subsequent runs are usually found at the end, starting with `path_gdx`: * `path_gdx` allows to specify initial conditions for the run, overwriting the usual initial conditions taken from the calibration files found in [`./config/gdx-files/`](../config/gdx-files/files). If it points to an unconverged run, this can be used to restart runs, similar to `Rscript start.R --restart`. -* `path_gdx_bau` points to the run used as business as usual (BAU) scenario, for example for runs using [`45_carbonprice/NDC`](../modules/45_carbonprice/NDC), where some countries specify emission as percentage reduction compared to BAU. All realizations needing it have to be summarized in [`scripts/start/needBau.R`](../scripts/start/needBau.R). +* `path_gdx_bau` points to the run used as business as usual (BAU) scenario, for example for runs using [`45_carbonprice/NDC`](../modules/45_carbonprice/NDC), where some countries specify emission as percentage reduction compared to BAU. All realizations needing it should be summarized in [`scripts/start/needBau.R`](../scripts/start/needBau.R). * `path_gdx_carbonprice` can be used to use a carbon tax path from an earlier run with realization [`45_carbonprice/exogenous`](../modules/45_carbonprice/exogenous). * `path_gdx_ref` points to the run used for all `t < cm_startyear`, which can be used for example for delayed transition scenarios. * `path_gdx_refpolicycost` points to the run that is used as a comparison for the policy cost calculation. If no such column exists, `path_gdx_ref` is used instead. diff --git a/tutorials/04_RunningREMINDandMAgPIE.md b/tutorials/04_RunningREMINDandMAgPIE.md index a0cf54aa6..ebc19a8db 100644 --- a/tutorials/04_RunningREMINDandMAgPIE.md +++ b/tutorials/04_RunningREMINDandMAgPIE.md @@ -107,7 +107,7 @@ All the columns must be present in the `scenario_config_coupled.csv` file, but m - `magpie_scen`: A pipe (`|`) separated list of configurations to pass to MAgPIE. Each entry should correspond to a column in [MAgPIE's scenario_config](https://github.com/magpiemodel/magpie/blob/master/config/scenario_config.csv), each one of them setting the multiple configuration flags listed in that file. The configurations are applied in the order that they appear. For example, to configure MAgPIE with SSP2 settings and climate change impacts according to RCP45 set `magpie_scen` to `SSP2|cc|rcp4p5`. To select scenarios from a different `scenario_config*.csv` file replace `magpie_scen` by the path to that file relative to MAgPIE's main folder, for example: `config/projects/scenario_config_PROJECT.csv`. The filename *must contain* the string `scenario_config`. You can also specify more than one column directing to another `scenario_config_PROJECT2.csv` file. They will be evaluated in the order in which they appear in the `scenario_config_coupled.csv`. There is another option of addressing MAgPIE switches described at the end of the list of optional columns below. - `no_ghgprices_land_until`: Controls at which timestep in the MAgPIE runs GHG prices from REMIND will start to be applied. This essentially enables you to set whether or not (or when) GHG prices on land should be applied in MAgPIE. If you want MAgPIE to always apply the same GHG prices from REMIND, you should set this to a timestep corresponding to the start of your REMIND run, such as `y2020` to start in the 2020 timestep. If you want to disable GHG prices in MAgPIE, regardless of what REMIND finds, set this to the last timestep of the run (usually `y2150`). Values in between allow the simulation of policies where GHG prices are only applied in the land use sector after a certain year. -Other, optional columns allow you to make a run start only after another has finished, set starting conditions, and give you finer control over which data is fed to MAgPIE. +Other, optional columns allow you to make a run start only after another has finished, set starting conditions, and give you finer control over which data is fed from REMIND to MAgPIE or from MAgPIE to REMIND. - `path_gdx`, `path_gdx_ref`, `path_gdx_refpolicycost`, `path_gdx_carbonprice`, `path_gdx_bau`, : Override these same settings in REMIND's `scenario_config`, see [`03_RunningBundleOfRuns`](./03_RunningBundleOfRuns.md) for a detailed explanation. - You can set these switches either to the full path of a `fulldata.gdx` file or simply to the name of another scenario in the file (without the "C_"!). So if you want a certain scenario (say `NDC`) to use as starting point the results of a `Base` scenario, you can simply set `path_gdx` to `Base` and it will automatically locate the appropriate `fulldata.gdx` in `Base`, for example `path_remind/C_Base-rem-x/fulldata.gdx`. @@ -121,6 +121,7 @@ Other, optional columns allow you to make a run start only after another has fin - `path_report: Provide a path to a MAgPIE report here if you want REMIND to start with it. It overwrites whatever might have been automatically found from former MAgPIE runs. - `cm_nash_autoconverge_lastrun`: can be used to specify `cm_nash_autoconverge`, but only for the last REMIND run, for example to increase precision there by setting it to `2`. - `cfg_mag$...`: If you don't want to select composed scenarios in MAgPIE to address switches, you can directly address individual MAgPIE switches in the `scenario_config_coupled.csv`. Add any number of columns to your `scenario_config_coupled.csv` that have the name of the MAgPIE switch as the column name. They need to start with `cfg_mag$`. For example: if you want to set `gms$s56_cprice_red_factor` to `3.14` for `SSP2-NPi`, add the column `cfg_mag$gms$s56_cprice_red_factor` to your `scenario_config_coupled.csv` and fill in `3.14` in the row that defines `SSP2-NPi`. + - `var_luc`: Controls, which variable to use in REMIND to represent land-use change (LUC) CO2 emissions from MAgPIE (`co2luc` in REMIND). By default, this switch is set to `smooth` such that the variable `Emissions|CO2|Land|+|Land-use Change` is used. This variable was i.a. obtained by applying a low-pass filter to the raw LUC emissions in order to smooth out spikes. Alternatively, this switch can be set to `raw`. Then the unfiltered variable `Emissions|CO2|Land RAW|+|Land-use Change` is used instead. ### Perform test start before actually submitting runs diff --git a/tutorials/05_AnalysingModelOutputs.md b/tutorials/05_AnalysingModelOutputs.md index f8b9f3e56..89eb28f32 100644 --- a/tutorials/05_AnalysingModelOutputs.md +++ b/tutorials/05_AnalysingModelOutputs.md @@ -92,23 +92,11 @@ Here **gdx** is the path to the gdx file, while the second argument is the **nam **In the following, we present several other tools and scripts that were developed to facilitate the output analysis:** -## 4. Automated model validation - -### 4.1. Generation of summary and validation pdfs -The automated model analysis (summary and validation) is an important example of output analysis based on model-internal scripts (see section 6). If these scripts are executed (either by selection via cfg$output as explained in 6.1. or by execution via command window as explained in 6.2.), standard evaluation pdfs are created. They validate numerous model outputs with historical data, either visually or via statistical tests. - -### 4.2 A Summary of Results -For a first overview and for not getting lost in the huge amount of variables you can look at the *REMIND_summary_[title].pdf*. This .pdf-file will give you an overview on the model results and guides you through the story. - -### 4.3 The Whole Range of Validation -A standard validation PDF *REMIND_validation_[title].pdf* consists of hundreds of evaluation outputs. By evaluating the model outputs on such a broad level rather than focusing only on key outputs, it allows getting a more complete picture of the corresponding scenario. The table of contents of the validation pdf gives a good overview about the breadth of model outputs that can be generated with a REMIND standard scenario, even though the validation pdf only shows a subset of possible model outputs. - - -## 5. Interactive scenario analysis +## 4. Interactive scenario analysis The automated model validation is a good tool for visually evaluating a broad range of model outputs. However, comparison between model runs, i.e. between different scenarios, is rather difficult and inconvenient if the model results are scattered across different large PDF files. -### 5.1. AppResults +### 4.1. AppResults To overcome this issue, we developed the interactive scenario analysis and evaluation tools appResults and appResultsLocal as part of the package **shinyresults** (), which show evaluation plots for multiple scenarios including historical data and other projections based on an interactive selection of regions and variables. @@ -151,9 +139,9 @@ Another tool for analyzing model output on your local computer is the scenario t mip::scenTool() ``` -## 6. Model-internal R-scripts for output analysis +## 5. Model-internal R-scripts for output analysis -### 6.1. Execution of model-internal output scripts via the REMIND configuration file +### 5.1. Execution of model-internal output scripts via the REMIND configuration file In the file *config/default.cfg*, it is possible to indicate which R-scripts are executed for output analysis after a model run is finished. Scripts evaluating single runs are stored in the folder **scripts/output/[title-of-the-run]**. In the default REMIND configuration, the scripts *reporting*, *validation* (see section 2.3), *validationSummary* (see section 2.3), *rds\_report* (to be used in appResults; see section 3), and *dashboard* are selected via cfg$output: @@ -161,7 +149,7 @@ In the file *config/default.cfg*, it is possible to indicate which R-scripts are cfg$output <- c("reporting","validation","rds_report","validationSummary","dashboard") ``` -### 6.2. Execution of model-internal output scripts in the command window +### 5.2. Execution of model-internal output scripts in the command window Output scripts that are included in the folders **scripts/output/single** and **scripts/output/comparison** can also be executed via a command window. To do so, windows users can open a command line prompt in the REMIND model folder by using **shift** + **right click** and then selecting *open command window here* option. @@ -184,6 +172,8 @@ Now, the selected scripts are executed. After completion, the results are writte One recommended script for comparison of different scenarios is `compareScenarios2`, see [the specific tutorial](https://pik-piam.r-universe.dev/articles/remind2/compareScenariosRemind2.html). After you selected folder names, specified a `filename_prefix`, the priority on the cluster, and a *profile* (describes some output parameters) it produces a large PDF (or HTML if a respective profile is chosen) in the `./remind/` folder. +Another useful script it `validateScenarios`, which performs an automated check of the scenario data against thresholds defined in a `validationConfig` and returns an html report with interactive heat maps in a traffic-light evaluation format. After choosing `validateScenarios` as a `comparison` script, you are prompted to select one of the configs that are shipped with the `piamValidation` package. The `default` config is a good starting point for any REMIND run and the `AMT` config is specifically tailored towards the automated model testruns. If you want to perform a more personalized validation, follow the instructions in the [vignette](https://pik-piam.r-universe.dev/articles/piamValidation/validateScenarios.html). + You can also specify the parameters in the command line, for example starting a `compareScenario2` run without any prefix as: ``` bash @@ -194,7 +184,7 @@ If you want to compare runs from different REMIND folders, add `remind_dir=.,../ How to create new plots is described in the tutorial [8_Advanced_AnalysingModelOutputs.Rmd](./08_Advanced_AnalysingModelOutputs.Rmd). Another useful and compatible resource for generating plots (e.g. box plots) from REMIND results is UTokyo's *mipplot* R package: https://github.com/UTokyo-mip/mipplot. -## 7. Analysis of outputs with the remind2 R package +## 6. Analysis of outputs with the remind2 R package If you want to go beyond visual output analysis and predefined output evaluation facilitated by scripts in the model folders **scripts/output/single** and **scripts/output/comparison**, you can use the functionality of the R package *remind2* (https://github.com/pik-piam/remind2). This package contains a list of common functions for extracting outputs from the REMIND model which are also the basis for the generation of the automated validation pdf. For a quick overview on the functions which are included in the package, you can scan the folder **remind2/R** of the remind2 package source code.