kineticTheoryModel.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "kineticTheoryModel.H"
27 #include "mathematicalConstants.H"
28 #include "twoPhaseSystem.H"
29 #include "fvOptions.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
34 (
35  const volScalarField& alpha,
36  const volScalarField& rho,
37  const volVectorField& U,
38  const surfaceScalarField& alphaRhoPhi,
39  const surfaceScalarField& phi,
40  const transportModel& phase,
41  const word& propertiesName,
42  const word& type
43 )
44 :
45  eddyViscosity
46  <
48  >
49  (
50  type,
51  alpha,
52  rho,
53  U,
54  alphaRhoPhi,
55  phi,
56  phase,
57  propertiesName
58  ),
59 
60  phase_(phase),
61 
62  viscosityModel_
63  (
64  kineticTheoryModels::viscosityModel::New
65  (
66  coeffDict_
67  )
68  ),
69  conductivityModel_
70  (
71  kineticTheoryModels::conductivityModel::New
72  (
73  coeffDict_
74  )
75  ),
76  radialModel_
77  (
78  kineticTheoryModels::radialModel::New
79  (
80  coeffDict_
81  )
82  ),
83  granularPressureModel_
84  (
85  kineticTheoryModels::granularPressureModel::New
86  (
87  coeffDict_
88  )
89  ),
90  frictionalStressModel_
91  (
92  kineticTheoryModels::frictionalStressModel::New
93  (
94  coeffDict_
95  )
96  ),
97 
98  equilibrium_(coeffDict_.lookup("equilibrium")),
99  e_("e", dimless, coeffDict_),
100  alphaMax_("alphaMax", dimless, coeffDict_),
101  alphaMinFriction_
102  (
103  "alphaMinFriction",
104  dimless,
105  coeffDict_
106  ),
107  residualAlpha_
108  (
109  "residualAlpha",
110  dimless,
111  coeffDict_
112  ),
113 
114  maxNut_
115  (
116  "maxNut",
117  dimensionSet(0,2,-1,0,0),
118  coeffDict_.lookupOrDefault<scalar>("maxNut",1000)
119  ),
120 
121  Theta_
122  (
123  IOobject
124  (
125  IOobject::groupName("Theta", phase.name()),
126  U.time().timeName(),
127  U.mesh(),
128  IOobject::MUST_READ,
129  IOobject::AUTO_WRITE
130  ),
131  U.mesh()
132  ),
133 
134  lambda_
135  (
136  IOobject
137  (
138  IOobject::groupName("lambda", phase.name()),
139  U.time().timeName(),
140  U.mesh(),
141  IOobject::NO_READ,
142  IOobject::NO_WRITE
143  ),
144  U.mesh(),
145  dimensionedScalar(dimensionSet(0, 2, -1, 0, 0), 0)
146  ),
147 
148  gs0_
149  (
150  IOobject
151  (
152  IOobject::groupName("gs0", phase.name()),
153  U.time().timeName(),
154  U.mesh(),
155  IOobject::NO_READ,
156  IOobject::NO_WRITE
157  ),
158  U.mesh(),
159  dimensionedScalar(dimensionSet(0, 0, 0, 0, 0), 0)
160  ),
161 
162  kappa_
163  (
164  IOobject
165  (
166  IOobject::groupName("kappa", phase.name()),
167  U.time().timeName(),
168  U.mesh(),
169  IOobject::NO_READ,
170  IOobject::NO_WRITE
171  ),
172  U.mesh(),
173  dimensionedScalar(dimensionSet(1, -1, -1, 0, 0), 0)
174  ),
175 
176  nuFric_
177  (
178  IOobject
179  (
180  IOobject::groupName("nuFric", phase.name()),
181  U.time().timeName(),
182  U.mesh(),
183  IOobject::NO_READ,
184  IOobject::AUTO_WRITE
185  ),
186  U.mesh(),
187  dimensionedScalar(dimensionSet(0, 2, -1, 0, 0), 0)
188  )
189 {
190  if (type == typeName)
191  {
192  printCoeffs(type);
193  }
194 }
195 
196 
197 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
198 
200 {}
201 
202 
203 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
204 
206 {
207  if
208  (
209  eddyViscosity
210  <
211  RASModel<EddyDiffusivity<phaseCompressibleTurbulenceModel>>
212  >::read()
213  )
214  {
215  coeffDict().lookup("equilibrium") >> equilibrium_;
216  e_.readIfPresent(coeffDict());
217  alphaMax_.readIfPresent(coeffDict());
218  alphaMinFriction_.readIfPresent(coeffDict());
219 
220  viscosityModel_->read();
221  conductivityModel_->read();
222  radialModel_->read();
223  granularPressureModel_->read();
224  frictionalStressModel_->read();
225 
226  return true;
227  }
228  else
229  {
230  return false;
231  }
232 }
233 
234 
237 {
239  return nut_;
240 }
241 
242 
245 {
247  return nut_;
248 }
249 
250 
253 {
255  (
256  IOobject::groupName("R", U_.group()),
257  - (nut_)*dev(twoSymm(fvc::grad(U_)))
258  - (lambda_*fvc::div(phi_))*symmTensor::I
259  );
260 }
261 
262 
265 {
266  const volScalarField& rho = phase_.rho();
267 
268  tmp<volScalarField> tpPrime
269  (
270  Theta_
271  *granularPressureModel_->granularPressureCoeffPrime
272  (
273  alpha_,
274  radialModel_->g0(alpha_, alphaMinFriction_, alphaMax_),
275  radialModel_->g0prime(alpha_, alphaMinFriction_, alphaMax_),
276  rho,
277  e_
278  )
279  + frictionalStressModel_->frictionalPressurePrime
280  (
281  phase_,
282  alphaMinFriction_,
283  alphaMax_
284  )
285  );
286 
287  volScalarField::Boundary& bpPrime =
288  tpPrime.ref().boundaryFieldRef();
289 
290  forAll(bpPrime, patchi)
291  {
292  if (!bpPrime[patchi].coupled())
293  {
294  bpPrime[patchi] == 0;
295  }
296  }
297 
298  return tpPrime;
299 }
300 
301 
304 {
305  return fvc::interpolate(pPrime());
306 }
307 
308 
311 {
313  (
314  IOobject::groupName("devRhoReff", U_.group()),
315  - (rho_*nut_)
316  *dev(twoSymm(fvc::grad(U_)))
317  - ((rho_*lambda_)*fvc::div(phi_))*symmTensor::I
318  );
319 }
320 
321 
324 (
325  volVectorField& U
326 ) const
327 {
328  return
329  (
330  - fvm::laplacian(rho_*nut_, U)
331  - fvc::div
332  (
333  (rho_*nut_)*dev2(T(fvc::grad(U)))
334  + ((rho_*lambda_)*fvc::div(phi_))
335  *dimensioned<symmTensor>("I", dimless, symmTensor::I)
336  )
337  );
338 }
339 
340 
342 {
343  // Local references
344  const twoPhaseSystem& fluid = refCast<const twoPhaseSystem>(phase_.fluid());
345  volScalarField alpha(max(alpha_, scalar(0)));
346  const volScalarField& rho = phase_.rho();
347  const surfaceScalarField& alphaRhoPhi = alphaRhoPhi_;
348  const volVectorField& U = U_;
349  const volVectorField& Uc_ = fluid.otherPhase(phase_).U();
350 
351  const scalar sqrtPi = sqrt(constant::mathematical::pi);
352  dimensionedScalar ThetaSmall("ThetaSmall", Theta_.dimensions(), 1.0e-6);
353  dimensionedScalar ThetaSmallSqrt(sqrt(ThetaSmall));
354 
355  tmp<volScalarField> tda(phase_.d());
356  const volScalarField& da = tda();
357 
358  tmp<volTensorField> tgradU(fvc::grad(U_));
359  const volTensorField& gradU(tgradU());
360  volSymmTensorField D(symm(gradU));
361 
362  // Calculating the radial distribution function
363  gs0_ = radialModel_->g0(alpha, alphaMinFriction_, alphaMax_);
364 
365  if (!equilibrium_)
366  {
367  // Particle viscosity (Table 3.2, p.47)
368  nut_ = viscosityModel_->nu(alpha, Theta_, gs0_, rho, da, e_);
369 
370  volScalarField ThetaSqrt("sqrtTheta", sqrt(Theta_));
371 
372  // Bulk viscosity p. 45 (Lun et al. 1984).
373  lambda_ = (4.0/3.0)*sqr(alpha)*da*gs0_*(1.0 + e_)*ThetaSqrt/sqrtPi;
374 
375  // Stress tensor, Definitions, Table 3.1, p. 43
377  (
378  rho*(2.0*nut_*D + (lambda_ - (2.0/3.0)*nut_)*tr(D)*I)
379  );
380 
381  // Dissipation (Eq. 3.24, p.50)
382  volScalarField gammaCoeff
383  (
384  "gammaCoeff",
385  12.0*(1.0 - sqr(e_))
386  *max(sqr(alpha), residualAlpha_)
387  *rho*gs0_*(1.0/da)*ThetaSqrt/sqrtPi
388  );
389 
390  // Drag
391  volScalarField beta
392  (
393  fluid.lookupSubModel<dragModel>
394  (
395  phase_,
396  fluid.otherPhase(phase_)
397  ).K()
398  );
399 
400  // Eq. 3.25, p. 50 Js = J1 - J2
401  volScalarField J1("J1", 3.0*beta);
402  volScalarField J2
403  (
404  "J2",
405  0.25*sqr(beta)*da*magSqr(U - Uc_)
406  /(
407  max(alpha, residualAlpha_)*rho
408  *sqrtPi*(ThetaSqrt + ThetaSmallSqrt)
409  )
410  );
411 
412  // particle pressure - coefficient in front of Theta (Eq. 3.22, p. 45)
413  volScalarField PsCoeff
414  (
415  granularPressureModel_->granularPressureCoeff
416  (
417  alpha,
418  gs0_,
419  rho,
420  e_
421  )
422  );
423 
424  // 'thermal' conductivity (Table 3.3, p. 49)
425  kappa_ = conductivityModel_->kappa(alpha, Theta_, gs0_, rho, da, e_);
426 
427  fv::options& fvOptions(fv::options::New(mesh_));
428 
429  // Construct the granular temperature equation (Eq. 3.20, p. 44)
430  // NB. note that there are two typos in Eq. 3.20:
431  // Ps should be without grad
432  // the laplacian has the wrong sign
433  fvScalarMatrix ThetaEqn
434  (
435  1.5*
436  (
437  fvm::ddt(alpha, rho, Theta_)
438  + fvm::div(alphaRhoPhi, Theta_)
439  - fvc::Sp(fvc::ddt(alpha, rho) + fvc::div(alphaRhoPhi), Theta_)
440  )
441  - fvm::laplacian(kappa_, Theta_, "laplacian(kappa,Theta)")
442  ==
443  - fvm::SuSp((PsCoeff*I) && gradU, Theta_)
444  + (tau && gradU)
445  + fvm::Sp(-gammaCoeff, Theta_)
446  + fvm::Sp(-J1, Theta_)
447  + fvm::Sp(J2/(Theta_ + ThetaSmall), Theta_)
448  + fvOptions(alpha, rho, Theta_)
449  );
450 
451  ThetaEqn.relax();
452  fvOptions.constrain(ThetaEqn);
453  ThetaEqn.solve();
454  fvOptions.correct(Theta_);
455  }
456  else
457  {
458  // Equilibrium => dissipation == production
459  // Eq. 4.14, p.82
460  volScalarField K1("K1", 2.0*(1.0 + e_)*rho*gs0_);
462  (
463  "K3",
464  0.5*da*rho*
465  (
466  (sqrtPi/(3.0*(3.0 - e_)))
467  *(1.0 + 0.4*(1.0 + e_)*(3.0*e_ - 1.0)*alpha*gs0_)
468  +1.6*alpha*gs0_*(1.0 + e_)/sqrtPi
469  )
470  );
471 
473  (
474  "K2",
475  4.0*da*rho*(1.0 + e_)*alpha*gs0_/(3.0*sqrtPi) - 2.0*K3/3.0
476  );
477 
478  volScalarField K4("K4", 12.0*(1.0 - sqr(e_))*rho*gs0_/(da*sqrtPi));
479 
480  volScalarField trD
481  (
482  "trD",
483  alpha/(alpha + residualAlpha_)
484  *fvc::div(phi_)
485  );
486  volScalarField tr2D("tr2D", sqr(trD));
487  volScalarField trD2("trD2", tr(D & D));
488 
489  volScalarField t1("t1", K1*alpha + rho);
490  volScalarField l1("l1", -t1*trD);
491  volScalarField l2("l2", sqr(t1)*tr2D);
492  volScalarField l3
493  (
494  "l3",
495  4.0
496  *K4
497  *alpha
498  *(2.0*K3*trD2 + K2*tr2D)
499  );
500 
501  Theta_ = sqr
502  (
503  (l1 + sqrt(l2 + l3))
504  /(2.0*max(alpha, residualAlpha_)*K4)
505  );
506 
507  kappa_ = conductivityModel_->kappa(alpha, Theta_, gs0_, rho, da, e_);
508  }
509 
510  Theta_.max(0);
511  Theta_.min(100);
512 
513  {
514  // particle viscosity (Table 3.2, p.47)
515  nut_ = viscosityModel_->nu(alpha, Theta_, gs0_, rho, da, e_);
516 
517  volScalarField ThetaSqrt("sqrtTheta", sqrt(Theta_));
518 
519  // Bulk viscosity p. 45 (Lun et al. 1984).
520  lambda_ = (4.0/3.0)*sqr(alpha)*da*gs0_*(1.0 + e_)*ThetaSqrt/sqrtPi;
521 
522  // Frictional pressure
523  volScalarField pf
524  (
525  frictionalStressModel_->frictionalPressure
526  (
527  phase_,
528  alphaMinFriction_,
529  alphaMax_
530  )
531  );
532 
533  nuFric_ = frictionalStressModel_->nu
534  (
535  phase_,
536  alphaMinFriction_,
537  alphaMax_,
538  pf/rho,
539  D
540  );
541 
542  // Limit viscosity and add frictional viscosity
543  nut_.min(maxNut_);
544  nuFric_ = min(nuFric_, maxNut_ - nut_);
545  nut_ += nuFric_;
546  }
547 
548  if (debug)
549  {
550  Info<< typeName << ':' << nl
551  << " max(Theta) = " << max(Theta_).value() << nl
552  << " max(nut) = " << max(nut_).value() << endl;
553  }
554 }
555 
556 
557 // ************************************************************************* //
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
Definition: volFieldsFwd.H:58
tmp< GeometricField< typename outerProduct< vector, Type >::type, fvPatchField, volMesh >> grad(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcGrad.C:52
fvMatrix< scalar > fvScalarMatrix
Definition: fvMatricesFwd.H:42
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
virtual tmp< volScalarField > epsilon() const
Return the turbulence kinetic energy dissipation rate.
ThermalDiffusivity< PhaseCompressibleTurbulenceModel< phaseModel > > phaseCompressibleTurbulenceModel
Typedef for phaseCompressibleTurbulenceModel.
tmp< fvMatrix< Type > > SuSp(const volScalarField::Internal &, const GeometricField< Type, fvPatchField, volMesh > &)
fv::options & fvOptions
#define K1
Definition: SHA1.C:167
#define K4
Definition: SHA1.C:170
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define K2
Definition: SHA1.C:168
virtual tmp< surfaceScalarField > pPrimef() const
Return the face-phase-pressure&#39;.
GeometricField< tensor, fvPatchField, volMesh > volTensorField
Definition: volFieldsFwd.H:59
dimensionedSymmTensor sqr(const dimensionedVector &dv)
tmp< GeometricField< Type, fvPatchField, volMesh > > div(const GeometricField< Type, fvsPatchField, surfaceMesh > &ssf)
Definition: fvcDiv.C:47
kineticTheoryModel(const volScalarField &alpha, const volScalarField &rho, const volVectorField &U, const surfaceScalarField &alphaRhoPhi, const surfaceScalarField &phi, const phaseModel &transport, const word &propertiesName=turbulenceModel::propertiesName, const word &type=typeName)
Construct from components.
#define K3
Definition: SHA1.C:169
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
tmp< GeometricField< Type, fvPatchField, volMesh > > Sp(const volScalarField &sp, const GeometricField< Type, fvPatchField, volMesh > &vf)
Definition: fvcSup.C:67
tmp< fvMatrix< Type > > Sp(const volScalarField::Internal &, const GeometricField< Type, fvPatchField, volMesh > &)
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:55
CGAL::Exact_predicates_exact_constructions_kernel K
dimensionedSymmTensor twoSymm(const dimensionedSymmTensor &dt)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
static tmp< GeometricField< symmTensor, fvPatchField, volMesh > > New(const word &name, const Mesh &, const dimensionSet &, const word &patchFieldType=fvPatchField< symmTensor >::calculatedType())
Return a temporary field constructed from name, mesh, dimensionSet.
tmp< GeometricField< Type, fvPatchField, volMesh > > ddt(const dimensioned< Type > dt, const fvMesh &mesh)
Definition: fvcDdt.C:45
virtual tmp< volSymmTensorField > R() const
Return the Reynolds stress tensor.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:52
stressControl lookup("compactNormalStress") >> compactNormalStress
dynamicFvMesh & mesh
dimensionedSymmTensor dev(const dimensionedSymmTensor &dt)
static const SymmTensor I
Definition: SymmTensor.H:72
virtual tmp< volSymmTensorField > devRhoReff() const
Return the effective stress tensor.
static word groupName(Name name, const word &group)
tmp< fvMatrix< Type > > ddt(const GeometricField< Type, fvPatchField, volMesh > &vf)
Definition: fvmDdt.C:46
virtual void correct()
Solve the kinetic theory equations and correct the viscosity.
word timeName
Definition: getTimeIndex.H:3
void min(const dimensioned< Type > &)
dimensionedScalar tr(const dimensionedSphericalTensor &dt)
dimensioned< scalar > magSqr(const dimensioned< Type > &)
virtual ~kineticTheoryModel()
Destructor.
static const char nl
Definition: Ostream.H:265
tmp< fvMatrix< Type > > div(const surfaceScalarField &flux, const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmDiv.C:46
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
RASModel< EddyDiffusivity< turbulenceModel > > RASModel
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
virtual tmp< fvVectorMatrix > divDevRhoReff(volVectorField &U) const
Return the source term for the momentum equation.
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Internal & ref()
Return a reference to the dimensioned internal field.
label patchi
dimensionedSymmTensor dev2(const dimensionedSymmTensor &dt)
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:47
dimensionedSymmTensor symm(const dimensionedSymmTensor &dt)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
tmp< fvMatrix< Type > > laplacian(const GeometricField< Type, fvPatchField, volMesh > &vf, const word &name)
Definition: fvmLaplacian.C:46
virtual tmp< volScalarField > pPrime() const
Return the phase-pressure&#39;.
virtual bool read()
Re-read model coefficients if they have changed.
messageStream Info
virtual tmp< volScalarField > k() const
Return the turbulence kinetic energy.
volScalarField alpha(IOobject("alpha", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE), lambda *max(Ua &U, zeroSensitivity))
A class for managing temporary objects.
Definition: PtrList.H:53
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
static options & New(const fvMesh &mesh)
Construct fvOptions and register to datbase if not present.
Definition: fvOptions.C:101
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:366