Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / primitives / random / Random.C
blob0a65b58d494552dcf6a58f26219a08ce9b0d64ca
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "Random.H"
28 #ifdef mingw
29 #   include "rand48.h"
30 #endif
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34 namespace Foam
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 #if INT_MAX    != 2147483647
40 #    error "INT_MAX    != 2147483647"
41 #    error "The random number generator may not work!"
42 #endif
44 #ifdef USE_RANDOM
45 #   include <climits>
46 #else
47 #   include <cstdlib>
48 #endif
51 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
53 // construct given seed
54 Random::Random(const label& seed)
56     if (seed > 1)
57     {
58         Seed = seed;
59     }
60     else
61     {
62         Seed = 1;
63     }
65 #   ifdef USE_RANDOM
66         srandom((unsigned int)Seed);
67 #   else
68         srand48(Seed);
69 #   endif
74 int Random::bit()
76 #   ifdef USE_RANDOM
77     if (random() > INT_MAX/2)
78 #   else
79     if (lrand48() > INT_MAX/2)
80 #   endif
81     {
82         return 1;
83     }
84     else
85     {
86         return 0;
87     }
91 scalar Random::scalar01()
93 #   ifdef USE_RANDOM
94         return (scalar)random()/INT_MAX;
95 #   else
96         return drand48();
97 #   endif
101 vector Random::vector01()
103     vector rndVec;
104     for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
105     {
106         rndVec.component(cmpt) = scalar01();
107     }
109     return rndVec;
113 sphericalTensor Random::sphericalTensor01()
115     sphericalTensor rndTen;
116     rndTen.ii() = scalar01();
118     return rndTen;
122 symmTensor Random::symmTensor01()
124     symmTensor rndTen;
125     for (direction cmpt=0; cmpt<symmTensor::nComponents; cmpt++)
126     {
127         rndTen.component(cmpt) = scalar01();
128     }
130     return rndTen;
134 symmTensor4thOrder Random::symmTensor4thOrder01()
136   symmTensor4thOrder rndTen;
137   for (direction cmpt=0; cmpt<symmTensor4thOrder::nComponents; cmpt++)
138     {
139       rndTen.component(cmpt) = scalar01();
140     }
142   return rndTen;
146 diagTensor Random::diagTensor01()
148   diagTensor rndTen;
149   for (direction cmpt=0; cmpt<diagTensor::nComponents; cmpt++)
150     {
151       rndTen.component(cmpt) = scalar01();
152     }
154   return rndTen;
158 tensor Random::tensor01()
160     tensor rndTen;
161     for (direction cmpt=0; cmpt<tensor::nComponents; cmpt++)
162     {
163         rndTen.component(cmpt) = scalar01();
164     }
166     return rndTen;
170 label Random::integer(const label lower, const label upper)
172 #   ifdef USE_RANDOM
173         return lower + (random() % (upper+1-lower));
174 #   else
175         return lower + (lrand48() % (upper+1-lower));
176 #   endif
180 vector Random::position(const vector& start, const vector& end)
182     vector rndVec(start);
184     for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
185     {
186         rndVec.component(cmpt) +=
187             scalar01()*(end.component(cmpt) - start.component(cmpt));
188     }
190     return rndVec;
194 void Random::randomise(scalar& s)
196      s = scalar01();
200 void Random::randomise(vector& v)
202     v = vector01();
206 void Random::randomise(sphericalTensor& st)
208     st = sphericalTensor01();
212 void Random::randomise(symmTensor& st)
214     st = symmTensor01();
218 void Random::randomise(symmTensor4thOrder& st)
220     st = symmTensor4thOrder01();
224 void Random::randomise(diagTensor& dt)
226     dt = diagTensor01();
230 void Random::randomise(tensor& t)
232     t = tensor01();
236 // return a normal Gaussian randon number
237 // with zero mean and unity variance N(0, 1)
239 scalar Random::GaussNormal()
241     static int iset = 0;
242     static scalar gset;
243     scalar fac, rsq, v1, v2;
245     if (iset == 0)
246     {
247         do
248         {
249             v1 = 2.0*scalar01() - 1.0;
250             v2 = 2.0*scalar01() - 1.0;
251             rsq = v1*v1 + v2*v2;
252         } while (rsq >= 1.0 || rsq == 0.0);
254         fac = sqrt(-2.0 * log(rsq)/rsq);
255         gset = v1*fac;
256         iset = 1;
258         return v2*fac;
259     }
260     else
261     {
262         iset = 0;
264         return gset;
265     }
269 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
271 } // End namespace Foam
273 // ************************************************************************* //