Cantera  3.1.0a1
Elements.cpp
Go to the documentation of this file.
1 /**
2  * @file Elements.cpp
3  * This file contains a database of atomic weights.
4  */
5 
6 // This file is part of Cantera. See License.txt in the top-level directory or
7 // at https://cantera.org/license.txt for license and copyright information.
8 
12 
13 namespace Cantera
14 {
15 
16 /**
17  * Database for atomic weights.
18  * Values are used from CIAAW. Atomic weights of the elements 2017
19  * when a single value is given. Available online at
20  * http://www.ciaaw.org/atomic-weights.htm
21  *
22  * When a range of values is given in the CIAAW table, the "conventional
23  * atomic weight" from the IUPAC Periodic Table is used. Available
24  * online at https://iupac.org/wp-content/uploads/2018/12/IUPAC_Periodic_Table-01Dec18.pdf
25  *
26  * If no value is given in either source, it is because no stable isotopes of
27  * that element are known and the atomic weight of that element is listed here
28  * as -1.0
29  *
30  * units = kg / kg-mol (or equivalently gm / gm-mol)
31  *
32  * This structure was picked because it's simple, compact, and extensible.
33  */
35  string symbol; //!< Element symbol, first letter capitalized
36  string fullName; //!< Element full name, first letter lowercase
37  double atomicWeight; //!< Element atomic weight in kg / kg-mol, if known. -1 if no stable isotope
38 };
39 
40 /**
41  * Database for named isotopic weights.
42  * Values are used from Kim, et al. @cite kim2019.
43  *
44  * units = kg / kg-mol (or equivalently gm / gm-mol)
45  *
46  * This structure was picked because it's simple, compact, and extensible.
47  */
49  string symbol; //!< Isotope symbol, first letter capitalized
50  string fullName; //!< Isotope full name, first letter lowercase
51  double atomicWeight; //!< Isotope atomic weight in kg / kg-mol
52  int atomicNumber; //!< Isotope atomic number
53 };
54 
55 /**
56  * @var static vector<atomicWeightData> atomicWeightTable
57  * @brief atomicWeightTable is a vector containing the atomic weights database.
58  *
59  * atomicWeightTable is a static variable with scope limited to this file.
60  * It can only be referenced via the functions in this file.
61  *
62  * The size of the table is given by the initial instantiation.
63  */
64 static vector<atomicWeightData> atomicWeightTable {
65  {"H", "hydrogen", 1.008},
66  {"He", "helium", 4.002602},
67  {"Li", "lithium", 6.94},
68  {"Be", "beryllium", 9.0121831},
69  {"B", "boron", 10.81},
70  {"C", "carbon", 12.011},
71  {"N", "nitrogen", 14.007},
72  {"O", "oxygen", 15.999},
73  {"F", "fluorine", 18.998403163},
74  {"Ne", "neon", 20.1797},
75  {"Na", "sodium", 22.98976928},
76  {"Mg", "magnesium", 24.305},
77  {"Al", "aluminum", 26.9815384},
78  {"Si", "silicon", 28.085},
79  {"P", "phosphorus", 30.973761998},
80  {"S", "sulfur", 32.06},
81  {"Cl", "chlorine", 35.45},
82  {"Ar", "argon", 39.95},
83  {"K", "potassium", 39.0983},
84  {"Ca", "calcium", 40.078},
85  {"Sc", "scandium", 44.955908},
86  {"Ti", "titanium", 47.867},
87  {"V", "vanadium", 50.9415},
88  {"Cr", "chromium", 51.9961},
89  {"Mn", "manganese", 54.938043},
90  {"Fe", "iron", 55.845},
91  {"Co", "cobalt", 58.933194},
92  {"Ni", "nickel", 58.6934},
93  {"Cu", "copper", 63.546},
94  {"Zn", "zinc", 65.38},
95  {"Ga", "gallium", 69.723},
96  {"Ge", "germanium", 72.630},
97  {"As", "arsenic", 74.921595},
98  {"Se", "selenium", 78.971},
99  {"Br", "bromine", 79.904},
100  {"Kr", "krypton", 83.798},
101  {"Rb", "rubidium", 85.4678},
102  {"Sr", "strontium", 87.62},
103  {"Y", "yttrium", 88.90584},
104  {"Zr", "zirconium", 91.224},
105  {"Nb", "nobelium", 92.90637},
106  {"Mo", "molybdenum", 95.95},
107  {"Tc", "technetium", -1.0},
108  {"Ru", "ruthenium", 101.07},
109  {"Rh", "rhodium", 102.90549},
110  {"Pd", "palladium", 106.42},
111  {"Ag", "silver", 107.8682},
112  {"Cd", "cadmium", 112.414},
113  {"In", "indium", 114.818},
114  {"Sn", "tin", 118.710},
115  {"Sb", "antimony", 121.760},
116  {"Te", "tellurium", 127.60 },
117  {"I", "iodine", 126.90447},
118  {"Xe", "xenon", 131.293},
119  {"Cs", "cesium", 132.90545196},
120  {"Ba", "barium", 137.327},
121  {"La", "lanthanum", 138.90547},
122  {"Ce", "cerium", 140.116},
123  {"Pr", "praseodymium", 140.90766},
124  {"Nd", "neodymium", 144.242},
125  {"Pm", "promethium", -1.0},
126  {"Sm", "samarium", 150.36},
127  {"Eu", "europium", 151.964},
128  {"Gd", "gadolinium", 157.25},
129  {"Tb", "terbium", 158.925354},
130  {"Dy", "dysprosium", 162.500},
131  {"Ho", "holmium", 164.930328},
132  {"Er", "erbium", 167.259},
133  {"Tm", "thulium", 168.934218},
134  {"Yb", "ytterbium", 173.045},
135  {"Lu", "lutetium", 174.9668},
136  {"Hf", "hafnium", 178.49},
137  {"Ta", "tantalum", 180.94788},
138  {"W", "tungsten", 183.84},
139  {"Re", "rhenium", 186.207},
140  {"Os", "osmium", 190.23 },
141  {"Ir", "iridium", 192.217},
142  {"Pt", "platinum", 195.084},
143  {"Au", "gold", 196.966570},
144  {"Hg", "mercury", 200.592},
145  {"Tl", "thallium", 204.38},
146  {"Pb", "lead", 207.2 },
147  {"Bi", "bismuth", 208.98040},
148  {"Po", "polonium", -1.0},
149  {"At", "astatine", -1.0},
150  {"Rn", "radon", -1.0},
151  {"Fr", "francium", -1.0},
152  {"Ra", "radium", -1.0},
153  {"Ac", "actinium", -1.0},
154  {"Th", "thorium", 232.0377},
155  {"Pa", "protactinium", 231.03588},
156  {"U", "uranium", 238.02891},
157  {"Np", "neptunium", -1.0},
158  {"Pu", "plutonium", -1.0},
159  {"Am", "americium", -1.0},
160  {"Cm", "curium", -1.0},
161  {"Bk", "berkelium", -1.0},
162  {"Cf", "californium", -1.0},
163  {"Es", "einsteinium", -1.0},
164  {"Fm", "fermium", -1.0},
165  {"Md", "mendelevium", -1.0},
166  {"No", "nobelium", -1.0},
167  {"Lr", "lawrencium", -1.0},
168  {"Rf", "rutherfordium", -1.0},
169  {"Db", "dubnium", -1.0},
170  {"Sg", "seaborgium", -1.0},
171  {"Bh", "bohrium", -1.0},
172  {"Hs", "hassium", -1.0},
173  {"Mt", "meitnerium", -1.0},
174  {"Ds", "darmstadtium", -1.0},
175  {"Rg", "roentgenium", -1.0},
176  {"Cn", "copernicium", -1.0},
177  {"Nh", "nihonium", -1.0},
178  {"Gl", "flerovium", -1.0},
179  {"Mc", "moscovium", -1.0},
180  {"Lv", "livermorium", -1.0},
181  {"Ts", "tennessine", -1.0},
182  {"Og", "oganesson", -1.0},
183 };
184 
185 /**
186  * @var static vector<isotopeWeightData> isotopeWeightTable
187  * @brief isotopeWeightTable is a vector containing the atomic weights database.
188  *
189  * isotopeWeightTable is a static variable with scope limited to this file.
190  * It can only be referenced via the functions in this file.
191  *
192  * The size of the table is given by the initial instantiation.
193  */
194 static vector<isotopeWeightData> isotopeWeightTable {
195  // M. Wang et al. The AME2016 atomic mass evaluation. Chinese Physics C.
196  // doi:10.1088/1674-1137/41/3/030003.
197  {"D", "deuterium", 2.0141017781, 1},
198  {"Tr", "tritium", 3.0160492820, 1},
199  {"E", "electron", ElectronMass * Avogadro, 0},
200 };
201 
202 // This is implemented as a separate function from elementSymbols() because this pattern
203 // allows elementSymbols() to return a const reference to the data.
204 vector<string> elementVectorsFromSymbols() {
205  vector<string> values;
206  for (const auto& atom : atomicWeightTable) {
207  values.push_back(atom.symbol);
208  }
209  return values;
210 }
211 
212 const vector<string>& elementSymbols() {
213  const static vector<string> values = elementVectorsFromSymbols();
214  return values;
215 }
216 
217 // This is implemented as a separate function from elementNames() because this pattern
218 // allows elementNames() to return a const reference to the data.
219 vector<string> elementVectorsFromNames() {
220  vector<string> values;
221  for (const auto& atom : atomicWeightTable) {
222  values.push_back(atom.fullName);
223  }
224  return values;
225 }
226 
227 const vector<string>& elementNames() {
228  const static vector<string> values = elementVectorsFromNames();
229  return values;
230 }
231 
232 map<string, double> mapAtomicWeights() {
233  map<string, double> symMap;
234 
235  for (auto const& atom : atomicWeightTable) {
236  symMap.emplace(atom.symbol, atom.atomicWeight);
237  symMap.emplace(atom.fullName, atom.atomicWeight);
238  }
239  for (auto const& isotope : isotopeWeightTable) {
240  symMap.emplace(isotope.symbol, isotope.atomicWeight);
241  symMap.emplace(isotope.fullName, isotope.atomicWeight);
242  }
243  return symMap;
244 }
245 
246 const map<string, double>& elementWeights() {
247  const static map<string, double> symMap = mapAtomicWeights();
248  return symMap;
249 }
250 
251 double getElementWeight(const string& ename)
252 {
253  const auto& elementMap = elementWeights();
254  double elementWeight = 0.0;
255  string symbol = trimCopy(ename);
256  auto search = elementMap.find(symbol);
257  if (search != elementMap.end()) {
258  elementWeight = search->second;
259  } else {
260  string name = toLowerCopy(symbol);
261  search = elementMap.find(name);
262  if (search != elementMap.end()) {
263  elementWeight = search->second;
264  }
265  }
266  if (elementWeight > 0.0) {
267  return elementWeight;
268  } else if (elementWeight < 0.0) {
269  throw CanteraError("getElementWeight",
270  "element '{}' has no stable isotopes", ename);
271  }
272  throw CanteraError("getElementWeight", "element not found: " + ename);
273 }
274 
275 double getElementWeight(int atomicNumber)
276 {
277  int num = static_cast<int>(numElementsDefined());
278  if (atomicNumber > num || atomicNumber < 1) {
279  throw IndexError("getElementWeight", "atomicWeightTable", atomicNumber, num);
280  }
281  double elementWeight = atomicWeightTable[atomicNumber - 1].atomicWeight;
282  if (elementWeight < 0.0) {
283  throw CanteraError("getElementWeight",
284  "element '{}' has no stable isotopes", getElementName(atomicNumber));
285  }
286  return elementWeight;
287 }
288 
289 string getElementSymbol(const string& ename)
290 {
291  string name = toLowerCopy(trimCopy(ename));
292  for (const auto& atom : atomicWeightTable) {
293  if (name == atom.fullName) {
294  return atom.symbol;
295  }
296  }
297  for (const auto& atom : isotopeWeightTable) {
298  if (name == atom.fullName) {
299  return atom.symbol;
300  }
301  }
302  throw CanteraError("getElementSymbol", "element not found: " + ename);
303 }
304 
305 string getElementSymbol(int atomicNumber)
306 {
307  int num = static_cast<int>(numElementsDefined());
308  if (atomicNumber > num || atomicNumber < 1) {
309  throw IndexError("getElementSymbol", "atomicWeightTable", atomicNumber, num);
310  }
311  return atomicWeightTable[atomicNumber - 1].symbol;
312 }
313 
314 string getElementName(const string& ename)
315 {
316  string symbol = trimCopy(ename);
317  for (const auto& atom : atomicWeightTable) {
318  if (symbol == atom.symbol) {
319  return atom.fullName;
320  }
321  }
322  for (const auto& atom : isotopeWeightTable) {
323  if (symbol == atom.symbol) {
324  return atom.fullName;
325  }
326  }
327  throw CanteraError("getElementName", "element not found: " + ename);
328 }
329 
330 string getElementName(int atomicNumber)
331 {
332  int num = static_cast<int>(numElementsDefined());
333  if (atomicNumber > num || atomicNumber < 1) {
334  throw IndexError("getElementName", "atomicWeightTable", atomicNumber, num);
335  }
336  return atomicWeightTable[atomicNumber - 1].fullName;
337 }
338 
339 int getAtomicNumber(const string& ename)
340 {
341  size_t numElements = numElementsDefined();
342  size_t numIsotopes = numIsotopesDefined();
343  string symbol = trimCopy(ename);
344  string name = toLowerCopy(symbol);
345  for (size_t i = 0; i < numElements; i++) {
346  if (symbol == atomicWeightTable[i].symbol) {
347  return static_cast<int>(i) + 1;
348  } else if (name == atomicWeightTable[i].fullName) {
349  return static_cast<int>(i) + 1;
350  }
351  }
352  for (size_t i = 0; i < numIsotopes; i++) {
353  if (symbol == isotopeWeightTable[i].symbol) {
354  return isotopeWeightTable[i].atomicNumber;
355  } else if (name == isotopeWeightTable[i].fullName) {
356  return isotopeWeightTable[i].atomicNumber;
357  }
358  }
359  throw CanteraError("getAtomicNumber", "element not found: " + ename);
360 }
361 
363 {
364  return atomicWeightTable.size();
365 }
366 
368 {
369  return isotopeWeightTable.size();
370 }
371 
372 }
Contains the getElementWeight function and the definitions of element constraint types.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:66
An array index is out of range.
Definition: ctexceptions.h:165
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
string trimCopy(const string &input)
Trim.
string toLowerCopy(const string &input)
Convert to lower case.
const double Avogadro
Avogadro's Number [number/kmol].
Definition: ct_defs.h:81
const double ElectronMass
Electron Mass [kg].
Definition: ct_defs.h:111
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
double getElementWeight(const string &ename)
Get the atomic weight of an element.
Definition: Elements.cpp:251
static vector< atomicWeightData > atomicWeightTable
atomicWeightTable is a vector containing the atomic weights database.
Definition: Elements.cpp:64
int getAtomicNumber(const string &ename)
Get the atomic number for an element.
Definition: Elements.cpp:339
const vector< string > & elementNames()
Get a vector of the names of the elements defined in Cantera.
Definition: Elements.cpp:227
static vector< isotopeWeightData > isotopeWeightTable
isotopeWeightTable is a vector containing the atomic weights database.
Definition: Elements.cpp:194
string getElementName(const string &ename)
Get the name of an element.
Definition: Elements.cpp:314
size_t numElementsDefined()
Get the number of named elements defined in Cantera.
Definition: Elements.cpp:362
string getElementSymbol(const string &ename)
Get the symbol for an element.
Definition: Elements.cpp:289
const map< string, double > & elementWeights()
Get a map with the element and isotope symbols and names as keys and weights as values.
Definition: Elements.cpp:246
const vector< string > & elementSymbols()
Get a vector of the atomic symbols of the elements defined in Cantera.
Definition: Elements.cpp:212
size_t numIsotopesDefined()
Get the number of named isotopes defined in Cantera.
Definition: Elements.cpp:367
Contains declarations for string manipulation functions within Cantera.
Database for atomic weights.
Definition: Elements.cpp:34
string fullName
Element full name, first letter lowercase.
Definition: Elements.cpp:36
string symbol
Element symbol, first letter capitalized.
Definition: Elements.cpp:35
double atomicWeight
Element atomic weight in kg / kg-mol, if known. -1 if no stable isotope.
Definition: Elements.cpp:37
Database for named isotopic weights.
Definition: Elements.cpp:48
int atomicNumber
Isotope atomic number.
Definition: Elements.cpp:52
string fullName
Isotope full name, first letter lowercase.
Definition: Elements.cpp:50
string symbol
Isotope symbol, first letter capitalized.
Definition: Elements.cpp:49
double atomicWeight
Isotope atomic weight in kg / kg-mol.
Definition: Elements.cpp:51