Path: blob/main/examples/tree_3d_dgsem/elixir_advection_diffusion_nonperiodic.jl
2055 views
using OrdinaryDiffEqLowStorageRK1using Trixi23###############################################################################4# semidiscretization of the linear advection-diffusion equation56diffusivity() = 5.0e-27advection_velocity = (1.0, 0.0, 0.0)8equations = LinearScalarAdvectionEquation3D(advection_velocity)9equations_parabolic = LaplaceDiffusion3D(diffusivity(), equations)1011# Create DG solver with polynomial degree = 3 and (local) Lax-Friedrichs/Rusanov flux as surface flux12solver = DGSEM(polydeg = 3, surface_flux = flux_lax_friedrichs)1314coordinates_min = (-1.0, -0.5, -0.5) # minimum coordinates (min(x), min(y), min(z))15coordinates_max = (0.0, 0.5, 0.5) # maximum coordinates (max(x), max(y), max(z))1617# Create a uniformly refined mesh with periodic boundaries18mesh = TreeMesh(coordinates_min, coordinates_max,19initial_refinement_level = 3,20periodicity = false,21n_cells_max = 30_000) # set maximum capacity of tree data structure2223# Example setup taken from24# - Truman Ellis, Jesse Chan, and Leszek Demkowicz (2016).25# Robust DPG methods for transient convection-diffusion.26# In: Building bridges: connections and challenges in modern approaches27# to numerical partial differential equations.28# [DOI](https://doi.org/10.1007/978-3-319-41640-3_6).29function initial_condition_eriksson_johnson(x, t, equations)30l = 431epsilon = diffusivity() # TODO: this requires epsilon < .6 due to sqrt32lambda_1 = (-1 + sqrt(1 - 4 * epsilon * l)) / (-2 * epsilon)33lambda_2 = (-1 - sqrt(1 - 4 * epsilon * l)) / (-2 * epsilon)34r1 = (1 + sqrt(1 + 4 * pi^2 * epsilon^2)) / (2 * epsilon)35s1 = (1 - sqrt(1 + 4 * pi^2 * epsilon^2)) / (2 * epsilon)36u = exp(-l * t) * (exp(lambda_1 * x[1]) - exp(lambda_2 * x[1])) +37cos(pi * x[2]) * (exp(s1 * x[1]) - exp(r1 * x[1])) / (exp(-s1) - exp(-r1))38return SVector{1}(u)39end40initial_condition = initial_condition_eriksson_johnson4142boundary_conditions = (; x_neg = BoundaryConditionDirichlet(initial_condition),43y_neg = BoundaryConditionDirichlet(initial_condition),44z_neg = boundary_condition_do_nothing,45y_pos = BoundaryConditionDirichlet(initial_condition),46x_pos = boundary_condition_do_nothing,47z_pos = boundary_condition_do_nothing)4849boundary_conditions_parabolic = BoundaryConditionDirichlet(initial_condition)5051# A semidiscretization collects data structures and functions for the spatial discretization52semi = SemidiscretizationHyperbolicParabolic(mesh,53(equations, equations_parabolic),54initial_condition, solver;55solver_parabolic = ViscousFormulationBassiRebay1(),56boundary_conditions = (boundary_conditions,57boundary_conditions_parabolic))5859###############################################################################60# ODE solvers, callbacks etc.6162# Create ODE problem with time span `tspan`63tspan = (0.0, 0.5)64ode = semidiscretize(semi, tspan)6566# At the beginning of the main loop, the SummaryCallback prints a summary of the simulation setup67# and resets the timers68summary_callback = SummaryCallback()6970# The AnalysisCallback allows to analyse the solution in regular intervals and prints the results71analysis_interval = 10072analysis_callback = AnalysisCallback(semi, interval = analysis_interval)7374# The AliveCallback prints short status information in regular intervals75alive_callback = AliveCallback(analysis_interval = analysis_interval)7677# Create a CallbackSet to collect all callbacks such that they can be passed to the ODE solver78callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback)7980###############################################################################81# run the simulation8283# OrdinaryDiffEq's `solve` method evolves the solution in time and executes the passed callbacks84time_int_tol = 1.0e-1185sol = solve(ode, RDPK3SpFSAL49(); abstol = time_int_tol, reltol = time_int_tol,86ode_default_options()..., callback = callbacks)878889