diff --git a/applications/test/BinSum/Test-BinSum.C b/applications/test/BinSum/Test-BinSum.C index 873e7eb893..6d0abfff28 100644 --- a/applications/test/BinSum/Test-BinSum.C +++ b/applications/test/BinSum/Test-BinSum.C @@ -46,7 +46,7 @@ int main(int argc, char *argv[]) scalarField samples(10000000); forAll(samples, i) { - samples[i] = rndGen.scalar01(); + samples[i] = rndGen.sample01(); } const scalar min = 0; diff --git a/applications/test/Distribution/Test-Distribution.C b/applications/test/Distribution/Test-Distribution.C index f893e1e4bc..647c7a7d42 100644 --- a/applications/test/Distribution/Test-Distribution.C +++ b/applications/test/Distribution/Test-Distribution.C @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dS.add(2.5*R.GaussNormal() + 8.5); + dS.add(2.5*R.GaussNormal() + 8.5); } Info<< "Mean " << dS.mean() << nl @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dS2.add(1.5*R.GaussNormal() -6.0); + dS2.add(1.5*R.GaussNormal() -6.0); } Info<< "Mean " << dS2.mean() << nl @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dS.add(R.scalar01() + 10*Pstream::myProcNo()); + dS.add(R.sample01() + 10*Pstream::myProcNo()); } Pout<< "Mean " << dS.mean() << nl @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dV.add(R.vector01()); + dV.add(R.sample01()); // Adding separate GaussNormal components with component // weights @@ -164,9 +164,9 @@ int main(int argc, char *argv[]) ( vector ( - R.GaussNormal()*3.0 + 1.5, - R.GaussNormal()*0.25 + 4.0, - R.GaussNormal()*3.0 - 1.5 + R.GaussNormal()*3.0 + 1.5, + R.GaussNormal()*0.25 + 4.0, + R.GaussNormal()*3.0 - 1.5 ), vector(1.0, 2.0, 5.0) ); @@ -225,7 +225,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dT.add(R.tensor01()); + dT.add(R.sample01()); } Info<< "Mean " << dT.mean() << nl @@ -249,7 +249,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dSyT.add(R.symmTensor01()); + dSyT.add(R.sample01()); } Info<< "Mean " << dSyT.mean() << nl @@ -273,7 +273,7 @@ int main(int argc, char *argv[]) for (label i = 0; i < randomDistributionTestSize; i++) { - dSpT.add(R.sphericalTensor01()); + dSpT.add(R.sample01()); } Info<< "Mean " << dSpT.mean() << nl diff --git a/applications/test/Polynomial/Test-Polynomial.C b/applications/test/Polynomial/Test-Polynomial.C index 352d15f96d..6a6fb8bb45 100644 --- a/applications/test/Polynomial/Test-Polynomial.C +++ b/applications/test/Polynomial/Test-Polynomial.C @@ -152,7 +152,7 @@ int main(int argc, char *argv[]) Random rnd(123456); for (int i=0; i<10; i++) { - scalar x = rnd.scalar01()*100; + scalar x = rnd.sample01()*100; scalar px = polyValue(x); scalar ipx = intPolyValue(x); diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H index 190e493322..929eeb306b 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshI.H @@ -293,9 +293,9 @@ inline Foam::point Foam::conformalVoronoiMesh::perturbPoint scalar pert = 1e-12*defaultCellSize(); - perturbedPt.x() += pert*(rndGen_.scalar01() - 0.5); - perturbedPt.y() += pert*(rndGen_.scalar01() - 0.5); - perturbedPt.z() += pert*(rndGen_.scalar01() - 0.5); + perturbedPt.x() += pert*(rndGen_.sample01() - 0.5); + perturbedPt.y() += pert*(rndGen_.sample01() - 0.5); + perturbedPt.z() += pert*(rndGen_.sample01() - 0.5); return perturbedPt; } diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/autoDensity/autoDensity.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/autoDensity/autoDensity.C index e2d1001504..1acd01d9bf 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/autoDensity/autoDensity.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/autoDensity/autoDensity.C @@ -553,11 +553,11 @@ bool Foam::autoDensity::fillBox + vector ( delta.x() - *(i + 0.5 + 0.1*(rndGen().scalar01() - 0.5)), + *(i + 0.5 + 0.1*(rndGen().sample01() - 0.5)), delta.y() - *(j + 0.5 + 0.1*(rndGen().scalar01() - 0.5)), + *(j + 0.5 + 0.1*(rndGen().sample01() - 0.5)), delta.z() - *(k + 0.5 + 0.1*(rndGen().scalar01() - 0.5)) + *(k + 0.5 + 0.1*(rndGen().sample01() - 0.5)) ); } } @@ -662,7 +662,7 @@ bool Foam::autoDensity::fillBox // TODO - is there a lot of cost in the 1/density calc? Could // assess on // (1/maxDensity)/(1/localDensity) = minVolume/localVolume - if (localDensity/maxDensity > rndGen().scalar01()) + if (localDensity/maxDensity > rndGen().sample01()) { scalar localVolume = 1/localDensity; @@ -675,7 +675,7 @@ bool Foam::autoDensity::fillBox scalar addProbability = (totalVolume - volumeAdded)/localVolume; - scalar r = rndGen().scalar01(); + scalar r = rndGen().sample01(); if (debug) { @@ -729,7 +729,7 @@ bool Foam::autoDensity::fillBox { trialPoints++; - point p = min + cmptMultiply(span, rndGen().vector01()); + point p = min + cmptMultiply(span, rndGen().sample01()); scalar localSize = cellShapeControls().cellSize(p); @@ -785,7 +785,7 @@ bool Foam::autoDensity::fillBox // Accept possible placements proportional to the relative local // density - if (localDensity/maxDensity > rndGen().scalar01()) + if (localDensity/maxDensity > rndGen().sample01()) { scalar localVolume = 1/localDensity; @@ -798,7 +798,7 @@ bool Foam::autoDensity::fillBox scalar addProbability = (totalVolume - volumeAdded)/localVolume; - scalar r = rndGen().scalar01(); + scalar r = rndGen().sample01(); if (debug) { diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/bodyCentredCubic/bodyCentredCubic.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/bodyCentredCubic/bodyCentredCubic.C index 17a4285d86..8991e7ae9d 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/bodyCentredCubic/bodyCentredCubic.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/bodyCentredCubic/bodyCentredCubic.C @@ -129,9 +129,9 @@ List bodyCentredCubic::initialPoints() const if (randomiseInitialGrid_) { - pA.x() += pert*(rndGen().scalar01() - 0.5); - pA.y() += pert*(rndGen().scalar01() - 0.5); - pA.z() += pert*(rndGen().scalar01() - 0.5); + pA.x() += pert*(rndGen().sample01() - 0.5); + pA.y() += pert*(rndGen().sample01() - 0.5); + pA.z() += pert*(rndGen().sample01() - 0.5); } if (Pstream::parRun()) @@ -150,9 +150,9 @@ List bodyCentredCubic::initialPoints() const if (randomiseInitialGrid_) { - pB.x() += pert*(rndGen().scalar01() - 0.5); - pB.y() += pert*(rndGen().scalar01() - 0.5); - pB.z() += pert*(rndGen().scalar01() - 0.5); + pB.x() += pert*(rndGen().sample01() - 0.5); + pB.y() += pert*(rndGen().sample01() - 0.5); + pB.z() += pert*(rndGen().sample01() - 0.5); } if (Pstream::parRun()) diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/faceCentredCubic/faceCentredCubic.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/faceCentredCubic/faceCentredCubic.C index 9fd36aee3a..36052a3bbb 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/faceCentredCubic/faceCentredCubic.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/faceCentredCubic/faceCentredCubic.C @@ -127,9 +127,9 @@ List faceCentredCubic::initialPoints() const if (randomiseInitialGrid_) { - p.x() += pert*(rndGen().scalar01() - 0.5); - p.y() += pert*(rndGen().scalar01() - 0.5); - p.z() += pert*(rndGen().scalar01() - 0.5); + p.x() += pert*(rndGen().sample01() - 0.5); + p.y() += pert*(rndGen().sample01() - 0.5); + p.z() += pert*(rndGen().sample01() - 0.5); } if (Pstream::parRun()) @@ -155,9 +155,9 @@ List faceCentredCubic::initialPoints() const if (randomiseInitialGrid_) { - p.x() += pert*(rndGen().scalar01() - 0.5); - p.y() += pert*(rndGen().scalar01() - 0.5); - p.z() += pert*(rndGen().scalar01() - 0.5); + p.x() += pert*(rndGen().sample01() - 0.5); + p.y() += pert*(rndGen().sample01() - 0.5); + p.z() += pert*(rndGen().sample01() - 0.5); } if (Pstream::parRun()) @@ -183,9 +183,9 @@ List faceCentredCubic::initialPoints() const if (randomiseInitialGrid_) { - p.x() += pert*(rndGen().scalar01() - 0.5); - p.y() += pert*(rndGen().scalar01() - 0.5); - p.z() += pert*(rndGen().scalar01() - 0.5); + p.x() += pert*(rndGen().sample01() - 0.5); + p.y() += pert*(rndGen().sample01() - 0.5); + p.z() += pert*(rndGen().sample01() - 0.5); } if (Pstream::parRun()) @@ -211,9 +211,9 @@ List faceCentredCubic::initialPoints() const if (randomiseInitialGrid_) { - p.x() += pert*(rndGen().scalar01() - 0.5); - p.y() += pert*(rndGen().scalar01() - 0.5); - p.z() += pert*(rndGen().scalar01() - 0.5); + p.x() += pert*(rndGen().sample01() - 0.5); + p.y() += pert*(rndGen().sample01() - 0.5); + p.z() += pert*(rndGen().sample01() - 0.5); } if (Pstream::parRun()) diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/pointFile/pointFile.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/pointFile/pointFile.C index 38742a6203..a09153cf20 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/pointFile/pointFile.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/pointFile/pointFile.C @@ -198,9 +198,15 @@ List pointFile::initialPoints() const if (randomiseInitialGrid_) { - p.x() += randomPerturbationCoeff_*(rndGen().scalar01() - 0.5); - p.y() += randomPerturbationCoeff_*(rndGen().scalar01() - 0.5); - p.z() += randomPerturbationCoeff_*(rndGen().scalar01() - 0.5); + p.x() += + randomPerturbationCoeff_ + *(rndGen().sample01() - 0.5); + p.y() += + randomPerturbationCoeff_ + *(rndGen().sample01() - 0.5); + p.z() += + randomPerturbationCoeff_ + *(rndGen().sample01() - 0.5); } initialPoints.append(Vb::Point(p.x(), p.y(), p.z())); diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/rayShooting/rayShooting.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/rayShooting/rayShooting.C index 103a09c23a..7727153e5b 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/rayShooting/rayShooting.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/rayShooting/rayShooting.C @@ -86,9 +86,9 @@ void rayShooting::splitLine { Foam::point newPt ( - midPoint.x() + pert*(rndGen().scalar01() - 0.5), - midPoint.y() + pert*(rndGen().scalar01() - 0.5), - midPoint.z() + pert*(rndGen().scalar01() - 0.5) + midPoint.x() + pert*(rndGen().sample01() - 0.5), + midPoint.y() + pert*(rndGen().sample01() - 0.5), + midPoint.z() + pert*(rndGen().sample01() - 0.5) ); if diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/uniformGrid/uniformGrid.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/uniformGrid/uniformGrid.C index 319db49293..e7d8d8dcf1 100644 --- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/uniformGrid/uniformGrid.C +++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/initialPointsMethod/uniformGrid/uniformGrid.C @@ -128,9 +128,9 @@ List uniformGrid::initialPoints() const if (randomiseInitialGrid_) { - p.x() += pert*(rndGen().scalar01() - 0.5); - p.y() += pert*(rndGen().scalar01() - 0.5); - p.z() += pert*(rndGen().scalar01() - 0.5); + p.x() += pert*(rndGen().sample01() - 0.5); + p.y() += pert*(rndGen().sample01() - 0.5); + p.z() += pert*(rndGen().sample01() - 0.5); } if diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C index 92d08f29d6..1a540eaf8d 100644 --- a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C +++ b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C @@ -264,8 +264,8 @@ void Foam::CV2D::insertGrid() if (meshControls().randomiseInitialGrid()) { - p.x() += pert*(rndGen.scalar01() - 0.5); - p.y() += pert*(rndGen.scalar01() - 0.5); + p.x() += pert*(rndGen.sample01() - 0.5); + p.y() += pert*(rndGen.sample01() - 0.5); } if (qSurf_.wellInside(p, 0.5*meshControls().minCellSize2())) diff --git a/applications/utilities/postProcessing/miscellaneous/pdfPlot/createFields.H b/applications/utilities/postProcessing/miscellaneous/pdfPlot/createFields.H index 85ec143ca9..68229a7a93 100644 --- a/applications/utilities/postProcessing/miscellaneous/pdfPlot/createFields.H +++ b/applications/utilities/postProcessing/miscellaneous/pdfPlot/createFields.H @@ -20,7 +20,7 @@ const fileName pdfPath = runTime.path()/"pdf"; mkDir(pdfPath); - cachedRandom rndGen(label(0), -1); + Random rndGen; autoPtr p ( diff --git a/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C b/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C index abc3d321d2..02d0b0c8e6 100644 --- a/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C +++ b/applications/utilities/surface/surfaceBooleanFeatures/surfaceBooleanFeatures.C @@ -783,7 +783,7 @@ labelPair edgeIntersectionsAndShuffleCGAL const edge& e = edges[edgeI]; forAll(e, eI) { - vector d = rndGen.vector01()-p05; + vector d = rndGen.sample01() - p05; surf1Points[mp[e[eI]]] += surf1PointTol[e[eI]]*d; } } diff --git a/applications/utilities/surface/surfaceInertia/surfaceInertia.C b/applications/utilities/surface/surfaceInertia/surfaceInertia.C index b0808d239d..fb45390688 100644 --- a/applications/utilities/surface/surfaceInertia/surfaceInertia.C +++ b/applications/utilities/surface/surfaceInertia/surfaceInertia.C @@ -125,9 +125,9 @@ int main(int argc, char *argv[]) << "No eigenValues found, shape may have symmetry, " << "perturbing inertia tensor diagonal" << endl; - J.xx() *= 1.0 + SMALL*rand.scalar01(); - J.yy() *= 1.0 + SMALL*rand.scalar01(); - J.zz() *= 1.0 + SMALL*rand.scalar01(); + J.xx() *= 1.0 + SMALL*rand.sample01(); + J.yy() *= 1.0 + SMALL*rand.sample01(); + J.zz() *= 1.0 + SMALL*rand.sample01(); eVal = eigenValues(J); diff --git a/src/OSspecific/POSIX/POSIX.C b/src/OSspecific/POSIX/POSIX.C index 5594acdee8..d444b83a0b 100644 --- a/src/OSspecific/POSIX/POSIX.C +++ b/src/OSspecific/POSIX/POSIX.C @@ -59,7 +59,6 @@ Description #include #include - #ifdef USE_RANDOM #include #if INT_MAX != 2147483647 @@ -1430,6 +1429,15 @@ Foam::fileNameList Foam::dlLoaded() return libs; } +Foam::label Foam::osRandomBufferSize() +{ + #ifdef USE_RANDOM + return sizeof(random_data); + #else + return sizeof(drand48_data); + #endif +} + void Foam::osRandomSeed(const label seed) { @@ -1461,4 +1469,42 @@ Foam::scalar Foam::osRandomDouble() } +void Foam::osRandomSeed(const label seed, List& buffer) +{ + #ifdef USE_RANDOM + srandom_r((unsigned int)seed, reinterpret_cast(buffer.begin())); + #else + srand48_r(seed, reinterpret_cast(buffer.begin())); + #endif +} + + +Foam::label Foam::osRandomInteger(List& buffer) +{ + #ifdef USE_RANDOM + int32_t result; + random_r(reinterpret_cast(buffer.begin()), &result); + return result; + #else + long result; + lrand48_r(reinterpret_cast(buffer.begin()), &result); + return result; + #endif +} + + +Foam::scalar Foam::osRandomDouble(List& buffer) +{ + #ifdef USE_RANDOM + int32_t result; + random_r(reinterpret_cast(buffer.begin()), &result); + return (scalar)result/INT_MAX; + #else + double result; + drand48_r(reinterpret_cast(buffer.begin()), &result); + return result; + #endif +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 14af54effd..5636f7c937 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -111,7 +111,6 @@ $(sha1)/SHA1.C $(sha1)/SHA1Digest.C primitives/random/Random/Random.C -primitives/random/cachedRandom/cachedRandom.C ranges = primitives/ranges $(ranges)/labelRange/labelRange.C diff --git a/src/OpenFOAM/include/OSspecific.H b/src/OpenFOAM/include/OSspecific.H index 3d5e3bbc7b..6dee7af27b 100644 --- a/src/OpenFOAM/include/OSspecific.H +++ b/src/OpenFOAM/include/OSspecific.H @@ -245,6 +245,18 @@ label osRandomInteger(); //- Return random double precision (uniform distribution between 0 and 1) scalar osRandomDouble(); +//- Return the size of the buffer for re-entrant random number generator +label osRandomBufferSize(); + +//- Seed random number generator. +void osRandomSeed(const label seed, List& buffer); + +//- Return random integer (uniform distribution between 0 and 2^31) +label osRandomInteger(List& buffer); + +//- Return random double precision (uniform distribution between 0 and 1) +scalar osRandomDouble(List& buffer); + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H index badea19542..2369e77ca8 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H +++ b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedron.H @@ -42,7 +42,6 @@ SourceFiles #include "point.H" #include "primitiveFieldsFwd.H" #include "pointHit.H" -#include "cachedRandom.H" #include "Random.H" #include "FixedList.H" #include "UList.H" @@ -239,10 +238,6 @@ public: // uniform distribution inline Point randomPoint(Random& rndGen) const; - //- Return a random point in the tetrahedron from a - // uniform distribution - inline Point randomPoint(cachedRandom& rndGen) const; - //- Calculate the barycentric coordinates of the given // point, in the same order as a, b, c, d. Returns the // determinant of the solution. diff --git a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H index 2c14d16121..d95f42dc1e 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H +++ b/src/OpenFOAM/meshes/primitiveShapes/tetrahedron/tetrahedronI.H @@ -249,42 +249,6 @@ inline Point Foam::tetrahedron::randomPoint // Adapted from // http://vcg.isti.cnr.it/activities/geometryegraphics/pointintetraedro.html - scalar s = rndGen.scalar01(); - scalar t = rndGen.scalar01(); - scalar u = rndGen.scalar01(); - - if (s + t > 1.0) - { - s = 1.0 - s; - t = 1.0 - t; - } - - if (t + u > 1.0) - { - scalar tmp = u; - u = 1.0 - s - t; - t = 1.0 - tmp; - } - else if (s + t + u > 1.0) - { - scalar tmp = u; - u = s + t + u - 1.0; - s = 1.0 - t - tmp; - } - - return (1 - s - t - u)*a_ + s*b_ + t*c_ + u*d_; -} - - -template -inline Point Foam::tetrahedron::randomPoint -( - cachedRandom& rndGen -) const -{ - // Adapted from - // http://vcg.isti.cnr.it/activities/geometryegraphics/pointintetraedro.html - scalar s = rndGen.sample01(); scalar t = rndGen.sample01(); scalar u = rndGen.sample01(); diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H index ea15519517..b97483ca27 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H +++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangle.H @@ -40,7 +40,6 @@ SourceFiles #include "tensor.H" #include "pointHit.H" #include "Random.H" -#include "cachedRandom.H" #include "FixedList.H" #include "UList.H" #include "linePointRef.H" @@ -238,10 +237,6 @@ public: // distribution inline Point randomPoint(Random& rndGen) const; - //- Return a random point on the triangle from a uniform - // distribution - inline Point randomPoint(cachedRandom& rndGen) const; - //- Calculate the barycentric coordinates of the given // point, in the same order as a, b, c. Returns the // determinant of the solution. diff --git a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H index eee54fd92c..605e10589b 100644 --- a/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H +++ b/src/OpenFOAM/meshes/primitiveShapes/triangle/triangleI.H @@ -249,25 +249,6 @@ inline Point Foam::triangle::randomPoint(Random& rndGen) const // from "Graphics Gems", Academic Press, 1990 // http://tog.acm.org/GraphicsGems/gems/TriPoints.c - scalar s = rndGen.scalar01(); - - scalar t = sqrt(rndGen.scalar01()); - - return (1 - t)*a_ + (1 - s)*t*b_ + s*t*c_; -} - - -template -inline Point Foam::triangle::randomPoint -( - cachedRandom& rndGen -) const -{ - // Generating Random Points in Triangles - // by Greg Turk - // from "Graphics Gems", Academic Press, 1990 - // http://tog.acm.org/GraphicsGems/gems/TriPoints.c - scalar s = rndGen.sample01(); scalar t = sqrt(rndGen.sample01()); diff --git a/src/OpenFOAM/meshes/treeBoundBox/treeBoundBox.H b/src/OpenFOAM/meshes/treeBoundBox/treeBoundBox.H index edc42983df..7c27f9fc26 100644 --- a/src/OpenFOAM/meshes/treeBoundBox/treeBoundBox.H +++ b/src/OpenFOAM/meshes/treeBoundBox/treeBoundBox.H @@ -335,7 +335,7 @@ public: label distanceCmp(const point& pt, const treeBoundBox& other) const; //- Return slightly wider bounding box - // Extends all dimensions with s*span*Random::scalar01() + // Extends all dimensions with s*span*Random::sample01() // and guarantees in any direction s*mag(span) minimum width inline treeBoundBox extend(Random& rndGen, const scalar s) const; diff --git a/src/OpenFOAM/meshes/treeBoundBox/treeBoundBoxI.H b/src/OpenFOAM/meshes/treeBoundBox/treeBoundBoxI.H index 4b073fd975..750a6737ff 100644 --- a/src/OpenFOAM/meshes/treeBoundBox/treeBoundBoxI.H +++ b/src/OpenFOAM/meshes/treeBoundBox/treeBoundBoxI.H @@ -336,8 +336,8 @@ inline Foam::treeBoundBox Foam::treeBoundBox::extend newSpan[dir] = Foam::max(newSpan[dir], minSpan); } - bb.min() -= cmptMultiply(s * rndGen.vector01(), newSpan); - bb.max() += cmptMultiply(s * rndGen.vector01(), newSpan); + bb.min() -= cmptMultiply(s*rndGen.sample01(), newSpan); + bb.max() += cmptMultiply(s*rndGen.sample01(), newSpan); return bb; } diff --git a/src/OpenFOAM/primitives/random/Random/Random.C b/src/OpenFOAM/primitives/random/Random/Random.C index 3fa14012c1..c17f5c2668 100644 --- a/src/OpenFOAM/primitives/random/Random/Random.C +++ b/src/OpenFOAM/primitives/random/Random/Random.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,173 +25,237 @@ License #include "Random.H" #include "OSspecific.H" +#include "PstreamReduceOps.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * // -#if INT_MAX != 2147483647 -# error "INT_MAX != 2147483647" -# error "The random number generator may not work!" -#endif +Foam::scalar Foam::Random::scalar01() +{ + return osRandomDouble(buffer_); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::Random::Random(const label seed) +: + buffer_(osRandomBufferSize()), + seed_(seed), + hasGaussSample_(false), + gaussSample_(0) +{ + // Initialise the random number generator + osRandomSeed(seed_, buffer_); +} + + +Foam::Random::Random(const Random& r, const bool reset) +: + buffer_(r.buffer_), + seed_(r.seed_), + hasGaussSample_(r.hasGaussSample_), + gaussSample_(r.gaussSample_) +{ + if (reset) + { + hasGaussSample_ = false; + gaussSample_ = 0; + + // Re-initialise the samples + osRandomSeed(seed_, buffer_); + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::Random::~Random() +{} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -Foam::Random::Random(const label seed) +void Foam::Random::reset(const label seed) { - if (seed > 1) - { - Seed = seed; - } - else - { - Seed = 1; - } - - osRandomSeed(Seed); + seed_ = seed; + osRandomSeed(seed_, buffer_); } int Foam::Random::bit() { - if (osRandomInteger() > INT_MAX/2) + return osRandomInteger(buffer_) & 1; +} + + +template<> +Foam::scalar Foam::Random::sample01() +{ + return scalar01(); +} + + +template<> +Foam::label Foam::Random::sample01() +{ + return round(scalar01()); +} + + +template<> +Foam::scalar Foam::Random::GaussNormal() +{ + if (hasGaussSample_) { - return 1; + hasGaussSample_ = false; + return gaussSample_; } else { - return 0; - } -} - - -Foam::scalar Foam::Random::scalar01() -{ - return osRandomDouble(); -} - - -Foam::vector Foam::Random::vector01() -{ - vector rndVec; - for (direction cmpt=0; cmpt= 1.0 || rsq == 0.0); + } while (rsq >= 1 || rsq == 0); - fac = sqrt(-2.0*log(rsq)/rsq); - gset = v1*fac; - iset = 1; + scalar fac = sqrt(-2*log(rsq)/rsq); + + gaussSample_ = v1*fac; + hasGaussSample_ = true; return v2*fac; } - else - { - iset = 0; +} - return gset; + +template<> +Foam::label Foam::Random::GaussNormal() +{ + return round(GaussNormal()); +} + + +template<> +Foam::scalar Foam::Random::position +( + const scalar& start, + const scalar& end +) +{ + return start + scalar01()*(end - start); +} + + +template<> +Foam::label Foam::Random::position(const label& start, const label& end) +{ + return start + round(scalar01()*(end - start)); +} + + +template<> +Foam::scalar Foam::Random::globalSample01() +{ + scalar value = -GREAT; + + if (Pstream::master()) + { + value = scalar01(); } + + Pstream::scatter(value); + + return value; +} + + +template<> +Foam::label Foam::Random::globalSample01() +{ + scalar value = -GREAT; + + if (Pstream::master()) + { + value = scalar01(); + } + + Pstream::scatter(value); + + return round(value); +} + + +template<> +Foam::scalar Foam::Random::globalGaussNormal() +{ + scalar value = -GREAT; + + if (Pstream::master()) + { + value = GaussNormal(); + } + + Pstream::scatter(value); + + return value; +} + + +template<> +Foam::label Foam::Random::globalGaussNormal() +{ + scalar value = -GREAT; + + if (Pstream::master()) + { + value = GaussNormal(); + } + + Pstream::scatter(value); + + return round(value); +} + + +template<> +Foam::scalar Foam::Random::globalPosition +( + const scalar& start, + const scalar& end +) +{ + scalar value = -GREAT; + + if (Pstream::master()) + { + value = scalar01()*(end - start); + } + + Pstream::scatter(value); + + return start + value; +} + + +template<> +Foam::label Foam::Random::globalPosition +( + const label& start, + const label& end +) +{ + label value = labelMin; + + if (Pstream::master()) + { + value = round(scalar01()*(end - start)); + } + + Pstream::scatter(value); + + return start + value; } diff --git a/src/OpenFOAM/primitives/random/Random/Random.H b/src/OpenFOAM/primitives/random/Random/Random.H index 1dd109a235..fb348fdafa 100644 --- a/src/OpenFOAM/primitives/random/Random/Random.H +++ b/src/OpenFOAM/primitives/random/Random/Random.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,24 +25,29 @@ Class Foam::Random Description - Simple random number generator. + Random number generator. + SourceFiles + RandomI.H Random.C + RandomTemplates.C \*---------------------------------------------------------------------------*/ #ifndef Random_H #define Random_H -#include "vector.H" -#include "tensor.H" +#include "List.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { +// Forward declaration of classes +class Random; + /*---------------------------------------------------------------------------*\ Class Random Declaration \*---------------------------------------------------------------------------*/ @@ -51,60 +56,165 @@ class Random { // Private data - label Seed; + //- Buffer used by re-entrant random number generator + List buffer_; + + //- Initial random number seed + label seed_; + + //- Indicator, which tells if there is a stored gaussian sample + bool hasGaussSample_; + + //- Stored sample value + scalar gaussSample_; + + + // Private Member Functions + + //- Returns the current sample + scalar scalar01(); public: - // Constructors - //- Construct given seed - Random(const label); + //- Construct given seed and sample count + Random(const label seed = 123456); + + //- Copy constructor with optional reset of sampleI + Random(const Random& r, const bool reset = false); + + + // Destructor + ~Random(); // Member functions - int bit(); + // Access - //- Scalar [0..1] (so including 0,1) - scalar scalar01(); + //- Return const access to the initial random number seed + inline label seed() const; - //- Vector with every component scalar01 - vector vector01(); + //- Reset the random number generator seed + void reset(const label seed); - //- sphericalTensor with every component scalar01 - sphericalTensor sphericalTensor01(); - //- symmTensor with every component scalar01 - symmTensor symmTensor01(); + // Evaluation - //- Tensor with every component scalar01 - tensor tensor01(); + // Random numbers - //- Label [lower..upper] - label integer(const label lower, const label upper); + //- Return a random bit + int bit(); - vector position(const vector&, const vector&); + //- Return a sample whose components lie in the range 0-1 + template + Type sample01(); - void randomise(scalar&); - void randomise(vector&); - void randomise(sphericalTensor&); - void randomise(symmTensor&); - void randomise(tensor&); + //- Return a sample whose components are normally distributed + // with zero mean and unity variance N(0, 1) + template + Type GaussNormal(); - //- Return a normal Gaussian randon number - // with zero mean and unity variance N(0, 1) - scalar GaussNormal(); + //- Return a sample between start and end + template + Type position(const Type& start, const Type& end); + + //- Randomise value in the range 0-1 + template + void randomise01(Type& value); + + //- Shuffle the values in the list + template + void shuffle(UList& values); + + + // Global random numbers - consistent across all processors + + //- Return a sample whose components lie in the range 0-1 + template + Type globalSample01(); + + //- Return a sample whose components are normally distributed + // with zero mean and unity variance N(0, 1) + template + Type globalGaussNormal(); + + //- Return a sample between start and end + template + Type globalPosition(const Type& start, const Type& end); + + //- Randomise value in the range 0-1 + template + void globalRandomise01(Type& value); }; +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Template specialisations + +template<> +scalar Random::sample01(); + +template<> +label Random::sample01