Skip to content

Commit

Permalink
Merge branch 'main' into msl/add-numfocus
Browse files Browse the repository at this point in the history
  • Loading branch information
sloede authored Nov 2, 2023
2 parents f62a5d5 + 08a2e09 commit 71dd0d2
Show file tree
Hide file tree
Showing 23 changed files with 1,268 additions and 207 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/SpellCheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ jobs:
- name: Checkout Actions Repository
uses: actions/checkout@v4
- name: Check spelling
uses: crate-ci/[email protected].15
uses: crate-ci/[email protected].21
108 changes: 108 additions & 0 deletions examples/tree_2d_dgsem/elixir_mhd_shockcapturing_subcell.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the compressible ideal GLM-MHD equations

equations = IdealGlmMhdEquations2D(1.4)

"""
initial_condition_blast_wave(x, t, equations::IdealGlmMhdEquations2D)
An MHD blast wave modified from:
- Dominik Derigs, Gregor J. Gassner, Stefanie Walch & Andrew R. Winters (2018)
Entropy Stable Finite Volume Approximations for Ideal Magnetohydrodynamics
[doi: 10.1365/s13291-018-0178-9](https://doi.org/10.1365/s13291-018-0178-9)
This setup needs a positivity limiter for the density.
"""
function initial_condition_blast_wave(x, t, equations::IdealGlmMhdEquations2D)
# setup taken from Derigs et al. DMV article (2018)
# domain must be [-0.5, 0.5] x [-0.5, 0.5], γ = 1.4
r = sqrt(x[1]^2 + x[2]^2)

pmax = 10.0
pmin = 1.0
rhomax = 1.0
rhomin = 0.01
if r <= 0.09
p = pmax
rho = rhomax
elseif r >= 0.1
p = pmin
rho = rhomin
else
p = pmin + (0.1 - r) * (pmax - pmin) / 0.01
rho = rhomin + (0.1 - r) * (rhomax - rhomin) / 0.01
end
v1 = 0.0
v2 = 0.0
v3 = 0.0
B1 = 1.0/sqrt(4.0*pi)
B2 = 0.0
B3 = 0.0
psi = 0.0
return prim2cons(SVector(rho, v1, v2, v3, p, B1, B2, B3, psi), equations)
end
initial_condition = initial_condition_blast_wave

surface_flux = (flux_lax_friedrichs, flux_nonconservative_powell_local_symmetric)
volume_flux = (flux_derigs_etal, flux_nonconservative_powell_local_symmetric)
basis = LobattoLegendreBasis(3)

limiter_idp = SubcellLimiterIDP(equations, basis;
positivity_variables_cons=[1],
positivity_correction_factor=0.5)
volume_integral = VolumeIntegralSubcellLimiting(limiter_idp;
volume_flux_dg=volume_flux,
volume_flux_fv=surface_flux)
solver = DGSEM(basis, surface_flux, volume_integral)

coordinates_min = (-0.5, -0.5)
coordinates_max = ( 0.5, 0.5)
mesh = TreeMesh(coordinates_min, coordinates_max,
initial_refinement_level=4,
n_cells_max=10_000)


semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver)


###############################################################################
# ODE solvers, callbacks etc.

tspan = (0.0, 0.1)
ode = semidiscretize(semi, tspan)

summary_callback = SummaryCallback()

analysis_interval = 100
analysis_callback = AnalysisCallback(semi, interval=analysis_interval)

alive_callback = AliveCallback(analysis_interval=analysis_interval)

save_solution = SaveSolutionCallback(interval=100,
save_initial_solution=true,
save_final_solution=true,
solution_variables=cons2prim)

cfl = 0.5
stepsize_callback = StepsizeCallback(cfl=cfl)

glm_speed_callback = GlmSpeedCallback(glm_scale=0.5, cfl=cfl)

callbacks = CallbackSet(summary_callback,
analysis_callback,
alive_callback,
save_solution,
stepsize_callback,
glm_speed_callback)

###############################################################################
# run the simulation
stage_callbacks = (SubcellLimiterIDPCorrection(), BoundsCheckCallback())

sol = Trixi.solve(ode, Trixi.SimpleSSPRK33(stage_callbacks=stage_callbacks);
dt=1.0, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep=false, callback=callbacks);
summary_callback() # print the timer summary
2 changes: 1 addition & 1 deletion src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export GradientVariablesPrimitive, GradientVariablesEntropy
export flux, flux_central, flux_lax_friedrichs, flux_hll, flux_hllc, flux_hlle,
flux_godunov,
flux_chandrashekar, flux_ranocha, flux_derigs_etal, flux_hindenlang_gassner,
flux_nonconservative_powell,
flux_nonconservative_powell, flux_nonconservative_powell_local_symmetric,
flux_kennedy_gruber, flux_shima_etal, flux_ec,
flux_fjordholm_etal, flux_nonconservative_fjordholm_etal, flux_es_fjordholm_etal,
flux_wintermeyer_etal, flux_nonconservative_wintermeyer_etal,
Expand Down
10 changes: 5 additions & 5 deletions src/callbacks_stage/subcell_limiter_idp_correction_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

function perform_idp_correction!(u, dt, mesh::TreeMesh2D, equations, dg, cache)
@unpack inverse_weights = dg.basis
@unpack antidiffusive_flux1, antidiffusive_flux2 = cache.antidiffusive_fluxes
@unpack antidiffusive_flux1_L, antidiffusive_flux2_L, antidiffusive_flux1_R, antidiffusive_flux2_R = cache.antidiffusive_fluxes
@unpack alpha1, alpha2 = dg.volume_integral.limiter.cache.subcell_limiter_coefficients

@threaded for element in eachelement(dg, cache)
Expand All @@ -17,16 +17,16 @@ function perform_idp_correction!(u, dt, mesh::TreeMesh2D, equations, dg, cache)
for j in eachnode(dg), i in eachnode(dg)
# Note: antidiffusive_flux1[v, i, xi, element] = antidiffusive_flux2[v, xi, i, element] = 0 for all i in 1:nnodes and xi in {1, nnodes+1}
alpha_flux1 = (1 - alpha1[i, j, element]) *
get_node_vars(antidiffusive_flux1, equations, dg, i, j,
get_node_vars(antidiffusive_flux1_R, equations, dg, i, j,
element)
alpha_flux1_ip1 = (1 - alpha1[i + 1, j, element]) *
get_node_vars(antidiffusive_flux1, equations, dg, i + 1,
get_node_vars(antidiffusive_flux1_L, equations, dg, i + 1,
j, element)
alpha_flux2 = (1 - alpha2[i, j, element]) *
get_node_vars(antidiffusive_flux2, equations, dg, i, j,
get_node_vars(antidiffusive_flux2_R, equations, dg, i, j,
element)
alpha_flux2_jp1 = (1 - alpha2[i, j + 1, element]) *
get_node_vars(antidiffusive_flux2, equations, dg, i,
get_node_vars(antidiffusive_flux2_L, equations, dg, i,
j + 1, element)

for v in eachvariable(equations)
Expand Down
36 changes: 4 additions & 32 deletions src/equations/compressible_euler_1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ function flux_hllc(u_ll, u_rr, orientation::Integer,
end

"""
flux_hlle(u_ll, u_rr, orientation, equations::CompressibleEulerEquations1D)
min_max_speed_einfeldt(u_ll, u_rr, orientation, equations::CompressibleEulerEquations1D)
Computes the HLLE (Harten-Lax-van Leer-Einfeldt) flux for the compressible Euler equations.
Special estimates of the signal velocites and linearization of the Riemann problem developed
Expand All @@ -825,8 +825,8 @@ Compactly summarized:
Numerical methods for conservation laws and related equations.
[Link](https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf)
"""
function flux_hlle(u_ll, u_rr, orientation::Integer,
equations::CompressibleEulerEquations1D)
@inline function min_max_speed_einfeldt(u_ll, u_rr, orientation::Integer,
equations::CompressibleEulerEquations1D)
# Calculate primitive variables, enthalpy and speed of sound
rho_ll, v_ll, p_ll = cons2prim(u_ll, equations)
rho_rr, v_rr, p_rr = cons2prim(u_rr, equations)
Expand Down Expand Up @@ -858,35 +858,7 @@ function flux_hlle(u_ll, u_rr, orientation::Integer,
SsL = min(v_roe - c_roe, v_ll - beta * c_ll, zero(v_roe))
SsR = max(v_roe + c_roe, v_rr + beta * c_rr, zero(v_roe))

if SsL >= 0.0 && SsR > 0.0
# Positive supersonic speed
f_ll = flux(u_ll, orientation, equations)

f1 = f_ll[1]
f2 = f_ll[2]
f3 = f_ll[3]
elseif SsR <= 0.0 && SsL < 0.0
# Negative supersonic speed
f_rr = flux(u_rr, orientation, equations)

f1 = f_rr[1]
f2 = f_rr[2]
f3 = f_rr[3]
else
# Subsonic case
# Compute left and right fluxes
f_ll = flux(u_ll, orientation, equations)
f_rr = flux(u_rr, orientation, equations)

f1 = (SsR * f_ll[1] - SsL * f_rr[1] + SsL * SsR * (u_rr[1] - u_ll[1])) /
(SsR - SsL)
f2 = (SsR * f_ll[2] - SsL * f_rr[2] + SsL * SsR * (u_rr[2] - u_ll[2])) /
(SsR - SsL)
f3 = (SsR * f_ll[3] - SsL * f_rr[3] + SsL * SsR * (u_rr[3] - u_ll[3])) /
(SsR - SsL)
end

return SVector(f1, f2, f3)
return SsL, SsR
end

@inline function max_abs_speeds(u, equations::CompressibleEulerEquations1D)
Expand Down
92 changes: 59 additions & 33 deletions src/equations/compressible_euler_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@ function flux_hllc(u_ll, u_rr, orientation::Integer,
end

"""
flux_hlle(u_ll, u_rr, orientation, equations::CompressibleEulerEquations2D)
min_max_speed_einfeldt(u_ll, u_rr, orientation, equations::CompressibleEulerEquations2D)
Computes the HLLE (Harten-Lax-van Leer-Einfeldt) flux for the compressible Euler equations.
Special estimates of the signal velocites and linearization of the Riemann problem developed
Expand All @@ -1267,8 +1267,8 @@ of the numerical flux.
On Godunov-type methods near low densities.
[DOI: 10.1016/0021-9991(91)90211-3](https://doi.org/10.1016/0021-9991(91)90211-3)
"""
function flux_hlle(u_ll, u_rr, orientation::Integer,
equations::CompressibleEulerEquations2D)
@inline function min_max_speed_einfeldt(u_ll, u_rr, orientation::Integer,
equations::CompressibleEulerEquations2D)
# Calculate primitive variables, enthalpy and speed of sound
rho_ll, v1_ll, v2_ll, p_ll = cons2prim(u_ll, equations)
rho_rr, v1_rr, v2_rr, p_rr = cons2prim(u_rr, equations)
Expand Down Expand Up @@ -1306,39 +1306,65 @@ function flux_hlle(u_ll, u_rr, orientation::Integer,
SsR = max(v2_roe + c_roe, v2_rr + beta * c_rr, zero(v2_roe))
end

if SsL >= 0.0 && SsR > 0.0
# Positive supersonic speed
f_ll = flux(u_ll, orientation, equations)
return SsL, SsR
end

f1 = f_ll[1]
f2 = f_ll[2]
f3 = f_ll[3]
f4 = f_ll[4]
elseif SsR <= 0.0 && SsL < 0.0
# Negative supersonic speed
f_rr = flux(u_rr, orientation, equations)
"""
min_max_speed_einfeldt(u_ll, u_rr, normal_direction, equations::CompressibleEulerEquations2D)
f1 = f_rr[1]
f2 = f_rr[2]
f3 = f_rr[3]
f4 = f_rr[4]
else
# Subsonic case
# Compute left and right fluxes
f_ll = flux(u_ll, orientation, equations)
f_rr = flux(u_rr, orientation, equations)

f1 = (SsR * f_ll[1] - SsL * f_rr[1] + SsL * SsR * (u_rr[1] - u_ll[1])) /
(SsR - SsL)
f2 = (SsR * f_ll[2] - SsL * f_rr[2] + SsL * SsR * (u_rr[2] - u_ll[2])) /
(SsR - SsL)
f3 = (SsR * f_ll[3] - SsL * f_rr[3] + SsL * SsR * (u_rr[3] - u_ll[3])) /
(SsR - SsL)
f4 = (SsR * f_ll[4] - SsL * f_rr[4] + SsL * SsR * (u_rr[4] - u_ll[4])) /
(SsR - SsL)
end
Computes the HLLE (Harten-Lax-van Leer-Einfeldt) flux for the compressible Euler equations.
Special estimates of the signal velocites and linearization of the Riemann problem developed
by Einfeldt to ensure that the internal energy and density remain positive during the computation
of the numerical flux.
return SVector(f1, f2, f3, f4)
- Bernd Einfeldt (1988)
On Godunov-type methods for gas dynamics.
[DOI: 10.1137/0725021](https://doi.org/10.1137/0725021)
- Bernd Einfeldt, Claus-Dieter Munz, Philip L. Roe and Björn Sjögreen (1991)
On Godunov-type methods near low densities.
[DOI: 10.1016/0021-9991(91)90211-3](https://doi.org/10.1016/0021-9991(91)90211-3)
"""
@inline function min_max_speed_einfeldt(u_ll, u_rr, normal_direction::AbstractVector,
equations::CompressibleEulerEquations2D)
# Calculate primitive variables, enthalpy and speed of sound
rho_ll, v1_ll, v2_ll, p_ll = cons2prim(u_ll, equations)
rho_rr, v1_rr, v2_rr, p_rr = cons2prim(u_rr, equations)

v_dot_n_ll = v1_ll * normal_direction[1] + v2_ll * normal_direction[2]
v_dot_n_rr = v1_rr * normal_direction[1] + v2_rr * normal_direction[2]

norm_ = norm(normal_direction)

# `u_ll[4]` is total energy `rho_e_ll` on the left
H_ll = (u_ll[4] + p_ll) / rho_ll
c_ll = sqrt(equations.gamma * p_ll / rho_ll) * norm_

# `u_rr[4]` is total energy `rho_e_rr` on the right
H_rr = (u_rr[4] + p_rr) / rho_rr
c_rr = sqrt(equations.gamma * p_rr / rho_rr) * norm_

# Compute Roe averages
sqrt_rho_ll = sqrt(rho_ll)
sqrt_rho_rr = sqrt(rho_rr)
inv_sum_sqrt_rho = inv(sqrt_rho_ll + sqrt_rho_rr)

v1_roe = (sqrt_rho_ll * v1_ll + sqrt_rho_rr * v1_rr) * inv_sum_sqrt_rho
v2_roe = (sqrt_rho_ll * v2_ll + sqrt_rho_rr * v2_rr) * inv_sum_sqrt_rho
v_roe = v1_roe * normal_direction[1] + v2_roe * normal_direction[2]
v_roe_mag = (v1_roe * normal_direction[1])^2 + (v2_roe * normal_direction[2])^2

H_roe = (sqrt_rho_ll * H_ll + sqrt_rho_rr * H_rr) * inv_sum_sqrt_rho
c_roe = sqrt((equations.gamma - 1) * (H_roe - 0.5 * v_roe_mag)) * norm_

# Compute convenience constant for positivity preservation, see
# https://doi.org/10.1016/0021-9991(91)90211-3
beta = sqrt(0.5 * (equations.gamma - 1) / equations.gamma)

# Estimate the edges of the Riemann fan (with positivity conservation)
SsL = min(v_roe - c_roe, v_dot_n_ll - beta * c_ll, zero(v_roe))
SsR = max(v_roe + c_roe, v_dot_n_rr + beta * c_rr, zero(v_roe))

return SsL, SsR
end

@inline function max_abs_speeds(u, equations::CompressibleEulerEquations2D)
Expand Down
Loading

0 comments on commit 71dd0d2

Please sign in to comment.