12#ifndef CD_ParticleContainerImplem_H
13#define CD_ParticleContainerImplem_H
22#include <ParticleDataI.H>
31#include <CD_NamespaceHeader.H>
37 m_isOrganizedByCell =
false;
55 CH_TIME(
"ParticleContainer::ParticleContainer");
72 CH_TIME(
"ParticleContainer::~ParticleContainer");
88 CH_TIME(
"ParticleContainer::~ParticleContainer");
100 m_dx.resize(1 + m_finestLevel);
101 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
105 constexpr int base = 0;
108 this->setupGrownGrids(
base, m_finestLevel);
109 this->setupParticleData(
base, m_finestLevel);
112 m_isOrganizedByCell =
false;
116 pp.query(
"profile", m_profile);
117 pp.query(
"debug", m_debug);
118 pp.query(
"verbose", m_verbose);
125 CH_TIME(
"ParticleContainer::setupGrownGrids");
127 pout() <<
"ParticleContainer::setupGrownGrids" <<
endl;
142 for (
auto& box :
boxes.stdVector()) {
143 box.grow(m_refRat[
lvl - 1]);
156 CH_TIME(
"ParticleContainer::setupParticleData");
158 pout() <<
"ParticleContainer::setupParticleData" <<
endl;
199 CH_TIME(
"ParticleContainer::sortParticles");
201 pout() <<
"ParticleContainer::sortParticles" <<
endl;
204 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
211#pragma omp parallel for schedule(runtime)
226 return m_isOrganizedByCell;
235 return m_finestLevel;
274 if (m_isOrganizedByCell) {
275 MayDay::Error(
"ParticleContainer::getParticles - particles are sorted by cell!");
287 if (m_isOrganizedByCell) {
288 MayDay::Abort(
"ParticleContainer::getParticles - particles are sorted by cell!");
300 return m_bufferParticles;
309 return m_bufferParticles;
318 return m_maskParticles;
327 return m_maskParticles;
336 if (m_isOrganizedByCell) {
337 MayDay::Error(
"ParticleContainer::operator[](a_lvl) - particles are sorted by cell!");
349 if (m_isOrganizedByCell) {
350 MayDay::Error(
"ParticleContainer::operator[](a_lvl) - particles are sorted by cell!");
362 if (!m_isOrganizedByCell) {
363 MayDay::Error(
"ParticleContainer::getCellParticles()- particles are not sorted by cell!");
366 return m_cellSortedParticles;
375 if (!m_isOrganizedByCell) {
376 MayDay::Error(
"ParticleContainer::getCellParticles()- particles are not sorted by cell!");
379 return m_cellSortedParticles;
388 if (!m_isOrganizedByCell) {
389 MayDay::Error(
"ParticleContainer::getCellParticles(level)- particles are not sorted by cell!");
392 return *m_cellSortedParticles[
a_level];
399 CH_TIME(
"ParticleContainer::getCellParticles(int)");
403 if (!m_isOrganizedByCell) {
404 MayDay::Error(
"ParticleContainer::getCellParticles(level)- particles are not sorted by cell!");
407 return *m_cellSortedParticles[
a_level];
414 CH_TIME(
"ParticleContainer::getCellParticles(BinFab)");
418 if (!m_isOrganizedByCell) {
419 MayDay::Error(
"ParticleContainer::getCellParticles - particles are not sorted by cell!");
430 CH_TIME(
"ParticleContainer::getCellParticlesDestructive");
434 if (!m_isOrganizedByCell) {
435 MayDay::Error(
"ParticleContainer::getCellParticlesDestructive - particles are not sorted by cell!");
446 CH_TIME(
"ParticleContainer::getCellParticles(int, DataIndex)");
450 if (!m_isOrganizedByCell) {
451 MayDay::Error(
"ParticleContainer::getCellParticles(int, dit) - particles are not sorted by cell!");
461 CH_TIME(
"ParticleContainer::getCellParticles(int, DataIndex)");
465 if (!m_isOrganizedByCell) {
466 MayDay::Error(
"ParticleContainer::getCellParticles(int, dit) - particles are not sorted by cell!");
476 CH_TIME(
"ParticleContainer::organizeParticlesByCell");
478 pout() <<
"ParticleContainer::organizeParticlesByCell" <<
endl;
483 if (!m_isOrganizedByCell) {
491#pragma omp parallel for schedule(runtime)
502 m_isOrganizedByCell =
true;
510 CH_TIME(
"ParticleContainer::organizeParticlesByPatch");
512 pout() <<
"ParticleContainer::organizeParticlesByPatch" <<
endl;
517 if (m_isOrganizedByCell) {
519 constexpr int comp = 0;
521 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
527#pragma omp parallel for schedule(runtime)
545 m_isOrganizedByCell =
false;
553 CH_TIME(
"ParticleContainer::addParticles");
555 pout() <<
"ParticleContainer::addParticles" <<
endl;
560 if (m_isOrganizedByCell) {
561 MayDay::Error(
"ParticleContainer::addParticles(List<P>) - particles are sorted by cell!");
619 CH_TIME(
"ParticleContainer::addParticlesDestructive");
621 pout() <<
"ParticleContainer::addParticlesDestructive" <<
endl;
626 if (m_isOrganizedByCell) {
627 MayDay::Error(
"ParticleContainer::addParticlesDestructive(List<P>) - particles are sorted by cell!");
685 CH_TIME(
"ParticleContainer::addParticles(BinFab)");
687 pout() <<
"ParticleContainer::addParticles(BinFab)" <<
endl;
693 if (!m_isOrganizedByCell) {
694 MayDay::Abort(
"ParticleContainer::addParticles(BinFab<P>) - particles are not sorted by cell!");
697 constexpr int comp = 0;
715 CH_TIME(
"ParticleContainer::addParticlesDestructive(BinFab)");
717 pout() <<
"ParticleContainer::addParticlesDestructive(BinFab)" <<
endl;
723 if (!m_isOrganizedByCell) {
724 MayDay::Error(
"ParticleContainer::addParticles(BinFab<P>) - particles are not sorted by cell!");
727 constexpr int comp = 0;
745 CH_TIME(
"ParticleContainer::addParticles(ParticleContainer)");
747 pout() <<
"ParticleContainer::addParticles(ParticleContainer)" <<
endl;
752 if (m_isOrganizedByCell) {
753 MayDay::Error(
"ParticleContainer::addParticles(ParticleContainer<P>) - particles are sorted by cell!");
760 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
766#pragma omp parallel for schedule(runtime)
829 CH_TIME(
"ParticleContainer::addParticlesDestructive(ParticleContainer)");
831 pout() <<
"ParticleContainer::addParticlesDestructive(ParticleContainer)" <<
endl;
839 if (m_isOrganizedByCell) {
840 MayDay::Error(
"ParticleContainer::addParticles(ParticleContainer<P>) - particles are sorted by cell!");
847 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
853#pragma omp parallel for schedule(runtime)
916 CH_TIME(
"ParticleContainer::transferParticles");
921 if (m_isOrganizedByCell) {
922 MayDay::Error(
"ParticleContainer::transferParticles(ParticleContainer<P>) - particles are sorted by cell!");
926 MayDay::Error(
"ParticleContainer::transferParticles(ParticleContainer<P>) - other particles are sorted by cell!");
931 "ParticleContainer::transferParticles(ParticleContainer<P>) - other container defined over a different realm");
941 CH_TIME(
"ParticleContainer::transferParticles(AMRParticles)");
943 pout() <<
"ParticleContainer::transferParticle(AMRParticles)" <<
endl;
948 if (m_isOrganizedByCell) {
949 MayDay::Error(
"ParticleContainer::transferParticles(ParticleContainer<P>) - particles are sorted by cell!");
953 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
959#pragma omp parallel for schedule(runtime)
975 CH_TIME(
"ParticleContainer<P>::remap");
977 pout() <<
"ParticleContainer::remap" <<
endl;
1032 this->sanityCheck();
1036template <
typename P>
1040 CH_TIME(
"ParticleContainer::sanityCheck");
1042 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1055 MayDay::Error(
"ParticleContainer::remap -- error2: particle is not contained in grid box!");
1062template <
typename P>
1066 CH_TIME(
"ParticleContainer::transferParticlesToSingleList");
1074#pragma omp for schedule(runtime)
1085template <
typename P>
1089 CH_TIME(
"ParticleContainer::copyParticlesToSingleList");
1097#pragma omp for schedule(runtime)
1108template <
typename P>
1113 CH_TIME(
"ParticleContainer::mapParticlesToAMRGrid");
1120 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1167template <
typename P>
1172 CH_TIME(
"ParticleContainer::catenateParticleMaps");
1187template <
typename P>
1192 CH_TIME(
"ParticleContainer::assignLocalParticles");
1199#pragma omp task firstprivate(mapIter)
1221 CH_TIME(
"ParticleContainer::preRegrid");
1223 pout() <<
"ParticleContainer::preRegrid" <<
endl;
1230 if (m_isOrganizedByCell) {
1231 MayDay::Error(
"ParticleContainer::preRegrid - particles are sorted by cell!");
1235 m_cacheParticles.resize(1 + m_finestLevel);
1237 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1246#pragma omp parallel for schedule(runtime)
1262 CH_TIME(
"ParticleContainer::resetParticleIDs");
1264 pout() <<
"ParticleContainer::resetParticleIDs" <<
endl;
1268 if (m_isOrganizedByCell) {
1269 MayDay::Error(
"ParticleContainer::preRegrid - particles are sorted by cell!");
1276 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1282#pragma omp parallel for schedule(runtime)
1307 CH_TIME(
"ParticleContainer::regrid");
1309 pout() <<
"ParticleContainer::regrid" <<
endl;
1315 if (m_isOrganizedByCell) {
1316 MayDay::Error(
"ParticleContainer::regrid(...) - particles are sorted by cell!");
1327 m_dx.resize(1 + m_finestLevel);
1328 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1332 this->setupGrownGrids(
a_lmin, m_finestLevel);
1333 this->setupParticleData(
a_lmin, m_finestLevel);
1353 this->transferParticlesToSingleList(
outcasts, m_cacheParticles);
1378 this->sanityCheck();
1382 m_cacheParticles.resize(0);
1386template <Real& (P::*particleScalarField)()>
1390 CH_TIME(
"ParticleContainer::setValue");
1392 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1398#pragma omp parallel for schedule(runtime)
1414template <RealVect& (P::*particleVectorField)()>
1418 CH_TIME(
"ParticleContainer::setValue");
1420 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1426#pragma omp parallel for schedule(runtime)
1445 CH_TIME(
"ParticleContainer::getNumberOfValidParticlesLocal");
1449 unsigned long long n = 0;
1451 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1457#pragma omp parallel for schedule(runtime) reduction(+ : n)
1474 CH_TIME(
"ParticleContainer::getNumberOfValidParticlesGlobal");
1478 const unsigned long long n = this->getNumberOfValidParticlesLocal();
1487 CH_TIME(
"ParticleContainer::getNumberOfOutcastParticlesLocal");
1491 unsigned long long n = 0;
1493 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1499#pragma omp parallel for schedule(runtime) reduction(+ : n)
1516 CH_TIME(
"ParticleContainer::getNumberOfOutcastParticlesGlobal");
1520 const unsigned long long n = this->getNumberOfOutcastParticlesLocal();
1529 CH_TIME(
"ParticleContainer::getNumberOfMaskParticlesLocal");
1533 unsigned long long n = 0;
1535 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1541#pragma omp parallel for schedule(runtime) reduction(+ : n)
1558 CH_TIME(
"ParticleContainer::getNumberOfMaskParticlesGlobal");
1562 const unsigned long long n = this->getNumberOfMaskParticlesLocal();
1571 CH_TIME(
"ParticleContainer::copyMaskParticles(amr)");
1575 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1586 CH_TIME(
"ParticleContainer::copyMaskParticles(level)");
1588 pout() <<
"ParticleContainer::copyMaskParticles(level)" <<
endl;
1593 m_maskParticles[
a_level]->clear();
1603#pragma omp parallel for schedule(runtime)
1609 if (
mask.isUsable()) {
1625 MayDay::Error(
"ParticleContainer::copyMaskParticles -- logic bust. Particle has fallen off grid");
1639 CH_TIME(
"ParticleContainer::transferMaskParticles(amr)");
1643 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1654 CH_TIME(
"ParticleContainer::transferMaskParticles(level)");
1656 pout() <<
"ParticleContainer::transferMaskParticles(level)" <<
endl;
1669#pragma omp parallel for schedule(runtime)
1675 if (
mask.isUsable()) {
1691 MayDay::Warning(
"ParticleContainer::transferMaskParticles -- logic bust. Particle has fallen off grid");
1723 this->clear(m_bufferParticles);
1732 this->clear(m_maskParticles);
1741 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1755 pout() <<
"ParticleContainer::clear(AMRParticles)" <<
endl;
1760 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1770#pragma omp parallel for schedule(runtime)
1785#include <CD_NamespaceFooter.H>
Declaration of a namespace for proto-typing grid and EB loops.
Declaration of various useful OpenMP-related utilities.
Agglomeration of basic MPI reductions.
Declaration of a class for holding particles on an AMR hierarchy.
Declaration of a static class containing some common useful particle routines that would otherwise be...
Implementation of CD_Timer.H.
AMRCellParticles< P > & getCellParticles()
Get all cell particles.
Definition CD_ParticleContainerImplem.H:358
void getCellParticlesDestructive(BinFab< P > &a_cellParticles, const int a_lvl, const DataIndex a_dit)
Fill a cell-sorted particle data holder with all the particles in the grid patch. The original partic...
Definition CD_ParticleContainerImplem.H:428
void organizeParticlesByPatch()
Sort particles by cell.
Definition CD_ParticleContainerImplem.H:508
const Vector< RealVect > getDx() const noexcept
Get grid resolutions.
Definition CD_ParticleContainerImplem.H:263
void clearMaskParticles() const
Clear the "mask" particles.
Definition CD_ParticleContainerImplem.H:1728
unsigned long long getNumberOfOutcastParticlesGlobal() const
Get global number of particles.
Definition CD_ParticleContainerImplem.H:1514
void setupParticleData(const int a_base, const int a_finestLevel)
Setup function for the particle data (m_particles and m_maskParticles)
Definition CD_ParticleContainerImplem.H:154
const RealVect getProbLo() const noexcept
Get lower-left corner.
Definition CD_ParticleContainerImplem.H:256
unsigned long long getNumberOfValidParticlesLocal() const
Get local number of particles.
Definition CD_ParticleContainerImplem.H:1443
void setValue(const Real a_value)
Set the particle member to the input value.
Definition CD_ParticleContainerImplem.H:1388
void preRegrid(const int a_base)
Cache particles before calling regrid.
Definition CD_ParticleContainerImplem.H:1219
void define(const Vector< DisjointBoxLayout > &a_grids, const Vector< ProblemDomain > &a_domains, const Vector< Real > &a_dx, const Vector< int > &a_refRat, const Vector< ValidMask > &a_validMask, const Vector< RefCountedPtr< LevelTiles > > &a_levelTiles, const RealVect &a_probLo, const int a_blockingFactor, const int a_finestLevel, const std::string a_realm)
Define the container. This will do a clear-out of all particles.
Definition CD_ParticleContainerImplem.H:77
virtual ~ParticleContainer()
Destructor ( does nothing)
Definition CD_ParticleContainerImplem.H:70
void sortParticles() noexcept
Sort particles according to the < operator in the particle.
Definition CD_ParticleContainerImplem.H:197
const Vector< DisjointBoxLayout > & getGrids() const
Get the AMR grids.
Definition CD_ParticleContainerImplem.H:249
unsigned long long getNumberOfOutcastParticlesLocal() const
Get local number of particles.
Definition CD_ParticleContainerImplem.H:1485
ParticleData< P > & operator[](const int a_level)
Get particle data on a level.
Definition CD_ParticleContainerImplem.H:332
void addParticles(const List< P > &a_particles)
Add particles to container.
Definition CD_ParticleContainerImplem.H:551
void setupGrownGrids(const int a_base, const int a_finestLevel)
Set up grown grids.
Definition CD_ParticleContainerImplem.H:123
unsigned long long getNumberOfMaskParticlesGlobal() const
Get the number particles in the halo cells.
Definition CD_ParticleContainerImplem.H:1556
void clear(AMRParticles< P > &a_particles) const
Clear particles on input data holder.
Definition CD_ParticleContainerImplem.H:1752
void remap()
Remap over the entire AMR hierarchy.
Definition CD_ParticleContainerImplem.H:973
void clearParticles()
Clear all particles.
Definition CD_ParticleContainerImplem.H:1710
void clearOutcast() noexcept
Clear outcast particles.
Definition CD_ParticleContainerImplem.H:1737
void catenateParticleMaps(std::vector< ParticleMap< List< P > > > &a_globalParticles, std::vector< ParticleMap< List< P > > > &a_localParticles) const noexcept
Catenate the particles. This is usually called within OpenMP parallel regions.
Definition CD_ParticleContainerImplem.H:1169
unsigned long long getNumberOfMaskParticlesLocal() const
Get the number particles in the halo cells.
Definition CD_ParticleContainerImplem.H:1527
void organizeParticlesByCell()
Sort particles by cell.
Definition CD_ParticleContainerImplem.H:474
void mapParticlesToAMRGrid(std::vector< ParticleMap< List< P > > > &a_mappedParticles, List< P > &a_unmappedParticles) const noexcept
Iterate through the unmapped particles and map them to proper level, grid indices,...
Definition CD_ParticleContainerImplem.H:1110
int getFinestLevel() const
Get finest AMR level.
Definition CD_ParticleContainerImplem.H:231
void clearBufferParticles() const
Clear the buffer particles.
Definition CD_ParticleContainerImplem.H:1719
void assignLocalParticles(ParticleMap< List< P > > &a_mappedParticles, AMRParticles< P > &a_particleData) const noexcept
Gather particles locally.
Definition CD_ParticleContainerImplem.H:1189
const std::string getRealm() const
Get the realm where this ParticleContainer lives.
Definition CD_ParticleContainerImplem.H:240
void transferParticlesToSingleList(List< P > &a_list, AMRParticles< P > &a_particles) const noexcept
Gather the particles onto a single list.
Definition CD_ParticleContainerImplem.H:1064
bool isOrganizedByCell() const
Is cell-sorted or not.
Definition CD_ParticleContainerImplem.H:224
void transferMaskParticles(const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_mask)
Copy particles to the mask particle data holder.
Definition CD_ParticleContainerImplem.H:1637
void copyParticlesToSingleList(List< P > &a_list, const AMRParticles< P > &a_particles) const noexcept
Copy the input particles onto a single list.
Definition CD_ParticleContainerImplem.H:1087
ParticleContainer()
Default constructor. Leaves object in undefined state.
Definition CD_ParticleContainerImplem.H:34
void sanityCheck() const noexcept
Run a sanity check and make sure all particles are in their correctly assigned box.
Definition CD_ParticleContainerImplem.H:1038
AMRParticles< P > & getMaskParticles()
Get the mask particles.
Definition CD_ParticleContainerImplem.H:314
unsigned long long getNumberOfValidParticlesGlobal() const
Get global number of particles.
Definition CD_ParticleContainerImplem.H:1472
void resetParticleIDs() noexcept
Compute new particle IDs.
Definition CD_ParticleContainerImplem.H:1260
void addParticlesDestructive(List< P > &a_particles)
Add particles to container. The input particles are destroyed by this routine.
Definition CD_ParticleContainerImplem.H:617
AMRParticles< P > & getBufferParticles()
Get buffer particles on all levels.
Definition CD_ParticleContainerImplem.H:296
AMRParticles< P > & getParticles()
Get all particles on all levels.
Definition CD_ParticleContainerImplem.H:270
void transferParticles(ParticleContainer< P > &a_otherContainer)
Move particles into this container.
Definition CD_ParticleContainerImplem.H:914
void regrid(const Vector< DisjointBoxLayout > &a_grids, const Vector< ProblemDomain > &a_domains, const Vector< Real > &a_dx, const Vector< int > &a_refRat, const Vector< ValidMask > &a_validMask, const Vector< RefCountedPtr< LevelTiles > > &a_levelTiles, const int a_base, const int a_newFinestLevel)
Regrid function. a_base is the coarsest grid level which did not change.
Definition CD_ParticleContainerImplem.H:1298
void copyMaskParticles(const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_mask) const
Copy particles to mask particle data holder.
Definition CD_ParticleContainerImplem.H:1569
static IntVect getParticleCellIndex(const RealVect &a_particlePosition, const RealVect &a_probLo, const Real &a_dx) noexcept
Get the cell index corresponding to the particle position.
Definition CD_ParticleOpsImplem.H:30
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:37
ParticleContainer< P > m_particles
Computational particles.
Definition CD_TracerParticleSolver.H:405
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:25
std::string m_realm
Realm where this solver lives.
Definition CD_TracerParticleSolver.H:345
virtual ParticleContainer< P > & getParticles()
Get all particles.
Definition CD_TracerParticleSolverImplem.H:662
ALWAYS_INLINE void loop(const Box &a_computeBox, Functor &&kernel, const IntVect &a_stride=IntVect::Unit)
Launch a C++ kernel over a regular grid.
Definition CD_BoxLoopsImplem.H:20
Real sum(const Real &a_value) noexcept
Compute the sum across all MPI ranks.
Definition CD_ParallelOpsImplem.H:353