1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "LarsenBorgnakkeVariableHardSphere.H"
27 #include "constants.H"
29 using namespace Foam::constant::mathematical;
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 template <class CloudType>
34 Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::energyRatio
40 CloudType& cloud(this->owner());
42 Random& rndGen(cloud.rndGen());
44 scalar ChiAMinusOne = ChiA - 1;
46 scalar ChiBMinusOne = ChiB - 1;
48 if (ChiAMinusOne < SMALL && ChiBMinusOne < SMALL)
50 return rndGen.scalar01();
61 energyRatio = rndGen.scalar01();
63 if (ChiAMinusOne < SMALL)
65 P = 1.0 - pow(energyRatio, ChiB);
67 else if (ChiBMinusOne < SMALL)
69 P = 1.0 - pow(energyRatio, ChiA);
76 (ChiAMinusOne + ChiBMinusOne)*energyRatio/ChiAMinusOne,
81 (ChiAMinusOne + ChiBMinusOne)*(1 - energyRatio)
86 } while (P < rndGen.scalar01());
92 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
94 template <class CloudType>
95 Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::
96 LarsenBorgnakkeVariableHardSphere
98 const dictionary& dict,
102 BinaryCollisionModel<CloudType>(dict, cloud, typeName),
103 Tref_(readScalar(this->coeffDict().lookup("Tref"))),
104 relaxationCollisionNumber_
106 readScalar(this->coeffDict().lookup("relaxationCollisionNumber"))
111 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
113 template <class CloudType>
114 Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::
115 ~LarsenBorgnakkeVariableHardSphere()
119 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
121 template<class CloudType>
122 bool Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::active() const
128 template <class CloudType>
129 Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::sigmaTcR
131 const typename CloudType::parcelType& pP,
132 const typename CloudType::parcelType& pQ
135 const CloudType& cloud(this->owner());
137 label typeIdP = pP.typeId();
138 label typeIdQ = pQ.typeId();
143 cloud.constProps(typeIdP).d()
144 + cloud.constProps(typeIdQ).d()
150 cloud.constProps(typeIdP).omega()
151 + cloud.constProps(typeIdQ).omega()
154 scalar cR = mag(pP.U() - pQ.U());
161 scalar mP = cloud.constProps(typeIdP).mass();
163 scalar mQ = cloud.constProps(typeIdQ).mass();
165 scalar mR = mP*mQ/(mP + mQ);
167 // calculating cross section = pi*dPQ^2, where dPQ is from Bird, eq. 4.79
170 *pow(2.0*physicoChemical::k.value()*Tref_/(mR*cR*cR), omegaPQ - 0.5)
171 /exp(Foam::lgamma(2.5 - omegaPQ));
177 template <class CloudType>
178 void Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::collide
180 typename CloudType::parcelType& pP,
181 typename CloudType::parcelType& pQ
184 CloudType& cloud(this->owner());
186 label typeIdP = pP.typeId();
187 label typeIdQ = pQ.typeId();
190 scalar& EiP = pP.Ei();
191 scalar& EiQ = pQ.Ei();
193 Random& rndGen(cloud.rndGen());
195 scalar inverseCollisionNumber = 1/relaxationCollisionNumber_;
197 // Larsen Borgnakke internal energy redistribution part. Using the serial
198 // application of the LB method, as per the INELRS subroutine in Bird's
201 scalar preCollisionEiP = EiP;
203 scalar preCollisionEiQ = EiQ;
205 scalar iDofP = cloud.constProps(typeIdP).internalDegreesOfFreedom();
207 scalar iDofQ = cloud.constProps(typeIdQ).internalDegreesOfFreedom();
212 cloud.constProps(typeIdP).omega()
213 + cloud.constProps(typeIdQ).omega()
216 scalar mP = cloud.constProps(typeIdP).mass();
218 scalar mQ = cloud.constProps(typeIdQ).mass();
220 scalar mR = mP*mQ/(mP + mQ);
222 vector Ucm = (mP*UP + mQ*UQ)/(mP + mQ);
224 scalar cRsqr = magSqr(UP - UQ);
226 scalar availableEnergy = 0.5*mR*cRsqr;
228 scalar ChiB = 2.5 - omegaPQ;
232 if (inverseCollisionNumber > rndGen.scalar01())
234 availableEnergy += preCollisionEiP;
236 scalar ChiA = 0.5*iDofP;
238 EiP = energyRatio(ChiA, ChiB)*availableEnergy;
240 availableEnergy -= EiP;
246 if (inverseCollisionNumber > rndGen.scalar01())
248 availableEnergy += preCollisionEiQ;
250 // Change to general LB ratio calculation
251 scalar energyRatio = 1.0 - pow(rndGen.scalar01(),(1.0/ChiB));
253 EiQ = energyRatio*availableEnergy;
255 availableEnergy -= EiQ;
259 // Rescale the translational energy
260 scalar cR = sqrt(2.0*availableEnergy/mR);
262 // Variable Hard Sphere collision part
264 scalar cosTheta = 2.0*rndGen.scalar01() - 1.0;
266 scalar sinTheta = sqrt(1.0 - cosTheta*cosTheta);
268 scalar phi = twoPi*rndGen.scalar01();
270 vector postCollisionRelU =
279 UP = Ucm + postCollisionRelU*mQ/(mP + mQ);
281 UQ = Ucm - postCollisionRelU*mP/(mP + mQ);
285 // ************************************************************************* //