chombo-discharge
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
ParticleContainer< P, Traits > Class Template Reference

AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form. More...

#include <CD_ParticleContainer.H>

Inheritance diagram for ParticleContainer< P, Traits >:
Inheritance graph
[legend]

Public Types

using Leaf = ParticleSoA< P, Traits >
 The per-patch leaf type owned at every (level, box).
 
using LevelParticles = LayoutData< Leaf >
 The per-level holder type (one Leaf per box on the level's DisjointBoxLayout).
 

Public Member Functions

LevelTiles::LevelAndBox findDestination (const RealVect &a_pos) const
 Map a position to its owning (level, grid index, rank) via the finest containing tile.
 
Construction and lifetime
 ParticleContainer ()
 Construct an empty, undefined container. Call define() before use.
 
 ~ParticleContainer ()=default
 Destructor.
 
 ParticleContainer (const ParticleContainer &)=delete
 Copy construction is deleted (holders are shared RefCountedPtr – a copy would alias).
 
ParticleContaineroperator= (const ParticleContainer &)=delete
 Copy assignment is deleted (move-only ownership).
 
void define (const Vector< DisjointBoxLayout > &a_grids, const Vector< ProblemDomain > &a_domains, const Vector< Real > &a_dx, const Vector< int > &a_refRat, const RealVect &a_probLo, const int a_minBlockSize, const Vector< RefCountedPtr< LevelTiles > > &a_levelTiles, const int a_finestLevel, const std::string &a_realm, const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > *a_validCells)
 Allocate the per-level holders and the per-level tile-ownership maps over the AMR grids.
 
Grid metadata
const Vector< DisjointBoxLayout > & getGrids () const
 Per-level AMR grids.
 
Vector< RealVect > getDx () const
 Per-level grid spacing.
 
RealVect getProbLo () const
 Lower-left corner of the physical domain.
 
int getFinestLevel () const
 Finest AMR level index.
 
std::string getRealm () const
 Realm label.
 
Particle holders
AMRParticlesSoA< P, Traits > & getParticles ()
 The valid particles on all levels.
 
const AMRParticlesSoA< P, Traits > & getParticles () const
 The valid particles on all levels (const).
 
AMRParticlesSoA< P, Traits > & getMaskParticles ()
 The halo/mask particles on all levels.
 
const AMRParticlesSoA< P, Traits > & getMaskParticles () const
 The halo/mask particles on all levels (const).
 
AMRParticlesSoA< P, Traits > & getBufferParticles ()
 The grown-grid buffer particles on all levels.
 
const AMRParticlesSoA< P, Traits > & getBufferParticles () const
 The grown-grid buffer particles on all levels (const).
 
LevelParticlesoperator[] (const int a_lvl)
 Valid particles on one level (index by DataIndex to reach a patch's Leaf).
 
const LevelParticlesoperator[] (const int a_lvl) const
 Valid particles on one level (const).
 
State
bool isOrganizedByCell () const
 Whether the valid leaves are currently cell-sorted.
 
bool isDefined () const
 Whether define() has been called.
 
Population
void clearParticles ()
 Drop all valid particles on every level (keeps each leaf's arena capacity).
 
void addParticlesDestructive (ParticleSoA< P, Traits > &a_particles)
 Add a free-standing buffer of particles to the container, routing each to its owner.
 
Counting
unsigned long long getNumberOfValidParticlesLocal () const
 Number of valid particles owned by this rank.
 
unsigned long long getNumberOfValidParticlesGlobal () const
 Number of valid particles across all ranks.
 
unsigned long long getNumberOfOutcastParticlesLocal () const
 Number of particles dropped off-domain by the most recent remap() on this rank.
 
unsigned long long getNumberOfOutcastParticlesGlobal () const
 Number of particles dropped off-domain by the most recent remap(), across all ranks.
 
Dynamics
void remap ()
 Redistribute every valid particle to the patch/level/rank that owns its cell.
 
void preRegrid ()
 Cache the current valid particles ahead of a regrid.
 
void regrid (const Vector< DisjointBoxLayout > &a_grids, const Vector< ProblemDomain > &a_domains, const Vector< Real > &a_dx, const Vector< int > &a_refRat, const int a_minBlockSize, const Vector< RefCountedPtr< LevelTiles > > &a_levelTiles, const int a_newFinestLevel)
 Rebuild over a new AMR layout and redistribute the preRegrid()-cached particles onto it.
 
Ghost particles
void fillGhostParticles (const AMRParticleGhostMask &a_maskSame, const AMRParticleGhostMask &a_maskCoarToFine, const AMRParticleGhostMask &a_maskFineToCoar)
 Fill each patch's ghost halo from prebuilt Realm particle ghost masks.
 
void clearGhostParticles ()
 Remove every ghost particle (any non-Valid GhostType) from all levels and patches.
 
void claimOwnership (const bool a_onlyValidRegion)
 Claim ownership of this rank's particles by stamping their owner rank (rankID = procID()).
 
long long resetParticleIDs (const bool a_onlyValidRegion, const ParticleID a_startID)
 Assign globally-unique, contiguous particle IDs to the owned particles.
 
Halo and buffer particles
void copyMaskParticles (const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_mask)
 Copy the valid particles selected by a per-cell mask into the mask holder, all levels.
 
void copyMaskParticles (const int a_level, const LevelData< BaseFab< bool > > &a_mask)
 Copy the valid particles whose cell the mask marks true into the mask holder, one level.
 
void transferMaskParticles (const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_mask)
 Move the valid particles selected by a per-cell mask into the mask holder, all levels.
 
void transferMaskParticles (const int a_level, const LevelData< BaseFab< bool > > &a_mask)
 Move the valid particles whose cell the mask marks true into the mask holder, one level.
 
void clearMaskParticles ()
 Drop all mask/halo particles on every level (keeps capacity).
 
void clearBufferParticles ()
 Drop all buffer particles on every level (keeps capacity).
 
const Vector< BoxLayout > & getGrownGrids () const
 Per-level grown grids that the buffer particles live on.
 
void transferParticles (AMRParticlesSoA< P, Traits > &a_source)
 Move all particles from another holder (on the same valid grids) into the valid holder.
 
Cell sorting
void organizeParticlesByCell ()
 Cell-sort every valid leaf (counting sort into Fortran cell order + CSR cell offsets).
 
void organizeParticlesByPatch ()
 Return to a by-patch view (the leaves remain a single contiguous array per patch).
 

Protected Types

using PoolKey = std::pair< int, unsigned int >
 Pool key identifying a destination patch: (level, grid index within the level).
 
using MoverPool = std::vector< std::map< PoolKey, Leaf > >
 Per-rank pool of movers: pool[rank] maps a destination patch to a small SoA of particles.
 

Protected Member Functions

void setupGrownGrids ()
 Build the grown grids (buffer-particle layout): boxes grown by the refinement factor.
 
MoverPool gatherToPool (AMRParticlesSoA< P, Traits > &a_source, const Vector< DisjointBoxLayout > &a_sourceGrids)
 Gather every particle of a source holder into a per-rank, per-destination-patch pool.
 
MoverPool gatherMoversToPool ()
 Mask fast path for remap(): pool ONLY the movers, leaving stayers in place.
 
MoverPool gatherGhostsFromMasks (const AMRParticleGhostMask &a_maskSame, const AMRParticleGhostMask &a_maskCoarToFine, const AMRParticleGhostMask &a_maskFineToCoar)
 Gather ghost copies into a per-rank pool using prebuilt particle ghost masks.
 
void distributeFromPool (MoverPool &a_pool, const bool a_setOwnerToReceiver)
 Assign a pool into the valid holders: local appends + MPI scatter.
 
IntVect cellIndex (const int a_lvl, const RealVect &a_pos) const
 Cell index containing a position on a given level (floor((x - probLo)/dx)).
 
bool inValidBox (const int a_lvl, const Box &a_box, const RealVect &a_pos) const
 True if a position's cell lies inside a (grid) box on a given level.
 

Protected Attributes

Vector< DisjointBoxLayout > m_grids
 Per-level AMR grids.
 
Vector< ProblemDomain > m_domains
 Per-level problem domains.
 
Vector< RealVect > m_dx
 Per-level grid spacing (isotropic, stored as RealVect).
 
Vector< int > m_refRat
 Per-level refinement ratios (entry l is the ratio between level l and l+1).
 
Vector< RefCountedPtr< LevelTiles > > m_levelTiles
 Per-level tile-ownership maps (cell tile -> owning grid index / rank), used by remap().
 
RealVect m_probLo
 Lower-left corner of the physical domain.
 
int m_minBlockSize
 Grid blocking factor (tile size).
 
int m_finestLevel
 Finest AMR level index.
 
unsigned long long m_numOutcastLocal
 Particles dropped off-domain by the most recent remap() (local count).
 
std::string m_realm
 Realm label (diagnostics only).
 
const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > * m_validCells = nullptr
 Optional alias to the realm's valid-cell mask (true = cell not covered by a finer level).
 
bool m_isDefined
 Whether define() has been called.
 
bool m_isOrganizedByCell
 Whether the valid leaves are currently cell-sorted.
 
AMRParticlesSoA< P, Traits > m_particles
 Valid particles: one ParticleSoA leaf per box, per level.
 
AMRParticlesSoA< P, Traits > m_cacheParticles
 Regrid cache: the pre-regrid valid holders, kept alive over the old layout by preRegrid().
 
Vector< DisjointBoxLayout > m_cacheGrids
 The old (pre-regrid) grids the cache holders are defined on (for iterating the cache).
 
AMRParticlesSoA< P, Traits > m_maskParticles
 Halo/mask particles per level.
 
AMRParticlesSoA< P, Traits > m_bufferParticles
 Grown-grid buffer particles per level (on m_grownGrids; filled during halo deposition).
 
Vector< BoxLayout > m_grownGrids
 Per-level grown grids (boxes grown by the refinement factor on finer levels) for the buffer.
 

Detailed Description

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
class ParticleContainer< P, Traits >

AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form.

ParticleContainer owns particles distributed across an AMR hierarchy. For every level it holds one LayoutData<ParticleSoA<P>> indexed by DataIndex over that level's DisjointBoxLayout, so the particles of a single patch are reached as container[lvl][din] and stored contiguously in Struct-of-Arrays form (see ParticleSoA). Each particle carries a position and a weight (owned by the leaf) plus the user payload P, which contributes the extra per-particle columns.

Particle holders

Three parallel sets of per-level leaves are maintained:

Ownership and lifetime

The per-level holders are shared RefCountedPtr, so the container is move-only: copy construction and copy assignment are deleted (a copy would alias the holders). Construct an empty container, then call define() with the grids and AMR metadata before any other use; isDefined() reports readiness.

Particle ownership and routing

A particle belongs to the patch on the finest level whose cell contains its position. After particles move, remap() routes each one back to its owning patch – across MPI ranks and across levels as needed. On a regrid, call preRegrid() before the grids change and regrid() afterwards to carry the particles onto the new layout. Particles that leave the domain are dropped and reported by getNumberOfOutcastParticlesLocal() / getNumberOfOutcastParticlesGlobal().

Cell sorting

A leaf stores its particles in arbitrary (append) order by default. organizeParticlesByCell() sorts each valid leaf so that the particles of a cell occupy a contiguous range (queried through the leaf's CSR cell offsets); organizeParticlesByPatch() returns to the unsorted view. isOrganizedByCell() reports the current state.

Typical usage

particles.define(grids, domains, dx, refRat, probLo, minBlockSize, levelTiles, finestLevel, "primal", validCells);
// Add particles locally, then route every particle to its owning patch (and across ranks).
particles.addParticlesLocal(lvl, pos, weight, MyPayload{...});
particles.remap();
// Iterate the valid particles of one patch.
const DisjointBoxLayout& dbl = particles.getGrids()[lvl];
const DataIterator& dit = dbl.dataIterator();
const int nbox = dit.size();
#pragma omp parallel for schedule(runtime)
for (int mybox = 0; mybox < nbox; mybox++) {
const DataIndex& din = dit[mybox];
ParticleSoA<MyPayload>& leaf = particles[lvl][din];
for (std::size_t i = 0; i < leaf.size(); i++) {
const RealVect x = leaf.position(i);
// ... use x, leaf.weight(i), payload columns ...
}
}
AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form.
Definition CD_ParticleContainer.H:123
void define(const Vector< DisjointBoxLayout > &a_grids, const Vector< ProblemDomain > &a_domains, const Vector< Real > &a_dx, const Vector< int > &a_refRat, const RealVect &a_probLo, const int a_minBlockSize, const Vector< RefCountedPtr< LevelTiles > > &a_levelTiles, const int a_finestLevel, const std::string &a_realm, const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > *a_validCells)
Allocate the per-level holders and the per-level tile-ownership maps over the AMR grids.
Definition CD_ParticleContainer.H:193
const Vector< DisjointBoxLayout > & getGrids() const
Per-level AMR grids.
Definition CD_ParticleContainer.H:260
void remap()
Redistribute every valid particle to the patch/level/rank that owns its cell.
Definition CD_ParticleContainerImplem.H:494
Arena-backed Struct-of-Arrays particle container for a single grid patch.
Definition CD_ParticleSoA.H:655
RealVect position(const std::size_t a_index) const noexcept
Position of particle i as a RealVect (by value, assembled from the scalar columns).
Definition CD_ParticleSoA.H:1188
std::size_t size() const noexcept
Number of particles currently stored.
Definition CD_ParticleSoA.H:882
Template Parameters
PUser payload struct contributing the per-particle payload columns; defaults to NoPayload.
TraitsColumn descriptor for the payload; defaults to ParticleTraits

.

Member Function Documentation

◆ addParticlesDestructive()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
void ParticleContainer< P, Traits >::addParticlesDestructive ( ParticleSoA< P, Traits > &  a_particles)
inline

Add a free-standing buffer of particles to the container, routing each to its owner.

The buffer (e.g. filled by ParticleManagement::drawRandomParticles(ParticleSoA)) is catenated onto a local leaf – O(1) when that leaf is empty – and then remap() routes every particle (including across ranks and levels) to the patch/level/rank that owns its position. a_particles is left empty. Assumes this rank owns at least one box (true whenever level 0 covers the domain). Unlike addParticlesLocal(), the positions need not already belong to this rank.

ParticleManagement::drawRandomParticles(drawn, ...);
particles.addParticlesDestructive(drawn); // drawn is empty afterwards; particles are routed to owners
Parameters
[in,out]a_particlesBuffer of particles to ingest (emptied on return).

◆ cellIndex()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
IntVect ParticleContainer< P, Traits >::cellIndex ( const int  a_lvl,
const RealVect &  a_pos 
) const
inlineprotected

Cell index containing a position on a given level (floor((x - probLo)/dx)).

Parameters
[in]a_lvlLevel index.
[in]a_posPosition.
Returns
The containing cell IntVect.

◆ claimOwnership()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::claimOwnership ( const bool  a_onlyValidRegion)
inline

Claim ownership of this rank's particles by stamping their owner rank (rankID = procID()).

Ghost particles (isGhost()) are always left untouched, so a ghost keeps the owner rank it carries. For non-ghost particles: when a_onlyValidRegion is true, only those whose cell lies inside the leaf's own grid box are claimed and out-of-box strays are left untouched; when false, every non-ghost particle is claimed. The region test is purely geometric on the ungrown patch box (it does not consider finer-level coverage or GhostType). No MPI communication.

Parameters
[in]a_onlyValidRegionRestrict to non-ghost particles inside the leaf's grid box.

◆ clearGhostParticles()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::clearGhostParticles ( )
inline

Remove every ghost particle (any non-Valid GhostType) from all levels and patches.

Owned (Valid) particles are left untouched. Removal is by swap-and-pop, so particle order within a leaf is not preserved. Keeps leaf capacity.

◆ copyMaskParticles() [1/2]

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::copyMaskParticles ( const int  a_level,
const LevelData< BaseFab< bool > > &  a_mask 
)
inline

Copy the valid particles whose cell the mask marks true into the mask holder, one level.

Clears the level's mask leaves, then COPIES (keeps in the valid holder) every valid particle whose cell is true in the mask. Ids/rank are preserved.

Parameters
[in]a_levelLevel to fill.
[in]a_maskPer-cell boolean mask over that level's valid grids (box == grid box).

◆ copyMaskParticles() [2/2]

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::copyMaskParticles ( const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &  a_mask)
inline

Copy the valid particles selected by a per-cell mask into the mask holder, all levels.

Parameters
[in]a_maskPer-level cell masks (skipped where null).

◆ define()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
void ParticleContainer< P, Traits >::define ( const Vector< DisjointBoxLayout > &  a_grids,
const Vector< ProblemDomain > &  a_domains,
const Vector< Real > &  a_dx,
const Vector< int > &  a_refRat,
const RealVect &  a_probLo,
const int  a_minBlockSize,
const Vector< RefCountedPtr< LevelTiles > > &  a_levelTiles,
const int  a_finestLevel,
const std::string &  a_realm,
const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > *  a_validCells 
)
inline

Allocate the per-level holders and the per-level tile-ownership maps over the AMR grids.

Allocates one empty Leaf per box for the valid, mask, and buffer holders on every level in [0, a_finestLevel], and builds a LevelTiles per level (from the grids + blocking factor) used by remap() to map a particle to its owning patch/rank. The mask and buffer holders start empty; they are populated on demand by copyMaskParticles()/transferMaskParticles() and the deposition routines. Must be called once before any other operation.

Parameters
[in]a_gridsPer-level DisjointBoxLayouts.
[in]a_domainsPer-level problem domains.
[in]a_dxPer-level (isotropic) grid spacing.
[in]a_refRatPer-level refinement ratio (entry l is the ratio between level l and l+1).
[in]a_probLoLower-left corner of the physical domain.
[in]a_minBlockSizeGrid blocking factor (tile size); the grids must be unions of minBlockSize-sized boxes for the tile ownership to be exact.
[in]a_levelTilesThe owning Realm's per-level tile->box maps, aliased (never built locally) as the patch-locating structure used by remap(). Must correspond to a_grids. Not owned; must outlive this container.
[in]a_finestLevelFinest AMR level index.
[in]a_realmRealm label (diagnostics only).
[in]a_validCellsOptional alias to the realm's valid-cell mask (true = cell not covered by a finer level), enabling remap()'s stayer fast path. Pass nullptr to always re-pool every particle. Not owned; must outlive this container.

◆ distributeFromPool()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::distributeFromPool ( MoverPool a_pool,
const bool  a_setOwnerToReceiver 
)
inlineprotected

Assign a pool into the valid holders: local appends + MPI scatter.

Parameters
[in,out]a_poolPer-rank pool (consumed). Same-rank bins are catenated into the destination leaf; cross-rank bins are linearized and Alltoallv'd.
[in]a_setOwnerToReceiverIf true, every cross-rank particle's rankID is set to the receiving rank (remap/regrid ownership). If false, the rankID carried in the pool is preserved (ghost particles keep their owner).

◆ fillGhostParticles()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::fillGhostParticles ( const AMRParticleGhostMask a_maskSame,
const AMRParticleGhostMask a_maskCoarToFine,
const AMRParticleGhostMask a_maskFineToCoar 
)
inline

Fill each patch's ghost halo from prebuilt Realm particle ghost masks.

A ghost particle is a transient, non-owned copy of a particle that lives in an adjacent region (a neighbouring patch on the same level, the next-coarser level, or the next-finer level) and overlaps this patch's ghosted box. For every valid particle, this scatters a copy to each destination patch listed by the masks for the particle's cell: same-level targets from a_maskSame, next-finer targets from a_maskCoarToFine, and next-coarser targets from a_maskFineToCoar. Copies are appended into the destination leaf (same-rank directly, cross-rank via MPI), tagged with the GhostType from the receiver's view (SameLevel / Coarse / Fine) so consumers can tell them from owned particles via ParticleSoA::isGhost(), and keep the source's particleID. clearGhostParticles() is called first so it is safe to refill; ghosts are transient (remap()/preRegrid()/regrid() drop them). Pass AmrMesh::getTrivialParticleGhostMask() for a direction that should not scatter. The masks must have been built on the same grids as this container (see AmrMesh::registerParticleGhostMask and AmrMesh::getParticleGhostMask(realm, width)). Periodic domains are not supported (mask construction aborts on them).

Parameters
[in]a_maskSameSame-level ghost mask (source cell -> same-level target boxes).
[in]a_maskCoarToFineCoarse-to-fine ghost mask (source cell -> next-finer target boxes).
[in]a_maskFineToCoarFine-to-coarse ghost mask (source cell -> next-coarser target boxes).

◆ findDestination()

template<typename P , typename Traits >
LevelTiles::LevelAndBox ParticleContainer< P, Traits >::findDestination ( const RealVect &  a_pos) const
inline

Map a position to its owning (level, grid index, rank) via the finest containing tile.

Thin wrapper over the shared LevelTiles::findDestination point->block core, passing this container's aliased grid metadata (probLo, dx, minBlockSize, level tiles). Public because the distributed nearest-neighbor particle merge (ParticleManagement::mergeNearestNeighborsTree) locates each newly created merged particle's owning patch/rank through the SAME tile-hash query remap() uses internally, rather than a linear scan over patches – see PositionLocator in CD_NearestNeighborParticleMerge.H.

Parameters
[in]a_posParticle position.
Returns
The resolved destination; valid==false if no tile on any level owns the cell.

◆ gatherGhostsFromMasks()

template<typename P , typename Traits >
ParticleContainer< P, Traits >::MoverPool ParticleContainer< P, Traits >::gatherGhostsFromMasks ( const AMRParticleGhostMask a_maskSame,
const AMRParticleGhostMask a_maskCoarToFine,
const AMRParticleGhostMask a_maskFineToCoar 
)
inlineprotected

Gather ghost copies into a per-rank pool using prebuilt particle ghost masks.

For each valid particle, reads its cell's target boxes from the three masks and bins a copy per (destination level, grid index, rank) with the GhostType from the receiver's view (SameLevel / Coarse / Fine); particleID preserved, rankID set to this rank (the owner). Distribute the returned pool with a_setOwnerToReceiver == false. A trivial (empty) mask contributes nothing.

Parameters
[in]a_maskSameSame-level mask.
[in]a_maskCoarToFineCoarse-to-fine mask (targets on the next-finer level).
[in]a_maskFineToCoarFine-to-coarse mask (targets on the next-coarser level).
Returns
The per-rank ghost pool.

◆ gatherMoversToPool()

template<typename P , typename Traits >
ParticleContainer< P, Traits >::MoverPool ParticleContainer< P, Traits >::gatherMoversToPool ( )
inlineprotected

Mask fast path for remap(): pool ONLY the movers, leaving stayers in place.

Scans m_particles in place; a particle still inside its box AND in a cell flagged valid by m_validCells (not covered by a finer level) is a stayer and is left untouched. Every other particle is a mover: it is copied into the returned pool (ids preserved, rankID set to the new owner) and swap-popped out of its leaf. Off-domain movers are counted into m_numOutcastLocal (reset here). Requires m_validCells to be non-null and sized to m_finestLevel+1 (the caller checks this).

Returns
The per-rank mover pool; stayers remain in m_particles (so distributeFromPool must append, not assume empty destinations, and remap() must NOT clearParticles() on this path).

◆ gatherToPool()

template<typename P , typename Traits >
ParticleContainer< P, Traits >::MoverPool ParticleContainer< P, Traits >::gatherToPool ( AMRParticlesSoA< P, Traits > &  a_source,
const Vector< DisjointBoxLayout > &  a_sourceGrids 
)
inlineprotected

Gather every particle of a source holder into a per-rank, per-destination-patch pool.

Reads each particle, resolves its owning (level, grid index, rank) on the CURRENT tile maps, and copies it into the pool (ids preserved, rankID set to the new owner). Off-domain particles are counted into m_numOutcastLocal (which this resets).

Parameters
[in]a_sourceSource holders (e.g. the valid particles, or the regrid cache).
[in]a_sourceGridsThe DisjointBoxLayouts the source holders are defined on.
Returns
The per-rank mover pool.

◆ getBufferParticles() [1/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
AMRParticlesSoA< P, Traits > & ParticleContainer< P, Traits >::getBufferParticles ( )
inline

The grown-grid buffer particles on all levels.

Returns
Mutable per-level holder vector.

◆ getBufferParticles() [2/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const AMRParticlesSoA< P, Traits > & ParticleContainer< P, Traits >::getBufferParticles ( ) const
inline

The grown-grid buffer particles on all levels (const).

Returns
Const per-level holder vector.

◆ getDx()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
Vector< RealVect > ParticleContainer< P, Traits >::getDx ( ) const
inline

Per-level grid spacing.

Returns
The (isotropic) grid spacing per level, as RealVects.

◆ getFinestLevel()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
int ParticleContainer< P, Traits >::getFinestLevel ( ) const
inline

Finest AMR level index.

Returns
The finest level.

◆ getGrids()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const Vector< DisjointBoxLayout > & ParticleContainer< P, Traits >::getGrids ( ) const
inline

Per-level AMR grids.

Returns
The DisjointBoxLayouts, one per level.

◆ getGrownGrids()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const Vector< BoxLayout > & ParticleContainer< P, Traits >::getGrownGrids ( ) const
inline

Per-level grown grids that the buffer particles live on.

Returns
The grown BoxLayouts (boxes grown by the refinement factor on finer levels).

◆ getMaskParticles() [1/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
AMRParticlesSoA< P, Traits > & ParticleContainer< P, Traits >::getMaskParticles ( )
inline

The halo/mask particles on all levels.

Returns
Mutable per-level holder vector.

◆ getMaskParticles() [2/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const AMRParticlesSoA< P, Traits > & ParticleContainer< P, Traits >::getMaskParticles ( ) const
inline

The halo/mask particles on all levels (const).

Returns
Const per-level holder vector.

◆ getNumberOfOutcastParticlesGlobal()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
unsigned long long ParticleContainer< P, Traits >::getNumberOfOutcastParticlesGlobal ( ) const
inline

Number of particles dropped off-domain by the most recent remap(), across all ranks.

Returns
Global outcast count from the last remap (== local in serial).

◆ getNumberOfOutcastParticlesLocal()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
unsigned long long ParticleContainer< P, Traits >::getNumberOfOutcastParticlesLocal ( ) const
inline

Number of particles dropped off-domain by the most recent remap() on this rank.

Returns
Local outcast count from the last remap.

◆ getNumberOfValidParticlesGlobal()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
unsigned long long ParticleContainer< P, Traits >::getNumberOfValidParticlesGlobal ( ) const
inline

Number of valid particles across all ranks.

Returns
Global valid particle count (MPI all-reduce of the local count; == local in serial).

◆ getNumberOfValidParticlesLocal()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
unsigned long long ParticleContainer< P, Traits >::getNumberOfValidParticlesLocal ( ) const
inline

Number of valid particles owned by this rank.

Ghost particles (any non-Valid GhostType) are excluded – only owned, valid particles are counted, even if a transient ghost halo is currently present in the leaves.

Returns
Local valid particle count summed over all levels and patches.

◆ getParticles() [1/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
AMRParticlesSoA< P, Traits > & ParticleContainer< P, Traits >::getParticles ( )
inline

The valid particles on all levels.

Returns
Mutable per-level holder vector.

◆ getParticles() [2/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const AMRParticlesSoA< P, Traits > & ParticleContainer< P, Traits >::getParticles ( ) const
inline

The valid particles on all levels (const).

Returns
Const per-level holder vector.

◆ getProbLo()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
RealVect ParticleContainer< P, Traits >::getProbLo ( ) const
inline

Lower-left corner of the physical domain.

Returns
The probLo corner.

◆ getRealm()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
std::string ParticleContainer< P, Traits >::getRealm ( ) const
inline

Realm label.

Returns
The realm string.

◆ inValidBox()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
bool ParticleContainer< P, Traits >::inValidBox ( const int  a_lvl,
const Box &  a_box,
const RealVect &  a_pos 
) const
inlineprotected

True if a position's cell lies inside a (grid) box on a given level.

Purely geometric valid-region test shared by claimOwnership/resetParticleIDs – the box is the leaf's ungrown patch box, so a particle in its patch's ghost shell tests false.

Parameters
[in]a_lvlLevel index.
[in]a_boxBox (typically the leaf's grid box).
[in]a_posPosition.
Returns
True if cellIndex(a_lvl, a_pos) is contained in a_box.

◆ isDefined()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
bool ParticleContainer< P, Traits >::isDefined ( ) const
inline

Whether define() has been called.

Returns
True iff defined.

◆ isOrganizedByCell()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
bool ParticleContainer< P, Traits >::isOrganizedByCell ( ) const
inline

Whether the valid leaves are currently cell-sorted.

Returns
True if organizeParticlesByCell() is in effect, false after organizeParticlesByPatch().

◆ operator=()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
ParticleContainer & ParticleContainer< P, Traits >::operator= ( const ParticleContainer< P, Traits > &  )
delete

Copy assignment is deleted (move-only ownership).

Returns
Reference to this.

◆ operator[]() [1/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
LevelParticles & ParticleContainer< P, Traits >::operator[] ( const int  a_lvl)
inline

Valid particles on one level (index by DataIndex to reach a patch's Leaf).

Chain a second index by DataIndex to reach the patch's ParticleSoA leaf:

ParticleSoA<P>& leaf = particles[lvl][din];
Parameters
[in]a_lvlLevel index.
Returns
Mutable per-level holder; operator[](DataIndex) yields the patch's ParticleSoA.

◆ operator[]() [2/2]

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const LevelParticles & ParticleContainer< P, Traits >::operator[] ( const int  a_lvl) const
inline

Valid particles on one level (const).

Parameters
[in]a_lvlLevel index.
Returns
Const per-level holder.

◆ organizeParticlesByCell()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
void ParticleContainer< P, Traits >::organizeParticlesByCell ( )
inline

Cell-sort every valid leaf (counting sort into Fortran cell order + CSR cell offsets).

After this, each leaf is isSorted() and cell c owns the contiguous particle range [cellStart(c), cellStart(c+1)) (query via the leaf accessors). Sets isOrganizedByCell().

◆ organizeParticlesByPatch()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
void ParticleContainer< P, Traits >::organizeParticlesByPatch ( )
inline

Return to a by-patch view (the leaves remain a single contiguous array per patch).

Clears isOrganizedByCell(); the CSR cell offsets are no longer to be relied upon. There is no data movement – the leaf already holds all particles of a patch contiguously.

◆ preRegrid()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::preRegrid ( )
inline

Cache the current valid particles ahead of a regrid.

Snapshots the current per-level holders (and their layout) so that regrid() can rebuild over a new layout and redistribute the cached particles. Call exactly once before regrid().

◆ regrid()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::regrid ( const Vector< DisjointBoxLayout > &  a_grids,
const Vector< ProblemDomain > &  a_domains,
const Vector< Real > &  a_dx,
const Vector< int > &  a_refRat,
const int  a_minBlockSize,
const Vector< RefCountedPtr< LevelTiles > > &  a_levelTiles,
const int  a_newFinestLevel 
)
inline

Rebuild over a new AMR layout and redistribute the preRegrid()-cached particles onto it.

Re-allocates the per-level holders and tile maps over the new grids (all levels), then runs the same pool->map->scatter as remap() but sourced from the cache. Positions are unchanged; each cached particle is routed to the patch/level/rank owning its cell on the NEW layout, with ids preserved. Off-domain particles are counted in getNumberOfOutcastParticles*(). Must follow a preRegrid().

Parameters
[in]a_gridsNew per-level DisjointBoxLayouts.
[in]a_domainsNew per-level problem domains.
[in]a_dxNew per-level (isotropic) grid spacing.
[in]a_refRatNew per-level refinement ratios.
[in]a_minBlockSizeGrid blocking factor (tile size) for the new grids.
[in]a_levelTilesThe owning Realm's per-level tile->box maps for the new grids, aliased (never built locally). Must correspond to a_grids.
[in]a_newFinestLevelNew finest AMR level index.

◆ remap()

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::remap ( )
inline

Redistribute every valid particle to the patch/level/rank that owns its cell.

Pool model: collect all valid particles, map each to its destination via the finest-level tile that contains it (LevelTiles), append same-rank movers into the destination leaf and scatter cross-rank movers with MPI. Particles whose cell is not owned by any tile on any level (off-domain) are dropped and counted in getNumberOfOutcastParticles*(). Invalidates any cell-sort. Particle ids are preserved; rankID is set to the new owning rank.

◆ resetParticleIDs()

template<typename P , typename Traits >
long long ParticleContainer< P, Traits >::resetParticleIDs ( const bool  a_onlyValidRegion,
const ParticleID  a_startID 
)
inline

Assign globally-unique, contiguous particle IDs to the owned particles.

Ghost particles (isGhost()) are always left untouched, so a ghost keeps the source's id. A non-ghost particle qualifies for a new id iff a_onlyValidRegion is false OR its cell lies inside the leaf's own grid box; a non-ghost that does not qualify (an out-of-box stray, only possible when a_onlyValidRegion is true) is set to ParticleSoA::s_invalidID. Qualifying particles receive contiguous ids in rank order (rank 0 first) starting at a_startID, made unique across ranks via an all-gather of the per-rank counts and an exclusive prefix. The region test is purely geometric on the ungrown patch box. Note: the assigned ids are a numbering snapshot, not a persistent identity – they depend on the rank/box ordering and change across regrids and different rank counts.

Parameters
[in]a_onlyValidRegionRestrict new ids to non-ghost particles inside the leaf's grid box.
[in]a_startIDGlobal id of the first assigned particle; ids occupy [a_startID, a_startID + return).
Returns
The global number of ids assigned (across all ranks).

◆ transferMaskParticles() [1/2]

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::transferMaskParticles ( const int  a_level,
const LevelData< BaseFab< bool > > &  a_mask 
)
inline

Move the valid particles whose cell the mask marks true into the mask holder, one level.

Like copyMaskParticles but MOVES (removes from the valid holder via swap-and-pop, which does not preserve order). Does not clear the mask holder first (accumulates). Ids/rank preserved.

Parameters
[in]a_levelLevel to fill.
[in]a_maskPer-cell boolean mask over that level's valid grids (box == grid box).

◆ transferMaskParticles() [2/2]

template<typename P , typename Traits >
void ParticleContainer< P, Traits >::transferMaskParticles ( const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &  a_mask)
inline

Move the valid particles selected by a per-cell mask into the mask holder, all levels.

Parameters
[in]a_maskPer-level cell masks (skipped where null).

◆ transferParticles()

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
void ParticleContainer< P, Traits >::transferParticles ( AMRParticlesSoA< P, Traits > &  a_source)
inline

Move all particles from another holder (on the same valid grids) into the valid holder.

Per level/patch, catenates the source leaf into the valid leaf (a per-column bulk move preserving ids/rank, or an O(1) arena swap when the valid leaf is empty), leaving the source empty. Used to return halo/mask particles to the valid holder after a HaloNGP deposition. Assumes a_source is defined over this container's valid grids.

Parameters
[in,out]a_sourceHolder to drain into the valid particles.

Member Data Documentation

◆ m_validCells

template<typename P = NoPayload, typename Traits = ParticleTraits<P>>
const Vector<RefCountedPtr<LevelData<BaseFab<bool> > > >* ParticleContainer< P, Traits >::m_validCells = nullptr
protected

Optional alias to the realm's valid-cell mask (true = cell not covered by a finer level).

Used by remap() to leave "stayer" particles in place: a particle still inside its box and in a cell not covered by a finer grid cannot change owner, so it need not be re-pooled. Null (or a stale size) makes remap() fall back to re-pooling every particle. Aliases a stable Realm member that is rebuilt each regrid; set at define(), never owned here.


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