Loading...
Searching...
No Matches
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-2022 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<>
67{
68 return round(scalar01());
69}
70
71
72template<>
73Foam::scalar Foam::Random::GaussNormal()
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<>
103{
104 return round(GaussNormal<scalar>());
105}
106
107
108template<>
109Foam::scalar Foam::Random::position
110(
111 const scalar& start,
112 const scalar& end
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<>
144Foam::scalar Foam::Random::globalSample01()
145{
146 scalar value(0);
147
148 if (Pstream::master())
149 {
150 value = scalar01();
151 }
152
154
155 return value;
156}
157
158
159template<>
161{
162 label value(0);
163
164 if (Pstream::master())
165 {
166 value = round(scalar01());
167 }
168
170
171 return value;
172}
173
174
175template<>
177{
178 scalar value(0);
179
180 if (Pstream::master())
181 {
182 value = GaussNormal<scalar>();
183 }
184
186
187 return value;
188}
189
190
191template<>
193{
194 label value(0);
195
196 if (Pstream::master())
197 {
198 value = GaussNormal<label>();
199 }
200
202
203 return value;
204}
205
206
207template<>
209(
210 const scalar& start,
211 const scalar& end
212)
213{
214 scalar value(0);
215
216 if (Pstream::master())
217 {
218 value = position<scalar>(start, end);
219 }
220
222
223 return value;
224}
225
226
227template<>
229(
230 const label& start,
231 const label& end
232)
233{
234 label value(0);
235
236 if (Pstream::master())
237 {
238 value = position<label>(start, end);
239 }
240
241 Pstream::broadcast(value);
242
243 return value;
244}
245
246
247// ************************************************************************* //
Inter-processor communication reduction functions.
void seed(uint32_t val=default_seed)
Reseed the generator.
Definition Rand48.H:124
Random number generator.
Definition Random.H:56
Type position(const Type &start, const Type &end)
Return a sample on the interval [start,end].
Type GaussNormal()
Return a sample whose components are normally distributed with zero mean and unity variance N(0,...
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:43
Random(const label seedValue=defaultSeed)
Construct with seed value.
Definition Random.C:26
Type globalPosition(const Type &start, const Type &end)
Return a sample on the interval [start,end].
Type globalGaussNormal()
Return a sample whose components are normally distributed with zero mean and unity variance N(0,...
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
@ broadcast
broadcast [MPI]
Definition UPstream.H:189
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
dimensionedSymmTensor sqr(const dimensionedVector &dv)
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:26
errorManip< error > abort(error &err)
Definition errorManip.H:139
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
Calculate the second temporal derivative.