Cantera  2.3.0
DustyGasTransport.cpp
Go to the documentation of this file.
1 /**
2  * @file DustyGasTransport.cpp
3  * Implementation file for class DustyGasTransport
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 
11 
12 using namespace std;
13 
14 namespace Cantera
15 {
16 DustyGasTransport::DustyGasTransport(thermo_t* thermo) :
17  Transport(thermo),
18  m_temp(-1.0),
19  m_gradP(0.0),
20  m_knudsen_ok(false),
21  m_bulk_ok(false),
22  m_porosity(0.0),
23  m_tortuosity(1.0),
24  m_pore_radius(0.0),
25  m_diam(0.0),
26  m_perm(-1.0)
27 {
28 }
29 
31  m_temp(-1.0),
32  m_gradP(0.0),
33  m_knudsen_ok(false),
34  m_bulk_ok(false),
35  m_porosity(0.0),
36  m_tortuosity(1.0),
37  m_pore_radius(0.0),
38  m_diam(0.0),
39  m_perm(-1.0)
40 {
41  *this = right;
42 }
43 
45 {
46  if (&right == this) {
47  return *this;
48  }
49  Transport::operator=(right);
50 
51  m_mw = right.m_mw;
52  m_d = right.m_d;
53  m_x = right.m_x;
54  m_dk = right.m_dk;
55  m_temp = right.m_temp;
56  m_multidiff = right.m_multidiff;
57  m_spwork = right.m_spwork;
58  m_spwork2 = right.m_spwork2;
59  m_gradP = right.m_gradP;
60  m_knudsen_ok = right.m_knudsen_ok;
61  m_bulk_ok= right.m_bulk_ok;
62  m_porosity = right.m_porosity;
63  m_tortuosity = right.m_tortuosity;
65  m_diam = right.m_diam;
66  m_perm = right.m_perm;
67 
68  // Warning -> gastran may not point to the correct object
69  // after this copy. The routine initialize() must be called
70  m_gastran.reset(right.m_gastran->duplMyselfAsTransport());
71 
72  return *this;
73 }
74 
76 {
77  DustyGasTransport* tr = new DustyGasTransport(*this);
78  return dynamic_cast<Transport*>(tr);
79 }
80 
82 {
84  m_gastran->setThermo(thermo);
85 }
86 
88 {
89  // constant mixture attributes
90  m_thermo = phase;
91  m_nsp = m_thermo->nSpecies();
92  if (m_gastran.get() != gastr) {
93  m_gastran.reset(gastr);
94  }
95 
96  // make a local copy of the molecular weights
98 
100  m_d.resize(m_nsp, m_nsp);
101  m_dk.resize(m_nsp, 0.0);
102 
103  m_x.resize(m_nsp, 0.0);
104  m_thermo->getMoleFractions(m_x.data());
105 
106  // set flags all false
107  m_knudsen_ok = false;
108  m_bulk_ok = false;
109 
110  m_spwork.resize(m_nsp);
111  m_spwork2.resize(m_nsp);
112 }
113 
115 {
116  if (m_bulk_ok) {
117  return;
118  }
119 
120  // get the gaseous binary diffusion coefficients
121  m_gastran->getBinaryDiffCoeffs(m_nsp, m_d.ptrColumn(0));
122  doublereal por2tort = m_porosity / m_tortuosity;
123  for (size_t n = 0; n < m_nsp; n++) {
124  for (size_t m = 0; m < m_nsp; m++) {
125  m_d(n,m) *= por2tort;
126  }
127  }
128  m_bulk_ok = true;
129 }
130 
132 {
133  if (m_knudsen_ok) {
134  return;
135  }
136  doublereal K_g = m_pore_radius * m_porosity / m_tortuosity;
137  for (size_t k = 0; k < m_nsp; k++) {
138  m_dk[k] = 2.0/3.0 * K_g * sqrt((8.0 * GasConstant * m_temp)/
139  (Pi * m_mw[k]));
140  }
141  m_knudsen_ok = true;
142 }
143 
145 {
148  for (size_t k = 0; k < m_nsp; k++) {
149  // evaluate off-diagonal terms
150  for (size_t j = 0; j < m_nsp; j++) {
151  m_multidiff(k,j) = -m_x[k]/m_d(k,j);
152  }
153 
154  // evaluate diagonal term
155  double sum = 0.0;
156  for (size_t j = 0; j < m_nsp; j++) {
157  if (j != k) {
158  sum += m_x[j]/m_d(k,j);
159  }
160  }
161  m_multidiff(k,k) = 1.0/m_dk[k] + sum;
162  }
163 }
164 
165 void DustyGasTransport::getMolarFluxes(const doublereal* const state1,
166  const doublereal* const state2,
167  const doublereal delta,
168  doublereal* const fluxes)
169 {
170  // cbar will be the average concentration between the two points
171  doublereal* const cbar = m_spwork.data();
172  doublereal* const gradc = m_spwork2.data();
173  const doublereal t1 = state1[0];
174  const doublereal t2 = state2[0];
175  const doublereal rho1 = state1[1];
176  const doublereal rho2 = state2[1];
177  const doublereal* const y1 = state1 + 2;
178  const doublereal* const y2 = state2 + 2;
179  doublereal c1sum = 0.0, c2sum = 0.0;
180 
181  for (size_t k = 0; k < m_nsp; k++) {
182  double conc1 = rho1 * y1[k] / m_mw[k];
183  double conc2 = rho2 * y2[k] / m_mw[k];
184  cbar[k] = 0.5*(conc1 + conc2);
185  gradc[k] = (conc2 - conc1) / delta;
186  c1sum += conc1;
187  c2sum += conc2;
188  }
189 
190  // Calculate the pressures at p1 p2 and pbar
191  doublereal p1 = c1sum * GasConstant * t1;
192  doublereal p2 = c2sum * GasConstant * t2;
193  doublereal pbar = 0.5*(p1 + p2);
194  doublereal gradp = (p2 - p1)/delta;
195  doublereal tbar = 0.5*(t1 + t2);
196  m_thermo->setState_TPX(tbar, pbar, cbar);
198 
199  // Multiply m_multidiff and gradc together and store the result in fluxes[]
200  multiply(m_multidiff, gradc, fluxes);
201  divide_each(cbar, cbar + m_nsp, m_dk.begin());
202 
203  // if no permeability has been specified, use result for
204  // close-packed spheres
205  double b = 0.0;
206  if (m_perm < 0.0) {
207  double p = m_porosity;
208  double d = m_diam;
209  double t = m_tortuosity;
210  b = p*p*p*d*d/(72.0*t*(1.0-p)*(1.0-p));
211  } else {
212  b = m_perm;
213  }
214  b *= gradp / m_gastran->viscosity();
215  scale(cbar, cbar + m_nsp, cbar, b);
216 
217  // Multiply m_multidiff with cbar and add it to fluxes
218  increment(m_multidiff, cbar, fluxes);
219  scale(fluxes, fluxes + m_nsp, fluxes, -1.0);
220 }
221 
223 {
224  // see if temperature has changed
226 
227  // update the mole fractions
229  eval_H_matrix();
230 
231  // invert H
232  int ierr = invert(m_multidiff);
233  if (ierr != 0) {
234  throw CanteraError("DustyGasTransport::updateMultiDiffCoeffs",
235  "invert returned ierr = {}", ierr);
236  }
237 }
238 
239 void DustyGasTransport::getMultiDiffCoeffs(const size_t ld, doublereal* const d)
240 {
242  for (size_t i = 0; i < m_nsp; i++) {
243  for (size_t j = 0; j < m_nsp; j++) {
244  d[ld*j + i] = m_multidiff(i,j);
245  }
246  }
247 }
248 
250 {
251  if (m_temp == m_thermo->temperature()) {
252  return;
253  }
255  m_knudsen_ok = false;
256  m_bulk_ok = false;
257 }
258 
260 {
261  m_thermo->getMoleFractions(m_x.data());
262 
263  // add an offset to avoid a pure species condition
264  // (check - this may be unnecessary)
265  for (size_t k = 0; k < m_nsp; k++) {
266  m_x[k] = std::max(Tiny, m_x[k]);
267  }
268  // diffusion coeffs depend on Pressure
269  m_bulk_ok = false;
270 }
271 
272 void DustyGasTransport::setPorosity(doublereal porosity)
273 {
274  m_porosity = porosity;
275  m_knudsen_ok = false;
276  m_bulk_ok = false;
277 }
278 
279 void DustyGasTransport::setTortuosity(doublereal tort)
280 {
281  m_tortuosity = tort;
282  m_knudsen_ok = false;
283  m_bulk_ok = false;
284 }
285 
287 {
288  m_pore_radius = rbar;
289  m_knudsen_ok = false;
290 }
291 
293 {
294  m_diam = dbar;
295 }
296 
298 {
299  m_perm = B;
300 }
301 
303 {
304  return *m_gastran;
305 }
306 
307 }
doublereal m_pore_radius
Pore radius (meter)
const vector_fp & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition: Phase.cpp:513
virtual void getMultiDiffCoeffs(const size_t ld, doublereal *const d)
Return the Multicomponent diffusion coefficients. Units: [m^2/s].
Headers for the DustyGasTransport object, which models transport properties in porous media using the...
std::unique_ptr< Transport > m_gastran
Pointer to the transport object for the gas phase.
int invert(DenseMatrix &A, size_t nn)
invert A. A is overwritten with A^-1.
void divide_each(OutputIter x_begin, OutputIter x_end, InputIter y_begin)
Templated divide of each element of x by the corresponding element of y.
Definition: utilities.h:269
void updateTransport_T()
Update temperature-dependent quantities within the object.
virtual void setThermo(thermo_t &thermo)
Specifies the ThermoPhase object.
Transport & gasTransport()
Return a reference to the transport manager used to compute the gas binary diffusion coefficients and...
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
virtual void setState_TPX(doublereal t, doublereal p, const doublereal *x)
Set the temperature (K), pressure (Pa), and mole fractions.
doublereal m_diam
Particle diameter.
vector_fp m_x
mole fractions
thermo_t * m_thermo
pointer to the object representing the phase
Class DustyGasTransport implements the Dusty Gas model for transport in porous media.
DenseMatrix m_d
binary diffusion coefficients
DustyGasTransport(thermo_t *thermo=0)
default constructor
Base class for transport property managers.
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:262
STL namespace.
DustyGasTransport & operator=(const DustyGasTransport &right)
Assignment operator.
void increment(const DenseMatrix &A, const double *b, double *prod)
Multiply A*b and add it to the result in prod. Uses BLAS routine DGEMV.
vector_fp m_dk
Knudsen diffusion coefficients.
const doublereal Pi
Pi.
Definition: ct_defs.h:51
doublereal * ptrColumn(size_t j)
Return a pointer to the top of column j, columns are contiguous in memory.
Definition: Array.h:314
void updateMultiDiffCoeffs()
Update the Multicomponent diffusion coefficients that are used in the approximation.
void eval_H_matrix()
Calculate the H matrix.
doublereal m_perm
Permeability of the media.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
doublereal m_gradP
Pressure Gradient.
void updateTransport_C()
Update concentration-dependent quantities within the object.
virtual Transport * duplMyselfAsTransport() const
Duplication routine for objects which inherit from Transport.
void setPorosity(doublereal porosity)
Set the porosity (dimensionless)
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the matrix.
Definition: DenseMatrix.cpp:69
bool m_knudsen_ok
Update-to-date variable for Knudsen diffusion coefficients.
void multiply(const DenseMatrix &A, const double *const b, double *const prod)
Multiply A*b and return the result in prod. Uses BLAS routine DGEMV.
vector_fp m_spwork2
work space of size m_nsp;
void initialize(ThermoPhase *phase, Transport *gastr)
Initialization routine called by TransportFactory.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
void setTortuosity(doublereal tort)
Set the tortuosity (dimensionless)
virtual void getMolarFluxes(const doublereal *const state1, const doublereal *const state2, const doublereal delta, doublereal *const fluxes)
Get the molar fluxes [kmol/m^2/s], given the thermodynamic state at two nearby points.
void setMeanPoreRadius(doublereal rbar)
Set the mean pore radius (m)
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:542
doublereal m_porosity
Porosity.
thermo_t & thermo()
doublereal m_tortuosity
Tortuosity.
void setPermeability(doublereal B)
Set the permeability of the media.
bool m_bulk_ok
Update-to-date variable for Binary diffusion coefficients.
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition: utilities.h:130
const doublereal Tiny
Small number to compare differences of mole fractions against.
Definition: ct_defs.h:143
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
Contains declarations for string manipulation functions within Cantera.
size_t m_nsp
Number of species.
doublereal m_temp
temperature
virtual void setThermo(thermo_t &thermo)
Specifies the ThermoPhase object.
Namespace for the Cantera kernel.
Definition: application.cpp:29
void updateBinaryDiffCoeffs()
Private routine to update the dusty gas binary diffusion coefficients.
DenseMatrix m_multidiff
Multicomponent diffusion coefficients.
Transport & operator=(const Transport &right)
vector_fp m_mw
Local copy of the species molecular weights.
vector_fp m_spwork
work space of size m_nsp;
void setMeanParticleDiameter(doublereal dbar)
Set the mean particle diameter.
void updateKnudsenDiffCoeffs()
Update the Knudsen diffusion coefficients.