peclet-amr 0.2.0
Block-local-Morton AMR octree + collocated cut-cell Navier–Stokes solver (header-only C++20, Kokkos + MPI)
Loading...
Searching...
No Matches
peclet::amr::Multigrid< Dim, Bits > Class Template Reference

#include <multigrid.hpp>

Public Types

enum class  Bottom { Auto , Smoother , Agglomerated }
 What solves the coarsest level (docs/amr_mg_depth.md §6.6). More...
 
using Octree = BlockOctree< Dim, Bits >
 
using M = typename Octree::M
 
using Code = typename Octree::Code
 
using Poisson = AmrPoisson< Dim, Bits >
 

Public Member Functions

void build (const Octree &finest, double h0, bool liftRoot=true, Index bottomExtent=4)
 Build + upload the hierarchy from a finest octree (uniform coarsening), openness- free.
 
void build (const Octree &finest, const Vec< Dim > &h0, bool liftRoot=true, Index bottomExtent=4)
 The per-axis form: h0 is the finest spacing (dx, dy, dz); every level inherits the root aspect ratio (docs/amr_anisotropic.md AM1).
 
template<class OpenFn >
void build (const Octree &finest, double h0, OpenFn &&openFn, bool periodic=true, bool immersedWall=false, bool liftRoot=true, Index bottomExtent=4)
 Build with cut-cell openness openFn(faceCentreWorld, axis) → [0,1], coarsened to every level by area-averaging (AmrMultigrid::setOpenness — the same coarsenOpenAvg the host uses): each level's face weight is α·A/d with α the coarsened aperture, so the coarse operators stay consistent cut-cell operators.
 
template<class OpenFn >
void build (const Octree &finest, const Vec< Dim > &h0, OpenFn &&openFn, bool periodic=true, bool immersedWall=false, bool liftRoot=true, Index bottomExtent=4)
 The per-axis form of the openness build (see the scalar-h0 overload above).
 
void buildRaw (const Octree &finest, const Vec< Dim > &h0, std::vector< double > alphaRaw, bool periodic=true, bool liftRoot=true, Index bottomExtent=4)
 Build from a finest octree whose face openness is handed over ALREADY EVALUATED — alphaRaw in the AmrPoisson::opennessRaw() layout (finest.numLeaves()·2·Dim doubles, face-major per leaf).
 
void setKappaRestrict (bool on)
 Opt-in: use κ-weighted (fluid-fraction) restriction instead of the default plain volume-average.
 
void setRemoveMean (bool on)
 Opt-in (default off): project the correction to mean-zero over fluid cells at every V-cycle level — the singular (periodic pure-Neumann) nullspace removal, mirroring flow CutcellMG::vcycle.
 
void setHelmholtz (double c0, double cD)
 Turn every level's operator into the Helmholtz form H = c0·I + cD·L (default c0=0, cD=1 ⇒ the pure Laplacian L).
 
void setBottom (Bottom b)
 Select what solves the coarsest level (§6.6).
 
Bottom bottom () const
 The selection in force (Auto unless setBottom said otherwise).
 
std::string bottomName () const
 "jacobi" | "amg" — what the coarsest level ACTUALLY runs.
 
Index bottomExtent () const
 The extent (cells per axis) the last build stopped the ladder at and Auto compares with.
 
Index bottomSize () const
 Rows of the exact bottom's matrix (0 when the sweeps run instead).
 
Index bottomIdentityRows () const
 Fully closed coarsest cells the exact bottom solves as identity rows (0 without it).
 
int bottomComponents () const
 Connected fluid components of the coarsest level (0 without the exact bottom).
 
int bottomIters () const
 Inner CG iterations of the last exact bottom solve (0 without it).
 
bool bottomOnDevice () const
 Whether the exact bottom's per-V-cycle solve runs on the device (§5.5's 10^4-row rule).
 
void setBottomCheck (bool on)
 Opt-in §6.6 consistency gate (flow's AGMG_DEBUG): after every exact bottom solve, recompute |b − L x| with the V-CYCLE'S OWN FvOp and record max|b − Lx| / max|b|.
 
double bottomResidual () const
 max|b − L x| / max|b| of the last checked bottom solve (0 unless setBottomCheck(true)).
 
std::size_t numLevels () const
 
Index numLeaves (std::size_t L=0) const
 
Code octreeCode (std::size_t L, Index i) const
 
View< double > x (std::size_t L=0)
 
View< double > b (std::size_t L=0)
 
const FvOp & op (std::size_t L=0) const
 
View< Index > quadStart () const
 
View< Index > quadSlot () const
 
View< double > quadCoef () const
 
void vcycle (int pre=2, int post=2, int bottom=40, double omega=0.8, std::size_t L=0)
 One V-cycle on level L (default finest) of the standard (consistent conservative) operator, correction scheme.
 
double solveQuad (int outer=20, int cyclesPerOuter=1, int pre=2, int post=2, int bottom=40, double omega=0.8)
 Solve L_quad u = rhs (the 2nd-order graded operator) by deferred correction: each outer step solves L_std u = rhs − (L_quad−L_std)u with the quadratic correction lagged, via cyclesPerOuter standard V-cycles.
 
void reassembleOperators ()
 Re-assemble every level's operator ON THE DEVICE from the (host) hierarchy's current geometry — the dynamic-AMR rebuild hook (D5/D6).
 

Detailed Description

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
class peclet::amr::Multigrid< Dim, Bits >

Definition at line 118 of file multigrid.hpp.

Member Typedef Documentation

◆ Octree

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
using peclet::amr::Multigrid< Dim, Bits >::Octree = BlockOctree<Dim, Bits>

Definition at line 120 of file multigrid.hpp.

◆ M

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
using peclet::amr::Multigrid< Dim, Bits >::M = typename Octree::M

Definition at line 121 of file multigrid.hpp.

◆ Code

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
using peclet::amr::Multigrid< Dim, Bits >::Code = typename Octree::Code

Definition at line 122 of file multigrid.hpp.

◆ Poisson

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
using peclet::amr::Multigrid< Dim, Bits >::Poisson = AmrPoisson<Dim, Bits>

Definition at line 123 of file multigrid.hpp.

Member Enumeration Documentation

◆ Bottom

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
enum class peclet::amr::Multigrid::Bottom
strong

What solves the coarsest level (docs/amr_mg_depth.md §6.6).

The three spellings are flow's set_pressure_bottom values: Auto engages the exact bottom iff the coarsest global extent exceeds bottomExtent (where 60 damped-Jacobi sweeps stop being a solve), Smoother forces the sweeps, Agglomerated forces the exact bottom.

Enumerator
Auto 
Smoother 
Agglomerated 

Definition at line 129 of file multigrid.hpp.

Member Function Documentation

◆ build() [1/4]

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::build ( const Octree &  finest,
double  h0,
bool  liftRoot = true,
Index  bottomExtent = 4 
)
inline

Build + upload the hierarchy from a finest octree (uniform coarsening), openness- free.

h0 is the finest spacing (every level shares it; a coarse leaf's higher level encodes its width). liftRoot / bottomExtent continue the ladder BELOW the root brick (docs/amr_mg_depth.md §6.1–§6.2); they are simply forwarded to AmrMultigrid::build.

Definition at line 136 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::bottomExtent(), peclet::amr::Multigrid< Dim, Bits >::build(), and peclet::amr::transferFieldGradients().

Referenced by peclet::amr::Multigrid< Dim, Bits >::build(), and peclet::amr::Multigrid< Dim, Bits >::build().

◆ build() [2/4]

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::build ( const Octree &  finest,
const Vec< Dim > &  h0,
bool  liftRoot = true,
Index  bottomExtent = 4 
)
inline

The per-axis form: h0 is the finest spacing (dx, dy, dz); every level inherits the root aspect ratio (docs/amr_anisotropic.md AM1).

Re-decides the bottom (setBottom's rule) at the end. Host setup + device upload; local (single-rank).

Definition at line 142 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::bottomExtent(), and peclet::amr::transferFieldGradients().

◆ build() [3/4]

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
template<class OpenFn >
void peclet::amr::Multigrid< Dim, Bits >::build ( const Octree &  finest,
double  h0,
OpenFn &&  openFn,
bool  periodic = true,
bool  immersedWall = false,
bool  liftRoot = true,
Index  bottomExtent = 4 
)
inline

Build with cut-cell openness openFn(faceCentreWorld, axis) → [0,1], coarsened to every level by area-averaging (AmrMultigrid::setOpenness — the same coarsenOpenAvg the host uses): each level's face weight is α·A/d with α the coarsened aperture, so the coarse operators stay consistent cut-cell operators.

Definition at line 155 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::bottomExtent(), peclet::amr::Multigrid< Dim, Bits >::build(), and peclet::amr::transferFieldGradients().

◆ build() [4/4]

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
template<class OpenFn >
void peclet::amr::Multigrid< Dim, Bits >::build ( const Octree &  finest,
const Vec< Dim > &  h0,
OpenFn &&  openFn,
bool  periodic = true,
bool  immersedWall = false,
bool  liftRoot = true,
Index  bottomExtent = 4 
)
inline

The per-axis form of the openness build (see the scalar-h0 overload above).

liftRoot / bottomExtent continue the ladder below the root brick exactly as in the openness-free build (docs/amr_mg_depth.md §6.1–§6.2); the openness of a lifted level is area-averaged like any other (§6.3).

Definition at line 165 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::bottomExtent(), and peclet::amr::transferFieldGradients().

◆ buildRaw()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::buildRaw ( const Octree &  finest,
const Vec< Dim > &  h0,
std::vector< double >  alphaRaw,
bool  periodic = true,
bool  liftRoot = true,
Index  bottomExtent = 4 
)
inline

Build from a finest octree whose face openness is handed over ALREADY EVALUATED — alphaRaw in the AmrPoisson::opennessRaw() layout (finest.numLeaves()·2·Dim doubles, face-major per leaf).

The ladder, the area-averaged coarsening and the device assembly are the openFn build's verbatim. This is the entry point the redundant tail uses (docs/amr_mg_depth.md §6.5 step 4): the tail's level 0 is a gathered copy of a distributed level, so its α is the distributed openness ladder's own output and must be carried over, not re-sampled.

Definition at line 182 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::bottomExtent(), and peclet::amr::transferFieldGradients().

◆ setKappaRestrict()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::setKappaRestrict ( bool  on)
inline

Opt-in: use κ-weighted (fluid-fraction) restriction instead of the default plain volume-average.

Experimental — validate with the comparison test before relying on it.

Definition at line 194 of file multigrid.hpp.

◆ setRemoveMean()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::setRemoveMean ( bool  on)
inline

Opt-in (default off): project the correction to mean-zero over fluid cells at every V-cycle level — the singular (periodic pure-Neumann) nullspace removal, mirroring flow CutcellMG::vcycle.

Needed when the V-cycle is the MG-PCG preconditioner for a singular operator (otherwise the cycle drifts / amplifies a near-nullspace mode and the projection blows up under large transient divergence). The bit-exact-vs-host MG test keeps this OFF.

Definition at line 201 of file multigrid.hpp.

◆ setHelmholtz()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::setHelmholtz ( double  c0,
double  cD 
)
inline

Turn every level's operator into the Helmholtz form H = c0·I + cD·L (default c0=0, cD=1 ⇒ the pure Laplacian L).

With c0=idiag, cD=−μ the hierarchy represents the momentum operator idiag·I − μ∇² and (being non-singular for c0≠0) is an effective V-cycle preconditioner for the momentum BiCGStab. The reaction c0 is held constant on every level (standard for a Helmholtz MG preconditioner); cD scales the coarsened L.

Definition at line 208 of file multigrid.hpp.

References peclet::amr::transferFieldGradients().

◆ setBottom()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::setBottom ( Bottom  b)
inline

Select what solves the coarsest level (§6.6).

Takes effect immediately — the exact bottom is (re)assembled here — so it may be called before or after build(); build re-applies the selection in force. Local. CAVEAT: the rule is the Laplacian's alone — setHelmholtz's fall-back to the sweeps (the exact bottom assembles the pure Laplacian) is undone by a LATER setBottom, build or reassembleOperators. Nothing combines them today (no caller of setHelmholtz); call setHelmholtz last if one ever does.

Definition at line 226 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::b().

◆ bottom()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
Bottom peclet::amr::Multigrid< Dim, Bits >::bottom ( ) const
inline

The selection in force (Auto unless setBottom said otherwise).

Definition at line 231 of file multigrid.hpp.

Referenced by peclet::amr::Multigrid< Dim, Bits >::solveQuad(), and peclet::amr::Multigrid< Dim, Bits >::vcycle().

◆ bottomName()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
std::string peclet::amr::Multigrid< Dim, Bits >::bottomName ( ) const
inline

"jacobi" | "amg" — what the coarsest level ACTUALLY runs.

Definition at line 233 of file multigrid.hpp.

◆ bottomExtent()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
Index peclet::amr::Multigrid< Dim, Bits >::bottomExtent ( ) const
inline

◆ bottomSize()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
Index peclet::amr::Multigrid< Dim, Bits >::bottomSize ( ) const
inline

Rows of the exact bottom's matrix (0 when the sweeps run instead).

Definition at line 237 of file multigrid.hpp.

◆ bottomIdentityRows()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
Index peclet::amr::Multigrid< Dim, Bits >::bottomIdentityRows ( ) const
inline

Fully closed coarsest cells the exact bottom solves as identity rows (0 without it).

Definition at line 239 of file multigrid.hpp.

◆ bottomComponents()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
int peclet::amr::Multigrid< Dim, Bits >::bottomComponents ( ) const
inline

Connected fluid components of the coarsest level (0 without the exact bottom).

Definition at line 241 of file multigrid.hpp.

◆ bottomIters()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
int peclet::amr::Multigrid< Dim, Bits >::bottomIters ( ) const
inline

Inner CG iterations of the last exact bottom solve (0 without it).

Definition at line 243 of file multigrid.hpp.

◆ bottomOnDevice()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
bool peclet::amr::Multigrid< Dim, Bits >::bottomOnDevice ( ) const
inline

Whether the exact bottom's per-V-cycle solve runs on the device (§5.5's 10^4-row rule).

Definition at line 245 of file multigrid.hpp.

◆ setBottomCheck()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::setBottomCheck ( bool  on)
inline

Opt-in §6.6 consistency gate (flow's AGMG_DEBUG): after every exact bottom solve, recompute |b − L x| with the V-CYCLE'S OWN FvOp and record max|b − Lx| / max|b|.

Off by default (two extra device reductions per V-cycle); §10 quotes bottomResidual() at <= 1e-9.

Definition at line 250 of file multigrid.hpp.

◆ bottomResidual()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
double peclet::amr::Multigrid< Dim, Bits >::bottomResidual ( ) const
inline

max|b − L x| / max|b| of the last checked bottom solve (0 unless setBottomCheck(true)).

Definition at line 252 of file multigrid.hpp.

◆ numLevels()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
std::size_t peclet::amr::Multigrid< Dim, Bits >::numLevels ( ) const
inline

Definition at line 254 of file multigrid.hpp.

◆ numLeaves()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
Index peclet::amr::Multigrid< Dim, Bits >::numLeaves ( std::size_t  L = 0) const
inline

Definition at line 255 of file multigrid.hpp.

References peclet::amr::transferFieldGradients().

◆ octreeCode()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
Code peclet::amr::Multigrid< Dim, Bits >::octreeCode ( std::size_t  L,
Index  i 
) const
inline

Definition at line 256 of file multigrid.hpp.

References peclet::amr::transferFieldGradients().

◆ x()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
View< double > peclet::amr::Multigrid< Dim, Bits >::x ( std::size_t  L = 0)
inline

Definition at line 257 of file multigrid.hpp.

References peclet::amr::transferFieldGradients().

◆ b()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
View< double > peclet::amr::Multigrid< Dim, Bits >::b ( std::size_t  L = 0)
inline

◆ op()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
const FvOp & peclet::amr::Multigrid< Dim, Bits >::op ( std::size_t  L = 0) const
inline

Definition at line 259 of file multigrid.hpp.

References peclet::amr::transferFieldGradients().

◆ quadStart()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
View< Index > peclet::amr::Multigrid< Dim, Bits >::quadStart ( ) const
inline

Definition at line 260 of file multigrid.hpp.

◆ quadSlot()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
View< Index > peclet::amr::Multigrid< Dim, Bits >::quadSlot ( ) const
inline

Definition at line 261 of file multigrid.hpp.

◆ quadCoef()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
View< double > peclet::amr::Multigrid< Dim, Bits >::quadCoef ( ) const
inline

Definition at line 262 of file multigrid.hpp.

◆ vcycle()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::vcycle ( int  pre = 2,
int  post = 2,
int  bottom = 40,
double  omega = 0.8,
std::size_t  L = 0 
)
inline

◆ solveQuad()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
double peclet::amr::Multigrid< Dim, Bits >::solveQuad ( int  outer = 20,
int  cyclesPerOuter = 1,
int  pre = 2,
int  post = 2,
int  bottom = 40,
double  omega = 0.8 
)
inline

Solve L_quad u = rhs (the 2nd-order graded operator) by deferred correction: each outer step solves L_std u = rhs − (L_quad−L_std)u with the quadratic correction lagged, via cyclesPerOuter standard V-cycles.

The finest b holds rhs on entry and is restored on return. Returns the final L_quad residual L2 norm.

Definition at line 303 of file multigrid.hpp.

References peclet::amr::Multigrid< Dim, Bits >::bottom(), peclet::amr::quadDelta(), peclet::amr::residualFv(), peclet::amr::transferFieldGradients(), and peclet::amr::Multigrid< Dim, Bits >::vcycle().

◆ reassembleOperators()

template<int Dim, unsigned Bits = (Dim == 2 ? 32u : (Dim == 3 ? 21u : 16u))>
void peclet::amr::Multigrid< Dim, Bits >::reassembleOperators ( )
inline

Re-assemble every level's operator ON THE DEVICE from the (host) hierarchy's current geometry — the dynamic-AMR rebuild hook (D5/D6).

After a moving boundary re-samples each level's openness on the host AmrPoisson (hmg_), this rebuilds all per-level FvOps on device with no host CSR walk and no round-trip, preserving each level's Helmholtz c0/cD. Topology (c2p/child maps) is unchanged.

Definition at line 496 of file multigrid.hpp.

References peclet::amr::transferFieldGradients().


The documentation for this class was generated from the following file: