IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
ParticleBase.h
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
62#include "Particle/ParticleLayout.h"
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;
94 using particle_index_type = ParticleAttrib<index_type, IDProperties...>;
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
104 using attribute_container_type =
105 typename detail::ContainerForAllSpaces<container_type>::type;
106
107 using bc_container_type = typename PLayout::bc_container_type;
108
109 using hash_container_type = typename detail::ContainerForAllSpaces<detail::hash_type>::type;
110
111 using size_type = detail::size_type;
112
113 public:
115 particle_position_type R;
116
119
124 ParticleBase();
125
133 ParticleBase(Layout_t& layout);
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
167 Layout_t& getLayout() { return *layout_m; }
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>
199 attribute_type<MemorySpace>* getAttribute(size_t i) {
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
257 void create(size_type nLocal, bool non_destructive = false);
258
266 void alloc(size_type nLocal);
267
273 void createWithID(index_type id);
274
280 void globalCreate(size_type nTotal);
281
289 template <typename... Properties>
290 void destroy(const Kokkos::View<bool*, Properties...>& invalid, const size_type destroyNum);
291
292 // This is a collective call.
293 void update() { layout_m->update(*this); }
294
295 /*
296 * The following functions should not be called in an application.
297 */
298
299 /* This function does not alter the totalNum_m member function. It should only be called
300 * during the update function where we know the number of particles remains the same.
301 */
302 template <typename... Properties>
303 void internalDestroy(const Kokkos::View<bool*, Properties...>& invalid,
304 const size_type destroyNum);
305
315 template <typename HashType>
316 void sendToRank(int rank, int tag, std::vector<MPI_Request>& requests,
317 const HashType& hash);
318
325 void recvFromRank(int rank, int tag, size_type nRecvs);
326
332 template <typename Archive>
333 void serialize(Archive& ar, size_type nsends);
334
340 template <typename Archive>
341 void deserialize(Archive& ar, size_type nrecvs);
342
349 template <typename MemorySpace>
350 size_type packedSize(const size_type count) const;
351
352 protected:
357 void pack(const hash_container_type& hash);
358
363 void unpack(size_type nrecvs);
364
365 private:
367 // cannot use std::unique_ptr due to Kokkos
368 Layout_t* layout_m;
369
371 size_type localNum_m;
372
374 size_type totalNum_m;
375
377 attribute_container_type attributes_m;
378
380 index_type nextID_m;
381
383 index_type numNodes_m;
384
386 hash_container_type deleteIndex_m;
387 hash_container_type keepIndex_m;
388 };
389} // namespace ippl
390
391#include "Particle/ParticleBase.hpp"
392
393#endif
Definition ParticleBase.h:73
Definition ParticleBase.h:87
void setParticleBC(const bc_container_type &bcs)
Definition ParticleBase.h:178
void addAttribute(detail::ParticleAttribBase< MemorySpace > &pa)
Definition ParticleBase.hpp:77
void pack(const hash_container_type &hash)
Definition ParticleBase.hpp:351
const Layout_t & getLayout() const
Definition ParticleBase.h:172
void serialize(Archive &ar, size_type nsends)
Definition ParticleBase.hpp:324
void setParticleBC(BC bc)
Definition ParticleBase.h:184
size_type getTotalNum() const
Definition ParticleBase.h:162
void globalCreate(size_type nTotal)
Definition ParticleBase.hpp:152
void forAllAttributes(Functor &&f) const
Definition ParticleBase.h:211
void initialize(Layout_t &layout)
Definition ParticleBase.hpp:83
Layout_t & getLayout()
Definition ParticleBase.h:167
void unpack(size_type nrecvs)
Definition ParticleBase.hpp:361
void create(size_type nLocal, bool non_destructive=false)
Definition ParticleBase.hpp:91
void destroy(const Kokkos::View< bool *, Properties... > &invalid, const size_type destroyNum)
Definition ParticleBase.hpp:170
size_type packedSize(const size_type count) const
unsigned getAttributeNum() const
Definition ParticleBase.h:240
void recvFromRank(int rank, int tag, size_type nRecvs)
Definition ParticleBase.hpp:307
void alloc(size_type nLocal)
Definition ParticleBase.hpp:126
void createWithID(index_type id)
Definition ParticleBase.hpp:135
attribute_type< MemorySpace > * getAttribute(size_t i)
Definition ParticleBase.h:199
void sendToRank(int rank, int tag, std::vector< MPI_Request > &requests, const HashType &hash)
Definition ParticleBase.hpp:283
ParticleBase()
Definition ParticleBase.hpp:55
particle_position_type R
view of particle positions
Definition ParticleBase.h:115
particle_index_type ID
view of particle IDs
Definition ParticleBase.h:118
void deserialize(Archive &ar, size_type nrecvs)
Definition ParticleBase.hpp:333
size_type getLocalNum() const
Definition ParticleBase.h:155
Definition ParticleAttribBase.h:30
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