Canoe
Comprehensive Atmosphere N' Ocean Engine
attenuation_cia.cpp
Go to the documentation of this file.
1 // C/C++ headers
2 #include <cmath>
3 
4 // CIA data headers
5 #include "mwr_absorber_cia.hpp"
6 
7 // cli, 190801
8 inline double SQUARE(double x) { return x * x; }
9 inline double Pa_from_bar(double P) { return 1.0e5 * P; }
10 static double const kBoltz_mks = 1.3806504e-23; // J/K
11 static double const Lo_mks =
12  2.68719e25; // Loschmidt number molecules/m^3 at STP
13 static double const c_cgs = 2.99792458e+10; // speed of light
14 // end
15 
16 double attenuation_CIA(double freq, double P, double T, double XH2, double XHe,
17  double XCH4, double mix) {
18  double const factor = Pa_from_bar(P) / (kBoltz_mks * T) / Lo_mks;
19  double const amagat_he = XHe * factor;
20  double const amagat_h2 = XH2 * factor;
21  double const amagat_ch4 = XCH4 * factor;
22 
23  double nu_invcm = freq * 1e9 / c_cgs;
24  double logT = log(T);
25  int Inu0 = CIA_Orton::find_index_wavenumber(nu_invcm);
26  int It0 = CIA_Orton::find_index_temp(logT);
27 
28  // if we are below Orton's spectral range, assume a nu^2 dependence
29  double nu_scale = 1.0;
30  if (Inu0 < 0) {
31  Inu0 = 0;
32  nu_scale = SQUARE(nu_invcm / CIA_Orton::wn[0]);
33  }
34 
35  // mix = 0 (equilibrium), 1 (normal, high temp)
36  double h2h2, h2he, h2ch4;
37  if (mix == 0.0) {
38  h2h2 = amagat_h2 * amagat_h2 *
39  exp(CIA_Orton::CIA_H2_H2_e(It0, Inu0, nu_invcm, logT));
40  h2he = amagat_h2 * amagat_he *
41  exp(CIA_Orton::CIA_H2_He_e(It0, Inu0, nu_invcm, logT));
42  h2ch4 = amagat_h2 * amagat_ch4 *
43  exp(CIA_Orton::CIA_H2_CH4_e(It0, Inu0, nu_invcm, logT));
44  } else if (mix == 1.0) {
45  h2h2 = amagat_h2 * amagat_h2 *
46  exp(CIA_Orton::CIA_H2_H2_n(It0, Inu0, nu_invcm, logT));
47  h2he = amagat_h2 * amagat_he *
48  exp(CIA_Orton::CIA_H2_He_n(It0, Inu0, nu_invcm, logT));
49  h2ch4 = amagat_h2 * amagat_ch4 *
50  exp(CIA_Orton::CIA_H2_CH4_n(It0, Inu0, nu_invcm, logT));
51  } else {
52  h2h2 = amagat_h2 * amagat_h2 *
53  (mix * exp(CIA_Orton::CIA_H2_H2_e(It0, Inu0, nu_invcm, logT)) +
54  (1 - mix) * exp(CIA_Orton::CIA_H2_H2_n(It0, Inu0, nu_invcm, logT)));
55  h2he = amagat_h2 * amagat_he *
56  (mix * exp(CIA_Orton::CIA_H2_He_e(It0, Inu0, nu_invcm, logT)) +
57  (1 - mix) * exp(CIA_Orton::CIA_H2_He_n(It0, Inu0, nu_invcm, logT)));
58  h2ch4 =
59  amagat_h2 * amagat_ch4 *
60  (mix * exp(CIA_Orton::CIA_H2_CH4_e(It0, Inu0, nu_invcm, logT)) +
61  (1 - mix) * exp(CIA_Orton::CIA_H2_CH4_n(It0, Inu0, nu_invcm, logT)));
62  }
63 
64  if (nu_scale != 1.0) {
65  h2h2 *= nu_scale;
66  h2he *= nu_scale;
67  h2ch4 *= nu_scale;
68  }
69 
70  return h2h2 + h2he + h2ch4;
71 }
static double const Lo_mks
double Pa_from_bar(double P)
static double const kBoltz_mks
static double const c_cgs
double SQUARE(double x)
double attenuation_CIA(double freq, double P, double T, double XH2, double XHe, double XCH4, double mix)
static double CIA_H2_He_e(int It0, int Inu0, double nu, double logT0)
static double CIA_H2_CH4_n(int It0, int Inu0, double nu, double logT0)
static double CIA_H2_CH4_e(int It0, int Inu0, double nu, double logT0)
static double CIA_H2_H2_e(int It0, int Inu0, double nu, double logT0)
static double CIA_H2_He_n(int It0, int Inu0, double nu, double logT0)
static int find_index_temp(double logT0)
static const double wn[]
static double CIA_H2_H2_n(int It0, int Inu0, double nu, double logT0)
static int find_index_wavenumber(double nu)