units.h

Go to the documentation of this file.
00001 /**
00002  * @file units.h
00003  * Header for units conversion utilities, which are used to translate
00004  * user input from input files (See \ref inputfiles and 
00005  * class \link Cantera::Unit Unit\endlink).
00006  *
00007  * This header is included only by file misc.cpp.
00008  */
00009 /*
00010  * $Id: units.h 368 2010-01-04 00:46:26Z hkmoffa $
00011  */
00012 //    Copyright 2002 California Institute of Technology
00013 
00014 #ifndef CT_UNITS_H
00015 #define CT_UNITS_H
00016 
00017 #include "ct_defs.h"
00018 #include "ctexceptions.h"
00019 
00020 #include <string>
00021 
00022 #if defined(THREAD_SAFE_CANTERA)
00023 #include <boost/thread/mutex.hpp>
00024 #endif
00025 
00026 namespace Cantera {
00027 
00028     //! Unit conversion utility
00029     /*!
00030      *
00031      * @ingroup inputfiles 
00032      */
00033     class Unit {
00034     public:
00035 
00036         //! Initialize the static Unit class.
00037         static Unit* units() {
00038 #if defined(THREAD_SAFE_CANTERA)
00039             boost::mutex::scoped_lock   lock(units_mutex) ;
00040 #endif
00041             if (!s_u) s_u = new Unit;
00042             return s_u;
00043         }
00044 
00045         //! Destroy the static Unit class
00046         /*!
00047          * Note this can't be done in a destructor.
00048          */
00049         static void deleteUnit() {
00050 #if defined(THREAD_SAFE_CANTERA)
00051             boost::mutex::scoped_lock   lock(units_mutex) ;
00052 #endif
00053             if (s_u) {
00054                 delete s_u;
00055                 s_u = 0;
00056             }
00057         }
00058 
00059         //! Empty Destructor
00060         virtual ~Unit() {}
00061 
00062         /**
00063          * Return the multiplier required to convert an activation
00064          * energy to SI units.
00065          * @param units activation energy units
00066          */
00067         doublereal actEnergyToSI(std::string units) {
00068             if (m_act_u.find(units) != m_act_u.end()) {
00069                 return m_act_u[units];
00070             }
00071             else {
00072                 return toSI(units);
00073             }
00074         }
00075 
00076         /**
00077          * Return the multiplier required to convert a dimensional quantity 
00078          * with units specified by string 'units' to SI units.
00079          * The list of recognized units is storred as a stl map
00080          *  <string, doublereal>called  m_u[] and m_act_u for activity
00081          * coefficients. These maps are initialized with likely values.
00082          *
00083          * @param units String containing the units description
00084          */
00085         doublereal toSI(std::string units) {
00086           
00087             // if dimensionless, return 1.0
00088             if (units == "") return 1.0;
00089           
00090             doublereal f = 1.0, fctr;
00091             int tsize;
00092             std::string u = units, tok, tsub;
00093             std::string::size_type k;
00094             char action = '-';
00095 
00096             while (1 > 0) {
00097 
00098                 // get token consisting of all characters up to the next 
00099                 // dash, slash, or the end of the string
00100                 k = u.find_first_of("/-");
00101                 if (k != std::string::npos)
00102                     tok = u.substr(0,k);
00103                 else
00104                     tok = u;
00105                 tsize = static_cast<int>(tok.size());
00106                 if (tsize == 0) 
00107                     fctr = 1.0;
00108                 else if (tok[tsize - 1] == '2') {
00109                     tsub = tok.substr(0,tsize-1);
00110                     fctr = m_u[tsub];
00111                     fctr *= fctr;
00112                 }
00113                 else if (tok[tsize - 1] == '3') {
00114                     tsub = tok.substr(0,tsize-1);
00115                     fctr = m_u[tsub];
00116                     fctr *= fctr*fctr;
00117                 }
00118                 else if (tok[tsize - 1] == '4') {
00119                     tsub = tok.substr(0,tsize-1);
00120                     fctr = m_u[tsub];
00121                     fctr *= fctr*fctr*fctr;
00122                 }
00123                 else if (tok[tsize - 1] == '5') {
00124                     tsub = tok.substr(0,tsize-1);
00125                     fctr = m_u[tsub];
00126                     fctr *= fctr*fctr*fctr*fctr;
00127                 }
00128                 else if (tok[tsize - 1] == '6') {
00129                     tsub = tok.substr(0,tsize-1);
00130                     fctr = m_u[tsub];
00131                     fctr *= fctr*fctr*fctr*fctr*fctr;
00132                 }
00133                 else {
00134                     tsub = tok;
00135                     fctr = m_u[tok];
00136                 }
00137 
00138                 // tok is not one of the entries in map m_u, then 
00139                 // m_u[tok] returns 0.0. Check for this.
00140                 if (fctr == 0) 
00141                     throw CanteraError("toSI","unknown unit: "+tsub);
00142                 if (action == '-') f *= fctr;
00143                 else if (action == '/') f /= fctr;
00144                 if (k == std::string::npos) break;
00145                 action = u[k];
00146                 u = u.substr(k+1,u.size());
00147             }
00148             return f;
00149         }
00150 
00151     private:
00152 
00153         /// pointer to the single instance of Unit
00154         static Unit* s_u;
00155 
00156         //! Map between a string and a units double value
00157         /*!
00158          *  This map maps the dimension string to the units value adjustment. Example
00159          *   -  m_u["m"]    = 1.0;
00160          *   -  m_u["cm"]   = 0.01;
00161          */
00162         std::map<std::string, doublereal> m_u;
00163 
00164         //! Map between a string and a units double value for activation energy units
00165         /*!
00166          *  This map maps the dimension string to the units value adjustment. Example
00167          *   -    m_act_u["K"] =  GasConstant;
00168          */
00169         std::map<std::string, doublereal> m_act_u;
00170 
00171 #if defined(THREAD_SAFE_CANTERA)
00172         //! Decl for static locker for Units singelton 
00173         static boost::mutex units_mutex;
00174 #endif
00175 
00176         /*!
00177          * Units class constructor, containing the default mappings between
00178          * strings and units.
00179          */
00180         Unit(){
00181 
00182             // length
00183             m_u["m"]    = 1.0;
00184             m_u["cm"]   = 0.01;
00185             m_u["km"]   = 1.0e3;
00186             m_u["mm"]   = 1.0e-3;
00187             m_u["micron"]   = 1.0e-6;
00188             m_u["nm"]   = 1.0e-9;
00189             m_u["A"]   = 1.0e-10;
00190             m_u["Angstrom"]   = 1.0e-10;
00191             m_u["Angstroms"]   = 1.0e-10;
00192 
00193             // energy
00194             m_u["J"]        = 1.0;
00195             m_u["kJ"]       = 1.0e3;
00196             m_u["cal"]      = 4.184;
00197             m_u["kcal"]     = 4184.0;
00198             m_u["eV"]       = Faraday; //1.60217733e-19;
00199 
00200             // quantity
00201             m_u["mol"]      = 1.0e-3;
00202             m_u["gmol"]     = 1.0e-3;
00203             m_u["mole"]     = 1.0e-3;
00204             m_u["kmol"]     = 1.0;
00205             m_u["kgmol"]     = 1.0;
00206             m_u["molec"]    = 1.0/Avogadro;
00207 
00208             // temperature
00209             m_u["K"]        = 1.0;
00210             m_u["C"]        = 1.0;
00211 
00212             // mass
00213             m_u["g"]        = 1.0e-3;
00214             m_u["kg"]       = 1.0;
00215 
00216             // pressure
00217             m_u["atm"]      = 1.01325e5;
00218             m_u["bar"]      = 1.0e5;
00219             m_u["Pa"]       = 1.0;
00220 
00221             // time
00222             m_u["s"]        = 1.0;
00223             m_u["min"]      = 60.0;
00224             m_u["hr"]       = 3600.0;
00225             m_u["ms"]       = 0.001;
00226 
00227             // frequency
00228             m_u["hZ"]       = 0.01/(lightSpeed);
00229             m_u["cm^-1"]    = 1.0;
00230             m_u["m^-1"]     = 0.1; 
00231             m_u["cm-1"]     = m_u["cm^-1"];
00232             m_u["m-1"]      = m_u["m^-1"];
00233             m_u["wavenumbers"] = m_u["cm^-1"];
00234 
00235             // viscosity
00236             m_u["poise"]    = 0.1;
00237             m_u["centipoise"] = 0.001;
00238 
00239             m_act_u["eV"] = m_u["eV"]; // /m_u["molec"];
00240             m_act_u["K"] =  GasConstant;
00241             m_act_u["Kelvin"] =  GasConstant;
00242             m_act_u["Dimensionless"] =  (GasConstant * 273.15);
00243         }
00244     };
00245 }
00246 
00247 #endif
00248 
Generated by  doxygen 1.6.3