-
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
ELEVATE WP4.4 in modul 21 a) import tax extension to carbon-content of imported PEs #1495
Conversation
…priced with national or average carbon price b) revenue recycling; modul 80 nash optimization no technology learning (fix foreign cap to 2020 level)
a055da2
to
c1a88fe
Compare
c1a88fe
to
ee7542f
Compare
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.
Fine from my side, but I did not check the latest latest version.
I did:
- the regexp adjustments, correcting errors
- delete engage config
- adjustments in prepare.R and checkFixCfg
@@ -1370,11 +1378,18 @@ $setglobal cm_steel_secondary_max_share_scenario off !! def off , switch on for | |||
*** cm_import_tax | |||
*** set tax on imports for specific regions on traded energy carriers | |||
*** as a fraction of import price | |||
*** example: "EUR.pebiolc 0.5" means bioenergy imports to EUR see 50% tax on top of world market price. | |||
*** example: "EUR.worldPricemarkup.pebiolc 0.5" means bioenergy imports to EUR see 50% tax on top of world market price. |
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.
please change to EUR.pebiolc.worldPricemarkup
.
@@ -67,7 +67,8 @@ checkFixCfg <- function(cfg, remindPath = ".", testmode = FALSE) { | |||
# count errors | |||
if (! is.null(errormsg)) { | |||
errorsfound <- errorsfound + 1 | |||
if (testmode) warning(errormsg) else message(errormsg) | |||
message(errormsg) |
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.
errors were just summarized in "there were 30 warnings" in start.R --> useless
@@ -48,7 +48,7 @@ checkFixCfg <- function(cfg, remindPath = ".", testmode = FALSE) { | |||
# how parameter n is defined in main.gms | |||
paramdef <- paste0("^([ ]*", n, "[ ]*=|\\$setglobal[ ]+", n, " )") | |||
# filter fitting parameter definition from code snippets containing regexp | |||
filtered <- grep(paste0(paramdef, ".*regexp[ ]*=[ ]*"), code, value = TRUE) | |||
filtered <- grep(paste0(paramdef, ".*regexp[ ]*=[ ]*"), code, value = TRUE, ignore.case = TRUE) | |||
if (length(filtered) == 1) { |
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.
identify setGlobal and setglobal
@@ -1242,7 +1250,7 @@ $setGlobal cm_oil_scen medOil !! def = medOil !! regexp = lowOil|medOi | |||
*** (lowGas): low | |||
*** (medGas): medium | |||
*** (highGas): high | |||
$setGlobal cm_gas_scen medGas !! def = medGas !! regexp = low|medium|high | |||
$setGlobal cm_gas_scen medGas !! def = medGas !! regexp = lowGas|medGas|highGas |
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.
some fixes to regexp because they were wrong
; | ||
cm_LearningSpillover = 1; !! def 1 = Learningspillover activated (set to 0 to deactivate) | ||
*' | ||
*' * if Learningspillover is deactivated, foreign capacity is set to the level of 2020 in technology learning. |
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 would add something like: "This means that in the model, each region's learning depends on its OWN additional capacity investment after 2020 in comparison to the GLOBAL cumulative capacity until 2020, so for small regions learning is very slow. This is a very pessimistic interpretation of 'no learning spillovers', as every region has to follow the global learning curve"
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.
Thank you, that is very helpful. Just for my understanding, what do you mean by "every region has to follow the global learning curve"? This would not hold anymore if cm_LearningSpillover = 0
, or?
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.
with "follow the global learning curve" I mean that in cm_learningSpillover = 0
a country only manages to "double capacity" (which is the moment that the costs are reduced by the learning rate value) when its own capacity addition is equal to the GLOBAL capacity in 2020.
so I think my initial formulation can be misunderstood - maybe "as every region has to climb up the global learning curve all by itself" is better?
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.
Great, thank you for the further explanation. We have added your suggestion in main.gms, see last commit.
modules/21_tax/on/equations.gms
Outdated
*' 3. "avCO2taxmarkup" = import tax level * max( national carbon price, average carbonprice) * imported carbon by carrier | ||
* NOTE: In case of "CO2taxmarkup" and "avCO2taxmarkup" there is double-taxation of the CO2-content of the imported energy carrier: Once when being imported (at the border) and once when being converted to Secondary Energy (normal CO2price applied by REMIND) | ||
***--------------------------------------------------------------------------- | ||
sum(tax_import_type_21, p21_tau_Import(t, regi, tradePe, tax_import_type_21)$sameas(tax_import_type_21, "worldPricemarkup") |
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 am confused by the splitting of this code.
If I understand it correctly, the equation has three different right sides, depending on whether tax_import_type_21 is a, b or c.
I would find it clearer to write each of the options individually and put one "$$sameas(tax_import_type_21,a)" behind it, but not have the $ command twice in each version of the right side:
so instead of
p21_tau_Import(t, regi, tradePe, tax_import_type_21)$sameas(tax_import_type_21, "CO2taxmarkup") * pm_taxCO2eqSum(t,regi) * pm_cintraw(tradePe) * vm_Mport(t,regi,tradePe) - p21_taxrevImport0(t,regi,tradePe,tax_import_type_21)$sameas(tax_import_type_21, "CO2taxmarkup")
I would write
+ ( p21_tau_Import(t, regi, tradePe, tax_import_type_21) * pm_taxCO2eqSum(t,regi) * pm_cintraw(tradePe) * vm_Mport(t,regi,tradePe)
- p21_taxrevImport0(t,regi,tradePe,tax_import_type_21)
)$sameas(tax_import_type_21, "CO2taxmarkup")
(and the same for the other two cases.
For me this makes it easier to see that this is really just a way of saying "only one of these 3 versions will be active, and you don't need to look into the contents of the ones that are not active"
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.
(and I would add a line break after the initial opening of the sum to show clearly these are three separate cases:
sum(tax_import_type_21,
( p21_tau_Import(t, regi, tradePe, tax_import_type_21) * pm_pvp(t,tradePe) / pm_pvp(t,"good") * vm_Mport(t,regi,tradePe)
- p21_taxrevImport0(t,regi,tradePe,tax_import_type_21)
)$sameas(tax_import_type_21, "worldPricemarkup")
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.
Nice code cleaning, thank you! We have changed the equation according to your suggestion, see last commit!
I added a number of detailed comments - please check/reply. For future PRs: I think it would be better to have this as 3 different PRs - each one changes an aspect of the code, and together there is so much change that it becomes a bit difficult to review. (Sometimes things are so interconnected that it is impossible to split, but here eg the learning would have been easy to do in a separate branch) also, to be able to understand if the learning part does what it is supposed to do, it would be great to have a plot with eg PV capital costs in CHA and JPN plotted in two NPi runs that are identical except for once having learning spillovers turned on and turned off. |
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 added a number of concrete comments and questions
modules/21_tax/on/equations.gms
Outdated
*' 3. "avCO2taxmarkup" = import tax level * max( national carbon price, average carbonprice) * imported carbon by carrier | ||
* NOTE: In case of "CO2taxmarkup" and "avCO2taxmarkup" there is double-taxation of the CO2-content of the imported energy carrier: Once when being imported (at the border) and once when being converted to Secondary Energy (normal CO2price applied by REMIND) | ||
***--------------------------------------------------------------------------- | ||
sum(tax_import_type_21, p21_tau_Import(t, regi, tradePe, tax_import_type_21)$sameas(tax_import_type_21, "worldPricemarkup") |
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.
(and I would add a line break after the initial opening of the sum to show clearly these are three separate cases:
sum(tax_import_type_21,
( p21_tau_Import(t, regi, tradePe, tax_import_type_21) * pm_pvp(t,tradePe) / pm_pvp(t,"good") * vm_Mport(t,regi,tradePe)
- p21_taxrevImport0(t,regi,tradePe,tax_import_type_21)
)$sameas(tax_import_type_21, "worldPricemarkup")
modules/21_tax/on/declarations.gms
Outdated
@@ -39,7 +39,7 @@ p21_taxrevBio0(ttot,all_regi) "reference level value of bioen | |||
p21_implicitDiscRate0(ttot,all_regi) "reference level value of implicit tax on energy efficient capital" | |||
p21_taxemiMkt0(ttot,all_regi,all_emiMkt) "reference level value of co2 emission taxes per emission market" | |||
p21_taxrevFlex0(ttot,all_regi) "reference level value of flexibility tax" | |||
p21_taxrevImport0(ttot,all_regi,all_enty) "reference level value of import tax" | |||
p21_taxrevImport0(ttot,all_regi,all_enty,tax_import_type_21) "reference level value of import tax" |
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.
sorry that everyone else before you got the naming wrong and I just noticed it when you copied it - but let's do it better from here on :-)
p21_taxrevImport0(ttot,all_regi,all_enty,tax_import_type_21) "reference level value of import tax"
-> this should be named something like "tax revenues from import tax in the previous iteration"
also,
v21_taxrevImport(ttot,all_regi,all_enty) "tax on energy imports"
should in fact be
"net change vs. last iteration of tax revenues from energy import tax"
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.
That's right, we have changed the naming accordingly! See last commit.
p21_tau_Import(t,regi,tradePe) * pm_pvp(t,tradePe) / pm_pvp(t,"good") * vm_Mport(t,regi,tradePe) | ||
- p21_taxrevImport0(t,regi,tradePe) | ||
***--------------------------------------------------------------------------- | ||
*' import taxation: 1. "worldPricemarkup" = import tax level * world market price * tradePE import |
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.
something seems wrong witht his formulation, just based on the units. if you multiply a world market price (in TUSD/TWa) by a tax level in TUSD/TWa times an import amount in TWa, you don't get TUSD but rather TUSD^2/TWa.
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.
@fschreyer we tried to extend your Import tax. Could you perhaps help us with the units in your original formula, which is based on the world market price?
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.
Sry, description of tax rate parameter was wrong. The parameter gives the shares of the world market price. Please subsitute
p21_tau_Import(ttot,all_regi,all_enty) "tax on energy imports, currently only works on primary energy levels as those are traded on nash markets [trUSD/TWa]"
by
p21_tau_Import(ttot,all_regi,all_enty) "tax on energy imports, only works on energy carriers traded on nash markets, tax defined as share of world market price pm_pvp [Unit: share]"
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.
Thank you, Felix! We have applied your change in our last commit.
|
|
A great thank you to @robertpietzcker! We highly appreciate your detailed review and effort! With our last commit "Addressed reviewer comments by Robert and Felix" we have tried to address all the mindful comments. After the last changes, we also rerun make test that resulted in 0 FAIL and 0 WARN. |
main.gms
Outdated
cm_LearningSpillover = 1; !! def 1 = Learningspillover activated (set to 0 to deactivate) | ||
*' | ||
*' * if Learningspillover is deactivated, foreign capacity is set to the level of 2020 in technology learning. | ||
*' * In combination with endogenous carbon pricing (e.g., in NDC), the deactivated Learningspillover will lead to higher overall carbon prices. Can be solved by setting carbonprice to exogenous (config). |
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.
sorry that I have a tiny other point - could you change the order of the explanations?
if you have a sentence starting "This means that ..." after "In combination with endogenous ...", one could misunderstand the "this" to refer to the previous sentence, and not the "if Learningspillover is deactivated ..."
so I would put the "In combination with endogenous" at the end of the explanation :-)
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.
Yes, I see your point and have changed the order (commit 9)!
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.
Great, thanks for the changes, and for doing the extra plot with PV costs!
The results look reasonable - until 2050 there is the global learning curve convergence, which means that small regions which apparently are below the global average in 2020 (NEU) actually see a cost increase because the local capacity additions are so small against the global capacity that the additional learning is more than overcompensated by the "convergence of underlying learning parameters". In JPN, the starting point is higher, so we see the opposite effect. In very large regions (OAS, SSA, CHA, IND) the long-term difference to the spillover case is not so large because they deploy a lot of PV capacity.
…priced with national or average carbon price b) revenue recycling; c) no technology learning spill-over (modul 80 nash optimization)
Purpose of this PR
ELEVATE WP4.4 "Energy autarchy and the green technology race - is climate the winner?"
Protectionist measures:
modules/21_tax:
Import tax: extension of import tax
q21_taxrevImport
that enables import tax of traded PE with world market pricesIntroduces possibility to tax imported PEs based on their carbon-content. (i.e emissions associated with imports of energy carriers) with carbon prices.
cm_import_tax
toCO2taxmarkup
cm_import_tax
toavCO2taxmarkup
Note: This option leads to double taxation of imported PEs (import tax at border + REMIND's normal CO2 tax).
Revenue recycling of import tax for additional investments in renewables
Narrative: Extra revenues from the import tax are used for extra investment in green and low-carbon technologies.
Implementation: Investments in wind, solar and storage equal investments from reference scenario with tax and no revenue recycling plus the revenues received from the tax.
Switch: Set
cm_taxrc_RE
toREdirect
no technology learning spill-over (modules/80_optimization/nash)
Narrative: Technology autarchy (total shut-down of global technology spillover effects)
Implementation: Fixing the level of
pm_capCumForeign
to the value from year 2020. After 2020, technology learning based only on regional capacity.Switch: Set
cm_LearningSpillover
to 0Type of change
(Make sure to delete from the Type-of-change list the items not relevant to your PR)
Checklist:
remind2
where it was neededforbiddenColumnNames
in readCheckScenarioConfig.R in case the PR leads to deprecated switchesFAIL 0
in the output ofmake test
)CHANGELOG.md
has been updated correctlyFurther information (optional):
\clusterfs\tmp\rahelma\ElevateWP4\remind3.2\CarbonPricing\remind\output
Import tax
Note. Emissions reduction by import tax on carbon content of imported fossil fuels. The effect is further enhanced if revenues are used for additional investments in renewables & storage (revenue recycling).
no technology learning spill-over
If tax on carbon-content of PE imports is combined with no further technology cooperation as of 2020 (NDC_avtax_nTecC: only regional learning) emissions are lower than in the NDC only case, but higher than in the NDC_avtax case with global learning.
Investment costs solar PV