Canoe
Comprehensive Atmosphere N' Ocean Engine
oxygen_cia.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <fstream>
3 #include <iostream>
4 #include <string>
5 
6 // canoe
7 #include <air_parcel.hpp>
8 #include <configure.hpp>
9 #include <constants.hpp>
10 
11 // climath
12 #include <climath/interpolation.h>
13 
14 // utils
15 #include <utils/vectorize.hpp>
16 
17 // opacity
18 #include "oxygen_cia.hpp"
19 
20 // netcdf
21 #ifdef NETCDFOUTPUT
22 extern "C" {
23 #include <netcdf.h>
24 }
25 #endif
26 
27 static int const n_fd_sets = 15;
28 static int const n_a1dg_x3sg00_sets = 1;
29 static int const n_a1dg_x3sg10_sets = 1;
30 static int const n_ab_sets = 1;
31 static int const n_other_sets = 1;
32 
33 void O2O2CIA::LoadCoefficient(std::string fname, size_t bid) {
34  std::string line;
35  std::ifstream file(fname);
36  double value;
37 
38  // Fundamental band
39  std::getline(file, line);
40  auto sline = Vectorize<std::string>(line.c_str());
41  int nwave = std::stoi(sline[3]), ntemp = n_fd_sets;
42 
43  fd_axis_.resize(ntemp + nwave);
44  fd_.resize(ntemp * nwave);
45 
46  for (int i = 0; i < ntemp; ++i) {
47  fd_axis_[i] = std::stod(sline[4]);
48  for (int j = 0; j < nwave; ++j) {
49  file >> value;
50  fd_axis_[ntemp + j] = value;
51  file >> value;
52  fd_[i * nwave + j] = std::max(value, 0.);
53  }
54  std::getline(file, line);
55  std::getline(file, line);
56  sline = Vectorize<std::string>(line.c_str());
57  }
58  fd_len_[0] = ntemp;
59  fd_len_[1] = nwave;
60 
61  // a1dg_x3sg00
62  nwave = std::stoi(sline[3]), ntemp = n_a1dg_x3sg00_sets;
63 
64  a1dg_x3sg00_axis_.resize(ntemp + nwave);
65  a1dg_x3sg00_.resize(ntemp * nwave);
66 
67  for (int i = 0; i < ntemp; ++i) {
68  a1dg_x3sg00_axis_[i] = std::stod(sline[4]);
69  for (int j = 0; j < nwave; ++j) {
70  file >> value;
71  a1dg_x3sg00_axis_[ntemp + j] = value;
72  file >> value;
73  a1dg_x3sg00_[i * nwave + j] = std::max(value, 0.);
74  }
75  std::getline(file, line);
76  std::getline(file, line);
77  sline = Vectorize<std::string>(line.c_str());
78  }
79  a1dg_x3sg00_len_[0] = ntemp;
80  a1dg_x3sg00_len_[1] = nwave;
81 
82  // a1dg_x3sg10
83  nwave = std::stoi(sline[3]), ntemp = n_a1dg_x3sg10_sets;
84 
85  a1dg_x3sg10_axis_.resize(ntemp + nwave);
86  a1dg_x3sg10_.resize(ntemp * nwave);
87 
88  for (int i = 0; i < ntemp; ++i) {
89  a1dg_x3sg10_axis_[i] = std::stod(sline[4]);
90  for (int j = 0; j < nwave; ++j) {
91  file >> value;
92  a1dg_x3sg10_axis_[ntemp + j] = value;
93  file >> value;
94  a1dg_x3sg10_[i * nwave + j] = std::max(value, 0.);
95  }
96  std::getline(file, line);
97  std::getline(file, line);
98  sline = Vectorize<std::string>(line.c_str());
99  }
100  a1dg_x3sg10_len_[0] = ntemp;
101  a1dg_x3sg10_len_[1] = nwave;
102 
103  // A band
104  nwave = std::stoi(sline[3]), ntemp = n_ab_sets;
105 
106  ab_axis_.resize(ntemp + nwave);
107  ab_.resize(ntemp * nwave);
108 
109  for (int i = 0; i < ntemp; ++i) {
110  ab_axis_[i] = std::stod(sline[4]);
111  for (int j = 0; j < nwave; ++j) {
112  file >> value;
113  ab_axis_[ntemp + j] = value;
114  file >> value;
115  ab_[i * nwave + j] = std::max(value, 0.);
116  file >> value;
117  }
118  std::getline(file, line);
119  std::getline(file, line);
120  sline = Vectorize<std::string>(line.c_str());
121  }
122  ab_len_[0] = ntemp;
123  ab_len_[1] = nwave;
124 
125  // other bands
126  nwave = std::stoi(sline[3]), ntemp = n_other_sets;
127 
128  other_axis_.resize(ntemp + nwave);
129  other_.resize(ntemp * nwave);
130 
131  for (int i = 0; i < ntemp; ++i) {
132  other_axis_[i] = std::stod(sline[4]);
133  for (int j = 0; j < nwave; ++j) {
134  file >> value;
135  other_axis_[ntemp + j] = value;
136  file >> value;
137  other_[i * nwave + j] = std::max(value, 0.);
138  file >> value;
139  }
140  std::getline(file, line);
141  std::getline(file, line);
142  sline = Vectorize<std::string>(line.c_str());
143  }
144  other_len_[0] = ntemp;
145  other_len_[1] = nwave;
146 }
147 
148 Real O2O2CIA::getAttenuation1(Real wave, AirParcel const& qfrac) const {
149  Real kk, temp = qfrac.w[IDN];
150 
151  Real coor[2] = {temp, wave};
152 
153  int iO2 = GetSpeciesIndex(0);
154 
155  if (wave >= 1150. && wave <= 1950.) {
156  interpnf(&kk, coor, fd_.data(), fd_axis_.data(), fd_len_, 2);
157  } else if (wave >= 7450. && wave <= 8487.)
158  interpnf(&kk, coor, a1dg_x3sg00_.data(), a1dg_x3sg00_axis_.data(),
159  a1dg_x3sg00_len_, 2);
160  else if (wave >= 9001. && wave <= 9997.)
161  interpnf(&kk, coor, a1dg_x3sg10_.data(), a1dg_x3sg10_axis_.data(),
162  a1dg_x3sg10_len_, 2);
163  else if (wave >= 12600. && wave <= 13839.)
164  interpnf(&kk, coor, ab_.data(), ab_axis_.data(), ab_len_, 2);
165  else if (wave >= 14996. && wave <= 29790.)
166  interpnf(&kk, coor, other_.data(), other_axis_.data(), other_len_, 2);
167  else
168  kk = 0.;
169 
170  Real num_o2 = qfrac.w[IPR] / (Constants::kBoltz * temp) * qfrac.w[iO2];
171 
172  // cm^5 molecule^{-2} * (molecule m^{-3})^2
173  return 1.E-10 * num_o2 * num_o2 * kk;
174 }
Real *const w
Definition: air_parcel.hpp:36
size_t a1dg_x3sg10_len_[2]
Definition: oxygen_cia.hpp:28
size_t fd_len_[2]
Definition: oxygen_cia.hpp:26
std::vector< Real > a1dg_x3sg00_
Definition: oxygen_cia.hpp:38
std::vector< Real > other_axis_
Definition: oxygen_cia.hpp:36
std::vector< Real > fd_
Definition: oxygen_cia.hpp:37
Real getAttenuation1(Real wave, AirParcel const &var) const
Definition: oxygen_cia.cpp:148
std::vector< Real > a1dg_x3sg10_
Definition: oxygen_cia.hpp:39
size_t other_len_[2]
Definition: oxygen_cia.hpp:30
void LoadCoefficient(std::string fname, size_t bid) override
Load absorption coefficient from file.
Definition: oxygen_cia.cpp:33
std::vector< Real > ab_axis_
Definition: oxygen_cia.hpp:35
std::vector< Real > a1dg_x3sg00_axis_
Definition: oxygen_cia.hpp:33
std::vector< Real > ab_
Definition: oxygen_cia.hpp:40
size_t a1dg_x3sg00_len_[2]
Definition: oxygen_cia.hpp:27
std::vector< Real > fd_axis_
Definition: oxygen_cia.hpp:32
std::vector< Real > other_
Definition: oxygen_cia.hpp:41
size_t ab_len_[2]
Definition: oxygen_cia.hpp:29
std::vector< Real > a1dg_x3sg10_axis_
Definition: oxygen_cia.hpp:34
int GetSpeciesIndex(int n) const
double max(double x1, double x2, double x3)
Definition: core.h:19
void interpnf(double *val, double const *coor, double const *data, double const *axis, size_t const *len, int ndim)
Definition: interpnf.c:13
double const kBoltz
Definition: constants.hpp:7
float temp
Definition: fit_ammonia.py:6
static int const n_ab_sets
Definition: oxygen_cia.cpp:30
static int const n_a1dg_x3sg00_sets
Definition: oxygen_cia.cpp:28
static int const n_a1dg_x3sg10_sets
Definition: oxygen_cia.cpp:29
static int const n_other_sets
Definition: oxygen_cia.cpp:31
static int const n_fd_sets
Definition: oxygen_cia.cpp:27