Path: blob/main/docs/literate/src/files/parabolic_source_terms.jl
5591 views
#src # Parabolic source terms (advection-diffusion).12# Source terms which depend on the gradient of the solution are available by specifying3# `source_terms_parabolic`. This demo illustrates parabolic source terms for the4# advection-diffusion equation.56using OrdinaryDiffEqLowStorageRK7using Trixi89const a = 0.110const nu = 0.111const beta = 0.31213equations = LinearScalarAdvectionEquation1D(a)14equations_parabolic = LaplaceDiffusion1D(nu, equations)1516solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)1718# ## Gradient-dependent source terms1920# For a mixed hyperbolic-parabolic system, one can specify source terms which depend21# on the gradient of the solution. Here, we solve a steady advection-diffusion22# equation with both solution and gradient-dependent source terms. The exact solution23# `u(x) = sin(x)` is given by `initial_condition`.2425initial_condition = function (x, t, equations::LinearScalarAdvectionEquation1D)26return SVector(sin(x[1]))27end2829# For standard hyperbolic source terms, we pass in the solution, the spatial coordinate,30# the current time, and the hyperbolic equations.3132source_terms = function (u, x, t, equations::LinearScalarAdvectionEquation1D)33f = a * cos(x[1]) + nu * sin(x[1]) - beta * (cos(x[1])^2)34return SVector(f)35end3637# For gradient-dependent source terms, we also pass the solution gradients and the38# parabolic equations instead of the hyperbolic equations. Note that all parabolic39# equations have `equations_hyperbolic` as a solution field.40#41# For advection-diffusion, the gradients are gradients of the solution `u`. However,42# for systems such as `CompressibleNavierStokesDiffusion1D`, different gradient43# variables can be selected through the `gradient_variables` keyword option. The44# choice of `gradient_variables` will also determine the variables whose gradients45# are passed into `source_terms_parabolic`.46#47# The `gradients` passed to the `source_terms_parabolic` are a tuple of vectors;48# `gradients[1]` are the gradients in the first coordinate direction,49# `gradients[1][1]` is the gradient of the first (and only in this case) variable50# in the first coordinate direction.5152source_terms_parabolic = function (u, gradients, x, t, equations::LaplaceDiffusion1D)53dudx = gradients[1][1]54return SVector(beta * dudx^2)55end5657# The parabolic source terms can then be supplied to `SemidiscretizationHyperbolicParabolic`58# by setting the optional keyword argument `source_terms_parabolic`.59# The rest of the code is identical to standard hyperbolic-parabolic cases. We create a60# system of ODEs through `semidiscretize`, define callbacks, and then passing the system61# to OrdinaryDiffEq.jl.62#63# Note that for this problem, since viscosity `nu` is relatively large, we utilize64# `ParabolicFormulationLocalDG` instead of the default `ParabolicFormulationBassiRebay1`65# parabolic solver, since the Bassi-Rebay 1 formulation is not accurate when the66# diffusivity is large relative to the mesh size.6768mesh = TreeMesh(-Float64(pi), Float64(pi);69initial_refinement_level = 4,70n_cells_max = 30_000,71periodicity = true)7273boundary_conditions = boundary_condition_periodic74boundary_conditions_parabolic = boundary_condition_periodic7576semi = SemidiscretizationHyperbolicParabolic(mesh, (equations, equations_parabolic),77initial_condition, solver;78solver_parabolic = ParabolicFormulationLocalDG(),79source_terms = source_terms,80source_terms_parabolic = source_terms_parabolic,81boundary_conditions = (boundary_conditions,82boundary_conditions_parabolic))8384tspan = (0.0, 1.0)85ode = semidiscretize(semi, tspan)8687# Finally, we note that while we solve the ODE system using explicit time-stepping, the maximum88# stable time-step is $O(h^2)$ due to the dominant parabolic term. We enforce this more stringent89# parabolic CFL condition using a diffusion-aware `StepsizeCallback`.9091cfl_hyperbolic = 0.592cfl_parabolic = 0.0593stepsize_callback = StepsizeCallback(cfl = cfl_hyperbolic,94cfl_parabolic = cfl_parabolic)95callbacks = CallbackSet(SummaryCallback(), stepsize_callback)96sol = solve(ode, RDPK3SpFSAL35(); adaptive = false, dt = stepsize_callback(ode),97ode_default_options()..., callback = callbacks)9899100