From da855852233f28cd80015ced162bea954e9e3668 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Fri, 28 Jul 2023 14:41:39 +0200 Subject: [PATCH 01/29] Add new variables and equations for cumulative LU emis accounting --- message_ix/model/MESSAGE/data_load.gms | 7 +++++ message_ix/model/MESSAGE/model_core.gms | 32 ++++++++++++++++++++-- message_ix/model/MESSAGE/sets_maps_def.gms | 2 ++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index 1f094303b..cd672c266 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -81,6 +81,13 @@ fixed_extraction, fixed_stock, fixed_new_capacity, fixed_capacity, fixed_activit storage_initial, storage_self_discharge, time_order ; +emission_cumulative(emission) = no; +emission_cumulative('TCE_CO2') = yes; +emission_cumulative('LU_CO2') = yes; +emission_cumulative('TCE') = yes; +emission_annual(emission) = yes; +emission_annual(emission_cumulative) = no; + *----------------------------------------------------------------------------------------------------------------------* * ensure that each node is mapped to itself * diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 8fcb836e6..42d116762 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -120,6 +120,8 @@ Variables COST_NODAL(node, year_all) system costs at the node level over time * auxiliary variable for aggregate emissions by technology type and land-use model emulator EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator +* auxiliary variable for aggregate emissions from land-use model emulator + EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device @@ -280,6 +282,8 @@ Equations ACTIVITY_CONSTRAINT_LO dynamic constraint on the market penetration of a technology activity (lower bound) ACTIVITY_SOFT_CONSTRAINT_LO bound on relaxation of the dynamic constraint on market penetration (lower bound) EMISSION_EQUIVALENCE auxiliary equation to simplify the notation of emissions + EMISSION_EQUIVALENCE_AUX_ANNUAL auxiliary equation calculating land-use emissions from annual scenario input + EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) @@ -1849,10 +1853,34 @@ EMISSION_EQUIVALENCE(node,emission,type_tec,year).. AND map_tec_act(location,tec,year,mode,time) AND map_tec_lifetime(location,tec,vintage,year) ), emission_factor(location,tec,vintage,year,mode,emission) * ACT(location,tec,vintage,year,mode,time) ) * emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' - + SUM(land_scenario$( type_tec_land(type_tec) ), - land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) +* + SUM(land_scenario $( type_tec_land(type_tec) ) , +* land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) + + EMISS_LU(location,emission,type_tec,year) $( type_tec_land(type_tec) ) ) ; +EMISSION_EQUIVALENCE_AUX_ANNUAL(location,emission,type_tec,year) $ emission_annual(emission).. + EMISS_LU(location,emission,type_tec,year) + =E= +* emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' + SUM(land_scenario , + land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) + ) ; + + +EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumulative(emission).. + EMISS_LU(location,emission,type_tec,year) + =E= +* emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' + ( SUM(land_scenario, + SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario, year2, emission) * duration_period(year2) ) * + LAND(location, land_scenario, year) + ) - + SUM(year2 $( year2.pos < year.pos ), + EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) + ) ) / + duration_period(year) ; + + *** * Bound on emissions * ^^^^^^^^^^^^^^^^^^ diff --git a/message_ix/model/MESSAGE/sets_maps_def.gms b/message_ix/model/MESSAGE/sets_maps_def.gms index 479da3298..6a31f1322 100644 --- a/message_ix/model/MESSAGE/sets_maps_def.gms +++ b/message_ix/model/MESSAGE/sets_maps_def.gms @@ -148,6 +148,8 @@ Sets tec technologies mode modes of operation emission greenhouse gases - pollutants - etc. + emission_annual (emission) greenhouse gases - pollutants - etc. from annual inputs + emission_cumulative (emission) greenhouse gases - pollutants - etc. from cumulative inputs land_scenario scenarios of land use (for land-use model emulator) land_type types of land use year_all years (over entire model horizon) From 440a610d32699d775bbfc724a952ec18bc852cb1 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Sep 2023 16:31:56 +0200 Subject: [PATCH 02/29] Add Tau Constraint --- message_ix/model/MESSAGE/model_core.gms | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 42d116762..59a21011b 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -290,6 +290,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) + TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -2101,6 +2102,20 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; + +TAU_CONSTRAINT(node, year, level, time) .. + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) + * LAND(node, land_scenario, year) + ) =G= + SUM((year_all2)$( seq_period(year_all2,year) ), + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) + * LAND(node, land_scenario, year_all2) + ) + ) +; + *----------------------------------------------------------------------------------------------------------------------* *** * .. _section_of_generic_relations: From 48d3a19c71433159a2699e1ae74535f9e0110e05 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Tue, 19 Sep 2023 11:43:05 +0200 Subject: [PATCH 03/29] Temporarily remove Tau constraint --- message_ix/model/MESSAGE/model_core.gms | 29 +++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 59a21011b..80bcdfa8d 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -290,7 +290,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) - TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) +* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -2084,7 +2084,7 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y land_use(node,land_scenario,year,land_type) * LAND(node,land_scenario,year) ) =G= * initial 'new' land used for that type (compounded over the duration of the period) - initial_land_lo(node,year,land_type) * ( - ( ( POWER( 1 + growth_land_up(node,year,land_type) , duration_period(year) ) - 1 ) + ( ( POWER( 1 + growth_land_lo(node,year,land_type) , duration_period(year) ) - 1 ) / growth_land_lo(node,year,land_type) )$( growth_land_lo(node,year,land_type) ) + ( duration_period(year) )$( NOT growth_land_lo(node,year,land_type) ) ) @@ -2103,18 +2103,19 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y ; -TAU_CONSTRAINT(node, year, level, time) .. - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) - * LAND(node, land_scenario, year) - ) =G= - SUM((year_all2)$( seq_period(year_all2,year) ), - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) - * LAND(node, land_scenario, year_all2) - ) - ) -; +*TAU_CONSTRAINT(node, year, level, time) .. +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) +* * LAND(node, land_scenario, year) +* ) =G= +* SUM((year_all2)$( seq_period(year_all2,year) ), +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) +* * LAND(node, land_scenario, year_all2) +* ) +* ) +*; + *----------------------------------------------------------------------------------------------------------------------* *** From 4ec2f0deaf0e1d7695f5983cc86e9a0850544a73 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 20 Sep 2023 13:02:28 +0200 Subject: [PATCH 04/29] Re-activate the Tau constraint --- message_ix/model/MESSAGE/model_core.gms | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 80bcdfa8d..acf59ee09 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -290,7 +290,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) -* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) + TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -2103,18 +2103,18 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y ; -*TAU_CONSTRAINT(node, year, level, time) .. -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) -* * LAND(node, land_scenario, year) -* ) =G= -* SUM((year_all2)$( seq_period(year_all2,year) ), -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) -* * LAND(node, land_scenario, year_all2) -* ) -* ) -*; +TAU_CONSTRAINT(node, year, level, time) .. + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) + * LAND(node, land_scenario, year) + ) =G= + SUM((year_all2)$( seq_period(year_all2,year) ), + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) + * LAND(node, land_scenario, year_all2) + ) + ) +; *----------------------------------------------------------------------------------------------------------------------* From 7bac2183c0b1e40381b1c87b759121b6c4925700 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 20 Sep 2023 13:07:08 +0200 Subject: [PATCH 05/29] Add primary forest growth constraint --- message_ix/model/MESSAGE/model_core.gms | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index acf59ee09..5669ca793 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -290,6 +290,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) + PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) @@ -2102,6 +2103,19 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; +PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) + * LAND(node, land_scenario, year) + ) =L= + SUM((year_all2)$( seq_period(year_all2,year) ), + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) + * LAND(node, land_scenario, year_all2) + ) + ) +; + TAU_CONSTRAINT(node, year, level, time) .. SUM(land_scenario$( map_land(node,land_scenario,year) ), From f04856b84191aa457d51d09719b5d37cedfd6516 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 20 Sep 2023 13:34:56 +0200 Subject: [PATCH 06/29] Remove LAND > 1 bug for historic time steps --- message_ix/model/MESSAGE/model_core.gms | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 5669ca793..a739e5247 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -2111,7 +2111,8 @@ PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. SUM((year_all2)$( seq_period(year_all2,year) ), SUM(land_scenario$( map_land(node,land_scenario,year) ), land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) - * LAND(node, land_scenario, year_all2) + * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) + + historical_land(node,land_scenario,year_all2) ) ) ) ; @@ -2125,7 +2126,8 @@ TAU_CONSTRAINT(node, year, level, time) .. SUM((year_all2)$( seq_period(year_all2,year) ), SUM(land_scenario$( map_land(node,land_scenario,year) ), land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) - * LAND(node, land_scenario, year_all2) + * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) + + historical_land(node,land_scenario,year_all2) ) ) ) ; From 6bed36e96a208b657eb52f3c3c6c5628ec8c0994 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Fri, 29 Sep 2023 09:52:32 +0200 Subject: [PATCH 07/29] Replace static land_cost with dynamic variable based on cumulative emiss --- message_ix/model/MESSAGE/data_load.gms | 41 +++++++ message_ix/model/MESSAGE/model_core.gms | 126 ++++++++++++++++++--- message_ix/model/MESSAGE/sets_maps_def.gms | 5 + 3 files changed, 156 insertions(+), 16 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index cd672c266..637a58b40 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -88,6 +88,47 @@ emission_cumulative('TCE') = yes; emission_annual(emission) = yes; emission_annual(emission_cumulative) = no; +sets +land_scenario_bio +/ BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / + +land_scenario_ghg_zero(land_scenario) +/ BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / + +map_scenario_bio(land_scenario_bio,land_scenario) +/ BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) + BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) + BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) + BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) + BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) + BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) + BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +/ + +map_bio_ghg_zero(land_scenario_bio,land_scenario) +/ BIO00 . BIO00GHG000 + BIO05 . BIO05GHG000 + BIO07 . BIO07GHG000 + BIO10 . BIO10GHG000 + BIO15 . BIO15GHG000 + BIO25 . BIO25GHG000 + BIO45 . BIO45GHG000 +/ + +map_scenario_zero(land_scenario_ghg_zero,land_scenario) +/ BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) + BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) + BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) + BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) + BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) + BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) + BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +/ + + +; + + *----------------------------------------------------------------------------------------------------------------------* * ensure that each node is mapped to itself * diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index a739e5247..8505b4b4e 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -105,10 +105,17 @@ Positive Variables ACT_LO(node,tec,year_all,time) relaxation variable for dynamic constraints on activity (downwards) * land-use model emulator LAND(node,land_scenario,year_all) relative share of land-use scenario + LAND_BIO(node,land_scenario_bio,year_all) relative share of biomass land-use scenario + LAND_GHG_ZERO(node, land_scenario_ghg_zero, year_all) relative share of G000 land-use scenarios * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) + + LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator ; + + + Variables * intertemporal stock variables (input or output quantity into the stock) STOCK_CHG(node,commodity,level,year_all,time) annual input into and output from stocks of commodities @@ -122,12 +129,21 @@ Variables EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator * auxiliary variable for aggregate emissions from land-use model emulator EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator + EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline + LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation + LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation + LAND_COST_BIO(node,year_all) Land scenario price component from biomass + LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device STORAGE_CHARGE(node,tec,mode,level,commodity,year_all,time) charging of storage in each time slice (negative for discharge) ; + + + + *** * .. _section_auxiliary_variable_def: * @@ -284,13 +300,21 @@ Equations EMISSION_EQUIVALENCE auxiliary equation to simplify the notation of emissions EMISSION_EQUIVALENCE_AUX_ANNUAL auxiliary equation calculating land-use emissions from annual scenario input EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input + EMISSION_EQUIVALENCE_AUX_ZERO auxiliary equation calculating the land-use emissions baseline from cumulative scenario input EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) + LAND_CHECK_EMISS fill LU_GHG check variable + LAND_CHECK_EMISS_ZERO fill LU_GHG check variable for emissions baseline + LAND_COST_CUMU dynamic land-cost calculation + LAND_COST_CUMU_BIO dynamic land-cost calculation helper for BIO price + LAND_COST_CUMU_GHG dynamic land-cost calculation helper for GHG price LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) + LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario + LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) - PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) +* PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) @@ -417,8 +441,9 @@ COST_ACCOUNTING_NODAL(node, year).. * tax_emission(node,type_emission,type_tec,type_year) * EMISS(node,emission,type_tec,year) ) * cost terms from land-use model emulator (only includes valid node-land_scenario-year combinations) - + SUM(land_scenario$( land_cost(node,land_scenario,year) ), - land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) +* + SUM(land_scenario$( land_cost(node,land_scenario,year) ), +* land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) + + LAND_COST_DYN(node,year) * cost terms associated with linear relations + SUM(relation$( relation_cost(relation,node,year) ), relation_cost(relation,node,year) * REL(relation,node,year) ) @@ -1883,6 +1908,67 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula duration_period(year) ; +EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. + EMISS_LU_ZERO(location,emission,type_tec,year) =E= + ( SUM(land_scenario_ghg_zero, + SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * + LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) + ) - + SUM(year2 $( year2.pos < year.pos ), + EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) + ) ) / + duration_period(year) ; + + +LAND_COST_CUMU(location, year)$( model_horizon(year) ).. + LAND_COST_DYN(location,year) =E= + LAND_COST_BIO(location,year) + + LAND_COST_GHG(location,year) ; + +LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. + LAND_COST_BIO(location,year) =E= + SUM(land_scenario$( map_land(location,land_scenario,year) ), + land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 + * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") + * LAND(location,land_scenario,year) ) ; + +LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. + LAND_COST_GHG(location,year) =E= + ( SUM(land_scenario$( map_land(location,land_scenario,year) ), + (LAND(location, land_scenario, year) + * ( SUM(year2 $ ( year2.pos <= year.pos ), + SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") + * duration_period(year2) ) + - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) + * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) + - SUM(year2 $ ( year2.pos < year.pos ), + LAND_COST_GHG(location, year2) * duration_period(year2) ) ) + / duration_period(year) + ; + +LAND_CHECK_EMISS_ZERO(location, year).. + LU_GHG_Base(location, year) =E= + SUM(land_scenario$( map_land(location,land_scenario,year) ), + LAND(location, land_scenario, year) + * SUM(year2 $ ( year2.pos <= year.pos ), + SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") + * duration_period(year2) ) ) ) ; + +LAND_CHECK_EMISS(location, year).. + LU_GHG(location, year) =E= + SUM(land_scenario$( map_land(location,land_scenario,year) ), + LAND(location, land_scenario, year) + * SUM(year2 $ ( year2.pos <= year.pos ), + land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; + + +* + (EMISS_LU_ZERO(location,"TCE","all",year) - EMISS_LU(location,"TCE","all",year)) * 44 / 12 +* * SUM(land_scenario$( map_land(location,land_scenario,year) ), +* LAND(location,land_scenario,year) +* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") +* ) ; + + *** * Bound on emissions * ^^^^^^^^^^^^^^^^^^ @@ -1944,6 +2030,14 @@ EMISSION_CONSTRAINT(node,type_emission,type_tec,type_year)$is_bound_emission(nod LAND_CONSTRAINT(node,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. SUM(land_scenario$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year) ) =E= 1 ; + +LAND_FILL_BIO(node,land_scenario_bio,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. + LAND_BIO(node,land_scenario_bio,year) =E= + SUM(map_scenario_bio(land_scenario_bio,land_scenario)$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year)); + +LAND_FILL_GHG_ZERO(node,land_scenario_ghg_zero,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. + LAND_GHG_ZERO(node, land_scenario_ghg_zero, year) =E= + SUM(map_bio_ghg_zero(land_scenario_bio,land_scenario_ghg_zero), LAND_BIO(node,land_scenario_bio,year) ); *** * Dynamic constraints on land use * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -2103,19 +2197,19 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; -PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) - * LAND(node, land_scenario, year) - ) =L= - SUM((year_all2)$( seq_period(year_all2,year) ), - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) - * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) - + historical_land(node,land_scenario,year_all2) ) - ) - ) -; +*PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) +* * LAND(node, land_scenario, year) +* ) =L= +* SUM((year_all2)$( seq_period(year_all2,year) ), +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) +* * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) +* + historical_land(node,land_scenario,year_all2) ) +* ) +* ) +*; TAU_CONSTRAINT(node, year, level, time) .. diff --git a/message_ix/model/MESSAGE/sets_maps_def.gms b/message_ix/model/MESSAGE/sets_maps_def.gms index 6a31f1322..bc7299797 100644 --- a/message_ix/model/MESSAGE/sets_maps_def.gms +++ b/message_ix/model/MESSAGE/sets_maps_def.gms @@ -151,6 +151,8 @@ Sets emission_annual (emission) greenhouse gases - pollutants - etc. from annual inputs emission_cumulative (emission) greenhouse gases - pollutants - etc. from cumulative inputs land_scenario scenarios of land use (for land-use model emulator) +* land_scenario_bio biomass scenarios of land use (for land-use emulator) + land_scenario_ghg emission scenarios of land use (for land-use emulator) land_type types of land use year_all years (over entire model horizon) year (year_all) years included in a model instance (for myopic or rolling-horizon optimization) @@ -400,6 +402,9 @@ Sets map_land(node,land_scenario,year_all) mapping of land-use model emulator scenarios to nodes and years map_relation(relation,node,year_all) mapping of generic (user-defined) relations to nodes and years +* map_scenario_bio(land_scenario_bio,land_scenario) mapping of land-use model emulator scenarios to biomass scenarios + map_scenario_ghg(land_scenario_ghg,land_scenario) mapping of land-use model emulator scenarios to emission scenarios + * Storage map_time_commodity_storage(node,tec,level,commodity,mode,year_all,time) mapping of storage containers to their input commodity-level (not commodity-level of stored media) ; From 810244b4457652a2f50002aa5a53a9f65325b8d4 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 2 Oct 2023 18:28:57 +0200 Subject: [PATCH 08/29] Limit cumulative accounting to net-positive emissions Also, remove cumulative cost accounting --- message_ix/model/MESSAGE/model_core.gms | 177 +++++++++++++----------- 1 file changed, 97 insertions(+), 80 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 8505b4b4e..106fc89a5 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -105,17 +105,16 @@ Positive Variables ACT_LO(node,tec,year_all,time) relaxation variable for dynamic constraints on activity (downwards) * land-use model emulator LAND(node,land_scenario,year_all) relative share of land-use scenario - LAND_BIO(node,land_scenario_bio,year_all) relative share of biomass land-use scenario - LAND_GHG_ZERO(node, land_scenario_ghg_zero, year_all) relative share of G000 land-use scenarios +* LAND_BIO(node,land_scenario_bio,year_all) relative share of biomass land-use scenario +* LAND_GHG_ZERO(node, land_scenario_ghg_zero, year_all) relative share of G000 land-use scenarios * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) - LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator + LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator + EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; - - Variables * intertemporal stock variables (input or output quantity into the stock) STOCK_CHG(node,commodity,level,year_all,time) annual input into and output from stocks of commodities @@ -129,11 +128,11 @@ Variables EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator * auxiliary variable for aggregate emissions from land-use model emulator EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator - EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline - LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation - LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation - LAND_COST_BIO(node,year_all) Land scenario price component from biomass - LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions +* EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline +* LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation +* LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation +* LAND_COST_BIO(node,year_all) Land scenario price component from biomass +* LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device @@ -300,16 +299,17 @@ Equations EMISSION_EQUIVALENCE auxiliary equation to simplify the notation of emissions EMISSION_EQUIVALENCE_AUX_ANNUAL auxiliary equation calculating land-use emissions from annual scenario input EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input - EMISSION_EQUIVALENCE_AUX_ZERO auxiliary equation calculating the land-use emissions baseline from cumulative scenario input +* EMISSION_EQUIVALENCE_AUX_ZERO auxiliary equation calculating the land-use emissions baseline from cumulative scenario input + EMISSION_EQUIVALENCE_AUX_CUMU_AUX auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) - LAND_CHECK_EMISS fill LU_GHG check variable - LAND_CHECK_EMISS_ZERO fill LU_GHG check variable for emissions baseline - LAND_COST_CUMU dynamic land-cost calculation - LAND_COST_CUMU_BIO dynamic land-cost calculation helper for BIO price - LAND_COST_CUMU_GHG dynamic land-cost calculation helper for GHG price +* LAND_CHECK_EMISS fill LU_GHG check variable +* LAND_CHECK_EMISS_ZERO fill LU_GHG check variable for emissions baseline +* LAND_COST_CUMU dynamic land-cost calculation +* LAND_COST_CUMU_BIO dynamic land-cost calculation helper for BIO price +* LAND_COST_CUMU_GHG dynamic land-cost calculation helper for GHG price LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) - LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario - LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario +* LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario +* LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) @@ -441,9 +441,9 @@ COST_ACCOUNTING_NODAL(node, year).. * tax_emission(node,type_emission,type_tec,type_year) * EMISS(node,emission,type_tec,year) ) * cost terms from land-use model emulator (only includes valid node-land_scenario-year combinations) -* + SUM(land_scenario$( land_cost(node,land_scenario,year) ), -* land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) - + LAND_COST_DYN(node,year) + + SUM(land_scenario$( land_cost(node,land_scenario,year) ), + land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) +* + LAND_COST_DYN(node,year) * cost terms associated with linear relations + SUM(relation$( relation_cost(relation,node,year) ), relation_cost(relation,node,year) * REL(relation,node,year) ) @@ -1897,9 +1897,26 @@ EMISSION_EQUIVALENCE_AUX_ANNUAL(location,emission,type_tec,year) $ emission_annu EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumulative(emission).. EMISS_LU(location,emission,type_tec,year) =E= + SUM(land_scenario , + land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) + + EMISS_LU_AUX(location,emission,type_tec,year) ; + * emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' +* ( SUM(land_scenario, +* SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario, year2, emission) * duration_period(year2) ) * +* LAND(location, land_scenario, year) +* ) - +* SUM(year2 $( year2.pos < year.pos ), +* EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) +* ) ) / +* duration_period(year) ; + +* find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps +EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year) $ emission_cumulative(emission).. + EMISS_LU_AUX(location,emission,type_tec,year) + =G= ( SUM(land_scenario, - SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario, year2, emission) * duration_period(year2) ) * + SUM(year2 $ ( year2.pos < year.pos ), land_emission(location, land_scenario, year2, emission) * duration_period(year2) ) * LAND(location, land_scenario, year) ) - SUM(year2 $( year2.pos < year.pos ), @@ -1908,58 +1925,58 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula duration_period(year) ; -EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. - EMISS_LU_ZERO(location,emission,type_tec,year) =E= - ( SUM(land_scenario_ghg_zero, - SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * - LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) - ) - - SUM(year2 $( year2.pos < year.pos ), - EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) - ) ) / - duration_period(year) ; - - -LAND_COST_CUMU(location, year)$( model_horizon(year) ).. - LAND_COST_DYN(location,year) =E= - LAND_COST_BIO(location,year) - + LAND_COST_GHG(location,year) ; - -LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. - LAND_COST_BIO(location,year) =E= - SUM(land_scenario$( map_land(location,land_scenario,year) ), - land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 - * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") - * LAND(location,land_scenario,year) ) ; - -LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. - LAND_COST_GHG(location,year) =E= - ( SUM(land_scenario$( map_land(location,land_scenario,year) ), - (LAND(location, land_scenario, year) - * ( SUM(year2 $ ( year2.pos <= year.pos ), - SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") - * duration_period(year2) ) - - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) - * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) - - SUM(year2 $ ( year2.pos < year.pos ), - LAND_COST_GHG(location, year2) * duration_period(year2) ) ) - / duration_period(year) - ; - -LAND_CHECK_EMISS_ZERO(location, year).. - LU_GHG_Base(location, year) =E= - SUM(land_scenario$( map_land(location,land_scenario,year) ), - LAND(location, land_scenario, year) - * SUM(year2 $ ( year2.pos <= year.pos ), - SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") - * duration_period(year2) ) ) ) ; - -LAND_CHECK_EMISS(location, year).. - LU_GHG(location, year) =E= - SUM(land_scenario$( map_land(location,land_scenario,year) ), - LAND(location, land_scenario, year) - * SUM(year2 $ ( year2.pos <= year.pos ), - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; +* EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. +* EMISS_LU_ZERO(location,emission,type_tec,year) =E= +* ( SUM(land_scenario_ghg_zero, +* SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * +* LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) +* ) - +* SUM(year2 $( year2.pos < year.pos ), +* EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) +* ) ) / +* duration_period(year) ; + + +* LAND_COST_CUMU(location, year)$( model_horizon(year) ).. +* LAND_COST_DYN(location,year) =E= +* LAND_COST_BIO(location,year) +* + LAND_COST_GHG(location,year) ; + +* LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. +* LAND_COST_BIO(location,year) =E= +* SUM(land_scenario$( map_land(location,land_scenario,year) ), +* land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 +* * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") +* * LAND(location,land_scenario,year) ) ; + +* LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. +* LAND_COST_GHG(location,year) =E= +* ( SUM(land_scenario$( map_land(location,land_scenario,year) ), +* (LAND(location, land_scenario, year) +* * ( SUM(year2 $ ( year2.pos <= year.pos ), +* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") +* * duration_period(year2) ) +* - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) +* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) +* - SUM(year2 $ ( year2.pos < year.pos ), +* LAND_COST_GHG(location, year2) * duration_period(year2) ) ) +* / duration_period(year) +* ; + +* LAND_CHECK_EMISS_ZERO(location, year).. +* LU_GHG_Base(location, year) =E= +* SUM(land_scenario$( map_land(location,land_scenario,year) ), +* LAND(location, land_scenario, year) +* * SUM(year2 $ ( year2.pos <= year.pos ), +* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") +* * duration_period(year2) ) ) ) ; + +* LAND_CHECK_EMISS(location, year).. +* LU_GHG(location, year) =E= +* SUM(land_scenario$( map_land(location,land_scenario,year) ), +* LAND(location, land_scenario, year) +* * SUM(year2 $ ( year2.pos <= year.pos ), +* land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; * + (EMISS_LU_ZERO(location,"TCE","all",year) - EMISS_LU(location,"TCE","all",year)) * 44 / 12 @@ -2031,13 +2048,13 @@ LAND_CONSTRAINT(node,year)$( SUM(land_scenario$( map_land(node,land_scenario,yea SUM(land_scenario$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year) ) =E= 1 ; -LAND_FILL_BIO(node,land_scenario_bio,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. - LAND_BIO(node,land_scenario_bio,year) =E= - SUM(map_scenario_bio(land_scenario_bio,land_scenario)$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year)); +* LAND_FILL_BIO(node,land_scenario_bio,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. +* LAND_BIO(node,land_scenario_bio,year) =E= +* SUM(map_scenario_bio(land_scenario_bio,land_scenario)$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year)); -LAND_FILL_GHG_ZERO(node,land_scenario_ghg_zero,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. - LAND_GHG_ZERO(node, land_scenario_ghg_zero, year) =E= - SUM(map_bio_ghg_zero(land_scenario_bio,land_scenario_ghg_zero), LAND_BIO(node,land_scenario_bio,year) ); +* LAND_FILL_GHG_ZERO(node,land_scenario_ghg_zero,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. +* LAND_GHG_ZERO(node, land_scenario_ghg_zero, year) =E= +* SUM(map_bio_ghg_zero(land_scenario_bio,land_scenario_ghg_zero), LAND_BIO(node,land_scenario_bio,year) ); *** * Dynamic constraints on land use * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 81d56e8dacffa3f4ea818a3316da103dd8924916 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 9 Oct 2023 16:31:52 +0200 Subject: [PATCH 09/29] Implement cumulative LU cost accounting (positive only) --- message_ix/model/MESSAGE/model_core.gms | 37 +++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 106fc89a5..868e1c097 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -110,11 +110,16 @@ Positive Variables * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) - LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator +* LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator + LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching + LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; + + + Variables * intertemporal stock variables (input or output quantity into the stock) STOCK_CHG(node,commodity,level,year_all,time) annual input into and output from stocks of commodities @@ -307,6 +312,8 @@ Equations * LAND_COST_CUMU dynamic land-cost calculation * LAND_COST_CUMU_BIO dynamic land-cost calculation helper for BIO price * LAND_COST_CUMU_GHG dynamic land-cost calculation helper for GHG price + LAND_COST_CUMU land cost including debt from scenario switching + LAND_COST_CUMU_AUX land cost debt from scenario switching LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) * LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario * LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario @@ -441,9 +448,10 @@ COST_ACCOUNTING_NODAL(node, year).. * tax_emission(node,type_emission,type_tec,type_year) * EMISS(node,emission,type_tec,year) ) * cost terms from land-use model emulator (only includes valid node-land_scenario-year combinations) - + SUM(land_scenario$( land_cost(node,land_scenario,year) ), - land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) -* + LAND_COST_DYN(node,year) +* + SUM(land_scenario$( land_cost(node,land_scenario,year) ), +* land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) +* + LAND_COST_DYN(node,year) + + LAND_COST_NEW(node, year) * cost terms associated with linear relations + SUM(relation$( relation_cost(relation,node,year) ), relation_cost(relation,node,year) * REL(relation,node,year) ) @@ -1882,7 +1890,7 @@ EMISSION_EQUIVALENCE(node,emission,type_tec,year).. * emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' * + SUM(land_scenario $( type_tec_land(type_tec) ) , * land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) - + EMISS_LU(location,emission,type_tec,year) $( type_tec_land(type_tec) ) + + EMISS_LU(location,emission,type_tec,year) $ ( type_tec_land(type_tec) ) ) ; EMISSION_EQUIVALENCE_AUX_ANNUAL(location,emission,type_tec,year) $ emission_annual(emission).. @@ -1936,6 +1944,25 @@ EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year) $ emission_cu * ) ) / * duration_period(year) ; +LAND_COST_CUMU(location, year)$( model_horizon(year) ).. + LAND_COST_NEW(location, year) =E= + SUM(land_scenario$( land_cost(location,land_scenario,year) ), + land_cost(location,land_scenario,year) * LAND(location,land_scenario,year) ) + + SUM(year2, + LAND_COST_DEBT(location, year, year2) + * df_period(year2) / df_period(year) + ) ; + +LAND_COST_CUMU_AUX(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. + LAND_COST_DEBT(location, year, year2) $ ( year2.pos < year.pos ) =G= + SUM(land_scenario$( land_cost(location,land_scenario,year) ), + LAND(location, land_scenario, year) * land_cost(location,land_scenario,year2) + - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) + - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; + +* LAND_COST_DEBT.UP(location, year, year2) = 0; +* LAND_COST_DEBT.UP(location, year, year2)$( year2.pos < year.pos ) = INF; + * LAND_COST_CUMU(location, year)$( model_horizon(year) ).. * LAND_COST_DYN(location,year) =E= From 17b4c6cf9dc4d468c8b0247de0c69dfabdaff18c Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 6 Dec 2023 12:39:45 +0100 Subject: [PATCH 10/29] Simplify cumulative LU changes --- message_ix/model/MESSAGE/data_load.gms | 75 ++++++++++++------------- message_ix/model/MESSAGE/model_core.gms | 22 ++++++-- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index 637a58b40..46ee38c74 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -88,45 +88,42 @@ emission_cumulative('TCE') = yes; emission_annual(emission) = yes; emission_annual(emission_cumulative) = no; -sets -land_scenario_bio -/ BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / - -land_scenario_ghg_zero(land_scenario) -/ BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / - -map_scenario_bio(land_scenario_bio,land_scenario) -/ BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) - BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) - BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) - BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) - BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) - BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) - BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -/ - -map_bio_ghg_zero(land_scenario_bio,land_scenario) -/ BIO00 . BIO00GHG000 - BIO05 . BIO05GHG000 - BIO07 . BIO07GHG000 - BIO10 . BIO10GHG000 - BIO15 . BIO15GHG000 - BIO25 . BIO25GHG000 - BIO45 . BIO45GHG000 -/ - -map_scenario_zero(land_scenario_ghg_zero,land_scenario) -/ BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) - BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) - BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) - BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) - BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) - BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) - BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -/ - - -; +* sets +* land_scenario_bio +* / BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / + +* land_scenario_ghg_zero(land_scenario) +* / BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / + +* map_scenario_bio(land_scenario_bio,land_scenario) +* / BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) +* BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) +* BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) +* BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) +* BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) +* BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) +* BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +* / + +* map_bio_ghg_zero(land_scenario_bio,land_scenario) +* / BIO00 . BIO00GHG000 +* BIO05 . BIO05GHG000 +* BIO07 . BIO07GHG000 +* BIO10 . BIO10GHG000 +* BIO15 . BIO15GHG000 +* BIO25 . BIO25GHG000 +* BIO45 . BIO45GHG000 +* / + +* map_scenario_zero(land_scenario_ghg_zero,land_scenario) +* / BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) +* BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) +* BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) +* BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) +* BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) +* BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) +* BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +* / ; diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 868e1c097..32de47dad 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -114,6 +114,7 @@ Positive Variables LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix + EMISS_LU_AUX2(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; @@ -306,6 +307,7 @@ Equations EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input * EMISSION_EQUIVALENCE_AUX_ZERO auxiliary equation calculating the land-use emissions baseline from cumulative scenario input EMISSION_EQUIVALENCE_AUX_CUMU_AUX auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix + EMISSION_EQUIVALENCE_AUX_CUMU_AUX2 auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) * LAND_CHECK_EMISS fill LU_GHG check variable * LAND_CHECK_EMISS_ZERO fill LU_GHG check variable for emissions baseline @@ -313,7 +315,7 @@ Equations * LAND_COST_CUMU_BIO dynamic land-cost calculation helper for BIO price * LAND_COST_CUMU_GHG dynamic land-cost calculation helper for GHG price LAND_COST_CUMU land cost including debt from scenario switching - LAND_COST_CUMU_AUX land cost debt from scenario switching + LAND_COST_CUMU_DEBT land cost debt from scenario switching LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) * LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario * LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario @@ -1907,7 +1909,9 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula =E= SUM(land_scenario , land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) - + EMISS_LU_AUX(location,emission,type_tec,year) ; +* + EMISS_LU_AUX(location,emission,type_tec,year) + + SUM(year2, EMISS_LU_AUX2(location,emission,type_tec,year, year2) ) + ; * emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' * ( SUM(land_scenario, @@ -1933,6 +1937,15 @@ EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year) $ emission_cu duration_period(year) ; +EMISSION_EQUIVALENCE_AUX_CUMU_AUX2(location,emission,type_tec,year,year2) $ (emission_cumulative(emission) AND model_horizon(year) AND year2.pos < year.pos).. + EMISS_LU_AUX2(location,emission,type_tec,year,year2) $ ( year2.pos < year.pos ) + =G= + SUM(land_scenario, + LAND(location, land_scenario, year) * land_emission(location, land_scenario, year2, emission) + - LAND(location, land_scenario, year2) * land_emission(location, land_scenario, year2, emission) ) + - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), EMISS_LU_AUX2(location, emission,type_tec, year3, year2) ) ; + + * EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. * EMISS_LU_ZERO(location,emission,type_tec,year) =E= * ( SUM(land_scenario_ghg_zero, @@ -1950,14 +1963,13 @@ LAND_COST_CUMU(location, year)$( model_horizon(year) ).. land_cost(location,land_scenario,year) * LAND(location,land_scenario,year) ) + SUM(year2, LAND_COST_DEBT(location, year, year2) - * df_period(year2) / df_period(year) ) ; -LAND_COST_CUMU_AUX(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. +LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. LAND_COST_DEBT(location, year, year2) $ ( year2.pos < year.pos ) =G= SUM(land_scenario$( land_cost(location,land_scenario,year) ), LAND(location, land_scenario, year) * land_cost(location,land_scenario,year2) - - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) + - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; * LAND_COST_DEBT.UP(location, year, year2) = 0; From 2ad397308697e70e39c588f3c4811310c57514af Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Thu, 25 Jul 2024 15:37:07 +0200 Subject: [PATCH 11/29] Clean up code and remove old experiments --- message_ix/model/MESSAGE/data_load.gms | 56 ++----- message_ix/model/MESSAGE/model_core.gms | 189 ++++-------------------- 2 files changed, 43 insertions(+), 202 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index 46ee38c74..817501d92 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -81,51 +81,6 @@ fixed_extraction, fixed_stock, fixed_new_capacity, fixed_capacity, fixed_activit storage_initial, storage_self_discharge, time_order ; -emission_cumulative(emission) = no; -emission_cumulative('TCE_CO2') = yes; -emission_cumulative('LU_CO2') = yes; -emission_cumulative('TCE') = yes; -emission_annual(emission) = yes; -emission_annual(emission_cumulative) = no; - -* sets -* land_scenario_bio -* / BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / - -* land_scenario_ghg_zero(land_scenario) -* / BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / - -* map_scenario_bio(land_scenario_bio,land_scenario) -* / BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) -* BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) -* BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) -* BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) -* BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) -* BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) -* BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -* / - -* map_bio_ghg_zero(land_scenario_bio,land_scenario) -* / BIO00 . BIO00GHG000 -* BIO05 . BIO05GHG000 -* BIO07 . BIO07GHG000 -* BIO10 . BIO10GHG000 -* BIO15 . BIO15GHG000 -* BIO25 . BIO25GHG000 -* BIO45 . BIO45GHG000 -* / - -* map_scenario_zero(land_scenario_ghg_zero,land_scenario) -* / BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) -* BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) -* BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) -* BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) -* BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) -* BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) -* BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -* / ; - - *----------------------------------------------------------------------------------------------------------------------* * ensure that each node is mapped to itself * @@ -148,6 +103,17 @@ Set rating_unrated(rating) ; rating_unrated(rating) = yes ; rating_unrated('unrated') = no ; +*----------------------------------------------------------------------------------------------------------------------* +* auxiliary mappings for split between cumulative and annualland-use emission calculations * +*----------------------------------------------------------------------------------------------------------------------* + +emission_cumulative(emission) = no; +emission_cumulative('TCE_CO2') = yes; +emission_cumulative('LU_CO2') = yes; +emission_cumulative('TCE') = yes; +emission_annual(emission) = yes; +emission_annual(emission_cumulative) = no; + *----------------------------------------------------------------------------------------------------------------------* * assignment and computation of MESSAGE-specific auxiliary parameters * *----------------------------------------------------------------------------------------------------------------------* diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 32de47dad..6ffe36822 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -105,20 +105,13 @@ Positive Variables ACT_LO(node,tec,year_all,time) relaxation variable for dynamic constraints on activity (downwards) * land-use model emulator LAND(node,land_scenario,year_all) relative share of land-use scenario -* LAND_BIO(node,land_scenario_bio,year_all) relative share of biomass land-use scenario -* LAND_GHG_ZERO(node, land_scenario_ghg_zero, year_all) relative share of G000 land-use scenarios -* content of storage - STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) - -* LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching - EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix - EMISS_LU_AUX2(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix -; - - + EMISS_LU_AUX(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix +* content of storage + STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) +; Variables @@ -134,11 +127,6 @@ Variables EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator * auxiliary variable for aggregate emissions from land-use model emulator EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator -* EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline -* LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation -* LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation -* LAND_COST_BIO(node,year_all) Land scenario price component from biomass -* LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device @@ -305,26 +293,16 @@ Equations EMISSION_EQUIVALENCE auxiliary equation to simplify the notation of emissions EMISSION_EQUIVALENCE_AUX_ANNUAL auxiliary equation calculating land-use emissions from annual scenario input EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input -* EMISSION_EQUIVALENCE_AUX_ZERO auxiliary equation calculating the land-use emissions baseline from cumulative scenario input EMISSION_EQUIVALENCE_AUX_CUMU_AUX auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix - EMISSION_EQUIVALENCE_AUX_CUMU_AUX2 auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) -* LAND_CHECK_EMISS fill LU_GHG check variable -* LAND_CHECK_EMISS_ZERO fill LU_GHG check variable for emissions baseline -* LAND_COST_CUMU dynamic land-cost calculation -* LAND_COST_CUMU_BIO dynamic land-cost calculation helper for BIO price -* LAND_COST_CUMU_GHG dynamic land-cost calculation helper for GHG price - LAND_COST_CUMU land cost including debt from scenario switching - LAND_COST_CUMU_DEBT land cost debt from scenario switching + LAND_COST_CUMU land cost including debt from scenario switching + LAND_COST_CUMU_DEBT land cost debt from scenario switching LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) -* LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario -* LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) -* PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) - TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) +* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -452,7 +430,6 @@ COST_ACCOUNTING_NODAL(node, year).. * cost terms from land-use model emulator (only includes valid node-land_scenario-year combinations) * + SUM(land_scenario$( land_cost(node,land_scenario,year) ), * land_cost(node,land_scenario,year) * LAND(node,land_scenario,year) ) -* + LAND_COST_DYN(node,year) + LAND_COST_NEW(node, year) * cost terms associated with linear relations + SUM(relation$( relation_cost(relation,node,year) ), @@ -1890,8 +1867,12 @@ EMISSION_EQUIVALENCE(node,emission,type_tec,year).. AND map_tec_act(location,tec,year,mode,time) AND map_tec_lifetime(location,tec,vintage,year) ), emission_factor(location,tec,vintage,year,mode,emission) * ACT(location,tec,vintage,year,mode,time) ) * emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' + +** old calculation directly based on land scenario mix * + SUM(land_scenario $( type_tec_land(type_tec) ) , * land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) + +** new calculation based on land scenario mix and its path dependencies for selected variables (emission_cumulative) + EMISS_LU(location,emission,type_tec,year) $ ( type_tec_land(type_tec) ) ) ; @@ -1909,54 +1890,21 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula =E= SUM(land_scenario , land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) -* + EMISS_LU_AUX(location,emission,type_tec,year) - + SUM(year2, EMISS_LU_AUX2(location,emission,type_tec,year, year2) ) + + SUM(year2, EMISS_LU_AUX(location,emission,type_tec,year, year2) ) ; - -* emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' -* ( SUM(land_scenario, -* SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario, year2, emission) * duration_period(year2) ) * -* LAND(location, land_scenario, year) -* ) - -* SUM(year2 $( year2.pos < year.pos ), -* EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) -* ) ) / -* duration_period(year) ; + * find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps -EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year) $ emission_cumulative(emission).. - EMISS_LU_AUX(location,emission,type_tec,year) - =G= - ( SUM(land_scenario, - SUM(year2 $ ( year2.pos < year.pos ), land_emission(location, land_scenario, year2, emission) * duration_period(year2) ) * - LAND(location, land_scenario, year) - ) - - SUM(year2 $( year2.pos < year.pos ), - EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) - ) ) / - duration_period(year) ; - - -EMISSION_EQUIVALENCE_AUX_CUMU_AUX2(location,emission,type_tec,year,year2) $ (emission_cumulative(emission) AND model_horizon(year) AND year2.pos < year.pos).. - EMISS_LU_AUX2(location,emission,type_tec,year,year2) $ ( year2.pos < year.pos ) +EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year,year2) $ (emission_cumulative(emission) AND model_horizon(year) AND year2.pos < year.pos).. + EMISS_LU_AUX(location,emission,type_tec,year,year2) $ ( year2.pos < year.pos ) =G= SUM(land_scenario, LAND(location, land_scenario, year) * land_emission(location, land_scenario, year2, emission) - LAND(location, land_scenario, year2) * land_emission(location, land_scenario, year2, emission) ) - - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), EMISS_LU_AUX2(location, emission,type_tec, year3, year2) ) ; - - -* EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. -* EMISS_LU_ZERO(location,emission,type_tec,year) =E= -* ( SUM(land_scenario_ghg_zero, -* SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * -* LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) -* ) - -* SUM(year2 $( year2.pos < year.pos ), -* EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) -* ) ) / -* duration_period(year) ; + - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), EMISS_LU_AUX(location, emission,type_tec, year3, year2) ) ; +* calculate scenario cost of current land scenario mix under consideration of its path dependencies and +* associated cost differences compared to the land scenario mix of earlier time steps LAND_COST_CUMU(location, year)$( model_horizon(year) ).. LAND_COST_NEW(location, year) =E= SUM(land_scenario$( land_cost(location,land_scenario,year) ), @@ -1972,58 +1920,6 @@ LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; -* LAND_COST_DEBT.UP(location, year, year2) = 0; -* LAND_COST_DEBT.UP(location, year, year2)$( year2.pos < year.pos ) = INF; - - -* LAND_COST_CUMU(location, year)$( model_horizon(year) ).. -* LAND_COST_DYN(location,year) =E= -* LAND_COST_BIO(location,year) -* + LAND_COST_GHG(location,year) ; - -* LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. -* LAND_COST_BIO(location,year) =E= -* SUM(land_scenario$( map_land(location,land_scenario,year) ), -* land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 -* * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") -* * LAND(location,land_scenario,year) ) ; - -* LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. -* LAND_COST_GHG(location,year) =E= -* ( SUM(land_scenario$( map_land(location,land_scenario,year) ), -* (LAND(location, land_scenario, year) -* * ( SUM(year2 $ ( year2.pos <= year.pos ), -* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") -* * duration_period(year2) ) -* - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) -* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) -* - SUM(year2 $ ( year2.pos < year.pos ), -* LAND_COST_GHG(location, year2) * duration_period(year2) ) ) -* / duration_period(year) -* ; - -* LAND_CHECK_EMISS_ZERO(location, year).. -* LU_GHG_Base(location, year) =E= -* SUM(land_scenario$( map_land(location,land_scenario,year) ), -* LAND(location, land_scenario, year) -* * SUM(year2 $ ( year2.pos <= year.pos ), -* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") -* * duration_period(year2) ) ) ) ; - -* LAND_CHECK_EMISS(location, year).. -* LU_GHG(location, year) =E= -* SUM(land_scenario$( map_land(location,land_scenario,year) ), -* LAND(location, land_scenario, year) -* * SUM(year2 $ ( year2.pos <= year.pos ), -* land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; - - -* + (EMISS_LU_ZERO(location,"TCE","all",year) - EMISS_LU(location,"TCE","all",year)) * 44 / 12 -* * SUM(land_scenario$( map_land(location,land_scenario,year) ), -* LAND(location,land_scenario,year) -* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") -* ) ; - *** * Bound on emissions @@ -2087,13 +1983,6 @@ LAND_CONSTRAINT(node,year)$( SUM(land_scenario$( map_land(node,land_scenario,yea SUM(land_scenario$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year) ) =E= 1 ; -* LAND_FILL_BIO(node,land_scenario_bio,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. -* LAND_BIO(node,land_scenario_bio,year) =E= -* SUM(map_scenario_bio(land_scenario_bio,land_scenario)$( map_land(node,land_scenario,year) ), LAND(node,land_scenario,year)); - -* LAND_FILL_GHG_ZERO(node,land_scenario_ghg_zero,year)$( SUM(land_scenario$( map_land(node,land_scenario,year) ), 1 ) ) .. -* LAND_GHG_ZERO(node, land_scenario_ghg_zero, year) =E= -* SUM(map_bio_ghg_zero(land_scenario_bio,land_scenario_ghg_zero), LAND_BIO(node,land_scenario_bio,year) ); *** * Dynamic constraints on land use * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -2253,34 +2142,20 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; -*PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) -* * LAND(node, land_scenario, year) -* ) =L= -* SUM((year_all2)$( seq_period(year_all2,year) ), -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) -* * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) -* + historical_land(node,land_scenario,year_all2) ) -* ) -* ) -*; - - -TAU_CONSTRAINT(node, year, level, time) .. - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) - * LAND(node, land_scenario, year) - ) =G= - SUM((year_all2)$( seq_period(year_all2,year) ), - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) - * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) - + historical_land(node,land_scenario,year_all2) ) - ) - ) -; + +* TAU_CONSTRAINT(node, year, level, time) .. +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) +* * LAND(node, land_scenario, year) +* ) =G= +* SUM((year_all2)$( seq_period(year_all2,year) ), +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) +* * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) +* + historical_land(node,land_scenario,year_all2) ) +* ) +* ) +* ; *----------------------------------------------------------------------------------------------------------------------* From af541d751365a6d256a27700b411922a44450999 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 13:39:55 +0100 Subject: [PATCH 12/29] Activate and comment Tau constraint --- message_ix/model/MESSAGE/model_core.gms | 46 +++++++++++++++++-------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 6ffe36822..9d58c92ec 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -302,7 +302,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) -* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) + TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -2143,19 +2143,37 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y ; -* TAU_CONSTRAINT(node, year, level, time) .. -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) -* * LAND(node, land_scenario, year) -* ) =G= -* SUM((year_all2)$( seq_period(year_all2,year) ), -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) -* * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) -* + historical_land(node,land_scenario,year_all2) ) -* ) -* ) -* ; +*** +* +* To ensure correct replication of MAgPIE behavior, the following constraint ensures that +* land-use intensity cannot decrease over time +* +* .. _equation_tau_constraint: +* +* Equation TAU_CONSTRAINT +* """""""""""""""""""""""""""""""""""""""" +* +* .. math:: +* \sum_{s \in S} \text{land_output Tau}_{n,s,y,l,h} &\cdot \text{LAND}_{n,s,y} +* \geq \sum_{s \in S} \big( \text{land_output Tau}_{n,s,y-1,l,h} +* & \quad \quad \cdot \big( \text{LAND}_{n,s,y-1} + \text{historical_land}_{n,s,y-1} \big) \big) +* +*** + + +TAU_CONSTRAINT(node, year, level, time) .. + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) + * LAND(node, land_scenario, year) + ) =G= + SUM((year_all2)$( seq_period(year_all2,year) ), + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year_all2, "Landuse intensity indicator Tau", level, time) + * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) + + historical_land(node,land_scenario,year_all2) ) + ) + ) +; *----------------------------------------------------------------------------------------------------------------------* From 2258a08842e0915f44980902dfce261961690d34 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 13:40:05 +0100 Subject: [PATCH 13/29] Remove unused sets --- message_ix/model/MESSAGE/sets_maps_def.gms | 5 ----- 1 file changed, 5 deletions(-) diff --git a/message_ix/model/MESSAGE/sets_maps_def.gms b/message_ix/model/MESSAGE/sets_maps_def.gms index bc7299797..6a31f1322 100644 --- a/message_ix/model/MESSAGE/sets_maps_def.gms +++ b/message_ix/model/MESSAGE/sets_maps_def.gms @@ -151,8 +151,6 @@ Sets emission_annual (emission) greenhouse gases - pollutants - etc. from annual inputs emission_cumulative (emission) greenhouse gases - pollutants - etc. from cumulative inputs land_scenario scenarios of land use (for land-use model emulator) -* land_scenario_bio biomass scenarios of land use (for land-use emulator) - land_scenario_ghg emission scenarios of land use (for land-use emulator) land_type types of land use year_all years (over entire model horizon) year (year_all) years included in a model instance (for myopic or rolling-horizon optimization) @@ -402,9 +400,6 @@ Sets map_land(node,land_scenario,year_all) mapping of land-use model emulator scenarios to nodes and years map_relation(relation,node,year_all) mapping of generic (user-defined) relations to nodes and years -* map_scenario_bio(land_scenario_bio,land_scenario) mapping of land-use model emulator scenarios to biomass scenarios - map_scenario_ghg(land_scenario_ghg,land_scenario) mapping of land-use model emulator scenarios to emission scenarios - * Storage map_time_commodity_storage(node,tec,level,commodity,mode,year_all,time) mapping of storage containers to their input commodity-level (not commodity-level of stored media) ; From 89c33dd206c23b8adad71e58f8b672dbbc13464a Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 13:40:17 +0100 Subject: [PATCH 14/29] Comment data load steps --- message_ix/model/MESSAGE/data_load.gms | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index 817501d92..ce3435bd9 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -107,10 +107,15 @@ rating_unrated('unrated') = no ; * auxiliary mappings for split between cumulative and annualland-use emission calculations * *----------------------------------------------------------------------------------------------------------------------* +* remove all emission types from subset for cumulative land-use emission accounting emission_cumulative(emission) = no; +* add emission types where land-use emissions should use the cumulative accounting approach +* TO DO: to avoid having to declarde these emissions in gams code, this section should be translated into a Python process emission_cumulative('TCE_CO2') = yes; emission_cumulative('LU_CO2') = yes; emission_cumulative('TCE') = yes; +* add all emission types to subset for annual land-use emission accounting, +* then remove the emission types that have been declared in the cumulative accounting set emission_annual(emission) = yes; emission_annual(emission_cumulative) = no; From ca3749a20ff9eaed485e63918c5ea9a0053c5f82 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 14:50:25 +0100 Subject: [PATCH 15/29] Clean up and comment the cumulative land-use emission approach --- message_ix/model/MESSAGE/model_core.gms | 38 ++++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 9d58c92ec..1658cb56d 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -1854,8 +1854,7 @@ ACTIVITY_SOFT_CONSTRAINT_LO(node,tec,year,time)$( soft_activity_lo(node,tec,year * \sum_{n^L \in N(n)} \Bigg( * \sum_{t \in T(\widehat{t}),y^V \leq y,m,h } * \text{emission_factor}_{n^L,t,y^V,y,m,e} \cdot \text{ACT}_{n^L,t,y^V,y,m,h} \\ -* + \sum_{s} \ \text{land_emission}_{n^L,s,y,e} \cdot \text{LAND}_{n^L,s,y} -* \text{ if } \widehat{t} \in \widehat{T}^{LAND} \Bigg) +* + \text{EMISS_LU}_{n^L,e,\widehat{t},y} \text{ if } \widehat{t} \in \widehat{T}^{LAND} \Bigg) * *** EMISSION_EQUIVALENCE(node,emission,type_tec,year).. @@ -1866,25 +1865,44 @@ EMISSION_EQUIVALENCE(node,emission,type_tec,year).. SUM((tec,vintage,mode,time)$( cat_tec(type_tec,tec) AND map_tec_act(location,tec,year,mode,time) AND map_tec_lifetime(location,tec,vintage,year) ), emission_factor(location,tec,vintage,year,mode,emission) * ACT(location,tec,vintage,year,mode,time) ) -* emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' - -** old calculation directly based on land scenario mix -* + SUM(land_scenario $( type_tec_land(type_tec) ) , -* land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) - -** new calculation based on land scenario mix and its path dependencies for selected variables (emission_cumulative) +* emissions from land-use activity based on land scenario mix and its path dependencies +* for selected variables (emission_cumulative) if 'type_tec' is included in the dynamic set 'type_tec_land' + EMISS_LU(location,emission,type_tec,year) $ ( type_tec_land(type_tec) ) ) ; + +* .. _equation_emission_equivalence_aux_annual: +* +* Equation EMISSION_EQUIVALENCE_AUX_ANNUAL +* """"""""""""""""""""""""""""" +* This auxillary equation accounts for emissions in set emission_annual without considering a path-dependent emission debt +* +* +* .. math:: +* \text{EMISS_LU}_{n^L,e^a,\widehat{t},y} = +* \sum_{s} \text{land_emission}_{n^L,s,y,e^a} \cdot \text{LAND}_{n^L,s,y} +* +*** EMISSION_EQUIVALENCE_AUX_ANNUAL(location,emission,type_tec,year) $ emission_annual(emission).. EMISS_LU(location,emission,type_tec,year) =E= -* emissions from land use if 'type_tec' is included in the dynamic set 'type_tec_land' SUM(land_scenario , land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) ; +* .. _equation_emission_equivalence_aux_cumu: +* +* Equation EMISSION_EQUIVALENCE_AUX_CUMU +* """"""""""""""""""""""""""""" +* This auxillary equation accounts for emissions in set emission_annual without considering a path-dependent emission debt +* +* +* .. math:: +* \text{EMISS_LU}_{n^L,e^a,\widehat{t},y} = +* \sum_{s} \text{land_emission}_{n^L,s,y,e^a} \cdot \text{LAND}_{n^L,s,y} +* +*** EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumulative(emission).. EMISS_LU(location,emission,type_tec,year) =E= From 3a711d7c597e70ec82e7b21c7326b699a8639607 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 15:05:29 +0100 Subject: [PATCH 16/29] Clean up and comment the cumulative land-use emissions accounting --- message_ix/model/MESSAGE/model_core.gms | 26 +++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 1658cb56d..e9752bb06 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -1895,12 +1895,19 @@ EMISSION_EQUIVALENCE_AUX_ANNUAL(location,emission,type_tec,year) $ emission_annu * * Equation EMISSION_EQUIVALENCE_AUX_CUMU * """"""""""""""""""""""""""""" -* This auxillary equation accounts for emissions in set emission_annual without considering a path-dependent emission debt -* +* This auxillary equation accounts for emissions in set emission_cumulative considering a path-dependent emission debt +* This debt is calculated by comparing the historic emissions of the current time step's land-use mix in variable LAND +* to the emissions of the actually chosen scenario mix of previous timesteps, including any emission debts accounted for +* before. To do so, first, for every previous model time step, the emissions in those steps under the current land-use +* scenario mix and the delta to the chosen mix in that time step are calculated. To ensure any historic emission debt is +* only accounted for the first time step(s) it occurs, the accounted debt towards any previous time step is subtracted +* towards a minimum of 0. +* * * .. math:: -* \text{EMISS_LU}_{n^L,e^a,\widehat{t},y} = -* \sum_{s} \text{land_emission}_{n^L,s,y,e^a} \cdot \text{LAND}_{n^L,s,y} +* \text{EMISS_LU}_{n^L,e^c,\widehat{t},y} = +* \sum_{s} \text{land_emission}_{n^L,s,y,e^c} \cdot \text{LAND}_{n^L,s,y} \\ +* + \sum_{\widehat{y}} \text{EMISS_LU_AUX}_{n^L,e^c,\widehat{t},y,\widehat{y}} * *** EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumulative(emission).. @@ -1911,8 +1918,15 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula + SUM(year2, EMISS_LU_AUX(location,emission,type_tec,year, year2) ) ; - -* find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps +* find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps by +* applying both the current and previously chosen land mix to the previous time steps. +* .. math:: +* \text{EMISS_LU_AUX}_{n^L,e^c,\widehat{t},y,\widehat{y}} \text{ if } \widehat{y} < y >= +* \sum_{s} \Bigg( \text{land_emission}_{n^L,s,\widehat{y},e^c} \cdot \text{LAND}_{n^L,s,y} \\ +* - \text{land_emission}_{n^L,s,\widehat{y},e^c} \cdot \text{LAND}_{n^L,s,\widehat{y}} \Bigg) \\ +* - \sum_{\dot{y}} \text{EMISS_LU_AUX}_{n^L,e^c,\widehat{t},\dot{y},\widehat{y}} \text{ if } \widehat{y} < \dot{y} \text{ and } \dot{y} < y +* +*** EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year,year2) $ (emission_cumulative(emission) AND model_horizon(year) AND year2.pos < year.pos).. EMISS_LU_AUX(location,emission,type_tec,year,year2) $ ( year2.pos < year.pos ) =G= From ccb47fc03933e88af71fc3225478f6c99f06f964 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 15:22:35 +0100 Subject: [PATCH 17/29] Update code comments for land scenario cost debt --- message_ix/model/MESSAGE/model_core.gms | 33 +++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index e9752bb06..a169a178a 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -1920,6 +1920,8 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula * find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps by * applying both the current and previously chosen land mix to the previous time steps. +* +* * .. math:: * \text{EMISS_LU_AUX}_{n^L,e^c,\widehat{t},y,\widehat{y}} \text{ if } \widehat{y} < y >= * \sum_{s} \Bigg( \text{land_emission}_{n^L,s,\widehat{y},e^c} \cdot \text{LAND}_{n^L,s,y} \\ @@ -1935,8 +1937,23 @@ EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year,year2) $ (emis - LAND(location, land_scenario, year2) * land_emission(location, land_scenario, year2, emission) ) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), EMISS_LU_AUX(location, emission,type_tec, year3, year2) ) ; -* calculate scenario cost of current land scenario mix under consideration of its path dependencies and -* associated cost differences compared to the land scenario mix of earlier time steps + +* .. _equation_land_cost_cumu: +* +* Equation LAND_COST_CUMU +* """"""""""""""""""""""""""""" +* This auxillary equation calculated the true cost of a specific land-use scenario by adding the path-dependency cost +* of the current land scenario mix on top of the base cost. This is done by comparing the cost of the current land scenario mix +* if followed over the whole model horizon up to this time step to the cost in every time step stemming from the chosen scenario +* mix minus any debt that has been accounted for already. +* +* +* .. math:: +* \text{LAND_COST_NEW}_{n^L,y} = +* \sum_{s} \text{land_cost}_{n^L,s,y} \cdot \text{LAND}_{n^L,s,y} \\ +* + \sum_{\widehat{y}} \text{LAND_COST_DEBT}_{n^L,y,\widehat{y}} +* +*** LAND_COST_CUMU(location, year)$( model_horizon(year) ).. LAND_COST_NEW(location, year) =E= SUM(land_scenario$( land_cost(location,land_scenario,year) ), @@ -1945,6 +1962,18 @@ LAND_COST_CUMU(location, year)$( model_horizon(year) ).. LAND_COST_DEBT(location, year, year2) ) ; +* Calculate scenario cost debt of current land scenario mix by comparing the current land scenario mix application to the actually applied +* mix in previous time steps. To avoid double accounting of any scenario cost debt, subtract the debt associated with a previous step accounted +* for in other time steps. +* +* +* .. math:: +* \text{LAND_COST_DEBT}_{n^L,y,\widehat{y}} \text{ if } \widehat{y} < y >= +* \sum_{s} \Bigg( \text{LAND}_{n^L,s,y} \cdot \text{land_cost}_{n^L,s,\widehat{y}} \\ +* - \text{LAND}_{n^L,s,\widehat{y}} \cdot \text{land_cost}_{n^L,s,\widehat{y}} \Bigg) \cdot \text{df_period}_{\widehat{y}} \ \text{df_period}_{y} \\ +* - \sum_{\dot{y}} \text{LAND_COST_DEBT}_{n^L,\dot{y},\widehat{y}} \text{ if } \widehat{y} < \dot{y} \text{ and } \dot{y} < y +* +*** LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. LAND_COST_DEBT(location, year, year2) $ ( year2.pos < year.pos ) =G= SUM(land_scenario$( land_cost(location,land_scenario,year) ), From 86bf21251e54b7742592225f82be46ad8783d724 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Fri, 28 Jul 2023 14:41:39 +0200 Subject: [PATCH 18/29] Add new variables and equations for cumulative LU emis accounting --- message_ix/model/MESSAGE/data_load.gms | 7 +++++++ message_ix/model/MESSAGE/model_core.gms | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index ce3435bd9..a99399590 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -81,6 +81,13 @@ fixed_extraction, fixed_stock, fixed_new_capacity, fixed_capacity, fixed_activit storage_initial, storage_self_discharge, time_order ; +emission_cumulative(emission) = no; +emission_cumulative('TCE_CO2') = yes; +emission_cumulative('LU_CO2') = yes; +emission_cumulative('TCE') = yes; +emission_annual(emission) = yes; +emission_annual(emission_cumulative) = no; + *----------------------------------------------------------------------------------------------------------------------* * ensure that each node is mapped to itself * diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index a169a178a..d52d59487 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -1981,7 +1981,6 @@ LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; - *** * Bound on emissions * ^^^^^^^^^^^^^^^^^^ From 1c6abbd2bfb470563a143815639ba47f9f1c2c9e Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Sep 2023 16:31:56 +0200 Subject: [PATCH 19/29] Add Tau Constraint --- message_ix/model/MESSAGE/model_core.gms | 1 - 1 file changed, 1 deletion(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index d52d59487..5312f07cf 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -2235,7 +2235,6 @@ TAU_CONSTRAINT(node, year, level, time) .. ) ; - *----------------------------------------------------------------------------------------------------------------------* *** * .. _section_of_generic_relations: From 0d7288c28ae8ba939fb0cdcc12ada607a04da3be Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Tue, 19 Sep 2023 11:43:05 +0200 Subject: [PATCH 20/29] Temporarily remove Tau constraint --- message_ix/model/MESSAGE/model_core.gms | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 5312f07cf..847e63aea 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -302,7 +302,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) - TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) +* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -2235,6 +2235,7 @@ TAU_CONSTRAINT(node, year, level, time) .. ) ; + *----------------------------------------------------------------------------------------------------------------------* *** * .. _section_of_generic_relations: From acbf36e1121d743bcd0d590448d86eb97acab965 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 20 Sep 2023 13:02:28 +0200 Subject: [PATCH 21/29] Re-activate the Tau constraint --- message_ix/model/MESSAGE/model_core.gms | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 847e63aea..91fd3deba 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -302,7 +302,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) -* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) + TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -2220,7 +2220,6 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y * *** - TAU_CONSTRAINT(node, year, level, time) .. SUM(land_scenario$( map_land(node,land_scenario,year) ), land_output(node, land_scenario, year, "Landuse intensity indicator Tau", level, time) From 06fce125552401d4248719f4d9616a26be24e849 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 20 Sep 2023 13:07:08 +0200 Subject: [PATCH 22/29] Add primary forest growth constraint --- message_ix/model/MESSAGE/model_core.gms | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 91fd3deba..0994eb0b1 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -302,6 +302,7 @@ Equations DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) + PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) @@ -2202,6 +2203,19 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; +PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) + * LAND(node, land_scenario, year) + ) =L= + SUM((year_all2)$( seq_period(year_all2,year) ), + SUM(land_scenario$( map_land(node,land_scenario,year) ), + land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) + * LAND(node, land_scenario, year_all2) + ) + ) +; + *** * From f0e85ece2513e60a54ea81bbdf4cb5919bbb2623 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 20 Sep 2023 13:34:56 +0200 Subject: [PATCH 23/29] Remove LAND > 1 bug for historic time steps --- message_ix/model/MESSAGE/model_core.gms | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 0994eb0b1..f450af7ce 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -2211,7 +2211,8 @@ PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. SUM((year_all2)$( seq_period(year_all2,year) ), SUM(land_scenario$( map_land(node,land_scenario,year) ), land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) - * LAND(node, land_scenario, year_all2) + * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) + + historical_land(node,land_scenario,year_all2) ) ) ) ; From ce0d3e865e780fd3f36cbe8b41660216bc247d35 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Fri, 29 Sep 2023 09:52:32 +0200 Subject: [PATCH 24/29] Replace static land_cost with dynamic variable based on cumulative emiss --- message_ix/model/MESSAGE/data_load.gms | 41 +++++++++ message_ix/model/MESSAGE/model_core.gms | 99 ++++++++++++++++++---- message_ix/model/MESSAGE/sets_maps_def.gms | 5 ++ 3 files changed, 130 insertions(+), 15 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index a99399590..ec6da33ca 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -88,6 +88,47 @@ emission_cumulative('TCE') = yes; emission_annual(emission) = yes; emission_annual(emission_cumulative) = no; +sets +land_scenario_bio +/ BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / + +land_scenario_ghg_zero(land_scenario) +/ BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / + +map_scenario_bio(land_scenario_bio,land_scenario) +/ BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) + BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) + BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) + BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) + BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) + BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) + BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +/ + +map_bio_ghg_zero(land_scenario_bio,land_scenario) +/ BIO00 . BIO00GHG000 + BIO05 . BIO05GHG000 + BIO07 . BIO07GHG000 + BIO10 . BIO10GHG000 + BIO15 . BIO15GHG000 + BIO25 . BIO25GHG000 + BIO45 . BIO45GHG000 +/ + +map_scenario_zero(land_scenario_ghg_zero,land_scenario) +/ BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) + BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) + BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) + BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) + BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) + BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) + BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +/ + + +; + + *----------------------------------------------------------------------------------------------------------------------* * ensure that each node is mapped to itself * diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index f450af7ce..ab2cc329a 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -108,9 +108,10 @@ Positive Variables LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching EMISS_LU_AUX(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix - * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) + + LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator ; @@ -127,6 +128,11 @@ Variables EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator * auxiliary variable for aggregate emissions from land-use model emulator EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator + EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline + LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation + LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation + LAND_COST_BIO(node,year_all) Land scenario price component from biomass + LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device @@ -298,11 +304,13 @@ Equations LAND_COST_CUMU land cost including debt from scenario switching LAND_COST_CUMU_DEBT land cost debt from scenario switching LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) + LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario + LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) - PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) +* PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) @@ -1982,6 +1990,67 @@ LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; +EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. + EMISS_LU_ZERO(location,emission,type_tec,year) =E= + ( SUM(land_scenario_ghg_zero, + SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * + LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) + ) - + SUM(year2 $( year2.pos < year.pos ), + EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) + ) ) / + duration_period(year) ; + + +LAND_COST_CUMU(location, year)$( model_horizon(year) ).. + LAND_COST_DYN(location,year) =E= + LAND_COST_BIO(location,year) + + LAND_COST_GHG(location,year) ; + +LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. + LAND_COST_BIO(location,year) =E= + SUM(land_scenario$( map_land(location,land_scenario,year) ), + land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 + * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") + * LAND(location,land_scenario,year) ) ; + +LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. + LAND_COST_GHG(location,year) =E= + ( SUM(land_scenario$( map_land(location,land_scenario,year) ), + (LAND(location, land_scenario, year) + * ( SUM(year2 $ ( year2.pos <= year.pos ), + SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") + * duration_period(year2) ) + - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) + * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) + - SUM(year2 $ ( year2.pos < year.pos ), + LAND_COST_GHG(location, year2) * duration_period(year2) ) ) + / duration_period(year) + ; + +LAND_CHECK_EMISS_ZERO(location, year).. + LU_GHG_Base(location, year) =E= + SUM(land_scenario$( map_land(location,land_scenario,year) ), + LAND(location, land_scenario, year) + * SUM(year2 $ ( year2.pos <= year.pos ), + SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") + * duration_period(year2) ) ) ) ; + +LAND_CHECK_EMISS(location, year).. + LU_GHG(location, year) =E= + SUM(land_scenario$( map_land(location,land_scenario,year) ), + LAND(location, land_scenario, year) + * SUM(year2 $ ( year2.pos <= year.pos ), + land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; + + +* + (EMISS_LU_ZERO(location,"TCE","all",year) - EMISS_LU(location,"TCE","all",year)) * 44 / 12 +* * SUM(land_scenario$( map_land(location,land_scenario,year) ), +* LAND(location,land_scenario,year) +* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") +* ) ; + + *** * Bound on emissions * ^^^^^^^^^^^^^^^^^^ @@ -2203,19 +2272,19 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; -PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) - * LAND(node, land_scenario, year) - ) =L= - SUM((year_all2)$( seq_period(year_all2,year) ), - SUM(land_scenario$( map_land(node,land_scenario,year) ), - land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) - * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) - + historical_land(node,land_scenario,year_all2) ) - ) - ) -; +*PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) +* * LAND(node, land_scenario, year) +* ) =L= +* SUM((year_all2)$( seq_period(year_all2,year) ), +* SUM(land_scenario$( map_land(node,land_scenario,year) ), +* land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) +* * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) +* + historical_land(node,land_scenario,year_all2) ) +* ) +* ) +*; *** diff --git a/message_ix/model/MESSAGE/sets_maps_def.gms b/message_ix/model/MESSAGE/sets_maps_def.gms index 6a31f1322..bc7299797 100644 --- a/message_ix/model/MESSAGE/sets_maps_def.gms +++ b/message_ix/model/MESSAGE/sets_maps_def.gms @@ -151,6 +151,8 @@ Sets emission_annual (emission) greenhouse gases - pollutants - etc. from annual inputs emission_cumulative (emission) greenhouse gases - pollutants - etc. from cumulative inputs land_scenario scenarios of land use (for land-use model emulator) +* land_scenario_bio biomass scenarios of land use (for land-use emulator) + land_scenario_ghg emission scenarios of land use (for land-use emulator) land_type types of land use year_all years (over entire model horizon) year (year_all) years included in a model instance (for myopic or rolling-horizon optimization) @@ -400,6 +402,9 @@ Sets map_land(node,land_scenario,year_all) mapping of land-use model emulator scenarios to nodes and years map_relation(relation,node,year_all) mapping of generic (user-defined) relations to nodes and years +* map_scenario_bio(land_scenario_bio,land_scenario) mapping of land-use model emulator scenarios to biomass scenarios + map_scenario_ghg(land_scenario_ghg,land_scenario) mapping of land-use model emulator scenarios to emission scenarios + * Storage map_time_commodity_storage(node,tec,level,commodity,mode,year_all,time) mapping of storage containers to their input commodity-level (not commodity-level of stored media) ; From 9bfaa0220a177eb4430a0fbd386ebeacf98c9b9e Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 2 Oct 2023 18:28:57 +0200 Subject: [PATCH 25/29] Limit cumulative accounting to net-positive emissions Also, remove cumulative cost accounting --- message_ix/model/MESSAGE/model_core.gms | 121 ++++++++++++------------ 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index ab2cc329a..9c09adf98 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -111,7 +111,8 @@ Positive Variables * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) - LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator + LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator + EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; @@ -128,11 +129,11 @@ Variables EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator * auxiliary variable for aggregate emissions from land-use model emulator EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator - EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline - LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation - LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation - LAND_COST_BIO(node,year_all) Land scenario price component from biomass - LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions +* EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline +* LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation +* LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation +* LAND_COST_BIO(node,year_all) Land scenario price component from biomass +* LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device @@ -304,8 +305,8 @@ Equations LAND_COST_CUMU land cost including debt from scenario switching LAND_COST_CUMU_DEBT land cost debt from scenario switching LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) - LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario - LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario +* LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario +* LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) @@ -1990,58 +1991,58 @@ LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; -EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. - EMISS_LU_ZERO(location,emission,type_tec,year) =E= - ( SUM(land_scenario_ghg_zero, - SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * - LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) - ) - - SUM(year2 $( year2.pos < year.pos ), - EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) - ) ) / - duration_period(year) ; - - -LAND_COST_CUMU(location, year)$( model_horizon(year) ).. - LAND_COST_DYN(location,year) =E= - LAND_COST_BIO(location,year) - + LAND_COST_GHG(location,year) ; - -LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. - LAND_COST_BIO(location,year) =E= - SUM(land_scenario$( map_land(location,land_scenario,year) ), - land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 - * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") - * LAND(location,land_scenario,year) ) ; - -LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. - LAND_COST_GHG(location,year) =E= - ( SUM(land_scenario$( map_land(location,land_scenario,year) ), - (LAND(location, land_scenario, year) - * ( SUM(year2 $ ( year2.pos <= year.pos ), - SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") - * duration_period(year2) ) - - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) - * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) - - SUM(year2 $ ( year2.pos < year.pos ), - LAND_COST_GHG(location, year2) * duration_period(year2) ) ) - / duration_period(year) - ; - -LAND_CHECK_EMISS_ZERO(location, year).. - LU_GHG_Base(location, year) =E= - SUM(land_scenario$( map_land(location,land_scenario,year) ), - LAND(location, land_scenario, year) - * SUM(year2 $ ( year2.pos <= year.pos ), - SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") - * duration_period(year2) ) ) ) ; - -LAND_CHECK_EMISS(location, year).. - LU_GHG(location, year) =E= - SUM(land_scenario$( map_land(location,land_scenario,year) ), - LAND(location, land_scenario, year) - * SUM(year2 $ ( year2.pos <= year.pos ), - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; +* EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. +* EMISS_LU_ZERO(location,emission,type_tec,year) =E= +* ( SUM(land_scenario_ghg_zero, +* SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * +* LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) +* ) - +* SUM(year2 $( year2.pos < year.pos ), +* EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) +* ) ) / +* duration_period(year) ; + + +* LAND_COST_CUMU(location, year)$( model_horizon(year) ).. +* LAND_COST_DYN(location,year) =E= +* LAND_COST_BIO(location,year) +* + LAND_COST_GHG(location,year) ; + +* LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. +* LAND_COST_BIO(location,year) =E= +* SUM(land_scenario$( map_land(location,land_scenario,year) ), +* land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 +* * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") +* * LAND(location,land_scenario,year) ) ; + +* LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. +* LAND_COST_GHG(location,year) =E= +* ( SUM(land_scenario$( map_land(location,land_scenario,year) ), +* (LAND(location, land_scenario, year) +* * ( SUM(year2 $ ( year2.pos <= year.pos ), +* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") +* * duration_period(year2) ) +* - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) +* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) +* - SUM(year2 $ ( year2.pos < year.pos ), +* LAND_COST_GHG(location, year2) * duration_period(year2) ) ) +* / duration_period(year) +* ; + +* LAND_CHECK_EMISS_ZERO(location, year).. +* LU_GHG_Base(location, year) =E= +* SUM(land_scenario$( map_land(location,land_scenario,year) ), +* LAND(location, land_scenario, year) +* * SUM(year2 $ ( year2.pos <= year.pos ), +* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") +* * duration_period(year2) ) ) ) ; + +* LAND_CHECK_EMISS(location, year).. +* LU_GHG(location, year) =E= +* SUM(land_scenario$( map_land(location,land_scenario,year) ), +* LAND(location, land_scenario, year) +* * SUM(year2 $ ( year2.pos <= year.pos ), +* land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; * + (EMISS_LU_ZERO(location,"TCE","all",year) - EMISS_LU(location,"TCE","all",year)) * 44 / 12 From 70b1620488d6a95484ff6953e0adc333fb9cb164 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 9 Oct 2023 16:31:52 +0200 Subject: [PATCH 26/29] Implement cumulative LU cost accounting (positive only) --- message_ix/model/MESSAGE/model_core.gms | 26 ++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 9c09adf98..2e93e8825 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -111,11 +111,16 @@ Positive Variables * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) - LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator +* LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator + LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching + LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; + + + Variables * intertemporal stock variables (input or output quantity into the stock) STOCK_CHG(node,commodity,level,year_all,time) annual input into and output from stocks of commodities @@ -2002,6 +2007,25 @@ LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos * ) ) / * duration_period(year) ; +LAND_COST_CUMU(location, year)$( model_horizon(year) ).. + LAND_COST_NEW(location, year) =E= + SUM(land_scenario$( land_cost(location,land_scenario,year) ), + land_cost(location,land_scenario,year) * LAND(location,land_scenario,year) ) + + SUM(year2, + LAND_COST_DEBT(location, year, year2) + * df_period(year2) / df_period(year) + ) ; + +LAND_COST_CUMU_AUX(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. + LAND_COST_DEBT(location, year, year2) $ ( year2.pos < year.pos ) =G= + SUM(land_scenario$( land_cost(location,land_scenario,year) ), + LAND(location, land_scenario, year) * land_cost(location,land_scenario,year2) + - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) + - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; + +* LAND_COST_DEBT.UP(location, year, year2) = 0; +* LAND_COST_DEBT.UP(location, year, year2)$( year2.pos < year.pos ) = INF; + * LAND_COST_CUMU(location, year)$( model_horizon(year) ).. * LAND_COST_DYN(location,year) =E= From a7d65b02044aeaa276b7ecc3b34b1aca4ac8d0bd Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Wed, 6 Dec 2023 12:39:45 +0100 Subject: [PATCH 27/29] Simplify cumulative LU changes --- message_ix/model/MESSAGE/data_load.gms | 75 ++++++++++++------------- message_ix/model/MESSAGE/model_core.gms | 28 ++------- 2 files changed, 40 insertions(+), 63 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index ec6da33ca..9fd51ce36 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -88,45 +88,42 @@ emission_cumulative('TCE') = yes; emission_annual(emission) = yes; emission_annual(emission_cumulative) = no; -sets -land_scenario_bio -/ BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / - -land_scenario_ghg_zero(land_scenario) -/ BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / - -map_scenario_bio(land_scenario_bio,land_scenario) -/ BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) - BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) - BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) - BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) - BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) - BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) - BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -/ - -map_bio_ghg_zero(land_scenario_bio,land_scenario) -/ BIO00 . BIO00GHG000 - BIO05 . BIO05GHG000 - BIO07 . BIO07GHG000 - BIO10 . BIO10GHG000 - BIO15 . BIO15GHG000 - BIO25 . BIO25GHG000 - BIO45 . BIO45GHG000 -/ - -map_scenario_zero(land_scenario_ghg_zero,land_scenario) -/ BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG990,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) - BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG990,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) - BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG990,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) - BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG990,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) - BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG990,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) - BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG990,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) - BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG990,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -/ - - -; +* sets +* land_scenario_bio +* / BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / + +* land_scenario_ghg_zero(land_scenario) +* / BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / + +* map_scenario_bio(land_scenario_bio,land_scenario) +* / BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) +* BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) +* BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) +* BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) +* BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) +* BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) +* BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +* / + +* map_bio_ghg_zero(land_scenario_bio,land_scenario) +* / BIO00 . BIO00GHG000 +* BIO05 . BIO05GHG000 +* BIO07 . BIO07GHG000 +* BIO10 . BIO10GHG000 +* BIO15 . BIO15GHG000 +* BIO25 . BIO25GHG000 +* BIO45 . BIO45GHG000 +* / + +* map_scenario_zero(land_scenario_ghg_zero,land_scenario) +* / BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) +* BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) +* BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) +* BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) +* BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) +* BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) +* BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) +* / ; diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 2e93e8825..52d121e94 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -115,6 +115,7 @@ Positive Variables LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix + EMISS_LU_AUX2(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; @@ -306,6 +307,7 @@ Equations EMISSION_EQUIVALENCE_AUX_ANNUAL auxiliary equation calculating land-use emissions from annual scenario input EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input EMISSION_EQUIVALENCE_AUX_CUMU_AUX auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix + EMISSION_EQUIVALENCE_AUX_CUMU_AUX2 auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) LAND_COST_CUMU land cost including debt from scenario switching LAND_COST_CUMU_DEBT land cost debt from scenario switching @@ -1932,27 +1934,6 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) + SUM(year2, EMISS_LU_AUX(location,emission,type_tec,year, year2) ) ; - -* find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps by -* applying both the current and previously chosen land mix to the previous time steps. -* -* -* .. math:: -* \text{EMISS_LU_AUX}_{n^L,e^c,\widehat{t},y,\widehat{y}} \text{ if } \widehat{y} < y >= -* \sum_{s} \Bigg( \text{land_emission}_{n^L,s,\widehat{y},e^c} \cdot \text{LAND}_{n^L,s,y} \\ -* - \text{land_emission}_{n^L,s,\widehat{y},e^c} \cdot \text{LAND}_{n^L,s,\widehat{y}} \Bigg) \\ -* - \sum_{\dot{y}} \text{EMISS_LU_AUX}_{n^L,e^c,\widehat{t},\dot{y},\widehat{y}} \text{ if } \widehat{y} < \dot{y} \text{ and } \dot{y} < y -* -*** -EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year,year2) $ (emission_cumulative(emission) AND model_horizon(year) AND year2.pos < year.pos).. - EMISS_LU_AUX(location,emission,type_tec,year,year2) $ ( year2.pos < year.pos ) - =G= - SUM(land_scenario, - LAND(location, land_scenario, year) * land_emission(location, land_scenario, year2, emission) - - LAND(location, land_scenario, year2) * land_emission(location, land_scenario, year2, emission) ) - - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), EMISS_LU_AUX(location, emission,type_tec, year3, year2) ) ; - - * .. _equation_land_cost_cumu: * * Equation LAND_COST_CUMU @@ -2013,14 +1994,13 @@ LAND_COST_CUMU(location, year)$( model_horizon(year) ).. land_cost(location,land_scenario,year) * LAND(location,land_scenario,year) ) + SUM(year2, LAND_COST_DEBT(location, year, year2) - * df_period(year2) / df_period(year) ) ; -LAND_COST_CUMU_AUX(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. +LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. LAND_COST_DEBT(location, year, year2) $ ( year2.pos < year.pos ) =G= SUM(land_scenario$( land_cost(location,land_scenario,year) ), LAND(location, land_scenario, year) * land_cost(location,land_scenario,year2) - - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) + - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; * LAND_COST_DEBT.UP(location, year, year2) = 0; From 523c87fda17566aa69b0045cd486b305da267803 Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Thu, 25 Jul 2024 15:37:07 +0200 Subject: [PATCH 28/29] Clean up code and remove old experiments --- message_ix/model/MESSAGE/data_load.gms | 56 ++------- message_ix/model/MESSAGE/model_core.gms | 148 ++---------------------- 2 files changed, 23 insertions(+), 181 deletions(-) diff --git a/message_ix/model/MESSAGE/data_load.gms b/message_ix/model/MESSAGE/data_load.gms index 9fd51ce36..0743b51cf 100644 --- a/message_ix/model/MESSAGE/data_load.gms +++ b/message_ix/model/MESSAGE/data_load.gms @@ -81,51 +81,6 @@ fixed_extraction, fixed_stock, fixed_new_capacity, fixed_capacity, fixed_activit storage_initial, storage_self_discharge, time_order ; -emission_cumulative(emission) = no; -emission_cumulative('TCE_CO2') = yes; -emission_cumulative('LU_CO2') = yes; -emission_cumulative('TCE') = yes; -emission_annual(emission) = yes; -emission_annual(emission_cumulative) = no; - -* sets -* land_scenario_bio -* / BIO00, BIO05, BIO07, BIO10, BIO15, BIO25, BIO45 / - -* land_scenario_ghg_zero(land_scenario) -* / BIO00GHG000, BIO05GHG000, BIO07GHG000, BIO10GHG000, BIO15GHG000, BIO25GHG000, BIO45GHG000 / - -* map_scenario_bio(land_scenario_bio,land_scenario) -* / BIO00 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) -* BIO05 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) -* BIO07 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) -* BIO10 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) -* BIO15 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) -* BIO25 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) -* BIO45 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -* / - -* map_bio_ghg_zero(land_scenario_bio,land_scenario) -* / BIO00 . BIO00GHG000 -* BIO05 . BIO05GHG000 -* BIO07 . BIO07GHG000 -* BIO10 . BIO10GHG000 -* BIO15 . BIO15GHG000 -* BIO25 . BIO25GHG000 -* BIO45 . BIO45GHG000 -* / - -* map_scenario_zero(land_scenario_ghg_zero,land_scenario) -* / BIO00GHG000 . (BIO00GHG000,BIO00GHG010,BIO00GHG020,BIO00GHG050,BIO00GHG100,BIO00GHG200,BIO00GHG400,BIO00GHG600,BIO00GHG1000,BIO00GHG2000,BIO00GHG3000,BIO00GHG4000) -* BIO05GHG000 . (BIO05GHG000,BIO05GHG010,BIO05GHG020,BIO05GHG050,BIO05GHG100,BIO05GHG200,BIO05GHG400,BIO05GHG600,BIO05GHG1000,BIO05GHG2000,BIO05GHG3000,BIO05GHG4000) -* BIO07GHG000 . (BIO07GHG000,BIO07GHG010,BIO07GHG020,BIO07GHG050,BIO07GHG100,BIO07GHG200,BIO07GHG400,BIO07GHG600,BIO07GHG1000,BIO07GHG2000,BIO07GHG3000,BIO07GHG4000) -* BIO10GHG000 . (BIO10GHG000,BIO10GHG010,BIO10GHG020,BIO10GHG050,BIO10GHG100,BIO10GHG200,BIO10GHG400,BIO10GHG600,BIO10GHG1000,BIO10GHG2000,BIO10GHG3000,BIO10GHG4000) -* BIO15GHG000 . (BIO15GHG000,BIO15GHG010,BIO15GHG020,BIO15GHG050,BIO15GHG100,BIO15GHG200,BIO15GHG400,BIO15GHG600,BIO15GHG1000,BIO15GHG2000,BIO15GHG3000,BIO15GHG4000) -* BIO25GHG000 . (BIO25GHG000,BIO25GHG010,BIO25GHG020,BIO25GHG050,BIO25GHG100,BIO25GHG200,BIO25GHG400,BIO25GHG600,BIO25GHG1000,BIO25GHG2000,BIO25GHG3000,BIO25GHG4000) -* BIO45GHG000 . (BIO45GHG000,BIO45GHG010,BIO45GHG020,BIO45GHG050,BIO45GHG100,BIO45GHG200,BIO45GHG400,BIO45GHG600,BIO45GHG1000,BIO45GHG2000,BIO45GHG3000,BIO45GHG4000) -* / ; - - *----------------------------------------------------------------------------------------------------------------------* * ensure that each node is mapped to itself * @@ -164,6 +119,17 @@ emission_cumulative('TCE') = yes; emission_annual(emission) = yes; emission_annual(emission_cumulative) = no; +*----------------------------------------------------------------------------------------------------------------------* +* auxiliary mappings for split between cumulative and annualland-use emission calculations * +*----------------------------------------------------------------------------------------------------------------------* + +emission_cumulative(emission) = no; +emission_cumulative('TCE_CO2') = yes; +emission_cumulative('LU_CO2') = yes; +emission_cumulative('TCE') = yes; +emission_annual(emission) = yes; +emission_annual(emission_cumulative) = no; + *----------------------------------------------------------------------------------------------------------------------* * assignment and computation of MESSAGE-specific auxiliary parameters * *----------------------------------------------------------------------------------------------------------------------* diff --git a/message_ix/model/MESSAGE/model_core.gms b/message_ix/model/MESSAGE/model_core.gms index 52d121e94..03553783b 100644 --- a/message_ix/model/MESSAGE/model_core.gms +++ b/message_ix/model/MESSAGE/model_core.gms @@ -108,20 +108,12 @@ Positive Variables LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching EMISS_LU_AUX(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix + * content of storage STORAGE(node,tec,mode,level,commodity,year_all,time) state of charge (SoC) of storage at each sub-annual time slice (positive) - -* LAND_COST_DYN(node,year_all) dynamically calculated cost from the land-use emulator - LAND_COST_NEW(node, year_all) Land cost including debt from scenario switching - LAND_COST_DEBT(node, year_all,year_all2) Land cost debt from scenario switching - EMISS_LU_AUX(node,emission,type_tec,year_all) positive emissions overshoot of historic emissions compared to chosen land scenario mix - EMISS_LU_AUX2(node,emission,type_tec,year_all,year_all2) positive emissions overshoot of historic emissions compared to chosen land scenario mix ; - - - Variables * intertemporal stock variables (input or output quantity into the stock) STOCK_CHG(node,commodity,level,year_all,time) annual input into and output from stocks of commodities @@ -135,11 +127,6 @@ Variables EMISS(node,emission,type_tec,year_all) aggregate emissions by technology type and land-use model emulator * auxiliary variable for aggregate emissions from land-use model emulator EMISS_LU(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator -* EMISS_LU_ZERO(node,emission,type_tec,year_all) aggregate emissions from land-use model emulator at GHG price baseline -* LU_GHG(node, year_all) Check variable for GHG emissions used for dynamic land cost calculation -* LU_GHG_Base(node, year_all) Check variable for baseline GHG emissions for dynamic land cost calculation -* LAND_COST_BIO(node,year_all) Land scenario price component from biomass -* LAND_COST_GHG(node,year_all) Land scenario price component from ghg emissions * auxiliary variable for left-hand side of relations (linear constraints) REL(relation,node,year_all) auxiliary variable for left-hand side of user-defined relations * change in the content of storage device @@ -307,19 +294,15 @@ Equations EMISSION_EQUIVALENCE_AUX_ANNUAL auxiliary equation calculating land-use emissions from annual scenario input EMISSION_EQUIVALENCE_AUX_CUMU auxiliary equation calculating land-use emissions from cumulative scenario input EMISSION_EQUIVALENCE_AUX_CUMU_AUX auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix - EMISSION_EQUIVALENCE_AUX_CUMU_AUX2 auxiliary equation calculating the land-use emissions overshoot if positive compared to historic scenario mix EMISSION_CONSTRAINT nodal-regional-global constraints on emissions (by category) LAND_COST_CUMU land cost including debt from scenario switching LAND_COST_CUMU_DEBT land cost debt from scenario switching LAND_CONSTRAINT constraint on total land use (linear combination of land scenarios adds up to 1) -* LAND_FILL_BIO mapping land-use scenario to biomass land-use scenario -* LAND_FILL_GHG_ZERO mapping biomass land-use scenario to G000 land-use scenario DYNAMIC_LAND_SCEN_CONSTRAINT_UP dynamic constraint on land scenario change (upper bound) DYNAMIC_LAND_SCEN_CONSTRAINT_LO dynamic constraint on land scenario change (lower bound) DYNAMIC_LAND_TYPE_CONSTRAINT_UP dynamic constraint on land-use change (upper bound) DYNAMIC_LAND_TYPE_CONSTRAINT_LO dynamic constraint on land-use change (lower bound) -* PRIMARY_FOREST_CONSTRAINT constraint on primary-forest growth (primary forest may not grow) - TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) +* TAU_CONSTRAINT constraint on land-use intensity growth (regional tau is not allowed to shrink) RELATION_EQUIVALENCE auxiliary equation to simplify the implementation of relations RELATION_CONSTRAINT_UP upper bound of relations (linear constraints) RELATION_CONSTRAINT_LO lower bound of relations (linear constraints) @@ -1934,60 +1917,19 @@ EMISSION_EQUIVALENCE_AUX_CUMU(location,emission,type_tec,year) $ emission_cumula land_emission(location,land_scenario,year,emission) * LAND(location,land_scenario,year) ) + SUM(year2, EMISS_LU_AUX(location,emission,type_tec,year, year2) ) ; -* .. _equation_land_cost_cumu: -* -* Equation LAND_COST_CUMU -* """"""""""""""""""""""""""""" -* This auxillary equation calculated the true cost of a specific land-use scenario by adding the path-dependency cost -* of the current land scenario mix on top of the base cost. This is done by comparing the cost of the current land scenario mix -* if followed over the whole model horizon up to this time step to the cost in every time step stemming from the chosen scenario -* mix minus any debt that has been accounted for already. -* -* -* .. math:: -* \text{LAND_COST_NEW}_{n^L,y} = -* \sum_{s} \text{land_cost}_{n^L,s,y} \cdot \text{LAND}_{n^L,s,y} \\ -* + \sum_{\widehat{y}} \text{LAND_COST_DEBT}_{n^L,y,\widehat{y}} -* -*** -LAND_COST_CUMU(location, year)$( model_horizon(year) ).. - LAND_COST_NEW(location, year) =E= - SUM(land_scenario$( land_cost(location,land_scenario,year) ), - land_cost(location,land_scenario,year) * LAND(location,land_scenario,year) ) - + SUM(year2, - LAND_COST_DEBT(location, year, year2) - ) ; -* Calculate scenario cost debt of current land scenario mix by comparing the current land scenario mix application to the actually applied -* mix in previous time steps. To avoid double accounting of any scenario cost debt, subtract the debt associated with a previous step accounted -* for in other time steps. -* -* -* .. math:: -* \text{LAND_COST_DEBT}_{n^L,y,\widehat{y}} \text{ if } \widehat{y} < y >= -* \sum_{s} \Bigg( \text{LAND}_{n^L,s,y} \cdot \text{land_cost}_{n^L,s,\widehat{y}} \\ -* - \text{LAND}_{n^L,s,\widehat{y}} \cdot \text{land_cost}_{n^L,s,\widehat{y}} \Bigg) \cdot \text{df_period}_{\widehat{y}} \ \text{df_period}_{y} \\ -* - \sum_{\dot{y}} \text{LAND_COST_DEBT}_{n^L,\dot{y},\widehat{y}} \text{ if } \widehat{y} < \dot{y} \text{ and } \dot{y} < y -* -*** -LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos < year.pos).. - LAND_COST_DEBT(location, year, year2) $ ( year2.pos < year.pos ) =G= - SUM(land_scenario$( land_cost(location,land_scenario,year) ), - LAND(location, land_scenario, year) * land_cost(location,land_scenario,year2) - - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; -* EMISSION_EQUIVALENCE_AUX_ZERO(location,emission,type_tec,year) $ emission_cumulative(emission).. -* EMISS_LU_ZERO(location,emission,type_tec,year) =E= -* ( SUM(land_scenario_ghg_zero, -* SUM(year2 $ ( year2.pos <= year.pos ), land_emission(location, land_scenario_ghg_zero, year2, emission) * duration_period(year2) ) * -* LAND_GHG_ZERO(location, land_scenario_ghg_zero, year) -* ) - -* SUM(year2 $( year2.pos < year.pos ), -* EMISS_LU(location, emission, type_tec, year2) * duration_period(year2) -* ) ) / -* duration_period(year) ; +* find positive emissions overshoot for history of current land scenario mix compared to mix of earlier time steps +EMISSION_EQUIVALENCE_AUX_CUMU_AUX(location,emission,type_tec,year,year2) $ (emission_cumulative(emission) AND model_horizon(year) AND year2.pos < year.pos).. + EMISS_LU_AUX(location,emission,type_tec,year,year2) $ ( year2.pos < year.pos ) + =G= + SUM(land_scenario, + LAND(location, land_scenario, year) * land_emission(location, land_scenario, year2, emission) + - LAND(location, land_scenario, year2) * land_emission(location, land_scenario, year2, emission) ) + - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), EMISS_LU_AUX(location, emission,type_tec, year3, year2) ) ; +* calculate scenario cost of current land scenario mix under consideration of its path dependencies and +* associated cost differences compared to the land scenario mix of earlier time steps LAND_COST_CUMU(location, year)$( model_horizon(year) ).. LAND_COST_NEW(location, year) =E= SUM(land_scenario$( land_cost(location,land_scenario,year) ), @@ -2003,58 +1945,6 @@ LAND_COST_CUMU_DEBT(location, year, year2) $ (model_horizon(year) AND year2.pos - LAND(location, land_scenario, year2) * land_cost(location,land_scenario,year2) ) * df_period(year2) / df_period(year) - SUM(year3 $ ( year3.pos < year.pos AND year2.pos < year3.pos ), LAND_COST_DEBT(location, year3, year2) ) ; -* LAND_COST_DEBT.UP(location, year, year2) = 0; -* LAND_COST_DEBT.UP(location, year, year2)$( year2.pos < year.pos ) = INF; - - -* LAND_COST_CUMU(location, year)$( model_horizon(year) ).. -* LAND_COST_DYN(location,year) =E= -* LAND_COST_BIO(location,year) -* + LAND_COST_GHG(location,year) ; - -* LAND_COST_CUMU_BIO(location, year)$( model_horizon(year) ).. -* LAND_COST_BIO(location,year) =E= -* SUM(land_scenario$( map_land(location,land_scenario,year) ), -* land_output(location, land_scenario, year, "bioenergy", "land_use", "year") * 1000 / 31.71 -* * land_output(location, land_scenario, year, "Price|Primary Energy|Biomass", "land_use_reporting", "year") -* * LAND(location,land_scenario,year) ) ; - -* LAND_COST_CUMU_GHG(location, year)$( model_horizon(year) ).. -* LAND_COST_GHG(location,year) =E= -* ( SUM(land_scenario$( map_land(location,land_scenario,year) ), -* (LAND(location, land_scenario, year) -* * ( SUM(year2 $ ( year2.pos <= year.pos ), -* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") -* * duration_period(year2) ) -* - land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) -* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") ) ) -* - SUM(year2 $ ( year2.pos < year.pos ), -* LAND_COST_GHG(location, year2) * duration_period(year2) ) ) -* / duration_period(year) -* ; - -* LAND_CHECK_EMISS_ZERO(location, year).. -* LU_GHG_Base(location, year) =E= -* SUM(land_scenario$( map_land(location,land_scenario,year) ), -* LAND(location, land_scenario, year) -* * SUM(year2 $ ( year2.pos <= year.pos ), -* SUM(map_scenario_zero(land_scenario_ghg_zero,land_scenario),land_output(location, land_scenario_ghg_zero, year2, "LU_GHG", "land_use_reporting", "year") -* * duration_period(year2) ) ) ) ; - -* LAND_CHECK_EMISS(location, year).. -* LU_GHG(location, year) =E= -* SUM(land_scenario$( map_land(location,land_scenario,year) ), -* LAND(location, land_scenario, year) -* * SUM(year2 $ ( year2.pos <= year.pos ), -* land_output(location, land_scenario, year2, "LU_GHG", "land_use_reporting", "year") * duration_period(year2) ) ) ; - - -* + (EMISS_LU_ZERO(location,"TCE","all",year) - EMISS_LU(location,"TCE","all",year)) * 44 / 12 -* * SUM(land_scenario$( map_land(location,land_scenario,year) ), -* LAND(location,land_scenario,year) -* * land_output(location, land_scenario, year, "Price|Carbon|CO2", "land_use_reporting", "year") -* ) ; - *** * Bound on emissions @@ -2277,20 +2167,6 @@ DYNAMIC_LAND_TYPE_CONSTRAINT_LO(node,year,land_type)$( is_dynamic_land_lo(node,y %SLACK_LAND_TYPE_LO% - SLACK_LAND_TYPE_LO(node,year,land_type) ; -*PRIMARY_FOREST_CONSTRAINT(node, year, level, time) .. -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year, "Land Cover|Forest|Forest old|Primary forest", level, time) -* * LAND(node, land_scenario, year) -* ) =L= -* SUM((year_all2)$( seq_period(year_all2,year) ), -* SUM(land_scenario$( map_land(node,land_scenario,year) ), -* land_output(node, land_scenario, year_all2, "Land Cover|Forest|Forest old|Primary forest", level, time) -* * ( LAND(node, land_scenario, year_all2) $ ( model_horizon(year_all2) ) -* + historical_land(node,land_scenario,year_all2) ) -* ) -* ) -*; - *** * From eb992736021d89016edab9a44a8980855b97093e Mon Sep 17 00:00:00 2001 From: Jan Steinhauser Date: Mon, 11 Nov 2024 15:27:46 +0100 Subject: [PATCH 29/29] Remove unused sets --- message_ix/model/MESSAGE/sets_maps_def.gms | 5 ----- 1 file changed, 5 deletions(-) diff --git a/message_ix/model/MESSAGE/sets_maps_def.gms b/message_ix/model/MESSAGE/sets_maps_def.gms index bc7299797..6a31f1322 100644 --- a/message_ix/model/MESSAGE/sets_maps_def.gms +++ b/message_ix/model/MESSAGE/sets_maps_def.gms @@ -151,8 +151,6 @@ Sets emission_annual (emission) greenhouse gases - pollutants - etc. from annual inputs emission_cumulative (emission) greenhouse gases - pollutants - etc. from cumulative inputs land_scenario scenarios of land use (for land-use model emulator) -* land_scenario_bio biomass scenarios of land use (for land-use emulator) - land_scenario_ghg emission scenarios of land use (for land-use emulator) land_type types of land use year_all years (over entire model horizon) year (year_all) years included in a model instance (for myopic or rolling-horizon optimization) @@ -402,9 +400,6 @@ Sets map_land(node,land_scenario,year_all) mapping of land-use model emulator scenarios to nodes and years map_relation(relation,node,year_all) mapping of generic (user-defined) relations to nodes and years -* map_scenario_bio(land_scenario_bio,land_scenario) mapping of land-use model emulator scenarios to biomass scenarios - map_scenario_ghg(land_scenario_ghg,land_scenario) mapping of land-use model emulator scenarios to emission scenarios - * Storage map_time_commodity_storage(node,tec,level,commodity,mode,year_all,time) mapping of storage containers to their input commodity-level (not commodity-level of stored media) ;