Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / lagrangian / dsmc / submodels / BinaryCollisionModel / LarsenBorgnakkeVariableHardSphere / LarsenBorgnakkeVariableHardSphere.C
blobaac86baf21dd30e3d7b13e904513a6b74e55bf4c
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "LarsenBorgnakkeVariableHardSphere.H"
28 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
30 template <class CloudType>
31 Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::energyRatio
33     scalar ChiA,
34     scalar ChiB
37     CloudType& cloud(this->owner());
39     Random& rndGen(cloud.rndGen());
41     scalar ChiAMinusOne = ChiA - 1;
43     scalar ChiBMinusOne = ChiB - 1;
45     if (ChiAMinusOne < SMALL && ChiBMinusOne < SMALL)
46     {
47         return rndGen.scalar01();
48     }
50     scalar energyRatio;
52     scalar P;
54     do
55     {
56         P = 0;
58         energyRatio = rndGen.scalar01();
60         if (ChiAMinusOne < SMALL)
61         {
62             P = 1.0 - pow(energyRatio, ChiB);
63         }
64         else if (ChiBMinusOne < SMALL)
65         {
66             P = 1.0 - pow(energyRatio, ChiA);
67         }
68         else
69         {
70             P =
71                 pow
72                 (
73                     (ChiAMinusOne + ChiBMinusOne)*energyRatio/ChiAMinusOne,
74                     ChiAMinusOne
75                 )
76                *pow
77                 (
78                     (ChiAMinusOne + ChiBMinusOne)*(1 - energyRatio)
79                     /ChiBMinusOne,
80                     ChiBMinusOne
81                 );
82         }
83     } while (P < rndGen.scalar01());
85     return energyRatio;
89 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
91 template <class CloudType>
92 Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::LarsenBorgnakkeVariableHardSphere
94     const dictionary& dict,
95     CloudType& cloud
98     BinaryCollisionModel<CloudType>(dict, cloud, typeName),
99     Tref_(readScalar(this->coeffDict().lookup("Tref"))),
100     relaxationCollisionNumber_
101     (
102         readScalar(this->coeffDict().lookup("relaxationCollisionNumber"))
103     )
107 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
109 template <class CloudType>
110 Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::
111 ~LarsenBorgnakkeVariableHardSphere()
115 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
118 template <class CloudType>
119 Foam::scalar Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::sigmaTcR
121     label typeIdP,
122     label typeIdQ,
123     const vector& UP,
124     const vector& UQ
125 ) const
127     const CloudType& cloud(this->owner());
129     scalar dPQ =
130         0.5
131        *(
132             cloud.constProps(typeIdP).d()
133           + cloud.constProps(typeIdQ).d()
134         );
136     scalar omegaPQ =
137         0.5
138        *(
139             cloud.constProps(typeIdP).omega()
140           + cloud.constProps(typeIdQ).omega()
141         );
143     scalar cR = mag(UP - UQ);
145     if (cR < VSMALL)
146     {
147         return 0;
148     }
150     scalar mP = cloud.constProps(typeIdP).mass();
152     scalar mQ = cloud.constProps(typeIdQ).mass();
154     scalar mR = mP*mQ/(mP + mQ);
156     // calculating cross section = pi*dPQ^2, where dPQ is from Bird, eq. 4.79
157     scalar sigmaTPQ =
158         mathematicalConstant::pi*dPQ*dPQ
159        *pow(2.0*CloudType::kb*Tref_/(mR*cR*cR), omegaPQ - 0.5)
160        /exp(Foam::lgamma(2.5 - omegaPQ));
162     return sigmaTPQ*cR;
166 template <class CloudType>
167 void Foam::LarsenBorgnakkeVariableHardSphere<CloudType>::collide
169     label typeIdP,
170     label typeIdQ,
171     vector& UP,
172     vector& UQ,
173     scalar& EiP,
174     scalar& EiQ
177     CloudType& cloud(this->owner());
179     Random& rndGen(cloud.rndGen());
181     scalar inverseCollisionNumber = 1/relaxationCollisionNumber_;
183     // Larsen Borgnakke internal energy redistribution part.  Using the serial
184     // application of the LB method, as per the INELRS subroutine in Bird's
185     // DSMC0R.FOR
187     scalar preCollisionEiP = EiP;
189     scalar preCollisionEiQ = EiQ;
191     scalar iDofP = cloud.constProps(typeIdP).internalDegreesOfFreedom();
193     scalar iDofQ = cloud.constProps(typeIdQ).internalDegreesOfFreedom();
195     scalar omegaPQ =
196         0.5
197        *(
198             cloud.constProps(typeIdP).omega()
199           + cloud.constProps(typeIdQ).omega()
200         );
202     scalar mP = cloud.constProps(typeIdP).mass();
204     scalar mQ = cloud.constProps(typeIdQ).mass();
206     scalar mR = mP*mQ/(mP + mQ);
208     vector Ucm = (mP*UP + mQ*UQ)/(mP + mQ);
210     scalar cRsqr = magSqr(UP - UQ);
212     scalar availableEnergy = 0.5*mR*cRsqr;
214     scalar ChiB = 2.5 - omegaPQ;
216     if (iDofP > 0)
217     {
218         if (inverseCollisionNumber > rndGen.scalar01())
219         {
220             availableEnergy += preCollisionEiP;
222             scalar ChiA = 0.5*iDofP;
224             EiP = energyRatio(ChiA, ChiB)*availableEnergy;
226             availableEnergy -= EiP;
227         }
228     }
230     if (iDofQ > 0)
231     {
232         if (inverseCollisionNumber > rndGen.scalar01())
233         {
234             availableEnergy += preCollisionEiQ;
236             // Change to general LB ratio calculation
237             scalar energyRatio = 1.0 - pow(rndGen.scalar01(),(1.0/ChiB));
239             EiQ = energyRatio*availableEnergy;
241             availableEnergy -= EiQ;
242         }
243     }
245     // Rescale the translational energy
246     scalar cR = sqrt(2.0*availableEnergy/mR);
248     // Variable Hard Sphere collision part
250     scalar cosTheta = 2.0*rndGen.scalar01() - 1.0;
252     scalar sinTheta = sqrt(1.0 - cosTheta*cosTheta);
254     scalar phi = 2.0*mathematicalConstant::pi*rndGen.scalar01();
256     vector postCollisionRelU =
257         cR
258        *vector
259         (
260             cosTheta,
261             sinTheta*cos(phi),
262             sinTheta*sin(phi)
263         );
265     UP = Ucm + postCollisionRelU*mQ/(mP + mQ);
267     UQ = Ucm - postCollisionRelU*mP/(mP + mQ);
271 // ************************************************************************* //