Canoe
Comprehensive Atmosphere N' Ocean Engine
hydrogen_thermo.cpp
Go to the documentation of this file.
1 
9 #include <cmath>
10 #include <cstdlib>
11 #include <sstream>
12 #include <stdexcept>
13 
14 #include "molecules.hpp"
15 
16 #define SQUARE(V) (V * V)
17 #define JMAX 20
18 
19 static double const h_cgs = 6.62606957e-27; // Planck constant
20 static double const c_cgs = 2.99792458e+10; // speed of light
21 static double const kBoltz_cgs = 1.3806504e-16; // erg/K
22 static double const FACT_cgs = h_cgs * c_cgs / kBoltz_cgs;
23 static double const R_cgs =
24  8.314462e+07; // universal gas constant in erg/K/mole
25 
26 double Hydrogen::FJ_[JMAX];
27 double Hydrogen::DJ_[JMAX];
28 double Hydrogen::nist_shomate1_[7] = {33.066178, -11.363417, 11.432816,
29  -2.772874, -0.158558, -9.980797,
30  172.707974};
31 double Hydrogen::nist_shomate2_[7] = {18.563083, 12.257357, -2.859786, 0.268238,
32  1.977990, -1.147438, 156.288133};
33 double Hydrogen::nist_shomate3_[7] = {43.413560, -4.293079, 1.272428,
34  -0.096876, -20.533862, -38.515158,
35  162.081354};
36 
38  double B0 = 59.322, D0 = 4.71e-02;
39 
40  for (int J = 0; J < JMAX; J++) {
41  DJ_[J] = ((J / 2) * 2 == J) ? 2 * J + 1 : 3 * (2 * J + 1);
42  FJ_[J] = B0 * J * (J + 1.) - D0 * SQUARE(J * (J + 1.));
43  }
44 }
45 
46 double Hydrogen::fpara_equil(double T) {
47  // compute partition functions
48  double Zpara = 0, Zortho = 0;
49 
50  for (size_t J = 0; J < JMAX; J += 2)
51  Zpara += DJ_[J] * exp(-FJ_[J] * FACT_cgs / T);
52 
53  for (size_t J = 1; J < JMAX; J += 2)
54  Zortho += DJ_[J] * exp(-FJ_[J] * FACT_cgs / T);
55 
56  return Zpara / (Zpara + Zortho);
57 }
58 
59 void Hydrogen::get_cp_(double *cp_para, double *cp_equil, double *cp_norm,
60  double *cp_ortho, double T) {
61  double FORTH = 0.75;
62  double FPARA = 0.25;
63 
64  double ZEQ = 0.0;
65  double SEQ1 = 0.0;
66  double SEQ2 = 0.0;
67 
68  double ZORTHO = 0.0;
69  double SO1 = 0.0;
70  double SO2 = 0.0;
71 
72  double ZPARA = 0.0;
73  double SP1 = 0.0;
74  double SP2 = 0.0;
75 
76  for (int JQ = 9; JQ >= 0; JQ--) {
77  double X = (FACT_cgs / T) * FJ_[JQ];
78  double P = DJ_[JQ] * exp(-X);
79 
80  ZEQ += P;
81  SEQ1 += DJ_[JQ] * SQUARE(X) * exp(-X);
82  SEQ2 += DJ_[JQ] * X * exp(-X);
83 
84  if ((JQ / 2) * 2 == JQ) {
85  ZPARA += P;
86  SP1 += DJ_[JQ] * SQUARE(X) * exp(-X);
87  SP2 += DJ_[JQ] * X * exp(-X);
88  } else {
89  ZORTHO += P;
90  SO1 += DJ_[JQ] * SQUARE(X) * exp(-X);
91  SO2 += DJ_[JQ] * X * exp(-X);
92  }
93  }
94 
95  *cp_equil = 5.0 / 2.0 + SEQ1 / ZEQ - SQUARE(SEQ2 / ZEQ);
96  *cp_equil = (*cp_equil) * R_cgs * 1.E-7;
97 
98  *cp_ortho = 5.0 / 2.0 + SO1 / ZORTHO - SQUARE(SO2 / ZORTHO);
99  *cp_ortho = (*cp_ortho) * R_cgs * 1.E-7;
100 
101  *cp_para = 5.0 / 2.0 + SP1 / ZPARA - SQUARE(SP2 / ZPARA);
102  *cp_para = (*cp_para) * R_cgs * 1.E-7;
103 
104  *cp_norm = FORTH * (*cp_ortho) + FPARA * (*cp_para);
105 }
106 
107 double Hydrogen::cp_para(double T) {
108  double para;
109  double equil;
110  double norm;
111  double ortho;
112  get_cp_(&para, &equil, &norm, &ortho, T);
113  return para;
114 }
115 
116 double Hydrogen::cp_ortho(double T) {
117  double para;
118  double equil;
119  double norm;
120  double ortho;
121  get_cp_(&para, &equil, &norm, &ortho, T);
122  return ortho;
123 }
124 
125 double Hydrogen::cp_norm(double T) {
126  double para;
127  double equil;
128  double norm;
129  double ortho;
130  get_cp_(&para, &equil, &norm, &ortho, T);
131  return norm;
132 }
133 
134 double Hydrogen::cp_equil(double T) {
135  double para;
136  double equil;
137  double norm;
138  double ortho;
139  get_cp_(&para, &equil, &norm, &ortho, T);
140  return equil;
141 }
142 
143 double Hydrogen::cp_nist(double T) {
144  double *pdata;
145  std::stringstream msg;
146  T = std::min(std::max(298., T), 6000.);
147  // if (T < 298. || T > 6000.) {
148  // msg << "ERROR: Temperature out of range in Hydrogen::cp_nist" <<
149  // std::endl; throw std::runtime_error(msg.str().c_str());
150  // }
151 
152  if (T < 1000.)
153  pdata = nist_shomate1_;
154  else if (T >= 1000. && T < 2500.)
155  pdata = nist_shomate2_;
156  else
157  pdata = nist_shomate3_;
158 
159  double result;
160  T /= 1.E3;
161  result = pdata[0] + pdata[1] * T + pdata[2] * T * T + pdata[3] * T * T * T +
162  pdata[4] / (T * T);
163  return result;
164 }
165 
166 #undef SQUARE
167 #undef JMAX
168 
static double fpara_equil(double T)
static double nist_shomate3_[7]
Definition: molecules.hpp:138
static double cp_equil(double T)
static double cp_ortho(double T)
static double DJ_[20]
Definition: molecules.hpp:135
static double nist_shomate1_[7]
Definition: molecules.hpp:136
static double nist_shomate2_[7]
Definition: molecules.hpp:137
static double cp_norm(double T)
static void get_cp_(double *cp_para, double *cp_equil, double *cp_norm, double *cp_ortho, double T)
static double cp_nist(double T)
static double cp_para(double T)
static double FJ_[20]
Definition: molecules.hpp:134
double min(double x1, double x2, double x3)
Definition: core.h:16
double max(double x1, double x2, double x3)
Definition: core.h:19
static double const R_cgs
Hydrogen aH2
#define JMAX
static double const h_cgs
static double const FACT_cgs
static double const kBoltz_cgs
#define SQUARE(V)
static double const c_cgs