Cantera  2.0
GasTransport.cpp
3 
4 namespace Cantera {
5 
6 GasTransport::GasTransport(ThermoPhase* thermo) :
7  Transport(thermo),
8  m_molefracs(0),
9  m_viscmix(0.0),
10  m_visc_ok(false),
11  m_viscwt_ok(false),
12  m_spvisc_ok(false),
13  m_bindiff_ok(false),
14  m_mode(0),
15  m_phi(0,0),
16  m_spwork(0),
17  m_visc(0),
18  m_visccoeffs(0),
19  m_mw(0),
20  m_wratjk(0,0),
21  m_wratkj1(0,0),
22  m_sqvisc(0),
23  m_polytempvec(5),
24  m_temp(-1.0),
25  m_kbt(0.0),
26  m_sqrt_kbt(0.0),
27  m_sqrt_t(0.0),
28  m_logt(0.0),
29  m_t14(0.0),
30  m_t32(0.0),
31  m_diffcoeffs(0),
32  m_bdiff(0, 0)
33 {
34 }
35 
36 GasTransport::GasTransport(const GasTransport& right) :
37  m_molefracs(0),
38  m_viscmix(0.0),
39  m_visc_ok(false),
40  m_viscwt_ok(false),
41  m_spvisc_ok(false),
42  m_bindiff_ok(false),
43  m_mode(0),
44  m_phi(0,0),
45  m_spwork(0),
46  m_visc(0),
47  m_visccoeffs(0),
48  m_mw(0),
49  m_wratjk(0,0),
50  m_wratkj1(0,0),
51  m_sqvisc(0),
52  m_polytempvec(5),
53  m_temp(-1.0),
54  m_kbt(0.0),
55  m_sqrt_kbt(0.0),
56  m_sqrt_t(0.0),
57  m_logt(0.0),
58  m_t14(0.0),
59  m_t32(0.0),
60  m_diffcoeffs(0),
61  m_bdiff(0, 0)
62 {
63 }
64 
65 GasTransport& GasTransport::operator=(const GasTransport& right)
66 {
67  m_molefracs = right.m_molefracs;
68  m_viscmix = right.m_viscmix;
69  m_visc_ok = right.m_visc_ok;
70  m_viscwt_ok = right.m_viscwt_ok;
71  m_spvisc_ok = right.m_spvisc_ok;
72  m_bindiff_ok = right.m_bindiff_ok;
73  m_mode = right.m_mode;
74  m_phi = right.m_phi;
75  m_spwork = right.m_spwork;
76  m_visc = right.m_visc;
77  m_mw = right.m_mw;
78  m_wratjk = right.m_wratjk;
79  m_wratkj1 = right.m_wratkj1;
80  m_sqvisc = right.m_sqvisc;
81  m_polytempvec = right.m_polytempvec;
82  m_temp = right.m_temp;
83  m_kbt = right.m_kbt;
84  m_sqrt_kbt = right.m_sqrt_kbt;
85  m_sqrt_t = right.m_sqrt_t;
86  m_logt = right.m_logt;
87  m_t14 = right.m_t14;
88  m_t32 = right.m_t32;
89  m_diffcoeffs = right.m_diffcoeffs;
90  m_bdiff = right.m_bdiff;
91 
92  return *this;
93 }
94 
96 {
97  // constant mixture attributes
98  m_thermo = tr.thermo;
99  m_nsp = m_thermo->nSpecies();
100 
101  // copy polynomials and parameters into local storage
104  m_mode = tr.mode_;
105 
106  m_molefracs.resize(m_nsp);
107  m_spwork.resize(m_nsp);
108  m_visc.resize(m_nsp);
109  m_phi.resize(m_nsp, m_nsp, 0.0);
111 
112  // make a local copy of the molecular weights
113  m_mw.resize(m_nsp);
114  copy(m_thermo->molecularWeights().begin(),
115  m_thermo->molecularWeights().end(), m_mw.begin());
116 
117  m_wratjk.resize(m_nsp, m_nsp, 0.0);
118  m_wratkj1.resize(m_nsp, m_nsp, 0.0);
119  for (size_t j = 0; j < m_nsp; j++) {
120  for (size_t k = j; k < m_nsp; k++) {
121  m_wratjk(j,k) = sqrt(m_mw[j]/m_mw[k]);
122  m_wratjk(k,j) = sqrt(m_wratjk(j,k));
123  m_wratkj1(j,k) = sqrt(1.0 + m_mw[k]/m_mw[j]);
124  }
125  }
126 
127  m_sqvisc.resize(m_nsp);
128 
129  // set flags all false
130  m_visc_ok = false;
131  m_viscwt_ok = false;
132  m_spvisc_ok = false;
133  m_bindiff_ok = false;
134 
135  return true;
136 }
137 
138 void GasTransport::update_T(void) {
139  double T = m_thermo->temperature();
140  if (T == m_temp) {
141  return;
142  }
143 
144  m_temp = T;
145  m_kbt = Boltzmann * m_temp;
146  m_sqrt_kbt = sqrt(Boltzmann*m_temp);
147  m_logt = log(m_temp);
148  m_sqrt_t = sqrt(m_temp);
149  m_t14 = sqrt(m_sqrt_t);
150  m_t32 = m_temp * m_sqrt_t;
151 
152  // compute powers of log(T)
153  m_polytempvec[0] = 1.0;
154  m_polytempvec[1] = m_logt;
156  m_polytempvec[3] = m_logt*m_logt*m_logt;
157  m_polytempvec[4] = m_logt*m_logt*m_logt*m_logt;
158 
159  // temperature has changed, so polynomial fits will need to be redone
160  m_visc_ok = false;
161  m_spvisc_ok = false;
162  m_viscwt_ok = false;
163  m_bindiff_ok = false;
164 }
165 
167 {
168  update_T();
169  update_C();
170 
171  if (m_visc_ok) {
172  return m_viscmix;
173  }
174 
175  doublereal vismix = 0.0;
176  // update m_visc and m_phi if necessary
177  if (!m_viscwt_ok) {
179  }
180 
182 
183  for (size_t k = 0; k < m_nsp; k++) {
184  vismix += m_molefracs[k] * m_visc[k]/m_spwork[k]; //denom;
185  }
186  m_viscmix = vismix;
187  return vismix;
188 }
189 
191 {
192  doublereal vratiokj, wratiojk, factor1;
193 
194  if (!m_spvisc_ok) {
196  }
197 
198  // see Eq. (9-5.15) of Reid, Prausnitz, and Poling
199  for (size_t j = 0; j < m_nsp; j++) {
200  for (size_t k = j; k < m_nsp; k++) {
201  vratiokj = m_visc[k]/m_visc[j];
202  wratiojk = m_mw[j]/m_mw[k];
203 
204  // Note that m_wratjk(k,j) holds the square root of m_wratjk(j,k)!
205  factor1 = 1.0 + (m_sqvisc[k]/m_sqvisc[j]) * m_wratjk(k,j);
206  m_phi(k,j) = factor1*factor1 / (SqrtEight * m_wratkj1(j,k));
207  m_phi(j,k) = m_phi(k,j)/(vratiokj * wratiojk);
208  }
209  }
210  m_viscwt_ok = true;
211 }
212 
214 {
215  update_T();
216  if (m_mode == CK_Mode) {
217  for (size_t k = 0; k < m_nsp; k++) {
218  m_visc[k] = exp(dot4(m_polytempvec, m_visccoeffs[k]));
219  m_sqvisc[k] = sqrt(m_visc[k]);
220  }
221  } else {
222  for (size_t k = 0; k < m_nsp; k++) {
223  // the polynomial fit is done for sqrt(visc/sqrt(T))
225  m_visc[k] = (m_sqvisc[k] * m_sqvisc[k]);
226  }
227  }
228  m_spvisc_ok = true;
229 }
230 
232 {
233  update_T();
234  // evaluate binary diffusion coefficients at unit pressure
235  size_t ic = 0;
236  if (m_mode == CK_Mode) {
237  for (size_t i = 0; i < m_nsp; i++) {
238  for (size_t j = i; j < m_nsp; j++) {
239  m_bdiff(i,j) = exp(dot4(m_polytempvec, m_diffcoeffs[ic]));
240  m_bdiff(j,i) = m_bdiff(i,j);
241  ic++;
242  }
243  }
244  } else {
245  for (size_t i = 0; i < m_nsp; i++) {
246  for (size_t j = i; j < m_nsp; j++) {
248  m_diffcoeffs[ic]);
249  m_bdiff(j,i) = m_bdiff(i,j);
250  ic++;
251  }
252  }
253  }
254  m_bindiff_ok = true;
255 }
256 
257 void GasTransport::getBinaryDiffCoeffs(const size_t ld, doublereal* const d)
258 {
259  update_T();
260  // if necessary, evaluate the binary diffusion coefficients from the polynomial fits
261  if (!m_bindiff_ok) {
262  updateDiff_T();
263  }
264  if (ld < m_nsp) {
265  throw CanteraError(" MixTransport::getBinaryDiffCoeffs()", "ld is too small");
266  }
267  doublereal rp = 1.0/m_thermo->pressure();
268  for (size_t i = 0; i < m_nsp; i++)
269  for (size_t j = 0; j < m_nsp; j++) {
270  d[ld*j + i] = rp * m_bdiff(i,j);
271  }
272 }
273 
274 void GasTransport::getMixDiffCoeffs(doublereal* const d)
275 {
276  update_T();
277  update_C();
278 
279  // update the binary diffusion coefficients if necessary
280  if (!m_bindiff_ok) {
281  updateDiff_T();
282  }
283 
284  doublereal mmw = m_thermo->meanMolecularWeight();
285  doublereal sumxw = 0.0;
286  doublereal p = m_thermo->pressure();
287  if (m_nsp == 1) {
288  d[0] = m_bdiff(0,0) / p;
289  } else {
290  for (size_t k = 0; k < m_nsp; k++) {
291  sumxw += m_molefracs[k] * m_mw[k];
292  }
293  for (size_t k = 0; k < m_nsp; k++) {
294  double sum2 = 0.0;
295  for (size_t j = 0; j < m_nsp; j++) {
296  if (j != k) {
297  sum2 += m_molefracs[j] / m_bdiff(j,k);
298  }
299  }
300  if (sum2 <= 0.0) {
301  d[k] = m_bdiff(k,k) / p;
302  } else {
303  d[k] = (sumxw - m_molefracs[k] * m_mw[k])/(p * mmw * sum2);
304  }
305  }
306  }
307 }
308 
309 void GasTransport::getMixDiffCoeffsMole(doublereal* const d)
310 {
311  update_T();
312  update_C();
313 
314  // update the binary diffusion coefficients if necessary
315  if (!m_bindiff_ok) {
316  updateDiff_T();
317  }
318 
319  doublereal p = m_thermo->pressure();
320  if (m_nsp == 1) {
321  d[0] = m_bdiff(0,0) / p;
322  } else {
323  for (size_t k = 0; k < m_nsp; k++) {
324  double sum2 = 0.0;
325  for (size_t j = 0; j < m_nsp; j++) {
326  if (j != k) {
327  sum2 += m_molefracs[j] / m_bdiff(j,k);
328  }
329  }
330  if (sum2 <= 0.0) {
331  d[k] = m_bdiff(k,k) / p;
332  } else {
333  d[k] = (1 - m_molefracs[k]) / (p * sum2);
334  }
335  }
336  }
337 }
338 
339 void GasTransport::getMixDiffCoeffsMass(doublereal* const d)
340 {
341  update_T();
342  update_C();
343 
344  // update the binary diffusion coefficients if necessary
345  if (!m_bindiff_ok) {
346  updateDiff_T();
347  }
348 
349  doublereal mmw = m_thermo->meanMolecularWeight();
350  doublereal p = m_thermo->pressure();
351 
352  if (m_nsp == 1) {
353  d[0] = m_bdiff(0,0) / p;
354  } else {
355  for (size_t k=0; k<m_nsp; k++) {
356  double sum1 = 0.0;
357  double sum2 = 0.0;
358  for (size_t i=0; i<m_nsp; i++) {
359  if (i==k) {
360  continue;
361  }
362  sum1 += m_molefracs[i] / m_bdiff(k,i);
363  sum2 += m_molefracs[i] * m_mw[i] / m_bdiff(k,i);
364  }
365  sum1 *= p;
366  sum2 *= p * m_molefracs[k] / (mmw - m_mw[k]*m_molefracs[k]);
367  d[k] = 1.0 / (sum1 + sum2);
368  }
369  }
370 }
371 
372 }