From ff8776e8210e9ac5ecccdbf66d779c25be8b924c Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Fri, 16 Sep 2022 17:02:44 -0700 Subject: [PATCH] Update Particle Container to Pure SoA Transition particle containers to pure SoA layouts. --- .../BackTransformParticleFunctor.H | 16 +-- .../FlushFormats/FlushFormatCheckpoint.cpp | 5 +- .../FlushFormats/FlushFormatPlotfile.cpp | 9 +- Source/Diagnostics/ParticleIO.cpp | 4 +- .../FieldProbeParticleContainer.H | 14 +- .../FieldProbeParticleContainer.cpp | 28 +--- Source/Diagnostics/WarpXOpenPMD.H | 4 +- Source/Diagnostics/WarpXOpenPMD.cpp | 29 +---- .../ParticleBoundaryProcess.H | 6 +- Source/EmbeddedBoundary/ParticleScraper.H | 3 +- .../BinaryCollision/ParticleCreationFunc.H | 13 +- .../ElementaryProcess/QEDPairGeneration.H | 2 +- Source/Particles/LaserParticleContainer.H | 9 +- Source/Particles/MultiParticleContainer.cpp | 2 + .../NamedComponentParticleContainer.H | 42 ++++-- Source/Particles/ParticleBoundaryBuffer.cpp | 2 +- .../Particles/ParticleCreation/SmartCreate.H | 36 +++--- .../Particles/ParticleCreation/SmartUtils.H | 8 +- Source/Particles/PhysicalParticleContainer.H | 4 +- .../Particles/PhysicalParticleContainer.cpp | 10 +- Source/Particles/Pusher/GetAndSetPosition.H | 120 +++++++++++------- Source/Particles/WarpXParticleContainer.H | 10 +- Source/Particles/WarpXParticleContainer.cpp | 58 ++++----- Source/Python/WarpXWrappers.H | 8 -- Source/Python/WarpXWrappers.cpp | 46 +------ Source/ablastr/particles/ParticleMoments.H | 25 ++-- 26 files changed, 243 insertions(+), 270 deletions(-) diff --git a/Source/Diagnostics/ComputeDiagFunctors/BackTransformParticleFunctor.H b/Source/Diagnostics/ComputeDiagFunctors/BackTransformParticleFunctor.H index 4bb1b0656aa..c26ef848e19 100644 --- a/Source/Diagnostics/ComputeDiagFunctors/BackTransformParticleFunctor.H +++ b/Source/Diagnostics/ComputeDiagFunctors/BackTransformParticleFunctor.H @@ -143,19 +143,19 @@ struct LorentzTransformParticles const amrex::ParticleReal uzp = uz_old_p * weight_old + uz_new_p * weight_new; #if defined (WARPX_DIM_3D) - dst.m_aos[i_dst].pos(0) = xp; - dst.m_aos[i_dst].pos(1) = yp; - dst.m_aos[i_dst].pos(2) = zp; + dst.m_rdata[PIdx::x][i_dst] = xp; + dst.m_rdata[PIdx::y][i_dst] = yp; + dst.m_rdata[PIdx::z][i_dst] = zp; #elif defined (WARPX_DIM_RZ) - dst.m_aos[i_dst].pos(0) = std::sqrt(xp*xp + yp*yp); - dst.m_aos[i_dst].pos(1) = zp; + dst.m_rdata[PIdx::x][i_dst] = std::sqrt(xp*xp + yp*yp); + dst.m_rdata[PIdx::z][i_dst] = zp; dst.m_rdata[PIdx::theta][i_dst] = std::atan2(yp, xp); #elif defined (WARPX_DIM_XZ) - dst.m_aos[i_dst].pos(0) = xp; - dst.m_aos[i_dst].pos(1) = zp; + dst.m_rdata[PIdx::x][i_dst] = xp; + dst.m_rdata[PIdx::z][i_dst] = zp; amrex::ignore_unused(yp); #elif defined (WARPX_DIM_1D) - dst.m_aos[i_dst].pos(0) = zp; + dst.m_rdata[PIdx::z][i_dst] = zp; amrex::ignore_unused(xp, yp); #else amrex::ignore_unused(xp, yp, zp); diff --git a/Source/Diagnostics/FlushFormats/FlushFormatCheckpoint.cpp b/Source/Diagnostics/FlushFormats/FlushFormatCheckpoint.cpp index 1ea619bbf80..e35eb81fb36 100644 --- a/Source/Diagnostics/FlushFormats/FlushFormatCheckpoint.cpp +++ b/Source/Diagnostics/FlushFormats/FlushFormatCheckpoint.cpp @@ -200,8 +200,9 @@ FlushFormatCheckpoint::CheckpointParticles ( auto runtime_inames = pc->getParticleRuntimeiComps(); for (auto const& x : runtime_inames) { int_names[x.second+0] = x.first; } - pc->Checkpoint(dir, part_diag.getSpeciesName(), true, - real_names, int_names); + // TODO + //pc->Checkpoint(dir, part_diag.getSpeciesName(), true, + // real_names, int_names); } } diff --git a/Source/Diagnostics/FlushFormats/FlushFormatPlotfile.cpp b/Source/Diagnostics/FlushFormats/FlushFormatPlotfile.cpp index 3b977b55218..67b77a93d61 100644 --- a/Source/Diagnostics/FlushFormats/FlushFormatPlotfile.cpp +++ b/Source/Diagnostics/FlushFormats/FlushFormatPlotfile.cpp @@ -406,10 +406,11 @@ FlushFormatPlotfile::WriteParticles(const std::string& dir, } // real_names contains a list of all particle attributes. // real_flags & int_flags are 1 or 0, whether quantity is dumped or not. - tmp.WritePlotFile( - dir, part_diag.getSpeciesName(), - real_flags, int_flags, - real_names, int_names); + // TODO + //tmp.WritePlotFile( + // dir, part_diag.getSpeciesName(), + // real_flags, int_flags, + // real_names, int_names); } } diff --git a/Source/Diagnostics/ParticleIO.cpp b/Source/Diagnostics/ParticleIO.cpp index 13a406acd2f..7daff1cf1ca 100644 --- a/Source/Diagnostics/ParticleIO.cpp +++ b/Source/Diagnostics/ParticleIO.cpp @@ -206,10 +206,10 @@ MultiParticleContainer::Restart (const std::string& dir) } } - pc->Restart(dir, species_names.at(i)); + //pc->Restart(dir, species_names.at(i)); // TODO } for (unsigned i = species_names.size(); i < species_names.size()+lasers_names.size(); ++i) { - allcontainers.at(i)->Restart(dir, lasers_names.at(i-species_names.size())); + //allcontainers.at(i)->Restart(dir, lasers_names.at(i-species_names.size())); // TODO } } diff --git a/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.H b/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.H index dbb55fc0aff..3437cf5837a 100644 --- a/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.H +++ b/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.H @@ -24,7 +24,8 @@ struct FieldProbePIdx { enum { - Ex = 0, Ey, Ez, + x, y, z, + Ex, Ey, Ez, Bx, By, Bz, S, //!< the Poynting vector nattribs @@ -37,16 +38,21 @@ struct FieldProbePIdx * nattribs tells the particle container to allot 7 SOA values. */ class FieldProbeParticleContainer - : public amrex::ParticleContainer<0, 0, FieldProbePIdx::nattribs> + : public amrex::ParticleContainerPureSoA { public: + static constexpr int NStructReal = 0; + static constexpr int NStructInt = 0; + static constexpr int NReal = FieldProbePIdx::nattribs; + static constexpr int NInt = 0; + FieldProbeParticleContainer (amrex::AmrCore* amr_core); virtual ~FieldProbeParticleContainer() {} //! amrex iterator for our number of attributes - using iterator = amrex::ParIter<0, 0, FieldProbePIdx::nattribs, 0>; + using iterator = amrex::ParIterSoA; //! amrex iterator for our number of attributes (read-only) - using const_iterator = amrex::ParConstIter<0, 0, FieldProbePIdx::nattribs, 0>; + using const_iterator = amrex::ParConstIterSoA; //! similar to WarpXParticleContainer::AddNParticles but does not include u(x,y,z) void AddNParticles (int lev, amrex::Vector const & x, amrex::Vector const & y, amrex::Vector const & z); diff --git a/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.cpp b/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.cpp index 501bfc81515..688dda4d469 100644 --- a/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.cpp +++ b/Source/Diagnostics/ReducedDiags/FieldProbeParticleContainer.cpp @@ -60,7 +60,7 @@ using namespace amrex; FieldProbeParticleContainer::FieldProbeParticleContainer (AmrCore* amr_core) - : ParticleContainer<0, 0, FieldProbePIdx::nattribs>(amr_core->GetParGDB()) + : ParticleContainerPureSoA(amr_core->GetParGDB()) { SetParticleSize(); } @@ -90,37 +90,23 @@ FieldProbeParticleContainer::AddNParticles (int lev, * is then coppied to the permament tile which is stored on the particle * (particle_tile). */ + using PinnedTile = typename ContainerLike::ParticleTileType; - using PinnedTile = ParticleTile, - NArrayReal, NArrayInt, - amrex::PinnedArenaAllocator>; PinnedTile pinned_tile; pinned_tile.define(NumRuntimeRealComps(), NumRuntimeIntComps()); for (int i = 0; i < np; i++) { - ParticleType p; - p.id() = ParticleType::NextID(); - p.cpu() = ParallelDescriptor::MyProc(); -#if defined(WARPX_DIM_3D) - p.pos(0) = x[i]; - p.pos(1) = y[i]; - p.pos(2) = z[i]; -#elif defined(WARPX_DIM_XZ) || defined(WARPX_DIM_RZ) - amrex::ignore_unused(y); - p.pos(0) = x[i]; - p.pos(1) = z[i]; -#elif defined(WARPX_DIM_1D_Z) - amrex::ignore_unused(x, y); - p.pos(0) = z[i]; -#endif - // write position, cpu id, and particle id to particle - pinned_tile.push_back(p); + pinned_tile.push_back_int(0, ParticleType::NextID()); + pinned_tile.push_back_int(1, amrex::ParallelDescriptor::MyProc()); } // write Real attributes (SoA) to particle initialized zero DefineAndReturnParticleTile(0, 0, 0); + pinned_tile.push_back_real(FieldProbePIdx::x, x); + pinned_tile.push_back_real(FieldProbePIdx::y, y); + pinned_tile.push_back_real(FieldProbePIdx::z, z); pinned_tile.push_back_real(FieldProbePIdx::Ex, np, 0.0); pinned_tile.push_back_real(FieldProbePIdx::Ey, np, 0.0); pinned_tile.push_back_real(FieldProbePIdx::Ez, np, 0.0); diff --git a/Source/Diagnostics/WarpXOpenPMD.H b/Source/Diagnostics/WarpXOpenPMD.H index aaa0acba88b..579445b19e6 100644 --- a/Source/Diagnostics/WarpXOpenPMD.H +++ b/Source/Diagnostics/WarpXOpenPMD.H @@ -62,7 +62,7 @@ class WarpXParticleCounter { public: using ParticleContainer = typename WarpXParticleContainer::ContainerLike; - using ParticleIter = typename amrex::ParIter<0, 0, PIdx::nattribs, 0, amrex::PinnedArenaAllocator>; + using ParticleIter = typename amrex::ParIterSoA; WarpXParticleCounter (ParticleContainer* pc); unsigned long GetTotalNumParticles () {return m_Total;} @@ -98,7 +98,7 @@ class WarpXOpenPMDPlot { public: using ParticleContainer = typename WarpXParticleContainer::ContainerLike; - using ParticleIter = typename amrex::ParConstIter<0, 0, PIdx::nattribs, 0, amrex::PinnedArenaAllocator>; + using ParticleIter = typename amrex::ParConstIterSoA; /** Initialize openPMD I/O routines * diff --git a/Source/Diagnostics/WarpXOpenPMD.cpp b/Source/Diagnostics/WarpXOpenPMD.cpp index c30d58726c4..9ae5bc8df15 100644 --- a/Source/Diagnostics/WarpXOpenPMD.cpp +++ b/Source/Diagnostics/WarpXOpenPMD.cpp @@ -939,31 +939,7 @@ WarpXOpenPMDPlot::SaveRealProperty (ParticleIter& pti, { auto const numParticleOnTile = pti.numParticles(); uint64_t const numParticleOnTile64 = static_cast( numParticleOnTile ); - auto const& aos = pti.GetArrayOfStructs(); // size = numParticlesOnTile auto const& soa = pti.GetStructOfArrays(); - // first we concatinate the AoS into contiguous arrays - { - // note: WarpX does not yet use extra AoS Real attributes - for( auto idx=0; idx d( - new amrex::ParticleReal[numParticleOnTile], - [](amrex::ParticleReal const *p){ delete[] p; } - ); - - for( auto kk=0; kk AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - void operator() (const PData& ptd, int i, + void operator() (PData& ptd, int i, const amrex::RealVect& /*pos*/, const amrex::RealVect& /*normal*/, amrex::RandomEngine const& /*engine*/) const noexcept { - auto& p = ptd.m_aos[i]; - p.id() = -p.id(); + //ptd.id(i) = -ptd.id(i); // FIXME: in AMReX - why does that not work? + ptd.m_idata[0][i] = -ptd.id(i); } }; } diff --git a/Source/EmbeddedBoundary/ParticleScraper.H b/Source/EmbeddedBoundary/ParticleScraper.H index b723fd2ce5e..2d2616f2536 100644 --- a/Source/EmbeddedBoundary/ParticleScraper.H +++ b/Source/EmbeddedBoundary/ParticleScraper.H @@ -167,13 +167,12 @@ scrapeParticles (PC& pc, const amrex::Vector& distance_t auto& tile = pti.GetParticleTile(); auto ptd = tile.getParticleTileData(); const auto np = tile.numParticles(); - amrex::Particle<0,0> * const particles = tile.GetArrayOfStructs()().data(); auto phi = (*distance_to_eb[lev])[pti].array(); // signed distance function amrex::ParallelForRNG( np, [=] AMREX_GPU_DEVICE (const int ip, amrex::RandomEngine const& engine) noexcept { // skip particles that are already flagged for removal - if (particles[ip].id() < 0) return; + if (ptd.id(ip) < 0) return; amrex::ParticleReal xp, yp, zp; getPosition(ip, xp, yp, zp); diff --git a/Source/Particles/Collision/BinaryCollision/ParticleCreationFunc.H b/Source/Particles/Collision/BinaryCollision/ParticleCreationFunc.H index 085adcc8860..9585295c9b5 100644 --- a/Source/Particles/Collision/BinaryCollision/ParticleCreationFunc.H +++ b/Source/Particles/Collision/BinaryCollision/ParticleCreationFunc.H @@ -204,14 +204,21 @@ public: // If the colliding particle weight decreases to zero, remove particle by // setting its id to -1 - constexpr amrex::Long minus_one_long = -1; if (w1[p_pair_indices_1[i]] <= amrex::ParticleReal(0.)) { - particle_ptr_1[p_pair_indices_1[i]].atomicSetID(minus_one_long); + //particle_ptr_1[p_pair_indices_1[i]].atomicSetID(minus_one_long); // TODO + // or? + //soa_1.m_idata[PIdxInt::id] = -1; + // or? + particle_ptr_1->id() = -1; } if (w2[p_pair_indices_2[i]] <= amrex::ParticleReal(0.)) { - particle_ptr_2[p_pair_indices_2[i]].atomicSetID(minus_one_long); + //particle_ptr_2[p_pair_indices_2[i]].atomicSetID(minus_one_long); // TODO + // or? + //soa_2.m_idata[PIdxInt::id] = -1; + // or? + particle_ptr_2->id() = -1; } // Initialize the product particles' momentum, using a function depending on the diff --git a/Source/Particles/ElementaryProcess/QEDPairGeneration.H b/Source/Particles/ElementaryProcess/QEDPairGeneration.H index a38d0754a0e..5b482abd734 100644 --- a/Source/Particles/ElementaryProcess/QEDPairGeneration.H +++ b/Source/Particles/ElementaryProcess/QEDPairGeneration.H @@ -160,7 +160,7 @@ public: p_ux, p_uy, p_uz, engine); - src.m_aos[i_src].id() = -1; //destroy photon after pair generation + src.m_idata[0][i_src] = -1; // destroy photon after pair generation } private: diff --git a/Source/Particles/LaserParticleContainer.H b/Source/Particles/LaserParticleContainer.H index 5e1debf5ed7..c2d4adbda61 100644 --- a/Source/Particles/LaserParticleContainer.H +++ b/Source/Particles/LaserParticleContainer.H @@ -50,11 +50,10 @@ public: * \brief Method to initialize runtime attributes. Does nothing for LaserParticleContainer. */ virtual void DefaultInitializeRuntimeAttributes ( - amrex::ParticleTile, - NArrayReal, NArrayInt, amrex::PinnedArenaAllocator>& /*pinned_tile*/, - const int /*n_external_attr_real*/, - const int /*n_external_attr_int*/, - const amrex::RandomEngine& /*engine*/) override final {} + typename ContainerLike::ParticleTileType& /*pinned_tile*/, + const int /*n_external_attr_real*/, + const int /*n_external_attr_int*/, + const amrex::RandomEngine& /*engine*/) override final {} virtual void ReadHeader (std::istream& is) final; diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index e397d1aa831..692f77d0b44 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -1400,6 +1400,7 @@ MultiParticleContainer::doQEDSchwinger () const auto Transform = SchwingerTransformFunc{m_qed_schwinger_y_size, PIdx::w}; + const auto num_added = filterCreateTransformFromFAB<1>( dst_ele_tile, dst_pos_tile, box, fieldsEB, np_ele_dst, np_pos_dst,Filter, CreateEle, CreatePos, @@ -1551,6 +1552,7 @@ void MultiParticleContainer::doQedBreitWheeler (int lev, const auto np_dst_ele = dst_ele_tile.numParticles(); const auto np_dst_pos = dst_pos_tile.numParticles(); + const auto num_added = filterCopyTransformParticles<1>( dst_ele_tile, dst_pos_tile, src_tile, np_dst_ele, np_dst_pos, diff --git a/Source/Particles/NamedComponentParticleContainer.H b/Source/Particles/NamedComponentParticleContainer.H index 7b2ac6f63b6..d795a5e0171 100644 --- a/Source/Particles/NamedComponentParticleContainer.H +++ b/Source/Particles/NamedComponentParticleContainer.H @@ -16,12 +16,19 @@ #include #include -/** Particle Attributes stored in amrex::ParticleContainer's struct of array +/** Real Particle Attributes stored in amrex::ParticleContainer's struct of array */ struct PIdx { enum { - w = 0, ///< weight +#if !defined (WARPX_DIM_1D) + x, +#endif +#if defined (WARPX_DIM_3D) + y, +#endif + z, + w, ///< weight ux, uy, uz, #ifdef WARPX_DIM_RZ theta, ///< RZ needs all three position components @@ -30,6 +37,17 @@ struct PIdx }; }; +/** Integer Particle Attributes stored in amrex::ParticleContainer's struct of array + */ +struct PIdxInt +{ + enum { + id, + cpu, + nattribs ///< number of attributes + }; +}; + /** Particle Container class that allows to add/access particle components * with a name (string) instead of doing so with an integer index. * (The "components" are all the particle quantities - except those @@ -43,11 +61,11 @@ struct PIdx */ template class T_Allocator=amrex::DefaultAllocator> class NamedComponentParticleContainer : -public amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator> +public amrex::ParticleContainerPureSoA { public: /** Construct an empty NamedComponentParticleContainer **/ - NamedComponentParticleContainer () : amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>() {} + NamedComponentParticleContainer () : amrex::ParticleContainerPureSoA() {} /** Construct a NamedComponentParticleContainer from an AmrParGDB object * @@ -59,7 +77,7 @@ public: * AMR hierarchy. Usually, this is generated by an AmrCore or AmrLevel object. */ NamedComponentParticleContainer (amrex::AmrParGDB* amr_pgdb) - : amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>(amr_pgdb) { + : amrex::ParticleContainerPureSoA(amr_pgdb) { // build up the map of string names to particle component numbers particle_comps["w"] = PIdx::w; particle_comps["ux"] = PIdx::ux; @@ -83,12 +101,12 @@ public: * @param p_ricomps name-to-index map for run-time integer components */ NamedComponentParticleContainer( - amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator> && pc, + amrex::ParticleContainerPureSoA && pc, std::map p_comps, std::map p_icomps, std::map p_rcomps, std::map p_ricomps) - : amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>(std::move(pc)), + : amrex::ParticleContainerPureSoA(std::move(pc)), particle_comps(p_comps), particle_icomps(p_icomps), particle_runtime_comps(p_rcomps), @@ -116,7 +134,7 @@ public: NamedComponentParticleContainer make_alike () const { auto tmp = NamedComponentParticleContainer( - amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>::template make_alike(), + amrex::ParticleContainerPureSoA::template make_alike(), particle_comps, particle_icomps, particle_runtime_comps, @@ -125,10 +143,10 @@ public: return tmp; } - using amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>::NumRealComps; - using amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>::NumIntComps; - using amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>::AddRealComp; - using amrex::ParticleContainer<0,0,PIdx::nattribs,0,T_Allocator>::AddIntComp; + using amrex::ParticleContainerPureSoA::NumRealComps; + using amrex::ParticleContainerPureSoA::NumIntComps; + using amrex::ParticleContainerPureSoA::AddRealComp; + using amrex::ParticleContainerPureSoA::AddIntComp; /** Allocate a new run-time real component * diff --git a/Source/Particles/ParticleBoundaryBuffer.cpp b/Source/Particles/ParticleBoundaryBuffer.cpp index 53a16996c2a..515a84cb9fb 100644 --- a/Source/Particles/ParticleBoundaryBuffer.cpp +++ b/Source/Particles/ParticleBoundaryBuffer.cpp @@ -207,7 +207,7 @@ void ParticleBoundaryBuffer::gatherParticles (MultiParticleContainer& mypc, { WARPX_PROFILE("ParticleBoundaryBuffer::gatherParticles"); - using PIter = amrex::ParConstIter<0,0,PIdx::nattribs>; + using PIter = amrex::ParConstIterSoA; const auto& warpx_instance = WarpX::GetInstance(); const amrex::Geometry& geom = warpx_instance.Geom(0); auto plo = geom.ProbLoArray(); diff --git a/Source/Particles/ParticleCreation/SmartCreate.H b/Source/Particles/ParticleCreation/SmartCreate.H index 875e69cab04..13188c7cf7d 100644 --- a/Source/Particles/ParticleCreation/SmartCreate.H +++ b/Source/Particles/ParticleCreation/SmartCreate.H @@ -47,32 +47,32 @@ struct SmartCreate const int id = 0) const noexcept { #if defined(WARPX_DIM_3D) - prt.m_aos[i_prt].pos(0) = x; - prt.m_aos[i_prt].pos(1) = y; - prt.m_aos[i_prt].pos(2) = z; + prt.m_rdata[0][i_prt] = x; + prt.m_rdata[1][i_prt] = y; + prt.m_rdata[2][i_prt] = z; #elif defined(WARPX_DIM_XZ) || defined(WARPX_DIM_RZ) - prt.m_aos[i_prt].pos(0) = x; - prt.m_aos[i_prt].pos(1) = z; + prt.m_rdata[0][i_prt] = x; + prt.m_rdata[1][i_prt] = z; amrex::ignore_unused(y); #else - prt.m_aos[i_prt].pos(0) = z; + prt.m_rdata[0][i_prt] = z; amrex::ignore_unused(x,y); #endif - prt.m_aos[i_prt].cpu() = cpu; - prt.m_aos[i_prt].id() = id; + prt.m_idata[0][i_prt] = id; + prt.m_idata[1][i_prt] = cpu; // TODO double check me - // initialize the real components - for (int j = 0; j < PartData::NAR; ++j) - prt.m_rdata[j][i_prt] = initializeRealValue(m_policy_real[j], engine); - for (int j = 0; j < prt.m_num_runtime_real; ++j) - prt.m_runtime_rdata[j][i_prt] = initializeRealValue(m_policy_real[j+PartData::NAR], engine); + // initialize the real components after position + for (int j = AMREX_SPACEDIM; j < PartData::NAR; ++j) + prt.m_rdata[j][i_prt] = initializeRealValue(m_policy_real[j], engine); + for (int j = 0; j < prt.m_num_runtime_real; ++j) + prt.m_runtime_rdata[j][i_prt] = initializeRealValue(m_policy_real[j+PartData::NAR], engine); - // initialize the int components - for (int j = 0; j < PartData::NAI; ++j) - prt.m_idata[j][i_prt] = initializeIntValue(m_policy_int[j]); - for (int j = 0; j < prt.m_num_runtime_int; ++j) - prt.m_runtime_idata[j][i_prt] = initializeIntValue(m_policy_int[j+PartData::NAI]); + // initialize the int components after cpu & id + for (int j = 2; j < PartData::NAI; ++j) + prt.m_idata[j][i_prt] = initializeIntValue(m_policy_int[j]); + for (int j = 0; j < prt.m_num_runtime_int; ++j) + prt.m_runtime_idata[j][i_prt] = initializeIntValue(m_policy_int[j+PartData::NAI]); } }; diff --git a/Source/Particles/ParticleCreation/SmartUtils.H b/Source/Particles/ParticleCreation/SmartUtils.H index ee1dc321cef..3c5e39a3447 100644 --- a/Source/Particles/ParticleCreation/SmartUtils.H +++ b/Source/Particles/ParticleCreation/SmartUtils.H @@ -60,12 +60,12 @@ void setNewParticleIDs (PTile& ptile, int old_size, int num_added) } const int cpuid = amrex::ParallelDescriptor::MyProc(); - auto pp = ptile.GetArrayOfStructs()().data() + old_size; + auto ptd = ptile.getParticleTileData(); amrex::ParallelFor(num_added, [=] AMREX_GPU_DEVICE (int ip) noexcept { - auto& p = pp[ip]; - p.id() = pid+ip; - p.cpu() = cpuid; + auto const new_id = ip + old_size; + ptd.m_idata[0][new_id] = pid+ip; + ptd.m_idata[1][new_id] = cpuid; // TODO double check me }); } diff --git a/Source/Particles/PhysicalParticleContainer.H b/Source/Particles/PhysicalParticleContainer.H index 4a9beeec24f..90bf209a362 100644 --- a/Source/Particles/PhysicalParticleContainer.H +++ b/Source/Particles/PhysicalParticleContainer.H @@ -234,9 +234,7 @@ public: * @param[in] engine the random engine, used in initialization of QED optical depths */ virtual void DefaultInitializeRuntimeAttributes ( - amrex::ParticleTile, - NArrayReal, NArrayInt, - amrex::PinnedArenaAllocator>& pinned_tile, + typename ContainerLike::ParticleTileType& pinned_tile, const int n_external_attr_real, const int n_external_attr_int, const amrex::RandomEngine& engine) override final; diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 0c9b7ce6994..6650eaae085 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -673,12 +673,10 @@ PhysicalParticleContainer::AddPlasmaFromFile(ParticleReal q_tot, void PhysicalParticleContainer::DefaultInitializeRuntimeAttributes ( - amrex::ParticleTile, - NArrayReal, NArrayInt, - amrex::PinnedArenaAllocator>& pinned_tile, - const int n_external_attr_real, - const int n_external_attr_int, - const amrex::RandomEngine& engine) + typename ContainerLike::ParticleTileType& pinned_tile, + const int n_external_attr_real, + const int n_external_attr_int, + const amrex::RandomEngine& engine) { using namespace amrex::literals; diff --git a/Source/Particles/Pusher/GetAndSetPosition.H b/Source/Particles/Pusher/GetAndSetPosition.H index 4067895790d..0357a9df538 100644 --- a/Source/Particles/Pusher/GetAndSetPosition.H +++ b/Source/Particles/Pusher/GetAndSetPosition.H @@ -51,10 +51,19 @@ void get_particle_position (const WarpXParticleContainer::SuperParticleType& p, */ struct GetParticlePosition { - using PType = WarpXParticleContainer::ParticleType; using RType = amrex::ParticleReal; - const PType* AMREX_RESTRICT m_structs = nullptr; +#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_XZ) + RType* AMREX_RESTRICT m_x = nullptr; + RType* AMREX_RESTRICT m_z = nullptr; +#elif defined(WARPX_DIM_3D) + const RType* AMREX_RESTRICT m_x = nullptr; + const RType* AMREX_RESTRICT m_y = nullptr; + const RType* AMREX_RESTRICT m_z = nullptr; +#elif defined(WARPX_DIM_1D_Z) + RType* AMREX_RESTRICT m_z = nullptr; +#endif + #if defined(WARPX_DIM_RZ) const RType* m_theta = nullptr; #elif defined(WARPX_DIM_XZ) || defined(WARPX_DIM_RZ) @@ -76,10 +85,19 @@ struct GetParticlePosition template GetParticlePosition (const ptiType& a_pti, int a_offset = 0) noexcept { - const auto& aos = a_pti.GetArrayOfStructs(); - m_structs = aos().dataPtr() + a_offset; + /* const */ auto& soa = a_pti.GetStructOfArrays(); // TODO: should this support const? + +#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_XZ) + m_x = soa.GetRealData(0).dataPtr() + a_offset; + m_z = soa.GetRealData(1).dataPtr() + a_offset; +#elif defined(WARPX_DIM_3D) + m_x = soa.GetRealData(0).dataPtr() + a_offset; + m_y = soa.GetRealData(1).dataPtr() + a_offset; + m_z = soa.GetRealData(2).dataPtr() + a_offset; +#elif defined(WARPX_DIM_1D_Z) + m_z = soa.GetRealData(0).dataPtr() + a_offset; +#endif #if defined(WARPX_DIM_RZ) - const auto& soa = a_pti.GetStructOfArrays(); m_theta = soa.GetRealData(PIdx::theta).dataPtr() + a_offset; #endif } @@ -90,24 +108,23 @@ struct GetParticlePosition AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator() (const int i, RType& x, RType& y, RType& z) const noexcept { - const PType& p = m_structs[i]; #ifdef WARPX_DIM_RZ - RType r = p.pos(0); + RType r = m_x[i]; x = r*std::cos(m_theta[i]); y = r*std::sin(m_theta[i]); - z = p.pos(1); + z = m_z[i]; #elif WARPX_DIM_3D - x = p.pos(0); - y = p.pos(1); - z = p.pos(2); + x = m_x[i]; + y = m_y[i]; + z = m_z[i]; #elif WARPX_DIM_XZ - x = p.pos(0); + x = m_x[i]; y = m_y_default; - z = p.pos(1); + z = m_z[i]; #else x = m_x_default; y = m_y_default; - z = p.pos(0); + z = m_z[i]; #endif } @@ -119,23 +136,22 @@ struct GetParticlePosition AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void AsStored (const int i, RType& x, RType& y, RType& z) const noexcept { - const PType& p = m_structs[i]; #ifdef WARPX_DIM_RZ - x = p.pos(0); + x = m_x[i]; y = m_theta[i]; - z = p.pos(1); + z = m_z[i]; #elif WARPX_DIM_3D - x = p.pos(0); - y = p.pos(1); - z = p.pos(2); + x = m_x[i]; + y = m_y[i]; + z = m_z[i]; #elif WARPX_DIM_XZ - x = p.pos(0); + x = m_x[i]; y = m_y_default; - z = p.pos(1); + z = m_z[i]; #else x = m_x_default; y = m_y_default; - z = p.pos(0); + z = m_z[i]; #endif } }; @@ -148,10 +164,18 @@ struct GetParticlePosition */ struct SetParticlePosition { - using PType = WarpXParticleContainer::ParticleType; using RType = amrex::ParticleReal; - PType* AMREX_RESTRICT m_structs; +#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_XZ) + RType* AMREX_RESTRICT m_x; + RType* AMREX_RESTRICT m_z; +#elif defined(WARPX_DIM_3D) + RType* AMREX_RESTRICT m_x; + RType* AMREX_RESTRICT m_y; + RType* AMREX_RESTRICT m_z; +#elif defined(WARPX_DIM_1D_Z) + RType* AMREX_RESTRICT m_z; +#endif #if defined(WARPX_DIM_RZ) RType* AMREX_RESTRICT m_theta; #endif @@ -159,10 +183,18 @@ struct SetParticlePosition template SetParticlePosition (const ptiType& a_pti, int a_offset = 0) noexcept { - auto& aos = a_pti.GetArrayOfStructs(); - m_structs = aos().dataPtr() + a_offset; -#if defined(WARPX_DIM_RZ) auto& soa = a_pti.GetStructOfArrays(); +#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_XZ) + m_x = soa.GetRealData(0).dataPtr() + a_offset; + m_z = soa.GetRealData(1).dataPtr() + a_offset; +#elif defined(WARPX_DIM_3D) + m_x = soa.GetRealData(0).dataPtr() + a_offset; + m_y = soa.GetRealData(1).dataPtr() + a_offset; + m_z = soa.GetRealData(2).dataPtr() + a_offset; +#elif defined(WARPX_DIM_1D_Z) + m_z = soa.GetRealData(0).dataPtr() + a_offset; +#endif +#if defined(WARPX_DIM_RZ) m_theta = soa.GetRealData(PIdx::theta).dataPtr() + a_offset; #endif } @@ -180,17 +212,17 @@ struct SetParticlePosition #endif #ifdef WARPX_DIM_RZ m_theta[i] = std::atan2(y, x); - m_structs[i].pos(0) = std::sqrt(x*x + y*y); - m_structs[i].pos(1) = z; + m_x[i] = std::sqrt(x*x + y*y); + m_z[i] = z; #elif WARPX_DIM_3D - m_structs[i].pos(0) = x; - m_structs[i].pos(1) = y; - m_structs[i].pos(2) = z; + m_x[i] = x; + m_y[i] = y; + m_z[i] = z; #elif WARPX_DIM_XZ - m_structs[i].pos(0) = x; - m_structs[i].pos(1) = z; + m_x[i] = x; + m_z[i] = z; #else - m_structs[i].pos(0) = z; + m_z[i] = z; #endif } @@ -208,18 +240,18 @@ struct SetParticlePosition amrex::ignore_unused(x,y); #endif #ifdef WARPX_DIM_RZ - m_structs[i].pos(0) = x; + m_x[i] = x; m_theta[i] = y; - m_structs[i].pos(1) = z; + m_z[i] = z; #elif WARPX_DIM_3D - m_structs[i].pos(0) = x; - m_structs[i].pos(1) = y; - m_structs[i].pos(2) = z; + m_x[i] = x; + m_y[i] = y; + m_z[i] = z; #elif WARPX_DIM_XZ - m_structs[i].pos(0) = x; - m_structs[i].pos(1) = z; + m_x[i] = x; + m_z[i] = z; #else - m_structs[i].pos(0) = z; + m_z[i] = z; #endif } }; diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index ffeead6f1d6..c8a9eede5c3 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -48,10 +48,10 @@ using namespace amrex::literals; class WarpXParIter - : public amrex::ParIter<0,0,PIdx::nattribs> + : public amrex::ParIterSoA { public: - using amrex::ParIter<0,0,PIdx::nattribs>::ParIter; + using amrex::ParIterSoA::ParIterSoA; WarpXParIter (ContainerType& pc, int level); @@ -83,7 +83,7 @@ public: * particle container classes (that store a collection of particles) derive. Derived * classes can be used for plasma particles, photon particles, or non-physical * particles (e.g., for the laser antenna). - * It derives from amrex::ParticleContainer<0,0,PIdx::nattribs>, where the + * It derives from amrex::ParticleContainerPureSoA, where the * template arguments stand for the number of int and amrex::Real SoA and AoS * data in amrex::Particle. * - AoS amrex::Real: x, y, z (default), 0 additional (first template @@ -145,9 +145,7 @@ public: * class. */ virtual void DefaultInitializeRuntimeAttributes ( - amrex::ParticleTile, - NArrayReal, NArrayInt, - amrex::PinnedArenaAllocator>& pinned_tile, + typename ContainerLike::ParticleTileType& pinned_tile, const int n_external_attr_real, const int n_external_attr_int, const amrex::RandomEngine& engine) = 0; diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp index b6e33180a8d..0461aae03d2 100644 --- a/Source/Particles/WarpXParticleContainer.cpp +++ b/Source/Particles/WarpXParticleContainer.cpp @@ -72,13 +72,13 @@ using namespace amrex; WarpXParIter::WarpXParIter (ContainerType& pc, int level) - : amrex::ParIter<0,0,PIdx::nattribs>(pc, level, + : amrex::ParIterSoA(pc, level, MFItInfo().SetDynamic(WarpX::do_dynamic_scheduling)) { } WarpXParIter::WarpXParIter (ContainerType& pc, int level, MFItInfo& info) - : amrex::ParIter<0,0,PIdx::nattribs>(pc, level, + : amrex::ParIterSoA(pc, level, info.SetDynamic(WarpX::do_dynamic_scheduling)) { } @@ -181,9 +181,7 @@ WarpXParticleContainer::AddNParticles (int /*lev*/, // Redistribute() will move them to proper places. auto& particle_tile = DefineAndReturnParticleTile(0, 0, 0); - using PinnedTile = amrex::ParticleTile, - NArrayReal, NArrayInt, - amrex::PinnedArenaAllocator>; + using PinnedTile = typename ContainerLike::ParticleTileType; PinnedTile pinned_tile; pinned_tile.define(NumRuntimeRealComps(), NumRuntimeIntComps()); @@ -193,45 +191,46 @@ WarpXParticleContainer::AddNParticles (int /*lev*/, amrex::Vector weight(np); #ifdef WARPX_DIM_RZ + amrex::Vector r(np); amrex::Vector theta(np); #endif for (int i = ibegin; i < iend; ++i) { - ParticleType p; - if (id==-1) - { - p.id() = ParticleType::NextID(); + if (id==-1) { + pinned_tile.push_back_int(PIdxInt::id, ParticleType::NextID()); } else { - p.id() = id; + pinned_tile.push_back_int(PIdxInt::id, id); } - p.cpu() = amrex::ParallelDescriptor::MyProc(); + pinned_tile.push_back_int(PIdxInt::cpu, amrex::ParallelDescriptor::MyProc()); + +#ifdef WARPX_DIM_RZ + r[i-ibegin] = std::sqrt(x[i]*x[i] + y[i]*y[i]); + theta[i-ibegin] = std::atan2(y[i], x[i]); +#endif + // grab weight from the attr array + weight[i-ibegin] = attr_real[i*nattr_real]; + } + + if (np > 0) + { #if defined(WARPX_DIM_3D) - p.pos(0) = x[i]; - p.pos(1) = y[i]; - p.pos(2) = z[i]; + pinned_tile.push_back_real(PIdx::x, x + ibegin, x + iend); + pinned_tile.push_back_real(PIdx::y, y + ibegin, y + iend); + pinned_tile.push_back_real(PIdx::z, z + ibegin, z + iend); #elif defined(WARPX_DIM_XZ) || defined(WARPX_DIM_RZ) amrex::ignore_unused(y); #ifdef WARPX_DIM_RZ - theta[i-ibegin] = std::atan2(y[i], x[i]); - p.pos(0) = std::sqrt(x[i]*x[i] + y[i]*y[i]); + pinned_tile.push_back_real(PIdx::x, r.data(), r.data() + np); #else - p.pos(0) = x[i]; + pinned_tile.push_back_real(PIdx::x, x + ibegin, x + iend); #endif - p.pos(1) = z[i]; + pinned_tile.push_back_real(PIdx::z, z + ibegin, z + iend); #else //AMREX_SPACEDIM == 1 amrex::ignore_unused(x,y); - p.pos(0) = z[i]; + pinned_tile.push_back_real(PIdx::z, z + ibegin, z + iend); #endif - pinned_tile.push_back(p); - - // grab weight from the attr array - weight[i-ibegin] = attr_real[i*nattr_real]; - } - - if (np > 0) - { pinned_tile.push_back_real(PIdx::w , weight.data(), weight.data() + np); pinned_tile.push_back_real(PIdx::ux, ux + ibegin, ux + iend); pinned_tile.push_back_real(PIdx::uy, uy + ibegin, uy + iend); @@ -1342,7 +1341,7 @@ void WarpXParticleContainer::defineAllParticleTiles () noexcept // This function is called in Redistribute, just after locate void -WarpXParticleContainer::particlePostLocate(ParticleType& p, +WarpXParticleContainer::particlePostLocate(ParticleType& p, // TODO const ParticleLocData& pld, const int lev) { @@ -1354,7 +1353,8 @@ WarpXParticleContainer::particlePostLocate(ParticleType& p, and p.id() != NoSplitParticleID and p.id() >= 0) { - p.id() = DoSplitParticleID; + // warning: overflow in conversion from 'long int' to 'int' changes value from '549755813884' to '-4' [-Woverflow] + p.id() = DoSplitParticleID; // TODO } if (pld.m_lev == lev-1){ diff --git a/Source/Python/WarpXWrappers.H b/Source/Python/WarpXWrappers.H index a62c4c3b810..3e1bd7b2bdb 100644 --- a/Source/Python/WarpXWrappers.H +++ b/Source/Python/WarpXWrappers.H @@ -86,10 +86,6 @@ extern "C" { void warpx_convert_cpu_to_int (int* cpus, const WarpXParticleContainer::ParticleType* pstructs, int size); - amrex::ParticleReal** warpx_getParticleStructs( - const char* char_species_name, int lev, int* num_tiles, - int** particles_per_tile); - amrex::ParticleReal** warpx_getParticleArrays( const char* char_species_name, const char* char_comp_name, int lev, int* num_tiles, int** particles_per_tile); @@ -112,10 +108,6 @@ extern "C" { const char* species_name, int boundary, int lev, int* num_tiles, int** particles_per_tile, const char* comp_name); - amrex::ParticleReal** warpx_getParticleBoundaryBufferStructs( - const char* species_name, int boundary, int lev, - int* num_tiles, int** particles_per_tile); - void warpx_clearParticleBoundaryBuffer (); /** diff --git a/Source/Python/WarpXWrappers.cpp b/Source/Python/WarpXWrappers.cpp index 2dd19d5cc39..83224d08cb1 100644 --- a/Source/Python/WarpXWrappers.cpp +++ b/Source/Python/WarpXWrappers.cpp @@ -449,27 +449,6 @@ namespace return getFieldNodalFlagData(pml->GetG_fp()); } - amrex::ParticleReal** warpx_getParticleStructs( - const char* char_species_name, int lev, - int* num_tiles, int** particles_per_tile) { - const auto & mypc = WarpX::GetInstance().GetPartContainer(); - const std::string species_name(char_species_name); - auto & myspc = mypc.GetParticleContainerFromName(species_name); - - *num_tiles = myspc.numLocalTilesAtLevel(lev); - *particles_per_tile = static_cast(malloc(*num_tiles*sizeof(int))); - memset(*particles_per_tile, 0, *num_tiles*sizeof(int)); - - auto data = static_cast(malloc(*num_tiles*sizeof(typename WarpXParticleContainer::ParticleType*))); - int i = 0; - for (WarpXParIter pti(myspc, lev); pti.isValid(); ++pti, ++i) { - auto& aos = pti.GetArrayOfStructs(); - data[i] = (amrex::ParticleReal*) aos.data(); - (*particles_per_tile)[i] = pti.numParticles(); - } - return data; - } - amrex::ParticleReal** warpx_getParticleArrays ( const char* char_species_name, const char* char_comp_name, int lev, int* num_tiles, int** particles_per_tile ) { @@ -587,7 +566,7 @@ namespace auto data = static_cast(malloc(*num_tiles*sizeof(int*))); int i = 0; - for (amrex::ParIter<0,0,PIdx::nattribs, 0, amrex::PinnedArenaAllocator> pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) { + for (amrex::ParIterSoA pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) { auto& soa = pti.GetStructOfArrays(); data[i] = (int*) soa.GetIntData(comp).dataPtr(); (*particles_per_tile)[i] = pti.numParticles(); @@ -611,7 +590,7 @@ namespace auto data = static_cast(malloc(*num_tiles*sizeof(amrex::ParticleReal*))); int i = 0; - for (amrex::ParIter<0,0,PIdx::nattribs, 0, amrex::PinnedArenaAllocator> pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) { + for (amrex::ParIterSoA pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) { auto& soa = pti.GetStructOfArrays(); data[i] = (amrex::ParticleReal*) soa.GetRealData(comp).dataPtr(); (*particles_per_tile)[i] = pti.numParticles(); @@ -620,27 +599,6 @@ namespace return data; } - amrex::ParticleReal** warpx_getParticleBoundaryBufferStructs(const char* species_name, int boundary, int lev, - int* num_tiles, int** particles_per_tile) - { - const std::string name(species_name); - auto& particle_buffers = WarpX::GetInstance().GetParticleBoundaryBuffer(); - auto& particle_buffer = particle_buffers.getParticleBuffer(species_name, boundary); - - *num_tiles = particle_buffer.numLocalTilesAtLevel(lev); - *particles_per_tile = static_cast(malloc(*num_tiles*sizeof(int))); - memset(*particles_per_tile, 0, *num_tiles*sizeof(int)); - - auto data = static_cast(malloc(*num_tiles*sizeof(typename WarpXParticleContainer::ParticleType*))); - int i = 0; - for (amrex::ParIter<0,0,PIdx::nattribs, 0, amrex::PinnedArenaAllocator> pti(particle_buffer, lev); pti.isValid(); ++pti, ++i) { - auto& aos = pti.GetArrayOfStructs(); - data[i] = (amrex::ParticleReal*) aos.data(); - (*particles_per_tile)[i] = pti.numParticles(); - } - return data; - } - void warpx_clearParticleBoundaryBuffer () { auto& particle_buffers = WarpX::GetInstance().GetParticleBoundaryBuffer(); particle_buffers.clearParticles(); diff --git a/Source/ablastr/particles/ParticleMoments.H b/Source/ablastr/particles/ParticleMoments.H index e45fb574cce..b648ccb28aa 100644 --- a/Source/ablastr/particles/ParticleMoments.H +++ b/Source/ablastr/particles/ParticleMoments.H @@ -35,7 +35,7 @@ namespace particles { amrex::ParticleReal, amrex::ParticleReal> MinAndMaxPositions (T_PC const & pc) { - using PType = typename T_PC::SuperParticleType; + using ConstParticleTileDataType = typename T_PC::ParticleTileType::ConstParticleTileDataType; // Get min and max for the local rank amrex::ReduceOps< @@ -46,11 +46,11 @@ namespace particles { amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal> >( pc, - [=] AMREX_GPU_DEVICE(PType const & p) noexcept + [=] AMREX_GPU_DEVICE(const ConstParticleTileDataType& ptd, const int i) noexcept { - amrex::ParticleReal const x = p.pos(0); - amrex::ParticleReal const y = p.pos(1); - amrex::ParticleReal const z = p.pos(2); + const amrex::ParticleReal x = ptd.rdata(0)[i]; + const amrex::ParticleReal y = ptd.rdata(1)[i]; + const amrex::ParticleReal z = ptd.rdata(2)[i]; return amrex::makeTuple(x, y, z, x, y, z); }, @@ -90,7 +90,8 @@ namespace particles { amrex::ParticleReal, amrex::ParticleReal> MeanAndStdPositions (T_PC const & pc) { - using PType = typename T_PC::SuperParticleType; + + using ConstParticleTileDataType = typename T_PC::ParticleTileType::ConstParticleTileDataType; amrex::ReduceOps< amrex::ReduceOpSum, amrex::ReduceOpSum, amrex::ReduceOpSum, @@ -103,12 +104,14 @@ namespace particles { amrex::ParticleReal> >( pc, - [=] AMREX_GPU_DEVICE(const PType& p) noexcept + [=] AMREX_GPU_DEVICE(const ConstParticleTileDataType& ptd, const int i) noexcept { - amrex::ParticleReal const x = p.pos(0); - amrex::ParticleReal const y = p.pos(1); - amrex::ParticleReal const z = p.pos(2); - amrex::ParticleReal const w = p.rdata(T_RealSoAWeight); + + const amrex::ParticleReal x = ptd.rdata(0)[i]; + const amrex::ParticleReal y = ptd.rdata(1)[i]; + const amrex::ParticleReal z = ptd.rdata(2)[i]; + + const amrex::ParticleReal w = ptd.rdata(T_RealSoAWeight)[i]; return amrex::makeTuple(x, x*x, y, y*y, z, z*z, w); },