Path: blob/main/src/equations/inviscid_burgers_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"""8InviscidBurgersEquation1D910The inviscid Burgers' equation11```math12\partial_t u + \frac{1}{2} \partial_1 u^2 = 013```14in one space dimension.15"""16struct InviscidBurgersEquation1D <: AbstractInviscidBurgersEquation{1, 1} end1718varnames(::typeof(cons2cons), ::InviscidBurgersEquation1D) = ("scalar",)19varnames(::typeof(cons2prim), ::InviscidBurgersEquation1D) = ("scalar",)2021# Set initial conditions at physical location `x` for time `t`22"""23initial_condition_constant(x, t, equations::InviscidBurgersEquation1D)2425A constant initial condition to test free-stream preservation.26"""27function initial_condition_constant(x, t, equation::InviscidBurgersEquation1D)28RealT = eltype(x)29return SVector(RealT(2))30end3132"""33initial_condition_convergence_test(x, t, equations::InviscidBurgersEquation1D)3435A smooth initial condition used for convergence tests.36"""37function initial_condition_convergence_test(x, t, equation::InviscidBurgersEquation1D)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::InviscidBurgersEquation1D)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::InviscidBurgersEquation1D)57# Same settings as in `initial_condition`58RealT = eltype(x)59c = 260A = 161L = 162f = 1.0f0 / L63omega = 2 * convert(RealT, pi) * f64du = omega * A * cos(omega * (x[1] - t)) * (c - 1 + A * sin(omega * (x[1] - t)))6566return SVector(du)67end6869# Pre-defined source terms should be implemented as70# function source_terms_WHATEVER(u, x, t, equations::InviscidBurgersEquation1D)7172# Calculate 1D flux for a single point73@inline function flux(u, orientation::Integer, equation::InviscidBurgersEquation1D)74return SVector(0.5f0 * u[1]^2)75end7677# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation78@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,79equations::InviscidBurgersEquation1D)80u_L = u_ll[1]81u_R = u_rr[1]8283return max(abs(u_L), abs(u_R))84end8586# Calculate minimum and maximum wave speeds for HLL-type fluxes87@inline function min_max_speed_naive(u_ll, u_rr, orientation::Integer,88equations::InviscidBurgersEquation1D)89u_L = u_ll[1]90u_R = u_rr[1]9192λ_min = min(u_L, u_R)93λ_max = max(u_L, u_R)9495return λ_min, λ_max96end9798@inline function max_abs_speeds(u, equation::InviscidBurgersEquation1D)99return (abs(u[1]),)100end101102@doc raw"""103flux_ec(u_ll, u_rr, orientation, equations::InviscidBurgersEquation1D)104105Entropy-conserving, symmetric flux for the inviscid Burgers' equation.106```math107F(u_L, u_R) = \frac{u_L^2 + u_L u_R + u_R^2}{6}108```109"""110function flux_ec(u_ll, u_rr, orientation, equation::InviscidBurgersEquation1D)111u_L = u_ll[1]112u_R = u_rr[1]113114return SVector((u_L^2 + u_L * u_R + u_R^2) / 6)115end116117"""118flux_godunov(u_ll, u_rr, orientation, equations::InviscidBurgersEquation1D)119120Godunov (upwind) numerical flux for the inviscid Burgers' equation.121See https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf ,122section 4.1.5 and especially equation (4.16).123"""124function flux_godunov(u_ll, u_rr, orientation, equation::InviscidBurgersEquation1D)125u_L = u_ll[1]126u_R = u_rr[1]127128return SVector(0.5f0 * max(max(u_L, 0)^2, min(u_R, 0)^2))129end130131# See https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf ,132# section 4.2.5 and especially equation (4.34).133function flux_engquist_osher(u_ll, u_rr, orientation,134equation::InviscidBurgersEquation1D)135u_L = u_ll[1]136u_R = u_rr[1]137138return SVector(0.5f0 * (max(u_L, 0)^2 + min(u_R, 0)^2))139end140141"""142splitting_lax_friedrichs(u, orientation::Integer,143equations::InviscidBurgersEquation1D)144splitting_lax_friedrichs(u, which::Union{Val{:minus}, Val{:plus}}145orientation::Integer,146equations::InviscidBurgersEquation1D)147148Naive local Lax-Friedrichs style flux splitting of the form `f⁺ = 0.5 (f + λ u)`149and `f⁻ = 0.5 (f - λ u)` where `λ = abs(u)`.150151Returns a tuple of the fluxes "minus" (associated with waves going into the152negative axis direction) and "plus" (associated with waves going into the153positive axis direction). If only one of the fluxes is required, use the154function signature with argument `which` set to `Val{:minus}()` or `Val{:plus}()`.155156!!! warning "Experimental implementation (upwind SBP)"157This is an experimental feature and may change in future releases.158"""159@inline function splitting_lax_friedrichs(u, orientation::Integer,160equations::InviscidBurgersEquation1D)161fm = splitting_lax_friedrichs(u, Val{:minus}(), orientation, equations)162fp = splitting_lax_friedrichs(u, Val{:plus}(), orientation, equations)163return fm, fp164end165166@inline function splitting_lax_friedrichs(u, ::Val{:plus}, orientation::Integer,167equations::InviscidBurgersEquation1D)168f = 0.5f0 * u[1]^2169lambda = abs(u[1])170return SVector(0.5f0 * (f + lambda * u[1]))171end172173@inline function splitting_lax_friedrichs(u, ::Val{:minus}, orientation::Integer,174equations::InviscidBurgersEquation1D)175f = 0.5f0 * u[1]^2176lambda = abs(u[1])177return SVector(0.5f0 * (f - lambda * u[1]))178end179180# Convert conservative variables to primitive181@inline cons2prim(u, equation::InviscidBurgersEquation1D) = u182183# Convert conservative variables to entropy variables184@inline cons2entropy(u, equation::InviscidBurgersEquation1D) = u185@inline entropy2cons(u, equation::InviscidBurgersEquation1D) = u186187# Calculate entropy for a conservative state `cons`188@inline entropy(u::Real, ::InviscidBurgersEquation1D) = 0.5f0 * u^2189@inline entropy(u, equation::InviscidBurgersEquation1D) = entropy(u[1], equation)190191# Calculate total energy for a conservative state `cons`192@inline energy_total(u::Real, ::InviscidBurgersEquation1D) = 0.5f0 * u^2193@inline function energy_total(u, equation::InviscidBurgersEquation1D)194energy_total(u[1], equation)195end196end # @muladd197198199