Random.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) 2017-2020 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "Random.H"
29#include "PstreamReduceOps.H"
30
31// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32
33Foam::Random::Random(const label seedValue)
34:
35 seed_(seedValue),
36 generator_(seed_),
37 uniform01_(),
38 hasGaussSample_(false),
39 gaussSample_(0)
40{}
41
42
43Foam::Random::Random(const Random& rnd, const bool reset)
44:
45 Random(rnd)
46{
47 if (reset)
48 {
49 hasGaussSample_ = false;
50 gaussSample_ = 0;
51 generator_.seed(seed_);
52 }
53}
54
55
56// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
57
58template<>
60{
61 return scalar01();
62}
63
64
65template<>
66Foam::label Foam::Random::sample01()
67{
68 return round(scalar01());
69}
70
71
72template<>
74{
75 if (hasGaussSample_)
76 {
77 hasGaussSample_ = false;
78 return gaussSample_;
79 }
80
81 // Gaussian random number as per Knuth/Marsaglia.
82 // Input: two uniform random numbers, output: two Gaussian random numbers.
83 // cache one of the values for the next call.
84 scalar rsq, v1, v2;
85 do
86 {
87 v1 = 2*scalar01() - 1;
88 v2 = 2*scalar01() - 1;
89 rsq = sqr(v1) + sqr(v2);
90 } while (rsq >= 1 || rsq == 0);
91
92 const scalar fac = sqrt(-2*log(rsq)/rsq);
93
94 gaussSample_ = v1*fac;
95 hasGaussSample_ = true;
96
97 return v2*fac;
98}
99
100
101template<>
102Foam::label Foam::Random::GaussNormal()
103{
104 return round(GaussNormal<scalar>());
105}
106
107
108template<>
110(
111 const scalar& start,
112 const scalar& end
113)
114{
115 return start + scalar01()*(end - start);
116}
117
118
119template<>
120Foam::label Foam::Random::position(const label& start, const label& end)
121{
122 #ifdef FULLDEBUG
123 if (start > end)
124 {
126 << "start index " << start << " > end index " << end << nl
127 << abort(FatalError);
128 }
129 #endif
130
131 // Extend the upper sampling range by 1 and floor the result.
132 // Since the range is non-negative, can use integer truncation
133 // instead using floor().
134
135 const label val = start + label(scalar01()*(end - start + 1));
136
137 // Rare case when scalar01() returns exactly 1.000 and the truncated
138 // value would be out of range.
139 return min(val, end);
140}
141
142
143template<>
145{
146 scalar value(-GREAT);
147
148 if (Pstream::master())
149 {
150 value = scalar01();
151 }
152
153 Pstream::scatter(value);
154
155 return value;
156}
157
158
159template<>
161{
162 label value(labelMin);
163
164 if (Pstream::master())
165 {
166 value = round(scalar01());
167 }
168
169 Pstream::scatter(value);
170
171 return value;
172}
173
174
175template<>
177{
178 scalar value(-GREAT);
179
180 if (Pstream::master())
181 {
182 value = GaussNormal<scalar>();
183 }
184
185 Pstream::scatter(value);
186
187 return value;
188}
189
190
191template<>
193{
194 label value(labelMin);
195
196 if (Pstream::master())
197 {
198 value = GaussNormal<label>();
199 }
200
201 Pstream::scatter(value);
202
203 return value;
204}
205
206
207template<>
209(
210 const scalar& start,
211 const scalar& end
212)
213{
214 scalar value(-GREAT);
215
216 if (Pstream::master())
217 {
218 value = position<scalar>(start, end);
219 }
220
221 Pstream::scatter(value);
222
223 return value;
224}
225
226
227template<>
229(
230 const label& start,
231 const label& end
232)
233{
234 label value(labelMin);
235
236 if (Pstream::master())
237 {
238 value = position<label>(start, end);
239 }
240
241 Pstream::scatter(value);
242
243 return value;
244}
245
246
247// ************************************************************************* //
Inter-processor communication reduction functions.
static void scatter(const List< commsStruct > &comms, T &value, const int tag, const label comm)
Broadcast data: Distribute without modification.
void seed(uint32_t val=default_seed)
Reseed the generator.
Definition: Rand48.H:112
Random number generator.
Definition: Random.H:60
Type GaussNormal()
Type sample01()
Return a sample whose components lie in the range [0,1].
Type globalSample01()
Return a sample whose components lie in the range [0,1].
void reset(const label seedValue)
Reset the random number generator seed.
Definition: RandomI.H:50
Type globalPosition(const Type &start, const Type &end)
Return a sample on the interval [start,end].
Type globalGaussNormal()
splitCell * master() const
Definition: splitCell.H:113
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
dimensionedSymmTensor sqr(const dimensionedVector &dv)
constexpr label labelMin
Definition: label.H:60
dimensionedScalar log(const dimensionedScalar &ds)
dimensionedScalar sqrt(const dimensionedScalar &ds)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
Calculate the second temporal derivative.