Import Geant4 9.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 15:58:43 +02:00
parent 96c8bcd0af
commit b79225fb37
7544 changed files with 245407 additions and 91099 deletions
@@ -14,6 +14,83 @@ code and to keep track of all tags.
* Please list in reverse chronological order (last date on top)
---------------------------------------------------------------
01 December 2008 Dennis Wright (hadr-man-V09-01-10)
---------------------------------------------------
- G4HadronicProcess - make MeanFreePath() public again. In future
make it protected again, but make a public method which calls it.
21 November 2008 Dennis Wright (hadr-man-V09-01-09)
---------------------------------------------------
- G4HadronicProcess - remove again method SetDispatch for major release
22 October 2008 Vladimir Ivanchenko (hadr-man-V09-01-08)
------------------------------------------------------
- G4HadronicProcessStore - use G4HadronicProcessType enumerator
- G4HadronicProcess - returned back obsolete method SetDispatch for minor release
02 October 2008 Dennis Wright (hadr-man-V09-01-07)
--------------------------------------------------
- create new hadronic process subtype enum G4HadronicProcessType:
enum G4HadronicProcessType
{
fHadronElastic = 111,
fHadronInelastic = 121,
fCapture = 131,
fFission = 141,
fHadronAtRest = 151,
fChargeExchange = 161
};
- G4HadronicProcess.hh - add enum to identify process subtypes
- G4HadronInelasticProcess.cc - change process sub-type from 12 to fHadronInelastic
04 August 2008 Vladimir Ivanchenko (hadr-man-V09-01-06)
------------------------------------------------------
- G4HadronicProcessStore - improve cout
- G4HadronicProcess - cleanup: use method SampleZandA to select an isotope
do not use home-made NanCheck
do not check environment variables run-time
directly fill G4HadronicWhiteBoard
implement PostStepDoIt and DumpPhysicsTable
methods
- G4HadronInelasticProcess - use methods of the base class
04 August 2008 Vladimir Ivanchenko (hadr-man-V09-01-05)
------------------------------------------------------
- G4HadronicProcessStore - use sub-types to access cross sections,
add proceses following only G4VProcess interface
08 July 2008 Dennis Wright (hadr-man-V09-01-04)
-----------------------------------------------
- set process sub-type to 12 for G4HadronInelasticProcess
09 June 2008 Dennis Wright (hadr-man-V09-01-03)
-----------------------------------------------
- G4HadronicProcess.cc - turn off error in case of fStopButAlive, but leave
it in place for fStopAndKill, fKillTrackAndSecondaries and fPostponeToNextEvent
05 June 2008 Vladimir Ivanchenko (hadr-man-V09-01-02)
----------------------------------------------------
- G4HadronicProcessStore - comment out destructor
19 May 2008 Vladimir Ivanchenko (hadr-man-V09-01-01)
----------------------------------------------------
- G4HadronicProcessStore - new singleton to keep pointers to all
hadronic processes
- G4HadronicProcess - added PreparPhysicsTable and BuildPhysicsTable
methods, added registration in G4HadronicProcessStore
19 May 2008 Vladimir Ivanchenko (hadr-man-V09-01-00)
----------------------------------------------------
- G4HadronicProcess - cleanup of the header (add comments, move
methods for isotope production to the src, make
GetMeanFreePath protected, remove duplication
of PostStepDoIt), add default implementation of
GetMicroscopicCrossSection, comment out check
IfApplicable in MeanFreePath
15 October 2007 Dennis Wright (hadr-man-V09-00-00)
--------------------------------------------------
- G4HadronicProcess::FillTotalResult: T. Koi's fix of bug #967 - replaced
@@ -25,7 +25,7 @@
//
//
// $Id: G4EnergyRangeManager.hh,v 1.9 2006/06/29 19:58:05 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
// Hadronic Process: Energy Range Manager
// original by H.P. Wellisch
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
// --------------------------------------------------------------------
#ifndef G4HadLeadBias_h
@@ -42,40 +42,25 @@
#define G4HadronInelasticProcess_h 1
#include "G4HadronicProcess.hh"
//#include "G4LPhysicsFreeVector.hh"
#include "G4HadronCrossSections.hh"
#include "G4CrossSectionDataStore.hh"
#include "G4HadronInelasticDataSet.hh"
#include "G4ParticleChange.hh"
class G4HadronInelasticProcess : public G4HadronicProcess
{
public:
class G4ParticleDefinition;
class G4HadronInelasticProcess : public G4HadronicProcess
{
public:
G4HadronInelasticProcess(
const G4String &processName,
G4ParticleDefinition *aParticle );
G4HadronInelasticProcess(const G4String &processName,
G4ParticleDefinition *aParticle );
virtual ~G4HadronInelasticProcess();
virtual ~G4HadronInelasticProcess();
void BuildThePhysicsTable();
G4bool IsApplicable(const G4ParticleDefinition& aP);
virtual G4bool IsApplicable(const G4ParticleDefinition& aParticleType);
G4VParticleChange *PostStepDoIt(const G4Track &aTrack, const G4Step &aStep);
private:
private:
G4ParticleDefinition* theParticle;
virtual G4double GetMicroscopicCrossSection( const G4DynamicParticle *aParticle,
const G4Element *anElement,
G4double aTemp );
protected:
G4ParticleDefinition *theParticle;
G4ParticleChange theParticleChange;
};
};
#endif
@@ -25,16 +25,14 @@
//
//
//
// This is the top level Hadronic Process class
// The inelastic, elastic, capture, and fission processes
// should derive from this class
// This is an abstract base class, since the pure virtual function
// PostStepDoIt has not been defined yet.
// Note: there is no .cc file
//
// original by H.P.Wellisch
// J.L. Chuma, TRIUMF, 10-Mar-1997
// Last modified: 04-Apr-1997
// This is the top level Hadronic Process class
// The inelastic, elastic, capture, and fission processes
// should derive from this class
//
// original by H.P.Wellisch
// J.L. Chuma, TRIUMF, 10-Mar-1997
// Last modified: 04-Apr-1997
// 19-May-2008 V.Ivanchenko cleanup and added comments
#ifndef G4HadronicProcess_h
#define G4HadronicProcess_h 1
@@ -49,193 +47,173 @@
#include "G4IsoParticleChange.hh"
#include "G4VCrossSectionDataSet.hh"
#include "G4VLeadingParticleBiasing.hh"
#include "G4Delete.hh"
//#include "G4Delete.hh"
#include "G4CrossSectionDataStore.hh"
#include "G4HadronicException.hh"
#include "G4HadronicProcessType.hh"
class G4Track;
class G4Step;
class G4Element;
class G4ParticleChange;
class G4HadronicProcess : public G4VDiscreteProcess
{
public:
class G4HadronicProcess : public G4VDiscreteProcess
{
public:
G4HadronicProcess( const G4String &processName = "Hadronic",
G4ProcessType aType = fHadronic );
virtual ~G4HadronicProcess();
G4HadronicProcess( const G4String &processName = "Hadronic",
G4ProcessType aType = fHadronic );
void RegisterMe( G4HadronicInteraction *a );
virtual ~G4HadronicProcess();
void AddDataSet(G4VCrossSectionDataSet * aDataSet)
{
theCrossSectionDataStore->AddDataSet(aDataSet);
}
virtual G4VParticleChange *PostStepDoIt( const G4Track &aTrack,
const G4Step &aStep ) = 0;
virtual
G4double GetMicroscopicCrossSection(const G4DynamicParticle *aParticle,
const G4Element *anElement,
G4double aTemp ) = 0;
G4double GetMeanFreePath(const G4Track &aTrack, G4double,
G4ForceCondition *);
// register generator of secondaries
void RegisterMe( G4HadronicInteraction *a );
// Set methods for isotope production
static void EnableIsotopeProductionGlobally();
static void DisableIsotopeProductionGlobally();
void EnableIsotopeCounting() {isoIsOnAnyway = 1;}
void DisableIsotopeCounting() {isoIsOnAnyway = -1;}
void RegisterIsotopeProductionModel(G4VIsotopeProduction * aModel)
{ theProductionModels.push_back(aModel); }
// get cross section per element
virtual
G4double GetMicroscopicCrossSection(const G4DynamicParticle *aParticle,
const G4Element *anElement,
G4double aTemp );
static G4IsoParticleChange * GetIsotopeProductionInfo()
{
G4IsoParticleChange * anIsoResult = theIsoResult;
if(theIsoResult) theOldIsoResult = theIsoResult;
theIsoResult = 0;
return anIsoResult;
}
// generic PostStepDoIt recommended for all derived classes
virtual G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep);
void BiasCrossSectionByFactor(G4double aScale)
{
xBiasOn = true;
aScaleFactor = aScale;
G4String it = GetProcessName();
if( (it != "PhotonInelastic") &&
(it != "ElectroNuclear") &&
(it != "PositronNuclear") )
{
G4Exception("G4HadronicProcess", "007", FatalException,
"Cross-section biasing available only for gamma and electro nuclear reactions.");
}
if(aScale<100)
{
G4Exception("G4HadronicProcess", "001", JustWarning,
"Cross-section bias readjusted to be above safe limit. New value is 100");
aScaleFactor = 100.;
}
}
protected:
virtual void ResetNumberOfInteractionLengthLeft()
{
G4VProcess::theNumberOfInteractionLengthLeft =
-std::log( G4UniformRand() );
theInitialNumberOfInteractionLength =
G4VProcess::theNumberOfInteractionLengthLeft;
}
// initialisation of physics tables and G4HadronicProcessStore
virtual void PreparePhysicsTable(const G4ParticleDefinition&);
G4VParticleChange *GeneralPostStepDoIt( const G4Track &aTrack,
const G4Step &aStep );
void SetDispatch( G4HadronicProcess *value )
{ dispatch=value; }
G4Element* ChooseAandZ(const G4DynamicParticle *aParticle,
const G4Material *aMaterial);
// build physics tables and print out the configuration of the process
virtual void BuildPhysicsTable(const G4ParticleDefinition&);
inline const G4EnergyRangeManager &GetEnergyRangeManager() const
{ return theEnergyRangeManager; }
// dump physics tables
inline void DumpPhysicsTable(const G4ParticleDefinition& p)
{ theCrossSectionDataStore->DumpPhysicsTable(p); }
// add cross section data set
inline void AddDataSet(G4VCrossSectionDataSet * aDataSet)
{ theCrossSectionDataStore->AddDataSet(aDataSet);}
// access to the manager
inline G4EnergyRangeManager *GetManagerPointer()
{ return &theEnergyRangeManager; }
// get inverse cross section per volume
G4double GetMeanFreePath(const G4Track &aTrack, G4double,
G4ForceCondition *);
protected:
// reset number of interaction length and save
virtual void ResetNumberOfInteractionLengthLeft()
{ G4VProcess::ResetNumberOfInteractionLengthLeft();
theInitialNumberOfInteractionLength =
G4VProcess::theNumberOfInteractionLengthLeft;
}
// generic method to choose secondary generator
// recommended for all derived classes
inline G4HadronicInteraction *ChooseHadronicInteraction(
G4double kineticEnergy, G4Material *aMaterial, G4Element *anElement )
{ return theEnergyRangeManager.GetHadronicInteraction(kineticEnergy,
aMaterial,anElement);
}
public:
// Methods for isotope production
static void EnableIsotopeProductionGlobally();
static void DisableIsotopeProductionGlobally();
inline void SetEnergyRangeManager( const G4EnergyRangeManager &value )
{ theEnergyRangeManager = value; }
inline G4HadronicInteraction *ChooseHadronicInteraction(
G4double kineticEnergy, G4Material *aMaterial, G4Element *anElement )
{
G4EnergyRangeManager* ERMan = GetManagerPointer();
if(!ERMan->GetHadronicInteractionCounter())
G4cout<< "*G4HadronicProcess::ChooseHadronicInteraction: process = "
<< GetProcessName() << ", nM="
<< ERMan->GetHadronicInteractionCounter() << G4endl;
return ERMan->GetHadronicInteraction(kineticEnergy,aMaterial,anElement);
}
inline G4HadronicInteraction *GetHadronicInteraction()
{ return theInteraction; }
void EnableIsotopeCounting() {isoIsOnAnyway = 1;}
void DisableIsotopeCounting() {isoIsOnAnyway = -1;}
public:
inline G4EnergyRangeManager *GetManagerPointer()
{ return &theEnergyRangeManager; }
protected:
void RegisterIsotopeProductionModel(G4VIsotopeProduction * aModel)
{ theProductionModels.push_back(aModel); }
G4CrossSectionDataStore* GetCrossSectionDataStore()
{
return theCrossSectionDataStore;
}
static G4IsoParticleChange * GetIsotopeProductionInfo();
void BiasCrossSectionByFactor(G4double aScale);
protected:
// obsolete method will be removed
inline const G4EnergyRangeManager &GetEnergyRangeManager() const
{ return theEnergyRangeManager; }
// obsolete method will be removed
inline void SetEnergyRangeManager( const G4EnergyRangeManager &value )
{ theEnergyRangeManager = value; }
// access to the chosen generator
inline G4HadronicInteraction *GetHadronicInteraction()
{ return theInteraction; }
// access to the cross section data store
inline G4CrossSectionDataStore* GetCrossSectionDataStore()
{ return theCrossSectionDataStore; }
G4double GetLastCrossSection() {return theLastCrossSection;}
private:
// access to the cross section data set
inline G4double GetLastCrossSection()
{ return theLastCrossSection; }
private:
G4HadFinalState * DoIsotopeCounting(G4HadFinalState * aResult,
const G4Track & aTrack,
const G4Nucleus & aNucleus);
void FillTotalResult(G4HadFinalState * aR, const G4Track & aT);
G4HadFinalState * DoIsotopeCounting(G4HadFinalState * aResult,
const G4Track & aTrack,
const G4Nucleus & aNucleus);
G4IsoResult * ExtractResidualNucleus(const G4Track & aTrack,
const G4Nucleus & aNucleus,
G4HadFinalState * aResult);
G4IsoResult * ExtractResidualNucleus(const G4Track & aTrack,
const G4Nucleus & aNucleus,
G4HadFinalState * aResult);
G4double GetTotalNumberOfInteractionLengthTraversed()
{
return theInitialNumberOfInteractionLength
-G4VProcess::theNumberOfInteractionLengthLeft;
}
inline G4double GetTotalNumberOfInteractionLengthTraversed()
{ return theInitialNumberOfInteractionLength
-G4VProcess::theNumberOfInteractionLengthLeft;
}
// inline void SetCrossSectionDataStore(G4CrossSectionDataStore* aDataStore)
// { theCrossSectionDataStore = aDataStore; }
G4double XBiasSurvivalProbability();
G4double XBiasSecondaryWeight();
private:
G4EnergyRangeManager theEnergyRangeManager;
G4HadronicInteraction *theInteraction;
void FillTotalResult(G4HadFinalState * aR, const G4Track & aT);
void SetCrossSectionDataStore(G4CrossSectionDataStore* aDataStore)
{
theCrossSectionDataStore = aDataStore;
}
G4double XBiasSurvivalProbability();
G4double XBiasSecondaryWeight();
private:
G4EnergyRangeManager theEnergyRangeManager;
G4HadronicInteraction *theInteraction;
G4CrossSectionDataStore* theCrossSectionDataStore;
G4CrossSectionDataStore* theCrossSectionDataStore;
G4Nucleus targetNucleus;
G4Nucleus targetNucleus;
G4HadronicProcess *dispatch;
G4HadronicProcess *dispatch;
// swiches for isotope production
static G4bool isoIsEnabled; // true or false; local swich overrides
G4int isoIsOnAnyway; // true(1), false(-1) or default(0)
G4IsoParticleChange theIsoPC;
std::vector<G4VIsotopeProduction *> theProductionModels;
std::vector<G4VLeadingParticleBiasing *> theBias;
bool G4HadronicProcess_debug_flag;
static G4IsoParticleChange* theIsoResult;
static G4IsoParticleChange* theOldIsoResult;
// swiches for isotope production
static G4bool isoIsEnabled; // true or false; local swich overrides
G4int isoIsOnAnyway; // true(1), false(-1) or default(0)
G4ParticleChange* theTotalResult;
G4IsoParticleChange theIsoPC;
std::vector<G4VIsotopeProduction *> theProductionModels;
G4double theInitialNumberOfInteractionLength;
std::vector<G4VLeadingParticleBiasing *> theBias;
G4double aScaleFactor;
G4bool xBiasOn;
G4double theLastCrossSection;
static G4IsoParticleChange* theIsoResult;
static G4IsoParticleChange* theOldIsoResult;
G4ParticleChange* theTotalResult;
G4double theInitialNumberOfInteractionLength;
G4int ModelingState;
};
G4double aScaleFactor;
G4bool xBiasOn;
G4double theLastCrossSection;
G4int ModelingState;
};
#endif
@@ -0,0 +1,226 @@
//
// ********************************************************************
// * 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: G4HadronicProcessStore.hh,v 1.3 2008/10/22 07:58:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class header file
//
//
// File name: G4HadronicProcessStore
//
// Author: Vladimir Ivanchenko
//
// Creation date: 09.05.2008
//
// Modifications:
//
//
// Class Description:
//
// -------------------------------------------------------------------
//
#ifndef G4HadronicProcessStore_h
#define G4HadronicProcessStore_h 1
#include "globals.hh"
#include "G4DynamicParticle.hh"
#include "G4HadronicProcess.hh"
#include "G4HadronicInteraction.hh"
#include "G4ParticleDefinition.hh"
#include "G4HadronicProcessType.hh"
#include <map>
#include <vector>
class G4Element;
class G4HadronicProcessStore
{
public:
static G4HadronicProcessStore* Instance();
~G4HadronicProcessStore();
G4double GetInelasticCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material);
G4double GetInelasticCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement);
G4double GetInelasticCrossSectionPerIsotope(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
G4int Z, G4int A);
G4double GetElasticCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material);
G4double GetElasticCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement);
G4double GetElasticCrossSectionPerIsotope(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
G4int Z, G4int A);
G4double GetCaptureCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material);
G4double GetCaptureCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement);
G4double GetCaptureCrossSectionPerIsotope(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
G4int Z, G4int A);
G4double GetFissionCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material);
G4double GetFissionCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement);
G4double GetFissionCrossSectionPerIsotope(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
G4int Z, G4int A);
G4double GetChargeExchangeCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material);
G4double GetChargeExchangeCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement);
G4double GetChargeExchangeCrossSectionPerIsotope(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
G4int Z, G4int A);
// register/deregister processes following G4HadronicProcess interface
void Register(G4HadronicProcess*);
void RegisterParticle(G4HadronicProcess*,
const G4ParticleDefinition*);
void RegisterInteraction(G4HadronicProcess*,
G4HadronicInteraction*);
void DeRegister(G4HadronicProcess*);
// register/deregister processes following only G4VProcess interface
void RegisterExtraProcess(G4VProcess*);
void RegisterParticleForExtraProcess(G4VProcess*,
const G4ParticleDefinition*);
void DeRegisterExtraProcess(G4VProcess*);
void PrintInfo(const G4ParticleDefinition*);
void Dump(G4int level);
void SetVerbose(G4int val);
G4int GetVerbose();
G4HadronicProcess* FindProcess(const G4ParticleDefinition*,
G4HadronicProcessType subType);
private:
// constructor
G4HadronicProcessStore();
// print process info
void Print(G4int idxProcess, G4int idxParticle);
static G4HadronicProcessStore* theInstance;
typedef const G4ParticleDefinition* PD;
typedef G4HadronicProcess* HP;
typedef G4HadronicInteraction* HI;
// hadronic processes following G4HadronicProcess interface
std::vector<G4HadronicProcess*> process;
std::vector<G4HadronicInteraction*> model;
std::vector<G4String> modelName;
std::vector<PD> particle;
std::vector<G4int> wasPrinted;
std::multimap<PD,HP> p_map;
std::multimap<HP,HI> m_map;
// hadronic processes following only G4VProcess interface
std::vector<G4VProcess*> extraProcess;
std::multimap<PD,G4VProcess*> ep_map;
// counters and options
G4int n_proc;
G4int n_model;
G4int n_part;
G4int n_extra;
G4int verbose;
G4bool buildTableStart;
// cash
HP currentProcess;
PD currentParticle;
G4DynamicParticle localDP;
};
#endif
@@ -0,0 +1,52 @@
//
// ********************************************************************
// * 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: G4HadronicProcessType.hh,v 1.1 2008/10/02 19:02:03 dennis Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
//
//---------------------------------------------------------------
//
// G4HadronicProcessType.hh
//
// Class Description:
// Enumerator to define hadronic process sub-type
//
//---------------------------------------------------------------
#ifndef G4HadronicProcessType_h
#define G4HadronicProcessType_h 1
enum G4HadronicProcessType
{
fHadronElastic = 111,
fHadronInelastic = 121,
fCapture = 131,
fFission = 141,
fHadronAtRest = 151,
fChargeExchange = 161
};
#endif
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4VLeadingParticleBiasing.hh,v 1.6 2006/06/29 19:58:19 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
// --------------------------------------------------------------------
#ifndef G4VLeadingParticleBiasing_h
@@ -25,7 +25,7 @@
//
//
// $Id: G4EnergyRangeManager.cc,v 1.15 2006/06/29 19:58:21 gunter Exp $
// GEANT4 tag $Name: geant4-09-01 $
// GEANT4 tag $Name: geant4-09-02 $
//
// Hadronic Process: Energy Range Manager
// original by H.P. Wellisch
@@ -24,84 +24,37 @@
// ********************************************************************
//
//
//
// Hadronic Inelastic Process Class
// J.L. Chuma, TRIUMF, 24-Mar-1997
// Last modified: 27-Mar-1997
// J.P. Wellisch: Bug hunting, 23-Apr-97
// Modified by J.L.Chuma 8-Jul-97 to eliminate possible division by zero for sigma
// Hadronic Inelastic Process Class
// J.L. Chuma, TRIUMF, 24-Mar-1997
// Last modified: 27-Mar-1997
// J.P. Wellisch: Bug hunting, 23-Apr-97
// Modified by J.L.Chuma 8-Jul-97 to eliminate possible division by zero for sigma
//
// 14-APR-98 F.W.Jones: variant G4HadronInelastic process for
// G4CrossSectionDataSet/DataStore class design.
//
// 17-JUN-98 F.W.Jones: removed extraneous code causing core dump.
// 01-SEP-2008 V.Ivanchenko: use methods from the base class
//
#include "G4HadronInelasticProcess.hh"
#include "G4HadronInelasticDataSet.hh"
#include "G4GenericIon.hh"
#include "G4ProcessManager.hh"
#include "G4ProcessVector.hh"
#include "G4HadronicException.hh"
#include "G4ParticleDefinition.hh"
void G4HadronInelasticProcess::BuildThePhysicsTable()
{
if (!G4HadronicProcess::GetCrossSectionDataStore()) {
return;
}
G4HadronicProcess::GetCrossSectionDataStore()->BuildPhysicsTable(*theParticle);
}
G4HadronInelasticProcess::G4HadronInelasticProcess(
const G4String &processName,
G4ParticleDefinition *aParticle ) :
G4HadronicProcess( processName )
{
G4HadronicProcess::AddDataSet(new G4HadronInelasticDataSet);
theParticle = aParticle;
}
G4HadronInelasticProcess::G4HadronInelasticProcess(const G4String& processName,
G4ParticleDefinition* aParticle):
G4HadronicProcess(processName)
{
SetProcessSubType(fHadronInelastic);
AddDataSet(new G4HadronInelasticDataSet());
theParticle = aParticle;
}
G4HadronInelasticProcess::~G4HadronInelasticProcess() { }
G4HadronInelasticProcess::~G4HadronInelasticProcess()
{}
G4VParticleChange *G4HadronInelasticProcess::
PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
{
if(0==GetLastCrossSection()&&!getenv("DebugNeutronHP"))
{
G4cerr << "G4HadronInelasticProcess: called for final state, while cross-section was zero"<<G4endl;
G4cerr << " Returning empty particle change...."<<G4endl;
G4double dummy=0;
G4ForceCondition condition;
G4double it = GetMeanFreePath(aTrack, dummy, &condition);
G4cerr << " current MeanFreePath is "<<it<<G4endl;
theParticleChange.Initialize(aTrack);
return &theParticleChange;
}
SetDispatch( this );
return G4HadronicProcess::GeneralPostStepDoIt( aTrack, aStep );
}
G4bool G4HadronInelasticProcess::
IsApplicable(const G4ParticleDefinition& aP)
{
return theParticle == &aP || theParticle == G4GenericIon::GenericIon();
}
G4double G4HadronInelasticProcess::GetMicroscopicCrossSection(
const G4DynamicParticle *aParticle,
const G4Element *anElement,
G4double aTemp)
{
// returns the microscopic cross section in GEANT4 internal units
if (!G4HadronicProcess::GetCrossSectionDataStore())
{
throw G4HadronicException(__FILE__, __LINE__,
"G4HadronInelasticProcess::GetMicroscopicCrossSection: "
"no CrossSectionDataStore");
return DBL_MIN;
}
return G4HadronicProcess::GetCrossSectionDataStore()->GetCrossSection(aParticle, anElement, aTemp);
}
/* end of file */
G4bool G4HadronInelasticProcess::IsApplicable(const G4ParticleDefinition& aP)
{
return theParticle == &aP || theParticle == G4GenericIon::GenericIon();
}
@@ -27,11 +27,11 @@
#include "G4Types.hh"
#include <fstream>
#include <sstream>
#include <stdlib.h>
//#include <fstream>
//#include <sstream>
//#include <stdlib.h>
#include "G4HadronicProcess.hh"
// #include "G4EffectiveCharge.hh"
#include "G4HadProjectile.hh"
#include "G4ElementVector.hh"
#include "G4Track.hh"
@@ -48,10 +48,13 @@
#include "G4HadLeadBias.hh"
#include "G4HadronicException.hh"
#include "G4HadReentrentException.hh"
#include "G4HadronicInteractionWrapper.hh"
#include "G4HadronicWhiteBoard.hh"
#include "G4HadSignalHandler.hh"
#include "G4HadronicProcessStore.hh"
#include <typeinfo>
namespace G4HadronicProcess_local
@@ -72,6 +75,8 @@ EnableIsotopeProductionGlobally() {isoIsEnabled = true;}
void G4HadronicProcess::
DisableIsotopeProductionGlobally() {isoIsEnabled = false;}
//////////////////////////////////////////////////////////////////
G4HadronicProcess::G4HadronicProcess( const G4String &processName,
G4ProcessType aType ) :
G4VDiscreteProcess( processName, aType)
@@ -80,20 +85,24 @@ G4VDiscreteProcess( processName, aType)
isoIsOnAnyway = -1;
theTotalResult = new G4ParticleChange();
theCrossSectionDataStore = new G4CrossSectionDataStore();
G4HadronicProcessStore::Instance()->Register(this);
aScaleFactor = 1;
xBiasOn = false;
G4HadronicProcess_debug_flag = false;
if(getenv("SwitchLeadBiasOn")) theBias.push_back(new G4HadLeadBias());
}
G4HadronicProcess::~G4HadronicProcess()
{
G4HadronicProcessStore::Instance()->DeRegister(this);
delete theTotalResult;
std::for_each(theProductionModels.begin(),
theProductionModels.end(), G4Delete());
std::for_each(theBias.begin(), theBias.end(), G4Delete());
delete theOldIsoResult; delete theIsoResult;
delete theOldIsoResult;
delete theIsoResult;
delete theCrossSectionDataStore;
}
@@ -106,40 +115,30 @@ void G4HadronicProcess::RegisterMe( G4HadronicInteraction *a )
G4Exception("G4HadronicProcess", "007", FatalException,
"Could not register G4HadronicInteraction");
}
G4HadronicProcessStore::Instance()->RegisterInteraction(this, a);
}
void G4HadronicProcess::PreparePhysicsTable(const G4ParticleDefinition& p)
{
if(getenv("G4HadronicProcess_debug")) G4HadronicProcess_debug_flag = true;
G4HadronicProcessStore::Instance()->RegisterParticle(this, &p);
}
void G4HadronicProcess::BuildPhysicsTable(const G4ParticleDefinition& p)
{
theCrossSectionDataStore->BuildPhysicsTable(p);
G4HadronicProcessStore::Instance()->PrintInfo(&p);
}
G4double G4HadronicProcess::
GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
{
G4double sigma = 0.0;
try
{
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
if( !IsApplicable(*aParticle->GetDefinition()))
{
G4cout << "Unrecoverable error: "<<G4endl;
G4ProcessManager * it = aParticle->GetDefinition()->GetProcessManager();
G4ProcessVector * itv = it->GetProcessList();
G4cout <<aParticle->GetDefinition()->GetParticleName()<<
" has the following processes:"<<G4endl;
for(G4int i=0; i<itv->size(); i++)
{
G4cout <<" "<<(*itv)[i]->GetProcessName()<<G4endl;
}
G4cout << "for kinetic energy "<<aParticle->GetKineticEnergy()<<G4endl;
G4cout << "and material "<<aTrack.GetMaterial()->GetName()<<G4endl;
G4Exception("G4HadronicProcess", "007", FatalException,
std::string(this->GetProcessName()+
" was called for "+
aParticle->GetDefinition()->GetParticleName()).c_str() );
}
G4Material *aMaterial = aTrack.GetMaterial();
ModelingState = 1;
sigma = theCrossSectionDataStore->GetCrossSection(aParticle, aMaterial);
sigma *= aScaleFactor;
theLastCrossSection = sigma;
ModelingState = 1;
theLastCrossSection = aScaleFactor*
theCrossSectionDataStore->GetCrossSection(aTrack.GetDynamicParticle(),
aTrack.GetMaterial());
}
catch(G4HadronicException aR)
{
@@ -147,68 +146,54 @@ GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
G4Exception("G4HadronicProcess", "007", FatalException,
"G4HadronicProcess::GetMeanFreePath failed");
}
if( sigma > 0.0 )
return 1.0/sigma;
else
return DBL_MAX;
G4double res = DBL_MAX;
if( theLastCrossSection > 0.0 ) res = 1.0/theLastCrossSection;
return res;
}
G4Element* G4HadronicProcess::ChooseAandZ(
const G4DynamicParticle *aParticle, const G4Material *aMaterial )
G4double G4HadronicProcess::
GetMicroscopicCrossSection(const G4DynamicParticle *aParticle,
const G4Element *anElement,
G4double aTemp )
{
std::pair<G4double, G4double> ZA =
theCrossSectionDataStore->SelectRandomIsotope(aParticle, aMaterial);
G4double ZZ = ZA.first;
G4double AA = ZA.second;
targetNucleus.SetParameters(AA, ZZ);
const G4int numberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
G4Element* chosen = 0;
for (G4int i = 0; i < numberOfElements; i++) {
chosen = (*theElementVector)[i];
if (chosen->GetZ() == ZZ) break;
}
return chosen;
return
theCrossSectionDataStore->GetCrossSection(aParticle, anElement, aTemp);
}
struct G4Nancheck{ bool operator()(G4double aV){return (!(aV<1))&&(!(aV>-1));}};
G4VParticleChange *G4HadronicProcess::GeneralPostStepDoIt(
const G4Track &aTrack, const G4Step &)
G4VParticleChange *G4HadronicProcess::PostStepDoIt(
const G4Track &aTrack, const G4Step &)
{
// Debugging stuff
bool G4HadronicProcess_debug_flag = false;
if(getenv("G4HadronicProcess_debug")) G4HadronicProcess_debug_flag = true;
if(G4HadronicProcess_debug_flag)
std::cout << "@@@@ hadronic process start "<< std::endl;
// G4cout << theNumberOfInteractionLengthLeft<<G4endl;
#ifndef G4HadSignalHandler_off
#ifndef G4HadSignalHandler_off
G4HadSignalHandler aHandler(G4HadronicProcess_local::G4HadronicProcessHandler_1);
#endif
#endif
if(aTrack.GetTrackStatus() != fAlive && aTrack.GetTrackStatus() != fSuspend)
{
G4cerr << "G4HadronicProcess: track in unusable state - "
<<aTrack.GetTrackStatus()<<G4endl;
G4cerr << "G4HadronicProcess: returning unchanged track "<<G4endl;
G4Exception("G4HadronicProcess", "001", JustWarning, "bailing out");
if(aTrack.GetTrackStatus() != fAlive && aTrack.GetTrackStatus() != fSuspend) {
if (aTrack.GetTrackStatus() == fStopAndKill ||
aTrack.GetTrackStatus() == fKillTrackAndSecondaries ||
aTrack.GetTrackStatus() == fPostponeToNextEvent) {
G4cerr << "G4HadronicProcess: track in unusable state - "
<< aTrack.GetTrackStatus() << G4endl;
G4cerr << "G4HadronicProcess: returning unchanged track " << G4endl;
G4Exception("G4HadronicProcess", "001", JustWarning, "bailing out");
}
// No warning for fStopButAlive which is a legal status here
theTotalResult->Clear();
theTotalResult->Initialize(aTrack);
return theTotalResult;
}
const G4DynamicParticle *aParticle = aTrack.GetDynamicParticle();
G4Material *aMaterial = aTrack.GetMaterial();
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
G4Material* aMaterial = aTrack.GetMaterial();
G4double originalEnergy = aParticle->GetKineticEnergy();
G4double kineticEnergy = originalEnergy;
// More debugging
/*
// It is not needed with standard NaN check
// More debugging
G4Nancheck go_wild;
if(go_wild(originalEnergy) ||
go_wild(aParticle->Get4Momentum().x()) ||
@@ -222,16 +207,19 @@ const G4Track &aTrack, const G4Step &)
theTotalResult->Initialize(aTrack);
return theTotalResult;
}
*/
// Get kinetic energy per nucleon for ions
if(aParticle->GetDefinition()->GetBaryonNumber() > 1.5)
kineticEnergy/=aParticle->GetDefinition()->GetBaryonNumber();
G4Element* anElement = 0;
try
{
anElement = ChooseAandZ( aParticle, aMaterial );
// anElement = ChooseAandZ( aParticle, aMaterial );
anElement = theCrossSectionDataStore->SampleZandA(aParticle,
aMaterial,
targetNucleus);
}
catch(G4HadronicException & aR)
{
@@ -242,7 +230,7 @@ const G4Track &aTrack, const G4Step &)
G4cout << " - Particle type = "
<<aParticle->GetDefinition()->GetParticleName()<<G4endl;
G4Exception("G4HadronicProcess", "007", FatalException,
"GeneralPostStepDoIt failed on element selection.");
"PostStepDoIt failed on element selection.");
}
try
@@ -274,14 +262,16 @@ const G4Track &aTrack, const G4Step &)
try
{
// Call the interaction
G4HadronicInteractionWrapper aW;
result = aW.ApplyInteraction(thePro, targetNucleus, theInteraction,
GetProcessName(),
theInteraction->GetModelName());
result = theInteraction->ApplyYourself( thePro, targetNucleus);
}
catch(G4HadReentrentException aR)
{
G4HadronicWhiteBoard & theBoard = G4HadronicWhiteBoard::Instance();
theBoard.SetProjectile(thePro);
theBoard.SetTargetNucleus(targetNucleus);
theBoard.SetProcessName(GetProcessName());
theBoard.SetModelName(theInteraction->GetModelName());
aR.Report(G4cout);
G4cout << " G4HadronicProcess re-entering the ApplyYourself call for "
<<G4endl;
@@ -293,13 +283,19 @@ const G4Track &aTrack, const G4Step &)
if(reentryCount>100)
{
G4Exception("G4HadronicProcess", "007", FatalException,
"GetHadronicProcess: Reentering ApplyYourself too often - GeneralPostStepDoIt failed.");
"GetHadronicProcess: Reentering ApplyYourself too often - PostStepDoIt failed.");
}
G4Exception("G4HadronicProcess", "007", FatalException,
"GetHadronicProcess: GeneralPostStepDoIt failed (Reentering ApplyYourself not yet supported.)");
"GetHadronicProcess: PostStepDoIt failed (Reentering ApplyYourself not yet supported.)");
}
catch(G4HadronicException aR)
{
G4HadronicWhiteBoard & theBoard = G4HadronicWhiteBoard::Instance();
theBoard.SetProjectile(thePro);
theBoard.SetTargetNucleus(targetNucleus);
theBoard.SetProcessName(GetProcessName());
theBoard.SetModelName(theInteraction->GetModelName());
aR.Report(G4cout);
G4cout << " G4HadronicProcess failed in ApplyYourself call for"
<< G4endl;
@@ -308,7 +304,7 @@ const G4Track &aTrack, const G4Step &)
G4cout << " - Particle type = "
<< aParticle->GetDefinition()->GetParticleName() << G4endl;
G4Exception("G4HadronicProcess", "007", FatalException,
"GeneralPostStepDoIt failed.");
"PostStepDoIt failed.");
}
}
while(!result);
@@ -330,40 +326,16 @@ const G4Track &aTrack, const G4Step &)
result->SetTrafoToLab(thePro.GetTrafoToLab());
/*
// Loop over charged ion secondaries
for(G4int i=0; i<result->GetNumberOfSecondaries(); i++)
{
G4DynamicParticle* aSecTrack = result->GetSecondary(i)->GetParticle();
if(aSecTrack->GetDefinition()->GetPDGCharge()>1.5)
{
G4EffectiveCharge aCalculator;
G4double charge =
aCalculator.GetCharge(aMaterial, aSecTrack->GetKineticEnergy(),
aSecTrack->GetDefinition()->GetPDGMass(),
aSecTrack->GetDefinition()->GetPDGCharge());
if(getenv("GHADChargeDebug"))
{
std::cout << "Recoil fractional charge is "
<< charge/aSecTrack->GetDefinition()->GetPDGCharge()<<" "
<< charge <<" "<<aSecTrack->GetDefinition()->GetPDGCharge()<<std::endl;
}
aSecTrack->SetCharge(charge);
}
}
*/
if(getenv("HadronicDoitLogging") )
{
G4cout << "HadronicDoitLogging "
<< GetProcessName() <<" "
<< aParticle->GetDefinition()->GetPDGEncoding()<<" "
<< originalEnergy<<" "
<< aParticle->GetMomentum()<<" "
<< targetNucleus.GetN()<<" "
<< targetNucleus.GetZ()<<" "
<< G4endl;
<< GetProcessName() <<" "
<< aParticle->GetDefinition()->GetPDGEncoding()<<" "
<< originalEnergy<<" "
<< aParticle->GetMomentum()<<" "
<< targetNucleus.GetN()<<" "
<< targetNucleus.GetZ()<<" "
<< G4endl;
}
ClearNumberOfInteractionLengthLeft();
@@ -508,7 +480,7 @@ G4double G4HadronicProcess::XBiasSecondaryWeight()
void
G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
{
G4Nancheck go_wild;
// G4Nancheck go_wild;
theTotalResult->Clear();
theTotalResult->ProposeLocalEnergyDeposit(0.);
theTotalResult->Initialize(aT);
@@ -558,6 +530,7 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
{
theTotalResult->ProposeParentWeight( XBiasSurvivalProbability()*aT.GetWeight() );
G4double newWeight = aR->GetWeightChange()*aT.GetWeight();
/*
if(go_wild(aR->GetEnergyChange()))
{
G4Exception("G4HadronicProcess", "007", FatalException,
@@ -570,6 +543,7 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
G4Exception("G4HadronicProcess", "007", FatalException,
"surviving track received NaN momentum.");
}
*/
G4double newM=aT.GetDefinition()->GetPDGMass();
G4double newE=aR->GetEnergyChange() + newM;
G4double newP=std::sqrt(newE*newE - newM*newM);
@@ -584,11 +558,13 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
theTotalResult->ProposeParentWeight(newWeight); // This is multiplicative
if(aR->GetEnergyChange()>-.5)
{
/*
if(go_wild(aR->GetEnergyChange()))
{
G4Exception("G4HadronicProcess", "007", FatalException,
"track received NaN energy.");
}
*/
theTotalResult->ProposeEnergy(aR->GetEnergyChange());
}
G4LorentzVector newDirection(aR->GetMomentumChange().unit(), 1.);
@@ -605,9 +581,8 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
if(GetProcessName() != "hElastic" && GetProcessName() != "HadronElastic"
&& theTotalResult->GetTrackStatus()==fAlive
&& aR->GetStatusChange()==isAlive
)
{
&& aR->GetStatusChange()==isAlive)
{
// Use for debugging: G4double newWeight = theTotalResult->GetParentWeight();
G4double newKE = std::max(DBL_MIN, aR->GetEnergyChange());
@@ -642,7 +617,7 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
G4LorentzVector theM = aR->GetSecondary(i)->GetParticle()->Get4Momentum();
theM.rotate(rotation, it);
theM*=aR->GetTrafoToLab();
/*
if(go_wild(theM.e()))
{
G4Exception("G4HadronicProcess", "007", FatalException,
@@ -655,14 +630,14 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
G4Exception("G4HadronicProcess", "007", FatalException,
"secondary track received NaN momentum.");
}
*/
aR->GetSecondary(i)->GetParticle()->Set4Momentum(theM);
G4double time = aR->GetSecondary(i)->GetTime();
if(time<0) time = aT.GetGlobalTime();
G4Track* track = new G4Track(aR->GetSecondary(i)->GetParticle(),
time,
aT.GetPosition());
time,
aT.GetPosition());
G4double newWeight = aT.GetWeight()*aR->GetSecondary(i)->GetWeight();
//static G4double pinelcount=0;
@@ -678,6 +653,7 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
// <<aR->GetSecondary(i)->GetParticle()->Get4Momentum()<<" "
// <<G4endl;
track->SetWeight(newWeight);
/*
G4double trackDeb = track->GetKineticEnergy();
if( ( trackDeb<0
|| (trackDeb>aT.GetKineticEnergy()+1*GeV) ) && getenv("GHADEnergyBalanceDebug") )
@@ -688,11 +664,40 @@ G4HadronicProcess::FillTotalResult(G4HadFinalState * aR, const G4Track & aT)
<<" "<<aT.GetDefinition()->GetParticleName()
<<G4endl;
}
track->SetTouchableHandle(aT.GetTouchableHandle());
theTotalResult->AddSecondary(track);
*/
track->SetTouchableHandle(aT.GetTouchableHandle());
theTotalResult->AddSecondary(track);
}
aR->Clear();
return;
}
G4IsoParticleChange* G4HadronicProcess::GetIsotopeProductionInfo()
{
G4IsoParticleChange * anIsoResult = theIsoResult;
if(theIsoResult) theOldIsoResult = theIsoResult;
theIsoResult = 0;
return anIsoResult;
}
void G4HadronicProcess::BiasCrossSectionByFactor(G4double aScale)
{
xBiasOn = true;
aScaleFactor = aScale;
G4String it = GetProcessName();
if( (it != "PhotonInelastic") &&
(it != "ElectroNuclear") &&
(it != "PositronNuclear") )
{
G4Exception("G4HadronicProcess", "007", FatalException,
"Cross-section biasing available only for gamma and electro nuclear reactions.");
}
if(aScale<100)
{
G4Exception("G4HadronicProcess", "001", JustWarning,
"Cross-section bias readjusted to be above safe limit. New value is 100");
aScaleFactor = 100.;
}
}
/* end of file */
@@ -0,0 +1,614 @@
//
// ********************************************************************
// * 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: G4HadronicProcessStore.cc,v 1.7 2008/10/22 07:58:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-09-02 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4HadronicProcessStore
//
// Author: Vladimir Ivanchenko
//
// Creation date: 09.05.2008
//
// Modifications:
//
//
// Class Description:
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4HadronicProcessStore.hh"
#include "G4Element.hh"
#include "G4ProcessManager.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
G4HadronicProcessStore* G4HadronicProcessStore::theInstance = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4HadronicProcessStore* G4HadronicProcessStore::Instance()
{
if(0 == theInstance) {
static G4HadronicProcessStore manager;
theInstance = &manager;
}
return theInstance;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4HadronicProcessStore::~G4HadronicProcessStore()
{
/*
for (G4int i=0; i<n_proc; i++) {
if( process[i] ) delete process[i];
}
*/
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4HadronicProcessStore::G4HadronicProcessStore()
{
n_proc = 0;
n_part = 0;
n_model= 0;
n_extra= 0;
currentProcess = 0;
currentParticle = 0;
verbose = 1;
buildTableStart = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetElasticCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material)
{
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
size_t nelm = material->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
cross += theAtomNumDensityVector[i]*
GetElasticCrossSectionPerAtom(aParticle,kineticEnergy,elm);
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetElasticCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement)
{
G4HadronicProcess* hp = FindProcess(aParticle, fHadronElastic);
localDP.SetKineticEnergy(kineticEnergy);
G4double cross = 0.0;
if(hp) cross = hp->GetMicroscopicCrossSection(&localDP,
anElement,
STP_Temperature);
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetElasticCrossSectionPerIsotope(
const G4ParticleDefinition*,
G4double,
G4int, G4int)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetInelasticCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material)
{
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
size_t nelm = material->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
cross += theAtomNumDensityVector[i]*
GetInelasticCrossSectionPerAtom(aParticle,kineticEnergy,elm);
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetInelasticCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement)
{
G4HadronicProcess* hp = FindProcess(aParticle, fHadronInelastic);
localDP.SetDefinition(const_cast<G4ParticleDefinition*>(aParticle));
localDP.SetKineticEnergy(kineticEnergy);
G4double cross = 0.0;
if(hp) cross = hp->GetMicroscopicCrossSection(&localDP,
anElement,
STP_Temperature);
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetInelasticCrossSectionPerIsotope(
const G4ParticleDefinition *,
G4double,
G4int, G4int)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetCaptureCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material)
{
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
size_t nelm = material->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
cross += theAtomNumDensityVector[i]*
GetCaptureCrossSectionPerAtom(aParticle,kineticEnergy,elm);
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetCaptureCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement)
{
G4HadronicProcess* hp = FindProcess(aParticle, fCapture);
localDP.SetDefinition(const_cast<G4ParticleDefinition*>(aParticle));
localDP.SetKineticEnergy(kineticEnergy);
G4double cross = 0.0;
if(hp) cross = hp->GetMicroscopicCrossSection(&localDP,
anElement,
STP_Temperature);
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetCaptureCrossSectionPerIsotope(
const G4ParticleDefinition *,
G4double,
G4int, G4int)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetFissionCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material)
{
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
size_t nelm = material->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
cross += theAtomNumDensityVector[i]*
GetFissionCrossSectionPerAtom(aParticle,kineticEnergy,elm);
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetFissionCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement)
{
G4HadronicProcess* hp = FindProcess(aParticle, fFission);
localDP.SetDefinition(const_cast<G4ParticleDefinition*>(aParticle));
localDP.SetKineticEnergy(kineticEnergy);
G4double cross = 0.0;
if(hp) cross = hp->GetMicroscopicCrossSection(&localDP,
anElement,
STP_Temperature);
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetFissionCrossSectionPerIsotope(
const G4ParticleDefinition *,
G4double,
G4int, G4int)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetChargeExchangeCrossSectionPerVolume(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Material *material)
{
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
size_t nelm = material->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
cross += theAtomNumDensityVector[i]*
GetChargeExchangeCrossSectionPerAtom(aParticle,kineticEnergy,elm);
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetChargeExchangeCrossSectionPerAtom(
const G4ParticleDefinition *aParticle,
G4double kineticEnergy,
const G4Element *anElement)
{
G4HadronicProcess* hp = FindProcess(aParticle, fChargeExchange);
localDP.SetDefinition(const_cast<G4ParticleDefinition*>(aParticle));
localDP.SetKineticEnergy(kineticEnergy);
G4double cross = 0.0;
if(hp) cross = hp->GetMicroscopicCrossSection(&localDP,
anElement,
STP_Temperature);
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4double G4HadronicProcessStore::GetChargeExchangeCrossSectionPerIsotope(
const G4ParticleDefinition *,
G4double,
G4int, G4int)
{
return 0.0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::Register(G4HadronicProcess* proc)
{
for(G4int i=0; i<n_proc; i++) {if(process[i] == proc) return;}
n_proc++;
process.push_back(proc);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::RegisterParticle(G4HadronicProcess* proc,
const G4ParticleDefinition* part)
{
G4int i=0;
for(; i<n_proc; i++) {if(process[i] == proc) break;}
G4int j=0;
for(; j<n_part; j++) {if(particle[j] == part) break;}
if(j == n_part) {
n_part++;
particle.push_back(part);
wasPrinted.push_back(0);
}
// the pair should be added?
if(i < n_proc) {
std::multimap<PD,HP,std::less<PD> >::iterator it;
for(it=p_map.lower_bound(part); it!=p_map.upper_bound(part); ++it) {
if(it->first == part) {
HP process = (it->second);
if(proc == process) return;
}
}
}
p_map.insert(std::multimap<PD,HP>::value_type(part,proc));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::RegisterInteraction(G4HadronicProcess* proc,
G4HadronicInteraction* mod)
{
G4int i=0;
for(; i<n_proc; i++) {if(process[i] == proc) break;}
G4int k=0;
for(; k<n_model; k++) {if(model[k] == mod) break;}
m_map.insert(std::multimap<HP,HI>::value_type(proc,mod));
if(k == n_model) {
n_model++;
model.push_back(mod);
modelName.push_back(mod->GetModelName());
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::DeRegister(G4HadronicProcess* proc)
{
for(G4int i=0; i<n_proc; i++) {
if(process[i] == proc) {
process[i] = 0;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::RegisterExtraProcess(G4VProcess* proc)
{
for(G4int i=0; i<n_extra; i++) {if(extraProcess[i] == proc) return;}
n_extra++;
extraProcess.push_back(proc);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::RegisterParticleForExtraProcess(
G4VProcess* proc,
const G4ParticleDefinition* part)
{
G4int i=0;
for(; i<n_extra; i++) {if(extraProcess[i] == proc) break;}
G4int j=0;
for(; j<n_part; j++) {if(particle[j] == part) break;}
if(j == n_part) {
n_part++;
particle.push_back(part);
wasPrinted.push_back(0);
}
// the pair should be added?
if(i < n_extra) {
std::multimap<PD,G4VProcess*,std::less<PD> >::iterator it;
for(it=ep_map.lower_bound(part); it!=ep_map.upper_bound(part); ++it) {
if(it->first == part) {
G4VProcess* process = (it->second);
if(proc == process) return;
}
}
}
ep_map.insert(std::multimap<PD,G4VProcess*>::value_type(part,proc));
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::DeRegisterExtraProcess(G4VProcess* proc)
{
for(G4int i=0; i<n_extra; i++) {
if(extraProcess[i] == proc) {
extraProcess[i] = 0;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::PrintInfo(const G4ParticleDefinition* part)
{
if(buildTableStart && part == particle[n_part - 1]) {
buildTableStart = false;
Dump(verbose);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::Dump(G4int level)
{
if(level > 0) {
G4cout << "=============================================================="
<< "=============================="
<< G4endl;
G4cout << " HADRONIC PROCESSES SUMMARY (verbose level " << level
<< ")" << G4endl;
}
for(G4int i=0; i<n_part; i++) {
PD part = particle[i];
G4String pname = part->GetParticleName();
G4bool yes = false;
if(level >= 2) yes = true;
else if(level == 1 && (pname == "proton" ||
pname == "neutron" ||
pname == "pi+" ||
pname == "pi-" ||
pname == "gamma" ||
pname == "e-" ||
pname == "mu-" ||
pname == "kaon+" ||
pname == "kaon-" ||
pname == "lambda" ||
pname == "anti_neutron" ||
pname == "anti_proton")) yes = true;
if(yes) {
// main processes
std::multimap<PD,HP,std::less<PD> >::iterator it;
for(it=p_map.lower_bound(part); it!=p_map.upper_bound(part); ++it) {
if(it->first == part) {
HP proc = (it->second);
G4int j=0;
for(; j<n_proc; j++) {
if(process[j] == proc) {
Print(j, i);
}
}
}
}
// extra processes
std::multimap<PD,G4VProcess*,std::less<PD> >::iterator itp;
for(itp=ep_map.lower_bound(part); itp!=ep_map.upper_bound(part); ++itp) {
if(itp->first == part) {
G4VProcess* proc = (itp->second);
if(wasPrinted[i] == 0) {
wasPrinted[i] = 1;
G4cout<<G4endl;
G4cout << " Hadronic Processes for <"
<<part->GetParticleName() << ">" << G4endl;
}
G4cout << " " << proc->GetProcessName() << G4endl;
}
}
}
}
if(level > 0) {
G4cout << "=============================================================="
<< "=============================="
<< G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::Print(G4int idxProc, G4int idxPart)
{
G4HadronicProcess* proc = process[idxProc];
const G4ParticleDefinition* part = particle[idxPart];
if(wasPrinted[idxPart] == 0) {
wasPrinted[idxPart] = 1;
G4cout<<G4endl;
G4cout << " Hadronic Processes for <"
<<part->GetParticleName() << ">" << G4endl;
}
HI hi = 0;
G4bool first;
std::multimap<HP,HI,std::less<HP> >::iterator ih;
G4cout << std::setw(20) << proc->GetProcessName()
<< " Models: ";
first = true;
for(ih=m_map.lower_bound(proc); ih!=m_map.upper_bound(proc); ++ih) {
if(ih->first == proc) {
hi = ih->second;
G4int i=0;
for(; i<n_model; i++) {
if(model[i] == hi) break;
}
if(!first) G4cout << " ";
first = false;
G4cout << std::setw(25) << modelName[i]
<< ": Emin(GeV)= "
<< std::setw(5) << hi->GetMinEnergy()/GeV
<< " Emax(GeV)= "
<< hi->GetMaxEnergy()/GeV
<< G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4HadronicProcessStore::SetVerbose(G4int val)
{
verbose = val;
G4int i;
for(i=0; i<n_proc; i++) {
if(process[i]) process[i]->SetVerboseLevel(val);
}
for(i=0; i<n_model; i++) {
if(model[i]) model[i]->SetVerboseLevel(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4int G4HadronicProcessStore::GetVerbose()
{
return verbose;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4HadronicProcess* G4HadronicProcessStore::FindProcess(
const G4ParticleDefinition* part, G4HadronicProcessType subType)
{
bool isNew = false;
G4HadronicProcess* hp = 0;
if(part != currentParticle) {
isNew = true;
currentParticle = part;
localDP.SetDefinition(const_cast<G4ParticleDefinition*>(part));
} else if(!currentProcess) {
isNew = true;
} else if(subType == currentProcess->GetProcessSubType()) {
hp = currentProcess;
} else {
isNew = true;
}
if(isNew) {
std::multimap<PD,HP,std::less<PD> >::iterator it;
for(it=p_map.lower_bound(part); it!=p_map.upper_bound(part); ++it) {
if(it->first == part && subType == (it->second)->GetProcessSubType()) {
hp = it->second;
break;
}
}
currentProcess = hp;
}
return hp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....