restructure to links without temperature correction
This commit is contained in:
parent
b70aa59dce
commit
548a99f273
@ -24,6 +24,7 @@ from _helpers import (
|
|||||||
)
|
)
|
||||||
from add_electricity import calculate_annuity, sanitize_carriers, sanitize_locations
|
from add_electricity import calculate_annuity, sanitize_carriers, sanitize_locations
|
||||||
from build_energy_totals import build_co2_totals, build_eea_co2, build_eurostat_co2
|
from build_energy_totals import build_co2_totals, build_eea_co2, build_eurostat_co2
|
||||||
|
from build_transport_demand import transport_degree_factor
|
||||||
from networkx.algorithms import complement
|
from networkx.algorithms import complement
|
||||||
from networkx.algorithms.connectivity.edge_augmentation import k_edge_augmentation
|
from networkx.algorithms.connectivity.edge_augmentation import k_edge_augmentation
|
||||||
from prepare_network import maybe_adjust_costs_and_potentials
|
from prepare_network import maybe_adjust_costs_and_potentials
|
||||||
@ -1502,41 +1503,18 @@ def add_storage_and_grids(n, costs):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_land_transport(n, costs):
|
def check_land_transport_shares(shares):
|
||||||
# TODO options?
|
# Sums up the shares, ignoring None values
|
||||||
|
total_share = sum(filter(None, shares))
|
||||||
logger.info("Add land transport")
|
|
||||||
|
|
||||||
transport = pd.read_csv(
|
|
||||||
snakemake.input.transport_demand, index_col=0, parse_dates=True
|
|
||||||
)
|
|
||||||
number_cars = pd.read_csv(snakemake.input.transport_data, index_col=0)[
|
|
||||||
"number cars"
|
|
||||||
]
|
|
||||||
avail_profile = pd.read_csv(
|
|
||||||
snakemake.input.avail_profile, index_col=0, parse_dates=True
|
|
||||||
)
|
|
||||||
dsm_profile = pd.read_csv(
|
|
||||||
snakemake.input.dsm_profile, index_col=0, parse_dates=True
|
|
||||||
)
|
|
||||||
|
|
||||||
fuel_cell_share = get(options["land_transport_fuel_cell_share"], investment_year)
|
|
||||||
electric_share = get(options["land_transport_electric_share"], investment_year)
|
|
||||||
ice_share = get(options["land_transport_ice_share"], investment_year)
|
|
||||||
|
|
||||||
total_share = fuel_cell_share + electric_share + ice_share
|
|
||||||
if total_share != 1:
|
if total_share != 1:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Total land transport shares sum up to {total_share:.2%}, corresponding to increased or decreased demand assumptions."
|
f"Total land transport shares sum up to {total_share:.2%},"
|
||||||
|
"corresponding to increased or decreased demand assumptions."
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"FCEV share: {fuel_cell_share*100}%")
|
def add_EVs(n, nodes, avail_profile, dsm_profile, p_set, electric_share,
|
||||||
logger.info(f"EV share: {electric_share*100}%")
|
number_cars, temperature):
|
||||||
logger.info(f"ICEV share: {ice_share*100}%")
|
|
||||||
|
|
||||||
nodes = pop_layout.index
|
|
||||||
|
|
||||||
if electric_share > 0:
|
|
||||||
n.add("Carrier", "Li ion")
|
n.add("Carrier", "Li ion")
|
||||||
|
|
||||||
n.madd(
|
n.madd(
|
||||||
@ -1548,25 +1526,33 @@ def add_land_transport(n, costs):
|
|||||||
unit="MWh_el",
|
unit="MWh_el",
|
||||||
)
|
)
|
||||||
|
|
||||||
p_set = (
|
# temperature correction for EVs
|
||||||
electric_share
|
dd_EV = transport_degree_factor(
|
||||||
* (
|
temperature,
|
||||||
transport[nodes]
|
options["transport_heating_deadband_lower"],
|
||||||
+ cycling_shift(transport[nodes], 1)
|
options["transport_heating_deadband_upper"],
|
||||||
+ cycling_shift(transport[nodes], 2)
|
options["EV_lower_degree_factor"],
|
||||||
)
|
options["EV_upper_degree_factor"],
|
||||||
/ 3
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
profile = p_set/p_set.max()
|
||||||
|
efficiency = costs.at['Battery electric (passenger cars)', 'efficiency']
|
||||||
|
|
||||||
n.madd(
|
n.madd(
|
||||||
"Load",
|
"Link",
|
||||||
nodes,
|
nodes,
|
||||||
suffix=" land transport EV",
|
suffix=" land transport EV",
|
||||||
bus=nodes + " EV battery",
|
bus0=nodes + " EV battery",
|
||||||
|
bus1=nodes + " land transport",
|
||||||
carrier="land transport EV",
|
carrier="land transport EV",
|
||||||
p_set=p_set,
|
efficiency=efficiency,
|
||||||
|
p_min_pu=profile,
|
||||||
|
p_max_pu=profile,
|
||||||
|
p_nom=electric_share*p_set.max()/efficiency,
|
||||||
|
p_nom_extendable=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
p_nom = number_cars * options.get("bev_charge_rate", 0.011) * electric_share
|
p_nom = number_cars * options.get("bev_charge_rate", 0.011) * electric_share
|
||||||
|
|
||||||
n.madd(
|
n.madd(
|
||||||
@ -1579,13 +1565,9 @@ def add_land_transport(n, costs):
|
|||||||
carrier="BEV charger",
|
carrier="BEV charger",
|
||||||
p_max_pu=avail_profile[nodes],
|
p_max_pu=avail_profile[nodes],
|
||||||
efficiency=options.get("bev_charge_efficiency", 0.9),
|
efficiency=options.get("bev_charge_efficiency", 0.9),
|
||||||
# These were set non-zero to find LU infeasibility when availability = 0.25
|
|
||||||
# p_nom_extendable=True,
|
|
||||||
# p_nom_min=p_nom,
|
|
||||||
# capital_cost=1e6, #i.e. so high it only gets built where necessary
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if electric_share > 0 and options["v2g"]:
|
if options["v2g"]:
|
||||||
n.madd(
|
n.madd(
|
||||||
"Link",
|
"Link",
|
||||||
nodes,
|
nodes,
|
||||||
@ -1598,7 +1580,7 @@ def add_land_transport(n, costs):
|
|||||||
efficiency=options.get("bev_charge_efficiency", 0.9),
|
efficiency=options.get("bev_charge_efficiency", 0.9),
|
||||||
)
|
)
|
||||||
|
|
||||||
if electric_share > 0 and options["bev_dsm"]:
|
if options["bev_dsm"]:
|
||||||
e_nom = (
|
e_nom = (
|
||||||
number_cars
|
number_cars
|
||||||
* options.get("bev_energy", 0.05)
|
* options.get("bev_energy", 0.05)
|
||||||
@ -1618,61 +1600,120 @@ def add_land_transport(n, costs):
|
|||||||
e_min_pu=dsm_profile[nodes],
|
e_min_pu=dsm_profile[nodes],
|
||||||
)
|
)
|
||||||
|
|
||||||
if fuel_cell_share > 0:
|
def add_fuel_cell_cars(n, nodes, p_set, fuel_cell_share, temperature):
|
||||||
|
|
||||||
|
efficiency = options["transport_fuel_cell_efficiency"]
|
||||||
|
profile = p_set / p_set.max()
|
||||||
|
p_nom = fuel_cell_share * p_set / efficiency
|
||||||
|
|
||||||
n.madd(
|
n.madd(
|
||||||
"Load",
|
"Link",
|
||||||
nodes,
|
nodes,
|
||||||
suffix=" land transport fuel cell",
|
suffix=" land transport fuel cell",
|
||||||
bus=nodes + " H2",
|
bus0=spatial.h2.nodes,
|
||||||
|
bus1=nodes + " land transport",
|
||||||
carrier="land transport fuel cell",
|
carrier="land transport fuel cell",
|
||||||
p_set=fuel_cell_share
|
efficiency=efficiency,
|
||||||
/ options["transport_fuel_cell_efficiency"]
|
p_nom_extendable=False,
|
||||||
* transport[nodes],
|
p_nom=p_nom,
|
||||||
|
p_min_pu=profile,
|
||||||
|
p_max_pu=profile,
|
||||||
)
|
)
|
||||||
|
|
||||||
if ice_share > 0:
|
|
||||||
|
def add_ice_cars(n, nodes, p_set, ice_share, temperature):
|
||||||
|
|
||||||
add_carrier_buses(n, "oil")
|
add_carrier_buses(n, "oil")
|
||||||
|
|
||||||
ice_efficiency = options["transport_internal_combustion_efficiency"]
|
ice_efficiency = options["transport_internal_combustion_efficiency"]
|
||||||
|
|
||||||
p_set_land_transport_oil = (
|
|
||||||
ice_share
|
|
||||||
/ ice_efficiency
|
|
||||||
* transport[nodes].rename(columns=lambda x: x + " land transport oil")
|
|
||||||
)
|
|
||||||
|
|
||||||
if not options["regional_oil_demand"]:
|
if not options["regional_oil_demand"]:
|
||||||
p_set_land_transport_oil = p_set_land_transport_oil.sum(axis=1).to_frame(
|
p_nom = ice_share * p_set.sum(axis=1).max() / ice_efficiency
|
||||||
name="EU land transport oil"
|
else:
|
||||||
)
|
p_nom = ice_share * p_set.max() / ice_efficiency
|
||||||
|
|
||||||
n.madd(
|
|
||||||
"Bus",
|
|
||||||
spatial.oil.land_transport,
|
|
||||||
location=spatial.oil.demand_locations,
|
|
||||||
carrier="land transport oil",
|
|
||||||
unit="land transport",
|
|
||||||
)
|
|
||||||
|
|
||||||
n.madd(
|
|
||||||
"Load",
|
|
||||||
spatial.oil.land_transport,
|
|
||||||
bus=spatial.oil.land_transport,
|
|
||||||
carrier="land transport oil",
|
|
||||||
p_set=p_set_land_transport_oil,
|
|
||||||
)
|
|
||||||
|
|
||||||
n.madd(
|
n.madd(
|
||||||
"Link",
|
"Link",
|
||||||
spatial.oil.land_transport,
|
nodes + " land transport ICE",
|
||||||
bus0=spatial.oil.nodes,
|
bus0=spatial.oil.nodes,
|
||||||
bus1=spatial.oil.land_transport,
|
bus1=nodes + " land transport",
|
||||||
bus2="co2 atmosphere",
|
bus2=["co2 atmosphere"],
|
||||||
carrier="land transport oil",
|
carrier="land transport oil",
|
||||||
|
efficiency=ice_efficiency,
|
||||||
efficiency2=costs.at["oil", "CO2 intensity"],
|
efficiency2=costs.at["oil", "CO2 intensity"],
|
||||||
p_nom_extendable=True,
|
p_nom_extendable=True,
|
||||||
|
# p_nom=p_nom,
|
||||||
|
capital_cost=1e4,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def add_land_transport(n, costs):
|
||||||
|
# TODO options?
|
||||||
|
|
||||||
|
logger.info("Add land transport")
|
||||||
|
|
||||||
|
# read in transport demand in units kinetic energy
|
||||||
|
transport = pd.read_csv(
|
||||||
|
snakemake.input.transport_demand, index_col=0, parse_dates=True
|
||||||
|
)
|
||||||
|
number_cars = pd.read_csv(snakemake.input.transport_data, index_col=0)[
|
||||||
|
"number cars"
|
||||||
|
]
|
||||||
|
avail_profile = pd.read_csv(
|
||||||
|
snakemake.input.avail_profile, index_col=0, parse_dates=True
|
||||||
|
)
|
||||||
|
dsm_profile = pd.read_csv(
|
||||||
|
snakemake.input.dsm_profile, index_col=0, parse_dates=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# exogenous share of passenger car type
|
||||||
|
engine_types = ["fuel_cell", "electric", "ice"]
|
||||||
|
shares = pd.Series()
|
||||||
|
for engine in engine_types:
|
||||||
|
shares[engine] = get(options[f"land_transport_{engine}_share"],
|
||||||
|
investment_year)
|
||||||
|
logger.info(f"{engine} share: {shares[engine]*100}%")
|
||||||
|
|
||||||
|
check_land_transport_shares(shares)
|
||||||
|
|
||||||
|
nodes = spatial.nodes
|
||||||
|
|
||||||
|
# Add load for transport demand
|
||||||
|
n.add("Carrier", "land transport demand")
|
||||||
|
|
||||||
|
n.madd("Bus",
|
||||||
|
nodes,
|
||||||
|
location=nodes,
|
||||||
|
suffix=" land transport",
|
||||||
|
carrier="land transport demand",
|
||||||
|
unit="MWh_kinetic")
|
||||||
|
|
||||||
|
p_set = transport[nodes]
|
||||||
|
|
||||||
|
# add demand
|
||||||
|
n.madd(
|
||||||
|
"Load",
|
||||||
|
nodes,
|
||||||
|
suffix=" land transport",
|
||||||
|
bus=nodes + " land transport",
|
||||||
|
carrier="land transport demand",
|
||||||
|
p_set=p_set,
|
||||||
|
)
|
||||||
|
|
||||||
|
# temperature for correction factor for heating/cooling
|
||||||
|
temperature = xr.open_dataarray(snakemake.input.temp_air_total).to_pandas()
|
||||||
|
|
||||||
|
if shares["electric"] > 0:
|
||||||
|
add_EVs(n, nodes, avail_profile, dsm_profile, p_set, shares["electric"],
|
||||||
|
number_cars, temperature)
|
||||||
|
|
||||||
|
if shares["fuel_cell"] > 0:
|
||||||
|
add_fuel_cell_cars(n, nodes, p_set, shares["fuel_cell"], temperature)
|
||||||
|
|
||||||
|
if shares["ice"] > 0:
|
||||||
|
add_ice_cars(n, nodes, p_set, shares["ice"], temperature)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def build_heat_demand(n):
|
def build_heat_demand(n):
|
||||||
heat_demand_shape = (
|
heat_demand_shape = (
|
||||||
@ -3565,19 +3606,19 @@ def lossy_bidirectional_links(n, carrier, efficiencies={}):
|
|||||||
-compression_per_1000km * n.links.loc[carrier_i, "length_original"] / 1e3
|
-compression_per_1000km * n.links.loc[carrier_i, "length_original"] / 1e3
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#%%
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if "snakemake" not in globals():
|
if "snakemake" not in globals():
|
||||||
from _helpers import mock_snakemake
|
from _helpers import mock_snakemake
|
||||||
|
|
||||||
snakemake = mock_snakemake(
|
snakemake = mock_snakemake(
|
||||||
"prepare_sector_network",
|
"prepare_sector_network",
|
||||||
configfiles="test/config.overnight.yaml",
|
# configfiles="test/config.overnight.yaml",
|
||||||
simpl="",
|
simpl="",
|
||||||
opts="",
|
opts="",
|
||||||
clusters="37",
|
clusters="37",
|
||||||
ll="v1.0",
|
ll="v1.0",
|
||||||
sector_opts="CO2L0-24H-T-H-B-I-A-dist1",
|
sector_opts="730H-T-H-B-I-A-dist1",
|
||||||
planning_horizons="2030",
|
planning_horizons="2030",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user