-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emi mkt target update #1331
Emi mkt target update #1331
Conversation
…e GAMS entry order
…efficiency targets
…carbon price and improve convergence algorithm for multiple temporal targets applied to the same region
…gipol emission quantity targets
p47_nonEnergyUse("2050",ext_regi)$(sameas(ext_regi, "EU27_regi")) = 0.121606*0.815; | ||
p47_nonEnergyUse("2050",ext_regi)$(sameas(ext_regi, "EUR_regi")) = 0.13*0.841; | ||
*** DEU -> 0.946 EJ = 0.03 Twa (2020 non-energy use) | ||
p47_nonEnergyUse("2030",ext_regi)$(sameas(ext_regi, "DEU")) = 0.03*0.928; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where do the 0.928 and 0.848 and 0.822 come from?
I guess the 2030 value is from the historical 2020 value (as in EU), but how is this projected to 2045/2050 - a REMIND run?
(I am not doubting the values, I am just thinking about the next person who has to work on this in 2 years and is wondering "was there a good source for this, or can I simply change it?")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pm_fe_nechem
values were calculated ad hoc by Michaja, and refers originally to a very rough estimation of non-energy use in chemicals.
Due the lack of a better alternative until we have proper non-energy trajectories being considered in REMIND, these are scaled to represent total non-energy use as described in: pik-piam/remind2#411 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the values that you see multiplied by the 2020 original non-energy use, are simply the relative difference that the exogenously defined trajectory in pm_fe_nechem
considers in comparison to 2020.
loop(regi$regi_groupExt(ext_regi,regi), | ||
loop(emiMkt$emiMktGroup(emiMktExt,emiMkt), | ||
*** if emiMKt target did not converged and we are not forcing negative prices (if the price is at minimal level (1$/tCO2) and current emissions are lower than the target) | ||
if(((abs(pm_emiMktTarget_dev(ttot,ttot2,ext_regi,emiMktExt)) gt cm_emiMktTarget_tolerance) and (not ((pm_taxemiMkt(ttot2,regi,emiMkt) eq 1*sm_DptCO2_2_TDpGtC) and (pm_emiMktTarget_dev(ttot,ttot2,ext_regi,emiMktExt) lt 0)))), !! if emiMKt target did not converged and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 questions:
-
does GAMS store the
pm_taxemiMkt(ttot2,regi,emiMkt)
with the same number of digits so that(not ((pm_taxemiMkt(ttot2,regi,emiMkt) eq 1*sm_DptCO2_2_TDpGtC)
will really be returned true? -
could there be the problem that the model has in one iteration quite low emissions, uses the slope to calculate new (negative) CO2 prices that in the end miss the target, but the algorithm never checks this as it stops in the first iteration?
maybe add a "needs to be 2 iterations in negative prices" safety buffer to prevent this from happening? or do you think this phenomenon will be very unlikely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
sm_DptCO2_2_TDpGtC
is a scalar hard-coded to0.00366667
. So yes, this number should be always the same and equal to0.00366667
as consequence. Tolerances only affect variables and equations as far as I know. -
All targets are checked at every iteration if they are converging or not, so the algorithm keeps checking if the convergence has changed, even if the model reached full convergence in some previous iteration. See: https://github.com/remindmodel/remind/blob/252343cf0b39d827317e6b7affbd86a69729e37e/modules/47_regipol/regiCarbonPrice/postsolve.gms#L181C1-L208
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still about 2, if a slope causes negative prices, the prices will be set to 1 dollar in this iteration. In the next iteration the slope will be then calculated against the 1 dollar price instead. This already adds a second attempt using a different slope to avoid the negative prices.
I am not saying the case you mention could not happen, but I don't I saw it happening yet, at least in the runs I did so far.
Avoiding this would require a bit more complicated code than checking negative prices in two consecutive runs. I only see the need to spend time with this if this becomes a recurrent issue.
Besides, as far as I saw, negative carbon taxes are much more a symptom of ill defined targets than a result of the algorithm so far. In this case, getting the modeler attention with a non-converged run is a much better result than handing these cases quietly inside the algorithm "black-box".
loop((ext_regi,ttot)$regiANDperiodEmiMktTarget_47(ttot,ext_regi), | ||
if(ord(iteration) eq 1, | ||
p47_slopeReferenceIteration(iteration,ttot,ext_regi) = 1; | ||
elseif(NOT(p47_currentConvergence_iter(iteration,ttot,ext_regi) eq p47_currentConvergence_iter(iteration-1,ttot,ext_regi))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get this - why is it the right question to ask if the target convergence check was different between last and this iteration? if I understand correctly, this gets updated to the current iteration if a) last iteration the check was on and now it is not on, and b) last iteration the check was off and now it is on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line says that, for a given region, whenever you change the target that you are currently updating in comparison to the previous iteration (NOT(p47_currentConvergence_iter(iteration,ttot,ext_regi) eq p47_currentConvergence_iter(iteration-1,ttot,ext_regi)
), you need to reset the p47_slopeReferenceIteration
value (p47_slopeReferenceIteration(iteration,ttot,ext_regi) = current iteration
).
Otherwise, you just keep the reference iteration value unchanged: p47_slopeReferenceIteration(iteration,ttot,ext_regi) = p47_slopeReferenceIteration(iteration-1,ttot,ext_regi);
.
This way, whenever you change your target year focus, you will run an initial tax update using a simplified formula, and only from the next iteration onwards the slope will be used to update the tax values using as reference the closest iteration that used the simplified formula.
Take a look at /p/projects/ecemf/REMIND/2040_scenarios/v04_2023_06_02/output/04_Nzero_57_RpEUEff_bio7p5_limCC_EU27_2023-06-02_17.25.43
for example.
We have two targets for EU27, one by 2030 and another by 2050 (cm_emiMktTarget
= 2020.2030.EU27_regi.all.year.netGHG_LULUCFGrassi_intraRegBunker 2.122, 2035.2050.EU27_regi.all.year.netGHG_LULUCFGrassi 0.01
)
If you take a look at p47_currentConvergence_iter
, you will see that at iterations 1, 6, 9 and 12, our focus to update the taxes changes from 2030 to 2050 to 2030 and back to 2050.
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
EU27_regi | 2030 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | |||||
EU27_regi | 2050 | 1 | 1 | 1 | 1 | 1 |
This means,
- the 2030 target converged at iteration 6, so we switched to try to solve the 2050 in the next one.
- Then, we updated the 2050 taxes for three iterations, but at iteration 9 these updates caused the 2030 to not converge anymore.
- We kept the 2050 as is, and got back on updating the 2030 target to converge from iteration 9, and it finally converged at iteration 12.
- The we got back to the 2050 target and finally from iteration 14 onward both targets converged, and kept converging until the end of the model run.
Now how the tax update was done:
- When you are at iterations that change target focus - iteration 1 by definition and iterations 6, 9 and 12 in the example above - the tax update is defined by a simple rule based on the current deviation.
- When you are at other iterations, the tax update is defined by the slope between the tax and target changes, calculated from the nearest iteration that had a target change focus.
- When you are at iterations 2 to 5, the tax update is defined by the slope that you observed from iteration 1.
- When you are at iterations 7 to 8, the tax update is defined by the slope that you observed from iteration 6.
- When you are at iterations 10 to 11, the tax update is defined by the slope that you observed from iteration 9.
- When you are at iteration 13 onward, the tax update is defined by the slope that you observed from iteration 12.
The values of p47_slopeReferenceIteration
reflect the reference iterations to calculate the slope as I described above:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | … | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
EU27_regi | 2030 | 1 | 1 | 1 | 1 | 1 | 6 | 6 | 6 | 9 | 9 | 9 | 12 | 12 | 12 | … |
EU27_regi | 2050 | 1 | 1 | 1 | 1 | 1 | 6 | 6 | 6 | 9 | 9 | 9 | 12 | 12 | 14 | … |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the extended explanation!
what about adding "!! reset the slope if the target that is being analyzed changes" in the elseif
line to get people thinking in the right direction?
I had misinterpreted the parameter as "is the target converged", and not "is this the target the model is currently focusing on"
Purpose of this PR
cm_emiMktTarget_tolerance
andcm_implicitQttyTarget_tolerance
).Type of change
Checklist:
remind2
where it was neededFAIL 0
in the output ofmake test
)Further information (optional):
/p/projects/ecemf/REMIND/2040_scenarios/v04_2023_06_02