Canoe
Comprehensive Atmosphere N' Ocean Engine
angular_momentum.cpp
Go to the documentation of this file.
1 
11 // C/C++ header
12 #include <cstring>
13 #include <sstream>
14 #include <stdexcept>
15 // MPI headers
16 #ifdef MPI_PARALLEL
17 #include <mpi.h>
18 #endif
19 
20 // Athena++ header
21 #include "../coordinates/coordinates.hpp"
22 #include "../math/core.h"
23 #include "diagnostics.hpp"
24 
25 AngularMomentum::AngularMomentum(MeshBlock *pmb) : Diagnostics(pmb, "am") {
26  type = "VECTORS";
27  grid = "---";
28  long_name =
29  "mass,moment of inertia relative to a thin spherical shell,mean angular "
30  "velocity";
31  units = "kg,1,1/s";
32  data.NewAthenaArray(3, 1, 1, 1);
33  if (strcmp(COORDINATE_SYSTEM, "spherical_polar") != 0) {
34  std::stringstream msg;
35  msg << "### FATAL ERROR in AngularMomentum::AngularMomentum" << std::endl
36  << "Diagnostics 'am' can only be used in spherical_polar geometry."
37  << std::endl;
38  ATHENA_ERROR(msg);
39  }
40 }
41 
43  MeshBlock *pmb = pmy_block_;
44  Coordinates *pcoord = pmb->pcoord;
45  int is = pmb->is, js = pmb->js, ks = pmb->ks;
46  int ie = pmb->ie, je = pmb->je, ke = pmb->ke;
47 
48  Real mass_moi_am[3];
49  mass_moi_am[0] = 0.;
50  mass_moi_am[1] = 0.;
51  mass_moi_am[2] = 0.;
52 
53  Real xmin = pmb->pmy_mesh->mesh_size.x1min;
54  Real xmax = pmb->pmy_mesh->mesh_size.x1max;
55  Real mean_radius = (xmin + xmax) / 2.;
56 
57  for (int k = ks; k <= ke; ++k)
58  for (int j = js; j <= je; ++j) {
59  pcoord->CellVolume(k, j, is, ie, vol_);
60  for (int i = is; i <= ie; ++i) {
61  // mass
62  mass_moi_am[0] += vol_(i) * w(IDN, k, j, i);
63  // moment of inertia
64  mass_moi_am[1] += vol_(i) * w(IDN, k, j, i) *
65  sqr(pcoord->x1v(i) * sin(pcoord->x2v(j)));
66  // angular momentum
67  mass_moi_am[2] += vol_(i) * w(IDN, k, j, i) * pcoord->x1v(i) *
68  sin(pcoord->x2v(j)) * w(IV3, k, j, i);
69  }
70  }
71 
72  // sum over all ranks
73 #ifdef MPI_PARALLEL
74  MPI_Allreduce(MPI_IN_PLACE, mass_moi_am, 3, MPI_ATHENA_REAL, MPI_SUM,
75  MPI_COMM_WORLD);
76 #endif
77  data(0) = mass_moi_am[0];
78  data(1) =
79  mass_moi_am[1] / (2. / 3. * mass_moi_am[0] * mean_radius * mean_radius);
80  if (mass_moi_am[1] != 0) data(2) = mass_moi_am[2] / mass_moi_am[1];
81 }
void Finalize(AthenaArray< Real > const &w)
AngularMomentum(MeshBlock *pmb)
std::string units
Definition: diagnostics.hpp:17
AthenaArray< Real > vol_
Definition: diagnostics.hpp:56
std::string long_name
Definition: diagnostics.hpp:17
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
double sqr(double x)
Definition: core.h:14