Path: blob/main/src/equations/traffic_flow_lwr_1d.jl
2055 views
# By default, Julia/LLVM does not use fused multiply-add operations (FMAs).1# Since these FMAs can increase the performance of many numerical algorithms,2# we need to opt-in explicitly.3# See https://ranocha.de/blog/Optimizing_EC_Trixi for further details.4@muladd begin5#! format: noindent67@doc raw"""8TrafficFlowLWREquations1D910The classic Lighthill-Witham Richards (LWR) model for 1D traffic flow.11The car density is denoted by $u \in [0, 1]$ and12the maximum possible speed (e.g. due to speed limits) is $v_{\text{max}}$.13```math14\partial_t u + v_{\text{max}} \partial_1 [u (1 - u)] = 015```16For more details see e.g. Section 11.1 of17- Randall LeVeque (2002)18Finite Volume Methods for Hyperbolic Problems19[DOI: 10.1017/CBO9780511791253](https://doi.org/10.1017/CBO9780511791253)20"""21struct TrafficFlowLWREquations1D{RealT <: Real} <: AbstractTrafficFlowLWREquations{1, 1}22v_max::RealT2324function TrafficFlowLWREquations1D(v_max = 1.0)25new{typeof(v_max)}(v_max)26end27end2829varnames(::typeof(cons2cons), ::TrafficFlowLWREquations1D) = ("car-density",)30varnames(::typeof(cons2prim), ::TrafficFlowLWREquations1D) = ("car-density",)3132"""33initial_condition_convergence_test(x, t, equations::TrafficFlowLWREquations1D)3435A smooth initial condition used for convergence tests.36"""37function initial_condition_convergence_test(x, t, equations::TrafficFlowLWREquations1D)38RealT = eltype(x)39c = 240A = 141L = 142f = 1.0f0 / L43omega = 2 * convert(RealT, pi) * f44scalar = c + A * sin(omega * (x[1] - t))4546return SVector(scalar)47end4849"""50source_terms_convergence_test(u, x, t, equations::TrafficFlowLWREquations1D)5152Source terms used for convergence tests in combination with53[`initial_condition_convergence_test`](@ref).54"""55@inline function source_terms_convergence_test(u, x, t,56equations::TrafficFlowLWREquations1D)57# Same settings as in `initial_condition`58RealT = eltype(x)59c = 260A = 161L = 162f = 1.0f0 / L63omega = 2 * convert(RealT, pi) * f64du = omega * cos(omega * (x[1] - t)) *65(-1 - equations.v_max * (2 * sin(omega * (x[1] - t)) + 3))6667return SVector(du)68end6970# Calculate 1D flux for a single point71@inline function flux(u, orientation::Integer, equations::TrafficFlowLWREquations1D)72return SVector(equations.v_max * u[1] * (1 - u[1]))73end7475# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation76@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,77equations::TrafficFlowLWREquations1D)78return max(abs(equations.v_max * (1 - 2 * u_ll[1])),79abs(equations.v_max * (1 - 2 * u_rr[1])))80end8182# Calculate minimum and maximum wave speeds for HLL-type fluxes83@inline function min_max_speed_naive(u_ll, u_rr, orientation::Integer,84equations::TrafficFlowLWREquations1D)85jac_L = equations.v_max * (1 - 2 * u_ll[1])86jac_R = equations.v_max * (1 - 2 * u_rr[1])8788λ_min = min(jac_L, jac_R)89λ_max = max(jac_L, jac_R)9091return λ_min, λ_max92end9394@inline function min_max_speed_davis(u_ll, u_rr, orientation::Integer,95equations::TrafficFlowLWREquations1D)96min_max_speed_naive(u_ll, u_rr, orientation, equations)97end9899@inline function max_abs_speeds(u, equations::TrafficFlowLWREquations1D)100return (abs(equations.v_max * (1 - 2 * u[1])),)101end102103# Convert conservative variables to primitive104@inline cons2prim(u, equations::TrafficFlowLWREquations1D) = u105106# Convert conservative variables to entropy variables107@inline cons2entropy(u, equations::TrafficFlowLWREquations1D) = u108109# Calculate entropy for a conservative state `cons`110@inline entropy(u::Real, ::TrafficFlowLWREquations1D) = 0.5f0 * u^2111@inline entropy(u, equations::TrafficFlowLWREquations1D) = entropy(u[1], equations)112113# Calculate total energy for a conservative state `cons`114@inline energy_total(u::Real, ::TrafficFlowLWREquations1D) = 0.5f0 * u^2115@inline energy_total(u, equations::TrafficFlowLWREquations1D) = energy_total(u[1],116equations)117end # @muladd118119120