Cantera  2.0
AqueousTransport.h
Go to the documentation of this file.
1 /**
2  * @file AqueousTransport.h
3  * Header file defining class AqueousTransport
4  */
5 // Copyright 2001 California Institute of Technology
6 
7 
8 #ifndef CT_AQUEOUSTRAN_H
9 #define CT_AQUEOUSTRAN_H
10 
11 
12 // Cantera includes
13 #include "TransportBase.h"
15 #include "TransportParams.h"
16 #include "LiquidTransportParams.h"
17 
18 
19 #include <vector>
20 #include <string>
21 #include <map>
22 #include <numeric>
23 #include <algorithm>
24 
25 namespace Cantera
26 {
27 
28 
29 class LiquidTransportParams;
30 
31 
32 //! Class AqueousTransport implements mixture-averaged transport
33 //! properties for brine phases.
34 /*!
35  * The model is based on that
36  * described by Newman, Electrochemical Systems
37  *
38  * The velocity of species i may be described by the
39  * following equation p. 297 (12.1)
40  *
41  * \f[
42  * c_i \nabla \mu_i = R T \sum_j \frac{c_i c_j}{c_T D_{ij}}
43  * (\mathbf{v}_j - \mathbf{v}_i)
44  * \f]
45  *
46  * This as written is degenerate by 1 dof.
47  *
48  * To fix this we must add in the definition of the mass averaged
49  * velocity of the solution. We will call the simple bold-faced
50  * \f$\mathbf{v} \f$
51  * symbol the mass-averaged velocity. Then, the relation
52  * between \f$\mathbf{v}\f$ and the individual species velocities is
53  * \f$\mathbf{v}_i\f$
54  *
55  * \f[
56  * \rho_i \mathbf{v}_i = \rho_i \mathbf{v} + \mathbf{j}_i
57  * \f]
58  * where \f$\mathbf{j}_i\f$ are the diffusional fluxes of species i
59  * with respect to the mass averaged velocity and
60  *
61  * \f[
62  * \sum_i \mathbf{j}_i = 0
63  * \f]
64  *
65  * and
66  *
67  * \f[
68  * \sum_i \rho_i \mathbf{v}_i = \rho \mathbf{v}
69  * \f]
70  *
71  * Using these definitions, we can write
72  *
73  * \f[
74  * \mathbf{v}_i = \mathbf{v} + \frac{\mathbf{j}_i}{\rho_i}
75  * \f]
76  *
77  *
78  * \f[
79  * c_i \nabla \mu_i = R T \sum_j \frac{c_i c_j}{c_T D_{ij}}
80  * (\frac{\mathbf{j}_j}{\rho_j} - \frac{\mathbf{j}_i}{\rho_i})
81  * = R T \sum_j \frac{1}{D_{ij}}
82  * (\frac{x_i \mathbf{j}_j}{M_j} - \frac{x_j \mathbf{j}_i}{M_i})
83  * \f]
84  *
85  * The equations that we actually solve are
86  *
87  * \f[
88  * c_i \nabla \mu_i =
89  * = R T \sum_j \frac{1}{D_{ij}}
90  * (\frac{x_i \mathbf{j}_j}{M_j} - \frac{x_j \mathbf{j}_i}{M_i})
91  * \f]
92  * and we replace the 0th equation with the following:
93  *
94  * \f[
95  * \sum_i \mathbf{j}_i = 0
96  * \f]
97  *
98  * When there are charged species, we replace the rhs with the
99  * gradient of the electrochemical potential to obtain the
100  * modified equation
101  *
102  * \f[
103  * c_i \nabla \mu_i + c_i F z_i \nabla \Phi
104  * = R T \sum_j \frac{1}{D_{ij}}
105  * (\frac{x_i \mathbf{j}_j}{M_j} - \frac{x_j \mathbf{j}_i}{M_i})
106  * \f]
107  *
108  * With this formulation we may solve for the diffusion velocities,
109  * without having to worry about what the mass averaged velocity
110  * is.
111  *
112  * <H2> Viscosity Calculation </H2>
113  *
114  * The viscosity calculation may be broken down into two parts.
115  * In the first part, the viscosity of the pure species are calculated
116  * In the second part, a mixing rule is applied, based on the
117  * Wilkes correlation, to yield the mixture viscosity.
118  *
119  *
120  *
121  */
123 {
124 
125 public:
126 
127  //! default constructor
129 
130  //! virtual destructor
131  virtual ~AqueousTransport() {}
132 
133  //! Return the model id for this transport parameterization
134  virtual int model() const {
135  return cAqueousTransport;
136  }
137 
138  //! Returns the viscosity of the solution
139  /*!
140  * The viscosity is computed using the Wilke mixture rule.
141  * \f[
142  * \mu = \sum_k \frac{\mu_k X_k}{\sum_j \Phi_{k,j} X_j}.
143  * \f]
144  * Here \f$ \mu_k \f$ is the viscosity of pure species \e k,
145  * and
146  * \f[
147  * \Phi_{k,j} = \frac{\left[1
148  * + \sqrt{\left(\frac{\mu_k}{\mu_j}\sqrt{\frac{M_j}{M_k}}\right)}\right]^2}
149  * {\sqrt{8}\sqrt{1 + M_k/M_j}}
150  * \f]
151  * @see updateViscosity_T();
152  *
153  * Controlling update boolean m_viscmix_ok
154  */
155  virtual doublereal viscosity();
156 
157  //! Returns the pure species viscosities
158  /*!
159  *
160  * Controlling update boolean = m_viscwt_ok
161  *
162  * @param visc Vector of species viscosities
163  */
164  virtual void getSpeciesViscosities(doublereal* const visc);
165 
166  //! Return a vector of Thermal diffusion coefficients [kg/m/sec].
167  /*!
168  * The thermal diffusion coefficient \f$ D^T_k \f$ is defined
169  * so that the diffusive mass flux of species <I>k</I> induced by the
170  * local temperature gradient is given by the following formula
171  *
172  * \f[
173  * M_k J_k = -D^T_k \nabla \ln T.
174  * \f]
175  *
176  * The thermal diffusion coefficient can be either positive or negative.
177  *
178  * In this method we set it to zero.
179  *
180  * @param dt On return, dt will contain the species thermal
181  * diffusion coefficients. Dimension dt at least as large as
182  * the number of species. Units are kg/m/s.
183  */
184  virtual void getThermalDiffCoeffs(doublereal* const dt);
185 
186  //! Return the thermal conductivity of the solution
187  /*!
188  * The thermal conductivity is computed from the following mixture rule:
189  * \f[
190  * \lambda = 0.5 \left( \sum_k X_k \lambda_k
191  * + \frac{1}{\sum_k X_k/\lambda_k}\right)
192  * \f]
193  *
194  * Controlling update boolean = m_condmix_ok
195  */
196  virtual doublereal thermalConductivity();
197 
198  //! Returns the binary diffusion coefficients
199  /*!
200  * @param ld
201  * @param d
202  */
203  virtual void getBinaryDiffCoeffs(const size_t ld, doublereal* const d);
204 
205  //! Get the Mixture diffusion coefficients
206  /*!
207  * @param d vector of mixture diffusion coefficients
208  * units = m2 s-1. length = number of species
209  */
210  virtual void getMixDiffCoeffs(doublereal* const d);
211 
212  //! Get the Electrical mobilities (m^2/V/s).
213  /*!
214  * This function returns the electrical mobilities. In some formulations
215  * this is equal to the normal mobility multiplied by faraday's constant.
216  *
217  * Frequently, but not always, the mobility is calculated from the
218  * diffusion coefficient using the Einstein relation
219  *
220  * \f[
221  * \mu^e_k = \frac{F D_k}{R T}
222  * \f]
223  *
224  * @param mobil_e Returns the mobilities of
225  * the species in array \c mobil_e. The array must be
226  * dimensioned at least as large as the number of species.
227  */
228  virtual void getMobilities(doublereal* const mobil_e);
229 
230  //! Get the fluid mobilities (s kmol/kg).
231  /*!
232  * This function returns the fluid mobilities. Usually, you have
233  * to multiply Faraday's constant into the resulting expression
234  * to general a species flux expression.
235  *
236  * Frequently, but not always, the mobility is calculated from the
237  * diffusion coefficient using the Einstein relation
238  *
239  * \f[
240  * \mu^f_k = \frac{D_k}{R T}
241  * \f]
242  *
243  * @param mobil_f Returns the mobilities of
244  * the species in array \c mobil_f. The array must be
245  * dimensioned at least as large as the number of species.
246  */
247  virtual void getFluidMobilities(doublereal* const mobil_f);
248 
249 
250  //! Specify the value of the gradient of the voltage
251  /*!
252  *
253  * @param grad_V Gradient of the voltage (length num dimensions);
254  */
255  virtual void set_Grad_V(const doublereal* const grad_V);
256 
257  //! Specify the value of the gradient of the temperature
258  /*!
259  *
260  * @param grad_T Gradient of the temperature (length num dimensions);
261  */
262  virtual void set_Grad_T(const doublereal* const grad_T);
263 
264  //! Specify the value of the gradient of the MoleFractions
265  /*!
266  *
267  * @param grad_X Gradient of the mole fractions(length nsp * num dimensions);
268  */
269  virtual void set_Grad_X(const doublereal* const grad_X);
270 
271  //! Handles the effects of changes in the Temperature, internally
272  //! within the object.
273  /*!
274  * This is called whenever a transport property is
275  * requested.
276  * The first task is to check whether the temperature has changed
277  * since the last call to update_T().
278  * If it hasn't then an immediate return is carried out.
279  *
280  * @internal
281  */
282  virtual void update_T();
283 
284  //! Handles the effects of changes in the mixture concentration
285  /*!
286  * This is called the first time any transport property
287  * is requested from Mixture after the concentrations
288  * have changed.
289  *
290  * @internal
291  */
292  virtual void update_C();
293 
294 
295  //! Get the species diffusive mass fluxes wrt to the specified solution averaged velocity,
296  //! given the gradients in mole fraction and temperature
297  /*!
298  * Units for the returned fluxes are kg m-2 s-1.
299  *
300  * Usually the specified solution average velocity is the mass averaged velocity.
301  * This is changed in some subclasses, however.
302  *
303  * @param ndim Number of dimensions in the flux expressions
304  * @param grad_T Gradient of the temperature
305  * (length = ndim)
306  * @param ldx Leading dimension of the grad_X array
307  * (usually equal to m_nsp but not always)
308  * @param grad_X Gradients of the mole fraction
309  * Flat vector with the m_nsp in the inner loop.
310  * length = ldx * ndim
311  * @param ldf Leading dimension of the fluxes array
312  * (usually equal to m_nsp but not always)
313  * @param fluxes Output of the diffusive mass fluxes
314  * Flat vector with the m_nsp in the inner loop.
315  * length = ldx * ndim
316  */
317  virtual void getSpeciesFluxes(size_t ndim, const doublereal* const grad_T,
318  size_t ldx, const doublereal* const grad_X,
319  size_t ldf, doublereal* const fluxes);
320 
321  //! Return the species diffusive mass fluxes wrt to the specified averaged velocity,
322  /*!
323  * This method acts similarly to getSpeciesFluxesES() but
324  * requires all gradients to be preset using methods set_Grad_X(), set_Grad_V(), set_Grad_T().
325  * See the documentation of getSpeciesFluxesES() for details.
326  *
327  * units = kg/m2/s
328  *
329  * Internally, gradients in the in mole fraction, temperature
330  * and electrostatic potential contribute to the diffusive flux
331  *
332  * The diffusive mass flux of species \e k is computed from the following formula
333  *
334  * \f[
335  * j_k = - \rho M_k D_k \nabla X_k - Y_k V_c
336  * \f]
337  *
338  * where V_c is the correction velocity
339  *
340  * \f[
341  * V_c = - \sum_j {\rho M_j D_j \nabla X_j}
342  * \f]
343  *
344  * @param ldf Stride of the fluxes array. Must be equal to or greater than the number of species.
345  * @param fluxes Output of the diffusive fluxes. Flat vector with the m_nsp in the inner loop.
346  * length = ldx * ndim
347  */
348  virtual void getSpeciesFluxesExt(size_t ldf, doublereal* const fluxes);
349 
350 
351  //! Initialize the transport object
352  /*!
353  * Here we change all of the internal dimensions to be sufficient.
354  * We get the object ready to do property evaluations.
355  *
356  * @param tr Transport parameters for all of the species
357  * in the phase.
358  */
359  virtual bool initLiquid(LiquidTransportParams& tr);
360 
361  friend class TransportFactory;
362 
363  /**
364  * Return a structure containing all of the pertinent parameters
365  * about a species that was used to construct the Transport
366  * properties in this object.
367  *
368  * @param k Species number to obtain the properties about.
369  */
371 
372 
373  //! Solve the stefan_maxell equations for the diffusive fluxes.
374  void stefan_maxwell_solve();
375 
376 private:
377  //! Minimum temperature applicable to the transport property eval
378  doublereal m_tmin;
379 
380  //! Maximum temperature applicable to the transport property evaluator
381  doublereal m_tmax;
382 
383  //! Local Copy of the molecular weights of the species
384  /*!
385  * Length is Equal to the number of species in the mechanism.
386  */
388 
389  //! Polynomial coefficients of the viscosity
390  /*!
391  * These express the temperature dependence of the pure species viscosities.
392  */
393  std::vector<vector_fp> m_visccoeffs;
394 
395  //! Polynomial coefficients of the conductivities
396  /*!
397  * These express the temperature dependence of the pure species conductivities
398  */
399  std::vector<vector_fp> m_condcoeffs;
400 
401  //! Polynomial coefficients of the binary diffusion coefficients
402  /*!
403  * These express the temperature dependence of the binary diffusivities.
404  * An overall pressure dependence is then added.
405  */
406  std::vector<vector_fp> m_diffcoeffs;
407 
408 
409  //! Internal value of the gradient of the mole fraction vector
410  /*!
411  * m_nsp is the number of species in the fluid
412  * k is the species index
413  * n is the dimensional index (x, y, or z). It has a length
414  * equal to m_nDim
415  *
416  * m_Grad_X[n*m_nsp + k]
417  */
419 
420  //! Internal value of the gradient of the Temperature vector
421  /*!
422  * Generally, if a transport property needs this
423  * in its evaluation it will look to this place
424  * to get it.
425  *
426  * No internal property is precalculated based on gradients.
427  * Gradients are assumed to be freshly updated before
428  * every property call.
429  */
431 
432  //! Internal value of the gradient of the Electric Voltage
433  /*!
434  * Generally, if a transport property needs this
435  * in its evaluation it will look to this place
436  * to get it.
437  *
438  * No internal property is precalculated based on gradients.
439  * Gradients are assumed to be freshly updated before
440  * every property call.
441  */
443 
444  //! Gradient of the electrochemical potential
445  /*!
446  * m_nsp is the number of species in the fluid
447  * k is the species index
448  * n is the dimensional index (x, y, or z)
449  *
450  * m_Grad_mu[n*m_nsp + k]
451  */
453 
454  // property values
455 
456  //! Array of Binary Diffusivities
457  /*!
458  * This has a size equal to nsp x nsp
459  * It is a symmetric matrix.
460  * D_ii is undefined.
461  *
462  * units m2/sec
463  */
465 
466  //! Species viscosities
467  /*!
468  * Viscosity of the species
469  * Length = number of species
470  *
471  * Depends on the temperature and perhaps pressure, but
472  * not the species concentrations
473  *
474  * controlling update boolean -> m_spvisc_ok
475  */
477 
478  //! Sqrt of the species viscosities
479  /*!
480  * The sqrt(visc) is used in the mixing formulas
481  * Length = m_nsp
482  *
483  * Depends on the temperature and perhaps pressure, but
484  * not the species concentrations
485  *
486  * controlling update boolean m_spvisc_ok
487  */
489 
490  //! Internal value of the species individual thermal conductivities
491  /*!
492  * Then a mixture rule is applied to get the solution conductivities
493  *
494  * Depends on the temperature and perhaps pressure, but
495  * not the species concentrations
496  *
497  * controlling update boolean -> m_spcond_ok
498  */
500 
501  //! Polynomials of the log of the temperature
503 
504  //! State of the mole fraction vector.
506 
507  //! Local copy of the mole fractions of the species in the phase
508  /*!
509  * Update info?
510  * length = m_nsp
511  */
513 
514  //! Local copy of the concentrations of the species in the phase
515  /*!
516  * Update info?
517  * length = m_nsp
518  */
520 
521  //! Local copy of the charge of each species
522  /*!
523  * Contains the charge of each species (length m_nsp)
524  */
526 
527  //! Stefan-Maxwell Diffusion Coefficients at T, P and C
528  /*!
529  * These diffusion coefficients are considered to be
530  * a function of Temperature, Pressure, and Concentration.
531  */
533 
534  //! viscosity weighting functions
536 
537  //! Matrix of the ratios of the species molecular weights
538  /*!
539  * m_wratjk(i,j) = (m_mw[j]/m_mw[k])**0.25
540  */
542 
543  //! Matrix of the ratios of the species molecular weights
544  /*!
545  * m_wratkj1(i,j) = (1.0 + m_mw[k]/m_mw[j])**0.5
546  */
548 
549  //! RHS to the stefan-maxwell equation
551 
552  //! Matrix for the stefan maxwell equation.
554 
555  //! Internal storage for the species LJ well depth
557 
558  //! Internal storage for species polarizability
560 
561  //! Current Temperature -> locally stored
562  /*!
563  * This is used to test whether new temperature computations
564  * should be performed.
565  */
566  doublereal m_temp;
567 
568  //! Current log(T)
569  doublereal m_logt;
570 
571  //! Current value of kT
572  doublereal m_kbt;
573 
574  //! Current Temperature **0.5
575  doublereal m_sqrt_t;
576 
577  //! Current Temperature **0.25
578  doublereal m_t14;
579 
580  //! Current Temperature **1.5
581  doublereal m_t32;
582 
583  //! Current temperature function
584  /*!
585  * This is equal to sqrt(Boltzmann * T)
586  */
587  doublereal m_sqrt_kbt;
588 
589  //! Current value of the pressure
590  doublereal m_press;
591 
592  //! Solution of the flux system
594 
595  //! saved value of the mixture thermal conductivity
596  doublereal m_lambda;
597 
598  //! Saved value of the mixture viscosity
599  doublereal m_viscmix;
600 
601  //! work space of size m_nsp
603 
604  //! Update the temperature-dependent viscosity terms.
605  //! Updates the array of pure species viscosities, and the
606  //! weighting functions in the viscosity mixture rule.
607  /*!
608  * The flag m_visc_ok is set to true.
609  */
610  void updateViscosity_T();
611 
612  //! Update the temperature-dependent parts of the mixture-averaged
613  //! thermal conductivity.
614  void updateCond_T();
615 
616  //! Update the species viscosities
617  /*!
618  * Internal routine is run whenever the update_boolean
619  * m_spvisc_ok is false. This routine will calculate
620  * internal values for the species viscosities.
621  *
622  * @internal
623  */
625 
626  //! Update the binary diffusion coefficients wrt T.
627  /*!
628  * These are evaluated
629  * from the polynomial fits at unit pressure (1 Pa).
630  */
631  void updateDiff_T();
632 
633  //! Boolean indicating that mixture viscosity is current
635 
636  //! Boolean indicating that weight factors wrt viscosity is current
638 
639  //! Flag to indicate that the pure species viscosities
640  //! are current wrt the temperature
642 
643  //! Boolean indicating that mixture diffusion coeffs are current
645 
646  //! Boolean indicating that binary diffusion coeffs are current
648 
649  //! Flag to indicate that the pure species conductivities
650  //! are current wrt the temperature
652 
653  //! Boolean indicating that mixture conductivity is current
655 
656  //! Mode for fitting the species viscosities
657  /*!
658  * Either it's CK_Mode or it's cantera mode
659  * in CK_Mode visc is fitted to a polynomial
660  * in Cantera mode sqrt(visc) is fitted.
661  */
662  int m_mode;
663 
664  //! Internal storage for the diameter - diameter
665  //! species interactions
667 
668  //! Debugging flags
669  /*!
670  * Turn on to get debugging information
671  */
672  bool m_debug;
673 
674  //! Number of dimensions
675  /*!
676  * Either 1, 2, or 3
677  */
678  size_t m_nDim;
679 };
680 }
681 #endif
682 
683 
684 
685 
686 
687