/* * The Cl- species is special in the sense that its single ion * molality-based activity coefficient is used in the specification * of the pH scale for single ions. Therefore, we need to know * what species index Cl- is. If the species isn't in the species * list then this routine returns -1, and we can't use the NBS * pH scale. * * Right now we use a restrictive interpretation. The species * must be named "Cl-". It must consist of exactly one Cl and one E * atom. */ size_t MolalityVPSSTP::findCLMIndex() const { size_t indexCLM = npos; size_t eCl = npos; size_t eE = npos; size_t ne = nElements(); string sn; for (size_t e = 0; e < ne; e++) { sn = elementName(e); if (sn == "Cl" || sn == "CL") { eCl = e; break; } } // We have failed if we can't find the Cl element index if (eCl == npos) { return npos; } for (size_t e = 0; e < ne; e++) { sn = elementName(e); if (sn == "E" || sn == "e") { eE = e; break; } } // We have failed if we can't find the E element index if (eE == npos) { return npos; } for (size_t k = 1; k < m_kk; k++) { doublereal nCl = nAtoms(k, eCl); if (nCl != 1.0) { continue; } doublereal nE = nAtoms(k, eE); if (nE != 1.0) { continue; } for (size_t e = 0; e < ne; e++) { if (e != eE && e != eCl) { doublereal nA = nAtoms(k, e); if (nA != 0.0) { continue; } } } sn = speciesName(k); if (sn != "Cl-" && sn != "CL-") { continue; } indexCLM = k; break; } return indexCLM; }
void MineralEQ3::convertDGFormation() { /* * Ok let's get the element compositions and conversion factors. */ int ne = nElements(); doublereal na; doublereal ge; string ename; doublereal totalSum = 0.0; for (int m = 0; m < ne; m++) { na = nAtoms(0, m); if (na > 0.0) { ename = elementName(m); ge = LookupGe(ename); totalSum += na * ge; } } // Add in the charge // if (m_charge_j != 0.0) { // ename = "H"; // ge = LookupGe(ename); // totalSum -= m_charge_j * ge; //} // Ok, now do the calculation. Convert to joules kmol-1 doublereal dg = m_deltaG_formation_pr_tr * 4.184 * 1.0E3; //! Store the result into an internal variable. m_Mu0_pr_tr = dg + totalSum; }
void MineralEQ3::convertDGFormation() { // Ok let's get the element compositions and conversion factors. doublereal totalSum = 0.0; for (size_t m = 0; m < nElements(); m++) { double na = nAtoms(0, m); if (na > 0.0) { totalSum += na * LookupGe(elementName(m)); } } // Ok, now do the calculation. Convert to joules kmol-1 doublereal dg = m_deltaG_formation_pr_tr * toSI("cal/gmol"); //! Store the result into an internal variable. m_Mu0_pr_tr = dg + totalSum; double Hcalc = m_Mu0_pr_tr + 298.15 * m_Entrop_pr_tr * toSI("cal/gmol"); double DHjmol = m_deltaH_formation_pr_tr * toSI("kal/gmol"); // If the discrepancy is greater than 100 cal gmol-1, print an error if (fabs(Hcalc -DHjmol) > 100 * toSI("cal/gmol")) { throw CanteraError("installMinEQ3asShomateThermoFromXML()", "DHjmol is not consistent with G and S: {} vs {}", Hcalc, DHjmol); } }
void System::writeToXYZ(const std::string& filename) { std::ofstream ofile(filename); // Header ofile << nAtoms() << std::endl; ofile << "Comment" << std::endl; // Atoms for (Atom *atom : m_atoms) { ofile << atom->getIndex() << " "; for (uint i = 0; i < 3; i++) { ofile << atom->getPosition()[i] << " "; } for (uint i = 0; i < 3; i++) { ofile << atom->getVelocity()[i] << " "; } for (uint i = 0; i < 3; i++) { ofile << atom->getForce()[i] << " "; } ofile << atom->getVelocity().length() << " "; ofile << atom->getForce().length() << " "; ofile << std::endl; } }
doublereal Phase::elementalMoleFraction(const size_t m) const { checkElementIndex(m); double denom = 0; for (size_t k = 0; k < m_kk; k++) { double atoms = 0; for (size_t j = 0; j < nElements(); j++) { atoms += nAtoms(k, j); } denom += atoms * moleFraction(k); } doublereal numerator = 0.0; for (size_t k = 0; k != m_kk; ++k) { numerator += nAtoms(k, m) * moleFraction(k); } return numerator / denom; }
doublereal Phase::elementalMassFraction(const size_t m) const { checkElementIndex(m); doublereal Z_m = 0.0; for (size_t k = 0; k != m_kk; ++k) { Z_m += nAtoms(k, m) * atomicWeight(m) / molecularWeight(k) * massFraction(k); } return Z_m; }
void IdealSolidSolnPhase::setToEquilState(const doublereal* lambda_RT) { const vector_fp& grt = gibbs_RT_ref(); // set the pressure and composition to be consistent with // the temperature, doublereal pres = 0.0; for (size_t k = 0; k < m_kk; k++) { m_pp[k] = -grt[k]; for (size_t m = 0; m < nElements(); m++) { m_pp[k] += nAtoms(k,m)*lambda_RT[m]; } m_pp[k] = m_Pref * exp(m_pp[k]); pres += m_pp[k]; } setState_PX(pres, &m_pp[0]); }
void System::writeToXYZWithBoxID(const std::string& filename) { std::ofstream ofile(filename); if (!ofile.is_open()) { std::cout << "Error: Couldn't open file \"" << filename << "\" for writing." << std::endl; } else { // Header ofile << nAtoms() << std::endl; ofile << "Comment" << std::endl; // Atoms for (const NeighborList& list : m_integrator->getNeighborLists()) { for (const Atom *atom : list.getAtoms()) { ofile << atom->getIndex() << " "; for (uint i = 0; i < 3; i++) { ofile << atom->getPosition()[i] << " "; } for (uint i = 0; i < 3; i++) { ofile << atom->getVelocity()[i] << " "; } for (uint i = 0; i < 3; i++) { ofile << atom->getForce()[i] << " "; } ofile << atom->getVelocity().length() << " "; ofile << atom->getForce().length() << " "; ofile << list.getLinearIndex() << " "; ofile << std::endl; } } } }