Esempio n. 1
0
doublereal MolarityIonicVPSSTP::err(const std::string& msg) const
{
    throw CanteraError("MolarityIonicVPSSTP","Base class method "
                       +msg+" called. Equation of state type: "+int2str(eosType()));
    return 0;
}
Esempio n. 2
0
PDSS*
VPSSMgr_General::returnPDSS_ptr(size_t k, const XML_Node& speciesNode,
                                const XML_Node* const phaseNode_ptr, bool& doST)
{
    PDSS* kPDSS = 0;
    doST = true;
    GeneralSpeciesThermo* genSpthermo = dynamic_cast<GeneralSpeciesThermo*>(m_spthermo);


    const XML_Node* const ss = speciesNode.findByName("standardState");
    if (!ss) {
        VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
        kPDSS = new PDSS_IdealGas(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
        return kPDSS;
    }
    std::string model = (*ss)["model"];
    if (model == "constant_incompressible") {
        VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
        kPDSS = new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
        if (!kPDSS) {
            throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_ConstVol failed");
        }
    } else if (model == "waterIAPWS" || model == "waterPDSS") {
        // VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
        kPDSS = new PDSS_Water(m_vptp_ptr, 0);
        if (!genSpthermo) {
            throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
                               "failed dynamic cast");
        }
        genSpthermo->installPDSShandler(k, kPDSS, this);
        m_useTmpRefStateStorage = false;
    } else if (model == "HKFT") {
        doST = false;
        kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
        if (!genSpthermo) {
            throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
                               "failed dynamic cast");
        }
        genSpthermo->installPDSShandler(k, kPDSS, this);

    } else if (model == "IonFromNeutral") {
        if (!genSpthermo) {
            throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
                               "failed dynamic cast");
        }
        doST = false;
        kPDSS = new PDSS_IonsFromNeutral(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
        if (!kPDSS) {
            throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
                               "new PDSS_IonsFromNeutral failed");
        }
        genSpthermo->installPDSShandler(k, kPDSS, this);

    } else if (model == "constant" || model == "temperature_polynomial" || model == "density_temperature_polynomial") {
        VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
        kPDSS = new PDSS_SSVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
        if (!kPDSS) {
            throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_SSVol failed");
        }
    } else {
        throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
                           "unknown standard state formulation: " + model);
    }
    return kPDSS;
}
Esempio n. 3
0
void vcs_VolPhase::resize(const size_t phaseNum, const size_t nspecies,
                          const size_t numElem, const char* const phaseName,
                          const double molesInert)
{
    AssertThrowMsg(nspecies > 0, "vcs_VolPhase::resize", "nspecies Error");
    setTotalMolesInert(molesInert);
    m_phi = 0.0;
    m_phiVarIndex = npos;

    if (phaseNum == VP_ID_) {
        if (strcmp(PhaseName.c_str(), phaseName)) {
            throw CanteraError("vcs_VolPhase::resize",
                               "Strings are different: " + PhaseName + " " +
                               phaseName + " :unknown situation");
        }
    } else {
        VP_ID_ = phaseNum;
        if (!phaseName) {
            std::stringstream sstmp;
            sstmp << "Phase_" << VP_ID_;
            PhaseName = sstmp.str();
        } else {
            PhaseName = phaseName;
        }
    }
    if (nspecies > 1) {
        m_singleSpecies = false;
    } else {
        m_singleSpecies = true;
    }

    if (m_numSpecies == nspecies && numElem == m_numElemConstraints) {
        return;
    }

    m_numSpecies = nspecies;
    if (nspecies > 1) {
        m_singleSpecies = false;
    }


    IndSpecies.resize(nspecies, npos);

    if (ListSpeciesPtr.size() >= m_numSpecies) {
        for (size_t i = 0; i < m_numSpecies; i++) {
            if (ListSpeciesPtr[i]) {
                delete ListSpeciesPtr[i];
                ListSpeciesPtr[i] = 0;
            }
        }
    }
    ListSpeciesPtr.resize(nspecies, 0);
    for (size_t i = 0; i < nspecies; i++) {
        ListSpeciesPtr[i] = new vcs_SpeciesProperties(phaseNum, i, this);
    }

    Xmol_.resize(nspecies, 0.0);
    creationMoleNumbers_.resize(nspecies, 0.0);
    creationGlobalRxnNumbers_.resize(nspecies, npos);
    for (size_t i = 0; i < nspecies; i++) {
        Xmol_[i] = 1.0/nspecies;
        creationMoleNumbers_[i] = 1.0/nspecies;
        if (IndSpecies[i] >= m_numElemConstraints) {
            creationGlobalRxnNumbers_[i] = IndSpecies[i] - m_numElemConstraints;
        } else {
            creationGlobalRxnNumbers_[i] = npos;
        }
    }

    SS0ChemicalPotential.resize(nspecies, -1.0);
    StarChemicalPotential.resize(nspecies, -1.0);
    StarMolarVol.resize(nspecies, -1.0);
    PartialMolarVol.resize(nspecies, -1.0);
    ActCoeff.resize(nspecies, 1.0);
    np_dLnActCoeffdMolNumber.resize(nspecies, nspecies, 0.0);


    m_speciesUnknownType.resize(nspecies, VCS_SPECIES_TYPE_MOLNUM);
    m_UpToDate            = false;
    m_vcsStateStatus      = VCS_STATECALC_OLD;
    m_UpToDate_AC         = false;
    m_UpToDate_VolStar    = false;
    m_UpToDate_VolPM      = false;
    m_UpToDate_GStar      = false;
    m_UpToDate_G0         = false;


    elemResize(numElem);

}
Esempio n. 4
0
void importPhase(XML_Node& phase, ThermoPhase* th)
{
    // Check the the supplied XML node in fact represents a phase.
    if (phase.name() != "phase") {
        throw CanteraError("importPhase",
                           "Current const XML_Node named, " + phase.name() +
                           ", is not a phase element.");
    }

    // In this section of code, we get the reference to the phase XML tree
    // within the ThermoPhase object. Then, we clear it and fill it with the
    // current information that we are about to use to construct the object. We
    // will then be able to resurrect the information later by calling xml().
    th->setXMLdata(phase);

    // set the id attribute of the phase to the 'id' attribute in the XML tree.
    th->setID(phase.id());
    th->setName(phase.id());

    // Number of spatial dimensions. Defaults to 3 (bulk phase)
    if (phase.hasAttrib("dim")) {
        int idim = intValue(phase["dim"]);
        if (idim < 1 || idim > 3) {
            throw CanteraError("importPhase",
                               "phase, " + th->id() +
                               ", has unphysical number of dimensions: " + phase["dim"]);
        }
        th->setNDim(idim);
    } else {
        th->setNDim(3); // default
    }

    // Set equation of state parameters. The parameters are specific to each
    // subclass of ThermoPhase, so this is done by method setParametersFromXML
    // in each subclass.
    const XML_Node& eos = phase.child("thermo");
    if (phase.hasChild("thermo")) {
        th->setParametersFromXML(eos);
    } else {
        throw CanteraError("importPhase",
                           " phase, " + th->id() +
                           ", XML_Node does not have a \"thermo\" XML_Node");
    }

    VPStandardStateTP* vpss_ptr = 0;
    int ssConvention = th->standardStateConvention();
    if (ssConvention == cSS_CONVENTION_VPSS) {
        vpss_ptr = dynamic_cast <VPStandardStateTP*>(th);
        if (vpss_ptr == 0) {
            throw CanteraError("importPhase",
                               "phase, " + th->id() + ", was VPSS, but dynamic cast failed");
        }
    }

    // Add the elements.
    if (ssConvention != cSS_CONVENTION_SLAVE) {
        installElements(*th, phase);
    }

    // Add the species.
    //
    // Species definitions may be imported from multiple sources. For each one,
    // a speciesArray element must be present.
    vector<XML_Node*> sparrays = phase.getChildren("speciesArray");
    if (ssConvention != cSS_CONVENTION_SLAVE && sparrays.empty()) {
        throw CanteraError("importPhase",
                           "phase, " + th->id() + ", has zero \"speciesArray\" XML nodes.\n"
                           + " There must be at least one speciesArray nodes "
                           "with one or more species");
    }
    vector<XML_Node*> dbases;
    vector_int sprule(sparrays.size(),0);

    // Default behavior when importing from CTI/XML is for undefined elements to
    // be treated as an error
    th->throwUndefinedElements();

    // loop over the speciesArray elements
    for (size_t jsp = 0; jsp < sparrays.size(); jsp++) {
        const XML_Node& speciesArray = *sparrays[jsp];

        // If the speciesArray element has a child element
        //
        //   <skip element="undeclared">
        //
        // then set sprule[jsp] to 1, so that any species with an undeclared
        // element will be quietly skipped when importing species. Additionally,
        // if the skip node has the following attribute:
        //
        // <skip species="duplicate">
        //
        // then duplicate species names will not cause Cantera to throw an
        // exception. Instead, the duplicate entry will be discarded.
        if (speciesArray.hasChild("skip")) {
            const XML_Node& sk = speciesArray.child("skip");
            string eskip = sk["element"];
            if (eskip == "undeclared") {
                sprule[jsp] = 1;
            }
            string dskip = sk["species"];
            if (dskip == "duplicate") {
                sprule[jsp] += 10;
            }
        }

        // Get a pointer to the node containing the species definitions for the
        // species declared in this speciesArray element. This may be in the
        // local file containing the phase element, or may be in another file.
        XML_Node* db = get_XML_Node(speciesArray["datasrc"], &phase.root());
        if (db == 0) {
            throw CanteraError("importPhase()",
                               " Can not find XML node for species database: "
                               + speciesArray["datasrc"]);
        }

        // add this node to the list of species database nodes.
        dbases.push_back(db);
    }

    // Now, collect all the species names and all the XML_Node * pointers for
    // those species in a single vector. This is where we decide what species
    // are to be included in the phase. The logic is complicated enough that we
    // put it in a separate routine.
    std::vector<XML_Node*> spDataNodeList;
    std::vector<std::string> spNamesList;
    vector_int spRuleList;
    formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList,
                           sparrays, dbases, sprule);

    size_t nsp = spDataNodeList.size();
    if (ssConvention == cSS_CONVENTION_SLAVE && nsp > 0) {
        throw CanteraError("importPhase()", "For Slave standard states, "
            "number of species must be zero: {}", nsp);
    }
    for (size_t k = 0; k < nsp; k++) {
        XML_Node* s = spDataNodeList[k];
        AssertTrace(s != 0);
        if (spRuleList[k]) {
           th->ignoreUndefinedElements();
        }
        th->addSpecies(newSpecies(*s));
        if (vpss_ptr) {
            const XML_Node* const ss = s->findByName("standardState");
            std::string ss_model = (ss) ? ss->attrib("model") : "ideal-gas";
            unique_ptr<PDSS> kPDSS(newPDSS(ss_model));
            kPDSS->setParametersFromXML(*s);
            vpss_ptr->installPDSS(k, std::move(kPDSS));
        }
        th->saveSpeciesData(k, s);
    }

    // Done adding species. Perform any required subclass-specific
    // initialization.
    th->initThermo();

    // Perform any required subclass-specific initialization that requires the
    // XML phase object
    std::string id = "";
    th->initThermoXML(phase, id);
}
Esempio n. 5
0
doublereal Domain1D::initialValue(size_t n, size_t j)
{
    throw CanteraError("Domain1D::initialValue",
                       "base class method called!");
    return 0.0;
}
/*
 * initThermoXML()                (virtual from ThermoPhase)
 *   Import and initialize a ThermoPhase object
 *
 * @param phaseNode This object must be the phase node of a
 *             complete XML tree
 *             description of the phase, including all of the
 *             species data. In other words while "phase" must
 *             point to an XML phase object, it must have
 *             sibling nodes "speciesData" that describe
 *             the species in the phase.
 * @param id   ID of the phase. If nonnull, a check is done
 *             to see if phaseNode is pointing to the phase
 *             with the correct id.
 */
void MixedSolventElectrolyte::initThermoXML(XML_Node& phaseNode, const std::string& id)
{
    string subname = "MixedSolventElectrolyte::initThermoXML";
    string stemp;

    if ((int) id.size() > 0) {
        string idp = phaseNode.id();
        if (idp != id) {
            throw CanteraError(subname, "phasenode and Id are incompatible");
        }
    }

    /*
     * Check on the thermo field. Must have:
     * <thermo model="MixedSolventElectrolyte" />
     */
    if (!phaseNode.hasChild("thermo")) {
        throw CanteraError(subname, "no thermo XML node");
    }
    XML_Node& thermoNode = phaseNode.child("thermo");
    string mStringa = thermoNode.attrib("model");
    string mString = lowercase(mStringa);
    if (mString != "MixedSolventElectrolyte") {
        throw CanteraError(subname, "Unknown thermo model: " + mStringa);
    }

    /*
     * Go get all of the coefficients and factors in the
     * activityCoefficients XML block
     */
    XML_Node* acNodePtr = 0;
    if (thermoNode.hasChild("activityCoefficients")) {
        XML_Node& acNode = thermoNode.child("activityCoefficients");
        acNodePtr = &acNode;
        string mStringa = acNode.attrib("model");
        string mString = lowercase(mStringa);
        if (mString != "margules") {
            throw CanteraError(subname.c_str(),
                               "Unknown activity coefficient model: " + mStringa);
        }
        size_t n = acNodePtr->nChildren();
        for (size_t i = 0; i < n; i++) {
            XML_Node& xmlACChild = acNodePtr->child(i);
            stemp = xmlACChild.name();
            string nodeName = lowercase(stemp);
            /*
             * Process a binary salt field, or any of the other XML fields
             * that make up the Pitzer Database. Entries will be ignored
             * if any of the species in the entry isn't in the solution.
             */
            if (nodeName == "binaryneutralspeciesparameters") {
                readXMLBinarySpecies(xmlACChild);

            }
        }
    }

    /*
     * Go down the chain
     */
    MolarityIonicVPSSTP::initThermoXML(phaseNode, id);


}
Esempio n. 7
0
void MargulesVPSSTP::readXMLBinarySpecies(XML_Node& xmLBinarySpecies)
{
    string xname = xmLBinarySpecies.name();
    if (xname != "binaryNeutralSpeciesParameters") {
        throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies",
                           "Incorrect name for processing this routine: " + xname);
    }
    string aName = xmLBinarySpecies.attrib("speciesA");
    if (aName == "") {
        throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies", "no speciesA attrib");
    }
    string bName = xmLBinarySpecies.attrib("speciesB");
    if (bName == "") {
        throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies", "no speciesB attrib");
    }

    vector_fp vParams;
    double h0 = 0.0;
    double h1 = 0.0;
    double s0 = 0.0;
    double s1 = 0.0;
    double vh0 = 0.0;
    double vh1 = 0.0;
    double vs0 = 0.0;
    double vs1 = 0.0;

    for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
        XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
        string nodeName = toLowerCopy(xmlChild.name());

        // Process the binary species interaction parameters.
        // They are in subblocks labeled:
        //           excessEnthalpy
        //           excessEntropy
        //           excessVolume_Enthalpy
        //           excessVolume_Entropy
        // Other blocks are currently ignored.
        // @TODO determine a policy about ignoring blocks that should or shouldn't be there.
        if (nodeName == "excessenthalpy") {
            // Get the string containing all of the values
            getFloatArray(xmlChild, vParams, true, "toSI", "excessEnthalpy");
            if (vParams.size() != 2) {
                throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
                    "excessEnthalpy for {} : {}: wrong number of params found."
                    " Need 2", aName, bName);
            }
            h0 = vParams[0];
            h1 = vParams[1];
        } else if (nodeName == "excessentropy") {
            // Get the string containing all of the values
            getFloatArray(xmlChild, vParams, true, "toSI", "excessEntropy");
            if (vParams.size() != 2) {
                throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
                    "excessEntropy for {} : {}: wrong number of params found."
                    " Need 2", aName, bName);
            }
            s0 = vParams[0];
            s1 = vParams[1];
        } else if (nodeName == "excessvolume_enthalpy") {
            // Get the string containing all of the values
            getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Enthalpy");
            if (vParams.size() != 2) {
                throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
                    "excessVolume_Enthalpy for {} : {}: wrong number of params"
                    "  found. Need 2", aName, bName);
            }
            vh0 = vParams[0];
            vh1 = vParams[1];
        } else if (nodeName == "excessvolume_entropy") {
            // Get the string containing all of the values
            getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Entropy");
            if (vParams.size() != 2) {
                throw CanteraError("MargulesVPSSTP::readXMLBinarySpecies"
                    "excessVolume_Entropy for {} : {}: wrong number of params"
                    " found. Need 2", aName, bName);
            }
            vs0 = vParams[0];
            vs1 = vParams[1];
        }
    }
    addBinaryInteraction(aName, bName, h0, h1, s0, s1, vh0, vh1, vs0, vs1);
}
Esempio n. 8
0
size_t Phase::addElement(const std::string& symbol, doublereal weight,
                         int atomic_number, doublereal entropy298,
                         int elem_type)
{
    // Look up the atomic weight if not given
    if (weight == 0.0) {
        try {
            weight = getElementWeight(symbol);
        } catch (CanteraError&) {
            // assume this is just a custom element with zero atomic weight
        }
    } else if (weight == -12345.0) {
        weight = getElementWeight(symbol);
    }

    // Try to look up the standard entropy if not given. Fail silently.
    if (entropy298 == ENTROPY298_UNKNOWN) {
        try {
            XML_Node* db = get_XML_File("elements.xml");
            XML_Node* elnode = db->findByAttr("name", symbol);
            if (elnode && elnode->hasChild("entropy298")) {
                entropy298 = fpValueCheck(elnode->child("entropy298")["value"]);
            }
        } catch (CanteraError&) {
        }
    }

    // Check for duplicates
    auto iter = find(m_elementNames.begin(), m_elementNames.end(), symbol);
    if (iter != m_elementNames.end()) {
        size_t m = iter - m_elementNames.begin();
        if (m_atomicWeights[m] != weight) {
            throw CanteraError("Phase::addElement",
                "Duplicate elements ({}) have different weights", symbol);
        } else {
            // Ignore attempt to add duplicate element with the same weight
            return m;
        }
    }

    // Add the new element
    m_atomicWeights.push_back(weight);
    m_elementNames.push_back(symbol);
    m_atomicNumbers.push_back(atomic_number);
    m_entropy298.push_back(entropy298);
    if (symbol == "E") {
        m_elem_type.push_back(CT_ELEM_TYPE_ELECTRONCHARGE);
    } else {
        m_elem_type.push_back(elem_type);
    }
    m_mm++;

    // Update species compositions
    if (m_kk) {
        vector_fp old(m_speciesComp);
        m_speciesComp.resize(m_kk*m_mm, 0.0);
        for (size_t k = 0; k < m_kk; k++) {
            size_t m_old = m_mm - 1;
            for (size_t m = 0; m < m_old; m++) {
                m_speciesComp[k * m_mm + m] = old[k * (m_old) + m];
            }
            m_speciesComp[k * (m_mm) + (m_mm-1)] = 0.0;
        }
    }

    return m_mm-1;
}
Esempio n. 9
0
bool Phase::addSpecies(shared_ptr<Species> spec) {
    if (m_species.find(toLowerCopy(spec->name)) != m_species.end()) {
        throw CanteraError("Phase::addSpecies",
            "Phase '{}' already contains a species named '{}'.",
            m_name, spec->name);
    }
    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_species[toLowerCopy(spec->name)] = spec;
    m_speciesIndices[toLowerCopy(spec->name)] = m_kk;
    m_speciesCharge.push_back(spec->charge);
    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;
}
Esempio n. 10
0
 /*
  * Calculate the constant volume heat capacity
  * in mks units of J kmol-1 K-1
  */
 doublereal 
 PDSS_IonsFromNeutral::cv_mole() const {
   throw CanteraError("PDSS_IonsFromNeutral::cv_mole()", "unimplemented");
   return 0.0;
 }
Esempio n. 11
0
 /// critical density
 doublereal PDSS_IonsFromNeutral::critDensity() const {
   throw CanteraError("PDSS_IonsFromNeutral::critDensity()", "unimplemented");
   return (0.0);
 }
/*!
 *  This is called if a 'Shomate' node is found in the XML input.
 *
 *  @param nodes        vector of 1 or 2 'Shomate' XML_Nodes, each defining the
 *      coefficients for a temperature range
 */
static SpeciesThermoInterpType* newShomateThermoFromXML(
    vector<XML_Node*>& nodes)
{
    bool dualRange = false;
    if (nodes.size() == 2) {
        dualRange = true;
    }
    double tmin0 = fpValue(nodes[0]->attrib("Tmin"));
    double tmax0 = fpValue(nodes[0]->attrib("Tmax"));

    doublereal p0 = OneAtm;
    if (nodes[0]->hasAttrib("P0")) {
        p0 = fpValue(nodes[0]->attrib("P0"));
    }
    if (nodes[0]->hasAttrib("Pref")) {
        p0 = fpValue(nodes[0]->attrib("Pref"));
    }
    p0 = OneAtm;

    double tmin1 = tmax0;
    double tmax1 = tmin1 + 0.0001;
    if (dualRange) {
        tmin1 = fpValue(nodes[1]->attrib("Tmin"));
        tmax1 = fpValue(nodes[1]->attrib("Tmax"));
    }

    vector_fp c0, c1;
    doublereal tmin, tmid, tmax;
    if (fabs(tmax0 - tmin1) < 0.01) {
        tmin = tmin0;
        tmid = tmax0;
        tmax = tmax1;
        getFloatArray(nodes[0]->child("floatArray"), c0, false);
        if (dualRange) {
            getFloatArray(nodes[1]->child("floatArray"), c1, false);
        } else {
            if(c0.size() != 7)
            {
              throw CanteraError("installShomateThermoFromXML",
                                 "Shomate thermo requires 7 coefficients in float array.");
            }
            c1.resize(7,0.0);
            copy(c0.begin(), c0.begin()+7, c1.begin());
        }
    } else if (fabs(tmax1 - tmin0) < 0.01) {
        tmin = tmin1;
        tmid = tmax1;
        tmax = tmax0;
        getFloatArray(nodes[1]->child("floatArray"), c0, false);
        getFloatArray(nodes[0]->child("floatArray"), c1, false);
    } else {
        throw CanteraError("installShomateThermoFromXML",
                           "non-continuous temperature ranges.");
    }
    if(c0.size() != 7 || c1.size() != 7)
    {
      throw CanteraError("installShomateThermoFromXML",
                         "Shomate thermo requires 7 coefficients in float array.");
    }
    vector_fp c(15);
    c[0] = tmid;
    copy(c0.begin(), c0.begin()+7, c.begin() + 1);
    copy(c1.begin(), c1.begin()+7, c.begin() + 8);
    return newSpeciesThermoInterpType(SHOMATE, tmin, tmax, p0, &c[0]);
}
Esempio n. 13
0
void VCS_SOLVE::vcs_nondim_TP()
{
    if (m_unitsState == VCS_DIMENSIONAL_G) {
        m_unitsState = VCS_NONDIMENSIONAL_G;
        double tf = 1.0 / vcs_nondimMult_TP(m_VCS_UnitsFormat, m_temperature);
        for (size_t i = 0; i < m_numSpeciesTot; ++i) {
            /*
             *        Modify the standard state and total chemical potential data,
             *        FF(I), to make it dimensionless, i.e., mu / RT.
             *        Thus, we may divide it by the temperature.
             */
            m_SSfeSpecies[i] *= tf;
            m_deltaGRxn_new[i] *= tf;
            m_deltaGRxn_old[i] *= tf;
            m_feSpecies_old[i] *= tf;
        }

        m_Faraday_dim = vcs_nondim_Farad(m_VCS_UnitsFormat, m_temperature);

        /*
         * Scale the total moles if necessary:
         *  First find out the total moles
         */
        double tmole_orig = vcs_tmoles();

        /*
         * Then add in the total moles of elements that are goals. Either one
         * or the other is specified here.
         */
        double esum = 0.0;
        for (size_t i = 0; i < m_numElemConstraints; ++i) {
            if (m_elType[i] == VCS_ELEM_TYPE_ABSPOS) {
                esum += fabs(m_elemAbundancesGoal[i]);
            }
        }
        tmole_orig += esum;

        /*
         * Ok now test out the bounds on the total moles that this program can
         * handle. These are a bit arbitrary. However, it would seem that any
         * reasonable input would be between these two numbers below.
         */
        if (tmole_orig < 1.0E-200 || tmole_orig > 1.0E200) {
            throw CanteraError("VCS_SOLVE::vcs_nondim_TP",
                               "Total input moles ," + fp2str(tmole_orig) +
                               "is outside the range handled by vcs.\n");
        }

        // Determine the scale of the problem
        if (tmole_orig > 1.0E4) {
            m_totalMoleScale = tmole_orig / 1.0E4;
        } else if (tmole_orig < 1.0E-4) {
            m_totalMoleScale = tmole_orig / 1.0E-4;
        } else {
            m_totalMoleScale = 1.0;
        }

        if (m_totalMoleScale != 1.0) {
            if (m_VCS_UnitsFormat == VCS_UNITS_MKS) {
                if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
                    plogf("  --- vcs_nondim_TP() called: USING A MOLE SCALE OF %g until further notice", m_totalMoleScale);
                    plogendl();
                }
                for (size_t i = 0; i < m_numSpeciesTot; ++i) {
                    if (m_speciesUnknownType[i] != VCS_SPECIES_TYPE_INTERFACIALVOLTAGE) {
                        m_molNumSpecies_old[i] *= (1.0 / m_totalMoleScale);
                    }
                }
                for (size_t i = 0; i < m_numElemConstraints; ++i) {
                    m_elemAbundancesGoal[i] *= (1.0 / m_totalMoleScale);
                }

                for (size_t iph = 0; iph < m_numPhases; iph++) {
                    TPhInertMoles[iph] *= (1.0 / m_totalMoleScale);
                    if (TPhInertMoles[iph] != 0.0) {
                        vcs_VolPhase* vphase = m_VolPhaseList[iph];
                        vphase->setTotalMolesInert(TPhInertMoles[iph]);
                    }
                }
            }
            vcs_tmoles();
        }
    }
}
Esempio n. 14
0
void MolarityIonicVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id)
{
    std::string subname = "MolarityIonicVPSSTP::initThermoXML";
    std::string stemp;

    if ((int) id.size() > 0) {
        string idp = phaseNode.id();
        if (idp != id) {
            throw CanteraError(subname, "phasenode and Id are incompatible");
        }
    }

    /*
     * Check on the thermo field. Must have one of:
     * <thermo model="MolarityIonicVPSS" />
     * <thermo model="MolarityIonicVPSSTP" />
     */
    if (!phaseNode.hasChild("thermo")) {
        throw CanteraError(subname, "no thermo XML node");
    }
    XML_Node& thermoNode = phaseNode.child("thermo");
    std::string mStringa = thermoNode.attrib("model");
    std::string mString = lowercase(mStringa);
    if (mString != "molarityionicvpss" && mString != "molarityionicvpsstp") {
        throw CanteraError(subname.c_str(),
                           "Unknown thermo model: " + mStringa + " - This object only knows \"MolarityIonicVPSSTP\" ");
    }

    /*
     * Go get all of the coefficients and factors in the
     * activityCoefficients XML block
     */
    XML_Node* acNodePtr = 0;
    if (thermoNode.hasChild("activityCoefficients")) {
        XML_Node& acNode = thermoNode.child("activityCoefficients");
        acNodePtr = &acNode;
        mStringa = acNode.attrib("model");
        mString = lowercase(mStringa);
        // if (mString != "redlich-kister") {
        //   throw CanteraError(subname.c_str(),
        //        "Unknown activity coefficient model: " + mStringa);
        //}
        size_t n = acNodePtr->nChildren();
        for (size_t i = 0; i < n; i++) {
            XML_Node& xmlACChild = acNodePtr->child(i);
            stemp = xmlACChild.name();
            std::string nodeName = lowercase(stemp);
            /*
             * Process a binary interaction
             */
            if (nodeName == "binaryneutralspeciesparameters") {
                readXMLBinarySpecies(xmlACChild);
            }
        }
    }


    /*
     * Go down the chain
     */
    GibbsExcessVPSSTP::initThermoXML(phaseNode, id);
}
Esempio n. 15
0
 void ConstDensityThermo::setToEquilState(const doublereal* lambda_RT) {
     throw CanteraError("setToEquilState","not yet impl.");
 }
Esempio n. 16
0
// critical density
doublereal PDSS_IdealGas::critDensity() const {
    throw CanteraError("PDSS_IdealGas::critDensity()", "unimplemented");
    return (0.0);
}
doublereal MixedSolventElectrolyte::err(const std::string& msg) const
{
    throw CanteraError("MixedSolventElectrolyte","Base class method "
                       +msg+" called. Equation of state type: "+int2str(eosType()));
    return 0;
}
Esempio n. 18
0
// saturation pressure
doublereal PDSS_IdealGas::satPressure(doublereal t) {
    throw CanteraError("PDSS_IdealGas::satPressure()", "unimplemented");
    /*NOTREACHED*/
    return (0.0);
}
/*
 * Process an XML node called "binaryNeutralSpeciesParameters"
 * This node contains all of the parameters necessary to describe
 * the Margules Interaction for a single binary interaction
 * This function reads the XML file and writes the coefficients
 * it finds to an internal data structures.
 */
void MixedSolventElectrolyte::readXMLBinarySpecies(XML_Node& xmLBinarySpecies)
{
    string xname = xmLBinarySpecies.name();
    if (xname != "binaryNeutralSpeciesParameters") {
        throw CanteraError("MixedSolventElectrolyte::readXMLBinarySpecies",
                           "Incorrect name for processing this routine: " + xname);
    }
    double* charge = DATA_PTR(m_speciesCharge);
    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];
        }


    }

}
Esempio n. 20
0
  /*
   *
   *  @param   file    Pointer to the file
   *  @param   debug   Turn on debug printing
   *
   *  @ingroup inputfiles
   */
  void ct2ctml(const char* file, const int debug) {

#ifdef HAS_NO_PYTHON
    /*
     *  Section to bomb out if python is not
     *  present in the computation environment.
     */
    string ppath = file;
    throw CanteraError("ct2ctml", 
		       "python cti to ctml conversion requested for file, " + ppath +
		       ", but not available in this computational environment");
#endif

    time_t aclock;
    time( &aclock );
    int ia = static_cast<int>(aclock);
    string path =  tmpDir()+"/.cttmp"+int2str(ia)+".pyw";
    ofstream f(path.c_str());
    if (!f) {
      throw CanteraError("ct2ctml","cannot open "+path+" for writing.");
    }

    f << "from ctml_writer import *\n"
      << "import sys, os, os.path\n"
      << "file = \"" << file << "\"\n"
      << "base = os.path.basename(file)\n"
      << "root, ext = os.path.splitext(base)\n"
      << "dataset(root)\n"
      << "execfile(file)\n"
      << "write()\n";
    f.close();
    string logfile = tmpDir()+"/ct2ctml.log";
#ifdef _WIN32
    string cmd = pypath() + " " + "\"" + path + "\"" + "> " + logfile + " 2>&1";
#else
    string cmd = "sleep " + sleep() + "; " + "\"" + pypath() + "\"" + 
      " " + "\"" + path + "\"" + " &> " + logfile;
#endif
#ifdef DEBUG_PATHS
    writelog("ct2ctml: executing the command " + cmd + "\n");
#endif
    if (debug > 0) {
      writelog("ct2ctml: executing the command " + cmd + "\n");
      writelog("ct2ctml: the Python command is: " + pypath() + "\n");
    }

    int ierr = 0;
    try {
      ierr = system(cmd.c_str());
    }
    catch (...) {
      ierr = -10;
	  if (debug > 0) {
	    writelog("ct2ctml: command execution failed.\n");
	  }
    }

    /*
     * This next section may seem a bit weird. However, it is in
     * response to an issue that arises when running cantera with
     * cygwin, using cygwin's python intepreter. Basically, the
     * xml file is written to the local directory by the last
     * system command. Then, the xml file is read immediately
     * after by an ifstream() c++ command. Unfortunately, it seems
     * that the directory info is not being synched fast enough so
     * that the ifstream() read fails, even though the file is
     * actually there. Putting in a sleep system call here fixes
     * this problem. Also, having the xml file pre-existing fixes
     * the problem as well. There may be more direct ways to fix
     * this bug; however, I am not aware of them.
     * HKM -> During the solaris port, I found the same thing.
     *        It probably has to do with NFS syncing problems.
     *        3/3/06
     */
#ifndef _WIN32
    string sss = sleep();
    if (debug > 0) {
      writelog("sleeping for " + sss + " secs+\n");
    }
    cmd = "sleep " + sss;
    try {
      ierr = system(cmd.c_str());
    }
    catch (...) {
      ierr = -10;
      writelog("ct2ctml: command execution failed.\n");
    }
#else
    // This command works on windows machines if Windows.h and Winbase.h are included
    // Sleep(5000);
#endif
    // show the contents of the log file on the screen
    try {
      char ch=0;
      string s = "";
      ifstream ferr("ct2ctml.log");
      if (ferr) {
	    while (!ferr.eof()) {
	      ferr.get(ch);
	      s += ch;
	      if (ch == '\n') {
	        writelog(s);
	        s = "";
	      }
	    }
	    ferr.close();
      }
      else {
            if (debug > 0) {
	      writelog("cannot open ct2ctml.log for reading.\n");
	    }
      }
    }
    catch (...) {
      writelog("ct2ctml: caught something \n");; 
    }
    if (ierr != 0) {
      string msg = cmd;
	  writelog("ct2ctml: throw cantera error \n");; 
      throw CanteraError("ct2ctml", 
			 "could not convert input file to CTML.\n "
			 "Command line was: \n" + msg);
    }

    // if the conversion succeeded and DEBUG_PATHS is not defined,
    // then clean up by deleting the temporary Python file.
#ifndef DEBUG_PATHS
    //#ifdef _WIN32
    //cmd = "cmd /C rm " + path;
    if (debug == 0)
      remove(path.c_str());
    else {
      writelog("ct2ctml: retaining temporary file "+path+"\n");
    }
#else
    if (debug > 0) {
      writelog("ct2ctml: retaining temporary file "+path+"\n");
    }
#endif
  }
Esempio n. 21
0
/*!
 *   @param spDataNodeList   Output vector of pointer to XML_Nodes which contain
 *       the species XML_Nodes for the species in the current phase.
 *   @param spNamesList      Output Vector of strings, which contain the names
 *       of the species in the phase
 *   @param spRuleList       Output Vector of ints, which contain the value of
 *       sprule for each species in the phase
 *   @param spArray_names    Vector of pointers to the XML_Nodes which contains
 *                           the names of the species in the phase
 *   @param spArray_dbases   Input vector of pointers to species data bases. We
 *                           search each data base for the required species
 *                           names
 *   @param  sprule          Input vector of sprule values
 */
static void formSpeciesXMLNodeList(std::vector<XML_Node*> &spDataNodeList,
                                   std::vector<std::string> &spNamesList,
                                   vector_int &spRuleList,
                                   const std::vector<XML_Node*> spArray_names,
                                   const std::vector<XML_Node*> spArray_dbases,
                                   const vector_int sprule)
{
    // used to check that each species is declared only once
    std::map<std::string, bool> declared;

    for (size_t jsp = 0; jsp < spArray_dbases.size(); jsp++) {
        const XML_Node& speciesArray = *spArray_names[jsp];

        // Get the top XML for the database
        const XML_Node* db = spArray_dbases[jsp];

        // Get the array of species name strings and then count them
        std::vector<std::string> spnames;
        getStringArray(speciesArray, spnames);
        size_t nsp = spnames.size();

        // if 'all' is specified as the one and only species in the
        // spArray_names field, then add all species defined in the
        // corresponding database to the phase
        if (nsp == 1 && spnames[0] == "all") {
            std::vector<XML_Node*> allsp = db->getChildren("species");
            nsp = allsp.size();
            spnames.resize(nsp);
            for (size_t nn = 0; nn < nsp; nn++) {
                string stemp = (*allsp[nn])["name"];
                if (!declared[stemp] || sprule[jsp] < 10) {
                    declared[stemp] = true;
                    spNamesList.push_back(stemp);
                    spDataNodeList.push_back(allsp[nn]);
                    spRuleList.push_back(sprule[jsp]);
                }
            }
        } else if (nsp == 1 && spnames[0] == "unique") {
            std::vector<XML_Node*> allsp = db->getChildren("species");
            nsp = allsp.size();
            spnames.resize(nsp);
            for (size_t nn = 0; nn < nsp; nn++) {
                string stemp = (*allsp[nn])["name"];
                if (!declared[stemp]) {
                    declared[stemp] = true;
                    spNamesList.push_back(stemp);
                    spDataNodeList.push_back(allsp[nn]);
                    spRuleList.push_back(sprule[jsp]);
                }
            }
        } else {
            std::map<std::string, XML_Node*> speciesNodes;
            for (size_t k = 0; k < db->nChildren(); k++) {
                XML_Node& child = db->child(k);
                speciesNodes[child["name"]] = &child;
            }
            for (size_t k = 0; k < nsp; k++) {
                string stemp = spnames[k];
                if (!declared[stemp] || sprule[jsp] < 10) {
                    declared[stemp] = true;
                    // Find the species in the database by name.
                    auto iter = speciesNodes.find(stemp);
                    if (iter == speciesNodes.end()) {
                        throw CanteraError("importPhase","no data for species, \""
                                           + stemp + "\"");
                    }
                    spNamesList.push_back(stemp);
                    spDataNodeList.push_back(iter->second);
                    spRuleList.push_back(sprule[jsp]);
                }
            }
        }
    }
}
Esempio n. 22
0
void ck2cti(const std::string& in_file, const std::string& thermo_file,
            const std::string& transport_file, const std::string& id_tag)
{
    string python_output;
    int python_exit_code;
    try {
        exec_stream_t python;
        python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes
        python.start(pypath(), "-i");
        stringstream output_stream;

        ostream& pyin = python.in();
        pyin << "if True:\n" << // Use this so that the rest is a single block
                "    import sys\n" <<
                "    sys.stderr = sys.stdout\n" <<
                "    try:\n" <<
                "        from cantera import ck2cti\n" <<
                "    except ImportError:\n" <<
                "        print('sys.path: ' + repr(sys.path))\n" <<
                "        raise\n"
                "    ck2cti.Parser().convertMech(r'" << in_file << "',";
        if (thermo_file != "" && thermo_file != "-") {
            pyin << " thermoFile=r'" << thermo_file << "',";
        }
        if (transport_file != "" && transport_file != "-") {
            pyin << " transportFile=r'" << transport_file << "',";
        }
        pyin << " phaseName='" << id_tag << "',";
        pyin << " permissive=True,";
        pyin << " quiet=True)\n";
        pyin << "    sys.exit(0)\n\n";
        pyin << "sys.exit(7)\n";
        python.close_in();

        std::string line;
        while (python.out().good()) {
            std::getline(python.out(), line);
            output_stream << line << std::endl;;
        }
        python.close();
        python_exit_code = python.exit_code();
        python_output = trimCopy(output_stream.str());
    } catch (std::exception& err) {
        // Report failure to execute Python
        stringstream message;
        message << "Error executing python while converting input file:\n";
        message << "Python command was: '" << pypath() << "'\n";
        message << err.what() << std::endl;
        throw CanteraError("ct2ctml", message.str());
    }

    if (python_exit_code != 0) {
        // Report a failure in the conversion process
        stringstream message;
        message << "Error converting input file \"" << in_file << "\" to CTI.\n";
        message << "Python command was: '" << pypath() << "'\n";
        message << "The exit code was: " << python_exit_code << "\n";
        if (python_output.size() > 0) {
            message << "-------------- start of converter log --------------\n";
            message << python_output << std::endl;
            message << "--------------- end of converter log ---------------";
        } else {
            message << "The command did not produce any output." << endl;
        }
        throw CanteraError("ck2cti", message.str());
    }

    if (python_output.size() > 0) {
        // Warn if there was any output from the conversion process
        stringstream message;
        message << "Warning: Unexpected output from CTI converter\n";
        message << "-------------- start of converter log --------------\n";
        message << python_output << std::endl;
        message << "--------------- end of converter log ---------------\n";
        writelog(message.str());
    }
}
Esempio n. 23
0
compositionMap parseCompString(const std::string& ss,
                               const std::vector<std::string>& names)
{
    compositionMap x;
    for (size_t k = 0; k < names.size(); k++) {
        x[names[k]] = 0.0;
    }

    size_t start = 0;
    size_t stop = 0;
    size_t left = 0;
    while (stop < ss.size()) {
        size_t colon = ss.find(':', left);
        if (colon == npos) {
            break;
        }
        size_t valstart = ss.find_first_not_of(" \t\n", colon+1);
        stop = ss.find_first_of(", ;\n\t", valstart);
        std::string name = ba::trim_copy(ss.substr(start, colon-start));
        if (!names.empty() && x.find(name) == x.end()) {
            throw CanteraError("parseCompString",
                "unknown species '" + name + "'");
        }

        double value;
        try {
            value = fpValueCheck(ss.substr(valstart, stop-valstart));
        } catch (CanteraError&) {
            // If we have a key containing a colon, we expect this to fail. In
            // this case, take the current substring as part of the key and look
            // to the right of the next colon for the corresponding value.
            // Otherwise, this is an invalid composition string.
            std::string testname = ss.substr(start, stop-start);
            if (testname.find_first_of(" \n\t") != npos) {
                // Space, tab, and newline are never allowed in names
                throw;
            } else if (ss.substr(valstart, stop-valstart).find(':') != npos) {
                left = colon + 1;
                stop = 0; // Force another iteration of this loop
                continue;
            } else {
                throw;
            }
        }
        if (getValue(x, name, 0.0) != 0.0) {
            throw CanteraError("parseCompString",
                               "Duplicate key: '" + name + "'.");
        }

        x[name] = value;
        start = ss.find_first_not_of(", ;\n\t", stop+1);
        left = start;
    }
    if (left != start) {
        throw CanteraError("parseCompString", "Unable to parse key-value pair:"
            "\n'{}'", ss.substr(start, stop));
    }
    if (stop != npos && !ba::trim_copy(ss.substr(stop)).empty()) {
        throw CanteraError("parseCompString", "Found non-key:value data "
            "in composition string: '" + ss.substr(stop) + "'");
    }
    return x;
}
Esempio n. 24
0
static std::string call_ctml_writer(const std::string& text, bool isfile)
{
    std::string file, arg;

    if (isfile) {
        file = text;
        arg = "r'" + text + "'";
    } else {
        file = "<string>";
        arg = "text=r'''" + text + "'''";
    }

    string python_output, error_output;
    int python_exit_code;
    try {
        exec_stream_t python;
        python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes
        stringstream output_stream, error_stream;
        python.start(pypath(), "");
        ostream& pyin = python.in();

        pyin << "from __future__ import print_function\n"
                "if True:\n"
                "    import sys\n"
                "    try:\n"
                "        from cantera import ctml_writer\n"
                "    except ImportError:\n"
                "        print('sys.path: ' + repr(sys.path) + '\\n', file=sys.stderr)\n"
                "        raise\n"
                "    ctml_writer.convert(";
        pyin << arg << ", outName='STDOUT')\n";
        pyin << "    sys.exit(0)\n\n";
        pyin << "sys.exit(7)\n";

        python.close_in();
        std::string line;

        while (python.out().good()) {
            std::getline(python.out(), line);
            output_stream << line << std::endl;
        }

#ifdef _WIN32
        // Sleeping for 1 ms prevents a (somewhat inexplicable) deadlock while
        // reading from the stream.
        Sleep(1);
#endif
        while (python.err().good()) {
            std::getline(python.err(), line);
            error_stream << line << std::endl;
        }
        python.close();
        python_exit_code = python.exit_code();
        error_output = trimCopy(error_stream.str());
        python_output = output_stream.str();
    } catch (std::exception& err) {
        // Report failure to execute Python
        stringstream message;
        message << "Error executing python while converting input file:\n";
        message << "Python command was: '" << pypath() << "'\n";
        message << err.what() << std::endl;
        throw CanteraError("ct2ctml_string", message.str());
    }

    if (python_exit_code != 0) {
        // Report a failure in the conversion process
        stringstream message;
        message << "Error converting input file \"" << file << "\" to CTML.\n";
        message << "Python command was: '" << pypath() << "'\n";
        message << "The exit code was: " << python_exit_code << "\n";
        if (error_output.size() > 0) {
            message << "-------------- start of converter log --------------\n";
            message << error_output << std::endl;
            message << "--------------- end of converter log ---------------";
        } else {
            message << "The command did not produce any output." << endl;
        }
        throw CanteraError("ct2ctml_string", message.str());
    }

    if (error_output.size() > 0) {
        // Warn if there was any output from the conversion process
        stringstream message;
        message << "Warning: Unexpected output from CTI converter\n";
        message << "-------------- start of converter log --------------\n";
        message << error_output << std::endl;
        message << "--------------- end of converter log ---------------\n";
        writelog(message.str());
    }

    return python_output;
}
Esempio n. 25
0
  /*
   * @param m String message
   */
  void Kinetics::err(std::string m) const {
    throw CanteraError("Kinetics::" + m, 
		       "The default Base class method was called, when "
		       "the inherited class's method should "
		       "have been called");
  }
Esempio n. 26
0
doublereal PDSS_IdealGas::pressure() const
{
    throw CanteraError("PDSS_IdealGas::pressure()", "unimplemented");
}
Esempio n. 27
0
  doublereal VPStandardStateTP::err(std::string msg) const {
    throw CanteraError("VPStandardStateTP","Base class method "
		       +msg+" called. Equation of state type: "+int2str(eosType()));
    return 0;
  }
Esempio n. 28
0
  /*
   * initThermoXML()                 (virtual from ThermoPhase)
   *
   *  This gets called from importPhase(). It processes the XML file
   *  after the species are set up. This is the main routine for
   *  reading in activity coefficient parameters.
   *
   * @param phaseNode This object must be the phase node of a
   *             complete XML tree
   *             description of the phase, including all of the
   *             species data. In other words while "phase" must
   *             point to an XML phase object, it must have
   *             sibling nodes "speciesData" that describe
   *             the species in the phase.
   * @param id   ID of the phase. If nonnull, a check is done
   *             to see if phaseNode is pointing to the phase
   *             with the correct id.
   */
  void MineralEQ3::initThermoXML(XML_Node& phaseNode, std::string id) {
    /*
     * Find the Thermo XML node 
     */
    if (!phaseNode.hasChild("thermo")) {
      throw CanteraError("HMWSoln::initThermoXML",
			 "no thermo XML node");
    }
   
    std::vector<const XML_Node *> xspecies = speciesData();
    const XML_Node *xsp = xspecies[0];

    XML_Node *aStandardState = 0;
    if (xsp->hasChild("standardState")) {
      aStandardState = &xsp->child("standardState");
    } else {
      throw CanteraError("MineralEQ3::initThermoXML",
			 "no standard state mode");
    }
    doublereal volVal = 0.0;
    string smodel = (*aStandardState)["model"];
    if (smodel != "constantVolume") {
      throw CanteraError("MineralEQ3::initThermoXML",
			 "wrong standard state mode");
    }
    if (aStandardState->hasChild("V0_Pr_Tr")) {
      XML_Node& aV = aStandardState->child("V0_Pr_Tr");
      string Aunits = "";
      double Afactor = toSI("cm3/gmol");
      if (aV.hasAttrib("units")) {
	Aunits = aV.attrib("units");
	Afactor = toSI(Aunits); 
      }
      volVal = ctml::getFloat(*aStandardState, "V0_Pr_Tr");
      m_V0_pr_tr= volVal;
      volVal *= Afactor;
      m_speciesSize[0] = volVal;
    } else {
      throw CanteraError("MineralEQ3::initThermoXML",
			 "wrong standard state mode");
    }
    doublereal rho = molecularWeight(0) / volVal;
    setDensity(rho);
    
    const XML_Node &sThermo = xsp->child("thermo");
    const XML_Node &MinEQ3node = sThermo.child("MinEQ3");
   

    m_deltaG_formation_pr_tr =
      ctml::getFloatDefaultUnits(MinEQ3node, "DG0_f_Pr_Tr", "cal/gmol", "actEnergy");
    m_deltaH_formation_pr_tr =
      ctml::getFloatDefaultUnits(MinEQ3node, "DH0_f_Pr_Tr", "cal/gmol", "actEnergy");
    m_Entrop_pr_tr = ctml::getFloatDefaultUnits(MinEQ3node, "S0_Pr_Tr", "cal/gmol/K");
    m_a = ctml::getFloatDefaultUnits(MinEQ3node, "a", "cal/gmol/K");
    m_b = ctml::getFloatDefaultUnits(MinEQ3node, "b", "cal/gmol/K2");
    m_c = ctml::getFloatDefaultUnits(MinEQ3node, "c", "cal-K/gmol");

  
    convertDGFormation();
  
  }
Esempio n. 29
0
void vcs_VolPhase::setMolesFromVCS(const int stateCalc,
                                   const double* molesSpeciesVCS)
{
    v_totalMoles = m_totalMolesInert;

    if (molesSpeciesVCS == 0) {
        AssertThrowMsg(m_owningSolverObject, "vcs_VolPhase::setMolesFromVCS",
                       "shouldn't be here");
        if (stateCalc == VCS_STATECALC_OLD) {
            molesSpeciesVCS = VCS_DATA_PTR(m_owningSolverObject->m_molNumSpecies_old);
        } else if (stateCalc == VCS_STATECALC_NEW) {
            molesSpeciesVCS = VCS_DATA_PTR(m_owningSolverObject->m_molNumSpecies_new);
        } else if (DEBUG_MODE_ENABLED) {
            throw CanteraError("vcs_VolPhase::setMolesFromVCS", "shouldn't be here");        }
    } else if (DEBUG_MODE_ENABLED && m_owningSolverObject) {
        if (stateCalc == VCS_STATECALC_OLD) {
            if (molesSpeciesVCS != VCS_DATA_PTR(m_owningSolverObject->m_molNumSpecies_old)) {
                throw CanteraError("vcs_VolPhase::setMolesFromVCS", "shouldn't be here");
            }
        } else if (stateCalc == VCS_STATECALC_NEW) {
            if (molesSpeciesVCS != VCS_DATA_PTR(m_owningSolverObject->m_molNumSpecies_new)) {
                throw CanteraError("vcs_VolPhase::setMolesFromVCS", "shouldn't be here");
            }
        }
    }

    for (size_t k = 0; k < m_numSpecies; k++) {
        if (m_speciesUnknownType[k] != VCS_SPECIES_TYPE_INTERFACIALVOLTAGE) {
            size_t kglob = IndSpecies[k];
            v_totalMoles += std::max(0.0, molesSpeciesVCS[kglob]);
        }
    }
    if (v_totalMoles > 0.0) {
        for (size_t k = 0; k < m_numSpecies; k++) {
            if (m_speciesUnknownType[k] != VCS_SPECIES_TYPE_INTERFACIALVOLTAGE) {
                size_t kglob = IndSpecies[k];
                double tmp = std::max(0.0, molesSpeciesVCS[kglob]);
                Xmol_[k] = tmp / v_totalMoles;
            }
        }
        m_existence = VCS_PHASE_EXIST_YES;
    } else {
        // This is where we will start to store a better approximation
        // for the mole fractions, when the phase doesn't exist.
        // This is currently unimplemented.
        m_existence = VCS_PHASE_EXIST_NO;
    }
    /*
     * Update the electric potential if it is a solution variable
     * in the equation system
     */
    if (m_phiVarIndex != npos) {
        size_t kglob = IndSpecies[m_phiVarIndex];
        if (m_numSpecies == 1) {
            Xmol_[m_phiVarIndex] = 1.0;
        } else {
            Xmol_[m_phiVarIndex] = 0.0;
        }
        double phi = molesSpeciesVCS[kglob];
        setElectricPotential(phi);
        if (m_numSpecies == 1) {
            m_existence = VCS_PHASE_EXIST_YES;
        }
    }
    _updateMoleFractionDependencies();
    if (m_totalMolesInert > 0.0) {
        m_existence = VCS_PHASE_EXIST_ALWAYS;
    }

    /*
     * If stateCalc is old and the total moles is positive,
     * then we have a valid state. If the phase went away, it would
     * be a valid starting point for F_k's. So, save the state.
     */
    if (stateCalc == VCS_STATECALC_OLD) {
        if (v_totalMoles > 0.0) {
            creationMoleNumbers_ = Xmol_;
        }
    }

    /*
     * Set flags indicating we are up to date with the VCS state vector.
     */
    m_UpToDate = true;
    m_vcsStateStatus = stateCalc;
}
Esempio n. 30
0
void MolarityIonicVPSSTP::calcPseudoBinaryMoleFractions() const
{
    size_t k;
    size_t kCat;
    size_t kMax;
    doublereal sumCat;
    doublereal sumAnion;
    doublereal chP, chM;
    doublereal sum = 0.0;
    doublereal sumMax;
    switch (PBType_) {
    case PBTYPE_PASSTHROUGH:
        for (k = 0; k < m_kk; k++) {
            PBMoleFractions_[k] = moleFractions_[k];
        }
        break;
    case PBTYPE_SINGLEANION:
        sumCat = 0.0;
        sumAnion = 0.0;
        for (k = 0; k < m_kk; k++) {
            moleFractionsTmp_[k] = moleFractions_[k];
        }
        kMax = npos;
        sumMax = 0.0;
        for (k = 0; k < cationList_.size(); k++) {
            kCat = cationList_[k];
            chP = m_speciesCharge[kCat];
            if (moleFractions_[kCat] > sumMax) {
                kMax = k;
                sumMax = moleFractions_[kCat];
            }
            sumCat += chP * moleFractions_[kCat];
        }
        k = anionList_[0];
        chM = m_speciesCharge[k];
        sumAnion = moleFractions_[k] * chM;
        sum = sumCat - sumAnion;
        if (fabs(sum) > 1.0E-16) {
            moleFractionsTmp_[cationList_[kMax]] -= sum / m_speciesCharge[kMax];
            sum = 0.0;
            for (k = 0; k < numCationSpecies_; k++) {
                sum +=  moleFractionsTmp_[k];
            }
            for (k = 0; k < numCationSpecies_; k++) {
                moleFractionsTmp_[k]/= sum;
            }
        }

        for (k = 0; k < numCationSpecies_; k++) {
            PBMoleFractions_[k] = moleFractionsTmp_[cationList_[k]];
        }
        for (k = 0; k <  numPassThroughSpecies_; k++) {
            PBMoleFractions_[neutralPBindexStart + k] = moleFractions_[passThroughList_[k]];
        }

        sum = std::max(0.0, PBMoleFractions_[0]);
        for (k = 1; k < numPBSpecies_; k++) {
            sum += PBMoleFractions_[k];

        }
        for (k = 0; k < numPBSpecies_; k++) {
            PBMoleFractions_[k] /= sum;
        }

        break;
    case PBTYPE_SINGLECATION:
        throw CanteraError("eosType", "Unknown type");

        break;

    case PBTYPE_MULTICATIONANION:
        throw CanteraError("eosType", "Unknown type");

        break;
    default:
        throw CanteraError("eosType", "Unknown type");
        break;

    }
}