Path: blob/main/examples/p4est_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 = P4estMesh{2}(mesh_file,80polydeg = 4,81mapping = mapping_twist,82initial_refinement_level = 1)8384boundary_condition = BoundaryConditionDirichlet(initial_condition)85boundary_conditions = Dict(:all => boundary_condition)8687semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver,88boundary_conditions = boundary_conditions)8990###############################################################################91# ODE solvers, callbacks etc.9293tspan = (0.0, 0.15)94ode = semidiscretize(semi, tspan)9596summary_callback = SummaryCallback()9798analysis_interval = 10099analysis_callback = AnalysisCallback(semi, interval = analysis_interval)100101alive_callback = AliveCallback(analysis_interval = analysis_interval)102103save_solution = SaveSolutionCallback(interval = 100,104save_initial_solution = true,105save_final_solution = true,106solution_variables = cons2prim)107108amr_indicator = IndicatorLöhner(semi,109variable = density_pressure)110111amr_controller = ControllerThreeLevel(semi, amr_indicator,112base_level = 1,113med_level = 3, med_threshold = 0.05,114max_level = 5, max_threshold = 0.1)115amr_callback = AMRCallback(semi, amr_controller,116interval = 5,117adapt_initial_condition = true,118adapt_initial_condition_only_refine = true)119120cfl = 0.5121stepsize_callback = StepsizeCallback(cfl = cfl)122123glm_speed_callback = GlmSpeedCallback(glm_scale = 0.5, cfl = cfl)124125callbacks = CallbackSet(summary_callback,126analysis_callback,127alive_callback,128save_solution,129amr_callback,130stepsize_callback,131glm_speed_callback)132133###############################################################################134# run the simulation135136sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);137dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback138ode_default_options()..., callback = callbacks);139140141