Random.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Random.H"
27 #include "PstreamReduceOps.H"
28 
29 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
30 
32 {
33  // Proper inversion of the distribution. Slow. Exactly maintains
34  // the random behaviour of the generator.
35 
36  /*
37  using namespace constant::mathematical;
38 
39  static const scalar sqrtTwo = sqrt(scalar(2));
40  static const scalar sqrtPiByTwo = sqrt(pi)/2;
41  static const scalar a = 8*(pi - 3)/(3*pi*(4 - pi));
42 
43  const scalar x = 2*scalar01() - 1;
44  const scalar xPos = mag(x);
45 
46  // Initial approximation
47  const scalar l = log(1 - sqr(xPos));
48  const scalar ll = 2/(pi*a) + l/2;
49  scalar y = sqrt(sqrt(sqr(ll) - l/a) - ll);
50 
51  // Newton improvement
52  label n = 0;
53  while (n < 2)
54  {
55  const scalar dt = (erf(y) - xPos)/exp(- y*y)*sqrtPiByTwo;
56  y -= dt;
57  n += mag(dt) < rootSmall;
58  }
59 
60  return sign(x)*sqrtTwo*y;
61  */
62 
63  // Box-Muller transform. Fast. Uses rejection and caching so the
64  // random sequence is not guaranteed.
65 
66  if (scalarNormalStored_)
67  {
68  scalarNormalStored_ = false;
69 
70  return scalarNormalValue_;
71  }
72  else
73  {
74  scalar x1, x2, rr;
75 
76  do
77  {
78  x1 = 2*scalar01() - 1;
79  x2 = 2*scalar01() - 1;
80  rr = sqr(x1) + sqr(x2);
81  }
82  while (rr >= 1 || rr == 0);
83 
84  const scalar f = sqrt(- 2*log(rr)/rr);
85 
86  scalarNormalValue_ = x1*f;
87  scalarNormalStored_ = true;
88 
89  return x2*f;
90  }
91 }
92 
93 
95 {
96  scalar value = - vGreat;
97 
98  if (Pstream::master())
99  {
100  value = scalar01();
101  }
102 
103  Pstream::scatter(value);
104 
105  return value;
106 }
107 
108 
109 // ************************************************************************* //
Inter-processor communication reduction functions.
dimensionedScalar log(const dimensionedScalar &ds)
scalar scalarNormal()
Advance the state and return a scalar sample from a normal.
Definition: Random.C:31
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar sqrt(const dimensionedScalar &ds)
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
scalar globalScalar01()
Advance the state and return a scalar sample from a uniform.
Definition: Random.C:94
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
labelList f(nPoints)
scalar scalar01()
Advance the state and return a scalar sample from a uniform.
Definition: RandomI.H:57