REMIND - REgional Model of INvestments and Development

3.7.0

created with goxygen 1.5.0

Model Assumptions (00_model_assumptions)

Description

Model Bounds and Assumptions

1. Conopt optimisation bounds

Set lower bounds on variables otherwise the conopt solver doesn’t see a benefit from changing variable value away from 0 These lower bounds are set so low that they do not restrict the results Lower limit on all P2SE technologies capacities to 100 kW of all technologies and all time steps

loop(pe2se(enty,enty2,te) $ (
    (not sameas(te,"biotr")) and
    (not sameas(te,"biodiesel")) and
    (not sameas(te,"bioeths")) and
    (not sameas(te,"gasftcrec")) and
    (not sameas(te,"gasftrec")) and
    (not sameas(te,"tnrs")) and
    (not teBiopyr(te))
  ),
  vm_cap.lo(t,regi,te,"1") $ (t.val >= 2030 and t.val <= 2070) = 1e-7;
  if(not teCCS(te), 
    vm_deltaCap.lo(t,regi,te,"1") $ (t.val >= 2030 and t.val <= 2070) = 1e-8;
  );
);

Make sure that the model also sees the se2se technologies (seel <–> seh2)

loop(se2se(enty,enty2,te),
  vm_cap.lo(t,regi,te,"1") $ (t.val >= 2030) = 1e-7;
);

Lower bound of 10 kW on each of the different grades for renewables with multiple resource grades

loop(teRe2rlfDetail(te,rlf),
  loop(regi $ (pm_dataren(regi,"maxprod",rlf,te) > 0),
    v_capDistr.lo(t,regi,te,rlf) $ (t.val >= 2015) = 1e-8;
    v_capDistr.lo("2015",regi,te,rlf) = 0.9 / max(1, p_aux_capacityFactorHistOverREMIND(regi,te)) * p_aux_capThisGrade(regi,te,rlf);
    v_capDistr.lo("2020",regi,te,rlf) = 0.9 / max(1, p_aux_capacityFactorHistOverREMIND(regi,te)) * p_aux_capThisGrade(regi,te,rlf);
  );
);

2. Historical and near-term capacities

Capacity for fossils and renewables
loop(t $ (t.val >= 2015 and t.val <= 2025),
  vm_cap.lo(t,regi,teVRE(te),"1") $ pm_histCap(t,regi,te) = 0.95 * pm_histCap(t,regi,te);
  if(t.val <= 2020, !! TODO: activate 2025 upper-bound when consolidated data available
    vm_cap.up(t,regi,teVRE(te),"1") $ pm_histCap(t,regi,te) = 1.05 * pm_histCap(t,regi,te);
  );
  if(t.val = 2025,
    vm_cap.lo(t,regi,teVRE(te),"1") $ p_histCapYearly("2024",regi,te) = max(p_histCapYearly("2024",regi,te) 
                                                                                + 0.5
                                                                                  * ( p_histCapYearly("2024",regi,te) 
                                                                                    - p_histCapYearly("2022",regi,te) ) / 2,
                                                                              p_histCapYearly("2024",regi,te)
                                                                            );
    vm_cap.up(t,regi,teVRE(te),"1") $ p_histCapYearly("2024",regi,te) = max(p_histCapYearly("2024",regi,te) 
                                                                                + 2
                                                                                  * ( p_histCapYearly("2024",regi,te) 
                                                                                    - p_histCapYearly("2022",regi,te) ) / 2,
                                                                              1.1 * p_histCapYearly("2024",regi,te)
                                                                            );
  );
  loop(te $ (sameas(te, "hydro") or sameas(te, "geohdr")),
    vm_cap.lo(t,regi,te,"1") $ pm_histCap(t,regi,te) = 0.7 * pm_histCap(t,regi,te);
    vm_cap.up(t,regi,te,"1") $ pm_histCap(t,regi,te) = 1.4 * pm_histCap(t,regi,te);
  );
  loop(te $ (sameas(te,"ngcc") or sameas(te,"ngt") or sameas(te,"gaschp")),
    vm_cap.lo(t,regi,te,"1") $ pm_histCap(t,regi,te) = 0.95 * pm_histCap(t,regi,te);
  );
);
loop(regi $ regi_group("EUR_regi",regi),

bounds on 2025 variable renewables generation in Europe based on historical growth rates

  vm_prodSe.up("2025",regi,"pewin","seel","windon") = p_histProdSe("2023",regi,"seel","windon") * power((p_maxhistProdSeGrowthRate(regi,"seel","windon") * 1.3 + 1), 2);
  vm_prodSe.up("2025",regi,"pesol","seel","spv")    = p_histProdSe("2023",regi,"seel","spv")    * power((p_maxhistProdSeGrowthRate(regi,"seel","spv")    * 1.3 + 1), 2);

no investment into oil turbines in Europe

  vm_deltaCap.up(t,regi,"dot","1") $ (t.val > 2005) = 1e-6;
);
vm_prodSe.lo("2020",regi,"pecoal","seel","coalchp") = 0.8 * pm_IO_output("2020",regi,"pecoal","seel","coalchp") ;
vm_prodSe.up("2020",regi,"pegas","seel","gaschp") = 1e-4 + 1.3 * pm_IO_output("2020",regi,"pegas","seel","gaschp");
vm_deltaCap.lo("2030",regi,te,"1") = sum( project_status,
                                      p_ProjectsCompletionShare("2030",regi,te,project_status)
                                      * p_CapacityBounds("2030",regi,te,project_status) )
                                    / 5;
Near-term capacity for electrolysis and hydrogen

set lower and upper bounds for 2025 and 2030 based on projects annoucements from IEA Hydryogen project database: https://www.iea.org/data-and-statistics/data-product/hydrogen-production-and-infrastructure-projects-database distribute to regions via GDP share of 2025 (we do not use later time steps as they may have different GDPs depending on the scenario) in future this should be differentiated by region based on regionalized input data of project announcements 2 GW(el) at least globally in 2025, about operational capacity as of 2023

vm_cap.lo("2025",regi,"elh2","1") =   2e-3 * pm_eta_conv("2025",regi,"elh2") * pm_gdp("2025",regi) / sum(regi2,pm_gdp("2025",regi2));

20 GW(el) at maximum globally in 2025 (be more generous to not overconstrain regions which scale-up fastest)

vm_cap.up("2025",regi,"elh2","1") =  20e-3 * pm_eta_conv("2025",regi,"elh2") * pm_gdp("2025",regi) / sum(regi2,pm_gdp("2025",regi2));

100 GW(el) at maximum globally in 2030 (upper end of feasibility range in Odenweller et al. 2022, https://doi.org/10.1038/s41560-022-01097-4, Fig. 4)

vm_cap.up("2030",regi,"elh2","1") = 100e-3 * pm_eta_conv("2025",regi,"elh2") * pm_gdp("2025",regi) / sum(regi2,pm_gdp("2025",regi2));

upper bound of 0.5 EJ/yr to prevent building too much grey hydrogen before 2020, distributed to regions via GDP share

vm_cap.up("2020",regi,"gash2","1")  = 0.5 * sm_EJ_2_TWa * pm_gdp("2020",regi) / sum(regi2, pm_gdp("2020",regi2));

Set upper bounds on biomass gasification for hydrogen production, which is not deployed as of 2025 allow for small production of at most 0.1 EJ/yr by 2030 for each technology globally, distributed to regions by GDP share in 2025

vm_cap.up("2030",regi,"bioh2","1")  = 0.1 * sm_EJ_2_TWa * pm_gdp("2025",regi) / sum(regi2, pm_gdp("2025",regi2));
vm_cap.up("2030",regi,"bioh2c","1") = 0.1 * sm_EJ_2_TWa * pm_gdp("2025",regi) / sum(regi2, pm_gdp("2025",regi2));

allow zero vm_deltaCap for bio-hydrogen up to 2030 to be consistent with above bounds

vm_deltaCap.lo(t,regi,"bioh2","1")  $ (t.val <= 2030) = 0;
vm_deltaCap.lo(t,regi,"bioh2c","1") $ (t.val <= 2030) = 0;
Technologies depending on learning and tech_stat
vm_costTeCapital.fx(ttot,regi,teNoLearn) = pm_inco0_t("2005",regi,teNoLearn); !! use 2005 value for the past
vm_costTeCapital.fx(t,   regi,teNoLearn) = pm_inco0_t(t,regi,teNoLearn);

No battery storage in 2010

vm_cap.up("2010",regi,teStor,"1") = 0;
vm_capCum.lo(ttot,regi,teLearn) $ (ttot.val >= cm_startyear) = pm_data(regi,"ccap0",teLearn);
vm_capCum.lo(ttot,regi,teLearn) $ (pm_data(regi,"tech_stat",teLearn) = 4 and ttot.val <= 2020) = 0;

Advanced technologies shouldn’t be built prior to 2015/2020

loop(regi,
  loop(teNoLearn(te) $ (pm_data(regi,"tech_stat",te) = 2),
    vm_deltaCap.fx("2010",regi,te,rlf) = 0;
    vm_cap.lo("2010",regi,te,rlf) = 0;
    vm_cap.lo("2015",regi,te,rlf) = 0;
  );
  loop(teNoLearn(te) $ (pm_data(regi,"tech_stat",te) = 3),
    vm_deltaCap.fx("2010",regi,te,rlf) = 0;
    vm_deltaCap.fx("2015",regi,te,rlf) = 0;
    vm_cap.lo("2010",regi,te,rlf) = 0;
    vm_cap.lo("2015",regi,te,rlf) = 0;
    vm_cap.lo("2020",regi,te,rlf) = 0;
  );
);

no technologies with tech_stat 4 before 2025

vm_cap.fx(t,regi,te,rlf) $ (t.val <= 2020 and pm_data(regi,"tech_stat",te) = 4) = 0;
vm_capCum.fx(t0,regi,teLearn) $ (pm_data(regi,"tech_stat",teLearn) = 4) = 0;
vm_costTeCapital.fx(t,regi,teLearn) $ (t.val <= 2020 and pm_data(regi,"tech_stat",teLearn) = 4) = fm_dataglob("inco0",teLearn);
vm_deltaCap.fx(t,regi,te,rlf) $ (t.val <= 2025 and pm_data(regi,"tech_stat",te) = 5) = 0;
Capacity for nuclear energy
loop(t,
  if( ( t.val > 2010 ) AND ( t.val < 2030 ) AND ( cm_startyear <= t.val ),

The spin-up capacity from initialcap2 may be larger than historic capacities. For all regions but DEU, we don’t want to enforce early retirement, so we calculate the standing capacities resulting from 2005 capacities and normal technical depreciation. For DEU, the explicit nuclear phaseout means that capacities are phased down faster than the normal techincal lifetime

    p_CapFixFromRWfix(t,regi,"tnrs") $ (NOT sameas(regi,"DEU") ) = max( pm_aux_capLowerLimit("tnrs",regi,t) , pm_NuclearConstraint(t,regi,"tnrs") );
    p_CapFixFromRWfix(t,regi,"tnrs") $ ( sameas(regi,"DEU") ) = pm_NuclearConstraint(t,regi,"tnrs") ;  
    p_deltaCapFromRWfix(t,regi,"tnrs") = ( p_CapFixFromRWfix(t,regi,"tnrs") - pm_aux_capLowerLimit("tnrs",regi,t) )
                                    / 7.5;  !! this parameter is currently only for display and not further used to fix anything
    vm_cap.lo(t,regi,"tnrs","1") = 0.9 * p_CapFixFromRWfix(t,regi,"tnrs");
    vm_cap.up(t,regi,"tnrs","1") = 1.1 * p_CapFixFromRWfix(t,regi,"tnrs");
  );
);
if(cm_startyear <= 2030, !! require the realization of at least 50% of the max additions until 2030 (estimated at 80% of plants currently under construction) 
   vm_deltaCap.lo("2030",regi,"tnrs","1") = 0.50 * pm_NuclearConstraint("2030",regi,"tnrs") / 5;
   vm_deltaCap.up("2030",regi,"tnrs","1") = pm_NuclearConstraint("2030",regi,"tnrs") / 5; 
);
if(cm_startyear <= 2035, !! upper bound calculated in mrremind/R/calcCapacityNuclear.R: 50% of planned and 30% of proposed plants, plus extra for lifetime extension and newcomers
   vm_deltaCap.up("2035",regi,"tnrs","1") = pm_NuclearConstraint("2035",regi,"tnrs") / 5;
);
if(cm_startyear <= 2040, !! upper bound calculated in mrremind/R/calcCapacityNuclear.R: 50% of planned and 70% of proposed plants, plus extra for lifetime extension and newcomers
   vm_deltaCap.up("2040",regi,"tnrs","1") = pm_NuclearConstraint("2040",regi,"tnrs") / 5;
);
display p_CapFixFromRWfix, p_deltaCapFromRWfix;

switch to prevent new nuclear capacities after 2025, until then all currently planned plants are built

if(cm_nucscen = 5,
  vm_deltaCap.up(t,regi_nucscen,"tnrs",rlf) $ (t.val > 2025) = 1e-6;
  vm_cap.lo(t,regi_nucscen,"tnrs",rlf) $ (t.val > 2025) = 0;
);

3. Assumptions on biomass

Traditional biomass use is phased out on an exogeneous time path Developed regions phase out quickly (no new capacities)

vm_deltaCap.fx(t,regi,"biotr",rlf) $ (t.val > 2005) = 0;

Developing regions (defined by GDP PPP threshold) phase out more slowly (+ varied by SSP)

loop(regi,
  if( (pm_gdp("2005",regi) / pm_pop("2005",regi) / pm_shPPPMER(regi)) < 4,
    vm_deltaCap.fx("2010",regi,"biotr","1") = 1.3  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2015",regi,"biotr","1") = 0.9  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2020",regi,"biotr","1") = 0.7  * vm_deltaCap.lo("2005",regi,"biotr","1");
$ifthen not %cm_tradbio_phaseout% == "fast" !! cm_tradbio_phaseout
    vm_deltaCap.fx("2025",regi,"biotr","1") = 0.5  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2030",regi,"biotr","1") = 0.4  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2035",regi,"biotr","1") = 0.3  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2040",regi,"biotr","1") = 0.2  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2045",regi,"biotr","1") = 0.15 * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2050",regi,"biotr","1") = 0.1  * vm_deltaCap.lo("2005",regi,"biotr","1");
    vm_deltaCap.fx("2055",regi,"biotr","1") = 0.1  * vm_deltaCap.lo("2005",regi,"biotr","1");
$endif
  );
);

Quick phaseout in SSP1 and SSP5

$if %cm_GDPpopScen% == "SSP1"   vm_deltaCap.fx(t,regi,"biotr","1") $ (t.val > 2020) = 0.5 * vm_deltaCap.lo(t,regi,"biotr","1");
$if %cm_GDPpopScen% == "SSP5"   vm_deltaCap.fx(t,regi,"biotr","1") $ (t.val > 2020) = 0.5 * vm_deltaCap.lo(t,regi,"biotr","1");

Quickest phaseout in SDP scenarios (no new capacities allowed)

$if %cm_GDPpopScen% == "SDP"    vm_deltaCap.up(t,regi,"biotr","1") $ (t.val > 2020) = 0;
$if %cm_GDPpopScen% == "SDP_EI" vm_deltaCap.up(t,regi,"biotr","1") $ (t.val > 2020) = 0;
$if %cm_GDPpopScen% == "SDP_MC" vm_deltaCap.up(t,regi,"biotr","1") $ (t.val > 2020) = 0;
$if %cm_GDPpopScen% == "SDP_RC" vm_deltaCap.up(t,regi,"biotr","1") $ (t.val > 2020) = 0;

Switch to deactivate technologies that produce liquids from lignocellulosic biomass

if(c_bioliqscen = 0, !! no bioliquids technologies
  vm_deltaCap.up(t,regi,"bioftrec",rlf)  $ (t.val > 2005) = 1e-6;
  vm_deltaCap.up(t,regi,"bioftcrec",rlf) $ (t.val > 2005) = 1e-6;
  vm_deltaCap.up(t,regi,"bioethl",rlf)   $ (t.val > 2005) = 1e-6;
  vm_deltaCap.up(t,regi,"biopyrliq",rlf) $ (t.val > 2025) = 1e-8;
);

Switch to prevent new capacities of 1st generation biofuel technologies after 2030, allowing more cost-efficient and more sustainable new generation of biofuel technologies free entrance to the market

if(cm_1stgen_phaseout = 1,
   vm_deltaCap.up(t,regi,"bioeths",rlf)   $ (t.val > 2030) = 0;
   vm_deltaCap.up(t,regi,"biodiesel",rlf) $ (t.val > 2030) = 0;
);

Switch to deactivate technologies that produce hydrogen from lignocellulosic biomass

if(c_bioh2scen = 0, !! no bioh2 technologies
  vm_deltaCap.up(t,regi,"bioh2",rlf)  $ (t.val > 2005) = 1e-6;
  vm_deltaCap.up(t,regi,"bioh2c",rlf) $ (t.val > 2005) = 1e-6;
);

Switches to activate pyrolysis technologies

loop(teBiopyr(te) $ (not sameas(te, "biopyrliq")), !! established industrial technologies
  vm_cap.fx(t,regi,te,rlf) $ (t.val <= 2015) = 0; 
  if(c_biopyrOptions eq 0,
    vm_deltaCap.fx(t,regi,te,rlf) $ (t.val >= cm_startyear) = 0; 
  else
    vm_cap.up("2020",regi,te,rlf) = p_boundCapBiochar("2020",regi) * sm_tBC_2_TWa / 3; 
    vm_cap.lo("2025",regi,te,rlf) = p_boundCapBiochar("2025",regi) * sm_tBC_2_TWa / 3; 
    !! set upper bound to 70% above the lower bound which is based on 2024 values    
    vm_cap.up("2025",regi,te,rlf) = 1.7 * p_boundCapBiochar("2025",regi) * sm_tBC_2_TWa / 3;                      
  );
);
loop(te $ sameas(te, "biopyrliq"), !! does not yet exist commercially
  vm_cap.fx(t,regi,"biopyrliq",rlf)  $ (t.val <= 2025) = 0;
  vm_deltaCap.lo(t,regi,"biopyrliq",rlf) $ (t.val > cm_startyear) = 1e-8; !! initiate a negligible increase to help model find the technology
  vm_deltaCap.up(t,regi,"biopyrliq",rlf) $ (t.val > cm_startyear) = inf; !! revert fixing to small values above
  if(c_biopyrOptions le 1,
  vm_deltaCap.fx(t,regi,"biopyrliq",rlf) $ (t.val >= cm_startyear) = 0;
  );
);

4. Assumptions on carbon management

Carbon capture is a positive variable

vm_emiTe.lo(ttot,regi,"cco2") = 0;

no CCS at all in 2010

vm_cap.fx("2010",regi,teCCS,rlf) = 0;

no BECCS in 2020

vm_cap.fx("2020",regi,te,rlf) $ (teBio(te) and teCCS(te)) = 0;

switch to deactivate carbon sequestration

if(c_ccsinjecratescen = 0,
  vm_co2CCS.fx(t,regi_capturescen,"cco2","ico2",te,rlf) $ teCCS2rlf(te,rlf) = 0;
);

Bounds on maximum annual carbon storage by region Upper limits on regional annual injection rates are calculated as percentage of total storage potential
DK 20100929: default value (pm_ccsinjecrate= 0.5%) is consistent with Interview Gerling (BGR) (http://www.iz-klima.de/aktuelles/archiv/news-2010/mai/news-05052010-2/): 12 Gt storage potential in Germany, 50-75 Mt/a injection => 60 Mt/a => 60/12000=0.005

if(c_ccsinjecratescen > 0,
  vm_co2CCS.up(t,regi,"cco2","ico2","ccsinjeon","1")  = pm_dataccs(regi,"quan","ccsinjeon")  * pm_ccsinjecrate(regi);
  vm_co2CCS.up(t,regi,"cco2","ico2","ccsinjeoff","1") = pm_dataccs(regi,"quan","ccsinjeoff") * pm_ccsinjecrate(regi);

Near-term limits derived from CCUS project announcements Lower limit for 2020-2030 is capacities of all projects that are operational (2020-2030) from project data base Upper limit for 2025 and 2030 additionally includes all projects under construction and 30% (default, or changed by c_fracRealfromAnnouncedCCScap2030) of announced/planned projects from project data base See also corresponding code in input validation data preparation in mrremind/R/calcProjectPipeline.R. In nash-mode regions cannot easily share ressources, therefore CCS potentials are redistributed in Europe in data preprocessing in mrremind: Potential of EU27 regions is pooled and redistributed according to GDP (Only upper limit for 2030) Norway and UK announced to store CO2 for EU27 countries. So 50% of Norway and UK potential in 2030 is attributed to EU27-Pool Furthermore we restrict 2035 capacities to a maximum of 2.5 times 2030 capacities, assuming an optimistic 20 percent annual growth. Regions without project announcements (IND, REF) are assigned an upper limit of 10 Mt storage per year in 2035.

  if(not cm_emiscen = 1, !! cm_emiscen 1 = BAU
    vm_co2CCS.lo(t,regi,"cco2","ico2","ccsinjeon","1") $ (t.val <= 2030) = sm_MtCO2_2_GtC * p_boundCapCCS(t,regi,"operational") $ (t.val <= 2030);
    vm_co2CCS.up(t,regi,"cco2","ico2","ccsinjeon","1") $ (t.val <= 2030) = sm_MtCO2_2_GtC * (
        p_boundCapCCS(t,regi,"operational") $ (t.val <= 2030)
      + p_boundCapCCS(t,regi,"construction") $ (t.val <= 2030)
      + p_boundCapCCS(t,regi,"planned") $ (t.val <= 2030) * c_fracRealfromAnnouncedCCScap2030);
      !! DKX: assumptions for ccsinjeoff
    vm_co2CCS.up(t,regi,"cco2","ico2","ccsinjeon","1") $ (t.val = 2035) =
      2.5 * sm_MtCO2_2_GtC * (
        p_boundCapCCS("2030",regi,"operational")
        + p_boundCapCCS("2030",regi,"construction")
        + p_boundCapCCS("2030",regi,"planned") * c_fracRealfromAnnouncedCCScap2030
      );
    loop(regi,
      if( ((p_boundCapCCS("2030",regi,"operational") + p_boundCapCCS("2030",regi,"construction") + p_boundCapCCS("2030",regi,"planned")) = 0),
        vm_co2CCS.up(t,regi,"cco2","ico2","ccsinjeon","1") $ (t.val = 2035) = 10 * sm_MtCO2_2_GtC;
      );
    );
  );
);

switch to deactivate carbon capture technologies

if(cm_emiscen = 1,
  vm_cap.fx(t,regi,teCCS,rlf) = 0;
);
if(cm_ccapturescen = 2, !! no carbon capture at all
  vm_cap.fx(t,regi_capturescen,teCCS,rlf) = 0;
  vm_cap.fx(t,regi_capturescen,te,rlf) $ teCCS2rlf(te,rlf) = 0;
elseif(cm_ccapturescen = 3), !! no bio carbon capture:
  vm_cap.fx(t,regi_capturescen,te,rlf) $ (teCCS(te) and teBio(te)) = 0;
elseif(cm_ccapturescen = 4), !! no carbon capture in the electricity sector
  loop(emi2te(enty,"seel",te,"cco2") $ ( sum(regi_capturescen, pm_emifac("2020",regi_capturescen,enty,"seel",te,"cco2")) > 0 ),
    loop(te2rlf(te,rlf),
      vm_cap.fx(t,regi_capturescen,te,rlf) = 0;
    );
  );
);

Fix capacities of technologies with carbon capture to zero if there are no CCS projects in the pipeline in that region

loop(regi,
  loop(t $ (t.val <= 2030),
    if( ((p_boundCapCCS(t,regi,"operational") + p_boundCapCCS(t,regi,"construction") + p_boundCapCCS(t,regi,"planned")) = 0),
      vm_cap.fx(t,regi,teCCS,rlf) = 0;
    );
  );
);

Limit REMINDs ability to vent captured CO2 to 1 MtCO2 per yr per region. This happens otherwise to a great extend in stringent climate policy scenarios if CCS and CCU capacities are limited in early years, to lower overall adjustment costs of capture technologies.

v_co2capturevalve.up(t,regi) = 1 * sm_MtCO2_2_GtC;
Assumptions on leakage in the CCUS chain:
  1. Leakage from CO2 capture and transportation: 1 percent of captured CO2 leaks back to the atmosphere and is directly deduced from each technology’s capture rate See s_co2pipe_leakage in datainput.
  2. Leakage from the geological reservoir: NOT considered in REMIND. Justification: effect is too small According to Alcalde et al. 2018 DOI: 10.1038/s41467-018-04423-1 “An unrealistic scenario, where CO2 storage is inadequately regulated, estimates that more than 78% will be retained over 10,000 years.” Relating these numbers to REMIND scenarios: Let R(t) be the fraction remaining after time t with (simplified) constant leakage rate k: R(t)=e^(kt) with R(10 000) = 0.78 leakage rate k = 0.0025% / yr After 100 years, this leads to a loss of 0.25% from the reservoirs so in the “unrealistic scenario” for every 400 GtCO2 stored, 1 GtCO2 leaks after 100 years. #### 5. Early retirement and phase-out of technologies Early Retirement Early retirement of capacities is not possible as long as vm_capEarlyReti is fixed to zero. If early retirement should be activated, vm_capEarlyReti is allowed to increase up to one. One means that 100% of standing capacity of this technology is retired and does not produce output in this time step. allow early retirement only for technologies in teEarlyReti
vm_capEarlyReti.up(t,regi,te)$( NOT(teEarlyReti(te))) = 0;
vm_capEarlyReti.up(t,regi,teEarlyReti) = 1;
$ifthen.tech_earlyreti not "%c_tech_earlyreti_rate%" == "off"

allow early retirement also for technology and region combinations as defined by c_tech_earlyreti_rate switch

loop((ext_regi,te) $ p_techEarlyRetiRate(ext_regi,te),
  vm_capEarlyReti.up(t,regi,te) $ (regi_group(ext_regi,regi)) = 1;
);
$endif.tech_earlyreti
vm_capEarlyReti.up(ttot,regi,te) $ (ttot.val < 2010 or ttot.val > 2110) = 0;
loop(regi$(NOT(regi_group("USA_regi",regi) or regi_group("EUR_regi",regi))),
  vm_capEarlyReti.up(t,regi,te) $ (t.val <= 2030) = 0;
);
vm_capEarlyReti.lo(t,regi,teEarlyReti) $ ( vm_capEarlyReti.up(t,regi,teEarlyReti) eq 1 and t.val > 2010 and t.val <= 2100) = 1e-4;

Phase-out of technologies Switch off coal-h2 hydrogen investments after 2020, and gas-h2 investments after 2030. Our current seh2 hydrogen represents only additional (clean) hydrogen use cases to current ones. However, as we have too high H2 demand in 2025 and 2030 from the input data, we need to allow grey hydrogen for these time periods to meet the hydrogen demand which cannot be fully met by incoming low-carbon H2 techologies. This should be removed once FE H2 industry input data is adapted. It is allowed before 2020 to not make the model infeasible for low demands of hydrogen in that year.

vm_deltaCap.fx(t,regi,"coalh2",rlf) $ (t.val >= 2020) = 0;
vm_deltaCap.fx(t,regi,"gash2",rlf) $ (t.val > 2030) = 0;
vm_cap.lo(t,regi,"coalh2",rlf) $ (t.val >= 2020) = 0;
vm_cap.lo(t,regi,"gash2",rlf) $ (t.val > 2030) = 0;
$ifthen %c_SSP_forcing_adjust% == "forcing_SSP1"
  vm_deltaCap.up(t,regi,"coalftrec","1")  $ (t.val > 2005) = 1e-6; 
  vm_deltaCap.up(t,regi,"coalftcrec","1")  $ (t.val > 2005) = 1e-6; 
  vm_cap.lo(t,regi,"coalftrec","1")  $ (t.val > 2005) = 0; !! also relax the lower bound on vm_cap to prevent infeasibilities when vm_capEarlyReti is already close to 1
  vm_cap.lo(t,regi,"coalftcrec","1")  $ (t.val > 2005) = 0; !! also relax the lower bound on vm_cap to prevent infeasibilities when vm_capEarlyReti is already close to 1
  vm_deltaCap.up(t,regi,"coalgas",rlf) $ (t.val > 2010) = 1e-5;
$endif
$ifthen %c_SSP_forcing_adjust% == "forcing_SSP2"
if(cm_emiscen > 1,
  vm_deltaCap.up(t,regi,"coalftcrec","1")  $ (t.val > 2005)  = 1e-7; 
  vm_cap.lo(t,regi,"coalftcrec","1")  $ (t.val > 2005) = 0; !! also relax the lower bound on vm_cap to prevent infeasibilities when vm_capEarlyReti is already close to 1
);
$endif

6. Energy demand sectors and final energy

upper and lower bounds on FE carrier shares

v_shfe.up(t,regi,entyFe,sector) $ pm_shfe_up(t,regi,entyFe,sector) = pm_shfe_up(t,regi,entyFe,sector);
v_shfe.lo(t,regi,entyFe,sector) $ pm_shfe_lo(t,regi,entyFe,sector) = pm_shfe_lo(t,regi,entyFe,sector);

upper and lower bounds on gases+liquids share in FE

v_shGasLiq_fe.up(t,regi,sector) $ pm_shGasLiq_fe_up(t,regi,sector) = pm_shGasLiq_fe_up(t,regi,sector);
v_shGasLiq_fe.lo(t,regi,sector) $ pm_shGasLiq_fe_lo(t,regi,sector) = pm_shGasLiq_fe_lo(t,regi,sector);

Set H2 upper bound in buildings for years defined at cm_H2InBuildOnlyAfter

vm_demFeSector.up(t,regi,"seh2","feh2s","build",emiMkt) $ (t.val <= cm_H2InBuildOnlyAfter) = 1e-6;

upper bound on bioliquids as a share of transport liquids

v_shBioTrans.up(t,regi) $ (t.val > 2020) = c_shBioTrans;

7. Assumptions for emissions

vm_emiMacSector.lo(t,regi,enty) = 0;
vm_emiMacSector.lo(t,regi,"co2luc") = -5.0; !! afforestation can lead to negative emissions
vm_emiMacSector.lo(t,regi,"n2ofertsom") = -1; !! small negative emissions can result from human activity
vm_emiMac.fx(t,regi,"so2") = 0;
vm_emiMac.fx(t,regi,"bc") = 0;
vm_emiMac.fx(t,regi,"oc") = 0;
vm_emiFgas.fx(ttot,all_regi,all_enty) = f_emiFgas(ttot,all_regi,"%c_SSP_forcing_adjust%","%cm_rcp_scen%","SPA0",all_enty);
display vm_emiFgas.L;

Other bounds

Bounds on 1st generation biomass annual production

1st generation biofuel quantities (from sugar/starch and oil crops) are not endogenously modeled but follow exogenous trajectories from IEA and FAO data and some future projections for the near term (until 2030). To align data with MAgPIE we mostly rely on FAO data for historic feedstock quantities, so vm_fuExtr is fixed to values from p30_datapebio, coming from FAO. Additionally there is the constraint to match historical capacities for the respective conversion technologies in 2005 from the IEA. Thus, the bound on vm_fuExtr is only applied from 2010 on (in 2005 feedstock quantities are fully determined via p05_cap0). However, in some cases the capacities that were build in 2005 or before require a feedstock supply that is higher than what the FAO-based bound on vm_fuExtr would allow for, i.e., FAO and IEA data do not match. In that case we relax the upper bound for all time steps such that the 2005 capacity constraint implcitly derived from IEA can still be matched. Eventually the lower bound is set to (almost) the upper bound to enforce matching the historical feedstock quantities. Please note that the link between capacity additions vm_deltaCap and the feedstock quantities basically follows what happens in the equations qm_fuel2pe, q_balPe, q_transPe2se, q_limitCapSe and q_cap. It is a bit simplified here, assuming that there is a one to one mapping between PE (pebios, pebioil) and the respective conversion technologies (bioeths, biodiesel, respectively), which is currently the case. If this changes in the future (which is unlikely), this part needs to be adapted.

vm_fuExtr.up(t, regi, "pebios", "5")$(t.val ge 2010 AND t.val ge cm_startyear) = 1.01 * max(
  !! Use original bounds based on (mainly) FAO inpout data.
  p30_datapebio(regi,"pebios","5","maxprod",t),
  !! If historic capacities from IEA input require a larger feedstock supply,
  !! relax the bound in 2010 and in all following time steps. We assume that
  !! the bound should never fall below the feedstock supply in 2005. For that
  !! we convert the sum of all (depreciated) historic capacity additions
  !! `vm_deltaCap` in 2005 to feedstock supply quantities.
    1 / pm_eta_conv(t,regi,"bioeths") * pm_cf(t,regi,"bioeths") * pm_dataren(regi,"nur","1","bioeths")
  * sum(ttot$(ttot.val eq 2005),
      sum(opTimeYr2te("bioeths",opTimeYr) $ (tsu2opTimeYr(ttot,opTimeYr) AND (opTimeYr.val ge 1)),
          pm_ts(ttot - (pm_tsu2opTimeYr(ttot,opTimeYr) - 1))
        * pm_omeg(regi,opTimeYr+1,"bioeths")
        * vm_deltaCap.up(ttot - (pm_tsu2opTimeYr(ttot,opTimeYr) - 1),regi,"bioeths","1")
      )
    )
  );
vm_fuExtr.lo(t, regi, "pebios", "5")$(t.val ge 2010 AND t.val ge cm_startyear) =  0.98 * vm_fuExtr.up(t, regi, "pebios", "5");
vm_fuExtr.up(t, regi, "pebioil", "5")$(t.val ge 2010 AND t.val ge cm_startyear) = 1.01 * max(
  !! Use original bounds based on (mainly) FAO inpout data.
  p30_datapebio(regi,"pebioil","5","maxprod",t),
  !! If historic capacities from IEA input require a larger feedstock supply,
  !! relax the bound in 2010 and in all following time steps. We assume that
  !! the bound should never fall below the feedstock supply in 2005. For that
  !! we convert the sum of all (depreciated) historic capacity additions
  !! `vm_deltaCap` in 2005 to feedstock supply quantities.
    1 / pm_eta_conv(t,regi,"biodiesel") * pm_cf(t,regi,"biodiesel") * pm_dataren(regi,"nur","1","biodiesel")
  * sum(ttot$(ttot.val eq 2005),
      sum(opTimeYr2te("biodiesel",opTimeYr) $ (tsu2opTimeYr(ttot,opTimeYr) AND (opTimeYr.val ge 1)),
          pm_ts(ttot - (pm_tsu2opTimeYr(ttot,opTimeYr) - 1))
        * pm_omeg(regi,opTimeYr+1,"biodiesel")
        * vm_deltaCap.up(ttot - (pm_tsu2opTimeYr(ttot,opTimeYr) - 1),regi,"biodiesel","1")
      )
    )
  );
vm_fuExtr.lo(t, regi, "pebioil", "5")$(t.val ge 2010 AND t.val ge cm_startyear) =  0.98 * vm_fuExtr.up(t, regi, "pebioil", "5");
if(cm_1stgen_phaseout=1,
  vm_fuExtr.lo(t,regi,"pebios","5")$(t.val gt 2030)  = 0;
  vm_fuExtr.lo(t,regi,"pebioil","5")$(t.val gt 2030) = 0;
);

Bounds on 2nd generation biomass annual production

  1. Bound on residues
p30_maxprod_residue(ttot,regi)     = max(p30_datapebio(regi,"pebiolc","2","maxprod",ttot), sum(teBioPebiolc, pm_pedem_res(ttot,regi,teBioPebiolc)));
vm_fuExtr.up(t,regi,"pebiolc","2") = p30_maxprod_residue(t,regi)*1.0001;
  1. Bound on purpose grown biomass
$ifthen.bioenergymaxscen not %cm_maxProdBiolc% == "off"
p30_max_pebiolc_path_glob(t) = %cm_maxProdBiolc% * sm_EJ_2_TWa;
p30_max_pebiolc_path_glob(t) = p30_max_pebiolc_path_glob(t) - sum(regi, p30_maxprod_residue(t,regi));
display p30_max_pebiolc_path_glob;
p30_max_pebiolc_dist_by_prod_grp("LAM_regi") = 4.34485;
p30_max_pebiolc_dist_by_prod_grp("OAS_regi") = 3.36905;
p30_max_pebiolc_dist_by_prod_grp("SSA_regi") = 1.73546;
p30_max_pebiolc_dist_by_prod_grp("EUR_regi") = 2.17023;
p30_max_pebiolc_dist_by_prod_grp("NEU_regi") = 0.42204;
p30_max_pebiolc_dist_by_prod_grp("MEA_regi") = 0.6659;
p30_max_pebiolc_dist_by_prod_grp("REF_regi") = 0.95342;
p30_max_pebiolc_dist_by_prod_grp("CAZ_regi") = 0.87566;
p30_max_pebiolc_dist_by_prod_grp("CHA_regi") = 4.79197;
p30_max_pebiolc_dist_by_prod_grp("IND_regi") = 2.80432;
p30_max_pebiolc_dist_by_prod_grp("JPN_regi") = 0.08197;
p30_max_pebiolc_dist_by_prod_grp("USA_regi") = 2.78513;
s30_max_pebiolc_dist_by_prod = sum(ext_regi, p30_max_pebiolc_dist_by_prod_grp(ext_regi));
p30_max_pebiolc_dist_by_prod(regi) = 0;
loop(ext_regi$p30_max_pebiolc_dist_by_prod_grp(ext_regi),
  if(sum(regi$regi_group(ext_regi,regi), pm_pebiolc_demandmag("2020",regi)) > 0,
    p30_max_pebiolc_dist_by_prod(regi)$regi_group(ext_regi,regi) =
        p30_max_pebiolc_dist_by_prod_grp(ext_regi) * sm_EJ_2_TWa
      * pm_pebiolc_demandmag("2020",regi)
      / sum(regi2$regi_group(ext_regi,regi2), pm_pebiolc_demandmag("2020",regi2));
  else
    p30_max_pebiolc_dist_by_prod(regi)$regi_group(ext_regi,regi) =
        p30_max_pebiolc_dist_by_prod_grp(ext_regi) * sm_EJ_2_TWa
      / sum(regi2$regi_group(ext_regi,regi2), 1);
  );
);
display p30_max_pebiolc_dist_by_prod;
p30_max_pebiolc_dist_by_prod_tot(t) = max(0,
  min( s30_max_pebiolc_dist_by_prod * sm_EJ_2_TWa,
       p30_max_pebiolc_path_glob(t) ));
p30_max_pebiolc_dist_by_prod_scaled(t,regi)$(sum(regi2, p30_max_pebiolc_dist_by_prod(regi2)) > 0) =
    p30_max_pebiolc_dist_by_prod(regi)
  * p30_max_pebiolc_dist_by_prod_tot(t)
  / sum(regi2, p30_max_pebiolc_dist_by_prod(regi2));
display p30_max_pebiolc_dist_by_prod_scaled;
p30_max_pebiolc_path_glob(t) = p30_max_pebiolc_path_glob(t) - p30_max_pebiolc_dist_by_prod_tot(t);

Calclate regional bounds with equal marginal costs from global bound

loop(ttot$(ttot.val ge cm_startyear),
     p30_max_pebiolc_dummy = 0;
     p30_pebiolc_price_dummy = 0.01;
     p30_fuelex_dummy(regi) = 0;
     while(p30_max_pebiolc_dummy < p30_max_pebiolc_path_glob(ttot),
           loop(regi$(NOT sameas(regi,'JPN')),
                if( p30_pebiolc_price_dummy > (i30_bioen_price_a(ttot,regi)) * 1.01,
                      p30_fuelex_dummy(regi) = (p30_pebiolc_price_dummy - i30_bioen_price_a(ttot,regi)) / i30_bioen_price_b(ttot,regi);
                 else
                      p30_fuelex_dummy(regi) = 0;
                );
           ); 
           p30_max_pebiolc_dummy = sum(regi, p30_fuelex_dummy(regi));
           p30_pebiolc_price_dummy = p30_pebiolc_price_dummy + 0.001;
     );
     p30_max_pebiolc_path(regi,ttot) = p30_fuelex_dummy(regi);
);
display p30_max_pebiolc_path;
p30_max_pebiolc_path(regi,ttot)$(ttot.val ge cm_startyear) =
    p30_max_pebiolc_path(regi,ttot)
  + p30_max_pebiolc_dist_by_prod_scaled(ttot,regi);
display p30_max_pebiolc_path;

According to EMF guidelines, the upper bound on total (residues+purpose) global biomass production does not include traditional biomass use. Since the demand for traditional biomass is already supplied by the residue grade we expand the purpose-grown grade by the demand for traditional biomass.

vm_fuExtr.up(t,regi,"pebiolc","1") = p30_max_pebiolc_path(regi,t) + pm_pedem_res(t,regi,"biotr");
$endif.bioenergymaxscen

Phase out capacities of bioenergy technologies that use

pebiolc as feedstock, if defined in config

if (cm_phaseoutBiolc eq 1,
    loop(t$(t.val ge max(2025, cm_startyear)),
        loop(regi,
            loop(te(teBioPebiolc),
                loop(rlf,
                    if(vm_deltaCap.up(t,regi,te,rlf) eq INF,
                       vm_deltaCap.up(t,regi,te,rlf) = 1e-6;
                    );
                );
            );
        );
    );
);

Model Bounds in Regipol Module (region-specific bounds with hard-coded regions)

These bounds are only active if in 47_regipol module the realization is regiCarbonPrice. They mostly refer to region-specific fixings of the model in European subregions to better represent historic or near-term values or specific policies of regions (e.g. national coal phase-out plans etc.).

Bounds for Germany
Bounds for Historic and Near-term Alignment

Power Sector

$ifThen.tech_bounds_2025 "%cm_tech_bounds_2025%" == "on"

Set bounds for renewable power capacity in 2025 based on recent and historic growth rates This limits wind and solar PV capacity additions for 2025 in light of recent slow developments as of 2023. Upper bound is double the historic maximum capacity addition in 2011-2020. In addition: Limit solar PV capacity to 120 GW in 2025 (2023-2027 average) given that we are at only 76 GW PV in 2023

loop(regi$(sameAs(regi,"DEU")),
  vm_deltaCap.up("2025",regi,"windon","1")=2*smax(tall$(tall.val ge 2011 and tall.val le 2020), pm_delta_histCap(tall,regi,"windon"));
  vm_deltaCap.up("2025",regi,"spv","1")=2*smax(tall$(tall.val ge 2011 and tall.val le 2020), pm_delta_histCap(tall,regi,"spv"));

2025 lower bounds for VRE capacities based on installed capacity by 2024 and recent yearly growth rates

  vm_cap.lo("2025",regi,"spv","1")=0.096+0.014;
  vm_cap.lo("2025",regi,"windon","1")=0.062+0.003;
  vm_cap.lo("2025",regi,"windoff","1")=0.009+0.001;
);
$endIf.tech_bounds_2025

make assumptions on minimum renewable power and heat pump growth for Germany between 2025 and 2030 and distinguish two different scenarios (“Current Policies” and “Optimistic”)

$ifthen.cm_VREminCap_Ger "%cm_VREminCap_Ger%" == "CurrPol"
    vm_deltaCap.lo("2030",regi,"windon","1")$(sameAs(regi,"DEU")) = 6/1000;
    vm_deltaCap.lo("2030",regi,"windoff","1")$(sameAs(regi,"DEU")) = 2/1000;
    vm_cap.lo("2030",regi,"geohe","1")$(sameAs(regi,"DEU")) = 7/1000;
$endIf.cm_VREminCap_Ger
$ifthen.cm_VREminCap_Ger "%cm_VREminCap_Ger%" == "Opt"
    vm_deltaCap.lo("2030",regi,"windon","1")$(sameAs(regi,"DEU")) = 7.5/1000;
    vm_deltaCap.lo("2030",regi,"windoff","1")$(sameAs(regi,"DEU")) = 3/1000;
    vm_cap.lo("2030",regi,"geohe","1")$(sameAs(regi,"DEU")) = 7/1000;
$endIf.cm_VREminCap_Ger

These bounds account for historic gas power development. TODO: Historical fixings should be done in the core the via input data from mrremind, this still needs to be moved

v47_prodSEtotal.up("2020",regi,"pegas","seel")$(sameAs(regi,"DEU"))= 0.36*sm_EJ_2_TWa;
$ifThen.tech_bounds_2025 "%cm_tech_bounds_2025%" == "on"
v47_prodSEtotal.up("2025",regi,"pegas","seel")$(sameAs(regi,"DEU"))= 0.4*sm_EJ_2_TWa;
$endIf.tech_bounds_2025

These bounds account for historic coal power development.

vm_cap.up("2020",regi,"pc","1")$((cm_startyear le 2020) and (sameas(regi,"DEU"))) = 38.028/1000;

This limits early retirement of coal power in Germany in 2020s to avoid extremly fast phase-out.

vm_capEarlyReti.up('2025',regi,'pc')$(sameAs(regi,"DEU")) = 0.65;

This aligns 2020 chp capcities for Germany with historic data (AGEB) most of district heating is provided by CHP plants. coal share of chp heat output to be between 20-25% of total district heating demand gas share of chp heat output to be between 50-55% of total district heating demand bio share of chp heat output to be between 15-25% of total district heating demand TODO: Historical fixings should be done in the core via input data from mrremind, this still needs to be moved

loop(regi$(sameAs(regi,"DEU")),
    loop(t$(t.val eq 2020),
        vm_cap.lo(t,regi,"coalchp","1")= 0.2
                                            * (pm_cesdata(t,regi,"feheb","quantity")
                                                + pm_cesdata(t,regi,"feheb","quantity"))
                                            / pm_eta_conv(t,regi,"tdhes")
                                            /  pm_prodCouple(regi,"pecoal","seel","coalchp","sehe")
                                            / pm_cf(t,regi,"coalchp");
        vm_cap.up(t,regi,"coalchp","1")= 0.25
                                            * (pm_cesdata(t,regi,"feheb","quantity")
                                                + pm_cesdata(t,regi,"feheb","quantity"))
                                            / pm_eta_conv(t,regi,"tdhes")
                                            /  pm_prodCouple(regi,"pecoal","seel","coalchp","sehe")
                                            / pm_cf(t,regi,"coalchp");
        vm_cap.lo(t,regi,"gaschp","1")= 0.5
                                            * (pm_cesdata(t,regi,"feheb","quantity")
                                                + pm_cesdata(t,regi,"feheb","quantity"))
                                            / pm_eta_conv(t,regi,"tdhes")
                                            /  pm_prodCouple(regi,"pegas","seel","gaschp","sehe")
                                            / pm_cf(t,regi,"gaschp");
        vm_cap.up(t,regi,"gaschp","1")= 0.55
                                            * (pm_cesdata(t,regi,"feheb","quantity")
                                                + pm_cesdata(t,regi,"feheb","quantity"))
                                            / pm_eta_conv(t,regi,"tdhes")
                                            /  pm_prodCouple(regi,"pegas","seel","gaschp","sehe")
                                            / pm_cf(t,regi,"gaschp");
        vm_cap.lo(t,regi,"biochp","1")= 0.15
                                            * (pm_cesdata(t,regi,"feheb","quantity")
                                                + pm_cesdata(t,regi,"feheb","quantity"))
                                            / pm_eta_conv(t,regi,"tdhes")
                                            /  pm_prodCouple(regi,"pebiolc","seel","biochp","sehe")
                                            / pm_cf(t,regi,"biochp");
        vm_cap.up(t,regi,"biochp","1")= 0.25
                                            * (pm_cesdata(t,regi,"feheb","quantity")
                                                + pm_cesdata(t,regi,"feheb","quantity"))
                                            / pm_eta_conv(t,regi,"tdhes")
                                            /  pm_prodCouple(regi,"pebiolc","seel","biochp","sehe")
                                            / pm_cf(t,regi,"biochp");
    );
);

Carbon Management

only start industry carbon capture in Germany by 2030 as status of projects for 2025 unclear, see IEA CCUS database https://www.iea.org/data-and-statistics/data-tools/ccus-projects-explorer

vm_emiIndCCS.up(t,regi,emiInd37)$(sameAs(regi,"DEU") AND t.val lt 2030)=0;
Bounds for Germany-specific Policies (activated by switches)

If c_noPeFosCCDeu = 1 chosen, fossil CCS for energy system technologies (pe2se) is forbidden.

vm_emiTeDetail.up(t,regi,peFos,entySe,teFosCCS,"cco2")$((sameas(regi,"DEU")) AND (cm_noPeFosCCDeu = 1)) = 1e-4;

If cm_deuCDRmax >= 0, limit German CDR amount (Energy system BECCS, DACCS, EW and negative Landuse Change emissions) to cm_deuCDRmax. Convert cm_deuCDRmax from MtCO2/yr to model unit of GtC/yr.

vm_emiCdrAll.up(t,regi)$((cm_deuCDRmax ge 0) AND (sameas(regi,"DEU"))) = cm_deuCDRmax / 1000 / sm_c_2_co2;
vm_emiCdrAll.up(t,regi)$((cm_EURCDRmax ge 0) AND (sameas(regi,"EUR"))) = cm_EURCDRmax / 1000 / sm_c_2_co2;

Bounds for German Energy Security Scenario (activated by switches) Background: The energy security scenario used for the Ariadne Report on energy sovereignity in 2022 assumes that there is a continued gas crisis after 2022/23 in Germany with higher gas prices (see cm_EnSecScen_price) or limits to gas consumption (see cm_EnSecScen_limit switch) in the medium-term. Moreover, this scenario is characterized by a more pronounced role of coal power in the short-term as well as a greater role of industrial relocation and behavioral and energy efficiency transformations in demand sectors. Bounds in this section refer to energy supply technologies only.  
Policy in energy security scenario for Germany: 5GW(el) electrolysis installed by 2030 in Germany at minimum.

$ifThen.ensec "%cm_Ger_Pol%" == "ensec"
    vm_cap.lo("2030",regi,"elh2","1")$(sameAs(regi,"DEU"))=5*pm_eta_conv("2030",regi,"elh2")/1000;
$endIf.ensec

Policy in energy security scenario for Germany: increase coal power capacity factors and decrease gas power capacity factors until 2030 to account for short-term gas to coal switch under the assumption of a continued gas crisis.

$ifThen.ensec "%cm_Ger_Pol%" == "ensec"
    vm_capFac.up("2025",regi,"pc")$sameas(regi,"DEU") = 0.6;
    vm_capFac.up("2030",regi,"pc")$sameas(regi,"DEU") = 0.6;
    vm_capFac.fx("2025",regi,"ngcc")$sameas(regi,"DEU") = 0.2;
    vm_capFac.lo("2030",regi,"ngcc")$sameas(regi,"DEU") = 0.2;
$endIf.ensec

Policy in energy security scenario for Germany activated by cm_EnSecScen_limit: Limit PE gas demand from 2025 on to cm_EnSecScen_limit (in EJ/yr) gas imports + domestic gas in Germany.

if (cm_EnSecScen_limit gt 0,
    vm_prodPe.up(t,regi,"pegas")$((t.val ge 2025) AND (sameas(regi,"DEU"))) = cm_EnSecScen_limit * sm_EJ_2_TWa;
);
Bounds for EU subregions
Bounds for historic and near-term Alignment

This account for historic coal power developments. Bounds for UKI region: 2019 capacity = 7TWh, capacity factor = 0.6 -> ~1.35GW -> Assuming no new capacity -> average 2018-2022 = ~ 1GW

vm_cap.up("2020",regi,"pc","1")$((cm_startyear le 2020) and (sameas(regi,"UKI"))) = 1.3/1000; 
Bounds for EU-specific policies (activated by switches)

This accounts for different nuclear power policies that can be chosen for the EU subregions. Basic nuclear policies:

$IFTHEN.NucRegiPol not "%cm_NucRegiPol%" == "off" 

Germany Nuclear phase-out

    vm_cap.up(t,regi,"tnrs","1")$((t.val ge 2025) and (t.val ge cm_startyear) and (sameas(regi,"DEU"))) = 1E-6;
    vm_cap.lo(t,regi,"tnrs","1")$((t.val ge 2025) and (t.val ge cm_startyear) and (sameas(regi,"DEU"))) = 0;

ESC -> no new Nuclear capacity (Italy had a plebiscite for this and Greece should not have any new capacity)

    vm_deltaCap.up(t,regi,"tnrs","1")$((t.val ge 2020) and (t.val ge cm_startyear) and (sameas(regi,"ESC"))) = 0;

Neither France, ENC, NEN, ECS, ESW or ECE currently plan to early-retire any of their current fleet until 2050

    vm_capEarlyReti.up(t,regi,"tnrs") $ ( (t.val ge cm_startyear) AND (t.val le 2050) AND (sameas(regi,"FRA")) ) = 1e-3;
    vm_capEarlyReti.up(t,regi,"tnrs") $ ( (t.val ge cm_startyear) AND (t.val le 2050) AND (sameas(regi,"ENC")) ) = 1e-3;
    vm_capEarlyReti.up(t,regi,"tnrs") $ ( (t.val ge cm_startyear) AND (t.val le 2050) AND (sameas(regi,"NEN")) ) = 1e-3;
    vm_capEarlyReti.up(t,regi,"tnrs") $ ( (t.val ge cm_startyear) AND (t.val le 2050) AND (sameas(regi,"ECS")) ) = 1e-3;
    vm_capEarlyReti.up(t,regi,"tnrs") $ ( (t.val ge cm_startyear) AND (t.val le 2050) AND (sameas(regi,"ESW")) ) = 1e-3;
    vm_capEarlyReti.up(t,regi,"tnrs") $ ( (t.val ge cm_startyear) AND (t.val le 2050) AND (sameas(regi,"ECE")) ) = 1e-3;
$ENDIF.NucRegiPol  

Extended nuclear policies:

$IFTHEN.proNucRegiPol not "%cm_proNucRegiPol%" == "off" 

Pro nuclear countries tend to keep nuclear production by political decision assuming France would keep at least 80% of its 2015 nuclear capacity in the future.

vm_cap.lo(t,regi,"tnrs","1")$((t.val ge cm_startyear) AND (t.val ge 2030) AND (sameas(regi,"FRA"))) = 0.8*pm_histCap("2015",regi,"tnrs");

Assuming Czech Republic would keep at least its 2015 nuclear capacity in the future (CZE corresponds to 61.8% of nuclear capacity of ECE in 2015)

vm_cap.lo(t,regi,"tnrs","1")$((t.val ge cm_startyear) AND (t.val ge 2030) AND (sameas(regi,"ECE"))) = 0.618*pm_histCap("2015",regi,"tnrs");

Assuming Finland would keep at least its 2015 nuclear capacity in the future (FIN corresponds to 21.6% of nuclear capacity of ENC in 2015)

vm_cap.lo(t,regi,"tnrs","1")$((t.val ge cm_startyear) AND (t.val ge 2030) AND (sameas(regi,"ENC"))) = 0.216*pm_histCap("2015",regi,"tnrs");

Assuming Romania would keep at least its 2015 nuclear capacity in the future (ROU corresponds to 22.1% of nuclear capacity of ECS in 2015)

vm_cap.lo(t,regi,"tnrs","1")$((t.val ge cm_startyear) AND (t.val ge 2030) AND (sameas(regi,"ECS"))) = 0.221*pm_histCap("2015",regi,"tnrs");
$ENDIF.proNucRegiPol 

This accounts for different CCS policies that can be chosen for the EU subregions.

$IFTHEN.CCSinvestment not "%cm_CCSRegiPol%" == "off" 

earliest investment in Europe, with one timestep split between countries currently exploring - Norway (NEN), Netherlands (EWN) and UK (UKI) - and others

vm_deltaCap.up(t,regi,teCCS,rlf)$( (t.val lt %cm_CCSRegiPol%) AND (sameas(regi,"NEN") OR sameas(regi,"EWN") OR sameas(regi,"UKI"))) = 1e-6; 
vm_deltaCap.up(t,regi,teCCS,rlf)$( (t.val le %cm_CCSRegiPol%) AND (regi_group("EUR_regi",regi)) AND (NOT(sameas(regi,"NEN") OR sameas(regi,"EWN") OR sameas(regi,"UKI")))) = 1e-6;
$ENDIF.CCSinvestment

This accounts for different coal power phase-out policies that can be chosen for the EU subregions. It is based on Beyond Coal 2021 (https://beyond-coal.eu/2021/03/03/overview-of-national-phase-out-announcements-march-2021/), whith adjustment for possible delay in Italy.

$IFTHEN.CoalRegiPol not "%cm_CoalRegiPol%" == "off" 
    vm_cap.up(t,regi,te,"1")$((t.val ge 2025) and (t.val ge cm_startyear) and (sameas(te,"igcc") or sameas(te,"pc") or sameas(te,"coalchp")) and (sameas(regi,"ESW") or sameas(regi,"FRA") )) = 1E-6;
    vm_cap.up(t,regi,te,"1")$((t.val ge 2030) and (t.val ge cm_startyear) and (sameas(te,"igcc") or sameas(te,"pc") or sameas(te,"coalchp")) and (sameas(regi,"ENC") or sameas(regi,"ESC") or sameas(regi,"EWN") )) = 1E-6;

DEU coal-power capacity phase-out, upper bounds following the Kohleausstiegsgesetz from 2020. https://www.bmuv.de/themen/klimaschutz-anpassung/klimaschutz/nationale-klimapolitik/fragen-und-antworten-zum-kohleausstieg-in-deutschland

    vm_capTotal.up("2025",regi,"pecoal","seel")$(sameas(regi,"DEU"))=25/1000;
    vm_capTotal.up("2030",regi,"pecoal","seel")$(sameas(regi,"DEU"))=17/1000;
    vm_capTotal.up("2035",regi,"pecoal","seel")$(sameas(regi,"DEU"))=6/1000;
    vm_capTotal.up("2040",regi,"pecoal","seel")$(sameas(regi,"DEU"))=1E-6;

UK coal capacity phase-out

    vm_cap.up(t,regi,te,"1")$((t.val ge 2025) and (t.val ge cm_startyear) and (sameas(te,"igcc") or sameas(te,"pc") or sameas(te,"coalchp")) and (sameas(regi,"UKI"))) = 1E-6;
$ENDIF.CoalRegiPol  

Represent region-specific renewable power policies with minimum VRE shares over time.

$ifthen.cm_VREminShare not "%cm_VREminShare%" == "off"
  loop((ttot,ext_regi)$(p47_VREminShare(ttot,ext_regi)),
    loop(regi$(regi_group(ext_regi,regi)),
      v47_VREshare.lo(t,regi)$(t.val ge ttot.val) = p47_VREminShare(t,ext_regi);
    )
  )
;
$endIf.cm_VREminShare

This bounds fixes CES function quantity trajectories to exogenous data if cm_exogDem_scen is activated. It is used, for example, to hit specific, steel and cement production trajectories in policy scenarios for project-specific scenarios. It is not necessarily a policy but a different (exogenuous) assumption about future production trajectories than what REMIND produces endogenuously.

$ifthen.exogDemScen NOT "%cm_exogDem_scen%" == "off"
vm_cesIO.fx(t,regi,in)$(pm_exogDemScen(t,regi,"%cm_exogDem_scen%",in))=pm_exogDemScen(t,regi,"%cm_exogDem_scen%",in);
$endif.exogDemScen

This bound avoids hydrogen production from gas in the European region (unlikely to happen after recent gas trade changes)

vm_deltaCap.up(t,regi,"gasftrec",rlf)$((t.val gt 2005) and (regi_group("EUR_regi",regi))) = 0;
vm_deltaCap.up(t,regi,"gasftcrec",rlf)$((t.val gt 2005) and (regi_group("EUR_regi",regi))) = 0;

TODO: Historical fixings should be done in the core the via input data from mrremind, this still needs to be moved

$ifthen.chaCoalBounds not "%cm_chaCoalBounds%" == "off"
loop(regi$(sameAs(regi,"CHA")),
vm_deltaCap.lo("2025",regi,"pc","1") = 20 * 0.78 / 1e3;
vm_deltaCap.lo("2025",regi,"coalchp","1") = 20 * 0.22 / 1e3;
vm_deltaCap.lo("2030",regi,"pc","1") = 20 * 0.78 / 1e3;
vm_deltaCap.lo("2030",regi,"coalchp","1") = 20 * 0.22 / 1e3;
vm_capFac.fx("2020",regi,"pc") = 0.54;
vm_capFac.fx("2025",regi,"pc") = 0.438;
vm_capFac.fx("2030",regi,"pc") = 0.35;
vm_capFac.fx("2020",regi,"coalchp") = 0.54;
vm_capFac.fx("2025",regi,"coalchp") = 0.438;
vm_capFac.fx("2030",regi,"coalchp") = 0.35;
);
$endif.chaCoalBounds

Interfaces

Interface plot missing!

Realizations

References