Loading...
Searching...
No Matches
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-2023 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,
39:
41{}
42
43
44template<class CloudType>
46(
47 const Stochastic<CloudType>& cm
48)
49:
52
53
54// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
55
56template<class CloudType>
58{}
59
60
61// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
62
63template<class CloudType>
64Foam::scalar Foam::IsotropyModels::Stochastic<CloudType>::sampleGauss()
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 auto& volumeAverage =
109 mesh.lookupObject<AveragingMethod<scalar>>
110 (
111 IOobject::scopedName(this->owner().name(), "volumeAverage")
112 );
113 const auto& radiusAverage =
114 mesh.lookupObject<AveragingMethod<scalar>>
115 (
116 IOobject::scopedName(this->owner().name(), "radiusAverage")
117 );
118 const auto& uAverage =
119 mesh.lookupObject<AveragingMethod<vector>>
120 (
121 IOobject::scopedName(this->owner().name(), "uAverage")
122 );
123 const auto& uSqrAverage =
124 mesh.lookupObject<AveragingMethod<scalar>>
125 (
126 IOobject::scopedName(this->owner().name(), "uSqrAverage")
127 );
128 const auto& frequencyAverage =
129 mesh.lookupObject<AveragingMethod<scalar>>
130 (
131 IOobject::scopedName(this->owner().name(), "frequencyAverage")
132 );
133 const auto& massAverage =
134 mesh.lookupObject<AveragingMethod<scalar>>
135 (
136 IOobject::scopedName(this->owner().name(), "massAverage")
137 );
138
139 // calculate time scales and pdf exponent
140 autoPtr<AveragingMethod<scalar>> exponentAveragePtr
141 (
143 (
145 (
146 IOobject::scopedName(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 (
192 IOobject
193 (
194 IOobject::scopedName(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 (
214 IOobject
215 (
216 IOobject::scopedName(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.
static autoPtr< AveragingMethod< Type > > New(const IOobject &io, const dictionary &dict, const fvMesh &mesh)
Selector.
virtual void average()
Calculate the average.
virtual Type interpolate(const barycentric &coordinates, const tetIndices &tetIs) const =0
Interpolate.
const CloudType & owner() const
Return const access to the owner cloud.
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
static word scopedName(const std::string &scope, const word &name)
Create scope:name or scope_name string.
Definition IOobjectI.H:50
IsotropyModel(CloudType &owner)
Construct null from owner.
autoPtr< TimeScaleModel > timeScaleModel_
Time scale model.
Stochastic return-to-isotropy model.
Definition Stochastic.H:71
virtual ~Stochastic()
Destructor.
Definition Stochastic.C:50
Stochastic(const dictionary &dict, CloudType &owner)
Construct from components.
Definition Stochastic.C:28
virtual void calculate()
Member Functions.
Definition Stochastic.C:93
Random number generator.
Definition Random.H:56
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
Selector class for relaxation factors, solver type and solution.
Definition solution.H:95
const dictionary & dict() const
Return const access to the cloud dictionary.
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
Definition tetIndices.H:79
volScalarField & p
dynamicFvMesh & mesh
auto & name
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:40
DSMCCloud< dsmcParcel > CloudType
dimensionedScalar exp(const dimensionedScalar &ds)
dimensionedScalar log(const dimensionedScalar &ds)
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
dimensionedScalar sqrt(const dimensionedScalar &ds)
Vector< scalar > vector
Definition vector.H:57
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
labelList f(nPoints)
dictionary dict
Random rndGen