IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
ParticleBase.h
Go to the documentation of this file.
1//
2// Class ParticleBase
3// Base class for all user-defined particle classes.
4//
5// ParticleBase is a container and manager for a set of particles.
6// The user must define a class derived from ParticleBase which describes
7// what specific data attributes the particle has (e.g., mass or charge).
8// Each attribute is an instance of a ParticleAttribute<T> class; ParticleBase
9// keeps a list of pointers to these attributes, and performs particle creation
10// and destruction.
11//
12// ParticleBase is templated on the ParticleLayout mechanism for the particles.
13// This template parameter should be a class derived from ParticleLayout.
14// ParticleLayout-derived classes maintain the info on which particles are
15// located on which processor, and performs the specific communication
16// required between processors for the particles. The ParticleLayout is
17// templated on the type and dimension of the atom position attribute, and
18// ParticleBase uses the same types for these items as the given
19// ParticleLayout.
20//
21// ParticleBase and all derived classes have the following common
22// characteristics:
23// - The spatial positions of the N particles are stored in the
24// particle_position_type variable R
25// - The global index of the N particles are stored in the
26// particle_index_type variable ID
27// - A pointer to an allocated layout class. When you construct a
28// ParticleBase, you must provide a layout instance, and ParticleBase
29// will delete this instance when it (the ParticleBase) is deleted.
30//
31// To use this class, the user defines a derived class with the same
32// structure as in this example:
33//
34// class UserParticles :
35// public ParticleBase< ParticleSpatialLayout<double,3> > {
36// public:
37// // attributes for this class
38// ParticleAttribute<double> rad; // radius
39// particle_position_type vel; // velocity, same storage type as R
40//
41// // constructor: add attributes to base class
42// UserParticles(ParticleSpatialLayout<double,2>* L) : ParticleBase(L) {
43// addAttribute(rad);
44// addAttribute(vel);
45// }
46// };
47//
48// This example defines a user class with 3D position and two extra
49// attributes: a radius rad (double), and a velocity vel (a 3D Vector).
50//
51#ifndef IPPL_PARTICLE_BASE_H
52#define IPPL_PARTICLE_BASE_H
53
54#include <tuple>
55#include <type_traits>
56#include <vector>
57
58#include "Types/IpplTypes.h"
59
60#include "Utility/TypeUtils.h"
61
63
64namespace ippl {
65
74 public:
75 virtual ~ParticleBaseBase() = default;
76 };
77
86 template <class PLayout, typename... IDProperties>
88 constexpr static bool EnableIDs = sizeof...(IDProperties) > 0;
89
90 public:
91 using vector_type = typename PLayout::vector_type;
92 using index_type = typename PLayout::index_type;
93 using particle_position_type = typename PLayout::particle_position_type;
95
96 using Layout_t = PLayout;
97
98 template <typename... Properties>
99 using attribute_type = typename detail::ParticleAttribBase<Properties...>;
100
101 template <typename MemorySpace>
102 using container_type = std::vector<attribute_type<MemorySpace>*>;
103
106
107 using bc_container_type = typename PLayout::bc_container_type;
108
110
112
113 public:
116
119
125
134
135 /* cannot use '= default' since we get a
136 * compiler warning otherwise:
137 * warning: calling a __host__ function("std::vector< ::ippl::detail::ParticleAttribBase *,
138 * ::std::allocator<
139 * ::ippl::detail::ParticleAttribBase *> > ::~vector") from a __host__ __device__
140 * function("ippl::ParticleBase<
141 * ::ippl::ParticleLayout<double, (unsigned int)3u> > ::~ParticleBase") is not allowed
142 */
143 ~ParticleBase() {} // = default; //{ }
144
150 void initialize(Layout_t& layout);
151
155 size_type getLocalNum() const { return localNum_m; }
156
157 void setLocalNum(size_type size) { localNum_m = size; }
158
162 size_type getTotalNum() const { return totalNum_m; }
163
168
172 const Layout_t& getLayout() const { return *layout_m; }
173
178 void setParticleBC(const bc_container_type& bcs) { layout_m->setParticleBC(bcs); }
179
184 void setParticleBC(BC bc) { layout_m->setParticleBC(bc); }
185
190 template <typename MemorySpace>
192
198 template <typename MemorySpace = Kokkos::DefaultExecutionSpace::memory_space>
200 return attributes_m.template get<MemorySpace>()[i];
201 }
202
210 template <typename MemorySpace = void, typename Functor>
211 void forAllAttributes(Functor&& f) const {
212 if constexpr (std::is_void_v<MemorySpace>) {
213 attributes_m.forAll(f);
214 } else {
215 for (auto& attribute : attributes_m.template get<MemorySpace>()) {
216 f(attribute);
217 }
218 }
219 }
220
221 // Non-const variant of same function
222 template <typename MemorySpace = void, typename Functor>
223 void forAllAttributes(Functor&& f) {
224 if constexpr (std::is_void_v<MemorySpace>) {
225 attributes_m.forAll([&]<typename Attributes>(Attributes& atts) {
226 for (auto& attribute : atts) {
227 f(attribute);
228 }
229 });
230 } else {
231 for (auto& attribute : attributes_m.template get<MemorySpace>()) {
232 f(attribute);
233 }
234 }
235 }
236
240 unsigned getAttributeNum() const {
241 unsigned total = 0;
242 detail::runForAllSpaces([&]<typename MemorySpace>() {
243 total += attributes_m.template get<MemorySpace>().size();
244 });
245 return total;
246 }
247
253 void create(size_type nLocal);
254
261
268
276 template <typename... Properties>
277 void destroy(const Kokkos::View<bool*, Properties...>& invalid, const size_type destroyNum);
278
279 // This is a collective call.
280 void update() { layout_m->update(*this); }
281
282 /*
283 * The following functions should not be called in an application.
284 */
285
286 /* This function does not alter the totalNum_m member function. It should only be called
287 * during the update function where we know the number of particles remains the same.
288 */
289 template <typename... Properties>
290 void internalDestroy(const Kokkos::View<bool*, Properties...>& invalid,
291 const size_type destroyNum);
292
303 template <typename HashType>
304 void sendToRank(int rank, int tag, std::vector<MPI_Request>& requests,
305 const HashType& hash);
306
314 void recvFromRank(int rank, int tag, size_type nRecvs);
315
320 template <typename Archive>
321 void serialize(Archive& ar, size_type nsends);
322
327 template <typename Archive>
328 void deserialize(Archive& ar, size_type nrecvs);
329
336 template <typename MemorySpace>
337 size_type packedSize(const size_type count) const;
338
339 protected:
345 void pack(const hash_container_type& hash);
346
351 void unpack(size_type nrecvs);
352
353 private:
355 // cannot use std::unique_ptr due to Kokkos
357
360
363
366
369
372
376 };
377} // namespace ippl
378
380
381#endif
Definition Archive.h:20
KOKKOS_INLINE_FUNCTION auto & get(Tuple< Ts... > &t)
Accessor function to get an element mutable reference at a specific index from a Tuple.
Definition Tuple.h:314
std::size_t size_type
Definition IpplTypes.h:13
void runForAllSpaces(Functor &&f)
Definition TypeUtils.h:428
virtual ~ParticleBaseBase()=default
std::vector< attribute_type< MemorySpace > * > container_type
void create(size_type nLocal)
void setParticleBC(const bc_container_type &bcs)
void addAttribute(detail::ParticleAttribBase< MemorySpace > &pa)
typename detail::ContainerForAllSpaces< detail::hash_type >::type hash_container_type
void pack(const hash_container_type &hash)
typename detail::ParticleAttribBase< Properties... > attribute_type
const Layout_t & getLayout() const
void serialize(Archive &ar, size_type nsends)
typename PLayout::vector_type vector_type
void forAllAttributes(Functor &&f)
void setParticleBC(BC bc)
void internalDestroy(const Kokkos::View< bool *, Properties... > &invalid, const size_type destroyNum)
ParticleAttrib< index_type, IDProperties... > particle_index_type
detail::size_type size_type
size_type getTotalNum() const
void globalCreate(size_type nTotal)
ParticleBase(Layout_t &layout)
void forAllAttributes(Functor &&f) const
void initialize(Layout_t &layout)
Layout_t & getLayout()
void unpack(size_type nrecvs)
void destroy(const Kokkos::View< bool *, Properties... > &invalid, const size_type destroyNum)
size_type packedSize(const size_type count) const
unsigned getAttributeNum() const
void recvFromRank(int rank, int tag, size_type nRecvs)
void createWithID(index_type id)
typename PLayout::index_type index_type
void setLocalNum(size_type size)
typename PLayout::bc_container_type bc_container_type
attribute_type< MemorySpace > * getAttribute(size_t i)
void sendToRank(int rank, int tag, std::vector< MPI_Request > &requests, const HashType &hash)
typename PLayout::particle_position_type particle_position_type
typename detail::ContainerForAllSpaces< container_type >::type attribute_container_type
void deserialize(Archive &ar, size_type nrecvs)
size_type getLocalNum() const
typename TypeForAllSpaces< container_type >::memory_spaces_type type
Definition TypeUtils.h:412