Canoe
Comprehensive Atmosphere N' Ocean Engine
celestrial_body.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <sstream>
3 #include <stdexcept>
4 
5 // application
6 #include <application/application.hpp>
7 
8 // athena
9 #include <athena/athena.hpp>
10 #include <athena/parameter_input.hpp>
11 
12 // climath
13 #include <climath/core.h>
14 #include <climath/interpolation.h>
15 
16 // utils
17 #include <utils/fileio.hpp>
18 
19 // canoe
20 #include <common.hpp>
21 
22 // astro
23 #include "celestrial_body.hpp"
24 
25 void CelestrialBody::readCelestrialData(ParameterInput *pin,
26  std::string myname) {
27  char entry[80];
28  snprintf(entry, sizeof(entry), "%s.re", name.c_str());
29  re = km2m(pin->GetOrAddReal("astronomy", entry, 0.));
30 
31  snprintf(entry, sizeof(entry), "%s.rp", name.c_str());
32  rp = km2m(pin->GetOrAddReal("astronomy", entry, re));
33 
34  snprintf(entry, sizeof(entry), "%s.obliq", name.c_str());
35  obliq = deg2rad(pin->GetOrAddReal("astronomy", entry, 0.));
36 
37  snprintf(entry, sizeof(entry), "%s.spinp", name.c_str());
38  spinp = day2sec(pin->GetOrAddReal("astronomy", entry, 0.));
39 
40  snprintf(entry, sizeof(entry), "%s.orbit_a", name.c_str());
41  orbit_a = au2m(pin->GetOrAddReal("astronomy", entry, 0.));
42 
43  snprintf(entry, sizeof(entry), "%s.orbit_e", name.c_str());
44  orbit_e = pin->GetOrAddReal("astronomy", entry, 0.);
45 
46  snprintf(entry, sizeof(entry), "%s.orbit_i", name.c_str());
47  orbit_i = deg2rad(pin->GetOrAddReal("astronomy", entry, 0.));
48 
49  snprintf(entry, sizeof(entry), "%s.orbit_p", name.c_str());
50  orbit_p = day2sec(pin->GetOrAddReal("astronomy", entry, 0.));
51 
52  snprintf(entry, sizeof(entry), "%s.equinox", name.c_str());
53  equinox = pin->GetOrAddReal("astronomy", entry, 0.);
54 
55  snprintf(entry, sizeof(entry), "%s.grav_eq", name.c_str());
56  grav_eq = pin->GetOrAddReal("astronomy", entry, 0.);
57 }
58 
59 CelestrialBody::CelestrialBody(ParameterInput *pin)
60  : parent(nullptr), spec_(nullptr), il_(-1) {
61  Application::Logger app("astro");
62  app->Log("Initialize CelestrialBody");
63 
64  std::stringstream msg;
65  name = pin->GetOrAddString("astronomy", "planet", "unknown");
67 
68  if (pin->DoesParameterExist("astronomy", name + ".parent")) {
69  std::string parent_name = pin->GetString("astronomy", name + ".parent");
70  parent = new CelestrialBody(pin, parent_name);
71  } else {
72  parent = nullptr;
73  }
74 
75  if (pin->DoesParameterExist("astronomy", name + ".spec_file")) {
76  std::string sfile = pin->GetString("astronomy", name + ".spec_file");
77  if (!FileExists(sfile)) {
78  app->Error("Cannot open spectral file " + sfile);
79  } else {
80  ReadSpectraFile(sfile);
81  }
82  } else {
83  spec_ = new float_triplet[1];
84  nspec_ = 1;
85  }
86 }
87 
88 CelestrialBody::CelestrialBody(ParameterInput *pin, std::string myname)
89  : parent(nullptr), name(myname), spec_(nullptr), il_(-1) {
90  Application::Logger app("astro");
91  app->Log("Initialize CelestrialBody");
92 
93  std::stringstream msg;
95 
96  if (pin->DoesParameterExist("astronomy", name + ".parent")) {
97  std::string parent_name = pin->GetString("astronomy", name + ".parent");
98  parent = new CelestrialBody(pin, parent_name);
99  } else {
100  parent = nullptr;
101  }
102 
103  if (pin->DoesParameterExist("astronomy", name + ".spec_file")) {
104  std::string sfile = pin->GetString("astronomy", name + ".spec_file");
105  if (!FileExists(sfile)) {
106  app->Error("Cannot open spectral file " + sfile);
107  } else {
108  ReadSpectraFile(sfile);
109  }
110  } else {
111  spec_ = new float_triplet[1];
112  nspec_ = 1;
113  }
114 }
115 
117  Application::Logger app("astro");
118  app->Log("Destroy CelestrialBody");
119 
120  if (parent != nullptr) delete parent;
121  delete[] spec_;
122 }
123 
124 void CelestrialBody::ReadSpectraFile(std::string sfile) {
125  AthenaArray<Real> spectrum;
126  ReadDataTable(&spectrum, sfile);
127 
128  nspec_ = spectrum.GetDim2();
129 
130  if (spec_ != nullptr) delete[] spec_;
131  spec_ = new float_triplet[nspec_];
132  for (int i = 0; i < nspec_; ++i) {
133  spec_[i].x = spectrum(i, 0);
134  spec_[i].y = spectrum(i, 1);
135  }
136 
137  spline(nspec_, spec_, 0., 0.);
138 }
139 
140 Direction CelestrialBody::ParentZenithAngle(Real time, Real colat, Real lon) {
141  Direction dir;
142 
143  Real lat = M_PI / 2. - colat;
144  if (spinp == 0. && orbit_p == 0.) dir.mu = cos(-lon + M_PI) * cos(lat);
145  if (spinp == 0. && orbit_p != 0.)
146  dir.mu = cos((time * 2. * M_PI * (-1. / orbit_p)) - lon + M_PI) * cos(lat);
147  if (spinp != 0. && orbit_p == 0.)
148  dir.mu = cos((time * 2. * M_PI * (1. / spinp)) - lon + M_PI) * cos(lat);
149  if (spinp != 0. && orbit_p != 0.)
150  dir.mu =
151  cos((time * 2. * M_PI * (1. / spinp - 1. / orbit_p)) - lon + M_PI) *
152  cos(lat);
153  dir.phi = 0.;
154 
155  return dir;
156 }
157 
158 Real CelestrialBody::ParentInsolationFlux(Real wav, Real dist_au) {
159  Real dx;
160  // assuming ascending in wav
161  if ((il_ >= 0) && (wav < parent->spec_[il_].x)) il_ = -1;
163  Real flux = splint(wav, parent->spec_ + il_, dx);
164  return flux / (dist_au * dist_au);
165 }
166 
167 Real CelestrialBody::ParentInsolationFlux(Real wlo, Real whi, Real dist_au) {
169  if (wlo == whi) return ParentInsolationFlux(wlo, dist_au);
170  // assuming ascending in wav
171  Real dx;
172  int il = find_place_in_table(parent->nspec_, parent->spec_, wlo, &dx, -1);
173  int iu = find_place_in_table(parent->nspec_, parent->spec_, whi, &dx, il);
174  Real flux = 0.5 * parent->spec_[il].y;
175  for (int i = il; i < iu; ++i) {
176  flux += 0.5 * (parent->spec_[i].y + parent->spec_[i + 1].y) *
177  (parent->spec_[i + 1].x - parent->spec_[i].x);
178  }
179  return flux / (dist_au * dist_au);
180 }
181 
183  Real orbit_b = sqrt(1. - orbit_e * orbit_e) * orbit_a;
184  Real orbit_c = orbit_b * orbit_b / orbit_a;
185  return m2au(orbit_c / (1. + orbit_e * cos(2. * M_PI / orbit_p * time -
186  equinox - M_PI / 2.)));
187 }
float_triplet * spec_
Real ParentInsolationFlux(Real wav, Real dist_au)
Real ParentDistanceInAu(Real time)
void ReadSpectraFile(std::string sfile)
CelestrialBody * parent
void readCelestrialData(ParameterInput *pin, std::string myname)
Direction ParentZenithAngle(Real time, Real colat, Real lon)
std::string name
CelestrialBody(ParameterInput *pin)
double deg2rad(double phi)
Definition: core.h:41
double day2sec(double x)
Definition: core.h:46
double km2m(double x)
Definition: core.h:43
double au2m(double x)
Definition: core.h:49
double m2au(double x)
Definition: core.h:50
bool FileExists(std::string fname)
test file existance
Definition: fileio.cpp:16
void ReadDataTable(AthenaArray< Real > *data, std::string fname, char c=' ')
int find_place_in_table(int n, struct float_triplet *table, double x, double *dx, int il)
double splint(double xx, struct float_triplet *table, double dx)
Definition: spline.c:152
void spline(int n, struct float_triplet *table, double y1_bot, double y1_top)
Definition: spline.c:21
Real mu
Definition: common.hpp:5
Real phi
Definition: common.hpp:5
double y
Definition: core.h:11
double x
Definition: core.h:11