LCOV - code coverage report
Current view: top level - src/Particle - ParticleAttrib.h (source / functions) Coverage Total Hit
Test: final_report.info Lines: 72.7 % 22 16
Test Date: 2025-07-18 17:15:09 Functions: 73.7 % 224 165

            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          288 :         void serialize(detail::Archive<memory_space>& ar, size_type nsends) override {
      68          288 :             ar.serialize(buf_m, nsends);
      69          288 :         }
      70              : 
      71          288 :         void deserialize(detail::Archive<memory_space>& ar, size_type nrecvs) override {
      72          288 :             ar.deserialize(buf_m, nrecvs);
      73          288 :         }
      74              : 
      75         3360 :         virtual ~ParticleAttrib() = default;
      76              : 
      77          480 :         size_type size() const override { return dview_m.extent(0); }
      78              : 
      79          576 :         size_type packedSize(const size_type count) const override {
      80          576 :             return count * sizeof(value_type);
      81              :         }
      82              : 
      83          116 :         void resize(size_type n) { Kokkos::resize(dview_m, n); }
      84              : 
      85          456 :         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          576 :         view_type& getView() { return dview_m; }
      98              : 
      99         1092 :         const view_type& getView() const { return dview_m; }
     100              : 
     101          336 :         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
     145              :          * is used.
     146              :          */
     147              :         template <typename Field, typename P2, typename policy_type>
     148              :         void scatter(Field& f, 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
     160              :          * data 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
     167              :          * value; 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              :         /*!
     179              :          * @brief Sort the attribute according to a permutation.
     180              :          *
     181              :          * This function sorts the attribute according to a given permutation such that afterward
     182              :          * attr(permutation(i)) = attr(i).
     183              :          *
     184              :          * @note this cannot be done inplace and is not very cache efficient
     185              :          *
     186              :          * @param permutation The permutation to apply
     187              :          */
     188              :         void applyPermutation(const hash_type& permutation);
     189              : 
     190              :         /*!
     191              :          * @brief Copy and create values of given indices.
     192              :          *
     193              :          * This functions creates new particles with the values copied from the given indices. The
     194              :          * values will be at the highest new indices.
     195              :          *
     196              :          * @param indices The indices to copy.
     197              :          */
     198              :         void internalCopy(const hash_type& indices);
     199              : 
     200              :     private:
     201              :         view_type dview_m;
     202              :         view_type buf_m;
     203              :     };
     204              : }  // namespace ippl
     205              : 
     206              : #include "Particle/ParticleAttrib.hpp"
     207              : 
     208              : #endif
        

Generated by: LCOV version 2.0-1