From 9df578f412c676048d4457f7a4edbce5437e9282 Mon Sep 17 00:00:00 2001 From: Andrew Heather Date: Thu, 27 Apr 2017 15:23:45 +0100 Subject: [PATCH 1/6] ENH: Random numbers - added re-entrant random interface --- src/OSspecific/POSIX/POSIX.C | 48 ++++++++++++++++++++++++++++++- src/OpenFOAM/include/OSspecific.H | 12 ++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) 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/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); + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // From 02205ef167b1f074ec09083894dadcf8f0fb0668 Mon Sep 17 00:00:00 2001 From: Andrew Heather Date: Thu, 27 Apr 2017 15:24:20 +0100 Subject: [PATCH 2/6] ENH: Random numbers - cachedRandom - updated to use the re-entrant random interface --- .../random/cachedRandom/cachedRandom.C | 77 ++++--------------- .../random/cachedRandom/cachedRandom.H | 35 ++------- .../random/cachedRandom/cachedRandomI.H | 18 ----- 3 files changed, 23 insertions(+), 107 deletions(-) diff --git a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.C b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.C index e2fec45161..47dd8e1c9e 100644 --- a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.C +++ b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.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. @@ -31,88 +31,38 @@ License Foam::scalar Foam::cachedRandom::scalar01() { - if (sampleI_ < 0) - { - return osRandomDouble(); - } - - if (sampleI_ == samples_.size() - 1) - { - scalar s = samples_[sampleI_]; - sampleI_ = 0; - return s; - } - else - { - scalar s = samples_[sampleI_]; - sampleI_++; - return s; - } + return osRandomDouble(buffer_); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::cachedRandom::cachedRandom(const label seed, const label count) +Foam::cachedRandom::cachedRandom(const label seed) : - seed_(1), - samples_(0), - sampleI_(-1), + buffer_(osRandomBufferSize()), + seed_(seed), hasGaussSample_(false), gaussSample_(0) { - if (seed > 1) - { - seed_ = seed; - } - - // Initialise samples - osRandomSeed(seed_); - - // Samples will be cached if count > 0 - if (count > 0) - { - samples_.setSize(count); - forAll(samples_, i) - { - samples_[i] = osRandomDouble(); - } - - sampleI_ = 0; - } + // Initialise the random number generator + osRandomSeed(seed_, buffer_); } Foam::cachedRandom::cachedRandom(const cachedRandom& cr, const bool reset) : + buffer_(cr.buffer_), seed_(cr.seed_), - samples_(cr.samples_), - sampleI_(cr.sampleI_), hasGaussSample_(cr.hasGaussSample_), gaussSample_(cr.gaussSample_) { - //if (sampleI_ == -1) - //{ - // WarningInFunction - // << "Copy constructor called, but samples not being cached. " - // << "This may lead to non-repeatable behaviour" << endl; - // - //} - if (reset) { hasGaussSample_ = false; gaussSample_ = 0; - if (samples_.size()) - { - sampleI_ = 0; - } - else - { - // Re-initialise the samples - osRandomSeed(seed_); - } + // Re-initialise the samples + osRandomSeed(seed_, buffer_); } } @@ -125,6 +75,13 @@ Foam::cachedRandom::~cachedRandom() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +void Foam::cachedRandom::reset(const label seed) +{ + seed_ = seed; + osRandomSeed(seed_, buffer_); +} + + template<> Foam::scalar Foam::cachedRandom::sample01() { diff --git a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.H b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.H index a42034284a..9e4224805c 100644 --- a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.H +++ b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.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. @@ -27,15 +27,6 @@ Class Description Random number generator. - Pre-computes and caches samples on construction, so that when sample01() - is called, the function simply returns the next (pre-computed) sample. On - reaching the last sample, the sample sequence is repeated. - - Constructed using a seed and sample count. If the supplied count is - negative, no caching is performed, and a new sample is generated on each - call to sample01(). - - Note: the copy constructor cannot be used if count = -1. SourceFiles cachedRandomI.H @@ -65,15 +56,12 @@ class cachedRandom { // Private data + //- Buffer used by re-entrant random number generator + List buffer_; + //- Initial random number seed label seed_; - //- List of scalar samples - scalarList samples_; - - //- Current sample marker - label sampleI_; - //- Indicator, which tells if there is a stored gaussian sample bool hasGaussSample_; @@ -92,7 +80,7 @@ public: // Constructors //- Construct given seed and sample count - cachedRandom(const label seed, const label count); + cachedRandom(const label seed = 123456); //- Copy constructor with optional reset of sampleI cachedRandom(const cachedRandom& cr, const bool reset = false); @@ -109,18 +97,7 @@ public: //- Return const access to the initial random number seed inline label seed() const; - //- Return const access to the list of samples - inline const scalarList& samples() const; - - //- Return the current sample marker - inline label sampleI() const; - - - // Manipulation - - //- Return non-const access to the sample marker - inline label& sampleI(); - + void reset(const label seed); // Evaluation diff --git a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandomI.H b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandomI.H index 8d23cbcede..e42e72329b 100644 --- a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandomI.H +++ b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandomI.H @@ -33,22 +33,4 @@ inline Foam::label Foam::cachedRandom::seed() const } -inline const Foam::scalarList& Foam::cachedRandom::samples() const -{ - return samples_; -} - - -inline Foam::label Foam::cachedRandom::sampleI() const -{ - return sampleI_; -} - - -inline Foam::label& Foam::cachedRandom::sampleI() -{ - return sampleI_; -} - - // ************************************************************************* // From 88a03de238bbdd75bfe4f2d09d15311318e45909 Mon Sep 17 00:00:00 2001 From: Andrew Heather Date: Thu, 27 Apr 2017 15:24:52 +0100 Subject: [PATCH 3/6] ENH: Random numbers - updated dependent code from change to cachedRandom class --- .../turbulentDFSEMInletFvPatchVectorField.C | 2 +- .../extractEulerianParticles.H | 1 - .../field/particleDistribution/particleDistribution.C | 2 +- .../clouds/Templates/KinematicCloud/KinematicCloud.C | 10 ++-------- .../force/contactAngleForce/contactAngleForce.C | 2 +- .../drippingInjection/drippingInjection.C | 2 +- 6 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/finiteVolume/fields/fvPatchFields/derived/turbulentDFSEMInlet/turbulentDFSEMInletFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/turbulentDFSEMInlet/turbulentDFSEMInletFvPatchVectorField.C index c68231649a..d997ddee5b 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/turbulentDFSEMInlet/turbulentDFSEMInletFvPatchVectorField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/turbulentDFSEMInlet/turbulentDFSEMInletFvPatchVectorField.C @@ -746,7 +746,7 @@ turbulentDFSEMInletFvPatchVectorField nCellPerEddy_(5), patchNormal_(vector::zero), v0_(0), - rndGen_(0, -1), + rndGen_(), sigmax_(size(), 0), maxSigmaX_(0), nEddy_(0), diff --git a/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.H b/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.H index effb0904fc..580babf826 100644 --- a/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.H +++ b/src/functionObjects/field/extractEulerianParticles/extractEulerianParticles/extractEulerianParticles.H @@ -71,7 +71,6 @@ SourceFiles #include "surfaceFieldsFwd.H" #include "vectorList.H" #include "globalIndex.H" -#include "cachedRandom.H" #include "eulerianParticle.H" #include "IOdictionary.H" #include "injectedParticleCloud.H" diff --git a/src/functionObjects/field/particleDistribution/particleDistribution.C b/src/functionObjects/field/particleDistribution/particleDistribution.C index 71919b0933..b8cf35122b 100644 --- a/src/functionObjects/field/particleDistribution/particleDistribution.C +++ b/src/functionObjects/field/particleDistribution/particleDistribution.C @@ -61,7 +61,7 @@ Foam::functionObjects::particleDistribution::particleDistribution cloudName_("unknown-cloudName"), nameVsBinWidth_(), tagFieldName_("none"), - rndGen_(1234, -1), + rndGen_(), writerPtr_(nullptr) { read(dict); diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C index d82b1bba67..31054caa50 100644 --- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C +++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/KinematicCloud.C @@ -316,13 +316,7 @@ Foam::KinematicCloud::KinematicCloud ( particleProperties_.subOrEmptyDict("subModels", solution_.active()) ), - rndGen_ - ( - label(0), - solution_.steadyState() ? - particleProperties_.lookupOrDefault