Branch data Line data Source code
1 : : //
2 : : // Class ParticleAttrib
3 : : // Templated class for all particle attribute classes.
4 : : //
5 : : // This templated class is used to represent a single particle attribute.
6 : : // An attribute is one data element within a particle object, and is
7 : : // stored as a Kokkos::View. This class stores the type information for the
8 : : // attribute, and provides methods to create and destroy new items, and
9 : : // to perform operations involving this attribute with others.
10 : : //
11 : : // ParticleAttrib is the primary element involved in expressions for
12 : : // particles (just as LField is the primary element there). This file
13 : : // defines the necessary templated classes and functions to make
14 : : // ParticleAttrib a capable expression-template participant.
15 : : //
16 : : #ifndef IPPL_PARTICLE_ATTRIB_H
17 : : #define IPPL_PARTICLE_ATTRIB_H
18 : :
19 : : #include "Expression/IpplExpressions.h"
20 : :
21 : : #include "Interpolation/CIC.h"
22 : : #include "Particle/ParticleAttribBase.h"
23 : :
24 : : namespace ippl {
25 : :
26 : : // ParticleAttrib class definition
27 : : template <typename T, class... Properties>
28 : : class ParticleAttrib : public detail::ParticleAttribBase<>::with_properties<Properties...>,
29 : : public detail::Expression<
30 : : ParticleAttrib<T, Properties...>,
31 : : sizeof(typename detail::ViewType<T, 1, Properties...>::view_type)> {
32 : : public:
33 : : typedef T value_type;
34 : : constexpr static unsigned dim = 1;
35 : :
36 : : using Base = typename detail::ParticleAttribBase<>::with_properties<Properties...>;
37 : :
38 : : using hash_type = typename Base::hash_type;
39 : :
40 : : using view_type = typename detail::ViewType<T, 1, Properties...>::view_type;
41 : :
42 : : using HostMirror = typename view_type::host_mirror_type;
43 : :
44 : : using memory_space = typename view_type::memory_space;
45 : : using execution_space = typename view_type::execution_space;
46 : :
47 : : using size_type = detail::size_type;
48 : :
49 : : // Create storage for M particle attributes. The storage is uninitialized.
50 : : // New items are appended to the end of the array.
51 : : void create(size_type) override;
52 : :
53 : : /*!
54 : : * Particle deletion function. Partition the particles into a valid region
55 : : * and an invalid region.
56 : : * @param deleteIndex List of indices of invalid particles in the valid region
57 : : * @param keepIndex List of indices of valid particles in the invalid region
58 : : * @param invalidCount Number of invalid particles in the valid region
59 : : */
60 : : void destroy(const hash_type& deleteIndex, const hash_type& keepIndex,
61 : : size_type invalidCount) override;
62 : :
63 : : void pack(const hash_type&) override;
64 : :
65 : : void unpack(size_type) override;
66 : :
67 : 0 : void serialize(detail::Archive<memory_space>& ar, size_type nsends) override {
68 : 0 : ar.serialize(buf_m, nsends);
69 : 0 : }
70 : :
71 : 0 : void deserialize(detail::Archive<memory_space>& ar, size_type nrecvs) override {
72 : 0 : ar.deserialize(buf_m, nrecvs);
73 : 0 : }
74 : :
75 : 864 : virtual ~ParticleAttrib() = default;
76 : :
77 : 264 : size_type size() const override { return dview_m.extent(0); }
78 : :
79 : 0 : size_type packedSize(const size_type count) const override {
80 : 0 : return count * sizeof(value_type);
81 : : }
82 : :
83 : 0 : void resize(size_type n) { Kokkos::resize(dview_m, n); }
84 : :
85 : 252 : void realloc(size_type n) { Kokkos::realloc(dview_m, n); }
86 : :
87 : 0 : void print() {
88 [ # # ]: 0 : HostMirror hview = Kokkos::create_mirror_view(dview_m);
89 [ # # ]: 0 : Kokkos::deep_copy(hview, dview_m);
90 [ # # ]: 0 : for (size_type i = 0; i < *(this->localNum_mp); ++i) {
91 [ # # # # ]: 0 : std::cout << hview(i) << std::endl;
92 : : }
93 : 0 : }
94 : :
95 : 10752 : KOKKOS_INLINE_FUNCTION T& operator()(const size_t i) const { return dview_m(i); }
96 : :
97 : 324 : view_type& getView() { return dview_m; }
98 : :
99 : 462 : const view_type& getView() const { return dview_m; }
100 : :
101 : 180 : HostMirror getHostMirror() { return Kokkos::create_mirror(dview_m); }
102 : :
103 : : /*!
104 : : * Assign the same value to the whole attribute.
105 : : */
106 : : // KOKKOS_INLINE_FUNCTION
107 : : ParticleAttrib<T, Properties...>& operator=(T x);
108 : :
109 : : /*!
110 : : * Assign an arbitrary particle attribute expression
111 : : * @tparam E expression type
112 : : * @tparam N size of the expression, this is necessary for running on the
113 : : * device since otherwise it does not allocate enough memory
114 : : * @param expr is the expression
115 : : */
116 : : template <typename E, size_t N>
117 : : // KOKKOS_INLINE_FUNCTION
118 : : ParticleAttrib<T, Properties...>& operator=(detail::Expression<E, N> const& expr);
119 : :
120 : : /**
121 : : * @brief Scatter particle attribute data onto a field.
122 : : *
123 : : * This function scatters data from this attribute onto the given field,
124 : : * using the given position attribute.
125 : : * The function can be used together with a custom iteration policy to iterate
126 : : * over a specified range and, optionally, an `ippl::hash_type` array to remap
127 : : * iteration indices.
128 : : *
129 : : * When a non-empty `hash_array` is provided, the function:
130 : : * - Checks that the iteration policy's range does not exceed the size of `hash_array`.
131 : : * - Maps the current index to the appropriate index using the `hash_array`.
132 : : * - Careful: access pattern optimization might be lost when using `hash_array`.
133 : : *
134 : : * @note This custom iteration functionality is needed to support energy binning
135 : : * in the field solver of OPAL-X, allowing only particles within a specific bin
136 : : * to be scattered.
137 : : *
138 : : * @tparam Field The type of the field.
139 : : * @tparam P2 The type for the position attribute.
140 : : * @tparam policy_type The type of the Kokkos iteration policy when using `hash_array`.
141 : : * @param f The field onto which the particle data is scattered.
142 : : * @param pp The ParticleAttrib representing particle positions.
143 : : * @param iteration_policy A custom `Kokkos::range_policy` defining the iteration range.
144 : : * @param hash_array An optional `ippl::hash_type` array for index mapping. If empty, no map is used.
145 : : */
146 : : template <typename Field, typename P2, typename policy_type>
147 : : void scatter(Field& f,
148 : : const ParticleAttrib<Vector<P2, Field::dim>, Properties...>& pp,
149 : : policy_type iteration_policy, hash_type hash_array = {}) const;
150 : :
151 : : /**
152 : : * @brief Gather field data into the particle attribute.
153 : : *
154 : : * This function gathers data from the given field into the particle attribute
155 : : * by iterating over all particles. Depending on the parameter @p addToAttribute,
156 : : * the gathered field value is either added to the existing attribute value (using "+=")
157 : : * or used to overwrite the attribute value.
158 : : *
159 : : * @note This behavior exists to give the OPAL-X field solver the ablity to gather field data
160 : : * per "energy bin".
161 : : *
162 : : * @tparam Field The type of the field.
163 : : * @tparam P2 The particle type for the position attribute.
164 : : * @param f The field from which data is gathered.
165 : : * @param pp The ParticleAttrib representing particle positions.
166 : : * @param addToAttribute If `true`, the gathered value is added to the current attribute value;
167 : : * otherwise, the attribute value is overwritten.
168 : : */
169 : : template <typename Field, typename P2>
170 : : void gather(Field& f, const ParticleAttrib<Vector<P2, Field::dim>, Properties...>& pp,
171 : : const bool addToAttribute = false);
172 : :
173 : : T sum();
174 : : T max();
175 : : T min();
176 : : T prod();
177 : :
178 : : private:
179 : : view_type dview_m;
180 : : view_type buf_m;
181 : : };
182 : : } // namespace ippl
183 : :
184 : : #include "Particle/ParticleAttrib.hpp"
185 : :
186 : : #endif
|