Import Geant4 4.0.0 source tree
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransitionManager.hh,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
//
|
||||
// 16 Sept 2001 First committed to cvs
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4AtomicDeexcitation.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
G4AtomicDeexcitation::G4AtomicDeexcitation()
|
||||
{ }
|
||||
|
||||
G4AtomicDeexcitation::~G4AtomicDeexcitation()
|
||||
|
||||
{ }
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int shellId)
|
||||
{
|
||||
G4std::vector<G4DynamicParticle*>* vectorOfParticles = new G4std::vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* aParticle;
|
||||
G4int provShellId = 0;
|
||||
G4int counter = 0;
|
||||
|
||||
// The aim of this loop is to generate more than one fluorecence photon
|
||||
// from the same ionizing event
|
||||
while (provShellId >= 0)
|
||||
{
|
||||
if (counter == 0)
|
||||
// First call to GenerateParticles(...):
|
||||
// shellId is given by the process
|
||||
{
|
||||
provShellId = SelectTypeOfTransition(Z, shellId);
|
||||
|
||||
if ( provShellId >0)
|
||||
{
|
||||
aParticle = GenerateFluorescence(Z,shellId,provShellId);
|
||||
}
|
||||
else if ( provShellId ==-1)
|
||||
{
|
||||
aParticle = GenerateAuger(Z, shellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4AtomicDeexcitation: starting shell uncorrect: check it");
|
||||
}
|
||||
}
|
||||
else
|
||||
// Following calls to GenerateParticles(...):
|
||||
// newShellId is given by GenerateFluorescence(...)
|
||||
{
|
||||
provShellId = SelectTypeOfTransition(Z,newShellId);
|
||||
if ( provShellId >0)
|
||||
{
|
||||
aParticle = GenerateFluorescence(Z,newShellId,provShellId);
|
||||
}
|
||||
else if ( provShellId ==-1)
|
||||
{
|
||||
aParticle = GenerateAuger(Z, newShellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception("G4AtomicDeexcitation: starting shell uncorrect: check it");
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
vectorOfParticles->push_back(aParticle);
|
||||
}
|
||||
|
||||
return vectorOfParticles;
|
||||
}
|
||||
|
||||
const G4int G4AtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
|
||||
{
|
||||
if (shellId <=0 )
|
||||
{G4Exception("G4AtomicDeexcitation: zero or negative shellId");}
|
||||
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
G4int provShellId = -1;
|
||||
G4int shellNum = 0;
|
||||
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
|
||||
|
||||
const G4AtomicTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
|
||||
|
||||
// This loop gives shellNum the value of the index of shellId
|
||||
// in the vector storing the list of the shells reachable through
|
||||
// a radiative transition
|
||||
if ( shellId <= refShell->FinalShellId())
|
||||
{
|
||||
while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId())
|
||||
{
|
||||
if(shellNum ==maxNumOfShells-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
shellNum++;
|
||||
}
|
||||
G4int transProb = 1;
|
||||
|
||||
G4double partialProb = G4UniformRand();
|
||||
G4double partSum = 0;
|
||||
const G4AtomicTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
|
||||
G4int trSize = (aShell->TransitionProbabilities()).size();
|
||||
|
||||
// Loop over the shells wich can provide an electron for a
|
||||
// radiative transition towards shellId:
|
||||
// in every loop the partial sum of the first transProb shells
|
||||
// is calculated and compared with a random number [0,1].
|
||||
// If the partial sum is greater the shell whose index transProb
|
||||
// is chosen as the starting shell for a radiative transition
|
||||
// and its identity is returned
|
||||
// Else, terminateded the loop, -1 is returned
|
||||
while(transProb < trSize){
|
||||
|
||||
partSum += aShell->TransitionProbability(transProb);
|
||||
|
||||
if(partialProb <= partSum)
|
||||
{
|
||||
provShellId = aShell->OriginatingShellId(transProb);
|
||||
break;
|
||||
}
|
||||
transProb++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
provShellId = -1;
|
||||
|
||||
}
|
||||
return provShellId;
|
||||
}
|
||||
|
||||
G4DynamicParticle* G4AtomicDeexcitation::GenerateFluorescence(G4int Z,
|
||||
G4int shellId,
|
||||
G4int provShellId )
|
||||
{
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
// G4int provenienceShell = provShellId;
|
||||
|
||||
//isotropic angular distribution for the outcoming photon
|
||||
G4double newcosTh = 1.-2.*G4UniformRand();
|
||||
G4double newsinTh = sqrt(1.-newcosTh*newcosTh);
|
||||
G4double newPhi = twopi*G4UniformRand();
|
||||
|
||||
G4double xDir = newsinTh*sin(newPhi);
|
||||
G4double yDir = newsinTh*cos(newPhi);
|
||||
G4double zDir = newcosTh;
|
||||
|
||||
G4ThreeVector newGammaDirection(xDir,yDir,zDir);
|
||||
|
||||
G4int shellNum = 0;
|
||||
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
|
||||
|
||||
// find the index of the shell named shellId
|
||||
while (shellId != transitionManager->
|
||||
ReachableShell(Z,shellNum)->FinalShellId())
|
||||
{
|
||||
if(shellNum == maxNumOfShells-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
shellNum++;
|
||||
}
|
||||
// number of shell from wich an electron can reach shellId
|
||||
size_t transitionSize = transitionManager->
|
||||
ReachableShell(Z,shellNum)->OriginatingShellIds().size();
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
// find the index of the shell named provShellId in the vector
|
||||
// storing the shells from which shellId can be reached
|
||||
while (provShellId != transitionManager->
|
||||
ReachableShell(Z,shellNum)->OriginatingShellId(index))
|
||||
{
|
||||
if(index == transitionSize-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
// energy of the gamma leaving provShellId for shellId
|
||||
G4double transitionEnergy = transitionManager->
|
||||
ReachableShell(Z,shellNum)->TransitionEnergy(index);
|
||||
|
||||
// This is the shell where the new vacancy is: it is the same
|
||||
// shell where the electron came from
|
||||
newShellId = transitionManager->
|
||||
ReachableShell(Z,shellNum)->OriginatingShellId(index);
|
||||
|
||||
|
||||
G4DynamicParticle* newPart = new G4DynamicParticle(G4Gamma::Gamma(),
|
||||
newGammaDirection,
|
||||
transitionEnergy);
|
||||
return newPart;
|
||||
}
|
||||
|
||||
G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+22
-27
@@ -21,42 +21,37 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// GEANT 4 class file
|
||||
// $Id: G4AtomicShell.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// CERN, Geneva, Switzerland
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
//
|
||||
// File name: G4FirstLevel.hh
|
||||
// History:
|
||||
// -----------
|
||||
// 16 Sept 2001 EG Modified according to a design iteration in the
|
||||
// LowEnergy category
|
||||
//
|
||||
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
|
||||
//
|
||||
// Creation date: 1 Giugno 1999
|
||||
//
|
||||
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4FirstLevel.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
|
||||
G4AtomicShell::G4AtomicShell(G4int id, G4double energy)
|
||||
{
|
||||
identifier = id;
|
||||
bindingEnergy = energy;
|
||||
}
|
||||
|
||||
G4FirstLevel::~G4FirstLevel(){
|
||||
G4AtomicShell::~G4AtomicShell()
|
||||
{ }
|
||||
|
||||
//this->clearAndDestroy();
|
||||
this->clear();
|
||||
}
|
||||
|
||||
G4bool G4FirstLevel::operator == (const G4FirstLevel& input) const{
|
||||
|
||||
// return( this->entries() == input.entries());
|
||||
return( this->size() == input.size());
|
||||
|
||||
}
|
||||
|
||||
G4bool G4FirstLevel::operator < (const G4FirstLevel& input) const{
|
||||
|
||||
// return(this->entries() < input.entries());
|
||||
return(this->size() < input.size());
|
||||
G4double G4AtomicShell::BindingEnergy() const {
|
||||
|
||||
return bindingEnergy;
|
||||
}
|
||||
|
||||
|
||||
G4int G4AtomicShell::ShellId() const{
|
||||
|
||||
return identifier;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransition.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 16 Sept 2001 EG Modified according to a design iteration in the
|
||||
// LowEnergy category
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4AtomicTransition.hh"
|
||||
|
||||
G4AtomicTransition::G4AtomicTransition(G4int finalShell,
|
||||
const G4std::vector<G4int>& ids,
|
||||
const G4DataVector& energies,
|
||||
const G4DataVector& prob)
|
||||
{
|
||||
finalShellId = finalShell;
|
||||
originatingShellIds = ids;
|
||||
transitionEnergies = energies;
|
||||
transitionProbabilities = prob;
|
||||
}
|
||||
|
||||
G4AtomicTransition::~G4AtomicTransition()
|
||||
{ }
|
||||
|
||||
const G4std::vector<G4int>& G4AtomicTransition::OriginatingShellIds() const
|
||||
{
|
||||
return originatingShellIds;
|
||||
}
|
||||
|
||||
const G4DataVector& G4AtomicTransition::TransitionEnergies() const
|
||||
{
|
||||
return transitionEnergies;
|
||||
}
|
||||
|
||||
const G4DataVector& G4AtomicTransition::TransitionProbabilities() const
|
||||
{
|
||||
return transitionProbabilities;
|
||||
}
|
||||
|
||||
const G4int G4AtomicTransition::FinalShellId() const
|
||||
{
|
||||
return finalShellId;
|
||||
}
|
||||
|
||||
G4int G4AtomicTransition::OriginatingShellId(G4int index) const
|
||||
{
|
||||
return originatingShellIds[index];
|
||||
}
|
||||
G4double G4AtomicTransition::TransitionEnergy(G4int index) const
|
||||
{
|
||||
return transitionEnergies[index];
|
||||
}
|
||||
G4double G4AtomicTransition::TransitionProbability(G4int index) const
|
||||
{
|
||||
return transitionProbabilities[index];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransitionManager.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 16 Sep 2001 E. Guardincerri First Committed to cvs
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
|
||||
G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4int limitInfTable,G4int limitSupTable)
|
||||
:zMin(minZ), zMax(maxZ),infTableLimit(limitInfTable),supTableLimit(limitSupTable)
|
||||
{
|
||||
// infTableLimit is initialized to 6 because EADL lacks data for Z<=5
|
||||
G4ShellData* shellManager = new G4ShellData;
|
||||
|
||||
shellManager->LoadData("/fluor/binding");
|
||||
|
||||
// Fills shellTable with the data from EADL, identities and binding
|
||||
// energies of shells
|
||||
for (G4int Z = zMin; Z<= zMax; Z++)
|
||||
{
|
||||
G4std::vector<G4AtomicShell*> vectorOfShells;
|
||||
|
||||
size_t numberOfShells=shellManager->NumberOfShells(Z);
|
||||
for (size_t shellIndex = 0; shellIndex<numberOfShells; shellIndex++)
|
||||
{
|
||||
G4int shellId = shellManager->ShellId(Z,shellIndex);
|
||||
G4double bindingEnergy = shellManager->BindingEnergy(Z,shellIndex);
|
||||
|
||||
G4AtomicShell * shell = new G4AtomicShell(shellId,bindingEnergy);
|
||||
|
||||
vectorOfShells.push_back(shell);
|
||||
}
|
||||
|
||||
// shellTable.insert(G4std::make_pair(Z, vectorOfShells));
|
||||
shellTable[Z] = vectorOfShells;
|
||||
}
|
||||
|
||||
// Fills transitionTable with the data from EADL, identities, transition
|
||||
// energies and transition probabilities
|
||||
for (G4int Znum= infTableLimit; Znum<=supTableLimit; Znum++)
|
||||
{ G4FluoData* fluoManager = new G4FluoData;
|
||||
G4std::vector<G4AtomicTransition*> vectorOfTransitions;
|
||||
fluoManager->LoadData(Znum);
|
||||
|
||||
size_t numberOfVacancies = fluoManager-> NumberOfVacancies();
|
||||
|
||||
for (size_t vacancyIndex = 0; vacancyIndex<numberOfVacancies; vacancyIndex++)
|
||||
|
||||
{
|
||||
G4std::vector<G4int> vectorOfIds;
|
||||
G4DataVector vectorOfEnergies;
|
||||
G4DataVector vectorOfProbabilities;
|
||||
|
||||
G4int finalShell = fluoManager->VacancyId(vacancyIndex);
|
||||
size_t numberOfTransitions = fluoManager->NumberOfTransitions(vacancyIndex);
|
||||
for (size_t origShellIndex = 0; origShellIndex <= numberOfTransitions;origShellIndex++)
|
||||
|
||||
{
|
||||
|
||||
G4int originatingShellId = fluoManager->StartShellId(origShellIndex,vacancyIndex);
|
||||
|
||||
vectorOfIds.push_back(originatingShellId);
|
||||
|
||||
G4double transitionEnergy = fluoManager->StartShellEnergy(origShellIndex,vacancyIndex);
|
||||
vectorOfEnergies.push_back(transitionEnergy);
|
||||
G4double transitionProbability = fluoManager->StartShellProb(origShellIndex,vacancyIndex);
|
||||
vectorOfProbabilities.push_back(transitionProbability);
|
||||
}
|
||||
G4AtomicTransition * transition = new G4AtomicTransition (finalShell,vectorOfIds,
|
||||
vectorOfEnergies,vectorOfProbabilities);
|
||||
vectorOfTransitions.push_back(transition);
|
||||
}
|
||||
// transitionTable.insert(G4std::make_pair(Znum, vectorOfTransitions));
|
||||
transitionTable[Znum] = vectorOfTransitions;
|
||||
|
||||
delete fluoManager;
|
||||
}
|
||||
delete shellManager;
|
||||
}
|
||||
|
||||
G4AtomicTransitionManager::~G4AtomicTransitionManager()
|
||||
|
||||
{ G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
for (pos = shellTable.begin(); pos != shellTable.end(); pos++){
|
||||
|
||||
G4std::vector< G4AtomicShell*>vec = (*pos).second;
|
||||
|
||||
G4int vecSize=vec.size();
|
||||
|
||||
for (G4int i=0; i< vecSize; i++){
|
||||
|
||||
delete vec[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator ppos;
|
||||
|
||||
for (ppos = transitionTable.begin(); ppos != transitionTable.end(); ppos++){
|
||||
|
||||
G4std::vector< G4AtomicTransition*>vec = (*ppos).second;
|
||||
|
||||
G4int vecSize=vec.size();
|
||||
|
||||
for (G4int i=0; i< vecSize; i++){
|
||||
|
||||
delete vec[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
G4AtomicTransitionManager* G4AtomicTransitionManager::instance = 0;
|
||||
|
||||
G4AtomicTransitionManager* G4AtomicTransitionManager::Instance()
|
||||
{
|
||||
if (instance==0)
|
||||
{
|
||||
instance = new G4AtomicTransitionManager;
|
||||
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
const G4AtomicShell* G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex)
|
||||
{
|
||||
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
pos = shellTable.find(Z);
|
||||
|
||||
if (pos!= shellTable.end()){
|
||||
|
||||
G4std::vector<G4AtomicShell*> v = (*pos).second;
|
||||
|
||||
if (shellIndex<v.size()){
|
||||
|
||||
return(v[shellIndex]);
|
||||
|
||||
}
|
||||
else {
|
||||
G4Exception("G4AtomicTransitionManager:shell not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
G4Exception("G4AtomicTransitionManager:Z not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const G4AtomicTransition* G4AtomicTransitionManager:: ReachableShell(G4int Z,size_t shellIndex)
|
||||
{
|
||||
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
|
||||
pos = transitionTable.find(Z);
|
||||
if (pos!= transitionTable.end())
|
||||
{
|
||||
G4std::vector<G4AtomicTransition*> v = (*pos).second;
|
||||
if (shellIndex < v.size()) return(v[shellIndex]);
|
||||
else {
|
||||
G4Exception("G4AtomicTransitionManager:reachable shell not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
G4Exception("G4AtomicTransitionManager:Z not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4int G4AtomicTransitionManager::NumberOfShells (G4int Z)
|
||||
{
|
||||
|
||||
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
pos = shellTable.find(Z);
|
||||
|
||||
if (pos!= shellTable.end()){
|
||||
|
||||
G4std::vector<G4AtomicShell*> v = (*pos).second;
|
||||
|
||||
return v.size();
|
||||
}
|
||||
|
||||
else{
|
||||
G4Exception( "G4AtomicTransitionManager: Z not found" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4int G4AtomicTransitionManager::NumberOfReachableShells(G4int Z)
|
||||
{
|
||||
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
pos = transitionTable.find(Z);
|
||||
|
||||
if (pos!= transitionTable.end())
|
||||
{
|
||||
G4std::vector<G4AtomicTransition*> v = (*pos).second;
|
||||
return v.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4Exception( "G4AtomicTransitionManager: Z not found" );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4AtomicTransitionManager::TotalRadiativeTransitionProbability(G4int Z,
|
||||
size_t shellIndex)
|
||||
|
||||
{
|
||||
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
pos = transitionTable.find(Z);
|
||||
|
||||
if (pos!= transitionTable.end())
|
||||
{
|
||||
G4std::vector<G4AtomicTransition*> v = (*pos).second;
|
||||
|
||||
if (shellIndex < v.size())
|
||||
{
|
||||
G4AtomicTransition* transition = v[shellIndex];
|
||||
G4DataVector transProb = transition->TransitionProbabilities();
|
||||
G4double totalRadTransProb = 0;
|
||||
|
||||
for (size_t j = 1; j<transProb.size(); j++)
|
||||
{
|
||||
totalRadTransProb = totalRadTransProb + transProb[j];
|
||||
}
|
||||
return totalRadTransProb;
|
||||
|
||||
}
|
||||
else {
|
||||
G4Exception( "G4AtomicTransitionManager: shell not found" );
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
G4Exception( "G4AtomicTransitionManager: Z not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4AtomicTransitionManager::TotalNonRadiativeTransitionProbability(G4int Z, size_t shellIndex)
|
||||
|
||||
{
|
||||
|
||||
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
pos = transitionTable.find(Z);
|
||||
|
||||
if (pos!= transitionTable.end()){
|
||||
|
||||
G4std::vector<G4AtomicTransition*> v = (*pos).second;
|
||||
|
||||
|
||||
if (shellIndex<v.size()){
|
||||
|
||||
G4AtomicTransition* transition=v[shellIndex];
|
||||
G4DataVector transProb = transition->TransitionProbabilities();
|
||||
G4double totalRadTransProb = 0;
|
||||
|
||||
for(size_t j = 1; j<transProb.size(); j++)
|
||||
{
|
||||
totalRadTransProb = totalRadTransProb + transProb[j];
|
||||
}
|
||||
|
||||
G4double totalNonRadTransProb= (1 - totalRadTransProb);
|
||||
|
||||
return totalNonRadTransProb; }
|
||||
|
||||
else {
|
||||
G4Exception( "shell not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
G4Exception("Z not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4BremsstrahlungCrossSectionHandler.cc,v 1.5 2001/10/25 14:31:20 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4BremsstrahlungCrossSectionHandler
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
// Creation date: 25 September 2001
|
||||
//
|
||||
// Modifications:
|
||||
// 10.10.2001 MGP Revision to improve code quality and consistency with design
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4BremsstrahlungCrossSectionHandler.hh"
|
||||
#include "G4eBremsstrahlungSpectrum.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4SemiLogInterpolation.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
|
||||
G4BremsstrahlungCrossSectionHandler::G4BremsstrahlungCrossSectionHandler(const G4VEnergySpectrum* spec,
|
||||
G4VDataSetAlgorithm* alg)
|
||||
: theBR(spec)
|
||||
{
|
||||
interp = new G4SemiLogInterpolation();
|
||||
}
|
||||
|
||||
|
||||
G4BremsstrahlungCrossSectionHandler::~G4BremsstrahlungCrossSectionHandler()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
|
||||
G4std::vector<G4VEMDataSet*>*
|
||||
G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
G4std::vector<G4VEMDataSet*>* set = new G4std::vector<G4VEMDataSet*>;
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* cs;
|
||||
G4int nOfBins = energyVector.size();
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4VCrossSectionHandler::G4VCrossSectionHandler - no MaterialTable found)");
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material = (*materialTable)[m];
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
G4double tcut = (*energyCuts)[m];
|
||||
|
||||
G4VDataSetAlgorithm* algo = interp->Clone();
|
||||
G4VEMDataSet* setForMat = new G4CompositeEMDataSet(algo,1.,1.);
|
||||
|
||||
for (G4int i=0; i<nElements; i++) {
|
||||
|
||||
G4int Z = (G4int) ((*elementVector)[i]->GetZ());
|
||||
energies = new G4DataVector;
|
||||
cs = new G4DataVector;
|
||||
G4double density = nAtomsPerVolume[i];
|
||||
|
||||
for (G4int bin=0; bin<nOfBins; bin++) {
|
||||
|
||||
G4double e = energyVector[bin];
|
||||
energies->push_back(e);
|
||||
G4double value = 0.0;
|
||||
|
||||
if(e > tcut) {
|
||||
G4double elemCs = FindValue(Z, e);
|
||||
|
||||
value = theBR->Probability(Z, tcut, e, e);
|
||||
|
||||
value *= elemCs*density;
|
||||
}
|
||||
cs->push_back(value);
|
||||
}
|
||||
G4VDataSetAlgorithm* algol = interp->Clone();
|
||||
G4VEMDataSet* elSet = new G4EMDataSet(i,energies,cs,algol,1.,1.);
|
||||
setForMat->AddComponent(elSet);
|
||||
}
|
||||
set->push_back(setForMat);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4BremsstrahlungParameters.cc,v 1.11 2001/11/29 22:59:56 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
// V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created
|
||||
// 12.09.01 V.Ivanchenko Add activeZ and paramA
|
||||
// 25.09.01 V.Ivanchenko Add parameter C and change interface to B
|
||||
// 29.11.01 V.Ivanchenko Update parametrisation
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4BremsstrahlungParameters.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
|
||||
G4BremsstrahlungParameters:: G4BremsstrahlungParameters(G4int minZ, G4int maxZ)
|
||||
: zMin(minZ),
|
||||
zMax(maxZ),
|
||||
length(16)
|
||||
{
|
||||
LoadData();
|
||||
}
|
||||
|
||||
|
||||
G4BremsstrahlungParameters::~G4BremsstrahlungParameters()
|
||||
{
|
||||
// Reset the map of data sets: remove the data sets from the map
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
for (pos = param.begin(); pos != param.end(); pos++)
|
||||
{
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
activeZ.clear();
|
||||
paramC.clear();
|
||||
}
|
||||
|
||||
|
||||
G4double G4BremsstrahlungParameters::Parameter(G4int parameterIndex,
|
||||
G4int Z,
|
||||
G4double energy) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
G4int id = Z*20 + parameterIndex;
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = param.find(id);
|
||||
if (pos!= param.end()) {
|
||||
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
const G4DataVector ener = dataSet->GetEnergies(0);
|
||||
G4double ee = G4std::max(ener.front(),G4std::min(ener.back(),energy));
|
||||
value = dataSet->FindValue(ee);
|
||||
|
||||
} else {
|
||||
G4cout << "WARNING: G4BremsstrahlungParameters::FindValue "
|
||||
<< "did not find ID = "
|
||||
<< id << G4endl;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void G4BremsstrahlungParameters::LoadData()
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
// define active elements
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4CrossSectionHandler: no MaterialTable found)");
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
G4double x = 1.e-9;
|
||||
for (G4int mm=0; mm<100; mm++) {
|
||||
paramC.push_back(x);
|
||||
}
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
for (G4int iEl=0; iEl<nElements; iEl++) {
|
||||
G4Element* element = (*elementVector)[iEl];
|
||||
G4double Z = element->GetZ();
|
||||
G4int iz = (G4int)Z;
|
||||
if(iz < 100)
|
||||
paramC[iz] = 0.217635e-33*(material->GetTotNbOfElectPerVolume());
|
||||
if (!(activeZ.contains(Z))) {
|
||||
activeZ.push_back(Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read parameters
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = G4String("G4BremsstrahlungParameters - G4LEDATA")
|
||||
+ G4String("environment variable not set");
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString_a(path);
|
||||
G4String name_a = pathString_a + "/brem/br-sp.dat";
|
||||
G4std::ifstream file_a(name_a);
|
||||
G4std::filebuf* lsdp_a = file_a.rdbuf();
|
||||
|
||||
if (! (lsdp_a->is_open()) ) {
|
||||
G4String excep = G4String("G4BremsstrahlungParameters: cannot open file ")
|
||||
+ name_a;
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
// 2nd column is the corresponding value
|
||||
// The file terminates with the pattern: -1 -1
|
||||
// -2 -2
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* data;
|
||||
G4double ener = 0.0;
|
||||
G4double sum = 0.0;
|
||||
energies = new G4DataVector();
|
||||
data = new G4DataVector();
|
||||
G4int z = 0;
|
||||
|
||||
G4bool used = false;
|
||||
G4std::vector<G4DataVector*> a;
|
||||
for (size_t j=0; j<length; j++) {
|
||||
G4DataVector* aa = new G4DataVector();
|
||||
a.push_back(aa);
|
||||
}
|
||||
G4DataVector e;
|
||||
e.clear();
|
||||
|
||||
do {
|
||||
file_a >> ener >> sum;
|
||||
|
||||
// End of file
|
||||
if (ener == -2) {
|
||||
break;
|
||||
|
||||
// End of next element
|
||||
} else if (ener == -1) {
|
||||
|
||||
z++;
|
||||
G4double Z = (G4double)z;
|
||||
|
||||
// fill map if Z is used
|
||||
if (activeZ.contains(Z)) {
|
||||
|
||||
for (size_t k=0; k<length; k++) {
|
||||
|
||||
G4int id = z*20 + k;
|
||||
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
|
||||
G4DataVector* eVector = new G4DataVector;
|
||||
size_t eSize = e.size();
|
||||
for (size_t s=0; s<eSize; s++) {
|
||||
eVector->push_back(e[s]);
|
||||
}
|
||||
G4VEMDataSet* set = new G4EMDataSet(id,eVector,a[k],inter,1.,1.);
|
||||
param[id] = set;
|
||||
}
|
||||
used = true;
|
||||
a.clear();
|
||||
for (size_t j=0; j<length; j++) {
|
||||
G4DataVector* aa = new G4DataVector();
|
||||
a.push_back(aa);
|
||||
}
|
||||
}
|
||||
if(!used) {
|
||||
for (size_t j=0; j<length; j++) {
|
||||
a[j]->clear();
|
||||
used = false;
|
||||
}
|
||||
}
|
||||
e.clear();
|
||||
|
||||
} else {
|
||||
|
||||
if(ener > 1000.) ener = 1000.;
|
||||
e.push_back(ener);
|
||||
a[length-1]->push_back(sum);
|
||||
|
||||
for (size_t j=0; j<length-1; j++) {
|
||||
G4double qRead;
|
||||
file_a >> qRead;
|
||||
/*
|
||||
if(ener == 1000.) {
|
||||
G4double x = 0.1*((G4double)j);
|
||||
if(j == 0) x = 0.01;
|
||||
if(j == 10) x = 0.95;
|
||||
if(j == 11) x = 0.97;
|
||||
if(j == 12) x = 0.99;
|
||||
if(j == 13) x = 0.995;
|
||||
if(j == 14) x = 1.0;
|
||||
qRead = 1. - x + 0.75*x*x;
|
||||
}
|
||||
*/
|
||||
a[j]->push_back(qRead);
|
||||
}
|
||||
|
||||
}
|
||||
} while (ener != -2);
|
||||
|
||||
file_a.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
G4double G4BremsstrahlungParameters::ParameterC(G4int id) const
|
||||
{
|
||||
G4int n = paramC.size();
|
||||
if (id < 0 || id >= n) {
|
||||
G4String ex = "G4BremsstrahlungParameters::ParameterC - wrong id=" + id;
|
||||
G4Exception(ex);
|
||||
}
|
||||
|
||||
return paramC[id];
|
||||
}
|
||||
|
||||
|
||||
void G4BremsstrahlungParameters::PrintData() const
|
||||
{
|
||||
|
||||
G4cout << G4endl;
|
||||
G4cout << "===== G4BremsstrahlungParameters =====" << G4endl;
|
||||
G4cout << G4endl;
|
||||
G4cout << "===== Parameters =====" << G4endl;
|
||||
G4cout << G4endl;
|
||||
|
||||
size_t nZ = activeZ.size();
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
for (size_t j=0; j<nZ; j++) {
|
||||
G4int Z = (G4int)activeZ[j];
|
||||
|
||||
for (size_t i=0; i<length; i++) {
|
||||
|
||||
pos = param.find(Z*20 + i);
|
||||
if (pos!= param.end()) {
|
||||
|
||||
G4cout << "===== Z= " << Z
|
||||
<< " parameter[" << i << "] ====="
|
||||
<< G4endl;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
dataSet->PrintData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4cout << "==========================================" << G4endl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4CompositeEMDataSet.cc,v 1.5 2001/10/25 02:32:16 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 1 Aug 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
|
||||
G4CompositeEMDataSet::G4CompositeEMDataSet(G4VDataSetAlgorithm* interpolation,
|
||||
G4double unitE, G4double unitData,
|
||||
G4int minZ, G4int maxZ)
|
||||
:algorithm(interpolation), unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
|
||||
{
|
||||
nComponents = 0;
|
||||
}
|
||||
|
||||
G4CompositeEMDataSet::G4CompositeEMDataSet(const G4String& dataFile,
|
||||
G4VDataSetAlgorithm* interpolation,
|
||||
G4double unitE, G4double unitData,
|
||||
G4int minZ, G4int maxZ)
|
||||
: algorithm(interpolation), unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
|
||||
{
|
||||
nComponents = 0;
|
||||
LoadData(dataFile);
|
||||
}
|
||||
|
||||
G4CompositeEMDataSet::~G4CompositeEMDataSet()
|
||||
{
|
||||
for (size_t i=0; i<nComponents; i++)
|
||||
{
|
||||
delete components[i];
|
||||
}
|
||||
delete algorithm;
|
||||
}
|
||||
|
||||
G4double G4CompositeEMDataSet::FindValue(G4double e, G4int id) const
|
||||
{
|
||||
// Returns the value in component id corresponding to e
|
||||
G4double value = 0.;
|
||||
|
||||
G4VEMDataSet* component = components[id];
|
||||
if (component != 0)
|
||||
{
|
||||
value = component->FindValue(e);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "WARNING - G4CompositeEMDataSet::FindValue - component "
|
||||
<< id << " not found" << G4endl;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void G4CompositeEMDataSet::PrintData() const
|
||||
{
|
||||
G4cout << "The data set has " << nComponents << " components" << G4endl;
|
||||
|
||||
for (size_t i=0; i<nComponents; i++)
|
||||
{
|
||||
G4cout << "--- Component " << i << " ---" << G4endl;
|
||||
G4VEMDataSet* component = components[i];
|
||||
component->PrintData();
|
||||
}
|
||||
}
|
||||
|
||||
void G4CompositeEMDataSet::LoadData(const G4String& fileName)
|
||||
{
|
||||
|
||||
for (G4int Z=zMin; Z<zMax; Z++)
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
ost << fileName << Z << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4CompositeEMDataSet - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + "/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4CompositeEMDataSet - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* data = new G4DataVector;
|
||||
do
|
||||
{
|
||||
file >> a;
|
||||
G4int nColumns = 2;
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
// 2nd column is the corresponding value
|
||||
// The file terminates with the pattern: -1 -1
|
||||
// -2 -2
|
||||
if (a == -1 || a == -2)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (k%nColumns != 0)
|
||||
{
|
||||
G4double e = a * unit1;
|
||||
energies->push_back(e);
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
{
|
||||
G4double value = a * unit2;
|
||||
data->push_back(value);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
} while (a != -2); // end of file
|
||||
|
||||
file.close();
|
||||
|
||||
G4VDataSetAlgorithm* algo = algorithm->Clone();
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(Z,energies,data,algo);
|
||||
AddComponent(dataSet);
|
||||
}
|
||||
}
|
||||
|
||||
void G4CompositeEMDataSet::AddComponent(G4VEMDataSet* component)
|
||||
{
|
||||
components.push_back(component);
|
||||
nComponents++;
|
||||
}
|
||||
|
||||
const G4DataVector& G4CompositeEMDataSet::GetEnergies(G4int i) const
|
||||
{
|
||||
const G4VEMDataSet* component = GetComponent(i);
|
||||
return (component->GetEnergies(i));
|
||||
}
|
||||
|
||||
const G4DataVector& G4CompositeEMDataSet::GetData(G4int i) const
|
||||
{
|
||||
const G4VEMDataSet* component = GetComponent(i);
|
||||
return (component->GetData(i));
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4CrossSectionHandler.cc,v 1.12 2001/10/08 07:48:57 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 1 Aug 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "g4std/map"
|
||||
#include "g4std/vector"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
|
||||
G4CrossSectionHandler::G4CrossSectionHandler()
|
||||
{ }
|
||||
|
||||
G4CrossSectionHandler::~G4CrossSectionHandler()
|
||||
{ }
|
||||
|
||||
G4std::vector<G4VEMDataSet*>*
|
||||
G4CrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
G4DataVector* energies;
|
||||
G4DataVector* data;
|
||||
|
||||
G4std::vector<G4VEMDataSet*>* matCrossSections = new G4std::vector<G4VEMDataSet*>;
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
size_t nOfBins = energyVector.size();
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++)
|
||||
{
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
G4VDataSetAlgorithm* interpolationAlgo = CreateInterpolation();
|
||||
for (size_t bin=0; bin<nOfBins; bin++)
|
||||
{
|
||||
G4double e = energyVector[bin];
|
||||
energies->push_back(e);
|
||||
G4double materialCrossSection = ValueForMaterial(material,e);
|
||||
data->push_back(materialCrossSection);
|
||||
}
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(m,energies,data,interpolationAlgo,1.,1.);
|
||||
matCrossSections->push_back(dataSet);
|
||||
}
|
||||
return matCrossSections;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4CutsPerMaterialWarning.cc,v 1.1 2001/11/07 22:39:02 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 05 Oct 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
|
||||
void G4CutsPerMaterialWarning::PrintWarning(const G4ParticleDefinition* particle) const
|
||||
{
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
size_t nMaterials = materialTable->size();
|
||||
if (nMaterials > 1)
|
||||
{
|
||||
G4Material* material = (*materialTable)[0];
|
||||
G4double cut0 = particle->GetRangeThreshold(material);
|
||||
G4double cut = cut0;
|
||||
G4bool different = false;
|
||||
size_t mat = 0;
|
||||
while ((!different) && mat < (nMaterials-1))
|
||||
{
|
||||
mat++;
|
||||
G4Material* material = (*materialTable)[mat];
|
||||
cut = particle->GetRangeThreshold(material);
|
||||
if (cut != cut0) different = true;
|
||||
}
|
||||
|
||||
|
||||
if (different)
|
||||
{
|
||||
G4cout << "========================== W A R N I N G ============================ " << G4endl
|
||||
<< " " << G4endl
|
||||
<< "You are using different range thresholds for different materials" << G4endl
|
||||
<< "This is an UNSUPPORTED feature temporarily implemented in Geant4" << G4endl
|
||||
<< "Geant4 Low Energy Electromagnetic Physics Processes are not supported," << G4endl
|
||||
<< "if this feature is activated and you may get inconsistent results" << G4endl
|
||||
<< "Please define the same range threshold for all materials" << G4endl
|
||||
<< " " << G4endl
|
||||
<< "========================== W A R N I N G ============================ " << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EMDataSet.cc,v 1.5 2001/10/08 07:48:57 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
// Constructor
|
||||
|
||||
G4EMDataSet::G4EMDataSet(G4int Z,
|
||||
G4DataVector* points,
|
||||
G4DataVector* values,
|
||||
G4VDataSetAlgorithm* interpolation,
|
||||
G4double unitE, G4double unitData)
|
||||
:z(Z), energies(points), data(values), algorithm(interpolation)
|
||||
{
|
||||
numberOfBins = energies->size();
|
||||
unit1 = unitE;
|
||||
unit2 = unitData;
|
||||
if (interpolation == 0)
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - interpolation algorithm = 0");
|
||||
}
|
||||
|
||||
G4EMDataSet:: G4EMDataSet(G4int Z,
|
||||
const G4String& dataFile,
|
||||
G4VDataSetAlgorithm* interpolation,
|
||||
G4double unitE, G4double unitData)
|
||||
:z(Z), algorithm(interpolation)
|
||||
{
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
unit1 = unitE;
|
||||
unit2 = unitData;
|
||||
LoadData(dataFile);
|
||||
numberOfBins = energies->size();
|
||||
if (interpolation == 0)
|
||||
G4Exception("G4EMDataSet::G4EMDataSet - interpolation algorithm = 0");
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
||||
G4EMDataSet::~G4EMDataSet()
|
||||
{
|
||||
delete algorithm;
|
||||
delete energies;
|
||||
delete data;
|
||||
}
|
||||
|
||||
|
||||
G4double G4EMDataSet::FindValue(G4double e, G4int id) const
|
||||
{
|
||||
G4double value;
|
||||
G4double e0 = (*energies)[0];
|
||||
// Protections
|
||||
size_t bin = FindBinLocation(e);
|
||||
if (bin == numberOfBins)
|
||||
{
|
||||
// G4cout << "WARNING - G4EMDataSet::FindValue: energy outside upper boundary"
|
||||
// << G4endl;
|
||||
value = (*data)[bin];
|
||||
}
|
||||
else if (e <= e0)
|
||||
{
|
||||
// G4cout << "WARNING - G4EMDataSet::FindValue: energy outside lower boundary"
|
||||
// << G4endl;
|
||||
value = (*data)[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (algorithm == 0)
|
||||
G4Exception("G4EMDataSet::FindValue - interpolation algorithm = 0");
|
||||
value = algorithm->Calculate(e,bin,*energies,*data);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
G4int G4EMDataSet::FindBinLocation(G4double energy) const
|
||||
{
|
||||
// Protection against call outside allowed range
|
||||
G4double e0 = (*energies)[0];
|
||||
if (energy < e0)
|
||||
{
|
||||
// G4cout << z
|
||||
// << " - WARNING - G4EMDataSet::FindBinLocation called with argument "
|
||||
// << energy
|
||||
// << " outside lower limit "
|
||||
// << e0
|
||||
// << "; replaced with lower limit"
|
||||
// << G4endl;
|
||||
energy = e0;
|
||||
}
|
||||
|
||||
size_t lowerBound = 0;
|
||||
size_t upperBound = numberOfBins - 1;
|
||||
|
||||
// Binary search
|
||||
while (lowerBound <= upperBound)
|
||||
{
|
||||
size_t midBin = (lowerBound + upperBound)/2;
|
||||
if ( energy < (*energies)[midBin] ) upperBound = midBin-1;
|
||||
else lowerBound = midBin+1;
|
||||
}
|
||||
|
||||
return upperBound;
|
||||
}
|
||||
|
||||
void G4EMDataSet::LoadData(const G4String& fileName)
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
ost << fileName << z << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + "/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4EMDataSet - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
|
||||
do
|
||||
{
|
||||
file >> a;
|
||||
G4int nColumns = 2;
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
// 2nd column is the corresponding value
|
||||
// The file terminates with the pattern: -1 -1
|
||||
// -2 -2
|
||||
if (a == -1 || a == -2)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (k%nColumns != 0)
|
||||
{
|
||||
G4double e = a * unit1;
|
||||
energies->push_back(e);
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
{
|
||||
G4double value = a * unit2;
|
||||
data->push_back(value);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
|
||||
} while (a != -2); // end of file
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void G4EMDataSet::PrintData() const
|
||||
{
|
||||
size_t size = numberOfBins;
|
||||
for (size_t i=0; i<size; i++)
|
||||
{
|
||||
G4double e = (*energies)[i] / unit1;
|
||||
G4double sigma = (*data)[i] / unit2 ;
|
||||
G4cout << "Point: "
|
||||
<< e
|
||||
<< " - Data value : "
|
||||
<< sigma
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4FluoDataData.cc,v 1.2
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 16 Sept 2001 First committed to cvs
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4FluoData.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
G4FluoData::G4FluoData()
|
||||
{
|
||||
numberOfVacancies=0;
|
||||
}
|
||||
|
||||
G4FluoData::~G4FluoData()
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
for (pos = idMap.begin(); pos != idMap.end(); pos++)
|
||||
{
|
||||
G4DataVector* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
for (pos = energyMap.begin(); pos != energyMap.end(); pos++)
|
||||
{
|
||||
G4DataVector* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
for (pos = probabilityMap.begin(); pos != probabilityMap.end(); pos++)
|
||||
{
|
||||
G4DataVector* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
}
|
||||
|
||||
size_t G4FluoData::NumberOfVacancies() const
|
||||
{
|
||||
return numberOfVacancies;
|
||||
}
|
||||
|
||||
G4int G4FluoData::VacancyId(G4int vacancyIndex) const
|
||||
{
|
||||
G4int n = -1;
|
||||
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
|
||||
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
|
||||
else
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = idMap.find(vacancyIndex);
|
||||
if (pos!= idMap.end())
|
||||
{ G4DataVector dataSet = (*(*pos).second);
|
||||
n = (G4int) dataSet[0];
|
||||
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t G4FluoData::NumberOfTransitions(G4int vacancyIndex) const
|
||||
{
|
||||
G4int n = 0;
|
||||
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
|
||||
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
|
||||
else
|
||||
{
|
||||
n = nInitShells[vacancyIndex]-1;
|
||||
//-1 is necessary because the elements of the vector nInitShells
|
||||
//include also the vacancy shell:
|
||||
// -1 subtracts this last one
|
||||
}
|
||||
return n;
|
||||
}
|
||||
G4int G4FluoData::StartShellId(G4int initIndex,G4int vacancyIndex)
|
||||
{
|
||||
G4int n = -1;
|
||||
|
||||
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
|
||||
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
|
||||
else
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = idMap.find(vacancyIndex);
|
||||
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
{
|
||||
n = (G4int) dataSet[initIndex];
|
||||
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
G4double G4FluoData::StartShellEnergy(G4int initIndex,G4int vacancyIndex)
|
||||
{
|
||||
G4double n = -1;
|
||||
|
||||
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
|
||||
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
|
||||
else
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = energyMap.find(vacancyIndex);
|
||||
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
{
|
||||
n = dataSet[initIndex];
|
||||
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
G4double G4FluoData::StartShellProb(G4int initIndex,G4int vacancyIndex)
|
||||
{
|
||||
G4double n = -1;
|
||||
|
||||
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
|
||||
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
|
||||
else
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = probabilityMap.find(vacancyIndex);
|
||||
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
|
||||
G4int nData = dataSet.size();
|
||||
if (initIndex >= 0 && initIndex < nData)
|
||||
{
|
||||
n = dataSet[initIndex];
|
||||
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void G4FluoData::LoadData(G4int Z)
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
if(Z != 0){
|
||||
ost << "fl-tr-pr-"<< Z << ".dat";
|
||||
}
|
||||
else{
|
||||
ost << "fl-tr-pr-"<<".dat";
|
||||
}
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + "/fluor/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4FluoData - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
G4int s = 0;
|
||||
|
||||
G4int vacId = 0;
|
||||
G4DataVector* initIds = new G4DataVector;
|
||||
G4DataVector* transEnergies = new G4DataVector;
|
||||
G4DataVector* transProbabilities = new G4DataVector;
|
||||
|
||||
do {
|
||||
file >> a;
|
||||
G4int nColumns = 3;
|
||||
if (a == -1)
|
||||
{
|
||||
if (s == 0)
|
||||
{
|
||||
// End of a shell data set
|
||||
idMap[vacId] = initIds;
|
||||
energyMap[vacId] = transEnergies;
|
||||
probabilityMap[vacId] = transProbabilities;
|
||||
// G4double size=transProbabilities->size();
|
||||
G4int n = initIds->size();
|
||||
|
||||
nInitShells.push_back(n);
|
||||
numberOfVacancies++;
|
||||
// Start of new shell data set
|
||||
initIds = new G4DataVector;
|
||||
transEnergies = new G4DataVector;
|
||||
transProbabilities = new G4DataVector;
|
||||
vacId++;
|
||||
}
|
||||
s++;
|
||||
if (s == nColumns)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
}
|
||||
else if (a == -2)
|
||||
{
|
||||
// End of file; delete the empty vectors created
|
||||
//when encountering the last -1 -1 row
|
||||
delete initIds;
|
||||
delete transEnergies;
|
||||
delete transProbabilities;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(k%nColumns == 2)
|
||||
{
|
||||
// 2nd column is transition probabilities
|
||||
|
||||
transProbabilities->push_back(a);
|
||||
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 1)
|
||||
{
|
||||
// 1st column is shell id
|
||||
|
||||
initIds->push_back(a);
|
||||
k++;
|
||||
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
|
||||
{//third column is transition energies
|
||||
|
||||
G4double e = a * MeV;
|
||||
transEnergies->push_back(e);
|
||||
|
||||
k=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (a != -2); // end of file
|
||||
file.close();
|
||||
}
|
||||
|
||||
void G4FluoData::PrintData()
|
||||
{
|
||||
|
||||
for (G4int i = 0; i <numberOfVacancies; i++)
|
||||
{
|
||||
G4cout << "---- TransitionData for the vacancy nb "
|
||||
<<i
|
||||
<<" ----- "
|
||||
<<G4endl;
|
||||
|
||||
for (size_t k = 0; k<=NumberOfTransitions(i); k++)
|
||||
{
|
||||
G4int id = StartShellId(k,i);
|
||||
G4double e = StartShellEnergy(k,i) /MeV;
|
||||
G4double p = StartShellProb(k,i);
|
||||
G4cout << k <<") Shell id: " << id <<G4endl;
|
||||
G4cout << " - Transition energy = " << e << " MeV "<<G4endl;
|
||||
G4cout << " - Transition probability = " << p <<G4endl;
|
||||
|
||||
}
|
||||
G4cout << "-------------------------------------------------"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+40
-30
@@ -21,42 +21,52 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// GEANT 4 class file
|
||||
// $Id: G4LinInterpolation.cc,v 1.1 2001/11/29 19:01:36 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// CERN, Geneva, Switzerland
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// File name: G4SecondLevel.hh
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created
|
||||
//
|
||||
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
|
||||
//
|
||||
// Creation date: 1 Giugno 1999
|
||||
//
|
||||
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4SecondLevel.hh"
|
||||
#include "G4LinInterpolation.hh"
|
||||
|
||||
// Constructor
|
||||
|
||||
G4LinInterpolation::G4LinInterpolation()
|
||||
{ }
|
||||
|
||||
|
||||
G4SecondLevel::~G4SecondLevel(){
|
||||
// Destructor
|
||||
|
||||
// this->clearAndDestroy();
|
||||
this->clear();
|
||||
G4LinInterpolation::~G4LinInterpolation()
|
||||
{ }
|
||||
|
||||
|
||||
G4double G4LinInterpolation::Calculate(G4double x, G4int bin,
|
||||
const G4DataVector& points,
|
||||
const G4DataVector& data) const
|
||||
{
|
||||
G4int nBins = data.size() - 1;
|
||||
G4double value = 0.;
|
||||
if (x < points[0])
|
||||
{
|
||||
value = 0.;
|
||||
}
|
||||
else if (bin < nBins)
|
||||
{
|
||||
G4double e1 = points[bin];
|
||||
G4double e2 = points[bin+1];
|
||||
G4double d1 = data[bin];
|
||||
G4double d2 = data[bin+1];
|
||||
value = d1 + (d2 - d1)*(x - e1)/(e2 - e1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = data[nBins];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
G4bool G4SecondLevel::operator == (const G4SecondLevel& input) const{
|
||||
|
||||
// return( this->entries() == input.entries());
|
||||
return( this->size() == input.size());
|
||||
|
||||
}
|
||||
|
||||
G4bool G4SecondLevel::operator < (const G4SecondLevel& input) const{
|
||||
|
||||
// return(this->entries() < input.entries());
|
||||
return(this->size() < input.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LogLogInterpolation.cc,v 1.3 2001/09/10 18:07:35 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
|
||||
// Constructor
|
||||
|
||||
G4LogLogInterpolation::G4LogLogInterpolation()
|
||||
{ }
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
G4LogLogInterpolation::~G4LogLogInterpolation()
|
||||
{ }
|
||||
|
||||
|
||||
G4double G4LogLogInterpolation::Calculate(G4double x, G4int bin,
|
||||
const G4DataVector& points,
|
||||
const G4DataVector& data) const
|
||||
{
|
||||
G4int nBins = data.size() - 1;
|
||||
G4double value = 0.;
|
||||
if (x < points[0])
|
||||
{
|
||||
value = 0.;
|
||||
}
|
||||
else if (bin < nBins)
|
||||
{
|
||||
G4double e1 = points[bin];
|
||||
G4double e2 = points[bin+1];
|
||||
G4double d1 = data[bin];
|
||||
G4double d2 = data[bin+1];
|
||||
value = (log10(d1)*log10(e2/x) + log10(d2)*log10(x/e1)) / log10(e2/e1);
|
||||
value = pow(10,value);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = data[nBins];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -20,22 +20,20 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.34.2.2 2001/06/28 20:19:28 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
//
|
||||
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.54 2001/11/29 19:01:36 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// ------------ G4LowEnergyBremsstrahlung: low energy modifications --------
|
||||
// by Alessandra Forti, March 1999
|
||||
// File name: G4LowEnergyBremsstrahlung
|
||||
//
|
||||
// **************************************************************
|
||||
// Author: Alessandra Forti, Vladimir Ivanchenko
|
||||
//
|
||||
// 18.04.2000 V.L.
|
||||
// - First implementation of continuous energy loss.
|
||||
// Creation date: March 1999
|
||||
//
|
||||
// Modifications:
|
||||
// 18.04.2000 V.L.
|
||||
// - First implementation of continuous energy loss.
|
||||
// 17.02.2000 Veronique Lefebure
|
||||
// - correct bug : the gamma energy was not deposited when the gamma was
|
||||
// not produced when its energy was < cutForLowEnergySecondaryPhotons
|
||||
@@ -47,198 +45,141 @@
|
||||
// Added map of the elements A. Forti
|
||||
// 20.09.00 update printout V.Ivanchenko
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
// 29.09.2001 V.Ivanchenko: major revision based on design iteration
|
||||
// 10.10.2001 MGP Revision to improve code quality and consistency with design
|
||||
// 18.10.2001 MGP Revision to improve code quality
|
||||
// 28.10.2001 VI Update printout
|
||||
// 29.11.2001 VI New parametrisation
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4LowEnergyBremsstrahlung.hh"
|
||||
#include "G4eBremsstrahlungSpectrum.hh"
|
||||
#include "G4BremsstrahlungCrossSectionHandler.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
//
|
||||
|
||||
// constructor
|
||||
|
||||
G4LowEnergyBremsstrahlung::G4LowEnergyBremsstrahlung(const G4String& processName)
|
||||
: G4eLowEnergyLoss(processName), // initialization
|
||||
theCrossSectionTable(0),
|
||||
theMeanFreePathTable(0),
|
||||
ATable(0),
|
||||
BTable(0),
|
||||
ZNumVec(0),
|
||||
lowEnergyCut(0.1*eV),
|
||||
cutForLowEnergySecondaryPhotons(0.)
|
||||
{
|
||||
lowestKineticEnergy = GetLowerBoundEloss();
|
||||
highestKineticEnergy = GetUpperBoundEloss();
|
||||
totBin = GetNbinEloss();
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
G4LowEnergyBremsstrahlung::G4LowEnergyBremsstrahlung(const G4String& nam)
|
||||
: G4eLowEnergyLoss(nam),
|
||||
crossSectionHandler(0),
|
||||
theMeanFreePath(0),
|
||||
energySpectrum(0)
|
||||
{
|
||||
cutForPhotons = 0.;
|
||||
verboseLevel = 0;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// destructor
|
||||
|
||||
|
||||
G4LowEnergyBremsstrahlung::~G4LowEnergyBremsstrahlung()
|
||||
{
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
if (ATable) {
|
||||
|
||||
delete ATable;
|
||||
}
|
||||
|
||||
if (BTable) {
|
||||
|
||||
delete BTable;
|
||||
}
|
||||
|
||||
if (&partialSumSigma) {
|
||||
|
||||
partialSumSigma.clearAndDestroy();
|
||||
}
|
||||
if(crossSectionHandler) delete crossSectionHandler;
|
||||
if(energySpectrum) delete energySpectrum;
|
||||
if(theMeanFreePath) delete theMeanFreePath;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SET CUT FOR LOW ENERGY SECONDARY PHOTONS A. FORTI
|
||||
void G4LowEnergyBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut){
|
||||
|
||||
cutForLowEnergySecondaryPhotons = cut;
|
||||
}
|
||||
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE
|
||||
void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
|
||||
BuildZVec();
|
||||
|
||||
// energy sampling formula coefficient
|
||||
BuildATable();
|
||||
BuildBTable();
|
||||
BuildCrossSectionTable() ;
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4LowEnergyBremsstrahlung::BuildPhysicsTable start"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
BuildLossTable(aParticleType) ;
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&aParticleType);
|
||||
|
||||
cutForSecondaryPhotons.clear();
|
||||
|
||||
if (&aParticleType==G4Electron::Electron()){
|
||||
// Create and fill BremsstrahlungParameters once
|
||||
if( energySpectrum != 0 ) delete energySpectrum;
|
||||
energySpectrum = new G4eBremsstrahlungSpectrum();
|
||||
|
||||
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable ;
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4LowEnergyBremsstrahlungSpectrum is initialized"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Create and fill G4CrossSectionHandler once
|
||||
|
||||
if( crossSectionHandler != 0 ) delete crossSectionHandler;
|
||||
G4VDataSetAlgorithm* interpolation = new G4LogLogInterpolation();
|
||||
G4double lowKineticEnergy = GetLowerBoundEloss();
|
||||
G4double highKineticEnergy = GetUpperBoundEloss();
|
||||
G4int totBin = GetNbinEloss();
|
||||
crossSectionHandler = new G4BremsstrahlungCrossSectionHandler(energySpectrum, interpolation);
|
||||
crossSectionHandler->Initialise(0,lowKineticEnergy, highKineticEnergy, totBin);
|
||||
crossSectionHandler->LoadShellData("brem/br-cs-");
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << GetProcessName()
|
||||
<< " is created; Cross section data: "
|
||||
<< G4endl;
|
||||
crossSectionHandler->PrintData();
|
||||
G4cout << "Parameters: "
|
||||
<< G4endl;
|
||||
energySpectrum->PrintData();
|
||||
}
|
||||
|
||||
// Build loss table for Bremsstrahlung
|
||||
|
||||
BuildLossTable(aParticleType);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "The loss table is built"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if (&aParticleType==G4Electron::Electron()) {
|
||||
|
||||
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable;
|
||||
CounterOfElectronProcess++;
|
||||
PrintInfoDefinition();
|
||||
}
|
||||
else{
|
||||
|
||||
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable ;
|
||||
} else {
|
||||
|
||||
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable;
|
||||
CounterOfPositronProcess++;
|
||||
}
|
||||
|
||||
BuildMeanFreePathTable() ;
|
||||
|
||||
BuildDEDXTable(aParticleType) ;
|
||||
|
||||
|
||||
}
|
||||
//
|
||||
|
||||
// CONSTRUCT THE CROSS SECTION TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC.
|
||||
void G4LowEnergyBremsstrahlung::BuildCrossSectionTable(){
|
||||
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
theCrossSectionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "brem/br-cs-");
|
||||
|
||||
// theCrossSectionTable->insert(oneAtomCS);
|
||||
theCrossSectionTable->push_back(oneAtomCS);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
// Build mean free path data using cut values
|
||||
|
||||
// CONSTRUCT THE TABLE OF THE FIRST PARAMETER OF THE SAMPLING FORMULA
|
||||
void G4LowEnergyBremsstrahlung::BuildATable(){
|
||||
if( theMeanFreePath != 0 ) delete theMeanFreePath;
|
||||
theMeanFreePath = crossSectionHandler->
|
||||
BuildMeanFreePathForMaterials(&cutForSecondaryPhotons);
|
||||
|
||||
if (ATable) {
|
||||
|
||||
delete ATable;
|
||||
}
|
||||
G4int dataNum = 2;
|
||||
ATable = util.BuildSecondLevelTables(0,dataNum,"brem/br-co-a");
|
||||
|
||||
}
|
||||
|
||||
// CONSTRUCT THE TABLE OF THE PARAMETERS OF THE FORMULA OF THE
|
||||
// SECOND PARAMETER OF THE SAMPLING FORMULA
|
||||
void G4LowEnergyBremsstrahlung::BuildBTable(){
|
||||
|
||||
if (BTable) {
|
||||
|
||||
delete BTable;
|
||||
}
|
||||
G4int dataNum = 2;
|
||||
BTable = util.BuildFirstLevelTables(0, dataNum, "brem/br-co-b");
|
||||
|
||||
}
|
||||
|
||||
// Vector mapping the existing elements in the material table
|
||||
// needed at initialization time to load only the necessary data
|
||||
void G4LowEnergyBremsstrahlung::BuildZVec(){
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if(ZNumVec){
|
||||
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
ZNumVec = new G4DataVector();
|
||||
for (G4int J=0 ; J < numOfMaterials; J++){
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ ){
|
||||
|
||||
G4double Zel = (*theElementVector)(iel)->GetZ();
|
||||
|
||||
if( !(ZNumVec->contains(Zel)) ) {
|
||||
ZNumVec->push_back(Zel);
|
||||
} else{
|
||||
continue;
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "The MeanFreePath table is built"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build common DEDX table for all ionisation processes
|
||||
|
||||
BuildDEDXTable(aParticleType);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4LowEnergyBremsstrahlung::BuildPhysicsTable end"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build table for energy loss due to soft brems
|
||||
// the tables are built for *MATERIALS*
|
||||
// Build table for energy loss due to soft brems
|
||||
// the tables are built for *MATERIALS* binning is taken from LowEnergyLoss
|
||||
|
||||
G4double lowKineticEnergy = GetLowerBoundEloss();
|
||||
G4double highKineticEnergy = GetUpperBoundEloss();
|
||||
size_t totBin = GetNbinEloss();
|
||||
|
||||
|
||||
// create table
|
||||
|
||||
if (theLossTable) {
|
||||
@@ -246,466 +187,176 @@ void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aPart
|
||||
delete theLossTable;
|
||||
}
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const G4int numOfMaterials = theMaterialTable->length();
|
||||
const size_t numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
theLossTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// loop for materials
|
||||
// Clean up the vector of cuts
|
||||
cutForSecondaryPhotons.clear();
|
||||
|
||||
// Loop for materials
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++){
|
||||
for (size_t j=0; j<numOfMaterials; j++) {
|
||||
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowestKineticEnergy,
|
||||
highestKineticEnergy,
|
||||
totBin);
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowKineticEnergy,
|
||||
highKineticEnergy,
|
||||
totBin);
|
||||
|
||||
const G4double Tcut = G4Gamma::Gamma()->GetCutsInEnergy()[material->GetIndex()] ;
|
||||
G4cout<<"*** LE Bremsstrahlung using Gamma Tcut = "<<Tcut
|
||||
<<" for material "<< material->GetName()
|
||||
<<G4endl;
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
const G4double* theAtomicNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
|
||||
// now comes the loop for the kinetic energy values
|
||||
for (G4int i = 0 ; i < totBin ; i++){
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[j];
|
||||
|
||||
const G4double LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
G4double ionloss = 0.;
|
||||
// loop for elements in the material
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ ){
|
||||
const G4double Z = (*theElementVector)(iel)->GetZ();
|
||||
ionloss += GetEnergyLossWithCut(Z,LowEdgeEnergy,Tcut)*
|
||||
theAtomicNumDensityVector[iel] ;
|
||||
}
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
// the cut cannot be below lowest limit
|
||||
G4double tCut = G4std::min(highKineticEnergy,
|
||||
((G4Gamma::Gamma())->GetEnergyThreshold(material)));
|
||||
// ((G4Gamma::Gamma())->GetCutsInEnergy())[j]);
|
||||
cutForSecondaryPhotons.push_back(tCut);
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
size_t NumberOfElements = material->GetNumberOfElements() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "Energy loss for material # " << j
|
||||
<< " tCut(keV)= " << tCut/keV
|
||||
<< G4endl;
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// now comes the loop for the kinetic energy values
|
||||
for (size_t i = 0; i<totBin; i++) {
|
||||
|
||||
//
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
|
||||
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
|
||||
//
|
||||
void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
|
||||
|
||||
// Build mean free path tables for the gamma emission by e- or e+.
|
||||
// tables are Build for MATERIALS. see GENERAL part of processes in GEANT4
|
||||
// manual
|
||||
{
|
||||
G4double FixedEnergy = (lowestKineticEnergy + highestKineticEnergy)/2.;
|
||||
|
||||
//create table
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
G4Material* material;
|
||||
G4double* CutInKineticEnergy = G4Gamma::Gamma()->GetCutsInEnergy() ;
|
||||
|
||||
partialSumSigma.clearAndDestroy();
|
||||
partialSumSigma.resize(NumbOfMaterials);
|
||||
|
||||
G4double LowEdgeEnergy , Value;
|
||||
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
|
||||
for ( G4int J=0 ; J < NumbOfMaterials; J++ ){
|
||||
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(lowestKineticEnergy, highestKineticEnergy,
|
||||
totBin ) ;
|
||||
|
||||
material= (*theMaterialTable)(J);
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
const G4double Threshold = CutInKineticEnergy[J] ;
|
||||
|
||||
for ( G4int i = 0 ; i < totBin ; i++ ){
|
||||
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
|
||||
const G4double BigPath= DBL_MAX;
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
|
||||
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
|
||||
G4double interCrsSec = GetCrossSectionWithCut(AtomIndex, LowEdgeEnergy,Threshold);
|
||||
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
|
||||
}
|
||||
|
||||
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insert( ptrVector );
|
||||
|
||||
// Compute the partialSumSigma table at a given fixed energy
|
||||
ComputepartialSumSigma(FixedEnergy, material,Threshold) ;
|
||||
}
|
||||
G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(i);
|
||||
G4double ionloss = 0.;
|
||||
|
||||
// loop for elements in the material
|
||||
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
|
||||
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
|
||||
G4double e = energySpectrum->AverageEnergy(Z, 0.0, tCut, lowEdgeEnergy);
|
||||
G4double pro = energySpectrum->Probability(Z, 0.0, tCut, lowEdgeEnergy);
|
||||
G4double cs= crossSectionHandler->FindValue(Z, lowEdgeEnergy);
|
||||
ionloss += e * cs * pro * theAtomicNumDensityVector[iel];
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "Z= " << Z
|
||||
<< "; tCut(keV)= " << tCut/keV
|
||||
<< "; E(keV)= " << lowEdgeEnergy/keV
|
||||
<< "; Eav(keV)= " << e/keV
|
||||
<< "; pro= " << pro
|
||||
<< "; cs= " << cs
|
||||
<< "; loss= " << ionloss
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
aVector->PutValue(i,ionloss);
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
|
||||
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
|
||||
//
|
||||
void G4LowEnergyBremsstrahlung::ComputepartialSumSigma(const G4double KineticEnergy,
|
||||
const G4Material* aMaterial,
|
||||
const G4double Threshold)
|
||||
|
||||
// Build the table of cross section per element. The table is built for MATERIALS.
|
||||
// This table is used by DoIt to select randomly an element in the material.
|
||||
|
||||
G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
G4int Imate = aMaterial->GetIndex();
|
||||
G4int NbOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
aParticleChange.Initialize(track);
|
||||
|
||||
partialSumSigma[Imate] = new G4DataVector();
|
||||
const G4Material* material = track.GetMaterial();
|
||||
G4double kineticEnergy = track.GetKineticEnergy();
|
||||
G4int index = material->GetIndex();
|
||||
G4double tCut = cutForSecondaryPhotons[index];
|
||||
|
||||
G4double SIGMA = 0. ;
|
||||
// Control limits
|
||||
if(tCut >= kineticEnergy)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
|
||||
for ( G4int Ielem=0 ; Ielem < NbOfElements ; Ielem++ ){
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material, kineticEnergy);
|
||||
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(Ielem)->GetZ();
|
||||
|
||||
G4double interCrsSec = GetCrossSectionWithCut(AtomIndex,KineticEnergy,Threshold);
|
||||
|
||||
SIGMA += theAtomNumDensityVector[Ielem]*interCrsSec;
|
||||
|
||||
partialSumSigma[Imate]->push_back(SIGMA);
|
||||
}
|
||||
}
|
||||
G4double tGamma = energySpectrum->SampleEnergy(Z, tCut, kineticEnergy, kineticEnergy);
|
||||
|
||||
//
|
||||
// Sample gamma angle (Z - axis along the parent particle).
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993)
|
||||
// Phys211) derived from Tsai distribution (Rev Mod Phys 49,421(1977))
|
||||
|
||||
G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& stepData){
|
||||
G4double totalEnergy = kineticEnergy + electron_mass_c2;
|
||||
|
||||
// This parametrization is derived from :
|
||||
// Migdal corrections (dielectric suppression).
|
||||
// Migdal: Phys Rev 103:1811 (1956); Messel & Crawford: Pergamon Press (1970)
|
||||
//
|
||||
|
||||
|
||||
aParticleChange.Initialize(trackData);
|
||||
|
||||
G4Material* aMaterial=trackData.GetMaterial() ;
|
||||
|
||||
|
||||
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
|
||||
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
|
||||
G4double ElectKinEn = aDynamicParticle->GetKineticEnergy();
|
||||
const G4double a1 = 0.625, a2 = 3.*a1, d = 27.;
|
||||
G4double u = - log(G4UniformRand()*G4UniformRand());
|
||||
|
||||
// MGP debug
|
||||
// G4cout << "G4LowEnergyBremsstrahlung::PostStepDoIt - ElectKinEn "
|
||||
// << ElectKinEn/keV << " keV " << G4endl;
|
||||
// MGP end
|
||||
|
||||
if(ElectKinEn <= lowestKineticEnergy){
|
||||
if (9./(9.+d) > G4UniformRand()) u /= a1;
|
||||
else u /= a2;
|
||||
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(ElectKinEn);
|
||||
G4double theta = u*electron_mass_c2/totalEnergy;
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4double dirZ = cos(theta);
|
||||
G4double sinTheta = sqrt(1. - dirZ*dirZ);
|
||||
G4double dirX = sinTheta*cos(phi);
|
||||
G4double dirY = sinTheta*sin(phi);
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
}
|
||||
|
||||
G4ParticleMomentum ElectDirection = aDynamicParticle->GetMomentumDirection();
|
||||
|
||||
// Gamma production cut in this material
|
||||
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
|
||||
|
||||
// check against insufficient energy
|
||||
if (ElectKinEn < GammaEnergyCut){
|
||||
aParticleChange.SetEnergyChange(ElectKinEn);
|
||||
aParticleChange.SetLocalEnergyDeposit(0.);
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
// select randomly one element constituing the material
|
||||
G4Element* anElement = SelectRandomAtom(aMaterial);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double TotalEnergy = ElectKinEn + electron_mass_c2;
|
||||
// G4double TotalEnergysquare = TotalEnergy*TotalEnergy ;
|
||||
G4ThreeVector gammaDirection (dirX, dirY, dirZ);
|
||||
G4ThreeVector electronDirection = track.GetMomentumDirection();
|
||||
|
||||
gammaDirection.rotateUz(electronDirection);
|
||||
|
||||
//
|
||||
// The emitted gamma energy is from EEDL data fitted with A/E+B function.
|
||||
// Original formula A/E+B+C*E and sampling methods are reported by J. Stepanek
|
||||
// formula has been modified by A. Forti and S. Giani.
|
||||
|
||||
//
|
||||
// sample the energy of the emitted gamma
|
||||
//
|
||||
G4double p1 = 0, p2 = 0;
|
||||
G4double coeffA = 0, coeffB = 0;
|
||||
G4int AtomicNum = (G4int) anElement->GetZ();
|
||||
coeffA = ComputeA(AtomicNum, ElectKinEn);
|
||||
coeffB = ComputeB(AtomicNum, ElectKinEn);
|
||||
|
||||
//const G4double minEn = lowEnergyCut;
|
||||
const G4double minEn = GammaEnergyCut;
|
||||
|
||||
|
||||
p1 = coeffA*log(ElectKinEn/minEn);
|
||||
p2 = coeffB*(ElectKinEn - minEn);
|
||||
|
||||
G4double IntegrProb = p1+p2;
|
||||
G4double R1 = G4UniformRand()*IntegrProb;
|
||||
|
||||
G4double GammaEnergy = 0.;
|
||||
|
||||
if(R1 <= p1){
|
||||
// Update the incident particle
|
||||
//
|
||||
|
||||
G4double R2 = G4UniformRand();
|
||||
GammaEnergy = ElectKinEn*pow((minEn/ElectKinEn),R2);
|
||||
/// stepanek does: GammaEnergy = exp(R2*log(ElectKinEn/minEn)+log(ElectKinEn));
|
||||
}
|
||||
else if ((p1 < R1) && (R1 <= p1+p2)){
|
||||
G4double finalEnergy = kineticEnergy - tGamma;
|
||||
|
||||
G4double R2 = G4UniformRand();
|
||||
GammaEnergy = ElectKinEn - R2*(ElectKinEn - minEn);
|
||||
// Kinematic problem
|
||||
if (finalEnergy < 0.) {
|
||||
tGamma += finalEnergy;
|
||||
finalEnergy = 0.0;
|
||||
}
|
||||
|
||||
// MGP debug
|
||||
// if (GammaEnergy > 10*keV)
|
||||
// G4cout << "MGP BremPostStepDoIt eGamma = " << GammaEnergy/keV << " keV" << G4endl;
|
||||
G4double momentum = sqrt((totalEnergy + electron_mass_c2)*kineticEnergy);
|
||||
|
||||
/*
|
||||
G4double R1 = minEn + G4UniformRand()*(ElectKinEn- minEn);
|
||||
G4double Max = coeffA/minEn + coeffB;
|
||||
G4double R2 = G4UniformRand()*Max;
|
||||
while (coeffA/R1 + coeffB < R2){
|
||||
R1 = minEn + G4UniformRand()*(ElectKinEn- minEn);
|
||||
R2 = G4UniformRand()*Max;
|
||||
}
|
||||
G4double GammaEnergy = R1;
|
||||
*/
|
||||
|
||||
//**********************//
|
||||
// Angular distribution //
|
||||
//**********************//
|
||||
|
||||
// angles of the emitted gamma. ( Z - axis along the parent particle)
|
||||
// universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev Mod Phys 49,421(1977))
|
||||
|
||||
if(GammaEnergy < minEn){
|
||||
G4cerr<<"Problem with bremsstrahlung gamma energy sampling: Energy<cut:"
|
||||
<<GammaEnergy<<" < "<<minEn
|
||||
<<G4endl;
|
||||
}
|
||||
|
||||
G4double u;
|
||||
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()) u = - log(G4UniformRand()*G4UniformRand())/a1 ;
|
||||
else u = - log(G4UniformRand()*G4UniformRand())/a2 ;
|
||||
|
||||
G4double Teta = u*electron_mass_c2/TotalEnergy ;
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sin(Teta)*cos(Phi) , diry = sin(Teta)*sin(Phi) , dirz = cos(Teta) ;
|
||||
|
||||
G4ThreeVector GammaDirection ( dirx, diry, dirz);
|
||||
|
||||
GammaDirection.rotateUz(ElectDirection);
|
||||
|
||||
//
|
||||
// Update the incident particle
|
||||
//
|
||||
|
||||
G4double NewKinEnergy = ElectKinEn - GammaEnergy;
|
||||
|
||||
//
|
||||
///final state electron:
|
||||
//
|
||||
if (NewKinEnergy > 0.){
|
||||
G4double finalX = momentum*electronDirection.x() - tGamma*gammaDirection.x();
|
||||
G4double finalY = momentum*electronDirection.y() - tGamma*gammaDirection.y();
|
||||
G4double finalZ = momentum*electronDirection.z() - tGamma*gammaDirection.z();
|
||||
|
||||
aParticleChange.SetMomentumChange( ElectDirection );
|
||||
aParticleChange.SetEnergyChange( NewKinEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
G4double norm = 1./sqrt(finalX*finalX + finalY*finalY + finalZ*finalZ);
|
||||
aParticleChange.SetMomentumChange(finalX*norm, finalY*norm, finalZ*norm);
|
||||
aParticleChange.SetEnergyChange( finalEnergy );
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
if (charge<0.){
|
||||
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
else{
|
||||
|
||||
aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
}
|
||||
//
|
||||
///emitted photon:
|
||||
//
|
||||
if(GammaEnergy < GammaEnergyCut){
|
||||
// create G4DynamicParticle object for the gamma
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
gammaDirection, tGamma);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(GammaEnergy);
|
||||
}
|
||||
else{
|
||||
|
||||
// create G4DynamicParticle object for the Gamma
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
GammaDirection, GammaEnergy);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
aParticleChange.SetLocalEnergyDeposit(0.);
|
||||
}
|
||||
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 15){
|
||||
|
||||
G4cout<<"LE Bremsstrahlung PostStepDoIt"<<G4endl;
|
||||
}
|
||||
#endif
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
}
|
||||
|
||||
G4double G4LowEnergyBremsstrahlung::GetEnergyLossWithCut(const G4double AtomicNumber,
|
||||
const G4double KineticEnergy,
|
||||
const G4double Tcut){
|
||||
const G4double minEn = lowEnergyCut ;
|
||||
if(minEn == 0.) G4cerr<<"Minimum Gamma energy should be finite"<<G4endl;
|
||||
|
||||
// shortcut ..........................
|
||||
if(Tcut <= minEn) return 0. ;
|
||||
|
||||
G4double CrossSection = GetCrossSection(AtomicNumber,KineticEnergy) ;
|
||||
// shortcut ..........................
|
||||
if(CrossSection <= 0.) return 0. ;
|
||||
|
||||
G4double loss = 0.;
|
||||
//
|
||||
// energy spectrum of the emitted gamma
|
||||
//
|
||||
G4double MeanTinc;
|
||||
MeanTinc = KineticEnergy;
|
||||
const G4double MeanCS = GetCrossSection(AtomicNumber,MeanTinc);
|
||||
const G4double coeffA = ComputeA(AtomicNumber, MeanTinc);
|
||||
const G4double coeffB = ComputeB(AtomicNumber, MeanTinc);
|
||||
//
|
||||
//integration of T*dSigma/dT between Tmin = minEn and Tcut
|
||||
//
|
||||
G4double Tmax;
|
||||
//
|
||||
//integration of T*dSigma/dT between Tmin = minEn and Tcut
|
||||
//
|
||||
Tmax = Tcut;
|
||||
if(Tmax>MeanTinc) Tmax = MeanTinc;
|
||||
G4double SmallLoss = 0.;
|
||||
SmallLoss = 0.5*coeffB*(Tmax*Tmax - minEn*minEn) + coeffA*(Tmax-minEn);
|
||||
if(SmallLoss < 0.) G4cerr<<"Problem with integration of gamma spectrum: SmallLoss = "<<SmallLoss<<G4endl;
|
||||
//
|
||||
//integration of dSigma/dT between Tmin = minEn and KineticEnergy
|
||||
//
|
||||
Tmax = MeanTinc;
|
||||
G4double norm = coeffB*(Tmax-minEn) + coeffA*log(Tmax/minEn);
|
||||
if(norm <= 0.) G4cerr<<"Problem with integration of gamma spectrum: norm = "<<norm<<G4endl;
|
||||
|
||||
SmallLoss *= MeanCS/norm ;
|
||||
loss+=SmallLoss;
|
||||
return loss ;
|
||||
}
|
||||
//
|
||||
G4double G4LowEnergyBremsstrahlung::GetCrossSection(const G4double AtomicNumber,
|
||||
const G4double KineticEnergy){
|
||||
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomicNumber)];
|
||||
|
||||
return util.DataLogInterpolation(KineticEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]) )*barn;
|
||||
|
||||
}
|
||||
G4double G4LowEnergyBremsstrahlung::GetCrossSectionWithCut(const G4double AtomicNumber,
|
||||
const G4double KineticEnergy,
|
||||
const G4double Tcut){
|
||||
if(KineticEnergy<=Tcut) return 0.;
|
||||
G4double Tmin = Tcut;
|
||||
if(Tcut<lowEnergyCut) Tmin = lowEnergyCut;
|
||||
G4double Tmax = KineticEnergy;
|
||||
|
||||
G4double CrossSection = GetCrossSection(AtomicNumber,KineticEnergy) ;
|
||||
if(CrossSection <= 0.) return 0.;
|
||||
|
||||
const G4double coeffA = ComputeA(AtomicNumber, KineticEnergy);
|
||||
const G4double coeffB = ComputeB(AtomicNumber, KineticEnergy);
|
||||
|
||||
G4double fraction = coeffB*(Tmax-Tmin) + coeffA*log(Tmax/Tmin);
|
||||
if(fraction <= 0.) G4cerr<<"Problem with integration of gamma spectrum: fraction = "<<fraction<<G4endl;
|
||||
G4double norm = coeffB*(Tmax-lowEnergyCut) + coeffA*log(Tmax/lowEnergyCut);
|
||||
if(norm <= 0.) G4cerr<<"Problem with integration of gamma spectrum: norm = "<<norm<<G4endl;
|
||||
fraction /= norm;
|
||||
|
||||
return CrossSection*fraction;
|
||||
}
|
||||
|
||||
//
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
|
||||
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
|
||||
G4Element* G4LowEnergyBremsstrahlung::SelectRandomAtom(G4Material* aMaterial) const
|
||||
{
|
||||
|
||||
|
||||
const G4int Index = aMaterial->GetIndex();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
|
||||
G4double rval = G4UniformRand()*((*partialSumSigma[Index])[NumberOfElements-1]);
|
||||
for ( G4int i=0; i < NumberOfElements; i++ )
|
||||
if (rval <= (*partialSumSigma[Index])[i]) return ((*theElementVector)(i));
|
||||
return (*theElementVector)(0);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void G4LowEnergyBremsstrahlung::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from EEDL database,";
|
||||
comments += "Gamma energy sampled from a parametrised formula.";
|
||||
comments += "Implementation of the continuous dE/dx part.";
|
||||
comments += "\n At present it can be used for electrons ";
|
||||
comments += " in the energy range [250eV,100GeV]";
|
||||
comments +=
|
||||
"\n the process must work with G4LowEnergyIonisation";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments<<G4endl;
|
||||
|
||||
G4String comments = "Total cross sections from EEDL database.";
|
||||
comments += "\n Gamma energy sampled from a parameterised formula.";
|
||||
comments += "\n Implementation of the continuous dE/dx part.";
|
||||
comments += "\n At present it can be used for electrons ";
|
||||
comments += "in the energy range [250eV,100GeV].";
|
||||
comments += "\n The process must work with G4LowEnergyIonisation.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments << G4endl;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
G4bool G4LowEnergyBremsstrahlung::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( (&particle == G4Electron::Electron()) );
|
||||
}
|
||||
|
||||
|
||||
G4double G4LowEnergyBremsstrahlung::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* cond)
|
||||
{
|
||||
*cond = NotForced;
|
||||
G4int index = (track.GetMaterial())->GetIndex();
|
||||
const G4VEMDataSet* data = theMeanFreePath->GetComponent(index);
|
||||
G4double meanFreePath = data->FindValue(track.GetKineticEnergy());
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
void G4LowEnergyBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut)
|
||||
{
|
||||
cutForPhotons = cut;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,416 +20,242 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LowEnergyCompton.cc,v 1.33 2001/11/07 20:47:29 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// $Id: G4LowEnergyCompton.cc,v 1.25.2.2 2001/06/28 20:19:29 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// ------------ G4LowEnergyCompton low energy modifications --------
|
||||
// by Alessandra Forti, October 1998
|
||||
// **************************************************************
|
||||
// History:
|
||||
// --------
|
||||
// Added Livermore data table construction methods A. Forti
|
||||
// Modified BuildMeanFreePath to read new data tables A. Forti
|
||||
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
|
||||
// Added SelectRandomAtom A. Forti
|
||||
// Added map of the elements A. Forti
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
// --------------------------------------------------------------
|
||||
// 24.04.2001 V.Ivanchenko - Remove RogueWave
|
||||
// 06.08.2001 MGP - Revised according to a design iteration
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// This Class Header
|
||||
#include "G4LowEnergyCompton.hh"
|
||||
|
||||
// Collaborating Class Headers
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ForceCondition.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4VCrossSectionHandler.hh"
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
// constructor
|
||||
|
||||
G4LowEnergyCompton::G4LowEnergyCompton(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
theCrossSectionTable(0),
|
||||
theScatteringFunctionTable(0),
|
||||
theMeanFreePathTable(0),
|
||||
ZNumVec(0),
|
||||
lowestEnergyLimit (250*eV), // initialization
|
||||
highestEnergyLimit(100*GeV),
|
||||
numbBinTable(200)
|
||||
lowEnergyLimit(250*eV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
{
|
||||
if (verboseLevel>0) {
|
||||
G4cout << GetProcessName() << " is created "<< G4endl;
|
||||
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
|
||||
G4cout << "highestEnergy: " << highestEnergyLimit/TeV << "TeV " << G4endl;
|
||||
}
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyCompton::G4LowEnergyCompton - energy outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler;
|
||||
|
||||
G4VDataSetAlgorithm* scatterInterpolation = new G4LogLogInterpolation;
|
||||
G4String scatterFile = "comp/ce-sf-";
|
||||
scatterFunctionData = new G4CompositeEMDataSet(scatterFile,scatterInterpolation,1.,1.);
|
||||
|
||||
meanFreePathTable = 0;
|
||||
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// destructor
|
||||
|
||||
G4LowEnergyCompton::~G4LowEnergyCompton()
|
||||
{
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
if (theScatteringFunctionTable) {
|
||||
|
||||
delete theScatteringFunctionTable;
|
||||
}
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
delete meanFreePathTable;
|
||||
delete crossSectionHandler;
|
||||
delete scatterFunctionData;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
|
||||
// methods.............................................................................
|
||||
|
||||
void G4LowEnergyCompton::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
|
||||
|
||||
BuildZVec();
|
||||
|
||||
// Build microscopic cross section table and mean free path table
|
||||
BuildCrossSectionTable();
|
||||
|
||||
// Build mean free path table for the Compton Scattering process
|
||||
BuildMeanFreePathTable();
|
||||
|
||||
// build the scattering function table
|
||||
BuildScatteringFunctionTable();
|
||||
|
||||
}
|
||||
// BUILD THE CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
|
||||
void G4LowEnergyCompton::BuildCrossSectionTable(){
|
||||
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
void G4LowEnergyCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
theCrossSectionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "comp/ce-cs-");
|
||||
|
||||
// theCrossSectionTable->insert(oneAtomCS);
|
||||
theCrossSectionTable->push_back(oneAtomCS);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
// BUILD THE SF TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
|
||||
void G4LowEnergyCompton::BuildScatteringFunctionTable(){
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
if (theScatteringFunctionTable) {
|
||||
|
||||
delete theScatteringFunctionTable;
|
||||
}
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "comp/ce-cs-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
theScatteringFunctionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomSF = util.BuildFirstLevelTables(AtomInd, dataNum, "comp/ce-sf-");
|
||||
|
||||
// theScatteringFunctionTable->insert(oneAtomSF);
|
||||
theScatteringFunctionTable->push_back(oneAtomSF);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
// vector mapping the elements in the material table
|
||||
void G4LowEnergyCompton::BuildZVec(){
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
ZNumVec = new G4DataVector();
|
||||
for (G4int J=0 ; J < numOfMaterials; J++){
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ ){
|
||||
|
||||
G4double Zel = (*theElementVector)(iel)->GetZ();
|
||||
|
||||
if(ZNumVec->contains(Zel) == FALSE){
|
||||
ZNumVec->push_back(Zel);
|
||||
} else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
// The scattered gamma energy is sampled according to Klein - Nishina formula.
|
||||
// then accepted or rejected depending on the Scattering Function multiplied
|
||||
// by factor from Klein - Nishina formula.
|
||||
// Expression of the angular distribution as Klein Nishina
|
||||
// angular and energy distribution and Scattering fuctions is taken from
|
||||
// D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
|
||||
// Phys. Res. B 101 (1995). Method of sampling with form factors is different
|
||||
// data are interpolated while in the article they are fitted.
|
||||
// Reference to the article is from J. Stepanek New Photon, Positron
|
||||
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
|
||||
// TeV (draft).
|
||||
// The random number techniques of Butcher & Messel are used
|
||||
// (Nucl Phys 20(1960),15).
|
||||
|
||||
G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
|
||||
|
||||
//
|
||||
// The scattered gamma energy is sampled according to Klein - Nishina formula.
|
||||
// And then Accepted or rejected basing of the Scattering Function multiplied by factor
|
||||
// from Klein - Nishina formula. Expression of the angular distribution as Klein Nishina
|
||||
// angular and energy distribution and Scattering fuctions is taken from
|
||||
// D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
|
||||
// Phys. Res. B 101 (1995). Method of sampling with form factors is different
|
||||
// data are interpolated while in the article they are fitted.
|
||||
// Reference to the article is from J. Stepanek New Photon, Positron
|
||||
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
|
||||
// TeV (draft).
|
||||
// The random number techniques of Butcher & Messel are used
|
||||
// (Nuc Phys 20(1960),15).
|
||||
// GEANT4 internal units
|
||||
//
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
// Dynamic particle quantities
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
if(GammaEnergy0 <= lowestEnergyLimit){
|
||||
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(GammaEnergy0);
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
|
||||
}
|
||||
|
||||
|
||||
G4double E0_m = GammaEnergy0 / electron_mass_c2 ;
|
||||
G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
// const G4int numOfElem = aMaterial->GetNumberOfElements();
|
||||
|
||||
G4Element* theElement = SelectRandomAtom(aDynamicGamma, aMaterial);
|
||||
G4int elementZ = (G4int) theElement->GetZ();
|
||||
G4double epsilon, epsilonsq, onecost, sint2, greject ;
|
||||
|
||||
G4double epsilon0 = 1./(1. + 2*E0_m) , epsilon0sq = epsilon0*epsilon0;
|
||||
G4double alpha1 = - log(epsilon0) , alpha2 = 0.5*(1.- epsilon0sq);
|
||||
G4double ScatteringFunction, x;
|
||||
G4double wlGamma = h_Planck*c_light/GammaEnergy0;
|
||||
|
||||
// sample the energy rate of the scattered gamma
|
||||
do{
|
||||
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand()){
|
||||
|
||||
epsilon = exp(-alpha1*G4UniformRand()); // pow(epsilon0,G4UniformRand())
|
||||
epsilonsq = epsilon*epsilon;
|
||||
}
|
||||
else{
|
||||
|
||||
epsilonsq = epsilon0sq + (1.- epsilon0sq)*G4UniformRand();
|
||||
epsilon = sqrt(epsilonsq);
|
||||
}
|
||||
|
||||
onecost = (1.- epsilon)/(epsilon*E0_m);
|
||||
sint2 = onecost*(2.-onecost);
|
||||
|
||||
x = sqrt(onecost/2)/(wlGamma/cm);
|
||||
|
||||
const G4FirstLevel* oneAtomSF
|
||||
= (*theScatteringFunctionTable)[ZNumVec->index(elementZ)];
|
||||
|
||||
ScatteringFunction = util.DataLogInterpolation(x, (*(*oneAtomSF)[0]),
|
||||
(*(*oneAtomSF)[1]));
|
||||
greject = (1. - epsilon*sint2/(1.+ epsilonsq))*ScatteringFunction;
|
||||
|
||||
} while(greject < G4UniformRand()*elementZ);
|
||||
|
||||
G4double cosTeta = 1. - onecost , sinTeta = sqrt (sint2);
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sinTeta*cos(Phi) , diry = sinTeta*sin(Phi) , dirz = cosTeta ;
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
//
|
||||
|
||||
G4ThreeVector GammaDirection1 ( dirx,diry,dirz );
|
||||
GammaDirection1.rotateUz(GammaDirection0);
|
||||
aParticleChange.SetMomentumChange( GammaDirection1 ) ;
|
||||
G4double GammaEnergy1 = epsilon*GammaEnergy0;
|
||||
if (GammaEnergy1 > 0.)
|
||||
if (photonEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( GammaEnergy1 ) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(photonEnergy0);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
G4double e0m = photonEnergy0 / electron_mass_c2 ;
|
||||
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element in the current material
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy0);
|
||||
|
||||
G4double epsilon0 = 1. / (1. + 2. * e0m);
|
||||
G4double epsilon0Sq = epsilon0 * epsilon0;
|
||||
G4double alpha1 = -log(epsilon0);
|
||||
G4double alpha2 = 0.5 * (1. - epsilon0Sq);
|
||||
|
||||
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
|
||||
|
||||
// Sample the energy of the scattered photon
|
||||
G4double epsilon;
|
||||
G4double epsilonSq;
|
||||
G4double oneCosT;
|
||||
G4double sinT2;
|
||||
G4double gReject;
|
||||
do
|
||||
{
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand())
|
||||
{
|
||||
epsilon = exp(-alpha1 * G4UniformRand()); // pow(epsilon0,G4UniformRand())
|
||||
epsilonSq = epsilon * epsilon;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilonSq = epsilon0Sq + (1. - epsilon0Sq) * G4UniformRand();
|
||||
epsilon = sqrt(epsilonSq);
|
||||
}
|
||||
|
||||
oneCosT = (1. - epsilon) / ( epsilon * e0m);
|
||||
sinT2 = oneCosT * (2. - oneCosT);
|
||||
G4double x = sqrt(oneCosT/2.) / (wlPhoton/cm);
|
||||
G4double scatteringFunction = scatterFunctionData->FindValue(x,Z-1);
|
||||
gReject = (1. - epsilon * sinT2 / (1. + epsilonSq)) * scatteringFunction;
|
||||
|
||||
} while(gReject < G4UniformRand()*Z);
|
||||
|
||||
G4double cosTheta = 1. - oneCosT;
|
||||
G4double sinTheta = sqrt (sinT2);
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sinTheta * cos(phi);
|
||||
G4double diry = sinTheta * sin(phi);
|
||||
G4double dirz = cosTheta ;
|
||||
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
|
||||
G4ThreeVector photonDirection1(dirx,diry,dirz);
|
||||
photonDirection1.rotateUz(photonDirection0);
|
||||
aParticleChange.SetMomentumChange(photonDirection1) ;
|
||||
G4double photonEnergy1 = epsilon * photonEnergy0;
|
||||
|
||||
if (photonEnergy1 > 0.)
|
||||
{
|
||||
aParticleChange.SetEnergyChange(photonEnergy1) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// kinematic of the scattered electron
|
||||
//
|
||||
|
||||
G4double ElecKineEnergy = GammaEnergy0 - GammaEnergy1 ;
|
||||
|
||||
if (G4EnergyLossTables::GetRange(G4Electron::Electron(), ElecKineEnergy, aMaterial)
|
||||
>= G4std::min(G4Electron::GetCuts(), aStep.GetPostStepPoint()->GetSafety())){
|
||||
// Kinematics of the scattered electron
|
||||
G4double eKineticEnergy = photonEnergy0 - photonEnergy1;
|
||||
|
||||
G4double ElecMomentum = sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector ElecDirection((GammaEnergy0*GammaDirection0 -
|
||||
GammaEnergy1*GammaDirection1)*(1./ElecMomentum));
|
||||
|
||||
// create G4DynamicParticle object for the electron.
|
||||
G4DynamicParticle* aElectron= new G4DynamicParticle (G4Electron::Electron(),
|
||||
ElecDirection, ElecKineEnergy) ;
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary( aElectron );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
}
|
||||
else{
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
aParticleChange.SetLocalEnergyDeposit (ElecKineEnergy);
|
||||
}
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 0){
|
||||
G4cout<<"LE Compton Effect PostStepDoIt"<<G4endl;
|
||||
}
|
||||
#endif
|
||||
// Generate the electron only if with large enough range w.r.t. cuts and safety
|
||||
|
||||
G4double safety = aStep.GetPostStepPoint()->GetSafety();
|
||||
|
||||
if (rangeTest->Escape(G4Electron::Electron(),material,eKineticEnergy,safety))
|
||||
{
|
||||
G4double eMomentum = sqrt(eKineticEnergy*(eKineticEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector eDirection((photonEnergy0 * photonDirection0 -
|
||||
photonEnergy1 * photonDirection1) * (1./eMomentum));
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
eDirection,eKineticEnergy) ;
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(electron);
|
||||
aParticleChange.SetLocalEnergyDeposit(0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
aParticleChange.SetLocalEnergyDeposit(eKineticEnergy);
|
||||
}
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
}
|
||||
|
||||
|
||||
// used log-log interpolation instead of linear interpolation to build the MFP
|
||||
// as reported in the stepanek paper
|
||||
void G4LowEnergyCompton::BuildMeanFreePathTable(){
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
|
||||
|
||||
// material
|
||||
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
G4Material* material;
|
||||
|
||||
// MeanFreePath
|
||||
G4double LowEdgeEnergy, Value;
|
||||
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
|
||||
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
|
||||
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, numbBinTable);
|
||||
|
||||
material = (*theMaterialTable)(J);
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
|
||||
for ( G4int i = 0 ; i < numbBinTable ; i++ ){
|
||||
//For each energy
|
||||
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
|
||||
const G4double BigPath= DBL_MAX;
|
||||
G4double SIGMA = 0 ;
|
||||
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
|
||||
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
|
||||
}
|
||||
|
||||
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
|
||||
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insertAt( J , ptrVector );
|
||||
}
|
||||
G4bool G4LowEnergyCompton::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
|
||||
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
|
||||
G4Element* G4LowEnergyCompton::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma,
|
||||
G4Material* aMaterial){
|
||||
// select randomly 1 element within the material
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
G4double G4LowEnergyCompton::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
|
||||
if (NumberOfElements == 1) return (*theElementVector)(0);
|
||||
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
|
||||
G4double PartialSumSigma = 0.;
|
||||
|
||||
G4double rval = 0;
|
||||
rval = G4UniformRand()/meanFreePath;
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
|
||||
|
||||
G4double crossSection;
|
||||
if (GammaEnergy < lowestEnergyLimit)
|
||||
crossSection = 0. ;
|
||||
else {
|
||||
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
|
||||
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(i)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
crossSection = util.DataLogInterpolation(GammaEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
}
|
||||
|
||||
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
|
||||
if(rval <= PartialSumSigma) return ((*theElementVector)(i));
|
||||
}
|
||||
|
||||
return (*theElementVector)(0);
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,149 +20,114 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyGammaConversion.cc,v 1.19.2.2 2001/06/28 20:19:29 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// --------------------------------------------------------------------
|
||||
///
|
||||
// $Id: G4LowEnergyGammaConversion.cc,v 1.26 2001/11/07 21:31:16 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// ------------ G4LowEnergyGammaConversion physics process --------
|
||||
// by A.Forti 1999/03/02
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 02/03/1999 A. Forti 1st implementation
|
||||
// 14.03.2000 Veronique Lefebure;
|
||||
// Change initialisation of lowestEnergyLimit from 1.22 to 1.022.
|
||||
// Note that the hard coded value 1.022 should be used instead of
|
||||
// 2*electron_mass_c2 in order to agree with the value of the data bank EPDL97
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
// **************************************************************
|
||||
// 27.07.01 F.Longo correct bug in energy distribution
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// This Class Header
|
||||
#include "G4LowEnergyGammaConversion.hh"
|
||||
|
||||
// Collaborating Class Headers
|
||||
#include "globals.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ForceCondition.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4IonisParamElm.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4VCrossSectionHandler.hh"
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
// constructor
|
||||
|
||||
G4LowEnergyGammaConversion::G4LowEnergyGammaConversion(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
theCrossSectionTable(0),
|
||||
theMeanFreePathTable(0),
|
||||
ZNumVec(0),
|
||||
//Use lowest limit of EPDL97 which is larger than 2*electron_mass_c2 = 1.02199812 MeV
|
||||
lowestEnergyLimit (1.022000*MeV),
|
||||
highestEnergyLimit(100*GeV),
|
||||
NumbBinTable(200)
|
||||
lowEnergyLimit(1.022000*MeV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(1.022000*MeV),
|
||||
intrinsicHighEnergyLimit(100*GeV),
|
||||
smallEnergy(2.*MeV)
|
||||
|
||||
{
|
||||
if (verboseLevel>0) {
|
||||
G4cout << GetProcessName() << " is created "<< G4endl;
|
||||
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
|
||||
G4cout << "highestEnergy: " << highestEnergyLimit/GeV << "GeV " << G4endl;
|
||||
}
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyGammaConversion::G4LowEnergyGammaConversion - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
// The following pointer is owned by G4DataHandler
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
crossSectionHandler->Initialise(0,1.0220*MeV,100.*GeV,400);
|
||||
meanFreePathTable = 0;
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / MeV << " MeV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// destructor
|
||||
|
||||
G4LowEnergyGammaConversion::~G4LowEnergyGammaConversion()
|
||||
{
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// methods.............................................................................
|
||||
void G4LowEnergyGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
|
||||
|
||||
BuildZVec();
|
||||
|
||||
// Build microscopic cross section tables for the Compton Scattering process
|
||||
BuildCrossSectionTable();
|
||||
|
||||
// Build mean free path table for the Compton Scattering process
|
||||
BuildMeanFreePathTable();
|
||||
delete meanFreePathTable;
|
||||
delete crossSectionHandler;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
void G4LowEnergyGammaConversion::BuildCrossSectionTable(){
|
||||
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
theCrossSectionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "pair/pp-cs-");
|
||||
|
||||
// theCrossSectionTable->insert(oneAtomCS);
|
||||
theCrossSectionTable->push_back(oneAtomCS);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
|
||||
void G4LowEnergyGammaConversion::BuildZVec(){
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
void G4LowEnergyGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
ZNumVec = new G4DataVector();
|
||||
for (G4int J=0 ; J < numOfMaterials; J++){
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ ){
|
||||
|
||||
G4double Zel = (*theElementVector)(iel)->GetZ();
|
||||
|
||||
if(ZNumVec->contains(Zel) == FALSE){
|
||||
ZNumVec->push_back(Zel);
|
||||
} else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "pair/pp-cs-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
|
||||
|
||||
//
|
||||
// The secondaries e+e- energies are sampled using the Bethe - Heitler
|
||||
G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
// The energies of the e+ e- secondaries are sampled using the Bethe - Heitler
|
||||
// cross sections with Coulomb correction. A modified version of the random
|
||||
// number techniques of Butcher & Messel is used (Nuc Phys 20(1960),15).
|
||||
//
|
||||
// GEANT4 internal units.
|
||||
//
|
||||
|
||||
// Note 1 : Effects due to the breakdown of the Born approximation at low
|
||||
// energy are ignored.
|
||||
// Note 2 : The differential cross section implicitly takes account of
|
||||
@@ -171,262 +136,216 @@ G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrac
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy = incidentPhoton->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
G4double epsil ;
|
||||
G4double epsil0 = electron_mass_c2 / GammaEnergy ;
|
||||
G4double epsilon ;
|
||||
G4double epsilon0 = electron_mass_c2 / photonEnergy ;
|
||||
|
||||
// do it fast if GammaEnergy < 2. MeV
|
||||
const G4double Egsmall=2.*MeV;
|
||||
if (GammaEnergy<Egsmall) { epsil = epsil0 + (0.5-epsil0)*G4UniformRand(); }
|
||||
|
||||
else{ // now comes the case with GammaEnergy >= 2. MeV
|
||||
// Do it fast if photon energy < 2. MeV
|
||||
if (photonEnergy < smallEnergy )
|
||||
{
|
||||
epsilon = epsilon0 + (0.5 - epsilon0) * G4UniformRand();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select randomly one element in the current material
|
||||
const G4Element* element = crossSectionHandler->SelectRandomElement(material,photonEnergy);
|
||||
|
||||
if (element == 0)
|
||||
{
|
||||
G4cout << "G4LowEnergyGammaConversion::PostStepDoIt - element = 0" << G4endl;
|
||||
}
|
||||
G4IonisParamElm* ionisation = element->GetIonisation();
|
||||
if (ionisation == 0)
|
||||
{
|
||||
G4cout << "G4LowEnergyGammaConversion::PostStepDoIt - ionisation = 0" << G4endl;
|
||||
}
|
||||
|
||||
// Extract Coulomb factor for this Element
|
||||
G4double fZ = 8. * (ionisation->GetlogZ3());
|
||||
if (photonEnergy > 50. * MeV) fZ += 8. * (element->GetfCoulomb());
|
||||
|
||||
// select randomly one element constituing the material
|
||||
G4Element* anElement = SelectRandomAtom(aDynamicGamma, aMaterial);
|
||||
|
||||
// Extract Coulomb factor for this Element
|
||||
G4double FZ = 8.*(anElement->GetIonisation()->GetlogZ3());
|
||||
if (GammaEnergy > 50.*MeV) FZ += 8.*(anElement->GetfCoulomb());
|
||||
|
||||
// limits of the screening variable
|
||||
G4double screenfac = 136.*epsil0/(anElement->GetIonisation()->GetZ3()) ;
|
||||
G4double screenmax = exp ((42.24 - FZ)/8.368) - 0.952 ;
|
||||
G4double screenmin = G4std::min(4.*screenfac,screenmax) ;
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double epsil1 = 0.5 - 0.5*sqrt(1. - screenmin/screenmax) ;
|
||||
G4double epsilmin = G4std::max(epsil0,epsil1) , epsilrange = 0.5 - epsilmin ;
|
||||
|
||||
//
|
||||
// sample the energy rate of the created electron (or positron)
|
||||
//
|
||||
//G4double epsil, screenvar, greject ;
|
||||
G4double screenvar, greject ;
|
||||
|
||||
G4double F10 = ScreenFunction1(screenmin) - FZ , F20 = ScreenFunction2(screenmin) - FZ;
|
||||
G4double NormF1 = G4std::max(F10*epsilrange*epsilrange,0.) , NormF2 = G4std::max(1.5*F20,0.);
|
||||
|
||||
do {
|
||||
if ( NormF1/(NormF1+NormF2) > G4UniformRand() ){
|
||||
|
||||
epsil = 0.5 - epsilrange*pow(G4UniformRand(), 1/3) ;
|
||||
screenvar = screenfac/(epsil*(1-epsil));
|
||||
greject = (ScreenFunction1(screenvar) - FZ)/F10 ;
|
||||
}
|
||||
else {
|
||||
epsil = epsilmin + epsilrange*G4UniformRand();
|
||||
screenvar = screenfac/(epsil*(1-epsil));
|
||||
greject = (ScreenFunction2(screenvar) - FZ)/F20 ;
|
||||
}
|
||||
// Limits of the screening variable
|
||||
G4double screenFactor = 136. * epsilon0 / (element->GetIonisation()->GetZ3()) ;
|
||||
G4double screenMax = exp ((42.24 - fZ)/8.368) - 0.952 ;
|
||||
G4double screenMin = G4std::min(4.*screenFactor,screenMax) ;
|
||||
|
||||
} while( greject < G4UniformRand() );
|
||||
|
||||
} // end of epsil sampling.........................
|
||||
// Limits of the energy sampling
|
||||
G4double epsilon1 = 0.5 - 0.5 * sqrt(1. - screenMin / screenMax) ;
|
||||
G4double epsilonMin = G4std::max(epsilon0,epsilon1);
|
||||
G4double epsilonRange = 0.5 - epsilonMin ;
|
||||
|
||||
// Sample the energy rate of the created electron (or positron)
|
||||
G4double screen;
|
||||
G4double gReject ;
|
||||
|
||||
G4double f10 = ScreenFunction1(screenMin) - fZ;
|
||||
G4double f20 = ScreenFunction2(screenMin) - fZ;
|
||||
G4double normF1 = G4std::max(f10 * epsilonRange * epsilonRange,0.);
|
||||
G4double normF2 = G4std::max(1.5 * f20,0.);
|
||||
|
||||
do {
|
||||
if (normF1 / (normF1 + normF2) > G4UniformRand() )
|
||||
{
|
||||
epsilon = 0.5 - epsilonRange * pow(G4UniformRand(), 0.3333) ;
|
||||
screen = screenFactor / (epsilon * (1. - epsilon));
|
||||
gReject = (ScreenFunction1(screen) - fZ) / f10 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilon = epsilonMin + epsilonRange * G4UniformRand();
|
||||
screen = screenFactor / (epsilon * (1 - epsilon));
|
||||
gReject = (ScreenFunction2(screen) - fZ) / f20 ;
|
||||
}
|
||||
} while ( gReject < G4UniformRand() );
|
||||
|
||||
} // End of epsilon sampling
|
||||
|
||||
//
|
||||
// fixe charges randomly
|
||||
//
|
||||
// Fix charges randomly
|
||||
|
||||
G4double ElectTotEnergy, PositTotEnergy;
|
||||
if (RandBit::shootBit()){
|
||||
G4double electronTotEnergy;
|
||||
G4double positronTotEnergy;
|
||||
|
||||
ElectTotEnergy = (1.-epsil)*GammaEnergy;
|
||||
PositTotEnergy = epsil*GammaEnergy;
|
||||
}
|
||||
else{
|
||||
|
||||
PositTotEnergy = (1.-epsil)*GammaEnergy;
|
||||
ElectTotEnergy = epsil*GammaEnergy;
|
||||
}
|
||||
if (RandBit::shootBit())
|
||||
{
|
||||
electronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
positronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
positronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
electronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
|
||||
//
|
||||
// scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
// universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev Mod Phys 49,421(1977))
|
||||
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev. Mod. Phys. 49, 421 (1977)
|
||||
|
||||
G4double u;
|
||||
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
|
||||
const G4double a1 = 0.625;
|
||||
G4double a2 = 3. * a1;
|
||||
// G4double d = 27. ;
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()){
|
||||
u = - log(G4UniformRand()*G4UniformRand())/a1 ;
|
||||
}
|
||||
// if (9. / (9. + d) > G4UniformRand())
|
||||
if (0.25 > G4UniformRand())
|
||||
{
|
||||
u = - log(G4UniformRand() * G4UniformRand()) / a1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
u = - log(G4UniformRand() * G4UniformRand()) / a2 ;
|
||||
}
|
||||
|
||||
else{
|
||||
u = - log(G4UniformRand()*G4UniformRand())/a2 ;
|
||||
}
|
||||
G4double theta = u * electron_mass_c2 / photonEnergy ;
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4double dirX = sin(theta) * cos(phi);
|
||||
G4double dirY = sin(theta) * sin(phi);
|
||||
G4double dirZ = cos(theta);
|
||||
|
||||
G4double Teta = u*electron_mass_c2/GammaEnergy ;
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sin(Teta)*cos(Phi) , diry = sin(Teta)*sin(Phi) , dirz = cos(Teta);
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
// Kinematics of the created pair:
|
||||
// the electron and positron are assumed to have a symetric angular
|
||||
// distribution with respect to the Z axis along the parent photon.
|
||||
// distribution with respect to the Z axis along the parent photon
|
||||
|
||||
G4double LocalEnerDeposit = 0. ;
|
||||
G4double localEnergyDeposit = 0. ;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2) ;
|
||||
G4double ElectKineEnergy = G4std::max(0.,ElectTotEnergy - electron_mass_c2) ;
|
||||
aParticleChange.SetNumberOfSecondaries(2.) ;
|
||||
G4double electronKineEnergy = G4std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// if (G4EnergyLossTables::GetRange(G4Electron::Electron(), ElectKineEnergy, aMaterial)
|
||||
// >= G4std::min(G4Electron::GetCuts(), aStep.GetPostStepPoint()->GetSafety()) ){
|
||||
if((G4EnergyLossTables::GetRange(G4Electron::Electron(),
|
||||
ElectKineEnergy,aMaterial)>aStep.GetPostStepPoint()->GetSafety())
|
||||
||
|
||||
(ElectKineEnergy >
|
||||
(G4Electron::Electron()->GetCutsInEnergy())[aMaterial->GetIndex()]))
|
||||
// Generate the electron only if with large enough range w.r.t. cuts and safety
|
||||
|
||||
{
|
||||
G4double safety = aStep.GetPostStepPoint()->GetSafety();
|
||||
|
||||
G4ThreeVector ElectDirection ( dirx, diry, dirz );
|
||||
ElectDirection.rotateUz(GammaDirection);
|
||||
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle (G4Electron::Electron(),ElectDirection, ElectKineEnergy);
|
||||
if (rangeTest->Escape(G4Electron::Electron(),material,electronKineEnergy,safety))
|
||||
{
|
||||
G4ThreeVector electronDirection ( dirX, dirY, dirZ );
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
aParticleChange.AddSecondary(particle1) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += electronKineEnergy ;
|
||||
}
|
||||
|
||||
aParticleChange.AddSecondary( aParticle1 ) ;
|
||||
}
|
||||
else{
|
||||
|
||||
LocalEnerDeposit += ElectKineEnergy ;
|
||||
}
|
||||
// The e+ is always created (even with kinetic energy = 0) for further annihilation
|
||||
G4double positronKineEnergy = G4std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// the e+ is always created (even with Ekine=0) for further annihilation.
|
||||
|
||||
G4double PositKineEnergy = G4std::max(0.,PositTotEnergy - electron_mass_c2) ;
|
||||
|
||||
if (G4EnergyLossTables::GetRange(G4Positron::Positron(),PositKineEnergy,aMaterial)
|
||||
< G4std::min(G4Positron::GetCuts(), aStep.GetPostStepPoint()->GetSafety()) ){
|
||||
|
||||
LocalEnerDeposit += PositKineEnergy ;
|
||||
PositKineEnergy = 0. ;
|
||||
}
|
||||
G4ThreeVector PositDirection ( -dirx, -diry, dirz );
|
||||
PositDirection.rotateUz(GammaDirection);
|
||||
// Is the local energy deposit correct, if the positron is always created?
|
||||
if (! (rangeTest->Escape(G4Positron::Positron(),material,positronKineEnergy,safety)))
|
||||
{
|
||||
localEnergyDeposit += positronKineEnergy ;
|
||||
positronKineEnergy = 0. ;
|
||||
}
|
||||
G4ThreeVector positronDirection(-dirX,-dirY,dirZ);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* aParticle2= new G4DynamicParticle (G4Positron::Positron(),
|
||||
PositDirection, PositKineEnergy);
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
aParticleChange.AddSecondary(particle2) ;
|
||||
|
||||
aParticleChange.AddSecondary( aParticle2 ) ;
|
||||
aParticleChange.SetLocalEnergyDeposit(localEnergyDeposit) ;
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit( LocalEnerDeposit ) ;
|
||||
|
||||
//
|
||||
// Kill the incident photon
|
||||
//
|
||||
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. ) ;
|
||||
aParticleChange.SetEnergyChange( 0. ) ;
|
||||
aParticleChange.SetStatusChange( fStopAndKill ) ;
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel > 15){
|
||||
G4cout<<"LE Gamma Conversion PostStepDoIt"<<G4endl;
|
||||
}
|
||||
#endif
|
||||
aParticleChange.SetMomentumChange(0.,0.,0.) ;
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill) ;
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
void G4LowEnergyGammaConversion::BuildMeanFreePathTable(){
|
||||
G4bool G4LowEnergyGammaConversion::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
|
||||
G4double G4LowEnergyGammaConversion::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
|
||||
// material
|
||||
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
G4Material* material;
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
// MeanFreePath
|
||||
G4double LowEdgeEnergy, Value;
|
||||
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
G4double G4LowEnergyGammaConversion::ScreenFunction1(G4double screenVariable)
|
||||
{
|
||||
// Compute the value of the screening function 3*phi1 - phi2
|
||||
|
||||
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
|
||||
G4double value;
|
||||
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, NumbBinTable);
|
||||
|
||||
material = (*theMaterialTable)(J);
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ ){
|
||||
//For each energy
|
||||
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
|
||||
const G4double BigPath= DBL_MAX;
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
|
||||
// For each element
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
|
||||
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
|
||||
|
||||
}
|
||||
|
||||
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
|
||||
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insertAt( J , ptrVector ) ;
|
||||
}
|
||||
}
|
||||
|
||||
G4Element* G4LowEnergyGammaConversion::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma, G4Material* aMaterial){
|
||||
|
||||
// select randomly 1 element within the material
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
if (NumberOfElements == 1) return (*theElementVector)(0);
|
||||
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
|
||||
G4double PartialSumSigma = 0.;
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
|
||||
|
||||
G4double crossSection;
|
||||
if (GammaEnergy < lowestEnergyLimit)
|
||||
crossSection = 0. ;
|
||||
else {
|
||||
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
|
||||
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(i)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
crossSection = util.DataLogInterpolation(GammaEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
|
||||
}
|
||||
|
||||
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
|
||||
if(rval <= PartialSumSigma) return ((*theElementVector)(i));
|
||||
}
|
||||
// G4cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
|
||||
// << "' has no elements" << G4endl;
|
||||
return (*theElementVector)(0);
|
||||
}
|
||||
|
||||
|
||||
if (screenVariable > 1.)
|
||||
value = 42.24 - 8.368 * log(screenVariable + 0.952);
|
||||
else
|
||||
value = 42.392 - screenVariable * (7.796 - 1.961 * screenVariable);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
G4double G4LowEnergyGammaConversion::ScreenFunction2(G4double screenVariable)
|
||||
{
|
||||
// Compute the value of the screening function 1.5*phi1 - 0.5*phi2
|
||||
|
||||
G4double value;
|
||||
|
||||
if (screenVariable > 1.)
|
||||
value = 42.24 - 8.368 * log(screenVariable + 0.952);
|
||||
else
|
||||
value = 41.405 - screenVariable * (5.828 - 0.8945 * screenVariable);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,17 +21,21 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyPhotoElectric.cc,v 1.31.2.2 2001/06/28 20:19:30 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// $Id: G4LowEnergyPhotoElectric.cc,v 1.42 2001/11/07 21:31:16 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// ------------ G4LowEnergyPhotoelctric: low energy modifications --------
|
||||
// by Alessandra Forti, October 1998
|
||||
// **************************************************************
|
||||
// History:
|
||||
// --------
|
||||
// October 1998 - low energy modifications by Alessandra Forti
|
||||
// Added Livermore data table construction methods A. Forti
|
||||
// Modified BuildMeanFreePath to read new data tables A. Forti
|
||||
// Added EnergySampling method A. Forti
|
||||
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
|
||||
// Added SelectRandomAtom A. Forti
|
||||
// Added map of the elements A. Forti
|
||||
// 10.04.2000 VL
|
||||
// - Correcting Fluorescence transition probabilities in order to take into account
|
||||
// non-radiative transitions. No Auger electron simulated yet: energy is locally deposited.
|
||||
@@ -41,707 +45,264 @@
|
||||
// . no Fluorescence was simulated when the photo-electron energy
|
||||
// was below production threshold.
|
||||
//
|
||||
// Added Livermore data table construction methods A. Forti
|
||||
// Modified BuildMeanFreePath to read new data tables A. Forti
|
||||
// Added EnergySampling method A. Forti
|
||||
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
|
||||
// Added SelectRandomAtom A. Forti
|
||||
// Added map of the elements A. Forti
|
||||
// 07-09-99, if no e- emitted: edep=photon energy, mma
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
// 12.08.2001 MGP Revised according to a design iteration
|
||||
// 16.09.2001 E. Guardincerri Added fluorescence generation
|
||||
// 06.10.2001 MGP Added protection to avoid negative electron energies
|
||||
// when binding energy of selected shell > photon energy
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// This Class Header
|
||||
#include "G4LowEnergyPhotoElectric.hh"
|
||||
|
||||
// Collaborating Class Headers
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ForceCondition.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4VCrossSectionHandler.hh"
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
|
||||
typedef G4std::vector<G4DynamicParticle*> G4ParticleVector;
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
// ..
|
||||
|
||||
// constructor
|
||||
|
||||
G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName), // initialization
|
||||
lowestEnergyLimit (250*eV),
|
||||
highestEnergyLimit(100*GeV),
|
||||
NumbBinTable(200),
|
||||
CutForLowEnergySecondaryPhotons(0.),
|
||||
theCrossSectionTable(0),
|
||||
theMeanFreePathTable(0),
|
||||
allAtomShellCrossSec(0),
|
||||
theFluorTransitionTable(0),
|
||||
theBindingEnergyTable(0),
|
||||
ZNumVec(0),
|
||||
ZNumVecFluor(0),
|
||||
MeanFreePath(0.)
|
||||
: G4VDiscreteProcess(processName), lowEnergyLimit(250*eV), highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV),
|
||||
cutForLowEnergySecondaryPhotons(0.)
|
||||
{
|
||||
if (verboseLevel>0) {
|
||||
G4cout << GetProcessName() << " is created "<< G4endl;
|
||||
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
|
||||
G4cout << "highestEnergy: " << highestEnergyLimit/MeV << "MeV " << G4endl;
|
||||
}
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
shellCrossSectionHandler = new G4CrossSectionHandler();
|
||||
meanFreePathTable = 0;
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
// destructor
|
||||
|
||||
G4LowEnergyPhotoElectric::~G4LowEnergyPhotoElectric()
|
||||
{
|
||||
if (theCrossSectionTable) {
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
if (theBindingEnergyTable) {
|
||||
// theBindingEnergyTable->clearAndDestroy();
|
||||
theBindingEnergyTable->clear();
|
||||
delete theBindingEnergyTable;
|
||||
}
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
// theMeanFreePathTable->clearAndDestroy();
|
||||
theMeanFreePathTable->clear();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
// ClearAndDestroy of this tables is called in their destructors
|
||||
if (theFluorTransitionTable) {
|
||||
delete theFluorTransitionTable;
|
||||
}
|
||||
|
||||
if (allAtomShellCrossSec) {
|
||||
|
||||
delete allAtomShellCrossSec;
|
||||
}
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
if(ZNumVecFluor){
|
||||
ZNumVecFluor->erase(ZNumVecFluor->begin(),ZNumVecFluor->end());
|
||||
delete ZNumVecFluor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
void G4LowEnergyPhotoElectric::SetCutForLowEnSecPhotons(G4double cut){
|
||||
|
||||
CutForLowEnergySecondaryPhotons = cut;
|
||||
delete crossSectionHandler;
|
||||
delete shellCrossSectionHandler;
|
||||
delete meanFreePathTable;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
void G4LowEnergyPhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& PhotonType)
|
||||
|
||||
// Build microscopic cross section table and mean free path table
|
||||
void G4LowEnergyPhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
BuildZVec();
|
||||
|
||||
BuildCrossSectionTable();
|
||||
|
||||
BuildShellCrossSectionTable();
|
||||
|
||||
BuildMeanFreePathTable();
|
||||
|
||||
BuildBindingEnergyTable();
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
BuildFluorTransitionTable();
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "phot/pe-cs-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
shellCrossSectionHandler->Clear();
|
||||
G4String shellCrossSectionFile = "phot/pe-ss-cs-";
|
||||
shellCrossSectionHandler->LoadShellData(shellCrossSectionFile);
|
||||
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
// CONSTRUCT THE CROSS SECTION TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL DATA
|
||||
void G4LowEnergyPhotoElectric::BuildCrossSectionTable(){
|
||||
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
theCrossSectionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "phot/pe-cs-");
|
||||
|
||||
// theCrossSectionTable->insert(oneAtomCS);
|
||||
theCrossSectionTable->push_back(oneAtomCS);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
// CONSTRUCT THE SUBSHELL CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL DATA
|
||||
void G4LowEnergyPhotoElectric::BuildShellCrossSectionTable(){
|
||||
|
||||
if (allAtomShellCrossSec) {
|
||||
|
||||
delete allAtomShellCrossSec;
|
||||
}
|
||||
|
||||
allAtomShellCrossSec = new allAtomTable();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
oneAtomTable* oneAtomShellCS = util.BuildSecondLevelTables(AtomInd, dataNum, "phot/pe-ss-cs-");
|
||||
|
||||
// allAtomShellCrossSec->insert(oneAtomShellCS);
|
||||
allAtomShellCrossSec->push_back(oneAtomShellCS);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
// CONSTRUCT THE BE TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EADL DATA
|
||||
void G4LowEnergyPhotoElectric::BuildBindingEnergyTable(){
|
||||
|
||||
if (theBindingEnergyTable) {
|
||||
|
||||
delete theBindingEnergyTable;
|
||||
}
|
||||
|
||||
G4int dataNum = 2;
|
||||
theBindingEnergyTable = util.BuildSecondLevelTables(0,dataNum,"fluor/binding");
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
// CONSTRUCT THE FTP TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EADL DATA
|
||||
void G4LowEnergyPhotoElectric::BuildFluorTransitionTable(){
|
||||
|
||||
if (theFluorTransitionTable) {
|
||||
|
||||
delete theFluorTransitionTable;
|
||||
}
|
||||
|
||||
theFluorTransitionTable = new allAtomTable();
|
||||
ZNumVecFluor = new G4DataVector(*ZNumVec);
|
||||
G4int dataNum = 3;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
if(AtomInd > 5){
|
||||
|
||||
oneAtomTable* oneAtomShellFL = util.BuildSecondLevelTables(AtomInd, dataNum, "fluor/fl-tr-pr-");
|
||||
// theFluorTransitionTable->insert(oneAtomShellFL);
|
||||
theFluorTransitionTable->push_back(oneAtomShellFL);
|
||||
}
|
||||
else{
|
||||
ZNumVecFluor->remove(AtomInd);
|
||||
}
|
||||
}//end for on atoms
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
//
|
||||
// vector mapping the elements of the material table
|
||||
//
|
||||
void G4LowEnergyPhotoElectric::BuildZVec(){
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
ZNumVec = new G4DataVector();
|
||||
for (G4int J=0 ; J < numOfMaterials; J++){
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ ){
|
||||
|
||||
G4double Zel = (*theElementVector)(iel)->GetZ();
|
||||
|
||||
if(ZNumVec->contains(Zel) == FALSE){
|
||||
ZNumVec->push_back(Zel);
|
||||
} else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
// Compute total cross section from subshell integrated cross section: needed for
|
||||
// selection of the first subshell ionized.
|
||||
|
||||
G4double G4LowEnergyPhotoElectric::ComputeCrossSection(const G4double AtomIndex,
|
||||
const G4double IncEnergy){
|
||||
// calculates the microscopic cross section from subshell cross sections
|
||||
//(it is called for elements , AtomicNumber = Z )
|
||||
|
||||
G4double TotalCrossSection(0.);
|
||||
|
||||
const oneAtomTable* oneAtomCS
|
||||
= (*allAtomShellCrossSec)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
for(size_t ind = 0; ind < oneAtomCS->size(); ind++){
|
||||
|
||||
G4double crossSec = 0;
|
||||
G4DataVector* EnergyVector = (*(*oneAtomCS)[ind])[0];
|
||||
G4DataVector* CrossSecVector = (*(*oneAtomCS)[ind])[1];
|
||||
|
||||
if(IncEnergy < (*EnergyVector)[1]){ // First element is the shell number
|
||||
|
||||
crossSec = 0;
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector))*barn;
|
||||
|
||||
}
|
||||
|
||||
TotalCrossSection += crossSec;
|
||||
}
|
||||
|
||||
return TotalCrossSection ;
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
void G4LowEnergyPhotoElectric::BuildMeanFreePathTable(){
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable; }
|
||||
|
||||
// material
|
||||
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
G4Material* material;
|
||||
|
||||
// MeanFreePath
|
||||
G4double LowEdgeEnergy, Value;
|
||||
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
|
||||
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
|
||||
|
||||
//create physics vector then fill it ....
|
||||
// WARNING: Lower limit of total cross sections in the data is the binding energy
|
||||
// of the relative subshell. MeanFreePath table require a common lowest limit.
|
||||
// This lowestEnergyLimit is at the moment fixed at 250 ev.
|
||||
|
||||
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, NumbBinTable);
|
||||
|
||||
material = (*theMaterialTable)(J);
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ ){
|
||||
//For each energy
|
||||
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
|
||||
G4double SIGMA = 0;
|
||||
|
||||
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
|
||||
// For each element
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy, (*(*oneAtomCS)[0]), (*(*oneAtomCS)[1]))*barn;
|
||||
|
||||
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
|
||||
}
|
||||
|
||||
Value = SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX ;
|
||||
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insertAt( J , ptrVector ) ;
|
||||
}
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
|
||||
|
||||
// Fluorescence (as reported by stepanek):
|
||||
// J. Stepanek " A program to determine the radiation spectra due to a single atomic
|
||||
G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
// Fluorescence generated according to:
|
||||
// J. Stepanek ,"A program to determine the radiation spectra due to a single atomic
|
||||
// subshell ionisation by a particle or due to deexcitation or decay of radionuclides",
|
||||
// Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
|
||||
//
|
||||
// incoming particle initialization
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
const G4DynamicParticle* aDynamicPhoton = aTrack.GetDynamicParticle();
|
||||
const G4double PhotonEnergy = aDynamicPhoton->GetKineticEnergy();
|
||||
if(PhotonEnergy <= lowestEnergyLimit){
|
||||
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(PhotonEnergy);
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
const G4ParticleMomentum PhotonDirection = aDynamicPhoton->GetMomentumDirection();
|
||||
|
||||
// select randomly one element constituing the material.
|
||||
G4Element* anElement = SelectRandomAtom(aDynamicPhoton, aMaterial);
|
||||
|
||||
// PAY ATTENTION TO THE MEANING OF THIS NUMBER!!! SelectRandomAtom requires to use AtomNum
|
||||
// the BindingEnergyTable requires AtomNum-1
|
||||
G4int AtomNum = (G4int) anElement->GetZ();
|
||||
|
||||
// First Ionised subshell is chosen basing on subshell integrated cross section EPDL97
|
||||
// using the partial sum method.
|
||||
// Select the subshell WARNING!!!!: it returns the subshell index in the table.
|
||||
|
||||
G4int subShellIndex = SelectRandomShell(AtomNum, PhotonEnergy);
|
||||
|
||||
G4FirstLevel* theBindEnVec = (*theBindingEnergyTable)[AtomNum-1];
|
||||
G4int thePrimaryShell = (G4int) (*(*theBindEnVec)[0])[subShellIndex];
|
||||
G4double BindingEn = ((*(*theBindEnVec)[1])[subShellIndex])*MeV;
|
||||
|
||||
if(thePrimShVec.size() != 0){
|
||||
|
||||
thePrimShVec.clear();
|
||||
}
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy = incidentPhoton->GetKineticEnergy();
|
||||
if (photonEnergy <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(photonEnergy);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element in the current material
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy);
|
||||
|
||||
thePrimShVec.push_back(thePrimaryShell);
|
||||
// Select the ionised shell in the current atom according to shell cross sections
|
||||
size_t shellIndex = shellCrossSectionHandler->SelectRandomShell(Z,photonEnergy);
|
||||
|
||||
// Retrieve the corresponding identifier and binding energy of the selected shell
|
||||
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
|
||||
const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
|
||||
G4double bindingEnergy = shell->BindingEnergy();
|
||||
G4int shellId = shell->ShellId();
|
||||
|
||||
// Create lists of pointers to DynamicParticles (photons and electrons)
|
||||
G4ParticleVector photvec;
|
||||
// G4int photInd = 0;
|
||||
G4ParticleVector elecvec;
|
||||
// G4int elecInd = 0;
|
||||
// (Is the electron vector necessary? To be checked)
|
||||
G4std::vector<G4DynamicParticle*>* photonVector = 0;
|
||||
G4std::vector<G4DynamicParticle*> electronVector;
|
||||
|
||||
// primary outcoming electron
|
||||
G4double ElecKineEnergy = (PhotonEnergy - BindingEn);
|
||||
G4double energyDeposit = bindingEnergy;
|
||||
|
||||
G4double theEnergyDeposit = BindingEn;
|
||||
// Primary outcoming electron
|
||||
G4double eKineticEnergy = photonEnergy - bindingEnergy;
|
||||
|
||||
if (G4EnergyLossTables::GetRange(G4Electron::Electron(),ElecKineEnergy,aMaterial)
|
||||
>= G4std::min(G4Electron::GetCuts(), aStep.GetPostStepPoint()->GetSafety())){
|
||||
// There may be cases where the binding energy of the selected shell is > photon energy
|
||||
// In such cases do not generate secondaries
|
||||
if (eKineticEnergy > 0.)
|
||||
{
|
||||
// Generate the electron only if with large enough range w.r.t. cuts and safety
|
||||
G4double safety = aStep.GetPostStepPoint()->GetSafety();
|
||||
|
||||
// the electron is created in the direction of the incident photon ...
|
||||
|
||||
G4DynamicParticle* aElectron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
PhotonDirection, ElecKineEnergy) ;
|
||||
elecvec.push_back(aElectron);
|
||||
} // END OF CUTS
|
||||
if (rangeTest->Escape(G4Electron::Electron(),material,eKineticEnergy,safety))
|
||||
{
|
||||
// The electron is created in the direction of the incident photon ...
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
photonDirection,
|
||||
eKineticEnergy);
|
||||
electronVector.push_back(electron);
|
||||
}
|
||||
else
|
||||
{
|
||||
energyDeposit += eKineticEnergy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
energyDeposit = photonEnergy;
|
||||
}
|
||||
|
||||
|
||||
G4int nElectrons = electronVector.size();
|
||||
size_t nTotPhotons = 0;
|
||||
G4int nPhotons=0;
|
||||
|
||||
// Generation of fluorescence
|
||||
// Data in EADL are available only for Z > 5
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// shell binding energy > photon energy
|
||||
if (Z > 5 && eKineticEnergy > 0.)
|
||||
{
|
||||
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
|
||||
nTotPhotons = photonVector->size();
|
||||
for (size_t k=0; k<nTotPhotons; k++)
|
||||
{
|
||||
G4DynamicParticle* aPhoton = (*photonVector)[k];
|
||||
if (aPhoton == 0)
|
||||
{
|
||||
delete aPhoton;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double itsKineticEnergy = aPhoton->GetKineticEnergy();
|
||||
G4double eDepositTmp = energyDeposit - itsKineticEnergy;
|
||||
if (itsKineticEnergy >= cutForLowEnergySecondaryPhotons &&
|
||||
eDepositTmp > 0.)
|
||||
{
|
||||
nPhotons++;
|
||||
// Local energy deposit is given as the sum of the
|
||||
// energies of incident photons minus the energies
|
||||
// of the outcoming fluorescence photons
|
||||
energyDeposit -= itsKineticEnergy;
|
||||
|
||||
}
|
||||
else
|
||||
{ delete aPhoton; }
|
||||
}
|
||||
}
|
||||
}
|
||||
G4int nSecondaries = nElectrons + nPhotons;
|
||||
|
||||
else{
|
||||
theEnergyDeposit += ElecKineEnergy;
|
||||
}
|
||||
|
||||
// load the transition probability table for the element
|
||||
// theTable[i][j][k]
|
||||
// i = subshell, j = type of information (second shell, transition energy ,
|
||||
// transition probability), k = previous vectors.
|
||||
|
||||
if(AtomNum > 5){
|
||||
|
||||
G4bool ThereAreShells = TRUE;
|
||||
G4int AtomInd = ZNumVecFluor->index(AtomNum);
|
||||
oneAtomTable* oneAtomFluorTrans = (*theFluorTransitionTable)[AtomInd];
|
||||
|
||||
while(ThereAreShells == TRUE){
|
||||
|
||||
// Select the second transition from another subshell
|
||||
// fluorPar[0] = SubShell
|
||||
// fluorPar[1] = Sec SubShell (if there is),
|
||||
// fluorPar[2] = Transition Probability
|
||||
// the same for augerPar
|
||||
|
||||
G4double fluorPar[3] = {0};
|
||||
ThereAreShells = SelectRandomTransition(thePrimaryShell,
|
||||
fluorPar,
|
||||
oneAtomFluorTrans);
|
||||
|
||||
// Daugther dynamic particle
|
||||
G4DynamicParticle* newPart;
|
||||
|
||||
// Direction of the outcoming particle isotropic selection
|
||||
G4double newcosTh = 1-2*G4UniformRand();
|
||||
G4double newsinTh = sqrt(1-newcosTh*newcosTh);
|
||||
G4double newPhi = twopi*G4UniformRand();
|
||||
|
||||
G4double dirx, diry, dirz;
|
||||
dirz = newcosTh;
|
||||
diry = newsinTh*cos(newPhi);
|
||||
dirx = newsinTh*sin(newPhi);
|
||||
G4ThreeVector newPartDirection(dirx, diry, dirz);
|
||||
/////newPartDirection.rotateUz(PhotonDirection);
|
||||
|
||||
if(ThereAreShells != FALSE){
|
||||
|
||||
thePrimaryShell = (G4int) fluorPar[0];
|
||||
|
||||
if(fluorPar[2]*MeV >= CutForLowEnergySecondaryPhotons){
|
||||
|
||||
theEnergyDeposit -= fluorPar[2]*MeV;
|
||||
|
||||
newPart = new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
newPartDirection,
|
||||
fluorPar[2]*MeV);
|
||||
// photvec.append(newPart);
|
||||
photvec.push_back(newPart);
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
/////Energy deposition vl
|
||||
////=================NEW================vl
|
||||
|
||||
/*
|
||||
G4int k = 0;
|
||||
while(thePrimaryShell != (*(*theBindEnVec)[0])[k]) k++;
|
||||
|
||||
G4double lastTransEnergy = ((*(*theBindEnVec)[1])[k])*MeV;
|
||||
thePrimaryShell = (G4int) fluorPar[0];
|
||||
|
||||
if(lastTransEnergy >= CutForLowEnergySecondaryPhotons){
|
||||
|
||||
theEnergyDeposit -= lastTransEnergy;
|
||||
|
||||
newPart = new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
newPartDirection,
|
||||
lastTransEnergy) ;
|
||||
photvec.push_back(newPart);
|
||||
|
||||
}
|
||||
thePrimShVec.insert(thePrimaryShell);
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
} //END OF THE CHECK ON ATOMIC NUMBER
|
||||
|
||||
G4int numOfElec = elecvec.size();
|
||||
G4int numOfPhot = photvec.size();
|
||||
G4int numOfDau = numOfElec + numOfPhot;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(numOfDau);
|
||||
G4int l = 0;
|
||||
for( l = 0; l<numOfElec; l++ ){
|
||||
|
||||
aParticleChange.AddSecondary(elecvec[l]);
|
||||
aParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
|
||||
G4int l = 0;
|
||||
for ( l = 0; l<nElectrons; l++ )
|
||||
{
|
||||
aParticleChange.AddSecondary(electronVector[l]);
|
||||
}
|
||||
|
||||
for(l = 0; l < numOfPhot; l++) {
|
||||
|
||||
aParticleChange.AddSecondary(photvec[l]);
|
||||
for (l = 0; l < nPhotons; l++)
|
||||
{
|
||||
aParticleChange.AddSecondary((*photonVector)[l]);
|
||||
}
|
||||
|
||||
photvec.clear();
|
||||
elecvec.clear();
|
||||
|
||||
if(theEnergyDeposit < 0){
|
||||
|
||||
theEnergyDeposit = 0;
|
||||
|
||||
delete photonVector;
|
||||
|
||||
if (energyDeposit < 0)
|
||||
{
|
||||
G4cout << "WARNING - "
|
||||
<< "G4LowEnergyPhotoElectric::PostStepDoIt - Negative energy deposit"
|
||||
<< G4endl;
|
||||
energyDeposit = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Kill the incident photon
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. );
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
|
||||
if (theEnergyDeposit < 0) theEnergyDeposit = 0;
|
||||
aParticleChange.SetLocalEnergyDeposit(theEnergyDeposit);
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(energyDeposit);
|
||||
aParticleChange.SetStatusChange( fStopAndKill );
|
||||
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
G4int G4LowEnergyPhotoElectric::SelectRandomShell(const G4int AtomIndex,
|
||||
const G4double IncEnergy)
|
||||
{
|
||||
G4double partialSum = 0;
|
||||
G4double totalSum = ComputeCrossSection(AtomIndex,IncEnergy);
|
||||
|
||||
G4double rval = totalSum*G4UniformRand();
|
||||
const oneAtomTable* oneAtomCS
|
||||
= (*allAtomShellCrossSec)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
for(size_t ind = 0; ind < oneAtomCS->size(); ind++){
|
||||
|
||||
G4double crossSec;
|
||||
G4DataVector* EnergyVector = (*(*oneAtomCS)[ind])[0];
|
||||
G4DataVector* CrossSecVector = (*(*oneAtomCS)[ind])[1];
|
||||
if(IncEnergy < (*EnergyVector)[0]){ //First element is the shell number
|
||||
|
||||
crossSec = 0;
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector))*barn;
|
||||
|
||||
}
|
||||
|
||||
partialSum += crossSec;
|
||||
|
||||
if(rval <= partialSum) return ind;
|
||||
}
|
||||
|
||||
G4Exception("LEPhotoElectric: Cannot select a shell");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ..
|
||||
|
||||
G4Element*
|
||||
G4LowEnergyPhotoElectric::SelectRandomAtom(const G4DynamicParticle* aDynamicPhoton,
|
||||
G4Material* aMaterial)
|
||||
G4bool G4LowEnergyPhotoElectric::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
// select randomly 1 element within the material
|
||||
G4double GammaEnergy = aDynamicPhoton->GetKineticEnergy();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
if (NumberOfElements == 1) return (*theElementVector)(0);
|
||||
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
|
||||
G4double PartialSumSigma = 0. ;
|
||||
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
|
||||
|
||||
G4double crossSection;
|
||||
if (GammaEnergy < lowestEnergyLimit)
|
||||
|
||||
crossSection = 0. ;
|
||||
|
||||
else {
|
||||
|
||||
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
|
||||
|
||||
G4int AtomIndex = (G4int) (*theElementVector)(i)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
crossSection = util.DataLogInterpolation(GammaEnergy, (*(*oneAtomCS)[0]), (*(*oneAtomCS)[1]))*barn;
|
||||
}
|
||||
|
||||
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
|
||||
|
||||
if (rval <= PartialSumSigma) return ((*theElementVector)(i));
|
||||
|
||||
}
|
||||
return (*theElementVector)(0);
|
||||
}
|
||||
// ..
|
||||
|
||||
//
|
||||
// Select a random transition with the transition probabilities and the partial sum
|
||||
// method using EADL data (A. Forti)
|
||||
//
|
||||
|
||||
G4bool G4LowEnergyPhotoElectric::SelectRandomTransition(G4int thePrimShell,
|
||||
G4double* TransParam,
|
||||
const oneAtomTable* TransitionTable){
|
||||
|
||||
G4int SubShellCol = 0, ProbCol = 1, EnergyCol = 2;
|
||||
// transitionTable contains all the transition probabilities of one atom:
|
||||
// loop on subshell is inside the method.
|
||||
|
||||
// when the last subshell is reached CollIsFull becomes FALSE.
|
||||
G4bool ColIsFull = FALSE;
|
||||
G4int ShellNum = 0;
|
||||
// G4double TotalSum = 0;
|
||||
G4int maxNumOfShells = TransitionTable->size()-1;
|
||||
|
||||
if(thePrimShell <= 0) {
|
||||
G4cerr<<"*** Unvalid Primary shell: "<<thePrimShell<<G4endl;
|
||||
return FALSE;
|
||||
}
|
||||
if(thePrimShell <= (*(*(*TransitionTable)[maxNumOfShells])[0])[0]){
|
||||
|
||||
while(thePrimShell != (*(*(*TransitionTable)[ShellNum])[0])[0]){
|
||||
|
||||
if(ShellNum == maxNumOfShells){
|
||||
break;
|
||||
}
|
||||
|
||||
ShellNum++;
|
||||
}
|
||||
|
||||
// TransProb is the index of the loop and of the table of transition. it starts from 1
|
||||
// because the first element of the data table is the primary shell id number and not a
|
||||
// transition probability: it must not be added to TotalSum.
|
||||
|
||||
G4int TransProb = 1;
|
||||
|
||||
// Include non-radiative transitions (vl):
|
||||
//// for(TransProb = 1; TransProb < (*(*TransitionTable)[ShellNum])[ProbCol]->length(); TransProb++){
|
||||
//// TotalSum += (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
|
||||
//// }
|
||||
////G4double PartialProb = G4UniformRand()*TotalSum;
|
||||
////
|
||||
G4double PartialProb = G4UniformRand();
|
||||
|
||||
|
||||
//vl.
|
||||
|
||||
|
||||
G4double PartSum = 0;
|
||||
|
||||
TransProb = 1;
|
||||
G4int trSize = (*(*TransitionTable)[ShellNum])[ProbCol]->size();
|
||||
while(TransProb < trSize){
|
||||
|
||||
PartSum += (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
|
||||
|
||||
if(PartialProb <= PartSum){
|
||||
|
||||
TransParam[0] = (*(*(*TransitionTable)[ShellNum])[SubShellCol])[TransProb];
|
||||
TransParam[1] = (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
|
||||
TransParam[2] = (*(*(*TransitionTable)[ShellNum])[EnergyCol])[TransProb];
|
||||
ColIsFull = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
TransProb++;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
ColIsFull = FALSE;
|
||||
}
|
||||
|
||||
return ColIsFull;
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
// ..
|
||||
G4double G4LowEnergyPhotoElectric::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit)
|
||||
meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
void G4LowEnergyPhotoElectric::SetCutForLowEnSecPhotons(G4double cut)
|
||||
{
|
||||
cutForLowEnergySecondaryPhotons = cut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.5.2.2 2001/06/28 20:19:30 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.11 2001/11/07 21:31:16 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -38,6 +38,8 @@
|
||||
// Temporary protection to avoid crash in the case
|
||||
// of polarisation || incident photon direction
|
||||
//
|
||||
// 17 October 2001 - F.Longo - Revised according to a design iteration
|
||||
//
|
||||
// ************************************************************
|
||||
//
|
||||
// Corrections by Rui Curado da Silva (2000)
|
||||
@@ -49,257 +51,88 @@
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4LowEnergyPolarizedCompton.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4SecondLevel.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ForceCondition.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4VCrossSectionHandler.hh"
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
// constructor
|
||||
|
||||
G4LowEnergyPolarizedCompton::G4LowEnergyPolarizedCompton(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
theCrossSectionTable(0),
|
||||
theScatteringFunctionTable(0),
|
||||
theMeanFreePathTable(0),
|
||||
ZNumVec(0),
|
||||
lowestEnergyLimit (250*eV), // initialization
|
||||
highestEnergyLimit(100*GeV),
|
||||
numbBinTable(200),
|
||||
meanFreePath(0)
|
||||
lowEnergyLimit (250*eV), // initialization
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
{
|
||||
if (verboseLevel>0) {
|
||||
G4cout << GetProcessName() << " is created "<< G4endl;
|
||||
G4cout << "LowestEnergy: " << lowestEnergyLimit/keV << "keV ";
|
||||
G4cout << "HighestEnergy: " << highestEnergyLimit/TeV << "TeV " << G4endl;
|
||||
}
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyPolarizedCompton::G4LowEnergyPolarizedCompton - energy outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler;
|
||||
|
||||
|
||||
G4VDataSetAlgorithm* scatterInterpolation = new G4LogLogInterpolation;
|
||||
G4String scatterFile = "comp/ce-sf-";
|
||||
scatterFunctionData = new
|
||||
G4CompositeEMDataSet(scatterFile,scatterInterpolation,1.,1.);
|
||||
|
||||
meanFreePathTable = 0;
|
||||
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// destructor
|
||||
|
||||
|
||||
G4LowEnergyPolarizedCompton::~G4LowEnergyPolarizedCompton()
|
||||
{
|
||||
if (theCrossSectionTable) {
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
if (theScatteringFunctionTable) {
|
||||
delete theScatteringFunctionTable;
|
||||
}
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
delete meanFreePathTable;
|
||||
delete crossSectionHandler;
|
||||
delete scatterFunctionData;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
void G4LowEnergyPolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
|
||||
|
||||
BuildZVec();
|
||||
|
||||
// Build microscopic cross section table and mean free path table
|
||||
BuildCrossSectionTable();
|
||||
|
||||
// Build mean free path table for the Compton Scattering process
|
||||
BuildMeanFreePathTable();
|
||||
|
||||
// build the scattering function table
|
||||
BuildScatteringFunctionTable();
|
||||
|
||||
}
|
||||
void G4LowEnergyPolarizedCompton::BuildCrossSectionTable(){
|
||||
|
||||
// BUILD THE CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
|
||||
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
void G4LowEnergyPolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
theCrossSectionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t tableInd = 0; tableInd < ZNumVec->size(); tableInd++){
|
||||
|
||||
G4int atomInd = (G4int) (*ZNumVec)[tableInd];
|
||||
|
||||
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(atomInd, dataNum, "comp/ce-cs-");
|
||||
|
||||
// theCrossSectionTable->insert(oneAtomCS);
|
||||
theCrossSectionTable->push_back(oneAtomCS);
|
||||
|
||||
}//end for on atoms
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "comp/ce-cs-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
void G4LowEnergyPolarizedCompton::BuildScatteringFunctionTable(){
|
||||
|
||||
// BUILD THE SF TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
|
||||
|
||||
if (theScatteringFunctionTable) {
|
||||
|
||||
delete theScatteringFunctionTable;
|
||||
}
|
||||
|
||||
theScatteringFunctionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t tableInd = 0; tableInd < ZNumVec->size(); tableInd++){
|
||||
|
||||
G4int atomInd = (G4int) (*ZNumVec)[tableInd];
|
||||
|
||||
G4FirstLevel* oneAtomSF = util.BuildFirstLevelTables(atomInd, dataNum, "comp/ce-sf-");
|
||||
|
||||
// theScatteringFunctionTable->insert(oneAtomSF);
|
||||
theScatteringFunctionTable->push_back(oneAtomSF);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
|
||||
|
||||
void G4LowEnergyPolarizedCompton::BuildZVec(){
|
||||
|
||||
// vector mapping the elements in the material table
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
ZNumVec = new G4DataVector();
|
||||
for (G4int J=0 ; J < numOfMaterials; J++){
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int numberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
for (G4int iel=0; iel<numberOfElements; iel++ ){
|
||||
|
||||
G4double Zel = (*theElementVector)(iel)->GetZ();
|
||||
|
||||
if(!(ZNumVec->contains(Zel))){
|
||||
ZNumVec->push_back(Zel);
|
||||
} else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4LowEnergyPolarizedCompton::BuildMeanFreePathTable(){
|
||||
|
||||
// used log-log interpolation instead of linear interpolation to build the MFP
|
||||
// as reported in the stepanek paper
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
|
||||
|
||||
// material
|
||||
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
G4Material* material;
|
||||
|
||||
// MeanFreePath
|
||||
G4double lowEdgeEnergy, value;
|
||||
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
|
||||
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
|
||||
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, numbBinTable);
|
||||
|
||||
material = (*theMaterialTable)(J);
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
|
||||
for ( G4int i = 0 ; i < numbBinTable ; i++ ){
|
||||
//For each energy
|
||||
|
||||
lowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
|
||||
const G4double bigPath = DBL_MAX;
|
||||
G4double sigma = 0. ;
|
||||
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
|
||||
|
||||
G4int atomIndex = (G4int) (*theElementVector)(k)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(atomIndex)];
|
||||
|
||||
G4double interCrsSec = util.DataLogInterpolation(lowEdgeEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
sigma += theAtomNumDensityVector[k]*interCrsSec;
|
||||
}
|
||||
|
||||
value = sigma<=0.0 ? bigPath : 1./sigma ;
|
||||
ptrVector->PutValue( i , value ) ;
|
||||
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insertAt( J , ptrVector );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4Element* G4LowEnergyPolarizedCompton::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma,
|
||||
G4Material* aMaterial){
|
||||
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
|
||||
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
|
||||
|
||||
|
||||
// select randomly 1 element within the material
|
||||
G4double gammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
|
||||
if (NumberOfElements == 1) return (*theElementVector)(0);
|
||||
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
|
||||
G4double partialSumSigma = 0.;
|
||||
|
||||
G4double rval = 0;
|
||||
rval = G4UniformRand()/meanFreePath;
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
|
||||
|
||||
G4double crossSection;
|
||||
if (gammaEnergy < lowestEnergyLimit)
|
||||
crossSection = 0. ;
|
||||
else {
|
||||
if (gammaEnergy > highestEnergyLimit) gammaEnergy = 0.99*highestEnergyLimit ;
|
||||
|
||||
G4int atomIndex = (G4int) (*theElementVector)(i)->GetZ();
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(atomIndex)];
|
||||
|
||||
crossSection = util.DataLogInterpolation(gammaEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
}
|
||||
|
||||
partialSumSigma += theAtomNumDensityVector[i] * crossSection;
|
||||
if(rval <= partialSumSigma) return ((*theElementVector)(i));
|
||||
}
|
||||
|
||||
return (*theElementVector)(0);
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
@@ -312,261 +145,211 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
// Dynamic particle quantities
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double gammaEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
G4double polarisation = gammaPolarization0.mag();
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double gammaEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
G4ThreeVector gammaPolarization0 = incidentPhoton->GetPolarization();
|
||||
|
||||
// Check magnitude of polarisation vector
|
||||
G4bool isPolarised = false;
|
||||
if (polarisation > 0. && polarisation <= 1.)
|
||||
{
|
||||
isPolarised = true;
|
||||
}
|
||||
// gammaPolarization0 = gammaPolarization0.unit(); //
|
||||
|
||||
// Temporary protection: a polarisation parallel to the
|
||||
// direction causes problems; in that case apply the regular LowEnergyCompton algorithm
|
||||
G4ThreeVector gammaDirection = aDynamicGamma->GetMomentumDirection();
|
||||
// Protection: a polarisation parallel to the
|
||||
// direction causes problems;
|
||||
// in that case find a random polarization
|
||||
|
||||
G4ThreeVector gammaDirection = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
G4double scalarproduct = gammaPolarization0.dot(gammaDirection);
|
||||
G4double angle = gammaPolarization0.angle(gammaDirection);
|
||||
if (angle == 0.)
|
||||
|
||||
if (scalarproduct != 0. || angle == 0)
|
||||
{
|
||||
isPolarised = false;
|
||||
// isPolarised = false;
|
||||
gammaPolarization0 = SetRandomPolarization(gammaDirection);
|
||||
}
|
||||
// End of temporary protection
|
||||
|
||||
|
||||
// End of Protection
|
||||
|
||||
// G4double polarisation = gammaPolarization0.mag();
|
||||
|
||||
// Within energy limit?
|
||||
|
||||
if(gammaEnergy0 <= lowestEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(gammaEnergy0);
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
if(gammaEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(gammaEnergy0);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
// Select randomly one element
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
G4Element* theElement = SelectRandomAtom(aDynamicGamma, aMaterial);
|
||||
G4int elementZ = (G4int) theElement->GetZ();
|
||||
|
||||
G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
|
||||
G4ThreeVector gammaDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
G4ThreeVector gammaDirection0 = aDynamicGamma->GetMomentumDirection();
|
||||
// Select randomly one element in the current material
|
||||
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,gammaEnergy0);
|
||||
|
||||
// Sample the energy and the polarization of the scattered photon
|
||||
|
||||
G4double epsilon, epsilonSq, onecost, sinThetaSqr, greject ;
|
||||
|
||||
|
||||
G4double epsilon0 = 1./(1. + 2*E0_m);
|
||||
G4double epsilon0Sq = epsilon0*epsilon0;
|
||||
G4double alpha1 = - log(epsilon0);
|
||||
G4double alpha2 = 0.5*(1.- epsilon0Sq);
|
||||
G4double ScatteringFunction;
|
||||
G4double x;
|
||||
|
||||
G4double wlGamma = h_Planck*c_light/gammaEnergy0;
|
||||
G4double gammaEnergy1;
|
||||
G4ThreeVector gammaDirection1;
|
||||
|
||||
// if (isPolarised) // apply Polarized Condition
|
||||
// {
|
||||
|
||||
if (isPolarised)
|
||||
do {
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
|
||||
{
|
||||
epsilon = exp(-alpha1*G4UniformRand());
|
||||
epsilonSq = epsilon*epsilon;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilonSq = epsilon0Sq + (1.- epsilon0Sq)*G4UniformRand();
|
||||
epsilon = sqrt(epsilonSq);
|
||||
}
|
||||
|
||||
onecost = (1.- epsilon)/(epsilon*E0_m);
|
||||
sinThetaSqr = onecost*(2.-onecost);
|
||||
|
||||
// Protection
|
||||
if (sinThetaSqr > 1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sin(theta)**2 = "
|
||||
<< sinThetaSqr
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
sinThetaSqr = 1.;
|
||||
}
|
||||
if (sinThetaSqr < 0.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sin(theta)**2 = "
|
||||
<< sinThetaSqr
|
||||
<< "; set to 0"
|
||||
<< G4endl;
|
||||
sinThetaSqr = 0.;
|
||||
}
|
||||
// End protection
|
||||
|
||||
G4double x = sqrt(onecost/2.) / (wlGamma/cm);;
|
||||
G4double scatteringFunction = scatterFunctionData->FindValue(x,Z-1);
|
||||
greject = (1. - epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
|
||||
//greject = 1. - epsilon*sinThetaSqr/(1.+ epsilonSq);
|
||||
|
||||
} while(greject < G4UniformRand()*Z);
|
||||
//(greject < G4UniformRand());
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// Phi determination
|
||||
// ****************************************************
|
||||
|
||||
G4double phi = SetPhi(epsilon,sinThetaSqr);
|
||||
|
||||
//
|
||||
// scattered gamma angles. ( Z - axis along the parent gamma)
|
||||
//
|
||||
|
||||
G4double cosTheta = 1. - onecost;
|
||||
|
||||
// Protection
|
||||
|
||||
if (cosTheta > 1.)
|
||||
{
|
||||
do {
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
|
||||
{
|
||||
epsilon = exp(-alpha1*G4UniformRand());
|
||||
epsilonSq = epsilon*epsilon;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilonSq = epsilon0Sq + (1.- epsilon0Sq)*G4UniformRand();
|
||||
epsilon = sqrt(epsilonSq);
|
||||
}
|
||||
|
||||
onecost = (1.- epsilon)/(epsilon*E0_m);
|
||||
sinThetaSqr = onecost*(2.-onecost);
|
||||
|
||||
// Protection
|
||||
if (sinThetaSqr > 1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sin(theta)**2 = "
|
||||
<< sinThetaSqr
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
sinThetaSqr = 1.;
|
||||
}
|
||||
if (sinThetaSqr < 0.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sin(theta)**2 = "
|
||||
<< sinThetaSqr
|
||||
<< "; set to 0"
|
||||
<< G4endl;
|
||||
sinThetaSqr = 0.;
|
||||
}
|
||||
// End protection
|
||||
|
||||
greject = 1. - epsilon*sinThetaSqr/(1.+ epsilonSq);
|
||||
} while (greject < G4UniformRand());
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "cosTheta = "
|
||||
<< cosTheta
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
cosTheta = 1.;
|
||||
}
|
||||
if (cosTheta < -1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "cosTheta = "
|
||||
<< cosTheta
|
||||
<< "; set to -1"
|
||||
<< G4endl;
|
||||
cosTheta = -1.;
|
||||
}
|
||||
// End protection
|
||||
|
||||
|
||||
G4double sinTheta = sqrt (sinThetaSqr);
|
||||
|
||||
// Protection
|
||||
if (sinTheta > 1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sinTheta = "
|
||||
<< sinTheta
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
sinTheta = 1.;
|
||||
}
|
||||
if (sinTheta < -1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sinTheta = "
|
||||
<< sinTheta
|
||||
<< "; set to -1"
|
||||
<< G4endl;
|
||||
sinTheta = -1.;
|
||||
}
|
||||
// End protection
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// Phi determination
|
||||
// ****************************************************
|
||||
G4double dirx = sinTheta*cos(phi);
|
||||
G4double diry = sinTheta*sin(phi);
|
||||
G4double dirz = cosTheta ;
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered photon
|
||||
//
|
||||
|
||||
gammaEnergy1 = epsilon*gammaEnergy0;
|
||||
|
||||
G4double phi = SetPhi(epsilon,sinThetaSqr);
|
||||
|
||||
//
|
||||
// scattered gamma angles. ( Z - axis along the parent gamma)
|
||||
//
|
||||
|
||||
G4double cosTheta = 1. - onecost;
|
||||
|
||||
// Protection
|
||||
|
||||
if (cosTheta > 1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "cosTheta = "
|
||||
<< cosTheta
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
cosTheta = 1.;
|
||||
}
|
||||
if (cosTheta < -1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "cosTheta = "
|
||||
<< cosTheta
|
||||
<< "; set to -1"
|
||||
<< G4endl;
|
||||
cosTheta = -1.;
|
||||
}
|
||||
// End protection
|
||||
|
||||
|
||||
G4double sinTheta = sqrt (sinThetaSqr);
|
||||
|
||||
// Protection
|
||||
if (sinTheta > 1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sinTheta = "
|
||||
<< sinTheta
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
sinTheta = 1.;
|
||||
}
|
||||
if (sinTheta < -1.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sinTheta = "
|
||||
<< sinTheta
|
||||
<< "; set to -1"
|
||||
<< G4endl;
|
||||
sinTheta = -1.;
|
||||
}
|
||||
// End protection
|
||||
|
||||
|
||||
G4double dirx = sinTheta*cos(phi);
|
||||
G4double diry = sinTheta*sin(phi);
|
||||
G4double dirz = cosTheta ;
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
//
|
||||
|
||||
gammaEnergy1 = epsilon*gammaEnergy0;
|
||||
|
||||
// New polarization
|
||||
|
||||
|
||||
G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
|
||||
sinThetaSqr,
|
||||
phi,
|
||||
cosTheta);
|
||||
|
||||
// Set new direction
|
||||
//G4ThreeVector tmpDirection1( dirx,diry,dirz );
|
||||
G4ParticleMomentum tmpDirection1( dirx,diry,dirz );
|
||||
|
||||
gammaDirection1 = tmpDirection1;
|
||||
|
||||
// Change reference frame.
|
||||
|
||||
SystemOfRefChange(gammaDirection0,gammaDirection1,
|
||||
gammaPolarization0,gammaPolarization1);
|
||||
|
||||
if (gammaEnergy1 > 0.)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
// New polarization
|
||||
|
||||
G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
|
||||
sinThetaSqr,
|
||||
phi,
|
||||
cosTheta);
|
||||
|
||||
// Set new direction
|
||||
//G4ThreeVector tmpDirection1( dirx,diry,dirz );
|
||||
|
||||
G4ParticleMomentum tmpDirection1( dirx,diry,dirz );
|
||||
gammaDirection1 = tmpDirection1;
|
||||
|
||||
// Change reference frame.
|
||||
|
||||
SystemOfRefChange(gammaDirection0,gammaDirection1,
|
||||
gammaPolarization0,gammaPolarization1);
|
||||
|
||||
if (gammaEnergy1 > 0.)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Temporary, same algorithm as G4LowEnergyCompton
|
||||
|
||||
do{
|
||||
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand()){
|
||||
|
||||
epsilon = exp(-alpha1*G4UniformRand()); // pow(epsilon0,G4UniformRand())
|
||||
epsilonSq = epsilon*epsilon;
|
||||
}
|
||||
else{
|
||||
|
||||
epsilonSq = epsilon0Sq + (1.- epsilon0Sq)*G4UniformRand();
|
||||
epsilon = sqrt(epsilonSq);
|
||||
}
|
||||
|
||||
onecost = (1.- epsilon)/(epsilon*E0_m);
|
||||
sinThetaSqr = onecost*(2.-onecost);
|
||||
|
||||
x = sqrt(onecost/2)/(wlGamma/cm);
|
||||
|
||||
const G4FirstLevel* oneAtomSF
|
||||
= (*theScatteringFunctionTable)[ZNumVec->index(elementZ)];
|
||||
|
||||
ScatteringFunction = util.DataLogInterpolation(x, (*(*oneAtomSF)[0]),
|
||||
(*(*oneAtomSF)[1]));
|
||||
greject = (1. - epsilon*sinThetaSqr/(1.+ epsilonSq))*ScatteringFunction;
|
||||
|
||||
} while(greject < G4UniformRand()*elementZ);
|
||||
|
||||
G4double cosTheta = 1. - onecost ;
|
||||
G4double sinTheta = sqrt (sinThetaSqr);
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sinTheta*cos(phi) , diry = sinTheta*sin(phi) , dirz = cosTheta ;
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
//
|
||||
|
||||
G4ThreeVector tmpGammaDirection( dirx,diry,dirz );
|
||||
gammaDirection1 = tmpGammaDirection;
|
||||
gammaDirection1.rotateUz(gammaDirection0);
|
||||
aParticleChange.SetMomentumChange( gammaDirection1 ) ;
|
||||
gammaEnergy1 = epsilon*gammaEnergy0;
|
||||
if (gammaEnergy1 > 0.)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -575,37 +358,27 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
|
||||
G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 ;
|
||||
|
||||
if((G4EnergyLossTables::GetRange(G4Electron::Electron(),
|
||||
ElecKineEnergy,aMaterial)>aStep.GetPostStepPoint()->GetSafety())
|
||||
||
|
||||
(ElecKineEnergy >
|
||||
(G4Electron::Electron()->GetCutsInEnergy())[aMaterial->GetIndex()]))
|
||||
|
||||
// Generate the electron only if with large enough range w.r.t. cuts and safety
|
||||
|
||||
G4double safety = aStep.GetPostStepPoint()->GetSafety();
|
||||
|
||||
if (rangeTest->Escape(G4Electron::Electron(),material,ElecKineEnergy,safety))
|
||||
{
|
||||
G4double ElecMomentum = sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector ElecDirection (
|
||||
(gammaEnergy0*gammaDirection0 - gammaEnergy1*gammaDirection1)*(1./ElecMomentum) );
|
||||
|
||||
// create G4DynamicParticle object for the electron.
|
||||
G4DynamicParticle* aElectron= new G4DynamicParticle (G4Electron::Electron(),
|
||||
ElecDirection,
|
||||
ElecKineEnergy) ;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(1) ;
|
||||
aParticleChange.AddSecondary( aElectron ) ;
|
||||
aParticleChange.SetLocalEnergyDeposit (0.) ;
|
||||
G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
|
||||
gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),ElecDirection,ElecKineEnergy) ;
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(electron);
|
||||
aParticleChange.SetLocalEnergyDeposit(0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetNumberOfSecondaries(0) ;
|
||||
aParticleChange.SetLocalEnergyDeposit (ElecKineEnergy) ;
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
aParticleChange.SetLocalEnergyDeposit(ElecKineEnergy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --- The end ---
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
|
||||
}
|
||||
@@ -640,6 +413,44 @@ G4double G4LowEnergyPolarizedCompton::SetPhi(G4double energyRate,
|
||||
}
|
||||
|
||||
|
||||
G4ThreeVector G4LowEnergyPolarizedCompton::SetPerpendicularVector(G4ThreeVector& a)
|
||||
{
|
||||
G4double dx = a.x();
|
||||
G4double dy = a.y();
|
||||
G4double dz = a.z();
|
||||
G4double x = dx < 0.0 ? -dx : dx;
|
||||
G4double y = dy < 0.0 ? -dy : dy;
|
||||
G4double z = dz < 0.0 ? -dz : dz;
|
||||
if (x < y) {
|
||||
return x < z ? G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
|
||||
}else{
|
||||
return y < z ? G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
|
||||
}
|
||||
}
|
||||
|
||||
G4ThreeVector G4LowEnergyPolarizedCompton::SetRandomPolarization(G4ThreeVector& direction0)
|
||||
{
|
||||
G4ThreeVector d0 = direction0.unit();
|
||||
G4ThreeVector a1 = SetPerpendicularVector(d0); //different orthogonal
|
||||
G4ThreeVector a0 = a1.unit(); // unit vector
|
||||
|
||||
G4double rand1 = G4UniformRand();
|
||||
|
||||
G4double angle = twopi*rand1; // random polar angle
|
||||
G4ThreeVector b0 = d0.cross(a0); // cross product
|
||||
|
||||
G4ThreeVector c;
|
||||
|
||||
c.setX(cos(angle)*(a0.x())+sin(angle)*b0.x());
|
||||
c.setY(cos(angle)*(a0.y())+sin(angle)*b0.y());
|
||||
c.setZ(cos(angle)*(a0.z())+sin(angle)*b0.z());
|
||||
|
||||
G4ThreeVector c0 = c.unit();
|
||||
|
||||
return c0;
|
||||
|
||||
}
|
||||
|
||||
G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
|
||||
G4double sinSqrTh,
|
||||
G4double phi,
|
||||
@@ -683,9 +494,9 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
|
||||
|
||||
G4double xParallel = normalisation*cosBeta;
|
||||
G4double yParallel = -(sinSqrTh*cosPhi*sinPhi)*cosBeta/normalisation;
|
||||
G4double zParallel = -(cosTheta*sinTheta*cosPhi)*cosBeta/normalisation;
|
||||
G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
|
||||
G4double xPerpendicular = 0.;
|
||||
G4double yPerpendicular = (cosTheta)*sinBeta/normalisation;
|
||||
G4double yPerpendicular = (costheta)*sinBeta/normalisation;
|
||||
G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
|
||||
|
||||
G4double xTotal = (xParallel + xPerpendicular);
|
||||
@@ -737,7 +548,9 @@ void G4LowEnergyPolarizedCompton::SystemOfRefChange
|
||||
}
|
||||
|
||||
// Added protection
|
||||
|
||||
G4double psi = 0;
|
||||
|
||||
if (sinPsi < 0.) psi = -pi/2.;
|
||||
if (sinPsi > 0.) psi = pi/2.;
|
||||
|
||||
@@ -768,32 +581,19 @@ G4bool G4LowEnergyPolarizedCompton::IsApplicable(const G4ParticleDefinition& par
|
||||
}
|
||||
|
||||
|
||||
G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*)
|
||||
G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
|
||||
// returns the gamma mean free path in GEANT4 internal units
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double gammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
// G4bool isOutRange ;
|
||||
|
||||
|
||||
if (gammaEnergy > highestEnergyLimit)
|
||||
{
|
||||
meanFreePath = DBL_MAX;
|
||||
}
|
||||
else if(gammaEnergy < lowestEnergyLimit)
|
||||
{
|
||||
meanFreePath = DBL_MIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
meanFreePath = util.DataLogInterpolation(gammaEnergy,
|
||||
aMaterial->GetIndex(),
|
||||
theMeanFreePathTable);
|
||||
}
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
@@ -810,4 +610,3 @@ G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& aTrack, G4d
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,363 +20,191 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// $Id: G4LowEnergyRayleigh.cc,v 1.22.2.2 2001/06/28 20:19:30 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// $Id: G4LowEnergyRayleigh.cc,v 1.28 2001/11/07 21:31:16 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// ------------ G4LowEnergyRayleigh physics process --------
|
||||
// by Alessandra Forti, November 1998
|
||||
// **************************************************************
|
||||
// History:
|
||||
// --------
|
||||
// Added Livermore data table construction methods A. Forti
|
||||
// Added BuildMeanFreePath A. Forti
|
||||
// Added PostStepDoIt A. Forti
|
||||
// Added SelectRandomAtom A. Forti
|
||||
// Added map of the elements A.Forti
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
// --------------------------------------------------------------
|
||||
// 11.08.2001 MGP - Major revision according to a design iteration
|
||||
// 06.10.2001 MGP - Added strategy to test range for secondary generation
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// This Class Header
|
||||
#include "G4LowEnergyRayleigh.hh"
|
||||
|
||||
// Collaborating Class Headers
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ForceCondition.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4VCrossSectionHandler.hh"
|
||||
#include "G4CrossSectionHandler.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
// constructor
|
||||
|
||||
G4LowEnergyRayleigh::G4LowEnergyRayleigh(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
theCrossSectionTable(0),
|
||||
theFormFactorTable(0),
|
||||
theMeanFreePathTable(0),
|
||||
ZNumVec(0),
|
||||
lowestEnergyLimit (250*eV), // initialization
|
||||
highestEnergyLimit(100*GeV),
|
||||
NumbBinTable(200),
|
||||
MeanFreePath(0)
|
||||
lowEnergyLimit(250*eV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
{
|
||||
if (verboseLevel>0) {
|
||||
G4cout << GetProcessName() << " is created "<< G4endl;
|
||||
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
|
||||
G4cout << "highestEnergy: " << highestEnergyLimit/TeV << "TeV " << G4endl;
|
||||
}
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyRayleigh::G4LowEnergyRayleigh - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
|
||||
G4VDataSetAlgorithm* ffInterpolation = new G4LogLogInterpolation;
|
||||
G4String formFactorFile = "rayl/re-ff-";
|
||||
formFactorData = new G4CompositeEMDataSet(formFactorFile,ffInterpolation,1.,1.);
|
||||
|
||||
meanFreePathTable = 0;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
// destructor
|
||||
|
||||
G4LowEnergyRayleigh::~G4LowEnergyRayleigh()
|
||||
{
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
|
||||
if(theFormFactorTable){
|
||||
|
||||
delete theFormFactorTable;
|
||||
}
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
delete meanFreePathTable;
|
||||
delete crossSectionHandler;
|
||||
delete formFactorData;
|
||||
}
|
||||
|
||||
|
||||
// methods.............................................................................
|
||||
|
||||
void G4LowEnergyRayleigh::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
|
||||
|
||||
BuildZVec();
|
||||
|
||||
// Build microscopic cross section tables for the Rayleigh process
|
||||
BuildCrossSectionTable();
|
||||
void G4LowEnergyRayleigh::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
// Build mean free path table for the Rayleigh Scattering process
|
||||
BuildMeanFreePathTable();
|
||||
|
||||
// build the scattering function table
|
||||
BuildFormFactorTable();
|
||||
}
|
||||
// CONSTRUCT THE CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL97 DATA
|
||||
void G4LowEnergyRayleigh::BuildCrossSectionTable(){
|
||||
|
||||
if (theCrossSectionTable) {
|
||||
|
||||
delete theCrossSectionTable;
|
||||
}
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
theCrossSectionTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "rayl/re-cs-");
|
||||
|
||||
// theCrossSectionTable->insert(oneAtomCS);
|
||||
theCrossSectionTable->push_back(oneAtomCS);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
// BUILD THE FF TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL97 DATA
|
||||
void G4LowEnergyRayleigh::BuildFormFactorTable(){
|
||||
|
||||
if (theFormFactorTable) {
|
||||
|
||||
delete theFormFactorTable;
|
||||
}
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "rayl/re-cs-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
theFormFactorTable = new G4SecondLevel();
|
||||
G4int dataNum = 2;
|
||||
|
||||
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
|
||||
|
||||
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
|
||||
|
||||
G4FirstLevel* oneAtomFF = util.BuildFirstLevelTables(AtomInd, dataNum, "rayl/re-ff-");
|
||||
|
||||
// theFormFactorTable->insert(oneAtomFF);
|
||||
theFormFactorTable->push_back(oneAtomFF);
|
||||
|
||||
}//end for on atoms
|
||||
}
|
||||
// vector mapping the elements in the material table
|
||||
void G4LowEnergyRayleigh::BuildZVec(){
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if(ZNumVec){
|
||||
ZNumVec->clear();
|
||||
delete ZNumVec;
|
||||
}
|
||||
|
||||
ZNumVec = new G4DataVector();
|
||||
for (G4int J=0 ; J < numOfMaterials; J++){
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ ){
|
||||
|
||||
G4double Zel = (*theElementVector)(iel)->GetZ();
|
||||
|
||||
if(ZNumVec->contains(Zel) == FALSE){
|
||||
ZNumVec->push_back(Zel);
|
||||
} else{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
|
||||
|
||||
//
|
||||
// The scattered gamma energy is sampled according to Form Factors
|
||||
// multiplied by the Rayleigh distribution with a pure rejection technique.
|
||||
// EGS4 W.R. Nelson et al. The EGS4 Code System. SLAC-Report-265 , December 1985
|
||||
// Expression of the angular distribution as Rayleigh distribution and Form factors
|
||||
// is taken from D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
|
||||
// Phys. Res. B 101 (1995). Method of sampling with form factors is different.
|
||||
// Reference to the article is from J. Stepanek New Photon, Positron
|
||||
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
|
||||
// TeV (draft).
|
||||
|
||||
G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
// The scattered gamma energy is sampled according to Form Factors
|
||||
// multiplied by the Rayleigh distribution with a pure rejection technique.
|
||||
// EGS4 W.R. Nelson et al. The EGS4 Code System. SLAC-Report-265 , December 1985
|
||||
// Expression of the angular distribution as Rayleigh distribution and
|
||||
// Form factors is taken from D. E. Cullen "A simple model of photon transport"
|
||||
// NIM B Phys. 101 (1995). Method of sampling with form factors is different.
|
||||
// Reference to the article is from J. Stepanek New Photon, Positron
|
||||
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10 TeV
|
||||
// (draft).
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
// Dynamic particle quantities
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
|
||||
if(GammaEnergy0 <= lowestEnergyLimit){
|
||||
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(GammaEnergy0);
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
// G4double E0_m = GammaEnergy0 / electron_mass_c2 ;
|
||||
G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
|
||||
// Select randomly one element
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
// const G4int numOfElem = aMaterial->GetNumberOfElements();
|
||||
G4Element* theElement = SelectRandomAtom(aDynamicGamma, aMaterial);
|
||||
if (photonEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(photonEnergy0);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
// G4double e0m = photonEnergy0 / electron_mass_c2 ;
|
||||
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element in the current material
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy0);
|
||||
|
||||
// sample the energy of the scattered gamma
|
||||
// Sample the energy of the scattered photon
|
||||
|
||||
G4double wlGamma = h_Planck*c_light/GammaEnergy0;
|
||||
G4int elementZ = (G4int) theElement->GetZ();
|
||||
// G4double tableIndex = elementZ - 1;
|
||||
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
|
||||
|
||||
G4double Theta, DataFormFactor;
|
||||
G4double cosTheta, greject;
|
||||
G4double Theta_Half, x, SinThHalf, RandomFormFactor;
|
||||
G4double gReject;
|
||||
G4double randomFormFactor;
|
||||
G4double cosTheta;
|
||||
G4double sinTheta;
|
||||
do{
|
||||
|
||||
Theta_Half = G4UniformRand()*pi/2;
|
||||
SinThHalf = sin(Theta_Half);
|
||||
x = SinThHalf/(wlGamma/cm);
|
||||
|
||||
const G4FirstLevel* oneAtomFF
|
||||
= (*theFormFactorTable)[ZNumVec->index(elementZ)];
|
||||
|
||||
DataFormFactor = util.DataLogInterpolation(x, (*(*oneAtomFF)[0]),
|
||||
(*(*oneAtomFF)[1]));
|
||||
RandomFormFactor = G4UniformRand()*elementZ*elementZ;
|
||||
|
||||
Theta = Theta_Half*2;
|
||||
cosTheta = cos(Theta);
|
||||
sinTheta = sin(Theta);
|
||||
G4double sqr_rayl = 1+cosTheta*cosTheta;
|
||||
greject = sqr_rayl*DataFormFactor*DataFormFactor;
|
||||
|
||||
}while( greject < RandomFormFactor);
|
||||
do
|
||||
{
|
||||
G4double thetaHalf = G4UniformRand() * pi / 2.;
|
||||
G4double sinThetaHalf = sin(thetaHalf);
|
||||
G4double x = sinThetaHalf / (wlPhoton/cm);
|
||||
G4double dataFormFactor = formFactorData->FindValue(x,Z-1);
|
||||
randomFormFactor = G4UniformRand() * Z * Z;
|
||||
G4double theta = thetaHalf*2;
|
||||
cosTheta = cos(theta);
|
||||
sinTheta = sin(theta);
|
||||
G4double sqrRayl = 1 + cosTheta * cosTheta;
|
||||
gReject = sqrRayl * dataFormFactor * dataFormFactor;
|
||||
|
||||
} while( gReject < randomFormFactor);
|
||||
|
||||
// scattered gamma angles. ( Z - axis along the parent gamma)
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sinTheta*cos(Phi) , diry = sinTheta*sin(Phi) , dirz = cosTheta ;
|
||||
// Scattered photon angles. ( Z - axis along the parent photon)
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
G4double dirX = sinTheta*cos(phi);
|
||||
G4double dirY = sinTheta*sin(phi);
|
||||
G4double dirZ = cosTheta;
|
||||
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
G4ThreeVector GammaDirection1(dirx, diry, dirz);
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
G4ThreeVector photonDirection1(dirX, dirY, dirZ);
|
||||
|
||||
GammaDirection1.rotateUz(GammaDirection0);
|
||||
aParticleChange.SetEnergyChange(GammaEnergy0);
|
||||
aParticleChange.SetMomentumChange(GammaDirection1);
|
||||
photonDirection1.rotateUz(photonDirection0);
|
||||
aParticleChange.SetEnergyChange(photonEnergy0);
|
||||
aParticleChange.SetMomentumChange(photonDirection1);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
|
||||
if(verboseLevel > 15){
|
||||
|
||||
G4cout<<"LE Rayleigh PostStepDoIt"<<G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
}
|
||||
// used log-log interpolation instead of linear interpolation to build the MFP
|
||||
void G4LowEnergyRayleigh::BuildMeanFreePathTable(){
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
|
||||
|
||||
// material
|
||||
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
G4Material* material;
|
||||
|
||||
// MeanFreePath
|
||||
G4double LowEdgeEnergy, Value;
|
||||
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
|
||||
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
|
||||
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, NumbBinTable);
|
||||
|
||||
material = (*theMaterialTable)(J);
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ ){
|
||||
//For each energy
|
||||
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
|
||||
const G4double BigPath= DBL_MAX;
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
|
||||
// For each element
|
||||
|
||||
G4double AtomIndex = (*theElementVector)(k)->GetZ();
|
||||
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
|
||||
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
|
||||
|
||||
}
|
||||
|
||||
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insertAt( J , ptrVector ) ;
|
||||
}
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
}
|
||||
|
||||
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
|
||||
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
|
||||
G4Element* G4LowEnergyRayleigh::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma,
|
||||
G4Material* aMaterial) {
|
||||
|
||||
// select randomly 1 element within the material
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
if (NumberOfElements == 1) return (*theElementVector)(0);
|
||||
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
|
||||
G4double PartialSumSigma = 0.;
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
|
||||
|
||||
G4double crossSection;
|
||||
if (GammaEnergy < lowestEnergyLimit)
|
||||
crossSection = 0. ;
|
||||
else {
|
||||
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
|
||||
|
||||
G4double AtomIndex = (*theElementVector)(i)->GetZ();
|
||||
|
||||
const G4FirstLevel* oneAtomCS
|
||||
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
|
||||
|
||||
crossSection = util.DataLogInterpolation(GammaEnergy,
|
||||
(*(*oneAtomCS)[0]),
|
||||
(*(*oneAtomCS)[1]))*barn;
|
||||
}
|
||||
|
||||
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
|
||||
if(rval <= PartialSumSigma) return ((*theElementVector)(i));
|
||||
}
|
||||
|
||||
return (*theElementVector)(0);
|
||||
G4bool G4LowEnergyRayleigh::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4LowEnergyRayleigh::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyUtilities.cc,v 1.9.2.1 2001/06/28 19:11:51 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// File name: G4LowEnergyUtilitie
|
||||
//
|
||||
// Author: A.Forti
|
||||
//
|
||||
// Creation date: 2 March 1999
|
||||
//
|
||||
// Modifications: 16.11.00 MG Pia Replaced HepString with G4String
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
// This Class Header
|
||||
#include "G4LowEnergyUtilities.hh"
|
||||
|
||||
// Collaborating Class Headers
|
||||
#include "G4Element.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
G4LowEnergyUtilities::G4LowEnergyUtilities()
|
||||
{}
|
||||
|
||||
G4LowEnergyUtilities::~G4LowEnergyUtilities()
|
||||
{}
|
||||
|
||||
G4SecondLevel* G4LowEnergyUtilities::BuildSecondLevelTables(const G4int TableInd,
|
||||
const G4int ParNum,
|
||||
const char* prename){
|
||||
|
||||
G4String prenameStr(prename);
|
||||
// HepString name, prenameStr(prename);
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
if(TableInd != 0){
|
||||
ost << prenameStr << TableInd << ".dat";
|
||||
// HepString Znum(TableInd);
|
||||
// name = prenameStr + Znum + ".dat";
|
||||
}
|
||||
else{
|
||||
ost << prenameStr << ".dat";
|
||||
// name = prenameStr+ ".dat";
|
||||
}
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if(!path){
|
||||
G4String excep = "Error!!! G4LEDATA (Low Energy Electromagnetic processes data directory) environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String path_string(path);
|
||||
G4String dir_file = path_string + "/" + name;
|
||||
G4std::ifstream file(dir_file);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if(!lsdp->is_open()){
|
||||
|
||||
G4String excep = "Error!!!! data file: " + dir_file + " NOT found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
oneAtomTable* oneAtomPar = new oneAtomTable();
|
||||
oneShellTable* oneShellPar = new oneShellTable();
|
||||
|
||||
for(G4int j = 0; j < ParNum; j++){
|
||||
|
||||
// oneShellPar->insertAt(j,new G4DataVector());
|
||||
oneShellPar->push_back(new G4DataVector());
|
||||
}
|
||||
|
||||
G4double a = 0;
|
||||
G4int k = 1, s = 0;
|
||||
|
||||
do{
|
||||
|
||||
file>>a;
|
||||
|
||||
if(a == -1){
|
||||
|
||||
if(s == 0){
|
||||
|
||||
// oneAtomPar->insert(oneShellPar);
|
||||
oneAtomPar->push_back(oneShellPar);
|
||||
oneShellPar = new oneShellTable();
|
||||
|
||||
for(G4int j = 0; j < ParNum; j++){
|
||||
|
||||
// oneShellPar->insertAt(j,new G4DataVector());
|
||||
oneShellPar->push_back(new G4DataVector());
|
||||
}
|
||||
}
|
||||
|
||||
s++;
|
||||
|
||||
if(s == ParNum){
|
||||
|
||||
s = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if(a == -2){
|
||||
|
||||
delete oneShellPar;
|
||||
}
|
||||
|
||||
else{
|
||||
|
||||
if(k%ParNum != 0){
|
||||
|
||||
(*oneShellPar)[k-1]->push_back(a);
|
||||
k++;
|
||||
}
|
||||
else if(k%ParNum == 0){
|
||||
|
||||
(*oneShellPar)[k-1]->push_back(a);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}while(a != -2); //end for on file
|
||||
|
||||
file.close();
|
||||
return oneAtomPar;
|
||||
}
|
||||
|
||||
|
||||
G4FirstLevel* G4LowEnergyUtilities::BuildFirstLevelTables(const G4int TableInd,
|
||||
const G4int ParNum,
|
||||
const char* prename){
|
||||
|
||||
G4String prenameStr(prename);
|
||||
// HepString name, prenameStr(prename);
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
if(TableInd != 0){
|
||||
ost << prenameStr << TableInd << ".dat";
|
||||
// HepString Znum(TableInd);
|
||||
// name = prenameStr + Znum + ".dat";
|
||||
}
|
||||
else{
|
||||
ost << prenameStr << ".dat";
|
||||
// name = prenameStr+ ".dat";
|
||||
}
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if(!path){
|
||||
G4String excep = "Error!!! G4LEDATA (Low Energy Electromagnetic processes data directory) environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String path_string(path);
|
||||
G4String dir_file = path_string + "/" + name;
|
||||
G4std::ifstream file(dir_file);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if(!lsdp->is_open()){
|
||||
|
||||
G4String excep = "Error!!!! data file: " + dir_file + " NOT found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4FirstLevel* oneAtomPar = new G4FirstLevel();
|
||||
|
||||
for(G4int j = 0; j < ParNum; j++){
|
||||
|
||||
// oneAtomPar->insertAt(j,new G4DataVector());
|
||||
oneAtomPar->push_back(new G4DataVector());
|
||||
}
|
||||
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
|
||||
do{
|
||||
|
||||
file>>a;
|
||||
|
||||
if(a == -1 || a == -2){
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
if(k%ParNum != 0){
|
||||
|
||||
(*oneAtomPar)[k-1]->push_back(a);
|
||||
k++;
|
||||
}
|
||||
else if(k%ParNum == 0){
|
||||
|
||||
(*oneAtomPar)[k-1]->push_back(a);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}while(a != -2); //end for on file
|
||||
|
||||
file.close();
|
||||
return oneAtomPar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+20
-35
@@ -21,46 +21,31 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// GEANT 4 class file
|
||||
// $Id: G4RangeTest.cc,v 1.4 2001/11/07 20:47:30 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// CERN, Geneva, Switzerland
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// File name: G4ThirdLevel.hh
|
||||
// History:
|
||||
// -----------
|
||||
// 05 Oct 2001 MGP Created
|
||||
//
|
||||
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
|
||||
//
|
||||
// Creation date: 1 Giugno 1999
|
||||
//
|
||||
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ThirdLevel.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
|
||||
G4bool G4RangeTest::Escape(const G4ParticleDefinition* particle,
|
||||
const G4Material* material,
|
||||
G4double energy,
|
||||
G4double safety) const
|
||||
{
|
||||
G4double range = G4EnergyLossTables::GetRange(particle,energy,material);
|
||||
G4double cut = particle->GetRangeThreshold(material);
|
||||
G4double rMin = G4std::min(cut,safety);
|
||||
G4bool value = (range > rMin);
|
||||
|
||||
G4ThirdLevel::~G4ThirdLevel(){
|
||||
|
||||
// this->clearAndDestroy();
|
||||
this->clear();
|
||||
return value;
|
||||
}
|
||||
|
||||
G4bool G4ThirdLevel::operator == (const G4ThirdLevel& input) const{
|
||||
|
||||
// return( this->entries() == input.entries());
|
||||
return( this->size() == input.size());
|
||||
|
||||
}
|
||||
|
||||
G4bool G4ThirdLevel::operator < (const G4ThirdLevel& input) const{
|
||||
|
||||
// return(this->entries() < input.entries());
|
||||
return(this->size() < input.size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4SemiLogInterpolation.cc,v 1.3 2001/09/10 18:07:35 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4SemiLogInterpolation.hh"
|
||||
|
||||
// Constructor
|
||||
|
||||
G4SemiLogInterpolation::G4SemiLogInterpolation()
|
||||
{ }
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
G4SemiLogInterpolation::~G4SemiLogInterpolation()
|
||||
{ }
|
||||
|
||||
|
||||
G4double G4SemiLogInterpolation::Calculate(G4double x, G4int bin,
|
||||
const G4DataVector& points,
|
||||
const G4DataVector& data) const
|
||||
{
|
||||
G4int nBins = data.size() - 1;
|
||||
G4double value = 0.;
|
||||
if (x < points[0])
|
||||
{
|
||||
value = 0.;
|
||||
}
|
||||
else if (bin < nBins)
|
||||
{
|
||||
G4double e1 = points[bin];
|
||||
G4double e2 = points[bin+1];
|
||||
G4double d1 = data[bin];
|
||||
G4double d2 = data[bin+1];
|
||||
value = (d1*log10(e2/x) + d2*log10(x/e1)) / log10(e2/e1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = data[nBins];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ShellData.cc,v 1.4 2001/09/26 21:19:23 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ShellData.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
// Constructor
|
||||
|
||||
G4ShellData::G4ShellData(G4int minZ, G4int maxZ)
|
||||
: zMin(minZ), zMax(maxZ)
|
||||
{ }
|
||||
|
||||
// Destructor
|
||||
G4ShellData::~G4ShellData()
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
for (pos = idMap.begin(); pos != idMap.end(); pos++)
|
||||
{
|
||||
G4DataVector* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
for (pos = bindingMap.begin(); pos != bindingMap.end(); pos++)
|
||||
{
|
||||
G4DataVector* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t G4ShellData::NumberOfShells(G4int Z) const
|
||||
{
|
||||
G4int z = Z - 1;
|
||||
G4int n = 0;
|
||||
|
||||
if (Z>= zMin && Z <= zMax)
|
||||
{
|
||||
n = nShells[z];
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
const G4DataVector& G4ShellData::ShellIdVector(G4int Z) const
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
if (Z < zMin || Z > zMax)
|
||||
G4Exception("G4ShellData::ShellIdVector - Z outside boundaries");
|
||||
pos = idMap.find(Z);
|
||||
G4DataVector* dataSet = (*pos).second;
|
||||
return *dataSet;
|
||||
}
|
||||
|
||||
G4int G4ShellData::ShellId(G4int Z, G4int shellIndex) const
|
||||
{
|
||||
G4int n = -1;
|
||||
|
||||
if (Z >= zMin && Z <= zMax)
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = idMap.find(Z);
|
||||
if (pos!= idMap.end())
|
||||
{
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
G4int nData = dataSet.size();
|
||||
if (shellIndex >= 0 && shellIndex < nData)
|
||||
{
|
||||
n = (G4int) dataSet[shellIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
G4double G4ShellData::BindingEnergy(G4int Z, G4int shellIndex) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
|
||||
if (Z >= zMin && Z <= zMax)
|
||||
{
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = bindingMap.find(Z);
|
||||
if (pos!= bindingMap.end())
|
||||
{
|
||||
G4DataVector dataSet = *((*pos).second);
|
||||
G4int nData = dataSet.size();
|
||||
if (shellIndex >= 0 && shellIndex < nData)
|
||||
{
|
||||
value = dataSet[shellIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void G4ShellData::PrintData() const
|
||||
{
|
||||
for (G4int Z = zMin; Z <= zMax; Z++)
|
||||
{
|
||||
G4cout << "---- Shell data for Z = "
|
||||
<< Z
|
||||
<< " ---- "
|
||||
<< G4endl;
|
||||
G4int nSh = nShells[Z-1];
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator posId;
|
||||
posId = idMap.find(Z);
|
||||
G4DataVector* ids = (*posId).second;
|
||||
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator posE;
|
||||
posE = bindingMap.find(Z);
|
||||
G4DataVector* energies = (*posE).second;
|
||||
for (G4int i=0; i<nSh; i++)
|
||||
{
|
||||
G4int id = (G4int) (*ids)[i];
|
||||
G4double e = (*energies)[i] / MeV;
|
||||
G4cout << i <<") Shell id: " << id
|
||||
<< " - Binding energy = "
|
||||
<< e << " MeV " << G4endl;
|
||||
}
|
||||
G4cout << "-------------------------------------------------"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4ShellData::LoadData(const G4String& fileName)
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
ost << fileName << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4ShellData - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
G4int s = 0;
|
||||
|
||||
G4int Z = 1;
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* ids = new G4DataVector;
|
||||
|
||||
do {
|
||||
file >> a;
|
||||
G4int nColumns = 2;
|
||||
if (a == -1)
|
||||
{
|
||||
if (s == 0)
|
||||
{
|
||||
// End of a shell data set
|
||||
idMap[Z] = ids;
|
||||
bindingMap[Z] = energies;
|
||||
G4int n = ids->size();
|
||||
nShells.push_back(n);
|
||||
// Start of new shell data set
|
||||
ids = new G4DataVector;
|
||||
energies = new G4DataVector;
|
||||
Z++;
|
||||
}
|
||||
s++;
|
||||
if (s == nColumns)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
}
|
||||
else if (a == -2)
|
||||
{
|
||||
// End of file; delete the empty vectors created when encountering the last -1 -1 row
|
||||
delete energies;
|
||||
delete ids;
|
||||
//nComponents = components.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1st column is shell id
|
||||
if(k%nColumns != 0)
|
||||
{
|
||||
ids->push_back(a);
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
{
|
||||
// 2nd column is binding energy
|
||||
G4double e = a * MeV;
|
||||
energies->push_back(e);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
} while (a != -2); // end of file
|
||||
file.close();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ShellEMDataSet.cc,v 1.7 2001/10/11 14:10:40 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 1 Aug 2001 MGP Created
|
||||
// 09.10.01 V.Ivanchenko Add case z=0
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
|
||||
G4ShellEMDataSet::G4ShellEMDataSet(G4int Z,
|
||||
const G4VDataSetAlgorithm* interpolation,
|
||||
G4double unitE, G4double unitData)
|
||||
:z(Z), algorithm(interpolation)
|
||||
{
|
||||
nComponents = 0;
|
||||
unit1 = unitE;
|
||||
unit2 = unitData;
|
||||
}
|
||||
|
||||
G4ShellEMDataSet::G4ShellEMDataSet(G4int Z, const G4String& dataFile,
|
||||
const G4VDataSetAlgorithm* interpolation,
|
||||
G4double unitE, G4double unitData)
|
||||
:z(Z), algorithm(interpolation)
|
||||
{
|
||||
nComponents = 0;
|
||||
unit1 = unitE;
|
||||
unit2 = unitData;
|
||||
LoadData(dataFile);
|
||||
}
|
||||
|
||||
G4ShellEMDataSet::~G4ShellEMDataSet()
|
||||
{
|
||||
for (size_t i=0; i<nComponents; i++)
|
||||
{
|
||||
delete components[i];
|
||||
}
|
||||
delete algorithm;
|
||||
}
|
||||
|
||||
G4double G4ShellEMDataSet::FindValue(G4double e, G4int id) const
|
||||
{
|
||||
// Returns the sum over the shells corresponding to e
|
||||
G4double value = 0.;
|
||||
|
||||
for (size_t i=0; i<nComponents; i++)
|
||||
{
|
||||
G4VEMDataSet* component = components[i];
|
||||
G4double shellValue = component->FindValue(e);
|
||||
value = value + shellValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void G4ShellEMDataSet::PrintData() const
|
||||
{
|
||||
G4cout << "The data set has " << nComponents << " components" << G4endl;
|
||||
|
||||
for (size_t i=0; i<nComponents; i++)
|
||||
{
|
||||
G4cout << "--- Component " << i << " ---" << G4endl;
|
||||
G4VEMDataSet* component = components[i];
|
||||
component->PrintData();
|
||||
}
|
||||
}
|
||||
|
||||
void G4ShellEMDataSet::LoadData(const G4String& fileName)
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
if (z != 0) ost << fileName << z << ".dat";
|
||||
else ost << fileName << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4ShellEMDataSet - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + "/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4ShellEMDataSet - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
G4int s = 0;
|
||||
|
||||
G4int shellIndex = 0;
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* data = new G4DataVector;
|
||||
|
||||
do {
|
||||
file >> a;
|
||||
G4int nColumns = 2;
|
||||
if (a == -1)
|
||||
{
|
||||
if (s == 0)
|
||||
{
|
||||
// End of a shell data set
|
||||
G4VDataSetAlgorithm* algo = algorithm->Clone();
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(shellIndex,energies,data,algo);
|
||||
AddComponent(dataSet);
|
||||
// Start of new shell data set
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
shellIndex++;
|
||||
}
|
||||
s++;
|
||||
if (s == nColumns)
|
||||
{
|
||||
s = 0;
|
||||
}
|
||||
}
|
||||
else if (a == -2)
|
||||
{
|
||||
// End of file; delete the empty vectors created when encountering the last -1 -1 row
|
||||
delete energies;
|
||||
delete data;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1st column is energy
|
||||
if(k%nColumns != 0)
|
||||
{
|
||||
G4double e = a * unit1;
|
||||
energies->push_back(e);
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
{
|
||||
// 2nd column is cross section
|
||||
G4double value = a * unit2;
|
||||
data->push_back(value);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
} while (a != -2); // end of file
|
||||
file.close();
|
||||
}
|
||||
|
||||
void G4ShellEMDataSet::AddComponent(G4VEMDataSet* component)
|
||||
{
|
||||
components.push_back(component);
|
||||
nComponents++;
|
||||
}
|
||||
|
||||
const G4DataVector& G4ShellEMDataSet::GetEnergies(G4int i) const
|
||||
{
|
||||
const G4VEMDataSet* component = GetComponent(i);
|
||||
return (component->GetEnergies(i));
|
||||
}
|
||||
|
||||
const G4DataVector& G4ShellEMDataSet::GetData(G4int i) const
|
||||
{
|
||||
const G4VEMDataSet* component = GetComponent(i);
|
||||
return (component->GetData(i));
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ShellVacancy.cc
|
||||
// GEANT4 tag $Name:
|
||||
//
|
||||
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 21 Sept 2001 Elena Guardincerri Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ShellVacancy.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
|
||||
G4ShellVacancy::G4ShellVacancy()
|
||||
|
||||
{ }
|
||||
|
||||
G4ShellVacancy::~G4ShellVacancy()
|
||||
|
||||
{
|
||||
G4int size = xsis.size();
|
||||
for (G4int k =0; k<size; k++)
|
||||
{
|
||||
delete xsis[k];
|
||||
xsis[k] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void G4ShellVacancy::AddXsiTable(G4VEMDataSet* set)
|
||||
|
||||
{
|
||||
xsis.push_back(set);
|
||||
}
|
||||
|
||||
G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4Material*
|
||||
material,
|
||||
G4double
|
||||
incidentEnergy,
|
||||
G4double eLoss) const
|
||||
|
||||
{
|
||||
G4std::vector<G4int> numberOfIonisations;
|
||||
|
||||
size_t numberOfElements = material->GetNumberOfElements();
|
||||
|
||||
for (size_t i = 0; i<numberOfElements; i++)
|
||||
{
|
||||
const G4Element* element = material->GetElement(i);
|
||||
|
||||
G4int averageNumberOfIonisations = AverageNOfIonisations(material,
|
||||
element,
|
||||
incidentEnergy,
|
||||
eLoss);
|
||||
G4int ionisations = (G4int) G4Poisson(averageNumberOfIonisations);
|
||||
|
||||
numberOfIonisations.push_back(ionisations);
|
||||
|
||||
}
|
||||
return numberOfIonisations;
|
||||
|
||||
}
|
||||
|
||||
G4int G4ShellVacancy::AverageNOfIonisations(const G4Material* material,
|
||||
const G4Element* element,
|
||||
G4double energy,
|
||||
G4double eLoss) const
|
||||
|
||||
{
|
||||
G4int indexOfElementInMaterial= -1;
|
||||
|
||||
G4double averageEnergy = energy - eLoss/2.;
|
||||
|
||||
G4String elementName = element->GetName();
|
||||
|
||||
size_t numberOfElements = material->GetNumberOfElements();
|
||||
|
||||
for (size_t i = 0; i<numberOfElements; i++)
|
||||
{
|
||||
const G4Element* anElement = material->GetElement(i);
|
||||
|
||||
G4String itsName = anElement->GetName();
|
||||
|
||||
if (itsName==elementName)
|
||||
{
|
||||
indexOfElementInMaterial=i;
|
||||
break;
|
||||
}
|
||||
//else
|
||||
//{break;}
|
||||
}
|
||||
size_t indexInMaterialTable = material->GetIndex();
|
||||
|
||||
G4VEMDataSet* aSetOfXsi = xsis[indexInMaterialTable];
|
||||
|
||||
G4double aXsi = aSetOfXsi->FindValue(averageEnergy,indexOfElementInMaterial);
|
||||
|
||||
G4int averageNumberOfIonisations = (G4int)(aXsi * eLoss);
|
||||
|
||||
return averageNumberOfIonisations;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,653 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VCrossSectionHandler.cc,v 1.8 2001/10/10 16:46:06 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 1 Aug 2001 MGP Created
|
||||
// 09.10.01 V.Ivanchenko Add FindValue with 3 parameters
|
||||
// + NumberOfComponents
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4VCrossSectionHandler.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "g4std/map"
|
||||
#include "g4std/vector"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
|
||||
G4VCrossSectionHandler::G4VCrossSectionHandler()
|
||||
{
|
||||
crossSections = 0;
|
||||
interpolation = 0;
|
||||
Initialise();
|
||||
ActiveElements();
|
||||
}
|
||||
|
||||
|
||||
G4VCrossSectionHandler::G4VCrossSectionHandler(G4VDataSetAlgorithm* algorithm,
|
||||
G4double minE,
|
||||
G4double maxE,
|
||||
G4int bins,
|
||||
G4double unitE,
|
||||
G4double unitData,
|
||||
G4int minZ,
|
||||
G4int maxZ)
|
||||
: interpolation(algorithm), eMin(minE), eMax(maxE), nBins(bins),
|
||||
unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
|
||||
{
|
||||
crossSections = 0;
|
||||
ActiveElements();
|
||||
}
|
||||
|
||||
G4VCrossSectionHandler::~G4VCrossSectionHandler()
|
||||
{
|
||||
delete interpolation;
|
||||
interpolation = 0;
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
for (pos = dataMap.begin(); pos != dataMap.end(); ++pos)
|
||||
{
|
||||
// The following is a workaround for STL ObjectSpace implementation,
|
||||
// which does not support the standard and does not accept
|
||||
// the syntax pos->second
|
||||
// G4VEMDataSet* dataSet = pos->second;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
if (crossSections != 0)
|
||||
{
|
||||
size_t n = crossSections->size();
|
||||
for (size_t i=0; i<n; i++)
|
||||
{
|
||||
delete (*crossSections)[i];
|
||||
}
|
||||
delete crossSections;
|
||||
crossSections = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void G4VCrossSectionHandler::Initialise(G4VDataSetAlgorithm* algorithm,
|
||||
G4double minE, G4double maxE,
|
||||
G4int numberOfBins,
|
||||
G4double unitE, G4double unitData,
|
||||
G4int minZ, G4int maxZ)
|
||||
{
|
||||
if (algorithm != 0)
|
||||
{
|
||||
delete interpolation;
|
||||
interpolation = algorithm;
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolation = CreateInterpolation();
|
||||
}
|
||||
|
||||
eMin = minE;
|
||||
eMax = maxE;
|
||||
nBins = numberOfBins;
|
||||
unit1 = unitE;
|
||||
unit2 = unitData;
|
||||
zMin = minZ;
|
||||
zMax = maxZ;
|
||||
}
|
||||
|
||||
void G4VCrossSectionHandler::PrintData() const
|
||||
{
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
for (pos = dataMap.begin(); pos != dataMap.end(); pos++)
|
||||
{
|
||||
// The following is a workaround for STL ObjectSpace implementation,
|
||||
// which does not support the standard and does not accept
|
||||
// the syntax pos->first or pos->second
|
||||
// G4int z = pos->first;
|
||||
// G4VEMDataSet* dataSet = pos->second;
|
||||
G4int z = (*pos).first;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
G4cout << "---- Data set for Z = "
|
||||
<< z
|
||||
<< G4endl;
|
||||
dataSet->PrintData();
|
||||
G4cout << "--------------------------------------------------" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4VCrossSectionHandler::LoadData(const G4String& fileName)
|
||||
{
|
||||
size_t nZ = activeZ.size();
|
||||
for (size_t i=0; i<nZ; i++)
|
||||
{
|
||||
G4int Z = (G4int) activeZ[i];
|
||||
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
ost << fileName << Z << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4VCrossSectionHandler - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + "/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4VCrossSectionHandler - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* data = new G4DataVector;
|
||||
do
|
||||
{
|
||||
file >> a;
|
||||
G4int nColumns = 2;
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
// 2nd column is the corresponding value
|
||||
// The file terminates with the pattern: -1 -1
|
||||
// -2 -2
|
||||
if (a == -1 || a == -2)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (k%nColumns != 0)
|
||||
{
|
||||
G4double e = a * unit1;
|
||||
energies->push_back(e);
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
{
|
||||
G4double value = a * unit2;
|
||||
data->push_back(value);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
} while (a != -2); // end of file
|
||||
|
||||
file.close();
|
||||
G4VDataSetAlgorithm* algo = interpolation->Clone();
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(Z,energies,data,algo);
|
||||
dataMap[Z] = dataSet;
|
||||
}
|
||||
}
|
||||
|
||||
void G4VCrossSectionHandler::LoadShellData(const G4String& fileName)
|
||||
{
|
||||
size_t nZ = activeZ.size();
|
||||
for (size_t i=0; i<nZ; i++)
|
||||
{
|
||||
G4int Z = (G4int) activeZ[i];
|
||||
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
ost << fileName << Z << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4VCrossSectionHandler - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
G4String dirFile = pathString + "/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) )
|
||||
{
|
||||
G4String excep = "G4VCrossSectionHandler - data file: " + dirFile + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4double a = 0;
|
||||
G4int k = 1;
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* data = new G4DataVector;
|
||||
do
|
||||
{
|
||||
file >> a;
|
||||
G4int nColumns = 2;
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
// 2nd column is the corresponding value
|
||||
// The file terminates with the pattern: -1 -1
|
||||
// -2 -2
|
||||
if (a == -1 || a == -2)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (k%nColumns != 0)
|
||||
{
|
||||
G4double e = a * unit1;
|
||||
energies->push_back(e);
|
||||
k++;
|
||||
}
|
||||
else if (k%nColumns == 0)
|
||||
{
|
||||
G4double value = a * unit2;
|
||||
data->push_back(value);
|
||||
k = 1;
|
||||
}
|
||||
}
|
||||
} while (a != -2); // end of file
|
||||
|
||||
file.close();
|
||||
G4VDataSetAlgorithm* algo = interpolation->Clone();
|
||||
G4VEMDataSet* dataSet = new G4ShellEMDataSet(Z,fileName,algo);
|
||||
dataMap[Z] = dataSet;
|
||||
}
|
||||
}
|
||||
|
||||
void G4VCrossSectionHandler::Clear()
|
||||
{
|
||||
// Reset the map of data sets: remove the data sets from the map
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
if(! dataMap.empty())
|
||||
{
|
||||
for (pos = dataMap.begin(); pos != dataMap.end(); ++pos)
|
||||
{
|
||||
// The following is a workaround for STL ObjectSpace implementation,
|
||||
// which does not support the standard and does not accept
|
||||
// the syntax pos->first or pos->second
|
||||
// G4VEMDataSet* dataSet = pos->second;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
dataSet = 0;
|
||||
G4int i = (*pos).first;
|
||||
dataMap[i] = 0;
|
||||
}
|
||||
dataMap.clear();
|
||||
}
|
||||
|
||||
activeZ.clear();
|
||||
ActiveElements();
|
||||
}
|
||||
|
||||
G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = dataMap.find(Z);
|
||||
if (pos!= dataMap.end())
|
||||
{
|
||||
// The following is a workaround for STL ObjectSpace implementation,
|
||||
// which does not support the standard and does not accept
|
||||
// the syntax pos->first or pos->second
|
||||
// G4VEMDataSet* dataSet = pos->second;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
value = dataSet->FindValue(energy);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find Z = "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy,
|
||||
G4int shellIndex) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = dataMap.find(Z);
|
||||
if (pos!= dataMap.end())
|
||||
{
|
||||
// The following is a workaround for STL ObjectSpace implementation,
|
||||
// which does not support the standard and does not accept
|
||||
// the syntax pos->first or pos->second
|
||||
// G4VEMDataSet* dataSet = pos->second;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
if (shellIndex >= 0)
|
||||
{
|
||||
G4int nComponents = dataSet->NumberOfComponents();
|
||||
if(shellIndex < nComponents)
|
||||
// - MGP - Why doesn't it use G4VEMDataSet::FindValue directly?
|
||||
value = dataSet->GetComponent(shellIndex)->FindValue(energy);
|
||||
else
|
||||
{
|
||||
G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find"
|
||||
<< " shellIndex= " << shellIndex
|
||||
<< " for Z= "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
} else {
|
||||
value = dataSet->FindValue(energy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find Z = "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material,
|
||||
G4double energy) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
for (G4int i=0 ; i<nElements ; i++)
|
||||
{
|
||||
G4int Z = (G4int) (*elementVector)[i]->GetZ();
|
||||
G4double elementValue = FindValue(Z,energy);
|
||||
G4double nAtomsVol = nAtomsPerVolume[i];
|
||||
value += nAtomsVol * elementValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
// Builds a CompositeDataSet containing the mean free path for each material
|
||||
// in the material table
|
||||
|
||||
G4DataVector energyVector;
|
||||
G4double dBin = log10(eMax/eMin) / nBins;
|
||||
|
||||
for (G4int i=0; i<nBins+1; i++)
|
||||
{
|
||||
energyVector.push_back(pow(10., log10(eMin)+i*dBin));
|
||||
}
|
||||
|
||||
// Factory method to build cross sections in derived classes,
|
||||
// related to the type of physics process
|
||||
|
||||
if (crossSections != 0)
|
||||
{ // Reset the list of cross sections
|
||||
G4std::vector<G4VEMDataSet*>::iterator mat;
|
||||
if (! crossSections->empty())
|
||||
{
|
||||
for (mat = crossSections->begin(); mat!= crossSections->end(); ++mat)
|
||||
{
|
||||
G4VEMDataSet* set = *mat;
|
||||
delete set;
|
||||
set = 0;
|
||||
}
|
||||
crossSections->clear();
|
||||
delete crossSections;
|
||||
crossSections = 0;
|
||||
}
|
||||
}
|
||||
|
||||
crossSections = BuildCrossSectionsForMaterials(energyVector,energyCuts);
|
||||
|
||||
if (crossSections == 0)
|
||||
G4Exception("G4VCrossSectionHandler::BuildMeanFreePathForMaterials, crossSections = 0");
|
||||
|
||||
G4VDataSetAlgorithm* algo = CreateInterpolation();
|
||||
G4VEMDataSet* materialSet = new G4CompositeEMDataSet(algo);
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* data;
|
||||
|
||||
size_t nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
for (size_t m=0; m<nMaterials; m++)
|
||||
{
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
for (G4int bin=0; bin<nBins; bin++)
|
||||
{
|
||||
G4double energy = energyVector[bin];
|
||||
energies->push_back(energy);
|
||||
G4VEMDataSet* matCrossSet = (*crossSections)[m];
|
||||
G4double materialCrossSection = matCrossSet->FindValue(energy);
|
||||
|
||||
if (materialCrossSection > 0.)
|
||||
{
|
||||
data->push_back(1./materialCrossSection);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->push_back(DBL_MAX);
|
||||
}
|
||||
}
|
||||
G4VDataSetAlgorithm* algo = CreateInterpolation();
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(m,energies,data,algo,1.,1.);
|
||||
materialSet->AddComponent(dataSet);
|
||||
}
|
||||
|
||||
return materialSet;
|
||||
}
|
||||
|
||||
G4int G4VCrossSectionHandler::SelectRandomAtom(const G4Material* material, G4double e) const
|
||||
{
|
||||
// Select randomly an element within the material, according to the weight
|
||||
// determined by the cross sections in the data set
|
||||
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
|
||||
// Special case: the material consists of one element
|
||||
if (nElements == 1)
|
||||
{
|
||||
G4int Z = (G4int) (*elementVector)[0]->GetZ();
|
||||
return Z;
|
||||
}
|
||||
|
||||
// Composite material
|
||||
|
||||
G4double materialCrossSection0 = ValueForMaterial(material,e);
|
||||
// size_t materialIndex = material->GetIndex();
|
||||
|
||||
// G4VEMDataSet* materialSet = crossSections[materialIndex];
|
||||
// G4double materialCrossSection = materialSet->FindValue(e);
|
||||
|
||||
G4double random = G4UniformRand() * materialCrossSection0;
|
||||
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
G4double partialSumSigma = 0.;
|
||||
|
||||
for ( G4int i=0 ; i < nElements ; i++ )
|
||||
{
|
||||
G4int Z = (G4int) (*elementVector)[i]->GetZ();
|
||||
G4double crossSection = FindValue(Z,e);
|
||||
partialSumSigma += nAtomsPerVolume[i] * crossSection;
|
||||
if (random <= partialSumSigma) return Z;
|
||||
}
|
||||
// It should never get here
|
||||
return 0;
|
||||
}
|
||||
|
||||
const G4Element* G4VCrossSectionHandler::SelectRandomElement(const G4Material* material,
|
||||
G4double e) const
|
||||
{
|
||||
// Select randomly an element within the material, according to the weight determined
|
||||
// by the cross sections in the data set
|
||||
|
||||
G4Element* nullElement = 0;
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
|
||||
// Special case: the material consists of one element
|
||||
if (nElements == 1)
|
||||
{
|
||||
G4Element* element = (*elementVector)[0];
|
||||
return element;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Composite material
|
||||
G4double materialCrossSection0 = ValueForMaterial(material,e);
|
||||
// size_t materialIndex = material->GetIndex();
|
||||
// G4VEMDataSet* materialSet = crossSections[materialIndex];
|
||||
// G4double materialCrossSection = materialSet->FindValue(e);
|
||||
|
||||
G4double random = G4UniformRand() * materialCrossSection0;
|
||||
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
G4double partialSumSigma = 0.;
|
||||
|
||||
for ( G4int i=0 ; i < nElements ; i++ )
|
||||
{
|
||||
G4Element* element = (*elementVector)[i];
|
||||
G4int Z = (G4int) element->GetZ();
|
||||
G4double crossSection = FindValue(Z,e);
|
||||
partialSumSigma += nAtomsPerVolume[i] * crossSection;
|
||||
if (random <= partialSumSigma) return element;
|
||||
}
|
||||
}
|
||||
// It should never end up here
|
||||
G4cout << "G4VCrossSectionHandler::SelectRandomElement - no element found" << G4endl;
|
||||
return nullElement;
|
||||
}
|
||||
|
||||
G4int G4VCrossSectionHandler::SelectRandomShell(G4int Z, G4double e) const
|
||||
{
|
||||
// Select randomly a shell, according to the weight determined by the cross sections
|
||||
// in the data set
|
||||
|
||||
// Note for later improvement: it would be useful to add a cache mechanism for already
|
||||
// used shells to improve performance
|
||||
|
||||
G4int shell = 0;
|
||||
|
||||
G4double totCrossSection = FindValue(Z,e);
|
||||
G4double random = G4UniformRand() * totCrossSection;
|
||||
G4double partialSum = 0.;
|
||||
|
||||
G4VEMDataSet* dataSet = 0;
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = dataMap.find(Z);
|
||||
// The following is a workaround for STL ObjectSpace implementation,
|
||||
// which does not support the standard and does not accept
|
||||
// the syntax pos->first or pos->second
|
||||
// if (pos != dataMap.end()) dataSet = pos->second;
|
||||
if (pos != dataMap.end()) dataSet = (*pos).second;
|
||||
|
||||
size_t nShells = dataSet->NumberOfComponents();
|
||||
for (size_t i=0; i<nShells; i++)
|
||||
{
|
||||
const G4VEMDataSet* shellDataSet = dataSet->GetComponent(i);
|
||||
if (shellDataSet != 0)
|
||||
{
|
||||
G4double value = shellDataSet->FindValue(e);
|
||||
partialSum += value;
|
||||
if (random <= partialSum) return i;
|
||||
}
|
||||
}
|
||||
// It should never get here
|
||||
return shell;
|
||||
}
|
||||
|
||||
void G4VCrossSectionHandler::ActiveElements()
|
||||
{
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4VCrossSectionHandler::ActiveElements - no MaterialTable found)");
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++)
|
||||
{
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
for (G4int iEl=0; iEl<nElements; iEl++)
|
||||
{
|
||||
G4Element* element = (*elementVector)[iEl];
|
||||
G4double Z = element->GetZ();
|
||||
if (!(activeZ.contains(Z)) && Z >= zMin && Z <= zMax)
|
||||
{
|
||||
activeZ.push_back(Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4VDataSetAlgorithm* G4VCrossSectionHandler::CreateInterpolation()
|
||||
{
|
||||
G4VDataSetAlgorithm* algorithm = new G4LogLogInterpolation;
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
G4int G4VCrossSectionHandler::NumberOfComponents(G4int Z) const
|
||||
{
|
||||
G4int n = 0;
|
||||
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
pos = dataMap.find(Z);
|
||||
if (pos!= dataMap.end())
|
||||
{
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
n = dataSet->NumberOfComponents();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "WARNING: G4VCrossSectionHandler::NumberOfComponents did not "
|
||||
<< "find Z = "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VeLowEnergyLoss.cc,v 1.12.2.2 2001/06/28 20:19:31 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// $Id: G4VeLowEnergyLoss.cc,v 1.17 2001/11/23 11:45:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -37,6 +37,7 @@
|
||||
// 22/11/00 minor fix in fluctuations V.Ivanchenko
|
||||
// 10/05/01 V.Ivanchenko Clean up againist Linux compilation with -Wall
|
||||
// 22/05/01 V.Ivanchenko Update range calculation
|
||||
// 23/11/01 V.Ivanchenko Move static member-functions from header to source
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -95,16 +96,33 @@ G4VeLowEnergyLoss::G4VeLowEnergyLoss(G4VeLowEnergyLoss& right)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
void G4VeLowEnergyLoss::SetRndmStep(G4bool value)
|
||||
{
|
||||
rndmStepFlag = value;
|
||||
}
|
||||
|
||||
void G4VeLowEnergyLoss::SetEnlossFluc(G4bool value)
|
||||
{
|
||||
EnlossFlucFlag = value;
|
||||
}
|
||||
|
||||
void G4VeLowEnergyLoss::SetStepFunction (G4double c1, G4double c2)
|
||||
{
|
||||
dRoverRange = c1;
|
||||
finalRange = c2;
|
||||
c1lim=dRoverRange;
|
||||
c2lim=2.*(1-dRoverRange)*finalRange;
|
||||
c3lim=-(1.-dRoverRange)*finalRange*finalRange;
|
||||
}
|
||||
|
||||
G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeTable(
|
||||
G4PhysicsTable* theDEDXTable,G4PhysicsTable* theRangeTable,
|
||||
G4double lowestKineticEnergy,G4double highestKineticEnergy,G4int TotBin)
|
||||
G4double lowestKineticEnergy,G4double highestKineticEnergy,
|
||||
G4int TotBin)
|
||||
// Build range table from the energy loss table
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theRangeTable)
|
||||
{ theRangeTable->clearAndDestroy();
|
||||
@@ -236,9 +254,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildLabTimeTable(G4PhysicsTable* theDEDXTabl
|
||||
G4double highestKineticEnergy,G4int TotBin)
|
||||
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theLabTimeTable)
|
||||
{ theLabTimeTable->clearAndDestroy();
|
||||
@@ -270,9 +287,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildProperTimeTable(G4PhysicsTable* theDEDXT
|
||||
G4double highestKineticEnergy,G4int TotBin)
|
||||
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theProperTimeTable)
|
||||
{ theProperTimeTable->clearAndDestroy();
|
||||
@@ -312,7 +328,6 @@ void G4VeLowEnergyLoss::BuildLabTimeVector(G4PhysicsTable* theDEDXTable,
|
||||
LowEdgeEnergy,tau,Value ;
|
||||
|
||||
G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
|
||||
//const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
|
||||
// low energy part first...
|
||||
losslim = physicsVector->GetValue(tlim,isOut);
|
||||
@@ -498,9 +513,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildInverseRangeTable(G4PhysicsTable* theRan
|
||||
{
|
||||
G4double SmallestRange,BiggestRange ;
|
||||
G4bool isOut ;
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theInverseRangeTable)
|
||||
{ theInverseRangeTable->clearAndDestroy();
|
||||
@@ -594,9 +608,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffATable(G4PhysicsTable* theRang
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "A"
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theRangeCoeffATable)
|
||||
{ theRangeCoeffATable->clearAndDestroy();
|
||||
@@ -657,9 +670,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffBTable(G4PhysicsTable* theRang
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "B"
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theRangeCoeffBTable)
|
||||
{ theRangeCoeffBTable->clearAndDestroy();
|
||||
@@ -719,9 +731,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRang
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "C"
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(theRangeCoeffCTable)
|
||||
{ theRangeCoeffCTable->clearAndDestroy();
|
||||
@@ -806,7 +817,7 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
ipotLogFluct = aMaterial->GetIonisation()->GetLogMeanExcEnergy();
|
||||
}
|
||||
G4double threshold,w1,w2,C,
|
||||
beta2,suma,e0,loss,lossc ,w;
|
||||
beta2,suma,e0,loss,lossc,w;
|
||||
G4double a1,a2,a3;
|
||||
G4int p1,p2,p3;
|
||||
G4int nb;
|
||||
@@ -823,7 +834,7 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
|
||||
// G4cout << "MGP -- Fluc Tkin " << Tkin/keV << " keV " << " MeanLoss = " << MeanLoss/keV << G4endl;
|
||||
|
||||
threshold =((*G4Electron::Electron()).GetCutsInEnergy())[imat];
|
||||
threshold = G4Electron::Electron()->GetEnergyThreshold(aMaterial);
|
||||
G4double rmass = electron_mass_c2/ParticleMass;
|
||||
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
|
||||
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass);
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4VhShellCrossSection
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 20 Oct 2001 V.Ivanchenko 1st implementation
|
||||
// 24 Oct 2001 MGP Minor clean-up
|
||||
// 29 Oct 2001 VI Add delta energy
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4VhShellCrossSection.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4VhShellCrossSection::G4VhShellCrossSection()
|
||||
{ }
|
||||
|
||||
|
||||
G4VhShellCrossSection::~G4VhShellCrossSection()
|
||||
{ }
|
||||
|
||||
|
||||
G4int G4VhShellCrossSection::SelectRandomShell(G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double mass,
|
||||
G4double deltaEnergy) const
|
||||
{
|
||||
G4std::vector<G4double> p = Probabilities(Z,incidentEnergy,mass,deltaEnergy);
|
||||
G4int shell = 0;
|
||||
size_t nShells = p.size();
|
||||
G4double q = G4UniformRand();
|
||||
for (size_t i=0; i<nShells; i++) {
|
||||
|
||||
if (p[i] >= q) {
|
||||
shell = i;
|
||||
break;
|
||||
}
|
||||
q -= p[i];
|
||||
}
|
||||
return shell;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eBremsstrahlungSpectrum.cc,v 1.5 2001/11/30 00:52:52 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4eBremsstrahlungSpectrum
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
// Creation date: 29 September 2001
|
||||
//
|
||||
// Modifications:
|
||||
// 10.10.01 MGP Revision to improve code quality and consistency with design
|
||||
// 15.11.01 VI Update spectrum model Bethe-Haitler spectrum at high energy
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4eBremsstrahlungSpectrum.hh"
|
||||
#include "G4BremsstrahlungParameters.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
|
||||
G4eBremsstrahlungSpectrum::G4eBremsstrahlungSpectrum():
|
||||
G4VEnergySpectrum(),
|
||||
lowestE(0.1*eV),
|
||||
length(15)
|
||||
{
|
||||
theBRparam = new G4BremsstrahlungParameters();
|
||||
xp.clear();
|
||||
for(size_t i=0; i<length; i++) {
|
||||
G4double x = 0.1*((G4double)i);
|
||||
if(i == 0) x = 0.01;
|
||||
if(i == 10) x = 0.95;
|
||||
if(i == 11) x = 0.97;
|
||||
if(i == 12) x = 0.99;
|
||||
if(i == 13) x = 0.995;
|
||||
if(i == 14) x = 1.0;
|
||||
xp.push_back(x);
|
||||
}
|
||||
verbose = 0;
|
||||
}
|
||||
|
||||
|
||||
G4eBremsstrahlungSpectrum::~G4eBremsstrahlungSpectrum()
|
||||
{
|
||||
delete theBRparam;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double e,
|
||||
G4int,
|
||||
const G4ParticleDefinition*) const
|
||||
{
|
||||
G4double tm = G4std::min(tmax, e);
|
||||
G4double t0 = G4std::max(tmin, lowestE);
|
||||
if(t0 >= tm) return 0.0;
|
||||
|
||||
t0 /= e;
|
||||
tm /= e;
|
||||
|
||||
G4double z = lowestE/e;
|
||||
G4double x, y;
|
||||
|
||||
// Below 10 MeV EEDL data base spectrum
|
||||
if(e < 1000000.*MeV) {
|
||||
|
||||
G4int iMax = 16;
|
||||
G4DataVector p;
|
||||
|
||||
// Access parameters
|
||||
for (G4int i=0; i<iMax; i++) {
|
||||
p.push_back(theBRparam->Parameter(i, Z, e));
|
||||
}
|
||||
|
||||
x = IntSpectrum(t0, tm, p);
|
||||
y = IntSpectrum(z, 1.0, p);
|
||||
p.clear();
|
||||
|
||||
|
||||
// Above Bethe-Heitler formula
|
||||
} else {
|
||||
|
||||
x = log(tm/t0) - tm + t0 + 0.375*(tm*tm - t0*t0);
|
||||
y = log(1./z) - 1.0 + z + 0.375*(1. - z*z);
|
||||
|
||||
}
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "tcut(MeV)= " << tmin/MeV
|
||||
<< "; tMax(MeV)= " << tmax/MeV
|
||||
<< "; t0= " << t0
|
||||
<< "; tm= " << tm
|
||||
<< "; xp[0]= " << xp[0]
|
||||
<< "; z= " << z
|
||||
<< "; val= " << x
|
||||
<< "; nor= " << y
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(y > 0.0) x /= y;
|
||||
else x = 0.0;
|
||||
if(x < 0.0) x = 0.0;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double e,
|
||||
G4int,
|
||||
const G4ParticleDefinition*) const
|
||||
{
|
||||
G4double tm = G4std::min(tmax, e);
|
||||
G4double t0 = G4std::max(tmin, lowestE);
|
||||
if(t0 >= tm) return 0.0;
|
||||
|
||||
G4double c = sqrt(theBRparam->ParameterC(Z));
|
||||
|
||||
t0 /= e;
|
||||
tm /= e;
|
||||
|
||||
G4double z = lowestE/e;
|
||||
G4double x, y, f;
|
||||
|
||||
// Below 10 MeV EEDL data base spectrum
|
||||
if(e < 1000000.*MeV) {
|
||||
|
||||
G4int iMax = 16;
|
||||
G4DataVector p;
|
||||
|
||||
// Access parameters
|
||||
for (G4int i=0; i<iMax; i++) {
|
||||
p.push_back(theBRparam->Parameter(i, Z, e));
|
||||
}
|
||||
|
||||
x = AverageValue(t0, tm, p);
|
||||
y = IntSpectrum(z, 1.0, p);
|
||||
f = Function(z, p);
|
||||
p.clear();
|
||||
|
||||
// Above Bethe-Heitler formula
|
||||
} else {
|
||||
|
||||
x = tm - t0 - 0.5*(tm*tm - t0*t0) + 0.25*(tm*tm*tm - t0*t0*t0);
|
||||
y = log(1./z) - 1.0 + z + 0.375*(1. - z*z);
|
||||
f = 1. - x + 0.75*x*x;
|
||||
|
||||
}
|
||||
|
||||
x += 0.5*f*z*(z - c*atan(z/c));
|
||||
|
||||
x *= e;
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "tcut(MeV)= " << tmin/MeV
|
||||
<< "; tMax(MeV)= " << tmax/MeV
|
||||
<< "; e(MeV)= " << e/MeV
|
||||
<< "; t0= " << t0
|
||||
<< "; tm= " << tm
|
||||
<< "; y= " << y
|
||||
<< "; x= " << x
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
if(y > 0.0) x /= y;
|
||||
else x = 0.0;
|
||||
if(x < 0.0) x = 0.0;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double e,
|
||||
G4int,
|
||||
const G4ParticleDefinition*) const
|
||||
{
|
||||
G4double tm = G4std::min(tmax, e);
|
||||
G4double t0 = G4std::max(tmin, lowestE);
|
||||
if(t0 >= tm) return 0.0;
|
||||
|
||||
t0 /= e;
|
||||
tm /= e;
|
||||
|
||||
G4int iMax = 16;
|
||||
G4DataVector p;
|
||||
|
||||
G4double amaj;
|
||||
|
||||
// Below 10 MeV EEDL data base spectrum
|
||||
if(e < 10000000.*MeV) {
|
||||
for (G4int i=0; i<iMax; i++) {
|
||||
p.push_back(theBRparam->Parameter(i, Z, e));
|
||||
}
|
||||
amaj = G4std::max(p[15], 1. - (p[1] - p[0])/9.);
|
||||
|
||||
} else {
|
||||
amaj = 1.0;
|
||||
}
|
||||
|
||||
|
||||
G4double amax = log(tm);
|
||||
G4double amin = log(t0);
|
||||
G4double tgam, q, fun;
|
||||
do {
|
||||
G4double x = amin + G4UniformRand()*(amax - amin);
|
||||
tgam = exp(x);
|
||||
if(e < 10.*MeV) {
|
||||
fun = Function(tgam, p);
|
||||
} else {
|
||||
fun = 1. - tgam + 0.75*tgam*tgam;
|
||||
}
|
||||
if(fun > amaj) {
|
||||
G4cout << "WARNING in G4eBremsstrahlungSpectrum::SampleEnergy:"
|
||||
<< " Majoranta " << amaj
|
||||
<< " < " << fun
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
q = amaj * G4UniformRand();
|
||||
} while (q > fun);
|
||||
|
||||
tgam *= e;
|
||||
|
||||
p.clear();
|
||||
|
||||
return tgam;
|
||||
}
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
|
||||
G4double xMax,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
G4double x1 = G4std::min(xMin, xp[0]);
|
||||
G4double x2 = G4std::min(xMax, xp[0]);
|
||||
G4double z1 = x1;
|
||||
G4double z2 = x2;
|
||||
G4double sum = 0.0;
|
||||
|
||||
if(x1 < x2) {
|
||||
G4double k = (p[1] - p[0])/0.09;
|
||||
sum += (1. - k*xp[0])*log(x2/x1) + k*(x2 - x1);
|
||||
}
|
||||
|
||||
for (size_t i=0; i<length-1; i++) {
|
||||
x1 = G4std::max(xMin, xp[i]);
|
||||
x2 = G4std::min(xMax, xp[i+1]);
|
||||
if(x1 < x2) {
|
||||
z1 = p[i];
|
||||
z2 = p[i+1];
|
||||
sum += z2 - z1 + log(x2/x1)*(z1*x2 - z2*x1)/(x2 - x1);
|
||||
}
|
||||
}
|
||||
if(sum < 0.0) sum = 0.0;
|
||||
return sum;
|
||||
}
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
|
||||
G4double xMax,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
G4double x1 = G4std::min(xMin, xp[0]);
|
||||
G4double x2 = G4std::min(xMax, xp[0]);
|
||||
G4double z1 = x1;
|
||||
G4double z2 = x2;
|
||||
G4double sum = 0.0;
|
||||
|
||||
if(x1 < x2) {
|
||||
G4double k = (p[1] - p[0])/0.09;
|
||||
sum += (z2 - z1)*(1. - k*xp[0]);
|
||||
z1 *= x1;
|
||||
z2 *= x2;
|
||||
sum += 0.5*k*(z1 - z2);
|
||||
}
|
||||
|
||||
for (size_t i=0; i<length-1; i++) {
|
||||
x1 = G4std::max(xMin, xp[i]);
|
||||
x2 = G4std::min(xMax, xp[i+1]);
|
||||
if(x1 < x2) {
|
||||
z1 = p[i];
|
||||
z2 = p[i+1];
|
||||
sum += 0.5*(z2 - z1)*(x2 + x1) + z1*x2 - z2*x1;
|
||||
}
|
||||
}
|
||||
if(sum < 0.0) sum = 0.0;
|
||||
return sum;
|
||||
}
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::Function(G4double x,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
G4double f = 0.0;
|
||||
|
||||
if(x <= xp[0]) {
|
||||
f = 1. + (p[1] - p[0])*(x - xp[0])/0.09;
|
||||
|
||||
} else {
|
||||
|
||||
for (size_t i=0; i<length-1; i++) {
|
||||
|
||||
if(x <= xp[i+1] && x >= xp[i]) {
|
||||
f = p[i] + (p[i+1] - p[i])*(x - xp[i])/(xp[i+1] - xp[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(f < 0.0) f = 0.0;
|
||||
return f;
|
||||
}
|
||||
|
||||
void G4eBremsstrahlungSpectrum::PrintData() const
|
||||
{ theBRparam->PrintData(); }
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eIonisationCrossSectionHandler.cc,v 1.6 2001/11/29 19:01:37 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4eIonisationCrossSectionHandler
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
// Creation date: 25 Sept 2001
|
||||
//
|
||||
// Modifications:
|
||||
// 10 Oct 2001 M.G. Pia Revision to improve code quality and consistency with design
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4eIonisationCrossSectionHandler.hh"
|
||||
#include "G4VEnergySpectrum.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4SemiLogInterpolation.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
|
||||
|
||||
G4eIonisationCrossSectionHandler::G4eIonisationCrossSectionHandler(
|
||||
const G4VEnergySpectrum* spec, G4VDataSetAlgorithm* alg,
|
||||
G4double emin, G4double emax, G4int nbin)
|
||||
: G4VCrossSectionHandler(),
|
||||
theParam(spec)
|
||||
{
|
||||
G4VCrossSectionHandler::Initialise(alg, emin, emax, nbin);
|
||||
interp = new G4SemiLogInterpolation();
|
||||
}
|
||||
|
||||
|
||||
G4eIonisationCrossSectionHandler::~G4eIonisationCrossSectionHandler()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
|
||||
G4std::vector<G4VEMDataSet*>* G4eIonisationCrossSectionHandler::BuildCrossSectionsForMaterials(
|
||||
const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
|
||||
G4std::vector<G4VEMDataSet*>* set = new G4std::vector<G4VEMDataSet*>;
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* cs;
|
||||
G4int nOfBins = energyVector.size();
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4VCrossSectionHandler::G4VCrossSectionHandler - no MaterialTable found)");
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material = (*materialTable)[m];
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
//const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
const G4double* nAtomsPerVolume = material->GetAtomicNumDensityVector();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
G4double tcut = (*energyCuts)[m];
|
||||
|
||||
G4VDataSetAlgorithm* algo = interp->Clone();
|
||||
G4VEMDataSet* setForMat = new G4CompositeEMDataSet(algo,1.,1.);
|
||||
|
||||
for (G4int i=0; i<nElements; i++) {
|
||||
|
||||
G4int Z = (G4int) (*elementVector)[i]->GetZ();
|
||||
G4int nShells = NumberOfComponents(Z);
|
||||
energies = new G4DataVector;
|
||||
cs = new G4DataVector;
|
||||
G4double density = nAtomsPerVolume[i];
|
||||
|
||||
for (G4int bin=0; bin<nOfBins; bin++) {
|
||||
|
||||
G4double e = energyVector[bin];
|
||||
energies->push_back(e);
|
||||
G4double value = 0.0;
|
||||
|
||||
if(e > tcut) {
|
||||
for (G4int n=0; n<nShells; n++) {
|
||||
G4double cross = FindValue(Z, e, n);
|
||||
G4double p = theParam->Probability(Z, tcut, e, e, n);
|
||||
value += cross * p * density;
|
||||
/*
|
||||
G4cout << "G4eIonisationCrossSectionHandler: e= " << e
|
||||
<< " n= " << n
|
||||
<< " cross= " << cross
|
||||
<< " p= " << p
|
||||
<< " value= " << value
|
||||
<< G4endl;
|
||||
*/
|
||||
}
|
||||
}
|
||||
cs->push_back(value);
|
||||
}
|
||||
G4VDataSetAlgorithm* algo = interp->Clone();
|
||||
G4VEMDataSet* elSet = new G4EMDataSet(i,energies,cs,algo,1.,1.);
|
||||
setForMat->AddComponent(elSet);
|
||||
}
|
||||
set->push_back(setForMat);
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eIonisationParameters.cc,v 1.17 2001/11/30 00:52:52 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 31 Jul 2001 MGP Created, with dummy implementation
|
||||
// 12.09.01 V.Ivanchenko Add param and interpolation of parameters
|
||||
// 04.10.01 V.Ivanchenko Add BindingEnergy method
|
||||
// 25.10.01 MGP Many bug fixes, mostly related to the
|
||||
// management of pointers
|
||||
// 29.11.01 V.Ivanchenko New parametrisation + Excitation
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4eIonisationParameters.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "g4std/fstream"
|
||||
#include "g4std/strstream"
|
||||
|
||||
|
||||
G4eIonisationParameters:: G4eIonisationParameters(G4int minZ, G4int maxZ)
|
||||
: zMin(minZ), zMax(maxZ),
|
||||
length(7)
|
||||
{
|
||||
LoadData();
|
||||
}
|
||||
|
||||
|
||||
G4eIonisationParameters::~G4eIonisationParameters()
|
||||
{
|
||||
// Reset the map of data sets: remove the data sets from the map
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
|
||||
|
||||
for (pos = param.begin(); pos != param.end(); ++pos)
|
||||
{
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
for (pos = excit.begin(); pos != excit.end(); ++pos)
|
||||
{
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
activeZ.clear();
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationParameters::Parameter(G4int Z, G4int shellIndex,
|
||||
G4int parameterIndex,
|
||||
G4double e) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
G4int id = Z*20 + parameterIndex;
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = param.find(id);
|
||||
if (pos!= param.end()) {
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
G4int nShells = dataSet->NumberOfComponents();
|
||||
|
||||
if(shellIndex < nShells) {
|
||||
const G4VEMDataSet* component = dataSet->GetComponent(shellIndex);
|
||||
const G4DataVector ener = component->GetEnergies(0);
|
||||
G4double ee = G4std::max(ener.front(),G4std::min(ener.back(),e));
|
||||
value = component->FindValue(ee);
|
||||
} else {
|
||||
G4cout << "WARNING: G4IonisationParameters::FindParameter "
|
||||
<< "has no parameters for shell= " << shellIndex
|
||||
<< "; Z= " << Z
|
||||
<< G4endl;
|
||||
}
|
||||
} else {
|
||||
G4cout << "WARNING: G4IonisationParameters::Parameter "
|
||||
<< "did not find ID = "
|
||||
<< shellIndex << G4endl;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
G4double G4eIonisationParameters::Excitation(G4int Z, G4double e) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = excit.find(Z);
|
||||
if (pos!= excit.end()) {
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
|
||||
const G4DataVector ener = dataSet->GetEnergies(0);
|
||||
G4double ee = G4std::max(ener.front(),G4std::min(ener.back(),e));
|
||||
value = dataSet->FindValue(ee);
|
||||
} else {
|
||||
G4cout << "WARNING: G4IonisationParameters::Excitation "
|
||||
<< "did not find ID = "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void G4eIonisationParameters::LoadData()
|
||||
{
|
||||
// ---------------------------------------
|
||||
// Please document what are the parameters
|
||||
// ---------------------------------------
|
||||
|
||||
// define active elements
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4eIonisationParameters: no MaterialTable found)");
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const size_t nElements = material->GetNumberOfElements();
|
||||
|
||||
for (size_t iEl=0; iEl<nElements; iEl++) {
|
||||
G4Element* element = (*elementVector)[iEl];
|
||||
G4double Z = element->GetZ();
|
||||
if (!(activeZ.contains(Z))) {
|
||||
activeZ.push_back(Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4eIonisationParameters - G4LEDATA environment variable not set";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString(path);
|
||||
pathString += "/ioni/io-sp-";
|
||||
|
||||
G4double energy, sum;
|
||||
|
||||
size_t nZ = activeZ.size();
|
||||
|
||||
for (size_t i=0; i<nZ; i++) {
|
||||
|
||||
G4int Z = (G4int)activeZ[i];
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
ost << pathString << Z << ".dat";
|
||||
G4String name(nameChar);
|
||||
|
||||
G4std::ifstream file(name);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (! (lsdp->is_open()) ) {
|
||||
G4String excep = "G4IonisationParameters - data file: "
|
||||
+ name + " not found";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
// - MGP - Please add some documentation about the parameters read
|
||||
// The file is organized into...:
|
||||
// 1st column is the energy
|
||||
// The file terminates with the pattern: -1 -1
|
||||
|
||||
G4std::vector<G4VEMDataSet*> p;
|
||||
for (size_t k=0; k<length; k++)
|
||||
{
|
||||
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
|
||||
G4VEMDataSet* composite = new G4CompositeEMDataSet(inter,1.,1.);
|
||||
p.push_back(composite);
|
||||
}
|
||||
|
||||
G4int shell = 0;
|
||||
G4std::vector<G4DataVector*> a;
|
||||
for (size_t j=0; j<length; j++)
|
||||
{
|
||||
G4DataVector* aa = new G4DataVector();
|
||||
a.push_back(aa);
|
||||
}
|
||||
G4DataVector e;
|
||||
e.clear();
|
||||
do {
|
||||
file >> energy >> sum;
|
||||
if (energy == -2) break;
|
||||
|
||||
if (energy > -1) {
|
||||
e.push_back(energy);
|
||||
a[0]->push_back(sum);
|
||||
for (size_t j=0; j<length-1; j++) {
|
||||
G4double qRead;
|
||||
file >> qRead;
|
||||
a[j + 1]->push_back(qRead);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// End of set for a shell, fill the map
|
||||
for (size_t k=0; k<length; k++) {
|
||||
|
||||
// G4int id = Z*20 + k;
|
||||
G4VDataSetAlgorithm* interp = new G4LogLogInterpolation();
|
||||
G4DataVector* eVector = new G4DataVector;
|
||||
size_t eSize = e.size();
|
||||
for (size_t s=0; s<eSize; s++) {
|
||||
eVector->push_back(e[s]);
|
||||
}
|
||||
G4VEMDataSet* set = new G4EMDataSet(shell,eVector,a[k],interp,1.,1.);
|
||||
|
||||
p[k]->AddComponent(set);
|
||||
}
|
||||
|
||||
// clear vectors
|
||||
for (size_t j2=0; j2<length; j2++) {
|
||||
a[j2] = new G4DataVector();
|
||||
}
|
||||
shell++;
|
||||
e.clear();
|
||||
}
|
||||
} while (energy > -2);
|
||||
|
||||
file.close();
|
||||
|
||||
for (size_t kk=0; kk<length; kk++)
|
||||
{
|
||||
G4int id = Z*20 + kk;
|
||||
param[id] = p[kk];
|
||||
}
|
||||
}
|
||||
|
||||
G4String pathString_a(path);
|
||||
G4String name_a = pathString_a + "/ioni/io-ex-av.dat";
|
||||
G4std::ifstream file_a(name_a);
|
||||
G4std::filebuf* lsdp_a = file_a.rdbuf();
|
||||
G4String pathString_b(path);
|
||||
G4String name_b = pathString_b + "/ioni/io-ex-sig.dat";
|
||||
G4std::ifstream file_b(name_b);
|
||||
G4std::filebuf* lsdp_b = file_b.rdbuf();
|
||||
|
||||
if (! (lsdp_a->is_open()) ) {
|
||||
G4String excep = G4String("G4eIonisationParameters: cannot open file ")
|
||||
+ name_a;
|
||||
G4Exception(excep);
|
||||
}
|
||||
if (! (lsdp_b->is_open()) ) {
|
||||
G4String excep = G4String("G4eIonisationParameters: cannot open file ")
|
||||
+ name_b;
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
// 2nd column is the corresponding value
|
||||
// The file terminates with the pattern: -1 -1
|
||||
// -2 -2
|
||||
|
||||
G4double ener, ener1, sig, sig1;
|
||||
G4int z = 0;
|
||||
|
||||
G4DataVector e;
|
||||
e.clear();
|
||||
G4DataVector d;
|
||||
d.clear();
|
||||
|
||||
do {
|
||||
file_a >> ener >> sig;
|
||||
file_b >> ener1 >> sig1;
|
||||
if(ener != ener1) {
|
||||
G4cout << "G4eIonisationParameters: problem in excitation data "
|
||||
<< "ener= " << ener
|
||||
<< " ener1= " << ener1
|
||||
<< G4endl;
|
||||
}
|
||||
// End of file
|
||||
if (ener == -2) {
|
||||
break;
|
||||
|
||||
// End of next element
|
||||
} else if (ener == -1) {
|
||||
|
||||
z++;
|
||||
G4double Z = (G4double)z;
|
||||
|
||||
// fill map if Z is used
|
||||
if (activeZ.contains(Z)) {
|
||||
|
||||
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
|
||||
G4DataVector* eVector = new G4DataVector;
|
||||
G4DataVector* dVector = new G4DataVector;
|
||||
size_t eSize = e.size();
|
||||
for (size_t s=0; s<eSize; s++) {
|
||||
eVector->push_back(e[s]);
|
||||
dVector->push_back(d[s]);
|
||||
}
|
||||
G4VEMDataSet* set = new G4EMDataSet(z,eVector,dVector,inter,1.,1.);
|
||||
excit[z] = set;
|
||||
}
|
||||
e.clear();
|
||||
d.clear();
|
||||
|
||||
} else {
|
||||
|
||||
e.push_back(ener);
|
||||
d.push_back(sig1*sig*barn*MeV);
|
||||
}
|
||||
} while (ener != -2);
|
||||
|
||||
file_a.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4eIonisationParameters::PrintData() const
|
||||
{
|
||||
G4cout << G4endl;
|
||||
G4cout << "===== G4eIonisationParameters =====" << G4endl;
|
||||
G4cout << G4endl;
|
||||
|
||||
size_t nZ = activeZ.size();
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
for (size_t i=0; i<nZ; i++) {
|
||||
G4int Z = (G4int)activeZ[i];
|
||||
|
||||
for (size_t j=0; j<length; j++) {
|
||||
|
||||
G4int index = Z*20 + j;
|
||||
|
||||
pos = param.find(index);
|
||||
if (pos!= param.end()) {
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
size_t nShells = dataSet->NumberOfComponents();
|
||||
|
||||
for (size_t k=0; k<nShells; k++) {
|
||||
|
||||
G4cout << "===== Z= " << Z << " shell= " << k
|
||||
<< " parameter[" << j << "] ====="
|
||||
<< G4endl;
|
||||
const G4VEMDataSet* comp = dataSet->GetComponent(k);
|
||||
comp->PrintData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
G4cout << "====================================" << G4endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eIonisationSpectrum.cc,v 1.12 2001/12/04 11:34:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4eIonisationSpectrum
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
// Creation date: 29 September 2001
|
||||
//
|
||||
// Modifications:
|
||||
// 10.10.2001 MGP Revision to improve code quality and
|
||||
// consistency with design
|
||||
// 02.11.2001 VI Optimize sampling of energy
|
||||
// 29.11.2001 VI New parametrisation
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "G4eIonisationSpectrum.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
#include "G4eIonisationParameters.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
|
||||
G4eIonisationSpectrum::G4eIonisationSpectrum():G4VEnergySpectrum(),
|
||||
lowestE(0.1*eV),
|
||||
verbose(0)
|
||||
{
|
||||
theParam = new G4eIonisationParameters();
|
||||
}
|
||||
|
||||
|
||||
G4eIonisationSpectrum::~G4eIonisationSpectrum()
|
||||
{
|
||||
delete theParam;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationSpectrum::Probability(G4int Z,
|
||||
G4double tMin,
|
||||
G4double tMax,
|
||||
G4double e,
|
||||
G4int shell,
|
||||
const G4ParticleDefinition* part) const
|
||||
{
|
||||
// Please comment what Probability does and what are the three
|
||||
// functions mentioned below
|
||||
// Describe the algorithms used
|
||||
|
||||
G4double eMax = MaxEnergyOfSecondaries(e);
|
||||
G4double t0 = G4std::max(tMin, lowestE);
|
||||
G4double tm = G4std::min(tMax, eMax);
|
||||
if(t0 >= tm) return 0.0;
|
||||
|
||||
G4double bindingEnergy = (G4AtomicTransitionManager::Instance())->
|
||||
Shell(Z, shell)->BindingEnergy();
|
||||
|
||||
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/(e + bindingEnergy));
|
||||
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/(e + bindingEnergy));
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4eIonisationSpectrum::Probability: Z= " << Z
|
||||
<< "; shell= " << shell
|
||||
<< "; E(keV)= " << e/keV
|
||||
<< "; x1= " << x1
|
||||
<< "; x2= " << x2
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4int iMax = 7;
|
||||
G4DataVector p;
|
||||
|
||||
// Access parameters
|
||||
for (G4int i=0; i<iMax; i++)
|
||||
{
|
||||
p.push_back(theParam->Parameter(Z, shell, i, e));
|
||||
}
|
||||
|
||||
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
|
||||
p.push_back((2.0*g - 1.0)/(g*g));
|
||||
|
||||
G4double val = IntSpectrum(x1, x2, p);
|
||||
G4double x0 = (lowestE + bindingEnergy)/(e + bindingEnergy);
|
||||
G4double nor = IntSpectrum(x0, 0.5, p);
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "tcut= " << tMin
|
||||
<< "; tMax= " << tMax
|
||||
<< "; x0= " << x0
|
||||
<< "; x1= " << x1
|
||||
<< "; x2= " << x2
|
||||
<< "; val= " << val
|
||||
<< "; nor= " << nor
|
||||
<< "; sum= " << p[0]
|
||||
<< "; a= " << p[1]
|
||||
<< "; b= " << p[2]
|
||||
<< "; c= " << p[3]
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
p.clear();
|
||||
|
||||
if(nor > 0.0) val /= nor;
|
||||
else val = 0.0;
|
||||
if(val < 0.0) val = 0.0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationSpectrum::AverageEnergy(G4int Z,
|
||||
G4double tMin,
|
||||
G4double tMax,
|
||||
G4double e,
|
||||
G4int shell,
|
||||
const G4ParticleDefinition* part) const
|
||||
{
|
||||
// Please comment what AverageEnergy does and what are the three
|
||||
// functions mentioned below
|
||||
// Describe the algorithms used
|
||||
|
||||
G4double eMax = MaxEnergyOfSecondaries(e);
|
||||
G4double t0 = G4std::max(tMin, lowestE);
|
||||
G4double tm = G4std::min(tMax, eMax);
|
||||
if(t0 >= tm) return 0.0;
|
||||
|
||||
G4double bindingEnergy = (G4AtomicTransitionManager::Instance())->
|
||||
Shell(Z, shell)->BindingEnergy();
|
||||
|
||||
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/(e + bindingEnergy));
|
||||
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/(e + bindingEnergy));
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4eIonisationSpectrum::AverageEnergy: Z= " << Z
|
||||
<< "; shell= " << shell
|
||||
<< "; E(keV)= " << e/keV
|
||||
<< "; bindingE(keV)= " << bindingEnergy/keV
|
||||
<< "; x1= " << x1
|
||||
<< "; x2= " << x2
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4int iMax = 7;
|
||||
G4DataVector p;
|
||||
|
||||
// Access parameters
|
||||
for (G4int i=0; i<iMax; i++)
|
||||
{
|
||||
p.push_back(theParam->Parameter(Z, shell, i, e));
|
||||
}
|
||||
|
||||
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
|
||||
p.push_back((2.0*g - 1.0)/(g*g));
|
||||
|
||||
G4double val = AverageValue(x1, x2, p);
|
||||
G4double x0 = (lowestE + bindingEnergy)/(e + bindingEnergy);
|
||||
G4double nor = IntSpectrum(x0, 0.5, p);
|
||||
val *= (e + bindingEnergy);
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "tcut(MeV)= " << tMin/MeV
|
||||
<< "; tMax(MeV)= " << tMax/MeV
|
||||
<< "; x0= " << x0
|
||||
<< "; x1= " << x1
|
||||
<< "; x2= " << x2
|
||||
<< "; val= " << val
|
||||
<< "; nor= " << nor
|
||||
<< "; sum= " << p[0]
|
||||
<< "; a= " << p[1]
|
||||
<< "; b= " << p[2]
|
||||
<< "; c= " << p[3]
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
p.clear();
|
||||
|
||||
if(nor > 0.0) val /= nor;
|
||||
else val = 0.0;
|
||||
if(val < 0.0) val = 0.0;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationSpectrum::SampleEnergy(G4int Z,
|
||||
G4double tMin,
|
||||
G4double tMax,
|
||||
G4double e,
|
||||
G4int shell,
|
||||
const G4ParticleDefinition* part) const
|
||||
{
|
||||
// Please comment what SampleEnergy does
|
||||
G4double tDelta = 0.0;
|
||||
G4double t0 = G4std::max(tMin, lowestE);
|
||||
G4double tm = G4std::min(tMax, MaxEnergyOfSecondaries(e));
|
||||
if(t0 > tm) return tDelta;
|
||||
|
||||
G4double bindingEnergy = (G4AtomicTransitionManager::Instance())->
|
||||
Shell(Z, shell)->BindingEnergy();
|
||||
|
||||
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/(e + bindingEnergy));
|
||||
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/(e + bindingEnergy));
|
||||
if(x1 >= x2) return tDelta;
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "G4eIonisationSpectrum::SampleEnergy: Z= " << Z
|
||||
<< "; shell= " << shell
|
||||
<< "; E(keV)= " << e/keV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Access parameters
|
||||
G4int iMax = 7;
|
||||
G4DataVector p;
|
||||
|
||||
// Access parameters
|
||||
for (G4int i=0; i<iMax; i++)
|
||||
{
|
||||
p.push_back(theParam->Parameter(Z, shell, i, e));
|
||||
}
|
||||
|
||||
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
|
||||
p.push_back((2.0*g - 1.0)/(g*g));
|
||||
|
||||
|
||||
G4double aria1 = 0.0;
|
||||
G4double a1 = G4std::min(x1,p[6]);
|
||||
G4double a2 = G4std::min(x2,p[6]);
|
||||
if(a1 < a2) aria1 = IntSpectrum(a1, a2, p);
|
||||
G4double aria2 = 0.0;
|
||||
G4double a3 = G4std::max(x1,p[6]);
|
||||
G4double a4 = G4std::max(x2,p[6]);
|
||||
if(a3 < a4) aria2 = IntSpectrum(a3, a4, p);
|
||||
|
||||
G4double aria = (aria1 + aria2)*G4UniformRand();
|
||||
G4double amaj, fun, q, x;
|
||||
|
||||
//======= First aria to sample =====
|
||||
|
||||
if(aria <= aria1) {
|
||||
|
||||
amaj = p[4];
|
||||
a1 = 1./a1;
|
||||
a2 = 1./a2;
|
||||
|
||||
//======= Second aria to sample =====
|
||||
|
||||
} else {
|
||||
|
||||
amaj = p[5];
|
||||
a1 = 1./a3;
|
||||
a2 = 1./a4;
|
||||
}
|
||||
amaj *= 1.25;
|
||||
|
||||
do {
|
||||
|
||||
x = 1./(a2 + G4UniformRand()*(a1 - a2));
|
||||
fun = Function(x, p);
|
||||
|
||||
if(fun > amaj) {
|
||||
G4cout << "WARNING in G4eIonisationSpectrum::SampleEnergy:"
|
||||
<< " Majoranta " << amaj
|
||||
<< " < " << fun
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
q = amaj*G4UniformRand();
|
||||
|
||||
} while (q >= fun);
|
||||
|
||||
p.clear();
|
||||
|
||||
tDelta = x*(e + bindingEnergy) - bindingEnergy;
|
||||
|
||||
if(verbose > 1) {
|
||||
G4cout << "tcut(MeV)= " << tMin/MeV
|
||||
<< "; tMax(MeV)= " << tMax/MeV
|
||||
<< "; x1= " << x1
|
||||
<< "; x2= " << x2
|
||||
<< "; a1= " << a1
|
||||
<< "; a2= " << a2
|
||||
<< "; x= " << x
|
||||
<< "; be= " << bindingEnergy
|
||||
<< "; e= " << e
|
||||
<< "; tDelta= " << tDelta
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
return tDelta;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationSpectrum::IntSpectrum(G4double xMin,
|
||||
G4double xMax,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
// Please comment what IntSpectrum does
|
||||
G4double x1 = 1./xMin;
|
||||
G4double x2 = 1./xMax;
|
||||
G4double x = x1 - x2 - p[7]*log(xMax/xMin) + (1. - p[7])*(xMax - xMin)
|
||||
+ 1./(1. - xMax) - 1./(1. - xMin)
|
||||
+ p[7]*log((1. - xMax)/(1. - xMin))
|
||||
+ 0.5*p[1]*p[3]*(x1*x1 - x2*x2);
|
||||
|
||||
if(x < 0.0) x = 0.0;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationSpectrum::AverageValue(G4double xMin,
|
||||
G4double xMax,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
|
||||
// G4double x1 = 1.;
|
||||
// G4double x2 = 1.;
|
||||
G4double x = log(xMax/xMin)
|
||||
+ 0.5*(1. - p[7])*(xMax*xMax - xMin*xMin)
|
||||
+ 1./(1. - xMax) - 1./(1. - xMin)
|
||||
+ (1. + p[7])*log((1. - xMax)/(1. - xMin))
|
||||
+ p[1]*p[3]*(1./xMin - 1./xMax);
|
||||
|
||||
if(x < 0.0) x = 0.0;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eIonisationSpectrum::Function(G4double x,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
// Please comment what Function does
|
||||
|
||||
|
||||
// G4double x1 = 1.0;
|
||||
G4double f = 1.0 - p[7]*x + x*x*(1.0 - p[7]
|
||||
+ (1.0/(1.0 - x) - p[7])/(1.0 - x) )
|
||||
+ p[1]*p[3]/x;
|
||||
|
||||
if(f < 0.0) f = 0.0;
|
||||
return f;
|
||||
}
|
||||
|
||||
G4double G4eIonisationSpectrum::Excitation(G4int Z, G4double e) const
|
||||
{
|
||||
return theParam->Excitation(Z, e);
|
||||
}
|
||||
|
||||
void G4eIonisationSpectrum::PrintData() const
|
||||
{
|
||||
theParam->PrintData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eLowEnergyLoss.cc,v 1.9.2.2 2001/06/28 20:19:32 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// $Id: G4eLowEnergyLoss.cc,v 1.23 2001/11/23 11:45:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -32,7 +32,6 @@
|
||||
// ---------- G4eLowEnergyLoss physics process -----------
|
||||
// by Laszlo Urban, 20 March 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
// It calculates the energy loss of e+/e-.
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
@@ -48,7 +47,14 @@
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// 11/04/00: Bug fix in dE/dx fluctuation simulation, Veronique Lefebure
|
||||
// 19-09-00 change of fluctuation sampling V.Ivanchenko
|
||||
// 20/09/00 update fluctuations V.Ivanchenko
|
||||
// 20/09/00 update fluctuations V.Ivanchenko
|
||||
// 18/10/01 add fluorescence AlongStepDoIt V.Ivanchenko
|
||||
// 18/10/01 Revision to improve code quality and consistency with design, MGP
|
||||
// 19/10/01 update according to new design, V.Ivanchenko
|
||||
// 24/10/01 MGP - Protection against negative energy loss in AlongStepDoIt
|
||||
// 26/10/01 VI Clean up access to deexcitation
|
||||
// 23/11/01 VI Move static member-functions from header to source
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4eLowEnergyLoss.hh"
|
||||
@@ -137,6 +143,55 @@ G4eLowEnergyLoss::~G4eLowEnergyLoss()
|
||||
}
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::SetNbOfProcesses(G4int nb)
|
||||
{
|
||||
NbOfProcesses=nb;
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::PlusNbOfProcesses()
|
||||
{
|
||||
NbOfProcesses++;
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::MinusNbOfProcesses()
|
||||
{
|
||||
NbOfProcesses--;
|
||||
}
|
||||
|
||||
G4int G4eLowEnergyLoss::GetNbOfProcesses()
|
||||
{
|
||||
return NbOfProcesses;
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::SetLowerBoundEloss(G4double val)
|
||||
{
|
||||
LowerBoundEloss=val;
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::SetUpperBoundEloss(G4double val)
|
||||
{
|
||||
UpperBoundEloss=val;
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::SetNbinEloss(G4int nb)
|
||||
{
|
||||
NbinEloss=nb;
|
||||
}
|
||||
|
||||
G4double G4eLowEnergyLoss::GetLowerBoundEloss()
|
||||
{
|
||||
return LowerBoundEloss;
|
||||
}
|
||||
|
||||
G4double G4eLowEnergyLoss::GetUpperBoundEloss()
|
||||
{
|
||||
return UpperBoundEloss;
|
||||
}
|
||||
|
||||
G4int G4eLowEnergyLoss::GetNbinEloss()
|
||||
{
|
||||
return NbinEloss;
|
||||
}
|
||||
//
|
||||
|
||||
void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
@@ -154,8 +209,7 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
// different processes.
|
||||
//
|
||||
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
// create table for the total energy loss
|
||||
|
||||
@@ -334,15 +388,13 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
// get particle and material pointers from trackData
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double E = aParticle->GetKineticEnergy() ;
|
||||
|
||||
// G4cout << "MGP -- Along eInit " << E/keV << " keV " << G4endl;
|
||||
|
||||
G4Material* aMaterial = trackData.GetMaterial();
|
||||
// G4int index = aMaterial->GetIndex();
|
||||
|
||||
G4double Step = stepData.GetStepLength();
|
||||
|
||||
fParticleChange.Initialize(trackData);
|
||||
aParticleChange.Initialize(trackData);
|
||||
//fParticleChange.Initialize(trackData);
|
||||
|
||||
G4double MeanLoss, finalT;
|
||||
|
||||
@@ -386,18 +438,64 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
if (finalT <= 0. )
|
||||
{
|
||||
finalT = 0.;
|
||||
if (Charge < 0.) fParticleChange.SetStatusChange(fStopAndKill);
|
||||
else fParticleChange.SetStatusChange(fStopButAlive);
|
||||
if (Charge < 0.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
// MGP debug
|
||||
// G4cout << "MGP AlongStepDoIt finalT = " << finalT/keV << " keV" << G4endl;
|
||||
G4double edep = E - finalT;
|
||||
|
||||
aParticleChange.SetEnergyChange(finalT);
|
||||
|
||||
// Deexcitation of ionised atoms
|
||||
G4std::vector<G4DynamicParticle*>* deexcitationProducts =
|
||||
DeexciteAtom(aMaterial,E,edep);
|
||||
|
||||
|
||||
fParticleChange.SetEnergyChange(finalT);
|
||||
fParticleChange.SetLocalEnergyDeposit(E-finalT);
|
||||
size_t nSecondaries = deexcitationProducts->size();
|
||||
aParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
|
||||
if (nSecondaries > 0) {
|
||||
|
||||
return &fParticleChange;
|
||||
const G4StepPoint* preStep = stepData.GetPreStepPoint();
|
||||
const G4StepPoint* postStep = stepData.GetPostStepPoint();
|
||||
G4ThreeVector r = preStep->GetPosition();
|
||||
G4ThreeVector deltaR = postStep->GetPosition();
|
||||
deltaR -= r;
|
||||
G4double t = preStep->GetGlobalTime();
|
||||
G4double deltaT = postStep->GetGlobalTime();
|
||||
deltaT -= t;
|
||||
G4double time, q;
|
||||
G4ThreeVector position;
|
||||
|
||||
for (size_t i=0; i<nSecondaries; i++) {
|
||||
|
||||
G4DynamicParticle* part = (*deexcitationProducts)[i];
|
||||
if (part != 0) {
|
||||
G4double eSecondary = part->GetKineticEnergy();
|
||||
edep -= eSecondary;
|
||||
if (edep > 0.)
|
||||
{
|
||||
q = G4UniformRand();
|
||||
time = deltaT*q + t;
|
||||
position = deltaR*q;
|
||||
position += r;
|
||||
G4Track* newTrack = new G4Track(part, time, position);
|
||||
aParticleChange.AddSecondary(newTrack);
|
||||
}
|
||||
else
|
||||
{
|
||||
edep += eSecondary;
|
||||
delete part;
|
||||
part = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete deexcitationProducts;
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(edep);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 20/07/2000 V.Ivanchenko First implementation
|
||||
// 18/06/2001 V.Ivanchenko Continuation for eff.charge (small change of y)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -210,7 +211,7 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
|
||||
} else {
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
const G4Element* element = (*theElementVector)(iel) ;
|
||||
const G4Element* element = (*theElementVector)[iel] ;
|
||||
G4double z2 = element->GetZ() ;
|
||||
const G4double weight = theAtomicNumDensityVector[iel] ;
|
||||
norm += weight ;
|
||||
@@ -254,7 +255,7 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
|
||||
|
||||
// Slower than Fermi velocity
|
||||
} else {
|
||||
y = 0.75 * vF * (1.0 + 2.0*v1*v1/3.0 + v1*v1*v1*v1/15.0) / (z13*z13) ;
|
||||
y = 0.6923 * vF * (1.0 + 2.0*v1*v1/3.0 + v1*v1*v1*v1/15.0) / (z13*z13) ;
|
||||
}
|
||||
|
||||
G4double y3 = pow(y, 0.3) ;
|
||||
|
||||
@@ -65,6 +65,10 @@
|
||||
// 10 May 2001 V.Ivanchenko Clean up againist Linux compilation with -Wall
|
||||
// 23 May 2001 V.Ivanchenko Minor fix in PostStepDoIt
|
||||
// 07 June 2001 V.Ivanchenko Clean up AntiProtonDEDX + add print out
|
||||
// 18 June 2001 V.Ivanchenko Cleanup print out
|
||||
// 18 Oct. 2001 V.Ivanchenko Add fluorescence
|
||||
// 30 Oct. 2001 V.Ivanchenko Add minGammaEnergy and minElectronEnergy
|
||||
// 07 Dec 2001 V.Ivanchenko Add SetFluorescence method
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -80,6 +84,15 @@
|
||||
#include "G4Material.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4AtomicDeexcitation.hh"
|
||||
#include "G4ShellVacancy.hh"
|
||||
#include "G4hShellCrossSection.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4SemiLogInterpolation.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -98,7 +111,10 @@ G4hLowEnergyIonisation::G4hLowEnergyIonisation(const G4String& processName)
|
||||
nStopping(true),
|
||||
theBarkas(true),
|
||||
theMeanFreePathTable(0),
|
||||
paramStepLimit (0.005)
|
||||
paramStepLimit (0.005),
|
||||
shellVacancy(0),
|
||||
shellCS(0),
|
||||
theFluo(true)
|
||||
{
|
||||
InitializeMe();
|
||||
}
|
||||
@@ -110,11 +126,15 @@ void G4hLowEnergyIonisation::InitializeMe()
|
||||
LowestKineticEnergy = 10.0*eV ;
|
||||
HighestKineticEnergy = 100.0*TeV ;
|
||||
MinKineticEnergy = 10.0*eV ;
|
||||
TotBin = 200 ;
|
||||
TotBin = 200 ;
|
||||
protonLowEnergy = 1.*keV ;
|
||||
protonHighEnergy = 2.*MeV ;
|
||||
antiProtonLowEnergy = 1.*keV ;
|
||||
antiProtonHighEnergy = 2.*MeV ;
|
||||
minGammaEnergy = 25.*keV;
|
||||
minElectronEnergy = 25.*keV;
|
||||
verboseLevel = 0;
|
||||
shellCS = new G4hShellCrossSection();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -132,6 +152,16 @@ G4hLowEnergyIonisation::~G4hLowEnergyIonisation()
|
||||
if(theIonEffChargeModel)delete theIonEffChargeModel;
|
||||
if(theIonChuFluctuationModel)delete theIonChuFluctuationModel;
|
||||
if(theIonYangFluctuationModel)delete theIonYangFluctuationModel;
|
||||
if(shellVacancy) delete shellVacancy;
|
||||
if(shellCS) delete shellCS;
|
||||
cutForDelta.clear();
|
||||
G4int length = zFluoDataVector.size();
|
||||
if(length) {
|
||||
for(G4int i=0; i<length; i++) {
|
||||
delete &(zFluoDataVector[i]);
|
||||
}
|
||||
zFluoDataVector.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -156,10 +186,6 @@ void G4hLowEnergyIonisation::InitializeParametrisation()
|
||||
G4Proton* theProton = G4Proton::Proton();
|
||||
G4AntiProton* theAntiProton = G4AntiProton::AntiProton();
|
||||
|
||||
// cuts for electron
|
||||
G4Electron* theElectron = G4Electron::Electron();
|
||||
deltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
|
||||
|
||||
// Define models for parametrisation of electronic energy losses
|
||||
theBetheBlochModel = new G4hBetheBlochModel("Bethe-Bloch") ;
|
||||
theProtonModel = new G4hParametrisedLossModel(theProtonTable) ;
|
||||
@@ -197,15 +223,55 @@ void G4hLowEnergyIonisation::BuildPhysicsTable(
|
||||
G4cout << "G4hLowEnergyIonisation::BuildPhysicsTable for "
|
||||
<< aParticleType.GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
|
||||
InitializeParametrisation() ;
|
||||
G4Proton* theProton = G4Proton::Proton();
|
||||
G4AntiProton* theAntiProton = G4AntiProton::AntiProton();
|
||||
G4Electron* theElectron = G4Electron::Electron();
|
||||
|
||||
charge = aParticleType.GetPDGCharge()/eplus ;
|
||||
chargeSquare = charge*charge ;
|
||||
|
||||
G4double electronCutInRange = theElectron->GetCuts();
|
||||
// ---- MGP ---- workaround for the deprecated "cuts per material"
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const G4Material* material = (*theMaterialTable)[0];
|
||||
G4double electronCutInRange = G4Electron::Electron()->GetEnergyThreshold(material);
|
||||
// was = G4Electron::Electron()->GetCuts();
|
||||
// ---- MGP ----
|
||||
|
||||
// Define cuts
|
||||
|
||||
// create table
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
cutForDelta.clear();
|
||||
cutForGamma.clear();
|
||||
|
||||
for (G4int j=0; j<numOfMaterials; j++) {
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[j];
|
||||
|
||||
// the cut cannot be below lowest limit
|
||||
G4double tCut = G4Electron::Electron()->GetEnergyThreshold(material);
|
||||
if(tCut > HighestKineticEnergy) tCut = HighestKineticEnergy;
|
||||
|
||||
G4double excEnergy = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
tCut = G4std::max(tCut,excEnergy);
|
||||
cutForDelta.push_back(tCut);
|
||||
|
||||
// the cut cannot be below lowest limit
|
||||
tCut = G4Gamma::Gamma()->GetEnergyThreshold(material);
|
||||
if(tCut > HighestKineticEnergy) tCut = HighestKineticEnergy;
|
||||
tCut = G4std::max(tCut,minGammaEnergy);
|
||||
cutForGamma.push_back(tCut);
|
||||
}
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Cuts are defined " << G4endl;
|
||||
}
|
||||
|
||||
|
||||
if(0.0 < charge)
|
||||
{
|
||||
@@ -235,6 +301,7 @@ void G4hLowEnergyIonisation::BuildPhysicsTable(
|
||||
}
|
||||
|
||||
BuildLambdaTable(aParticleType) ;
|
||||
BuildDataForFluorescence(aParticleType);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4hLowEnergyIonisation::BuildPhysicsTable: "
|
||||
@@ -276,7 +343,7 @@ void G4hLowEnergyIonisation::BuildLossTable(
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
|
||||
// create table
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if ( theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
@@ -344,12 +411,140 @@ void G4hLowEnergyIonisation::BuildLossTable(
|
||||
}
|
||||
|
||||
// now put the loss into the vector
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "E(MeV)= " << lowEdgeEnergy/MeV
|
||||
<< " dE/dx(MeV/mm)= " << ionloss*mm/MeV
|
||||
<< " in " << material->GetName() << G4endl;
|
||||
}
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
}
|
||||
// Insert vector for this material into the table
|
||||
theLossTable->insert(aVector) ;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyIonisation::BuildDataForFluorescence(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4hLowEnergyIonisation::BuildDataForFluorescence for "
|
||||
<< aParticleType.GetParticleName() << " is started" << G4endl;
|
||||
}
|
||||
|
||||
// fill data for fluorescence
|
||||
|
||||
G4double mass = aParticleType.GetPDGMass();
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
|
||||
// create table
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if (shellVacancy != 0) delete shellVacancy;
|
||||
shellVacancy = new G4ShellVacancy();
|
||||
G4DataVector* ksi = 0;
|
||||
G4DataVector* ksi1 = 0;
|
||||
G4DataVector* energy = 0;
|
||||
G4DataVector* energy1 = 0;
|
||||
size_t binForFluo = TotBin/10;
|
||||
G4int length = zFluoDataVector.size();
|
||||
if(length > 0) {
|
||||
for(G4int i=0; i<length; i++) {
|
||||
G4VEMDataSet* x = zFluoDataVector[i];
|
||||
delete x;
|
||||
}
|
||||
zFluoDataVector.clear();
|
||||
}
|
||||
|
||||
G4PhysicsLogVector* bVector = new G4PhysicsLogVector(LowestKineticEnergy,
|
||||
HighestKineticEnergy,
|
||||
binForFluo);
|
||||
G4AtomicTransitionManager* transitionManager =
|
||||
G4AtomicTransitionManager::Instance();
|
||||
|
||||
G4double bindingEnergy;
|
||||
// G4double x;
|
||||
// G4double y;
|
||||
|
||||
// loop for materials
|
||||
for (G4int j=0; j<numOfMaterials; j++) {
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[j];
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
size_t NumberOfElements = material->GetNumberOfElements() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
G4VDataSetAlgorithm* interp = new G4SemiLogInterpolation();
|
||||
G4VEMDataSet* xsis = new G4CompositeEMDataSet(interp, 1., 1.);
|
||||
G4VDataSetAlgorithm* interp1 = new G4SemiLogInterpolation();
|
||||
G4VEMDataSet* xsis1 = new G4CompositeEMDataSet(interp1, 1., 1.);
|
||||
|
||||
G4double tCut = cutForDelta[j];
|
||||
G4double elDensity = 1.;
|
||||
|
||||
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
|
||||
|
||||
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
|
||||
energy = new G4DataVector();
|
||||
ksi = new G4DataVector();
|
||||
energy1= new G4DataVector();
|
||||
ksi1 = new G4DataVector();
|
||||
//if(NumberOfElements > 1)
|
||||
elDensity = theAtomicNumDensityVector[iel];
|
||||
|
||||
for (size_t j = 0; j<binForFluo; j++) {
|
||||
|
||||
G4double tkin = bVector->GetLowEdgeEnergy(j);
|
||||
G4double gamma = tkin/mass + 1.;
|
||||
G4double r = electron_mass_c2/mass;
|
||||
G4double tmax = 2.*mass*r*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
|
||||
G4double cross = 0.;
|
||||
G4double cross1 = 0.;
|
||||
G4double eAverage= 0.;
|
||||
G4int nShells = transitionManager->NumberOfShells(Z);
|
||||
G4double tmin = G4std::min(tCut,tmax);
|
||||
|
||||
for (G4int n=0; n<nShells; n++) {
|
||||
|
||||
bindingEnergy = transitionManager->Shell(Z, n)->BindingEnergy();
|
||||
eAverage += elDensity*log(tmin/bindingEnergy + 1.);
|
||||
cross += elDensity*tmin/((bindingEnergy + tmin)*bindingEnergy);
|
||||
cross1 += elDensity*(tmax - tmin)/
|
||||
((tmax + bindingEnergy)*(tmin + bindingEnergy));
|
||||
}
|
||||
|
||||
energy1->push_back(tkin);
|
||||
ksi1->push_back(cross1);
|
||||
|
||||
if(eAverage > 0.) cross /= eAverage;
|
||||
else cross = 0.;
|
||||
|
||||
energy->push_back(tkin);
|
||||
ksi->push_back(cross);
|
||||
}
|
||||
G4VDataSetAlgorithm* algo = interp->Clone();
|
||||
G4VEMDataSet* set = new G4EMDataSet(Z,energy,ksi,algo,1.,1.);
|
||||
xsis->AddComponent(set);
|
||||
G4VDataSetAlgorithm* algo1 = interp1->Clone();
|
||||
G4VEMDataSet* set1 = new G4EMDataSet(Z,energy1,ksi1,algo1,1.,1.);
|
||||
xsis1->AddComponent(set1);
|
||||
}
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "### Shell inverse cross sections for "
|
||||
<< material->GetName() << G4endl;
|
||||
xsis->PrintData();
|
||||
G4cout << "### Atom cross sections for "
|
||||
<< material->GetName() << G4endl;
|
||||
xsis1->PrintData();
|
||||
}
|
||||
shellVacancy->AddXsiTable(xsis);
|
||||
zFluoDataVector.push_back(xsis1);
|
||||
}
|
||||
delete bVector;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -361,13 +556,19 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
|
||||
// Build mean free path tables for the delta ray production process
|
||||
// tables are built for MATERIALS
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "G4hLowEnergyIonisation::BuildLambdaTable for "
|
||||
<< aParticleType.GetParticleName() << " is started" << G4endl;
|
||||
}
|
||||
|
||||
|
||||
G4double lowEdgeEnergy, value;
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
charge = aParticleType.GetPDGCharge()/eplus ;
|
||||
chargeSquare = charge*charge ;
|
||||
|
||||
//create table
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
@@ -375,11 +576,7 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
|
||||
}
|
||||
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// get electron and particle cuts in kinetic energy
|
||||
|
||||
// deltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
|
||||
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0 ; J < numOfMaterials; J++) {
|
||||
@@ -397,15 +594,13 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
G4double excEnergy = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
// get the electron kinetic energy cut for the actual material,
|
||||
// it will be used in ComputeMicroscopicCrossSection
|
||||
// ( it is the SAME for ALL the ELEMENTS in THIS MATERIAL )
|
||||
// ------------------------------------------------------
|
||||
|
||||
// Cut in Delta energy is limited by exitation energy
|
||||
G4double deltaCut = G4std::max(excEnergy,deltaCutInKineticEnergy[J]) ;
|
||||
G4double deltaCut = cutForDelta[J];
|
||||
|
||||
for ( G4int i = 0 ; i < TotBin ; i++ ) {
|
||||
lowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
@@ -419,7 +614,7 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
|
||||
ComputeMicroscopicCrossSection(
|
||||
aParticleType,
|
||||
lowEdgeEnergy,
|
||||
(*theElementVector)(iel)->GetZ(),
|
||||
(*theElementVector)[iel]->GetZ(),
|
||||
deltaCut ) ;
|
||||
}
|
||||
|
||||
@@ -429,9 +624,10 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
|
||||
|
||||
aVector->PutValue(i, value) ;
|
||||
}
|
||||
|
||||
|
||||
theMeanFreePathTable->insert(aVector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -492,6 +688,33 @@ G4double G4hLowEnergyIonisation::ComputeMicroscopicCrossSection(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4hLowEnergyIonisation::GetMeanFreePath(const G4Track& trackData,
|
||||
G4double previousStepSize,
|
||||
enum G4ForceCondition* condition)
|
||||
{
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
|
||||
G4Material* aMaterial = trackData.GetMaterial() ;
|
||||
G4double meanFreePath;
|
||||
G4bool isOutRange ;
|
||||
|
||||
*condition = NotForced ;
|
||||
|
||||
G4double kineticEnergy = aParticle->GetKineticEnergy() ;
|
||||
|
||||
if(kineticEnergy < LowestKineticEnergy) meanFreePath = DBL_MAX;
|
||||
|
||||
else {
|
||||
if(kineticEnergy > HighestKineticEnergy)
|
||||
kineticEnergy = HighestKineticEnergy ;
|
||||
meanFreePath = ((*theMeanFreePathTable)(aMaterial->GetIndex()))->
|
||||
GetValue(kineticEnergy,isOutRange) ;
|
||||
}
|
||||
|
||||
return meanFreePath ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4hLowEnergyIonisation::GetConstraints(
|
||||
const G4DynamicParticle* particle,
|
||||
const G4Material* material)
|
||||
@@ -569,8 +792,9 @@ G4double G4hLowEnergyIonisation::GetConstraints(
|
||||
// Normal energy
|
||||
} else {
|
||||
|
||||
fRangeNow = G4EnergyLossTables::GetRange(theAntiProton, tscaled, material) ;
|
||||
dx = G4EnergyLossTables::GetRange(theAntiProton, highEnergy, material) ;
|
||||
fRangeNow = G4EnergyLossTables::GetRange(theAntiProton, tscaled,
|
||||
material);
|
||||
dx = G4EnergyLossTables::GetRange(theAntiProton, highEnergy, material);
|
||||
|
||||
if(tscaled > highEnergy) {
|
||||
fdEdx = G4EnergyLossTables::GetDEDX(theAntiProton, tscaled, material)
|
||||
@@ -578,7 +802,7 @@ G4double G4hLowEnergyIonisation::GetConstraints(
|
||||
|
||||
// For Bragg's peak dE/dx is recalculated
|
||||
} else {
|
||||
fdEdx = AntiProtonParametrisedDEDX(material, tscaled) * chargeSquare ;
|
||||
fdEdx = AntiProtonParametrisedDEDX(material, tscaled) * chargeSquare;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -620,6 +844,7 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
|
||||
G4double finalT = 0.0 ;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
|
||||
G4Material* material = trackData.GetMaterial() ;
|
||||
|
||||
// get the actual (true) Step length from stepData
|
||||
@@ -652,9 +877,17 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
|
||||
G4double eFinal = kineticEnergy - step*fdEdx - nloss ;
|
||||
|
||||
if(0.0 < eFinal) {
|
||||
eloss = (fdEdx +
|
||||
ProtonParametrisedDEDX(material,eFinal*massRatio)*chargeSquare)
|
||||
* step * 0.5 ;
|
||||
|
||||
G4double ts = eFinal*massRatio;
|
||||
G4double fdEdx1 = ProtonParametrisedDEDX(material,ts)*chargeSquare;
|
||||
|
||||
// Correction for positive ions
|
||||
//if(theBarkas && 1.0 < charge) {
|
||||
// fdEdx1 += BarkasTerm(material,ts)*(charge -1.0) * chargeSquare ;
|
||||
// fdEdx1 += BlochTerm(material,ts,chargeSquare) ;
|
||||
// fdEdx1 -= BlochTerm(material,ts,1.0) ;
|
||||
// }
|
||||
eloss = (fdEdx + fdEdx1) * step * 0.5 ;
|
||||
} else {
|
||||
eloss = kineticEnergy - nloss ;
|
||||
}
|
||||
@@ -707,29 +940,84 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
|
||||
eloss = step*fdEdx ;
|
||||
}
|
||||
}
|
||||
|
||||
if(eloss < 0.0) eloss = 0.0;
|
||||
|
||||
finalT = kineticEnergy - eloss - nloss ;
|
||||
finalT = kineticEnergy - eloss - nloss;
|
||||
|
||||
if( EnlossFlucFlag && 0.0 < eloss ) {
|
||||
|
||||
// now the electron loss with fluctuation
|
||||
eloss = ElectronicLossFluctuation(particle, material, eloss, step) ;
|
||||
finalT = kineticEnergy - eloss - nloss ;
|
||||
if(eloss < 0.0) eloss = 0.0;
|
||||
finalT = kineticEnergy - eloss - nloss;
|
||||
}
|
||||
|
||||
// stop particle if the kinetic energy <= MinKineticEnergy
|
||||
if (finalT <= MinKineticEnergy )
|
||||
{
|
||||
finalT = 0.0 ;
|
||||
if( "proton" == (particle->GetDefinition()->GetParticleName()) )
|
||||
if (finalT <= MinKineticEnergy ) {
|
||||
|
||||
finalT = 0.0;
|
||||
if( "proton" == (particle->GetDefinition()->GetParticleName()) )
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else
|
||||
else
|
||||
aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalT ) ;
|
||||
aParticleChange.SetLocalEnergyDeposit(kineticEnergy-finalT) ;
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalT );
|
||||
G4double edep = kineticEnergy-finalT;
|
||||
|
||||
// Deexcitation only of ionised atoms
|
||||
eloss = G4std::min(edep, eloss);
|
||||
|
||||
G4double hMass = particle->GetMass();
|
||||
G4std::vector<G4DynamicParticle*>* newpart = 0;
|
||||
G4DynamicParticle* part = 0;
|
||||
|
||||
if(theFluo) newpart = DeexciteAtom(material, kineticEnergy, hMass, eloss);
|
||||
|
||||
if(newpart != 0) {
|
||||
|
||||
size_t nSecondaries = newpart->size();
|
||||
aParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
G4Track* newtrack = 0;
|
||||
const G4StepPoint* preStep = stepData.GetPreStepPoint();
|
||||
const G4StepPoint* postStep = stepData.GetPostStepPoint();
|
||||
G4ThreeVector r = preStep->GetPosition();
|
||||
G4ThreeVector deltaR = postStep->GetPosition();
|
||||
deltaR -= r;
|
||||
G4double t = preStep->GetGlobalTime();
|
||||
G4double deltaT = postStep->GetGlobalTime();
|
||||
deltaT -= t;
|
||||
G4double time, q, e;
|
||||
G4ThreeVector position;
|
||||
|
||||
for(size_t i=0; i<nSecondaries; i++) {
|
||||
|
||||
part = (*newpart)[i];
|
||||
if(part) {
|
||||
|
||||
e = part->GetKineticEnergy();
|
||||
if(e <= edep) {
|
||||
|
||||
edep -= e;
|
||||
q = G4UniformRand();
|
||||
time = deltaT*q + t;
|
||||
position = deltaR*q;
|
||||
position += r;
|
||||
newtrack = new G4Track(part, time, position);
|
||||
aParticleChange.AddSecondary(newtrack);
|
||||
|
||||
} else {
|
||||
|
||||
delete part;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
delete newpart;
|
||||
}
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(edep);
|
||||
return &aParticleChange ;
|
||||
}
|
||||
|
||||
@@ -755,7 +1043,7 @@ G4double G4hLowEnergyIonisation::ProtonParametrisedDEDX(
|
||||
// Delta rays energy
|
||||
eloss -= DeltaRaysEnergy(material,kineticEnergy,proton_mass_c2) ;
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
if(verboseLevel > 2) {
|
||||
G4cout << "p E(MeV)= " << kineticEnergy/MeV
|
||||
<< " dE/dx(MeV/mm)= " << eloss*mm/MeV
|
||||
<< " for " << material->GetName()
|
||||
@@ -805,7 +1093,7 @@ G4double G4hLowEnergyIonisation::AntiProtonParametrisedDEDX(
|
||||
// Delta rays energy
|
||||
eloss -= DeltaRaysEnergy(material,kineticEnergy,proton_mass_c2) ;
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
if(verboseLevel > 2) {
|
||||
G4cout << "pbar E(MeV)= " << kineticEnergy/MeV
|
||||
<< " dE/dx(MeV/mm)= " << eloss*mm/MeV
|
||||
<< " for " << material->GetName()
|
||||
@@ -826,7 +1114,7 @@ G4double G4hLowEnergyIonisation::DeltaRaysEnergy(
|
||||
{
|
||||
G4double dloss = 0.0 ;
|
||||
|
||||
G4double deltaCutNow = deltaCutInKineticEnergy[(material->GetIndex())] ;
|
||||
G4double deltaCutNow = cutForDelta[(material->GetIndex())] ;
|
||||
G4double electronDensity = material->GetElectronDensity();
|
||||
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
@@ -861,58 +1149,43 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
{
|
||||
// Units are expressed in GEANT4 internal units.
|
||||
|
||||
G4double KineticEnergy,TotalEnergy,TotalMomentum,
|
||||
betasquare,MaxKineticEnergyTransfer,
|
||||
G4double KineticEnergy,TotalEnergy,TotalMomentum,betasquare,
|
||||
DeltaKineticEnergy,DeltaTotalMomentum,costheta,sintheta,phi,
|
||||
dirx,diry,dirz,finalKineticEnergy,finalPx,finalPy,finalPz,
|
||||
x,xc,grej,Psquare,Esquare,summass,rate,finalMomentum ;
|
||||
x,xc,grej,Psquare,Esquare,rate,finalMomentum ;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
G4Material* aMaterial = trackData.GetMaterial() ;
|
||||
G4double Eexc = aMaterial->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
// some kinematics
|
||||
|
||||
ParticleMass=aParticle->GetDefinition()->GetPDGMass();
|
||||
KineticEnergy=aParticle->GetKineticEnergy();
|
||||
TotalEnergy=KineticEnergy + ParticleMass ;
|
||||
Psquare=KineticEnergy*(TotalEnergy+ParticleMass) ;
|
||||
Esquare=TotalEnergy*TotalEnergy ;
|
||||
summass = ParticleMass + electron_mass_c2 ;
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection() ;
|
||||
Esquare=TotalEnergy*TotalEnergy;
|
||||
betasquare=Psquare/Esquare;
|
||||
G4ThreeVector ParticleDirection = aParticle->GetMomentumDirection() ;
|
||||
|
||||
// get kinetic energy cut for the electron....
|
||||
G4double DeltaCutInKineticEnergyNow =
|
||||
deltaCutInKineticEnergy[aMaterial->GetIndex()];
|
||||
|
||||
// some kinematics......................
|
||||
G4double gamma= KineticEnergy/ParticleMass + 1.;
|
||||
G4double r = electron_mass_c2/ParticleMass;
|
||||
G4double tmax = 2.*ParticleMass*r*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
|
||||
|
||||
betasquare=Psquare/Esquare ;
|
||||
MaxKineticEnergyTransfer = 2.*electron_mass_c2*Psquare
|
||||
/(summass*summass+2.*electron_mass_c2*KineticEnergy);
|
||||
|
||||
// Validity range for delta electron cross section
|
||||
G4double DeltaCut = G4std::max(DeltaCutInKineticEnergyNow,Eexc);
|
||||
G4double DeltaCut = cutForDelta[aMaterial->GetIndex()];
|
||||
|
||||
// This should not be a case
|
||||
if(DeltaCut >= tmax)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
// sampling kinetic energy of the delta ray
|
||||
|
||||
if( MaxKineticEnergyTransfer <= DeltaCut )
|
||||
{
|
||||
// pathological case (it should not happen ,
|
||||
// there is no change at all).....
|
||||
xc = DeltaCut / tmax;
|
||||
rate = tmax / TotalEnergy;
|
||||
rate = rate*rate ;
|
||||
G4double spin = aParticle->GetDefinition()->GetPDGSpin() ;
|
||||
|
||||
return &aParticleChange;
|
||||
//return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal case ......................................
|
||||
xc = DeltaCut / MaxKineticEnergyTransfer ;
|
||||
rate = MaxKineticEnergyTransfer / TotalEnergy ;
|
||||
rate = rate*rate ;
|
||||
G4double spin = aParticle->GetDefinition()->GetPDGSpin() ;
|
||||
|
||||
// sampling follows ...
|
||||
// sampling follows ...
|
||||
do {
|
||||
x=xc/(1.-(1.-xc)*G4UniformRand());
|
||||
|
||||
@@ -929,13 +1202,10 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
}
|
||||
|
||||
} while( G4UniformRand() > grej );
|
||||
}
|
||||
|
||||
DeltaKineticEnergy = x * MaxKineticEnergyTransfer ;
|
||||
|
||||
if(DeltaKineticEnergy <= 0.)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
DeltaKineticEnergy = x * tmax;
|
||||
|
||||
DeltaTotalMomentum = sqrt(DeltaKineticEnergy * (DeltaKineticEnergy +
|
||||
2. * electron_mass_c2 )) ;
|
||||
TotalMomentum = sqrt(Psquare) ;
|
||||
@@ -950,7 +1220,7 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
|
||||
// direction of the delta electron ........
|
||||
phi = twopi * G4UniformRand() ;
|
||||
sintheta = sqrt((1.+costheta)*(1.-costheta));
|
||||
sintheta = sqrt(1. - costheta*costheta);
|
||||
dirx = sintheta * cos(phi) ;
|
||||
diry = sintheta * sin(phi) ;
|
||||
dirz = costheta ;
|
||||
@@ -968,8 +1238,69 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
|
||||
// fill aParticleChange
|
||||
finalKineticEnergy = KineticEnergy - DeltaKineticEnergy ;
|
||||
G4double Edep = 0 ;
|
||||
|
||||
// Generation of Fluorescence and Auger
|
||||
size_t nSecondaries = 0;
|
||||
size_t totalNumber = 1;
|
||||
G4std::vector<G4DynamicParticle*>* secondaryVector = 0;
|
||||
G4DynamicParticle* aSecondary = 0;
|
||||
G4ParticleDefinition* type = 0;
|
||||
|
||||
// Select atom and shell
|
||||
G4int Z = SelectRandomAtom(aMaterial, KineticEnergy);
|
||||
G4int shell = shellCS->SelectRandomShell(Z, KineticEnergy,
|
||||
ParticleMass,DeltaKineticEnergy);
|
||||
const G4AtomicShell* atomicShell =
|
||||
(G4AtomicTransitionManager::Instance())->Shell(Z, shell);
|
||||
G4double bindingEnergy = atomicShell->BindingEnergy();
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "PostStep Z= " << Z << " shell= " << shell
|
||||
<< " bindingE(keV)= " << bindingEnergy/keV
|
||||
<< " finalE(keV)= " << finalKineticEnergy/keV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Fluorescence data start from element 6
|
||||
|
||||
if (theFluo && Z > 5 && finalKineticEnergy >= bindingEnergy
|
||||
&& (bindingEnergy >= minGammaEnergy
|
||||
|| bindingEnergy >= minElectronEnergy) ) {
|
||||
|
||||
G4int shellId = atomicShell->ShellId();
|
||||
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
|
||||
|
||||
if (secondaryVector != 0) {
|
||||
|
||||
nSecondaries = secondaryVector->size();
|
||||
for (size_t i = 0; i<nSecondaries; i++) {
|
||||
|
||||
aSecondary = (*secondaryVector)[i];
|
||||
if (aSecondary) {
|
||||
|
||||
G4double e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if (e < finalKineticEnergy &&
|
||||
((type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
|
||||
(type == G4Electron::Electron() && e > minElectronEnergy ))) {
|
||||
|
||||
finalKineticEnergy -= e;
|
||||
totalNumber++;
|
||||
|
||||
} else {
|
||||
|
||||
delete aSecondary;
|
||||
(*secondaryVector)[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save delta-electrons
|
||||
|
||||
G4double edep = 0.0;
|
||||
|
||||
if (finalKineticEnergy > MinKineticEnergy)
|
||||
{
|
||||
finalPx = TotalMomentum*ParticleDirection.x()
|
||||
@@ -988,23 +1319,191 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
|
||||
}
|
||||
else
|
||||
{
|
||||
finalKineticEnergy = 0. ;
|
||||
Edep = finalKineticEnergy ;
|
||||
edep = finalKineticEnergy;
|
||||
finalKineticEnergy = 0.;
|
||||
aParticleChange.SetMomentumChange(ParticleDirection.x(),
|
||||
ParticleDirection.y(),ParticleDirection.z());
|
||||
if (aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalKineticEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary( theDeltaRay );
|
||||
aParticleChange.SetLocalEnergyDeposit (Edep);
|
||||
aParticleChange.SetLocalEnergyDeposit (edep);
|
||||
aParticleChange.SetNumberOfSecondaries(totalNumber);
|
||||
aParticleChange.AddSecondary(theDeltaRay);
|
||||
|
||||
// Save Fluorescence and Auger
|
||||
|
||||
if (secondaryVector) {
|
||||
|
||||
for (size_t l = 0; l < nSecondaries; l++) {
|
||||
|
||||
aSecondary = (*secondaryVector)[l];
|
||||
if(aSecondary) aParticleChange.AddSecondary(aSecondary);
|
||||
}
|
||||
delete secondaryVector;
|
||||
}
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4std::vector<G4DynamicParticle*>*
|
||||
G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
|
||||
G4double incidentEnergy,
|
||||
G4double hMass,
|
||||
G4double eLoss)
|
||||
{
|
||||
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "DeexciteAtom: cutForPhotons(keV)= " << minGammaEnergy/keV
|
||||
<< " cutForElectrons(keV)= " << minElectronEnergy/keV
|
||||
<< " eLoss(MeV)= " << eLoss
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(eLoss < minGammaEnergy && eLoss < minElectronEnergy) return 0;
|
||||
|
||||
G4int index = material->GetIndex();
|
||||
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
G4double x = cutForDelta[index]/eexc;
|
||||
G4double deltaEnergy = eexc*(x + 1)*log(x + 1)/x;
|
||||
G4AtomicTransitionManager* transitionManager =
|
||||
G4AtomicTransitionManager::Instance();
|
||||
|
||||
size_t nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
G4bool stop = true;
|
||||
|
||||
for (size_t j=0; j<nElements; j++) {
|
||||
|
||||
G4int Z = (G4int)((*theElementVector)[j]->GetZ());
|
||||
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
|
||||
|
||||
if (Z>5 && (maxE>minGammaEnergy || maxE>minElectronEnergy) ) {
|
||||
stop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(stop) return 0;
|
||||
|
||||
// create vector of tracks of secondary particles
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* partVector =
|
||||
new G4std::vector<G4DynamicParticle*>;
|
||||
G4std::vector<G4DynamicParticle*>* secVector = 0;
|
||||
G4DynamicParticle* aSecondary = 0;
|
||||
G4ParticleDefinition* type = 0;
|
||||
G4double e;
|
||||
G4ThreeVector position;
|
||||
G4int shell, shellId;
|
||||
|
||||
// sample secondaries
|
||||
|
||||
G4double etot = 0.0;
|
||||
G4std::vector<G4int> n = shellVacancy->GenerateNumberOfIonisations(material,
|
||||
incidentEnergy, eLoss);
|
||||
|
||||
for (size_t i=0; i<nElements; i++) {
|
||||
|
||||
size_t nVacancies = n[i];
|
||||
G4int Z = (G4int)((*theElementVector)[i]->GetZ());
|
||||
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
|
||||
|
||||
if (nVacancies && Z>5 && (maxE>minGammaEnergy || maxE>minElectronEnergy)) {
|
||||
for(size_t j=0; j<nVacancies; j++) {
|
||||
|
||||
shell = shellCS->SelectRandomShell(Z,incidentEnergy,hMass,deltaEnergy);
|
||||
shellId = transitionManager->Shell(Z, shell)->ShellId();
|
||||
G4double maxE = transitionManager->Shell(Z, shell)->BindingEnergy();
|
||||
|
||||
if (maxE>minGammaEnergy || maxE>minElectronEnergy ) {
|
||||
secVector = deexcitationManager.GenerateParticles(Z, shellId);
|
||||
} else {
|
||||
secVector = 0;
|
||||
}
|
||||
|
||||
if (secVector) {
|
||||
|
||||
for (size_t l = 0; l<secVector->size(); l++) {
|
||||
|
||||
aSecondary = (*secVector)[l];
|
||||
if(aSecondary) {
|
||||
|
||||
e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if ( etot + e <= eLoss &&
|
||||
(type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
|
||||
(type == G4Electron::Electron() && e > minElectronEnergy)) {
|
||||
|
||||
etot += e;
|
||||
partVector->push_back(aSecondary);
|
||||
|
||||
} else {
|
||||
delete aSecondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete secVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(partVector->empty()) {
|
||||
delete partVector;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return partVector;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4hLowEnergyIonisation::SelectRandomAtom(const G4Material* material,
|
||||
G4double kineticEnergy) const
|
||||
{
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
G4int Z = 0;
|
||||
|
||||
if(nElements == 1) {
|
||||
Z = (G4int)(material->GetZ());
|
||||
return Z;
|
||||
}
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
G4std::vector<G4double> p;
|
||||
G4int index = material->GetIndex();
|
||||
|
||||
G4double norm = 0.0;
|
||||
for (G4int j=0; j<nElements; j++) {
|
||||
|
||||
const G4VEMDataSet* set = (zFluoDataVector[index])->GetComponent(j);
|
||||
G4double cross = set->FindValue(kineticEnergy);
|
||||
|
||||
p.push_back(cross);
|
||||
norm += cross;
|
||||
}
|
||||
|
||||
G4double q = norm*G4UniformRand();
|
||||
|
||||
for (G4int i=0; i<nElements; i++) {
|
||||
|
||||
if(p[i] > q) {
|
||||
Z = (G4int)((*theElementVector)[i]->GetZ());
|
||||
break;
|
||||
}
|
||||
q -= p[i];
|
||||
}
|
||||
|
||||
return Z;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4hLowEnergyIonisation::ComputeDEDX(
|
||||
const G4ParticleDefinition* aParticle,
|
||||
const G4Material* material,
|
||||
@@ -1113,8 +1612,8 @@ G4double G4hLowEnergyIonisation::BarkasTerm(const G4Material* material,
|
||||
|
||||
for (G4int i = 0; i<numberOfElements; i++) {
|
||||
|
||||
AMaterial = (*theElementVector)(i)->GetA()*mole/g;
|
||||
ZMaterial = (*theElementVector)(i)->GetZ();
|
||||
AMaterial = (*theElementVector)[i]->GetA()*mole/g;
|
||||
ZMaterial = (*theElementVector)[i]->GetZ();
|
||||
|
||||
G4double X = 137.0 * 137.0 * beta2 / ZMaterial;
|
||||
|
||||
@@ -1213,7 +1712,7 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
|
||||
// get particle data
|
||||
G4double tkin = particle->GetKineticEnergy();
|
||||
G4double particleMass = particle->GetMass() ;
|
||||
G4double deltaCutInKineticEnergyNow = deltaCutInKineticEnergy[imaterial];
|
||||
G4double deltaCutInKineticEnergyNow = cutForDelta[imaterial];
|
||||
|
||||
// shortcut for very very small loss
|
||||
if(meanLoss < minLoss) return meanLoss ;
|
||||
@@ -1431,6 +1930,20 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyIonisation::SetCutForSecondaryPhotons(G4double cut)
|
||||
{
|
||||
minGammaEnergy = cut;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyIonisation::SetCutForAugerElectrons(G4double cut)
|
||||
{
|
||||
minElectronEnergy = cut;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyIonisation::PrintInfoDefinition() const
|
||||
{
|
||||
G4String comments = " Knock-on electron cross sections . ";
|
||||
@@ -1461,14 +1974,14 @@ void G4hLowEnergyIonisation::PrintInfoDefinition() const
|
||||
G4bool printHead = true;
|
||||
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int j=0 ; j < numOfMaterials; j++) {
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[j];
|
||||
G4double deltaCutNow = deltaCutInKineticEnergy[(material->GetIndex())] ;
|
||||
G4double deltaCutNow = cutForDelta[(material->GetIndex())] ;
|
||||
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
if(eexc > deltaCutNow) {
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4hLowEnergyLoss.cc,v 1.9.2.2 2001/06/28 20:19:34 gunter Exp $
|
||||
// GEANT4 tag $Name: $
|
||||
// $Id: G4hLowEnergyLoss.cc,v 1.14 2001/11/23 11:45:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -44,6 +44,7 @@
|
||||
// 31/03/00 rename to lowenergy as G4hLowEnergyLoss.cc V.Ivanchenko
|
||||
// 05/11/00 new method to calculate particle ranges
|
||||
// 10/05/01 V.Ivanchenko Clean up againist Linux compilation with -Wall
|
||||
// 23/11/01 V.Ivanchenko Move static member-functions from header to source
|
||||
// --------------------------------------------------------------
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -161,6 +162,66 @@ G4hLowEnergyLoss::~G4hLowEnergyLoss()
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4hLowEnergyLoss::GetNumberOfProcesses()
|
||||
{
|
||||
return NumberOfProcesses;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::SetNumberOfProcesses(G4int number)
|
||||
{
|
||||
NumberOfProcesses=number;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::PlusNumberOfProcesses()
|
||||
{
|
||||
NumberOfProcesses++;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::MinusNumberOfProcesses()
|
||||
{
|
||||
NumberOfProcesses--;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::SetdRoverRange(G4double value)
|
||||
{
|
||||
dRoverRange = value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::SetRndmStep (G4bool value)
|
||||
{
|
||||
rndmStepFlag = value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::SetEnlossFluc (G4bool value)
|
||||
{
|
||||
EnlossFlucFlag = value;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::SetStepFunction (G4double c1, G4double c2)
|
||||
{
|
||||
dRoverRange = c1;
|
||||
finalRange = c2;
|
||||
c1lim=dRoverRange;
|
||||
c2lim=2.*(1-dRoverRange)*finalRange;
|
||||
c3lim=-(1.-dRoverRange)*finalRange*finalRange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
@@ -178,7 +239,12 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
// create table if there is no table or there is a new cut value
|
||||
G4bool MakeTable = false ;
|
||||
|
||||
G4double ElectronCutInRange = G4Electron::Electron()->GetCuts();
|
||||
// ---- MGP ---- workaround for the deprecated "cuts per material"
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const G4Material* material = (*theMaterialTable)[0];
|
||||
G4double ElectronCutInRange = G4Electron::Electron()->GetEnergyThreshold(material);
|
||||
// was = G4Electron::Electron()->GetCuts();
|
||||
// ---- MGP ----
|
||||
|
||||
// create/fill proton or antiproton tables depending on the charge
|
||||
Charge = aParticleType.GetPDGCharge()/eplus;
|
||||
@@ -196,9 +262,8 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
)
|
||||
MakeTable = true ;
|
||||
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if( MakeTable )
|
||||
{
|
||||
@@ -316,9 +381,8 @@ void G4hLowEnergyLoss::BuildRangeTable(
|
||||
// Build range table from the energy loss table
|
||||
{
|
||||
Mass = proton_mass_c2;
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if( Charge >0.)
|
||||
{
|
||||
@@ -355,9 +419,8 @@ void G4hLowEnergyLoss::BuildRangeTable(
|
||||
void G4hLowEnergyLoss::BuildTimeTables(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
{
|
||||
@@ -455,7 +518,6 @@ void G4hLowEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
LowEdgeEnergy,tau,Value ;
|
||||
|
||||
G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
|
||||
//const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
|
||||
// low energy part first...
|
||||
losslim = physicsVector->GetValue(tlim,isOut);
|
||||
@@ -515,8 +577,7 @@ void G4hLowEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
LowEdgeEnergy,tau,Value ;
|
||||
|
||||
G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
|
||||
//const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
|
||||
|
||||
// low energy part first...
|
||||
losslim = physicsVector->GetValue(tlim,isOut);
|
||||
taulim=tlim/ParticleMass ;
|
||||
@@ -699,9 +760,8 @@ void G4hLowEnergyLoss::BuildRangeCoeffATable(
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "A"
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
@@ -772,9 +832,8 @@ void G4hLowEnergyLoss::BuildRangeCoeffBTable(
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "B"
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
@@ -844,9 +903,8 @@ void G4hLowEnergyLoss::BuildRangeCoeffCTable(
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "C"
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
@@ -917,9 +975,8 @@ void G4hLowEnergyLoss::BuildInverseRangeTable(
|
||||
{
|
||||
G4double SmallestRange,BiggestRange ;
|
||||
G4bool isOut ;
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
{
|
||||
if(theInverseRangepTable)
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "G4Material.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -101,7 +102,7 @@ void G4hNuclearStoppingModel::InitializeMe()
|
||||
}
|
||||
|
||||
// Default is nuclear stopping fluctuations On
|
||||
nStopingPowerTable->SetNuclearStoppingFluctuationsOn();
|
||||
nStopingPowerTable->SetNuclearStoppingFluctuationsOff();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -165,8 +166,8 @@ G4double G4hNuclearStoppingModel::StoppingPower(
|
||||
G4double nloss = 0.0;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++) {
|
||||
const G4Element* element = (*theElementVector)(iel) ;
|
||||
G4double z2 = element->GetZ() ;
|
||||
const G4Element* element = (*theElementVector)[iel] ;
|
||||
G4double z2 = element->GetZ();
|
||||
G4double m2 = element->GetA()*mole/g ;
|
||||
nloss += (nStopingPowerTable->
|
||||
NuclearStoppingPower(kineticEnergy, z1, z2, m1, m2))
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ElementVector.hh"
|
||||
#include "G4Material.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -251,7 +252,7 @@ G4double G4hParametrisedLossModel::StoppingPower(
|
||||
|
||||
// loop for the elements in the material
|
||||
for (G4int i=0; i<numberOfElements; i++) {
|
||||
const G4Element* element = (*theElementVector)(i) ;
|
||||
const G4Element* element = (*theElementVector)[i] ;
|
||||
G4double z = element->GetZ() ;
|
||||
eloss +=(eStopingPowerTable->ElectronicStoppingPower(z,kineticEnergy))
|
||||
* theAtomicNumDensityVector[i] ;
|
||||
@@ -270,7 +271,7 @@ G4double G4hParametrisedLossModel::StoppingPower(
|
||||
// loop for the elements in the material
|
||||
for (G4int i=0; i<numberOfElements; i++)
|
||||
{
|
||||
const G4Element* element = (*theElementVector)(i) ;
|
||||
const G4Element* element = (*theElementVector)[i] ;
|
||||
G4double z = element->GetZ() ;
|
||||
eloss += (eStopingPowerTable->ElectronicStoppingPower(z,kineticEnergy))
|
||||
* theAtomicNumDensityVector[i];
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * 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. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4hShellCrossSection
|
||||
//
|
||||
// Author: S. Dussoni and A. Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 23 Oct 2001 A. Mantero 1st implementation
|
||||
// 24 Oct 2001 MGP Cleaned up
|
||||
// 30 Oct 2001 V.Ivanchenko Include formula (53)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4hShellCrossSection.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
G4hShellCrossSection::G4hShellCrossSection()
|
||||
{ }
|
||||
|
||||
|
||||
G4hShellCrossSection::~G4hShellCrossSection()
|
||||
{ }
|
||||
|
||||
|
||||
G4std::vector<G4double> G4hShellCrossSection::Probabilities(
|
||||
G4int Z,
|
||||
G4double incidentEnergy,
|
||||
G4double hMass,
|
||||
G4double deltaEnergy) const
|
||||
{
|
||||
// Cross-sections for proton ionization calculated as in
|
||||
// "M. Gryzinski, Two-Particle Collisions. I. General Relations for
|
||||
// Collisions in the Laboratory system, Phys.Rev. 138 A305"
|
||||
// Other reference papers are Gryzinski's "Paper I" and "Paper II"
|
||||
|
||||
// V.Ivanchenko add only implementation of the formula (53)
|
||||
// last factor neglected because it is 1 with a good accuracy
|
||||
|
||||
G4AtomicTransitionManager* transitionManager =
|
||||
G4AtomicTransitionManager::Instance();
|
||||
|
||||
size_t nShells = transitionManager->NumberOfShells(Z);
|
||||
|
||||
// Vector that stores the calculated cross-sections for each shell:
|
||||
G4std::vector<G4double> crossSections;
|
||||
|
||||
// Partial and total cross-section used for normalization of crossSections:
|
||||
G4double aCrossSection = 0.;
|
||||
G4double totalCrossSection = 0.;
|
||||
|
||||
// In this loop we calculate cross-section for every shell in the atom
|
||||
for (size_t k=0; k<nShells; k++)
|
||||
{
|
||||
G4double bindingEnergy = transitionManager->Shell(Z,k)->BindingEnergy();
|
||||
G4double xDelta = deltaEnergy/bindingEnergy;
|
||||
G4double y = incidentEnergy*electron_mass_c2/(bindingEnergy*hMass);
|
||||
G4double x = 1.0 + xDelta;
|
||||
|
||||
aCrossSection = (x/(xDelta*(1. + 1./y))
|
||||
+ 4.*log(2.7 + sqrt(y))/3.)/ (x*x*x);
|
||||
|
||||
// Calculation of total cross-section
|
||||
totalCrossSection += aCrossSection;
|
||||
|
||||
// Fill the vector of cross sections with the value just calculated
|
||||
crossSections.push_back(aCrossSection);
|
||||
}
|
||||
|
||||
// Normalization of relative cross-sections to 1
|
||||
for (size_t j=0; j<nShells; j++)
|
||||
{
|
||||
crossSections[j] = crossSections[j] / totalCrossSection;
|
||||
}
|
||||
|
||||
// Returns the normalized vector
|
||||
return crossSections;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user