Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement BR1 scheme #378

Closed
wants to merge 59 commits into from
Closed
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
ec90914
Add "GradientEquations2D" and start adding stuff to cache
sloede Dec 11, 2020
0422a0a
Update gradient equations
sloede Dec 11, 2020
59d52c6
Bug fixes for GradientEquations2D
sloede Dec 11, 2020
01ad2ba
Add heat equation in 2D
sloede Dec 11, 2020
9a5396a
Fix sign in gradient equations to calculate gradient and not negative…
sloede Dec 11, 2020
d3bcf3c
Hack in the calculation of the Laplacian in DG 2D
sloede Dec 11, 2020
cf6cc6a
Add elixir for heat equation
sloede Dec 11, 2020
d21e1c4
Bug fixes
sloede Dec 11, 2020
9eefbab
Add advection-diffusion equation
sloede Dec 13, 2020
de8618b
Add test for linear advection-diffusion
sloede Jan 17, 2021
4265f1d
Remove duplicate function
sloede Jan 17, 2021
926b173
Add test for heat equation
sloede Jan 18, 2021
7eaeb20
Add semi parabolic aux vars
sloede Jan 18, 2021
8d1941f
Add parabolic flux function to heat equation
sloede Jan 18, 2021
5d76839
Allow creation of solvers for auxiliary variables
sloede Jan 18, 2021
4b4b2cd
Switch heat equation to parabolic semi
sloede Jan 18, 2021
a79f897
Heat equation test still passes
sloede Jan 18, 2021
7dfa562
Add parabolic central flux
sloede Jan 18, 2021
1e7a811
Add functionality for DG to handle parabolic system
sloede Jan 18, 2021
98f619f
Pass gradients cache to rhs!
sloede Jan 18, 2021
d748522
Use central flux
sloede Jan 18, 2021
c9b813b
Fix sign of the flux
sloede Jan 18, 2021
7c7e295
Add parabolic flux to advection-diffusion equation
sloede Jan 18, 2021
a9d11c7
Add hyperbolic-parabolic semidiscretization
sloede Jan 18, 2021
317a76b
Change adv-diff elixir such that it works again (without mortars yet)
sloede Jan 18, 2021
3aca3e2
Move parabolic implementaiton to different file
sloede Jan 18, 2021
9e99677
Implement mortar fluxes
sloede Jan 18, 2021
3efdb0d
re-enable mortars for adv-div; convergence tests works but different …
sloede Jan 18, 2021
44d1bd9
Remove `have_parabolic_terms` at it is currently not needed
sloede Jan 18, 2021
d477c13
Add convenience method `SemidiscretizationHyperbolicParabolicBR1`
sloede Jan 18, 2021
3125aa5
Add convenience method `SemidiscretizationHyperbolicParabolicBR1`
sloede Jan 18, 2021
7e27661
Change test reference values although they should not change; however…
sloede Jan 18, 2021
2d3b594
Merge branch 'master' into br1
sloede Jan 18, 2021
a343eca
Fix call syntax in semidiscretizations for `calc_error_norms`
sloede Jan 18, 2021
fab783c
Add Gauss pulse IC to heat equation/advdiff equation
sloede Jan 18, 2021
fa9b8f0
Remove unnecessary variables
sloede Jan 19, 2021
291884a
Fix bug in mortar code \o/
sloede Jan 19, 2021
0b5984c
Make AMR work
sloede Jan 19, 2021
3e545da
Allow changing plot properties for mesh plots
sloede Jan 19, 2021
8486e60
Make AMR test more fun...
sloede Jan 19, 2021
6af4cd4
Add test for heat equation AMR
sloede Jan 19, 2021
2d737b7
Update include order
sloede Jan 19, 2021
a0a8f21
Apply suggestions from code review
sloede Jan 19, 2021
4cc23f4
Fix docstring for heat equation
sloede Jan 19, 2021
7716534
Remove unused function
sloede Jan 19, 2021
379c059
Fix docstring for advection-diffusion equation
sloede Jan 19, 2021
7912939
Add comment as suggested by @andrewwinters5000
sloede Jan 19, 2021
50242e0
Fix bug with mesh_equations_solver_cache use
sloede Jan 19, 2021
665e99f
Make weak form the default for the BR1 scheme
sloede Jan 19, 2021
5769eae
Add very early support for boundary conditions for parabolic problems…
sloede Feb 2, 2021
8991ea4
Add source terms for parabolic system (convtest seems ok)
sloede Feb 2, 2021
8645e7d
Implement stepsize calculation for parabolic systems in the StepsizeC…
sloede Feb 2, 2021
6231077
Implement stepsize calculation for hyperbolic-parabolic systems
sloede Feb 2, 2021
a0e4694
Add "experimental code" warning to be able to change the implementati…
sloede Feb 8, 2021
8f9657a
Small comment fixes
sloede Feb 17, 2021
ecdf2ca
Merge branch 'main' into br1
sloede Apr 3, 2021
c10d796
Replace @SVector by SVector
sloede Apr 3, 2021
2d8736b
Deprecate `max_dt` for `max_dt_hyperbolic`
sloede Apr 3, 2021
5113a59
Make CFL number an arbitray type to support multiple CFL numbers
sloede Apr 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions examples/2d/elixir_advdiff_amr.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the linear advection equation

advectionvelocity = (1.8, 0.6)
nu = 2.4e-1
equations = LinearAdvectionDiffusionEquation2D(advectionvelocity, nu)

# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux
polydeg = 3
solver_hyperbolic = DGSEM(polydeg, flux_lax_friedrichs)

coordinates_min = (-4, -4)
coordinates_max = ( 4, 4)

# Create a uniformely refined mesh with periodic boundaries
mesh = TreeMesh(coordinates_min, coordinates_max,
initial_refinement_level=3,
n_cells_max=30_000) # set maximum capacity of tree data structure

# A semidiscretization collects data structures and functions for the spatial discretization
initial_condition = initial_condition_gauss
semi = SemidiscretizationHyperbolicParabolicBR1(mesh, equations, initial_condition, solver_hyperbolic)


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

# Create ODE problem with time span from 0.0 to 1.0
tspan = (0.0, 1.0)
ode = semidiscretize(semi, tspan);

# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
# and resets the timers
summary_callback = SummaryCallback()

# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_callback = AnalysisCallback(semi, interval=100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval=100,
solution_variables=cons2prim)

amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable=first),
base_level=3,
med_level=4, med_threshold=0.1,
max_level=5, max_threshold=0.5)
amr_callback = AMRCallback(semi, amr_controller,
interval=5,
adapt_initial_condition=true,
adapt_initial_condition_only_refine=true)

# The StepsizeCallback handles the re-calculcation of the maximum Δt after each time step
# stepsize_callback = StepsizeCallback(cfl=1.6)

# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, amr_callback)


###############################################################################
# run the simulation

# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false),
dt=1e-3, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep=false, callback=callbacks);

# Print the timer summary
summary_callback()
68 changes: 68 additions & 0 deletions examples/2d/elixir_advdiff_basic.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the linear advection equation

advectionvelocity = (0.2, 0.6)
nu = 1.2e-2
equations = LinearAdvectionDiffusionEquation2D(advectionvelocity, nu)

# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux
polydeg = 4
solver_hyperbolic = DGSEM(polydeg, flux_lax_friedrichs)

coordinates_min = (-1, -1) # minimum coordinates (min(x), min(y))
coordinates_max = ( 1, 1) # maximum coordinates (max(x), max(y))
refinement_patches = (
(type="box", coordinates_min=(0.0, -1.0), coordinates_max=(1.0, 1.0)),
)

# Create a uniformely refined mesh with periodic boundaries
mesh = TreeMesh(coordinates_min, coordinates_max,
initial_refinement_level=2,
refinement_patches=refinement_patches,
n_cells_max=30_000) # set maximum capacity of tree data structure

# A semidiscretization collects data structures and functions for the spatial discretization
initial_condition = initial_condition_convergence_test
semi = SemidiscretizationHyperbolicParabolicBR1(mesh, equations, initial_condition, solver_hyperbolic)


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

# Create ODE problem with time span from 0.0 to 1.0
tspan = (0.0, 1.0)
ode = semidiscretize(semi, tspan);

# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
# and resets the timers
summary_callback = SummaryCallback()

# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_callback = AnalysisCallback(semi, interval=100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval=100,
solution_variables=cons2prim)

# The StepsizeCallback handles the re-calculcation of the maximum Δt after each time step
# stepsize_callback = StepsizeCallback(cfl=1.6)

# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
# callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, stepsize_callback)
callbacks = CallbackSet(summary_callback, analysis_callback, save_solution)


###############################################################################
# run the simulation

# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false),
dt=1e-3, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep=false, callback=callbacks);

# Print the timer summary
summary_callback()
71 changes: 71 additions & 0 deletions examples/2d/elixir_heat_amr.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the linear advection equation

nu = 4.8e-1
equations = HeatEquation2D(nu)

# Create DG solver with polynomial degree = 3 and the central flux as surface flux
solver = DGSEM(3, flux_central)

coordinates_min = (-4, -4) # minimum coordinates (min(x), min(y))
coordinates_max = ( 4, 4) # maximum coordinates (max(x), max(y))

# Create a uniformely refined mesh with periodic boundaries
mesh = TreeMesh(coordinates_min, coordinates_max,
initial_refinement_level=3,
n_cells_max=30_000) # set maximum capacity of tree data structure

# A semidiscretization collects data structures and functions for the spatial discretization
initial_condition = initial_condition_gauss
semi = SemidiscretizationParabolicAuxVars(mesh, equations, initial_condition, solver)


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

# Create ODE problem with time span from 0.0 to 1.0
tspan = (0.0, 1.0)
ode = semidiscretize(semi, tspan);

# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
# and resets the timers
summary_callback = SummaryCallback()

# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_callback = AnalysisCallback(semi, interval=100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval=100,
solution_variables=cons2prim)

amr_controller = ControllerThreeLevel(semi, IndicatorMax(semi, variable=first),
base_level=3,
med_level=4, med_threshold=0.05,
max_level=5, max_threshold=0.3)
amr_callback = AMRCallback(semi, amr_controller,
interval=5,
adapt_initial_condition=true,
adapt_initial_condition_only_refine=true)

# The StepsizeCallback handles the re-calculcation of the maximum Δt after each time step
# stepsize_callback = StepsizeCallback(cfl=1.6)

# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
# callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, stepsize_callback)
callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, amr_callback)


###############################################################################
# run the simulation

# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false),
dt=1e-3, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep=false, callback=callbacks, maxiters=1e5);

# Print the timer summary
summary_callback()
62 changes: 62 additions & 0 deletions examples/2d/elixir_heat_basic.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the linear advection equation

nu = 1.2e-2
equations = HeatEquation2D(nu)

# Create DG solver with polynomial degree = 3 and the central flux as surface flux
solver = DGSEM(3, flux_central)

coordinates_min = (-1, -1) # minimum coordinates (min(x), min(y))
coordinates_max = ( 1, 1) # maximum coordinates (max(x), max(y))

# Create a uniformely refined mesh with periodic boundaries
mesh = TreeMesh(coordinates_min, coordinates_max,
initial_refinement_level=2,
n_cells_max=30_000) # set maximum capacity of tree data structure

# A semidiscretization collects data structures and functions for the spatial discretization
initial_condition = initial_condition_convergence_test
semi = SemidiscretizationParabolicAuxVars(mesh, equations, initial_condition, solver)


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

# Create ODE problem with time span from 0.0 to 1.0
tspan = (0.0, 1.0)
ode = semidiscretize(semi, tspan);

# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup
# and resets the timers
summary_callback = SummaryCallback()

# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results
analysis_callback = AnalysisCallback(semi, interval=100)

# The SaveSolutionCallback allows to save the solution to a file in regular intervals
save_solution = SaveSolutionCallback(interval=100,
solution_variables=cons2prim)

# The StepsizeCallback handles the re-calculcation of the maximum Δt after each time step
# stepsize_callback = StepsizeCallback(cfl=1.6)

# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver
# callbacks = CallbackSet(summary_callback, analysis_callback, save_solution, stepsize_callback)
callbacks = CallbackSet(summary_callback, analysis_callback, save_solution)


###############################################################################
# run the simulation

# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks
sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false),
dt=1e-3, # solve needs some value here but it will be overwritten by the stepsize_callback
save_everystep=false, callback=callbacks, maxiters=1e5);

# Print the timer summary
summary_callback()
10 changes: 8 additions & 2 deletions src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ include("semidiscretization/semidiscretization_hyperbolic.jl")
include("callbacks_step/callbacks_step.jl")
include("callbacks_stage/callbacks_stage.jl")
include("semidiscretization/semidiscretization_euler_gravity.jl")
include("semidiscretization/semidiscretization_parabolic_auxvars.jl")
include("semidiscretization/semidiscretization_hyperbolic_parabolic.jl")
include("time_integration/time_integration.jl")

# `trixi_include` and special elixirs such as `convergence_test`
Expand All @@ -74,7 +76,9 @@ export CompressibleEulerEquations1D, CompressibleEulerEquations2D, CompressibleE
IdealGlmMhdEquations1D, IdealGlmMhdEquations2D, IdealGlmMhdEquations3D,
HyperbolicDiffusionEquations1D, HyperbolicDiffusionEquations2D, HyperbolicDiffusionEquations3D,
LinearScalarAdvectionEquation1D, LinearScalarAdvectionEquation2D, LinearScalarAdvectionEquation3D,
LatticeBoltzmannEquations2D, LatticeBoltzmannEquations3D
LatticeBoltzmannEquations2D, LatticeBoltzmannEquations3D,
HeatEquation2D,
LinearAdvectionDiffusionEquation2D

export flux_central, flux_lax_friedrichs, flux_hll, flux_hllc, flux_upwind,
flux_chandrashekar, flux_chandrashekar_stable, flux_ranocha, flux_derigs_etal, flux_kennedy_gruber, flux_shima_etal
Expand Down Expand Up @@ -125,7 +129,9 @@ export DG,
export nelements, nnodes, nvariables,
eachelement, eachnode, eachvariable

export SemidiscretizationHyperbolic, semidiscretize, compute_coefficients, integrate
export SemidiscretizationHyperbolic, SemidiscretizationParabolicAuxVars,
SemidiscretizationHyperbolicParabolic, SemidiscretizationHyperbolicParabolicBR1,
semidiscretize, compute_coefficients, integrate

export SemidiscretizationEulerGravity, ParametersEulerGravity,
timestep_gravity_erk52_3Sstar!, timestep_gravity_carpenter_kennedy_erk54_2N!
Expand Down
24 changes: 23 additions & 1 deletion src/equations/equations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ default_analysis_integrals(::AbstractEquations) = (entropy_timederivative,)

"""
flux_central(u_ll, u_rr, orientation, equations::AbstractEquations)
flux_central(u_ll, u_rr, gradients_ll, gradients_rr, orientation, equations::AbstractEquations)

The classical central numerical flux `f((u_ll) + f(u_rr)) / 2`. When this flux is
used as volume flux, the discretization is equivalent to the classical weak form
DG method (except floating point errors).
DG method (except floating point errors). The second version call the parabolic flux, which requires
the gradients as additional arguments.
"""
@inline function flux_central(u_ll, u_rr, orientation, equations::AbstractEquations)
# Calculate regular 1D fluxes
Expand All @@ -68,6 +70,14 @@ DG method (except floating point errors).
# Average regular fluxes
return 0.5 * (f_ll + f_rr)
end
@inline function flux_central(u_ll, u_rr, gradients_ll, gradients_rr, orientation, equations::AbstractEquations)
# Calculate regular 1D fluxes
f_ll = calcflux(u_ll, gradients_ll, orientation, equations)
f_rr = calcflux(u_rr, gradients_rr, orientation, equations)

# Average regular fluxes
return 0.5 * (f_ll + f_rr)
end


@inline cons2cons(u, ::AbstractEquations) = u
Expand Down Expand Up @@ -114,3 +124,15 @@ include("hyperbolic_diffusion_3d.jl")
abstract type AbstractLatticeBoltzmannEquations{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end
include("lattice_boltzmann_2d.jl")
include("lattice_boltzmann_3d.jl")

# Gradient equations
abstract type AbstractGradientEquations{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end
include("gradient_equations_2d.jl")

# Heat equation
abstract type AbstractHeatEquation{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end
include("heat_equation_2d.jl")

# Linear scalar advection-diffusion equation
abstract type AbstractLinearAdvectionDiffusionEquation{NDIMS, NVARS} <: AbstractEquations{NDIMS, NVARS} end
include("linear_advection_diffusion_2d.jl")
46 changes: 46 additions & 0 deletions src/equations/gradient_equations_2d.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

@doc raw"""
GradientEquations2D

The gradient equations
```math
q^d - \partial_d u = 0
```
in direction `d` in two space dimensions as required for, e.g., the Bassi & Rebay 1 (BR1) or the
local discontinuous Galerkin (LDG) schemes.
"""
struct GradientEquations2D{RealT<:Real, NVARS} <: AbstractGradientEquations{2, NVARS}
orientation::Int
end

GradientEquations2D(::Type{RealT}, nvars, orientation) where RealT = GradientEquations2D{RealT, nvars}(orientation)
GradientEquations2D(nvars, orientation) = GradientEquations2D(Float64, nvars, orientation)


get_name(::GradientEquations2D) = "GradientEquations2D"
varnames(::typeof(cons2cons), equations::GradientEquations2D) = SVector(ntuple(v -> "gradient_"*string(v), nvariables(equations)))
varnames(::typeof(cons2prim), equations::GradientEquations2D) = varnames(cons2cons, equations)

# Set initial conditions at physical location `x` for time `t`
"""
initial_condition_constant(x, t, equations::GradientEquations2D)

A constant initial condition to test free-stream preservation.
"""
function initial_condition_constant(x, t, equations::GradientEquations2D)
return SVector(ntuple(v -> zero(eltype(x)), nvariables(equations)))
end


# Pre-defined source terms should be implemented as
# function source_terms_WHATEVER(u, x, t, equations::GradientEquations2D)


# Calculate 1D flux in for a single point
@inline function calcflux(u, orientation, equations::GradientEquations2D)
sloede marked this conversation as resolved.
Show resolved Hide resolved
if orientation == equations.orientation
return -u
else
return SVector(ntuple(v -> zero(eltype(u)), nvariables(equations)))
end
end
Loading