Import Geant4 10.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2017-12-08 12:52:30 +01:00
parent 98e455a940
commit fc6af9e721
2166 changed files with 276760 additions and 100873 deletions
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ComptonScattering.cc 84598 2014-10-17 07:39:15Z gcosmo $
// $Id: G4ComptonScattering.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
//
//------------ G4ComptonScattering physics process -----------------------------
@@ -101,11 +101,11 @@ void G4ComptonScattering::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
if(!EmModel(1)) { SetEmModel(new G4KleinNishinaCompton(), 1); }
if(!EmModel(0)) { SetEmModel(new G4KleinNishinaCompton()); }
G4EmParameters* param = G4EmParameters::Instance();
EmModel(1)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(1)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, EmModel(1));
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(0)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, EmModel(0));
}
}
@@ -115,3 +115,11 @@ void G4ComptonScattering::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4ComptonScattering::ProcessDescription(std::ostream& out) const
{
out << "<strong>Compton scattering</strong>";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4CoulombScattering.cc 85246 2014-10-27 08:26:11Z gcosmo $
// $Id: G4CoulombScattering.cc 107365 2017-11-09 10:54:29Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -125,11 +125,11 @@ void G4CoulombScattering::InitialiseProcess(const G4ParticleDefinition* p)
name != "kaon+" && name != "proton" ) { SetVerboseLevel(0); }
}
if(!EmModel(1)) {
if(yes) { SetEmModel(new G4eCoulombScatteringModel(), 1); }
else { SetEmModel(new G4IonCoulombScatteringModel(), 1); }
if(!EmModel(0)) {
if(yes) { SetEmModel(new G4eCoulombScatteringModel()); }
else { SetEmModel(new G4IonCoulombScatteringModel()); }
}
G4VEmModel* model = EmModel(1);
G4VEmModel* model = EmModel(0);
G4double emin = std::max(param->MinKinEnergy(),model->LowEnergyLimit());
G4double emax = std::min(param->MaxKinEnergy(),model->HighEnergyLimit());
model->SetPolarAngleLimit(theta);
@@ -160,13 +160,29 @@ G4double G4CoulombScattering::MinPrimaryEnergy(const G4ParticleDefinition* part,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4CoulombScattering::PrintInfo()
void G4CoulombScattering::StreamProcessInfo(std::ostream& outFile,
G4String endOfLine) const
{
G4cout << " " << G4EmParameters::Instance()->MscThetaLimit()/degree
<< " < Theta(degree) < 180";
G4double tetmin = G4EmParameters::Instance()->MscThetaLimit()/degree;
outFile << " ";
if(tetmin > 179.) { outFile << "ThetaMin(p)"; }
else { outFile << tetmin; }
outFile << " < Theta(degree) < 180";
if(q2Max < DBL_MAX) { G4cout << "; pLimit(GeV^1)= " << sqrt(q2Max)/GeV; }
G4cout << G4endl;
if(q2Max < DBL_MAX) { outFile << "; pLimit(GeV^1)= " << sqrt(q2Max)/GeV; }
outFile << endOfLine;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4CoulombScattering::ProcessDescription(std::ostream& out) const
{
out <<
"<strong>Coulomb scattering</strong>. Simulation of elastic scattering <br>"
"events individually. May be used in combination with multiple<br>"
"scattering, where Coulomb scattering is used for hard (large angle)<br>"
"collisions and multiple scattering for soft collisions.";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,553 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: $
//
// ----------------------------------------------------------------------------
//
//
// File name: G4GSMottCorrection
//
// Author: Mihaly Novak
//
// Creation date: 23.08.2017
//
// Modifications:
//
// Class description: see the header file.
//
// -----------------------------------------------------------------------------
#include "G4GSMottCorrection.hh"
#include "G4PhysicalConstants.hh"
#include "zlib.h"
#include "Randomize.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Material.hh"
#include "G4ElementVector.hh"
#include "G4Element.hh"
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
const std::string G4GSMottCorrection::gElemSymbols[] = {"H","He","Li","Be","B" ,
"C" ,"N" ,"O" ,"F" ,"Ne","Na","Mg","Al","Si","P" , "S","Cl","Ar","K" ,"Ca","Sc",
"Ti","V" ,"Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr","Rb",
"Sr","Y" ,"Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I" ,
"Xe","Cs","Ba","La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm",
"Yb","Lu","Hf","Ta","W" ,"Re","Os","Ir","Pt","Au","Hg","Tl","Pb","Bi","Po","At",
"Rn","Fr","Ra","Ac","Th","Pa","U" ,"Np","Pu","Am","Cm","Bk","Cf"};
G4GSMottCorrection::G4GSMottCorrection(G4bool iselectron) : fIsElectron(iselectron) {
// init grids related data member values
fMaxEkin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-gMaxBeta2)-1.);
fLogMinEkin = G4Log(gMinEkin);
fInvLogDelEkin = (gNumEkin-gNumBeta2)/G4Log(gMidEkin/gMinEkin);
G4double pt2 = gMidEkin*(gMidEkin+2.0*CLHEP::electron_mass_c2);
fMinBeta2 = pt2/(pt2+CLHEP::electron_mass_c2*CLHEP::electron_mass_c2);
fInvDelBeta2 = (gNumBeta2-1.)/(gMaxBeta2-fMinBeta2);
fInvDelDelta = (gNumDelta-1.)/gMaxDelta;
fInvDelAngle = gNumAngle-1.;
}
G4GSMottCorrection::~G4GSMottCorrection() {
ClearMCDataPerElement();
ClearMCDataPerMaterial();
}
void G4GSMottCorrection::GetMottCorrectionFactors(G4double logekin, G4double beta2, G4int matindx, G4double &mcToScr,
G4double &mcToQ1, G4double &mcToG2PerG1) {
G4int ekinIndxLow = 0;
G4double remRfaction = 0.;
if (beta2>=gMaxBeta2) {
ekinIndxLow = gNumEkin - 1;
// remRfaction = -1.
} else if (beta2>=fMinBeta2) { // linear interpolation on \beta^2
remRfaction = (beta2 - fMinBeta2) * fInvDelBeta2;
ekinIndxLow = (G4int)remRfaction;
remRfaction -= ekinIndxLow;
ekinIndxLow += (gNumEkin - gNumBeta2);
} else if (logekin>=fLogMinEkin) {
remRfaction = (logekin - fLogMinEkin) * fInvLogDelEkin;
ekinIndxLow = (G4int)remRfaction;
remRfaction -= ekinIndxLow;
} // the defaults otherwise i.e. use the lowest energy values when ekin is smaller than the minum ekin
//
DataPerEkin *perEkinLow = fMCDataPerMaterial[matindx]->fDataPerEkin[ekinIndxLow];
mcToScr = perEkinLow->fMCScreening;
mcToQ1 = perEkinLow->fMCFirstMoment;
mcToG2PerG1 = perEkinLow->fMCSecondMoment;
if (remRfaction>0.) {
DataPerEkin *perEkinHigh = fMCDataPerMaterial[matindx]->fDataPerEkin[ekinIndxLow+1];
mcToScr += remRfaction*(perEkinHigh->fMCScreening - perEkinLow->fMCScreening);
mcToQ1 += remRfaction*(perEkinHigh->fMCFirstMoment - perEkinLow->fMCFirstMoment);
mcToG2PerG1 += remRfaction*(perEkinHigh->fMCSecondMoment - perEkinLow->fMCSecondMoment);
}
}
// accept cost if rndm [0,1] < return value
double G4GSMottCorrection::GetMottRejectionValue(G4double logekin, G4double beta2, G4double q1, G4double cost,
G4int matindx, G4int &ekindx, G4int &deltindx) {
G4double val = 1.0;
G4double delta = q1/(0.5+q1);
// check if converged to 1 for all angles => accept cost
if (delta>=gMaxDelta) {
return val;
}
//
// check if kinetic energy index needs to be determined
if (ekindx<0) {
G4int ekinIndxLow = 0;
G4double probIndxHigh = 0.; // will be the prob. of taking the ekinIndxLow+1 bin
if (beta2>gMaxBeta2) {
ekinIndxLow = gNumEkin - 1;
// probIndxHigh = -1.
} else if (beta2>=fMinBeta2) { // linear interpolation on \beta^2
probIndxHigh = (beta2 - fMinBeta2) * fInvDelBeta2;
ekinIndxLow = (G4int)probIndxHigh;
probIndxHigh -= ekinIndxLow;
ekinIndxLow += (gNumEkin - gNumBeta2);
} else if (logekin>fLogMinEkin) { // linear interpolation on \ln(E_{kin})
probIndxHigh = (logekin - fLogMinEkin) * fInvLogDelEkin;
ekinIndxLow = (G4int)probIndxHigh;
probIndxHigh -= ekinIndxLow;
} // the defaults otherwise i.e. use the lowest energy values when ekin is smaller than the minum ekin
//
// check if need to take the higher ekin index
if (G4UniformRand()<probIndxHigh) {
++ekinIndxLow;
}
// set kinetic energy grid index
ekindx = ekinIndxLow;
}
// check if delta value index needs to be determined (note: in case of single scattering deltindx will be set to 0 by
// by the caller but the ekindx will be -1: kinetic energy index is not known but the delta index is known)
if (deltindx<0) {
// note: delta is for sure < gMaxDelta at this point ( and minimum delta value is 0)
G4double probIndxHigh = delta*fInvDelDelta; // will be the prob. of taking the deltIndxLow+1 bin
G4int deltIndxLow = (G4int)probIndxHigh;
probIndxHigh -= deltIndxLow;
// check if need to take the higher delta index
if (G4UniformRand()<probIndxHigh) {
++deltIndxLow;
}
// set the delta value grid index
deltindx = deltIndxLow;
}
//
// get the corresponding distribution
DataPerDelta *perDelta = fMCDataPerMaterial[matindx]->fDataPerEkin[ekindx]->fDataPerDelta[deltindx];
//
// determine lower index of the angular bin
G4double ang = std::sqrt(0.5*(1.-cost)); // sin(0.5\theta) in [0,1]
G4double remRfaction = ang*fInvDelAngle;
G4int angIndx = (G4int)remRfaction;
remRfaction -= angIndx;
if (angIndx<gNumAngle-2) { // normal case: linear interpolation
val = remRfaction*(perDelta->fRejFuntion[angIndx+1]-perDelta->fRejFuntion[angIndx]) + perDelta->fRejFuntion[angIndx];
} else { // last bin
G4double dum = ang-1.+1./fInvDelAngle;
val = perDelta->fSA + dum*(perDelta->fSB + dum*(perDelta->fSC + dum*perDelta->fSD));
}
return val;
}
void G4GSMottCorrection::Initialise() {
// load Mott-correction data for each elements that belongs to materials that are used in the detector
InitMCDataPerElement();
// clrea Mott-correction data per material
ClearMCDataPerMaterial();
// initialise Mott-correction data for the materials that are used in the detector
InitMCDataPerMaterials();
}
void G4GSMottCorrection::InitMCDataPerElement() {
// do it only once
if (fMCDataPerElement.size()<gMaxZet+1) {
fMCDataPerElement.resize(gMaxZet+1,nullptr);
}
// loop over all materials, for those that are used check the list of elements and load data from file if the
// corresponding data has not been loaded yet
G4ProductionCutsTable *thePCTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numMatCuts = thePCTable->GetTableSize();
for (size_t imc=0; imc<numMatCuts; ++imc) {
const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
if (!matCut->IsUsed()) {
continue;
}
const G4Material *mat = matCut->GetMaterial();
const G4ElementVector *elemVect = mat->GetElementVector();
//
size_t numElems = elemVect->size();
for (size_t ielem=0; ielem<numElems; ++ielem) {
const G4Element *elem = (*elemVect)[ielem];
G4int izet = G4lrint(elem->GetZ());
if (izet>gMaxZet) {
izet = gMaxZet;
}
if (!fMCDataPerElement[izet]) {
LoadMCDataElement(elem);
}
}
}
}
void G4GSMottCorrection::InitMCDataPerMaterials() {
// prepare size of the container
size_t numMaterials = G4Material::GetNumberOfMaterials();
if (fMCDataPerMaterial.size()!=numMaterials) {
fMCDataPerMaterial.resize(numMaterials);
}
// init. Mott-correction data for the Materials that are used in the geometry
G4ProductionCutsTable *thePCTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numMatCuts = thePCTable->GetTableSize();
for (size_t imc=0; imc<numMatCuts; ++imc) {
const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
if (!matCut->IsUsed()) {
continue;
}
const G4Material *mat = matCut->GetMaterial();
if (!fMCDataPerMaterial[mat->GetIndex()]) {
InitMCDataMaterial(mat);
}
}
}
// it's called only if data has not been loaded for this element yet
void G4GSMottCorrection::LoadMCDataElement(const G4Element *elem) {
// allocate memory
G4int izet = G4lrint(elem->GetZ());
if (izet>gMaxZet) {
izet = gMaxZet;
}
DataPerMaterial *perElem = new DataPerMaterial();
AllocateDataPerMaterial(perElem);
fMCDataPerElement[izet] = perElem;
//
// load data from file
char* tmppath = getenv("G4LEDATA");
if (!tmppath) {
G4Exception("G4GSMottCorrection::LoadMCDataElement()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
return;
}
std::string path(tmppath);
if (fIsElectron) {
path += "/msc_GS/MottCor/el/";
} else {
path += "/msc_GS/MottCor/pos/";
}
std::string fname = path+"rej_"+gElemSymbols[izet-1];
std::istringstream infile(std::ios::in);
ReadCompressedFile(fname, infile);
// check if file is open !!!
for (G4int iek=0; iek<gNumEkin; ++iek) {
DataPerEkin *perEkin = perElem->fDataPerEkin[iek];
// 1. get the 3 Mott-correction factors for the current kinetic energy
infile >> perEkin->fMCScreening;
infile >> perEkin->fMCFirstMoment;
infile >> perEkin->fMCSecondMoment;
// 2. load each data per delta:
for (G4int idel=0; idel<gNumDelta; ++idel) {
DataPerDelta *perDelta = perEkin->fDataPerDelta[idel];
// 2./a. : first the rejection function values
for (G4int iang=0; iang<gNumAngle; ++iang) {
infile >> perDelta->fRejFuntion[iang];
}
// 2./b. : then the 4 spline parameter for the last bin
infile >> perDelta->fSA;
infile >> perDelta->fSB;
infile >> perDelta->fSC;
infile >> perDelta->fSD;
}
}
}
// uncompress one data file into the input string stream
void G4GSMottCorrection::ReadCompressedFile(std::string fname, std::istringstream &iss) {
std::string *dataString = nullptr;
std::string compfilename(fname+".z");
// create input stream with binary mode operation and positioning at the end of the file
std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
if (in.good()) {
// get current position in the stream (was set to the end)
int fileSize = in.tellg();
// set current position being the beginning of the stream
in.seekg(0,std::ios::beg);
// create (zlib) byte buffer for the data
Bytef *compdata = new Bytef[fileSize];
while(in) {
in.read((char*)compdata, fileSize);
}
// create (zlib) byte buffer for the uncompressed data
uLongf complen = (uLongf)(fileSize*4);
Bytef *uncompdata = new Bytef[complen];
while (Z_OK!=uncompress(uncompdata, &complen, compdata, fileSize)) {
// increase uncompressed byte buffer
delete[] uncompdata;
complen *= 2;
uncompdata = new Bytef[complen];
}
// delete the compressed data buffer
delete [] compdata;
// create a string from the uncompressed data (will be deallocated by the caller)
dataString = new std::string((char*)uncompdata, (long)complen);
// delete the uncompressed data buffer
delete [] uncompdata;
} else {
std::string msg = " Problem while trying to read " + compfilename + " data file.\n";
G4Exception("G4GSMottCorrection::ReadCompressedFile","em0006", FatalException,msg.c_str());
return;
}
// create the input string stream from the data string
if (dataString) {
iss.str(*dataString);
in.close();
delete dataString;
}
}
void G4GSMottCorrection::InitMCDataMaterial(const G4Material *mat) {
constexpr G4double const1 = 7821.6; // [cm2/g]
constexpr G4double const2 = 0.1569; // [cm2 MeV2 / g]
constexpr G4double finstrc2 = 5.325135453E-5; // fine-structure const. square
G4double constFactor = CLHEP::electron_mass_c2*CLHEP::fine_structure_const/0.88534;
constFactor *= constFactor; // (mc^2)^2\alpha^2/( C_{TF}^2)
// allocate memory
DataPerMaterial *perMat = new DataPerMaterial();
AllocateDataPerMaterial(perMat);
fMCDataPerMaterial[mat->GetIndex()] = perMat;
//
const G4ElementVector* elemVect = mat->GetElementVector();
const G4int numElems = mat->GetNumberOfElements();
const G4double* nbAtomsPerVolVect = mat->GetVecNbOfAtomsPerVolume();
G4double totNbAtomsPerVol = mat->GetTotNbOfAtomsPerVolume();
//
// 1. Compute material dependent part of Moliere's b_c \chi_c^2
// (with \xi=1 (i.e. total sub-threshold scattering power correction)
G4double moliereBc = 0.0;
G4double moliereXc2 = 0.0;
G4double zs = 0.0;
G4double ze = 0.0;
G4double zx = 0.0;
G4double sa = 0.0;
G4double xi = 1.0;
for (G4int ielem=0; ielem<numElems; ++ielem) {
G4double zet = (*elemVect)[ielem]->GetZ();
if (zet>gMaxZet) {
zet = (G4double)gMaxZet;
}
G4double iwa = (*elemVect)[ielem]->GetN();
G4double ipz = nbAtomsPerVolVect[ielem]/totNbAtomsPerVol;
G4double dum = ipz*zet*(zet+xi);
zs += dum;
ze += dum*(-2.0/3.0)*G4Log(zet);
zx += dum*G4Log(1.0+3.34*finstrc2*zet*zet);
sa += ipz*iwa;
}
G4double density = mat->GetDensity()*CLHEP::cm3/CLHEP::g; // [g/cm3]
//
moliereBc = const1*density*zs/sa*G4Exp(ze/zs)/G4Exp(zx/zs); //[1/cm]
moliereXc2 = const2*density*zs/sa; // [MeV2/cm]
// change to Geant4 internal units of 1/length and energ2/length
moliereBc *= 1.0/CLHEP::cm;
moliereXc2 *= CLHEP::MeV*CLHEP::MeV/CLHEP::cm;
//
// 2. loop over the kinetic energy grid
for (G4int iek=0; iek<gNumEkin; ++iek) {
// 2./a. set current kinetic energy and pt2 value
G4double ekin = G4Exp(fLogMinEkin+iek/fInvLogDelEkin);
G4double pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
if (ekin>gMidEkin) {
G4double b2 = fMinBeta2+(iek-(gNumEkin-gNumBeta2))/fInvDelBeta2;
ekin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-b2)-1.);
pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
}
// 2./b. loop over the elements at the current kinetic energy point
for (G4int ielem=0; ielem<numElems; ++ielem) {
const G4Element *elem = (*elemVect)[ielem];
G4double zet = elem->GetZ();
if (zet>gMaxZet) {
zet = (G4double)gMaxZet;
}
G4int izet = G4lrint(zet);
// xi should be one i.e. z(z+1) since total sub-threshold scattering power correction
G4double nZZPlus1 = nbAtomsPerVolVect[ielem]*zet*(zet+1.0)/totNbAtomsPerVol;
G4double Z23 = std::pow(zet,2./3.);
//
DataPerEkin *perElemPerEkin = fMCDataPerElement[izet]->fDataPerEkin[iek];
DataPerEkin *perMatPerEkin = perMat->fDataPerEkin[iek];
//
// 2./b./(i) Add the 3 Mott-correction factors
G4double mcScrCF = perElemPerEkin->fMCScreening; // \kappa_i[1.13+3.76(\alpha Z_i)^2] with \kappa_i=scr_mc/scr_sr
// compute the screening parameter correction factor (Z_i contribution to the material)
// src_{mc} = C \exp\left[ \frac{ \sum_i n_i Z_i(Z_i+1)\ln[Z_{i}^{2/3}\kappa_i(1.13+3.76(\alpha Z_i)^2)] } {\sum_i n_i Z_i(Z_i+1)}
// with C = \frac{(mc^2)^\alpha^2} {4(pc)^2 C_{TF}^2} = constFactor/(4*(pc)^2)
// here we compute the \sum_i n_i Z_i(Z_i+1)\ln[Z_{i}^{2/3}\kappa_i(1.13+3.76(\alpha Z_i)^2)] part
perMatPerEkin->fMCScreening += nZZPlus1*G4Log(Z23*mcScrCF);
// compute the corrected screening parameter for the current Z_i and E_{kin}
// src(Z_i)_{mc} = \frac{(mc^2)^\alpha^2 Z_i^{2/3}} {4(pc)^2 C_{TF}^2} \kappa_i[1.13+3.76(\alpha Z_i)^2]
mcScrCF *= constFactor*Z23/(4.*pt2);
// compute first moment correction factor
// q1_{mc} = \frac{ \sum_i n_i Z_i(Z_i+1) A_i B_i } {\sum_i n_i Z_i(Z_i+1)} \frac{1}{C}
// where:
// A_i(src(Z_i)_{mc}) = [\ln(1+1/src(Z_i)_{mc}) - 1/(1+src(Z_i)_{mc})]; where \sigma(Z_i)_{tr1}^(sr) = A_i(src(Z_i)_{mc}) [2\pi r_0 Z_i mc^2/(pc)\beta]^2
// B_i = \beta_i \gamma_i with beta_i(Z_i) = \sigma(Z_i)_{tr1}^(PWA)/\sigma(Z_i,src(Z_i)_{mc})_{tr1}^(sr)
// and \gamma_i = \sigma(Z_i)_{el}^(MC-DCS)/\sigma(Z_i,src(Z_i)_{mc})_{el}^(sr)
// C(src_{mc}) = [\ln(1+1/src_{mc}) - 1/(1+src_{mc})]; where \sigma_{tr1}^(sr) = C(src_{mc}) [2\pi r_0 Z_i mc^2/(pc)\beta]^2
// A_i x B_i is stored in file per e-/e+, E_{kin} and Z_i
// here we compute the \sum_i n_i Z_i(Z_i+1) A_i B_i part
perMatPerEkin->fMCFirstMoment += nZZPlus1*(G4Log(1.+1./mcScrCF)-1./(1.+mcScrCF))*perElemPerEkin->fMCFirstMoment;
// compute the second moment correction factor
// [G2/G1]_{mc} = \frac{ \sum_i n_i Z_i(Z_i+1) A_i } {\sum_i n_i Z_i(Z_i+1)} \frac{1}{C}
// with A_i(Z_i) = G2(Z_i)^{PWA}/G1(Z_i)^{PWA} and C=G2(Z_i,scr_{mc})^{sr}/G1(Z_i,scr_{mc})^{sr}}
// here we compute the \sum_i n_i Z_i(Z_i+1) A_i part
perMatPerEkin->fMCSecondMoment += nZZPlus1*perElemPerEkin->fMCSecondMoment;
//
// 2./b./(ii) Go for the rejection funtion part
// I. loop over delta values
for (G4int idel=0; idel<gNumDelta; ++idel) {
DataPerDelta *perMatPerDelta = perMatPerEkin->fDataPerDelta[idel];
DataPerDelta *perElemPerDelta = perElemPerEkin->fDataPerDelta[idel];
// I./a. loop over angles (i.e. the \sin(0.5\theta) values) and add the rejection function
for (G4int iang=0; iang<gNumAngle; ++iang) {
perMatPerDelta->fRejFuntion[iang] += nZZPlus1*perElemPerDelta->fRejFuntion[iang];
}
// I./b. get the last bin spline parameters and add them (a+bx+cx^2+dx^3)
perMatPerDelta->fSA += nZZPlus1*perElemPerDelta->fSA;
perMatPerDelta->fSB += nZZPlus1*perElemPerDelta->fSB;
perMatPerDelta->fSC += nZZPlus1*perElemPerDelta->fSC;
perMatPerDelta->fSD += nZZPlus1*perElemPerDelta->fSD;
}
//
// 2./b./(iii) When the last element has been added:
if (ielem==numElems-1) {
//
// 1. the remaining part of the sreening correction and divide the corrected screening par. with Moliere's one:
// (Moliere screening parameter = moliereXc2/(4(pc)^2 moliereBc) )
G4double dumScr = G4Exp(perMatPerEkin->fMCScreening/zs);
perMatPerEkin->fMCScreening = constFactor*dumScr*moliereBc/moliereXc2;
//
// 2. the remaining part of the first moment correction and divide by the one computed by using the corrected
// screening parameter (= (mc^2)^\alpha^2/(4(pc)^2C_{TF}^2) dumScr
G4double scrCorTed = constFactor*dumScr/(4.*pt2);
G4double dum0 = G4Log(1.+1./scrCorTed);
perMatPerEkin->fMCFirstMoment = perMatPerEkin->fMCFirstMoment/(zs*(dum0-1./(1.-scrCorTed)));
//
// 3. the remaining part of the second moment correction and divide by the one computed by using the corrected
// screening parameter
G4double G2PerG1 = 3.*(1.+scrCorTed)*((1.+2.*scrCorTed)*dum0-2.)/((1.+scrCorTed)*dum0-1.);
perMatPerEkin->fMCSecondMoment = perMatPerEkin->fMCSecondMoment/(zs*G2PerG1);
//
// 4. scale the maximum of the rejection function to unity and correct the last bin spline parameters as well
// I. loop over delta values
for (G4int idel=0; idel<gNumDelta; ++idel) {
DataPerDelta *perMatPerDelta = perMatPerEkin->fDataPerDelta[idel];
G4double maxVal = -1.;
// II. llop over angles
for (G4int iang=0; iang<gNumAngle; ++iang) {
if (perMatPerDelta->fRejFuntion[iang]>maxVal)
maxVal = perMatPerDelta->fRejFuntion[iang];
}
for (G4int iang=0; iang<gNumAngle; ++iang) {
perMatPerDelta->fRejFuntion[iang] /=maxVal;
}
perMatPerDelta->fSA /= maxVal;
perMatPerDelta->fSB /= maxVal;
perMatPerDelta->fSC /= maxVal;
perMatPerDelta->fSD /= maxVal;
}
}
}
}
}
void G4GSMottCorrection::AllocateDataPerMaterial(DataPerMaterial *data) {
data->fDataPerEkin = new DataPerEkin*[gNumEkin]();
for (G4int iek=0; iek<gNumEkin; ++iek) {
DataPerEkin *perEkin = new DataPerEkin();
perEkin->fDataPerDelta = new DataPerDelta*[gNumDelta]();
for (G4int idel=0; idel<gNumDelta; ++idel) {
DataPerDelta *perDelta = new DataPerDelta();
perDelta->fRejFuntion = new double[gNumAngle]();
perEkin->fDataPerDelta[idel] = perDelta;
}
data->fDataPerEkin[iek] = perEkin;
}
}
void G4GSMottCorrection::DeAllocateDataPerMaterial(DataPerMaterial *data) {
for (G4int iek=0; iek<gNumEkin; ++iek) {
DataPerEkin *perEkin = data->fDataPerEkin[iek]; //new DataPerEkin();
for (G4int idel=0; idel<gNumDelta; ++idel) {
DataPerDelta *perDelta = perEkin->fDataPerDelta[idel];
delete [] perDelta->fRejFuntion;
delete perDelta;
}
delete [] perEkin->fDataPerDelta;
delete perEkin;
}
delete [] data->fDataPerEkin;
}
void G4GSMottCorrection::ClearMCDataPerElement() {
for (size_t i=0; i<fMCDataPerElement.size(); ++i) {
if (fMCDataPerElement[i]) {
DeAllocateDataPerMaterial(fMCDataPerElement[i]);
delete fMCDataPerElement[i];
}
}
fMCDataPerElement.clear();
}
void G4GSMottCorrection::ClearMCDataPerMaterial() {
for (size_t i=0; i<fMCDataPerMaterial.size(); ++i) {
if (fMCDataPerMaterial[i]) {
DeAllocateDataPerMaterial(fMCDataPerMaterial[i]);
delete fMCDataPerMaterial[i];
}
}
fMCDataPerMaterial.clear();
}
@@ -0,0 +1,368 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: $
//
// ----------------------------------------------------------------------------
//
//
// File name: G4GSPWACorrections
//
// Author: Mihaly Novak
//
// Creation date: 17.10.2017
//
// Modifications:
//
// Class description: see the header file.
//
// -----------------------------------------------------------------------------
#include "G4GSPWACorrections.hh"
#include "G4PhysicalConstants.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
#include "G4ProductionCutsTable.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4Material.hh"
#include "G4ElementVector.hh"
#include "G4Element.hh"
const std::string G4GSPWACorrections::gElemSymbols[] = {"H","He","Li","Be","B" ,
"C" ,"N" ,"O" ,"F" ,"Ne","Na","Mg","Al","Si","P" , "S","Cl","Ar","K" ,"Ca","Sc",
"Ti","V" ,"Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr","Rb",
"Sr","Y" ,"Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I" ,
"Xe","Cs","Ba","La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm",
"Yb","Lu","Hf","Ta","W" ,"Re","Os","Ir","Pt","Au","Hg","Tl","Pb","Bi","Po","At",
"Rn","Fr","Ra","Ac","Th","Pa","U" ,"Np","Pu","Am","Cm","Bk","Cf"};
G4GSPWACorrections::G4GSPWACorrections(G4bool iselectron) : fIsElectron(iselectron) {
// init grids related data member values
fMaxEkin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-gMaxBeta2)-1.);
fLogMinEkin = G4Log(gMinEkin);
fInvLogDelEkin = (gNumEkin-gNumBeta2)/G4Log(gMidEkin/gMinEkin);
G4double pt2 = gMidEkin*(gMidEkin+2.0*CLHEP::electron_mass_c2);
fMinBeta2 = pt2/(pt2+CLHEP::electron_mass_c2*CLHEP::electron_mass_c2);
fInvDelBeta2 = (gNumBeta2-1.)/(gMaxBeta2-fMinBeta2);
}
G4GSPWACorrections::~G4GSPWACorrections() {
ClearDataPerElement();
ClearDataPerMaterial();
}
void G4GSPWACorrections::GetPWACorrectionFactors(G4double logekin, G4double beta2, G4int matindx,
G4double &corToScr, G4double &corToQ1, G4double &corToG2PerG1) {
G4int ekinIndxLow = 0;
G4double remRfaction = 0.;
if (beta2>=gMaxBeta2) {
ekinIndxLow = gNumEkin - 1;
// remRfaction = -1.
} else if (beta2>=fMinBeta2) { // linear interpolation on \beta^2
remRfaction = (beta2 - fMinBeta2) * fInvDelBeta2;
ekinIndxLow = (G4int)remRfaction;
remRfaction -= ekinIndxLow;
ekinIndxLow += (gNumEkin - gNumBeta2);
} else if (logekin>=fLogMinEkin) {
remRfaction = (logekin - fLogMinEkin) * fInvLogDelEkin;
ekinIndxLow = (G4int)remRfaction;
remRfaction -= ekinIndxLow;
} // the defaults otherwise i.e. use the lowest energy values when ekin is smaller than the minum ekin
//
DataPerMaterial *data = fDataPerMaterial[matindx];
corToScr = data->fCorScreening[ekinIndxLow];
corToQ1 = data->fCorFirstMoment[ekinIndxLow];
corToG2PerG1 = data->fCorSecondMoment[ekinIndxLow];
if (remRfaction>0.) {
corToScr += remRfaction*(data->fCorScreening[ekinIndxLow+1] - data->fCorScreening[ekinIndxLow]);
corToQ1 += remRfaction*(data->fCorFirstMoment[ekinIndxLow+1] - data->fCorFirstMoment[ekinIndxLow]);
corToG2PerG1 += remRfaction*(data->fCorSecondMoment[ekinIndxLow+1] - data->fCorSecondMoment[ekinIndxLow]);
}
}
void G4GSPWACorrections::Initialise() {
// load PWA correction data for each elements that belongs to materials that are used in the detector
InitDataPerElement();
// clear PWA correction data per material
ClearDataPerMaterial();
// initialise PWA correction data for the materials that are used in the detector
InitDataPerMaterials();
}
void G4GSPWACorrections::InitDataPerElement() {
// do it only once
if (fDataPerElement.size()<gMaxZet+1) {
fDataPerElement.resize(gMaxZet+1,nullptr);
}
// loop over all materials, for those that are used check the list of elements and load data from file if the
// corresponding data has not been loaded yet
G4ProductionCutsTable *thePCTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numMatCuts = thePCTable->GetTableSize();
for (size_t imc=0; imc<numMatCuts; ++imc) {
const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
if (!matCut->IsUsed()) {
continue;
}
const G4Material *mat = matCut->GetMaterial();
const G4ElementVector *elemVect = mat->GetElementVector();
//
size_t numElems = elemVect->size();
for (size_t ielem=0; ielem<numElems; ++ielem) {
const G4Element *elem = (*elemVect)[ielem];
G4int izet = G4lrint(elem->GetZ());
if (izet>gMaxZet) {
izet = gMaxZet;
}
if (!fDataPerElement[izet]) {
LoadDataElement(elem);
}
}
}
}
void G4GSPWACorrections::InitDataPerMaterials() {
// prepare size of the container
size_t numMaterials = G4Material::GetNumberOfMaterials();
if (fDataPerMaterial.size()!=numMaterials) {
fDataPerMaterial.resize(numMaterials);
}
// init. PWA correction data for the Materials that are used in the geometry
G4ProductionCutsTable *thePCTable = G4ProductionCutsTable::GetProductionCutsTable();
size_t numMatCuts = thePCTable->GetTableSize();
for (size_t imc=0; imc<numMatCuts; ++imc) {
const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
if (!matCut->IsUsed()) {
continue;
}
const G4Material *mat = matCut->GetMaterial();
if (!fDataPerMaterial[mat->GetIndex()]) {
InitDataMaterial(mat);
}
}
}
// it's called only if data has not been loaded for this element yet
void G4GSPWACorrections::LoadDataElement(const G4Element *elem) {
// allocate memory
G4int izet = G4lrint(elem->GetZ());
if (izet>gMaxZet) {
izet = gMaxZet;
}
// load data from file
char* tmppath = getenv("G4LEDATA");
if (!tmppath) {
G4Exception("G4GSPWACorrection::LoadDataElement()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
return;
}
std::string path(tmppath);
if (fIsElectron) {
path += "/msc_GS/PWACor/el/";
} else {
path += "/msc_GS/PWACor/pos/";
}
std::string fname = path+"cf_"+gElemSymbols[izet-1];
std::ifstream infile(fname,std::ios::in);
if (!infile.is_open()) {
std::string msg = " Problem while trying to read " + fname + " data file.\n";
G4Exception("G4GSPWACorrection::LoadDataElement","em0006", FatalException,msg.c_str());
return;
}
// allocate data structure
DataPerMaterial *perElem = new DataPerMaterial();
perElem->fCorScreening.resize(gNumEkin,0.0);
perElem->fCorFirstMoment.resize(gNumEkin,0.0);
perElem->fCorSecondMoment.resize(gNumEkin,0.0);
fDataPerElement[izet] = perElem;
G4double dum0;
for (G4int iek=0; iek<gNumEkin; ++iek) {
infile >> dum0;
infile >> perElem->fCorScreening[iek];
infile >> perElem->fCorFirstMoment[iek];
infile >> perElem->fCorSecondMoment[iek];
}
infile.close();
}
void G4GSPWACorrections::InitDataMaterial(const G4Material *mat) {
constexpr G4double const1 = 7821.6; // [cm2/g]
constexpr G4double const2 = 0.1569; // [cm2 MeV2 / g]
constexpr G4double finstrc2 = 5.325135453E-5; // fine-structure const. square
G4double constFactor = CLHEP::electron_mass_c2*CLHEP::fine_structure_const/0.88534;
constFactor *= constFactor; // (mc^2)^2\alpha^2/( C_{TF}^2)
// allocate memory
DataPerMaterial *perMat = new DataPerMaterial();
perMat->fCorScreening.resize(gNumEkin,0.0);
perMat->fCorFirstMoment.resize(gNumEkin,0.0);
perMat->fCorSecondMoment.resize(gNumEkin,0.0);
fDataPerMaterial[mat->GetIndex()] = perMat;
//
const G4ElementVector* elemVect = mat->GetElementVector();
const G4int numElems = mat->GetNumberOfElements();
const G4double* nbAtomsPerVolVect = mat->GetVecNbOfAtomsPerVolume();
G4double totNbAtomsPerVol = mat->GetTotNbOfAtomsPerVolume();
//
// 1. Compute material dependent part of Moliere's b_c \chi_c^2
// (with \xi=1 (i.e. total sub-threshold scattering power correction)
G4double moliereBc = 0.0;
G4double moliereXc2 = 0.0;
G4double zs = 0.0;
G4double ze = 0.0;
G4double zx = 0.0;
G4double sa = 0.0;
G4double xi = 1.0;
for (G4int ielem=0; ielem<numElems; ++ielem) {
G4double zet = (*elemVect)[ielem]->GetZ();
if (zet>gMaxZet) {
zet = (G4double)gMaxZet;
}
G4double iwa = (*elemVect)[ielem]->GetN();
G4double ipz = nbAtomsPerVolVect[ielem]/totNbAtomsPerVol;
G4double dum = ipz*zet*(zet+xi);
zs += dum;
ze += dum*(-2.0/3.0)*G4Log(zet);
zx += dum*G4Log(1.0+3.34*finstrc2*zet*zet);
sa += ipz*iwa;
}
G4double density = mat->GetDensity()*CLHEP::cm3/CLHEP::g; // [g/cm3]
//
moliereBc = const1*density*zs/sa*G4Exp(ze/zs)/G4Exp(zx/zs); //[1/cm]
moliereXc2 = const2*density*zs/sa; // [MeV2/cm]
// change to Geant4 internal units of 1/length and energ2/length
moliereBc *= 1.0/CLHEP::cm;
moliereXc2 *= CLHEP::MeV*CLHEP::MeV/CLHEP::cm;
//
// 2. loop over the kinetic energy grid
for (G4int iek=0; iek<gNumEkin; ++iek) {
// 2./a. set current kinetic energy and pt2 value
G4double ekin = G4Exp(fLogMinEkin+iek/fInvLogDelEkin);
G4double pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
if (ekin>gMidEkin) {
G4double b2 = fMinBeta2+(iek-(gNumEkin-gNumBeta2))/fInvDelBeta2;
ekin = CLHEP::electron_mass_c2*(1./std::sqrt(1.-b2)-1.);
pt2 = ekin*(ekin+2.0*CLHEP::electron_mass_c2);
}
// 2./b. loop over the elements at the current kinetic energy point
for (G4int ielem=0; ielem<numElems; ++ielem) {
const G4Element *elem = (*elemVect)[ielem];
G4double zet = elem->GetZ();
if (zet>gMaxZet) {
zet = (G4double)gMaxZet;
}
G4int izet = G4lrint(zet);
// loaded PWA corrections for the current element
DataPerMaterial *perElem = fDataPerElement[izet];
//
// xi should be one i.e. z(z+1) since total sub-threshold scattering power correction
G4double nZZPlus1 = nbAtomsPerVolVect[ielem]*zet*(zet+1.0)/totNbAtomsPerVol;
G4double Z23 = std::pow(zet,2./3.);
//
// 2./b./(i) Add the 3 PWA correction factors
G4double mcScrCF = perElem->fCorScreening[iek]; // \kappa_i[1.13+3.76(\alpha Z_i)^2] with \kappa_i=scr_mc/scr_sr
// compute the screening parameter correction factor (Z_i contribution to the material)
// src_{mc} = C \exp\left[ \frac{ \sum_i n_i Z_i(Z_i+1)\ln[Z_{i}^{2/3}\kappa_i(1.13+3.76(\alpha Z_i)^2)] } {\sum_i n_i Z_i(Z_i+1)}
// with C = \frac{(mc^2)^\alpha^2} {4(pc)^2 C_{TF}^2} = constFactor/(4*(pc)^2)
// here we compute the \sum_i n_i Z_i(Z_i+1)\ln[Z_{i}^{2/3}\kappa_i(1.13+3.76(\alpha Z_i)^2)] part
perMat->fCorScreening[iek] += nZZPlus1*G4Log(Z23*mcScrCF);
// compute the corrected screening parameter for the current Z_i and E_{kin}
// src(Z_i)_{mc} = \frac{(mc^2)^\alpha^2 Z_i^{2/3}} {4(pc)^2 C_{TF}^2} \kappa_i[1.13+3.76(\alpha Z_i)^2]
mcScrCF *= constFactor*Z23/(4.*pt2);
// compute first moment correction factor
// q1_{mc} = \frac{ \sum_i n_i Z_i(Z_i+1) A_i B_i } {\sum_i n_i Z_i(Z_i+1)} \frac{1}{C}
// where:
// A_i(src(Z_i)_{mc}) = [\ln(1+1/src(Z_i)_{mc}) - 1/(1+src(Z_i)_{mc})]; where \sigma(Z_i)_{tr1}^(sr) = A_i(src(Z_i)_{mc}) [2\pi r_0 Z_i mc^2/(pc)\beta]^2
// B_i = \beta_i \gamma_i with beta_i(Z_i) = \sigma(Z_i)_{tr1}^(PWA)/\sigma(Z_i,src(Z_i)_{mc})_{tr1}^(sr)
// and \gamma_i = \sigma(Z_i)_{el}^(MC-DCS)/\sigma(Z_i,src(Z_i)_{mc})_{el}^(sr)
// C(src_{mc}) = [\ln(1+1/src_{mc}) - 1/(1+src_{mc})]; where \sigma_{tr1}^(sr) = C(src_{mc}) [2\pi r_0 Z_i mc^2/(pc)\beta]^2
// A_i x B_i is stored in file per e-/e+, E_{kin} and Z_i
// here we compute the \sum_i n_i Z_i(Z_i+1) A_i B_i part
perMat->fCorFirstMoment[iek] += nZZPlus1*(G4Log(1.+1./mcScrCF)-1./(1.+mcScrCF))*perElem->fCorFirstMoment[iek];
// compute the second moment correction factor
// [G2/G1]_{mc} = \frac{ \sum_i n_i Z_i(Z_i+1) A_i } {\sum_i n_i Z_i(Z_i+1)} \frac{1}{C}
// with A_i(Z_i) = G2(Z_i)^{PWA}/G1(Z_i)^{PWA} and C=G2(Z_i,scr_{mc})^{sr}/G1(Z_i,scr_{mc})^{sr}}
// here we compute the \sum_i n_i Z_i(Z_i+1) A_i part
perMat->fCorSecondMoment[iek] += nZZPlus1*perElem->fCorSecondMoment[iek];
//
// 2./b./(ii) When the last element has been added:
if (ielem==numElems-1) {
//
// 1. the remaining part of the sreening correction and divide the corrected screening par. with Moliere's one:
// (Moliere screening parameter = moliereXc2/(4(pc)^2 moliereBc) )
G4double dumScr = G4Exp(perMat->fCorScreening[iek]/zs);
perMat->fCorScreening[iek] = constFactor*dumScr*moliereBc/moliereXc2;
//
// 2. the remaining part of the first moment correction and divide by the one computed by using the corrected
// screening parameter (= (mc^2)^\alpha^2/(4(pc)^2C_{TF}^2) dumScr
G4double scrCorTed = constFactor*dumScr/(4.*pt2);
G4double dum0 = G4Log(1.+1./scrCorTed);
perMat->fCorFirstMoment[iek] = perMat->fCorFirstMoment[iek]/(zs*(dum0-1./(1.-scrCorTed)));
//
// 3. the remaining part of the second moment correction and divide by the one computed by using the corrected
// screening parameter
G4double G2PerG1 = 3.*(1.+scrCorTed)*((1.+2.*scrCorTed)*dum0-2.)/((1.+scrCorTed)*dum0-1.);
perMat->fCorSecondMoment[iek] = perMat->fCorSecondMoment[iek]/(zs*G2PerG1);
}
}
}
}
void G4GSPWACorrections::ClearDataPerElement() {
for (size_t i=0; i<fDataPerElement.size(); ++i) {
if (fDataPerElement[i]) {
fDataPerElement[i]->fCorScreening.clear();
fDataPerElement[i]->fCorFirstMoment.clear();
fDataPerElement[i]->fCorSecondMoment.clear();
delete fDataPerElement[i];
}
}
fDataPerElement.clear();
}
void G4GSPWACorrections::ClearDataPerMaterial() {
for (size_t i=0; i<fDataPerMaterial.size(); ++i) {
if (fDataPerMaterial[i]) {
fDataPerMaterial[i]->fCorScreening.clear();
fDataPerMaterial[i]->fCorFirstMoment.clear();
fDataPerMaterial[i]->fCorSecondMoment.clear();
delete fDataPerMaterial[i];
}
}
fDataPerMaterial.clear();
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4GammaConversion.cc 84598 2014-10-17 07:39:15Z gcosmo $
// $Id: G4GammaConversion.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
//
//------------------ G4GammaConversion physics process -------------------------
@@ -114,16 +114,16 @@ void G4GammaConversion::InitialiseProcess(const G4ParticleDefinition*)
SetMinKinEnergy(emin);
if(!EmModel(1)) { SetEmModel(new G4BetheHeitlerModel(), 1); }
EmModel(1)->SetLowEnergyLimit(emin);
EmModel(1)->SetHighEnergyLimit(energyLimit);
AddEmModel(1, EmModel(1));
if(!EmModel(0)) { SetEmModel(new G4BetheHeitlerModel()); }
EmModel(0)->SetLowEnergyLimit(emin);
EmModel(0)->SetHighEnergyLimit(energyLimit);
AddEmModel(1, EmModel(0));
if(emax > energyLimit) {
if(!EmModel(2)) { SetEmModel(new G4PairProductionRelModel(), 2); }
EmModel(2)->SetLowEnergyLimit(energyLimit);
EmModel(2)->SetHighEnergyLimit(emax);
AddEmModel(2, EmModel(2));
if(!EmModel(1)) { SetEmModel(new G4PairProductionRelModel()); }
EmModel(1)->SetLowEnergyLimit(energyLimit);
EmModel(1)->SetHighEnergyLimit(emax);
AddEmModel(1, EmModel(1));
}
}
}
@@ -142,3 +142,11 @@ void G4GammaConversion::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4GammaConversion::ProcessDescription(std::ostream& out) const
{
out << "<strong>Gamma conversion</strong>";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ICRU49NuclearStoppingModel.cc 103955 2017-05-04 11:29:54Z gcosmo $
// $Id: G4ICRU49NuclearStoppingModel.cc 106442 2017-10-10 08:00:30Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -130,7 +130,7 @@ G4ICRU49NuclearStoppingModel::ComputeDEDXPerVolume(
// projectile
G4double mass1 = p->GetPDGMass();
G4double z1 = std::fabs(p->GetPDGCharge()/eplus);
G4double z1 = std::abs(p->GetPDGCharge()/eplus);
if(kinEnergy*proton_mass_c2/mass1 > z1*z1*MeV) { return nloss; }
@@ -69,7 +69,7 @@ using namespace std;
G4MottCoefficients::G4MottCoefficients()
{
fG4pow = G4Pow::GetInstance();
fG4pow = G4Pow::GetInstance();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -80,6 +80,124 @@ G4MottCoefficients::~G4MottCoefficients()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MottCoefficients::GetTransitionRandom(G4double Z, G4double energy){
static const G4double prm[92][11]={
{-3.45427,-1.17273,-0.674098,0.00696853,0.141878,0.0121233,-0.018557,0.00236715,-0.000372957,0.000177557,-2.10679e-05},
{-3.29628,-1.18151,-0.703359,0.0103044,0.163054,0.0115247,-0.0215392,0.00261679,-0.000348795,0.000209188,-2.68608e-05},
{-3.21835,-1.18266,-0.735985,0.0115607,0.187515,0.0101161,-0.0252226,0.00302583,-0.00031054,0.00024924,-3.53293e-05},
{-3.1717,-1.14925,-0.790004,-0.0198764,0.234438,0.0105132,-0.033369,0.00468367,-0.000489407,0.000336593,-4.92297e-05},
{-3.17209,-1.22705,-0.688282,0.0457405,0.159246,0.0111483,-0.0209024,0.00159142,-5.23442e-05,0.000192063,-2.82055e-05},
{-3.16083,-1.22387,-0.70212,0.0399292,0.171785,0.0119655,-0.0233146,0.00193347,-6.22793e-05,0.000213781,-3.21789e-05},
{-3.15413,-1.19529,-0.746885,0.00939304,0.211887,0.0152694,-0.0314518,0.00326366,-0.000138169,0.00028801,-4.55196e-05},
{-3.17206,-1.22774,-0.698953,0.0372708,0.18142,0.0152531,-0.0263482,0.00200525,2.7775e-05,0.000234207,-3.74789e-05},
{-3.17449,-1.20587,-0.734414,0.00491526,0.217546,0.0215135,-0.0349861,0.0032042,-4.9299e-06,0.000307788,-5.12635e-05},
{-3.1924,-1.23048,-0.698328,0.0268472,0.184787,0.0260339,-0.0279849,-0.000229421,0.000577754,0.000276219,-5.16374e-05},
{-3.2049,-1.24254,-0.706055,0.0356984,0.19275,0.0245999,-0.029428,-4.55243e-05,0.000620556,0.000286538,-5.49918e-05},
{-3.22766,-1.24018,-0.699531,0.0292779,0.194941,0.0272524,-0.0304795,-0.000102565,0.000639556,0.000298322,-5.69012e-05},
{-3.24588,-1.2344,-0.705018,0.0181285,0.206355,0.0312091,-0.0340683,0.000193923,0.000686569,0.000325252,-6.30398e-05},
{-3.26373,-1.23951,-0.70502,0.0212337,0.20878,0.0312006,-0.0347649,0.000306563,0.000692132,0.000328136,-6.38534e-05},
{-3.28305,-1.23997,-0.710294,0.0142502,0.219202,0.0349216,-0.038322,0.00061188,0.000739166,0.000355053,-7.00194e-05},
{-3.30593,-1.23538,-0.703515,0.00260105,0.22212,0.040248,-0.040836,0.000805208,0.000736592,0.000373285,-7.28831e-05},
{-3.33916,-1.22704,-0.625808,-0.0575292,0.17402,0.0944467,-0.0434333,-0.0092778,0.00412198,2.87672e-05,-6.93206e-05},
{-3.36453,-1.21502,-0.609634,-0.0965305,0.17717,0.117298,-0.0512211,-0.0108645,0.00501469,-3.45852e-05,-7.5006e-05},
{-3.38155,-1.43456,-0.609212,0.270927,0.107979,-0.0306118,-0.00218581,-1.34583e-05,-0.000136473,0.000111238,-1.07532e-05},
{-3.40227,-1.40841,-0.634279,0.25675,0.126197,-0.0331101,-0.00316589,0.00023027,-0.000190379,0.000129144,-1.26628e-05},
{-3.39149,-1.34102,-0.799316,0.211216,0.241378,-0.0375171,-0.023294,0.00279561,0.000871935,-5.13124e-05,-1.41801e-05},
{-2.4747,-0.673854,-0.949469,-0.150542,0.272209,0.0188266,-0.0308029,0.000659245,0.00130619,-0.000117714,-3.56591e-06},
{-2.23681,-0.925239,-0.747925,-0.0739567,0.170753,0.0137901,-0.0155923,0.000134395,0.000465198,-6.45333e-05,7.19535e-06},
{-2.11934,-1.01535,-0.609797,-0.055407,0.0974267,0.014963,-0.00347492,-0.000553922,-0.000278579,-1.42579e-05,1.83269e-05},
{-2.00521,-1.03932,-0.6315,-0.0662658,0.09963,0.018045,-0.00354355,-0.000700334,-0.000299444,-1.79189e-05,2.05635e-05},
{-1.92535,-1.05016,-0.611446,-0.0595249,0.0924364,0.0166651,-0.00304578,-0.00064247,-0.000285856,-1.58822e-05,1.8711e-05},
{-1.85487,-1.0455,-0.595443,-0.0568245,0.0869614,0.0156046,-0.00261736,-0.000574645,-0.000286237,-1.46623e-05,1.75923e-05},
{-1.78958,-1.03358,-0.593189,-0.066245,0.0851314,0.0169641,-0.00254946,-0.00058829,-0.00028881,-1.94165e-05,1.84522e-05},
{-1.7312,-1.03187,-0.595721,-0.0687198,0.0844325,0.0173088,-0.00241511,-0.000603525,-0.000298154,-1.85105e-05,1.85247e-05},
{-1.67552,-1.02443,-0.595395,-0.072281,0.0828622,0.017723,-0.00225957,-0.000610151,-0.000302192,-1.94811e-05,1.86356e-05},
{-1.62282,-1.01332,-0.602885,-0.0787764,0.0838998,0.0185986,-0.00230456,-0.000621724,-0.000310777,-2.11935e-05,1.92922e-05},
{-1.57541,-1.00961,-0.606542,-0.0805026,0.0839081,0.018709,-0.00229554,-0.000614519,-0.000311766,-2.125e-05,1.92361e-05},
{-1.53386,-1.00016,-0.607855,-0.0861356,0.0831995,0.0195493,-0.00219244,-0.000638326,-0.000322125,-2.25062e-05,1.98282e-05},
{-1.49079,-0.993843,-0.608259,-0.0892669,0.0825349,0.020055,-0.00218695,-0.000646426,-0.000319155,-2.4519e-05,2.00785e-05},
{-1.45611,-0.989,-0.609355,-0.0925922,0.0819072,0.0204973,-0.00209186,-0.000657213,-0.000327024,-2.4845e-05,2.03551e-05},
{-1.41871,-0.982753,-0.613789,-0.0939993,0.0823134,0.0206126,-0.00207367,-0.000661344,-0.00033119,-2.43004e-05,2.03755e-05},
{-1.3876,-0.974781,-0.612345,-0.0976259,0.0813288,0.0210619,-0.00201616,-0.000665815,-0.00033189,-2.53876e-05,2.04942e-05},
{-1.35484,-0.968802,-0.612766,-0.0987116,0.080421,0.0210492,-0.00192582,-0.000655693,-0.000331531,-2.55126e-05,2.025e-05},
{-1.34772,-1.00326,-0.556153,-0.0424339,0.070231,0.0104262,-0.00175413,-0.000279392,-0.000219016,-7.48141e-06,1.08526e-05},
{-1.32033,-0.998614,-0.556946,-0.0433613,0.0698885,0.0104265,-0.00173528,-0.000269835,-0.00021763,-7.70613e-06,1.07236e-05},
{-1.29387,-0.991914,-0.556351,-0.0433399,0.0690369,0.0101818,-0.00166188,-0.00025643,-0.000214616,-6.96604e-06,1.02468e-05},
{-1.26937,-0.984208,-0.559893,-0.0473158,0.0696842,0.0107802,-0.00169281,-0.000264224,-0.000223084,-8.77498e-06,1.10006e-05},
{-1.24606,-0.982953,-0.557063,-0.044914,0.0685251,0.010376,-0.00159731,-0.000266324,-0.000219274,-6.68118e-06,1.03695e-05},
{-1.22265,-0.977172,-0.560847,-0.0470713,0.069072,0.0107057,-0.00160698,-0.000277367,-0.00022425,-6.96396e-06,1.0673e-05},
{-1.20578,-0.971237,-0.557586,-0.0490051,0.067968,0.0109327,-0.00152961,-0.000278309,-0.000225988,-7.684e-06,1.07652e-05},
{-1.18467,-0.969531,-0.558205,-0.0474022,0.0680256,0.0106047,-0.00155372,-0.000264934,-0.000222263,-7.10051e-06,1.04828e-05},
{-1.16668,-0.962652,-0.557634,-0.0505,0.067703,0.0110136,-0.00156156,-0.000267733,-0.000221753,-8.39898e-06,1.06854e-05},
{-1.15074,-0.957517,-0.560071,-0.0541672,0.0682883,0.0117987,-0.0015924,-0.000298938,-0.000227628,-9.6769e-06,1.13059e-05},
{-1.13288,-0.957159,-0.557679,-0.049911,0.0674192,0.0109158,-0.00153791,-0.000266411,-0.00022149,-8.01081e-06,1.05714e-05},
{-1.1196,-0.950271,-0.559097,-0.0547589,0.0680769,0.0117711,-0.00166561,-0.000276567,-0.000219439,-1.12569e-05,1.12041e-05},
{-1.10563,-0.943237,-0.557926,-0.0565505,0.0681072,0.0120531,-0.00171725,-0.000282879,-0.000218682,-1.21928e-05,1.14843e-05},
{-1.09235,-0.941569,-0.560505,-0.0561123,0.0685157,0.0119646,-0.00169261,-0.000280428,-0.000223617,-1.1682e-05,1.15322e-05},
{-1.08165,-0.939346,-0.555938,-0.0560682,0.0673082,0.0119112,-0.0016401,-0.000274998,-0.000219648,-1.139e-05,1.11769e-05},
{-1.0696,-0.937992,-0.557616,-0.0570681,0.0680815,0.0121915,-0.00172775,-0.000284477,-0.000220627,-1.21141e-05,1.15469e-05},
{-1.05804,-0.937207,-0.558408,-0.0566075,0.0682875,0.012231,-0.00174882,-0.000293511,-0.000220088,-1.18869e-05,1.1573e-05},
{-1.0487,-0.93416,-0.559485,-0.0573018,0.0687981,0.0123716,-0.0017948,-0.000298165,-0.000220727,-1.20823e-05,1.17117e-05},
{-1.03853,-0.930536,-0.561213,-0.0596194,0.0693916,0.0127633,-0.0018757,-0.000302286,-0.00022093,-1.35729e-05,1.21118e-05},
{-1.03259,-0.931439,-0.556726,-0.0570483,0.0685184,0.0123419,-0.00183882,-0.000290425,-0.000216266,-1.27107e-05,1.16801e-05},
{-1.02709,-0.933279,-0.555008,-0.0568133,0.0682819,0.0124695,-0.00185261,-0.00029575,-0.000215381,-1.34199e-05,1.1844e-05},
{-1.01793,-0.929331,-0.562398,-0.0612057,0.070269,0.0133683,-0.00199229,-0.000324079,-0.000221687,-1.53905e-05,1.27335e-05},
{-1.01629,-0.929382,-0.55768,-0.061975,0.0694549,0.013656,-0.00198758,-0.000327635,-0.000220765,-1.71386e-05,1.30514e-05},
{-1.01017,-0.933211,-0.553837,-0.0563843,0.069119,0.0127631,-0.00202446,-0.000306269,-0.000209907,-1.50295e-05,1.22372e-05},
{-1.00402,-0.931527,-0.561663,-0.0614812,0.0714191,0.0138037,-0.00221284,-0.000334504,-0.000214929,-1.75699e-05,1.32174e-05},
{-1.00296,-0.935577,-0.556482,-0.0566492,0.0707889,0.0131248,-0.00222224,-0.000315959,-0.000207854,-1.66993e-05,1.2789e-05},
{-0.999308,-0.940971,-0.558419,-0.0565687,0.0713035,0.0134232,-0.00225806,-0.000337324,-0.000209122,-1.69497e-05,1.30385e-05},
{-0.99743,-0.937256,-0.558277,-0.0576755,0.0720174,0.0136793,-0.00232713,-0.000344131,-0.000212815,-1.77581e-05,1.34929e-05},
{-0.996147,-0.942928,-0.559895,-0.0571104,0.0728195,0.0138271,-0.00242734,-0.000350052,-0.000210827,-1.80175e-05,1.36015e-05},
{-0.997667,-0.950669,-0.555255,-0.0523833,0.0725868,0.0133248,-0.00251216,-0.000343447,-0.000199857,-1.73841e-05,1.32229e-05},
{-0.993545,-0.951196,-0.562655,-0.0541101,0.0747495,0.0136734,-0.00266748,-0.000346536,-0.000202929,-1.84821e-05,1.37021e-05},
{-0.996861,-0.959249,-0.558053,-0.0499803,0.0740782,0.0133638,-0.0026,-0.000356007,-0.000206035,-1.74446e-05,1.37177e-05},
{-0.998852,-0.959127,-0.559367,-0.0530054,0.0751304,0.0140818,-0.00276284,-0.000372799,-0.000203002,-1.99556e-05,1.43134e-05},
{-0.999091,-0.968269,-0.559251,-0.0479489,0.0758764,0.0134949,-0.00287584,-0.00036583,-0.000194827,-1.85467e-05,1.39202e-05},
{-1.00359,-0.972198,-0.556711,-0.0477494,0.0757621,0.0137758,-0.00288699,-0.000378367,-0.000197018,-1.97346e-05,1.43232e-05},
{-1.00288,-0.975142,-0.561481,-0.0490123,0.0775024,0.0142525,-0.00304164,-0.000397013,-0.000198895,-2.09334e-05,1.49274e-05},
{-1.00826,-0.98024,-0.560716,-0.0475238,0.0777307,0.0142664,-0.00306904,-0.000404107,-0.000198918,-2.11886e-05,1.50728e-05},
{-1.01165,-0.987835,-0.560303,-0.0449431,0.0786238,0.0141298,-0.00319235,-0.000406331,-0.000195207,-2.10731e-05,1.51339e-05},
{-1.018,-0.997307,-0.556998,-0.041257,0.0782376,0.0138629,-0.00318327,-0.000410616,-0.000192401,-2.05472e-05,1.49881e-05},
{-1.02086,-1.00489,-0.561339,-0.0386772,0.0800913,0.0137721,-0.00332262,-0.00041823,-0.000194708,-2.03251e-05,1.53389e-05},
{-1.02511,-1.00748,-0.563121,-0.0416363,0.0811907,0.0146575,-0.00349921,-0.000446843,-0.000191104,-2.32522e-05,1.60824e-05},
{-1.0274,-1.0166,-0.565418,-0.0382969,0.0822905,0.0143542,-0.00358594,-0.000445608,-0.000189679,-2.23899e-05,1.60135e-05},
{-1.03437,-1.02268,-0.565814,-0.035928,0.0832699,0.0142663,-0.00367908,-0.000454381,-0.000189162,-2.20657e-05,1.61487e-05},
{-1.04332,-1.02938,-0.561205,-0.0342207,0.0829085,0.0142911,-0.00371948,-0.000457825,-0.000185521,-2.29898e-05,1.6307e-05},
{-1.04429,-1.03749,-0.568732,-0.0314777,0.0849283,0.0140019,-0.00383956,-0.000454762,-0.00018503,-2.19763e-05,1.6222e-05},
{-1.04911,-1.04439,-0.571889,-0.0319427,0.0862762,0.0145259,-0.00395989,-0.000485614,-0.000187376,-2.29388e-05,1.68404e-05},
{-1.05909,-1.04857,-0.566255,-0.0309344,0.0861182,0.0147465,-0.00407832,-0.000497202,-0.000179714,-2.4611e-05,1.71362e-05},
{-1.06439,-1.05789,-0.570318,-0.0266983,0.0878402,0.0143828,-0.00418574,-0.000502199,-0.000180593,-2.32303e-05,1.71511e-05},
{-1.06775,-1.06261,-0.572843,-0.0257022,0.0889957,0.0143758,-0.00430065,-0.000498425,-0.000178364,-2.38618e-05,1.72926e-05},
{-1.07551,-1.06847,-0.571036,-0.0246921,0.088754,0.0145911,-0.00425427,-0.000527694,-0.000182927,-2.34593e-05,1.75615e-05},
{-1.07971,-1.0743,-0.571836,-0.0217792,0.0892357,0.0142461,-0.00430431,-0.000520164,-0.000178707,-2.28916e-05,1.73228e-05},
{-1.04956,-0.951005,-0.714805,-0.212099,0.178657,0.085347,-0.0264126,-0.010159,0.00231653,0.000412161,-8.84648e-05},
{-1.08715,-1.07732,-0.576722,-0.0221064,0.0917223,0.0146632,-0.0045922,-0.000535837,-0.000172049,-2.46466e-05,1.78337e-05},
{-1.09157,-1.07821,-0.57956,-0.0222743,0.0927873,0.0148675,-0.00463775,-0.000551921,-0.000176996,-2.45488e-05,1.81678e-05}
};
G4int indexZ=int(Z)-1;
G4double result=prm[indexZ][0]
+prm[indexZ][1]*log10(energy)
+prm[indexZ][2]*fG4pow->powN(log10(energy),2)
+prm[indexZ][3]*fG4pow->powN(log10(energy),3)
+prm[indexZ][4]*fG4pow->powN(log10(energy),4)
+prm[indexZ][5]*fG4pow->powN(log10(energy),5)
+prm[indexZ][6]*fG4pow->powN(log10(energy),6)
+prm[indexZ][7]*fG4pow->powN(log10(energy),7)
+prm[indexZ][8]*fG4pow->powN(log10(energy),8)
+prm[indexZ][9]*fG4pow->powN(log10(energy),9)
+prm[indexZ][10]*fG4pow->powN(log10(energy),10);
return G4Exp(G4Log(10)*result);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MottCoefficients::SetMottCoeff(G4double Z, G4double coeffb[5][6]){
//H.......................................
@@ -820,7 +938,7 @@ static const G4double bU[5][6]={
};
for(int j=0 ;j<5;j++){
for(int k=0;k<6;k++ ){
for(int k=0;k<6;k++ ){
if (Z==1)coeffb[j][k]= bH[j][k];
else if (Z==2)coeffb[j][k]= bHe[j][k];
else if (Z==3)coeffb[j][k]= bLi[j][k];
@@ -915,7 +1033,7 @@ static const G4double bU[5][6]={
else if (Z==92)coeffb[j][k]= bU[j][k];
else coeffb[j][k]=0;
}
}
}
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4NuclearStopping.cc 103955 2017-05-04 11:29:54Z gcosmo $
// $Id: G4NuclearStopping.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -----------------------------------------------------------------------------
//
@@ -82,10 +82,9 @@ void G4NuclearStopping::InitialiseProcess(const G4ParticleDefinition*)
if(!isInitialized) {
isInitialized = true;
if(!EmModel(1)) {
SetEmModel(new G4ICRU49NuclearStoppingModel());
}
if(!EmModel(0)) { SetEmModel(new G4ICRU49NuclearStoppingModel()); }
AddEmModel(1, EmModel());
EmModel()->SetActivationHighEnergyLimit(10*GeV);
EmModel()->SetParticleChange(&nParticleChange);
}
}
@@ -115,8 +114,9 @@ G4VParticleChange* G4NuclearStopping::AlongStepDoIt(const G4Track& track,
const G4ParticleDefinition* part = track.GetParticleDefinition();
G4double Z = std::abs(part->GetPDGCharge()/eplus);
G4double massR = proton_mass_c2/part->GetPDGMass();
if(T2 > 0.0 && T2*proton_mass_c2 < Z*Z*MeV*part->GetPDGMass()) {
if(T2 > 0.0 && T2*massR < Z*Z*MeV) {
G4double length = step.GetStepLength();
if(length > 0.0) {
@@ -125,15 +125,18 @@ G4VParticleChange* G4NuclearStopping::AlongStepDoIt(const G4Track& track,
G4double T1= step.GetPreStepPoint()->GetKineticEnergy();
G4double T = 0.5*(T1 + T2);
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
G4VEmModel* mod = SelectModel(T, couple->GetIndex());
G4double Tscaled = T*massR;
G4VEmModel* mod = SelectModel(Tscaled, couple->GetIndex());
// sample stopping
G4double nloss =
length*mod->ComputeDEDXPerVolume(couple->GetMaterial(), part, T);
if(nloss > T1) { nloss = T1; }
nParticleChange.SetProposedKineticEnergy(T1 - nloss);
nParticleChange.ProposeLocalEnergyDeposit(nloss);
nParticleChange.ProposeNonIonizingEnergyDeposit(nloss);
if(mod->IsActive(Tscaled)) {
G4double nloss =
length*mod->ComputeDEDXPerVolume(couple->GetMaterial(), part, T);
nloss = std::min(nloss, T1);
nParticleChange.SetProposedKineticEnergy(T1 - nloss);
nParticleChange.ProposeLocalEnergyDeposit(nloss);
nParticleChange.ProposeNonIonizingEnergyDeposit(nloss);
}
}
}
return &nParticleChange;
@@ -146,3 +149,10 @@ void G4NuclearStopping::PrintInfo()
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4NuclearStopping::ProcessDescription(std::ostream& out) const
{
out << "<strong>Nuclear stopping</strong>";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4PAIModel.cc 96934 2016-05-18 09:10:41Z gcosmo $
// $Id: G4PAIModel.cc 106217 2017-09-21 00:03:23Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -90,6 +90,7 @@ G4PAIModel::G4PAIModel(const G4ParticleDefinition* p, const G4String& nam)
// default generator
SetAngularDistribution(new G4DeltaAngle());
fLowestTcut = 12.5*CLHEP::eV;
}
////////////////////////////////////////////////////////////////////////////
@@ -201,6 +202,14 @@ void G4PAIModel::InitialiseLocal(const G4ParticleDefinition* p,
//////////////////////////////////////////////////////////////////////////////
G4double G4PAIModel::MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*)
{
return fLowestTcut;
}
//////////////////////////////////////////////////////////////////////////////
G4double G4PAIModel::ComputeDEDXPerVolume(const G4Material*,
const G4ParticleDefinition* p,
G4double kineticEnergy,
@@ -86,6 +86,7 @@ G4PAIPhotModel::G4PAIPhotModel(const G4ParticleDefinition* p, const G4String& na
// default generator
SetAngularDistribution(new G4DeltaAngle());
fLowestTcut = 12.5*CLHEP::eV;
}
////////////////////////////////////////////////////////////////////////////
@@ -99,7 +100,7 @@ G4PAIPhotModel::~G4PAIPhotModel()
////////////////////////////////////////////////////////////////////////////
void G4PAIPhotModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
const G4DataVector& cuts)
{
if(fVerbose > 0)
{
@@ -193,6 +194,14 @@ void G4PAIPhotModel::InitialiseLocal(const G4ParticleDefinition*,
//////////////////////////////////////////////////////////////////////////////
G4double G4PAIPhotModel::MinEnergyCut(const G4ParticleDefinition*,
const G4MaterialCutsCouple*)
{
return fLowestTcut;
}
//////////////////////////////////////////////////////////////////////////////
G4double G4PAIPhotModel::ComputeDEDXPerVolume(const G4Material*,
const G4ParticleDefinition* p,
G4double kineticEnergy,
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4PAIxSection.cc 91726 2015-08-03 15:41:36Z gcosmo $
// $Id: G4PAIxSection.cc 106442 2017-10-10 08:00:30Z gcosmo $
// GEANT4 tag $Name: geant4-09-03-ref-06 $
//
//
@@ -1658,7 +1658,7 @@ G4double G4PAIxSection::SumOverInterval( G4int i )
// b = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
a += 1.;
if( std::fabs(a) < 1.e-6 )
if( std::abs(a) < 1.e-6 )
{
result = b*log(x1/x0);
}
@@ -1667,7 +1667,7 @@ G4double G4PAIxSection::SumOverInterval( G4int i )
result = y0*(x1*pow(c,a-1) - x0)/a;
}
a += 1.;
if( std::fabs(a) < 1.e-6 )
if( std::abs(a) < 1.e-6 )
{
fIntegralPAIxSection[0] += b*log(x1/x0);
}
@@ -1881,7 +1881,7 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
b = y0/pow(x0,a); // pow(10.,b);
a += 1.;
if( std::fabs(a) < 1.e-6 )
if( std::abs(a) < 1.e-6 )
{
result = b*log(x0/e0);
}
@@ -1890,7 +1890,7 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
result = y0*(x0 - e0*pow(d,a-1))/a;
}
a += 1.;
if( std::fabs(a) < 1.e-6 )
if( std::abs(a) < 1.e-6 )
{
fIntegralPAIxSection[0] += b*log(x0/e0);
}
@@ -1909,7 +1909,7 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
// b0 = log10(y0) - a*log10(x0);
b = y0/pow(x0,a);
a += 1.;
if( std::fabs(a) < 1.e-6 )
if( std::abs(a) < 1.e-6 )
{
result += b*log(e0/x0);
}
@@ -1918,7 +1918,7 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
result += y0*(e0*pow(d,a-1) - x0)/a;
}
a += 1.;
if( std::fabs(a) < 1.e-6 )
if( std::abs(a) < 1.e-6 )
{
fIntegralPAIxSection[0] += b*log(e0/x0);
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4PEEffectFluoModel.cc 93362 2015-10-19 13:45:19Z gcosmo $
// $Id: G4PEEffectFluoModel.cc 106442 2017-10-10 08:00:30Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -246,7 +246,7 @@ G4PEEffectFluoModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
edep += elecKineEnergy;
elecKineEnergy = 0.0;
}
if(fabs(energy - elecKineEnergy - esec - edep) > eV) {
if(std::abs(energy - elecKineEnergy - esec - edep) > CLHEP::eV) {
G4cout << "### G4PEffectFluoModel dE(eV)= "
<< (energy - elecKineEnergy - esec - edep)/eV
<< " shell= " << i
@@ -1,231 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: $
//
// -----------------------------------------------------------------------------
//
// GEANT4 Class implementation file
//
// File name: G4PWATotalXsecTable
//
// Author: Mihaly Novak
//
// Creation date: 18.05.2015
//
// Class description:
// Class to load and handle elastic, first and second transport cross sections
// precomputed by using ELSEPA [1] in the 100 eV - 1 GeV kinetic and Z = 1-103
// energy range for electrons and positrons.G4PWATotalXsecZ is responsible to
// to handle cross sections by individual Z that are used in the current
// geometry and G4PWATotalXsecTable is a collection of G4PWATotalXsecZ objects.
//
// Modifications:
//
// References:
// [1] Francesc Salvat, Aleksander Jablonski, Cedric J Powell,
// ELSEPA—Dirac partial-wave calculation of elastic scattering of electrons
// and positrons by atoms, positive ions and molecules,
// Computer physics communications; 165, 2, (2005)
//
// -----------------------------------------------------------------------------
#include "G4PWATotalXsecTable.hh"
#include <vector>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include "G4MaterialTable.hh"
#include "G4Material.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
////////////////////////////////////////////////////////////////////////////////
// G4PWATotalXsecZ: sub-class for PWA xsec data that belong to a given Z number
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
const G4double G4PWATotalXsecZ::fgPWATotalXsecEnergyGrid[]={
// energy bin values for total elastic, first and second transport cross scetions in MeV
1.00000000e-04, 1.16591440e-04, 1.35935639e-04, 1.58489319e-04, 1.84784980e-04, 2.15443469e-04, 2.51188643e-04, 2.92864456e-04,
3.41454887e-04, 3.98107171e-04, 4.64158883e-04, 5.41169527e-04, 6.30957344e-04, 7.35642254e-04, 8.57695899e-04, 1.00000000e-03,
1.16591440e-03, 1.35935639e-03, 1.58489319e-03, 1.84784980e-03, 2.15443469e-03, 2.51188643e-03, 2.92864456e-03, 3.41454887e-03,
3.98107171e-03, 4.64158883e-03, 5.41169527e-03, 6.30957344e-03, 7.35642254e-03, 8.57695899e-03, 1.00000000e-02, 1.16591440e-02,
1.35935639e-02, 1.58489319e-02, 1.84784980e-02, 2.15443469e-02, 2.51188643e-02, 2.92864456e-02, 3.41454887e-02, 3.98107171e-02,
4.64158883e-02, 5.41169527e-02, 6.30957344e-02, 7.35642254e-02, 8.57695899e-02, 1.00000000e-01, 1.16591440e-01, 1.35935639e-01,
1.58489319e-01, 1.84784980e-01, 2.15443469e-01, 2.51188643e-01, 2.92864456e-01, 3.41454887e-01, 3.98107171e-01, 4.64158883e-01,
5.41169527e-01, 6.30957344e-01, 7.35642254e-01, 8.57695899e-01, 1.00000000e+00, 1.16591440e+00, 1.35935639e+00, 1.58489319e+00,
1.84784980e+00, 2.15443469e+00, 2.51188643e+00, 2.92864456e+00, 3.41454887e+00, 3.98107171e+00, 4.64158883e+00, 5.41169527e+00,
6.30957344e+00, 7.35642254e+00, 8.57695899e+00, 1.00000000e+01, 1.16591440e+01, 1.35935639e+01, 1.58489319e+01, 1.84784980e+01,
2.15443469e+01, 2.51188643e+01, 2.92864456e+01, 3.41454887e+01, 3.98107171e+01, 4.64158883e+01, 5.41169527e+01, 6.30957344e+01,
7.35642254e+01, 8.57695899e+01, 1.00000000e+02, 1.16591440e+02, 1.35935639e+02, 1.58489319e+02, 1.84784980e+02, 2.15443469e+02,
2.51188643e+02, 2.92864456e+02, 3.41454887e+02, 3.98107171e+02, 4.64158883e+02, 5.41169527e+02, 6.30957344e+02, 7.35642254e+02,
8.57695899e+02, 1.00000000e+03
};
////////////////////////////////////////////////////////////////////////////////
G4PWATotalXsecZ::G4PWATotalXsecZ(G4int Z){
G4int nn = fgNumTotalXsecBins*6;
for(G4int i=0; i<nn; ++i) {
fPWAXsecs[i] = 0.0;
fInterpParamA[i] = 0.0;
fInterpParamB[i] = 0.0;
}
LoadPWATotalXsecZ(Z);
}
////////////////////////////////////////////////////////////////////////////////
void G4PWATotalXsecZ::LoadPWATotalXsecZ(G4int Z){
G4double dum;
char fname[512];
char* path = getenv("G4LEDATA");
if (!path) {
G4Exception("G4PWATotalXsecZ::LoadPWATotalXsecZ()","em0006",
FatalException,
"Environment variable G4LEDATA not defined");
return;
}
std::string pathString(path);
sprintf(fname,"%s/msc_GS/xsecs/xsecs_%d",path,Z);
std::ifstream infile(fname,std::ios::in);
if(!infile.is_open()){
char msgc[512];
sprintf(msgc," Total PWA xsection %s not found.",fname);
G4Exception("G4PWATotalXsecZ::LoadPWATotalXsecZ()","em0006",
FatalException,
msgc);
return;
}
G4double dummy;
for(G4int i=0; i<fgNumTotalXsecBins; ++i)
for(G4int j=0; j<7; ++j)
if(j==0) infile >> dum;
else {
// load pwa xsection that are stored in cm2 units in file and change to
// Geant4 internal length2 units
infile >> dummy;
fPWAXsecs[(j-1)*fgNumTotalXsecBins+i] = dummy*CLHEP::cm2;
}
infile.close();
// compute log-log linear intrp. parameters
for(G4int i=0; i<fgNumTotalXsecBins-1; ++i)
for(G4int k=0; k<6; ++k) {
G4int j = k*fgNumTotalXsecBins+i;
G4double val2 = fPWAXsecs[j+1];
G4double val1 = fPWAXsecs[j];
fInterpParamA[j] = G4Log(val2/val1)/G4Log(fgPWATotalXsecEnergyGrid[i+1]/fgPWATotalXsecEnergyGrid[i]);
fInterpParamB[j] = G4Exp(G4Log(val1) - fInterpParamA[j]*G4Log(fgPWATotalXsecEnergyGrid[i]));
}
}
////////////////////////////////////////////////////////////////////////////////
// Get the index of the lower energy bin edge
G4int G4PWATotalXsecZ::GetPWATotalXsecEnergyBinIndex(G4double energy) const {
// log(fgPWATotalXsecEnergyGrid[0]);
const G4double lne0 = -9.21034037197618e+00;
// 1./log(fgPWATotalXsecEnergyGrid[i+1]/fgPWATotalXsecEnergyGrid[i]);
const G4double invlnde = 6.51441722854880e+00;
return (G4int)((G4Log(energy)-lne0)*invlnde);
}
////////////////////////////////////////////////////////////////////////////////
// j-dependent type interploated cross section in Geant4 internal length2 unit
// energy is assumed to be in [MeV]
G4double G4PWATotalXsecZ::GetInterpXsec(G4double energy, G4int elowindex, G4int j) const {
// protection : out of energy grid range
if(energy < GetLowestEnergy())
return GetLowestXsecValue(j);
if(energy >= GetHighestEnergy())
return GetHighestXsecValue(j);
// normal case log-log linear intrp.
G4int k = j*fgNumTotalXsecBins+elowindex;
return G4Exp(G4Log(energy)*fInterpParamA[k])*fInterpParamB[k];
}
////////////////////////////////////////////////////////////////////////////////
G4double G4PWATotalXsecZ::GetInterpXsec(G4double energy, G4int j) const {
// protection : out of energy grid range
if(energy < GetLowestEnergy())
return GetLowestXsecValue(j);
if(energy >= GetHighestEnergy())
return GetHighestXsecValue(j);
// normal case log-log linear intrp.
G4int elowindex = GetPWATotalXsecEnergyBinIndex(energy);
G4int k = j*fgNumTotalXsecBins+elowindex;
return G4Exp(G4Log(energy)*fInterpParamA[k])*fInterpParamB[k];
}
////////////////////////////////////////////////////////////////////////////////
// G4PWATotalXsecTable
////////////////////////////////////////////////////////////////////////////////
G4PWATotalXsecZ* G4PWATotalXsecTable::fgPWATotalXsecTable[fgNumZet] = {0};
////////////////////////////////////////////////////////////////////////////////
G4PWATotalXsecTable::~G4PWATotalXsecTable(){
for(G4int i = 0; i < fgNumZet; ++i)
if(fgPWATotalXsecTable[i]) {
delete fgPWATotalXsecTable[i];
fgPWATotalXsecTable[i] = 0;
}
}
////////////////////////////////////////////////////////////////////////////////
void G4PWATotalXsecTable::Initialise(){
G4int isUsedZ[fgNumZet] ={0}; //xsec data available up to fgNumZet Z-number
// check used elements
G4MaterialTable *theMaterialTable = G4Material::GetMaterialTable();
for(unsigned int imat = 0; imat < theMaterialTable->size(); ++imat) {
const G4ElementVector *theElemVect = ((*theMaterialTable)[imat])->GetElementVector();
for(unsigned int ielem = 0; ielem < theElemVect->size(); ++ielem) {
G4int zet = G4lrint((*theElemVect)[ielem]->GetZ());
zet = zet>fgNumZet ? fgNumZet : zet;
if(!isUsedZ[zet-1])
isUsedZ[zet-1] = 1;
}
}
for(G4int i = 0; i < fgNumZet; ++i)
if(isUsedZ[i] && !fgPWATotalXsecTable[i]) // used but not there yet -> load it
fgPWATotalXsecTable[i] = new G4PWATotalXsecZ(i+1);
else if(!isUsedZ[i] && fgPWATotalXsecTable[i]) { // there but not used now -> delete
delete fgPWATotalXsecTable[i];
fgPWATotalXsecTable[i] = 0;
}
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4PairProductionRelModel.cc 104555 2017-06-06 07:31:32Z gcosmo $
// $Id: G4PairProductionRelModel.cc 106628 2017-10-17 06:25:38Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -102,7 +102,7 @@ G4PairProductionRelModel::G4PairProductionRelModel(const G4ParticleDefinition*,
thePositron = G4Positron::Positron();
theElectron = G4Electron::Electron();
nist = G4NistManager::Instance();
g4calc = G4Pow::GetInstance();
currentZ = z13 = z23 = lnZ = Fel = Finel = fCoulomb = phiLPM = gLPM = xiLPM = 0;
}
@@ -388,7 +388,7 @@ G4PairProductionRelModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fve
do {
if ( NormF1/(NormF1+NormF2) > rndmEngine->flat() ) {
epsil = 0.5 - epsilrange*nist->GetZ13(rndmEngine->flat());
epsil = 0.5 - epsilrange*g4calc->Z13(rndmEngine->flat());
screenvar = screenfac/(epsil*(1-epsil));
if (fLPMflag && GammaEnergy > Eghigh) {
CalcLPMFunctions(GammaEnergy,GammaEnergy*epsil);
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4PhotoElectricEffect.cc 84598 2014-10-17 07:39:15Z gcosmo $
// $Id: G4PhotoElectricEffect.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
//
//------------------ G4PhotoElectricEffect physics process ---------------------
@@ -105,11 +105,11 @@ void G4PhotoElectricEffect::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
if(!EmModel(1)) { SetEmModel(new G4PEEffectFluoModel(),1); }
if(!EmModel()) { SetEmModel(new G4PEEffectFluoModel()); }
G4EmParameters* param = G4EmParameters::Instance();
EmModel(1)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(1)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, EmModel(1));
EmModel()->SetLowEnergyLimit(param->MinKinEnergy());
EmModel()->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(1, EmModel());
}
}
@@ -119,3 +119,11 @@ void G4PhotoElectricEffect::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PhotoElectricEffect::ProcessDescription(std::ostream& out) const
{
out << "<strong>Photoelectric effect</strong>";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -152,7 +152,6 @@ void G4ScreeningMottCrossSection::SetScreeningCoefficient()
G4double factor= 1.13 + 3.76*targetZ*targetZ*invbeta2*alpha2;
As=0.25*(htc2)/(twoR2*mom2)*factor;
//cout<<"0k .........................As "<<As<<endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -162,7 +161,6 @@ G4double G4ScreeningMottCrossSection::GetScreeningAngle()
SetScreeningCoefficient();
G4double screenangle=2.*asin(sqrt(As));
// cout<<" screenangle "<< screenangle <<endl;
if(screenangle>=pi) screenangle=pi;
return screenangle;
@@ -183,8 +181,8 @@ void G4ScreeningMottCrossSection::SetupKinematic(G4double ekin, G4double Z )
mottcoeff->SetMottCoeff(targetZ, coeffb);
//cout<<"......... targetA "<< targetA <<endl;
//cout<<"......... targetMass "<< targetMass/MeV <<endl;
//G4cout<<"......... targetA "<< targetA <<G4endl;
//G4cout<<"......... targetMass "<< targetMass/MeV <<G4endl;
// incident particle lab
tkinLab = ekin;
@@ -209,7 +207,7 @@ void G4ScreeningMottCrossSection::SetupKinematic(G4double ekin, G4double Z )
tkin = momCM*sqrt(invbeta2) - mu_rel;//Ekin of mu_rel
G4double beta2=1./invbeta2;
beta=std::sqrt(beta2) ;
G4double gamma2= invbeta2/x;
G4double gamma2= invbeta2/x;
gamma=std::sqrt(gamma2);
//.........................................................
@@ -244,8 +242,6 @@ G4double G4ScreeningMottCrossSection::FormFactor2ExpHof(G4double angles)
G4double form2=(FN*FN);
return form2;
//cout<<"..................... form2 "<< form2<<endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -268,8 +264,6 @@ G4double G4ScreeningMottCrossSection::FormFactor2Gauss(G4double angles)
G4double form2=(FN*FN);
return form2;
//cout<<"..................... form2 "<< form2<<endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -298,11 +292,7 @@ G4double G4ScreeningMottCrossSection::FormFactor2UniformHelm(G4double angles)
G4double form2=(F*F);
//cout<<"htc: "<<sqrt(htc2)<<" R0: "<<R0<<" F0: "<<F0<<" F1: "<<F1<<" Targer Mass: "<<targetMass<<" Energy: "<<tkinLab<<" ANGLE: "<<angles<<" FORM: "<<form2<<endl;
return form2;
//cout<<"..................... form2 "<< form2<<endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -342,60 +332,82 @@ G4double G4ScreeningMottCrossSection::RatioMottRutherford(G4double angles)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ScreeningMottCrossSection::NuclearCrossSection(G4int form)
G4double G4ScreeningMottCrossSection::SetDifferentialXSection(G4double angles, G4double step, G4int form)
{
G4double Xsec=0;
G4double R=0;
G4double F2=0;
if(form==0){F2=1;}
if(form==1){F2=FormFactor2ExpHof(angles);}
if(form==2){F2=FormFactor2Gauss(angles);}
if(form==3){F2=FormFactor2UniformHelm(angles);}
if (coeffb[0][0]!=0){
//G4cout<<" Mott....targetZ "<< targetZ<<G4endl;
R=RatioMottRutherford(angles);
} else if (coeffb[0][0]==0){
//G4cout<<" McF.... targetZ "<< targetZ<<G4endl;
R=McFcorrection(angles);
}
G4double den=2.*As+2.*fG4pow->powN(sin(angles*0.5),2);
G4double func=1./(den*den);
G4double fatt= targetZ/(mu_rel*gamma*beta*beta);
G4double sigma=e2*e2*fatt*fatt*func;
G4double pi2sintet=twopi*sin(angles);
Xsec=pi2sintet*F2*R*sigma*step;
if(Xsec<0){Xsec=0;};
return Xsec;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ScreeningMottCrossSection::NuclearCrossSection(G4int form, G4int FastComputation)
{
if(cosTetMaxNuc >= cosTetMinNuc) return 0.0;
TotalCross=0;
//G4cout<<"MODEL: "<<FastComputation<<G4endl;
//************ PRECISE COMPUTATION
if(FastComputation==0){
for(G4int i=0; i<DIM; ++i){
G4double R=0;
G4double F2=0;
if(form==0){F2=1;}
if(form==1){F2=FormFactor2ExpHof(tet[i]);}
if(form==2){F2=FormFactor2Gauss(tet[i]);}
if(form==3){F2=FormFactor2UniformHelm(tet[i]);}
if (coeffb[0][0]!=0){
//cout<<" Mott....targetZ "<< targetZ<<endl;
R=RatioMottRutherford(tet[i]);
} else if (coeffb[0][0]==0){
// cout<<" McF.... targetZ "<< targetZ<<endl;
R=McFcorrection(tet[i]);
for(G4int i=0; i<DIM; ++i){
cross[i]=SetDifferentialXSection(tet[i],dangle[i],form);
//G4cout<<i<<" Angle: "<<angle[i]<<" tet: "<<tet[i]<<" Cross: "<<cross[i]<G4endl;
TotalCross+=cross[i];
}
//**************** FAST COMPUTATION
}else if(FastComputation==1){
//cout<<"----------------- R "<<R<<" F2 "<<F2<<endl;
// cout<<"angle "<<tet[i] << " F2 "<<F2<<endl;
G4double p0 = electron_mass_c2*classic_electr_radius;
G4double coeff = twopi*p0*p0;
G4double den=2.*As+2.*fG4pow->powN(sin(tet[i]*0.5),2);
G4double func=1./(den*den);
G4double fac = coeff*targetZ*(targetZ)*invbeta2/mom2;
G4double fatt= targetZ/(mu_rel*gamma*beta*beta);
G4double sigma=e2*e2*fatt*fatt*func;
G4double pi2sintet=twopi*sin(tet[i]);
G4double x = 1.0 - cosTetMinNuc;
G4double x1 = x + 2*As;
cross[i]=pi2sintet*F2*R*sigma*dangle[i];
//cout<<i<<" Angle: "<<angle[i]<<" tet: "<<tet[i]<<" Cross: "<<cross[i]<<endl;
if(cross[i]<0){cross[i]=0;};
TotalCross+=cross[i];
}//end integral
// scattering with nucleus
TotalCross = fac*(cosTetMinNuc - cosTetMaxNuc)/
(x1*(1.0 - cosTetMaxNuc + 2*As));
}
//cout<< "ok ......... TotalCross "<<TotalCross<<endl;
// G4cout<<"Energy: "<<tkinLab/MeV<<" Total Cross: "<<TotalCross<<G4endl;
return TotalCross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4ScreeningMottCrossSection::GetScatteringAngle()
G4double G4ScreeningMottCrossSection::GetScatteringAngle(G4int form, G4int FastComputation)
{
//cout<<"Z: "<<targetZ<<" Energy: "<<tkinLab/MeV<<endl;
// cout<<"................ tkinLab "<< G4BestUnit(tkinLab,"Energy") << " anglemin= "<<anglemin<<endl;
//cout<<"anglemax= "<<anglemax<<endl;
//G4double r =3e-6*G4UniformRand();
//***** FOR TESTING HIGH ANGLES
//G4double r=3e-6*G4UniformRand();
//G4double r=1e-12*G4UniformRand();
G4double r=G4UniformRand();
@@ -403,14 +415,45 @@ G4double G4ScreeningMottCrossSection::GetScatteringAngle()
G4double y=0;
G4double step=0;
for(G4int i=DIM-1; i>=0; --i){
step=(1./TotalCross)*cross[i];
y+=step;
if(r >=y-step && r<y ){
scattangle= angle[i] +G4UniformRand()*dangle[i];
break;
//************ PRECISE COMPUTATION
if(FastComputation==0){
for(G4int i=DIM-1; i>=0; --i){
step=(1./TotalCross)*cross[i];
y+=step;
if(r >=y-step && r<y ){
scattangle= angle[i] +G4UniformRand()*dangle[i];
break;
}
}
//**************** FAST COMPUTATION
}else if(FastComputation==1){
G4double limit=mottcoeff->GetTransitionRandom(targetZ,tkinLab);
G4double Sz=2*As;
G4double angle_limit=acos(Sz-((Sz*(2+Sz))/(Sz+2*limit))+1);
//G4cout<<"ANGLE LIMIT: "<<angle_limit<<G4endl;
if(r>limit){
scattangle=acos(Sz-((Sz*(2+Sz))/(Sz+2*r))+1);
//G4cout<<"FAST"<<G4endl;
}else{
//G4cout<<"SLOW"<<G4endl;
for(G4int i=DIM-1; i>=0; --i){
cross[i]=SetDifferentialXSection(tet[i],dangle[i],form);
step=(1./TotalCross)*cross[i];
y+=step;
if(r >=y-step && r<y ){
scattangle= angle[i] +G4UniformRand()*dangle[i];
if(scattangle<angle_limit){scattangle=0;};
break;
}
}
}
}
//cout<<"Energy: "<<tkinLab/MeV<<" SCATTANGLE: "<<scattangle<<endl;
//************************************************
//G4cout<<"Energy: "<<tkinLab/MeV<<" SCATTANGLE: "<<scattangle<<G4endl;
return scattangle;
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4UniversalFluctuation.cc 104682 2017-06-12 08:45:44Z gcosmo $
// $Id: G4UniversalFluctuation.cc 106265 2017-09-26 23:32:49Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -32,35 +32,12 @@
//
// File name: G4UniversalFluctuation
//
// Author: Laszlo Urban
// Author: V. Ivanchenko for Laszlo Urban
//
// Creation date: 03.01.2002
//
// Modifications:
//
// 28-12-02 add method Dispersion (V.Ivanchenko)
// 07-02-03 change signature (V.Ivanchenko)
// 13-02-03 Add name (V.Ivanchenko)
// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
// 07-11-03 Fix problem of rounding of double in G4UniversalFluctuations
// 06-02-04 Add control on big sigma > 2*meanLoss (V.Ivanchenko)
// 26-04-04 Comment out the case of very small step (V.Ivanchenko)
// 07-02-05 define problim = 5.e-3 (mma)
// 03-05-05 conditions of Gaussian fluctuation changed (bugfix)
// + smearing for very small loss (L.Urban)
// 03-10-05 energy dependent rate -> cut dependence of the
// distribution is much weaker (L.Urban)
// 17-10-05 correction for very small loss (L.Urban)
// 20-03-07 'GLANDZ' part rewritten completely, no 'very small loss'
// regime any more (L.Urban)
// 03-04-07 correction to get better width of eloss distr.(L.Urban)
// 13-07-07 add protection for very small step or low-density material (VI)
// 19-03-09 new width correction (does not depend on previous steps) (L.Urban)
// 20-03-09 modification in the width correction (L.Urban)
// 14-06-10 fixed tail distribution - do not use uniform function (L.Urban)
// 08-08-10 width correction algorithm has bee modified -->
// better results for thin targets (L.Urban)
// 06-02-11 correction for very small losses (L.Urban)
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -89,14 +66,14 @@ G4UniversalFluctuation::G4UniversalFluctuation(const G4String& nam)
minNumberInteractionsBohr(10.0),
minLoss(10.*eV),
nmaxCont(16.),
rate(0.55),
fw(4.)
rate(0.56),
a0(50.),
fw(4.00)
{
lastMaterial = 0;
lastMaterial = nullptr;
particleMass = chargeSquare = ipotFluct = electronDensity = f1Fluct = f2Fluct
= e1Fluct = e2Fluct = e1LogFluct = e2LogFluct = ipotLogFluct = e0 = esmall
= e1 = e2 = 0;
= e1 = e2 = 0.0;
m_Inv_particleMass = m_massrate = DBL_MAX;
sizearray = 30;
rndmarray = new G4double[30];
@@ -214,118 +191,94 @@ G4UniversalFluctuation::SampleFluctuations(const G4MaterialCutsCouple* couple,
// very small step or low-density material
if(tmax <= e0) { return meanLoss; }
G4double losstot = 0.;
G4int nstep = 1;
if(meanLoss < 25.*ipotFluct)
{
if(rndmEngineF->flat()*ipotFluct< 0.04*meanLoss)
{ nstep = 1; }
else
{
nstep = 2;
meanLoss *= 0.5;
}
}
// width correction for small cuts
G4double scaling = std::min(1.+0.5*CLHEP::keV/tmax,1.50);
meanLoss /= scaling;
G4double a1, a2, a3;
for (G4int istep=0; istep < nstep; ++istep) {
G4double a1(0.0), a2(0.0), a3(0.0);
loss = a1 = a2 = a3 = 0.;
e1 = e1Fluct;
e2 = e2Fluct;
loss = 0.0;
if(tmax > ipotFluct) {
G4double w2 = G4Log(2.*electron_mass_c2*beta2*gam2)-beta2;
e1 = e1Fluct;
e2 = e2Fluct;
if(w2 > ipotLogFluct) {
if(w2 > e2LogFluct) {
G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
a1 = C*f1Fluct*(w2-e1LogFluct)/e1Fluct;
a2 = C*f2Fluct*(w2-e2LogFluct)/e2Fluct;
} else {
a1 = meanLoss*(1.-rate)/e1;
}
if(tmax > ipotFluct) {
G4double w2 = G4Log(2.*electron_mass_c2*beta2*gam2)-beta2;
if(a1 < nmaxCont) {
//small energy loss
G4double sa1 = sqrt(a1);
if(rndmEngineF->flat() < G4Exp(-sa1))
{
e1 = esmall;
a1 = meanLoss*(1.-rate)/e1;
a2 = 0.;
}
else
{
a1 = sa1 ;
e1 = sa1*e1Fluct;
}
} else {
//not small energy loss
//correction to get better fwhm value
a1 /= fw;
e1 = fw*e1Fluct;
}
}
}
G4double w1 = tmax/e0;
if(tmax > e0) {
a3 = rate*meanLoss*(tmax-e0)/(e0*tmax*G4Log(w1));
if(a1+a2 <= 0.) {
a3 /= rate;
if(w2 > ipotLogFluct) {
if(w2 > e2LogFluct) {
G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
a1 = C*f1Fluct*(w2-e1LogFluct)/e1Fluct;
a2 = C*f2Fluct*(w2-e2LogFluct)/e2Fluct;
} else {
a1 = meanLoss*(1.-rate)/e1;
}
}
//'nearly' Gaussian fluctuation if a1>nmaxCont&&a2>nmaxCont&&a3>nmaxCont
G4double emean = 0.;
G4double sig2e = 0.;
// excitation of type 1
AddExcitation(rndmEngineF, a1, e1, emean, loss, sig2e);
// excitation of type 2
AddExcitation(rndmEngineF, a2, e2, emean, loss, sig2e);
if(emean > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
// ionisation
if(a3 > 0.) {
emean = 0.;
sig2e = 0.;
G4double p3 = a3;
G4double alfa = 1.;
if(a3 > nmaxCont)
{
alfa = w1*(nmaxCont+a3)/(w1*nmaxCont+a3);
G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
emean += namean*e0*alfa1;
sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
p3 = a3-namean;
}
G4double w2 = alfa*e0;
if(tmax > w2) {
G4double w = (tmax-w2)/tmax;
G4int nb = G4Poisson(p3);
if(nb > 0) {
if(nb > sizearray) {
sizearray = nb;
delete [] rndmarray;
rndmarray = new G4double[nb];
}
rndmEngineF->flatArray(nb, rndmarray);
for (G4int k=0; k<nb; ++k) { loss += w2/(1.-w*rndmarray[k]); }
}
if(a1 < a0) {
G4double fwnow = 0.5+(fw-0.5)*sqrt(a1/a0);
a1 /= fwnow;
e1 *= fwnow;
} else {
a1 /= fw;
e1 = fw*e1Fluct;
}
if(emean > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
}
losstot += loss;
}
}
//G4cout << "Vavilov: " << losstot << " Nstep= " << nstep << G4endl;
return losstot;
G4double w1 = tmax/e0;
if(tmax > e0) {
a3 = rate*meanLoss*(tmax-e0)/(e0*tmax*G4Log(w1));
if(a1+a2 <= 0.) {
a3 /= rate;
}
}
//'nearly' Gaussian fluctuation if a1>nmaxCont&&a2>nmaxCont&&a3>nmaxCont
G4double emean = 0.;
G4double sig2e = 0.;
// excitation of type 1
if(a1 > 0.0) { AddExcitation(rndmEngineF, a1, e1, emean, loss, sig2e); }
// excitation of type 2
if(a2 > 0.0) { AddExcitation(rndmEngineF, a2, e2, emean, loss, sig2e); }
if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
// ionisation
if(a3 > 0.) {
emean = 0.;
sig2e = 0.;
G4double p3 = a3;
G4double alfa = 1.;
if(a3 > nmaxCont)
{
alfa = w1*(nmaxCont+a3)/(w1*nmaxCont+a3);
G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
emean += namean*e0*alfa1;
sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
p3 = a3-namean;
}
G4double w2 = alfa*e0;
if(tmax > w2) {
G4double w = (tmax-w2)/tmax;
G4int nnb = G4Poisson(p3);
if(nnb > 0) {
if(nnb > sizearray) {
sizearray = nnb;
delete [] rndmarray;
rndmarray = new G4double[nnb];
}
rndmEngineF->flatArray(nnb, rndmarray);
for (G4int k=0; k<nnb; ++k) { loss += w2/(1.-w*rndmarray[k]); }
}
}
if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
}
loss *= scaling;
return loss;
}
@@ -1,333 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4UniversalFluctuation2017.cc 104232 2017-05-19 14:56:13Z vnivanch $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4UniversalFluctuation2017
//
// Author: V. Ivanchenko for Laszlo Urban
//
// Creation date: 24.05.2017
//
// Modifications:
//
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4UniversalFluctuation2017.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
#include "G4Poisson.hh"
#include "G4Step.hh"
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
using namespace std;
G4UniversalFluctuation2017::G4UniversalFluctuation2017(const G4String& nam)
:G4VEmFluctuationModel(nam),
particle(nullptr),
minNumberInteractionsBohr(10.0),
minLoss(10.*eV),
nmaxCont(16.),
rate(0.511),
fw(3.)
{
lastMaterial = nullptr;
fw2 = fw*fw;
fw3 = (fw-1.)/(fw2*fw2);
particleMass = chargeSquare = ipotFluct = electronDensity = f1Fluct = f2Fluct
= e1Fluct = e2Fluct = e1LogFluct = e2LogFluct = ipotLogFluct = e0 = esmall
= e1 = e2 = 0.0;
m_Inv_particleMass = m_massrate = DBL_MAX;
sizearray = 30;
rndmarray = new G4double[30];
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UniversalFluctuation2017::~G4UniversalFluctuation2017()
{
delete [] rndmarray;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4UniversalFluctuation2017::InitialiseMe(const G4ParticleDefinition* part)
{
particle = part;
particleMass = part->GetPDGMass();
G4double q = part->GetPDGCharge()/eplus;
// Derived quantities
m_Inv_particleMass = 1.0 / particleMass;
m_massrate = electron_mass_c2 * m_Inv_particleMass ;
chargeSquare = q*q;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double
G4UniversalFluctuation2017::SampleFluctuations(const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double tmax,
G4double length,
G4double averageLoss)
{
// Calculate actual loss from the mean loss.
// The model used to get the fluctuations is essentially the same
// as in Glandz in Geant3 (Cern program library W5013, phys332).
// L. Urban et al. NIM A362, p.416 (1995) and Geant4 Physics Reference Manual
// shortcut for very small loss or from a step nearly equal to the range
// (out of validity of the model)
//
G4double meanLoss = averageLoss;
G4double tkin = dp->GetKineticEnergy();
//G4cout<< "Emean= "<< meanLoss<< " tmax= "<< tmax<< " L= "<<length<<G4endl;
if (meanLoss < minLoss) { return meanLoss; }
if(dp->GetDefinition() != particle) { InitialiseMe(dp->GetDefinition()); }
CLHEP::HepRandomEngine* rndmEngineF = G4Random::getTheEngine();
G4double tau = tkin * m_Inv_particleMass;
G4double gam = tau + 1.0;
G4double gam2 = gam*gam;
G4double beta2 = tau*(tau + 2.0)/gam2;
G4double loss(0.), siga(0.);
const G4Material* material = couple->GetMaterial();
// Gaussian regime
// for heavy particles only and conditions
// for Gauusian fluct. has been changed
//
if ((particleMass > electron_mass_c2) &&
(meanLoss >= minNumberInteractionsBohr*tmax))
{
G4double tmaxkine = 2.*electron_mass_c2*beta2*gam2/
(1.+m_massrate*(2.*gam+m_massrate)) ;
if (tmaxkine <= 2.*tmax)
{
electronDensity = material->GetElectronDensity();
siga = sqrt((1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
* electronDensity * chargeSquare);
G4double sn = meanLoss/siga;
// thick target case
if (sn >= 2.0) {
G4double twomeanLoss = meanLoss + meanLoss;
do {
loss = G4RandGauss::shoot(rndmEngineF,meanLoss,siga);
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (0.0 > loss || twomeanLoss < loss);
// Gamma distribution
} else {
G4double neff = sn*sn;
loss = meanLoss*G4RandGamma::shoot(rndmEngineF,neff,1.0)/neff;
}
//G4cout << "Gauss: " << loss << G4endl;
return loss;
}
}
// Glandz regime : initialisation
//
if (material != lastMaterial) {
f1Fluct = material->GetIonisation()->GetF1fluct();
f2Fluct = material->GetIonisation()->GetF2fluct();
e1Fluct = material->GetIonisation()->GetEnergy1fluct();
e2Fluct = material->GetIonisation()->GetEnergy2fluct();
e1LogFluct = material->GetIonisation()->GetLogEnergy1fluct();
e2LogFluct = material->GetIonisation()->GetLogEnergy2fluct();
ipotFluct = material->GetIonisation()->GetMeanExcitationEnergy();
ipotLogFluct = material->GetIonisation()->GetLogMeanExcEnergy();
e0 = material->GetIonisation()->GetEnergy0fluct();
esmall = 0.5*sqrt(e0*ipotFluct);
lastMaterial = material;
}
// very small step or low-density material
if(tmax <= e0) { return meanLoss; }
G4double a1(0.0), a2(0.0), a3(0.0);
loss = 0.0;
G4double rnow = rate + 0.489/(1.+0.050*meanLoss/ipotFluct);
e1 = e1Fluct;
e2 = e2Fluct;
if(tmax > ipotFluct) {
G4double w2 = G4Log(2.*electron_mass_c2*beta2*gam2)-beta2;
if(w2 > ipotLogFluct) {
if(w2 > e2LogFluct) {
G4double C = meanLoss*(1.-rnow)/(w2-ipotLogFluct);
a1 = C*f1Fluct*(w2-e1LogFluct)/e1Fluct;
a2 = C*f2Fluct*(w2-e2LogFluct)/e2Fluct;
} else {
a1 = meanLoss*(1.-rnow)/e1;
}
if(a1 < fw2) {
G4double fwnow = fw-fw3*(fw2-a1)*(fw2-a1);
a1 /= fwnow;
e1 *= fwnow;
} else {
a1 /= fw;
e1 = fw*e1Fluct;
}
if(a2 < fw2) {
G4double fwnow = fw-fw3*(fw2-a2)*(fw2-a2);
a2 /= fwnow;
e2 *= fwnow;
} else {
a2 /= fw;
e2 = fw*e2Fluct;
}
}
}
G4double w1 = tmax/e0;
if(tmax > e0) {
a3 = rnow*meanLoss*(tmax-e0)/(e0*tmax*G4Log(w1));
if(a1+a2 <= 0.) {
a3 /= rnow;
}
}
//'nearly' Gaussian fluctuation if a1>nmaxCont&&a2>nmaxCont&&a3>nmaxCont
G4double emean = 0.;
G4double sig2e = 0.;
// excitation of type 1
if(a1 > 0.0) { AddExcitation(rndmEngineF, a1, e1, emean, loss, sig2e); }
// excitation of type 2
if(a2 > 0.0) { AddExcitation(rndmEngineF, a2, e2, emean, loss, sig2e); }
if(emean > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
// ionisation
if(a3 > 0.) {
emean = 0.;
sig2e = 0.;
G4double p3 = a3;
G4double alfa = 1.;
if(a3 > nmaxCont)
{
alfa = w1*(nmaxCont+a3)/(w1*nmaxCont+a3);
G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
emean += namean*e0*alfa1;
sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
p3 = a3-namean;
}
G4double w2 = alfa*e0;
if(tmax > w2) {
G4double w = (tmax-w2)/tmax;
G4int nnb = G4Poisson(p3);
if(nnb > 0) {
if(nnb > sizearray) {
sizearray = nnb;
delete [] rndmarray;
rndmarray = new G4double[nnb];
}
rndmEngineF->flatArray(nnb, rndmarray);
for (G4int k=0; k<nnb; ++k) { loss += w2/(1.-w*rndmarray[k]); }
}
}
if(emean > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
}
return loss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4UniversalFluctuation2017::Dispersion(
const G4Material* material,
const G4DynamicParticle* dp,
G4double tmax,
G4double length)
{
if(dp->GetDefinition() != particle) { InitialiseMe(dp->GetDefinition()); }
electronDensity = material->GetElectronDensity();
G4double gam = (dp->GetKineticEnergy())*m_Inv_particleMass + 1.0;
G4double beta2 = 1.0 - 1.0/(gam*gam);
G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
* electronDensity * chargeSquare;
return siga;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4UniversalFluctuation2017::SetParticleAndCharge(const G4ParticleDefinition* part,
G4double q2)
{
if(part != particle) {
particle = part;
particleMass = part->GetPDGMass();
// Derived quantities
if( particleMass != 0.0 ){
m_Inv_particleMass = 1.0 / particleMass;
m_massrate = electron_mass_c2 * m_Inv_particleMass ;
}else{
m_Inv_particleMass = DBL_MAX;
m_massrate = DBL_MAX;
}
}
chargeSquare = q2;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -63,6 +63,7 @@
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4LossTableManager.hh"
#include "G4EmParameters.hh"
#include "G4ParticleChangeForMSC.hh"
#include "G4Poisson.hh"
@@ -123,7 +124,7 @@ G4UrbanMscModel::G4UrbanMscModel(const G4String& nam)
firstStep = true;
insideskin = false;
latDisplasmentbackup = false;
displacementFlag = true;
dispAlg96 = true;
rangecut = geombig;
drr = 0.35 ;
@@ -153,19 +154,13 @@ void G4UrbanMscModel::Initialise(const G4ParticleDefinition* p,
{
// set values of some data members
SetParticle(p);
/*
if(p->GetPDGMass() > MeV) {
G4cout << "### WARNING: G4UrbanMscModel model is used for "
<< p->GetParticleName() << " !!! " << G4endl;
G4cout << "### This model should be used only for e+-"
<< G4endl;
}
*/
fParticleChange = GetParticleChangeForMSC(p);
latDisplasmentbackup = latDisplasment;
dispAlg96 = (G4EmParameters::Instance()->LateralDisplacementAlg96());
//G4cout << "### G4UrbanMscModel::Initialise done!" << G4endl;
//G4cout << "### G4UrbanMscModel::Initialise done for "
// << p->GetParticleName() << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -869,7 +864,7 @@ G4UrbanMscModel::SampleScattering(const G4ThreeVector& oldDirection,
G4double cth = SampleCosineTheta(tPathLength,kineticEnergy);
// protection against 'bad' cth values
if(std::fabs(cth) >= 1.0) { return fDisplacement; }
if(std::abs(cth) >= 1.0) { return fDisplacement; }
/*
if(cth < 1.0 - 1000*tPathLength/lambda0 && cth < 0.5 &&
@@ -899,10 +894,9 @@ G4UrbanMscModel::SampleScattering(const G4ThreeVector& oldDirection,
<< G4endl;
*/
if (latDisplasment && currentTau >= tausmall) {
if(displacementFlag) { SampleDisplacementNew(cth, phi); }
else { SampleDisplacement(sth, phi); }
if(dispAlg96) { SampleDisplacement(sth, phi); }
else { SampleDisplacementNew(cth, phi); }
fDisplacement.rotateUz(oldDirection);
}
return fDisplacement;
@@ -919,7 +913,7 @@ G4double G4UrbanMscModel::SampleCosineTheta(G4double trueStepLength,
lambdaeff = lambda0;
G4double lambda1 = GetTransportMeanFreePath(particle,KineticEnergy);
if(std::fabs(lambda1 - lambda0) > lambda0*0.01 && lambda1 > 0.)
if(std::abs(lambda1 - lambda0) > lambda0*0.01 && lambda1 > 0.)
{
// mean tau value
tau = trueStepLength*G4Log(lambda0/lambda1)/(lambda0-lambda1);
@@ -980,7 +974,7 @@ G4double G4UrbanMscModel::SampleCosineTheta(G4double trueStepLength,
// parameter for tail
G4double ltau= G4Log(tau);
G4double u = G4Exp(ltau/6.);
if(extremesmallstep) u = G4Exp(G4Log(tsmall/lambda0)/6.);
if(extremesmallstep) { u = G4Exp(G4Log(tsmall/lambda0)/6.); }
G4double xx = G4Log(lambdaeff/currentRadLength);
G4double xsi = coeffc1+u*(coeffc2+coeffc3*u)+coeffc4*xx;
@@ -1159,8 +1153,7 @@ void G4UrbanMscModel::SampleDisplacement(G4double sth, G4double phi)
(1.-(kappa+1.)*currentTau*third)*third;
} else {
G4double etau = 0.;
if(currentTau < taubig) { etau = G4Exp(-currentTau); }
G4double etau = (currentTau < taubig) ? G4Exp(-currentTau) : 0.;
latcorr = -kappa*currentTau;
latcorr = G4Exp(latcorr)/kappami1;
latcorr += 1.-kappa*etau/kappami1 ;
@@ -1171,7 +1164,7 @@ void G4UrbanMscModel::SampleDisplacement(G4double sth, G4double phi)
// sample direction of lateral displacement
// compute it from the lateral correlation
G4double Phi = 0.;
G4double Phi;
if(std::abs(r*sth) < latcorr) {
Phi = twopi*rndmEngineMod->flat();
@@ -1179,11 +1172,8 @@ void G4UrbanMscModel::SampleDisplacement(G4double sth, G4double phi)
//G4cout << "latcorr= " << latcorr << " r*sth= " << r*sth
// << " ratio= " << latcorr/(r*sth) << G4endl;
G4double psi = std::acos(latcorr/(r*sth));
if(rndmEngineMod->flat() < 0.5) {
Phi = phi+psi;
} else {
Phi = phi-psi;
}
G4double rdm = rndmEngineMod->flat();
Phi = (rdm < 0.5) ? phi+psi : phi-psi;
}
fDisplacement.set(r*std::cos(Phi),r*std::sin(Phi),0.0);
}
@@ -1244,15 +1234,13 @@ void G4UrbanMscModel::SampleDisplacementNew(G4double , G4double phi)
} else {
if(random < probv2) {
v = (-1.+1./G4Exp(G4Log(1.-rndmEngineMod->flat()*(1.-w2v))/30.))/6.30e-2;
} else {
v = (-1.+1./G4Exp(G4Log(1.-rndmEngineMod->flat()*(1.-w3v))/-1.842))/1.45e1;
}
G4double rnd = rndmEngineMod->flat();
v = (random < probv2)
? (-1.+1./G4Exp(G4Log(1.-rnd*(1.-w2v))/30.))/6.30e-2
: (-1.+1./G4Exp(G4Log(1.-rnd*(1.-w3v))/-1.842))/1.45e1;
random = rndmEngineMod->flat();
if(random < 0.5) { Phi = phi+v; }
else { Phi = phi-v; }
rnd = rndmEngineMod->flat();
Phi = (rnd < 0.5) ? phi+v : phi-v;
}
fDisplacement.set(r*std::cos(Phi),r*std::sin(Phi),0.0);
}
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4WentzelOKandVIxSection.cc 104802 2017-06-19 07:11:40Z gcosmo $
// $Id: G4WentzelOKandVIxSection.cc 105734 2017-08-16 12:58:28Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -169,6 +169,11 @@ void G4WentzelOKandVIxSection::InitialiseA()
void G4WentzelOKandVIxSection::SetupParticle(const G4ParticleDefinition* p)
{
/*
G4cout << "G4WentzelOKandVIxSection::SetupParticle " << p
<< " " << particle << " " << this << G4endl;
G4cout << this << " " << p->GetParticleName() << G4endl;
*/
particle = p;
mass = particle->GetPDGMass();
spin = particle->GetPDGSpin();
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4WentzelVIModel.cc 104802 2017-06-19 07:11:40Z gcosmo $
// $Id: G4WentzelVIModel.cc 105734 2017-08-16 12:58:28Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -89,11 +89,11 @@ G4WentzelVIModel::G4WentzelVIModel(G4bool comb, const G4String& nam)
invsqrt12 = 1./sqrt(12.);
tlimitminfix = 1.e-6*mm;
lowEnergyLimit = 1.0*eV;
particle = 0;
particle = nullptr;
nelments = 5;
xsecn.resize(nelments);
prob.resize(nelments);
wokvi = nullptr;
wokvi = new G4WentzelOKandVIxSection(isCombined);
fixedCut = -1.0;
minNCollisions = 10;
@@ -123,8 +123,6 @@ G4WentzelVIModel::~G4WentzelVIModel()
void G4WentzelVIModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if(!wokvi) { wokvi = new G4WentzelOKandVIxSection(isCombined); }
// reset parameters
SetupParticle(p);
currentRange = 0.0;
@@ -138,7 +136,7 @@ void G4WentzelVIModel::Initialise(const G4ParticleDefinition* p,
// << " " << this << " " << wokvi << G4endl;
wokvi->Initialise(p, cosThetaMax);
/*
/*
G4cout << "G4WentzelVIModel: " << particle->GetParticleName()
<< " 1-cos(ThetaLimit)= " << 1 - cosThetaMax
<< " SingScatFactor= " << ssFactor
@@ -229,7 +227,7 @@ G4double G4WentzelVIModel::ComputeCrossSectionPerAtom(
G4double cutEnergy, G4double)
{
G4double cross = 0.0;
if(p != particle) { SetupParticle(p); }
SetupParticle(p);
if(kinEnergy < lowEnergyLimit) { return cross; }
if(!CurrentCouple()) {
G4Exception("G4WentzelVIModel::ComputeCrossSectionPerAtom", "em0011",
@@ -256,7 +254,12 @@ G4double G4WentzelVIModel::ComputeCrossSectionPerAtom(
void G4WentzelVIModel::StartTracking(G4Track* track)
{
SetupParticle(track->GetDynamicParticle()->GetDefinition());
/*
G4cout << "G4WentzelVIModel::StartTracking " << track << " " << this << " "
<< track->GetParticleDefinition()->GetParticleName()
<< " workvi: " << wokvi << G4endl;
*/
SetupParticle(track->GetParticleDefinition());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -764,8 +767,8 @@ G4double G4WentzelVIModel::ComputeTransportXSectionPerVolume(G4double cosTheta)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4WentzelVIModel:: ComputeSecondMoment(const G4ParticleDefinition* p,
G4double kinEnergy)
G4double G4WentzelVIModel::ComputeSecondMoment(const G4ParticleDefinition* p,
G4double kinEnergy)
{
G4double xs = 0.0;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4alphaIonisation.cc 96934 2016-05-18 09:10:41Z gcosmo $
// $Id: G4alphaIonisation.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -87,7 +87,7 @@ G4alphaIonisation::~G4alphaIonisation()
G4bool G4alphaIonisation::IsApplicable(const G4ParticleDefinition& p)
{
return (!p.IsShortLived() &&
std::fabs(p.GetPDGCharge()/CLHEP::eplus - 2) < 0.01);
std::abs(p.GetPDGCharge()/CLHEP::eplus - 2) < 0.01);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -124,23 +124,23 @@ void G4alphaIonisation::InitialiseEnergyLossProcess(
SetBaseParticle(theBaseParticle);
SetSecondaryParticle(G4Electron::Electron());
if (!EmModel(1)) { SetEmModel(new G4BraggIonModel(), 1); }
if (!EmModel(0)) { SetEmModel(new G4BraggIonModel()); }
G4EmParameters* param = G4EmParameters::Instance();
G4double emin = param->MinKinEnergy();
EmModel(1)->SetLowEnergyLimit(emin);
EmModel(0)->SetLowEnergyLimit(emin);
// model limit defined for alpha
eth = (EmModel(1)->HighEnergyLimit())*ratio;
EmModel(1)->SetHighEnergyLimit(eth);
AddEmModel(1, EmModel(1), new G4IonFluctuations());
eth = (EmModel(0)->HighEnergyLimit())*ratio;
EmModel(0)->SetHighEnergyLimit(eth);
AddEmModel(1, EmModel(0), new G4IonFluctuations());
if (!FluctModel()) { SetFluctModel(new G4UniversalFluctuation()); }
if (!EmModel(2)) { SetEmModel(new G4BetheBlochModel(),2); }
EmModel(2)->SetLowEnergyLimit(eth);
EmModel(2)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(2, EmModel(2), FluctModel());
if (!EmModel(1)) { SetEmModel(new G4BetheBlochModel()); }
EmModel(1)->SetLowEnergyLimit(eth);
EmModel(1)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(2, EmModel(1), FluctModel());
isInitialised = true;
}
@@ -152,3 +152,11 @@ void G4alphaIonisation::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4alphaIonisation::ProcessDescription(std::ostream& out) const
{
out << "<strong>Alpha ionisation</strong>";
G4VEnergyLossProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4eBremsstrahlung.cc 98737 2016-08-09 12:51:38Z gcosmo $
// $Id: G4eBremsstrahlung.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -125,20 +125,20 @@ G4eBremsstrahlung::InitialiseEnergyLossProcess(const G4ParticleDefinition*,
G4double energyLimit = std::min(emax, GeV);
G4VEmFluctuationModel* fm = nullptr;
if (!EmModel(1)) { SetEmModel(new G4SeltzerBergerModel(), 1); }
EmModel(1)->SetLowEnergyLimit(emin);
EmModel(1)->SetHighEnergyLimit(energyLimit);
EmModel(1)->SetSecondaryThreshold(param->BremsstrahlungTh());
EmModel(1)->SetLPMFlag(false);
AddEmModel(1, EmModel(1), fm);
if (!EmModel(0)) { SetEmModel(new G4SeltzerBergerModel()); }
EmModel(0)->SetLowEnergyLimit(emin);
EmModel(0)->SetHighEnergyLimit(energyLimit);
EmModel(0)->SetSecondaryThreshold(param->BremsstrahlungTh());
EmModel(0)->SetLPMFlag(false);
AddEmModel(1, EmModel(0), fm);
if(emax > energyLimit) {
if (!EmModel(2)) { SetEmModel(new G4eBremsstrahlungRelModel(), 2); }
EmModel(2)->SetLowEnergyLimit(energyLimit);
EmModel(2)->SetHighEnergyLimit(emax);
EmModel(2)->SetSecondaryThreshold(param->BremsstrahlungTh());
EmModel(2)->SetLPMFlag(param->LPM());
AddEmModel(2, EmModel(2), fm);
if (!EmModel(1)) { SetEmModel(new G4eBremsstrahlungRelModel()); }
EmModel(1)->SetLowEnergyLimit(energyLimit);
EmModel(1)->SetHighEnergyLimit(emax);
EmModel(1)->SetSecondaryThreshold(param->BremsstrahlungTh());
EmModel(1)->SetLPMFlag(param->LPM());
AddEmModel(1, EmModel(1), fm);
}
isInitialised = true;
}
@@ -146,18 +146,27 @@ G4eBremsstrahlung::InitialiseEnergyLossProcess(const G4ParticleDefinition*,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eBremsstrahlung::PrintInfo()
void G4eBremsstrahlung::StreamProcessInfo(std::ostream& out,
G4String endOfLine) const
{
if(EmModel(1)) {
if(EmModel(0)) {
G4EmParameters* param = G4EmParameters::Instance();
G4double eth = param->BremsstrahlungTh();
G4cout << " LPM flag: " << param->LPM() << " for E > "
<< EmModel(1)->HighEnergyLimit()/GeV << " GeV";
out << " LPM flag: " << param->LPM() << " for E > "
<< EmModel(0)->HighEnergyLimit()/GeV << " GeV";
if(eth < DBL_MAX) {
G4cout << ", VertexHighEnergyTh(GeV)= " << eth/GeV;
out << ", VertexHighEnergyTh(GeV)= " << eth/GeV;
}
G4cout << G4endl;
out << endOfLine;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eBremsstrahlung::ProcessDescription(std::ostream& out) const
{
out << "<strong>Bremsstrahlung</strong>";
G4VEnergyLossProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4eIonisation.cc 96934 2016-05-18 09:10:41Z gcosmo $
// $Id: G4eIonisation.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -124,10 +124,10 @@ void G4eIonisation::InitialiseEnergyLossProcess(
{
if(!isInitialised) {
if(part != theElectron) { isElectron = false; }
if (!EmModel(1)) { SetEmModel(new G4MollerBhabhaModel()); }
if (!EmModel(0)) { SetEmModel(new G4MollerBhabhaModel()); }
G4EmParameters* param = G4EmParameters::Instance();
EmModel(1)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(1)->SetHighEnergyLimit(param->MaxKinEnergy());
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(0)->SetHighEnergyLimit(param->MaxKinEnergy());
if (!FluctModel()) { SetFluctModel(new G4UniversalFluctuation()); }
AddEmModel(1, EmModel(), FluctModel());
@@ -141,3 +141,11 @@ void G4eIonisation::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eIonisation::ProcessDescription(std::ostream& out) const
{
out << "<strong>Ionisation</strong>";
G4VEnergyLossProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4eMultipleScattering.cc 97741 2016-06-08 09:24:21Z gcosmo $
// $Id: G4eMultipleScattering.cc 107365 2017-11-09 10:54:29Z gcosmo $
//
// -----------------------------------------------------------------------------
//
@@ -75,23 +75,35 @@ G4bool G4eMultipleScattering::IsApplicable (const G4ParticleDefinition& p)
void G4eMultipleScattering::InitialiseProcess(const G4ParticleDefinition*)
{
if(isInitialized) { return; }
if(!EmModel(1)) { SetEmModel(new G4UrbanMscModel(), 1); }
AddEmModel(1, EmModel(1));
if(!EmModel(0)) { SetEmModel(new G4UrbanMscModel()); }
AddEmModel(1, EmModel(0));
if(EmModel(1)) { AddEmModel(1, EmModel(1)); }
isInitialized = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4eMultipleScattering::PrintInfo()
void G4eMultipleScattering::StreamProcessInfo(std::ostream& out,
G4String endOfLine) const
{
G4cout << " RangeFactor= " << RangeFactor()
<< ", stepLimitType: " << StepLimitType()
<< ", latDisplacement: " << LateralDisplasmentFlag();
out << " RangeFactor= " << RangeFactor()
<< ", stepLimitType: " << StepLimitType()
<< ", latDisplacement: " << LateralDisplasmentFlag();
if(StepLimitType() == fUseDistanceToBoundary) {
G4cout << ", skin= " << Skin() << ", geomFactor= " << GeomFactor();
out << ", skin= " << Skin() << ", geomFactor= " << GeomFactor();
}
G4cout << G4endl;
out << endOfLine;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4eMultipleScattering::ProcessDescription(std::ostream& out) const
{
out <<
"<strong>Multiple scattering</strong>. Simulates combined effects of <br>"
"elastic scattering at the end of the step, to save computing time. May<br>"
"be combined with Coulomb scattering in a 'mixed' scattering algorithm.";
G4VMultipleScattering::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -87,6 +87,7 @@ G4eSingleCoulombScatteringModel::G4eSingleCoulombScatteringModel(const G4String&
lowEnergyLimit = 0*keV;
recoilThreshold = 0.*eV;
XSectionModel = 1;
FormFactor = 0;
particle = nullptr;
mass=0.0;
@@ -162,9 +163,11 @@ G4double G4eSingleCoulombScatteringModel::ComputeCrossSectionPerAtom(
//Total Cross section
Mottcross->SetupKinematic(kinEnergy, Z);
cross = Mottcross->NuclearCrossSection(FormFactor);
cross = Mottcross->NuclearCrossSection(FormFactor,XSectionModel);
//cout<< "Compute Cross Section....cross "<<G4BestUnit(cross,"Surface") << " cm2 "<< cross/cm2 <<" Z: "<<Z<<" kinEnergy: "<<kinEnergy<<endl;
//G4cout<<"Energy: "<<kinEnergy/MeV<<" Total Cross: "<<cross<<G4endl;
return cross;
}
@@ -198,11 +201,11 @@ void G4eSingleCoulombScatteringModel::SampleSecondaries(
//G4cout<<"..Z: "<<Z<<" ..iz: "<<iz<<" ..ia: "<<ia<<" ..mass2: "<<mass2<<G4endl;
Mottcross->SetupKinematic(kinEnergy, Z);
G4double cross= Mottcross->NuclearCrossSection(FormFactor); //MODIFY TO LOAD TABLE
G4double cross= Mottcross->NuclearCrossSection(FormFactor,XSectionModel);
if(cross == 0.0) { return; }
//cout<< "Energy: "<<kinEnergy/MeV<<" Z: "<<Z<<"....cross "<<G4BestUnit(cross,"Surface") << " cm2 "<< cross/cm2 <<endl;
G4double z1 = Mottcross->GetScatteringAngle();
G4double z1 = Mottcross->GetScatteringAngle(FormFactor,XSectionModel);
G4double sint = sin(z1);
G4double cost = sqrt(1.0 - sint*sint);
G4double phi = twopi* G4UniformRand();
@@ -244,6 +247,8 @@ void G4eSingleCoulombScatteringModel::SampleSecondaries(
if(pCuts) {
tcut= std::max(tcut,(*pCuts)[currentMaterialIndex]);
//G4cout<<"Cuts: "<<(*pCuts)[currentMaterialIndex]/eV<<" eV"<<G4endl;
//G4cout<<"Threshold: "<<tcut/eV<<" eV"<<G4endl;
}
if(trec > tcut) {
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4eplusAnnihilation.cc 101249 2016-11-10 08:52:15Z gcosmo $
// $Id: G4eplusAnnihilation.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -103,16 +103,17 @@ void G4eplusAnnihilation::InitialiseProcess(const G4ParticleDefinition*)
{
if(!isInitialised) {
isInitialised = true;
if(!EmModel(1)) { SetEmModel(new G4eeToTwoGammaModel(),1); }
EmModel(1)->SetLowEnergyLimit(MinKinEnergy());
EmModel(1)->SetHighEnergyLimit(MaxKinEnergy());
AddEmModel(1, EmModel(1));
if(!EmModel(0)) { SetEmModel(new G4eeToTwoGammaModel()); }
EmModel(0)->SetLowEnergyLimit(MinKinEnergy());
EmModel(0)->SetHighEnergyLimit(MaxKinEnergy());
AddEmModel(1, EmModel(0));
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusAnnihilation::PrintInfo()
void G4eplusAnnihilation::StreamProcessInfo(std::ostream&,
G4String) const
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -170,3 +171,11 @@ G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& aTrack,
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eplusAnnihilation::ProcessDescription(std::ostream& out) const
{
out << "<strong>Positron annihilation</strong>";
G4VEmProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4hIonisation.cc 102525 2017-02-08 11:23:26Z gcosmo $
// $Id: G4hIonisation.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -198,20 +198,20 @@ void G4hIonisation::InitialiseEnergyLossProcess(
SetDEDXBinning(bin);
}
if (!EmModel(1)) {
if(q > 0.0) { SetEmModel(new G4BraggModel(),1); }
else { SetEmModel(new G4ICRU73QOModel(),1); }
if (!EmModel(0)) {
if(q > 0.0) { SetEmModel(new G4BraggModel()); }
else { SetEmModel(new G4ICRU73QOModel()); }
}
EmModel(1)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(1)->SetHighEnergyLimit(eth);
AddEmModel(1, EmModel(1), new G4IonFluctuations());
EmModel(0)->SetLowEnergyLimit(emin);
EmModel(0)->SetHighEnergyLimit(eth);
AddEmModel(1, EmModel(0), new G4IonFluctuations());
if (!FluctModel()) { SetFluctModel(new G4UniversalFluctuation()); }
if (!EmModel(2)) { SetEmModel(new G4BetheBlochModel(),2); }
EmModel(2)->SetLowEnergyLimit(eth);
EmModel(2)->SetHighEnergyLimit(param->MaxKinEnergy());
AddEmModel(2, EmModel(2), FluctModel());
if (!EmModel(1)) { SetEmModel(new G4BetheBlochModel()); }
EmModel(1)->SetLowEnergyLimit(eth);
EmModel(1)->SetHighEnergyLimit(emax);
AddEmModel(1, EmModel(1), FluctModel());
isInitialised = true;
}
@@ -223,3 +223,11 @@ void G4hIonisation::PrintInfo()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4hIonisation::ProcessDescription(std::ostream& out) const
{
out << "<strong>Ionisation</strong>";
G4VEnergyLossProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4hMultipleScattering.cc 97741 2016-06-08 09:24:21Z gcosmo $
// $Id: G4hMultipleScattering.cc 107365 2017-11-09 10:54:29Z gcosmo $
//
// -----------------------------------------------------------------------------
//
@@ -75,23 +75,36 @@ G4bool G4hMultipleScattering::IsApplicable (const G4ParticleDefinition& p)
void G4hMultipleScattering::InitialiseProcess(const G4ParticleDefinition*)
{
if(isInitialized) { return; }
if(!EmModel(1)) { SetEmModel(new G4UrbanMscModel(), 1); }
AddEmModel(1, EmModel(1));
if(!EmModel(0)) { SetEmModel(new G4UrbanMscModel()); }
AddEmModel(1, EmModel(0));
isInitialized = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4hMultipleScattering::PrintInfo()
void G4hMultipleScattering::StreamProcessInfo(std::ostream& out,
G4String endOfLine) const
{
G4cout << " RangeFactor= " << RangeFactor()
<< ", stepLimitType: " << StepLimitType()
<< ", latDisplacement: " << LateralDisplasmentFlag();
out << " RangeFactor= " << RangeFactor()
<< ", stepLimitType: " << StepLimitType()
<< ", latDisplacement: " << LateralDisplasmentFlag();
if(StepLimitType() == fUseDistanceToBoundary) {
G4cout << ", skin= " << Skin() << ", geomFactor= " << GeomFactor();
out << ", skin= " << Skin() << ", geomFactor= " << GeomFactor();
}
G4cout << G4endl;
out << endOfLine;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4hMultipleScattering::ProcessDescription(std::ostream& out) const
{
out <<
"<strong>"
"Hadron multiple scattering</strong>. Simulates combined effects of <br>"
"elastic scattering at the end of the step, to save computing time. May<br>"
"be combined with Coulomb scattering in a 'mixed' scattering algorithm.";
G4VMultipleScattering::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ionIonisation.cc 96934 2016-05-18 09:10:41Z gcosmo $
// $Id: G4ionIonisation.cc 107058 2017-11-01 14:54:12Z gcosmo $
//
// -------------------------------------------------------------------
//
@@ -138,31 +138,31 @@ void G4ionIonisation::InitialiseEnergyLossProcess(
SetBaseParticle(theBaseParticle);
if (!EmModel(1)) { SetEmModel(new G4BraggIonModel(), 1); }
if (!EmModel(0)) { SetEmModel(new G4BraggIonModel()); }
G4EmParameters* param = G4EmParameters::Instance();
EmModel(1)->SetLowEnergyLimit(param->MinKinEnergy());
EmModel(0)->SetLowEnergyLimit(param->MinKinEnergy());
// model limit defined for protons
eth = (EmModel(1)->HighEnergyLimit())*part->GetPDGMass()/proton_mass_c2;
EmModel(1)->SetHighEnergyLimit(eth);
eth = (EmModel(0)->HighEnergyLimit())*part->GetPDGMass()/proton_mass_c2;
EmModel(0)->SetHighEnergyLimit(eth);
if (!FluctModel()) { SetFluctModel(new G4IonFluctuations()); }
AddEmModel(1, EmModel(1), FluctModel());
AddEmModel(1, EmModel(0), FluctModel());
G4double emax = param->MaxKinEnergy();
if(eth < emax) {
if (!EmModel(2)) { SetEmModel(new G4BetheBlochModel(),2); }
EmModel(2)->SetLowEnergyLimit(eth);
EmModel(2)->SetHighEnergyLimit(emax);
AddEmModel(2, EmModel(2), FluctModel());
if (!EmModel(1)) { SetEmModel(new G4BetheBlochModel()); }
EmModel(1)->SetLowEnergyLimit(eth);
EmModel(1)->SetHighEnergyLimit(emax);
AddEmModel(2, EmModel(1), FluctModel());
// Add ion stoping tables for Generic Ion if the default
// model is used (with eth ~= 2 MeV)
if(part == ion) {
stopDataActive = true;
G4WaterStopping ws(corr);
corr->SetIonisationModels(EmModel(1),EmModel(2));
corr->SetIonisationModels(EmModel(0),EmModel(1));
}
}
isInitialised = true;
@@ -173,13 +173,14 @@ void G4ionIonisation::InitialiseEnergyLossProcess(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ionIonisation::PrintInfo()
void G4ionIonisation::StreamProcessInfo(std::ostream& out,
G4String endOfLine) const
{
if (stopDataActive && G4GenericIon::GenericIon() == theParticle) {
G4cout << " Stopping Power data for "
<< corr->GetNumberOfStoppingVectors()
<< " ion/material pairs "
<< G4endl;
out << " Stopping Power data for "
<< corr->GetNumberOfStoppingVectors()
<< " ion/material pairs "
<< endOfLine;
}
}
@@ -193,3 +194,11 @@ void G4ionIonisation::AddStoppingData(G4int Z, G4int A,
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ionIonisation::ProcessDescription(std::ostream& out) const
{
out << "<strong>Ion ionisation</strong>";
G4VEnergyLossProcess::ProcessDescription(out);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....