cantera/Cantera/src/units.h
2005-06-18 16:58:39 +00:00

180 lines
5.1 KiB
C++

/**
* @file units.h
*
* Unit conversions. This header is included only by file misc.cpp.
*/
#ifndef CT_UNITS_H
#define CT_UNITS_H
#include "ct_defs.h"
#include "ctexceptions.h"
namespace Cantera {
class Unit {
public:
static Unit* units() {
if (!__u) __u = new Unit;
return __u;
}
static void deleteUnit() {
if (__u) {
delete __u;
__u = 0;
}
}
virtual ~Unit() {}
/**
* Return the multiplier required to convert an activation
* energy to SI units.
* @param units activation energy units
*/
doublereal actEnergyToSI(string units) {
if (m_act_u.find(units) != m_act_u.end()) {
return m_act_u[units];
}
else {
return toSI(units);
}
}
/**
* Return the multiplier required to convert a dimensional quantity
* with units specified by string 'units' to SI units.
* The list of recognized units is storred as a stl map
* <string, doublereal>called m_u[] and m_act_u for activity
* coefficients. These maps are initialized with likely values.
*/
doublereal toSI(string units) {
// if dimensionless, return 1.0
if (units == "") return 1.0;
doublereal f = 1.0, fctr;
int tsize;
string u = units, tok, tsub;
string::size_type k;
char action = '-';
while (1 > 0) {
// get token consisting of all characters up to the next
// dash, slash, or the end of the string
k = u.find_first_of("/-");
if (k != string::npos)
tok = u.substr(0,k);
else
tok = u;
tsize = static_cast<int>(tok.size());
if (tsize == 0)
fctr = 1.0;
else if (tok[tsize - 1] == '2') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr;
}
else if (tok[tsize - 1] == '3') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr;
}
else if (tok[tsize - 1] == '4') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr;
}
else if (tok[tsize - 1] == '5') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr*fctr;
}
else if (tok[tsize - 1] == '6') {
tsub = tok.substr(0,tsize-1);
fctr = m_u[tsub];
fctr *= fctr*fctr*fctr*fctr*fctr;
}
else {
tsub = tok;
fctr = m_u[tok];
}
// tok is not one of the entries in map m_u, then
// m_u[tok] returns 0.0. Check for this.
if (fctr == 0)
throw CanteraError("toSI","unknown unit: "+tsub);
if (action == '-') f *= fctr;
else if (action == '/') f /= fctr;
if (k == string::npos) break;
action = u[k];
u = u.substr(k+1,u.size());
}
return f;
}
private:
/// pointer to the single instance of Unit
static Unit* __u;
map<string, doublereal> m_u;
map<string, doublereal> m_act_u;
Unit(){
// length
m_u["m"] = 1.0;
m_u["cm"] = 0.01;
m_u["km"] = 1.0e3;
m_u["mm"] = 1.0e-3;
m_u["micron"] = 1.0e-6;
m_u["nm"] = 1.0e-9;
m_u["A"] = 1.0e-10;
m_u["Angstrom"] = 1.0e-10;
m_u["Angstroms"] = 1.0e-10;
// energy
m_u["J"] = 1.0;
m_u["kJ"] = 1.0e3;
m_u["cal"] = 4.184;
m_u["kcal"] = 4184.0;
m_u["eV"] = 1.602e-19;
// quantity
m_u["mol"] = 1.0e-3;
m_u["mole"] = 1.0e-3;
m_u["kmol"] = 1.0;
m_u["molec"] = 1.0/Avogadro;
// temperature
m_u["K"] = 1.0;
m_u["C"] = 1.0;
// mass
m_u["g"] = 1.0e-3;
m_u["kg"] = 1.0;
// pressure
m_u["atm"] = 1.01325e5;
m_u["bar"] = 1.0e5;
m_u["Pa"] = 1.0;
// time
m_u["s"] = 1.0;
m_u["min"] = 60.0;
m_u["hr"] = 3600.0;
m_u["ms"] = 0.001;
m_act_u["eV"] = m_u["eV"]/m_u["molec"];
m_act_u["K"] = GasConstant;
m_act_u["Kelvin"] = GasConstant;
m_act_u["Dimensionless"] = (GasConstant * 273.15);
}
};
}
#endif