Cantera  2.0
units.h
Go to the documentation of this file.
1 /**
2  * @file units.h
3  * Header for units conversion utilities, which are used to translate
4  * user input from input files (See \ref inputfiles and
5  * class \link Cantera::Unit Unit\endlink).
6  *
7  * This header is included only by file misc.cpp.
8  */
9 // Copyright 2002 California Institute of Technology
10 
11 #ifndef CT_UNITS_H
12 #define CT_UNITS_H
13 
14 #include "cantera/base/ct_defs.h"
16 #include "cantera/base/ct_thread.h"
17 
18 #include <string>
19 
20 namespace Cantera
21 {
22 
23 //! Unit conversion utility
24 /*!
25  *
26  * @ingroup inputfiles
27  */
28 class Unit
29 {
30 public:
31 
32  //! Initialize the static Unit class.
33  static Unit* units() {
34  ScopedLock lock(units_mutex);
35  if (!s_u) {
36  s_u = new Unit;
37  }
38  return s_u;
39  }
40 
41  //! Destroy the static Unit class
42  /*!
43  * Note this can't be done in a destructor.
44  */
45  static void deleteUnit() {
46  ScopedLock lock(units_mutex);
47  if (s_u) {
48  delete s_u;
49  s_u = 0;
50  }
51  }
52 
53  //! Empty Destructor
54  virtual ~Unit() {}
55 
56  /**
57  * Return the multiplier required to convert an activation
58  * energy to SI units.
59  * @param units activation energy units
60  */
61  doublereal actEnergyToSI(std::string units) {
62  if (m_act_u.find(units) != m_act_u.end()) {
63  return m_act_u[units];
64  } else {
65  return toSI(units);
66  }
67  }
68 
69  /**
70  * Return the multiplier required to convert a dimensional quantity
71  * with units specified by string 'units' to SI units.
72  * The list of recognized units is stored as a stl map
73  * <string, doublereal>called m_u[] and m_act_u for activity
74  * coefficients. These maps are initialized with likely values.
75  *
76  * @param units String containing the units description
77  */
78  doublereal toSI(std::string units) {
79 
80  // if dimensionless, return 1.0
81  if (units == "") {
82  return 1.0;
83  }
84 
85  doublereal f = 1.0, fctr;
86  int tsize;
87  std::string u = units, tok, tsub;
88  std::string::size_type k;
89  char action = '-';
90 
91  while (1 > 0) {
92 
93  // get token consisting of all characters up to the next
94  // dash, slash, or the end of the string
95  k = u.find_first_of("/-");
96  if (k != std::string::npos) {
97  tok = u.substr(0,k);
98  } else {
99  tok = u;
100  }
101  tsize = static_cast<int>(tok.size());
102  if (tsize == 0) {
103  fctr = 1.0;
104  } else if (tok[tsize - 1] == '2') {
105  tsub = tok.substr(0,tsize-1);
106  fctr = m_u[tsub];
107  fctr *= fctr;
108  } else if (tok[tsize - 1] == '3') {
109  tsub = tok.substr(0,tsize-1);
110  fctr = m_u[tsub];
111  fctr *= fctr*fctr;
112  } else if (tok[tsize - 1] == '4') {
113  tsub = tok.substr(0,tsize-1);
114  fctr = m_u[tsub];
115  fctr *= fctr*fctr*fctr;
116  } else if (tok[tsize - 1] == '5') {
117  tsub = tok.substr(0,tsize-1);
118  fctr = m_u[tsub];
119  fctr *= fctr*fctr*fctr*fctr;
120  } else if (tok[tsize - 1] == '6') {
121  tsub = tok.substr(0,tsize-1);
122  fctr = m_u[tsub];
123  fctr *= fctr*fctr*fctr*fctr*fctr;
124  } else {
125  tsub = tok;
126  fctr = m_u[tok];
127  }
128 
129  // tok is not one of the entries in map m_u, then
130  // m_u[tok] returns 0.0. Check for this.
131  if (fctr == 0) {
132  throw CanteraError("toSI","unknown unit: "+tsub);
133  }
134  if (action == '-') {
135  f *= fctr;
136  } else if (action == '/') {
137  f /= fctr;
138  }
139  if (k == std::string::npos) {
140  break;
141  }
142  action = u[k];
143  u = u.substr(k+1,u.size());
144  }
145  return f;
146  }
147 
148 private:
149 
150  /// pointer to the single instance of Unit
151  static Unit* s_u;
152 
153  //! Map between a string and a units double value
154  /*!
155  * This map maps the dimension string to the units value adjustment. Example
156  * - m_u["m"] = 1.0;
157  * - m_u["cm"] = 0.01;
158  */
159  std::map<std::string, doublereal> m_u;
160 
161  //! Map between a string and a units double value for activation energy units
162  /*!
163  * This map maps the dimension string to the units value adjustment. Example
164  * - m_act_u["K"] = GasConstant;
165  */
166  std::map<std::string, doublereal> m_act_u;
167 
168  //! Decl for static locker for Units singleton
169  static mutex_t units_mutex;
170 
171  //! Units class constructor, containing the default mappings between
172  //! strings and units.
173  Unit() :
174  m_u(),
175  m_act_u() {
176 
177  // unity
178  m_u["1"] = 1.0;
179 
180  // length
181  m_u["m"] = 1.0;
182  m_u["cm"] = 0.01;
183  m_u["km"] = 1.0e3;
184  m_u["mm"] = 1.0e-3;
185  m_u["micron"] = 1.0e-6;
186  m_u["nm"] = 1.0e-9;
187  m_u["A"] = 1.0e-10;
188  m_u["Angstrom"] = 1.0e-10;
189  m_u["Angstroms"] = 1.0e-10;
190 
191  // energy
192  m_u["J"] = 1.0;
193  m_u["kJ"] = 1.0e3;
194  m_u["cal"] = 4.184;
195  m_u["kcal"] = 4184.0;
196  m_u["eV"] = Faraday; //1.60217733e-19;
197 
198  // resistance
199  m_u["ohm"] = 1.0;
200 
201  // quantity
202  m_u["mol"] = 1.0e-3;
203  m_u["gmol"] = 1.0e-3;
204  m_u["mole"] = 1.0e-3;
205  m_u["kmol"] = 1.0;
206  m_u["kgmol"] = 1.0;
207  m_u["molec"] = 1.0/Avogadro;
208 
209  // temperature
210  m_u["K"] = 1.0;
211  m_u["C"] = 1.0;
212  m_u["Kelvin"] = 1.0;
213 
214  // mass
215  m_u["gm"] = 1.0e-3;
216  m_u["g"] = 1.0e-3;
217  m_u["kg"] = 1.0;
218 
219  // pressure
220  m_u["atm"] = 1.01325e5;
221  m_u["bar"] = 1.0e5;
222  m_u["Pa"] = 1.0;
223 
224  // time
225  m_u["s"] = 1.0;
226  m_u["min"] = 60.0;
227  m_u["hr"] = 3600.0;
228  m_u["ms"] = 0.001;
229 
230  // electric potential
231  m_u["volt"] = 1.0;
232 
233  // charge
234  m_u["coulomb"] = 1.0;
235 
236  /*
237  // frequency - Took frequency out to reevaluate it. Inverse cm is probably the wrong default unit
238  m_u["hZ"] = 0.01/(lightSpeed);
239  m_u["cm^-1"] = 1.0;
240  m_u["m^-1"] = 0.1;
241  m_u["cm-1"] = m_u["cm^-1"];
242  m_u["m-1"] = m_u["m^-1"];
243  m_u["wavenumbers"] = m_u["cm^-1"];
244  */
245 
246  // viscosity
247  m_u["Pa-s"] = 1;
248  m_u["poise"] = 0.1;
249  m_u["centipoise"] = 0.001;
250  m_u["P"] = 0.1;
251  m_u["cP"] = 0.001;
252 
253  // volume
254  m_u["kL"] = 1.0;
255  m_u["liter"] = 0.001;
256  m_u["L"] = 0.001;
257  m_u["l"] = 0.001;
258  m_u["mL"] = 1.0e-6;
259  m_u["ml"] = 1.0e-6;
260  m_u["cc"] = 1.0e-6;
261 
262  m_act_u["eV"] = m_u["eV"]; // /m_u["molec"];
263  m_act_u["K"] = GasConstant;
264  m_act_u["Kelvin"] = GasConstant;
265  m_act_u["Dimensionless"] = (GasConstant * 273.15);
266  }
267 };
268 }
269 
270 #endif
271