91 lowEnergyLimit (250*
eV),
92 highEnergyLimit(100*
GeV),
93 intrinsicLowEnergyLimit(10*
eV),
94 intrinsicHighEnergyLimit(100*
GeV)
96 if (lowEnergyLimit < intrinsicLowEnergyLimit ||
97 highEnergyLimit > intrinsicHighEnergyLimit)
99 G4Exception(
"G4LowEnergyPolarizedCompton::G4LowEnergyPolarizedCompton()",
101 "Energy outside intrinsic process validity range!");
108 G4String scatterFile =
"comp/ce-sf-";
110 scatterFunctionData->
LoadData(scatterFile);
112 meanFreePathTable = 0;
124 << lowEnergyLimit /
keV <<
" keV - "
125 << highEnergyLimit /
GeV <<
" GeV"
134 delete meanFreePathTable;
135 delete crossSectionHandler;
136 delete scatterFunctionData;
144 crossSectionHandler->
Clear();
145 G4String crossSectionFile =
"comp/ce-cs-";
146 crossSectionHandler->
LoadData(crossSectionFile);
147 delete meanFreePathTable;
186 if(!(gammaPolarization0.
isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.
mag()==0))
188 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
194 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
202 if(gammaEnergy0 <= lowEnergyLimit)
219 G4double epsilon, epsilonSq, onecost, sinThetaSqr, greject ;
223 G4double alpha1 = - std::log(epsilon0);
224 G4double alpha2 = 0.5*(1.- epsilon0Sq);
234 epsilonSq = epsilon*epsilon;
239 epsilon = std::sqrt(epsilonSq);
242 onecost = (1.- epsilon)/(epsilon*E0_m);
243 sinThetaSqr = onecost*(2.-onecost);
246 if (sinThetaSqr > 1.)
249 <<
" -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
250 <<
"sin(theta)**2 = "
256 if (sinThetaSqr < 0.)
259 <<
" -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
260 <<
"sin(theta)**2 = "
268 G4double x = std::sqrt(onecost/2.) / (wlGamma/
cm);;
270 greject = (1. - epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
279 G4double phi = SetPhi(epsilon,sinThetaSqr);
292 <<
" -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
302 <<
" -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
312 G4double sinTheta = std::sqrt (sinThetaSqr);
318 <<
" -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
328 <<
" -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
338 G4double dirx = sinTheta*std::cos(phi);
339 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;
421 G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
428 gammaDirection1 = tmpDirection1;
432 SystemOfRefChange(gammaDirection0,gammaDirection1,
433 gammaPolarization0,gammaPolarization1);
435 if (gammaEnergy1 > 0.)
451 G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 -bindingE;
462 G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
463 gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
498 b = energyRate + 1/energyRate;
500 phiProbability = 1 - (a/
b)*(std::cos(phi)*std::cos(phi));
505 while ( rand2 > phiProbability );
519 return x < z ?
G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
521 return y < z ?
G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
538 c.
setX(std::cos(angle)*(a0.
x())+std::sin(angle)*b0.
x());
539 c.
setY(std::cos(angle)*(a0.
y())+std::sin(angle)*b0.
y());
540 c.
setZ(std::cos(angle)*(a0.
z())+std::sin(angle)*b0.
z());
549 G4ThreeVector G4LowEnergyPolarizedCompton::GetPerpendicularPolarization
563 return gammaPolarization - gammaPolarization.
dot(gammaDirection)/gammaDirection.
dot(gammaDirection) * gammaDirection;
576 G4double sinTheta = std::sqrt(sinSqrTh);
580 G4double normalisation = std::sqrt(1. - cosSqrPhi*sinSqrTh);
619 if (rand1<(epsilon+1.0/epsilon-2)/(2.0*(epsilon+1.0/epsilon)-4.0*sinSqrTh*cosSqrPhi))
634 G4double sinBeta = std::sqrt(1-cosBeta*cosBeta);
638 G4double xParallel = normalisation*cosBeta;
639 G4double yParallel = -(sinSqrTh*cosPhi*sinPhi)*cosBeta/normalisation;
640 G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
642 G4double yPerpendicular = (costheta)*sinBeta/normalisation;
643 G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
645 G4double xTotal = (xParallel + xPerpendicular);
646 G4double yTotal = (yParallel + yPerpendicular);
647 G4double zTotal = (zParallel + zPerpendicular);
649 gammaPolarization1.
setX(xTotal);
650 gammaPolarization1.
setY(yTotal);
651 gammaPolarization1.
setZ(zTotal);
653 return gammaPolarization1;
658 void G4LowEnergyPolarizedCompton::SystemOfRefChange(
G4ThreeVector& direction0,
674 direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
679 polarization1 = (polarization_x*Axis_X0 + polarization_y*Axis_Y0 + polarization_z*Axis_Z0).unit();
697 size_t materialIndex = couple->
GetIndex();
699 if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->
FindValue(highEnergyLimit,materialIndex);
700 else if (energy < lowEnergyLimit) meanFreePath =
DBL_MAX;
701 else meanFreePath = meanFreePathTable->
FindValue(energy,materialIndex);
void BuildPhysicsTable(const G4ParticleDefinition &photon)
G4double GetKineticEnergy() const
CLHEP::Hep3Vector G4ThreeVector
G4LowEnergyPolarizedCompton(const G4String &processName="polarLowEnCompt")
const G4DynamicParticle * GetDynamicParticle() const
double dot(const Hep3Vector &) const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4double BindingEnergy(G4int Z, G4int shellIndex) const
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
G4RDVEMDataSet * BuildMeanFreePathForMaterials(const G4DataVector *energyCuts=0)
double howOrthogonal(const Hep3Vector &v) const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void LoadData(const G4String &fileName)
REAL *8 function var(A, B, C, D)
~G4LowEnergyPolarizedCompton()
G4GLOB_DLL std::ostream G4cout
G4double GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition)
const G4ThreeVector & GetMomentumDirection() const
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
const G4String & GetProcessName() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
virtual G4bool Escape(const G4ParticleDefinition *particle, const G4MaterialCutsCouple *couple, G4double energy, G4double safety) const =0
virtual void Initialize(const G4Track &)
void SetNumberOfSecondaries(G4int totSecondaries)
G4StepPoint * GetPostStepPoint() const
G4int SelectRandomAtom(const G4MaterialCutsCouple *couple, G4double e) const
const G4ThreeVector & GetPolarization() const
void ProposeEnergy(G4double finalEnergy)
G4ParticleChange aParticleChange
G4double GetSafety() const
void AddSecondary(G4Track *aSecondary)
static G4Electron * Electron()
void LoadData(const G4String &dataFile)
Hep3Vector cross(const Hep3Vector &) const
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
void ProposeTrackStatus(G4TrackStatus status)
G4int SelectRandomShell(G4int Z) const
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4bool IsApplicable(const G4ParticleDefinition &definition)
virtual G4bool LoadData(const G4String &fileName)=0