Skip to content

JustMIP ES - #2437

Open
RahelMA wants to merge 14 commits into
remindmodel:developfrom
RahelMA:JustmipDefault
Open

JustMIP ES#2437
RahelMA wants to merge 14 commits into
remindmodel:developfrom
RahelMA:JustmipDefault

Conversation

@RahelMA

@RahelMA RahelMA commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Purpose of this PR

Concept of standard permit trading:

  1. Permit allocation is distributed via a certain rule e.g., POPint, CandC
  2. The trading permits are connected to regional emissions as a quantity constraint here.
  3. Quantity restricted permit trade scenarios run under cm_emiscen = 6 or 4

This PR introduces the 41_emicapregi realization JustMIP that allows for limited emission trading that relaxes the regional budget allocations in 45_carbonprice/functionalFormRegi.
With these central main differences compared to regular permit trading scenarios:

  1. Initial permit allocation is generously distributed to all regions! Trade restriction is only linked to the trading volume as 1% of global GDP and trade volume in valued in regional carbon prices.
q41_globalPermitTradeCap(t,regi)$(t.val gt 2025) ..
    sum(regi2,
        (vm_Xport(t,regi2,"perm") + vm_Mport(t,regi2,"perm"))*(1/sm_c_2_co2)
        * (pm_taxCO2eq(t,regi2))
    )
    =l=
    0.01 * p41_gdpGlob(t);
  1. Trading permits are NOT linked to emission quantities but relax the regional carbon budget in FunktionalFormRegi.
  2. Emission trading is now also allowed under a policy run cm_emiscen = 9 if cm_permTradingJustMip = 1. Emission permit are consistently treated in GtCO2eq. This still requires adjustments in remind2 for the correct unit output.

Changes in the configs

File comparison: /p/projects/rd3mod/github/repos/remindmodel/remind/develop/config/scenario_config_JustMIP.csv -> config/scenario_config_JustMIP.csv
Columns deleted: -
Columns added:   c_budgetscen, c_edgeTransportIter, c_magpieIter, cm_33_maxFeShare, cm_budgetCO2from2020RegiShare, cm_CPslopeAdjustment, cm_nash_autoconverge, cm_peakBudgYrRegi, cm_permitTradeFinalYr, cm_permitTradeRatio, cm_permittradescen, cm_permTradingJustMip, cm_taxCO2_IncAfterPeakBudgYr, cm_taxCO2_lowerBound_nr, cm_taxCO2_lowerBound_path_gdx_ref, cm_taxCO2_Shape, cm_useInputGdxForCarbonPrice, emicapregi, jpn_goes_wild
Renamed columns: -
Renamed rows:    -

Changes in the rows:
+ SSP1_800f_es1 was added.
+ SSP1_800f_es1_noTrading was added.
~ SSP2_dls1:
    start: 0 -> 1
    path_gdx_ref: SSP2-NPi2025-CES -> SSP2-NPi2025
    path_gdx_refpolicycost: Reference_SSP2_800f -> NA
    description: was changed (default: REMIND run with default settings)
    path_gdx_carbonprice: NA -> Reference_SSP2_800f
+ SSP2_dls1_800 was added.
~ SSP1_dls1:
    start: 0 -> 1
    path_gdx_ref: SSP2-NPi2025-CES -> SSP2-NPi2025
    path_gdx_refpolicycost: Reference_SSP1_800f -> NA
    description: was changed (default: REMIND run with default settings)
    path_gdx_carbonprice: NA -> Reference_SSP1_800f
+ SSP1_dls1_800 was added.
- SSP2-NPi2025-CES was deleted.

$allwarnings
NULL

File comparison: /p/projects/rd3mod/github/repos/remindmodel/remind/develop/config/scenario_config_magpie_JustMIP.csv -> config/scenario_config_magpie_JustMIP.csv
Columns deleted: -
Columns added:   path_mif_ghgprice_land
Renamed columns: -
Renamed rows:    -

Changes in the rows:
~ SSP2-NPi2025:
    start: 1 -> 0
~ SSP1-NPi2025:
    start: 1 -> 0
~ Reference_SSP1_800f:
    start: 1 -> 0
~ Reference_SSP2_800f:
    start: 1 -> 0
+ SSP1_800f_es1_noTrading was added.
+ SSP1_800f_es1_Trading_refRef was added.
+ SSP2_dls1_800 was added.
+ SSP1_dls1_800 was added.
- SSP2-NPi2025-CES was deleted.

$allwarnings
NULL

Scenarios including and excluding trade:
/p/projects/elevate/WP5.4/Tests_Rahel/CO2eqWP/compScen-Submission_V1_ES-2026-08-02_06.19.43-REMIND-MAgPIE.pdf

image image

Trade

image image

Strong trade price increase seems to motivate regions to change trading strategies

</style>
    pm_pvp perm pm_pvp good price in $/tCO2
2030 perm 0.00042 0.00464 90.25291
2035 perm 0.00043 0.00365 117.6696
2040 perm 0.00043 0.00279 153.3952
2045 perm 0.00043 0.00209 203.9378
2050 perm 0.00042 0.00156 271.848
2055 perm 0.00042 0.00119 355.5936
2060 perm 0.00043 0.00079 540.2535
2070 perm 0.00043 0.00058 738.1596
2080 perm 0.00043 0.00034 1246.955
2090 perm 0.00043 0.00022 1950.41
2100 perm 0.00043 0.00015 2867.72

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?):

Comment thread core/datainput.gms
if (c_ccsinjecratescen eq 6, s_ccsinjecrate = s_ccsinjecrate * 0.44 ); !! Intermediate estimate
pm_ccsinjecrate(regi) = s_ccsinjecrate;

if (jpn_goes_wild = 1,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Delete jpn_goes_wild, instead adjust in config file c_ccsinjecrateRegi for JPN

Comment thread core/postsolve.gms
- sum(se2fe(enty,enty2,te), !! subtract bunker emissions if cm_bunkerscen is eq 3 or 6
pm_emifac(ttot2,regi,enty,enty2,te,"co2")
* vm_demFeSector.l(ttot2,regi,enty,enty2,"trans","other"))$(c_budgetscen eq 3 OR c_budgetscen eq 6))
* vm_demFeSector.l(ttot2,regi,enty,enty2,"trans","other"))$(c_budgetscen eq 3 OR c_budgetscen eq 6))!! subtract net trade of permits if cm_emiscen is eq 6 or 4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If this applies to cm_emiscen eq 4, please adjust it in the line above, where eq 3 is still written

Comment thread core/postsolve.gms
- sum(se2fe(enty,enty2,te), !! subtract bunker emissions if cm_bunkerscen is eq 3 or 6
pm_emifac(ttot2,regi,enty,enty2,te,"co2")
* vm_demFeSector.l(ttot2,regi,enty,enty2,"trans","other"))$(c_budgetscen eq 3 OR c_budgetscen eq 6)
+ (vm_Xport.l(ttot2,regi,"perm") - vm_Mport.l(ttot2,regi,"perm"))*(1/sm_c_2_co2))!! subtract net trade of permits (units from CO2 to C)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Adjust vm_Xport and vm_Mport to GtC instead of conversion

p33_EW_maxShareOfCropland(regi)$(regi_groupExt(ext_regi, regi)) = f33_EW_maxShareOfCropland(ext_regi);
);

if (jpn_goes_wild = 1,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See comment above regarding jpn_goes_wild, should be adjusted via config cm_33_EW_maxShareOfCropland JPN 0.5

*** In later iterations, recalculate allocation from market emissions

!! Set bounds for permit allocation
vm_perm.lo(t,regi) = -10;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please explain logic and values for this and following line

Comment on lines +13 to +15
pm_emicapglob(t) = 100;
pm_shPerm(t,regi) = 1;
vm_perm.fx(t,regi) = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add further explanation for values

Comment thread main.gms
*' * (0): no numeric lower bound for the carbon price
*' * (any number > 0): numeric lower bound for the carbon price in $ per t CO2eq

parameter

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

remove switch also here please :)

);
);

*RM* Permit price growth reflects the carbon price trajectory

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

interesting that you made this choice! let's talk about whether it is necessary and/or wanted? Also in combination with the othre changes you make to the intertemporal budget equation of regions?


*AJS* starting policy runs from permit prices that are all zero doesnot work. start from 49$ price path instead
if((cm_emiscen ne 1) and (cm_emiscen ne 9) and (smax(t,pm_pvp(t,"perm"))) eq 0,
if((cm_emiscen ne 1 or (cm_emiscen ne 9 and cm_permTradingJustMip eq 0)) and (smax(t,pm_pvp(t,"perm"))) eq 0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this now means that it is active when cm_emiscen = 9 and cm_permTradingJustMIP = 1
Just checking that this is what you want?

!! "Very low" is for now <1 USD/t CO2 in 2100, tbd
else
if ((abs(p80_regionalBudget_absDev_iter(iteration,regi)) gt abs(cm_budgetCO2_absDevTol))
AND (pm_taxCO2eq("2100",regi) gt (1 * sm_DptCO2_2_TDpGtC)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the problem may also be the combination with the lower bound on carbon prices? I will have a look

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.

3 participants