Canoe
Comprehensive Atmosphere N' Ocean Engine
linear_exchanger.hpp
Go to the documentation of this file.
1 #ifndef SRC_EXCHANGER_LINEAR_EXCHANGER_HPP_
2 #define SRC_EXCHANGER_LINEAR_EXCHANGER_HPP_
3 
4 // athena
5 #include <athena/globals.hpp>
6 #include <athena/mesh/mesh.hpp>
7 
8 // canoe
9 #include "common.hpp"
10 
11 // exchanger
12 #include "exchanger.hpp"
13 
14 #ifdef MPI_PARALLEL
15 #include <mpi.h>
16 #endif // MPI_PARALLEL
17 
18 template <typename T>
20  color_.resize(Globals::nranks);
21  brank_.resize(Globals::nranks);
22 }
23 
24 template <typename T>
26  int r = 0;
27  int b = brank_[Globals::my_rank];
28  while (b != -1) {
29  r++;
30  b = brank_[b];
31  }
32  return r;
33 }
34 
35 template <typename T>
36 void LinearExchanger<T>::Regroup(MeshBlock const *pmb,
37  CoordinateDirection dir) {
38  NeighborBlock bblock, tblock;
39  ExchangerHelper::find_neighbors(pmb, dir, &bblock, &tblock);
40 
41  if (dir == X1DIR) {
42  if (pmb->block_size.x1min <= pmb->pmy_mesh->mesh_size.x1min) {
43  bblock.snb.gid = -1;
44  bblock.snb.rank = -1;
45  }
46  if (pmb->block_size.x1max >= pmb->pmy_mesh->mesh_size.x1max) {
47  tblock.snb.gid = -1;
48  tblock.snb.rank = -1;
49  }
50  } else if (dir == X2DIR) {
51  if (pmb->block_size.x2min <= pmb->pmy_mesh->mesh_size.x2min) {
52  bblock.snb.gid = -1;
53  bblock.snb.rank = -1;
54  }
55  if (pmb->block_size.x2max >= pmb->pmy_mesh->mesh_size.x2max) {
56  tblock.snb.gid = -1;
57  tblock.snb.rank = -1;
58  }
59  } else { // X3DIR
60  if (pmb->block_size.x3min <= pmb->pmy_mesh->mesh_size.x3min) {
61  bblock.snb.gid = -1;
62  bblock.snb.rank = -1;
63  }
64  if (pmb->block_size.x3max >= pmb->pmy_mesh->mesh_size.x3max) {
65  tblock.snb.gid = -1;
66  tblock.snb.rank = -1;
67  }
68  }
69 
70 #ifdef MPI_PARALLEL
71  MPI_Allgather(&bblock.snb.rank, 1, MPI_INT, brank_.data(), 1, MPI_INT,
72  MPI_COMM_WORLD);
73 #else
74  brank_[0] = -1;
75 #endif
76 
77  std::fill(color_.begin(), color_.end(), -1);
78  int c = 0;
79  for (int i = 0; i < Globals::nranks; ++i) {
80  // color[i] = brank_[i] == -1 ? color[i] : color[brank_[i]];
81  if (brank_[i] == -1) {
82  if (color_[i] == -1) color_[i] = c++;
83  } else
84  color_[i] = color_[brank_[i]];
85  }
86 
87 #ifdef MPI_PARALLEL
88  if (mpi_comm_ != MPI_COMM_WORLD) {
89  MPI_Comm_free(&mpi_comm_);
90  }
91 
92  MPI_Comm_split(MPI_COMM_WORLD, color_[Globals::my_rank], Globals::my_rank,
93  &mpi_comm_);
94 #endif
95 }
96 
97 #endif // SRC_EXCHANGER_LINEAR_EXCHANGER_HPP_
int GetRankInGroup() const
void Regroup(MeshBlock const *pmb, CoordinateDirection dir)
void find_neighbors(MeshBlock const *pmb, CoordinateDirection dir, NeighborBlock *bblock, NeighborBlock *tblock)
find neighbors in one coordinate direction
Definition: exchanger.cpp:80