diff --git a/CHANGELOG.md b/CHANGELOG.md index bc9c6dd83..24b4f5dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - **core** change of preference parameters and associated computation of interest rates/mark ups - **scripts** add script to automatically check project summations from piamInterfaces [[#1587](https://github.com/remindmodel/remind/pull/1587)] +- **32_power** extend and reparameterize flexibility tax implementation for electrolysis for hydrogen production +- **21_tax** add SE tax on electricity going into electrolysis for hydrogen production - **scripts** add compareScenarios section for MAGICC7 AR6 output [[#1615](https://github.com/remindmodel/remind/pull/1615) diff --git a/core/bounds.gms b/core/bounds.gms index 76ffa476e..f0a67fc34 100755 --- a/core/bounds.gms +++ b/core/bounds.gms @@ -427,9 +427,6 @@ loop(regi, *** Fixing will produce clearly attributable errors (good for debugging) when using inconsistent data, as the GAMS accuracy when comparing fixed results is very high (< 1e-8). ***vm_prodFe.fx("2005",regi,se2fe(enty,enty2,te)) = sum(fe2ppfEn(enty2,in), pm_cesdata("2005",regi,in,"quantity") ); -vm_deltaCap.up(t,regi,"gasftrec",rlf)$(t.val gt 2005) = 0.0; -vm_deltaCap.up(t,regi,"gasftcrec",rlf)$(t.val gt 2005) = 0.0; - $ontext *** ------------------------------------------------------------- *** *RP* Chinese depoyment of coal power plants and coal use in industry was probably not only demand-driven, but also policy-driven (faster than demand). Therefore, we implement lower bounds on coal power plants and solid coal use: diff --git a/core/datainput.gms b/core/datainput.gms index fb78f50ad..67310eb18 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -811,9 +811,9 @@ loop(regi, *RP* calculate annuity of a technology p_discountedLifetime(te) = sum(opTimeYr, (sum(regi, pm_omeg(regi,opTimeYr,te))/sum(regi,1)) / 1.06**opTimeYr.val ); -p_teAnnuity(te) = 1/p_discountedLifetime(te) ; +pm_teAnnuity(te) = 1/p_discountedLifetime(te) ; -display p_discountedLifetime, p_teAnnuity; +display p_discountedLifetime, pm_teAnnuity; *** read in data on Nuclear capacities used as bound on vm_cap.fx("2015",regi,"tnrs","1"), vm_deltaCap.fx("2020",regi,"tnrs","1") and vm_deltaCap.up("2025" and "2030") parameter pm_NuclearConstraint(ttot,all_regi,all_te) "parameter with the real-world capacities, construction and plans" diff --git a/core/declarations.gms b/core/declarations.gms index eaeac341c..31c26cf98 100644 --- a/core/declarations.gms +++ b/core/declarations.gms @@ -307,7 +307,7 @@ p_share_seh2_s(ttot,all_regi) "share of hydrogen used for p_share_seel_s(ttot,all_regi) "Share of electricity used for stationary sector (feels). [0..1]" p_discountedLifetime(all_te) "Sum over the discounted (@6%) depreciation factor (omega)" -p_teAnnuity(all_te) "Annuity factor of a technology" +pm_teAnnuity(all_te) "Annuity factor of a technology" ; diff --git a/core/sets.gms b/core/sets.gms index be4fb3110..4e64968aa 100755 --- a/core/sets.gms +++ b/core/sets.gms @@ -204,7 +204,7 @@ all_te "all energy technologies, including from modules" solhe "solar thermal heat generation" tnrs "thermal nuclear reactor (simple structure)" fnrs "fast nuclear reactor (simple structure)" - elh2 "hydrogen elecrolysis" + elh2 "hydrogen electrolysis, using grid electricity" h2turb "hydrogen turbine for electricity production" elh2VRE "dummy technology: hydrogen electrolysis; to demonstrate the capacities and SE flows inside the storXXX technologies" h2turbVRE "dummy technology: hydrogen turbine for electricity production; to demonstrate the capacities and SE flows inside the storXXX technologies" diff --git a/main.gms b/main.gms index 88b16e139..365b8bd76 100755 --- a/main.gms +++ b/main.gms @@ -1000,9 +1000,9 @@ parameter cm_PriceDurSlope_elh2 "slope of price duration curve of electrolysis" ; cm_PriceDurSlope_elh2 = 15; !! def = 15 -*' cm_PriceDurSlope_elh2, slope of price duration curve for electrolysis (increase means more flexibility subsidy for electrolysis H2) +*' cm_PriceDurSlope_elh2, slope of price duration curve for electrolysis (increase means more flexibility subsidy for electrolysis H2) *' This switch only has an effect if the flexibility tax is on by cm_flex_tax set to 1 -*' +*' Default value is based on data from German Langfristszenarien (see ./modules/32_power/IntC/datainput.gms). parameter cm_FlexTaxFeedback "switch deciding whether flexibility tax feedback on buildlings and industry electricity prices is on" ; diff --git a/modules/21_tax/off/not_used.txt b/modules/21_tax/off/not_used.txt index 239fd4d83..6199f444e 100644 --- a/modules/21_tax/off/not_used.txt +++ b/modules/21_tax/off/not_used.txt @@ -70,3 +70,6 @@ vm_costInvTeDir,input,only needed if tax is on vm_costInvTeAdj,input,only needed if tax is on pm_cintraw,input,only needed if tax is on pm_gdp,input,only needed if tax is on +pm_cf,input,only needed if tax is on +vm_shDemSeel,input,only needed if tax is on +pm_teAnnuity,input,only needed if tax is on diff --git a/modules/21_tax/on/declarations.gms b/modules/21_tax/on/declarations.gms index 63c971645..819025499 100644 --- a/modules/21_tax/on/declarations.gms +++ b/modules/21_tax/on/declarations.gms @@ -17,6 +17,7 @@ p21_bio_EF(ttot,all_regi) "bioenergy emission factor, which p21_tau_Import(ttot,all_regi,all_enty,tax_import_type_21) "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]" pm_tau_pe_tax(ttot,all_regi,all_enty) "pe tax path" pm_tau_ces_tax(ttot,all_regi,all_in) "ces production tax to implement CES mark-up cost in a budget-neutral way" +p21_tau_SE_tax(ttot,all_regi,all_te) "maximum tax rate for SE electricity tax, used for taxes on electrolysis" p21_tau_fe_tax(ttot,all_regi,emi_sectors,all_enty) "tax path for final energy" p21_tau_fe_sub(ttot,all_regi,emi_sectors,all_enty) "subsidy path for final energy" @@ -39,6 +40,7 @@ p21_taxemiMkt0(ttot,all_regi,all_emiMkt) "reference level va p21_taxrevFlex0(ttot,all_regi) "reference level value of flexibility tax" p21_taxrevImport0(ttot,all_regi,all_enty,tax_import_type_21) "tax revenues from import tax in the previous iteration" p21_taxrevChProdStartYear0(ttot,all_regi) "reference level value of tax to limit changes compared to reference run in cm_startyear" +p21_taxrevSE0(ttot,all_regi) "reference level value of tax on SE electricity demand" p21_taxrevGHG_iter(iteration,ttot,all_regi) "reference level value of GHG emission tax revenue" p21_taxrevCCS_iter(iteration,ttot,all_regi) "reference level value of CCS tax revenue" @@ -55,6 +57,7 @@ p21_implicitDiscRate_iter(iteration,ttot,all_regi) "reference level valu p21_taxrevFlex_iter(iteration,ttot,all_regi) "reference level value of flexibility tax revenue" p21_taxrevImport_iter(iteration,ttot,all_regi,all_enty) "reference level value of import tax" p21_taxrevChProdStartYear_iter(iteration,ttot,all_regi) "Difference to tax revenues in last iteration for: tax to limit changes compared to reference run in cm_startyear" +p21_taxrevSE_iter(iteration,ttot,all_regi) "Difference to tax revenues in last iteration for: tax on SE electricity demand" p21_CO2TaxSectorMarkup(ttot,all_regi,emi_sectors) "CO2 tax markup in building, industry or transport sector" @@ -64,6 +67,8 @@ p21_tau_CO2_tax_gdx(ttot,all_regi) "tax path from gdx, may overwrite d p21_tau_CO2_tax_gdx_bau(ttot,all_regi) "tax path from gdx, may overwrite default values" p21_implicitDiscRateMarg(ttot,all_regi,all_in) "Difference between the normal discount rate and the implicit discount rate" + +p21_tau_SE_tax_rampup(ttot,all_regi,all_te,teSeTax_coeff) "Paramters of logistic function to describe relationship between SE electricity tax rate and share of technology in total electricity demand" ; @@ -118,11 +123,13 @@ v21_implicitDiscRate(ttot,all_regi) "implicit tax on energy efficie v21_taxemiMkt(ttot,all_regi,all_emiMkt) "tax on greenhouse gas emissions" v21_taxrevImport(ttot,all_regi,all_enty) "net change vs. last iteration of tax revenues from energy import tax" v21_taxrevChProdStartYear(ttot,all_regi) "tax to limit changes compared to reference run in cm_startyear" +v21_taxrevSE(ttot,all_regi) "tax on SE electricity demand, used for taxes on electrolysis" ; Positive Variable v21_emiALLco2neg(ttot,all_regi) "negative part of total CO2 emissions" v21_emiALLco2neg_slack(ttot,all_regi) "dummy variable to extract negatice CO2 emissions from emiAll" +v21_tau_SE_tax(ttot,all_regi,all_te) "tax rate of tax on SE electricity demand, used for taxes on electrolysis" ; equations @@ -147,6 +154,8 @@ q21_implicitDiscRate(ttot,all_regi) "calculation of the implicit dis q21_taxemiMkt(ttot,all_regi,all_emiMkt) "calculation of specific emission market tax on CO2 emissions" q21_taxrevImport(ttot,all_regi,all_enty) "calculation of import tax" q21_taxrevChProdStartYear(ttot,all_regi) "calculation of tax to limit changes compared to reference run in cm_startyear" +q21_taxrevSE(ttot,all_regi) "calculation of tax on SE electricity demand, used for taxes on electrolysis" +q21_SeTaxRate(ttot,all_regi,all_te) "calculation of SE tax rate, used for taxes on electrolysis" ; $ifthen.importtaxrc "%cm_taxrc_RE%" == "REdirect" diff --git a/modules/21_tax/on/equations.gms b/modules/21_tax/on/equations.gms index 9faf8a1c9..becc31bef 100644 --- a/modules/21_tax/on/equations.gms +++ b/modules/21_tax/on/equations.gms @@ -36,6 +36,7 @@ q21_taxrev(t,regi)$(t.val ge max(2010,cm_startyear)).. + v21_taxrevCCS(t,regi) + v21_taxrevNetNegEmi(t,regi) + sum(entyPe, v21_taxrevPE(t,regi,entyPe)) + + v21_taxrevSE(t,regi) + v21_taxrevFE(t,regi) + sum(in, v21_taxrevCES(t,regi,in)) + v21_taxrevResEx(t,regi) @@ -122,6 +123,26 @@ q21_taxrevPE(t,regi,entyPe)$(t.val ge max(2010,cm_startyear)).. v21_taxrevPE(t,regi,entyPe) =e= pm_tau_pe_tax(t,regi,entyPe) * vm_prodPe(t,regi,entyPe) - p21_taxrevPE0(t,regi,entyPe); + +***--------------------------------------------------------------------------- +*' Calculation of SE tax: tax rate times secondary energy times secondary energy demand +*' Typically, energy taxes are accounted on FE level. However, this tax is used to +*' account for taxes and grid fees for the electricity input to electrolysis, which is an SE2SE technology. +***--------------------------------------------------------------------------- + +q21_taxrevSE(t,regi)$( t.val ge max(2010, cm_startyear) ) .. + v21_taxrevSE(t,regi) + =e= + sum(se2se(enty,enty2,te)$(teSeTax(te)), +*** v21_tau_SE_tax is the (endogenous calculated) tax rate, +*** i.e. electricity price increase due to taxes and grid fees + v21_tau_SE_tax(t,regi,te) + * vm_demSe(t,regi,enty,enty2,te) + ) + - p21_taxrevSE0(t,regi) +; + + ***--------------------------------------------------------------------------- *' Calculation of final Energy taxes: effective tax rate (tax - subsidy) times FE use in the specific sector *' Documentation of overall tax approach is above at q21_taxrev. @@ -253,7 +274,7 @@ q21_taxemiMkt(t,regi,emiMkt)$(t.val ge max(2010,cm_startyear)).. ; ***--------------------------------------------------------------------------- -*' FS: Calculation of tax/subsidy on technologies with inflexible/flexible electricity input +*' Calculation of tax/subsidy on technologies with inflexible/flexible electricity input *' This is to emulate the effect of lower/higher electricity prices in high VRE systems on flexible/inflexible electricity demands. ***--------------------------------------------------------------------------- @@ -272,7 +293,7 @@ q21_taxrevFlex(t,regi)$( t.val ge max(2010, cm_startyear) ) .. ***--------------------------------------------------------------------------- -*' FS: (PE) import tax +*' (PE) import tax *' can be used to place taxes on PE energy imports *' e.g. bioenergy import taxes due to sustainability concerns by importers ***--------------------------------------------------------------------------- @@ -342,5 +363,30 @@ q21_taxrevChProdStartYear(t,regi)$(t.val ge max(2010,cm_startyear)).. ; +*' This calculates the SE tax rate for electricity going into electrolysis. +*' It contains the final energy tax rate for electricity use in industry and +*' grid fees that are assumed be equal to the investment cost of tdfels. +*' We furthermore assume that these taxes and fees are small at low shares +*' of electrolysis in total electricity demand as electrolysis has power system +*' benefits at low shares. The tax rate increases with increasing share of electrolysis +*' following a logistic curve. It starts at close to zero tax rate for a share o 0%, reaches half +*' of the full tax rate at 10% share and is within 1% of the full tax rate above a 25% share of +*' electrolysis electricity demand within total electricity demand. The parameters +*' to define this functional relationsship are set to in the preloop file. +q21_SeTaxRate(t,regi,te)$(teSeTax(te)).. + v21_tau_SE_tax(t,regi,te) + =e= +*** maximum electrolysis SE tax rate + p21_tau_SE_tax(t,regi,te) +*** logistic ramp-up function depending on electrolysis share in total electricity demand vm_shDemSeel + / ( 1 + + (exp(-p21_tau_SE_tax_rampup(t,regi,te,"a") + * (vm_shDemSeel(t,regi,te) * 100 + - p21_tau_SE_tax_rampup(t,regi,te,"b")) + ) + ) + ) +; + *** EOF ./modules/21_tax/on/equations.gms diff --git a/modules/21_tax/on/postsolve.gms b/modules/21_tax/on/postsolve.gms index eec063a23..3a5015b37 100644 --- a/modules/21_tax/on/postsolve.gms +++ b/modules/21_tax/on/postsolve.gms @@ -57,6 +57,10 @@ p21_taxrevImport0(ttot,regi,tradePe,tax_import_type_21) = p21_tau_Import(ttot,r p21_taxrevChProdStartYear0(t,regi) = sum(en2en(enty,enty2,te), vm_changeProdStartyearCost.l(t,regi,te)$( (t.val gt 2005) AND (t.val eq cm_startyear ) ) ); +p21_taxrevSE0(t,regi) = sum(se2se(enty,enty2,te)$(teSeTax(te)), + v21_tau_SE_tax.l(t,regi,te) + * vm_demSe.l(t,regi,enty,enty2,te)); + *** Save reference level of tax revenues for each iteration p21_taxrevGHG_iter(iteration+1,ttot,regi) = v21_taxrevGHG.l(ttot,regi); @@ -75,6 +79,7 @@ p21_implicitDiscRate_iter(iteration+1,ttot,regi) = v21_implicitDiscRate.l(ttot,r p21_taxrevFlex_iter(iteration+1,ttot,regi) = v21_taxrevFlex.l(ttot,regi); p21_taxrevImport_iter(iteration+1,ttot,regi,tradePe) = v21_taxrevImport.l(ttot,regi,tradePe); p21_taxrevChProdStartYear_iter(iteration+1,t,regi) = v21_taxrevChProdStartYear.l(t,regi); +p21_taxrevSE_iter(iteration+1,t,regi) = v21_taxrevSE.l(t,regi); display p21_taxrevFE_iter; diff --git a/modules/21_tax/on/preloop.gms b/modules/21_tax/on/preloop.gms index a4b2a681b..62b81c001 100644 --- a/modules/21_tax/on/preloop.gms +++ b/modules/21_tax/on/preloop.gms @@ -139,6 +139,24 @@ display p21_tau_fe_sub; display p21_tau_fe_tax; display p21_tau_pe2se_sub, p21_tau_fuEx_sub; +*** SE Tax +*** SE tax is currently used to tax electricity going into electrolysis. There is a maximum tax rate that is assumed +*** to be the sum of the industry electricity FE tax and the investment cost per unit electricity of the grid (grid fee). +*** There is a ramp up of the SE electricity tax for electrolysis depending on the share of electrolysis in total electricity demand +*** described by a logistic function. This results in low taxes for electrolysis at low shares of electrolysis in the power system +*** as the technology has system benefits in this domain. At higher shares this rapidly increases and converges towards the maximum tax rate. +*** See the equations file of the tax module for more information on the SE tax. +*** Parameter datainput needs to happen here because pm_tau_fe_tax, the final energy tax rate, is set in this file and not in the datainput file. +p21_tau_SE_tax(t,regi,"elh2") = p21_tau_fe_tax(t,regi,"indst","feels") +*** calculate grid fees as levelized cost of CAPEX from tdels, the electricity transmission and distribution grid +*** by annualising the CAPEX and dividing by the capacity factor + + pm_inco0_t(t,regi,"tdels") + * pm_teAnnuity("tdels") + / pm_cf(t,regi,"tdels"); + +p21_tau_SE_tax_rampup(t,regi,te,"a") = 0.4; +p21_tau_SE_tax_rampup(t,regi,te,"b") = 10; + *LB* initialization of vm_emiMac vm_emiMac.l(ttot,regi,enty) = 0; *LB* initialization of v21_emiALLco2neg @@ -159,4 +177,7 @@ v21_taxrevImport.l(t,regi,tradePe) = 0; *** initialize taxrevImport v21_taxrevChProdStartYear.l(t,regi) = 0; +*** initialize SE tax rate +v21_tau_SE_tax.l(t,regi,te)=0; + *** EOF ./modules/21_tax/on/preloop.gms diff --git a/modules/21_tax/on/presolve.gms b/modules/21_tax/on/presolve.gms index d1c774ddb..37b204f93 100644 --- a/modules/21_tax/on/presolve.gms +++ b/modules/21_tax/on/presolve.gms @@ -53,5 +53,8 @@ p21_taxrevImport0(ttot,regi,tradePe,tax_import_type_21) = p21_tau_Import(ttot,r p21_tau_Import(ttot, regi, tradePe, tax_import_type_21)$sameas(tax_import_type_21, "avCO2taxmarkup") * max(pm_taxCO2eqSum(ttot,regi), sum(regi2, pm_taxCO2eqSum(ttot,regi2))/(card(regi2))) * pm_cintraw(tradePe) * vm_Mport.l(ttot,regi,tradePe); p21_taxrevChProdStartYear0(t,regi) = sum(en2en(enty,enty2,te), vm_changeProdStartyearCost.l(t,regi,te)$( (t.val gt 2005) AND (t.val eq cm_startyear ) ) ); +p21_taxrevSE0(t,regi) = sum(se2se(enty,enty2,te)$(teSeTax(te)), + v21_tau_SE_tax.l(t,regi,te) + * vm_demSe.l(t,regi,enty,enty2,te)); *** EOF ./modules/21_tax/on/presolve.gms diff --git a/modules/21_tax/on/sets.gms b/modules/21_tax/on/sets.gms index 20cc7b9b5..e07908229 100644 --- a/modules/21_tax/on/sets.gms +++ b/modules/21_tax/on/sets.gms @@ -15,6 +15,19 @@ $else.regi_bio_EFTax set regi_bio_EFTax21(all_regi) "regions in which an emission-factor-based bioenergy tax is active" / %cm_regi_bioenergy_EFTax% /; $endif.regi_bio_EFTax +Sets +teSeTax(all_te) "all technologies which SE electricity demand tax" +/ +elh2 +/ + +teSeTax_coeff "coefficients of logistic function to describe relationsship between SE tax rate and share of technology in total SE demand" +/ + "a" + "b" +/ +; + *** EOF ./modules/21_tax/on/sets.gms *** Module specific set diff --git a/modules/32_power/DTcoup/not_used.txt b/modules/32_power/DTcoup/not_used.txt index 50ddbe1c0..374a11820 100644 --- a/modules/32_power/DTcoup/not_used.txt +++ b/modules/32_power/DTcoup/not_used.txt @@ -15,3 +15,4 @@ cm_emiscen,input,questionnaire cm_ccapturescen,input,questionnaire pm_boundCapCCS,input,questionnaire pm_cap0,input,questionnaire +vm_shDemSeel,input,only used in IntC realization diff --git a/modules/32_power/IntC/bounds.gms b/modules/32_power/IntC/bounds.gms index 7b524972e..ccea911d9 100644 --- a/modules/32_power/IntC/bounds.gms +++ b/modules/32_power/IntC/bounds.gms @@ -34,9 +34,11 @@ if ( cm_flex_tax eq 1, vm_capFac.lo(t,regi,teFlexTax)$(t.val ge 2010) = 0.1; vm_capFac.up(t,regi,teFlexTax)$(t.val ge 2010) = pm_cf(t,regi,teFlexTax); else -*** if flexibility tax feedback is off, only flexibliity tax benefit for flexible technologies and 0.5 capacity factor - vm_capFac.fx(t,regi,teFlex)$(t.val ge 2010) = 0.5; -*** electricity price of inflexible technologies the same w/o feedback +*** if flexibility tax feedback is off, flexibility tax benefit only for flexible technologies and capacity factors fixed. +*** Assume capacity factor of flexible electrolysis to be 0.38. +*** The value based on data from German Langfristszenarien (see flexibility tax section in datainput file). + vm_capFac.fx(t,regi,"elh2")$(t.val ge 2010) = 0.38; +*** electricity price of inflexible technologies the same as w/o feedback v32_flexPriceShare.fx(t,regi,te)$(teFlexTax(te) AND NOT(teFlex(te))) = 1; ); ); diff --git a/modules/32_power/IntC/datainput.gms b/modules/32_power/IntC/datainput.gms index b443ec499..452771b86 100644 --- a/modules/32_power/IntC/datainput.gms +++ b/modules/32_power/IntC/datainput.gms @@ -96,7 +96,18 @@ p32_flex_maxdiscount(regi,te) = p32_flex_maxdiscount(regi,te) * sm_TWa_2_MWh * s display p32_flex_maxdiscount; $offtext -*** initialize p32_PriceDurSlope parameter +*** Flexibility Tax Parameter + +*** Both flexibility tax parameters are based on a regression analysis with hourly dispatch data from high-VRE scenarios of the Langfristszenarien +*** for Germany provided by the Enertile power system model. +*** See: https://langfristszenarien.de/enertile-explorer-de/szenario-explorer/angebot.php + +*** This parameter determines by the maximum electricity price reduction for electrolysis at 100% VRE share and 0% share of electrolysis in total electricity demand. +*** Standard value is derived based on the regression of the German Langfristzenarien. p32_PriceDurSlope(regi,"elh2") = cm_PriceDurSlope_elh2; +*** Slope of increase of electricity price for electrolysis with increasing share of electrolysis in power system +*** The value of 1.1 is derived from the regression of the German Langfristzenarien. +p32_flexSeelShare_slope(t,regi,"elh2") = 1.1; + *** EOF ./modules/32_power/IntC/datainput.gms diff --git a/modules/32_power/IntC/declarations.gms b/modules/32_power/IntC/declarations.gms index c28a5f23d..78cc1a6f5 100644 --- a/modules/32_power/IntC/declarations.gms +++ b/modules/32_power/IntC/declarations.gms @@ -18,6 +18,7 @@ parameters o32_dispatchDownPe2se(ttot,all_regi,all_te) "output parameter to check by how much a pe2se te reduced its output below the normal, in % of the normal output." p32_shThresholdTotVREAddIntCost(ttot) "Total VRE share threshold above which additional integration challenges arise. Increases with time as eg in 2030, there is still little experience with managing systems with 80% VRE share. Unit: Percent" p32_FactorAddIntCostTotVRE "Multiplicative factor that influences how much the total VRE share increases integration challenges" + p32_flexSeelShare_slope(ttot,all_regi,all_te) "Slope of relationship between average electricity price for flexible technology and share of this technology in total electricity demand. Unit: [ % percentage of average electricity price / % share in electricity demand]." ; scalars @@ -31,6 +32,7 @@ positive variables v32_testdemSeShare(ttot,all_regi,all_te) "test variable for tech share of SE electricity demand" v32_TotVREshare(ttot,all_regi) "Total VRE share as calculated by summing shSeEl. Unit: Percent" v32_shAddIntCostTotVRE(ttot,all_regi) "Variable containing how much the total VRE share is above the threshold - needed to calculate additional integation costs due to total VRE share." + vm_shDemSeel(ttot,all_regi,all_te) "Share of electricity demand per technology in total electricity demand" ; equations @@ -46,17 +48,20 @@ equations q32_operatingReserve(ttot,all_regi) "operating reserve for necessary flexibility" q32_h2turbVREcapfromTestor(tall,all_regi) "calculate capacities of dummy seel<--h2 technology from storXXX technologies" q32_h2turbVREcapfromTestorUp(ttot,all_regi) "constraint h2turbVRE hydrogen turbines to be only built together with storage capacities" - q32_flexAdj(tall,all_regi,all_te) "calculate flexibility used in flexibility tax for technologies with electricity input" - q32_flexPriceShareMin "calculatae miniumum share of average electricity that flexible technologies can see" - q32_flexPriceShare(tall,all_regi,all_te) "calculate share of average electricity price that flexible technologies see" - q32_flexPriceBalance(tall,all_regi) "constraint such that flexible electricity prices balanance to average electricity price" + q32_flexAdj(ttot,all_regi,all_te) "calculate flexibility benefit or cost per flexible technology to be used by flexibility tax" + q32_flexPriceShareMin(ttot,all_regi,all_te) "calculate miniumum share of average electricity that flexible technologies can see" + q32_flexPriceShareVRE(ttot,all_regi,all_te) "calculate miniumum share of average electricity that flexible technologies can see given the current VRE share" + q32_flexPriceShare(ttot,all_regi,all_te) "calculate share of average electricity price that flexible technologies see given a certain VRE share and share of electrolysis in total electricity demand" + q32_flexPriceBalance(ttot,all_regi) "constraint such that flexible electricity prices balanance to average electricity price" q32_TotVREshare(ttot,all_regi) "calculate total VRE share" q32_shAddIntCostTotVRE(ttot,all_regi) "calculate how much total VRE share is above threshold value" + q32_shDemSeel(ttot,all_regi,all_te) "calculate share of electricity demand per technology in total electricity demand" ; variables -v32_flexPriceShare(tall,all_regi,all_te) "share of average electricity price that flexible technologies see [share: 0...1]" -v32_flexPriceShareMin(tall,all_regi,all_te) "possible minimum of share of average electricity price that flexible technologies see [share: 0...1]" -; +v32_flexPriceShare(ttot,all_regi,all_te) "share of average electricity price that flexible technologies see [share: 0...1]" +v32_flexPriceShareVRE(ttot,all_regi,all_te) "possible minimum of share of average electricity price that flexible technologies see given the current VRE share [share: 0...1]" +v32_flexPriceShareMin(ttot,all_regi,all_te) "possible minimum of share of average electricity price that flexible technologies see [share: 0...1]" +; *** EOF ./modules/32_power/IntC/declarations.gms diff --git a/modules/32_power/IntC/equations.gms b/modules/32_power/IntC/equations.gms index a9fad71b6..c309b2161 100644 --- a/modules/32_power/IntC/equations.gms +++ b/modules/32_power/IntC/equations.gms @@ -218,10 +218,15 @@ q32_operatingReserve(t,regi)$(t.val ge 2010).. ***---------------------------------------------------------------------------- *** This equation calculates the minimal flexible electricity price that flexible technologies (like elh2) can see. It is reached when the VRE share is 100%. -*** It depends on the capacity factor with a hyperbolic function. The equation ensures that by decreasing +*** It depends on the capacity factor with a hyperbolic function. The equation ensures that by decreasing *** capacity factor of flexible technologies (teFlex) these technologies see lower electricity prices given that there is a high VRE share in the power system. +*** Note: By default, capacity factors in REMIND are exogenuous (see bounds file of the power module). +*** In that standard case, the minimum electricity price for electrolysis, v32_flexPriceShareMin, only depends on p32_PriceDurSlope, +*** which is defined by scenario assumptions via the switch cm_PriceDurSlope_elh2. +*** It essentially makes an assumption about how many low electricity price hours electrolysis will run on in future VRE-based power systems. +*** The standard value is derived from data of the German Langfristszenarien (see datainput file). -*** On the derivation of the equation: +*** On the derivation of the equation: *** The formulation assumes a cubic price duration curve. That is, the effective electricity price the flexible technologies sees *** depends on the capacity factor (CF) with a cubic function centered at (0.5,1): *** p32_PriceDurSlope * (CF-0.5)^3 + 1, @@ -238,20 +243,58 @@ q32_operatingReserve(t,regi)$(t.val ge 2010).. 4 * vm_capFac(t,regi,te) ; -*** Calculates the electricity price of flexible technologies: -*** The effective flexible price linearly decreases with VRE share -*** from 1 (at 0% VRE share) to v32_flexPriceShareMin (at 100% VRE). +*** Calculates the minimum electricity price of flexible technologies depending on VRE share. +*** 100% VRE share will give v32_flexPriceShareMin, +*** 0% VRE share will give 1, i.e. no flexibility benefit or cost. +*** In the latter case, electricity price is annual average electricity price from pm_SEPrice. +*** Linear relation assumed between flexibility benefit or cost in range of 0-100% VRE share. +*** This parameterizes that flexibility benefits increase in power systems with higher VRE shares. +q32_flexPriceShareVRE(t,regi,te)$(teFlex(te)).. + v32_flexPriceShareVRE(t,regi,te) + =e= + 1 - +*** maximum flexibility benefit + ( ( 1-v32_flexPriceShareMin(t,regi,te) ) +*** VRE share + * sum(teVRE, vm_shSeEl(t,regi,teVRE))/100 + ) +; + +*** Calculate share of electricity demand per technology in total electricity demand +*** Relevant for technologies that see flexibility tax or SE (electricity) taxes. +q32_shDemSeel(t,regi,te)$(teFlex(te) OR teSeTax(te)).. + vm_shDemSeel(t,regi,te) + * sum(en2en(enty,enty2,te2)$(sameas(enty,"seel")), + vm_demSe(t,regi,enty,enty2,te2)) + =e= + sum(en2en(enty,enty2,te)$(sameas(enty,"seel")), + vm_demSe(t,regi,enty,enty2,te)) +; + +*** Calculates the electricity price of flexible technologies +*** depending on the share of the flexible technology in total electricity demand +*** At 0% demand share, v32_flexPriceShare = v32_flexPriceShareVRE from above equation. +*** Linear relation between flexibility benefit based on regression +*** from German Langfristszenarien (see datainput file). q32_flexPriceShare(t,regi,te)$(teFlex(te)).. v32_flexPriceShare(t,regi,te) =e= - 1 - (1-v32_flexPriceShareMin(t,regi,te)) * sum(teVRE, vm_shSeEl(t,regi,teVRE))/100 +*** minimum electricity price of flexible technology at this VRE share + v32_flexPriceShareVRE(t,regi,te) +*** linearly scale with share of flexible technology in total electricity demand + + p32_flexSeelShare_slope(t,regi,te) + * vm_shDemSeel(t,regi,te) ; + + + +*** Note: This equation is not active by default. This means that there is no change in electricity prices for inflexible technologies. +*** The equation is only active if cm_FlexTaxFeedback = 1. *** This balance ensures that the lower electricity prices of flexible technologies are compensated *** by higher electricity prices of inflexible technologies. Inflexible technologies are all technologies *** which are part of teFlexTax but not of teFlex. The weighted sum of *** flexible/inflexible electricity prices (v32_flexPriceShare) and electricity demand must be one. -*** Note: this is only on if cm_FlexTaxFeedback = 1. Otherwise, there is no change in electricity prices for inflexible technologies. q32_flexPriceBalance(t,regi)$(cm_FlexTaxFeedback eq 1).. sum(en2en(enty,enty2,te)$(teFlexTax(te)), vm_demSe(t,regi,enty,enty2,te)) diff --git a/modules/32_power/IntC/postsolve.gms b/modules/32_power/IntC/postsolve.gms index ca9f0a346..7442a50a7 100644 --- a/modules/32_power/IntC/postsolve.gms +++ b/modules/32_power/IntC/postsolve.gms @@ -20,6 +20,5 @@ loop(t, ); ); - *** EOF ./modules/32_power/IntC/postsolve.gms diff --git a/modules/32_power/RLDC/not_used.txt b/modules/32_power/RLDC/not_used.txt index a2d124323..a80a3d9a4 100644 --- a/modules/32_power/RLDC/not_used.txt +++ b/modules/32_power/RLDC/not_used.txt @@ -11,3 +11,4 @@ cm_VRE_supply_assumptions,input,questionnaire cm_flex_tax,input,questionnaire cm_PriceDurSlope_elh2,input,questionnaire cm_FlexTaxFeedback,input,questionnaire +vm_shDemSeel,input,only used in IntC realization