ThunderEgg  1.0.0
InterfaceDomain.h
Go to the documentation of this file.
1 /***************************************************************************
2  * ThunderEgg, a library for solvers on adaptively refined block-structured
3  * Cartesian grids.
4  *
5  * Copyright (c) 2017-2021 Scott Aiton
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  ***************************************************************************/
20 
21 #ifndef THUNDEREGG_SCHUR_InterfaceDomain_H
22 #define THUNDEREGG_SCHUR_InterfaceDomain_H
23 
30 #include <ThunderEgg/Vector.h>
31 #include <deque>
32 namespace ThunderEgg {
33 namespace Schur {
54 template<int D>
56 {
57 private:
58  std::array<int, D - 1> iface_ns;
59  Domain<D> domain;
60 
65  std::vector<std::shared_ptr<const PatchIfaceInfo<D>>> piinfos;
70  std::vector<std::shared_ptr<const Interface<D>>> interfaces;
74  int num_global_ifaces = 0;
75 
84  static void IndexIfacesLocal(const std::map<int, std::shared_ptr<Interface<D>>>& id_to_iface_map,
85  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos,
86  std::vector<std::shared_ptr<Interface<D>>>& interfaces)
87  {
88  int curr_local_index = 0;
89 
90  // index interface objects first
91  interfaces.clear();
92  interfaces.reserve(id_to_iface_map.size());
93  for (auto pair : id_to_iface_map) {
94  auto iface = pair.second;
95 
96  iface->local_index = curr_local_index;
97  interfaces.push_back(iface);
98 
99  for (auto patch : iface->patches) {
100  if (patch.type.isNormal() || patch.type.isFineToFine() || patch.type.isCoarseToCoarse()) {
101  patch.getNonConstPiinfo()->getIfaceInfo(patch.side)->patch_local_index = curr_local_index;
102  patch.getNonConstPiinfo()->getIfaceInfo(patch.side)->col_local_index = curr_local_index;
103  patch.getNonConstPiinfo()->getIfaceInfo(patch.side)->row_local_index = curr_local_index;
104  } else if (patch.type.isFineToCoarse()) {
105  patch.getNonConstPiinfo()->getCoarseIfaceInfo(patch.side)->coarse_col_local_index =
106  curr_local_index;
107  } else if (patch.type.isCoarseToFine()) {
108  auto iface_info = patch.getNonConstPiinfo()->getFineIfaceInfo(patch.side);
109  for (size_t i = 0; i < iface_info->fine_col_local_indexes.size(); i++) {
110  if (iface_info->fine_ids[i] == iface->id) {
111  iface_info->fine_col_local_indexes[i] = curr_local_index;
112  break;
113  }
114  }
115  }
116  }
117 
118  curr_local_index++;
119  }
120 
121  // perform rest of necessary indexing
122  IndexRemainingColIfacesLocal(curr_local_index, interfaces);
123  IndexRemainingRowIfacesLocal(curr_local_index, interfaces);
124  IndexRemainingPatchIfacesLocal(curr_local_index, piinfos);
125  }
132  static void GetRemainginColIfacesLocalForPatch(
133  std::shared_ptr<PatchIfaceInfo<D>> piinfo,
134  std::map<int, std::set<int*>>& id_to_local_indexes_to_set)
135  {
136  for (Side<D> s : Side<D>::getValues()) {
137  if (piinfo->pinfo.hasNbr(s)) {
138  auto iface_info = piinfo->getIfaceInfo(s);
139  if (iface_info->col_local_index == -1) {
140  id_to_local_indexes_to_set[iface_info->id].insert(&iface_info->col_local_index);
141  }
142 
143  NbrType nbr_type = piinfo->pinfo.getNbrType(s);
144 
145  if (nbr_type == NbrType::Coarse) {
146  auto coarse_iface_info = piinfo->getCoarseIfaceInfo(s);
147  if (coarse_iface_info->coarse_col_local_index == -1) {
148  id_to_local_indexes_to_set[coarse_iface_info->coarse_id].insert(
149  &coarse_iface_info->coarse_col_local_index);
150  }
151  } else if (nbr_type == NbrType::Fine) {
152  auto fine_iface_info = piinfo->getFineIfaceInfo(s);
153  for (size_t i = 0; i < fine_iface_info->fine_col_local_indexes.size(); i++) {
154  if (fine_iface_info->fine_col_local_indexes[i] == -1) {
155  id_to_local_indexes_to_set[fine_iface_info->fine_ids[i]].insert(
156  &fine_iface_info->fine_col_local_indexes[i]);
157  }
158  }
159  }
160  }
161  }
162  }
169  static void IndexRemainingColIfacesLocal(
170  int curr_local_index,
171  const std::vector<std::shared_ptr<Interface<D>>>& interfaces)
172  {
173  std::map<int, std::set<int*>> id_to_local_indexes_to_set;
174  for (auto iface : interfaces) {
175  for (auto patch : iface->patches) {
176  auto piinfo = patch.getNonConstPiinfo();
177 
178  if (patch.type.isNormal() || patch.type.isFineToFine() || patch.type.isCoarseToCoarse()) {
179  GetRemainginColIfacesLocalForPatch(piinfo, id_to_local_indexes_to_set);
180  }
181  }
182  }
183  for (auto id_and_local_indexes : id_to_local_indexes_to_set) {
184  for (int* local_index_to_set : id_and_local_indexes.second) {
185  *local_index_to_set = curr_local_index;
186  }
187  curr_local_index++;
188  }
189  }
196  static void IndexRemainingRowIfacesLocal(
197  int curr_local_index,
198  const std::vector<std::shared_ptr<Interface<D>>>& interfaces)
199  {
200  std::map<int, std::set<int*>> id_to_local_indexes_to_set;
201  for (auto iface : interfaces) {
202  for (auto patch : iface->patches) {
203  auto piinfo = patch.getNonConstPiinfo();
204 
205  for (Side<D> s : Side<D>::getValues()) {
206  if (piinfo->pinfo.hasNbr(s)) {
207  auto iface_info = piinfo->getIfaceInfo(s);
208 
209  if (iface_info->row_local_index == -1) {
210  id_to_local_indexes_to_set[iface_info->id].insert(&iface_info->row_local_index);
211  }
212  }
213  }
214  }
215  }
216  for (auto id_and_local_indexes : id_to_local_indexes_to_set) {
217  for (int* local_index_to_set : id_and_local_indexes.second) {
218  *local_index_to_set = curr_local_index;
219  }
220  curr_local_index++;
221  }
222  }
229  static void IndexRemainingPatchIfacesLocal(
230  int curr_local_index,
231  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos)
232  {
233  for (auto piinfo : piinfos) {
234  for (Side<D> s : Side<D>::getValues()) {
235  if (piinfo->pinfo.hasNbr(s)) {
236  auto iface_info = piinfo->getIfaceInfo(s);
237 
238  if (iface_info->patch_local_index == -1) {
239  iface_info->patch_local_index = curr_local_index;
240  curr_local_index++;
241  }
242  }
243  }
244  }
245  }
252  static void IndexIfacesGlobal(const std::vector<std::shared_ptr<Interface<D>>>& interfaces,
253  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos)
254  {
255  // get starting global index for this rank
256  int starting_global_index;
257  int num_local_interfaces = (int)interfaces.size();
258  MPI_Scan(&num_local_interfaces, &starting_global_index, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
259  starting_global_index -= num_local_interfaces;
260 
261  // index local interfaces first
262  for (auto iface : interfaces) {
263  iface->global_index = starting_global_index + iface->local_index;
264 
265  for (auto patch : iface->patches) {
266  if (patch.type.isNormal() || patch.type.isFineToFine() || patch.type.isCoarseToCoarse()) {
267  auto iface_info = patch.getNonConstPiinfo()->getIfaceInfo(patch.side);
268  iface_info->global_index = iface->global_index;
269  } else if (patch.type.isFineToCoarse()) {
270  auto iface_info = patch.getNonConstPiinfo()->getCoarseIfaceInfo(patch.side);
271  iface_info->coarse_global_index = iface->global_index;
272  } else if (patch.type.isCoarseToFine()) {
273  auto iface_info = patch.getNonConstPiinfo()->getFineIfaceInfo(patch.side);
274  for (size_t i = 0; i < iface_info->fine_col_local_indexes.size(); i++) {
275  if (iface_info->fine_ids[i] == iface->id) {
276  iface_info->fine_global_indexes[i] = iface->global_index;
277  break;
278  }
279  }
280  }
281  }
282  }
283  SendAndReceiveGlobalIndexes(interfaces, piinfos);
284  }
291  static void SendAndReceiveGlobalIndexes(
292  const std::vector<std::shared_ptr<Interface<D>>>& interfaces,
293  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos)
294  {
295  std::map<int, std::map<int, std::set<int*>>> rank_to_id_to_global_indexes_to_set;
296  std::deque<std::vector<int>> recv_buffers;
297  std::vector<MPI_Request> recv_requests;
298  SetupGlobalIndexRecvRequests(
299  interfaces, piinfos, rank_to_id_to_global_indexes_to_set, recv_buffers, recv_requests);
300 
301  std::deque<std::vector<int>> send_buffers;
302  std::vector<MPI_Request> send_requests;
303  SetupGlobalIndexSendRequests(interfaces, send_buffers, send_requests);
304 
305  size_t num_recvs = recv_requests.size();
306  for (size_t i = 0; i < num_recvs; i++) {
307  int index;
308  MPI_Status status;
309  MPI_Waitany(recv_requests.size(), recv_requests.data(), &index, &status);
310  const std::vector<int>& buffer = recv_buffers[index];
311  const auto& id_to_global_indexes_to_set =
312  rank_to_id_to_global_indexes_to_set[status.MPI_SOURCE];
313 
314  // set the global indexes
315  size_t curr_index = 0;
316  for (auto pair : id_to_global_indexes_to_set) {
317  for (int* global_index_to_set : pair.second) {
318  *global_index_to_set = buffer[curr_index];
319  }
320  curr_index++;
321  }
322  }
323 
324  MPI_Waitall((int)send_requests.size(), send_requests.data(), MPI_STATUSES_IGNORE);
325  }
337  static void SetupGlobalIndexRecvRequests(
338  const std::vector<std::shared_ptr<Interface<D>>>& interfaces,
339  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos,
340  std::map<int, std::map<int, std::set<int*>>>& rank_to_id_to_global_indexes_to_set,
341  std::deque<std::vector<int>>& recv_buffers,
342  std::vector<MPI_Request>& recv_requests)
343  {
344  GetGlobalIndexesToSet(interfaces, piinfos, rank_to_id_to_global_indexes_to_set);
345 
346  for (auto pair : rank_to_id_to_global_indexes_to_set) {
347  recv_buffers.emplace_back(pair.second.size());
348  MPI_Request request;
349  MPI_Irecv(recv_buffers.back().data(),
350  (int)recv_buffers.back().size(),
351  MPI_INT,
352  pair.first,
353  0,
354  MPI_COMM_WORLD,
355  &request);
356  recv_requests.push_back(request);
357  }
358  }
366  static void GetGlobalIndexesToSetForOuterInterfaces(
367  std::shared_ptr<PatchIfaceInfo<D>> piinfo,
368  std::map<int, std::map<int, std::set<int*>>>& rank_to_id_to_global_indexes_to_set)
369  {
370  for (Side<D> s : Side<D>::getValues()) {
371  if (piinfo->pinfo.hasNbr(s)) {
372  NbrType nbr_type = piinfo->pinfo.getNbrType(s);
373 
374  if (nbr_type == NbrType::Coarse) {
375  auto coarse_iface_info = piinfo->getCoarseIfaceInfo(s);
376  if (coarse_iface_info->coarse_global_index == -1) {
377  rank_to_id_to_global_indexes_to_set[coarse_iface_info->coarse_rank]
378  [coarse_iface_info->coarse_id]
379  .insert(&coarse_iface_info->coarse_global_index);
380  }
381  } else if (nbr_type == NbrType::Fine) {
382  auto fine_iface_info = piinfo->getFineIfaceInfo(s);
383  for (size_t i = 0; i < fine_iface_info->fine_global_indexes.size(); i++) {
384  if (fine_iface_info->fine_global_indexes[i] == -1) {
385  rank_to_id_to_global_indexes_to_set[fine_iface_info->fine_ranks[i]]
386  [fine_iface_info->fine_ids[i]]
387  .insert(
388  &fine_iface_info->fine_global_indexes[i]);
389  }
390  }
391  }
392  }
393  }
394  }
403  static void GetGlobalIndexesToSet(
404  const std::vector<std::shared_ptr<Interface<D>>>& interfaces,
405  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos,
406  std::map<int, std::map<int, std::set<int*>>>& rank_to_id_to_global_indexes_to_set)
407  {
408  // patch interfaces
409  GetGlobalIndexesToSetForPatchInterfaces(piinfos, rank_to_id_to_global_indexes_to_set);
410 
411  // rows and columns
412  for (auto iface : interfaces) {
413  for (auto patch : iface->patches) {
414  auto piinfo = patch.getNonConstPiinfo();
415 
416  // row
417  for (Side<D> s : Side<D>::getValues()) {
418  // the inner interfaces of this patch will affect this interface
419  if (piinfo->pinfo.hasNbr(s)) {
420  auto iface_info = piinfo->getIfaceInfo(s);
421 
422  if (iface_info->global_index == -1) {
423  rank_to_id_to_global_indexes_to_set[iface_info->rank][iface_info->id].insert(
424  &iface_info->global_index);
425  }
426  }
427  }
428  // column
429  if (patch.type.isNormal() || patch.type.isFineToFine() || patch.type.isCoarseToCoarse()) {
430  // this interface will affect the values of the outer interfaces
431  GetGlobalIndexesToSetForOuterInterfaces(piinfo, rank_to_id_to_global_indexes_to_set);
432  }
433  }
434  }
435  }
443  static void GetGlobalIndexesToSetForPatchInterfaces(
444  const std::vector<std::shared_ptr<PatchIfaceInfo<D>>>& piinfos,
445  std::map<int, std::map<int, std::set<int*>>>& rank_to_id_to_global_indexes_to_set)
446  {
447  for (auto piinfo : piinfos) {
448  for (Side<D> s : Side<D>::getValues()) {
449  if (piinfo->pinfo.hasNbr(s)) {
450  auto iface_info = piinfo->getIfaceInfo(s);
451 
452  if (iface_info->global_index == -1) {
453  rank_to_id_to_global_indexes_to_set[iface_info->rank][iface_info->id].insert(
454  &iface_info->global_index);
455  }
456  }
457  }
458  }
459  }
468  static void SetupGlobalIndexSendRequests(
469  const std::vector<std::shared_ptr<Interface<D>>>& interfaces,
470  std::deque<std::vector<int>>& send_buffers,
471  std::vector<MPI_Request>& send_requests)
472  {
473  std::map<int, std::set<std::pair<int, int>>> rank_to_id_and_global_index_pairs;
474  GetGlobalIndexesToSend(interfaces, rank_to_id_and_global_index_pairs);
475 
476  for (auto pair : rank_to_id_and_global_index_pairs) {
477  send_buffers.emplace_back();
478  std::vector<int>& send_buffer = send_buffers.back();
479  send_buffer.reserve(pair.second.size());
480 
481  for (auto id_global_index_pair : pair.second) {
482  send_buffer.push_back(id_global_index_pair.second);
483  }
484 
485  MPI_Request request;
486  MPI_Isend(send_buffer.data(),
487  (int)send_buffer.size(),
488  MPI_INT,
489  pair.first,
490  0,
491  MPI_COMM_WORLD,
492  &request);
493  send_requests.push_back(request);
494  }
495  }
503  static void GetGlobalIndexesToSend(
504  const std::vector<std::shared_ptr<Interface<D>>>& interfaces,
505  std::map<int, std::set<std::pair<int, int>>>& rank_to_id_and_global_index_pairs)
506  {
507  int rank;
508  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
509  for (auto iface : interfaces) {
510  for (auto patch : iface->patches) {
511  auto piinfo = patch.piinfo;
512  // patch interfaces
513  if (piinfo->pinfo.rank != rank) {
514  rank_to_id_and_global_index_pairs[piinfo->pinfo.rank].emplace(iface->id,
515  iface->global_index);
516  }
517  // cols
518  for (Side<D> s : Side<D>::getValues()) {
519  // the inner interfaces of this patch will affect this interface
520  if (piinfo->pinfo.hasNbr(s)) {
521  auto iface_info = piinfo->getIfaceInfo(s);
522 
523  if (iface_info->rank != rank) {
524  rank_to_id_and_global_index_pairs[iface_info->rank].emplace(iface->id,
525  iface->global_index);
526  }
527  }
528  }
529  // row
530  if (patch.type.isNormal() || patch.type.isCoarseToCoarse() || patch.type.isFineToFine()) {
531  // this interface will affect the values of the outer interfaces
532  GetGlobalIndexesToSendForOuterInterfaces(
533  iface, piinfo, rank_to_id_and_global_index_pairs);
534  }
535  }
536  }
537  }
546  static void GetGlobalIndexesToSendForOuterInterfaces(
547  std::shared_ptr<const Interface<D>> interface,
548  std::shared_ptr<const PatchIfaceInfo<D>> piinfo,
549  std::map<int, std::set<std::pair<int, int>>>& rank_to_id_and_global_index_pairs)
550  {
551  int rank;
552  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
553  for (Side<D> s : Side<D>::getValues()) {
554  if (piinfo->pinfo.hasNbr(s)) {
555  NbrType nbr_type = piinfo->pinfo.getNbrType(s);
556 
557  if (nbr_type == NbrType::Coarse) {
558  auto coarse_iface_info = piinfo->getCoarseIfaceInfo(s);
559  if (coarse_iface_info->coarse_rank != rank) {
560  rank_to_id_and_global_index_pairs[coarse_iface_info->coarse_rank].emplace(
561  interface->id, interface->global_index);
562  }
563  } else if (nbr_type == NbrType::Fine) {
564  auto fine_iface_info = piinfo->getFineIfaceInfo(s);
565  for (size_t i = 0; i < fine_iface_info->fine_col_local_indexes.size(); i++) {
566  if (fine_iface_info->fine_ranks[i] != rank) {
567  rank_to_id_and_global_index_pairs[fine_iface_info->fine_ranks[i]].emplace(
568  interface->id, interface->global_index);
569  }
570  }
571  }
572  }
573  }
574  }
575 
576 public:
577  InterfaceDomain() = default;
583  explicit InterfaceDomain(const Domain<D>& domain)
584  : domain(domain)
585  {
586  iface_ns.fill(domain.getNs()[0]);
587  int rank;
588  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
589 
590  std::vector<std::shared_ptr<PatchIfaceInfo<D>>> piinfos_non_const;
591  piinfos.reserve(domain.getNumLocalPatches());
592  piinfos_non_const.reserve(domain.getNumLocalPatches());
593  for (const PatchInfo<D>& pinfo : domain.getPatchInfoVector()) {
594  piinfos_non_const.emplace_back(new PatchIfaceInfo<D>(pinfo));
595  piinfos.push_back(piinfos_non_const.back());
596  }
597 
598  std::map<int, std::map<int, std::shared_ptr<Schur::Interface<D>>>> rank_id_iface_map;
599  std::vector<std::shared_ptr<Schur::PatchIfaceInfo<D>>> off_proc_piinfos;
600  Interface<D>::EnumerateIfacesFromPiinfoVector(piinfos, rank_id_iface_map, off_proc_piinfos);
601 
602  std::vector<std::shared_ptr<Schur::Interface<D>>> interfaces_non_const;
603  IndexIfacesLocal(rank_id_iface_map[rank], piinfos_non_const, interfaces_non_const);
604  IndexIfacesGlobal(interfaces_non_const, piinfos_non_const);
605 
606  interfaces.reserve(interfaces_non_const.size());
607  for (auto iface : interfaces_non_const) {
608  interfaces.push_back(iface);
609  }
610 
611  int num_ifaces = interfaces.size();
612  MPI_Allreduce(&num_ifaces, &num_global_ifaces, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
613  }
614 
620  int getNumLocalInterfaces() const { return interfaces.size(); }
626  int getNumGlobalInterfaces() const { return num_global_ifaces; }
636  const std::vector<std::shared_ptr<const Interface<D>>> getInterfaces() const
637  {
638  return interfaces;
639  }
649  const std::vector<std::shared_ptr<const PatchIfaceInfo<D>>>& getPatchIfaceInfos() const
650  {
651  return piinfos;
652  }
658  const Domain<D>& getDomain() const { return domain; }
659 
665  Vector<D - 1> getNewVector() const
666  {
667  return Vector<D - 1>(domain.getCommunicator(), iface_ns, 1, getNumLocalInterfaces(), 0);
668  }
669 };
670 extern template class InterfaceDomain<2>;
671 extern template class InterfaceDomain<3>;
672 } // namespace Schur
673 } // namespace ThunderEgg
674 #endif
ThunderEgg::Schur::InterfaceDomain::InterfaceDomain
InterfaceDomain(const Domain< D > &domain)
Create a InterfaceDomain from a given Domain.
Definition: InterfaceDomain.h:583
Vector.h
Vector class.
ThunderEgg::NbrType::Coarse
@ Coarse
The neighbor is at a coarser refinement level.
ThunderEgg::Domain::getNs
const std::array< int, D > & getNs() const
Get the number of cells in each direction.
Definition: Domain.h:264
ThunderEgg::Schur::InterfaceDomain::getNumLocalInterfaces
int getNumLocalInterfaces() const
Get the number of local Interfaces on this rank.
Definition: InterfaceDomain.h:620
ThunderEgg::Domain
Uses a collection of PatchInfo objects to represent the domain of the problem.
Definition: Domain.h:50
ThunderEgg::Domain::getNumLocalPatches
int getNumLocalPatches() const
Get the number of local patches.
Definition: Domain.h:272
ThunderEgg::Domain::getCommunicator
const Communicator & getCommunicator() const
Get the Communicator object associated with this domain.
Definition: Domain.h:254
ThunderEgg::NbrType
NbrType
The type of neighbor.
Definition: NbrType.h:34
ThunderEgg::Schur::InterfaceDomain::getInterfaces
const std::vector< std::shared_ptr< const Interface< D > > > getInterfaces() const
Get the vector Interfaces objects for this rank.
Definition: InterfaceDomain.h:636
ThunderEgg
The ThunderEgg namespace.
Definition: BiLinearGhostFiller.h:31
ThunderEgg::Schur::InterfaceDomain::getPatchIfaceInfos
const std::vector< std::shared_ptr< const PatchIfaceInfo< D > > > & getPatchIfaceInfos() const
Get the vector PatchIfaceInfo objects for this rank.
Definition: InterfaceDomain.h:649
ThunderEgg::PatchInfo
Contains metadata for a patch.
Definition: PatchInfo.h:51
ThunderEgg::NbrType::Fine
@ Fine
The nighbor is at a finer refinement level.
ThunderEgg::Schur::Interface::EnumerateIfacesFromPiinfoVector
static void EnumerateIfacesFromPiinfoVector(std::vector< std::shared_ptr< const PatchIfaceInfo< D >>> piinfos, std::map< int, std::map< int, std::shared_ptr< Interface< D >>>> &rank_id_iface_map, std::vector< std::shared_ptr< PatchIfaceInfo< D >>> &off_proc_piinfos)
Will enumerate a map from interface id to this rank's interfaces, will also do any neccesary communic...
Definition: Interface.h:317
ThunderEgg::Schur::InterfaceDomain::getDomain
const Domain< D > & getDomain() const
Get the Domain object that cooresponds to this InterfaceDomain.
Definition: InterfaceDomain.h:658
ThunderEgg::Vector
Vector class for use in thunderegg.
Definition: Vector.h:42
ThunderEgg::Domain::getPatchInfoVector
const std::vector< PatchInfo< D > > & getPatchInfoVector() const
Get a vector of PatchInfo pointers where index in the vector corresponds to the patch's local index.
Definition: Domain.h:259
ThunderEgg::Schur::InterfaceDomain::getNewVector
Vector< D - 1 > getNewVector() const
Get a new vector for the schur compliment system.
Definition: InterfaceDomain.h:665
ThunderEgg::Face
Enum-style class for the faces of an n-dimensional cube.
Definition: Face.h:41
ThunderEgg::Schur::InterfaceDomain::getNumGlobalInterfaces
int getNumGlobalInterfaces() const
Get the number of Interfaces on all ranks.
Definition: InterfaceDomain.h:626
Interface.h
Interface class.
PatchIfaceInfo.h
PatchIfaceInfo class.
ThunderEgg::Schur::InterfaceDomain
Represents the Schur compliment domain of the problem.
Definition: InterfaceDomain.h:55
ThunderEgg::Schur::Interface
This is a set of PatchIfaceInfo objects for an interface.
Definition: Interface.h:47
ThunderEgg::Schur::PatchIfaceInfo
This decorates a PatchInfo object with a IfaceInfo object for each side of the patch.
Definition: PatchIfaceInfo.h:40