diff --git a/workflow/Snakefile b/workflow/Snakefile index 4cec21f8..a6dfdbf8 100644 --- a/workflow/Snakefile +++ b/workflow/Snakefile @@ -200,8 +200,12 @@ rule modify_prenetwork: "mobility_demand_aladin_{simpl}_{clusters}_{planning_horizons}.csv" ), transport_data=resources("transport_data_s{simpl}_{clusters}.csv"), - biomass_potentials=resources("biomass_potentials_s{simpl}_{clusters}_{planning_horizons}.csv"), - industrial_demand=resources("industrial_energy_demand_elec_s{simpl}_{clusters}_{planning_horizons}.csv"), + biomass_potentials=resources( + "biomass_potentials_s{simpl}_{clusters}_{planning_horizons}.csv" + ), + industrial_demand=resources( + "industrial_energy_demand_elec_s{simpl}_{clusters}_{planning_horizons}.csv" + ), output: network=RESULTS + "prenetworks-final/elec_s{simpl}_{clusters}_l{ll}_{opts}_{sector_opts}_{planning_horizons}.nc", diff --git a/workflow/scripts/additional_functionality.py b/workflow/scripts/additional_functionality.py index b4cbea07..37afc6e9 100644 --- a/workflow/scripts/additional_functionality.py +++ b/workflow/scripts/additional_functionality.py @@ -378,25 +378,34 @@ def add_co2limit_country(n, limit_countries, snakemake, debug=False): ) lhs.append( - (n.model["Link-p"].loc[:, outgoing_methanol] - / snakemake.config["sector"]["MWh_MeOH_per_tCO2"] - * n.snapshot_weightings.generators).sum()) - + ( + n.model["Link-p"].loc[:, outgoing_methanol] + / snakemake.config["sector"]["MWh_MeOH_per_tCO2"] + * n.snapshot_weightings.generators + ).sum() + ) + # Methane incoming_CH4 = n.links.index[n.links.index == "EU renewable gas -> DE gas"] outgoing_CH4 = n.links.index[n.links.index == "DE renewable gas -> EU gas"] lhs.append( - (-1 * n.model["Link-p"].loc[:, incoming_CH4] - * 0.198 - * n.snapshot_weightings.generators).sum()) - + ( + -1 + * n.model["Link-p"].loc[:, incoming_CH4] + * 0.198 + * n.snapshot_weightings.generators + ).sum() + ) + lhs.append( - (n.model["Link-p"].loc[:, outgoing_CH4] - * 0.198 - * n.snapshot_weightings.generators).sum()) + ( + n.model["Link-p"].loc[:, outgoing_CH4] + * 0.198 + * n.snapshot_weightings.generators + ).sum() + ) - lhs = sum(lhs) cname = f"co2_limit-{ct}" @@ -516,8 +525,20 @@ def add_h2_derivate_limit(n, investment_year, limits_volume_max): logger.info(f"limiting H2 derivate imports in {ct} to {limit/1e6} TWh/a") - incoming = n.links.loc[["EU renewable oil -> DE oil", "EU methanol -> DE methanol", "EU renewable gas -> DE gas"]].index - outgoing = n.links.loc[["DE renewable oil -> EU oil", "DE methanol -> EU methanol", "DE renewable gas -> EU gas"]].index + incoming = n.links.loc[ + [ + "EU renewable oil -> DE oil", + "EU methanol -> DE methanol", + "EU renewable gas -> DE gas", + ] + ].index + outgoing = n.links.loc[ + [ + "DE renewable oil -> EU oil", + "DE methanol -> EU methanol", + "DE renewable gas -> EU gas", + ] + ].index incoming_p = ( n.model["Link-p"].loc[:, incoming] * n.snapshot_weightings.generators diff --git a/workflow/scripts/export_ariadne_variables.py b/workflow/scripts/export_ariadne_variables.py index b30f70b1..59f0bef1 100644 --- a/workflow/scripts/export_ariadne_variables.py +++ b/workflow/scripts/export_ariadne_variables.py @@ -74,6 +74,7 @@ def _get_oil_fossil_fraction(n, region): return oil_fossil_fraction + def _get_gas_fractions(n, region): kwargs = { "groupby": n.statistics.groupers.get_name_bus_and_carrier, @@ -81,68 +82,92 @@ def _get_gas_fractions(n, region): "nice_names": False, } - renewable_gas_supply = n.statistics.supply( - bus_carrier="renewable gas", **kwargs - ).groupby(["bus","carrier"]).sum() + renewable_gas_supply = ( + n.statistics.supply(bus_carrier="renewable gas", **kwargs) + .groupby(["bus", "carrier"]) + .sum() + ) - total_gas_supply = n.statistics.supply( - bus_carrier="gas", **kwargs - ).groupby(["name", "carrier"]).sum() + total_gas_supply = ( + n.statistics.supply(bus_carrier="gas", **kwargs) + .groupby(["name", "carrier"]) + .sum() + ) if "DE" in region: - domestic_gas_supply = total_gas_supply.reindex([ - ("DE gas", "gas"), - ("DE renewable gas -> DE gas", "renewable gas"), - ("EU renewable gas -> DE gas", "renewable gas"), - ]).dropna().groupby("carrier").sum() # If links are not used they are dropped here + domestic_gas_supply = ( + total_gas_supply.reindex( + [ + ("DE gas", "gas"), + ("DE renewable gas -> DE gas", "renewable gas"), + ("EU renewable gas -> DE gas", "renewable gas"), + ] + ) + .dropna() + .groupby("carrier") + .sum() + ) # If links are not used they are dropped here total_imported_renewable_gas = total_gas_supply.get( - ("EU renewable gas -> DE gas", "renewable gas"), 0) + ("EU renewable gas -> DE gas", "renewable gas"), 0 + ) total_exported_renewable_gas = total_gas_supply.get( - ("DE renewable gas -> EU gas", "renewable gas"), 0) + ("DE renewable gas -> EU gas", "renewable gas"), 0 + ) domestic_renewable_gas = renewable_gas_supply.loc["DE renewable gas"] foreign_renewable_gas = renewable_gas_supply.loc["EU renewable gas"] else: - domestic_gas_supply = total_gas_supply.reindex([ - ("EU gas", "gas"), - ("DE renewable gas -> EU gas", "renewable gas"), - ("EU renewable gas -> EU gas", "renewable gas"), - ]).dropna().groupby("carrier").sum() + domestic_gas_supply = ( + total_gas_supply.reindex( + [ + ("EU gas", "gas"), + ("DE renewable gas -> EU gas", "renewable gas"), + ("EU renewable gas -> EU gas", "renewable gas"), + ] + ) + .dropna() + .groupby("carrier") + .sum() + ) total_imported_renewable_gas = total_gas_supply.get( - ("DE renewable gas -> EU gas", "renewable gas"), 0) + ("DE renewable gas -> EU gas", "renewable gas"), 0 + ) total_exported_renewable_gas = total_gas_supply.get( - ("EU renewable gas -> DE gas", "renewable gas"), 0) + ("EU renewable gas -> DE gas", "renewable gas"), 0 + ) domestic_renewable_gas = renewable_gas_supply.loc["EU renewable gas"] foreign_renewable_gas = renewable_gas_supply.loc["DE renewable gas"] - + # Legacy code for dropping gas pipelines (now deactivated) drops = ["gas pipeline", "gas pipeline new"] for d in drops: if d in total_gas_supply.index: total_gas_supply.drop(d, inplace=True) - + imported_renewable_gas = ( - foreign_renewable_gas / foreign_renewable_gas.sum() - * total_imported_renewable_gas + foreign_renewable_gas + / foreign_renewable_gas.sum() + * total_imported_renewable_gas ) exported_renewable_gas = ( - domestic_renewable_gas / domestic_renewable_gas.sum() + domestic_renewable_gas + / domestic_renewable_gas.sum() * total_exported_renewable_gas ) renewable_gas_supply = ( - domestic_renewable_gas - + imported_renewable_gas - - exported_renewable_gas + domestic_renewable_gas + imported_renewable_gas - exported_renewable_gas ) # Check for small differences assert domestic_gas_supply.get("renewable gas", 0) - renewable_gas_supply.sum() < 1 - - gas_fractions = pd.Series({ + + gas_fractions = pd.Series( + { "Natural Gas": domestic_gas_supply.get("gas", 0), "Biomass": renewable_gas_supply.filter(like="biogas").sum(), "Efuel": renewable_gas_supply.get("Sabatier", 0), - }).divide(domestic_gas_supply.sum()) - + } + ).divide(domestic_gas_supply.sum()) + assert isclose(gas_fractions.sum(), 1) return gas_fractions @@ -883,12 +908,16 @@ def _get_capacities(n, region, cap_func, cap_string="Capacity|", costs=None): var[cap_string + "Hydrogen|Reservoir"] = storage_capacities.get("H2", 0) - capacities_gas = cap_func( - bus_carrier="renewable gas", - **kwargs, - ).filter( - like=region - ).groupby("carrier").sum().multiply(MW2GW) + capacities_gas = ( + cap_func( + bus_carrier="renewable gas", + **kwargs, + ) + .filter(like=region) + .groupby("carrier") + .sum() + .multiply(MW2GW) + ) var[cap_string + "Gases|Hydrogen"] = capacities_gas.get("Sabatier", 0) @@ -1028,16 +1057,21 @@ def get_primary_energy(n, region): # Eventhough biogas gets routed through the EU gas bus, # it should be counted separately as Primary Energy|Biomass - gas_usage = n.statistics.withdrawal( - bus_carrier="gas", - **kwargs, - ).filter( - like=region - ).drop( - "Store", errors="ignore", - ).groupby( - "carrier" - ).sum().multiply(gas_fractions["Natural Gas"]).multiply(MWh2PJ) + gas_usage = ( + n.statistics.withdrawal( + bus_carrier="gas", + **kwargs, + ) + .filter(like=region) + .drop( + "Store", + errors="ignore", + ) + .groupby("carrier") + .sum() + .multiply(gas_fractions["Natural Gas"]) + .multiply(MWh2PJ) + ) gas_CHP_E_usage, gas_CHP_H_usage = get_CHP_E_and_H_usage( n, "gas", region, fossil_fraction=gas_fractions["Natural Gas"] @@ -1480,11 +1514,14 @@ def get_secondary_energy(n, region, _industry_demand): heat_supply[~heat_supply.index.str.contains("discharger")].sum(), ) - hydrogen_production = n.statistics.supply( - bus_carrier="H2", **kwargs - ).filter(like=region).drop("Store", errors="ignore").groupby( - ["carrier"] - ).sum().multiply(MWh2PJ) + hydrogen_production = ( + n.statistics.supply(bus_carrier="H2", **kwargs) + .filter(like=region) + .drop("Store", errors="ignore") + .groupby(["carrier"]) + .sum() + .multiply(MWh2PJ) + ) var["Secondary Energy|Hydrogen|Electricity"] = hydrogen_production.get( "H2 Electrolysis", 0 @@ -1502,9 +1539,7 @@ def get_secondary_energy(n, region, _industry_demand): assert isclose( var["Secondary Energy|Hydrogen"], hydrogen_production[ - ~hydrogen_production.index.str.startswith( - "H2 pipeline" - ) + ~hydrogen_production.index.str.startswith("H2 pipeline") ].sum(), ) @@ -1561,8 +1596,6 @@ def get_secondary_energy(n, region, _industry_demand): except KeyError: var["Secondary Energy|Methanol"] = 0 - - gas_fuel_usage = ( n.statistics.withdrawal(bus_carrier="gas", **kwargs) .filter(like=region) @@ -1584,19 +1617,16 @@ def get_secondary_energy(n, region, _industry_demand): gas_fractions = _get_gas_fractions(n, region) # Fraction supplied by Hydrogen conversion - var["Secondary Energy|Gases|Hydrogen"] = ( - total_gas_fuel_usage - * gas_fractions.get("Efuel") + var["Secondary Energy|Gases|Hydrogen"] = total_gas_fuel_usage * gas_fractions.get( + "Efuel" ) - var["Secondary Energy|Gases|Biomass"] = ( - total_gas_fuel_usage - * gas_fractions.get("Biomass") + var["Secondary Energy|Gases|Biomass"] = total_gas_fuel_usage * gas_fractions.get( + "Biomass" ) var["Secondary Energy|Gases|Natural Gas"] = ( - total_gas_fuel_usage - * gas_fractions.get("Natural Gas") + total_gas_fuel_usage * gas_fractions.get("Natural Gas") ) var["Secondary Energy|Gases"] = ( @@ -1605,11 +1635,7 @@ def get_secondary_energy(n, region, _industry_demand): + var["Secondary Energy|Gases|Natural Gas"] ) - assert isclose( - var["Secondary Energy|Gases"], - total_gas_fuel_usage - ) - + assert isclose(var["Secondary Energy|Gases"], total_gas_fuel_usage) industry_demand = _industry_demand.filter( like=region, @@ -3349,8 +3375,11 @@ def get_prices(n, region): ) nodal_prices_gas = n.buses_t.marginal_price[nodal_flows_gas.columns] # TODO renewable gas prices - var["Price|Secondary Energy|Gases"] = \ - nodal_flows_gas.mul(nodal_prices_gas).values.sum() / nodal_flows_gas.values.sum() /MWh2GJ + var["Price|Secondary Energy|Gases"] = ( + nodal_flows_gas.mul(nodal_prices_gas).values.sum() + / nodal_flows_gas.values.sum() + / MWh2GJ + ) nodal_flows_oil = get_nodal_flows( n, @@ -3519,13 +3548,12 @@ def get_grid_investments(n, costs, region, dg_cost_factor=1.0, length_factor=1.0 ) # TODO add retrofitted costs!! - var["Investment|Energy Supply|Hydrogen|Transmission"] = \ - h2_costs.sum() / 5 + var["Investment|Energy Supply|Hydrogen|Transmission"] = h2_costs.sum() / 5 if "gas pipeline" in n.links.carrier.unique(): gas_links = n.links[ ( - ((n.links.carrier == "gas pipeline") & (n.links.build_year > 2020)) + ((n.links.carrier == "gas pipeline") & (n.links.build_year > 2020)) | (n.links.carrier == "gas pipeline new") ) & ~n.links.reversed @@ -3533,17 +3561,15 @@ def get_grid_investments(n, costs, region, dg_cost_factor=1.0, length_factor=1.0 ] year = n.links.build_year.max() new_gas_links = gas_links[ - ((year - 5) < gas_links.build_year) - & (gas_links.build_year <= year)] + ((year - 5) < gas_links.build_year) & (gas_links.build_year <= year) + ] gas_costs = ( - new_gas_links.length * new_gas_links.p_nom_opt.apply( - lambda x: get_discretized_value(x, 1200) - ) + new_gas_links.length + * new_gas_links.p_nom_opt.apply(lambda x: get_discretized_value(x, 1200)) * costs.at["CH4 (g) pipeline", "investment"] ) - var["Investment|Energy Supply|Gas|Transmission"] = \ - gas_costs.sum() / 5 + var["Investment|Energy Supply|Gas|Transmission"] = gas_costs.sum() / 5 # var["Investment|Energy Supply|Electricity|Electricity Storage"] = \ # var["Investment|Energy Supply|Hydrogen|Fossil"] = \ @@ -3723,13 +3749,18 @@ def get_export_import_links(n, region, carriers): gas_fractions = _get_gas_fractions(n, region) if "gas pipeline" in n.links.carrier.unique(): - exports_gas, imports_gas = get_export_import_links(n, region, ["gas pipeline", "gas pipeline new"]) - var["Trade|Primary Energy|Gas|Volume"] = \ - ((exports_gas - imports_gas) * MWh2PJ) * gas_fractions["Natural Gas"] - var["Trade|Primary Energy|Gas|Volume|Imports"] = \ + exports_gas, imports_gas = get_export_import_links( + n, region, ["gas pipeline", "gas pipeline new"] + ) + var["Trade|Primary Energy|Gas|Volume"] = ( + (exports_gas - imports_gas) * MWh2PJ + ) * gas_fractions["Natural Gas"] + var["Trade|Primary Energy|Gas|Volume|Imports"] = ( imports_gas * MWh2PJ * gas_fractions["Natural Gas"] - var["Trade|Primary Energy|Gas|Volume|Exports"] = \ + ) + var["Trade|Primary Energy|Gas|Volume|Exports"] = ( exports_gas * MWh2PJ * gas_fractions["Natural Gas"] + ) # Trade|Primary Energy|Oil|Volume @@ -4115,10 +4146,18 @@ def get_data( print("Assigning mean investments of year and year + 5 to year.") investment_rows = df.loc[df["Variable"].str.contains("Investment")] - average_investments = investment_rows[planning_horizons].add( - investment_rows[planning_horizons].shift(-1,axis=1)).div(2).fillna(0.0) - average_investments[planning_horizons[0]] += investment_rows[planning_horizons[0]].div(2) - average_investments[planning_horizons[-1]] += investment_rows[planning_horizons[-1]].div(2) + average_investments = ( + investment_rows[planning_horizons] + .add(investment_rows[planning_horizons].shift(-1, axis=1)) + .div(2) + .fillna(0.0) + ) + average_investments[planning_horizons[0]] += investment_rows[ + planning_horizons[0] + ].div(2) + average_investments[planning_horizons[-1]] += investment_rows[ + planning_horizons[-1] + ].div(2) df.loc[investment_rows.index, planning_horizons] = average_investments df["Region"] = df["Region"].str.replace("DE", "DEU") diff --git a/workflow/scripts/modify_prenetwork.py b/workflow/scripts/modify_prenetwork.py index f9498d4c..4c734be9 100644 --- a/workflow/scripts/modify_prenetwork.py +++ b/workflow/scripts/modify_prenetwork.py @@ -424,21 +424,23 @@ def unravel_oilbus(n): capital_cost=0.02, ) + def unravel_gasbus(n, costs): """ - Unravel European gas bus to enable energy balances for import of gas products. - + Unravel European gas bus to enable energy balances for import of gas + products. """ logger.info("Unraveling gas bus") ### create DE gas bus/generator/store - n.add("Bus", - "DE gas", - location="DE", - x=10.5, - y=51.2, - carrier="gas", - ) + n.add( + "Bus", + "DE gas", + location="DE", + x=10.5, + y=51.2, + carrier="gas", + ) n.add( "Generator", "DE gas", @@ -478,32 +480,35 @@ def unravel_gasbus(n, costs): ### biogas is counted as renewable gas biogas_carrier = ["biogas to gas", "biogas to gas CC"] - biogas_DE = n.links[(n.links.carrier.isin(biogas_carrier)) & - (n.links.index.str[:2] == "DE")] + biogas_DE = n.links[ + (n.links.carrier.isin(biogas_carrier)) & (n.links.index.str[:2] == "DE") + ] n.links.loc[biogas_DE.index, "bus1"] = "DE renewable gas" - biogas_EU = n.links[(n.links.carrier.isin(biogas_carrier)) & - (n.links.index.str[:2] != "DE")] + biogas_EU = n.links[ + (n.links.carrier.isin(biogas_carrier)) & (n.links.index.str[:2] != "DE") + ] n.links.loc[biogas_EU.index, "bus1"] = "EU renewable gas" ### Sabatier is counted as renewable gas sabatier_carrier = ["Sabatier"] - sabatier_DE = n.links[(n.links.carrier.isin(sabatier_carrier)) & - (n.links.index.str[:2] == "DE")] + sabatier_DE = n.links[ + (n.links.carrier.isin(sabatier_carrier)) & (n.links.index.str[:2] == "DE") + ] n.links.loc[sabatier_DE.index, "bus1"] = "DE renewable gas" - sabatier_EU = n.links[(n.links.carrier.isin(sabatier_carrier)) & - (n.links.index.str[:2] != "DE")] + sabatier_EU = n.links[ + (n.links.carrier.isin(sabatier_carrier)) & (n.links.index.str[:2] != "DE") + ] n.links.loc[sabatier_EU.index, "bus1"] = "EU renewable gas" - ### change buses of German gas links - fossil_links = n.links[(n.links.bus0 == "EU gas") & - (n.links.index.str[:2] == "DE")] + fossil_links = n.links[(n.links.bus0 == "EU gas") & (n.links.index.str[:2] == "DE")] n.links.loc[fossil_links.index, "bus0"] = "DE gas" - + ### add import/export links - n.madd("Link", + n.madd( + "Link", ["EU renewable gas -> DE gas", "DE renewable gas -> EU gas"], bus0=["EU renewable gas", "DE renewable gas"], bus1=["DE gas", "EU gas"], @@ -513,7 +518,8 @@ def unravel_gasbus(n, costs): ) ### add links between renewable and fossil gas buses - n.madd("Link", + n.madd( + "Link", ["EU renewable gas -> EU gas", "DE renewable gas -> DE gas"], bus0=["EU renewable gas", "DE renewable gas"], bus1=["EU gas", "DE gas"], @@ -522,6 +528,7 @@ def unravel_gasbus(n, costs): p_min_pu=0, ) + def transmission_costs_from_modified_cost_data( n, costs, transmission, length_factor=1.0 ):