AmrSystem 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
|
Single block carried on an AMR hierarchy, composed at runtime. More...
#include <amr_system.hpp>
Collaboration diagram for pops::AmrSystem:Classes | |
| struct | SourceNewtonReport |
| Report of the implicit (IMEX) source Newton of a block, AGGREGATED over the levels and substeps of the block's LAST advance. More... | |
Public Member Functions | |||
| AmrSystem (const AmrSystemConfig &cfg) | |||
| ~AmrSystem () | |||
| AmrSystem (const AmrSystem &)=delete | |||
| AmrSystem & | operator= (const AmrSystem &)=delete | ||
| AmrSystem (AmrSystem &&) noexcept | |||
| AmrSystem & | operator= (AmrSystem &&) noexcept | ||
| void | add_dt_bound (const std::string &label, std::function< double()> fn) | ||
| GLOBAL time-step bound (AMR counterpart of System::add_dt_bound): fn() evaluated ONCE per step_cfl (host), all_reduce_min (identical dt on all ranks), <= 0 / non-finite = inert this step. | |||
| std::string | last_dt_bound () const | ||
| ACTIVE bound of the last step_cfl: "transport:<block>" | "source_frequency:<block>" | "stability_dt:<block>" | "global:<label>" | "degenerate" | "" (no CFL step yet). | |||
| void | add_block (const std::string &name, const ModelSpec &model, const std::string &limiter="minmod", const std::string &riemann="rusanov", const std::string &recon="conservative", const std::string &time="explicit", int substeps=1, int stride=1, const std::vector< std::string > &implicit_vars={}, const std::vector< std::string > &implicit_roles={}, const NewtonOptions &newton={}, bool newton_diagnostics=false, double positivity_floor=0.0) | ||
| Adds a block carried on the AMR. | |||
| SourceNewtonReport | newton_report (const std::string &name) | ||
| POPS_EXPORT void | set_compiled_block (int ncomp, double gamma, int substeps, std::function< AmrCompiledHooks(const AmrBuildParams &)> mono_builder, AmrCompiledBlockBuilder multi_builder={}, const std::string &name=std::string(), bool recon_prim=false, bool imex=false, int stride=1, const std::vector< std::string > &implicit_vars={}, const std::vector< std::string > &implicit_roles={}, double pos_floor=0.0) | ||
| Registers a COMPILED block (add_compiled_model path, header amr_dsl_block.hpp). | |||
| void | add_native_block (const std::string &name, const std::string &so_path, const std::string &limiter="minmod", const std::string &riemann="rusanov", const std::string &recon="conservative", const std::string &time="explicit", double gamma=1.4, int substeps=1, double positivity_floor=0.0) | ||
| Wires a NATIVE AMR block from a .so loader generated by the DSL (backend "production", target "amr_system": dsl.compile_native(target="amr_system") / compile(backend="production", target="amr_system")). | |||
| void | set_refinement (double threshold, const std::string &variable=std::string(), const std::string &role=std::string()) | ||
Refines the cells where the SELECTED conserved variable exceeds threshold. | |||
| void | set_phi_refinement (double grad_threshold) | ||
Adds to the regrid criterion the PHI tag on |grad phi| (D4 of the design docs/AMR_REGRID_UNION_TAGS_DESIGN.md): also refines the cells where the norm of the gradient of the electrostatic potential |grad phi| (components 1,2 of the shared aux) exceeds grad_threshold. | |||
| void | set_poisson (const std::string &rhs="charge_density", const std::string &solver="geometric_mg", const std::string &bc="auto", const std::string &wall="none", double wall_radius=0.0) | ||
| Configures the coarse Poisson (cf. | |||
| void | set_density (const std::string &name, const std::vector< double > &rho) | ||
| Sets the initial density on the coarse level (component 0), n*n row-major. | |||
| void | set_conservative_state (const std::string &name, const std::vector< double > &U) | ||
| Sets the FULL INITIAL CONSERVATIVE STATE (all components) on the coarse level, then prolongs it to the fine levels at build (constant injection, like the density). | |||
| void | set_magnetic_field (const std::vector< double > &bz) | ||
| Sets the magnetic field B_z(x, y) of the coarse level (n*n row-major), required by the Schur-condensed source stage (Lorentz term Omega = B_z). | |||
| void | set_aux_field_component (int comp, const std::vector< double > &field) | ||
Sets a model-NAMED aux field (ADC-291) at shared-channel component comp (>= kAuxNamedBase) from a coarse base-level field field (n*n row-major). | |||
| void | set_aux_field_halo_component (int comp, int bc_type, double value) | ||
Declares a per-field aux HALO policy (ADC-369) for the NAMED component comp (>= kAuxNamedBase): bc_type is pops::BCType (Foextrap=1 / Dirichlet=2), value the Dirichlet boundary value. | |||
| void | set_source_stage (const std::string &name, const std::string &kind, double theta, double alpha, const SourceStageOptions &opts={}) | ||
Enables the Schur-CONDENSED SOURCE STAGE (amr-schur path) on block name. | |||
| void | set_time_scheme (const std::string &scheme) | ||
| Chooses the time-splitting policy of the condensed source stage: "lie" (default, H(dt) S(dt)) or "strang" (H(dt/2) S(dt) H(dt/2), 2nd order). | |||
| void | add_coupled_source (const CoupledSourceProgram &prog, double frequency=0.0, const std::string &label="coupled_source") | ||
| Registers an inter-species COUPLED SOURCE (compiled pops.dsl.CoupledSource, flat bytecode ABI P5), refined counterpart of System::add_coupled_source but on the SHARED AMR hierarchy. | |||
| void | step (double dt) | ||
| one AMR macro-step (periodic regrid included) | |||
| void | advance (double dt, int nsteps) | ||
| double | step_cfl (double cfl) | ||
| Advances at dt = cfl * coarse_dx / max wave speed. | |||
| int | nx () const | ||
| double | time () const | ||
| int | macro_step () const | ||
| MACRO-STEP counter (0-indexed; incremented by step / advance / step_cfl), parity with System::macro_step. | |||
| void | set_clock (double t, int macro_step) | ||
| RESTORES the AMR clock (t, macro_step) – parity with System::set_clock. | |||
| int | n_blocks () const | ||
| number of blocks (1 = mono-block AmrCouplerMP; >= 2 = AmrRuntime) | |||
| std::vector< std::string > | block_names () const | ||
| Names of the blocks in add order (parity with System::block_names): the IO facade iterates over them to write EACH block by its name (an empty name -> block 0, historical mono-block compat). | |||
| int | n_patches () | ||
| number of current fine patches (of the shared hierarchy) | |||
| std::vector< PatchBox > | patch_boxes () | ||
| Index-space signatures of the current fine patches: one PatchBox (level, ilo, jlo, ihi, jhi) per fine box, for ALL fine levels (level >= 1). | |||
| int | coarse_local_boxes () | ||
| COARSE-level (base) box counts, MPI ownership diagnostic (ADC-319). | |||
| int | coarse_total_boxes () | ||
| int | n_levels () | ||
| AMR CHECKPOINT / RESTART (ADC-65 single-block single-rank; ADC-509 multi-block + np>1): per-level STATE accessors + hierarchy imposition for a BIT-IDENTICAL resumption (cf. | |||
| int | n_vars () | ||
| number of conserved components (MONO-BLOCK; multi-block: block_n_vars) | |||
| std::vector< double > | level_state (int k) | ||
FULL conservative state of level k, flat component-major c*nf*nf + j*nf + i (nf = n << k; zeros outside the patches at the fine level – only the patch interior is defined). | |||
| std::vector< double > | level_state_global (int k) | ||
| MONO-BLOCK, np>1 gather (all ranks call) | |||
| void | set_level_state (int k, const std::vector< double > &s) | ||
restores the state of level k (as is) | |||
| std::vector< double > | level_potential (int k) | ||
Potential phi of level k, flat nf*nf row-major. | |||
| std::vector< double > | level_potential_global (int k) | ||
| np>1 gather (all ranks call) | |||
| void | set_level_potential (int k, const std::vector< double > &p) | ||
restores phi of level k | |||
| void | set_hierarchy (const std::vector< PatchBox > &boxes) | ||
Imposes the SAVED fine hierarchy (at restart) instead of Berger-Rigoutsos clustering: boxes are the patch_boxes() signatures of the checkpoint (filtered to level 1 in mono-block). | |||
| int | block_n_vars (const std::string &name) | ||
| MULTI-BLOCK per-BLOCK per-level checkpoint accessors (ADC-509). | |||
| std::vector< double > | block_level_state (const std::string &name, int k) | ||
| std::vector< double > | block_level_state_global (const std::string &name, int k) | ||
| np>1 gather (all ranks call) | |||
| void | set_block_level_state (const std::string &name, int k, const std::vector< double > &s) | ||
| double | mass () | ||
| mass of the 1st block on the coarse (conserved at reflux) | |||
| double | mass (const std::string &name) | ||
| mass of the named block on the coarse (conserved PER BLOCK) | |||
| std::vector< double > | density () | ||
| coarse density of the 1st block (component 0), n*n row-major | |||
| std::vector< double > | density (const std::string &name) | ||
| coarse density of the named block, n*n | |||
| std::vector< double > | potential () | ||
| Electrostatic potential phi of the COARSE LEVEL (base), n*n row-major. | |||
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 System::register_elliptic_field / set_block_elliptic_field. The named field owns its RHS (a per-block brick), a DEDICATED coarse GeometricMG, and its OWN aux output components; AmrRuntime solves it each solve_fields and injects it to the fine levels, so a bare run() leaves it SOLVED. The default Poisson path is untouched / bit-identical. Registering a named field forces the MULTI-BLOCK runtime engine (AmrRuntime) even for a single block (the named-field solve lives there, not on the single-block AmrCouplerMP coupler). POPS_EXPORT: resolved by the generated AMR .so / native loader across the dlopen boundary, like set_compiled_block. Registers named
| |||
| POPS_EXPORT void | register_elliptic_field (const std::string &field, int phi_comp, int gx_comp, int gy_comp) | ||
| POPS_EXPORT void | set_block_elliptic_field (const std::string &block_name, const std::string &field, std::function< void(const MultiFab &, MultiFab &)> rhs) | ||
Attaches named field's RHS closure (rhs += elliptic_field_rhs(U)) to block block_name. | |||
| std::vector< double > | named_field_values (const std::string &field) | ||
Solved potential of named field on the COARSE level, n*n row-major (read-back). | |||
AMR / MPI profiling (Spec 5 sec.12.5, ADC-479 criterion 43) | |||
Per-phase wall-clock timing of the AMR runtime: the engine times its non-numeric phases – "regrid" (rebuild the patch hierarchy), "fill_boundary" (the cross-rank ghost halo exchange), "average_down" (restrict fine onto coarse) – plus integer counters ("regrid" / "fill_boundary" per-run counts, and under MPI np>1 "mpi_reductions" / "mpi_messages"). Disabled by default (no hot-path cost when off, parity with System). enable_profiling() then step()/step_cfl() over a run where a regrid fires (regrid_every set) then profile_report() returns the table; the typed PerformanceSummary.by_amr_mpi() view surfaces it. Per-rank (no cross-rank reduction of the report). Multi-block engine only (the runtime owns the union regrid + shared-aux halo). | |||
| void | enable_profiling () | ||
| void | disable_profiling () | ||
| bool | is_profiling () const | ||
| void | reset_profiling () | ||
| std::string | profile_report () const | ||
Detailed Description
Single block carried on an AMR hierarchy, composed at runtime.
Constructor & Destructor Documentation
◆ AmrSystem() [1/3]
|
explicit |
◆ ~AmrSystem()
| pops::AmrSystem::~AmrSystem | ( | ) |
◆ AmrSystem() [2/3]
|
delete |
◆ AmrSystem() [3/3]
|
noexcept |
Member Function Documentation
◆ add_block()
| void pops::AmrSystem::add_block | ( | const std::string & | name, |
| const ModelSpec & | model, | ||
| const std::string & | limiter = "minmod", |
||
| const std::string & | riemann = "rusanov", |
||
| const std::string & | recon = "conservative", |
||
| const std::string & | time = "explicit", |
||
| int | substeps = 1, |
||
| int | stride = 1, |
||
| const std::vector< std::string > & | implicit_vars = {}, |
||
| const std::vector< std::string > & | implicit_roles = {}, |
||
| const NewtonOptions & | newton = {}, |
||
| bool | newton_diagnostics = false, |
||
| double | positivity_floor = 0.0 |
||
| ) |
Adds a block carried on the AMR.
Same spatial-scheme parameters as System (limiter x riemann x recon), applied to each level/patch of the hierarchy. The FIRST add_block defines the block; a 2nd (or more) switches to the multi-block engine (shared hierarchy, co-located sum Poisson). Blocks can have DIFFERENT SPATIAL SCHEMES.
- Parameters
-
name block name: INDEXES the block (set_density(name), mass(name), density(name)). In multi-block the name must be unique; mono-block an empty name targets the single block. model composition of bricks (transport/source/elliptic + parameters) limiter "none" | "minmod" | "vanleer" | "weno5" (weno5 = WENO5-Z, 3 ghosts; rusanov) riemann "rusanov" | "hll" (generic signed-wave, requires model.wave_speeds) | "hllc" | "roe" (generic when the model supplies the Riemann capability HasHLLCStructure / HasRoeDissipation; else the canonical Euler 2D layout, 4 variables + pressure) time "explicit" (SSPRK2, forward-Euler source carried by the AMR step) | "ssprk3" (SSPRK3, order 3, reflux per stage; explicit transport, EXCLUSIVE of imex) | "imex" (stiff source handled IMPLICITLY by backward_euler_source; the transport stays explicit, carried by the conservative reflux; cf. capstone vii). Any other treatment is refused. substeps explicit substeps of the block (>= 1): the effective step is split into substeps equal pieces (MULTI-BLOCK only; in mono-block, carried by AmrCouplerMP). stride HOLD-THEN-CATCH-UP cadence of the block (>= 1; default 1 = each macro-step). stride=M holds the block M-1 macro-steps then catches it up by an effective step M*dt (multirate). MULTI-BLOCK only (a single block always advances every step). step_cfl honors the cadence: dt = cfl*h*min_b(substeps_b/(stride_b*w_b)), mirror of System::step_cfl. implicit_vars / implicit_roles partial IMEX mask CARRIED BY THE BLOCK (cf. System::add_block): conserved components handled IMPLICITLY, by NAME (implicit_vars) or by physical ROLE (implicit_roles). EMPTY (default) -> full backward-Euler (all components implicit). Only meaningful with time="imex": requesting them in explicit is an ERROR (no silent ignore). MULTI-BLOCK only (the mono-block AmrCouplerMP carries its IMEX without a mask; a mask there is therefore refused).
- Exceptions
-
std::runtime_error if a block is already defined, if substeps < 1, if stride < 1, if time is not in {explicit, ssprk3, imex}, if recon is not in {conservative, primitive}, or if an implicit mask is requested outside IMEX / with a name-role absent from the block.
- Parameters
-
newton options of the IMEX source Newton grouped in a POD (ADC-214; cf. NewtonOptions; parity with System::add_block): max_iters / rel_tol / abs_tol / fd_eps / damping / fail_policy. Default {} = historical constants, bit-identical. SUPPORT (wave 3, settled): these OPTIONS are wired in MONO-BLOCK (coupler AmrCouplerMP) AND in MULTI-BLOCK (AmrRuntime engine); the .so loaders reject them (flat ABI). fail_policy warn/throw works everywhere. newton_diagnostics aggregated Newton report (newton_report): wired in NATIVE MULTI-BLOCK only (the mono-block rejects it at build, the .so loaders at the facade). Stays flat (a separate bool, outside the homogeneous family of convergence options). positivity_floor Zhang-Shu positivity floor (ADC-259): if > 0, the AMR transport floors the Density-role face states (reconstruct_pp / zhang_shu_scale) AND the C/F fine ghost means to >= floor. Default 0 = inactive, bit-identical. Guarantee = face / ghost-state Density positivity only (order-1 fallback), NOT updated-mean nor pressure positivity (parity with System::add_block). A model without a Density role rejects floor > 0. The COMPILED .so path carries it too (ADC-322): a loader regenerated against this header marshals the floor (pops_install_native_amr).
◆ add_coupled_source()
| void pops::AmrSystem::add_coupled_source | ( | const CoupledSourceProgram & | prog, |
| double | frequency = 0.0, |
||
| const std::string & | label = "coupled_source" |
||
| ) |
Registers an inter-species COUPLED SOURCE (compiled pops.dsl.CoupledSource, flat bytecode ABI P5), refined counterpart of System::add_coupled_source but on the SHARED AMR hierarchy.
The source is applied at EACH macro-step AFTER the transport, by forward-Euler splitting, level by level, followed by a fine -> coarse cascade (consistency of the covered coarse cells, #169). The coupling is baked into a device-clean stack machine (CoupledSourceKernel): NO per-cell Python callback in the hot path. MULTI-BLOCK only (>= 2 add_block: the coupling reads/writes SEVERAL named blocks). Must be called BEFORE the first step (the runtime engine is built at lazy build; the source is injected into it).
CONSERVATION: an add_pair construction (a term +expr on a block, -expr exactly on the other, SAME cell) makes the sum of the two blocks conserved PER CELL (and globally) to machine precision. The engine does NOT IMPOSE it (an ionization creating an e/i pair is legal): it is a property of the constructed coupling (verify_conservation on the DSL side checks it symbolically).
- Exceptions
-
std::runtime_error if called in mono-block, if the system is already built, or if the shape of the bytecode / a role / a block is invalid (same guards as System).
- Parameters
-
prog bytecode description of the coupling grouped in a POD (ADC-214; cf. CoupledSourceProgram; parity with System::add_coupled_source): in_blocks / in_roles / consts / out_blocks / out_roles + prog_ops / prog_args / prog_lens (stack machine) + freq_prog_ops / freq_prog_args (PER-CELL frequency mu(U) optional; EMPTY = constant frequency only, bit-identical; non-empty: evaluated on the COARSE LEVEL of the input blocks at each step_cfl, MAX + all_reduce_max, bound dt <= cfl / max(mu) on the coarse, not the patches). frequency CONSTANT declared frequency mu [1/s] of the coupling (wave 3): bound dt <= cfl/mu on the macro-step of step_cfl; <= 0 (default) = no bound. label name of the coupling (reason "coupled_source:<label>" of last_dt_bound).
◆ add_dt_bound()
| void pops::AmrSystem::add_dt_bound | ( | const std::string & | label, |
| std::function< double()> | fn | ||
| ) |
GLOBAL time-step bound (AMR counterpart of System::add_dt_bound): fn() evaluated ONCE per step_cfl (host), all_reduce_min (identical dt on all ranks), <= 0 / non-finite = inert this step.
Hook for non-local constraints (coupling, scheduler, user ramp).
◆ add_native_block()
| void pops::AmrSystem::add_native_block | ( | const std::string & | name, |
| const std::string & | so_path, | ||
| const std::string & | limiter = "minmod", |
||
| const std::string & | riemann = "rusanov", |
||
| const std::string & | recon = "conservative", |
||
| const std::string & | time = "explicit", |
||
| double | gamma = 1.4, |
||
| int | substeps = 1, |
||
| double | positivity_floor = 0.0 |
||
| ) |
Wires a NATIVE AMR block from a .so loader generated by the DSL (backend "production", target "amr_system": dsl.compile_native(target="amr_system") / compile(backend="production", target="amr_system")).
AMR counterpart of System::add_native_block: the .so inlines the header template add_compiled_model(AmrSystem&, ...), which materializes a concrete AmrCouplerMP<Model> at lazy build and installs its hooks via set_compiled_block – NATIVE path, SAME AMR hierarchy as add_block (conservative reflux, regrid), no flat-array marshaling.
The _pops module is PROMOTED to global scope (RTLD_NOLOAD) then the loader is dlopen-ed in RTLD_GLOBAL to resolve set_compiled_block; the ABI key baked in the loader (pops_native_abi_key) is compared to the module's (abi_key()) – mismatch => clear error (no silent UB at the C++ boundary). Same scheme guard-rails as System (upstream validation).
MULTI-BLOCK (capstone v): add_native_block CAN now be called several times (or mixed with native add_block) -> the compiled blocks co-exist on the shared hierarchy via AmrRuntime (the loader recompiled against this header provides the runtime builder; cf. set_compiled_block). The name then INDEXES the block (set_density/mass/density), like add_block. time is wired to {explicit, imex} (imex = stiff implicit source via backward_euler_source; any other treatment is rejected by add_compiled_model). The multirate (stride) and the partial IMEX mask do NOT transit through the flat ABI of the loader (ABI unchanged): this .so path now REJECTS them at the Python facade level (AmrSystem.add_equation raises ValueError on stride>1 or a non-empty IMEX mask, rather than ignoring them silently). For these parameters, use native add_block (ModelSpec) or add_compiled_model(AmrSystem&) DIRECTLY (header), which expose stride and the mask. recon "primitive" and flux "roe"/"hllc" are WIRED at parity (#113: dispatch_amr_compiled accepts them; the Python facade applies a pressure guard for hllc/roe). limiter "weno5" (WENO5-Z, 3 ghosts) is WIRED on rusanov (#105: the coupler levels are allocated to Limiter::n_ghost and the regrid inherits n_grow(): no out-of-bounds read).
- Exceptions
-
std::runtime_error if the ABI diverges, if a symbol is missing, or substeps < 1.
- Parameters
-
name block name: cosmetic in mono-block, INDEXES the block in multi-block (set_density/ mass/density; must be unique and non-empty from the 2nd block on, like add_block). positivity_floor Zhang-Shu positivity floor of the block (ADC-322): the .so flat ABI now carries it (pops_install_native_amr -> add_compiled_model -> set_compiled_block), so a loader regenerated against this header floors the Density-role face states like a native add_block. 0 (default) = inactive, bit-identical.
◆ advance()
| void pops::AmrSystem::advance | ( | double | dt, |
| int | nsteps | ||
| ) |
◆ block_level_state()
| std::vector< double > pops::AmrSystem::block_level_state | ( | const std::string & | name, |
| int | k | ||
| ) |
◆ block_level_state_global()
| std::vector< double > pops::AmrSystem::block_level_state_global | ( | const std::string & | name, |
| int | k | ||
| ) |
np>1 gather (all ranks call)
◆ block_n_vars()
| int pops::AmrSystem::block_n_vars | ( | const std::string & | name | ) |
MULTI-BLOCK per-BLOCK per-level checkpoint accessors (ADC-509).
The AmrRuntime engine shares the layout AND the aux across blocks, so the per-level STATE is read/restored PER BLOCK (by NAME) while phi stays shared (level_potential above). name indexes the block (block_names()); k: level. The _global variant all_reduce_sum the per-rank fabs (np>1 gather, all ranks call); the shared hierarchy is the deterministic frozen central patch (regrid_every==0), reproduced at restart by replaying the same composition -> no set_hierarchy needed.
- Exceptions
-
in MONO-BLOCK (use the level_state path) or if name/kis out of bounds. conserved components of the named block
◆ block_names()
| std::vector< std::string > pops::AmrSystem::block_names | ( | ) | const |
Names of the blocks in add order (parity with System::block_names): the IO facade iterates over them to write EACH block by its name (an empty name -> block 0, historical mono-block compat).
◆ coarse_local_boxes()
| int pops::AmrSystem::coarse_local_boxes | ( | ) |
COARSE-level (base) box counts, MPI ownership diagnostic (ADC-319).
coarse_local_boxes() = number of base boxes OWNED by this rank (level-0 MultiFab local_size()); coarse_total_boxes() = total base boxes across all ranks (BoxArray size, identical on every rank). With distribute_coarse=true the base is split into several boxes spread round-robin, so local < total per rank and the coarse transport distributes (MPI strong-scaling); a single-box or replicated base gives local == total on every rank. coarse_local_boxes() is rank-dependent, coarse_total_boxes() is rank-independent. Forces the lazy build (ensure_built) like n_patches()/mass()/density().
◆ coarse_total_boxes()
| int pops::AmrSystem::coarse_total_boxes | ( | ) |
◆ density() [1/2]
| std::vector< double > pops::AmrSystem::density | ( | ) |
coarse density of the 1st block (component 0), n*n row-major
◆ density() [2/2]
| std::vector< double > pops::AmrSystem::density | ( | const std::string & | name | ) |
coarse density of the named block, n*n
◆ disable_profiling()
| void pops::AmrSystem::disable_profiling | ( | ) |
◆ enable_profiling()
| void pops::AmrSystem::enable_profiling | ( | ) |
◆ is_profiling()
| bool pops::AmrSystem::is_profiling | ( | ) | const |
◆ last_dt_bound()
| std::string pops::AmrSystem::last_dt_bound | ( | ) | const |
ACTIVE bound of the last step_cfl: "transport:<block>" | "source_frequency:<block>" | "stability_dt:<block>" | "global:<label>" | "degenerate" | "" (no CFL step yet).
◆ level_potential()
| std::vector< double > pops::AmrSystem::level_potential | ( | int | k | ) |
Potential phi of level k, flat nf*nf row-major.
Level 0 = warm-start of the multigrid (bit-identical resumption); level >= 1 = aux comp 0 (recomputed at update). SHARED -> works in MONO-BLOCK as well as MULTI-BLOCK (single aux). The _global variant gathers under np>1.
◆ level_potential_global()
| std::vector< double > pops::AmrSystem::level_potential_global | ( | int | k | ) |
np>1 gather (all ranks call)
◆ level_state()
| std::vector< double > pops::AmrSystem::level_state | ( | int | k | ) |
FULL conservative state of level k, flat component-major c*nf*nf + j*nf + i (nf = n << k; zeros outside the patches at the fine level – only the patch interior is defined).
MONO-BLOCK.
◆ level_state_global()
| std::vector< double > pops::AmrSystem::level_state_global | ( | int | k | ) |
MONO-BLOCK, np>1 gather (all ranks call)
◆ macro_step()
| int pops::AmrSystem::macro_step | ( | ) | const |
MACRO-STEP counter (0-indexed; incremented by step / advance / step_cfl), parity with System::macro_step.
Required for checkpoint/restart (the stride / regrid cadence depends on macro_step % stride|regrid_every, not only on t). Prerequisite IO PR-IO-3 (audit 2026-06).
◆ mass() [1/2]
| double pops::AmrSystem::mass | ( | ) |
mass of the 1st block on the coarse (conserved at reflux)
◆ mass() [2/2]
| double pops::AmrSystem::mass | ( | const std::string & | name | ) |
mass of the named block on the coarse (conserved PER BLOCK)
◆ n_blocks()
| int pops::AmrSystem::n_blocks | ( | ) | const |
number of blocks (1 = mono-block AmrCouplerMP; >= 2 = AmrRuntime)
◆ n_levels()
| int pops::AmrSystem::n_levels | ( | ) |
AMR CHECKPOINT / RESTART (ADC-65 single-block single-rank; ADC-509 multi-block + np>1): per-level STATE accessors + hierarchy imposition for a BIT-IDENTICAL resumption (cf.
AmrSystem.checkpoint/restart on the Python side). MONO-BLOCK uses these (level_state / level_potential / set_hierarchy on the AmrCouplerMP coupler); MULTI-BLOCK (AmrRuntime engine, SHARED layout + aux) uses the per-BLOCK variants below (block_level_state ...), plus the SHARED level_potential / n_levels (no set_hierarchy: the shared hierarchy is the deterministic frozen central patch, reproduced by replaying the same composition). The _global variants all_reduce_sum the per-rank fabs so a np>1 checkpoint gathers onto rank 0 (mono-rank: identity, bit-identical). Force the lazy build (ensure_built) like patch_boxes()/mass(). k: level (0 = coarse, >= 1 = fine). number of levels of the hierarchy (>= 1; mono OR multi-block)
◆ n_patches()
| int pops::AmrSystem::n_patches | ( | ) |
number of current fine patches (of the shared hierarchy)
◆ n_vars()
| int pops::AmrSystem::n_vars | ( | ) |
number of conserved components (MONO-BLOCK; multi-block: block_n_vars)
◆ named_field_values()
| std::vector< double > pops::AmrSystem::named_field_values | ( | const std::string & | field | ) |
Solved potential of named field on the COARSE level, n*n row-major (read-back).
Solves the hierarchy fields if needed (so it is current even before any step), then reads the field's phi component. AMR counterpart of System::aux_field_component for a named elliptic field.
- Exceptions
-
if the field is unregistered (or in the single-block AmrCouplerMP path, which carries no named field).
◆ newton_report()
| SourceNewtonReport pops::AmrSystem::newton_report | ( | const std::string & | name | ) |
- Exceptions
-
std::runtime_error if the block is unknown, in mono-block, on a .so loader, or if the block did not enable newton_diagnostics. Forces the lazy build (ensure_built).
◆ nx()
| int pops::AmrSystem::nx | ( | ) | const |
◆ operator=() [1/2]
◆ operator=() [2/2]
◆ patch_boxes()
| std::vector< PatchBox > pops::AmrSystem::patch_boxes | ( | ) |
Index-space signatures of the current fine patches: one PatchBox (level, ilo, jlo, ihi, jhi) per fine box, for ALL fine levels (level >= 1).
INCLUSIVE corners in the index space of the level (n << level cells/direction, ratio 2). SAME source as n_patches() (the GLOBAL fine BoxArray, all boxes/all ranks -> rank-independent, MPI-safe, zero communication). It is a QUERY (between steps): read-only of the already-stored boxes, NO hot-path cost. The conversion to [0, L]^2 is done on the Python side (which knows n via nx() and L). Forces the lazy build (ensure_built) like n_patches()/mass()/density().
◆ potential()
| std::vector< double > pops::AmrSystem::potential | ( | ) |
Electrostatic potential phi of the COARSE LEVEL (base), n*n row-major.
Level 0 covers the whole domain: enough to sample a median circle (azimuthal FFT), SAME observable as System::potential() on a single-level mesh. Solves the coarse Poisson if needed (cf. System::potential / ensure_elliptic), so current value even before any step. MULTI-BLOCK: phi results from the SYSTEM Poisson (Sum_b q_b n_b co-located); shared by all the blocks (single aux). The block name therefore does not intervene.
◆ profile_report()
| std::string pops::AmrSystem::profile_report | ( | ) | const |
◆ register_elliptic_field()
| POPS_EXPORT void pops::AmrSystem::register_elliptic_field | ( | const std::string & | field, |
| int | phi_comp, | ||
| int | gx_comp, | ||
| int | gy_comp | ||
| ) |
◆ reset_profiling()
| void pops::AmrSystem::reset_profiling | ( | ) |
◆ set_aux_field_component()
| void pops::AmrSystem::set_aux_field_component | ( | int | comp, |
| const std::vector< double > & | field | ||
| ) |
Sets a model-NAMED aux field (ADC-291) at shared-channel component comp (>= kAuxNamedBase) from a coarse base-level field field (n*n row-major).
AMR counterpart of System::set_aux_field_component: the field is STATIC (re-applied by the engine each update, so it survives a regrid) and reaches every level via the coarse->fine aux injection. Works on the single-block (AmrCouplerMP) AND multi-block (AmrRuntime) paths. The Python facade resolves the name to comp and reshapes the array. Mono-rank facade (same as set_density).
- Exceptions
-
if the system is already built, if compis reserved (< kAuxNamedBase), or iffieldis not of size n*n.
◆ set_aux_field_halo_component()
| void pops::AmrSystem::set_aux_field_halo_component | ( | int | comp, |
| int | bc_type, | ||
| double | value | ||
| ) |
Declares a per-field aux HALO policy (ADC-369) for the NAMED component comp (>= kAuxNamedBase): bc_type is pops::BCType (Foextrap=1 / Dirichlet=2), value the Dirichlet boundary value.
Seeded onto the engine at build and applied after the shared coarse aux fill (overriding only that component's physical-face ghosts; periodic faces keep their wrap). AMR counterpart of System::set_aux_field_halo_component.
- Exceptions
-
on a reserved component or an unsupported type.
◆ set_block_elliptic_field()
| POPS_EXPORT void pops::AmrSystem::set_block_elliptic_field | ( | const std::string & | block_name, |
| const std::string & | field, | ||
| std::function< void(const MultiFab &, MultiFab &)> | rhs | ||
| ) |
Attaches named field's RHS closure (rhs += elliptic_field_rhs(U)) to block block_name.
Called by the native AMR loader (make_poisson_rhs of the per-field brick).
- Exceptions
-
if the system is already built or the block is unknown.
◆ set_block_level_state()
| void pops::AmrSystem::set_block_level_state | ( | const std::string & | name, |
| int | k, | ||
| const std::vector< double > & | s | ||
| ) |
◆ set_clock()
| void pops::AmrSystem::set_clock | ( | double | t, |
| int | macro_step | ||
| ) |
RESTORES the AMR clock (t, macro_step) – parity with System::set_clock.
Sets the time AND the macro-step counter (propagated to the regrid/stride cadence of the engine, mono-block as well as multi-block). Useful alone (stride cadence + clock resumption).
- Exceptions
-
if macro_step < 0.
◆ set_compiled_block()
| POPS_EXPORT void pops::AmrSystem::set_compiled_block | ( | int | ncomp, |
| double | gamma, | ||
| int | substeps, | ||
| std::function< AmrCompiledHooks(const AmrBuildParams &)> | mono_builder, | ||
| AmrCompiledBlockBuilder | multi_builder = {}, |
||
| const std::string & | name = std::string(), |
||
| bool | recon_prim = false, |
||
| bool | imex = false, |
||
| int | stride = 1, |
||
| const std::vector< std::string > & | implicit_vars = {}, |
||
| const std::vector< std::string > & | implicit_roles = {}, |
||
| double | pos_floor = 0.0 |
||
| ) |
Registers a COMPILED block (add_compiled_model path, header amr_dsl_block.hpp).
TWO type-erased builders are frozen here, for the TWO routings of the facade:
mono_builder:given the AmrBuildParams frozen at lazy build, returns the AmrCompiledHooks of a concrete AmrCouplerMP<Model>. Used IN MONO-BLOCK (1 single compiled block) -> historical AmrCouplerMP path, UNTOUCHED, bit-identical.multi_builder:given the SHARED layout materialized at lazy build (common to all blocks), returns the type-erased AmrRuntimeBlock of the block. Used IN MULTI-BLOCK (>= 2 blocks, compiled and/or native mixed) -> AmrRuntime runtime engine, exactly like add_block.recon_prim/imex/stride/implicit_vars/implicit_roles:metadata of the block (temporal scheme, multirate, partial IMEX mask) frozen at add time, consumed by the multi-block routing (the mono-block already carries them in the AmrBuildParams via mono_builder). DO NOT call directly: go through the free function add_compiled_model(AmrSystem&, ...).- Exceptions
-
std::runtime_error if the system is already built. DEFAULT VISIBILITY (POPS_EXPORT): the ONLY method called by the header template add_compiled_model(AmrSystem&) (cf. amr_dsl_block.hpp). A generated .so loader (DSL "production" path on the AMR side, emit_cpp_native_loader(target="amr_system") / add_native_block) inlines this template and must resolve this symbol from the already-loaded _pops module; compiled with -fvisibility=hidden (pybind11), the module would not export it without this annotation and the dlopen of the loader would fail. Symmetric with the POPS_EXPORT methods of System (grid_context/install_block).
◆ set_conservative_state()
| void pops::AmrSystem::set_conservative_state | ( | const std::string & | name, |
| const std::vector< double > & | U | ||
| ) |
Sets the FULL INITIAL CONSERVATIVE STATE (all components) on the coarse level, then prolongs it to the fine levels at build (constant injection, like the density).
U is flat component-major (c*n*n + j*n + i) of size ncomp*n*n; ncomp == n_vars of the model (checked at build, where only Model::n_vars is known). Takes priority over set_density: allows starting the AMR from a full drift state (rho, rho*u, rho*v) instead of m=0. The conversion primitive -> conservative (rho_u = rho*u) is done on the Python side (the caller already supplies the conservative). Wired on the NATIVE blocks (mono-block as well as multi-block: threaded to the native builder, seed the coarse then inject to the fine); in multi-block name indexes the target block. A COMPILED (.so) block carrying a state raises at build in multi-block (the .so loader does not transport the state): use a native block pops.Model(...) or set_density.
- Exceptions
-
std::runtime_error if the system is already built, if U is empty, or if its size is not a multiple of n*n.
◆ set_density()
| void pops::AmrSystem::set_density | ( | const std::string & | name, |
| const std::vector< double > & | rho | ||
| ) |
Sets the initial density on the coarse level (component 0), n*n row-major.
- Parameters
-
name cosmetic label (mono-block AMR: the density targets the single block).
◆ set_hierarchy()
| void pops::AmrSystem::set_hierarchy | ( | const std::vector< PatchBox > & | boxes | ) |
Imposes the SAVED fine hierarchy (at restart) instead of Berger-Rigoutsos clustering: boxes are the patch_boxes() signatures of the checkpoint (filtered to level 1 in mono-block).
MONO-BLOCK.
◆ set_level_potential()
| void pops::AmrSystem::set_level_potential | ( | int | k, |
| const std::vector< double > & | p | ||
| ) |
restores phi of level k
◆ set_level_state()
| void pops::AmrSystem::set_level_state | ( | int | k, |
| const std::vector< double > & | s | ||
| ) |
restores the state of level k (as is)
◆ set_magnetic_field()
| void pops::AmrSystem::set_magnetic_field | ( | const std::vector< double > & | bz | ) |
Sets the magnetic field B_z(x, y) of the coarse level (n*n row-major), required by the Schur-condensed source stage (Lorentz term Omega = B_z).
AMR counterpart of System::set_magnetic_field. MONO-BLOCK only (the condensed AMR stage is wired on the mono-block coupler AmrCouplerMP).
- Exceptions
-
std::runtime_error if the system is already built or if bz is not of size n*n.
◆ set_phi_refinement()
| void pops::AmrSystem::set_phi_refinement | ( | double | grad_threshold | ) |
Adds to the regrid criterion the PHI tag on |grad phi| (D4 of the design docs/AMR_REGRID_UNION_TAGS_DESIGN.md): also refines the cells where the norm of the gradient of the electrostatic potential |grad phi| (components 1,2 of the shared aux) exceeds grad_threshold.
MULTI-BLOCK only (the AmrRuntime runtime engine carries the union-of-tags regrid; the mono-block path AmrCouplerMP has no separate phi predicate). The phi tag is ADDED to the union of the density tags per block (set_refinement): the mesh refines where ANY block exceeds its density threshold OR |grad phi| exceeds grad_threshold. PHYSICAL criterion: a sharp ring/edge feature follows the gradient of the potential, not the density alone.
- Parameters
-
grad_threshold threshold of |grad phi|. <= 0 (DEFAULT) -> the phi tag is DISABLED (phi does not contribute to the union; bit-identical to before this call). Without regrid_every > 0, no effect (the regrid is never called). To be called BEFORE the first step.
◆ set_poisson()
| void pops::AmrSystem::set_poisson | ( | const std::string & | rhs = "charge_density", |
| const std::string & | solver = "geometric_mg", |
||
| const std::string & | bc = "auto", |
||
| const std::string & | wall = "none", |
||
| double | wall_radius = 0.0 |
||
| ) |
Configures the coarse Poisson (cf.
System::set_poisson). On AMR the elliptic solver is ALWAYS GeometricMG and the right-hand side ALWAYS f = sum of the block's elliptic bricks.
- Parameters
-
rhs "charge_density" | "composite" (same composed right-hand side as System) solver "geometric_mg" only (the only one wired on the hierarchy; no FFT) bc "auto" | "periodic" | "dirichlet" | "neumann" wall "none" | "circle" (circular conductive wall, requires wall_radius > 0)
- Exceptions
-
std::runtime_error if rhs, solver, bc or wall is outside the supported domain.
◆ set_refinement()
| void pops::AmrSystem::set_refinement | ( | double | threshold, |
| const std::string & | variable = std::string(), |
||
| const std::string & | role = std::string() |
||
| ) |
Refines the cells where the SELECTED conserved variable exceeds threshold.
By default the variable is component 0 (historically the density), preserving the bit-identical 1e30 no-op. Optionally the variable is selected PER BLOCK by NAME (variable, e.g. "E") or by physical ROLE (role, e.g. "energy"): each block resolves it against its OWN conservative VariableSet, so a model whose refinement variable is NOT at component 0 refines correctly (ADC-296). Resolution is STRICT – a block lacking the requested name/role raises an explicit error at build, never a silent fallback to component 0 (mirror of add_coupled_source). At most one of variable / role may be set. MULTI-BLOCK only for a non-default selector (the AmrRuntime union-of-tags regrid carries the per-block predicates); the mono-block AmrCouplerMP path and the compiled .so loader refine on component 0 only and reject a non-empty selector, mirroring how set_phi_refinement is multi-block only.
- Parameters
-
threshold refinement threshold ( 1e30default elsewhere => no refinement, frozen).variable conserved-variable NAME to threshold; empty (default) => component 0. role conserved-variable physical ROLE to threshold; empty (default) => component 0.
◆ set_source_stage()
| void pops::AmrSystem::set_source_stage | ( | const std::string & | name, |
| const std::string & | kind, | ||
| double | theta, | ||
| double | alpha, | ||
| const SourceStageOptions & | opts = {} |
||
| ) |
Enables the Schur-CONDENSED SOURCE STAGE (amr-schur path) on block name.
AMR counterpart of System::set_source_stage: assembles and solves the GLOBAL electrostatic/Lorentz condensed operator (on the coarse, by composing the uniform stage #126), instead of the LOCAL cell-by-cell IMEX source. This is the OPT-IN of the amr-schur path, the refined equivalent of the uniform time=Strang(Explicit(ssprk3), CondensedSchur(theta, alpha)). The block transport must be SOURCE-FREE (model with NoSource source brick): the source is played separately by the stage.
- Parameters
-
kind only "electrostatic_lorentz" wired (cf. CondensedSchurSourceStepper). theta theta-scheme in (0, 1] (0.5 = Crank-Nicolson). alpha electrostatic coupling constant.
- Exceptions
-
std::runtime_error if the system is already built, in MULTI-BLOCK, if kind/theta are out of domain, or (at build) if the block does not expose Density/MomentumX/MomentumY or if set_magnetic_field was not called.
- Parameters
-
opts settings grouped in a POD (ADC-214; cf. SourceStageOptions; parity with System::set_source_stage): krylov_tol / krylov_max_iters (COARSE Krylov solve; <= 0 = historical defaults 1e-10 / 400; the FAC composite solve keeps its own tolerances, Phase 4) and descriptors density / momentum_x / momentum_y / energy ("" = canonical role, bit-identical; otherwise stable role name or block variable name, resolved at build). The POD's bz_aux_component field is IGNORED here (the mono-block AMR stage reads the canonical B_z channel). Default {} = historical behavior.
◆ set_time_scheme()
| void pops::AmrSystem::set_time_scheme | ( | const std::string & | scheme | ) |
Chooses the time-splitting policy of the condensed source stage: "lie" (default, H(dt) S(dt)) or "strang" (H(dt/2) S(dt) H(dt/2), 2nd order).
AMR counterpart of System::set_time_scheme. Without a condensed source stage (set_source_stage not called), no effect.
- Exceptions
-
if scheme unknown / already built.
◆ step()
| void pops::AmrSystem::step | ( | double | dt | ) |
one AMR macro-step (periodic regrid included)
◆ step_cfl()
| double pops::AmrSystem::step_cfl | ( | double | cfl | ) |
Advances at dt = cfl * coarse_dx / max wave speed.
- Returns
- the dt used.
◆ time()
| double pops::AmrSystem::time | ( | ) | const |
The documentation for this class was generated from the following file:
- include/pops/runtime/amr_system.hpp
Generated by