include/pops/numerics/elliptic/mg/geometric_mg.hpp File ReferenceΒΆ

adc_cpp: include/pops/numerics/elliptic/mg/geometric_mg.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
geometric_mg.hpp File Reference

GeometricMG: in-house geometric multigrid (V-cycle) for the elliptic operator, Gauss-Seidel smoother and bottom solve. More...

+ Include dependency graph for geometric_mg.hpp:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  pops::detail::CopyComp0Kernel
 
class  pops::GeometricMG
 

Namespaces

namespace  pops
 
namespace  pops::detail
 

Functions

void pops::detail::mg_trace_mark (const char *w)
 
BCRec pops::homogeneous (const BCRec &b)
 

Detailed Description

GeometricMG: in-house geometric multigrid (V-cycle) for the elliptic operator, Gauss-Seidel smoother and bottom solve.

Models the EllipticSolver and LinearSolver concepts.

Layer: include/pops/numerics/elliptic/mg. Role: solve L(phi) = f by a classic V-cycle (pre-smoothing, residual restriction via average_down onto a twice-coarser grid, recursive solve of the correction with homogeneous BCs, prolongation via interpolate, post-smoothing; at the coarsest level, long smoothing = bottom solve). The hierarchy is obtained by coarsening the domain by 2 down to a minimal size; restriction and prolongation reuse the AMR transfer operators. This is the ONLY type that carries the operator role (EllipticOperator: accessors op_eps()/op_kappa()/... + bc() + geom()), reused by the Krylov solver for a matvec consistent with the MG residual. Contract: solve(rel_tol, max_cycles, abs_tol=0) returns the number of cycles; MIXED stopping criterion residual <= max(rel_tol * r0, abs_tol) (hypre/AMReX convention). solve() with no argument takes the default tolerance (1e-8, 50 cycles). phi is kept between calls (warm start). solve_robust hardens the smoothing ONLY in case of true divergence at the embedded boundary (otherwise bit-identical).

Invariants:

  • coarsening stops if a box does not coarsen CLEANLY (refine(coarsen(b)) != b): avoids a degenerate coarse BoxArray (duplicate 1x1 boxes) where average_down would read out of bounds (MPI bug);
  • current_residual() does a MANDATORY all_reduce_max (distributed multi-box coarse): otherwise the stopping criterion fires at different iterations per rank -> MPI desynchronization;
  • replicated: level replicated on all ranks (per-fab V-cycle without communication), as expected by the AMR coupler; in serial bit-for-bit identical to round-robin;
  • cut_cell: order-2 Shortley-Weller weights at the embedded boundary (vs staircase); cut_cell=false bit-identical to the historical stencil;
  • device kernels are NAMED FUNCTORS (recipe #93/#64): extended lambda forbidden cross-TU under nvcc.