Path: blob/main/src/equations/inviscid_burgers_1d.jl
2831 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).5455References for the method of manufactured solutions (MMS):56- Kambiz Salari and Patrick Knupp (2000)57Code Verification by the Method of Manufactured Solutions58[DOI: 10.2172/759450](https://doi.org/10.2172/759450)59- Patrick J. Roache (2002)60Code Verification by the Method of Manufactured Solutions61[DOI: 10.1115/1.1436090](https://doi.org/10.1115/1.1436090)62"""63@inline function source_terms_convergence_test(u, x, t,64equations::InviscidBurgersEquation1D)65# Same settings as in `initial_condition`66RealT = eltype(x)67c = 268A = 169L = 170f = 1.0f0 / L71omega = 2 * convert(RealT, pi) * f72du = omega * A * cos(omega * (x[1] - t)) * (c - 1 + A * sin(omega * (x[1] - t)))7374return SVector(du)75end7677# Calculate 1D flux for a single point78@inline function flux(u, orientation::Integer, equation::InviscidBurgersEquation1D)79return SVector(0.5f0 * u[1]^2)80end8182# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation83@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,84equations::InviscidBurgersEquation1D)85u_L = u_ll[1]86u_R = u_rr[1]8788return max(abs(u_L), abs(u_R))89end9091# Calculate minimum and maximum wave speeds for HLL-type fluxes92@inline function min_max_speed_naive(u_ll, u_rr, orientation::Integer,93equations::InviscidBurgersEquation1D)94u_L = u_ll[1]95u_R = u_rr[1]9697λ_min = min(u_L, u_R)98λ_max = max(u_L, u_R)99100return λ_min, λ_max101end102103@inline function max_abs_speeds(u, equation::InviscidBurgersEquation1D)104return (abs(u[1]),)105end106107@doc raw"""108flux_ec(u_ll, u_rr, orientation, equations::InviscidBurgersEquation1D)109110Entropy-conserving, symmetric flux for the inviscid Burgers' equation.111```math112F(u_L, u_R) = \frac{u_L^2 + u_L u_R + u_R^2}{6}113```114"""115function flux_ec(u_ll, u_rr, orientation, equation::InviscidBurgersEquation1D)116u_L = u_ll[1]117u_R = u_rr[1]118119return SVector((u_L^2 + u_L * u_R + u_R^2) / 6)120end121122"""123flux_godunov(u_ll, u_rr, orientation, equations::InviscidBurgersEquation1D)124125Godunov (upwind) numerical flux for the inviscid Burgers' equation.126See https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf ,127section 4.1.5 and especially equation (4.16).128"""129function flux_godunov(u_ll, u_rr, orientation, equation::InviscidBurgersEquation1D)130u_L = u_ll[1]131u_R = u_rr[1]132133return SVector(0.5f0 * max(max(u_L, 0)^2, min(u_R, 0)^2))134end135136# See https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf ,137# section 4.2.5 and especially equation (4.34).138function flux_engquist_osher(u_ll, u_rr, orientation,139equation::InviscidBurgersEquation1D)140u_L = u_ll[1]141u_R = u_rr[1]142143return SVector(0.5f0 * (max(u_L, 0)^2 + min(u_R, 0)^2))144end145146"""147splitting_lax_friedrichs(u, orientation::Integer,148equations::InviscidBurgersEquation1D)149splitting_lax_friedrichs(u, which::Union{Val{:minus}, Val{:plus}}150orientation::Integer,151equations::InviscidBurgersEquation1D)152153Naive local Lax-Friedrichs style flux splitting of the form `f⁺ = 0.5 (f + λ u)`154and `f⁻ = 0.5 (f - λ u)` where `λ = abs(u)`.155156Returns a tuple of the fluxes "minus" (associated with waves going into the157negative axis direction) and "plus" (associated with waves going into the158positive axis direction). If only one of the fluxes is required, use the159function signature with argument `which` set to `Val{:minus}()` or `Val{:plus}()`.160161!!! warning "Experimental implementation (upwind SBP)"162This is an experimental feature and may change in future releases.163"""164@inline function splitting_lax_friedrichs(u, orientation::Integer,165equations::InviscidBurgersEquation1D)166fm = splitting_lax_friedrichs(u, Val{:minus}(), orientation, equations)167fp = splitting_lax_friedrichs(u, Val{:plus}(), orientation, equations)168return fm, fp169end170171@inline function splitting_lax_friedrichs(u, ::Val{:plus}, orientation::Integer,172equations::InviscidBurgersEquation1D)173f = 0.5f0 * u[1]^2174lambda = abs(u[1])175return SVector(0.5f0 * (f + lambda * u[1]))176end177178@inline function splitting_lax_friedrichs(u, ::Val{:minus}, orientation::Integer,179equations::InviscidBurgersEquation1D)180f = 0.5f0 * u[1]^2181lambda = abs(u[1])182return SVector(0.5f0 * (f - lambda * u[1]))183end184185# Convert conservative variables to primitive186@inline cons2prim(u, equation::InviscidBurgersEquation1D) = u187188# Convert conservative variables to entropy variables189@inline cons2entropy(u, equation::InviscidBurgersEquation1D) = u190@inline entropy2cons(u, equation::InviscidBurgersEquation1D) = u191192@doc raw"""193entropy(u, equations::InviscidBurgersEquation1D)194195Calculate entropy for a conservative state `u` as196```math197S(u) = \frac{1}{2} u^2198```199"""200@inline entropy(u::Real, ::InviscidBurgersEquation1D) = 0.5f0 * u^2201@inline entropy(u, equation::InviscidBurgersEquation1D) = entropy(u[1], equation)202203# Calculate total energy for a conservative state `u`204@inline energy_total(u::Real, ::InviscidBurgersEquation1D) = 0.5f0 * u^2205@inline function energy_total(u, equation::InviscidBurgersEquation1D)206return energy_total(u[1], equation)207end208end # @muladd209210211