Rising bubble (dry Euler with gravity)
This tutorial sets up a warm rising-bubble test case in TrixiAtmo.jl.
The setup follows the warm-bubble benchmark described by Bryan and Fritsch, which includes both dry and moist atmospheric variants:
Bryan, G. H., and Fritsch, J. M. (2002). A benchmark simulation for moist nonhydrostatic numerical models. Monthly Weather Review, 130(12), 2917-2928. DOI: 10.1175/1520-0493(2002)130<2917:ABSFMN>2.0.CO;2
The setup is based on a standard atmospheric benchmark where a localized warm perturbation is placed in a background atmosphere. Since the perturbation is warmer than the air around it, it should rise as the solution evolves.
This example uses the moist Euler equations, but the moisture variables are initialized to zero in our initial condition.
In this tutorial we go through:
- the governing equations
- the warm-bubble initial condition
- the mesh and DG discretization
- the source term and boundary conditions
- the time integration setup
Load packages
We start by loading the time integrator, the core Trixi.jl tools, and the atmospheric extensions from TrixiAtmo.jl.
using OrdinaryDiffEqLowStorageRKusing Trixiusing TrixiAtmousing TrixiAtmo: cons2drypotGoverning equations
Here we use the two-dimensional compressible moist Euler equations with gravity. The parameters below specify the specific heat values in $\mathrm{J}\,\mathrm{kg}^{-1}\,\mathrm{K}^{-1}$ for dry air and water vapor.
c_pd = 1004 # specific heat at constant pressure for dry airc_vd = 717 # specific heat at constant volume for dry airc_pv = 1885 # specific heat at constant pressure for water vaporc_vv = 1424 # specific heat at constant volume for water vaporequations = CompressibleMoistEulerEquations2D(c_pd = c_pd, c_vd = c_vd, c_pv = c_pv, c_vv = c_vv, gravity = EARTH_GRAVITATIONAL_ACCELERATION)equations┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ CompressibleMoistEulerEquations2D │
│ ═════════════════════════════════ │
│ #variables: ……………………………………………………………… 6 │
│ │ variable 1: ………………………………………………………… rho │
│ │ variable 2: ………………………………………………………… rho_v1 │
│ │ variable 3: ………………………………………………………… rho_v2 │
│ │ variable 4: ………………………………………………………… rho_E │
│ │ variable 5: ………………………………………………………… rho_qv │
│ │ variable 6: ………………………………………………………… rho_ql │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘Initial condition: warm bubble
This follows the warm bubble setup from Bryan and Fritsch (2002).
The background potential temperature is $\theta_{ref} = 300\,\mathrm{K}$, and a localized perturbation is added inside a bubble centered at $(x_c, z_c) = (10000\,\mathrm{m}, 2000\,\mathrm{m})$ with radius $r_c = 2000\,\mathrm{m}$.
Inside the bubble, the perturbation is
\[\Delta \theta = 2\,\mathrm{K} \cos^2\!\left(\frac{\pi}{2}\frac{r}{r_c}\right),\]
and outside the bubble it is zero.
The pressure is chosen from an isentropic background state. Then density and temperature are reconstructed from pressure and potential temperature.
The moisture variables are initialized to zero.
For reusable examples, this initial condition could be moved to the equations source file. Here we keep it local so that the tutorial is self contained and readers can see exactly how the warm bubble state is constructed.
function initial_condition_warm_bubble(x, t, equations::CompressibleMoistEulerEquations2D) @unpack p_0, kappa, g, c_pd, c_vd, R_d, R_v = equations xc = 10000 zc = 2000 r = sqrt((x[1] - xc)^2 + (x[2] - zc)^2) rc = 2000 θ_ref = 300 Δθ = 0 if r <= rc Δθ = 2 * cospi(0.5f0 * r / rc)^2 end # Potential temperature with warm perturbation θ = θ_ref + Δθ # Background hydrostatic pressure p = p_0 * (1 - kappa * g * x[2] / (R_d * θ_ref))^(c_pd / R_d) # Recover density and temperature rho = p / ((p / p_0)^kappa * R_d * θ) T = p / (R_d * rho) v1 = 20 v2 = 0 rho_v1 = rho * v1 rho_v2 = rho * v2 rho_E = rho * c_vd * T + 1 / 2 * rho * (v1^2 + v2^2) return SVector(rho, rho_v1, rho_v2, rho_E, zero(eltype(g)), zero(eltype(g)))endinitial_condition = initial_condition_warm_bubbleinitial_condition_warm_bubble (generic function with 1 method)Boundary conditions and source term
The mesh is periodic in the horizontal direction. Therefore, no boundary condition is needed in the x-direction. The vertical direction is not periodic, so we prescribe slip-wall boundary conditions at the bottom and top boundaries.
This must match the mesh periodicity setting below:
periodicity = (true, false)where the first entry corresponds to the horizontal x-direction and the second entry corresponds to the vertical z-direction.
boundary_conditions = (; y_neg = boundary_condition_slip_wall, y_pos = boundary_condition_slip_wall)(y_neg = Trixi.boundary_condition_slip_wall, y_pos = Trixi.boundary_condition_slip_wall)Gravity acts in the vertical direction. For the conservative variables
\[ \mathbf{u} = \left( \rho, \rho v_1, \rho v_2, \rho E, \rho q_v, \rho q_l \right)^\mathrm{T},\]
the gravitational source contributes to the vertical momentum equation and to the total energy equation through the vertical velocity.
function source_terms_gravity(u, x, t, equations::CompressibleMoistEulerEquations2D) @unpack g = equations rho = u[1] rho_v2 = u[3] return SVector(zero(eltype(u)), zero(eltype(u)), -g * rho, -g * rho_v2, zero(eltype(u)), zero(eltype(u)))endsource_term = source_terms_gravitysource_terms_gravity (generic function with 1 method)DG discretization
We use a DGSEM discretization with polynomial degree polydeg = 4. The surface flux is LMARS, and the volume flux is the Chandrashekar flux in flux-differencing form.
polydeg = 4surface_flux = FluxLMARS(360.0)volume_flux = flux_chandrashekarvolume_integral = VolumeIntegralFluxDifferencing(volume_flux)solver = DGSEM(polydeg, surface_flux, volume_integral)solver┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ DG{Float64} │
│ ═══════════ │
│ basis: …………………………………………………………………………… LobattoLegendreBasis{Float64}(polydeg=4) │
│ mortar: ………………………………………………………………………… LobattoLegendreMortarL2{Float64}(polydeg=4) │
│ surface integral: ……………………………………………… SurfaceIntegralWeakForm │
│ │ surface flux: …………………………………………………… FluxLMARS{Float64}(360.0) │
│ volume integral: ………………………………………………… VolumeIntegralFluxDifferencing │
│ │ volume flux: ……………………………………………………… flux_chandrashekar │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘Mesh
The computational domain is
\[ x \in [0, 20000]\,\mathrm{m}, \quad z \in [-5000, 15000]\,\mathrm{m}\]
We use a P4estMesh with horizontal periodicity and non-periodic vertical boundaries.
The initial coarse p4est mesh has 2 x 2 macro cells. During construction, each macro cell is uniformly refined initial_refinement_level times, so the actual computational mesh is much finer than the initial 2 x 2 layout.
coordinates_min = (0.0, -5000.0)coordinates_max = (20000.0, 15000.0)trees_per_dimension = (2, 2)initial_refinement_level = 4mesh = P4estMesh(trees_per_dimension, polydeg = 1, coordinates_min = coordinates_min, coordinates_max = coordinates_max, initial_refinement_level = initial_refinement_level, periodicity = (true, false))mesh┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ P4estMesh{2, 2, Float64} │
│ ════════════════════════ │
│ #trees: ………………………………………………………………………… 4 │
│ current #cells: …………………………………………………… 1024 │
│ polydeg: ……………………………………………………………………… 1 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘Semidiscretization
Next we combine the mesh, equations, initial condition, solver, boundary conditions, and source term into a semidiscretization.
semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver, boundary_conditions = boundary_conditions, source_terms = source_term)semi┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SemidiscretizationHyperbolic │
│ ════════════════════════════ │
│ #spatial dimensions: ……………………………………… 2 │
│ mesh: ……………………………………………………………………………… P4estMesh{2, 2, Float64} │
│ equations: ………………………………………………………………… CompressibleMoistEulerEquations2D │
│ initial condition: …………………………………………… initial_condition_warm_bubble │
│ boundary conditions: ……………………………………… 2 │
│ │ y_neg: ……………………………………………………………………… typeof(boundary_condition_slip_wall) │
│ │ y_pos: ……………………………………………………………………… typeof(boundary_condition_slip_wall) │
│ source terms: ………………………………………………………… source_terms_gravity │
│ solver: ………………………………………………………………………… DG │
│ total #DOFs per field: ………………………………… 25600 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘Time interval and ODE problem
The problem is evolved on the shortened time interval tspan = (0.0, 400.0) so that the tutorial remains inexpensive to run. For a longer benchmark-style simulation, increase the final time to 1000.0 and optionally increase initial_refinement_level.
tspan = (0.0, 400.0)ode = semidiscretize(semi, tspan)ODEProblem with uType Vector{Float64} and tType Float64. In-place: true
Non-trivial mass matrix: false
timespan: (0.0, 400.0)
u0: 153600-element Vector{Float64}:
1.6928994337172714
33.85798867434543
0.0
423758.16154419235
0.0
0.0
1.6928994337172714
33.85798867434543
0.0
423758.16154419235
⋮
24006.265810013676
0.0
0.0
0.21773417227496653
4.35468344549933
0.0
24006.265810013676
0.0
0.0Callbacks and diagnostics
We use a standard collection of callbacks:
SummaryCallback()for a summary of the runAnalysisCallback(...)for diagnosticsAliveCallback(...)for progress informationSaveSolutionCallback(...)to write outputStepsizeCallback(...)to control the time step with a CFL condition
The saved variables are given by cons2drypot.
summary_callback = SummaryCallback()analysis_interval = 1000solution_variables = cons2drypotcons2drypot (generic function with 1 method)The entropy conservation error is a standard diagnostic for entropy-conservative or entropy-stable discretizations. It is useful here because the volume flux is the Chandrashekar flux in flux-differencing form.
analysis_callback = AnalysisCallback(semi, interval = analysis_interval, extra_analysis_errors = (:entropy_conservation_error,))alive_callback = AliveCallback(analysis_interval = analysis_interval)save_solution = SaveSolutionCallback(interval = 1000, save_initial_solution = true, save_final_solution = true, solution_variables = solution_variables)┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SaveSolutionCallback │
│ ════════════════════ │
│ interval: …………………………………………………………………… 1000 │
│ solution variables: ………………………………………… cons2drypot │
│ save initial solution: ………………………………… yes │
│ save final solution: ……………………………………… yes │
│ output directory: ……………………………………………… /home/runner/work/TrixiAtmo.jl/TrixiAtmo.jl/docs/out │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘The time step is selected dynamically from a CFL condition. A moderate CFL number keeps the tutorial run stable while avoiding an unnecessarily small time step.
stepsize_callback = StepsizeCallback(cfl = 0.5)callbacks = CallbackSet(summary_callback, analysis_callback, alive_callback, save_solution, stepsize_callback)callbacksSciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{typeof(Trixi.summary_callback), typeof(Trixi.summary_callback), Trixi.var"#initialize#SummaryCallback##0"{Bool}, typeof(Trixi.finalize_summary_callback), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{Trixi.var"#1314#1315"{Int64}, Trixi.AnalysisCallback{Trixi.LobattoLegendreAnalyzer{Float64, 9, SVector{9, Float64}, Matrix{Float64}}, Tuple{typeof(Trixi.entropy_timederivative)}, SVector{6, Float64}, @NamedTuple{u_local::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{6}, Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 486}, u_tmp1::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{6}, Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 270}, x_local::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{2}, Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 162}, x_tmp1::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{2}, Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 90}, jacobian_local::StrideArraysCore.StaticStrideArray{Float64, 2, (1, 2), Tuple{Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}, 81}, jacobian_tmp1::StrideArraysCore.StaticStrideArray{Float64, 2, (1, 2), Tuple{Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}, 45}}}, typeof(Trixi.initialize!), typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{Trixi.AliveCallback, Trixi.AliveCallback, typeof(Trixi.initialize!), typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{Trixi.SaveSolutionCallback{Int64, typeof(TrixiAtmo.cons2drypot)}, Trixi.SaveSolutionCallback{Int64, typeof(TrixiAtmo.cons2drypot)}, typeof(Trixi.initialize_save_cb!), typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{Trixi.StepsizeCallback{Returns{Float64}, Returns{Float64}}, Trixi.StepsizeCallback{Returns{Float64}, Returns{Float64}}, typeof(Trixi.initialize!), typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}}}((), (SummaryCallback, SciMLBase.DiscreteCallback{Trixi.var"#1314#1315"{Int64}, Trixi.AnalysisCallback{Trixi.LobattoLegendreAnalyzer{Float64, 9, SVector{9, Float64}, Matrix{Float64}}, Tuple{typeof(Trixi.entropy_timederivative)}, SVector{6, Float64}, @NamedTuple{u_local::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{6}, Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 486}, u_tmp1::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{6}, Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 270}, x_local::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{2}, Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 162}, x_tmp1::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{2}, Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 90}, jacobian_local::StrideArraysCore.StaticStrideArray{Float64, 2, (1, 2), Tuple{Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}, 81}, jacobian_tmp1::StrideArraysCore.StaticStrideArray{Float64, 2, (1, 2), Tuple{Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}, 45}}}, typeof(Trixi.initialize!), typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}(Trixi.var"#1314#1315"{Int64}(1000), Trixi.AnalysisCallback{Trixi.LobattoLegendreAnalyzer{Float64, 9, SVector{9, Float64}, Matrix{Float64}}, Tuple{typeof(Trixi.entropy_timederivative)}, SVector{6, Float64}, @NamedTuple{u_local::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{6}, Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 486}, u_tmp1::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{6}, Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 270}, x_local::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{2}, Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 162}, x_tmp1::StrideArraysCore.StaticStrideArray{Float64, 3, (1, 2, 3), Tuple{Static.StaticInt{2}, Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}, Static.StaticInt{1}}, 90}, jacobian_local::StrideArraysCore.StaticStrideArray{Float64, 2, (1, 2), Tuple{Static.StaticInt{9}, Static.StaticInt{9}}, Tuple{Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}, 81}, jacobian_tmp1::StrideArraysCore.StaticStrideArray{Float64, 2, (1, 2), Tuple{Static.StaticInt{9}, Static.StaticInt{5}}, Tuple{Nothing, Nothing}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}, 45}}}(0.0, 0.0, 0, 0.0, 1000, false, "out", "analysis.dat", LobattoLegendreAnalyzer{Float64}(polydeg=8), [:l2_error, :linf_error, :entropy_conservation_error], (Trixi.entropy_timederivative,), [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], (u_local = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], u_tmp1 = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], x_local = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], x_tmp1 = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0;;; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], jacobian_local = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], jacobian_tmp1 = [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0])), Trixi.initialize!, SciMLBase.FINALIZE_DEFAULT, Bool[0, 0], nothing, (), true), AliveCallback(alive_interval=100), SaveSolutionCallback(interval=1000), StepsizeCallback(cfl_hyperbolic=Returns{Float64}(0.5), cfl_parabolic=Returns{Float64}(0.0), interval=1)))Run the simulation
We now run the simulation. The value dt = 1.0 is only an initial time-step guess; the actual time step is adjusted by StepsizeCallback.
sol = solve(ode, CarpenterKennedy2N54(williamson_condition = false), maxiters = 1.0e7, dt = 1.0, save_everystep = false, callback = callbacks)summary_callback()
████████╗██████╗ ██╗██╗ ██╗██╗
╚══██╔══╝██╔══██╗██║╚██╗██╔╝██║
██║ ██████╔╝██║ ╚███╔╝ ██║
██║ ██╔══██╗██║ ██╔██╗ ██║
██║ ██║ ██║██║██╔╝ ██╗██║
╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SemidiscretizationHyperbolic │
│ ════════════════════════════ │
│ #spatial dimensions: ……………………………………… 2 │
│ mesh: ……………………………………………………………………………… P4estMesh{2, 2, Float64} │
│ equations: ………………………………………………………………… CompressibleMoistEulerEquations2D │
│ initial condition: …………………………………………… initial_condition_warm_bubble │
│ boundary conditions: ……………………………………… 2 │
│ │ y_neg: ……………………………………………………………………… typeof(boundary_condition_slip_wall) │
│ │ y_pos: ……………………………………………………………………… typeof(boundary_condition_slip_wall) │
│ source terms: ………………………………………………………… source_terms_gravity │
│ solver: ………………………………………………………………………… DG │
│ total #DOFs per field: ………………………………… 25600 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ P4estMesh{2, 2, Float64} │
│ ════════════════════════ │
│ #trees: ………………………………………………………………………… 4 │
│ current #cells: …………………………………………………… 1024 │
│ polydeg: ……………………………………………………………………… 1 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ CompressibleMoistEulerEquations2D │
│ ═════════════════════════════════ │
│ #variables: ……………………………………………………………… 6 │
│ │ variable 1: ………………………………………………………… rho │
│ │ variable 2: ………………………………………………………… rho_v1 │
│ │ variable 3: ………………………………………………………… rho_v2 │
│ │ variable 4: ………………………………………………………… rho_E │
│ │ variable 5: ………………………………………………………… rho_qv │
│ │ variable 6: ………………………………………………………… rho_ql │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ DG{Float64} │
│ ═══════════ │
│ basis: …………………………………………………………………………… LobattoLegendreBasis{Float64}(polydeg=4) │
│ mortar: ………………………………………………………………………… LobattoLegendreMortarL2{Float64}(polydeg=4) │
│ surface integral: ……………………………………………… SurfaceIntegralWeakForm │
│ │ surface flux: …………………………………………………… FluxLMARS{Float64}(360.0) │
│ volume integral: ………………………………………………… VolumeIntegralFluxDifferencing │
│ │ volume flux: ……………………………………………………… flux_chandrashekar │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ AnalysisCallback │
│ ════════════════ │
│ interval: …………………………………………………………………… 1000 │
│ analyzer: …………………………………………………………………… LobattoLegendreAnalyzer{Float64}(polydeg=8) │
│ │ error 1: ………………………………………………………………… l2_error │
│ │ error 2: ………………………………………………………………… linf_error │
│ │ error 3: ………………………………………………………………… entropy_conservation_error │
│ │ integral 1: ………………………………………………………… entropy_timederivative │
│ save analysis to file: ………………………………… no │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ AliveCallback │
│ ═════════════ │
│ interval: …………………………………………………………………… 100 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ SaveSolutionCallback │
│ ════════════════════ │
│ interval: …………………………………………………………………… 1000 │
│ solution variables: ………………………………………… cons2drypot │
│ save initial solution: ………………………………… yes │
│ save final solution: ……………………………………… yes │
│ output directory: ……………………………………………… /home/runner/work/TrixiAtmo.j…o.jl/docs/build/tutorials/out │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ StepsizeCallback │
│ ════════════════ │
│ CFL Hyperbolic: …………………………………………………… Returns{Float64}(0.5) │
│ CFL Parabolic: ……………………………………………………… Returns{Float64}(0.0) │
│ Interval: …………………………………………………………………… 1 │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Time integration │
│ ════════════════ │
│ Start time: ……………………………………………………………… 0.0 │
│ Final time: ……………………………………………………………… 400.0 │
│ time integrator: ………………………………………………… CarpenterKennedy2N54 │
│ adaptive: …………………………………………………………………… false │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Environment information │
│ ═══════════════════════ │
│ #threads: …………………………………………………………………… 1 │
│ threading backend: …………………………………………… polyester │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'CompressibleMoistEulerEquations2D' with DGSEM(polydeg=4)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 0 run time: 9.96000000e-07 s
Δt: 1.00000000e+00 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 0.00000000e+00 (0.000%) time/DOF/RHS: NaN s
PID: Inf s
#DOFs per field: 25600 alloc'd memory: 366.199 MiB
#elements: 1024 device memory: 0.000 MiB
Variable: rho rho_v1 rho_v2 rho_E rho_qv rho_ql
L2 error: 3.21304264e-07 6.42608527e-06 0.00000000e+00 6.42607011e-05 0.00000000e+00 0.00000000e+00
Linf error: 8.91156392e-06 1.78231278e-04 0.00000000e+00 1.78238348e-03 0.00000000e+00 0.00000000e+00
∑∂S/∂U ⋅ Uₜ : -1.84841147e-14
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 100 │ Δt: 8.1291e-02 │ sim. time: 8.1291e+00 (2.032%) │ run time: 2.2681e+00 s
#timesteps: 200 │ Δt: 8.1291e-02 │ sim. time: 1.6258e+01 (4.065%) │ run time: 4.3935e+00 s
#timesteps: 300 │ Δt: 8.1290e-02 │ sim. time: 2.4387e+01 (6.097%) │ run time: 6.5501e+00 s
#timesteps: 400 │ Δt: 8.1290e-02 │ sim. time: 3.2516e+01 (8.129%) │ run time: 8.7320e+00 s
#timesteps: 500 │ Δt: 8.1289e-02 │ sim. time: 4.0645e+01 (10.161%) │ run time: 1.0879e+01 s
#timesteps: 600 │ Δt: 8.1289e-02 │ sim. time: 4.8774e+01 (12.194%) │ run time: 1.3039e+01 s
#timesteps: 700 │ Δt: 8.1289e-02 │ sim. time: 5.6903e+01 (14.226%) │ run time: 1.5183e+01 s
#timesteps: 800 │ Δt: 8.1288e-02 │ sim. time: 6.5032e+01 (16.258%) │ run time: 1.7335e+01 s
#timesteps: 900 │ Δt: 8.1287e-02 │ sim. time: 7.3161e+01 (18.290%) │ run time: 1.9491e+01 s
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'CompressibleMoistEulerEquations2D' with DGSEM(polydeg=4)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 1000 run time: 2.17440221e+01 s
Δt: 8.12864418e-02 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 8.12893091e+01 (20.322%) time/DOF/RHS: 1.57483082e-07 s
PID: 1.69192137e-07 s
#DOFs per field: 25600 alloc'd memory: 383.278 MiB
#elements: 1024 device memory: 0.000 MiB
Variable: rho rho_v1 rho_v2 rho_E rho_qv rho_ql
L2 error: 5.73956933e-04 1.35463224e-01 2.29967644e-01 2.06304998e+01 0.00000000e+00 0.00000000e+00
Linf error: 6.20336379e-03 9.44174145e-01 2.52725356e+00 7.56292331e+01 0.00000000e+00 0.00000000e+00
∑∂S/∂U ⋅ Uₜ : -2.16034247e-11
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 1100 │ Δt: 8.1286e-02 │ sim. time: 8.9418e+01 (22.354%) │ run time: 2.3831e+01 s
#timesteps: 1200 │ Δt: 8.1285e-02 │ sim. time: 9.7546e+01 (24.387%) │ run time: 2.5997e+01 s
#timesteps: 1300 │ Δt: 8.1286e-02 │ sim. time: 1.0568e+02 (26.419%) │ run time: 2.8146e+01 s
#timesteps: 1400 │ Δt: 8.1284e-02 │ sim. time: 1.1380e+02 (28.451%) │ run time: 3.0297e+01 s
#timesteps: 1500 │ Δt: 8.1282e-02 │ sim. time: 1.2193e+02 (30.483%) │ run time: 3.2452e+01 s
#timesteps: 1600 │ Δt: 8.1282e-02 │ sim. time: 1.3006e+02 (32.515%) │ run time: 3.4614e+01 s
#timesteps: 1700 │ Δt: 8.1282e-02 │ sim. time: 1.3819e+02 (34.547%) │ run time: 3.6752e+01 s
#timesteps: 1800 │ Δt: 8.1282e-02 │ sim. time: 1.4632e+02 (36.579%) │ run time: 3.8938e+01 s
#timesteps: 1900 │ Δt: 8.1282e-02 │ sim. time: 1.5444e+02 (38.611%) │ run time: 4.1113e+01 s
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'CompressibleMoistEulerEquations2D' with DGSEM(polydeg=4)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 2000 run time: 4.33725813e+01 s
Δt: 8.12805730e-02 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 1.62572884e+02 (40.643%) time/DOF/RHS: 1.57981875e-07 s
PID: 1.68874316e-07 s
#DOFs per field: 25600 alloc'd memory: 393.478 MiB
#elements: 1024 device memory: 0.000 MiB
Variable: rho rho_v1 rho_v2 rho_E rho_qv rho_ql
L2 error: 6.77361371e-04 2.68751167e-01 4.56148953e-01 2.51166554e+01 0.00000000e+00 0.00000000e+00
Linf error: 6.51258325e-03 1.86283545e+00 4.93987964e+00 9.99506964e+01 0.00000000e+00 0.00000000e+00
∑∂S/∂U ⋅ Uₜ : -4.41374541e-11
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 2100 │ Δt: 8.1280e-02 │ sim. time: 1.7070e+02 (42.675%) │ run time: 4.5469e+01 s
#timesteps: 2200 │ Δt: 8.1280e-02 │ sim. time: 1.7883e+02 (44.707%) │ run time: 4.7636e+01 s
#timesteps: 2300 │ Δt: 8.1281e-02 │ sim. time: 1.8696e+02 (46.739%) │ run time: 4.9825e+01 s
#timesteps: 2400 │ Δt: 8.1280e-02 │ sim. time: 1.9509e+02 (48.771%) │ run time: 5.1987e+01 s
#timesteps: 2500 │ Δt: 8.1279e-02 │ sim. time: 2.0321e+02 (50.803%) │ run time: 5.4146e+01 s
#timesteps: 2600 │ Δt: 8.1277e-02 │ sim. time: 2.1134e+02 (52.835%) │ run time: 5.6276e+01 s
#timesteps: 2700 │ Δt: 8.1277e-02 │ sim. time: 2.1947e+02 (54.867%) │ run time: 5.8411e+01 s
#timesteps: 2800 │ Δt: 8.1278e-02 │ sim. time: 2.2760e+02 (56.899%) │ run time: 6.0575e+01 s
#timesteps: 2900 │ Δt: 8.1277e-02 │ sim. time: 2.3572e+02 (58.931%) │ run time: 6.2760e+01 s
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'CompressibleMoistEulerEquations2D' with DGSEM(polydeg=4)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 3000 run time: 6.50418476e+01 s
Δt: 8.12753553e-02 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 2.43851732e+02 (60.963%) time/DOF/RHS: 1.58338565e-07 s
PID: 1.69195781e-07 s
#DOFs per field: 25600 alloc'd memory: 403.733 MiB
#elements: 1024 device memory: 0.000 MiB
Variable: rho rho_v1 rho_v2 rho_E rho_qv rho_ql
L2 error: 6.76856790e-04 3.94236274e-01 6.76031129e-01 1.64513717e+01 0.00000000e+00 0.00000000e+00
Linf error: 6.50120087e-03 2.79714045e+00 6.99136906e+00 1.05141151e+02 0.00000000e+00 0.00000000e+00
∑∂S/∂U ⋅ Uₜ : -1.35094529e-10
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 3100 │ Δt: 8.1275e-02 │ sim. time: 2.5198e+02 (62.995%) │ run time: 6.7144e+01 s
#timesteps: 3200 │ Δt: 8.1275e-02 │ sim. time: 2.6011e+02 (65.027%) │ run time: 6.9321e+01 s
#timesteps: 3300 │ Δt: 8.1274e-02 │ sim. time: 2.6823e+02 (67.059%) │ run time: 7.1509e+01 s
#timesteps: 3400 │ Δt: 8.1276e-02 │ sim. time: 2.7636e+02 (69.090%) │ run time: 7.3683e+01 s
#timesteps: 3500 │ Δt: 8.1276e-02 │ sim. time: 2.8449e+02 (71.122%) │ run time: 7.5887e+01 s
#timesteps: 3600 │ Δt: 8.1275e-02 │ sim. time: 2.9262e+02 (73.154%) │ run time: 7.8099e+01 s
#timesteps: 3700 │ Δt: 8.1274e-02 │ sim. time: 3.0074e+02 (75.186%) │ run time: 8.0287e+01 s
#timesteps: 3800 │ Δt: 8.1273e-02 │ sim. time: 3.0887e+02 (77.218%) │ run time: 8.2483e+01 s
#timesteps: 3900 │ Δt: 8.1273e-02 │ sim. time: 3.1700e+02 (79.250%) │ run time: 8.4672e+01 s
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'CompressibleMoistEulerEquations2D' with DGSEM(polydeg=4)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 4000 run time: 8.69400307e+01 s
Δt: 8.12729829e-02 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 3.25126215e+02 (81.282%) time/DOF/RHS: 1.60039549e-07 s
PID: 1.70978671e-07 s
#DOFs per field: 25600 alloc'd memory: 413.933 MiB
#elements: 1024 device memory: 0.000 MiB
Variable: rho rho_v1 rho_v2 rho_E rho_qv rho_ql
L2 error: 6.79869782e-04 5.12271742e-01 8.80902115e-01 2.36173162e+01 0.00000000e+00 0.00000000e+00
Linf error: 6.51188612e-03 3.69003695e+00 8.48262666e+00 1.39519131e+02 0.00000000e+00 0.00000000e+00
∑∂S/∂U ⋅ Uₜ : -4.35071818e-10
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 4100 │ Δt: 8.1274e-02 │ sim. time: 3.3325e+02 (83.313%) │ run time: 8.9027e+01 s
#timesteps: 4200 │ Δt: 8.1271e-02 │ sim. time: 3.4138e+02 (85.345%) │ run time: 9.1175e+01 s
#timesteps: 4300 │ Δt: 8.1271e-02 │ sim. time: 3.4951e+02 (87.377%) │ run time: 9.3296e+01 s
#timesteps: 4400 │ Δt: 8.1271e-02 │ sim. time: 3.5764e+02 (89.409%) │ run time: 9.5431e+01 s
#timesteps: 4500 │ Δt: 8.1272e-02 │ sim. time: 3.6576e+02 (91.441%) │ run time: 9.7575e+01 s
#timesteps: 4600 │ Δt: 8.1270e-02 │ sim. time: 3.7389e+02 (93.472%) │ run time: 9.9691e+01 s
#timesteps: 4700 │ Δt: 8.1270e-02 │ sim. time: 3.8202e+02 (95.504%) │ run time: 1.0181e+02 s
#timesteps: 4800 │ Δt: 8.1269e-02 │ sim. time: 3.9014e+02 (97.536%) │ run time: 1.0396e+02 s
#timesteps: 4900 │ Δt: 8.1270e-02 │ sim. time: 3.9827e+02 (99.568%) │ run time: 1.0613e+02 s
────────────────────────────────────────────────────────────────────────────────────────────────────
Simulation running 'CompressibleMoistEulerEquations2D' with DGSEM(polydeg=4)
────────────────────────────────────────────────────────────────────────────────────────────────────
#timesteps: 4922 run time: 1.06701121e+02 s
Δt: 2.30230462e-02 └── GC time: 0.00000000e+00 s (0.000%)
sim. time: 4.00000000e+02 (100.000%) time/DOF/RHS: 1.56558848e-07 s
PID: 1.67341217e-07 s
#DOFs per field: 25600 alloc'd memory: 424.241 MiB
#elements: 1024 device memory: 0.000 MiB
Variable: rho rho_v1 rho_v2 rho_E rho_qv rho_ql
L2 error: 6.74923238e-04 6.11686329e-01 1.04891770e+00 2.46721003e+01 0.00000000e+00 0.00000000e+00
Linf error: 6.50091004e-03 4.37358858e+00 9.40454011e+00 1.53040255e+02 0.00000000e+00 0.00000000e+00
∑∂S/∂U ⋅ Uₜ : -2.21047459e-09
────────────────────────────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────────────────────────────
Trixi.jl simulation finished. Final time: 400.0 Time steps: 4922 (accepted), 4922 (total)
────────────────────────────────────────────────────────────────────────────────────────────────────
Trixi.jl
──────────────────────────────────────────────────────────────────────────────────────
Time Allocations
────────────────────── ────────────────────────
Tot / % measured: 108s / 94.1% 94.2MiB / 60.4%
──────────────────────────────── ────────────────────── ────────────────────────
Section ncalls time %tot avg alloc %tot avg
──────────────────────────────────────────────────────────────────────────────────────
rhs_hyperbolic! 24.6k 100s 98.4% 4.05ms 3.92KiB 0.0% 0.16B
├─ volume integral 24.6k 80.4s 79.4% 3.27ms ∅ ∅ ∅
├─ interface flux 24.6k 9.47s 9.4% 385μs ∅ ∅ ∅
├─ prolong2interfaces 24.6k 3.18s 3.1% 129μs ∅ ∅ ∅
├─ surface integral 24.6k 2.26s 2.2% 91.8μs ∅ ∅ ∅
├─ source terms 24.6k 1.57s 1.5% 63.6μs ∅ ∅ ∅
├─ reset ∂u/∂t 24.6k 1.10s 1.1% 44.7μs ∅ ∅ ∅
├─ Jacobian 24.6k 1.04s 1.0% 42.4μs ∅ ∅ ∅
├─ boundary flux 24.6k 475ms 0.5% 19.3μs ∅ ∅ ∅
├─ ~rhs_hyperbolic!~ 24.6k 79.4ms 0.1% 3.23μs 3.92KiB 0.0% 0.16B
├─ prolong2boundaries 24.6k 60.1ms 0.1% 2.44μs ∅ ∅ ∅
├─ prolong2mortars 24.6k 3.91ms 0.0% 159ns ∅ ∅ ∅
└─ mortar flux 24.6k 2.45ms 0.0% 100ns ∅ ∅ ∅
calculate dt 4.92k 1.41s 1.4% 286μs ∅ ∅ ∅
analyze solution 6 146ms 0.1% 24.3ms 34.5MiB 60.7% 5.75MiB
I/O 7 66.8ms 0.1% 9.54ms 22.4MiB 39.3% 3.20MiB
├─ save solution 6 59.5ms 0.1% 9.92ms 22.4MiB 39.3% 3.73MiB
├─ ~I/O~ 7 7.23ms 0.0% 1.03ms 8.38KiB 0.0% 1.20KiB
├─ get element variables 6 2.10μs 0.0% 351ns ∅ ∅ ∅
├─ save mesh 6 1.77μs 0.0% 295ns ∅ ∅ ∅
└─ get node variables 6 965ns 0.0% 161ns ∅ ∅ ∅
──────────────────────────────────────────────────────────────────────────────────────
Trixi.jl
──────────────────────────────────────────────────────────────────────────────────────
Time Allocations
────────────────────── ────────────────────────
Tot / % measured: 109s / 92.7% 183MiB / 31.1%
──────────────────────────────── ────────────────────── ────────────────────────
Section ncalls time %tot avg alloc %tot avg
──────────────────────────────────────────────────────────────────────────────────────
rhs_hyperbolic! 24.6k 100s 98.4% 4.05ms 3.92KiB 0.0% 0.16B
├─ volume integral 24.6k 80.4s 79.4% 3.27ms ∅ ∅ ∅
├─ interface flux 24.6k 9.47s 9.4% 385μs ∅ ∅ ∅
├─ prolong2interfaces 24.6k 3.18s 3.1% 129μs ∅ ∅ ∅
├─ surface integral 24.6k 2.26s 2.2% 91.8μs ∅ ∅ ∅
├─ source terms 24.6k 1.57s 1.5% 63.6μs ∅ ∅ ∅
├─ reset ∂u/∂t 24.6k 1.10s 1.1% 44.7μs ∅ ∅ ∅
├─ Jacobian 24.6k 1.04s 1.0% 42.4μs ∅ ∅ ∅
├─ boundary flux 24.6k 475ms 0.5% 19.3μs ∅ ∅ ∅
├─ ~rhs_hyperbolic!~ 24.6k 79.4ms 0.1% 3.23μs 3.92KiB 0.0% 0.16B
├─ prolong2boundaries 24.6k 60.1ms 0.1% 2.44μs ∅ ∅ ∅
├─ prolong2mortars 24.6k 3.91ms 0.0% 159ns ∅ ∅ ∅
└─ mortar flux 24.6k 2.45ms 0.0% 100ns ∅ ∅ ∅
calculate dt 4.92k 1.41s 1.4% 286μs ∅ ∅ ∅
analyze solution 6 146ms 0.1% 24.3ms 34.5MiB 60.7% 5.75MiB
I/O 7 66.8ms 0.1% 9.54ms 22.4MiB 39.3% 3.20MiB
├─ save solution 6 59.5ms 0.1% 9.92ms 22.4MiB 39.3% 3.73MiB
├─ ~I/O~ 7 7.23ms 0.0% 1.03ms 8.38KiB 0.0% 1.20KiB
├─ get element variables 6 2.10μs 0.0% 351ns ∅ ∅ ∅
├─ save mesh 6 1.77μs 0.0% 295ns ∅ ∅ ∅
└─ get node variables 6 965ns 0.0% 161ns ∅ ∅ ∅
──────────────────────────────────────────────────────────────────────────────────────Expected behavior
Since the perturbation is warmer than the surrounding air, it is less dense and should rise under gravity. As the solution develops, the bubble should move upward and begin to deform.
This kind of test is a standard atmospheric benchmark because it checks how well the method handles buoyancy, gravity, compressibility, and the spatial discretization all at once.
This page was generated using Literate.jl.