Canoe
Comprehensive Atmosphere N' Ocean Engine
radiation_utils.cpp
Go to the documentation of this file.
1 // C++
2 #include <algorithm>
3 #include <fstream>
4 #include <iomanip>
5 #include <iostream>
6 #include <sstream>
7 #include <vector>
8 
9 // canoe
10 #include <configure.hpp>
11 
12 // climath
13 #include <climath/core.h>
14 
15 // utils
16 #include <utils/vectorize.hpp>
17 
18 // harp
19 #include "radiation_utils.hpp"
20 
21 /*void Radiation::TotalFlux(AthenaArray<Real>& flux) const
22 {
23  // count how many bands
24  int b = 0;
25  int max_ntau = 0;
26  Radiation const *p = this;
27  while (p != NULL) {
28  max_ntau = std::max(max_ntau, p->ntau);
29  p = p->next;
30  b++;
31  }
32 
33  // check dimension consistancy, reallocate memory if necessary
34  if (flux.GetDim1() != b && flux.GetDim2() < max_ntau) {
35  flux.DeleteAthenaArray();
36  flux.NewAthenaArray(max_ntau, b);
37  }
38 
39  b = 0;
40  p = this;
41  while (p != NULL) {
42  for (int j = 0; j < p->ntau; ++j)
43  flux(j,b) = 0.;
44  for (int i = 0; i < p->nwave; ++i)
45  for (int j = 0; j < p->ntau; ++j)
46  // flup - rfldn - rfldir
47  flux(j,b) += p->weight_[i]*(p->rad(i,j,2) - p->rad(i,j,1) -
48 p->rad(i,j,0)); p = p->next; b++;
49  }
50 }
51 
52 void Radiation::SumTotalFlux(AthenaArray<Real>& tflux, AthenaArray<Real>&
53 disort_flux, int gk, int gj) const
54 {
55  // count how many bands
56  int b = 0;
57  int max_ntau = 0;
58  Radiation const *p = this;
59  while (p != NULL) {
60  max_ntau = std::max(max_ntau, p->ntau);
61  p = p->next;
62  b++;
63  }
64  AthenaArray<Real> flux;
65  flux.NewAthenaArray(max_ntau, b);
66  b = 0;
67  p = this;
68  while (p != NULL) {
69  for (int j = 0; j < p->ntau; ++j)
70  flux(j,b) = 0.;
71  for (int j = 0; j < p->ntau+2*(NGHOST); ++j){
72  disort_flux(0,gk,gj,j) = 0.;
73  disort_flux(1,gk,gj,j) = 0.;
74  disort_flux(2,gk,gj,j) = 0.;
75  }
76  for (int i = 0; i < p->nwave; ++i)
77  for (int j = 0; j < p->ntau; ++j){
78  // flup - rfldn - rfldir
79  disort_flux(0,gk,gj,j+NGHOST) += p->weight_[i]*p->rad(i,j,2);
80  disort_flux(1,gk,gj,j+NGHOST) += p->weight_[i]*p->rad(i,j,1);
81  disort_flux(2,gk,gj,j+NGHOST) += p->weight_[i]*p->rad(i,j,0);
82  flux(j,b) += p->weight_[i]*(p->rad(i,j,2) - p->rad(i,j,1) -
83 p->rad(i,j,0));
84  }
85  p = p->next;
86  b++;
87  }
88 
89  // sum; thl
90  for (int j =0; j < max_ntau; ++j){
91  tflux(j) = 0.;
92  }
93  for (int j =0; j <max_ntau; ++j)
94  for (int bb =0; bb <b; ++bb){
95  tflux(j) += flux(max_ntau-j-1,bb);
96  }
97 }
98 
99 void Radiation::WriteTopFlux(std::string fname) const
100 {
101  std::cout << "Top flux written into file: " << fname << std::endl;
102  std::ofstream out(fname.c_str(), std::ios::out);
103  out << std::left << std::setw(20) << std::setprecision(8) << "#
104 Wavenumber(cm-1)"
105  << std::left << std::setw(20) << "Top rfldir[]"
106  << std::left << std::setw(20) << "Top rfldn[]"
107  << std::left << std::setw(20) << "Top flup[]"
108  << std::endl;
109 
110  Radiation const *p = this;
111  while (p != NULL) {
112  for (int i = 0; i < p->nwave; ++i)
113  out << std::left << std::setw(20) << p->wave[i]
114  << std::left << std::setw(20) << p->rad(i,0,0)
115  << std::left << std::setw(20) << p->rad(i,0,1)
116  << std::left << std::setw(20) << p->rad(i,0,2)
117  << std::endl;
118  p = p->next;
119  }
120 }
121 
122 void Radiation::WriteOpticalDepth(std::string fname) const
123 {
124  std::cout << "Optical depth written into file: " << fname << std::endl;
125  std::ofstream out(fname.c_str(), std::ios::out);
126 
127  Radiation const *p = this;
128  while (p != NULL) {
129  out << std::left << "# Band: " << p->myname << std::endl;
130  out << std::setw(40) << "# Number of wavenumbers : " << p->nwave <<
131 std::endl; out << std::setw(40) << "# Number of levels: " << p->nlevel <<
132 std::endl; out << std::right; for (int i = 0; i < p->nlevel; ++i) out <<
133 std::setw(16) << std::setprecision(8) << p->level[i]/1.E3; out << std::endl;
134 
135  for (int i = 0; i < p->nwave; ++i) {
136  out << std::setw(16) << std::setprecision(8) << p->wave[i];
137  for (int j = 0; j < p->nlevel - 1; ++j)
138  out << std::setw(16) << std::setprecision(8) << p->tau(ITAU,i,j);
139  out << std::endl;
140  }
141  p = p->next;
142  }
143 }
144 
145 void Radiation::WriteTopRadiance(std::string fname) const
146 {
147  std::cout << "Top radiance written into file: " << fname << std::endl;
148  std::ofstream out(fname.c_str(), std::ios::out);
149  out << std::left << std::setw(20) << std::setprecision(8)
150  << "# Wavenumber/Frequency" << std::endl;
151 
152  Radiation const *p = this;
153  while (p != NULL) {
154  for (int i = 0; i < p->nwave; ++i) {
155  out << std::left << std::setw(20) << p->wave[i];
156  for (int j = 0; j < p->nphi; ++j)
157  for (int k = 0; k < p->numu; ++k)
158  out << std::left << std::setw(20) << p->uu(i,j,0,k);
159  out << std::endl;
160  }
161  p = p->next;
162  }
163 }
164 
165 void WriteHeatingRate(std::string fname, AthenaArray<Real> const& flux,
166  AthenaArray<Real> const& hrate, Real const* level)
167 {
168  int nband = flux.GetDim1();
169  int nlevel = flux.GetDim2();
170 
171  // print mean intensity, flux divergence and heating rate
172  std::cout << "Heating rate written into file: " << fname << std::endl;
173  std::ofstream out(fname.c_str(), std::ios::out);
174  out << std::left << std::setw(6) << "Level"
175  << std::left << std::setw(12) << "Height [km]";
176 
177  for (int b = 0; b < nband; ++b) {
178  char bname[80];
179  sprintf(bname, "B%d flux [w/m^2]", b + 1);
180  out << std::left << std::setw(16) << bname
181  << std::left << std::setw(20) << "Heating rate [w/kg]";
182  }
183 
184  if (nband > 1) {
185  out << std::left << std::setw(16) << "Flux [w/m^2]"
186  << std::left << std::setw(20) << "Heating rate [w/kg]"
187  << std::endl;
188  } else {
189  out << std::endl;
190  }
191 
192  for (int i = 0; i < nlevel; ++i) {
193  out << std::left << std::setw(6) << i + 1
194  << std::left << std::setw(12) << level[i]/1.E3;
195 
196  Real total_flux = 0., total_hrate = 0.;
197  for (int b = 0; b < nband; ++b) {
198  out << std::left << std::setw(16) << std::setprecision(8) << flux(i,b)
199  << std::left << std::setw(20) << std::setprecision(8) << hrate(i,b);
200  total_flux += flux(i,b);
201  total_hrate += hrate(i,b);
202  }
203 
204  if (nband > 1) {
205  out << std::left << std::setw(16) << std::setprecision(8) << total_flux
206  << std::left << std::setw(20) << std::setprecision(8) << total_hrate
207  << std::endl;
208  } else {
209  out << std::endl;
210  }
211  }
212 }*/
213 
214 void set_radiation_flags(uint64_t *flags, std::string str) {
215  std::stringstream msg;
216  std::vector<std::string> dstr = Vectorize<std::string>(str.c_str(), " ,");
217  for (int i = 0; i < dstr.size(); ++i) {
218  if (dstr[i] == "static") {
219  *flags &= !RadiationFlags::Dynamic;
220  } else if (dstr[i] == "dynamic") {
221  *flags |= RadiationFlags::Dynamic;
222  } else if (dstr[i] == "bin") {
223  *flags &= !RadiationFlags::LineByLine;
224  } else if (dstr[i] == "lbl") {
225  *flags |= RadiationFlags::LineByLine;
226  } else if (dstr[i] == "ck") {
227  *flags |= RadiationFlags::CorrelatedK;
228  } else if (dstr[i] == "planck") {
229  *flags |= RadiationFlags::Planck;
230  } else if (dstr[i] == "star") {
231  *flags |= RadiationFlags::Star;
232  } else if (dstr[i] == "spher") {
233  *flags |= RadiationFlags::Sphere;
234  } else if (dstr[i] == "only") {
235  *flags |= RadiationFlags::FluxOnly;
236  } else if (dstr[i] == "normalize") {
237  *flags |= RadiationFlags::Normalize;
238  } else if (dstr[i] == "write_bin_radiance") {
240  } else {
241  msg << "### FATAL ERROR in function setRadiatino" << std::endl
242  << "flag:" << dstr[i] << "unrecognized" << std::endl;
243  ATHENA_ERROR(msg);
244  }
245 
246  // check flags consistency
247  if ((*flags & RadiationFlags::LineByLine) &&
248  (*flags & RadiationFlags::CorrelatedK)) {
249  msg << "### FATAL ERROR in function setRadiation" << std::endl
250  << "ck cannot be used with lbl." << std::endl;
251  }
252  }
253 }
254 
255 void get_phase_momentum(Real *pmom, int iphas, Real gg, int npmom) {
256  pmom[0] = 1.;
257  for (int k = 1; k < npmom; k++) pmom[k] = 0.;
258 
259  switch (iphas) {
260  case 0: // HENYEY_GREENSTEIN
261  if (gg <= -1. || gg >= 1.)
262  std::cout << "getmom--bad input variable gg" << std::endl;
263  for (int k = 1; k <= npmom; k++) pmom[k] = pow(gg, (Real)k);
264  break;
265 
266  case 1: // RAYLEIGH
267  pmom[2] = 0.1;
268  break;
269  }
270 }
271 
272 void packSpectralProperties(Real *buf, Real const *tau, Real const *ssa,
273  Real const *pmom, int nlayer, int npmom) {
274  for (int i = 0; i < nlayer; ++i) *(buf++) = tau[i];
275  for (int i = 0; i < nlayer; ++i) *(buf++) = ssa[i];
276  for (int i = 0; i < nlayer; ++i)
277  for (int j = 0; j < npmom; ++j) *(buf++) = pmom[i * npmom + j];
278 }
279 
280 void unpackSpectralProperties(Real *tau, Real *ssa, Real *pmom, Real const *buf,
281  int slyr, int npmom, int nblocks, int npmom_max) {
282  npmom_max = std::max(npmom_max, npmom);
283  for (int n = 0; n < nblocks; ++n) {
284  for (int i = 0; i < slyr; ++i) tau[n * slyr + i] = *(buf++);
285  for (int i = 0; i < slyr; ++i) ssa[n * slyr + i] = *(buf++);
286  for (int i = 0; i < slyr; ++i) {
287  for (int j = 0; j < npmom; ++j)
288  pmom[n * slyr * npmom_max + i * npmom_max + j] = *(buf++);
289  for (int j = npmom; j < npmom_max; ++j)
290  pmom[n * slyr * npmom_max + i * npmom_max + j] = 0.;
291  }
292  }
293 }
294 
295 void read_radiation_directions(std::vector<Direction> *ray, std::string str) {
296  std::vector<std::string> dstr = Vectorize<std::string>(str.c_str());
297  int nray = dstr.size();
298  ray->resize(nray);
299 
300  auto jt = dstr.begin();
301  for (auto it = ray->begin(); it != ray->end(); ++it, ++jt) {
302  it->phi = 0.;
303  sscanf(jt->c_str(), "(%lf,%lf)", &it->mu, &it->phi);
304  it->mu = cos(deg2rad(it->mu));
305  it->phi = deg2rad(it->phi);
306  }
307 }
double deg2rad(double phi)
Definition: core.h:41
double max(double x1, double x2, double x3)
Definition: core.h:19
const uint64_t Sphere
Definition: radiation.hpp:29
const uint64_t Dynamic
Definition: radiation.hpp:24
const uint64_t WriteBinRadiance
Definition: radiation.hpp:32
const uint64_t Star
Definition: radiation.hpp:28
const uint64_t LineByLine
Definition: radiation.hpp:25
const uint64_t FluxOnly
Definition: radiation.hpp:30
const uint64_t Normalize
Definition: radiation.hpp:31
const uint64_t Planck
Definition: radiation.hpp:27
const uint64_t CorrelatedK
Definition: radiation.hpp:26
void get_phase_momentum(Real *pmom, int iphas, Real gg, int npmom)
void set_radiation_flags(uint64_t *flags, std::string str)
void packSpectralProperties(Real *buf, Real const *tau, Real const *ssa, Real const *pmom, int nlayer, int npmom)
void unpackSpectralProperties(Real *tau, Real *ssa, Real *pmom, Real const *buf, int slyr, int npmom, int nblocks, int npmom_max)
void read_radiation_directions(std::vector< Direction > *ray, std::string str)