Import Geant4 10.5.0.beta source tree
This commit is contained in:
@@ -1,170 +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:$
|
||||
//
|
||||
// Class G4MTHepRandom
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class HepRandom
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTHepRandom_h
|
||||
#define G4MTHepRandom_h 1
|
||||
|
||||
#include <CLHEP/Random/RandomEngine.h>
|
||||
#include <CLHEP/Random/RandExponential.h>
|
||||
#include <CLHEP/Random/RandFlat.h>
|
||||
#include <CLHEP/Random/RandBit.h>
|
||||
#include <CLHEP/Random/RandGamma.h>
|
||||
#include <CLHEP/Random/RandGaussQ.h>
|
||||
#include <CLHEP/Random/RandGeneral.h>
|
||||
|
||||
#include "tls.hh"
|
||||
#include "G4Types.hh"
|
||||
|
||||
class G4MTHepRandom
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4MTHepRandom();
|
||||
G4MTHepRandom(G4long seed);
|
||||
// Contructors with and without a seed using the default engine
|
||||
// (JamesRandom).
|
||||
|
||||
G4MTHepRandom(CLHEP::HepRandomEngine & algorithm);
|
||||
G4MTHepRandom(CLHEP::HepRandomEngine * algorithm);
|
||||
// Constructor taking an alternative engine as argument. If a pointer is
|
||||
// given the corresponding object will be deleted by the HepRandom
|
||||
// destructor.
|
||||
|
||||
virtual ~G4MTHepRandom();
|
||||
// Destructor
|
||||
|
||||
G4double flat();
|
||||
// Returns the flat value ( interval ]0...1[ ).
|
||||
|
||||
void flatArray(const G4int size, G4double* vect);
|
||||
// Fills "vect" array of flat random values, given the size.
|
||||
|
||||
inline G4double flat (CLHEP::HepRandomEngine* theNewEngine);
|
||||
// Returns a flat value, given a defined Random Engine.
|
||||
|
||||
inline void flatArray(CLHEP::HepRandomEngine* theNewEngine,
|
||||
const G4int size, G4double* vect);
|
||||
// Fills "vect" array of flat random values, given the size
|
||||
// and a defined Random Engine.
|
||||
|
||||
virtual G4double operator()();
|
||||
// To get a flat random number using the operator ().
|
||||
|
||||
virtual std::ostream & put ( std::ostream & os ) const;
|
||||
virtual std::istream & get ( std::istream & is );
|
||||
// Save and restore to/from streams
|
||||
|
||||
// --------------------------------------------------
|
||||
// Static member functions using the static generator
|
||||
// --------------------------------------------------
|
||||
|
||||
static void setTheSeed(G4long seed, G4int lux=3);
|
||||
// (Re)Initializes the generator with a seed.
|
||||
|
||||
static G4long getTheSeed();
|
||||
// Gets the current seed of the current generator.
|
||||
|
||||
static void setTheSeeds(const G4long* seeds, G4int aux=-1);
|
||||
// (Re)Initializes the generator with a zero terminated list of seeds.
|
||||
|
||||
static const G4long* getTheSeeds();
|
||||
// Gets the current array of seeds of the current generator.
|
||||
|
||||
static void getTheTableSeeds (G4long* seeds, G4int index);
|
||||
// Gets the array of seeds in the static seedTable at "index" position.
|
||||
|
||||
static G4MTHepRandom * getTheGenerator();
|
||||
// Return the current static generator.
|
||||
|
||||
static void setTheEngine (CLHEP::HepRandomEngine* theNewEngine);
|
||||
// To set the underlying algorithm object.
|
||||
|
||||
static CLHEP::HepRandomEngine * getTheEngine();
|
||||
// Returns a pointer to the underlying algorithm object.
|
||||
|
||||
static void saveEngineStatus( const char filename[] = "Config.conf" );
|
||||
// Saves to file the current status of the current engine.
|
||||
|
||||
static void restoreEngineStatus( const char filename[] = "Config.conf" );
|
||||
// Restores a saved status (if any) for the current engine.
|
||||
|
||||
static std::ostream& saveFullState ( std::ostream & os );
|
||||
// Saves to stream the state of the engine and cached data.
|
||||
|
||||
static std::istream& restoreFullState ( std::istream & is );
|
||||
// Restores from stream the state of the engine and cached data.
|
||||
|
||||
static std::ostream& saveDistState ( std::ostream & os ) {return os;}
|
||||
// Saves to stream the state of the cached data.
|
||||
|
||||
static std::istream& restoreDistState ( std::istream & is ) {return is;}
|
||||
// Restores from stream the state of the cached data.
|
||||
|
||||
static std::ostream& saveStaticRandomStates ( std::ostream & os );
|
||||
// Saves to stream the engine and cached data for all distributions.
|
||||
|
||||
static std::istream& restoreStaticRandomStates ( std::istream & is );
|
||||
// Restores from stream the engine and cached data for all distributions.
|
||||
|
||||
static void showEngineStatus();
|
||||
// Dumps the current engine status on screen.
|
||||
|
||||
static G4int createInstance();
|
||||
// used to initialise HepRandom::isActive and instantiate singleton
|
||||
|
||||
static G4int createInstanceOnce();
|
||||
// used to initialise HepRandom::isActive and instantiate singleton
|
||||
|
||||
private: // -------- Data members ---------
|
||||
|
||||
static G4ThreadLocal CLHEP::HepRandomEngine * theEngine;
|
||||
// The corresponding algorithm.
|
||||
|
||||
static G4ThreadLocal G4MTHepRandom * theGenerator;
|
||||
// The common shared static generator
|
||||
|
||||
static G4ThreadLocal G4int isActive;
|
||||
// Flag notifying singleton instance
|
||||
|
||||
G4bool deleteEngine;
|
||||
// True if the engine should be deleted on destruction.
|
||||
};
|
||||
|
||||
std::ostream & operator<< (std::ostream & os, const G4MTHepRandom & dist);
|
||||
std::istream & operator>> (std::istream & is, G4MTHepRandom & dist);
|
||||
|
||||
#include "G4MTHepRandom.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,39 +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:$
|
||||
//
|
||||
inline G4double G4MTHepRandom::flat(CLHEP::HepRandomEngine* theNewEngine)
|
||||
{
|
||||
return theNewEngine->flat();
|
||||
}
|
||||
|
||||
inline void G4MTHepRandom::flatArray(CLHEP::HepRandomEngine* theNewEngine,
|
||||
const G4int size, G4double* vect)
|
||||
{
|
||||
theNewEngine->flatArray(size,vect);
|
||||
}
|
||||
|
||||
@@ -1,79 +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:$
|
||||
//
|
||||
// Class G4MTRandBit
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandBit
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandBit_h
|
||||
#define G4MTRandBit_h 1
|
||||
|
||||
#include "G4MTRandFlat.hh"
|
||||
|
||||
class G4MTRandBit : public G4MTRandFlat
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline G4MTRandBit ( CLHEP::HepRandomEngine& anEngine );
|
||||
inline G4MTRandBit ( CLHEP::HepRandomEngine& anEngine, G4double width );
|
||||
inline G4MTRandBit ( CLHEP::HepRandomEngine& anEngine, G4double a, G4double b );
|
||||
inline G4MTRandBit ( CLHEP::HepRandomEngine* anEngine );
|
||||
inline G4MTRandBit ( CLHEP::HepRandomEngine* anEngine, G4double width );
|
||||
inline G4MTRandBit ( CLHEP::HepRandomEngine* anEngine, G4double a, G4double b );
|
||||
// These constructors should be used to instantiate a G4MTRandBit
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skipped using the non-static methods
|
||||
// defined below.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the G4MTRandBit destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the G4MTRandBit destructor.
|
||||
|
||||
virtual ~G4MTRandBit();
|
||||
// Destructor
|
||||
|
||||
// Other than the Bit routines, constructors, and destructor, everything is
|
||||
// simply inherited from RandFlat.
|
||||
|
||||
static G4int shootBit();
|
||||
|
||||
static G4int shootBit( CLHEP::HepRandomEngine* );
|
||||
|
||||
// Methods using the localEngine to shoot random values, by-passing
|
||||
// the static generator.
|
||||
|
||||
inline G4int fireBit();
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandBit.icc"
|
||||
|
||||
#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:$
|
||||
//
|
||||
inline G4MTRandBit::
|
||||
G4MTRandBit(CLHEP::HepRandomEngine & anEngine)
|
||||
: G4MTRandFlat (anEngine)
|
||||
{}
|
||||
|
||||
inline G4MTRandBit::
|
||||
G4MTRandBit(CLHEP::HepRandomEngine & anEngine, G4double width )
|
||||
: G4MTRandFlat (anEngine, width)
|
||||
{}
|
||||
|
||||
inline G4MTRandBit::
|
||||
G4MTRandBit(CLHEP::HepRandomEngine & anEngine, G4double a, G4double b )
|
||||
: G4MTRandFlat (anEngine, a, b)
|
||||
{}
|
||||
|
||||
inline G4MTRandBit::
|
||||
G4MTRandBit(CLHEP::HepRandomEngine * anEngine)
|
||||
: G4MTRandFlat (anEngine)
|
||||
{}
|
||||
|
||||
inline G4MTRandBit::
|
||||
G4MTRandBit(CLHEP::HepRandomEngine * anEngine, G4double width )
|
||||
: G4MTRandFlat (anEngine, width)
|
||||
{}
|
||||
|
||||
inline G4MTRandBit::
|
||||
G4MTRandBit(CLHEP::HepRandomEngine * anEngine, G4double a, G4double b )
|
||||
: G4MTRandFlat (anEngine, a, b)
|
||||
{}
|
||||
|
||||
//---------------------
|
||||
|
||||
inline G4int G4MTRandBit::fireBit()
|
||||
{
|
||||
G4double x = fire(0,1);
|
||||
G4int retval = 0;
|
||||
if (x > .5) { retval = 1; }
|
||||
return retval;
|
||||
}
|
||||
@@ -1,101 +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:$
|
||||
//
|
||||
// Class G4MTRandExponential
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandExponential
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandExponential_h
|
||||
#define G4MTRandExponential_h 1
|
||||
|
||||
#include "G4MTHepRandom.hh"
|
||||
|
||||
class G4MTRandExponential : public G4MTHepRandom
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline G4MTRandExponential ( CLHEP::HepRandomEngine& anEngine, G4double mean=1.0 );
|
||||
inline G4MTRandExponential ( CLHEP::HepRandomEngine* anEngine, G4double mean=1.0 );
|
||||
// These constructors should be used to instantiate a G4MTRandExponential
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skipped using the non-static methods
|
||||
// defined below.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the G4MTRandExponential destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the G4MTRandExponential destructor.
|
||||
|
||||
virtual ~G4MTRandExponential();
|
||||
// Destructor
|
||||
|
||||
// Static methods to shoot random values using the static generator
|
||||
|
||||
static G4double shoot();
|
||||
|
||||
static G4double shoot( G4double mean );
|
||||
|
||||
static void shootArray ( const G4int size, G4double* vect,
|
||||
G4double mean=1.0 );
|
||||
|
||||
// Static methods to shoot random values using a given engine
|
||||
// by-passing the static generator.
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anEngine );
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anEngine, G4double mean );
|
||||
|
||||
static void shootArray ( CLHEP::HepRandomEngine* anEngine, const G4int size,
|
||||
G4double* vect, G4double mean=1.0 );
|
||||
|
||||
// Methods using the localEngine to shoot random values, by-passing
|
||||
// the static generator.
|
||||
|
||||
inline G4double fire();
|
||||
|
||||
inline G4double fire( G4double mean );
|
||||
|
||||
void fireArray ( const G4int size, G4double* vect );
|
||||
void fireArray ( const G4int size, G4double* vect, G4double mean );
|
||||
|
||||
G4double operator()();
|
||||
G4double operator()( G4double mean );
|
||||
|
||||
private:
|
||||
|
||||
CLHEP::HepRandomEngine* localEngine;
|
||||
G4bool deleteEngine;
|
||||
G4double defaultMean;
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandExponential.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,62 +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:$
|
||||
//
|
||||
#include <cmath> // for log()
|
||||
|
||||
inline G4MTRandExponential::
|
||||
G4MTRandExponential(CLHEP::HepRandomEngine & anEngine, G4double mean )
|
||||
: localEngine(&anEngine), deleteEngine(false), defaultMean(mean) {}
|
||||
|
||||
inline G4MTRandExponential::
|
||||
G4MTRandExponential(CLHEP::HepRandomEngine * anEngine, G4double mean )
|
||||
: localEngine(anEngine), deleteEngine(true), defaultMean(mean) {}
|
||||
|
||||
//-------------
|
||||
|
||||
inline G4double G4MTRandExponential::shoot(CLHEP::HepRandomEngine* anEngine)
|
||||
{
|
||||
return -std::log(anEngine->flat());
|
||||
}
|
||||
|
||||
inline G4double G4MTRandExponential::shoot(CLHEP::HepRandomEngine* anEngine,
|
||||
G4double mean)
|
||||
{
|
||||
return -std::log(anEngine->flat())*mean;
|
||||
}
|
||||
|
||||
//-------------
|
||||
|
||||
inline G4double G4MTRandExponential::fire()
|
||||
{
|
||||
return -std::log(localEngine->flat())*defaultMean;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandExponential::fire(G4double mean)
|
||||
{
|
||||
return -std::log(localEngine->flat())*mean;
|
||||
}
|
||||
@@ -1,166 +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:$
|
||||
//
|
||||
// Class G4MTRandFlat
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandFlat
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandFlat_hh
|
||||
#define G4MTRandFlat_hh 1
|
||||
|
||||
#include "G4MTHepRandom.hh"
|
||||
|
||||
class G4MTRandFlat : public G4MTHepRandom
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline G4MTRandFlat ( CLHEP::HepRandomEngine& anEngine );
|
||||
inline G4MTRandFlat ( CLHEP::HepRandomEngine& anEngine, G4double width );
|
||||
inline G4MTRandFlat ( CLHEP::HepRandomEngine& anEngine, G4double a, G4double b );
|
||||
inline G4MTRandFlat ( CLHEP::HepRandomEngine* anEngine );
|
||||
inline G4MTRandFlat ( CLHEP::HepRandomEngine* anEngine, G4double width );
|
||||
inline G4MTRandFlat ( CLHEP::HepRandomEngine* anEngine, G4double a, G4double b );
|
||||
// These constructors should be used to instantiate a RandFlat
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skipped using the non-static methods
|
||||
// defined below.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the RandFlat destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the RandFlat destructor.
|
||||
|
||||
virtual ~G4MTRandFlat();
|
||||
// Destructor
|
||||
|
||||
// Static methods to shoot random values using the static generator
|
||||
|
||||
static G4double shoot();
|
||||
|
||||
static inline G4double shoot( G4double width );
|
||||
|
||||
static inline G4double shoot( G4double a, G4double b );
|
||||
|
||||
static inline G4long shootInt( G4long n );
|
||||
|
||||
static inline G4long shootInt( G4long m, G4long n );
|
||||
|
||||
static inline G4int shootBit();
|
||||
|
||||
static void shootArray ( const G4int size, G4double* vect );
|
||||
|
||||
static void shootArray ( const G4int size, G4double* vect,
|
||||
G4double lx, G4double dx );
|
||||
|
||||
// Static methods to shoot random values using a given engine
|
||||
// by-passing the static generator.
|
||||
|
||||
static inline G4double shoot ( CLHEP::HepRandomEngine* anEngine );
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anEngine, G4double width );
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anEngine,
|
||||
G4double a, G4double b );
|
||||
static inline G4long shootInt( CLHEP::HepRandomEngine* anEngine, G4long n );
|
||||
|
||||
static inline G4long shootInt( CLHEP::HepRandomEngine* anEngine, G4long m, G4long n );
|
||||
|
||||
static inline G4int shootBit( CLHEP::HepRandomEngine* );
|
||||
|
||||
static inline void shootArray ( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect );
|
||||
|
||||
static void shootArray ( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect,
|
||||
G4double lx, G4double dx );
|
||||
|
||||
// Methods using the localEngine to shoot random values, by-passing
|
||||
// the static generator.
|
||||
|
||||
inline G4double fire();
|
||||
|
||||
inline G4double fire( G4double width );
|
||||
|
||||
inline G4double fire( G4double a, G4double b );
|
||||
|
||||
inline G4long fireInt( G4long n );
|
||||
|
||||
inline G4long fireInt( G4long m, G4long n );
|
||||
|
||||
inline G4int fireBit();
|
||||
|
||||
void fireArray (const G4int size, G4double* vect);
|
||||
|
||||
void fireArray (const G4int size, G4double* vect,
|
||||
G4double lx, G4double dx);
|
||||
|
||||
G4double operator()();
|
||||
G4double operator()( G4double width );
|
||||
G4double operator()( G4double a, G4double b );
|
||||
|
||||
private:
|
||||
|
||||
// ShootBits generates an integer random number,
|
||||
// which is used by fireBit().
|
||||
// The number is stored in randomInt and firstUnusedBit
|
||||
|
||||
inline void fireBits();
|
||||
static inline void shootBits();
|
||||
static inline void shootBits(CLHEP::HepRandomEngine*);
|
||||
|
||||
// In MSB, the most significant bit of the integer random number
|
||||
// generated by ShootBits() is set.
|
||||
// Note:
|
||||
// the number of significant bits must be chosen so that
|
||||
// - an unsigned long can hold it
|
||||
// - and it should be less than the number of bits returned
|
||||
// by Shoot() which are not affected by precision problems
|
||||
// on _each_ architecture.
|
||||
// (Aim: the random generators should be machine-independent).
|
||||
|
||||
static const unsigned long MSB;
|
||||
static const G4int MSBBits;
|
||||
// These two are set up in RandFlat.cc and need not be saved/restored
|
||||
|
||||
unsigned long randomInt;
|
||||
unsigned long firstUnusedBit;
|
||||
static G4ThreadLocal unsigned long staticRandomInt;
|
||||
static G4ThreadLocal unsigned long staticFirstUnusedBit;
|
||||
|
||||
CLHEP::HepRandomEngine* localEngine;
|
||||
G4bool deleteEngine;
|
||||
G4double defaultA;
|
||||
G4double defaultB;
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandFlat.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,190 +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:$
|
||||
//
|
||||
inline G4MTRandFlat::
|
||||
G4MTRandFlat(CLHEP::HepRandomEngine & anEngine)
|
||||
: firstUnusedBit(0), localEngine(&anEngine), deleteEngine(false),
|
||||
defaultA(0.0), defaultB(1.0) {}
|
||||
|
||||
inline G4MTRandFlat::
|
||||
G4MTRandFlat(CLHEP::HepRandomEngine & anEngine, G4double width )
|
||||
: firstUnusedBit(0), localEngine(&anEngine), deleteEngine(false),
|
||||
defaultA(0.0), defaultB(width) {}
|
||||
|
||||
inline G4MTRandFlat::
|
||||
G4MTRandFlat(CLHEP::HepRandomEngine & anEngine, G4double a, G4double b )
|
||||
: firstUnusedBit(0), localEngine(&anEngine), deleteEngine(false),
|
||||
defaultA(a), defaultB(b) {}
|
||||
|
||||
inline G4MTRandFlat::
|
||||
G4MTRandFlat(CLHEP::HepRandomEngine * anEngine)
|
||||
: firstUnusedBit(0), localEngine(anEngine), deleteEngine(true),
|
||||
defaultA(0.0), defaultB(1.0) {}
|
||||
|
||||
inline G4MTRandFlat::
|
||||
G4MTRandFlat(CLHEP::HepRandomEngine * anEngine, G4double width )
|
||||
: firstUnusedBit(0), localEngine(anEngine), deleteEngine(true),
|
||||
defaultA(0.0), defaultB(width) {}
|
||||
|
||||
inline G4MTRandFlat::
|
||||
G4MTRandFlat(CLHEP::HepRandomEngine * anEngine, G4double a, G4double b )
|
||||
: firstUnusedBit(0), localEngine(anEngine), deleteEngine(true),
|
||||
defaultA(a), defaultB(b) {}
|
||||
|
||||
inline G4double G4MTRandFlat::shoot(G4double a, G4double b)
|
||||
{
|
||||
return (b-a)* shoot() + a;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandFlat::shoot(G4double width)
|
||||
{
|
||||
return width * shoot();
|
||||
}
|
||||
|
||||
inline G4long G4MTRandFlat::shootInt(G4long n)
|
||||
{
|
||||
return G4long(shoot()*G4double(n));
|
||||
}
|
||||
|
||||
inline G4long G4MTRandFlat::shootInt(G4long mLong, G4long nLong)
|
||||
{
|
||||
return G4long(shoot()*G4double(nLong-mLong)) + mLong;
|
||||
}
|
||||
|
||||
inline void G4MTRandFlat::shootBits()
|
||||
{
|
||||
const G4double factor= 2.0*MSB; // this should fit into a double!
|
||||
staticFirstUnusedBit= MSB;
|
||||
staticRandomInt= (unsigned long)(factor*shoot());
|
||||
}
|
||||
|
||||
inline G4int G4MTRandFlat::shootBit()
|
||||
{
|
||||
if (staticFirstUnusedBit==0)
|
||||
shootBits();
|
||||
unsigned long temp= staticFirstUnusedBit&staticRandomInt;
|
||||
staticFirstUnusedBit>>= 1;
|
||||
return temp!=0;
|
||||
}
|
||||
|
||||
//---------------------
|
||||
|
||||
inline G4double G4MTRandFlat::shoot(CLHEP::HepRandomEngine* anEngine)
|
||||
{
|
||||
return anEngine->flat();
|
||||
}
|
||||
|
||||
|
||||
inline G4double G4MTRandFlat::shoot(CLHEP::HepRandomEngine* anEngine,
|
||||
G4double a, G4double b)
|
||||
{
|
||||
return (b-a)* anEngine->flat() + a;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandFlat::shoot(CLHEP::HepRandomEngine* anEngine,
|
||||
G4double width)
|
||||
{
|
||||
return width * anEngine->flat();
|
||||
}
|
||||
|
||||
inline G4long G4MTRandFlat::shootInt(CLHEP::HepRandomEngine* anEngine,
|
||||
G4long n)
|
||||
{
|
||||
return G4long(anEngine->flat()*G4double(n));
|
||||
}
|
||||
|
||||
inline G4long G4MTRandFlat::shootInt(CLHEP::HepRandomEngine* anEngine,
|
||||
G4long mparam, G4long n)
|
||||
{
|
||||
return G4long(G4double(n-mparam)*anEngine->flat()) + mparam;
|
||||
}
|
||||
|
||||
inline void G4MTRandFlat::shootArray(CLHEP::HepRandomEngine* anEngine,
|
||||
const G4int size, G4double* vect)
|
||||
{
|
||||
anEngine->flatArray(size,vect);
|
||||
}
|
||||
|
||||
inline void G4MTRandFlat::shootBits(CLHEP::HepRandomEngine* engine)
|
||||
{
|
||||
const G4double factor= 2.0*MSB; // this should fit into a double!
|
||||
staticFirstUnusedBit= MSB;
|
||||
staticRandomInt= (unsigned long)(factor*shoot(engine));
|
||||
}
|
||||
|
||||
inline G4int G4MTRandFlat::shootBit(CLHEP::HepRandomEngine* engine)
|
||||
{
|
||||
if (staticFirstUnusedBit==0)
|
||||
shootBits(engine);
|
||||
unsigned long temp= staticFirstUnusedBit&staticRandomInt;
|
||||
staticFirstUnusedBit>>= 1;
|
||||
return temp!=0;
|
||||
}
|
||||
|
||||
//---------------------
|
||||
|
||||
inline G4double G4MTRandFlat::fire()
|
||||
{
|
||||
return (defaultB-defaultA)*localEngine->flat()+defaultA;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandFlat::fire(G4double a, G4double b)
|
||||
{
|
||||
return (b-a)* localEngine->flat() + a;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandFlat::fire(G4double width)
|
||||
{
|
||||
return width * localEngine->flat();
|
||||
}
|
||||
|
||||
inline G4long G4MTRandFlat::fireInt(G4long n)
|
||||
{
|
||||
return G4long(localEngine->flat()*G4double(n));
|
||||
}
|
||||
|
||||
inline G4long G4MTRandFlat::fireInt(G4long mparam, G4long n)
|
||||
{
|
||||
return G4long(localEngine->flat()*G4double(n-mparam)) + mparam;
|
||||
}
|
||||
|
||||
inline void G4MTRandFlat::fireBits()
|
||||
{
|
||||
const G4double factor= 2.0*MSB; // this should fit into a double!
|
||||
firstUnusedBit= MSB;
|
||||
randomInt= (unsigned long)(factor*localEngine->flat());
|
||||
}
|
||||
|
||||
inline G4int G4MTRandFlat::fireBit()
|
||||
{
|
||||
if (firstUnusedBit==0)
|
||||
fireBits();
|
||||
unsigned long temp= firstUnusedBit&randomInt;
|
||||
firstUnusedBit>>= 1;
|
||||
return temp!=0;
|
||||
}
|
||||
@@ -1,109 +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:$
|
||||
//
|
||||
// Class G4MTRandGamma
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandGamma
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandGamma_h
|
||||
#define G4MTRandGamma_h 1
|
||||
|
||||
#include "G4MTHepRandom.hh"
|
||||
|
||||
class G4MTRandGamma : public G4MTHepRandom
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline G4MTRandGamma ( CLHEP::HepRandomEngine& anEngine, G4double k=1.0,
|
||||
G4double lambda=1.0 );
|
||||
inline G4MTRandGamma ( CLHEP::HepRandomEngine* anEngine, G4double k=1.0,
|
||||
G4double lambda=1.0 );
|
||||
// These constructors should be used to instantiate a G4MTRandGamma
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skipped using the non-static methods
|
||||
// defined below.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the G4MTRandGamma destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the G4MTRandGamma destructor.
|
||||
|
||||
virtual ~G4MTRandGamma();
|
||||
// Destructor
|
||||
|
||||
// Static methods to shoot random values using the static generator
|
||||
|
||||
static inline G4double shoot();
|
||||
|
||||
static G4double shoot( G4double k, G4double lambda );
|
||||
|
||||
static void shootArray ( const G4int size, G4double* vect,
|
||||
G4double k=1.0, G4double lambda=1.0 );
|
||||
|
||||
// Static methods to shoot random values using a given engine
|
||||
// by-passing the static generator.
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anEngine );
|
||||
|
||||
static G4double shoot( CLHEP::HepRandomEngine* anEngine,
|
||||
G4double k, G4double lambda );
|
||||
|
||||
static void shootArray ( CLHEP::HepRandomEngine* anEngine, const G4int size,
|
||||
G4double* vect, G4double k=1.0,
|
||||
G4double lambda=1.0 );
|
||||
|
||||
// Methods using the localEngine to shoot random values, by-passing
|
||||
// the static generator.
|
||||
|
||||
inline G4double fire();
|
||||
|
||||
G4double fire( G4double k, G4double lambda );
|
||||
|
||||
void fireArray ( const G4int size, G4double* vect);
|
||||
void fireArray ( const G4int size, G4double* vect,
|
||||
G4double k, G4double lambda );
|
||||
inline G4double operator()();
|
||||
inline G4double operator()( G4double k, G4double lambda );
|
||||
|
||||
private:
|
||||
|
||||
static G4double genGamma( CLHEP::HepRandomEngine *anEngine, G4double k,
|
||||
G4double lambda );
|
||||
|
||||
CLHEP::HepRandomEngine* localEngine;
|
||||
G4bool deleteEngine;
|
||||
G4double defaultK;
|
||||
G4double defaultLambda;
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandGamma.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,57 +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:$
|
||||
//
|
||||
inline G4MTRandGamma::G4MTRandGamma(CLHEP::HepRandomEngine & anEngine, G4double k,
|
||||
G4double lambda )
|
||||
: localEngine(&anEngine), deleteEngine(false),
|
||||
defaultK(k), defaultLambda(lambda) {}
|
||||
|
||||
inline G4MTRandGamma::G4MTRandGamma(CLHEP::HepRandomEngine * anEngine, G4double k,
|
||||
G4double lambda )
|
||||
: localEngine(anEngine), deleteEngine(true),
|
||||
defaultK(k), defaultLambda(lambda) {}
|
||||
|
||||
inline G4double G4MTRandGamma::shoot() {
|
||||
return shoot( 1.0, 1.0 );
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGamma::shoot( CLHEP::HepRandomEngine* anEngine ) {
|
||||
return shoot( anEngine, 1.0, 1.0 );
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGamma::operator()() {
|
||||
return fire( defaultK, defaultLambda );
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGamma::operator()( G4double k, G4double lambda ) {
|
||||
return fire( k, lambda );
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGamma::fire() {
|
||||
return fire( defaultK, defaultLambda );
|
||||
}
|
||||
@@ -1,135 +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:$
|
||||
//
|
||||
// Class G4MTRandGauss
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandGauss
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandGauss_h
|
||||
#define G4MTRandGauss_h 1
|
||||
|
||||
#include "G4MTHepRandom.hh"
|
||||
|
||||
class G4MTRandGauss : public G4MTHepRandom
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline G4MTRandGauss ( CLHEP::HepRandomEngine& anEngine, G4double mean=0.0,
|
||||
G4double stdDev=1.0 );
|
||||
inline G4MTRandGauss ( CLHEP::HepRandomEngine* anEngine, G4double mean=0.0,
|
||||
G4double stdDev=1.0 );
|
||||
// These constructors should be used to instantiate a G4MTRandGauss
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skipped using the non-static methods
|
||||
// defined below.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the G4MTRandGauss destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the G4MTRandGauss destructor.
|
||||
|
||||
virtual ~G4MTRandGauss();
|
||||
// Destructor
|
||||
|
||||
// Static methods to shoot random values using the static generator
|
||||
|
||||
static G4double shoot();
|
||||
|
||||
static inline G4double shoot( G4double mean, G4double stdDev );
|
||||
|
||||
static void shootArray ( const G4int size, G4double* vect,
|
||||
G4double mean=0.0, G4double stdDev=1.0 );
|
||||
|
||||
// Static methods to shoot random values using a given engine
|
||||
// by-passing the static generator.
|
||||
|
||||
static G4double shoot( CLHEP::HepRandomEngine* anEngine );
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anEngine,
|
||||
G4double mean, G4double stdDev );
|
||||
|
||||
static void shootArray ( CLHEP::HepRandomEngine* anEngine, const G4int size,
|
||||
G4double* vect, G4double mean=0.0,
|
||||
G4double stdDev=1.0 );
|
||||
|
||||
// Methods using the localEngine to shoot random values, by-passing
|
||||
// the static generator.
|
||||
|
||||
G4double fire();
|
||||
|
||||
inline G4double fire( G4double mean, G4double stdDev );
|
||||
|
||||
void fireArray ( const G4int size, G4double* vect);
|
||||
void fireArray ( const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev );
|
||||
|
||||
virtual G4double operator()();
|
||||
virtual G4double operator()( G4double mean, G4double stdDev );
|
||||
|
||||
// values.
|
||||
|
||||
static G4bool getFlag() {return set_st;}
|
||||
|
||||
static void setFlag( G4bool val ) {set_st = val;}
|
||||
|
||||
G4bool getF() const {return set;}
|
||||
|
||||
void setF( G4bool val ) {set = val;}
|
||||
|
||||
// Methods overriding the base class static saveEngineStatus ones,
|
||||
// by adding extra data so that save in one program, then further gaussians,
|
||||
// will produce the identical sequence to restore in another program, then
|
||||
// generating gaussian randoms there
|
||||
|
||||
static G4double getVal() {return nextGauss_st;}
|
||||
|
||||
static void setVal( G4double nextVal ) {nextGauss_st = nextVal;}
|
||||
|
||||
G4double normal();
|
||||
|
||||
G4double defaultMean;
|
||||
G4double defaultStdDev;
|
||||
|
||||
CLHEP::HepRandomEngine* localEngine;
|
||||
|
||||
private:
|
||||
|
||||
G4bool deleteEngine, set;
|
||||
G4double nextGauss;
|
||||
|
||||
// static data
|
||||
static G4ThreadLocal G4bool set_st;
|
||||
static G4ThreadLocal G4double nextGauss_st;
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandGauss.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,62 +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:$
|
||||
//
|
||||
inline G4MTRandGauss::
|
||||
G4MTRandGauss(CLHEP::HepRandomEngine& anEngine, G4double mean, G4double stdDev )
|
||||
: defaultMean(mean), defaultStdDev(stdDev),
|
||||
localEngine(&anEngine), deleteEngine(false), set(false), nextGauss(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
inline G4MTRandGauss::
|
||||
G4MTRandGauss(CLHEP::HepRandomEngine* anEngine, G4double mean, G4double stdDev )
|
||||
: defaultMean(mean), defaultStdDev(stdDev),
|
||||
localEngine(anEngine), deleteEngine(true), set(false), nextGauss(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGauss::shoot(G4double mean, G4double stdDev)
|
||||
{
|
||||
return shoot()*stdDev + mean;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGauss::shoot(CLHEP::HepRandomEngine* anEngine,
|
||||
G4double mean, G4double stdDev)
|
||||
{
|
||||
return shoot(anEngine)*stdDev + mean;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGauss::fire()
|
||||
{
|
||||
return normal()*defaultStdDev + defaultMean;
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGauss::fire(G4double mean, G4double stdDev)
|
||||
{
|
||||
return normal()*stdDev + mean;
|
||||
}
|
||||
@@ -1,122 +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:$
|
||||
//
|
||||
// Class G4MTRandGaussQ
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandGaussQ
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandGaussQ_h
|
||||
#define G4MTRandGaussQ_h 1
|
||||
|
||||
#include "G4MTRandGauss.hh"
|
||||
|
||||
class G4MTRandGaussQ : public G4MTRandGauss
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline G4MTRandGaussQ ( CLHEP::HepRandomEngine& anEngine, G4double mean=0.0,
|
||||
G4double stdDev=1.0 );
|
||||
inline G4MTRandGaussQ ( CLHEP::HepRandomEngine* anEngine, G4double mean=0.0,
|
||||
G4double stdDev=1.0 );
|
||||
// These constructors should be used to instantiate a G4MTRandGaussQ
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skipped using the non-static methods
|
||||
// defined below.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the G4MTRandGaussQ destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the G4MTRandGaussQ destructor.
|
||||
|
||||
// Destructor
|
||||
virtual ~G4MTRandGaussQ();
|
||||
|
||||
//
|
||||
// Methods to generate Gaussian-distributed random deviates:
|
||||
//
|
||||
// If a fast good engine takes 1 usec, G4MTRandGauss::fire()
|
||||
// adds 1 usec while G4MTRandGaussQ::fire() adds only .4 usec.
|
||||
//
|
||||
|
||||
// Static methods to shoot random values using the static generator
|
||||
|
||||
static inline G4double shoot();
|
||||
|
||||
static inline G4double shoot( G4double mean, G4double stdDev );
|
||||
|
||||
static void shootArray ( const G4int size, G4double* vect,
|
||||
G4double mean=0.0, G4double stdDev=1.0 );
|
||||
|
||||
// Static methods to shoot random values using a given engine
|
||||
// by-passing the static generator.
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anotherEngine );
|
||||
|
||||
static inline G4double shoot( CLHEP::HepRandomEngine* anotherEngine,
|
||||
G4double mean, G4double stdDev );
|
||||
|
||||
|
||||
static void shootArray ( CLHEP::HepRandomEngine* anotherEngine,
|
||||
const G4int size,
|
||||
G4double* vect, G4double mean=0.0,
|
||||
G4double stdDev=1.0 );
|
||||
|
||||
// Instance methods using the localEngine to instead of the static
|
||||
// generator, and the default mean and stdDev established at construction
|
||||
|
||||
inline G4double fire();
|
||||
|
||||
inline G4double fire ( G4double mean, G4double stdDev );
|
||||
|
||||
void fireArray ( const G4int size, G4double* vect);
|
||||
void fireArray ( const G4int size, G4double* vect,
|
||||
G4double mean, G4double stdDev );
|
||||
|
||||
virtual G4double operator()();
|
||||
virtual G4double operator()( G4double mean, G4double stdDev );
|
||||
|
||||
protected:
|
||||
|
||||
static G4double transformQuick (G4double r);
|
||||
static G4double transformSmall (G4double r);
|
||||
|
||||
private:
|
||||
|
||||
// Private copy constructor. Defining it here disallows use.
|
||||
G4MTRandGaussQ(const G4MTRandGaussQ& d);
|
||||
|
||||
// All the engine info, and the default mean and sigma,
|
||||
// are in the G4MTRandGauss base class.
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandGaussQ.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,79 +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:$
|
||||
//
|
||||
G4MTRandGaussQ::
|
||||
G4MTRandGaussQ(CLHEP::HepRandomEngine & anEngine, G4double mean,
|
||||
G4double stdDev )
|
||||
: G4MTRandGauss(anEngine, mean, stdDev)
|
||||
{
|
||||
}
|
||||
|
||||
G4MTRandGaussQ::
|
||||
G4MTRandGaussQ(CLHEP::HepRandomEngine * anEngine, G4double mean,
|
||||
G4double stdDev )
|
||||
: G4MTRandGauss(anEngine, mean, stdDev)
|
||||
{
|
||||
}
|
||||
|
||||
// Getting a Gaussian deviate - static methods
|
||||
// -------------------------------------------
|
||||
|
||||
G4double G4MTRandGaussQ::shoot()
|
||||
{
|
||||
CLHEP::HepRandomEngine* anEngine = G4MTHepRandom::getTheEngine();
|
||||
return transformQuick (anEngine->flat());
|
||||
}
|
||||
|
||||
G4double G4MTRandGaussQ::shoot( CLHEP::HepRandomEngine* anotherEngine )
|
||||
{
|
||||
return transformQuick (anotherEngine->flat());
|
||||
}
|
||||
|
||||
G4double G4MTRandGaussQ::shoot(G4double mean, G4double stdDev)
|
||||
{
|
||||
return shoot()*stdDev + mean;
|
||||
}
|
||||
|
||||
G4double G4MTRandGaussQ::shoot(CLHEP::HepRandomEngine* anotherEngine,
|
||||
G4double mean, G4double stdDev)
|
||||
{
|
||||
return shoot(anotherEngine)*stdDev + mean;
|
||||
}
|
||||
|
||||
// Getting a Gaussian deviate - instance methods
|
||||
// ---------------------------------------------
|
||||
|
||||
G4double G4MTRandGaussQ::fire()
|
||||
{
|
||||
return transformQuick(localEngine->flat()) * defaultStdDev + defaultMean;
|
||||
}
|
||||
|
||||
G4double G4MTRandGaussQ::fire(G4double mean, G4double stdDev)
|
||||
{
|
||||
return transformQuick(localEngine->flat()) * stdDev + mean;
|
||||
}
|
||||
@@ -1,127 +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:$
|
||||
//
|
||||
// Class G4MTRandGeneral
|
||||
//
|
||||
// Modified version with MT extensions
|
||||
// of corresponding CLHEP class RandGeneral
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MTRandGeneral_h
|
||||
#define G4MTRandGeneral_h 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "G4MTHepRandom.hh"
|
||||
|
||||
class G4MTRandGeneral : public G4MTHepRandom
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
G4MTRandGeneral ( const G4double* aProbFunc,
|
||||
G4int theProbSize,
|
||||
G4int IntType=0 );
|
||||
G4MTRandGeneral ( CLHEP::HepRandomEngine& anEngine,
|
||||
const G4double* aProbFunc,
|
||||
G4int theProbSize,
|
||||
G4int IntType=0 );
|
||||
G4MTRandGeneral ( CLHEP::HepRandomEngine* anEngine,
|
||||
const G4double* aProbFunc,
|
||||
G4int theProbSize,
|
||||
G4int IntType=0 );
|
||||
// These constructors should be used to instantiate a G4MTRandGeneral
|
||||
// distribution object defining a local engine for it.
|
||||
// The static generator will be skiped by using the non-static methods
|
||||
// defined below. In case no engine is specified in the constructor, the
|
||||
// default engine used by the static generator is applied.
|
||||
// If the engine is passed by pointer the corresponding engine object
|
||||
// will be deleted by the G4MTRandGeneral destructor.
|
||||
// If the engine is passed by reference the corresponding engine object
|
||||
// will not be deleted by the G4MTRandGeneral destructor.
|
||||
// The probability distribution function (Pdf) must be provided by the user
|
||||
// as an array of positive real number. The array size must also be
|
||||
// provided. The Pdf doesn't need to be normalized to 1.
|
||||
// if IntType = 0 ( default value ) a uniform random number is
|
||||
// generated using the engine. The uniform number is then transformed
|
||||
// to the user's distribution using the cumulative probability
|
||||
// distribution constructed from his histogram. The cumulative
|
||||
// distribution is inverted using a binary search for the nearest
|
||||
// bin boundary and a linear interpolation within the
|
||||
// bin. G4MTRandGeneral therefore generates a constant density within
|
||||
// each bin.
|
||||
// if IntType = 1 no interpolation is performed and the result is a
|
||||
// discrete distribution.
|
||||
|
||||
virtual ~G4MTRandGeneral();
|
||||
// Destructor
|
||||
|
||||
// Methods to shoot random values using the static generator
|
||||
// N.B.: The methods are NOT static since they use nonstatic members
|
||||
// theIntegralPdf & nBins
|
||||
|
||||
inline G4double shoot();
|
||||
|
||||
inline void shootArray ( const G4int size, G4double* vect);
|
||||
|
||||
// Methods to shoot random values using a given engine
|
||||
// by-passing the static generator.
|
||||
|
||||
G4double shoot( CLHEP::HepRandomEngine* anEngine );
|
||||
|
||||
void shootArray ( CLHEP::HepRandomEngine* anEngine, const G4int size,
|
||||
G4double* vect );
|
||||
|
||||
// Methods using the localEngine to shoot random values, by-passing
|
||||
// the static generator.
|
||||
|
||||
G4double fire();
|
||||
|
||||
void fireArray ( const G4int size, G4double* vect);
|
||||
|
||||
G4double operator()();
|
||||
|
||||
private:
|
||||
|
||||
CLHEP::HepRandomEngine* localEngine;
|
||||
G4bool deleteEngine;
|
||||
std::vector<G4double> theIntegralPdf;
|
||||
G4int nBins;
|
||||
G4double oneOverNbins;
|
||||
G4int InterpolationType;
|
||||
|
||||
// Private methods to factor out replicated implementation sections
|
||||
void prepareTable(const G4double* aProbFunc);
|
||||
void useFlatDistribution();
|
||||
G4double mapRandom(G4double rand) const;
|
||||
|
||||
};
|
||||
|
||||
#include "G4MTRandGeneral.icc"
|
||||
|
||||
#endif
|
||||
@@ -1,54 +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:$
|
||||
//
|
||||
inline G4double G4MTRandGeneral::fire()
|
||||
{
|
||||
G4double rand = localEngine->flat();
|
||||
return mapRandom(rand);
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGeneral::shoot()
|
||||
{
|
||||
return fire();
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGeneral::operator() ()
|
||||
{
|
||||
return fire();
|
||||
}
|
||||
|
||||
inline G4double G4MTRandGeneral::shoot( CLHEP::HepRandomEngine* anEngine )
|
||||
{
|
||||
G4double rand = anEngine->flat();
|
||||
return mapRandom(rand);
|
||||
}
|
||||
|
||||
inline void G4MTRandGeneral::shootArray( const G4int size, G4double* vect )
|
||||
{
|
||||
fireArray(size, vect);
|
||||
}
|
||||
@@ -32,8 +32,10 @@
|
||||
// ------------------------------------------------------------
|
||||
// Class description:
|
||||
//
|
||||
//
|
||||
// Class implementing a pool of random numbers filled according
|
||||
// to specified fixed size (default 1024).
|
||||
|
||||
// Author: A.Dotti (SLAC)
|
||||
// ------------------------------------------------------------
|
||||
#ifndef G4UNIFORMRANDPOOL_HH
|
||||
#define G4UNIFORMRANDPOOL_HH
|
||||
@@ -72,7 +74,7 @@ class G4UniformRandPool
|
||||
|
||||
private:
|
||||
|
||||
inline void Fill( G4int howmany );
|
||||
void Fill( G4int howmany );
|
||||
|
||||
private:
|
||||
|
||||
@@ -98,14 +100,4 @@ inline /*PoolSize_t*/ G4int G4UniformRandPool::GetPoolSize() const
|
||||
return size;
|
||||
}
|
||||
|
||||
inline void G4UniformRandPool::Fill( G4int howmany )
|
||||
{
|
||||
assert(howmany>0 && howmany <= size);
|
||||
|
||||
// Fill buffer with random numbers
|
||||
//
|
||||
G4Random::getTheEngine()->flatArray(howmany,buffer);
|
||||
currentIdx = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,57 +24,13 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: Randomize.hh 96593 2016-04-25 10:12:49Z gcosmo $
|
||||
// $Id: Randomize.hh 108829 2018-03-09 12:44:00Z gcosmo $
|
||||
//
|
||||
#ifndef randomize_h
|
||||
#define randomize_h 1
|
||||
|
||||
#include <CLHEP/Random/Randomize.h>
|
||||
|
||||
#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))))
|
||||
|
||||
// MT needs special Random Number distribution classes
|
||||
//
|
||||
#include "G4MTHepRandom.hh"
|
||||
#include "G4MTRandBit.hh"
|
||||
#include "G4MTRandExponential.hh"
|
||||
#include "G4MTRandFlat.hh"
|
||||
#include "G4MTRandGamma.hh"
|
||||
#include "G4MTRandGauss.hh"
|
||||
#include "G4MTRandGaussQ.hh"
|
||||
#include "G4MTRandGeneral.hh"
|
||||
|
||||
// NOTE: G4RandStat MT-version is missing, but actually currently
|
||||
// never used in the G4 source
|
||||
//
|
||||
#define G4RandFlat G4MTRandFlat
|
||||
#define G4RandBit G4MTRandBit
|
||||
#define G4RandGamma G4MTRandGamma
|
||||
#define G4RandGauss G4MTRandGaussQ
|
||||
#define G4RandExponential G4MTRandExponential
|
||||
#define G4RandGeneral G4MTRandGeneral
|
||||
#define G4Random G4MTHepRandom
|
||||
|
||||
#define G4UniformRand() G4MTHepRandom::getTheEngine()->flat()
|
||||
//
|
||||
//#include "G4UniformRandPool.hh"
|
||||
//#define G4UniformRand() G4UniformRandPool::flat()
|
||||
// Currently not be used in G4 source
|
||||
//
|
||||
#define G4RandFlatArray G4MTRandFlat::shootArray
|
||||
#define G4RandFlatInt G4MTRandFlat::shootInt
|
||||
#define G4RandGeneralTmp G4MTRandGeneral
|
||||
|
||||
#else // Sequential mode or supporting C++11 standard
|
||||
|
||||
// Distributions used ...
|
||||
//
|
||||
#include <CLHEP/Random/RandFlat.h>
|
||||
@@ -96,5 +52,4 @@
|
||||
|
||||
#define G4UniformRand() CLHEP::HepRandom::getTheEngine()->flat()
|
||||
|
||||
#endif // G4MULTITHREADED
|
||||
#endif // randomize_h
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# Generated on : 24/9/2010
|
||||
#
|
||||
# $Id: sources.cmake 89393 2015-04-09 07:45:40Z gcosmo $
|
||||
# $Id: sources.cmake 108829 2018-03-09 12:44:00Z gcosmo $
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@@ -25,39 +25,6 @@ include_directories(${CMAKE_SOURCE_DIR}/source/global/management/include)
|
||||
# Define the Geant4 Module.
|
||||
#
|
||||
|
||||
# The following are needed only in
|
||||
# multi-threaded builds
|
||||
set (_mtheaders "")
|
||||
set (_mtsrcs "")
|
||||
if(GEANT4_BUILD_MULTITHREADED)
|
||||
set(_mtheaders ${_mtheaders}
|
||||
G4MTHepRandom.hh
|
||||
G4MTHepRandom.icc
|
||||
G4MTRandBit.hh
|
||||
G4MTRandBit.icc
|
||||
G4MTRandExponential.hh
|
||||
G4MTRandExponential.icc
|
||||
G4MTRandFlat.hh
|
||||
G4MTRandFlat.icc
|
||||
G4MTRandGamma.hh
|
||||
G4MTRandGamma.icc
|
||||
G4MTRandGauss.hh
|
||||
G4MTRandGauss.icc
|
||||
G4MTRandGaussQ.hh
|
||||
G4MTRandGaussQ.icc
|
||||
G4MTRandGeneral.hh
|
||||
G4MTRandGeneral.icc )
|
||||
set(_mtsrcs ${_mtsrcs}
|
||||
G4MTHepRandom.cc
|
||||
G4MTRandBit.cc
|
||||
G4MTRandExponential.cc
|
||||
G4MTRandFlat.cc
|
||||
G4MTRandGamma.cc
|
||||
G4MTRandGauss.cc
|
||||
G4MTRandGaussQ.cc
|
||||
G4MTRandGeneral.cc )
|
||||
endif()
|
||||
|
||||
include(Geant4MacroDefineModule)
|
||||
GEANT4_DEFINE_MODULE(NAME G4heprandom
|
||||
HEADERS
|
||||
@@ -66,9 +33,7 @@ GEANT4_DEFINE_MODULE(NAME G4heprandom
|
||||
G4RandomTools.hh
|
||||
Randomize.hh
|
||||
G4UniformRandPool.hh
|
||||
${_mtheaders}
|
||||
SOURCES
|
||||
${_mtsrcs}
|
||||
G4Poisson.cc
|
||||
G4UniformRandPool.cc
|
||||
GRANULAR_DEPENDENCIES
|
||||
|
||||
@@ -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
|
||||
@@ -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
+120
-3
@@ -17,15 +17,132 @@ committal in the SVN repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
February 12, 2018 G.Cosmo (global-V10-03-12)
|
||||
June 6, 2018 Jonathan Madsen (global-V10-04-18)
|
||||
- Added G4TiMemory.hh which defines an dummy initializer and empty macros when
|
||||
TiMemory is disabled and includes the TiMemory headers and defines an
|
||||
initializer when built with TiMemory support
|
||||
- Removed "#define times ostimes" from G4Timer.hh and G4SliceTimer.hh
|
||||
- conflicts with TiMemory and this is left over from a conflict that
|
||||
no longer exists (see global-01-00-03 from 1999)
|
||||
- Removed corresponding "#undef times" from G4Timer.cc and G4SliceTimer.cc
|
||||
- Added TiMemory libraries and includes to sources.cmake
|
||||
|
||||
May 18, 2018 Gabriele Cosmo (global-V10-04-17)
|
||||
- Moved G4Exception functions to inline and extracted banner front/end
|
||||
strings for use in Qt parsing.
|
||||
|
||||
May 17, 2018 Jonathan Madsen (global-V10-04-16)
|
||||
- Removed G4GLOB_DLL from G4CacheReference<G4double>
|
||||
|
||||
May 17, 2018 Jonathan Madsen (global-V10-04-15)
|
||||
- Updated "thread-local-static-var" model to
|
||||
"function-returning-thread-local-static-reference" model
|
||||
which fixes Windows DLL + MT
|
||||
|
||||
March 23, 2018 Mihaly Novak (global-V10-04-14)
|
||||
- Increased accuracy of G4Pow::A13 in the most critical [1/4,4] interval.
|
||||
|
||||
March 22, 2018 Gabriele Cosmo (global-V10-04-13)
|
||||
- Avoid exporting symbols for Windows DLLs in multi-threaded builds.
|
||||
|
||||
March 21, 2018 Gabriele Cosmo (global-V10-04-12)
|
||||
- Moved test80 to unit tests in HEPRandom/test module and renamed testRngMT.
|
||||
|
||||
March 9, 2018 Gabriele Cosmo (global-V10-04-11)
|
||||
- Removed obsolete MT wrappers for random numbers, no longer necessary.
|
||||
Simplified definition of G4Random types in Randomize.hh accordingly.
|
||||
- Full support for thread-local storage on clang (also MacOS clang) now
|
||||
enabled; updated tls.hh definitions accordingly; removed use of the
|
||||
G4USE_STD11 flag, now always enabled by default.
|
||||
- Minor code cleanup in G4UniformRandPool.
|
||||
|
||||
March 7, 2018 Jonathan Madsen (global-V10-04-10)
|
||||
- Replaced erroneous "id_type" return type for G4DummyThread::get_id()
|
||||
with correct "id" type.
|
||||
|
||||
March 6, 2018 Jonathan Madsen (global-V10-04-09)
|
||||
- updated G4cout_p and G4cerr_p to point to std::cout and std::cerr before
|
||||
and after library load. G4cout before G4RunManager creation has been seen to
|
||||
fail on Windows
|
||||
- Improvement to G4AutoLock in non-MT mode + bug fix (void try_lock() ->
|
||||
bool try_lock()) plus error handling within G4AutoLock if static mutex
|
||||
is attempted to be used at application cleanup (previously handled in
|
||||
G4Cache)
|
||||
- using atomics in G4Cache
|
||||
- Define G4ThisThread, G4Promise, G4Future, and G4SharedFuture in G4Threading
|
||||
the promises and futures are not currently used except for in upcoming
|
||||
RNG testing but will be used in future
|
||||
- G4TypeMutex and G4RecursiveTypeMutex now accept an index, e.g.
|
||||
G4AutoLock l(G4TypeMutex<G4SomeClass>(0)) and
|
||||
G4AutoLock l(G4TypeMutex<G4SomeClass>(1))
|
||||
- G4DummyThread typedef std::thread::id as id instead of id_type
|
||||
|
||||
March 6, 2018 Gabriele Cosmo (global-V10-04-08)
|
||||
- Use thread_local keyword on Windows, instead of __declspec(thread) in tls.hh.
|
||||
- Removed no longer necessary windefs.hh header.
|
||||
|
||||
February 21, 2018 Jonathan Madsen (global-V10-04-07)
|
||||
- Overloaded G4AutoLock member functions in serial mode to not
|
||||
execute locking/unlocking
|
||||
- Fixed std::system_error in G4Cache where destructor tries
|
||||
to use a static G4Mutex that has already been deleted by cleanup
|
||||
which is a non-critical error related to a singleton memory leak
|
||||
- Returned some functionality in G4Threading to dummy types such
|
||||
as G4MUTEXLOCK and G4MUTEXUNLOCK do not actually lock
|
||||
and G4Thread is a dummy thread that executes upon construction
|
||||
|
||||
February 19, 2018 Jonathan Madsen (global-V10-04-06)
|
||||
- Added G4TypeMutex<T> and G4TypeRecursiveMutex<T> function to threading
|
||||
for safely obtaining a static mutex that is unique to the template type T
|
||||
- Replaced static G4Mutex in G4Cache<T> with calls to G4TypeMutex<G4Cache<T>>
|
||||
function calls to safely initialize mutexes on Windows
|
||||
|
||||
February 14, 2018 Jonathan Madsen (global-V10-04-05)
|
||||
- G4THREADSLEEP had an extra space before paramter field rendering the
|
||||
macro invalid. This was fixed
|
||||
- Sequential clang builds were emitting -Wunused-private-field warning
|
||||
in G4MTBarrier. Modified G4CONDITION macros to fix this
|
||||
|
||||
February 13, 2018 Jonathan Madsen (global-V10-04-04)
|
||||
- Simplified G4Threading by not ifdef'ing out G4Mutex
|
||||
It was determined the average time to lock and unlock a mutex in
|
||||
single-thread mode is ~5 nanoseconds in release mode. Therefore, it
|
||||
was determined the mutex locking is not a concern for performance in
|
||||
non-MT mode. This fixes issues with G4Mutex and G4AutoLock in
|
||||
global-V10-04-03
|
||||
- Extended G4TemplateAutoLock to take advantage of the features
|
||||
std::unique_lock offers
|
||||
- migrated G4Timer real (wall) time to use std::chrono::high_precision_clock
|
||||
from C++11
|
||||
|
||||
February 12, 2018 Jonathan Madsen (global-V10-04-03)
|
||||
- G4Threading - replaced POSIX threading with C++11 threading
|
||||
- std::condition_variable
|
||||
- std::mutex + std::recursive_mutex
|
||||
- std::thread
|
||||
- many of the former macros are now dummy macros (e.g. G4MUTEXINIT,
|
||||
G4MUTEX_INITIALIZER, etc.)
|
||||
- G4GetPidId() -> uses std::this_thread::get_id()
|
||||
- G4GetNumberOfCores() -> uses std::thread::hardware_concurrency()
|
||||
- Updated pin affinity
|
||||
- Removed G4THREADSELF (not used, no C++11 platform-independent equivalent)
|
||||
- G4AutoLock is now a thin wrapper around std::unique_lock providing previous
|
||||
functionality + more features (e.g. try_lock, try_lock_until, etc.)
|
||||
- Added G4RecursiveAutoLock for recursive mutexes
|
||||
- Expanded DEFINED_PPC and DEFINED_INTEL in G4FPEDetection (warning in GCC 7+)
|
||||
- G4MTBarrier: removed WIN32 specifics, updated G4CONDITIONWAIT to use
|
||||
G4AutoLock (std::unique_lock) instead of G4Mutex, removed G4MUTEX_INITIALIZER
|
||||
from constructor
|
||||
|
||||
February 12, 2018 G.Cosmo (global-V10-04-02)
|
||||
- G4StateManager: move static method SetVerboseLevel() to be non inline.
|
||||
|
||||
February 9, 2018 M.Asai
|
||||
February 9, 2018 M.Asai (global-V10-04-01)
|
||||
- G4MTcoutDestination.cc blocks G4cout from worker threads while spplication
|
||||
is in G4State_Init instead of G4State_Idle.
|
||||
- G4StateManager has a new method to set verbosity and print the state change.
|
||||
|
||||
December 19, 2017 G.Cosmo
|
||||
December 19, 2017 G.Cosmo (global-V10-04-00)
|
||||
- Fixed self-consistency in G4ReferenceCountedHandle header (missing #include).
|
||||
Added missing #ifdef guard in G4CacheDetails header; code formatting.
|
||||
Thanks to Raphael Isemann for reporting these.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: GNUmakefile 108486 2018-02-15 14:47:25Z gcosmo $
|
||||
# $Id: GNUmakefile 108071 2017-12-19 15:30:19Z gcosmo $
|
||||
# --------------------------------------------------------------
|
||||
# GNUmakefile for global management. Gabriele Cosmo, 26/9/96.
|
||||
# --------------------------------------------------------------
|
||||
|
||||
@@ -36,82 +36,529 @@
|
||||
//
|
||||
// #include "G4Threading.hh"
|
||||
// #include "G4AutoLock.hh"
|
||||
// /* somehwere */
|
||||
// G4Mutex aMutex = G4MUTEX_INITIALIZER;
|
||||
// /*
|
||||
// somewhere else:
|
||||
// The G4AutoLock instance will automatically unlock the mutex when it
|
||||
// goes out of scope, lock and unlock method are anyway available for
|
||||
// explicit handling of mutex lock. */
|
||||
// G4AutoLock l(&aMutex);
|
||||
// ProtectedCode();
|
||||
// l.unlock(); //explicit unlock
|
||||
// UnprotectedCode();
|
||||
// l.lock(); //explicit lock
|
||||
//
|
||||
// Note that G4AutoLock is defined also for a sequential Geant4 build,
|
||||
// but has no effect.
|
||||
|
||||
// // defined somewhere -- static so all threads see the same mutex
|
||||
// static G4Mutex aMutex;
|
||||
//
|
||||
// // somewhere else:
|
||||
// // The G4AutoLock instance will automatically unlock the mutex when it
|
||||
// // goes out of scope. One typically defines the scope within { } if
|
||||
// // there is thread-safe code following the auto-lock
|
||||
//
|
||||
// {
|
||||
// G4AutoLock l(&aMutex);
|
||||
// ProtectedCode();
|
||||
// }
|
||||
//
|
||||
// UnprotectedCode();
|
||||
//
|
||||
// // When ProtectedCode() is calling a function that also tries to lock
|
||||
// // a normal G4AutoLock + G4Mutex will "deadlock". In other words, the
|
||||
// // the mutex in the ProtectedCode() function will wait forever to
|
||||
// // acquire the lock that is being held by the function that called
|
||||
// // ProtectedCode(). In this situation, use a G4RecursiveAutoLock +
|
||||
// // G4RecursiveMutex, e.g.
|
||||
//
|
||||
// // defined somewhere -- static so all threads see the same mutex
|
||||
// static G4RecursiveMutex aRecursiveMutex;
|
||||
//
|
||||
// // this function is sometimes called directly and sometimes called
|
||||
// // from SomeFunction_B(), which also locks the mutex
|
||||
// void SomeFunction_A()
|
||||
// {
|
||||
// // when called from SomeFunction_B(), a G4Mutex + G4AutoLock will
|
||||
// // deadlock
|
||||
// G4RecursiveAutoLock l(&aRecursiveMutex);
|
||||
// // do something
|
||||
// }
|
||||
//
|
||||
// void SomeFunction_B()
|
||||
// {
|
||||
//
|
||||
// {
|
||||
// G4RecursiveAutoLock l(&aRecursiveMutex);
|
||||
// SomeFunction_A();
|
||||
// }
|
||||
//
|
||||
// UnprotectedCode();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// ---------------------------------------------------------------
|
||||
// Author: Andrea Dotti (15 Feb 2013): First Implementation
|
||||
//
|
||||
// Update: Jonathan Madsen (9 Feb 2018): Replaced custom implementation
|
||||
// with inheritance from C++11 unique_lock, which inherits the
|
||||
// following member functions:
|
||||
//
|
||||
// - unique_lock(unique_lock&& other) noexcept;
|
||||
// - explicit unique_lock(mutex_type& m);
|
||||
// - unique_lock(mutex_type& m, std::defer_lock_t t) noexcept;
|
||||
// - unique_lock(mutex_type& m, std::try_to_lock_t t);
|
||||
// - unique_lock(mutex_type& m, std::adopt_lock_t t);
|
||||
//
|
||||
// - template <typename Rep, typename Period>
|
||||
// unique_lock(mutex_type& m,
|
||||
// const std::chrono::duration<Rep,Period>& timeout_duration);
|
||||
//
|
||||
// - template<typename Clock, typename Duration>
|
||||
// unique_lock(mutex_type& m,
|
||||
// const std::chrono::time_point<Clock,Duration>& timeout_time);
|
||||
//
|
||||
// - void lock();
|
||||
// - void unlock();
|
||||
// - bool try_lock();
|
||||
//
|
||||
// - template <typename Rep, typename Period>
|
||||
// bool try_lock_for(const std::chrono::duration<Rep,Period>&);
|
||||
//
|
||||
// - template <typename Rep, typename Period>
|
||||
// bool try_lock_until(const std::chrono::time_point<Clock,Duration>&);
|
||||
//
|
||||
// - void swap(unique_lock& other) noexcept;
|
||||
// - mutex_type* release() noexcept;
|
||||
// - mutex_type* mutex() const noexcept;
|
||||
// - bool owns_lock() const noexcept;
|
||||
// - explicit operator bool() const noexcept;
|
||||
// - unique_lock& operator=(unique_lock&& other);
|
||||
//
|
||||
// ---------------------------------------------------------------
|
||||
//
|
||||
// Note that G4AutoLock is defined also for a sequential Geant4 build but below
|
||||
// regarding implementation (also found in G4Threading.hh)
|
||||
//
|
||||
//
|
||||
// NOTE ON GEANT4 SERIAL BUILDS AND MUTEX/UNIQUE_LOCK
|
||||
// ==================================================
|
||||
//
|
||||
// G4Mutex and G4RecursiveMutex are always C++11 std::mutex types
|
||||
// however, in serial mode, using G4MUTEXLOCK and G4MUTEXUNLOCK on these
|
||||
// types has no effect -- i.e. the mutexes are not actually locked or unlocked
|
||||
//
|
||||
// Additionally, when a G4Mutex or G4RecursiveMutex is used with G4AutoLock
|
||||
// and G4RecursiveAutoLock, respectively, these classes also suppressing
|
||||
// the locking and unlocking of the mutex. Regardless of the build type,
|
||||
// G4AutoLock and G4RecursiveAutoLock inherit from std::unique_lock<std::mutex>
|
||||
// and std::unique_lock<std::recursive_mutex>, respectively. This means
|
||||
// that in situations (such as is needed by the analysis category), the
|
||||
// G4AutoLock and G4RecursiveAutoLock can be passed to functions requesting
|
||||
// a std::unique_lock. Within these functions, since std::unique_lock
|
||||
// member functions are not virtual, they will not retain the dummy locking
|
||||
// and unlocking behavior
|
||||
// --> An example of this behavior can be found below
|
||||
//
|
||||
// Jonathan R. Madsen (February 21, 2018)
|
||||
//
|
||||
/**
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void print_threading()
|
||||
{
|
||||
#ifdef G4MULTITHREADED
|
||||
std::cout << "\nUsing G4MULTITHREADED version..." << std::endl;
|
||||
#else
|
||||
std::cout << "\nUsing G4SERIAL version..." << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
typedef std::unique_lock<std::mutex> unique_lock_t;
|
||||
// functions for casting G4AutoLock to std::unique_lock to demonstrate
|
||||
// that G4AutoLock is NOT polymorphic
|
||||
void as_unique_lock(unique_lock_t* lock) { lock->lock(); }
|
||||
void as_unique_unlock(unique_lock_t* lock) { lock->unlock(); }
|
||||
|
||||
//============================================================================//
|
||||
|
||||
void run(const uint64_t& n)
|
||||
{
|
||||
// sync the threads a bit
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
// get two mutexes to avoid deadlock when l32 actually locks
|
||||
G4AutoLock l32(G4TypeMutex<int32_t>(), std::defer_lock);
|
||||
G4AutoLock l64(G4TypeMutex<int64_t>(), std::defer_lock);
|
||||
|
||||
// when serial: will not execute std::unique_lock::lock() because
|
||||
// it overrides the member function
|
||||
l32.lock();
|
||||
// regardless of serial or MT: will execute std::unique_lock::lock()
|
||||
// because std::unique_lock::lock() is not virtual
|
||||
as_unique_lock(&l64);
|
||||
|
||||
std::cout << "Running iteration " << n << "..." << std::endl;
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
// execute some work
|
||||
template <typename thread_type = std::thread>
|
||||
void exec(uint64_t n)
|
||||
{
|
||||
// get two mutexes to avoid deadlock when l32 actually locks
|
||||
G4AutoLock l32(G4TypeMutex<int32_t>(), std::defer_lock);
|
||||
G4AutoLock l64(G4TypeMutex<int64_t>(), std::defer_lock);
|
||||
|
||||
std::vector<thread_type*> threads(n, nullptr);
|
||||
for(uint64_t i = 0; i < n; ++i)
|
||||
{
|
||||
threads[i] = new thread_type();
|
||||
*(threads[i]) = std::move(thread_type(run, i));
|
||||
}
|
||||
|
||||
// when serial: will not execute std::unique_lock::lock() because
|
||||
// it overrides the member function
|
||||
l32.lock();
|
||||
// regardless of serial or MT: will execute std::unique_lock::lock()
|
||||
// because std::unique_lock::lock() is not virtual
|
||||
as_unique_lock(&l64);
|
||||
|
||||
std::cout << "Joining..." << std::endl;
|
||||
|
||||
// when serial: will not execute std::unique_lock::unlock() because
|
||||
// it overrides the member function
|
||||
l32.unlock();
|
||||
// regardless of serial or MT: will execute std::unique_lock::unlock()
|
||||
// because std::unique_lock::unlock() is not virtual
|
||||
as_unique_unlock(&l64);
|
||||
|
||||
// NOTE ABOUT UNLOCKS:
|
||||
// in MT, commenting out either
|
||||
// l32.unlock();
|
||||
// or
|
||||
// as_unique_unlock(&l64);
|
||||
// creates a deadlock; in serial, commenting out
|
||||
// as_unique_unlock(&l64);
|
||||
// creates a deadlock but commenting out
|
||||
// l32.unlock();
|
||||
// does not
|
||||
|
||||
// clean up and join
|
||||
for(uint64_t i = 0; i < n; ++i)
|
||||
{
|
||||
threads[i]->join();
|
||||
delete threads[i];
|
||||
}
|
||||
threads.clear();
|
||||
}
|
||||
|
||||
//============================================================================//
|
||||
|
||||
int main()
|
||||
{
|
||||
print_threading();
|
||||
|
||||
uint64_t n = 30;
|
||||
std::cout << "\nRunning with real threads...\n" << std::endl;
|
||||
exec<std::thread>(n);
|
||||
std::cout << "\nRunning with fake threads...\n" << std::endl;
|
||||
exec<G4DummyThread>(n);
|
||||
|
||||
}
|
||||
|
||||
**/
|
||||
|
||||
#ifndef G4AUTOLOCK_HH
|
||||
#define G4AUTOLOCK_HH
|
||||
|
||||
#include "G4Threading.hh"
|
||||
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <system_error>
|
||||
#include <iostream>
|
||||
|
||||
// Note: Note that G4TemplateAutoLock by itself is not thread-safe and
|
||||
// cannot be shared among threads due to the locked switch
|
||||
//
|
||||
template<class M, typename L, typename U>
|
||||
class G4TemplateAutoLock
|
||||
template <typename _Mutex_t>
|
||||
class G4TemplateAutoLock : public std::unique_lock<_Mutex_t>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
//------------------------------------------------------------------------//
|
||||
// Some useful typedefs
|
||||
//------------------------------------------------------------------------//
|
||||
typedef std::unique_lock<_Mutex_t> unique_lock_t;
|
||||
typedef G4TemplateAutoLock<_Mutex_t> this_type;
|
||||
typedef typename unique_lock_t::mutex_type mutex_type;
|
||||
|
||||
G4TemplateAutoLock(M* mtx, L l, U u) : locked(false), _m(mtx), _l(l), _u(u)
|
||||
public:
|
||||
//------------------------------------------------------------------------//
|
||||
// STL-consistent reference form constructors
|
||||
//------------------------------------------------------------------------//
|
||||
|
||||
// reference form is consistent with STL lock_guard types
|
||||
// Locks the associated mutex by calling m.lock(). The behavior is
|
||||
// undefined if the current thread already owns the mutex except when
|
||||
// the mutex is recursive
|
||||
G4TemplateAutoLock(mutex_type& _mutex)
|
||||
: unique_lock_t(_mutex, std::defer_lock)
|
||||
{
|
||||
lock();
|
||||
// call termination-safe locking. if serial, this call has no effect
|
||||
_lock_deferred();
|
||||
}
|
||||
|
||||
virtual ~G4TemplateAutoLock()
|
||||
// Tries to lock the associated mutex by calling
|
||||
// m.try_lock_for(_timeout_duration). Blocks until specified
|
||||
// _timeout_duration has elapsed or the lock is acquired, whichever comes
|
||||
// first. May block for longer than _timeout_duration.
|
||||
template <typename Rep, typename Period>
|
||||
G4TemplateAutoLock(mutex_type& _mutex,
|
||||
const std::chrono::duration<Rep, Period>&
|
||||
_timeout_duration)
|
||||
: unique_lock_t(_mutex, std::defer_lock)
|
||||
{
|
||||
unlock();
|
||||
// call termination-safe locking. if serial, this call has no effect
|
||||
_lock_deferred(_timeout_duration);
|
||||
}
|
||||
|
||||
inline void unlock() {
|
||||
if ( !locked ) return;
|
||||
_u(_m);
|
||||
locked = false;
|
||||
// Tries to lock the associated mutex by calling
|
||||
// m.try_lock_until(_timeout_time). Blocks until specified _timeout_time has
|
||||
// been reached or the lock is acquired, whichever comes first. May block
|
||||
// for longer than until _timeout_time has been reached.
|
||||
template<typename Clock, typename Duration>
|
||||
G4TemplateAutoLock(mutex_type& _mutex,
|
||||
const std::chrono::time_point<Clock, Duration>&
|
||||
_timeout_time)
|
||||
: unique_lock_t(_mutex, std::defer_lock)
|
||||
{
|
||||
// call termination-safe locking. if serial, this call has no effect
|
||||
_lock_deferred(_timeout_time);
|
||||
}
|
||||
|
||||
inline void lock() {
|
||||
if ( locked ) return;
|
||||
_l(_m);
|
||||
locked = true;
|
||||
// Does not lock the associated mutex.
|
||||
G4TemplateAutoLock(mutex_type& _mutex, std::defer_lock_t _lock) noexcept
|
||||
: unique_lock_t(_mutex, _lock)
|
||||
{ }
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
// Tries to lock the associated mutex without blocking by calling
|
||||
// m.try_lock(). The behavior is undefined if the current thread already
|
||||
// owns the mutex except when the mutex is recursive.
|
||||
G4TemplateAutoLock(mutex_type& _mutex, std::try_to_lock_t _lock)
|
||||
: unique_lock_t(_mutex, _lock)
|
||||
{ }
|
||||
|
||||
// Assumes the calling thread already owns m
|
||||
G4TemplateAutoLock(mutex_type& _mutex, std::adopt_lock_t _lock)
|
||||
: unique_lock_t(_mutex, _lock)
|
||||
{ }
|
||||
|
||||
#else
|
||||
|
||||
// serial dummy version (initializes unique_lock but does not lock)
|
||||
G4TemplateAutoLock(mutex_type& _mutex, std::try_to_lock_t)
|
||||
: unique_lock_t(_mutex, std::defer_lock)
|
||||
{ }
|
||||
|
||||
// serial dummy version (initializes unique_lock but does not lock)
|
||||
G4TemplateAutoLock(mutex_type& _mutex, std::adopt_lock_t)
|
||||
: unique_lock_t(_mutex, std::defer_lock)
|
||||
{ }
|
||||
|
||||
#endif // defined(G4MULTITHREADED)
|
||||
|
||||
public:
|
||||
//------------------------------------------------------------------------//
|
||||
// Backwards compatibility versions (constructor with pointer to mutex)
|
||||
//------------------------------------------------------------------------//
|
||||
G4TemplateAutoLock(mutex_type* _mutex)
|
||||
: unique_lock_t(*_mutex, std::defer_lock)
|
||||
{
|
||||
// call termination-safe locking. if serial, this call has no effect
|
||||
_lock_deferred();
|
||||
}
|
||||
|
||||
private:
|
||||
G4TemplateAutoLock(mutex_type* _mutex, std::defer_lock_t _lock) noexcept
|
||||
: unique_lock_t(*_mutex, _lock)
|
||||
{ }
|
||||
|
||||
// Disable copy and assignement operators
|
||||
//
|
||||
G4TemplateAutoLock( const G4TemplateAutoLock& rhs );
|
||||
G4TemplateAutoLock& operator= ( const G4TemplateAutoLock& rhs );
|
||||
#if defined(G4MULTITHREADED)
|
||||
|
||||
G4TemplateAutoLock(mutex_type* _mutex, std::try_to_lock_t _lock)
|
||||
: unique_lock_t(*_mutex, _lock)
|
||||
{ }
|
||||
|
||||
G4TemplateAutoLock(mutex_type* _mutex, std::adopt_lock_t _lock)
|
||||
: unique_lock_t(*_mutex, _lock)
|
||||
{ }
|
||||
|
||||
#else // NOT defined(G4MULTITHREADED) -- i.e. serial
|
||||
|
||||
G4TemplateAutoLock(mutex_type* _mutex, std::try_to_lock_t)
|
||||
: unique_lock_t(*_mutex, std::defer_lock)
|
||||
{ }
|
||||
|
||||
G4TemplateAutoLock(mutex_type* _mutex, std::adopt_lock_t)
|
||||
: unique_lock_t(*_mutex, std::defer_lock)
|
||||
{ }
|
||||
|
||||
#endif // defined(G4MULTITHREADED)
|
||||
|
||||
public:
|
||||
//------------------------------------------------------------------------//
|
||||
// Non-constructor overloads
|
||||
//------------------------------------------------------------------------//
|
||||
|
||||
#if defined(G4MULTITHREADED)
|
||||
|
||||
// overload nothing
|
||||
|
||||
#else // NOT defined(G4MULTITHREADED) -- i.e. serial
|
||||
|
||||
// override unique lock member functions to keep from locking/unlocking
|
||||
// but does not override in polymorphic usage
|
||||
void lock() { }
|
||||
void unlock() { }
|
||||
bool try_lock() { return true; }
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
bool try_lock_for(const std::chrono::duration<Rep, Period>&)
|
||||
{ return true; }
|
||||
|
||||
template <typename Clock, typename Duration>
|
||||
bool try_lock_until(const std::chrono::time_point<Clock, Duration>&)
|
||||
{ return true; }
|
||||
|
||||
void swap(this_type& other) noexcept { std::swap(*this, other); }
|
||||
bool owns_lock() const noexcept { return false; }
|
||||
|
||||
// no need to overload
|
||||
//explicit operator bool() const noexcept;
|
||||
//this_type& operator=(this_type&& other);
|
||||
//mutex_type* release() noexcept;
|
||||
//mutex_type* mutex() const noexcept;
|
||||
|
||||
#endif // defined(G4MULTITHREADED)
|
||||
|
||||
private:
|
||||
// helpful macros
|
||||
#define _is_stand_mutex(_Tp) (std::is_same<_Tp, G4Mutex>::value)
|
||||
#define _is_recur_mutex(_Tp) (std::is_same<_Tp, G4RecursiveMutex>::value)
|
||||
#define _is_other_mutex(_Tp) (! _is_stand_mutex(_Tp) && ! _is_recur_mutex(_Tp) )
|
||||
|
||||
template <typename _Tp = _Mutex_t,
|
||||
typename std::enable_if<_is_stand_mutex(_Tp), int>::type = 0>
|
||||
std::string GetTypeString() { return "G4AutoLock<G4Mutex>"; }
|
||||
|
||||
template <typename _Tp = _Mutex_t,
|
||||
typename std::enable_if<_is_recur_mutex(_Tp), int>::type = 0>
|
||||
std::string GetTypeString() { return "G4AutoLock<G4RecursiveMutex>"; }
|
||||
|
||||
template <typename _Tp = _Mutex_t,
|
||||
typename std::enable_if<_is_other_mutex(_Tp), int>::type = 0>
|
||||
std::string GetTypeString() { return "G4AutoLock<UNKNOWN_MUTEX>"; }
|
||||
|
||||
// pollution is bad
|
||||
#undef _is_stand_mutex
|
||||
#undef _is_recur_mutex
|
||||
#undef _is_other_mutex
|
||||
|
||||
// used in _lock_deferred chrono variants to avoid ununsed-variable warning
|
||||
template <typename _Tp>
|
||||
void suppress_unused_variable(const _Tp&) { }
|
||||
|
||||
//========================================================================//
|
||||
// NOTE on _lock_deferred(...) variants:
|
||||
// a system_error in lock means that the mutex is unavailable
|
||||
// we want to throw the error that comes from locking an unavailable
|
||||
// mutex so that we know there is a memory leak
|
||||
// if the mutex is valid, this will hold until the other thread
|
||||
// finishes
|
||||
|
||||
// sometimes certain destructors use locks, this isn't an issue unless
|
||||
// the object is leaked. When this occurs, the application finalization
|
||||
// (i.e. the real or implied "return 0" part of main) will call destructors
|
||||
// on Geant4 object after some static mutex variables are deleted, leading
|
||||
// to the error code (typically on Clang compilers):
|
||||
// libc++abi.dylib: terminating with uncaught exception of type
|
||||
// std::__1::system_error: mutex lock failed: Invalid argument
|
||||
// this function protects against this failure until such a time that
|
||||
// these issues have been resolved
|
||||
|
||||
//========================================================================//
|
||||
// standard locking
|
||||
inline void _lock_deferred()
|
||||
{
|
||||
#if defined(G4MULTITHREADED)
|
||||
try { this->unique_lock_t::lock(); }
|
||||
catch (std::system_error& e) { PrintLockErrorMessage(e); }
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================//
|
||||
// Tries to lock the associated mutex by calling
|
||||
// m.try_lock_for(_timeout_duration). Blocks until specified
|
||||
// _timeout_duration has elapsed or the lock is acquired, whichever comes
|
||||
// first. May block for longer than _timeout_duration.
|
||||
template <typename Rep, typename Period>
|
||||
void _lock_deferred(const std::chrono::duration<Rep, Period>&
|
||||
_timeout_duration)
|
||||
{
|
||||
#if defined(G4MULTITHREADED)
|
||||
try { this->unique_lock_t::try_lock_for(_timeout_duration); }
|
||||
catch (std::system_error& e) { PrintLockErrorMessage(e); }
|
||||
#else
|
||||
suppress_unused_variable(_timeout_duration);
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================//
|
||||
// Tries to lock the associated mutex by calling
|
||||
// m.try_lock_until(_timeout_time). Blocks until specified _timeout_time has
|
||||
// been reached or the lock is acquired, whichever comes first. May block
|
||||
// for longer than until _timeout_time has been reached.
|
||||
template<typename Clock, typename Duration>
|
||||
void _lock_deferred(const std::chrono::time_point<Clock, Duration>&
|
||||
_timeout_time)
|
||||
{
|
||||
#if defined(G4MULTITHREADED)
|
||||
try { this->unique_lock_t::try_lock_until(_timeout_time); }
|
||||
catch (std::system_error& e) { PrintLockErrorMessage(e); }
|
||||
#else
|
||||
suppress_unused_variable(_timeout_time);
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================//
|
||||
// the message for what mutex lock fails due to deleted static mutex
|
||||
// at termination
|
||||
void PrintLockErrorMessage(std::system_error& e)
|
||||
{
|
||||
// use std::cout/std::endl to avoid include dependencies
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
// the error that comes from locking an unavailable mutex
|
||||
#if defined(G4VERBOSE)
|
||||
cout << "Non-critical error: mutex lock failure in "
|
||||
<< GetTypeString<mutex_type>() << ". "
|
||||
<< "If the app is terminating, Geant4 failed to "
|
||||
<< "delete an allocated resource and a Geant4 destructor is "
|
||||
<< "being called after the statics were destroyed. \n\t--> "
|
||||
<< "Exception: [code: " << e.code() << "] caught: "
|
||||
<< e.what() << endl;
|
||||
#else
|
||||
suppress_unused_variable(e);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
G4bool locked;
|
||||
M* _m;
|
||||
L _l;
|
||||
U _u;
|
||||
};
|
||||
|
||||
struct G4ImpMutexAutoLock
|
||||
: public G4TemplateAutoLock<G4Mutex,thread_lock,thread_unlock>
|
||||
{
|
||||
G4ImpMutexAutoLock(G4Mutex* mtx)
|
||||
: G4TemplateAutoLock<G4Mutex, thread_lock, thread_unlock>
|
||||
(mtx, &G4MUTEXLOCK, &G4MUTEXUNLOCK) {}
|
||||
};
|
||||
typedef G4ImpMutexAutoLock G4AutoLock;
|
||||
// -------------------------------------------------------------------------- //
|
||||
//
|
||||
// Use the non-template types below:
|
||||
// - G4AutoLock with G4Mutex
|
||||
// - G4RecursiveAutoLock with G4RecursiveMutex
|
||||
//
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
typedef G4TemplateAutoLock<G4Mutex> G4AutoLock;
|
||||
typedef G4TemplateAutoLock<G4RecursiveMutex> G4RecursiveAutoLock;
|
||||
|
||||
// provide abbriviated type if another mutex type is desired to be used
|
||||
// aside from above
|
||||
template <typename _Tp> using G4TAutoLock = G4TemplateAutoLock<_Tp>;
|
||||
|
||||
#endif //G4AUTOLOCK_HH
|
||||
|
||||
@@ -77,6 +77,13 @@
|
||||
//Debug this code
|
||||
//#define g4cdebug 1
|
||||
|
||||
#include <system_error>
|
||||
#include <atomic>
|
||||
|
||||
// also included in G4CacheDetails.hh
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
//Thread Local storage details are in this header file
|
||||
#include "G4CacheDetails.hh"
|
||||
|
||||
@@ -109,18 +116,18 @@ public:
|
||||
G4Cache& operator=(const G4Cache& rhs);
|
||||
|
||||
protected:
|
||||
const int& GetId() const { return id; }
|
||||
private:
|
||||
int id;
|
||||
mutable G4CacheReference<value_type> theCache;
|
||||
static G4Mutex gMutex;
|
||||
static unsigned int instancesctr;
|
||||
static unsigned int dstrctr;
|
||||
const int& GetId() const { return id; }
|
||||
|
||||
inline value_type& GetCache() const {
|
||||
theCache.Initialize(id);
|
||||
return theCache.GetCache(id);
|
||||
}
|
||||
private:
|
||||
int id;
|
||||
mutable G4CacheReference<value_type> theCache;
|
||||
static std::atomic<unsigned int> instancesctr;
|
||||
static std::atomic<unsigned int> dstrctr;
|
||||
|
||||
inline value_type& GetCache() const {
|
||||
theCache.Initialize(id);
|
||||
return theCache.GetCache(id);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -215,7 +222,7 @@ using std::endl;
|
||||
template<class V>
|
||||
G4Cache<V>::G4Cache()
|
||||
{
|
||||
G4AutoLock l(&gMutex);
|
||||
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
|
||||
id = instancesctr++;
|
||||
#ifdef g4cdebug
|
||||
cout<<"G4Cache id: "<<id<<endl;
|
||||
@@ -228,7 +235,7 @@ G4Cache<V>::G4Cache(const G4Cache<V>& rhs)
|
||||
//Copy is special, we need to copy the content
|
||||
//of the cache, not the cache object
|
||||
if ( this == &rhs ) return;
|
||||
G4AutoLock l(&gMutex);
|
||||
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
|
||||
id = instancesctr++;
|
||||
//Force copy of cached data
|
||||
V aCopy = rhs.GetCache();
|
||||
@@ -254,8 +261,8 @@ G4Cache<V>& G4Cache<V>::operator=(const G4Cache<V>& rhs)
|
||||
template<class V>
|
||||
G4Cache<V>::G4Cache(const V& v)
|
||||
{
|
||||
G4AutoLock l(&gMutex);
|
||||
id = instancesctr++;
|
||||
G4AutoLock l(G4TypeMutex<G4Cache<V>>());
|
||||
id = instancesctr++;
|
||||
Put(v);
|
||||
#ifdef g4cdebug
|
||||
cout<<"G4Cache id: "<<id<<" "<<endl;
|
||||
@@ -268,13 +275,38 @@ G4Cache<V>::~G4Cache()
|
||||
#ifdef g4cdebug
|
||||
cout<<"~G4Cache id: "<<id<<" "<<endl;
|
||||
#endif
|
||||
G4AutoLock l(&gMutex);
|
||||
++dstrctr;
|
||||
// don't automatically lock --> wait until we can catch an error
|
||||
// without scoping the G4AutoLock
|
||||
G4AutoLock l(G4TypeMutex<G4Cache<V>>(), std::defer_lock);
|
||||
// sometimes the mutex is unavailable in destructors so
|
||||
// try to lock the associated mutex, but catch if fails
|
||||
try
|
||||
{
|
||||
// a system_error in lock means that the mutex is unavailable
|
||||
// we want to throw the error that comes from locking an unavailable
|
||||
// mutex so that we know there is a memory leak
|
||||
// if the mutex is valid, this will hold until the other thread finishes
|
||||
l.lock();
|
||||
}
|
||||
catch (std::system_error& e)
|
||||
{
|
||||
// the error that comes from locking an unavailable mutex
|
||||
#ifdef G4VERBOSE
|
||||
G4cout << "Non-critical error: mutex lock failure in ~G4Cache<"
|
||||
<< typeid(V).name() << ">. "
|
||||
<< "If the RunManagerKernel has been deleted, it failed to "
|
||||
<< "delete an allocated resource and this destructor is being "
|
||||
<< "called after the statics were destroyed." << G4endl;
|
||||
G4cout << "Exception: [code: " << e.code() << "] caught: "
|
||||
<< e.what() << G4endl;
|
||||
#endif
|
||||
}
|
||||
++dstrctr;
|
||||
G4bool last = ( dstrctr == instancesctr );
|
||||
theCache.Destroy(id,last);
|
||||
theCache.Destroy(id, last);
|
||||
if (last) {
|
||||
instancesctr = 0;
|
||||
dstrctr = 0;
|
||||
instancesctr.store(0);
|
||||
dstrctr.store(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,13 +324,10 @@ V G4Cache<V>::Pop()
|
||||
{ return GetCache(); }
|
||||
|
||||
template<class V>
|
||||
unsigned int G4Cache<V>::instancesctr = 0;
|
||||
std::atomic<unsigned int> G4Cache<V>::instancesctr(0);
|
||||
|
||||
template<class V>
|
||||
unsigned int G4Cache<V>::dstrctr = 0;
|
||||
|
||||
template<class V>
|
||||
G4Mutex G4Cache<V>::gMutex = G4MUTEX_INITIALIZER;
|
||||
std::atomic<unsigned int> G4Cache<V>::dstrctr(0);
|
||||
|
||||
//========== Implementation: G4VectorCache<V>
|
||||
template<class V>
|
||||
@@ -388,10 +417,8 @@ G4MapCache<K,V>::~G4MapCache()
|
||||
}
|
||||
|
||||
template<class K, class V>
|
||||
std::pair<typename G4MapCache<K,V>::iterator,G4bool> G4MapCache<K,V>::Insert(
|
||||
const K& k,
|
||||
const V& v
|
||||
)
|
||||
std::pair<typename G4MapCache<K,V>::iterator,G4bool>
|
||||
G4MapCache<K,V>::Insert(const K& k, const V& v)
|
||||
{
|
||||
return G4Cache<map_type>::Get().insert( std::pair<key_type,value_type>(k,v) );
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ template<class VALTYPE> class G4CacheReference
|
||||
// std::vector in case of stored objects and allow use of
|
||||
// specialized allocators
|
||||
|
||||
static G4ThreadLocal cache_container *cache;
|
||||
static cache_container*& cache();
|
||||
};
|
||||
|
||||
// Template specialization for pointers
|
||||
@@ -118,7 +118,7 @@ template<class VALTYPE> class G4CacheReference<VALTYPE*>
|
||||
|
||||
private:
|
||||
typedef std::vector<VALTYPE*> cache_container;
|
||||
static G4ThreadLocal cache_container *cache;
|
||||
static cache_container*& cache();
|
||||
};
|
||||
|
||||
// Template specialization for probably the most used case: double
|
||||
@@ -137,7 +137,7 @@ template<> class G4CacheReference<G4double>
|
||||
private:
|
||||
|
||||
typedef std::vector<G4double> cache_container;
|
||||
G4GLOB_DLL static G4ThreadLocal std::vector<G4double> *cache;
|
||||
static G4GLOB_DLL cache_container*& cache();
|
||||
};
|
||||
|
||||
|
||||
@@ -152,47 +152,47 @@ template<class V>
|
||||
void G4CacheReference<V>::Initialize( unsigned int id )
|
||||
{
|
||||
#ifdef g4cdebug
|
||||
if ( cache == 0 )
|
||||
if ( cache() == 0 )
|
||||
cout<<"Generic template"<<endl;
|
||||
#endif
|
||||
|
||||
// Create cache container
|
||||
if ( cache == 0 )
|
||||
cache = new cache_container;
|
||||
if ( cache->size() <= id )
|
||||
cache->resize(id+1,static_cast<V*>(0));
|
||||
if ( (*cache)[id] == 0 )
|
||||
(*cache)[id]=new V;
|
||||
if ( cache() == 0 )
|
||||
cache() = new cache_container;
|
||||
if ( cache()->size() <= id )
|
||||
cache()->resize(id+1,static_cast<V*>(0));
|
||||
if ( (*cache())[id] == 0 )
|
||||
(*cache())[id]=new V;
|
||||
}
|
||||
|
||||
template<class V>
|
||||
void G4CacheReference<V>::Destroy( unsigned int id, G4bool last )
|
||||
{
|
||||
if ( cache )
|
||||
if ( cache() )
|
||||
{
|
||||
#ifdef g4cdebug
|
||||
cout<<"Destroying element"<<id<<" is last?"<<last<<endl;
|
||||
#endif
|
||||
if ( cache->size() < id )
|
||||
if ( cache()->size() < id )
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Internal fatal error. Invalid G4Cache size (requested id: "
|
||||
<< id << " but cache has size: "<<cache->size();
|
||||
<< id << " but cache has size: "<< cache()->size();
|
||||
msg << " Possibly client created G4Cache object in a thread and"
|
||||
<< " tried to delete it from another thread!";
|
||||
G4Exception("G4CacheReference<V>::Destroy", "Cache001",
|
||||
FatalException, msg);
|
||||
return;
|
||||
}
|
||||
if ( cache->size() > id && (*cache)[id] )
|
||||
if ( cache()->size() > id && (*cache())[id] )
|
||||
{
|
||||
delete (*cache)[id];
|
||||
(*cache)[id]=0;
|
||||
delete (*cache())[id];
|
||||
(*cache())[id]=0;
|
||||
}
|
||||
if (last)
|
||||
{
|
||||
delete cache;
|
||||
cache = 0;
|
||||
delete cache();
|
||||
cache() = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,12 +200,16 @@ void G4CacheReference<V>::Destroy( unsigned int id, G4bool last )
|
||||
template<class V>
|
||||
V& G4CacheReference<V>::GetCache( unsigned int id ) const
|
||||
{
|
||||
return *(cache->operator[](id));
|
||||
return *(cache()->operator[](id));
|
||||
}
|
||||
|
||||
template<class V>
|
||||
G4ThreadLocal typename
|
||||
G4CacheReference<V>::cache_container * G4CacheReference<V>::cache = 0;
|
||||
typename G4CacheReference<V>::cache_container*&
|
||||
G4CacheReference<V>::cache()
|
||||
{
|
||||
G4ThreadLocalStatic cache_container* _instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
//======= Implementation: G4CacheReference<V*>
|
||||
//============================================
|
||||
@@ -214,45 +218,45 @@ template<class V>
|
||||
void G4CacheReference<V*>::Initialize( unsigned int id )
|
||||
{
|
||||
#ifdef g4cdebug
|
||||
if ( cache == 0 )
|
||||
if ( cache() == 0 )
|
||||
cout<<"Pointer template"<<endl;
|
||||
#endif
|
||||
if ( cache == 0 )
|
||||
cache = new cache_container;
|
||||
if ( cache->size() <= id )
|
||||
cache->resize(id+1,static_cast<V*>(0));
|
||||
if ( cache() == 0 )
|
||||
cache() = new cache_container;
|
||||
if ( cache()->size() <= id )
|
||||
cache()->resize(id+1,static_cast<V*>(0));
|
||||
}
|
||||
|
||||
template<class V>
|
||||
inline void G4CacheReference<V*>::Destroy( unsigned int id , G4bool last )
|
||||
{
|
||||
if ( cache )
|
||||
if ( cache() )
|
||||
{
|
||||
#ifdef g4cdebug
|
||||
cout << "Destroying element" << id << " is last?" << last
|
||||
<< "-Pointer template specialization-" << endl;
|
||||
#endif
|
||||
if ( cache->size() < id )
|
||||
if ( cache()->size() < id )
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Internal fatal error. Invalid G4Cache size (requested id: "
|
||||
<< id << " but cache has size: " << cache->size();
|
||||
<< id << " but cache has size: " << cache()->size();
|
||||
msg << " Possibly client created G4Cache object in a thread and"
|
||||
<< " tried to delete it from another thread!";
|
||||
G4Exception("G4CacheReference<V*>::Destroy", "Cache001",
|
||||
FatalException, msg);
|
||||
return;
|
||||
}
|
||||
if ( cache->size() > id && (*cache)[id] )
|
||||
if ( cache()->size() > id && (*cache())[id] )
|
||||
{
|
||||
// Ownership is for client
|
||||
// delete (*cache)[id];
|
||||
(*cache)[id]=0;
|
||||
(*cache())[id]=0;
|
||||
}
|
||||
if (last )
|
||||
{
|
||||
delete cache;
|
||||
cache = 0;
|
||||
delete cache();
|
||||
cache() = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -260,12 +264,16 @@ inline void G4CacheReference<V*>::Destroy( unsigned int id , G4bool last )
|
||||
template<class V>
|
||||
V*& G4CacheReference<V*>::GetCache(unsigned int id) const
|
||||
{
|
||||
return (cache->operator[](id));
|
||||
return (cache()->operator[](id));
|
||||
}
|
||||
|
||||
template<class V>
|
||||
G4ThreadLocal typename
|
||||
G4CacheReference<V*>::cache_container * G4CacheReference<V*>::cache = 0;
|
||||
typename G4CacheReference<V*>::cache_container*&
|
||||
G4CacheReference<V*>::cache()
|
||||
{
|
||||
G4ThreadLocalStatic cache_container* _instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
//======= Implementation: G4CacheReference<double>
|
||||
//============================================
|
||||
@@ -275,10 +283,10 @@ void G4CacheReference<G4double>::Initialize( unsigned int id )
|
||||
#ifdef g4cdebug
|
||||
cout<<"Specialized template for G4double"<<endl;
|
||||
#endif
|
||||
if ( cache == 0 )
|
||||
cache = new cache_container;
|
||||
if ( cache->size() <= id )
|
||||
cache->resize(id+1,static_cast<G4double>(0));
|
||||
if ( cache() == 0 )
|
||||
cache() = new cache_container;
|
||||
if ( cache()->size() <= id )
|
||||
cache()->resize(id+1,static_cast<G4double>(0));
|
||||
}
|
||||
|
||||
#ifdef g4cdebug
|
||||
@@ -287,20 +295,20 @@ void G4CacheReference<G4double>::Destroy( unsigned int id , G4bool last)
|
||||
void G4CacheReference<G4double>::Destroy( unsigned int /*id*/ , G4bool last)
|
||||
#endif
|
||||
{
|
||||
if ( cache && last )
|
||||
if ( cache() && last )
|
||||
{
|
||||
#ifdef g4cdebug
|
||||
cout << "Destroying element" << id << " is last?" << last
|
||||
<< "-Pointer template specialization-" << endl;
|
||||
#endif
|
||||
delete cache;
|
||||
cache = 0;
|
||||
delete cache();
|
||||
cache() = 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4double& G4CacheReference<G4double>::GetCache(unsigned int id) const
|
||||
{
|
||||
return cache->operator[](id);
|
||||
return cache()->operator[](id);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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:$
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
// G4Exception
|
||||
//
|
||||
// Global error function prints string to G4cerr (or G4cout in case of
|
||||
// warning). May abort program according to severity.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#ifndef G4EXCEPTION_HH
|
||||
#define G4EXCEPTION_HH
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4String.hh"
|
||||
#include "G4StateManager.hh"
|
||||
#include "G4VExceptionHandler.hh"
|
||||
|
||||
typedef std::ostringstream G4ExceptionDescription;
|
||||
|
||||
inline const G4String G4ExceptionErrBannerStart()
|
||||
{
|
||||
return "\n-------- EEEE ------- G4Exception-START -------- EEEE -------\n";
|
||||
}
|
||||
inline const G4String G4ExceptionWarnBannerStart()
|
||||
{
|
||||
return "\n-------- WWWW ------- G4Exception-START -------- WWWW -------\n";
|
||||
}
|
||||
|
||||
inline const G4String G4ExceptionErrBannerEnd()
|
||||
{
|
||||
return "\n-------- EEEE ------- G4Exception-END -------- EEEE -------\n";
|
||||
}
|
||||
inline const G4String G4ExceptionWarnBannerEnd()
|
||||
{
|
||||
return "\n-------- WWWW ------- G4Exception-END -------- WWWW -------\n";
|
||||
}
|
||||
|
||||
inline void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
const char* description)
|
||||
{
|
||||
G4VExceptionHandler* exceptionHandler
|
||||
= G4StateManager::GetStateManager()->GetExceptionHandler();
|
||||
G4bool toBeAborted = true;
|
||||
if(exceptionHandler)
|
||||
{
|
||||
toBeAborted = exceptionHandler
|
||||
->Notify(originOfException,exceptionCode,severity,description);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const G4String& es_banner = G4ExceptionErrBannerStart();
|
||||
static const G4String& ee_banner = G4ExceptionErrBannerEnd();
|
||||
static const G4String& ws_banner = G4ExceptionWarnBannerStart();
|
||||
static const G4String& we_banner = G4ExceptionWarnBannerEnd();
|
||||
std::ostringstream message;
|
||||
message << "\n*** ExceptionHandler is not defined ***\n"
|
||||
<< "*** G4Exception : " << exceptionCode << G4endl
|
||||
<< " issued by : " << originOfException << G4endl
|
||||
<< description << G4endl;
|
||||
switch(severity)
|
||||
{
|
||||
case FatalException:
|
||||
G4cerr << es_banner << message.str() << "*** Fatal Exception ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
case FatalErrorInArgument:
|
||||
G4cerr << es_banner << message.str() << "*** Fatal Error In Argument ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
case RunMustBeAborted:
|
||||
G4cerr << es_banner << message.str() << "*** Run Must Be Aborted ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
case EventMustBeAborted:
|
||||
G4cerr << es_banner << message.str() << "*** Event Must Be Aborted ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
default:
|
||||
G4cout << ws_banner << message.str()
|
||||
<< "*** This is just a warning message. ***"
|
||||
<< we_banner << G4endl;
|
||||
toBeAborted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(toBeAborted)
|
||||
{
|
||||
if(G4StateManager::GetStateManager()->SetNewState(G4State_Abort))
|
||||
{
|
||||
G4cerr << G4endl << "*** G4Exception: Aborting execution ***" << G4endl;
|
||||
abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cerr << G4endl << "*** G4Exception: Abortion suppressed ***"
|
||||
<< G4endl << "*** No guarantee for further execution ***" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
G4ExceptionDescription & description)
|
||||
{
|
||||
G4String des = description.str();
|
||||
G4Exception(originOfException, exceptionCode, severity, des.c_str());
|
||||
}
|
||||
|
||||
inline void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
G4ExceptionDescription & description,
|
||||
const char* comments)
|
||||
{
|
||||
description << comments << G4endl;
|
||||
G4Exception(originOfException, exceptionCode, severity, description);
|
||||
}
|
||||
|
||||
#endif /* G4EXCEPTION_HH */
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4FPEDetection.hh 86793 2014-11-18 10:01:46Z gcosmo $
|
||||
// $Id: G4FPEDetection.hh 108434 2018-02-14 07:20:56Z gcosmo $
|
||||
//
|
||||
//
|
||||
// -*- C++ -*-
|
||||
@@ -164,10 +164,10 @@
|
||||
#include <fenv.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__))
|
||||
#define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__))
|
||||
//#define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__))
|
||||
//#define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
#if DEFINED_PPC
|
||||
#if (defined(__ppc__) || defined(__ppc64__)) // PPC
|
||||
|
||||
#define FE_EXCEPT_SHIFT 22 // shift flags right to get masks
|
||||
#define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
|
||||
@@ -198,7 +198,7 @@
|
||||
return ( fesetenv (&fenv) ? -1 : old_excepts );
|
||||
}
|
||||
|
||||
#elif DEFINED_INTEL
|
||||
#elif (defined(__i386__) || defined(__x86_64__)) // INTEL
|
||||
|
||||
static inline int feenableexcept (unsigned int excepts)
|
||||
{
|
||||
|
||||
@@ -119,11 +119,8 @@
|
||||
|
||||
#ifndef G4MTBARRIER_HH_
|
||||
#define G4MTBARRIER_HH_
|
||||
#include "G4Threading.hh"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "windefs.hh"
|
||||
#endif
|
||||
#include "G4Threading.hh"
|
||||
|
||||
class G4MTBarrier
|
||||
{
|
||||
@@ -154,11 +151,6 @@ private:
|
||||
G4Mutex m_mutex;
|
||||
G4Condition m_counterChanged;
|
||||
G4Condition m_continue;
|
||||
#if defined(WIN32)
|
||||
CRITICAL_SECTION cs1;
|
||||
CRITICAL_SECTION cs2;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* G4MTBARRIER_HH_ */
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4Pow.hh 93311 2015-10-16 10:16:37Z gcosmo $
|
||||
// $Id: G4Pow.hh 109086 2018-03-26 08:20:25Z gcosmo $
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
@@ -64,7 +64,7 @@ class G4Pow
|
||||
// Fast computation of Z^1/3
|
||||
//
|
||||
inline G4double Z13(G4int Z) const;
|
||||
inline G4double A13(G4double A) const;
|
||||
G4double A13(G4double A) const;
|
||||
|
||||
// Fast computation of Z^2/3
|
||||
//
|
||||
@@ -101,6 +101,9 @@ class G4Pow
|
||||
|
||||
G4Pow();
|
||||
|
||||
G4double A13Low(const G4double, const bool) const;
|
||||
G4double A13High(const G4double, const bool) const;
|
||||
|
||||
inline G4double logBase(G4double x) const;
|
||||
|
||||
static G4Pow* fpInstance;
|
||||
@@ -109,12 +112,14 @@ class G4Pow
|
||||
const G4int max2;
|
||||
|
||||
G4double maxA;
|
||||
G4double maxLowA;
|
||||
G4double maxA2;
|
||||
G4double maxAexp;
|
||||
|
||||
G4DataVector ener;
|
||||
G4DataVector logen;
|
||||
G4DataVector pz13;
|
||||
G4DataVector lowa13;
|
||||
G4DataVector lz;
|
||||
G4DataVector lz2;
|
||||
G4DataVector fexp;
|
||||
@@ -129,28 +134,6 @@ inline G4double G4Pow::Z13(G4int Z) const
|
||||
return pz13[Z];
|
||||
}
|
||||
|
||||
inline G4double G4Pow::A13(G4double A) const
|
||||
{
|
||||
G4double res = 0.0;
|
||||
if(A > 0.0)
|
||||
{
|
||||
G4double a = (1.0 <= A) ? A : 1.0/A;
|
||||
if(1.0 > A) { a = 1.0/A; }
|
||||
if(a <= maxA)
|
||||
{
|
||||
G4int i = G4int(a + 0.5);
|
||||
G4double x = (a/G4double(i) - 1.0)*onethird;
|
||||
res = pz13[i]*(1.0 + x - x*x*(1.0 - 1.66666666*x));
|
||||
if(1.0 > A) { res = 1.0/res; }
|
||||
}
|
||||
else
|
||||
{
|
||||
res = std::pow(A, onethird);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline G4double G4Pow::Z23(G4int Z) const
|
||||
{
|
||||
G4double x = Z13(Z);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ReferenceCountedHandle.hh 108486 2018-02-15 14:47:25Z gcosmo $
|
||||
// $Id: G4ReferenceCountedHandle.hh 110251 2018-05-17 14:09:28Z gcosmo $
|
||||
//
|
||||
//
|
||||
// Class G4ReferenceCountedHandle
|
||||
@@ -115,8 +115,8 @@ private:
|
||||
// The object subject to reference counting.
|
||||
};
|
||||
|
||||
extern G4GLOB_DLL G4ThreadLocal
|
||||
G4Allocator<G4ReferenceCountedHandle<void> > *aRCHAllocator;
|
||||
extern G4GLOB_DLL
|
||||
G4Allocator<G4ReferenceCountedHandle<void>>*& aRCHAllocator();
|
||||
|
||||
template <class X>
|
||||
class G4CountedObject
|
||||
@@ -156,8 +156,8 @@ private:
|
||||
// The counted object.
|
||||
};
|
||||
|
||||
extern G4GLOB_DLL G4ThreadLocal
|
||||
G4Allocator<G4CountedObject<void> > *aCountedObjectAllocator;
|
||||
extern G4GLOB_DLL
|
||||
G4Allocator<G4CountedObject<void>>*& aCountedObjectAllocator();
|
||||
|
||||
// --------- G4CountedObject<X> Inline function definitions ---------
|
||||
|
||||
@@ -189,15 +189,15 @@ void G4CountedObject<X>::Release()
|
||||
template <class X>
|
||||
void* G4CountedObject<X>::operator new( size_t )
|
||||
{
|
||||
if (!aCountedObjectAllocator)
|
||||
aCountedObjectAllocator = new G4Allocator<G4CountedObject<void> >;
|
||||
return( (void *)aCountedObjectAllocator->MallocSingle() );
|
||||
if (!aCountedObjectAllocator())
|
||||
aCountedObjectAllocator() = new G4Allocator<G4CountedObject<void>>;
|
||||
return( (void *)aCountedObjectAllocator()->MallocSingle() );
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void G4CountedObject<X>::operator delete( void *pObj )
|
||||
{
|
||||
aCountedObjectAllocator->FreeSingle( (G4CountedObject<void>*)pObj );
|
||||
aCountedObjectAllocator()->FreeSingle( (G4CountedObject<void>*)pObj );
|
||||
}
|
||||
|
||||
// --------- G4ReferenceCountedHandle<X> Inline function definitions ---------
|
||||
@@ -282,15 +282,15 @@ X* G4ReferenceCountedHandle<X>::operator ()() const
|
||||
template <class X>
|
||||
void* G4ReferenceCountedHandle<X>::operator new( size_t )
|
||||
{
|
||||
if (!aRCHAllocator)
|
||||
aRCHAllocator = new G4Allocator<G4ReferenceCountedHandle<void> >;
|
||||
return( (void *)aRCHAllocator->MallocSingle() );
|
||||
if (!aRCHAllocator())
|
||||
aRCHAllocator() = new G4Allocator<G4ReferenceCountedHandle<void> >;
|
||||
return( (void *)aRCHAllocator()->MallocSingle() );
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void G4ReferenceCountedHandle<X>::operator delete( void *pObj )
|
||||
{
|
||||
aRCHAllocator->FreeSingle( (G4ReferenceCountedHandle<void>*)pObj );
|
||||
aRCHAllocator()->FreeSingle( (G4ReferenceCountedHandle<void>*)pObj );
|
||||
}
|
||||
|
||||
#endif // _G4REFERENCECOUNTEDHANDLE_H_
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4SliceTimer.hh 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4SliceTimer.hh 110674 2018-06-07 10:30:11Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -134,6 +134,4 @@ std::ostream& operator << (std::ostream& os, const G4SliceTimer& t);
|
||||
|
||||
#include "G4SliceTimer.icc"
|
||||
|
||||
#define times ostimes
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4StateManager.hh 108486 2018-02-15 14:47:25Z gcosmo $
|
||||
// $Id: G4StateManager.hh 110286 2018-05-18 09:40:01Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
@@ -52,7 +52,8 @@
|
||||
#define G4StateManager_h 1
|
||||
|
||||
#include <vector>
|
||||
#include "globals.hh"
|
||||
#include "G4Types.hh"
|
||||
#include "G4String.hh"
|
||||
#include "G4ApplicationState.hh"
|
||||
#include "G4VStateDependent.hh"
|
||||
#include "G4VExceptionHandler.hh"
|
||||
|
||||
@@ -40,179 +40,242 @@
|
||||
|
||||
#include "G4Types.hh"
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
|
||||
// Macro to put current thread to sleep
|
||||
//
|
||||
#if defined(WIN32)
|
||||
#define G4THREADSLEEP( tick ) { Sleep(tick); }
|
||||
#else
|
||||
#include <unistd.h> // needed for sleep()
|
||||
#define G4THREADSLEEP( tick ) { sleep(tick); }
|
||||
#endif
|
||||
#define G4THREADSLEEP(tick) \
|
||||
std::this_thread::sleep_for(std::chrono::seconds( tick ))
|
||||
|
||||
// will be used in the future when migrating threading to task-based style
|
||||
//template <typename _Tp> using G4Future = std::future<_Tp>;
|
||||
//template <typename _Tp> using G4SharedFuture = std::shared_future<_Tp>;
|
||||
//template <typename _Tp> using G4Promise = std::promise<_Tp>;
|
||||
|
||||
//
|
||||
// NOTE ON GEANT4 SERIAL BUILDS AND MUTEX/UNIQUE_LOCK
|
||||
// ==================================================
|
||||
//
|
||||
// G4Mutex and G4RecursiveMutex are always C++11 std::mutex types
|
||||
// however, in serial mode, using G4MUTEXLOCK and G4MUTEXUNLOCK on these
|
||||
// types has no effect -- i.e. the mutexes are not actually locked or unlocked
|
||||
//
|
||||
// Additionally, when a G4Mutex or G4RecursiveMutex is used with G4AutoLock
|
||||
// and G4RecursiveAutoLock, respectively, these classes also suppressing
|
||||
// the locking and unlocking of the mutex. Regardless of the build type,
|
||||
// G4AutoLock and G4RecursiveAutoLock inherit from std::unique_lock<std::mutex>
|
||||
// and std::unique_lock<std::recursive_mutex>, respectively. This means
|
||||
// that in situations (such as is needed by the analysis category), the
|
||||
// G4AutoLock and G4RecursiveAutoLock can be passed to functions requesting
|
||||
// a std::unique_lock. Within these functions, since std::unique_lock
|
||||
// member functions are not virtual, they will not retain the dummy locking
|
||||
// and unlocking behavior
|
||||
// --> An example of this behavior can be found in G4AutoLock.hh
|
||||
//
|
||||
// Jonathan R. Madsen (February 21, 2018)
|
||||
//
|
||||
|
||||
// global mutex types
|
||||
typedef std::mutex G4Mutex;
|
||||
typedef std::recursive_mutex G4RecursiveMutex;
|
||||
|
||||
// mutex macros
|
||||
#define G4MUTEX_INITIALIZER {}
|
||||
#define G4MUTEXINIT(mutex) ;;
|
||||
#define G4MUTEXDESTROY(mutex) ;;
|
||||
|
||||
// static functions: get_id(), sleep_for(...), sleep_until(...), yield(),
|
||||
namespace G4ThisThread { using namespace std::this_thread; }
|
||||
|
||||
// will be used in the future when migrating threading to task-based style
|
||||
// and are currently used in unit tests
|
||||
template <typename _Tp> using G4Promise = std::promise<_Tp>;
|
||||
template <typename _Tp> using G4Future = std::future<_Tp>;
|
||||
template <typename _Tp> using G4SharedFuture = std::shared_future<_Tp>;
|
||||
|
||||
// Some useful types
|
||||
typedef void* G4ThreadFunReturnType;
|
||||
typedef void* G4ThreadFunArgType;
|
||||
typedef G4int (*thread_lock)(G4Mutex*);
|
||||
typedef G4int (*thread_unlock)(G4Mutex*);
|
||||
|
||||
// Helper function for getting a unique static mutex for a specific
|
||||
// class or type
|
||||
// Usage example:
|
||||
// a template class "G4Cache<T>" that required a static
|
||||
// mutex for specific to type T:
|
||||
// G4AutoLock l(G4TypeMutex<G4Cache<T>>());
|
||||
template <typename _Tp>
|
||||
G4Mutex& G4TypeMutex(const unsigned int& _n = 0)
|
||||
{
|
||||
static G4Mutex* _mutex = new G4Mutex();
|
||||
if(_n == 0)
|
||||
return *_mutex;
|
||||
|
||||
static std::vector<G4Mutex*> _mutexes;
|
||||
if(_n > _mutexes.size())
|
||||
_mutexes.resize(_n, nullptr);
|
||||
if(!_mutexes[_n])
|
||||
_mutexes[_n] = new G4Mutex();
|
||||
return *(_mutexes[_n-1]);
|
||||
}
|
||||
|
||||
// Helper function for getting a unique static recursive_mutex for a
|
||||
// specific class or type
|
||||
// Usage example:
|
||||
// a template class "G4Cache<T>" that required a static
|
||||
// recursive_mutex for specific to type T:
|
||||
// G4RecursiveAutoLock l(G4TypeRecursiveMutex<G4Cache<T>>());
|
||||
template <typename _Tp>
|
||||
G4RecursiveMutex& G4TypeRecursiveMutex(const unsigned int& _n = 0)
|
||||
{
|
||||
static G4RecursiveMutex* _mutex = new G4RecursiveMutex();
|
||||
if(_n == 0)
|
||||
return *(_mutex);
|
||||
|
||||
static std::vector<G4RecursiveMutex*> _mutexes;
|
||||
if(_n > _mutexes.size())
|
||||
_mutexes.resize(_n, nullptr);
|
||||
if(!_mutexes[_n])
|
||||
_mutexes[_n] = new G4RecursiveMutex();
|
||||
return *(_mutexes[_n-1]);
|
||||
}
|
||||
|
||||
#if defined(G4MULTITHREADED)
|
||||
//===============================
|
||||
// Multi-threaded build
|
||||
//===============================
|
||||
#if ( defined(__MACH__) && defined(__clang__) && defined(__x86_64__) ) || \
|
||||
( defined(__MACH__) && defined(__GNUC__) && (__GNUC__>=4 && __GNUC_MINOR__>=7 || __GNUC__>=5) ) || \
|
||||
defined(__linux__) || defined(_AIX)
|
||||
//
|
||||
// Multi-threaded build: for POSIX systems
|
||||
//
|
||||
#include <pthread.h>
|
||||
#if defined(__MACH__) // needed only for MacOSX for definition of pid_t
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
//==========================================
|
||||
// G4MULTITHREADED is ON - threading enabled
|
||||
//==========================================
|
||||
|
||||
typedef pthread_mutex_t G4Mutex;
|
||||
typedef pthread_t G4Thread;
|
||||
// global thread types
|
||||
typedef std::thread G4Thread;
|
||||
typedef std::thread::native_handle_type G4NativeThread;
|
||||
|
||||
// G4Mutex initializer macro
|
||||
//
|
||||
#define G4MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
// Lock/unlock a G4Mutex function name
|
||||
//
|
||||
#define G4MUTEXLOCK pthread_mutex_lock
|
||||
#define G4MUTEXUNLOCK pthread_mutex_unlock
|
||||
|
||||
// Macro to initialize a Mutex
|
||||
//
|
||||
#define G4MUTEXINIT(mutex) pthread_mutex_init( &mutex , NULL);
|
||||
#define G4MUTEXDESTROY(mutex) pthread_mutex_destroy( &mutex );
|
||||
|
||||
// Macro to create a G4Thread object
|
||||
//
|
||||
#define G4THREADCREATE( worker , func , arg ) { \
|
||||
pthread_attr_t attr; \
|
||||
pthread_attr_init(&attr); \
|
||||
pthread_attr_setstacksize(&attr,16*1024*1024); \
|
||||
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); \
|
||||
pthread_create( worker, &attr, func , arg ); \
|
||||
}
|
||||
// mutex macros
|
||||
#define G4MUTEXLOCK(mutex) { (mutex)->lock(); }
|
||||
#define G4MUTEXUNLOCK(mutex) { (mutex)->unlock(); }
|
||||
|
||||
// Macro to join thread
|
||||
//
|
||||
#define G4THREADJOIN( worker ) pthread_join( worker , NULL)
|
||||
#define G4THREADJOIN(worker) (worker).join()
|
||||
|
||||
// Macro to retrieve caller thread
|
||||
//
|
||||
#define G4THREADSELF pthread_self
|
||||
// std::thread::id does not cast to integer
|
||||
typedef std::thread::id G4Pid_t;
|
||||
|
||||
// Some useful types
|
||||
//
|
||||
typedef void* G4ThreadFunReturnType;
|
||||
typedef void* G4ThreadFunArgType;
|
||||
typedef G4int (*thread_lock)(G4Mutex*);
|
||||
typedef G4int (*thread_unlock)(G4Mutex*);
|
||||
|
||||
typedef pid_t G4Pid_t;
|
||||
// Instead of previous macro taking one argument, define function taking
|
||||
// unlimited arguments
|
||||
template <typename _Worker, typename _Func, typename... _Args>
|
||||
void G4THREADCREATE(_Worker*& worker, _Func func, _Args... args)
|
||||
{
|
||||
*worker = G4Thread(func, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
// Conditions
|
||||
//
|
||||
// See G4MTRunManager for example on how to use these
|
||||
// This complication is needed to be portable with WIN32
|
||||
// Note that WIN32 requires an additional initialization step.
|
||||
// See example code
|
||||
//
|
||||
typedef pthread_cond_t G4Condition;
|
||||
#define G4CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER
|
||||
|
||||
#define G4CONDITIONWAIT( cond, mutex ) pthread_cond_wait( cond , mutex );
|
||||
#define G4CONDITIONBROADCAST( cond ) pthread_cond_broadcast( cond );
|
||||
|
||||
#elif defined(WIN32)
|
||||
typedef std::condition_variable G4Condition;
|
||||
#define G4CONDITION_INITIALIZER {}
|
||||
#define G4CONDITIONWAIT(cond, lock) (cond)->wait(*lock);
|
||||
#define G4CONDITIONWAITLAMBDA(cond, lock, lambda) (cond)->wait(*lock, lambda);
|
||||
#define G4CONDITIONBROADCAST(cond) (cond)->notify_all();
|
||||
//
|
||||
// Multi-threaded build: for Windows systems
|
||||
// we don't define above globally so single-threaded code does not get
|
||||
// caught in condition with no other thread to wake it up
|
||||
//
|
||||
#include "windefs.hh" // Include 'safe...' <windows.h>
|
||||
|
||||
typedef HANDLE G4Mutex;
|
||||
typedef HANDLE G4Thread;
|
||||
|
||||
#define G4MUTEX_INITIALIZER CreateMutex(NULL,FALSE,NULL)
|
||||
DWORD /*WINAPI*/ G4WaitForSingleObjectInf( __in G4Mutex m );
|
||||
#define G4MUTEXLOCK G4WaitForSingleObjectInf
|
||||
|
||||
// #define G4MUTEXINIT(mutex) InitializeCriticalSection( &mutex );
|
||||
#define G4MUTEXINIT(mutex);
|
||||
#define G4MUTEXDESTROY(mutex);
|
||||
|
||||
// Not clear why following two lines are needed...
|
||||
//
|
||||
BOOL G4ReleaseMutex( __in G4Mutex m);
|
||||
#define G4MUTEXUNLOCK G4ReleaseMutex
|
||||
|
||||
#define G4THREADCREATE( worker, func, arg ) { *worker = CreateThread( NULL, 16*1024*1024 , func , arg , 0 , NULL ); }
|
||||
#define G4THREADJOIN( worker ) WaitForSingleObject( worker , INFINITE);
|
||||
#define G4THREADSELF GetCurrentThreadId
|
||||
#define G4ThreadFunReturnType DWORD WINAPI
|
||||
typedef LPVOID G4ThreadFunArgType;
|
||||
typedef DWORD (*thread_lock)(G4Mutex);
|
||||
typedef BOOL (*thread_unlock)(G4Mutex);
|
||||
typedef DWORD G4Pid_t;
|
||||
|
||||
// Conditions
|
||||
//
|
||||
typedef CONDITION_VARIABLE G4Condition;
|
||||
#define G4CONDITION_INITIALIZER CONDITION_VARIABLE_INIT
|
||||
|
||||
#define G4CONDITIONWAIT( cond , criticalsectionmutex ) SleepConditionVariableCS( cond, criticalsectionmutex , INFINITE );
|
||||
#define G4CONDITIONBROADCAST( cond ) WakeAllConditionVariable( cond );
|
||||
|
||||
#else
|
||||
|
||||
#error "No Threading model technology supported for this platform. Use sequential build !"
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
//==========================================
|
||||
// G4MULTITHREADED is OFF - Sequential build
|
||||
//==========================================
|
||||
typedef G4int G4Mutex;
|
||||
typedef G4int G4Thread;
|
||||
#define G4MUTEX_INITIALIZER 1
|
||||
G4int fake_mutex_lock_unlock( G4Mutex* );// { return 0; }
|
||||
#define G4MUTEXINIT(mutex) ;;
|
||||
#define G4MUTEXDESTROY(mutex) ;;
|
||||
#define G4MUTEXLOCK fake_mutex_lock_unlock
|
||||
#define G4MUTEXUNLOCK fake_mutex_lock_unlock
|
||||
#define G4THREADCREATE( worker , func , arg ) ;;
|
||||
#define G4THREADJOIN( worker ) ;;
|
||||
#define G4THREADSELF( nothing ) G4Thread(nothing);
|
||||
typedef void* G4ThreadFunReturnType;
|
||||
typedef void* G4ThreadFunArgType;
|
||||
typedef G4int (*thread_lock)(G4Mutex*);
|
||||
typedef G4int (*thread_unlock)(G4Mutex*);
|
||||
typedef G4int G4Pid_t;
|
||||
typedef G4int G4Condition;
|
||||
#define G4CONDITION_INITIALIZER 1
|
||||
#define G4CONDITIONWAIT( cond, mutex ) { ++(*cond); ++(*mutex); }
|
||||
#define G4CONDITIONBROADCAST( cond ) { ++(*cond); }
|
||||
//==========================================
|
||||
// G4MULTITHREADED is OFF - Sequential build
|
||||
//==========================================
|
||||
|
||||
// implement a dummy thread class that acts like a thread
|
||||
class G4DummyThread
|
||||
{
|
||||
public:
|
||||
typedef G4int native_handle_type;
|
||||
typedef std::thread::id id;
|
||||
|
||||
public:
|
||||
// does nothing
|
||||
G4DummyThread()
|
||||
{ }
|
||||
// a std::thread-like constructor that execute upon construction
|
||||
template <typename _Func, typename... _Args>
|
||||
G4DummyThread(_Func func, _Args&&... _args)
|
||||
{
|
||||
func(std::forward<_Args>(_args)...);
|
||||
}
|
||||
|
||||
public:
|
||||
native_handle_type native_handle() const { return native_handle_type(); }
|
||||
bool joinable() const { return true; }
|
||||
id get_id() const noexcept { return std::this_thread::get_id(); }
|
||||
void swap(G4DummyThread&) { }
|
||||
void join() { }
|
||||
void detach() { }
|
||||
|
||||
public:
|
||||
static unsigned int hardware_concurrency() noexcept
|
||||
{
|
||||
return std::thread::hardware_concurrency();
|
||||
}
|
||||
};
|
||||
|
||||
// global thread types
|
||||
typedef G4DummyThread G4Thread;
|
||||
typedef G4DummyThread::native_handle_type G4NativeThread;
|
||||
|
||||
// mutex macros
|
||||
#define G4MUTEXLOCK(mutex) ;;
|
||||
#define G4MUTEXUNLOCK(mutex) ;;
|
||||
|
||||
// Macro to join thread
|
||||
#define G4THREADJOIN(worker) ;;
|
||||
|
||||
typedef G4int G4Pid_t;
|
||||
|
||||
// Instead of previous macro taking one argument, define function taking
|
||||
// unlimited arguments
|
||||
template <typename _Worker, typename _Func, typename... _Args>
|
||||
void G4THREADCREATE(_Worker*& worker, _Func func, _Args... args)
|
||||
{
|
||||
*worker = G4Thread(func, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
typedef G4int G4Condition;
|
||||
#define G4CONDITION_INITIALIZER 1
|
||||
#define G4CONDITIONWAIT( cond, mutex ) { (*cond)++; }
|
||||
#define G4CONDITIONWAITLAMBDA( cond, mutex, lambda ) { (*cond)++; }
|
||||
#define G4CONDITIONBROADCAST( cond ) { (*cond)++; }
|
||||
|
||||
#endif //G4MULTITHREADING
|
||||
|
||||
namespace G4Threading
|
||||
{
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
SEQUENTIAL_ID = -2,
|
||||
MASTER_ID = -1,
|
||||
WORKER_ID = 0,
|
||||
GENERICTHREAD_ID = -1000
|
||||
};
|
||||
G4Pid_t G4GetPidId();
|
||||
G4int G4GetNumberOfCores();
|
||||
G4int G4GetThreadId();
|
||||
G4bool IsWorkerThread();
|
||||
G4bool IsMasterThread();
|
||||
void G4SetThreadId( G4int aNewValue );
|
||||
G4bool G4SetPinAffinity( G4int idx , G4Thread& at);
|
||||
void SetMultithreadedApplication(G4bool value);
|
||||
G4bool IsMultithreadedApplication();
|
||||
int WorkerThreadLeavesPool();
|
||||
int WorkerThreadJoinsPool();
|
||||
G4int GetNumberOfRunningWorkerThreads();
|
||||
|
||||
G4Pid_t G4GetPidId();
|
||||
G4int G4GetNumberOfCores();
|
||||
G4int G4GetThreadId();
|
||||
G4bool IsWorkerThread();
|
||||
G4bool IsMasterThread();
|
||||
void G4SetThreadId( G4int aNewValue );
|
||||
G4bool G4SetPinAffinity( G4int idx , G4NativeThread& at);
|
||||
void SetMultithreadedApplication(G4bool value);
|
||||
G4bool IsMultithreadedApplication();
|
||||
int WorkerThreadLeavesPool();
|
||||
int WorkerThreadJoinsPool();
|
||||
G4int GetNumberOfRunningWorkerThreads();
|
||||
}
|
||||
|
||||
#endif //G4Threading_hh
|
||||
|
||||
+51
-25
@@ -23,34 +23,60 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// ---------------------------------------------------------------
|
||||
// GEANT 4 class header file
|
||||
// $Id:$
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// This file includes Windows declarations from <windows.h> protecting
|
||||
// those defines that may cause troubles within the Geant4 code.
|
||||
// ----------------------------------------------------------------------
|
||||
// G4TiMemory
|
||||
//
|
||||
// Provides empty macros when Geant4 is compiled with TiMemory disabled
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
#ifndef windefs_hh
|
||||
#define windefs_hh
|
||||
#ifndef g4timemory_hh_
|
||||
#define g4timemory_hh_
|
||||
|
||||
#if defined(WIN32)
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX // avoid redefinition of min() and max()
|
||||
#include <windows.h>
|
||||
#undef pascal // trick to overcome redefinition of 'pascal'
|
||||
#undef scr1
|
||||
#undef scr2
|
||||
#undef rad1
|
||||
#undef rad2
|
||||
#undef small
|
||||
#undef ABSOLUTE
|
||||
#undef RELATIVE
|
||||
#undef GetObject
|
||||
#endif // WIN32
|
||||
#include "globals.hh"
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
#ifdef GEANT4_USE_TIMEMORY
|
||||
|
||||
# if defined __GNUC__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wexceptions"
|
||||
# pragma GCC diagnostic ignored "-Wunused-private-field"
|
||||
# endif
|
||||
|
||||
#include <timemory/timemory.hpp>
|
||||
|
||||
typedef tim::auto_timer G4AutoTimer;
|
||||
|
||||
inline void InitializeTiMemory()
|
||||
{
|
||||
tim::manager* instance = tim::manager::instance();
|
||||
instance->enable(true);
|
||||
}
|
||||
|
||||
# if defined __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
#define TIMEMORY_AUTO_TIMER(str)
|
||||
#define TIMEMORY_AUTO_TIMER_OBJ(str) {}
|
||||
|
||||
#define TIMEMORY_BASIC_AUTO_TIMER(str)
|
||||
#define TIMEMORY_BASIC_AUTO_TIMER_OBJ(str) {}
|
||||
|
||||
#define TIMEMORY_DEBUG_BASIC_AUTO_TIMER(str)
|
||||
#define TIMEMORY_DEBUG_AUTO_TIMER(str)
|
||||
|
||||
inline void InitializeTiMemory()
|
||||
{ }
|
||||
|
||||
#endif
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#endif
|
||||
|
||||
#endif //windefs_hh
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4Timer.hh 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4Timer.hh 110674 2018-06-07 10:30:11Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -107,9 +107,13 @@
|
||||
#include "G4Types.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class G4Timer
|
||||
{
|
||||
public:
|
||||
typedef std::chrono::high_resolution_clock clock_type;
|
||||
|
||||
public:
|
||||
|
||||
G4Timer();
|
||||
|
||||
@@ -121,10 +125,10 @@ class G4Timer
|
||||
G4double GetSystemElapsed() const;
|
||||
G4double GetUserElapsed() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
G4bool fValidTimes;
|
||||
clock_t fStartRealTime,fEndRealTime;
|
||||
std::chrono::time_point<clock_type> fStartRealTime, fEndRealTime;
|
||||
tms fStartTimes,fEndTimes;
|
||||
};
|
||||
|
||||
@@ -132,6 +136,4 @@ std::ostream& operator << (std::ostream& os, const G4Timer& t);
|
||||
|
||||
#include "G4Timer.icc"
|
||||
|
||||
#define times ostimes
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4Timer.icc 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4Timer.icc 108434 2018-02-14 07:20:56Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
@@ -35,13 +35,15 @@ inline
|
||||
void G4Timer::Start()
|
||||
{
|
||||
fValidTimes=false;
|
||||
fStartRealTime=times(&fStartTimes);
|
||||
times(&fStartTimes);
|
||||
fStartRealTime = clock_type::now();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4Timer::Stop()
|
||||
{
|
||||
fEndRealTime=times(&fEndTimes);
|
||||
times(&fEndTimes);
|
||||
fEndRealTime = clock_type::now();
|
||||
fValidTimes=true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4Types.hh 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4Types.hh 109033 2018-03-22 11:14:17Z gcosmo $
|
||||
//
|
||||
//
|
||||
// GEANT4 native types
|
||||
@@ -43,7 +43,7 @@
|
||||
// Define DLL export macro for WIN32 systems for
|
||||
// importing/exporting external symbols to DLLs
|
||||
//
|
||||
#if defined G4LIB_BUILD_DLL
|
||||
#if defined G4LIB_BUILD_DLL && !defined G4MULTITHREADED
|
||||
#define G4DLLEXPORT __declspec( dllexport )
|
||||
#define G4DLLIMPORT __declspec( dllimport )
|
||||
#else
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VExceptionHandler.hh 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4VExceptionHandler.hh 110286 2018-05-18 09:40:01Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
@@ -49,7 +49,7 @@
|
||||
#ifndef G4VExceptionHandler_h
|
||||
#define G4VExceptionHandler_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4Types.hh"
|
||||
#include "G4ExceptionSeverity.hh"
|
||||
|
||||
class G4VExceptionHandler
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VStateDependent.hh 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4VStateDependent.hh 110286 2018-05-18 09:40:01Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
@@ -49,7 +49,7 @@
|
||||
#ifndef G4VStateDependent_h
|
||||
#define G4VStateDependent_h 1
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4Types.hh"
|
||||
#include "G4ApplicationState.hh"
|
||||
|
||||
class G4VStateDependent
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4Version.hh 110074 2018-05-15 10:03:53Z gcosmo $
|
||||
// $Id: G4Version.hh 110902 2018-06-25 08:56:46Z gcosmo $
|
||||
// GEANT4 tag $Name:$
|
||||
//
|
||||
// Version information
|
||||
@@ -46,11 +46,11 @@
|
||||
// |--> patch number
|
||||
|
||||
#ifndef G4VERSION_NUMBER
|
||||
#define G4VERSION_NUMBER 1042
|
||||
#define G4VERSION_NUMBER 1050
|
||||
#endif
|
||||
|
||||
#ifndef G4VERSION_TAG
|
||||
#define G4VERSION_TAG "$Name: geant4-10-04-patch-02 $"
|
||||
#define G4VERSION_TAG "$Name: geant4-10-05-beta-01 $"
|
||||
#endif
|
||||
|
||||
// as variables
|
||||
@@ -58,10 +58,10 @@
|
||||
#include "G4String.hh"
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
static const G4String G4Version = "$Name: geant4-10-04-patch-02 [MT]$";
|
||||
static const G4String G4Version = "$Name: geant4-10-05-beta-01 [MT]$";
|
||||
#else
|
||||
static const G4String G4Version = "$Name: geant4-10-04-patch-02 $";
|
||||
static const G4String G4Version = "$Name: geant4-10-05-beta-01 $";
|
||||
#endif
|
||||
static const G4String G4Date = "(25-May-2018)";
|
||||
static const G4String G4Date = "(29-June-2018)";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ios.hh 70021 2013-05-22 07:55:29Z gcosmo $
|
||||
// $Id: G4ios.hh 110251 2018-05-17 14:09:28Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ---------------------------------------------------------------
|
||||
@@ -42,10 +42,10 @@
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
extern G4GLOB_DLL G4ThreadLocal std::ostream *G4cout_p;
|
||||
extern G4GLOB_DLL G4ThreadLocal std::ostream *G4cerr_p;
|
||||
#define G4cout (*G4cout_p)
|
||||
#define G4cerr (*G4cerr_p)
|
||||
extern G4GLOB_DLL std::ostream*& _G4cout_p();
|
||||
extern G4GLOB_DLL std::ostream*& _G4cerr_p();
|
||||
#define G4cout (*_G4cout_p())
|
||||
#define G4cerr (*_G4cerr_p())
|
||||
|
||||
#else // Sequential
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4strstreambuf.hh 103661 2017-04-20 14:57:11Z gcosmo $
|
||||
// $Id: G4strstreambuf.hh 110251 2018-05-17 14:09:28Z gcosmo $
|
||||
//
|
||||
// ====================================================================
|
||||
//
|
||||
@@ -43,10 +43,10 @@ class G4strstreambuf;
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
|
||||
extern G4GLOB_DLL G4ThreadLocal G4strstreambuf *G4coutbuf_p;
|
||||
extern G4GLOB_DLL G4ThreadLocal G4strstreambuf *G4cerrbuf_p;
|
||||
#define G4coutbuf (*G4coutbuf_p)
|
||||
#define G4cerrbuf (*G4cerrbuf_p)
|
||||
extern G4GLOB_DLL G4strstreambuf*& _G4coutbuf_p();
|
||||
extern G4GLOB_DLL G4strstreambuf*& _G4cerrbuf_p();
|
||||
#define G4coutbuf (*_G4coutbuf_p())
|
||||
#define G4cerrbuf (*_G4cerrbuf_p())
|
||||
|
||||
#else // Sequential
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: globals.hh 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: globals.hh 110286 2018-05-18 09:40:01Z gcosmo $
|
||||
//
|
||||
//
|
||||
// Global Constants and typedefs
|
||||
@@ -66,28 +66,7 @@
|
||||
// Includes some additional definitions: sqr, G4SwapPtr, G4SwapObj.
|
||||
#include "templates.hh"
|
||||
|
||||
// Includes Physical Constants and System of Units
|
||||
// #include "G4PhysicalConstants.hh"
|
||||
// #include "G4SystemOfUnits.hh"
|
||||
|
||||
// Global error function
|
||||
#include "G4ExceptionSeverity.hh"
|
||||
|
||||
typedef std::ostringstream G4ExceptionDescription;
|
||||
|
||||
void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
const char* comments);
|
||||
void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
G4ExceptionDescription & description);
|
||||
void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
G4ExceptionDescription & description,
|
||||
const char* comments);
|
||||
#include "G4Exception.hh"
|
||||
|
||||
#endif /* GLOBALS_HH */
|
||||
|
||||
|
||||
@@ -36,34 +36,19 @@
|
||||
#if defined (G4MULTITHREADED)
|
||||
#if ( defined(__MACH__) && defined(__clang__) && defined(__x86_64__) ) || \
|
||||
( defined(__linux__) && defined(__clang__) )
|
||||
#if (defined (G4USE_STD11) && __has_feature(cxx_thread_local))
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#else
|
||||
# define G4ThreadLocalStatic static __thread
|
||||
# define G4ThreadLocal __thread
|
||||
#endif
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#elif ( (defined(__linux__) || defined(__MACH__)) && \
|
||||
!defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__>=4 && __GNUC_MINOR__<9))
|
||||
#if defined (G4USE_STD11)
|
||||
# define G4ThreadLocalStatic static __thread
|
||||
# define G4ThreadLocal thread_local
|
||||
#else
|
||||
# define G4ThreadLocalStatic static __thread
|
||||
# define G4ThreadLocal __thread
|
||||
#endif
|
||||
# define G4ThreadLocalStatic static __thread
|
||||
# define G4ThreadLocal thread_local
|
||||
#elif ( (defined(__linux__) || defined(__MACH__)) && \
|
||||
!defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__>=4 && __GNUC_MINOR__>=9) || __GNUC__>=5 )
|
||||
#if defined (G4USE_STD11)
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#else
|
||||
# define G4ThreadLocalStatic static __thread
|
||||
# define G4ThreadLocal __thread
|
||||
#endif
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#elif ( (defined(__linux__) || defined(__MACH__)) && \
|
||||
defined(__INTEL_COMPILER) )
|
||||
#if (defined (G4USE_STD11) && __INTEL_COMPILER>=1500)
|
||||
#if __INTEL_COMPILER>=1500
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#else
|
||||
@@ -71,16 +56,11 @@
|
||||
# define G4ThreadLocal __thread
|
||||
#endif
|
||||
#elif defined(_AIX)
|
||||
#if defined (G4USE_STD11)
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#else
|
||||
# define G4ThreadLocalStatic static __thread
|
||||
# define G4ThreadLocal __thread
|
||||
#endif
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#elif defined(WIN32)
|
||||
# define G4ThreadLocalStatic static __declspec(thread)
|
||||
# define G4ThreadLocal __declspec(thread)
|
||||
# define G4ThreadLocalStatic static thread_local
|
||||
# define G4ThreadLocal thread_local
|
||||
#else
|
||||
# error "No Thread Local Storage (TLS) technology supported for this platform. Use sequential build !"
|
||||
#endif
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
#
|
||||
# Generated on : 24/9/2010
|
||||
#
|
||||
# $Id: sources.cmake 103592 2017-04-19 08:09:03Z gcosmo $
|
||||
# $Id: sources.cmake 110674 2018-06-07 10:30:11Z gcosmo $
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# List external includes needed.
|
||||
include_directories(${CLHEP_INCLUDE_DIRS})
|
||||
include_directories(${TiMemory_INCLUDE_DIRS})
|
||||
|
||||
# List internal includes needed.
|
||||
|
||||
@@ -29,7 +30,6 @@ GEANT4_DEFINE_MODULE(NAME G4globman
|
||||
globals.hh
|
||||
templates.hh
|
||||
tls.hh
|
||||
windefs.hh
|
||||
G4Allocator.hh
|
||||
G4strstreambuf.icc
|
||||
G4AllocatorPool.hh
|
||||
@@ -41,6 +41,7 @@ GEANT4_DEFINE_MODULE(NAME G4globman
|
||||
G4ErrorPropagatorData.hh
|
||||
G4ErrorPropagatorData.icc
|
||||
G4Evaluator.hh
|
||||
G4Exception.hh
|
||||
G4ExceptionSeverity.hh
|
||||
G4Exp.hh
|
||||
G4FPEDetection.hh
|
||||
@@ -105,6 +106,7 @@ GEANT4_DEFINE_MODULE(NAME G4globman
|
||||
G4MasterForwardcoutDestination.hh
|
||||
G4FilecoutDestination.hh
|
||||
G4BuffercoutDestination.hh
|
||||
G4TiMemory.hh
|
||||
SOURCES
|
||||
G4Allocator.cc
|
||||
G4AllocatorPool.cc
|
||||
@@ -147,6 +149,7 @@ GEANT4_DEFINE_MODULE(NAME G4globman
|
||||
GLOBAL_DEPENDENCIES
|
||||
LINK_LIBRARIES
|
||||
${CLHEP_LIBRARIES}
|
||||
${TiMemory_LIBRARIES}
|
||||
)
|
||||
|
||||
# List any source specific properties here
|
||||
|
||||
@@ -28,4 +28,10 @@
|
||||
|
||||
// Decalare needed static data member for fully specialized version of cache
|
||||
#include "G4CacheDetails.hh"
|
||||
G4ThreadLocal std::vector<G4double>* G4CacheReference<G4double>::cache = 0;
|
||||
|
||||
G4CacheReference<G4double>::cache_container*&
|
||||
G4CacheReference<G4double>::cache()
|
||||
{
|
||||
G4ThreadLocalStatic std::vector<G4double>* _instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
@@ -24,104 +24,11 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4Exception.cc 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4Exception.cc 110286 2018-05-18 09:40:01Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
// G4Exception
|
||||
//
|
||||
// Global error function prints string to G4cerr (or G4cout in case of
|
||||
// warning). May abort program according to severity.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4String.hh"
|
||||
#include "G4StateManager.hh"
|
||||
|
||||
void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
const char* description)
|
||||
{
|
||||
G4VExceptionHandler* exceptionHandler
|
||||
= G4StateManager::GetStateManager()->GetExceptionHandler();
|
||||
G4bool toBeAborted = true;
|
||||
if(exceptionHandler)
|
||||
{
|
||||
toBeAborted = exceptionHandler
|
||||
->Notify(originOfException,exceptionCode,severity,description);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const G4String es_banner
|
||||
= "\n-------- EEEE ------- G4Exception-START -------- EEEE -------\n";
|
||||
static const G4String ee_banner
|
||||
= "\n-------- EEEE -------- G4Exception-END --------- EEEE -------\n";
|
||||
static const G4String ws_banner
|
||||
= "\n-------- WWWW ------- G4Exception-START -------- WWWW -------\n";
|
||||
static const G4String we_banner
|
||||
= "\n-------- WWWW -------- G4Exception-END --------- WWWW -------\n";
|
||||
std::ostringstream message;
|
||||
message << "\n*** ExceptionHandler is not defined ***\n"
|
||||
<< "*** G4Exception : " << exceptionCode << G4endl
|
||||
<< " issued by : " << originOfException << G4endl
|
||||
<< description << G4endl;
|
||||
switch(severity)
|
||||
{
|
||||
case FatalException:
|
||||
G4cerr << es_banner << message.str() << "*** Fatal Exception ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
case FatalErrorInArgument:
|
||||
G4cerr << es_banner << message.str() << "*** Fatal Error In Argument ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
case RunMustBeAborted:
|
||||
G4cerr << es_banner << message.str() << "*** Run Must Be Aborted ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
case EventMustBeAborted:
|
||||
G4cerr << es_banner << message.str() << "*** Event Must Be Aborted ***"
|
||||
<< ee_banner << G4endl;
|
||||
break;
|
||||
default:
|
||||
G4cout << ws_banner << message.str()
|
||||
<< "*** This is just a warning message. ***"
|
||||
<< we_banner << G4endl;
|
||||
toBeAborted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(toBeAborted)
|
||||
{
|
||||
if(G4StateManager::GetStateManager()->SetNewState(G4State_Abort))
|
||||
{
|
||||
G4cerr << G4endl << "*** G4Exception: Aborting execution ***" << G4endl;
|
||||
abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cerr << G4endl << "*** G4Exception: Abortion suppressed ***"
|
||||
<< G4endl << "*** No guarantee for further execution ***" << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
G4ExceptionDescription & description)
|
||||
{
|
||||
G4String des = description.str();
|
||||
G4Exception(originOfException, exceptionCode, severity, des.c_str());
|
||||
}
|
||||
|
||||
void G4Exception(const char* originOfException,
|
||||
const char* exceptionCode,
|
||||
G4ExceptionSeverity severity,
|
||||
G4ExceptionDescription & description,
|
||||
const char* comments)
|
||||
{
|
||||
description << comments << G4endl;
|
||||
G4Exception(originOfException, exceptionCode, severity, description);
|
||||
}
|
||||
#include "G4Exception.hh"
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
*
|
||||
* Created on: Feb 10, 2016
|
||||
* Author: adotti
|
||||
* Updated on: Feb 9, 2018
|
||||
* Author: jmadsen
|
||||
*/
|
||||
|
||||
#include "G4MTBarrier.hh"
|
||||
@@ -37,60 +39,30 @@
|
||||
|
||||
G4MTBarrier::G4MTBarrier(unsigned int numThreads ) :
|
||||
m_numActiveThreads(numThreads),
|
||||
m_counter(0),
|
||||
m_mutex(G4MUTEX_INITIALIZER),
|
||||
m_counterChanged(G4CONDITION_INITIALIZER),
|
||||
m_continue(G4CONDITION_INITIALIZER)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
InitializeCriticalSection( &cs1 );
|
||||
InitializeCriticalSection( &cs2 );
|
||||
#endif
|
||||
}
|
||||
m_counter(0)
|
||||
{}
|
||||
|
||||
void G4MTBarrier::ThisWorkerReady() {
|
||||
//Step-1: Worker acquires lock on shared resource (the counter)
|
||||
#ifndef WIN32
|
||||
G4AutoLock lock(&m_mutex);
|
||||
#else
|
||||
EnterCriticalSection( &cs1 );
|
||||
#endif
|
||||
//Step-2: Worker increases counter
|
||||
++m_counter;
|
||||
//Step-3: Worker broadcasts that the counter has changed
|
||||
G4CONDITIONBROADCAST(&m_counterChanged);
|
||||
//Step-4: Worker waits on condition to continue
|
||||
#ifndef WIN32
|
||||
G4CONDITIONWAIT(&m_continue,&m_mutex);
|
||||
#else
|
||||
# ifdef G4MULTITHREADED
|
||||
G4CONDITIONWAIT(&m_continue,&cs1);
|
||||
# endif
|
||||
LeaveCriticalSection(&cs1);
|
||||
#endif
|
||||
G4CONDITIONWAIT(&m_continue,&lock);
|
||||
}
|
||||
|
||||
void G4MTBarrier::Wait() {
|
||||
while (true)
|
||||
{
|
||||
//Step-2: Acquires lock on shared resource (the counter)
|
||||
#ifndef WIN32
|
||||
G4AutoLock lock(&m_mutex);
|
||||
#else
|
||||
EnterCriticalSection(&cs2);
|
||||
#endif
|
||||
//If the counter equals active threads, all threads are ready, exit the loop
|
||||
if ( m_counter == m_numActiveThreads ) { break; }
|
||||
//Step-3: Not all workers are ready, wait for the number to change
|
||||
//before repeating the check
|
||||
#ifdef WIN32
|
||||
# ifdef G4MULTITHREADED
|
||||
G4CONDITIONWAIT(&m_counterChanged,&cs2);
|
||||
# endif
|
||||
LeaveCriticalSection(&cs2);
|
||||
#else
|
||||
G4CONDITIONWAIT(&m_counterChanged,&m_mutex);
|
||||
#endif
|
||||
G4CONDITIONWAIT(&m_counterChanged,&lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4Pow.cc 93311 2015-10-16 10:16:37Z gcosmo $
|
||||
// $Id: G4Pow.cc 109086 2018-03-26 08:20:25Z gcosmo $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -40,6 +40,8 @@
|
||||
// 08.01.2011 V.Ivanchenko extended maxZ from 256 to 512
|
||||
// 02.05.2013 V.Ivanchenko added expA and logX methods,
|
||||
// revised A13, logA, powZ, powA to improved accuracy
|
||||
// 23.03.2018 M.Novak increased accuracy of A13 on the most critical
|
||||
// [1/4,4] interval by introducing a denser(0.25) grid
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -74,17 +76,20 @@ G4Pow::G4Pow()
|
||||
"Attempt to instantiate G4Pow in worker thread!");
|
||||
}
|
||||
#endif
|
||||
const G4int maxZ = 512;
|
||||
const G4int maxZ = 512;
|
||||
const G4int maxZfact = 170;
|
||||
const G4int numLowA = 17;
|
||||
|
||||
maxA = -0.6 + maxZ;
|
||||
maxA2 = 1.25 + max2*0.2;
|
||||
maxLowA = 4.0;
|
||||
maxA2 = 1.25 + max2*0.2;
|
||||
maxAexp = -0.76+ maxZfact*0.5;
|
||||
|
||||
ener.resize(max2+1,1.0);
|
||||
logen.resize(max2+1,0.0);
|
||||
lz2.resize(max2+1,0.0);
|
||||
pz13.resize(maxZ,0.0);
|
||||
lowa13.resize(numLowA,0.0);
|
||||
lz.resize(maxZ,0.0);
|
||||
fexp.resize(maxZfact,0.0);
|
||||
fact.resize(maxZfact,0.0);
|
||||
@@ -116,6 +121,11 @@ G4Pow::G4Pow()
|
||||
logf += lz[i];
|
||||
logfact[i] = logf;
|
||||
}
|
||||
|
||||
for (G4int i=4; i<numLowA; ++i) {
|
||||
lowa13[i] = std::pow(0.25*i,onethird);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@@ -125,6 +135,45 @@ G4Pow::~G4Pow()
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4double G4Pow::A13(G4double A) const {
|
||||
G4double res = 0.;
|
||||
if (A>0.) {
|
||||
const bool invert = (A<1.);
|
||||
const G4double a = invert ? 1./A : A;
|
||||
res = (a<maxLowA) ? A13Low(a, invert) : A13High(a, invert);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4double G4Pow::A13High(const G4double a, const bool invert) const {
|
||||
G4double res;
|
||||
if (a<maxA) {
|
||||
const G4int i = static_cast<G4int>(a+0.5);
|
||||
const G4double x = (a/i-1.)*onethird;
|
||||
res = pz13[i]*(1.+x-x*x*(1.-1.666667*x));
|
||||
} else {
|
||||
res = G4Exp(G4Log(a)*onethird);
|
||||
}
|
||||
res = invert ? 1./res : res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4double G4Pow::A13Low(const G4double a, const bool invert) const {
|
||||
G4double res;
|
||||
const G4int i = static_cast<G4int>(4.*(a+0.125));
|
||||
const G4double y = 0.25*i;
|
||||
const G4double x = (a/y-1.)*onethird;
|
||||
res = lowa13[i]*(1.+x-x*x*(1.-1.666667*x));
|
||||
res = invert ? 1./res : res;
|
||||
return res;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
G4double G4Pow::powN(G4double x, G4int n) const
|
||||
{
|
||||
if(0.0 == x) { return 0.0; }
|
||||
|
||||
@@ -37,5 +37,15 @@
|
||||
#include "G4Types.hh"
|
||||
#include "G4ReferenceCountedHandle.hh"
|
||||
|
||||
G4ThreadLocal G4Allocator<G4CountedObject<void> > *aCountedObjectAllocator = 0;
|
||||
G4ThreadLocal G4Allocator<G4ReferenceCountedHandle<void> > *aRCHAllocator = 0;
|
||||
G4Allocator<G4CountedObject<void>>*& aCountedObjectAllocator()
|
||||
{
|
||||
G4ThreadLocalStatic G4Allocator<G4CountedObject<void>>* _instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
G4Allocator<G4ReferenceCountedHandle<void>>*& aRCHAllocator()
|
||||
{
|
||||
G4ThreadLocalStatic G4Allocator<G4ReferenceCountedHandle<void>>*
|
||||
_instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4SliceTimer.cc 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4SliceTimer.cc 110674 2018-06-07 10:30:11Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -36,8 +36,6 @@
|
||||
#include "G4SliceTimer.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
#undef times
|
||||
|
||||
#if defined(IRIX6_2)
|
||||
# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE_EXTENDED==1)
|
||||
# define __vfork vfork
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4StateManager.cc 108486 2018-02-15 14:47:25Z gcosmo $
|
||||
// $Id: G4StateManager.cc 108402 2018-02-12 10:31:27Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@@ -58,31 +58,14 @@ namespace
|
||||
}
|
||||
|
||||
G4Pid_t G4Threading::G4GetPidId()
|
||||
{ // In multithreaded mode return Thread ID
|
||||
#if defined(__MACH__)
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
|
||||
uint64_t tid64;
|
||||
pthread_threadid_np(NULL, &tid64);
|
||||
return (pid_t)tid64;
|
||||
#else
|
||||
return syscall(SYS_thread_selfid);
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
return GetCurrentThreadId();
|
||||
#else
|
||||
return syscall(SYS_gettid);
|
||||
#endif
|
||||
{
|
||||
// In multithreaded mode return Thread ID
|
||||
return std::this_thread::get_id();
|
||||
}
|
||||
|
||||
G4int G4Threading::G4GetNumberOfCores()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo( &sysinfo );
|
||||
return static_cast<G4int>( sysinfo.dwNumberOfProcessors );
|
||||
#else
|
||||
return static_cast<G4int>(sysconf( _SC_NPROCESSORS_ONLN ));
|
||||
#endif
|
||||
return std::thread::hardware_concurrency();
|
||||
}
|
||||
|
||||
void G4Threading::G4SetThreadId(G4int value ) { G4ThreadID = value; }
|
||||
@@ -90,38 +73,40 @@ G4int G4Threading::G4GetThreadId() { return G4ThreadID; }
|
||||
G4bool G4Threading::IsWorkerThread() { return (G4ThreadID>=0); }
|
||||
G4bool G4Threading::IsMasterThread() { return (G4ThreadID==MASTER_ID); }
|
||||
|
||||
#if defined(WIN32) // WIN32 stuff needed for MT
|
||||
DWORD /*WINAPI*/ G4WaitForSingleObjectInf( __in G4Mutex m )
|
||||
{ return WaitForSingleObject( m , INFINITE); }
|
||||
BOOL G4ReleaseMutex( __in G4Mutex m)
|
||||
{ return ReleaseMutex(m); }
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(_AIX)
|
||||
G4bool G4Threading::G4SetPinAffinity(G4int cpu, G4Thread& aT)
|
||||
G4bool G4Threading::G4SetPinAffinity(G4int cpu, G4NativeThread& aT)
|
||||
{
|
||||
cpu_set_t* aset = new cpu_set_t;
|
||||
G4AutoDelete::Register(aset);
|
||||
CPU_ZERO(aset);
|
||||
CPU_SET(cpu,aset);
|
||||
return ( pthread_setaffinity_np(aT, sizeof(cpu_set_t), aset) == 0 );
|
||||
cpu_set_t* aset = new cpu_set_t;
|
||||
G4AutoDelete::Register(aset);
|
||||
CPU_ZERO(aset);
|
||||
CPU_SET(cpu, aset);
|
||||
pthread_t& _aT = (pthread_t&) (aT);
|
||||
return (pthread_setaffinity_np(_aT, sizeof(cpu_set_t), aset) == 0);
|
||||
}
|
||||
#else //Not available for Mac, WIN,...
|
||||
G4bool G4Threading::G4SetPinAffinity(G4int, G4Thread&)
|
||||
G4bool G4Threading::G4SetPinAffinity(G4int, G4NativeThread&)
|
||||
{
|
||||
G4Exception("G4Threading::G4SetPinAffinity()",
|
||||
"NotImplemented", JustWarning,
|
||||
"Affinity setting not available for this architecture, ignoring...");
|
||||
return true;
|
||||
G4Exception("G4Threading::G4SetPinAffinity()",
|
||||
"NotImplemented", JustWarning,
|
||||
"Affinity setting not available for this architecture, "
|
||||
"ignoring...");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void G4Threading::SetMultithreadedApplication(G4bool value ) { isMTAppType = value; }
|
||||
G4bool G4Threading::IsMultithreadedApplication() { return isMTAppType; }
|
||||
void G4Threading::SetMultithreadedApplication(G4bool value)
|
||||
{
|
||||
isMTAppType = value;
|
||||
}
|
||||
|
||||
G4bool G4Threading::IsMultithreadedApplication()
|
||||
{
|
||||
return isMTAppType;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::atomic_int numActThreads(0);
|
||||
std::atomic_int numActThreads(0);
|
||||
}
|
||||
int G4Threading::WorkerThreadLeavesPool() { return numActThreads--; }
|
||||
int G4Threading::WorkerThreadJoinsPool() { return numActThreads++;}
|
||||
@@ -129,15 +114,14 @@ G4int G4Threading::GetNumberOfRunningWorkerThreads() { return numActThreads.load
|
||||
|
||||
#else // Sequential mode
|
||||
|
||||
G4int fake_mutex_lock_unlock( G4Mutex* ) { return 0; }
|
||||
|
||||
G4Pid_t G4Threading::G4GetPidId()
|
||||
{ // In sequential mode return Process ID and not Thread ID
|
||||
#if defined(WIN32)
|
||||
{
|
||||
// In sequential mode return Process ID and not Thread ID
|
||||
#if defined(WIN32)
|
||||
return GetCurrentProcessId();
|
||||
#else
|
||||
#else
|
||||
return getpid();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
G4int G4Threading::G4GetNumberOfCores() { return 1; }
|
||||
@@ -146,7 +130,7 @@ G4bool G4Threading::IsWorkerThread() { return false; }
|
||||
G4bool G4Threading::IsMasterThread() { return true; }
|
||||
void G4Threading::G4SetThreadId(G4int) {}
|
||||
|
||||
G4bool G4Threading::G4SetPinAffinity(G4int,G4Thread&) { return true;}
|
||||
G4bool G4Threading::G4SetPinAffinity(G4int, G4NativeThread&) { return true; }
|
||||
|
||||
void G4Threading::SetMultithreadedApplication(G4bool) {}
|
||||
G4bool G4Threading::IsMultithreadedApplication() { return false; }
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4Timer.cc 67970 2013-03-13 10:10:06Z gcosmo $
|
||||
// $Id: G4Timer.cc 110674 2018-06-07 10:30:11Z gcosmo $
|
||||
//
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "G4Timer.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
#undef times
|
||||
#include <iomanip>
|
||||
|
||||
// Global error function
|
||||
#include "G4ExceptionSeverity.hh"
|
||||
@@ -86,16 +86,31 @@ void G4Exception(const char* originOfException,
|
||||
// Print timer status n std::ostream
|
||||
std::ostream& operator << (std::ostream& os, const G4Timer& t)
|
||||
{
|
||||
// so fixed doesn't propagate
|
||||
std::stringstream ss;
|
||||
ss << std::fixed;
|
||||
if (t.IsValid())
|
||||
{
|
||||
ss << "User=" << t.GetUserElapsed()
|
||||
<< "s Real=" << t.GetRealElapsed()
|
||||
<< "s Sys=" << t.GetSystemElapsed() << "s";
|
||||
#ifdef G4MULTITHREADED
|
||||
// avoid possible FPE error
|
||||
if(t.GetRealElapsed() > 1.0e-6)
|
||||
{
|
||||
os << "User=" << t.GetUserElapsed()
|
||||
<< "s Real=" << t.GetRealElapsed()
|
||||
<< "s Sys=" << t.GetSystemElapsed() << "s";
|
||||
double cpu_util = (t.GetUserElapsed()+t.GetRealElapsed()) /
|
||||
t.GetRealElapsed() * 100.0;
|
||||
ss << std::setprecision(1);
|
||||
ss << " [Cpu=" << std::setprecision(1) << cpu_util << "%]";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "User=****s Real=****s Sys=****s";
|
||||
}
|
||||
{
|
||||
ss << "User=****s Real=****s Sys=****s";
|
||||
}
|
||||
os << ss.str();
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -111,8 +126,8 @@ G4double G4Timer::GetRealElapsed() const
|
||||
G4Exception("G4Timer::GetRealElapsed()", "InvalidCondition",
|
||||
FatalException, "Timer not stopped or times not recorded!");
|
||||
}
|
||||
G4double diff=fEndRealTime-fStartRealTime;
|
||||
return diff/sysconf(_SC_CLK_TCK);
|
||||
std::chrono::duration<double> diff=fEndRealTime-fStartRealTime;
|
||||
return diff.count();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ios.cc 78780 2014-01-23 13:55:15Z gcosmo $
|
||||
// $Id: G4ios.cc 110251 2018-05-17 14:09:28Z gcosmo $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -36,53 +36,75 @@
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4strstreambuf.hh"
|
||||
#include <iostream>
|
||||
|
||||
#ifdef G4MULTITHREADED
|
||||
G4ThreadLocal G4strstreambuf *G4coutbuf_p = 0;
|
||||
G4ThreadLocal G4strstreambuf *G4cerrbuf_p = 0;
|
||||
G4ThreadLocal std::ostream *G4cout_p = 0;
|
||||
G4ThreadLocal std::ostream *G4cerr_p = 0;
|
||||
#define G4coutbuf (*G4coutbuf_p)
|
||||
#define G4cerrbuf (*G4cerrbuf_p)
|
||||
#define G4cout (*G4cout_p)
|
||||
#define G4cerr (*G4cerr_p)
|
||||
|
||||
void G4iosInitialization()
|
||||
{
|
||||
if (G4coutbuf_p == 0) G4coutbuf_p = new G4strstreambuf;
|
||||
if (G4cerrbuf_p == 0) G4cerrbuf_p = new G4strstreambuf;
|
||||
if (G4cout_p == 0) G4cout_p = new std::ostream(G4coutbuf_p);
|
||||
if (G4cerr_p == 0) G4cerr_p = new std::ostream(G4cerrbuf_p);
|
||||
}
|
||||
G4strstreambuf*& _G4coutbuf_p()
|
||||
{
|
||||
G4ThreadLocalStatic G4strstreambuf* _instance = new G4strstreambuf();
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void G4iosFinalization()
|
||||
{
|
||||
delete G4cout_p; G4cout_p = 0;
|
||||
delete G4cerr_p; G4cerr_p = 0;
|
||||
delete G4coutbuf_p; G4coutbuf_p = 0;
|
||||
delete G4cerrbuf_p; G4cerrbuf_p = 0;
|
||||
}
|
||||
G4strstreambuf*& _G4cerrbuf_p()
|
||||
{
|
||||
G4ThreadLocalStatic G4strstreambuf* _instance = new G4strstreambuf();
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// These two functions are guaranteed to be called at load and
|
||||
// unload of the library containing this code.
|
||||
namespace
|
||||
{
|
||||
std::ostream*& _G4cout_p()
|
||||
{
|
||||
G4ThreadLocalStatic std::ostream* _instance = new std::ostream(_G4coutbuf_p());
|
||||
return _instance;
|
||||
}
|
||||
|
||||
std::ostream*& _G4cerr_p()
|
||||
{
|
||||
G4ThreadLocalStatic std::ostream* _instance = new std::ostream(_G4cerrbuf_p());
|
||||
return _instance;
|
||||
}
|
||||
|
||||
#define G4coutbuf (*_G4coutbuf_p())
|
||||
#define G4cerrbuf (*_G4cerrbuf_p())
|
||||
#define G4cout (*_G4cout_p())
|
||||
#define G4cerr (*_G4cerr_p())
|
||||
|
||||
void G4iosInitialization()
|
||||
{
|
||||
if (_G4coutbuf_p() == 0) _G4coutbuf_p() = new G4strstreambuf;
|
||||
if (_G4cerrbuf_p() == 0) _G4cerrbuf_p() = new G4strstreambuf;
|
||||
if (_G4cout_p() == &std::cout || _G4cout_p() == 0) _G4cout_p() = new std::ostream(_G4coutbuf_p());
|
||||
if (_G4cerr_p() == &std::cerr || _G4cerr_p() == 0) _G4cerr_p() = new std::ostream(_G4cerrbuf_p());
|
||||
}
|
||||
|
||||
void G4iosFinalization()
|
||||
{
|
||||
delete _G4cout_p(); _G4cout_p() = &std::cout;
|
||||
delete _G4cerr_p(); _G4cerr_p() = &std::cerr;
|
||||
delete _G4coutbuf_p(); _G4coutbuf_p() = nullptr;
|
||||
delete _G4cerrbuf_p(); _G4cerrbuf_p() = nullptr;
|
||||
}
|
||||
|
||||
// These two functions are guaranteed to be called at load and
|
||||
// unload of the library containing this code.
|
||||
namespace
|
||||
{
|
||||
#ifndef WIN32
|
||||
void setupG4ioSystem(void) __attribute__ ((constructor));
|
||||
void cleanupG4ioSystem(void) __attribute__((destructor));
|
||||
#endif
|
||||
void setupG4ioSystem(void) { G4iosInitialization(); }
|
||||
void cleanupG4ioSystem(void) { G4iosFinalization(); }
|
||||
}
|
||||
}
|
||||
|
||||
#else // Sequential
|
||||
|
||||
G4strstreambuf G4coutbuf;
|
||||
G4strstreambuf G4cerrbuf;
|
||||
std::ostream G4cout(&G4coutbuf);
|
||||
std::ostream G4cerr(&G4cerrbuf);
|
||||
G4strstreambuf G4coutbuf;
|
||||
G4strstreambuf G4cerrbuf;
|
||||
std::ostream G4cout(&G4coutbuf);
|
||||
std::ostream G4cerr(&G4cerrbuf);
|
||||
|
||||
void G4iosInitialization() {}
|
||||
void G4iosFinalization() {}
|
||||
void G4iosInitialization() {}
|
||||
void G4iosFinalization() {}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user