Skip to content

Commit

Permalink
upwind tutorial (#1283)
Browse files Browse the repository at this point in the history
* add NEWS

* WIP: tutorial on upwind FD SBP methods

* first draft of tutorial

* add to make.jl

* fix tutorials?

* Update upwind_fdsbp.jl

* Apply suggestions from code review

Co-authored-by: Michael Schlottke-Lakemper <[email protected]>

* explain bias

Co-authored-by: Michael Schlottke-Lakemper <[email protected]>
  • Loading branch information
ranocha and sloede committed Dec 2, 2022
1 parent 16385b3 commit 9498920
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 7 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ for human readability.

#### Added

- Experimental support for upwind finite difference summation by parts (FDSBP)
has been added. The first implementation requires a `TreeMesh` and comes
with several examples in the `examples_dir()` of Trixi.jl.
- Experimental support for 2D parabolic diffusion terms has been added.
* `LaplaceDiffusion2D` and `CompressibleNavierStokesDiffusion2D` can be used to add
diffusion to systems. `LaplaceDiffusion2D` can be used to add scalar diffusion to each
Expand Down
22 changes: 15 additions & 7 deletions docs/literate/src/files/index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,33 +56,41 @@
# For instance, we show how to set up a finite differences (FD) scheme and a continuous Galerkin
# (CGSEM) method.

# ### [7 Adding a new scalar conservation law](@ref adding_new_scalar_equations)
# ### [7 Upwind FD SBP schemes](@ref upwind_fdsbp)
#-
# General SBP schemes can not only be used via the [`DGMulti`](@ref) solver but
# also with a general `DG` solver. In particular, upwind finite difference SBP
# methods can be used together with the `TreeMesh`. Similar to general SBP
# schemes in the `DGMulti` framework, the interface is based on the package
# [SummationByPartsOperators.jl](https://github.com/ranocha/SummationByPartsOperators.jl).

# ### [8 Adding a new scalar conservation law](@ref adding_new_scalar_equations)
#-
# This tutorial explains how to add a new physics model using the example of the cubic conservation
# law. First, we define the equation using a `struct` `CubicEquation` and the physical flux. Then,
# the corresponding standard setup in Trixi.jl (`mesh`, `solver`, `semi` and `ode`) is implemented
# and the ODE problem is solved by OrdinaryDiffEq's `solve` method.

# ### [8 Adding a non-conservative equation](@ref adding_nonconservative_equation)
# ### [9 Adding a non-conservative equation](@ref adding_nonconservative_equation)
#-
# In this part, another physics model is implemented, the nonconservative linear advection equation.
# We run two different simulations with different levels of refinement and compare the resulting errors.

# ### [9 Adaptive mesh refinement](@ref adaptive_mesh_refinement)
# ### [10 Adaptive mesh refinement](@ref adaptive_mesh_refinement)
#-
# Adaptive mesh refinement (AMR) helps to increase the accuracy in sensitive or turbolent regions while
# not wasting ressources for less interesting parts of the domain. This leads to much more efficient
# simulations. This tutorial presents the implementation strategy of AMR in Trixi, including the use of
# different indicators and controllers.

# ### [10 Structured mesh with curvilinear mapping](@ref structured_mesh_mapping)
# ### [11 Structured mesh with curvilinear mapping](@ref structured_mesh_mapping)
#-
# In this tutorial, the use of Trixi's structured curved mesh type [`StructuredMesh`](@ref) is explained.
# We present the two basic option to initialize such a mesh. First, the curved domain boundaries
# of a circular cylinder are set by explicit boundary functions. Then, a fully curved mesh is
# defined by passing the transformation mapping.

# ### [11 Unstructured meshes with HOHQMesh.jl](@ref hohqmesh_tutorial)
# ### [12 Unstructured meshes with HOHQMesh.jl](@ref hohqmesh_tutorial)
#-
# The purpose of this tutorial is to demonstrate how to use the [`UnstructuredMesh2D`](@ref)
# functionality of Trixi.jl. This begins by running and visualizing an available unstructured
Expand All @@ -91,13 +99,13 @@
# software in the Trixi.jl ecosystem, and then run a simulation using Trixi.jl on said mesh.
# In the end, the tutorial briefly explains how to simulate an example using AMR via `P4estMesh`.

# ### [12 Explicit time stepping](@ref time_stepping)
# ### [13 Explicit time stepping](@ref time_stepping)
# -
# This tutorial is about time integration using [OrdinaryDiffEq.jl](https://github.com/SciML/OrdinaryDiffEq.jl).
# It explains how to use their algorithms and presents two types of time step choices - with error-based
# and CFL-based adaptive step size control.

# ### [13 Differentiable programming](@ref differentiable_programming)
# ### [14 Differentiable programming](@ref differentiable_programming)
#-
# This part deals with some basic differentiable programming topics. For example, a Jacobian, its
# eigenvalues and a curve of total energy (through the simulation) are calculated and plotted for
Expand Down
64 changes: 64 additions & 0 deletions docs/literate/src/files/upwind_fdsbp.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#src # Upwind FD SBP schemes

# General tensor product SBP methods are supported via the `DGMulti` solver
# in a reasonably complete way, see [the previous tutorial](@ref DGMulti_2).
# Nevertheless, there is also experimental support for SBP methods with
# other solver and mesh types.

# The first step is to set up an SBP operator. A classical (central) SBP
# operator can be created as follows.
using Trixi
D_SBP = derivative_operator(SummationByPartsOperators.MattssonNordström2004(),
derivative_order=1, accuracy_order=2,
xmin=0.0, xmax=1.0, N=11)
# Instead of prefixing the source of coefficients `MattssonNordström2004()`,
# you can also load the package SummationByPartsOperators.jl. Either way,
# this yields an object representing the operator efficiently. If you want to
# compare it to coefficients presented in the literature, you can convert it
# to a matrix.
Matrix(D_SBP)

# Upwind SBP operators are a concept introduced in 2017 by Ken Mattsson. You can
# create them as follows.
D_upw = upwind_operators(SummationByPartsOperators.Mattsson2017,
derivative_order=1, accuracy_order=2,
xmin=0.0, xmax=1.0, N=11)
# Upwind operators are derivative operators biased towards one direction.
# The "minus" variants has a bias towards the left side, i.e., it uses values
# from more nodes to the left than from the right to compute the discrete
# derivative approximation at a given node (in the interior of the domain).
# In matrix form, this means more non-zero entries are left from the diagonal.
Matrix(D_upw.minus)
# Analogously, the "plus" variant has a bias towards the right side.
Matrix(D_upw.plus)
# For more information on upwind SBP operators, please refer to the documentation
# of [SummationByPartsOperators.jl](https://github.com/ranocha/SummationByPartsOperators.jl)
# and references cited there.

# The basic idea of upwind SBP schemes is to apply a flux vector splitting and
# use appropriate upwind operators for both parts of the flux. In 1D, this means
# to split the flux
# ```math
# f(u) = f^-(u) + f^+(u)
# ```
# such that $f^-(u)$ is associated with left-going waves and $f^+(u)$ with
# right-going waves. Then, we apply upwind SBP operators $D^-, D^+$ with an
# appropriate upwind bias, resulting in
# ```math
# \partial_x f(u) \approx D^+ f^-(u) + D^- f^+(u)
# ```
# Note that the established notations of upwind operators $D^\pm$ and flux
# splittings $f^\pm$ clash. The right-going waves from $f^+$ need an operator
# biased towards their upwind side, i.e., the left side. This upwind bias is
# provided by the operator $D^-$.

# Many classical flux vector splittings have been developed for finite volume
# methods and are described in the book "Riemann Solvers and Numerical Methods
# for Fluid Dynamics: A Practical Introduction" of Eleuterio F. Toro (2009),
# [DOI: 10.1007/b79761](https://doi.org/10.1007/b79761). One such a well-known
# splitting provided by Trixi.jl is [`splitting_steger_warming`](@ref).

# Trixi.jl comes with several example setups using upwind SBP methods with
# flux vector splitting, e.g.,
# - [`elixir_euler_vortex.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_2d_fdsbp/elixir_euler_vortex.jl)
# - [`elixir_euler_taylor_green_vortex.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/tree_3d_fdsbp/elixir_euler_taylor_green_vortex.jl)
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ files = [
"Non-periodic boundaries" => "non_periodic_boundaries.jl",
"DG schemes via `DGMulti` solver" => "DGMulti_1.jl",
"Other SBP schemes (FD, CGSEM) via `DGMulti` solver" => "DGMulti_2.jl",
"Upwind FD SBP schemes" => "upwind_fdsbp.jl",
# Topic: equations
"Adding a new scalar conservation law" => "adding_new_scalar_equations.jl",
"Adding a non-conservative equation" => "adding_nonconservative_equation.jl",
Expand Down

0 comments on commit 9498920

Please sign in to comment.