AMR Regridding Conservation

This example checks the conservative part of the dynamic AMR algorithm: prolongation, restriction, and coarse-fine flux correction during repeated regridding. A transported entropy pulse is evolved over a short time so the feature stays well away from the physical boundaries and the observed drift is dominated by the adaptive machinery rather than true domain outflow.

Mathematical Setup

We track the relative drift in the four Euler conserved quantities: total mass, $x$-momentum, $y$-momentum, and total energy.

Reference

  • Berger, M.J. & Colella, P. (1989). Local Adaptive Mesh Refinement for Shock Hydrodynamics. Journal of Computational Physics, 82, 64-84.
using CairoMakie

amr_common_path = joinpath(@__DIR__, "amr_common.jl")
isfile(amr_common_path) || (amr_common_path = joinpath(@__DIR__, "..", "literate_verification", "amr_common.jl"))
include(amr_common_path)

base_cells = [8, 12, 16]
results = [dynamic_conservation_case(base; max_level = 2) for base in base_cells]
max_drifts = [result.max_relative_drift for result in results]
component_drifts = [
    [result.relative_drift[index] for result in results] for index in eachindex(AMR_CONSERVED_NAMES)
]

fig = Figure(fontsize = 22, size = (850, 500))
ax = Axis(
    fig[1, 1],
    xlabel = "Base block cells per side",
    ylabel = "Maximum relative conserved drift",
    yscale = log10,
    title = "Dynamic AMR Conservation Drift",
)
scatterlines!(
    ax,
    base_cells,
    max_drifts;
    color = :crimson,
    marker = :rect,
    linewidth = 2,
    markersize = 12,
)
resize_to_layout!(fig)
fig
Example block output

Test Assertions

The regridding/conservation drift should stay below 1e-3 and improve as the base AMR resolution is increased.

if isdefined(@__MODULE__, :record_evidence_result)
    record_evidence_result(
        metrics = Dict(
            "max_relative_drifts" => max_drifts,
            "component_drifts" => Dict(
                AMR_CONSERVED_NAMES[index] => component_drifts[index] for index in eachindex(AMR_CONSERVED_NAMES)
            ),
            "worst_drift" => maximum(max_drifts),
        ),
        artifacts = ["amr_regridding_conservation.png"],
        notes = [
            "This invariant exercises the dynamic solve_amr(prob) regridding path rather than the fixed-hierarchy canonical ODEProblem route.",
            "The short integration horizon keeps the entropy pulse far from the domain boundaries so the reported drift reflects adaptive transfer consistency.",
        ],
        summary = Dict(
            "base_cells" => base_cells,
            "max_relative_drifts" => max_drifts,
            "component_drifts" => Dict(
                AMR_CONSERVED_NAMES[index] => component_drifts[index] for index in eachindex(AMR_CONSERVED_NAMES)
            ),
        ),
    )
end

Just the code

An uncommented version of this example is given below. You can view the source code for this file here.

using CairoMakie

amr_common_path = joinpath(@__DIR__, "amr_common.jl")
isfile(amr_common_path) || (amr_common_path = joinpath(@__DIR__, "..", "literate_verification", "amr_common.jl"))
include(amr_common_path)

base_cells = [8, 12, 16]
results = [dynamic_conservation_case(base; max_level = 2) for base in base_cells]
max_drifts = [result.max_relative_drift for result in results]
component_drifts = [
    [result.relative_drift[index] for result in results] for index in eachindex(AMR_CONSERVED_NAMES)
]

fig = Figure(fontsize = 22, size = (850, 500))
ax = Axis(
    fig[1, 1],
    xlabel = "Base block cells per side",
    ylabel = "Maximum relative conserved drift",
    yscale = log10,
    title = "Dynamic AMR Conservation Drift",
)
scatterlines!(
    ax,
    base_cells,
    max_drifts;
    color = :crimson,
    marker = :rect,
    linewidth = 2,
    markersize = 12,
)
resize_to_layout!(fig)
fig


if isdefined(@__MODULE__, :record_evidence_result)
    record_evidence_result(
        metrics = Dict(
            "max_relative_drifts" => max_drifts,
            "component_drifts" => Dict(
                AMR_CONSERVED_NAMES[index] => component_drifts[index] for index in eachindex(AMR_CONSERVED_NAMES)
            ),
            "worst_drift" => maximum(max_drifts),
        ),
        artifacts = ["amr_regridding_conservation.png"],
        notes = [
            "This invariant exercises the dynamic solve_amr(prob) regridding path rather than the fixed-hierarchy canonical ODEProblem route.",
            "The short integration horizon keeps the entropy pulse far from the domain boundaries so the reported drift reflects adaptive transfer consistency.",
        ],
        summary = Dict(
            "base_cells" => base_cells,
            "max_relative_drifts" => max_drifts,
            "component_drifts" => Dict(
                AMR_CONSERVED_NAMES[index] => component_drifts[index] for index in eachindex(AMR_CONSERVED_NAMES)
            ),
        ),
    )
end

This page was generated using Literate.jl.