Cantera  2.1.2
TransportFactory.cpp
Go to the documentation of this file.
1 /**
2  * @file TransportFactory.cpp
3  *
4  * Implementation file for class TransportFactory.
5  */
6 
8 
9 // known transport models
19 
21 #include "MMCollisionInt.h"
22 
23 #include "cantera/base/xml.h"
24 #include "cantera/base/XML_Writer.h"
29 #include "cantera/base/global.h"
31 #include "cantera/base/ctml.h"
33 
34 #include <fstream>
35 
36 using namespace std;
37 
38 //! polynomial degree used for fitting collision integrals
39 //! except in CK mode, where the degree is 6.
40 #define COLL_INT_POLY_DEGREE 8
41 
42 namespace Cantera
43 {
44 /////////////////////////// constants //////////////////////////
45 //@ \cond
46 const doublereal ThreeSixteenths = 3.0/16.0;
47 const doublereal TwoOverPi = 2.0/Pi;
48 const doublereal FiveThirds = 5.0/3.0;
49 //@ \endcond
50 
51 TransportFactory* TransportFactory::s_factory = 0;
52 
53 // declaration of static storage for the mutex
54 mutex_t TransportFactory::transport_mutex;
55 
56 ////////////////////////// exceptions /////////////////////////
57 
58 //! Exception thrown if an error is encountered while reading the transport database
60 {
61 public:
62  //! Default constructor
63  /*!
64  * @param linenum inputs the line number
65  * @param msg String message to be sent to the user
66  */
67  TransportDBError(int linenum, const std::string& msg) :
68  CanteraError("getTransportData", "error reading transport data: " + msg + "\n") {
69  }
70 };
71 
72 //////////////////// class TransportFactory methods //////////////
73 
74 void TransportFactory::getBinDiffCorrection(doublereal t,
75  const GasTransportParams& tr, MMCollisionInt& integrals,
76  size_t k, size_t j, doublereal xk, doublereal xj,
77  doublereal& fkj, doublereal& fjk)
78 {
79  doublereal w1, w2, wsum, sig1, sig2, sig12, sigratio, sigratio2,
80  sigratio3, tstar1, tstar2, tstar12,
81  om22_1, om22_2, om11_12, astar_12, bstar_12, cstar_12,
82  cnst, wmwp, sqw12, p1, p2, p12, q1, q2, q12;
83 
84  w1 = tr.mw[k];
85  w2 = tr.mw[j];
86  wsum = w1 + w2;
87  wmwp = (w1 - w2)/wsum;
88  sqw12 = sqrt(w1*w2);
89 
90  sig1 = tr.sigma[k];
91  sig2 = tr.sigma[j];
92  sig12 = 0.5*(tr.sigma[k] + tr.sigma[j]);
93  sigratio = sig1*sig1/(sig2*sig2);
94  sigratio2 = sig1*sig1/(sig12*sig12);
95  sigratio3 = sig2*sig2/(sig12*sig12);
96 
97  tstar1 = Boltzmann * t / tr.eps[k];
98  tstar2 = Boltzmann * t / tr.eps[j];
99  tstar12 = Boltzmann * t / sqrt(tr.eps[k] * tr.eps[j]);
100 
101  om22_1 = integrals.omega22(tstar1, tr.delta(k,k));
102  om22_2 = integrals.omega22(tstar2, tr.delta(j,j));
103  om11_12 = integrals.omega11(tstar12, tr.delta(k,j));
104  astar_12 = integrals.astar(tstar12, tr.delta(k,j));
105  bstar_12 = integrals.bstar(tstar12, tr.delta(k,j));
106  cstar_12 = integrals.cstar(tstar12, tr.delta(k,j));
107 
108  cnst = sigratio * sqrt(2.0*w2/wsum) * 2.0 *
109  w1*w1/(wsum * w2);
110  p1 = cnst * om22_1 / om11_12;
111 
112  cnst = (1.0/sigratio) * sqrt(2.0*w1/wsum) * 2.0*w2*w2/(wsum*w1);
113  p2 = cnst * om22_2 / om11_12;
114 
115  p12 = 15.0 * wmwp*wmwp + 8.0*w1*w2*astar_12/(wsum*wsum);
116 
117  cnst = (2.0/(w2*wsum))*sqrt(2.0*w2/wsum)*sigratio2;
118  q1 = cnst*((2.5 - 1.2*bstar_12)*w1*w1 + 3.0*w2*w2
119  + 1.6*w1*w2*astar_12);
120 
121  cnst = (2.0/(w1*wsum))*sqrt(2.0*w1/wsum)*sigratio3;
122  q2 = cnst*((2.5 - 1.2*bstar_12)*w2*w2 + 3.0*w1*w1
123  + 1.6*w1*w2*astar_12);
124 
125  q12 = wmwp*wmwp*15.0*(2.5 - 1.2*bstar_12)
126  + 4.0*w1*w2*astar_12*(11.0 - 2.4*bstar_12)/(wsum*wsum)
127  + 1.6*wsum*om22_1*om22_2/(om11_12*om11_12*sqw12)
128  * sigratio2 * sigratio3;
129 
130  cnst = 6.0*cstar_12 - 5.0;
131  fkj = 1.0 + 0.1*cnst*cnst *
132  (p1*xk*xk + p2*xj*xj + p12*xk*xj)/
133  (q1*xk*xk + q2*xj*xj + q12*xk*xj);
134  fjk = 1.0 + 0.1*cnst*cnst *
135  (p2*xk*xk + p1*xj*xj + p12*xk*xj)/
136  (q2*xk*xk + q1*xj*xj + q12*xk*xj);
137 }
138 
139 void TransportFactory::makePolarCorrections(size_t i, size_t j,
140  const GasTransportParams& tr, doublereal& f_eps, doublereal& f_sigma)
141 {
142  // no correction if both are nonpolar, or both are polar
143  if (tr.polar[i] == tr.polar[j]) {
144  f_eps = 1.0;
145  f_sigma = 1.0;
146  return;
147  }
148 
149  // corrections to the effective diameter and well depth
150  // if one is polar and one is non-polar
151 
152  size_t kp = (tr.polar[i] ? i : j); // the polar one
153  size_t knp = (i == kp ? j : i); // the nonpolar one
154 
155  doublereal d3np, d3p, alpha_star, mu_p_star, xi;
156  d3np = pow(tr.sigma[knp],3);
157  d3p = pow(tr.sigma[kp],3);
158  alpha_star = tr.alpha[knp]/d3np;
159  mu_p_star = tr.dipole(kp,kp)/sqrt(d3p * tr.eps[kp]);
160  xi = 1.0 + 0.25 * alpha_star * mu_p_star * mu_p_star *
161  sqrt(tr.eps[kp]/tr.eps[knp]);
162  f_sigma = pow(xi, -1.0/6.0);
163  f_eps = xi*xi;
164 }
165 
166 TransportFactory::TransportFactory() :
167  m_verbose(false)
168 {
169  m_models["Mix"] = cMixtureAveraged;
170  m_models["Multi"] = cMulticomponent;
171  m_models["Solid"] = cSolidTransport;
172  m_models["DustyGas"] = cDustyGasTransport;
173  m_models["CK_Multi"] = CK_Multicomponent;
174  m_models["CK_Mix"] = CK_MixtureAveraged;
175  m_models["Liquid"] = cLiquidTransport;
176  m_models["Aqueous"] = cAqueousTransport;
177  m_models["Simple"] = cSimpleTransport;
178  m_models["User"] = cUserTransport;
179  m_models["Pecos"] = cPecosTransport;
180  m_models["None"] = None;
181  //m_models["Radiative"] = cRadiative;
182  for (map<string, int>::iterator iter = m_models.begin();
183  iter != m_models.end();
184  iter++) {
185  m_modelNames[iter->second] = iter->first;
186  }
187 
188  m_tranPropMap["viscosity"] = TP_VISCOSITY;
189  m_tranPropMap["ionConductivity"] = TP_IONCONDUCTIVITY;
190  m_tranPropMap["mobilityRatio"] = TP_MOBILITYRATIO;
191  m_tranPropMap["selfDiffusion"] = TP_SELFDIFFUSION;
192  m_tranPropMap["thermalConductivity"] = TP_THERMALCOND;
193  m_tranPropMap["speciesDiffusivity"] = TP_DIFFUSIVITY;
194  m_tranPropMap["hydrodynamicRadius"] = TP_HYDRORADIUS;
195  m_tranPropMap["electricalConductivity"] = TP_ELECTCOND;
196  m_tranPropMap["defectDiffusivity"] = TP_DEFECTDIFF;
197  m_tranPropMap["defectActivity"] = TP_DEFECTCONC;
198 
199  m_LTRmodelMap[""] = LTP_TD_CONSTANT;
200  m_LTRmodelMap["constant"] = LTP_TD_CONSTANT;
201  m_LTRmodelMap["arrhenius"] = LTP_TD_ARRHENIUS;
202  m_LTRmodelMap["coeffs"] = LTP_TD_POLY;
203  m_LTRmodelMap["exptemp"] = LTP_TD_EXPT;
204 
205  m_LTImodelMap[""] = LTI_MODEL_NOTSET;
206  m_LTImodelMap["none"] = LTI_MODEL_NONE;
207  m_LTImodelMap["solvent"] = LTI_MODEL_SOLVENT;
208  m_LTImodelMap["moleFractions"] = LTI_MODEL_MOLEFRACS;
209  m_LTImodelMap["massFractions"] = LTI_MODEL_MASSFRACS;
210  m_LTImodelMap["logMoleFractions"] = LTI_MODEL_LOG_MOLEFRACS;
211  m_LTImodelMap["pairwiseInteraction"] = LTI_MODEL_PAIRWISE_INTERACTION;
212  m_LTImodelMap["stefanMaxwell_PPN"] = LTI_MODEL_STEFANMAXWELL_PPN;
213  m_LTImodelMap["moleFractionsExpT"] = LTI_MODEL_MOLEFRACS_EXPT;
214 }
215 
217 {
218  ScopedLock transportLock(transport_mutex);
219  if (s_factory) {
220  delete s_factory;
221  s_factory = 0;
222  }
223 }
224 
225 std::string TransportFactory::modelName(int model)
226 {
227  TransportFactory& f = *factory();
228  map<int, string>::iterator iter = f.m_modelNames.find(model);
229  if (iter != f.m_modelNames.end()) {
230  return iter->second;
231  } else {
232  return "";
233  }
234 }
235 
236 LTPspecies* TransportFactory::newLTP(const XML_Node& trNode, const std::string& name,
237  TransportPropertyType tp_ind, thermo_t* thermo)
238 {
239  LTPspecies* ltps = 0;
240  std::string model = lowercase(trNode["model"]);
241  switch (m_LTRmodelMap[model]) {
242  case LTP_TD_CONSTANT:
243  ltps = new LTPspecies_Const(trNode, name, tp_ind, thermo);
244  break;
245  case LTP_TD_ARRHENIUS:
246  ltps = new LTPspecies_Arrhenius(trNode, name, tp_ind, thermo);
247  break;
248  case LTP_TD_POLY:
249  ltps = new LTPspecies_Poly(trNode, name, tp_ind, thermo);
250  break;
251  case LTP_TD_EXPT:
252  ltps = new LTPspecies_ExpT(trNode, name, tp_ind, thermo);
253  break;
254  default:
255  throw CanteraError("newLTP","unknown transport model: " + model);
256  ltps = new LTPspecies(&trNode, name, tp_ind, thermo);
257  }
258  return ltps;
259 }
260 
262  TransportPropertyType tp_ind,
263  LiquidTransportParams& trParam)
264 {
265  LiquidTranInteraction* lti = 0;
266 
267  thermo_t* thermo = trParam.thermo;
268 
269  std::string model = trNode["model"];
270  switch (m_LTImodelMap[model]) {
271  case LTI_MODEL_SOLVENT:
272  lti = new LTI_Solvent(tp_ind);
273  lti->init(trNode, thermo);
274  break;
275  case LTI_MODEL_MOLEFRACS:
276  lti = new LTI_MoleFracs(tp_ind);
277  lti->init(trNode, thermo);
278  break;
279  case LTI_MODEL_MASSFRACS:
280  lti = new LTI_MassFracs(tp_ind);
281  lti->init(trNode, thermo);
282  break;
283  case LTI_MODEL_LOG_MOLEFRACS:
284  lti = new LTI_Log_MoleFracs(tp_ind);
285  lti->init(trNode, thermo);
286  break;
287  case LTI_MODEL_PAIRWISE_INTERACTION:
288  lti = new LTI_Pairwise_Interaction(tp_ind);
289  lti->init(trNode, thermo);
290  lti->setParameters(trParam);
291  break;
292  case LTI_MODEL_STEFANMAXWELL_PPN:
293  lti = new LTI_StefanMaxwell_PPN(tp_ind);
294  lti->init(trNode, thermo);
295  lti->setParameters(trParam);
296  break;
297  case LTI_MODEL_STOKES_EINSTEIN:
298  lti = new LTI_StokesEinstein(tp_ind);
299  lti->init(trNode, thermo);
300  lti->setParameters(trParam);
301  break;
302  case LTI_MODEL_MOLEFRACS_EXPT:
303  lti = new LTI_MoleFracs_ExpT(tp_ind);
304  lti->init(trNode, thermo);
305  break;
306  default:
307  // throw CanteraError("newLTI","unknown transport model: " + model );
308  lti = new LiquidTranInteraction(tp_ind);
309  lti->init(trNode, thermo);
310  }
311  return lti;
312 }
313 
314 Transport* TransportFactory::newTransport(const std::string& transportModel,
315  thermo_t* phase, int log_level, int ndim)
316 {
317 
318  if (transportModel == "") {
319  return new Transport;
320  }
321 
322 
323  vector_fp state;
324  Transport* tr = 0, *gastr = 0;
325  DustyGasTransport* dtr = 0;
326  phase->saveState(state);
327 
328  switch (m_models[transportModel]) {
329  case None:
330  tr = new Transport;
331  break;
332  case cMulticomponent:
333  tr = new MultiTransport;
334  initTransport(tr, phase, 0, log_level);
335  break;
336  case CK_Multicomponent:
337  tr = new MultiTransport;
338  initTransport(tr, phase, CK_Mode, log_level);
339  break;
340  case cMixtureAveraged:
341  tr = new MixTransport;
342  initTransport(tr, phase, 0, log_level);
343  break;
344  case CK_MixtureAveraged:
345  tr = new MixTransport;
346  initTransport(tr, phase, CK_Mode, log_level);
347  break;
348  // adding pecos transport model 2/13/12
349  case cPecosTransport:
350  tr = new PecosTransport;
351  initTransport(tr, phase, 0, log_level);
352  break;
353  case cSolidTransport:
354 
355  tr = new SolidTransport;
356  initSolidTransport(tr, phase, log_level);
357  tr->setThermo(*phase);
358  break;
359  case cDustyGasTransport:
360  tr = new DustyGasTransport;
361  gastr = new MultiTransport;
362  initTransport(gastr, phase, 0, log_level);
363  dtr = (DustyGasTransport*)tr;
364  dtr->initialize(phase, gastr);
365  break;
366  case cSimpleTransport:
367  tr = new SimpleTransport();
368  initLiquidTransport(tr, phase, log_level);
369  tr->setThermo(*phase);
370  break;
371  case cLiquidTransport:
372  tr = new LiquidTransport(phase, ndim);
373  initLiquidTransport(tr, phase, log_level);
374  tr->setThermo(*phase);
375  break;
376  case cAqueousTransport:
377  tr = new AqueousTransport;
378  initLiquidTransport(tr, phase, log_level);
379  tr->setThermo(*phase);
380  break;
381  default:
382  throw CanteraError("newTransport","unknown transport model: " + transportModel);
383  }
384  phase->restoreState(state);
385  return tr;
386 }
387 
389 {
390  XML_Node& phaseNode=phase->xml();
391  /*
392  * Find the Thermo XML node
393  */
394  if (!phaseNode.hasChild("transport")) {
395  throw CanteraError("TransportFactory::newTransport",
396  "no transport XML node");
397  }
398  XML_Node& transportNode = phaseNode.child("transport");
399  std::string transportModel = transportNode.attrib("model");
400  if (transportModel == "") {
401  throw CanteraError("TransportFactory::newTransport",
402  "transport XML node doesn't have a model string");
403  }
404  return newTransport(transportModel, phase,log_level);
405 }
406 
407 void TransportFactory::setupMM(std::ostream& flog, const std::vector<const XML_Node*> &transport_database,
408  thermo_t* thermo, int mode, int log_level, GasTransportParams& tr)
409 {
410 
411  // constant mixture attributes
412  tr.thermo = thermo;
413  tr.nsp_ = tr.thermo->nSpecies();
414  size_t nsp = tr.nsp_;
415 
416  tr.tmin = thermo->minTemp();
417  tr.tmax = thermo->maxTemp();
418  tr.mw.resize(nsp);
419  tr.log_level = log_level;
420 
421  copy(tr.thermo->molecularWeights().begin(), tr.thermo->molecularWeights().end(), tr.mw.begin());
422 
423  tr.mode_ = mode;
424  tr.epsilon.resize(nsp, nsp, 0.0);
425  tr.delta.resize(nsp, nsp, 0.0);
426  tr.reducedMass.resize(nsp, nsp, 0.0);
427  tr.dipole.resize(nsp, nsp, 0.0);
428  tr.diam.resize(nsp, nsp, 0.0);
429  tr.crot.resize(nsp);
430  tr.zrot.resize(nsp);
431  tr.polar.resize(nsp, false);
432  tr.alpha.resize(nsp, 0.0);
433  tr.poly.resize(nsp);
434  tr.sigma.resize(nsp);
435  tr.eps.resize(nsp);
436 
437  XML_Node root, log;
438  getTransportData(transport_database, log, tr.thermo->speciesNames(), tr);
439 
440  for (size_t i = 0; i < nsp; i++) {
441  tr.poly[i].resize(nsp);
442  }
443 
444  doublereal ts1, ts2, tstar_min = 1.e8, tstar_max = 0.0;
445  doublereal f_eps, f_sigma;
446 
447  DenseMatrix& diam = tr.diam;
448  DenseMatrix& epsilon = tr.epsilon;
449 
450  for (size_t i = 0; i < nsp; i++) {
451  for (size_t j = i; j < nsp; j++) {
452  // the reduced mass
453  tr.reducedMass(i,j) = tr.mw[i] * tr.mw[j] / (Avogadro * (tr.mw[i] + tr.mw[j]));
454 
455  // hard-sphere diameter for (i,j) collisions
456  diam(i,j) = 0.5*(tr.sigma[i] + tr.sigma[j]);
457 
458  // the effective well depth for (i,j) collisions
459  epsilon(i,j) = sqrt(tr.eps[i]*tr.eps[j]);
460 
461  // The polynomial fits of collision integrals vs. T*
462  // will be done for the T* from tstar_min to tstar_max
463  ts1 = Boltzmann * tr.tmin/epsilon(i,j);
464  ts2 = Boltzmann * tr.tmax/epsilon(i,j);
465  if (ts1 < tstar_min) {
466  tstar_min = ts1;
467  }
468  if (ts2 > tstar_max) {
469  tstar_max = ts2;
470  }
471 
472  // the effective dipole moment for (i,j) collisions
473  tr.dipole(i,j) = sqrt(tr.dipole(i,i)*tr.dipole(j,j));
474 
475  // reduced dipole moment delta* (nondimensional)
476  doublereal d = diam(i,j);
477  tr.delta(i,j) = 0.5 * tr.dipole(i,j)*tr.dipole(i,j)
478  / (epsilon(i,j) * d * d * d);
479 
480  makePolarCorrections(i, j, tr, f_eps, f_sigma);
481  tr.diam(i,j) *= f_sigma;
482  epsilon(i,j) *= f_eps;
483 
484  // properties are symmetric
485  tr.reducedMass(j,i) = tr.reducedMass(i,j);
486  diam(j,i) = diam(i,j);
487  epsilon(j,i) = epsilon(i,j);
488  tr.dipole(j,i) = tr.dipole(i,j);
489  tr.delta(j,i) = tr.delta(i,j);
490  }
491  }
492 
493  // Chemkin fits the entire T* range in the Monchick and Mason tables,
494  // so modify tstar_min and tstar_max if in Chemkin compatibility mode
495 
496  if (mode == CK_Mode) {
497  tstar_min = 0.101;
498  tstar_max = 99.9;
499  }
500 
501 
502  // initialize the collision integral calculator for the desired
503  // T* range
504 #ifdef DEBUG_MODE
505  if (m_verbose) {
506  tr.xml->XML_open(flog, "collision_integrals");
507  }
508 #endif
509  MMCollisionInt integrals;
510  integrals.init(tr.xml, tstar_min, tstar_max, log_level);
511  fitCollisionIntegrals(flog, tr, integrals);
512 #ifdef DEBUG_MODE
513  if (m_verbose) {
514  tr.xml->XML_close(flog, "collision_integrals");
515  }
516 #endif
517  // make polynomial fits
518 #ifdef DEBUG_MODE
519  if (m_verbose) {
520  tr.xml->XML_open(flog, "property fits");
521  }
522 #endif
523  fitProperties(tr, integrals, flog);
524 #ifdef DEBUG_MODE
525  if (m_verbose) {
526  tr.xml->XML_close(flog, "property fits");
527  }
528 #endif
529 }
530 
531 void TransportFactory::setupLiquidTransport(std::ostream& flog, thermo_t* thermo, int log_level,
532  LiquidTransportParams& trParam)
533 {
534 
535  const std::vector<const XML_Node*> & species_database = thermo->speciesData();
536  const XML_Node* phase_database = &thermo->xml();
537 
538  // constant mixture attributes
539  trParam.thermo = thermo;
540  trParam.nsp_ = trParam.thermo->nSpecies();
541  size_t nsp = trParam.nsp_;
542 
543  trParam.tmin = thermo->minTemp();
544  trParam.tmax = thermo->maxTemp();
545  trParam.log_level = log_level;
546 
547  // Get the molecular weights and load them into trParam
548  trParam.mw.resize(nsp);
549  copy(trParam.thermo->molecularWeights().begin(),
550  trParam.thermo->molecularWeights().end(), trParam.mw.begin());
551 
552  // Resize all other vectors in trParam
553  trParam.LTData.resize(nsp);
554 
555  // Need to identify a method to obtain interaction matrices.
556  // This will fill LiquidTransportParams members visc_Eij, visc_Sij
557  // trParam.visc_Eij.resize(nsp,nsp);
558  // trParam.visc_Sij.resize(nsp,nsp);
559  trParam.thermalCond_Aij.resize(nsp,nsp);
560  trParam.diff_Dij.resize(nsp,nsp);
561  trParam.radius_Aij.resize(nsp,nsp);
562 
563  XML_Node root, log;
564  // Note that getLiquidSpeciesTransportData just populates the pure species transport data.
565  getLiquidSpeciesTransportData(species_database, log, trParam.thermo->speciesNames(), trParam);
566 
567  // getLiquidInteractionsTransportData() populates the
568  // species-species interaction models parameters
569  // like visc_Eij
570  if (phase_database->hasChild("transport")) {
571  XML_Node& transportNode = phase_database->child("transport");
572  getLiquidInteractionsTransportData(transportNode, log, trParam.thermo->speciesNames(), trParam);
573  }
574 
575 }
576 
577 void TransportFactory::setupSolidTransport(std::ostream& flog, thermo_t* thermo, int log_level,
578  SolidTransportData& trParam)
579 {
580  const XML_Node* phase_database = &thermo->xml();
581 
582  // constant mixture attributes
583  trParam.thermo = thermo;
584  trParam.nsp_ = trParam.thermo->nSpecies();
585  int nsp = trParam.nsp_;
586 
587  trParam.tmin = thermo->minTemp();
588  trParam.tmax = thermo->maxTemp();
589  trParam.log_level = log_level;
590 
591  // Get the molecular weights and load them into trParam
592  trParam.mw.resize(nsp);
593  copy(trParam.thermo->molecularWeights().begin(),
594  trParam.thermo->molecularWeights().end(), trParam.mw.begin());
595 
596  // Resize all other vectors in trParam
597  //trParam.LTData.resize(nsp);
598 
599  XML_Node root, log;
600 
601  // Note that getSolidSpeciesTransportData just populates the pure species transport data.
602  // const std::vector<const XML_Node*> & species_database = thermo->speciesData();
603  // getSolidSpeciesTransportData(species_database, log, trParam.thermo->speciesNames(), trParam);
604 
605  // getSolidTransportData() populates the
606  // phase transport models like electronic conductivity
607  // thermal conductivity, interstitial diffusion
608  if (phase_database->hasChild("transport")) {
609  XML_Node& transportNode = phase_database->child("transport");
610  getSolidTransportData(transportNode, log, thermo->name(), trParam);
611  }
612 }
613 
615  thermo_t* thermo, int mode, int log_level)
616 {
617  ScopedLock transportLock(transport_mutex);
618 
619  const std::vector<const XML_Node*> & transport_database = thermo->speciesData();
620 
621  GasTransportParams trParam;
622 #ifdef DEBUG_MODE
623  if (log_level == 0) {
624  m_verbose = 0;
625  }
626  ofstream flog("transport_log.xml");
627  trParam.xml = new XML_Writer(flog);
628  if (m_verbose) {
629  trParam.xml->XML_open(flog, "transport");
630  }
631 #else
632  // create the object, but don't associate it with a file
633  std::ostream& flog(std::cout);
634 #endif
635  // set up Monchick and Mason collision integrals
636  setupMM(flog, transport_database, thermo, mode, log_level, trParam);
637  // do model-specific initialization
638  tran->initGas(trParam);
639 #ifdef DEBUG_MODE
640  if (m_verbose) {
641  trParam.xml->XML_close(flog, "transport");
642  }
643  // finished with log file
644  flog.close();
645 #endif
646  return;
647 }
648 
650  thermo_t* thermo,
651  int log_level)
652 {
653  LiquidTransportParams trParam;
654 #ifdef DEBUG_MODE
655  ofstream flog("transport_log.xml");
656  trParam.xml = new XML_Writer(flog);
657  if (m_verbose) {
658  trParam.xml->XML_open(flog, "transport");
659  }
660 #else
661  // create the object, but don't associate it with a file
662  std::ostream& flog(std::cout);
663 #endif
664  setupLiquidTransport(flog, thermo, log_level, trParam);
665  // do model-specific initialization
666  tran->initLiquid(trParam);
667 #ifdef DEBUG_MODE
668  if (m_verbose) {
669  trParam.xml->XML_close(flog, "transport");
670  }
671  // finished with log file
672  flog.close();
673 #endif
674  return;
675 }
676 
678  thermo_t* thermo,
679  int log_level)
680 {
681  SolidTransportData trParam;
682 
683  //setup output
684 #ifdef DEBUG_MODE
685  ofstream flog("transport_log.xml");
686  trParam.xml = new XML_Writer(flog);
687  if (m_verbose) {
688  trParam.xml->XML_open(flog, "transport");
689  }
690 #else
691  // create the object, but don't associate it with a file
692  std::ostream& flog(std::cout);
693 #endif
694 
695  //real work next two statements
696  setupSolidTransport(flog, thermo, log_level, trParam);
697  // do model-specific initialization
698  tran->initSolid(trParam);
699 
700 
701 #ifdef DEBUG_MODE
702  if (m_verbose) {
703  trParam.xml->XML_close(flog, "transport");
704  }
705  // finished with log file
706  flog.close();
707 #endif
708  return;
709 }
710 
712  GasTransportParams& tr,
713  MMCollisionInt& integrals)
714 {
715  vector_fp::iterator dptr;
716  doublereal dstar;
717  size_t nsp = tr.nsp_;
718  int mode = tr.mode_;
719  size_t i, j;
720 
721  // Chemkin fits to sixth order polynomials
722  int degree = (mode == CK_Mode ? 6 : COLL_INT_POLY_DEGREE);
723 #ifdef DEBUG_MODE
724  if (m_verbose) {
725  tr.xml->XML_open(logfile, "tstar_fits");
726  tr.xml->XML_comment(logfile, "fits to A*, B*, and C* vs. log(T*).\n"
727  "These are done only for the required dstar(j,k) values.");
728  if (tr.log_level < 3) {
729  tr.xml->XML_comment(logfile, "*** polynomial coefficients not printed (log_level < 3) ***");
730  }
731  }
732 #endif
733  for (i = 0; i < nsp; i++) {
734  for (j = i; j < nsp; j++) {
735  // Chemkin fits only delta* = 0
736  if (mode != CK_Mode) {
737  dstar = tr.delta(i,j);
738  } else {
739  dstar = 0.0;
740  }
741 
742  // if a fit has already been generated for
743  // delta* = tr.delta(i,j), then use it. Otherwise,
744  // make a new fit, and add tr.delta(i,j) to the list
745  // of delta* values for which fits have been done.
746 
747  // 'find' returns a pointer to end() if not found
748  dptr = find(tr.fitlist.begin(), tr.fitlist.end(), dstar);
749  if (dptr == tr.fitlist.end()) {
750  vector_fp ca(degree+1), cb(degree+1), cc(degree+1);
751  vector_fp co22(degree+1);
752  integrals.fit(logfile, degree, dstar,
753  DATA_PTR(ca), DATA_PTR(cb), DATA_PTR(cc));
754  integrals.fit_omega22(logfile, degree, dstar,
755  DATA_PTR(co22));
756  tr.omega22_poly.push_back(co22);
757  tr.astar_poly.push_back(ca);
758  tr.bstar_poly.push_back(cb);
759  tr.cstar_poly.push_back(cc);
760  tr.poly[i][j] = static_cast<int>(tr.astar_poly.size()) - 1;
761  tr.fitlist.push_back(dstar);
762  }
763 
764  // delta* found in fitlist, so just point to this
765  // polynomial
766  else {
767  tr.poly[i][j] = static_cast<int>((dptr - tr.fitlist.begin()));
768  }
769  tr.poly[j][i] = tr.poly[i][j];
770  }
771  }
772 #ifdef DEBUG_MODE
773  if (m_verbose) {
774  tr.xml->XML_close(logfile, "tstar_fits");
775  }
776 #endif
777 }
778 
779 void TransportFactory::getTransportData(const std::vector<const XML_Node*> &xspecies,
780  XML_Node& log, const std::vector<std::string> &names, GasTransportParams& tr)
781 {
782  std::map<std::string, size_t> speciesIndices;
783  for (size_t i = 0; i < names.size(); i++) {
784  speciesIndices[names[i]] = i;
785  }
786 
787  for (size_t i = 0; i < xspecies.size(); i++) {
788  const XML_Node& sp = *xspecies[i];
789 
790  // Find the index for this species in 'names'
791  std::map<std::string, size_t>::const_iterator iter =
792  speciesIndices.find(sp["name"]);
793  size_t j;
794  if (iter != speciesIndices.end()) {
795  j = iter->second;
796  } else {
797  // Don't need transport data for this species
798  continue;
799  }
800 
801  XML_Node& node = sp.child("transport");
802 
803  // parameters are converted to SI units before storing
804 
805  // Molecular geometry; rotational heat capacity / R
806  XML_Node* geomNode = ctml::getByTitle(node, "geometry");
807  std::string geom = (geomNode) ? geomNode->value() : "";
808  if (geom == "atom") {
809  tr.crot[j] = 0.0;
810  } else if (geom == "linear") {
811  tr.crot[j] = 1.0;
812  } else if (geom == "nonlinear") {
813  tr.crot[j] = 1.5;
814  } else {
815  throw TransportDBError(i, "invalid geometry");
816  }
817 
818  // Well-depth parameter in Kelvin (converted to Joules)
819  double welldepth = ctml::getFloat(node, "LJ_welldepth");
820  if (welldepth >= 0.0) {
821  tr.eps[j] = Boltzmann * welldepth;
822  } else {
823  throw TransportDBError(i, "negative well depth");
824  }
825 
826  // Lennard-Jones diameter of the molecule, given in Angstroms.
827  double diam = ctml::getFloat(node, "LJ_diameter");
828  if (diam > 0.0) {
829  tr.sigma[j] = 1.e-10 * diam; // A -> m
830  } else {
831  throw TransportDBError(i, "negative or zero diameter");
832  }
833 
834  // Dipole moment of the molecule.
835  // Given in Debye (a debye is 10-18 cm3/2 erg1/2)
836  double dipole = ctml::getFloat(node, "dipoleMoment");
837  if (dipole >= 0.0) {
838  tr.dipole(j,j) = 1.e-25 * SqrtTen * dipole;
839  tr.polar[j] = (dipole > 0.0);
840  } else {
841  throw TransportDBError(i, "negative dipole moment");
842  }
843 
844  // Polarizability of the molecule, given in cubic Angstroms.
845  double polar = ctml::getFloat(node, "polarizability");
846  if (polar >= 0.0) {
847  tr.alpha[j] = 1.e-30 * polar; // A^3 -> m^3
848  } else {
849  throw TransportDBError(i, "negative polarizability");
850  }
851 
852  // Rotational relaxation number. (Number of collisions it takes to
853  // equilibrate the rotational dofs with the temperature)
854  double rot = ctml::getFloat(node, "rotRelax");
855  if (rot >= 0.0) {
856  tr.zrot[j] = std::max(1.0, rot);
857  } else {
858  throw TransportDBError(i, "negative rotation relaxation number");
859  }
860  }
861 }
862 
863 void TransportFactory::getLiquidSpeciesTransportData(const std::vector<const XML_Node*> &xspecies,
864  XML_Node& log,
865  const std::vector<std::string> &names,
866  LiquidTransportParams& trParam)
867 {
868  std::string name;
869  /*
870  Create a map of species names versus liquid transport data parameters
871  */
872  std::map<std::string, LiquidTransportData> datatable;
873  std::map<std::string, LiquidTransportData>::iterator it;
874 
875  // Store the number of species in the phase
876  size_t nsp = trParam.nsp_;
877 
878  // Store the number of off-diagonal symmetric interactions between species in the phase
879  size_t nBinInt = nsp*(nsp-1)/2;
880 
881  // read all entries in database into 'datatable' and check for
882  // errors. Note that this procedure validates all entries, not
883  // only those for the species listed in 'names'.
884  for (size_t i = 0; i < nsp; i++) {
885  const XML_Node& sp = *xspecies[i];
886  name = sp["name"];
887  vector_fp vCoeff;
888 
889  // Species with no 'transport' child are skipped. However, if that species is in the list,
890  // it will throw an exception below.
891  try {
892  if (sp.hasChild("transport")) {
893  XML_Node& trNode = sp.child("transport");
894 
895  // Fill datatable with LiquidTransportData objects for error checking
896  // and then insertion into LiquidTransportData objects below.
897  LiquidTransportData data;
898  data.speciesName = name;
899  data.mobilityRatio.resize(nsp*nsp,0);
900  data.selfDiffusion.resize(nsp,0);
901  ThermoPhase* temp_thermo = trParam.thermo;
902 
903  size_t num = trNode.nChildren();
904  for (size_t iChild = 0; iChild < num; iChild++) {
905  XML_Node& xmlChild = trNode.child(iChild);
906  std::string nodeName = xmlChild.name();
907 
908  switch (m_tranPropMap[nodeName]) {
909  case TP_VISCOSITY:
910  data.viscosity = newLTP(xmlChild, name, m_tranPropMap[nodeName], temp_thermo);
911  break;
912  case TP_IONCONDUCTIVITY:
913  data.ionConductivity = newLTP(xmlChild, name, m_tranPropMap[nodeName], temp_thermo);
914  break;
915  case TP_MOBILITYRATIO: {
916  for (size_t iSpec = 0; iSpec< nBinInt; iSpec++) {
917  XML_Node& propSpecNode = xmlChild.child(iSpec);
918  std::string specName = propSpecNode.name();
919  size_t loc = specName.find(":");
920  std::string firstSpec = specName.substr(0,loc);
921  std::string secondSpec = specName.substr(loc+1);
922  size_t index = temp_thermo->speciesIndex(firstSpec.c_str())+nsp*temp_thermo->speciesIndex(secondSpec.c_str());
923  data.mobilityRatio[index] = newLTP(propSpecNode, name, m_tranPropMap[nodeName], temp_thermo);
924  };
925  };
926  break;
927  case TP_SELFDIFFUSION: {
928  for (size_t iSpec = 0; iSpec< nsp; iSpec++) {
929  XML_Node& propSpecNode = xmlChild.child(iSpec);
930  std::string specName = propSpecNode.name();
931  size_t index = temp_thermo->speciesIndex(specName.c_str());
932  data.selfDiffusion[index] = newLTP(propSpecNode, name, m_tranPropMap[nodeName], temp_thermo);
933  };
934  };
935  break;
936  case TP_THERMALCOND:
937  data.thermalCond = newLTP(xmlChild,
938  name,
939  m_tranPropMap[nodeName],
940  temp_thermo);
941  break;
942  case TP_DIFFUSIVITY:
943  data.speciesDiffusivity = newLTP(xmlChild,
944  name,
945  m_tranPropMap[nodeName],
946  temp_thermo);
947  break;
948  case TP_HYDRORADIUS:
949  data.hydroRadius = newLTP(xmlChild,
950  name,
951  m_tranPropMap[nodeName],
952  temp_thermo);
953  break;
954  case TP_ELECTCOND:
955  data.electCond = newLTP(xmlChild,
956  name,
957  m_tranPropMap[nodeName],
958  temp_thermo);
959 
960  break;
961  default:
962  throw CanteraError("getLiquidSpeciesTransportData","unknown transport property: " + nodeName);
963  }
964 
965  }
966  datatable.insert(pair<std::string, LiquidTransportData>(name,data));
967  }
968  } catch (CanteraError& err) {
969  err.save();
970  throw err;
971  }
972  }
973 
974  trParam.LTData.clear();
975  for (size_t i = 0; i < trParam.nsp_; i++) {
976  /*
977  Check to see that we have a LiquidTransportData object for all of the
978  species in the phase. If not, throw an error.
979  */
980  it = datatable.find(names[i]);
981  if (it == datatable.end()) {
982  throw TransportDBError(0,"No transport data found for species " + names[i]);
983  }
984  LiquidTransportData& trdat = it->second;
985 
986  /*
987  Now, transfer these objects into LTData in the correct phase index order by
988  calling the default copy constructor for LiquidTransportData.
989  */
990  trParam.LTData.push_back(trdat);
991  }
992 }
993 
994 
995 /*
996  Read transport property data from a file for interactions
997  between species in a liquid.
998  Given the name of a file containing transport property
999  parameters and a list of species names, this method returns an
1000  instance of TransportParams containing the transport data for
1001  these species read from the file.
1002 */
1004  XML_Node& log,
1005  const std::vector<std::string> &names,
1006  LiquidTransportParams& trParam)
1007 {
1008  try {
1009 
1010  size_t nsp = trParam.nsp_;
1011  size_t nBinInt = nsp*(nsp-1)/2;
1012 
1013  size_t num = transportNode.nChildren();
1014  for (size_t iChild = 0; iChild < num; iChild++) {
1015  //tranTypeNode is a type of transport property like viscosity
1016  XML_Node& tranTypeNode = transportNode.child(iChild);
1017  std::string nodeName = tranTypeNode.name();
1018 
1019  trParam.mobilityRatio.resize(nsp*nsp,0);
1020  trParam.selfDiffusion.resize(nsp,0);
1021  ThermoPhase* temp_thermo = trParam.thermo;
1022 
1023 
1024  if (tranTypeNode.hasChild("compositionDependence")) {
1025  //compDepNode contains the interaction model
1026  XML_Node& compDepNode = tranTypeNode.child("compositionDependence");
1027  switch (m_tranPropMap[nodeName]) {
1028  break;
1029  case TP_VISCOSITY:
1030  trParam.viscosity = newLTI(compDepNode, m_tranPropMap[nodeName], trParam);
1031  break;
1032  case TP_IONCONDUCTIVITY:
1033  trParam.ionConductivity = newLTI(compDepNode,
1034  m_tranPropMap[nodeName],
1035  trParam);
1036  break;
1037  case TP_MOBILITYRATIO: {
1038  for (size_t iSpec = 0; iSpec< nBinInt; iSpec++) {
1039  XML_Node& propSpecNode = compDepNode.child(iSpec);
1040  string specName = propSpecNode.name();
1041  size_t loc = specName.find(":");
1042  string firstSpec = specName.substr(0,loc);
1043  string secondSpec = specName.substr(loc+1);
1044  size_t index = temp_thermo->speciesIndex(firstSpec.c_str())+nsp*temp_thermo->speciesIndex(secondSpec.c_str());
1045  trParam.mobilityRatio[index] = newLTI(propSpecNode,
1046  m_tranPropMap[nodeName],
1047  trParam);
1048  };
1049  };
1050  break;
1051  case TP_SELFDIFFUSION: {
1052  for (size_t iSpec = 0; iSpec< nsp; iSpec++) {
1053  XML_Node& propSpecNode = compDepNode.child(iSpec);
1054  string specName = propSpecNode.name();
1055  size_t index = temp_thermo->speciesIndex(specName.c_str());
1056  trParam.selfDiffusion[index] = newLTI(propSpecNode,
1057  m_tranPropMap[nodeName],
1058  trParam);
1059  };
1060  };
1061  break;
1062  case TP_THERMALCOND:
1063  trParam.thermalCond = newLTI(compDepNode,
1064  m_tranPropMap[nodeName],
1065  trParam);
1066  break;
1067  case TP_DIFFUSIVITY:
1068  trParam.speciesDiffusivity = newLTI(compDepNode,
1069  m_tranPropMap[nodeName],
1070  trParam);
1071  break;
1072  case TP_HYDRORADIUS:
1073  trParam.hydroRadius = newLTI(compDepNode,
1074  m_tranPropMap[nodeName],
1075  trParam);
1076  break;
1077  case TP_ELECTCOND:
1078  trParam.electCond = newLTI(compDepNode,
1079  m_tranPropMap[nodeName],
1080  trParam);
1081  break;
1082  default:
1083  throw CanteraError("getLiquidInteractionsTransportData","unknown transport property: " + nodeName);
1084 
1085  }
1086  }
1087  /* Allow a switch between mass-averaged, mole-averaged
1088  * and solvent specified reference velocities.
1089  * XML code within the transportProperty node
1090  * (i.e. within <viscosity>) should read as follows
1091  * <velocityBasis basis="mass"> <!-- mass averaged -->
1092  * <velocityBasis basis="mole"> <!-- mole averaged -->
1093  * <velocityBasis basis="H2O"> <!-- H2O solvent -->
1094  */
1095  if (tranTypeNode.hasChild("velocityBasis")) {
1096  std::string velocityBasis =
1097  tranTypeNode.child("velocityBasis").attrib("basis");
1098  if (velocityBasis == "mass") {
1099  trParam.velocityBasis_ = VB_MASSAVG;
1100  } else if (velocityBasis == "mole") {
1101  trParam.velocityBasis_ = VB_MOLEAVG;
1102  } else if (trParam.thermo->speciesIndex(velocityBasis) > 0) {
1103  trParam.velocityBasis_ = static_cast<int>(trParam.thermo->speciesIndex(velocityBasis));
1104  } else {
1105  int linenum = __LINE__;
1106  throw TransportDBError(linenum, "Unknown attribute \"" + velocityBasis + "\" for <velocityBasis> node. ");
1107  }
1108  }
1109  }
1110  } catch (CanteraError& err) {
1111  std::cout << err.what() << std::endl;
1112  }
1113  return;
1114 }
1115 
1117  XML_Node& log,
1118  const std::string phaseName,
1119  SolidTransportData& trParam)
1120 {
1121  try {
1122 
1123  int num = transportNode.nChildren();
1124  for (int iChild = 0; iChild < num; iChild++) {
1125  //tranTypeNode is a type of transport property like viscosity
1126  XML_Node& tranTypeNode = transportNode.child(iChild);
1127  std::string nodeName = tranTypeNode.name();
1128 
1129  ThermoPhase* temp_thermo = trParam.thermo;
1130 
1131  //tranTypeNode contains the interaction model
1132  // XML_Node &compDepNode = tranTypeNode.child("compositionDependence");
1133  switch (m_tranPropMap[nodeName]) {
1134  case TP_IONCONDUCTIVITY:
1135  trParam.ionConductivity = newLTP(tranTypeNode, phaseName,
1136  m_tranPropMap[nodeName],
1137  temp_thermo);
1138  break;
1139  case TP_THERMALCOND:
1140  trParam.thermalConductivity = newLTP(tranTypeNode, phaseName,
1141  m_tranPropMap[nodeName],
1142  temp_thermo);
1143  break;
1144  case TP_DEFECTDIFF:
1145  trParam.defectDiffusivity = newLTP(tranTypeNode, phaseName,
1146  m_tranPropMap[nodeName],
1147  temp_thermo);
1148  break;
1149  case TP_DEFECTCONC:
1150  trParam.defectActivity = newLTP(tranTypeNode, phaseName,
1151  m_tranPropMap[nodeName],
1152  temp_thermo);
1153  break;
1154  case TP_ELECTCOND:
1155  trParam.electConductivity = newLTP(tranTypeNode, phaseName,
1156  m_tranPropMap[nodeName],
1157  temp_thermo);
1158  break;
1159  default:
1160  throw CanteraError("getSolidTransportData","unknown transport property: " + nodeName);
1161 
1162  }
1163  }
1164  } catch (CanteraError) {
1165  showErrors(std::cout);
1166  }
1167  //catch(CanteraError) {
1168  // ;
1169  //}
1170  return;
1171 }
1172 
1174  MMCollisionInt& integrals, std::ostream& logfile)
1175 {
1176  doublereal tstar;
1177  int ndeg = 0;
1178 #ifdef DEBUG_MODE
1179  char s[100];
1180 #endif
1181  // number of points to use in generating fit data
1182  const size_t np = 50;
1183 
1184  int mode = tr.mode_;
1185  int degree = (mode == CK_Mode ? 3 : 4);
1186 
1187  doublereal t, om22;
1188  doublereal dt = (tr.tmax - tr.tmin)/(np-1);
1189  vector_fp tlog(np), spvisc(np), spcond(np);
1190  doublereal val, fit;
1191 
1192  vector_fp w(np), w2(np);
1193 
1194  // generate array of log(t) values
1195  for (size_t n = 0; n < np; n++) {
1196  t = tr.tmin + dt*n;
1197  tlog[n] = log(t);
1198  }
1199 
1200  // vector of polynomial coefficients
1201  vector_fp c(degree + 1), c2(degree + 1);
1202 
1203 
1204  // fit the pure-species viscosity and thermal conductivity for
1205  // each species
1206 #ifdef DEBUG_MODE
1207  if (tr.log_level < 2 && m_verbose) {
1208  tr.xml->XML_comment(logfile,
1209  "*** polynomial coefficients not printed (log_level < 2) ***");
1210  }
1211 #endif
1212  doublereal sqrt_T, visc, err, relerr,
1213  mxerr = 0.0, mxrelerr = 0.0, mxerr_cond = 0.0, mxrelerr_cond = 0.0;
1214 
1215 #ifdef DEBUG_MODE
1216  if (m_verbose) {
1217  tr.xml->XML_open(logfile, "viscosity");
1218  tr.xml->XML_comment(logfile,"Polynomial fits for viscosity");
1219  if (mode == CK_Mode) {
1220  tr.xml->XML_comment(logfile,"log(viscosity) fit to cubic "
1221  "polynomial in log(T)");
1222  } else {
1223  sprintf(s, "viscosity/sqrt(T) fit to "
1224  "polynomial of degree %d in log(T)",degree);
1225  tr.xml->XML_comment(logfile,s);
1226  }
1227  }
1228 #endif
1229 
1230  doublereal cp_R, cond, w_RT, f_int, A_factor, B_factor,
1231  c1, cv_rot, cv_int, f_rot, f_trans, om11;
1232  doublereal diffcoeff;
1233 
1234  for (size_t k = 0; k < tr.nsp_; k++) {
1235  for (size_t n = 0; n < np; n++) {
1236  t = tr.tmin + dt*n;
1237 
1238  tr.thermo->setTemperature(t);
1239  cp_R = ((IdealGasPhase*)tr.thermo)->cp_R_ref()[k];
1240 
1241  tstar = Boltzmann * t/ tr.eps[k];
1242  sqrt_T = sqrt(t);
1243  om22 = integrals.omega22(tstar, tr.delta(k,k));
1244  om11 = integrals.omega11(tstar, tr.delta(k,k));
1245 
1246  // self-diffusion coefficient, without polar
1247  // corrections
1248  diffcoeff = ThreeSixteenths *
1249  sqrt(2.0 * Pi/tr.reducedMass(k,k)) *
1250  pow((Boltzmann * t), 1.5)/
1251  (Pi * tr.sigma[k] * tr.sigma[k] * om11);
1252 
1253  // viscosity
1254  visc = FiveSixteenths
1255  * sqrt(Pi * tr.mw[k] * Boltzmann * t / Avogadro) /
1256  (om22 * Pi * tr.sigma[k]*tr.sigma[k]);
1257 
1258  // thermal conductivity
1259  w_RT = tr.mw[k]/(GasConstant * t);
1260  f_int = w_RT * diffcoeff/visc;
1261  cv_rot = tr.crot[k];
1262 
1263  A_factor = 2.5 - f_int;
1264  B_factor = tr.zrot[k] + TwoOverPi
1265  *(FiveThirds * cv_rot + f_int);
1266  c1 = TwoOverPi * A_factor/B_factor;
1267  cv_int = cp_R - 2.5 - cv_rot;
1268 
1269  f_rot = f_int * (1.0 + c1);
1270  f_trans = 2.5 * (1.0 - c1 * cv_rot/1.5);
1271 
1272  cond = (visc/tr.mw[k])*GasConstant*(f_trans * 1.5
1273  + f_rot * cv_rot + f_int * cv_int);
1274 
1275  if (mode == CK_Mode) {
1276  spvisc[n] = log(visc);
1277  spcond[n] = log(cond);
1278  w[n] = -1.0;
1279  w2[n] = -1.0;
1280  } else {
1281  // the viscosity should be proportional
1282  // approximately to sqrt(T); therefore,
1283  // visc/sqrt(T) should have only a weak
1284  // temperature dependence. And since the mixture
1285  // rule requires the square root of the
1286  // pure-species viscosity, fit the square root of
1287  // (visc/sqrt(T)) to avoid having to compute
1288  // square roots in the mixture rule.
1289  spvisc[n] = sqrt(visc/sqrt_T);
1290 
1291  // the pure-species conductivity scales
1292  // approximately with sqrt(T). Unlike the
1293  // viscosity, there is no reason here to fit the
1294  // square root, since a different mixture rule is
1295  // used.
1296  spcond[n] = cond/sqrt_T;
1297  w[n] = 1.0/(spvisc[n]*spvisc[n]);
1298  w2[n] = 1.0/(spcond[n]*spcond[n]);
1299  }
1300  }
1301  polyfit(np, DATA_PTR(tlog), DATA_PTR(spvisc),
1302  DATA_PTR(w), degree, ndeg, 0.0, DATA_PTR(c));
1303  polyfit(np, DATA_PTR(tlog), DATA_PTR(spcond),
1304  DATA_PTR(w), degree, ndeg, 0.0, DATA_PTR(c2));
1305 
1306  // evaluate max fit errors for viscosity
1307  for (size_t n = 0; n < np; n++) {
1308  if (mode == CK_Mode) {
1309  val = exp(spvisc[n]);
1310  fit = exp(poly3(tlog[n], DATA_PTR(c)));
1311  } else {
1312  sqrt_T = exp(0.5*tlog[n]);
1313  val = sqrt_T * pow(spvisc[n],2);
1314  fit = sqrt_T * pow(poly4(tlog[n], DATA_PTR(c)),2);
1315  }
1316  err = fit - val;
1317  relerr = err/val;
1318  if (fabs(err) > mxerr) {
1319  mxerr = fabs(err);
1320  }
1321  if (fabs(relerr) > mxrelerr) {
1322  mxrelerr = fabs(relerr);
1323  }
1324  }
1325 
1326  // evaluate max fit errors for conductivity
1327  for (size_t n = 0; n < np; n++) {
1328  if (mode == CK_Mode) {
1329  val = exp(spcond[n]);
1330  fit = exp(poly3(tlog[n], DATA_PTR(c2)));
1331  } else {
1332  sqrt_T = exp(0.5*tlog[n]);
1333  val = sqrt_T * spcond[n];
1334  fit = sqrt_T * poly4(tlog[n], DATA_PTR(c2));
1335  }
1336  err = fit - val;
1337  relerr = err/val;
1338  if (fabs(err) > mxerr_cond) {
1339  mxerr_cond = fabs(err);
1340  }
1341  if (fabs(relerr) > mxrelerr_cond) {
1342  mxrelerr_cond = fabs(relerr);
1343  }
1344  }
1345  tr.visccoeffs.push_back(c);
1346  tr.condcoeffs.push_back(c2);
1347 
1348 #ifdef DEBUG_MODE
1349  if (tr.log_level >= 2 && m_verbose) {
1350  tr.xml->XML_writeVector(logfile, " ", tr.thermo->speciesName(k),
1351  c.size(), DATA_PTR(c));
1352  }
1353 #endif
1354  }
1355 #ifdef DEBUG_MODE
1356  if (m_verbose) {
1357  sprintf(s, "Maximum viscosity absolute error: %12.6g", mxerr);
1358  tr.xml->XML_comment(logfile,s);
1359  sprintf(s, "Maximum viscosity relative error: %12.6g", mxrelerr);
1360  tr.xml->XML_comment(logfile,s);
1361  tr.xml->XML_close(logfile, "viscosity");
1362 
1363 
1364  tr.xml->XML_open(logfile, "conductivity");
1365  tr.xml->XML_comment(logfile,"Polynomial fits for conductivity");
1366  if (mode == CK_Mode)
1367  tr.xml->XML_comment(logfile,"log(conductivity) fit to cubic "
1368  "polynomial in log(T)");
1369  else {
1370  sprintf(s, "conductivity/sqrt(T) fit to "
1371  "polynomial of degree %d in log(T)",degree);
1372  tr.xml->XML_comment(logfile,s);
1373  }
1374  if (tr.log_level >= 2)
1375  for (size_t k = 0; k < tr.nsp_; k++) {
1376  tr.xml->XML_writeVector(logfile, " ", tr.thermo->speciesName(k),
1377  degree+1, DATA_PTR(tr.condcoeffs[k]));
1378  }
1379  sprintf(s, "Maximum conductivity absolute error: %12.6g", mxerr_cond);
1380  tr.xml->XML_comment(logfile,s);
1381  sprintf(s, "Maximum conductivity relative error: %12.6g", mxrelerr_cond);
1382  tr.xml->XML_comment(logfile,s);
1383  tr.xml->XML_close(logfile, "conductivity");
1384 
1385  // fit the binary diffusion coefficients for each species pair
1386 
1387  tr.xml->XML_open(logfile, "binary_diffusion_coefficients");
1388  tr.xml->XML_comment(logfile, "binary diffusion coefficients");
1389  if (mode == CK_Mode)
1390  tr.xml->XML_comment(logfile,"log(D) fit to cubic "
1391  "polynomial in log(T)");
1392  else {
1393  sprintf(s, "D/T**(3/2) fit to "
1394  "polynomial of degree %d in log(T)",degree);
1395  tr.xml->XML_comment(logfile,s);
1396  }
1397  }
1398 #endif
1399 
1400  mxerr = 0.0, mxrelerr = 0.0;
1401  vector_fp diff(np + 1);
1402  doublereal eps, sigma;
1403  for (size_t k = 0; k < tr.nsp_; k++) {
1404  for (size_t j = k; j < tr.nsp_; j++) {
1405  for (size_t n = 0; n < np; n++) {
1406 
1407  t = tr.tmin + dt*n;
1408 
1409  eps = tr.epsilon(j,k);
1410  tstar = Boltzmann * t/eps;
1411  sigma = tr.diam(j,k);
1412  om11 = integrals.omega11(tstar, tr.delta(j,k));
1413 
1414  diffcoeff = ThreeSixteenths *
1415  sqrt(2.0 * Pi/tr.reducedMass(k,j)) *
1416  pow((Boltzmann * t), 1.5)/
1417  (Pi * sigma * sigma * om11);
1418 
1419 
1420  // 2nd order correction
1421  // NOTE: THIS CORRECTION IS NOT APPLIED
1422  doublereal fkj, fjk;
1423  getBinDiffCorrection(t, tr, integrals, k, j, 1.0, 1.0, fkj, fjk);
1424  //diffcoeff *= fkj;
1425 
1426 
1427  if (mode == CK_Mode) {
1428  diff[n] = log(diffcoeff);
1429  w[n] = -1.0;
1430  } else {
1431  diff[n] = diffcoeff/pow(t, 1.5);
1432  w[n] = 1.0/(diff[n]*diff[n]);
1433  }
1434  }
1435  polyfit(np, DATA_PTR(tlog), DATA_PTR(diff),
1436  DATA_PTR(w), degree, ndeg, 0.0, DATA_PTR(c));
1437 
1438  doublereal pre;
1439  for (size_t n = 0; n < np; n++) {
1440  if (mode == CK_Mode) {
1441  val = exp(diff[n]);
1442  fit = exp(poly3(tlog[n], DATA_PTR(c)));
1443  } else {
1444  t = exp(tlog[n]);
1445  pre = pow(t, 1.5);
1446  val = pre * diff[n];
1447  fit = pre * poly4(tlog[n], DATA_PTR(c));
1448  }
1449  err = fit - val;
1450  relerr = err/val;
1451  if (fabs(err) > mxerr) {
1452  mxerr = fabs(err);
1453  }
1454  if (fabs(relerr) > mxrelerr) {
1455  mxrelerr = fabs(relerr);
1456  }
1457  }
1458  tr.diffcoeffs.push_back(c);
1459 #ifdef DEBUG_MODE
1460  if (tr.log_level >= 2 && m_verbose) {
1461  tr.xml->XML_writeVector(logfile, " ", tr.thermo->speciesName(k)
1462  + "__"+tr.thermo->speciesName(j), c.size(), DATA_PTR(c));
1463  }
1464 #endif
1465  }
1466  }
1467 #ifdef DEBUG_MODE
1468  if (m_verbose) {
1469  sprintf(s,"Maximum binary diffusion coefficient absolute error:"
1470  " %12.6g", mxerr);
1471  tr.xml->XML_comment(logfile,s);
1472  sprintf(s, "Maximum binary diffusion coefficient relative error:"
1473  "%12.6g", mxrelerr);
1474  tr.xml->XML_comment(logfile,s);
1475  tr.xml->XML_close(logfile, "binary_diffusion_coefficients");
1476  }
1477 #endif
1478 }
1479 
1480 Transport* newTransportMgr(const std::string& transportModel, thermo_t* thermo, int loglevel, TransportFactory* f, int ndim)
1481 {
1482  if (f == 0) {
1484  }
1485  Transport* ptr = f->newTransport(transportModel, thermo, loglevel, ndim);
1486  /*
1487  * Note: We delete the static s_factory instance here, instead of in
1488  * appdelete() in misc.cpp, to avoid linking problems involving
1489  * the need for multiple cantera and transport library statements
1490  * for applications that don't have transport in them.
1491  */
1492  return ptr;
1493 }
1494 
1496 {
1497  if (f == 0) {
1499  }
1500  Transport* ptr = f->newTransport(thermo, loglevel);
1501  /*
1502  * Note: We delete the static s_factory instance here, instead of in
1503  * appdelete() in misc.cpp, to avoid linking problems involving
1504  * the need for multiple cantera and transport library statements
1505  * for applications that don't have transport in them.
1506  */
1507  return ptr;
1508 }
1509 }
LTPspecies * defectDiffusivity
Model type for the defectDiffusivity – or more like a defect diffusivity in the context of the solid ...
doublereal tmin
Minimum temperatures for parameter fits.
R poly3(D x, R *c)
Templated evaluation of a polynomial of order 3.
Definition: utilities.h:650
Headers for the DustyGasTransport object, which models transport properties in porous media using the...
Class PecosTransport implements mixture-averaged transport properties for ideal gas mixtures...
DenseMatrix diam
hard-sphere diameter for (i,j) collision
TransportPropertyType
Enumeration of the types of transport properties that can be handled by the variables in the various ...
Definition: LTPspecies.h:32
void restoreState(const vector_fp &state)
Restore a state saved on a previous call to saveState.
Definition: Phase.cpp:289
DenseMatrix radius_Aij
Interaction associated with hydrodynamic radius.
This structure holds transport model parameters relevant to transport in ideal gases with a kinetic t...
void getTransportData(const std::vector< const XML_Node * > &xspecies, XML_Node &log, const std::vector< std::string > &names, GasTransportParams &tr)
Read the transport database.
void init(XML_Writer *xml, doublereal tsmin, doublereal tsmax, int loglevel=0)
Initialize the object for calculation.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
std::vector< LiquidTranInteraction * > mobilityRatio
Vector of pointer to the LiquidTranInteraction object which handles the calculation of each species' ...
vector_fp alpha
Polarizability of each species in the phase.
thermo_t * thermo
Pointer to the ThermoPhase object.
std::vector< vector_fp > omega22_poly
This is vector of vectors containing the astar fit.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:534
virtual Transport * newTransport(const std::string &model, thermo_t *thermo, int log_level=0, int ndim=1)
Build a new transport manager using a transport manager that may not be the same as in the phase desc...
std::vector< vector_fp > astar_poly
This is vector of vectors containing the astar fit.
LTPspecies * thermalCond
Model type for the thermal conductivity.
Simple mass fraction weighting of transport properties.
void showErrors(std::ostream &f)
Prints all of the error messages to an ostream.
Definition: global.cpp:171
Class IdealGasPhase represents low-density gases that obey the ideal gas equation of state...
Factory class for creating new instances of classes derived from Transport.
Interface for class MultiTransport.
LTPspecies * defectActivity
Model type for the defectActivity.
const doublereal FiveSixteenths
5/16
Definition: ct_defs.h:130
void getSolidTransportData(const XML_Node &transportNode, XML_Node &log, const std::string phaseName, SolidTransportData &tr)
Read transport property data from a file for a solid phase.
size_t nsp_
Local storage of the number of species.
doublereal tmax
Maximum temperatures for parameter fits.
Transport * newTransportMgr(const std::string &transportModel, thermo_t *thermo, int loglevel, TransportFactory *f, int ndim)
Create a new transport manager instance.
Class LiquidTransport implements models for transport properties for liquid phases.
Class DustyGasTransport implements the Dusty Gas model for transport in porous media.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
Header file defining class SolidTransportData.
Transport properties that act like pairwise interactions as in binary diffusion coefficients.
Base class for transport property managers.
const doublereal SqrtTen
sqrt(10)
Definition: ct_defs.h:132
doublereal getFloat(const Cantera::XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:267
void fitProperties(GasTransportParams &tr, MMCollisionInt &integrals, std::ostream &logfile)
Generate polynomial fits to the viscosity, conductivity, and the binary diffusion coefficients...
std::map< int, std::string > m_modelNames
Inverse mapping of transport models, from integer constant to string.
LiquidTranInteraction * viscosity
Object that specifies the viscosity interaction for the mixture.
Class LiquidTransportData holds transport parameters for a specific liquid-phase species.
vector_fp sigma
Lennard-Jones diameter of the species in the current phase.
virtual bool initSolid(SolidTransportData &tr)
Called by TransportFactory to set parameters.
Class LTPspecies_Arrhenius holds transport parameters for a specific liquid-phase species (LTPspecies...
Definition: LTPspecies.h:241
const doublereal Pi
Pi.
Definition: ct_defs.h:51
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:58
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, HTML_logs (see Input File Handling, Diagnostic Output, Writing messages to the screen and Writing HTML Logfiles).
void getLiquidSpeciesTransportData(const std::vector< const XML_Node * > &db, XML_Node &log, const std::vector< std::string > &names, LiquidTransportParams &tr)
Read transport property data from a file for a list of species that comprise the phase.
Header file defining class PecosTransport.
DenseMatrix reducedMass
This is the reduced mass of the interaction between species i and j.
virtual void initTransport(Transport *tr, thermo_t *thermo, int mode=0, int log_level=0)
Initialize an existing transport manager.
C interface for Fortran DPOLFT subroutine.
vector_fp fitlist
This is vector containing the values of delta(i,j) that are used in the collision integral fits...
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:129
LTPspecies * electConductivity
Model type for the electrical conductivity.
LTPspecies * speciesDiffusivity
Model type for the speciesDiffusivity.
Header file for defining the class SolidTransport, which handles transport of ions within solid phase...
Monk and Monchick collision integrals.
static TransportFactory * s_factory
Static instance of the factor -> This is the only instance of this object allowed.
std::vector< vector_fp > cstar_poly
This is vector of vectors containing the astar fit.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:584
Header file defining class TransportFactory (see TransportFactory)
Class SolidTransport implements transport properties for solids.
std::vector< vector_fp > diffcoeffs
temperature-fits of the diffusivity
XML_Node * getByTitle(const Cantera::XML_Node &node, const std::string &title)
Search the child nodes of the current node for an XML Node with a Title attribute of a given name...
Definition: ctml.cpp:152
R poly4(D x, R *c)
Evaluates a polynomial of order 4.
Definition: utilities.h:638
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:101
static std::string modelName(int model)
Get the name of the transport model corresponding to the specified constant.
Class LiquidTransportParams holds transport model parameters relevant to transport in mixtures...
void getLiquidInteractionsTransportData(const XML_Node &phaseTran_db, XML_Node &log, const std::vector< std::string > &names, LiquidTransportParams &tr)
Read transport property data from a file for interactions between species.
std::vector< LiquidTranInteraction * > selfDiffusion
Vector of pointer to the LiquidTranInteraction object which handles the calculation of each species' ...
void getBinDiffCorrection(doublereal t, const GasTransportParams &tr, MMCollisionInt &integrals, size_t k, size_t j, doublereal xk, doublereal xj, doublereal &fkj, doublereal &fjk)
Second-order correction to the binary diffusion coefficients.
Header file defining class LiquidTransportParams.
doublereal polyfit(int n, doublereal *x, doublereal *y, doublereal *w, int maxdeg, int &ndeg, doublereal eps, doublereal *r)
Fits a polynomial function to a set of data points.
Definition: funcs.cpp:122
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:229
vector_fp zrot
Rotational relaxation number for the species in the current phase.
LiquidTranInteraction * ionConductivity
Object that specifes the ionic Conductivity of the mixture.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the matrix.
Definition: DenseMatrix.cpp:71
vector_fp eps
Lennard-Jones well-depth of the species in the current phase.
VelocityBasis velocityBasis_
A basis for the average velocity can be specified.
std::vector< bool > polar
Vector of booleans indicating whether a species is a polar molecule.
Mixing rule using logarithms of the mole fractions.
ThermoPhase object for the ideal gas equation of state - workhorse for Cantera (see Thermodynamic Pro...
#define COLL_INT_POLY_DEGREE
polynomial degree used for fitting collision integrals except in CK mode, where the degree is 6...
const char * what() const
Get a description of the error.
Header file defining the class LiquidTranInteraction and classes which derive from LiquidTranInteract...
std::map< std::string, TransportPropertyType > m_tranPropMap
Mapping between between the string name for a transport property and the integer name.
void setupSolidTransport(std::ostream &flog, thermo_t *thermo, int log_level, SolidTransportData &trParam)
Prepare to build a new transport manager for solids.
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
Definition: ThermoPhase.h:244
std::map< std::string, LiquidTranMixingModel > m_LTImodelMap
Mapping between between the string name for a liquid mixture transport property model and the integer...
std::string name() const
Returns the name of the XML node.
Definition: xml.h:390
Header file for the class SimpleTransport which provides simple transport properties for liquids and ...
Classes providing support for XML data files.
virtual LiquidTranInteraction * newLTI(const XML_Node &trNode, TransportPropertyType tp_ind, LiquidTransportParams &trParam)
Factory function for the construction of new LiquidTranInteraction objects, which are transport model...
void initialize(ThermoPhase *phase, Transport *gastr)
Initialization routine called by TransportFactory.
DenseMatrix thermalCond_Aij
Interaction associated with linear weighting of thermal conductivity.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:68
std::map< std::string, int > m_models
Mapping between between the string name for a transport model and the integer name.
Header file defining class AqueousTransport.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:574
void setupMM(std::ostream &flog, const std::vector< const XML_Node * > &transport_database, thermo_t *thermo, int mode, int log_level, GasTransportParams &tr)
Prepare to build a new kinetic-theory-based transport manager for low-density gases.
bool m_verbose
Boolean indicating whether to turn on verbose printing.
Class LTPspecies_Const holds transport parameters for a specific liquid-phase species (LTPspecies) wh...
Definition: LTPspecies.h:182
TransportDBError(int linenum, const std::string &msg)
Default constructor.
DenseMatrix delta
Matrix containing the reduced dipole moment of the interaction between two species.
LiquidTranInteraction * speciesDiffusivity
Pointer to the LiquidTranInteraction object which handles the calculation of the species diffusivity ...
vector_fp crot
Dimensionless rotational heat capacity of the species in the current phase.
DenseMatrix epsilon
The effective well depth for (i,j) collisions.
Class LTPspecies holds transport parameters for a specific liquid-phase species.
Definition: LTPspecies.h:73
vector_fp mw
Local storage of the molecular weights of the species.
Simple mole fraction weighting of transport properties.
static TransportFactory * factory()
Return a pointer to a TransportFactory instance.
void makePolarCorrections(size_t i, size_t j, const GasTransportParams &tr, doublereal &f_eps, doublereal &f_sigma)
Corrections for polar-nonpolar binary diffusion coefficients.
std::vector< Cantera::LiquidTransportData > LTData
Species transport parameters.
std::vector< vector_fp > bstar_poly
This is vector of vectors containing the astar fit.
virtual void initLiquidTransport(Transport *tr, thermo_t *thermo, int log_level=0)
Initialize an existing transport manager for liquid phase.
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:252
std::vector< std::vector< int > > poly
This is vector of vectors containing the integer lookup value for the (i,j) interaction.
Class MultiTransport implements multicomponent transport properties for ideal gas mixtures...
const std::vector< std::string > & speciesNames() const
Return a const reference to the vector of species names.
Definition: Phase.cpp:252
std::string value() const
Return the value of an XML node as a string.
Definition: xml.cpp:488
const vector_fp & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition: Phase.cpp:505
const doublereal Avogadro
Avogadro's Number [number/kmol].
Definition: ct_defs.h:63
std::map< std::string, LTPTemperatureDependenceType > m_LTRmodelMap
Mapping between between the string name for a species-specific transport property model and the integ...
const VelocityBasis VB_MOLEAVG
Diffusion velocities are based on the mole averaged velocities.
Definition: TransportBase.h:93
LTPspecies * electCond
Model type for the electrical conductivity.
Class LTPspecies_ExpT holds transport parameters for a specific liquid- phase species (LTPspecies) wh...
Definition: LTPspecies.h:391
int mode_
Mode parameter.
Header file defining class LiquidTransport.
void setupLiquidTransport(std::ostream &flog, thermo_t *thermo, int log_level, LiquidTransportParams &trParam)
Prepare to build a new transport manager for liquids assuming that viscosity transport data is provid...
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:165
DenseMatrix dipole
The effective dipole moment for (i,j) collisions.
virtual bool initLiquid(LiquidTransportParams &tr)
Called by TransportFactory to set parameters.
std::vector< vector_fp > visccoeffs
temperature-fit of the viscosity
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:562
std::string speciesName
A LiquidTransportData object is instantiated for each species.
std::vector< LTPspecies * > mobilityRatio
Model type for the mobility ratio.
std::vector< vector_fp > condcoeffs
temperature-fits of the heat conduction
LTPspecies * ionConductivity
Model type for the ionic conductivity.
Exception thrown if an error is encountered while reading the transport database. ...
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:66
LTPspecies * hydroRadius
Model type for the hydroradius.
Stefan Maxwell Diffusion Coefficients can be solved for given ion conductivity, mobility ratios...
DenseMatrix diff_Dij
Interaction associated with linear weighting of thermal conductivity.
const std::vector< const XML_Node * > & speciesData() const
Return a pointer to the vector of XML nodes containing the species data for this phase.
Contains declarations for string manipulation functions within Cantera.
std::vector< LTPspecies * > selfDiffusion
Model type for the self diffusion coefficients.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
Definition: ct_defs.h:36
LTPspecies * viscosity
Model type for the viscosity.
Simple mole fraction weighting of transport properties.
void saveState(vector_fp &state) const
Save the current internal state of the phase Write to vector 'state' the current internal state...
Definition: Phase.cpp:277
LiquidTranInteraction * hydroRadius
Pointer to the LiquidTranInteraction object which handles the calculation of the hydrodynamic radius ...
XML_Node & xml()
Returns a reference to the XML_Node stored for the phase.
Definition: Phase.cpp:114
const VelocityBasis VB_MASSAVG
Diffusion velocities are based on the mass averaged velocity.
Definition: TransportBase.h:91
XML_Writer * xml
Pointer to the xml tree describing the implementation of transport for this object.
virtual void setThermo(thermo_t &thermo)
Specifies the ThermoPhase object.
Calculation of Collision integrals.
void fitCollisionIntegrals(std::ostream &logfile, GasTransportParams &tr, MMCollisionInt &integrals)
Generate polynomial fits to collision integrals.
virtual LTPspecies * newLTP(const XML_Node &trNode, const std::string &name, TransportPropertyType tp_ind, thermo_t *thermo)
Make one of several transport models, and return a base class pointer to it.
virtual void init(const XML_Node &compModelNode=XML_Node(), thermo_t *thermo=0)
initialize LiquidTranInteraction objects with thermo and XML node
LTPspecies * thermalConductivity
Model type for the thermal conductivity.
Transport * newDefaultTransportMgr(thermo_t *thermo, int loglevel, TransportFactory *f)
Create a new transport manager instance.
virtual void initSolidTransport(Transport *tr, thermo_t *thermo, int log_level=0)
Initialize an existing transport manager for solid phase.
Class MixTransport implements mixture-averaged transport properties for ideal gas mixtures...
Definition: MixTransport.h:56
LTPspecies * ionConductivity
Model type for the ionic conductivity.
static mutex_t transport_mutex
Static instance of the mutex used to ensure the proper reading of the transport database.
Class LTPspecies_Poly holds transport parameters for a specific liquid-phase species (LTPspecies) whe...
Definition: LTPspecies.h:326
Header file for class ThermoPhase, the base class for phases with thermodynamic properties, and the text for the Module thermoprops (see Thermodynamic Properties and class ThermoPhase).
virtual void deleteFactory()
Deletes the statically allocated factory instance.
Class SolidTransportData holds transport parameters for a specific solid-phase species.
Headers for the MixTransport object, which models transport properties in ideal gas solutions using a...
Base class to handle transport property evaluation in a mixture.
LiquidTranInteraction * thermalCond
Pointer to the LiquidTranInteraction object which handles the calculation of the mixture thermal cond...
virtual bool initGas(GasTransportParams &tr)
Called by TransportFactory to set parameters.
Class that holds the data that is read in from the xml file, and which is used for processing of the ...
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:246
Class SimpleTransport implements mixture-averaged transport properties for liquid phases...
const doublereal Boltzmann
Boltzmann's constant [J/K].
Definition: ct_defs.h:78
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:594
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
Definition: DenseMatrix.h:70
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid...
Definition: ThermoPhase.h:175
LiquidTranInteraction * electCond
Pointer to the LiquidTranInteraction object which handles the calculation of the electrical conductiv...
Class AqueousTransport implements mixture-averaged transport properties for brine phases...
void save()
Function to put this error onto Cantera's error stack.