FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

kineticTheoryModel.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "kineticTheoryModel.H"
00027 #include <finiteVolume/surfaceInterpolate.H>
00028 #include <OpenFOAM/mathematicalConstants.H>
00029 #include <finiteVolume/fvCFD.H>
00030 
00031 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00032 
00033 Foam::kineticTheoryModel::kineticTheoryModel
00034 (
00035     const Foam::phaseModel& phasea,
00036     const Foam::volVectorField& Ub,
00037     const Foam::volScalarField& alpha,
00038     const Foam::dragModel& draga
00039 )
00040 :
00041     phasea_(phasea),
00042     Ua_(phasea.U()),
00043     Ub_(Ub),
00044     alpha_(alpha),
00045     phia_(phasea.phi()),
00046     draga_(draga),
00047 
00048     rhoa_(phasea.rho()),
00049     da_(phasea.d()),
00050     nua_(phasea.nu()),
00051 
00052     kineticTheoryProperties_
00053     (
00054         IOobject
00055         (
00056             "kineticTheoryProperties",
00057             Ua_.time().constant(),
00058             Ua_.mesh(),
00059             IOobject::MUST_READ,
00060             IOobject::NO_WRITE
00061         )
00062     ),
00063     kineticTheory_(kineticTheoryProperties_.lookup("kineticTheory")),
00064     equilibrium_(kineticTheoryProperties_.lookup("equilibrium")),
00065 
00066     viscosityModel_
00067     (
00068         kineticTheoryModels::viscosityModel::New
00069         (
00070             kineticTheoryProperties_
00071         )
00072     ),
00073     conductivityModel_
00074     (
00075         conductivityModel::New
00076         (
00077             kineticTheoryProperties_
00078         )
00079     ),
00080     radialModel_
00081     (
00082         radialModel::New
00083         (
00084             kineticTheoryProperties_
00085         )
00086     ),
00087     granularPressureModel_
00088     (
00089         granularPressureModel::New
00090         (
00091             kineticTheoryProperties_
00092         )
00093     ),
00094     frictionalStressModel_
00095     (
00096         frictionalStressModel::New
00097         (
00098             kineticTheoryProperties_
00099         )
00100     ),
00101     e_(kineticTheoryProperties_.lookup("e")),
00102     alphaMax_(kineticTheoryProperties_.lookup("alphaMax")),
00103     alphaMinFriction_(kineticTheoryProperties_.lookup("alphaMinFriction")),
00104     Fr_(kineticTheoryProperties_.lookup("Fr")),
00105     eta_(kineticTheoryProperties_.lookup("eta")),
00106     p_(kineticTheoryProperties_.lookup("p")),
00107     phi_(dimensionedScalar(kineticTheoryProperties_.lookup("phi"))*M_PI/180.0),
00108     Theta_
00109     (
00110         IOobject
00111         (
00112             "Theta",
00113             Ua_.time().timeName(),
00114             Ua_.mesh(),
00115             IOobject::MUST_READ,
00116             IOobject::AUTO_WRITE
00117         ),
00118         Ua_.mesh()
00119     ),
00120     mua_
00121     (
00122         IOobject
00123         (
00124             "mua",
00125             Ua_.time().timeName(),
00126             Ua_.mesh(),
00127             IOobject::NO_READ,
00128             IOobject::AUTO_WRITE
00129         ),
00130         Ua_.mesh(),
00131         dimensionedScalar("zero", dimensionSet(1, -1, -1, 0, 0), 0.0)
00132     ),
00133     lambda_
00134     (
00135         IOobject
00136         (
00137             "lambda",
00138             Ua_.time().timeName(),
00139             Ua_.mesh(),
00140             IOobject::NO_READ,
00141             IOobject::NO_WRITE
00142         ),
00143         Ua_.mesh(),
00144         dimensionedScalar("zero", dimensionSet(1, -1, -1, 0, 0), 0.0)
00145     ),
00146     pa_
00147     (
00148         IOobject
00149         (
00150             "pa",
00151             Ua_.time().timeName(),
00152             Ua_.mesh(),
00153             IOobject::NO_READ,
00154             IOobject::AUTO_WRITE
00155         ),
00156         Ua_.mesh(),
00157         dimensionedScalar("zero", dimensionSet(1, -1, -2, 0, 0), 0.0)
00158     ),
00159     kappa_
00160     (
00161         IOobject
00162         (
00163             "kappa",
00164             Ua_.time().timeName(),
00165             Ua_.mesh(),
00166             IOobject::NO_READ,
00167             IOobject::NO_WRITE
00168         ),
00169         Ua_.mesh(),
00170         dimensionedScalar("zero", dimensionSet(1, -1, -1, 0, 0), 0.0)
00171     ),
00172     gs0_
00173     (
00174         IOobject
00175         (
00176             "gs0",
00177             Ua_.time().timeName(),
00178             Ua_.mesh(),
00179             IOobject::NO_READ,
00180             IOobject::NO_WRITE
00181         ),
00182         Ua_.mesh(),
00183         dimensionedScalar("zero", dimensionSet(0, 0, 0, 0, 0), 1.0)
00184     )
00185 {}
00186 
00187 
00188 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00189 
00190 Foam::kineticTheoryModel::~kineticTheoryModel()
00191 {}
00192 
00193 
00194 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00195 
00196 void Foam::kineticTheoryModel::solve(const volTensorField& gradUat)
00197 {
00198     if (!kineticTheory_)
00199     {
00200         return;
00201     }
00202 
00203     const scalar sqrtPi = sqrt(mathematicalConstant::pi);
00204 
00205     surfaceScalarField phi = 1.5*rhoa_*phia_*fvc::interpolate(alpha_);
00206 
00207     volTensorField dU = gradUat.T();//fvc::grad(Ua_);
00208     volSymmTensorField D = symm(dU);
00209 
00210     // NB, drag = K*alpha*beta,
00211     // (the alpha and beta has been extracted from the drag function for
00212     // numerical reasons)
00213     volScalarField Ur = mag(Ua_ - Ub_);
00214     volScalarField betaPrim = alpha_*(1.0 - alpha_)*draga_.K(Ur);
00215 
00216     // Calculating the radial distribution function (solid volume fraction is
00217     //  limited close to the packing limit, but this needs improvements)
00218     //  The solution is higly unstable close to the packing limit.
00219     gs0_ = radialModel_->g0
00220     (
00221         min(max(alpha_, scalar(1e-6)), alphaMax_ - 0.01),
00222         alphaMax_
00223     );
00224 
00225     // particle pressure - coefficient in front of Theta (Eq. 3.22, p. 45)
00226     volScalarField PsCoeff = granularPressureModel_->granularPressureCoeff
00227     (
00228         alpha_,
00229         gs0_,
00230         rhoa_,
00231         e_
00232     );
00233 
00234     // 'thermal' conductivity (Table 3.3, p. 49)
00235     kappa_ = conductivityModel_->kappa(alpha_, Theta_, gs0_, rhoa_, da_, e_);
00236 
00237     // particle viscosity (Table 3.2, p.47)
00238     mua_ = viscosityModel_->mua(alpha_, Theta_, gs0_, rhoa_, da_, e_);
00239 
00240     dimensionedScalar Tsmall
00241     (
00242         "small",
00243         dimensionSet(0 , 2 ,-2 ,0 , 0, 0, 0),
00244         1.0e-6
00245     );
00246 
00247     dimensionedScalar TsmallSqrt = sqrt(Tsmall);
00248     volScalarField ThetaSqrt = sqrt(Theta_);
00249 
00250     // dissipation (Eq. 3.24, p.50)
00251     volScalarField gammaCoeff =
00252         12.0*(1.0 - sqr(e_))*sqr(alpha_)*rhoa_*gs0_*(1.0/da_)*ThetaSqrt/sqrtPi;
00253 
00254     // Eq. 3.25, p. 50 Js = J1 - J2
00255     volScalarField J1 = 3.0*betaPrim;
00256     volScalarField J2 =
00257         0.25*sqr(betaPrim)*da_*sqr(Ur)
00258        /(max(alpha_, scalar(1e-6))*rhoa_*sqrtPi*(ThetaSqrt + TsmallSqrt));
00259 
00260     // bulk viscosity  p. 45 (Lun et al. 1984).
00261     lambda_ = (4.0/3.0)*sqr(alpha_)*rhoa_*da_*gs0_*(1.0+e_)*ThetaSqrt/sqrtPi;
00262 
00263     // stress tensor, Definitions, Table 3.1, p. 43
00264     volSymmTensorField tau = 2.0*mua_*D + (lambda_ - (2.0/3.0)*mua_)*tr(D)*I;
00265 
00266     if (!equilibrium_)
00267     {
00268         // construct the granular temperature equation (Eq. 3.20, p. 44)
00269         // NB. note that there are two typos in Eq. 3.20
00270         // no grad infront of Ps
00271         // wrong sign infront of laplacian
00272         fvScalarMatrix ThetaEqn
00273         (
00274             fvm::ddt(1.5*alpha_*rhoa_, Theta_)
00275           + fvm::div(phi, Theta_, "div(phi,Theta)")
00276          ==
00277             fvm::SuSp(-((PsCoeff*I) && dU), Theta_)
00278           + (tau && dU)
00279           + fvm::laplacian(kappa_, Theta_, "laplacian(kappa,Theta)")
00280           + fvm::Sp(-gammaCoeff, Theta_)
00281           + fvm::Sp(-J1, Theta_)
00282           + fvm::Sp(J2/(Theta_ + Tsmall), Theta_)
00283         );
00284 
00285         ThetaEqn.relax();
00286         ThetaEqn.solve();
00287     }
00288     else
00289     {
00290         // equilibrium => dissipation == production
00291         // Eq. 4.14, p.82
00292         volScalarField K1 = 2.0*(1.0 + e_)*rhoa_*gs0_;
00293         volScalarField K3 = 0.5*da_*rhoa_*
00294             (
00295                 (sqrtPi/(3.0*(3.0-e_)))
00296                *(1.0 + 0.4*(1.0 + e_)*(3.0*e_ - 1.0)*alpha_*gs0_)
00297                +1.6*alpha_*gs0_*(1.0 + e_)/sqrtPi
00298             );
00299 
00300         volScalarField K2 =
00301             4.0*da_*rhoa_*(1.0 + e_)*alpha_*gs0_/(3.0*sqrtPi) - 2.0*K3/3.0;
00302 
00303         volScalarField K4 = 12.0*(1.0 - sqr(e_))*rhoa_*gs0_/(da_*sqrtPi);
00304 
00305         volScalarField trD = tr(D);
00306         volScalarField tr2D = sqr(trD);
00307         volScalarField trD2 = tr(D & D);
00308 
00309         volScalarField t1 = K1*alpha_ + rhoa_;
00310         volScalarField l1 = -t1*trD;
00311         volScalarField l2 = sqr(t1)*tr2D;
00312         volScalarField l3 = 4.0*K4*max(alpha_, scalar(1e-6))*(2.0*K3*trD2 + K2*tr2D);
00313 
00314         Theta_ = sqr((l1 + sqrt(l2 + l3))/(2.0*(alpha_ + 1.0e-4)*K4));
00315     }
00316 
00317     Theta_.max(1.0e-15);
00318     Theta_.min(1.0e+3);
00319 
00320     volScalarField pf = frictionalStressModel_->frictionalPressure
00321     (
00322         alpha_,
00323         alphaMinFriction_,
00324         alphaMax_,
00325         Fr_,
00326         eta_,
00327         p_
00328     );
00329 
00330     PsCoeff += pf/(Theta_+Tsmall);
00331 
00332     PsCoeff.min(1.0e+10);
00333     PsCoeff.max(-1.0e+10);
00334 
00335     // update particle pressure
00336     pa_ = PsCoeff*Theta_;
00337 
00338     // frictional shear stress, Eq. 3.30, p. 52
00339     volScalarField muf = frictionalStressModel_->muf
00340     (
00341         alpha_,
00342         alphaMax_,
00343         pf,
00344         D,
00345         phi_
00346     );
00347 
00348    // add frictional stress
00349     mua_ += muf;
00350     mua_.min(1.0e+2);
00351     mua_.max(0.0);
00352 
00353     Info<< "kinTheory: max(Theta) = " << max(Theta_).value() << endl;
00354 
00355     volScalarField ktn = mua_/rhoa_;
00356 
00357     Info<< "kinTheory: min(nua) = " << min(ktn).value()
00358         << ", max(nua) = " << max(ktn).value() << endl;
00359 
00360     Info<< "kinTheory: min(pa) = " << min(pa_).value()
00361         << ", max(pa) = " << max(pa_).value() << endl;
00362 }
00363 
00364 
00365 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines