include/pops/runtime/system/system_field_solver.hpp Source FileΒΆ
|
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
|
system_field_solver.hpp
Go to the documentation of this file.
11#include <pops/numerics/elliptic/polar/polar_poisson_solver.hpp> // PolarPoissonSolver (direct polar Poisson)
13#include <pops/runtime/builders/block/block_builder_polar.hpp> // derive_aux_polar (polar aux in local basis)
16#include <cstdio> // POPS_TRACE_SOLVE_FIELDS: device diagnostic trace (env-gated, inert by default)
115 // ABSOLUTE floor of the GeometricMG V-cycle stopping criterion (same units as the residual). Default 0:
117 // it makes the off-step solve_fields exit WITHOUT cycling on an already converged state (diagnostics, oracles,
123 false; // ANISOTROPIC permittivity eps_x(x), eps_y(x) (operator div(diag(eps_x,eps_y) grad phi))
128 bool has_kappa_field_ = false; // REACTION term kappa(x) provided: div(eps grad phi) - kappa phi
133 // Poisson; it only DERIVES the aux (phi, grad phi) from the CURRENT phi -- the one that the condensed
136 // INERT without a Schur stage (phi would stay frozen after t=0). The lock gauss_solved_once_ guarantees that
142 // polar_ (cf. ensure_elliptic_polar). SEPARATE from ell_ (geom() returns a PolarGeometry, not a
145 // phi buffer of the POLAR condensed SOURCE STAGE (Path A step 2c). The direct PolarPoissonSolver
146 // (pell_->phi()) is WITHOUT ghost (valid box = allocation); but the PolarCondensedSchurSourceStepper
149 // solve_fields_polar) before the source stage, which carries phi^{n+1} on output (warm start of the next
156 // canonical component (>= kAuxNamedBase = 5), value = field n*n (cartesian) / nr*ntheta (polar)
159 // REALLOCATION of the aux channel (ensure_aux_width) starts again from a zeroed MultiFab -> we re-apply
162 // Per-field aux HALO policy (ADC-369): key = canonical component (>= kAuxNamedBase), value = the
163 // uniform boundary policy declared via pops.AuxHalo. Applied by apply_named_aux_bc() AFTER the shared
164 // aux ghost fill, overriding only that component's PHYSICAL-face ghosts (periodic faces -- Cartesian
165 // periodic, polar theta -- keep their wrap). Empty -> shared aux BC for every field, bit-identical.
168 // NAMED multi-elliptic fields (ADC-428): a SECOND elliptic solve (beyond the default Poisson) for a
170 // - phi_comp / gx_comp / gy_comp: the aux channel components (>= kAuxNamedBase) its solution and
172 // reads them like any other named aux). gx_comp / gy_comp < 0 => the field declares fewer than 3
174 // - a DEDICATED elliptic solver instance (cartesian GeometricMG / FFT), built lazily the SAME way
175 // as the default ell_ (ensure_named_elliptic mirrors ensure_elliptic's poisson operator), so the
177 // The RHS = sum over blocks of s.named_poisson_rhs[name] (the per-field brick, ADC-428), assembled
325 // of this composite right-hand side. "composite" names this behavior honestly; "charge_density"
336 // deadlock), so only the pure periodic constant-coefficient case reaches the layout switch below.
354 // references, e.g. poisson_fft.m of RIEMOM2D); 'fft' keeps the discrete stencil (bit-identical).
359 // dereference a nonexistent fab(0) on a rank without a box (SIGSEGV). RemappedFFTSolver presents
361 // hides a scatter/gather around PoissonFFT inside solve() -> the field-solve path is untouched.
362 // COLLECTIVE: every rank constructs the same type; its Ny % n_ranks() guard throws on all ranks
363 // (no deadlock). NOTE: pending the ADC-273 design vote (structural change to the ell_ variant).
502 // --- ELLIPTIC-SOLVER PROFILING COUNTERS (Spec 5 sec.13.11.1, ADC-479 criteria 42/43) ----------
503 // Read-back accessors for the per-solve stats of the ACTIVE cartesian elliptic solver, queried at
504 // the System solve_fields seam AFTER ell_solve()+device_fence() to populate the native profiler
505 // counters (mg_cycles / krylov_iters / mg_levels / elliptic_bottom). LOW-INVASIVE by design: the
506 // deep numerics never sees the profiler -- GeometricMG caches the stats per solve (chrono only) and
510 // krylov_iters is 0 on the cartesian field-solve path: the default Poisson uses GeometricMG (or a
511 // direct FFT), never a Krylov solver (the Krylov path lives in the condensed Schur SOURCE stage,
512 // which is not the ell_ elliptic solve). The counter is emitted for completeness / future Krylov
581 // ba.size()!=1). We raise a clear UPSTREAM message HERE -- before the construction of the solver, so from the
582 // 1st solve_fields / potential / set_potential of a System with theta_boxes > 1 -- rather than letting
665 // Derivation (phi, grad_r, grad_theta) in the local basis (e_r, e_theta) via the SAME helper as the C++
666 // test (derive_aux_polar of block_builder_polar.hpp). phi is WITHOUT ghost (direct single-box solver):
667 // the helper thus never reads an out-of-domain index (radial OFFSET at the walls, theta WRAPPED in
668 // periodic) -- that was the bug: the centered difference read phi(lo-1)/phi(hi+1)/phi(.,jlo-1) out of
672 // Aux ghosts: theta PERIODIC (joint 0/2pi), r PHYSICAL (extrapolation at the boundary). fill_ghosts
673 // already routes through bc_ (xlo/xhi Foextrap, ylo/yhi Periodic) -> correct periodic azimuthal halo.
675 apply_named_aux_bc(); // ADC-369: per-field halo override on the RADIAL faces (theta stays periodic)
699 // Schur source stage evolves in-place), giving a restart-free -Delta phi evolution (Gauss imposed only at t=0).
704 // target_block / U_stage override the target block reads U_stage (per-stage field solve, ADC-409).
730 // distributes ONE box (round-robin DistributionMapping(1, n_ranks())), so at np>1 a single rank
731 // owns it; the others have local_size()==0 and HAVE NO fab to derive. We iterate over the LOCAL
748 apply_te(); // T_e = p/rho of the fluid block source, recomputed on each solve (B_z, comp 3, preserved)
755 apply_named_aux_bc(); // ADC-369: per-field halo override (after the shared fill; no-op if none)
944 // CONSTANT permittivity eps != 1: lap phi = f/eps (1/eps scaling), like the default Poisson. The
958 device_fence(); // CRITICAL: the V-cycle must finish before phi is read (same invariant as ell_)
977 // Ghost-fill the named field's aux components: the shared aux fill (same routing as solve_fields)
978 // then the per-field halo override (ADC-369). This re-fills ALL components -- the shared phi/grad
POLAR counterpart of block_builder.hpp: builds a block's closures (time advance + residual + Poisson ...
Box2D: the integer index space of a 2D cell-centered Cartesian grid.
ConstArray4 const_array() const
READ handle (POD device-copyable) over this Fab. Valid as long as the Fab lives.
Definition fab2d.hpp:96
Array4 array()
WRITE handle (POD device-copyable) over this Fab. Valid as long as the Fab lives.
Definition fab2d.hpp:91
Definition geometric_mg.hpp:79
void set_epsilon(std::function< Real(Real, Real)> eps_fn)
Definition geometric_mg.hpp:249
void set_reaction(std::function< Real(Real, Real)> kappa_fn)
Definition geometric_mg.hpp:304
void set_epsilon_anisotropic(std::function< Real(Real, Real)> eps_x_fn, std::function< Real(Real, Real)> eps_y_fn)
Definition geometric_mg.hpp:274
Field distributed over a level: decomposition (BoxArray) + distribution (DistributionMapping) + ncomp...
Definition multifab.hpp:33
Fab2D & fab(int li)
Local fab at index li (0 <= li < local_size()), for writing.
Definition multifab.hpp:67
const Box2D & box(int li) const
VALID box of local fab li.
Definition multifab.hpp:71
void set_val(Real v)
Fills all cells (valid + ghosts) of every local fab with v.
Definition multifab.hpp:85
int local_size() const
Number of fabs OWNED by this rank (bound on local indices).
Definition multifab.hpp:65
SystemFieldSolver<Impl>: see contract above.
Definition system_field_solver.hpp:83
void solve_fields(int target_block=-1, const MultiFab *U_stage=nullptr)
Solves the system Poisson then DERIVES the aux = (phi, grad phi[, B_z, T_e]).
Definition system_field_solver.hpp:689
bool has_kappa_field_
Definition system_field_solver.hpp:128
BCRec poisson_bc()
Resolves the BC mode into a BCRec: "auto" -> dirichlet if wall/non-periodic, otherwise periodic; "per...
Definition system_field_solver.hpp:292
bool has_eps_xy_field_
Definition system_field_solver.hpp:122
std::vector< double > p_eps_x_field_
Definition system_field_solver.hpp:125
void solve_fields_from_blocks(const std::vector< const MultiFab * > &U_stages)
Coupled multi-block field solve (Spec 3 criterion 24, ADC-457): SAME elliptic solve + aux derivation ...
Definition system_field_solver.hpp:813
std::optional< std::variant< GeometricMG, PoissonFFTSolver, RemappedFFTSolver > > ell_
Definition system_field_solver.hpp:140
std::optional< MultiFab > phi_src_polar_
Definition system_field_solver.hpp:152
bool has_eps_field_
Definition system_field_solver.hpp:120
std::string p_wall
Definition system_field_solver.hpp:112
void solve_fields_from_state(int block_idx, const MultiFab &U_stage)
Per-stage field solve (ADC-409): SAME solve + derive-aux as solve_fields(), but the target block bloc...
Definition system_field_solver.hpp:767
double p_wall_radius
Definition system_field_solver.hpp:113
void apply_te()
Populates the T_e component (electron temperature) = p/rho of the fluid block source te_src_.
Definition system_field_solver.hpp:240
void apply_bz()
Populates the B_z component (index kAuxBaseComps) of the shared channel from bz_field_,...
Definition system_field_solver.hpp:217
MultiFab & ell_phi()
Potential phi read (and rewritten) by the condensed source stage.
Definition system_field_solver.hpp:468
std::vector< double > p_eps_y_field_
Definition system_field_solver.hpp:127
void ensure_elliptic_polar()
Builds the direct POLAR Poisson (PolarPoissonSolver, single-rank, single box covering the ring) LAZIL...
Definition system_field_solver.hpp:564
SystemFieldSolver(Impl *owner)
Definition system_field_solver.hpp:86
void ell_solve()
Solves the active cartesian Poisson (GeometricMG V-cycle or direct FFT).
Definition system_field_solver.hpp:487
void register_named_field(const std::string &field, int phi_comp, int gx_comp, int gy_comp)
Register a named elliptic field (ADC-428): records the aux output components (where the field's solve...
Definition system_field_solver.hpp:192
static constexpr int kTeComp
Canonical component of T_e (after phi/grad/B_z); cf. pops::Aux and AUX_CANONICAL on the DSL side.
Definition system_field_solver.hpp:89
void apply_named_aux_bc()
Re-applies the per-field aux HALO policies (ADC-369) onto the shared channel, AFTER the shared fill_g...
Definition system_field_solver.hpp:203
bool gauss_evolve_
Definition system_field_solver.hpp:138
Real p_abs_tol_
Definition system_field_solver.hpp:119
std::optional< PolarPoissonSolver > pell_
Definition system_field_solver.hpp:144
void apply_named_aux_one(int comp, const std::vector< Real > &field)
Populates ONE NAMED aux component (canonical index comp >= kAuxNamedBase) of the shared channel from ...
Definition system_field_solver.hpp:267
std::vector< Real > bz_field_
Definition system_field_solver.hpp:153
void solve_fields_polar_from_blocks(const std::vector< const MultiFab * > &U_stages)
POLAR coupled multi-block solve (Spec 3 criterion 24, ADC-457): same solve + aux derivation as solve_...
Definition system_field_solver.hpp:780
int last_mg_cycles() const
Definition system_field_solver.hpp:514
std::map< std::string, NamedField > named_fields_
Definition system_field_solver.hpp:185
int last_num_levels() const
Definition system_field_solver.hpp:530
void apply_reaction_field()
Installs the reaction term kappa(x) (n*n row-major) on the GeometricMG: the operator becomes div(eps ...
Definition system_field_solver.hpp:443
void assemble_named_poisson_rhs(const std::string &field, MultiFab &rhs, int target_block, const MultiFab *U_stage)
Assembles the RIGHT-HAND SIDE of named field field into rhs: f = Sum_s named_poisson_rhs_s[field](U_s...
Definition system_field_solver.hpp:896
double last_bottom_seconds() const
Definition system_field_solver.hpp:543
void assemble_poisson_rhs_from_blocks(MultiFab &rhs, const std::vector< const MultiFab * > &U_stages)
Assembles the system Poisson RIGHT-HAND SIDE into rhs for a SIMULTANEOUS coupled multi-block solve (S...
Definition system_field_solver.hpp:627
void ensure_named_elliptic(NamedField &nf)
Builds the DEDICATED cartesian elliptic solver of named field nf, the SAME poisson operator as the de...
Definition system_field_solver.hpp:865
bool provides_aux(const std::string &name) const
True if the named aux field is provided at install time, for Spec-2 criterion 24 install-time require...
Definition system_field_solver.hpp:97
std::vector< double > p_kappa_field_
Definition system_field_solver.hpp:129
std::vector< double > p_eps_field_
Definition system_field_solver.hpp:121
std::map< int, AuxHaloPolicy > named_aux_bc_
Definition system_field_solver.hpp:166
void apply_epsilon_field()
Installs the eps(x) field (n*n row-major) on the GeometricMG: the operator becomes div(eps grad phi) ...
Definition system_field_solver.hpp:398
void apply_named_aux()
Re-applies ALL the stored named aux fields (cf.
Definition system_field_solver.hpp:284
bool gauss_solved_once_
Definition system_field_solver.hpp:139
std::map< int, std::vector< Real > > named_aux_
Definition system_field_solver.hpp:161
void apply_epsilon_anisotropic_field()
Installs the eps_x(x), eps_y(x) fields (n*n row-major each) on the GeometricMG: the operator becomes ...
Definition system_field_solver.hpp:419
void assemble_poisson_rhs(MultiFab &rhs, int target_block=-1, const MultiFab *U_stage=nullptr)
Assembles the system Poisson RIGHT-HAND SIDE into rhs: f = Sum_s elliptic_rhs_s(U_s),...
Definition system_field_solver.hpp:606
std::function< bool(Real, Real)> wall_active()
"Conductor interior" predicate from p_wall / p_wall_radius / cfg.L (cf.
Definition system_field_solver.hpp:311
void ensure_elliptic()
Builds the cartesian elliptic solver (ell_) LAZILY according to p_solver: GeometricMG (carries eps(x)...
Definition system_field_solver.hpp:319
int last_krylov_iters() const
Definition system_field_solver.hpp:527
std::string p_solver
Definition system_field_solver.hpp:110
void solve_named_field_from_state(const std::string &field, int block_idx, const MultiFab &U_stage)
Solves named field field's SECOND elliptic problem from block block_idx's stage state U_stage and wri...
Definition system_field_solver.hpp:922
void solve_fields_polar(int target_block=-1, const MultiFab *U_stage=nullptr)
POLAR solve_fields: assembles f = Sum_s elliptic_rhs_s(U_s) (host loop per cell), solves the polar Po...
Definition system_field_solver.hpp:647
MultiFab & ell_rhs()
Right-hand side f of the active cartesian elliptic solver (GeometricMG or FFT), via std::visit.
Definition system_field_solver.hpp:459
Parallel seam: minimal MPI abstraction (rank/size + collectives) with serial fallback.
for_each_cell and reductions: the parallelism SEAM over the cells of a Box2D; sync_host / sync_device...
GeometricMG: in-house geometric multigrid (V-cycle) for the elliptic operator, Gauss-Seidel smoother ...
MultiFab: a field DISTRIBUTED over a level (equivalent of AMReX's MultiFab).
std::function< bool(Real, Real)> wall_predicate(const std::string &wall, double wall_radius, double L, const std::string &err_context)
Builds the "inside the conductor" predicate (embedded wall for the Poisson solver) from the wall mode...
Definition wall_predicate.hpp:30
bool pops_trace_sf()
True if the DIAGNOSTIC trace of the solve_fields path is active (environment variable POPS_TRACE_SOLV...
Definition system_field_solver.hpp:66
void pops_sf_mark(const char *w)
Writes the marker w to stderr (with flush) ONLY if pops_trace_sf(); no-op otherwise.
Definition system_field_solver.hpp:71
Definition amr_hierarchy.hpp:29
BCRec aux_halo_override(const BCRec &shared, const AuxHaloPolicy &p)
Builds the effective override BCRec for a per-field aux halo: starts from the SHARED aux BC shared (s...
Definition physical_bc.hpp:204
void device_fence()
Device barrier: waits for in-flight kernels to finish before a HOST access to unified memory.
Definition kokkos_env.hpp:43
void fill_boundary(MultiFab &mf, const Box2D &domain, Periodicity per={})
BLOCKING halo exchange: begin then end immediately (no overlap).
Definition fill_boundary.hpp:333
void fill_physical_bc(MultiFab &mf, const Box2D &domain, const BCRec &bc)
Fills the physical-face ghosts of ALL components per bc (historical entry point, bit-identical).
Definition physical_bc.hpp:176
void derive_aux_polar(const MultiFab &phi, MultiFab &aux, const PolarGeometry &g)
Derives the POLAR aux in the local basis (e_r, e_theta) from the potential phi resolved by PolarPoiss...
Definition block_builder_polar.hpp:231
@ Foextrap
@ Dirichlet
void fill_ghosts(MultiFab &mf, const Box2D &domain, const BCRec &bc)
COMPLETE ghost filling: fill_boundary (interior + periodic, periodicity deduced from bc) THEN fill_ph...
Definition physical_bc.hpp:227
PHYSICAL boundary conditions at the domain edge (BCType, BCRec, fill_physical_bc, fill_ghosts).
DIRECT EllipticSolver backends via spectral FFT (periodic BCs), MultiFab wrappers around PoissonFFT: ...
Direct POLAR Poisson solver on an annulus (PolarGeometry), Phase 2a.
Pointwise types of the physics layer: StateVec<N> (conserved state) and Aux (auxiliary fields from th...
WRITE POD handle (raw pointer + strides) over a Fab2D buffer, indexed by (i, j, c) IN GLOBAL INDICES ...
Definition fab2d.hpp:29
Boundary conditions for the FOUR faces of the domain (type + associated Dirichlet value).
Definition physical_bc.hpp:29
READ-only handle (const counterpart of Array4): same layout and same contract (POD device-copyable,...
Definition fab2d.hpp:44
Definition system_field_solver.hpp:179
int gy_comp
Definition system_field_solver.hpp:182
int phi_comp
Definition system_field_solver.hpp:180
std::optional< std::variant< GeometricMG, PoissonFFTSolver, RemappedFFTSolver > > ell
Definition system_field_solver.hpp:183
int gx_comp
Definition system_field_solver.hpp:181
Base scalar types and the POPS_HD macro (host+device portability).
ELLIPTIC conductor-wall predicate shared by the System and AmrSystem runtimes (the wall acts on the P...
Generated by