GRINS-0.8.0
hitran.C
Go to the documentation of this file.
1 
2 //-----------------------------------------------------------------------bl-
3 //--------------------------------------------------------------------------
4 //
5 // GRINS - General Reacting Incompressible Navier-Stokes
6 //
7 // Copyright (C) 2014-2017 Paul T. Bauman, Roy H. Stogner
8 // Copyright (C) 2010-2013 The PECOS Development Team
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the Version 2.1 GNU Lesser General
12 // Public License as published by the Free Software Foundation.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
22 // Boston, MA 02110-1301 USA
23 //
24 //-----------------------------------------------------------------------el-
25 
26 // this class
27 #include "grins/hitran.h"
28 
29 // libMesh
30 
31 // GRINS
32 #include "grins/string_utils.h"
33 
34 // C++
35 #include <fstream>
36 #include <algorithm>
37 
38 namespace GRINS
39 {
40  HITRAN::HITRAN(const std::string & data_file, const std::string & partition_function_file,
41  libMesh::Real T_min, libMesh::Real T_max, libMesh::Real T_step)
42  : _Tmin(T_min),
43  _Tmax(T_max),
44  _Tstep(T_step),
45  _T0(296.0)
46  {
47  // sanity checks on temperature range specification
48  if ( (T_min<0.0) || (T_min>=T_max) || (T_step<=0.0) || (T_min>_T0) || (T_max<_T0) )
49  {
50  std::stringstream ss;
51  ss <<"Invalid specification of temperature range:" <<std::endl;
52  ss <<"T_min: " <<T_min <<std::endl;
53  ss <<"T_max: " <<T_max <<std::endl;
54  ss <<"T_step: " <<T_step <<std::endl;
55  libmesh_error_msg(ss.str());
56  }
57 
58  // open data file
59  std::ifstream hitran_file;
60  hitran_file.open(data_file);
61  if (!hitran_file.is_open())
62  {
63  std::stringstream ss;
64  ss <<"Unable to open provided hitran_file: " <<data_file <<std::endl;
65  libmesh_error_msg(ss.str());
66  }
67 
68  while(!hitran_file.eof())
69  {
70  std::string line;
71  getline(hitran_file,line);
72 
73  if (line == "")
74  continue;
75 
76  std::vector<libMesh::Real> vals;
77 
79 
80  libmesh_assert_equal_to(vals.size(),8);
81 
82  // HITRAN gives isotopologue numbers starting at 1
83  // shift to zero-based to make indexing easier
84  _isotop.push_back(static_cast<unsigned int>(vals[0]-1));
85 
86  _nu.push_back(vals[1]);
87  _sw.push_back(vals[2]);
88  _gamma_air.push_back(vals[3]);
89  _gamma_self.push_back(vals[4]);
90  _elower.push_back(vals[5]);
91  _n.push_back(vals[6]);
92  _delta_air.push_back(vals[7]);
93  }
94 
95  // sanity checks
96  libmesh_assert_equal_to( _isotop.size(), _nu.size() );
97  libmesh_assert_equal_to( _nu.size(), _sw.size() );
98  libmesh_assert_equal_to( _sw.size(), _gamma_air.size() );
99  libmesh_assert_equal_to( _gamma_air.size(), _gamma_self.size() );
100  libmesh_assert_equal_to( _gamma_self.size(), _elower.size() );
101  libmesh_assert_equal_to( _elower.size(), _n.size() );
102  libmesh_assert_equal_to( _n.size(), _delta_air.size() );
103 
104  // save data length and close HITRAN data file
105  _data_size = _isotop.size(); // all data vectors are the same length
106  hitran_file.close();
107 
108  // file with partition function values
109  std::ifstream qT_file;
110  qT_file.open(partition_function_file);
111  if (!qT_file.is_open())
112  {
113  std::stringstream ss;
114  ss <<"Unable to open provided partition_function_file: " <<partition_function_file <<std::endl;
115  libmesh_error_msg(ss.str());
116  }
117 
118  // number of temperature values
119  unsigned int num_T = (T_max-T_min)/T_step + 1;
120 
121  // read the partition function values
122  unsigned int counter = 0;
123 
124  while(!qT_file.eof())
125  {
126  std::string line;
127  getline(qT_file,line);
128 
129  if (line == "")
130  continue;
131 
132  _qT.push_back(std::vector<libMesh::Real>());
133 
135 
136  // we should have a partition function value for each temperature
137  libmesh_assert_equal_to(num_T,_qT[counter].size());
138 
139  counter++;
140  }
141 
142  // save length and close partition sum file
143  _q_size = num_T;
144  qT_file.close();
145 
146  // cache the partition function values at the referece temperature
147  for(unsigned int i=0; i<_qT.size(); i++)
148  _qT0.push_back(this->get_partition_function_value(_T0,i));
149 
150  return;
151  }
152 
153  unsigned int HITRAN::get_data_size()
154  {
155  return _data_size;
156  }
157 
158  libMesh::Real HITRAN::partition_function_derivative(libMesh::Real T, unsigned int iso)
159  {
160  libMesh::Real deriv = -1.0;
161  if (std::abs(T-_Tmin)<libMesh::TOLERANCE) // 1st order forward difference
162  {
163  libMesh::Real QT0 = this->partition_function(_Tmin,iso);
164  libMesh::Real QT1 = this->partition_function(_Tmin+_Tstep,iso);
165 
166  deriv = (QT1-QT0)/_Tstep;
167  }
168  else if (std::abs(T-_Tmax)<libMesh::TOLERANCE) // 1st order backward difference
169  {
170  libMesh::Real QT0 = this->partition_function(_Tmax-_Tstep,iso);
171  libMesh::Real QT1 = this->partition_function(_Tmax,iso);
172 
173  deriv = (QT1-QT0)/_Tstep;
174  }
175  else // 2nd order central difference
176  {
177  libMesh::Real QT1 = this->partition_function(T+_Tstep,iso);
178  libMesh::Real QT0 = this->partition_function(T-_Tstep,iso);
179 
180  deriv = (QT1-QT0)/(2.0*_Tstep);
181  }
182 
183  return deriv;
184  }
185 
186  unsigned int HITRAN::isotopologue(unsigned int index)
187  {
188  libmesh_assert_less(index,_isotop.size());
189  return _isotop[index];
190  }
191 
192  libMesh::Real HITRAN::nu0(unsigned int index)
193  {
194  libmesh_assert_less(index,_nu.size());
195  return _nu[index];
196  }
197 
198  libMesh::Real HITRAN::sw(unsigned int index)
199  {
200  libmesh_assert_less(index,_sw.size());
201  return _sw[index];
202  }
203 
204  libMesh::Real HITRAN::gamma_air(unsigned int index)
205  {
206  libmesh_assert_less(index,_gamma_air.size());
207  return _gamma_air[index];
208  }
209 
210  libMesh::Real HITRAN::gamma_self(unsigned int index)
211  {
212  libmesh_assert_less(index,_gamma_self.size());
213  return _gamma_self[index];
214  }
215 
216  libMesh::Real HITRAN::elower(unsigned int index)
217  {
218  libmesh_assert_less(index,_elower.size());
219  return _elower[index];
220  }
221 
222  libMesh::Real HITRAN::n_air(unsigned int index)
223  {
224  libmesh_assert_less(index,_n.size());
225  return _n[index];
226  }
227 
228  libMesh::Real HITRAN::delta_air(unsigned int index)
229  {
230  libmesh_assert_less(index,_delta_air.size());
231  return _delta_air[index];
232  }
233 
234  libMesh::Real HITRAN::partition_function(libMesh::Real T, unsigned int iso)
235  {
236  libMesh::Real qt;
237 
238  if (T==_T0)
239  qt = _qT0[iso];
240  else
241  qt = this->get_partition_function_value(T,iso);
242 
243  return qt;
244  }
245 
246  libMesh::Real HITRAN::get_partition_function_value(libMesh::Real T, unsigned int iso)
247  {
248  libMesh::Real retval = -1.0;
249 
250  int i = T_index(T);
251 
252  if (i >= 0)
253  retval = this->interpolate_values(i,T,_qT[iso]);
254  else
255  {
256  std::stringstream ss;
257  ss <<"Error: Temperature " <<T <<"K does not exist in the given partition sum data" <<std::endl;
258  libmesh_error_msg(ss.str());
259  }
260 
261  return retval;
262  }
263 
264  int HITRAN::T_index(libMesh::Real T)
265  {
266  unsigned int index = std::ceil((T-_Tmin)/_Tstep);
267  index = std::max(index,(unsigned int)1);
268  return index;
269  }
270 
271  libMesh::Real HITRAN::interpolate_values( int index_r, libMesh::Real T_star, const std::vector<libMesh::Real> & y) const
272  {
273  if ( (T_star>_Tmax) || (T_star<_Tmin) )
274  {
275  std::stringstream ss;
276  ss <<"Error, temperature T=" <<T_star <<" is outside the specified range of provided partition function values" <<std::endl;
277  libmesh_error_msg(ss.str());
278  }
279 
280  libMesh::Real T = _Tmin + (_Tstep*index_r);
281  return y[index_r-1] + ( (T_star-(T-_Tstep))*(y[index_r]-y[index_r-1]) )/(T-(T-_Tstep));
282  }
283 
284 }
libMesh::Real interpolate_values(int index_r, libMesh::Real T_star, const std::vector< libMesh::Real > &y) const
Linear interpolation helper function.
Definition: hitran.C:271
std::vector< libMesh::Real > _nu
Definition: hitran.h:124
libMesh::Real elower(unsigned int index)
Lower state energy of transition [ ].
Definition: hitran.C:216
unsigned int get_data_size()
Return the data size.
Definition: hitran.C:153
libMesh::Real partition_function(libMesh::Real T, unsigned int iso)
Definition: hitran.C:234
int _data_size
Size of spectroscopic data.
Definition: hitran.h:110
libMesh::Real _Tstep
Definition: hitran.h:107
libMesh::Real nu0(unsigned int index)
Linecenter wavenumber [ ].
Definition: hitran.C:192
std::vector< libMesh::Real > _sw
Definition: hitran.h:125
libMesh::Real _Tmax
Definition: hitran.h:107
unsigned int isotopologue(unsigned int index)
Isotopologue ID.
Definition: hitran.C:186
GRINS namespace.
std::vector< libMesh::Real > _gamma_air
Definition: hitran.h:126
std::vector< libMesh::Real > _gamma_self
Definition: hitran.h:127
libMesh::Real partition_function_derivative(libMesh::Real T, unsigned int iso)
Finite difference derivative for partition function.
Definition: hitran.C:158
void split_string_real(const std::string &input, const std::string &delimiter, std::vector< libMesh::Real > &results)
Definition: string_utils.C:53
std::vector< libMesh::Real > _n
Definition: hitran.h:129
libMesh::Real delta_air(unsigned int index)
Air pressure-induced line shift [ ].
Definition: hitran.C:228
libMesh::Real get_partition_function_value(libMesh::Real T, unsigned int iso)
Search through the partition function data to get value for given temperature.
Definition: hitran.C:246
libMesh::Real n_air(unsigned int index)
Temperature coefficient [].
Definition: hitran.C:222
HITRAN()
User should not call empty constructor.
libMesh::Real _T0
Reference temperature (296K)
Definition: hitran.h:116
libMesh::Real gamma_self(unsigned int index)
Self-broadening half-wdith [ ].
Definition: hitran.C:210
std::vector< libMesh::Real > _delta_air
Definition: hitran.h:130
std::vector< unsigned int > _isotop
Definition: hitran.h:123
int _q_size
Size of partition function data.
Definition: hitran.h:113
std::vector< std::vector< libMesh::Real > > _qT
Vector for partition function values for all isotopologues.
Definition: hitran.h:133
int T_index(libMesh::Real T)
Find the index into _T corresponding to the given temperature.
Definition: hitran.C:264
libMesh::Real _Tmin
Definition: hitran.h:107
libMesh::Real sw(unsigned int index)
Linestrength [ ].
Definition: hitran.C:198
std::vector< libMesh::Real > _elower
Definition: hitran.h:128
libMesh::Real gamma_air(unsigned int index)
Air-broadening half-width [ ].
Definition: hitran.C:204
std::vector< libMesh::Real > _qT0
Definition: hitran.h:120

Generated on Tue Dec 19 2017 12:47:28 for GRINS-0.8.0 by  doxygen 1.8.9.1