21 #ifndef THUNDEREGG_DOMAIN_H
22 #define THUNDEREGG_DOMAIN_H
64 std::array<int, D> ns;
72 int num_cells_in_patch;
76 int num_cells_in_patch_with_ghost;
81 std::vector<PatchInfo<D>> pinfos;
85 int global_num_patches = 1;
89 mutable std::shared_ptr<Timer> timer;
94 void indexPatchesLocal()
98 std::map<int, int> id_to_local_index;
99 for (
auto& pinfo : pinfos) {
100 pinfo.local_index = curr_index;
101 id_to_local_index[pinfo.id] = pinfo.local_index;
106 for (
auto& pinfo : pinfos) {
107 pinfo.setNeighborLocalIndexes(id_to_local_index);
113 void indexPatchesGlobal()
116 int num_local_patches = (int)pinfos.size();
117 int curr_global_index;
118 MPI_Scan(&num_local_patches, &curr_global_index, 1, MPI_INT, MPI_SUM, comm.
getMPIComm());
119 curr_global_index -= num_local_patches;
122 std::map<int, int> id_to_global_index;
123 for (
auto& pinfo : pinfos) {
124 pinfo.global_index = curr_global_index;
125 id_to_global_index[pinfo.id] = pinfo.global_index;
129 std::map<int, std::set<std::pair<int, int>>> ranks_to_ids_and_global_indexes_outgoing;
130 std::map<int, std::set<int>> ranks_to_ids_incoming;
131 for (
auto& pinfo : pinfos) {
132 auto ranks = pinfo.getNbrRanks();
133 auto ids = pinfo.getNbrIds();
134 for (
size_t idx = 0; idx < ranks.size(); idx++) {
135 int nbr_id = ids[idx];
136 int nbr_rank = ranks[idx];
137 if (nbr_rank != comm.
getRank()) {
138 ranks_to_ids_and_global_indexes_outgoing[nbr_rank].insert(
139 std::make_pair(pinfo.id, pinfo.global_index));
140 ranks_to_ids_incoming[nbr_rank].insert(nbr_id);
146 std::vector<MPI_Request> recv_requests;
149 std::map<int, std::vector<int>> rank_to_incoming_data;
150 for (
const auto& pair : ranks_to_ids_incoming) {
151 int source_rank = pair.first;
152 std::vector<int>& incoming_data = rank_to_incoming_data[source_rank];
153 incoming_data.resize(pair.second.size());
156 MPI_Irecv(incoming_data.data(),
157 (
int)incoming_data.size(),
163 recv_requests.push_back(request);
167 std::vector<MPI_Request> send_requests;
170 std::map<int, std::vector<int>> rank_to_outgoing_data;
171 for (
const auto& pair : ranks_to_ids_and_global_indexes_outgoing) {
172 int dest_rank = pair.first;
174 std::vector<int>& data = rank_to_outgoing_data[dest_rank];
175 data.reserve(pair.second.size());
176 for (
const auto& id_and_global_index : pair.second) {
177 data.push_back(id_and_global_index.second);
180 MPI_Isend(data.data(), (
int)data.size(), MPI_INT, dest_rank, 0, comm.
getMPIComm(), &request);
181 send_requests.push_back(request);
185 for (
size_t i = 0; i < recv_requests.size(); i++) {
188 MPI_Waitany((
int)recv_requests.size(), recv_requests.data(), &request_index, &status);
190 int source_rank = status.MPI_SOURCE;
191 const std::set<int>& incoming_ids = ranks_to_ids_incoming[source_rank];
192 const std::vector<int>& data = rank_to_incoming_data[source_rank];
194 auto curr_id = incoming_ids.cbegin();
195 auto curr_global_index_iter = data.cbegin();
196 while (curr_id != incoming_ids.cend()) {
197 id_to_global_index[*curr_id] = *curr_global_index_iter;
199 curr_global_index_iter++;
204 MPI_Waitall((
int)send_requests.size(), send_requests.data(), MPI_STATUSES_IGNORE);
207 for (
auto& pinfo : pinfos) {
208 pinfo.setNeighborGlobalIndexes(id_to_global_index);
223 template<
class InputIterator>
226 std::array<int, D> ns,
228 InputIterator first_pinfo,
229 InputIterator last_pinfo)
233 , num_ghost_cells(num_ghost_cells)
234 , pinfos(first_pinfo, last_pinfo)
236 num_cells_in_patch = 1;
237 num_cells_in_patch_with_ghost = 1;
238 for (
size_t i = 0; i < D; i++) {
239 num_cells_in_patch *= ns[i];
240 num_cells_in_patch_with_ghost *= (ns[i] + 2 * num_ghost_cells);
243 int num_local_domains = pinfos.size();
244 MPI_Allreduce(&num_local_domains, &global_num_patches, 1, MPI_INT, MPI_SUM, comm.
getMPIComm());
247 indexPatchesGlobal();
264 const std::array<int, D>&
getNs()
const {
return ns; }
286 return ((
int)pinfos.size()) * num_cells_in_patch_with_ghost;
304 for (
auto& pinfo : pinfos) {
305 double patch_vol = 1;
306 for (
size_t i = 0; i < D; i++) {
307 patch_vol *= pinfo.spacings[i] * pinfo.ns[i];
312 MPI_Allreduce(&sum, &retval, 1, MPI_DOUBLE, MPI_SUM, comm.
getMPIComm());
323 timer->addDomain(
id, *
this);
330 std::shared_ptr<Timer>
getTimer()
const {
return timer; }
346 to_json(tpl::nlohmann::json& j,
const Domain<D>& domain)
348 for (
auto pinfo : domain.getPatchInfoVector()) {
353 extern template class Domain<2>;
354 extern template class Domain<3>;
356 to_json<2>(tpl::nlohmann::json& j,
const Domain<2>& domain);
358 to_json<3>(tpl::nlohmann::json& j,
const Domain<3>& domain);