diff --git a/include/cantera/base/ctml.h b/include/cantera/base/ctml.h index 5dac32542..b3a4aa437 100644 --- a/include/cantera/base/ctml.h +++ b/include/cantera/base/ctml.h @@ -187,6 +187,61 @@ void addFloatArray(Cantera::XML_Node& node, const std::string& titleString, const doublereal minval = Cantera::Undef, const doublereal maxval = Cantera::Undef); +//! This function adds a child node with the name given by the first parameter with a value +//! consisting of a comma separated list of floats +/*! + * This function will add a child node to the current XML node, with the + * name given in the list. It will have a title attribute, and the body + * of the XML node will be filled out with a comma separated list of + * integers + * + * Example: + * + * Code snipet: + * @verbatum + const XML_Node &node; + std::string titleString = "additionalTemperatures"; + int n = 3; + int Tcases[3] = [273.15, 298.15, 373.15]; + std::string typeString = "optional"; + std::string units = "Kelvin"; + addNamedFloatArray(node, titleString, n, &cases[0], typeString, units); + @endverbatum + * + * Creates the following the snippet in the XML file: + * @verbatum + + + 273.15, 298.15, 373.15 + <\additionalTemperatures> + <\parentNode> + @endverbatum + * + * @param node reference to the XML_Node object of the parent XML element + * @param name Name of the XML node + * @param n Length of the doubles vector. + * @param values Pointer to a vector of doubles + * @param unitsString String name of the Units attribute. This is an optional + * parameter. The default is to + * have an empty string. + * @param type String type. This is an optional parameter. The default + * is to have an empty string. + * @param minval Minimum allowed value of the int. This is an optional + * parameter. The default is the + * special double, Cantera::Undef, which means to ignore the + * entry. + * @param maxval Maximum allowed value of the int. This is an optional + * parameter. The default is the + * special double, Cantera::Undef, which means to ignore the + * entry. + * + */ +void addNamedFloatArray(Cantera::XML_Node& parentNode, const std::string &name, const int n, + const doublereal* const vals, const std::string units = "", + const std::string type = "", + const doublereal minval = Cantera::Undef, + const doublereal maxval = Cantera::Undef); + //! This function adds a child node with the name string with a string value //! to the current node /*! @@ -703,6 +758,41 @@ bool getOptionalModel(const Cantera::XML_Node& parent, const std::string& nodeNa */ Cantera::XML_Node* getByTitle(const Cantera::XML_Node& node, const std::string& title); +//! This function reads a child node with the name string with a specific +//! title attribute named titleString +/*! + * This function will read a child node to the current XML node with the name "string". + * It must have a title attribute, named titleString, and the body + * of the XML node will be read into the valueString output argument. + * + * If the child node is not found then the empty string is returned. + * + * Example: + * + * Code snipet: + * @verbatim + const XML_Node &node; + getString(XML_Node& node, std::string titleString, std::string valueString, + std::string typeString); + @endverbatim + * + * Reads the following the snippet in the XML file: + * @verbatim + + valueString + <\string> + @endverbatim + * + * @param node Reference to the XML_Node object of the parent XML element + * @param titleString String name of the title attribute of the child node + * @param valueString Value string that is found in the child node. output variable + * @param typeString String type. This is an optional output variable. It is filled + * with the attribute "type" of the XML entry. + */ + void getString(const Cantera::XML_Node& node, const std::string &titleString, + std::string& valueString, std::string& typeString); + + //! This function attempts to read a named child node and returns with the contents in the value string. //! title attribute named "titleString" /*! diff --git a/include/cantera/transport/MixTransport.h b/include/cantera/transport/MixTransport.h index aee105a6f..a00c37712 100644 --- a/include/cantera/transport/MixTransport.h +++ b/include/cantera/transport/MixTransport.h @@ -260,7 +260,14 @@ private: //! Update boolean for the mixture rule for the mixture thermal conductivity bool m_condmix_ok; - + public: + vector_fp m_eps; + vector_fp m_sigma; + vector_fp m_alpha; + DenseMatrix m_dipole; + vector_fp m_zrot; + vector_fp m_crot; + private: //! Debug flag - turns on more printing bool m_debug; }; diff --git a/include/cantera/transport/MultiTransport.h b/include/cantera/transport/MultiTransport.h index 85be91ae9..422218c65 100644 --- a/include/cantera/transport/MultiTransport.h +++ b/include/cantera/transport/MultiTransport.h @@ -176,10 +176,15 @@ private: //! Dense matrix for omega22 DenseMatrix m_om22; - vector_fp m_zrot; + public: vector_fp m_crot; vector_fp m_cinternal; + vector_fp m_zrot; vector_fp m_eps; + vector_fp m_sigma; + vector_fp m_alpha; + DenseMatrix m_dipole; + private: vector_fp m_sqrt_eps_k; DenseMatrix m_log_eps_k; diff --git a/src/base/ctml.cpp b/src/base/ctml.cpp index 4647c6313..1585e5a0d 100644 --- a/src/base/ctml.cpp +++ b/src/base/ctml.cpp @@ -234,6 +234,84 @@ void addFloatArray(Cantera::XML_Node& node, const std::string& title, const size f.addAttribute("max",maxval); } } +//==================================================================================================================== +// This function adds a child node with the name given by the first parameter with a value +// consisting of a comma separated list of floats +/* + * This function will add a child node to the current XML node, with the + * name given in the list. It will have a title attribute, and the body + * of the XML node will be filled out with a comma separated list of + * integers + * + * Example: + * + * Code snipet: + * @verbatum + const XML_Node &node; + std::string titleString = "additionalTemperatures"; + int n = 3; + int Tcases[3] = [273.15, 298.15, 373.15]; + std::string typeString = "optional"; + std::string units = "Kelvin"; + addNamedFloatArray(node, titleString, n, &cases[0], typeString, units); + @endverbatum + * + * Creates the following the snippet in the XML file: + * @verbatum + + + 273.15, 298.15, 373.15 + <\additionalTemperatures> + <\parentNode> + @endverbatum +* +* @param node reference to the XML_Node object of the parent XML element +* @param name Name of the XML node +* @param n Length of the doubles vector. +* @param values Pointer to a vector of doubles +* @param unitsString String name of the Units attribute. This is an optional +* parameter. The default is to +* have an empty string. +* @param type String type. This is an optional parameter. The default +* is to have an empty string. +* @param minval Minimum allowed value of the int. This is an optional +* parameter. The default is the +* special double, Cantera::Undef, which means to ignore the +* entry. +* @param maxval Maximum allowed value of the int. This is an optional +* parameter. The default is the +* special double, Cantera::Undef, which means to ignore the +* entry. +* +*/ +void addNamedFloatArray(Cantera::XML_Node& node, const std::string &name, const int n, + const doublereal* const vals, const std::string units, + const std::string type, const doublereal minval, + const doublereal maxval) +{ + int i; + std::string v = ""; + for (i = 0; i < n; i++) { + v += fp2str(vals[i],FP_Format); + if (i == n-1) v += "\n"; + else if (i > 0 && (i+1) % 3 == 0) v += ",\n"; + else v += ", "; + } + XML_Node& f = node.addChild(name, v); + if (type != "") { + f.addAttribute("type",type); + } + /* + * Add vtype, which indicates the type of the value. Here we specify it as a list of floats separated + * by commas, with a length given by size attribute. + */ + f.addAttribute("vtype", "floatArray"); + + f.addAttribute("size", n); + if (units != "") f.addAttribute("units", units); + if (minval != Undef) f.addAttribute("min", minval); + if (maxval != Undef) f.addAttribute("max", maxval); +} //==================================================================================================================== // This function adds a child node with the name string with a string value @@ -322,28 +400,115 @@ std::string getChildValue(const Cantera::XML_Node& parent, const std::string& na } return parent(nameString); } - void getNamedStringValue(const Cantera::XML_Node& node, const std::string &nameString, std::string& valueString, - std::string& typeString) - { + + //==================================================================================================================== + // This function reads a child node with the name, "string", with a specific + // title attribute named "titleString" + /* + * This function will read a child node to the current XML node, with the + * name "string". It must have a title attribute, named titleString, and the body + * of the XML node will be read into the valueString output argument. + * + * Example: + * + * Code snipet: + * @verbatum + const XML_Node &node; + getString(XML_Node& node, std::string titleString, std::string valueString, + std::string typeString); + @endverbatum + * + * Reads the following the snippet in the XML file: + * @verbatum + + valueString + <\string> + @endverbatum + * + * @param node Reference to the XML_Node object of the parent XML element + * @param titleString String name of the title attribute of the child node + * @param valueString Value string that is found in the child node. output variable + * @param typeString String type. This is an optional output variable. It is filled + * with the attribute "type" of the XML entry. + */ + void getString(const Cantera::XML_Node& node, const std::string &titleString, std::string& valueString, + std::string& typeString) { valueString = ""; typeString = ""; - if (node.hasChild(nameString)) { - XML_Node &xc = node.child(nameString); - valueString = xc.value(); - typeString = xc["type"]; - } else { - XML_Node* s = getByTitle(node, nameString); - if (s) { - if (s->name() == "string") { - valueString = (*s).value(); - typeString = (*s)["type"]; - return; - } + XML_Node* s = getByTitle(node, titleString); + if (s) + if (s->name() == "string") { + valueString = (*s).value(); + typeString = (*s)["type"]; + return; } - } } +//======================================================================================================================= + +// This function attempts to read a named child node and returns with the contents in the value string. +// title attribute named "titleString" +/* + * This function will read a child node to the current XML node, with the + * name "string". It must have a title attribute, named titleString, and the body + * of the XML node will be read into the valueString output argument. + * + * If the child node is not found then the empty string is returned. + * + * Example: + * + * Code snipet: + * @verbatum + const XML_Node &node; + std::string valueString; + std::string typeString; + std::string nameString = "timeIncrement"; + getString(XML_Node& node, nameString, valueString, valueString, typeString); + @endverbatum + * + * Reads the following the snippet in the XML file: + * + * * @verbatum + + valueString + <\nameString> + @endverbatum + * + * or alternatively as a retrofit and special case, it also reads the following case + * + * @verbatum + + valueString + <\string> + @endverbatum + * + * @param node Reference to the XML_Node object of the parent XML element + * @param nameString Name of the XML Node input variable + * @param valueString Value string that is found in the child node. output variable + * @param typeString String type. This is an optional output variable. It is filled + * with the attribute "type" of the XML entry. output variable + */ +void getNamedStringValue(const Cantera::XML_Node& node, const std::string &nameString, std::string& valueString, + std::string& typeString) +{ + valueString = ""; + typeString = ""; + if (node.hasChild(nameString)) { + XML_Node &xc = node.child(nameString); + valueString = xc.value(); + typeString = xc["type"]; + } else { + XML_Node* s = getByTitle(node, nameString); + if (s) { + if (s->name() == "string") { + valueString = (*s).value(); + typeString = (*s)["type"]; + return; + } + } + } +} //==================================================================================================================== // Get a vector of integer values from a child element. /* @@ -946,6 +1111,97 @@ size_t getFloatArray(const Cantera::XML_Node& node, std::vector & v, return v.size(); } + //==================================================================================================================== + int getNamedFloatArray(const Cantera::XML_Node& parentNode, const std::string & nodeName, std::vector & v, + const bool convert, const std::string unitsString) { + std::string::size_type icom; + std::string numstr; + doublereal dtmp; + std::string nn = parentNode.name(); + v.clear(); + const Cantera::XML_Node *readNode = parentNode.findByName(nodeName); + if (!readNode) { + return 0; + } + + doublereal vmin = Undef; + doublereal vmax = Undef; + doublereal funit = 1.0; + /* + * Get the attributes field, units, from the XML node + */ + std::string units = (*readNode)["units"]; + if (units != "" && convert) { + if (unitsString == "actEnergy" && units != "") { + funit = actEnergyToSI(units); + } else if (unitsString != "" && units != "") { + funit = toSI(units); + } + } + + if ((*readNode)["min"] != "") + vmin = atofCheck((*readNode)["min"].c_str()); + if ((*readNode)["max"] != "") + vmax = atofCheck((*readNode)["max"].c_str()); + + int expectedSize = 0; + nn = (*readNode)["size"]; + expectedSize = atoi(nn.c_str()); + + nn = (*readNode)["vtype"]; + if (nn != "floatArray") { + throw CanteraError("getNamedFloatArray", + "node named " + nodeName + "didn't have correct vtype"); + } + + + doublereal vv; + std::string val = readNode->value(); + while (1 > 0) { + icom = val.find(','); + if (icom != string::npos) { + numstr = val.substr(0,icom); + val = val.substr(icom+1,val.size()); + dtmp = atofCheck(numstr.c_str()); + v.push_back(dtmp); + } + else { + /* + * This little bit of code is to allow for the + * possibility of a comma being the last + * item in the value text. This was allowed in + * previous versions of Cantera, even though it + * would appear to be odd. So, we keep the + * possibilty in for backwards compatibility. + */ + int nlen = strlen(val.c_str()); + if (nlen > 0) { + dtmp = atofCheck(val.c_str()); + v.push_back(dtmp); + } + break; + } + vv = v.back(); + if (vmin != Undef && vv < vmin - Tiny) { + writelog("\nWarning: value "+fp2str(vv)+ + " is below lower limit of " +fp2str(vmin)+".\n"); + } + if (vmax != Undef && vv > vmax + Tiny) { + writelog("\nWarning: value "+fp2str(vv)+ + " is above upper limit of " +fp2str(vmin)+".\n"); + } + } + int nv = v.size(); + for (int n = 0; n < nv; n++) { + v[n] *= funit; + } + if (nv != expectedSize) { + throw CanteraError("getNamedFloatArray", + "node named " + nodeName + "didn't have correct number of floats" + + int2str(expectedSize) + " vs " + int2str(nv)); + } + return nv; + } //==================================================================================================================== // This routine is used to interpret the value portions of XML // elements that contain colon separated pairs. @@ -1183,4 +1439,5 @@ void getStringArray(const Cantera::XML_Node& node, std::vector& v) tokenizeString(val, v); } + } diff --git a/src/thermo/IonsFromNeutralVPSSTP.cpp b/src/thermo/IonsFromNeutralVPSSTP.cpp index dcb76573c..8f32ba6e6 100644 --- a/src/thermo/IonsFromNeutralVPSSTP.cpp +++ b/src/thermo/IonsFromNeutralVPSSTP.cpp @@ -103,10 +103,10 @@ IonsFromNeutralVPSSTP::IonsFromNeutralVPSSTP(const std::string& inputFile, } constructPhaseFile(inputFile, id); geThermo = dynamic_cast(neutralMoleculePhase_); - y.resize(numNeutralMoleculeSpecies_,0.0); - size_t numNeutMolSpec = geThermo->nSpecies(); - dlnActCoeff_NeutralMolecule.resize(numNeutMolSpec); - dX_NeutralMolecule.resize(numNeutMolSpec); + //y.resize(numNeutralMoleculeSpecies_,0.0); + //size_t numNeutMolSpec = geThermo->nSpecies(); + //dlnActCoeff_NeutralMolecule.resize(numNeutMolSpec); + //dX_NeutralMolecule.resize(numNeutMolSpec); } //==================================================================================================================== IonsFromNeutralVPSSTP::IonsFromNeutralVPSSTP(XML_Node& phaseRoot, @@ -201,6 +201,7 @@ operator=(const IonsFromNeutralVPSSTP& b) GibbsExcessVPSSTP::operator=(b); + ionSolnType_ = b.ionSolnType_; numNeutralMoleculeSpecies_ = b.numNeutralMoleculeSpecies_; indexSpecialSpecies_ = b.indexSpecialSpecies_; @@ -215,6 +216,10 @@ operator=(const IonsFromNeutralVPSSTP& b) passThroughList_ = b.passThroughList_; numPassThroughSpecies_ = b.numPassThroughSpecies_; + y = b.y; + dlnActCoeff_NeutralMolecule = b.dlnActCoeff_NeutralMolecule; + dX_NeutralMolecule = b.dX_NeutralMolecule; + IOwnNThermoPhase_ = b.IOwnNThermoPhase_; moleFractionsTmp_ = b.moleFractionsTmp_; muNeutralMolecule_ = b.muNeutralMolecule_; @@ -224,9 +229,6 @@ operator=(const IonsFromNeutralVPSSTP& b) dlnActCoeffdlnX_diag_NeutralMolecule_ = b.dlnActCoeffdlnX_diag_NeutralMolecule_; dlnActCoeffdlnN_diag_NeutralMolecule_ = b.dlnActCoeffdlnN_diag_NeutralMolecule_; dlnActCoeffdlnN_NeutralMolecule_ = b.dlnActCoeffdlnN_NeutralMolecule_; - y = b.y; - dlnActCoeff_NeutralMolecule = b.dlnActCoeff_NeutralMolecule ; - dX_NeutralMolecule = b.dX_NeutralMolecule ; return *this; } @@ -1162,6 +1164,11 @@ void IonsFromNeutralVPSSTP::initLengths() dlnActCoeffdlnX_diag_NeutralMolecule_.resize(numNeutralMoleculeSpecies_); dlnActCoeffdlnN_diag_NeutralMolecule_.resize(numNeutralMoleculeSpecies_); dlnActCoeffdlnN_NeutralMolecule_.resize(numNeutralMoleculeSpecies_, numNeutralMoleculeSpecies_, 0.0); + + y.resize(numNeutralMoleculeSpecies_, 0.0); + dlnActCoeff_NeutralMolecule.resize(numNeutralMoleculeSpecies_, 0.0); + dX_NeutralMolecule.resize(numNeutralMoleculeSpecies_, 0.0); + } //==================================================================================================================== //! Return the factor overlap @@ -1499,7 +1506,6 @@ void IonsFromNeutralVPSSTP::getdlnActCoeffds(const doublereal dTds, const double return; } - size_t numNeutMolSpec = geThermo->nSpecies(); // static vector_fp dlnActCoeff_NeutralMolecule(numNeutMolSpec); // static vector_fp dX_NeutralMolecule(numNeutMolSpec); diff --git a/src/transport/MixTransport.cpp b/src/transport/MixTransport.cpp index be37ee7eb..fec6d70c8 100644 --- a/src/transport/MixTransport.cpp +++ b/src/transport/MixTransport.cpp @@ -91,6 +91,14 @@ Transport* MixTransport::duplMyselfAsTransport() const bool MixTransport::initGas(GasTransportParams& tr) { GasTransport::initGas(tr); + + + m_eps = tr.eps; + m_sigma = tr.sigma; + m_alpha = tr.alpha; + m_dipole = tr.dipole; + m_zrot = tr.zrot; + m_crot = tr.crot; // copy polynomials and parameters into local storage m_condcoeffs = tr.condcoeffs; diff --git a/src/transport/MultiTransport.cpp b/src/transport/MultiTransport.cpp index f5f3f09e2..9fcd79e00 100644 --- a/src/transport/MultiTransport.cpp +++ b/src/transport/MultiTransport.cpp @@ -74,6 +74,10 @@ bool MultiTransport::initGas(GasTransportParams& tr) m_zrot = tr.zrot; m_crot = tr.crot; m_eps = tr.eps; + m_sigma = tr.sigma; + m_alpha = tr.alpha; + m_dipole = tr.dipole; + m_zrot = tr.zrot; // the L matrix m_Lmatrix.resize(3*m_nsp, 3*m_nsp);