Import Geant4 11.0.0.beta source tree
This commit is contained in:
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Cerenkov Radiation Class Implementation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -56,22 +54,26 @@
|
||||
// > add protection against /0
|
||||
// > G4MaterialPropertiesTable; new physics/tracking scheme
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
#include "G4OpticalParameters.hh"
|
||||
#include "G4Cerenkov.hh"
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4MaterialPropertiesTable.hh"
|
||||
#include "G4OpticalParameters.hh"
|
||||
#include "G4OpticalPhoton.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4ParticleMomentum.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4PhysicsFreeVector.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4Cerenkov::G4Cerenkov(const G4String& processName, G4ProcessType type)
|
||||
: G4VProcess(processName, type)
|
||||
@@ -98,6 +100,21 @@ G4Cerenkov::~G4Cerenkov()
|
||||
}
|
||||
}
|
||||
|
||||
void G4Cerenkov::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "The Cerenkov effect simulates optical photons created by the\n";
|
||||
out << "passage of charged particles through matter. Materials need\n";
|
||||
out << "to have the property RINDEX (refractive index) defined.\n";
|
||||
G4VProcess::DumpInfo();
|
||||
|
||||
G4OpticalParameters* params = G4OpticalParameters::Instance();
|
||||
out << "Maximum beta change per step: " << params->GetCerenkovMaxBetaChange();
|
||||
out << "Maximum photons per step: " << params->GetCerenkovMaxPhotonsPerStep();
|
||||
out << "Track secondaries first: " << params->GetCerenkovTrackSecondariesFirst();
|
||||
out << "Stack photons: " << params->GetCerenkovStackPhotons();
|
||||
out << "Verbose level: " << params->GetCerenkovVerboseLevel();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4bool G4Cerenkov::IsApplicable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
@@ -134,33 +151,30 @@ void G4Cerenkov::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// loop over materials
|
||||
for(G4int i = 0; i < numOfMaterials; ++i)
|
||||
{
|
||||
G4PhysicsOrderedFreeVector* aPhysicsOrderedFreeVector = 0;
|
||||
G4PhysicsFreeVector* cerenkovIntegral = nullptr;
|
||||
|
||||
// Retrieve vector of refraction indices for the material
|
||||
// from the material's optical properties table
|
||||
G4Material* aMaterial = (*theMaterialTable)[i];
|
||||
G4MaterialPropertiesTable* aMaterialPropertiesTable =
|
||||
aMaterial->GetMaterialPropertiesTable();
|
||||
G4MaterialPropertiesTable* MPT = aMaterial->GetMaterialPropertiesTable();
|
||||
|
||||
if(aMaterialPropertiesTable)
|
||||
if(MPT)
|
||||
{
|
||||
aPhysicsOrderedFreeVector = new G4PhysicsOrderedFreeVector();
|
||||
G4MaterialPropertyVector* theRefractionIndexVector =
|
||||
aMaterialPropertiesTable->GetProperty(kRINDEX);
|
||||
cerenkovIntegral = new G4PhysicsFreeVector();
|
||||
G4MaterialPropertyVector* refractiveIndex = MPT->GetProperty(kRINDEX);
|
||||
|
||||
if(theRefractionIndexVector)
|
||||
if(refractiveIndex)
|
||||
{
|
||||
// Retrieve the first refraction index in vector
|
||||
// of (photon energy, refraction index) pairs
|
||||
G4double currentRI = (*theRefractionIndexVector)[0];
|
||||
|
||||
G4double currentRI = (*refractiveIndex)[0];
|
||||
if(currentRI > 1.0)
|
||||
{
|
||||
// Create first (photon energy, Cerenkov Integral) pair
|
||||
G4double currentPM = theRefractionIndexVector->Energy(0);
|
||||
G4double currentPM = refractiveIndex->Energy(0);
|
||||
G4double currentCAI = 0.0;
|
||||
|
||||
aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCAI);
|
||||
cerenkovIntegral->InsertValues(currentPM, currentCAI);
|
||||
|
||||
// Set previous values to current ones prior to loop
|
||||
G4double prevPM = currentPM;
|
||||
@@ -169,16 +183,15 @@ void G4Cerenkov::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
|
||||
// loop over all (photon energy, refraction index)
|
||||
// pairs stored for this material
|
||||
for(size_t ii = 1; ii < theRefractionIndexVector->GetVectorLength();
|
||||
++ii)
|
||||
for(size_t ii = 1; ii < refractiveIndex->GetVectorLength(); ++ii)
|
||||
{
|
||||
currentRI = (*theRefractionIndexVector)[ii];
|
||||
currentPM = theRefractionIndexVector->Energy(ii);
|
||||
currentRI = (*refractiveIndex)[ii];
|
||||
currentPM = refractiveIndex->Energy(ii);
|
||||
currentCAI = prevCAI + (currentPM - prevPM) * 0.5 *
|
||||
(1.0 / (prevRI * prevRI) +
|
||||
1.0 / (currentRI * currentRI));
|
||||
|
||||
aPhysicsOrderedFreeVector->InsertValues(currentPM, currentCAI);
|
||||
cerenkovIntegral->InsertValues(currentPM, currentCAI);
|
||||
|
||||
prevPM = currentPM;
|
||||
prevCAI = currentCAI;
|
||||
@@ -191,7 +204,7 @@ void G4Cerenkov::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// The Cerenkov integral for a given material will be inserted in
|
||||
// thePhysicsTable according to the position of the material in
|
||||
// the material table.
|
||||
thePhysicsTable->insertAt(i, aPhysicsOrderedFreeVector);
|
||||
thePhysicsTable->insertAt(i, cerenkovIntegral);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,10 +219,6 @@ G4VParticleChange* G4Cerenkov::PostStepDoIt(const G4Track& aTrack,
|
||||
// they are added to the particle change.
|
||||
|
||||
{
|
||||
////////////////////////////////////////////////////
|
||||
// Should we ensure that the material is dispersive?
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
|
||||
@@ -233,8 +242,6 @@ G4VParticleChange* G4Cerenkov::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double charge = aParticle->GetDefinition()->GetPDGCharge();
|
||||
G4double beta = (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta()) * 0.5;
|
||||
|
||||
// fNumPhotons = 0; // in PostStepGetPhysicalInteractionLength()
|
||||
|
||||
G4double MeanNumberOfPhotons =
|
||||
GetAverageNumberOfPhotons(charge, beta, aMaterial, Rindex);
|
||||
|
||||
@@ -447,9 +454,8 @@ G4double G4Cerenkov::PostStepGetPhysicalInteractionLength(
|
||||
particleType, kineticEnergy, couple);
|
||||
G4double Step = Range - RangeMin;
|
||||
|
||||
// If the step is smaller than 1e-16 mm, it may happen that the particle
|
||||
// If the step is smaller than 1e-15 mm, it may happen that the particle
|
||||
// does not move. See bug 1992.
|
||||
// 2019-03-11: change to 1e-15
|
||||
if(Step < 1.e-15 * mm)
|
||||
return StepLimit;
|
||||
|
||||
@@ -493,22 +499,21 @@ G4double G4Cerenkov::GetAverageNumberOfPhotons(
|
||||
const G4double charge, const G4double beta, const G4Material* aMaterial,
|
||||
G4MaterialPropertyVector* Rindex) const
|
||||
// This routine computes the number of Cerenkov photons produced per
|
||||
// GEANT4-unit (millimeter) in the current medium.
|
||||
// ^^^^^^^^^^
|
||||
// Geant4-unit (millimeter) in the current medium.
|
||||
{
|
||||
const G4double Rfact = 369.81 / (eV * cm);
|
||||
constexpr G4double Rfact = 369.81 / (eV * cm);
|
||||
if(beta <= 0.0)
|
||||
return 0.0;
|
||||
G4double BetaInverse = 1. / beta;
|
||||
|
||||
// Vectors used in computation of Cerenkov Angle Integral:
|
||||
// - Refraction Indices for the current material
|
||||
// - new G4PhysicsOrderedFreeVector allocated to hold CAI's
|
||||
// - new G4PhysicsFreeVector allocated to hold CAI's
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
|
||||
// Retrieve the Cerenkov Angle Integrals for this material
|
||||
G4PhysicsOrderedFreeVector* CerenkovAngleIntegrals =
|
||||
(G4PhysicsOrderedFreeVector*) ((*thePhysicsTable)(materialIndex));
|
||||
G4PhysicsFreeVector* CerenkovAngleIntegrals =
|
||||
(G4PhysicsFreeVector*) ((*thePhysicsTable)(materialIndex));
|
||||
|
||||
if(!(CerenkovAngleIntegrals->IsFilledVectorExist()))
|
||||
return 0.0;
|
||||
@@ -583,10 +588,9 @@ void G4Cerenkov::SetMaxNumPhotonsPerStep(const G4int NumPhotons)
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void G4Cerenkov::DumpPhysicsTable() const
|
||||
{
|
||||
G4PhysicsOrderedFreeVector* v;
|
||||
G4cout << "Dump Physics Table!" << G4endl;
|
||||
for(size_t i = 0; i < thePhysicsTable->entries(); ++i)
|
||||
{
|
||||
v = (G4PhysicsOrderedFreeVector*) (*thePhysicsTable)[i];
|
||||
v->DumpValues();
|
||||
((G4PhysicsFreeVector*) (*thePhysicsTable)[i])->DumpValues();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,99 +23,77 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "G4GammaXTRadiator.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4GammaXTRadiator::G4GammaXTRadiator(G4LogicalVolume* anEnvelope,
|
||||
G4double alphaPlate,
|
||||
G4double alphaGas,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4GammaXTRadiator::G4GammaXTRadiator(G4LogicalVolume* anEnvelope,
|
||||
G4double alphaPlate, G4double alphaGas,
|
||||
G4Material* foilMat, G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
|
||||
const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
|
||||
{
|
||||
G4cout<<"Gamma distributed X-ray TR radiator model is called"<<G4endl ;
|
||||
G4cout << "Gamma distributed X-ray TR radiator model is called" << G4endl;
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
|
||||
fAlphaPlate = alphaPlate ;
|
||||
fAlphaGas = alphaGas ;
|
||||
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
|
||||
|
||||
// BuildTable() ;
|
||||
fAlphaPlate = alphaPlate;
|
||||
fAlphaGas = alphaGas;
|
||||
G4cout << "fAlphaPlate = " << fAlphaPlate << " ; fAlphaGas = " << fAlphaGas
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4GammaXTRadiator::~G4GammaXTRadiator() {}
|
||||
|
||||
G4GammaXTRadiator::~G4GammaXTRadiator()
|
||||
void G4GammaXTRadiator::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
;
|
||||
out
|
||||
<< "Rough approximation describing a radiator of X-ray transition "
|
||||
"radiation.\n"
|
||||
"Thicknesses of plates and gas gaps are distributed according to gamma\n"
|
||||
"description.\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Rough approximation for radiator interference factor for the case of
|
||||
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
|
||||
// according to exponent. The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in coresponding material.
|
||||
|
||||
G4double
|
||||
G4GammaXTRadiator::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
|
||||
// according to exponent. The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in corresponding material.
|
||||
G4double G4GammaXTRadiator::GetStackFactor(G4double energy, G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
G4double result, Za, Zb, Ma, Mb ;
|
||||
|
||||
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
|
||||
Zb = GetGasFormationZone(energy,gamma,varAngle) ;
|
||||
G4double result, Za, Zb, Ma, Mb;
|
||||
|
||||
Ma = GetPlateLinearPhotoAbs(energy) ;
|
||||
Mb = GetGasLinearPhotoAbs(energy) ;
|
||||
Za = GetPlateFormationZone(energy, gamma, varAngle);
|
||||
Zb = GetGasFormationZone(energy, gamma, varAngle);
|
||||
|
||||
Ma = GetPlateLinearPhotoAbs(energy);
|
||||
Mb = GetGasLinearPhotoAbs(energy);
|
||||
|
||||
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate) ;
|
||||
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas) ;
|
||||
G4complex Ca(1.0 + 0.5 * fPlateThick * Ma / fAlphaPlate,
|
||||
fPlateThick / Za / fAlphaPlate);
|
||||
G4complex Cb(1.0 + 0.5 * fGasThick * Mb / fAlphaGas,
|
||||
fGasThick / Zb / fAlphaGas);
|
||||
|
||||
G4complex Ha = std::pow(Ca,-fAlphaPlate) ;
|
||||
G4complex Hb = std::pow(Cb,-fAlphaGas) ;
|
||||
G4complex H = Ha*Hb ;
|
||||
G4complex Ha = std::pow(Ca, -fAlphaPlate);
|
||||
G4complex Hb = std::pow(Cb, -fAlphaGas);
|
||||
G4complex H = Ha * Hb;
|
||||
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
|
||||
* G4double(fPlateNumber) ;
|
||||
G4complex F1 = (1.0 - Ha) * (1.0 - Hb) / (1.0 - H) * G4double(fPlateNumber);
|
||||
|
||||
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
|
||||
* (1.0 - std::pow(H,fPlateNumber)) ;
|
||||
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb / (1.0 - H) / (1.0 - H) *
|
||||
(1.0 - std::pow(H, fPlateNumber));
|
||||
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle) ;
|
||||
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
|
||||
result = 2.0*std::real(R) ;
|
||||
|
||||
return result ;
|
||||
result = 2.0 * std::real(R);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,235 +23,142 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "G4RegularXTRadiator.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4RegularXTRadiator::G4RegularXTRadiator(G4LogicalVolume *anEnvelope,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
|
||||
G4RegularXTRadiator::G4RegularXTRadiator(G4LogicalVolume* anEnvelope,
|
||||
G4Material* foilMat,
|
||||
G4Material* gasMat, G4double a,
|
||||
G4double b, G4int n,
|
||||
const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
|
||||
{
|
||||
G4cout<<"Regular X-ray TR radiator EM process is called"<<G4endl ;
|
||||
G4cout << "Regular X-ray TR radiator EM process is called" << G4endl;
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
|
||||
fAlphaPlate = 10000;
|
||||
fAlphaGas = 1000;
|
||||
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
|
||||
|
||||
// BuildTable() ;
|
||||
G4cout << "fAlphaPlate = " << fAlphaPlate << " ; fAlphaGas = " << fAlphaGas
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4RegularXTRadiator::~G4RegularXTRadiator() {}
|
||||
|
||||
G4RegularXTRadiator::~G4RegularXTRadiator()
|
||||
void G4RegularXTRadiator::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
;
|
||||
out << "Simulation of X-ray transition radiation generated by\n"
|
||||
"relativistic charged particles crossing the interface between\n"
|
||||
"two materials. Thicknesses of plates and gaps are fixed.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4RegularXTRadiator::SpectralXTRdEdx(G4double energy)
|
||||
{
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
|
||||
G4double aMa, bMb ,sigma, dump;
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
|
||||
G4double aMa, bMb, sigma, dump;
|
||||
G4int k, kMax, kMin;
|
||||
|
||||
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
|
||||
sigma = 0.5*(aMa + bMb);
|
||||
dump = std::exp(-fPlateNumber*sigma);
|
||||
if(verboseLevel > 2) G4cout<<" dump = "<<dump<<G4endl;
|
||||
cofPHC = 4*pi*hbarc;
|
||||
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
|
||||
cof1 = fPlateThick*tmp;
|
||||
cof2 = fGasThick*tmp;
|
||||
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
|
||||
sigma = 0.5 * (aMa + bMb);
|
||||
dump = std::exp(-fPlateNumber * sigma);
|
||||
if(verboseLevel > 2)
|
||||
G4cout << " dump = " << dump << G4endl;
|
||||
cofPHC = 4 * pi * hbarc;
|
||||
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
|
||||
cof1 = fPlateThick * tmp;
|
||||
cof2 = fGasThick * tmp;
|
||||
|
||||
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
|
||||
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
|
||||
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
|
||||
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
|
||||
cofMin /= cofPHC;
|
||||
|
||||
theta2 = cofPHC/(energy*(fPlateThick + fGasThick));
|
||||
|
||||
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
|
||||
// else kMin = 1;
|
||||
|
||||
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
|
||||
|
||||
kMin = G4int(cofMin);
|
||||
if (cofMin > kMin) kMin++;
|
||||
if(cofMin > kMin)
|
||||
kMin++;
|
||||
|
||||
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
|
||||
// tmp /= cofPHC;
|
||||
// kMax = G4int(tmp);
|
||||
// if(kMax < 0) kMax = 0;
|
||||
// kMax += kMin;
|
||||
|
||||
|
||||
kMax = kMin + 49; // 19; // kMin + G4int(tmp);
|
||||
|
||||
// tmp /= fGamma;
|
||||
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
|
||||
kMax = kMin + 49;
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout<<cof1<<" "<<cof2<<" "<<cofMin<<G4endl;
|
||||
G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
|
||||
}
|
||||
for( k = kMin; k <= kMax; k++ )
|
||||
{
|
||||
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
|
||||
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
|
||||
// tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
if( k == kMin && kMin == G4int(cofMin) )
|
||||
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
|
||||
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
|
||||
}
|
||||
for(k = kMin; k <= kMax; ++k)
|
||||
{
|
||||
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
|
||||
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
|
||||
if(k == kMin && kMin == G4int(cofMin))
|
||||
{
|
||||
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum +=
|
||||
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
theta2k = std::sqrt(theta2*std::abs(k-cofMin));
|
||||
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
// G4cout<<"k = "<<k<<"; sqrt(theta2k) = "<<theta2k<<"; tmp = "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
|
||||
// <<"; sum = "<<sum<<G4endl;
|
||||
G4cout<<k<<" "<<theta2k<<" "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
|
||||
<<" "<<sum<<G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << k << " " << theta2k << " "
|
||||
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
|
||||
<< " " << sum << G4endl;
|
||||
}
|
||||
}
|
||||
result = 2*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
|
||||
// result *= ( 1 - std::exp(-0.5*fPlateNumber*sigma) )/( 1 - std::exp(-0.5*sigma) );
|
||||
// fPlateNumber;
|
||||
result *= ( 1 - dump + 2*dump*fPlateNumber );
|
||||
/*
|
||||
fEnergy = energy;
|
||||
// G4Integrator<G4VXTRenergyLoss,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
|
||||
G4Integrator<G4TransparentRegXTRadiator,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
|
||||
|
||||
tmp = integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.0,0.3*fMaxThetaTR) +
|
||||
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.3*fMaxThetaTR,0.6*fMaxThetaTR) +
|
||||
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.6*fMaxThetaTR,fMaxThetaTR) ;
|
||||
result += tmp;
|
||||
*/
|
||||
result = 2 * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
|
||||
result *= (1 - dump + 2 * dump * fPlateNumber);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Approximation for radiator interference factor for the case of
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in coresponding material.
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in corresponding material.
|
||||
|
||||
G4double
|
||||
G4RegularXTRadiator::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
G4double G4RegularXTRadiator::GetStackFactor(G4double energy, G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
|
||||
// some gamma (10000/1000) like algorithm
|
||||
|
||||
G4double result, Za, Zb, Ma, Mb;
|
||||
|
||||
Za = GetPlateFormationZone(energy,gamma,varAngle);
|
||||
Zb = GetGasFormationZone(energy,gamma,varAngle);
|
||||
|
||||
Za = GetPlateFormationZone(energy, gamma, varAngle);
|
||||
Zb = GetGasFormationZone(energy, gamma, varAngle);
|
||||
|
||||
Ma = GetPlateLinearPhotoAbs(energy);
|
||||
Mb = GetGasLinearPhotoAbs(energy);
|
||||
|
||||
G4complex Ca(1.0 + 0.5 * fPlateThick * Ma / fAlphaPlate,
|
||||
fPlateThick / Za / fAlphaPlate);
|
||||
G4complex Cb(1.0 + 0.5 * fGasThick * Mb / fAlphaGas,
|
||||
fGasThick / Zb / fAlphaGas);
|
||||
|
||||
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate);
|
||||
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas);
|
||||
G4complex Ha = std::pow(Ca, -fAlphaPlate);
|
||||
G4complex Hb = std::pow(Cb, -fAlphaGas);
|
||||
G4complex H = Ha * Hb;
|
||||
|
||||
G4complex Ha = std::pow(Ca,-fAlphaPlate);
|
||||
G4complex Hb = std::pow(Cb,-fAlphaGas);
|
||||
G4complex H = Ha*Hb;
|
||||
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
|
||||
* G4double(fPlateNumber);
|
||||
G4complex F1 = (1.0 - Ha) * (1.0 - Hb) / (1.0 - H) * G4double(fPlateNumber);
|
||||
|
||||
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
|
||||
* (1.0 - std::pow(H,fPlateNumber));
|
||||
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb / (1.0 - H) / (1.0 - H) *
|
||||
(1.0 - std::pow(H, fPlateNumber));
|
||||
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
|
||||
result = 2.0*std::real(R);
|
||||
|
||||
return result;
|
||||
|
||||
/*
|
||||
// numerically stable but slow algorithm
|
||||
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
|
||||
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb; // , D;
|
||||
|
||||
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle);
|
||||
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle);
|
||||
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
|
||||
Qa = std::exp(-aMa);
|
||||
Qb = std::exp(-bMb);
|
||||
Q = Qa*Qb;
|
||||
G4complex Ha( std::exp(-0.5*aMa)*std::cos(aZa),
|
||||
-std::exp(-0.5*aMa)*std::sin(aZa) );
|
||||
G4complex Hb( std::exp(-0.5*bMb)*std::cos(bZb),
|
||||
-std::exp(-0.5*bMb)*std::sin(bZb) );
|
||||
G4complex H = Ha*Hb;
|
||||
|
||||
G4complex Hs = conj(H);
|
||||
D = 1.0 /( (1 - std::sqrt(Q))*(1 - std::sqrt(Q)) +
|
||||
4*std::sqrt(Q)*std::sin(0.5*(aZa+bZb))*std::sin(0.5*(aZa+bZb)) );
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb)*(1.0 - Hs)
|
||||
* G4double(fPlateNumber)*D;
|
||||
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb*(1.0-Hs)*(1.0-Hs)
|
||||
* (1.0 - std::pow(H,fPlateNumber)) * D*D;
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
|
||||
result = 2.0 * std::real(R);
|
||||
|
||||
G4complex S(0.,0.), c(1.,0.);
|
||||
G4int k;
|
||||
for(k = 1; k < fPlateNumber; k++)
|
||||
{
|
||||
c *= H;
|
||||
S += ( G4double(fPlateNumber) - G4double(k) )*c;
|
||||
}
|
||||
G4complex R = (2.- Ha - 1./Ha)*S + (1. - Ha)*G4double(fPlateNumber);
|
||||
R *= OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
result = 2.0*std::real(R);
|
||||
return result;
|
||||
*/
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Scintillation Light Class Implementation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -62,20 +60,29 @@
|
||||
// 2001-09-17, migration of Materials to pure STL (mma)
|
||||
// 2003-06-03, V.Ivanchenko fix compilation warnings
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "globals.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ParticleTypes.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
|
||||
#include "G4OpticalParameters.hh"
|
||||
#include "G4ScintillationTrackInformation.hh"
|
||||
#include "G4Scintillation.hh"
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialPropertiesTable.hh"
|
||||
#include "G4MaterialPropertyVector.hh"
|
||||
#include "G4OpticalParameters.hh"
|
||||
#include "G4ParticleMomentum.hh"
|
||||
#include "G4ParticleTypes.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4PhysicsFreeVector.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4ScintillationTrackInformation.hh"
|
||||
#include "G4StepPoint.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4Scintillation::G4Scintillation(const G4String& processName,
|
||||
G4ProcessType type)
|
||||
@@ -83,8 +90,8 @@ G4Scintillation::G4Scintillation(const G4String& processName,
|
||||
, fIntegralTable1(nullptr)
|
||||
, fIntegralTable2(nullptr)
|
||||
, fIntegralTable3(nullptr)
|
||||
, fNumPhotons(0)
|
||||
, fEmSaturation(nullptr)
|
||||
, fNumPhotons(0)
|
||||
{
|
||||
SetProcessSubType(fScintillation);
|
||||
|
||||
@@ -120,6 +127,23 @@ G4Scintillation::~G4Scintillation()
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void G4Scintillation::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Scintillation simulates production of optical photons produced\n"
|
||||
"by a high energy particle traversing matter.\n"
|
||||
"Various material properties need to be defined.\n";
|
||||
G4VRestDiscreteProcess::DumpInfo();
|
||||
|
||||
G4OpticalParameters* params = G4OpticalParameters::Instance();
|
||||
out << "Track secondaries first: " << params->GetScintTrackSecondariesFirst();
|
||||
out << "Finite rise time: " << params->GetScintFiniteRiseTime();
|
||||
out << "Scintillation by particle type: " << params->GetScintByParticleType();
|
||||
out << "Save track information: " << params->GetScintTrackInfo();
|
||||
out << "Stack photons: " << params->GetScintStackPhotons();
|
||||
out << "Verbose level: " << params->GetScintVerboseLevel();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4bool G4Scintillation::IsApplicable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
@@ -142,10 +166,7 @@ void G4Scintillation::Initialise()
|
||||
G4OpticalParameters* params = G4OpticalParameters::Instance();
|
||||
SetTrackSecondariesFirst(params->GetScintTrackSecondariesFirst());
|
||||
SetFiniteRiseTime(params->GetScintFiniteRiseTime());
|
||||
SetScintillationYieldFactor(params->GetScintYieldFactor());
|
||||
SetScintillationExcitationRatio(params->GetScintExcitationRatio());
|
||||
SetScintillationByParticleType(params->GetScintByParticleType());
|
||||
SetEnhancedTimeConstants(params->GetScintEnhancedTimeConstants());
|
||||
SetScintillationTrackInfo(params->GetScintTrackInfo());
|
||||
SetStackPhotons(params->GetScintStackPhotons());
|
||||
SetVerboseLevel(params->GetScintVerboseLevel());
|
||||
@@ -186,9 +207,9 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
|
||||
for(size_t i = 0; i < numOfMaterials; ++i)
|
||||
{
|
||||
G4PhysicsOrderedFreeVector* vector1 = new G4PhysicsOrderedFreeVector();
|
||||
G4PhysicsOrderedFreeVector* vector2 = new G4PhysicsOrderedFreeVector();
|
||||
G4PhysicsOrderedFreeVector* vector3 = new G4PhysicsOrderedFreeVector();
|
||||
G4PhysicsFreeVector* vector1 = new G4PhysicsFreeVector();
|
||||
G4PhysicsFreeVector* vector2 = new G4PhysicsFreeVector();
|
||||
G4PhysicsFreeVector* vector3 = new G4PhysicsFreeVector();
|
||||
|
||||
// Retrieve vector of scintillation wavelength intensity for
|
||||
// the material from the material's optical properties table.
|
||||
@@ -197,10 +218,7 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
|
||||
if(MPT)
|
||||
{
|
||||
// integral table 1 is either FASTCOMPONENT or SCINTILLATIONCOMPONENT1
|
||||
G4MaterialPropertyVector* MPV = MPT->GetProperty(kFASTCOMPONENT);
|
||||
if(!MPV)
|
||||
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT1);
|
||||
G4MaterialPropertyVector* MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT1);
|
||||
if(MPV)
|
||||
{
|
||||
// Retrieve the first intensity point in vector
|
||||
@@ -236,7 +254,6 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
}
|
||||
}
|
||||
|
||||
// integral table 2 is SCINTILLATIONCOMPONENT2
|
||||
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT2);
|
||||
if(MPV)
|
||||
{
|
||||
@@ -272,10 +289,7 @@ void G4Scintillation::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
}
|
||||
}
|
||||
}
|
||||
// integral table 3 is either SLOWCOMPONENT or SCINTILLATIONCOMPONENT3
|
||||
MPV = MPT->GetProperty(kSLOWCOMPONENT);
|
||||
if(!MPV)
|
||||
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT3);
|
||||
MPV = MPT->GetProperty(kSCINTILLATIONCOMPONENT3);
|
||||
if(MPV)
|
||||
{
|
||||
// Retrieve the first intensity point in vector
|
||||
@@ -355,30 +369,14 @@ G4VParticleChange* G4Scintillation::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
G4int N_timeconstants = 1;
|
||||
|
||||
// only needed for old (two time constants) version
|
||||
G4MaterialPropertyVector* Fast_Intensity = nullptr;
|
||||
G4MaterialPropertyVector* Slow_Intensity = nullptr;
|
||||
|
||||
if(fEnhancedTimeConstants)
|
||||
if(MPT->GetProperty(kSCINTILLATIONCOMPONENT3))
|
||||
N_timeconstants = 3;
|
||||
else if(MPT->GetProperty(kSCINTILLATIONCOMPONENT2))
|
||||
N_timeconstants = 2;
|
||||
else if(!(MPT->GetProperty(kSCINTILLATIONCOMPONENT1)))
|
||||
{
|
||||
if(MPT->GetProperty(kSCINTILLATIONCOMPONENT3))
|
||||
N_timeconstants = 3;
|
||||
else if(MPT->GetProperty(kSCINTILLATIONCOMPONENT2))
|
||||
N_timeconstants = 2;
|
||||
else if(!(MPT->GetProperty(kSCINTILLATIONCOMPONENT1)))
|
||||
{
|
||||
// no components were specified
|
||||
return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // OLD METHOD
|
||||
Fast_Intensity = MPT->GetProperty(kFASTCOMPONENT);
|
||||
Slow_Intensity = MPT->GetProperty(kSLOWCOMPONENT);
|
||||
if(!Fast_Intensity && !Slow_Intensity)
|
||||
return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
if(Fast_Intensity && Slow_Intensity)
|
||||
N_timeconstants = 2;
|
||||
// no components were specified
|
||||
return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
}
|
||||
|
||||
G4double ResolutionScale = MPT->GetConstProperty(kRESOLUTIONSCALE);
|
||||
@@ -389,61 +387,37 @@ G4VParticleChange* G4Scintillation::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double yield3 = 0.;
|
||||
G4double sum_yields = 0.;
|
||||
|
||||
if(!fEnhancedTimeConstants)
|
||||
{
|
||||
// Scintillation depends on particle type, energy deposited
|
||||
if(fScintillationByParticleType)
|
||||
{
|
||||
MeanNumberOfPhotons = GetScintillationYieldByParticleType(aTrack, aStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The default linear scintillation process
|
||||
// Units: [# scintillation photons / MeV]
|
||||
MeanNumberOfPhotons =
|
||||
MPT->GetConstProperty(kSCINTILLATIONYIELD) * fYieldFactor;
|
||||
// Birk's correction via fEmSaturation and specifying scintillation by
|
||||
// by particle type are physically mutually exclusive
|
||||
if(fEmSaturation)
|
||||
MeanNumberOfPhotons *=
|
||||
(fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
|
||||
else
|
||||
MeanNumberOfPhotons *= TotalEnergyDeposit;
|
||||
}
|
||||
}
|
||||
|
||||
if(fScintillationByParticleType)
|
||||
{
|
||||
MeanNumberOfPhotons = GetScintillationYieldByParticleType(
|
||||
aTrack, aStep, yield1, yield2, yield3);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fScintillationByParticleType)
|
||||
{
|
||||
MeanNumberOfPhotons = GetScintillationYieldByParticleType(
|
||||
aTrack, aStep, yield1, yield2, yield3);
|
||||
}
|
||||
yield1 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD1)
|
||||
? MPT->GetConstProperty(kSCINTILLATIONYIELD1)
|
||||
: 1.;
|
||||
yield2 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD2)
|
||||
? MPT->GetConstProperty(kSCINTILLATIONYIELD2)
|
||||
: 0.;
|
||||
yield3 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD3)
|
||||
? MPT->GetConstProperty(kSCINTILLATIONYIELD3)
|
||||
: 0.;
|
||||
// The default linear scintillation process
|
||||
// Units: [# scintillation photons / MeV]
|
||||
MeanNumberOfPhotons =
|
||||
MPT->GetConstProperty(kSCINTILLATIONYIELD);
|
||||
// Birk's correction via fEmSaturation and specifying scintillation by
|
||||
// by particle type are physically mutually exclusive
|
||||
if(fEmSaturation)
|
||||
MeanNumberOfPhotons *=
|
||||
(fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
|
||||
else
|
||||
{
|
||||
yield1 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD1)
|
||||
? MPT->GetConstProperty(kSCINTILLATIONYIELD1)
|
||||
: 1.;
|
||||
yield2 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD2)
|
||||
? MPT->GetConstProperty(kSCINTILLATIONYIELD2)
|
||||
: 0.;
|
||||
yield3 = MPT->ConstPropertyExists(kSCINTILLATIONYIELD3)
|
||||
? MPT->GetConstProperty(kSCINTILLATIONYIELD3)
|
||||
: 0.;
|
||||
// The default linear scintillation process
|
||||
// Units: [# scintillation photons / MeV]
|
||||
MeanNumberOfPhotons =
|
||||
MPT->GetConstProperty(kSCINTILLATIONYIELD) * fYieldFactor;
|
||||
// Birk's correction via fEmSaturation and specifying scintillation by
|
||||
// by particle type are physically mutually exclusive
|
||||
if(fEmSaturation)
|
||||
MeanNumberOfPhotons *=
|
||||
(fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
|
||||
else
|
||||
MeanNumberOfPhotons *= TotalEnergyDeposit;
|
||||
}
|
||||
sum_yields = yield1 + yield2 + yield3;
|
||||
MeanNumberOfPhotons *= TotalEnergyDeposit;
|
||||
}
|
||||
sum_yields = yield1 + yield2 + yield3;
|
||||
|
||||
|
||||
if(MeanNumberOfPhotons > 10.)
|
||||
{
|
||||
@@ -473,134 +447,66 @@ G4VParticleChange* G4Scintillation::PostStepDoIt(const G4Track& aTrack,
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
|
||||
// Retrieve the Scintillation Integral for this material
|
||||
// new G4PhysicsOrderedFreeVector allocated to hold CII's
|
||||
size_t numPhot = fNumPhotons;
|
||||
G4double scintTime = 0.;
|
||||
G4double riseTime = 0.;
|
||||
G4PhysicsOrderedFreeVector* scintIntegral = nullptr;
|
||||
G4ScintillationType scintType = Slow;
|
||||
// new G4PhysicsFreeVector allocated to hold CII's
|
||||
size_t numPhot = fNumPhotons;
|
||||
G4double scintTime = 0.;
|
||||
G4double riseTime = 0.;
|
||||
G4PhysicsFreeVector* scintIntegral = nullptr;
|
||||
G4ScintillationType scintType = Slow;
|
||||
|
||||
for(G4int scnt = 0; scnt < N_timeconstants; ++scnt)
|
||||
{
|
||||
// Original method with FAST and SLOW
|
||||
if(!fEnhancedTimeConstants)
|
||||
// if there is 1 time constant it is #1, etc.
|
||||
if(scnt == 0)
|
||||
{
|
||||
if(scnt == 0)
|
||||
if(N_timeconstants == 1)
|
||||
{
|
||||
if(N_timeconstants == 1)
|
||||
{
|
||||
if(Fast_Intensity)
|
||||
{
|
||||
scintTime = MPT->GetConstProperty(kFASTTIMECONSTANT);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kFASTSCINTILLATIONRISETIME);
|
||||
}
|
||||
scintType = Fast;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable1)(materialIndex));
|
||||
}
|
||||
if(Slow_Intensity)
|
||||
{
|
||||
scintTime = MPT->GetConstProperty(kSLOWTIMECONSTANT);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSLOWSCINTILLATIONRISETIME);
|
||||
}
|
||||
scintType = Slow;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable3)(materialIndex));
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /// N_timeconstants != 1 and still scnt == 0
|
||||
G4double yieldRatio = MPT->GetConstProperty(kYIELDRATIO);
|
||||
if(fExcitationRatio == 1.0 || fExcitationRatio == 0.0)
|
||||
{
|
||||
numPhot = G4int(std::min(yieldRatio, 1.0) * fNumPhotons);
|
||||
}
|
||||
else
|
||||
{
|
||||
numPhot = G4int(std::min(fExcitationRatio, 1.0) * fNumPhotons);
|
||||
}
|
||||
scintTime = MPT->GetConstProperty(kFASTTIMECONSTANT);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kFASTSCINTILLATIONRISETIME);
|
||||
}
|
||||
scintType = Fast;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable1)(materialIndex));
|
||||
}
|
||||
numPhot = fNumPhotons;
|
||||
}
|
||||
else
|
||||
{ // scnt != 0
|
||||
numPhot = fNumPhotons - numPhot;
|
||||
scintTime = MPT->GetConstProperty(kSLOWTIMECONSTANT);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSLOWSCINTILLATIONRISETIME);
|
||||
}
|
||||
scintType = Slow;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable3)(materialIndex));
|
||||
{
|
||||
numPhot = yield1 / sum_yields * fNumPhotons;
|
||||
}
|
||||
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT1);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME1);
|
||||
}
|
||||
scintType = Fast;
|
||||
scintIntegral =
|
||||
(G4PhysicsFreeVector*) ((*fIntegralTable1)(materialIndex));
|
||||
}
|
||||
else
|
||||
{ // fEnhancedTimeConstants == true
|
||||
// in the new method, if there is 1 time constant it is #1, etc.
|
||||
// Note: fExcitationRatio is not used
|
||||
if(scnt == 0)
|
||||
else if(scnt == 1)
|
||||
{
|
||||
// to be consistent with old version (due to double->int conversion)
|
||||
if(N_timeconstants == 2)
|
||||
{
|
||||
if(N_timeconstants == 1)
|
||||
{
|
||||
numPhot = fNumPhotons;
|
||||
}
|
||||
else
|
||||
{
|
||||
numPhot = yield1 / sum_yields * fNumPhotons;
|
||||
}
|
||||
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT1);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME1);
|
||||
}
|
||||
scintType = Fast;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable1)(materialIndex));
|
||||
numPhot = fNumPhotons - numPhot;
|
||||
}
|
||||
else if(scnt == 1)
|
||||
else
|
||||
{
|
||||
// to be consistent with old version (due to double->int conversion)
|
||||
if(N_timeconstants == 2)
|
||||
{
|
||||
numPhot = fNumPhotons - numPhot;
|
||||
}
|
||||
else
|
||||
{
|
||||
numPhot = yield2 / sum_yields * fNumPhotons;
|
||||
}
|
||||
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT2);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME2);
|
||||
}
|
||||
scintType = Medium;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable2)(materialIndex));
|
||||
numPhot = yield2 / sum_yields * fNumPhotons;
|
||||
}
|
||||
else if(scnt == 2)
|
||||
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT2);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
numPhot = yield3 / sum_yields * fNumPhotons;
|
||||
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT3);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME3);
|
||||
}
|
||||
scintType = Slow;
|
||||
scintIntegral =
|
||||
(G4PhysicsOrderedFreeVector*) ((*fIntegralTable3)(materialIndex));
|
||||
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME2);
|
||||
}
|
||||
scintType = Medium;
|
||||
scintIntegral =
|
||||
(G4PhysicsFreeVector*) ((*fIntegralTable2)(materialIndex));
|
||||
}
|
||||
else if(scnt == 2)
|
||||
{
|
||||
numPhot = yield3 / sum_yields * fNumPhotons;
|
||||
scintTime = MPT->GetConstProperty(kSCINTILLATIONTIMECONSTANT3);
|
||||
if(fFiniteRiseTime)
|
||||
{
|
||||
riseTime = MPT->GetConstProperty(kSCINTILLATIONRISETIME3);
|
||||
}
|
||||
scintType = Slow;
|
||||
scintIntegral =
|
||||
(G4PhysicsFreeVector*) ((*fIntegralTable3)(materialIndex));
|
||||
}
|
||||
|
||||
if(!scintIntegral)
|
||||
@@ -739,137 +645,6 @@ G4double G4Scintillation::sample_time(G4double tau1, G4double tau2)
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4double G4Scintillation::GetScintillationYieldByParticleType(
|
||||
const G4Track& aTrack, const G4Step& aStep)
|
||||
{
|
||||
// Get the G4MaterialPropertyVector containing the scintillation
|
||||
// yield as a function of the energy deposited and particle type
|
||||
|
||||
G4ParticleDefinition* pDef = aTrack.GetDynamicParticle()->GetDefinition();
|
||||
G4MaterialPropertyVector* scintVector = nullptr;
|
||||
G4MaterialPropertiesTable* MPT =
|
||||
aTrack.GetMaterial()->GetMaterialPropertiesTable();
|
||||
|
||||
// Protons
|
||||
if(pDef == G4Proton::ProtonDefinition())
|
||||
scintVector = MPT->GetProperty(kPROTONSCINTILLATIONYIELD);
|
||||
|
||||
// Deuterons
|
||||
else if(pDef == G4Deuteron::DeuteronDefinition())
|
||||
scintVector = MPT->GetProperty(kDEUTERONSCINTILLATIONYIELD);
|
||||
|
||||
// Tritons
|
||||
else if(pDef == G4Triton::TritonDefinition())
|
||||
scintVector = MPT->GetProperty(kTRITONSCINTILLATIONYIELD);
|
||||
|
||||
// Alphas
|
||||
else if(pDef == G4Alpha::AlphaDefinition())
|
||||
scintVector = MPT->GetProperty(kALPHASCINTILLATIONYIELD);
|
||||
|
||||
// Ions (particles derived from G4VIon and G4Ions) and recoil ions
|
||||
// below the production cut from neutrons after hElastic
|
||||
else if(pDef->GetParticleType() == "nucleus" ||
|
||||
pDef == G4Neutron::NeutronDefinition())
|
||||
scintVector = MPT->GetProperty(kIONSCINTILLATIONYIELD);
|
||||
|
||||
// Electrons (must also
|
||||
else if(pDef == G4Electron::ElectronDefinition() ||
|
||||
pDef == G4Gamma::GammaDefinition())
|
||||
scintVector = MPT->GetProperty(kELECTRONSCINTILLATIONYIELD);
|
||||
|
||||
// Default for particles not enumerated/listed above
|
||||
// includes gamma to account for shell-binding energy
|
||||
// attributed to gamma from standard photoelectric effect)
|
||||
else
|
||||
scintVector = MPT->GetProperty(kELECTRONSCINTILLATIONYIELD);
|
||||
|
||||
// Throw an exception if no scintillation yield vector is found
|
||||
if(!scintVector)
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "\nG4Scintillation::PostStepDoIt(): "
|
||||
<< "Request for scintillation yield for energy deposit and particle\n"
|
||||
<< "type without correct entry in MaterialPropertiesTable.\n"
|
||||
<< "ScintillationByParticleType requires at minimum that \n"
|
||||
<< "ELECTRONSCINTILLATIONYIELD is set by the user\n"
|
||||
<< G4endl;
|
||||
G4String comments = "Missing MaterialPropertiesTable entry - No correct "
|
||||
"entry in MaterialPropertiesTable";
|
||||
G4Exception("G4Scintillation::PostStepDoIt", "Scint01", FatalException, ed,
|
||||
comments);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Calculate the scintillation light //
|
||||
///////////////////////////////////////
|
||||
// To account for potential nonlinearity and scintillation photon
|
||||
// density along the track, light (L) is produced according to:
|
||||
// L_currentStep = L(PreStepKE) - L(PreStepKE - EDep)
|
||||
|
||||
G4double ScintillationYield = 0.;
|
||||
G4double StepEnergyDeposit = aStep.GetTotalEnergyDeposit();
|
||||
G4double PreStepKineticEnergy = aStep.GetPreStepPoint()->GetKineticEnergy();
|
||||
|
||||
if(PreStepKineticEnergy <= scintVector->GetMaxEnergy())
|
||||
{
|
||||
G4double Yield1 = scintVector->Value(PreStepKineticEnergy);
|
||||
G4double Yield2 =
|
||||
scintVector->Value(PreStepKineticEnergy - StepEnergyDeposit);
|
||||
ScintillationYield = Yield1 - Yield2;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "\nG4Scintillation::GetScintillationYieldByParticleType(): Request\n"
|
||||
<< "for scintillation light yield above the available energy range\n"
|
||||
<< "specified in G4MaterialPropertiesTable. A linear interpolation\n"
|
||||
<< "will be performed to compute the scintillation light yield using\n"
|
||||
<< "(L_max / E_max) as the photon yield per unit energy." << G4endl;
|
||||
G4String cmt = "\nScintillation yield may be unphysical!\n";
|
||||
G4Exception("G4Scintillation::GetScintillationYieldByParticleType()",
|
||||
"Scint03", JustWarning, ed, cmt);
|
||||
|
||||
// Units: [# scintillation photons]
|
||||
ScintillationYield = scintVector->GetMaxValue() /
|
||||
scintVector->GetMaxEnergy() * StepEnergyDeposit;
|
||||
}
|
||||
|
||||
#ifdef G4DEBUG_SCINTILLATION
|
||||
// Increment track aggregators
|
||||
ScintTrackYield += ScintillationYield;
|
||||
ScintTrackEDep += StepEnergyDeposit;
|
||||
|
||||
G4cout << "\n--- G4Scintillation::GetScintillationYieldByParticleType() ---\n"
|
||||
<< "--\n"
|
||||
<< "-- Name = "
|
||||
<< aTrack.GetParticleDefinition()->GetParticleName() << "\n"
|
||||
<< "-- TrackID = " << aTrack.GetTrackID() << "\n"
|
||||
<< "-- ParentID = " << aTrack.GetParentID() << "\n"
|
||||
<< "-- Current KE = " << aTrack.GetKineticEnergy() / MeV
|
||||
<< " MeV\n"
|
||||
<< "-- Step EDep = " << aStep.GetTotalEnergyDeposit() / MeV
|
||||
<< " MeV\n"
|
||||
<< "-- Track EDep = " << ScintTrackEDep / MeV << " MeV\n"
|
||||
<< "-- Vertex KE = " << aTrack.GetVertexKineticEnergy() / MeV
|
||||
<< " MeV\n"
|
||||
<< "-- Step yield = " << ScintillationYield << " photons\n"
|
||||
<< "-- Track yield = " << ScintTrackYield << " photons\n"
|
||||
<< G4endl;
|
||||
|
||||
// The track has terminated within or has left the scintillator volume
|
||||
if((aTrack.GetTrackStatus() == fStopButAlive) or
|
||||
(aStep.GetPostStepPoint()->GetStepStatus() == fGeomBoundary))
|
||||
{
|
||||
// Reset aggregators for the next track
|
||||
ScintTrackEDep = 0.;
|
||||
ScintTrackYield = 0.;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ScintillationYield;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
G4double G4Scintillation::GetScintillationYieldByParticleType(
|
||||
const G4Track& aTrack, const G4Step& aStep, G4double& yield1,
|
||||
@@ -1069,29 +844,25 @@ G4double G4Scintillation::GetScintillationYieldByParticleType(
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
void G4Scintillation::DumpPhysicsTable() const
|
||||
{
|
||||
G4PhysicsOrderedFreeVector* v;
|
||||
if(fIntegralTable1)
|
||||
{
|
||||
for(size_t i = 0; i < fIntegralTable1->entries(); ++i)
|
||||
{
|
||||
v = (G4PhysicsOrderedFreeVector*) (*fIntegralTable1)[i];
|
||||
v->DumpValues();
|
||||
((G4PhysicsFreeVector*) (*fIntegralTable1)[i])->DumpValues();
|
||||
}
|
||||
}
|
||||
if(fIntegralTable2)
|
||||
{
|
||||
for(size_t i = 0; i < fIntegralTable2->entries(); ++i)
|
||||
{
|
||||
v = (G4PhysicsOrderedFreeVector*) (*fIntegralTable2)[i];
|
||||
v->DumpValues();
|
||||
((G4PhysicsFreeVector*) (*fIntegralTable2)[i])->DumpValues();
|
||||
}
|
||||
}
|
||||
if(fIntegralTable3)
|
||||
{
|
||||
for(size_t i = 0; i < fIntegralTable3->entries(); ++i)
|
||||
{
|
||||
v = (G4PhysicsOrderedFreeVector*) (*fIntegralTable3)[i];
|
||||
v->DumpValues();
|
||||
((G4PhysicsFreeVector*) (*fIntegralTable3)[i])->DumpValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author : Valentin Libioulle valentin.libioulle@usherbrooke.ca (3IT - GRAMS)
|
||||
//
|
||||
|
||||
|
||||
@@ -23,198 +23,164 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4StrawTubeXTRadiator.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4StrawTubeXTRadiator::G4StrawTubeXTRadiator(G4LogicalVolume *anEnvelope,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4double a, G4double b, G4Material* mediumMat,
|
||||
G4bool unishut,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,1,processName)
|
||||
G4StrawTubeXTRadiator::G4StrawTubeXTRadiator(G4LogicalVolume* anEnvelope,
|
||||
G4Material* foilMat,
|
||||
G4Material* gasMat, G4double a,
|
||||
G4double b, G4Material* mediumMat,
|
||||
G4bool unishut,
|
||||
const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, 1, processName)
|
||||
{
|
||||
if(verboseLevel > 0)
|
||||
G4cout<<"Straw tube X-ray TR radiator EM process is called"<<G4endl;
|
||||
G4cout << "Straw tube X-ray TR radiator EM process is called" << G4endl;
|
||||
|
||||
if( unishut )
|
||||
if(unishut)
|
||||
{
|
||||
fAlphaPlate = 1./3.;
|
||||
fAlphaPlate = 1. / 3.;
|
||||
fAlphaGas = 12.4;
|
||||
if(verboseLevel > 0)
|
||||
G4cout<<"straw uniform shooting: "<<"fAlphaPlate = "
|
||||
<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl;
|
||||
|
||||
G4cout << "straw uniform shooting: "
|
||||
<< "fAlphaPlate = " << fAlphaPlate
|
||||
<< " ; fAlphaGas = " << fAlphaGas << G4endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fAlphaPlate = 0.5;
|
||||
fAlphaGas = 5.;
|
||||
if(verboseLevel > 0)
|
||||
G4cout<<"straw isotropical shooting: "<<"fAlphaPlate = "
|
||||
<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl;
|
||||
|
||||
|
||||
G4cout << "straw isotropical shooting: "
|
||||
<< "fAlphaPlate = " << fAlphaPlate
|
||||
<< " ; fAlphaGas = " << fAlphaGas << G4endl;
|
||||
}
|
||||
// index of medium material
|
||||
|
||||
// index of medium material
|
||||
fMatIndex3 = mediumMat->GetIndex();
|
||||
if(verboseLevel > 0)
|
||||
G4cout<<"medium material = "<<mediumMat->GetName()<<G4endl;
|
||||
G4cout << "medium material = " << mediumMat->GetName() << G4endl;
|
||||
|
||||
// plasma energy squared for plate material
|
||||
|
||||
fSigma3 = fPlasmaCof*mediumMat->GetElectronDensity();
|
||||
fSigma3 = fPlasmaCof * mediumMat->GetElectronDensity();
|
||||
if(verboseLevel > 0)
|
||||
G4cout<<"medium plasma energy = "<<std::sqrt(fSigma3)/eV<<" eV"<<G4endl;
|
||||
G4cout << "medium plasma energy = " << std::sqrt(fSigma3) / eV << " eV"
|
||||
<< G4endl;
|
||||
|
||||
// Compute cofs for preparation of linear photo absorption in external medium
|
||||
|
||||
ComputeMediumPhotoAbsCof();
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
|
||||
// BuildTable();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4StrawTubeXTRadiator::~G4StrawTubeXTRadiator() {}
|
||||
|
||||
G4StrawTubeXTRadiator::~G4StrawTubeXTRadiator()
|
||||
void G4StrawTubeXTRadiator::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Simulation of forward X-ray transition radiation for the case of\n"
|
||||
"a straw tube radiator.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Approximation for radiator interference factor for the case of
|
||||
// straw tube radiator. The plate (window, straw wall) and gas (inside straw)
|
||||
// gap thicknesses are gamma distributed.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// straw tube radiator. The plate (window, straw wall) and gas (inside straw)
|
||||
// gap thicknesses are gamma distributed.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zone.
|
||||
|
||||
G4double
|
||||
G4StrawTubeXTRadiator::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
G4double G4StrawTubeXTRadiator::GetStackFactor(G4double energy, G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
|
||||
|
||||
G4double result, L2, L3, M2, M3;
|
||||
|
||||
L2 = GetPlateFormationZone(energy,gamma,varAngle);
|
||||
L3 = GetGasFormationZone(energy,gamma,varAngle);
|
||||
|
||||
L2 = GetPlateFormationZone(energy, gamma, varAngle);
|
||||
L3 = GetGasFormationZone(energy, gamma, varAngle);
|
||||
|
||||
M2 = GetPlateLinearPhotoAbs(energy);
|
||||
M3 = GetGasLinearPhotoAbs(energy);
|
||||
|
||||
G4complex C2(1.0 + 0.5*fPlateThick*M2/fAlphaPlate, fPlateThick/L2/fAlphaPlate);
|
||||
G4complex C3(1.0 + 0.5*fGasThick*M3/fAlphaGas, fGasThick/L3/fAlphaGas);
|
||||
G4complex C2(1.0 + 0.5 * fPlateThick * M2 / fAlphaPlate,
|
||||
fPlateThick / L2 / fAlphaPlate);
|
||||
G4complex C3(1.0 + 0.5 * fGasThick * M3 / fAlphaGas,
|
||||
fGasThick / L3 / fAlphaGas);
|
||||
|
||||
G4complex H2 = std::pow(C2,-fAlphaPlate);
|
||||
G4complex H3 = std::pow(C3,-fAlphaGas);
|
||||
G4complex H = H2*H3;
|
||||
G4complex H2 = std::pow(C2, -fAlphaPlate);
|
||||
G4complex H3 = std::pow(C3, -fAlphaGas);
|
||||
G4complex H = H2 * H3;
|
||||
|
||||
G4complex Z1 = GetMediumComplexFZ(energy,gamma,varAngle);
|
||||
G4complex Z2 = GetPlateComplexFZ(energy,gamma,varAngle);
|
||||
G4complex Z3 = GetGasComplexFZ(energy,gamma,varAngle);
|
||||
G4complex Z1 = GetMediumComplexFZ(energy, gamma, varAngle);
|
||||
G4complex Z2 = GetPlateComplexFZ(energy, gamma, varAngle);
|
||||
G4complex Z3 = GetGasComplexFZ(energy, gamma, varAngle);
|
||||
|
||||
G4complex R = (Z1 - Z2) * (Z1 - Z2) * (1. - H2 * H) +
|
||||
(Z2 - Z3) * (Z2 - Z3) * (1. - H3) +
|
||||
2. * (Z1 - Z2) * (Z2 - Z3) * H2 * (1. - H3);
|
||||
|
||||
G4complex R = ( Z1 - Z2 )*( Z1 - Z2 )*( 1. - H2*H ) +
|
||||
( Z2 - Z3 )*( Z2 - Z3 )*( 1. - H3 ) +
|
||||
2.*( Z1 - Z2 )*( Z2 - Z3 )*H2*( 1. - H3 ) ;
|
||||
|
||||
result = 2.0*std::real(R)*(varAngle*energy/hbarc/hbarc);
|
||||
|
||||
return result;
|
||||
result = 2.0 * std::real(R) * (varAngle * energy / hbarc / hbarc);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Calculates formation zone for external medium. Omega is energy !!!
|
||||
|
||||
G4double G4StrawTubeXTRadiator::GetMediumFormationZone( G4double omega ,
|
||||
G4double gamma ,
|
||||
G4double varAngle )
|
||||
G4double G4StrawTubeXTRadiator::GetMediumFormationZone(G4double omega,
|
||||
G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
G4double cof, lambda;
|
||||
lambda = 1.0/gamma/gamma + varAngle + fSigma3/omega/omega;
|
||||
cof = 2.0*hbarc/omega/lambda ;
|
||||
return cof ;
|
||||
lambda = 1.0 / gamma / gamma + varAngle + fSigma3 / omega / omega;
|
||||
cof = 2.0 * hbarc / omega / lambda;
|
||||
return cof;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Calculates complex formation zone for external medium. Omega is energy !!!
|
||||
|
||||
G4complex G4StrawTubeXTRadiator::GetMediumComplexFZ( G4double omega ,
|
||||
G4double gamma ,
|
||||
G4double varAngle )
|
||||
G4complex G4StrawTubeXTRadiator::GetMediumComplexFZ(G4double omega,
|
||||
G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
G4double cof, length,delta, real_v, image_v;
|
||||
G4double cof, length, delta, real_v, image_v;
|
||||
|
||||
length = 0.5*GetMediumFormationZone(omega,gamma,varAngle);
|
||||
delta = length*GetMediumLinearPhotoAbs(omega);
|
||||
cof = 1.0/(1.0 + delta*delta);
|
||||
length = 0.5 * GetMediumFormationZone(omega, gamma, varAngle);
|
||||
delta = length * GetMediumLinearPhotoAbs(omega);
|
||||
cof = 1.0 / (1.0 + delta * delta);
|
||||
|
||||
real_v = length*cof;
|
||||
image_v = real_v*delta;
|
||||
real_v = length * cof;
|
||||
image_v = real_v * delta;
|
||||
|
||||
G4complex zone(real_v,image_v);
|
||||
G4complex zone(real_v, image_v);
|
||||
return zone;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Computes matrix of Sandia photo absorption cross section coefficients for
|
||||
// medium material
|
||||
|
||||
void G4StrawTubeXTRadiator::ComputeMediumPhotoAbsCof()
|
||||
void G4StrawTubeXTRadiator::ComputeMediumPhotoAbsCof()
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const G4Material* mat = (*theMaterialTable)[fMatIndex3];
|
||||
fMediumPhotoAbsCof = mat->GetSandiaTable();
|
||||
const G4Material* mat = (*theMaterialTable)[fMatIndex3];
|
||||
fMediumPhotoAbsCof = mat->GetSandiaTable();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns the value of linear photo absorption coefficient (in reciprocal
|
||||
// Returns the value of linear photo absorption coefficient (in reciprocal
|
||||
// length) for medium for given energy of X-ray photon omega
|
||||
|
||||
G4double G4StrawTubeXTRadiator::GetMediumLinearPhotoAbs(G4double omega)
|
||||
G4double G4StrawTubeXTRadiator::GetMediumLinearPhotoAbs(G4double omega)
|
||||
{
|
||||
G4double omega2, omega3, omega4;
|
||||
G4double omega2, omega3, omega4;
|
||||
|
||||
omega2 = omega*omega;
|
||||
omega3 = omega2*omega;
|
||||
omega4 = omega2*omega2;
|
||||
omega2 = omega * omega;
|
||||
omega3 = omega2 * omega;
|
||||
omega4 = omega2 * omega2;
|
||||
|
||||
const G4double* SandiaCof = fMediumPhotoAbsCof->GetSandiaCofForMaterial(omega);
|
||||
const G4double* SandiaCof =
|
||||
fMediumPhotoAbsCof->GetSandiaCofForMaterial(omega);
|
||||
|
||||
G4double cross = SandiaCof[0]/omega + SandiaCof[1]/omega2 +
|
||||
SandiaCof[2]/omega3 + SandiaCof[3]/omega4;
|
||||
G4double cross = SandiaCof[0] / omega + SandiaCof[1] / omega2 +
|
||||
SandiaCof[2] / omega3 + SandiaCof[3] / omega4;
|
||||
return cross;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,42 +23,39 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// History: first implementation,
|
||||
// History: first implementation,
|
||||
// 21-5-98 V.Grichine
|
||||
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
|
||||
// 04.03.05, V.Grichine: get local field interface
|
||||
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
|
||||
// 04.03.05, V.Grichine: get local field interface
|
||||
// 18-05-06 H. Burkhardt: Energy spectrum from function rather than table
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4SynchrotronRadiation.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
|
||||
#include "G4DipBustGenerator.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4EmProcessSubType.hh"
|
||||
#include "G4Log.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4PropagatorInField.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
|
||||
G4SynchrotronRadiation::G4SynchrotronRadiation(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
theGamma (G4Gamma::Gamma() )
|
||||
G4ProcessType type)
|
||||
: G4VDiscreteProcess(processName, type)
|
||||
, theGamma(G4Gamma::Gamma())
|
||||
{
|
||||
G4TransportationManager* transportMgr =
|
||||
G4TransportationManager* transportMgr =
|
||||
G4TransportationManager::GetTransportationManager();
|
||||
|
||||
fFieldPropagator = transportMgr->GetPropagatorInField();
|
||||
@@ -74,10 +71,7 @@ G4SynchrotronRadiation::G4SynchrotronRadiation(const G4String& processName,
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
//
|
||||
|
||||
G4SynchrotronRadiation::~G4SynchrotronRadiation()
|
||||
{
|
||||
delete genAngle;
|
||||
@@ -85,122 +79,115 @@ G4SynchrotronRadiation::~G4SynchrotronRadiation()
|
||||
}
|
||||
|
||||
/////////////////////////////// METHODS /////////////////////////////////
|
||||
//
|
||||
|
||||
void
|
||||
G4SynchrotronRadiation::SetAngularGenerator(G4VEmAngularDistribution* p)
|
||||
void G4SynchrotronRadiation::SetAngularGenerator(G4VEmAngularDistribution* p)
|
||||
{
|
||||
if(p != genAngle) {
|
||||
if(p != genAngle)
|
||||
{
|
||||
delete genAngle;
|
||||
genAngle = p;
|
||||
}
|
||||
}
|
||||
|
||||
G4bool
|
||||
G4SynchrotronRadiation::IsApplicable(const G4ParticleDefinition& particle)
|
||||
G4bool G4SynchrotronRadiation::IsApplicable(
|
||||
const G4ParticleDefinition& particle)
|
||||
{
|
||||
return (particle.GetPDGCharge() != 0.0 && !particle.IsShortLived());
|
||||
return (particle.GetPDGCharge() != 0.0 && !particle.IsShortLived());
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Production of synchrotron X-ray photon
|
||||
// GEANT4 internal units.
|
||||
//
|
||||
|
||||
G4double
|
||||
G4SynchrotronRadiation::GetMeanFreePath(const G4Track& trackData,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
// Geant4 internal units.
|
||||
G4double G4SynchrotronRadiation::GetMeanFreePath(const G4Track& trackData,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
// gives the MeanFreePath in GEANT4 internal units
|
||||
// gives the MeanFreePath in Geant4 internal units
|
||||
G4double MeanFreePath = DBL_MAX;
|
||||
|
||||
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
|
||||
|
||||
*condition = NotForced;
|
||||
|
||||
G4double gamma = aDynamicParticle->GetTotalEnergy()/
|
||||
aDynamicParticle->GetMass();
|
||||
G4double gamma =
|
||||
aDynamicParticle->GetTotalEnergy() / aDynamicParticle->GetMass();
|
||||
|
||||
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
|
||||
if ( gamma < 1.0e3 || 0.0 == particleCharge) { MeanFreePath = DBL_MAX; }
|
||||
if(gamma < 1.0e3 || 0.0 == particleCharge)
|
||||
{
|
||||
MeanFreePath = DBL_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
G4FieldManager* fieldMgr =
|
||||
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
|
||||
|
||||
|
||||
G4FieldManager* fieldMgr =
|
||||
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
|
||||
|
||||
if ( fieldMgr != nullptr )
|
||||
if(fieldMgr != nullptr)
|
||||
{
|
||||
// If the field manager has no field, there is no field !
|
||||
|
||||
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
|
||||
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
|
||||
}
|
||||
|
||||
if ( fieldExertsForce )
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
if(fieldExertsForce)
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
|
||||
globPosVec[0] = globPosition.x();
|
||||
globPosVec[1] = globPosition.y();
|
||||
globPosVec[2] = globPosition.z();
|
||||
globPosVec[3] = trackData.GetGlobalTime();
|
||||
|
||||
pField->GetFieldValue( globPosVec, FieldValueVec );
|
||||
pField->GetFieldValue(globPosVec, FieldValueVec);
|
||||
|
||||
FieldValue = G4ThreeVector( FieldValueVec[0],
|
||||
FieldValueVec[1],
|
||||
FieldValueVec[2] );
|
||||
FieldValue =
|
||||
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag();
|
||||
|
||||
static const G4double fLambdaConst = std::sqrt(3.0)*eplus/
|
||||
(2.5*fine_structure_const*c_light);
|
||||
|
||||
if( perpB > 0.0 )
|
||||
static const G4double fLambdaConst =
|
||||
std::sqrt(3.0) * eplus / (2.5 * fine_structure_const * c_light);
|
||||
|
||||
if(perpB > 0.0)
|
||||
{
|
||||
MeanFreePath =
|
||||
fLambdaConst*aDynamicParticle->GetDefinition()->GetPDGMass()
|
||||
/(perpB*particleCharge*particleCharge);
|
||||
MeanFreePath = fLambdaConst *
|
||||
aDynamicParticle->GetDefinition()->GetPDGMass() /
|
||||
(perpB * particleCharge * particleCharge);
|
||||
}
|
||||
if(verboseLevel > 0 && FirstTime)
|
||||
{
|
||||
G4cout << "G4SynchrotronRadiation::GetMeanFreePath "
|
||||
<< " for particle "
|
||||
<< aDynamicParticle->GetDefinition()->GetParticleName()
|
||||
<< ":" << '\n' //hbunew
|
||||
<< " MeanFreePath = " << G4BestUnit(MeanFreePath, "Length")
|
||||
<< G4endl;
|
||||
<< " for particle "
|
||||
<< aDynamicParticle->GetDefinition()->GetParticleName() << ":"
|
||||
<< '\n'
|
||||
<< " MeanFreePath = " << G4BestUnit(MeanFreePath, "Length")
|
||||
<< G4endl;
|
||||
if(verboseLevel > 1)
|
||||
{
|
||||
G4ThreeVector pvec = aDynamicParticle->GetMomentum();
|
||||
G4double Btot = FieldValue.getR();
|
||||
G4double ptot = pvec.getR();
|
||||
G4double rho = ptot / (MeV * c_light * Btot );
|
||||
// full bending radius
|
||||
G4double Theta=unitMomentum.theta(FieldValue);
|
||||
// angle between particle and field
|
||||
G4cout << " B = " << Btot/tesla << " Tesla"
|
||||
<< " perpB = " << perpB/tesla << " Tesla"
|
||||
<< " Theta = " << Theta << " std::sin(Theta)="
|
||||
<< std::sin(Theta) << '\n'
|
||||
<< " ptot = " << G4BestUnit(ptot,"Energy")
|
||||
<< " rho = " << G4BestUnit(rho,"Length")
|
||||
<< G4endl;
|
||||
G4double Btot = FieldValue.getR();
|
||||
G4double ptot = pvec.getR();
|
||||
G4double rho = ptot / (MeV * c_light * Btot);
|
||||
// full bending radius
|
||||
G4double Theta = unitMomentum.theta(FieldValue);
|
||||
// angle between particle and field
|
||||
G4cout << " B = " << Btot / tesla << " Tesla"
|
||||
<< " perpB = " << perpB / tesla << " Tesla"
|
||||
<< " Theta = " << Theta
|
||||
<< " std::sin(Theta)=" << std::sin(Theta) << '\n'
|
||||
<< " ptot = " << G4BestUnit(ptot, "Energy")
|
||||
<< " rho = " << G4BestUnit(rho, "Length") << G4endl;
|
||||
}
|
||||
FirstTime=false;
|
||||
FirstTime = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,220 +195,229 @@ G4SynchrotronRadiation::GetMeanFreePath(const G4Track& trackData,
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4VParticleChange*
|
||||
G4SynchrotronRadiation::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& stepData )
|
||||
G4VParticleChange* G4SynchrotronRadiation::PostStepDoIt(
|
||||
const G4Track& trackData, const G4Step& stepData)
|
||||
|
||||
{
|
||||
aParticleChange.Initialize(trackData);
|
||||
|
||||
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
|
||||
|
||||
G4double gamma = aDynamicParticle->GetTotalEnergy()/
|
||||
(aDynamicParticle->GetDefinition()->GetPDGMass());
|
||||
G4double gamma = aDynamicParticle->GetTotalEnergy() /
|
||||
(aDynamicParticle->GetDefinition()->GetPDGMass());
|
||||
|
||||
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
if(gamma <= 1.0e3 || 0.0 == particleCharge)
|
||||
if(gamma <= 1.0e3 || 0.0 == particleCharge)
|
||||
{
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
|
||||
G4bool fieldExertsForce = false;
|
||||
G4FieldManager* fieldMgr =
|
||||
G4bool fieldExertsForce = false;
|
||||
G4FieldManager* fieldMgr =
|
||||
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
|
||||
|
||||
if ( fieldMgr != nullptr )
|
||||
if(fieldMgr != nullptr)
|
||||
{
|
||||
// If the field manager has no field, there is no field !
|
||||
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
|
||||
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
|
||||
}
|
||||
|
||||
if ( fieldExertsForce )
|
||||
|
||||
if(fieldExertsForce)
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
globPosVec[0] = globPosition.x();
|
||||
globPosVec[1] = globPosition.y();
|
||||
globPosVec[2] = globPosition.z();
|
||||
globPosVec[3] = trackData.GetGlobalTime();
|
||||
|
||||
pField->GetFieldValue( globPosVec, FieldValueVec );
|
||||
FieldValue = G4ThreeVector( FieldValueVec[0],
|
||||
FieldValueVec[1],
|
||||
FieldValueVec[2] );
|
||||
pField->GetFieldValue(globPosVec, FieldValueVec);
|
||||
FieldValue =
|
||||
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag();
|
||||
if(perpB > 0.0)
|
||||
{
|
||||
// M-C of synchrotron photon energy
|
||||
|
||||
G4double energyOfSR =
|
||||
GetRandomEnergySR(gamma,perpB,
|
||||
aDynamicParticle->GetDefinition()->GetPDGMass());
|
||||
G4double energyOfSR = GetRandomEnergySR(
|
||||
gamma, perpB, aDynamicParticle->GetDefinition()->GetPDGMass());
|
||||
|
||||
// check against insufficient energy
|
||||
|
||||
if( energyOfSR <= 0.0 )
|
||||
if(energyOfSR <= 0.0)
|
||||
{
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
|
||||
G4ThreeVector gammaDirection =
|
||||
genAngle->SampleDirection(aDynamicParticle,
|
||||
energyOfSR, 1, 0);
|
||||
G4ThreeVector gammaDirection =
|
||||
genAngle->SampleDirection(aDynamicParticle, energyOfSR, 1, 0);
|
||||
|
||||
G4ThreeVector gammaPolarization = FieldValue.cross(gammaDirection);
|
||||
gammaPolarization = gammaPolarization.unit();
|
||||
gammaPolarization = gammaPolarization.unit();
|
||||
|
||||
// create G4DynamicParticle object for the SR photon
|
||||
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle ( theGamma,
|
||||
gammaDirection,
|
||||
energyOfSR );
|
||||
aGamma->SetPolarization( gammaPolarization.x(),
|
||||
gammaPolarization.y(),
|
||||
gammaPolarization.z() );
|
||||
G4DynamicParticle* aGamma =
|
||||
new G4DynamicParticle(theGamma, gammaDirection, energyOfSR);
|
||||
aGamma->SetPolarization(gammaPolarization.x(), gammaPolarization.y(),
|
||||
gammaPolarization.z());
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
|
||||
// Update the incident particle
|
||||
|
||||
G4double newKinEnergy = kineticEnergy - energyOfSR;
|
||||
|
||||
if (newKinEnergy > 0.)
|
||||
if(newKinEnergy > 0.)
|
||||
{
|
||||
aParticleChange.ProposeEnergy( newKinEnergy );
|
||||
aParticleChange.ProposeEnergy(newKinEnergy);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.ProposeEnergy( 0. );
|
||||
aParticleChange.ProposeEnergy(0.);
|
||||
}
|
||||
}
|
||||
}
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4SynchrotronRadiation::InvSynFracInt(G4double x)
|
||||
// direct generation
|
||||
{
|
||||
// from 0 to 0.7
|
||||
static const G4double aa1=0 ,aa2=0.7;
|
||||
static const G4int ncheb1=27;
|
||||
static const G4double cheb1[] =
|
||||
{ 1.22371665676046468821,0.108956475422163837267,0.0383328524358594396134,0.00759138369340257753721,
|
||||
0.00205712048644963340914,0.000497810783280019308661,0.000130743691810302187818,0.0000338168760220395409734,
|
||||
8.97049680900520817728e-6,2.38685472794452241466e-6,6.41923109149104165049e-7,1.73549898982749277843e-7,
|
||||
4.72145949240790029153e-8,1.29039866111999149636e-8,3.5422080787089834182e-9,9.7594757336403784905e-10,
|
||||
2.6979510184976065731e-10,7.480422622550977077e-11,2.079598176402699913e-11,5.79533622220841193e-12,
|
||||
1.61856011449276096e-12,4.529450993473807e-13,1.2698603951096606e-13,3.566117394511206e-14,1.00301587494091e-14,
|
||||
2.82515346447219e-15,7.9680747949792e-16};
|
||||
static constexpr G4double aa1 = 0;
|
||||
static constexpr G4double aa2 = 0.7;
|
||||
static constexpr G4int ncheb1 = 27;
|
||||
static constexpr G4double cheb1[ncheb1] = {
|
||||
1.22371665676046468821, 0.108956475422163837267,
|
||||
0.0383328524358594396134, 0.00759138369340257753721,
|
||||
0.00205712048644963340914, 0.000497810783280019308661,
|
||||
0.000130743691810302187818, 0.0000338168760220395409734,
|
||||
8.97049680900520817728e-6, 2.38685472794452241466e-6,
|
||||
6.41923109149104165049e-7, 1.73549898982749277843e-7,
|
||||
4.72145949240790029153e-8, 1.29039866111999149636e-8,
|
||||
3.5422080787089834182e-9, 9.7594757336403784905e-10,
|
||||
2.6979510184976065731e-10, 7.480422622550977077e-11,
|
||||
2.079598176402699913e-11, 5.79533622220841193e-12,
|
||||
1.61856011449276096e-12, 4.529450993473807e-13,
|
||||
1.2698603951096606e-13, 3.566117394511206e-14,
|
||||
1.00301587494091e-14, 2.82515346447219e-15,
|
||||
7.9680747949792e-16
|
||||
};
|
||||
// from 0.7 to 0.9132260271183847
|
||||
static const G4double aa3=0.9132260271183847;
|
||||
static const G4int ncheb2=27;
|
||||
static const G4double cheb2[] =
|
||||
{ 1.1139496701107756,0.3523967429328067,0.0713849171926623,0.01475818043595387,0.003381255637322462,
|
||||
0.0008228057599452224,0.00020785506681254216,0.00005390169253706556,0.000014250571923902464,3.823880733161044e-6,
|
||||
1.0381966089136036e-6,2.8457557457837253e-7,7.86223332179956e-8,2.1866609342508474e-8,6.116186259857143e-9,
|
||||
1.7191233618437565e-9,4.852755117740807e-10,1.3749966961763457e-10,3.908961987062447e-11,1.1146253766895824e-11,
|
||||
3.1868887323415814e-12,9.134319791300977e-13,2.6211077371181566e-13,7.588643377757906e-14,2.1528376972619e-14,
|
||||
6.030906040404772e-15,1.9549163926819867e-15};
|
||||
// Chebyshev with exp/log scale
|
||||
// a = -Log[1 - SynFracInt[1]]; b = -Log[1 - SynFracInt[7]];
|
||||
static const G4double aa4=2.4444485538746025480,aa5=9.3830728608909477079;
|
||||
static const G4int ncheb3=28;
|
||||
static const G4double cheb3[] =
|
||||
{ 1.2292683840435586977,0.160353449247864455879,-0.0353559911947559448721,0.00776901561223573936985,
|
||||
-0.00165886451971685133259,0.000335719118906954279467,-0.0000617184951079161143187,9.23534039743246708256e-6,
|
||||
-6.06747198795168022842e-7,-3.07934045961999778094e-7,1.98818772614682367781e-7,-8.13909971567720135413e-8,
|
||||
2.84298174969641838618e-8,-9.12829766621316063548e-9,2.77713868004820551077e-9,-8.13032767247834023165e-10,
|
||||
2.31128525568385247392e-10,-6.41796873254200220876e-11,1.74815310473323361543e-11,-4.68653536933392363045e-12,
|
||||
1.24016595805520752748e-12,-3.24839432979935522159e-13,8.44601465226513952994e-14,-2.18647276044246803998e-14,
|
||||
5.65407548745690689978e-15,-1.46553625917463067508e-15,3.82059606377570462276e-16,-1.00457896653436912508e-16};
|
||||
static const G4double aa6=33.122936966163038145;
|
||||
static const G4int ncheb4=27;
|
||||
static const G4double cheb4[] =
|
||||
{1.69342658227676741765,0.0742766400841232319225,-0.019337880608635717358,0.00516065527473364110491,
|
||||
-0.00139342012990307729473,0.000378549864052022522193,-0.000103167085583785340215,0.0000281543441271412178337,
|
||||
-7.68409742018258198651e-6,2.09543221890204537392e-6,-5.70493140367526282946e-7,1.54961164548564906446e-7,
|
||||
-4.19665599629607704794e-8,1.13239680054166507038e-8,-3.04223563379021441863e-9,8.13073745977562957997e-10,
|
||||
-2.15969415476814981374e-10,5.69472105972525594811e-11,-1.48844799572430829499e-11,3.84901514438304484973e-12,
|
||||
-9.82222575944247161834e-13,2.46468329208292208183e-13,-6.04953826265982691612e-14,1.44055805710671611984e-14,
|
||||
-3.28200813577388740722e-15,6.96566359173765367675e-16,-1.294122794852896275e-16};
|
||||
static constexpr G4double aa3 = 0.9132260271183847;
|
||||
static constexpr G4int ncheb2 = 27;
|
||||
static constexpr G4double cheb2[ncheb2] = {
|
||||
1.1139496701107756, 0.3523967429328067, 0.0713849171926623,
|
||||
0.01475818043595387, 0.003381255637322462, 0.0008228057599452224,
|
||||
0.00020785506681254216, 0.00005390169253706556, 0.000014250571923902464,
|
||||
3.823880733161044e-6, 1.0381966089136036e-6, 2.8457557457837253e-7,
|
||||
7.86223332179956e-8, 2.1866609342508474e-8, 6.116186259857143e-9,
|
||||
1.7191233618437565e-9, 4.852755117740807e-10, 1.3749966961763457e-10,
|
||||
3.908961987062447e-11, 1.1146253766895824e-11, 3.1868887323415814e-12,
|
||||
9.134319791300977e-13, 2.6211077371181566e-13, 7.588643377757906e-14,
|
||||
2.1528376972619e-14, 6.030906040404772e-15, 1.9549163926819867e-15
|
||||
};
|
||||
// Chebyshev with exp/log scale
|
||||
// a = -Log[1 - SynFracInt[1]]; b = -Log[1 - SynFracInt[7]];
|
||||
static constexpr G4double aa4 = 2.4444485538746025480;
|
||||
static constexpr G4double aa5 = 9.3830728608909477079;
|
||||
static constexpr G4int ncheb3 = 28;
|
||||
static constexpr G4double cheb3[ncheb3] = {
|
||||
1.2292683840435586977, 0.160353449247864455879,
|
||||
-0.0353559911947559448721, 0.00776901561223573936985,
|
||||
-0.00165886451971685133259, 0.000335719118906954279467,
|
||||
-0.0000617184951079161143187, 9.23534039743246708256e-6,
|
||||
-6.06747198795168022842e-7, -3.07934045961999778094e-7,
|
||||
1.98818772614682367781e-7, -8.13909971567720135413e-8,
|
||||
2.84298174969641838618e-8, -9.12829766621316063548e-9,
|
||||
2.77713868004820551077e-9, -8.13032767247834023165e-10,
|
||||
2.31128525568385247392e-10, -6.41796873254200220876e-11,
|
||||
1.74815310473323361543e-11, -4.68653536933392363045e-12,
|
||||
1.24016595805520752748e-12, -3.24839432979935522159e-13,
|
||||
8.44601465226513952994e-14, -2.18647276044246803998e-14,
|
||||
5.65407548745690689978e-15, -1.46553625917463067508e-15,
|
||||
3.82059606377570462276e-16, -1.00457896653436912508e-16
|
||||
};
|
||||
static constexpr G4double aa6 = 33.122936966163038145;
|
||||
static constexpr G4int ncheb4 = 27;
|
||||
static constexpr G4double cheb4[ncheb4] = {
|
||||
1.69342658227676741765, 0.0742766400841232319225,
|
||||
-0.019337880608635717358, 0.00516065527473364110491,
|
||||
-0.00139342012990307729473, 0.000378549864052022522193,
|
||||
-0.000103167085583785340215, 0.0000281543441271412178337,
|
||||
-7.68409742018258198651e-6, 2.09543221890204537392e-6,
|
||||
-5.70493140367526282946e-7, 1.54961164548564906446e-7,
|
||||
-4.19665599629607704794e-8, 1.13239680054166507038e-8,
|
||||
-3.04223563379021441863e-9, 8.13073745977562957997e-10,
|
||||
-2.15969415476814981374e-10, 5.69472105972525594811e-11,
|
||||
-1.48844799572430829499e-11, 3.84901514438304484973e-12,
|
||||
-9.82222575944247161834e-13, 2.46468329208292208183e-13,
|
||||
-6.04953826265982691612e-14, 1.44055805710671611984e-14,
|
||||
-3.28200813577388740722e-15, 6.96566359173765367675e-16,
|
||||
-1.294122794852896275e-16
|
||||
};
|
||||
|
||||
if(x<aa2) return x*x*x*Chebyshev(aa1,aa2,cheb1,ncheb1,x);
|
||||
else if(x<aa3) return Chebyshev(aa2,aa3,cheb2,ncheb2,x);
|
||||
else if(x<1-0.0000841363)
|
||||
{ G4double y=-G4Log(1-x);
|
||||
return y*Chebyshev(aa4,aa5,cheb3,ncheb3,y);
|
||||
if(x < aa2)
|
||||
return x * x * x * Chebyshev(aa1, aa2, cheb1, ncheb1, x);
|
||||
else if(x < aa3)
|
||||
return Chebyshev(aa2, aa3, cheb2, ncheb2, x);
|
||||
else if(x < 1 - 0.0000841363)
|
||||
{
|
||||
G4double y = -G4Log(1 - x);
|
||||
return y * Chebyshev(aa4, aa5, cheb3, ncheb3, y);
|
||||
}
|
||||
else
|
||||
{ G4double y=-G4Log(1-x);
|
||||
return y*Chebyshev(aa5,aa6,cheb4,ncheb4,y);
|
||||
{
|
||||
G4double y = -G4Log(1 - x);
|
||||
return y * Chebyshev(aa5, aa6, cheb4, ncheb4, y);
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4SynchrotronRadiation::GetRandomEnergySR(
|
||||
G4double gamma, G4double perpB, G4double mass_c2)
|
||||
G4double G4SynchrotronRadiation::GetRandomEnergySR(G4double gamma,
|
||||
G4double perpB,
|
||||
G4double mass_c2)
|
||||
{
|
||||
|
||||
static const G4double fEnergyConst = 1.5*c_light*c_light*eplus*hbar_Planck;
|
||||
G4double Ecr=fEnergyConst*gamma*gamma*perpB/mass_c2;
|
||||
static const G4double fEnergyConst =
|
||||
1.5 * c_light * c_light * eplus * hbar_Planck;
|
||||
G4double Ecr = fEnergyConst * gamma * gamma * perpB / mass_c2;
|
||||
|
||||
if(verboseLevel > 0 && FirstTime1)
|
||||
{
|
||||
// mean and rms of photon energy
|
||||
G4double Emean=8./(15.*std::sqrt(3.))*Ecr;
|
||||
G4double E_rms=std::sqrt(211./675.)*Ecr;
|
||||
G4int prec = G4cout.precision();
|
||||
G4cout << "G4SynchrotronRadiation::GetRandomEnergySR :" << '\n'
|
||||
<< std::setprecision(4)
|
||||
<< " Ecr = " << G4BestUnit(Ecr,"Energy") << '\n'
|
||||
<< " Emean = " << G4BestUnit(Emean,"Energy") << '\n'
|
||||
<< " E_rms = " << G4BestUnit(E_rms,"Energy") << G4endl;
|
||||
FirstTime1=false;
|
||||
G4cout.precision(prec);
|
||||
{
|
||||
// mean and rms of photon energy
|
||||
G4double Emean = 8. / (15. * std::sqrt(3.)) * Ecr;
|
||||
G4double E_rms = std::sqrt(211. / 675.) * Ecr;
|
||||
G4int prec = G4cout.precision();
|
||||
G4cout << "G4SynchrotronRadiation::GetRandomEnergySR :" << '\n'
|
||||
<< std::setprecision(4) << " Ecr = " << G4BestUnit(Ecr, "Energy")
|
||||
<< '\n'
|
||||
<< " Emean = " << G4BestUnit(Emean, "Energy") << '\n'
|
||||
<< " E_rms = " << G4BestUnit(E_rms, "Energy") << G4endl;
|
||||
FirstTime1 = false;
|
||||
G4cout.precision(prec);
|
||||
}
|
||||
|
||||
G4double energySR=Ecr*InvSynFracInt(G4UniformRand());
|
||||
G4double energySR = Ecr * InvSynFracInt(G4UniformRand());
|
||||
return energySR;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void
|
||||
G4SynchrotronRadiation::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
void G4SynchrotronRadiation::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
if(0 < verboseLevel && &part==G4Electron::Electron() ) PrintInfoDefinition();
|
||||
if(0 < verboseLevel && &part == G4Electron::Electron())
|
||||
ProcessDescription(G4cout);
|
||||
// same for all particles, print only for one (electron)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void G4SynchrotronRadiation::PrintInfoDefinition()
|
||||
// not yet called, usually called from BuildPhysicsTable
|
||||
void G4SynchrotronRadiation::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
G4String comments ="Incoherent Synchrotron Radiation\n";
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< " good description for long magnets at all energies"
|
||||
<< G4endl;
|
||||
out << GetProcessName()
|
||||
<< ": Incoherent Synchrotron Radiation\n"
|
||||
"Good description for long magnets at all energies.\n";
|
||||
}
|
||||
|
||||
///////////////////// end of G4SynchrotronRadiation.cc
|
||||
|
||||
@@ -23,11 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// History: first implementation,
|
||||
// 21-5-98 V.Grichine
|
||||
@@ -35,650 +32,553 @@
|
||||
// 04.03.05, V.Grichine: get local field interface
|
||||
// 19-05-06, V.Ivanchenko rename from G4SynchrotronRadiation
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "G4SynchrotronRadiationInMat.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4Integrator.hh"
|
||||
|
||||
#include "G4EmProcessSubType.hh"
|
||||
#include "G4Field.hh"
|
||||
#include "G4FieldManager.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4PropagatorInField.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant for calculation of mean free path
|
||||
//
|
||||
|
||||
const G4double
|
||||
G4SynchrotronRadiationInMat::fLambdaConst = std::sqrt(3.0)*electron_mass_c2/
|
||||
(2.5*fine_structure_const*eplus*c_light) ;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant for calculation of characterictic energy
|
||||
//
|
||||
|
||||
const G4double
|
||||
G4SynchrotronRadiationInMat::fEnergyConst = 1.5*c_light*c_light*eplus*hbar_Planck/
|
||||
electron_mass_c2 ;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Array of integral probability of synchrotron photons:
|
||||
//
|
||||
// the corresponding energy = 0.0001*i*i*(characteristic energy)
|
||||
//
|
||||
|
||||
const G4double
|
||||
G4SynchrotronRadiationInMat::fIntegralProbabilityOfSR[200] =
|
||||
{
|
||||
1.000000e+00, 9.428859e-01, 9.094095e-01, 8.813971e-01, 8.565154e-01,
|
||||
8.337008e-01, 8.124961e-01, 7.925217e-01, 7.735517e-01, 7.554561e-01,
|
||||
7.381233e-01, 7.214521e-01, 7.053634e-01, 6.898006e-01, 6.747219e-01,
|
||||
6.600922e-01, 6.458793e-01, 6.320533e-01, 6.185872e-01, 6.054579e-01,
|
||||
5.926459e-01, 5.801347e-01, 5.679103e-01, 5.559604e-01, 5.442736e-01,
|
||||
5.328395e-01, 5.216482e-01, 5.106904e-01, 4.999575e-01, 4.894415e-01,
|
||||
4.791351e-01, 4.690316e-01, 4.591249e-01, 4.494094e-01, 4.398800e-01,
|
||||
4.305320e-01, 4.213608e-01, 4.123623e-01, 4.035325e-01, 3.948676e-01,
|
||||
3.863639e-01, 3.780179e-01, 3.698262e-01, 3.617858e-01, 3.538933e-01,
|
||||
3.461460e-01, 3.385411e-01, 3.310757e-01, 3.237474e-01, 3.165536e-01,
|
||||
3.094921e-01, 3.025605e-01, 2.957566e-01, 2.890784e-01, 2.825237e-01,
|
||||
2.760907e-01, 2.697773e-01, 2.635817e-01, 2.575020e-01, 2.515365e-01,
|
||||
2.456834e-01, 2.399409e-01, 2.343074e-01, 2.287812e-01, 2.233607e-01,
|
||||
2.180442e-01, 2.128303e-01, 2.077174e-01, 2.027040e-01, 1.977885e-01,
|
||||
1.929696e-01, 1.882457e-01, 1.836155e-01, 1.790775e-01, 1.746305e-01,
|
||||
1.702730e-01, 1.660036e-01, 1.618212e-01, 1.577243e-01, 1.537117e-01,
|
||||
1.497822e-01, 1.459344e-01, 1.421671e-01, 1.384791e-01, 1.348691e-01,
|
||||
1.313360e-01, 1.278785e-01, 1.244956e-01, 1.211859e-01, 1.179483e-01,
|
||||
1.147818e-01, 1.116850e-01, 1.086570e-01, 1.056966e-01, 1.028026e-01,
|
||||
9.997405e-02, 9.720975e-02, 9.450865e-02, 9.186969e-02, 8.929179e-02,
|
||||
8.677391e-02, 8.431501e-02, 8.191406e-02, 7.957003e-02, 7.728192e-02,
|
||||
7.504872e-02, 7.286944e-02, 7.074311e-02, 6.866874e-02, 6.664538e-02,
|
||||
6.467208e-02, 6.274790e-02, 6.087191e-02, 5.904317e-02, 5.726079e-02,
|
||||
5.552387e-02, 5.383150e-02, 5.218282e-02, 5.057695e-02, 4.901302e-02,
|
||||
4.749020e-02, 4.600763e-02, 4.456450e-02, 4.315997e-02, 4.179325e-02,
|
||||
4.046353e-02, 3.917002e-02, 3.791195e-02, 3.668855e-02, 3.549906e-02,
|
||||
3.434274e-02, 3.321884e-02, 3.212665e-02, 3.106544e-02, 3.003452e-02,
|
||||
2.903319e-02, 2.806076e-02, 2.711656e-02, 2.619993e-02, 2.531021e-02,
|
||||
2.444677e-02, 2.360897e-02, 2.279620e-02, 2.200783e-02, 2.124327e-02,
|
||||
2.050194e-02, 1.978324e-02, 1.908662e-02, 1.841151e-02, 1.775735e-02,
|
||||
1.712363e-02, 1.650979e-02, 1.591533e-02, 1.533973e-02, 1.478250e-02,
|
||||
1.424314e-02, 1.372117e-02, 1.321613e-02, 1.272755e-02, 1.225498e-02,
|
||||
1.179798e-02, 1.135611e-02, 1.092896e-02, 1.051609e-02, 1.011712e-02,
|
||||
9.731635e-03, 9.359254e-03, 8.999595e-03, 8.652287e-03, 8.316967e-03,
|
||||
7.993280e-03, 7.680879e-03, 7.379426e-03, 7.088591e-03, 6.808051e-03,
|
||||
6.537491e-03, 6.276605e-03, 6.025092e-03, 5.782661e-03, 5.549027e-03,
|
||||
5.323912e-03, 5.107045e-03, 4.898164e-03, 4.697011e-03, 4.503336e-03,
|
||||
4.316896e-03, 4.137454e-03, 3.964780e-03, 3.798649e-03, 3.638843e-03,
|
||||
3.485150e-03, 3.337364e-03, 3.195284e-03, 3.058715e-03, 2.927469e-03,
|
||||
2.801361e-03, 2.680213e-03, 2.563852e-03, 2.452110e-03, 2.344824e-03
|
||||
const G4double G4SynchrotronRadiationInMat::fIntegralProbabilityOfSR[200] = {
|
||||
1.000000e+00, 9.428859e-01, 9.094095e-01, 8.813971e-01, 8.565154e-01,
|
||||
8.337008e-01, 8.124961e-01, 7.925217e-01, 7.735517e-01, 7.554561e-01,
|
||||
7.381233e-01, 7.214521e-01, 7.053634e-01, 6.898006e-01, 6.747219e-01,
|
||||
6.600922e-01, 6.458793e-01, 6.320533e-01, 6.185872e-01, 6.054579e-01,
|
||||
5.926459e-01, 5.801347e-01, 5.679103e-01, 5.559604e-01, 5.442736e-01,
|
||||
5.328395e-01, 5.216482e-01, 5.106904e-01, 4.999575e-01, 4.894415e-01,
|
||||
4.791351e-01, 4.690316e-01, 4.591249e-01, 4.494094e-01, 4.398800e-01,
|
||||
4.305320e-01, 4.213608e-01, 4.123623e-01, 4.035325e-01, 3.948676e-01,
|
||||
3.863639e-01, 3.780179e-01, 3.698262e-01, 3.617858e-01, 3.538933e-01,
|
||||
3.461460e-01, 3.385411e-01, 3.310757e-01, 3.237474e-01, 3.165536e-01,
|
||||
3.094921e-01, 3.025605e-01, 2.957566e-01, 2.890784e-01, 2.825237e-01,
|
||||
2.760907e-01, 2.697773e-01, 2.635817e-01, 2.575020e-01, 2.515365e-01,
|
||||
2.456834e-01, 2.399409e-01, 2.343074e-01, 2.287812e-01, 2.233607e-01,
|
||||
2.180442e-01, 2.128303e-01, 2.077174e-01, 2.027040e-01, 1.977885e-01,
|
||||
1.929696e-01, 1.882457e-01, 1.836155e-01, 1.790775e-01, 1.746305e-01,
|
||||
1.702730e-01, 1.660036e-01, 1.618212e-01, 1.577243e-01, 1.537117e-01,
|
||||
1.497822e-01, 1.459344e-01, 1.421671e-01, 1.384791e-01, 1.348691e-01,
|
||||
1.313360e-01, 1.278785e-01, 1.244956e-01, 1.211859e-01, 1.179483e-01,
|
||||
1.147818e-01, 1.116850e-01, 1.086570e-01, 1.056966e-01, 1.028026e-01,
|
||||
9.997405e-02, 9.720975e-02, 9.450865e-02, 9.186969e-02, 8.929179e-02,
|
||||
8.677391e-02, 8.431501e-02, 8.191406e-02, 7.957003e-02, 7.728192e-02,
|
||||
7.504872e-02, 7.286944e-02, 7.074311e-02, 6.866874e-02, 6.664538e-02,
|
||||
6.467208e-02, 6.274790e-02, 6.087191e-02, 5.904317e-02, 5.726079e-02,
|
||||
5.552387e-02, 5.383150e-02, 5.218282e-02, 5.057695e-02, 4.901302e-02,
|
||||
4.749020e-02, 4.600763e-02, 4.456450e-02, 4.315997e-02, 4.179325e-02,
|
||||
4.046353e-02, 3.917002e-02, 3.791195e-02, 3.668855e-02, 3.549906e-02,
|
||||
3.434274e-02, 3.321884e-02, 3.212665e-02, 3.106544e-02, 3.003452e-02,
|
||||
2.903319e-02, 2.806076e-02, 2.711656e-02, 2.619993e-02, 2.531021e-02,
|
||||
2.444677e-02, 2.360897e-02, 2.279620e-02, 2.200783e-02, 2.124327e-02,
|
||||
2.050194e-02, 1.978324e-02, 1.908662e-02, 1.841151e-02, 1.775735e-02,
|
||||
1.712363e-02, 1.650979e-02, 1.591533e-02, 1.533973e-02, 1.478250e-02,
|
||||
1.424314e-02, 1.372117e-02, 1.321613e-02, 1.272755e-02, 1.225498e-02,
|
||||
1.179798e-02, 1.135611e-02, 1.092896e-02, 1.051609e-02, 1.011712e-02,
|
||||
9.731635e-03, 9.359254e-03, 8.999595e-03, 8.652287e-03, 8.316967e-03,
|
||||
7.993280e-03, 7.680879e-03, 7.379426e-03, 7.088591e-03, 6.808051e-03,
|
||||
6.537491e-03, 6.276605e-03, 6.025092e-03, 5.782661e-03, 5.549027e-03,
|
||||
5.323912e-03, 5.107045e-03, 4.898164e-03, 4.697011e-03, 4.503336e-03,
|
||||
4.316896e-03, 4.137454e-03, 3.964780e-03, 3.798649e-03, 3.638843e-03,
|
||||
3.485150e-03, 3.337364e-03, 3.195284e-03, 3.058715e-03, 2.927469e-03,
|
||||
2.801361e-03, 2.680213e-03, 2.563852e-03, 2.452110e-03, 2.344824e-03
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
|
||||
G4SynchrotronRadiationInMat::G4SynchrotronRadiationInMat(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
LowestKineticEnergy (10.*keV),
|
||||
theGamma (G4Gamma::Gamma() ),
|
||||
theElectron ( G4Electron::Electron() ),
|
||||
thePositron ( G4Positron::Positron() ),
|
||||
fAlpha(0.0), fRootNumber(80),
|
||||
fVerboseLevel( verboseLevel )
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
G4SynchrotronRadiationInMat::G4SynchrotronRadiationInMat(
|
||||
const G4String& processName, G4ProcessType type)
|
||||
: G4VDiscreteProcess(processName, type)
|
||||
, theGamma(G4Gamma::Gamma())
|
||||
, theElectron(G4Electron::Electron())
|
||||
, thePositron(G4Positron::Positron())
|
||||
, LowestKineticEnergy(10. * keV)
|
||||
, fAlpha(0.0)
|
||||
, fRootNumber(80)
|
||||
, fVerboseLevel(verboseLevel)
|
||||
{
|
||||
G4TransportationManager* transportMgr = G4TransportationManager::GetTransportationManager();
|
||||
G4TransportationManager* transportMgr =
|
||||
G4TransportationManager::GetTransportationManager();
|
||||
|
||||
fFieldPropagator = transportMgr->GetPropagatorInField();
|
||||
SetProcessSubType(fSynchrotronRadiation);
|
||||
CutInRange = GammaCutInKineticEnergyNow = ElectronCutInKineticEnergyNow =
|
||||
PositronCutInKineticEnergyNow = ParticleCutInKineticEnergyNow = fKsi =
|
||||
fPsiGamma = fEta = fOrderAngleK = 0.0;
|
||||
CutInRange = GammaCutInKineticEnergyNow = ElectronCutInKineticEnergyNow =
|
||||
PositronCutInKineticEnergyNow = ParticleCutInKineticEnergyNow = fKsi =
|
||||
fPsiGamma = fEta = fOrderAngleK = 0.0;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
//
|
||||
|
||||
G4SynchrotronRadiationInMat::~G4SynchrotronRadiationInMat()
|
||||
{}
|
||||
|
||||
G4SynchrotronRadiationInMat::~G4SynchrotronRadiationInMat() {}
|
||||
|
||||
G4bool
|
||||
G4SynchrotronRadiationInMat::IsApplicable( const G4ParticleDefinition& particle )
|
||||
G4bool G4SynchrotronRadiationInMat::IsApplicable(
|
||||
const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( ( &particle == (const G4ParticleDefinition *)theElectron ) ||
|
||||
( &particle == (const G4ParticleDefinition *)thePositron ));
|
||||
return ((&particle == (const G4ParticleDefinition*) theElectron) ||
|
||||
(&particle == (const G4ParticleDefinition*) thePositron));
|
||||
}
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetLambdaConst()
|
||||
{
|
||||
return fLambdaConst;
|
||||
}
|
||||
G4double G4SynchrotronRadiationInMat::GetLambdaConst() { return fLambdaConst; }
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetEnergyConst() { return fEnergyConst; }
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetEnergyConst()
|
||||
{
|
||||
return fEnergyConst;
|
||||
}
|
||||
|
||||
/////////////////////////////// METHODS /////////////////////////////////
|
||||
//
|
||||
//
|
||||
// Production of synchrotron X-ray photon
|
||||
// GEANT4 internal units.
|
||||
//
|
||||
|
||||
|
||||
G4double
|
||||
G4SynchrotronRadiationInMat::GetMeanFreePath( const G4Track& trackData,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
// Geant4 internal units.
|
||||
G4double G4SynchrotronRadiationInMat::GetMeanFreePath(
|
||||
const G4Track& trackData, G4double, G4ForceCondition* condition)
|
||||
{
|
||||
// gives the MeanFreePath in GEANT4 internal units
|
||||
G4double MeanFreePath;
|
||||
|
||||
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
|
||||
// G4Material* aMaterial = trackData.GetMaterial();
|
||||
|
||||
//G4bool isOutRange ;
|
||||
|
||||
*condition = NotForced ;
|
||||
*condition = NotForced;
|
||||
|
||||
G4double gamma = aDynamicParticle->GetTotalEnergy()/
|
||||
aDynamicParticle->GetMass();
|
||||
G4double gamma =
|
||||
aDynamicParticle->GetTotalEnergy() / aDynamicParticle->GetMass();
|
||||
|
||||
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
|
||||
G4double KineticEnergy = aDynamicParticle->GetKineticEnergy();
|
||||
|
||||
if ( KineticEnergy < LowestKineticEnergy || gamma < 1.0e3 ) MeanFreePath = DBL_MAX;
|
||||
if(KineticEnergy < LowestKineticEnergy || gamma < 1.0e3)
|
||||
MeanFreePath = DBL_MAX;
|
||||
else
|
||||
{
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
G4FieldManager* fieldMgr = nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
|
||||
G4FieldManager* fieldMgr=nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
|
||||
if( (particleCharge != 0.0) )
|
||||
if((particleCharge != 0.0))
|
||||
{
|
||||
fieldMgr = fFieldPropagator->FindAndSetFieldManager( trackData.GetVolume() );
|
||||
fieldMgr =
|
||||
fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
|
||||
|
||||
if ( fieldMgr != nullptr )
|
||||
if(fieldMgr != nullptr)
|
||||
{
|
||||
// If the field manager has no field, there is no field !
|
||||
|
||||
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
|
||||
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
|
||||
}
|
||||
}
|
||||
if ( fieldExertsForce )
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField() ;
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
if(fieldExertsForce)
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
|
||||
globPosVec[0] = globPosition.x();
|
||||
globPosVec[1] = globPosition.y();
|
||||
globPosVec[2] = globPosition.z();
|
||||
globPosVec[3] = trackData.GetGlobalTime();
|
||||
|
||||
pField->GetFieldValue( globPosVec, FieldValueVec );
|
||||
pField->GetFieldValue(globPosVec, FieldValueVec);
|
||||
|
||||
FieldValue = G4ThreeVector( FieldValueVec[0],
|
||||
FieldValueVec[1],
|
||||
FieldValueVec[2] );
|
||||
FieldValue =
|
||||
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
|
||||
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag();
|
||||
G4double beta = aDynamicParticle->GetTotalMomentum() /
|
||||
(aDynamicParticle->GetTotalEnergy());
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum) ;
|
||||
G4double perpB = unitMcrossB.mag() ;
|
||||
G4double beta = aDynamicParticle->GetTotalMomentum()/
|
||||
(aDynamicParticle->GetTotalEnergy() );
|
||||
|
||||
if( perpB > 0.0 ) MeanFreePath = fLambdaConst*beta/perpB;
|
||||
else MeanFreePath = DBL_MAX;
|
||||
if(perpB > 0.0)
|
||||
MeanFreePath = fLambdaConst * beta / perpB;
|
||||
else
|
||||
MeanFreePath = DBL_MAX;
|
||||
}
|
||||
else MeanFreePath = DBL_MAX;
|
||||
else
|
||||
MeanFreePath = DBL_MAX;
|
||||
}
|
||||
if(fVerboseLevel > 0)
|
||||
{
|
||||
G4cout<<"G4SynchrotronRadiationInMat::MeanFreePath = "<<MeanFreePath/m<<" m"<<G4endl;
|
||||
G4cout << "G4SynchrotronRadiationInMat::MeanFreePath = " << MeanFreePath / m
|
||||
<< " m" << G4endl;
|
||||
}
|
||||
return MeanFreePath;
|
||||
}
|
||||
return MeanFreePath;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4VParticleChange*
|
||||
G4SynchrotronRadiationInMat::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& stepData )
|
||||
G4VParticleChange* G4SynchrotronRadiationInMat::PostStepDoIt(
|
||||
const G4Track& trackData, const G4Step& stepData)
|
||||
|
||||
{
|
||||
aParticleChange.Initialize(trackData);
|
||||
|
||||
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
|
||||
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
|
||||
|
||||
G4double gamma = aDynamicParticle->GetTotalEnergy()/
|
||||
(aDynamicParticle->GetMass() );
|
||||
G4double gamma =
|
||||
aDynamicParticle->GetTotalEnergy() / (aDynamicParticle->GetMass());
|
||||
|
||||
if(gamma <= 1.0e3 )
|
||||
if(gamma <= 1.0e3)
|
||||
{
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr ;
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
|
||||
G4FieldManager* fieldMgr=nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
G4FieldManager* fieldMgr = nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
|
||||
if( (particleCharge != 0.0) )
|
||||
if((particleCharge != 0.0))
|
||||
{
|
||||
fieldMgr = fFieldPropagator->FindAndSetFieldManager( trackData.GetVolume() );
|
||||
if ( fieldMgr != nullptr )
|
||||
fieldMgr = fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
|
||||
if(fieldMgr != nullptr)
|
||||
{
|
||||
// If the field manager has no field, there is no field !
|
||||
|
||||
fieldExertsForce = ( fieldMgr->GetDetectorField() != nullptr );
|
||||
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
|
||||
}
|
||||
}
|
||||
if ( fieldExertsForce )
|
||||
if(fieldExertsForce)
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField() ;
|
||||
G4ThreeVector globPosition = trackData.GetPosition() ;
|
||||
G4double globPosVec[4], FieldValueVec[6] ;
|
||||
globPosVec[0] = globPosition.x() ;
|
||||
globPosVec[1] = globPosition.y() ;
|
||||
globPosVec[2] = globPosition.z() ;
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
G4double globPosVec[4], FieldValueVec[6];
|
||||
globPosVec[0] = globPosition.x();
|
||||
globPosVec[1] = globPosition.y();
|
||||
globPosVec[2] = globPosition.z();
|
||||
globPosVec[3] = trackData.GetGlobalTime();
|
||||
|
||||
pField->GetFieldValue( globPosVec, FieldValueVec ) ;
|
||||
FieldValue = G4ThreeVector( FieldValueVec[0],
|
||||
FieldValueVec[1],
|
||||
FieldValueVec[2] );
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag() ;
|
||||
pField->GetFieldValue(globPosVec, FieldValueVec);
|
||||
FieldValue =
|
||||
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag();
|
||||
if(perpB > 0.0)
|
||||
{
|
||||
// M-C of synchrotron photon energy
|
||||
|
||||
G4double energyOfSR = GetRandomEnergySR(gamma,perpB);
|
||||
G4double energyOfSR = GetRandomEnergySR(gamma, perpB);
|
||||
|
||||
if(fVerboseLevel > 0)
|
||||
{
|
||||
G4cout<<"SR photon energy = "<<energyOfSR/keV<<" keV"<<G4endl;
|
||||
G4cout << "SR photon energy = " << energyOfSR / keV << " keV" << G4endl;
|
||||
}
|
||||
// check against insufficient energy
|
||||
|
||||
if( energyOfSR <= 0.0 )
|
||||
// check against insufficient energy
|
||||
if(energyOfSR <= 0.0)
|
||||
{
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
|
||||
G4ParticleMomentum
|
||||
particleDirection = aDynamicParticle->GetMomentumDirection();
|
||||
G4ParticleMomentum particleDirection =
|
||||
aDynamicParticle->GetMomentumDirection();
|
||||
|
||||
// M-C of its direction, simplified dipole busted approach
|
||||
|
||||
// G4double Teta = G4UniformRand()/gamma ; // Very roughly
|
||||
|
||||
G4double cosTheta, sinTheta, fcos, beta;
|
||||
|
||||
do
|
||||
{
|
||||
cosTheta = 1. - 2.*G4UniformRand();
|
||||
fcos = (1 + cosTheta*cosTheta)*0.5;
|
||||
}
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
while( fcos < G4UniformRand() );
|
||||
do
|
||||
{
|
||||
cosTheta = 1. - 2. * G4UniformRand();
|
||||
fcos = (1 + cosTheta * cosTheta) * 0.5;
|
||||
}
|
||||
// Loop checking, 07-Aug-2015, Vladimir Ivanchenko
|
||||
while(fcos < G4UniformRand());
|
||||
|
||||
beta = std::sqrt(1. - 1./(gamma*gamma));
|
||||
beta = std::sqrt(1. - 1. / (gamma * gamma));
|
||||
|
||||
cosTheta = (cosTheta + beta)/(1. + beta*cosTheta);
|
||||
cosTheta = (cosTheta + beta) / (1. + beta * cosTheta);
|
||||
|
||||
if( cosTheta > 1. ) cosTheta = 1.;
|
||||
if( cosTheta < -1. ) cosTheta = -1.;
|
||||
if(cosTheta > 1.)
|
||||
cosTheta = 1.;
|
||||
if(cosTheta < -1.)
|
||||
cosTheta = -1.;
|
||||
|
||||
sinTheta = std::sqrt(1. - cosTheta*cosTheta );
|
||||
sinTheta = std::sqrt(1. - cosTheta * cosTheta);
|
||||
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double Phi = twopi * G4UniformRand();
|
||||
|
||||
G4double dirx = sinTheta*std::cos(Phi) ,
|
||||
diry = sinTheta*std::sin(Phi) ,
|
||||
dirz = cosTheta;
|
||||
G4double dirx = sinTheta * std::cos(Phi);
|
||||
G4double diry = sinTheta * std::sin(Phi);
|
||||
G4double dirz = cosTheta;
|
||||
|
||||
G4ThreeVector gammaDirection(dirx, diry, dirz);
|
||||
gammaDirection.rotateUz(particleDirection);
|
||||
|
||||
G4ThreeVector gammaDirection ( dirx, diry, dirz);
|
||||
gammaDirection.rotateUz(particleDirection);
|
||||
|
||||
// polarization of new gamma
|
||||
|
||||
// G4double sx = std::cos(Teta)*std::cos(Phi);
|
||||
// G4double sy = std::cos(Teta)*std::sin(Phi);
|
||||
// G4double sz = -std::sin(Teta);
|
||||
|
||||
G4ThreeVector gammaPolarization = FieldValue.cross(gammaDirection);
|
||||
gammaPolarization = gammaPolarization.unit();
|
||||
|
||||
// (sx, sy, sz);
|
||||
// gammaPolarization.rotateUz(particleDirection);
|
||||
gammaPolarization = gammaPolarization.unit();
|
||||
|
||||
// create G4DynamicParticle object for the SR photon
|
||||
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle ( G4Gamma::Gamma(),
|
||||
gammaDirection,
|
||||
energyOfSR );
|
||||
aGamma->SetPolarization( gammaPolarization.x(),
|
||||
gammaPolarization.y(),
|
||||
gammaPolarization.z() );
|
||||
|
||||
G4DynamicParticle* aGamma =
|
||||
new G4DynamicParticle(G4Gamma::Gamma(), gammaDirection, energyOfSR);
|
||||
aGamma->SetPolarization(gammaPolarization.x(), gammaPolarization.y(),
|
||||
gammaPolarization.z());
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
|
||||
// Update the incident particle
|
||||
|
||||
G4double newKinEnergy = kineticEnergy - energyOfSR ;
|
||||
|
||||
if (newKinEnergy > 0.)
|
||||
// Update the incident particle
|
||||
G4double newKinEnergy = kineticEnergy - energyOfSR;
|
||||
|
||||
if(newKinEnergy > 0.)
|
||||
{
|
||||
aParticleChange.ProposeMomentumDirection( particleDirection );
|
||||
aParticleChange.ProposeEnergy( newKinEnergy );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
}
|
||||
aParticleChange.ProposeMomentumDirection(particleDirection);
|
||||
aParticleChange.ProposeEnergy(newKinEnergy);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.ProposeEnergy( 0. );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
if (charge<0.)
|
||||
{
|
||||
aParticleChange.ProposeEnergy(0.);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(0.);
|
||||
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
if(charge < 0.)
|
||||
{
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill) ;
|
||||
}
|
||||
else
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.ProposeTrackStatus(fStopButAlive) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
aParticleChange.ProposeTrackStatus(fStopButAlive);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
}
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
return G4VDiscreteProcess::PostStepDoIt(trackData, stepData);
|
||||
}
|
||||
|
||||
|
||||
G4double
|
||||
G4SynchrotronRadiationInMat::GetPhotonEnergy( const G4Track& trackData,
|
||||
const G4Step& )
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetPhotonEnergy(const G4Track& trackData,
|
||||
const G4Step&)
|
||||
{
|
||||
G4int i ;
|
||||
G4double energyOfSR = -1.0 ;
|
||||
//G4Material* aMaterial=trackData.GetMaterial() ;
|
||||
G4int i;
|
||||
G4double energyOfSR = -1.0;
|
||||
|
||||
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
|
||||
const G4DynamicParticle* aDynamicParticle = trackData.GetDynamicParticle();
|
||||
|
||||
G4double gamma = aDynamicParticle->GetTotalEnergy()/
|
||||
(aDynamicParticle->GetMass() ) ;
|
||||
G4double gamma =
|
||||
aDynamicParticle->GetTotalEnergy() / (aDynamicParticle->GetMass());
|
||||
|
||||
G4double particleCharge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr ;
|
||||
G4ThreeVector FieldValue;
|
||||
const G4Field* pField = nullptr;
|
||||
|
||||
G4FieldManager* fieldMgr=nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
G4FieldManager* fieldMgr = nullptr;
|
||||
G4bool fieldExertsForce = false;
|
||||
|
||||
if( (particleCharge != 0.0) )
|
||||
if((particleCharge != 0.0))
|
||||
{
|
||||
fieldMgr = fFieldPropagator->FindAndSetFieldManager( trackData.GetVolume() );
|
||||
if ( fieldMgr != nullptr )
|
||||
fieldMgr = fFieldPropagator->FindAndSetFieldManager(trackData.GetVolume());
|
||||
if(fieldMgr != nullptr)
|
||||
{
|
||||
// If the field manager has no field, there is no field !
|
||||
|
||||
fieldExertsForce = ( fieldMgr->GetDetectorField() != 0 );
|
||||
fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
|
||||
}
|
||||
}
|
||||
if ( fieldExertsForce )
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
G4double globPosVec[3], FieldValueVec[3];
|
||||
if(fieldExertsForce)
|
||||
{
|
||||
pField = fieldMgr->GetDetectorField();
|
||||
G4ThreeVector globPosition = trackData.GetPosition();
|
||||
G4double globPosVec[3], FieldValueVec[3];
|
||||
|
||||
globPosVec[0] = globPosition.x();
|
||||
globPosVec[1] = globPosition.y();
|
||||
globPosVec[2] = globPosition.z();
|
||||
|
||||
pField->GetFieldValue( globPosVec, FieldValueVec );
|
||||
FieldValue = G4ThreeVector( FieldValueVec[0],
|
||||
FieldValueVec[1],
|
||||
FieldValueVec[2] );
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum) ;
|
||||
pField->GetFieldValue(globPosVec, FieldValueVec);
|
||||
FieldValue =
|
||||
G4ThreeVector(FieldValueVec[0], FieldValueVec[1], FieldValueVec[2]);
|
||||
|
||||
G4ThreeVector unitMomentum = aDynamicParticle->GetMomentumDirection();
|
||||
G4ThreeVector unitMcrossB = FieldValue.cross(unitMomentum);
|
||||
G4double perpB = unitMcrossB.mag();
|
||||
if( perpB > 0.0 )
|
||||
if(perpB > 0.0)
|
||||
{
|
||||
// M-C of synchrotron photon energy
|
||||
|
||||
G4double random = G4UniformRand() ;
|
||||
for(i=0;i<200;i++)
|
||||
G4double random = G4UniformRand();
|
||||
for(i = 0; i < 200; ++i)
|
||||
{
|
||||
if(random >= fIntegralProbabilityOfSR[i]) break ;
|
||||
if(random >= fIntegralProbabilityOfSR[i])
|
||||
break;
|
||||
}
|
||||
energyOfSR = 0.0001*i*i*fEnergyConst*gamma*gamma*perpB ;
|
||||
energyOfSR = 0.0001 * i * i * fEnergyConst * gamma * gamma * perpB;
|
||||
|
||||
// check against insufficient energy
|
||||
|
||||
if(energyOfSR <= 0.0)
|
||||
{
|
||||
return -1.0 ;
|
||||
return -1.0;
|
||||
}
|
||||
//G4double kineticEnergy = aDynamicParticle->GetKineticEnergy();
|
||||
//G4ParticleMomentum
|
||||
//particleDirection = aDynamicParticle->GetMomentumDirection();
|
||||
|
||||
// Gamma production cut in this material
|
||||
//G4double
|
||||
//gammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
|
||||
// SR photon has energy more than the current material cut
|
||||
// M-C of its direction
|
||||
|
||||
//G4double Teta = G4UniformRand()/gamma ; // Very roughly
|
||||
|
||||
//G4double Phi = twopi * G4UniformRand() ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1.0 ;
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
return energyOfSR ;
|
||||
}
|
||||
return energyOfSR;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetRandomEnergySR(G4double gamma, G4double perpB)
|
||||
G4double G4SynchrotronRadiationInMat::GetRandomEnergySR(G4double gamma,
|
||||
G4double perpB)
|
||||
{
|
||||
G4int i, iMax;
|
||||
G4int i;
|
||||
static constexpr G4int iMax = 200;
|
||||
G4double energySR, random, position;
|
||||
|
||||
iMax = 200;
|
||||
random = G4UniformRand();
|
||||
|
||||
for( i = 0; i < iMax; i++ )
|
||||
for(i = 0; i < iMax; ++i)
|
||||
{
|
||||
if( random >= fIntegralProbabilityOfSR[i] ) break;
|
||||
if(random >= fIntegralProbabilityOfSR[i])
|
||||
break;
|
||||
}
|
||||
if(i <= 0 ) position = G4UniformRand(); // 0.
|
||||
else if( i>= iMax) position = G4double(iMax);
|
||||
else position = i + G4UniformRand(); // -1
|
||||
//
|
||||
// it was in initial implementation:
|
||||
// energyOfSR = 0.0001*i*i*fEnergyConst*gamma*gamma*perpB ;
|
||||
if(i <= 0)
|
||||
position = G4UniformRand();
|
||||
else if(i >= iMax)
|
||||
position = G4double(iMax);
|
||||
else
|
||||
position = i + G4UniformRand();
|
||||
|
||||
energySR = 0.0001*position*position*fEnergyConst*gamma*gamma*perpB;
|
||||
energySR =
|
||||
0.0001 * position * position * fEnergyConst * gamma * gamma * perpB;
|
||||
|
||||
if( energySR < 0. ) energySR = 0.;
|
||||
if(energySR < 0.)
|
||||
energySR = 0.;
|
||||
|
||||
return energySR;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// return
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt( G4double t)
|
||||
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt(G4double t)
|
||||
{
|
||||
G4double result, hypCos2, hypCos=std::cosh(t);
|
||||
G4double result, hypCos2, hypCos = std::cosh(t);
|
||||
|
||||
hypCos2 = hypCos*hypCos;
|
||||
result = std::cosh(5.*t/3.)*std::exp(t-fKsi*hypCos); // fKsi > 0. !
|
||||
hypCos2 = hypCos * hypCos;
|
||||
result = std::cosh(5. * t / 3.) * std::exp(t - fKsi * hypCos); // fKsi > 0. !
|
||||
result /= hypCos2;
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// return the probability to emit SR photon with relative energy
|
||||
// energy/energy_c >= ksi
|
||||
// for ksi <= 0. P = 1., however the method works for ksi > 0 only!
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetIntProbSR( G4double ksi)
|
||||
G4double G4SynchrotronRadiationInMat::GetIntProbSR(G4double ksi)
|
||||
{
|
||||
if (ksi <= 0.) return 1.0;
|
||||
fKsi = ksi; // should be > 0. !
|
||||
if(ksi <= 0.)
|
||||
return 1.0;
|
||||
fKsi = ksi; // should be > 0. !
|
||||
G4int n;
|
||||
G4double result, a;
|
||||
|
||||
a = fAlpha; // always = 0.
|
||||
n = fRootNumber; // around default = 80
|
||||
a = fAlpha; // always = 0.
|
||||
n = fRootNumber; // around default = 80
|
||||
|
||||
G4Integrator<G4SynchrotronRadiationInMat, G4double(G4SynchrotronRadiationInMat::*)(G4double)> integral;
|
||||
G4Integrator<G4SynchrotronRadiationInMat,
|
||||
G4double (G4SynchrotronRadiationInMat::*)(G4double)>
|
||||
integral;
|
||||
|
||||
result = integral.Laguerre(this,
|
||||
&G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt, a, n);
|
||||
result = integral.Laguerre(
|
||||
this, &G4SynchrotronRadiationInMat::GetProbSpectrumSRforInt, a, n);
|
||||
|
||||
result *= 3./5./pi;
|
||||
result *= 3. / 5. / pi;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// return an auxiliary function for K_5/3 integral representation
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy( G4double t)
|
||||
G4double G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy(G4double t)
|
||||
{
|
||||
G4double result, hypCos=std::cosh(t);
|
||||
|
||||
result = std::cosh(5.*t/3.)*std::exp(t - fKsi*hypCos); // fKsi > 0. !
|
||||
G4double result, hypCos = std::cosh(t);
|
||||
|
||||
result = std::cosh(5. * t / 3.) * std::exp(t - fKsi * hypCos); // fKsi > 0. !
|
||||
result /= hypCos;
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// return the probability to emit SR photon energy with relative energy
|
||||
// energy/energy_c >= ksi
|
||||
// for ksi <= 0. P = 1., however the method works for ksi > 0 only!
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetEnergyProbSR( G4double ksi)
|
||||
G4double G4SynchrotronRadiationInMat::GetEnergyProbSR(G4double ksi)
|
||||
{
|
||||
if (ksi <= 0.) return 1.0;
|
||||
fKsi = ksi; // should be > 0. !
|
||||
if(ksi <= 0.)
|
||||
return 1.0;
|
||||
fKsi = ksi; // should be > 0. !
|
||||
G4int n;
|
||||
G4double result, a;
|
||||
|
||||
a = fAlpha; // always = 0.
|
||||
n = fRootNumber; // around default = 80
|
||||
a = fAlpha; // always = 0.
|
||||
n = fRootNumber; // around default = 80
|
||||
|
||||
G4Integrator<G4SynchrotronRadiationInMat, G4double(G4SynchrotronRadiationInMat::*)(G4double)> integral;
|
||||
G4Integrator<G4SynchrotronRadiationInMat,
|
||||
G4double (G4SynchrotronRadiationInMat::*)(G4double)>
|
||||
integral;
|
||||
|
||||
result = integral.Laguerre(this,
|
||||
&G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy, a, n);
|
||||
result = integral.Laguerre(
|
||||
this, &G4SynchrotronRadiationInMat::GetProbSpectrumSRforEnergy, a, n);
|
||||
|
||||
result *= 9.*std::sqrt(3.)*ksi/8./pi;
|
||||
result *= 9. * std::sqrt(3.) * ksi / 8. / pi;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetIntegrandForAngleK( G4double t)
|
||||
G4double G4SynchrotronRadiationInMat::GetIntegrandForAngleK(G4double t)
|
||||
{
|
||||
G4double result, hypCos=std::cosh(t);
|
||||
|
||||
result = std::cosh(fOrderAngleK*t)*std::exp(t - fEta*hypCos); // fEta > 0. !
|
||||
G4double result, hypCos = std::cosh(t);
|
||||
|
||||
result =
|
||||
std::cosh(fOrderAngleK * t) * std::exp(t - fEta * hypCos); // fEta > 0. !
|
||||
result /= hypCos;
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Return K 1/3 or 2/3 for angular distribution
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetAngleK( G4double eta)
|
||||
G4double G4SynchrotronRadiationInMat::GetAngleK(G4double eta)
|
||||
{
|
||||
fEta = eta; // should be > 0. !
|
||||
fEta = eta; // should be > 0. !
|
||||
G4int n;
|
||||
G4double result, a;
|
||||
|
||||
a = fAlpha; // always = 0.
|
||||
n = fRootNumber; // around default = 80
|
||||
a = fAlpha; // always = 0.
|
||||
n = fRootNumber; // around default = 80
|
||||
|
||||
G4Integrator<G4SynchrotronRadiationInMat, G4double(G4SynchrotronRadiationInMat::*)(G4double)> integral;
|
||||
G4Integrator<G4SynchrotronRadiationInMat,
|
||||
G4double (G4SynchrotronRadiationInMat::*)(G4double)>
|
||||
integral;
|
||||
|
||||
result = integral.Laguerre(this,
|
||||
&G4SynchrotronRadiationInMat::GetIntegrandForAngleK, a, n);
|
||||
result = integral.Laguerre(
|
||||
this, &G4SynchrotronRadiationInMat::GetIntegrandForAngleK, a, n);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Relative angle diff distribution for given fKsi, which is set externally
|
||||
|
||||
G4double G4SynchrotronRadiationInMat::GetAngleNumberAtGammaKsi( G4double gpsi)
|
||||
G4double G4SynchrotronRadiationInMat::GetAngleNumberAtGammaKsi(G4double gpsi)
|
||||
{
|
||||
G4double result, funK, funK2, gpsi2 = gpsi*gpsi;
|
||||
G4double result, funK, funK2, gpsi2 = gpsi * gpsi;
|
||||
|
||||
fPsiGamma = gpsi;
|
||||
fEta = 0.5*fKsi*(1. + gpsi2)*std::sqrt(1. + gpsi2);
|
||||
|
||||
fOrderAngleK = 1./3.;
|
||||
funK = GetAngleK(fEta);
|
||||
funK2 = funK*funK;
|
||||
fPsiGamma = gpsi;
|
||||
fEta = 0.5 * fKsi * (1. + gpsi2) * std::sqrt(1. + gpsi2);
|
||||
|
||||
result = gpsi2*funK2/(1. + gpsi2);
|
||||
fOrderAngleK = 1. / 3.;
|
||||
funK = GetAngleK(fEta);
|
||||
funK2 = funK * funK;
|
||||
|
||||
fOrderAngleK = 2./3.;
|
||||
funK = GetAngleK(fEta);
|
||||
funK2 = funK*funK;
|
||||
result = gpsi2 * funK2 / (1. + gpsi2);
|
||||
|
||||
fOrderAngleK = 2. / 3.;
|
||||
funK = GetAngleK(fEta);
|
||||
funK2 = funK * funK;
|
||||
|
||||
result += funK2;
|
||||
result *= (1. + gpsi2) * fKsi;
|
||||
|
||||
result += funK2;
|
||||
result *= (1. + gpsi2)*fKsi;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////// end of G4SynchrotronRadiationInMat.cc
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// G4TransitionRadiation class -- implementation file
|
||||
|
||||
// GEANT 4 class implementation file --- Copyright CERN 1995
|
||||
// CERN Geneva Switzerland
|
||||
|
||||
// For information related to this code, please, contact
|
||||
// CERN, CN Division, ASD Group
|
||||
@@ -36,195 +34,174 @@
|
||||
// 2nd version 16.12.97 V. Grichine
|
||||
// 3rd version 28.07.05, P.Gumplinger add G4ProcessType to constructor
|
||||
|
||||
|
||||
#include <cmath>
|
||||
//#include <cmath>
|
||||
|
||||
#include "G4TransitionRadiation.hh"
|
||||
#include "G4Material.hh"
|
||||
|
||||
#include "G4EmProcessSubType.hh"
|
||||
|
||||
// Local constants
|
||||
|
||||
const G4int G4TransitionRadiation::fSympsonNumber = 100 ;
|
||||
const G4int G4TransitionRadiation::fGammaNumber = 15 ;
|
||||
const G4int G4TransitionRadiation::fPointNumber = 100 ;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor for selected couple of materials
|
||||
//
|
||||
|
||||
G4TransitionRadiation::
|
||||
G4TransitionRadiation( const G4String& processName, G4ProcessType type )
|
||||
G4TransitionRadiation::G4TransitionRadiation(const G4String& processName,
|
||||
G4ProcessType type)
|
||||
: G4VDiscreteProcess(processName, type)
|
||||
{
|
||||
SetProcessSubType(fTransitionRadiation);
|
||||
fMatIndex1 = fMatIndex2 = 0;
|
||||
|
||||
fGamma = fEnergy = fVarAngle = fMinEnergy = fMaxEnergy = fMaxTheta = fSigma1 = fSigma2 = 0.0;
|
||||
fGamma = fEnergy = fVarAngle = fMinEnergy = fMaxEnergy = fMaxTheta = 0.0;
|
||||
fSigma1 = fSigma2 = 0.0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Destructor
|
||||
//
|
||||
G4TransitionRadiation::~G4TransitionRadiation() {}
|
||||
|
||||
G4TransitionRadiation::~G4TransitionRadiation()
|
||||
{}
|
||||
|
||||
G4bool
|
||||
G4TransitionRadiation::IsApplicable(const G4ParticleDefinition& aParticleType)
|
||||
void G4TransitionRadiation::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
return ( aParticleType.GetPDGCharge() != 0.0 );
|
||||
out << "Base class for simulation of x-ray transition radiation.\n";
|
||||
}
|
||||
|
||||
G4double G4TransitionRadiation::GetMeanFreePath(const G4Track&,
|
||||
G4double,
|
||||
G4ForceCondition* condition)
|
||||
G4bool G4TransitionRadiation::IsApplicable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
return (aParticleType.GetPDGCharge() != 0.0);
|
||||
}
|
||||
|
||||
G4double G4TransitionRadiation::GetMeanFreePath(const G4Track&, G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
*condition = Forced;
|
||||
return DBL_MAX; // so TR doesn't limit mean free path
|
||||
return DBL_MAX; // so TR doesn't limit mean free path
|
||||
}
|
||||
|
||||
G4VParticleChange* G4TransitionRadiation::PostStepDoIt(const G4Track&,
|
||||
const G4Step&)
|
||||
const G4Step&)
|
||||
{
|
||||
ClearNumberOfInteractionLengthLeft();
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Sympson integral of TR spectral-angle density over energy between
|
||||
// the limits energy 1 and energy2 at fixed varAngle = 1 - std::cos(Theta)
|
||||
|
||||
G4double
|
||||
G4TransitionRadiation::IntegralOverEnergy( G4double energy1,
|
||||
G4double energy2,
|
||||
G4double varAngle ) const
|
||||
G4double G4TransitionRadiation::IntegralOverEnergy(G4double energy1,
|
||||
G4double energy2,
|
||||
G4double varAngle) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
|
||||
h = 0.5*(energy2 - energy1)/fSympsonNumber ;
|
||||
for(i=1;i<fSympsonNumber;i++)
|
||||
G4int i;
|
||||
G4double h, sumEven = 0.0, sumOdd = 0.0;
|
||||
h = 0.5 * (energy2 - energy1) / fSympsonNumber;
|
||||
for(i = 1; i < fSympsonNumber; i++)
|
||||
{
|
||||
sumEven += SpectralAngleTRdensity(energy1 + 2*i*h,varAngle) ;
|
||||
sumOdd += SpectralAngleTRdensity(energy1 + (2*i - 1)*h,varAngle) ;
|
||||
sumEven += SpectralAngleTRdensity(energy1 + 2 * i * h, varAngle);
|
||||
sumOdd += SpectralAngleTRdensity(energy1 + (2 * i - 1) * h, varAngle);
|
||||
}
|
||||
sumOdd += SpectralAngleTRdensity(energy1 + (2*fSympsonNumber - 1)*h,varAngle) ;
|
||||
return h*( SpectralAngleTRdensity(energy1,varAngle)
|
||||
+ SpectralAngleTRdensity(energy2,varAngle)
|
||||
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
|
||||
sumOdd +=
|
||||
SpectralAngleTRdensity(energy1 + (2 * fSympsonNumber - 1) * h, varAngle);
|
||||
return h *
|
||||
(SpectralAngleTRdensity(energy1, varAngle) +
|
||||
SpectralAngleTRdensity(energy2, varAngle) + 4.0 * sumOdd +
|
||||
2.0 * sumEven) /
|
||||
3.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Sympson integral of TR spectral-angle density over energy between
|
||||
// the limits varAngle1 and varAngle2 at fixed energy
|
||||
|
||||
G4double
|
||||
G4TransitionRadiation::IntegralOverAngle( G4double energy,
|
||||
G4double varAngle1,
|
||||
G4double varAngle2 ) const
|
||||
G4double G4TransitionRadiation::IntegralOverAngle(G4double energy,
|
||||
G4double varAngle1,
|
||||
G4double varAngle2) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
|
||||
h = 0.5*(varAngle2 - varAngle1)/fSympsonNumber ;
|
||||
for(i=1;i<fSympsonNumber;i++)
|
||||
G4int i;
|
||||
G4double h, sumEven = 0.0, sumOdd = 0.0;
|
||||
h = 0.5 * (varAngle2 - varAngle1) / fSympsonNumber;
|
||||
for(i = 1; i < fSympsonNumber; ++i)
|
||||
{
|
||||
sumEven += SpectralAngleTRdensity(energy,varAngle1 + 2*i*h) ;
|
||||
sumOdd += SpectralAngleTRdensity(energy,varAngle1 + (2*i - 1)*h) ;
|
||||
sumEven += SpectralAngleTRdensity(energy, varAngle1 + 2 * i * h);
|
||||
sumOdd += SpectralAngleTRdensity(energy, varAngle1 + (2 * i - 1) * h);
|
||||
}
|
||||
sumOdd += SpectralAngleTRdensity(energy,varAngle1 + (2*fSympsonNumber - 1)*h) ;
|
||||
sumOdd +=
|
||||
SpectralAngleTRdensity(energy, varAngle1 + (2 * fSympsonNumber - 1) * h);
|
||||
|
||||
return h*( SpectralAngleTRdensity(energy,varAngle1)
|
||||
+ SpectralAngleTRdensity(energy,varAngle2)
|
||||
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
|
||||
return h *
|
||||
(SpectralAngleTRdensity(energy, varAngle1) +
|
||||
SpectralAngleTRdensity(energy, varAngle2) + 4.0 * sumOdd +
|
||||
2.0 * sumEven) /
|
||||
3.0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The number of transition radiation photons generated in the
|
||||
// angle interval between varAngle1 and varAngle2
|
||||
//
|
||||
|
||||
G4double G4TransitionRadiation::
|
||||
AngleIntegralDistribution( G4double varAngle1,
|
||||
G4double varAngle2 ) const
|
||||
G4double G4TransitionRadiation::AngleIntegralDistribution(
|
||||
G4double varAngle1, G4double varAngle2) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
|
||||
h = 0.5*(varAngle2 - varAngle1)/fSympsonNumber ;
|
||||
for(i=1;i<fSympsonNumber;i++)
|
||||
G4int i;
|
||||
G4double h, sumEven = 0.0, sumOdd = 0.0;
|
||||
h = 0.5 * (varAngle2 - varAngle1) / fSympsonNumber;
|
||||
for(i = 1; i < fSympsonNumber; ++i)
|
||||
{
|
||||
sumEven += IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy +0.3*(fMaxEnergy-fMinEnergy),
|
||||
varAngle1 + 2*i*h)
|
||||
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy,
|
||||
varAngle1 + 2*i*h);
|
||||
sumOdd += IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
varAngle1 + (2*i - 1)*h)
|
||||
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy,
|
||||
varAngle1 + (2*i - 1)*h) ;
|
||||
sumEven += IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
varAngle1 + 2 * i * h) +
|
||||
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy, varAngle1 + 2 * i * h);
|
||||
sumOdd += IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
varAngle1 + (2 * i - 1) * h) +
|
||||
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy, varAngle1 + (2 * i - 1) * h);
|
||||
}
|
||||
sumOdd += IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
varAngle1 + (2*fSympsonNumber - 1)*h)
|
||||
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy,
|
||||
varAngle1 + (2*fSympsonNumber - 1)*h) ;
|
||||
sumOdd +=
|
||||
IntegralOverEnergy(fMinEnergy, fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
varAngle1 + (2 * fSympsonNumber - 1) * h) +
|
||||
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy), fMaxEnergy,
|
||||
varAngle1 + (2 * fSympsonNumber - 1) * h);
|
||||
|
||||
return h*(IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
varAngle1)
|
||||
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy,
|
||||
varAngle1)
|
||||
+ IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
varAngle2)
|
||||
+ IntegralOverEnergy(fMinEnergy + 0.3*(fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy,
|
||||
varAngle2)
|
||||
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
|
||||
return h *
|
||||
(IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
varAngle1) +
|
||||
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy, varAngle1) +
|
||||
IntegralOverEnergy(fMinEnergy,
|
||||
fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
varAngle2) +
|
||||
IntegralOverEnergy(fMinEnergy + 0.3 * (fMaxEnergy - fMinEnergy),
|
||||
fMaxEnergy, varAngle2) +
|
||||
4.0 * sumOdd + 2.0 * sumEven) /
|
||||
3.0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The number of transition radiation photons, generated in the
|
||||
// energy interval between energy1 and energy2
|
||||
//
|
||||
|
||||
G4double G4TransitionRadiation::
|
||||
EnergyIntegralDistribution( G4double energy1,
|
||||
G4double energy2 ) const
|
||||
G4double G4TransitionRadiation::EnergyIntegralDistribution(
|
||||
G4double energy1, G4double energy2) const
|
||||
{
|
||||
G4int i ;
|
||||
G4double h , sumEven = 0.0 , sumOdd = 0.0 ;
|
||||
h = 0.5*(energy2 - energy1)/fSympsonNumber ;
|
||||
for(i=1;i<fSympsonNumber;i++)
|
||||
G4int i;
|
||||
G4double h, sumEven = 0.0, sumOdd = 0.0;
|
||||
h = 0.5 * (energy2 - energy1) / fSympsonNumber;
|
||||
for(i = 1; i < fSympsonNumber; ++i)
|
||||
{
|
||||
sumEven += IntegralOverAngle(energy1 + 2*i*h,0.0,0.01*fMaxTheta )
|
||||
+ IntegralOverAngle(energy1 + 2*i*h,0.01*fMaxTheta,fMaxTheta);
|
||||
sumOdd += IntegralOverAngle(energy1 + (2*i - 1)*h,0.0,0.01*fMaxTheta)
|
||||
+ IntegralOverAngle(energy1 + (2*i - 1)*h,0.01*fMaxTheta,fMaxTheta) ;
|
||||
sumEven +=
|
||||
IntegralOverAngle(energy1 + 2 * i * h, 0.0, 0.01 * fMaxTheta) +
|
||||
IntegralOverAngle(energy1 + 2 * i * h, 0.01 * fMaxTheta, fMaxTheta);
|
||||
sumOdd +=
|
||||
IntegralOverAngle(energy1 + (2 * i - 1) * h, 0.0, 0.01 * fMaxTheta) +
|
||||
IntegralOverAngle(energy1 + (2 * i - 1) * h, 0.01 * fMaxTheta, fMaxTheta);
|
||||
}
|
||||
sumOdd += IntegralOverAngle(energy1 + (2*fSympsonNumber - 1)*h,
|
||||
0.0,0.01*fMaxTheta)
|
||||
+ IntegralOverAngle(energy1 + (2*fSympsonNumber - 1)*h,
|
||||
0.01*fMaxTheta,fMaxTheta) ;
|
||||
sumOdd += IntegralOverAngle(energy1 + (2 * fSympsonNumber - 1) * h, 0.0,
|
||||
0.01 * fMaxTheta) +
|
||||
IntegralOverAngle(energy1 + (2 * fSympsonNumber - 1) * h,
|
||||
0.01 * fMaxTheta, fMaxTheta);
|
||||
|
||||
return h*(IntegralOverAngle(energy1,0.0,0.01*fMaxTheta)
|
||||
+ IntegralOverAngle(energy1,0.01*fMaxTheta,fMaxTheta)
|
||||
+ IntegralOverAngle(energy2,0.0,0.01*fMaxTheta)
|
||||
+ IntegralOverAngle(energy2,0.01*fMaxTheta,fMaxTheta)
|
||||
+ 4.0*sumOdd + 2.0*sumEven )/3.0 ;
|
||||
return h *
|
||||
(IntegralOverAngle(energy1, 0.0, 0.01 * fMaxTheta) +
|
||||
IntegralOverAngle(energy1, 0.01 * fMaxTheta, fMaxTheta) +
|
||||
IntegralOverAngle(energy2, 0.0, 0.01 * fMaxTheta) +
|
||||
IntegralOverAngle(energy2, 0.01 * fMaxTheta, fMaxTheta) +
|
||||
4.0 * sumOdd + 2.0 * sumEven) /
|
||||
3.0;
|
||||
}
|
||||
|
||||
// end of G4TransitionRadiation implementation file --------------------------
|
||||
|
||||
@@ -23,215 +23,128 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "G4TransparentRegXTRadiator.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4TransparentRegXTRadiator::G4TransparentRegXTRadiator(G4LogicalVolume *anEnvelope,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
|
||||
G4TransparentRegXTRadiator::G4TransparentRegXTRadiator(
|
||||
G4LogicalVolume* anEnvelope, G4Material* foilMat, G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n, const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
|
||||
{
|
||||
if(verboseLevel > 0)
|
||||
G4cout<<"Regular transparent X-ray TR radiator EM process is called"<<G4endl;
|
||||
G4cout << "Regular transparent X-ray TR radiator EM process is called"
|
||||
<< G4endl;
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
|
||||
fAlphaPlate = 10000;
|
||||
fAlphaGas = 1000;
|
||||
|
||||
// BuildTable();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4TransparentRegXTRadiator::~G4TransparentRegXTRadiator() {}
|
||||
|
||||
G4TransparentRegXTRadiator::~G4TransparentRegXTRadiator()
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void G4TransparentRegXTRadiator::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
;
|
||||
out << "Simulation of forward X-ray transition radiation generated by\n"
|
||||
"relativistic charged particles crossing the interface between\n"
|
||||
"two materials.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4TransparentRegXTRadiator::SpectralXTRdEdx(G4double energy)
|
||||
{
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k /*, aMa, bMb ,sigma*/;
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
|
||||
G4int k, kMax, kMin;
|
||||
|
||||
//aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
|
||||
//bMb = fGasThick*GetGasLinearPhotoAbs(energy);
|
||||
//sigma = aMa + bMb;
|
||||
|
||||
cofPHC = 4*pi*hbarc;
|
||||
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
|
||||
cof1 = fPlateThick*tmp;
|
||||
cof2 = fGasThick*tmp;
|
||||
cofPHC = 4. * pi * hbarc;
|
||||
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
|
||||
cof1 = fPlateThick * tmp;
|
||||
cof2 = fGasThick * tmp;
|
||||
|
||||
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
|
||||
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
|
||||
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
|
||||
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
|
||||
cofMin /= cofPHC;
|
||||
|
||||
theta2 = cofPHC/(energy*(fPlateThick + fGasThick));
|
||||
|
||||
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
|
||||
// else kMin = 1;
|
||||
|
||||
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
|
||||
|
||||
kMin = G4int(cofMin);
|
||||
if (cofMin > kMin) kMin++;
|
||||
if(cofMin > kMin)
|
||||
kMin++;
|
||||
|
||||
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
|
||||
// tmp /= cofPHC;
|
||||
// kMax = G4int(tmp);
|
||||
// if(kMax < 0) kMax = 0;
|
||||
// kMax += kMin;
|
||||
|
||||
|
||||
kMax = kMin + 49; // 19; // kMin + G4int(tmp);
|
||||
|
||||
// tmp /= fGamma;
|
||||
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
|
||||
kMax = kMin + 49;
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout<<cof1<<" "<<cof2<<" "<<cofMin<<G4endl;
|
||||
G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
|
||||
}
|
||||
for( k = kMin; k <= kMax; k++ )
|
||||
{
|
||||
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
|
||||
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
|
||||
// tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
if( k == kMin && kMin == G4int(cofMin) )
|
||||
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
|
||||
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
|
||||
}
|
||||
for(k = kMin; k <= kMax; ++k)
|
||||
{
|
||||
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
|
||||
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
|
||||
if(k == kMin && kMin == G4int(cofMin))
|
||||
{
|
||||
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum +=
|
||||
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
theta2k = std::sqrt(theta2*std::abs(k-cofMin));
|
||||
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
// G4cout<<"k = "<<k<<"; sqrt(theta2k) = "<<theta2k<<"; tmp = "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
|
||||
// <<"; sum = "<<sum<<G4endl;
|
||||
G4cout<<k<<" "<<theta2k<<" "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
|
||||
<<" "<<sum<<G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << k << " " << theta2k << " "
|
||||
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
|
||||
<< " " << sum << G4endl;
|
||||
}
|
||||
}
|
||||
result = 4.*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
|
||||
// result *= ( 1 - std::exp(-0.5*fPlateNumber*sigma) )/( 1 - std::exp(-0.5*sigma) );
|
||||
// fPlateNumber;
|
||||
result *= fPlateNumber; // *std::exp(-0.5*fPlateNumber*sigma);
|
||||
// +1-std::exp(-0.5*fPlateNumber*sigma);
|
||||
/*
|
||||
fEnergy = energy;
|
||||
// G4Integrator<G4VXTRenergyLoss,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
|
||||
G4Integrator<G4TransparentRegXTRadiator,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
|
||||
|
||||
tmp = integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.0,0.3*fMaxThetaTR) +
|
||||
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.3*fMaxThetaTR,0.6*fMaxThetaTR) +
|
||||
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.6*fMaxThetaTR,fMaxThetaTR) ;
|
||||
result += tmp;
|
||||
*/
|
||||
result = 4. * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
|
||||
result *= fPlateNumber;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Approximation for radiator interference factor for the case of
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in coresponding material.
|
||||
|
||||
G4double
|
||||
G4TransparentRegXTRadiator::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in corresponding material.
|
||||
G4double G4TransparentRegXTRadiator::GetStackFactor(G4double energy,
|
||||
G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
/*
|
||||
G4double result, Za, Zb, Ma, Mb, sigma;
|
||||
|
||||
Za = GetPlateFormationZone(energy,gamma,varAngle);
|
||||
Zb = GetGasFormationZone(energy,gamma,varAngle);
|
||||
Ma = GetPlateLinearPhotoAbs(energy);
|
||||
Mb = GetGasLinearPhotoAbs(energy);
|
||||
sigma = Ma*fPlateThick + Mb*fGasThick;
|
||||
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, D, sigma;
|
||||
|
||||
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate);
|
||||
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas);
|
||||
aZa = fPlateThick / GetPlateFormationZone(energy, gamma, varAngle);
|
||||
bZb = fGasThick / GetGasFormationZone(energy, gamma, varAngle);
|
||||
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
|
||||
sigma = aMa * fPlateThick + bMb * fGasThick;
|
||||
Qa = std::exp(-0.5 * aMa);
|
||||
Qb = std::exp(-0.5 * bMb);
|
||||
Q = Qa * Qb;
|
||||
|
||||
G4complex Ha = std::pow(Ca,-fAlphaPlate);
|
||||
G4complex Hb = std::pow(Cb,-fAlphaGas);
|
||||
G4complex H = Ha*Hb;
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
|
||||
* G4double(fPlateNumber) ;
|
||||
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
|
||||
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) ;
|
||||
// *(1.0 - std::pow(H,fPlateNumber)) ;
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
// G4complex R = F2*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
result = 2.0*std::real(R);
|
||||
return result;
|
||||
*/
|
||||
// numerically unstable result
|
||||
|
||||
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, D, sigma;
|
||||
|
||||
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle);
|
||||
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle);
|
||||
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
|
||||
sigma = aMa*fPlateThick + bMb*fGasThick;
|
||||
Qa = std::exp(-0.5*aMa);
|
||||
Qb = std::exp(-0.5*bMb);
|
||||
Q = Qa*Qb;
|
||||
|
||||
G4complex Ha( Qa*std::cos(aZa), -Qa*std::sin(aZa) );
|
||||
G4complex Hb( Qb*std::cos(bZb), -Qb*std::sin(bZb) );
|
||||
G4complex H = Ha*Hb;
|
||||
G4complex Ha(Qa * std::cos(aZa), -Qa * std::sin(aZa));
|
||||
G4complex Hb(Qb * std::cos(bZb), -Qb * std::sin(bZb));
|
||||
G4complex H = Ha * Hb;
|
||||
G4complex Hs = conj(H);
|
||||
D = 1.0 /( (1 - Q)*(1 - Q) +
|
||||
4*Q*std::sin(0.5*(aZa + bZb))*std::sin(0.5*(aZa + bZb)) );
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb)*(1.0 - Hs)
|
||||
* G4double(fPlateNumber)*D;
|
||||
G4complex F2 = (1.0 - Ha)*(1.0 - Ha)*Hb*(1.0 - Hs)*(1.0 - Hs)
|
||||
// * (1.0 - std::pow(H,fPlateNumber)) * D*D;
|
||||
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) * D*D;
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
result = 2.0*std::real(R);
|
||||
return result;
|
||||
|
||||
D = 1.0 / ((1 - Q) * (1 - Q) +
|
||||
4 * Q * std::sin(0.5 * (aZa + bZb)) * std::sin(0.5 * (aZa + bZb)));
|
||||
G4complex F1 =
|
||||
(1.0 - Ha) * (1.0 - Hb) * (1.0 - Hs) * G4double(fPlateNumber) * D;
|
||||
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb * (1.0 - Hs) * (1.0 - Hs) *
|
||||
(1.0 - std::exp(-0.5 * fPlateNumber * sigma)) * D * D;
|
||||
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
result = 2.0 * std::real(R);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,36 +23,32 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4VTransitionRadiation class -- implementation file
|
||||
|
||||
// GEANT 4 class implementation file --- Copyright CERN 1995
|
||||
// CERN Geneva Switzerland
|
||||
|
||||
// History:
|
||||
// 29.02.04 V.Ivanchenko create
|
||||
// 28.07.05, P.Gumplinger add G4ProcessType to constructor
|
||||
|
||||
#include "G4VTransitionRadiation.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VTRModel.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
#include "G4EmProcessSubType.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4VTRModel.hh"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4VTransitionRadiation::G4VTransitionRadiation( const G4String& processName,
|
||||
G4ProcessType type )
|
||||
: G4VDiscreteProcess(processName, type),
|
||||
region(nullptr),
|
||||
model(nullptr),
|
||||
nSteps(0),
|
||||
gammaMin(100.),
|
||||
cosDThetaMax(std::cos(0.1))
|
||||
G4VTransitionRadiation::G4VTransitionRadiation(const G4String& processName,
|
||||
G4ProcessType type)
|
||||
: G4VDiscreteProcess(processName, type)
|
||||
, region(nullptr)
|
||||
, model(nullptr)
|
||||
, gammaMin(100.)
|
||||
, cosDThetaMax(std::cos(0.1))
|
||||
, nSteps(0)
|
||||
{
|
||||
SetProcessSubType(fTransitionRadiation);
|
||||
Clear();
|
||||
@@ -61,15 +57,21 @@ G4VTransitionRadiation::G4VTransitionRadiation( const G4String& processName,
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4VTransitionRadiation::~G4VTransitionRadiation()
|
||||
{
|
||||
Clear();
|
||||
theManager->DeRegister(this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void G4VTransitionRadiation::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
out << "Generic process of transition radiation.\n";
|
||||
|
||||
if(model)
|
||||
model->PrintInfo();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void G4VTransitionRadiation::Clear()
|
||||
{
|
||||
materials.clear();
|
||||
@@ -79,112 +81,102 @@ void G4VTransitionRadiation::Clear()
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4VParticleChange* G4VTransitionRadiation::PostStepDoIt(
|
||||
const G4Track& track,
|
||||
const G4Step& step)
|
||||
G4VParticleChange* G4VTransitionRadiation::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
|
||||
// Fill temporary vectors
|
||||
|
||||
const G4Material* material = track.GetMaterial();
|
||||
G4double length = step.GetStepLength();
|
||||
G4ThreeVector direction = track.GetMomentumDirection();
|
||||
|
||||
if(nSteps == 0) {
|
||||
G4double length = step.GetStepLength();
|
||||
G4ThreeVector direction = track.GetMomentumDirection();
|
||||
|
||||
if(nSteps == 0)
|
||||
{
|
||||
nSteps = 1;
|
||||
materials.push_back(material);
|
||||
steps.push_back(length);
|
||||
const G4StepPoint* point = step.GetPreStepPoint();
|
||||
startingPosition = point->GetPosition();
|
||||
startingDirection = point->GetMomentumDirection();
|
||||
G4bool valid = true;
|
||||
startingPosition = point->GetPosition();
|
||||
startingDirection = point->GetMomentumDirection();
|
||||
G4bool valid = true;
|
||||
G4ThreeVector n = G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking()->GetLocalExitNormal(&valid);
|
||||
if(valid) normals.push_back(n);
|
||||
else normals.push_back(direction);
|
||||
|
||||
} else {
|
||||
|
||||
if(material == materials[nSteps-1]) {
|
||||
steps[nSteps-1] += length;
|
||||
} else {
|
||||
nSteps++;
|
||||
->GetNavigatorForTracking()
|
||||
->GetLocalExitNormal(&valid);
|
||||
if(valid)
|
||||
normals.push_back(n);
|
||||
else
|
||||
normals.push_back(direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(material == materials[nSteps - 1])
|
||||
{
|
||||
steps[nSteps - 1] += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
++nSteps;
|
||||
materials.push_back(material);
|
||||
steps.push_back(length);
|
||||
G4bool valid = true;
|
||||
G4bool valid = true;
|
||||
G4ThreeVector n = G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking()->GetLocalExitNormal(&valid);
|
||||
if(valid) normals.push_back(n);
|
||||
else normals.push_back(direction);
|
||||
->GetNavigatorForTracking()
|
||||
->GetLocalExitNormal(&valid);
|
||||
if(valid)
|
||||
normals.push_back(n);
|
||||
else
|
||||
normals.push_back(direction);
|
||||
}
|
||||
}
|
||||
|
||||
// Check POstStepPoint condition
|
||||
|
||||
// Check PostStepPoint condition
|
||||
if(track.GetTrackStatus() == fStopAndKill ||
|
||||
track.GetVolume()->GetLogicalVolume()->GetRegion() != region ||
|
||||
startingDirection.x()*direction.x() +
|
||||
startingDirection.y()*direction.y() +
|
||||
startingDirection.z()*direction.z() < cosDThetaMax)
|
||||
startingDirection.x() * direction.x() +
|
||||
startingDirection.y() * direction.y() +
|
||||
startingDirection.z() * direction.z() <
|
||||
cosDThetaMax)
|
||||
{
|
||||
if(model) {
|
||||
model->GenerateSecondaries(*pParticleChange, materials, steps,
|
||||
normals, startingPosition, track);
|
||||
}
|
||||
Clear();
|
||||
if(model)
|
||||
{
|
||||
model->GenerateSecondaries(*pParticleChange, materials, steps, normals,
|
||||
startingPosition, track);
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
return pParticleChange;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4bool G4VTransitionRadiation::IsApplicable(
|
||||
const G4ParticleDefinition& aParticle)
|
||||
const G4ParticleDefinition& aParticle)
|
||||
{
|
||||
return ( aParticle.GetPDGCharge() != 0.0 );
|
||||
return (aParticle.GetPDGCharge() != 0.0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void G4VTransitionRadiation::SetRegion(const G4Region* reg)
|
||||
{
|
||||
region = reg;
|
||||
}
|
||||
void G4VTransitionRadiation::SetRegion(const G4Region* reg) { region = reg; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4VTransitionRadiation::SetModel(G4VTRModel* mod)
|
||||
{
|
||||
model = mod;
|
||||
}
|
||||
void G4VTransitionRadiation::SetModel(G4VTRModel* mod) { model = mod; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4VTransitionRadiation::PrintInfoDefinition()
|
||||
G4double G4VTransitionRadiation::GetMeanFreePath(const G4Track& track, G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
if(model) model->PrintInfo();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4VTransitionRadiation::GetMeanFreePath(
|
||||
const G4Track& track, G4double,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
if(nSteps > 0) {
|
||||
if(nSteps > 0)
|
||||
{
|
||||
*condition = StronglyForced;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*condition = NotForced;
|
||||
if(track.GetKineticEnergy()/track.GetDefinition()->GetPDGMass() + 1.0 > gammaMin &&
|
||||
track.GetVolume()->GetLogicalVolume()->GetRegion() == region) {
|
||||
*condition = StronglyForced;
|
||||
if(track.GetKineticEnergy() / track.GetDefinition()->GetPDGMass() + 1.0 >
|
||||
gammaMin &&
|
||||
track.GetVolume()->GetLogicalVolume()->GetRegion() == region)
|
||||
{
|
||||
*condition = StronglyForced;
|
||||
}
|
||||
}
|
||||
return DBL_MAX; // so TR doesn't limit mean free path
|
||||
return DBL_MAX; // so TR doesn't limit mean free path
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,113 +23,84 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "G4XTRGammaRadModel.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4XTRGammaRadModel::G4XTRGammaRadModel(G4LogicalVolume* anEnvelope,
|
||||
G4double alphaPlate,
|
||||
G4double alphaGas,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
|
||||
G4double alphaPlate, G4double alphaGas,
|
||||
G4Material* foilMat, G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
|
||||
{
|
||||
G4cout<<"Gamma distributed X-ray TR radiator model is called"<<G4endl ;
|
||||
G4cout << "Gamma distributed X-ray TR radiator model is called" << G4endl;
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
|
||||
fAlphaPlate = alphaPlate ;
|
||||
fAlphaGas = alphaGas ;
|
||||
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
|
||||
fAlphaPlate = alphaPlate;
|
||||
fAlphaGas = alphaGas;
|
||||
G4cout << "fAlphaPlate = " << fAlphaPlate << " ; fAlphaGas = " << fAlphaGas
|
||||
<< G4endl;
|
||||
fExitFlux = true;
|
||||
// BuildTable() ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4XTRGammaRadModel::~G4XTRGammaRadModel() {}
|
||||
|
||||
G4XTRGammaRadModel::~G4XTRGammaRadModel()
|
||||
void G4XTRGammaRadModel::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
;
|
||||
out << "Rough model describing X-ray transition radiation. Thicknesses of "
|
||||
"plates\n"
|
||||
"and gas gaps are distributed according to gamma distributions.\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Rough approximation for radiator interference factor for the case of
|
||||
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
|
||||
// according to exponent. The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
|
||||
// according to exponent. The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in coresponding material.
|
||||
|
||||
G4double
|
||||
G4XTRGammaRadModel::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
G4double G4XTRGammaRadModel::GetStackFactor(G4double energy, G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb ;
|
||||
|
||||
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
|
||||
Zb = GetGasFormationZone(energy,gamma,varAngle) ;
|
||||
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb;
|
||||
|
||||
Ma = GetPlateLinearPhotoAbs(energy) ;
|
||||
Mb = GetGasLinearPhotoAbs(energy) ;
|
||||
Za = GetPlateFormationZone(energy, gamma, varAngle);
|
||||
Zb = GetGasFormationZone(energy, gamma, varAngle);
|
||||
|
||||
Qa = ( 1.0 + fPlateThick*Ma/fAlphaPlate ) ;
|
||||
Qa = std::pow(Qa,-fAlphaPlate) ;
|
||||
Qb = ( 1.0 + fGasThick*Mb/fAlphaGas ) ;
|
||||
Qb = std::pow(Qb,-fAlphaGas) ;
|
||||
Q = Qa*Qb ;
|
||||
Ma = GetPlateLinearPhotoAbs(energy);
|
||||
Mb = GetGasLinearPhotoAbs(energy);
|
||||
|
||||
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate) ;
|
||||
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas) ;
|
||||
Qa = (1.0 + fPlateThick * Ma / fAlphaPlate);
|
||||
Qa = std::pow(Qa, -fAlphaPlate);
|
||||
Qb = (1.0 + fGasThick * Mb / fAlphaGas);
|
||||
Qb = std::pow(Qb, -fAlphaGas);
|
||||
Q = Qa * Qb;
|
||||
|
||||
G4complex Ha = std::pow(Ca,-fAlphaPlate) ;
|
||||
G4complex Hb = std::pow(Cb,-fAlphaGas) ;
|
||||
G4complex H = Ha*Hb ;
|
||||
G4complex Ca(1.0 + 0.5 * fPlateThick * Ma / fAlphaPlate,
|
||||
fPlateThick / Za / fAlphaPlate);
|
||||
G4complex Cb(1.0 + 0.5 * fGasThick * Mb / fAlphaGas,
|
||||
fGasThick / Zb / fAlphaGas);
|
||||
|
||||
G4complex F1 = ( 0.5*(1+Qa)*(1.0+H) - Ha - Qa*Hb )/(1.0-H) ;
|
||||
G4complex Ha = std::pow(Ca, -fAlphaPlate);
|
||||
G4complex Hb = std::pow(Cb, -fAlphaGas);
|
||||
G4complex H = Ha * Hb;
|
||||
|
||||
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb/(1.0-H)/(Q-H) ;
|
||||
G4complex F1 = (0.5 * (1 + Qa) * (1.0 + H) - Ha - Qa * Hb) / (1.0 - H);
|
||||
|
||||
F2 *= std::pow(Q,G4double(fPlateNumber)) - std::pow(H,fPlateNumber) ;
|
||||
G4complex F2 = (1.0 - Ha) * (Qa - Ha) * Hb / (1.0 - H) / (Q - H);
|
||||
|
||||
result = ( 1. - std::pow(Q,G4double(fPlateNumber)) )/( 1. - Q ) ;
|
||||
F2 *= std::pow(Q, G4double(fPlateNumber)) - std::pow(H, fPlateNumber);
|
||||
|
||||
G4complex stack = result*F1;
|
||||
stack += F2;
|
||||
stack *= 2.0*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
result = (1. - std::pow(Q, G4double(fPlateNumber))) / (1. - Q);
|
||||
|
||||
result = std::real(stack);
|
||||
G4complex stack = result * F1;
|
||||
stack += F2;
|
||||
stack *= 2.0 * OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
|
||||
// result *= 2.0*std::real(F1);
|
||||
// result += 2.0*std::real(F2);
|
||||
result = std::real(stack);
|
||||
|
||||
return result ;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,216 +23,148 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "G4XTRRegularRadModel.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "G4Gamma.hh"
|
||||
using namespace std;
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4XTRRegularRadModel::G4XTRRegularRadModel(G4LogicalVolume *anEnvelope,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
|
||||
G4XTRRegularRadModel::G4XTRRegularRadModel(G4LogicalVolume* anEnvelope,
|
||||
G4Material* foilMat,
|
||||
G4Material* gasMat, G4double a,
|
||||
G4double b, G4int n,
|
||||
const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
|
||||
{
|
||||
G4cout<<" XTR Regular discrete radiator model is called"<<G4endl ;
|
||||
G4cout << " XTR Regular discrete radiator model is called" << G4endl;
|
||||
|
||||
fExitFlux = true;
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
|
||||
// BuildTable() ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4XTRRegularRadModel::~G4XTRRegularRadModel() {}
|
||||
|
||||
G4XTRRegularRadModel::~G4XTRRegularRadModel()
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void G4XTRRegularRadModel::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
;
|
||||
out << "Describes X-ray transition radiation with thickness of gaps and "
|
||||
"plates\n"
|
||||
"fixed.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4XTRRegularRadModel::SpectralXTRdEdx(G4double energy)
|
||||
{
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC, theta2, theta2k;
|
||||
G4double aMa, bMb ,sigma, dump;
|
||||
static constexpr G4double cofPHC = 4. * pi * hbarc;
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, theta2, theta2k;
|
||||
G4double aMa, bMb, sigma, dump;
|
||||
G4int k, kMax, kMin;
|
||||
|
||||
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
|
||||
sigma = 0.5*(aMa + bMb);
|
||||
dump = std::exp(-fPlateNumber*sigma);
|
||||
if(verboseLevel > 2) G4cout<<" dump = "<<dump<<G4endl;
|
||||
cofPHC = 4*pi*hbarc;
|
||||
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
|
||||
cof1 = fPlateThick*tmp;
|
||||
cof2 = fGasThick*tmp;
|
||||
aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick * GetGasLinearPhotoAbs(energy);
|
||||
sigma = 0.5 * (aMa + bMb);
|
||||
dump = std::exp(-fPlateNumber * sigma);
|
||||
if(verboseLevel > 2)
|
||||
G4cout << " dump = " << dump << G4endl;
|
||||
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
|
||||
cof1 = fPlateThick * tmp;
|
||||
cof2 = fGasThick * tmp;
|
||||
|
||||
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
|
||||
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
|
||||
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
|
||||
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
|
||||
cofMin /= cofPHC;
|
||||
|
||||
theta2 = cofPHC/(energy*(fPlateThick + fGasThick));
|
||||
|
||||
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
|
||||
// else kMin = 1;
|
||||
|
||||
theta2 = cofPHC / (energy * (fPlateThick + fGasThick));
|
||||
|
||||
kMin = G4int(cofMin);
|
||||
if (cofMin > kMin) kMin++;
|
||||
if(cofMin > kMin)
|
||||
kMin++;
|
||||
|
||||
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
|
||||
// tmp /= cofPHC;
|
||||
// kMax = G4int(tmp);
|
||||
// if(kMax < 0) kMax = 0;
|
||||
// kMax += kMin;
|
||||
|
||||
|
||||
kMax = kMin + 49; // 19; // kMin + G4int(tmp);
|
||||
|
||||
// tmp /= fGamma;
|
||||
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
|
||||
kMax = kMin + 49;
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
G4cout<<cof1<<" "<<cof2<<" "<<cofMin<<G4endl;
|
||||
G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
|
||||
}
|
||||
for( k = kMin; k <= kMax; k++ )
|
||||
{
|
||||
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
|
||||
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
|
||||
// tmp = std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
if( k == kMin && kMin == G4int(cofMin) )
|
||||
G4cout << cof1 << " " << cof2 << " " << cofMin << G4endl;
|
||||
G4cout << "kMin = " << kMin << "; kMax = " << kMax << G4endl;
|
||||
}
|
||||
for(k = kMin; k <= kMax; ++k)
|
||||
{
|
||||
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
|
||||
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
|
||||
if(k == kMin && kMin == G4int(cofMin))
|
||||
{
|
||||
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum +=
|
||||
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
theta2k = std::sqrt(theta2*std::abs(k-cofMin));
|
||||
theta2k = std::sqrt(theta2 * std::abs(k - cofMin));
|
||||
|
||||
if(verboseLevel > 2)
|
||||
{
|
||||
// G4cout<<"k = "<<k<<"; sqrt(theta2k) = "<<theta2k<<"; tmp = "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
|
||||
// <<"; sum = "<<sum<<G4endl;
|
||||
G4cout<<k<<" "<<theta2k<<" "<<std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result
|
||||
<<" "<<sum<<G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << k << " " << theta2k << " "
|
||||
<< std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result
|
||||
<< " " << sum << G4endl;
|
||||
}
|
||||
}
|
||||
result = 2*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
|
||||
// result *= ( 1 - std::exp(-0.5*fPlateNumber*sigma) )/( 1 - std::exp(-0.5*sigma) );
|
||||
// fPlateNumber;
|
||||
result *= dump*( -1 + dump + 2*fPlateNumber );
|
||||
/*
|
||||
fEnergy = energy;
|
||||
// G4Integrator<G4VXTRenergyLoss,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
|
||||
G4Integrator<G4TransparentRegXTRadiator,G4double(G4VXTRenergyLoss::*)(G4double)> integral;
|
||||
|
||||
tmp = integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.0,0.3*fMaxThetaTR) +
|
||||
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.3*fMaxThetaTR,0.6*fMaxThetaTR) +
|
||||
integral.Legendre96(this,&G4VXTRenergyLoss::SpectralAngleXTRdEdx,
|
||||
0.6*fMaxThetaTR,fMaxThetaTR) ;
|
||||
result += tmp;
|
||||
*/
|
||||
result = 2 * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
|
||||
result *= dump * (-1 + dump + 2 * fPlateNumber);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Approximation for radiator interference factor for the case of
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in coresponding material.
|
||||
|
||||
G4double
|
||||
G4XTRRegularRadModel::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in corresponding material.
|
||||
G4double G4XTRRegularRadModel::GetStackFactor(G4double energy, G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, I2 ;
|
||||
|
||||
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle) ;
|
||||
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle) ;
|
||||
G4double aZa = fPlateThick / GetPlateFormationZone(energy, gamma, varAngle);
|
||||
G4double bZb = fGasThick / GetGasFormationZone(energy, gamma, varAngle);
|
||||
|
||||
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy) ;
|
||||
bMb = fGasThick*GetGasLinearPhotoAbs(energy) ;
|
||||
G4double aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
|
||||
G4double bMb = fGasThick * GetGasLinearPhotoAbs(energy);
|
||||
|
||||
Qa = std::exp(-aMa) ;
|
||||
Qb = std::exp(-bMb) ;
|
||||
Q = Qa*Qb ;
|
||||
G4double Qa = std::exp(-aMa);
|
||||
G4double Qb = std::exp(-bMb);
|
||||
G4double Q = Qa * Qb;
|
||||
|
||||
// G4complex Ca(1.0+0.5*fPlateThick*Ma,fPlateThick/Za) ;
|
||||
// G4complex Cb(1.0+0.5*fGasThick*Mb,fGasThick/Zb) ;
|
||||
G4complex Ha(std::exp(-0.5 * aMa) * std::cos(aZa),
|
||||
-std::exp(-0.5 * aMa) * std::sin(aZa));
|
||||
|
||||
G4complex Ha( std::exp(-0.5*aMa)*std::cos(aZa),
|
||||
-std::exp(-0.5*aMa)*std::sin(aZa) ) ;
|
||||
|
||||
G4complex Hb( std::exp(-0.5*bMb)*std::cos(bZb),
|
||||
-std::exp(-0.5*bMb)*std::sin(bZb) ) ;
|
||||
G4complex Hb(std::exp(-0.5 * bMb) * std::cos(bZb),
|
||||
-std::exp(-0.5 * bMb) * std::sin(bZb));
|
||||
|
||||
G4complex H = Ha*Hb ;
|
||||
G4complex H = Ha * Hb;
|
||||
G4complex Hs = std::conj(H);
|
||||
|
||||
G4complex Hs = std::conj(H) ;
|
||||
G4complex F2 = (1.0 - Ha) * (Qa - Ha) * Hb * (1.0 - Hs) * (Q - Hs);
|
||||
F2 *= std::pow(Q, G4double(fPlateNumber)) - std::pow(H, fPlateNumber);
|
||||
|
||||
// G4complex F1 = ( 0.5*(1+Qa)*(1+H) - Ha - Qa*Hb )/(1-H) ;
|
||||
G4double result = (1. - std::pow(Q, G4double(fPlateNumber))) / (1. - Q);
|
||||
result *= (1. - Qa) * (1. + Qa - 2. * std::sqrt(Qa) * std::cos(aZa));
|
||||
result /= (1. - std::sqrt(Q)) * (1. - std::sqrt(Q)) +
|
||||
4. * std::sqrt(Q) * std::sin(0.5 * (aZa + bZb)) *
|
||||
std::sin(0.5 * (aZa + bZb));
|
||||
|
||||
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb*(1.0-Hs)*(Q-Hs) ;
|
||||
G4double I2 = 1.;
|
||||
I2 /= (1. - std::sqrt(Q)) * (1. - std::sqrt(Q)) +
|
||||
4. * std::sqrt(Q) * std::sin(0.5 * (aZa + bZb)) *
|
||||
std::sin(0.5 * (aZa + bZb));
|
||||
|
||||
F2 *= std::pow(Q,G4double(fPlateNumber)) - std::pow(H,fPlateNumber) ;
|
||||
I2 /= Q * ((std::sqrt(Q) - std::cos(aZa + bZb)) *
|
||||
(std::sqrt(Q) - std::cos(aZa + bZb)) +
|
||||
std::sin(aZa + bZb) * std::sin(aZa + bZb));
|
||||
|
||||
result = ( 1. - std::pow(Q,G4double(fPlateNumber)) )/( 1. - Q ) ;
|
||||
G4complex stack = 2. * I2 * F2;
|
||||
stack += result;
|
||||
stack *= OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
|
||||
result *= (1. - Qa)*(1. + Qa - 2.*std::sqrt(Qa)*std::cos(aZa)) ;
|
||||
|
||||
result /= (1. - std::sqrt(Q))*(1. - std::sqrt(Q)) +
|
||||
4.*std::sqrt(Q)*std::sin(0.5*(aZa+bZb))*std::sin(0.5*(aZa+bZb)) ;
|
||||
|
||||
I2 = 1.; // 2.0*std::real(F2) ;
|
||||
|
||||
I2 /= (1. - std::sqrt(Q))*(1. - std::sqrt(Q)) +
|
||||
4.*std::sqrt(Q)*std::sin(0.5*(aZa+bZb))*std::sin(0.5*(aZa+bZb)) ;
|
||||
|
||||
I2 /= Q*( (std::sqrt(Q)-std::cos(aZa+bZb))*(std::sqrt(Q)-std::cos(aZa+bZb)) +
|
||||
std::sin(aZa+bZb)*std::sin(aZa+bZb) ) ;
|
||||
|
||||
G4complex stack = 2.*I2*F2;
|
||||
stack += result;
|
||||
stack *= OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
|
||||
// result += I2 ;
|
||||
result = std::real(stack);
|
||||
|
||||
return result ;
|
||||
return std::real(stack);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,51 +23,40 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
|
||||
#include <complex>
|
||||
|
||||
#include "G4XTRTransparentRegRadModel.hh"
|
||||
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Integrator.hh"
|
||||
#include "G4Gamma.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor, destructor
|
||||
|
||||
G4XTRTransparentRegRadModel::G4XTRTransparentRegRadModel(G4LogicalVolume *anEnvelope,
|
||||
G4Material* foilMat,G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n,
|
||||
const G4String& processName) :
|
||||
G4VXTRenergyLoss(anEnvelope,foilMat,gasMat,a,b,n,processName)
|
||||
G4XTRTransparentRegRadModel::G4XTRTransparentRegRadModel(
|
||||
G4LogicalVolume* anEnvelope, G4Material* foilMat, G4Material* gasMat,
|
||||
G4double a, G4double b, G4int n, const G4String& processName)
|
||||
: G4VXTRenergyLoss(anEnvelope, foilMat, gasMat, a, b, n, processName)
|
||||
{
|
||||
G4cout<<"Regular transparent X-ray TR radiator EM process is called"<<G4endl;
|
||||
G4cout << "Regular transparent X-ray TR radiator EM process is called"
|
||||
<< G4endl;
|
||||
|
||||
// Build energy and angular integral spectra of X-ray TR photons from
|
||||
// a radiator
|
||||
fExitFlux = true;
|
||||
fAlphaPlate = 10000;
|
||||
fAlphaGas = 1000;
|
||||
|
||||
// BuildTable();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
G4XTRTransparentRegRadModel::~G4XTRTransparentRegRadModel() {}
|
||||
|
||||
G4XTRTransparentRegRadModel::~G4XTRTransparentRegRadModel()
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void G4XTRTransparentRegRadModel::ProcessDescription(std::ostream& out) const
|
||||
{
|
||||
;
|
||||
out << "Process describing radiator of X-ray transition radiation.\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4XTRTransparentRegRadModel::SpectralXTRdEdx(G4double energy)
|
||||
{
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, cofPHC,aMa, bMb, sigma;
|
||||
static constexpr G4double cofPHC = 4. * pi * hbarc;
|
||||
G4double result, sum = 0., tmp, cof1, cof2, cofMin, aMa, bMb, sigma;
|
||||
G4int k, kMax, kMin;
|
||||
|
||||
aMa = GetPlateLinearPhotoAbs(energy);
|
||||
@@ -82,133 +71,71 @@ G4double G4XTRTransparentRegRadModel::SpectralXTRdEdx(G4double energy)
|
||||
bMb *= fGasThick;
|
||||
|
||||
sigma = aMa + bMb;
|
||||
|
||||
cofPHC = 4.*pi*hbarc;
|
||||
tmp = (fSigma1 - fSigma2)/cofPHC/energy;
|
||||
cof1 = fPlateThick*tmp;
|
||||
cof2 = fGasThick*tmp;
|
||||
|
||||
cofMin = energy*(fPlateThick + fGasThick)/fGamma/fGamma;
|
||||
cofMin += (fPlateThick*fSigma1 + fGasThick*fSigma2)/energy;
|
||||
tmp = (fSigma1 - fSigma2) / cofPHC / energy;
|
||||
cof1 = fPlateThick * tmp;
|
||||
cof2 = fGasThick * tmp;
|
||||
|
||||
cofMin = energy * (fPlateThick + fGasThick) / fGamma / fGamma;
|
||||
cofMin += (fPlateThick * fSigma1 + fGasThick * fSigma2) / energy;
|
||||
cofMin /= cofPHC;
|
||||
|
||||
// if (fGamma < 1200) kMin = G4int(cofMin); // 1200 ?
|
||||
// else kMin = 1;
|
||||
|
||||
|
||||
kMin = G4int(cofMin);
|
||||
if (cofMin > kMin) kMin++;
|
||||
if(cofMin > kMin)
|
||||
kMin++;
|
||||
|
||||
// tmp = (fPlateThick + fGasThick)*energy*fMaxThetaTR;
|
||||
// tmp /= cofPHC;
|
||||
// kMax = G4int(tmp);
|
||||
// if(kMax < 0) kMax = 0;
|
||||
// kMax += kMin;
|
||||
|
||||
kMax = kMin + 19;
|
||||
|
||||
kMax = kMin + 19; // 5; // 9; // kMin + G4int(tmp);
|
||||
|
||||
// tmp /= fGamma;
|
||||
// if( G4int(tmp) < kMin ) kMin = G4int(tmp);
|
||||
// G4cout<<"kMin = "<<kMin<<"; kMax = "<<kMax<<G4endl;
|
||||
|
||||
for( k = kMin; k <= kMax; k++ )
|
||||
for(k = kMin; k <= kMax; k++)
|
||||
{
|
||||
tmp = pi*fPlateThick*(k + cof2)/(fPlateThick + fGasThick);
|
||||
result = (k - cof1)*(k - cof1)*(k + cof2)*(k + cof2);
|
||||
tmp = pi * fPlateThick * (k + cof2) / (fPlateThick + fGasThick);
|
||||
result = (k - cof1) * (k - cof1) * (k + cof2) * (k + cof2);
|
||||
|
||||
if( k == kMin && kMin == G4int(cofMin) )
|
||||
if(k == kMin && kMin == G4int(cofMin))
|
||||
{
|
||||
sum += 0.5*std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum +=
|
||||
0.5 * std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum += std::sin(tmp)*std::sin(tmp)*std::abs(k-cofMin)/result;
|
||||
sum += std::sin(tmp) * std::sin(tmp) * std::abs(k - cofMin) / result;
|
||||
}
|
||||
// G4cout<<"k = "<<k<<"; sum = "<<sum<<G4endl;
|
||||
}
|
||||
result = 4.*( cof1 + cof2 )*( cof1 + cof2 )*sum/energy;
|
||||
result *= ( 1. - std::exp(-fPlateNumber*sigma) )/( 1. - std::exp(-sigma) );
|
||||
result = 4. * (cof1 + cof2) * (cof1 + cof2) * sum / energy;
|
||||
result *= (1. - std::exp(-fPlateNumber * sigma)) / (1. - std::exp(-sigma));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Approximation for radiator interference factor for the case of
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in coresponding material.
|
||||
|
||||
G4double
|
||||
G4XTRTransparentRegRadModel::GetStackFactor( G4double energy,
|
||||
G4double gamma, G4double varAngle )
|
||||
// fully Regular radiator. The plate and gas gap thicknesses are fixed.
|
||||
// The mean values of the plate and gas gap thicknesses
|
||||
// are supposed to be about XTR formation zones but much less than
|
||||
// mean absorption length of XTR photons in corresponding material.
|
||||
G4double G4XTRTransparentRegRadModel::GetStackFactor(G4double energy,
|
||||
G4double gamma,
|
||||
G4double varAngle)
|
||||
{
|
||||
/*
|
||||
G4double result, Za, Zb, Ma, Mb, sigma;
|
||||
|
||||
Za = GetPlateFormationZone(energy,gamma,varAngle);
|
||||
Zb = GetGasFormationZone(energy,gamma,varAngle);
|
||||
Ma = GetPlateLinearPhotoAbs(energy);
|
||||
Mb = GetGasLinearPhotoAbs(energy);
|
||||
sigma = Ma*fPlateThick + Mb*fGasThick;
|
||||
G4double aZa = fPlateThick / GetPlateFormationZone(energy, gamma, varAngle);
|
||||
G4double bZb = fGasThick / GetGasFormationZone(energy, gamma, varAngle);
|
||||
G4double aMa = fPlateThick * GetPlateLinearPhotoAbs(energy);
|
||||
G4double bMb = fGasThick * GetGasLinearPhotoAbs(energy);
|
||||
G4double sigma = aMa * fPlateThick + bMb * fGasThick;
|
||||
G4double Qa = std::exp(-0.5 * aMa);
|
||||
G4double Qb = std::exp(-0.5 * bMb);
|
||||
G4double Q = Qa * Qb;
|
||||
|
||||
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate);
|
||||
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas);
|
||||
|
||||
G4complex Ha = std::pow(Ca,-fAlphaPlate);
|
||||
G4complex Hb = std::pow(Cb,-fAlphaGas);
|
||||
G4complex H = Ha*Hb;
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb )/(1.0 - H)
|
||||
* G4double(fPlateNumber) ;
|
||||
G4complex F2 = (1.0-Ha)*(1.0-Ha)*Hb/(1.0-H)/(1.0-H)
|
||||
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) ;
|
||||
// *(1.0 - std::pow(H,fPlateNumber)) ;
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
// G4complex R = F2*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
result = 2.0*std::real(R);
|
||||
return result;
|
||||
*/
|
||||
// numerically unstable result
|
||||
|
||||
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, D, sigma;
|
||||
|
||||
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle);
|
||||
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle);
|
||||
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy);
|
||||
bMb = fGasThick*GetGasLinearPhotoAbs(energy);
|
||||
sigma = aMa*fPlateThick + bMb*fGasThick;
|
||||
Qa = std::exp(-0.5*aMa);
|
||||
Qb = std::exp(-0.5*bMb);
|
||||
Q = Qa*Qb;
|
||||
|
||||
G4complex Ha( Qa*std::cos(aZa), -Qa*std::sin(aZa) );
|
||||
G4complex Hb( Qb*std::cos(bZb), -Qb*std::sin(bZb) );
|
||||
G4complex H = Ha*Hb;
|
||||
G4complex Ha(Qa * std::cos(aZa), -Qa * std::sin(aZa));
|
||||
G4complex Hb(Qb * std::cos(bZb), -Qb * std::sin(bZb));
|
||||
G4complex H = Ha * Hb;
|
||||
G4complex Hs = conj(H);
|
||||
D = 1.0 /( (1. - Q)*(1. - Q) +
|
||||
4.*Q*std::sin(0.5*(aZa + bZb))*std::sin(0.5*(aZa + bZb)) );
|
||||
G4complex F1 = (1.0 - Ha)*(1.0 - Hb)*(1.0 - Hs)
|
||||
* G4double(fPlateNumber)*D;
|
||||
G4complex F2 = (1.0 - Ha)*(1.0 - Ha)*Hb*(1.0 - Hs)*(1.0 - Hs)
|
||||
// * (1.0 - std::pow(H,fPlateNumber)) * D*D;
|
||||
* (1.0 - std::exp(-0.5*fPlateNumber*sigma)) * D*D;
|
||||
G4complex R = (F1 + F2)*OneInterfaceXTRdEdx(energy,gamma,varAngle);
|
||||
result = 2.0*std::real(R);
|
||||
return result;
|
||||
|
||||
G4double D =
|
||||
1.0 / ((1. - Q) * (1. - Q) +
|
||||
4. * Q * std::sin(0.5 * (aZa + bZb)) * std::sin(0.5 * (aZa + bZb)));
|
||||
G4complex F1 =
|
||||
(1.0 - Ha) * (1.0 - Hb) * (1.0 - Hs) * G4double(fPlateNumber) * D;
|
||||
G4complex F2 = (1.0 - Ha) * (1.0 - Ha) * Hb * (1.0 - Hs) * (1.0 - Hs) *
|
||||
(1.0 - std::exp(-0.5 * fPlateNumber * sigma)) * D * D;
|
||||
G4complex R = (F1 + F2) * OneInterfaceXTRdEdx(energy, gamma, varAngle);
|
||||
return 2.0 * std::real(R);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user