Path: blob/main/src/solvers/dgsem_tree/subcell_finite_volume_O2.jl
5590 views
"""1reconstruction_constant(u_ll, u_lr, u_rl, u_rr,2sc_interface_coords,3node_index, limiter, dg)45Returns the constant "reconstructed" values `u_lr, u_rl` at the interface `sc_interface_coords[node_index - 1]`.6Supposed to be used in conjunction with [`VolumeIntegralPureLGLFiniteVolumeO2`](@ref).7Formally first order accurate.8If a first-order finite volume scheme is desired, [`VolumeIntegralPureLGLFiniteVolume`](@ref) is an9equivalent, but more efficient choice.10"""11@inline function reconstruction_constant(u_ll, u_lr, u_rl, u_rr,12sc_interface_coords, node_index,13limiter, dg)14return u_lr, u_rl15end1617# Helper functions for reconstructions below18@inline function reconstruction_linear(u_lr, u_rl, s_l, s_r,19x_lr, x_rl, sc_interface_coords, node_index)20# Linear reconstruction at the interface21u_lr = u_lr + s_l * (sc_interface_coords[node_index - 1] - x_lr)22u_rl = u_rl + s_r * (sc_interface_coords[node_index - 1] - x_rl)2324return u_lr, u_rl25end2627# Reference element:28# -1 ------------------0------------------ 1 -> x29# Gauss-Lobatto-Legendre nodes (schematic for k = 3):30# . . . .31# ^ ^ ^ ^32# Node indices:33# 1 2 3 434# The inner subcell boundaries are governed by the35# cumulative sum of the quadrature weights - 1 .36# -1 ------------------0------------------ 1 -> x37# w1-1 (w1+w2)-1 (w1+w2+w3)-138# | | | | |39# Note that only the inner boundaries are stored.40# Subcell interface indices, loop only over 2 -> nnodes(dg) = 441# 1 2 3 4 542#43# In general a four-point stencil is required, since we reconstruct the44# piecewise linear solution in both subcells next to the subcell interface.45# Since these subcell boundaries are not aligned with the DG nodes,46# on each neighboring subcell two linear solutions are reconstructed => 4 point stencil.47# For the outer interfaces the stencil shrinks since we do not consider values48# outside the element (volume integral).49#50# The left subcell node values are labelled `_ll` (left-left) and `_lr` (left-right), while51# the right subcell node values are labelled `_rl` (right-left) and `_rr` (right-right).5253"""54reconstruction_O2_full(u_ll, u_lr, u_rl, u_rr,55sc_interface_coords, node_index,56limiter, dg::DGSEM)5758Returns the reconstructed values `u_lr, u_rl` at the interface `sc_interface_coords[node_index - 1]`.59Computes limited (linear) slopes on the subcells for a DGSEM element.60Supposed to be used in conjunction with [`VolumeIntegralPureLGLFiniteVolumeO2`](@ref).6162The supplied `limiter` governs the choice of slopes given the nodal values63`u_ll`, `u_lr`, `u_rl`, and `u_rr` at the (Gauss-Lobatto Legendre) nodes.6465**Symmetric** total-Variation-Diminishing (TVD) choices for the limiter are661) [`minmod`](@ref)672) [`monotonized_central`](@ref)683) [`superbee`](@ref)694) [`vanleer`](@ref)705) [`koren_symmetric`](@ref)71**Asymmetric** TVD limiters are also available, e.g.,721) [`koren`](@ref) for positive (right-going) velocities732) [`koren_flipped`](@ref) for negative (left-going) velocities7475The reconstructed slopes are for `reconstruction_O2_full` not limited at the cell boundaries.76Formally second order accurate when used without a limiter, i.e., `limiter = `[`central_slope`](@ref).77This approach corresponds to equation (79) described in78- Rueda-Ramírez, Hennemann, Hindenlang, Winters, & Gassner (2021).79"An entropy stable nodal discontinuous Galerkin method for the resistive MHD equations.80Part II: Subcell finite volume shock capturing"81[JCP: 2021.110580](https://doi.org/10.1016/j.jcp.2021.110580)82"""83@inline function reconstruction_O2_full(u_ll, u_lr, u_rl, u_rr,84sc_interface_coords, node_index,85limiter, dg::DGSEM)86@unpack nodes = dg.basis87x_lr = nodes[node_index - 1]88x_rl = nodes[node_index]8990# Slope between "middle" nodes91s_m = (u_rl - u_lr) / (x_rl - x_lr)9293if node_index == 2 # Catch case ll == lr94s_l = s_m # Use unlimited "central" slope95else96x_ll = nodes[node_index - 2]97# Slope between "left" nodes98s_lr = (u_lr - u_ll) / (x_lr - x_ll)99# Select slope between extrapolated (left) and crossing (middle) slope100s_l = limiter.(s_lr, s_m)101end102103if node_index == nnodes(dg) # Catch case rl == rr104s_r = s_m # Use unlimited "central" slope105else106x_rr = nodes[node_index + 1]107# Slope between "right" nodes108s_rl = (u_rr - u_rl) / (x_rr - x_rl)109# Select slope between crossing (middle) and extrapolated (right) slope110s_r = limiter.(s_m, s_rl)111end112113return reconstruction_linear(u_lr, u_rl, s_l, s_r,114x_lr, x_rl, sc_interface_coords, node_index)115end116117"""118reconstruction_O2_inner(u_ll, u_lr, u_rl, u_rr,119sc_interface_coords, node_index,120limiter, dg::DGSEM)121122Returns the reconstructed values `u_lr, u_rl` at the interface `sc_interface_coords[node_index - 1]`.123Computes limited (linear) slopes on the *inner* subcells for a DGSEM element.124Supposed to be used in conjunction with [`VolumeIntegralPureLGLFiniteVolumeO2`](@ref).125126The supplied `limiter` governs the choice of slopes given the nodal values127`u_ll`, `u_lr`, `u_rl`, and `u_rr` at the (Gauss-Lobatto Legendre) nodes.128129**Symmetric** total-Variation-Diminishing (TVD) choices for the limiter are1301) [`minmod`](@ref)1312) [`monotonized_central`](@ref)1323) [`superbee`](@ref)1334) [`vanleer`](@ref)1345) [`koren_symmetric`](@ref)135**Asymmetric** limiters are also available, e.g.,1361) [`koren`](@ref) for dominantly positive velocities1372) [`koren_flipped`](@ref) for dominantly negative velocities138139For the outer, i.e., boundary subcells, constant values are used, i.e, no reconstruction.140This reduces the order of the scheme below 2.141This approach corresponds to equation (78) described in142- Rueda-Ramírez, Hennemann, Hindenlang, Winters, & Gassner (2021).143"An entropy stable nodal discontinuous Galerkin method for the resistive MHD equations.144Part II: Subcell finite volume shock capturing"145[JCP: 2021.110580](https://doi.org/10.1016/j.jcp.2021.110580)146"""147@inline function reconstruction_O2_inner(u_ll, u_lr, u_rl, u_rr,148sc_interface_coords, node_index,149limiter, dg::DGSEM)150@unpack nodes = dg.basis151x_lr = nodes[node_index - 1]152x_rl = nodes[node_index]153154# Slope between "middle" nodes155s_m = (u_rl - u_lr) / (x_rl - x_lr)156157if node_index == 2 # Catch case ll == lr158# Do not reconstruct at the boundary159s_l = zero(s_m)160else161x_ll = nodes[node_index - 2]162# Slope between "left" nodes163s_lr = (u_lr - u_ll) / (x_lr - x_ll)164# Select slope between extrapolated (left) and crossing (middle) slope165s_l = limiter.(s_lr, s_m)166end167168if node_index == nnodes(dg) # Catch case rl == rr169# Do not reconstruct at the boundary170s_r = zero(s_m)171else172x_rr = nodes[node_index + 1]173# Slope between "right" nodes174s_rl = (u_rr - u_rl) / (x_rr - x_rl)175# Select slope between crossing (middle) and extrapolated (right) slope176s_r = limiter.(s_m, s_rl)177end178179return reconstruction_linear(u_lr, u_rl, s_l, s_r,180x_lr, x_rl, sc_interface_coords, node_index)181end182183"""184central_slope(sl, sr)185186Central, non-TVD reconstruction given left and right slopes `sl` and `sr`.187Gives formally full order of accuracy at the expense of sacrificed nonlinear stability.188Similar in spirit to [`flux_central`](@ref).189"""190@inline function central_slope(sl, sr)191return 0.5f0 * (sl + sr)192end193194"""195minmod(sl, sr)196197Classic minmod limiter function for a TVD reconstruction given left and right slopes `sl` and `sr`.198There are many different ways how the minmod limiter can be implemented.199For reference, see for instance Eq. (6.27) in200201- Randall J. LeVeque (2002)202Finite Volume Methods for Hyperbolic Problems203[DOI: 10.1017/CBO9780511791253](https://doi.org/10.1017/CBO9780511791253)204"""205@inline function minmod(sl, sr)206return 0.5f0 * (sign(sl) + sign(sr)) * min(abs(sl), abs(sr))207end208209"""210monotonized_central(sl, sr)211212Monotonized central limiter function for a TVD reconstruction given left and right slopes `sl` and `sr`.213There are many different ways how the monotonized central limiter can be implemented.214For reference, see for instance Eq. (6.29) in215216- Randall J. LeVeque (2002)217Finite Volume Methods for Hyperbolic Problems218[DOI: 10.1017/CBO9780511791253](https://doi.org/10.1017/CBO9780511791253)219"""220@inline function monotonized_central(sl, sr)221# Use recursive property of minmod function222return minmod(0.5f0 * (sl + sr), 2 * minmod(sl, sr))223end224225"""226superbee(sl, sr)227228Superbee limiter function for a TVD reconstruction given left and right slopes `sl` and `sr`.229There are many different ways how the superbee limiter can be implemented.230For reference, see for instance Eq. (6.28) in231232- Randall J. LeVeque (2002)233Finite Volume Methods for Hyperbolic Problems234[DOI: 10.1017/CBO9780511791253](https://doi.org/10.1017/CBO9780511791253)235"""236@inline function superbee(sl, sr)237return maxmod(minmod(sl, 2 * sr), minmod(2 * sl, sr))238end239240"""241vanleer(sl, sr)242243Symmetric limiter by van Leer.244See for reference page 70 in245246- Siddhartha Mishra, Ulrik Skre Fjordholm and Rémi Abgrall247Numerical methods for conservation laws and related equations.248[Link](https://metaphor.ethz.ch/x/2019/hs/401-4671-00L/literature/mishra_hyperbolic_pdes.pdf)249"""250@inline function vanleer(sl, sr)251if abs(sl) + abs(sr) > zero(sl)252return (abs(sr) * sl + abs(sl) * sr) / (abs(sl) + abs(sr))253else254return zero(sl)255end256end257258"""259koren(sl, sr)260261**Asymmetric** limiter by Barry Koren, originally proposed in Chapter 5.2.2. of262263- B. Koren (1993)264A robust upwind discretization method for advection, diffusion and source terms.265In: C.B. Vreugdenhil, B. Koren (eds): Numerical Methods for Advection-Diffusion Problems.266Notes on Numerical Fluid Mechanics, Vol 15. Braunschweig/Wiesbaden.267[URL](https://ir.cwi.nl/pub/2269/2269D.pdf)268269A version in left/right slopes `sl, sr` is given by equations (14) and (15) in270- P. Jenny (2020)271Time adaptive conservative finite volume method.272[DOI:10.1016/j.jcp.2019.109067](https://doi.org/10.1016/j.jcp.2019.109067)273274This limiter is biased for positive (right-going) velocities.275For the flipped version, which is biased for negative (left-going) velocities,276see [`koren_flipped`](@ref).277"""278@inline function koren(sl, sr)279return minmod(2 * minmod(sl, sr), (sl + 2 * sr) / 3)280end281282"""283koren_flipped(sl, sr)284285**Asymmetric** limiter by Barry Koren, flipped version biased for negative (left-going) velocities.286See [`koren`](@ref) for references.287"""288@inline function koren_flipped(sl, sr)289return koren(sr, sl)290end291292"""293koren_symmetric(sl, sr)294295**Symmetric** version of the [`koren`](@ref) limiter by Barry Koren.296Puts equal weight on left and right slopes.297"""298@inline function koren_symmetric(sl, sr)299return minmod(2 * minmod(sl, sr), minmod(sl + 2 * sr, 2 * sl + sr) / 3)300end301302303