Import Geant4 5.1.0 source tree
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransitionManager.hh,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
@@ -50,7 +50,7 @@ G4AtomicDeexcitation::G4AtomicDeexcitation():
|
||||
G4AtomicDeexcitation::~G4AtomicDeexcitation()
|
||||
{}
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int shellId)
|
||||
G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int givenShellId)
|
||||
{
|
||||
G4std::vector<G4DynamicParticle*>* vectorOfParticles = new G4std::vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* aParticle;
|
||||
@@ -63,17 +63,17 @@ do
|
||||
{
|
||||
if (counter == 0)
|
||||
// First call to GenerateParticles(...):
|
||||
// shellId is given by the process
|
||||
// givenShellId is given by the process
|
||||
{
|
||||
provShellId = SelectTypeOfTransition(Z, shellId);
|
||||
provShellId = SelectTypeOfTransition(Z, givenShellId);
|
||||
|
||||
if ( provShellId >0)
|
||||
{
|
||||
aParticle = GenerateFluorescence(Z,shellId,provShellId);
|
||||
aParticle = GenerateFluorescence(Z,givenShellId,provShellId);
|
||||
}
|
||||
else if ( provShellId == -1)
|
||||
{
|
||||
aParticle = GenerateAuger(Z, shellId);
|
||||
aParticle = GenerateAuger(Z, givenShellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -102,7 +102,9 @@ do
|
||||
if (aParticle != 0) {vectorOfParticles->push_back(aParticle);}
|
||||
else {provShellId = -2;}
|
||||
}
|
||||
while (provShellId >= 0);
|
||||
|
||||
// Look this in a particular way: only one auger emitted! //
|
||||
while (provShellId >= -1);
|
||||
|
||||
return vectorOfParticles;
|
||||
}
|
||||
@@ -252,9 +254,9 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
transitionManager->ReachableAugerShell(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 NON-radiative transition
|
||||
// This loop gives to shellNum the value of the index of shellId
|
||||
// in the vector storing the list of the vacancies in the variuos shells
|
||||
// that can originate a NON-radiative transition
|
||||
|
||||
// ---- MGP ---- Next line commented out to remove compilation warning
|
||||
// G4int p = refAugerTransition->FinalShellId();
|
||||
@@ -262,20 +264,31 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
G4int shellNum = 0;
|
||||
|
||||
|
||||
if ( shellId <= refAugerTransition->FinalShellId() )
|
||||
if ( shellId <= refAugerTransition->FinalShellId() )
|
||||
//"FinalShellId" is final from the point of view of the elctron who makes the transition,
|
||||
// being the Id of the shell in which there is a vacancy
|
||||
{
|
||||
G4int pippo = transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId();
|
||||
if (shellId != pippo ) {
|
||||
do {
|
||||
shellNum++;
|
||||
if(shellNum == maxNumOfShells)
|
||||
{
|
||||
G4Exception("G4AtomicDeexcitation: No Auger transition found");
|
||||
}
|
||||
}
|
||||
while (shellId != (transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId()) ) ;
|
||||
}
|
||||
/* {
|
||||
|
||||
do
|
||||
if(shellNum == maxNumOfShells-1)
|
||||
{
|
||||
G4Exception("G4AtomicDeexcitation: No Auger tramsition found");
|
||||
}
|
||||
shellNum++;
|
||||
}*/
|
||||
|
||||
|
||||
{
|
||||
if(shellNum == maxNumOfShells-1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
shellNum++;
|
||||
}
|
||||
|
||||
while (shellId != transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId());
|
||||
|
||||
|
||||
// Now we have that shellnum is the shellIndex of the shell named ShellId
|
||||
@@ -300,14 +313,21 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
G4int augerIndex = 0;
|
||||
// G4int partSum2 = 0;
|
||||
|
||||
while (augerIndex < numberOfPossibleAuger) {
|
||||
partSum += anAugerTransition->AugerTransitionProbability(augerIndex,
|
||||
transitionLoopShellId);
|
||||
augerIndex++;
|
||||
}
|
||||
|
||||
if (augerIndex < numberOfPossibleAuger) {
|
||||
|
||||
do
|
||||
{
|
||||
G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex,
|
||||
transitionLoopShellId);
|
||||
partSum += thisProb;
|
||||
augerIndex++;
|
||||
|
||||
} while (augerIndex < numberOfPossibleAuger);
|
||||
}
|
||||
transitionLoopShellIndex++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Now we have the entire probability of an auger transition for the vacancy
|
||||
@@ -338,8 +358,10 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
|
||||
|
||||
while (augerIndex < numberOfPossibleAuger) {
|
||||
partSum += anAugerTransition->AugerTransitionProbability(augerIndex,
|
||||
transitionRandomShellId);
|
||||
G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex,
|
||||
transitionRandomShellId);
|
||||
|
||||
partSum += thisProb;
|
||||
|
||||
if (partSum >= (partialProb/totalVacancyAugerProbability) ) {break;}
|
||||
augerIndex++;
|
||||
@@ -361,46 +383,17 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
|
||||
G4ThreeVector newElectronDirection(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 auger electron emitted
|
||||
|
||||
|
||||
G4double transitionEnergy =
|
||||
anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId);
|
||||
|
||||
/*
|
||||
G4cout << "AUger TransitionId " << anAugerTransition->FinalShellId() << G4endl;
|
||||
G4cout << "augerIndex: " << augerIndex << G4endl;
|
||||
G4cout << "transitionShellId: " << transitionRandomShellId << G4endl;
|
||||
*/
|
||||
|
||||
// This is the shell where the new vacancy is: it is the same
|
||||
// shell where the electron came from
|
||||
newShellId = transitionRandomShellId;
|
||||
@@ -411,7 +404,7 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
|
||||
transitionEnergy);
|
||||
return newPart;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//G4Exception("G4AtomicDeexcitation: no auger transition found");
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicShell.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransition.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
//
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4AtomicTransitionManager.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
|
||||
@@ -173,24 +173,35 @@ G4AtomicShell* G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex) cons
|
||||
|
||||
pos = shellTable.find(Z);
|
||||
|
||||
if (pos!= shellTable.end()){
|
||||
|
||||
G4std::vector<G4AtomicShell*> v = (*pos).second;
|
||||
|
||||
if (shellIndex<v.size()){
|
||||
|
||||
return(v[shellIndex]);
|
||||
|
||||
if (pos!= shellTable.end())
|
||||
{
|
||||
G4std::vector<G4AtomicShell*> v = (*pos).second;
|
||||
if (shellIndex<v.size())
|
||||
{
|
||||
return(v[shellIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t lastShell = v.size();
|
||||
G4cout << "G4AtomicTransitionManager::Shell - Z = "
|
||||
<< Z << ", shellIndex = " << shellIndex
|
||||
<< " not found; number of shells = " << lastShell << G4endl;
|
||||
// G4Exception("G4AtomicTransitionManager:shell not found");
|
||||
if (lastShell > 0)
|
||||
{
|
||||
return v[lastShell - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4Exception("G4AtomicTransitionManager:shell not found");
|
||||
else
|
||||
{
|
||||
G4Exception("G4AtomicTransitionManager:Z not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
G4Exception("G4AtomicTransitionManager:Z not found");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function gives, upon Z and the Index of the initial shell where te vacancy is,
|
||||
|
||||
@@ -65,17 +65,17 @@ const G4std::vector<G4int>* G4AugerTransition::AugerOriginatingShellIds(G4int st
|
||||
{
|
||||
G4std::map<G4int,G4std::vector<G4int>,G4std::less<G4int> >::const_iterator shellId = augerOriginatingShellIdsMap.find(startShellId);
|
||||
|
||||
const G4std::vector<G4int> dataSet = (*shellId).second;
|
||||
const G4std::vector<G4int>* dataOut = 0;
|
||||
const G4std::vector<G4int>* dataSet = &(*shellId).second;
|
||||
//const G4std::vector<G4int>* dataOut = 0;
|
||||
|
||||
if (dataSet.size() == 0) {G4cout << "Error: no auger Id found"<< G4endl;}
|
||||
if (dataSet->size() == 0) {G4cout << "Error: no auger Id found"<< G4endl;}
|
||||
else {
|
||||
|
||||
dataOut = &dataSet;
|
||||
// dataOut = &dataSet;
|
||||
|
||||
}
|
||||
|
||||
return dataOut;
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
// Returns the ids of the shells from wich an electron cuuld fill the vacancy in finalShellId
|
||||
|
||||
+18
-18
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4BremsstrahlungCrossSectionHandler.cc,v 1.5 2001/10/25 14:31:20 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4BremsstrahlungCrossSectionHandler.cc,v 1.6 2003/01/22 18:47:26 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -36,6 +36,7 @@
|
||||
//
|
||||
// Modifications:
|
||||
// 10.10.2001 MGP Revision to improve code quality and consistency with design
|
||||
// 21.01.2003 VI cut per region
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -48,9 +49,9 @@
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
G4BremsstrahlungCrossSectionHandler::G4BremsstrahlungCrossSectionHandler(const G4VEnergySpectrum* spec,
|
||||
G4BremsstrahlungCrossSectionHandler::G4BremsstrahlungCrossSectionHandler(const G4VEnergySpectrum* spec,
|
||||
G4VDataSetAlgorithm* alg)
|
||||
: theBR(spec)
|
||||
{
|
||||
@@ -58,14 +59,14 @@ G4BremsstrahlungCrossSectionHandler::G4BremsstrahlungCrossSectionHandler(const G
|
||||
}
|
||||
|
||||
|
||||
G4BremsstrahlungCrossSectionHandler::~G4BremsstrahlungCrossSectionHandler()
|
||||
G4BremsstrahlungCrossSectionHandler::~G4BremsstrahlungCrossSectionHandler()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
|
||||
G4std::vector<G4VEMDataSet*>*
|
||||
G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
|
||||
G4std::vector<G4VEMDataSet*>*
|
||||
G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
G4std::vector<G4VEMDataSet*>* set = new G4std::vector<G4VEMDataSet*>;
|
||||
@@ -74,15 +75,14 @@ G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4Data
|
||||
G4DataVector* cs;
|
||||
G4int nOfBins = energyVector.size();
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4VCrossSectionHandler::G4VCrossSectionHandler - no MaterialTable found)");
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
for (size_t m=0; m<numOfCouples; m++) {
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material = (*materialTable)[m];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(m);
|
||||
const G4Material* material= couple->GetMaterial();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
@@ -93,7 +93,7 @@ G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4Data
|
||||
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;
|
||||
@@ -107,19 +107,19 @@ G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4Data
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4BremsstrahlungParameters.cc,v 1.14 2002/11/18 18:08:25 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4BremsstrahlungParameters.cc,v 1.16 2003/02/28 08:42:18 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
// V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
|
||||
@@ -34,6 +34,8 @@
|
||||
// 25.09.01 V.Ivanchenko Add parameter C and change interface to B
|
||||
// 29.11.01 V.Ivanchenko Update parametrisation
|
||||
// 18.11.02 V.Ivanchenko Fix problem of load
|
||||
// 21.02.03 V.Ivanchenko Number of parameters is defined in the constructor
|
||||
// 28.02.03 V.Ivanchenko Filename is defined in the constructor
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -46,18 +48,19 @@
|
||||
#include "g4std/strstream"
|
||||
|
||||
|
||||
G4BremsstrahlungParameters:: G4BremsstrahlungParameters(G4int minZ, G4int maxZ)
|
||||
: zMin(minZ),
|
||||
G4BremsstrahlungParameters:: G4BremsstrahlungParameters(const G4String& name,
|
||||
size_t num, G4int minZ, G4int maxZ)
|
||||
: zMin(minZ),
|
||||
zMax(maxZ),
|
||||
length(16)
|
||||
length(num)
|
||||
{
|
||||
LoadData();
|
||||
LoadData(name);
|
||||
}
|
||||
|
||||
|
||||
G4BremsstrahlungParameters::~G4BremsstrahlungParameters()
|
||||
{
|
||||
// Reset the map of data sets: remove the data sets from the map
|
||||
{
|
||||
// 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)
|
||||
@@ -71,12 +74,12 @@ G4BremsstrahlungParameters::~G4BremsstrahlungParameters()
|
||||
}
|
||||
|
||||
|
||||
G4double G4BremsstrahlungParameters::Parameter(G4int parameterIndex,
|
||||
G4int Z,
|
||||
G4double G4BremsstrahlungParameters::Parameter(G4int parameterIndex,
|
||||
G4int Z,
|
||||
G4double energy) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
G4int id = Z*20 + parameterIndex;
|
||||
G4int id = Z*length + parameterIndex;
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
pos = param.find(id);
|
||||
@@ -86,7 +89,7 @@ G4double G4BremsstrahlungParameters::Parameter(G4int parameterIndex,
|
||||
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 = "
|
||||
@@ -96,7 +99,7 @@ G4double G4BremsstrahlungParameters::Parameter(G4int parameterIndex,
|
||||
return value;
|
||||
}
|
||||
|
||||
void G4BremsstrahlungParameters::LoadData()
|
||||
void G4BremsstrahlungParameters::LoadData(const G4String& name)
|
||||
{
|
||||
// Build the complete string identifying the file with the data set
|
||||
|
||||
@@ -112,13 +115,13 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
for (G4int mm=0; mm<100; mm++) {
|
||||
paramC.push_back(x);
|
||||
}
|
||||
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material= (*materialTable)[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();
|
||||
@@ -127,31 +130,30 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
paramC[iz] = 0.217635e-33*(material->GetTotNbOfElectPerVolume());
|
||||
if (!(activeZ.contains(Z))) {
|
||||
activeZ.push_back(Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read parameters
|
||||
|
||||
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (path == 0)
|
||||
{
|
||||
{
|
||||
G4String excep("G4BremsstrahlungParameters - G4LEDATA environment variable not set");
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4String pathString_a(path);
|
||||
G4String stringConversion1("/brem/br-sp.dat");
|
||||
G4String name_a = pathString_a + stringConversion1;
|
||||
G4String name_a = pathString_a + name;
|
||||
G4std::ifstream file_a(name_a);
|
||||
G4std::filebuf* lsdp_a = file_a.rdbuf();
|
||||
|
||||
if (! (lsdp_a->is_open()) )
|
||||
|
||||
if (! (lsdp_a->is_open()) )
|
||||
{
|
||||
G4String stringConversion2("G4BremsstrahlungParameters: cannot open file ");
|
||||
G4String excep = stringConversion2 + name_a;
|
||||
G4Exception(excep);
|
||||
}
|
||||
}
|
||||
|
||||
// The file is organized into two columns:
|
||||
// 1st column is the energy
|
||||
@@ -163,15 +165,15 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
G4DataVector* data;
|
||||
G4double ener = 0.0;
|
||||
G4double sum = 0.0;
|
||||
energies = new G4DataVector();
|
||||
data = new G4DataVector();
|
||||
energies = new G4DataVector();
|
||||
data = new G4DataVector();
|
||||
G4int z = 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();
|
||||
|
||||
@@ -179,21 +181,21 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
file_a >> ener >> sum;
|
||||
|
||||
// End of file
|
||||
if (ener == -2) {
|
||||
if (ener == (G4double)(-2)) {
|
||||
break;
|
||||
|
||||
// End of next element
|
||||
} else if (ener == -1) {
|
||||
} else if (ener == (G4double)(-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;
|
||||
G4int id = z*length + k;
|
||||
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
|
||||
G4DataVector* eVector = new G4DataVector;
|
||||
size_t eSize = e.size();
|
||||
@@ -207,14 +209,14 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
for (size_t j=0; j<length; j++) {
|
||||
G4DataVector* aa = new G4DataVector();
|
||||
a.push_back(aa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t j=0; j<length; j++) {
|
||||
a[j]->clear();
|
||||
}
|
||||
}
|
||||
e.clear();
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if(ener > 1000.) ener = 1000.;
|
||||
@@ -225,11 +227,11 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
G4double qRead;
|
||||
file_a >> qRead;
|
||||
a[j]->push_back(qRead);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} while (ener != -2);
|
||||
|
||||
} while (ener != (G4double)(-2));
|
||||
|
||||
file_a.close();
|
||||
|
||||
}
|
||||
@@ -238,7 +240,7 @@ void G4BremsstrahlungParameters::LoadData()
|
||||
G4double G4BremsstrahlungParameters::ParameterC(G4int id) const
|
||||
{
|
||||
G4int n = paramC.size();
|
||||
if (id < 0 || id >= n)
|
||||
if (id < 0 || id >= n)
|
||||
{
|
||||
G4String stringConversion1("G4BremsstrahlungParameters::ParameterC - wrong id = ");
|
||||
G4String stringConversion2(id);
|
||||
@@ -252,7 +254,7 @@ G4double G4BremsstrahlungParameters::ParameterC(G4int id) const
|
||||
|
||||
void G4BremsstrahlungParameters::PrintData() const
|
||||
{
|
||||
|
||||
|
||||
G4cout << G4endl;
|
||||
G4cout << "===== G4BremsstrahlungParameters =====" << G4endl;
|
||||
G4cout << G4endl;
|
||||
@@ -263,15 +265,15 @@ void G4BremsstrahlungParameters::PrintData() const
|
||||
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
|
||||
|
||||
for (size_t j=0; j<nZ; j++) {
|
||||
G4int Z = (G4int)activeZ[j];
|
||||
G4int Z = (G4int)activeZ[j];
|
||||
|
||||
for (size_t i=0; i<length; i++) {
|
||||
|
||||
pos = param.find(Z*20 + i);
|
||||
pos = param.find(Z*length + i);
|
||||
if (pos!= param.end()) {
|
||||
|
||||
G4cout << "===== Z= " << Z
|
||||
<< " parameter[" << i << "] ====="
|
||||
G4cout << "===== Z= " << Z
|
||||
<< " parameter[" << i << "] ====="
|
||||
<< G4endl;
|
||||
G4VEMDataSet* dataSet = (*pos).second;
|
||||
dataSet->PrintData();
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4CompositeEMDataSet.cc,v 1.6 2002/05/28 09:20:18 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4CrossSectionHandler.cc,v 1.14 2002/07/19 17:32:48 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4CrossSectionHandler.cc,v 1.15 2003/04/24 14:19:37 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
@@ -30,6 +30,7 @@
|
||||
// -----------
|
||||
// 1 Aug 2001 MGP Created
|
||||
// 19 Jul 2002 VI Create composite data set for material
|
||||
// 24 Apr 2003 VI Cut per region mfpt
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -39,10 +40,10 @@
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "g4std/map"
|
||||
#include "g4std/vector"
|
||||
#include "g4std/fstream"
|
||||
@@ -56,7 +57,7 @@ G4CrossSectionHandler::G4CrossSectionHandler()
|
||||
G4CrossSectionHandler::~G4CrossSectionHandler()
|
||||
{ }
|
||||
|
||||
G4std::vector<G4VEMDataSet*>*
|
||||
G4std::vector<G4VEMDataSet*>*
|
||||
G4CrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
|
||||
const G4DataVector*)
|
||||
{
|
||||
@@ -65,15 +66,17 @@ G4CrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energy
|
||||
|
||||
G4std::vector<G4VEMDataSet*>* matCrossSections = new G4std::vector<G4VEMDataSet*>;
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
size_t nOfBins = energyVector.size();
|
||||
const G4VDataSetAlgorithm* interpolationAlgo = CreateInterpolation();
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++)
|
||||
for (size_t m=0; m<numOfCouples; m++)
|
||||
{
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(m);
|
||||
const G4Material* material= couple->GetMaterial();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double* nAtomsPerVolume = material->GetAtomicNumDensityVector();
|
||||
|
||||
@@ -1,73 +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: G4CutsPerMaterialWarning.cc,v 1.1 2001/11/07 22:39:02 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EMDataSet.cc,v 1.6 2002/05/28 09:20:19 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4EMDataSet.cc,v 1.7 2003/02/24 00:36:10 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
@@ -82,29 +82,30 @@ G4EMDataSet::~G4EMDataSet()
|
||||
|
||||
G4double G4EMDataSet::FindValue(G4double e, G4int id) const
|
||||
{
|
||||
G4double value;
|
||||
G4double e0 = (*energies)[0];
|
||||
// Protections
|
||||
size_t bin = FindBinLocation(e);
|
||||
if (bin == numberOfBins)
|
||||
G4double value = 0.;
|
||||
if ( !(energies->empty()) )
|
||||
{
|
||||
// G4cout << "WARNING - G4EMDataSet::FindValue: energy outside upper boundary"
|
||||
// << G4endl;
|
||||
value = (*data)[bin];
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4FluoTransition.cc,v 1.2 ????
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
//
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4LinInterpolation.cc,v 1.2 2002/05/28 09:20:19 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4LogLogInterpolation.cc,v 1.4 2002/05/28 09:20:19 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.55 2002/07/30 18:14:36 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.58 2003/02/28 08:42:17 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// File name: G4LowEnergyBremsstrahlung
|
||||
//
|
||||
// Author: Alessandra Forti, Vladimir Ivanchenko
|
||||
//
|
||||
//
|
||||
// Creation date: March 1999
|
||||
//
|
||||
// Modifications:
|
||||
@@ -51,6 +51,9 @@
|
||||
// 28.10.2001 VI Update printout
|
||||
// 29.11.2001 VI New parametrisation
|
||||
// 30.07.2002 VI Fix in restricted energy loss
|
||||
// 21.01.2003 VI Cut per region
|
||||
// 21.02.2003 V.Ivanchenko Energy bins for spectrum are defined here
|
||||
// 28.02.03 V.Ivanchenko Filename is defined in the constructor
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -64,11 +67,11 @@
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
G4LowEnergyBremsstrahlung::G4LowEnergyBremsstrahlung(const G4String& nam)
|
||||
: G4eLowEnergyLoss(nam),
|
||||
: G4eLowEnergyLoss(nam),
|
||||
crossSectionHandler(0),
|
||||
theMeanFreePath(0),
|
||||
energySpectrum(0)
|
||||
@@ -83,6 +86,7 @@ G4LowEnergyBremsstrahlung::~G4LowEnergyBremsstrahlung()
|
||||
if(crossSectionHandler) delete crossSectionHandler;
|
||||
if(energySpectrum) delete energySpectrum;
|
||||
if(theMeanFreePath) delete theMeanFreePath;
|
||||
energyBins.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -92,15 +96,24 @@ void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aP
|
||||
G4cout << "G4LowEnergyBremsstrahlung::BuildPhysicsTable start"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&aParticleType);
|
||||
|
||||
cutForSecondaryPhotons.clear();
|
||||
|
||||
// Create and fill BremsstrahlungParameters once
|
||||
if( energySpectrum != 0 ) delete energySpectrum;
|
||||
energySpectrum = new G4eBremsstrahlungSpectrum();
|
||||
energyBins.clear();
|
||||
for(size_t i=0; i<15; 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;
|
||||
energyBins.push_back(x);
|
||||
}
|
||||
const G4String dataName("/brem/br-sp.dat");
|
||||
energySpectrum = new G4eBremsstrahlungSpectrum(energyBins,dataName);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4LowEnergyBremsstrahlungSpectrum is initialized"
|
||||
@@ -119,11 +132,11 @@ void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aP
|
||||
crossSectionHandler->LoadShellData("brem/br-cs-");
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << GetProcessName()
|
||||
<< " is created; Cross section data: "
|
||||
G4cout << GetProcessName()
|
||||
<< " is created; Cross section data: "
|
||||
<< G4endl;
|
||||
crossSectionHandler->PrintData();
|
||||
G4cout << "Parameters: "
|
||||
G4cout << "Parameters: "
|
||||
<< G4endl;
|
||||
energySpectrum->PrintData();
|
||||
}
|
||||
@@ -161,7 +174,7 @@ void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aP
|
||||
}
|
||||
|
||||
// Build common DEDX table for all ionisation processes
|
||||
|
||||
|
||||
BuildDEDXTable(aParticleType);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
@@ -187,50 +200,52 @@ void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aPart
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const size_t numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
theLossTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
theLossTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
// Clean up the vector of cuts
|
||||
cutForSecondaryPhotons.clear();
|
||||
|
||||
// Loop for materials
|
||||
|
||||
for (size_t j=0; j<numOfMaterials; j++) {
|
||||
|
||||
|
||||
for (size_t j=0; j<numOfCouples; j++) {
|
||||
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowKineticEnergy,
|
||||
highKineticEnergy,
|
||||
totBin);
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[j];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(j);
|
||||
const G4Material* material= couple->GetMaterial();
|
||||
|
||||
// the cut cannot be below lowest limit
|
||||
G4double tCut = G4std::min(highKineticEnergy,
|
||||
((G4Gamma::Gamma())->GetEnergyThreshold(material)));
|
||||
G4double tCut = (*(theCoupleTable->GetEnergyCutsVector(0)))[j];
|
||||
tCut = G4std::min(highKineticEnergy, tCut);
|
||||
cutForSecondaryPhotons.push_back(tCut);
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
size_t NumberOfElements = material->GetNumberOfElements() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
if(verboseLevel > 1) {
|
||||
G4cout << "Energy loss for material # " << j
|
||||
<< " tCut(keV)= " << tCut/keV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
// now comes the loop for the kinetic energy values
|
||||
for (size_t i = 0; i<totBin; i++) {
|
||||
|
||||
G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(i);
|
||||
G4double ionloss = 0.;
|
||||
|
||||
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 e = energySpectrum->AverageEnergy(Z, 0.0, tCut, lowEdgeEnergy);
|
||||
G4double cs= crossSectionHandler->FindValue(Z, lowEdgeEnergy);
|
||||
ionloss += e * cs * theAtomicNumDensityVector[iel];
|
||||
if(verboseLevel > 1) {
|
||||
@@ -242,7 +257,7 @@ void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aPart
|
||||
<< "; loss= " << ionloss
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
aVector->PutValue(i,ionloss);
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
@@ -255,38 +270,38 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& track,
|
||||
{
|
||||
aParticleChange.Initialize(track);
|
||||
|
||||
const G4Material* material = track.GetMaterial();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
G4double kineticEnergy = track.GetKineticEnergy();
|
||||
G4int index = material->GetIndex();
|
||||
G4int index = couple->GetIndex();
|
||||
G4double tCut = cutForSecondaryPhotons[index];
|
||||
|
||||
// Control limits
|
||||
if(tCut >= kineticEnergy)
|
||||
if(tCut >= kineticEnergy)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material, kineticEnergy);
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple, kineticEnergy);
|
||||
|
||||
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)
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993)
|
||||
// Phys211) derived from Tsai distribution (Rev Mod Phys 49,421(1977))
|
||||
|
||||
G4double totalEnergy = kineticEnergy + electron_mass_c2;
|
||||
G4double totalEnergy = kineticEnergy + electron_mass_c2;
|
||||
|
||||
const G4double a1 = 0.625, a2 = 3.*a1, d = 27.;
|
||||
G4double u = - log(G4UniformRand()*G4UniformRand());
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()) u /= a1;
|
||||
else u /= a2;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
G4double dirY = sinTheta*sin(phi);
|
||||
|
||||
G4ThreeVector gammaDirection (dirX, dirY, dirZ);
|
||||
G4ThreeVector electronDirection = track.GetMomentumDirection();
|
||||
|
||||
@@ -318,7 +333,7 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& track,
|
||||
// create G4DynamicParticle object for the gamma
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
gammaDirection, tGamma);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
}
|
||||
@@ -347,11 +362,11 @@ G4double G4LowEnergyBremsstrahlung::GetMeanFreePath(const G4Track& track,
|
||||
G4ForceCondition* cond)
|
||||
{
|
||||
*cond = NotForced;
|
||||
G4int index = (track.GetMaterial())->GetIndex();
|
||||
G4int index = (track.GetMaterialCutsCouple())->GetIndex();
|
||||
const G4VEMDataSet* data = theMeanFreePath->GetComponent(index);
|
||||
G4double meanFreePath = data->FindValue(track.GetKineticEnergy());
|
||||
return meanFreePath;
|
||||
}
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
void G4LowEnergyBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut)
|
||||
{
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LowEnergyCompton.cc,v 1.33 2001/11/07 20:47:29 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyCompton.cc,v 1.36 2003/04/24 14:19:37 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
@@ -33,8 +33,11 @@
|
||||
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
|
||||
// Added SelectRandomAtom A. Forti
|
||||
// Added map of the elements A. Forti
|
||||
// 24.04.2001 V.Ivanchenko - Remove RogueWave
|
||||
// 24.04.2001 V.Ivanchenko - Remove RogueWave
|
||||
// 06.08.2001 MGP - Revised according to a design iteration
|
||||
// 22.01.2003 V.Ivanchenko - Cut per region
|
||||
// 10.03.2003 V.Ivanchenko - Remove CutPerMaterial warning
|
||||
// 24.04.2003 V.Ivanchenko - Cut per region mfpt
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -58,17 +61,17 @@
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
|
||||
G4LowEnergyCompton::G4LowEnergyCompton(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
lowEnergyLimit(250*eV),
|
||||
lowEnergyLimit(250*eV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyCompton::G4LowEnergyCompton - energy outside intrinsic process validity range");
|
||||
@@ -84,16 +87,16 @@ G4LowEnergyCompton::G4LowEnergyCompton(const G4String& processName)
|
||||
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4LowEnergyCompton::~G4LowEnergyCompton()
|
||||
{
|
||||
delete meanFreePathTable;
|
||||
@@ -104,9 +107,6 @@ G4LowEnergyCompton::~G4LowEnergyCompton()
|
||||
|
||||
void G4LowEnergyCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "comp/ce-cs-";
|
||||
@@ -116,26 +116,26 @@ void G4LowEnergyCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
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
|
||||
// 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
|
||||
// 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
|
||||
// TeV (draft).
|
||||
// The random number techniques of Butcher & Messel are used
|
||||
// (Nucl Phys 20(1960),15).
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
// Dynamic particle quantities
|
||||
|
||||
// Dynamic particle quantities
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
|
||||
@@ -151,8 +151,8 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element in the current material
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy0);
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy0);
|
||||
|
||||
G4double epsilon0 = 1. / (1. + 2. * e0m);
|
||||
G4double epsilon0Sq = epsilon0 * epsilon0;
|
||||
@@ -160,8 +160,8 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double alpha2 = 0.5 * (1. - epsilon0Sq);
|
||||
|
||||
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
|
||||
|
||||
// Sample the energy of the scattered photon
|
||||
|
||||
// Sample the energy of the scattered photon
|
||||
G4double epsilon;
|
||||
G4double epsilonSq;
|
||||
G4double oneCosT;
|
||||
@@ -172,20 +172,20 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand())
|
||||
{
|
||||
epsilon = exp(-alpha1 * G4UniformRand()); // pow(epsilon0,G4UniformRand())
|
||||
epsilonSq = epsilon * epsilon;
|
||||
epsilonSq = epsilon * epsilon;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilonSq = epsilon0Sq + (1. - epsilon0Sq) * G4UniformRand();
|
||||
epsilon = sqrt(epsilonSq);
|
||||
}
|
||||
|
||||
|
||||
oneCosT = (1. - epsilon) / ( epsilon * e0m);
|
||||
sinT2 = oneCosT * (2. - oneCosT);
|
||||
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;
|
||||
@@ -195,8 +195,8 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double diry = sinTheta * sin(phi);
|
||||
G4double dirz = cosTheta ;
|
||||
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
|
||||
G4ThreeVector photonDirection1(dirx,diry,dirz);
|
||||
photonDirection1.rotateUz(photonDirection0);
|
||||
aParticleChange.SetMomentumChange(photonDirection1) ;
|
||||
@@ -207,28 +207,28 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
aParticleChange.SetEnergyChange(photonEnergy1) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
// Kinematics of the scattered electron
|
||||
|
||||
// Kinematics of the scattered electron
|
||||
G4double eKineticEnergy = photonEnergy0 - photonEnergy1;
|
||||
|
||||
// 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))
|
||||
if (rangeTest->Escape(G4Electron::Electron(),couple,eKineticEnergy,safety))
|
||||
{
|
||||
G4double eMomentum = sqrt(eKineticEnergy*(eKineticEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector eDirection((photonEnergy0 * photonDirection0 -
|
||||
photonEnergy1 * photonDirection1) * (1./eMomentum));
|
||||
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.);
|
||||
aParticleChange.SetLocalEnergyDeposit(0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,17 +241,17 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
G4bool G4LowEnergyCompton::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4LowEnergyCompton::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
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();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
size_t materialIndex = couple->GetIndex();
|
||||
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
///
|
||||
// $Id: G4LowEnergyGammaConversion.cc,v 1.27 2002/05/31 18:48:43 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyGammaConversion.cc,v 1.30 2003/04/24 14:19:37 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -38,8 +38,11 @@
|
||||
// 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
|
||||
// 24.04.01 V.Ivanchenko remove RogueWave
|
||||
// 27.07.01 F.Longo correct bug in energy distribution
|
||||
// 21.01.03 V.Ivanchenko Cut per region
|
||||
// 25.03.03 F.Longo fix in angular distribution of e+/e-
|
||||
// 24.04.03 V.Ivanchenko - Cut per region mfpt
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -65,11 +68,10 @@
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
G4LowEnergyGammaConversion::G4LowEnergyGammaConversion(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
: G4VDiscreteProcess(processName),
|
||||
lowEnergyLimit(1.022000*MeV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(1.022000*MeV),
|
||||
@@ -109,9 +111,6 @@ G4LowEnergyGammaConversion::~G4LowEnergyGammaConversion()
|
||||
|
||||
void G4LowEnergyGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "pair/pp-cs-";
|
||||
@@ -121,92 +120,92 @@ void G4LowEnergyGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& p
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
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
|
||||
// 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).
|
||||
|
||||
// Note 1 : Effects due to the breakdown of the Born approximation at low
|
||||
// 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
|
||||
// pair creation in both nuclear and atomic electron fields. However triplet
|
||||
// Note 2 : The differential cross section implicitly takes account of
|
||||
// pair creation in both nuclear and atomic electron fields. However triplet
|
||||
// prodution is not generated.
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy = incidentPhoton->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
|
||||
G4double epsilon ;
|
||||
G4double epsilon0 = electron_mass_c2 / photonEnergy ;
|
||||
|
||||
// Do it fast if photon energy < 2. MeV
|
||||
if (photonEnergy < smallEnergy )
|
||||
{
|
||||
epsilon = epsilon0 + (0.5 - epsilon0) * G4UniformRand();
|
||||
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);
|
||||
const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
|
||||
|
||||
if (element == 0)
|
||||
if (element == 0)
|
||||
{
|
||||
G4cout << "G4LowEnergyGammaConversion::PostStepDoIt - element = 0" << G4endl;
|
||||
}
|
||||
G4IonisParamElm* ionisation = element->GetIonisation();
|
||||
if (ionisation == 0)
|
||||
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());
|
||||
|
||||
|
||||
// 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) ;
|
||||
|
||||
|
||||
// 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)
|
||||
|
||||
// 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
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilon = epsilonMin + epsilonRange * G4UniformRand();
|
||||
screen = screenFactor / (epsilon * (1 - epsilon));
|
||||
gReject = (ScreenFunction2(screen) - fZ) / f20 ;
|
||||
}
|
||||
} while ( gReject < G4UniformRand() );
|
||||
|
||||
|
||||
} // End of epsilon sampling
|
||||
|
||||
// Fix charges randomly
|
||||
|
||||
|
||||
// Fix charges randomly
|
||||
|
||||
G4double electronTotEnergy;
|
||||
G4double positronTotEnergy;
|
||||
|
||||
@@ -220,7 +219,7 @@ G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrac
|
||||
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)
|
||||
@@ -229,7 +228,7 @@ G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrac
|
||||
const G4double a1 = 0.625;
|
||||
G4double a2 = 3. * a1;
|
||||
// G4double d = 27. ;
|
||||
|
||||
|
||||
// if (9. / (9. + d) > G4UniformRand())
|
||||
if (0.25 > G4UniformRand())
|
||||
{
|
||||
@@ -240,51 +239,55 @@ G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrac
|
||||
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);
|
||||
|
||||
// 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
|
||||
G4double thetaEle = u*electron_mass_c2/electronTotEnergy;
|
||||
G4double thetaPos = u*electron_mass_c2/positronTotEnergy;
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
|
||||
G4double dxEle= sin(thetaEle)*cos(phi),dyEle= sin(thetaEle)*sin(phi),dzEle=cos(thetaEle);
|
||||
G4double dxPos=-sin(thetaPos)*cos(phi),dyPos=-sin(thetaPos)*sin(phi),dzPos=cos(thetaPos);
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
G4double localEnergyDeposit = 0. ;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2) ;
|
||||
G4double electronKineEnergy = G4std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
|
||||
// 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,electronKineEnergy,safety))
|
||||
|
||||
if (rangeTest->Escape(G4Electron::Electron(),couple,electronKineEnergy,safety))
|
||||
{
|
||||
G4ThreeVector electronDirection ( dirX, dirY, dirZ );
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
G4ThreeVector electronDirection (dxEle, dyEle, dzEle);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
aParticleChange.AddSecondary(particle1) ;
|
||||
aParticleChange.AddSecondary(particle1) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += electronKineEnergy ;
|
||||
{
|
||||
localEnergyDeposit += electronKineEnergy ;
|
||||
}
|
||||
|
||||
// The e+ is always created (even with kinetic energy = 0) for further annihilation
|
||||
G4double positronKineEnergy = G4std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// Is the local energy deposit correct, if the positron is always created?
|
||||
if (! (rangeTest->Escape(G4Positron::Positron(),material,positronKineEnergy,safety)))
|
||||
if (! (rangeTest->Escape(G4Positron::Positron(),couple,positronKineEnergy,safety)))
|
||||
{
|
||||
localEnergyDeposit += positronKineEnergy ;
|
||||
positronKineEnergy = 0. ;
|
||||
}
|
||||
G4ThreeVector positronDirection(-dirX,-dirY,dirZ);
|
||||
|
||||
G4ThreeVector positronDirection (dxPos, dyPos, dzPos);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
@@ -312,8 +315,8 @@ G4double G4LowEnergyGammaConversion::GetMeanFreePath(const G4Track& track,
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
size_t materialIndex = couple->GetIndex();
|
||||
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4LowEnergyIonisation.cc,v 1.90 2002/10/28 09:43:49 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyIonisation.cc,v 1.93 2003/04/12 16:40:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
@@ -77,7 +77,7 @@
|
||||
// 10.10.01 MGP Revision to improve code quality and
|
||||
// consistency with design
|
||||
// 18.10.01 V.Ivanchenko Add fluorescence AlongStepDoIt
|
||||
// 18.10.01 MGP Revision to improve code quality and
|
||||
// 18.10.01 MGP Revision to improve code quality and
|
||||
// consistency with design
|
||||
// 19.10.01 V.Ivanchenko update according to new design, V.Ivanchenko
|
||||
// 26.10.01 V.Ivanchenko clean up deexcitation
|
||||
@@ -86,12 +86,15 @@
|
||||
// 25.03.02 V.Ivanchneko Fix in fluorescence
|
||||
// 28.03.02 V.Ivanchenko Add flag of fluorescence
|
||||
// 28.05.02 V.Ivanchenko Remove flag fStopAndKill
|
||||
// 31.05.02 V.Ivanchenko Add path of Fluo + Auger cuts to
|
||||
// 31.05.02 V.Ivanchenko Add path of Fluo + Auger cuts to
|
||||
// AtomicDeexcitation
|
||||
// 03.06.02 MGP Restore fStopAndKill
|
||||
// 19.06.02 VI Additional printout
|
||||
// 30.07.02 VI Fix in restricted energy loss
|
||||
// 20.09.02 VI Remove ActivateFlurescence from SetCut...
|
||||
// 21.01.03 VI Cut per region
|
||||
// 12.02.03 VI Change signature for Deexcitation
|
||||
// 12.04.03 V.Ivanchenko Cut per region for fluo AlongStep
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -111,8 +114,7 @@
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
G4LowEnergyIonisation::G4LowEnergyIonisation(const G4String& nam)
|
||||
: G4eLowEnergyLoss(nam),
|
||||
@@ -142,9 +144,6 @@ void G4LowEnergyIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParti
|
||||
G4cout << "G4LowEnergyIonisation::BuildPhysicsTable start"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&aParticleType);
|
||||
|
||||
cutForDelta.clear();
|
||||
|
||||
@@ -164,19 +163,19 @@ void G4LowEnergyIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParti
|
||||
G4double lowKineticEnergy = GetLowerBoundEloss();
|
||||
G4double highKineticEnergy = GetUpperBoundEloss();
|
||||
G4int totBin = GetNbinEloss();
|
||||
crossSectionHandler = new G4eIonisationCrossSectionHandler(energySpectrum,
|
||||
crossSectionHandler = new G4eIonisationCrossSectionHandler(energySpectrum,
|
||||
interpolation,
|
||||
lowKineticEnergy,
|
||||
lowKineticEnergy,
|
||||
highKineticEnergy,
|
||||
totBin);
|
||||
crossSectionHandler->LoadShellData("ioni/ion-ss-cs-");
|
||||
|
||||
if (verboseLevel > 0) {
|
||||
G4cout << GetProcessName()
|
||||
<< " is created; Cross section data: "
|
||||
G4cout << GetProcessName()
|
||||
<< " is created; Cross section data: "
|
||||
<< G4endl;
|
||||
crossSectionHandler->PrintData();
|
||||
G4cout << "Parameters: "
|
||||
G4cout << "Parameters: "
|
||||
<< G4endl;
|
||||
energySpectrum->PrintData();
|
||||
}
|
||||
@@ -236,14 +235,15 @@ void G4LowEnergyIonisation::BuildLossTable(
|
||||
size_t totBin = GetNbinEloss();
|
||||
|
||||
// create table
|
||||
|
||||
|
||||
if (theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const size_t numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
theLossTable = new G4PhysicsTable(numOfMaterials);
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
theLossTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
if (shellVacancy != 0) delete shellVacancy;
|
||||
shellVacancy = new G4ShellVacancy();
|
||||
@@ -261,38 +261,39 @@ void G4LowEnergyIonisation::BuildLossTable(
|
||||
cutForDelta.clear();
|
||||
|
||||
// Loop for materials
|
||||
|
||||
for (size_t m=0; m<numOfMaterials; m++) {
|
||||
|
||||
|
||||
for (size_t m=0; m<numOfCouples; m++) {
|
||||
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowKineticEnergy,
|
||||
highKineticEnergy,
|
||||
totBin);
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[m];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(m);
|
||||
const G4Material* material= couple->GetMaterial();
|
||||
|
||||
// the cut cannot be below lowest limit
|
||||
G4double tCut = G4Electron::Electron()->GetEnergyThreshold(material);
|
||||
G4double tCut = (*(theCoupleTable->GetEnergyCutsVector(1)))[m];
|
||||
if(tCut > highKineticEnergy) tCut = highKineticEnergy;
|
||||
cutForDelta.push_back(tCut);
|
||||
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
size_t NumberOfElements = material->GetNumberOfElements() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "Energy loss for material # " << m
|
||||
<< " tCut(keV)= " << tCut/keV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
// now comes the loop for the kinetic energy values
|
||||
for (size_t i = 0; i<totBin; i++) {
|
||||
|
||||
G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(i);
|
||||
G4double ionloss = 0.;
|
||||
|
||||
G4double ionloss = 0.;
|
||||
|
||||
// loop for elements in the material
|
||||
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
|
||||
|
||||
@@ -302,7 +303,7 @@ void G4LowEnergyIonisation::BuildLossTable(
|
||||
|
||||
for (G4int n=0; n<nShells; n++) {
|
||||
|
||||
G4double e = energySpectrum->AverageEnergy(Z, 0.0, tCut,
|
||||
G4double e = energySpectrum->AverageEnergy(Z, 0.0, tCut,
|
||||
lowEdgeEnergy, n);
|
||||
G4double cs= crossSectionHandler->FindValue(Z, lowEdgeEnergy, n);
|
||||
ionloss += e * cs * theAtomicNumDensityVector[iel];
|
||||
@@ -319,9 +320,9 @@ void G4LowEnergyIonisation::BuildLossTable(
|
||||
}
|
||||
G4double esp = energySpectrum->Excitation(Z, lowEdgeEnergy);
|
||||
ionloss += esp * theAtomicNumDensityVector[iel];
|
||||
}
|
||||
}
|
||||
if(verboseLevel > 1 || (m == 0 && lowEdgeEnergy>=1. && lowEdgeEnergy<=0.)) {
|
||||
G4cout << "Sum: "
|
||||
G4cout << "Sum: "
|
||||
<< " E(keV)= " << lowEdgeEnergy/keV
|
||||
<< " loss(MeV/mm)= " << ionloss*mm/MeV
|
||||
<< G4endl;
|
||||
@@ -349,9 +350,9 @@ void G4LowEnergyIonisation::BuildLossTable(
|
||||
|
||||
for (G4int n=0; n<nShells; n++) {
|
||||
|
||||
G4double e = energySpectrum->AverageEnergy(Z, 0.0, tCut,
|
||||
G4double e = energySpectrum->AverageEnergy(Z, 0.0, tCut,
|
||||
lowEdgeEnergy, n);
|
||||
G4double pro = energySpectrum->Probability(Z, 0.0, tCut,
|
||||
G4double pro = energySpectrum->Probability(Z, 0.0, tCut,
|
||||
lowEdgeEnergy, n);
|
||||
G4double cs= crossSectionHandler->FindValue(Z, lowEdgeEnergy, n);
|
||||
eAverage += e * cs * theAtomicNumDensityVector[iel];
|
||||
@@ -389,7 +390,7 @@ void G4LowEnergyIonisation::BuildLossTable(
|
||||
xsis->AddComponent(set);
|
||||
}
|
||||
if(verboseLevel) xsis->PrintData();
|
||||
shellVacancy->AddXsiTable(xsis);
|
||||
shellVacancy->AddXsiTable(xsis);
|
||||
}
|
||||
delete bVector;
|
||||
}
|
||||
@@ -399,50 +400,50 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
// Delta electron production mechanism on base of the model
|
||||
// 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",
|
||||
// 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-19 (1997)
|
||||
|
||||
aParticleChange.Initialize(track);
|
||||
|
||||
const G4Material* material = track.GetMaterial();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
G4double kineticEnergy = track.GetKineticEnergy();
|
||||
|
||||
// Select atom and shell
|
||||
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material, kineticEnergy);
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple, kineticEnergy);
|
||||
G4int shell = crossSectionHandler->SelectRandomShell(Z, kineticEnergy);
|
||||
const G4AtomicShell* atomicShell =
|
||||
const G4AtomicShell* atomicShell =
|
||||
(G4AtomicTransitionManager::Instance())->Shell(Z, shell);
|
||||
G4double bindingEnergy = atomicShell->BindingEnergy();
|
||||
G4int shellId = atomicShell->ShellId();
|
||||
|
||||
// Sample delta energy
|
||||
|
||||
G4int index = material->GetIndex();
|
||||
G4int index = couple->GetIndex();
|
||||
G4double tCut = cutForDelta[index];
|
||||
G4double tmax = energySpectrum->MaxEnergyOfSecondaries(kineticEnergy);
|
||||
G4double tDelta = energySpectrum->SampleEnergy(Z, tCut, tmax,
|
||||
G4double tDelta = energySpectrum->SampleEnergy(Z, tCut, tmax,
|
||||
kineticEnergy, shell);
|
||||
|
||||
if(tDelta == 0.0)
|
||||
if(tDelta == 0.0)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
|
||||
// Transform to shell potential
|
||||
G4double deltaKinE = tDelta + 2.0*bindingEnergy;
|
||||
G4double primaryKinE = kineticEnergy + 2.0*bindingEnergy;
|
||||
G4double deltaKinE = tDelta + 2.0*bindingEnergy;
|
||||
G4double primaryKinE = kineticEnergy + 2.0*bindingEnergy;
|
||||
|
||||
// sampling of scattering angle neglecting atomic motion
|
||||
G4double deltaMom = sqrt(deltaKinE*(deltaKinE + 2.0*electron_mass_c2));
|
||||
G4double primaryMom = sqrt(primaryKinE*(primaryKinE + 2.0*electron_mass_c2));
|
||||
|
||||
|
||||
G4double cost = deltaKinE * (primaryKinE + 2.0*electron_mass_c2)
|
||||
/ (deltaMom * primaryMom);
|
||||
|
||||
if (cost > 1.) cost = 1.;
|
||||
G4double sint = sqrt(1. - cost*cost);
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4double dirx = sint * cos(phi);
|
||||
G4double diry = sint * sin(phi);
|
||||
G4double dirz = cost;
|
||||
@@ -461,7 +462,7 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
|
||||
cost = 2.0*G4UniformRand() - 1.0;
|
||||
sint = sqrt(1. - cost*cost);
|
||||
phi = twopi * G4UniformRand();
|
||||
phi = twopi * G4UniformRand();
|
||||
G4double del = sqrt(bindingEnergy *(bindingEnergy + 2.0*electron_mass_c2))
|
||||
/ deltaMom;
|
||||
dirx += del* sint * cos(phi);
|
||||
@@ -469,9 +470,9 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
dirz += del* cost;
|
||||
|
||||
// Find out new primary electron direction
|
||||
G4double finalPx = primaryMom*primaryDirection.x() - deltaMom*dirx;
|
||||
G4double finalPy = primaryMom*primaryDirection.y() - deltaMom*diry;
|
||||
G4double finalPz = primaryMom*primaryDirection.z() - deltaMom*dirz;
|
||||
G4double finalPx = primaryMom*primaryDirection.x() - deltaMom*dirx;
|
||||
G4double finalPy = primaryMom*primaryDirection.y() - deltaMom*diry;
|
||||
G4double finalPz = primaryMom*primaryDirection.z() - deltaMom*dirz;
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
G4DynamicParticle* theDeltaRay = new G4DynamicParticle();
|
||||
@@ -480,19 +481,19 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
dirx *= norm;
|
||||
diry *= norm;
|
||||
dirz *= norm;
|
||||
theDeltaRay->SetMomentumDirection(dirx, diry, dirz);
|
||||
theDeltaRay->SetMomentumDirection(dirx, diry, dirz);
|
||||
theDeltaRay->SetDefinition(G4Electron::Electron());
|
||||
|
||||
|
||||
G4double theEnergyDeposit = bindingEnergy;
|
||||
|
||||
// fill ParticleChange
|
||||
// fill ParticleChange
|
||||
// changed energy and momentum of the actual particle
|
||||
|
||||
G4double finalKinEnergy = kineticEnergy - tDelta - theEnergyDeposit;
|
||||
if(finalKinEnergy < 0.0) {
|
||||
theEnergyDeposit += finalKinEnergy;
|
||||
finalKinEnergy = 0.0;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -511,10 +512,10 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
G4std::vector<G4DynamicParticle*>* secondaryVector = 0;
|
||||
G4DynamicParticle* aSecondary = 0;
|
||||
G4ParticleDefinition* type = 0;
|
||||
|
||||
|
||||
// Fluorescence data start from element 6
|
||||
|
||||
if (Fluorescence() && Z > 5 && (bindingEnergy >= cutForPhotons
|
||||
|
||||
if (Fluorescence() && Z > 5 && (bindingEnergy >= cutForPhotons
|
||||
|| bindingEnergy >= cutForElectrons)) {
|
||||
|
||||
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
|
||||
@@ -526,11 +527,11 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
|
||||
aSecondary = (*secondaryVector)[i];
|
||||
if (aSecondary) {
|
||||
|
||||
|
||||
G4double e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if (e < theEnergyDeposit &&
|
||||
((type == G4Gamma::Gamma() && e > cutForPhotons ) ||
|
||||
if (e < theEnergyDeposit &&
|
||||
((type == G4Gamma::Gamma() && e > cutForPhotons ) ||
|
||||
(type == G4Electron::Electron() && e > cutForElectrons ))) {
|
||||
|
||||
theEnergyDeposit -= e;
|
||||
@@ -545,14 +546,14 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Save delta-electrons
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(totalNumber);
|
||||
aParticleChange.AddSecondary(theDeltaRay);
|
||||
|
||||
// Save Fluorescence and Auger
|
||||
|
||||
|
||||
if (secondaryVector) {
|
||||
|
||||
for (size_t l = 0; l < nSecondaries; l++) {
|
||||
@@ -562,13 +563,13 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
|
||||
if(aSecondary) {
|
||||
|
||||
aParticleChange.AddSecondary(aSecondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete secondaryVector;
|
||||
}
|
||||
|
||||
|
||||
if(theEnergyDeposit < 0.) {
|
||||
G4cout << "G4LowEnergyIonisation: Negative energy deposit: "
|
||||
G4cout << "G4LowEnergyIonisation: Negative energy deposit: "
|
||||
<< theEnergyDeposit/eV << " eV" << G4endl;
|
||||
theEnergyDeposit = 0.0;
|
||||
}
|
||||
@@ -582,97 +583,98 @@ void G4LowEnergyIonisation::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from EEDL database.";
|
||||
comments += "\n Gamma energy sampled from a parametrised formula.";
|
||||
comments += "\n Implementation of the continuous dE/dx part.";
|
||||
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 G4LowEnergyBremsstrahlung.";
|
||||
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4LowEnergyIonisation::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( (&particle == G4Electron::Electron()) );
|
||||
}
|
||||
|
||||
G4std::vector<G4DynamicParticle*>*
|
||||
G4LowEnergyIonisation::DeexciteAtom(const G4Material* material,
|
||||
G4std::vector<G4DynamicParticle*>*
|
||||
G4LowEnergyIonisation::DeexciteAtom(const G4MaterialCutsCouple* couple,
|
||||
G4double incidentEnergy,
|
||||
G4double eLoss)
|
||||
{
|
||||
{
|
||||
// create vector of secondary particles
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* partVector =
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* partVector =
|
||||
new G4std::vector<G4DynamicParticle*>;
|
||||
|
||||
|
||||
if(eLoss > cutForPhotons && eLoss > cutForElectrons) {
|
||||
|
||||
const G4AtomicTransitionManager* transitionManager =
|
||||
const G4AtomicTransitionManager* transitionManager =
|
||||
G4AtomicTransitionManager::Instance();
|
||||
|
||||
|
||||
size_t nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* secVector = 0;
|
||||
|
||||
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,
|
||||
|
||||
G4double eTot = 0.0;
|
||||
G4std::vector<G4int> n =
|
||||
shellVacancy->GenerateNumberOfIonisations(couple,
|
||||
incidentEnergy,eLoss);
|
||||
for (size_t i=0; i<nElements; i++) {
|
||||
|
||||
G4int Z = (G4int)((*theElementVector)[i]->GetZ());
|
||||
size_t nVacancies = n[i];
|
||||
|
||||
|
||||
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
|
||||
|
||||
|
||||
if (nVacancies && Z > 5 && (maxE>cutForPhotons || maxE>cutForElectrons)) {
|
||||
|
||||
for (size_t j=0; j<nVacancies; j++) {
|
||||
|
||||
|
||||
shell = crossSectionHandler->SelectRandomShell(Z, incidentEnergy);
|
||||
shellId = transitionManager->Shell(Z, shell)->ShellId();
|
||||
G4double maxEShell =
|
||||
G4double maxEShell =
|
||||
transitionManager->Shell(Z, shell)->BindingEnergy();
|
||||
|
||||
|
||||
if (maxEShell>cutForPhotons || maxEShell>cutForElectrons ) {
|
||||
|
||||
secVector = deexcitationManager.GenerateParticles(Z, shellId);
|
||||
|
||||
if (secVector != 0) {
|
||||
|
||||
|
||||
if (secVector != 0) {
|
||||
|
||||
for (size_t l = 0; l<secVector->size(); l++) {
|
||||
|
||||
|
||||
aSecondary = (*secVector)[l];
|
||||
if (aSecondary != 0) {
|
||||
|
||||
|
||||
e = aSecondary->GetKineticEnergy();
|
||||
type = aSecondary->GetDefinition();
|
||||
if ( eTot + e <= eLoss &&
|
||||
(type == G4Gamma::Gamma() && e>cutForPhotons ) ||
|
||||
(type == G4Gamma::Gamma() && e>cutForPhotons ) ||
|
||||
(type == G4Electron::Electron() && e>cutForElectrons)) {
|
||||
|
||||
eTot += e;
|
||||
|
||||
eTot += e;
|
||||
partVector->push_back(aSecondary);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
delete aSecondary;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
delete secVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -684,17 +686,17 @@ G4double G4LowEnergyIonisation::GetMeanFreePath(const G4Track& track,
|
||||
G4ForceCondition* cond)
|
||||
{
|
||||
*cond = NotForced;
|
||||
G4int index = (track.GetMaterial())->GetIndex();
|
||||
G4int index = (track.GetMaterialCutsCouple())->GetIndex();
|
||||
const G4VEMDataSet* data = theMeanFreePath->GetComponent(index);
|
||||
G4double meanFreePath = data->FindValue(track.GetKineticEnergy());
|
||||
return meanFreePath;
|
||||
}
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
void G4LowEnergyIonisation::SetCutForLowEnSecPhotons(G4double cut)
|
||||
{
|
||||
cutForPhotons = cut;
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cut);
|
||||
}
|
||||
}
|
||||
|
||||
void G4LowEnergyIonisation::SetCutForLowEnSecElectrons(G4double cut)
|
||||
{
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyPhotoElectric.cc,v 1.48 2002/06/14 17:39:09 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyPhotoElectric.cc,v 1.49 2003/01/22 18:47:28 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
@@ -52,10 +52,11 @@
|
||||
// 06.10.2001 MGP Added protection to avoid negative electron energies
|
||||
// when binding energy of selected shell > photon energy
|
||||
// 18.04.2001 V.Ivanchenko Fix problem with low energy gammas from fluorescence
|
||||
// MeanFreePath is calculated by crosSectionHandler directly
|
||||
// MeanFreePath is calculated by crosSectionHandler directly
|
||||
// 31.05.2002 V.Ivanchenko Add path of Fluo + Auger cuts to AtomicDeexcitation
|
||||
// 14.06.2002 V.Ivanchenko By default do not cheak range of e-
|
||||
//
|
||||
// 21.01.2003 V.Ivanchenko Cut per region
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4LowEnergyPhotoElectric.hh"
|
||||
@@ -79,8 +80,7 @@
|
||||
#include "G4RangeNoTest.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName), lowEnergyLimit(250*eV), highEnergyLimit(100*GeV),
|
||||
@@ -100,12 +100,12 @@ G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric(const G4String& processName)
|
||||
meanFreePathTable = 0;
|
||||
rangeTest = new G4RangeNoTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
@@ -120,9 +120,6 @@ G4LowEnergyPhotoElectric::~G4LowEnergyPhotoElectric()
|
||||
|
||||
void G4LowEnergyPhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "phot/pe-cs-";
|
||||
@@ -136,11 +133,11 @@ void G4LowEnergyPhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& pho
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
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
|
||||
// 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)
|
||||
|
||||
@@ -157,10 +154,10 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
}
|
||||
|
||||
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
|
||||
// Select randomly one element in the current material
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy);
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
|
||||
|
||||
// Select the ionised shell in the current atom according to shell cross sections
|
||||
size_t shellIndex = shellCrossSectionHandler->SelectRandomShell(Z,photonEnergy);
|
||||
@@ -188,17 +185,17 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
// 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))
|
||||
if (rangeTest->Escape(G4Electron::Electron(),couple,eKineticEnergy,safety))
|
||||
{
|
||||
// The electron is created in the direction of the incident photon ...
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
photonDirection,
|
||||
// The electron is created in the direction of the incident photon ...
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
|
||||
photonDirection,
|
||||
eKineticEnergy);
|
||||
electronVector.push_back(electron);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
energyDeposit += eKineticEnergy;
|
||||
energyDeposit += eKineticEnergy;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -209,19 +206,25 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
G4int nElectrons = electronVector.size();
|
||||
size_t nTotPhotons = 0;
|
||||
G4int nPhotons=0;
|
||||
G4double cutg = G4std::min(cutForLowEnergySecondaryPhotons,
|
||||
G4Gamma::Gamma()->GetEnergyThreshold(material));
|
||||
G4double cute = G4std::min(cutForLowEnergySecondaryElectrons,
|
||||
G4Electron::Electron()->GetEnergyThreshold(material));
|
||||
G4DynamicParticle* aPhoton;
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
size_t index = couple->GetIndex();
|
||||
G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
|
||||
cutg = G4std::min(cutForLowEnergySecondaryPhotons,cutg);
|
||||
|
||||
G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
|
||||
cute = G4std::min(cutForLowEnergySecondaryPhotons,cute);
|
||||
|
||||
G4DynamicParticle* aPhoton;
|
||||
|
||||
// Generation of fluorescence
|
||||
// Data in EADL are available only for Z > 5
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// Protection to avoid generating photons in the unphysical case of
|
||||
// shell binding energy > photon energy
|
||||
if (Z > 5 && (bindingEnergy > cutg || bindingEnergy > cute))
|
||||
{
|
||||
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
|
||||
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
|
||||
nTotPhotons = photonVector->size();
|
||||
for (size_t k=0; k<nTotPhotons; k++)
|
||||
{
|
||||
@@ -235,15 +238,15 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
if (itsEnergy > itsCut && itsEnergy <= bindingEnergy)
|
||||
{
|
||||
nPhotons++;
|
||||
// Local energy deposit is given as the sum of the
|
||||
// Local energy deposit is given as the sum of the
|
||||
// energies of incident photons minus the energies
|
||||
// of the outcoming fluorescence photons
|
||||
bindingEnergy -= itsEnergy;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aPhoton;
|
||||
{
|
||||
delete aPhoton;
|
||||
(*photonVector)[k] = 0;
|
||||
}
|
||||
}
|
||||
@@ -262,16 +265,16 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
aParticleChange.AddSecondary(aPhoton);
|
||||
}
|
||||
}
|
||||
for ( size_t ll = 0; ll < nTotPhotons; ll++)
|
||||
for ( size_t ll = 0; ll < nTotPhotons; ll++)
|
||||
{
|
||||
aPhoton = (*photonVector)[ll];
|
||||
if(aPhoton) {
|
||||
aParticleChange.AddSecondary(aPhoton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete photonVector;
|
||||
|
||||
|
||||
if (energyDeposit < 0)
|
||||
{
|
||||
G4cout << "WARNING - "
|
||||
@@ -279,25 +282,25 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
|
||||
<< G4endl;
|
||||
energyDeposit = 0;
|
||||
}
|
||||
|
||||
// Kill the incident photon
|
||||
|
||||
// Kill the incident photon
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. );
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(energyDeposit);
|
||||
aParticleChange.SetStatusChange( fStopAndKill );
|
||||
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(energyDeposit);
|
||||
aParticleChange.SetStatusChange( fStopAndKill );
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
}
|
||||
|
||||
G4bool G4LowEnergyPhotoElectric::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4LowEnergyPhotoElectric::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double G4LowEnergyPhotoElectric::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
@@ -334,10 +337,3 @@ void G4LowEnergyPhotoElectric::ActivateAuger(G4bool val)
|
||||
{
|
||||
deexcitationManager.ActivateAugerElectronProduction(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.13 2002/06/02 21:27:52 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.15 2003/04/24 14:19:37 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// ------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -44,12 +44,14 @@
|
||||
// 21 February 2002 - F.Longo Revisions with A.Zoglauer and G.Depaola
|
||||
// - better description of parallelism
|
||||
// - system of ref change method improved
|
||||
// 22 January 2003 - V.Ivanchenko Cut per region
|
||||
// 24 April 2003 - V.Ivanchenko Cut per region mfpt
|
||||
//
|
||||
//
|
||||
// ************************************************************
|
||||
//
|
||||
// Corrections by Rui Curado da Silva (2000)
|
||||
// New Implementation by G.Depaola & F.Longo
|
||||
// New Implementation by G.Depaola & F.Longo
|
||||
//
|
||||
// - sampling of phi
|
||||
// - polarization of scattered photon
|
||||
@@ -75,8 +77,7 @@
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
// constructor
|
||||
|
||||
@@ -87,30 +88,30 @@ G4LowEnergyPolarizedCompton::G4LowEnergyPolarizedCompton(const G4String& process
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
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
|
||||
scatterFunctionData = new
|
||||
G4CompositeEMDataSet(scatterFile,scatterInterpolation,1.,1.);
|
||||
|
||||
|
||||
meanFreePathTable = 0;
|
||||
|
||||
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
@@ -124,13 +125,10 @@ G4LowEnergyPolarizedCompton::~G4LowEnergyPolarizedCompton()
|
||||
delete scatterFunctionData;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void G4LowEnergyPolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "comp/ce-cs-";
|
||||
@@ -150,26 +148,26 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
// Dynamic particle quantities
|
||||
// Dynamic particle quantities
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double gammaEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
G4ThreeVector gammaPolarization0 = incidentPhoton->GetPolarization();
|
||||
G4ThreeVector gammaPolarization0 = incidentPhoton->GetPolarization();
|
||||
|
||||
// gammaPolarization0 = gammaPolarization0.unit(); //
|
||||
// gammaPolarization0 = gammaPolarization0.unit(); //
|
||||
|
||||
// Protection: a polarisation parallel to the
|
||||
// direction causes problems;
|
||||
// Protection: a polarisation parallel to the
|
||||
// direction causes problems;
|
||||
// in that case find a random polarization
|
||||
|
||||
|
||||
G4ThreeVector gammaDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
// ---- MGP ---- Next two lines commented out to remove compilation warnings
|
||||
// G4double scalarproduct = gammaPolarization0.dot(gammaDirection0);
|
||||
// G4double angle = gammaPolarization0.angle(gammaDirection0);
|
||||
|
||||
// Make sure that the polarization vector is perpendicular to the
|
||||
// gamma direction. If not
|
||||
|
||||
if(!(gammaPolarization0.isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.mag()==0))
|
||||
// Make sure that the polarization vector is perpendicular to the
|
||||
// gamma direction. If not
|
||||
|
||||
if(!(gammaPolarization0.isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.mag()==0))
|
||||
{ // only for testing now
|
||||
gammaPolarization0 = GetRandomPolarization(gammaDirection0);
|
||||
}
|
||||
@@ -184,7 +182,7 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
// End of Protection
|
||||
|
||||
// Within energy limit?
|
||||
|
||||
|
||||
if(gammaEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
@@ -192,18 +190,18 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
aParticleChange.SetLocalEnergyDeposit(gammaEnergy0);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
|
||||
G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
|
||||
|
||||
// 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
|
||||
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple,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);
|
||||
@@ -212,10 +210,10 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
G4double wlGamma = h_Planck*c_light/gammaEnergy0;
|
||||
G4double gammaEnergy1;
|
||||
G4ThreeVector gammaDirection1;
|
||||
|
||||
|
||||
do {
|
||||
if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
|
||||
{
|
||||
{
|
||||
epsilon = exp(-alpha1*G4UniformRand());
|
||||
epsilonSq = epsilon*epsilon;
|
||||
}
|
||||
@@ -224,28 +222,28 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
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
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sin(theta)**2 = "
|
||||
<< "sin(theta)**2 = "
|
||||
<< sinThetaSqr
|
||||
<< "; set to 1"
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
sinThetaSqr = 1.;
|
||||
}
|
||||
if (sinThetaSqr < 0.)
|
||||
{
|
||||
if (verboseLevel>0) G4cout
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sin(theta)**2 = "
|
||||
<< "sin(theta)**2 = "
|
||||
<< sinThetaSqr
|
||||
<< "; set to 0"
|
||||
<< "; set to 0"
|
||||
<< G4endl;
|
||||
sinThetaSqr = 0.;
|
||||
}
|
||||
@@ -253,32 +251,32 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
|
||||
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))*scatteringFunction;
|
||||
|
||||
} while(greject < G4UniformRand()*Z);
|
||||
|
||||
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// Phi determination
|
||||
// ****************************************************
|
||||
|
||||
|
||||
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
|
||||
if (verboseLevel>0) G4cout
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "cosTheta = "
|
||||
<< "cosTheta = "
|
||||
<< cosTheta
|
||||
<< "; set to 1"
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
cosTheta = 1.;
|
||||
}
|
||||
@@ -288,7 +286,7 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "cosTheta = "
|
||||
<< cosTheta
|
||||
<< "; set to -1"
|
||||
<< "; set to -1"
|
||||
<< G4endl;
|
||||
cosTheta = -1.;
|
||||
}
|
||||
@@ -304,7 +302,7 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
|
||||
<< "sinTheta = "
|
||||
<< sinTheta
|
||||
<< "; set to 1"
|
||||
<< "; set to 1"
|
||||
<< G4endl;
|
||||
sinTheta = 1.;
|
||||
}
|
||||
@@ -328,25 +326,25 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
//
|
||||
// update G4VParticleChange for the scattered photon
|
||||
//
|
||||
|
||||
|
||||
gammaEnergy1 = epsilon*gammaEnergy0;
|
||||
|
||||
|
||||
// New polarization
|
||||
|
||||
|
||||
G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
|
||||
sinThetaSqr,
|
||||
phi,
|
||||
cosTheta);
|
||||
|
||||
// Set new direction
|
||||
|
||||
// Set new direction
|
||||
G4ThreeVector tmpDirection1( dirx,diry,dirz );
|
||||
gammaDirection1 = tmpDirection1;
|
||||
|
||||
|
||||
// Change reference frame.
|
||||
|
||||
|
||||
SystemOfRefChange(gammaDirection0,gammaDirection1,
|
||||
gammaPolarization0,gammaPolarization1);
|
||||
|
||||
gammaPolarization0,gammaPolarization1);
|
||||
|
||||
if (gammaEnergy1 > 0.)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
|
||||
@@ -354,26 +352,26 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
|
||||
aParticleChange.SetPolarizationChange( gammaPolarization1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// kinematic of the scattered electron
|
||||
//
|
||||
|
||||
|
||||
G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 ;
|
||||
|
||||
|
||||
// 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))
|
||||
|
||||
if (rangeTest->Escape(G4Electron::Electron(),couple,ElecKineEnergy,safety))
|
||||
{
|
||||
G4double ElecMomentum = sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
|
||||
gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
|
||||
G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
|
||||
gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
|
||||
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),ElecDirection.unit(),ElecKineEnergy) ;
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(electron);
|
||||
@@ -398,7 +396,7 @@ G4double G4LowEnergyPolarizedCompton::SetPhi(G4double energyRate,
|
||||
G4double phiProbability;
|
||||
G4double phi;
|
||||
G4double a, b;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
rand1 = G4UniformRand();
|
||||
@@ -476,7 +474,7 @@ G4ThreeVector G4LowEnergyPolarizedCompton::GetPerpendicularPolarization
|
||||
}
|
||||
|
||||
|
||||
G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
|
||||
G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
|
||||
G4double sinSqrTh,
|
||||
G4double phi,
|
||||
G4double costheta)
|
||||
@@ -508,7 +506,7 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
|
||||
a = 4*normalisation*normalisation;
|
||||
b = (epsilon + 1/epsilon) - 2;
|
||||
thetaProbability = (b + a*cos(theta)*cos(theta))/(a+b);
|
||||
cosTheta = cos(theta);
|
||||
cosTheta = cos(theta);
|
||||
}
|
||||
while ( rand2 > thetaProbability );
|
||||
|
||||
@@ -516,14 +514,14 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
|
||||
G4double sinBeta = sqrt(1-cosBeta*cosBeta);
|
||||
|
||||
G4ThreeVector gammaPolarization1;
|
||||
|
||||
|
||||
G4double xParallel = normalisation*cosBeta;
|
||||
G4double yParallel = -(sinSqrTh*cosPhi*sinPhi)*cosBeta/normalisation;
|
||||
G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
|
||||
G4double xPerpendicular = 0.;
|
||||
G4double yPerpendicular = (costheta)*sinBeta/normalisation;
|
||||
G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
|
||||
|
||||
|
||||
G4double xTotal = (xParallel + xPerpendicular);
|
||||
G4double yTotal = (yParallel + yPerpendicular);
|
||||
G4double zTotal = (zParallel + zPerpendicular);
|
||||
@@ -558,7 +556,7 @@ void G4LowEnergyPolarizedCompton::SystemOfRefChange
|
||||
G4double polarization_x = polarization1.getX();
|
||||
G4double polarization_y = polarization1.getY();
|
||||
G4double polarization_z = polarization1.getZ();
|
||||
|
||||
|
||||
polarization1 =(polarization_x*Axis_X0+polarization_y*Axis_Y0+polarization_z*Axis_Z0).unit();
|
||||
|
||||
}
|
||||
@@ -570,14 +568,14 @@ G4bool G4LowEnergyPolarizedCompton::IsApplicable(const G4ParticleDefinition& par
|
||||
}
|
||||
|
||||
|
||||
G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& track,
|
||||
G4double G4LowEnergyPolarizedCompton::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();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
size_t materialIndex = couple->GetIndex();
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
|
||||
|
||||
@@ -22,24 +22,26 @@
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// $Id: G4LowEnergyRayleigh.cc,v 1.30 2002/11/08 07:59:05 flongo Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4LowEnergyRayleigh.cc,v 1.32 2003/04/24 14:19:37 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: A. Forti
|
||||
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// 05.06.2002 F.Longo and G.Depaola - bug fixed in angular distribution
|
||||
// 20.10.2002 G. Depaola - Change sampling method of theta
|
||||
// 20.10.2002 G. Depaola - Change sampling method of theta
|
||||
// 22.01.2003 V.Ivanchenko - Cut per region
|
||||
// 24.04.2003 V.Ivanchenko - Cut per region mfpt
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -61,21 +63,21 @@
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
|
||||
#include "G4CutsPerMaterialWarning.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
G4LowEnergyRayleigh::G4LowEnergyRayleigh(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
lowEnergyLimit(250*eV),
|
||||
lowEnergyLimit(250*eV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4LowEnergyRayleigh::G4LowEnergyRayleigh - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
|
||||
G4VDataSetAlgorithm* ffInterpolation = new G4LogLogInterpolation;
|
||||
@@ -84,16 +86,16 @@ G4LowEnergyRayleigh::G4LowEnergyRayleigh(const G4String& processName)
|
||||
|
||||
meanFreePathTable = 0;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4LowEnergyRayleigh::~G4LowEnergyRayleigh()
|
||||
{
|
||||
delete meanFreePathTable;
|
||||
@@ -103,9 +105,6 @@ G4LowEnergyRayleigh::~G4LowEnergyRayleigh()
|
||||
|
||||
void G4LowEnergyRayleigh::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
G4CutsPerMaterialWarning warning;
|
||||
warning.PrintWarning(&photon);
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "rayl/re-cs-";
|
||||
@@ -115,7 +114,7 @@ void G4LowEnergyRayleigh::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
|
||||
@@ -123,7 +122,7 @@ G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
|
||||
|
||||
if (photonEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
@@ -136,10 +135,10 @@ G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
// Select randomly one element in the current material
|
||||
G4Material* material = aTrack.GetMaterial();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy0);
|
||||
|
||||
// Sample the angle of the scattered photon
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy0);
|
||||
|
||||
// Sample the angle of the scattered photon
|
||||
|
||||
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
|
||||
|
||||
@@ -159,14 +158,14 @@ G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
G4double sinThetaHalf = sqrt((1. - cosTheta) / 2.);
|
||||
x = sinThetaHalf / (wlPhoton/cm);
|
||||
if (x > 1.e+005)
|
||||
if (x > 1.e+005)
|
||||
dataFormFactor = formFactorData->FindValue(x,Z-1);
|
||||
else
|
||||
dataFormFactor = formFactorData->FindValue(0.,Z-1);
|
||||
randomFormFactor = G4UniformRand() * Z * Z;
|
||||
sinTheta = sqrt(1. - cosTheta*cosTheta);
|
||||
gReject = dataFormFactor * dataFormFactor;
|
||||
|
||||
|
||||
} while( gReject < randomFormFactor);
|
||||
|
||||
// Scattered photon angles. ( Z - axis along the parent photon)
|
||||
@@ -174,14 +173,14 @@ G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double dirX = sinTheta*cos(phi);
|
||||
G4double dirY = sinTheta*sin(phi);
|
||||
G4double dirZ = cosTheta;
|
||||
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
|
||||
// Update G4VParticleChange for the scattered photon
|
||||
G4ThreeVector photonDirection1(dirX, dirY, dirZ);
|
||||
|
||||
photonDirection1.rotateUz(photonDirection0);
|
||||
aParticleChange.SetEnergyChange(photonEnergy0);
|
||||
aParticleChange.SetMomentumChange(photonDirection1);
|
||||
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
@@ -198,8 +197,8 @@ G4double G4LowEnergyRayleigh::GetMeanFreePath(const G4Track& track,
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
size_t materialIndex = couple->GetIndex();
|
||||
|
||||
G4double meanFreePath;
|
||||
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeBremsstrahlung.cc,v 1.5 2003/04/24 14:51:10 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// File name: G4PenelopeBremsstrahlung
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// Creation date: February 2003
|
||||
//
|
||||
// Modifications:
|
||||
// 24.04.2003 V.Ivanchenko - Cut per region mfpt
|
||||
//
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeBremsstrahlung.hh"
|
||||
#include "G4PenelopeBremsstrahlungContinuous.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"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Il load dei dati continui si puo' mettere nel BuildLossTable
|
||||
//
|
||||
//
|
||||
// Anche la sezione d'urto totale dovrebbe essere convertita
|
||||
// le tabelle di G4 mi paiono piu' complete pero' (le lascio!)
|
||||
//
|
||||
|
||||
G4PenelopeBremsstrahlung::G4PenelopeBremsstrahlung(const G4String& nam)
|
||||
: G4eLowEnergyLoss(nam),
|
||||
crossSectionHandler(0),
|
||||
theMeanFreePath(0),
|
||||
energySpectrum(0)
|
||||
{
|
||||
materialAngularData.clear();
|
||||
cutForPhotons = 0.;
|
||||
verboseLevel = 0;
|
||||
LoadAngularData();
|
||||
}
|
||||
|
||||
|
||||
G4PenelopeBremsstrahlung::~G4PenelopeBremsstrahlung()
|
||||
{
|
||||
if(crossSectionHandler) delete crossSectionHandler;
|
||||
if(energySpectrum) delete energySpectrum;
|
||||
if(theMeanFreePath) delete theMeanFreePath;
|
||||
}
|
||||
|
||||
|
||||
void G4PenelopeBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4PenelopeBremsstrahlung::BuildPhysicsTable start"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
cutForSecondaryPhotons.clear();
|
||||
|
||||
// Create and fill BremsstrahlungParameters once
|
||||
if( energySpectrum != 0 ) delete energySpectrum;
|
||||
//grid of reduced energy bins for photons
|
||||
|
||||
G4DataVector ebins;
|
||||
ebins.push_back(1.0e-12);
|
||||
ebins.push_back(0.05);
|
||||
ebins.push_back(0.075);
|
||||
ebins.push_back(0.1);
|
||||
ebins.push_back(0.125);
|
||||
ebins.push_back(0.15);
|
||||
ebins.push_back(0.2);
|
||||
ebins.push_back(0.25);
|
||||
ebins.push_back(0.3);
|
||||
ebins.push_back(0.35);
|
||||
ebins.push_back(0.40);
|
||||
ebins.push_back(0.45);
|
||||
ebins.push_back(0.50);
|
||||
ebins.push_back(0.55);
|
||||
ebins.push_back(0.60);
|
||||
ebins.push_back(0.65);
|
||||
ebins.push_back(0.70);
|
||||
ebins.push_back(0.75);
|
||||
ebins.push_back(0.80);
|
||||
ebins.push_back(0.85);
|
||||
ebins.push_back(0.90);
|
||||
ebins.push_back(0.925);
|
||||
ebins.push_back(0.95);
|
||||
ebins.push_back(0.97);
|
||||
ebins.push_back(0.99);
|
||||
ebins.push_back(0.995);
|
||||
ebins.push_back(0.999);
|
||||
ebins.push_back(0.9995);
|
||||
ebins.push_back(0.9999);
|
||||
ebins.push_back(0.99995);
|
||||
ebins.push_back(0.99999);
|
||||
ebins.push_back(1.0);
|
||||
|
||||
|
||||
const G4String dataName("/penelope/br-sp-pen.dat");
|
||||
energySpectrum = new G4eBremsstrahlungSpectrum(ebins,dataName);
|
||||
|
||||
//the shape of the energy spectrum for positron is the same used for the electrons,
|
||||
//as the differential cross section is scaled of a factor f(E,Z) which is independent
|
||||
//on the energy of the gamma
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4PenelopeBremsstrahlungSpectrum 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);
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
//G4cout << "Leggo le sezioni d'urto degli elettroni" << G4endl;
|
||||
crossSectionHandler->LoadShellData("brem/br-cs-");
|
||||
}
|
||||
else
|
||||
{
|
||||
//G4cout << "Leggo le sezioni d'urto dei positroni" << G4endl;
|
||||
crossSectionHandler->LoadShellData("penelope/br-cs-pos-"); //cross section for positrons
|
||||
}
|
||||
|
||||
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;
|
||||
CounterOfPositronProcess++;
|
||||
}
|
||||
|
||||
// Build mean free path data using cut values
|
||||
|
||||
if( theMeanFreePath != 0 ) delete theMeanFreePath;
|
||||
theMeanFreePath = crossSectionHandler->
|
||||
BuildMeanFreePathForMaterials(&cutForSecondaryPhotons);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "The MeanFreePath table is built"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
// Build common DEDX table for all ionisation processes
|
||||
|
||||
BuildDEDXTable(aParticleType);
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4PenelopeBremsstrahlung::BuildPhysicsTable end"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4PenelopeBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// 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) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
theLossTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
|
||||
// Clean up the vector of cuts
|
||||
cutForSecondaryPhotons.clear();
|
||||
|
||||
// Loop for materials
|
||||
for (size_t j=0; j<numOfCouples; j++) {
|
||||
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowKineticEnergy,
|
||||
highKineticEnergy,
|
||||
totBin);
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(j);
|
||||
const G4Material* material= couple->GetMaterial();
|
||||
// the cut cannot be below lowest limit
|
||||
G4double tCut = (*(theCoupleTable->GetEnergyCutsVector(0)))[j];
|
||||
tCut = G4std::min(highKineticEnergy, tCut);
|
||||
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;
|
||||
}
|
||||
|
||||
G4DataVector* ionloss = new G4DataVector();
|
||||
for (size_t i = 0; i<totBin; i++) {
|
||||
ionloss->push_back(0.0); //il vettore ha come elementi totBin zeri
|
||||
}
|
||||
|
||||
const G4String partName = aParticleType.GetParticleName();
|
||||
// loop for elements in the material
|
||||
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
|
||||
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
|
||||
//costruttore del continuo per l'elemento Z
|
||||
G4PenelopeBremsstrahlungContinuous* ContLoss = new G4PenelopeBremsstrahlungContinuous(Z,tCut,GetLowerBoundEloss(),
|
||||
GetUpperBoundEloss(),
|
||||
partName);
|
||||
//l'inizializzazione va ripetuta per ogni Z!
|
||||
// now comes the loop for the kinetic energy values
|
||||
for (size_t k = 0; k<totBin; k++) {
|
||||
G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(k);
|
||||
//qui viene chiamato il metodo giusto della perdita continua
|
||||
(*ionloss)[k] += ContLoss->CalculateStopping(lowEdgeEnergy) * theAtomicNumDensityVector[iel];
|
||||
//if (Z == 29)
|
||||
// G4cout << lowEdgeEnergy << " " << ContLoss->CalculateStopping(lowEdgeEnergy) * theAtomicNumDensityVector[iel] << G4endl;
|
||||
//va chiamato una volta per ogni energia
|
||||
//per ogni energia k, somma su tutti gli elementi del materiale
|
||||
}
|
||||
delete ContLoss;
|
||||
}
|
||||
|
||||
for (size_t ibin = 0; ibin<totBin; ibin++) {
|
||||
aVector->PutValue(ibin,(*ionloss)[ibin]); //un valore per ogni energia (somma sugli elementi del mate)
|
||||
}
|
||||
delete ionloss;
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4PenelopeBremsstrahlung::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
aParticleChange.Initialize(track);
|
||||
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4double kineticEnergy = track.GetKineticEnergy();
|
||||
G4int index = couple->GetIndex();
|
||||
G4double tCut = cutForSecondaryPhotons[index];
|
||||
|
||||
// Control limits
|
||||
if(tCut >= kineticEnergy)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple, kineticEnergy);
|
||||
|
||||
G4double tGamma = energySpectrum->SampleEnergy(Z, tCut, kineticEnergy, kineticEnergy);
|
||||
//bisogna recuperare il puntatore
|
||||
G4AngularData* elementData = materialAngularData[index]; //punta al vettore che contiene i puntatori del materiale
|
||||
//look for the index of the selected atom
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
size_t NumberOfElements = material->GetNumberOfElements();
|
||||
// loop for elements in the material
|
||||
size_t iel=0;
|
||||
G4int Z_try=0,indexEl=0;
|
||||
do {
|
||||
if (iel >= NumberOfElements ) {
|
||||
G4String excep = "Not found the angular data for material " + material->GetName();
|
||||
G4Exception(excep);
|
||||
}
|
||||
Z_try = (G4int)((*theElementVector)[(size_t) iel]->GetZ());
|
||||
indexEl = iel;
|
||||
iel++;
|
||||
}while(Z_try != Z);
|
||||
|
||||
G4PenelopeBremsstrahlungAngular* finalAngularData = (*elementData)[indexEl];
|
||||
|
||||
// Sample gamma angle (Z - axis along the parent particle).
|
||||
G4double dirZ = finalAngularData->ExtractCosTheta(kineticEnergy,tGamma);
|
||||
|
||||
//G4std::ofstream fff("prova.dat",G4std::ios::app);
|
||||
//fff << dirZ << G4endl;
|
||||
//fff.close();
|
||||
|
||||
G4double totalEnergy = kineticEnergy + electron_mass_c2;
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4double sinTheta = sqrt(1. - dirZ*dirZ);
|
||||
G4double dirX = sinTheta*cos(phi);
|
||||
G4double dirY = sinTheta*sin(phi);
|
||||
|
||||
G4ThreeVector gammaDirection (dirX, dirY, dirZ);
|
||||
G4ThreeVector electronDirection = track.GetMomentumDirection();
|
||||
|
||||
gammaDirection.rotateUz(electronDirection);
|
||||
|
||||
//
|
||||
// Update the incident particle
|
||||
//
|
||||
|
||||
G4double finalEnergy = kineticEnergy - tGamma;
|
||||
|
||||
// Kinematic problem
|
||||
if (finalEnergy < 0.) {
|
||||
tGamma += finalEnergy;
|
||||
finalEnergy = 0.0;
|
||||
}
|
||||
|
||||
G4double momentum = sqrt((totalEnergy + electron_mass_c2)*kineticEnergy);
|
||||
|
||||
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.SetNumberOfSecondaries(1);
|
||||
G4double norm = 1./sqrt(finalX*finalX + finalY*finalY + finalZ*finalZ);
|
||||
aParticleChange.SetMomentumChange(finalX*norm, finalY*norm, finalZ*norm);
|
||||
aParticleChange.SetEnergyChange( finalEnergy );
|
||||
|
||||
// create G4DynamicParticle object for the gamma
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
gammaDirection, tGamma);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
|
||||
}
|
||||
|
||||
|
||||
void G4PenelopeBremsstrahlung::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from EEDL database for electrons.";
|
||||
comments += "\n Total cross section for positrons calculated from the electrons";
|
||||
comments += "\n through an empirical scaling function.";
|
||||
comments += "\n Gamma energy sampled from a data-driven histogram.";
|
||||
comments += "\n Implementation of the continuous dE/dx part.";
|
||||
comments += "\n It can be used for electrons and positrons";
|
||||
comments += "in the energy range [250eV,100GeV].";
|
||||
comments += "\n The process must work with G4LowEnergyIonisation.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments << G4endl;
|
||||
}
|
||||
|
||||
G4bool G4PenelopeBremsstrahlung::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( (&particle == G4Electron::Electron()) || (&particle == G4Positron::Positron()) );
|
||||
}
|
||||
|
||||
|
||||
G4double G4PenelopeBremsstrahlung::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* cond)
|
||||
{
|
||||
//*cond = NotForced;
|
||||
G4int index = (track.GetMaterialCutsCouple())->GetIndex();
|
||||
const G4VEMDataSet* data = theMeanFreePath->GetComponent(index);
|
||||
G4double meanFreePath = data->FindValue(track.GetKineticEnergy());
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
void G4PenelopeBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut)
|
||||
{
|
||||
cutForPhotons = cut;
|
||||
}
|
||||
|
||||
void G4PenelopeBremsstrahlung::LoadAngularData()
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const size_t numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
materialAngularData.clear();
|
||||
|
||||
for (size_t 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();
|
||||
// loop for elements in the material
|
||||
G4AngularData* elementAngularData = new G4AngularData;
|
||||
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
|
||||
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
|
||||
G4PenelopeBremsstrahlungAngular* AngPointer = new G4PenelopeBremsstrahlungAngular(Z);
|
||||
elementAngularData->push_back(AngPointer);
|
||||
}
|
||||
materialAngularData.push_back(elementAngularData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeBremsstrahlungAngular.cc,v 1.3 2003/03/28 11:16:29 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// File name: G4PenelopeBremsstrahlungAngular
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// Creation date: February 2003
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 04 Feb 2003 L. Pandola 1st implementation
|
||||
// 19 Mar 2003 L. Pandola Bugs fixed
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeBremsstrahlungAngular.hh"
|
||||
#include "G4PenelopeInterpolator.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
G4PenelopeBremsstrahlungAngular::G4PenelopeBremsstrahlungAngular (G4int Zed)
|
||||
: Zmat(Zed)
|
||||
{
|
||||
InterpolationTableForZ();
|
||||
InterpolationForK();
|
||||
}
|
||||
|
||||
|
||||
G4PenelopeBremsstrahlungAngular::~G4PenelopeBremsstrahlungAngular()
|
||||
{
|
||||
}
|
||||
|
||||
void G4PenelopeBremsstrahlungAngular::InterpolationTableForZ()
|
||||
{
|
||||
G4double pZ[NumberofZPoints] = {2.0,8.0,13.0,47.0,79.0,92.0};
|
||||
G4double pX[NumberofZPoints],pY[NumberofZPoints];
|
||||
G4double QQ1[NumberofZPoints][NumberofEPoints][NumberofKPoints];
|
||||
G4double QQ2[NumberofZPoints][NumberofEPoints][NumberofKPoints];
|
||||
|
||||
//Read information from DataBase file
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4PenelopeBremsstrahlungAngular - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/br-ang-pen.dat";
|
||||
G4std::ifstream file(pathFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (!(lsdp->is_open()))
|
||||
{
|
||||
G4String excep = "G4PenelopeBremsstrahlungAngular - data file " + pathFile + " not found!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4int i=0,j=0,k=0; // i=index for Z, j=index for E, k=index for K
|
||||
G4double a1,a2;
|
||||
while(i != -1) {
|
||||
file >> i >> j >> k >> a1 >> a2;
|
||||
if (i > -1){
|
||||
QQ1[i][j][k]=a1;
|
||||
QQ2[i][j][k]=a2;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
|
||||
//Interpolation in Z
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
for (k=0;k<NumberofZPoints;k++){
|
||||
pX[k]=log(QQ1[k][i][j]);
|
||||
pY[k]=QQ2[k][i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator1 = new G4PenelopeInterpolator(pZ,pX,NumberofZPoints);
|
||||
Q1[i][j]=exp(interpolator1->CubicSplineInterpolation((G4double) Zmat));
|
||||
delete interpolator1;
|
||||
G4PenelopeInterpolator* interpolator2 = new G4PenelopeInterpolator(pZ,pY,NumberofZPoints);
|
||||
Q2[i][j]=interpolator2->CubicSplineInterpolation((G4double) Zmat);
|
||||
delete interpolator2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//G4std::ofstream fil("matrice.dat",G4std::ios::app);
|
||||
//fil << "Numero atomico: " << Zmat << G4endl;
|
||||
//for (i=0;i<NumberofEPoints;i++)
|
||||
//{
|
||||
// fil << Q1[i][0] << " " << Q1[i][1] << " " << Q1[i][2] << " " << Q1[i][3] << G4endl;
|
||||
//}
|
||||
//fil.close();
|
||||
|
||||
}
|
||||
|
||||
void G4PenelopeBremsstrahlungAngular::InterpolationForK()
|
||||
{
|
||||
G4double pE[NumberofEPoints] = {1.0e-03,5.0e-03,1.0e-02,5.0e-02,1.0e-01,5.0e-01};
|
||||
G4double pK[NumberofKPoints] = {0.0,0.6,0.8,0.95};
|
||||
G4double ppK[reducedEnergyGrid];
|
||||
G4double pX[NumberofKPoints];
|
||||
G4int i,j;
|
||||
|
||||
for(i=0;i<reducedEnergyGrid;i++){
|
||||
ppK[i]=((G4double) i) * 0.05;
|
||||
}
|
||||
|
||||
for(i=0;i<NumberofEPoints;i++){
|
||||
betas[i]=sqrt(pE[i]*(pE[i]+2*electron_mass_c2))/(pE[i]+electron_mass_c2);
|
||||
}
|
||||
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
Q1[i][j]=Q1[i][j]/((G4double) Zmat);
|
||||
}
|
||||
}
|
||||
|
||||
//Expanded table of distribution parameters
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
pX[j]=log(Q1[i][j]); //logarithmic
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator = new G4PenelopeInterpolator(pK,pX,NumberofKPoints);
|
||||
for (j=0;j<reducedEnergyGrid;j++){
|
||||
Q1E[i][j]=interpolator->CubicSplineInterpolation(ppK[j]);
|
||||
}
|
||||
delete interpolator;
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
pX[j]=Q2[i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator2 = new G4PenelopeInterpolator(pK,pX,NumberofKPoints);
|
||||
for (j=0;j<reducedEnergyGrid;j++){
|
||||
Q2E[i][j]=interpolator2->CubicSplineInterpolation(ppK[j]);
|
||||
}
|
||||
delete interpolator2;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4PenelopeBremsstrahlungAngular::ExtractCosTheta(G4double e1,G4double e2)
|
||||
{
|
||||
//e1 = kinetic energy of the electron
|
||||
//e2 = energy of the bremsstrahlung photon
|
||||
|
||||
G4double beta = sqrt(e1*(e1+2*electron_mass_c2))/(e1+electron_mass_c2);
|
||||
|
||||
|
||||
G4double RK=20.0*e2/e1;
|
||||
G4int ik=G4std::min((G4int) RK,19);
|
||||
|
||||
G4double P10=0,P11=0,P1=0;
|
||||
G4double P20=0,P21=0,P2=0;
|
||||
G4double pX[NumberofEPoints];
|
||||
|
||||
//First coefficient
|
||||
G4int i;
|
||||
G4int j = ik;
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
pX[i]=Q1E[i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator = new G4PenelopeInterpolator(betas,pX,NumberofEPoints);
|
||||
P10=interpolator->CubicSplineInterpolation(beta);
|
||||
delete interpolator;
|
||||
j++; //(j=ik+1)
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
pX[i]=Q1E[i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator2 = new G4PenelopeInterpolator(betas,pX,NumberofEPoints);
|
||||
P11=interpolator2->CubicSplineInterpolation(beta);
|
||||
delete interpolator2;
|
||||
P1=P10+(RK-(G4double) ik)*(P11-P10);
|
||||
|
||||
//Second coefficient
|
||||
j = ik;
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
pX[i]=Q2E[i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator3 = new G4PenelopeInterpolator(betas,pX,NumberofEPoints);
|
||||
P20=interpolator3->CubicSplineInterpolation(beta);
|
||||
delete interpolator3;
|
||||
j++; //(j=ik+1)
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
pX[i]=Q2E[i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator4 = new G4PenelopeInterpolator(betas,pX,NumberofEPoints);
|
||||
P21=interpolator4->CubicSplineInterpolation(beta);
|
||||
delete interpolator4;
|
||||
P2=P20+(RK-(G4double) ik)*(P21-P20);
|
||||
|
||||
//Sampling from the Lorenz-trasformed dipole distributions
|
||||
P1=G4std::min(exp(P1)/beta,1.0);
|
||||
G4double betap = G4std::min(G4std::max(beta*(1.0+P2/beta),0.0),0.9999);
|
||||
|
||||
G4double cdt=0,testf=0;
|
||||
|
||||
if (G4UniformRand() < P1){
|
||||
do{
|
||||
cdt = 2.0*G4UniformRand()-1.0;
|
||||
testf=2.0*G4UniformRand()-(1.0+cdt*cdt);
|
||||
}while(testf>0);
|
||||
}
|
||||
else{
|
||||
do{
|
||||
cdt = 2.0*G4UniformRand()-1.0;
|
||||
testf=G4UniformRand()-(1.0-cdt*cdt);
|
||||
}while(testf>0);
|
||||
}
|
||||
cdt = (cdt+betap)/(1.0+betap*cdt);
|
||||
return cdt;
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeBremsstrahlungContinuous.cc,v 1.4 2003/03/28 11:16:29 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// File name: G4PenelopeBremsstrahlungContinuous
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// Creation date: February 2003
|
||||
// History:
|
||||
// -----------
|
||||
// 20 Feb 2003 L. Pandola 1st implementation
|
||||
// 17 Mar 2003 L. Pandola Added the correction for positrons
|
||||
// 19 Mar 2003 L. Pandola Bugs fixed
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeBremsstrahlungContinuous.hh"
|
||||
#include "G4PenelopeInterpolator.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "globals.hh"
|
||||
#include "g4std/strstream"
|
||||
|
||||
G4PenelopeBremsstrahlungContinuous::G4PenelopeBremsstrahlungContinuous (G4int Zed,G4double taglio,G4double e1,
|
||||
G4double e2,
|
||||
const G4String name) :
|
||||
Zmat(Zed),tCut(taglio),MinE(e1),MaxE(e2),partName(name)
|
||||
{
|
||||
//Construct extended energy table
|
||||
//200 bins between MinE and MaxE (logarithmic)
|
||||
G4double EL=0.99999*MinE;
|
||||
G4double EU=1.00001*MaxE;
|
||||
DLFC=log(EU/EL)/((G4double) (NumberofExtendedEGrid-1));
|
||||
ExtendedLogEnergy[0]=log(EL);
|
||||
for (size_t i=1;i<NumberofExtendedEGrid;i++){
|
||||
ExtendedLogEnergy[i]=ExtendedLogEnergy[i-1]+DLFC;
|
||||
}
|
||||
DLFC=1.0/DLFC;
|
||||
|
||||
LoadFromFile();
|
||||
PrepareInterpolationTable();
|
||||
}
|
||||
|
||||
|
||||
G4PenelopeBremsstrahlungContinuous::~G4PenelopeBremsstrahlungContinuous()
|
||||
{
|
||||
}
|
||||
|
||||
void G4PenelopeBremsstrahlungContinuous::LoadFromFile()
|
||||
{
|
||||
//Read information from DataBase File
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4PenelopeBremsstrahlungContinuous - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String filename = "br-pen-cont-";
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
ost << filename << Zmat << ".dat";
|
||||
G4String name(nameChar);
|
||||
G4String dirFile = pathString + "/penelope/" + name;
|
||||
G4std::ifstream file(dirFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
if (!(lsdp->is_open()))
|
||||
{
|
||||
G4String excep = "G4PenelopeBremsstrahlungContinuous - data file " + name + " not found!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4double a1;
|
||||
for (size_t i=0;i<NumberofEPoints;i++){
|
||||
file >> a1;
|
||||
Energies[i]=a1;
|
||||
for (size_t j=0;j<NumberofKPoints;j++){
|
||||
file >> a1;
|
||||
ReducedCS[i][j]=a1/millibarn; //coversion present in Penelope source
|
||||
}
|
||||
file >> a1;
|
||||
TotalCS[i]=a1/millibarn; //conversion present in Penelope source
|
||||
file >> a1;
|
||||
if (a1 != ((G4double) -1)){
|
||||
G4String excep = "G4PenelopeBremsstrahlungContinuous - Check the bremms data file "+ name;
|
||||
G4Exception(excep);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void G4PenelopeBremsstrahlungContinuous::PrepareInterpolationTable()
|
||||
{
|
||||
//The energy-loss spectrum is re-normalized to reproduce the
|
||||
//total scaled cross-section of Berger and Seltzer
|
||||
|
||||
G4double pK[NumberofKPoints] = {1.0e-12,0.05,0.075,0.1,0.125,0.15,0.2,0.25,
|
||||
0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,
|
||||
0.75,0.8,0.85,0.9,0.925,0.95,0.97,0.99,
|
||||
0.995,0.999,0.9995,0.9999,0.99995,0.99999,1.0};
|
||||
G4double pY[NumberofKPoints];
|
||||
|
||||
size_t i=0,j=0;
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
pY[j]= ReducedCS[i][j];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator = new G4PenelopeInterpolator(pK,pY,NumberofKPoints);
|
||||
G4double Rsum = interpolator->CalculateMomentum(1.0,0);
|
||||
|
||||
delete interpolator;
|
||||
G4double Fact = (millibarn/cm2)*(Energies[i]+electron_mass_c2)*(1.0/fine_structure_const)/
|
||||
(pow(classic_electr_radius,2)*(Energies[i]+2.0*electron_mass_c2));
|
||||
G4double Normalization = TotalCS[i]/(Rsum*Fact);
|
||||
G4double TST = abs(Normalization-100.0);
|
||||
if (TST > 1.0) {
|
||||
G4String excep = "G4PenelopeBremsstrahlungContinuous - Check the bremms data file";
|
||||
G4Exception(excep);
|
||||
}
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
ReducedCS[i][j] = ReducedCS[i][j]*Normalization;
|
||||
}
|
||||
}
|
||||
|
||||
//Compute the scaled energy loss distribution and sampling parameters
|
||||
// for the energies in the simulation grid
|
||||
|
||||
// Interpolation in E
|
||||
G4double pX[NumberofEPoints];
|
||||
G4double pYY[NumberofEPoints];
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
pX[i] = log(Energies[i]);
|
||||
}
|
||||
|
||||
for (j=0;j<NumberofKPoints;j++){
|
||||
for (i=0;i<NumberofEPoints;i++){
|
||||
pYY[i] = log(ReducedCS[i][j]);
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator2 = new G4PenelopeInterpolator(pX,pYY,NumberofEPoints);
|
||||
for (i=0;i<NumberofExtendedEGrid;i++){
|
||||
G4double ELL = ExtendedLogEnergy[i];
|
||||
if (ELL >= pX[0]) {
|
||||
p0[i][j] = exp(interpolator2->CubicSplineInterpolation(ELL));
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double F1=interpolator2->CubicSplineInterpolation(pX[0]);
|
||||
G4double FP1 = interpolator2->FirstDerivative(pX[0]);
|
||||
p0[i][j] = exp(F1+FP1*(ELL-pX[0]));
|
||||
}
|
||||
}
|
||||
delete interpolator2;
|
||||
}
|
||||
|
||||
//Forse questa roba (e Pbcut come membro privato) non serve
|
||||
// G4double PDF[NumberofKPoints];
|
||||
|
||||
// for (i=0;i<NumberofExtendedEGrid;i++){
|
||||
// for (j=0;j<NumberofKPoints;j++){
|
||||
// PDF[j]=p0[i][j];
|
||||
// }
|
||||
// G4double Xc=0;
|
||||
// if (i<(NumberofExtendedEGrid-1)){
|
||||
// Xc=tCut/exp(ExtendedLogEnergy[i+1]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Xc=tCut/exp(ExtendedLogEnergy[NumberofExtendedEGrid-1]);
|
||||
// }
|
||||
|
||||
// G4PenelopeInterpolator* interpolator3 = new G4PenelopeInterpolator(pK,PDF,NumberofKPoints);
|
||||
// Pbcut[i]=interpolator3->CalculateMomentum(Xc,-1);
|
||||
// delete interpolator3;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
G4double G4PenelopeBremsstrahlungContinuous::CalculateStopping(G4double e1)
|
||||
//Stopping power expressed in MeV/mm*2
|
||||
{
|
||||
G4double Xel=G4std::max(log(e1),ExtendedLogEnergy[0]);
|
||||
G4double Xe=1.0+(Xel-ExtendedLogEnergy[0])*DLFC;
|
||||
G4int Ke = (G4int) Xe;
|
||||
G4double Xek = Xe-Ke;
|
||||
|
||||
//Global x-section factor
|
||||
G4double Fact=pow((G4double) Zmat,2)*(pow(e1+electron_mass_c2,2)/(e1*(e1+2.0*electron_mass_c2)))
|
||||
*(millibarn/cm2);
|
||||
//G4cout << "Particella: " << partName << ";Z: " << Zmat << ";Energia: " << e1 << "; fattore di correzione: "
|
||||
// << PositronCorrection(e1) << G4endl;
|
||||
Fact=Fact*PositronCorrection(e1);
|
||||
|
||||
//Moments of the scaled bremss x-section
|
||||
G4double wcre = tCut/e1;
|
||||
G4double pY[NumberofKPoints];
|
||||
G4double pK[NumberofKPoints] = {1.0e-12,0.05,0.075,0.1,0.125,0.15,0.2,0.25,
|
||||
0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,
|
||||
0.75,0.8,0.85,0.9,0.925,0.95,0.97,0.99,
|
||||
0.995,0.999,0.9995,0.9999,0.99995,0.99999,1.0};
|
||||
|
||||
for (size_t i=0;i<NumberofKPoints;i++){
|
||||
pY[i] = p0[Ke][i];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator1 = new G4PenelopeInterpolator(pK,pY,NumberofKPoints);
|
||||
G4double XS1A = interpolator1->CalculateMomentum(wcre,0);
|
||||
G4double XS2A = interpolator1->CalculateMomentum(wcre,1);
|
||||
delete interpolator1;
|
||||
for (size_t k=0;k<NumberofKPoints;k++){
|
||||
pY[k] = p0[G4std::min(Ke+1,(G4int) NumberofExtendedEGrid-1)][k];
|
||||
}
|
||||
G4PenelopeInterpolator* interpolator2 = new G4PenelopeInterpolator (pK,pY,NumberofKPoints);
|
||||
G4double XS1B = interpolator2->CalculateMomentum(wcre,0);
|
||||
G4double XS2B = interpolator2->CalculateMomentum(wcre,1);
|
||||
delete interpolator2;
|
||||
|
||||
G4double XS1 = ((1.0-Xek)*XS1A+Xek*XS1B)*Fact*e1; //weighted mean between the energy bin of the grid
|
||||
G4double XS2 = ((1.0-Xek)*XS2A+Xek*XS2B)*Fact*e1*e1; //straggling cross section (2nd momentum);
|
||||
//Il secondo momento XS2 potrebbe tornare utile in seguito
|
||||
|
||||
//XS1 is given in MeV*cm2, as in Penelope, but it must be converted in MeV*mm2
|
||||
XS1=XS1*cm2/mm2;
|
||||
//XS2 is given in MeV2*cm2, as in Penelope, but it must be converted in MeV2*mm2
|
||||
XS2=XS2*cm2/mm2;
|
||||
|
||||
//Deve includere anche le famose correzioni per tenere conto
|
||||
//che la sezione d'urto varia sullo step!
|
||||
//Il valore che tira fuori va nella tabella e non viene piu' modificato
|
||||
return XS1;
|
||||
}
|
||||
|
||||
G4double G4PenelopeBremsstrahlungContinuous::PositronCorrection(G4double en)
|
||||
{
|
||||
const G4double Coeff[7]={-1.2359e-01,6.1274e-2,-3.1516e-2,7.7446e-3,-1.0595e-3,
|
||||
7.0568e-5,-1.8080e-6};
|
||||
G4double T=0;
|
||||
G4double correct=0;
|
||||
if (partName == "e-") {
|
||||
return 1.0; //no correction for electrons
|
||||
}
|
||||
else if (partName == "e+"){
|
||||
T=log(1+((1e6*en)/(pow( (G4double) Zmat,2)*electron_mass_c2)));
|
||||
for (G4int i=0;i<7;i++){
|
||||
correct += Coeff[i]*pow(T,i+1);
|
||||
}
|
||||
correct = 1.0-exp(correct);
|
||||
return correct;
|
||||
}
|
||||
else //ne' elettroni ne' positroni...exception
|
||||
{
|
||||
G4String excep = "G4PenelopeBremmstrahlungContinuous: the particle is not e- nor e+!";
|
||||
G4Exception(excep);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,660 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeCompton.cc,v 1.10 2003/03/13 16:56:40 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Luciano Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 12 Feb 2003 MG Pia const argument in SelectRandomAtomForCompton
|
||||
// Migration to "cuts per region"
|
||||
// 14 Feb 2003 MG Pia Corrected compilation errors and warnings
|
||||
// from SUN
|
||||
// Modified some variables to lowercase initial
|
||||
// 10 Mar 2003 V.Ivanchenko Remove CutPerMaterial warning
|
||||
// 13 Mar 2003 L.Pandola Code "cleaned"
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeCompton.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 "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4VRangeTest.hh"
|
||||
#include "G4RangeTest.hh"
|
||||
#include "G4PenelopeIntegrator.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
|
||||
G4PenelopeCompton::G4PenelopeCompton(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
lowEnergyLimit(250*eV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV),
|
||||
energyForIntegration(0.0),
|
||||
ZForIntegration(1),
|
||||
nBins(200)
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4PenelopeCompton::G4PenelopeCompton - energy outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
meanFreePathTable = 0;
|
||||
ionizationEnergy = new G4std::vector<G4DataVector*>;
|
||||
hartreeFunction = new G4std::vector<G4DataVector*>;
|
||||
occupationNumber = new G4std::vector<G4DataVector*>;
|
||||
rangeTest = new G4RangeTest;
|
||||
|
||||
ReadData(); //Legge i dati da file!
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4PenelopeCompton::~G4PenelopeCompton()
|
||||
{
|
||||
delete meanFreePathTable;
|
||||
delete rangeTest;
|
||||
delete matCrossSections;
|
||||
delete ionizationEnergy;
|
||||
delete hartreeFunction;
|
||||
delete occupationNumber;
|
||||
}
|
||||
|
||||
void G4PenelopeCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
G4DataVector energyVector;
|
||||
G4double dBin = log10(highEnergyLimit/lowEnergyLimit)/nBins;
|
||||
G4int i;
|
||||
for (i=0;i<nBins;i++)
|
||||
{
|
||||
energyVector.push_back(pow(10.,log10(lowEnergyLimit)+i*dBin));
|
||||
}
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4VDataSetAlgorithm* algo = new G4LogLogInterpolation();
|
||||
|
||||
size_t nOfBins = energyVector.size();
|
||||
size_t bin=0;
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* data;
|
||||
|
||||
matCrossSections = new G4std::vector<G4VEMDataSet*>;
|
||||
|
||||
|
||||
G4int m;
|
||||
for (m=0; m<nMaterials; m++)
|
||||
{
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double* nAtomsPerVolume = material->GetAtomicNumDensityVector();
|
||||
|
||||
G4VEMDataSet* setForMat = new G4CompositeEMDataSet(algo,1.,1.);
|
||||
|
||||
for (i=0; i<nElements; i++) {
|
||||
|
||||
G4int Z = (G4int) (*elementVector)[i]->GetZ();
|
||||
G4double density = nAtomsPerVolume[i];
|
||||
G4double cross=0.0;
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
|
||||
|
||||
for (bin=0; bin<nOfBins; bin++)
|
||||
{
|
||||
G4double e = energyVector[bin];
|
||||
energies->push_back(e);
|
||||
cross = density * CrossSection(e,Z);
|
||||
data->push_back(cross);
|
||||
}
|
||||
|
||||
G4VEMDataSet* elSet = new G4EMDataSet(i,energies,data,algo,1.,1.);
|
||||
setForMat->AddComponent(elSet);
|
||||
}
|
||||
|
||||
matCrossSections->push_back(setForMat);
|
||||
}
|
||||
|
||||
G4double matCS = 0.0;
|
||||
G4VEMDataSet* matCrossSet = new G4CompositeEMDataSet(algo,1.,1.);
|
||||
G4VEMDataSet* materialSet = new G4CompositeEMDataSet(algo,1.,1.);
|
||||
|
||||
|
||||
for (m=0; m<nMaterials; m++)
|
||||
{
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
const G4Material* material= (*materialTable)[m];
|
||||
material= (*materialTable)[m];
|
||||
for (bin=0; bin<nOfBins; bin++)
|
||||
{
|
||||
G4double energy = energyVector[bin];
|
||||
energies->push_back(energy);
|
||||
matCrossSet = (*matCrossSections)[m];
|
||||
matCS = 0.0;
|
||||
G4int nElm = matCrossSet->NumberOfComponents();
|
||||
for(G4int j=0; j<nElm; j++) {
|
||||
matCS += matCrossSet->GetComponent(j)->FindValue(energy);
|
||||
}
|
||||
if (matCS > 0.)
|
||||
{
|
||||
data->push_back(1./matCS);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->push_back(DBL_MAX);
|
||||
}
|
||||
}
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(m,energies,data,algo,1.,1.);
|
||||
materialSet->AddComponent(dataSet);
|
||||
}
|
||||
meanFreePathTable = materialSet;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4PenelopeCompton::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
//Penelope model
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
// Dynamic particle quantities
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
|
||||
if (photonEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(photonEnergy0);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4int Z = SelectRandomAtomForCompton(material,photonEnergy0);
|
||||
const G4int nmax = 64;
|
||||
G4double rn[nmax],pac[nmax];
|
||||
|
||||
G4double ki,ki1,ki2,ki3,taumin,a1,a2;
|
||||
G4double tau,TST;
|
||||
G4double S=0.0;
|
||||
G4double epsilon,cosTheta;
|
||||
G4double harFunc = 0.0;
|
||||
G4int occupNb= 0;
|
||||
G4double ionEnergy=0.0;
|
||||
G4int nosc = ((*occupationNumber)[Z-1])->size();
|
||||
G4int iosc = nosc;
|
||||
ki = photonEnergy0/electron_mass_c2;
|
||||
ki2 = 2*ki+1.0;
|
||||
ki3 = ki*ki;
|
||||
ki1 = ki3-ki2-1.0;
|
||||
taumin = 1.0/ki2;
|
||||
a1 = log(ki2);
|
||||
a2 = a1+2.0*ki*(1.0+ki)/(ki2*ki2);
|
||||
if (photonEnergy0 > 5*MeV)
|
||||
{
|
||||
do{
|
||||
do{
|
||||
if ((a2*G4UniformRand()) < a1)
|
||||
{
|
||||
tau = pow(taumin,G4UniformRand());
|
||||
}
|
||||
else
|
||||
{
|
||||
tau = sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));
|
||||
}
|
||||
//rejection function
|
||||
TST = (1+tau*(ki1+tau*(ki2+tau*ki3)))/(ki3*tau*(1.0+tau*tau));
|
||||
}while (G4UniformRand()> TST);
|
||||
epsilon=tau;
|
||||
cosTheta = 1.0 - (1.0-tau)/(ki*tau);
|
||||
//Target shell electrons
|
||||
TST = Z*G4UniformRand();
|
||||
iosc = nosc;
|
||||
S=0.0;
|
||||
for (G4int j=0;j<nosc;j++)
|
||||
{
|
||||
occupNb = (G4int) (*((*occupationNumber)[Z-1]))[j];
|
||||
S = S + occupNb;
|
||||
if (S > TST) iosc = j;
|
||||
if (S > TST) break;
|
||||
}
|
||||
ionEnergy = (*((*ionizationEnergy)[Z-1]))[iosc];
|
||||
}while((epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
|
||||
}
|
||||
|
||||
else //photonEnergy0<5 MeV
|
||||
{
|
||||
//Incoherent scattering function for theta=PI
|
||||
G4double s0=0.0;
|
||||
G4double pzomc=0.0,rni=0.0;
|
||||
G4double aux=0.0;
|
||||
for (G4int i=0;i<nosc;i++){
|
||||
ionEnergy = (*((*ionizationEnergy)[Z-1]))[i];
|
||||
if (photonEnergy0 > ionEnergy)
|
||||
{
|
||||
G4double aux = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
|
||||
harFunc = (*((*hartreeFunction)[Z-1]))[i]/fine_structure_const;
|
||||
occupNb = (G4int) (*((*occupationNumber)[Z-1]))[i];
|
||||
pzomc = harFunc*(aux-electron_mass_c2*ionEnergy)/
|
||||
(electron_mass_c2*sqrt(2.0*aux+pow(ionEnergy,2)));
|
||||
if (pzomc > 0)
|
||||
{
|
||||
rni = 1.0-0.5*exp(0.5-pow(sqrt(0.5)+sqrt(2.0)*pzomc,2));
|
||||
}
|
||||
else
|
||||
{
|
||||
rni = 0.5*exp(0.5-pow(sqrt(0.5)-sqrt(2.0)*pzomc,2));
|
||||
}
|
||||
s0 = s0 + occupNb*rni;
|
||||
}
|
||||
}
|
||||
|
||||
//Sampling tau
|
||||
G4double cdt1;
|
||||
do
|
||||
{
|
||||
if ((G4UniformRand()*a2) < a1)
|
||||
{
|
||||
tau = pow(taumin,G4UniformRand());
|
||||
}
|
||||
else
|
||||
{
|
||||
tau = sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));
|
||||
}
|
||||
cdt1 = (1.0-tau)/(ki*tau);
|
||||
S=0.0;
|
||||
//Incoherent scattering function
|
||||
for (G4int i=0;i<nosc;i++){
|
||||
ionEnergy = (*((*ionizationEnergy)[Z-1]))[i];
|
||||
if (photonEnergy0 > ionEnergy) //sum only on excitable levels
|
||||
{
|
||||
aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
|
||||
harFunc = (*((*hartreeFunction)[Z-1]))[i]/fine_structure_const;
|
||||
occupNb = (G4int) (*((*occupationNumber)[Z-1]))[i];
|
||||
pzomc = harFunc*(aux-electron_mass_c2*ionEnergy)/
|
||||
(electron_mass_c2*sqrt(2.0*aux+pow(ionEnergy,2)));
|
||||
if (pzomc > 0)
|
||||
{
|
||||
rn[i] = 1.0-0.5*exp(0.5-pow(sqrt(0.5)+sqrt(2.0)*pzomc,2));
|
||||
}
|
||||
else
|
||||
{
|
||||
rn[i] = 0.5*exp(0.5-pow(sqrt(0.5)-sqrt(2.0)*pzomc,2));
|
||||
}
|
||||
S = S + occupNb*rn[i];
|
||||
pac[i] = S;
|
||||
}
|
||||
else
|
||||
{
|
||||
pac[i] = S-(1e-06);
|
||||
}
|
||||
}
|
||||
//Rejection function
|
||||
TST = S*(1.0+tau*(ki1+tau*(ki2+tau*ki3)))/(ki3*tau*(1.0+tau*tau));
|
||||
}while ((G4UniformRand()*s0) > TST);
|
||||
|
||||
//Target electron shell
|
||||
cosTheta = 1.0 - cdt1;
|
||||
G4double fpzmax=0.0,fpz=0.0;
|
||||
G4double A=0.0;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
TST =S*G4UniformRand();
|
||||
iosc=nosc;
|
||||
for (G4int i=0;i<nosc;i++){
|
||||
if (pac[i]>TST) iosc = i;
|
||||
if (pac[i]>TST) break;
|
||||
}
|
||||
A = G4UniformRand()*rn[iosc];
|
||||
harFunc = (*((*hartreeFunction)[Z-1]))[iosc]/fine_structure_const;
|
||||
occupNb = (G4int) (*((*occupationNumber)[Z-1]))[iosc];
|
||||
if (A < 0.5) {
|
||||
pzomc = (sqrt(0.5)-sqrt(0.5-log(2.0*A)))/
|
||||
(sqrt(2.0)*harFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
pzomc = (sqrt(0.5-log(2.0-2.0*A))-sqrt(0.5))/
|
||||
(sqrt(2.0)*harFunc);
|
||||
}
|
||||
} while (pzomc < -1);
|
||||
// F(EP) rejection
|
||||
G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
|
||||
G4double AF = sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
|
||||
if (AF > 0) {
|
||||
fpzmax = 1.0+AF*0.2;
|
||||
}
|
||||
else
|
||||
{
|
||||
fpzmax = 1.0-AF*0.2;
|
||||
}
|
||||
fpz = 1.0+AF*G4std::max(G4std::min(pzomc,0.2),-0.2);
|
||||
}while ((fpzmax*G4UniformRand())>fpz);
|
||||
|
||||
//Energy of the scattered photon
|
||||
G4double T = pow(pzomc,2);
|
||||
G4double b1 = 1.0-T*tau*tau;
|
||||
G4double b2 = 1.0-T*tau*cosTheta;
|
||||
if (pzomc > 0.0)
|
||||
{
|
||||
epsilon = (tau/b1)*(b2+sqrt(abs(b2*b2-b1*(1.0-T))));
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilon = (tau/b1)*(b2-sqrt(abs(b2*b2-b1*(1.0-T))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double sinTheta = sqrt(1-pow(cosTheta,2));
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// Kinematics of the scattered electron
|
||||
|
||||
G4double diffEnergy = photonEnergy0*(1-epsilon);
|
||||
ionEnergy = (*((*ionizationEnergy)[Z-1]))[iosc];
|
||||
G4double eKineticEnergy = diffEnergy - ionEnergy;
|
||||
G4double Q2 = pow(photonEnergy0,2)+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
|
||||
G4double cosThetaE; //scattering angle for the electron
|
||||
if (Q2 > 1.0e-12)
|
||||
{
|
||||
cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/sqrt(Q2);
|
||||
}
|
||||
else
|
||||
{
|
||||
cosThetaE = 1.0;
|
||||
}
|
||||
G4double sinThetaE = sqrt(1-pow(cosThetaE,2));
|
||||
|
||||
// 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(),couple,eKineticEnergy,safety))
|
||||
{
|
||||
G4double xEl = sinThetaE * cos(phi+pi);
|
||||
G4double yEl = sinThetaE * sin(phi+pi);
|
||||
G4double zEl = cosThetaE;
|
||||
G4ThreeVector eDirection(xEl,yEl,zEl); //electron direction
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
G4bool G4PenelopeCompton::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4PenelopeCompton::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 G4PenelopeCompton::ReadData()
|
||||
{
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4PenelopeCompton - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/comptondata.dat";
|
||||
G4std::ifstream file(pathFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (!(lsdp->is_open()))
|
||||
{
|
||||
G4String excep = "G4PenelopeCompton - data file " + pathFile + " not found!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
file.close();
|
||||
|
||||
//This algorithm is slow and unelegant!
|
||||
//It must be improved.
|
||||
G4int k1,k2;
|
||||
G4double a1,a2;
|
||||
G4int Z=0;
|
||||
G4DataVector* f;
|
||||
G4DataVector* u;
|
||||
G4DataVector* j;
|
||||
for(Z=1;Z<93;Z++) {
|
||||
f = new G4DataVector;
|
||||
u = new G4DataVector;
|
||||
j = new G4DataVector;
|
||||
G4std::ifstream file(pathFile);
|
||||
k1=1;
|
||||
while (k1>0)
|
||||
{
|
||||
file >> k1 >> k2 >> a1 >> a2;
|
||||
if(k1 == Z)
|
||||
{
|
||||
f->push_back((G4double) k2);
|
||||
u->push_back(a1);
|
||||
j->push_back(a2);
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
ionizationEnergy->push_back(u);
|
||||
hartreeFunction->push_back(j);
|
||||
occupationNumber->push_back(f);
|
||||
}
|
||||
//(*((*ionizationEnergy)[Z-1]))[i] contains the ionization energy of the i-th level of
|
||||
//the element Z
|
||||
};
|
||||
|
||||
G4double G4PenelopeCompton::CrossSection(G4double energy,G4int Z)
|
||||
{
|
||||
G4double cs=0.0;
|
||||
energyForIntegration=energy;
|
||||
ZForIntegration = Z;
|
||||
if (energy< 5*MeV)
|
||||
{
|
||||
G4PenelopeIntegrator<G4PenelopeCompton,G4double (G4PenelopeCompton::*)(G4double)> theIntegrator;
|
||||
cs = theIntegrator.Calculate(this,&G4PenelopeCompton::DifferentialCrossSection,-1.0,1.0,1e-05);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double ki=energy/electron_mass_c2;
|
||||
G4double ki3=ki*ki;
|
||||
G4double ki2=1.0+2*ki;
|
||||
G4double ki1=ki3-ki2-1.0;
|
||||
G4double t0=1.0/(ki2);
|
||||
G4double csl = 0.5*ki3*t0*t0+ki2*t0+ki1*log(t0)-(1.0/t0);
|
||||
G4int nosc = ((*occupationNumber)[Z-1])->size();
|
||||
for (G4int i=0;i<nosc;i++)
|
||||
{
|
||||
G4double ionEnergy = (*((*ionizationEnergy)[Z-1]))[i];
|
||||
G4double tau=(energy-ionEnergy)/energy;
|
||||
if (tau > t0)
|
||||
{
|
||||
G4double csu = 0.5*ki3*tau*tau+ki2*tau+ki1*log(tau)-(1.0/tau);
|
||||
G4int f = (G4int) (*((*occupationNumber)[Z-1]))[i];
|
||||
cs = cs + f*(csu-csl);
|
||||
}
|
||||
}
|
||||
cs=pi*classic_electr_radius*classic_electr_radius*cs/(ki*ki3);
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
|
||||
G4double G4PenelopeCompton::DifferentialCrossSection(G4double cosTheta)
|
||||
{
|
||||
const G4double k2 = sqrt(2.0);
|
||||
const G4double k1 = sqrt(0.5);
|
||||
const G4double k12 = 0.5;
|
||||
G4double cdt1 = 1.0-cosTheta;
|
||||
G4double energy = energyForIntegration;
|
||||
G4int Z = ZForIntegration;
|
||||
G4double ionEnergy=0.0,Pzimax=0.0,XKN=0.0;
|
||||
G4double diffCS=0.0;
|
||||
G4double x=0.0,siap=0.0;
|
||||
G4double harFunc=0.0;
|
||||
G4int occupNb;
|
||||
//energy of Compton line;
|
||||
G4double EOEC = 1.0+(energy/electron_mass_c2)*cdt1;
|
||||
G4double ECOE = 1.0/EOEC;
|
||||
//Incoherent scattering function (analytical profile)
|
||||
G4double sia = 0.0;
|
||||
G4int nosc = ((*occupationNumber)[Z-1])->size();
|
||||
for (G4int i=0;i<nosc;i++){
|
||||
ionEnergy = (*((*ionizationEnergy)[Z-1]))[i];
|
||||
//Sum only of those shells for which E>Eion
|
||||
if (energy > ionEnergy)
|
||||
{
|
||||
G4double aux = energy * (energy-ionEnergy)*cdt1;
|
||||
Pzimax = (aux - electron_mass_c2*ionEnergy)/(electron_mass_c2*sqrt(2*aux+pow(ionEnergy,2)));
|
||||
harFunc = (*((*hartreeFunction)[Z-1]))[i]/fine_structure_const;
|
||||
occupNb = (G4int) (*((*occupationNumber)[Z-1]))[i];
|
||||
x = harFunc*Pzimax;
|
||||
if (x > 0)
|
||||
{
|
||||
siap = 1.0-0.5*exp(k12-pow((k1+k2*x),2));
|
||||
}
|
||||
else
|
||||
{
|
||||
siap = 0.5*exp(k12-pow((k1-k2*x),2));
|
||||
}
|
||||
sia = sia + occupNb*siap; //sum of all contributions;
|
||||
}
|
||||
}
|
||||
XKN = EOEC+ECOE-1+cosTheta*cosTheta;
|
||||
diffCS = pi*pow(classic_electr_radius,2)*pow(ECOE,2)*XKN*sia;
|
||||
return diffCS;
|
||||
}
|
||||
|
||||
G4int G4PenelopeCompton::SelectRandomAtomForCompton(const G4Material* material,G4double energy) const
|
||||
{
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
//Special case: the material consists of one element
|
||||
if (nElements == 1)
|
||||
{
|
||||
G4int Z = (G4int) material->GetZ();
|
||||
return Z;
|
||||
}
|
||||
|
||||
//Composite material
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
|
||||
G4VEMDataSet* materialSet = (*matCrossSections)[materialIndex];
|
||||
G4double materialCrossSection0 = 0.0;
|
||||
G4DataVector cross;
|
||||
cross.clear();
|
||||
G4int i;
|
||||
for (i=0;i<nElements;i++)
|
||||
{
|
||||
G4double cr = (materialSet->GetComponent(i))->FindValue(energy);
|
||||
materialCrossSection0 += cr;
|
||||
cross.push_back(materialCrossSection0); //cumulative cross section
|
||||
}
|
||||
|
||||
G4double random = G4UniformRand()*materialCrossSection0;
|
||||
for (i=0;i<nElements;i++)
|
||||
{
|
||||
if (random <= cross[i]) return (G4int) (*elementVector)[i]->GetZ();
|
||||
}
|
||||
//It should never get here
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,379 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
// Author: L.Pandola
|
||||
// History:
|
||||
// --------
|
||||
// 02 Dec 2002 L.Pandola 1st implementation
|
||||
// 12 Feb 2003 MG Pia Migration to "cuts per region"
|
||||
// 10 Mar 2003 V.Ivanchenko Remove CutPerMaterial warning
|
||||
// 13 Mar 2003 L.Pandola Code "cleaned"
|
||||
// 25 Mar 2003 L.Pandola Changed the name of the database file to read
|
||||
// 24 Apr 2003 V.Ivanchenko Cut per region mfpt
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeGammaConversion.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 "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 "G4MaterialCutsCouple.hh"
|
||||
|
||||
|
||||
G4PenelopeGammaConversion::G4PenelopeGammaConversion(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
lowEnergyLimit(1.022000*MeV),
|
||||
highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(1.022000*MeV),
|
||||
intrinsicHighEnergyLimit(100*GeV),
|
||||
smallEnergy(1.1*MeV)
|
||||
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4PenelopeGammaConversion::G4PenelopeGammaConversion - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
// The following pointer is owned by G4DataHandler
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
// Log log interpolation (default)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
G4PenelopeGammaConversion::~G4PenelopeGammaConversion()
|
||||
{
|
||||
delete meanFreePathTable;
|
||||
delete crossSectionHandler;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
void G4PenelopeGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "penelope/pp-cs-pen-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4PenelopeGammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy = incidentPhoton->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
|
||||
|
||||
G4double eps ;
|
||||
G4double eki = electron_mass_c2 / photonEnergy ;
|
||||
|
||||
// Do it fast if photon energy < 1.1 MeV
|
||||
if (photonEnergy < smallEnergy )
|
||||
{
|
||||
eps = eki + (1-2*eki) * G4UniformRand();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select randomly one element in the current material
|
||||
const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
|
||||
|
||||
if (element == 0)
|
||||
{
|
||||
G4cout << "G4PenelopeGammaConversion::PostStepDoIt - element = 0" << G4endl;
|
||||
}
|
||||
G4IonisParamElm* ionisation = element->GetIonisation();
|
||||
if (ionisation == 0)
|
||||
{
|
||||
G4cout << "G4PenelopeGammaConversion::PostStepDoIt - ionisation = 0" << G4endl;
|
||||
}
|
||||
|
||||
//Low energy and Coulomb corrections
|
||||
G4double Z=ionisation->GetZ();
|
||||
G4double ZAlpha = Z*fine_structure_const;
|
||||
G4double ScreenRadius = GetScreeningRadius(Z);
|
||||
G4double funct1=0,g0=0;
|
||||
G4double g1min=0,g2min=0;
|
||||
funct1 = 4.0*log(ScreenRadius);
|
||||
g0 = funct1-4*CoulombCorrection(ZAlpha)+LowEnergyCorrection(ZAlpha,eki);
|
||||
G4double bmin = 2*eki*ScreenRadius;
|
||||
g1min=g0+ScreenFunction(bmin,1);
|
||||
g2min=g0+ScreenFunction(bmin,2);
|
||||
G4double xr,a1,p1;
|
||||
xr=0.5-eki;
|
||||
a1=(2.0/3.0)*g1min*xr*xr;
|
||||
p1=a1/(a1+g2min);
|
||||
|
||||
//Random sampling of eps
|
||||
G4double rand1,rand2,rand3,b;
|
||||
G4double g1;
|
||||
|
||||
do{
|
||||
rand1 = G4UniformRand();
|
||||
if (rand1 < p1) {
|
||||
rand2 = 2.0*G4UniformRand()-1.0;
|
||||
if (rand2 < 0) {
|
||||
eps = 0.5 - xr*pow(abs(rand2),(1./3.));
|
||||
}
|
||||
else
|
||||
{
|
||||
eps = 0.5 + xr*pow(rand2,(1./3.));
|
||||
}
|
||||
b = (eki*ScreenRadius)/(2*eps*(1.0-eps));
|
||||
g1 = g0+ScreenFunction(b,1);
|
||||
if (g1 < 0) g1=0;
|
||||
rand3 = G4UniformRand()*g1min;
|
||||
}
|
||||
else
|
||||
{
|
||||
eps = eki+2.0*xr*G4UniformRand();
|
||||
b = (eki*ScreenRadius)/(2*eps*(1.0-eps));
|
||||
g1 = g0+ScreenFunction(b,2);
|
||||
if (g1 < 0) g1=0;
|
||||
rand3 = G4UniformRand()*g2min;
|
||||
}
|
||||
} while (rand3>g1);
|
||||
} //End of eps sampling
|
||||
|
||||
G4double electronTotEnergy;
|
||||
G4double positronTotEnergy;
|
||||
|
||||
electronTotEnergy = eps*photonEnergy;
|
||||
positronTotEnergy = (1.0-eps)*photonEnergy;
|
||||
|
||||
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
|
||||
//electron kinematics
|
||||
G4double costheta_el,costheta_po;
|
||||
G4double phi_el,phi_po;
|
||||
G4double electronKineEnergy = G4std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
costheta_el = G4UniformRand()*2.0-1.0;
|
||||
G4double kk = sqrt(electronKineEnergy*(electronKineEnergy+2.*electron_mass_c2));
|
||||
costheta_el = (costheta_el*electronTotEnergy+kk)/(electronTotEnergy+costheta_el*kk);
|
||||
phi_el = twopi * G4UniformRand() ;
|
||||
G4double dirX_el = sqrt(1.-costheta_el*costheta_el) * cos(phi_el);
|
||||
G4double dirY_el = sqrt(1.-costheta_el*costheta_el) * sin(phi_el);
|
||||
G4double dirZ_el = costheta_el;
|
||||
|
||||
//positron kinematics
|
||||
G4double positronKineEnergy = G4std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
costheta_po = G4UniformRand()*2.0-1.0;
|
||||
kk = sqrt(positronKineEnergy*(positronKineEnergy+2.*electron_mass_c2));
|
||||
costheta_po = (costheta_po*positronTotEnergy+kk)/(positronTotEnergy+costheta_po*kk);
|
||||
phi_po = twopi * G4UniformRand() ;
|
||||
G4double dirX_po = sqrt(1.-costheta_po*costheta_po) * cos(phi_po);
|
||||
G4double dirY_po = sqrt(1.-costheta_po*costheta_po) * sin(phi_po);
|
||||
G4double dirZ_po = costheta_po;
|
||||
|
||||
// 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
|
||||
|
||||
G4double localEnergyDeposit = 0. ;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2) ;
|
||||
|
||||
|
||||
// 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(),couple,electronKineEnergy,safety))
|
||||
{
|
||||
G4ThreeVector electronDirection ( dirX_el, dirY_el, dirZ_el);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
aParticleChange.AddSecondary(particle1) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += electronKineEnergy ;
|
||||
}
|
||||
|
||||
|
||||
if (! (rangeTest->Escape(G4Positron::Positron(),couple,positronKineEnergy,safety)))
|
||||
{
|
||||
localEnergyDeposit += positronKineEnergy ;
|
||||
positronKineEnergy = 0. ;
|
||||
}
|
||||
G4ThreeVector positronDirection(dirX_po,dirY_po,dirZ_po);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection, positronKineEnergy);
|
||||
aParticleChange.AddSecondary(particle2) ;
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(localEnergyDeposit) ;
|
||||
|
||||
// Kill the incident photon
|
||||
aParticleChange.SetMomentumChange(0.,0.,0.) ;
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill) ;
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
G4bool G4PenelopeGammaConversion::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4PenelopeGammaConversion::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
size_t materialIndex = couple->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;
|
||||
}
|
||||
|
||||
G4double G4PenelopeGammaConversion::ScreenFunction(G4double b,G4int icase)
|
||||
{
|
||||
G4double bsquare=b*b;
|
||||
G4double a0,f1,f2,g1,g2;
|
||||
f1=2.0-2*log(1+bsquare);
|
||||
f2=f1-(2.0/3.0);
|
||||
if (b < 1.0e-10)
|
||||
{
|
||||
f1=f1-twopi*b;
|
||||
}
|
||||
else
|
||||
{
|
||||
a0 = 4*b*atan(1.0/b);
|
||||
f1 = f1 - a0;
|
||||
f2 = f2+2*bsquare*(4.0-a0-3*log((1+bsquare)/bsquare));
|
||||
}
|
||||
g1=0.5*(3*f1-f2);
|
||||
g2=0.25*(3*f1+f2);
|
||||
if (icase==1) {
|
||||
return g1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g2;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4PenelopeGammaConversion::CoulombCorrection(G4double a)
|
||||
{
|
||||
G4double fc=0;
|
||||
G4double b[7] = {0.202059,-0.03693,0.00835,-0.00201,0.00049,-0.00012,0.00003};
|
||||
fc = ((1.0/(1.0+a*a))+b[0]+b[1]*pow(a,2)+b[2]*pow(a,4)+b[3]*pow(a,6)+b[4]*pow(a,8)+b[5]*pow(a,10)+b[6]*pow(a,12));
|
||||
fc=pow(a,2)*fc;
|
||||
return fc;
|
||||
}
|
||||
|
||||
G4double G4PenelopeGammaConversion::LowEnergyCorrection(G4double a,G4double eki)
|
||||
{
|
||||
G4double f0=0,t=0;
|
||||
G4double b[12] = {-1.744,-12.10,11.18,8.523,73.26,-41.41,-13.52,-121.1,94.41,8.946,62.05,-63.41};
|
||||
t=sqrt(2.0*eki);
|
||||
f0=(b[0]+b[1]*a+b[2]*a*a)*t+(b[3]+b[4]*a+b[5]*a*a)*pow(t,2)+(b[6]+b[7]*a+b[8]*a*a)*pow(t,3)+
|
||||
(b[9]+b[10]*a+b[11]*a*a)*pow(t,4);
|
||||
return f0;
|
||||
}
|
||||
|
||||
G4double G4PenelopeGammaConversion::GetScreeningRadius(G4double Z)
|
||||
{
|
||||
char* path = getenv("G4LEDATA");
|
||||
if (!path)
|
||||
{
|
||||
G4String excep = "G4PenelopeGammaConversion - G4LEDATA environment variable not set!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4String pathString(path);
|
||||
G4String pathFile = pathString + "/penelope/pp-pen.dat";
|
||||
G4std::ifstream file(pathFile);
|
||||
G4std::filebuf* lsdp = file.rdbuf();
|
||||
|
||||
if (!(lsdp->is_open()))
|
||||
{
|
||||
G4String excep = "G4PenelopeGammaConversion - data file " + pathFile + "not found!";
|
||||
G4Exception(excep);
|
||||
}
|
||||
G4int k;
|
||||
G4double a1,a2;
|
||||
while(!file.eof()) {
|
||||
file >> k >> a1 >> a2;
|
||||
if ((G4double) k == Z)
|
||||
{
|
||||
return a1;
|
||||
}
|
||||
}
|
||||
G4String excep = "G4PenelopeGammaConversion - Screening Radius for not found in the data file";
|
||||
G4Exception(excep);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author: Luciano Pandola (Luciano.Pandola@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 17 Feb 2003 LP Created
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeInterpolator.hh"
|
||||
#include "G4DataVector.hh"
|
||||
|
||||
G4PenelopeInterpolator::G4PenelopeInterpolator(G4double* pX,G4double* pY,G4int nOfData,G4double S1,G4double SN) :
|
||||
a(0),b(0),c(0),d(0),x(0),y(0)
|
||||
{
|
||||
// pX = X grid points (ascending order)
|
||||
// pY = corresponding function values
|
||||
// nOfData = number of points in the grid > 4
|
||||
// S1 and S2 = second derivatives at X[0] and X[nOfData-1]
|
||||
a = new G4DataVector;
|
||||
b = new G4DataVector;
|
||||
c = new G4DataVector;
|
||||
d = new G4DataVector;
|
||||
|
||||
if (nOfData < 4 )
|
||||
{
|
||||
G4String excep = "Spline interpolation cannot be performed with less than 4 points";
|
||||
G4Exception(excep);
|
||||
}
|
||||
|
||||
G4int N1=nOfData-1;
|
||||
G4int N2=nOfData-2;
|
||||
G4int i;
|
||||
G4int k=0;
|
||||
G4DataVector A(N1),B(N2),D(nOfData);//auxiliary arrays
|
||||
A.clear();
|
||||
B.clear();
|
||||
D.clear();
|
||||
for (i=0;i<N1;i++){
|
||||
if ((pX[i+1]-pX[i]) < 1.0e-13)
|
||||
{
|
||||
G4String excep = "Spline x values not in increasing order";
|
||||
G4Exception(excep);
|
||||
}
|
||||
A.push_back(pX[i+1]-pX[i]);
|
||||
D.push_back((pY[i+1]-pY[i])/A[i]);
|
||||
}
|
||||
|
||||
//Symmetric coefficient matrix
|
||||
for (i=0;i<N2;i++){
|
||||
B.push_back(2.0*(A[i]+A[i+1]));
|
||||
k=N1-i-1;
|
||||
D[k]=6.0*(D[k]-D[k-1]);
|
||||
}
|
||||
D[1]=D[1]-A[0]*S1;
|
||||
D[N1-1]=D[N1-1]-A[N1-1]*SN;
|
||||
|
||||
//Gauss solution of the tridiagonal system
|
||||
for (i=1;i<N2;i++){
|
||||
G4double R=A[i]/B[i-1];
|
||||
B[i]=B[i]-R*A[i];
|
||||
D[i+1]=D[i+1]-R*D[i];
|
||||
}
|
||||
|
||||
//The sigma coefficients are stored in array D
|
||||
D[N1-1]=D[N1-1]/B[N2-1];
|
||||
for (i=1;i<N2;i++){
|
||||
k=N1-i-1;
|
||||
D[k]=(D[k]-A[k]*D[k+1])/B[k-1];
|
||||
}
|
||||
D.push_back(SN);
|
||||
|
||||
//Spline coefficients
|
||||
G4double SI1=S1;
|
||||
G4double SI=0,H=0,HI=0;
|
||||
G4double store=0;
|
||||
for (i=0;i<N1;i++){
|
||||
SI=SI1;
|
||||
SI1=D[i+1];
|
||||
H=A[i];
|
||||
HI=1.0/H;
|
||||
store=HI*(SI*pow(pX[i+1],3)-SI1*pow(pX[i],3))/6.0+HI*(pY[i]*pX[i+1]-pY[i+1]*pX[i])+
|
||||
H*(SI1*pX[i]-SI*pX[i+1])/6.0;
|
||||
a->push_back(store);
|
||||
store=(HI/2.0)*(SI1*pow(pX[i],2)-SI*pow(pX[i+1],2))+HI*(pY[i+1]-pY[i])+(H/6.0)*(SI-SI1);
|
||||
b->push_back(store);
|
||||
store=(HI/2.0)*(SI*pX[i+1]-SI1*pX[i]);
|
||||
c->push_back(store);
|
||||
store=(HI/6.0)*(SI1-SI);
|
||||
d->push_back(store);
|
||||
}
|
||||
//Natural cubic spline for x > x[nOfData-1]
|
||||
G4double FN=pY[nOfData-1];
|
||||
store=(*b)[N1-1]+pX[nOfData-1]*(2.0*(*c)[N1-1]+pX[nOfData-1]*3.0*(*d)[N1-1]);
|
||||
a->push_back(FN-pX[nOfData-1]*store);
|
||||
b->push_back(store);
|
||||
c->push_back(0.0);
|
||||
d->push_back(0.0);
|
||||
|
||||
x = new G4DataVector;
|
||||
y = new G4DataVector;
|
||||
|
||||
for (i=0;i<nOfData;i++){
|
||||
x->push_back(pX[i]);
|
||||
y->push_back(pY[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
G4double G4PenelopeInterpolator::CubicSplineInterpolation(G4double xx)
|
||||
{
|
||||
G4double interp=0;
|
||||
G4int index = FindBin(xx);
|
||||
interp=(*a)[index]+xx*((*b)[index]+xx*((*c)[index]+xx*(*d)[index]));
|
||||
return interp;
|
||||
}
|
||||
|
||||
G4double G4PenelopeInterpolator::FirstDerivative(G4double xx)
|
||||
{
|
||||
G4double interp=0;
|
||||
G4int index = FindBin(xx);
|
||||
interp=(*b)[index]+xx*((*c)[index]*2.0+xx*(*d)[index]*3.0);
|
||||
return interp;
|
||||
}
|
||||
|
||||
G4double G4PenelopeInterpolator::CalculateMomentum(G4double UpperLimit,
|
||||
G4int MomentumOrder)
|
||||
{
|
||||
G4int i;
|
||||
G4int nOfData = (G4int) x->size();
|
||||
const G4double eps=1.0e-35;
|
||||
if (MomentumOrder < -1) G4Exception("Calculate Momentum: error 0");
|
||||
if (nOfData < 2) G4Exception("Calculate Momentum: error 1");
|
||||
if ((*x)[0]<0) G4Exception("Calculate Momentum: error 2");
|
||||
for (i=1;i<nOfData;i++)
|
||||
{
|
||||
if ((*x)[i]<0) G4Exception("Calculate Momentum: error 3");
|
||||
if ((*x)[i] < (*x)[i-1]) G4Exception ("Calculate Momentum: error 4");
|
||||
}
|
||||
|
||||
G4double RMom=0.0;
|
||||
if (UpperLimit < (*x)[0]) return RMom;
|
||||
G4int iend=0;
|
||||
G4double xt=G4std::min(UpperLimit,(*x)[nOfData-1]);
|
||||
G4double x1,x2,y1,y2;
|
||||
G4double xtc,dx,dy,a1,b1,ds;
|
||||
for (i=0;i<(nOfData-1);i++){
|
||||
x1=G4std::max((*x)[i],eps);
|
||||
y1=(*y)[i];
|
||||
x2=G4std::max((*x)[i+1],eps);
|
||||
y2=(*y)[i+1];
|
||||
if (xt < x2)
|
||||
{
|
||||
xtc=xt;
|
||||
iend=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xtc=x2;
|
||||
}
|
||||
dx=x2-x1;
|
||||
dy=y2-y1;
|
||||
if (abs(dx) > (1e-14*abs(dy)))
|
||||
{
|
||||
b1=dy/dx;
|
||||
a1=y1-b1*x1;
|
||||
if (MomentumOrder == -1)
|
||||
{
|
||||
ds=a1*log(xtc/x1)+b1*(xtc-x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ds=a1*(pow(xtc,MomentumOrder+1)-pow(x1,MomentumOrder+1))/ ((G4double) (MomentumOrder+1))+
|
||||
b1*(pow(xtc,MomentumOrder+2)-pow(x1,MomentumOrder+2))/((G4double) (MomentumOrder+2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ds=0.5*(y1+y2)*pow((xtc-x1),MomentumOrder);
|
||||
}
|
||||
RMom += ds;
|
||||
if (iend != 0) return RMom;
|
||||
}
|
||||
return RMom;
|
||||
}
|
||||
|
||||
G4int G4PenelopeInterpolator::FindBin(G4double xx)
|
||||
{
|
||||
//Finds the interval x[i],x[i+1] which contains the value xx
|
||||
|
||||
G4int nbOfPoints=x->size();
|
||||
|
||||
if (xx > (*x)[nbOfPoints-1])
|
||||
{
|
||||
return (nbOfPoints-1);
|
||||
}
|
||||
if (xx < (*x)[0])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
G4int i=0,i1=nbOfPoints-1;
|
||||
do{
|
||||
G4int it=(i+i1)/2;
|
||||
if (xx > (*x)[it])
|
||||
{
|
||||
i=it;
|
||||
}
|
||||
else
|
||||
{
|
||||
i1=it;
|
||||
}
|
||||
} while((i1-i) > 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopePhotoElectric.cc,v 1.5 2003/03/13 17:04:10 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: L. Pandola
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// January 2003 - Created
|
||||
// 12 Feb 2003 MG Pia Migration to "cuts per region"
|
||||
// 10 Mar 2003 V.Ivanchenko Remome CutPerMaterial warning
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopePhotoElectric.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 "G4RangeNoTest.hh"
|
||||
#include "G4AtomicTransitionManager.hh"
|
||||
#include "G4AtomicShell.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
G4PenelopePhotoElectric::G4PenelopePhotoElectric(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName), lowEnergyLimit(250*eV), highEnergyLimit(100*GeV),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV),
|
||||
cutForLowEnergySecondaryPhotons(250.*eV),
|
||||
cutForLowEnergySecondaryElectrons(250.*eV)
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4PenelopePhotoElectric::G4PenelopePhotoElectric - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
crossSectionHandler = new G4CrossSectionHandler();
|
||||
shellCrossSectionHandler = new G4CrossSectionHandler();
|
||||
meanFreePathTable = 0;
|
||||
rangeTest = new G4RangeNoTest;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4PenelopePhotoElectric::~G4PenelopePhotoElectric()
|
||||
{
|
||||
delete crossSectionHandler;
|
||||
delete shellCrossSectionHandler;
|
||||
delete meanFreePathTable;
|
||||
delete rangeTest;
|
||||
}
|
||||
|
||||
void G4PenelopePhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
crossSectionHandler->Clear();
|
||||
G4String crossSectionFile = "penelope/ph-cs-pen-";
|
||||
crossSectionHandler->LoadData(crossSectionFile);
|
||||
|
||||
shellCrossSectionHandler->Clear();
|
||||
G4String shellCrossSectionFile = "penelope/ph-ss-cs-pen-";
|
||||
shellCrossSectionHandler->LoadShellData(shellCrossSectionFile);
|
||||
|
||||
delete meanFreePathTable;
|
||||
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
|
||||
}
|
||||
|
||||
G4VParticleChange* G4PenelopePhotoElectric::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)
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
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
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
|
||||
G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
|
||||
|
||||
// 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
|
||||
const 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)
|
||||
// (Is the electron vector necessary? To be checked)
|
||||
G4std::vector<G4DynamicParticle*>* photonVector = 0;
|
||||
G4std::vector<G4DynamicParticle*> electronVector;
|
||||
|
||||
G4double energyDeposit = 0.0;
|
||||
|
||||
// Primary outcoming electron
|
||||
G4double eKineticEnergy = photonEnergy - bindingEnergy;
|
||||
|
||||
// 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();
|
||||
|
||||
if (rangeTest->Escape(G4Electron::Electron(),couple,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
|
||||
{
|
||||
bindingEnergy = photonEnergy;
|
||||
}
|
||||
|
||||
G4int nElectrons = electronVector.size();
|
||||
size_t nTotPhotons = 0;
|
||||
G4int nPhotons=0;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
size_t index = couple->GetIndex();
|
||||
G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
|
||||
cutg = G4std::min(cutForLowEnergySecondaryPhotons,cutg);
|
||||
|
||||
G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
|
||||
cute = G4std::min(cutForLowEnergySecondaryPhotons,cute);
|
||||
|
||||
G4DynamicParticle* aPhoton;
|
||||
|
||||
// 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 && (bindingEnergy > cutg || bindingEnergy > cute))
|
||||
{
|
||||
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
|
||||
nTotPhotons = photonVector->size();
|
||||
for (size_t k=0; k<nTotPhotons; k++)
|
||||
{
|
||||
aPhoton = (*photonVector)[k];
|
||||
if (aPhoton)
|
||||
{
|
||||
G4double itsCut = cutg;
|
||||
if(aPhoton->GetDefinition() == G4Electron::Electron()) itsCut = cute;
|
||||
G4double itsEnergy = aPhoton->GetKineticEnergy();
|
||||
|
||||
if (itsEnergy > itsCut && itsEnergy <= bindingEnergy)
|
||||
{
|
||||
nPhotons++;
|
||||
// Local energy deposit is given as the sum of the
|
||||
// energies of incident photons minus the energies
|
||||
// of the outcoming fluorescence photons
|
||||
bindingEnergy -= itsEnergy;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
delete aPhoton;
|
||||
(*photonVector)[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
energyDeposit += bindingEnergy;
|
||||
|
||||
G4int nSecondaries = nElectrons + nPhotons;
|
||||
aParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
|
||||
for (G4int l = 0; l<nElectrons; l++ )
|
||||
{
|
||||
aPhoton = electronVector[l];
|
||||
if(aPhoton) {
|
||||
aParticleChange.AddSecondary(aPhoton);
|
||||
}
|
||||
}
|
||||
for ( size_t ll = 0; ll < nTotPhotons; ll++)
|
||||
{
|
||||
aPhoton = (*photonVector)[ll];
|
||||
if(aPhoton) {
|
||||
aParticleChange.AddSecondary(aPhoton);
|
||||
}
|
||||
}
|
||||
|
||||
delete photonVector;
|
||||
|
||||
if (energyDeposit < 0)
|
||||
{
|
||||
G4cout << "WARNING - "
|
||||
<< "G4PenelopePhotoElectric::PostStepDoIt - Negative energy deposit"
|
||||
<< G4endl;
|
||||
energyDeposit = 0;
|
||||
}
|
||||
|
||||
// Kill the incident photon
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. );
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(energyDeposit);
|
||||
aParticleChange.SetStatusChange( fStopAndKill );
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
}
|
||||
|
||||
G4bool G4PenelopePhotoElectric::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4PenelopePhotoElectric::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
G4Material* material = track.GetMaterial();
|
||||
|
||||
G4double meanFreePath = DBL_MAX;
|
||||
|
||||
G4double cross = shellCrossSectionHandler->ValueForMaterial(material,energy);
|
||||
if(cross > 0.0) meanFreePath = 1.0/cross;
|
||||
|
||||
return meanFreePath;
|
||||
}
|
||||
|
||||
void G4PenelopePhotoElectric::SetCutForLowEnSecPhotons(G4double cut)
|
||||
{
|
||||
cutForLowEnergySecondaryPhotons = cut;
|
||||
deexcitationManager.SetCutForSecondaryPhotons(cut);
|
||||
}
|
||||
|
||||
void G4PenelopePhotoElectric::SetCutForLowEnSecElectrons(G4double cut)
|
||||
{
|
||||
cutForLowEnergySecondaryElectrons = cut;
|
||||
deexcitationManager.SetCutForAugerElectrons(cut);
|
||||
}
|
||||
|
||||
void G4PenelopePhotoElectric::ActivateAuger(G4bool val)
|
||||
{
|
||||
deexcitationManager.ActivateAugerElectronProduction(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,499 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4PenelopeRayleigh.cc,v 1.7 2003/03/13 16:55:35 pandola Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: L. Pandola (luciano.pandola@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// --------
|
||||
// 14 Feb 2003 MG Pia Corrected compilation errors and warnings
|
||||
// from SUN
|
||||
// 10 Mar 2003 V.Ivanchenko Remove CutPerMaterial warning
|
||||
// 12 Mar 2003 L.Pandola Code "cleaned" - Cuts per region
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4PenelopeRayleigh.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 "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4VDataSetAlgorithm.hh"
|
||||
#include "G4LogLogInterpolation.hh"
|
||||
#include "G4PenelopeIntegrator.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
|
||||
G4PenelopeRayleigh::G4PenelopeRayleigh(const G4String& processName)
|
||||
: G4VDiscreteProcess(processName),
|
||||
lowEnergyLimit(250*eV),
|
||||
highEnergyLimit(100*GeV),
|
||||
samplingConstant(0.0),
|
||||
nBins(200),
|
||||
intrinsicLowEnergyLimit(10*eV),
|
||||
intrinsicHighEnergyLimit(100*GeV)
|
||||
|
||||
{
|
||||
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
|
||||
highEnergyLimit > intrinsicHighEnergyLimit)
|
||||
{
|
||||
G4Exception("G4PenelopeRayleigh::G4PenelopeRayleigh - energy limit outside intrinsic process validity range");
|
||||
}
|
||||
|
||||
samplingFunction_x = new G4DataVector();
|
||||
samplingFunction_y = new G4DataVector();
|
||||
meanFreePathTable = 0;
|
||||
material = 0;
|
||||
|
||||
if (verboseLevel > 0)
|
||||
{
|
||||
G4cout << GetProcessName() << " is created " << G4endl
|
||||
<< "Energy range: "
|
||||
<< lowEnergyLimit / keV << " keV - "
|
||||
<< highEnergyLimit / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4PenelopeRayleigh::~G4PenelopeRayleigh()
|
||||
{
|
||||
delete meanFreePathTable;
|
||||
delete samplingFunction_x;
|
||||
delete samplingFunction_y;
|
||||
}
|
||||
|
||||
void G4PenelopeRayleigh::BuildPhysicsTable(const G4ParticleDefinition& photon)
|
||||
{
|
||||
|
||||
G4DataVector energyVector;
|
||||
G4double dBin = log10(highEnergyLimit/lowEnergyLimit)/nBins;
|
||||
for (G4int i=0;i<nBins;i++)
|
||||
{
|
||||
energyVector.push_back(pow(10.,log10(lowEnergyLimit)+i*dBin));
|
||||
}
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
size_t nOfBins = energyVector.size();
|
||||
size_t bin=0;
|
||||
|
||||
G4VDataSetAlgorithm* algo = new G4LogLogInterpolation();
|
||||
G4VEMDataSet* materialSet = new G4CompositeEMDataSet(algo,1.,1.);
|
||||
G4std::vector<G4VEMDataSet*> matCrossSections;
|
||||
|
||||
G4int m;
|
||||
for (m=0; m<nMaterials; m++)
|
||||
{
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* data = new G4DataVector;
|
||||
material = (*materialTable)[m];
|
||||
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double k1=849.3315;
|
||||
|
||||
|
||||
G4int IZZ=0;
|
||||
G4int iright=0;
|
||||
for (G4int i=0; i<nElements; i++) {
|
||||
G4int Z = (G4int) (*elementVector)[i]->GetZ();
|
||||
if (Z>IZZ){
|
||||
IZZ = Z;
|
||||
iright=i;
|
||||
}
|
||||
}
|
||||
|
||||
for (bin=0; bin<nOfBins; bin++)
|
||||
{
|
||||
energies->push_back(energyVector[bin]);
|
||||
G4double ec=G4std::min(energyVector[bin],0.5*IZZ);
|
||||
facte=k1*pow(ec/electron_mass_c2,2);
|
||||
G4double cs=0;
|
||||
G4PenelopeIntegrator<G4PenelopeRayleigh,G4double(G4PenelopeRayleigh::*)(G4double)> theIntegrator;
|
||||
cs =
|
||||
theIntegrator.Calculate(this,&G4PenelopeRayleigh::DifferentialCrossSection,-1.0,0.90,1e-06);
|
||||
cs += theIntegrator.Calculate(this,&G4PenelopeRayleigh::DifferentialCrossSection,0.90,0.9999999,1e-06);
|
||||
cs = cs*pow((ec/energyVector[bin]),2)*pi*pow(classic_electr_radius,2);
|
||||
const G4double* vector_of_atoms = material->GetVecNbOfAtomsPerVolume();
|
||||
const G4int* stechiometric = material->GetAtomsVector();
|
||||
G4double density;
|
||||
if (stechiometric)
|
||||
{
|
||||
density = vector_of_atoms[iright]/stechiometric[iright]; //number of molecules per volume
|
||||
}
|
||||
else
|
||||
{
|
||||
density = vector_of_atoms[iright]; //non-bound molecules
|
||||
}
|
||||
G4double cross = density*cs;
|
||||
data->push_back(cross);
|
||||
}
|
||||
G4VEMDataSet* elSet = new G4EMDataSet(0,energies,data,algo);
|
||||
G4VEMDataSet* setForMat = new G4CompositeEMDataSet(algo);
|
||||
setForMat->AddComponent(elSet);
|
||||
matCrossSections.push_back(setForMat);
|
||||
}
|
||||
G4double matCS = 0.0;
|
||||
|
||||
for (m=0; m<nMaterials; m++)
|
||||
{
|
||||
G4DataVector* energies = new G4DataVector;
|
||||
G4DataVector* data = new G4DataVector;
|
||||
for (bin=0;bin<nOfBins;bin++){
|
||||
energies->push_back(energyVector[bin]);
|
||||
matCS = (matCrossSections[m]->GetComponent(0))->FindValue(energyVector[bin]);
|
||||
if (matCS > 0.){
|
||||
data->push_back(1./matCS);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->push_back(DBL_MAX);
|
||||
}
|
||||
}
|
||||
G4VEMDataSet* dataSet = new G4EMDataSet(m,energies,data,algo,1.,1.);
|
||||
materialSet->AddComponent(dataSet);
|
||||
}
|
||||
meanFreePathTable = materialSet;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4PenelopeRayleigh::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
{
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
|
||||
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
|
||||
|
||||
if (photonEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetLocalEnergyDeposit(photonEnergy0);
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
}
|
||||
|
||||
|
||||
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
|
||||
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
|
||||
material = couple->GetMaterial();
|
||||
|
||||
// Sampling inizialitation (build internal table)
|
||||
|
||||
InizialiseSampling();
|
||||
|
||||
// Sample the angle of the scattered photon
|
||||
const G4double xpar=41.2148;
|
||||
G4double x2max = 2.0*log(xpar*photonEnergy0/electron_mass_c2);
|
||||
G4int jm;
|
||||
G4int asize = samplingFunction_x->size();
|
||||
if (x2max<(*samplingFunction_x)[1])
|
||||
{
|
||||
jm=0;
|
||||
}
|
||||
else if(x2max>(*samplingFunction_x)[asize-2])
|
||||
{
|
||||
jm=asize-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
jm=(G4int) ((x2max-(*samplingFunction_x)[0])/samplingConstant);
|
||||
}
|
||||
G4double rumax = (*samplingFunction_y)[jm]+((*samplingFunction_y)[jm+1]-(*samplingFunction_y)[jm])*
|
||||
(x2max-(*samplingFunction_x)[jm])/((*samplingFunction_x)[jm+1]-(*samplingFunction_x)[jm]);
|
||||
G4int j,ju,jt;
|
||||
G4double ru,denomin,x2rat;
|
||||
G4double CDT,G,rand;
|
||||
do{
|
||||
ru = rumax + log(G4UniformRand());
|
||||
j=0;
|
||||
ju=jm+1;
|
||||
do{
|
||||
jt=(j+ju)/2; //bipartition
|
||||
if (ru > (*samplingFunction_y)[jt])
|
||||
{
|
||||
j=jt;
|
||||
}
|
||||
else
|
||||
{
|
||||
ju=jt;
|
||||
}
|
||||
}while ((ju-j)>1);
|
||||
denomin = (*samplingFunction_y)[j+1]-(*samplingFunction_y)[j];
|
||||
if (denomin > 1e-12)
|
||||
{
|
||||
x2rat = (*samplingFunction_x)[j]+(((*samplingFunction_x)[j+1]-(*samplingFunction_x)[j])*
|
||||
(ru-(*samplingFunction_y)[j])/denomin)-x2max;
|
||||
}
|
||||
else
|
||||
{
|
||||
x2rat = (*samplingFunction_x)[j]-x2max;
|
||||
}
|
||||
CDT = 1.0-2.0*exp(x2rat);
|
||||
G = 0.5*(1.0+CDT*CDT);
|
||||
rand = G4UniformRand();
|
||||
}while (rand>G);
|
||||
|
||||
G4double cosTheta = CDT;
|
||||
G4double sinTheta = sqrt(1-cosTheta*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 photon
|
||||
G4ThreeVector photonDirection1(dirX, dirY, dirZ);
|
||||
|
||||
photonDirection1.rotateUz(photonDirection0);
|
||||
aParticleChange.SetEnergyChange(photonEnergy0);
|
||||
aParticleChange.SetMomentumChange(photonDirection1);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
}
|
||||
|
||||
G4bool G4PenelopeRayleigh::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
G4double G4PenelopeRayleigh::GetMeanFreePath(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition*)
|
||||
{
|
||||
const G4DynamicParticle* photon = track.GetDynamicParticle();
|
||||
G4double energy = photon->GetKineticEnergy();
|
||||
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 G4PenelopeRayleigh::InizialiseSampling()
|
||||
{
|
||||
const G4int points=241;
|
||||
samplingFunction_x->clear();
|
||||
samplingFunction_y->clear();
|
||||
G4double sum = 0.0;
|
||||
G4double Xlow=0;
|
||||
G4double Xhigh=1e-04;
|
||||
G4double fact = pow((1e06/Xhigh),(1/240.0));
|
||||
G4PenelopeIntegrator<G4PenelopeRayleigh,G4double(G4PenelopeRayleigh::*)(G4double)> theIntegrator;
|
||||
sum = theIntegrator.Calculate(this,&G4PenelopeRayleigh::MolecularFormFactor,
|
||||
Xlow,Xhigh,1e-10);
|
||||
samplingFunction_x->push_back(Xhigh);
|
||||
samplingFunction_y->push_back(sum);
|
||||
G4int i;
|
||||
for (i=1;i<points;i++){
|
||||
Xlow=Xhigh;
|
||||
Xhigh=Xhigh*fact;
|
||||
sum = theIntegrator.Calculate(this,
|
||||
&G4PenelopeRayleigh::MolecularFormFactor,
|
||||
Xlow,Xhigh,1e-10);
|
||||
samplingFunction_x->push_back(Xhigh);
|
||||
samplingFunction_y->push_back(sum+(*samplingFunction_y)[i-1]);
|
||||
}
|
||||
for (i=0;i<points;i++){
|
||||
(*samplingFunction_x)[i]=log((*samplingFunction_x)[i]);
|
||||
(*samplingFunction_y)[i]=log((*samplingFunction_y)[i]);
|
||||
}
|
||||
samplingConstant=log(fact);
|
||||
}
|
||||
|
||||
|
||||
G4double G4PenelopeRayleigh::MolecularFormFactor(G4double y)
|
||||
{
|
||||
const G4int ntot=95;
|
||||
G4double RA1[ntot] = {0.0e0, 3.9265e+0, 4.3100e+1, 5.2757e+1, 2.5021e+1,
|
||||
1.2211e+1, 9.3229e+0, 3.2455e+0, 2.4197e+0, 1.5985e+0,
|
||||
3.0926e+1, 1.5315e+1, 7.7061e+0, 3.9493e+0, 2.2042e+0,
|
||||
1.9453e+1, 1.9354e+1, 8.0374e+0, 8.3779e+1, 5.7370e+1,
|
||||
5.2310e+1, 4.7514e+1, 4.3785e+1, 4.2048e+1, 3.6972e+1,
|
||||
3.3849e+1, 3.1609e+1, 2.8763e+1, 2.7217e+1, 2.4263e+1,
|
||||
2.2403e+1, 1.8606e+1, 1.5143e+1, 1.4226e+1, 1.1792e+1,
|
||||
9.7574e+0, 1.2796e+1, 1.2854e+1, 1.2368e+1, 1.0208e+1,
|
||||
8.2823e+0, 7.4677e+0, 7.6028e+0, 6.1090e+0, 5.5346e+0,
|
||||
4.2340e+0, 4.0444e+0, 4.2905e+0, 4.7950e+0, 5.1112e+0,
|
||||
5.2407e+0, 5.2153e+0, 5.1639e+0, 4.8814e+0, 5.8054e+0,
|
||||
6.6724e+0, 6.5104e+0, 6.3364e+0, 6.2889e+0, 6.3028e+0,
|
||||
6.3853e+0, 6.3475e+0, 6.5779e+0, 6.8486e+0, 7.0993e+0,
|
||||
7.6122e+0, 7.9681e+0, 8.3481e+0, 6.3875e+0, 8.0042e+0,
|
||||
8.0820e+0, 7.6940e+0, 7.1927e+0, 6.6751e+0, 6.1623e+0,
|
||||
5.8335e+0, 5.5599e+0, 4.6551e+0, 4.4327e+0, 4.7601e+0,
|
||||
5.2872e+0, 5.6084e+0, 5.7680e+0, 5.8041e+0, 5.7566e+0,
|
||||
5.6541e+0, 6.3932e+0, 6.9313e+0, 7.0027e+0, 6.8796e+0,
|
||||
6.4739e+0, 6.2405e+0, 6.0081e+0, 5.5708e+0, 5.3680e+0};
|
||||
|
||||
|
||||
G4double RA2[ntot] = {0.0e0, 1.3426e-1, 9.4875e+1,-1.0896e+2,-4.5494e+1,
|
||||
-1.9572e+1,-1.2382e+1,-3.6827e+0,-2.4542e+0,-1.4453e+0,
|
||||
1.3401e+2, 7.9717e+1, 6.2164e+1, 4.0300e+1, 3.1682e+1,
|
||||
-1.3639e+1,-1.5950e+1,-5.1523e+0, 1.8351e+2, 1.2205e+2,
|
||||
1.0007e+2, 8.5632e+1, 7.9145e+1, 6.3675e+1, 6.2954e+1,
|
||||
5.6601e+1, 5.4171e+1, 4.8752e+1, 3.8062e+1, 3.9933e+1,
|
||||
4.8343e+1, 4.2137e+1, 3.4617e+1, 2.9430e+1, 2.4010e+1,
|
||||
1.9744e+1, 4.0009e+1, 5.1614e+1, 5.0456e+1, 3.9088e+1,
|
||||
2.6824e+1, 2.2953e+1, 2.4773e+1, 1.6893e+1, 1.4548e+1,
|
||||
9.7226e+0, 1.0192e+1, 1.1153e+1, 1.3188e+1, 1.4733e+1,
|
||||
1.5644e+1, 1.5939e+1, 1.5923e+1, 1.5254e+1, 2.0748e+1,
|
||||
2.6901e+1, 2.7032e+1, 2.4938e+1, 2.1528e+1, 2.0362e+1,
|
||||
1.9474e+1, 1.8238e+1, 1.7898e+1, 1.9174e+1, 1.9023e+1,
|
||||
1.8194e+1, 1.8504e+1, 1.8955e+1, 1.4276e+1, 1.7558e+1,
|
||||
1.8651e+1, 1.7984e+1, 1.6793e+1, 1.5469e+1, 1.4143e+1,
|
||||
1.3149e+1, 1.2255e+1, 9.2352e+0, 8.6067e+0, 9.7460e+0,
|
||||
1.1749e+1, 1.3281e+1, 1.4326e+1, 1.4920e+1, 1.5157e+1,
|
||||
1.5131e+1, 1.9489e+1, 2.3649e+1, 2.4686e+1, 2.4760e+1,
|
||||
2.1519e+1, 2.0099e+1, 1.8746e+1, 1.5943e+1, 1.4880e+1};
|
||||
|
||||
G4double RA3[ntot] = {0.0e0, 2.2648e+0, 1.0579e+3, 8.6177e+2, 2.4422e+2,
|
||||
7.8788e+1, 3.8293e+1, 1.2564e+1, 6.9091e+0, 3.7926e+0,
|
||||
0.0000e+0, 0.0000e+0, 1.6759e-9, 1.3026e+1, 3.0569e+0,
|
||||
1.5521e+2, 1.2815e+2, 4.7378e+1, 9.2802e+2, 4.7508e+2,
|
||||
3.6612e+2, 2.7582e+2, 2.1008e+2, 1.5903e+2, 1.2322e+2,
|
||||
9.2898e+1, 7.1345e+1, 5.1651e+1, 3.8474e+1, 2.7410e+1,
|
||||
1.9126e+1, 1.0889e+1, 5.3479e+0, 8.2223e+0, 5.0837e+0,
|
||||
2.8905e+0, 2.7457e+0, 6.7082e-1, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 1.7264e-1, 2.7322e-1,
|
||||
3.9444e-1, 4.5648e-1, 6.2286e-1, 7.2468e-1, 8.4296e-1,
|
||||
1.1698e+0, 1.2994e+0, 1.4295e+0, 0.0000e+0, 8.1570e-1,
|
||||
6.9349e-1, 4.9536e-1, 3.1211e-1, 1.5931e-1, 2.9512e-2,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0,
|
||||
0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0, 0.0000e+0};
|
||||
|
||||
G4double RA4[ntot] = {1.1055e1,6.3519e0,4.7367e+1, 3.9402e+1, 2.2896e+1,
|
||||
1.3979e+1, 1.0766e+1, 6.5252e+0, 5.1631e+0, 4.0524e+0,
|
||||
2.7145e+1, 1.8724e+1, 1.4782e+1, 1.1608e+1, 9.7750e+0,
|
||||
1.6170e+1, 1.5249e+1, 9.1916e+0, 5.4499e+1, 4.1381e+1,
|
||||
3.7395e+1, 3.3815e+1, 3.1135e+1, 2.8273e+1, 2.6140e+1,
|
||||
2.3948e+1, 2.2406e+1, 2.0484e+1, 1.8453e+1, 1.7386e+1,
|
||||
1.7301e+1, 1.5388e+1, 1.3411e+1, 1.2668e+1, 1.1133e+1,
|
||||
9.8081e+0, 1.3031e+1, 1.4143e+1, 1.3815e+1, 1.2077e+1,
|
||||
1.0033e+1, 9.2549e+0, 9.5338e+0, 7.9076e+0, 7.3263e+0,
|
||||
5.9996e+0, 6.0087e+0, 6.2660e+0, 6.7914e+0, 7.1501e+0,
|
||||
7.3367e+0, 7.3729e+0, 7.3508e+0, 7.1465e+0, 8.2731e+0,
|
||||
9.3745e+0, 9.3508e+0, 8.9897e+0, 8.4566e+0, 8.2690e+0,
|
||||
8.1398e+0, 7.9183e+0, 7.9123e+0, 8.1677e+0, 8.1871e+0,
|
||||
8.1766e+0, 8.2881e+0, 8.4227e+0, 7.0273e+0, 8.0002e+0,
|
||||
8.1440e+0, 7.9104e+0, 7.5685e+0, 7.1970e+0, 6.8184e+0,
|
||||
6.5469e+0, 6.3056e+0, 5.4844e+0, 5.2832e+0, 5.5889e+0,
|
||||
6.0919e+0, 6.4340e+0, 6.6426e+0, 6.7428e+0, 6.7636e+0,
|
||||
6.7281e+0, 7.5729e+0, 8.2808e+0, 8.4400e+0, 8.4220e+0,
|
||||
7.8662e+0, 7.5993e+0, 7.3353e+0, 6.7829e+0, 6.5520e+0};
|
||||
|
||||
G4double RA5[ntot] = {0.0e0, 4.9828e+0, 5.5674e+1, 3.0902e+1, 1.1496e+1,
|
||||
4.8936e+0, 2.5506e+0, 1.2236e+0, 7.4698e-1, 4.7042e-1,
|
||||
4.7809e+0, 4.6315e+0, 4.3677e+0, 4.9269e+0, 2.6033e+0,
|
||||
9.6229e+0, 7.2592e+0, 4.1634e+0, 1.3999e+1, 8.6975e+0,
|
||||
6.9630e+0, 5.4681e+0, 4.2653e+0, 3.2848e+0, 2.7354e+0,
|
||||
2.1617e+0, 1.7030e+0, 1.2826e+0, 9.7080e-1, 7.2227e-1,
|
||||
5.0874e-1, 3.1402e-1, 1.6360e-1, 3.2918e-1, 2.3570e-1,
|
||||
1.5868e-1, 1.5146e-1, 9.7662e-2, 7.3151e-2, 6.4206e-2,
|
||||
4.8945e-2, 4.3189e-2, 4.4368e-2, 3.3976e-2, 3.0466e-2,
|
||||
2.4477e-2, 3.7202e-2, 3.7093e-2, 3.8161e-2, 3.8576e-2,
|
||||
3.8403e-2, 3.7806e-2, 3.4958e-2, 3.6029e-2, 4.3087e-2,
|
||||
4.7069e-2, 4.6452e-2, 4.2486e-2, 4.1517e-2, 4.1691e-2,
|
||||
4.2813e-2, 4.2294e-2, 4.5287e-2, 4.8462e-2, 4.9726e-2,
|
||||
5.5097e-2, 5.6568e-2, 5.8069e-2, 1.2270e-2, 3.8006e-2,
|
||||
3.5048e-2, 3.0050e-2, 2.5069e-2, 2.0485e-2, 1.6151e-2,
|
||||
1.4631e-2, 1.4034e-2, 1.1978e-2, 1.1522e-2, 1.2375e-2,
|
||||
1.3805e-2, 1.4954e-2, 1.5832e-2, 1.6467e-2, 1.6896e-2,
|
||||
1.7166e-2, 1.9954e-2, 2.2497e-2, 2.1942e-2, 2.1965e-2,
|
||||
2.0005e-2, 1.8927e-2, 1.8167e-2, 1.6314e-2, 1.5522e-2};
|
||||
|
||||
G4double x=sqrt(y);
|
||||
G4double gradx1=0.0;
|
||||
G4double fa=0.0;
|
||||
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4int* stechiometric = material->GetAtomsVector();
|
||||
const G4double* vector_of_atoms = material->GetVecNbOfAtomsPerVolume();
|
||||
const G4double tot_atoms = material->GetTotNbOfAtomsPerVolume();
|
||||
for (G4int i=0;i<nElements;i++){
|
||||
G4int Z = (G4int) (*elementVector)[i]->GetZ();
|
||||
if (Z>ntot) Z=95;
|
||||
fa=Z*(1+y*(RA1[Z-1]+x*(RA2[Z-1]+x*RA3[Z-1])))/pow((1+y*(RA4[Z-1]+y*RA5[Z-1])),2);
|
||||
G4bool a = ((Z>10) && (fa>2.0));
|
||||
if (a)
|
||||
{
|
||||
G4double Pa,Pg,Pq,fb;
|
||||
G4double k1=0.3125;
|
||||
G4double k2=2.426311e-02;
|
||||
Pa=(Z-k1)*fine_structure_const;
|
||||
Pg=sqrt(1-pow(Pa,2));
|
||||
Pq=k2*x/Pa;
|
||||
fb=sin(2*Pg*atan(Pq))/(Pg*Pq*pow((1+Pq*Pq),Pg));
|
||||
fa=G4std::max(fa,fb);
|
||||
}
|
||||
if (stechiometric)
|
||||
{
|
||||
gradx1=gradx1+stechiometric[i]*(fa*fa); //sum on the molecule
|
||||
}
|
||||
else
|
||||
{
|
||||
gradx1=gradx1+(vector_of_atoms[i]/tot_atoms)*(fa*fa); //weighted mean
|
||||
}
|
||||
}
|
||||
return gradx1;
|
||||
}
|
||||
|
||||
|
||||
G4double G4PenelopeRayleigh::DifferentialCrossSection(G4double x)
|
||||
{
|
||||
G4double x2=facte*(1-x);
|
||||
G4double gradx = (1+x*x)*MolecularFormFactor(x2);
|
||||
return gradx;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,8 +54,6 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4QAOLowEnergyLoss.hh"
|
||||
#include "PhysicalConstants.h"
|
||||
#include "SystemOfUnits.h"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
@@ -21,34 +21,42 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4RangeTest.cc,v 1.5 2002/05/28 09:20:21 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4RangeTest.cc,v 1.6 2003/01/22 18:47:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 05 Oct 2001 MGP Created
|
||||
// 21 Jan 2003 VI Cut per region
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4RangeTest.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
|
||||
G4RangeTest::~G4RangeTest()
|
||||
{ }
|
||||
|
||||
G4bool G4RangeTest::Escape(const G4ParticleDefinition* particle,
|
||||
const G4Material* material,
|
||||
G4double energy,
|
||||
G4bool G4RangeTest::Escape(const G4ParticleDefinition* particle,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
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);
|
||||
|
||||
G4bool value = true;
|
||||
size_t idx = 0;
|
||||
if(particle == G4Electron::Electron()) idx = 1;
|
||||
else if(particle == G4Positron::Positron()) idx = 2;
|
||||
if(idx>0) {
|
||||
G4double range = G4EnergyLossTables::GetRange(particle,energy,couple);
|
||||
G4double cut = couple->GetProductionCuts()->GetProductionCut(idx);
|
||||
G4double rMin = G4std::min(cut,safety);
|
||||
value = (range > rMin);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4SemiLogInterpolation.cc,v 1.4 2002/05/28 09:20:21 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4ShellData.cc,v 1.5 2002/05/28 09:20:21 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4ShellEMDataSet.cc,v 1.8 2002/05/28 09:20:21 pia Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -22,18 +22,19 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4ShellVacancy.cc
|
||||
// GEANT4 tag $Name:
|
||||
// GEANT4 tag $Name:
|
||||
//
|
||||
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
|
||||
//
|
||||
// History:
|
||||
// -----------
|
||||
// 21 Sept 2001 Elena Guardincerri Created
|
||||
// 25 Mar 2002 V.Ivanchenko Change AverageNOfIonisations int->double
|
||||
// 25 Mar 2002 V.Ivanchenko Change AverageNOfIonisations int->double
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4ShellVacancy.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4VEMDataSet.hh"
|
||||
@@ -44,13 +45,13 @@ 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)
|
||||
@@ -59,20 +60,20 @@ void G4ShellVacancy::AddXsiTable(G4VEMDataSet* set)
|
||||
xsis.push_back(set);
|
||||
}
|
||||
|
||||
G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4Material*
|
||||
material,
|
||||
G4double
|
||||
incidentEnergy,
|
||||
G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4MaterialCutsCouple*
|
||||
couple,
|
||||
G4double
|
||||
incidentEnergy,
|
||||
G4double eLoss) const
|
||||
|
||||
{
|
||||
G4std::vector<G4int> numberOfIonisations;
|
||||
|
||||
{
|
||||
G4std::vector<G4int> numberOfIonisations;
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4int numberOfElements = material->GetNumberOfElements();
|
||||
|
||||
for (G4int i = 0; i<numberOfElements; i++)
|
||||
{
|
||||
G4double averageNumberOfIonisations = AverageNOfIonisations(material,
|
||||
G4double averageNumberOfIonisations = AverageNOfIonisations(couple,
|
||||
i,
|
||||
incidentEnergy,
|
||||
eLoss);
|
||||
@@ -82,27 +83,27 @@ G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4Materia
|
||||
}
|
||||
|
||||
numberOfIonisations.push_back(ionisations);
|
||||
|
||||
|
||||
}
|
||||
return numberOfIonisations;
|
||||
return numberOfIonisations;
|
||||
|
||||
}
|
||||
|
||||
G4double G4ShellVacancy::AverageNOfIonisations(const G4Material* material,
|
||||
G4int index,
|
||||
G4double G4ShellVacancy::AverageNOfIonisations(const G4MaterialCutsCouple* couple,
|
||||
G4int index,
|
||||
G4double energy,
|
||||
G4double eLoss) const
|
||||
|
||||
{
|
||||
// G4int indexOfElementInMaterial= -1;
|
||||
|
||||
|
||||
G4double averageEnergy = energy - eLoss/2.;
|
||||
|
||||
size_t indexInMaterialTable = material->GetIndex();
|
||||
|
||||
size_t indexInMaterialTable = couple->GetIndex();
|
||||
|
||||
G4VEMDataSet* aSetOfXsi = xsis[indexInMaterialTable];
|
||||
|
||||
G4double aXsi = aSetOfXsi->FindValue(averageEnergy,index);
|
||||
|
||||
return aXsi * eLoss;
|
||||
G4double aXsi = aSetOfXsi->FindValue(averageEnergy,index);
|
||||
|
||||
return aXsi * eLoss;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VCrossSectionHandler.cc,v 1.11 2002/07/30 10:06:21 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4VCrossSectionHandler.cc,v 1.12 2003/01/22 18:47:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
@@ -32,6 +32,7 @@
|
||||
// 09 Oct 2001 VI Add FindValue with 3 parameters
|
||||
// + NumberOfComponents
|
||||
// 19 Jul 2002 VI Create composite data set for material
|
||||
// 21 Jan 2003 VI Cut per region
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -42,10 +43,10 @@
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4CompositeEMDataSet.hh"
|
||||
#include "G4ShellEMDataSet.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Element.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "g4std/map"
|
||||
#include "g4std/vector"
|
||||
#include "g4std/fstream"
|
||||
@@ -62,10 +63,10 @@ G4VCrossSectionHandler::G4VCrossSectionHandler()
|
||||
|
||||
|
||||
G4VCrossSectionHandler::G4VCrossSectionHandler(G4VDataSetAlgorithm* algorithm,
|
||||
G4double minE,
|
||||
G4double maxE,
|
||||
G4double minE,
|
||||
G4double maxE,
|
||||
G4int bins,
|
||||
G4double unitE,
|
||||
G4double unitE,
|
||||
G4double unitData,
|
||||
G4int minZ,
|
||||
G4int maxZ)
|
||||
@@ -234,7 +235,7 @@ void G4VCrossSectionHandler::LoadShellData(const G4String& fileName)
|
||||
|
||||
char nameChar[100] = {""};
|
||||
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
|
||||
|
||||
|
||||
ost << fileName << Z << ".dat";
|
||||
|
||||
G4String name(nameChar);
|
||||
@@ -306,7 +307,7 @@ void G4VCrossSectionHandler::Clear()
|
||||
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
|
||||
// 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;
|
||||
@@ -349,7 +350,7 @@ 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())
|
||||
@@ -385,17 +386,17 @@ G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy,
|
||||
}
|
||||
|
||||
|
||||
G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material,
|
||||
G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material,
|
||||
G4double energy) const
|
||||
{
|
||||
G4double value = 0.;
|
||||
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
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];
|
||||
@@ -406,7 +407,7 @@ G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material,
|
||||
}
|
||||
|
||||
|
||||
G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4DataVector* energyCuts)
|
||||
G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4DataVector* energyCuts)
|
||||
{
|
||||
// Builds a CompositeDataSet containing the mean free path for each material
|
||||
// in the material table
|
||||
@@ -414,13 +415,13 @@ G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4Data
|
||||
G4DataVector energyVector;
|
||||
G4double dBin = log10(eMax/eMin) / nBins;
|
||||
|
||||
for (G4int i=0; i<nBins+1; i++)
|
||||
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
|
||||
// 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
|
||||
@@ -441,7 +442,7 @@ G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4Data
|
||||
|
||||
crossSections = BuildCrossSectionsForMaterials(energyVector,energyCuts);
|
||||
|
||||
if (crossSections == 0)
|
||||
if (crossSections == 0)
|
||||
G4Exception("G4VCrossSectionHandler::BuildMeanFreePathForMaterials, crossSections = 0");
|
||||
|
||||
G4VDataSetAlgorithm* algo = CreateInterpolation();
|
||||
@@ -449,10 +450,13 @@ G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4Data
|
||||
|
||||
G4DataVector* energies;
|
||||
G4DataVector* data;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
size_t nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
for (size_t m=0; m<nMaterials; m++)
|
||||
for (size_t m=0; m<numOfCouples; m++)
|
||||
{
|
||||
energies = new G4DataVector;
|
||||
data = new G4DataVector;
|
||||
@@ -484,15 +488,17 @@ G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4Data
|
||||
return materialSet;
|
||||
}
|
||||
|
||||
G4int G4VCrossSectionHandler::SelectRandomAtom(const G4Material* material, G4double e) const
|
||||
G4int G4VCrossSectionHandler::SelectRandomAtom(const G4MaterialCutsCouple* couple,
|
||||
G4double e) const
|
||||
{
|
||||
// Select randomly an element within the material, according to the weight
|
||||
// Select randomly an element within the material, according to the weight
|
||||
// determined by the cross sections in the data set
|
||||
|
||||
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
// Special case: the material consists of one element
|
||||
if (nElements == 1)
|
||||
if (nElements == 1)
|
||||
{
|
||||
G4int Z = (G4int) material->GetZ();
|
||||
return Z;
|
||||
@@ -501,66 +507,67 @@ G4int G4VCrossSectionHandler::SelectRandomAtom(const G4Material* material, G4dou
|
||||
// Composite material
|
||||
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
size_t materialIndex = material->GetIndex();
|
||||
size_t materialIndex = couple->GetIndex();
|
||||
|
||||
G4VEMDataSet* materialSet = (*crossSections)[materialIndex];
|
||||
G4double materialCrossSection0 = 0.0;
|
||||
G4DataVector cross;
|
||||
cross.clear();
|
||||
for ( G4int i=0; i < nElements; i++ )
|
||||
for ( G4int i=0; i < nElements; i++ )
|
||||
{
|
||||
G4double cr = materialSet->GetComponent(i)->FindValue(e);
|
||||
materialCrossSection0 += cr;
|
||||
cross.push_back(materialCrossSection0);
|
||||
}
|
||||
}
|
||||
|
||||
G4double random = G4UniformRand() * materialCrossSection0;
|
||||
|
||||
for (G4int k=0 ; k < nElements ; k++ )
|
||||
{
|
||||
{
|
||||
if (random <= cross[k]) return (G4int) (*elementVector)[k]->GetZ();
|
||||
}
|
||||
// It should never get here
|
||||
return 0;
|
||||
}
|
||||
|
||||
const G4Element* G4VCrossSectionHandler::SelectRandomElement(const G4Material* material,
|
||||
const G4Element* G4VCrossSectionHandler::SelectRandomElement(const G4MaterialCutsCouple* couple,
|
||||
G4double e) const
|
||||
{
|
||||
// Select randomly an element within the material, according to the weight determined
|
||||
// by the cross sections in the data set
|
||||
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4Element* nullElement = 0;
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
|
||||
// Special case: the material consists of one element
|
||||
if (nElements == 1)
|
||||
if (nElements == 1)
|
||||
{
|
||||
G4Element* element = (*elementVector)[0];
|
||||
return element;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Composite material
|
||||
// Composite material
|
||||
|
||||
size_t materialIndex = material->GetIndex();
|
||||
size_t materialIndex = couple->GetIndex();
|
||||
|
||||
G4VEMDataSet* materialSet = (*crossSections)[materialIndex];
|
||||
G4double materialCrossSection0 = 0.0;
|
||||
G4DataVector cross;
|
||||
cross.clear();
|
||||
for (G4int i=0; i<nElements; i++)
|
||||
for (G4int i=0; i<nElements; i++)
|
||||
{
|
||||
G4double cr = materialSet->GetComponent(i)->FindValue(e);
|
||||
materialCrossSection0 += cr;
|
||||
cross.push_back(materialCrossSection0);
|
||||
}
|
||||
}
|
||||
|
||||
G4double random = G4UniformRand() * materialCrossSection0;
|
||||
|
||||
for (G4int k=0 ; k < nElements ; k++ )
|
||||
{
|
||||
{
|
||||
if (random <= cross[k]) return (*elementVector)[k];
|
||||
}
|
||||
// It should never end up here
|
||||
@@ -586,8 +593,8 @@ G4int G4VCrossSectionHandler::SelectRandomShell(G4int Z, G4double e) const
|
||||
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 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;
|
||||
@@ -612,20 +619,20 @@ 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 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)
|
||||
if (!(activeZ.contains(Z)) && Z >= zMin && Z <= zMax)
|
||||
{
|
||||
activeZ.push_back(Z);
|
||||
}
|
||||
@@ -642,7 +649,7 @@ G4VDataSetAlgorithm* G4VCrossSectionHandler::CreateInterpolation()
|
||||
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())
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VeLowEnergyLoss.cc,v 1.18 2002/09/09 08:54:08 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4VeLowEnergyLoss.cc,v 1.21 2003/04/24 11:24:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// History: first implementation, based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
@@ -38,16 +38,20 @@
|
||||
// 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
|
||||
// 22/01/03 V.Ivanchenko Cut per region
|
||||
// 11/02/03 V.Ivanchenko Add limits to fluctuations
|
||||
// 24/04/03 V.Ivanchenko Fix the problem of table size
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4VeLowEnergyLoss.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
G4double G4VeLowEnergyLoss::ParticleMass ;
|
||||
G4double G4VeLowEnergyLoss::taulow ;
|
||||
G4double G4VeLowEnergyLoss::tauhigh ;
|
||||
G4double G4VeLowEnergyLoss::ltaulow ;
|
||||
G4double G4VeLowEnergyLoss::ltauhigh ;
|
||||
G4double G4VeLowEnergyLoss::ParticleMass ;
|
||||
G4double G4VeLowEnergyLoss::taulow ;
|
||||
G4double G4VeLowEnergyLoss::tauhigh ;
|
||||
G4double G4VeLowEnergyLoss::ltaulow ;
|
||||
G4double G4VeLowEnergyLoss::ltauhigh ;
|
||||
|
||||
|
||||
G4bool G4VeLowEnergyLoss::rndmStepFlag = false;
|
||||
@@ -59,7 +63,7 @@ G4double G4VeLowEnergyLoss::c2lim = 2.*(1.-dRoverRange)*finalRange ;
|
||||
G4double G4VeLowEnergyLoss::c3lim = -(1.-dRoverRange)*finalRange*finalRange;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4VeLowEnergyLoss::G4VeLowEnergyLoss()
|
||||
:G4VContinuousDiscreteProcess("No Name Loss Process"),
|
||||
@@ -70,7 +74,7 @@ G4VeLowEnergyLoss::G4VeLowEnergyLoss()
|
||||
G4Exception("G4VeLowEnergyLoss:: default constructor is called");
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4VeLowEnergyLoss::G4VeLowEnergyLoss(const G4String& aName , G4ProcessType aType)
|
||||
: G4VContinuousDiscreteProcess(aName, aType),
|
||||
@@ -80,13 +84,13 @@ G4VeLowEnergyLoss::G4VeLowEnergyLoss(const G4String& aName , G4ProcessType aType
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4VeLowEnergyLoss::~G4VeLowEnergyLoss()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4VeLowEnergyLoss::G4VeLowEnergyLoss(G4VeLowEnergyLoss& right)
|
||||
: G4VContinuousDiscreteProcess(right),
|
||||
@@ -96,19 +100,19 @@ G4VeLowEnergyLoss::G4VeLowEnergyLoss(G4VeLowEnergyLoss& right)
|
||||
{
|
||||
}
|
||||
|
||||
void G4VeLowEnergyLoss::SetRndmStep(G4bool value)
|
||||
void G4VeLowEnergyLoss::SetRndmStep(G4bool value)
|
||||
{
|
||||
rndmStepFlag = value;
|
||||
}
|
||||
|
||||
void G4VeLowEnergyLoss::SetEnlossFluc(G4bool value)
|
||||
void G4VeLowEnergyLoss::SetEnlossFluc(G4bool value)
|
||||
{
|
||||
EnlossFlucFlag = value;
|
||||
}
|
||||
|
||||
void G4VeLowEnergyLoss::SetStepFunction (G4double c1, G4double c2)
|
||||
{
|
||||
dRoverRange = c1;
|
||||
dRoverRange = c1;
|
||||
finalRange = c2;
|
||||
c1lim=dRoverRange;
|
||||
c2lim=2.*(1-dRoverRange)*finalRange;
|
||||
@@ -116,22 +120,22 @@ void G4VeLowEnergyLoss::SetStepFunction (G4double c1, G4double c2)
|
||||
}
|
||||
|
||||
G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeTable(
|
||||
G4PhysicsTable* theDEDXTable,G4PhysicsTable* theRangeTable,
|
||||
G4PhysicsTable* theDEDXTable,G4PhysicsTable* theRangeTable,
|
||||
G4double lowestKineticEnergy,G4double highestKineticEnergy,
|
||||
G4int TotBin)
|
||||
// Build range table from the energy loss table
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
G4int numOfCouples = theDEDXTable->length();
|
||||
|
||||
if(theRangeTable)
|
||||
{ theRangeTable->clearAndDestroy();
|
||||
delete theRangeTable; }
|
||||
theRangeTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
aVector = new G4PhysicsLogVector(lowestKineticEnergy,
|
||||
@@ -141,9 +145,9 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeTable(
|
||||
theRangeTable->insert(aVector);
|
||||
}
|
||||
return theRangeTable ;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
void G4VeLowEnergyLoss::BuildRangeVector(G4PhysicsTable* theDEDXTable,
|
||||
G4double lowestKineticEnergy,
|
||||
@@ -179,9 +183,9 @@ void G4VeLowEnergyLoss::BuildRangeVector(G4PhysicsTable* theDEDXTable,
|
||||
dedx = dedx1 ;
|
||||
energy1 = energy2 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4VeLowEnergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
@@ -212,7 +216,7 @@ G4double G4VeLowEnergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
|
||||
return Value;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4VeLowEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
@@ -246,24 +250,24 @@ G4double G4VeLowEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4PhysicsTable* G4VeLowEnergyLoss::BuildLabTimeTable(G4PhysicsTable* theDEDXTable,
|
||||
G4PhysicsTable* theLabTimeTable,
|
||||
G4double lowestKineticEnergy,
|
||||
G4double highestKineticEnergy,G4int TotBin)
|
||||
|
||||
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(theLabTimeTable)
|
||||
{ theLabTimeTable->clearAndDestroy();
|
||||
delete theLabTimeTable; }
|
||||
theLabTimeTable = new G4PhysicsTable(numOfMaterials);
|
||||
theLabTimeTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
|
||||
@@ -288,15 +292,15 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildProperTimeTable(G4PhysicsTable* theDEDXT
|
||||
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(theProperTimeTable)
|
||||
{ theProperTimeTable->clearAndDestroy();
|
||||
delete theProperTimeTable; }
|
||||
theProperTimeTable = new G4PhysicsTable(numOfMaterials);
|
||||
theProperTimeTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
|
||||
@@ -513,15 +517,15 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildInverseRangeTable(G4PhysicsTable* theRan
|
||||
{
|
||||
G4bool b;
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(theInverseRangeTable)
|
||||
{ theInverseRangeTable->clearAndDestroy();
|
||||
delete theInverseRangeTable; }
|
||||
theInverseRangeTable = new G4PhysicsTable(numOfMaterials);
|
||||
theInverseRangeTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
// loop for materials
|
||||
for (G4int i=0; i<numOfMaterials; i++)
|
||||
for (G4int i=0; i<numOfCouples; i++)
|
||||
{
|
||||
|
||||
G4PhysicsVector* pv = (*theRangeTable)[i];
|
||||
@@ -549,7 +553,7 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildInverseRangeTable(G4PhysicsTable* theRan
|
||||
|
||||
for (ihigh=ilow+1; ihigh<nbins; ihigh++) {
|
||||
energy2 = pv->GetLowEdgeEnergy(ihigh);
|
||||
range2 = pv->GetValue(energy2, b);
|
||||
range2 = pv->GetValue(energy2, b);
|
||||
if(range2 >= range || ihigh == nbins-1) {
|
||||
ilow = ihigh - 1;
|
||||
energy1 = pv->GetLowEdgeEnergy(ilow);
|
||||
@@ -634,12 +638,12 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffATable(G4PhysicsTable* theRang
|
||||
// create table for coefficients "A"
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(theRangeCoeffATable)
|
||||
{ theRangeCoeffATable->clearAndDestroy();
|
||||
delete theRangeCoeffATable; }
|
||||
theRangeCoeffATable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffATable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
G4double RTable = exp(log(highestKineticEnergy/lowestKineticEnergy)/TotBin) ;
|
||||
G4double R2 = RTable*RTable ;
|
||||
@@ -650,7 +654,7 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffATable(G4PhysicsTable* theRang
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector =
|
||||
@@ -696,12 +700,12 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffBTable(G4PhysicsTable* theRang
|
||||
// create table for coefficients "B"
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(theRangeCoeffBTable)
|
||||
{ theRangeCoeffBTable->clearAndDestroy();
|
||||
delete theRangeCoeffBTable; }
|
||||
theRangeCoeffBTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffBTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
G4double RTable = exp(log(highestKineticEnergy/lowestKineticEnergy)/TotBin) ;
|
||||
G4double R2 = RTable*RTable ;
|
||||
@@ -712,7 +716,7 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffBTable(G4PhysicsTable* theRang
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector =
|
||||
@@ -757,12 +761,12 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRang
|
||||
// create table for coefficients "C"
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(theRangeCoeffCTable)
|
||||
{ theRangeCoeffCTable->clearAndDestroy();
|
||||
delete theRangeCoeffCTable; }
|
||||
theRangeCoeffCTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffCTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
G4double RTable = exp(log(highestKineticEnergy/lowestKineticEnergy)/TotBin) ;
|
||||
G4double R2 = RTable*RTable ;
|
||||
@@ -773,7 +777,7 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRang
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector =
|
||||
@@ -811,7 +815,7 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRang
|
||||
//
|
||||
|
||||
G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double MeanLoss,
|
||||
G4double step)
|
||||
// calculate actual loss from the mean loss
|
||||
@@ -823,14 +827,14 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
static const G4double alim=10.;
|
||||
static const G4double kappa = 10. ;
|
||||
static const G4double factor = twopi_mc2_rcl2 ;
|
||||
|
||||
const G4Material* aMaterial = couple->GetMaterial();
|
||||
|
||||
// check if the material has changed ( cache mechanism)
|
||||
|
||||
if (aMaterial != lastMaterial)
|
||||
{
|
||||
lastMaterial = aMaterial;
|
||||
imat = aMaterial->GetIndex();
|
||||
imat = couple->GetIndex();
|
||||
f1Fluct = aMaterial->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = aMaterial->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = aMaterial->GetIonisation()->GetEnergy1fluct();
|
||||
@@ -851,7 +855,7 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4double dp3;
|
||||
G4double siga ;
|
||||
|
||||
// shortcut for very very small loss
|
||||
// shortcut for very very small loss
|
||||
if(MeanLoss < minLoss) return MeanLoss ;
|
||||
|
||||
// get particle data
|
||||
@@ -859,67 +863,60 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
|
||||
// G4cout << "MGP -- Fluc Tkin " << Tkin/keV << " keV " << " MeanLoss = " << MeanLoss/keV << G4endl;
|
||||
|
||||
threshold = G4Electron::Electron()->GetEnergyThreshold(aMaterial);
|
||||
threshold = (*((G4ProductionCutsTable::GetProductionCutsTable())
|
||||
->GetEnergyCutsVector(1)))[imat];
|
||||
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);
|
||||
|
||||
// G4cout << "MGP Particle mass " << ParticleMass/MeV << " Tm " << Tm << G4endl;
|
||||
|
||||
if (Tm <= ipotFluct) Tm = ipotFluct ;
|
||||
|
||||
if(Tm > threshold) Tm = threshold;
|
||||
beta2 = tau2/(tau1*tau1);
|
||||
|
||||
// Gaussian fluctuation ?
|
||||
if(MeanLoss >= kappa*Tm)
|
||||
if(MeanLoss >= kappa*Tm || MeanLoss <= kappa*ipotFluct)
|
||||
{
|
||||
G4double electronDensity = aMaterial->GetElectronDensity() ;
|
||||
siga = sqrt(Tm*(1.0-0.5*beta2)*step*
|
||||
factor*electronDensity/beta2) ;
|
||||
loss = G4RandGauss::shoot(MeanLoss,siga) ;
|
||||
if(loss < 0.) loss = 0. ;
|
||||
do {
|
||||
loss = G4RandGauss::shoot(MeanLoss,siga) ;
|
||||
} while (loss < 0. || loss > 2.0*MeanLoss);
|
||||
return loss ;
|
||||
}
|
||||
|
||||
w1 = Tm/ipotFluct;
|
||||
w2 = log(2.*electron_mass_c2*tau2);
|
||||
|
||||
|
||||
C = MeanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
|
||||
|
||||
|
||||
a1 = C*f1Fluct*(w2-e1LogFluct-beta2)/e1Fluct;
|
||||
a2 = C*f2Fluct*(w2-e2LogFluct-beta2)/e2Fluct;
|
||||
if(Tm > ipotFluct)
|
||||
a3 = rateFluct*MeanLoss*(Tm-ipotFluct)/(ipotFluct*Tm*log(w1));
|
||||
else
|
||||
{
|
||||
a1 /= 1.-rateFluct ;
|
||||
a2 /= 1.-rateFluct ;
|
||||
a3 = 0. ;
|
||||
}
|
||||
|
||||
a3 = rateFluct*MeanLoss*(Tm-ipotFluct)/(ipotFluct*Tm*log(w1));
|
||||
|
||||
suma = a1+a2+a3;
|
||||
|
||||
|
||||
loss = 0. ;
|
||||
|
||||
|
||||
if(suma < sumaLim) // very small Step
|
||||
{
|
||||
e0 = aMaterial->GetIonisation()->GetEnergy0fluct();
|
||||
// G4cout << "MGP e0 = " << e0/keV << G4endl;
|
||||
|
||||
|
||||
if(Tm == ipotFluct)
|
||||
{
|
||||
a3 = MeanLoss/e0;
|
||||
|
||||
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,G4int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
else p3 = G4Poisson(a3);
|
||||
|
||||
|
||||
loss = p3*e0 ;
|
||||
|
||||
|
||||
if(p3 > 0) loss += (1.-2.*G4UniformRand())*e0 ;
|
||||
// G4cout << "MGP very small step " << loss/keV << G4endl;
|
||||
}
|
||||
@@ -929,8 +926,8 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
Tm = Tm-ipotFluct+e0 ;
|
||||
|
||||
// MGP ---- workaround to avoid log argument<0, TO BE CHECKED
|
||||
if (Tm <= 0.)
|
||||
{
|
||||
if (Tm <= 0.)
|
||||
{
|
||||
loss = MeanLoss;
|
||||
p3 = 0;
|
||||
// G4cout << "MGP correction loss = MeanLoss " << loss/keV << G4endl;
|
||||
@@ -971,7 +968,7 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else // not so small Step
|
||||
{
|
||||
// excitation type 1
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eBremsstrahlungSpectrum.cc,v 1.7 2002/05/30 17:53:09 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4eBremsstrahlungSpectrum.cc,v 1.9 2003/02/28 08:42:18 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -31,14 +31,16 @@
|
||||
// File name: G4eBremsstrahlungSpectrum
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
//
|
||||
// Creation date: 29 September 2001
|
||||
//
|
||||
// Modifications:
|
||||
// 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
|
||||
// 30.05.02 VI Update interpolation between 2 last energy points in the
|
||||
// parametrisation
|
||||
// 21.02.03 V.Ivanchenko Energy bins are defined in the constructor
|
||||
// 28.02.03 V.Ivanchenko Filename is defined in the constructor
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -47,36 +49,27 @@
|
||||
#include "Randomize.hh"
|
||||
|
||||
|
||||
G4eBremsstrahlungSpectrum::G4eBremsstrahlungSpectrum():
|
||||
G4VEnergySpectrum(),
|
||||
G4eBremsstrahlungSpectrum::G4eBremsstrahlungSpectrum(const G4DataVector& bins,
|
||||
const G4String& name):G4VEnergySpectrum(),
|
||||
lowestE(0.1*eV),
|
||||
length(15)
|
||||
xp(bins)
|
||||
{
|
||||
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);
|
||||
}
|
||||
length = xp.size();
|
||||
theBRparam = new G4BremsstrahlungParameters(name,length+1);
|
||||
|
||||
verbose = 0;
|
||||
}
|
||||
|
||||
|
||||
G4eBremsstrahlungSpectrum::~G4eBremsstrahlungSpectrum()
|
||||
G4eBremsstrahlungSpectrum::~G4eBremsstrahlungSpectrum()
|
||||
{
|
||||
delete theBRparam;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double e,
|
||||
G4int,
|
||||
const G4ParticleDefinition*) const
|
||||
@@ -95,20 +88,20 @@ G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
|
||||
for (size_t i=0; i<=length; i++) {
|
||||
p.push_back(theBRparam->Parameter(i, Z, e));
|
||||
}
|
||||
|
||||
|
||||
G4double x = IntSpectrum(t0, tm, p);
|
||||
G4double y = IntSpectrum(z, 1.0, p);
|
||||
G4double y = IntSpectrum(z, 1.0, p);
|
||||
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "tcut(MeV)= " << tmin/MeV
|
||||
<< "; tMax(MeV)= " << tmax/MeV
|
||||
<< "; t0= " << t0
|
||||
<< "; tm= " << tm
|
||||
G4cout << "tcut(MeV)= " << tmin/MeV
|
||||
<< "; tMax(MeV)= " << tmax/MeV
|
||||
<< "; t0= " << t0
|
||||
<< "; tm= " << tm
|
||||
<< "; xp[0]= " << xp[0]
|
||||
<< "; z= " << z
|
||||
<< "; val= " << x
|
||||
<< "; nor= " << y
|
||||
<< "; z= " << z
|
||||
<< "; val= " << x
|
||||
<< "; nor= " << y
|
||||
<< G4endl;
|
||||
}
|
||||
p.clear();
|
||||
@@ -117,13 +110,13 @@ G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
|
||||
else x = 0.0;
|
||||
// if(x < 0.0) x = 0.0;
|
||||
|
||||
return x;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double e,
|
||||
G4int,
|
||||
const G4ParticleDefinition*) const
|
||||
@@ -153,16 +146,16 @@ G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
|
||||
G4double f = Function(z0, p);
|
||||
x += 0.5*f*z0*(z0 - c*atan(z0/c));
|
||||
|
||||
x *= e;
|
||||
x *= e;
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "tcut(MeV)= " << tmin/MeV
|
||||
<< "; tMax(MeV)= " << tmax/MeV
|
||||
<< "; e(MeV)= " << e/MeV
|
||||
<< "; t0= " << t0
|
||||
<< "; tm= " << tm
|
||||
G4cout << "tcut(MeV)= " << tmin/MeV
|
||||
<< "; tMax(MeV)= " << tmax/MeV
|
||||
<< "; e(MeV)= " << e/MeV
|
||||
<< "; t0= " << t0
|
||||
<< "; tm= " << tm
|
||||
<< "; y= " << y
|
||||
<< "; x= " << x
|
||||
<< "; x= " << x
|
||||
<< G4endl;
|
||||
}
|
||||
p.clear();
|
||||
@@ -171,13 +164,13 @@ G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
|
||||
else x = 0.0;
|
||||
// if(x < 0.0) x = 0.0;
|
||||
|
||||
return x;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double tmin,
|
||||
G4double tmax,
|
||||
G4double e,
|
||||
G4int,
|
||||
const G4ParticleDefinition*) const
|
||||
@@ -194,7 +187,7 @@ G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
|
||||
for (size_t i=0; i<=length; i++) {
|
||||
p.push_back(theBRparam->Parameter(i, Z, e));
|
||||
}
|
||||
G4double amaj = G4std::max(p[15], 1. - (p[1] - p[0])/9.);
|
||||
G4double amaj = G4std::max(p[length], 1. - (p[1] - p[0])*xp[0]/(xp[1] - xp[0]) );
|
||||
|
||||
G4double amax = log(tm);
|
||||
G4double amin = log(t0);
|
||||
@@ -206,8 +199,8 @@ G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
|
||||
fun = Function(tgam, p);
|
||||
|
||||
if(fun > amaj) {
|
||||
G4cout << "WARNING in G4eBremsstrahlungSpectrum::SampleEnergy:"
|
||||
<< " Majoranta " << amaj
|
||||
G4cout << "WARNING in G4eBremsstrahlungSpectrum::SampleEnergy:"
|
||||
<< " Majoranta " << amaj
|
||||
<< " < " << fun
|
||||
<< G4endl;
|
||||
}
|
||||
@@ -219,19 +212,19 @@ G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
|
||||
|
||||
p.clear();
|
||||
|
||||
return tgam;
|
||||
return tgam;
|
||||
}
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
|
||||
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 sum = 0.0;
|
||||
|
||||
|
||||
if(x1 < x2) {
|
||||
G4double k = (p[1] - p[0])/0.09;
|
||||
G4double k = (p[1] - p[0])/(xp[1] - xp[0]);
|
||||
sum += (1. - k*xp[0])*log(x2/x1) + k*(x2 - x1);
|
||||
}
|
||||
|
||||
@@ -248,7 +241,7 @@ G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
|
||||
return sum;
|
||||
}
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
|
||||
G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
|
||||
G4double xMax,
|
||||
const G4DataVector& p) const
|
||||
{
|
||||
@@ -257,9 +250,9 @@ G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
|
||||
G4double z1 = x1;
|
||||
G4double z2 = x2;
|
||||
G4double sum = 0.0;
|
||||
|
||||
|
||||
if(x1 < x2) {
|
||||
G4double k = (p[1] - p[0])/0.09;
|
||||
G4double k = (p[1] - p[0])/(xp[1] - xp[0]);
|
||||
sum += (z2 - z1)*(1. - k*xp[0]);
|
||||
z1 *= x1;
|
||||
z2 *= x2;
|
||||
@@ -277,15 +270,15 @@ G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
|
||||
}
|
||||
if(sum < 0.0) sum = 0.0;
|
||||
return sum;
|
||||
}
|
||||
|
||||
G4double G4eBremsstrahlungSpectrum::Function(G4double x,
|
||||
}
|
||||
|
||||
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;
|
||||
f = 1. + (p[1] - p[0])*(x - xp[0])/(xp[1] - xp[0]);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -298,7 +291,7 @@ G4double G4eBremsstrahlungSpectrum::Function(G4double x,
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
void G4eBremsstrahlungSpectrum::PrintData() const
|
||||
{ theBRparam->PrintData(); }
|
||||
@@ -311,6 +304,6 @@ G4double G4eBremsstrahlungSpectrum::Excitation(G4int Z, G4double kineticEnergy)
|
||||
G4double G4eBremsstrahlungSpectrum::MaxEnergyOfSecondaries(G4double kineticEnergy,
|
||||
G4int Z,
|
||||
const G4ParticleDefinition*) const
|
||||
{
|
||||
return kineticEnergy;
|
||||
{
|
||||
return kineticEnergy;
|
||||
}
|
||||
|
||||
+27
-28
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eIonisationCrossSectionHandler.cc,v 1.8 2002/07/19 17:32:50 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4eIonisationCrossSectionHandler.cc,v 1.9 2003/01/22 18:47:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -35,8 +35,9 @@
|
||||
// Creation date: 25 Sept 2001
|
||||
//
|
||||
// Modifications:
|
||||
// 10 Oct 2001 M.G. Pia Revision to improve code quality and consistency with design
|
||||
// 19 Jul 2002 VI Create composite data set for material
|
||||
// 10 Oct 2001 M.G. Pia Revision to improve code quality and consistency with design
|
||||
// 19 Jul 2002 VI Create composite data set for material
|
||||
// 21 Jan 2003 V.Ivanchenko Cut per region
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
@@ -50,11 +51,11 @@
|
||||
#include "G4VEMDataSet.hh"
|
||||
#include "G4EMDataSet.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
|
||||
G4eIonisationCrossSectionHandler::G4eIonisationCrossSectionHandler(
|
||||
const G4VEnergySpectrum* spec, G4VDataSetAlgorithm* alg,
|
||||
const G4VEnergySpectrum* spec, G4VDataSetAlgorithm* alg,
|
||||
G4double emin, G4double emax, G4int nbin)
|
||||
: G4VCrossSectionHandler(),
|
||||
theParam(spec)
|
||||
@@ -64,15 +65,15 @@ G4eIonisationCrossSectionHandler::G4eIonisationCrossSectionHandler(
|
||||
}
|
||||
|
||||
|
||||
G4eIonisationCrossSectionHandler::~G4eIonisationCrossSectionHandler()
|
||||
G4eIonisationCrossSectionHandler::~G4eIonisationCrossSectionHandler()
|
||||
{
|
||||
delete interp;
|
||||
}
|
||||
|
||||
|
||||
G4std::vector<G4VEMDataSet*>* G4eIonisationCrossSectionHandler::BuildCrossSectionsForMaterials(
|
||||
const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
const G4DataVector& energyVector,
|
||||
const G4DataVector* energyCuts)
|
||||
{
|
||||
G4int verbose = 0;
|
||||
G4std::vector<G4VEMDataSet*>* set = new G4std::vector<G4VEMDataSet*>;
|
||||
@@ -81,33 +82,31 @@ G4std::vector<G4VEMDataSet*>* G4eIonisationCrossSectionHandler::BuildCrossSectio
|
||||
G4DataVector* cs;
|
||||
G4int nOfBins = energyVector.size();
|
||||
|
||||
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
|
||||
if (materialTable == 0)
|
||||
G4Exception("G4VCrossSectionHandler::G4VCrossSectionHandler - no MaterialTable found)");
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
G4int nMaterials = G4Material::GetNumberOfMaterials();
|
||||
for (size_t m=0; m<numOfCouples; m++) {
|
||||
|
||||
for (G4int m=0; m<nMaterials; m++) {
|
||||
|
||||
const G4Material* material = (*materialTable)[m];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(m);
|
||||
const G4Material* material= couple->GetMaterial();
|
||||
const G4ElementVector* elementVector = material->GetElementVector();
|
||||
//const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
const G4double* nAtomsPerVolume = material->GetAtomicNumDensityVector();
|
||||
G4int nElements = material->GetNumberOfElements();
|
||||
|
||||
if(verbose > 0) {
|
||||
G4cout << "eIonisation CS for " << m << "th material "
|
||||
<< material->GetName()
|
||||
<< " eEl= " << nElements << G4endl;
|
||||
G4cout << "eIonisation CS for " << m << "th material "
|
||||
<< material->GetName()
|
||||
<< " eEl= " << nElements << G4endl;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -123,10 +122,10 @@ G4std::vector<G4VEMDataSet*>* G4eIonisationCrossSectionHandler::BuildCrossSectio
|
||||
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);
|
||||
G4double p = theParam->Probability(Z, tcut, e, e, n);
|
||||
value += cross * p * density;
|
||||
|
||||
if(verbose>0 && m == 0 && e>=1. && e<=0.) {
|
||||
|
||||
if(verbose>0 && m == 0 && e>=1. && e<=0.) {
|
||||
G4cout << "G4eIonCrossSH: e(MeV)= " << e/MeV
|
||||
<< " n= " << n
|
||||
<< " cross= " << cross
|
||||
@@ -137,18 +136,18 @@ G4std::vector<G4VEMDataSet*>* G4eIonisationCrossSectionHandler::BuildCrossSectio
|
||||
<< " Z= " << Z
|
||||
<< 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//
|
||||
//
|
||||
// $Id: G4eIonisationParameters.cc,v 1.19 2002/05/30 17:53:09 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
|
||||
//
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eIonisationSpectrum.cc,v 1.20 2002/07/19 17:32:50 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eLowEnergyLoss.cc,v 1.29 2002/10/28 09:43:51 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4eLowEnergyLoss.cc,v 1.30 2003/01/22 18:47:29 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -42,7 +42,7 @@
|
||||
// 08-09-98: cleanup
|
||||
// 24-09-98: rndmStepFlag false by default (no randomization of the step)
|
||||
// 14-10-98: messenger file added.
|
||||
// 16-10-98: public method SetStepFunction()
|
||||
// 16-10-98: public method SetStepFunction()
|
||||
// 20-01-99: important correction in AlongStepDoIt , L.Urban
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// 11/04/00: Bug fix in dE/dx fluctuation simulation, Veronique Lefebure
|
||||
@@ -52,19 +52,21 @@
|
||||
// 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
|
||||
// 26/10/01 VI Clean up access to deexcitation
|
||||
// 23/11/01 VI Move static member-functions from header to source
|
||||
// 28/05/02 VI Remove flag fStopAndKill
|
||||
// 03/06/02 MGP - Restore fStopAndKill
|
||||
// 28/10/02 VI Optimal binning for dE/dx
|
||||
// 21/01/03 VI cut per region
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
#include "G4eLowEnergyLoss.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
// Initialisation of static data members
|
||||
// -------------------------------------
|
||||
@@ -84,7 +86,7 @@ G4PhysicsTable** G4eLowEnergyLoss::RecorderOfElectronProcess =
|
||||
new G4PhysicsTable*[10];
|
||||
G4PhysicsTable** G4eLowEnergyLoss::RecorderOfPositronProcess =
|
||||
new G4PhysicsTable*[10];
|
||||
|
||||
|
||||
|
||||
G4PhysicsTable* G4eLowEnergyLoss::theDEDXElectronTable = 0;
|
||||
G4PhysicsTable* G4eLowEnergyLoss::theDEDXPositronTable = 0;
|
||||
@@ -136,7 +138,7 @@ G4eLowEnergyLoss::G4eLowEnergyLoss(const G4String& processName)
|
||||
if(!eLossMessenger) eLossMessenger = new G4EnergyLossMessenger();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
G4eLowEnergyLoss::~G4eLowEnergyLoss()
|
||||
{
|
||||
@@ -170,19 +172,19 @@ G4int G4eLowEnergyLoss::GetNbOfProcesses()
|
||||
void G4eLowEnergyLoss::SetLowerBoundEloss(G4double val)
|
||||
{
|
||||
LowerBoundEloss=val;
|
||||
}
|
||||
}
|
||||
|
||||
void G4eLowEnergyLoss::SetUpperBoundEloss(G4double val)
|
||||
{
|
||||
UpperBoundEloss=val;
|
||||
}
|
||||
|
||||
|
||||
void G4eLowEnergyLoss::SetNbinEloss(G4int nb)
|
||||
{
|
||||
NbinEloss=nb;
|
||||
}
|
||||
|
||||
G4double G4eLowEnergyLoss::GetLowerBoundEloss()
|
||||
G4double G4eLowEnergyLoss::GetLowerBoundEloss()
|
||||
{
|
||||
return LowerBoundEloss;
|
||||
}
|
||||
@@ -191,7 +193,7 @@ G4double G4eLowEnergyLoss::GetUpperBoundEloss()
|
||||
{
|
||||
return UpperBoundEloss;
|
||||
}
|
||||
|
||||
|
||||
G4int G4eLowEnergyLoss::GetNbinEloss()
|
||||
{
|
||||
return NbinEloss;
|
||||
@@ -210,11 +212,13 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
LOGRTable=lrate/NbinEloss;
|
||||
RTable =exp(LOGRTable);
|
||||
// Build energy loss table as a sum of the energy loss due to the
|
||||
// different processes.
|
||||
// different processes.
|
||||
//
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
// create table for the total energy loss
|
||||
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
@@ -224,11 +228,11 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
if (CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
if (theDEDXElectronTable)
|
||||
{
|
||||
{
|
||||
theDEDXElectronTable->clearAndDestroy();
|
||||
delete theDEDXElectronTable;
|
||||
delete theDEDXElectronTable;
|
||||
}
|
||||
theDEDXElectronTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXElectronTable = new G4PhysicsTable(numOfCouples);
|
||||
theDEDXTable = theDEDXElectronTable;
|
||||
}
|
||||
}
|
||||
@@ -239,11 +243,11 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
if (CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
if (theDEDXPositronTable)
|
||||
{
|
||||
{
|
||||
theDEDXPositronTable->clearAndDestroy();
|
||||
delete theDEDXPositronTable;
|
||||
delete theDEDXPositronTable;
|
||||
}
|
||||
theDEDXPositronTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXPositronTable = new G4PhysicsTable(numOfCouples);
|
||||
theDEDXTable = theDEDXPositronTable;
|
||||
}
|
||||
}
|
||||
@@ -256,39 +260,39 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
G4bool isOutRange;
|
||||
G4PhysicsTable* pointer;
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfCouples; J++)
|
||||
{
|
||||
// create physics vector and fill it
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowerBoundEloss, UpperBoundEloss, NbinEloss);
|
||||
LowerBoundEloss, UpperBoundEloss, NbinEloss);
|
||||
|
||||
// loop for the kinetic energy
|
||||
for (G4int i=0; i<NbinEloss; i++)
|
||||
for (G4int i=0; i<NbinEloss; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
//here comes the sum of the different tables created by the
|
||||
//processes (ionisation,bremsstrahlung,etc...)
|
||||
Value = 0.;
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
//here comes the sum of the different tables created by the
|
||||
//processes (ionisation,bremsstrahlung,etc...)
|
||||
Value = 0.;
|
||||
for (G4int process=0; process < NbOfProcesses; process++)
|
||||
{
|
||||
pointer= RecorderOfProcess[process];
|
||||
Value += (*pointer)[J]->GetValue(LowEdgeEnergy,isOutRange);
|
||||
}
|
||||
|
||||
aVector->PutValue(i,Value) ;
|
||||
aVector->PutValue(i,Value) ;
|
||||
}
|
||||
|
||||
theDEDXTable->insert(aVector) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//reset counter to zero
|
||||
if (&aParticleType==G4Electron::Electron()) CounterOfElectronProcess=0;
|
||||
if (&aParticleType==G4Positron::Positron()) CounterOfPositronProcess=0;
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
@@ -370,7 +374,7 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
|
||||
|
||||
// make the energy loss and the range table available
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
(&aParticleType==G4Electron::Electron())?
|
||||
theDEDXElectronTable: theDEDXPositronTable,
|
||||
(&aParticleType==G4Electron::Electron())?
|
||||
@@ -385,83 +389,83 @@ void G4eLowEnergyLoss::BuildDEDXTable(
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
{
|
||||
// compute the energy loss after a Step
|
||||
|
||||
static const G4double faclow = 1.5 ;
|
||||
|
||||
// get particle and material pointers from trackData
|
||||
// get particle and material pointers from trackData
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double E = aParticle->GetKineticEnergy() ;
|
||||
|
||||
G4Material* aMaterial = trackData.GetMaterial();
|
||||
|
||||
G4double E = aParticle->GetKineticEnergy();
|
||||
|
||||
const G4MaterialCutsCouple* couple = trackData.GetMaterialCutsCouple();
|
||||
|
||||
G4double Step = stepData.GetStepLength();
|
||||
|
||||
aParticleChange.Initialize(trackData);
|
||||
//fParticleChange.Initialize(trackData);
|
||||
|
||||
G4double MeanLoss, finalT;
|
||||
aParticleChange.Initialize(trackData);
|
||||
//fParticleChange.Initialize(trackData);
|
||||
|
||||
if (E < MinKineticEnergy) finalT = 0.;
|
||||
|
||||
else if ( E< faclow*LowerBoundEloss)
|
||||
G4double MeanLoss, finalT;
|
||||
|
||||
if (E < MinKineticEnergy) finalT = 0.;
|
||||
|
||||
else if ( E< faclow*LowerBoundEloss)
|
||||
{
|
||||
if (Step >= fRangeNow) finalT = 0.;
|
||||
if (Step >= fRangeNow) finalT = 0.;
|
||||
// else finalT = E*(1.-Step/fRangeNow) ;
|
||||
else finalT = E*(1.-sqrt(Step/fRangeNow)) ;
|
||||
}
|
||||
|
||||
|
||||
else if (E>=UpperBoundEloss) finalT = E - Step*fdEdx;
|
||||
|
||||
else if (Step >= fRangeNow) finalT = 0.;
|
||||
|
||||
|
||||
else if (Step >= fRangeNow) finalT = 0.;
|
||||
|
||||
else
|
||||
{
|
||||
if(Step/fRangeNow < linLossLimit) finalT = E-Step*fdEdx ;
|
||||
else
|
||||
{
|
||||
if (Charge<0.) finalT = G4EnergyLossTables::GetPreciseEnergyFromRange
|
||||
(G4Electron::Electron(),fRangeNow-Step,aMaterial);
|
||||
(G4Electron::Electron(),fRangeNow-Step,couple);
|
||||
else finalT = G4EnergyLossTables::GetPreciseEnergyFromRange
|
||||
(G4Positron::Positron(),fRangeNow-Step,aMaterial);
|
||||
(G4Positron::Positron(),fRangeNow-Step,couple);
|
||||
}
|
||||
}
|
||||
|
||||
if(finalT < MinKineticEnergy) finalT = 0. ;
|
||||
|
||||
MeanLoss = E-finalT ;
|
||||
|
||||
MeanLoss = E-finalT ;
|
||||
|
||||
//now the loss with fluctuation
|
||||
if ((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowerBoundEloss))
|
||||
{
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss,Step);
|
||||
finalT = E-GetLossWithFluct(aParticle,couple,MeanLoss,Step);
|
||||
if (finalT < 0.) finalT = 0.;
|
||||
}
|
||||
|
||||
// kill the particle if the kinetic energy <= 0
|
||||
// kill the particle if the kinetic energy <= 0
|
||||
if (finalT <= 0. )
|
||||
{
|
||||
finalT = 0.;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
G4double edep = E - finalT;
|
||||
|
||||
aParticleChange.SetEnergyChange(finalT);
|
||||
|
||||
aParticleChange.SetEnergyChange(finalT);
|
||||
|
||||
// Deexcitation of ionised atoms
|
||||
G4std::vector<G4DynamicParticle*>* deexcitationProducts = 0;
|
||||
if (theFluo) deexcitationProducts = DeexciteAtom(aMaterial,E,edep);
|
||||
if (theFluo) deexcitationProducts = DeexciteAtom(couple,E,edep);
|
||||
|
||||
size_t nSecondaries = 0;
|
||||
size_t nSecondaries = 0;
|
||||
if (deexcitationProducts != 0) nSecondaries = deexcitationProducts->size();
|
||||
aParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
|
||||
|
||||
if (nSecondaries > 0) {
|
||||
|
||||
const G4StepPoint* preStep = stepData.GetPreStepPoint();
|
||||
@@ -474,14 +478,14 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
deltaT -= t;
|
||||
G4double time, q;
|
||||
G4ThreeVector position;
|
||||
|
||||
|
||||
for (size_t i=0; i<nSecondaries; i++) {
|
||||
|
||||
G4DynamicParticle* part = (*deexcitationProducts)[i];
|
||||
G4DynamicParticle* part = (*deexcitationProducts)[i];
|
||||
if (part != 0) {
|
||||
G4double eSecondary = part->GetKineticEnergy();
|
||||
edep -= eSecondary;
|
||||
if (edep > 0.)
|
||||
if (edep > 0.)
|
||||
{
|
||||
q = G4UniformRand();
|
||||
time = deltaT*q + t;
|
||||
@@ -498,14 +502,13 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete deexcitationProducts;
|
||||
|
||||
}
|
||||
delete deexcitationProducts;
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(edep);
|
||||
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,23 +21,23 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4hLowEnergyLoss.cc,v 1.17 2002/10/28 09:43:52 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4hLowEnergyLoss.cc,v 1.19 2003/01/23 11:39:07 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// History: based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ---------- G4hEnergyLoss physics process -----------
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
//
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
// It calculates the energy loss of charged hadrons.
|
||||
// **************************************************************
|
||||
//
|
||||
// 7/10/98 bug fixes + some cleanup , L.Urban
|
||||
// 7/10/98 bug fixes + some cleanup , L.Urban
|
||||
// 22/10/98 cleanup , L.Urban
|
||||
// 07/12/98 works for ions as well+ bug corrected, L.Urban
|
||||
// 02/02/99 several bugs fixed, L.Urban
|
||||
@@ -46,19 +46,22 @@
|
||||
// 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
|
||||
// 28/10/02 V.Ivanchenko Optimal binning for dE/dx
|
||||
// 21/01/03 V.Ivanchenko Cut per region
|
||||
// 23/01/03 V.Ivanchenko Fix in table build
|
||||
// --------------------------------------------------------------
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4hLowEnergyLoss.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// Initialisation of static members ******************************************
|
||||
// contributing processes : ion.loss ->NumberOfProcesses is initialized
|
||||
// to 1 . YOU DO NOT HAVE TO CHANGE this variable for a 'normal' run.
|
||||
// You have to change NumberOfProcesses
|
||||
// You have to change NumberOfProcesses
|
||||
// if you invent a new process contributing to the cont. energy loss,
|
||||
// NumberOfProcesses should be 2 in this case,
|
||||
// or for debugging purposes.
|
||||
@@ -133,7 +136,7 @@ G4bool G4hLowEnergyLoss::rndmStepFlag = false ;
|
||||
G4bool G4hLowEnergyLoss::EnlossFlucFlag = true ;
|
||||
|
||||
G4double G4hLowEnergyLoss::LowestKineticEnergy = 10.*eV;
|
||||
G4double G4hLowEnergyLoss::HighestKineticEnergy= 100.*GeV;
|
||||
G4double G4hLowEnergyLoss::HighestKineticEnergy= 100.*GeV;
|
||||
G4int G4hLowEnergyLoss::TotBin = 360;
|
||||
G4double G4hLowEnergyLoss::RTable,G4hLowEnergyLoss::LOGRTable;
|
||||
|
||||
@@ -143,7 +146,6 @@ G4double G4hLowEnergyLoss::RTable,G4hLowEnergyLoss::LOGRTable;
|
||||
|
||||
G4hLowEnergyLoss::G4hLowEnergyLoss(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess (processName),
|
||||
lastMaterial (0),
|
||||
MaxExcitationNumber (1.e6),
|
||||
probLimFluct (0.01),
|
||||
nmaxDirectFluct (100),
|
||||
@@ -230,49 +232,26 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// calculate data members TotBin,LOGRTable,RTable first
|
||||
/*
|
||||
G4double binning = dRoverRange;
|
||||
G4double lrate = log(HighestKineticEnergy/LowestKineticEnergy);
|
||||
G4int nbin = G4int(lrate/log(1.+binning) + 0.5 );
|
||||
nbin = (nbin+25)/50;
|
||||
LOGRTable=lrate/TotBin;
|
||||
RTable =exp(LOGRTable);
|
||||
*/
|
||||
// create table if there is no table or there is a new cut value
|
||||
G4bool MakeTable = false ;
|
||||
|
||||
// ---- 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
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
// create/fill proton or antiproton tables depending on the charge
|
||||
Charge = aParticleType.GetPDGCharge()/eplus;
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
if (Charge>0.) {theDEDXTable= theDEDXpTable;}
|
||||
else {theDEDXTable= theDEDXpbarTable;}
|
||||
|
||||
if(
|
||||
((Charge>0.) && ((theDEDXTable==0) ||
|
||||
(ElectronCutInRange != ptableElectronCutInRange)))
|
||||
||
|
||||
((Charge<0.) && ((theDEDXTable==0) ||
|
||||
(ElectronCutInRange != pbartableElectronCutInRange)))
|
||||
if( ((Charge>0.) && (theDEDXTable==0)) ||
|
||||
((Charge<0.) && (theDEDXTable==0))
|
||||
)
|
||||
MakeTable = true ;
|
||||
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
if( MakeTable )
|
||||
{
|
||||
|
||||
// Build energy loss table as a sum of the energy loss due to the
|
||||
// different processes.
|
||||
if( Charge >0.)
|
||||
// different processes.
|
||||
if( Charge >0.)
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpProcess;
|
||||
CounterOfProcess=CounterOfpProcess;
|
||||
@@ -282,9 +261,8 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
if(theDEDXpTable)
|
||||
{ theDEDXpTable->clearAndDestroy();
|
||||
delete theDEDXpTable; }
|
||||
theDEDXpTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXpTable = new G4PhysicsTable(numOfCouples);
|
||||
theDEDXTable = theDEDXpTable;
|
||||
ptableElectronCutInRange = ElectronCutInRange ;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -297,9 +275,8 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
if(theDEDXpbarTable)
|
||||
{ theDEDXpbarTable->clearAndDestroy();
|
||||
delete theDEDXpbarTable; }
|
||||
theDEDXpbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXpbarTable = new G4PhysicsTable(numOfCouples);
|
||||
theDEDXTable = theDEDXpbarTable;
|
||||
pbartableElectronCutInRange = ElectronCutInRange ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,18 +287,18 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
G4bool isOutRange ;
|
||||
G4PhysicsTable* pointer ;
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
for (size_t J=0; J<numOfCouples; J++)
|
||||
{
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
|
||||
// loop for the kinetic energy
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
Value = 0. ;
|
||||
|
||||
|
||||
// loop for the contributing processes
|
||||
for (G4int process=0; process < NumberOfProcesses; process++)
|
||||
{
|
||||
@@ -330,24 +307,24 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
GetValue(LowEdgeEnergy,isOutRange) ;
|
||||
}
|
||||
|
||||
aVector->PutValue(i,Value) ;
|
||||
aVector->PutValue(i,Value) ;
|
||||
}
|
||||
|
||||
theDEDXTable->insert(aVector) ;
|
||||
}
|
||||
|
||||
|
||||
// reset counter to zero ..................
|
||||
if( Charge >0.)
|
||||
if( Charge >0.)
|
||||
CounterOfpProcess=0 ;
|
||||
else
|
||||
CounterOfpbarProcess=0 ;
|
||||
|
||||
// Build range table
|
||||
BuildRangeTable( aParticleType);
|
||||
BuildRangeTable( aParticleType);
|
||||
|
||||
// Build lab/proper time tables
|
||||
BuildTimeTables( aParticleType) ;
|
||||
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
BuildRangeCoeffATable( aParticleType);
|
||||
BuildRangeCoeffBTable( aParticleType);
|
||||
@@ -360,7 +337,7 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
}
|
||||
// make the energy loss and the range table available
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
(Charge>0)?
|
||||
theDEDXpTable: theDEDXpbarTable,
|
||||
(Charge>0)?
|
||||
@@ -378,35 +355,37 @@ void G4hLowEnergyLoss::BuildDEDXTable(
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
void G4hLowEnergyLoss::BuildRangeTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// Build range table from the energy loss table
|
||||
{
|
||||
Mass = aParticleType.GetPDGMass();
|
||||
Mass = aParticleType.GetPDGMass();
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if( Charge >0.)
|
||||
{
|
||||
{
|
||||
if(theRangepTable)
|
||||
{ theRangepTable->clearAndDestroy();
|
||||
delete theRangepTable; }
|
||||
theRangepTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangepTable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if(theRangepbarTable)
|
||||
{ theRangepbarTable->clearAndDestroy();
|
||||
delete theRangepbarTable; }
|
||||
theRangepbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangepbarTable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
aVector = new G4PhysicsLogVector(LowestKineticEnergy,
|
||||
@@ -415,7 +394,7 @@ void G4hLowEnergyLoss::BuildRangeTable(
|
||||
BuildRangeVector(J, aVector);
|
||||
theRangeTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -423,20 +402,22 @@ void G4hLowEnergyLoss::BuildTimeTables(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
{
|
||||
if(theLabTimepTable)
|
||||
{ theLabTimepTable->clearAndDestroy();
|
||||
delete theLabTimepTable; }
|
||||
theLabTimepTable = new G4PhysicsTable(numOfMaterials);
|
||||
theLabTimepTable = new G4PhysicsTable(numOfCouples);
|
||||
theLabTimeTable = theLabTimepTable ;
|
||||
|
||||
if(theProperTimepTable)
|
||||
{ theProperTimepTable->clearAndDestroy();
|
||||
delete theProperTimepTable; }
|
||||
theProperTimepTable = new G4PhysicsTable(numOfMaterials);
|
||||
theProperTimepTable = new G4PhysicsTable(numOfCouples);
|
||||
theProperTimeTable = theProperTimepTable ;
|
||||
}
|
||||
|
||||
@@ -445,17 +426,17 @@ void G4hLowEnergyLoss::BuildTimeTables(
|
||||
if(theLabTimepbarTable)
|
||||
{ theLabTimepbarTable->clearAndDestroy();
|
||||
delete theLabTimepbarTable; }
|
||||
theLabTimepbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theLabTimepbarTable = new G4PhysicsTable(numOfCouples);
|
||||
theLabTimeTable = theLabTimepbarTable ;
|
||||
|
||||
if(theProperTimepbarTable)
|
||||
{ theProperTimepbarTable->clearAndDestroy();
|
||||
delete theProperTimepbarTable; }
|
||||
theProperTimepbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theProperTimepbarTable = new G4PhysicsTable(numOfCouples);
|
||||
theProperTimeTable = theProperTimepbarTable ;
|
||||
}
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
G4PhysicsLogVector* bVector;
|
||||
@@ -591,7 +572,7 @@ void G4hLowEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
G4int i=-1;
|
||||
G4double oldValue = 0. ;
|
||||
G4double tauold ;
|
||||
do
|
||||
do
|
||||
{
|
||||
i += 1 ;
|
||||
LowEdgeEnergy = timeVector->GetLowEdgeEnergy(i);
|
||||
@@ -764,23 +745,23 @@ void G4hLowEnergyLoss::BuildRangeCoeffATable(
|
||||
// create table for coefficients "A"
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
if(thepRangeCoeffATable)
|
||||
{ thepRangeCoeffATable->clearAndDestroy();
|
||||
delete thepRangeCoeffATable; }
|
||||
thepRangeCoeffATable = new G4PhysicsTable(numOfMaterials);
|
||||
thepRangeCoeffATable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeCoeffATable = thepRangeCoeffATable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if(thepbarRangeCoeffATable)
|
||||
{ thepbarRangeCoeffATable->clearAndDestroy();
|
||||
delete thepbarRangeCoeffATable; }
|
||||
thepbarRangeCoeffATable = new G4PhysicsTable(numOfMaterials);
|
||||
thepbarRangeCoeffATable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeCoeffATable = thepbarRangeCoeffATable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
@@ -793,7 +774,7 @@ void G4hLowEnergyLoss::BuildRangeCoeffATable(
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector =
|
||||
@@ -836,14 +817,14 @@ void G4hLowEnergyLoss::BuildRangeCoeffBTable(
|
||||
// create table for coefficients "B"
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
if(thepRangeCoeffBTable)
|
||||
{ thepRangeCoeffBTable->clearAndDestroy();
|
||||
delete thepRangeCoeffBTable; }
|
||||
thepRangeCoeffBTable = new G4PhysicsTable(numOfMaterials);
|
||||
thepRangeCoeffBTable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeCoeffBTable = thepRangeCoeffBTable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
@@ -852,7 +833,7 @@ void G4hLowEnergyLoss::BuildRangeCoeffBTable(
|
||||
if(thepbarRangeCoeffBTable)
|
||||
{ thepbarRangeCoeffBTable->clearAndDestroy();
|
||||
delete thepbarRangeCoeffBTable; }
|
||||
thepbarRangeCoeffBTable = new G4PhysicsTable(numOfMaterials);
|
||||
thepbarRangeCoeffBTable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeCoeffBTable = thepbarRangeCoeffBTable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
@@ -865,7 +846,7 @@ void G4hLowEnergyLoss::BuildRangeCoeffBTable(
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector =
|
||||
@@ -907,14 +888,14 @@ void G4hLowEnergyLoss::BuildRangeCoeffCTable(
|
||||
// create table for coefficients "C"
|
||||
{
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfCouples = G4ProductionCutsTable::GetProductionCutsTable()->GetTableSize();
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
if(thepRangeCoeffCTable)
|
||||
{ thepRangeCoeffCTable->clearAndDestroy();
|
||||
delete thepRangeCoeffCTable; }
|
||||
thepRangeCoeffCTable = new G4PhysicsTable(numOfMaterials);
|
||||
thepRangeCoeffCTable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeCoeffCTable = thepRangeCoeffCTable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
@@ -923,7 +904,7 @@ void G4hLowEnergyLoss::BuildRangeCoeffCTable(
|
||||
if(thepbarRangeCoeffCTable)
|
||||
{ thepbarRangeCoeffCTable->clearAndDestroy();
|
||||
delete thepbarRangeCoeffCTable; }
|
||||
thepbarRangeCoeffCTable = new G4PhysicsTable(numOfMaterials);
|
||||
thepbarRangeCoeffCTable = new G4PhysicsTable(numOfCouples);
|
||||
theRangeCoeffCTable = thepbarRangeCoeffCTable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
@@ -936,7 +917,7 @@ void G4hLowEnergyLoss::BuildRangeCoeffCTable(
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (G4int J=0; J<numOfCouples; J++)
|
||||
{
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector =
|
||||
@@ -978,13 +959,16 @@ void G4hLowEnergyLoss::BuildInverseRangeTable(
|
||||
{
|
||||
G4bool b;
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
{
|
||||
if(theInverseRangepTable)
|
||||
{ theInverseRangepTable->clearAndDestroy();
|
||||
delete theInverseRangepTable; }
|
||||
theInverseRangepTable = new G4PhysicsTable(numOfMaterials);
|
||||
theInverseRangepTable = new G4PhysicsTable(numOfCouples);
|
||||
theInverseRangeTable = theInverseRangepTable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
theDEDXTable = theDEDXpTable ;
|
||||
@@ -998,7 +982,7 @@ void G4hLowEnergyLoss::BuildInverseRangeTable(
|
||||
if(theInverseRangepbarTable)
|
||||
{ theInverseRangepbarTable->clearAndDestroy();
|
||||
delete theInverseRangepbarTable; }
|
||||
theInverseRangepbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theInverseRangepbarTable = new G4PhysicsTable(numOfCouples);
|
||||
theInverseRangeTable = theInverseRangepbarTable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
theDEDXTable = theDEDXpbarTable ;
|
||||
@@ -1008,7 +992,7 @@ void G4hLowEnergyLoss::BuildInverseRangeTable(
|
||||
}
|
||||
|
||||
// loop for materials
|
||||
for (G4int i=0; i<numOfMaterials; i++)
|
||||
for (size_t i=0; i<numOfCouples; i++)
|
||||
{
|
||||
|
||||
G4PhysicsVector* pv = (*theRangeTable)[i];
|
||||
@@ -1036,11 +1020,11 @@ void G4hLowEnergyLoss::BuildInverseRangeTable(
|
||||
|
||||
for (ihigh=ilow+1; ihigh<nbins; ihigh++) {
|
||||
energy2 = pv->GetLowEdgeEnergy(ihigh);
|
||||
range2 = pv->GetValue(energy2, b);
|
||||
range2 = pv->GetValue(energy2, b);
|
||||
if(range2 >= range || ihigh == nbins-1) {
|
||||
ilow = ihigh - 1;
|
||||
energy1 = pv->GetLowEdgeEnergy(ilow);
|
||||
range1 = pv->GetValue(energy1, b);
|
||||
range1 = pv->GetValue(energy1, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1106,5 +1090,24 @@ void G4hLowEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4hLowEnergyLoss::CutsWhereModified()
|
||||
{
|
||||
G4bool wasModified = false;
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
for (size_t j=0; j<numOfCouples; j++){
|
||||
if (theCoupleTable->GetMaterialCutsCouple(j)->IsRecalcNeeded()) {
|
||||
wasModified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return wasModified;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
// 18/08/2000 V.Ivanchenko TRIM85 model is added
|
||||
// 03/10/2000 V.Ivanchenko CodeWizard clean up
|
||||
// 10/05/2001 V.Ivanchenko Clean up againist Linux compilation with -Wall
|
||||
// 30/12/2003 V.Ivanchenko SRIM2003 model is added
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -55,6 +56,8 @@
|
||||
#include "G4hZiegler1977p.hh"
|
||||
#include "G4hZiegler1977He.hh"
|
||||
#include "G4hZiegler1985p.hh"
|
||||
#include "G4hSRIM2000p.hh"
|
||||
//#include "G4hSRIM2003p.hh"
|
||||
#include "G4hICRU49p.hh"
|
||||
#include "G4hICRU49He.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
@@ -83,11 +86,12 @@ void G4hParametrisedLossModel::InitializeMe()
|
||||
G4String ir49p = G4String("ICRU_R49p") ;
|
||||
G4String ir49He = G4String("ICRU_R49He") ;
|
||||
G4String zi85p = G4String("Ziegler1985p") ;
|
||||
if(zi77p == modelName) {
|
||||
G4String zi00p = G4String("SRIM2000p") ;
|
||||
if(zi77p == modelName) {
|
||||
eStopingPowerTable = new G4hZiegler1977p();
|
||||
highEnergyLimit = 100.0*MeV;
|
||||
lowEnergyLimit = 1.0*keV;
|
||||
|
||||
|
||||
} else if(zi77He == modelName) {
|
||||
eStopingPowerTable = new G4hZiegler1977He();
|
||||
highEnergyLimit = 10.0*MeV/4.0;
|
||||
@@ -96,7 +100,12 @@ void G4hParametrisedLossModel::InitializeMe()
|
||||
} else if(zi85p == modelName) {
|
||||
eStopingPowerTable = new G4hZiegler1985p();
|
||||
highEnergyLimit = 100.0*MeV;
|
||||
lowEnergyLimit = 1.0*eV;
|
||||
lowEnergyLimit = 1.0*keV;
|
||||
|
||||
} else if(zi00p == modelName) {
|
||||
eStopingPowerTable = new G4hSRIM2000p();
|
||||
highEnergyLimit = 100.0*MeV;
|
||||
lowEnergyLimit = 1.0*keV;
|
||||
|
||||
} else if(ir49p == modelName || blank == modelName) {
|
||||
eStopingPowerTable = new G4hICRU49p();
|
||||
@@ -107,7 +116,7 @@ void G4hParametrisedLossModel::InitializeMe()
|
||||
eStopingPowerTable = new G4hICRU49He();
|
||||
highEnergyLimit = 10.0*MeV/4.0;
|
||||
lowEnergyLimit = 1.0*keV/4.0;
|
||||
|
||||
|
||||
} else {
|
||||
G4cout <<
|
||||
"G4hLowEnergyIonisation warning: There is no table with the modelName <"
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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: G4hSRIM2000p
|
||||
//
|
||||
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
|
||||
//
|
||||
// Creation date: 07 Jan 2003
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Electronic stopping power parametrised according to
|
||||
// J. F. Ziegler, SRIM-2000 software package from www.SRIM.org
|
||||
//
|
||||
// Class Description: End
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4hSRIM2000p.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4Material.hh"
|
||||
|
||||
G4double G4hSRIM2000p::a[92][8] = {
|
||||
{ 1.28116E-02, 5.33047E-03, 6.51042E-01, 5.31902E-01, 1.95901E03, 1.18870E00, 5.98263E02, 9.54514E-03}
|
||||
,{ 3.11787E-01, 4.99529E-03, 1.18546E-01, 9.20917E-01, 9.84843E02, 1.08223E00, 5.54388E02, 5.05072E-02}
|
||||
,{ 6.44503E-01, 5.00368E-03, 8.66544E-01, 5.67488E-01, 9.62900E02, 1.01566E00, 1.62034E03, 2.37767E-02}
|
||||
,{ 9.53561E-01, 5.07406E-03, 1.30450E00, 5.90300E-01, 1.94512E03, 1.05703E00, 3.26951E02, 1.30441E-02}
|
||||
,{ 1.53151E00, 4.88520E-03, 2.56760E00, 4.23246E-01, 1.73888E03, 1.03208E00, 1.82942E03, 2.00331E-02}
|
||||
,{ 2.40289E00, 4.91497E-03, 2.49101E00, 4.14939E-01, 1.85836E03, 1.01581E00, 2.50417E03, 1.81984E-02}
|
||||
,{ 3.31007E00, 4.95744E-03, 5.40621E-01, 7.79940E-01, 1.10415E03, 9.67848E-01, 2.23535E03, 5.31612E-02}
|
||||
,{ 9.72706E-01, 5.00390E-03, 1.35102E00, 5.49800E-01, 1.25428E03, 9.68356E-01, 5.09320E03, 5.36453E-02}
|
||||
,{ 6.90408E-01, 4.62723E-03, 3.26749E-01, 1.10520E00, 1.30190E03, 9.43525E-01, 4.70373E01, 2.80245E-02}
|
||||
,{ 2.81235E-01, 4.59698E-03, 5.25630E-01, 8.78183E-01, 1.15830E03, 9.38564E-01, 1.01606E01, 4.14147E-02}
|
||||
,{ 2.15352E00, 4.40847E-03, 2.30923E00, 6.06001E-01, 1.33224E03, 9.43478E-01, 7.35116E02, 5.77231E-02}
|
||||
,{ 3.42983E00, 4.36897E-03, 2.39377E00, 5.54737E-01, 1.14029E03, 9.29844E-01, 2.10748E03, 7.89342E-02}
|
||||
,{ 3.89096E-02, 4.54168E-03, 4.27975E00, 4.78838E-01, 1.31642E03, 9.34106E-01, 5.65574E02, 5.27220E-02}
|
||||
,{ 1.33101E00, 4.43533E-03, 1.52262E00, 7.75843E-01, 1.22702E03, 9.14146E-01, 1.09117E03, 4.44972E-02}
|
||||
,{ 5.78119E00, 3.98281E-03, 3.24072E-01, 1.22769E00, 6.73459E02, 8.65731E-01, 1.23619E02, 1.82036E-01}
|
||||
,{ 6.11741E-01, 4.46376E-03, 3.38101E00, 5.42907E-01, 1.16067E03, 9.12049E-01, 1.40312E04, 8.77050E-02}
|
||||
,{ 1.15307E00, 4.47333E-03, 4.20464E00, 5.38231E-01, 1.30113E03, 9.02702E-01, 4.92301E03, 5.25717E-02}
|
||||
,{ 1.70408E00, 4.47609E-03, 2.75072E00, 5.83835E-01, 2.71393E03, 9.53183E-01, 2.03579E03, 1.46897E-02}
|
||||
,{ 2.60265E00, 4.32185E-03, 1.56811E00, 8.64656E-01, 5.56393E02, 8.44750E-01, 1.20010E02, 9.62648E-01}
|
||||
,{ 5.36555E-01, 4.40846E-03, 3.22706E00, 6.02927E-01, 5.00851E02, 8.33450E-01, 1.76639E03, 2.02699E00}
|
||||
,{ 1.71870E00, 4.36934E-03, 4.60285E00, 5.16212E-01, 1.60160E03, 9.14664E-01, 6.34168E03, 6.29243E-02}
|
||||
,{ 1.46403E-01, 4.84558E-03, 5.54014E00, 4.55903E-01, 1.76346E03, 9.19014E-01, 3.95193E03, 5.50341E-02}
|
||||
,{ 4.21238E00, 4.00130E-03, 3.79858E00, 4.82892E-01, 2.41697E03, 9.36204E-01, 7.73596E03, 2.89635E-02}
|
||||
,{ 6.97881E-01, 4.30794E-03, 2.28630E00, 7.84069E-01, 9.67872E02, 8.57874E-01, 1.78526E01, 1.11149E-01}
|
||||
,{ 5.92743E-01, 4.31334E-03, 1.40625E00, 9.68261E-01, 1.42642E03, 8.81488E-01, 1.44002E01, 4.24183E-02}
|
||||
,{ 2.83155E-02, 3.54506E-03, 5.64961E-01, 1.24111E00, 1.52781E03, 8.81848E-01, 2.59497E01, 3.54067E-02}
|
||||
,{ 2.69545E-01, 4.32088E-03, 2.24249E00, 7.64706E-01, 1.24391E03, 8.67051E-01, 2.34911E01, 6.04457E-02}
|
||||
,{ 3.68234E00, 4.37139E-03, 1.52146E00, 7.36656E-01, 1.47086E03, 8.74909E-01, 2.51685E02, 4.28115E-02}
|
||||
,{ 2.15403E00, 4.32278E-03, 2.69390E00, 5.23003E-01, 1.71727E03, 8.93617E-01, 2.09938E03, 5.25222E-02}
|
||||
,{ 5.31847E-01, 3.82833E-03, 6.75606E-01, 1.06647E00, 1.00848E03, 8.26099E-01, 3.58939E01, 4.19818E-02}
|
||||
,{ 6.91973E00, 4.01198E-03, 5.22284E-01, 9.74708E-01, 8.99033E02, 8.21636E-01, 3.71581E02, 7.38361E-02}
|
||||
,{ 1.80976E00, 4.48896E-03, 5.66120E00, 4.18493E-01, 1.55821E03, 8.70542E-01, 1.75605E03, 6.05859E-02}
|
||||
,{ 1.64641E00, 4.30255E-03, 5.12108E00, 5.16356E-01, 1.02024E03, 8.32723E-01, 2.20277E03, 8.46531E-02}
|
||||
,{ 4.07150E00, 4.29051E-03, 3.33803E00, 5.43517E-01, 2.60626E03, 9.03072E-01, 1.08974E03, 1.81133E-02}
|
||||
,{ 1.99798E00, 4.29503E-03, 3.23907E00, 5.93111E-01, 4.64572E03, 9.47444E-01, 6.40841E02, 9.69460E-03}
|
||||
,{ 5.08884E00, 4.25630E-03, 1.43000E00, 7.22156E-01, 7.08778E03, 9.79865E-01, 7.62818E02, 6.04351E-03}
|
||||
,{ 6.26370E-01, 4.13189E-03, 6.66229E-02, 2.65318E00, 1.07460E03, 8.14706E-01, 8.69523E00, 5.04427E-02}
|
||||
,{ 5.04987E00, 3.93427E-03, 4.95613E00, 5.27062E-01, 1.88617E03, 8.68672E-01, 4.81765E03, 3.49423E-02}
|
||||
,{ 1.17376E00, 4.21587E-03, 5.93823E00, 4.90520E-01, 1.55691E03, 8.49851E-01, 7.82193E03, 4.34207E-02}
|
||||
,{ 7.26083E00, 4.19413E-03, 5.93121E00, 4.47579E-01, 4.68769E03, 9.39722E-01, 2.44636E03, 1.01526E-02}
|
||||
,{ 3.51621E-01, 4.12551E-03, 1.33637E00, 1.28649E00, 1.49535E03, 8.50544E-01, 1.27864E01, 4.71084E-02}
|
||||
,{ 1.79112E-02, 4.17066E-03, 1.16601E00, 1.18837E00, 1.26027E03, 8.25733E-01, 1.29721E01, 4.82827E-02}
|
||||
,{ 3.72287E00, 4.17681E-03, 4.62860E00, 5.67689E-01, 1.67802E03, 8.62020E-01, 3.09395E03, 6.24402E-02}
|
||||
,{ 1.79112E-02, 4.17066E-03, 1.16601E00, 1.18837E00, 1.26027E03, 8.25733E-01, 1.29721E01, 4.82827E-02}
|
||||
,{ 3.07959E-01, 4.14183E-03, 5.45099E-01, 1.36766E00, 1.49906E03, 8.36456E-01, 2.65156E01, 3.82323E-02}
|
||||
,{ 8.13324E-01, 4.21976E-03, 5.48878E00, 6.21228E-01, 1.49147E03, 8.43298E-01, 1.70197E01, 6.33415E-02}
|
||||
,{ 2.89508E00, 4.20494E-03, 5.30021E00, 4.58632E-01, 1.38077E03, 8.35929E-01, 1.31565E04, 7.68200E-02}
|
||||
,{ 3.47169E00, 4.13440E-03, 3.23372E00, 6.37885E-01, 1.11636E03, 8.19589E-01, 4.76603E03, 1.17895E-01}
|
||||
,{ 2.28576E00, 4.22582E-03, 3.48478E00, 6.25713E-01, 8.04033E02, 7.95990E-01, 8.95357E03, 3.02479E-01}
|
||||
,{ 4.70915E00, 4.09414E-03, 3.88322E00, 5.82491E-01, 1.03140E03, 8.15544E-01, 1.33004E04, 1.67355E-01}
|
||||
,{ 7.35883E00, 4.38746E-03, 3.22730E00, 6.93616E-01, 1.36465E03, 8.32171E-01, 1.51236E03, 7.87703E-02}
|
||||
,{ 1.20379E00, 4.21476E-03, 4.65732E00, 6.15557E-01, 8.57568E02, 7.94208E-01, 5.81437E03, 2.55765E-01}
|
||||
,{ 4.21323E00, 4.20978E-03, 4.67533E00, 5.79451E-01, 3.50393E03, 8.92614E-01, 1.46887E03, 1.43590E-02}
|
||||
,{ 1.00615E01, 3.91035E-03, 3.64002E-01, 1.20347E00, 1.53997E03, 8.21892E-01, 1.42428E03, 4.02424E-02}
|
||||
,{ 3.73157E-01, 3.64035E-03, 2.26519E00, 1.15100E00, 1.67529E03, 8.37764E-01, 1.30656E01, 5.16993E-02}
|
||||
,{ 4.82483E00, 4.14578E-03, 6.09343E00, 5.70256E-01, 2.30011E03, 8.63588E-01, 2.98072E03, 3.86788E-02}
|
||||
,{ 5.74872E-01, 4.10857E-03, 2.76314E00, 8.78406E-01, 6.54727E02, 7.77081E-01, 4.60584E02, 9.63426E-01}
|
||||
,{ 3.27544E00, 4.21774E-03, 5.76803E00, 5.40540E-01, 6.63129E03, 9.42817E-01, 7.44066E02, 8.30259E-03}
|
||||
,{ 2.99783E00, 4.09014E-03, 4.52986E00, 6.20247E-01, 2.16115E03, 8.56688E-01, 1.26859E03, 4.30305E-02}
|
||||
,{ 3.02248E00, 4.10313E-03, 3.16182E00, 7.50444E-01, 6.87321E02, 7.65038E-01, 3.63380E02, 3.89438E-01}
|
||||
,{ 3.56550E00, 4.11367E-03, 6.01196E00, 5.21709E-01, 1.83002E03, 8.38996E-01, 3.66199E03, 5.75667E-02}
|
||||
,{ 3.64072E00, 4.17820E-03, 4.87424E00, 5.78614E-01, 1.26770E03, 8.22111E-01, 3.50817E03, 2.41737E-01}
|
||||
,{ 5.42525E-01, 4.12806E-03, 4.33656E00, 6.39323E-01, 1.10785E03, 7.88122E-01, 3.52321E02, 9.46601E-02}
|
||||
,{ 7.54702E00, 4.08134E-03, 4.92913E00, 5.07107E-01, 2.56583E03, 8.61877E-01, 3.29996E03, 3.12730E-02}
|
||||
,{ 4.43006E00, 4.19028E-03, 5.39210E00, 5.08608E-01, 3.60527E03, 8.85038E-01, 1.68786E03, 1.64866E-02}
|
||||
,{ 4.31706E00, 4.06269E-03, 3.55237E00, 5.72971E-01, 2.13874E03, 8.39174E-01, 3.20435E03, 2.94710E-02}
|
||||
,{ 2.73097E00, 4.02842E-03, 3.10590E00, 6.45438E-01, 1.80236E03, 8.20889E-01, 6.91941E02, 3.06839E-02}
|
||||
,{ 1.27982E00, 4.05535E-03, 4.63018E00, 5.73846E-01, 1.59512E03, 8.16419E-01, 1.06728E03, 5.52321E-02}
|
||||
,{ 5.75613E00, 4.04905E-03, 4.35700E00, 5.24956E-01, 2.20732E03, 8.37956E-01, 1.57951E03, 2.71650E-02}
|
||||
,{ 9.20610E00, 4.03636E-03, 3.37689E00, 5.72174E-01, 3.66035E03, 8.68034E-01, 1.19114E03, 9.53995E-03}
|
||||
,{ 8.23962E00, 4.04348E-03, 3.83028E00, 5.34511E-01, 4.35771E03, 8.82431E-01, 1.52426E03, 7.86437E-03}
|
||||
,{ 3.06189E00, 4.05111E-03, 3.58030E00, 5.90820E-01, 2.34610E03, 8.37132E-01, 1.22199E03, 2.00717E-02}
|
||||
,{ 7.99485E00, 3.29576E-03, 1.26335E00, 7.77934E-01, 1.80413E03, 8.12400E-01, 1.26630E03, 2.63526E-02}
|
||||
,{ 6.48326E00, 4.14609E-03, 7.76185E-01, 1.08393E00, 2.50557E02, 6.43106E-01, 1.77277E02, 8.98821E-01}
|
||||
,{ 6.20494E-01, 4.03017E-03, 2.53792E00, 6.77642E-01, 7.27918E02, 7.48340E-01, 1.17069E02, 2.01369E-01}
|
||||
,{ 5.51045E-01, 4.02571E-03, 2.70928E00, 6.83870E-01, 1.08946E03, 7.77755E-01, 1.08830E03, 8.10305E-02}
|
||||
,{ 1.26011E00, 4.04797E-03, 3.57127E00, 5.25416E-01, 2.61309E03, 8.53001E-01, 2.15571E03, 2.82139E-02}
|
||||
,{ 3.20857E00, 4.05101E-03, 3.66577E00, 5.36178E-01, 3.09116E03, 8.56024E-01, 1.50812E03, 1.54014E-02}
|
||||
,{ 1.04066E00, 4.05071E-03, 5.61035E00, 4.39133E-01, 3.64613E03, 8.69259E-01, 2.87840E03, 1.39437E-02}
|
||||
,{ 1.04586E00, 4.05038E-03, 5.38433E00, 4.45067E-01, 3.71715E03, 8.70310E-01, 2.90728E03, 1.32933E-02}
|
||||
,{ 3.15124E00, 4.05235E-03, 4.09956E00, 5.42499E-01, 3.24631E03, 8.57723E-01, 1.69177E03, 1.50581E-02}
|
||||
,{ 3.06995E00, 4.05334E-03, 6.62045E00, 4.52822E-01, 3.38058E03, 8.60267E-01, 2.63856E03, 1.53938E-02}
|
||||
,{ 3.84541E00, 4.06028E-03, 8.77920E00, 4.42301E-01, 2.72199E03, 8.43866E-01, 2.51315E03, 2.28962E-02}
|
||||
,{ 4.36117E00, 4.05648E-03, 8.18512E00, 4.36260E-01, 3.11358E03, 8.52235E-01, 3.00179E03, 1.72051E-02}
|
||||
,{ 4.36117E00, 4.05648E-03, 8.18512E00, 4.36260E-01, 3.11358E03, 8.52235E-01, 3.00179E03, 1.72051E-02}
|
||||
,{ 3.22200E00, 4.00409E-03, 5.90236E00, 5.26779E-01, 4.04015E03, 8.68037E-01, 1.65835E03, 1.17469E-02}
|
||||
,{ 9.34124E00, 3.96606E-03, 7.92099E00, 4.29769E-01, 5.18090E03, 8.87726E-01, 2.17316E03, 9.20070E-03}
|
||||
,{ 6.28686E00, 3.96735E-03, 5.81778E00, 5.35859E-01, 4.86643E03, 8.84427E-01, 2.25734E03, 1.05815E-02}
|
||||
,{ 5.92839E00, 3.96948E-03, 6.40824E00, 5.21225E-01, 4.61951E03, 8.80827E-01, 2.32352E03, 1.16274E-02}
|
||||
,{ 5.24536E00, 3.97440E-03, 6.79689E00, 4.85424E-01, 4.58631E03, 8.77944E-01, 2.48150E03, 1.12824E-02}
|
||||
,{ 2.77047E00, 3.98192E-03, 3.55107E00, 6.38231E-01, 2.51688E03, 8.29309E-01, 2.15559E03, 2.31207E-02}
|
||||
,{ 2.78483E00, 3.98116E-03, 3.32988E00, 6.47983E-01, 2.66277E03, 8.36780E-01, 2.33743E03, 2.40740E-02}
|
||||
|
||||
};
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4hSRIM2000p::G4hSRIM2000p():G4VhElectronicStoppingPower(),
|
||||
protonMassAMU(1.007276)
|
||||
{;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4hSRIM2000p::~G4hSRIM2000p()
|
||||
{;}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4hSRIM2000p::HasMaterial(const G4Material* material)
|
||||
{
|
||||
if(1 == (material->GetNumberOfElements())) return true;
|
||||
return false ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4hSRIM2000p::StoppingPower(const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
G4double ionloss = 0.0 ;
|
||||
|
||||
// pure material (normally not the case for this function)
|
||||
if(1 == (material->GetNumberOfElements())) {
|
||||
G4double z = material->GetZ() ;
|
||||
ionloss = ElectronicStoppingPower( z, kineticEnergy ) ;
|
||||
}
|
||||
|
||||
return ionloss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4hSRIM2000p::ElectronicStoppingPower(G4double z,
|
||||
G4double kineticEnergy) const
|
||||
{
|
||||
G4double ionloss ;
|
||||
G4int i = G4int(z) - 1 ; // index of atom
|
||||
if(i < 0) i = 0 ;
|
||||
if(i > 91) i = 91 ;
|
||||
|
||||
// Proton kinetic energy for parametrisation in Ziegler's units (keV/amu)
|
||||
|
||||
G4double T = kineticEnergy/(keV*protonMassAMU) ;
|
||||
|
||||
|
||||
|
||||
G4double e = T ;
|
||||
if ( T < 25.0 ) e = 25.0 ;
|
||||
|
||||
// universal approximation
|
||||
G4double slow = a[i][0] * pow(e, a[i][1]) + a[i][2] * pow(e, a[i][3]) ;
|
||||
G4double shigh = log( a[i][6]/e + a[i][7]*e ) * a[i][4] / pow(e, a[i][5]) ;
|
||||
ionloss = slow*shigh / (slow + shigh) ;
|
||||
|
||||
// low energy region
|
||||
if ( T < 25.0 ) {
|
||||
|
||||
G4double s = 0.45 ;
|
||||
// light elements
|
||||
if(6.5 > z) s = 0.25 ;
|
||||
// semiconductors
|
||||
if(5 == i || 13 == i || 31 == i) s = 0.375 ;
|
||||
|
||||
ionloss *= pow(T/25.0, s) ;
|
||||
}
|
||||
|
||||
if ( ionloss < 0.0) ionloss = 0.0 ;
|
||||
|
||||
return ionloss;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user