include/pops/runtime/amr/amr_runtime.hpp File ReferenceΒΆ

adc_cpp: include/pops/runtime/amr/amr_runtime.hpp File Reference
adc_cpp 0.3.0
Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends
amr_runtime.hpp File Reference

AMR multi-block engine at RUNTIME (type-erased registry keyed by name). More...

+ Include dependency graph for amr_runtime.hpp:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  pops::AmrRuntimeBlock
 Type-erased closures of ONE AMR block, placed on the shared hierarchy. More...
 
class  pops::AmrRuntime
 AMR multi-block engine at runtime. More...
 

Namespaces

namespace  pops
 

Detailed Description

AMR multi-block engine at RUNTIME (type-erased registry keyed by name).

Runtime counterpart of System::Impl (python/system.cpp): where System type-erases the species (struct Species) on a SINGLE-LEVEL grid, AmrRuntime type-erases N blocks on a SHARED AMR hierarchy. It FAITHFULLY reproduces the AmrSystemCoupler::solve_fields / step algorithm (include/pops/coupling/amr_system_coupler.hpp), but over type-erased closures (the runtime facade does not know the blocks' Model/Limiter/Flux types at compile time) rather than over a compile-time CoupledSystem<Blocks...>.

INVARIANTS (multi-block capstone, docs/AMR_MULTIBLOCK_DESIGN.md):

  • ONE single shared AMR hierarchy (AmrHierarchyLayout, same_layout_or_throw guard): all blocks live on EXACTLY the same BoxArray + DistributionMapping + dx/dy per level;
  • ALL blocks live on ALL patches (never a local spatial absence of a block);
  • SYSTEM Poisson with a SUMMED and CO-LOCATED right-hand side: rhs[coarse] = Sum_b elliptic_rhs_b(U_b) read at the SAME cells of the shared coarse;
  • aux SHARED per level (phi, grad phi); a single coarse Poisson solve then coarse->fine injection (coupler_inject_aux_mb), exactly like AmrSystemCoupler;
  • PER-BLOCK conservation (reflux + average_down of the AMR engine, in the advance closure).

SCOPE (capstone). We carry blocks with potentially DIFFERENT spatial schemes over the FROZEN hierarchy (no regrid: AmrSystemCoupler has none), with per-block MULTIRATE: substeps (explicit substeps) and stride (hold-then-catch-up cadence), honored in step() mirroring AmrSystemCoupler::step (#140). The TEMPORAL TREATMENT is PER BLOCK: explicit (forward-Euler source, carried by the AMR step) OR IMEX (stiff source treated IMPLICITLY by backward_euler_source, transport staying explicit; capstone vii), selected in step().

IMEX SEMANTICS UNDER substeps (integration decision, follow-up review #184). At substeps=1 AND stride=1 the runtime IMEX branch COINCIDES with the IMEX branch of the compile-time engine AmrSystemCoupler::step (a SOURCE-FREE transport + a backward_euler_source over the effective step). FOR substeps>1 the two paths DIVERGE DELIBERATELY:

  • the COMPILE-TIME engine IGNORES substeps on the IMEX branch: it does ONE single source-free transport then ONE single implicit_advance over the whole effective step bdt (cf. amr_system_coupler.hpp: the substep loop exists only in the Explicit branch);
  • the RUNTIME SUB-CYCLES the IMEX splitting: it applies imex_advance K=substeps times, each over bdt/K, i.e. K Lie steps [transport(dt/K); implicit source(dt/K)]. This choice is INTENTIONAL and SOUND (it is NOT a bug): (a) the source-free explicit transport becomes SAFER in CFL (each substep carries dt/K, so a wave speed K times larger stays admissible); (b) backward-Euler is UNCONDITIONALLY STABLE whatever the step, so sub-cycling never destabilizes the source; (c) refining the backward-Euler step BRINGS the stiff relaxation CLOSER to its continuous trajectory (splitting error and implicit temporal error both O(dt), both reduced). The runtime thus does NOT mirror the compile-time bit-for-bit once substeps>1; it honors substeps CONSISTENTLY with the explicit branch (same split into K equal substeps), which is the behavior expected by a user setting substeps. Non-regression guard: test_amr_multiblock_imex compares a substeps=4 trajectory to substeps=1 and requires them to DIFFER (the sub-cycling is intentional, not accidental).

The union-tags regrid and the compiled multi-block production DSL remain LATER PRs. The runtime facade (AmrSystem) explicitly REFUSES multi-block + regrid_every > 0 as long as the union regrid does not exist.