Exemplo n.º 1
0
  void SurfPhase::
  setCoveragesByName(std::string cov) {
    int kk = nSpecies();
    int k;
    compositionMap cc;
    for (k = 0; k < kk; k++) { 
      cc[speciesName(k)] = -1.0;
    }
    parseCompString(cov, cc);
    doublereal c;
    vector_fp cv(kk, 0.0);
    bool ifound = false;
    for (k = 0; k < kk; k++) { 
      c = cc[speciesName(k)];
      if (c > 0.0) {
	ifound = true;
	cv[k] = c;
      }
    }
    if (!ifound) {
      throw CanteraError("SurfPhase::setCoveragesByName",
			 "Input coverages are all zero or negative");
    }
    setCoverages(DATA_PTR(cv));
  }
void ThermoPhase::modifySpecies(size_t k, shared_ptr<Species> spec)
{
    Phase::modifySpecies(k, spec);
    if (speciesName(k) != spec->name) {
        throw CanteraError("ThermoPhase::modifySpecies",
            "New species '{}' does not match existing species '{}' at index {}",
                           spec->name, speciesName(k), k);
    }
    spec->thermo->validate(spec->name);
    m_spthermo->modifySpecies(k, spec->thermo);
}
Exemplo n.º 3
0
 /**
  * Get the mole fractions by name. 
  */
 void Phase::getMoleFractionsByName(compositionMap& x) const {
   x.clear();
   int kk = nSpecies();
   for (int k = 0; k < kk; k++) {
     x[speciesName(k)] = State::moleFraction(k);
   }
 }
Exemplo n.º 4
0
void Phase::modifySpecies(size_t k, shared_ptr<Species> spec)
{
    if (speciesName(k) != spec->name) {
        throw CanteraError("Phase::modifySpecies",
            "New species name '{}' does not match existing name '{}'",
                           spec->name, speciesName(k));
    }
    const shared_ptr<Species>& old = m_species[spec->name];
    if (spec->composition != old->composition) {
        throw CanteraError("Phase::modifySpecies",
            "New composition for '{}' does not match existing composition",
            spec->name);
    }
    m_species[spec->name] = spec;
    invalidateCache();
}
void ThermoPhase::reportCSV(std::ofstream& csvFile) const
{
    int tabS = 15;
    int tabM = 30;
    csvFile.precision(8);
    vector_fp X(nSpecies());
    getMoleFractions(&X[0]);
    std::vector<std::string> pNames;
    std::vector<vector_fp> data;
    getCsvReportData(pNames, data);

    csvFile << setw(tabS) << "Species,";
    for (size_t i = 0; i < pNames.size(); i++) {
        csvFile << setw(tabM) << pNames[i] << ",";
    }
    csvFile << endl;
    for (size_t k = 0; k < nSpecies(); k++) {
        csvFile << setw(tabS) << speciesName(k) + ",";
        if (X[k] > SmallNumber) {
            for (size_t i = 0; i < pNames.size(); i++) {
                csvFile << setw(tabM) << data[i][k] << ",";
            }
            csvFile << endl;
        } else {
            for (size_t i = 0; i < pNames.size(); i++) {
                csvFile << setw(tabM) << 0 << ",";
            }
            csvFile << endl;
        }
    }
}
Exemplo n.º 6
0
 void Phase::setMassFractionsByName(const std::string& y) {
   compositionMap yy;
   int kk = nSpecies();
   for (int k = 0; k < kk; k++) { 
     yy[speciesName(k)] = -1.0;
   }
   parseCompString(y, yy);
   setMassFractionsByName(yy);
 }
Exemplo n.º 7
0
/*
 * setMolalitiesByNames()
 *
 *   Set the molalities of the solutes by name
 */
void MolalityVPSSTP::setMolalitiesByName(const std::string& x)
{
    compositionMap xx;
    for (size_t k = 0; k < nSpecies(); k++) {
        xx[speciesName(k)] = -1.0;
    }
    parseCompString(x, xx);
    setMolalitiesByName(xx);
}
Exemplo n.º 8
0
void Phase::setMassFractionsByName(const compositionMap& yMap)
{
    size_t kk = nSpecies();
    vector_fp mf(kk, 0.0);
    for (size_t k = 0; k < kk; k++) {
        mf[k] = std::max(getValue(yMap, speciesName(k), 0.0), 0.0);
    }
    setMassFractions(&mf[0]);
}
Exemplo n.º 9
0
/*
 *  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;
}
Exemplo n.º 10
0
 void Phase::setMoleFractionsByName(compositionMap& xMap) {
   int kk = nSpecies();
   doublereal x;
   vector_fp mf(kk, 0.0);
   for (int k = 0; k < kk; k++) {
     x = xMap[speciesName(k)];
     if (x > 0.0) mf[k] = x;
   }
   setMoleFractions(&mf[0]);
 }
Exemplo n.º 11
0
void Phase::setMoleFractionsByName(const std::string& x)
{
    size_t kk = nSpecies();
    compositionMap xx;
    for (size_t k = 0; k < kk; k++) {
        xx[speciesName(k)] = -1.0;
    }
    parseCompString(x, xx);
    setMoleFractionsByName(xx);
}
Exemplo n.º 12
0
 void Phase::setMassFractionsByName(compositionMap& yMap) {
   int kk = nSpecies();
   doublereal y;
   vector_fp mf(kk, 0.0);
   for (int k = 0; k < kk; k++) { 
     y = yMap[speciesName(k)];
     if (y > 0.0) mf[k] = y;
   }
   setMassFractions(&mf[0]);
 }
Exemplo n.º 13
0
compositionMap Phase::getMassFractionsByName(double threshold) const
{
    compositionMap comp;
    for (size_t k = 0; k < m_kk; k++) {
        double x = massFraction(k);
        if (x > threshold) {
            comp[speciesName(k)] = x;
        }
    }
    return comp;
}
Exemplo n.º 14
0
void Phase::getMoleFractionsByName(compositionMap& x) const
{
    warn_deprecated("void Phase::getMoleFractionsByName(compositionMap&)",
                    "To be removed after Cantera 2.2. Use"
                    " 'compositionMap getMoleFractionsByName(double threshold)'"
                    " instead");
    x.clear();
    size_t kk = nSpecies();
    for (size_t k = 0; k < kk; k++) {
        x[speciesName(k)] = Phase::moleFraction(k);
    }
}
Exemplo n.º 15
0
 void Phase::setMoleFractionsByName(const std::string& x) {
   compositionMap xx;
   int kk = nSpecies();
   for (int k = 0; k < kk; k++) { 
     xx[speciesName(k)] = -1.0;
   }
   parseCompString(x, xx);
   setMoleFractionsByName(xx);
   //int kk = nSpecies();
   //vector_fp mf(kk);
   //for (int k = 0; k < kk; k++) { 
   //    mf[k] = xx[speciesName(k)];
   //}
   //setMoleFractions(mf.begin());
 }
void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string& id_)
{
    if (id_.size() > 0 && phaseNode.id() != id_) {
        throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
                           "phasenode and Id are incompatible");
    }

    // Check on the thermo field. Must have:
    // <thermo model="MaskellSolidSolution" />
    if (phaseNode.hasChild("thermo")) {
        XML_Node& thNode = phaseNode.child("thermo");
        if (!ba::iequals(thNode["model"], "maskellsolidsolnphase")) {
            throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
                               "Unknown thermo model: " + thNode["model"]);
        }

        // Parse the enthalpy of mixing constant
        if (thNode.hasChild("h_mix")) {
            set_h_mix(fpValue(thNode.child("h_mix").value()));
        } else {
            throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
                               "Mixing enthalpy parameter not specified.");
        }

        if (thNode.hasChild("product_species")) {
            setProductSpecies(thNode.child("product_species").value());
        } else {
            setProductSpecies(speciesName(0)); // default
        }
    } else {
        throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
                           "Unspecified thermo model");
    }

    // Confirm that the phase only contains 2 species
    if (m_kk != 2) {
        throw CanteraError("MaskellSolidSolnPhase::initThermoXML",
                "MaskellSolidSolution model requires exactly 2 species.");
    }

    // Call the base initThermo, which handles setting the initial state.
    VPStandardStateTP::initThermoXML(phaseNode, id_);
}
void LatticePhase::initThermoXML(XML_Node& phaseNode, const std::string& id_)
{
    if (!id_.empty() && id_ != phaseNode.id()) {
        throw CanteraError("LatticePhase::initThermoXML",
                           "ids don't match");
    }

    // Check on the thermo field. Must have:
    // <thermo model="Lattice" />
    if (phaseNode.hasChild("thermo")) {
        XML_Node& thNode = phaseNode.child("thermo");
        std::string mString = thNode.attrib("model");
        if (lowercase(mString) != "lattice") {
            throw CanteraError("LatticePhase::initThermoXML",
                               "Unknown thermo model: " + mString);
        }
    } else {
        throw CanteraError("LatticePhase::initThermoXML",
                           "Unspecified thermo model");
    }

    // Now go get the molar volumes. use the default if not found
    XML_Node& speciesList = phaseNode.child("speciesArray");
    XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"], &phaseNode.root());

    for (size_t k = 0; k < m_kk; k++) {
        m_speciesMolarVolume[k] = m_site_density;
        XML_Node* s = speciesDB->findByAttr("name", speciesName(k));
        if (!s) {
            throw CanteraError(" LatticePhase::initThermoXML", "database problems");
        }
        XML_Node* ss = s->findByName("standardState");
        if (ss && ss->findByName("molarVolume")) {
            m_speciesMolarVolume[k] = getFloat(*ss, "molarVolume", "toSI");
        }
    }

    // Call the base initThermo, which handles setting the initial state.
    ThermoPhase::initThermoXML(phaseNode, id_);
}
Exemplo n.º 18
0
std::string Phase::speciesSPName(int k) const
{
    return m_name + ":" + speciesName(k);
}
Exemplo n.º 19
0
void RedlichKisterVPSSTP::readXMLBinarySpecies(XML_Node& xmLBinarySpecies)
{
    std::string xname = xmLBinarySpecies.name();
    if (xname != "binaryNeutralSpeciesParameters") {
        throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies",
                           "Incorrect name for processing this routine: " + xname);
    }
    size_t Npoly = 0;
    vector_fp hParams, sParams;
    std::string iName = xmLBinarySpecies.attrib("speciesA");
    if (iName == "") {
        throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesA attrib");
    }
    std::string jName = xmLBinarySpecies.attrib("speciesB");
    if (jName == "") {
        throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesB attrib");
    }
    /*
     * Find the index of the species in the current phase. It's not
     * an error to not find the species. This means that the interaction doesn't occur for the current
     * implementation of the phase.
     */
    size_t iSpecies = speciesIndex(iName);
    if (iSpecies == npos) {
        return;
    }
    string ispName = speciesName(iSpecies);
    if (charge(iSpecies) != 0) {
        throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "speciesA charge problem");
    }
    size_t jSpecies = speciesIndex(jName);
    if (jSpecies == npos) {
        return;
    }
    std::string jspName = speciesName(jSpecies);
    if (charge(jSpecies) != 0) {
        throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "speciesB charge problem");
    }
    /*
     *  Ok we have found a valid interaction
     */
    numBinaryInteractions_++;
    size_t iSpot = numBinaryInteractions_ - 1;
    m_pSpecies_A_ij.resize(numBinaryInteractions_);
    m_pSpecies_B_ij.resize(numBinaryInteractions_);
    m_pSpecies_A_ij[iSpot] = iSpecies;
    m_pSpecies_B_ij[iSpot] = jSpecies;

    for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
        XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
        string nodeName = lowercase(xmlChild.name());
        /*
         * Process the binary species interaction child elements
         */
        if (nodeName == "excessenthalpy") {
            /*
             * Get the string containing all of the values
             */
            getFloatArray(xmlChild, hParams, true, "toSI", "excessEnthalpy");
            Npoly = std::max(hParams.size(), Npoly);
        }

        if (nodeName == "excessentropy") {
            /*
             * Get the string containing all of the values
             */
            getFloatArray(xmlChild, sParams, true, "toSI", "excessEntropy");
            Npoly = std::max(sParams.size(), Npoly);
        }
    }
    hParams.resize(Npoly, 0.0);
    sParams.resize(Npoly, 0.0);
    m_HE_m_ij.push_back(hParams);
    m_SE_m_ij.push_back(sParams);
    m_N_ij.push_back(Npoly);
    resizeNumInteractions(numBinaryInteractions_);
}
Exemplo n.º 20
0
/*
 * Format a summary of the mixture state for output.
 */
void MolalityVPSSTP::reportCSV(std::ofstream& csvFile) const
{


    csvFile.precision(3);
    int tabS = 15;
    int tabM = 30;
    int tabL = 40;
    try {
        if (name() != "") {
            csvFile << "\n"+name()+"\n\n";
        }
        csvFile << setw(tabL) << "temperature (K) =" << setw(tabS) << temperature() << endl;
        csvFile << setw(tabL) << "pressure (Pa) =" << setw(tabS) << pressure() << endl;
        csvFile << setw(tabL) << "density (kg/m^3) =" << setw(tabS) << density() << endl;
        csvFile << setw(tabL) << "mean mol. weight (amu) =" << setw(tabS) << meanMolecularWeight() << endl;
        csvFile << setw(tabL) << "potential (V) =" << setw(tabS) << electricPotential() << endl;
        csvFile << endl;

        csvFile << setw(tabL) << "enthalpy (J/kg) = " << setw(tabS) << enthalpy_mass() << setw(tabL) << "enthalpy (J/kmol) = " << setw(tabS) << enthalpy_mole() << endl;
        csvFile << setw(tabL) << "internal E (J/kg) = " << setw(tabS) << intEnergy_mass() << setw(tabL) << "internal E (J/kmol) = " << setw(tabS) << intEnergy_mole() << endl;
        csvFile << setw(tabL) << "entropy (J/kg) = " << setw(tabS) << entropy_mass() << setw(tabL) << "entropy (J/kmol) = " << setw(tabS) << entropy_mole() << endl;
        csvFile << setw(tabL) << "Gibbs (J/kg) = " << setw(tabS) << gibbs_mass() << setw(tabL) << "Gibbs (J/kmol) = " << setw(tabS) << gibbs_mole() << endl;
        csvFile << setw(tabL) << "heat capacity c_p (J/K/kg) = " << setw(tabS) << cp_mass() << setw(tabL) << "heat capacity c_p (J/K/kmol) = " << setw(tabS) << cp_mole() << endl;
        csvFile << setw(tabL) << "heat capacity c_v (J/K/kg) = " << setw(tabS) << cv_mass() << setw(tabL) << "heat capacity c_v (J/K/kmol) = " << setw(tabS) << cv_mole() << endl;

        csvFile.precision(8);

        vector<std::string> pNames;
        vector<vector_fp> data;
        vector_fp temp(nSpecies());

        getMoleFractions(&temp[0]);
        pNames.push_back("X");
        data.push_back(temp);
        try {
            getMolalities(&temp[0]);
            pNames.push_back("Molal");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getChemPotentials(&temp[0]);
            pNames.push_back("Chem. Pot. (J/kmol)");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getStandardChemPotentials(&temp[0]);
            pNames.push_back("Chem. Pot. SS (J/kmol)");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getMolalityActivityCoefficients(&temp[0]);
            pNames.push_back("Molal Act. Coeff.");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getActivities(&temp[0]);
            pNames.push_back("Molal Activity");
            data.push_back(temp);
            size_t iHp = speciesIndex("H+");
            if (iHp != npos) {
                double pH = -log(temp[iHp]) / log(10.0);
                csvFile << setw(tabL) << "pH = " << setw(tabS) << pH << endl;
            }
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getPartialMolarEnthalpies(&temp[0]);
            pNames.push_back("Part. Mol Enthalpy (J/kmol)");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getPartialMolarEntropies(&temp[0]);
            pNames.push_back("Part. Mol. Entropy (J/K/kmol)");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getPartialMolarIntEnergies(&temp[0]);
            pNames.push_back("Part. Mol. Energy (J/kmol)");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getPartialMolarCp(&temp[0]);
            pNames.push_back("Part. Mol. Cp (J/K/kmol");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }
        try {
            getPartialMolarVolumes(&temp[0]);
            pNames.push_back("Part. Mol. Cv (J/K/kmol)");
            data.push_back(temp);
        } catch (CanteraError& err) {
            err.save();
        }

        csvFile << endl << setw(tabS) << "Species,";
        for (size_t i = 0; i < pNames.size(); i++) {
            csvFile << setw(tabM) << pNames[i] << ",";
        }
        csvFile << endl;
        /*
        csvFile.fill('-');
        csvFile << setw(tabS+(tabM+1)*pNames.size()) << "-\n";
        csvFile.fill(' ');
        */
        for (size_t k = 0; k < nSpecies(); k++) {
            csvFile << setw(tabS) << speciesName(k) + ",";
            if (data[0][k] > SmallNumber) {
                for (size_t i = 0; i < pNames.size(); i++) {
                    csvFile << setw(tabM) << data[i][k] << ",";
                }
                csvFile << endl;
            } else {
                for (size_t i = 0; i < pNames.size(); i++) {
                    csvFile << setw(tabM) << 0 << ",";
                }
                csvFile << endl;
            }
        }
    } catch (CanteraError& err) {
        err.save();
    }
}
Exemplo n.º 21
0
/**
  * Format a summary of the mixture state for output.
  */
std::string MolalityVPSSTP::report(bool show_thermo) const
{


    char p[800];
    string s = "";
    try {
        if (name() != "") {
            sprintf(p, " \n  %s:\n", name().c_str());
            s += p;
        }
        sprintf(p, " \n       temperature    %12.6g  K\n", temperature());
        s += p;
        sprintf(p, "          pressure    %12.6g  Pa\n", pressure());
        s += p;
        sprintf(p, "           density    %12.6g  kg/m^3\n", density());
        s += p;
        sprintf(p, "  mean mol. weight    %12.6g  amu\n", meanMolecularWeight());
        s += p;

        doublereal phi = electricPotential();
        sprintf(p, "         potential    %12.6g  V\n", phi);
        s += p;

        size_t kk = nSpecies();
        vector_fp x(kk);
        vector_fp molal(kk);
        vector_fp mu(kk);
        vector_fp muss(kk);
        vector_fp acMolal(kk);
        vector_fp actMolal(kk);
        getMoleFractions(&x[0]);
        getMolalities(&molal[0]);
        getChemPotentials(&mu[0]);
        getStandardChemPotentials(&muss[0]);
        getMolalityActivityCoefficients(&acMolal[0]);
        getActivities(&actMolal[0]);

        size_t iHp = speciesIndex("H+");
        if (iHp != npos) {
            double pH = -log(actMolal[iHp]) / log(10.0);
            sprintf(p, "                pH    %12.4g  \n", pH);
            s += p;
        }

        if (show_thermo) {
            sprintf(p, " \n");
            s += p;
            sprintf(p, "                          1 kg            1 kmol\n");
            s += p;
            sprintf(p, "                       -----------      ------------\n");
            s += p;
            sprintf(p, "          enthalpy    %12.6g     %12.4g     J\n",
                    enthalpy_mass(), enthalpy_mole());
            s += p;
            sprintf(p, "   internal energy    %12.6g     %12.4g     J\n",
                    intEnergy_mass(), intEnergy_mole());
            s += p;
            sprintf(p, "           entropy    %12.6g     %12.4g     J/K\n",
                    entropy_mass(), entropy_mole());
            s += p;
            sprintf(p, "    Gibbs function    %12.6g     %12.4g     J\n",
                    gibbs_mass(), gibbs_mole());
            s += p;
            sprintf(p, " heat capacity c_p    %12.6g     %12.4g     J/K\n",
                    cp_mass(), cp_mole());
            s += p;
            try {
                sprintf(p, " heat capacity c_v    %12.6g     %12.4g     J/K\n",
                        cv_mass(), cv_mole());
                s += p;
            } catch (CanteraError& err) {
                err.save();
                sprintf(p, " heat capacity c_v    <not implemented>       \n");
                s += p;
            }
        }

        sprintf(p, " \n");
        s += p;
        if (show_thermo) {
            sprintf(p, "                           X        "
                    "   Molalities         Chem.Pot.    ChemPotSS    ActCoeffMolal\n");
            s += p;
            sprintf(p, "                                    "
                    "                      (J/kmol)      (J/kmol)                 \n");
            s += p;
            sprintf(p, "                     -------------  "
                    "  ------------     ------------  ------------    ------------\n");
            s += p;
            for (size_t k = 0; k < kk; k++) {
                if (x[k] > SmallNumber) {
                    sprintf(p, "%18s  %12.6g     %12.6g     %12.6g   %12.6g   %12.6g\n",
                            speciesName(k).c_str(), x[k], molal[k], mu[k], muss[k], acMolal[k]);
                } else {
                    sprintf(p, "%18s  %12.6g     %12.6g          N/A      %12.6g   %12.6g \n",
                            speciesName(k).c_str(), x[k], molal[k], muss[k], acMolal[k]);
                }
                s += p;
            }
        } else {
            sprintf(p, "                           X"
                    "Molalities\n");
            s += p;
            sprintf(p, "                     -------------"
                    "     ------------\n");
            s += p;
            for (size_t k = 0; k < kk; k++) {
                sprintf(p, "%18s   %12.6g     %12.6g\n",
                        speciesName(k).c_str(), x[k], molal[k]);
                s += p;
            }
        }
    } catch (CanteraError& err) {
        err.save();
    }
    return s;
}
Exemplo n.º 22
0
std::string Phase::speciesSPName(int k) const
{
    std::string sn = speciesName(k);
    return m_name + ":" + sn;
}
Exemplo n.º 23
0
std::string ThermoPhase::report(bool show_thermo, doublereal threshold) const
{
    fmt::MemoryWriter b;
    try {
        if (name() != "") {
            b.write("\n  {}:\n", name());
        }
        b.write("\n");
        b.write("       temperature    {:12.6g}  K\n", temperature());
        b.write("          pressure    {:12.6g}  Pa\n", pressure());
        b.write("           density    {:12.6g}  kg/m^3\n", density());
        b.write("  mean mol. weight    {:12.6g}  amu\n", meanMolecularWeight());

        doublereal phi = electricPotential();
        if (phi != 0.0) {
            b.write("         potential    {:12.6g}  V\n", phi);
        }
        if (show_thermo) {
            b.write("\n");
            b.write("                          1 kg            1 kmol\n");
            b.write("                       -----------      ------------\n");
            b.write("          enthalpy    {:12.5g}     {:12.4g}     J\n",
                    enthalpy_mass(), enthalpy_mole());
            b.write("   internal energy    {:12.5g}     {:12.4g}     J\n",
                    intEnergy_mass(), intEnergy_mole());
            b.write("           entropy    {:12.5g}     {:12.4g}     J/K\n",
                    entropy_mass(), entropy_mole());
            b.write("    Gibbs function    {:12.5g}     {:12.4g}     J\n",
                    gibbs_mass(), gibbs_mole());
            b.write(" heat capacity c_p    {:12.5g}     {:12.4g}     J/K\n",
                    cp_mass(), cp_mole());
            try {
                b.write(" heat capacity c_v    {:12.5g}     {:12.4g}     J/K\n",
                        cv_mass(), cv_mole());
            } catch (NotImplementedError&) {
                b.write(" heat capacity c_v    <not implemented>       \n");
            }
        }

        vector_fp x(m_kk);
        vector_fp y(m_kk);
        vector_fp mu(m_kk);
        getMoleFractions(&x[0]);
        getMassFractions(&y[0]);
        getChemPotentials(&mu[0]);
        int nMinor = 0;
        doublereal xMinor = 0.0;
        doublereal yMinor = 0.0;
        b.write("\n");
        if (show_thermo) {
            b.write("                           X     "
                    "            Y          Chem. Pot. / RT\n");
            b.write("                     -------------     "
                    "------------     ------------\n");
            for (size_t k = 0; k < m_kk; k++) {
                if (abs(x[k]) >= threshold) {
                    if (abs(x[k]) > SmallNumber) {
                        b.write("{:>18s}   {:12.6g}     {:12.6g}     {:12.6g}\n",
                                speciesName(k), x[k], y[k], mu[k]/RT());
                    } else {
                        b.write("{:>18s}   {:12.6g}     {:12.6g}\n",
                                speciesName(k), x[k], y[k]);
                    }
                } else {
                    nMinor++;
                    xMinor += x[k];
                    yMinor += y[k];
                }
            }
        } else {
            b.write("                           X                 Y\n");
            b.write("                     -------------     ------------\n");
            for (size_t k = 0; k < m_kk; k++) {
                if (abs(x[k]) >= threshold) {
                    b.write("{:>18s}   {:12.6g}     {:12.6g}\n",
                            speciesName(k), x[k], y[k]);
                } else {
                    nMinor++;
                    xMinor += x[k];
                    yMinor += y[k];
                }
            }
        }
        if (nMinor) {
            b.write("     [{:+5d} minor]   {:12.6g}     {:12.6g}\n",
                    nMinor, xMinor, yMinor);
        }
    } catch (CanteraError& err) {
        return b.str() + err.what();
    }
    return b.str();
}
Exemplo n.º 24
0
void IdealSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string& id_)
{
    if (id_.size() > 0 && phaseNode.id() != id_) {
        throw CanteraError("IdealSolidSolnPhase::initThermoXML",
                           "phasenode and Id are incompatible");
    }

    /*
     * Check on the thermo field. Must have:
     * <thermo model="IdealSolidSolution" />
     */
    if (phaseNode.hasChild("thermo")) {
        XML_Node& thNode = phaseNode.child("thermo");
        string mString = thNode.attrib("model");
        if (lowercase(mString) != "idealsolidsolution") {
            throw CanteraError("IdealSolidSolnPhase::initThermoXML",
                               "Unknown thermo model: " + mString);
        }
    } else {
        throw CanteraError("IdealSolidSolnPhase::initThermoXML",
                           "Unspecified thermo model");
    }

    /*
     * Form of the standard concentrations. Must have one of:
     *
     *     <standardConc model="unity" />
     *     <standardConc model="molar_volume" />
     *     <standardConc model="solvent_volume" />
     */
    if (phaseNode.hasChild("standardConc")) {
        XML_Node& scNode = phaseNode.child("standardConc");
        string formStringa = scNode.attrib("model");
        string formString = lowercase(formStringa);
        if (formString == "unity") {
            m_formGC = 0;
        } else if (formString == "molar_volume") {
            m_formGC = 1;
        } else if (formString == "solvent_volume") {
            m_formGC = 2;
        } else {
            throw CanteraError("IdealSolidSolnPhase::initThermoXML",
                               "Unknown standardConc model: " + formStringa);
        }
    } else {
        throw CanteraError("IdealSolidSolnPhase::initThermoXML",
                           "Unspecified standardConc model");
    }

    /*
     * Initialize all of the lengths now that we know how many species
     * there are in the phase.
     */
    initLengths();
    /*
     * Now go get the molar volumes
     */
    XML_Node& speciesList = phaseNode.child("speciesArray");
    XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
                                         &phaseNode.root());

    for (size_t k = 0; k < m_kk; k++) {
        XML_Node* s = speciesDB->findByAttr("name", speciesName(k));
        XML_Node* ss = s->findByName("standardState");
        m_speciesMolarVolume[k] = getFloat(*ss, "molarVolume", "toSI");
    }

    /*
     * Call the base initThermo, which handles setting the initial
     * state.
     */
    ThermoPhase::initThermoXML(phaseNode, id_);
}
Exemplo n.º 25
0
void MixedSolventElectrolyte::readXMLBinarySpecies(XML_Node& xmLBinarySpecies)
{
    string xname = xmLBinarySpecies.name();
    if (xname != "binaryNeutralSpeciesParameters") {
        throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies",
                           "Incorrect name for processing this routine: " + xname);
    }
    string stemp;
    size_t nParamsFound;
    vector_fp vParams;
    string iName = xmLBinarySpecies.attrib("speciesA");
    if (iName == "") {
        throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies", "no speciesA attrib");
    }
    string jName = xmLBinarySpecies.attrib("speciesB");
    if (jName == "") {
        throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies", "no speciesB attrib");
    }
    /*
     * Find the index of the species in the current phase. It's not
     * an error to not find the species
     */
    size_t iSpecies = speciesIndex(iName);
    if (iSpecies == npos) {
        return;
    }
    string ispName = speciesName(iSpecies);
    if (charge(iSpecies) != 0) {
        throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies", "speciesA charge problem");
    }
    size_t jSpecies = speciesIndex(jName);
    if (jSpecies == npos) {
        return;
    }
    string jspName = speciesName(jSpecies);
    if (charge(jSpecies) != 0) {
        throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies", "speciesB charge problem");
    }

    resizeNumInteractions(numBinaryInteractions_ + 1);
    size_t iSpot = numBinaryInteractions_ - 1;
    m_pSpecies_A_ij[iSpot] = iSpecies;
    m_pSpecies_B_ij[iSpot] = jSpecies;

    size_t num = xmLBinarySpecies.nChildren();
    for (size_t iChild = 0; iChild < num; iChild++) {
        XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
        stemp = xmlChild.name();
        string nodeName = lowercase(stemp);
        /*
         * Process the binary species interaction child elements
         */
        if (nodeName == "excessenthalpy") {
            /*
             * Get the string containing all of the values
             */
            ctml::getFloatArray(xmlChild, vParams, true, "toSI", "excessEnthalpy");
            nParamsFound = vParams.size();

            if (nParamsFound != 2) {
                throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies::excessEnthalpy for " + ispName
                                   + "::" + jspName,
                                   "wrong number of params found");
            }
            m_HE_b_ij[iSpot] = vParams[0];
            m_HE_c_ij[iSpot] = vParams[1];
        }

        if (nodeName == "excessentropy") {
            /*
             * Get the string containing all of the values
             */
            ctml::getFloatArray(xmlChild, vParams, true, "toSI", "excessEntropy");
            nParamsFound = vParams.size();

            if (nParamsFound != 2) {
                throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies::excessEntropy for " + ispName
                                   + "::" + jspName,
                                   "wrong number of params found");
            }
            m_SE_b_ij[iSpot] = vParams[0];
            m_SE_c_ij[iSpot] = vParams[1];
        }

        if (nodeName == "excessvolume_enthalpy") {
            /*
             * Get the string containing all of the values
             */
            ctml::getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Enthalpy");
            nParamsFound = vParams.size();

            if (nParamsFound != 2) {
                throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies::excessVolume_Enthalpy for " + ispName
                                   + "::" + jspName,
                                   "wrong number of params found");
            }
            m_VHE_b_ij[iSpot] = vParams[0];
            m_VHE_c_ij[iSpot] = vParams[1];
        }

        if (nodeName == "excessvolume_entropy") {
            /*
             * Get the string containing all of the values
             */
            ctml::getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Entropy");
            nParamsFound = vParams.size();

            if (nParamsFound != 2) {
                throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies::excessVolume_Entropy for " + ispName
                                   + "::" + jspName,
                                   "wrong number of params found");
            }
            m_VSE_b_ij[iSpot] = vParams[0];
            m_VSE_c_ij[iSpot] = vParams[1];
        }
    }
}
void MolalityVPSSTP::setMolalitiesByName(const compositionMap& mMap)
{
    // HKM -> Might need to be more complicated here, setting neutrals so that
    //        the existing mole fractions are preserved.

    // Get a vector of mole fractions
    vector_fp mf(m_kk, 0.0);
    getMoleFractions(mf.data());
    double xmolSmin = std::max(mf[m_indexSolvent], m_xmolSolventMIN);
    for (size_t k = 0; k < m_kk; k++) {
        double mol_k = getValue(mMap, speciesName(k), 0.0);
        if (mol_k > 0) {
            mf[k] = mol_k * m_Mnaught * xmolSmin;
        }
    }

    // check charge neutrality
    size_t largePos = npos;
    double cPos = 0.0;
    size_t largeNeg = npos;
    double cNeg = 0.0;
    double sum = 0.0;
    for (size_t k = 0; k < m_kk; k++) {
        double ch = charge(k);
        if (mf[k] > 0.0) {
            if (ch > 0.0 && ch * mf[k] > cPos) {
                largePos = k;
                cPos = ch * mf[k];
            }
            if (ch < 0.0 && fabs(ch) * mf[k] > cNeg) {
                largeNeg = k;
                cNeg = fabs(ch) * mf[k];
            }
        }
        sum += mf[k] * ch;
    }
    if (sum != 0.0) {
        if (sum > 0.0) {
            if (cPos > sum) {
                mf[largePos] -= sum / charge(largePos);
            } else {
                throw CanteraError("MolalityVPSSTP:setMolalitiesbyName",
                                   "unbalanced charges");
            }
        } else {
            if (cNeg > (-sum)) {
                mf[largeNeg] -= (-sum) / fabs(charge(largeNeg));
            } else {
                throw CanteraError("MolalityVPSSTP:setMolalitiesbyName",
                                   "unbalanced charges");
            }
        }
    }
    sum = 0.0;
    for (size_t k = 0; k < m_kk; k++) {
        sum += mf[k];
    }
    sum = 1.0/sum;
    for (size_t k = 0; k < m_kk; k++) {
        mf[k] *= sum;
    }
    setMoleFractions(mf.data());

    // After we formally set the mole fractions, we calculate the molalities
    // again and store it in this object.
    calcMolalities();
}
std::string MolalityVPSSTP::report(bool show_thermo, doublereal threshold) const
{
    fmt::MemoryWriter b;
    try {
        if (name() != "") {
            b.write("\n  {}:\n", name());
        }
        b.write("\n");
        b.write("       temperature    {:12.6g}  K\n", temperature());
        b.write("          pressure    {:12.6g}  Pa\n", pressure());
        b.write("           density    {:12.6g}  kg/m^3\n", density());
        b.write("  mean mol. weight    {:12.6g}  amu\n", meanMolecularWeight());

        doublereal phi = electricPotential();
        b.write("         potential    {:12.6g}  V\n", phi);

        vector_fp x(m_kk);
        vector_fp molal(m_kk);
        vector_fp mu(m_kk);
        vector_fp muss(m_kk);
        vector_fp acMolal(m_kk);
        vector_fp actMolal(m_kk);
        getMoleFractions(&x[0]);
        getMolalities(&molal[0]);
        getChemPotentials(&mu[0]);
        getStandardChemPotentials(&muss[0]);
        getMolalityActivityCoefficients(&acMolal[0]);
        getActivities(&actMolal[0]);

        size_t iHp = speciesIndex("H+");
        if (iHp != npos) {
            double pH = -log(actMolal[iHp]) / log(10.0);
            b.write("                pH    {:12.4g}\n", pH);
        }

        if (show_thermo) {
            b.write("\n");
            b.write("                          1 kg            1 kmol\n");
            b.write("                       -----------      ------------\n");
            b.write("          enthalpy    {:12.6g}     {:12.4g}     J\n",
                    enthalpy_mass(), enthalpy_mole());
            b.write("   internal energy    {:12.6g}     {:12.4g}     J\n",
                    intEnergy_mass(), intEnergy_mole());
            b.write("           entropy    {:12.6g}     {:12.4g}     J/K\n",
                    entropy_mass(), entropy_mole());
            b.write("    Gibbs function    {:12.6g}     {:12.4g}     J\n",
                    gibbs_mass(), gibbs_mole());
            b.write(" heat capacity c_p    {:12.6g}     {:12.4g}     J/K\n",
                    cp_mass(), cp_mole());
            try {
                b.write(" heat capacity c_v    {:12.6g}     {:12.4g}     J/K\n",
                        cv_mass(), cv_mole());
            } catch (NotImplementedError& e) {
                b.write(" heat capacity c_v    <not implemented>\n");
            }
        }

        b.write("\n");
        int nMinor = 0;
        doublereal xMinor = 0.0;
        if (show_thermo) {
            b.write("                           X        "
                    "   Molalities         Chem.Pot.    ChemPotSS    ActCoeffMolal\n");
            b.write("                                    "
                    "                      (J/kmol)      (J/kmol)\n");
            b.write("                     -------------  "
                    "  ------------     ------------  ------------    ------------\n");
            for (size_t k = 0; k < m_kk; k++) {
                if (x[k] > threshold) {
                    if (x[k] > SmallNumber) {
                        b.write("{:>18s}  {:12.6g}     {:12.6g}     {:12.6g}   {:12.6g}   {:12.6g}\n",
                                speciesName(k), x[k], molal[k], mu[k], muss[k], acMolal[k]);
                    } else {
                        b.write("{:>18s}  {:12.6g}     {:12.6g}          N/A      {:12.6g}   {:12.6g}\n",
                                speciesName(k), x[k], molal[k], muss[k], acMolal[k]);
                    }
                } else {
                    nMinor++;
                    xMinor += x[k];
                }
            }
        } else {
            b.write("                           X"
                    "Molalities\n");
            b.write("                     -------------"
                    "     ------------\n");
            for (size_t k = 0; k < m_kk; k++) {
                if (x[k] > threshold) {
                    b.write("{:>18s}   {:12.6g}     {:12.6g}\n",
                            speciesName(k), x[k], molal[k]);
                } else {
                    nMinor++;
                    xMinor += x[k];
                }
            }
        }
        if (nMinor) {
            b.write("     [{:+5d} minor] {:12.6g}\n", nMinor, xMinor);
        }
    } catch (CanteraError& err) {
        return b.str() + err.what();
    }
    return b.str();
}
Exemplo n.º 28
0
/*
 * setMolalitiesByName()
 *
 *  This routine sets the molalities by name
 *  HKM -> Might need to be more complicated here, setting
 *         neutrals so that the existing mole fractions are
 *         preserved.
 */
void MolalityVPSSTP::setMolalitiesByName(compositionMap& mMap)
{
    size_t kk = nSpecies();
    doublereal x;
    /*
     * Get a vector of mole fractions
     */
    vector_fp mf(kk, 0.0);
    getMoleFractions(DATA_PTR(mf));
    double xmolS = mf[m_indexSolvent];
    double xmolSmin = std::max(xmolS, m_xmolSolventMIN);
    compositionMap::iterator p;
    for (size_t k = 0; k < kk; k++) {
        p = mMap.find(speciesName(k));
        if (p != mMap.end()) {
            x = mMap[speciesName(k)];
            if (x > 0.0) {
                mf[k] = x * m_Mnaught * xmolSmin;
            }
        }
    }
    /*
     * check charge neutrality
     */
    size_t largePos = npos;
    double cPos = 0.0;
    size_t largeNeg = npos;
    double cNeg = 0.0;
    double sum = 0.0;
    for (size_t k = 0; k < kk; k++) {
        double ch = charge(k);
        if (mf[k] > 0.0) {
            if (ch > 0.0) {
                if (ch * mf[k] > cPos) {
                    largePos = k;
                    cPos = ch * mf[k];
                }
            }
            if (ch < 0.0) {
                if (fabs(ch) * mf[k] > cNeg) {
                    largeNeg = k;
                    cNeg = fabs(ch) * mf[k];
                }
            }
        }
        sum += mf[k] * ch;
    }
    if (sum != 0.0) {
        if (sum > 0.0) {
            if (cPos > sum) {
                mf[largePos] -= sum / charge(largePos);
            } else {
                throw CanteraError("MolalityVPSSTP:setMolalitiesbyName",
                                   "unbalanced charges");
            }
        } else {
            if (cNeg > (-sum)) {
                mf[largeNeg] -= (-sum) / fabs(charge(largeNeg));
            } else {
                throw CanteraError("MolalityVPSSTP:setMolalitiesbyName",
                                   "unbalanced charges");
            }
        }

    }
    sum = 0.0;
    for (size_t k = 0; k < kk; k++) {
        sum += mf[k];
    }
    sum = 1.0/sum;
    for (size_t k = 0; k < kk; k++) {
        mf[k] *= sum;
    }
    setMoleFractions(DATA_PTR(mf));
    /*
     * After we formally set the mole fractions, we
     * calculate the molalities again and store it in
     * this object.
     */
    calcMolalities();
}