Canoe
Comprehensive Atmosphere N' Ocean Engine
exchanger.hpp
Go to the documentation of this file.
1 #ifndef SRC_EXCHANGER_EXCHANGER_HPP_
2 #define SRC_EXCHANGER_EXCHANGER_HPP_
3 
4 // Athena++
5 #include <athena/mesh/mesh.hpp>
6 
7 // canoe
8 #include <configure.hpp>
9 #include <impl.hpp>
10 
11 // exchanger
12 #include "message_traits.hpp"
13 
14 class NeighborBlock;
15 class MeshBlock;
16 
18  public: // constructor and destructor
20 #ifdef MPI_PARALLEL
21  mpi_comm_ = MPI_COMM_WORLD;
22 #endif
23  }
24  virtual ~ExchangerBase() {}
25 
27  virtual void PackData(MeshBlock const *pmb) {}
28 
30  virtual bool UnpackData(MeshBlock const *pmb) { return true; }
31 
33  virtual void Transfer(MeshBlock const *pmb, int n = -1) = 0;
34 
35  protected:
36 #ifdef MPI_PARALLEL
37  MPI_Comm mpi_comm_;
38 #endif
39 };
40 
41 template <typename T>
42 class Exchanger : public ExchangerBase {
43  public: // constructor and destructor
45  using BufferType = std::vector<DataType>;
46 #ifdef MPI_PARALLEL
47  using ExchangerBase::mpi_comm_;
48 #endif
49 
51  for (int n = 0; n < MessageTraits<T>::num_buffers; ++n) {
52 #ifdef MPI_PARALLEL
53  req_mpi_send_[n] = MPI_REQUEST_NULL;
54  req_mpi_recv_[n] = MPI_REQUEST_NULL;
55 #endif // MPI_PARALLEL
56  }
57  }
58 
59  virtual ~Exchanger() {
60  for (int n = 0; n < MessageTraits<T>::num_buffers; ++n) {
61 #ifdef MPI_PARALLEL
62  req_mpi_send_[n] = MPI_REQUEST_NULL;
63  req_mpi_recv_[n] = MPI_REQUEST_NULL;
64 
65  if (mpi_comm_ != MPI_COMM_WORLD) {
66  MPI_Comm_free(&mpi_comm_);
67  }
68 #endif // MPI_PARALLEL
69  }
70  }
71 
73  virtual void ClearBuffer(MeshBlock const *pmb) {
74  for (int n = 0; n < MessageTraits<T>::num_buffers; ++n) {
75 #ifdef MPI_PARALLEL
76  MPI_Wait(&req_mpi_send_[n], MPI_STATUS_IGNORE);
77 #endif // MPI_PARALLEL
78  }
79  }
80 
82  void SetBoundaryStatus(int bid, BoundaryStatus status) {
83  status_flag_[bid] = status;
84  }
85 
86  protected:
87  enum BoundaryStatus status_flag_[MessageTraits<T>::num_buffers];
90 
91 #ifdef MPI_PARALLEL
92  MPI_Request req_mpi_send_[MessageTraits<T>::num_buffers];
93  MPI_Request req_mpi_recv_[MessageTraits<T>::num_buffers];
94 #endif // MPI_PARALLEL
95 };
96 
97 namespace ExchangerHelper {
98 
100 NeighborBlock const *find_bot_neighbor(MeshBlock const *pmb);
101 
103 NeighborBlock const *find_top_neighbor(MeshBlock const *pmb);
104 
106 NeighborBlock const *find_left_neighbor(MeshBlock const *pmb);
107 
109 NeighborBlock const *find_right_neighbor(MeshBlock const *pmb);
110 
112 NeighborBlock const *find_back_neighbor(MeshBlock const *pmb);
113 
115 NeighborBlock const *find_front_neighbor(MeshBlock const *pmb);
116 
118 void find_neighbors(MeshBlock const *pmb, CoordinateDirection dir,
119  NeighborBlock *bblock, NeighborBlock *tblock);
120 } // namespace ExchangerHelper
121 
122 template <typename T>
123 class NeighborExchanger : public Exchanger<T> {
124  public:
128 #ifdef MPI_PARALLEL
129  using Base::mpi_comm_;
130  using Base::req_mpi_recv_;
131  using Base::req_mpi_send_;
132 #endif // MPI_PARALLEL
133 
135 
137  void Transfer(MeshBlock const *pmb, int n = -1) override;
138 
140  void ClearBuffer(MeshBlock const *pmb) override;
141 };
142 
143 template <typename T>
144 class LinearExchanger : public Exchanger<T> {
145  public: // constructor and destructor
147 #ifdef MPI_PARALLEL
148  using Base::mpi_comm_;
149 #endif // MPI_PARALLEL
150 
151  LinearExchanger();
152 
153  public: // member functions
154  int GetRankInGroup() const;
155  void Regroup(MeshBlock const *pmb, CoordinateDirection dir);
156 
157  private:
159  std::vector<int> color_;
160 
162  std::vector<int> brank_;
163 };
164 
165 template <typename T>
166 class PlanarExchanger : public Exchanger<T> {
167  public:
169 };
170 
171 #endif // SRC_EXCHANGER_EXCHANGER_HPP_
virtual void Transfer(MeshBlock const *pmb, int n=-1)=0
Send and receive data.
virtual void PackData(MeshBlock const *pmb)
Pack data to send buffer.
Definition: exchanger.hpp:27
virtual bool UnpackData(MeshBlock const *pmb)
Unpack data from receive buffer.
Definition: exchanger.hpp:30
virtual ~ExchangerBase()
Definition: exchanger.hpp:24
virtual ~Exchanger()
Definition: exchanger.hpp:59
typename MessageTraits< T >::DataType DataType
Definition: exchanger.hpp:44
std::vector< DataType > BufferType
Definition: exchanger.hpp:45
BufferType recv_buffer_[MessageTraits< T >::num_buffers]
Definition: exchanger.hpp:89
void SetBoundaryStatus(int bid, BoundaryStatus status)
Set the boundary status.
Definition: exchanger.hpp:82
enum BoundaryStatus status_flag_[MessageTraits< T >::num_buffers]
Definition: exchanger.hpp:87
virtual void ClearBuffer(MeshBlock const *pmb)
Clear buffer.
Definition: exchanger.hpp:73
BufferType send_buffer_[MessageTraits< T >::num_buffers]
Definition: exchanger.hpp:88
std::vector< int > color_
MPI color of each block.
Definition: exchanger.hpp:159
std::vector< int > brank_
MPI rank of the bottom of each block.
Definition: exchanger.hpp:162
int GetRankInGroup() const
void Regroup(MeshBlock const *pmb, CoordinateDirection dir)
void ClearBuffer(MeshBlock const *pmb) override
Clear buffer.
void Transfer(MeshBlock const *pmb, int n=-1) override
Send and receive data.
NeighborBlock const * find_back_neighbor(MeshBlock const *pmb)
find back neighbor block
Definition: exchanger.cpp:56
NeighborBlock const * find_left_neighbor(MeshBlock const *pmb)
find left neighbor block
Definition: exchanger.cpp:32
NeighborBlock const * find_front_neighbor(MeshBlock const *pmb)
find front neighbor block
Definition: exchanger.cpp:68
NeighborBlock const * find_bot_neighbor(MeshBlock const *pmb)
find bottom neighbor block
Definition: exchanger.cpp:10
NeighborBlock const * find_top_neighbor(MeshBlock const *pmb)
find top neighbor block
Definition: exchanger.cpp:21
NeighborBlock const * find_right_neighbor(MeshBlock const *pmb)
find right neighbor block
Definition: exchanger.cpp:44
void find_neighbors(MeshBlock const *pmb, CoordinateDirection dir, NeighborBlock *bblock, NeighborBlock *tblock)
find neighbors in one coordinate direction
Definition: exchanger.cpp:80
Traits class providing Message information for class T.