Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/declarations.gms
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,8 @@ parameters
pm_budgetCO2eq(all_regi) "budget for regional energy-emissions in period 1 [GtC]"
pm_actualbudgetco2(ttot) "actual level of cumulated emissions starting from 2020 [GtCO2]"
p_actualbudgetco2_iter(iteration,ttot) "track actual level of cumulated emissions starting from 2020 over iterations [GtCO2]"
pm_actualbudgetco2Regi(ttot,all_regi) "Regional- actual level of cumulated emissions starting from 2020 [GtCO2]"
p_actualbudgetco2Regi_iter(iteration,ttot,all_regi) "Regional- track actual level of cumulated emissions starting from 2020 over iterations [GtCO2]"

*** iteration parameters
pm_SolNonInfes(all_regi) "model status from last iteration. 1 means status 2 or 7, 0 for all other status codes"
Expand Down
13 changes: 13 additions & 0 deletions core/postsolve.gms
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,21 @@ pm_actualbudgetco2(ttot)$( 2020 lt ttot.val )
)
)
* sm_c_2_co2;

*** `pm_actualbudgetco2Regi(ttot, regi)` includes emissions from 2020 to `ttot` (inclusive).
pm_actualbudgetco2Regi(ttot,regi)$( 2020 lt ttot.val )
= sum((ttot2)$( 2020 le ttot2.val AND ttot2.val le ttot.val ),
vm_emiAll.l(ttot2,regi,"co2")
* ( (0.5 + pm_ts(ttot2) / 2)$( ttot2.val eq 2020 ) !! second half of the 2020 period (mid 2020 - end 2022) plus 0.5 to account fo beginning 2020 - mid 2020
+ (pm_ts(ttot2))$( 2020 lt ttot2.val AND ttot2.val lt ttot.val ) !! entire middle periods
+ ((pm_ttot_val(ttot) - pm_ttot_val(ttot-1)) / 2 + 0.5)$(ttot2.val eq ttot.val ) !! first half of the final period plus 0.5 to account fo mid - end of final year
)
)
* sm_c_2_co2;

*** track `pm_actualbudgetco2(ttot)` over iterations
p_actualbudgetco2_iter(iteration,ttot)$( 2020 lt ttot.val) = pm_actualbudgetco2(ttot);
p_actualbudgetco2Regi_iter(iteration,ttot,regi)$( 2020 lt ttot.val) = pm_actualbudgetco2Regi(ttot,regi);

*** track pm_taxCO2eq over iterations - pm_taxCO2eq is adjusted in 45_carbonprice/functionalForm/postsolve.gms and consequently pm_taxCO2eq_iter gets overwritten there
pm_taxCO2eq_iter(iteration,t,regi) = pm_taxCO2eq(t,regi);
Expand Down
58 changes: 50 additions & 8 deletions main.gms
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,8 @@ $setglobal emicapregi none !! def = none
*' * (functionalForm): [REMIND default for peak budget and end-of-century budget runs]
*' * Carbon price trajectory follows a prescribed functional form (linear/exponential) - either until peak year or until end-of-century -
*' * and can be endogenously adjusted to meet CO2 budget targets - either peak or end-of-century - that are formulated in terms of total cumulated CO2 emissions from 2020 (cm_budgetCO2from2020).
*' * Flexible choices for regional carbon price differentiation.
*' * Four main design choices:
*' * For global targets, flexible choices for regional carbon price differentiation.
*' * Four main design choices:
*' * [Global anchor trajectory]: The realization uses a global anchor trajectory based on which the regional carbon price trajectories are defined.
*' * The functional form (linear/exponential) of the global anchor trajectory is chosen via cm_taxCO2_functionalForm [default = linear].
*' * The (initial) carbon price in cm_startyear is chosen via cm_taxCO2_startyear. This value is endogenously adjusted to meet CO2 budget targets if cm_iterative_target_adj is set to 5, 7, or 9.
Expand All @@ -384,6 +384,7 @@ $setglobal emicapregi none !! def = none
*' * [Post-peak behaviour]: The global anchor trajectory can be adjusted after reaching the peak of global CO2 emissions in cm_peakBudgYr. See cm_iterative_target_adj and 45_carbonprice/functionalForm/realization.gms for details.
*' * [Regional differentiation]: Regional carbon price differentiation relative to global anchor trajectory is chosen via cm_taxCO2_regiDiff [default = initialSpread10].
*' * In addition, the carbon prices provided by path_gdx_ref can be used as a lower bound based on the switch cm_taxCO2_lowerBound_path_gdx_ref [def = on].
*' * For regional targets, the shape can be chosen to peak in a specified year or in 2100. Linear shapes can be either shifted up and down in start-year or the slope can be endogenously adjusted to meet the target
*' * (expoLinear): 4.5% exponential increase until cm_expoLinear_yearStart, transitioning into linear increase thereafter
*' * (exogenous): carbon price is specified using an external input file or using the switch cm_regiExoPrice. Requires cm_emiscen = 9 and cm_iterative_target_adj = 0
*' * (temperatureNotToExceed): [see realization for details. Test and verify before using it! ]
Expand Down Expand Up @@ -550,7 +551,45 @@ parameter
;
cm_budgetCO2_absDevTol = 2; !! def = 2 !! regexp = is.nonnegative
*'

parameter
cm_regionalBudgetTolerance_Rel
;
cm_regionalBudgetTolerance_Rel = 0.3; !! def = 0.3 !! regexp. is.nonnegative
*'
parameter
cm_regionalBudgetTolerance_Abs "absolute deviation from a regional target. If = 0 -> Relative tolerance is used instead"
;
cm_regionalBudgetTolerance_Abs = 0; !! def = 0 !! regexp. is.nonnegative
*'
parameter
cm_CPslopeAdjustment "whether the slope of the carbon price is adjusted endogenously or the entire curve is just shifted up and down"
;
cm_CPslopeAdjustment = 0; !! def = 0
*' (0): no adjustment of the slope; i.e. carbon price shape chosen from the input-gdx and the curve is shifted up and down from cm_startYear
*' (1): endogenous adjustment of the slope, i.e. linear increase to the highest carbon price
*'
parameter
cm_CPadjustmentAlternating "for regional targets: whether carbon prices are adjusted only one direction per iteration, or both directions "
;
cm_CPadjustmentAlternating = 0; !! def = 0
*' (0): carbon prices are always adjusted
*' (1): regional carbon prices are adjusted only upwards or downwards in a given iteration. Alternating up and down
*'
parameter
cm_funnelFactor
;
cm_funnelFactor = 2; !! def = 2
*'
parameter
cm_funnelExponent
;
cm_funnelExponent = 0.18; !! def = 0.18
*'
parameter
cm_funnelLower
;
cm_funnelLower = 0.001; !! def = 0.005 !! regexp. is.nonnegative
*'
parameter
cm_peakBudgYr "time of global net-zero CO2 emissions (peak budget)"
;
Expand Down Expand Up @@ -895,14 +934,16 @@ parameter
parameter
cm_iterative_target_adj "settings on iterative adjustment for CO2 tax based on in-iteration emission or forcing level. Allow iteratively generated endogenous global CO2 tax under peak budget constraint or end-of-century budget constraint."
;
cm_iterative_target_adj = 0; !! def = 0 !! regexp = 0|2|3|5|7|9
cm_iterative_target_adj = 0; !! def = 0 !! regexp = 0|2|3|4|44|5|7|9
Copy link
Member

Choose a reason for hiding this comment

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

why 44?

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 just an intermediate solution. 44 is a variation of 4. I think it would be good to think about a new logic for cm_iterative_target_adj in general. I also put that as a comment in the issue!

*' * (0): no iterative adjustment of CO2 tax (terminology: CO2 price and CO2 tax in REMIND is used interchangeably)
*' * (2): iterative adjustment of CO2 tax or cumulative emission based on climate forcing calculated by climate model magicc, for runs with budget or CO2 tax constraints. See ./modules/45_carbonprice/NDC/postsolve.gms for direct algorithm
*' * (3): [requires 45_carbonprice = NDC and emiscen = 9] iterative adjustment of CO2 tax based on 2025 or 2030 regionally differentiated emissions, for runs with emission budget or CO2 tax constraints. See ./modules/45_carbonprice/NDC/postsolve.gms for direct algorithm
*' * (5): [requires 45_carbonprice = functionalForm and emiscen = 9] iterative adjustment of CO2 tax based on economy-wide CO2 cumulative emission budget(2020-2100), for runs with emission budget or CO2 tax constraints. [see 45_carbonprice/functionalForm/postsolve.gms for direct algorithm]
*' * (4): [requires 45_carbonprice = functionalForm and emiscen = 9] regional: iterative adjustment of CO2 tax based on economy-wide CO2 cumulative emission budget(2020-2100), for runs with emission budget or CO2 tax constraints. [see 45_carbonprice/functionalForm/postsolve.gms for direct algorithm]
*' * (44): [requires 45_carbonprice = functionalForm and emiscen = 9] regional: iterative adjustment of CO2 tax based on regional economy-wide CO2 cumulative emission EOC budget,
*' * (5): [requires 45_carbonprice = functionalForm and emiscen = 9] global: iterative adjustment of CO2 tax based on economy-wide CO2 cumulative emission budget(2020-2100), for runs with emission budget or CO2 tax constraints. [see 45_carbonprice/functionalForm/postsolve.gms for direct algorithm]
*' * (7): [requires 45_carbonprice = functionalForm and emiscen = 9] iterative adjustment of CO2 tax based on economy-wide CO2 cumulative emission peak budget, for runs with emission budget or CO2 tax constraints. Features: results in a peak budget with zero net CO2 emissions after peak budget is reached. See core/postsolve.gms for direct algorithms [see 45_carbonprice/functionalForm/postsolve.gms for direct algorithm]
*' * (9): [requires 45_carbonprice = functionalForm and emiscen = 9] iterative adjustment of CO2 tax based on economy-wide CO2 cumulative emission peak budget, for runs with emission budget or CO2 tax constraints. Features: 1) after the year when budget peaks, CO2 tax has an annual increase by cm_taxCO2_IncAfterPeakBudgYr, 2) automatically shifts cm_peakBudgYr to find the correct year of budget peaking for a given budget. [see 45_carbonprice/functionalForm/postsolve.gms for direct algorithm]
*'
*' * (9): [requires 45_carbonprice = functionalForm and emiscen = 9] global: iterative adjustment of CO2 tax based on economy-wide CO2 cumulative emission peak budget, for runs with emission budget or CO2 tax constraints. Features: 1) after the year when budget peaks, CO2 tax has an annual increase by cm_taxCO2_IncAfterPeakBudgYr, 2) automatically shifts cm_peakBudgYr to find the correct year of budget peaking for a given budget. [see 45_carbonprice/functionalForm/postsolve.gms for direct algorithm]

parameter
cm_NDC_divergentScenario "choose scenario about convergence of CO2eq prices [45_carbonprice = NDC]"
;
Expand Down Expand Up @@ -1817,7 +1858,8 @@ $setglobal cm_taxCO2_regiDiff_convergence scenario !! def = scenario
*** For example, setting the switch to GLO 50, SSA 5, CHA 40 means that in cm_startyear, SSA has carbon price of 5$/tCO2, CHA has carbon price of 40$/tCO2, and all other regions have carbon price of 50$/tCO2.
*** Important note: If regional carbon prices in the start year are manually set, the regional values are used as lower bounds for pm_taxCO2eq
$setglobal cm_taxCO2_regiDiff_startyearValue endogenous !! def = "endogenous"

*' cm_budgetCO2from2020RegiShare "switch to set eoc regional carbon budget shares by region (for easier comparison than total budgets, endogenous calculation possible)"
$setglobal cm_budgetCO2from2020RegiShare off !! def = off
*** cm_ind_energy_limit Switch for setting upper limits on industry energy
*** efficiency improvements. See ./modules/37_subsectors/datainput.gms for
*** implementation.
Expand Down
26 changes: 24 additions & 2 deletions modules/45_carbonprice/functionalForm/datainput.gms
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
*** SOF ./modules/45_carbonprice/functionalForm/datainput.gms

*** Check that cm_iterative_target_adj is equal to 0, 5, 7, or 9
if( not ((cm_iterative_target_adj = 0) or (cm_iterative_target_adj eq 5) or (cm_iterative_target_adj eq 7) or (cm_iterative_target_adj eq 9) ),
abort "The realization 45_carbonprice/functionalForm is only compatible with cm_iterative_target_adj = 0, 5, 7 or 9. Please adjust config file accordingly"
if( not ((cm_iterative_target_adj = 0) or (cm_iterative_target_adj eq 5) or (cm_iterative_target_adj eq 7) or (cm_iterative_target_adj eq 9) OR (cm_iterative_target_adj eq 4) OR (cm_iterative_target_adj eq 44)),
abort "The realization 45_carbonprice/functionalForm is only compatible with cm_iterative_target_adj = 0, 4, 44, 5, 7 or 9. Please adjust config file accordingly"
);

*** Read pm_taxCO2eq from path_gdx_ref
Expand All @@ -19,6 +19,28 @@ display p45_taxCO2eq_path_gdx_ref;
o45_reached_until2150pricepath(iteration) = 0;


*** ---- for regional carbon budgets (cm_iterative_target_adj eq 4) OR (cm_iterative_target_adj eq 44)
if (not ((cm_iterative_target_adj = 4) OR (cm_iterative_target_adj = 44)),
pm_budgetCO2from2020Regi(regi) = 1; !! not sure if needed
pm_budgetCO2from2020RegiShare(regi) = 1; !!
else
pm_budgetCO2from2020Regi(regi) = pm_budgetCO2from2020RegiShare(regi) * cm_budgetCO2from2020;
);

** Compute the absolute budget deviation tolerance level
if(cm_regionalBudgetTolerance_Abs > 0,
pm_regionalBudget_absDevTol(regi) = cm_regionalBudgetTolerance_Abs;
else
pm_regionalBudget_absDevTol(regi) = cm_regionalBudgetTolerance_Rel * pm_budgetCO2from2020Regi(regi);
);

loop(iteration,
p45_FunnelUpper(iteration) = cm_funnelFactor * EXP( -cm_funnelExponent * iteration.val) + 1 + cm_funnelLower;
p45_FunnelLower(iteration) = 1/ ( cm_funnelFactor * EXP( -cm_funnelExponent * iteration.val) + 1 + cm_funnelLower);
);

s45_YearBeforeStartYear = smax(ttot$( ttot.val lt cm_startyear ), ttot.val); !! Timestep before startyear

***-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
*** Part I (Global anchor trajectory): The functional form (linear/exponential) of the global anchor trajectory is chosen via cm_taxCO2_functionalForm.
*** The (initial) global anchor carbon price in cm_startyear is chosen via cm_taxCO2_startyear. Alternatively, the (initial) global anchor carbon price in cm_peakBudgYr is chosen via cm_taxCO2_peakBudgYr.
Expand Down
35 changes: 34 additions & 1 deletion modules/45_carbonprice/functionalForm/declarations.gms
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,39 @@ p45_regiDiff_startyearValue(all_regi) "manually chosen regional carbon pri
p45_regiDiff_startyearValue_data(ext_regi) "input data for regional carbon price in start year provided by switch cm_taxCO2_regiDiff_startyearValue"
/ %cm_taxCO2_regiDiff_startyearValue% /
$endIf.taxCO2regiDiffStartyearValue1
;


*** If there is a regional budget, read regional carbon budget from switch and set additionally needed parameters
pm_budgetCO2from2020Regi(all_regi) "regional carbon budget (Gt CO2)"
!!$ifthen.regiBudget "%cm_iterative_target_adj%" == "4" OR "%cm_iterative_target_adj%" == "44"
$ifthen.regiBudget "%cm_budgetCO2from2020RegiShare%" == "off" !! (cm_iterative_target_adj == "4") OR (cm_iterative_target_adj == "44")
pm_budgetCO2from2020RegiShare(all_regi) "share of region in global carbon budget"
$else.regiBudget
pm_budgetCO2from2020RegiShare(all_regi) "share of region in global carbon budget" /%cm_budgetCO2from2020RegiShare%/
$endif.regiBudget
p45_actualbudgetco2Regi(all_regi) "regional - actual level of 2020-2100 cumulated emissions, including all CO2 for last iteration"
p45_actualbudgetco2Regi_iter(iteration,all_regi) "regional - actual level of 2020-2100 cumulated emissions, including all CO2 for last iteration"
p45_factorRescale_taxCO2Regi(iteration,all_regi) "regional - Multiplicative factor for rescaling the CO2 price to reach the target"
p45_factorRescale_taxCO2Regi_Funneled(iteration, all_regi) "regional - Multiplicative factor for rescaling the CO2 price to reach the target - Funnelled (static)"
pm_factorRescale_taxCO2Regi_Funneled2(iteration, all_regi) "regional - Multiplicative factor for rescaling the CO2 price to reach the target - Funnelled (interactive, incl. adjustments based on last iterations)"
p45_factorRescale_taxCO2Regi_Final(iteration, all_regi) "regional - Multiplicative factor for rescaling the CO2 price to reach the target - Funnelled, may include up/downward iteration differentiation"
p45_taxCO2eq_anchorRegi(ttot,all_regi) "regional anchor trajectory for regional CO2 price trajectories in T$/GtC = $/kgC"
p45_taxCO2eq_anchorRegi_iter(ttot, all_regi, iteration) "regional anchor trajectory for regional CO2 price trajectories in T$/GtC = $/kgC across iterations"
p45_temp_anchor(ttot,all_regi) "regionally shifted anchor for all iterations (helper, may be removed)"
pm_budgetDeviation(all_regi) "deviations from regional targets"
p45_budgetDeviation_iter(iteration, all_regi) "deviations from regional targets across iterations"
pm_regionalBudget_absDevTol(all_regi) "tolerance of deviation from regional targets in absolute terms"

p45_TaxBudgetSlopeCurrent(all_regi) "regional carbon price change/regional carbon budget change - from the last 2 iterations"
p45_TaxBudgetSlopeCurrent_iter(iteration, all_regi) "regional carbon price change/regional carbon budget change - from the last 2 iterations, for each iteration. 0 when no carbon price change"
p45_TaxBudgetSlopeBest(all_regi) "last available regional carbon price change/regional carbon budget change that is negative"
p45_TaxBudgetSlopeBest_iter(iteration, all_regi) "last available regional carbon price change/regional carbon budget change that is negative for each iteration"
p45_CarbonPriceSlope(all_regi) "when carbon price slope is regionally adjusted: increase of carbon price per year"
p45_CarbonPriceSlope_iter(iteration,all_regi) "when carbon price slope is regionally adjusted: increase of carbon price per year for each iteration"

p45_FunnelUpper(iteration) "upper bound on regional carbon price funnel (helper, may be removed)"
p45_FunnelLower(iteration) "lower bound on regional carbon price funnel (helper, may be removed)"
;
*** Scalars only used in functionForm/postsolve.gms
scalars
s45_actualbudgetco2 "actual level of 2020-2100 cumulated emissions, including all CO2 for last iteration"
Expand All @@ -58,6 +89,8 @@ s45_factorRescale_taxCO2_exponent_from10 "exponent determining se
s45_peakBudget "peak CO2 budget as calculated as the maximum of cumulative CO2 emissions, used to check adjustment algorithm [GtC/yr]"
sm_peakBudgYr_check "peak budget year calculated based on maximum of cumulative CO2 emissions, used to check adjustment algorithm [year]"
sm_peakbudget_diff "difference in cumulative CO2 emissions between cumulative emissions in cm_peakBudgYr and time step of maximum cumulative CO2 emissions [GtCO2]"

s45_YearBeforeStartYear "! This is the same value as s45_interpolation_startYr but the naming does not make sense for these extended purposes, thus creating a new scalar as preliminary solution"
;

*** Parameters only used in functionForm/postsolve.gms
Expand Down
Loading
Loading