Import Geant4 10.7.0.beta source tree
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
//
|
||||
/*
|
||||
Authors:
|
||||
Updated 15 Novebmer 2019
|
||||
|
||||
M. Omer and R. Hajima on 17 October 2016
|
||||
contact:
|
||||
omer.mohamed@jaea.go.jp and hajima.ryoichi@qst.go.jp
|
||||
|
||||
@@ -25,6 +25,13 @@
|
||||
//
|
||||
/*
|
||||
Authors:
|
||||
|
||||
Updated 15 Novebmer 2019
|
||||
|
||||
Updates:
|
||||
1. Change reading method for cross section data.
|
||||
2. Add warning not to use with polarized photons.
|
||||
|
||||
M. Omer and R. Hajima on 17 October 2016
|
||||
contact:
|
||||
omer.mohamed@jaea.go.jp and hajima.ryoichi@qst.go.jp
|
||||
@@ -47,10 +54,8 @@ using namespace std;
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4JAEAElasticScatteringModel::maxZ = 99;
|
||||
G4LPhysicsFreeVector* G4JAEAElasticScatteringModel::dataCS[] ;
|
||||
//Initialising an array to hold all elastic scattering data.
|
||||
G4double Diff_CS_data[100][183][300];
|
||||
G4LPhysicsFreeVector* G4JAEAElasticScatteringModel::dataCS[]={nullptr} ;
|
||||
G4DataVector* G4JAEAElasticScatteringModel::ES_Data[]={nullptr};
|
||||
|
||||
G4JAEAElasticScatteringModel::G4JAEAElasticScatteringModel()
|
||||
:G4VEmModel("G4JAEAElasticScatteringModel"),isInitialised(false)
|
||||
@@ -77,10 +82,14 @@ G4JAEAElasticScatteringModel::G4JAEAElasticScatteringModel()
|
||||
G4JAEAElasticScatteringModel::~G4JAEAElasticScatteringModel()
|
||||
{
|
||||
if(IsMaster()) {
|
||||
for(G4int i=0; i<maxZ; ++i) {
|
||||
for(G4int i=0; i<=maxZ; ++i) {
|
||||
if(dataCS[i]) {
|
||||
delete dataCS[i];
|
||||
dataCS[i] = 0;
|
||||
dataCS[i] = nullptr;
|
||||
}
|
||||
if (ES_Data[i]){
|
||||
delete ES_Data[i];
|
||||
ES_Data[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,18 +183,19 @@ void G4JAEAElasticScatteringModel::ReadData(size_t Z, const char* path)
|
||||
The first row is the energy, and the second row is the total cross section.
|
||||
Rows from the 3rd to the 183rd are the differential cross section with an angular resolution of 1 degree.
|
||||
*/
|
||||
G4double ESdata[183][300];
|
||||
|
||||
|
||||
std::ostringstream ostCS;
|
||||
ostCS << datadir << "/JAEAESData/cs_Z_" << Z <<".dat";
|
||||
std::ifstream alldata(ostCS.str().c_str());
|
||||
if(!alldata.is_open())
|
||||
ostCS << datadir << "/JAEAESData/amp_Z_" << Z ;
|
||||
std::ifstream ES_Data_Buffer(ostCS.str().c_str(),ios::binary);
|
||||
if( !ES_Data_Buffer.is_open() )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4JAEAElasticScattering Model data file <" << ostCS.str().c_str()
|
||||
ed << "G4JAEAElasticScattertingModel data file <" << ostCS.str().c_str()
|
||||
<< "> is not opened!" << G4endl;
|
||||
G4Exception("Elastic Scattering::ReadData()","em0003",FatalException,
|
||||
ed,"G4LEDATA version should be G4EMLOW6.27 or later. Elastic Scattering Data are not loaded");
|
||||
G4Exception("G4JAEAElasticScatteringModel::ReadData()","em0003",FatalException,
|
||||
ed,
|
||||
"G4LEDATA version should be G4EMLOW7.11 or later. Elastic Scattering Data are not loaded");
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -195,19 +205,18 @@ else
|
||||
<< " is opened by G4JAEAElasticScatteringModel" << G4endl;
|
||||
}
|
||||
}
|
||||
while (!alldata.eof())
|
||||
if (!ES_Data[Z])
|
||||
ES_Data[Z] = new G4DataVector();
|
||||
|
||||
|
||||
G4float buffer_var;
|
||||
while (ES_Data_Buffer.read(reinterpret_cast<char*>(&buffer_var),sizeof(float)))
|
||||
{
|
||||
for (int i=0; i<183;i++)
|
||||
{
|
||||
for (int j=0; j<300; j++)
|
||||
{
|
||||
alldata >> ESdata[i][j];
|
||||
Diff_CS_data[Z][i][j]=ESdata[i][j];
|
||||
}
|
||||
}
|
||||
if (!alldata) break;
|
||||
ES_Data[Z]->push_back(buffer_var);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Writing the total cross section data to a G4LPhysicsFreeVector.
|
||||
This provides an interpolation of the Energy-Total Cross Section data.
|
||||
@@ -215,14 +224,14 @@ This provides an interpolation of the Energy-Total Cross Section data.
|
||||
|
||||
dataCS[Z] = new G4LPhysicsFreeVector(300,0.01,3.);
|
||||
//Note that the total cross section and energy are converted to the internal units.
|
||||
for (int i=0;i<300;i++)
|
||||
dataCS[Z]->PutValue(i,Diff_CS_data[Z][0][i]*1e-3,Diff_CS_data[Z][1][i]*1e-22);
|
||||
|
||||
// Activation of spline interpolation
|
||||
dataCS[Z] ->SetSpline(true);
|
||||
for (G4int i=0;i<300;++i)
|
||||
dataCS[Z]->PutValue(i,10.*i*1e-3,ES_Data[Z]->at(i)*1e-22);
|
||||
|
||||
// Activation of spline interpolation
|
||||
dataCS[Z] ->SetSpline(true);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -234,7 +243,7 @@ G4double G4JAEAElasticScatteringModel::ComputeCrossSectionPerAtom(
|
||||
G4double, G4double)
|
||||
{
|
||||
|
||||
if (verboseLevel > 1)
|
||||
if (verboseLevel > 2)
|
||||
{
|
||||
G4cout << "G4JAEAElasticScatteringModel::ComputeCrossSectionPerAtom()"
|
||||
<< G4endl;
|
||||
@@ -291,10 +300,11 @@ void G4JAEAElasticScatteringModel::SampleSecondaries(
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double, G4double)
|
||||
{
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "Calling SampleSecondaries() of G4JAEAElasticScatteringModel"
|
||||
if (verboseLevel > 2) {
|
||||
G4cout << "Calling SampleSecondaries() of G4JAEAElasticScatteringModel."
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
|
||||
// Absorption of low-energy gamma
|
||||
@@ -303,46 +313,64 @@ void G4JAEAElasticScatteringModel::SampleSecondaries(
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeLocalEnergyDeposit(photonEnergy0);
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Warning if the incoming photon has polarization
|
||||
|
||||
G4double Xi1=0, Xi2=0, Xi3=0;
|
||||
G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
Xi1=gammaPolarization0.x();
|
||||
Xi2=gammaPolarization0.y();
|
||||
Xi3=gammaPolarization0.z();
|
||||
|
||||
G4double polarization_magnitude=Xi1*Xi1+Xi2*Xi2+Xi3*Xi3;
|
||||
if ((polarization_magnitude)>0 || (Xi1*Xi1>0) || (Xi2*Xi2>0) || (Xi3*Xi3>0))
|
||||
{
|
||||
G4cout<<"WARNING: G4JAEAElasticScatteringModel is only compatible with non-polarized photons."<<G4endl;
|
||||
G4cout<<"The event is ignored."<<G4endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Select randomly one element in the current material
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* elm = SelectRandomAtom(couple,particle,photonEnergy0);
|
||||
G4int Z = G4lrint(elm->GetZ());
|
||||
|
||||
|
||||
//Select the angular distribution depending on the photon energy
|
||||
G4double *whichdistribution = lower_bound(Diff_CS_data[Z][0],Diff_CS_data[Z][0]+300,photonEnergy0*1000.);
|
||||
int index = max(0,(int)(whichdistribution-Diff_CS_data[Z][0]-1));
|
||||
|
||||
//Rounding up to half the energy-grid separation (5 keV)
|
||||
if (photonEnergy0*1000>=0.5*(Diff_CS_data[Z][0][index]+Diff_CS_data[Z][0][index+1]))
|
||||
index++;
|
||||
G4int energyindex=round(100*photonEnergy0)-1;
|
||||
/*
|
||||
Getting the normalized probablity distrbution function and
|
||||
normalization factor to create the probability distribution function
|
||||
*/
|
||||
G4double normdist=0;
|
||||
for (int i=0;i<=180;i++)
|
||||
{
|
||||
distribution[i]=Diff_CS_data[Z][i+2][index];
|
||||
normdist = normdist + distribution[i];
|
||||
}
|
||||
G4double a1=0, a2=0, a3=0,a4=0;
|
||||
G4double normdist=0;
|
||||
for (G4int i=0;i<=180;++i)
|
||||
{
|
||||
a1=ES_Data[Z]->at(4*i+300+181*4*(energyindex));
|
||||
a2=ES_Data[Z]->at(4*i+1+300+181*4*(energyindex));
|
||||
a3=ES_Data[Z]->at(4*i+2+300+181*4*(energyindex));
|
||||
a4=ES_Data[Z]->at(4*i+3+300+181*4*(energyindex));
|
||||
distribution[i]=a1*a1+a2*a2+a3*a3+a4*a4;
|
||||
normdist += distribution[i];
|
||||
}
|
||||
|
||||
|
||||
//Create the cummulative distribution function (cdf)
|
||||
for (int i =0;i<=180;i++) pdf[i]=distribution[i]/normdist;
|
||||
for (G4int i =0;i<=180;++i)
|
||||
pdf[i]=distribution[i]/normdist;
|
||||
cdf[0]=0;
|
||||
G4double cdfsum =0;
|
||||
for (int i=0; i<=180;i++)
|
||||
{
|
||||
cdfsum=cdfsum+pdf[i];
|
||||
cdf[i]=cdfsum;
|
||||
}
|
||||
//Sampling the polar angle by inverse transform uing cdf.
|
||||
for (G4int i=0; i<=180;++i)
|
||||
{
|
||||
cdfsum=cdfsum+pdf[i];
|
||||
cdf[i]=cdfsum;
|
||||
}
|
||||
//Sampling the polar angle by inverse transform uing cdf.
|
||||
G4double r = G4UniformRand();
|
||||
G4double *cdfptr=lower_bound(cdf,cdf+181,r);
|
||||
int cdfindex = (int)(cdfptr-cdf-1);
|
||||
G4int cdfindex = (G4int)(cdfptr-cdf-1);
|
||||
G4double cdfinv = (r-cdf[cdfindex])/(cdf[cdfindex+1]-cdf[cdfindex]);
|
||||
G4double theta = (cdfindex+cdfinv)/180.;
|
||||
//polar is now ready
|
||||
|
||||
+604
@@ -0,0 +1,604 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
/*/
|
||||
Authors:
|
||||
M. Omer and R. Hajima on 15 November 2019
|
||||
contact:
|
||||
omer.mohamed@jaea.go.jp and hajima.ryoichi@qst.go.jp
|
||||
Publication Information:
|
||||
1- M. Omer, R. Hajima, Validating polarization effects in gamma-rays elastic scattering by Monte
|
||||
Carlo simulation, New J. Phys., vol. 21, 2019, pp. 113006 (1-10),
|
||||
https://doi.org/10.1088/1367-2630/ab4d8a
|
||||
*/
|
||||
|
||||
#include "G4JAEAPolarizedElasticScatteringModel.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LPhysicsFreeVector* G4JAEAPolarizedElasticScatteringModel::dataCS[] = {nullptr};
|
||||
G4DataVector* G4JAEAPolarizedElasticScatteringModel::Polarized_ES_Data[] = {nullptr};
|
||||
|
||||
G4JAEAPolarizedElasticScatteringModel::G4JAEAPolarizedElasticScatteringModel()
|
||||
:G4VEmModel("G4JAEAPolarizedElasticScatteringModel"),isInitialised(false)
|
||||
{
|
||||
fParticleChange = 0;
|
||||
lowEnergyLimit = 100 * keV; //low energy limit for JAEAElasticScattering cross section data
|
||||
fLinearPolarizationSensitvity1=1;
|
||||
fLinearPolarizationSensitvity2=1;
|
||||
fCircularPolarizationSensitvity=1;
|
||||
|
||||
verboseLevel= 0;
|
||||
// Verbosity scale for debugging purposes:
|
||||
// 0 = nothing
|
||||
// 1 = calculation of cross sections, file openings...
|
||||
// 2 = entering in methods
|
||||
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4JAEAPolarizedElasticScatteringModel is constructed " << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4JAEAPolarizedElasticScatteringModel::~G4JAEAPolarizedElasticScatteringModel()
|
||||
{
|
||||
if(IsMaster()) {
|
||||
for(G4int i=0; i<=maxZ; ++i) {
|
||||
if(dataCS[i]) {
|
||||
delete dataCS[i];
|
||||
dataCS[i] = nullptr;
|
||||
}
|
||||
if (Polarized_ES_Data[i]){
|
||||
delete Polarized_ES_Data[i];
|
||||
Polarized_ES_Data[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4JAEAPolarizedElasticScatteringModel::Initialise(const G4ParticleDefinition* particle,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "Calling Initialise() of G4JAEAPolarizedElasticScatteringModel." << G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / eV << " eV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(IsMaster()) {
|
||||
|
||||
// Initialise element selector
|
||||
InitialiseElementSelectors(particle, cuts);
|
||||
|
||||
// Access to elements
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
G4ProductionCutsTable* theCoupleTable =
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
for(G4int i=0; i<numOfCouples; ++i)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple =
|
||||
theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
G4int nelm = material->GetNumberOfElements();
|
||||
|
||||
for (G4int j=0; j<nelm; ++j)
|
||||
{
|
||||
G4int Z = G4lrint((*theElementVector)[j]->GetZ());
|
||||
if(Z < 1) { Z = 1; }
|
||||
else if(Z > maxZ) { Z = maxZ; }
|
||||
if( (!dataCS[Z]) ) { ReadData(Z, path); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isInitialised) { return; }
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
isInitialised = true;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4JAEAPolarizedElasticScatteringModel::InitialiseLocal(const G4ParticleDefinition*,
|
||||
G4VEmModel* masterModel)
|
||||
{
|
||||
SetElementSelectors(masterModel->GetElementSelectors());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4JAEAPolarizedElasticScatteringModel::ReadData(size_t Z, const char* path)
|
||||
{
|
||||
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "Calling ReadData() of G4JAEAPolarizedElasticScatteringModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(dataCS[Z]) { return; }
|
||||
|
||||
const char* datadir = path;
|
||||
|
||||
if(!datadir)
|
||||
{
|
||||
datadir = std::getenv("G4LEDATA");
|
||||
if(!datadir)
|
||||
{
|
||||
G4Exception("G4JAEAPolarizedElasticScatteringModel::ReadData()","em0006",
|
||||
FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::ostringstream ostCS;
|
||||
ostCS << datadir << "/JAEAESData/amp_Z_" << Z ;
|
||||
std::ifstream ES_Data_Buffer(ostCS.str().c_str(),ios::binary);
|
||||
if( !ES_Data_Buffer.is_open() )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4JAEAPolarizedElasticScattering Model data file <" << ostCS.str().c_str()
|
||||
<< "> is not opened!" << G4endl;
|
||||
G4Exception("G4JAEAPolarizedElasticScatteringModel::ReadData()","em0003",FatalException,
|
||||
ed,"G4LEDATA version should be G4EMLOW7.11 or later. Polarized Elastic Scattering Data are not loaded");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(verboseLevel > 3) {
|
||||
G4cout << "File " << ostCS.str()
|
||||
<< " is opened by G4JAEAPolarizedElasticScatteringModel" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!Polarized_ES_Data[Z])
|
||||
Polarized_ES_Data[Z] = new G4DataVector();
|
||||
|
||||
G4float buffer_var;
|
||||
while (ES_Data_Buffer.read(reinterpret_cast<char*>(&buffer_var),sizeof(float)))
|
||||
{
|
||||
Polarized_ES_Data[Z]->push_back(buffer_var);
|
||||
}
|
||||
|
||||
dataCS[Z] = new G4LPhysicsFreeVector(300,0.01,3.);
|
||||
|
||||
for (G4int i=0;i<300;++i)
|
||||
dataCS[Z]->PutValue(i,10.*i*1e-3,Polarized_ES_Data[Z]->at(i)*1e-22);
|
||||
|
||||
|
||||
// Activation of spline interpolation
|
||||
dataCS[Z] ->SetSpline(true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4JAEAPolarizedElasticScatteringModel::ComputeCrossSectionPerAtom(
|
||||
const G4ParticleDefinition*,
|
||||
G4double GammaEnergy,
|
||||
G4double Z, G4double,
|
||||
G4double, G4double)
|
||||
{
|
||||
|
||||
|
||||
//Select the energy-grid point closest to the photon energy
|
||||
// G4double *whichenergy = lower_bound(ESdata[0],ESdata[0]+300,GammaEnergy);
|
||||
// int energyindex = max(0,(int)(whichenergy-ESdata[0]-1));
|
||||
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "G4JAEAPolarizedElasticScatteringModel::ComputeCrossSectionPerAtom()"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(GammaEnergy < lowEnergyLimit) { return 0.0; }
|
||||
|
||||
G4double xs = 0.0;
|
||||
|
||||
G4int intZ = G4lrint(Z);
|
||||
|
||||
if(intZ < 1 || intZ > maxZ) { return xs; }
|
||||
|
||||
G4LPhysicsFreeVector* pv = dataCS[intZ];
|
||||
|
||||
// if element was not initialised
|
||||
// do initialisation safely for MT mode
|
||||
if(!pv) {
|
||||
InitialiseForElement(0, intZ);
|
||||
pv = dataCS[intZ];
|
||||
if(!pv) { return xs; }
|
||||
}
|
||||
|
||||
G4int n = pv->GetVectorLength() - 1;
|
||||
|
||||
G4double e = GammaEnergy;
|
||||
if(e >= pv->Energy(n)) {
|
||||
xs = (*pv)[n];
|
||||
} else if(e >= pv->Energy(0)) {
|
||||
xs = pv->Value(e);
|
||||
}
|
||||
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "****** DEBUG: tcs value for Z=" << Z << " at energy (MeV)="
|
||||
<< e << G4endl;
|
||||
G4cout << " cs (Geant4 internal unit)=" << xs << G4endl;
|
||||
G4cout << " -> first E*E*cs value in CS data file (iu) =" << (*pv)[0]
|
||||
<< G4endl;
|
||||
G4cout << " -> last E*E*cs value in CS data file (iu) =" << (*pv)[n]
|
||||
<< G4endl;
|
||||
G4cout << "*********************************************************"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
return (xs);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4JAEAPolarizedElasticScatteringModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>*,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double, G4double)
|
||||
{
|
||||
if (verboseLevel > 1) {
|
||||
|
||||
G4cout << "Calling SampleSecondaries() of G4JAEAPolarizedElasticScatteringModel."
|
||||
<< G4endl;
|
||||
}
|
||||
G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
|
||||
// absorption of low-energy gamma
|
||||
if (photonEnergy0 <= lowEnergyLimit)
|
||||
{
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeLocalEnergyDeposit(photonEnergy0);
|
||||
return ;
|
||||
}
|
||||
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* elm = SelectRandomAtom(couple,particle,photonEnergy0);
|
||||
G4int Z = G4lrint(elm->GetZ());
|
||||
|
||||
|
||||
//Getting the corresponding distrbution
|
||||
G4int energyindex=round(100*photonEnergy0)-1;
|
||||
//G4cout<<"Rounding Photon Energy for element Z = "<<Z<<G4endl;
|
||||
//G4cout<<photonEnergy0<<" "<<" "<<round(1000*photonEnergy0)<<" "<<energyindex<<G4endl;
|
||||
G4double a1=0, a2=0, a3=0,a4=0;
|
||||
for (G4int i=0;i<=180;++i)
|
||||
{
|
||||
a1=Polarized_ES_Data[Z]->at(4*i+300+181*4*(energyindex));
|
||||
a2=Polarized_ES_Data[Z]->at(4*i+1+300+181*4*(energyindex));
|
||||
a3=Polarized_ES_Data[Z]->at(4*i+2+300+181*4*(energyindex));
|
||||
a4=Polarized_ES_Data[Z]->at(4*i+3+300+181*4*(energyindex));
|
||||
distribution[i]=a1*a1+a2*a2+a3*a3+a4*a4;
|
||||
}
|
||||
|
||||
CLHEP::RandGeneral GenThetaDist(distribution,180);
|
||||
//Intial sampling of the scattering angle. To be updated for the circular polarization
|
||||
G4double theta = CLHEP::pi*GenThetaDist.shoot();
|
||||
//G4double theta =45.*CLHEP::pi/180.;
|
||||
//Theta is in degree to call scattering amplitudes
|
||||
G4int theta_in_degree =round(theta*180./CLHEP::pi);
|
||||
|
||||
//theta_in_degree=45;
|
||||
|
||||
G4double am1=0,am2=0,am3=0,am4=0,aparaSquare=0,aperpSquare=0,apara_aper_Asterisk=0,img_apara_aper_Asterisk=0;
|
||||
am1=Polarized_ES_Data[Z]->at(4*theta_in_degree+300+181*4*(energyindex));
|
||||
am2=Polarized_ES_Data[Z]->at(4*theta_in_degree+1+300+181*4*(energyindex));
|
||||
am3=Polarized_ES_Data[Z]->at(4*theta_in_degree+2+300+181*4*(energyindex));
|
||||
am4=Polarized_ES_Data[Z]->at(4*theta_in_degree+3+300+181*4*(energyindex));
|
||||
aparaSquare=am1*am1+am2*am2;
|
||||
aperpSquare=am3*am3+am4*am4;
|
||||
apara_aper_Asterisk=2*a1*a3+2*a2*a4;
|
||||
img_apara_aper_Asterisk=2*a1*a4-2*a2*a3;
|
||||
|
||||
G4ThreeVector Direction_Unpolarized(0.,0.,0.);
|
||||
G4ThreeVector Direction_Linear1(0.,0.,0.);
|
||||
G4ThreeVector Direction_Linear2(0.,0.,0.);
|
||||
G4ThreeVector Direction_Circular(0.,0.,0.);
|
||||
G4ThreeVector Polarization_Unpolarized(0.,0.,0.);
|
||||
G4ThreeVector Polarization_Linear1(0.,0.,0.);
|
||||
G4ThreeVector Polarization_Linear2(0.,0.,0.);
|
||||
G4ThreeVector Polarization_Circular(0.,0.,0.);
|
||||
|
||||
|
||||
//Stokes parameters for the incoming and outgoing photon
|
||||
G4double Xi1=0, Xi2=0, Xi3=0, Xi1_Prime=0,Xi2_Prime=0,Xi3_Prime=0;
|
||||
|
||||
//Getting the Stokes parameters for the incoming photon
|
||||
G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
Xi1=gammaPolarization0.x();
|
||||
Xi2=gammaPolarization0.y();
|
||||
Xi3=gammaPolarization0.z();
|
||||
|
||||
//Polarization vector must be unit vector
|
||||
G4double polarization_magnitude=Xi1*Xi1+Xi2*Xi2+Xi3*Xi3;
|
||||
if ((polarization_magnitude)>1 || (Xi1*Xi1>1) || (Xi2*Xi2>1) || (Xi3*Xi3>1))
|
||||
{
|
||||
G4cout<<"WARNING: G4JAEAPolarizedElasticScatteringModel is only compatible with a unit polarization vector."<<G4endl;
|
||||
G4cout<<"The event is ignored."<<G4endl;
|
||||
return;
|
||||
}
|
||||
//Unpolarized gamma rays
|
||||
if (Xi1==0 && Xi2==0 && Xi3==0)
|
||||
{
|
||||
G4double Phi_Unpolarized=0;
|
||||
if (fLinearPolarizationSensitvity1)
|
||||
Phi_Unpolarized=GeneratePolarizedPhi(aparaSquare,aperpSquare,0.);
|
||||
else
|
||||
Phi_Unpolarized=CLHEP::twopi*G4UniformRand();
|
||||
Direction_Unpolarized.setX(sin(theta)*cos(Phi_Unpolarized));
|
||||
Direction_Unpolarized.setY(sin(theta)*sin(Phi_Unpolarized));
|
||||
Direction_Unpolarized.setZ(cos(theta));
|
||||
Direction_Unpolarized.rotateUz(aDynamicGamma->GetMomentumDirection());
|
||||
Xi1_Prime=(aparaSquare-aperpSquare)/(aparaSquare+aperpSquare);
|
||||
Polarization_Unpolarized.setX(Xi1_Prime);
|
||||
Polarization_Unpolarized.setY(0.);
|
||||
Polarization_Unpolarized.setZ(0.);
|
||||
fParticleChange->ProposeMomentumDirection(Direction_Unpolarized);
|
||||
fParticleChange->ProposePolarization(Polarization_Unpolarized);
|
||||
return;
|
||||
}
|
||||
|
||||
//Linear polarization defined by first Stokes parameter
|
||||
G4double InitialAzimuth=aDynamicGamma->GetMomentumDirection().phi();
|
||||
if(InitialAzimuth<0) InitialAzimuth=InitialAzimuth+CLHEP::twopi;
|
||||
|
||||
G4double Phi_Linear1=0.;
|
||||
|
||||
Phi_Linear1 = GeneratePolarizedPhi(aparaSquare+aperpSquare+Xi1*(aparaSquare-aperpSquare),
|
||||
aparaSquare+aperpSquare-Xi1*(aparaSquare-aperpSquare),InitialAzimuth);
|
||||
|
||||
Xi1_Prime=((aparaSquare-aperpSquare)+Xi1*(aparaSquare+aperpSquare)*cos(2*Phi_Linear1))/
|
||||
((aparaSquare+aperpSquare)+Xi1*(aparaSquare-aperpSquare)*cos(2*Phi_Linear1));
|
||||
Xi2_Prime=(-Xi1*apara_aper_Asterisk*sin(2*Phi_Linear1))/
|
||||
((aparaSquare+aperpSquare)+Xi1*(aparaSquare-aperpSquare)*cos(2*Phi_Linear1));
|
||||
Xi3_Prime=(-Xi1*img_apara_aper_Asterisk*sin(2*Phi_Linear1))/
|
||||
((aparaSquare+aperpSquare)+Xi1*(aparaSquare-aperpSquare)*cos(2*Phi_Linear1));
|
||||
//Store momentum direction and po;arization
|
||||
Direction_Linear1.setX(sin(theta)*cos(Phi_Linear1));
|
||||
Direction_Linear1.setY(sin(theta)*sin(Phi_Linear1));
|
||||
Direction_Linear1.setZ(cos(theta));
|
||||
Polarization_Linear1.setX(Xi1_Prime);
|
||||
Polarization_Linear1.setY(Xi2_Prime);
|
||||
Polarization_Linear1.setZ(Xi3_Prime);
|
||||
|
||||
//Set scattered photon polarization sensitivity
|
||||
Xi1_Prime=Xi1_Prime*fLinearPolarizationSensitvity1;
|
||||
Xi2_Prime=Xi2_Prime*fLinearPolarizationSensitvity2;
|
||||
Xi3_Prime=Xi3_Prime*fCircularPolarizationSensitvity;
|
||||
|
||||
G4double dsigmaL1=0.0;
|
||||
if(abs(Xi1)>0.0) dsigmaL1=0.25*((aparaSquare+aperpSquare)*(1+Xi1*Xi1_Prime*cos(2*Phi_Linear1))+(aparaSquare-aperpSquare)*(Xi1*cos(2*Phi_Linear1)+Xi1_Prime)
|
||||
-Xi1*Xi2_Prime*apara_aper_Asterisk*sin(2*Phi_Linear1)-Xi1*Xi3_Prime*img_apara_aper_Asterisk*sin(2*Phi_Linear1));
|
||||
|
||||
//Linear polarization defined by second Stokes parameter
|
||||
//G4double IntialAzimuth=aDynamicGamma->GetMomentumDirection().phi();
|
||||
|
||||
G4double Phi_Linear2=0.;
|
||||
|
||||
InitialAzimuth=InitialAzimuth-CLHEP::pi/4.;
|
||||
if(InitialAzimuth<0) InitialAzimuth=InitialAzimuth+CLHEP::twopi;
|
||||
|
||||
Phi_Linear2 = GeneratePolarizedPhi(aparaSquare+aperpSquare+Xi1*(aparaSquare-aperpSquare)
|
||||
,aparaSquare+aperpSquare-Xi1*(aparaSquare-aperpSquare),InitialAzimuth);
|
||||
|
||||
Xi1_Prime=((aparaSquare-aperpSquare)+Xi2*(aparaSquare+aperpSquare)*sin(2*Phi_Linear2))/
|
||||
((aparaSquare+aperpSquare)+Xi2*(aparaSquare-aperpSquare)*sin(2*Phi_Linear2));
|
||||
Xi2_Prime=(Xi2*apara_aper_Asterisk*cos(2*Phi_Linear2))/
|
||||
((aparaSquare+aperpSquare)+Xi2*(aparaSquare-aperpSquare)*sin(2*Phi_Linear2));
|
||||
Xi3_Prime=(Xi2*img_apara_aper_Asterisk*cos(2*Phi_Linear2))/
|
||||
((aparaSquare+aperpSquare)+Xi2*(aparaSquare-aperpSquare)*sin(2*Phi_Linear2));
|
||||
//Store momentum direction and polarization
|
||||
Direction_Linear2.setX(sin(theta)*cos(Phi_Linear2));
|
||||
Direction_Linear2.setY(sin(theta)*sin(Phi_Linear2));
|
||||
Direction_Linear2.setZ(cos(theta));
|
||||
Polarization_Linear2.setX(Xi1_Prime);
|
||||
Polarization_Linear2.setY(Xi2_Prime);
|
||||
Polarization_Linear2.setZ(Xi3_Prime);
|
||||
|
||||
//Set scattered photon polarization sensitivity
|
||||
Xi1_Prime=Xi1_Prime*fLinearPolarizationSensitvity1;
|
||||
Xi2_Prime=Xi2_Prime*fLinearPolarizationSensitvity2;
|
||||
Xi3_Prime=Xi3_Prime*fCircularPolarizationSensitvity;
|
||||
|
||||
G4double dsigmaL2=0.0;
|
||||
if(abs(Xi2)>0.0)
|
||||
dsigmaL2=0.25*((aparaSquare+aperpSquare)*(1+Xi2*Xi1_Prime*sin(2*Phi_Linear2))+(aparaSquare-aperpSquare)*(Xi2*sin(2*Phi_Linear2)+Xi1_Prime)
|
||||
+Xi2*Xi2_Prime*apara_aper_Asterisk*cos(2*Phi_Linear2)-Xi2*Xi3_Prime*img_apara_aper_Asterisk*cos(2*Phi_Linear2));
|
||||
|
||||
|
||||
//Circular polarization
|
||||
G4double Phi_Circular = CLHEP::twopi*G4UniformRand();
|
||||
G4double Theta_Circular = 0;
|
||||
|
||||
Xi1_Prime=(aparaSquare-aperpSquare)/(aparaSquare+aperpSquare);
|
||||
Xi2_Prime=(-Xi3*img_apara_aper_Asterisk)/(aparaSquare+aperpSquare);
|
||||
Xi3_Prime=(Xi3*apara_aper_Asterisk)/(aparaSquare+aperpSquare);
|
||||
|
||||
Polarization_Circular.setX(Xi1_Prime);
|
||||
Polarization_Circular.setY(Xi2_Prime);
|
||||
Polarization_Circular.setZ(Xi3_Prime);
|
||||
|
||||
//Set scattered photon polarization sensitivity
|
||||
Xi1_Prime=Xi1_Prime*fLinearPolarizationSensitvity1;
|
||||
Xi2_Prime=Xi2_Prime*fLinearPolarizationSensitvity2;
|
||||
Xi3_Prime=Xi3_Prime*fCircularPolarizationSensitvity;
|
||||
|
||||
G4double dsigmaC=0.0;
|
||||
if(abs(Xi3)>0.0)
|
||||
dsigmaC=0.25*(aparaSquare+aperpSquare+Xi1_Prime*(aparaSquare-aperpSquare)-Xi3*Xi2_Prime*img_apara_aper_Asterisk
|
||||
+Xi3*Xi3_Prime*apara_aper_Asterisk);
|
||||
|
||||
if (abs(Xi3)==0.0 && abs(Xi1_Prime)==0.0)
|
||||
{
|
||||
Direction_Circular.setX(sin(theta)*cos(Phi_Circular));
|
||||
Direction_Circular.setY(sin(theta)*sin(Phi_Circular));
|
||||
Direction_Circular.setZ(cos(theta));
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double c1=0, c2=0, c3=0,c4=0;
|
||||
for (G4int i=0;i<=180;++i)
|
||||
{
|
||||
c1=Polarized_ES_Data[Z]->at(4*i+300+181*4*(energyindex));
|
||||
c2=Polarized_ES_Data[Z]->at(4*i+1+300+181*4*(energyindex));
|
||||
c3=Polarized_ES_Data[Z]->at(4*i+2+300+181*4*(energyindex));
|
||||
c4=Polarized_ES_Data[Z]->at(4*i+3+300+181*4*(energyindex));
|
||||
cdistribution[i]=0.25*((c1*c1+c2*c2+c3*c3+c4*c4)+Xi1_Prime*(c1*c1+c2*c2-c3*c3-c4*c4)-Xi3*Xi2_Prime*(2*c1*c4-2*c2*c3)
|
||||
+Xi3*Xi3_Prime*(2*c1*c4-2*c2*c3));
|
||||
}
|
||||
CLHEP::RandGeneral GenTheta_Circ_Dist(cdistribution,180);
|
||||
Theta_Circular=CLHEP::pi*GenTheta_Circ_Dist.shoot();
|
||||
Direction_Circular.setX(sin(Theta_Circular)*cos(Phi_Circular));
|
||||
Direction_Circular.setY(sin(Theta_Circular)*sin(Phi_Circular));
|
||||
Direction_Circular.setZ(cos(Theta_Circular));
|
||||
}
|
||||
|
||||
// Sampling scattered photon direction based on asymmetry arising from polarization mixing
|
||||
G4double totalSigma= dsigmaL1+dsigmaL2+dsigmaC;
|
||||
G4double prob1=dsigmaL1/totalSigma;
|
||||
G4double prob2=dsigmaL2/totalSigma;
|
||||
G4double probc=1-(prob1+prob2);
|
||||
|
||||
//Check the Probability of polarization mixing
|
||||
if (abs(probc - dsigmaC)>=0.0001)
|
||||
{
|
||||
G4cout<<"WARNING: Polarization mixing might be incorrect."<<G4endl;
|
||||
}
|
||||
|
||||
// Generate outgoing photon direction
|
||||
G4ThreeVector finaldirection(0.0,0.0,0.0);
|
||||
G4ThreeVector outcomingPhotonPolarization(0.0,0.0,0.0);
|
||||
|
||||
//Polarization mixing
|
||||
G4double polmix=G4UniformRand();
|
||||
if (polmix<=prob1)
|
||||
{
|
||||
finaldirection.setX(Direction_Linear1.x());
|
||||
finaldirection.setY(Direction_Linear1.y());
|
||||
finaldirection.setZ(Direction_Linear1.z());
|
||||
outcomingPhotonPolarization.setX(Polarization_Linear1.x());
|
||||
outcomingPhotonPolarization.setY(Polarization_Linear1.y());
|
||||
outcomingPhotonPolarization.setZ(Polarization_Linear1.z());
|
||||
}
|
||||
else if ((polmix>prob1) && (polmix<=prob1+prob2))
|
||||
{
|
||||
finaldirection.setX(Direction_Linear2.x());
|
||||
finaldirection.setY(Direction_Linear2.y());
|
||||
finaldirection.setZ(Direction_Linear2.z());
|
||||
outcomingPhotonPolarization.setX(Polarization_Linear2.x());
|
||||
outcomingPhotonPolarization.setY(Polarization_Linear2.y());
|
||||
outcomingPhotonPolarization.setZ(Polarization_Linear2.z());
|
||||
}
|
||||
else if (polmix>prob1+prob2)
|
||||
{
|
||||
finaldirection.setX(Direction_Circular.x());
|
||||
finaldirection.setY(Direction_Circular.y());
|
||||
finaldirection.setZ(Direction_Circular.z());
|
||||
outcomingPhotonPolarization.setX(Polarization_Circular.x());
|
||||
outcomingPhotonPolarization.setY(Polarization_Circular.y());
|
||||
outcomingPhotonPolarization.setZ(Polarization_Circular.z());
|
||||
}
|
||||
|
||||
//Sampling the Final State
|
||||
finaldirection.rotateUz(aDynamicGamma->GetMomentumDirection());
|
||||
fParticleChange->ProposeMomentumDirection(finaldirection);
|
||||
fParticleChange->SetProposedKineticEnergy(photonEnergy0);
|
||||
fParticleChange->ProposePolarization(outcomingPhotonPolarization);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4JAEAPolarizedElasticScatteringModel::GeneratePolarizedPhi(G4double Sigma_para,G4double Sigma_perp, G4double initial_Pol_Plane)
|
||||
{
|
||||
G4double phi;
|
||||
G4double phiProbability;
|
||||
G4double Probability=Sigma_perp/(Sigma_para+Sigma_perp);
|
||||
if (Probability<=G4UniformRand())
|
||||
{
|
||||
do
|
||||
{
|
||||
phi = CLHEP::twopi * G4UniformRand();
|
||||
phiProbability = cos(phi+initial_Pol_Plane)*cos(phi+initial_Pol_Plane);
|
||||
}
|
||||
while (phiProbability < G4UniformRand());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
phi = CLHEP::twopi * G4UniformRand();
|
||||
phiProbability = sin(phi+initial_Pol_Plane)*sin(phi+initial_Pol_Plane);
|
||||
}
|
||||
while (phiProbability < G4UniformRand());
|
||||
}
|
||||
return phi;
|
||||
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex G4JAEAPolarizedElasticScatteringModelMutex = G4MUTEX_INITIALIZER; }
|
||||
|
||||
void
|
||||
G4JAEAPolarizedElasticScatteringModel::InitialiseForElement(const G4ParticleDefinition*,
|
||||
G4int Z)
|
||||
{
|
||||
G4AutoLock l(&G4JAEAPolarizedElasticScatteringModelMutex);
|
||||
// G4cout << "G4JAEAPolarizedElasticScatteringModel::InitialiseForElement Z= "
|
||||
// << Z << G4endl;
|
||||
if(!dataCS[Z]) { ReadData(Z); }
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -0,0 +1,226 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: Zhuxin Li@CENBG
|
||||
// 11 March 2020
|
||||
// on the base of G4LivermoreGammaConversionModel
|
||||
// derives from G4BetheHeitler5DModel
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4LivermoreGammaConversion5DModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4EmParameters.hh"
|
||||
#include "G4ParticleChangeForGamma.hh"
|
||||
#include "G4LPhysicsFreeVector.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Exp.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermoreGammaConversion5DModel::lowEnergyLimit = 2.*CLHEP::electron_mass_c2;
|
||||
G4int G4LivermoreGammaConversion5DModel::verboseLevel = 0;
|
||||
constexpr G4int G4LivermoreGammaConversion5DModel::maxZ;
|
||||
G4LPhysicsFreeVector* G4LivermoreGammaConversion5DModel::data[] = {nullptr};
|
||||
|
||||
G4LivermoreGammaConversion5DModel::G4LivermoreGammaConversion5DModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
: G4BetheHeitler5DModel(p, nam), fParticleChange(nullptr)
|
||||
{
|
||||
// Verbosity scale for debugging purposes:
|
||||
// 0 = nothing
|
||||
// 1 = calculation of cross sections, file openings...
|
||||
// 2 = entering in methods
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4LivermoreGammaConversion5DModel is constructed " << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LivermoreGammaConversion5DModel::~G4LivermoreGammaConversion5DModel()
|
||||
{
|
||||
if(IsMaster()) {
|
||||
for(G4int i=0; i<maxZ; ++i) {
|
||||
if(data[i]) {
|
||||
delete data[i];
|
||||
data[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void
|
||||
G4LivermoreGammaConversion5DModel::Initialise( const G4ParticleDefinition* particle,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
G4BetheHeitler5DModel::Initialise(particle, cuts);
|
||||
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "Calling Initialise() of G4LivermoreGammaConversion5DModel."
|
||||
<< G4endl
|
||||
<< "Energy range: "
|
||||
<< LowEnergyLimit() / MeV << " MeV - "
|
||||
<< HighEnergyLimit() / GeV << " GeV isMater: " << IsMaster()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(!fParticleChange) {
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
}
|
||||
|
||||
if(IsMaster())
|
||||
{
|
||||
// Initialise element selector
|
||||
InitialiseElementSelectors(particle, cuts);
|
||||
// Access to elements
|
||||
char* path = std::getenv("G4LEDATA");
|
||||
G4ProductionCutsTable* theCoupleTable =
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4int numOfCouples = theCoupleTable->GetTableSize();
|
||||
for(G4int i=0; i<numOfCouples; ++i)
|
||||
{
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
SetCurrentCouple(couple);
|
||||
const G4Material* mat = couple->GetMaterial();
|
||||
const G4ElementVector* theElementVector = mat->GetElementVector();
|
||||
G4int nelm = mat->GetNumberOfElements();
|
||||
for (G4int j=0; j<nelm; ++j)
|
||||
{
|
||||
G4int Z = std::max(1, std::min((*theElementVector)[j]->GetZasInt(), maxZ));
|
||||
if(!data[Z]) { ReadData(Z, path); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermoreGammaConversion5DModel::ReadData(size_t Z, const char* path)
|
||||
{
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "Calling ReadData() of G4LivermoreGammaConversion5DModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
if(data[Z]) { return; }
|
||||
const char* datadir = path;
|
||||
if(!datadir)
|
||||
{
|
||||
datadir = std::getenv("G4LEDATA");
|
||||
if(!datadir)
|
||||
{
|
||||
G4Exception("G4LivermoreGammaConversion5DModel::ReadData()",
|
||||
"em0006",FatalException,
|
||||
"Environment variable G4LEDATA not defined");
|
||||
return;
|
||||
}
|
||||
}
|
||||
data[Z] = new G4LPhysicsFreeVector();
|
||||
std::ostringstream ost;
|
||||
ost << datadir << "/epics2017/pair/pp-cs-" << Z <<".dat";
|
||||
std::ifstream fin(ost.str().c_str());
|
||||
|
||||
if( !fin.is_open())
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4LivermoreGammaConversion5DModel data file <" << ost.str().c_str()
|
||||
<< "> is not opened!" << G4endl;
|
||||
G4Exception("G4LivermoreGammaConversion5DModel::ReadData()",
|
||||
"em0003",FatalException,
|
||||
ed,"G4LEDATA version should be G4EMLOW6.27 or later.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(verboseLevel > 1) { G4cout << "File " << ost.str()
|
||||
<< " is opened by G4LivermoreGammaConversion5DModel" << G4endl;}
|
||||
data[Z]->Retrieve(fin, true);
|
||||
}
|
||||
// Activation of linear interpolation
|
||||
data[Z]->SetSpline(false); // EPICS2017 has more points -> linear is fine
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4LivermoreGammaConversion5DModel::ComputeCrossSectionPerAtom(
|
||||
const G4ParticleDefinition* particle, G4double GammaEnergy, G4double Z,
|
||||
G4double, G4double, G4double)
|
||||
{
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "G4LivermoreGammaConversion5DModel::ComputeCrossSectionPerAtom() Z= "
|
||||
<< Z << G4endl;
|
||||
}
|
||||
G4double xs = 0.0;
|
||||
if (GammaEnergy < lowEnergyLimit) { return xs; }
|
||||
|
||||
G4int intZ = std::max(1, std::min(G4lrint(Z), maxZ));
|
||||
G4LPhysicsFreeVector* pv = data[intZ];
|
||||
// if element was not initialised
|
||||
// do initialisation safely for MT mode
|
||||
if(!pv)
|
||||
{
|
||||
InitialiseForElement(particle, intZ);
|
||||
pv = data[intZ];
|
||||
if(!pv) { return xs; }
|
||||
}
|
||||
// x-section is taken from the table
|
||||
xs = pv->Value(GammaEnergy);
|
||||
if(verboseLevel > 0)
|
||||
{
|
||||
G4cout << "*** Gamma conversion xs for Z=" << Z << " at energy E(MeV)="
|
||||
<< GammaEnergy/MeV << " cs=" << xs/millibarn << " mb" << G4endl;
|
||||
}
|
||||
return xs;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex LivermoreGammaConversion5DModelMutex = G4MUTEX_INITIALIZER; }
|
||||
|
||||
void G4LivermoreGammaConversion5DModel::InitialiseForElement(
|
||||
const G4ParticleDefinition*,
|
||||
G4int Z)
|
||||
{
|
||||
G4AutoLock l(&LivermoreGammaConversion5DModelMutex);
|
||||
// G4cout << "G4LivermoreGammaConversion5DModel::InitialiseForElement Z= "
|
||||
// << Z << G4endl;
|
||||
if(!data[Z]) { ReadData(Z); }
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
+14
-257
@@ -27,6 +27,11 @@
|
||||
// 22 January 2012
|
||||
// on base of G4LivermoreGammaConversionModel (original version)
|
||||
// and G4LivermoreRayleighModel (MT version)
|
||||
//
|
||||
// Modifications: Zhuxin Li@CENBG
|
||||
// 11 March 2020
|
||||
// derives from G4PairProductionRelModel
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4LivermoreGammaConversionModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
@@ -44,17 +49,13 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LivermoreGammaConversionModel::lowEnergyLimit = 2.*CLHEP::electron_mass_c2;
|
||||
G4double G4LivermoreGammaConversionModel::tripletLowEnergy = 0.0;
|
||||
G4double G4LivermoreGammaConversionModel::tripletHighEnergy = 100.0*CLHEP::GeV;
|
||||
G4int G4LivermoreGammaConversionModel::verboseLevel = 0;
|
||||
G4int G4LivermoreGammaConversionModel::nbinsTriplet = 0;
|
||||
G4int G4LivermoreGammaConversionModel::maxZ = 99;
|
||||
constexpr G4int G4LivermoreGammaConversionModel::maxZ;
|
||||
G4LPhysicsFreeVector* G4LivermoreGammaConversionModel::data[] = {nullptr};
|
||||
G4PhysicsLogVector* G4LivermoreGammaConversionModel::probTriplet[] = {nullptr};
|
||||
|
||||
G4LivermoreGammaConversionModel::G4LivermoreGammaConversionModel
|
||||
(const G4ParticleDefinition*, const G4String& nam)
|
||||
: G4VEmModel(nam),fParticleChange(nullptr)
|
||||
(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4PairProductionRelModel(p,nam),fParticleChange(nullptr)
|
||||
{
|
||||
// Verbosity scale for debugging purposes:
|
||||
// 0 = nothing
|
||||
@@ -77,10 +78,6 @@ G4LivermoreGammaConversionModel::~G4LivermoreGammaConversionModel()
|
||||
delete data[i];
|
||||
data[i] = nullptr;
|
||||
}
|
||||
if(probTriplet[i]) {
|
||||
delete probTriplet[i];
|
||||
probTriplet[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +87,7 @@ G4LivermoreGammaConversionModel::~G4LivermoreGammaConversionModel()
|
||||
void G4LivermoreGammaConversionModel::Initialise(
|
||||
const G4ParticleDefinition* particle,
|
||||
const G4DataVector& cuts)
|
||||
{
|
||||
{ G4PairProductionRelModel::Initialise(particle, cuts);
|
||||
if (verboseLevel > 1)
|
||||
{
|
||||
G4cout << "Calling Initialise() of G4LivermoreGammaConversionModel."
|
||||
@@ -103,12 +100,8 @@ void G4LivermoreGammaConversionModel::Initialise(
|
||||
|
||||
if(!fParticleChange) {
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
if(GetTripletModel()) {
|
||||
GetTripletModel()->SetParticleChange(fParticleChange);
|
||||
}
|
||||
}
|
||||
if(GetTripletModel()) { GetTripletModel()->Initialise(particle, cuts); }
|
||||
|
||||
|
||||
if(IsMaster())
|
||||
{
|
||||
// Initialise element selector
|
||||
@@ -133,29 +126,11 @@ void G4LivermoreGammaConversionModel::Initialise(
|
||||
{
|
||||
G4int Z = std::min((*theElementVector)[j]->GetZasInt(), maxZ);
|
||||
if(!data[Z]) { ReadData(Z, path); }
|
||||
if(GetTripletModel()) { InitialiseProbability(particle, Z); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermoreGammaConversionModel::InitialiseLocal(
|
||||
const G4ParticleDefinition*, G4VEmModel* masterModel)
|
||||
{
|
||||
SetElementSelectors(masterModel->GetElementSelectors());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double
|
||||
G4LivermoreGammaConversionModel::MinPrimaryEnergy(const G4Material*,
|
||||
const G4ParticleDefinition*,
|
||||
G4double)
|
||||
{
|
||||
return lowEnergyLimit;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -184,7 +159,7 @@ void G4LivermoreGammaConversionModel::ReadData(size_t Z, const char* path)
|
||||
}
|
||||
data[Z] = new G4LPhysicsFreeVector();
|
||||
std::ostringstream ost;
|
||||
ost << datadir << "/livermore/pair/pp-cs-" << Z <<".dat";
|
||||
ost << datadir << "/epics2017/pair/pp-cs-" << Z <<".dat";
|
||||
std::ifstream fin(ost.str().c_str());
|
||||
|
||||
if( !fin.is_open())
|
||||
@@ -205,8 +180,8 @@ void G4LivermoreGammaConversionModel::ReadData(size_t Z, const char* path)
|
||||
|
||||
data[Z]->Retrieve(fin, true);
|
||||
}
|
||||
// Activation of spline interpolation
|
||||
data[Z] ->SetSpline(true);
|
||||
// Activation of linear interpolation
|
||||
data[Z] ->SetSpline(false); // EPICS2017 has more points -> linear is fine
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -250,237 +225,19 @@ G4double G4LivermoreGammaConversionModel::ComputeCrossSectionPerAtom(
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LivermoreGammaConversionModel::SampleSecondaries(
|
||||
std::vector<G4DynamicParticle*>* fvect,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4double, G4double)
|
||||
{
|
||||
|
||||
// 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
|
||||
// energy are ignored.
|
||||
// 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.
|
||||
|
||||
if (verboseLevel > 1) {
|
||||
G4cout << "Calling SampleSecondaries() of G4LivermoreGammaConversionModel"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
G4double epsilon ;
|
||||
G4double epsilon0Local = electron_mass_c2 / photonEnergy ;
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
// Do it fast if photon energy < 2. MeV
|
||||
static const G4double smallEnergy = 2.*CLHEP::MeV;
|
||||
if (photonEnergy < smallEnergy )
|
||||
{
|
||||
epsilon = epsilon0Local + (0.5 - epsilon0Local) * rndmEngine->flat();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select randomly one element in the current material
|
||||
|
||||
const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
|
||||
const G4Element* element = SelectRandomAtom(couple,particle,photonEnergy);
|
||||
G4int Z = element->GetZasInt();
|
||||
|
||||
// triplet production
|
||||
if(GetTripletModel()) {
|
||||
if(!probTriplet[Z]) { InitialiseForElement(particle, Z); }
|
||||
/*
|
||||
G4cout << "Liv: E= " << photonEnergy
|
||||
<< " prob= " << probTriplet[Z]->Value(photonEnergy)
|
||||
<< G4endl;
|
||||
*/
|
||||
if(probTriplet[Z] &&
|
||||
rndmEngine->flat() < probTriplet[Z]->Value(photonEnergy)) {
|
||||
GetTripletModel()->SampleSecondaries(fvect, couple, aDynamicGamma);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
G4IonisParamElm* ionisation = element->GetIonisation();
|
||||
|
||||
// Extract Coulomb factor for this Element
|
||||
G4double fZ = 8. * (ionisation->GetlogZ3());
|
||||
static const G4double midEnergy = 50.*CLHEP::MeV;
|
||||
if (photonEnergy > midEnergy) { fZ += 8. * (element->GetfCoulomb()); }
|
||||
|
||||
// Limits of the screening variable
|
||||
G4double screenFactor = 136. * epsilon0Local / (element->GetIonisation()->GetZ3());
|
||||
G4double screenMax = G4Exp((42.24 - fZ)/8.368) + 0.952;
|
||||
G4double screenMin = std::min(4.*screenFactor,screenMax);
|
||||
|
||||
// Limits of the energy sampling
|
||||
G4double epsilon1 = 0.5 - 0.5 * std::sqrt(1. - screenMin / screenMax) ;
|
||||
G4double epsilonMin = std::max(epsilon0Local,epsilon1);
|
||||
G4double epsilonRange = 0.5 - epsilonMin ;
|
||||
|
||||
// Sample the energy rate of the created electron (or positron)
|
||||
G4double screen;
|
||||
G4double gReject;
|
||||
|
||||
G4double f10 = ScreenFunction1(screenMin) - fZ;
|
||||
G4double f20 = ScreenFunction2(screenMin) - fZ;
|
||||
G4double normF1 = std::max(f10 * epsilonRange * epsilonRange,0.);
|
||||
G4double normF2 = std::max(1.5 * f20,0.);
|
||||
|
||||
do
|
||||
{
|
||||
if (normF1 > (normF1 + normF2)*rndmEngine->flat() )
|
||||
{
|
||||
epsilon = 0.5 - epsilonRange *G4Exp(G4Log(rndmEngine->flat())/3.);
|
||||
screen = screenFactor / (epsilon * (1. - epsilon));
|
||||
gReject = (ScreenFunction1(screen) - fZ) / f10 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
epsilon = epsilonMin + epsilonRange * rndmEngine->flat();
|
||||
screen = screenFactor / (epsilon * (1 - epsilon));
|
||||
gReject = (ScreenFunction2(screen) - fZ) / f20 ;
|
||||
}
|
||||
} while ( gReject < rndmEngine->flat() );
|
||||
|
||||
} // End of epsilon sampling
|
||||
|
||||
// Fix charges randomly
|
||||
|
||||
G4double electronTotEnergy;
|
||||
G4double positronTotEnergy;
|
||||
|
||||
if (rndmEngine->flat() > 0.5)
|
||||
{
|
||||
electronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
positronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
positronTotEnergy = (1. - epsilon) * photonEnergy;
|
||||
electronTotEnergy = epsilon * photonEnergy;
|
||||
}
|
||||
|
||||
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
|
||||
// Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev. Mod. Phys. 49, 421 (1977)
|
||||
|
||||
static const G4double a1 = 1.6;
|
||||
static const G4double a2 = 0.5333333333;
|
||||
G4double uu = -G4Log(rndmEngine->flat()*rndmEngine->flat());
|
||||
G4double u = (0.25 > rndmEngine->flat()) ? uu*a1 : uu*a2;
|
||||
|
||||
G4double thetaEle = u*electron_mass_c2/electronTotEnergy;
|
||||
G4double sinte = std::sin(thetaEle);
|
||||
G4double coste = std::cos(thetaEle);
|
||||
|
||||
G4double thetaPos = u*electron_mass_c2/positronTotEnergy;
|
||||
G4double sintp = std::sin(thetaPos);
|
||||
G4double costp = std::cos(thetaPos);
|
||||
|
||||
G4double phi = twopi * rndmEngine->flat();
|
||||
G4double sinp = std::sin(phi);
|
||||
G4double cosp = std::cos(phi);
|
||||
|
||||
// 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 electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
G4ThreeVector electronDirection (sinte*cosp, sinte*sinp, coste);
|
||||
electronDirection.rotateUz(photonDirection);
|
||||
|
||||
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
|
||||
electronDirection,
|
||||
electronKineEnergy);
|
||||
|
||||
// The e+ is always created
|
||||
G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
|
||||
|
||||
G4ThreeVector positronDirection (-sintp*cosp, -sintp*sinp, costp);
|
||||
positronDirection.rotateUz(photonDirection);
|
||||
|
||||
// Create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
|
||||
positronDirection,
|
||||
positronKineEnergy);
|
||||
// Fill output vector
|
||||
fvect->push_back(particle1);
|
||||
fvect->push_back(particle2);
|
||||
|
||||
// kill incident photon
|
||||
fParticleChange->SetProposedKineticEnergy(0.);
|
||||
fParticleChange->ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex LivermoreGammaConversionModelMutex = G4MUTEX_INITIALIZER; }
|
||||
|
||||
void G4LivermoreGammaConversionModel::InitialiseForElement(
|
||||
const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition*,
|
||||
G4int Z)
|
||||
{
|
||||
if(GetTripletModel()) { GetTripletModel()->InitialiseForElement(part, Z); }
|
||||
G4AutoLock l(&LivermoreGammaConversionModelMutex);
|
||||
// G4cout << "G4LivermoreGammaConversionModel::InitialiseForElement Z= "
|
||||
// << Z << G4endl;
|
||||
if(!data[Z]) { ReadData(Z); }
|
||||
if(GetTripletModel() && !probTriplet[Z]) { InitialiseProbability(part, Z); }
|
||||
l.unlock();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LivermoreGammaConversionModel::InitialiseProbability(
|
||||
const G4ParticleDefinition* part, G4int Z)
|
||||
{
|
||||
if(!probTriplet[Z]) {
|
||||
const G4Material* mat = (CurrentCouple()) ? CurrentCouple()->GetMaterial()
|
||||
: nullptr;
|
||||
if(0 == nbinsTriplet) {
|
||||
tripletLowEnergy = GetTripletModel()->MinPrimaryEnergy(mat, part, 0.0);
|
||||
tripletHighEnergy =
|
||||
std::max(GetTripletModel()->HighEnergyLimit(), 10*tripletLowEnergy);
|
||||
G4int nbins = G4EmParameters::Instance()->NumberOfBinsPerDecade();
|
||||
nbinsTriplet = std::max(3,
|
||||
(G4int)(nbins*G4Log(tripletHighEnergy/tripletLowEnergy)/(6*G4Log(10.))));
|
||||
}
|
||||
/*
|
||||
G4cout << "G4LivermoreGammaConversionModel::InitialiseProbability Z= "
|
||||
<< Z << " Nbin= " << nbinsTriplet
|
||||
<< " Emin(MeV)= " << tripletLowEnergy
|
||||
<< " Emax(MeV)= " << tripletHighEnergy << G4endl;
|
||||
*/
|
||||
probTriplet[Z] =
|
||||
new G4PhysicsLogVector(tripletLowEnergy,tripletHighEnergy,nbinsTriplet);
|
||||
probTriplet[Z]->SetSpline(true);
|
||||
G4double zz = (G4double)Z;
|
||||
// loop over bins
|
||||
for(G4int j=0; j<=nbinsTriplet; ++j) {
|
||||
G4double e = (probTriplet[Z])->Energy(j);
|
||||
SetupForMaterial(part, mat, e);
|
||||
G4double cross = ComputeCrossSectionPerAtom(part, e, zz);
|
||||
G4double tcross =
|
||||
GetTripletModel()->ComputeCrossSectionPerAtom(part, e, zz);
|
||||
tcross = (0.0 < cross) ? tcross/cross : 0.0;
|
||||
(probTriplet[Z])->PutValue(j, tcross);
|
||||
//G4cout << j << ". E= " << e << " prob= " << tcross << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -130,7 +130,8 @@ G4LivermorePhotoElectricModel::Initialise(const G4ParticleDefinition*,
|
||||
|
||||
if(!fWater) {
|
||||
fWater = G4Material::GetMaterial("G4_WATER", false);
|
||||
if(fWater) { fWaterEnergyLimit = 13.6*eV; }
|
||||
if(!fWater) { fWater = G4Material::GetMaterial("Water", false); }
|
||||
if(fWater) { fWaterEnergyLimit = 13.6*eV; }
|
||||
}
|
||||
|
||||
if(!fShellCrossSection) { fShellCrossSection = new G4ElementData(); }
|
||||
|
||||
@@ -575,26 +575,26 @@ G4double G4ecpssrBaseKxsModel::FunctionFK(G4double k, G4double theta)
|
||||
|
||||
// END PROTECTION
|
||||
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec.begin(),dummyVec.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec.begin(),dummyVec.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap[(*t1)].begin(),aVecMap[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap[(*t1)].begin(),aVecMap[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap[(*t2)].begin(),aVecMap[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap[(*t2)].begin(),aVecMap[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
|
||||
xs11 = FKData[valueT1][valueE11];
|
||||
xs12 = FKData[valueT1][valueE12];
|
||||
xs21 = FKData[valueT2][valueE21];
|
||||
xs22 = FKData[valueT2][valueE22];
|
||||
xs11 = FKData[valueT1][valueE11];
|
||||
xs12 = FKData[valueT1][valueE12];
|
||||
xs21 = FKData[valueT2][valueE21];
|
||||
xs22 = FKData[valueT2][valueE22];
|
||||
|
||||
/*
|
||||
if (verboseLevel>0)
|
||||
|
||||
@@ -799,26 +799,26 @@ G4double G4ecpssrBaseLixsModel::FunctionFL1(G4double k, G4double theta)
|
||||
|
||||
// END PROTECTION
|
||||
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec1.begin(),dummyVec1.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec1.begin(),dummyVec1.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap1[(*t1)].begin(),aVecMap1[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap1[(*t1)].begin(),aVecMap1[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap1[(*t2)].begin(),aVecMap1[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap1[(*t2)].begin(),aVecMap1[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
|
||||
xs11 = FL1Data[valueT1][valueE11];
|
||||
xs12 = FL1Data[valueT1][valueE12];
|
||||
xs21 = FL1Data[valueT2][valueE21];
|
||||
xs22 = FL1Data[valueT2][valueE22];
|
||||
xs11 = FL1Data[valueT1][valueE11];
|
||||
xs12 = FL1Data[valueT1][valueE12];
|
||||
xs21 = FL1Data[valueT2][valueE21];
|
||||
xs22 = FL1Data[valueT2][valueE22];
|
||||
|
||||
if (verboseLevel>0)
|
||||
G4cout
|
||||
@@ -890,26 +890,26 @@ G4double G4ecpssrBaseLixsModel::FunctionFL2(G4double k, G4double theta)
|
||||
|
||||
// END PROTECTION
|
||||
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec2.begin(),dummyVec2.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
std::vector<double>::iterator t2 = std::upper_bound(dummyVec2.begin(),dummyVec2.end(), k);
|
||||
std::vector<double>::iterator t1 = t2-1;
|
||||
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap2[(*t1)].begin(),aVecMap2[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
std::vector<double>::iterator e12 = std::upper_bound(aVecMap2[(*t1)].begin(),aVecMap2[(*t1)].end(), theta);
|
||||
std::vector<double>::iterator e11 = e12-1;
|
||||
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap2[(*t2)].begin(),aVecMap2[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
std::vector<double>::iterator e22 = std::upper_bound(aVecMap2[(*t2)].begin(),aVecMap2[(*t2)].end(), theta);
|
||||
std::vector<double>::iterator e21 = e22-1;
|
||||
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
valueT1 =*t1;
|
||||
valueT2 =*t2;
|
||||
valueE21 =*e21;
|
||||
valueE22 =*e22;
|
||||
valueE12 =*e12;
|
||||
valueE11 =*e11;
|
||||
|
||||
xs11 = FL2Data[valueT1][valueE11];
|
||||
xs12 = FL2Data[valueT1][valueE12];
|
||||
xs21 = FL2Data[valueT2][valueE21];
|
||||
xs22 = FL2Data[valueT2][valueE22];
|
||||
xs11 = FL2Data[valueT1][valueE11];
|
||||
xs12 = FL2Data[valueT1][valueE12];
|
||||
xs21 = FL2Data[valueT2][valueE21];
|
||||
xs22 = FL2Data[valueT2][valueE22];
|
||||
|
||||
if (verboseLevel>0)
|
||||
G4cout
|
||||
|
||||
Reference in New Issue
Block a user