void Phase::addSpecies(const std::string& name_, const doublereal* comp, doublereal charge_, doublereal size_) { freezeElements(); m_speciesNames.push_back(name_); m_speciesCharge.push_back(charge_); m_speciesSize.push_back(size_); size_t ne = nElements(); // Create a changeable copy of the element composition. We now change // the charge potentially vector_fp compNew(ne); for (size_t m = 0; m < ne; m++) { compNew[m] = comp[m]; } double wt = 0.0; const vector_fp& aw = atomicWeights(); if (charge_ != 0.0) { size_t eindex = elementIndex("E"); if (eindex != npos) { doublereal ecomp = compNew[eindex]; if (fabs(charge_ + ecomp) > 0.001) { if (ecomp != 0.0) { throw CanteraError("Phase::addSpecies", "Input charge and element E compositions differ " "for species " + name_); } else { // Just fix up the element E composition based on the input // species charge compNew[eindex] = -charge_; } } } else { addUniqueElementAfterFreeze("E", 0.000545, 0, 0.0, CT_ELEM_TYPE_ELECTRONCHARGE); ne = nElements(); eindex = elementIndex("E"); compNew.resize(ne); compNew[ne - 1] = - charge_; } } for (size_t m = 0; m < ne; m++) { m_speciesComp.push_back(compNew[m]); wt += compNew[m] * aw[m]; } m_molwts.push_back(wt); m_kk++; }
bool Phase::addSpecies(shared_ptr<Species> spec) { m_species[spec->name] = spec; vector_fp comp(nElements()); for (const auto& elem : spec->composition) { size_t m = elementIndex(elem.first); if (m == npos) { // Element doesn't exist in this phase switch (m_undefinedElementBehavior) { case UndefElement::ignore: return false; case UndefElement::add: addElement(elem.first); comp.resize(nElements()); m = elementIndex(elem.first); break; case UndefElement::error: default: throw CanteraError("Phase::addSpecies", "Species '{}' contains an undefined element '{}'.", spec->name, elem.first); } } comp[m] = elem.second; } m_speciesNames.push_back(spec->name); m_speciesIndices[spec->name] = m_kk; m_speciesCharge.push_back(spec->charge); m_speciesSize.push_back(spec->size); size_t ne = nElements(); double wt = 0.0; const vector_fp& aw = atomicWeights(); if (spec->charge != 0.0) { size_t eindex = elementIndex("E"); if (eindex != npos) { doublereal ecomp = comp[eindex]; if (fabs(spec->charge + ecomp) > 0.001) { if (ecomp != 0.0) { throw CanteraError("Phase::addSpecies", "Input charge and element E compositions differ " "for species " + spec->name); } else { // Just fix up the element E composition based on the input // species charge comp[eindex] = -spec->charge; } } } else { addElement("E", 0.000545, 0, 0.0, CT_ELEM_TYPE_ELECTRONCHARGE); ne = nElements(); eindex = elementIndex("E"); comp.resize(ne); comp[ne - 1] = - spec->charge; } } for (size_t m = 0; m < ne; m++) { m_speciesComp.push_back(comp[m]); wt += comp[m] * aw[m]; } // Some surface phases may define species representing empty sites // that have zero molecular weight. Give them a very small molecular // weight to avoid dividing by zero. wt = std::max(wt, Tiny); m_molwts.push_back(wt); m_rmolwts.push_back(1.0/wt); m_kk++; // Ensure that the Phase has a valid mass fraction vector that sums to // one. We will assume that species 0 has a mass fraction of 1.0 and mass // fraction of all other species is 0.0. if (m_kk == 1) { m_y.push_back(1.0); m_ym.push_back(m_rmolwts[0]); m_mmw = 1.0 / m_ym[0]; } else { m_y.push_back(0.0); m_ym.push_back(0.0); } invalidateCache(); return true; }