Path: blob/main/src/equations/ideal_glm_mhd_multicomponent_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"""8IdealGlmMhdMulticomponentEquations1D910The ideal compressible multicomponent GLM-MHD equations in one space dimension.11"""12struct IdealGlmMhdMulticomponentEquations1D{NVARS, NCOMP, RealT <: Real} <:13AbstractIdealGlmMhdMulticomponentEquations{1, NVARS, NCOMP}14gammas::SVector{NCOMP, RealT}15gas_constants::SVector{NCOMP, RealT}16cv::SVector{NCOMP, RealT}17cp::SVector{NCOMP, RealT}1819function IdealGlmMhdMulticomponentEquations1D{NVARS, NCOMP, RealT}(gammas::SVector{NCOMP,20RealT},21gas_constants::SVector{NCOMP,22RealT}) where {23NVARS,24NCOMP,25RealT <:26Real27}28NCOMP >= 1 ||29throw(DimensionMismatch("`gammas` and `gas_constants` have to be filled with at least one value"))3031cv = gas_constants ./ (gammas .- 1)32cp = gas_constants + gas_constants ./ (gammas .- 1)3334new(gammas, gas_constants, cv, cp)35end36end3738function IdealGlmMhdMulticomponentEquations1D(; gammas, gas_constants)39_gammas = promote(gammas...)40_gas_constants = promote(gas_constants...)41RealT = promote_type(eltype(_gammas), eltype(_gas_constants))4243__gammas = SVector(map(RealT, _gammas))44__gas_constants = SVector(map(RealT, _gas_constants))4546NVARS = length(_gammas) + 747NCOMP = length(_gammas)4849return IdealGlmMhdMulticomponentEquations1D{NVARS, NCOMP, RealT}(__gammas,50__gas_constants)51end5253# Outer constructor for `@reset` works correctly54function IdealGlmMhdMulticomponentEquations1D(gammas, gas_constants, cv, cp, c_h)55IdealGlmMhdMulticomponentEquations1D(gammas = gammas, gas_constants = gas_constants)56end5758@inline function Base.real(::IdealGlmMhdMulticomponentEquations1D{NVARS, NCOMP, RealT}) where {59NVARS,60NCOMP,61RealT62}63RealT64end6566have_nonconservative_terms(::IdealGlmMhdMulticomponentEquations1D) = False()6768function varnames(::typeof(cons2cons), equations::IdealGlmMhdMulticomponentEquations1D)69cons = ("rho_v1", "rho_v2", "rho_v3", "rho_e", "B1", "B2", "B3")70rhos = ntuple(n -> "rho" * string(n), Val(ncomponents(equations)))71return (cons..., rhos...)72end7374function varnames(::typeof(cons2prim), equations::IdealGlmMhdMulticomponentEquations1D)75prim = ("v1", "v2", "v3", "p", "B1", "B2", "B3")76rhos = ntuple(n -> "rho" * string(n), Val(ncomponents(equations)))77return (prim..., rhos...)78end7980"""81initial_condition_convergence_test(x, t, equations::IdealGlmMhdMulticomponentEquations1D)8283An Alfvén wave as smooth initial condition used for convergence tests.84"""85function initial_condition_convergence_test(x, t,86equations::IdealGlmMhdMulticomponentEquations1D)87# smooth Alfvén wave test from Derigs et al. FLASH (2016)88# domain must be set to [0, 1], γ = 5/38990RealT = eltype(x)91rho = one(RealT)92prim_rho = SVector{ncomponents(equations), real(equations)}(2^(i - 1) * (1 - 2) *93rho / (1 -942^ncomponents(equations))95for i in eachcomponent(equations))96v1 = 097si, co = sincospi(2 * x[1])98v2 = convert(RealT, 0.1) * si99v3 = convert(RealT, 0.1) * co100p = convert(RealT, 0.1)101B1 = 1102B2 = v2103B3 = v3104prim_other = SVector(v1, v2, v3, p, B1, B2, B3)105106return prim2cons(vcat(prim_other, prim_rho), equations)107end108109"""110initial_condition_weak_blast_wave(x, t, equations::IdealGlmMhdMulticomponentEquations1D)111112A weak blast wave adapted from113- Sebastian Hennemann, Gregor J. Gassner (2020)114A provably entropy stable subcell shock capturing approach for high order split form DG115[arXiv: 2008.12044](https://arxiv.org/abs/2008.12044)116"""117function initial_condition_weak_blast_wave(x, t,118equations::IdealGlmMhdMulticomponentEquations1D)119# Adapted MHD version of the weak blast wave from Hennemann & Gassner JCP paper 2020 (Sec. 6.3)120# Same discontinuity in the velocities but with magnetic fields121# Set up polar coordinates122RealT = eltype(x)123inicenter = (0)124x_norm = x[1] - inicenter[1]125r = sqrt(x_norm^2)126phi = atan(x_norm)127128# Calculate primitive variables129# We initialize each species with a fraction of the total density `rho`, such130# that the sum of the densities is `rho := density(prim, equations)`. The density of131# a species is double the density of the next species.132if r > 0.5f0133rho = one(RealT)134prim_rho = SVector{ncomponents(equations), real(equations)}(2^(i - 1) *135(1 - 2) * rho /136(1 -1372^ncomponents(equations))138for i in eachcomponent(equations))139else140rho = convert(RealT, 1.1691)141prim_rho = SVector{ncomponents(equations), real(equations)}(2^(i - 1) *142(1 - 2) * rho /143(1 -1442^ncomponents(equations))145for i in eachcomponent(equations))146end147v1 = r > 0.5f0 ? zero(RealT) : convert(RealT, 0.1882) * cos(phi)148p = r > 0.5f0 ? one(RealT) : convert(RealT, 1.245)149150prim_other = SVector(v1, 0, 0, p, 1, 1, 1)151152return prim2cons(vcat(prim_other, prim_rho), equations)153end154155# Calculate 1D flux for a single point156@inline function flux(u, orientation::Integer,157equations::IdealGlmMhdMulticomponentEquations1D)158rho_v1, rho_v2, rho_v3, rho_e, B1, B2, B3 = u159160rho = density(u, equations)161162v1 = rho_v1 / rho163v2 = rho_v2 / rho164v3 = rho_v3 / rho165kin_en = 0.5f0 * rho * (v1^2 + v2^2 + v3^2)166mag_en = 0.5f0 * (B1^2 + B2^2 + B3^2)167gamma = totalgamma(u, equations)168p = (gamma - 1) * (rho_e - kin_en - mag_en)169170f_rho = densities(u, v1, equations)171f1 = rho_v1 * v1 + p + mag_en - B1^2172f2 = rho_v1 * v2 - B1 * B2173f3 = rho_v1 * v3 - B1 * B3174f4 = (kin_en + gamma * p / (gamma - 1) + 2 * mag_en) * v1 -175B1 * (v1 * B1 + v2 * B2 + v3 * B3)176f5 = 0177f6 = v1 * B2 - v2 * B1178f7 = v1 * B3 - v3 * B1179180f_other = SVector(f1, f2, f3, f4, f5, f6, f7)181182return vcat(f_other, f_rho)183end184185"""186flux_derigs_etal(u_ll, u_rr, orientation, equations::IdealGlmMhdEquations1D)187188Entropy conserving two-point flux adapted by189- Derigs et al. (2018)190Ideal GLM-MHD: About the entropy consistent nine-wave magnetic field191divergence diminishing ideal magnetohydrodynamics equations for multicomponent192[DOI: 10.1016/j.jcp.2018.03.002](https://doi.org/10.1016/j.jcp.2018.03.002)193"""194function flux_derigs_etal(u_ll, u_rr, orientation::Integer,195equations::IdealGlmMhdMulticomponentEquations1D)196# Unpack left and right states to get velocities, pressure, and inverse temperature (called beta)197rho_v1_ll, rho_v2_ll, rho_v3_ll, rho_e_ll, B1_ll, B2_ll, B3_ll = u_ll198rho_v1_rr, rho_v2_rr, rho_v3_rr, rho_e_rr, B1_rr, B2_rr, B3_rr = u_rr199@unpack gammas, gas_constants, cv = equations200201rho_ll = density(u_ll, equations)202rho_rr = density(u_rr, equations)203204gamma_ll = totalgamma(u_ll, equations)205gamma_rr = totalgamma(u_rr, equations)206207rhok_mean = SVector{ncomponents(equations), real(equations)}(ln_mean(u_ll[i + 7],208u_rr[i + 7])209for i in eachcomponent(equations))210rhok_avg = SVector{ncomponents(equations), real(equations)}(0.5f0 * (u_ll[i + 7] +211u_rr[i + 7])212for i in eachcomponent(equations))213214v1_ll = rho_v1_ll / rho_ll215v2_ll = rho_v2_ll / rho_ll216v3_ll = rho_v3_ll / rho_ll217v1_rr = rho_v1_rr / rho_rr218v2_rr = rho_v2_rr / rho_rr219v3_rr = rho_v3_rr / rho_rr220vel_norm_ll = v1_ll^2 + v2_ll^2 + v3_ll^2221vel_norm_rr = v1_rr^2 + v2_rr^2 + v3_rr^2222mag_norm_ll = B1_ll^2 + B2_ll^2 + B3_ll^2223mag_norm_rr = B1_rr^2 + B2_rr^2 + B3_rr^2224# for convenience store v⋅B225vel_dot_mag_ll = v1_ll * B1_ll + v2_ll * B2_ll + v3_ll * B3_ll226vel_dot_mag_rr = v1_rr * B1_rr + v2_rr * B2_rr + v3_rr * B3_rr227228# Compute the necessary mean values needed for either direction229v1_avg = 0.5f0 * (v1_ll + v1_rr)230v2_avg = 0.5f0 * (v2_ll + v2_rr)231v3_avg = 0.5f0 * (v3_ll + v3_rr)232v_sum = v1_avg + v2_avg + v3_avg233B1_avg = 0.5f0 * (B1_ll + B1_rr)234B2_avg = 0.5f0 * (B2_ll + B2_rr)235B3_avg = 0.5f0 * (B3_ll + B3_rr)236vel_norm_avg = 0.5f0 * (vel_norm_ll + vel_norm_rr)237mag_norm_avg = 0.5f0 * (mag_norm_ll + mag_norm_rr)238vel_dot_mag_avg = 0.5f0 * (vel_dot_mag_ll + vel_dot_mag_rr)239240RealT = eltype(u_ll)241enth = zero(RealT)242help1_ll = zero(RealT)243help1_rr = zero(RealT)244245for i in eachcomponent(equations)246enth += rhok_avg[i] * gas_constants[i]247help1_ll += u_ll[i + 7] * cv[i]248help1_rr += u_rr[i + 7] * cv[i]249end250251T_ll = (rho_e_ll - 0.5f0 * rho_ll * (vel_norm_ll) - 0.5f0 * mag_norm_ll) / help1_ll252T_rr = (rho_e_rr - 0.5f0 * rho_rr * (vel_norm_rr) - 0.5f0 * mag_norm_rr) / help1_rr253T = 0.5f0 * (1 / T_ll + 1 / T_rr)254T_log = ln_mean(1 / T_ll, 1 / T_rr)255256# Calculate fluxes depending on orientation with specific direction averages257help1 = zero(RealT)258help2 = zero(RealT)259260f_rho = SVector{ncomponents(equations), real(equations)}(rhok_mean[i] * v1_avg261for i in eachcomponent(equations))262for i in eachcomponent(equations)263help1 += f_rho[i] * cv[i]264help2 += f_rho[i]265end266f1 = help2 * v1_avg + enth / T + 0.5f0 * mag_norm_avg - B1_avg * B1_avg267f2 = help2 * v2_avg - B1_avg * B2_avg268f3 = help2 * v3_avg - B1_avg * B3_avg269f5 = 0270f6 = v1_avg * B2_avg - v2_avg * B1_avg271f7 = v1_avg * B3_avg - v3_avg * B1_avg272273# total energy flux is complicated and involves the previous eight components274v1_mag_avg = 0.5f0 * (v1_ll * mag_norm_ll + v1_rr * mag_norm_rr)275276f4 = (help1 / T_log) - 0.5f0 * (vel_norm_avg) * (help2) + f1 * v1_avg +277f2 * v2_avg +278f3 * v3_avg +279f5 * B1_avg + f6 * B2_avg + f7 * B3_avg - 0.5f0 * v1_mag_avg +280B1_avg * vel_dot_mag_avg281282f_other = SVector(f1, f2, f3, f4, f5, f6, f7)283284return vcat(f_other, f_rho)285end286287"""288flux_hindenlang_gassner(u_ll, u_rr, orientation_or_normal_direction,289equations::IdealGlmMhdMulticomponentEquations1D)290291Adaption of the entropy conserving and kinetic energy preserving two-point flux of292Hindenlang (2019), extending [`flux_ranocha`](@ref) to the MHD equations.293## References294- Florian Hindenlang, Gregor Gassner (2019)295A new entropy conservative two-point flux for ideal MHD equations derived from296first principles.297Presented at HONOM 2019: European workshop on high order numerical methods298for evolutionary PDEs, theory and applications299- Hendrik Ranocha (2018)300Generalised Summation-by-Parts Operators and Entropy Stability of Numerical Methods301for Hyperbolic Balance Laws302[PhD thesis, TU Braunschweig](https://cuvillier.de/en/shop/publications/7743)303- Hendrik Ranocha (2020)304Entropy Conserving and Kinetic Energy Preserving Numerical Methods for305the Euler Equations Using Summation-by-Parts Operators306[Proceedings of ICOSAHOM 2018](https://doi.org/10.1007/978-3-030-39647-3_42)307"""308@inline function flux_hindenlang_gassner(u_ll, u_rr, orientation::Integer,309equations::IdealGlmMhdMulticomponentEquations1D)310# Unpack left and right states311v1_ll, v2_ll, v3_ll, p_ll, B1_ll, B2_ll, B3_ll = cons2prim(u_ll, equations)312v1_rr, v2_rr, v3_rr, p_rr, B1_rr, B2_rr, B3_rr = cons2prim(u_rr, equations)313314rho_ll = density(u_ll, equations)315rho_rr = density(u_rr, equations)316317# Compute the necessary mean values needed for either direction318# Algebraically equivalent to `inv_ln_mean(rho_ll / p_ll, rho_rr / p_rr)`319# in exact arithmetic since320# log((ϱₗ/pₗ) / (ϱᵣ/pᵣ)) / (ϱₗ/pₗ - ϱᵣ/pᵣ)321# = pₗ pᵣ log((ϱₗ pᵣ) / (ϱᵣ pₗ)) / (ϱₗ pᵣ - ϱᵣ pₗ)322inv_rho_p_mean = p_ll * p_rr * inv_ln_mean(rho_ll * p_rr, rho_rr * p_ll)323v1_avg = 0.5f0 * (v1_ll + v1_rr)324v2_avg = 0.5f0 * (v2_ll + v2_rr)325v3_avg = 0.5f0 * (v3_ll + v3_rr)326p_avg = 0.5f0 * (p_ll + p_rr)327velocity_square_avg = 0.5f0 * (v1_ll * v1_rr + v2_ll * v2_rr + v3_ll * v3_rr)328magnetic_square_avg = 0.5f0 * (B1_ll * B1_rr + B2_ll * B2_rr + B3_ll * B3_rr)329330inv_gamma_minus_one = 1 / (totalgamma(0.5f0 * (u_ll + u_rr), equations) - 1)331332rhok_mean = SVector{ncomponents(equations), real(equations)}(ln_mean(u_ll[i + 7],333u_rr[i + 7])334for i in eachcomponent(equations))335rhok_avg = SVector{ncomponents(equations), real(equations)}(0.5f0 * (u_ll[i + 7] +336u_rr[i + 7])337for i in eachcomponent(equations))338339RealT = eltype(u_ll)340f1 = zero(RealT)341f_rho = SVector{ncomponents(equations), real(equations)}(rhok_mean[i] * v1_avg342for i in eachcomponent(equations))343for i in eachcomponent(equations)344f1 += f_rho[i]345end346347# Calculate fluxes depending on orientation with specific direction averages348f2 = f1 * v1_avg + p_avg + magnetic_square_avg -3490.5f0 * (B1_ll * B1_rr + B1_rr * B1_ll)350f3 = f1 * v2_avg - 0.5f0 * (B1_ll * B2_rr + B1_rr * B2_ll)351f4 = f1 * v3_avg - 0.5f0 * (B1_ll * B3_rr + B1_rr * B3_ll)352# f5 below353f6 = 0354f7 = 0.5f0 * (v1_ll * B2_ll - v2_ll * B1_ll + v1_rr * B2_rr - v2_rr * B1_rr)355f8 = 0.5f0 * (v1_ll * B3_ll - v3_ll * B1_ll + v1_rr * B3_rr - v3_rr * B1_rr)356# total energy flux is complicated and involves the previous components357f5 = (f1 * (velocity_square_avg + inv_rho_p_mean * inv_gamma_minus_one)358+3590.5f0 * (+p_ll * v1_rr + p_rr * v1_ll360+ (v1_ll * B2_ll * B2_rr + v1_rr * B2_rr * B2_ll)361+ (v1_ll * B3_ll * B3_rr + v1_rr * B3_rr * B3_ll)362-363(v2_ll * B1_ll * B2_rr + v2_rr * B1_rr * B2_ll)364-365(v3_ll * B1_ll * B3_rr + v3_rr * B1_rr * B3_ll)))366367f_other = SVector(f2, f3, f4, f5, f6, f7, f8)368369return vcat(f_other, f_rho)370end371372# Calculate maximum wave speed for local Lax-Friedrichs-type dissipation373@inline function max_abs_speed_naive(u_ll, u_rr, orientation::Integer,374equations::IdealGlmMhdMulticomponentEquations1D)375rho_v1_ll, _ = u_ll376rho_v1_rr, _ = u_rr377378rho_ll = density(u_ll, equations)379rho_rr = density(u_rr, equations)380381# Calculate velocities (ignore orientation since it is always "1" in 1D)382# and fast magnetoacoustic wave speeds383# left384v_ll = rho_v1_ll / rho_ll385cf_ll = calc_fast_wavespeed(u_ll, orientation, equations)386# right387v_rr = rho_v1_rr / rho_rr388cf_rr = calc_fast_wavespeed(u_rr, orientation, equations)389390return max(abs(v_ll), abs(v_rr)) + max(cf_ll, cf_rr)391end392393# Less "cautious", i.e., less overestimating `λ_max` compared to `max_abs_speed_naive`394@inline function max_abs_speed(u_ll, u_rr, orientation::Integer,395equations::IdealGlmMhdMulticomponentEquations1D)396rho_v1_ll, _ = u_ll397rho_v1_rr, _ = u_rr398399rho_ll = density(u_ll, equations)400rho_rr = density(u_rr, equations)401402# Calculate velocities (ignore orientation since it is always "1" in 1D)403# and fast magnetoacoustic wave speeds404# left405v_ll = rho_v1_ll / rho_ll406cf_ll = calc_fast_wavespeed(u_ll, orientation, equations)407# right408v_rr = rho_v1_rr / rho_rr409cf_rr = calc_fast_wavespeed(u_rr, orientation, equations)410411return max(abs(v_ll) + cf_ll, abs(v_rr) + cf_rr)412end413414@inline function max_abs_speeds(u, equations::IdealGlmMhdMulticomponentEquations1D)415rho_v1, _ = u416417rho = density(u, equations)418419v1 = rho_v1 / rho420421cf_x_direction = calc_fast_wavespeed(u, 1, equations)422423return (abs(v1) + cf_x_direction,)424end425426# Convert conservative variables to primitive427function cons2prim(u, equations::IdealGlmMhdMulticomponentEquations1D)428rho_v1, rho_v2, rho_v3, rho_e, B1, B2, B3 = u429430prim_rho = SVector{ncomponents(equations), real(equations)}(u[i + 7]431for i in eachcomponent(equations))432rho = density(u, equations)433434v1 = rho_v1 / rho435v2 = rho_v2 / rho436v3 = rho_v3 / rho437438gamma = totalgamma(u, equations)439440p = (gamma - 1) *441(rho_e - 0.5f0 * rho * (v1^2 + v2^2 + v3^2) - 0.5f0 * (B1^2 + B2^2 + B3^2))442prim_other = SVector(v1, v2, v3, p, B1, B2, B3)443444return vcat(prim_other, prim_rho)445end446447# Convert conservative variables to entropy448@inline function cons2entropy(u, equations::IdealGlmMhdMulticomponentEquations1D)449rho_v1, rho_v2, rho_v3, rho_e, B1, B2, B3 = u450@unpack cv, gammas, gas_constants = equations451452rho = density(u, equations)453454v1 = rho_v1 / rho455v2 = rho_v2 / rho456v3 = rho_v3 / rho457v_square = v1^2 + v2^2 + v3^2458gamma = totalgamma(u, equations)459p = (gamma - 1) * (rho_e - 0.5f0 * rho * v_square - 0.5f0 * (B1^2 + B2^2 + B3^2))460s = log(p) - gamma * log(rho)461rho_p = rho / p462463# Multicomponent stuff464RealT = eltype(u)465help1 = zero(RealT)466467for i in eachcomponent(equations)468help1 += u[i + 7] * cv[i]469end470471T = (rho_e - 0.5f0 * rho * v_square - 0.5f0 * (B1^2 + B2^2 + B3^2)) / (help1)472473entrop_rho = SVector{ncomponents(equations), real(equations)}(-1 *474(cv[i] * log(T) -475gas_constants[i] *476log(u[i + 7])) +477gas_constants[i] +478cv[i] -479(v_square / (2 * T))480for i in eachcomponent(equations))481482w1 = v1 / T483w2 = v2 / T484w3 = v3 / T485w4 = -1 / T486w5 = B1 / T487w6 = B2 / T488w7 = B3 / T489490entrop_other = SVector(w1, w2, w3, w4, w5, w6, w7)491492return vcat(entrop_other, entrop_rho)493end494495# Convert primitive to conservative variables496@inline function prim2cons(prim, equations::IdealGlmMhdMulticomponentEquations1D)497v1, v2, v3, p, B1, B2, B3 = prim498499cons_rho = SVector{ncomponents(equations), real(equations)}(prim[i + 7]500for i in eachcomponent(equations))501rho = density(prim, equations)502503rho_v1 = rho * v1504rho_v2 = rho * v2505rho_v3 = rho * v3506507gamma = totalgamma(prim, equations)508rho_e = p / (gamma - 1) + 0.5f0 * (rho_v1 * v1 + rho_v2 * v2 + rho_v3 * v3) +5090.5f0 * (B1^2 + B2^2 + B3^2)510511cons_other = SVector(rho_v1, rho_v2, rho_v3, rho_e, B1, B2, B3)512513return vcat(cons_other, cons_rho)514end515516@inline function density_pressure(u, equations::IdealGlmMhdMulticomponentEquations1D)517rho_v1, rho_v2, rho_v3, rho_e, B1, B2, B3 = u518rho = density(u, equations)519gamma = totalgamma(u, equations)520p = (gamma - 1) * (rho_e - 0.5f0 * (rho_v1^2 + rho_v2^2 + rho_v3^2) / rho521-5220.5f0 * (B1^2 + B2^2 + B3^2))523return rho * p524end525526# Compute the fastest wave speed for ideal MHD equations: c_f, the fast magnetoacoustic eigenvalue527@inline function calc_fast_wavespeed(cons, direction,528equations::IdealGlmMhdMulticomponentEquations1D)529rho_v1, rho_v2, rho_v3, rho_e, B1, B2, B3 = cons530rho = density(cons, equations)531v1 = rho_v1 / rho532v2 = rho_v2 / rho533v3 = rho_v3 / rho534v_mag = sqrt(v1^2 + v2^2 + v3^2)535gamma = totalgamma(cons, equations)536p = (gamma - 1) * (rho_e - 0.5f0 * rho * v_mag^2 - 0.5f0 * (B1^2 + B2^2 + B3^2))537a_square = gamma * p / rho538sqrt_rho = sqrt(rho)539b1 = B1 / sqrt_rho540b2 = B2 / sqrt_rho541b3 = B3 / sqrt_rho542b_square = b1^2 + b2^2 + b3^2543544c_f = sqrt(0.5f0 * (a_square + b_square) +5450.5f0 * sqrt((a_square + b_square)^2 - 4 * a_square * b1^2))546547return c_f548end549550@inline function density(u, equations::IdealGlmMhdMulticomponentEquations1D)551RealT = eltype(u)552rho = zero(RealT)553554for i in eachcomponent(equations)555rho += u[i + 7]556end557558return rho559end560561@inline function totalgamma(u, equations::IdealGlmMhdMulticomponentEquations1D)562@unpack cv, gammas = equations563564RealT = eltype(u)565help1 = zero(RealT)566help2 = zero(RealT)567568for i in eachcomponent(equations)569help1 += u[i + 7] * cv[i] * gammas[i]570help2 += u[i + 7] * cv[i]571end572573return help1 / help2574end575576@inline function densities(u, v, equations::IdealGlmMhdMulticomponentEquations1D)577return SVector{ncomponents(equations), real(equations)}(u[i + 7] * v578for i in eachcomponent(equations))579end580end # @muladd581582583