13#ifndef CD_PARTICLECONTAINERIMPLEM_H
14#define CD_PARTICLECONTAINERIMPLEM_H
23#include <ParticleDataI.H>
32#include <CD_NamespaceHeader.H>
49 CH_TIME(
"ParticleContainer::ParticleContainer");
66 CH_TIME(
"ParticleContainer::~ParticleContainer");
82 CH_TIME(
"ParticleContainer::~ParticleContainer");
94 m_dx.resize(1 + m_finestLevel);
95 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
99 constexpr int base = 0;
102 this->setupGrownGrids(
base, m_finestLevel);
103 this->setupParticleData(
base, m_finestLevel);
106 m_isOrganizedByCell =
false;
110 pp.query(
"profile", m_profile);
111 pp.query(
"debug", m_debug);
112 pp.query(
"verbose", m_verbose);
119 CH_TIME(
"ParticleContainer::setupGrownGrids");
121 pout() <<
"ParticleContainer::setupGrownGrids" <<
endl;
136 for (
auto& box :
boxes.stdVector()) {
137 box.grow(m_refRat[
lvl - 1]);
150 CH_TIME(
"ParticleContainer::setupParticleData");
152 pout() <<
"ParticleContainer::setupParticleData" <<
endl;
193 CH_TIME(
"ParticleContainer::sortParticles");
195 pout() <<
"ParticleContainer::sortParticles" <<
endl;
198 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
205#pragma omp parallel for schedule(runtime)
220 return m_isOrganizedByCell;
229 return m_finestLevel;
268 if (m_isOrganizedByCell) {
269 MayDay::Error(
"ParticleContainer::getParticles - particles are sorted by cell!");
281 if (m_isOrganizedByCell) {
282 MayDay::Abort(
"ParticleContainer::getParticles - particles are sorted by cell!");
294 return m_bufferParticles;
303 return m_bufferParticles;
312 return m_maskParticles;
321 return m_maskParticles;
330 if (m_isOrganizedByCell) {
331 MayDay::Error(
"ParticleContainer::operator[](a_lvl) - particles are sorted by cell!");
343 if (m_isOrganizedByCell) {
344 MayDay::Error(
"ParticleContainer::operator[](a_lvl) - particles are sorted by cell!");
356 if (!m_isOrganizedByCell) {
357 MayDay::Error(
"ParticleContainer::getCellParticles()- particles are not sorted by cell!");
360 return m_cellSortedParticles;
369 if (!m_isOrganizedByCell) {
370 MayDay::Error(
"ParticleContainer::getCellParticles()- particles are not sorted by cell!");
373 return m_cellSortedParticles;
382 if (!m_isOrganizedByCell) {
383 MayDay::Error(
"ParticleContainer::getCellParticles(level)- particles are not sorted by cell!");
386 return *m_cellSortedParticles[
a_level];
393 CH_TIME(
"ParticleContainer::getCellParticles(int)");
397 if (!m_isOrganizedByCell) {
398 MayDay::Error(
"ParticleContainer::getCellParticles(level)- particles are not sorted by cell!");
401 return *m_cellSortedParticles[
a_level];
408 CH_TIME(
"ParticleContainer::getCellParticles(BinFab)");
412 if (!m_isOrganizedByCell) {
413 MayDay::Error(
"ParticleContainer::getCellParticles - particles are not sorted by cell!");
424 CH_TIME(
"ParticleContainer::getCellParticlesDestructive");
428 if (!m_isOrganizedByCell) {
429 MayDay::Error(
"ParticleContainer::getCellParticlesDestructive - particles are not sorted by cell!");
440 CH_TIME(
"ParticleContainer::getCellParticles(int, DataIndex)");
444 if (!m_isOrganizedByCell) {
445 MayDay::Error(
"ParticleContainer::getCellParticles(int, dit) - particles are not sorted by cell!");
455 CH_TIME(
"ParticleContainer::getCellParticles(int, DataIndex)");
459 if (!m_isOrganizedByCell) {
460 MayDay::Error(
"ParticleContainer::getCellParticles(int, dit) - particles are not sorted by cell!");
470 CH_TIME(
"ParticleContainer::organizeParticlesByCell");
472 pout() <<
"ParticleContainer::organizeParticlesByCell" <<
endl;
477 if (!m_isOrganizedByCell) {
485#pragma omp parallel for schedule(runtime)
496 m_isOrganizedByCell =
true;
504 CH_TIME(
"ParticleContainer::organizeParticlesByPatch");
506 pout() <<
"ParticleContainer::organizeParticlesByPatch" <<
endl;
511 if (m_isOrganizedByCell) {
513 constexpr int comp = 0;
521#pragma omp parallel for schedule(runtime)
541 m_isOrganizedByCell =
false;
549 CH_TIME(
"ParticleContainer::addParticles");
551 pout() <<
"ParticleContainer::addParticles" <<
endl;
556 if (m_isOrganizedByCell) {
557 MayDay::Error(
"ParticleContainer::addParticles(List<P>) - particles are sorted by cell!");
615 CH_TIME(
"ParticleContainer::addParticlesDestructive");
617 pout() <<
"ParticleContainer::addParticlesDestructive" <<
endl;
622 if (m_isOrganizedByCell) {
623 MayDay::Error(
"ParticleContainer::addParticlesDestructive(List<P>) - particles are sorted by cell!");
681 CH_TIME(
"ParticleContainer::addParticles(BinFab)");
683 pout() <<
"ParticleContainer::addParticles(BinFab)" <<
endl;
689 if (!m_isOrganizedByCell) {
690 MayDay::Abort(
"ParticleContainer::addParticles(BinFab<P>) - particles are not sorted by cell!");
693 constexpr int comp = 0;
712 CH_TIME(
"ParticleContainer::addParticlesDestructive(BinFab)");
714 pout() <<
"ParticleContainer::addParticlesDestructive(BinFab)" <<
endl;
720 if (!m_isOrganizedByCell) {
721 MayDay::Error(
"ParticleContainer::addParticles(BinFab<P>) - particles are not sorted by cell!");
724 constexpr int comp = 0;
743 CH_TIME(
"ParticleContainer::addParticles(ParticleContainer)");
745 pout() <<
"ParticleContainer::addParticles(ParticleContainer)" <<
endl;
750 if (m_isOrganizedByCell) {
751 MayDay::Error(
"ParticleContainer::addParticles(ParticleContainer<P>) - particles are sorted by cell!");
758 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
764#pragma omp parallel for schedule(runtime)
827 CH_TIME(
"ParticleContainer::addParticlesDestructive(ParticleContainer)");
829 pout() <<
"ParticleContainer::addParticlesDestructive(ParticleContainer)" <<
endl;
837 if (m_isOrganizedByCell) {
838 MayDay::Error(
"ParticleContainer::addParticles(ParticleContainer<P>) - particles are sorted by cell!");
845 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
851#pragma omp parallel for schedule(runtime)
914 CH_TIME(
"ParticleContainer::transferParticles");
919 if (m_isOrganizedByCell) {
920 MayDay::Error(
"ParticleContainer::transferParticles(ParticleContainer<P>) - particles are sorted by cell!");
924 MayDay::Error(
"ParticleContainer::transferParticles(ParticleContainer<P>) - other particles are sorted by cell!");
929 "ParticleContainer::transferParticles(ParticleContainer<P>) - other container defined over a different realm");
939 CH_TIME(
"ParticleContainer::transferParticles(AMRParticles)");
941 pout() <<
"ParticleContainer::transferParticle(AMRParticles)" <<
endl;
946 if (m_isOrganizedByCell) {
947 MayDay::Error(
"ParticleContainer::transferParticles(ParticleContainer<P>) - particles are sorted by cell!");
951 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
957#pragma omp parallel for schedule(runtime)
973 CH_TIME(
"ParticleContainer<P>::remap");
975 pout() <<
"ParticleContainer::remap" <<
endl;
1030 this->sanityCheck();
1034template <
typename P>
1038 CH_TIME(
"ParticleContainer::sanityCheck");
1040 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1053 MayDay::Error(
"ParticleContainer::remap -- error2: particle is not contained in grid box!");
1060template <
typename P>
1064 CH_TIME(
"ParticleContainer::transferParticlesToSingleList");
1072#pragma omp for schedule(runtime)
1083template <
typename P>
1087 CH_TIME(
"ParticleContainer::copyParticlesToSingleList");
1095#pragma omp for schedule(runtime)
1106template <
typename P>
1111 CH_TIME(
"ParticleContainer::mapParticlesToAMRGrid");
1118 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1165template <
typename P>
1170 CH_TIME(
"ParticleContainer::catenateParticleMaps");
1185template <
typename P>
1190 CH_TIME(
"ParticleContainer::assignLocalParticles");
1197#pragma omp task firstprivate(mapIter)
1219 CH_TIME(
"ParticleContainer::preRegrid");
1221 pout() <<
"ParticleContainer::preRegrid" <<
endl;
1228 if (m_isOrganizedByCell) {
1229 MayDay::Error(
"ParticleContainer::preRegrid - particles are sorted by cell!");
1233 m_cacheParticles.resize(1 + m_finestLevel);
1235 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1244#pragma omp parallel for schedule(runtime)
1260 CH_TIME(
"ParticleContainer::resetParticleIDs");
1262 pout() <<
"ParticleContainer::resetParticleIDs" <<
endl;
1266 if (m_isOrganizedByCell) {
1267 MayDay::Error(
"ParticleContainer::preRegrid - particles are sorted by cell!");
1274 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1280#pragma omp parallel for schedule(runtime)
1305 CH_TIME(
"ParticleContainer::regrid");
1307 pout() <<
"ParticleContainer::regrid" <<
endl;
1313 if (m_isOrganizedByCell) {
1314 MayDay::Error(
"ParticleContainer::regrid(...) - particles are sorted by cell!");
1325 m_dx.resize(1 + m_finestLevel);
1326 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1330 this->setupGrownGrids(
a_lmin, m_finestLevel);
1331 this->setupParticleData(
a_lmin, m_finestLevel);
1351 this->transferParticlesToSingleList(
outcasts, m_cacheParticles);
1376 this->sanityCheck();
1380 m_cacheParticles.resize(0);
1384template <Real& (P::*particleScalarField)()>
1388 CH_TIME(
"ParticleContainer::setValue");
1390 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1396#pragma omp parallel for schedule(runtime)
1412template <RealVect& (P::*particleVectorField)()>
1416 CH_TIME(
"ParticleContainer::setValue");
1418 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1424#pragma omp parallel for schedule(runtime)
1443 CH_TIME(
"ParticleContainer::getNumberOfValidParticlesLocal");
1447 unsigned long long n = 0;
1449 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1455#pragma omp parallel for schedule(runtime) reduction(+ : n)
1472 CH_TIME(
"ParticleContainer::getNumberOfValidParticlesGlobal");
1476 const unsigned long long n = this->getNumberOfValidParticlesLocal();
1485 CH_TIME(
"ParticleContainer::getNumberOfOutcastParticlesLocal");
1489 unsigned long long n = 0;
1491 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1497#pragma omp parallel for schedule(runtime) reduction(+ : n)
1514 CH_TIME(
"ParticleContainer::getNumberOfOutcastParticlesGlobal");
1518 const unsigned long long n = this->getNumberOfOutcastParticlesLocal();
1527 CH_TIME(
"ParticleContainer::getNumberOfMaskParticlesLocal");
1531 unsigned long long n = 0;
1533 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1539#pragma omp parallel for schedule(runtime) reduction(+ : n)
1556 CH_TIME(
"ParticleContainer::getNumberOfMaskParticlesGlobal");
1560 const unsigned long long n = this->getNumberOfMaskParticlesLocal();
1569 CH_TIME(
"ParticleContainer::copyMaskParticles(amr)");
1573 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1584 CH_TIME(
"ParticleContainer::copyMaskParticles(level)");
1586 pout() <<
"ParticleContainer::copyMaskParticles(level)" <<
endl;
1591 m_maskParticles[
a_level]->clear();
1601#pragma omp parallel for schedule(runtime)
1607 if (
mask.isUsable()) {
1623 MayDay::Error(
"ParticleContainer::copyMaskParticles -- logic bust. Particle has fallen off grid");
1637 CH_TIME(
"ParticleContainer::transferMaskParticles(amr)");
1641 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1652 CH_TIME(
"ParticleContainer::transferMaskParticles(level)");
1654 pout() <<
"ParticleContainer::transferMaskParticles(level)" <<
endl;
1667#pragma omp parallel for schedule(runtime)
1673 if (
mask.isUsable()) {
1689 MayDay::Warning(
"ParticleContainer::transferMaskParticles -- logic bust. Particle has fallen off grid");
1721 this->clear(m_bufferParticles);
1730 this->clear(m_maskParticles);
1739 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1753 pout() <<
"ParticleContainer::clear(AMRParticles)" <<
endl;
1758 for (
int lvl = 0;
lvl <= m_finestLevel;
lvl++) {
1768#pragma omp parallel for schedule(runtime)
1783#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.
std::unordered_map< std::pair< uint32_t, uint32_t >, T, PairHash > ParticleMap
Underlying particle map when gathering/scattering particles.
Definition CD_ParticleMap.H:75
Declaration of a static class containing some common useful particle routines that would otherwise be...
Implementation of CD_Timer.H.
Vector< RealVect > getDx() const noexcept
Get grid resolutions.
Definition CD_ParticleContainerImplem.H:257
RealVect getProbLo() const noexcept
Get lower-left corner.
Definition CD_ParticleContainerImplem.H:250
AMRCellParticles< P > & getCellParticles()
Get all cell particles.
Definition CD_ParticleContainerImplem.H:352
void organizeParticlesByPatch()
Sort particles by cell.
Definition CD_ParticleContainerImplem.H:502
void clearMaskParticles() const
Clear the "mask" particles.
Definition CD_ParticleContainerImplem.H:1726
unsigned long long getNumberOfOutcastParticlesGlobal() const
Get global number of particles.
Definition CD_ParticleContainerImplem.H:1512
unsigned long long getNumberOfValidParticlesLocal() const
Get local number of particles.
Definition CD_ParticleContainerImplem.H:1441
void getCellParticlesDestructive(BinFab< P > &a_cellParticles, 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:422
void preRegrid(int a_lmin)
Cache particles before calling regrid.
Definition CD_ParticleContainerImplem.H:1217
ParticleData< P > & operator[](int a_lvl)
Get particle data on a level.
Definition CD_ParticleContainerImplem.H:326
std::string getRealm() const
Get the realm where this ParticleContainer lives.
Definition CD_ParticleContainerImplem.H:234
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, int a_base, int a_newFinestLevel)
Regrid function. a_base is the coarsest grid level which did not change.
Definition CD_ParticleContainerImplem.H:1296
virtual ~ParticleContainer()
Destructor ( does nothing)
Definition CD_ParticleContainerImplem.H:64
void sortParticles() noexcept
Sort particles according to the < operator in the particle.
Definition CD_ParticleContainerImplem.H:191
const Vector< DisjointBoxLayout > & getGrids() const
Get the AMR grids.
Definition CD_ParticleContainerImplem.H:243
unsigned long long getNumberOfOutcastParticlesLocal() const
Get local number of particles.
Definition CD_ParticleContainerImplem.H:1483
void addParticles(const List< P > &a_particles)
Add particles to container.
Definition CD_ParticleContainerImplem.H:547
unsigned long long getNumberOfMaskParticlesGlobal() const
Get the number particles in the halo cells.
Definition CD_ParticleContainerImplem.H:1554
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, int a_blockingFactor, int a_finestLevel, const std::string &a_realm)
Define the container. This will do a clear-out of all particles.
Definition CD_ParticleContainerImplem.H:71
void clear(AMRParticles< P > &a_particles) const
Clear particles on input data holder.
Definition CD_ParticleContainerImplem.H:1750
void remap()
Remap over the entire AMR hierarchy.
Definition CD_ParticleContainerImplem.H:971
void setupParticleData(int a_base, int a_finestLevel)
Setup function for the particle data (m_particles and m_maskParticles)
Definition CD_ParticleContainerImplem.H:148
void clearParticles()
Clear all particles.
Definition CD_ParticleContainerImplem.H:1708
void clearOutcast() noexcept
Clear outcast particles.
Definition CD_ParticleContainerImplem.H:1735
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:1167
unsigned long long getNumberOfMaskParticlesLocal() const
Get the number particles in the halo cells.
Definition CD_ParticleContainerImplem.H:1525
void organizeParticlesByCell()
Sort particles by cell.
Definition CD_ParticleContainerImplem.H:468
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:1108
int getFinestLevel() const
Get finest AMR level.
Definition CD_ParticleContainerImplem.H:225
void clearBufferParticles() const
Clear the buffer particles.
Definition CD_ParticleContainerImplem.H:1717
void assignLocalParticles(ParticleMap< List< P > > &a_mappedParticles, AMRParticles< P > &a_particleData) const noexcept
Gather particles locally.
Definition CD_ParticleContainerImplem.H:1187
void transferParticlesToSingleList(List< P > &a_list, AMRParticles< P > &a_particles) const noexcept
Gather the particles onto a single list.
Definition CD_ParticleContainerImplem.H:1062
bool isOrganizedByCell() const
Is cell-sorted or not.
Definition CD_ParticleContainerImplem.H:218
void transferMaskParticles(const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_mask)
Copy particles to the mask particle data holder.
Definition CD_ParticleContainerImplem.H:1635
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:1085
ParticleContainer()
Default constructor. Leaves object in undefined state.
void sanityCheck() const noexcept
Run a sanity check and make sure all particles are in their correctly assigned box.
Definition CD_ParticleContainerImplem.H:1036
void setValue(Real a_value)
Set the particle member to the input value.
Definition CD_ParticleContainerImplem.H:1386
AMRParticles< P > & getMaskParticles()
Get the mask particles.
Definition CD_ParticleContainerImplem.H:308
unsigned long long getNumberOfValidParticlesGlobal() const
Get global number of particles.
Definition CD_ParticleContainerImplem.H:1470
void resetParticleIDs() noexcept
Compute new particle IDs.
Definition CD_ParticleContainerImplem.H:1258
void addParticlesDestructive(List< P > &a_particles)
Add particles to container. The input particles are destroyed by this routine.
Definition CD_ParticleContainerImplem.H:613
void setupGrownGrids(int a_base, int a_finestLevel)
Set up grown grids.
Definition CD_ParticleContainerImplem.H:117
AMRParticles< P > & getBufferParticles()
Get buffer particles on all levels.
Definition CD_ParticleContainerImplem.H:290
AMRParticles< P > & getParticles()
Get all particles on all levels.
Definition CD_ParticleContainerImplem.H:264
void transferParticles(ParticleContainer< P > &a_otherContainer)
Move particles into this container.
Definition CD_ParticleContainerImplem.H:912
void copyMaskParticles(const Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > &a_mask) const
Copy particles to mask particle data holder.
Definition CD_ParticleContainerImplem.H:1567
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:31
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:38
ParticleContainer< P > m_particles
Computational particles.
Definition CD_TracerParticleSolver.H:412
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:26
std::string m_realm
Realm where this solver lives.
Definition CD_TracerParticleSolver.H:352
virtual ParticleContainer< P > & getParticles()
Get all particles.
Definition CD_TracerParticleSolverImplem.H:663
Real sum(const Real &a_value) noexcept
Compute the sum across all MPI ranks.
Definition CD_ParallelOpsImplem.H:354