safe transport demand in unit kinetic energy
This commit is contained in:
parent
986c7be48e
commit
b70aa59dce
@ -19,13 +19,16 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def build_nodal_transport_data(fn, pop_layout):
|
||||
# get numbers of car and fuel efficieny per country
|
||||
transport_data = pd.read_csv(fn, index_col=0)
|
||||
|
||||
|
||||
# break number of cars down to nodal level based on population density
|
||||
nodal_transport_data = transport_data.loc[pop_layout.ct].fillna(0.0)
|
||||
nodal_transport_data.index = pop_layout.index
|
||||
nodal_transport_data["number cars"] = (
|
||||
pop_layout["fraction"] * nodal_transport_data["number cars"]
|
||||
)
|
||||
# fill missing fuel efficiency with average data
|
||||
nodal_transport_data.loc[
|
||||
nodal_transport_data["average fuel efficiency"] == 0.0,
|
||||
"average fuel efficiency",
|
||||
@ -35,10 +38,14 @@ def build_nodal_transport_data(fn, pop_layout):
|
||||
|
||||
|
||||
def build_transport_demand(traffic_fn, airtemp_fn, nodes, nodal_transport_data):
|
||||
## Get overall demand curve for all vehicles
|
||||
|
||||
traffic = pd.read_csv(traffic_fn, skiprows=2, usecols=["count"]).squeeze("columns")
|
||||
|
||||
"""
|
||||
returns transport demand per bus in unit kinetic energy.
|
||||
"""
|
||||
# averaged weekly counts from the year 2010-2015
|
||||
traffic = pd.read_csv(traffic_fn, skiprows=2,
|
||||
usecols=["count"]).squeeze("columns")
|
||||
|
||||
# create annual profile take account time zone + summer time
|
||||
transport_shape = generate_periodic_profiles(
|
||||
dt_index=snapshots,
|
||||
nodes=nodes,
|
||||
@ -46,15 +53,6 @@ def build_transport_demand(traffic_fn, airtemp_fn, nodes, nodal_transport_data):
|
||||
)
|
||||
transport_shape = transport_shape / transport_shape.sum()
|
||||
|
||||
# electric motors are more efficient, so alter transport demand
|
||||
|
||||
plug_to_wheels_eta = options["bev_plug_to_wheel_efficiency"]
|
||||
battery_to_wheels_eta = plug_to_wheels_eta * options["bev_charge_efficiency"]
|
||||
|
||||
efficiency_gain = (
|
||||
nodal_transport_data["average fuel efficiency"] / battery_to_wheels_eta
|
||||
)
|
||||
|
||||
# get heating demand for correction to demand time series
|
||||
temperature = xr.open_dataarray(airtemp_fn).to_pandas()
|
||||
|
||||
@ -67,16 +65,8 @@ def build_transport_demand(traffic_fn, airtemp_fn, nodes, nodal_transport_data):
|
||||
options["ICE_upper_degree_factor"],
|
||||
)
|
||||
|
||||
dd_EV = transport_degree_factor(
|
||||
temperature,
|
||||
options["transport_heating_deadband_lower"],
|
||||
options["transport_heating_deadband_upper"],
|
||||
options["EV_lower_degree_factor"],
|
||||
options["EV_upper_degree_factor"],
|
||||
)
|
||||
|
||||
|
||||
# divide out the heating/cooling demand from ICE totals
|
||||
# and multiply back in the heating/cooling demand for EVs
|
||||
ice_correction = (transport_shape * (1 + dd_ICE)).sum() / transport_shape.sum()
|
||||
|
||||
energy_totals_transport = (
|
||||
@ -87,8 +77,7 @@ def build_transport_demand(traffic_fn, airtemp_fn, nodes, nodal_transport_data):
|
||||
|
||||
return (
|
||||
(transport_shape.multiply(energy_totals_transport) * 1e6 * nyears)
|
||||
.divide(efficiency_gain * ice_correction)
|
||||
.multiply(1 + dd_EV)
|
||||
.divide(nodal_transport_data["average fuel efficiency"] * ice_correction)
|
||||
)
|
||||
|
||||
|
||||
@ -125,11 +114,14 @@ def bev_availability_profile(fn, snapshots, nodes, options):
|
||||
"""
|
||||
Derive plugged-in availability for passenger electric vehicles.
|
||||
"""
|
||||
# car count in typical week
|
||||
traffic = pd.read_csv(fn, skiprows=2, usecols=["count"]).squeeze("columns")
|
||||
|
||||
# maximum share plugged-in availability for passenger electric vehicles
|
||||
avail_max = options["bev_avail_max"]
|
||||
# average share plugged-in availability for passenger electric vehicles
|
||||
avail_mean = options["bev_avail_mean"]
|
||||
|
||||
# linear scaling, highest when traffic is lowest, decreases if traffic increases
|
||||
avail = avail_max - (avail_max - avail_mean) * (traffic - traffic.min()) / (
|
||||
traffic.mean() - traffic.min()
|
||||
)
|
||||
@ -149,7 +141,9 @@ def bev_availability_profile(fn, snapshots, nodes, options):
|
||||
|
||||
def bev_dsm_profile(snapshots, nodes, options):
|
||||
dsm_week = np.zeros((24 * 7,))
|
||||
|
||||
|
||||
# assuming that at a certain time ("bev_dsm_restriction_time") EVs have to
|
||||
# be charged to a minimum value (defined in bev_dsm_restriction_value)
|
||||
dsm_week[(np.arange(0, 7, 1) * 24 + options["bev_dsm_restriction_time"])] = options[
|
||||
"bev_dsm_restriction_value"
|
||||
]
|
||||
@ -160,7 +154,7 @@ def bev_dsm_profile(snapshots, nodes, options):
|
||||
weekly_profile=dsm_week,
|
||||
)
|
||||
|
||||
|
||||
#%%
|
||||
if __name__ == "__main__":
|
||||
if "snakemake" not in globals():
|
||||
from _helpers import mock_snakemake
|
||||
@ -168,7 +162,7 @@ if __name__ == "__main__":
|
||||
snakemake = mock_snakemake(
|
||||
"build_transport_demand",
|
||||
simpl="",
|
||||
clusters=48,
|
||||
clusters=37,
|
||||
)
|
||||
configure_logging(snakemake)
|
||||
set_scenario_config(snakemake)
|
||||
|
Loading…
Reference in New Issue
Block a user