void LatticeSolidPhase::initThermo() { size_t kk = 0; size_t kstart = 0; lkstart_.resize(m_lattice.size() + 1); size_t loc = 0; for (size_t n = 0; n < m_lattice.size(); n++) { LatticePhase* lp = m_lattice[n]; vector_fp constArr(lp->nElements()); const vector_fp& aws = lp->atomicWeights(); for (size_t es = 0; es < lp->nElements(); es++) { addElement(lp->elementName(es), aws[es], lp->atomicNumber(es), lp->entropyElement298(es), lp->elementType(es)); } kstart = kk; for (size_t k = 0; k < lp->nSpecies(); k++) { addSpecies(lp->species(k)); kk++; } // Add in the lattice stoichiometry constraint if (n > 0) { string econ = fmt::format("LC_{}_{}", n, id()); size_t m = addElement(econ, 0.0, 0, 0.0, CT_ELEM_TYPE_LATTICERATIO); size_t mm = nElements(); size_t nsp0 = m_lattice[0]->nSpecies(); for (size_t k = 0; k < nsp0; k++) { m_speciesComp[k * mm + m] = -theta_[0]; } for (size_t k = 0; k < lp->nSpecies(); k++) { size_t ks = kstart + k; m_speciesComp[ks * mm + m] = theta_[n]; } } size_t nsp = m_lattice[n]->nSpecies(); lkstart_[n] = loc; for (size_t k = 0; k < nsp; k++) { m_x[loc] =m_lattice[n]->moleFraction(k) / (double) m_lattice.size(); loc++; } lkstart_[n+1] = loc; } setMoleFractions(m_x.data()); ThermoPhase::initThermo(); }
void LatticeSolidPhase::installSlavePhases(Cantera::XML_Node* phaseNode) { size_t kk = 0; size_t kstart = 0; m_speciesData.clear(); XML_Node& eosdata = phaseNode->child("thermo"); XML_Node& la = eosdata.child("LatticeArray"); std::vector<XML_Node*> lattices = la.getChildren("phase"); for (size_t n = 0; n < m_nlattice; n++) { LatticePhase* lp = m_lattice[n]; size_t nsp = lp->nSpecies(); vector<doublereal> constArr(lp->nElements()); const vector_fp& aws = lp->atomicWeights(); for (size_t es = 0; es < lp->nElements(); es++) { string esName = lp->elementName(es); double wt = aws[es]; int an = lp->atomicNumber(es); int e298 = lp->entropyElement298(es); //! @todo Why is this an int instead of a double? int et = lp->elementType(es); addElement(esName, wt, an, e298, et); } const std::vector<const XML_Node*> & spNode = lp->speciesData(); kstart = kk; for (size_t k = 0; k < nsp; k++) { std::string sname = lp->speciesName(k); std::map<std::string, double> comp; lp->getAtoms(k, DATA_PTR(constArr)); size_t nel = nElements(); vector_fp ecomp(nel, 0.0); for (size_t m = 0; m < lp->nElements(); m++) { if (constArr[m] != 0.0) { std::string oldEname = lp->elementName(m); size_t newIndex = elementIndex(oldEname); if (newIndex == npos) { throw CanteraError("LatticeSolidPhase::installSlavePhases", "element not found"); } ecomp[newIndex] = constArr[m]; } } double chrg = lp->charge(k); double sz = lp->size(k); addUniqueSpecies(sname, &ecomp[0], chrg, sz); SpeciesThermoInterpType* stit = newSpeciesThermoInterpType(*spNode[k]); stit->setIndex(kk); stit->validate(spNode[k]->attrib("name")); m_spthermo->install_STIT(stit); m_speciesData.push_back(new XML_Node(*(spNode[k]))); kk++; } /* * Add in the lattice stoichiometry constraint */ if (n > 0) { string econ = "LC_"; econ += int2str(n); econ += "_" + id(); size_t m = addElement(econ, 0.0, 0, 0.0, CT_ELEM_TYPE_LATTICERATIO); size_t mm = nElements(); LatticePhase* lp0 = m_lattice[0]; size_t nsp0 = lp0->nSpecies(); for (size_t k = 0; k < nsp0; k++) { m_speciesComp[k * mm + m] = -theta_[0]; } for (size_t k = 0; k < nsp; k++) { size_t ks = kstart + k; m_speciesComp[ks * mm + m] = theta_[n]; } } } }