Import Geant4 11.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2023-12-08 10:43:34 +01:00
parent dd1f179cda
commit 860a2b92bf
3962 changed files with 139318 additions and 164259 deletions
@@ -6,6 +6,20 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-10-23 Alexei Sytov (fastsimchanneling-V11-01-04)
- G4Log replaced std::log
- some small issues were fixed to comply with the Geant4 guidelines
## 2023-10-18 Alexei Sytov (fastsimchanneling-V11-01-03)
- Considerable updates:
- Revised version of the Baier-Katkov method with a new features of
increasing of the photon statistics in certain intervals of spectrum;
updates in defaults; some bugs were corrected
- The electromagnetic shower in W was simulated and preliminarly
validated with experimental data from Eur. Phys. J. C 82, 699 (2022)
- Added the Crystalline Undulator (CU) as a periodically bent crystal
to the internal crystal geometry (still needs to be validated).
## 2023-06-15 Gabriele Cosmo (fastsimchanneling-V11-01-02)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -59,7 +59,8 @@ public:
of the radiation type you are interested in
CAUTION: do ResetRadIntegral() before the start of a new trajectory
1) change some model defaults if necessary (SetSinglePhotonRadiationProbabilityLimit,
1) change some model defaults if necessary
(SetSinglePhotonRadiationProbabilityLimit,
SetNSmallTrajectorySteps, SetSpectrumEnergyRange)
2) call DoRadiation at each step of your trajectory
3) if DoRadiation returns TRUE, this means that a photon is produced (not added
@@ -98,7 +99,8 @@ public:
const G4ThreeVector& GetParticleNewCoordinateXYZ(){return fNewParticleCoordinateXYZ;}
///get photon energies (x-value in spectrum)
const std::vector<G4double>& GetPhotonEnergyInSpectrum(){return fPhotonEnergyInSpectrum;}
const std::vector<G4double>& GetPhotonEnergyInSpectrum()
{return fPhotonEnergyInSpectrum;}
///get fTotalSpectrum after finishing the trajectory part with DoRadiation
const std::vector<G4double>& GetTotalSpectrum(){return fTotalSpectrum;}
@@ -121,7 +123,12 @@ public:
///setting the number of photons in sampling of Baier-Katkov Integral
///(MC integration by photon energy and angles <=> photon momentum)
void SetSamplingPhotonsNumber(G4double nPhotons){fNMCPhotons = nPhotons;}
void SetSamplingPhotonsNumber(G4int nPhotons){fNMCPhotons = nPhotons;}
///setting the number of radiation angles 1/gamma, defining the width of
///the angular distribution of photon sampling in the Baier-Katkov Integral
void SetRadiationAngleFactor(G4double radiationAngleFactor)
{fRadiationAngleFactor = radiationAngleFactor;}
///CAUTION, the bins width is logarithmic
///Do not worry if the maximal energy > particle energy.
@@ -142,6 +149,16 @@ public:
fMaxPhotonEnergy,
nbin);}
/// Increase the statistic of virtual photons in a certain energy region
/// CAUTION! : don't do it before SetSpectrumEnergyRange or SetMinPhotonEnergy
void AddStatisticsInPhotonEnergyRegion(G4double emin, G4double emax,
G4int timesPhotonStatistics);
/// Virtual collimator masks the selection of photon angles in fTotalSpectrum
/// Virtual collimator doesn't influence on Geant4 simulations.
void SetVirtualCollimator(G4double virtualCollimatorAngularDiameter)
{fVirtualCollimatorAngularDiameter=virtualCollimatorAngularDiameter;}
/// add the new elements of the trajectory, calculate radiation in a crystal
/// see complete description in G4BaierKatkov::DoRadiation
/// calls RadIntegral and all the necessary functions
@@ -196,14 +213,14 @@ private:
G4int FindVectorIndex(std::vector<G4double> &myvector, G4double value);
G4double fTotalRadiationProbability = 0.;
G4double fSinglePhotonRadiationProbabilityLimit=0.05;//Maximal radiation
G4double fSinglePhotonRadiationProbabilityLimit=0.25;//Maximal radiation
//probability to preserve single photon radiation
//number of steps in a trajectory piece before the next call of the radiation integral
G4int fNSmallTrajectorySteps=1000;
G4int fNSmallTrajectorySteps=10000;
///trajectory element No (the first element of the array feeded in RadIntegral)
G4int fImin0 = 0;
///number of Monte Carlo points of integration on photon angles
///Monte Carlo statistics of photon sampling in Baier-Katkov with 1 trajectory
G4int fNMCPhotons =150;
///the number of bins in photon spectrum
G4int fNBinsSpectrum = 110;
@@ -218,6 +235,14 @@ private:
G4double fLogEdEmin = 1.; // = log(E/fMinPhotonEnergy), the same as fLogEmaxdEmin
// but with the particle energy as the maximal limit
G4double fVirtualCollimatorAngularDiameter=1.;//default, infinite angle
std::vector<G4bool> fInsideVirtualCollimator;
///data of the phootn energy range with additional statistics
std::vector<G4double> fLogAddRangeEmindEmin;//=G4Log(emin/fMinPhotonEnergy)
std::vector<G4double> fLogAddRangeEmaxdEmin;//=G4Log(emax/fMinPhotonEnergy)
std::vector<G4int> fTimesPhotonStatistics;
///number of trajectories
//(at each of the Baier-Katkov Integral is calculated for the same photons)
G4int fItrajectories = 0;
@@ -234,6 +259,9 @@ private:
//in sampling, y-plane
G4double fParamPhotonAngleY=1.e-3*CLHEP::rad; //a parameter radiated photon
//sampling distribution, y-plane
G4double fRadiationAngleFactor = 1.; // number of radiation angles 1/gamma:
// more fRadiationAngleFactor =>
// higher fParamPhotonAngleX and Y
///new particle parameters (the parameters at the point of radiation emission)
G4double fNewParticleEnergy=0;
@@ -277,14 +305,14 @@ private:
std::vector<G4int> fNPhotonsPerBin; //number of photons per spectrum bin
//(accumulating during total run)
std::vector<G4double> fSpectrum; //spectrum normalized by the total radiation probability
//of one particle at one call of RadIntegral
std::vector<G4double> fSpectrum; //spectrum normalized by the total
//radiation probability of one particle at one call of RadIntegral
std::vector<std::vector<G4double>> fAccumSpectrum; //accumulate Spectrum during
//the part of a trajectory
std::vector<G4double> fAccumTotalSpectrum; //spectrum normalized by the total radiation
//probability summed
std::vector<G4double> fAccumTotalSpectrum; //spectrum normalized by the total
//radiation probability summed
//for all the particles (is not divided
//of one particle number fNPhotonsPerBin)
@@ -295,8 +323,8 @@ private:
//multiplied by the number of trajectories
//(fItrajectories)
std::vector<G4double> fImax0; //trajectory element numbers at the end of each small piece
//G4double just for security of some operations
std::vector<G4double> fImax0; //trajectory element numbers at the end of each
//small piece; G4double just for security of some operations
///total radiation probability along this trajectory
std::vector<G4double> fTotalRadiationProbabilityAlongTrajectory;
};
@@ -77,11 +77,13 @@ public:
///calculate the horizontal angle in the co-rotating reference system
///within a channel (periodic cell)
///(connected with crystal planes/axes either bent or straight)
G4double AngleXFromBoxToLattice(G4double tx, G4double z){return tx-AngleXShift(z);}
G4double AngleXFromBoxToLattice(G4double tx, G4double z)
{return tx-AngleXShift(z)-GetCUtetax(z);}
///calculate the horizontal angle in the Box reference system
///(connected with the bounding box of the volume)
G4double AngleXFromLatticeToBox(G4double tx, G4double z){return tx+AngleXShift(z);}
G4double AngleXFromLatticeToBox(G4double tx, G4double z)
{return tx+AngleXShift(z)+GetCUtetax(z);}
///auxialiary function to transform the horizontal angle
G4double AngleXShift(G4double z){return fMiscutAngle + z*fCurv;}
@@ -99,7 +101,8 @@ private:
//inside the box; =0 in the case of planes
///values related to the crystal lattice
G4int fNpointsx=0,fNpointsy=0;// number of horizontal and vertical nodes of interpolation
G4int fNpointsx=0,fNpointsy=0;// number of horizontal and vertical nodes of
// interpolation
G4double fDx=0, fDy=0;// channel (periodic cell)
//horizontal and vertical dimensions
@@ -72,9 +72,9 @@ private:
G4double Spline1D(G4double xx);
G4double Spline2D(G4double xx, G4double yy);// cubic spline of 2-variable function
G4double fDx=0, fDy=0; //channel width and height
G4double fStepi=0, fStepj=0; //interpolation steps in x and y, respectively
G4double fStepi2=0; //=fStepi*fStepi
G4double fDx=0., fDy=0.; //channel width and height
G4double fStepi=0., fStepj=0.; //interpolation steps in x and y, respectively
G4double fStepi2=0.; //=fStepi*fStepi
G4int nPointsx=0, nPointsy=0; //number of interpolation nodes in x and y, respectively
std::vector <G4double> fAI;
@@ -107,7 +107,14 @@ public:
G4double GetMiscutAngle(){return fMiscutAngle;}
///get crystal curvature
G4double GetCurv(){return fCurv;}
///for crystalline undulator the curvature is a function, otherwise it's a constant
G4double GetCurv(G4double z){return fCU ? -fCUK2*GetCUx(z) : fCurv;}
///get crystalline undulator wave function
G4double GetCUx(G4double z){return fCUAmplitude*std::cos(fCUK*z+fCUPhase);}
///get crystalline undulator wave 1st derivative function
G4double GetCUtetax(G4double z){
return fCU ? -fCUAmplitudeK*std::sin(fCUK*z+fCUPhase) : 0;}
///find and upload crystal lattice input files, calculate all the basic values
///(to do only once)
@@ -128,6 +135,19 @@ public:
///otherwise geometry routines may be unstable
void SetMiscutAngle(G4double tetam, const G4LogicalVolume *crystallogic);
///set crystalline undulator parameters: amplitude, period and phase
/// (default: all 3 value = 0)
/// function to use in Detector Construction
void SetCrystallineUndulatorParameters(G4double amplitude,
G4double period,
G4double phase,
const G4LogicalVolume *crystallogic);
///set crystalline undulator parameters (internal function of the model)
///for convenience we put amplitude, period and phase in a G4ThreeVector
void SetCUParameters(const G4ThreeVector &amplitudePeriodPhase,
const G4LogicalVolume *crystallogic);
///recalculate all the important values
///(to do both at the trajectory start and after energy loss)
void SetParticleProperties(G4double etotal,
@@ -145,8 +165,7 @@ public:
virtual G4ThreeVector CoordinatesFromLatticeToBox(const G4ThreeVector &pos) = 0;
///change the channel if necessary, recalculate x o y
virtual G4ThreeVector ChannelChange(G4double& x, G4double& y,
G4double& z) = 0;
virtual G4ThreeVector ChannelChange(G4double& x, G4double& y, G4double& z) = 0;
///return correction of the longitudinal coordinate
/// (along current plane/axis vs "central plane/axis")
@@ -215,6 +234,14 @@ protected:
//(along current plane/axis vs "central plane/axis"), 1 is default value
//(for "central plane/axis" or a straight crystal)
G4bool fCU = false;//flag of crystalline undulator geometry
//(periodically bent crystal)
G4double fCUAmplitude=0.; //Amplitude of a crystalline undulator
G4double fCUK=0.; //2*pi/period of a crystalline undulator
G4double fCUPhase=0.;//Phase of a crystalline undulator
G4double fCUAmplitudeK=0.;//fCUAmplitude*fCUK
G4double fCUK2=0.; //fCUK^2
///values related to the crystal lattice
G4int fNelements=1;//number of nuclear elements in a crystal
G4int iModel=1;// model type (iModel=1 for interplanar potential,
@@ -278,6 +305,10 @@ private:
std::unordered_map<G4int, G4double> fMapMiscutAngle;//the map fMiscutAngle
//for different logical volumes
std::unordered_map<G4int, G4ThreeVector> fMapCUAmplitudePeriodPhase;//the map of
//AmplitudePeriodPhase
//for different logical volumes
G4double fChannelingStep=0;// simulation step under the channeling conditions =
//channeling oscillation length/fNsteps
// channeling oscillation length: Biryukov book Eq. (1.24)
@@ -30,6 +30,7 @@
#include "G4Gamma.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4Log.hh"
G4BaierKatkov::G4BaierKatkov()
{
@@ -40,6 +41,10 @@ G4BaierKatkov::G4BaierKatkov()
//Do not worry if the maximal energy > particle energy
//this elements of spectrum with non-physical energies
//will not be processed (they will be 0)
G4cout << " "<< G4endl;
G4cout << "G4BaierKatkov model is activated."<< G4endl;
G4cout << " "<< G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -106,7 +111,7 @@ void G4BaierKatkov::SetSpectrumEnergyRange(G4double emin,
fMaxPhotonEnergy = emax;
fNBinsSpectrum = numberOfBins;
fLogEmaxdEmin = std::log(fMaxPhotonEnergy/fMinPhotonEnergy);
fLogEmaxdEmin = G4Log(fMaxPhotonEnergy/fMinPhotonEnergy);
//in initializing fNPhotonsPerBin
fNPhotonsPerBin.resize(fNBinsSpectrum);
@@ -140,13 +145,100 @@ void G4BaierKatkov::SetSpectrumEnergyRange(G4double emin,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4BaierKatkov::AddStatisticsInPhotonEnergyRegion(G4double emin,
G4double emax,
G4int timesPhotonStatistics)
{
if(timesPhotonStatistics<=1)
{
G4cout << "G4BaierKatkov model, "
"function AddStatisticsInPhotonEnergyRegion("
<< emin/CLHEP::MeV << " MeV, "
<< emax/CLHEP::MeV << " MeV, "
<< timesPhotonStatistics << ")" << G4endl;
G4cout << "Warning: the statistics factor cannot be <=1." << G4endl;
G4cout << "The statistics was not added." << G4endl;
G4cout << " "<< G4endl;
}
else if(fMinPhotonEnergy>emin)
{
G4cout << "G4BaierKatkov model, "
"function AddStatisticsInPhotonEnergyRegion("
<< emin/CLHEP::MeV << " MeV, "
<< emax/CLHEP::MeV << " MeV, "
<< timesPhotonStatistics << ")" << G4endl;
G4cout << "Warning: the minimal energy inserted is less then "
"the minimal energy cut of the spectrum: "
<< fMinPhotonEnergy/CLHEP::MeV << " MeV." << G4endl;
G4cout << "The statistics was not added." << G4endl;
G4cout << " "<< G4endl;
}
else if(emax-emin<DBL_EPSILON)
{
G4cout << "G4BaierKatkov model, "
"function AddStatisticsInPhotonEnergyRegion("
<< emin/CLHEP::MeV << " MeV, "
<< emax/CLHEP::MeV << " MeV, "
<< timesPhotonStatistics << ")" << G4endl;
G4cout << "Warning: the maximal energy <= the minimal energy." << G4endl;
G4cout << "The statistics was not added." << G4endl;
G4cout << " "<< G4endl;
}
else
{
G4bool setrange = true;
G4double logAddRangeEmindEmin = G4Log(emin/fMinPhotonEnergy);
G4double logAddRangeEmaxdEmin = G4Log(emax/fMinPhotonEnergy);
G4int nAddRange = (G4int)fTimesPhotonStatistics.size();
for (G4int j=0;j<nAddRange;j++)
{
if((logAddRangeEmindEmin>=fLogAddRangeEmindEmin[j]&&
logAddRangeEmindEmin< fLogAddRangeEmaxdEmin[j])||
(logAddRangeEmaxdEmin> fLogAddRangeEmindEmin[j]&&
logAddRangeEmaxdEmin<=fLogAddRangeEmaxdEmin[j])||
(logAddRangeEmindEmin<=fLogAddRangeEmindEmin[j]&&
logAddRangeEmaxdEmin>=fLogAddRangeEmaxdEmin[j]))
{
G4cout << "G4BaierKatkov model, "
"function AddStatisticsInPhotonEnergyRegion("
<< emin/CLHEP::MeV << " MeV, "
<< emax/CLHEP::MeV << " MeV, "
<< timesPhotonStatistics << ")" << G4endl;
G4cout << "Warning: the energy range intersects another "
"added energy range." << G4endl;
G4cout << "The statistics was not added." << G4endl;
G4cout << " "<< G4endl;
setrange = false;
break;
}
}
if (setrange)
{
fLogAddRangeEmindEmin.push_back(logAddRangeEmindEmin);
fLogAddRangeEmaxdEmin.push_back(logAddRangeEmaxdEmin);
fTimesPhotonStatistics.push_back(timesPhotonStatistics);
G4cout << "G4BaierKatkov model: increasing the statistics of photon sampling "
"in Baier-Katkov with a factor of "
<< timesPhotonStatistics << G4endl;
G4cout << "in the energy spectrum range: ("
<< emin/CLHEP::MeV << " MeV, "
<< emax/CLHEP::MeV << " MeV)" << G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4BaierKatkov::SetPhotonSamplingParameters(G4double ekin,
G4double minPhotonAngleX,
G4double maxPhotonAngleX,
G4double minPhotonAngleY,
G4double maxPhotonAngleY)
{
fLogEdEmin = std::log(ekin/fMinPhotonEnergy);
fLogEdEmin = G4Log(ekin/fMinPhotonEnergy);
fMeanPhotonAngleX = (maxPhotonAngleX+minPhotonAngleX)/2.;
fParamPhotonAngleX = (maxPhotonAngleX-minPhotonAngleX)/2.;
fMeanPhotonAngleY = (maxPhotonAngleY+minPhotonAngleY)/2.;
@@ -161,28 +253,77 @@ void G4BaierKatkov::GeneratePhotonSampling()
fPhotonAngleInIntegralX.clear();
fPhotonAngleInIntegralY.clear();
fPhotonAngleNormCoef.clear();
fInsideVirtualCollimator.clear();
fIBinsSpectrum.clear();
G4double ksi=0.;
G4double rho=1.;
G4double rhocut=15.;//radial angular cut of the distribution
G4double norm=std::atan(rhocut*rhocut)*
CLHEP::pi*fParamPhotonAngleX*fParamPhotonAngleY;
std::vector<G4int> moreStatistics;
moreStatistics.resize(fTimesPhotonStatistics.size());
std::fill(moreStatistics.begin(), moreStatistics.end(), 0);
G4int nAddRange = (G4int)fTimesPhotonStatistics.size();
//sampling of the energy and the angles of a photon emission
//sampling of the energy of a photon emission
//(integration variables, Monte Carlo integration)
for (G4int j=0;j<fNMCPhotons;j++)
{
ksi = G4UniformRand();
ksi = G4UniformRand()*fLogEdEmin;
fIBinsSpectrum.push_back((G4int)std::trunc(
ksi*fNBinsSpectrum*fLogEdEmin/fLogEmaxdEmin));
ksi*fNBinsSpectrum/fLogEmaxdEmin));
//we consider also the energy outside the spectrum output range
//(E>Emax => fLogEdEmin>fLogEmaxdEmin)
//in this case we don't count the photon in the spectrum output
if(fIBinsSpectrum[j]<fNBinsSpectrum) {fNPhotonsPerBin[fIBinsSpectrum[j]]+=1;}
fPhotonEnergyInIntegral.push_back(fMinPhotonEnergy*std::exp(fLogEdEmin*ksi));
fPhotonEnergyInIntegral.push_back(fMinPhotonEnergy*std::exp(ksi));
fPhotonAngleNormCoef.push_back(1.);
for (G4int j2=0;j2<nAddRange;j2++)
{
if(ksi>fLogAddRangeEmindEmin[j2]&&
ksi<fLogAddRangeEmaxdEmin[j2])
{
//calculating the current statistics in this region
//to increase it proportionally
moreStatistics[j2]+=1;
fPhotonAngleNormCoef[j]/=fTimesPhotonStatistics[j2];
break;
}
}
}
for (G4int j2=0;j2<nAddRange;j2++)
{
G4int totalAddRangeStatistics = moreStatistics[j2]*fTimesPhotonStatistics[j2];
for (G4int j=moreStatistics[j2];j<totalAddRangeStatistics;j++)
{
ksi = fLogAddRangeEmindEmin[j2]+
G4UniformRand()*(std::min(fLogAddRangeEmaxdEmin[j2],fLogEdEmin)-
fLogAddRangeEmindEmin[j2]);
fIBinsSpectrum.push_back((G4int)std::trunc(
ksi*fNBinsSpectrum/fLogEmaxdEmin));
/* //we consider also the energy outside the spectrum output range
//(E>Emax => fLogEdEmin>fLogEmaxdEmin)
//in this case we don't count the photon in the spectrum output
if(fIBinsSpectrum.back()<fNBinsSpectrum)
{fNPhotonsPerBin[fIBinsSpectrum.back()]+=1;}*/
fPhotonEnergyInIntegral.push_back(fMinPhotonEnergy*std::exp(ksi));
fPhotonAngleNormCoef.push_back(1./fTimesPhotonStatistics[j2]);
}
}
G4double rho=1.;
const G4double rhocut=15.;//radial angular cut of the distribution
G4double norm=std::atan(rhocut*rhocut)*
CLHEP::pi*fParamPhotonAngleX*fParamPhotonAngleY;
//sampling of the angles of a photon emission
//(integration variables, Monte Carlo integration)
G4int nmctotal = (G4int)fPhotonEnergyInIntegral.size();
for (G4int j=0;j<nmctotal;j++)
{
//photon distribution with long tails (useful to not exclude particle angles
//after a strong single scattering)
//at ellipsescale < 1 => half of statistics of photons
@@ -199,11 +340,40 @@ void G4BaierKatkov::GeneratePhotonSampling()
fPhotonAngleInIntegralY.push_back(fMeanPhotonAngleY+
fParamPhotonAngleY*
rho*std::sin(CLHEP::twopi*ksi));
fPhotonAngleNormCoef.push_back((1.+rho*rho*rho*rho)*norm);
fPhotonAngleNormCoef[j]*=(1.+rho*rho*rho*rho)*norm;
//test if the photon with these angles enter the virtual collimator
//(doesn't influence the Geant4 simulations,
//but only the accumulation of fTotalSpectrum
fInsideVirtualCollimator.push_back(fVirtualCollimatorAngularDiameter >
std::sqrt(fPhotonAngleInIntegralX[j]*
fPhotonAngleInIntegralX[j]+
fPhotonAngleInIntegralY[j]*
fPhotonAngleInIntegralY[j]));
}
//reinitialize the vector of radiation CDF for each photon
fPhotonProductionCDF.resize(fNMCPhotons+1);// 0 element is equal to 0
fPhotonProductionCDF.resize(nmctotal+1);//0 element equal to 0
std::fill(fPhotonProductionCDF.begin(), fPhotonProductionCDF.end(), 0.);
//if we have additional photons
if (nmctotal>fNMCPhotons)
{
//reinitialize intermediate integrals with zeros again
fFa.resize(nmctotal);
fSs.resize(nmctotal);
fSc.resize(nmctotal);
fSsx.resize(nmctotal);
fSsy.resize(nmctotal);
fScx.resize(nmctotal);
fScy.resize(nmctotal);
std::fill(fFa.begin(), fFa.end(), 0.);
std::fill(fSs.begin(), fSs.end(), 0.);
std::fill(fSc.begin(), fSc.end(), 0.);
std::fill(fSsx.begin(), fSsx.end(), 0.);
std::fill(fSsy.begin(), fSsy.end(), 0.);
std::fill(fScx.begin(), fScx.end(), 0.);
std::fill(fScy.begin(), fScy.end(), 0.);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -270,13 +440,17 @@ G4double G4BaierKatkov::RadIntegral(G4double etotal, G4double mass,
G4double e2 = etotal*etotal;
G4double gammaInverse2 = mass*mass/(etotal*etotal);// 1/gamma^2 of
//the radiating charge particle
G4double coefNormLogdNMC = fLogEdEmin/fNMCPhotons;
G4double coefNormLogdNMC = fLogEdEmin/fNMCPhotons;//here fNMCPhotons is correct,
//additional photons have been already
//taken into account in weights
G4double coefNorm = CLHEP::fine_structure_const/(8*(CLHEP::pi2))*coefNormLogdNMC;
G4double e2pluseprime2 = 0.;//e2pluseprime2 =e2+eprime2
G4double coefNormom2deprime2 = 0.; //coefNormom2deprime2 = coefNorm*om2/eprime2;
G4double gammaInverse2om = 0.; //gammaInverse2*om
for (G4int j=0;j<fNMCPhotons;j++)
std::size_t nmctotal = fPhotonEnergyInIntegral.size();
for (std::size_t j=0;j<nmctotal;j++)
//the final number of photons may be different from fNMCPhotons
{
om = fPhotonEnergyInIntegral[j];
eprime=etotal-om; //E'=E-omega
@@ -342,7 +516,8 @@ G4double G4BaierKatkov::RadIntegral(G4double etotal, G4double mass,
//we consider also the energy outside the spectrum output range
//(E>Emax => fLogEdEmin>fLogEmaxdEmin)
//in this case we don't count the photon in the spectrum output
if(fIBinsSpectrum[j]<fNBinsSpectrum)
//we fill the spectrum only in case of the angles inside the virtual collimator
if((fIBinsSpectrum[j]<fNBinsSpectrum)&&fInsideVirtualCollimator[j])
{fSpectrum[fIBinsSpectrum[j]] += totalRadiationProbabilityPhj/
(om*coefNormLogdNMC);}
@@ -381,13 +556,15 @@ G4bool G4BaierKatkov::SetPhotonProductionParameters(G4double etotal, G4double ma
//Generally ksi = G4UniformRand() is ok, but
//we use as a correction for the case
//when the radiation probability becomes too high (> 0.1)
G4double ksi = -std::log(G4UniformRand());
G4double ksi = -G4Log(G4UniformRand());
if (ksi< fTotalRadiationProbabilityAlongTrajectory.back()) // photon produced
{
G4double ksi1 = G4UniformRand()*fTotalRadiationProbabilityAlongTrajectory.back();
//randomly choosing the photon to be produced from the sampling list
//according to the probabilities calculated in the Baier-Katkov integral
G4int iphoton = FindVectorIndex(fPhotonProductionCDF,ksi)-1;//index of
G4int iphoton = FindVectorIndex(fPhotonProductionCDF,ksi1)-1;//index of
//a photon produced
//energy of the photon produced
@@ -406,7 +583,7 @@ G4bool G4BaierKatkov::SetPhotonProductionParameters(G4double etotal, G4double ma
momentumDirectionZ);
//random calculation of the radiation point index (iNode)
ksi = G4UniformRand()*fTotalRadiationProbabilityAlongTrajectory.back();
//ksi = G4UniformRand()*fTotalRadiationProbabilityAlongTrajectory.back();
//sort fTotalRadiationProbabilityAlongTrajectory
//(increasing but oscillating function => non-monotonic)
@@ -524,8 +701,8 @@ G4bool G4BaierKatkov::DoRadiation(G4double etotal, G4double mass,
//set the angular limits at the start of the trajectory part
if(fImin0==0)
{
//radiation within the angle = +-4/gamma ("4" - just an empirical number)
G4double radiationAngleLimit=4*mass/etotal;
//radiation within the angle = +-fRadiationAngleFactor/gamma
G4double radiationAngleLimit=fRadiationAngleFactor*mass/etotal;
SetPhotonSamplingParameters(etotal-mass,
*std::min_element(fParticleAnglesX.begin(),
@@ -558,9 +735,11 @@ G4bool G4BaierKatkov::DoRadiation(G4double etotal, G4double mass,
if(fTotalRadiationProbability>fSinglePhotonRadiationProbabilityLimit||
flagEndTrajectory)
{
fItrajectories += 1; //count this trajectory !!!correction 19.07.2023
flagPhotonProduced = SetPhotonProductionParameters(etotal,mass);
fItrajectories += 1; //count this trajectory
// correction 19.07.2023 fItrajectories += 1; //count this trajectory
//reinitialize intermediate integrals fFa, fSs, fSc, fSsx, fSsy, fScx, fScy;
//reset radiation integral internal variables to defaults;
@@ -129,7 +129,8 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(const G4Material *cry
fVmax2=2.*fVmax;
//read the on-zero minimal potential inside the crystal,
//necessary for angle recalculation for entrance/exit through the crystal lateral surface
//necessary for angle recalculation for entrance/exit through
//the crystal lateral surface
vfilein >> fVMinCrystal;
fVMinCrystal*=eV;
@@ -316,6 +317,9 @@ G4ThreeVector G4ChannelingFastSimCrystalData::CoordinatesFromBoxToLattice
x = x0*fCosMiscutAngle - z0*fSinMiscutAngle;
y = y0;
z = x0*fSinMiscutAngle + z0*fCosMiscutAngle;
//for crystalline undulator
if(fCU){x-=GetCUx(z);}
}
//calculation of coordinates within a channel (periodic cell)
@@ -358,6 +362,9 @@ G4ThreeVector G4ChannelingFastSimCrystalData::CoordinatesFromLatticeToBox(
}
else
{
//for crystalline undulator
if(fCU){x+=GetCUx(z);}
//for straight crystal
x0 = x*fCosMiscutAngle + z*fSinMiscutAngle;
y0 = y;
@@ -37,7 +37,8 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ChannelingFastSimModel::G4ChannelingFastSimModel(const G4String& modelName, G4Region* envelope)
G4ChannelingFastSimModel::G4ChannelingFastSimModel(const G4String& modelName,
G4Region* envelope)
: G4VFastSimulationModel(modelName, envelope)
{
}
@@ -115,7 +116,8 @@ G4bool G4ChannelingFastSimModel::ModelTrigger(const G4FastTrack& fastTrack)
modelTrigger = (crystallogic->GetSolid()->
Inside(xyz0)==kInside) &&
momentumDirection.z()>0. &&
std::abs(angle) < GetLindhardAngleNumberHighLimit(particleDefinitionID) *
std::abs(angle) <
GetLindhardAngleNumberHighLimit(particleDefinitionID) *
fCrystalData->GetLindhardAngle(etotal,mass);
}
@@ -233,13 +235,13 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
//trajectory calculation:
//Runge-Cutt "3/8"
//fCrystalData->GetCurv()*fCrystalData->GetCorrectionZ() is due to dependence of
//fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ() is due to dependence of
//the radius on x; GetCurv gets 1/R for the central ("central plane/axis")
//first step
kvx1=fCrystalData->Ex(x,y);
x1=x+tx*dzd3;
tx1=tx+(kvx1-fCrystalData->GetCurv()*fCrystalData->GetCorrectionZ())*dzd3;
tx1=tx+(kvx1-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dzd3;
if (fCrystalData->GetModel()==2)
{
kvy1=fCrystalData->Ey(x,y);
@@ -250,8 +252,8 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
//second step
kvx2=fCrystalData->Ex(x1,y1);
x2=x-tx*dzd3+tx1*dz;
tx2=tx-(kvx1-fCrystalData->GetCurv()*fCrystalData->GetCorrectionZ())*dzd3+
(kvx2-fCrystalData->GetCurv()*fCrystalData->GetCorrectionZ())*dz;
tx2=tx-(kvx1-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dzd3+
(kvx2-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dz;
if (fCrystalData->GetModel()==2)
{
kvy2=fCrystalData->Ey(x1,y1);
@@ -262,7 +264,7 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
//third step
kvx3=fCrystalData->Ex(x2,y2);
x3=x+(tx-tx1+tx2)*dz;
tx3=tx+(kvx1-kvx2+kvx3-fCrystalData->GetCurv()*fCrystalData->GetCorrectionZ())*dz;
tx3=tx+(kvx1-kvx2+kvx3-fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ())*dz;
if (fCrystalData->GetModel()==2)
{
kvy3=fCrystalData->Ey(x2,y2);
@@ -274,7 +276,7 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
kvx4=fCrystalData->Ex(x3,y3);
x4=x+(tx+3.*tx1+3.*tx2+tx3)*dzd8;
tx4=tx+(kvx1+3.*kvx2+3.*kvx3+kvx4)*dzd8-
fCrystalData->GetCurv()*fCrystalData->GetCorrectionZ()*dz;
fCrystalData->GetCurv(z)*fCrystalData->GetCorrectionZ()*dz;
if (fCrystalData->GetModel()==2)
{
kvy4=fCrystalData->Ey(x3,y3);
@@ -27,6 +27,7 @@
#include "G4VChannelingFastSimCrystalData.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4Log.hh"
G4VChannelingFastSimCrystalData::G4VChannelingFastSimCrystalData()
{
@@ -44,15 +45,21 @@ void G4VChannelingFastSimCrystalData::SetGeometryParameters
{
G4int crystalID = crystallogic->GetInstanceID();
//set bending angle if the volume exists in the list, otherwise default = 0
//set bending angle if the it exists in the list, otherwise default = 0
(fMapBendingAngle.count(crystalID) > 0)
? SetBendingAngle(fMapBendingAngle[crystalID],crystallogic)
: SetBendingAngle(0.,crystallogic);
//set miscut angle if the volume exists in the list, otherwise default = 0
//set miscut angle if the it exists in the list, otherwise default = 0
(fMapMiscutAngle.count(crystalID) > 0)
? SetMiscutAngle(fMapMiscutAngle[crystalID],crystallogic)
: SetMiscutAngle(0.,crystallogic);
//set crystalline undulator parameters if they exist in the list,
//otherwise default = G4ThreeVector(0,0,0).
(fMapCUAmplitudePeriodPhase.count(crystalID) > 0)
? SetCUParameters(fMapCUAmplitudePeriodPhase[crystalID],crystallogic)
: SetCUParameters(G4ThreeVector(0.,0.,0.),crystallogic);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -78,6 +85,12 @@ void G4VChannelingFastSimCrystalData::SetBendingAngle(G4double tetab,
fBendingAngle=std::abs(tetab);
if (fBendingAngle<0.000001)//no bending less then 1 urad
{
if(fBendingAngle>DBL_EPSILON)
{
G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
G4cout << "Warning: bending angle is lower than 1 urad => set to 0" << G4endl;
}
fBent=0;
fBendingAngle=0.;
fBendingR=0.;//just for convenience (infinity in reality)
@@ -85,8 +98,7 @@ void G4VChannelingFastSimCrystalData::SetBendingAngle(G4double tetab,
fBendingRsquare=0.;
fCurv=0.;
G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
G4cout << "Warning: bending angle is lower than 1 urad => set to 0" << G4endl;
fCorrectionZ = 1.;
}
else
{
@@ -129,6 +141,72 @@ void G4VChannelingFastSimCrystalData::SetMiscutAngle(G4double tetam,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VChannelingFastSimCrystalData::SetCrystallineUndulatorParameters(
G4double amplitude,
G4double period,
G4double phase,
const G4LogicalVolume *crystallogic)
{
if (amplitude<DBL_EPSILON||period<DBL_EPSILON)
{
amplitude = 0.;
period=0.;
phase=0.;
G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
G4cout << "Warning: The crystalline undulator parameters are out of range "
"=> the crystalline undulator mode switched off" << G4endl;
}
SetCUParameters(G4ThreeVector(amplitude,period,phase),crystallogic);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VChannelingFastSimCrystalData::SetCUParameters(
const G4ThreeVector &amplitudePeriodPhase,
const G4LogicalVolume *crystallogic)
{
G4int crystalID = crystallogic->GetInstanceID();
//set the crystalline undulator parameters for this logical volume
fMapCUAmplitudePeriodPhase[crystalID]=amplitudePeriodPhase;
fCUAmplitude=amplitudePeriodPhase.x();
G4double period = amplitudePeriodPhase.y();
fCUPhase = amplitudePeriodPhase.z();
//if the amplidude of the crystalline undulator is 0 => no undulator
if(fCUAmplitude>DBL_EPSILON&&period>DBL_EPSILON)
{
//crystalline undulator flag
fCU = true;
fCUK = CLHEP::twopi/period;
if(fBendingAngle>DBL_EPSILON)
{
//bent and periodically bent crystal are not compatible
SetBendingAngle(0,crystallogic);
G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
G4cout << "Warning: crystalline undulator is not compatible with "
"a bent crystal mode => setting bending angle to 0." << G4endl;
}
}
else
{
fCU = false;
fCUAmplitude = 0.;
fCUK = 0.;
fCUPhase = 0.;
fMapCUAmplitudePeriodPhase[crystalID] = G4ThreeVector(0.,0.,0.);
}
fCUK2 = fCUK*fCUK;
fCUAmplitudeK = fCUAmplitude*fCUK;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VChannelingFastSimCrystalData::SetParticleProperties(G4double etotal,
G4double mass,
G4double charge,
@@ -286,7 +364,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombAtomicScattering(
G4double aa1=1.+aa;
// crystal, with scattering suppression
G4double tetamsi=e1*(std::log(aa1)+
G4double tetamsi=e1*(G4Log(aa1)+
(1.-std::exp(-aa*fBB[ielement]))/aa1+
fBBDEXP[ielement]*
(expint(fBB[ielement]*aa1)-fE1XBbb[ielement]));
@@ -297,7 +375,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombAtomicScattering(
// *(ln(1+a)+(1-exp(-a*b))/(1+a)+(1+b)*exp(b)*(E1XB(b*(1+a))-E1XB(b)))
ksi=G4UniformRand();
t=std::sqrt(-tetamsi*std::log(ksi));
t=std::sqrt(-tetamsi*G4Log(ksi));
ksi=G4UniformRand();
@@ -312,7 +390,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombAtomicScattering(
// (calculation of a distance, at which another single scattering can happen)
ksi=G4UniformRand();
zss=-std::log(ksi)*step/(e1*(1./teta122-1./fTetamax12[ielement]));
zss=-G4Log(ksi)*step/(e1*(1./teta122-1./fTetamax12[ielement]));
G4double tt;
// At some step several single scattering can occur.
@@ -353,7 +431,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombAtomicScattering(
// (calculation of a distance, at which another single scattering can happen)
ksi=G4UniformRand();
zss=-std::log(ksi)*step/(e1*(1./teta122-1./fTetamax12[ielement]));
zss=-G4Log(ksi)*step/(e1*(1./teta122-1./fTetamax12[ielement]));
}
//********************************************
return G4ThreeVector(tx,ty,0.);
@@ -388,7 +466,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombElectronScattering(
// simulation of scattering length (by the same way single scattering by nucleus
ksi=G4UniformRand();
zss=-1.0*std::log(ksi)/(fK3*electronDensity)/(1./eMinIonization-1./fTmax);
zss=-1.0*G4Log(ksi)/(fK3*electronDensity)/(1./eMinIonization-1./fTmax);
//********************************************
// if at a step a single scattering occur
@@ -417,7 +495,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombElectronScattering(
// (by the same way single scattering by nucleus
ksi=G4UniformRand();
zss=-1.0*std::log(ksi)/(fK3*electronDensity)/(1./eMinIonization-1./fTmax);
zss=-1.0*G4Log(ksi)/(fK3*electronDensity)/(1./eMinIonization-1./fTmax);
}
//********************************************
}
@@ -431,7 +509,7 @@ G4double G4VChannelingFastSimCrystalData::IonizationLosses(G4double dz,
{
G4double elosses = 0.;
if (fHadron) {elosses=fKD[ielement]/fV2*
(std::log(fMe2Gamma*fV2/fI0[ielement]/fGamma) - fV2)*dz;}
(G4Log(fMe2Gamma*fV2/fI0[ielement]/fGamma) - fV2)*dz;}
return elosses;
}
@@ -465,7 +543,7 @@ else if (X<=1.)
if (std::abs(R)<=std::abs(E1)*1.0e-15) {break;}
}
E1=-0.5772156649015328-std::log(X)+X*E1;
E1=-0.5772156649015328-G4Log(X)+X*E1;
}
else
{
+6
View File
@@ -6,6 +6,12 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2023-10-19 Ben Morgan (gflash-V11-01-01)
- Replace use of deprecated functions with modern equivalents
## 2023-08-29 Ben Morgan (gflash-V11-01-00)
- Fix Coverity warnings for uninitialized data members.
## 2022-11-18 Gabriele Cosmo (gflash-V11-00-03)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -35,7 +35,6 @@ geant4_module_link_libraries(G4gflash
G4partman
G4navigation
G4geometrymng
G4volumes
G4intercoms
G4globman
PRIVATE
@@ -61,6 +61,7 @@ GFlashShowerModel::GFlashShowerModel(G4String modelName,
FlagParamType = 0;
FlagParticleContainment = 1;
StepInX0 = 0.1;
EnergyStop = 0.0;
Messenger = new GFlashShowerModelMessenger(this);
}
@@ -71,6 +72,7 @@ GFlashShowerModel::GFlashShowerModel(G4String modelName)
FlagParamType =1;
FlagParticleContainment = 1;
StepInX0 = 0.1;
EnergyStop = 0.0;
Messenger = new GFlashShowerModelMessenger(this);
}
@@ -193,8 +195,8 @@ GFlashShowerModel::ElectronDoIt(const G4FastTrack& fastTrack,
// std::cout<<"--- ElectronDoit --- "<<std::endl;
fastStep.KillPrimaryTrack();
fastStep.SetPrimaryTrackPathLength(0.0);
fastStep.SetTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->
fastStep.ProposePrimaryTrackPathLength(0.0);
fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->
GetKineticEnergy());
//-----------------------------