Path: blob/main/docs/literate/src/files/DGMulti_1.jl
5591 views
#src # DG schemes via `DGMulti` solver12# [`DGMulti`](@ref) is a DG solver that allows meshes with simplex elements. The basic idea and3# implementation of this solver is explained in section ["Meshes"](@ref DGMulti).4# Here, we want to give some examples and a quick overview about the options with `DGMulti`.56# We start with a simple example we already used in the [tutorial about flux differencing](@ref fluxDiffExample).7# There, we implemented a simulation with [`initial_condition_weak_blast_wave`](@ref) for the8# 2D compressible Euler equations [`CompressibleEulerEquations2D`](@ref) and used the DG formulation9# with flux differencing using volume flux [`flux_ranocha`](@ref) and surface flux [`flux_lax_friedrichs`](@ref).1011# Here, we want to implement the equivalent example, only now using the `DGMulti` solver12# instead of [`DGSEM`](@ref).1314using OrdinaryDiffEqLowStorageRK15using Trixi1617equations = CompressibleEulerEquations2D(1.4)1819initial_condition = initial_condition_weak_blast_wave2021# To use the Gauss-Lobatto nodes again, we choose `approximation_type=SBP()` in the solver.22# Since we want to start with a Cartesian domain discretized with squares, we use the element23# type `Quad()`.24dg = DGMulti(polydeg = 3,25element_type = Quad(),26approximation_type = SBP(),27surface_flux = flux_lax_friedrichs,28volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))2930cells_per_dimension = (32, 32)31mesh = DGMultiMesh(dg,32cells_per_dimension, # initial_refinement_level = 533coordinates_min = (-2.0, -2.0),34coordinates_max = (2.0, 2.0),35periodicity = true)3637semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,38boundary_conditions = boundary_condition_periodic)39tspan = (0.0, 0.4)40ode = semidiscretize(semi, tspan)4142alive_callback = AliveCallback(alive_interval = 10)43analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg))44callbacks = CallbackSet(analysis_callback, alive_callback);4546# Run the simulation with the same time integration algorithm as before.47sol = solve(ode, RDPK3SpFSAL49(), abstol = 1.0e-6, reltol = 1.0e-6;48callback = callbacks, ode_default_options()...);49#-50using Plots51pd = PlotData2D(sol)52plot(pd)53#-54plot(pd["rho"])55plot!(getmesh(pd))5657# This simulation is not as fast as the equivalent with `TreeMesh` since no special optimizations for58# quads (for instance tensor product structure) have been implemented. Figure 4 in ["Efficient implementation of modern entropy stable59# and kinetic energy preserving discontinuous Galerkin methods for conservation laws"](https://arxiv.org/abs/2112.10517)60# (2021) provides a nice runtime comparison between the different mesh types. On the other hand,61# the functions are more general and thus we have more option we can choose from.6263# ## Simulation with Gauss nodes64# For instance, we can change the approximation type of our simulation.65using OrdinaryDiffEqLowStorageRK66using Trixi67equations = CompressibleEulerEquations2D(1.4)68initial_condition = initial_condition_weak_blast_wave6970# We now use Gauss nodes instead of Gauss-Lobatto nodes which can be done for the element types71# `Quad()` and `Hex()`. Therefore, we set `approximation_type=GaussSBP()`. Alternatively, we72# can use a modal approach using the approximation type `Polynomial()`.73dg = DGMulti(polydeg = 3,74element_type = Quad(),75approximation_type = GaussSBP(),76surface_flux = flux_lax_friedrichs,77volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))7879cells_per_dimension = (32, 32)80mesh = DGMultiMesh(dg,81cells_per_dimension, # initial_refinement_level = 582coordinates_min = (-2.0, -2.0),83coordinates_max = (2.0, 2.0),84periodicity = true)8586semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,87boundary_conditions = boundary_condition_periodic)88tspan = (0.0, 0.4)89ode = semidiscretize(semi, tspan)9091alive_callback = AliveCallback(alive_interval = 10)92analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg))93callbacks = CallbackSet(analysis_callback, alive_callback);9495sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6,96ode_default_options()..., callback = callbacks);97#-98using Plots99pd = PlotData2D(sol)100plot(pd)101102# ## Simulation with triangular elements103# Also, we can set another element type. We want to use triangles now.104using OrdinaryDiffEqLowStorageRK105using Trixi106equations = CompressibleEulerEquations2D(1.4)107initial_condition = initial_condition_weak_blast_wave108109# Since there is no direct equivalent to Gauss-Lobatto nodes on triangles, the approximation type110# `SBP()` now uses Gauss-Lobatto nodes on faces and special nodes in the interior of the triangular.111# More details can be found in the documentation of112# [StartUpDG.jl](https://jlchan.github.io/StartUpDG.jl/dev/RefElemData/#RefElemData-based-on-SBP-finite-differences).113dg = DGMulti(polydeg = 3,114element_type = Tri(),115approximation_type = SBP(),116surface_flux = flux_lax_friedrichs,117volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))118119cells_per_dimension = (32, 32)120mesh = DGMultiMesh(dg,121cells_per_dimension, # initial_refinement_level = 5122coordinates_min = (-2.0, -2.0),123coordinates_max = (2.0, 2.0),124periodicity = true)125126semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,127boundary_conditions = boundary_condition_periodic)128tspan = (0.0, 0.4)129ode = semidiscretize(semi, tspan)130131alive_callback = AliveCallback(alive_interval = 10)132analysis_callback = AnalysisCallback(semi, interval = 100, uEltype = real(dg))133callbacks = CallbackSet(analysis_callback, alive_callback);134135sol = solve(ode, RDPK3SpFSAL49(); abstol = 1.0e-6, reltol = 1.0e-6,136ode_default_options()..., callback = callbacks);137#-138using Plots139pd = PlotData2D(sol)140plot(pd)141#-142plot(pd["rho"])143plot!(getmesh(pd))144145# ## Triangular meshes on non-Cartesian domains146# To use triangular meshes on a non-Cartesian domain, Trixi.jl uses the package [StartUpDG.jl](https://github.com/jlchan/StartUpDG.jl).147# The following example is based on [`elixir_euler_triangulate_pkg_mesh.jl`](https://github.com/trixi-framework/Trixi.jl/blob/main/examples/dgmulti_2d/elixir_euler_triangulate_pkg_mesh.jl)148# and uses a pre-defined mesh from StartUpDG.jl.149using OrdinaryDiffEqLowStorageRK150using Trixi151152# We want to simulate the smooth initial condition [`initial_condition_convergence_test`](@ref)153# with source terms [`source_terms_convergence_test`](@ref) for the 2D compressible Euler equations.154equations = CompressibleEulerEquations2D(1.4)155initial_condition = initial_condition_convergence_test156source_terms = source_terms_convergence_test157158# We create the solver `DGMulti` with triangular elements (`Tri()`) as before.159dg = DGMulti(polydeg = 3, element_type = Tri(),160approximation_type = Polynomial(),161surface_flux = flux_lax_friedrichs,162volume_integral = VolumeIntegralFluxDifferencing(flux_ranocha))163164# StartUpDG.jl provides for instance a pre-defined Triangulate geometry for a rectangular domain with165# hole `RectangularDomainWithHole`. Other pre-defined Triangulate geometries are e.g., `SquareDomain`,166# `Scramjet`, and `CircularDomain`.167meshIO = StartUpDG.triangulate_domain(StartUpDG.RectangularDomainWithHole());168169# The pre-defined Triangulate geometry in StartUpDG has integer boundary tags. With [`DGMultiMesh`](@ref)170# we assign boundary faces based on these integer boundary tags and create a mesh compatible with Trixi.jl.171mesh = DGMultiMesh(dg, meshIO, Dict(:outer_boundary => 1, :inner_boundary => 2))172#-173boundary_condition_convergence_test = BoundaryConditionDirichlet(initial_condition)174boundary_conditions = (; outer_boundary = boundary_condition_convergence_test,175inner_boundary = boundary_condition_convergence_test)176177semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, dg,178source_terms = source_terms,179boundary_conditions = boundary_conditions)180181tspan = (0.0, 0.2)182ode = semidiscretize(semi, tspan)183184alive_callback = AliveCallback(alive_interval = 20)185analysis_callback = AnalysisCallback(semi, interval = 200, uEltype = real(dg))186callbacks = CallbackSet(alive_callback, analysis_callback);187188sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);189dt = 0.5 * estimate_dt(mesh, dg),190ode_default_options()...,191callback = callbacks);192#-193using Plots194pd = PlotData2D(sol)195plot(pd["rho"])196plot!(getmesh(pd))197198# For more information, please have a look in the [StartUpDG.jl documentation](https://jlchan.github.io/StartUpDG.jl/stable/).199200# ## Package versions201202# These results were obtained using the following versions.203204using InteractiveUtils205versioninfo()206207using Pkg208Pkg.status(["Trixi", "StartUpDG", "OrdinaryDiffEqLowStorageRK", "Plots"],209mode = PKGMODE_MANIFEST)210211212