From 6577102937578eaf64ec2bf3a85163c98fee371d Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Wed, 22 Feb 2023 16:58:10 +0100 Subject: [PATCH 01/19] Add OAE to the CDR portfolio --- core/datainput.gms | 5 ++ core/sets.gms | 4 ++ main.gms | 31 +++++++++++ modules/33_CDR/portfolio/bounds.gms | 7 +++ modules/33_CDR/portfolio/datainput.gms | 27 ++++++++++ modules/33_CDR/portfolio/declarations.gms | 12 ++++- modules/33_CDR/portfolio/equations.gms | 63 +++++++++++++++-------- modules/33_CDR/portfolio/sets.gms | 14 +++++ scripts/input/exoGAINSAirpollutants.R | 4 +- scripts/input/prepare_NDC.R | 2 +- scripts/output/single/reporting.R | 3 +- scripts/start/prepare.R | 5 +- 12 files changed, 149 insertions(+), 28 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index 56d7f2e34..b0f0dbbc7 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -729,6 +729,9 @@ pm_cf(ttot,regi,"idr") = 0.8; pm_cf(ttot,regi,"idrcc") = 1.0; !! capex is derived from numbers per ton of CO2, where cf = 1 is assumed in conversion pm_cf(ttot,regi,"eaf") = 1.0; !! capex is derived from numbers per ton of CO2, where cf = 1 is assumed in conversion +*KK TODO move to mrremind* +pm_cf(ttot,regi,"oae") = 0.8; + *RP* phasing down the ngt cf to "peak load" cf of 5% pm_cf(ttot,regi,"ngt")$(ttot.val eq 2025) = 0.9 * pm_cf(ttot,regi,"ngt"); pm_cf(ttot,regi,"ngt")$(ttot.val eq 2030) = 0.8 * pm_cf(ttot,regi,"ngt"); @@ -1201,6 +1204,7 @@ loop(ttot$(ttot.val ge 2005), p_adj_seed_te(ttot,regi,"coalftcrec") = 0.25; p_adj_seed_te(ttot,regi,"coaltr") = 4.00; p_adj_seed_te(ttot,regi,'dac') = 0.25; + p_adj_seed_te(ttot,regi,'oae') = 0.25; p_adj_seed_te(ttot,regi,'geohe') = 0.33; $ifthen.cm_subsec_model_steel "%cm_subsec_model_steel%" == "processes" p_adj_seed_te(ttot,regi,"bfcc") = 0.05; @@ -1248,6 +1252,7 @@ $ifthen.WindOff %cm_wind_offshore% == "1" $endif.WindOff p_adj_coeff(ttot,regi,"dac") = 0.8; + p_adj_coeff(ttot,regi,'oae') = 0.8; p_adj_coeff(ttot,regi,teGrid) = 0.3; p_adj_coeff(ttot,regi,teStor) = 0.05; ); diff --git a/core/sets.gms b/core/sets.gms index dd972a068..f8f3d8bc3 100755 --- a/core/sets.gms +++ b/core/sets.gms @@ -268,8 +268,12 @@ $ENDIF.WindOff weathering "enhanced weathering" dac "direct air capture" +<<<<<<< HEAD oae_ng "ocean akalinity ehnacement via ocean liming using a traditional calciner" oae_el "ocean akalinity ehnacement via ocean liming using a novel calciner technology" +======= + oae "ocean alkalinity enhancement" +>>>>>>> ef6d08a4 (Add OAE to the CDR portfolio) x_gas2elec d_bio2elec "d_* transmission and distribution losses" d_coal2elec diff --git a/main.gms b/main.gms index 4294f8f27..c54338d48 100755 --- a/main.gms +++ b/main.gms @@ -861,6 +861,32 @@ parameter *' * (1): enhanced weathering is included *' * (0): not included *' +parameter + cm_33OAE "choose whether OAE (ocean alkalinity enhancement) should be included into the CDR portfolio. 0 = OAE not used, 1 = used" +; + cm_33OAE = 0; !! def = 0 +*' * (1): ocean alkalinity enhancement is included +*' * (0): not included +*' +parameter + cm_33_OAE_eff "OAE efficiency measured in tCO2 uptaken by the ocean per tCaO. Typically between 0.9-1.4. [tCO2/tCaO]" +; + cm_33_OAE_eff = 0.9; !! def = 0.9 +*' +parameter + cm_33_OAE_scen "OAE distribution scenarios" +; + cm_33_OAE_scen = 0; !! def = 0 +*' * (0): pessimistic: a rather low discharge rate (30 tCaO per h), corresponding to high distribution costs +*' * (1): optimistic: a high discharge rate (250 tCaO per h), corresponding to lower distribution costs +*' +parameter + cm_33_OAE_startyr "The year when OAE could start being deployed [year]" +; + cm_33_OAE_startyr = 2025; !! def = 2025 !! regexp = 2025|20[3-9](0|5) +*' * (2025): earliest year when OAE could be deployed +*' * (....): later timesteps +*' parameter cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" ; @@ -1567,6 +1593,11 @@ $setglobal cm_Industry_CCS_markup off !! def = off *** def <- "off" = use default floor cost for renewables. *** or list of techs with respective value to be added to the renewables floor cost in Europe $setglobal cm_renewables_floor_cost off !! def = off +*** cm_33_OAE_lim "Global limit for OAE [MtCO2 per yr]" +*** (off): no bound +*** (5000): (default) global limit of 5GtCO2 per yr +*** (any value ge 0): set maximum to that value +$setglobal cm_33_OAE_lim 5000 !! def = 5000 !! regexp = off|is.nonnegative *** cm_sehe_upper "secondary energy district heating and heat pumps upper bound" *** def <- "off" = no additional limit for district heating and heat pumps. *** or number (ex. 2), district heating and heat pumps are limited to an upper bound of 2 times the 2020 model values. diff --git a/modules/33_CDR/portfolio/bounds.gms b/modules/33_CDR/portfolio/bounds.gms index 2fd7bc04f..09eac84dd 100644 --- a/modules/33_CDR/portfolio/bounds.gms +++ b/modules/33_CDR/portfolio/bounds.gms @@ -55,4 +55,11 @@ if(not te_used33("weathering"), vm_cap.fx(t,regi,"weathering",rlf) = 0; ); +if(te_used33("oae"), +$ifthen not %cm_33_OAE_lim% == "off" + vm_emiCdrTeDetail.lo(t, regi, "oae") = - (pm_gdp("2005",regi) / sum(regi2, pm_gdp("2005", regi2))) * s33_OAE_glo_limit / sm_c_2_co2; +$endif + vm_cap.fx(t, regi, "oae", rlf)$(t.val lt cm_33_OAE_startyr) = 0; +); + *** EOF ./modules/33_CDR/portfolio/bounds.gms diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index f386d913c..18879ca74 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -49,5 +49,32 @@ p33_fedem("weathering", "fedie") = 0.3; *' Factor distributing the global rock limit across regions according to population p33_LimRock(regi) = pm_pop("2005",regi) / sum(regi2,pm_pop("2005",regi2)); + +*** ocean alkalinity enhancement input data + +!! An assumption; generally the efficiency might vary between 1.2-1.8 tCO2/tCaO, +!! depending on e.g., ocean chemistry and currents in a given region +s33_OAE_efficiency = cm_33_oae_eff / sm_c_2_co2; !! GtC (ocean uptake) per unit of GtCaO + +!! 0.78 tCO2 are emitted in the decomposition of limestone to produce 1 tCaO +s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_oae_efficiency; !! GtC from decomposition per 1GtC taken by the ocean + +p33_fedem("oae", "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO +p33_fedem("oae", "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO + +if(cm_33_OAE_scen = 0, !! pessimistic scenario for distribution, high diesel demand + p33_fedem("oae", "fedie") = 2.6 / s33_OAE_efficiency; !! 2600 MJ/tCaO +); + +if(cm_33_OAE_scen = 1, !! optimistic scenario for distribution, lower diesel demand + p33_fedem("oae", "fedie") = 0.7 / s33_OAE_efficiency; !! 674 MJ/tCaO +); + +$ifthen.OAE_glo_limit not %cm_33_OAE_lim% == "off" +*** get the global limit on OAE (if exists) in GtC per yr +s33_OAE_glo_limit = %cm_33_OAE_lim% / 1000 / sm_c_2_co2; +$endif.OAE_glo_limit + *' @stop + *** EOF ./modules/33_CDR/portfolio/datainput.gms diff --git a/modules/33_CDR/portfolio/declarations.gms b/modules/33_CDR/portfolio/declarations.gms index 9a1a43c63..bc58030ba 100644 --- a/modules/33_CDR/portfolio/declarations.gms +++ b/modules/33_CDR/portfolio/declarations.gms @@ -11,6 +11,10 @@ s33_co2_rem_rate "carbon removal rate [fraction of annual reduction o s33_costs_fix "fixed costs for mining, grinding, spreading [T$/Gt stone]" s33_step "size of bins in v33_weathering_onfield [Gt stone]" *JeS* GJ/tCO2 = EJ/Gt CO2 = 44/12 EJ/Gt C. + +s33_OAE_efficiency "the amount of rock required to sequester 1GtC [Gt rock / GtC]" +s33_OAE_chem_decomposition "the fraction of CO2 that comes from chemical decomposition in the calcination process" +s33_OAE_glo_limit "global limit for OAE [tC / a]" ; parameters @@ -34,9 +38,11 @@ equations q33_demFeCDR(ttot,all_regi,all_enty) "CDR demand balance for final energy" q33_emiCDR(ttot,all_regi) "aggregates the (negative) emissions captured by the CDR technologies" q33_H2bio_lim(ttot,all_regi) "limits H2 from bioenergy to FE - H2 demand from CDR, i.e. no H2 from bioenergy for DAC" -q33_DAC_emi(ttot,all_regi) "calculates amount of carbon captured by DAC" +q33_capconst(ttot,all_regi,all_te) "calculates amount of carbon captured by DAC and OAE" +q33_ccsbal(ttot,all_regi,all_enty,all_enty,all_te) "calculates CCS emissions from CDR technologies" + q33_DAC_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from DAC" -q33_DAC_ccsbal(ttot,all_regi,all_enty,all_enty,all_te) "calculates CCS emissions from CDR technologies" + q33_EW_capconst(ttot,all_regi) "calculates amount of ground rock spread on fields" q33_EW_onfield_tot(ttot,all_regi,rlf,rlf) "total amount of ground rock on fields" q33_EW_omcosts(ttot,all_regi) "calculates O&M costs for spreading ground rocks on fields" @@ -44,6 +50,8 @@ q33_EW_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from en q33_EW_potential(ttot,all_regi,rlf) "limits the total potential of EW per region and grade" q33_EW_emi(ttot,all_regi) "calculates amount of carbon captured by EW" q33_EW_LimEmi(ttot,all_regi) "limits EW to a maximal annual amount of ground rock of cm_LimRock" + +q33_OAE_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand for ocean alkalinity enhancement" ; *** EOF ./modules/33_CDR/portfolio/declarations.gms diff --git a/modules/33_CDR/portfolio/equations.gms b/modules/33_CDR/portfolio/equations.gms index e171ac591..0c246f31d 100644 --- a/modules/33_CDR/portfolio/equations.gms +++ b/modules/33_CDR/portfolio/equations.gms @@ -34,26 +34,16 @@ q33_emiCDR(t,regi).. ; ***--------------------------------------------------------------------------- -*' Limit the amount of H2 from biomass to the demand without CDR. -*' It's a sustainability bound to prevent a large demand for biomass. -***--------------------------------------------------------------------------- -q33_H2bio_lim(t,regi).. - sum(pe2se("pebiolc","seh2",te), vm_prodSe(t,regi,"pebiolc","seh2",te)) - =l= - vm_prodFe(t,regi,"seh2","feh2s","tdh2s") - sum(fe2cdr("feh2s",entyFe2,te_used33), v33_FEdemand(t,regi,"feh2s",entyFe2,te_used33)) - ; - +*' Calculation of (negative) CO2 emissions from capacity. +*' Negative emissions from enhanced weathering also result from decaying rock +*' spread in previous timesteps, so emissions do not equal to the capacity +*' (i.e., how much rock is spread in a given timestep). ***--------------------------------------------------------------------------- -*' #### DAC equations - -***--------------------------------------------------------------------------- -*' Calculation of (negative) atmospheric CO2 captured by direct air capture. -***--------------------------------------------------------------------------- -q33_DAC_emi(t,regi).. - vm_emiCdrTeDetail(t,regi,"dac") +q33_capconst(t, regi, te_used33)$(not sameAs(te_used33, "weathering")).. + vm_emiCdrTeDetail(t, regi, te_used33) =e= - - sum(teNoTransform2rlf33("dac",rlf), - vm_capFac(t,regi,"dac") * vm_cap(t,regi,"dac",rlf) + - sum(teNoTransform2rlf33(te_used33, rlf), + vm_capFac(t, regi, te_used33) * vm_cap(t, regi, te_used33, rlf) ) ; @@ -61,15 +51,30 @@ q33_DAC_emi(t,regi).. *' Preparation of captured emissions to enter the CCUS chain. *' The first part of the equation describes emissions captured from the ambient air, *' the second part calculates the CO2 captured from the gas used for heat production -*' assuming 90% capture rate. +*' required for all CDR assuming 90% capture rate. The third part is the CCS needed for +*' limestone decomposition emissions for ocean alkalinity enhancement. ***--------------------------------------------------------------------------- -q33_DAC_ccsbal(t,regi,ccs2te(ccsCo2(enty),enty2,te)).. - sum(teCCS2rlf(te,rlf), vm_ccs_cdr(t,regi,enty,enty2,te,rlf)) +q33_ccsbal(t, regi, ccs2te(ccsCo2(enty), enty2, te)).. + sum(teCCS2rlf(te, rlf), vm_ccs_cdr(t, regi, enty, enty2, te, rlf)) =e= - - vm_emiCdrTeDetail(t,regi,"dac") + - vm_emiCdrTeDetail(t, regi, "dac") + (1 / pm_eta_conv(t,regi,"gash2c")) * fm_dataemiglob("pegas","seh2","gash2c","cco2") * sum(fe2cdr("fegas",entyFe2,te_used33), v33_FEdemand(t,regi,"fegas", entyFe2,te_used33)) + - s33_OAE_chem_decomposition * vm_emiCdrTeDetail(t, regi, "oae") + ; + +***--------------------------------------------------------------------------- +*' Limit the amount of H2 from biomass to the demand without CDR. +*' It's a sustainability bound to prevent a large demand for biomass. +***--------------------------------------------------------------------------- +q33_H2bio_lim(t,regi).. + sum(pe2se("pebiolc","seh2",te), vm_prodSE(t,regi,"pebiolc","seh2",te)) + =l= + vm_prodFe(t,regi,"seh2","feh2s","tdh2s") - sum(fe2cdr("feh2s",entyFe2,te_used33), v33_FEdemand(t,regi,"feh2s",entyFe2,te_used33)) ; +***--------------------------------------------------------------------------- +*' #### DAC equations + ***--------------------------------------------------------------------------- *' Calculation of FE demand for DAC, i.e., electricity demand for ventilation, *' and heat demand. @@ -166,5 +171,19 @@ q33_EW_LimEmi(t,regi).. cm_LimRock * p33_LimRock(regi) ; + +***--------------------------------------------------------------------------- +*' #### OAE equations + +***--------------------------------------------------------------------------- +*' Calculation of FE demand for OAE, i.e., electricity for rock preprocessing, +*' and heat for calcination. +***--------------------------------------------------------------------------- +q33_OAE_FEdemand(t,regi,entyFe2)$sum(entyFe, fe2cdr(entyFe,entyFe2,"oae")).. + sum(fe2cdr(entyFe,entyFe2,"oae"), v33_FEdemand(t,regi,entyFe,entyFe2,"oae")) + =e= + p33_fedem("oae", entyFe2) * sm_EJ_2_TWa * (- vm_emiCdrTeDetail(t,regi,"oae")) + ; + *' @stop *** EOF ./modules/33_CDR/portfolio/equations.gms diff --git a/modules/33_CDR/portfolio/sets.gms b/modules/33_CDR/portfolio/sets.gms index cf70edd0e..123051c1c 100644 --- a/modules/33_CDR/portfolio/sets.gms +++ b/modules/33_CDR/portfolio/sets.gms @@ -11,6 +11,7 @@ te_all33(all_te) "all CDR technologies" / weathering "enhanced weathering" dac "direct air capture" + oae "ocean alkalinity enhancement" / te_used33(all_te) "used CDR technologies (specified by switches)" @@ -34,6 +35,11 @@ fe2cdr(all_enty,all_enty,all_te) "mapping of FE carriers supplying FE demand for fegas.fehes.dac feels.feels.weathering fedie.fedie.weathering + feels.feels.oae + fegas.fehes.oae + feels.fehes.oae + feh2s.fehes.oae + fedie.fedie.oae / rlf_cz33(rlf) "representing weathering rates depending on climate zones according to Strefler, Amann et al. (2017)" @@ -62,6 +68,14 @@ if(cm_33EW eq 1, teNoTransform2rlf33("weathering", "1") = YES; ); +if(cm_33OAE eq 1, + te_used33("oae") = YES; + teNoTransform33("oae") = YES; + teNoTransform2rlf33("oae", "1") = YES; + teAdj33("oae") = YES; + te_ccs33("oae") = YES; +); + ***------------------------------------------------------------------------- *** add module specific sets and mappings to the global sets and mappings ***------------------------------------------------------------------------- diff --git a/scripts/input/exoGAINSAirpollutants.R b/scripts/input/exoGAINSAirpollutants.R index d7494b6a0..0cd5de7cb 100644 --- a/scripts/input/exoGAINSAirpollutants.R +++ b/scripts/input/exoGAINSAirpollutants.R @@ -19,10 +19,12 @@ if (file.exists("log.txt")){ #rm(list=ls()) # load required packages -for (pkg in c('madrat', 'dplyr', 'remind2', 'gdx')) { +for (pkg in c('madrat', 'dplyr', 'gdx')) { suppressPackageStartupMessages(require(pkg, character.only = TRUE)) } +devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") + # stop madrat reporting its default settings _every damn time_ invisible(getConfig(option = NULL, verbose = firstIteration)) diff --git a/scripts/input/prepare_NDC.R b/scripts/input/prepare_NDC.R index 79c32a58a..64df019a7 100644 --- a/scripts/input/prepare_NDC.R +++ b/scripts/input/prepare_NDC.R @@ -11,7 +11,7 @@ prepare_NDC<-function(gdx, cfg){ library(luplot,quietly=TRUE,warn.conflicts =FALSE) library(lucode2,quietly=TRUE,warn.conflicts =FALSE) library(gdx,quietly=TRUE,warn.conflicts =FALSE) - library(remind2,quietly = TRUE,warn.conflicts =FALSE) + devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") ############################# BASIC CONFIGURATION ############################# diff --git a/scripts/output/single/reporting.R b/scripts/output/single/reporting.R index aa62ed57b..9152c2f38 100644 --- a/scripts/output/single/reporting.R +++ b/scripts/output/single/reporting.R @@ -6,7 +6,8 @@ # | Contact: remind@pik-potsdam.de library(magclass) -library(remind2) +# library(remind2) +devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") library(lucode2) library(gms) library(methods) diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index b098bc23d..47f9b1f19 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -13,7 +13,8 @@ prepare <- function() { #require(lucode, quietly = TRUE,warn.conflicts =FALSE) require(magclass, quietly = TRUE,warn.conflicts =FALSE) require(tools, quietly = TRUE,warn.conflicts =FALSE) - require(remind2, quietly = TRUE,warn.conflicts =FALSE) + devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") + # require(remind2) require(mrremind) require(mrvalidation) @@ -519,6 +520,8 @@ prepare <- function() { list(c("q33_DacFEdemand_heat.M", "!!q33_DacFEdemand_heat.M")), list(c("q33_DacFEdemand_el.M", "!!q33_DacFEdemand_el.M")), list(c("q33_capconst_dac.M", "!!q33_capconst_dac.M")), + list(c("q33_DAC_capconst.M", "!!q33_DAC_capconst.M")), + list(c("q33_DAC_ccsbal.M", "!!q33_DAC_ccsbal.M")), list(c("q33_ccsbal.M", "!!q33_ccsbal.M")), list(c("q33_H2bio_lim.M", "!!q33_H2bio_lim.M")), list(c("q33_demFeCDR.M", "!!q33_demFeCDR.M")), From d4a925637d5d16ecfab173658e2374e4d441e59f Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Wed, 17 Apr 2024 11:53:51 +0200 Subject: [PATCH 02/19] Add qttyTarget to OAE --- main.gms | 2 +- modules/33_CDR/portfolio/bounds.gms | 1 + modules/33_CDR/portfolio/datainput.gms | 6 +++++- modules/47_regipol/regiCarbonPrice/datainput.gms | 1 + modules/47_regipol/regiCarbonPrice/equations.gms | 4 ++++ modules/47_regipol/regiCarbonPrice/postsolve.gms | 6 ++++++ modules/47_regipol/regiCarbonPrice/presolve.gms | 3 +++ modules/47_regipol/regiCarbonPrice/sets.gms | 5 +++-- 8 files changed, 24 insertions(+), 4 deletions(-) diff --git a/main.gms b/main.gms index c54338d48..5bf95598a 100755 --- a/main.gms +++ b/main.gms @@ -1344,7 +1344,7 @@ $setGlobal cm_proNucRegiPol off !! def = off $setGlobal cm_CCSRegiPol off !! def = off *** cm_vehiclesSubsidies - If "on" applies country specific BEV and FCEV subsidies from 2020 onwards $setGlobal cm_vehiclesSubsidies off !! def = off -*** cm_implicitQttyTarget - Define quantity target for primary, secondary, final energy or CCS (PE, SE and FE in TWa, or CCS in Mt CO2) per target group (total, biomass, fossil, VRE, renewables, synthetic, ...). +*** cm_implicitQttyTarget - Define quantity target for primary, secondary, final energy or CCS (PE, SE and FE in TWa, or CCS and OAE in Mt CO2) per target group (total, biomass, fossil, VRE, renewables, synthetic, ...). *** The target is achieved by an endogenous calculated markup in the form or a tax or subsidy in between iterations. *** If cm_implicitQttyTargetType is set to "config", the quantity targets will be defined directly in this switch. Check below for examples on how to do this. *** If cm_implicitQttyTargetType is set to "scenario", you should define the list of pre-defined scenarios hard-coded in module '47_regipol' that should be active for the current run (this avoids reaching the 255 characters limit in more complex definitions). diff --git a/modules/33_CDR/portfolio/bounds.gms b/modules/33_CDR/portfolio/bounds.gms index 09eac84dd..069dfd0b2 100644 --- a/modules/33_CDR/portfolio/bounds.gms +++ b/modules/33_CDR/portfolio/bounds.gms @@ -56,6 +56,7 @@ if(not te_used33("weathering"), ); if(te_used33("oae"), +*** Limiting deployment proportional to GDP, an alternative is to use qttyTarget (preferred) $ifthen not %cm_33_OAE_lim% == "off" vm_emiCdrTeDetail.lo(t, regi, "oae") = - (pm_gdp("2005",regi) / sum(regi2, pm_gdp("2005", regi2))) * s33_OAE_glo_limit / sm_c_2_co2; $endif diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index 18879ca74..99952c708 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -71,10 +71,14 @@ if(cm_33_OAE_scen = 1, !! optimistic scenario for distribution, lower diesel dem ); $ifthen.OAE_glo_limit not %cm_33_OAE_lim% == "off" -*** get the global limit on OAE (if exists) in GtC per yr +*** get the global limit on OAE (if exists) in GtC per yr, +*** the limit is set in bounds.gms, and distributed among regions proportional to GDP +*** note that an alternative to using this is the qttyTarget (preferred) s33_OAE_glo_limit = %cm_33_OAE_lim% / 1000 / sm_c_2_co2; $endif.OAE_glo_limit +vm_costTeCapital.fx(t,regi,"oae") = pm_inco0_t(t, regi, "oae") / s33_OAE_efficiency; + *' @stop *** EOF ./modules/33_CDR/portfolio/datainput.gms diff --git a/modules/47_regipol/regiCarbonPrice/datainput.gms b/modules/47_regipol/regiCarbonPrice/datainput.gms index a12c04100..2670a6309 100644 --- a/modules/47_regipol/regiCarbonPrice/datainput.gms +++ b/modules/47_regipol/regiCarbonPrice/datainput.gms @@ -155,6 +155,7 @@ $endif.cm_implicitQttyTargetType p47_implicitQttyTargetIterationCount(ext_regi) = 0; *** intialize energy type bound implicit target parameters pm_implicitQttyTarget(ttot,ext_regi,taxType,targetType,"CCS",qttyTargetGroup)$pm_implicitQttyTarget(ttot,ext_regi,taxType,targetType,"CCS",qttyTargetGroup) = pm_implicitQttyTarget(ttot,ext_regi,taxType,targetType,"CCS",qttyTargetGroup)/(sm_c_2_co2*1000); + pm_implicitQttyTarget(ttot,ext_regi,taxType,targetType,"oae",qttyTargetGroup)$pm_implicitQttyTarget(ttot,ext_regi,taxType,targetType,"oae",qttyTargetGroup) = pm_implicitQttyTarget(ttot,ext_regi,taxType,targetType,"oae",qttyTargetGroup)/(sm_c_2_co2*1000); p47_implicitQttyTargetTax0(t,all_regi) = 0; $endIf.cm_implicitQttyTarget diff --git a/modules/47_regipol/regiCarbonPrice/equations.gms b/modules/47_regipol/regiCarbonPrice/equations.gms index 242f27d10..82f695678 100644 --- a/modules/47_regipol/regiCarbonPrice/equations.gms +++ b/modules/47_regipol/regiCarbonPrice/equations.gms @@ -32,6 +32,10 @@ q47_implicitQttyTargetTax(t,regi)$(t.val ge max(2010,cm_startyear)).. ( p47_implicitQttyTargetTax(t,regi,qttyTarget,qttyTargetGroup) * sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS(t,regi,enty,enty2,te,rlf))) )$(sameas(qttyTarget,"CCS")) + + + ( + p47_implicitQttyTargetTax(t,regi,qttyTarget,qttyTargetGroup) * (-vm_emiCdrTeDetail(t,regi,"oae")) + )$(sameas(qttyTarget,"oae")) ) - p47_implicitQttyTargetTax0(t,regi) diff --git a/modules/47_regipol/regiCarbonPrice/postsolve.gms b/modules/47_regipol/regiCarbonPrice/postsolve.gms index 3f75c13d2..74d0ff386 100644 --- a/modules/47_regipol/regiCarbonPrice/postsolve.gms +++ b/modules/47_regipol/regiCarbonPrice/postsolve.gms @@ -497,6 +497,9 @@ p47_implicitQttyTargetTax0(t,regi) = ( sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS.l(t,regi,enty,enty2,te,rlf))) )$(sameas(qttyTarget,"CCS") AND sameas(qttyTargetGroup,"all")) + + ( -vm_emiCdrTeDetail.l(t,regi,"oae") + )$(sameas(qttyTarget,"oae") AND sameas(qttyTargetGroup,"all")) + + (( !! Supply side BECCS sum(emiBECCS2te(enty,enty2,te,enty3),vm_emiTeDetail.l(t,regi,enty,enty2,te,enty3)) !! Industry BECCS (using biofuels in Industry with CCS) @@ -527,6 +530,9 @@ loop((ttot,ext_regi,taxType,targetType,qttyTarget,qttyTargetGroup)$pm_implicitQt ( sum(regi$regi_groupExt(ext_regi,regi), sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS.l(ttot,regi,enty,enty2,te,rlf)))) )$(sameas(qttyTarget,"CCS") AND sameas(qttyTargetGroup,"all")) + + ( sum(regi$regi_groupExt(ext_regi,regi), -vm_emiCdrTeDetail.l(ttot,regi,"oae")) + )$(sameas(qttyTarget,"oae") AND sameas(qttyTargetGroup,"all")) + + sum(regi$regi_groupExt(ext_regi,regi), ( !! Supply side BECCS sum(emiBECCS2te(enty,enty2,te,enty3),vm_emiTeDetail.l(ttot,regi,enty,enty2,te,enty3)) !! Industry BECCS (using biofuels in Industry with CCS) diff --git a/modules/47_regipol/regiCarbonPrice/presolve.gms b/modules/47_regipol/regiCarbonPrice/presolve.gms index 645404d86..b7798a56a 100644 --- a/modules/47_regipol/regiCarbonPrice/presolve.gms +++ b/modules/47_regipol/regiCarbonPrice/presolve.gms @@ -51,6 +51,9 @@ p47_implicitQttyTargetTax0(t,regi) = ( sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS.l(t,regi,enty,enty2,te,rlf))) )$(sameas(qttyTarget,"CCS") AND sameas(qttyTargetGroup,"all")) + + ( -vm_emiCdrTeDetail.l(t,regi,"oae") + )$(sameas(qttyTarget,"oae") AND sameas(qttyTargetGroup,"all")) + + (( !! Supply side BECCS sum(emiBECCS2te(enty,enty2,te,enty3),vm_emiTeDetail.l(t,regi,enty,enty2,te,enty3)) !! Industry BECCS (using biofuels in Industry with CCS) diff --git a/modules/47_regipol/regiCarbonPrice/sets.gms b/modules/47_regipol/regiCarbonPrice/sets.gms index d4c725822..cc9d36ccf 100644 --- a/modules/47_regipol/regiCarbonPrice/sets.gms +++ b/modules/47_regipol/regiCarbonPrice/sets.gms @@ -30,7 +30,7 @@ $ifThen.emiMkt not "%cm_emiMktTarget%" == "off" regiEmiMktconvergenceType(iteration,ttot,ttot,ext_regi,emiMktExt,convergenceType) "saving convergence type in iteration" / / $ENDIF.emiMkt -*** Implicit tax/subsidy necessary to achieve quantity target for primary, secondary, final energy and/or CCS +*** Implicit tax/subsidy necessary to achieve quantity target for primary, secondary, final energy and/or CCS and/or OAE $ifthen.cm_implicitQttyTarget not "%cm_implicitQttyTarget%" == "off" taxType "PE, SE or FE tax type" @@ -45,7 +45,7 @@ targetType "PE, SE or FE target type" s "relative target (s=share)" / -qttyTarget "quantity target for energy carrier level (primary, secondary, final energy) or CCS" +qttyTarget "quantity target for energy carrier level (primary, secondary, final energy) or CCS or OAE" / PE "Primary Energy" SE "Secondary Energy" @@ -54,6 +54,7 @@ qttyTarget "quantity target for energy carrier level (primary, secondary, final FE_wo_n_e "Final Energy without non-energy" FE_wo_b_wo_n_e "Final Energy without bunkers and non-energy" CCS "carbon capture and storage" + oae "ocean alkalinity enhancement" / qttyTargetGroup "quantity target aggregated categories" From fbfce721fafebfbed7ad243cfa214b530be06665 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Tue, 21 May 2024 16:34:09 +0200 Subject: [PATCH 03/19] Update paths to remind2 --- scripts/input/exoGAINSAirpollutants.R | 2 +- scripts/input/prepare_NDC.R | 2 +- scripts/output/single/reporting.R | 2 +- scripts/start/prepare.R | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/input/exoGAINSAirpollutants.R b/scripts/input/exoGAINSAirpollutants.R index 0cd5de7cb..ac0136aa9 100644 --- a/scripts/input/exoGAINSAirpollutants.R +++ b/scripts/input/exoGAINSAirpollutants.R @@ -23,7 +23,7 @@ for (pkg in c('madrat', 'dplyr', 'gdx')) { suppressPackageStartupMessages(require(pkg, character.only = TRUE)) } -devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") +devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") # stop madrat reporting its default settings _every damn time_ invisible(getConfig(option = NULL, verbose = firstIteration)) diff --git a/scripts/input/prepare_NDC.R b/scripts/input/prepare_NDC.R index 64df019a7..6dfa6e2b7 100644 --- a/scripts/input/prepare_NDC.R +++ b/scripts/input/prepare_NDC.R @@ -11,7 +11,7 @@ prepare_NDC<-function(gdx, cfg){ library(luplot,quietly=TRUE,warn.conflicts =FALSE) library(lucode2,quietly=TRUE,warn.conflicts =FALSE) library(gdx,quietly=TRUE,warn.conflicts =FALSE) - devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") + devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") ############################# BASIC CONFIGURATION ############################# diff --git a/scripts/output/single/reporting.R b/scripts/output/single/reporting.R index 9152c2f38..fc43528fc 100644 --- a/scripts/output/single/reporting.R +++ b/scripts/output/single/reporting.R @@ -7,7 +7,7 @@ library(magclass) # library(remind2) -devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") +devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") library(lucode2) library(gms) library(methods) diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index 47f9b1f19..daedcbe31 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -13,7 +13,7 @@ prepare <- function() { #require(lucode, quietly = TRUE,warn.conflicts =FALSE) require(magclass, quietly = TRUE,warn.conflicts =FALSE) require(tools, quietly = TRUE,warn.conflicts =FALSE) - devtools::load_all("/p/tmp/katarkow/remind2/rebased-cdr-portfolio-oae") + devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") # require(remind2) require(mrremind) require(mrvalidation) From 0ac58d18f95345632f2cf06df30af184e06ec90a Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Wed, 12 Jun 2024 11:29:27 +0200 Subject: [PATCH 04/19] Update OAE costs --- core/datainput.gms | 3 +++ core/input/generisdata_tech.prn | 7 +++++++ modules/33_CDR/portfolio/datainput.gms | 6 ++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index b0f0dbbc7..af513f6a6 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -261,6 +261,9 @@ p_inco0(ttot,regi,te) = s_DpKW_2_TDpTW * p_inco0(ttot,regi,t fm_dataglob("inco0","csp") = 0.7 * fm_dataglob("inco0","csp"); fm_dataglob("incolearn","csp") = 0.7 * fm_dataglob("incolearn","csp"); +*KK* adjust costs for oae from USD/GtCaO to USD/GtC +fm_dataglob("inco0", "oae") = fm_dataglob("inco0", "oae") / (cm_33_oae_eff / sm_c_2_co2); +fm_dataglob("omf", "oae") = fm_dataglob("omf", "oae") / (cm_33_oae_eff / sm_c_2_co2); *** -------------------------------------------------------------------------------- *** Regionalize technology investment cost data diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index f1f712a65..bbcf3d286 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -157,10 +157,17 @@ lifetime 45 45 45 + weathering dac oae_ng oae_el tech_stat 4 +<<<<<<< HEAD inco0 0.01 18800 200 400 mix0 0 0 0 0 eta 1.00 1.00 1.00 1.00 omf 0.84 0.025 0.35 0.17 +======= +inco0 0.01 18800 400 +mix0 0 0 0 +eta 1.00 1.00 1.00 +omf 0.84 0.025 0.2 +>>>>>>> a171f380 (Update OAE costs) omv 0 lifetime 20 20 25 25 incolearn 14000 diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index 99952c708..f3e720d25 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -50,14 +50,14 @@ p33_fedem("weathering", "fedie") = 0.3; *' Factor distributing the global rock limit across regions according to population p33_LimRock(regi) = pm_pop("2005",regi) / sum(regi2,pm_pop("2005",regi2)); -*** ocean alkalinity enhancement input data +*** ocean alkalinity enhancement input data (Kowalczyk et al., 2024) !! An assumption; generally the efficiency might vary between 1.2-1.8 tCO2/tCaO, !! depending on e.g., ocean chemistry and currents in a given region s33_OAE_efficiency = cm_33_oae_eff / sm_c_2_co2; !! GtC (ocean uptake) per unit of GtCaO !! 0.78 tCO2 are emitted in the decomposition of limestone to produce 1 tCaO -s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_oae_efficiency; !! GtC from decomposition per 1GtC taken by the ocean +s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_oae_efficiency; !! GtC from decomposition per 1GtC taken by the ocean, 0.78 t/tCaO p33_fedem("oae", "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO p33_fedem("oae", "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO @@ -77,8 +77,6 @@ $ifthen.OAE_glo_limit not %cm_33_OAE_lim% == "off" s33_OAE_glo_limit = %cm_33_OAE_lim% / 1000 / sm_c_2_co2; $endif.OAE_glo_limit -vm_costTeCapital.fx(t,regi,"oae") = pm_inco0_t(t, regi, "oae") / s33_OAE_efficiency; - *' @stop *** EOF ./modules/33_CDR/portfolio/datainput.gms From bdad78f3afbf341da13a4641ac2098ddbeabaad6 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Wed, 19 Jun 2024 11:56:58 +0200 Subject: [PATCH 05/19] Update parameters, matching to OAE NG, lower omf --- core/input/generisdata_tech.prn | 7 +++++++ main.gms | 2 +- modules/33_CDR/portfolio/datainput.gms | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index bbcf3d286..f54b81229 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -158,6 +158,7 @@ lifetime 45 45 45 + weathering dac oae_ng oae_el tech_stat 4 <<<<<<< HEAD +<<<<<<< HEAD inco0 0.01 18800 200 400 mix0 0 0 0 0 eta 1.00 1.00 1.00 1.00 @@ -168,6 +169,12 @@ mix0 0 0 0 eta 1.00 1.00 1.00 omf 0.84 0.025 0.2 >>>>>>> a171f380 (Update OAE costs) +======= +inco0 0.01 18800 200 +mix0 0 0 0 +eta 1.00 1.00 1.00 +omf 0.84 0.025 0.07 +>>>>>>> 8228b98d (Update parameters, matching to OAE NG, lower omf) omv 0 lifetime 20 20 25 25 incolearn 14000 diff --git a/main.gms b/main.gms index 5bf95598a..1038fb15d 100755 --- a/main.gms +++ b/main.gms @@ -1597,7 +1597,7 @@ $setglobal cm_renewables_floor_cost off !! def = off *** (off): no bound *** (5000): (default) global limit of 5GtCO2 per yr *** (any value ge 0): set maximum to that value -$setglobal cm_33_OAE_lim 5000 !! def = 5000 !! regexp = off|is.nonnegative +$setglobal cm_33_OAE_lim off !! def = 5000 !! regexp = off|is.nonnegative *** cm_sehe_upper "secondary energy district heating and heat pumps upper bound" *** def <- "off" = no additional limit for district heating and heat pumps. *** or number (ex. 2), district heating and heat pumps are limited to an upper bound of 2 times the 2020 model values. diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index f3e720d25..b758de0c8 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -63,11 +63,11 @@ p33_fedem("oae", "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO p33_fedem("oae", "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO if(cm_33_OAE_scen = 0, !! pessimistic scenario for distribution, high diesel demand - p33_fedem("oae", "fedie") = 2.6 / s33_OAE_efficiency; !! 2600 MJ/tCaO + p33_fedem("oae", "fedie") = 2.6 / s33_OAE_efficiency; !! 2600 MJ/tCaO (corresponds to discharge rate of 30 t/h) ); if(cm_33_OAE_scen = 1, !! optimistic scenario for distribution, lower diesel demand - p33_fedem("oae", "fedie") = 0.7 / s33_OAE_efficiency; !! 674 MJ/tCaO + p33_fedem("oae", "fedie") = 0.77 / s33_OAE_efficiency; !! 770 MJ/tCaO (corresponds to the discharge rate of 100 t/h) ); $ifthen.OAE_glo_limit not %cm_33_OAE_lim% == "off" From d65f6ebb2e40cccc92068892f878f38482fbd3cb Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Thu, 4 Jul 2024 11:18:28 +0200 Subject: [PATCH 06/19] Split into natural gas calciner and novel calciner --- core/datainput.gms | 13 +++++--- core/input/generisdata_tech.prn | 14 -------- core/sets.gms | 4 --- main.gms | 5 --- modules/33_CDR/portfolio/bounds.gms | 8 ++--- modules/33_CDR/portfolio/datainput.gms | 15 +++------ modules/33_CDR/portfolio/declarations.gms | 2 +- modules/33_CDR/portfolio/equations.gms | 8 ++--- modules/33_CDR/portfolio/sets.gms | 32 ++++++++++++------- .../47_regipol/regiCarbonPrice/equations.gms | 2 +- .../47_regipol/regiCarbonPrice/postsolve.gms | 4 +-- .../47_regipol/regiCarbonPrice/presolve.gms | 2 +- scripts/input/exoGAINSAirpollutants.R | 3 +- scripts/input/prepare_NDC.R | 3 +- scripts/output/single/reporting.R | 2 +- scripts/start/prepare.R | 12 ++++--- 16 files changed, 57 insertions(+), 72 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index af513f6a6..c61d0b686 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -262,8 +262,8 @@ fm_dataglob("inco0","csp") = 0.7 * fm_dataglob("inco0","csp"); fm_dataglob("incolearn","csp") = 0.7 * fm_dataglob("incolearn","csp"); *KK* adjust costs for oae from USD/GtCaO to USD/GtC -fm_dataglob("inco0", "oae") = fm_dataglob("inco0", "oae") / (cm_33_oae_eff / sm_c_2_co2); -fm_dataglob("omf", "oae") = fm_dataglob("omf", "oae") / (cm_33_oae_eff / sm_c_2_co2); +fm_dataglob("inco0", "oae_ng") = fm_dataglob("inco0", "oae_ng") / (cm_33_oae_eff / sm_c_2_co2); +fm_dataglob("inco0", "oae_el") = fm_dataglob("inco0", "oae_el") / (cm_33_oae_eff / sm_c_2_co2); *** -------------------------------------------------------------------------------- *** Regionalize technology investment cost data @@ -733,7 +733,8 @@ pm_cf(ttot,regi,"idrcc") = 1.0; !! capex is derived from numbers per ton of CO2, pm_cf(ttot,regi,"eaf") = 1.0; !! capex is derived from numbers per ton of CO2, where cf = 1 is assumed in conversion *KK TODO move to mrremind* -pm_cf(ttot,regi,"oae") = 0.8; +pm_cf(ttot,regi,"oae_ng") = 0.8; +pm_cf(ttot,regi,"oae_el") = 0.8; *RP* phasing down the ngt cf to "peak load" cf of 5% pm_cf(ttot,regi,"ngt")$(ttot.val eq 2025) = 0.9 * pm_cf(ttot,regi,"ngt"); @@ -1207,7 +1208,8 @@ loop(ttot$(ttot.val ge 2005), p_adj_seed_te(ttot,regi,"coalftcrec") = 0.25; p_adj_seed_te(ttot,regi,"coaltr") = 4.00; p_adj_seed_te(ttot,regi,'dac') = 0.25; - p_adj_seed_te(ttot,regi,'oae') = 0.25; + p_adj_seed_te(ttot,regi,'oae_ng') = 0.25; + p_adj_seed_te(ttot,regi,'oae_el') = 0.25; p_adj_seed_te(ttot,regi,'geohe') = 0.33; $ifthen.cm_subsec_model_steel "%cm_subsec_model_steel%" == "processes" p_adj_seed_te(ttot,regi,"bfcc") = 0.05; @@ -1255,7 +1257,8 @@ $ifthen.WindOff %cm_wind_offshore% == "1" $endif.WindOff p_adj_coeff(ttot,regi,"dac") = 0.8; - p_adj_coeff(ttot,regi,'oae') = 0.8; + p_adj_coeff(ttot,regi,'oae_ng') = 0.8; + p_adj_coeff(ttot,regi,'oae_el') = 0.8; p_adj_coeff(ttot,regi,teGrid) = 0.3; p_adj_coeff(ttot,regi,teStor) = 0.05; ); diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index f54b81229..f1f712a65 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -157,24 +157,10 @@ lifetime 45 45 45 + weathering dac oae_ng oae_el tech_stat 4 -<<<<<<< HEAD -<<<<<<< HEAD inco0 0.01 18800 200 400 mix0 0 0 0 0 eta 1.00 1.00 1.00 1.00 omf 0.84 0.025 0.35 0.17 -======= -inco0 0.01 18800 400 -mix0 0 0 0 -eta 1.00 1.00 1.00 -omf 0.84 0.025 0.2 ->>>>>>> a171f380 (Update OAE costs) -======= -inco0 0.01 18800 200 -mix0 0 0 0 -eta 1.00 1.00 1.00 -omf 0.84 0.025 0.07 ->>>>>>> 8228b98d (Update parameters, matching to OAE NG, lower omf) omv 0 lifetime 20 20 25 25 incolearn 14000 diff --git a/core/sets.gms b/core/sets.gms index f8f3d8bc3..dd972a068 100755 --- a/core/sets.gms +++ b/core/sets.gms @@ -268,12 +268,8 @@ $ENDIF.WindOff weathering "enhanced weathering" dac "direct air capture" -<<<<<<< HEAD oae_ng "ocean akalinity ehnacement via ocean liming using a traditional calciner" oae_el "ocean akalinity ehnacement via ocean liming using a novel calciner technology" -======= - oae "ocean alkalinity enhancement" ->>>>>>> ef6d08a4 (Add OAE to the CDR portfolio) x_gas2elec d_bio2elec "d_* transmission and distribution losses" d_coal2elec diff --git a/main.gms b/main.gms index 1038fb15d..3d8c18ffe 100755 --- a/main.gms +++ b/main.gms @@ -1593,11 +1593,6 @@ $setglobal cm_Industry_CCS_markup off !! def = off *** def <- "off" = use default floor cost for renewables. *** or list of techs with respective value to be added to the renewables floor cost in Europe $setglobal cm_renewables_floor_cost off !! def = off -*** cm_33_OAE_lim "Global limit for OAE [MtCO2 per yr]" -*** (off): no bound -*** (5000): (default) global limit of 5GtCO2 per yr -*** (any value ge 0): set maximum to that value -$setglobal cm_33_OAE_lim off !! def = 5000 !! regexp = off|is.nonnegative *** cm_sehe_upper "secondary energy district heating and heat pumps upper bound" *** def <- "off" = no additional limit for district heating and heat pumps. *** or number (ex. 2), district heating and heat pumps are limited to an upper bound of 2 times the 2020 model values. diff --git a/modules/33_CDR/portfolio/bounds.gms b/modules/33_CDR/portfolio/bounds.gms index 069dfd0b2..90e11687e 100644 --- a/modules/33_CDR/portfolio/bounds.gms +++ b/modules/33_CDR/portfolio/bounds.gms @@ -55,12 +55,8 @@ if(not te_used33("weathering"), vm_cap.fx(t,regi,"weathering",rlf) = 0; ); -if(te_used33("oae"), -*** Limiting deployment proportional to GDP, an alternative is to use qttyTarget (preferred) -$ifthen not %cm_33_OAE_lim% == "off" - vm_emiCdrTeDetail.lo(t, regi, "oae") = - (pm_gdp("2005",regi) / sum(regi2, pm_gdp("2005", regi2))) * s33_OAE_glo_limit / sm_c_2_co2; -$endif - vm_cap.fx(t, regi, "oae", rlf)$(t.val lt cm_33_OAE_startyr) = 0; +if(card(te_oae33) ne 0, + vm_cap.fx(t, regi, te_oae33, rlf)$(t.val lt cm_33_OAE_startyr) = 0; ); *** EOF ./modules/33_CDR/portfolio/bounds.gms diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index b758de0c8..b5c6a1f83 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -59,24 +59,17 @@ s33_OAE_efficiency = cm_33_oae_eff / sm_c_2_co2; !! GtC (ocean uptake) per uni !! 0.78 tCO2 are emitted in the decomposition of limestone to produce 1 tCaO s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_oae_efficiency; !! GtC from decomposition per 1GtC taken by the ocean, 0.78 t/tCaO -p33_fedem("oae", "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO -p33_fedem("oae", "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO +p33_fedem(te_oae33, "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO +p33_fedem(te_oae33, "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO if(cm_33_OAE_scen = 0, !! pessimistic scenario for distribution, high diesel demand - p33_fedem("oae", "fedie") = 2.6 / s33_OAE_efficiency; !! 2600 MJ/tCaO (corresponds to discharge rate of 30 t/h) + p33_fedem(te_oae33, "fedie") = 2.6 / s33_OAE_efficiency; !! 2600 MJ/tCaO (corresponds to discharge rate of 30 t/h) ); if(cm_33_OAE_scen = 1, !! optimistic scenario for distribution, lower diesel demand - p33_fedem("oae", "fedie") = 0.77 / s33_OAE_efficiency; !! 770 MJ/tCaO (corresponds to the discharge rate of 100 t/h) + p33_fedem(te_oae33, "fedie") = 0.77 / s33_OAE_efficiency; !! 770 MJ/tCaO (corresponds to the discharge rate of 100 t/h) ); -$ifthen.OAE_glo_limit not %cm_33_OAE_lim% == "off" -*** get the global limit on OAE (if exists) in GtC per yr, -*** the limit is set in bounds.gms, and distributed among regions proportional to GDP -*** note that an alternative to using this is the qttyTarget (preferred) -s33_OAE_glo_limit = %cm_33_OAE_lim% / 1000 / sm_c_2_co2; -$endif.OAE_glo_limit - *' @stop *** EOF ./modules/33_CDR/portfolio/datainput.gms diff --git a/modules/33_CDR/portfolio/declarations.gms b/modules/33_CDR/portfolio/declarations.gms index bc58030ba..1aa1eb2c7 100644 --- a/modules/33_CDR/portfolio/declarations.gms +++ b/modules/33_CDR/portfolio/declarations.gms @@ -51,7 +51,7 @@ q33_EW_potential(ttot,all_regi,rlf) "limits the total potential of EW per regio q33_EW_emi(ttot,all_regi) "calculates amount of carbon captured by EW" q33_EW_LimEmi(ttot,all_regi) "limits EW to a maximal annual amount of ground rock of cm_LimRock" -q33_OAE_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand for ocean alkalinity enhancement" +q33_OAE_FEdemand(ttot,all_regi,all_enty,all_te) "calculates final energy demand for ocean alkalinity enhancement" ; *** EOF ./modules/33_CDR/portfolio/declarations.gms diff --git a/modules/33_CDR/portfolio/equations.gms b/modules/33_CDR/portfolio/equations.gms index 0c246f31d..fdf277693 100644 --- a/modules/33_CDR/portfolio/equations.gms +++ b/modules/33_CDR/portfolio/equations.gms @@ -59,7 +59,7 @@ q33_ccsbal(t, regi, ccs2te(ccsCo2(enty), enty2, te)).. =e= - vm_emiCdrTeDetail(t, regi, "dac") + (1 / pm_eta_conv(t,regi,"gash2c")) * fm_dataemiglob("pegas","seh2","gash2c","cco2") * sum(fe2cdr("fegas",entyFe2,te_used33), v33_FEdemand(t,regi,"fegas", entyFe2,te_used33)) - - s33_OAE_chem_decomposition * vm_emiCdrTeDetail(t, regi, "oae") + - s33_OAE_chem_decomposition * sum(te_oae33, vm_emiCdrTeDetail(t, regi, te_oae33)) ; ***--------------------------------------------------------------------------- @@ -179,10 +179,10 @@ q33_EW_LimEmi(t,regi).. *' Calculation of FE demand for OAE, i.e., electricity for rock preprocessing, *' and heat for calcination. ***--------------------------------------------------------------------------- -q33_OAE_FEdemand(t,regi,entyFe2)$sum(entyFe, fe2cdr(entyFe,entyFe2,"oae")).. - sum(fe2cdr(entyFe,entyFe2,"oae"), v33_FEdemand(t,regi,entyFe,entyFe2,"oae")) +q33_OAE_FEdemand(t,regi,entyFe2, te_oae33)$sum(entyFe, fe2cdr(entyFe,entyFe2,te_oae33)).. + sum(fe2cdr(entyFe, entyFe2, te_oae33), v33_FEdemand(t, regi, entyFe, entyFe2, te_oae33)) =e= - p33_fedem("oae", entyFe2) * sm_EJ_2_TWa * (- vm_emiCdrTeDetail(t,regi,"oae")) + p33_fedem(te_oae33, entyFe2) * sm_EJ_2_TWa * (- vm_emiCdrTeDetail(t, regi, te_oae33)) ; *' @stop diff --git a/modules/33_CDR/portfolio/sets.gms b/modules/33_CDR/portfolio/sets.gms index 123051c1c..0631ec6c9 100644 --- a/modules/33_CDR/portfolio/sets.gms +++ b/modules/33_CDR/portfolio/sets.gms @@ -11,11 +11,14 @@ te_all33(all_te) "all CDR technologies" / weathering "enhanced weathering" dac "direct air capture" - oae "ocean alkalinity enhancement" + oae_ng "ocean alkalinity enhancement, natural gas calciner" + oae_el "ocean alkalinity enhancement, electric calciner" / te_used33(all_te) "used CDR technologies (specified by switches)" +te_oae33(all_te) "OAE technologies used" + teNoTransform33(all_te) "used CDR technologies that do not transform energy but still have investment and O&M costs (like storage or grid)" teNoTransform2rlf33(all_te,rlf) "mapping for final energy to grades (used CDR technologies)" @@ -33,13 +36,18 @@ fe2cdr(all_enty,all_enty,all_te) "mapping of FE carriers supplying FE demand for feels.fehes.dac feh2s.fehes.dac fegas.fehes.dac + feels.feels.weathering fedie.fedie.weathering - feels.feels.oae - fegas.fehes.oae - feels.fehes.oae - feh2s.fehes.oae - fedie.fedie.oae + + feels.feels.oae_ng + fedie.fedie.oae_ng + fegas.fehes.oae_ng + + feels.feels.oae_el + fedie.fedie.oae_el + feels.fehes.oae_el + feh2s.fehes.oae_el / rlf_cz33(rlf) "representing weathering rates depending on climate zones according to Strefler, Amann et al. (2017)" @@ -69,11 +77,13 @@ if(cm_33EW eq 1, ); if(cm_33OAE eq 1, - te_used33("oae") = YES; - teNoTransform33("oae") = YES; - teNoTransform2rlf33("oae", "1") = YES; - teAdj33("oae") = YES; - te_ccs33("oae") = YES; + te_oae33("oae_ng") = YES; + te_oae33("oae_el") = YES; + te_used33(te_oae33) = YES; + teNoTransform33(te_oae33) = YES; + teNoTransform2rlf33(te_oae33, "1") = YES; + teAdj33(te_oae33) = YES; + te_ccs33(te_oae33) = YES; ); ***------------------------------------------------------------------------- diff --git a/modules/47_regipol/regiCarbonPrice/equations.gms b/modules/47_regipol/regiCarbonPrice/equations.gms index 82f695678..a2c8d86f9 100644 --- a/modules/47_regipol/regiCarbonPrice/equations.gms +++ b/modules/47_regipol/regiCarbonPrice/equations.gms @@ -34,7 +34,7 @@ q47_implicitQttyTargetTax(t,regi)$(t.val ge max(2010,cm_startyear)).. )$(sameas(qttyTarget,"CCS")) + ( - p47_implicitQttyTargetTax(t,regi,qttyTarget,qttyTargetGroup) * (-vm_emiCdrTeDetail(t,regi,"oae")) + p47_implicitQttyTargetTax(t,regi,qttyTarget,qttyTargetGroup) * (-sum(te_oae33, vm_emiCdrTeDetail(t,regi,te_oae33))) )$(sameas(qttyTarget,"oae")) ) - diff --git a/modules/47_regipol/regiCarbonPrice/postsolve.gms b/modules/47_regipol/regiCarbonPrice/postsolve.gms index 74d0ff386..700615abe 100644 --- a/modules/47_regipol/regiCarbonPrice/postsolve.gms +++ b/modules/47_regipol/regiCarbonPrice/postsolve.gms @@ -497,7 +497,7 @@ p47_implicitQttyTargetTax0(t,regi) = ( sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS.l(t,regi,enty,enty2,te,rlf))) )$(sameas(qttyTarget,"CCS") AND sameas(qttyTargetGroup,"all")) + - ( -vm_emiCdrTeDetail.l(t,regi,"oae") + ( sum(te_oae33, -vm_emiCdrTeDetail.l(t,regi,te_oae33)) )$(sameas(qttyTarget,"oae") AND sameas(qttyTargetGroup,"all")) + (( !! Supply side BECCS @@ -530,7 +530,7 @@ loop((ttot,ext_regi,taxType,targetType,qttyTarget,qttyTargetGroup)$pm_implicitQt ( sum(regi$regi_groupExt(ext_regi,regi), sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS.l(ttot,regi,enty,enty2,te,rlf)))) )$(sameas(qttyTarget,"CCS") AND sameas(qttyTargetGroup,"all")) + - ( sum(regi$regi_groupExt(ext_regi,regi), -vm_emiCdrTeDetail.l(ttot,regi,"oae")) + ( sum(regi$regi_groupExt(ext_regi,regi), sum(te_oae33, -vm_emiCdrTeDetail.l(ttot,regi,te_oae33))) )$(sameas(qttyTarget,"oae") AND sameas(qttyTargetGroup,"all")) + sum(regi$regi_groupExt(ext_regi,regi), ( !! Supply side BECCS diff --git a/modules/47_regipol/regiCarbonPrice/presolve.gms b/modules/47_regipol/regiCarbonPrice/presolve.gms index b7798a56a..49e0b31af 100644 --- a/modules/47_regipol/regiCarbonPrice/presolve.gms +++ b/modules/47_regipol/regiCarbonPrice/presolve.gms @@ -51,7 +51,7 @@ p47_implicitQttyTargetTax0(t,regi) = ( sum(ccs2te(ccsCo2(enty),enty2,te), sum(teCCS2rlf(te,rlf),vm_co2CCS.l(t,regi,enty,enty2,te,rlf))) )$(sameas(qttyTarget,"CCS") AND sameas(qttyTargetGroup,"all")) + - ( -vm_emiCdrTeDetail.l(t,regi,"oae") + ( sum(te_oae33, -vm_emiCdrTeDetail.l(t,regi,te_oae33)) )$(sameas(qttyTarget,"oae") AND sameas(qttyTargetGroup,"all")) + (( !! Supply side BECCS diff --git a/scripts/input/exoGAINSAirpollutants.R b/scripts/input/exoGAINSAirpollutants.R index ac0136aa9..d3f918200 100644 --- a/scripts/input/exoGAINSAirpollutants.R +++ b/scripts/input/exoGAINSAirpollutants.R @@ -23,7 +23,8 @@ for (pkg in c('madrat', 'dplyr', 'gdx')) { suppressPackageStartupMessages(require(pkg, character.only = TRUE)) } -devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") +devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") +# library(remind2) # stop madrat reporting its default settings _every damn time_ invisible(getConfig(option = NULL, verbose = firstIteration)) diff --git a/scripts/input/prepare_NDC.R b/scripts/input/prepare_NDC.R index 6dfa6e2b7..7ca37fc52 100644 --- a/scripts/input/prepare_NDC.R +++ b/scripts/input/prepare_NDC.R @@ -11,7 +11,8 @@ prepare_NDC<-function(gdx, cfg){ library(luplot,quietly=TRUE,warn.conflicts =FALSE) library(lucode2,quietly=TRUE,warn.conflicts =FALSE) library(gdx,quietly=TRUE,warn.conflicts =FALSE) - devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") + devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") + # library(remind2) ############################# BASIC CONFIGURATION ############################# diff --git a/scripts/output/single/reporting.R b/scripts/output/single/reporting.R index fc43528fc..07a0d1369 100644 --- a/scripts/output/single/reporting.R +++ b/scripts/output/single/reporting.R @@ -7,7 +7,7 @@ library(magclass) # library(remind2) -devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") +devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") library(lucode2) library(gms) library(methods) diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index daedcbe31..ee9ef66a9 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -13,7 +13,7 @@ prepare <- function() { #require(lucode, quietly = TRUE,warn.conflicts =FALSE) require(magclass, quietly = TRUE,warn.conflicts =FALSE) require(tools, quietly = TRUE,warn.conflicts =FALSE) - devtools::load_all("/p/tmp/katarkow/remind2/syntra-low-risk") + devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") # require(remind2) require(mrremind) require(mrvalidation) @@ -436,11 +436,14 @@ prepare <- function() { #KK CDR module realizations levs_manipulateThis <- c(levs_manipulateThis, - list(c("rockgrind", "weathering")), list(c("grindrock", "weathering"))) + list(c("rockgrind", "weathering")), list(c("grindrock", "weathering")), + list(c("\"oae\"", "\"oae_ng\""))) fixings_manipulateThis <- c(fixings_manipulateThis, - list(c("rockgrind", "weathering")), list(c("grindrock", "weathering"))) + list(c("rockgrind", "weathering")), list(c("grindrock", "weathering")), + list(c("\"oae\"", "\"oae_ng\""))) margs_manipulateThis <- c(margs_manipulateThis, - list(c("rockgrind", "weathering")), list(c("grindrock", "weathering"))) + list(c("rockgrind", "weathering")), list(c("grindrock", "weathering")), + list(c("\"oae\"", "\"oae_ng\""))) if(cfg$gms$CDR == 'DAC'){ fixings_manipulateThis <- c(fixings_manipulateThis, @@ -524,6 +527,7 @@ prepare <- function() { list(c("q33_DAC_ccsbal.M", "!!q33_DAC_ccsbal.M")), list(c("q33_ccsbal.M", "!!q33_ccsbal.M")), list(c("q33_H2bio_lim.M", "!!q33_H2bio_lim.M")), + list(c("q33_OAE_FEdemand.M", "!!q33_OAE_FEdemand.M")), list(c("q33_demFeCDR.M", "!!q33_demFeCDR.M")), list(c("q33_emicdrregi.M", "!!q33_emicdrregi.M")), list(c("q33_otherFEdemand.M", "!!q33_otherFEdemand.M"))) From 37c02111fc76716a343c59f765e32d914728698a Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Thu, 25 Jul 2024 13:11:56 +0200 Subject: [PATCH 07/19] Read OAE capacity factor from input data --- core/datainput.gms | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index c61d0b686..19be68ece 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -732,10 +732,6 @@ pm_cf(ttot,regi,"idr") = 0.8; pm_cf(ttot,regi,"idrcc") = 1.0; !! capex is derived from numbers per ton of CO2, where cf = 1 is assumed in conversion pm_cf(ttot,regi,"eaf") = 1.0; !! capex is derived from numbers per ton of CO2, where cf = 1 is assumed in conversion -*KK TODO move to mrremind* -pm_cf(ttot,regi,"oae_ng") = 0.8; -pm_cf(ttot,regi,"oae_el") = 0.8; - *RP* phasing down the ngt cf to "peak load" cf of 5% pm_cf(ttot,regi,"ngt")$(ttot.val eq 2025) = 0.9 * pm_cf(ttot,regi,"ngt"); pm_cf(ttot,regi,"ngt")$(ttot.val eq 2030) = 0.8 * pm_cf(ttot,regi,"ngt"); From b230366970c63f699e90f4388ad8d98d088655b5 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Thu, 25 Jul 2024 15:48:52 +0200 Subject: [PATCH 08/19] Update documentation and rename vm_ccs_cdr --- core/equations.gms | 6 +++--- core/postsolve.gms | 2 +- main.gms | 10 +++++----- modules/33_CDR/portfolio/bounds.gms | 4 ++-- modules/33_CDR/portfolio/datainput.gms | 8 ++++---- modules/33_CDR/portfolio/declarations.gms | 4 +++- modules/33_CDR/portfolio/equations.gms | 21 +++++++++++++++------ scripts/start/prepare.R | 3 +++ 8 files changed, 36 insertions(+), 22 deletions(-) diff --git a/core/equations.gms b/core/equations.gms index cc6a4a1c0..fd90c7159 100644 --- a/core/equations.gms +++ b/core/equations.gms @@ -742,7 +742,7 @@ q_emiCdrAll(t,regi).. vm_emiCdrAll(t,regi) =e= !! BECC + DACC (sum(emiBECCS2te(enty,enty2,te,enty3),vm_emiTeDetail(t,regi,enty,enty2,te,enty3)) - + sum(teCCS2rlf(te,rlf), vm_ccs_cdr(t,regi,"cco2","ico2","ccsinje",rlf))) + + sum(teCCS2rlf(te,rlf), vm_co2capture_cdr(t,regi,"cco2","ico2","ccsinje",rlf))) !! scaled by the fraction that gets stored geologically * (sum(teCCS2rlf(te,rlf), vm_co2CCS(t,regi,"cco2","ico2",te,rlf)) / @@ -751,7 +751,7 @@ q_emiCdrAll(t,regi).. !! net negative emissions from co2luc - p_macBaseMagpieNegCo2(t,regi) !! negative emissions from the cdr module that are not stored geologically - - (vm_emiCdr(t,regi,"co2") + sum(teCCS2rlf(te,rlf), vm_ccs_cdr(t,regi,"cco2","ico2","ccsinje",rlf))) + - (vm_emiCdr(t,regi,"co2") + sum(teCCS2rlf(te,rlf), vm_co2capture_cdr(t,regi,"cco2","ico2","ccsinje",rlf))) ; @@ -838,7 +838,7 @@ q_balcapture(t,regi,ccs2te(ccsCo2(enty),enty2,te)) .. vm_emiTeDetail(t,regi,enty3,enty4,te2,enty) ) !! carbon captured from CDR technologies in CDR module - + sum(teCCS2rlf(te,rlf), vm_ccs_cdr(t,regi,enty,enty2,te,rlf)) + + sum(teCCS2rlf(te,rlf), vm_co2capture_cdr(t,regi,enty,enty2,te,rlf)) !! carbon captured from industry + sum(emiInd37, vm_emiIndCCS(t,regi,emiInd37)) + sum((sefe(entySe,entyFe),emiMkt)$( diff --git a/core/postsolve.gms b/core/postsolve.gms index 4418b4e57..c44973646 100644 --- a/core/postsolve.gms +++ b/core/postsolve.gms @@ -759,7 +759,7 @@ o_capture_energy_other(ttot,regi,"co2")$(ttot.val ge 2005) = ***Carbon Management|Carbon Capture|Process|Direct Air Capture (Mt CO2/yr) o_capture_cdr(ttot,regi,"co2")$(ttot.val ge 2005) = sum(teCCS2rlf("ccsinje",rlf), - vm_ccs_cdr.l(ttot,regi,"cco2","ico2","ccsinje",rlf) + vm_co2capture_cdr.l(ttot,regi,"cco2","ico2","ccsinje",rlf) )*o_emi_conv("co2"); ***Carbon Management|Carbon Capture|Process|Industrial Processes (Mt CO2/yr) diff --git a/main.gms b/main.gms index 3d8c18ffe..583a6e648 100755 --- a/main.gms +++ b/main.gms @@ -869,22 +869,22 @@ parameter *' * (0): not included *' parameter - cm_33_OAE_eff "OAE efficiency measured in tCO2 uptaken by the ocean per tCaO. Typically between 0.9-1.4. [tCO2/tCaO]" + cm_33_OAE_eff "OAE efficiency measured in tCO2 uptaken by the ocean per tCaO. Typically between 0.9-1.4 (which corresponds to 1.2-1.8 molCO2/molCaO). [tCO2/tCaO]" ; - cm_33_OAE_eff = 0.9; !! def = 0.9 + cm_33_OAE_eff = 1.2; !! def = 1.2 *' parameter cm_33_OAE_scen "OAE distribution scenarios" ; - cm_33_OAE_scen = 0; !! def = 0 + cm_33_OAE_scen = 1; !! def = 1 *' * (0): pessimistic: a rather low discharge rate (30 tCaO per h), corresponding to high distribution costs *' * (1): optimistic: a high discharge rate (250 tCaO per h), corresponding to lower distribution costs *' parameter cm_33_OAE_startyr "The year when OAE could start being deployed [year]" ; - cm_33_OAE_startyr = 2025; !! def = 2025 !! regexp = 2025|20[3-9](0|5) -*' * (2025): earliest year when OAE could be deployed + cm_33_OAE_startyr = 2030; !! def = 2030 !! regexp = 20[3-9](0|5) +*' * (2030): earliest year when OAE could be deployed *' * (....): later timesteps *' parameter diff --git a/modules/33_CDR/portfolio/bounds.gms b/modules/33_CDR/portfolio/bounds.gms index 90e11687e..00628e1b2 100644 --- a/modules/33_CDR/portfolio/bounds.gms +++ b/modules/33_CDR/portfolio/bounds.gms @@ -16,7 +16,7 @@ if(card(te_used33) eq 0, *** Fix CCS from CDR if there're no technologies that require CCS if(card(te_ccs33) eq 0, - vm_ccs_cdr.fx(t,regi,enty,enty2,te,rlf)$ccs2te(enty,enty2,te) = 0; + vm_co2capture_cdr.fx(t,regi,enty,enty2,te,rlf)$ccs2te(enty,enty2,te) = 0; ); *** Fix negative emissions and FE demand to zero for all the technologies that are not used @@ -31,7 +31,7 @@ vm_emiCdr.fx(t,regi,"co2")$(t.val lt 2025) = 0; vm_omcosts_cdr.fx(t,regi)$((t.val lt 2025)) = 0; vm_cap.fx(t,regi,"weathering",rlf)$(t.val lt 2025) = 0; *** vm_cap for dac is fixed for t<2025 in core/bounds.gms (tech_stat eq 4) -vm_ccs_cdr.fx(t,regi,enty,enty2,te,rlf)$(ccs2te(enty,enty2,te) AND t.val lt 2025) = 0; +vm_co2capture_cdr.fx(t,regi,enty,enty2,te,rlf)$(ccs2te(enty,enty2,te) AND t.val lt 2025) = 0; *** Set minimum DAC capacities (if available) to help the solver find the technology diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index b5c6a1f83..1cf4f8a54 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -52,19 +52,19 @@ p33_LimRock(regi) = pm_pop("2005",regi) / sum(regi2,pm_pop("2005",regi2)); *** ocean alkalinity enhancement input data (Kowalczyk et al., 2024) -!! An assumption; generally the efficiency might vary between 1.2-1.8 tCO2/tCaO, +!! An assumption; generally the efficiency might vary between 0.9-1.4 tCO2/tCaO (1.2-1.8 molCO2/molCaO), !! depending on e.g., ocean chemistry and currents in a given region s33_OAE_efficiency = cm_33_oae_eff / sm_c_2_co2; !! GtC (ocean uptake) per unit of GtCaO !! 0.78 tCO2 are emitted in the decomposition of limestone to produce 1 tCaO s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_oae_efficiency; !! GtC from decomposition per 1GtC taken by the ocean, 0.78 t/tCaO -p33_fedem(te_oae33, "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO -p33_fedem(te_oae33, "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO +p33_fedem(te_oae33, "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO, used for grinding, air separation, CO2 compression +p33_fedem(te_oae33, "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO, used for calcination if(cm_33_OAE_scen = 0, !! pessimistic scenario for distribution, high diesel demand p33_fedem(te_oae33, "fedie") = 2.6 / s33_OAE_efficiency; !! 2600 MJ/tCaO (corresponds to discharge rate of 30 t/h) -); +); !! fedie is used for inland transport of the material and maritime transport to distribute the material in the ocean if(cm_33_OAE_scen = 1, !! optimistic scenario for distribution, lower diesel demand p33_fedem(te_oae33, "fedie") = 0.77 / s33_OAE_efficiency; !! 770 MJ/tCaO (corresponds to the discharge rate of 100 t/h) diff --git a/modules/33_CDR/portfolio/declarations.gms b/modules/33_CDR/portfolio/declarations.gms index 1aa1eb2c7..be34f8cdb 100644 --- a/modules/33_CDR/portfolio/declarations.gms +++ b/modules/33_CDR/portfolio/declarations.gms @@ -27,7 +27,8 @@ positive variables v33_EW_onfield(ttot,all_regi,rlf,rlf) "amount of ground rock spread on fields in each timestep [Gt]" v33_EW_onfield_tot(ttot,all_regi,rlf,rlf) "total amount of ground rock on fields, for each climate zone and transportation distance [Gt]" v33_FEdemand(ttot,all_regi,all_enty,all_enty,all_te) "FE demand of each technology [TWa]" -vm_ccs_cdr(ttot,all_regi,all_enty,all_enty,all_te,rlf) "total emissions captured through technologies in the CDR module that enter the CCUS chain + captured emissions from associated FE demand [GtC / a]" +vm_co2capture_cdr(ttot,all_regi,all_enty,all_enty,all_te,rlf) "total emissions captured through technologies in the CDR module that enter the CCUS chain + captured emissions from associated FE demand [GtC / a]" +v33_co2capture_non_atm(ttot, all_regi) "part of the captured CO2 from CDR-related acitivites that does not come from the atmosphere [GtC / a]" ; negative variables @@ -39,6 +40,7 @@ q33_demFeCDR(ttot,all_regi,all_enty) "CDR demand balance for final energy" q33_emiCDR(ttot,all_regi) "aggregates the (negative) emissions captured by the CDR technologies" q33_H2bio_lim(ttot,all_regi) "limits H2 from bioenergy to FE - H2 demand from CDR, i.e. no H2 from bioenergy for DAC" q33_capconst(ttot,all_regi,all_te) "calculates amount of carbon captured by DAC and OAE" +q33_co2capture_non_atm(ttot,all_regi) "calculates the share of captured CO2 that does not come from the atmosphere" q33_ccsbal(ttot,all_regi,all_enty,all_enty,all_te) "calculates CCS emissions from CDR technologies" q33_DAC_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from DAC" diff --git a/modules/33_CDR/portfolio/equations.gms b/modules/33_CDR/portfolio/equations.gms index fdf277693..8013cdb8d 100644 --- a/modules/33_CDR/portfolio/equations.gms +++ b/modules/33_CDR/portfolio/equations.gms @@ -47,19 +47,28 @@ q33_capconst(t, regi, te_used33)$(not sameAs(te_used33, "weathering")).. ) ; +***--------------------------------------------------------------------------- +*' The CO2 captured from the gas used for heat production +*' required for all CDR and from limestone decomposition ocean alkalinity enhancement, +*' assuming a certain capture rate s33_capture rate. +***--------------------------------------------------------------------------- +q33_co2capture_non_atm(t, regi).. + v33_co2capture_non_atm(t, regi) + =e= + fm_dataemiglob("pegas","seh2","gash2c","cco2") * sum(fe2cdr("fegas",entyFe2,te_used33), v33_FEdemand(t,regi,"fegas", entyFe2,te_used33)) + - s33_OAE_chem_decomposition * sum(te_oae33, vm_emiCdrTeDetail(t, regi, te_oae33)) + ; + ***--------------------------------------------------------------------------- *' Preparation of captured emissions to enter the CCUS chain. *' The first part of the equation describes emissions captured from the ambient air, -*' the second part calculates the CO2 captured from the gas used for heat production -*' required for all CDR assuming 90% capture rate. The third part is the CCS needed for -*' limestone decomposition emissions for ocean alkalinity enhancement. +*' the second part is non-atmospheric CO2 (e.g., from energy usage). ***--------------------------------------------------------------------------- q33_ccsbal(t, regi, ccs2te(ccsCo2(enty), enty2, te)).. - sum(teCCS2rlf(te, rlf), vm_ccs_cdr(t, regi, enty, enty2, te, rlf)) + sum(teCCS2rlf(te, rlf), vm_co2capture_cdr(t, regi, enty, enty2, te, rlf)) =e= - vm_emiCdrTeDetail(t, regi, "dac") - + (1 / pm_eta_conv(t,regi,"gash2c")) * fm_dataemiglob("pegas","seh2","gash2c","cco2") * sum(fe2cdr("fegas",entyFe2,te_used33), v33_FEdemand(t,regi,"fegas", entyFe2,te_used33)) - - s33_OAE_chem_decomposition * sum(te_oae33, vm_emiCdrTeDetail(t, regi, te_oae33)) + + v33_co2capture_non_atm(t, regi) ; ***--------------------------------------------------------------------------- diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index ee9ef66a9..79854a6d6 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -535,14 +535,17 @@ prepare <- function() { if(cfg$gms$CDR == 'portfolio'){ fixings_manipulateThis <- c(fixings_manipulateThis, + list(c("vm_ccs_cdr.FX", "vm_co2capture_cdr.FX")), list(c("vm_otherFEdemand.FX", "!!vm_otherFEdemand.FX")), list(c("v33_emi.FX", "vm_emiCdrTeDetail.FX"))) levs_manipulateThis <- c(levs_manipulateThis, + list(c("vm_ccs_cdr.L", "vm_co2capture_cdr.L")), list(c("vm_otherFEdemand.L", "!!vm_otherFEdemand.L")), list(c("v33_emi.L", "vm_emiCdrTeDetail.L"))) margs_manipulateThis <- c(margs_manipulateThis, + list(c("vm_ccs_cdr.M", "vm_co2capture_cdr.M")), list(c("vm_otherFEdemand.M", "!!vm_otherFEdemand.M")), list(c("q33_DAC_capconst.M", "q33_DAC_emi.M"))) } From f9e62723b738b7a6d378f66804a49603eaf21376 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 18:51:30 +0200 Subject: [PATCH 09/19] How to use bounds for OAE --- main.gms | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.gms b/main.gms index 583a6e648..f382f3b7c 100755 --- a/main.gms +++ b/main.gms @@ -865,6 +865,11 @@ parameter cm_33OAE "choose whether OAE (ocean alkalinity enhancement) should be included into the CDR portfolio. 0 = OAE not used, 1 = used" ; cm_33OAE = 0; !! def = 0 +*' Since OAE is quite a cheap CDR option, runs might not converge because the model tries to deploy +*' a lot of OAE. In this case, use a quantity target to limit OAE by adding something like: +*' (2070,2080,2090,2100).GLO.tax.t.oae.all 5000 to cm_implicitQttyTarget in your config file, +*' starting from the year in which OAE is deployed above 5000 MtCO2 / yr. This will limit the global +*' deployment to 5000 Mt / yr in timesteps 2070-2100. *' * (1): ocean alkalinity enhancement is included *' * (0): not included *' From 8ea6f912c9a7b2035e893cda0f2ea701988d7c5a Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 18:52:23 +0200 Subject: [PATCH 10/19] Fix bug in emissions --- core/equations.gms | 21 +++++++------- modules/33_CDR/portfolio/bounds.gms | 2 ++ modules/33_CDR/portfolio/declarations.gms | 8 ++++-- modules/33_CDR/portfolio/equations.gms | 34 ++++++++++++++--------- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/core/equations.gms b/core/equations.gms index fd90c7159..1ade747b3 100644 --- a/core/equations.gms +++ b/core/equations.gms @@ -740,18 +740,19 @@ q_emiMac(t,regi,emiMac) .. ***-------------------------------------------------- q_emiCdrAll(t,regi).. vm_emiCdrAll(t,regi) - =e= !! BECC + DACC - (sum(emiBECCS2te(enty,enty2,te,enty3),vm_emiTeDetail(t,regi,enty,enty2,te,enty3)) - + sum(teCCS2rlf(te,rlf), vm_co2capture_cdr(t,regi,"cco2","ico2","ccsinje",rlf))) - !! scaled by the fraction that gets stored geologically - * (sum(teCCS2rlf(te,rlf), - vm_co2CCS(t,regi,"cco2","ico2",te,rlf)) / - (sum(teCCS2rlf(te,rlf), - vm_co2capture(t,regi,"cco2","ico2","ccsinje",rlf))+sm_eps)) + =e= + ( !! BECC + DACC + sum(emiBECCS2te(enty,enty2,te,enty3),vm_emiTeDetail(t,regi,enty,enty2,te,enty3)) + - vm_emiCdrTeDetail(t, regi, "dac") !! this is a negative value + ) + * ( !! scaled by the fraction that gets stored geologically + sum(teCCS2rlf(te, rlf), vm_co2CCS(t, regi, "cco2", "ico2", te, rlf)) + / (sum(teCCS2rlf(te, rlf), vm_co2capture(t, regi, "cco2", "ico2", "ccsinje", rlf)) + sm_eps) + ) !! net negative emissions from co2luc - p_macBaseMagpieNegCo2(t,regi) - !! negative emissions from the cdr module that are not stored geologically - - (vm_emiCdr(t,regi,"co2") + sum(teCCS2rlf(te,rlf), vm_co2capture_cdr(t,regi,"cco2","ico2","ccsinje",rlf))) + !! negative emissions from the cdr module that are not stored geologically + - (vm_emiCdr(t,regi,"co2") - vm_emiCdrTeDetail(t, regi, "dac")) ; diff --git a/modules/33_CDR/portfolio/bounds.gms b/modules/33_CDR/portfolio/bounds.gms index 00628e1b2..d66248c86 100644 --- a/modules/33_CDR/portfolio/bounds.gms +++ b/modules/33_CDR/portfolio/bounds.gms @@ -17,6 +17,7 @@ if(card(te_used33) eq 0, *** Fix CCS from CDR if there're no technologies that require CCS if(card(te_ccs33) eq 0, vm_co2capture_cdr.fx(t,regi,enty,enty2,te,rlf)$ccs2te(enty,enty2,te) = 0; + v33_co2emi_non_atm.fx(t,regi,te_all33) = 0; ); *** Fix negative emissions and FE demand to zero for all the technologies that are not used @@ -27,6 +28,7 @@ v33_FEdemand.fx(t,regi,entyFe,entyFe2,te_all33)$(not te_used33(te_all33) and fe2 *** to reduce unnecessary freedom (and likelyhood of spontaneous solver infeasibilities) vm_emiCdrTeDetail.fx(t,regi,te_used33)$(t.val lt 2025) = 0.0; v33_FEdemand.fx(t,regi,entyFe,entyFe2,te_used33)$(fe2cdr(entyFe,entyFe2,te_used33) AND (t.val lt 2025)) = 0.0; +v33_co2emi_non_atm.fx(t,regi,te_used33)$(t.val lt 2025) = 0; vm_emiCdr.fx(t,regi,"co2")$(t.val lt 2025) = 0; vm_omcosts_cdr.fx(t,regi)$((t.val lt 2025)) = 0; vm_cap.fx(t,regi,"weathering",rlf)$(t.val lt 2025) = 0; diff --git a/modules/33_CDR/portfolio/declarations.gms b/modules/33_CDR/portfolio/declarations.gms index be34f8cdb..3955d5973 100644 --- a/modules/33_CDR/portfolio/declarations.gms +++ b/modules/33_CDR/portfolio/declarations.gms @@ -6,6 +6,8 @@ *** | Contact: remind@pik-potsdam.de *** SOF ./modules/33_CDR/portfolio/declarations.gms scalars +s33_capture_rate "CO2 capture rate for capturing emissions, e.g., from burning natural gas" / 0.9 / + s33_co2_rem_pot "specific carbon removal potential [Gt C per Gt ground rock]" s33_co2_rem_rate "carbon removal rate [fraction of annual reduction of total carbon removal potential]" s33_costs_fix "fixed costs for mining, grinding, spreading [T$/Gt stone]" @@ -28,11 +30,11 @@ v33_EW_onfield(ttot,all_regi,rlf,rlf) "amount of ground rock spread on fields i v33_EW_onfield_tot(ttot,all_regi,rlf,rlf) "total amount of ground rock on fields, for each climate zone and transportation distance [Gt]" v33_FEdemand(ttot,all_regi,all_enty,all_enty,all_te) "FE demand of each technology [TWa]" vm_co2capture_cdr(ttot,all_regi,all_enty,all_enty,all_te,rlf) "total emissions captured through technologies in the CDR module that enter the CCUS chain + captured emissions from associated FE demand [GtC / a]" -v33_co2capture_non_atm(ttot, all_regi) "part of the captured CO2 from CDR-related acitivites that does not come from the atmosphere [GtC / a]" +v33_co2emi_non_atm(ttot,all_regi,all_te) "captured CO2 from CDR-related acitivites that does not come from the atmosphere [GtC / a]" ; negative variables -vm_emiCdrTeDetail(ttot,all_regi,all_te) "(negative) emissions from CDR technologies in the CDR module by technology. Includes all atmospheric CO2 that enter the CCUS chain (i.e. CO2 stored (CDR) AND used (not CDR)) [GtC / a]" +vm_emiCdrTeDetail(ttot,all_regi,all_te) "gross (negative) emissions from CDR technologies in the CDR module by technology. Includes all atmospheric CO2 that enter the CCUS chain (i.e. CO2 stored (CDR) AND used (not CDR)) [GtC / a]" ; equations @@ -40,7 +42,7 @@ q33_demFeCDR(ttot,all_regi,all_enty) "CDR demand balance for final energy" q33_emiCDR(ttot,all_regi) "aggregates the (negative) emissions captured by the CDR technologies" q33_H2bio_lim(ttot,all_regi) "limits H2 from bioenergy to FE - H2 demand from CDR, i.e. no H2 from bioenergy for DAC" q33_capconst(ttot,all_regi,all_te) "calculates amount of carbon captured by DAC and OAE" -q33_co2capture_non_atm(ttot,all_regi) "calculates the share of captured CO2 that does not come from the atmosphere" +q33_co2emi_non_atm(ttot,all_regi,all_te) "calculates the share of captured CO2 that does not come from the atmosphere" q33_ccsbal(ttot,all_regi,all_enty,all_enty,all_te) "calculates CCS emissions from CDR technologies" q33_DAC_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from DAC" diff --git a/modules/33_CDR/portfolio/equations.gms b/modules/33_CDR/portfolio/equations.gms index 8013cdb8d..0a7f08749 100644 --- a/modules/33_CDR/portfolio/equations.gms +++ b/modules/33_CDR/portfolio/equations.gms @@ -25,16 +25,19 @@ q33_demFeCDR(t,regi,entyFe)$(entyFe2Sector(entyFe,"cdr")).. ***--------------------------------------------------------------------------- *' Sum of all CDR emissions other than BECCS and afforestation, which are calculated in the core. +*' The negative emissions are discounted by emissions that are released due to <100 percent capture +*' rate, as they are unavoidable (1-s33_capture_rate of the emissions that are possible to capture). *' Note that this includes all atmospheric CO2 captured in this module that enters the CCUS chain. ***--------------------------------------------------------------------------- q33_emiCDR(t,regi).. vm_emiCdr(t,regi,"co2") =e= sum(te_used33, vm_emiCdrTeDetail(t,regi,te_used33)) + + (1 - s33_capture_rate) * sum(te_ccs33, v33_co2emi_non_atm(t, regi, te_ccs33)) ; ***--------------------------------------------------------------------------- -*' Calculation of (negative) CO2 emissions from capacity. +*' Calculation of gross (negative) CO2 emissions from capacity. *' Negative emissions from enhanced weathering also result from decaying rock *' spread in previous timesteps, so emissions do not equal to the capacity *' (i.e., how much rock is spread in a given timestep). @@ -48,27 +51,31 @@ q33_capconst(t, regi, te_used33)$(not sameAs(te_used33, "weathering")).. ; ***--------------------------------------------------------------------------- -*' The CO2 captured from the gas used for heat production -*' required for all CDR and from limestone decomposition ocean alkalinity enhancement, -*' assuming a certain capture rate s33_capture rate. +*' The CO2 captured from the gas used for heat production (DAC, OAE) +*' and from limestone decomposition (OAE only). ***--------------------------------------------------------------------------- -q33_co2capture_non_atm(t, regi).. - v33_co2capture_non_atm(t, regi) +q33_co2emi_non_atm(t, regi, te_ccs33).. + v33_co2emi_non_atm(t, regi, te_ccs33) =e= - fm_dataemiglob("pegas","seh2","gash2c","cco2") * sum(fe2cdr("fegas",entyFe2,te_used33), v33_FEdemand(t,regi,"fegas", entyFe2,te_used33)) - - s33_OAE_chem_decomposition * sum(te_oae33, vm_emiCdrTeDetail(t, regi, te_oae33)) + !! carbon captured from burning gas (DAC and OAE technologies) + fm_dataemiglob("pegas","seh2","gash2c","cco2") !! conversion from PE to emissions + * (1 / pm_eta_conv(t,regi,"gash2c")) !! conversion from PE to FE + * sum(fe2cdr("fegas", entyFe2, te_ccs33), v33_FEdemand(t, regi,"fegas", entyFe2, te_ccs33)) !! FE gas used + !! carbon captured from calcination (OAE technologies only) + - (s33_OAE_chem_decomposition * vm_emiCdrTeDetail(t, regi, te_ccs33))$te_oae33(te_ccs33) ; ***--------------------------------------------------------------------------- *' Preparation of captured emissions to enter the CCUS chain. -*' The first part of the equation describes emissions captured from the ambient air, -*' the second part is non-atmospheric CO2 (e.g., from energy usage). +*' The first part of the equation describes emissons captured from the ambient air, +*' the second part is non-atmospheric CO2 (e.g., from energy usage), +*' assuming a capture rate s33_capture_rate. ***--------------------------------------------------------------------------- q33_ccsbal(t, regi, ccs2te(ccsCo2(enty), enty2, te)).. sum(teCCS2rlf(te, rlf), vm_co2capture_cdr(t, regi, enty, enty2, te, rlf)) =e= - vm_emiCdrTeDetail(t, regi, "dac") - + v33_co2capture_non_atm(t, regi) + + s33_capture_rate * sum(te_ccs33, v33_co2emi_non_atm(t, regi, te_ccs33)) ; ***--------------------------------------------------------------------------- @@ -78,7 +85,8 @@ q33_ccsbal(t, regi, ccs2te(ccsCo2(enty), enty2, te)).. q33_H2bio_lim(t,regi).. sum(pe2se("pebiolc","seh2",te), vm_prodSE(t,regi,"pebiolc","seh2",te)) =l= - vm_prodFe(t,regi,"seh2","feh2s","tdh2s") - sum(fe2cdr("feh2s",entyFe2,te_used33), v33_FEdemand(t,regi,"feh2s",entyFe2,te_used33)) + vm_prodFe(t,regi,"seh2","feh2s","tdh2s") + - sum(fe2cdr("feh2s",entyFe2,te_used33), v33_FEdemand(t,regi,"feh2s",entyFe2,te_used33)) ; ***--------------------------------------------------------------------------- @@ -188,7 +196,7 @@ q33_EW_LimEmi(t,regi).. *' Calculation of FE demand for OAE, i.e., electricity for rock preprocessing, *' and heat for calcination. ***--------------------------------------------------------------------------- -q33_OAE_FEdemand(t,regi,entyFe2, te_oae33)$sum(entyFe, fe2cdr(entyFe,entyFe2,te_oae33)).. +q33_OAE_FEdemand(t,regi,entyFe2,te_oae33)$sum(entyFe, fe2cdr(entyFe,entyFe2,te_oae33)).. sum(fe2cdr(entyFe, entyFe2, te_oae33), v33_FEdemand(t, regi, entyFe, entyFe2, te_oae33)) =e= p33_fedem(te_oae33, entyFe2) * sm_EJ_2_TWa * (- vm_emiCdrTeDetail(t, regi, te_oae33)) From 2fe3124072748f3e5418cf0aa2b4faa1051441db Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 19:06:20 +0200 Subject: [PATCH 11/19] Restore remind2 --- scripts/input/exoGAINSAirpollutants.R | 5 +---- scripts/input/prepare_NDC.R | 3 +-- scripts/output/single/reporting.R | 3 +-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/scripts/input/exoGAINSAirpollutants.R b/scripts/input/exoGAINSAirpollutants.R index d3f918200..d7494b6a0 100644 --- a/scripts/input/exoGAINSAirpollutants.R +++ b/scripts/input/exoGAINSAirpollutants.R @@ -19,13 +19,10 @@ if (file.exists("log.txt")){ #rm(list=ls()) # load required packages -for (pkg in c('madrat', 'dplyr', 'gdx')) { +for (pkg in c('madrat', 'dplyr', 'remind2', 'gdx')) { suppressPackageStartupMessages(require(pkg, character.only = TRUE)) } -devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") -# library(remind2) - # stop madrat reporting its default settings _every damn time_ invisible(getConfig(option = NULL, verbose = firstIteration)) diff --git a/scripts/input/prepare_NDC.R b/scripts/input/prepare_NDC.R index 7ca37fc52..6b77d30d7 100644 --- a/scripts/input/prepare_NDC.R +++ b/scripts/input/prepare_NDC.R @@ -11,8 +11,7 @@ prepare_NDC<-function(gdx, cfg){ library(luplot,quietly=TRUE,warn.conflicts =FALSE) library(lucode2,quietly=TRUE,warn.conflicts =FALSE) library(gdx,quietly=TRUE,warn.conflicts =FALSE) - devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") - # library(remind2) + library(remind2) ############################# BASIC CONFIGURATION ############################# diff --git a/scripts/output/single/reporting.R b/scripts/output/single/reporting.R index 07a0d1369..aa62ed57b 100644 --- a/scripts/output/single/reporting.R +++ b/scripts/output/single/reporting.R @@ -6,8 +6,7 @@ # | Contact: remind@pik-potsdam.de library(magclass) -# library(remind2) -devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") +library(remind2) library(lucode2) library(gms) library(methods) From b40e379a6c9af875d5f60675cf49ed208c9522cf Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 19:08:02 +0200 Subject: [PATCH 12/19] Clean up --- modules/33_CDR/portfolio/datainput.gms | 1 - modules/33_CDR/portfolio/sets.gms | 4 ++-- scripts/input/exoGAINSAirpollutants.R | 5 ++++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index 1cf4f8a54..6a5a26107 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -71,5 +71,4 @@ if(cm_33_OAE_scen = 1, !! optimistic scenario for distribution, lower diesel dem ); *' @stop - *** EOF ./modules/33_CDR/portfolio/datainput.gms diff --git a/modules/33_CDR/portfolio/sets.gms b/modules/33_CDR/portfolio/sets.gms index 0631ec6c9..07b4060a8 100644 --- a/modules/33_CDR/portfolio/sets.gms +++ b/modules/33_CDR/portfolio/sets.gms @@ -11,8 +11,8 @@ te_all33(all_te) "all CDR technologies" / weathering "enhanced weathering" dac "direct air capture" - oae_ng "ocean alkalinity enhancement, natural gas calciner" - oae_el "ocean alkalinity enhancement, electric calciner" + oae_ng "ocean akalinity ehnacement via ocean liming using a traditional calciner" + oae_el "ocean akalinity ehnacement via ocean liming using a novel calciner technology" / te_used33(all_te) "used CDR technologies (specified by switches)" diff --git a/scripts/input/exoGAINSAirpollutants.R b/scripts/input/exoGAINSAirpollutants.R index d7494b6a0..d3f918200 100644 --- a/scripts/input/exoGAINSAirpollutants.R +++ b/scripts/input/exoGAINSAirpollutants.R @@ -19,10 +19,13 @@ if (file.exists("log.txt")){ #rm(list=ls()) # load required packages -for (pkg in c('madrat', 'dplyr', 'remind2', 'gdx')) { +for (pkg in c('madrat', 'dplyr', 'gdx')) { suppressPackageStartupMessages(require(pkg, character.only = TRUE)) } +devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") +# library(remind2) + # stop madrat reporting its default settings _every damn time_ invisible(getConfig(option = NULL, verbose = firstIteration)) From bdf3c4c17704a210ba7c15b8553e09b186ef1eee Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 19:19:32 +0200 Subject: [PATCH 13/19] Clean up fixings --- modules/33_CDR/portfolio/declarations.gms | 2 +- modules/33_CDR/portfolio/sets.gms | 4 ++-- scripts/input/prepare_NDC.R | 2 +- scripts/start/prepare.R | 7 +++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/33_CDR/portfolio/declarations.gms b/modules/33_CDR/portfolio/declarations.gms index 3955d5973..80cca8d63 100644 --- a/modules/33_CDR/portfolio/declarations.gms +++ b/modules/33_CDR/portfolio/declarations.gms @@ -30,7 +30,7 @@ v33_EW_onfield(ttot,all_regi,rlf,rlf) "amount of ground rock spread on fields i v33_EW_onfield_tot(ttot,all_regi,rlf,rlf) "total amount of ground rock on fields, for each climate zone and transportation distance [Gt]" v33_FEdemand(ttot,all_regi,all_enty,all_enty,all_te) "FE demand of each technology [TWa]" vm_co2capture_cdr(ttot,all_regi,all_enty,all_enty,all_te,rlf) "total emissions captured through technologies in the CDR module that enter the CCUS chain + captured emissions from associated FE demand [GtC / a]" -v33_co2emi_non_atm(ttot,all_regi,all_te) "captured CO2 from CDR-related acitivites that does not come from the atmosphere [GtC / a]" +v33_co2emi_non_atm(ttot,all_regi,all_te) "CO2 from CDR-related acitivites that does not come from the atmosphere [GtC / a]" ; negative variables diff --git a/modules/33_CDR/portfolio/sets.gms b/modules/33_CDR/portfolio/sets.gms index 07b4060a8..1d8fcd57d 100644 --- a/modules/33_CDR/portfolio/sets.gms +++ b/modules/33_CDR/portfolio/sets.gms @@ -11,8 +11,8 @@ te_all33(all_te) "all CDR technologies" / weathering "enhanced weathering" dac "direct air capture" - oae_ng "ocean akalinity ehnacement via ocean liming using a traditional calciner" - oae_el "ocean akalinity ehnacement via ocean liming using a novel calciner technology" + oae_ng "ocean akalinity ehnacement via ocean liming using a traditional calciner" + oae_el "ocean akalinity ehnacement via ocean liming using a novel calciner technology" / te_used33(all_te) "used CDR technologies (specified by switches)" diff --git a/scripts/input/prepare_NDC.R b/scripts/input/prepare_NDC.R index 6b77d30d7..79c32a58a 100644 --- a/scripts/input/prepare_NDC.R +++ b/scripts/input/prepare_NDC.R @@ -11,7 +11,7 @@ prepare_NDC<-function(gdx, cfg){ library(luplot,quietly=TRUE,warn.conflicts =FALSE) library(lucode2,quietly=TRUE,warn.conflicts =FALSE) library(gdx,quietly=TRUE,warn.conflicts =FALSE) - library(remind2) + library(remind2,quietly = TRUE,warn.conflicts =FALSE) ############################# BASIC CONFIGURATION ############################# diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index 79854a6d6..d3187c3ff 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -13,8 +13,7 @@ prepare <- function() { #require(lucode, quietly = TRUE,warn.conflicts =FALSE) require(magclass, quietly = TRUE,warn.conflicts =FALSE) require(tools, quietly = TRUE,warn.conflicts =FALSE) - devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") - # require(remind2) + require(remind2,quietly = TRUE,warn.conflicts =FALSE) require(mrremind) require(mrvalidation) @@ -529,6 +528,7 @@ prepare <- function() { list(c("q33_H2bio_lim.M", "!!q33_H2bio_lim.M")), list(c("q33_OAE_FEdemand.M", "!!q33_OAE_FEdemand.M")), list(c("q33_demFeCDR.M", "!!q33_demFeCDR.M")), + list(c("q33_co2capture_non_atm.M", "!!q33_co2capture_non_atm.M")), list(c("q33_emicdrregi.M", "!!q33_emicdrregi.M")), list(c("q33_otherFEdemand.M", "!!q33_otherFEdemand.M"))) } @@ -537,15 +537,18 @@ prepare <- function() { fixings_manipulateThis <- c(fixings_manipulateThis, list(c("vm_ccs_cdr.FX", "vm_co2capture_cdr.FX")), list(c("vm_otherFEdemand.FX", "!!vm_otherFEdemand.FX")), + list(c("v33_co2capture_non_atm.FX", "!!v33_co2capture_non_atm.FX")), list(c("v33_emi.FX", "vm_emiCdrTeDetail.FX"))) levs_manipulateThis <- c(levs_manipulateThis, list(c("vm_ccs_cdr.L", "vm_co2capture_cdr.L")), + list(c("v33_co2capture_non_atm.L", "!!v33_co2capture_non_atm.L")), list(c("vm_otherFEdemand.L", "!!vm_otherFEdemand.L")), list(c("v33_emi.L", "vm_emiCdrTeDetail.L"))) margs_manipulateThis <- c(margs_manipulateThis, list(c("vm_ccs_cdr.M", "vm_co2capture_cdr.M")), + list(c("v33_co2capture_non_atm.M", "!!v33_co2capture_non_atm.M")), list(c("vm_otherFEdemand.M", "!!vm_otherFEdemand.M")), list(c("q33_DAC_capconst.M", "q33_DAC_emi.M"))) } From 6f5e062035e1bf7cbfdbcd8b7b899bf6ebb1a6d5 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 19:40:26 +0200 Subject: [PATCH 14/19] Fix warnings --- core/datainput.gms | 4 ++-- modules/33_CDR/portfolio/datainput.gms | 4 ++-- scripts/input/exoGAINSAirpollutants.R | 5 +---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index 19be68ece..45600690d 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -262,8 +262,8 @@ fm_dataglob("inco0","csp") = 0.7 * fm_dataglob("inco0","csp"); fm_dataglob("incolearn","csp") = 0.7 * fm_dataglob("incolearn","csp"); *KK* adjust costs for oae from USD/GtCaO to USD/GtC -fm_dataglob("inco0", "oae_ng") = fm_dataglob("inco0", "oae_ng") / (cm_33_oae_eff / sm_c_2_co2); -fm_dataglob("inco0", "oae_el") = fm_dataglob("inco0", "oae_el") / (cm_33_oae_eff / sm_c_2_co2); +fm_dataglob("inco0", "oae_ng") = fm_dataglob("inco0", "oae_ng") / (cm_33_OAE_eff / sm_c_2_co2); +fm_dataglob("inco0", "oae_el") = fm_dataglob("inco0", "oae_el") / (cm_33_OAE_eff / sm_c_2_co2); *** -------------------------------------------------------------------------------- *** Regionalize technology investment cost data diff --git a/modules/33_CDR/portfolio/datainput.gms b/modules/33_CDR/portfolio/datainput.gms index 6a5a26107..51bbf0cdd 100644 --- a/modules/33_CDR/portfolio/datainput.gms +++ b/modules/33_CDR/portfolio/datainput.gms @@ -54,10 +54,10 @@ p33_LimRock(regi) = pm_pop("2005",regi) / sum(regi2,pm_pop("2005",regi2)); !! An assumption; generally the efficiency might vary between 0.9-1.4 tCO2/tCaO (1.2-1.8 molCO2/molCaO), !! depending on e.g., ocean chemistry and currents in a given region -s33_OAE_efficiency = cm_33_oae_eff / sm_c_2_co2; !! GtC (ocean uptake) per unit of GtCaO +s33_OAE_efficiency = cm_33_OAE_eff / sm_c_2_co2; !! GtC (ocean uptake) per unit of GtCaO !! 0.78 tCO2 are emitted in the decomposition of limestone to produce 1 tCaO -s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_oae_efficiency; !! GtC from decomposition per 1GtC taken by the ocean, 0.78 t/tCaO +s33_OAE_chem_decomposition = 0.78 / sm_c_2_co2 / s33_OAE_efficiency; !! GtC from decomposition per 1GtC taken by the ocean, 0.78 t/tCaO p33_fedem(te_oae33, "feels") = 1.0 / s33_OAE_efficiency; !! 996 MJ/tCaO, used for grinding, air separation, CO2 compression p33_fedem(te_oae33, "fehes") = 3.1 / s33_OAE_efficiency; !! 3100 MJ/tCaO, used for calcination diff --git a/scripts/input/exoGAINSAirpollutants.R b/scripts/input/exoGAINSAirpollutants.R index d3f918200..d7494b6a0 100644 --- a/scripts/input/exoGAINSAirpollutants.R +++ b/scripts/input/exoGAINSAirpollutants.R @@ -19,13 +19,10 @@ if (file.exists("log.txt")){ #rm(list=ls()) # load required packages -for (pkg in c('madrat', 'dplyr', 'gdx')) { +for (pkg in c('madrat', 'dplyr', 'remind2', 'gdx')) { suppressPackageStartupMessages(require(pkg, character.only = TRUE)) } -devtools::load_all("/p/tmp/katarkow/remind2/ng-el-OAE") -# library(remind2) - # stop madrat reporting its default settings _every damn time_ invisible(getConfig(option = NULL, verbose = firstIteration)) From 81afa1dfb97fa71430e955f3194d4784a3cfeabc Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Mon, 29 Jul 2024 19:40:51 +0200 Subject: [PATCH 15/19] Remove unused fixings --- scripts/start/prepare.R | 125 +++------------------------------------- 1 file changed, 9 insertions(+), 116 deletions(-) diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index d3187c3ff..423118b6a 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -434,125 +434,18 @@ prepare <- function() { } #KK CDR module realizations - levs_manipulateThis <- c(levs_manipulateThis, - list(c("rockgrind", "weathering")), list(c("grindrock", "weathering")), - list(c("\"oae\"", "\"oae_ng\""))) fixings_manipulateThis <- c(fixings_manipulateThis, - list(c("rockgrind", "weathering")), list(c("grindrock", "weathering")), - list(c("\"oae\"", "\"oae_ng\""))) - margs_manipulateThis <- c(margs_manipulateThis, - list(c("rockgrind", "weathering")), list(c("grindrock", "weathering")), - list(c("\"oae\"", "\"oae_ng\""))) - - if(cfg$gms$CDR == 'DAC'){ - fixings_manipulateThis <- c(fixings_manipulateThis, - list(c("v33_emiEW.FX", "!!v33_emiEW.FX")), - list(c("v33_weathering_onfield.FX", "!!v33_grindrock_onfield.FX")), - list(c("v33_weathering_onfield_tot.FX", "!!v33_grindrock_onfield_tot.FX"))) - - levs_manipulateThis <- c(levs_manipulateThis, - list(c("v33_emiEW.L", "!!v33_emiEW.L")), - list(c("v33_weathering_onfield.L", "!!v33_grindrock_onfield.L")), - list(c("v33_weathering_onfield_tot.L", "!!v33_grindrock_onfield_tot.L"))) - - margs_manipulateThis <- c(margs_manipulateThis, - list(c("v33_emiEW.M", "!!v33_emiEW.M")), - list(c("v33_weathering_onfield.M", "!!v33_grindrock_onfield.M")), - list(c("v33_weathering_onfield_tot.M", "!!v33_grindrock_onfield_tot.M")), - list(c("q33_capconst_weathering.M", "!!q33_capconst_grindrock.M")), - list(c("q33_weathering_onfield_tot.M", "!!q33_grindrock_onfield_tot.M")), - list(c("q33_omcosts.M", "!!q33_omcosts.M")), - list(c("q33_potential.M", "!!q33_potential.M")), - list(c("q33_emiEW.M", "!!q33_emiEW.M")), - list(c("q33_LimEmiEW.M", "!!q33_LimEmiEW.M"))) - } - - if(cfg$gms$CDR == 'weathering'){ - fixings_manipulateThis <- c(fixings_manipulateThis, - list(c("v33_emiDAC.FX", "!!v33_emiDAC.FX")), - list(c("v33_DacFEdemand_el.FX", "!!v33_DacFEdemand_el.FX")), - list(c("v33_DacFEdemand_heat.FX", "!!v33_DacFEdemand_heat.FX"))) - - levs_manipulateThis <- c(levs_manipulateThis, - list(c("v33_emiDAC.L", "!!v33_emiDAC.L")), - list(c("v33_DacFEdemand_el.L", "!!v33_DacFEdemand_el.L")), - list(c("v33_DacFEdemand_heat.L", "!!v33_DacFEdemand_heat.L"))) - - margs_manipulateThis <- c(margs_manipulateThis, - list(c("v33_emiDAC.M", "!!v33_emiDAC.")), - list(c("v33_DacFEdemand_el.M", "!!v33_DacFEdemand_el.M")), - list(c("v33_DacFEdemand_heat.M", "!!v33_DacFEdemand_heat.M")), - list(c("q33_DacFEdemand_heat.M", "!!q33_DacFEdemand_heat.M")), - list(c("q33_DacFEdemand_el.M", "!!q33_DacFEdemand_el.M")), - list(c("q33_capconst_dac.M", "!!q33_capconst_dac.M")), - list(c("q33_ccsbal.M", "!!q33_ccsbal.M")), - list(c("q33_H2bio_lim.M", "!!q33_H2bio_lim.M"))) - } + list(c("vm_ccs_cdr.FX", "vm_co2capture_cdr.FX")), + list(c("v33_emi.FX", "vm_emiCdrTeDetail.FX"))) - if(cfg$gms$CDR == 'off' || cfg$gms$CDR == 'portfolio'){ - fixings_manipulateThis <- c(fixings_manipulateThis, - list(c("v33_emiDAC.FX", "!!v33_emiDAC.FX")), - list(c("v33_emiEW.FX", "!!v33_emiEW.FX")), - list(c("v33_DacFEdemand_el.FX", "!!v33_DacFEdemand_el.FX")), - list(c("v33_DacFEdemand_heat.FX", "!!v33_DacFEdemand_heat.FX")), - list(c("v33_weathering_onfield.FX", "!!v33_grindrock_onfield.FX")), - list(c("v33_weathering_onfield_tot.FX", "!!v33_grindrock_onfield_tot.FX"))) - - levs_manipulateThis <- c(levs_manipulateThis, - list(c("v33_emiDAC.L", "!!v33_emiDAC.L")), - list(c("v33_emiEW.L", "!!v33_emiEW.L")), - list(c("v33_DacFEdemand_el.L", "!!v33_DacFEdemand_el.L")), - list(c("v33_DacFEdemand_heat.L", "!!v33_DacFEdemand_heat.L")), - list(c("v33_weathering_onfield.L", "!!v33_grindrock_onfield.L")), - list(c("v33_weathering_onfield_tot.L", "!!v33_grindrock_onfield_tot.L"))) - - margs_manipulateThis <- c(margs_manipulateThis, - list(c("v33_emiDAC.M", "!!v33_emiDAC.M")), - list(c("v33_emiEW.M", "!!v33_emiEW.M")), - list(c("v33_weathering_onfield.M", "!!v33_grindrock_onfield.M")), - list(c("v33_weathering_onfield_tot.M", "!!v33_grindrock_onfield_tot.M")), - list(c("v33_DacFEdemand_el.M", "!!v33_DacFEdemand_el.M")), - list(c("v33_DacFEdemand_heat.M", "!!v33_DacFEdemand_heat.M")), - list(c("q33_capconst_weathering.M", "!!q33_capconst_grindrock.M")), - list(c("q33_weathering_onfield_tot.M", "!!q33_grindrock_onfield_tot.M")), - list(c("q33_omcosts.M", "!!q33_omcosts.M")), - list(c("q33_potential.M", "!!q33_potential.M")), - list(c("q33_emiEW.M", "!!q33_emiEW.M")), - list(c("q33_LimEmiEW.M", "!!q33_LimEmiEW.M")), - list(c("q33_DacFEdemand_heat.M", "!!q33_DacFEdemand_heat.M")), - list(c("q33_DacFEdemand_el.M", "!!q33_DacFEdemand_el.M")), - list(c("q33_capconst_dac.M", "!!q33_capconst_dac.M")), - list(c("q33_DAC_capconst.M", "!!q33_DAC_capconst.M")), - list(c("q33_DAC_ccsbal.M", "!!q33_DAC_ccsbal.M")), - list(c("q33_ccsbal.M", "!!q33_ccsbal.M")), - list(c("q33_H2bio_lim.M", "!!q33_H2bio_lim.M")), - list(c("q33_OAE_FEdemand.M", "!!q33_OAE_FEdemand.M")), - list(c("q33_demFeCDR.M", "!!q33_demFeCDR.M")), - list(c("q33_co2capture_non_atm.M", "!!q33_co2capture_non_atm.M")), - list(c("q33_emicdrregi.M", "!!q33_emicdrregi.M")), - list(c("q33_otherFEdemand.M", "!!q33_otherFEdemand.M"))) - } - - if(cfg$gms$CDR == 'portfolio'){ - fixings_manipulateThis <- c(fixings_manipulateThis, - list(c("vm_ccs_cdr.FX", "vm_co2capture_cdr.FX")), - list(c("vm_otherFEdemand.FX", "!!vm_otherFEdemand.FX")), - list(c("v33_co2capture_non_atm.FX", "!!v33_co2capture_non_atm.FX")), - list(c("v33_emi.FX", "vm_emiCdrTeDetail.FX"))) - - levs_manipulateThis <- c(levs_manipulateThis, - list(c("vm_ccs_cdr.L", "vm_co2capture_cdr.L")), - list(c("v33_co2capture_non_atm.L", "!!v33_co2capture_non_atm.L")), - list(c("vm_otherFEdemand.L", "!!vm_otherFEdemand.L")), - list(c("v33_emi.L", "vm_emiCdrTeDetail.L"))) - - margs_manipulateThis <- c(margs_manipulateThis, - list(c("vm_ccs_cdr.M", "vm_co2capture_cdr.M")), - list(c("v33_co2capture_non_atm.M", "!!v33_co2capture_non_atm.M")), - list(c("vm_otherFEdemand.M", "!!vm_otherFEdemand.M")), - list(c("q33_DAC_capconst.M", "q33_DAC_emi.M"))) - } + levs_manipulateThis <- c(levs_manipulateThis, + list(c("vm_ccs_cdr.L", "vm_co2capture_cdr.L")), + list(c("v33_emi.L", "vm_emiCdrTeDetail.L"))) + margs_manipulateThis <- c(margs_manipulateThis, + list(c("vm_ccs_cdr.M", "vm_co2capture_cdr.M")), + list(c("q33_DAC_ccsbal.M", "!!q33_DAC_ccsbal.M")), + list(c("q33_DAC_emi.M", "!!q33_DAC_emi.M"))) # end of CDR module realizations levs_manipulateThis <- c(levs_manipulateThis, From 858d131a356a826f7d7af62af40e5acf5146f6b5 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Thu, 8 Aug 2024 13:11:20 +0200 Subject: [PATCH 16/19] OAE documentation --- modules/33_CDR/module.gms | 2 +- modules/33_CDR/portfolio/realization.gms | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/33_CDR/module.gms b/modules/33_CDR/module.gms index ebfac14c5..ee3ca39b9 100644 --- a/modules/33_CDR/module.gms +++ b/modules/33_CDR/module.gms @@ -10,7 +10,7 @@ *' *' @description The 33_CDR module adds further options to remove CO2 from the atmosphere beyond BECCS *' and afforestation, which are calculated in the core. Currently, direct air carbon capture and storage (DACCS) -*' and enhanced weathering of rocks (EW) are available, ocean alkalinization will follow soon. +*' and enhanced weathering of rocks (EW) are available, ocean alkalinization (OAE) implemented as ocean liming. *' All options can be switched on and off individually via the switches called cm_33[option abbreviation]. *' The module calculates capacities, emissions (including captured carbon), energy demand & supply, costs, *' and limitations associated with the different options. diff --git a/modules/33_CDR/portfolio/realization.gms b/modules/33_CDR/portfolio/realization.gms index 084ac57eb..e332585f4 100644 --- a/modules/33_CDR/portfolio/realization.gms +++ b/modules/33_CDR/portfolio/realization.gms @@ -14,6 +14,7 @@ *' electricity and 21.12 EJ/Gt C (* 12 Gt C/44 Gt CO2) = 5,76 GJ/tCO2 (*10^6 kJ / GJ * 1h/3600s) = 1600 kWh/tCO2 *' low-temperature heat demand. The heat can be provided via district heat, electricity, gas, or H2. If gas is used, *' the resulting CO2 is captured with a capture rate of 90%. +*' *' (EW) Basalt is mined and ground to fine grain sizes (specified in cm_gs_ew, by default 20 µm), and then spread *' on crop fields where it weathers in reaction with water and atmospheric CO2. Electricity is needed to grind the *' rocks and diesel is needed for transportation and spreading on crop fields. The weathering process leads to an exponential @@ -22,6 +23,17 @@ *' limit of the amount of rock spread each year can be set in cm_LimRock. Costs consist of costs for capital, O&M, *' distribution and transport (grades depend on region specific transport distance from mine to fields). *' +*' (OAE) Ocean alkalinity enhancement via ocean liming draws down CO2 from the atmosphere by adding (hydrated) lime +*' to the coastal or open ocean. Calcination process, which involves heating limestone to typically around 900-1000°C, +*' results in lime (CaO) and CO2. The CO2 from the process as well as burning gas (if used for fueling the calciner) +*' is assumed to be captured with a capture rate of 90%. The steps required to produce hydrated lime for ocean liming, +*' including limestone extraction, comminution, calcination, and hydration, are already well-established and used at a +*' large scale in the cement industry. Two options for ocean liming are parametrized: obtaining lime using a traditional +*' calciner fueled by natural gas and a novel calciner that can be fueled by either electricity or hydrogen. The efficiency +*' of the method depends on exogenous parameter cm_33_OAE_eff and distribution scenario (which can be optimistic or +*' pesimistic depending on the discharge rate, e.g., how hard it is to avoid precipitation when distributing the alkaline +*' material). +*' *' Equations for each option determine the capacity, emissions, energy demand, costs and limits. ***---------------------------------------------------- From d32daad6758c11b03ac6adff9ac91d65dbf6164e Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Thu, 8 Aug 2024 13:12:22 +0200 Subject: [PATCH 17/19] Calculated emissions captured from gas and calcination separately --- modules/33_CDR/portfolio/bounds.gms | 17 ++++++++----- modules/33_CDR/portfolio/declarations.gms | 6 +++-- modules/33_CDR/portfolio/equations.gms | 31 +++++++++++++++-------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/modules/33_CDR/portfolio/bounds.gms b/modules/33_CDR/portfolio/bounds.gms index d66248c86..0a4d275fd 100644 --- a/modules/33_CDR/portfolio/bounds.gms +++ b/modules/33_CDR/portfolio/bounds.gms @@ -17,25 +17,26 @@ if(card(te_used33) eq 0, *** Fix CCS from CDR if there're no technologies that require CCS if(card(te_ccs33) eq 0, vm_co2capture_cdr.fx(t,regi,enty,enty2,te,rlf)$ccs2te(enty,enty2,te) = 0; - v33_co2emi_non_atm.fx(t,regi,te_all33) = 0; ); *** Fix negative emissions and FE demand to zero for all the technologies that are not used vm_emiCdrTeDetail.fx(t,regi,te_all33)$(not te_used33(te_all33)) = 0; v33_FEdemand.fx(t,regi,entyFe,entyFe2,te_all33)$(not te_used33(te_all33) and fe2cdr(entyFe,entyFe2,te_all33)) = 0; +*** Fix non atmospheric emissions from CDR for all technologies that are not used +v33_co2emi_non_atm_gas.fx(t,regi,te_all33)$(not te_ccs33(te_all33)) = 0; *** Fix all CDR-related variables to zero for early time steps t< 2025 (no CDR in the real world) *** to reduce unnecessary freedom (and likelyhood of spontaneous solver infeasibilities) vm_emiCdrTeDetail.fx(t,regi,te_used33)$(t.val lt 2025) = 0.0; v33_FEdemand.fx(t,regi,entyFe,entyFe2,te_used33)$(fe2cdr(entyFe,entyFe2,te_used33) AND (t.val lt 2025)) = 0.0; -v33_co2emi_non_atm.fx(t,regi,te_used33)$(t.val lt 2025) = 0; vm_emiCdr.fx(t,regi,"co2")$(t.val lt 2025) = 0; vm_omcosts_cdr.fx(t,regi)$((t.val lt 2025)) = 0; vm_cap.fx(t,regi,"weathering",rlf)$(t.val lt 2025) = 0; +v33_co2emi_non_atm_gas.fx(t,regi,te_used33)$(t.val lt 2025) = 0; +v33_co2emi_non_atm_calcination.fx(t,regi,te_oae33)$(t.val lt 2025) = 0; *** vm_cap for dac is fixed for t<2025 in core/bounds.gms (tech_stat eq 4) vm_co2capture_cdr.fx(t,regi,enty,enty2,te,rlf)$(ccs2te(enty,enty2,te) AND t.val lt 2025) = 0; - *** Set minimum DAC capacities (if available) to help the solver find the technology if (te_used33("dac"), vm_cap.lo(t,regi,"dac",rlf)$(teNoTransform2rlf33("dac",rlf) AND (t.val ge 2030)) = sm_eps; @@ -49,16 +50,18 @@ if(te_used33("weathering"), !! if cm_startyear > 2025 and input_ref.gdx used EW, this fixing will be overwritten in submit.R v33_EW_onfield.fx(ttot,regi,rlf_cz33,rlf)$(ttot.val lt max(2025,cm_startyear)) = 0.0; !! v33_EW_onfield_tot.fx(ttot,regi,rlf_cz33,rlf)$(ttot.val lt max(2025,cm_startyear)) = 0.0; !! -); - -*** Bounds if enhanced weathering is not in the portfolio -if(not te_used33("weathering"), +else vm_omcosts_cdr.fx(t,regi) = 0; vm_cap.fx(t,regi,"weathering",rlf) = 0; ); +*** Bounds for OAE if(card(te_oae33) ne 0, + !! OAE starts in cm_33_OAE_startyear vm_cap.fx(t, regi, te_oae33, rlf)$(t.val lt cm_33_OAE_startyr) = 0; +else + v33_co2emi_non_atm_calcination.fx(t, regi, "oae_ng") = 0; + v33_co2emi_non_atm_calcination.fx(t, regi, "oae_el") = 0; ); *** EOF ./modules/33_CDR/portfolio/bounds.gms diff --git a/modules/33_CDR/portfolio/declarations.gms b/modules/33_CDR/portfolio/declarations.gms index 80cca8d63..81d08f9bd 100644 --- a/modules/33_CDR/portfolio/declarations.gms +++ b/modules/33_CDR/portfolio/declarations.gms @@ -30,7 +30,8 @@ v33_EW_onfield(ttot,all_regi,rlf,rlf) "amount of ground rock spread on fields i v33_EW_onfield_tot(ttot,all_regi,rlf,rlf) "total amount of ground rock on fields, for each climate zone and transportation distance [Gt]" v33_FEdemand(ttot,all_regi,all_enty,all_enty,all_te) "FE demand of each technology [TWa]" vm_co2capture_cdr(ttot,all_regi,all_enty,all_enty,all_te,rlf) "total emissions captured through technologies in the CDR module that enter the CCUS chain + captured emissions from associated FE demand [GtC / a]" -v33_co2emi_non_atm(ttot,all_regi,all_te) "CO2 from CDR-related acitivites that does not come from the atmosphere [GtC / a]" +v33_co2emi_non_atm_gas(ttot,all_regi,all_te) "CO2 from CDR-related acitivites that comes from energy demand [GtC / a]" +v33_co2emi_non_atm_calcination(ttot,all_regi,all_te) "CO2 from calcination [GtC / a]" ; negative variables @@ -42,7 +43,7 @@ q33_demFeCDR(ttot,all_regi,all_enty) "CDR demand balance for final energy" q33_emiCDR(ttot,all_regi) "aggregates the (negative) emissions captured by the CDR technologies" q33_H2bio_lim(ttot,all_regi) "limits H2 from bioenergy to FE - H2 demand from CDR, i.e. no H2 from bioenergy for DAC" q33_capconst(ttot,all_regi,all_te) "calculates amount of carbon captured by DAC and OAE" -q33_co2emi_non_atm(ttot,all_regi,all_te) "calculates the share of captured CO2 that does not come from the atmosphere" +q33_co2emi_non_atm_gas(ttot,all_regi,all_te) "calculates the share of captured CO2 that comes from burning gas" q33_ccsbal(ttot,all_regi,all_enty,all_enty,all_te) "calculates CCS emissions from CDR technologies" q33_DAC_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from DAC" @@ -56,6 +57,7 @@ q33_EW_emi(ttot,all_regi) "calculates amount of carbon captured by EW" q33_EW_LimEmi(ttot,all_regi) "limits EW to a maximal annual amount of ground rock of cm_LimRock" q33_OAE_FEdemand(ttot,all_regi,all_enty,all_te) "calculates final energy demand for ocean alkalinity enhancement" +q33_OAE_co2emi_non_atm_calcination(ttot,all_regi,all_te) "calculates the CO2 that comes from calcination (limestone decomposition)" ; *** EOF ./modules/33_CDR/portfolio/declarations.gms diff --git a/modules/33_CDR/portfolio/equations.gms b/modules/33_CDR/portfolio/equations.gms index 0a7f08749..f9e80630b 100644 --- a/modules/33_CDR/portfolio/equations.gms +++ b/modules/33_CDR/portfolio/equations.gms @@ -33,7 +33,10 @@ q33_emiCDR(t,regi).. vm_emiCdr(t,regi,"co2") =e= sum(te_used33, vm_emiCdrTeDetail(t,regi,te_used33)) - + (1 - s33_capture_rate) * sum(te_ccs33, v33_co2emi_non_atm(t, regi, te_ccs33)) + + (1 - s33_capture_rate) * ( + sum(te_ccs33, v33_co2emi_non_atm_gas(t, regi, te_ccs33)) + + sum(te_oae33, v33_co2emi_non_atm_calcination(t, regi, te_oae33)) + ) ; ***--------------------------------------------------------------------------- @@ -51,31 +54,30 @@ q33_capconst(t, regi, te_used33)$(not sameAs(te_used33, "weathering")).. ; ***--------------------------------------------------------------------------- -*' The CO2 captured from the gas used for heat production (DAC, OAE) -*' and from limestone decomposition (OAE only). +*' The CO2 captured from gas used for heat production (DAC, OAE). ***--------------------------------------------------------------------------- -q33_co2emi_non_atm(t, regi, te_ccs33).. - v33_co2emi_non_atm(t, regi, te_ccs33) +q33_co2emi_non_atm_gas(t, regi, te_ccs33).. + v33_co2emi_non_atm_gas(t, regi, te_ccs33) =e= - !! carbon captured from burning gas (DAC and OAE technologies) fm_dataemiglob("pegas","seh2","gash2c","cco2") !! conversion from PE to emissions * (1 / pm_eta_conv(t,regi,"gash2c")) !! conversion from PE to FE * sum(fe2cdr("fegas", entyFe2, te_ccs33), v33_FEdemand(t, regi,"fegas", entyFe2, te_ccs33)) !! FE gas used - !! carbon captured from calcination (OAE technologies only) - - (s33_OAE_chem_decomposition * vm_emiCdrTeDetail(t, regi, te_ccs33))$te_oae33(te_ccs33) ; ***--------------------------------------------------------------------------- *' Preparation of captured emissions to enter the CCUS chain. *' The first part of the equation describes emissons captured from the ambient air, -*' the second part is non-atmospheric CO2 (e.g., from energy usage), +*' the second part is non-atmospheric CO2 (e.g., from energy usage and calcination), *' assuming a capture rate s33_capture_rate. ***--------------------------------------------------------------------------- q33_ccsbal(t, regi, ccs2te(ccsCo2(enty), enty2, te)).. sum(teCCS2rlf(te, rlf), vm_co2capture_cdr(t, regi, enty, enty2, te, rlf)) =e= - vm_emiCdrTeDetail(t, regi, "dac") - + s33_capture_rate * sum(te_ccs33, v33_co2emi_non_atm(t, regi, te_ccs33)) + + s33_capture_rate * ( + sum(te_ccs33, v33_co2emi_non_atm_gas(t, regi, te_ccs33)) + + sum(te_oae33, v33_co2emi_non_atm_calcination(t, regi, te_oae33)) + ) ; ***--------------------------------------------------------------------------- @@ -202,5 +204,14 @@ q33_OAE_FEdemand(t,regi,entyFe2,te_oae33)$sum(entyFe, fe2cdr(entyFe,entyFe2,te_o p33_fedem(te_oae33, entyFe2) * sm_EJ_2_TWa * (- vm_emiCdrTeDetail(t, regi, te_oae33)) ; +***--------------------------------------------------------------------------- +*' The CO2 captured from limestone decomposition (OAE technologies only). +***--------------------------------------------------------------------------- +q33_OAE_co2emi_non_atm_calcination(t, regi, te_oae33).. + v33_co2emi_non_atm_calcination(t, regi, te_oae33) + =e= + - s33_OAE_chem_decomposition * vm_emiCdrTeDetail(t, regi, te_oae33) + ; + *' @stop *** EOF ./modules/33_CDR/portfolio/equations.gms From 8ed5bf2f53b30353d28cf2eb183e4d012f38531d Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Sat, 10 Aug 2024 09:43:20 +0200 Subject: [PATCH 18/19] Add missing space --- scripts/start/prepare.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/start/prepare.R b/scripts/start/prepare.R index 423118b6a..07d93af87 100644 --- a/scripts/start/prepare.R +++ b/scripts/start/prepare.R @@ -13,7 +13,7 @@ prepare <- function() { #require(lucode, quietly = TRUE,warn.conflicts =FALSE) require(magclass, quietly = TRUE,warn.conflicts =FALSE) require(tools, quietly = TRUE,warn.conflicts =FALSE) - require(remind2,quietly = TRUE,warn.conflicts =FALSE) + require(remind2, quietly = TRUE,warn.conflicts =FALSE) require(mrremind) require(mrvalidation) From 5b80c3fe2bce990ec59c327c9619f5f60c3529a4 Mon Sep 17 00:00:00 2001 From: Katarzyna Kowalczyk Date: Sat, 10 Aug 2024 10:42:26 +0200 Subject: [PATCH 19/19] OAE in CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eacc60f7..4660735c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). [[#1739](https://github.com/remindmodel/remind/pull/1739)] - **scripts** fail transparently on duplicated column names in `scenario_config*.csv` files [[#1742](https://github.com/remindmodel/remind/pull/1742)] +- **33_CDR** added ocean alkalinity enhancement to the CDR portfolio (OAE is turned off by default) + [[#1777](https://github.com/remindmodel/remind/pull/1777)] ### fixed - included CCS from plastic waste incineration in CCS mass flows so it is