AmrRuntime Class 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 multi-block engine at runtime. More...
#include <amr_runtime.hpp>
Collaboration diagram for pops::AmrRuntime:Public Types | |
| using | TagPredicate = std::function< bool(const ConstArray4 &, int, int)> |
| Tag predicate of the union regrid: (ConstArray4 of the read field, i, j) -> should we refine ? HOST type (evaluated in the host loop of tag_cells, never on device): a std::function capturing a concrete functor is licit (nvcc-safe – the predicate does not enter a kernel). | |
Public Member Functions | |
| AmrRuntime (const Geometry &geom, const BoxArray &ba_coarse, const BCRec &bcPhi, std::vector< AmrRuntimeBlock > blocks, Periodicity base_per=Periodicity{true, true}, bool replicated_coarse=true, std::function< bool(Real, Real)> active={}) | |
| int | nlev () const |
| std::size_t | n_blocks () const |
| const VariableSet & | block_cons_vars (std::size_t b) const |
Conservative VariableSet (names + physical roles, Model::conservative_vars()) of block b. | |
| std::size_t | n_coupled_sources () const |
| MultiFab & | phi () |
| MultiFab & | poisson_rhs () |
| const MultiFab & | aux (int k) const |
| std::vector< AmrLevelMP > & | levels (std::size_t b) |
| Real | mass (std::size_t b) const |
| std::vector< double > | density (std::size_t b) const |
| int | solve_count () const |
| int | regrid_count () const |
| void | set_regrid (int every, int grow=2, int margin=2) |
Activates the UNION-TAGS REGRID at the cadence every (in macro-steps): every every macro-steps, BEFORE the macro-step's step(dt) (D2, consistent with the single-block amr_dsl_block.hpp:104), the shared hierarchy is re-gridded from the UNION of the tags of all blocks + phi. | |
| void | set_block_tag_predicate (std::size_t b, TagPredicate crit) |
Registers the TAG PREDICATE of block b (D1: PER-BLOCK union criterion). | |
| void | set_phi_tag_predicate (TagPredicate crit) |
| Registers the PHI TAG PREDICATE (D4: SEPARATE phi criterion, on |grad phi|). | |
| void | set_named_aux (int comp, std::vector< Real > field) |
Registers a model-NAMED aux field (ADC-291) at shared-channel component comp (= kAuxNamedBase. | |
| void | set_named_aux_bc (int comp, AuxHaloPolicy policy) |
Registers a per-field aux HALO policy (ADC-369) for the named component comp: solve_fields applies it onto the COARSE aux AFTER the shared fill_ghosts, overriding only that component's physical-face ghosts (periodic faces stay periodic). | |
| void | add_coupled_source (const std::vector< std::string > &in_blocks, const std::vector< std::string > &in_roles, const std::vector< double > &consts, const std::vector< std::string > &out_blocks, const std::vector< std::string > &out_roles, const std::vector< int > &prog_ops, const std::vector< int > &prog_args, const std::vector< int > &prog_lens) |
| Registers an inter-species COUPLED SOURCE (DSL CoupledSource, P5 bytecode) on the runtime facade, counterpart of System::add_coupled_source. | |
| void | coupled_source_step (Real dt) |
| Applies ALL the registered coupled sources of a step dt, by forward-Euler splitting. | |
| void | solve_fields () |
| sync_down (per block) + system coarse Poisson (CO-LOCATED SUMMED RHS) + coarse aux + fine injection. | |
| void | solve_named_fields () |
| Solves every registered NAMED elliptic field (ADC-428) on the coarse, writes phi (+ centered grad) into the field's own aux components, ghost-fills them and injects coarse->fine. | |
| void | regrid () |
| UNION-TAGS REGRID (capstone Phase 2, C.6; docs/AMR_REGRID_UNION_TAGS_DESIGN.md, steps R0-R8). | |
| void | step (Real dt) |
| Advances the system by one macro-step dt. | |
| Real | step_cfl (Real cfl, Real h) |
| substeps/stride-aware CFL step (runtime counterpart of System::step_cfl, EXACT mirror of its formula). | |
| int | macro_step () const |
| MACRO-STEP counter of the engine (regrid + hold-then-catch-up stride cadence: regrid when macro_step_ % regrid_every == 0, stride catch-up when (macro_step_+1) % stride == 0). | |
| void | set_macro_step (int s) |
| RESTORES the macro-step counter (IO v1, reserved for restart via AmrSystem::set_clock): without it the regrid/stride cadence would restart from phase 0 after a resume. | |
| void | set_profiler (runtime::program::Profiler *prof) |
| AMR / MPI PROFILING SEAM (Spec 5 sec.12.5, ADC-479 criterion 43). | |
| void | add_dt_bound (const std::string &label, std::function< double()> fn) |
| GLOBAL step bound (AMR counterpart of System::add_dt_bound): fn() evaluated once per step_cfl, all_reduce_min, <= 0/non-finite = inert. | |
| void | add_coupled_frequency (const std::string &label, Real mu) |
| DECLARED frequency of a coupled source (CoupledSource.frequency, wave-3 audit): step bound dt <= cfl / mu on the MACRO-step (the couplings apply once per macro-step). | |
| void | add_coupled_frequency_expr (const std::string &label, const std::vector< std::string > &in_blocks, const std::vector< std::string > &in_roles, const std::vector< double > &consts, const std::vector< int > &freq_prog_ops, const std::vector< int > &freq_prog_args) |
| PER-CELL COUPLED frequency (CoupledSource.frequency with an Expr, refinement of the CONSTANT frequency above): a bytecode program mu(U) on the SAME register table as the source (inputs in_blocks/in_roles then constants consts). | |
| const std::string & | last_dt_bound () const |
| ACTIVE bound of the last step_cfl ("transport:<block>" / "source_frequency:<block>" / "stability_dt:<block>" / "global:<label>" / "degenerate" / "" before the first step). | |
| const NewtonReport & | newton_report (const std::string &name) const |
NEWTON REPORT (OPT-IN IMEX diagnostics) of block name, AGGREGATED over the levels and substeps of its LAST advance (cf. | |
| std::vector< double > | potential () |
| Coarse potential (component 0 of the shared aux) as an n*n row-major field. | |
| Real | max_speed () |
| Max SYSTEM wave speed (max over the blocks) on the current coarse. Requires the aux up to date. | |
| int | n_patches () const |
| std::vector< PatchBox > | patch_boxes () const |
| int | coarse_local_boxes () const |
| int | coarse_total_boxes () const |
| int | block_n_vars (std::size_t b) const |
| std::vector< double > | block_level_state (std::size_t b, int k) const |
| std::vector< double > | block_level_state_global (std::size_t b, int k) const |
| void | set_block_level_state (std::size_t b, int k, const std::vector< double > &s) |
| std::vector< double > | level_potential (int k) |
| std::vector< double > | level_potential_global (int k) |
| void | set_level_potential (int k, const std::vector< double > &p) |
Named multi-elliptic fields (ADC-428) | |
A SECOND elliptic solve (beyond the default coarse Poisson) for a user-named field (m.elliptic_field("psi", rhs=..., aux=[...])) on the AMR hierarchy. AMR counterpart of SystemFieldSolver::register_named_field / solve_named_field_from_state. Each named field owns a DEDICATED coarse GeometricMG solver (built lazily, REUSING the native solver – the operator is never reimplemented), its RHS = sum over blocks of Registers named | |
| void | register_named_field (const std::string &field, int phi_comp, int gx_comp, int gy_comp) |
| void | set_block_named_elliptic_rhs (std::size_t b, const std::string &field, std::function< void(const MultiFab &, MultiFab &)> rhs) |
Attaches named field's RHS contribution closure (rhs += elliptic_field_rhs(U_b)) to block b. | |
| std::size_t | n_named_fields () const |
| Number of registered named elliptic fields (diagnostic / test). | |
| bool | has_named_field (const std::string &field) const |
True if field is a registered named elliptic field. | |
| std::vector< double > | named_field_values (const std::string &field) |
Solved potential of named field as a COARSE n*n row-major field (diagnostic / read-back). | |
Detailed Description
AMR multi-block engine at runtime.
Owns the SHARED aux per level, the coarse Poisson (GeometricMG), the geometry + BC, and the type-erased block REGISTRY. Reproduces the AmrSystemCoupler algorithm (solve_fields + step) over closures rather than a CoupledSystem.
Member Typedef Documentation
◆ TagPredicate
| using pops::AmrRuntime::TagPredicate = std::function<bool(const ConstArray4&, int, int)> |
Tag predicate of the union regrid: (ConstArray4 of the read field, i, j) -> should we refine ? HOST type (evaluated in the host loop of tag_cells, never on device): a std::function capturing a concrete functor is licit (nvcc-safe – the predicate does not enter a kernel).
We use it for the PER-BLOCK criterion (read on the block density/U, component 0) and for the phi criterion (read on the shared aux). docs/AMR_REGRID_UNION_TAGS_DESIGN.md (D1, D4).
Constructor & Destructor Documentation
◆ AmrRuntime()
|
inline |
- Parameters
-
geom geometry of the coarse level (domain + physical extents). ba_coarse BoxArray of the coarse (the coarse Poisson lives on it). bcPhi BC of the coarse Poisson. blocks block registry (>= 1), all on the SAME layout (guarded at the ctor). base_per periodicity of the base domain (transport). replicated_coarse ownership of level 0 (replicated single-box, or distributed multi-box). active conductive-wall predicate (passed to MG; empty = none).
Member Function Documentation
◆ add_coupled_frequency()
|
inline |
DECLARED frequency of a coupled source (CoupledSource.frequency, wave-3 audit): step bound dt <= cfl / mu on the MACRO-step (the couplings apply once per macro-step).
mu <= 0 = inert (no bound).
◆ add_coupled_frequency_expr()
|
inline |
PER-CELL COUPLED frequency (CoupledSource.frequency with an Expr, refinement of the CONSTANT frequency above): a bytecode program mu(U) on the SAME register table as the source (inputs in_blocks/in_roles then constants consts).
Evaluated at each step_cfl on the COARSE level of the input blocks (where the AMR CFL lives: h = dx_coarse), MAX reduction + global all_reduce_max, bound dt <= cfl / max(mu) on the macro-step. The bound is thus evaluated on the COARSE (not on the fine patches): consistent with the AMR transport CFL, but a local under-estimate of mu under a fine patch is not seen (assumed choice, documented). Empty program -> ignored (no bound). Form validation (opcodes / register bounds) and STRICT role resolution, like add_coupled_source.
Here is the call graph for this function:◆ add_coupled_source()
|
inline |
Registers an inter-species COUPLED SOURCE (DSL CoupledSource, P5 bytecode) on the runtime facade, counterpart of System::add_coupled_source.
The ABI is FLAT (postfix bytecode): we resolve each (block, role) into (block index, component) then store a closure that, at each macro-step AFTER the transport, applies the source by additive forward-Euler splitting via coupled_source_step. The coupling is ENTIRELY baked into a stack machine (device-clean functor CoupledSourceKernel): NO per-cell Python callback in the hot path.
CONSERVATION (conservative exchange): with an add_pair construction (one +expr term on one block, -expr exactly on the other, SAME cell), the two per-cell contributions are opposite up to sign, so n_a + n_b is conserved PER CELL (and globally) to machine precision, independent of dt and of the state. The engine does not enforce it (an ionization creating a pair is licit): conservation is a property of the constructed coupling, checked test-side.
- Parameters
-
in_blocks/in_roles READ fields (one register per (block, role)), in register order. consts constants (parameters), loaded into the registers after the inputs. out_blocks/out_roles target (block, role) of each source term. prog_ops/prog_args CONCATENATED postfix bytecode of all the terms (split by prog_lens). prog_lens program length of each term (size == out_blocks).
- Exceptions
-
std::runtime_error on an inconsistent form, an unknown role, an unknown block, an opcode or register out of bounds, or a program too long (same guards as System).
Here is the call graph for this function:◆ add_dt_bound()
|
inline |
GLOBAL step bound (AMR counterpart of System::add_dt_bound): fn() evaluated once per step_cfl, all_reduce_min, <= 0/non-finite = inert.
For user coupling/scheduler/policies.
◆ aux()
|
inline |
◆ block_cons_vars()
|
inline |
Conservative VariableSet (names + physical roles, Model::conservative_vars()) of block b.
The SAME cons_vars that add_coupled_source resolves (block, role) against; exposed read-only so the facade can resolve a name/role-selected regrid variable into a component per block (ADC-296).
- Exceptions
-
if bis out of bounds.
◆ block_level_state()
|
inline |
Here is the call graph for this function:◆ block_level_state_global()
|
inline |
Here is the call graph for this function:◆ block_n_vars()
|
inline |
◆ coarse_local_boxes()
|
inline |
◆ coarse_total_boxes()
|
inline |
◆ coupled_source_step()
|
inline |
Applies ALL the registered coupled sources of a step dt, by forward-Euler splitting.
Runtime counterpart of AmrSystemCoupler::coupled_source_step: we refresh the fields (aux per level) then, source by source, we apply the bytecode INDEPENDENTLY AT EACH LEVEL of the shared hierarchy (the blocks live on ALL levels), followed by a fine -> coarse cascade.
COVERAGE INVARIANT (#169): the source was applied independently on EACH level, so a coarse cell COVERED by a fine patch would otherwise carry its own coarse source, unrelated to the source seen by its fine children. A covered coarse cell MUST be the 2x2 average of its children (it does not represent matter on its own). We restore this consistency by the SAME fine -> coarse cascade (mf_average_down_mb) as solve_fields and the compile-time engine: without it, the mass diagnostic (sum of the coarse only) would count a phantom coarse source under the patch. Single-level hierarchy: no covered cell, the cascade loops do not run -> bit-identical to the no-patch case.
PER-CELL CONSERVATION: at a given level, each term writes out(i,j,comp) += dt * S(reg(i,j)) on the SAME cell (i,j) read by the inputs; an add_pair exchange lays +S on one block and -S on the other AT THE SAME (i,j), so the sum of the two blocks is unchanged cell by cell. Without a registered source (coupled_sources_ empty): total no-op -> bit-identical trajectory to the historical one.
Here is the call graph for this function:
Here is the caller graph for this function:◆ density()
|
inline |
◆ has_named_field()
|
inline |
True if field is a registered named elliptic field.
◆ last_dt_bound()
|
inline |
ACTIVE bound of the last step_cfl ("transport:<block>" / "source_frequency:<block>" / "stability_dt:<block>" / "global:<label>" / "degenerate" / "" before the first step).
◆ level_potential()
|
inline |
Here is the call graph for this function:◆ level_potential_global()
|
inline |
Here is the call graph for this function:◆ levels()
|
inline |
Here is the caller graph for this function:◆ macro_step()
|
inline |
MACRO-STEP counter of the engine (regrid + hold-then-catch-up stride cadence: regrid when macro_step_ % regrid_every == 0, stride catch-up when (macro_step_+1) % stride == 0).
◆ mass()
|
inline |
◆ max_speed()
|
inline |
Max SYSTEM wave speed (max over the blocks) on the current coarse. Requires the aux up to date.
Here is the call graph for this function:◆ n_blocks()
|
inline |
◆ n_coupled_sources()
|
inline |
◆ n_named_fields()
|
inline |
Number of registered named elliptic fields (diagnostic / test).
◆ n_patches()
|
inline |
◆ named_field_values()
|
inline |
Solved potential of named field as a COARSE n*n row-major field (diagnostic / read-back).
Solves the fields if needed (counterpart of potential() for the default phi), then reads the field's phi_comp on the coarse aux.
- Exceptions
-
if fieldis unregistered. AMR counterpart of System::aux_field_component for a named elliptic field.
Here is the call graph for this function:◆ newton_report()
|
inline |
NEWTON REPORT (OPT-IN IMEX diagnostics) of block name, AGGREGATED over the levels and substeps of its LAST advance (cf.
AmrRuntimeBlock::newton_report). AMR counterpart of System::newton_report.
- Exceptions
-
std::runtime_error if the block is unknown, or if it was not added with newton_diagnostics=true (no silently empty report).
◆ nlev()
|
inline |
◆ patch_boxes()
|
inline |
◆ phi()
|
inline |
Here is the call graph for this function:◆ poisson_rhs()
|
inline |
Here is the call graph for this function:◆ potential()
|
inline |
Coarse potential (component 0 of the shared aux) as an n*n row-major field.
Solves the fields if needed (counterpart of AmrSystem::potential), then reads aux(0). Identical for all blocks.
Here is the call graph for this function:◆ register_named_field()
|
inline |
◆ regrid()
|
inline |
UNION-TAGS REGRID (capstone Phase 2, C.6; docs/AMR_REGRID_UNION_TAGS_DESIGN.md, steps R0-R8).
Re-grids the SHARED hierarchy from the UNION (cell-by-cell OR) of the tags of ALL blocks (per-block predicate, D1) + the phi tags (on |grad phi|, D4), followed by ONE SINGLE Berger-Rigoutsos clustering -> ONE SINGLE new fine layout applied to ALL blocks (including those held by their stride, D3) AND to the shared aux. Maintains the shared-layout PRECONDITION (same_layout_or_throw) after the regrid. v1 with 2 LEVELS (coarse + 1 fine, D5): no-op if nlev < 2. No-op (grid unchanged) if the union of the tags is empty (nothing to refine).
Here is the call graph for this function:
Here is the caller graph for this function:◆ regrid_count()
|
inline |
◆ set_block_level_state()
|
inline |
Here is the call graph for this function:◆ set_block_named_elliptic_rhs()
|
inline |
Attaches named field's RHS contribution closure (rhs += elliptic_field_rhs(U_b)) to block b.
Called per declared field once the runtime owns the blocks.
- Exceptions
-
if bis out of bounds.
◆ set_block_tag_predicate()
|
inline |
Registers the TAG PREDICATE of block b (D1: PER-BLOCK union criterion).
The predicate is evaluated on the block U (component 0 = density, or a discrete gradient at the caller's charge) at the PARENT level during the regrid; the UNION (OR) of the predicates of all blocks + the phi criterion drives the clustering. A block WITHOUT a registered predicate tags nothing on ITS side (it stays re-gridded as background, present everywhere, by the union of the other criteria).
- Exceptions
-
if bis out of bounds.
◆ set_level_potential()
|
inline |
Here is the call graph for this function:◆ set_macro_step()
|
inline |
RESTORES the macro-step counter (IO v1, reserved for restart via AmrSystem::set_clock): without it the regrid/stride cadence would restart from phase 0 after a resume.
No effect on the level state; only sets the cadence phase.
◆ set_named_aux()
|
inline |
Registers a model-NAMED aux field (ADC-291) at shared-channel component comp (= kAuxNamedBase.
- k for the k-th named field of a block), as a coarse base-level field
field(n*n row-major, global cell index j*nx+i). The field is STATIC (external to the elliptic): solve_fields re-applies it onto the coarse aux every macro-step AFTER field_postprocess (which only writes phi/grad, comps 0..2) and BEFORE the coarse->fine injection, so it reaches every level and SURVIVES a regrid (regrid re-solves). AMR counterpart of System::set_aux_field_component. No-op default: without a named field the map is empty and the path is bit-identical.compmust be >= kAuxNamedBase and within the channel (the facade validates and resolves the name).
◆ set_named_aux_bc()
|
inline |
Registers a per-field aux HALO policy (ADC-369) for the named component comp: solve_fields applies it onto the COARSE aux AFTER the shared fill_ghosts, overriding only that component's physical-face ghosts (periodic faces stay periodic).
Coarse-level scope (fine patches touching the domain boundary inherit the shared BC). No-op default. AMR counterpart of System::set_aux_field_halo_component.
◆ set_phi_tag_predicate()
|
inline |
Registers the PHI TAG PREDICATE (D4: SEPARATE phi criterion, on |grad phi|).
The predicate is evaluated on the shared aux of the parent level (components 1,2 = grad phi in x,y) during the regrid; it adds to the union of the blocks' tags. Not registered -> phi does not contribute to the union.
◆ set_profiler()
|
inline |
AMR / MPI PROFILING SEAM (Spec 5 sec.12.5, ADC-479 criterion 43).
The AmrSystem owns the runtime::program::Profiler (parity with System::profiler_) and wires it in here AFTER build, so the engine times its non-numeric AMR phases – regrid, fill_boundary (the cross-rank ghost exchange), average_down (fine -> coarse restriction) – into the SAME table profile_report() renders, alongside the coarse step / field_solve phases. The pointer is null by default (the engine never touches it), and every scope/count is guarded by profiler_->enabled(), so a run WITHOUT profiling pays ZERO cost (no scope object, no clock read) – the granularity is per-regrid / per-solve, NOT per-cell. Passing nullptr detaches the profiler (no-op timing).
◆ set_regrid()
|
inline |
Activates the UNION-TAGS REGRID at the cadence every (in macro-steps): every every macro-steps, BEFORE the macro-step's step(dt) (D2, consistent with the single-block amr_dsl_block.hpp:104), the shared hierarchy is re-gridded from the UNION of the tags of all blocks + phi.
every == 0 (DEFAULT) -> FROZEN hierarchy, regrid never called -> BIT-IDENTICAL trajectory to the historical one (the feature is opt-in). grow: tag dilation (nesting + anticipation); margin: nesting (clamp the patches to the boundaries). Must be called BEFORE the first step.
◆ solve_count()
|
inline |
◆ solve_fields()
|
inline |
sync_down (per block) + system coarse Poisson (CO-LOCATED SUMMED RHS) + coarse aux + fine injection.
Reproduces AmrSystemCoupler::solve_fields identically, but the system RHS is assembled by the blocks' add_elliptic_rhs closures (Sum_b elliptic_rhs_b(U_b)) instead of a compile-time RhsAssembler.
Here is the call graph for this function:
Here is the caller graph for this function:◆ solve_named_fields()
|
inline |
Solves every registered NAMED elliptic field (ADC-428) on the coarse, writes phi (+ centered grad) into the field's own aux components, ghost-fills them and injects coarse->fine.
Mirror of the default Poisson block above (steps 2-4) but per named field, reusing a DEDICATED GeometricMG. The default phi/grad (comps 0..2) are never touched. No-op (early return) without a named field, so the default-only path stays bit-identical.
Here is the call graph for this function:
Here is the caller graph for this function:◆ step()
|
inline |
Advances the system by one macro-step dt.
We first solve the fields (co-located summed Poisson, ONCE per macro-step: OncePerStep cadence), then each block advances over ITS level stack with ITS scheme, honoring its stride cadence and its substeps, and ITS temporal treatment. Runtime counterpart of AmrSystemCoupler::step (OncePerStep): the compile-time version carries substeps/stride in block_substeps_v / block_stride_v and chooses the treatment by the constexpr block_time_treatment_v; here the engine carries the substep loop, the stride filter AND the IMEX-vs-explicit selection.
TREATMENT SELECTION (capstone vii):
- EXPLICIT block (b.imex == false): the advance closure does ONE advance_amr (transport + forward-Euler source), called substeps times;
- IMEX block (b.imex == true): the imex_advance closure does ONE SOURCE-FREE advance_amr then the IMPLICIT stiff source backward_euler_source per level + cascade (cf. AmrRuntimeBlock::imex_advance), called substeps times. Unconditionally stable on a stiff relaxation (where the explicit, of factor |1 - dt/eps|, DIVERGES as soon as dt > 2 eps). The substep loop is COMMON to both treatments (substeps applications of h = bdt/substeps), so the runtime also SUB-CYCLES the IMEX splitting. At substeps=1 this sub-cycling is a no-op and the IMEX path coincides with the IMEX branch of the compile-time engine AmrSystemCoupler::step; for substeps>1 it DIVERGES deliberately from that engine (which itself ignores substeps on its IMEX branch): see IMEX SEMANTICS UNDER substeps in the header (CFL-safe on the transport, backward-Euler stable at any step, stiff relaxation more accurate). imex == false everywhere -> advance path only -> bit-identical trajectory to the historical one (the IMEX is opt-in).
Here is the call graph for this function:
Here is the caller graph for this function:◆ step_cfl()
substeps/stride-aware CFL step (runtime counterpart of System::step_cfl, EXACT mirror of its formula).
A block of stride cadence advances by an effective step stride*dt in substeps substeps, so each substep is worth stride*dt/substeps; the per-substep stability condition stride*dt/substeps <= cfl*h/w_b gives dt <= cfl*h*substeps_b/(stride_b*w_b). The GLOBAL dt is the min over the blocks (the most constraining). We first solve the fields (per-block max_speed requires the aux up to date), compute dt, then advance by one step(dt). h = coarse mesh spacing (dx_coarse). Returns the dt used. Single-block (a single block, stride=1): if w_b is the only constraining one, dt = cfl*h*substeps/w (identical to System::step_cfl single-block).
Here is the call graph for this function:The documentation for this class was generated from the following file:
- include/pops/runtime/amr/amr_runtime.hpp
Generated by