IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
SubFieldLayout.hpp
1//
2// Class SubFieldLayout
3// SubFieldLayout provides a layout for a sub-region of a larger field.
4// It ensures that the sub-region is partitioned in the same way as the original FieldLayout,
5// maintaining consistent parallel decomposition and neighbor relationships within the sub-region.
6//
7#include "Ippl.h"
8
9#include <cstdlib>
10#include <limits>
11
12#include "Utility/IpplException.h"
13#include "Utility/IpplTimings.h"
14#include "Utility/PAssert.h"
15
16#include "FieldLayout/SubFieldLayout.h"
17
18namespace ippl {
19
27 template <unsigned Dim>
29 : FieldLayout<Dim>(communicator) {}
30
43 template <unsigned Dim>
45 const NDIndex<Dim>& subDomain, std::array<bool, Dim> isParallel, bool isAllPeriodic)
46 : FieldLayout<Dim>(communicator) {
47 initialize(domain, subDomain, isParallel, isAllPeriodic);
48 }
49
57 template <unsigned Dim>
59 std::array<bool, Dim> isParallel, bool isAllPeriodic)
60 : FieldLayout<Dim>(communicator) {
61 initialize(domain, isParallel, isAllPeriodic);
62 }
63
75 template <unsigned Dim>
76 void SubFieldLayout<Dim>::initialize(const NDIndex<Dim>& domain, const NDIndex<Dim>& subDomain, std::array<bool, Dim> isParallel,
77 bool isAllPeriodic) {
78
79 // Ensure the sub-domain is contained within the main domain
80 PAssert(domain.contains(subDomain));
81
82 // Call the base class initialize method to set up the main domain and parallel decomposition
83 FieldLayout<Dim>::initialize(domain, isParallel, isAllPeriodic);
84
85 unsigned int nRanks = this->comm.size();
86
87 originDomain_m = domain;
88
89 this->gDomain_m = subDomain;
90
91 // Check if all ranks have a valid local domain that intersects with the sub-domain
92 if (this->hLocalDomains_m(this->comm.rank()).intersect(subDomain).empty()) {
93 throw std::runtime_error("SubFieldLayout:initialize: given subdomain is not valid, rank"
94 + std::to_string(this->comm.rank()) + " has an empty local domain, choose a sub-domain that has content on all ranks");
95 }
96
97 // If the local domain is not contained in the sub-domain, change it to the intersection of the local domain and the sub-domain
98 // This ensures that the sub-field layout is consistent with the original layout
99 for (unsigned int rank = 0; rank < nRanks; ++rank) {
100 if (!this->gDomain_m.contains(this->hLocalDomains_m(rank))) {
101 this->hLocalDomains_m(rank) = this->hLocalDomains_m(rank).intersect(this->gDomain_m);
102 }
103 }
104
105 this->findNeighbors();
106
107 Kokkos::deep_copy(this->dLocalDomains_m, this->hLocalDomains_m);
108
109 this->calcWidths();
110 }
111
119 template <unsigned Dim>
120 void SubFieldLayout<Dim>::initialize(const NDIndex<Dim>& domain, std::array<bool, Dim> isParallel,
121 bool isAllPeriodic) {
122 // Call the base class initialize method to set up the main domain and parallel decomposition
123 FieldLayout<Dim>::initialize(domain, isParallel, isAllPeriodic);
124
125 originDomain_m = domain;
126 }
127
128} // namespace ippl
Definition FieldLayout.h:166
Definition NDIndex.h:21
SubFieldLayout(const mpi::Communicator &=MPI_COMM_WORLD)
Default constructor, which should only be used if you are going to call 'initialize' soon after (befo...
Definition SubFieldLayout.hpp:28
void initialize(const NDIndex< Dim > &domain, const NDIndex< Dim > &subDomain, std::array< bool, Dim > decomp, bool isAllPeriodic=false)
Initializes a SubFieldLayout with the sub-domain partitioned in the same way as the original FieldLay...
Definition SubFieldLayout.hpp:76
Definition Communicator.h:31
Definition Archive.h:20