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 -------------------------------------------------------------------------------
11 License
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 
33 template<class CloudType>
35 (
36  const dictionary& dict,
37  CloudType& owner
38 )
39 :
40  IsotropyModel<CloudType>(dict, owner, typeName)
41 {}
42 
43 
44 template<class CloudType>
46 (
47  const Stochastic<CloudType>& cm
48 )
49 :
51 {}
52 
53 
54 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
55 
56 template<class CloudType>
58 {}
59 
60 
61 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
62 
63 template<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 
99 template<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  (
144  IOobject
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  (
192  IOobject
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  (
214  IOobject
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 // ************************************************************************* //
dictionary dict
dimensionedScalar log(const dimensionedScalar &ds)
static autoPtr< AveragingMethod< scalar > > New(const IOobject &io, const dictionary &dict, const fvMesh &mesh)
Selector.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
Stochastic return-to-isotropy model.
Definition: Stochastic.H:68
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Random rndGen
Definition: createFields.H:23
dimensionedScalar sqrt(const dimensionedScalar &ds)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
word timeName
Definition: getTimeIndex.H:3
scalar y
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
dimensionedScalar exp(const dimensionedScalar &ds)
Storage and named access for the indices of a tet which is part of the decomposition of a cell...
Definition: tetIndices.H:78
Stochastic(const dictionary &dict, CloudType &owner)
Construct from components.
Definition: Stochastic.C:28
Vector< scalar > vector
Definition: vector.H:57
Random number generator.
Definition: Random.H:55
ParcelType parcelType
Type of parcel the cloud was instantiated for.
Definition: DSMCCloud.H:290
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
labelList f(nPoints)
Base class for collisional return-to-isotropy models.
virtual ~Stochastic()
Destructor.
Definition: Stochastic.C:50
virtual Type interpolate(const barycentric &coordinates, const tetIndices &tetIs) const =0
Interpolate.
virtual void calculate()
Member Functions.
Definition: Stochastic.C:93
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
Selector class for relaxation factors, solver type and solution.
Definition: solution.H:92
volScalarField & p
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
Templated base class for dsmc cloud.
Definition: DSMCCloud.H:67
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)