Line data Source code
1 :
2 : //
3 : // Class ParticleSpatialLayout
4 : // Particle layout based on spatial decomposition.
5 : //
6 : // This is a specialized version of ParticleLayout, which places particles
7 : // on processors based on their spatial location relative to a fixed grid.
8 : // In particular, this can maintain particles on processors based on a
9 : // specified FieldLayout or RegionLayout, so that particles are always on
10 : // the same node as the node containing the Field region to which they are
11 : // local. This may also be used if there is no associated Field at all,
12 : // in which case a grid is selected based on an even distribution of
13 : // particles among processors.
14 : //
15 : // After each 'time step' in a calculation, which is defined as a period
16 : // in which the particle positions may change enough to affect the global
17 : // layout, the user must call the 'update' routine, which will move
18 : // particles between processors, etc. After the Nth call to update, a
19 : // load balancing routine will be called instead. The user may set the
20 : // frequency of load balancing (N), or may supply a function to
21 : // determine if load balancing should be done or not.
22 : //
23 : #ifndef IPPL_PARTICLE_SPATIAL_LAYOUT_H
24 : #define IPPL_PARTICLE_SPATIAL_LAYOUT_H
25 :
26 : #include "Types/IpplTypes.h"
27 :
28 : #include "FieldLayout/FieldLayout.h"
29 : #include "Particle/ParticleBase.h"
30 : #include "Particle/ParticleLayout.h"
31 : #include "Region/RegionLayout.h"
32 :
33 : #include "Communicate/Window.h"
34 : #include <vector>
35 :
36 : namespace ippl {
37 :
38 : /*!
39 : * ParticleSpatialLayout class definition.
40 : * @tparam T value type
41 : * @tparam Dim dimension
42 : * @tparam Mesh type
43 : */
44 : template <typename T, unsigned Dim, class Mesh = UniformCartesian<T, Dim>,
45 : typename... PositionProperties>
46 : class ParticleSpatialLayout : public detail::ParticleLayout<T, Dim, PositionProperties...> {
47 : public:
48 : using Base = detail::ParticleLayout<T, Dim, PositionProperties...>;
49 : using typename Base::position_memory_space, typename Base::position_execution_space;
50 :
51 : using hash_type = detail::hash_type<position_memory_space>;
52 : using locate_type = typename detail::ViewType<int, 1, position_memory_space>::view_type;
53 : using bool_type = typename detail::ViewType<bool, 1, position_memory_space>::view_type;
54 :
55 : using vector_type = typename Base::vector_type;
56 : using RegionLayout_t =
57 : typename detail::RegionLayout<T, Dim, Mesh, position_memory_space>::uniform_type;
58 : using FieldLayout_t = typename ippl::FieldLayout<Dim>;
59 :
60 : using size_type = detail::size_type;
61 :
62 : public:
63 : // constructor: this one also takes a Mesh
64 : ParticleSpatialLayout(FieldLayout<Dim>&, Mesh&);
65 :
66 : ParticleSpatialLayout()
67 : : detail::ParticleLayout<T, Dim, PositionProperties...>() {}
68 :
69 144 : ~ParticleSpatialLayout() = default;
70 :
71 : void updateLayout(FieldLayout<Dim>&, Mesh&);
72 :
73 : template <class ParticleContainer>
74 : void update(ParticleContainer& pc);
75 :
76 24 : const RegionLayout_t& getRegionLayout() const { return rlayout_m; }
77 :
78 : protected:
79 : //! The RegionLayout which determines where our particles go.
80 : RegionLayout_t rlayout_m;
81 :
82 : //! The FieldLayout containing information on nearest neighbors
83 : FieldLayout_t& flayout_m;
84 :
85 :
86 : // Vector keeping track of the recieves from all ranks
87 : std::vector<size_type> nRecvs_m;
88 :
89 : // MPI RMA window for one-sided communication
90 : mpi::rma::Window<mpi::rma::Active> window_m;
91 :
92 : //! Type of the Kokkos view containing the local regions.
93 : using region_view_type = typename RegionLayout_t::view_type;
94 : //! Type of a single Region object.
95 : using region_type = typename region_view_type::value_type;
96 : //! Array of N rank lists, where N = number of hypercubes for the dimension Dim.
97 : using neighbor_list = typename FieldLayout_t::neighbor_list;
98 :
99 : template <size_t... Idx>
100 : KOKKOS_INLINE_FUNCTION constexpr static bool positionInRegion(
101 : const std::index_sequence<Idx...>&, const vector_type& pos, const region_type& region);
102 :
103 : /*!
104 : * Evaluates the total number of MPI ranks sharing the spatial nearest neighbors.
105 : * @param neighbors structure containing, for every spatial direction, a list of
106 : * MPI ranks IDs corresponding to the nearest neighbors of the current local domain section.
107 : * @return The total number of the ranks.
108 : */
109 : size_type getNeighborSize(const neighbor_list& neighbors) const;
110 :
111 : public:
112 : /*!
113 : * For each particle in the bunch, determine the rank on which it should
114 : * be stored based on its location
115 : * @tparam ParticleContainer the particle container type
116 : * @param pc the particle container
117 : * @param ranks the integer view in which to store the destination ranks
118 : * @param invalid the boolean view in which to store whether each particle
119 : * is invalidated, i.e. needs to be sent to another rank
120 : * @return The total number of invalidated particles
121 : */
122 : template <typename ParticleContainer>
123 : std::pair<size_type,size_type> locateParticles(const ParticleContainer& pc, locate_type& ranks,
124 : bool_type& invalid, locate_type& nSends_dview, locate_type& sends_dview) const;
125 :
126 : /*!
127 : * @param rank we sent to
128 : * @param ranks a container specifying where a particle at the i-th index should go.
129 : * @param hash a mapping to fill the send buffer contiguously
130 : */
131 : void fillHash(int rank, const locate_type& ranks, hash_type& hash);
132 :
133 : /*!
134 : * @param rank we sent to
135 : * @param ranks a container specifying where a particle at the i-th index should go.
136 : */
137 : size_t numberOfSends(int rank, const locate_type& ranks);
138 : };
139 : } // namespace ippl
140 :
141 : #include "Particle/ParticleSpatialLayout.hpp"
142 :
143 : #endif
144 :
|