diff --git a/config/config.default.yaml b/config/config.default.yaml index 54701daf..1a7f9e57 100644 --- a/config/config.default.yaml +++ b/config/config.default.yaml @@ -1127,6 +1127,7 @@ plotting: services rural biomass boiler: '#c6cf98' services urban decentral biomass boiler: '#dde5b5' biomass to liquid: '#32CD32' + unsustainable solid biomass: '#998622' unsustainable bioliquids: '#32CD32' electrobiofuels: 'red' BioSNG: '#123456' diff --git a/rules/build_sector.smk b/rules/build_sector.smk old mode 100644 new mode 100755 diff --git a/scripts/build_biomass_potentials.py b/scripts/build_biomass_potentials.py old mode 100644 new mode 100755 index 4c7752e4..a3c51292 --- a/scripts/build_biomass_potentials.py +++ b/scripts/build_biomass_potentials.py @@ -330,7 +330,7 @@ def add_unsustainable_potentials(df): ) share_sus = params.get("share_sustainable_potential_available").get(investment_year) - df *= share_sus + df.loc[df_wo_ch.index] *= share_sus df = df.join(df_wo_ch.filter(like="unsustainable")).fillna(0) @@ -345,8 +345,8 @@ if __name__ == "__main__": snakemake = mock_snakemake( "build_biomass_potentials", simpl="", - clusters="37", - planning_horizons=2020, + clusters="38", + planning_horizons=2050, ) configure_logging(snakemake) diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py old mode 100644 new mode 100755 index 9242fbf3..8748b64f --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -63,7 +63,8 @@ def define_spatial(nodes, options): if options.get("biomass_spatial", options["biomass_transport"]): spatial.biomass.nodes = nodes + " solid biomass" - spatial.biomass.bioliquids = nodes + " bioliquids" + spatial.biomass.nodes_unsustainable = nodes + " unsustainable solid biomass" + spatial.biomass.bioliquids = nodes + " unsustainable bioliquids" spatial.biomass.locations = nodes spatial.biomass.industry = nodes + " solid biomass for industry" spatial.biomass.industry_cc = nodes + " solid biomass for industry CC" @@ -71,6 +72,7 @@ def define_spatial(nodes, options): spatial.msw.locations = nodes else: spatial.biomass.nodes = ["EU solid biomass"] + spatial.biomass.nodes_unsustainable = ["EU unsustainable solid biomass"] spatial.biomass.bioliquids = ["EU unsustainable bioliquids"] spatial.biomass.locations = ["EU"] spatial.biomass.industry = ["solid biomass for industry"] @@ -2493,14 +2495,21 @@ def add_biomass(n, costs): e_max_pu=e_max_pu, ) + n.madd( + "Bus", + spatial.biomass.nodes_unsustainable, + location=spatial.biomass.locations, + carrier="unsustainable solid biomass", + unit="MWh_LHV", + ) + e_max_pu = pd.DataFrame(1, index=n.snapshots, columns=spatial.biomass.nodes) e_max_pu.iloc[-1] = 0 n.madd( "Store", - spatial.biomass.nodes, - suffix=" unsustainable", - bus=spatial.biomass.nodes, + spatial.biomass.nodes_unsustainable, + bus=spatial.biomass.nodes_unsustainable, carrier="unsustainable solid biomass", e_nom=unsustainable_solid_biomass_potentials_spatial, marginal_cost=costs.at["fuelwood", "fuel"], @@ -2509,6 +2518,16 @@ def add_biomass(n, costs): e_max_pu=e_max_pu, ) + n.madd( + "Link", + spatial.biomass.nodes_unsustainable, + bus0=spatial.biomass.nodes_unsustainable, + bus1=spatial.biomass.nodes, + carrier="unsustainable solid biomass", + efficiency=1, + p_nom=unsustainable_solid_biomass_potentials_spatial, + ) + n.madd( "Bus", spatial.biomass.bioliquids, @@ -2525,7 +2544,6 @@ def add_biomass(n, costs): n.madd( "Store", spatial.biomass.bioliquids, - suffix=" unsustainable", bus=spatial.biomass.bioliquids, carrier="unsustainable bioliquids", e_nom=unsustainable_liquid_biofuel_potentials_spatial, @@ -2535,6 +2553,8 @@ def add_biomass(n, costs): e_max_pu=e_max_pu, ) + add_carrier_buses(n, "oil") + n.madd( "Link", spatial.biomass.bioliquids, @@ -2663,6 +2683,29 @@ def add_biomass(n, costs): constant=biomass_potentials["solid biomass"].sum(), type="operational_limit", ) + if biomass_potentials["unsustainable solid biomass"].sum() > 0: + n.madd( + "Generator", + spatial.biomass.nodes_unsustainable, + bus=spatial.biomass.nodes_unsustainable, + carrier="unsustainable solid biomass", + p_nom=10000, + marginal_cost=costs.at["fuelwood", "fuel"] + + bus_transport_costs * average_distance, + ) + # Set last snapshot of e_max_pu for unsustainable solid biomass to 1 to make operational limit work + unsus_stores_idx = n.stores.loc[ + n.stores.carrier == "unsustainable solid biomass" + ].index + n.stores_t.e_max_pu.loc[n.snapshots[-1], unsus_stores_idx] = 1 + n.add( + "GlobalConstraint", + "unsustainable biomass limit", + carrier_attribute="unsustainable solid biomass", + sense="==", + constant=biomass_potentials["unsustainable solid biomass"].sum(), + type="operational_limit", + ) if options["municipal_solid_waste"]: # Add municipal solid waste @@ -4285,10 +4328,10 @@ if __name__ == "__main__": "prepare_sector_network", simpl="", opts="", - clusters="37", + clusters="38", ll="vopt", sector_opts="", - planning_horizons="2050", + planning_horizons="2030", ) configure_logging(snakemake)