Canoe
Comprehensive Atmosphere N' Ocean Engine
diagnostics.cpp
Go to the documentation of this file.
1 // C/C++ headers
2 #include <cstring>
3 #include <sstream>
4 #include <stdexcept>
5 
6 // Athena++ headers
7 #include "../coordinates/coordinates.hpp"
8 #include "../debugger/debugger.hpp"
9 #include "../globals.hpp"
10 #include "../mesh/mesh.hpp"
11 #include "diagnostics.hpp"
12 
13 Diagnostics::Diagnostics(MeshBlock *pmb, ParameterInput *pin)
14  : myname("HEAD"),
15  type(""),
16  grid(""),
17  varname("HEAD"),
18  long_name(""),
19  units(""),
20  prev(nullptr),
21  next(nullptr),
22  ncycle(0),
23  pmy_block_(pmb) {
24  pmb->pdebug->Enter("Diagnostics List");
25  std::stringstream msg;
26  char cstr[80];
27  std::string diag_names = pin->GetOrAddString("problem", "diagnostics", "");
28  std::strcpy(cstr, diag_names.c_str());
29  char *p = std::strtok(cstr, " ,");
30  while (p != NULL) {
31  std::string name(p);
32  if (name == "div") { // 1.
34  } else if (name == "curl") // 2.
35  AddDiagnostics(Curl(pmb));
36  else if (name == "mean") // 3.
38  else if (name == "tempa") // 4.
40  else if (name == "presa") // 5.
42  else if (name == "eddyflux") // 6.
44  else if (name == "hydroflux") // 7.
46  else if (name == "div_h") // 8.
48  else if (name == "b") // 9.
50  else if (name == "radflux") // 10.
52  else if (name == "am") // 11.
54  else if (name == "eke") // 12.
56  else if (name == "tendency") // 13.
58  else {
59  msg << "### FATAL ERROR in function Diagnostics::Diagnostics" << std::endl
60  << "Diagnostic variable " << name << " not defined";
61  ATHENA_ERROR(msg);
62  }
63  // msg << "- add diagnostics " + name << std::endl;
64  p = std::strtok(NULL, " ,");
65  }
66 
67 #if MAIN_TASKLIST != InversionTaskList
68  if (NGHOST < 2) {
69  msg << "### FATAL ERROR in function Diagnostics::Diagnostics" << std::endl
70  << "Most diagnostic variables require at least 2 ghost cells";
71  ATHENA_ERROR(msg);
72  }
73 #endif
74 
75  // pmb->pdebug->WriteMessage(msg.str());
76  pmb->pdebug->Leave();
77 }
78 
79 Diagnostics::Diagnostics(MeshBlock *pmb, std::string name)
80  : myname(name),
81  varname(name),
82  prev(nullptr),
83  next(nullptr),
84  ncycle(0),
85  pmy_block_(pmb) {
86  pmb->pdebug->Enter("Diagnostics-" + name);
87  std::stringstream msg;
88  ncells1_ = pmb->block_size.nx1 + 2 * (NGHOST);
89  ncells2_ = 1;
90  ncells3_ = 1;
91  if (pmb->pmy_mesh->f2) ncells2_ = pmb->block_size.nx2 + 2 * (NGHOST);
92  if (pmb->pmy_mesh->f3) ncells3_ = pmb->block_size.nx3 + 2 * (NGHOST);
93 
94  x1edge_.NewAthenaArray(ncells1_ + 1);
95  x1edge_p1_.NewAthenaArray(ncells1_);
96  x2edge_.NewAthenaArray(ncells1_ + 1);
97  x2edge_p1_.NewAthenaArray(ncells1_);
98  x3edge_.NewAthenaArray(ncells1_ + 1);
99  x3edge_p1_.NewAthenaArray(ncells1_);
100 
101  x1area_.NewAthenaArray(ncells1_ + 1);
102  x2area_.NewAthenaArray(ncells1_);
103  x2area_p1_.NewAthenaArray(ncells1_);
104  x3area_.NewAthenaArray(ncells1_);
105  x3area_p1_.NewAthenaArray(ncells1_);
106 
107  vol_.NewAthenaArray(ncells1_);
108  total_vol_.NewAthenaArray(ncells1_);
109  brank_.resize(Globals::nranks);
110  color_.resize(Globals::nranks);
111 
112  for (int i = 0; i < Globals::nranks; ++i) {
113  brank_[i] = -1;
114  color_[i] = -1;
115  }
116 
117  pmb->pdebug->Leave();
118 }
119 
121  if (prev != nullptr) prev->next = next;
122  if (next != nullptr) next->prev = prev;
123 }
124 
126  Diagnostics *p = this;
127  while (p != nullptr) {
128  if (p->myname == name) return p;
129  p = p->next;
130  }
131  return p;
132 }
133 
134 void Diagnostics::setColor_(int *color, CoordinateDirection dir) {
135  MeshBlock *pmb = pmy_block_;
136  NeighborBlock bblock, tblock;
137  pmb->FindNeighbors(dir, bblock, tblock);
138 
139  if (dir == X1DIR) {
140  if (pmb->block_size.x1min <= pmb->pmy_mesh->mesh_size.x1min) {
141  bblock.snb.gid = -1;
142  bblock.snb.rank = -1;
143  }
144  if (pmb->block_size.x1max >= pmb->pmy_mesh->mesh_size.x1max) {
145  tblock.snb.gid = -1;
146  tblock.snb.rank = -1;
147  }
148  } else if (dir == X2DIR) {
149  if (pmb->block_size.x2min <= pmb->pmy_mesh->mesh_size.x2min) {
150  bblock.snb.gid = -1;
151  bblock.snb.rank = -1;
152  }
153  if (pmb->block_size.x2max >= pmb->pmy_mesh->mesh_size.x2max) {
154  tblock.snb.gid = -1;
155  tblock.snb.rank = -1;
156  }
157  } else { // X3DIR
158  if (pmb->block_size.x3min <= pmb->pmy_mesh->mesh_size.x3min) {
159  bblock.snb.gid = -1;
160  bblock.snb.rank = -1;
161  }
162  if (pmb->block_size.x3max >= pmb->pmy_mesh->mesh_size.x3max) {
163  tblock.snb.gid = -1;
164  tblock.snb.rank = -1;
165  }
166  }
167 
168 #ifdef MPI_PARALLEL
169  MPI_Allgather(&bblock.snb.rank, 1, MPI_INT, brank_.data(), 1, MPI_INT,
170  MPI_COMM_WORLD);
171 #else
172  brank_[0] = -1;
173 #endif
174 
175  int c = 0;
176  for (int i = 0; i < Globals::nranks; ++i) {
177  // color[i] = brank_[i] == -1 ? color[i] : color[brank_[i]];
178  if (brank_[i] == -1) {
179  if (color[i] == -1) color[i] = c++;
180  } else
181  color[i] = color[brank_[i]];
182  }
183 }
184 
186  AthenaArray<Real> &total_data) {
187  MeshBlock *pmb = pmy_block_;
188 
189  // calculate total volume
190  total_vol.ZeroClear();
191  for (int k = pmb->ks; k <= pmb->ke; ++k)
192  for (int j = pmb->js; j <= pmb->je; ++j) {
193  pmb->pcoord->CellVolume(k, j, pmb->is, pmb->ie, vol_);
194  for (int i = pmb->is; i <= pmb->ie; ++i) total_vol(i) += vol_(i);
195  }
196 
197  // sum over all ranks
198 #ifdef MPI_PARALLEL
199  MPI_Comm comm;
200  std::fill(color_.data(), color_.data() + Globals::nranks, -1);
201  setColor_(color_.data(), X2DIR);
202  setColor_(color_.data(), X3DIR);
203  MPI_Comm_split(MPI_COMM_WORLD, color_[Globals::my_rank], Globals::my_rank,
204  &comm);
205  // int size;
206  // MPI_Comm_size(comm, &size);
207  // std::cout << size << std::endl;
208  MPI_Allreduce(MPI_IN_PLACE, total_vol.data(), total_vol.GetSize(),
209  MPI_ATHENA_REAL, MPI_SUM, comm);
210  MPI_Allreduce(MPI_IN_PLACE, total_data.data(), total_data.GetSize(),
211  MPI_ATHENA_REAL, MPI_SUM, comm);
212  MPI_Comm_free(&comm);
213 #endif
214 }
void gatherAllData23_(AthenaArray< Real > &total_vol, AthenaArray< Real > &total_data)
AthenaArray< Real > x2area_p1_
Definition: diagnostics.hpp:56
AthenaArray< Real > x3edge_p1_
Definition: diagnostics.hpp:59
AthenaArray< Real > vol_
Definition: diagnostics.hpp:56
void setColor_(int *color, CoordinateDirection dir)
std::vector< int > color_
MPI color of each rank.
Definition: diagnostics.hpp:51
AthenaArray< Real > x2edge_p1_
Definition: diagnostics.hpp:58
AthenaArray< Real > x3area_
Definition: diagnostics.hpp:56
Diagnostics(MeshBlock *pmb, ParameterInput *pin)
Definition: diagnostics.cpp:13
Diagnostics * next
Definition: diagnostics.hpp:18
AthenaArray< Real > x1area_
scratch geometric arrays
Definition: diagnostics.hpp:56
Diagnostics * AddDiagnostics(Dg const &d)
Definition: diagnostics.hpp:30
AthenaArray< Real > x1edge_
Definition: diagnostics.hpp:58
Diagnostics * prev
Definition: diagnostics.hpp:18
virtual ~Diagnostics()
std::vector< int > brank_
rank of the bottom block
Definition: diagnostics.hpp:53
AthenaArray< Real > x2edge_
Definition: diagnostics.hpp:58
AthenaArray< Real > x3edge_
Definition: diagnostics.hpp:58
AthenaArray< Real > x1edge_p1_
Definition: diagnostics.hpp:58
AthenaArray< Real > x2area_
Definition: diagnostics.hpp:56
AthenaArray< Real > x3area_p1_
Definition: diagnostics.hpp:56
Diagnostics * operator[](std::string name)
MeshBlock * pmy_block_
Definition: diagnostics.hpp:44
AthenaArray< Real > total_vol_
Definition: diagnostics.hpp:57