Path: blob/main/examples/t8code_2d_dgsem/elixir_mhd_rotor.jl
2055 views
using OrdinaryDiffEqLowStorageRK1using Trixi23###############################################################################4# semidiscretization of the compressible ideal GLM-MHD equations5equations = IdealGlmMhdEquations2D(1.4)67"""8initial_condition_rotor(x, t, equations::IdealGlmMhdEquations2D)910The classical MHD rotor test case. Here, the setup is taken from11- Dominik Derigs, Gregor J. Gassner, Stefanie Walch & Andrew R. Winters (2018)12Entropy Stable Finite Volume Approximations for Ideal Magnetohydrodynamics13[doi: 10.1365/s13291-018-0178-9](https://doi.org/10.1365/s13291-018-0178-9)14"""15function initial_condition_rotor(x, t, equations::IdealGlmMhdEquations2D)16# setup taken from Derigs et al. DMV article (2018)17# domain must be [0, 1] x [0, 1], γ = 1.418dx = x[1] - 0.519dy = x[2] - 0.520r = sqrt(dx^2 + dy^2)21f = (0.115 - r) / 0.01522if r <= 0.123rho = 10.024v1 = -20.0 * dy25v2 = 20.0 * dx26elseif r >= 0.11527rho = 1.028v1 = 0.029v2 = 0.030else31rho = 1.0 + 9.0 * f32v1 = -20.0 * f * dy33v2 = 20.0 * f * dx34end35v3 = 0.036p = 1.037B1 = 5.0 / sqrt(4.0 * pi)38B2 = 0.039B3 = 0.040psi = 0.041return prim2cons(SVector(rho, v1, v2, v3, p, B1, B2, B3, psi), equations)42end43initial_condition = initial_condition_rotor4445# Up to version 0.13.0, `max_abs_speed_naive` was used as the default wave speed estimate of46# `const flux_lax_friedrichs = FluxLaxFriedrichs(), i.e., `FluxLaxFriedrichs(max_abs_speed = max_abs_speed_naive)`.47# In the `StepsizeCallback`, though, the less diffusive `max_abs_speeds` is employed which is consistent with `max_abs_speed`.48# Thus, we exchanged in PR#2458 the default wave speed used in the LLF flux to `max_abs_speed`.49# To ensure that every example still runs we specify explicitly `FluxLaxFriedrichs(max_abs_speed_naive)`.50# We remark, however, that the now default `max_abs_speed` is in general recommended due to compliance with the51# `StepsizeCallback` (CFL-Condition) and less diffusion.52surface_flux = (FluxLaxFriedrichs(max_abs_speed_naive), flux_nonconservative_powell)53volume_flux = (flux_hindenlang_gassner, flux_nonconservative_powell)54polydeg = 455basis = LobattoLegendreBasis(polydeg)56indicator_sc = IndicatorHennemannGassner(equations, basis,57alpha_max = 0.5,58alpha_min = 0.001,59alpha_smooth = true,60variable = density_pressure)61volume_integral = VolumeIntegralShockCapturingHG(indicator_sc;62volume_flux_dg = volume_flux,63volume_flux_fv = surface_flux)64solver = DGSEM(basis, surface_flux, volume_integral)6566# Affine type mapping to take the [-1,1]^2 domain from the mesh file67# and put it onto the rotor domain [0,1]^2 and then warp it with a mapping68# as described in https://arxiv.org/abs/2012.1204069function mapping_twist(xi, eta)70y = 0.5 * (eta + 1.0) +710.05 * cos(1.5 * pi * (2.0 * xi - 1.0)) * cos(0.5 * pi * (2.0 * eta - 1.0))72x = 0.5 * (xi + 1.0) + 0.05 * cos(0.5 * pi * (2.0 * xi - 1.0)) * cos(2.0 * pi * y)73return SVector(x, y)74end7576mesh_file = Trixi.download("https://gist.githubusercontent.com/efaulhaber/63ff2ea224409e55ee8423b3a33e316a/raw/7db58af7446d1479753ae718930741c47a3b79b7/square_unstructured_2.inp",77joinpath(@__DIR__, "square_unstructured_2.inp"))7879mesh = T8codeMesh(mesh_file, 2; polydeg = 4,80mapping = mapping_twist,81initial_refinement_level = 1)8283boundary_condition = BoundaryConditionDirichlet(initial_condition)84boundary_conditions = Dict(:all => boundary_condition)8586semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,87boundary_conditions = boundary_conditions)8889###############################################################################90# ODE solvers, callbacks etc.9192tspan = (0.0, 0.15)93ode = semidiscretize(semi, tspan)9495summary_callback = SummaryCallback()9697analysis_interval = 10098analysis_callback = AnalysisCallback(semi, interval = analysis_interval)99100alive_callback = AliveCallback(analysis_interval = analysis_interval)101102save_solution = SaveSolutionCallback(interval = 100,103save_initial_solution = true,104save_final_solution = true,105solution_variables = cons2prim)106107amr_indicator = IndicatorLöhner(semi,108variable = density_pressure)109110amr_controller = ControllerThreeLevel(semi, amr_indicator,111base_level = 1,112med_level = 3, med_threshold = 0.05,113max_level = 5, max_threshold = 0.1)114amr_callback = AMRCallback(semi, amr_controller,115interval = 5,116adapt_initial_condition = true,117adapt_initial_condition_only_refine = true,118dynamic_load_balancing = false)119# We disable `dynamic_load_balancing` for now, since t8code does not support120# partitioning for coarsening yet. That is, a complete family of elements always121# stays on rank and is not split up due to partitioning. Without this feature122# dynamic AMR simulations are not perfectly deterministic regarding to123# convergent tests. Once this feature is available in t8code load balancing is124# enabled again.125126cfl = 0.5127stepsize_callback = StepsizeCallback(cfl = cfl)128129glm_speed_callback = GlmSpeedCallback(glm_scale = 0.5, cfl = cfl)130131callbacks = CallbackSet(summary_callback,132analysis_callback,133alive_callback,134save_solution,135amr_callback,136stepsize_callback,137glm_speed_callback)138139###############################################################################140# run the simulation141142sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);143dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback144ode_default_options()..., callback = callbacks);145146147