Skip to content

Commit 3ca6008

Browse files
committed
SoA: InitRandom/RandomPerBox/OnePerCell
Support more init methods on SoA particle containers.
1 parent a6e89ec commit 3ca6008

File tree

3 files changed

+69
-25
lines changed

3 files changed

+69
-25
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
@@ -1354,48 +1354,64 @@ InitOnePerCell (Real x_off, Real y_off, Real z_off, const ParticleInitData& pdat
13541354

13551355
const Real* dx = geom.CellSize();
13561356

1357-
ParticleType p;
1358-
13591357
// We'll generate the particles in parallel -- but no tiling of the grid here.
13601358
for (MFIter mfi(*m_dummy_mf[0], false); mfi.isValid(); ++mfi) {
13611359
Box grid = ParticleBoxArray(0)[mfi.index()];
13621360
auto ind = std::make_pair(mfi.index(), mfi.LocalTileIndex());
13631361
RealBox grid_box (grid,dx,geom.ProbLo());
1362+
1363+
// tile for one particle
13641364
ParticleTile<ParticleType, NArrayReal, NArrayInt, amrex::PinnedArenaAllocator> ptile_tmp;
1365+
ptile_tmp.resize(1);
1366+
auto ptd = ptile_tmp.getParticleTileData();
1367+
13651368
for (IntVect beg = grid.smallEnd(), end=grid.bigEnd(), cell = grid.smallEnd(); cell <= end; grid.next(cell))
13661369
{
1367-
// the real struct data
1368-
AMREX_D_TERM(p.pos(0) = static_cast<ParticleReal>(grid_box.lo(0) + (x_off + cell[0]-beg[0])*dx[0]);,
1369-
p.pos(1) = static_cast<ParticleReal>(grid_box.lo(1) + (y_off + cell[1]-beg[1])*dx[1]);,
1370-
p.pos(2) = static_cast<ParticleReal>(grid_box.lo(2) + (z_off + cell[2]-beg[2])*dx[2]););
1370+
// particle index
1371+
constexpr int i = 0;
1372+
1373+
// the position data
1374+
for (int d = 0; d < AMREX_SPACEDIM; d++) {
1375+
ptile_tmp.pos(i, d) = static_cast<ParticleReal>(grid_box.lo(d) + (x_off + cell[d]-beg[d])*dx[d]);
1376+
}
13711377

13721378
for (int d = 0; d < AMREX_SPACEDIM; ++d) {
1373-
AMREX_ASSERT(p.pos(d) < grid_box.hi(d));
1379+
AMREX_ASSERT(ptile_tmp.pos(i, d) < grid_box.hi(d));
13741380
}
13751381

1376-
for (int i = 0; i < NStructReal; i++) {
1377-
p.rdata(i) = static_cast<ParticleReal>(pdata.real_struct_data[i]);
1382+
if constexpr(!ParticleType::is_soa_particle) {
1383+
for (int n = 0; n < NStructReal; n++) {
1384+
ptd.rdata(n)[i] = static_cast<ParticleReal>(pdata.real_struct_data[n]);
1385+
}
13781386
}
13791387

13801388
// the int struct data
1381-
p.id() = ParticleType::NextID();
1382-
p.cpu() = ParallelDescriptor::MyProc();
1383-
1384-
for (int i = 0; i < NStructInt; i++) {
1385-
p.idata(i) = pdata.int_struct_data[i];
1389+
if constexpr(ParticleType::is_soa_particle) {
1390+
ptd.idata(0)[i] = ParticleType::NextID();
1391+
ptd.idata(1)[i] = ParallelDescriptor::MyProc();
1392+
}
1393+
else {
1394+
auto& p = make_particle<ParticleType>{}(ptd, i);
1395+
p.id() = ParticleType::NextID();
1396+
p.cpu() = ParallelDescriptor::MyProc();
13861397
}
13871398

1388-
// add the struct
1389-
ptile_tmp.push_back(p);
1399+
if constexpr(!ParticleType::is_soa_particle) {
1400+
for (int n = 0; n < NStructInt; n++) {
1401+
ptd.idata(n)[i] = pdata.int_struct_data[n];
1402+
}
1403+
}
13901404

13911405
// add the real...
1392-
for (int i = 0; i < NArrayReal; i++) {
1393-
ptile_tmp.push_back_real(i, static_cast<ParticleReal>(pdata.real_array_data[i]));
1406+
int n_min_real = ParticleType::is_soa_particle ? AMREX_SPACEDIM : 0; // jump over position
1407+
for (int n = n_min_real; n < NArrayReal; n++) {
1408+
ptile_tmp.push_back_real(n, static_cast<ParticleReal>(pdata.real_array_data[n]));
13941409
}
13951410

13961411
// ... and int array data
1397-
for (int i = 0; i < NArrayInt; i++) {
1398-
ptile_tmp.push_back_int(i, pdata.int_array_data[i]);
1412+
int n_min_int = ParticleType::is_soa_particle ? 2 : 0; // jump over cpuid
1413+
for (int n = n_min_int; n < NArrayInt; n++) {
1414+
ptile_tmp.push_back_int(n, pdata.int_array_data[n]);
13991415
}
14001416
}
14011417

Src/Particle/AMReX_ParticleTile.H

+11-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ struct ParticleTileData
6868
return this->m_rdata[dir][index];
6969
}
7070

71+
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
72+
auto& cpuid (const int index) &
73+
{
74+
if constexpr(!ParticleType::is_soa_particle) {
75+
return this->m_aos[index].id();
76+
} else {
77+
return this->m_idata[0][index];
78+
}
79+
}
80+
7181
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
7282
auto id (const int index) const &
7383
{
@@ -82,7 +92,7 @@ struct ParticleTileData
8292
auto& id (const int index) &
8393
{
8494
if constexpr(!ParticleType::is_soa_particle) {
85-
return this->m_aos[index].id();
95+
return this->m_aos[index].id();
8696
} else {
8797
return this->m_idata[0][index];
8898
}

0 commit comments

Comments
 (0)