Import Geant4 10.5.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2018-06-29 10:58:11 +02:00
parent fe81a77428
commit 6aa23be517
1581 changed files with 124288 additions and 83758 deletions
@@ -1,234 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include <CLHEP/Random/StaticRandomStates.h>
#include <CLHEP/Random/JamesRandom.h>
#include "G4MTHepRandom.hh"
#include "G4Threading.hh"
#include "G4AutoLock.hh"
G4ThreadLocal CLHEP::HepRandomEngine* G4MTHepRandom::theEngine = 0;
G4ThreadLocal G4MTHepRandom* G4MTHepRandom::theGenerator = 0;
G4ThreadLocal G4int G4MTHepRandom::isActive = 0 ;
//---------------------------- HepRandom ---------------------------------
G4MTHepRandom::G4MTHepRandom()
: deleteEngine(false)
{
createInstance();
}
G4MTHepRandom::G4MTHepRandom(G4long seed)
: deleteEngine(false)
{
createInstance();
setTheSeed(seed);
}
G4MTHepRandom::G4MTHepRandom(CLHEP::HepRandomEngine & algorithm)
: deleteEngine(false)
{
theGenerator = this;
theEngine = &algorithm;
isActive = 1;
}
G4MTHepRandom::G4MTHepRandom(CLHEP::HepRandomEngine * algorithm)
: deleteEngine(true)
{
createInstance();
theEngine = algorithm;
}
G4MTHepRandom::~G4MTHepRandom()
{
if ( deleteEngine ) { delete theEngine; theEngine = 0; }
//if ( theGenerator ) { delete theGenerator; theGenerator = 0; }
}
G4double G4MTHepRandom::flat()
{
return theEngine->flat();
}
void G4MTHepRandom::flatArray(const G4int size, G4double* vect)
{
theEngine->flatArray(size,vect);
}
G4double G4MTHepRandom::operator()()
{
return flat();
}
std::ostream & operator<< (std::ostream & os, const G4MTHepRandom & dist)
{
return dist.put(os);
}
std::istream & operator>> (std::istream & is, G4MTHepRandom & dist)
{
return dist.get(is);
}
std::ostream & G4MTHepRandom::put(std::ostream & os) const
{
return os;
}
std::istream & G4MTHepRandom::get(std::istream & is)
{
return is;
}
// --------------------------
// Static methods definitions
// --------------------------
void G4MTHepRandom::setTheSeed(G4long seed, G4int lux)
{
createInstance();
theEngine->setSeed(seed,lux);
}
G4long G4MTHepRandom::getTheSeed()
{
createInstance();
return theEngine->getSeed();
}
void G4MTHepRandom::setTheSeeds(const G4long* seeds, G4int aux)
{
createInstance();
theEngine->setSeeds(seeds,aux);
}
const G4long* G4MTHepRandom::getTheSeeds ()
{
createInstance();
return theEngine->getSeeds();
}
G4MTHepRandom * G4MTHepRandom::getTheGenerator()
{
if (!isActive) { isActive = G4MTHepRandom::createInstanceOnce(); }
return theGenerator;
}
CLHEP::HepRandomEngine * G4MTHepRandom::getTheEngine()
{
if (!isActive) { isActive = G4MTHepRandom::createInstanceOnce(); }
return theEngine;
}
void G4MTHepRandom::setTheEngine (CLHEP::HepRandomEngine* theNewEngine)
{
theEngine = theNewEngine;
}
void G4MTHepRandom::saveEngineStatus( const char filename[] )
{
createInstance();
theEngine->saveStatus( filename );
}
void G4MTHepRandom::restoreEngineStatus( const char filename[] )
{
createInstance();
theEngine->restoreStatus( filename );
}
std::ostream& G4MTHepRandom::saveFullState ( std::ostream & os )
{
os << *getTheEngine();
return os;
}
std::istream& G4MTHepRandom::restoreFullState ( std::istream & is )
{
is >> *getTheEngine();
return is;
}
std::ostream& G4MTHepRandom::saveStaticRandomStates ( std::ostream & os )
{
return CLHEP::StaticRandomStates::save(os);
}
std::istream& G4MTHepRandom::restoreStaticRandomStates ( std::istream & is )
{
return CLHEP::StaticRandomStates::restore(is);
}
void G4MTHepRandom::showEngineStatus()
{
createInstance();
theEngine->showStatus();
}
G4int G4MTHepRandom::createInstance()
{
if (!isActive) { isActive = G4MTHepRandom::createInstanceOnce(); }
if (theGenerator) return 1; // should always be true
return 0;
}
namespace {
G4Mutex jamesrandom = G4MUTEX_INITIALIZER;
}
G4int G4MTHepRandom::createInstanceOnce()
{
if (isActive) return isActive;
isActive = 1;
static G4ThreadLocal CLHEP::HepJamesRandom *defaultEngine = 0;
if (!defaultEngine) {
G4AutoLock l(&jamesrandom);
defaultEngine = new CLHEP::HepJamesRandom;
}
if ( !theEngine ) { theEngine = defaultEngine; }
if ( !theGenerator ) { theGenerator = new G4MTHepRandom( theEngine ); }
return 1;
}
#endif
@@ -1,67 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include "G4MTRandBit.hh"
G4MTRandBit::~G4MTRandBit()
{
}
// Static methods
G4int G4MTRandBit::shootBit()
{
G4double x = shoot();
if (x > .5) {
return 1;
} else {
return 0;
}
}
G4int G4MTRandBit::shootBit(CLHEP::HepRandomEngine* engine)
{
G4double x = shoot(engine);
if (x > .5) {
return 1;
} else {
return 0;
}
}
#endif
@@ -1,93 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include "G4MTRandExponential.hh"
G4MTRandExponential::~G4MTRandExponential()
{
if ( deleteEngine ) delete localEngine;
}
G4double G4MTRandExponential::operator()()
{
return fire( defaultMean );
}
G4double G4MTRandExponential::operator()( G4double mean )
{
return fire( mean );
}
G4double G4MTRandExponential::shoot()
{
return -std::log(G4MTHepRandom::getTheEngine()->flat());
}
G4double G4MTRandExponential::shoot(G4double mean)
{
return -std::log(G4MTHepRandom::getTheEngine()->flat())*mean;
}
void G4MTRandExponential::shootArray( const G4int size, G4double* vect,
G4double mean )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(mean);
}
void G4MTRandExponential::shootArray(CLHEP::HepRandomEngine* anEngine,
const G4int size, G4double* vect, G4double mean )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(anEngine, mean);
}
void G4MTRandExponential::fireArray( const G4int size, G4double* vect)
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( defaultMean );
}
void G4MTRandExponential::fireArray( const G4int size, G4double* vect,
G4double mean )
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( mean );
}
#endif
-104
View File
@@ -1,104 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include "G4MTRandFlat.hh"
const G4int G4MTRandFlat::MSBBits= 15;
const unsigned long G4MTRandFlat::MSB= 1ul<<G4MTRandFlat::MSBBits;
G4ThreadLocal unsigned long G4MTRandFlat::staticRandomInt= 0;
G4ThreadLocal unsigned long G4MTRandFlat::staticFirstUnusedBit= 0;
G4MTRandFlat::~G4MTRandFlat()
{
if ( deleteEngine ) delete localEngine;
}
G4double G4MTRandFlat::operator()()
{
return fire( defaultA, defaultB );
}
G4double G4MTRandFlat::operator()( G4double w )
{
return fire( w );
}
G4double G4MTRandFlat::operator()( G4double a, G4double b )
{
return fire( a, b );
}
G4double G4MTRandFlat::shoot()
{
return G4MTHepRandom::getTheEngine()->flat();
}
void G4MTRandFlat::shootArray(const G4int size, G4double* vect)
{
G4MTHepRandom::getTheEngine()->flatArray(size,vect);
}
void G4MTRandFlat::shootArray( const G4int size, G4double* vect,
G4double lx, G4double dx )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(lx,dx);
}
void G4MTRandFlat::shootArray( CLHEP::HepRandomEngine* anEngine,
const G4int size, G4double* vect,
G4double lx, G4double dx )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(anEngine,lx,dx);
}
void G4MTRandFlat::fireArray( const G4int size, G4double* vect)
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( defaultA, defaultB );
}
void G4MTRandFlat::fireArray( const G4int size, G4double* vect,
G4double lx, G4double dx )
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( lx, dx );
}
#endif
@@ -1,247 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include <cmath> // for log()
#include "G4MTRandGamma.hh"
G4MTRandGamma::~G4MTRandGamma() {
if ( deleteEngine ) delete localEngine;
}
G4double G4MTRandGamma::shoot( CLHEP::HepRandomEngine *anEngine, G4double k,
G4double lambda ) {
return genGamma( anEngine, k, lambda );
}
G4double G4MTRandGamma::shoot( G4double k, G4double lambda ) {
CLHEP::HepRandomEngine *anEngine = G4MTHepRandom::getTheEngine();
return genGamma( anEngine, k, lambda );
}
G4double G4MTRandGamma::fire( G4double k, G4double lambda ) {
return genGamma( localEngine, k, lambda );
}
void G4MTRandGamma::shootArray( const G4int size, G4double* vect,
G4double k, G4double lambda )
{
G4int i;
for (i=0; i<size; ++i)
vect[i] = shoot(k,lambda);
}
void G4MTRandGamma::shootArray( CLHEP::HepRandomEngine* anEngine,
const G4int size, G4double* vect,
G4double k, G4double lambda )
{
G4int i;
for (i=0; i<size; ++i)
vect[i] = shoot(anEngine,k,lambda);
}
void G4MTRandGamma::fireArray( const G4int size, G4double* vect)
{
G4int i;
for (i=0; i<size; ++i)
vect[i] = fire(defaultK,defaultLambda);
}
void G4MTRandGamma::fireArray( const G4int size, G4double* vect,
G4double k, G4double lambda )
{
G4int i;
for (i=0; i<size; ++i)
vect[i] = fire(k,lambda);
}
G4double G4MTRandGamma::genGamma( CLHEP::HepRandomEngine *anEngine,
G4double a, G4double lambda ) {
/*************************************************************************
* Gamma Distribution - Rejection algorithm gs combined with *
* Acceptance complement method gd *
*************************************************************************/
static G4ThreadLocal G4double aa = -1.0, aaa = -1.0, b, c, d, e, r, s, si, ss, q0,
q1 = 0.0416666664, q2 = 0.0208333723, q3 = 0.0079849875,
q4 = 0.0015746717, q5 = -0.0003349403, q6 = 0.0003340332,
q7 = 0.0006053049, q8 = -0.0004701849, q9 = 0.0001710320,
a1 = 0.333333333, a2 = -0.249999949, a3 = 0.199999867,
a4 =-0.166677482, a5 = 0.142873973, a6 =-0.124385581,
a7 = 0.110368310, a8 = -0.112750886, a9 = 0.104089866,
e1 = 1.000000000, e2 = 0.499999994, e3 = 0.166666848,
e4 = 0.041664508, e5 = 0.008345522, e6 = 0.001353826,
e7 = 0.000247453;
G4double gds,p,q,t,sign_u,u,v,w,x;
G4double v1,v2,v12;
// Check for invalid input values
if( a <= 0.0 ) return (-1.0);
if( lambda <= 0.0 ) return (-1.0);
if (a < 1.0)
{ // CASE A: Acceptance rejection algorithm gs
b = 1.0 + 0.36788794412 * a; // Step 1
for(;;)
{
p = b * anEngine->flat();
if (p <= 1.0)
{ // Step 2. Case gds <= 1
gds = std::exp(std::log(p) / a);
if (std::log(anEngine->flat()) <= -gds) return(gds/lambda);
}
else
{ // Step 3. Case gds > 1
gds = - std::log ((b - p) / a);
if (std::log(anEngine->flat()) <= ((a - 1.0) * std::log(gds))) return(gds/lambda);
}
}
}
else
{ // CASE B: Acceptance complement algorithm gd
if (a != aa)
{ // Step 1. Preparations
aa = a;
ss = a - 0.5;
s = std::sqrt(ss);
d = 5.656854249 - 12.0 * s;
}
// Step 2. Normal deviate
do {
v1 = 2.0 * anEngine->flat() - 1.0;
v2 = 2.0 * anEngine->flat() - 1.0;
v12 = v1*v1 + v2*v2;
} while ( v12 > 1.0 );
t = v1*std::sqrt(-2.0*std::log(v12)/v12);
x = s + 0.5 * t;
gds = x * x;
if (t >= 0.0) return(gds/lambda); // Immediate acceptance
u = anEngine->flat(); // Step 3. Uniform random number
if (d * u <= t * t * t) return(gds/lambda); // Squeeze acceptance
if (a != aaa)
{ // Step 4. Set-up for hat case
aaa = a;
r = 1.0 / a;
q0 = ((((((((q9 * r + q8) * r + q7) * r + q6) * r + q5) * r + q4) *
r + q3) * r + q2) * r + q1) * r;
if (a > 3.686)
{
if (a > 13.022)
{
b = 1.77;
si = 0.75;
c = 0.1515 / s;
}
else
{
b = 1.654 + 0.0076 * ss;
si = 1.68 / s + 0.275;
c = 0.062 / s + 0.024;
}
}
else
{
b = 0.463 + s - 0.178 * ss;
si = 1.235;
c = 0.195 / s - 0.079 + 0.016 * s;
}
}
if (x > 0.0) // Step 5. Calculation of q
{
v = t / (s + s); // Step 6.
if (std::fabs(v) > 0.25)
{
q = q0 - s * t + 0.25 * t * t + (ss + ss) * std::log(1.0 + v);
}
else
{
q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) *
v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
} // Step 7. Quotient acceptance
if (std::log(1.0 - u) <= q) return(gds/lambda);
}
for(;;)
{ // Step 8. Double exponential deviate t
do
{
e = -std::log(anEngine->flat());
u = anEngine->flat();
u = u + u - 1.0;
sign_u = (u > 0)? 1.0 : -1.0;
t = b + (e * si) * sign_u;
}
while (t <= -0.71874483771719); // Step 9. Rejection of t
v = t / (s + s); // Step 10. New q(t)
if (std::fabs(v) > 0.25)
{
q = q0 - s * t + 0.25 * t * t + (ss + ss) * std::log(1.0 + v);
}
else
{
q = q0 + 0.5 * t * t * ((((((((a9 * v + a8) * v + a7) * v + a6) *
v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v;
}
if (q <= 0.0) continue; // Step 11.
if (q > 0.5)
{
w = std::exp(q) - 1.0;
}
else
{
w = ((((((e7 * q + e6) * q + e5) * q + e4) * q + e3) * q + e2) *
q + e1) * q;
} // Step 12. Hat acceptance
if ( c * u * sign_u <= w * std::exp(e - 0.5 * t * t))
{
x = s + 0.5 * t;
return(x*x/lambda);
}
}
}
}
#endif
@@ -1,171 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include <cmath> // for log()
#include "G4MTRandGauss.hh"
// Initialisation of static data
G4ThreadLocal G4bool G4MTRandGauss::set_st = false;
G4ThreadLocal G4double G4MTRandGauss::nextGauss_st = 0.0;
G4MTRandGauss::~G4MTRandGauss()
{
if ( deleteEngine ) delete localEngine;
}
G4double G4MTRandGauss::operator()()
{
return fire( defaultMean, defaultStdDev );
}
G4double G4MTRandGauss::operator()( G4double mean, G4double stdDev )
{
return fire( mean, stdDev );
}
G4double G4MTRandGauss::shoot()
{
// Gaussian random numbers are generated two at the time, so every other
// time this is called we just return a number generated the time before.
if ( getFlag() ) {
setFlag(false);
G4double x = getVal();
return x;
// return getVal();
}
G4double r;
G4double v1,v2,fac,val;
CLHEP::HepRandomEngine* anEngine = G4MTHepRandom::getTheEngine();
do {
v1 = 2.0 * anEngine->flat() - 1.0;
v2 = 2.0 * anEngine->flat() - 1.0;
r = v1*v1 + v2*v2;
} while ( r > 1.0 );
fac = std::sqrt(-2.0*std::log(r)/r);
val = v1*fac;
setVal(val);
setFlag(true);
return v2*fac;
}
void G4MTRandGauss::shootArray( const G4int size, G4double* vect,
G4double mean, G4double stdDev )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(mean,stdDev);
}
G4double G4MTRandGauss::shoot( CLHEP::HepRandomEngine* anEngine )
{
// Gaussian random numbers are generated two at the time, so every other
// time this is called we just return a number generated the time before.
if ( getFlag() ) {
setFlag(false);
return getVal();
}
G4double r;
G4double v1,v2,fac,val;
do {
v1 = 2.0 * anEngine->flat() - 1.0;
v2 = 2.0 * anEngine->flat() - 1.0;
r = v1*v1 + v2*v2;
} while ( r > 1.0 );
fac = std::sqrt( -2.0*std::log(r)/r);
val = v1*fac;
setVal(val);
setFlag(true);
return v2*fac;
}
void G4MTRandGauss::shootArray( CLHEP::HepRandomEngine* anEngine,
const G4int size, G4double* vect,
G4double mean, G4double stdDev )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(anEngine,mean,stdDev);
}
G4double G4MTRandGauss::normal()
{
// Gaussian random numbers are generated two at the time, so every other
// time this is called we just return a number generated the time before.
if ( set ) {
set = false;
return nextGauss;
}
G4double r;
G4double v1,v2,fac,val;
do {
v1 = 2.0 * localEngine->flat() - 1.0;
v2 = 2.0 * localEngine->flat() - 1.0;
r = v1*v1 + v2*v2;
} while ( r > 1.0 );
fac = std::sqrt(-2.0*std::log(r)/r);
val = v1*fac;
nextGauss = val;
set = true;
return v2*fac;
}
void G4MTRandGauss::fireArray( const G4int size, G4double* vect)
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( defaultMean, defaultStdDev );
}
void G4MTRandGauss::fireArray( const G4int size, G4double* vect,
G4double mean, G4double stdDev )
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( mean, stdDev );
}
#endif
@@ -1,194 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include <cmath> // for log()
#include <CLHEP/Units/PhysicalConstants.h>
#include "G4MTRandGaussQ.hh"
G4MTRandGaussQ::~G4MTRandGaussQ()
{
}
G4MTRandGaussQ::G4MTRandGaussQ(const G4MTRandGaussQ& right)
: G4MTRandGauss(right)
{
}
G4double G4MTRandGaussQ::operator()()
{
return transformQuick(localEngine->flat()) * defaultStdDev + defaultMean;
}
G4double G4MTRandGaussQ::operator()( G4double mean, G4double stdDev )
{
return transformQuick(localEngine->flat()) * stdDev + mean;
}
void G4MTRandGaussQ::shootArray( const G4int size, G4double* vect,
G4double mean, G4double stdDev )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(mean,stdDev);
}
void G4MTRandGaussQ::shootArray( CLHEP::HepRandomEngine* anEngine,
const G4int size, G4double* vect,
G4double mean, G4double stdDev )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(anEngine,mean,stdDev);
}
void G4MTRandGaussQ::fireArray( const G4int size, G4double* vect)
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( defaultMean, defaultStdDev );
}
void G4MTRandGaussQ::fireArray( const G4int size, G4double* vect,
G4double mean, G4double stdDev )
{
for (G4int i=0; i<size; ++i)
vect[i] = fire( mean, stdDev );
}
//
// Table of errInts, for use with transform(r) and quickTransform(r)
//
// Since all these are this is static to this compilation unit only, the
// info is establised a priori and not at each invocation.
// The main data is of course the gaussQTables table; the rest is all
// bookkeeping to know what the tables mean.
#define Table0size 250
#define Table1size 1000
#define TableSize (Table0size+Table1size)
#define Table0step (2.0E-6)
#define Table1step (5.0E-4)
#define Table0scale (1.0/Table1step)
#define Table0offset 0
#define Table1offset (Table0size)
// Here comes the big (5K bytes) table, kept in a file ---
static const G4float gaussTables [TableSize] = {
#include "gaussQTables.cdat"
};
G4double G4MTRandGaussQ::transformQuick (G4double r)
{
G4double sign = +1.0; // We always compute a negative number of
// sigmas. For r > 0 we will multiply by
// sign = -1 to return a positive number.
if ( r > .5 ) {
r = 1-r;
sign = -1.0;
}
G4int index;
G4double dx;
if ( r >= Table1step ) {
index = G4int((Table1size<<1) * r); // 1 to Table1size
if (index == Table1size) return 0.0;
dx = (Table1size<<1) * r - index; // fraction of way to next bin
index += Table1offset-1;
} else if ( r > Table0step ) {
G4double rr = r * Table0scale;
index = G4int(Table0size * rr); // 1 to Table0size
dx = Table0size * rr - index; // fraction of way to next bin
index += Table0offset-1;
} else { // r <= Table0step - not in tables
return sign*transformSmall(r);
}
G4double y0 = gaussTables [index++];
G4double y1 = gaussTables [index];
return (G4float) (sign * ( y1 * dx + y0 * (1.0-dx) ));
} // transformQuick()
G4double G4MTRandGaussQ::transformSmall (G4double r)
{
// Solve for -v in the asymtotic formula
//
// errInt (-v) = exp(-v*v/2) 1 1*3 1*3*5
// ------------ * (1 - ---- + ---- - ----- + ... )
// v*sqrt(2*pi) v**2 v**4 v**6
// The value of r (=errInt(-v)) supplied is going to less than 2.0E-13,
// which is such that v < -7.25. Since the value of r is meaningful only
// to an absolute error of 1E-16 (double precision accuracy for a number
// which on the high side could be of the form 1-epsilon), computing
// v to more than 3-4 digits of accuracy is suspect; however, to ensure
// smoothness with the table generator (which uses quite a few terms) we
// also use terms up to 1*3*5* ... *13/v**14, and insist on accuracy of
// solution at the level of 1.0e-7.
// This routine is called less than one time in a million firings, so
// speed is of no concern. As a matter of technique, we terminate the
// iterations in case they would be infinite, but this should not happen.
G4double eps = 1.0e-7;
G4double guess = 7.5;
G4double v;
for ( G4int i = 1; i < 50; i++ ) {
G4double vn2 = 1.0/(guess*guess);
G4double s = -13*11*9*7*5*3 * vn2*vn2*vn2*vn2*vn2*vn2*vn2;
s += 11*9*7*5*3 * vn2*vn2*vn2*vn2*vn2*vn2;
s += -9*7*5*3 * vn2*vn2*vn2*vn2*vn2;
s += 7*5*3 * vn2*vn2*vn2*vn2;
s += -5*3 * vn2*vn2*vn2;
s += 3 * vn2*vn2 - vn2 + 1.0;
v = std::sqrt ( 2.0 * std::log ( s / (r*guess*std::sqrt(CLHEP::twopi)) ) );
if ( std::fabs(v-guess) < eps ) break;
guess = v;
}
return -v;
} // transformSmall()
#endif
@@ -1,226 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
#if __clang__
#if ((defined(G4MULTITHREADED) && !defined(G4USE_STD11)) || \
!__has_feature(cxx_thread_local)) || !__has_feature(c_atomic)
#define CLANG_NOSTDTLS
#endif
#endif
#if (defined(G4MULTITHREADED) && \
(!defined(G4USE_STD11) || (defined(CLANG_NOSTDTLS) || defined(__INTEL_COMPILER))))
#include "G4MTRandGeneral.hh"
//////////////////
// Constructors
//////////////////
G4MTRandGeneral::G4MTRandGeneral( const G4double* aProbFunc,
G4int theProbSize,
G4int IntType )
: deleteEngine(false),
nBins(theProbSize),
InterpolationType(IntType)
{
localEngine = G4MTHepRandom::getTheEngine();
prepareTable(aProbFunc);
}
G4MTRandGeneral::G4MTRandGeneral(CLHEP::HepRandomEngine& anEngine,
const G4double* aProbFunc,
G4int theProbSize,
G4int IntType )
: localEngine(&anEngine),
deleteEngine(false),
nBins(theProbSize),
InterpolationType(IntType)
{
prepareTable(aProbFunc);
}
G4MTRandGeneral::G4MTRandGeneral(CLHEP::HepRandomEngine* anEngine,
const G4double* aProbFunc,
G4int theProbSize,
G4int IntType )
: localEngine(anEngine),
deleteEngine(true),
nBins(theProbSize),
InterpolationType(IntType)
{
prepareTable(aProbFunc);
}
void G4MTRandGeneral::prepareTable(const G4double* aProbFunc)
{
//
// Private method called only by constructors. Prepares theIntegralPdf.
//
if (nBins < 1) {
std::cerr <<
"G4MTRandGeneral constructed with no bins - will use flat distribution\n";
useFlatDistribution();
return;
}
theIntegralPdf.resize(nBins+1);
theIntegralPdf[0] = 0;
G4int ptn;
G4double weight;
for ( ptn = 0; ptn<nBins; ++ptn ) {
weight = aProbFunc[ptn];
if ( weight < 0 ) {
// We can't stomach negative bin contents, they invalidate the
// search algorithm when the distribution is fired.
std::cerr <<
"G4MTRandGeneral constructed with negative-weight bin " << ptn <<
" = " << weight << " \n -- will substitute 0 weight \n";
weight = 0;
}
// std::cout << ptn << " " << weight << " " << theIntegralPdf[ptn] << "\n";
theIntegralPdf[ptn+1] = theIntegralPdf[ptn] + weight;
}
if ( theIntegralPdf[nBins] <= 0 ) {
std::cerr <<
"G4MTRandGeneral constructed nothing in bins - will use flat distribution\n";
useFlatDistribution();
return;
}
for ( ptn = 0; ptn < nBins+1; ++ptn ) {
theIntegralPdf[ptn] /= theIntegralPdf[nBins];
// std::cout << ptn << " " << theIntegralPdf[ptn] << "\n";
}
// And another useful variable is ...
oneOverNbins = 1.0 / nBins;
// One last chore:
if ( (InterpolationType != 0) && (InterpolationType != 1) ) {
std::cerr <<
"G4MTRandGeneral does not recognize IntType " << InterpolationType
<< "\n Will use type 0 (continuous linear interpolation \n";
InterpolationType = 0;
}
} // prepareTable()
void G4MTRandGeneral::useFlatDistribution()
{
//
// Private method called only by prepareTables in case of user error.
//
nBins = 1;
theIntegralPdf.resize(2);
theIntegralPdf[0] = 0;
theIntegralPdf[1] = 1;
oneOverNbins = 1.0;
return;
} // UseFlatDistribution()
//////////////////
// Destructor
//////////////////
G4MTRandGeneral::~G4MTRandGeneral()
{
if ( deleteEngine ) delete localEngine;
}
///////////////////
// mapRandom(rand)
///////////////////
G4double G4MTRandGeneral::mapRandom(G4double rand) const
{
//
// Private method to take the random (however it is created) and map it
// according to the distribution.
//
G4int nbelow = 0; // largest k such that I[k] is known to be <= rand
G4int nabove = nBins; // largest k such that I[k] is known to be > rand
G4int middle;
while (nabove > nbelow+1) {
middle = (nabove + nbelow+1)>>1;
if (rand >= theIntegralPdf[middle]) {
nbelow = middle;
} else {
nabove = middle;
}
} // after this loop, nabove is always nbelow+1 and they straddle rad:
// assert ( nabove == nbelow+1 );
// assert ( theIntegralPdf[nbelow] <= rand );
// assert ( theIntegralPdf[nabove] >= rand );
// If a defective engine produces rand=1, that will
// still give sensible results so we relax the > rand assertion
if ( InterpolationType == 1 ) {
return nbelow * oneOverNbins;
} else {
G4double binMeasure = theIntegralPdf[nabove] - theIntegralPdf[nbelow];
// binMeasure is always aProbFunc[nbelow],
// but we don't have aProbFunc any more so we subtract.
if ( binMeasure == 0 ) {
// rand lies right in a bin of measure 0. Simply return the center
// of the range of that bin. (Any value between k/N and (k+1)/N is
// equally good, in this rare case.)
return (nbelow + .5) * oneOverNbins;
}
G4double binFraction = (rand - theIntegralPdf[nbelow]) / binMeasure;
return (nbelow + binFraction) * oneOverNbins;
}
} // mapRandom(rand)
void G4MTRandGeneral::shootArray( CLHEP::HepRandomEngine* anEngine,
const G4int size, G4double* vect )
{
for (G4int i=0; i<size; ++i)
vect[i] = shoot(anEngine);
}
void G4MTRandGeneral::fireArray( const G4int size, G4double* vect )
{
for (G4int i=0; i<size; ++i)
vect[i] = fire();
}
#endif
@@ -25,11 +25,16 @@
//
//
// $Id:$
//
// G4UniformRandPool implementation
//
// Author: A.Dotti (SLAC)
// ------------------------------------------------------------
#include "G4UniformRandPool.hh"
#include "globals.hh"
#include "G4Threading.hh"
#include "G4AutoDelete.hh"
#include <climits>
#include <stdlib.h>
@@ -48,7 +53,6 @@ void destroy_pool( G4double*& buffer)
delete[] buffer;
}
#if defined(WIN32)
// No bother with WIN
void create_pool_align( G4double*& buffer , G4int ps)
@@ -67,11 +71,6 @@ void destroy_pool_align( G4double*& buffer )
//
void create_pool_align( G4double*& buffer , G4int ps)
{
//#if defined(__ICC) || (__INTEL_COMPILER)
// //INTEL optimized way
// buffer = (G4doulbe*)mm_allign(ps*sizeof(G4double),sizeof(G4double)*CHAR_BIT);
//#else
// POSIX standard way
G4int errcode = posix_memalign( (void**) &buffer ,
sizeof(G4double)*CHAR_BIT,
@@ -83,20 +82,12 @@ void create_pool_align( G4double*& buffer , G4int ps)
"Cannot allocate aligned buffer");
return;
}
//#endif
return;
}
void destroy_pool_align( G4double*& buffer )
{
//#if defined(__ICC) || (__INTEL_COMPILER)
//mm_free(buffer);
//#else
free(buffer);
//#endif
}
#endif
@@ -153,6 +144,16 @@ void G4UniformRandPool::Resize(/*PoolSize_t*/ G4int newSize )
currentIdx = 0;
}
void G4UniformRandPool::Fill( G4int howmany )
{
assert(howmany>0 && howmany <= size);
// Fill buffer with random numbers
//
G4Random::getTheEngine()->flatArray(howmany,buffer);
currentIdx = 0;
}
void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
{
assert(rnds!=0 && howmany>0);
@@ -171,7 +172,7 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
const G4int peel = howmany%size;
assert(peel<size);
// Ok from now I will get random numbers in group of "size"
// Ok from now on I will get random numbers in group of "size"
// Note that if howmany<size maxcycles == 0
//
G4int cycle = 0;
@@ -190,9 +191,9 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
// We can use memcpy of std::copy, it turns out that the two are basically
// performance-wise equivalent (expected), since in my tests memcpy is a
// little bit faster, I use that
// std::copy(buffer,buffer+size,rnds+(cycle*size));
//
memcpy(rnds+(cycle*size),buffer,sizeof(G4double)*size );
// std::copy(buffer,buffer+size,rnds+(cycle*size));
// Get a new set of numbers
//
@@ -201,7 +202,7 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
// If maxcycles>0 last think we did was to call Fill(size)
// so currentIdx == 0
// and it is guranteed that peel<size, we have enough fresh random numbers
// and it is guaranteed that peel<size, we have enough fresh random numbers
// but if maxcycles==0 currentIdx can be whatever, let's make sure we have
// enough fresh numbers
//
@@ -220,9 +221,6 @@ void G4UniformRandPool::GetMany( G4double* rnds , G4int howmany )
// Static interfaces implementing CLHEP methods
#include "G4Threading.hh"
#include "G4AutoDelete.hh"
namespace
{
G4ThreadLocal G4UniformRandPool* rndpool = 0;
File diff suppressed because it is too large Load Diff