When assessing vehicle emissions
inventories for particles, one relevant step is taking into account the
non-exhaust processes, such as tire, brake and road wear. The
gtfs2emis
incorporates the non-exhaust emissions methods
from EMEP-EEA.
The following equation is employed to evaluate emissions originating from tire and brake wear
TEi = dist × EFtsp(j) × mfs(i) × SC(speed) where:
In the case of heavy-duty vehicles, the emission factor needs the incorporation of vehicle size, as determined by the number of axles, and load. These parameters are introduced into the equation as follows:
EFTSPtirehdv = 0.5 × Naxle × LCFtire × EFTSPtirepc
where:
and LCFtire = 1.41 + (1.38 × LF)
where:
The function considers the following look-up table for number of vehicle axes:
vehicle class (j) | number of axes |
---|---|
Ubus Midi <=15 t | 2 |
Ubus Std 15 - 18 t | 2 |
Ubus Artic >18 t | 3 |
Coaches Std <=18 t | 2 |
Coaches Artic >18 t | 3 |
The size distribution of tire wear particles are given by:
particle size class (i) | mass fraction of TSP |
---|---|
TSP | 1.000 |
PM10 | 0.600 |
PM2.5 | 0.420 |
PM1.0 | 0.060 |
PM0.1 | 0.048 |
Finally, the speed correction is:
library(gtfs2emis)
emi_europe_emep_wear(dist = units::set_units(1,"km"),
speed = units::set_units(30,"km/h"),
pollutant = c("PM10","TSP","PM2.5"),
veh_type = "Ubus Std 15 - 18 t",
fleet_composition = 1,
load = 0.5,
process = c("tyre"),
as_list = TRUE)
#> $pollutant
#> [1] "PM10" "TSP" "PM2.5"
#>
#> $veh_type
#> [1] "Ubus Std 15 - 18 t"
#>
#> $fleet_composition
#> [1] 1
#>
#> $speed
#> 30 [km/h]
#>
#> $dist
#> 1 [km]
#>
#> $emi
#> PM10_tyre_veh_1 TSP_tyre_veh_1 PM2.5_tyre_veh_1
#> <units> <units> <units>
#> 1: 0.01873998 [g] 0.0312333 [g] 0.01311799 [g]
#>
#> $process
#> [1] "tyre"
The heavy-duty vehicle emission factor is derived by modifying the passenger car emission factor to conform to experimental data obtained from heavy-duty vehicles.
EFTSPbrakehdv = 1.956 × LCFbrake × EFTSPbrakepc
where:
LCFbrake = 1 + (0.79 × LF),
where:
The size distribution of brake wear particles are given by:
particle size class (i) | mass fraction of TSP |
---|---|
TSP | 1.000 |
PM10 | 0.980 |
PM2.5 | 0.390 |
PM1.0 | 0.100 |
PM0.1 | 0.080 |
Finally, the speed correction is:
emi_europe_emep_wear(dist = units::set_units(1,"km"),
speed = units::set_units(30,"km/h"),
pollutant = c("PM10","TSP","PM2.5"),
veh_type = "Ubus Std 15 - 18 t",
fleet_composition = 1,
load = 0.5,
process = c("brake"),
as_list = TRUE)
#> $pollutant
#> [1] "PM10" "TSP" "PM2.5"
#>
#> $veh_type
#> [1] "Ubus Std 15 - 18 t"
#>
#> $fleet_composition
#> [1] 1
#>
#> $speed
#> 30 [km/h]
#>
#> $dist
#> 1 [km]
#>
#> $emi
#> PM10_brake_veh_1 TSP_brake_veh_1 PM2.5_brake_veh_1
#> <units> <units> <units>
#> 1: 0.03349245 [g] 0.03417597 [g] 0.01332863 [g]
#>
#> $process
#> [1] "brake"
Emissions are calculated according to the equation:
TE(i) = dist × EFtsproad(j) × mfroad
where:
The following table shows the size distribution of road surface wear particles
particle size class (i) | mass fraction of TSP |
---|---|
TSP | 1.00 |
PM10 | 0.50 |
PM2.5 | 0.27 |
emi_europe_emep_wear(dist = units::set_units(1,"km"),
speed = units::set_units(30,"km/h"),
pollutant = c("PM10","TSP","PM2.5"),
veh_type = "Ubus Std 15 - 18 t",
fleet_composition = 1,
load = 0.5,
process = c("road"),
as_list = TRUE)
#> $pollutant
#> [1] "PM10" "TSP" "PM2.5"
#>
#> $veh_type
#> [1] "Ubus Std 15 - 18 t"
#>
#> $fleet_composition
#> [1] 1
#>
#> $speed
#> 30 [km/h]
#>
#> $dist
#> 1 [km]
#>
#> $emi
#> PM10_road_veh_1 TSP_road_veh_1 PM2.5_road_veh_1
#> <units> <units> <units>
#> 1: 0.038 [g] 0.076 [g] 0.02052 [g]
#>
#> $process
#> [1] "road"
Users can also use one single function to apply for more than one process (e.g. tire, brake and road), as shown below.
library(units)
library(ggplot2)
emis_list <- emi_europe_emep_wear(dist = units::set_units(rep(1,100),"km"),
speed = units::set_units(1:100,"km/h"),
pollutant = c("PM10","TSP","PM2.5"),
veh_type = c("Ubus Std 15 - 18 t"),
fleet_composition = c(1),
load = 0.5,
process = c("brake","tyre","road"),
as_list = TRUE)
ef_dt <- gtfs2emis::emis_to_dt(emis_list,emi_vars = "emi"
,segment_vars = "speed")
ggplot(ef_dt)+
geom_line(aes(x = as.numeric(speed),y = as.numeric(emi),color = pollutant))+
facet_wrap(facets = vars(process))+
labs(x = "Speed (km/h)",y = "Emissions (g)")+
theme_minimal()
When using the transport_model()
output, users can also
visualize both hot-exhaust and non-exhaust emissions taking few more
steps. This can be done in three main stages: a) Preparing the data, b)
Creating spatial grid; c) Generating spatial and temporal
visualizations.
library(gtfstools)
library(sf)
# read GTFS
gtfs_file <- system.file("extdata/bra_cur_gtfs.zip", package = "gtfs2emis")
gtfs <- gtfstools::read_gtfs(gtfs_file)
# keep a single trip_id to speed up this example
gtfs_small <- gtfstools::filter_by_trip_id(gtfs, trip_id ="4451136")
# run transport model
tp_model <- transport_model(gtfs_data = gtfs_small,
spatial_resolution = 100,
parallel = FALSE)
# Fleet data, using Brazilian emission model and fleet
fleet_data_ef_emep <- data.frame(veh_type = "Ubus Std 15 - 18 t",
fleet_composition = 1,
euro = "V", # for hot-exhaust emissions
fuel = "D", # for hot-exhaust emissions
tech = "SCR") # for hot-exhaust emissions
# Emission model (hot-exhaust)
emi_list_he <- emission_model(
tp_model = tp_model,
ef_model = "ef_europe_emep",
fleet_data = fleet_data_ef_emep,
pollutant = "PM10"
)
# Emission model (non-exhaust)
emi_list_ne <- emi_europe_emep_wear(
dist = tp_model$dist,
speed = tp_model$speed,
pollutant = "PM10",
veh_type = c("Ubus Std 15 - 18 t"),
fleet_composition = c(1),
load = 0.5,
process = c("brake","tyre","road"),
as_list = TRUE)
emi_list_ne$tp_model <- tp_model
# create spatial grid
grid <- sf::st_make_grid(
x = sf::st_make_valid(tp_model)
, cellsize = 0.25 / 200
, crs= 4326
, what = "polygons"
, square = FALSE
)
# grid (hot-exhaust)
emi_grid_he <- emis_grid( emi_list_he,grid,time_resolution = 'day'
,aggregate = TRUE)
setDT(emi_grid_he)
pol_names <- setdiff(names(emi_grid_he),"geometry")
emi_grid_he_dt <- melt(emi_grid_he,measure.vars = pol_names,id.vars = "geometry")
emi_grid_he_dt <- sf::st_as_sf(emi_grid_he_dt)
# grid (non-exhaust)
emi_grid_ne <- emis_grid( emi_list_ne,grid,time_resolution = 'day'
,aggregate = TRUE)
setDT(emi_grid_ne)
pol_names <- setdiff(names(emi_grid_ne),"geometry")
emi_grid_ne_dt <- melt(emi_grid_ne,measure.vars = pol_names,id.vars = "geometry")
emi_grid_ne_dt <- sf::st_as_sf(emi_grid_ne_dt)
# bind grid
emi_grid_dt <- data.table::rbindlist(l = list(emi_grid_he_dt,emi_grid_ne_dt))
emi_grid_sf <- sf::st_as_sf(emi_grid_dt)
# plot
library(ggplot2)
ggplot(emi_grid_sf) +
geom_sf(aes(fill= as.numeric(value)), color=NA) +
geom_sf(data = tp_model$geometry,color = "black")+
scale_fill_continuous(type = "viridis")+
labs(fill = "PM10 (g)")+
facet_wrap(facets = vars(variable),nrow = 1)+
theme_void()
The total emissions can be also viewed in bar graphics
# Emissions by time
emi_time_he <- emis_summary(emi_list_he,by = "time")
emi_time_ne <- emis_summary(emi_list_ne,by = "time")
emi_time <- data.table::rbindlist(l = list(emi_time_he,emi_time_ne))
ggplot(emi_time)+
geom_col(aes(x = process,y = as.numeric(emi),fill = as.numeric(emi)))+
scale_fill_continuous(type = "viridis")+
labs(fill = "PM10 level",y = "Emissions (g)")+
theme_minimal()
If you have any suggestions or want to report an error, please visit the package GitHub page.