00001 /*---------------------------------------------------------------------------*\ 00002 ========= | 00003 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox 00004 \\ / O peration | 00005 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. 00006 \\/ M anipulation | 00007 ------------------------------------------------------------------------------- 00008 License 00009 This file is part of OpenFOAM. 00010 00011 OpenFOAM is free software: you can redistribute it and/or modify it 00012 under the terms of the GNU General Public License as published by 00013 the Free Software Foundation, either version 3 of the License, or 00014 (at your option) any later version. 00015 00016 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00018 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00019 for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. 00023 00024 \*---------------------------------------------------------------------------*/ 00025 00026 #include <OpenFOAM/Random.H> 00027 00028 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00029 00030 namespace Foam 00031 { 00032 00033 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00034 00035 #if INT_MAX != 2147483647 00036 # error "INT_MAX != 2147483647" 00037 # error "The random number generator may not work!" 00038 #endif 00039 00040 #ifdef USE_RANDOM 00041 # include <climits> 00042 #else 00043 # include <cstdlib> 00044 #endif 00045 00046 00047 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // 00048 00049 // construct given seed 00050 Random::Random(const label& seed) 00051 { 00052 if (seed > 1) 00053 { 00054 Seed = seed; 00055 } 00056 else 00057 { 00058 Seed = 1; 00059 } 00060 00061 # ifdef USE_RANDOM 00062 srandom((unsigned int)Seed); 00063 # else 00064 srand48(Seed); 00065 # endif 00066 00067 } 00068 00069 00070 int Random::bit() 00071 { 00072 # ifdef USE_RANDOM 00073 if (random() > INT_MAX/2) 00074 # else 00075 if (lrand48() > INT_MAX/2) 00076 # endif 00077 { 00078 return 1; 00079 } 00080 else 00081 { 00082 return 0; 00083 } 00084 } 00085 00086 00087 scalar Random::scalar01() 00088 { 00089 # ifdef USE_RANDOM 00090 return (scalar)random()/INT_MAX; 00091 # else 00092 return drand48(); 00093 # endif 00094 } 00095 00096 00097 vector Random::vector01() 00098 { 00099 vector rndVec; 00100 for (direction cmpt=0; cmpt<vector::nComponents; cmpt++) 00101 { 00102 rndVec.component(cmpt) = scalar01(); 00103 } 00104 00105 return rndVec; 00106 } 00107 00108 00109 sphericalTensor Random::sphericalTensor01() 00110 { 00111 sphericalTensor rndTen; 00112 rndTen.ii() = scalar01(); 00113 00114 return rndTen; 00115 } 00116 00117 00118 symmTensor Random::symmTensor01() 00119 { 00120 symmTensor rndTen; 00121 for (direction cmpt=0; cmpt<symmTensor::nComponents; cmpt++) 00122 { 00123 rndTen.component(cmpt) = scalar01(); 00124 } 00125 00126 return rndTen; 00127 } 00128 00129 00130 tensor Random::tensor01() 00131 { 00132 tensor rndTen; 00133 for (direction cmpt=0; cmpt<tensor::nComponents; cmpt++) 00134 { 00135 rndTen.component(cmpt) = scalar01(); 00136 } 00137 00138 return rndTen; 00139 } 00140 00141 00142 label Random::integer(const label lower, const label upper) 00143 { 00144 # ifdef USE_RANDOM 00145 return lower + (random() % (upper+1-lower)); 00146 # else 00147 return lower + (lrand48() % (upper+1-lower)); 00148 # endif 00149 } 00150 00151 00152 vector Random::position(const vector& start, const vector& end) 00153 { 00154 vector rndVec(start); 00155 00156 for (direction cmpt=0; cmpt<vector::nComponents; cmpt++) 00157 { 00158 rndVec.component(cmpt) += 00159 scalar01()*(end.component(cmpt) - start.component(cmpt)); 00160 } 00161 00162 return rndVec; 00163 } 00164 00165 00166 void Random::randomise(scalar& s) 00167 { 00168 s = scalar01(); 00169 } 00170 00171 00172 void Random::randomise(vector& v) 00173 { 00174 v = vector01(); 00175 } 00176 00177 00178 void Random::randomise(sphericalTensor& st) 00179 { 00180 st = sphericalTensor01(); 00181 } 00182 00183 00184 void Random::randomise(symmTensor& st) 00185 { 00186 st = symmTensor01(); 00187 } 00188 00189 00190 void Random::randomise(tensor& t) 00191 { 00192 t = tensor01(); 00193 } 00194 00195 00196 // return a normal Gaussian randon number 00197 // with zero mean and unity variance N(0, 1) 00198 00199 scalar Random::GaussNormal() 00200 { 00201 static int iset = 0; 00202 static scalar gset; 00203 scalar fac, rsq, v1, v2; 00204 00205 if (iset == 0) 00206 { 00207 do 00208 { 00209 v1 = 2.0*scalar01() - 1.0; 00210 v2 = 2.0*scalar01() - 1.0; 00211 rsq = v1*v1 + v2*v2; 00212 } while (rsq >= 1.0 || rsq == 0.0); 00213 00214 fac = sqrt(-2.0 * log(rsq)/rsq); 00215 gset = v1*fac; 00216 iset = 1; 00217 00218 return v2*fac; 00219 } 00220 else 00221 { 00222 iset = 0; 00223 00224 return gset; 00225 } 00226 } 00227 00228 00229 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 00230 00231 } // End namespace Foam 00232 00233 // ************************ vim: set sw=4 sts=4 et: ************************ //