include/pops/runtime/system/system_field_solver.hpp File ReferenceΒΆ

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

SystemFieldSolver: the ELLIPTIC SOLVE + FIELD DERIVATION responsibility extracted from the god-class System::Impl (audit Lot B, cf. More...

#include <pops/core/state/state.hpp>
#include <pops/core/foundation/types.hpp>
#include <pops/mesh/storage/multifab.hpp>
#include <pops/mesh/index/box2d.hpp>
#include <pops/mesh/execution/for_each.hpp>
#include <pops/mesh/boundary/physical_bc.hpp>
#include <pops/numerics/elliptic/mg/geometric_mg.hpp>
#include <pops/numerics/elliptic/poisson/poisson_fft_solver.hpp>
#include <pops/numerics/elliptic/polar/polar_poisson_solver.hpp>
#include <pops/parallel/comm.hpp>
#include <pops/runtime/builders/block/block_builder_polar.hpp>
#include <pops/runtime/context/wall_predicate.hpp>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <map>
#include <optional>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <variant>
#include <vector>
+ Include dependency graph for system_field_solver.hpp:

Go to the source code of this file.

Classes

class  pops::field_solver::SystemFieldSolver< Impl >
 SystemFieldSolver<Impl>: see contract above. More...
 
struct  pops::field_solver::SystemFieldSolver< Impl >::NamedField
 

Namespaces

namespace  pops
 
namespace  pops::field_solver
 

Functions

bool pops::field_solver::pops_trace_sf ()
 True if the DIAGNOSTIC trace of the solve_fields path is active (environment variable POPS_TRACE_SOLVE_FIELDS set).
 
void pops::field_solver::pops_sf_mark (const char *w)
 Writes the marker w to stderr (with flush) ONLY if pops_trace_sf(); no-op otherwise.
 

Detailed Description

SystemFieldSolver: the ELLIPTIC SOLVE + FIELD DERIVATION responsibility extracted from the god-class System::Impl (audit Lot B, cf.

docs/SYSTEM_CPP_EXTRACTION_PLAN.md section 2). Extracted VERBATIM from python/system.cpp: no change to the numerics, to the order of operations, to fill_ghosts/fill_boundary, to device_fence or to tolerance. STRICTLY bit-identical – the code is moved as is, only access to the SHARED members of Impl (aux, sp, cfg, geom, pgeom_, ba, dm, bc_, dom, per_, periodic_, polar_) goes through the back-pointer owner_->.

CONTRACT / INVARIANTS

  • OWNS: the elliptic solvers (ell_ cartesian GeometricMG/PoissonFFTSolver; pell_ polar PolarPoissonSolver), the Poisson configuration tokens (p_rhs/p_solver/p_bc/p_wall/ p_wall_radius/p_eps_), the coefficient fields and flags (eps(x), eps_x/eps_y, kappa) as well as the aux field APPLICATION buffers (bz_field_ and te_src_) with their methods apply_bz / apply_te.
  • READS (without owning) the SHARED aux and the block list via owner_->: the aux is populated by solve_fields (phi, grad phi, B_z, T_e) then its halos are filled; the block list provides the right-hand side of the Poisson (sum of the per-block elliptic bricks) and the fluid source of T_e.
  • DISPATCH cartesian vs polar: solve_fields() routes to solve_fields_polar() when owner_->polar_, otherwise the cartesian path. The two paths are independent (ell_ never touched in polar and vice versa). ensure_elliptic / ensure_elliptic_polar build the solver lazily.
  • CRITICAL device INVARIANT: the device_fence() between ell_solve() and the derivation of grad phi MUST stay atomic (without it, the GPU V-cycle is not finished when phi is read). Same in polar after pell_->solve(). DO NOT reorder.
  • MPI INVARIANT: the derivation / population loops (B_z, T_e, eps, kappa) iterate over the LOCAL fabs (local_size()), never fab(0) hardcoded: no-op on a rank without a box, bit-identical to the owner. This guard is PRESERVED by the extraction.

Since System::Impl stays PRIVATE to python/system.cpp, this helper is a TEMPLATE parametrized on the real Impl type (same technique as native_loader): python/system.cpp instantiates it with System::Impl after defining Impl. owner_ is an Impl* (the lifetime of the helper is subordinate to that of Impl).