Canoe
Comprehensive Atmosphere N' Ocean Engine
absorption_function_ph3.cpp
Go to the documentation of this file.
1 /**************************************************************************
2 
3  ===== JUNO codes =====
4 
5  Copyright (C) 2019 California Institute of Technology (Caltech)
6  All rights reserved.
7 
8  Written by Fabiano Oyafuso (fabiano@jpl.nasa.gov)
9  Adapted by Cheng Li (cli@gps.caltech.edu) to SNAP structure
10 
11 **************************************************************************/
12 
13 // C/C++ headers
14 #include <cmath>
15 
16 // ph3 data headers
17 #include "mwr_absorber_ph3.hpp"
18 
19 // cli, 190801
20 inline double SQUARE(double x) { return x * x; }
21 inline double atm_from_bar(double P) { return 0.9869232667160128 * P; }
22 static double const pi = 3.14159265358979;
23 // end
24 
25 double absorption_coefficient_PH3_radtran(double freq, double P, double T,
26  double XH2, double XHe, double XPH3) {
27  double dtaua = 0.0;
28 
29  double const PPH3 = atm_from_bar(P * XPH3);
30  double const PH2 = atm_from_bar(P * XH2);
31  double const PHe = atm_from_bar(P * XHe);
32 
33  // this flag controls whether to use the ad-hoc correction to the
34  // PH3 absorption coefficients: (TBD!)
35 
36  bool iph3cor = true;
37 
38  double const hc_over_kTref = 4.7959e-3;
39 
40  // sum the contributions of all lines:
41  double const acon = 2.452e11; // gives a in cm^-1
42  double const fcon = 1.e-9 / 3.14159; // old notes: 1.e12 ??
43  double const texp = 3.5;
44 
45  for (int i = 0; i < NLINE_PH3; i++) {
46  double frq0 = ph3_lines[i].FREQ * 1e-3;
47  double intens = pow(10, ph3_lines[i].LGINT);
48  double elow = ph3_lines[i].ELO;
49 
50  double tx = 300.0 / T;
51  double fx = freq / frq0;
52  double delnu = 1.419 * (PPH3 * 4.2154 + PH2 * 3.29283 + PHe * 1.6807);
53 
54  // don't use this form, for now:
55  // double fline = fcon*fx*(delnu/(pow((freq-frq0),2)+ pow(delnu,2)) +
56  // delnu/(pow((freq+frq0),2) + pow(delnu,2)))
57 
58  double df = freq - frq0;
59  double fline = fcon * fx * (delnu / (df * df + delnu * delnu));
60 
61  double tx35 = tx * tx * tx *
62  sqrt(tx); // was pow(tx,texp), but gnu pow() is very slow
63  double boltzf = exp(hc_over_kTref * elow * (1.0 - tx));
64  dtaua += acon * PPH3 * intens * tx35 * boltzf * fx * fline;
65  }
66 
67  if (iph3cor) dtaua *= 35.386 * pow(freq, -0.7969);
68 
69  return dtaua; // in cm^-1
70 }
71 
72 double absorption_coefficient_PH3_Hoffman(double freq, double P, double T,
73  double XH2, double XHe, double XPH3) {
74  double const factor =
75  241.43; // bar/P_cgs * 1/kb_cgs * (cm/nm)^2 / (300K) * (GHz/MHz)
76 
77  double dtaua = 0.0;
78 
79  double const PPH3 = P * XPH3;
80  double const PH2 = P * XH2;
81  double const PHe = P * XHe;
82 
83  double const hc_over_kTref = 4.7959e-3;
84 
85  // sum the contributions of all lines:
86  for (int i = 0; i < NLINE_PH3; i++) {
87  double frq0 = ph3_lines[i].FREQ * 1e-3;
88  double intens = pow(10, ph3_lines[i].LGINT);
89  double elow = ph3_lines[i].ELO;
90 
91  double tx = 300.0 / T;
92 
93  double gamma_H2, gamma_He, gamma_PH3;
94  if (i < 40 && (std::abs(ph3_lines[i].QNp[1]) == 6 ||
95  (std::abs(ph3_lines[i].QNp[1]) == 3 &&
96  std::abs(ph3_lines[i].QNp[0]) < 8))) {
97  intens *= 2.78;
98  gamma_H2 = 1.4121;
99  gamma_He = 0.7205;
100  gamma_PH3 = 0.4976;
101  // cout << "3x correction: " << i << " " << frq0 << endl;
102  } else if (i < 40 &&
103  (std::abs(ph3_lines[i].QNp[1]) == 3 &&
104  std::abs(ph3_lines[i].QNp[0]) >= 8) &&
105  std::abs(ph3_lines[i].QNp[0]) <= 26) {
106  intens *= 36.65;
107  gamma_H2 = 0.5978;
108  gamma_He = 0.3050;
109  gamma_PH3 = 3.1723;
110  // cout << "37x correction: " << i << " " << frq0 << endl;
111  } else {
112  gamma_H2 = 3.2930;
113  gamma_He = 1.6803;
114  gamma_PH3 = 4.2157;
115  }
116 
117  double fx = freq / frq0;
118  double delnu = PPH3 * gamma_PH3 * tx +
119  pow(tx, 0.75) * (PH2 * gamma_H2 + PHe * gamma_He);
120 
121  double delnu_sq = SQUARE(delnu);
122  double fline = fx / pi * delnu *
123  (1.0 / (SQUARE(freq - frq0) + delnu_sq) +
124  1.0 / (SQUARE(freq + frq0) + delnu_sq));
125 
126  double tx35 = tx * tx * tx * sqrt(tx); // tx^3.5
127  double boltzf = exp(hc_over_kTref * elow * (1.0 - tx));
128 
129  dtaua += factor * PPH3 * intens * tx35 * boltzf * fx * fline;
130  }
131 
132  return dtaua; // in cm^-1
133 }
double atm_from_bar(double P)
static double const pi
double absorption_coefficient_PH3_Hoffman(double freq, double P, double T, double XH2, double XHe, double XPH3)
double SQUARE(double x)
double absorption_coefficient_PH3_radtran(double freq, double P, double T, double XH2, double XHe, double XPH3)
constexpr int NLINE_PH3
static PH3LineList ph3_lines[]