Skip to content

Commit 8aec382

Browse files
committed
SoA: InitRandom/RandomPerBox/OnePerCell
Support more init methods on SoA particle containers.
1 parent 76d6d34 commit 8aec382

File tree

2 files changed

+58
-24
lines changed

2 files changed

+58
-24
lines changed

Src/Particle/AMReX_ParticleContainer.H

+22-4
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,35 @@ struct ParticleLocData
108108
*
109109
* Example usage:
110110
*
111-
* ParticleInitType<0, 2, 4, 1> pdata = {{}, {7, 9}, {1.5, 2.5, 3.5, 4.5}, {11}};
111+
* ParticleInitType<Particle<0, 2>, 4, 1> pdata = {{}, {7, 9}, {1.5, 2.5, 3.5, 4.5}, {11}};
112+
* ParticleInitType<SoAParticle<3, 2>, 3, 2> pdata = {{1.5, 2.5, 3.5, 4.5}, {7, 9}};
112113
*/
113-
template<int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
114-
struct ParticleInitType
114+
template <int NArrayReal, int NArrayInt>
115+
struct ParticleInitTypeSoA
116+
{
117+
std::array<double, NArrayReal > real_array_data;
118+
std::array<int, NArrayInt > int_array_data;
119+
};
120+
template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt>
121+
struct ParticleInitTypeLegacy
115122
{
116123
std::array<double, NStructReal> real_struct_data;
117124
std::array<int, NStructInt > int_struct_data;
118125
std::array<double, NArrayReal > real_array_data;
119126
std::array<int, NArrayInt > int_array_data;
120127
};
121128

129+
template <typename T_ParticleType, int NArrayReal=0, int NArrayInt=0>
130+
struct ParticleInitType
131+
: public std::conditional<
132+
T_ParticleType::is_soa_particle,
133+
ParticleInitTypeSoA<NArrayReal, NArrayInt>,
134+
ParticleInitTypeLegacy<T_ParticleType::NReal, T_ParticleType::NInt, NArrayReal, NArrayInt>
135+
>::type
136+
{
137+
using ParticleType = T_ParticleType;
138+
};
139+
122140
template <bool is_const, typename T_ParticleType, int NArrayReal, int NArrayInt,
123141
template<class> class Allocator>
124142

@@ -177,7 +195,7 @@ public:
177195

178196
using ParticleContainerType = ParticleContainer_impl<ParticleType, NArrayReal, NArrayInt, Allocator>;
179197
using ParticleTileType = ParticleTile<ParticleType, NArrayReal, NArrayInt, Allocator>;
180-
using ParticleInitData = ParticleInitType<NStructReal, NStructInt, NArrayReal, NArrayInt>;
198+
using ParticleInitData = ParticleInitType<ParticleType, NArrayReal, NArrayInt>;
181199

182200
//! A single level worth of particles is indexed (grid id, tile id)
183201
//! for both SoA and AoS data.

Src/Particle/AMReX_ParticleInit.H

+36-20
Original file line numberDiff line numberDiff line change
@@ -1438,48 +1438,64 @@ InitOnePerCell (Real x_off, Real y_off, Real z_off, const ParticleInitData& pdat
14381438

14391439
const Real* dx = geom.CellSize();
14401440

1441-
ParticleType p;
1442-
14431441
// We'll generate the particles in parallel -- but no tiling of the grid here.
14441442
for (MFIter mfi(*m_dummy_mf[0], false); mfi.isValid(); ++mfi) {
14451443
Box grid = ParticleBoxArray(0)[mfi.index()];
14461444
auto ind = std::make_pair(mfi.index(), mfi.LocalTileIndex());
14471445
RealBox grid_box (grid,dx,geom.ProbLo());
1446+
1447+
// tile for one particle
14481448
ParticleTile<ParticleType, NArrayReal, NArrayInt, amrex::PinnedArenaAllocator> ptile_tmp;
1449+
ptile_tmp.resize(1);
1450+
auto ptd = ptile_tmp.getParticleTileData();
1451+
14491452
for (IntVect beg = grid.smallEnd(), end=grid.bigEnd(), cell = grid.smallEnd(); cell <= end; grid.next(cell))
14501453
{
1451-
// the real struct data
1452-
AMREX_D_TERM(p.pos(0) = static_cast<ParticleReal>(grid_box.lo(0) + (x_off + cell[0]-beg[0])*dx[0]);,
1453-
p.pos(1) = static_cast<ParticleReal>(grid_box.lo(1) + (y_off + cell[1]-beg[1])*dx[1]);,
1454-
p.pos(2) = static_cast<ParticleReal>(grid_box.lo(2) + (z_off + cell[2]-beg[2])*dx[2]););
1454+
// particle index
1455+
constexpr int i = 0;
1456+
1457+
// the position data
1458+
for (int d = 0; d < AMREX_SPACEDIM; d++) {
1459+
ptile_tmp.pos(i, d) = static_cast<ParticleReal>(grid_box.lo(d) + (x_off + cell[d]-beg[d])*dx[d]);
1460+
}
14551461

14561462
for (int d = 0; d < AMREX_SPACEDIM; ++d) {
1457-
AMREX_ASSERT(p.pos(d) < grid_box.hi(d));
1463+
AMREX_ASSERT(ptile_tmp.pos(i, d) < grid_box.hi(d));
14581464
}
14591465

1460-
for (int i = 0; i < NStructReal; i++) {
1461-
p.rdata(i) = static_cast<ParticleReal>(pdata.real_struct_data[i]);
1466+
if constexpr(!ParticleType::is_soa_particle) {
1467+
for (int n = 0; n < NStructReal; n++) {
1468+
ptd.rdata(n)[i] = static_cast<ParticleReal>(pdata.real_struct_data[n]);
1469+
}
14621470
}
14631471

14641472
// the int struct data
1465-
p.id() = ParticleType::NextID();
1466-
p.cpu() = ParallelDescriptor::MyProc();
1467-
1468-
for (int i = 0; i < NStructInt; i++) {
1469-
p.idata(i) = pdata.int_struct_data[i];
1473+
if constexpr(ParticleType::is_soa_particle) {
1474+
ptd.idata(0)[i] = ParticleType::NextID();
1475+
ptd.idata(1)[i] = ParallelDescriptor::MyProc();
1476+
}
1477+
else {
1478+
auto& p = make_particle<ParticleType>{}(ptd, i);
1479+
p.id() = ParticleType::NextID();
1480+
p.cpu() = ParallelDescriptor::MyProc();
14701481
}
14711482

1472-
// add the struct
1473-
ptile_tmp.push_back(p);
1483+
if constexpr(!ParticleType::is_soa_particle) {
1484+
for (int n = 0; n < NStructInt; n++) {
1485+
ptd.idata(n)[i] = pdata.int_struct_data[n];
1486+
}
1487+
}
14741488

14751489
// add the real...
1476-
for (int i = 0; i < NArrayReal; i++) {
1477-
ptile_tmp.push_back_real(i, static_cast<ParticleReal>(pdata.real_array_data[i]));
1490+
int n_min_real = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0; // jump over position
1491+
for (int n = n_min_real; n < NArrayReal; n++) {
1492+
ptile_tmp.push_back_real(n, static_cast<ParticleReal>(pdata.real_array_data[n]));
14781493
}
14791494

14801495
// ... and int array data
1481-
for (int i = 0; i < NArrayInt; i++) {
1482-
ptile_tmp.push_back_int(i, pdata.int_array_data[i]);
1496+
int n_min_int = ParticleType::is_soa_particle ? 2 : 0; // jump over cpuid
1497+
for (int n = n_min_int; n < NArrayInt; n++) {
1498+
ptile_tmp.push_back_int(n, pdata.int_array_data[n]);
14831499
}
14841500
}
14851501

0 commit comments

Comments
 (0)