Cantera  2.4.0
LiquidTranInteraction.cpp
Go to the documentation of this file.
1 /**
2  * @file LiquidTranInteraction.cpp
3  * Source code for liquid mixture transport property evaluations.
4  */
5 
6 // This file is part of Cantera. See License.txt in the top-level directory or
7 // at http://www.cantera.org/license.txt for license and copyright information.
8 
13 #include "cantera/base/ctml.h"
14 
15 using namespace std;
16 
17 namespace Cantera
18 {
19 
20 /**
21  * Exception thrown if an error is encountered while reading the
22  * transport database.
23  */
25 {
26 public:
27  explicit LTPmodelError(const std::string& msg)
28  : CanteraError("LTPspecies",
29  "error parsing transport data: "
30  + msg + "\n") {}
31 };
32 
33 LiquidTranInteraction::LiquidTranInteraction(TransportPropertyType tp_ind) :
34  m_model(LTI_MODEL_NOTSET),
35  m_property(tp_ind)
36 {
37  warn_deprecated("Class LiquidTranInteraction", "To be removed after Cantera 2.4");
38 }
39 
40 LiquidTranInteraction::~LiquidTranInteraction()
41 {
42  for (size_t k = 0; k < m_Aij.size(); k++) {
43  delete m_Aij[k];
44  }
45  for (size_t k = 0; k < m_Bij.size(); k++) {
46  delete m_Bij[k];
47  }
48  for (size_t k = 0; k < m_Hij.size(); k++) {
49  delete m_Hij[k];
50  }
51  for (size_t k = 0; k < m_Sij.size(); k++) {
52  delete m_Sij[k];
53  }
54 }
55 
56 void LiquidTranInteraction::init(const XML_Node& compModelNode,
57  thermo_t* thermo)
58 {
59  m_thermo = thermo;
60  size_t nsp = thermo->nSpecies();
61  m_Dij.resize(nsp, nsp, 0.0);
62  m_Eij.resize(nsp, nsp, 0.0);
63 
64  for (size_t iChild = 0; iChild < compModelNode.nChildren(); iChild++) {
65  XML_Node& xmlChild = compModelNode.child(iChild);
66  std::string nodeName = xmlChild.name();
67  if (!caseInsensitiveEquals(nodeName, "interaction")) {
68  throw CanteraError("TransportFactory::getLiquidInteractionsTransportData",
69  "expected <interaction> element and got <" + nodeName + ">");
70  }
71  string speciesA = xmlChild.attrib("speciesA");
72  string speciesB = xmlChild.attrib("speciesB");
73  size_t iSpecies = m_thermo->speciesIndex(speciesA);
74  if (iSpecies == npos) {
75  throw CanteraError("TransportFactory::getLiquidInteractionsTransportData",
76  "Unknown species " + speciesA);
77  }
78  size_t jSpecies = m_thermo->speciesIndex(speciesB);
79  if (jSpecies == npos) {
80  throw CanteraError("TransportFactory::getLiquidInteractionsTransportData",
81  "Unknown species " + speciesB);
82  }
83 
84  if (xmlChild.hasChild("Eij")) {
85  m_Eij(iSpecies,jSpecies) = getFloat(xmlChild, "Eij", "actEnergy");
86  m_Eij(iSpecies,jSpecies) /= GasConstant;
87  m_Eij(jSpecies,iSpecies) = m_Eij(iSpecies,jSpecies);
88  }
89 
90  if (xmlChild.hasChild("Aij")) {
91  vector_fp poly;
92  getFloatArray(xmlChild, poly, true, "toSI", "Aij");
93  while (m_Aij.size()<poly.size()) {
94  DenseMatrix* aTemp = new DenseMatrix();
95  aTemp->resize(nsp, nsp, 0.0);
96  m_Aij.push_back(aTemp);
97  }
98  for (int i = 0; i < (int)poly.size(); i++) {
99  (*m_Aij[i])(iSpecies,jSpecies) = poly[i];
100  }
101  }
102 
103  if (xmlChild.hasChild("Bij")) {
104  vector_fp poly;
105  getFloatArray(xmlChild, poly, true, "toSI", "Bij");
106  while (m_Bij.size() < poly.size()) {
107  DenseMatrix* bTemp = new DenseMatrix();
108  bTemp->resize(nsp, nsp, 0.0);
109  m_Bij.push_back(bTemp);
110  }
111  for (size_t i=0; i<poly.size(); i++) {
112  (*m_Bij[i])(iSpecies,jSpecies) = poly[i];
113  }
114  }
115 
116  if (xmlChild.hasChild("Hij")) {
117  vector_fp poly;
118  getFloatArray(xmlChild, poly, true, "actEnergy", "Hij");
119  while (m_Hij.size()<poly.size()) {
120  DenseMatrix* hTemp = new DenseMatrix();
121  hTemp->resize(nsp, nsp, 0.0);
122  m_Hij.push_back(hTemp);
123  }
124  for (size_t i=0; i<poly.size(); i++) {
125  (*m_Hij[i])(iSpecies,jSpecies) = poly[i];
126  (*m_Hij[i])(iSpecies,jSpecies) /= GasConstant;
127  }
128  }
129 
130  if (xmlChild.hasChild("Sij")) {
131  vector_fp poly;
132  getFloatArray(xmlChild, poly, true, "actEnergy", "Sij");
133  while (m_Sij.size()<poly.size()) {
134  DenseMatrix* sTemp = new DenseMatrix();
135  sTemp->resize(nsp, nsp, 0.0);
136  m_Sij.push_back(sTemp);
137  }
138  for (size_t i=0; i<poly.size(); i++) {
139  (*m_Sij[i])(iSpecies,jSpecies) = poly[i];
140  (*m_Sij[i])(iSpecies,jSpecies) /= GasConstant;
141  }
142  }
143 
144  if (xmlChild.hasChild("Dij")) {
145  m_Dij(iSpecies,jSpecies) = getFloat(xmlChild, "Dij", "toSI");
146  m_Dij(jSpecies,iSpecies) = m_Dij(iSpecies,jSpecies);
147  }
148  }
149 }
150 
151 LTI_Solvent::LTI_Solvent(TransportPropertyType tp_ind) :
152  LiquidTranInteraction(tp_ind)
153 {
154  m_model = LTI_MODEL_SOLVENT;
155 }
156 
157 doublereal LTI_Solvent::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
158 {
159  size_t nsp = m_thermo->nSpecies();
160  doublereal temp = m_thermo->temperature();
161  vector_fp molefracs(nsp);
162  m_thermo->getMoleFractions(&molefracs[0]);
163  doublereal value = 0.0;
164 
165  //if weightings are specified, use those
166  if (speciesWeight) {
167  for (size_t k = 0; k < nsp; k++) {
168  // should be: molefracs[k] = molefracs[k]*speciesWeight[k]; for consistency, but weight(solvent)=1?
169  }
170  } else {
171  throw CanteraError("LTI_Solvent::getMixTransProp","You should be specifying the speciesWeight");
172  }
173 
174  for (size_t i = 0; i < nsp; i++) {
175  //presume that the weighting is set to 1.0 for solvent and 0.0 for everything else.
176  value += speciesValues[i] * speciesWeight[i];
177  if (i == 0) {
178  AssertTrace(speciesWeight[i] == 1.0);
179  } else {
180  AssertTrace(speciesWeight[i] == 0.0);
181  }
182  for (size_t j = 0; j < nsp; j++) {
183  for (size_t k = 0; k < m_Aij.size(); k++) {
184  value += molefracs[i]*molefracs[j]*(*m_Aij[k])(i,j)*pow(molefracs[i], (int) k);
185  }
186  for (size_t k = 0; k < m_Bij.size(); k++) {
187  value += molefracs[i]*molefracs[j]*(*m_Bij[k])(i,j)*temp*pow(molefracs[i], (int) k);
188  }
189  }
190  }
191  return value;
192 }
193 
194 doublereal LTI_Solvent::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
195 {
196  size_t nsp = m_thermo->nSpecies();
197  doublereal temp = m_thermo->temperature();
198  vector_fp molefracs(nsp);
199  m_thermo->getMoleFractions(&molefracs[0]);
200  doublereal value = 0.0;
201 
202  for (size_t k = 0; k < nsp; k++) {
203  // should be: molefracs[k] = molefracs[k]*LTPptrs[k]->getMixWeight(); for consistency, but weight(solvent)=1?
204  }
205 
206  for (size_t i = 0; i < nsp; i++) {
207  //presume that the weighting is set to 1.0 for solvent and 0.0 for everything else.
208  value += LTPptrs[i]->getSpeciesTransProp() * LTPptrs[i]->getMixWeight();
209  for (size_t j = 0; j < nsp; j++) {
210  for (size_t k = 0; k < m_Aij.size(); k++) {
211  value += molefracs[i]*molefracs[j]*(*m_Aij[k])(i,j)*pow(molefracs[i], (int) k);
212  }
213  for (size_t k = 0; k < m_Bij.size(); k++) {
214  value += molefracs[i]*molefracs[j]*(*m_Bij[k])(i,j)*temp*pow(molefracs[i], (int) k);
215  }
216  }
217  }
218  return value;
219 }
220 
221 void LTI_Solvent::getMatrixTransProp(DenseMatrix& mat, doublereal* speciesValues)
222 {
223  mat = (*m_Aij[0]);
224 }
225 
226 doublereal LTI_MoleFracs::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
227 {
228  size_t nsp = m_thermo->nSpecies();
229  doublereal temp = m_thermo->temperature();
230  vector_fp molefracs(nsp);
231  m_thermo->getMoleFractions(&molefracs[0]);
232  doublereal value = 0;
233 
234  //if weightings are specified, use those
235  if (speciesWeight) {
236  for (size_t k = 0; k < nsp; k++) {
237  molefracs[k] = molefracs[k]*speciesWeight[k];
238  }
239  } else {
240  throw CanteraError("LTI_MoleFracs::getMixTransProp","You should be specifying the speciesWeight");
241  }
242 
243  for (size_t i = 0; i < nsp; i++) {
244  value += speciesValues[i] * molefracs[i];
245  for (size_t j = 0; j < nsp; j++) {
246  for (size_t k = 0; k < m_Aij.size(); k++) {
247  value += molefracs[i]*molefracs[j]*(*m_Aij[k])(i,j)*pow(molefracs[i], (int) k);
248  }
249  for (size_t k = 0; k < m_Bij.size(); k++) {
250  value += molefracs[i]*molefracs[j]*(*m_Bij[k])(i,j)*temp*pow(molefracs[i], (int) k);
251  }
252  }
253  }
254  return value;
255 }
256 
257 doublereal LTI_MoleFracs::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
258 {
259  size_t nsp = m_thermo->nSpecies();
260  doublereal temp = m_thermo->temperature();
261  vector_fp molefracs(nsp);
262  m_thermo->getMoleFractions(&molefracs[0]);
263  doublereal value = 0;
264 
265  for (size_t k = 0; k < nsp; k++) {
266  molefracs[k] = molefracs[k]*LTPptrs[k]->getMixWeight();
267  }
268 
269  for (size_t i = 0; i < nsp; i++) {
270  value += LTPptrs[i]->getSpeciesTransProp() * molefracs[i];
271  for (size_t j = 0; j < nsp; j++) {
272  for (size_t k = 0; k < m_Aij.size(); k++) {
273  value += molefracs[i]*molefracs[j]*(*m_Aij[k])(i,j)*pow(molefracs[i], (int) k);
274  }
275  for (size_t k = 0; k < m_Bij.size(); k++) {
276  value += molefracs[i]*molefracs[j]*(*m_Bij[k])(i,j)*temp*pow(molefracs[i], (int) k);
277  }
278  }
279  }
280  return value;
281 }
282 
283 doublereal LTI_MassFracs::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
284 {
285  size_t nsp = m_thermo->nSpecies();
286  doublereal temp = m_thermo->temperature();
287  vector_fp massfracs(nsp);
288  m_thermo->getMassFractions(&massfracs[0]);
289  doublereal value = 0;
290 
291  //if weightings are specified, use those
292  if (speciesWeight) {
293  for (size_t k = 0; k < nsp; k++) {
294  massfracs[k] = massfracs[k]*speciesWeight[k];
295  }
296  } else {
297  throw CanteraError("LTI_MassFracs::getMixTransProp","You should be specifying the speciesWeight");
298  }
299 
300  for (size_t i = 0; i < nsp; i++) {
301  value += speciesValues[i] * massfracs[i];
302  for (size_t j = 0; j < nsp; j++) {
303  for (size_t k = 0; k < m_Aij.size(); k++) {
304  value += massfracs[i]*massfracs[j]*(*m_Aij[k])(i,j)*pow(massfracs[i], (int) k);
305  }
306  for (size_t k = 0; k < m_Bij.size(); k++) {
307  value += massfracs[i]*massfracs[j]*(*m_Bij[k])(i,j)*temp*pow(massfracs[i], (int) k);
308  }
309  }
310  }
311 
312  return value;
313 }
314 
315 doublereal LTI_MassFracs::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
316 {
317  size_t nsp = m_thermo->nSpecies();
318  doublereal temp = m_thermo->temperature();
319  vector_fp massfracs(nsp);
320  m_thermo->getMassFractions(&massfracs[0]);
321  doublereal value = 0;
322 
323  for (size_t k = 0; k < nsp; k++) {
324  massfracs[k] = massfracs[k]*LTPptrs[k]->getMixWeight();
325  }
326 
327  for (size_t i = 0; i < nsp; i++) {
328  value += LTPptrs[i]->getSpeciesTransProp() * massfracs[i];
329  for (size_t j = 0; j < nsp; j++) {
330  for (size_t k = 0; k < m_Aij.size(); k++) {
331  value += massfracs[i]*massfracs[j]*(*m_Aij[k])(i,j)*pow(massfracs[i], (int) k);
332  }
333  for (size_t k = 0; k < m_Bij.size(); k++) {
334  value += massfracs[i]*massfracs[j]*(*m_Bij[k])(i,j)*temp*pow(massfracs[i], (int) k);
335  }
336  }
337  }
338  return value;
339 }
340 
341 doublereal LTI_Log_MoleFracs::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
342 {
343  size_t nsp = m_thermo->nSpecies();
344  doublereal temp = m_thermo->temperature();
345  vector_fp molefracs(nsp);
346  m_thermo->getMoleFractions(&molefracs[0]);
347  doublereal value = 0;
348 
349  //if weightings are specified, use those
350  if (speciesWeight) {
351  for (size_t k = 0; k < nsp; k++) {
352  molefracs[k] = molefracs[k]*speciesWeight[k];
353  }
354  } else {
355  throw CanteraError("LTI_Log_MoleFracs::getMixTransProp","You probably should have a speciesWeight when you call getMixTransProp to convert ion mole fractions to molecular mole fractions");
356  }
357 
358  for (size_t i = 0; i < nsp; i++) {
359  value += log(speciesValues[i]) * molefracs[i];
360  for (size_t j = 0; j < nsp; j++) {
361  for (size_t k = 0; k < m_Hij.size(); k++) {
362  value += molefracs[i]*molefracs[j]*(*m_Hij[k])(i,j)/temp*pow(molefracs[i], (int) k);
363  }
364  for (size_t k = 0; k < m_Sij.size(); k++) {
365  value -= molefracs[i]*molefracs[j]*(*m_Sij[k])(i,j)*pow(molefracs[i], (int) k);
366  }
367  }
368  }
369  return exp(value);
370 }
371 
372 doublereal LTI_Log_MoleFracs::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
373 {
374  size_t nsp = m_thermo->nSpecies();
375  doublereal temp = m_thermo->temperature();
376  vector_fp molefracs(nsp);
377  m_thermo->getMoleFractions(&molefracs[0]);
378  doublereal value = 0;
379 
380  //if weightings are specified, use those
381  for (size_t k = 0; k < nsp; k++) {
382  molefracs[k] = molefracs[k]*LTPptrs[k]->getMixWeight();
383  }
384 
385  for (size_t i = 0; i < nsp; i++) {
386  value += log(LTPptrs[i]->getSpeciesTransProp()) * molefracs[i];
387  for (size_t j = 0; j < nsp; j++) {
388  for (size_t k = 0; k < m_Hij.size(); k++) {
389  value += molefracs[i]*molefracs[j]*(*m_Hij[k])(i,j)/temp*pow(molefracs[i], (int) k);
390  }
391  for (size_t k = 0; k < m_Sij.size(); k++) {
392  value -= molefracs[i]*molefracs[j]*(*m_Sij[k])(i,j)*pow(molefracs[i], (int) k);
393  }
394  }
395  }
396  return exp(value);
397 }
398 
399 void LTI_Pairwise_Interaction::setParameters(LiquidTransportParams& trParam)
400 {
401  size_t nsp = m_thermo->nSpecies();
402  m_diagonals.resize(nsp, 0);
403 
404  for (size_t k = 0; k < nsp; k++) {
405  LiquidTransportData& ltd = trParam.LTData[k];
406  if (ltd.speciesDiffusivity) {
407  m_diagonals[k] = ltd.speciesDiffusivity;
408  }
409  }
410 }
411 
412 doublereal LTI_Pairwise_Interaction::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
413 {
414  throw LTPmodelError("Calling LTI_Pairwise_Interaction::getMixTransProp does not make sense.");
415 }
416 
417 doublereal LTI_Pairwise_Interaction::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
418 {
419  throw LTPmodelError("Calling LTI_Pairwise_Interaction::getMixTransProp does not make sense.");
420 }
421 
422 void LTI_Pairwise_Interaction::getMatrixTransProp(DenseMatrix& mat, doublereal* speciesValues)
423 {
424  size_t nsp = m_thermo->nSpecies();
425  doublereal temp = m_thermo->temperature();
426  vector_fp molefracs(nsp);
427  m_thermo->getMoleFractions(&molefracs[0]);
428 
429  mat.resize(nsp, nsp, 0.0);
430  for (size_t i = 0; i < nsp; i++) {
431  for (size_t j = 0; j < i; j++) {
432  mat(i,j) = mat(j,i) = exp(m_Eij(i,j) / temp) / m_Dij(i,j);
433  }
434  }
435 
436  for (size_t i = 0; i < nsp; i++) {
437  if (mat(i,i) == 0.0 && m_diagonals[i]) {
438  mat(i,i) = 1.0 / m_diagonals[i]->getSpeciesTransProp();
439  }
440  }
441 }
442 
443 void LTI_StefanMaxwell_PPN::setParameters(LiquidTransportParams& trParam)
444 {
445  size_t nsp = m_thermo->nSpecies();
446  m_ionCondMix = 0;
447  m_ionCondMixModel = trParam.ionConductivity;
448  m_ionCondSpecies.resize(nsp,0);
449  m_mobRatMix.resize(nsp,nsp,0.0);
450  m_mobRatMixModel.resize(nsp*nsp);
451  m_mobRatSpecies.resize(nsp*nsp);
452  m_selfDiffMix.resize(nsp,0.0);
453  m_selfDiffMixModel.resize(nsp);
454  m_selfDiffSpecies.resize(nsp);
455 
456  for (size_t k = 0; k < nsp*nsp; k++) {
457  m_mobRatMixModel[k] = trParam.mobilityRatio[k];
458  m_mobRatSpecies[k].resize(nsp,0);
459  }
460  for (size_t k = 0; k < nsp; k++) {
461  m_selfDiffMixModel[k] = trParam.selfDiffusion[k];
462  m_selfDiffSpecies[k].resize(nsp,0);
463  }
464 
465  for (size_t k = 0; k < nsp; k++) {
466  LiquidTransportData& ltd = trParam.LTData[k];
467  m_ionCondSpecies[k] = ltd.ionConductivity;
468  for (size_t j = 0; j < nsp*nsp; j++) {
469  m_mobRatSpecies[j][k] = ltd.mobilityRatio[j];
470  }
471  for (size_t j = 0; j < nsp; j++) {
472  m_selfDiffSpecies[j][k] = ltd.selfDiffusion[j];
473  }
474  }
475 }
476 
477 doublereal LTI_StefanMaxwell_PPN::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
478 {
479  throw LTPmodelError("Calling LTI_StefanMaxwell_PPN::getMixTransProp does not make sense.");
480 }
481 
482 doublereal LTI_StefanMaxwell_PPN::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
483 {
484  throw LTPmodelError("Calling LTI_StefanMaxwell_PPN::getMixTransProp does not make sense.");
485 }
486 
487 void LTI_StefanMaxwell_PPN::getMatrixTransProp(DenseMatrix& mat, doublereal* speciesValues)
488 {
489  IonsFromNeutralVPSSTP* ions_thermo = dynamic_cast<IonsFromNeutralVPSSTP*>(m_thermo);
490  size_t nsp = m_thermo->nSpecies();
491  if (nsp != 3) {
492  throw CanteraError("LTI_StefanMaxwell_PPN::getMatrixTransProp","Function may only be called with a 3-ion system");
493  }
494  doublereal temp = m_thermo->temperature();
495  vector_fp molefracs(nsp);
496  m_thermo->getMoleFractions(&molefracs[0]);
497  vector_fp neut_molefracs;
498  ions_thermo->getNeutralMolecMoleFractions(neut_molefracs);
499  vector<size_t> cation;
500  vector<size_t> anion;
501  ions_thermo->getCationList(cation);
502  ions_thermo->getAnionList(anion);
503 
504  // Reaction Coeffs and Charges
505  vector_fp viS(6);
506  vector_fp charges(3);
507  std::vector<size_t> neutMolIndex(3);
508  ions_thermo->getDissociationCoeffs(viS,charges,neutMolIndex);
509 
510  if (anion.size() != 1) {
511  throw CanteraError("LTI_StefanMaxwell_PPN::getMatrixTransProp","Must have one anion only for StefanMaxwell_PPN");
512  }
513  if (cation.size() != 2) {
514  throw CanteraError("LTI_StefanMaxwell_PPN::getMatrixTransProp","Must have two cations of equal charge for StefanMaxwell_PPN");
515  }
516  if (charges[cation[0]] != charges[cation[1]]) {
517  throw CanteraError("LTI_StefanMaxwell_PPN::getMatrixTransProp","Cations must be of equal charge for StefanMaxwell_PPN");
518  }
519 
520  m_ionCondMix = m_ionCondMixModel->getMixTransProp(m_ionCondSpecies);
521  MargulesVPSSTP* marg_thermo = dynamic_cast<MargulesVPSSTP*>(ions_thermo->getNeutralMoleculePhase().get());
522  doublereal vol = m_thermo->molarVolume();
523 
524  size_t k = 0;
525  for (size_t j = 0; j < nsp; j++) {
526  for (size_t i = 0; i < nsp; i++) {
527  if (m_mobRatMixModel[k]) {
528  m_mobRatMix(i,j) = m_mobRatMixModel[k]->getMixTransProp(m_mobRatSpecies[k]);
529  if (m_mobRatMix(i,j) > 0.0) {
530  m_mobRatMix(j,i) = 1.0/m_mobRatMix(i,j);
531  }
532  }
533  k++;
534  }
535  }
536 
537  for (k = 0; k < nsp; k++) {
538  m_selfDiffMix[k] = m_selfDiffMixModel[k]->getMixTransProp(m_selfDiffSpecies[k]);
539  }
540 
541  double vP = max(viS[cation[0]],viS[cation[1]]);
542  double vM = viS[anion[0]];
543  double zP = charges[cation[0]];
544  double zM = charges[anion[0]];
545  vector_fp dlnActCoeffdlnN_diag(neut_molefracs.size(),0.0);
546  marg_thermo->getdlnActCoeffdlnN_diag(&dlnActCoeffdlnN_diag[0]);
547 
548  double xA = neut_molefracs[neutMolIndex[cation[0]]];
549  double xB = neut_molefracs[neutMolIndex[cation[1]]];
550  double eps = (1-m_mobRatMix(cation[1],cation[0]))/(xA+xB*m_mobRatMix(cation[1],cation[0]));
551  double inv_vP_vM_MutualDiff = (xA*(1-xB+dlnActCoeffdlnN_diag[neutMolIndex[cation[1]]])/m_selfDiffMix[cation[1]]+xB*(1-xA+dlnActCoeffdlnN_diag[neutMolIndex[cation[0]]])/m_selfDiffMix[cation[0]]);
552 
553  mat.resize(nsp, nsp, 0.0);
554  mat(cation[0],cation[1]) = mat(cation[1],cation[0]) = (1+vM/vP)*(1+eps*xB)*(1-eps*xA)*inv_vP_vM_MutualDiff-zP*zP*Faraday*Faraday/GasConstant/temp/m_ionCondMix/vol;
555  mat(cation[0],anion[0]) = mat(anion[0],cation[0]) = (1+vP/vM)*(-eps*xB*(1-eps*xA)*inv_vP_vM_MutualDiff)-zP*zM*Faraday*Faraday/GasConstant/temp/m_ionCondMix/vol;
556  mat(cation[1],anion[0]) = mat(anion[0],cation[1]) = (1+vP/vM)*(eps*xA*(1+eps*xB)*inv_vP_vM_MutualDiff)-zP*zM*Faraday*Faraday/GasConstant/temp/m_ionCondMix/vol;
557 }
558 
559 doublereal LTI_StokesEinstein::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
560 {
561  throw LTPmodelError("Calling LTI_StokesEinstein::getMixTransProp does not make sense.");
562 }
563 
564 doublereal LTI_StokesEinstein::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
565 {
566  throw LTPmodelError("Calling LTI_StokesEinstein::getMixTransProp does not make sense.");
567 }
568 
569 void LTI_StokesEinstein::setParameters(LiquidTransportParams& trParam)
570 {
571  size_t nsp = m_thermo->nSpecies();
572  m_viscosity.resize(nsp, 0);
573  m_hydroRadius.resize(nsp, 0);
574  for (size_t k = 0; k < nsp; k++) {
575  LiquidTransportData& ltd = trParam.LTData[k];
576  m_viscosity[k] = ltd.viscosity;
577  m_hydroRadius[k] = ltd.hydroRadius;
578  }
579 }
580 
581 void LTI_StokesEinstein::getMatrixTransProp(DenseMatrix& mat, doublereal* speciesValues)
582 {
583  size_t nsp = m_thermo->nSpecies();
584  doublereal temp = m_thermo->temperature();
585  vector_fp viscSpec(nsp);
586  vector_fp radiusSpec(nsp);
587 
588  for (size_t k = 0; k < nsp; k++) {
589  viscSpec[k] = m_viscosity[k]->getSpeciesTransProp();
590  radiusSpec[k] = m_hydroRadius[k]->getSpeciesTransProp();
591  }
592 
593  mat.resize(nsp,nsp, 0.0);
594  for (size_t i = 0; i < nsp; i++) {
595  for (size_t j = 0; j < nsp; j++) {
596  mat(i,j) = (6.0 * Pi * radiusSpec[i] * viscSpec[j]) / GasConstant / temp;
597  }
598  }
599 }
600 
601 doublereal LTI_MoleFracs_ExpT::getMixTransProp(doublereal* speciesValues, doublereal* speciesWeight)
602 {
603  size_t nsp = m_thermo->nSpecies();
604  doublereal temp = m_thermo->temperature();
605  vector_fp molefracs(nsp);
606  m_thermo->getMoleFractions(&molefracs[0]);
607  doublereal value = 0;
608 
609  //if weightings are specified, use those
610  if (speciesWeight) {
611  for (size_t k = 0; k < nsp; k++) {
612  molefracs[k] = molefracs[k]*speciesWeight[k];
613  }
614  } else {
615  throw CanteraError("LTI_MoleFracs_ExpT::getMixTransProp","You should be specifying the speciesWeight");
616  }
617 
618  for (size_t i = 0; i < nsp; i++) {
619  value += speciesValues[i] * molefracs[i];
620  for (size_t j = 0; j < nsp; j++) {
621  for (size_t k = 0; k < m_Aij.size(); k++) {
622  value += molefracs[i]*molefracs[j]*(*m_Aij[k])(i,j)*pow(molefracs[i], (int) k)*exp((*m_Bij[k])(i,j)*temp);
623  }
624  }
625  }
626  return value;
627 }
628 
629 doublereal LTI_MoleFracs_ExpT::getMixTransProp(std::vector<LTPspecies*> LTPptrs)
630 {
631  size_t nsp = m_thermo->nSpecies();
632  doublereal temp = m_thermo->temperature();
633  vector_fp molefracs(nsp);
634  m_thermo->getMoleFractions(&molefracs[0]);
635  doublereal value = 0;
636 
637  for (size_t k = 0; k < nsp; k++) {
638  molefracs[k] = molefracs[k]*LTPptrs[k]->getMixWeight();
639  }
640 
641  for (size_t i = 0; i < nsp; i++) {
642  value += LTPptrs[i]->getSpeciesTransProp() * molefracs[i];
643  for (size_t j = 0; j < nsp; j++) {
644  for (size_t k = 0; k < m_Aij.size(); k++) {
645  value += molefracs[i]*molefracs[j]*(*m_Aij[k])(i,j)*pow(molefracs[i], (int) k)*exp((*m_Bij[k])(i,j)*temp);
646  }
647  }
648  }
649  return value;
650 }
651 
652 } //namespace Cantera
doublereal molarVolume() const
Molar volume (m^3/kmol).
Definition: Phase.cpp:600
thermo_t * m_thermo
pointer to thermo object to get current temperature
doublereal getMixTransProp(doublereal *valueSpecies, doublereal *weightSpecies=0)
Return the mixture transport property value.
TransportPropertyType
Enumeration of the types of transport properties that can be handled by the variables in the various ...
Definition: LTPspecies.h:34
LiquidTranMixingModel m_model
Model for species interaction effects. Takes enum LiquidTranMixingModel.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
std::string name() const
Returns the name of the XML node.
Definition: xml.h:370
std::vector< LiquidTranInteraction * > mobilityRatio
Vector of pointer to the LiquidTranInteraction object which handles the calculation of the mobility r...
void getMassFractions(doublereal *const y) const
Get the species mass fractions.
Definition: Phase.cpp:508
(see Thermodynamic Properties and class MargulesVPSSTP).
std::vector< DenseMatrix * > m_Hij
Matrix of interaction coefficients for polynomial in molefraction*weight of speciesA (in energy units...
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert, const std::string &unitsString, const std::string &nodeName)
This function reads the current node or a child node of the current node with the default name...
Definition: ctml.cpp:256
size_t speciesIndex(const std::string &name) const
Returns the index of a species named &#39;name&#39; within the Phase object.
Definition: Phase.cpp:175
Header for intermediate ThermoPhase object for phases which consist of ions whose thermodynamics is c...
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
doublereal getMixTransProp(doublereal *valueSpecies, doublereal *weightSpecies=0)
Return the mixture transport property value.
std::vector< DenseMatrix * > m_Bij
Matrix of interaction coefficients for polynomial in molefraction*weight of speciesA (linear temperat...
std::vector< DenseMatrix * > m_Aij
Matrix of interaction coefficients for polynomial in molefraction*weight of speciesA (no temperature ...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:266
STL namespace.
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
const doublereal Pi
Pi.
Definition: ct_defs.h:51
virtual doublereal getMixTransProp(doublereal *speciesValues, doublereal *weightSpecies=0)
Return the mixture transport property value.
void getMatrixTransProp(DenseMatrix &mat, doublereal *speciesValues=0)
Return the matrix of binary interaction parameters.
void getMatrixTransProp(DenseMatrix &mat, doublereal *speciesValues=0)
Return the matrix of binary interaction parameters.
std::vector< LiquidTransportData > LTData
Species transport parameters.
void getAnionList(std::vector< size_t > &anion) const
Get the list of anions in this object.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
Class LiquidTransportParams holds transport model parameters relevant to transport in mixtures...
std::vector< LiquidTranInteraction * > selfDiffusion
Vector of pointer to the LiquidTranInteraction object which handles the calculation of each species&#39; ...
Header file defining class LiquidTransportParams.
LiquidTranInteraction * ionConductivity
Object that specifies the ionic Conductivity of the mixture.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the matrix.
Definition: DenseMatrix.cpp:69
DenseMatrix m_Dij
Matrix of interactions.
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
Exception thrown if an error is encountered while reading the transport database. ...
std::vector< DenseMatrix * > m_Sij
Matrix of interaction coefficients for polynomial in molefraction*weight of speciesA (in entropy unit...
void getNeutralMolecMoleFractions(vector_fp &neutralMoleculeMoleFractions) const
Return the current value of the neutral mole fraction vector.
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:466
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:536
XML_Node & child(const size_t n) const
Return a changeable reference to the n&#39;th child of the current node.
Definition: xml.cpp:546
#define AssertTrace(expr)
Assertion must be true or an error is thrown.
Definition: ctexceptions.h:233
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:500
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:157
doublereal getMixTransProp(doublereal *valueSpecies, doublereal *weightSpecies=0)
Return the mixture transport property value.
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
doublereal getMixTransProp(doublereal *valueSpecies, doublereal *weightSpecies=0)
Return the mixture transport property value.
Contains declarations for string manipulation functions within Cantera.
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:164
MargulesVPSSTP is a derived class of GibbsExcessVPSSTP that employs the Margules approximation for th...
doublereal getMixTransProp(doublereal *valueSpecies, doublereal *weightSpecies=0)
Return the mixture transport property value.
void getCationList(std::vector< size_t > &cation) const
Get the list of cations in this object.
virtual void init(const XML_Node &compModelNode=XML_Node(), thermo_t *thermo=0)
initialize LiquidTranInteraction objects with thermo and XML node
void getDissociationCoeffs(vector_fp &fm_neutralMolec_ions, vector_fp &charges, std::vector< size_t > &neutMolIndex) const
Get the Salt Dissociation Coefficients.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
doublereal getMixTransProp(doublereal *valueSpecies, doublereal *weightSpecies=0)
Return the mixture transport property value.
DenseMatrix m_Eij
Matrix of interactions (in energy units, 1/RT temperature dependence)
Base class to handle transport property evaluation in a mixture.
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:556
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
Definition: DenseMatrix.h:50