Canoe
Comprehensive Atmosphere N' Ocean Engine
molecules.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <cassert>
3 #include <sstream>
4 
5 // application
6 #include <application/application.hpp>
7 #include <application/exceptions.hpp>
8 
9 // utils
10 #include <utils/fileio.hpp>
11 
12 // climath
13 #include <climath/interpolation.h>
14 
15 #include <climath/root.hpp>
16 
17 // snap
18 #include "molecules.hpp"
19 
20 #define PRECISION 1.E-8
21 
22 std::ostream& operator<<(std::ostream& os, Molecule const& mol) {
23  os << "name: " << mol.m_name << std::endl
24  << "molecular weight: " << mol.m_mu << " kg/mol" << std::endl
25  << "heat capacity (cp): " << mol.m_cp << " J/(mol K)" << std::endl
26  << "vaporization heat at triple point: " << mol.m_latent << " kJ/mol"
27  << std::endl
28  << "vapor pressure coefficients: " << mol.m_beta << " " << mol.m_gamma
29  << std::endl
30  << "standard entropy: " << mol.m_entropy << " J/(mol K)" << std::endl
31  << "standard enthalpy: " << mol.m_enthalpy << " kJ/mol" << std::endl;
32 
33  return os;
34 }
35 
36 void Molecule::LoadThermodynamicFile(std::string chemfile) {
37  auto app = Application::GetInstance();
38  auto full_path = app->FindInputFile(chemfile);
39 
40  std::stringstream inp(DecommentFile(full_path));
41  double junk;
42 
43  inp >> m_name >> m_mu >> m_entropy >> m_enthalpy >> m_gibbs >> m_cp >> m_tr >>
44  m_pr >> m_tc >> m_pc;
45  inp >> m_nshomate;
46  for (int i = 0; i < m_nshomate; i++) {
47  inp >> m_shomate_sp.at(i) >> junk;
48  for (int j = 0; j < NSHOMATE; j++) inp >> m_shomate.at(i * NSHOMATE + j);
49  }
50  m_shomate_sp.at(m_nshomate) = junk;
51 
52  inp >> m_cliq >> m_enliq >> m_csld >> m_ensld;
53 
54  m_mu *= 1.E-3; // g/mol -> kg/mol
55 }
56 
57 double Molecule::cp(double T) const {
58  int i = locate(m_shomate_sp.data(), T, m_nshomate + 1);
59  if (i == m_nshomate) i = m_nshomate - 1;
60  if (i < 0) i = 0;
61 
62  double result;
63  T /= 1.E3;
64  result = m_shomate[i * NSHOMATE] + m_shomate[i * NSHOMATE + 1] * T +
65  m_shomate[i * NSHOMATE + 2] * T * T +
66  m_shomate[i * NSHOMATE + 3] * T * T * T +
67  m_shomate[i * NSHOMATE + 4] / (T * T);
68 
69  return result;
70 }
71 
72 double Molecule::enthalpy(double T) const {
73  int i = locate(m_shomate_sp.data(), T, m_nshomate + 1);
74  if (i == m_nshomate) i = m_nshomate - 1;
75  if (i < 0) i = 0;
76 
77  double result;
78  T /= 1.E3;
79  result = m_shomate[i * NSHOMATE] * T +
80  0.5 * m_shomate[i * NSHOMATE + 1] * T * T +
81  1. / 3. * m_shomate[i * NSHOMATE + 2] * T * T * T +
82  1. / 4. * m_shomate[i * NSHOMATE + 3] * T * T * T * T +
83  -m_shomate[i * NSHOMATE + 4] / T + m_shomate[i * NSHOMATE + 5];
84 
85  return result;
86 }
87 
88 double Molecule::entropy(double T) const {
89  int i = locate(m_shomate_sp.data(), T, m_nshomate + 1);
90  if (i == m_nshomate) i = m_nshomate - 1;
91  if (i < 0) i = 0;
92 
93  double result;
94  T /= 1.E3;
95  result = m_shomate[i * NSHOMATE] * log(T) + m_shomate[i * NSHOMATE + 1] * T +
96  0.5 * m_shomate[i * NSHOMATE + 2] * T * T +
97  1. / 3. * m_shomate[i * NSHOMATE + 3] * T * T * T +
98  -m_shomate[i * NSHOMATE + 4] / (2. * T * T) +
99  m_shomate[i * NSHOMATE + 6];
100 
101  return result;
102 }
103 
104 double Molecule::latent(double T) const {
105  double result;
106  result = m_latent + enthalpy(T) - enthalpy(m_tr) - m_cp * (T - m_tr) / 1.E3;
107 
108  return result;
109 }
110 
111 double Molecule::isat_vapor_p(double P) const {
112  double Tsat, Tmin, Tmax;
113  Tmin = 50.;
114  Tmax = 2000.;
115  int error = root(Tmin, Tmax, PRECISION, &Tsat,
116  [this, P](double T) { return this->sat_vapor_p(T) - P; });
117  if (error) {
118  std::stringstream msg;
119  msg << "Inverting saturation vapor pressure is not sucessfull" << std::endl;
120  msg << "Pressure = " << P << " Pa" << std::endl;
121  msg << "Tmin = " << Tmin << std::endl;
122  msg << "Tmax = " << Tmax << std::endl;
123  msg << "Saturation vapor pressure at Tmin = " << sat_vapor_p(Tmin)
124  << std::endl;
125  msg << "Saturation vapor pressure at Tmax = " << sat_vapor_p(Tmax)
126  << std::endl;
127  msg << *this << std::endl;
128  throw RuntimeError("Molecule", msg.str());
129  }
130 
131  return Tsat;
132 }
double cp() const
Definition: molecules.hpp:109
double m_enliq
Definition: molecules.hpp:55
int m_nshomate
Definition: molecules.hpp:57
double isat_vapor_p(double P) const
Definition: molecules.cpp:111
double m_mu
Definition: molecules.hpp:54
double m_cliq
Definition: molecules.hpp:55
std::string m_name
Definition: molecules.hpp:52
std::array< double, MAXSHOMATE+1 > m_shomate_sp
Definition: molecules.hpp:61
double m_latent
Definition: molecules.hpp:54
double m_gibbs
Definition: molecules.hpp:54
virtual double entropy(double T) const
Definition: molecules.cpp:88
double m_beta
Definition: molecules.hpp:55
double m_pr
Definition: molecules.hpp:54
virtual double enthalpy(double T) const
Definition: molecules.cpp:72
double m_tc
Definition: molecules.hpp:54
double m_entropy
Definition: molecules.hpp:54
double m_cp
Definition: molecules.hpp:54
double m_tr
Definition: molecules.hpp:54
void LoadThermodynamicFile(std::string chemfile)
Definition: molecules.cpp:36
double latent() const
Definition: molecules.hpp:119
std::array< double, MAXSHOMATE *NSHOMATE > m_shomate
Definition: molecules.hpp:59
double m_ensld
Definition: molecules.hpp:55
double sat_vapor_p(double T) const
Definition: molecules.hpp:99
double m_csld
Definition: molecules.hpp:55
double m_enthalpy
Definition: molecules.hpp:54
double m_pc
Definition: molecules.hpp:55
double m_gamma
Definition: molecules.hpp:55
std::string DecommentFile(std::string fname)
decomment a file
Definition: fileio.cpp:30
int locate(double const *xx, double x, int n)
Definition: locate.c:7
std::ostream & operator<<(std::ostream &os, Molecule const &mol)
Definition: molecules.cpp:22
#define PRECISION
Definition: molecules.cpp:20
#define NSHOMATE
Molecule stored the necessary information for calculating the thermodynamic properties of an air parc...
Definition: molecules.hpp:43
int root(double x1, double x2, double xacc, double *x_root, RootFunction_t func, void *aux)
Definition: root.c:10