Import Geant4 11.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2025-12-05 08:54:02 +01:00
parent a499fb82e9
commit b4a16de652
6484 changed files with 232674 additions and 221097 deletions
@@ -6,6 +6,22 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-09-10 Gabriele Cosmo (fastsimchanneling-V11-03-02)
- Fixed compilation warnings on macOS/XCode for implicit type conversions
in G4VChannelingFastSimCrystalData.
## 2025-08-16 Alexei Sytov (fastsimchanneling-V11-03-01)
- Considerable updates of functionality:
- Introduced reading from an input file of custom internal geometry of
a periodically bent crystal which also works, if necessary, with multiple
input files, each per logical volume of an oriented crystal;
- Introduced various types of radiation virtual collimators in
G4BaierKatkov;
- Deleted redundant lines setting up the defaults of angular and low
energy cuts in void G4ChannelingFastSimModel::Input;
- Polishing of the code according to the Geant4 guidelines.
NOT AFFECTING THE CURRENT VERSION OF EXISTING EXAMPLES ch1, ch2, ch3.
## 2025-04-06 Dmitri Konstantinov (fastsimchanneling-V11-03-00)
- In G4VChannelingFastSimCrystalData::IonizationLosses(), fixed bug
in the electron ionization loss correction formula.
@@ -32,7 +32,7 @@
#define G4BaierKatkov_h 1
#include "globals.hh"
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4ios.hh"
#include <vector>
#include "G4ThreeVector.hh"
@@ -160,8 +160,38 @@ public:
/// Virtual collimator masks the selection of photon angles in fTotalSpectrum
/// Virtual collimator doesn't influence on Geant4 simulations.
void SetVirtualCollimator(G4double virtualCollimatorAngularDiameter)
{fVirtualCollimatorAngularDiameter=virtualCollimatorAngularDiameter;}
void SetRoundVirtualCollimator(G4double virtualCollimatorAngularRadius,
G4double virtualCollimatorAngularCenterX = 0.,
G4double virtualCollimatorAngularCenterY = 0.)
{fVirtualCollimatorAngularHalfWidthX2 = virtualCollimatorAngularRadius*
virtualCollimatorAngularRadius;
fVirtualCollimatorAngularHalfWidthY2 = fVirtualCollimatorAngularHalfWidthX2;
fVirtualCollimatorAngularCenterX = virtualCollimatorAngularCenterX;
fVirtualCollimatorAngularCenterY = virtualCollimatorAngularCenterY;
fVirtualCollimatorTypeID = 1;}
void SetEllipticVirtualCollimator(G4double virtualCollimatorAngularRadiusX,
G4double virtualCollimatorAngularRadiusY,
G4double virtualCollimatorAngularCenterX = 0.,
G4double virtualCollimatorAngularCenterY = 0.)
{fVirtualCollimatorAngularHalfWidthX2 = virtualCollimatorAngularRadiusX*
virtualCollimatorAngularRadiusX;
fVirtualCollimatorAngularHalfWidthY2 = virtualCollimatorAngularRadiusY*
virtualCollimatorAngularRadiusY;
fVirtualCollimatorAngularCenterX = virtualCollimatorAngularCenterX;
fVirtualCollimatorAngularCenterY = virtualCollimatorAngularCenterY;
fVirtualCollimatorTypeID = 1;}
void SetRectangularVirtualCollimator(G4double virtualCollimatorAngularHalfWidthX,
G4double virtualCollimatorAngularHalfWidthY,
G4double virtualCollimatorAngularCenterX = 0.,
G4double virtualCollimatorAngularCenterY = 0.)
{fVirtualCollimatorAngularHalfWidthX = virtualCollimatorAngularHalfWidthX;
fVirtualCollimatorAngularHalfWidthY = virtualCollimatorAngularHalfWidthY;
fVirtualCollimatorAngularCenterX = virtualCollimatorAngularCenterX;
fVirtualCollimatorAngularCenterY = virtualCollimatorAngularCenterY;
fVirtualCollimatorTypeID = 2;}
/// add the new elements of the trajectory, calculate radiation in a crystal
/// see complete description in G4BaierKatkov::DoRadiation
@@ -239,8 +269,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
G4double fVirtualCollimatorAngularHalfWidthX = 1.;//angular half width in X
G4double fVirtualCollimatorAngularHalfWidthY = 1.;//angular half width in Y
G4double fVirtualCollimatorAngularHalfWidthX2=1.;//angular half width X square
G4double fVirtualCollimatorAngularHalfWidthY2=1.;//angular half width Y square
G4double fVirtualCollimatorAngularCenterX = 0.;// angular center
G4double fVirtualCollimatorAngularCenterY = 0.;// angular center
std::vector<G4bool> fInsideVirtualCollimator;
G4int fVirtualCollimatorTypeID = 0; //0 - infinite, 1 - round or ellipse, 2 - rectangular
///data of the phootn energy range with additional statistics
std::vector<G4double> fLogAddRangeEmindEmin;//=G4Log(emin/fMinPhotonEnergy)
@@ -29,16 +29,13 @@
#ifndef G4ChannelingFastSimCrystalData_h
#define G4ChannelingFastSimCrystalData_h 1
#include "G4ios.hh"
#include "globals.hh"
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4ThreeVector.hh"
#include "Randomize.hh"
#include "G4Material.hh"
#include <unordered_map>
#include "globals.hh"
#include "G4ios.hh"
#include "G4ThreeVector.hh"
#include "G4Material.hh"
#include "G4VChannelingFastSimCrystalData.hh"
#include "G4ChannelingFastSimInterpolation.hh"
/** \file G4ChannelingFastSimCrystalData.hh
* \brief Definition of the G4ChannelingFastSimCrystalData class
@@ -54,10 +51,8 @@ class G4ChannelingFastSimCrystalData : public G4VChannelingFastSimCrystalData
{
public:
G4ChannelingFastSimCrystalData();
virtual ~G4ChannelingFastSimCrystalData() = default;
public:
G4ChannelingFastSimCrystalData() = default;
~G4ChannelingFastSimCrystalData() = default;
///find and upload crystal lattice input files, calculate all the basic values
///(to do only once)
@@ -28,10 +28,9 @@
#ifndef G4ChannelingFastSimInterpolation_h
#define G4ChannelingFastSimInterpolation_h
#include "G4PhysicsVector.hh"
#include "G4Physics2DVector.hh"
#include "G4ThreeVector.hh"
#include "G4PhysicsLinearVector.hh"
#include "globals.hh"
#include "G4ios.hh"
#include <vector>
/** \file G4ChannelingFastSimInterpolation.hh
* \brief Definition of the G4ChannelingFastSimInterpolation class
@@ -32,11 +32,8 @@
#define G4ChannelingFastSimModel_h 1
#include "G4VFastSimulationModel.hh"
#include "G4Step.hh"
#include "G4TouchableHandle.hh"
#include <vector>
#include <CLHEP/Units/SystemOfUnits.h>
#include <CLHEP/Units/PhysicalConstants.h>
#include "globals.hh"
#include "G4ios.hh"
#include "G4ChannelingFastSimCrystalData.hh"
#include <unordered_map>
@@ -57,7 +54,7 @@ public:
// Constructor, destructor
G4ChannelingFastSimModel (const G4String&, G4Region*);
G4ChannelingFastSimModel (const G4String&);
~G4ChannelingFastSimModel ();
~G4ChannelingFastSimModel () = default;
/// -- IsApplicable
G4bool IsApplicable(const G4ParticleDefinition&) override;
@@ -31,14 +31,15 @@
#ifndef G4VChannelingFastSimCrystalData_h
#define G4VChannelingFastSimCrystalData_h 1
#include "G4ios.hh"
#include "globals.hh"
#include "G4ios.hh"
#include "G4ThreeVector.hh"
#include "Randomize.hh"
#include "G4LogicalVolume.hh"
#include "G4Material.hh"
#include "G4VSolid.hh"
#include <unordered_map>
#include "G4PhysicsLinearVector.hh"
#include "G4ChannelingFastSimInterpolation.hh"
@@ -111,13 +112,26 @@ public:
///get crystal curvature
///for crystalline undulator the curvature is a function, otherwise it's a constant
G4double GetCurv(G4double z){return fCU ? -fCUK2*GetCUx(z) : fCurv;}
G4double GetCurv(G4double z)
{return fCU ? //select between a crystalline undulator (CU) and a bent crystal
( fImportCrystalGeometry ? //select between a realistic and an ideal CU
fVecCUCurv[fCUID].Value(z) :
-fCUK2*GetCUx(z)) :
fCurv;}
///get crystalline undulator wave function
G4double GetCUx(G4double z){return fCUAmplitude*std::cos(fCUK*z+fCUPhase);}
G4double GetCUx(G4double z)
{return fImportCrystalGeometry ? //select between a realistic and an ideal CU
fVecCUx[fCUID].Value(z) :
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;}
G4double GetCUtetax(G4double z)
{return fCU ? //select between a crystalline undulator (CU) and a bent crystal
( fImportCrystalGeometry ? //select between a realistic and an ideal CU
fVecCUtetax[fCUID].Value(z) :
-fCUAmplitudeK*std::sin(fCUK*z+fCUPhase)) :
0.;}
///find and upload crystal lattice input files, calculate all the basic values
///(to do only once)
@@ -147,6 +161,10 @@ public:
G4double phase,
const G4LogicalVolume *crystallogic);
///set importing geometry of a crystalline undulator from file for specific volume
void SetCrystallineUndulatorParameters(const G4LogicalVolume *crystallogic,
const G4String &filename = "CUgeometry.dat");
///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,
@@ -296,9 +314,31 @@ protected:
//Variable to control printout
G4int fVerbosity = 1;
private:
///variables for realistic crystalline undulator
// flag of custom crystal geometry uploaded from a file
G4bool fImportCrystalGeometry = false;
//crystalline undulator wave function data (realistic crystalline undulator)
std::vector <G4PhysicsLinearVector> fVecCUx;
//crystalline undulator 1st derivative wave function data (realistic crystalline undulator)
std::vector <G4PhysicsLinearVector> fVecCUtetax;
//crystalline undulator curvature (realistic crystalline undulator)
std::vector <G4PhysicsLinearVector> fVecCUCurv;
std::unordered_map<G4int, G4ThreeVector> fMapCUAmplitudePeriodPhase;//the map of
//AmplitudePeriodPhase
//for different logical volumes
std::unordered_map<G4int, G4bool> fMapImportCrystalGeometry;//the map of
//fImportCrystalGeometry flag
//for different logical volumes
std::unordered_map<G4int, G4int> fMapCUID;//the map of the crystalline undulator ID
G4int fCUID = 0; //current logical volume ID for the crystalline undulator
//exponential integral
G4double expint(G4double x);
@@ -310,9 +350,6 @@ 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
@@ -24,11 +24,11 @@ geant4_add_module(G4channeling
G4heprandom
G4materials
G4parameterisation
G4track
G4partman
G4procman
PRIVATE
G4bosons
G4navigation
G4track
G4leptons
G4emutils)
@@ -32,15 +32,13 @@
#include "Randomize.hh"
#include "G4Gamma.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4Log.hh"
G4BaierKatkov::G4BaierKatkov()
{
//sets the default spectrum energy range of integration and
//calls ResetRadIntegral()
SetSpectrumEnergyRange(0.1*MeV,1.*GeV,110);
SetSpectrumEnergyRange(0.1*CLHEP::MeV,1.*CLHEP::GeV,110);
//Do not worry if the maximal energy > particle energy
//this elements of spectrum with non-physical energies
@@ -76,12 +74,12 @@ void G4BaierKatkov::ResetRadIntegral()
//Reset radiation integral internal variables to defaults
fMeanPhotonAngleX =0.; //average angle of
//radiated photon direction in sampling, x-plane
fParamPhotonAngleX=1.e-3*rad; //a parameter of
//radiated photon sampling distribution, x-plane
fParamPhotonAngleX=1.e-3*CLHEP::rad; //a parameter of
//radiated photon sampling distribution, x-plane
fMeanPhotonAngleY =0.; //average angle of
//radiated photon direction in sampling, y-plane
fParamPhotonAngleY=1.e-3*rad; //a parameter of
//radiated photon sampling distribution, y-plane
fParamPhotonAngleY=1.e-3*CLHEP::rad; //a parameter of
//radiated photon sampling distribution, y-plane
fImin0 = 0;//set the first vector element to 0
@@ -349,11 +347,25 @@ void G4BaierKatkov::GeneratePhotonSampling()
//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]));
if(fVirtualCollimatorTypeID == 1) //round or ellipse collimator
{
fInsideVirtualCollimator.push_back(1. >
std::sqrt((fPhotonAngleInIntegralX[j]-fVirtualCollimatorAngularCenterX)*
(fPhotonAngleInIntegralX[j]-fVirtualCollimatorAngularCenterX)/
fVirtualCollimatorAngularHalfWidthX2 +
(fPhotonAngleInIntegralY[j]-fVirtualCollimatorAngularCenterY)*
(fPhotonAngleInIntegralY[j]-fVirtualCollimatorAngularCenterY)/
fVirtualCollimatorAngularHalfWidthY2));
}
else if (fVirtualCollimatorTypeID == 2) //rectangular collimator
{
fInsideVirtualCollimator.push_back(
std::abs(fPhotonAngleInIntegralX[j]-fVirtualCollimatorAngularCenterX) <
fVirtualCollimatorAngularHalfWidthX&&
std::abs(fPhotonAngleInIntegralY[j]-fVirtualCollimatorAngularCenterY) <
fVirtualCollimatorAngularHalfWidthY);
}
else{fInsideVirtualCollimator.push_back(true);}//default - infinite collimator
}
//reinitialize the vector of radiation CDF for each photon
fPhotonProductionCDF.resize(nmctotal+1);//0 element equal to 0
@@ -586,9 +598,6 @@ G4bool G4BaierKatkov::SetPhotonProductionParameters(G4double etotal, G4double ma
momentumDirectionZ*std::tan(photonAngleY),
momentumDirectionZ);
//random calculation of the radiation point index (iNode)
//ksi = G4UniformRand()*fTotalRadiationProbabilityAlongTrajectory.back();
//sort fTotalRadiationProbabilityAlongTrajectory
//(increasing but oscillating function => non-monotonic)
std::vector<G4double> temporaryVector;
@@ -743,8 +752,6 @@ G4bool G4BaierKatkov::DoRadiation(G4double etotal, G4double mass,
flagPhotonProduced = SetPhotonProductionParameters(etotal,mass);
// 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;
//reset the trajectory and radiation probability along the trajectory
@@ -27,15 +27,6 @@
// Co-author: Gianfranco Paternò (modifications & testing)
#include "G4ChannelingFastSimCrystalData.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
G4ChannelingFastSimCrystalData::G4ChannelingFastSimCrystalData()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4ChannelingFastSimCrystalData::SetMaterialProperties(
const G4Material *crystal,
@@ -119,21 +110,21 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
for(G4int i=0; i<fNelements; i++)
{
vfilein >> var;
fN0.push_back(var/cm3);
fN0.push_back(var/CLHEP::cm3);
}
//read amplitude of thermal oscillations
for(G4int i=0; i<fNelements; i++)
{
vfilein >> var;
fU1.push_back(var*cm);
fU1.push_back(var*CLHEP::cm);
}
if (iModel==1)
{
// read channel dimensions
vfilein >> fDx;
fDx*=cm;
fDx*=CLHEP::cm;
// read interpolation step size
vfilein >> fNpointsx;
@@ -144,22 +135,22 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
{
// read channel dimensions
vfilein >> fDx >> fDy;
fDx*=cm;
fDy*=cm;
fDx*=CLHEP::cm;
fDy*=CLHEP::cm;
// read the number of nodes of interpolation
vfilein >> fNpointsx >> fNpointsy;
}
//read the height of the potential well, necessary only for step length calculation
vfilein >> fVmax;
fVmax*=eV;
fVmax*=CLHEP::eV;
fVmax2=2.*fVmax;
//read the on-zero minimal potential inside the crystal,
//necessary for angle recalculation for entrance/exit through
//the crystal lateral surface
vfilein >> fVMinCrystal;
fVMinCrystal*=eV;
fVMinCrystal*=CLHEP::eV;
// to create the class of interpolation for any function
fElectricFieldX =
@@ -186,7 +177,7 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
//reading the coefficients of cubic spline
vfilein >> ai >> bi >> ci >> di;
//setting spline coefficients for electric field
unitIF=eV/cm;
unitIF=CLHEP::eV/CLHEP::cm;
fElectricFieldX->SetCoefficients1D(ai*unitIF, bi*unitIF,
ci*unitIF, di*unitIF, i);
@@ -200,14 +191,14 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
//reading the coefficients of cubic spline
vfilein >> ai >> bi >> ci >> di;
//setting spline coefficients for electron density
unitIF=1./cm3;
unitIF=1./CLHEP::cm3;
fElectronDensity->SetCoefficients1D(ai*unitIF, bi*unitIF,
ci*unitIF, di*unitIF, i);
//reading the coefficients of cubic spline
vfilein >> ai >> bi >> ci >> di;
//setting spline coefficients for minimal ionization energy
unitIF=eV;
unitIF=CLHEP::eV;
fMinIonizationEnergy->SetCoefficients1D(ai*unitIF, bi*unitIF,
ci*unitIF, di*unitIF, i);
@@ -233,7 +224,7 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
{
//reading the coefficients of cubic spline
vfilein >> ai3D >> bi3D >> ci3D;
unitIF=eV;
unitIF=CLHEP::eV;
//setting spline coefficients for minimal ionization energy
fMinIonizationEnergy->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
i, j, k);
@@ -241,14 +232,14 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
//reading the coefficients of cubic spline
vfilein >> ai3D >> bi3D >> ci3D;
//setting spline coefficients for horizontal electric field
unitIF=eV/cm;
unitIF=CLHEP::eV/CLHEP::cm;
fElectricFieldX->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
i, j, k);
//reading the coefficients of cubic spline
vfilein >> ai3D >> bi3D >> ci3D;
//setting spline coefficients for vertical electric field
unitIF=eV/cm;
unitIF=CLHEP::eV/CLHEP::cm;
fElectricFieldY->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
i, j, k);
@@ -262,7 +253,7 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
//reading the coefficients of cubic spline
vfilein >> ai3D >> bi3D >> ci3D;
//setting spline coefficients for electron density
unitIF=1./cm3;
unitIF=1./CLHEP::cm3;
fElectronDensity->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
i, j, k);
@@ -291,7 +282,7 @@ void G4ChannelingFastSimCrystalData::SetMaterialProperties(
for(G4int i=0; i<fNelements; i++)
{
fRF.push_back((std::pow(9*CLHEP::pi*CLHEP::pi/128/fZ1[i],1/3.))
*0.5291772109217*angstrom);//Thomas-Fermi screening radius
*0.5291772109217*CLHEP::angstrom);//Thomas-Fermi screening radius
fTetamax0.push_back(CLHEP::hbarc/(fR0*std::pow(fAN[i],1./3.)));
fTeta10.push_back(CLHEP::hbarc/fRF[i]);
@@ -93,9 +93,9 @@ void G4ChannelingFastSimInterpolation::SetCoefficients1D(G4double AI0,
G4double DI0,
G4int i){
fAI[i] = AI0;
fBI[i] = BI0/cm;
fCI[i] = CI0/cm2;
fDI[i] = DI0/cm3;
fBI[i] = BI0/CLHEP::cm;
fCI[i] = CI0/CLHEP::cm2;
fDI[i] = DI0/CLHEP::cm3;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -110,13 +110,13 @@ void G4ChannelingFastSimInterpolation::SetCoefficients2D(G4double AI3D0,
{
fAI3D[i][j] = AI3D0/fStepj/fStepi/6.;
fBI3D[i][j] = BI3D0/fStepj/fStepi/6.;
fCI3D[i][j] = CI3D0/fStepj/fStepi/6./cm2;
fCI3D[i][j] = CI3D0/fStepj/fStepi/6./CLHEP::cm2;
}
else if (k==1)
{
fAI3D3[i][j] = AI3D0/fStepj/fStepi/6./cm2;
fBI3D3[i][j] = BI3D0/fStepj/fStepi/6./cm2;
fCI3D3[i][j] = CI3D0/fStepj/fStepi/6./cm2/cm2;
fAI3D3[i][j] = AI3D0/fStepj/fStepi/6./CLHEP::cm2;
fBI3D3[i][j] = BI3D0/fStepj/fStepi/6./CLHEP::cm2;
fCI3D3[i][j] = CI3D0/fStepj/fStepi/6./CLHEP::cm2/CLHEP::cm2;
}
}
@@ -35,11 +35,6 @@
//
#include "G4ChannelingFastSimModel.hh"
#include "Randomize.hh"
#include "G4TransportationManager.hh"
#include "G4SystemOfUnits.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ChannelingFastSimModel::G4ChannelingFastSimModel(const G4String& modelName,
@@ -58,12 +53,6 @@ G4ChannelingFastSimModel::G4ChannelingFastSimModel(const G4String& modelName)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ChannelingFastSimModel::~G4ChannelingFastSimModel()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4ChannelingFastSimModel::IsApplicable(const G4ParticleDefinition& particleType)
{
return std::abs(particleType.GetPDGCharge())>DBL_EPSILON;
@@ -445,12 +434,12 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
eDeposited += elossAccum;
elossAccum=0;
ekinetic = etotal-mass;
if(ekinetic<1*keV)
if(ekinetic<1*CLHEP::keV)
{
G4cout << "Warning in G4ChannelingFastSimModel: " <<
ekinetic << "<" << 1*keV << " !" << G4endl;
eDeposited-=(1*keV-ekinetic);
ekinetic = 1*keV;
ekinetic << "<" << 1*CLHEP::keV << " !" << G4endl;
eDeposited-=(1*CLHEP::keV-ekinetic);
ekinetic = 1*CLHEP::keV;
G4cout << "Setting deposited energy=" <<
eDeposited << " & ekinetic=" << ekinetic << G4endl;
etotal = mass+ekinetic;
@@ -503,12 +492,12 @@ void G4ChannelingFastSimModel::DoIt(const G4FastTrack& fastTrack,
etotal -= elossAccum;
eDeposited += elossAccum;
ekinetic = etotal-mass;
if(ekinetic<1*keV)
if(ekinetic<1*CLHEP::keV)
{
G4cout << "Warning in G4ChannelingFastSimModel: " <<
ekinetic << "<" << 1*keV << " !" << G4endl;
eDeposited-=(1*keV-ekinetic);
ekinetic = 1*keV;
ekinetic << "<" << 1*CLHEP::keV << " !" << G4endl;
eDeposited-=(1*CLHEP::keV-ekinetic);
ekinetic = 1*CLHEP::keV;
G4cout << "Setting deposited energy=" <<
eDeposited << " & ekinetic=" << ekinetic << G4endl;
}
@@ -538,18 +527,6 @@ void G4ChannelingFastSimModel::Input(const G4Material *crystal,
fCrystalData = new G4ChannelingFastSimCrystalData();
//setting all the crystal material and lattice data
fCrystalData->SetMaterialProperties(crystal,lattice,filePath);
//setting default low energy cuts for kinetic energy
SetLowKineticEnergyLimit(1*GeV,"proton");
SetLowKineticEnergyLimit(1*GeV,"anti_proton");
SetLowKineticEnergyLimit(200*MeV,"e-");
SetLowKineticEnergyLimit(200*MeV,"e+");
//set the model high limit of the angle expressed in [Lindhard angle] units
SetLindhardAngleNumberHighLimit(100.,"proton");
SetLindhardAngleNumberHighLimit(100.,"anti_proton");
SetLindhardAngleNumberHighLimit(100.,"e-");
SetLindhardAngleNumberHighLimit(100.,"e+");
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -29,18 +29,13 @@
// A. I. Sytov, V. V. Tikhomirov, and L. Bandiera PRAB 22, 064601 (2019)
#include "G4VChannelingFastSimCrystalData.hh"
#include "G4SystemOfUnits.hh"
#include "G4PhysicalConstants.hh"
#include "G4Log.hh"
G4VChannelingFastSimCrystalData::G4VChannelingFastSimCrystalData()
{
}
G4VChannelingFastSimCrystalData::G4VChannelingFastSimCrystalData(){}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VChannelingFastSimCrystalData::~G4VChannelingFastSimCrystalData(){;}
G4VChannelingFastSimCrystalData::~G4VChannelingFastSimCrystalData(){}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -133,7 +128,7 @@ void G4VChannelingFastSimCrystalData::SetMiscutAngle(G4double tetam,
// fMiscutAngle>0: rotation of xz coordinate planes clockwise in the xz plane
fMiscutAngle=tetam;
if (std::abs(tetam)>1.*mrad)
if (std::abs(tetam)>1.*CLHEP::mrad)
{
G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
G4cout << "Warning: miscut angle is higher than 1 mrad => " << G4endl;
@@ -166,6 +161,133 @@ void G4VChannelingFastSimCrystalData::SetCrystallineUndulatorParameters(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VChannelingFastSimCrystalData::SetCrystallineUndulatorParameters(
const G4LogicalVolume *crystallogic,
const G4String &filename)
{
G4int crystalID = crystallogic->GetInstanceID();
fMapImportCrystalGeometry[crystalID] = true;
G4PhysicsLinearVector vec(true); //CU geometry data x=f(z) - transverse coordinate vs longitudinal
G4PhysicsLinearVector vecD(true); // = first derivative of vec
G4PhysicsLinearVector vecDD(true);// = second derivative of vec
//open input file for CU data
std::ifstream vfilein;
vfilein.open(filename);
if (!vfilein) {
G4String message = "Input file " +
filename +
" is not found!";
G4Exception("SetCrystallineUndulatorParameters",// Origin of the exception
"001", // Unique error code
FatalException, // Terminate the program
message);
}
G4cout << "Importing the Crystal geometry from the file: "
<< filename << G4endl;
//reading from file
//CAUTION: all the values in the file in mm!!!
vec.Retrieve(vfilein,true);
vfilein.close();
//check the start coordinate (10.*DBL_EPSILON to add more flexibility, if not equal, no problem)
if(std::abs(vec.GetMinEnergy()) > 10.*DBL_EPSILON)
{
G4Exception("SetCrystallineUndulatorParameters",// Origin of the exception
"001", // Unique error code
FatalException, // Terminate the program
"The interpolation of the crystalline undulator does not start from 0.! "
"The program will terminate.");
}
//check the end coordinate (1.e8*DBL_EPSILON - single precision check)
if(std::abs(vec.GetMaxEnergy() - 2.*fHalfDimBoundingBox.z()) > 100000000.*DBL_EPSILON)
{
G4Exception("SetCrystallineUndulatorParameters",// Origin of the exception
"001", // Unique error code
FatalException, // Terminate the program
"The interpolation of the crystalline undulator does not end with at"
"the boundary of the volume => check the crystal thickness in z! "
"The program will terminate.");
}
// Get the total length of vectors
std::size_t inodes = vec.GetVectorLength();
//check if the interpolation nodes are equidistant (otherwise )
for(std::size_t i=1; i<inodes-1; i++)
{
if(std::abs((vec.Energy(i+1)-vec.Energy(i))-
(vec.Energy(i) -vec.Energy(i-1)))>100000000.*DBL_EPSILON)//single precision
{
G4String message = "The interpolation nodes in the file " + filename +
" are not equidistant! The program will terminate.";
G4Exception("SetCrystallineUndulatorParameters",// Origin of the exception
"001", // Unique error code
FatalException, // Terminate the program
message);
}
}
//necessary to use spline interpolation
vec.FillSecondDerivatives(G4SplineType::Base);
//setting up the vectors (to have the same arguments)
vecD = vec;
vecDD = vec;
//calculating the derivatives
for(std::size_t i=1; i<inodes-1; i++)
{
vecD.PutValue(i,(vec[i+1]-vec[i-1])/(vec.Energy(i+1)-vec.Energy(i-1)));
vecDD.PutValue(i,((vec[i+1]-vec[i])/(vec.Energy(i+1)-vec.Energy(i)) -
(vec[i]-vec[i-1])/(vec.Energy(i)-vec.Energy(i-1)))*
2./(vec.Energy(i+1)-vec.Energy(i-1)));
}
//end points have the same values as neighbouring
vecD.PutValue(0,vecD[1]);
vecD.PutValue(inodes-1,vecD[inodes-2]);
vecDD.PutValue(0,vecDD[1]);
vecDD.PutValue(inodes-1,vecDD[inodes-2]);
//necessary to use spline interpolation
vecD.FillSecondDerivatives(G4SplineType::Base);
vecDD.FillSecondDerivatives(G4SplineType::Base);
fVecCUx.push_back(vec);
fVecCUtetax.push_back(vecD);
fVecCUCurv.push_back(vecDD);
//check if the fVecCUx was already set up for this logical volume
if(fMapCUID.count(crystalID) > 0)
{
G4Exception("SetCrystallineUndulatorParameters",// Origin of the exception
"001", // Unique error code
FatalException, // Terminate the program
"It is not allowed to set up the crystalline undulator geometry "
"the second time for the same logical volume! The program will terminate.");
}
//save the number of current element in fVecCUx, fVecCUtetax, fVecCUCurv
//to call them later using crystalID
fMapCUID[crystalID] = (G4int)fVecCUx.size()-1;
SetCUParameters(G4ThreeVector(1.,1.,0.),crystallogic);// input G4ThreeVector(1.,1.,0.)
// is needed just to setup
// the undulator in a normal way =>
// first 2 arguments > 0.
// values do not matter
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VChannelingFastSimCrystalData::SetCUParameters(
const G4ThreeVector &amplitudePeriodPhase,
const G4LogicalVolume *crystallogic)
@@ -178,6 +300,11 @@ void G4VChannelingFastSimCrystalData::SetCUParameters(
G4double period = amplitudePeriodPhase.y();
fCUPhase = amplitudePeriodPhase.z();
// flag of custom crystal geometry uploaded from a file
fImportCrystalGeometry = (fMapImportCrystalGeometry.count(crystalID) > 0) ?
fMapImportCrystalGeometry[crystalID] :
false;
//if the amplidude of the crystalline undulator is 0 => no undulator
if(fCUAmplitude>DBL_EPSILON&&period>DBL_EPSILON)
{
@@ -195,6 +322,13 @@ void G4VChannelingFastSimCrystalData::SetCUParameters(
G4cout << "Warning: crystalline undulator is not compatible with "
"a bent crystal mode => setting bending angle to 0." << G4endl;
}
//setup crystal internal geometry data to access the correct elements of
//fVecCUx, fVecCUtetax, fVecCUCurv
if(fImportCrystalGeometry)
{
fCUID = fMapCUID[crystalID];
}
}
else
{
@@ -463,7 +597,7 @@ G4ThreeVector G4VChannelingFastSimCrystalData::CoulombElectronScattering(
// eMinIonization - minimal energy transfered to electron
// a cut to reduce the number of calls of electron scattering
// is needed only at low density regions, in many cases does not do anything at all
if (eMinIonization<0.5*eV){eMinIonization=0.5*eV;}
if (eMinIonization<0.5*CLHEP::eV){eMinIonization=0.5*CLHEP::eV;}
// single scattering on electrons routine
if ((eMinIonization<fTmax)&&(electronDensity>DBL_EPSILON))
@@ -523,19 +657,19 @@ G4double G4VChannelingFastSimCrystalData::IonizationLosses(G4double dz,
// 1/2 already taken into account in fKD
G4double loge = G4Log(fMe2Gamma*fGamma*fV2/fI0[ielement]);
G4double delta= 2*(G4Log(fBeta*fGamma)+fLogPlasmaEdI0[ielement]-0.5);
if(delta<0){delta=0;}
G4double delta= 2.*(G4Log(fBeta*fGamma)+fLogPlasmaEdI0[ielement]-0.5);
if(delta<0.){delta=0.;}
loge-=delta;
if(fParticleName=="e-")
{
loge+=(-G4Log(2.) + 1
-(2*fGamma - 1)/fGamma/fGamma*G4Log(2.) +
1./8.*((fGamma - 1)/fGamma)*((fGamma - 1)/fGamma));
loge+=(-G4Log(2.) + 1.
-(2.*fGamma - 1.)/fGamma/fGamma*G4Log(2.) +
1./8.*((fGamma - 1.)/fGamma)*((fGamma - 1.)/fGamma));
}
else if(fParticleName=="e+")
{
loge+=(-fV2/12*(11 + 14/(fGamma + 1) + 10/(fGamma + 1)/(fGamma + 1) +
4/(fGamma + 1)/(fGamma + 1)/(fGamma + 1)));
loge+=(-fV2/12.*(11. + 14./(fGamma + 1.) + 10./(fGamma + 1.)/(fGamma + 1.) +
4./(fGamma + 1.)/(fGamma + 1.)/(fGamma + 1.)));
}
else
{