From 46bf44d59fdb478f4d79f778631840fb09ae3dc6 Mon Sep 17 00:00:00 2001 From: John Hewson Date: Fri, 20 Nov 2009 04:04:33 +0000 Subject: [PATCH] Added Factory method to return LTPspecies instances virtual LTPspecies* newLTP( const XML_Node &trNode, std::string &name, TransportPropertyList tp_ind, thermo_t* thermo) ; This method returns a pointer to the appropriate subclass of LTPspecies. Added maps of TransportPropertyList and LiquidTR std::map m_tranPropMap; std::map m_LTRmodelMap; Moved the method getArrhenius() from TransportFactory.cpp to LiquidTransportData.cpp In TransportFactory::getLiquidSpeciesTransportData(), removed the lines associated with parsing the XML for the individual transport properties. This XML parsing is now carried out within the LTPspecies subclass constructors. Instead, within getLiquidSpeciesTransportData() we call newLTP() method that creates these subclassed methods and returns a pointer to the new LTPspecies object. --- Cantera/src/transport/TransportFactory.cpp | 304 ++++++--------------- Cantera/src/transport/TransportFactory.h | 23 +- 2 files changed, 112 insertions(+), 215 deletions(-) diff --git a/Cantera/src/transport/TransportFactory.cpp b/Cantera/src/transport/TransportFactory.cpp index 8ab778853..dc0735948 100644 --- a/Cantera/src/transport/TransportFactory.cpp +++ b/Cantera/src/transport/TransportFactory.cpp @@ -97,21 +97,6 @@ namespace Cantera { }; - /** - * getArrhenius() parses the xml element called Arrhenius. - * The Arrhenius expression is - * \f[ k = A T^(b) exp (-E_a / RT). \f] - */ - static void getArrhenius(const XML_Node& node, - doublereal& A, doublereal& b, doublereal& E) { - /* parse the children for the A, b, and E conponents. - */ - A = getFloat(node, "A", "toSI"); - b = getFloat(node, "b"); - E = getFloat(node, "E", "actEnergy"); - E /= GasConstant; - } - //////////////////// class TransportFactory methods ////////////// @@ -260,6 +245,16 @@ namespace Cantera { m_models["None"] = None; //m_models["Radiative"] = cRadiative; + m_tranPropMap["viscostiy"] = TP_VISCOSITY; + m_tranPropMap["thermalConductivity"] = TP_THERMALCOND; + m_tranPropMap["speciesDiffusivity"] = TP_DIFFUSIVITY; + m_tranPropMap["hydrodynamicRadius"] = TP_HYDRORADIUS; + m_tranPropMap["electricalConductivity"] = TP_ELECTCOND; + + m_LTRmodelMap[""] = LTR_MODEL_CONSTANT; + m_LTRmodelMap["constant"] = LTR_MODEL_CONSTANT; + m_LTRmodelMap["arrhenius"] = LTR_MODEL_ARRHENIUS; + m_LTRmodelMap["coeffs"] = LTR_MODEL_POLY; } /** @@ -291,6 +286,48 @@ namespace Cantera { } } + /** + * make one of several transport models, and return a base class + * pointer to it. This method operates at the level of a + * single transport property as a function of temperature + * and possibly composition. + */ + LTPspecies* TransportFactory::newLTP( const XML_Node &trNode, + std::string &name, + TransportPropertyList tp_ind, + thermo_t* thermo) { + LTPspecies* ltps = 0; + + std::string model = lowercase(trNode["model"]); + switch ( m_LTRmodelMap[model] ) { + case LTR_MODEL_CONSTANT: + ltps = new LTPspecies_Const( trNode, + name, + tp_ind, + thermo ); + break; + case LTR_MODEL_ARRHENIUS: + ltps = new LTPspecies_Arrhenius( trNode, + name, + tp_ind, + thermo ); + break; + case LTR_MODEL_POLY: + ltps = new LTPspecies_Poly( trNode, + name, + tp_ind, + thermo ); + break; + default: + throw CanteraError("newLTP","unknown transport model: " + model ); + ltps = new LTPspecies( trNode, + name, + tp_ind, + thermo ); + } + return ltps; + } + /** * make one of several transport models, and return a base class * pointer to it. @@ -337,9 +374,9 @@ namespace Cantera { dtr->initialize(phase, gastr); break; case cSimpleTransport: - tr = new SimpleTransport(); - initLiquidTransport(tr, phase, log_level); - tr->setThermo(*phase); + // tr = new SimpleTransport(); + // initLiquidTransport(tr, phase, log_level); + // tr->setThermo(*phase); break; #ifdef WITH_IDEAL_SOLUTIONS case cLiquidTransport: @@ -855,7 +892,6 @@ namespace Cantera { * Create a map of species names versus liquid transport data parameters */ std::map datatable; - doublereal A_k, n_k, Tact_k; int nsp = static_cast(xspecies.size()); std::cout << "Size of xspecies " << nsp << std::endl; @@ -864,7 +900,6 @@ namespace Cantera { // errors. Note that this procedure validates all entries, not // only those for the species listed in 'names'. - int linenum = 0; int i; for (i = 0; i < nsp; i++) { const XML_Node& sp = *xspecies[i]; @@ -883,202 +918,43 @@ namespace Cantera { LiquidTransportData data; data.speciesName = name; - /* - * hydrodynamic radius - * - * format: - * 3.0 - * 3.0 - * - * 1.0 - * 2.0 - * 3.0 - * - * - * - * 0.0. 1.0, 2.0, 3.0, 4.0 - * - * - */ - if (trNode.hasChild("hydrodynamicRadius")) { - XML_Node& hnode = trNode.child("hydrodynamicRadius"); - std::string units = lowercase(hnode["units"]); - if ( units == "" ) - std::cout << "Warning::hydrodynamicRadius units not given for " - << name << std::endl - << " Units assumed to be meters." << endl; - std::string model = lowercase(hnode["model"]); - if (model == "" || model == "constant") { - A_k = getFloat(trNode, "hydrodynamicRadius", "toSI"); - //A_k = hnode.fp_value(); - //// Angstroms -> meters - //A_k = 1.e-10 * A_k; - if (A_k > 0.0) { - (data.hydroRadiusCoeffs).push_back(A_k); - } else throw TransportDBError(linenum, - "negative or zero hydrodynamic radius"); - data.model_hydroradius = LTR_MODEL_CONSTANT; - } else if (model == "arrhenius") { - getArrhenius(hnode, A_k, n_k, Tact_k); - if (A_k <= 0.0) { - throw TransportDBError(linenum, "negative or zero hydrodynamic radius"); - } - // Angstroms -> meters - //already done in getArrhenius??? - //A_k = 1.e-10 * A_k; - (data.hydroRadiusCoeffs).push_back(A_k); - (data.hydroRadiusCoeffs).push_back(n_k); - (data.hydroRadiusCoeffs).push_back(Tact_k); - data.model_hydroradius = LTR_MODEL_ARRHENIUS; - } else if (model == "coeffs") { - getFloatArray(hnode, vCoeff, true); // if units labeled, convert Angstroms -> meters - data.hydroRadiusCoeffs = vCoeff; - vCoeff.clear(); - data.model_hydroradius = LTR_MODEL_POLY; - } else { - throw CanteraError(" TransportFactory::getLiquidSpeciesTransportData", - "Unknown model for hydrodynamicRadius:" + model); + //////// new stuff + int num = trNode.nChildren(); + for (int iChild = 0; iChild < num; iChild++) { + XML_Node &xmlChild = trNode.child(iChild); + std::string nodeName = xmlChild.name(); + + switch ( m_tranPropMap[nodeName] ) { + case TP_VISCOSITY: + data.viscosity = newLTP( xmlChild, + name, + m_tranPropMap[nodeName], + trParam.thermo ); + case TP_THERMALCOND: + data.thermalCond = newLTP( xmlChild, + name, + m_tranPropMap[nodeName], + trParam.thermo ); + case TP_DIFFUSIVITY: + data.speciesDiffusivity = newLTP( xmlChild, + name, + m_tranPropMap[nodeName], + trParam.thermo ); + case TP_HYDRORADIUS: + data.hydroradius = newLTP( xmlChild, + name, + m_tranPropMap[nodeName], + trParam.thermo ); + case TP_ELECTCOND: + data.electCond = newLTP( xmlChild, + name, + m_tranPropMap[nodeName], + trParam.thermo ); + } + } - /* - * viscosity - * - * format: - * 3.0 - * 3.0 - * - * 1.0 - * 2.0 - * 3.0 - * - * - * - * 0.0. 1.0, 2.0, 3.0, 4.0 - * - * - */ - if (trNode.hasChild("viscosity")) { - XML_Node& vnode = trNode.child("viscosity"); - std::string model = lowercase(vnode["model"]); - if (model == "" || model == "constant") { - A_k = ctml::getFloatCurrent(vnode, "toSI"); - if (A_k > 0.0) (data.viscCoeffs).push_back(A_k); - else throw TransportDBError(linenum, - "negative or zero viscosity"); - data.model_viscosity = LTR_MODEL_CONSTANT; - } else if (model == "arrhenius") { - getArrhenius(vnode, A_k, n_k, Tact_k); - if (A_k <= 0.0) { - throw TransportDBError(linenum, "negative or zero viscosity"); - } - (data.viscCoeffs).push_back(A_k); - (data.viscCoeffs).push_back(n_k); - (data.viscCoeffs).push_back(Tact_k); - data.model_viscosity = LTR_MODEL_ARRHENIUS; - } else if (model == "coeffs") { - getFloatArray(vnode, vCoeff, true); - data.viscCoeffs = vCoeff; - vCoeff.clear(); - data.model_viscosity = LTR_MODEL_POLY; - } else { - throw CanteraError(" TransportFactory::getLiquidSpeciesTransportData", - "Unknown model for viscosity:" + vnode["model"]); - } - } - - /* - * thermalConductivity - * - * format: - * 3.0 - * 3.0 - * - * 1.0 - * 2.0 - * 3.0 - * - * - * - * 0.0. 1.0, 2.0, 3.0, 4.0 - * - * - */ - if (trNode.hasChild("thermalConductivity")) { - XML_Node& tnode = trNode.child("thermalConductivity"); - std::string model = lowercase(tnode["model"]); - if (model == "" || model == "constant") { - A_k = ctml::getFloatCurrent(tnode, "toSI"); - if (A_k > 0.0) (data.thermalCondCoeffs).push_back(A_k); - else throw TransportDBError(linenum, - "negative or zero thermalConductivity"); - data.model_thermalCond = LTR_MODEL_CONSTANT; - } else if (model == "arrhenius") { - getArrhenius(tnode, A_k, n_k, Tact_k); - if (A_k <= 0.0) { - throw TransportDBError(linenum, "negative or zero thermalConductivity"); - } - (data.thermalCondCoeffs).push_back(A_k); - (data.thermalCondCoeffs).push_back(n_k); - (data.thermalCondCoeffs).push_back(Tact_k); - data.model_thermalCond = LTR_MODEL_ARRHENIUS; - } else if (model == "coeffs") { - getFloatArray(tnode, vCoeff, true); - data.thermalCondCoeffs = vCoeff; - vCoeff.clear(); - data.model_thermalCond = LTR_MODEL_POLY; - } else { - throw CanteraError(" TransportFactory::getLiquidSpeciesTransportData", - "Unknown model for thermalConductivity:" + tnode["model"]); - } - } - - - /* - * speciesDiffusivity - * - * format: - * 3.0 - * 3.0 - * - * 1.0 - * 2.0 - * 3.0 - * - * - * - * 0.0. 1.0, 2.0, 3.0, 4.0 - * - * - */ - if (trNode.hasChild("speciesDiffusivity")) { - XML_Node& dnode = trNode.child("speciesDiffusivity"); - std::string model = lowercase(dnode["model"]); - if (model == "" || model == "constant") { - A_k = ctml::getFloatCurrent(dnode, "toSI"); - if (A_k > 0.0) (data.speciesDiffusivityCoeffs).push_back(A_k); - else throw TransportDBError(linenum, - "negative or zero speciesDiffusivity"); - data.model_speciesDiffusivity = LTR_MODEL_CONSTANT; - } else if (model == "arrhenius") { - getArrhenius(dnode, A_k, n_k, Tact_k); - if (A_k <= 0.0) { - throw TransportDBError(linenum, "negative or zero speciesDiffusivity"); - } - (data.speciesDiffusivityCoeffs).push_back(A_k); - (data.speciesDiffusivityCoeffs).push_back(n_k); - (data.speciesDiffusivityCoeffs).push_back(Tact_k); - data.model_speciesDiffusivity = LTR_MODEL_ARRHENIUS; - } else if (model == "coeffs") { - getFloatArray(dnode, vCoeff, true); - data.speciesDiffusivityCoeffs = vCoeff; - data.model_speciesDiffusivity = LTR_MODEL_POLY; - } else { - throw CanteraError(" TransportFactory::getLiquidSpeciesTransportData", - "Unknown model for speciesDiffusivity:" + dnode["model"]); - } - } - datatable[name] = data; } } @@ -1095,7 +971,7 @@ namespace Cantera { // 'datatable' returns a default TransportData object if // the species name is not one in the transport database. // This can be detected by examining 'geometry'. - if (trdat.viscCoeffs[0] <= 0.0 ) { + if ( !( (trdat.viscosity)->checkPositive() ) ) { throw TransportDBError(0,"no viscosity transport data found for species " + names[i]); std::cout << "No viscosity seen for " << names[i] diff --git a/Cantera/src/transport/TransportFactory.h b/Cantera/src/transport/TransportFactory.h index d41e23d21..fbe8ecfc9 100644 --- a/Cantera/src/transport/TransportFactory.h +++ b/Cantera/src/transport/TransportFactory.h @@ -132,8 +132,21 @@ namespace Cantera { * @param thermo ThermoPhase object * @param log_level log level */ + + + /** + * make one of several transport models, and return a base class + * pointer to it. This method operates at the level of a + * single transport property as a function of temperature + * and possibly composition. + */ + virtual LTPspecies* + newLTP( const XML_Node &trNode, std::string &name, + TransportPropertyList tp_ind, thermo_t* thermo) ; + + virtual Transport* - newTransport(std::string model, thermo_t* thermo, int log_level=0); + newTransport(std::string model, thermo_t* thermo, int log_level=0); //! Build a new transport manager using the default transport manager //! in the phase description @@ -244,6 +257,14 @@ namespace Cantera { //! Mapping between between the string name //! for a transport model and the integer name. std::map m_models; + + //! Mapping between between the string name + //! for a transport property and the integer name. + std::map m_tranPropMap; + + //! Mapping between between the string name for a + //! species-specific transport property model and the integer name. + std::map m_LTRmodelMap; };