53 :
G4VEmModel(nam),fParticleChange(0),isInitialised(false),
54 meanFreePathTable(0),scatterFunctionData(0),crossSectionHandler(0)
56 lowEnergyLimit = 250 *
eV;
57 highEnergyLimit = 100 *
GeV;
69 if( verboseLevel>0 ) {
70 G4cout <<
"Livermore Polarized Compton is constructed " <<
G4endl
72 << lowEnergyLimit /
eV <<
" eV - "
73 << highEnergyLimit /
GeV <<
" GeV"
82 if (meanFreePathTable)
delete meanFreePathTable;
83 if (crossSectionHandler)
delete crossSectionHandler;
84 if (scatterFunctionData)
delete scatterFunctionData;
93 G4cout <<
"Calling G4LivermorePolarizedComptonModel::Initialise()" <<
G4endl;
95 if (crossSectionHandler)
97 crossSectionHandler->
Clear();
98 delete crossSectionHandler;
104 crossSectionHandler->
Clear();
105 G4String crossSectionFile =
"comp/ce-cs-";
106 crossSectionHandler->
LoadData(crossSectionFile);
108 meanFreePathTable = 0;
112 G4String scatterFile =
"comp/ce-sf-";
114 scatterFunctionData->
LoadData(scatterFile);
121 if (verboseLevel > 2)
122 G4cout <<
"Loaded cross section files for Livermore Polarized Compton model" <<
G4endl;
126 if( verboseLevel>0 ) {
127 G4cout <<
"Livermore Polarized Compton model is initialized " << G4endl
136 if(isInitialised)
return;
138 isInitialised =
true;
149 if (verboseLevel > 3)
150 G4cout <<
"Calling ComputeCrossSectionPerAtom() of G4LivermorePolarizedComptonModel" <<
G4endl;
152 if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit)
return 0.0;
172 if (verboseLevel > 3)
173 G4cout <<
"Calling SampleSecondaries() of G4LivermorePolarizedComptonModel" <<
G4endl;
187 if(!(gammaPolarization0.
isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.
mag()==0))
189 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
195 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
203 if(gammaEnergy0 <= lowEnergyLimit)
221 G4double epsilon, epsilonSq, onecost, sinThetaSqr, greject ;
223 G4double epsilon0Local = 1./(1. + 2*E0_m);
224 G4double epsilon0Sq = epsilon0Local*epsilon0Local;
225 G4double alpha1 = - std::log(epsilon0Local);
226 G4double alpha2 = 0.5*(1.- epsilon0Sq);
236 epsilonSq = epsilon*epsilon;
241 epsilon = std::sqrt(epsilonSq);
244 onecost = (1.- epsilon)/(epsilon*E0_m);
245 sinThetaSqr = onecost*(2.-onecost);
248 if (sinThetaSqr > 1.)
251 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
252 <<
"sin(theta)**2 = "
258 if (sinThetaSqr < 0.)
261 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
262 <<
"sin(theta)**2 = "
270 G4double x = std::sqrt(onecost/2.) / (wlGamma/
cm);;
272 greject = (1. - epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
281 G4double phi = SetPhi(epsilon,sinThetaSqr);
294 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
304 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
314 G4double sinTheta = std::sqrt (sinThetaSqr);
320 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
330 <<
" -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
340 G4double dirx = sinTheta*std::cos(phi);
341 G4double diry = sinTheta*std::sin(phi);
354 G4int maxDopplerIterations = 1000;
356 G4double photonEoriginal = epsilon * gammaEnergy0;
368 eMax = gammaEnergy0 - bindingE;
374 G4double pDoppler2 = pDoppler * pDoppler;
375 G4double var2 = 1. + onecost * E0_m;
376 G4double var3 = var2*var2 - pDoppler2;
377 G4double var4 = var2 - pDoppler2 * cosTheta;
378 G4double var = var4*var4 - var3 + pDoppler2 * var3;
384 if (
G4UniformRand() < 0.5) photonE = (var4 - varSqrt) * scale;
385 else photonE = (var4 + varSqrt) * scale;
391 }
while ( iteration <= maxDopplerIterations &&
392 (photonE < 0. || photonE > eMax || photonE < eMax*
G4UniformRand()) );
396 if (iteration >= maxDopplerIterations)
398 photonE = photonEoriginal;
402 gammaEnergy1 = photonE;
413 G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
420 gammaDirection1 = tmpDirection1;
424 SystemOfRefChange(gammaDirection0,gammaDirection1,
425 gammaPolarization0,gammaPolarization1);
427 if (gammaEnergy1 > 0.)
444 G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 -bindingE;
448 if(ElecKineEnergy < 0.0) {
457 G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
458 gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
463 fvect->push_back(dp);
486 b = energyRate + 1/energyRate;
488 phiProbability = 1 - (a/
b)*(std::cos(phi)*std::cos(phi));
493 while ( rand2 > phiProbability );
509 return x < z ?
G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
511 return y < z ?
G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
530 c.
setX(std::cos(angle)*(a0.
x())+std::sin(angle)*b0.
x());
531 c.
setY(std::cos(angle)*(a0.
y())+std::sin(angle)*b0.
y());
532 c.
setZ(std::cos(angle)*(a0.
z())+std::sin(angle)*b0.
z());
542 G4ThreeVector G4LivermorePolarizedComptonModel::GetPerpendicularPolarization
556 return gammaPolarization - gammaPolarization.
dot(gammaDirection)/gammaDirection.
dot(gammaDirection) * gammaDirection;
570 G4double sinTheta = std::sqrt(sinSqrTh);
574 G4double normalisation = std::sqrt(1. - cosSqrPhi*sinSqrTh);
613 if (rand1<(epsilon+1.0/epsilon-2)/(2.0*(epsilon+1.0/epsilon)-4.0*sinSqrTh*cosSqrPhi))
628 G4double sinBeta = std::sqrt(1-cosBeta*cosBeta);
632 G4double xParallel = normalisation*cosBeta;
633 G4double yParallel = -(sinSqrTh*cosPhi*sinPhi)*cosBeta/normalisation;
634 G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
636 G4double yPerpendicular = (costheta)*sinBeta/normalisation;
637 G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
639 G4double xTotal = (xParallel + xPerpendicular);
640 G4double yTotal = (yParallel + yPerpendicular);
641 G4double zTotal = (zParallel + zPerpendicular);
643 gammaPolarization1.
setX(xTotal);
644 gammaPolarization1.
setY(yTotal);
645 gammaPolarization1.
setZ(zTotal);
647 return gammaPolarization1;
653 void G4LivermorePolarizedComptonModel::SystemOfRefChange(
G4ThreeVector& direction0,
669 direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
674 polarization1 = (polarization_x*Axis_X0 + polarization_y*Axis_Y0 + polarization_z*Axis_Z0).unit();
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
G4double LowEnergyLimit() const
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
virtual ~G4LivermorePolarizedComptonModel()
G4double GetKineticEnergy() const
CLHEP::Hep3Vector G4ThreeVector
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
G4double HighEnergyLimit() const
double dot(const Hep3Vector &) const
G4ParticleDefinition * GetDefinition() const
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4int SelectRandomShell(G4int Z) const
double howOrthogonal(const Hep3Vector &v) const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void LoadData(const G4String &fileName)
void SetHighEnergyLimit(G4double)
REAL *8 function var(A, B, C, D)
G4double FindValue(G4int Z, G4double e) const
G4GLOB_DLL std::ostream G4cout
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
const G4ThreeVector & GetMomentumDirection() const
G4double BindingEnergy(G4int Z, G4int shellIndex) const
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
void ProposePolarization(const G4ThreeVector &dir)
G4VEMDataSet * BuildMeanFreePathForMaterials(const G4DataVector *energyCuts=0)
G4ParticleChangeForGamma * fParticleChange
G4LivermorePolarizedComptonModel(const G4ParticleDefinition *p=0, const G4String &nam="LivermorePolarizedCompton")
const G4ThreeVector & GetPolarization() const
void LoadData(const G4String &dataFile)
virtual G4bool LoadData(const G4String &fileName)=0
static G4Electron * Electron()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
Hep3Vector cross(const Hep3Vector &) const
void ProposeTrackStatus(G4TrackStatus status)
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
G4ParticleChangeForGamma * GetParticleChangeForGamma()