Canoe
Comprehensive Atmosphere N' Ocean Engine
eddy_flux.cpp
Go to the documentation of this file.
1 // C/C++ headers
2 // MPI headers
3 #ifdef MPI_PARALLEL
4 #include <mpi.h>
5 #endif
6 
7 #include "../coordinates/coordinates.hpp"
8 #include "../reconstruct/interpolation.hpp"
9 #include "../thermodynamics/thermodynamics.hpp"
10 #include "diagnostics.hpp"
11 
12 EddyFlux::EddyFlux(MeshBlock *pmb) : Diagnostics(pmb, "eddyflux") {
13  type = "VECTORS";
14  grid = "--C";
15  long_name = "Z-coordinate eddy flux";
16  eddy_.NewAthenaArray(NHYDRO, ncells3_, ncells2_, ncells1_);
17  mean_.NewAthenaArray(NHYDRO, ncells3_, ncells2_, ncells1_);
18  data.NewAthenaArray(2 * NHYDRO, 1, 1, ncells1_);
19 }
20 
22  eddy_.DeleteAthenaArray();
23  mean_.DeleteAthenaArray();
24  data.DeleteAthenaArray();
25 }
26 
28  MeshBlock *pmb = pmy_block_;
29  Coordinates *pcoord = pmb->pcoord;
30  Thermodynamics *pthermo = pmb->pthermo;
31 
32  int is = pmb->is, js = pmb->js, ks = pmb->ks;
33  int ie = pmb->ie, je = pmb->je, ke = pmb->ke;
34 
35  Real *data_sum = new Real[(NHYDRO + 1) * ncells1_];
36  std::fill(data_sum, data_sum + (NHYDRO + 1) * ncells1_, 0.);
37 
38  // calculate horizontal mean
39  for (int k = ks; k <= ke; ++k)
40  for (int j = js; j <= je; ++j) {
41  pcoord->CellVolume(k, j, is, ie, vol_);
42  for (int i = is; i <= ie; ++i) {
43  for (int n = 0; n < IPR; ++n)
44  data_sum[n * ncells1_ + i] += vol_(i) * w(n, k, j, i);
45  data_sum[IPR * ncells1_ + i] +=
46  vol_(i) * pthermo->GetTemp(w.at(k, j, i));
47  data_sum[NHYDRO * ncells1_ + i] += vol_(i);
48  }
49  }
50 
51 #ifdef MPI_PARALLEL
52  // sum over all ranks
53  MPI_Allreduce(MPI_IN_PLACE, data_sum, (NHYDRO + 1) * ncells1_,
54  MPI_ATHENA_REAL, MPI_SUM, MPI_COMM_WORLD);
55 #endif
56 
57  // calculate eddy term
58  for (int k = ks; k <= ke; ++k)
59  for (int j = js; j <= je; ++j)
60  for (int i = is; i <= ie; ++i) {
61  Real vol = data_sum[NHYDRO * ncells1_ + i];
62  for (int n = 0; n < IPR; ++n) {
63  mean_(n, k, j, i) = data_sum[n * ncells1_ + i] / vol;
64  eddy_(n, k, j, i) = w(n, k, j, i) - mean_(n, k, j, i);
65  }
66  mean_(IPR, k, j, i) = data_sum[IPR * ncells1_ + i] / vol;
67  eddy_(IPR, k, j, i) =
68  pthermo->GetTemp(w.at(k, j, i)) - mean_(IPR, k, j, i);
69  }
70 
71  // take horizontal average
72  if (ncycle == 0) std::fill(data.data(), data.data() + data.GetSize(), 0.);
73 
74  for (int n = 0; n < NHYDRO; ++n)
75  for (int k = ks; k <= ke; ++k)
76  for (int j = js; j <= je; ++j) {
77  pcoord->CellVolume(k, j, is, ie, vol_);
78  for (int i = is; i <= ie; ++i) {
79  data(n, i) += eddy_(n, k, j, i) * eddy_(IVX, k, j, i) * vol_(i);
80  data(n + NHYDRO, i) +=
81  mean_(n, k, j, i) * mean_(IVX, k, j, i) * vol_(i);
82  }
83  }
84 
85  ncycle++;
86  delete[] data_sum;
87 }
88 
90  MeshBlock *pmb = pmy_block_;
91 
92  int is = pmb->is, js = pmb->js, ks = pmb->ks;
93  int ie = pmb->ie, je = pmb->je, ke = pmb->ke;
94 
95  Real *total_vol = new Real[ncells1_];
96  std::fill(total_vol, total_vol + ncells1_, 0.);
97 
98  // calculate total volume
99  for (int k = ks; k <= ke; ++k)
100  for (int j = js; j <= je; ++j) {
101  pmb->pcoord->CellVolume(k, j, is, ie, vol_);
102  for (int i = is; i <= ie; ++i) total_vol[i] += vol_(i);
103  }
104 
105  // take time and spatial average
106  if (ncycle > 0) {
107  // sum over all ranks
108 #ifdef MPI_PARALLEL
109  MPI_Allreduce(MPI_IN_PLACE, data.data(), data.GetSize(), MPI_ATHENA_REAL,
110  MPI_SUM, MPI_COMM_WORLD);
111  MPI_Allreduce(MPI_IN_PLACE, total_vol, ncells1_, MPI_ATHENA_REAL, MPI_SUM,
112  MPI_COMM_WORLD);
113 #endif
114  for (int n = 0; n < 2 * NHYDRO; ++n)
115  for (int i = is; i <= ie; ++i) data(n, i) /= ncycle * total_vol[i];
116  }
117 
118  // clear cycle;
119  delete[] total_vol;
120  ncycle = 0;
121 }
AthenaArray< Real > mean_
mean and eddy component
Definition: diagnostics.hpp:48
AthenaArray< Real > vol_
Definition: diagnostics.hpp:56
std::string long_name
Definition: diagnostics.hpp:17
AthenaArray< Real > eddy_
Definition: diagnostics.hpp:48
std::string type
Definition: diagnostics.hpp:16
AthenaArray< Real > data
Definition: diagnostics.hpp:19
MeshBlock * pmy_block_
Definition: diagnostics.hpp:44
std::string grid
Definition: diagnostics.hpp:16
void Finalize(AthenaArray< Real > const &w)
Definition: eddy_flux.cpp:89
void Progress(AthenaArray< Real > const &w)
Definition: eddy_flux.cpp:27
virtual ~EddyFlux()
Definition: eddy_flux.cpp:21
EddyFlux(MeshBlock *pmb)
Definition: eddy_flux.cpp:12
Real GetTemp(MeshBlock const *pmb, int k, int j, int i) const
Calculate temperature from primitive variable.