options: biosng_cc, biomass_to_liquid_cc, 98% capture rate Allam gas,… (#1298)
* options: biosng_cc, biomass_to_liquid_cc, 98% capture rate Allam gas, avoid option.get * fix duplicated bus port
This commit is contained in:
parent
df71b1a64c
commit
d8f8a828f9
@ -693,8 +693,10 @@ sector:
|
||||
conventional_generation:
|
||||
OCGT: gas
|
||||
biomass_to_liquid: false
|
||||
biomass_to_liquid_cc: false
|
||||
electrobiofuels: false
|
||||
biosng: false
|
||||
biosng_cc: false
|
||||
bioH2: false
|
||||
municipal_solid_waste: false
|
||||
limit_max_growth:
|
||||
|
@ -167,7 +167,9 @@ biomass_transport,--,"{true, false}",Add option for transporting solid biomass b
|
||||
biogas_upgrading_cc,--,"{true, false}",Add option to capture CO2 from biomass upgrading
|
||||
conventional_generation,,,Add a more detailed description of conventional carriers. Any power generation requires the consumption of fuel from nodes representing that fuel.
|
||||
biomass_to_liquid,--,"{true, false}",Add option for transforming solid biomass into liquid fuel with the same properties as oil
|
||||
biomass_to_liquid_cc,--,"{true, false}",Add option for transforming solid biomass into liquid fuel with the same properties as oil with carbon capture
|
||||
biosng,--,"{true, false}",Add option for transforming solid biomass into synthesis gas with the same properties as natural gas
|
||||
biosng_cc,--,"{true, false}",Add option for transforming solid biomass into synthesis gas with the same properties as natural gas with carbon capture
|
||||
bioH2,--,"{true, false}",Add option for transforming solid biomass into hydrogen with carbon capture
|
||||
municipal_solid_waste,--,"{true, false}",Add option for municipal solid waste
|
||||
limit_max_growth,,,
|
||||
|
|
@ -68,6 +68,11 @@ Upcoming Release
|
||||
defaults to 10 km. Previously the distance to the region's centroid was
|
||||
used, which is not practical when the regions are already aggregated.
|
||||
|
||||
* Added options ``biosng_cc`` and ``biomass_to_liquid_cc`` to separate the base
|
||||
technology from the option to capture carbon from it.
|
||||
|
||||
* Added 98% imperfect capture rate of Allam cycle gas turbine.
|
||||
|
||||
PyPSA-Eur 0.13.0 (13th September 2024)
|
||||
======================================
|
||||
|
||||
|
@ -132,9 +132,9 @@ def define_spatial(nodes, options):
|
||||
|
||||
# ammonia
|
||||
|
||||
if options.get("ammonia"):
|
||||
if options["ammonia"]:
|
||||
spatial.ammonia = SimpleNamespace()
|
||||
if options.get("ammonia") == "regional":
|
||||
if options["ammonia"] == "regional":
|
||||
spatial.ammonia.nodes = nodes + " NH3"
|
||||
spatial.ammonia.locations = nodes
|
||||
else:
|
||||
@ -519,7 +519,7 @@ def add_carrier_buses(n, carrier, nodes=None):
|
||||
)
|
||||
|
||||
fossils = ["coal", "gas", "oil", "lignite"]
|
||||
if options.get("fossil_fuels", True) and carrier in fossils:
|
||||
if options["fossil_fuels"] and carrier in fossils:
|
||||
|
||||
suffix = ""
|
||||
|
||||
@ -750,7 +750,7 @@ def add_co2_network(n, costs):
|
||||
)
|
||||
|
||||
|
||||
def add_allam(n, costs):
|
||||
def add_allam_gas(n, costs):
|
||||
logger.info("Adding Allam cycle gas power plants.")
|
||||
|
||||
nodes = pop_layout.index
|
||||
@ -758,17 +758,18 @@ def add_allam(n, costs):
|
||||
n.madd(
|
||||
"Link",
|
||||
nodes,
|
||||
suffix=" allam",
|
||||
suffix=" allam gas",
|
||||
bus0=spatial.gas.df.loc[nodes, "nodes"].values,
|
||||
bus1=nodes,
|
||||
bus2=spatial.co2.df.loc[nodes, "nodes"].values,
|
||||
carrier="allam",
|
||||
bus3="co2 atmosphere",
|
||||
carrier="allam gas",
|
||||
p_nom_extendable=True,
|
||||
# TODO: add costs to technology-data
|
||||
capital_cost=costs.at["allam", "fixed"] * costs.at["allam", "efficiency"],
|
||||
marginal_cost=costs.at["allam", "VOM"] * costs.at["allam", "efficiency"],
|
||||
efficiency=costs.at["allam", "efficiency"],
|
||||
efficiency2=costs.at["gas", "CO2 intensity"],
|
||||
efficiency2=0.98 * costs.at["gas", "CO2 intensity"],
|
||||
efficiency3=0.02 * costs.at["gas", "CO2 intensity"],
|
||||
lifetime=costs.at["allam", "lifetime"],
|
||||
)
|
||||
|
||||
@ -823,8 +824,10 @@ def add_biomass_to_methanol_cc(n, costs):
|
||||
)
|
||||
|
||||
|
||||
def add_methanol_to_power(n, costs, types={}):
|
||||
# TODO: add costs to technology-data
|
||||
def add_methanol_to_power(n, costs, types=None):
|
||||
|
||||
if types is None:
|
||||
types = {}
|
||||
|
||||
nodes = pop_layout.index
|
||||
|
||||
@ -1121,8 +1124,7 @@ def add_generation(n, costs):
|
||||
|
||||
nodes = pop_layout.index
|
||||
|
||||
fallback = {"OCGT": "gas"}
|
||||
conventionals = options.get("conventional_generation", fallback)
|
||||
conventionals = options["conventional_generation"]
|
||||
|
||||
for generator, carrier in conventionals.items():
|
||||
carrier_nodes = vars(spatial)[carrier].nodes
|
||||
@ -1564,7 +1566,7 @@ def add_storage_and_grids(n, costs):
|
||||
complement_edges["length"] = complement_edges.apply(haversine, axis=1)
|
||||
|
||||
# apply k_edge_augmentation weighted by length of complement edges
|
||||
k_edge = options.get("gas_network_connectivity_upgrade", 3)
|
||||
k_edge = options["gas_network_connectivity_upgrade"]
|
||||
if augmentation := list(
|
||||
k_edge_augmentation(G, k_edge, avail=complement_edges.values)
|
||||
):
|
||||
@ -1612,7 +1614,7 @@ def add_storage_and_grids(n, costs):
|
||||
lifetime=costs.at["H2 (g) pipeline repurposed", "lifetime"],
|
||||
)
|
||||
|
||||
if options.get("H2_network", True):
|
||||
if options["H2_network"]:
|
||||
logger.info("Add options for new hydrogen pipelines.")
|
||||
|
||||
h2_pipes = create_network_topology(
|
||||
@ -1682,7 +1684,7 @@ def add_storage_and_grids(n, costs):
|
||||
bus2=spatial.co2.nodes,
|
||||
p_nom_extendable=True,
|
||||
carrier="Sabatier",
|
||||
p_min_pu=options.get("min_part_load_methanation", 0),
|
||||
p_min_pu=options["min_part_load_methanation"],
|
||||
efficiency=costs.at["methanation", "efficiency"],
|
||||
efficiency2=-costs.at["methanation", "efficiency"]
|
||||
* costs.at["gas", "CO2 intensity"],
|
||||
@ -1691,7 +1693,7 @@ def add_storage_and_grids(n, costs):
|
||||
lifetime=costs.at["methanation", "lifetime"],
|
||||
)
|
||||
|
||||
if options.get("coal_cc"):
|
||||
if options["coal_cc"]:
|
||||
n.madd(
|
||||
"Link",
|
||||
spatial.nodes,
|
||||
@ -1835,7 +1837,7 @@ def add_EVs(
|
||||
p_set=profile,
|
||||
)
|
||||
|
||||
p_nom = number_cars * options.get("bev_charge_rate", 0.011) * electric_share
|
||||
p_nom = number_cars * options["bev_charge_rate"] * electric_share
|
||||
|
||||
n.madd(
|
||||
"Link",
|
||||
@ -1847,7 +1849,7 @@ def add_EVs(
|
||||
carrier="BEV charger",
|
||||
p_max_pu=avail_profile[spatial.nodes],
|
||||
lifetime=1,
|
||||
efficiency=options.get("bev_charge_efficiency", 0.9),
|
||||
efficiency=options["bev_charge_efficiency"],
|
||||
)
|
||||
|
||||
if options["v2g"]:
|
||||
@ -1861,13 +1863,13 @@ def add_EVs(
|
||||
carrier="V2G",
|
||||
p_max_pu=avail_profile[spatial.nodes],
|
||||
lifetime=1,
|
||||
efficiency=options.get("bev_charge_efficiency", 0.9),
|
||||
efficiency=options["bev_charge_efficiency"],
|
||||
)
|
||||
|
||||
if options["bev_dsm"]:
|
||||
e_nom = (
|
||||
number_cars
|
||||
* options.get("bev_energy", 0.05)
|
||||
* options["bev_energy"]
|
||||
* options["bev_availability"]
|
||||
* electric_share
|
||||
)
|
||||
@ -2116,7 +2118,7 @@ def add_heat(n: pypsa.Network, costs: pd.DataFrame, cop: xr.DataArray):
|
||||
unit="MWh_th",
|
||||
)
|
||||
|
||||
if heat_system == HeatSystem.URBAN_CENTRAL and options.get("central_heat_vent"):
|
||||
if heat_system == HeatSystem.URBAN_CENTRAL and options["central_heat_vent"]:
|
||||
n.madd(
|
||||
"Generator",
|
||||
nodes + f" {heat_system} heat vent",
|
||||
@ -2786,7 +2788,7 @@ def add_biomass(n, costs):
|
||||
p_nom_extendable=True,
|
||||
)
|
||||
|
||||
if options.get("biogas_upgrading_cc"):
|
||||
if options["biogas_upgrading_cc"]:
|
||||
# Assuming for costs that the CO2 from upgrading is pure, such as in amine scrubbing. I.e., with and without CC is
|
||||
# equivalent. Adding biomass CHP capture because biogas is often small-scale and decentral so further
|
||||
# from e.g. CO2 grid or buyers. This is a proxy for the added cost for e.g. a raw biogas pipeline to a central upgrading facility
|
||||
@ -3034,6 +3036,8 @@ def add_biomass(n, costs):
|
||||
marginal_cost=costs.at["BtL", "VOM"] * costs.at["BtL", "efficiency"],
|
||||
)
|
||||
|
||||
# Solid biomass to liquid fuel with carbon capture
|
||||
if options["biomass_to_liquid_cc"]:
|
||||
# Assuming that acid gas removal (incl. CO2) from syngas i performed with Rectisol
|
||||
# process (Methanol) and that electricity demand for this is included in the base process
|
||||
n.madd(
|
||||
@ -3044,7 +3048,7 @@ def add_biomass(n, costs):
|
||||
bus1=spatial.oil.nodes,
|
||||
bus2="co2 atmosphere",
|
||||
bus3=spatial.co2.nodes,
|
||||
carrier="biomass to liquid",
|
||||
carrier="biomass to liquid CC",
|
||||
lifetime=costs.at["BtL", "lifetime"],
|
||||
efficiency=costs.at["BtL", "efficiency"],
|
||||
efficiency2=-costs.at["solid biomass", "CO2 intensity"]
|
||||
@ -3112,6 +3116,8 @@ def add_biomass(n, costs):
|
||||
marginal_cost=costs.at["BioSNG", "VOM"] * costs.at["BioSNG", "efficiency"],
|
||||
)
|
||||
|
||||
# BioSNG from solid biomass with carbon capture
|
||||
if options["biosng_cc"]:
|
||||
# Assuming that acid gas removal (incl. CO2) from syngas i performed with Rectisol
|
||||
# process (Methanol) and that electricity demand for this is included in the base process
|
||||
n.madd(
|
||||
@ -3122,7 +3128,7 @@ def add_biomass(n, costs):
|
||||
bus1=spatial.gas.nodes,
|
||||
bus2=spatial.co2.nodes,
|
||||
bus3="co2 atmosphere",
|
||||
carrier="BioSNG",
|
||||
carrier="BioSNG CC",
|
||||
lifetime=costs.at["BioSNG", "lifetime"],
|
||||
efficiency=costs.at["BioSNG", "efficiency"],
|
||||
efficiency2=costs.at["BioSNG", "CO2 stored"]
|
||||
@ -3162,10 +3168,6 @@ def add_biomass(n, costs):
|
||||
* costs.at["solid biomass to hydrogen", "efficiency"]
|
||||
+ costs.at["biomass CHP capture", "fixed"]
|
||||
* costs.at["solid biomass", "CO2 intensity"],
|
||||
overnight_cost=costs.at["solid biomass to hydrogen", "investment"]
|
||||
* costs.at["solid biomass to hydrogen", "efficiency"]
|
||||
+ costs.at["biomass CHP capture", "investment"]
|
||||
* costs.at["solid biomass", "CO2 intensity"],
|
||||
marginal_cost=0.0,
|
||||
)
|
||||
|
||||
@ -3356,7 +3358,7 @@ def add_industry(n, costs):
|
||||
bus3=spatial.co2.nodes,
|
||||
carrier="methanolisation",
|
||||
p_nom_extendable=True,
|
||||
p_min_pu=options.get("min_part_load_methanolisation", 0),
|
||||
p_min_pu=options["min_part_load_methanolisation"],
|
||||
capital_cost=costs.at["methanolisation", "fixed"]
|
||||
* options["MWh_MeOH_per_MWh_H2"], # EUR/MW_H2/a
|
||||
marginal_cost=options["MWh_MeOH_per_MWh_H2"]
|
||||
@ -3552,12 +3554,12 @@ def add_industry(n, costs):
|
||||
efficiency2=-costs.at["oil", "CO2 intensity"]
|
||||
* costs.at["Fischer-Tropsch", "efficiency"],
|
||||
p_nom_extendable=True,
|
||||
p_min_pu=options.get("min_part_load_fischer_tropsch", 0),
|
||||
p_min_pu=options["min_part_load_fischer_tropsch"],
|
||||
lifetime=costs.at["Fischer-Tropsch", "lifetime"],
|
||||
)
|
||||
|
||||
# naphtha
|
||||
demand_factor = options.get("HVC_demand_factor", 1)
|
||||
demand_factor = options["HVC_demand_factor"]
|
||||
if demand_factor != 1:
|
||||
logger.warning(f"Changing HVC demand by {demand_factor*100-100:+.2f}%.")
|
||||
|
||||
@ -3630,7 +3632,7 @@ def add_industry(n, costs):
|
||||
efficiency3=process_co2_per_naphtha,
|
||||
)
|
||||
|
||||
if options.get("biomass", True) and options["municipal_solid_waste"]:
|
||||
if options["biomass"] and options["municipal_solid_waste"]:
|
||||
n.madd(
|
||||
"Link",
|
||||
spatial.msw.locations,
|
||||
@ -3722,7 +3724,7 @@ def add_industry(n, costs):
|
||||
)
|
||||
|
||||
# aviation
|
||||
demand_factor = options.get("aviation_demand_factor", 1)
|
||||
demand_factor = options["aviation_demand_factor"]
|
||||
if demand_factor != 1:
|
||||
logger.warning(f"Changing aviation demand by {demand_factor*100-100:+.2f}%.")
|
||||
|
||||
@ -3862,7 +3864,7 @@ def add_industry(n, costs):
|
||||
lifetime=costs.at["cement capture", "lifetime"],
|
||||
)
|
||||
|
||||
if options.get("ammonia"):
|
||||
if options["ammonia"]:
|
||||
if options["ammonia"] == "regional":
|
||||
p_set = (
|
||||
industrial_demand.loc[spatial.ammonia.locations, "ammonia"].rename(
|
||||
@ -4639,8 +4641,8 @@ if __name__ == "__main__":
|
||||
if options["co2network"]:
|
||||
add_co2_network(n, costs)
|
||||
|
||||
if options["allam_cycle"]:
|
||||
add_allam(n, costs)
|
||||
if options["allam_cycle_gas"]:
|
||||
add_allam_gas(n, costs)
|
||||
|
||||
n = set_temporal_aggregation(
|
||||
n, snakemake.params.time_resolution, snakemake.input.snapshot_weightings
|
||||
@ -4701,7 +4703,7 @@ if __name__ == "__main__":
|
||||
snakemake.params.planning_horizons[0] == investment_year
|
||||
)
|
||||
|
||||
if options.get("cluster_heat_buses", False) and not first_year_myopic:
|
||||
if options["cluster_heat_buses"] and not first_year_myopic:
|
||||
cluster_heat_buses(n)
|
||||
|
||||
maybe_adjust_costs_and_potentials(
|
||||
|
Loading…
Reference in New Issue
Block a user