Skip to content

Comments

update NDC realization to run 2030+2035 NDC emissions targets by default and clean up + extend on switches for NDC variants#2289

Merged
fschreyer merged 18 commits intoremindmodel:developfrom
fschreyer:NpiNDC
Feb 20, 2026
Merged

update NDC realization to run 2030+2035 NDC emissions targets by default and clean up + extend on switches for NDC variants#2289
fschreyer merged 18 commits intoremindmodel:developfrom
fschreyer:NpiNDC

Conversation

@fschreyer
Copy link
Contributor

@fschreyer fschreyer commented Feb 18, 2026

Purpose of this PR

This PR works over the realization of the NDC scenario in REMIND. The main changes are:

  • change default NDC scenario to new scenario including 2030 and 2035 emissions targets derived from PBL data (scenario config change still to-do)
  • remove / add switches to run NDC variants
    • cm_NDC_CO2PriceLimit
    • cm_NDC_postTargetDevelopment
    • cm_NDC_CO2PriceMinimum
    • cm_NDC_TargetCheckConv
    • cm_NDC_divergentScenario (removed)
  • clean-up NDC realization and improve documentation

Type of change

Indicate the items relevant for your PR by replacing ◻️ with ☑️.
Do not delete any lines. This makes it easier to understand which areas are affected by your changes and which are not.

Parts concerned

  • ☑️: GAMS Code
  • ◻️ R-scripts
  • ◻️ Documentation (GAMS incode documentation, comments, tutorials)
  • ◻️ Input data / CES parameters
  • ◻️ Tests, CI/CD (continuous integration/deployment)
  • ◻️ Configuration (switches in main.gms, default.cfg, and scenario_config*.csv files)
  • ◻️ Other (please give a description)

Impact

  • ◻️ Bug fix
  • ◻️ Refactoring
  • ☑️ New feature
  • ◻️ Change of parameter values or input data (including CES parameters)
  • ◻️ Minor change (default scenarios show only small differences)
  • ◻️ Fundamental change of results of default scenarios

Checklist

Do not delete any line. Leave unfinished elements unchecked so others know how far along you are.
In the end all checkboxes must be ticked before you can merge
.

  • I executed the automated model tests (make test) after my final commit and all tests pass (FAIL 0)
  • I adjusted the reporting in remind2 if and where it was needed
  • I adjusted the madrat packages (mrremind and other packages involved) for input data generation if and where it was needed
  • My code follows the coding etiquette
  • I explained my changes within the PR, particularly in hard-to-understand areas
  • I checked that the in-code documentation is up-to-date
  • I adjusted forbiddenColumnNames in readCheckScenarioConfig.R in case the PR leads to deprecated switches
  • I updated the CHANGELOG.md correctly (added, changed, fixed, removed, input data/calibration)

Further information (optional)

  • Runs with these changes are here:
  • Comparison of results (what changes by this PR?):
    /p/tmp/schreyer/Modeling/remind/Dev1/compScen-NDC_Current_vs_2030_vs_NDCallPF-2026-02-17_10.19.07-H12.pdf

New NDC is NDC_all_pf. Old NDC is SSP2-NDC-AMT.

Felix Schreyer added 14 commits January 8, 2026 20:59
…ion 2025_cond/uncond and improve documentation of NDC target versions
…p45_useSingleYearCloseTo as this is meanwhile done by switch cm_NDC_targetYear
…nd clean-up NDC post-target co2 price settings. This introduces new flags cm_NDC_CO2PriceLimit, cm_NDC_postTargetDevelopment, cm_NDC_CO2PriceMinimum
… emissions targets should be convergence criterion. By default, runs do not require NDC target compliance
…DC realization always iterates carbon prices
…al NDC targets based on latest PBL data) and switch on targets for 2030 and 2035 by default
@fschreyer fschreyer marked this pull request as ready for review February 20, 2026 09:46
Copy link
Contributor

@RahelMA RahelMA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, thank you! I just have minor documentation comments!

p45_taxCO2eqConvergenceYear = 3000;
);
*** initialize carbon price trajectory before target adjustment iterations by setting carbon price to NPi
pm_taxCO2eq(t,regi) = p45_taxCO2eq_bau(t,regi);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initializing on the NPi2025 is useful, have you check that we never are below? I just wonder if we also need a constraint NPI <= NDC e.g. with low 2035 NDC targets

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is taken care of by cm_NDC_CO2PriceMinimum = NPi which is the default setting now.

Scalar p45_minRatioOfCoverageToMax "only targets whose coverage is this times p45_bestNDCcoverage are considered. Use 1 for only best [0..1]" /1.0/;
Scalar p45_useSingleYearCloseTo "if 0: use all. If > 0: use only one single NDC target per country closest to this year (use 2030.4 to prefer 2030 over 2035 over 2025) [year]" /2030.4/;
Scalar p45_minRatioOfCoverageToMax "only targets whose coverage is this times p45_bestNDCcoverage are considered. Use 1 for only best [0..1]" /0/;
Scalar p45_useSingleYearCloseTo "if 0: use all. If > 0: use only one single NDC target per country closest to this year (use 2030.4 to prefer 2030 over 2035 over 2025) [year]" /0/;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Use NDC targets independent from coverage, top!
  2. I think with your change you use all targets in the input data, I asume thats ok as we only have 2030 and 2035 for Emissions_2026_cond, for other versions this would cause an error (e.g. 2024 also includes some 2050 targets) ... maybe you want to add a little warning note?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switch cm_NDC_targetYear = 2030, 2035 now only selects those two years.


if (not sameas("%cm_NDC_version%","2018_uncond"),
p45_factorTargetyear(t,regi)$(sameas(regi,"LAM") AND sameas(t,"2030")) = p45_factorTargetyear(t,regi) + 0.2;
p45_factorTargetyear(t,regi)$(sameas(regi,"LAM") AND sameas(t,"2035")) = p45_factorTargetyear(t,regi) + 0.2;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With these deletions, older version may have problems, but that ok, as we will remove them this summer ;)

p45_taxCO2eq_bau(ttot,all_regi) "level of CO2 taxes in business as usual run [T$/GtC]"
pm_NDCEmiTargetDeviation(ttot,all_regi) "deviation of REMIND emissions to NDC target emissions in last iteration normalized to NDC target emissions [0-1]"
$ifthen not "%cm_NDC_CO2PriceLimit%" == "off"
p45_CO2PriceLimitNDC(ttot,all_regi) "Upper limit of CO2 price in NDC realization, read from switch cm_NDC_CO2PriceLimit [$/tCO2]" / %cm_NDC_CO2PriceLimit% /
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we currently set the price limit in the config, that's nice!

pm_budgetDeviation,input,added by codeCheck
pm_regionalBudget_absDevTol,input,added by codeCheck
cm_startyear,input,not used
sm_D2005_2_D2017,input,not used
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to add this here? sm_D2005_2_D2017

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a code check request. Probably I deleted code using this before.

*#' calculate level of emission target per REMIND region. It is componsed to two terms:
*#' 1. Contribution of countries within REMIND region with NDC target:
*#' share of emissions covered by NDC in particular region * REMIND NPI emissions in 2015 * (country-aggregated) relative NDC emissions target with respect to 2015
*#' 2. Contribution of countries within REMIND region without NDC target:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice documentation

p45_CO2eqwoLU_goal(p45_NDCyearSet(t,regi)) =
p45_shareTarget(t,regi) * p45_BAU_reg_emi_wo_LU_wo_bunkers("2015",regi) * p45_factorTargetyear(t,regi) !! share with NDC target
+ (1-p45_shareTarget(t,regi)) * p45_BAU_reg_emi_wo_LU_wo_bunkers(t,regi); !! baseline for share of countries without NDC target
+ (1-p45_shareTarget(t,regi)) * p45_BAU_reg_emi_wo_LU_wo_bunkers(t,regi); !! baseline for share of countries without NDC target
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see it correctly, you have not changed the formula, right?

$ifthen.NDC "%carbonprice%" == "NDC"
$ifthen.targetCheck "%cm_NDC_TargetCheckConv%" == "on"
*** additional criterion: Were NDC emissions targets reached?
loop((t,regi)$pm_NDCEmiTargetDeviation(t,regi),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add the documentation what happens in pm_NDCEmiTargetDeviation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this only checking if the target is reached?

*' * (2026_uncond): all NDCs independent of international financial support published until end of 2025 (PBL collection), note that for countries / regions with target ranges (e.g. EU 66-72% 2035 target)
*' * the less ambitious target is chosen even if it is strictly speaking not an unconditional NDC target
*' * (2024_cond_extrapol): all NDCs conditional to international financial support published until August 31, 2024 with extrapolation of 2030 targets to 2035 targets for conutries without 2035 target
*' * (2024_uncond_extrapol): all NDCs independent of international financial support published until August 31, 2024 with extrapolation of 2030 targets to 2035 targets for conutries without 2035 target
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great documentation!

main.gms Outdated
*' * Note: including target years here does not mean they are automcatically considered in the carbonprice NDC realization.
*' * Depending on the p45_minRatioOfCoverageToMax parameter, each region receives the target year with the highest share of emissions covered under NDCs.
$setglobal cm_NDC_targetYear "2030" !! def = "2030"
$setglobal cm_NDC_targetYear "2030, 2035" !! def = "2030, 2035"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see we only have 2030 and 2035, so you can ignore my comment before ;)

@RahelMA
Copy link
Contributor

RahelMA commented Feb 20, 2026

Could you please provide the config changes in a readable format using
comparescenconf!

@fschreyer
Copy link
Contributor Author

Eventually, I realized I didn't need a scenario config change. I tested the new default NDC run here /p/tmp/schreyer/Modeling/remind/Dev1/output/SSP2-NDC_2026-02-20_10.02.30.

@fschreyer fschreyer merged commit 23604eb into remindmodel:develop Feb 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants