diff --git a/config.default.yaml b/config.default.yaml index 156454543..aa8add2e7 100644 --- a/config.default.yaml +++ b/config.default.yaml @@ -519,6 +519,8 @@ sector: set_color_shares: false blue_share: 0.40 pink_share: 0.05 + production: ["H2 Electrolysis", "SMR", "SMR CC"] # ["Alkaline electrolyzer", "PEM electrolyzer", "SOEC", "Solid biomass steam reforming", "Biomass gasification", "Biomass gasification CC", "Natural gas steam reforming", "Natural gas steam reforming CC", "Coal gasification", "Coal gasification CC", "Heavy oil partial oxidation"] + coal: spatial_coal: true shift_to_elec: true # If true, residential and services demand of coal is shifted to electricity. If false, the final energy demand of coal is disregarded @@ -669,8 +671,6 @@ sector: methanation: true helmeth: true dac: true - SMR: true - SMR CC: true cc_fraction: 0.9 cc: true space_heat_share: 0.6 # the share of space heating from all heating. Remainder goes to water heating. diff --git a/scripts/prepare_sector_network.py b/scripts/prepare_sector_network.py index 01ab70a7b..a5ae576de 100644 --- a/scripts/prepare_sector_network.py +++ b/scripts/prepare_sector_network.py @@ -199,51 +199,234 @@ def add_hydrogen(n, costs): y=n.buses.loc[list(spatial.nodes)].y.values, ) - if snakemake.config["sector"]["hydrogen"]["hydrogen_colors"]: - n.madd( - "Bus", - nodes + " grid H2", - location=nodes, - carrier="grid H2", - x=n.buses.loc[list(nodes)].x.values, - y=n.buses.loc[list(nodes)].y.values, - ) + # Read hydrogen production options + h2_options = options.get("hydrogen", {}) + h2_techs = h2_options.get("production", []) + # H2 production technologies by color + green_h2_techs = [ + "H2 Electrolysis", + "Alkaline electrolyzer", + "PEM electrolyzer", + "SOEC", + "Solid biomass steam reforming", + "Biomass gasification", + "Biomass gasification CC", + ] + grey_h2_techs = [ + "SMR", + "Natural gas steam reforming", + "Coal gasification", + "Heavy oil partial oxidation", + ] + blue_h2_techs = ["SMR CC", "Natural gas steam reforming CC", "Coal gasification CC"] + + # Dictionary containing distinct parameters of H2 production technologies + tech_params = { + "H2 Electrolysis": {"bus1": spatial.nodes + " grid H2"}, + "Alkaline electrolyzer": {"bus1": spatial.nodes + " grid H2"}, + "PEM electrolyzer": {"bus1": spatial.nodes + " grid H2"}, + "SOEC": {"bus1": spatial.nodes + " grid H2"}, + "Solid biomass steam reforming": { + "bus0": spatial.biomass.nodes, + "bus1": spatial.nodes + " grid H2", + "efficiency2": costs.at["solid biomass", "CO2 intensity"], + }, + "Biomass gasification": { + "bus0": spatial.biomass.nodes, + "bus1": spatial.nodes + " grid H2", + "efficiency2": costs.at["solid biomass", "CO2 intensity"], + }, + "Biomass gasification CC": { + "bus0": spatial.biomass.nodes, + "bus1": spatial.nodes + " grid H2", + "bus3": spatial.co2.nodes, + "efficiency2": costs.at["solid biomass", "CO2 intensity"] + * (1 - options["cc_fraction"]), + "efficiency3": costs.at["solid biomass", "CO2 intensity"] + * options["cc_fraction"], + }, + "SMR": { + "bus0": spatial.gas.nodes, + "bus1": spatial.nodes + " grey H2", + "efficiency2": costs.at["gas", "CO2 intensity"], + }, + "SMR CC": { + "bus0": spatial.gas.nodes, + "bus1": spatial.nodes + " blue H2", + "efficiency2": costs.at["gas", "CO2 intensity"] + * (1 - options["cc_fraction"]), + "efficiency3": costs.at["gas", "CO2 intensity"] * options["cc_fraction"], + }, + "Natural gas steam reforming": { + "bus0": spatial.gas.nodes, + "bus1": spatial.nodes + " grey H2", + "efficiency2": costs.at["gas", "CO2 intensity"], + }, + "Natural gas steam reforming CC": { + "bus0": spatial.gas.nodes, + "bus1": spatial.nodes + " blue H2", + "efficiency2": costs.at["gas", "CO2 intensity"] + * (1 - options["cc_fraction"]), + "efficiency3": costs.at["gas", "CO2 intensity"] * options["cc_fraction"], + }, + "Coal gasification": { + "bus0": spatial.coal.nodes, + "bus1": spatial.nodes + " grey H2", + "efficiency2": costs.at["coal", "CO2 intensity"], + }, + "Coal gasification CC": { + "bus0": spatial.coal.nodes, + "bus1": spatial.nodes + " blue H2", + "bus3": spatial.co2.nodes, + "efficiency2": costs.at["coal", "CO2 intensity"] + * (1 - options["cc_fraction"]), + "efficiency3": costs.at["coal", "CO2 intensity"] * options["cc_fraction"], + }, + "Heavy oil partial oxidation": { + "bus0": spatial.oil.nodes, + "bus1": spatial.nodes + " grey H2", + "efficiency2": costs.at["oil", "CO2 intensity"], + }, + } + + if h2_options.get("hydrogen_colors", False): + # Add infrastructure for green hydrogen + if set(h2_techs) & set(green_h2_techs): + n.madd( + "Bus", + nodes + " grid H2", + location=nodes, + carrier="grid H2", + x=n.buses.loc[list(nodes)].x.values, + y=n.buses.loc[list(nodes)].y.values, + ) - n.madd( - "Link", - nodes + " H2 Electrolysis", - bus0=nodes, - bus1=nodes + " grid H2", - p_nom_extendable=True, - carrier="H2 Electrolysis", - efficiency=costs.at["electrolysis", "efficiency"], - capital_cost=costs.at["electrolysis", "fixed"], - lifetime=costs.at["electrolysis", "lifetime"], - ) + n.madd( + "Link", + nodes + " grid H2", + bus0=nodes + " grid H2", + bus1=nodes + " H2", + p_nom_extendable=True, + carrier="grid H2", + efficiency=1, + capital_cost=0, + ) - n.madd( - "Link", - nodes + " grid H2", - bus0=nodes + " grid H2", - bus1=nodes + " H2", - p_nom_extendable=True, - carrier="grid H2", - efficiency=1, - capital_cost=0, - ) + # Add infrastructure for grey hydrogen + if set(h2_techs) & set(grey_h2_techs): + n.madd( + "Bus", + spatial.nodes + " grey H2", + location=spatial.nodes, + carrier="grey H2", + x=n.buses.loc[list(spatial.nodes)].x.values, + y=n.buses.loc[list(spatial.nodes)].y.values, + ) - else: - n.madd( - "Link", - nodes + " H2 Electrolysis", - bus1=nodes + " H2", - bus0=nodes, - p_nom_extendable=True, - carrier="H2 Electrolysis", - efficiency=costs.at["electrolysis", "efficiency"], - capital_cost=costs.at["electrolysis", "fixed"], - lifetime=costs.at["electrolysis", "lifetime"], - ) + n.madd( + "Link", + spatial.nodes + " grey H2", + bus0=spatial.nodes + " grey H2", + bus1=spatial.nodes + " H2", + carrier="grey H2", + capital_cost=0, + p_nom_extendable=True, + # lifetime=costs.at["battery inverter", "lifetime"], + ) + + # Add infrastructure for blue hydrogen + if set(h2_techs) & set(blue_h2_techs): + n.madd( + "Bus", + spatial.nodes + " blue H2", + location=spatial.nodes, + carrier="blue H2", + x=n.buses.loc[list(spatial.nodes)].x.values, + y=n.buses.loc[list(spatial.nodes)].y.values, + ) + + n.madd( + "Link", + spatial.nodes + " blue H2", + bus0=spatial.nodes + " blue H2", + bus1=spatial.nodes + " H2", + carrier="blue H2", + capital_cost=0, + p_nom_extendable=True, + # lifetime=costs.at["battery inverter", "lifetime"], + ) + + # Add hydrogen production technologies + for h2_tech in h2_techs: + # Set H2 buses as production output if colors are not used + if not h2_options.get("hydrogen_colors", False): + tech_params[h2_tech]["bus1"] = spatial.nodes + " H2" + + # Add electrolysis based green H2 production technologies (links with 2 buses) + if h2_tech in [ + "H2 Electrolysis", + "Alkaline electrolyzer", + "PEM electrolyzer", + "SOEC", + ]: + # H2 production technology name in costs file + costs_name = "electrolysis" if h2_tech == "H2 Electrolysis" else h2_tech + + n.madd( + "Link", + nodes + " " + h2_tech, + bus0=spatial.nodes, + bus1=tech_params[h2_tech]["bus1"], + p_nom_extendable=True, + carrier=h2_tech, + efficiency=costs.at[costs_name, "efficiency"], + capital_cost=costs.at[costs_name, "fixed"], + lifetime=costs.at[costs_name, "lifetime"], + ) + # Add H2 production technologies without carbon capture technologies (links with 3 buses) + if h2_tech in [ + "Solid biomass steam reforming", + "Biomass gasification", + "SMR", + "Natural gas steam reforming", + "Coal gasification", + "Heavy oil partial oxidation", + ]: + n.madd( + "Link", + spatial.nodes + " " + h2_tech, + bus0=tech_params[h2_tech]["bus0"], + bus1=tech_params[h2_tech]["bus1"], + bus2="co2 atmosphere", + p_nom_extendable=True, + carrier=h2_tech, + efficiency=costs.at[h2_tech, "efficiency"], + efficiency2=tech_params[h2_tech]["efficiency2"], + capital_cost=costs.at[h2_tech, "fixed"], + lifetime=costs.at[h2_tech, "lifetime"], + ) + # Add H2 production technologies with carbon capture technologies (links with 4 buses) + if h2_tech in [ + "SMR CC", + "Biomass gasification CC", + "Natural gas steam reforming CC", + "Coal gasification CC", + ]: + n.madd( + "Link", + spatial.nodes + " " + h2_tech, + bus0=tech_params[h2_tech]["bus0"], + bus1=tech_params[h2_tech]["bus1"], + bus2="co2 atmosphere", + bus3=spatial.co2.nodes, + p_nom_extendable=True, + carrier=h2_tech, + efficiency=costs.at[h2_tech, "efficiency"], + efficiency2=tech_params[h2_tech]["efficiency2"], + efficiency3=tech_params[h2_tech]["efficiency3"], + capital_cost=costs.at[h2_tech, "fixed"], + lifetime=costs.at[h2_tech, "lifetime"], + ) n.madd( "Link", @@ -1170,116 +1353,6 @@ def h2_hc_conversions(n, costs): lifetime=costs.at["helmeth", "lifetime"], ) - if options["SMR CC"]: - if snakemake.config["sector"]["hydrogen"]["hydrogen_colors"]: - n.madd( - "Bus", - spatial.nodes + " blue H2", - location=spatial.nodes, - carrier="blue H2", - x=n.buses.loc[list(spatial.nodes)].x.values, - y=n.buses.loc[list(spatial.nodes)].y.values, - ) - - n.madd( - "Link", - spatial.nodes, - suffix=" SMR CC", - bus0=spatial.gas.nodes, - bus1=spatial.nodes + " blue H2", - bus2="co2 atmosphere", - bus3=spatial.co2.nodes, - p_nom_extendable=True, - carrier="SMR CC", - efficiency=costs.at["SMR CC", "efficiency"], - efficiency2=costs.at["gas", "CO2 intensity"] - * (1 - options["cc_fraction"]), - efficiency3=costs.at["gas", "CO2 intensity"] * options["cc_fraction"], - capital_cost=costs.at["SMR CC", "fixed"], - lifetime=costs.at["SMR CC", "lifetime"], - ) - - n.madd( - "Link", - spatial.nodes + " blue H2", - bus0=spatial.nodes + " blue H2", - bus1=spatial.nodes + " H2", - carrier="blue H2", - capital_cost=0, - p_nom_extendable=True, - # lifetime=costs.at["battery inverter", "lifetime"], - ) - - else: - n.madd( - "Link", - spatial.nodes, - suffix=" SMR CC", - bus0=spatial.gas.nodes, - bus1=spatial.nodes + " H2", - bus2="co2 atmosphere", - bus3=spatial.co2.nodes, - p_nom_extendable=True, - carrier="SMR CC", - efficiency=costs.at["SMR CC", "efficiency"], - efficiency2=costs.at["gas", "CO2 intensity"] - * (1 - options["cc_fraction"]), - efficiency3=costs.at["gas", "CO2 intensity"] * options["cc_fraction"], - capital_cost=costs.at["SMR CC", "fixed"], - lifetime=costs.at["SMR CC", "lifetime"], - ) - - if options["SMR"]: - if snakemake.config["sector"]["hydrogen"]["hydrogen_colors"]: - n.madd( - "Bus", - spatial.nodes + " grey H2", - location=spatial.nodes, - carrier="grey H2", - x=n.buses.loc[list(spatial.nodes)].x.values, - y=n.buses.loc[list(spatial.nodes)].y.values, - ) - - n.madd( - "Link", - spatial.nodes + " SMR", - bus0=spatial.gas.nodes, - bus1=spatial.nodes + " grey H2", - bus2="co2 atmosphere", - p_nom_extendable=True, - carrier="SMR", - efficiency=costs.at["SMR", "efficiency"], - efficiency2=costs.at["gas", "CO2 intensity"], - capital_cost=costs.at["SMR", "fixed"], - lifetime=costs.at["SMR", "lifetime"], - ) - - n.madd( - "Link", - spatial.nodes + " grey H2", - bus0=spatial.nodes + " grey H2", - bus1=spatial.nodes + " H2", - carrier="grey H2", - capital_cost=0, - p_nom_extendable=True, - # lifetime=costs.at["battery inverter", "lifetime"], - ) - - else: - n.madd( - "Link", - spatial.nodes + " SMR", - bus0=spatial.gas.nodes, - bus1=spatial.nodes + " H2", - bus2="co2 atmosphere", - p_nom_extendable=True, - carrier="SMR", - efficiency=costs.at["SMR", "efficiency"], - efficiency2=costs.at["gas", "CO2 intensity"], - capital_cost=costs.at["SMR", "fixed"], - lifetime=costs.at["SMR", "lifetime"], - ) - def add_shipping(n, costs): ports = pd.read_csv(