Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
trixi-framework
GitHub Repository: trixi-framework/Trixi.jl
Path: blob/main/docs/literate/src/files/parabolic_source_terms.jl
5591 views
1
#src # Parabolic source terms (advection-diffusion).
2
3
# Source terms which depend on the gradient of the solution are available by specifying
4
# `source_terms_parabolic`. This demo illustrates parabolic source terms for the
5
# advection-diffusion equation.
6
7
using OrdinaryDiffEqLowStorageRK
8
using Trixi
9
10
const a = 0.1
11
const nu = 0.1
12
const beta = 0.3
13
14
equations = LinearScalarAdvectionEquation1D(a)
15
equations_parabolic = LaplaceDiffusion1D(nu, equations)
16
17
solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)
18
19
# ## Gradient-dependent source terms
20
21
# For a mixed hyperbolic-parabolic system, one can specify source terms which depend
22
# on the gradient of the solution. Here, we solve a steady advection-diffusion
23
# equation with both solution and gradient-dependent source terms. The exact solution
24
# `u(x) = sin(x)` is given by `initial_condition`.
25
26
initial_condition = function (x, t, equations::LinearScalarAdvectionEquation1D)
27
return SVector(sin(x[1]))
28
end
29
30
# For standard hyperbolic source terms, we pass in the solution, the spatial coordinate,
31
# the current time, and the hyperbolic equations.
32
33
source_terms = function (u, x, t, equations::LinearScalarAdvectionEquation1D)
34
f = a * cos(x[1]) + nu * sin(x[1]) - beta * (cos(x[1])^2)
35
return SVector(f)
36
end
37
38
# For gradient-dependent source terms, we also pass the solution gradients and the
39
# parabolic equations instead of the hyperbolic equations. Note that all parabolic
40
# equations have `equations_hyperbolic` as a solution field.
41
#
42
# For advection-diffusion, the gradients are gradients of the solution `u`. However,
43
# for systems such as `CompressibleNavierStokesDiffusion1D`, different gradient
44
# variables can be selected through the `gradient_variables` keyword option. The
45
# choice of `gradient_variables` will also determine the variables whose gradients
46
# are passed into `source_terms_parabolic`.
47
#
48
# The `gradients` passed to the `source_terms_parabolic` are a tuple of vectors;
49
# `gradients[1]` are the gradients in the first coordinate direction,
50
# `gradients[1][1]` is the gradient of the first (and only in this case) variable
51
# in the first coordinate direction.
52
53
source_terms_parabolic = function (u, gradients, x, t, equations::LaplaceDiffusion1D)
54
dudx = gradients[1][1]
55
return SVector(beta * dudx^2)
56
end
57
58
# The parabolic source terms can then be supplied to `SemidiscretizationHyperbolicParabolic`
59
# by setting the optional keyword argument `source_terms_parabolic`.
60
# The rest of the code is identical to standard hyperbolic-parabolic cases. We create a
61
# system of ODEs through `semidiscretize`, define callbacks, and then passing the system
62
# to OrdinaryDiffEq.jl.
63
#
64
# Note that for this problem, since viscosity `nu` is relatively large, we utilize
65
# `ParabolicFormulationLocalDG` instead of the default `ParabolicFormulationBassiRebay1`
66
# parabolic solver, since the Bassi-Rebay 1 formulation is not accurate when the
67
# diffusivity is large relative to the mesh size.
68
69
mesh = TreeMesh(-Float64(pi), Float64(pi);
70
initial_refinement_level = 4,
71
n_cells_max = 30_000,
72
periodicity = true)
73
74
boundary_conditions = boundary_condition_periodic
75
boundary_conditions_parabolic = boundary_condition_periodic
76
77
semi = SemidiscretizationHyperbolicParabolic(mesh, (equations, equations_parabolic),
78
initial_condition, solver;
79
solver_parabolic = ParabolicFormulationLocalDG(),
80
source_terms = source_terms,
81
source_terms_parabolic = source_terms_parabolic,
82
boundary_conditions = (boundary_conditions,
83
boundary_conditions_parabolic))
84
85
tspan = (0.0, 1.0)
86
ode = semidiscretize(semi, tspan)
87
88
# Finally, we note that while we solve the ODE system using explicit time-stepping, the maximum
89
# stable time-step is $O(h^2)$ due to the dominant parabolic term. We enforce this more stringent
90
# parabolic CFL condition using a diffusion-aware `StepsizeCallback`.
91
92
cfl_hyperbolic = 0.5
93
cfl_parabolic = 0.05
94
stepsize_callback = StepsizeCallback(cfl = cfl_hyperbolic,
95
cfl_parabolic = cfl_parabolic)
96
callbacks = CallbackSet(SummaryCallback(), stepsize_callback)
97
sol = solve(ode, RDPK3SpFSAL35(); adaptive = false, dt = stepsize_callback(ode),
98
ode_default_options()..., callback = callbacks)
99
100