Path: blob/main/src/solvers/solvers_parabolic.jl
5586 views
"""1ParabolicFormulationBassiRebay1()23The classical BR1 flux from45- F. Bassi, S. Rebay (1997)6A High-Order Accurate Discontinuous Finite Element Method for7the Numerical Solution of the Compressible Navier-Stokes Equations8[DOI: 10.1006/jcph.1996.5572](https://doi.org/10.1006/jcph.1996.5572)910A more detailed study of the BR1 scheme for the DGSEM can be found in11- G. J. Gassner, A. R. Winters, F. J. Hindenlang, D. Kopriva (2018)12The BR1 Scheme is Stable for the Compressible Navier-Stokes Equations13[DOI: 10.1007/s10915-018-0702-1](https://doi.org/10.1007/s10915-018-0702-1)1415The BR1 scheme works well for convection-dominated problems, but may cause instabilities or16reduced convergence for diffusion-dominated problems.17In the latter case, the [`ParabolicFormulationLocalDG`](@ref) scheme is recommended.18"""19struct ParabolicFormulationBassiRebay1 end2021"""22flux_parabolic(u_ll, u_rr,23gradient_or_divergence, equations_parabolic,24parabolic_scheme::ParabolicFormulationBassiRebay1)2526flux_parabolic(u_ll, u_rr, normal_direction::AbstractVector,27gradient_or_divergence, equations_parabolic,28parabolic_scheme::ParabolicFormulationBassiRebay1)2930This computes the classical BR1 flux. Since the interface flux for both the31DG gradient and DG divergence under BR1 are identical, this function does32not need to be specialized for `Gradient` and `Divergence`.3334`normal_direction` is not used in the BR1 flux,35but is included as an argument for consistency with the [`ParabolicFormulationLocalDG`](@ref) flux,36which does use the `normal_direction` to compute the LDG "switch" on the generally non-Cartesian [`P4estMesh`](@ref).37"""38function flux_parabolic(u_ll, u_rr, # Version for `TreeMesh`39gradient_or_divergence, equations_parabolic,40parabolic_scheme::ParabolicFormulationBassiRebay1)41return 0.5f0 * (u_ll + u_rr)42end43# Version for `P4estMesh`44function flux_parabolic(u_ll, u_rr, normal_direction::AbstractVector,45gradient_or_divergence, equations_parabolic,46parabolic_scheme::ParabolicFormulationBassiRebay1)47return 0.5f0 * (u_ll + u_rr)48end4950"""51ParabolicFormulationLocalDG(penalty_parameter)5253The local DG (LDG) flux from "The Local Discontinuous Galerkin Method for Time-Dependent54Convection-Diffusion Systems" by Cockburn and Shu (1998).5556The parabolic "upwinding" vector is currently implemented for `TreeMesh`; for all other mesh types,57the LDG solver is equivalent to [`ParabolicFormulationBassiRebay1`](@ref) with an LDG-type penalization.5859- Cockburn and Shu (1998).60The Local Discontinuous Galerkin Method for Time-Dependent61Convection-Diffusion Systems62[DOI: 10.1137/S0036142997316712](https://doi.org/10.1137/S0036142997316712)63"""64struct ParabolicFormulationLocalDG{P}65penalty_parameter::P66end6768"""69ParabolicFormulationLocalDG()7071The minimum dissipation local DG (LDG) flux from "An Analysis of the Minimal Dissipation Local72Discontinuous Galerkin Method for Convection–Diffusion Problems" by Cockburn and Dong (2007).73This scheme corresponds to an LDG parabolic "upwinding/downwinding" but no LDG penalty parameter.74Cockburn and Dong proved that this scheme is still stable despite the zero penalty parameter.7576- Cockburn and Dong (2007)77An Analysis of the Minimal Dissipation Local Discontinuous78Galerkin Method for Convection–Diffusion Problems.79[DOI: 10.1007/s10915-007-9130-3](https://doi.org/10.1007/s10915-007-9130-3)80"""81ParabolicFormulationLocalDG() = ParabolicFormulationLocalDG(nothing)8283@doc raw"""84flux_parabolic(u_ll, u_rr,85::Gradient, equations_parabolic,86parabolic_scheme::ParabolicFormulationLocalDG)8788flux_parabolic(u_ll, u_rr, normal_direction,89::Gradient, equations_parabolic,90parabolic_scheme::ParabolicFormulationLocalDG)9192These fluxes computes the gradient and divergence interface fluxes for the93local DG method. The local DG method uses an "upwind/downwind" flux for the94gradient and divergence (i.e., if the gradient is upwinded, the divergence95must be downwinded in order to preserve symmetry and positive definiteness).96Here, we use the convention that the gradient flux is upwinded, thus we have97```math98f_{\text{gradient}} = u_{L}99```100on the Cartesian [`TreeMesh`](@ref).101102For the [`P4estMesh`](@ref), the `normal_direction` is used to compute the LDG "switch" ``\sigma`` for the upwinding.103This is realized by selecting the sign of the maximum (in absolute value sense) normal direction component,104which corresponds to the "dominant" direction of the interface normal.105```math106i = \text{argmax} \{ \begin{pmatrix} \vert n_1 \vert \\ \vert n_2 \vert \\ \dots \end{pmatrix} \}107\sigma = \text{sign} (n_i)108```109"""110function flux_parabolic(u_ll, u_rr, # Version for `TreeMesh`111::Gradient, equations_parabolic,112parabolic_scheme::ParabolicFormulationLocalDG)113# The LDG flux is {{f}} + beta * [[f]], where beta is the LDG "switch",114# which we set to -1 on the left and +1 on the right in 1D. The sign of the115# jump term should be opposite that of the sign used in the divergence flux.116# This is equivalent to setting the flux equal to `u_ll` for the gradient,117# and `u_rr` for the divergence.118return u_ll # Use the upwind value for the gradient interface flux119end120# Version for `P4estMesh`121function flux_parabolic(u_ll, u_rr, normal_direction,122::Gradient, equations_parabolic,123parabolic_scheme::ParabolicFormulationLocalDG)124# Use "Upwind in dominant direction" for LDG switch125abs_max_dir = argmax(abs.(normal_direction))126ldg_switch = sign(normal_direction[abs_max_dir])127return 0.5f0 * (u_ll + u_rr - ldg_switch * (u_rr - u_ll))128end129130@doc raw"""131flux_parabolic(u_ll, u_rr,132::Divergence, equations_parabolic,133parabolic_scheme::ParabolicFormulationLocalDG)134135flux_parabolic(u_ll, u_rr, normal_direction,136::Divergence, equations_parabolic,137parabolic_scheme::ParabolicFormulationLocalDG)138139These fluxes computes the gradient and divergence interface fluxes for the140local DG method. The local DG method uses an "upwind/downwind" flux for the141gradient and divergence (i.e., if the gradient is upwinded, the divergence142must be downwinded in order to preserve symmetry and positive definiteness).143Here, we use the convention that, because the gradient flux is upwinded, the divergence flux is downwinded.144Thus we have145```math146f_{\text{divergence}} = u_{R}147```148on the Cartesian [`TreeMesh`](@ref).149150For the [`P4estMesh`](@ref), the `normal_direction` is used to compute the LDG "switch" ``\sigma`` for the downwinding.151This is realized by selecting the sign of the maximum (in absolute value sense) normal direction component,152which corresponds to the "dominant" direction of the interface normal.153```math154i = \text{argmax} \{ \begin{pmatrix} \vert n_1 \vert \\ \vert n_2 \vert \\ \dots \end{pmatrix} \}155\sigma = -\text{sign} (n_i)156```157"""158function flux_parabolic(u_ll, u_rr, # Version for `TreeMesh`159::Divergence, equations_parabolic,160parabolic_scheme::ParabolicFormulationLocalDG)161return u_rr # Use the downwind value for the divergence interface flux162end163# Version for `P4estMesh`164function flux_parabolic(u_ll, u_rr, normal_direction,165::Divergence, equations_parabolic,166parabolic_scheme::ParabolicFormulationLocalDG)167# Use "Downwind in dominant direction" for LDG switch168abs_max_dir = argmax(abs.(normal_direction))169ldg_switch = -sign(normal_direction[abs_max_dir])170return 0.5f0 * (u_ll + u_rr - ldg_switch * (u_rr - u_ll))171end172173default_parabolic_solver() = ParabolicFormulationBassiRebay1()174175176