diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 32249f8da4..531202fc8e 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -62,6 +62,7 @@ $(sha1)/SHA1.C $(sha1)/SHA1Digest.C primitives/random/Random/Random.C +primitives/random/cachedRandom/cachedRandom.H containers/HashTables/HashTable/HashTableCore.C containers/HashTables/StaticHashTable/StaticHashTableCore.C diff --git a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.C b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.C new file mode 100644 index 0000000000..3865f60fe1 --- /dev/null +++ b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.C @@ -0,0 +1,159 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "cachedRandom.H" +#include + +#if INT_MAX != 2147483647 +# error "INT_MAX != 2147483647" +# error "The random number generator may not work!" +#endif + +// * * * * * * * * * * * * * private Member Functions * * * * * * * * * * * // + +Foam::scalar Foam::cachedRandom::scalar01() +{ + if (sampleI_ < 0) + { + return drand48(); + } + + if (sampleI_ == samples_.size() - 1) + { + scalar s = samples_[sampleI_]; + sampleI_ = 0; + return s; + } + else + { + scalar s = samples_[sampleI_]; + sampleI_++; + return s; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cachedRandom::cachedRandom(const label seed, const label count) +: + seed_(1), + samples_(0), + sampleI_(-1) +{ + if (seed > 1) + { + seed_ = seed; + } + + // Samples will be cached if count > 0 + if (count > 0) + { + samples_.setSize(count); + sampleI_ = 0; + } + + // Initialise samples + srand48(seed_); + forAll(samples_, i) + { + samples_[i] = drand48(); + } +} + + +Foam::cachedRandom::cachedRandom(const cachedRandom& cr, const bool reset) +: + seed_(cr.seed_), + samples_(cr.samples_), + sampleI_(cr.sampleI_) +{ + if (sampleI_ == -1) + { + WarningIn + ( + "Foam::cachedRandom::cachedRandom(const cachedRandom& cr)" + ) << "Copy constructor called, but samples not being cached. " + << "This may lead to non-repeatable behaviour" << endl; + + srand48(seed_); + } + else if (reset) + { + sampleI_ = 0; + } +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cachedRandom::~cachedRandom() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<> +Foam::label Foam::cachedRandom::sample01() +{ + return round(scalar01()); +} + + +template<> +Foam::scalar Foam::cachedRandom::sample01() +{ + return scalar01(); +} + + +template<> +Foam::label Foam::cachedRandom::position(const label& start, const label& end) +{ + return start + round(scalar01()*(end - start)); +} + + +template<> +Foam::scalar Foam::cachedRandom::position +( + const scalar& start, + const scalar& end +) +{ + return start + scalar01()*(end - start); +} + + +void Foam::cachedRandom::operator=(const cachedRandom& cr) +{ + seed_ = cr.seed_; + samples_ = cr.samples_; + sampleI_ = cr.sampleI_; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.H b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.H new file mode 100644 index 0000000000..76da5228e6 --- /dev/null +++ b/src/OpenFOAM/primitives/random/cachedRandom/cachedRandom.H @@ -0,0 +1,182 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::cachedRandom + +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 + cachedRandom.C + cachedRandomTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cachedRandom_H +#define cachedRandom_H + +#include "scalarList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration of classes +class cachedRandom; + +/*---------------------------------------------------------------------------*\ + Class cachedRandom Declaration +\*---------------------------------------------------------------------------*/ + +class cachedRandom +{ +private: + + // Private data + + //- Initial random number seed + label seed_; + + //- List of scalar samples + scalarList samples_; + + //- Current sample marker + label sampleI_; + + + // Private Member Functions + + //- Returns the current sample + scalar scalar01(); + + +public: + + + // Constructors + + //- Construct given seed and sample count + cachedRandom(const label seed, const label count); + + //- Copy constructor with optional reset of sampleI + cachedRandom(const cachedRandom& cr, const bool reset = false); + + + // Destructor + ~cachedRandom(); + + + // Member functions + + // Access + + //- 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(); + + + // Evaluation + + //- Return a sample whose components lie in the range 0-1 + template + Type sample01(); + + //- 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); + + + // Operators + + //- Assignment operator + void operator=(const cachedRandom& cr); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Template specialisations + +template<> +label cachedRandom::sample01