14template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
15 template<
class>
class Allocator,
class CellAssignor>
19 num_real_comm_comps = 0;
20 int comm_comps_start = 0;
21 if constexpr (!ParticleType::is_soa_particle) {
24 for (
int i = comm_comps_start; i < comm_comps_start +
NumRealComps(); ++i) {
28 num_int_comm_comps = 0;
30 for (
int i = comm_comps_start; i < comm_comps_start +
NumIntComps(); ++i) {
34 if constexpr (ParticleType::is_soa_particle) {
35 particle_size =
sizeof(uint64_t);
39 superparticle_size = particle_size +
40 num_real_comm_comps*
sizeof(
ParticleReal) + num_int_comm_comps*
sizeof(
int);
43template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
44 template<
class>
class Allocator,
class CellAssignor>
48 levelDirectoriesCreated =
false;
53 if constexpr (ParticleType::is_soa_particle)
55 h_redistribute_real_comp.resize(NArrayReal,
true);
57 h_redistribute_real_comp.resize(AMREX_SPACEDIM + NStructReal + NArrayReal,
true);
59 h_redistribute_int_comp.resize(2 + NStructInt + NArrayInt,
true);
64 m_soa_rdata_names.clear();
65 for (
int i=0; i<NArrayReal; ++i)
69 m_soa_idata_names.clear();
70 for (
int i=0; i<NArrayInt; ++i)
75 static bool initialized =
false;
78 static_assert(
sizeof(ParticleType)%
sizeof(RealType) == 0,
79 "sizeof ParticleType is not a multiple of sizeof RealType");
82 pp.queryAdd(
"do_tiling", do_tiling);
84 if (pp.queryarr(
"tile_size", tilesize, 0, AMREX_SPACEDIM)) {
85 for (
int i=0; i<AMREX_SPACEDIM; ++i) { tile_size[i] = tilesize[i]; }
88 static_assert(std::is_standard_layout_v<ParticleType>,
89 "Particle type must be standard layout");
93 pp.query(
"use_prepost", usePrePost);
94 pp.query(
"do_unlink", doUnlink);
95 pp.queryAdd(
"do_mem_efficient_sort", memEfficientSort);
96 pp.queryAdd(
"use_comms_arena", use_comms_arena);
103 typename ParticleType,
106 template<
class>
class Allocator,
111 std::vector<std::string>
const & rdata_name, std::vector<std::string>
const & idata_name
118 std::set<std::string>
const unique_r_names(rdata_name.begin(), rdata_name.end());
119 std::set<std::string>
const unique_i_names(idata_name.begin(), idata_name.end());
125 m_soa_rdata_names.at(i) = rdata_name.at(i);
129 m_soa_idata_names.at(i) = idata_name.at(i);
134 typename ParticleType,
137 template<
class>
class Allocator,
143 return std::ranges::find(m_soa_rdata_names, name) != std::end(m_soa_rdata_names);
146template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
147 template<
class>
class Allocator,
class CellAssignor>
151 return std::ranges::find(m_soa_idata_names, name) != std::end(m_soa_idata_names);
155 typename ParticleType,
158 template<
class>
class Allocator,
164 const auto it = std::ranges::find(m_soa_rdata_names, name);
166 if (it == m_soa_rdata_names.end())
168 throw std::runtime_error(
"GetRealCompIndex: Component " + name +
" does not exist!");
172 return std::distance(m_soa_rdata_names.begin(), it);
177 typename ParticleType,
180 template<
class>
class Allocator,
186 const auto it = std::ranges::find(m_soa_idata_names, name);
188 if (it == m_soa_idata_names.end())
190 throw std::runtime_error(
"GetIntCompIndex: Component " + name +
" does not exist!");
194 return std::distance(m_soa_idata_names.begin(), it);
198template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
199 template<
class>
class Allocator,
class CellAssignor>
200template <
typename P,
typename Assignor>
205 const auto& domain = geom.
Domain();
209 return Assignor{}(
p, plo, dxi, domain);
212template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
213 template<
class>
class Allocator,
class CellAssignor>
222 int local_grid)
const
235 std::vector< std::pair<int, Box> > isects;
237 for (
int lev = lev_max; lev >= lev_min; lev--) {
239 if (lev == pld.
m_lev) {
256 if (local_grid < 0) {
257 bool findfirst = (nGrow == 0) ?
true :
false;
259 grid = isects.empty() ? -1 : isects[0].first;
260 if (nGrow != 0 && std::ssize(isects) > 1) {
261 for (
auto & isect : isects) {
263 for (
int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
266 gr[dir] = nGrow[dir];
275 grid = (*redistribute_mask_ptr)[local_grid](iv, 0);
293template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
294 template<
class>
class Allocator,
class CellAssignor>
302 int local_grid)
const
307 if (!
Geom(0).isAnyPeriodic()) {
return false; }
318 p_prime.
pos(1) =
p.pos(1);,
319 p_prime.
pos(2) =
p.pos(2));
321 std::vector< std::pair<int,Box> > isects;
322 for (
int lev = lev_max; lev >= lev_min; lev--) {
329 if (local_grid < 0) {
332 grid = isects.empty() ? -1 : isects[0].first;
335 if (ba[local_grid].contains(iv))
342 grid = isects.empty() ? -1 : isects[0].first;
345 grid = (*redistribute_mask_ptr)[local_grid](
Index(
p, lev), 0);
352 p.pos(1) = p_prime.
pos(1);,
353 p.pos(2) = p_prime.
pos(2););
372template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
373 template<
class>
class Allocator,
class CellAssignor>
379 const auto& geom =
Geom(0);
380 const auto plo = geom.ProbLoArray();
381 const auto phi = geom.ProbHiArray();
382 const auto rlo = geom.ProbLoArrayInParticleReal();
383 const auto rhi = geom.ProbHiArrayInParticleReal();
384 const auto is_per = geom.isPeriodicArray();
389template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
390 template<
class>
class Allocator,
class CellAssignor>
402 if (!ok &&
Geom(0).isAnyPeriodic())
418 p.id().make_invalid();
424template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
425 template<
class>
class Allocator,
class CellAssignor>
433template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
434 template<
class>
class Allocator,
class CellAssignor>
440 m_particles.resize(nlevs);
443template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
444 template<
class>
class Allocator,
class CellAssignor>
447ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>::locateParticle (P&
p,
ParticleLocData& pld,
448 int lev_min,
int lev_max,
IntVect nGrow,
int local_grid)
const
451 if (Geom(0).outsideRoundoffDomain(
AMREX_D_DECL(
p.pos(0),
p.pos(1),
p.pos(2))))
454 success = EnforcePeriodicWhere(
p, pld, lev_min, lev_max, local_grid);
455 if (!success && lev_min == 0)
458 p.id().make_invalid();
464 success = Where(
p, pld, lev_min, lev_max,
IntVect(0), local_grid);
469 success = (nGrow != 0) && Where(
p, pld, lev_min, lev_min, nGrow);
475 amrex::Abort(
"ParticleContainer::locateParticle(): invalid particle.");
479template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
480 template<
class>
class Allocator,
class CellAssignor>
494template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
495 template<
class>
class Allocator,
class CellAssignor>
499 AMREX_ASSERT(lev >= 0 && lev < std::ssize(m_particles));
506 int gid = pti.index();
510 const int np = ptile.numParticles();
511 auto const ptd = ptile.getConstParticleTileData();
515 using ReduceTuple =
typename decltype(reduce_data)::Type;
517 reduce_op.
eval(np, reduce_data,
520 return (ptd.id(i).is_valid()) ? 1 : 0;
524 np_per_grid_local[gid] += np_valid;
527 np_per_grid_local[gid] += pti.numParticles();
536 nparticles[pti.index()] = np_per_grid_local[pti.index()];
551template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
552 template<
class>
class Allocator,
class CellAssignor>
557 if (level < 0 || level >= std::ssize(m_particles)) {
return nparticles; }
562 using ReduceTuple =
typename decltype(reduce_data)::Type;
565 const auto& ptile = kv.second;
566 auto const ptd = ptile.getConstParticleTileData();
568 reduce_op.
eval(ptile.numParticles(), reduce_data,
571 return (ptd.id(i).is_valid()) ? 1 : 0;
579 const auto& ptile = kv.second;
580 nparticles += ptile.numParticles();
593template <std::
integral Int>
594requires (
sizeof(Int) >=
sizeof(
Long))
598 AMREX_ASSERT(lev >= 0 && lev < std::ssize(m_particles));
606 int gid = pti.index();
607 mem[gid] +=
static_cast<Int
>(pti.capacity());
615template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
623 for (
unsigned lev = 0; lev < m_particles.size(); lev++) {
624 const auto& pmap = m_particles[lev];
625 for (
const auto& kv : pmap) {
626 const auto& ptile = kv.second;
627 cnt += ptile.numParticles();
631 Long mn = cnt, mx = mn;
634 const Long sz =
sizeof(ParticleType)+NumRealComps()*
sizeof(
ParticleReal)+NumIntComps()*
sizeof(
int);
643 amrex::Print() <<
"ParticleContainer spread across MPI nodes - bytes (num particles): [Min: "
651 <<
" (" << cnt <<
")]\n";
656 return {mn*sz, mx*sz, cnt*sz};
659template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
660 template<
class>
class Allocator,
class CellAssignor>
667 for (
unsigned lev = 0; lev < m_particles.size(); lev++) {
668 const auto& pmap = m_particles[lev];
669 for (
const auto& kv : pmap) {
670 const auto& ptile = kv.second;
671 cnt += ptile.capacity();
675 Long mn = cnt, mx = mn;
686 amrex::Print() <<
"ParticleContainer spread across MPI nodes - bytes: [Min: "
697 return {mn, mx, cnt};
705 for (
unsigned lev = 0; lev < m_particles.size(); lev++) {
706 auto& pmap = m_particles[lev];
707 for (
auto& kv : pmap) {
708 auto& ptile = kv.second;
709 ptile.shrink_to_fit();
728 if (m_particles.empty()) {
return; }
729 AMREX_ASSERT(lev >= 0 && lev < std::ssize(m_particles));
732 const auto& geom =
Geom(lev);
733 const auto plo = geom.ProbLoArray();
734 const auto dxi = geom.InvCellSizeArray();
735 const auto domain = geom.Domain();
737 [=]
AMREX_GPU_DEVICE (
const typename ParticleTileType::ConstParticleTileDataType& ptd,
int ip,
740 const auto p = ptd[ip];
742 IntVect iv = assignor(
p, plo, dxi, domain);
747template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
748 template<
class>
class Allocator,
class CellAssignor>
752 BL_PROFILE(
"ParticleContainer::IncrementWithTotal(lev)");
757template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
758 template<
class>
class Allocator,
class CellAssignor>
762 BL_PROFILE(
"ParticleContainer::RemoveParticlesAtLevel()");
763 if (level >= std::ssize(this->m_particles)) {
return; }
765 if (!this->m_particles[level].empty())
771template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
772 template<
class>
class Allocator,
class CellAssignor>
776 BL_PROFILE(
"ParticleContainer::RemoveParticlesNotAtFinestLevel()");
781 for (
unsigned lev = 0; lev < m_particles.size() - 1; ++lev) {
782 auto& pmap = m_particles[lev];
784 for (
auto& kv : pmap) {
785 const auto& pbx = kv.second;
786 cnt += pbx.numParticles();
797 <<
" particles not in finest level\n";
813 template <
typename SrcData>
815 int operator() (
const SrcData& src,
int src_i)
const noexcept
824 template <
typename DstData,
typename SrcData>
827 int src_i,
int dst_i)
const noexcept
837template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
838 template<
class>
class Allocator,
class CellAssignor>
840ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
841::CreateVirtualParticles (
int level,
AoS& virts)
const
845 ptile.GetArrayOfStructs().swap(virts);
848template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
849 template<
class>
class Allocator,
class CellAssignor>
854 BL_PROFILE(
"ParticleContainer::CreateVirtualParticles()");
858 if (level >= std::ssize(m_particles)) {
865 if (aggregation_type ==
"None")
867 auto virts_offset = virts.numParticles();
872 auto np = src_tile.numParticles();
873 virts.resize(virts_offset+np);
878 if (aggregation_type ==
"Cell")
889 const auto& geom =
Geom(level);
890 const auto plo = geom.ProbLoArray();
891 const auto dxi = geom.InvCellSizeArray();
892 const auto domain = geom.Domain();
896 BoxArray buffer(std::move(bl_buffer));
897 buffer.
grow(aggregation_buffer);
910 if(assign_buffer_grid(iv).first == -1)
918 for (
int i = 0; i < AMREX_SPACEDIM; ++i)
928 for (
int i = 0; i < 1; ++i)
944 if(assign_buffer_grid(iv).first == -1)
947 if(partData(iv,0)==0)
964 virts.resize(imf.
sum(0));
969 const auto bx = mfi.tilebox();
970 const auto partData = mf.
array(mfi);
971 const auto imf_arr = imf.
array(mfi);
974 auto *offsets_ptr = offsets.
dataPtr();
976 auto dst = virts.getParticleTileData();
979 if(imf_arr(i,j,k,0)!=0)
981 const auto idx = last_offset + offsets_ptr[
991 p.rdata(0) =
static_cast<ParticleReal>(partData(i,j,k,AMREX_SPACEDIM));;
993 for (
int n = 0; n < AMREX_SPACEDIM; ++n)
995 p.pos(n) =
static_cast<ParticleReal>(partData(i,j,k,n) /
p.rdata(0));
1000 p.rdata(n) =
static_cast<ParticleReal>(partData(i,j,k,AMREX_SPACEDIM+n) /
p.rdata(0));
1010 p.idata(n) = imf_arr(i,j,k,1+n);
1015 dst.idata(n)[idx] = imf_arr(i,j,k,1+
NStructInt+n);
1020 last_offset+=next_offset;
1025 auto virts_offset = last_offset;
1030 auto np = src_tile.numParticles();
1031 virts.resize(virts_offset+np);
1035 virts.resize(virts_offset);
1054 template <
typename SrcData>
1063 return p_boxes_max >=0 && p_boxes ==
m_gid && p_levs_max ==
m_lev_max;
1070 template <
typename DstData,
typename SrcData>
1073 int src_i,
int dst_i)
const noexcept
1082template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1083 template<
class>
class Allocator,
class CellAssignor>
1085ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor>
1086::CreateGhostParticles (
int level,
int nGrow,
AoS& ghosts)
const
1090 ptile.GetArrayOfStructs().swap(ghosts);
1093template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1094 template<
class>
class Allocator,
class CellAssignor>
1099 BL_PROFILE(
"ParticleContainer::CreateGhostParticles()");
1103 if (level >= std::ssize(m_particles)) {
1113 auto ghost_offset = ghosts.numParticles();
1117 int gid = pti.index();
1119 auto np = src_tile.numParticles();
1120 ghosts.resize(ghost_offset+np);
1123 ghosts.resize(ghost_offset);
1127template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1128 template<
class>
class Allocator,
class CellAssignor>
1133 BL_PROFILE(
"ParticleContainer::clearParticles()");
1135 for (
int lev = 0; lev < std::ssize(m_particles); ++lev)
1137 for (
auto& kv : m_particles[lev]) { kv.second.resize(0); }
1138 particle_detail::clearEmptyEntries(m_particles[lev]);
1142template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1143 template<
class>
class Allocator,
class CellAssignor>
1144template <
class PCType>
1150 using PData =
typename ParticleTileType::ConstParticleTileDataType;
1154template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1155 template<
class>
class Allocator,
class CellAssignor>
1156template <
class PCType>
1162 using PData =
typename ParticleTileType::ConstParticleTileDataType;
1166template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1167 template<
class>
class Allocator,
class CellAssignor>
1168template <
class F,
class PCType>
1174 BL_PROFILE(
"ParticleContainer::copyParticles");
1179template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1180 template<
class>
class Allocator,
class CellAssignor>
1181template <
class F,
class PCType>
1187 BL_PROFILE(
"ParticleContainer::addParticles");
1190 for (
int lev = 0; lev < other.numLevels(); ++lev)
1193 const auto& plevel_other = other.GetParticles(lev);
1194 for(
MFIter mfi = other.MakeMFIter(lev); mfi.
isValid(); ++mfi)
1196 auto index = std::make_pair(mfi.index(), mfi.LocalTileIndex());
1197 if(!plevel_other.contains(index)) {
continue; }
1204#pragma omp parallel if (Gpu::notInLaunchRegion())
1206 for (
int lev = 0; lev < other.numLevels(); ++lev)
1208 const auto& plevel_other = other.GetParticles(lev);
1209 for(
MFIter mfi = other.MakeMFIter(lev); mfi.
isValid(); ++mfi)
1211 auto index = std::make_pair(mfi.index(), mfi.LocalTileIndex());
1212 if(!plevel_other.contains(index)) {
continue; }
1215 auto& ptile =
ParticlesAt(lev, mfi.index(), mfi.LocalTileIndex());
1216 const auto& ptile_other = plevel_other.at(index);
1217 auto np = ptile_other.numParticles();
1218 if (np == 0) {
continue; }
1220 auto dst_index = ptile.numParticles();
1221 ptile.resize(dst_index + np);
1224 static_cast<decltype(np)
>(0), dst_index, np);
1226 ptile.resize(dst_index + count);
1236template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1237 template<
class>
class Allocator,
class CellAssignor>
1241 bool local,
IntVect max_cells_moved,
bool remove_negative)
1247 "ParticleContainer with RTSoA requires at least AMREX_SPACEDIM "
1248 "runtime real components for positions"
1259template <
class index_type>
1265 const size_t np = ptile.numParticles();
1266 const size_t np_total = np + ptile.numNeighborParticles();
1271 ParticleTileType ptile_tmp;
1272 ptile_tmp.define(m_num_runtime_real, m_num_runtime_int,
1273 &m_soa_rdata_names, &m_soa_idata_names, arena());
1274 ptile_tmp.resize(np_total);
1279 ptile.swap(ptile_tmp);
1283template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1284 template<
class>
class Allocator,
class CellAssignor>
1291template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1292 template<
class>
class Allocator,
class CellAssignor>
1297 BL_PROFILE(
"ParticleContainer::SortParticlesByBin()");
1301 for (
int lev = 0; lev <
numLevels(); ++lev)
1306 const auto domain = geom.
Domain();
1311 const size_t np = ptile.numParticles();
1317 m_bins.build(np, ptile.getParticleTileData(), ntiles,
1319 .bin_size = bin_size, .box = box});
1325template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1326 template<
class>
class Allocator,
class CellAssignor>
1331 BL_PROFILE(
"ParticleContainer::SortParticlesForDeposition()");
1333 for (
int lev = 0; lev <
numLevels(); ++lev)
1340 const size_t np = ptile.numParticles();
1344 using index_type =
typename decltype(
m_bins)::index_type;
1352template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1353 template<
class>
class Allocator,
class CellAssignor>
1358 int lev,
int gid,
int tid,
1359 int lev_min,
int lev_max,
IntVect nGrow,
bool local,
1360 bool remove_negative,
int myproc,
1368 auto ptd = src_tile.getParticleTileData();
1371 Long last = src_tile.numParticles() - 1;
1374 while (pindex <= last) {
1375 decltype(
auto)
p = ptd[pindex];
1378 if (!ptd.id(pindex).is_valid()) {
1379 if (remove_negative) {
1381 correctCellVectors(last, pindex, gid,
p);
1392 if (lev == lev_max && pld.
m_tile == tid && pld.
m_grid == gid && pld.
m_lev == lev && who == myproc) {
1401 locateParticle(
p, pld, lev_min, lev_max, nGrow, local ? gid : -1);
1402 particlePostLocate(
p, pld, lev);
1405 if (!ptd.id(pindex).is_valid()) {
1407 correctCellVectors(last, pindex, gid,
p);
1414 if (pld.
m_lev != lev || pld.
m_grid != gid || pld.
m_tile != tid || who != myproc) {
1417 correctCellVectors(last, pindex, gid,
p);
1418 boxes[num_move] = pld.
m_grid;
1419 levels[num_move] = pld.
m_lev;
1420 tiles[num_move] = pld.
m_tile;
1421 src_indices[num_move] =
static_cast<int>(last);
1433 src_indices.
resize(num_move);
1434 periodic_shift.
resize(num_move);
1436 return static_cast<int>(pindex);
1442template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1443 template<
class>
class Allocator,
class CellAssignor>
1447 bool local,
IntVect max_cells_moved,
bool remove_negative)
1449 BL_PROFILE(
"ParticleContainer::Redistribute_impl()");
1452 int theEffectiveFinestLevel =
m_gdb->finestLevel();
1453 while (!
m_gdb->LevelDefined(theEffectiveFinestLevel)) { theEffectiveFinestLevel--; }
1455 if (std::ssize(m_particles) < theEffectiveFinestLevel+1) {
1457 amrex::Print() <<
"ParticleContainer::Redistribute() resizing containers from "
1458 << m_particles.size() <<
" to "
1459 << theEffectiveFinestLevel + 1 <<
'\n';
1461 m_particles.resize(theEffectiveFinestLevel+1);
1462 m_dummy_mf.resize(theEffectiveFinestLevel+1);
1465 for (
int lev = 0; lev < theEffectiveFinestLevel+1; ++lev) {
RedefineDummyMF(lev); }
1467 int finest_lev_particles;
1468 if (lev_max == -1) {
1469 lev_max = theEffectiveFinestLevel;
1470 finest_lev_particles = m_particles.size() - 1;
1472 finest_lev_particles = lev_max;
1479 max_cells_moved) == 0);
1484#ifndef AMREX_USE_GPU
1485 const bool use_mask_lookup = local && lev_min == 0 && lev_max == 0
1489 if (! m_particle_locator.isValid(GetParGDB(), do_tiling, tile_size)) { m_particle_locator.build(GetParGDB(), do_tiling, tile_size); }
1490 m_particle_locator.setGeometry(GetParGDB());
1495 int num_levels = finest_lev_particles + 1;
1496 op.setNumLevels(num_levels);
1498#ifndef AMREX_USE_GPU
1503 const auto plo =
Geom(0).ProbLoArray();
1504 const auto phi =
Geom(0).ProbHiArray();
1505 const auto rlo =
Geom(0).ProbLoArrayInParticleReal();
1506 const auto rhi =
Geom(0).ProbHiArrayInParticleReal();
1507 const auto is_per =
Geom(0).isPeriodicArray();
1510#if defined(AMREX_USE_OMP) || defined(AMREX_USE_GPU)
1515#ifndef AMREX_USE_GPU
1522 std::size_t num_tiles = 0;
1523 for (
int lev = lev_min; lev <= finest_lev_particles; ++lev) {
1524 for (
auto const& kv : m_particles[lev]) {
1525 if (kv.second.numParticles() != 0) {
1530 grid_tile_ids.reserve(num_tiles);
1531 ptile_ptrs.reserve(num_tiles);
1532 plevs.reserve(num_tiles);
1533 new_size_ptrs.reserve(num_tiles);
1534#ifndef AMREX_USE_GPU
1535 box_ptrs.reserve(num_tiles);
1536 level_ptrs.reserve(num_tiles);
1537 tile_ptrs.reserve(num_tiles);
1538 src_index_ptrs.reserve(num_tiles);
1539 periodic_shift_ptrs.reserve(num_tiles);
1541 for (
int lev = lev_min; lev <= finest_lev_particles; lev++) {
1542 auto& pmap = m_particles[lev];
1543 for (
auto& kv : pmap)
1545 const auto np = kv.second.numParticles();
1546 if (np == 0) {
continue; }
1548 grid_tile_ids.push_back(kv.first);
1549 ptile_ptrs.push_back(&(kv.second));
1550 plevs.push_back(lev);
1551 auto index = std::make_pair(kv.first.first, kv.first.second);
1552 auto& new_size = new_sizes[lev][index];
1554 new_size_ptrs.push_back(&new_size);
1555#ifndef AMREX_USE_GPU
1556 op.resize(kv.first.first, kv.first.second, lev,
static_cast<int>(np));
1557 auto& boxes = op.m_boxes[lev][index];
1558 auto& levels = op.m_levels[lev][index];
1559 auto& tiles = op.m_tiles[lev][index];
1560 auto& src_indices = op.m_src_indices[lev][index];
1561 auto& periodic_shift = op.m_periodic_shift[lev][index];
1562 box_ptrs.push_back(&boxes);
1563 level_ptrs.push_back(&levels);
1564 tile_ptrs.push_back(&tiles);
1565 src_index_ptrs.push_back(&src_indices);
1566 periodic_shift_ptrs.push_back(&periodic_shift);
1572#if defined(AMREX_USE_OMP) || defined(AMREX_USE_GPU)
1574#pragma omp parallel for
1576 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
1578 int lev = plevs[pmap_it];
1579 int gid = grid_tile_ids[pmap_it].first;
1580 int tid = grid_tile_ids[pmap_it].second;
1581 auto& src_tile = *ptile_ptrs[pmap_it];
1582 const size_t np = src_tile.numParticles();
1583 if (np == 0) {
continue;}
1585#ifndef AMREX_USE_GPU
1586 auto& boxes = *box_ptrs[pmap_it];
1587 auto& levels = *level_ptrs[pmap_it];
1588 auto& tiles = *tile_ptrs[pmap_it];
1589 auto& src_indices = *src_index_ptrs[pmap_it];
1590 auto& periodic_shift = *periodic_shift_ptrs[pmap_it];
1591 *new_size_ptrs[pmap_it] = hostPartitionTile(src_tile,
1593 lev_min, lev_max, nGrow, use_mask_lookup,
1594 remove_negative, myproc,
1595 boxes, levels, tiles,
1596 src_indices, periodic_shift);
1599 std::forward<CellAssignor>(CellAssignor{}),
1601 plo, phi, rlo, rhi, is_per, lev, gid, tid,
1602 lev_min, lev_max, nGrow, remove_negative);
1604 int num_move = np - num_stay;
1605 *new_size_ptrs[pmap_it] = num_stay;
1606 op.resize(gid, tid, lev, num_move);
1608 auto index = std::make_pair(gid, tid);
1609 auto* p_boxes = op.m_boxes[lev][index].dataPtr();
1610 auto* p_levs = op.m_levels[lev][index].dataPtr();
1611 auto* p_tiles = op.m_tiles[lev][index].dataPtr();
1612 auto* p_src_indices = op.m_src_indices[lev][index].dataPtr();
1613 auto* p_periodic_shift = op.m_periodic_shift[lev][index].dataPtr();
1614 auto ptd = src_tile.getParticleTileData();
1618 const auto p = ptd[i + num_stay];
1620 if (!
p.id().is_valid())
1628 const auto tup = assign_grid(
p, lev_min, lev_max, nGrow,
1629 std::forward<CellAssignor>(CellAssignor{}));
1635 p_src_indices[i] = i+num_stay;
1640 for (
int lev = lev_min; lev <= finest_lev_particles; ++lev) {
1641 auto& pmap = m_particles[lev];
1642 for (
auto& kv : pmap)
1644 auto& src_tile = kv.second;
1645 const auto np = src_tile.numParticles();
1646 if (np == 0) {
continue; }
1648 int gid = kv.first.first;
1649 int tid = kv.first.second;
1650 auto index = std::make_pair(gid, tid);
1651 auto& new_size = new_sizes[lev][index];
1654 op.resize(gid, tid, lev,
static_cast<int>(np));
1655 auto& boxes = op.m_boxes[lev][index];
1656 auto& levels = op.m_levels[lev][index];
1657 auto& tiles = op.m_tiles[lev][index];
1658 auto& src_indices = op.m_src_indices[lev][index];
1659 auto& periodic_shift = op.m_periodic_shift[lev][index];
1660 new_size = hostPartitionTile(src_tile,
1662 lev_min, lev_max, nGrow, use_mask_lookup,
1663 remove_negative, myproc,
1664 boxes, levels, tiles,
1665 src_indices, periodic_shift);
1673 plan.
build(*
this, op, h_redistribute_int_comp,
1674 h_redistribute_real_comp, local, max_cells_moved);
1677 amrex::PODVector<char, PolymorphicArenaAllocator<char> > snd_buffer;
1678 amrex::PODVector<char, PolymorphicArenaAllocator<char> > rcv_buffer;
1680 if (use_comms_arena) {
1688 for (
int lev = lev_min; lev <= lev_max; ++lev)
1690 auto& plev = m_particles[lev];
1691 for (
auto& kv : plev)
1693 int gid = kv.first.first;
1694 int tid = kv.first.second;
1695 auto index = std::make_pair(gid, tid);
1696 auto& tile = plev[index];
1697 tile.resize(new_sizes[lev][index]);
1701 for (
int lev = lev_min; lev <= lev_max; lev++)
1703 particle_detail::clearEmptyEntries(m_particles[lev]);
1706 if (std::ssize(m_particles) > theEffectiveFinestLevel+1) {
1707 if (m_verbose > 0) {
1708 amrex::Print() <<
"ParticleContainer::Redistribute() resizing m_particles from "
1709 << m_particles.size() <<
" to " << theEffectiveFinestLevel+1 <<
'\n';
1713 m_particles.resize(theEffectiveFinestLevel + 1);
1714 m_dummy_mf.resize(theEffectiveFinestLevel + 1);
1719 plan.buildMPIFinish(BufferMap());
1721 this->ReserveForRedistribute(plan);
1732 if (snd_buffer.arena()->isPinned()) {
1733 plan.buildMPIFinish(BufferMap());
1737 pinned_snd_buffer.resize(snd_buffer.
size());
1739 plan.buildMPIFinish(BufferMap());
1744 this->ReserveForRedistribute(plan);
1746 rcv_buffer.
resize(pinned_rcv_buffer.size());
1757template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1758 template<
class>
class Allocator,
class CellAssignor>
1763 BL_PROFILE(
"ParticleContainer::ReserveForRedistribute()");
1765 std::map<ParticleTileType*, int> addsizes;
1767 for (
int lev = 0; lev < this->
BufferMap().numLevels(); ++lev) {
1769 int gid = mfi.
index();
1773 if (num_copies > 0) {
1774 addsizes[&tile] += num_copies;
1786 addsizes[&tile] += copy_size;
1790 ParticleTileType::reserve(addsizes);
1793template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1794 template<
class>
class Allocator,
class CellAssignor>
1800 if (lev_max == -1) {
1807template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1808 template<
class>
class Allocator,
class CellAssignor>
1814 ptile.GetArrayOfStructs().swap(particles);
1818template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1819 template<
class>
class Allocator,
class CellAssignor>
1824 BL_PROFILE(
"ParticleContainer::AddParticlesAtLevel()");
1826 if (std::ssize(m_particles) < level+1)
1830 amrex::Print() <<
"ParticleContainer::AddParticlesAtLevel resizing m_particles from "
1831 << m_particles.size()
1835 m_particles.resize(level+1);
1837 for (
int lev = 0; lev < level+1; ++lev) {
1843 int old_np = ptile.size();
1844 int num_to_add = particles.size();
1845 int new_np = old_np + num_to_add;
1846 ptile.resize(new_np);
1849 particles.resize(0);
1853template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1854 template<
class>
class Allocator,
class CellAssignor>
1861 int particle_lvl_offset)
const
1863 BL_PROFILE(
"ParticleContainer::AssignCellDensitySingleLevel()");
1865 if (rho_index != 0) {
amrex::Abort(
"AssignCellDensitySingleLevel only works if rho_index = 0"); }
1872 mf_pointer = &mf_to_be_filled;
1879 ncomp, mf_to_be_filled.
nGrow());
1886 if (mf_pointer->
nGrow() < 1) {
1887 amrex::Error(
"Must have at least one ghost cell when in AssignCellDensitySingleLevel");
1892 const auto dxi =
Geom(lev).InvCellSizeArray();
1893 const auto plo =
Geom(lev).ProbLoArray();
1894 const auto pdxi =
Geom(lev + particle_lvl_offset).InvCellSizeArray();
1896 if (
Geom(lev).isAnyPeriodic() && !
Geom(lev).isAllPeriodic())
1898 amrex::Error(
"AssignCellDensitySingleLevel: problem must be periodic in no or all directions");
1905#pragma omp parallel if (Gpu::notInLaunchRegion())
1909 for (
ParConstIter pti(*
this, lev); pti.isValid(); ++pti) {
1910 const Long np = pti.numParticles();
1911 auto ptd = pti.GetParticleTile().getConstParticleTileData();
1913 auto rhoarr = fab.
array();
1918 tile_box = pti.tilebox();
1920 local_rho.
resize(tile_box,ncomp);
1922 rhoarr = local_rho.
array();
1926 if (particle_lvl_offset == 0)
1931 amrex_deposit_cic(
p, ncomp, rhoarr, plo, dxi);
1939 amrex_deposit_particle_dx_cic(
p, ncomp, rhoarr, plo, dxi, pdxi);
1957 for (
int n = 1; n < ncomp; n++)
1961 (*mf_pointer)[mfi].protected_divide<
RunOn::Device>((*mf_pointer)[mfi],0,n,1);
1968 const Real* dx =
Geom(lev).CellSize();
1975 if (mf_pointer != &mf_to_be_filled)
1977 mf_to_be_filled.
ParallelCopy(*mf_pointer,0,0,ncomp,0,0);
1988 amrex::Print() <<
"ParticleContainer::AssignCellDensitySingleLevel) time: "
1989 << stoptime <<
'\n';
1993template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
1994 template<
class>
class Allocator,
class CellAssignor>
1999 int old_size = m_num_runtime_real;
2001 m_runtime_comps_defined = (new_size > 0);
2002 m_num_runtime_real = new_size;
2007 for (
int lev = 0; lev <
numLevels(); ++lev) {
2008 for (
ParIterType pti(*
this,lev); pti.isValid(); ++pti) {
2010 auto np = tile.numParticles();
2011 if (np > 0 && new_size > old_size) {
2012 auto& soa = tile.GetStructOfArrays();
2019template <
typename ParticleType,
int NArrayReal,
int NArrayInt,
2020 template<
class>
class Allocator,
class CellAssignor>
2025 int old_size = m_num_runtime_int;
2027 m_runtime_comps_defined = (new_size > 0);
2028 m_num_runtime_int = new_size;
2033 for (
int lev = 0; lev <
numLevels(); ++lev) {
2034 for (
ParIterType pti(*
this,lev); pti.isValid(); ++pti) {
2036 auto np = tile.numParticles();
2037 if (np > 0 && new_size > old_size) {
2038 auto& soa = tile.GetStructOfArrays();
#define BL_PROFILE_VAR_START(vname)
Definition AMReX_BLProfiler.H:604
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:593
#define BL_PROFILE_VAR_STOP(vname)
Definition AMReX_BLProfiler.H:605
#define BL_PROFILE_SYNC_STOP()
Definition AMReX_BLProfiler.H:709
#define BL_PROFILE_SYNC_START_TIMED(fname)
Definition AMReX_BLProfiler.H:708
#define BL_PROFILE_VAR_NS(fname, vname)
Definition AMReX_BLProfiler.H:603
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_HOST_DEVICE_FOR_1D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:105
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
while parser_exe_t p
Definition AMReX_Parser_Exe_Body.H:33
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Print on all processors of the default communicator.
Definition AMReX_Print.H:113
BaseFab< T > & atomicAdd(const BaseFab< T > &x) noexcept
Atomic FAB addition (a[i] <- a[i] + b[i]).
Definition AMReX_BaseFab.H:2658
Array4< T const > array() const noexcept
Create an Array4 view over all components.
Definition AMReX_BaseFab.H:475
void setVal(T const &x, const Box &bx, int dcomp, int ncomp) noexcept
The setVal functions set sub-regions in the BaseFab to a constant value. This most general form speci...
Definition AMReX_BaseFab.H:1538
Reference-counted collection of Boxes.
Definition AMReX_BoxArray.H:681
IndexType ixType() const noexcept
Return index type of this BoxArray.
Definition AMReX_BoxArray.H:1268
BoxArray & grow(int n)
Grow each Box by n cells in every direction.
Definition AMReX_BoxArray.cpp:722
std::vector< std::pair< int, Box > > intersections(const Box &bx) const
Return all intersections of bx with this BoxArray.
Definition AMReX_BoxArray.cpp:1202
Box getCellCenteredBox(int index) const noexcept
Return cell-centered box at element index of this BoxArray.
Definition AMReX_BoxArray.H:1099
static bool SameRefs(const BoxArray &lhs, const BoxArray &rhs)
whether two BoxArrays share the same data
Definition AMReX_BoxArray.H:1251
A list of Boxes sharing a common IndexType.
Definition AMReX_BoxList.H:109
BoxList & complementIn(const Box &b, const BoxList &bl)
Set this BoxList to the complement of BoxList bl in Box b.
Definition AMReX_BoxList.cpp:312
__host__ __device__ BoxND & grow(int i) noexcept
Grow in all directions by i cells (negative shrinks).
Definition AMReX_Box.H:668
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
GpuArray< Real, 3 > InvCellSizeArray() const noexcept
Returns the inverse cell sizes as a GpuArray for use on host or device.
Definition AMReX_CoordSys.H:97
A Fortran Array of REALs.
Definition AMReX_FArrayBox.H:237
void resize(const Box &b, int N=1, Arena *ar=nullptr)
For debugging purposes we hide BaseFab version and do some extra work.
Definition AMReX_FArrayBox.cpp:178
int size() const noexcept
Return the number of FABs in the FabArray.
Definition AMReX_FabArrayBase.H:115
int nGrow(int direction=0) const noexcept
Return the grow factor that defines the region of definition.
Definition AMReX_FabArrayBase.H:83
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition AMReX_FabArrayBase.H:135
const BoxArray & boxArray() const noexcept
Return a constant reference to the BoxArray that defines the valid region associated with this FabArr...
Definition AMReX_FabArrayBase.H:100
void ParallelCopy(const FabArray< FAB > &src, const Periodicity &period=Periodicity::NonPeriodic(), CpOp op=FabArrayBase::COPY)
Definition AMReX_FabArray.H:971
void setVal(value_type val)
Set all components in the entire region of each FAB to val.
Definition AMReX_FabArray.H:2988
Array4< typename FabArray< FAB >::value_type const > array(const MFIter &mfi) const noexcept
Read-only Array4 view for the FAB referenced by iterator mfi.
Definition AMReX_FabArray.H:621
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:87
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:246
GpuArray< Real, 3 > ProbLoArray() const noexcept
Return the lo end of the problem domain in a GpuArray for device code.
Definition AMReX_Geometry.H:219
static void streamSynchronize() noexcept
Definition AMReX_GpuDevice.cpp:992
__host__ __device__ bool cellCentered() const noexcept
True if the IndexTypeND is CELL based in all directions.
Definition AMReX_IndexType.H:102
An Integer Vector in dim-Dimensional Space.
Definition AMReX_IntVect.H:149
__host__ __device__ constexpr bool allGE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than or equal to argument for all components. NOTE: This is NOT a str...
Definition AMReX_IntVect.H:542
__host__ static __device__ constexpr IntVectND< dim > TheZeroVector() noexcept
Definition AMReX_IntVect.H:771
a one-thingy-per-box distributed object
Definition AMReX_LayoutData.H:13
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
int LocalTileIndex() const noexcept
The current local tile index in the current grid;.
Definition AMReX_MFIter.H:185
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:176
Box validbox() const noexcept
Return the valid Box in which the current tile resides.
Definition AMReX_MFIter.H:167
int index() const noexcept
The index into the underlying BoxArray of the current FAB.
Definition AMReX_MFIter.H:179
A collection (stored as an array) of FArrayBox objects.
Definition AMReX_MultiFab.H:40
void mult(Real val, int comp, int num_comp, int nghost=0)
Scales the value of each cell in the specified subregion of the MultiFab by the scalar val (a[i] <- a...
Definition AMReX_MultiFab.cpp:1620
size_type size() const noexcept
Definition AMReX_PODVector.H:654
void resize(size_type a_new_size, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_PODVector.H:734
T * dataPtr() noexcept
Definition AMReX_PODVector.H:676
Definition AMReX_ParIter.H:147
Parse Parameters From Command Line and Input Files.
Definition AMReX_ParmParse.H:354
const DistributionMapping & ParticleDistributionMap(int lev) const
Get the DistributionMapping for a given level.
Definition AMReX_ParticleContainerBase.H:207
ParGDBBase * m_gdb
Definition AMReX_ParticleContainerBase.H:305
const BoxArray & ParticleBoxArray(int lev) const
Get the BoxArray for a given level.
Definition AMReX_ParticleContainerBase.H:200
virtual void reserveData()
Definition AMReX_ParticleContainerBase.cpp:70
static const std::string & AggregationType()
Definition AMReX_ParticleContainerBase.cpp:321
const Geometry & Geom(int lev) const
Get the Geometry for a given level.
Definition AMReX_ParticleContainerBase.H:214
static bool memEfficientSort
Definition AMReX_ParticleContainerBase.H:286
bool RedistributeMaskLooksCheap(int lev, IntVect nghost) const
Definition AMReX_ParticleContainerBase.cpp:361
int numLevels() const
the number of defined levels in the ParticleContainer
Definition AMReX_ParticleContainerBase.H:229
int m_verbose
Definition AMReX_ParticleContainerBase.H:302
const ParGDBBase * GetParGDB() const
Get the ParGDB object used to define this container (const version).
Definition AMReX_ParticleContainerBase.H:232
bool OnSameGrids(int level, const MF &mf) const
Definition AMReX_ParticleContainerBase.H:266
static bool do_tiling
Definition AMReX_ParticleContainerBase.H:284
void BuildRedistributeMask(int lev, IntVect nghost) const
Definition AMReX_ParticleContainerBase.cpp:427
AmrParticleLocator< DenseBins< Box > > m_particle_locator
Definition AMReX_ParticleContainerBase.H:288
int finestLevel() const
the finest level actually defined for the ParticleContainer
Definition AMReX_ParticleContainerBase.H:223
void defineBufferMap() const
Definition AMReX_ParticleContainerBase.cpp:102
static int AggregationBuffer()
Definition AMReX_ParticleContainerBase.cpp:341
void RedefineDummyMF(int lev)
Definition AMReX_ParticleContainerBase.cpp:84
int maxLevel() const
the finest allowed level in the ParticleContainer, whether it is defined or not.
Definition AMReX_ParticleContainerBase.H:226
Vector< std::unique_ptr< MultiFab > > m_dummy_mf
Definition AMReX_ParticleContainerBase.H:306
MFIter MakeMFIter(int lev, const MFItInfo &info) const
Definition AMReX_ParticleContainerBase.H:112
const ParticleBufferMap & BufferMap() const
Definition AMReX_ParticleContainerBase.H:245
static IntVect tile_size
Definition AMReX_ParticleContainerBase.H:285
virtual void resizeData()
Definition AMReX_ParticleContainerBase.cpp:75
A distributed container for Particles sorted onto the levels, grids, and tiles of a block-structured ...
Definition AMReX_ParticleContainer.H:149
IntVect Index(const P &p, int lev) const
Definition AMReX_ParticleContainerI.H:202
void ResizeRuntimeIntComp(int new_size, bool communicate)
Definition AMReX_ParticleContainerI.H:2023
bool OK(int lev_min=0, int lev_max=-1, int nGrow=0) const
Definition AMReX_ParticleContainerI.H:1796
void CapacityOfParticlesInGrid(LayoutData< Int > &mem, int lev) const
Return capacity of memory for particles at specific grid.
Definition AMReX_ParticleContainerI.H:596
std::conditional_t< is_rtsoa_pc, ParticleTileRT< typename ParticleType::RealType, typename ParticleType::IntType >, ParticleTile< ParticleType, NArrayReal, NArrayInt, Allocator > > ParticleTileType
Definition AMReX_ParticleContainer.H:187
bool PeriodicShift(P &p) const
Returns true if the particle was shifted.
Definition AMReX_ParticleContainerI.H:377
std::map< std::pair< int, int >, ParticleTileType > ParticleLevel
Definition AMReX_ParticleContainer.H:196
static constexpr int NArrayInt
Number of extra integer components stored in struct-of-array form.
Definition AMReX_ParticleContainer.H:162
static constexpr int NArrayReal
Number of extra Real components stored in struct-of-array form.
Definition AMReX_ParticleContainer.H:160
void SetSoACompileTimeNames(std::vector< std::string > const &rdata_name, std::vector< std::string > const &idata_name)
Definition AMReX_ParticleContainerI.H:110
void Redistribute(int lev_min=0, int lev_max=-1, int nGrow=0, int local=0, bool remove_negative=true)
Redistribute puts all the particles back in the right places (for some value of right).
Definition AMReX_ParticleContainer.H:514
typename ParticleTileType::AoS AoS
Definition AMReX_ParticleContainer.H:199
void SetParticleSize()
Definition AMReX_ParticleContainerI.H:17
void RemoveParticlesAtLevel(int level)
The Following methods are for managing Virtual and Ghost Particles.
Definition AMReX_ParticleContainerI.H:760
const ParticleTileType & ParticlesAt(int lev, int grid, int tile) const
Return the ParticleTile for level "lev", grid "grid" and tile "tile." Const version.
Definition AMReX_ParticleContainer.H:1096
static constexpr int NStructInt
Number of extra integer components in the particle struct.
Definition AMReX_ParticleContainer.H:158
ParticleContainer_impl()
Definition AMReX_ParticleContainer.H:217
int NumRealComps() const
Definition AMReX_ParticleContainer.H:1385
void clearParticles()
Clear all the particles in this container. This does not free memory.
Definition AMReX_ParticleContainerI.H:1131
void Increment(MultiFab &mf, int level)
Definition AMReX_ParticleContainerI.H:723
Vector< int > h_redistribute_int_comp
Definition AMReX_ParticleContainer.H:1449
void AssignCellDensitySingleLevel(int rho_index, MultiFab &mf, int level, int ncomp=1, int particle_lvl_offset=0) const
Definition AMReX_ParticleContainerI.H:1857
void CreateGhostParticles(int level, int ngrow, AoS &ghosts) const
Create ghost particles for a given level that are copies of particles near coarse->fine boundaries in...
Definition AMReX_ParticleContainerI.H:1086
void SortParticlesByBin(IntVect bin_size)
Sort the particles on each tile by groups of cells, given an IntVect bin_size.
Definition AMReX_ParticleContainerI.H:1295
bool HasIntComp(std::string const &name)
Definition AMReX_ParticleContainerI.H:149
DefaultAssignor CellAssignor
Definition AMReX_ParticleContainer.H:153
const Vector< ParticleLevel > & GetParticles() const
Definition AMReX_ParticleContainer.H:1036
DenseBins< typename ParticleTileType::ParticleTileDataType > m_bins
Definition AMReX_ParticleContainer.H:1561
void ShrinkToFit()
Definition AMReX_ParticleContainerI.H:703
ParConstIter_impl< ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor > ParConstIterType
Definition AMReX_ParticleContainer.H:207
bool HasRealComp(std::string const &name)
Definition AMReX_ParticleContainerI.H:141
void resizeData() override
This resizes the vector of dummy MultiFabs used by the ParticleContainer for the current number of le...
Definition AMReX_ParticleContainerI.H:436
int NumRuntimeRealComps() const
Definition AMReX_ParticleContainer.H:1382
void ResizeRuntimeRealComp(int new_size, bool communicate)
Definition AMReX_ParticleContainerI.H:1997
Long IncrementWithTotal(MultiFab &mf, int level, bool local=false)
Definition AMReX_ParticleContainerI.H:750
static constexpr int NStructReal
Number of extra Real components in the particle struct.
Definition AMReX_ParticleContainer.H:156
Long NumberOfParticlesAtLevel(int level, bool only_valid=true, bool only_local=false) const
Returns # of particles at specified the level.
Definition AMReX_ParticleContainerI.H:553
void SortParticlesByCell()
Sort the particles on each tile by cell, using Fortran ordering.
Definition AMReX_ParticleContainerI.H:1286
Vector< int > h_redistribute_real_comp
Definition AMReX_ParticleContainer.H:1448
void addParticles(const PCType &other, bool local=false)
Add particles from other to this ParticleContainer. local controls whether or not to call Redistribut...
Definition AMReX_ParticleContainerI.H:1160
static constexpr bool is_rtsoa_pc
Definition AMReX_ParticleContainer.H:184
int GetRealCompIndex(std::string const &name)
Definition AMReX_ParticleContainerI.H:162
int NumIntComps() const
Definition AMReX_ParticleContainer.H:1386
bool Where(const P &prt, ParticleLocData &pld, int lev_min=0, int lev_max=-1, IntVect nGrow=IntVect(0), int local_grid=-1) const
Definition AMReX_ParticleContainerI.H:217
void Redistribute_impl(int lev_min=0, int lev_max=-1, int nGrow=0, int local=0, bool remove_negative=true)
Definition AMReX_ParticleContainer.H:1301
int GetIntCompIndex(std::string const &name)
Definition AMReX_ParticleContainerI.H:184
ParticleTileType & DefineAndReturnParticleTile(int lev, int grid, int tile)
Define and return the ParticleTile for level "lev", grid "grid" and tile "tile.".
Definition AMReX_ParticleContainer.H:1196
void copyParticles(const PCType &other, bool local=false)
Copy particles from other to this ParticleContainer. Will clear all the particles from this container...
Definition AMReX_ParticleContainerI.H:1148
void RemoveParticlesNotAtFinestLevel()
Definition AMReX_ParticleContainerI.H:774
Vector< Long > NumberOfParticlesInGrid(int level, bool only_valid=true, bool only_local=false) const
Definition AMReX_ParticleContainerI.H:497
ParticleLocData Reset(ParticleType &prt, bool update, bool verbose=true, ParticleLocData pld=ParticleLocData()) const
Updates a particle's location (Where), tries to periodic shift any particles that have left the domai...
Definition AMReX_ParticleContainerI.H:393
void CreateVirtualParticles(int level, AoS &virts) const
Creates virtual particles for a given level that represent in some capacity all particles at finer le...
Definition AMReX_ParticleContainerI.H:841
ParIter_impl< ParticleType, NArrayReal, NArrayInt, Allocator, CellAssignor > ParIterType
Definition AMReX_ParticleContainer.H:206
void AddParticlesAtLevel(AoS &particles, int level, int nGrow=0)
Add particles from a pbox to the grid at this level.
Definition AMReX_ParticleContainerI.H:1811
Long TotalNumberOfParticles(bool only_valid=true, bool only_local=false) const
Returns # of particles at all levels.
Definition AMReX_ParticleContainerI.H:482
void reserveData() override
This reserves data in the vector of dummy MultiFabs used by the ParticleContainer for the maximum num...
Definition AMReX_ParticleContainerI.H:427
T_ParticleType ParticleType
Definition AMReX_ParticleContainer.H:151
Definition AMReX_ParticleLocator.H:137
void build(const BoxArray &ba, const Geometry &geom, bool a_do_tiling=false, const IntVect &a_tile_size=IntVect(1024000, 1024000, 1024000))
Definition AMReX_ParticleLocator.H:144
AssignGrid< BinIteratorFactory > getGridAssignor() const noexcept
Definition AMReX_ParticleLocator.H:220
This class provides the user with a few print options.
Definition AMReX_Print.H:35
Definition AMReX_Reduce.H:556
Type value()
Definition AMReX_Reduce.H:591
Definition AMReX_Reduce.H:715
void eval(MF const &mf, IntVect const &nghost, D &reduce_data, F &&f)
Definition AMReX_Reduce.H:852
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
A Collection of IArrayBoxes.
Definition AMReX_iMultiFab.H:34
Long sum(int comp, int nghost=0, bool local=false) const
Returns the sum in component comp.
Definition AMReX_iMultiFab.cpp:460
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
amrex_particle_real ParticleReal
Floating Point Type for Particles.
Definition AMReX_REAL.H:91
amrex_long Long
Definition AMReX_INT.H:30
T ExclusiveSum(N n, T const *in, T *out, RetSum a_ret_sum=retSum)
Exclusive sum.
Definition AMReX_Scan.H:1045
ArrayND< T, 4, true > Array4
Convenient alias for a 4D ArrayND with three spatial dimensions plus a component dimension.
Definition AMReX_Array4.H:1340
void SumBoundary(const Periodicity &period=Periodicity::NonPeriodic(), bool deterministic=false)
Sum values in overlapped cells.
Definition AMReX_FabArray.H:3938
__host__ __device__ BoxND< dim > grow(const BoxND< dim > &b, int i) noexcept
Return a copy of b grown uniformly by i cells in every direction.
Definition AMReX_Box.H:1328
PODVector< T, PinnedArenaAllocator< T > > PinnedVector
A PODVector that uses the pinned memory arena.
Definition AMReX_GpuContainers.H:48
PODVector< T, ArenaAllocator< T > > DeviceVector
A PODVector that uses the standard memory Arena. Note that the memory might or might not be managed d...
Definition AMReX_GpuContainers.H:24
Arena * The_Comms_Arena()
Definition AMReX_Arena.cpp:899
void Min(KeyValuePair< K, V > &vi, int root, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:287
void Max(KeyValuePair< K, V > &vi, int root, MPI_Comm comm)
Definition AMReX_ParallelReduce.H:254
void Bcast(Gpu::DeviceVector< T > &v, int root, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:105
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:37
void Sum(Gpu::DeviceVector< T > &v, int root, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:62
__host__ __device__ AMREX_FORCE_INLINE void AddNoRet(T *sum, T value) noexcept
Definition AMReX_GpuAtomic.H:283
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:329
void dtoh_memcpy_async(void *p_h, const void *p_d, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:454
bool notInLaunchRegion() noexcept
Definition AMReX_GpuControl.H:89
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition AMReX_GpuDevice.H:440
void QueueReduction(Func f)
Definition AMReX_Lazy.cpp:7
constexpr Long GhostParticleID
Definition AMReX_Particle.H:19
constexpr Long VirtualParticleID
Definition AMReX_Particle.H:20
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
int MyProcSub() noexcept
my sub-rank in current frame
Definition AMReX_ParallelContext.H:76
int IOProcessorNumberSub() noexcept
IO sub-rank in current frame.
Definition AMReX_ParallelContext.H:78
bool UseGpuAwareMpi()
Definition AMReX_ParallelDescriptor.H:113
void GatherLayoutDataToVector(const LayoutData< T > &sendbuf, Vector< T > &recvbuf, int root)
Gather LayoutData values to a vector on root.
Definition AMReX_ParallelDescriptor.H:1286
static constexpr RetSum retSum
Definition AMReX_Scan.H:34
Definition AMReX_Amr.cpp:50
void gatherParticles(PTile &dst, const PTile &src, N np, const Index *inds)
Gather particles copies particles into contiguous order from an arbitrary order. Specifically,...
Definition AMReX_ParticleTransformation.H:739
ParConstIter_impl< Particle< T_NStructReal, T_NStructInt >, T_NArrayReal, T_NArrayInt, Allocator, CellAssignor > ParConstIter
Definition AMReX_ParIter.H:227
__host__ __device__ void swapParticle(const ParticleTileData< T_ParticleType, NAR, NAI > &dst, const ParticleTileData< T_ParticleType, NAR, NAI > &src, int src_i, int dst_i) noexcept
A general single particle swapping routine that can run on the GPU.
Definition AMReX_ParticleTransformation.H:120
__host__ __device__ int getTileIndex(const IntVect &iv, const Box &box, const bool a_do_tiling, const IntVect &a_tile_size, Box &tbx)
Definition AMReX_ParticleUtil.H:191
@ F
Definition AMReX_Order.H:7
__host__ __device__ void copyParticle(const ParticleTileData< T_ParticleType, NAR, NAI > &dst, const ConstParticleTileData< T_ParticleType, NAR, NAI > &src, int src_i, int dst_i) noexcept
A general single particle copying routine that can run on the GPU.
Definition AMReX_ParticleTransformation.H:32
void copyParticles(DstTile &dst, const SrcTile &src) noexcept
Copy particles from src to dst. This version copies all the particles, writing them to the beginning ...
Definition AMReX_ParticleTransformation.H:222
std::string getDefaultCompNameInt(const int i)
Definition AMReX_ParticleUtil.H:937
@ Host
Definition AMReX_GpuControl.H:65
@ Device
Definition AMReX_GpuControl.H:65
void communicateParticlesStart(const PC &pc, ParticleCopyPlan &plan, const SndBuffer &snd_buffer, RcvBuffer &rcv_buffer)
Definition AMReX_ParticleCommunication.H:910
int partitionParticlesByDest(PTile &ptile, const PLocator &ploc, CellAssignor const &assignor, const ParticleBufferMap &pmap, const GpuArray< Real, 3 > &plo, const GpuArray< Real, 3 > &phi, const GpuArray< ParticleReal, 3 > &rlo, const GpuArray< ParticleReal, 3 > &rhi, const GpuArray< int, 3 > &is_per, int lev, int gid, int tid, int lev_min, int lev_max, IntVect nGrow, bool remove_negative)
Definition AMReX_ParticleUtil.H:654
void ReorderParticles(PTile &ptile, const index_type *permutations)
Reorder particles on the tile ptile using a the permutations array.
Definition AMReX_ParticleUtil.H:955
__host__ __device__ bool enforcePeriodic(P &p, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &phi, amrex::GpuArray< amrex::ParticleReal, 3 > const &rlo, amrex::GpuArray< amrex::ParticleReal, 3 > const &rhi, amrex::GpuArray< int, 3 > const &is_per) noexcept
Definition AMReX_ParticleUtil.H:423
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
__host__ __device__ int numTilesInBox(const Box &box, const bool a_do_tiling, const IntVect &a_tile_size)
Definition AMReX_ParticleUtil.H:239
BoxND< 3 > Box
Box is an alias for amrex::BoxND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:35
std::string getDefaultCompNameReal(const int i)
Definition AMReX_ParticleUtil.H:922
void ParticleToMesh(PC const &pc, const Vector< MultiFab * > &mf, int lev_min, int lev_max, F &&f, bool zero_out_input=true, bool vol_weight=true)
Deposit particles onto a hierarchy of MultiFabs.
Definition AMReX_AmrParticles.H:189
void unpackBuffer(PC &pc, const ParticleCopyPlan &plan, const Buffer &snd_buffer, UnpackPolicy const &policy)
Definition AMReX_ParticleCommunication.H:783
double second() noexcept
Definition AMReX_Utility.cpp:919
void packBuffer(const PC &pc, const ParticleCopyOp &op, const ParticleCopyPlan &plan, Buffer &snd_buffer)
Definition AMReX_ParticleCommunication.H:583
int nComp(FabArrayBase const &fa)
Convenience wrapper that forwards to fa.nComp().
Definition AMReX_FabArrayBase.cpp:2980
void communicateParticlesFinish(const ParticleCopyPlan &plan)
Definition AMReX_ParticleCommunication.cpp:445
Index filterAndTransformParticles(DstTile &dst, const SrcTile &src, Index *mask, F const &f, Index src_start, Index dst_start) noexcept
Conditionally copy particles from src to dst based on the value of mask. A transformation will also b...
Definition AMReX_ParticleTransformation.H:516
void unpackRemotes(PC &pc, const ParticleCopyPlan &plan, Buffer &rcv_buffer, UnpackPolicy const &policy)
Definition AMReX_ParticleCommunication.H:1010
void Error(const std::string &msg)
Print a message to stderr and abort the program.
Definition AMReX.cpp:238
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
int numParticlesOutOfRange(Iterator const &pti, int nGrow)
Returns the number of particles that are more than nGrow cells from the box correspond to the input i...
Definition AMReX_ParticleUtil.H:36
void PermutationForDeposition(Gpu::DeviceVector< index_type > &perm, index_type nitems, index_type nbins, F const &f)
Definition AMReX_ParticleUtil.H:768
int Verbose() noexcept
Return the verbosity level configured via ParmParse or SetVerbose().
Definition AMReX.cpp:184
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:244
const int[]
Definition AMReX_BLProfiler.cpp:1665
Index filterParticles(DstTile &dst, const SrcTile &src, const Index *mask) noexcept
Conditionally copy particles from src to dst based on the value of mask.
Definition AMReX_ParticleTransformation.H:389
void transformParticles(DstTile &dst, const SrcTile &src, F &&f) noexcept
Apply the function f to all the particles in src, writing the result to dst. This version does all th...
Definition AMReX_ParticleTransformation.H:273
__host__ __device__ IntVect getParticleCell(P const &p, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &dxi) noexcept
Returns the cell index for a given particle using the provided lower bounds and cell sizes.
Definition AMReX_ParticleUtil.H:343
__host__ __device__ constexpr int get(IntVectND< dim > const &iv) noexcept
Get the Idx-th element of IntVectND<dim>.
Definition AMReX_IntVect.H:1360
Definition AMReX_ParticleLocator.H:262
Definition AMReX_ParticleContainerI.H:1041
amrex::AmrAssignGrid< amrex::DenseBinIteratorFactory< amrex::Box > > m_assign_grid
Definition AMReX_ParticleContainerI.H:1044
int m_lev_max
Definition AMReX_ParticleContainerI.H:1043
AssignGridFilter(amrex::AmrAssignGrid< amrex::DenseBinIteratorFactory< amrex::Box > > assign_grid, int gid, int level, int nGrow)
This filters based on matching grids.
Definition AMReX_ParticleContainerI.H:1050
int m_nGrow
Definition AMReX_ParticleContainerI.H:1043
int m_lev_min
Definition AMReX_ParticleContainerI.H:1043
AMREX_GPU_HOST_DEVICE int operator()(const SrcData &src, int src_i) const noexcept
Definition AMReX_ParticleContainerI.H:1056
int m_gid
Definition AMReX_ParticleContainerI.H:1043
Definition AMReX_ParticleLocator.H:17
Definition AMReX_ParticleUtil.H:396
Definition AMReX_DenseBins.H:110
Definition AMReX_ParticleContainerI.H:802
Box m_domain
Definition AMReX_ParticleContainerI.H:806
GpuArray< Real, 3 > m_dxi
Definition AMReX_ParticleContainerI.H:805
FilterVirt(const amrex::AssignGrid< amrex::DenseBinIteratorFactory< amrex::Box > > &assign_buffer_grid, const GpuArray< Real, 3 > &plo, const GpuArray< Real, 3 > &dxi, const Box &domain)
Definition AMReX_ParticleContainerI.H:808
AMREX_GPU_HOST_DEVICE int operator()(const SrcData &src, int src_i) const noexcept
Definition AMReX_ParticleContainerI.H:815
amrex::AssignGrid< amrex::DenseBinIteratorFactory< amrex::Box > > m_assign_buffer_grid
Definition AMReX_ParticleContainerI.H:804
GpuArray< Real, 3 > m_plo
Definition AMReX_ParticleContainerI.H:805
Definition AMReX_ParticleUtil.H:310
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:52
Definition AMReX_GpuControl.H:180
Definition AMReX_TypeTraits.H:90
Definition AMReX_ParticleCommunication.H:92
Vector< int > m_rcv_box_ids
Definition AMReX_ParticleCommunication.H:366
Vector< int > m_rcv_box_counts
Definition AMReX_ParticleCommunication.H:364
void build(const PC &pc, const ParticleCopyOp &op, const Vector< int > &int_comp_mask, const Vector< int > &real_comp_mask, bool local, IntVect max_cells_moved)
Definition AMReX_ParticleCommunication.H:409
Vector< int > m_rcv_box_levs
Definition AMReX_ParticleCommunication.H:369
Vector< int > m_rcv_box_tids
Definition AMReX_ParticleCommunication.H:367
int m_nrcvs
Definition AMReX_ParticleCommunication.H:372
Gpu::HostVector< unsigned int > m_box_counts_h
Definition AMReX_ParticleCommunication.H:361
A struct used for storing a particle's position in the AMR hierarchy.
Definition AMReX_ParticleContainer.H:93
Box m_grown_gridbox
Definition AMReX_ParticleContainer.H:100
IntVect m_cell
Definition AMReX_ParticleContainer.H:97
int m_grid
Definition AMReX_ParticleContainer.H:95
int m_tile
Definition AMReX_ParticleContainer.H:96
int m_lev
Definition AMReX_ParticleContainer.H:94
Box m_tilebox
Definition AMReX_ParticleContainer.H:99
Box m_gridbox
Definition AMReX_ParticleContainer.H:98
The struct used to store particles.
Definition AMReX_Particle.H:405
__host__ __device__ RealVect pos() const &
Definition AMReX_Particle.H:456
Definition AMReX_ParticleCommunication.H:42