AmrRuntimeBlock Struct 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
|
Type-erased closures of ONE AMR block, placed on the shared hierarchy. More...
#include <amr_runtime.hpp>
Collaboration diagram for pops::AmrRuntimeBlock:Public Attributes | |
| std::string | name |
| int | ncomp = 1 |
| double | gamma = 1.4 |
| int | substeps = 1 |
| EXPLICIT substeps of the block within ITS effective macro-step: the effective step (stride * dt) is split into substeps equal pieces and each piece is advanced by ONE advance_amr (cf. | |
| int | stride = 1 |
| HOLD-THEN-CATCH-UP cadence of the block (multirate). | |
| int | aux_ncomp = kAuxBaseComps |
| Width of the aux channel READ by the block model (aux_comps<Model>(); >= kAuxBaseComps). | |
| VariableSet | cons_vars |
| Descriptor of the model CONSERVATIVE variables (names + physical ROLES, Model::conservative_vars()). | |
| std::shared_ptr< std::vector< AmrLevelMP > > | levels |
| Level stack of the block (level 0 = coarse, > 0 = fine patches), ON the shared layout. | |
| std::function< void(std::vector< AmrLevelMP > &, const Box2D &, Real, Periodicity, bool)> | advance |
| Advances the block by ONE substep of size dt: AMR transport (Berger-Oliger + conservative reflux. | |
| bool | imex = false |
| TEMPORAL TREATMENT of the block: false (default) = EXPLICIT (forward-Euler source, in advance); true = IMEX (stiff source treated IMPLICITLY by backward_euler_source). | |
| std::function< void(std::vector< AmrLevelMP > &, const Box2D &, Real, Periodicity, bool)> | imex_advance |
| IMEX advance of the block by ONE substep of size dt: (1) EXPLICIT TRANSPORT on the SOURCE-FREE model (-div F only, SourceFreeModel<Model>) by the AMR engine (Berger-Oliger + conservative reflux + average_down), then (2) IMPLICIT STIFF SOURCE backward_euler_source AT EACH LEVEL (local Newton, finite-difference jacobian; implicit mask CARRIED BY THE BLOCK for partial IMEX), followed by a fine -> coarse cascade (mf_average_down_mb). | |
| std::function< void(std::vector< AmrLevelMP > &)> | project_per_level |
| POINTWISE PROJECTION post-pas (ADC-177) : U <- project(U, aux) appliquee PAR NIVEAU a la FIN de l'avance complete du bloc (substeps + reflux/cascade faits). | |
| bool | newton_diagnostics = false |
| NEWTON DIAGNOSTICS (OPT-IN, wave 3: AMR counterpart of System::newton_report). | |
| std::shared_ptr< NewtonReport > | newton_report |
| std::function< void(const MultiFab &, MultiFab &)> | add_elliptic_rhs |
| Contribution of the block to the Poisson right-hand side: rhs += elliptic_rhs_b(U_b) on the coarse. | |
| std::map< std::string, std::function< void(const MultiFab &, MultiFab &)> > | named_elliptic_rhs |
Per-NAMED-field elliptic right-hand-side contributions of the block (ADC-428): field name -> closure rhs += elliptic_field_rhs_b(U_b) on the coarse, exactly like add_elliptic_rhs but for a SECOND (user-named) elliptic field declared by the block's model (m.elliptic_field). | |
| std::function< Real(const MultiFab &, const MultiFab &)> | max_speed |
| Speed driving the block CFL on the coarse. | |
| std::function< Real(const MultiFab &, const MultiFab &)> | source_frequency |
| OPTIONAL STEP BOUNDS of the block (AMR StabilityPolicy, audit 2026-06): evaluated on the COARSE (level 0, where the AMR CFL lives – cf. | |
| std::function< Real(const MultiFab &, const MultiFab &)> | stability_dt |
| std::function< Real()> | mass |
| Mass of component 0 of the block coarse (sum u*dV; cross-rank reduced if distributed). | |
| std::function< std::vector< double >()> | density |
| Coarse density (component 0) of the block as a global n*n row-major field (diagnostic). | |
| std::function< std::vector< double >(const MultiFab &)> | potential |
| Coarse potential read from the shared aux (component 0) as an n*n row-major field (diagnostic). | |
Detailed Description
Type-erased closures of ONE AMR block, placed on the shared hierarchy.
AMR counterpart of the Species struct of System::Impl: a name + its level stack (on the shared layout) + its closures (advance / elliptic-rhs / max_speed / mass / density). The closures capture the CONCRETE Model/Limiter/Flux of the block (resolved at build): the kernel stays COMPILED, only the block list is type-erased. Produced by detail::build_amr_block (amr_dsl_block.hpp).
Member Data Documentation
◆ add_elliptic_rhs
Contribution of the block to the Poisson right-hand side: rhs += elliptic_rhs_b(U_b) on the coarse.
CO-LOCATED: the loop reads U_b and writes rhs AT THE SAME cells (same shared coarse BoxArray). The SUM of the contributions of all blocks forms the system Poisson RHS.
◆ advance
| std::function<void(std::vector<AmrLevelMP>&, const Box2D&, Real, Periodicity, bool)> pops::AmrRuntimeBlock::advance |
Advances the block by ONE substep of size dt: AMR transport (Berger-Oliger + conservative reflux.
- average_down) over the block level stack, with ITS spatial scheme (Limiter, Flux). Captures advance_amr<Limiter, Flux> on the concrete Model. The substep loop and the stride cadence are carried by AmrRuntime::step (runtime counterpart of AmrSystemCoupler::step): the closure does ONE advance_amr, the engine calls it substeps times (dt = effective step/substeps). The signature passes the base domain + periodicity + coarse ownership policy, rewired by the engine.
◆ aux_ncomp
| int pops::AmrRuntimeBlock::aux_ncomp = kAuxBaseComps |
Width of the aux channel READ by the block model (aux_comps<Model>(); >= kAuxBaseComps).
The aux channel SHARED per level is sized to the MAX of this width over all blocks, so that a block reading an extra field (B_z, T_e; n_aux > 3) never reads out of bounds.
◆ cons_vars
| VariableSet pops::AmrRuntimeBlock::cons_vars |
Descriptor of the model CONSERVATIVE variables (names + physical ROLES, Model::conservative_vars()).
Single source of truth to resolve a role (Density, MomentumX, ...) -> component index in add_coupled_source, like System::add_coupled_source reads Species::cons_vars. The resolution is STRICT (#181): if the block does NOT expose the requested canonical role (index_of < 0), add_coupled_source THROWS instead of falling back to component 0 (a silent fallback would apply the source to the wrong field).
◆ density
| std::function<std::vector<double>()> pops::AmrRuntimeBlock::density |
Coarse density (component 0) of the block as a global n*n row-major field (diagnostic).
◆ gamma
| double pops::AmrRuntimeBlock::gamma = 1.4 |
◆ imex
| bool pops::AmrRuntimeBlock::imex = false |
TEMPORAL TREATMENT of the block: false (default) = EXPLICIT (forward-Euler source, in advance); true = IMEX (stiff source treated IMPLICITLY by backward_euler_source).
The facade (AmrSystem) freezes it from time="imex". Selected EXPLICITLY in AmrRuntime::step (runtime counterpart of the constexpr block_time_treatment_v dispatch of AmrSystemCoupler::step): an explicit block goes through advance, an IMEX block through imex_advance. false everywhere -> bit-identical trajectory to the historical one.
◆ imex_advance
| std::function<void(std::vector<AmrLevelMP>&, const Box2D&, Real, Periodicity, bool)> pops::AmrRuntimeBlock::imex_advance |
IMEX advance of the block by ONE substep of size dt: (1) EXPLICIT TRANSPORT on the SOURCE-FREE model (-div F only, SourceFreeModel<Model>) by the AMR engine (Berger-Oliger + conservative reflux + average_down), then (2) IMPLICIT STIFF SOURCE backward_euler_source AT EACH LEVEL (local Newton, finite-difference jacobian; implicit mask CARRIED BY THE BLOCK for partial IMEX), followed by a fine -> coarse cascade (mf_average_down_mb).
ONE call = ONE Lie step [transport; implicit source] over dt. The SEMANTICS of this splitting (source-free transport then backward-Euler) mirror the IMEX branch of AmrSystemCoupler::step (SourceFreeModel + AmrImplicitSourceStepper); at substeps=1 it is IDENTICAL to it. But step() calls THIS closure substeps times (over dt = effective step / substeps), so for substeps>1 the runtime SUB-CYCLES the IMEX splitting where the compile-time applies it once over the whole effective step: DIVERGENCE INTENTIONAL (cf. IMEX SEMANTICS UNDER substeps, file header). Captures the CONCRETE Model/Limiter/Flux + the mask (build_amr_block); the kernel stays COMPILED, only the block registry is type-erased. CONSERVATION INVARIANT (LOCAL source): the source is cell-local (outside face fluxes), so OUTSIDE the reflux registers -> conservation at coarse-fine interfaces stays intact; a COVERED coarse cell becomes again the 2x2 average of its children through the final cascade (otherwise the mass diagnostic, sum of the coarse only, would count a phantom source). Empty for an explicit block (imex == false): step() never calls it.
◆ levels
| std::shared_ptr<std::vector<AmrLevelMP> > pops::AmrRuntimeBlock::levels |
Level stack of the block (level 0 = coarse, > 0 = fine patches), ON the shared layout.
The aux pointer of each AmrLevelMP is (re)wired by AmrRuntime to the SHARED aux of the level. shared_ptr: AmrRuntimeBlock stays MOVABLE (a std::vector<AmrLevelMP> is heavy to move into a std::function, and the engine ctor needs a stable address for the closures).
◆ mass
| std::function<Real()> pops::AmrRuntimeBlock::mass |
Mass of component 0 of the block coarse (sum u*dV; cross-rank reduced if distributed).
◆ max_speed
Speed driving the block CFL on the coarse.
By default max_wave_speed (historical); when the model declares the HasStabilitySpeed trait, it is lambda* (stability_speed) that the closure reduces – SAME policy as System (make_max_speed), cf. build_amr_block.
◆ name
| std::string pops::AmrRuntimeBlock::name |
◆ named_elliptic_rhs
| std::map<std::string, std::function<void(const MultiFab&, MultiFab&)> > pops::AmrRuntimeBlock::named_elliptic_rhs |
Per-NAMED-field elliptic right-hand-side contributions of the block (ADC-428): field name -> closure rhs += elliptic_field_rhs_b(U_b) on the coarse, exactly like add_elliptic_rhs but for a SECOND (user-named) elliptic field declared by the block's model (m.elliptic_field).
The native loader attaches one closure here per declared field (set_block_elliptic_field). AmrRuntime sums them over the blocks into the named field's dedicated solver RHS (solve_named_fields). Empty for a block that declares no named field -> the named-field solve loop never reads it (bit-identical).
◆ ncomp
| int pops::AmrRuntimeBlock::ncomp = 1 |
◆ newton_diagnostics
| bool pops::AmrRuntimeBlock::newton_diagnostics = false |
NEWTON DIAGNOSTICS (OPT-IN, wave 3: AMR counterpart of System::newton_report).
false (default) -> imex_advance passes report=nullptr to backward_euler_source: FAST bit-identical path, no extra allocation or reduction. true -> imex_advance passes newton_report.get() (STABLE address since shared_ptr) to the backward_euler_source of EACH level; the report is AGGREGATED (max residual, max iterations, sum of failed cells, MPI all_reduce) over all levels AND all substeps of a macro-step. AmrRuntime::step RESETS the report at the head of the block advance (parity with System::AdvanceImex which resets at the head of operator()). MULTI-BLOCK native only (the single-block coupler and the .so loaders reject it at build / at the facade). STABLE address (shared_ptr): captured by the imex_advance closure AND read by AmrRuntime::newton_report.
◆ newton_report
| std::shared_ptr<NewtonReport> pops::AmrRuntimeBlock::newton_report |
◆ potential
| std::function<std::vector<double>(const MultiFab&)> pops::AmrRuntimeBlock::potential |
Coarse potential read from the shared aux (component 0) as an n*n row-major field (diagnostic).
Identical for all blocks (shared aux); carried per block for API symmetry.
◆ project_per_level
| std::function<void(std::vector<AmrLevelMP>&)> pops::AmrRuntimeBlock::project_per_level |
POINTWISE PROJECTION post-pas (ADC-177) : U <- project(U, aux) appliquee PAR NIVEAU a la FIN de l'avance complete du bloc (substeps + reflux/cascade faits).
Vide -> aucune projection (modele sans HasPointwiseProjection : trajectoire bit-identique). Locale par niveau (aucun collectif MPI). Cf. detail::apply_pointwise_project_amr, cable par build_amr_block.
◆ source_frequency
OPTIONAL STEP BOUNDS of the block (AMR StabilityPolicy, audit 2026-06): evaluated on the COARSE (level 0, where the AMR CFL lives – cf.
step_cfl: h = dx_coarse). EMPTY (default) -> step_cfl keeps the transport bound only, bit-identical. Filled by build_amr_block / build_amr_compiled when the model declares HasSourceFrequency / HasStabilityDt (same semantics as System: mu in 1/s -> dt <= cfl*substeps/(stride*mu), without h; direct admissible step -> dt <= dt_adm*substeps/stride, without cfl).
◆ stability_dt
◆ stride
| int pops::AmrRuntimeBlock::stride = 1 |
HOLD-THEN-CATCH-UP cadence of the block (multirate).
stride=1 (default): the block advances at EVERY macro-step (bit-identical). stride=M>1: the block is HELD at macro-steps 0..M-2 (not advanced) then CATCHES UP at macro-step M-1, where (macro_step+1)M==0, by an effective step M*dt. Same semantics as block_stride_v / AmrSystemCoupler::step (#140). The INVARIANT of the end-of-window catch-up: at macro-step k the system time is (k+1)*dt and the block that catches up has then accumulated (k+1)*dt, so it stays temporally CONSISTENT with the fast blocks (never "in the future"), which keeps the Poisson coupling (summed RHS) meaningful: a held block contributes with its FROZEN state (its last advance), not with an anticipated state that would falsify q_b n_b in the sum.
◆ substeps
| int pops::AmrRuntimeBlock::substeps = 1 |
EXPLICIT substeps of the block within ITS effective macro-step: the effective step (stride * dt) is split into substeps equal pieces and each piece is advanced by ONE advance_amr (cf.
AmrRuntime::step). substeps=1 => a single advance_amr over the whole effective step (bit-identical).
The documentation for this struct was generated from the following file:
- include/pops/runtime/amr/amr_runtime.hpp
Generated by