Path: blob/main/docs/literate/src/files/DGSEM_FluxDiff.jl
5591 views
#src # DGSEM with flux differencing12# This tutorial starts with a presentation of the weak formulation of the discontinuous Galerkin3# spectral element method (DGSEM) in order to fix the notation of the used operators.4# Then, the DGSEM formulation with flux differencing (split form DGSEM) and its implementation in5# [Trixi.jl](https://github.com/trixi-framework/Trixi.jl) is shown.67# We start with the one-dimensional conservation law8# ```math9# u_t + f(u)_x = 0, \qquad t\in \mathbb{R}^+, x\in\Omega10# ```11# with the physical flux $f$.1213# We split the domain $\Omega$ into elements $K$ with center $x_K$ and size $\Delta x$. With the14# transformation mapping $x(\xi)=x_K + \frac{\Delta x}{2} \xi$ we can transform the reference element15# $[-1,1]$ to every physical element. So, the equation can be restricted to the reference element using the16# determinant of the Jacobian matrix of the transformation mapping17# $J=\frac{\partial x}{\partial \xi}=\frac{\Delta x}{2}$.18# ```math19# J u_t + f(u)_{\xi} = 0, \qquad t\in \mathbb{R}^+, \xi\in [-1,1]20# ```2122# ## The weak form of the DGSEM23# We consider the so-called discontinuous Galerkin spectral element method (DGSEM) with collocation.24# It results from choosing a nodal DG ansatz using $N+1$ Gauss-Lobatto nodes $\xi_i$ in $[-1,1]$25# with matching interpolation weights $w_i$, which are used for numerical integration and interpolation with26# the Lagrange polynomial basis $l_i$ of degree $N$. The Lagrange functions are created with those nodes and27# hence fulfil a Kronecker property at the GL nodes.28# The weak formulation of the DGSEM for one element is29# ```math30# J \underline{\dot{u}}(t) = - M^{-1} B \underline{f}^* + M^{-1} D^T M \underline{f}31# ```32# where $\underline{u}=(u_0, u_1, \dots, u_N)^T\in\mathbb{R}^{N+1}$ is the collected pointwise evaluation33# of $u$ at the discretization nodes and $\dot{u} = \partial u / \partial t = u_t$ is the temporal derivative.34# The nodal values of the flux function $f$ results with collocation in $\underline{f}$, since35# $\underline{f}_j=f(\underline{u}_j)$. Moreover, we got the numerical flux $f^*=f^*(u^-, u^+)$.3637# We will now have a short overview over the operators we used.3839# The **derivative matrix** $D\in\mathbb{R}^{(N+1)\times (N+1)}$ mimics a spatial derivation on a40# discrete level with $\underline{f}_x \approx D \underline{f}$. It is defined by $D_{ij} = l_j'(\xi_i)$.4142# The diagonal **mass matrix** $M$ is defined by $M_{ij}=\langle l_j, l_i\rangle_N$ with the43# numerical scalar product $\langle \cdot, \cdot\rangle_N$ defined for functions $f$ and $g$ by44# ```math45# \langle f, g\rangle_N := \int_{-1, N}^1 f(\xi) g(\xi) d\xi := \sum_{k=0}^N f(\xi_k) g(\xi_k) w_k.46# ```47# The multiplication by $M$ matches a discrete integration48# ```math49# \int_{-1}^1 f(\xi) \underline{l}(\xi) d\xi \approx M \underline{f},50# ```5152# The **boundary matrix** $B=\text{diag}([-1, 0,..., 0, 1])$ represents an evaluation of a53# function at the boundaries $\xi_0=-1$ and $\xi_N=1$.5455# For these operators the following property holds:56# ```math57# M D + (M D)^T = B.58# ```59# This is called the summation-by-parts (SBP) property since it mimics integration by parts on a60# discrete level ([Gassner (2013)](https://doi.org/10.1137/120890144)).6162# The explicit definitions of the operators and the construction of the 1D algorithm can be found63# for instance in the tutorial [introduction to DG methods](@ref scalar_linear_advection_1d)64# or in more detail in [Kopriva (2009)](https://link.springer.com/book/10.1007/978-90-481-2261-5).6566# This property shows the equivalence between the weak form and the following strong formulation67# of the DGSEM.68# ```math69# \begin{align*}70# J \underline{\dot{u}}(t)71# &= - M^{-1} B \underline{f}^* + M^{-1} D^T M \underline{f}\\[5pt]72# &= - M^{-1} B \underline{f}^* + M^{-1} (B - MD) \underline{f}\\[5pt]73# &= - M^{-1} B (\underline{f}^* - \underline{f}) - D \underline{f}74# \end{align*}75# ```76# More information about the equivalence you can find in [Kopriva, Gassner (2010)](https://doi.org/10.1007/s10915-010-9372-3).7778# ## DGSEM with flux differencing79# When using the diagonal SBP property it is possible to rewrite the application of the derivative80# operator $D$ in the calculation of the volume integral into a subcell based finite volume type81# differencing formulation ([Fisher, Carpenter (2013)](https://doi.org/10.1016/j.jcp.2013.06.014)).82# Generalizing83# ```math84# (D \underline{f})_i = \sum_j D_{i,j} \underline{f}_j85# = 2\sum_j \frac{1}{2} D_{i,j} (\underline{f}_j + \underline{f}_i)86# \eqqcolon 2\sum_j D_{i,j} f_\text{central}(u_i, u_j),87# ```88# we replace $D \underline{f}$ in the strong form by $2D \underline{f}_{vol}(u^-, u^+)$ with89# the consistent two-point volume flux $f_{vol}$ and receive the DGSEM formulation with flux differencing90# (split form DGSEM) ([Gassner, Winters, Kopriva (2016)](https://doi.org/10.1016/j.jcp.2016.09.013)).91# The above manipulations are possible due to the "telescoping" property of the derivative matrix ``D``, see92# [Fisher, Carpenter (2013)](https://doi.org/10.1016/j.jcp.2013.06.014).93# In particular, we can check that every row sum ``\sum_j D_{i,j}`` is zero, which makes the94# above manipulations possible:95using Trixi9697N = 398basis = LobattoLegendreBasis(N)99D = basis.derivative_matrix100sum(D, dims = 2)101102# ```math103# \begin{align*}104# J \underline{\dot{u}}(t) &= - M^{-1} B (\underline{f}^* - \underline{f}) - 2D \underline{f}_{vol}(u^-, u^+)\\[5pt]105# &= - M^{-1} B (\underline{f}^* - \underline{f}_{vol}(\underline{u}, \underline{u})) - 2D \underline{f}_{vol}(u^-, u^+)\\[5pt]106# &= - M^{-1} B \underline{f}_{surface}^* - (2D - M^{-1} B) \underline{f}_{vol}\\[5pt]107# &= - M^{-1} B \underline{f}_{surface}^* - D_{split} \underline{f}_{vol}108# \end{align*}109# ```110# This formulation is in a weak form type formulation and can be implemented by using the derivative111# split matrix $D_{split}=(2D-M^{-1}B)$ and two different fluxes. We divide between the surface112# flux $f=f_{surface}$ used for the numerical flux $f_{surface}^*$ and the already mentioned volume113# flux $f_{vol}$ especially for this formulation.114115# This formulation creates a more stable version of DGSEM, because it fulfils entropy stability.116# Moreover it allows the construction of entropy conserving discretizations without relying on117# exact integration. This is achieved when using a symmetric two-point entropy conserving flux function as118# volume flux in the volume flux differencing formulation.119# Then, the numerical surface flux ``\underline{f}_{surface}^*`` can be used to control the120# dissipation of the discretization and to guarantee decreasing entropy, i.e. entropy stability.121122# ## [Implementation in Trixi.jl](@id fluxDiffExample)123# Now, we have a look at the implementation of DGSEM with flux differencing with [Trixi.jl](https://github.com/trixi-framework/Trixi.jl).124using OrdinaryDiffEqLowStorageRK125126# We implement a simulation for the compressible Euler equations in 2D127# ```math128# \partial_t \begin{pmatrix} \rho \\ \rho v_1 \\ \rho v_2 \\ \rho e \end{pmatrix}129# + \partial_x \begin{pmatrix} \rho v_1 \\ \rho v_1^2 + p \\ \rho v_1 v_2 \\ (\rho e +p) v_1 \end{pmatrix}130# + \partial_y \begin{pmatrix} \rho v_2 \\ \rho v_1 v_2 \\ \rho v_2^2 + p \\ (\rho e +p) v_2 \end{pmatrix}131# = \begin{pmatrix} 0 \\ 0 \\ 0 \\ 0 \end{pmatrix}132# ```133# for an ideal gas with ratio of specific heats $\gamma=1.4$.134# Here, $\rho$ is the density, $v_1$, $v_2$ the velocities, $e$ the specific total energy and135# ```math136# p = (\gamma - 1) \left( \rho e - \frac{1}{2} \rho (v_1^2+v_2^2) \right)137# ```138# the pressure.139140gamma = 1.4141equations = CompressibleEulerEquations2D(gamma)142143# As our initial condition we will use a weak blast wave from [Hennemann, Gassner (2020)](https://arxiv.org/abs/2008.12044).144# The primitive variables are defined by145# ```math146# \begin{pmatrix} \rho \\ v_1 \\ v_2 \\ p \end{pmatrix}147# = \begin{pmatrix} 1.0 \\ 0.0 \\ 0.0 \\ 1.0 \end{pmatrix} \text{if } \|x\|_2 > 0.5,\;148# \text{and } \begin{pmatrix} \rho \\ v_1 \\ v_2 \\ p \end{pmatrix}149# = \begin{pmatrix} 1.1691 \\ 0.1882 * \cos(\phi) \\ 0.1882 * \sin(\phi) \\ 1.245 \end{pmatrix} \text{else}150# ```151# with $\phi = \tan^{-1}(\frac{x_2}{x_1})$.152153# This initial condition is implemented in Trixi.jl under the name [`initial_condition_weak_blast_wave`](@ref).154initial_condition = initial_condition_weak_blast_wave155156# In Trixi.jl, flux differencing for the volume integral can be implemented with157# [`VolumeIntegralFluxDifferencing`](@ref) using symmetric two-point volume fluxes.158# First, we set up a simulation with the entropy conserving and kinetic energy preserving159# flux [`flux_ranocha`](@ref) by [Hendrik Ranocha (2018)](https://cuvillier.de/en/shop/publications/7743)160# as surface and volume flux.161162# We will confirm the entropy conservation property numerically.163164volume_flux = flux_ranocha # = f_vol165solver = DGSEM(polydeg = N, surface_flux = volume_flux,166volume_integral = VolumeIntegralFluxDifferencing(volume_flux))167168# Now, we implement Trixi.jl's `mesh`, `semi` and `ode` in a simple framework. For more information please169# have a look at the documentation, the basic tutorial [introduction to DG methods](@ref scalar_linear_advection_1d)170# or some basic elixirs.171coordinates_min = (-2.0, -2.0)172coordinates_max = (2.0, 2.0)173mesh = TreeMesh(coordinates_min, coordinates_max,174initial_refinement_level = 5,175n_cells_max = 10_000,176periodicity = true)177178semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,179boundary_conditions = boundary_condition_periodic)180181## ODE solvers182tspan = (0.0, 0.4)183ode = semidiscretize(semi, tspan);184185# To analyse the entropy conservation of the approximation, we will use the analysis callback186# implemented in Trixi. It provides some information about the approximation including the entropy change.187analysis_callback = AnalysisCallback(semi, interval = 100);188189# We now run the simulation using `flux_ranocha` for both surface and volume flux.190sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6,191ode_default_options()..., callback = analysis_callback);192# A look at the change in entropy $\sum \partial S/\partial U \cdot U_t$ in the analysis callback193# confirms that the flux is entropy conserving since the change is about machine precision.194195# We can plot the approximated solution at the time `t=0.4`.196using Plots197plot(sol)198199# Now, we can use for instance the dissipative flux [`flux_lax_friedrichs`](@ref) as surface flux200# to get an entropy stable method.201using OrdinaryDiffEqLowStorageRK, Trixi202203gamma = 1.4204equations = CompressibleEulerEquations2D(gamma)205206initial_condition = initial_condition_weak_blast_wave207208volume_flux = flux_ranocha # = f_vol209solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs,210volume_integral = VolumeIntegralFluxDifferencing(volume_flux))211212coordinates_min = (-2.0, -2.0)213coordinates_max = (2.0, 2.0)214mesh = TreeMesh(coordinates_min, coordinates_max,215initial_refinement_level = 5,216n_cells_max = 10_000,217periodicity = true)218219semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,220boundary_conditions = boundary_condition_periodic)221222## ODE solvers223tspan = (0.0, 0.4)224ode = semidiscretize(semi, tspan);225226analysis_callback = AnalysisCallback(semi, interval = 100);227228# We now run the simulation using the volume flux `flux_ranocha` and surface flux `flux_lax_friedrichs`.229sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6,230ode_default_options()..., callback = analysis_callback);231# The change in entropy confirms the expected entropy stability.232233using Plots234plot(sol)235236# Of course, you can use more than these two fluxes in Trixi. Here, we will give a short list237# of possible fluxes for the compressible Euler equations.238# For the volume flux Trixi.jl provides for example [`flux_ranocha`](@ref), [`flux_shima_etal`](@ref),239# [`flux_chandrashekar`](@ref), [`flux_kennedy_gruber`](@ref).240# As surface flux you can use all volume fluxes and additionally for instance [`flux_lax_friedrichs`](@ref),241# [`flux_hll`](@ref), [`flux_hllc`](@ref).242243# ## Package versions244245# These results were obtained using the following versions.246247using InteractiveUtils248versioninfo()249250using Pkg251Pkg.status(["Trixi", "OrdinaryDiffEqLowStorageRK", "Plots"],252mode = PKGMODE_MANIFEST)253254255