Path: blob/main/examples/structured_2d_dgsem/elixir_euler_warm_bubble.jl
2055 views
using OrdinaryDiffEqLowStorageRK1using Trixi23# Warm bubble test case from4# - Wicker, L. J., and Skamarock, W. C. (1998)5# A time-splitting scheme for the elastic equations incorporating6# second-order Runge–Kutta time differencing7# [DOI: 10.1175/1520-0493(1998)126%3C1992:ATSSFT%3E2.0.CO;2](https://doi.org/10.1175/1520-0493(1998)126%3C1992:ATSSFT%3E2.0.CO;2)8# See also9# - Bryan and Fritsch (2002)10# A Benchmark Simulation for Moist Nonhydrostatic Numerical Models11# [DOI: 10.1175/1520-0493(2002)130<2917:ABSFMN>2.0.CO;2](https://doi.org/10.1175/1520-0493(2002)130<2917:ABSFMN>2.0.CO;2)12# - Carpenter, Droegemeier, Woodward, Hane (1990)13# Application of the Piecewise Parabolic Method (PPM) to14# Meteorological Modeling15# [DOI: 10.1175/1520-0493(1990)118<0586:AOTPPM>2.0.CO;2](https://doi.org/10.1175/1520-0493(1990)118<0586:AOTPPM>2.0.CO;2)16struct WarmBubbleSetup17# Physical constants18g::Float64 # gravity of earth19c_p::Float64 # heat capacity for constant pressure (dry air)20c_v::Float64 # heat capacity for constant volume (dry air)21gamma::Float64 # heat capacity ratio (dry air)2223function WarmBubbleSetup(; g = 9.81, c_p = 1004.0, c_v = 717.0, gamma = c_p / c_v)24new(g, c_p, c_v, gamma)25end26end2728# Initial condition29function (setup::WarmBubbleSetup)(x, t, equations::CompressibleEulerEquations2D)30@unpack g, c_p, c_v = setup3132# center of perturbation33center_x = 10000.034center_z = 2000.035# radius of perturbation36radius = 2000.037# distance of current x to center of perturbation38r = sqrt((x[1] - center_x)^2 + (x[2] - center_z)^2)3940# perturbation in potential temperature41potential_temperature_ref = 300.042potential_temperature_perturbation = 0.043if r <= radius44potential_temperature_perturbation = 2 * cospi(0.5 * r / radius)^245end46potential_temperature = potential_temperature_ref + potential_temperature_perturbation4748# Exner pressure, solves hydrostatic equation for x[2]49exner = 1 - g / (c_p * potential_temperature) * x[2]5051# pressure52p_0 = 100_000.0 # reference pressure53R = c_p - c_v # gas constant (dry air)54p = p_0 * exner^(c_p / R)5556# temperature57T = potential_temperature * exner5859# density60rho = p / (R * T)6162v1 = 20.063v2 = 0.064E = c_v * T + 0.5 * (v1^2 + v2^2)65return SVector(rho, rho * v1, rho * v2, rho * E)66end6768# Source terms69@inline function (setup::WarmBubbleSetup)(u, x, t, equations::CompressibleEulerEquations2D)70@unpack g = setup71rho, _, rho_v2, _ = u72return SVector(zero(eltype(u)), zero(eltype(u)), -g * rho, -g * rho_v2)73end7475###############################################################################76# semidiscretization of the compressible Euler equations77warm_bubble_setup = WarmBubbleSetup()7879equations = CompressibleEulerEquations2D(warm_bubble_setup.gamma)8081boundary_conditions = (x_neg = boundary_condition_periodic,82x_pos = boundary_condition_periodic,83y_neg = boundary_condition_slip_wall,84y_pos = boundary_condition_slip_wall)8586polydeg = 387basis = LobattoLegendreBasis(polydeg)8889# This is a good estimate for the speed of sound in this example.90# Other values between 300 and 400 should work as well.91surface_flux = FluxLMARS(340.0)9293volume_flux = flux_kennedy_gruber94volume_integral = VolumeIntegralFluxDifferencing(volume_flux)9596solver = DGSEM(basis, surface_flux, volume_integral)9798coordinates_min = (0.0, 0.0)99coordinates_max = (20_000.0, 10_000.0)100101cells_per_dimension = (64, 32)102mesh = StructuredMesh(cells_per_dimension, coordinates_min, coordinates_max,103periodicity = (true, false))104105semi = SemidiscretizationHyperbolic(mesh, equations, warm_bubble_setup, solver,106source_terms = warm_bubble_setup,107boundary_conditions = boundary_conditions)108109###############################################################################110# ODE solvers, callbacks etc.111112tspan = (0.0, 1000.0) # 1000 seconds final time113114ode = semidiscretize(semi, tspan)115116summary_callback = SummaryCallback()117118analysis_interval = 1000119120analysis_callback = AnalysisCallback(semi, interval = analysis_interval,121extra_analysis_errors = (:entropy_conservation_error,))122123alive_callback = AliveCallback(analysis_interval = analysis_interval)124125save_solution = SaveSolutionCallback(interval = analysis_interval,126save_initial_solution = true,127save_final_solution = true,128output_directory = "out",129solution_variables = cons2prim)130131stepsize_callback = StepsizeCallback(cfl = 1.0)132133callbacks = CallbackSet(summary_callback,134analysis_callback,135alive_callback,136save_solution,137stepsize_callback)138139###############################################################################140# run the simulation141sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false);142maxiters = 1.0e7,143dt = 1.0, # solve needs some value here but it will be overwritten by the stepsize_callback144ode_default_options()..., callback = callbacks);145146147