Branch data Line data Source code
1 : : //
2 : : // Class RegionLayout
3 : : // RegionLayout stores a partitioned set of NDRegion objects, to represent
4 : : // the parallel layout of an encompassing NDRegion. It also contains
5 : : // functions to find the subsets of the NDRegion partitions which intersect
6 : : // or touch a given NDRegion. It is similar to FieldLayout, with the
7 : : // following changes:
8 : : // 1. It uses NDRegion instead of NDIndex, so it is templated on the position
9 : : // data type (although it can be constructed with an NDIndex and a Mesh
10 : : // as well);
11 : : // 2. It does not contain any consideration for guard cells;
12 : : // 3. It can store not only the partitioned domain, but periodic copies of
13 : : // the partitioned domain for use by particle periodic boundary conditions
14 : : // 4. It also keeps a list of FieldLayoutUser's, so that it can notify them
15 : : // when the internal FieldLayout here is reparitioned or otherwise changed.
16 : : //
17 : : // If this is constructed with a FieldLayout, it stores a pointer to it
18 : : // so that if we must repartition the copy of the FieldLayout that
19 : : // is stored here, we will end up repartitioning all the registered Fields.
20 : : //
21 : : namespace ippl {
22 : : namespace detail {
23 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
24 : 60 : RegionLayout<T, Dim, Mesh, Properties...>::RegionLayout()
25 [ + - ]: 60 : : dLocalRegions_m("local regions (device)", 0)
26 [ + - + - ]: 120 : , hLocalRegions_m(Kokkos::create_mirror_view(dLocalRegions_m)) {
27 [ + - ]: 60 : indexOffset_m.fill(0);
28 [ + - ]: 60 : centerOffset_m.fill(0);
29 : 60 : }
30 : :
31 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
32 : 60 : RegionLayout<T, Dim, Mesh, Properties...>::RegionLayout(const FieldLayout<Dim>& fl,
33 : : const Mesh& mesh)
34 : 60 : : RegionLayout() {
35 [ + - ]: 60 : changeDomain(fl, mesh);
36 : 60 : }
37 : :
38 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
39 : 84 : void RegionLayout<T, Dim, Mesh, Properties...>::changeDomain(const FieldLayout<Dim>& fl,
40 : : const Mesh& mesh) {
41 : : // set our index space offset
42 [ + + ]: 378 : for (unsigned int d = 0; d < Dim; ++d) {
43 : 294 : indexOffset_m[d] = fl.getDomain()[d].first();
44 : 294 : centerOffset_m[d] = 1;
45 : : }
46 : :
47 [ + - ]: 84 : region_m = convertNDIndex(fl.getDomain(), mesh);
[ + - + - ]
48 : :
49 : 84 : fillRegions(fl, mesh);
50 : 84 : }
51 : :
52 : : // convert a given NDIndex into an NDRegion ... if this object was
53 : : // constructed from a FieldLayout, this does nothing, but if we are maintaining
54 : : // our own internal FieldLayout, we must convert from the [0,N-1] index
55 : : // space to our own continuous NDRegion space.
56 : : // NOTE: THIS ASSUMES THAT REGION'S HAVE first() < last() !!
57 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
58 : : typename RegionLayout<T, Dim, Mesh, Properties...>::NDRegion_t
59 : 168 : RegionLayout<T, Dim, Mesh, Properties...>::convertNDIndex(const NDIndex<Dim>& ni,
60 : : const Mesh& mesh) const {
61 : : // find first and last points in NDIndex and get coordinates from mesh
62 : 168 : NDIndex<Dim> firstPoint, lastPoint;
63 [ + + ]: 756 : for (unsigned int d = 0; d < Dim; d++) {
64 : 588 : int first = ni[d].first() - indexOffset_m[d];
65 : 588 : int last = ni[d].last() - indexOffset_m[d] + centerOffset_m[d];
66 [ + - ]: 588 : firstPoint[d] = Index(first, first);
67 [ + - ]: 588 : lastPoint[d] = Index(last, last);
68 : : }
69 : :
70 : : // convert to mesh space
71 [ + - ]: 168 : Vector<T, Dim> firstCoord = mesh.getVertexPosition(firstPoint);
[ + - + - ]
72 [ + - ]: 168 : Vector<T, Dim> lastCoord = mesh.getVertexPosition(lastPoint);
[ + - + - ]
73 [ + - ]: 168 : NDRegion_t ndregion;
74 [ + + ]: 756 : for (unsigned int d = 0; d < Dim; d++) {
75 [ + - ]: 588 : ndregion[d] = PRegion<T>(firstCoord(d), lastCoord(d));
76 : : }
77 : 168 : return ndregion;
78 : 168 : }
79 : :
80 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
81 : 84 : void RegionLayout<T, Dim, Mesh, Properties...>::fillRegions(const FieldLayout<Dim>& fl,
82 : : const Mesh& mesh) {
83 : : using domain_type = typename FieldLayout<Dim>::host_mirror_type;
84 [ + - ]: 84 : const domain_type& ldomains = fl.getHostLocalDomains();
85 : :
86 [ + - + - ]: 84 : Kokkos::resize(hLocalRegions_m, ldomains.size());
87 [ + - + - ]: 84 : Kokkos::resize(dLocalRegions_m, ldomains.size());
88 : :
89 : : using size_type = typename domain_type::size_type;
90 [ + - + + ]: 168 : for (size_type i = 0; i < ldomains.size(); ++i) {
91 [ + - ]: 168 : hLocalRegions_m(i) = convertNDIndex(ldomains(i), mesh);
[ + - + - ]
92 : : }
93 : :
94 [ + - ]: 84 : Kokkos::deep_copy(dLocalRegions_m, hLocalRegions_m);
95 : 84 : }
96 : :
97 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
98 : : void RegionLayout<T, Dim, Mesh, Properties...>::write(std::ostream& out) const {
99 : : if (Comm->rank() > 0) {
100 : : return;
101 : : }
102 : :
103 : : out << "Total region = " << region_m << "\n"
104 : : << "Total number of subregions = " << hLocalRegions_m.size() << "\n";
105 : :
106 : : using size_type = typename host_mirror_type::size_type;
107 : : for (size_type i = 0; i < hLocalRegions_m.size(); ++i) {
108 : : out << " subregion " << i << " " << hLocalRegions_m(i) << "\n";
109 : : }
110 : : }
111 : :
112 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
113 : : const typename RegionLayout<T, Dim, Mesh, Properties...>::view_type
114 : 12 : RegionLayout<T, Dim, Mesh, Properties...>::getdLocalRegions() const {
115 : 12 : return dLocalRegions_m;
116 : : }
117 : :
118 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
119 : : const typename RegionLayout<T, Dim, Mesh, Properties...>::host_mirror_type
120 : 0 : RegionLayout<T, Dim, Mesh, Properties...>::gethLocalRegions() const {
121 : 0 : return hLocalRegions_m;
122 : : }
123 : :
124 : : template <typename T, unsigned Dim, class Mesh, class... Properties>
125 : : std::ostream& operator<<(std::ostream& out, const RegionLayout<T, Dim, Mesh>& rl) {
126 : : rl.write(out);
127 : : return out;
128 : : }
129 : : } // namespace detail
130 : : } // namespace ippl
|