Constituents.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifdef WIN32
00016 #pragma warning(disable:4786)
00017 #endif
00018
00019 #include "Constituents.h"
00020 #include "Elements.h"
00021 using namespace std;
00022
00023 namespace Cantera {
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 Constituents::Constituents(Elements* ptr_Elements) :
00050 m_kk(0),
00051 m_speciesFrozen(false) ,
00052 m_Elements(ptr_Elements)
00053 {
00054 if (!m_Elements) m_Elements = new Elements();
00055
00056
00057
00058 m_Elements->subscribe();
00059 }
00060
00061
00062
00063
00064
00065
00066
00067 Constituents::~Constituents()
00068 {
00069 int ileft = m_Elements->unsubscribe();
00070
00071
00072
00073
00074
00075 if (ileft <= 0) {
00076 vector<Elements *>::iterator it;
00077 for (it = Elements::Global_Elements_List.begin();
00078 it != Elements::Global_Elements_List.end(); ++it) {
00079 if (*it == m_Elements) {
00080 Elements::Global_Elements_List.erase(it);
00081 break;
00082 }
00083 }
00084 delete m_Elements;
00085 }
00086 }
00087
00088 int Constituents::nElements() const { return m_Elements->nElements(); }
00089
00090
00091
00092
00093
00094
00095 doublereal Constituents::atomicWeight(int m) const {
00096 return m_Elements->atomicWeight(m);
00097 }
00098
00099
00100 doublereal Constituents::entropyElement298(int m) const {
00101 return m_Elements->entropyElement298(m);
00102 }
00103
00104
00105
00106
00107
00108
00109 const vector_fp& Constituents::atomicWeights() const {
00110 return m_Elements->atomicWeights();
00111 }
00112
00113
00114
00115
00116
00117 int Constituents::atomicNumber(int m) const {
00118 return m_Elements->atomicNumber(m);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 void Constituents::
00132 addElement(const std::string& symbol, doublereal weight)
00133 {
00134 m_Elements->addElement(symbol, weight);
00135 }
00136
00137 void Constituents::
00138 addElement(const XML_Node& e)
00139 {
00140 m_Elements->addElement(e);
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void Constituents::
00157 addUniqueElement(const std::string& symbol, doublereal weight,
00158 int atomicNumber, doublereal entropy298)
00159 {
00160 m_Elements->addUniqueElement(symbol, weight, atomicNumber, entropy298);
00161 }
00162
00163 void Constituents::
00164 addUniqueElement(const XML_Node& e)
00165 {
00166 m_Elements->addUniqueElement(e);
00167 }
00168
00169 void Constituents::addElementsFromXML(const XML_Node& phase) {
00170 m_Elements->addElementsFromXML(phase);
00171 }
00172
00173
00174
00175
00176 void Constituents::freezeElements() {
00177 m_Elements->freezeElements();
00178 }
00179
00180
00181
00182
00183 bool Constituents::elementsFrozen() {
00184 return m_Elements->elementsFrozen();
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 int Constituents::elementIndex(std::string name) const {
00198 return (m_Elements->elementIndex(name));
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 string Constituents::elementName(int m) const {
00210 return (m_Elements->elementName(m));
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 const vector<string>& Constituents::elementNames() const {
00230 return m_Elements->elementNames();
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240 doublereal Constituents::molecularWeight(int k) const {
00241 if (k < 0 || k >= nSpecies()) {
00242 throw SpeciesRangeError("Constituents::molecularWeight",
00243 k, nSpecies());
00244 }
00245 return m_weight[k];
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 const array_fp& Constituents::molecularWeights() const {
00257 return m_weight;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 doublereal Constituents::charge(int k) const {
00267 return m_speciesCharge[k];
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 void Constituents::
00288 addSpecies(const std::string& name, const doublereal* comp,
00289 doublereal charge, doublereal size) {
00290 m_Elements->freezeElements();
00291 m_speciesNames.push_back(name);
00292 m_speciesCharge.push_back(charge);
00293 m_speciesSize.push_back(size);
00294 int m_mm = m_Elements->nElements();
00295
00296 vector_fp compNew(m_mm);
00297 for (int m = 0; m < m_mm; m++) {
00298 compNew[m] = comp[m];
00299 }
00300 double wt = 0.0;
00301 const vector_fp &aw = m_Elements->atomicWeights();
00302 if (charge != 0.0) {
00303 int eindex = m_Elements->elementIndex("E");
00304 if (eindex >= 0) {
00305 doublereal ecomp = compNew[eindex];
00306 if (fabs (charge + ecomp) > 0.001) {
00307 if (ecomp != 0.0) {
00308 throw CanteraError("Constituents::addSpecies",
00309 "Input charge and element E compositions differ for species " + name);
00310 } else {
00311
00312 compNew[eindex] = -charge;
00313 }
00314 }
00315 } else {
00316 m_Elements->m_elementsFrozen = false;
00317 addUniqueElement("E", 0.000545, 0, 0.0);
00318 m_Elements->m_elementsFrozen = true;
00319 m_mm = m_Elements->nElements();
00320 if (m_kk > 0) {
00321 vector_fp old(m_speciesComp);
00322 m_speciesComp.resize(m_kk*m_mm, 0.0);
00323 for (int k = 0; k < m_kk; k++) {
00324 int m_old = m_mm - 1;
00325 for (int m = 0; m < m_old; m++) {
00326 m_speciesComp[k * m_mm + m] = old[k * (m_old) + m];
00327 }
00328 m_speciesComp[k * (m_mm) + (m_mm-1)] = 0.0;
00329 }
00330 }
00331 eindex = m_Elements->elementIndex("E");
00332 compNew.resize(m_mm);
00333 compNew[m_mm-1] = - charge;
00334
00335
00336
00337 }
00338 }
00339 for (int m = 0; m < m_mm; m++) {
00340 m_speciesComp.push_back(compNew[m]);
00341 wt += compNew[m] * aw[m];
00342 }
00343 m_weight.push_back(wt);
00344 m_kk++;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 void Constituents::
00357 addUniqueSpecies(const std::string& name, const doublereal* comp,
00358 doublereal charge, doublereal size) {
00359 vector<string>::const_iterator it = m_speciesNames.begin();
00360 for (int k = 0; k < m_kk; k++) {
00361 if (*it == name) {
00362
00363
00364
00365
00366
00367 int m_mm = m_Elements->nElements();
00368 for (int i = 0; i < m_mm; i++) {
00369 if (comp[i] != m_speciesComp[m_kk * m_mm + i]) {
00370 throw CanteraError("addUniqueSpecies",
00371 "Duplicate species have different "
00372 "compositions: " + *it);
00373 }
00374 }
00375 if (charge != m_speciesCharge[m_kk]) {
00376 throw CanteraError("addUniqueSpecies",
00377 "Duplicate species have different "
00378 "charges: " + *it);
00379 }
00380 if (size != m_speciesSize[m_kk]) {
00381 throw CanteraError("addUniqueSpecies",
00382 "Duplicate species have different "
00383 "sizes: " + *it);
00384 }
00385 return;
00386 }
00387 ++it;
00388 }
00389 addSpecies(name, comp, charge, size);
00390 }
00391
00392
00393
00394
00395
00396
00397
00398 void Constituents::freezeSpecies() {
00399 m_speciesFrozen = true;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 int Constituents::speciesIndex(std::string name) const {
00415 vector<string>::const_iterator it = m_speciesNames.begin();
00416 for (int k = 0; k < m_kk; k++) {
00417 if (*it == name) {
00418
00419
00420
00421 return k;
00422 }
00423 ++it;
00424 }
00425 return -1;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 string Constituents::speciesName(int k) const {
00435 if (k < 0 || k >= nSpecies())
00436 throw SpeciesRangeError("Constituents::speciesName",
00437 k, nSpecies());
00438 return m_speciesNames[k];
00439 }
00440
00441
00442
00443
00444
00445
00446
00447 const vector<string>& Constituents::speciesNames() const {
00448 return m_speciesNames;
00449 }
00450
00451
00452
00453
00454
00455
00456 bool Constituents::ready() const {
00457 return (m_Elements->elementsFrozen() && m_speciesFrozen);
00458 }
00459
00460
00461
00462
00463 doublereal Constituents::nAtoms(int k, int m) const
00464 {
00465 const int m_mm = m_Elements->nElements();
00466 if (m < 0 || m >=m_mm)
00467 throw ElementRangeError("Constituents::nAtoms",m,nElements());
00468 if (k < 0 || k >= nSpecies())
00469 throw SpeciesRangeError("Constituents::nAtoms",k,nSpecies());
00470 return m_speciesComp[m_mm * k + m];
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480 void Constituents::getAtoms(int k, double *atomArray) const
00481 {
00482 const int m_mm = m_Elements->nElements();
00483 for (int m = 0; m < m_mm; m++) {
00484 atomArray[m] = (double) m_speciesComp[m_mm * k + m];
00485 }
00486 }
00487
00488
00489
00490
00491
00492
00493 Constituents::Constituents(const Constituents& right) :
00494 m_kk(0),
00495 m_speciesFrozen(false),
00496 m_Elements(0)
00497 {
00498 *this = right;
00499 }
00500
00501
00502
00503
00504
00505
00506 Constituents& Constituents::operator=(const Constituents& right) {
00507
00508
00509
00510 if (this == &right) return *this;
00511
00512
00513
00514
00515 m_kk = right.m_kk;
00516 m_weight = right.m_weight;
00517 m_speciesFrozen = right.m_speciesFrozen;
00518 if (m_Elements) {
00519 int nleft = m_Elements->unsubscribe();
00520 if (nleft <= 0) {
00521 vector<Elements *>::iterator it;
00522 for (it = Elements::Global_Elements_List.begin();
00523 it != Elements::Global_Elements_List.end(); ++it) {
00524 if (*it == m_Elements) {
00525 Elements::Global_Elements_List.erase(it);
00526 break;
00527 }
00528 }
00529 delete m_Elements;
00530 }
00531 }
00532 m_Elements = right.m_Elements;
00533 if (m_Elements) {
00534 m_Elements->subscribe();
00535 }
00536 m_speciesNames = right.m_speciesNames;
00537 m_speciesComp = right.m_speciesComp;
00538 m_speciesCharge = right.m_speciesCharge;
00539 m_speciesSize = right.m_speciesSize;
00540
00541
00542
00543 return *this;
00544 }
00545
00546
00547 }