From 904d2d0338f246aa3222f0781a7c3774165ae92f Mon Sep 17 00:00:00 2001 From: tabeado Date: Thu, 16 Jul 2026 10:31:53 +0200 Subject: [PATCH 01/11] ERW unit documentation --- core/datainput.gms | 6 +++--- core/input/generisdata_tech.prn | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index f1b5a31686..7e746e0d36 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -290,9 +290,9 @@ fm_dataglob("inco0", "oae_ng") = fm_dataglob("inco0", "oae_ng") / (cm_33_OAE_eff fm_dataglob("inco0", "oae_el") = fm_dataglob("inco0", "oae_el") / (cm_33_OAE_eff / sm_c_2_co2); *** convert inco0, floorcost and omv to REMIND units by applying a factor 0.001 -*** category energy technology ccs technology process-based industry -*** input data unit $/kW $/(tC/a) $/(t/a) -*** REMIND unit T$/TW T$/(GtC/a) T$/(Gt/a) +*** category energy technology ccs technology process-based industry weathering +*** input data unit $/kW $/(tC/a) $/(t/a) $/(t rocks/a) +*** REMIND unit T$/TW T$/(GtC/a) T$/(Gt/a) T$/(Gt rocks/a) fm_dataglob("inco0",te) = s_DpKW_2_TDpTW * fm_dataglob("inco0",te); fm_dataglob("floorcost",te) = s_DpKW_2_TDpTW * fm_dataglob("floorcost",te); fm_dataglob("omv",te) = s_DpKWa_2_TDpTWa * fm_dataglob("omv",te); diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index 689d68f66d..f731e7e457 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -1,7 +1,7 @@ *** SOF ./core/input/generisdata_tech.prn $ontext tech_stat technology status: how close a technology is to market readiness. Scale: 0-3, with 0 'I can go out and build a GW plant today' to 3 'Still some research necessary' -inco0 Initial investment costs given in $[2015] / kW[output] capacity; for dac/prc cc: $[2015] / (tC[captured]/a); for other indutry prc: $[2015]/(t[output]/a) +inco0 Initial investment costs given in $[2015] / kW[output] capacity; for dac/prc cc: $[2015] / (tC[captured]/a); for other indutry prc: $[2015]/(t[output]/a); for weathering: $[2015]/(t rock/a) floorcost Floor investment costs, given in $[2015] / kW[output]; for dac: $[2015] / (tC[captured]/a) constrTme Construction time in years, needed to calculate turn-key cost premium compared to overnight costs lifetime Average lifetime of a technology, given in years. Effective maximum lifetime is longer than that. From 814ed21c19ad0f6cb184de454bbe51774758a4e6 Mon Sep 17 00:00:00 2001 From: tabeado Date: Tue, 21 Jul 2026 11:58:34 +0200 Subject: [PATCH 02/11] remove global rock limit switch --- main.gms | 5 ++--- modules/33_carbonRemoval/portfolio/datainput.gms | 5 +---- modules/33_carbonRemoval/portfolio/declarations.gms | 2 -- modules/33_carbonRemoval/portfolio/equations.gms | 10 ---------- modules/33_carbonRemoval/portfolio/realization.gms | 3 +-- standalone/MOFEX/MOFEX.gms | 2 -- standalone/template.gms | 2 -- standalone/trade/trade.gms | 2 -- 8 files changed, 4 insertions(+), 27 deletions(-) diff --git a/main.gms b/main.gms index 31538296af..0de13db480 100755 --- a/main.gms +++ b/main.gms @@ -1086,10 +1086,9 @@ parameter ; cm_gs_ew = 20; !! def = 20 !! regexp = is.numeric *' + parameter - cm_LimRock "limit amount of rock spread each year [Gt]" -; - cm_LimRock = 1000; !! def = 1000 + *' parameter cm_33_EW_upScalingRateLimit "Annual growth rate limit on upscaling of mining & spreading rocks on fields" diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index 755deccb6f..90c52ca256 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -54,9 +54,6 @@ p33_rock_weath_rate("2") = s33_rock_weath_rate_ambientT * 0.29; p33_fedem("weathering", "feels") = 6.62 * cm_gs_ew**(-1.16); 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)); - *' Annual growth rate limit on upscaling of mining & spreading rocks on fields p33_EW_upScalingLimit(ttot) = cm_33_EW_upScalingRateLimit; @@ -64,7 +61,7 @@ p33_EW_upScalingLimit(ttot) = cm_33_EW_upScalingRateLimit; p33_EW_shortTermEW_Limit(regi) = cm_33_EW_shortTermLimit * sum(rlf, f33_maxProdGradeRegiWeathering(regi, rlf)); *' Narrative switch: what share of cropland can be used for EW? -parameter f33_EW_maxShareOfCropland(ext_regi) "Maximum share of cropland available for enhanced weathering by region" / %cm_33_EW_maxShareOfCropland% /; +parameter f33_EW_maxShareOfCropland(ext_regi) "Maximum share of suitable cropland available for enhanced weathering by region" / %cm_33_EW_maxShareOfCropland% /; p33_EW_maxShareOfCropland(regi) = 1; !! if no value is assigned to GLO, the default share is set to 100% p33_EW_maxShareOfCropland(regi) = f33_EW_maxShareOfCropland("GLO"); !! if a value is assigned to GLO, this value is set for all regions loop(ext_regi$f33_EW_maxShareOfCropland(ext_regi), diff --git a/modules/33_carbonRemoval/portfolio/declarations.gms b/modules/33_carbonRemoval/portfolio/declarations.gms index 2614d4d8c5..972d7d1552 100644 --- a/modules/33_carbonRemoval/portfolio/declarations.gms +++ b/modules/33_carbonRemoval/portfolio/declarations.gms @@ -24,7 +24,6 @@ parameters *** Multiple options p33_fedem(all_te,all_enty) "final energy demand of each technology [EJ/GtC] (for EW the unit is [EJ/Gt stone])" *** EW -p33_LimRock(all_regi) "regional share of EW limit [fraction], calculated ex ante for a maximal annual amount of 8 Gt rock in D:\projects\CEMICS\paper_technical\supply_curve_transport_remind_regions.m" p33_rock_weath_rate(rlf) "fraction of stone weathering per year depending on climate grade (warm or temperate)" p33_EW_upScalingLimit(ttot) "Annual growth rate limit on upscaling of mining & spreading rocks on fields" p33_EW_shortTermEW_Limit(all_regi) "Limit on 2030 potential for enhanced weathering, defined in Gt rocks, based on % of land on which EW is applied" @@ -89,7 +88,6 @@ q33_EW_omcosts(ttot,all_regi) "calculates O&M costs for spreading ground rocks q33_EW_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from enhanced weathering" 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_EW_upscaling_rate(ttot, all_regi) "limits spreading of rock to a steep but credible upscaling rate" q33_EW_ShortTermBound(ttot,all_regi) "Limits short term potential for enhanced weathering" diff --git a/modules/33_carbonRemoval/portfolio/equations.gms b/modules/33_carbonRemoval/portfolio/equations.gms index b53f78255b..902b27582d 100644 --- a/modules/33_carbonRemoval/portfolio/equations.gms +++ b/modules/33_carbonRemoval/portfolio/equations.gms @@ -189,16 +189,6 @@ q33_EW_potential(t,regi,rlf_cz33).. ; -***--------------------------------------------------------------------------- -*' An annual limit for the maximum global amount of rocks spread [Gt] can be set via cm_LimRock, -*' e.g. due to sustainability concerns. -***--------------------------------------------------------------------------- -q33_EW_LimEmi(t,regi).. - sum((rlf_cz33, rlf), v33_EW_onfield(t,regi,rlf_cz33,rlf)) - =l= - cm_LimRock * p33_LimRock(regi) - ; - ***--------------------------------------------------------------------------- *' Short term bound on spreading of rock ***--------------------------------------------------------------------------- diff --git a/modules/33_carbonRemoval/portfolio/realization.gms b/modules/33_carbonRemoval/portfolio/realization.gms index a36706d8af..5c60d42e47 100644 --- a/modules/33_carbonRemoval/portfolio/realization.gms +++ b/modules/33_carbonRemoval/portfolio/realization.gms @@ -19,8 +19,7 @@ *' 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 *' decay over time of the spread rocks. There is an upper limit on the amount of rock that can be on the fields, so that -*' in equilibrium only the part that decays in one timestep can be replaced in the next. In addition, an arbitrary -*' limit of the amount of rock spread each year can be set in cm_LimRock. Costs consist of costs for capital, O&M, +*' in equilibrium only the part that decays in one timestep can be replaced in the next. 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 diff --git a/standalone/MOFEX/MOFEX.gms b/standalone/MOFEX/MOFEX.gms index 78266bd2c4..e41aacdfda 100644 --- a/standalone/MOFEX/MOFEX.gms +++ b/standalone/MOFEX/MOFEX.gms @@ -170,7 +170,6 @@ c_export_tax_scen "choose which oil export tax is used in the model. 0 = none cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" -cm_LimRock "limit amount of rock spread each year [Gt]" cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" c_budgetCO2FFI "carbon budget for CO2 emissions from FFI (in GtCO2)" @@ -299,7 +298,6 @@ cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 cm_gs_ew = 20; !! def = 20 -cm_LimRock = 1000; !! def = 1000 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 c_abtrdy = 2010; !! def = 2010 diff --git a/standalone/template.gms b/standalone/template.gms index 36e48f195b..32843c7795 100644 --- a/standalone/template.gms +++ b/standalone/template.gms @@ -166,7 +166,6 @@ c_export_tax_scen "choose which oil export tax is used in the model. 0 = none cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" -cm_LimRock "limit amount of rock spread each year [Gt]" cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" c_budgetCO2FFI "carbon budget for CO2 emissions from FFI (in GtCO2)" @@ -253,7 +252,6 @@ cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 cm_gs_ew = 20; !! def = 20 -cm_LimRock = 1000; !! def = 1000 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 c_abtrdy = 2010; !! def = 2010 diff --git a/standalone/trade/trade.gms b/standalone/trade/trade.gms index 68ae9acc91..d5be04c038 100644 --- a/standalone/trade/trade.gms +++ b/standalone/trade/trade.gms @@ -174,7 +174,6 @@ c_export_tax_scen "choose which oil export tax is used in the model. 0 = none cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" -cm_LimRock "limit amount of rock spread each year [Gt]" cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" c_budgetCO2FFI "carbon budget for CO2 emissions from FFI (in GtCO2)" @@ -304,7 +303,6 @@ cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 cm_gs_ew = 20; !! def = 20 -cm_LimRock = 1000; !! def = 1000 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 c_abtrdy = 2010; !! def = 2010 From 33324f26574b54d5f6aac96e59086bc29f9c6b3a Mon Sep 17 00:00:00 2001 From: tabeado Date: Wed, 22 Jul 2026 12:29:52 +0200 Subject: [PATCH 03/11] adjust weathering cost + documentation --- core/input/generisdata_tech.prn | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index f731e7e457..9a6595dea2 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -162,7 +162,7 @@ constrTme 3 5 lifetime 40 40 20 20 25 25 mix0 1.00 1.00 eta 1.00 1.00 1.00 1.00 1.00 1.00 -omf 0.06 0.12 0.84 0.025 0.35 0.17 +omf 0.06 0.12 0.59 0.025 0.35 0.17 ccap0 0.0008 learn 0.15 @@ -303,6 +303,13 @@ Ocean Liming - oae Costs per tC removed is calculated in the code as it depends on the efficiency (tCO2/tCaO; exogenous): cost (USD/tC) = inco0 (USD/tCaO) / ( efficiency (tCO2/tCaO) / 3.66 (tCO2/tC) ) +Enhanced Rock Weathering - weathering + Parameterization based on Strefler et al (2018) doi.org/10.1088/1748-9326/aaa9c4 + annuity factor = 0.08 for lifetime of 20 years and r = 0.05; capacity factor = 0.69 + inco0: 5 (USD/t rock) * 0.69 / 0.08 = 43 USD/t rock/a for mining and production + omf: O&M cost from rock mining & production (25 USD/t rock) and transportation & distribution (12 USD/t rock), i.e. 37/(43/0.69) = 0.86 + To use the upper Capital Cost estimate from Strefler et al, 15 USD/t rock, set inco0 = 129 and omf = 0.2 + Gas to Liquids (GtL) Fischer-Tropsch Process - gasftrec/gasftcrec efficiency eta = 0.60 (0.57 with capture), estimation at higher end of efficiency spectrum Details in Issue 518/PR 2034 From eb4eacf49481eb2b634925e73512bc6f6881b5ec Mon Sep 17 00:00:00 2001 From: tabeado Date: Wed, 22 Jul 2026 15:37:30 +0200 Subject: [PATCH 04/11] add cm_33_EW_rockRemPot, documentation, fixes --- core/input/generisdata_tech.prn | 4 ++-- main.gms | 10 +++++++++- modules/33_carbonRemoval/portfolio/datainput.gms | 4 +++- modules/33_carbonRemoval/portfolio/declarations.gms | 2 +- modules/33_carbonRemoval/portfolio/equations.gms | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index 9a6595dea2..3b7b833bcf 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -155,8 +155,8 @@ lifetime 30 30 45 45 45 *** carbon management + ccsinjeon ccsinjeoff weathering dac oae_ng oae_el -tech_stat 0 0 4 -inco0 350 525 0.01 18800 200 400 +tech_stat 0 0 1 4 +inco0 350 525 43 18800 200 400 floorcost 4800 constrTme 3 5 lifetime 40 40 20 20 25 25 diff --git a/main.gms b/main.gms index 0de13db480..cf90c2ef13 100755 --- a/main.gms +++ b/main.gms @@ -1088,7 +1088,15 @@ parameter *' parameter - + cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock." +; + cm_33_EW_rockRemPot = 0.3; !! def = 0.3 t CO2 / t basalt +*' Theoretical potential is influenced by the chemical composition of the rock, in particular calcium and magnesium content. +*' * (0.3): 0.3 t CO2 / t basalt is the commonly used average, see e.g. Strefler et al 2018 (SI-A Table A-1) +*' * (0.2-0.4): 0.2 and 0.4 t CO2 / t basalt are a lower and upper bound in Strefler et al 2018 (SI-A Table A-1) +*' The theoretical potential may not be reached due to different loss pathways (dissolution through strong acids; +*' secondary mineral formation (esp. clays); secondary carbonate formation (where carbon retention is only temporary)) which +*' strongly depend on the local soil conditions. Reduction below 50% of the theoretical potential is well possible. *' parameter cm_33_EW_upScalingRateLimit "Annual growth rate limit on upscaling of mining & spreading rocks on fields" diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index 90c52ca256..76b49a11e3 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -39,7 +39,9 @@ s33_step = 2.5; *' @code *' fix costs [T$/Gt stone]. Data from strefler et al. in $/t stone: mining, crushing, grinding (5.0 investment costs, 25.1 O&M costs), spreading (12.1 O&M costs) s33_costs_fix = 0.0422; -s33_co2_rem_pot = 0.3 * 12/44; !! default for basalt, for Olivine 1.1 +s33_rockRemPot = cm_33_EW_rockRemPot * 12/44; !! default for basalt is 0.3 t CO2/t rock, for Olivine 1.1 t CO2/t rock. Converted to t C/t rock. +*' Sources for loss pathways that would reduce the total removal potential per ton rock: +*' https://www.carbon-drawdown.de/blog/2026-7-18-where-does-the-co-removal-potential-of-enhanced-weathering-actually-go; https://cdrxiv.org/preprint/417 *' rock weathering rate (i.e. fraction of rock weathering per year) at ambient temperature (25 degree C), based on *' eq 2 in strefler, amann et al. (2018): diff --git a/modules/33_carbonRemoval/portfolio/declarations.gms b/modules/33_carbonRemoval/portfolio/declarations.gms index 972d7d1552..bfbacca902 100644 --- a/modules/33_carbonRemoval/portfolio/declarations.gms +++ b/modules/33_carbonRemoval/portfolio/declarations.gms @@ -9,7 +9,7 @@ scalars *** Multiple options sm_capture_rate_cdrmodule "CO2 capture rate for CDR energy and process emissions, i.e. fegas use in OAE and DAC and for calcination emissions in oae" / 0.9 / *** EW -s33_co2_rem_pot "specific carbon removal potential [Gt C per Gt ground rock]" +s33_rockRemPot "specific carbon removal potential [Gt C per Gt ground rock]" s33_rock_weath_rate_ambientT "fraction of stone weathering per year at ambient temperature (25 degree C)" s33_costs_fix "fixed costs for mining, grinding, spreading [T$/Gt stone]" s33_step "size of bins in v33_weathering_onfield [Gt stone]" diff --git a/modules/33_carbonRemoval/portfolio/equations.gms b/modules/33_carbonRemoval/portfolio/equations.gms index 902b27582d..d3a59c993e 100644 --- a/modules/33_carbonRemoval/portfolio/equations.gms +++ b/modules/33_carbonRemoval/portfolio/equations.gms @@ -154,7 +154,7 @@ q33_EW_emi(t,regi).. vm_emiCdrTeDetail(t,regi, "weathering") =e= sum((rlf_cz33, rlf), - - v33_EW_onfield_tot(t,regi,rlf_cz33,rlf) * s33_co2_rem_pot * p33_rock_weath_rate(rlf_cz33) + - v33_EW_onfield_tot(t,regi,rlf_cz33,rlf) * s33_rockRemPot * p33_rock_weath_rate(rlf_cz33) ) ; From 031af72144ab514703902d8215529472137c8e87 Mon Sep 17 00:00:00 2001 From: Tabea Dorndorf <117268634+tabeado@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:47:25 +0200 Subject: [PATCH 05/11] bugfix in description Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- core/input/generisdata_tech.prn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index 3b7b833bcf..0b973768a8 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -307,7 +307,7 @@ Enhanced Rock Weathering - weathering Parameterization based on Strefler et al (2018) doi.org/10.1088/1748-9326/aaa9c4 annuity factor = 0.08 for lifetime of 20 years and r = 0.05; capacity factor = 0.69 inco0: 5 (USD/t rock) * 0.69 / 0.08 = 43 USD/t rock/a for mining and production - omf: O&M cost from rock mining & production (25 USD/t rock) and transportation & distribution (12 USD/t rock), i.e. 37/(43/0.69) = 0.86 + omf: O&M cost from rock mining & production (25 USD/t rock) and transportation & distribution (12 USD/t rock), i.e. 37/(43/0.69) = 0.59 To use the upper Capital Cost estimate from Strefler et al, 15 USD/t rock, set inco0 = 129 and omf = 0.2 Gas to Liquids (GtL) Fischer-Tropsch Process - gasftrec/gasftcrec From d54eac80c757d13c4e07e4e84bfca4be8be699e9 Mon Sep 17 00:00:00 2001 From: tabeado Date: Mon, 27 Jul 2026 12:19:24 +0200 Subject: [PATCH 06/11] remove old ERW cost calculation in module 33 + renaming --- core/equations.gms | 2 +- modules/33_carbonRemoval/portfolio/bounds.gms | 4 ++-- modules/33_carbonRemoval/portfolio/datainput.gms | 2 -- modules/33_carbonRemoval/portfolio/declarations.gms | 3 +-- modules/33_carbonRemoval/portfolio/equations.gms | 4 ++-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/core/equations.gms b/core/equations.gms index 2ed65dd7dd..ccf1e94836 100644 --- a/core/equations.gms +++ b/core/equations.gms @@ -106,7 +106,7 @@ q_costOM(t,regi).. vm_costTeCapital(t,regi,te) * vm_cap(t,regi,te,rlf) ) ) - + vm_omcosts_cdr(t,regi) + + vm_EW_transport_costs(t,regi) ; ***--------------------------------------------------------------------------- diff --git a/modules/33_carbonRemoval/portfolio/bounds.gms b/modules/33_carbonRemoval/portfolio/bounds.gms index 25474693d3..495d8e453f 100644 --- a/modules/33_carbonRemoval/portfolio/bounds.gms +++ b/modules/33_carbonRemoval/portfolio/bounds.gms @@ -30,7 +30,7 @@ vm_co2emi_cdrFE_beforeCapture.fx(t,regi,te_all33)$(not te_ccs33(te_all33)) = 0; 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; vm_emiCdr.fx(t,regi,"co2")$(t.val lt 2025) = 0; -vm_omcosts_cdr.fx(t,regi)$((t.val lt 2025)) = 0; +vm_EW_transport_costs.fx(t,regi)$((t.val lt 2025)) = 0; vm_cap.fx(t,regi,"weathering",rlf)$(t.val lt 2025) = 0; vm_co2emi_cdrFE_beforeCapture.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; @@ -61,7 +61,7 @@ if(te_used33("weathering"), v33_EW_onfield_tot.fx(ttot,regi,rlf_cz33,rlf)$(ttot.val lt max(2025,cm_startyear)) = 0.0; !! vm_emiCdrTeDetail.up(ttot,regi,"weathering")$(ttot.val gt 2040) = - sm_eps; !! force some minimum amount of EW to help the solver see it else - vm_omcosts_cdr.fx(t,regi) = 0; + vm_EW_transport_costs.fx(t,regi) = 0; vm_cap.fx(t,regi,"weathering",rlf) = 0; ); diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index 76b49a11e3..5a090b1eb9 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -37,8 +37,6 @@ display p33_EW_transport_costs; s33_step = 2.5; *' @code -*' fix costs [T$/Gt stone]. Data from strefler et al. in $/t stone: mining, crushing, grinding (5.0 investment costs, 25.1 O&M costs), spreading (12.1 O&M costs) -s33_costs_fix = 0.0422; s33_rockRemPot = cm_33_EW_rockRemPot * 12/44; !! default for basalt is 0.3 t CO2/t rock, for Olivine 1.1 t CO2/t rock. Converted to t C/t rock. *' Sources for loss pathways that would reduce the total removal potential per ton rock: *' https://www.carbon-drawdown.de/blog/2026-7-18-where-does-the-co-removal-potential-of-enhanced-weathering-actually-go; https://cdrxiv.org/preprint/417 diff --git a/modules/33_carbonRemoval/portfolio/declarations.gms b/modules/33_carbonRemoval/portfolio/declarations.gms index bfbacca902..46f774c2c0 100644 --- a/modules/33_carbonRemoval/portfolio/declarations.gms +++ b/modules/33_carbonRemoval/portfolio/declarations.gms @@ -11,7 +11,6 @@ sm_capture_rate_cdrmodule "CO2 capture rate for CDR energy and process emi *** EW s33_rockRemPot "specific carbon removal potential [Gt C per Gt ground rock]" s33_rock_weath_rate_ambientT "fraction of stone weathering per year at ambient temperature (25 degree C)" -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. *** OAE @@ -41,7 +40,7 @@ p33_GDP_NetNeg_share(all_regi) "Upper bound on share of expen ; variables -vm_omcosts_cdr(tall,all_regi) "O&M costs for spreading grinded rocks on fields [T$]" +vm_EW_transport_costs(tall,all_regi) "O&M costs for spreading grinded rocks on fields [T$]" ; positive variables diff --git a/modules/33_carbonRemoval/portfolio/equations.gms b/modules/33_carbonRemoval/portfolio/equations.gms index d3a59c993e..c926a638f7 100644 --- a/modules/33_carbonRemoval/portfolio/equations.gms +++ b/modules/33_carbonRemoval/portfolio/equations.gms @@ -172,10 +172,10 @@ q33_EW_FEdemand(t,regi,entyFe2)$sum(entyFe, fe2cdr(entyFe,entyFe2,"weathering")) *' O&M costs of EW, consisting of fix costs for mining, grinding and spreading, and transportation costs. ***--------------------------------------------------------------------------- q33_EW_omcosts(t,regi).. - vm_omcosts_cdr(t,regi) + vm_EW_transport_costs(t,regi) =e= sum((rlf_cz33, rlf), - (s33_costs_fix + p33_EW_transport_costs(regi,rlf_cz33,rlf)) * v33_EW_onfield(t,regi,rlf_cz33,rlf) + (p33_EW_transport_costs(regi,rlf_cz33,rlf)) * v33_EW_onfield(t,regi,rlf_cz33,rlf) ) ; From c4ad69d81612377671f2a98dfa7c18fe90554a8b Mon Sep 17 00:00:00 2001 From: tabeado Date: Mon, 27 Jul 2026 14:26:13 +0200 Subject: [PATCH 07/11] consistency fixes --- core/datainput.gms | 4 ++-- core/input/generisdata_tech.prn | 2 +- main.gms | 2 +- modules/33_carbonRemoval/portfolio/datainput.gms | 2 +- modules/33_carbonRemoval/portfolio/declarations.gms | 6 +++--- standalone/MOFEX/MOFEX.gms | 2 ++ standalone/template.gms | 2 ++ standalone/trade/trade.gms | 2 ++ 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/core/datainput.gms b/core/datainput.gms index 7e746e0d36..5ced91119c 100644 --- a/core/datainput.gms +++ b/core/datainput.gms @@ -291,8 +291,8 @@ fm_dataglob("inco0", "oae_el") = fm_dataglob("inco0", "oae_el") / (cm_33_OAE_eff *** convert inco0, floorcost and omv to REMIND units by applying a factor 0.001 *** category energy technology ccs technology process-based industry weathering -*** input data unit $/kW $/(tC/a) $/(t/a) $/(t rocks/a) -*** REMIND unit T$/TW T$/(GtC/a) T$/(Gt/a) T$/(Gt rocks/a) +*** input data unit $/kW $/(tC/a) $/(t/a) $/(t rock/a) +*** REMIND unit T$/TW T$/(GtC/a) T$/(Gt/a) T$/(Gt rock/a) fm_dataglob("inco0",te) = s_DpKW_2_TDpTW * fm_dataglob("inco0",te); fm_dataglob("floorcost",te) = s_DpKW_2_TDpTW * fm_dataglob("floorcost",te); fm_dataglob("omv",te) = s_DpKWa_2_TDpTWa * fm_dataglob("omv",te); diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index 0b973768a8..3864a4ed21 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -1,7 +1,7 @@ *** SOF ./core/input/generisdata_tech.prn $ontext tech_stat technology status: how close a technology is to market readiness. Scale: 0-3, with 0 'I can go out and build a GW plant today' to 3 'Still some research necessary' -inco0 Initial investment costs given in $[2015] / kW[output] capacity; for dac/prc cc: $[2015] / (tC[captured]/a); for other indutry prc: $[2015]/(t[output]/a); for weathering: $[2015]/(t rock/a) +inco0 Initial investment costs given in $[2015] / kW[output] capacity; for dac/prc cc: $[2015] / (tC[captured]/a); for other industry prc: $[2015]/(t[output]/a); for weathering: $[2015]/(t rock/a) floorcost Floor investment costs, given in $[2015] / kW[output]; for dac: $[2015] / (tC[captured]/a) constrTme Construction time in years, needed to calculate turn-key cost premium compared to overnight costs lifetime Average lifetime of a technology, given in years. Effective maximum lifetime is longer than that. diff --git a/main.gms b/main.gms index cf90c2ef13..568aa023b6 100755 --- a/main.gms +++ b/main.gms @@ -1088,7 +1088,7 @@ parameter *' parameter - cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock." + cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." ; cm_33_EW_rockRemPot = 0.3; !! def = 0.3 t CO2 / t basalt *' Theoretical potential is influenced by the chemical composition of the rock, in particular calcium and magnesium content. diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index 5a090b1eb9..c16a911bb5 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -37,7 +37,7 @@ display p33_EW_transport_costs; s33_step = 2.5; *' @code -s33_rockRemPot = cm_33_EW_rockRemPot * 12/44; !! default for basalt is 0.3 t CO2/t rock, for Olivine 1.1 t CO2/t rock. Converted to t C/t rock. +s33_rockRemPot = cm_33_EW_rockRemPot / sm_c_2_co2; !! default for basalt is 0.3 t CO2/t rock, for Olivine 1.1 t CO2/t rock. Converted to t C/t rock. *' Sources for loss pathways that would reduce the total removal potential per ton rock: *' https://www.carbon-drawdown.de/blog/2026-7-18-where-does-the-co-removal-potential-of-enhanced-weathering-actually-go; https://cdrxiv.org/preprint/417 diff --git a/modules/33_carbonRemoval/portfolio/declarations.gms b/modules/33_carbonRemoval/portfolio/declarations.gms index 46f774c2c0..b5a37fb0a6 100644 --- a/modules/33_carbonRemoval/portfolio/declarations.gms +++ b/modules/33_carbonRemoval/portfolio/declarations.gms @@ -9,9 +9,9 @@ scalars *** Multiple options sm_capture_rate_cdrmodule "CO2 capture rate for CDR energy and process emissions, i.e. fegas use in OAE and DAC and for calcination emissions in oae" / 0.9 / *** EW -s33_rockRemPot "specific carbon removal potential [Gt C per Gt ground rock]" +s33_rockRemPot "specific carbon removal potential [t C / t rock]" s33_rock_weath_rate_ambientT "fraction of stone weathering per year at ambient temperature (25 degree C)" -s33_step "size of bins in v33_weathering_onfield [Gt stone]" +s33_step "size of bins in v33_weathering_onfield [Gt stone]" / 2.5 / *JeS* GJ/tCO2 = EJ/Gt CO2 = 44/12 EJ/Gt C. *** OAE s33_OAE_efficiency "the amount of rock required to sequester 1GtC [Gt rock / GtC]" @@ -21,7 +21,7 @@ s33_OAE_glo_limit "global limit for OAE [tC / a]" parameters *** Multiple options -p33_fedem(all_te,all_enty) "final energy demand of each technology [EJ/GtC] (for EW the unit is [EJ/Gt stone])" +p33_fedem(all_te,all_enty) "final energy demand of each technology [EJ/GtC] (for EW the unit is [EJ/Gt rock])" *** EW p33_rock_weath_rate(rlf) "fraction of stone weathering per year depending on climate grade (warm or temperate)" p33_EW_upScalingLimit(ttot) "Annual growth rate limit on upscaling of mining & spreading rocks on fields" diff --git a/standalone/MOFEX/MOFEX.gms b/standalone/MOFEX/MOFEX.gms index e41aacdfda..2b7414b8c9 100644 --- a/standalone/MOFEX/MOFEX.gms +++ b/standalone/MOFEX/MOFEX.gms @@ -170,6 +170,7 @@ c_export_tax_scen "choose which oil export tax is used in the model. 0 = none cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" +cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" c_budgetCO2FFI "carbon budget for CO2 emissions from FFI (in GtCO2)" @@ -298,6 +299,7 @@ cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 cm_gs_ew = 20; !! def = 20 +cm_33_EW_rockRemPot = 0.3; !! def = 0.3 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 c_abtrdy = 2010; !! def = 2010 diff --git a/standalone/template.gms b/standalone/template.gms index 32843c7795..f0b001ea63 100644 --- a/standalone/template.gms +++ b/standalone/template.gms @@ -166,6 +166,7 @@ c_export_tax_scen "choose which oil export tax is used in the model. 0 = none cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" +cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" c_budgetCO2FFI "carbon budget for CO2 emissions from FFI (in GtCO2)" @@ -252,6 +253,7 @@ cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 cm_gs_ew = 20; !! def = 20 +cm_33_EW_rockRemPot = 0.3; !! def = 0.3 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 c_abtrdy = 2010; !! def = 2010 diff --git a/standalone/trade/trade.gms b/standalone/trade/trade.gms index d5be04c038..68a7580b20 100644 --- a/standalone/trade/trade.gms +++ b/standalone/trade/trade.gms @@ -174,6 +174,7 @@ c_export_tax_scen "choose which oil export tax is used in the model. 0 = none cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" +cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" c_budgetCO2FFI "carbon budget for CO2 emissions from FFI (in GtCO2)" @@ -303,6 +304,7 @@ cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 cm_gs_ew = 20; !! def = 20 +cm_33_EW_rockRemPot = 0.3; !! def = 0.3 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 c_abtrdy = 2010; !! def = 2010 From 49c5700091b7a14442bb3a6e0f3066af34190b30 Mon Sep 17 00:00:00 2001 From: tabeado Date: Thu, 6 Aug 2026 15:58:49 +0200 Subject: [PATCH 08/11] ERW documentation and removing cm_gs_ew --- core/input/generisdata_tech.prn | 3 ++- main.gms | 5 ----- modules/33_carbonRemoval/portfolio/datainput.gms | 4 ++-- .../33_carbonRemoval/portfolio/declarations.gms | 7 ++++--- modules/33_carbonRemoval/portfolio/equations.gms | 6 +++--- .../33_carbonRemoval/portfolio/realization.gms | 16 ++++++++++++---- standalone/MOFEX/MOFEX.gms | 2 -- standalone/template.gms | 2 -- standalone/trade/trade.gms | 2 -- tests/testthat/test_01-checkFixCfg.R | 1 - 10 files changed, 23 insertions(+), 25 deletions(-) diff --git a/core/input/generisdata_tech.prn b/core/input/generisdata_tech.prn index 3864a4ed21..a71219ec18 100644 --- a/core/input/generisdata_tech.prn +++ b/core/input/generisdata_tech.prn @@ -307,7 +307,8 @@ Enhanced Rock Weathering - weathering Parameterization based on Strefler et al (2018) doi.org/10.1088/1748-9326/aaa9c4 annuity factor = 0.08 for lifetime of 20 years and r = 0.05; capacity factor = 0.69 inco0: 5 (USD/t rock) * 0.69 / 0.08 = 43 USD/t rock/a for mining and production - omf: O&M cost from rock mining & production (25 USD/t rock) and transportation & distribution (12 USD/t rock), i.e. 37/(43/0.69) = 0.59 + omf: O&M cost from rock mining & production (25 USD/t rock) and spreading on fields (12 USD/t rock), i.e. 37/(43/0.69) = 0.59 + Additional transport cost from mine to field are accounted separately in 33_carbonRemoval depending on distance grade. To use the upper Capital Cost estimate from Strefler et al, 15 USD/t rock, set inco0 = 129 and omf = 0.2 Gas to Liquids (GtL) Fischer-Tropsch Process - gasftrec/gasftcrec diff --git a/main.gms b/main.gms index 568aa023b6..2657fc6835 100755 --- a/main.gms +++ b/main.gms @@ -1081,11 +1081,6 @@ parameter *' 5 Gt CO2/yr uptake limit corresponds roughly to CaO being distributed in the upper 2m of the entire (!) EEZ *' up to the precipitation avoiding concentration limit, assuming average uptake efficiency. *' -parameter - cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" -; - cm_gs_ew = 20; !! def = 20 !! regexp = is.numeric -*' parameter cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index c16a911bb5..79b83f8994 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -51,8 +51,8 @@ p33_rock_weath_rate("1") = s33_rock_weath_rate_ambientT * 0.94; p33_rock_weath_rate("2") = s33_rock_weath_rate_ambientT * 0.29; *' JeS FE demand fit from Thorben: SI D in strefler, amann et al. (2018) -p33_fedem("weathering", "feels") = 6.62 * cm_gs_ew**(-1.16); -p33_fedem("weathering", "fedie") = 0.3; +p33_fedem("weathering", "feels") = 6.62 * s33_rockGrainSize**(-1.16); !! electricity for grinding of rocks, depends on the grain size. +p33_fedem("weathering", "fedie") = 0.3; !! diesel for spreading rocks on fields using tractors *' Annual growth rate limit on upscaling of mining & spreading rocks on fields p33_EW_upScalingLimit(ttot) = cm_33_EW_upScalingRateLimit; diff --git a/modules/33_carbonRemoval/portfolio/declarations.gms b/modules/33_carbonRemoval/portfolio/declarations.gms index b5a37fb0a6..9934a4ed86 100644 --- a/modules/33_carbonRemoval/portfolio/declarations.gms +++ b/modules/33_carbonRemoval/portfolio/declarations.gms @@ -9,6 +9,7 @@ scalars *** Multiple options sm_capture_rate_cdrmodule "CO2 capture rate for CDR energy and process emissions, i.e. fegas use in OAE and DAC and for calcination emissions in oae" / 0.9 / *** EW +s33_rockGrainSize "grain size of ground rock, influences electricity demand and weathering rate. By default 20 micrometer based on Strefler et al. (2018) [micrometre]" /20/ s33_rockRemPot "specific carbon removal potential [t C / t rock]" s33_rock_weath_rate_ambientT "fraction of stone weathering per year at ambient temperature (25 degree C)" s33_step "size of bins in v33_weathering_onfield [Gt stone]" / 2.5 / @@ -40,7 +41,7 @@ p33_GDP_NetNeg_share(all_regi) "Upper bound on share of expen ; variables -vm_EW_transport_costs(tall,all_regi) "O&M costs for spreading grinded rocks on fields [T$]" +vm_EW_transport_costs(tall,all_regi) "O&M costs for transporting ground rocks from mines to fields [T$]" ; positive variables @@ -83,8 +84,8 @@ q33_DAC_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from D *** EW 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" -q33_EW_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from enhanced weathering" +q33_EW_transportCosts(ttot,all_regi) "calculates transport costs for transporting ground rocks from mines to fields" +q33_EW_FEdemand(ttot,all_regi,all_enty) "calculates final energy demand from enhanced weathering for grinding and spreading rocks on fields" 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_upscaling_rate(ttot, all_regi) "limits spreading of rock to a steep but credible upscaling rate" diff --git a/modules/33_carbonRemoval/portfolio/equations.gms b/modules/33_carbonRemoval/portfolio/equations.gms index c926a638f7..03b20c9d1c 100644 --- a/modules/33_carbonRemoval/portfolio/equations.gms +++ b/modules/33_carbonRemoval/portfolio/equations.gms @@ -160,7 +160,7 @@ q33_EW_emi(t,regi).. ***--------------------------------------------------------------------------- *' Calculation of FE demand for enhanced weathering, i.e., electricity demand for grinding, -*' and the diesel demand for transportation and spreading on crop fields. +*' and the diesel demand for spreading rocks on crop fields. ***--------------------------------------------------------------------------- q33_EW_FEdemand(t,regi,entyFe2)$sum(entyFe, fe2cdr(entyFe,entyFe2,"weathering")).. sum(fe2cdr(entyFe,entyFe2,"weathering"), v33_FEdemand(t,regi,entyFe,entyFe2,"weathering")) @@ -169,9 +169,9 @@ q33_EW_FEdemand(t,regi,entyFe2)$sum(entyFe, fe2cdr(entyFe,entyFe2,"weathering")) ; ***--------------------------------------------------------------------------- -*' O&M costs of EW, consisting of fix costs for mining, grinding and spreading, and transportation costs. +*' Transport cost for rocks from mine to field ***--------------------------------------------------------------------------- -q33_EW_omcosts(t,regi).. +q33_EW_transportCosts(t,regi).. vm_EW_transport_costs(t,regi) =e= sum((rlf_cz33, rlf), diff --git a/modules/33_carbonRemoval/portfolio/realization.gms b/modules/33_carbonRemoval/portfolio/realization.gms index 5c60d42e47..10d7b422b5 100644 --- a/modules/33_carbonRemoval/portfolio/realization.gms +++ b/modules/33_carbonRemoval/portfolio/realization.gms @@ -15,12 +15,15 @@ *' 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 +*' (EW) Basalt is mined and ground to fine grain sizes (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 +*' rocks and diesel is needed for spreading on crop fields. Transport costs from mine to fields depend on distance grades. +*' In addition, capital cost for mining and production, and O&M cost for mining and distribution on fields are added. +*' The amount of rock that can be spread on fields is limited by the maximum potential for enhanced weathering, +*' which depends on the region and climate grade. The weathering process leads to an exponential *' decay over time of the spread rocks. There is an upper limit on the amount of rock that can be on the fields, so that -*' in equilibrium only the part that decays in one timestep can be replaced in the next. Costs consist of costs for capital, O&M, -*' distribution and transport (grades depend on region specific transport distance from mine to fields). +*' in equilibrium only the part that decays in one timestep can be replaced in the next. The share of suitable fields that can be +*' used for spreading rocks can be adjusted via cm_33_EW_maxShareOfCropland. *' *' (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, @@ -34,6 +37,11 @@ *' material). *' *' Equations for each option determine the capacity, emissions, energy demand, costs and limits. + +*' (Overarching) This module further limits the amount of final energy that can be used for CDR technologies (via cm_33_maxFeShare), +*' and the share of GDP that can be spent on net negative emissions (via cm_33_GDP_netNegCDR_maxShare). It also contains +*' the biochar material value price assumption and revenue calculation. + ***---------------------------------------------------- *####################### R SECTION START (PHASES) ############################## diff --git a/standalone/MOFEX/MOFEX.gms b/standalone/MOFEX/MOFEX.gms index 2b7414b8c9..1dafff636d 100644 --- a/standalone/MOFEX/MOFEX.gms +++ b/standalone/MOFEX/MOFEX.gms @@ -169,7 +169,6 @@ c_ccscapratescen "CCS capture rate" c_export_tax_scen "choose which oil export tax is used in the model. 0 = none, 1 = fix" cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" -cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" @@ -298,7 +297,6 @@ c_export_tax_scen = 0; !! def = 0 cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 -cm_gs_ew = 20; !! def = 20 cm_33_EW_rockRemPot = 0.3; !! def = 0.3 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 diff --git a/standalone/template.gms b/standalone/template.gms index f0b001ea63..1eacd1380f 100644 --- a/standalone/template.gms +++ b/standalone/template.gms @@ -165,7 +165,6 @@ c_ccscapratescen "CCS capture rate" c_export_tax_scen "choose which oil export tax is used in the model. 0 = none, 1 = fix" cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" -cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" @@ -252,7 +251,6 @@ c_export_tax_scen = 0; !! def = 0 cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 -cm_gs_ew = 20; !! def = 20 cm_33_EW_rockRemPot = 0.3; !! def = 0.3 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 diff --git a/standalone/trade/trade.gms b/standalone/trade/trade.gms index 68a7580b20..c9d0c123e0 100644 --- a/standalone/trade/trade.gms +++ b/standalone/trade/trade.gms @@ -173,7 +173,6 @@ c_ccscapratescen "CCS capture rate" c_export_tax_scen "choose which oil export tax is used in the model. 0 = none, 1 = fix" cm_iterative_target_adj "whether or not a tax or a budget target should be iteratively adjusted depending on actual emission or forcing level" cm_gdximport_target "whether or not the starting value for iteratively adjusted budgets, tax scenarios, or forcing targets (emiscen 5,6,8,9) should be read in from the input.gdx" -cm_gs_ew "grain size (for enhanced weathering, CDR module) [micrometre]" cm_33_EW_rockRemPot "Maximum CO2 removal potential per ton of rock (t CO2 / t rock)." cm_expoLinear_yearStart "time at which carbon price increases linearly instead of exponentially" @@ -303,7 +302,6 @@ c_export_tax_scen = 0; !! def = 0 cm_iterative_target_adj = 0; !! def = 0 cm_gdximport_target = 0; !! def = 0 $setglobal c_SSP_forcing_adjust forcing_SSP2 !! def = forcing_SSP2 -cm_gs_ew = 20; !! def = 20 cm_33_EW_rockRemPot = 0.3; !! def = 0.3 cm_expoLinear_yearStart = 2050; !! def = 2050 c_budgetCO2FFI = 1000; !! def = 1000 diff --git a/tests/testthat/test_01-checkFixCfg.R b/tests/testthat/test_01-checkFixCfg.R index 3e3fc37cf2..c162e9a33d 100644 --- a/tests/testthat/test_01-checkFixCfg.R +++ b/tests/testthat/test_01-checkFixCfg.R @@ -13,7 +13,6 @@ test_that("checkFixCfg works", { "cm_NDC_version" = "2004_cond", "cm_emiscen" = "123", "cm_nash_autoconverge" = "NA", - "cm_gs_ew" = "2.2.2", "cm_taxCO2_expGrowth" = "333++", "c_macscen" = "-1", "cm_keep_presolve_gdxes" = "1.1", From b1c8868f2bc688f8db31d7c0617f62c8476ec38d Mon Sep 17 00:00:00 2001 From: tabeado Date: Thu, 6 Aug 2026 15:59:27 +0200 Subject: [PATCH 09/11] change cm_gs_ew to s33_rockGrainSize in datainput --- modules/33_carbonRemoval/portfolio/datainput.gms | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index 79b83f8994..bc1ec91824 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -44,8 +44,8 @@ s33_rockRemPot = cm_33_EW_rockRemPot / sm_c_2_co2; !! default for basalt i *' rock weathering rate (i.e. fraction of rock weathering per year) at ambient temperature (25 degree C), based on *' eq 2 in strefler, amann et al. (2018): *' wr = grain surface area based weathering rate (10^-10.53 mol m^-2 s^-1) * molar weight of basalt/forsterite (140.7 g/mol) -*' * 3.155^7 s/a * specific surface area(depending on grain size cm_gs_ew) -s33_rock_weath_rate_ambientT = 10**(-10.53) * 125 * 3.155*10**7 * 69.18*(cm_gs_ew**(-1.24)); +*' * 3.155^7 s/a * specific surface area(depending on grain size s33_rockGrainSize) +s33_rock_weath_rate_ambientT = 10**(-10.53) * 125 * 3.155*10**7 * 69.18*(s33_rockGrainSize**(-1.24)); *' rock weathering rate for different climate grades: SI Tab F-1 of strefler, amann et al. (2018) p33_rock_weath_rate("1") = s33_rock_weath_rate_ambientT * 0.94; p33_rock_weath_rate("2") = s33_rock_weath_rate_ambientT * 0.29; From 35fa982da4e017aeca0f6f11bf11ccf5978047cb Mon Sep 17 00:00:00 2001 From: tabeado Date: Thu, 6 Aug 2026 16:00:16 +0200 Subject: [PATCH 10/11] wording --- modules/33_carbonRemoval/portfolio/datainput.gms | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index bc1ec91824..cbd60af42a 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -18,14 +18,14 @@ p33_fedem("dac", "fehes") = 21.12; !! FE demand heat for material recovery *' #### EW input data *------------------------------------------------------------------------------------ *' @stop -table f33_maxProdGradeRegiWeathering(all_regi,rlf) "regional maximum potentials for enhanced weathering in Gt of grinded stone/a for different grades" +table f33_maxProdGradeRegiWeathering(all_regi,rlf) "regional maximum potentials for enhanced weathering in Gt of ground rock/a for different grades" $ondelim $include "./modules/33_carbonRemoval/portfolio/input/f33_maxProdGradeRegiWeathering.cs3r" $offdelim ; display f33_maxProdGradeRegiWeathering; -parameter p33_EW_transport_costs(all_regi,rlf,rlf) "transport costs [T$/Gt stone]" +parameter p33_EW_transport_costs(all_regi,rlf,rlf) "transport costs [T$/Gt rock]" / $ondelim $include "./modules/33_carbonRemoval/portfolio/input/p33_transportCostsWeathering.cs4r" From 4301cb81479a17e7a8299cfe3a202a436f994d3c Mon Sep 17 00:00:00 2001 From: tabeado Date: Thu, 6 Aug 2026 16:32:40 +0200 Subject: [PATCH 11/11] s33_step adjustments --- modules/33_carbonRemoval/portfolio/datainput.gms | 2 -- modules/33_carbonRemoval/portfolio/declarations.gms | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/33_carbonRemoval/portfolio/datainput.gms b/modules/33_carbonRemoval/portfolio/datainput.gms index cbd60af42a..f1347e5ee8 100644 --- a/modules/33_carbonRemoval/portfolio/datainput.gms +++ b/modules/33_carbonRemoval/portfolio/datainput.gms @@ -34,8 +34,6 @@ $offdelim ; display p33_EW_transport_costs; -s33_step = 2.5; - *' @code s33_rockRemPot = cm_33_EW_rockRemPot / sm_c_2_co2; !! default for basalt is 0.3 t CO2/t rock, for Olivine 1.1 t CO2/t rock. Converted to t C/t rock. *' Sources for loss pathways that would reduce the total removal potential per ton rock: diff --git a/modules/33_carbonRemoval/portfolio/declarations.gms b/modules/33_carbonRemoval/portfolio/declarations.gms index 9934a4ed86..22bd351517 100644 --- a/modules/33_carbonRemoval/portfolio/declarations.gms +++ b/modules/33_carbonRemoval/portfolio/declarations.gms @@ -12,7 +12,7 @@ sm_capture_rate_cdrmodule "CO2 capture rate for CDR energy and process emi s33_rockGrainSize "grain size of ground rock, influences electricity demand and weathering rate. By default 20 micrometer based on Strefler et al. (2018) [micrometre]" /20/ s33_rockRemPot "specific carbon removal potential [t C / t rock]" s33_rock_weath_rate_ambientT "fraction of stone weathering per year at ambient temperature (25 degree C)" -s33_step "size of bins in v33_weathering_onfield [Gt stone]" / 2.5 / +s33_step "size of bins in v33_EW_onfield_tot [Gt rock]" / 2.5 / *JeS* GJ/tCO2 = EJ/Gt CO2 = 44/12 EJ/Gt C. *** OAE s33_OAE_efficiency "the amount of rock required to sequester 1GtC [Gt rock / GtC]"