Stochastic.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2013-2017 OpenFOAM Foundation
9 Copyright (C) 2019 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "Stochastic.H"
30
31// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32
33template<class CloudType>
35(
36 const dictionary& dict,
37 CloudType& owner
38)
39:
40 IsotropyModel<CloudType>(dict, owner, typeName)
41{}
42
43
44template<class CloudType>
46(
47 const Stochastic<CloudType>& cm
48)
49:
51{}
52
53
54// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
55
56template<class CloudType>
58{}
59
60
61// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
62
63template<class CloudType>
65{
66 static bool isCached = true;
67 static scalar xCached;
68
69 if (isCached)
70 {
71 isCached = false;
72
73 return xCached;
74 }
75 else
76 {
77 Random& rndGen = this->owner().rndGen();
78
79 scalar f, m, x, y;
80
81 do
82 {
83 x = 2.0*rndGen.sample01<scalar>() - 1.0;
84 y = 2.0*rndGen.sample01<scalar>() - 1.0;
85 m = x*x + y*y;
86 } while (m >= 1.0 || m == 0.0);
87
88 f = sqrt(-2.0*log(m)/m);
89 xCached = x*f;
90 isCached = true;
91
92 return y*f;
93 }
94}
95
96
97// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
98
99template<class CloudType>
101{
102 const fvMesh& mesh = this->owner().mesh();
103 const scalar deltaT(this->owner().db().time().deltaTValue());
104 Random& rndGen = this->owner().rndGen();
105
106 const scalar oneBySqrtThree = sqrt(1.0/3.0);
107
108 const AveragingMethod<scalar>& volumeAverage =
109 mesh.lookupObject<AveragingMethod<scalar>>
110 (
111 this->owner().name() + ":volumeAverage"
112 );
113 const AveragingMethod<scalar>& radiusAverage =
114 mesh.lookupObject<AveragingMethod<scalar>>
115 (
116 this->owner().name() + ":radiusAverage"
117 );
118 const AveragingMethod<vector>& uAverage =
119 mesh.lookupObject<AveragingMethod<vector>>
120 (
121 this->owner().name() + ":uAverage"
122 );
123 const AveragingMethod<scalar>& uSqrAverage =
124 mesh.lookupObject<AveragingMethod<scalar>>
125 (
126 this->owner().name() + ":uSqrAverage"
127 );
128 const AveragingMethod<scalar>& frequencyAverage =
129 mesh.lookupObject<AveragingMethod<scalar>>
130 (
131 this->owner().name() + ":frequencyAverage"
132 );
133 const AveragingMethod<scalar>& massAverage =
134 mesh.lookupObject<AveragingMethod<scalar>>
135 (
136 this->owner().name() + ":massAverage"
137 );
138
139 // calculate time scales and pdf exponent
140 autoPtr<AveragingMethod<scalar>> exponentAveragePtr
141 (
143 (
145 (
146 this->owner().name() + ":exponentAverage",
147 this->owner().db().time().timeName(),
148 mesh
149 ),
150 this->owner().solution().dict(),
151 mesh
152 )
153 );
154 AveragingMethod<scalar>& exponentAverage = exponentAveragePtr();
155 exponentAverage =
156 exp
157 (
158 - deltaT
159 *this->timeScaleModel_->oneByTau
160 (
161 volumeAverage,
162 radiusAverage,
163 uSqrAverage,
164 frequencyAverage
165 )
166 )();
167
168 // random sampling
169 for (typename CloudType::parcelType& p : this->owner())
170 {
171 const tetIndices tetIs(p.currentTetIndices());
172
173 const scalar x = exponentAverage.interpolate(p.coordinates(), tetIs);
174
175 if (x < rndGen.sample01<scalar>())
176 {
177 const vector r(sampleGauss(), sampleGauss(), sampleGauss());
178
179 const vector u = uAverage.interpolate(p.coordinates(), tetIs);
180 const scalar uRms =
181 sqrt(max(uSqrAverage.interpolate(p.coordinates(), tetIs), 0.0));
182
183 p.U() = u + r*uRms*oneBySqrtThree;
184 }
185 }
186
187 // correction velocity averages
188 autoPtr<AveragingMethod<vector>> uTildeAveragePtr
189 (
191 (
193 (
194 this->owner().name() + ":uTildeAverage",
195 this->owner().db().time().timeName(),
196 mesh
197 ),
198 this->owner().solution().dict(),
199 mesh
200 )
201 );
202 AveragingMethod<vector>& uTildeAverage = uTildeAveragePtr();
203 for (typename CloudType::parcelType& p : this->owner())
204 {
205 const tetIndices tetIs(p.currentTetIndices());
206 uTildeAverage.add(p.coordinates(), tetIs, p.nParticle()*p.mass()*p.U());
207 }
208 uTildeAverage.average(massAverage);
209
210 autoPtr<AveragingMethod<scalar>> uTildeSqrAveragePtr
211 (
213 (
215 (
216 this->owner().name() + ":uTildeSqrAverage",
217 this->owner().db().time().timeName(),
218 mesh
219 ),
220 this->owner().solution().dict(),
221 mesh
222 )
223 );
224 AveragingMethod<scalar>& uTildeSqrAverage = uTildeSqrAveragePtr();
225 for (typename CloudType::parcelType& p : this->owner())
226 {
227 const tetIndices tetIs(p.currentTetIndices());
228 const vector uTilde = uTildeAverage.interpolate(p.coordinates(), tetIs);
229 uTildeSqrAverage.add
230 (
231 p.coordinates(),
232 tetIs,
233 p.nParticle()*p.mass()*magSqr(p.U() - uTilde)
234 );
235 }
236 uTildeSqrAverage.average(massAverage);
237
238 // conservation correction
239 for (typename CloudType::parcelType& p : this->owner())
240 {
241 const tetIndices tetIs(p.currentTetIndices());
242
243 const vector u = uAverage.interpolate(p.coordinates(), tetIs);
244 const scalar uRms =
245 sqrt(max(uSqrAverage.interpolate(p.coordinates(), tetIs), 0.0));
246
247 const vector uTilde = uTildeAverage.interpolate(p.coordinates(), tetIs);
248 const scalar uTildeRms =
249 sqrt
250 (
251 max(uTildeSqrAverage.interpolate(p.coordinates(), tetIs), 0.0)
252 );
253
254 p.U() = u + (p.U() - uTilde)*uRms/max(uTildeRms, SMALL);
255 }
256}
257
258
259// ************************************************************************* //
scalar y
Base class for lagrangian averaging methods.
virtual void add(const barycentric &coordinates, const tetIndices &tetIs, const Type &value)=0
Member Functions.
virtual void average()
Calculate the average.
virtual Type interpolate(const barycentric &coordinates, const tetIndices &tetIs) const =0
Interpolate.
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:75
ParcelType parcelType
Type of parcel the cloud was instantiated for.
Definition: DSMCCloud.H:220
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
Base class for collisional return-to-isotropy models.
Definition: IsotropyModel.H:66
Stochastic return-to-isotropy model.
Definition: Stochastic.H:75
virtual ~Stochastic()
Destructor.
Definition: Stochastic.C:57
virtual void calculate()
Member Functions.
Definition: Stochastic.C:100
Random number generator.
Definition: Random.H:60
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
Selector class for relaxation factors, solver type and solution.
Definition: solution.H:66
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
Definition: tetIndices.H:84
volScalarField & p
dynamicFvMesh & mesh
word timeName
Definition: getTimeIndex.H:3
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedScalar log(const dimensionedScalar &ds)
dimensionedScalar sqrt(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
labelList f(nPoints)
dictionary dict
Random rndGen
Definition: createFields.H:23