73 const G4int arrayDim = 980;
80 betaArray[2] = arrayDim - 1;
83 for(
G4int level = 0; level < 2; level++){
85 char nameChar0[100] =
"ftab0.dat";
86 char nameChar1[100] =
"ftab1.dat";
89 if(level == 0) filename = nameChar0;
90 if(level == 1) filename = nameChar1;
92 char* path = getenv(
"G4LEDATA");
95 G4String excep =
"G4EMDataSet - G4LEDATA environment variable not set";
96 G4Exception(
"G4PhotoElectricAngularGeneratorPolarized::G4PhotoElectricAngularGeneratorPolarized",
102 G4String dirFile = pathString +
"/photoelectric_angular/" + filename;
103 std::ifstream infile(dirFile);
104 if (!infile.is_open())
106 G4String excep =
"data file: " + dirFile +
" not found";
107 G4Exception(
"G4PhotoElectricAngularGeneratorPolarized::G4PhotoElectricAngularGeneratorPolarized",
113 G4float aRead=0,cRead=0, beta=0;
114 for(
G4int i=0 ; i<arrayDim ;i++){
116 infile >> beta >> aRead >> cRead;
117 aMajorantSurfaceParameterTable[i][level] = aRead;
118 cMajorantSurfaceParameterTable[i][level] = cRead;
139 G4double beta = std::sqrt((gamma - 1)*(gamma + 1))/gamma;
152 PhotoElectronGetMajorantSurfaceAandCParameters(shellId, beta, &aBeta, &cBeta);
156 PhotoElectronGeneratePhiAndTheta(shellId, beta, aBeta, cBeta, &phi, &theta);
160 PhotoElectronRotationMatrix(direction, polarization);
163 fLocalDirection = PhotoElectronComputeFinalDirection(rotation, theta, phi);
169 G4PhotoElectricAngularGeneratorPolarized::PhotoElectronGeneratePhiAndTheta(
177 G4double crossSectionMajorantFunctionValue = 0;
194 theta=std::sqrt(((std::exp(rand2*std::log(1+cBeta*
pi*
pi)))-1)/cBeta);
195 crossSectionMajorantFunctionValue =
196 CrossSectionMajorantFunction(theta, cBeta);
197 crossSectionValue = DSigmaKshellGavrila1959(beta, theta, phi);
202 theta = std::sqrt(((std::exp(rand2*std::log(1+cBeta*
pi*
pi)))-1)/cBeta);
203 crossSectionMajorantFunctionValue =
204 CrossSectionMajorantFunction(theta, cBeta);
205 crossSectionValue = DSigmaL1shellGavrila(beta, theta, phi);
209 maxBeta=rand3*aBeta*crossSectionMajorantFunctionValue;
212 if(crossSectionValue < 0.0) { crossSectionValue = maxBeta; }
214 }
while(maxBeta > crossSectionValue || theta > CLHEP::pi);
221 G4PhotoElectricAngularGeneratorPolarized::CrossSectionMajorantFunction(
225 G4double crossSectionMajorantFunctionValue = 0;
226 crossSectionMajorantFunctionValue = theta/(1+cBeta*theta*theta);
227 return crossSectionMajorantFunctionValue;
231 G4PhotoElectricAngularGeneratorPolarized::DSigmaKshellGavrila1959(
238 G4double sqrtOneBeta2 = std::sqrt(oneBeta2);
239 G4double oneBeta2_to_3_2 = std::pow(oneBeta2,1.5);
240 G4double cosTheta = std::cos(theta);
241 G4double sinTheta2 = std::sin(theta)*std::sin(theta);
242 G4double cosPhi2 = std::cos(phi)*std::cos(phi);
243 G4double oneBetaCosTheta = 1-beta*cosTheta;
248 firstTerm = sinTheta2*cosPhi2/std::pow(oneBetaCosTheta,4)-(1 - sqrtOneBeta2)/(2*oneBeta2) *
249 (sinTheta2 * cosPhi2)/std::pow(oneBetaCosTheta,3) + (1-sqrtOneBeta2)*
250 (1-sqrtOneBeta2)/(4*oneBeta2_to_3_2) * sinTheta2/std::pow(oneBetaCosTheta,3);
252 secondTerm = std::sqrt(1 - sqrtOneBeta2)/(std::pow(2.,3.5)*beta2*std::pow(oneBetaCosTheta,2.5)) *
253 (4*beta2/sqrtOneBeta2 * sinTheta2*cosPhi2/oneBetaCosTheta + 4*beta/oneBeta2 * cosTheta * cosPhi2
254 - 4*(1-sqrtOneBeta2)/oneBeta2 *(1+cosPhi2) - beta2 * (1-sqrtOneBeta2)/oneBeta2 * sinTheta2/oneBetaCosTheta
255 + 4*beta2*(1-sqrtOneBeta2)/oneBeta2_to_3_2 - 4*beta*(1-sqrtOneBeta2)*(1-sqrtOneBeta2)/oneBeta2_to_3_2 * cosTheta)
256 + (1-sqrtOneBeta2)/(4*beta2*oneBetaCosTheta*oneBetaCosTheta) * (beta/oneBeta2 - 2/oneBeta2 * cosTheta * cosPhi2 +
257 (1-sqrtOneBeta2)/oneBeta2_to_3_2 * cosTheta - beta * (1-sqrtOneBeta2)/oneBeta2_to_3_2);
267 G4PhotoElectricAngularGeneratorPolarized::DSigmaL1shellGavrila(
274 G4double sqrtOneBeta2 = std::sqrt(oneBeta2);
275 G4double oneBeta2_to_3_2=std::pow(oneBeta2,1.5);
276 G4double cosTheta = std::cos(theta);
277 G4double sinTheta2 =std::sin(theta)*std::sin(theta);
278 G4double cosPhi2 = std::cos(phi)*std::cos(phi);
279 G4double oneBetaCosTheta = 1-beta*cosTheta;
285 firstTerm = sinTheta2*cosPhi2/std::pow(oneBetaCosTheta,4)-(1 - sqrtOneBeta2)/(2*oneBeta2)
286 * (sinTheta2 * cosPhi2)/std::pow(oneBetaCosTheta,3) + (1-sqrtOneBeta2)*
287 (1-sqrtOneBeta2)/(4*oneBeta2_to_3_2) * sinTheta2/std::pow(oneBetaCosTheta,3);
289 secondTerm = std::sqrt(1 - sqrtOneBeta2)/(std::pow(2.,3.5)*beta2*std::pow(oneBetaCosTheta,2.5)) *
290 (4*beta2/sqrtOneBeta2 * sinTheta2*cosPhi2/oneBetaCosTheta + 4*beta/oneBeta2 * cosTheta * cosPhi2
291 - 4*(1-sqrtOneBeta2)/oneBeta2 *(1+cosPhi2) - beta2 * (1-sqrtOneBeta2)/oneBeta2 * sinTheta2/oneBetaCosTheta
292 + 4*beta2*(1-sqrtOneBeta2)/oneBeta2_to_3_2 - 4*beta*(1-sqrtOneBeta2)*(1-sqrtOneBeta2)/oneBeta2_to_3_2 * cosTheta)
293 + (1-sqrtOneBeta2)/(4*beta2*oneBetaCosTheta*oneBetaCosTheta) * (beta/oneBeta2 - 2/oneBeta2 * cosTheta * cosPhi2 +
294 (1-sqrtOneBeta2)/oneBeta2_to_3_2*cosTheta - beta*(1-sqrtOneBeta2)/oneBeta2_to_3_2);
302 G4PhotoElectricAngularGeneratorPolarized::PhotoElectronRotationMatrix(
311 if(!(polarization.
isOrthogonal(direction,kTolerance)) || mS == 0){
319 c.
setX(std::cos(angle)*(a0.
x())+std::sin(angle)*b0.
x());
320 c.
setY(std::cos(angle)*(a0.
y())+std::sin(angle)*b0.
y());
321 c.
setZ(std::cos(angle)*(a0.
z())+std::sin(angle)*b0.
z());
322 polarization2 = c.
unit();
323 mS = polarization2.
mag();
328 polarization2 = polarization
329 - polarization.
dot(direction)/direction.
dot(direction) * direction;
334 polarization2 = polarization2/mS;
343 G4PhotoElectricAngularGeneratorPolarized::PhotoElectronGetMajorantSurfaceAandCParameters(
G4int shellId,
G4double beta,
G4double *majorantSurfaceParameterA,
G4double *majorantSurfaceParameterC)
const
352 if(shellId > 0) { level = 1; }
355 bStep = betaArray[1];
356 indexMax = (
G4int)betaArray[2];
367 aBeta =
std::max(aMajorantSurfaceParameterTable[k][level],aMajorantSurfaceParameterTable[k+1][level]);
369 aBeta =
std::max(aMajorantSurfaceParameterTable[k-1][level],aMajorantSurfaceParameterTable[k][level]);
371 aBeta =
std::max(aMajorantSurfaceParameterTable[k-1][level],aMajorantSurfaceParameterTable[k][level]);
372 aBeta =
std::max(aBeta,aMajorantSurfaceParameterTable[k+1][level]);
376 cBeta =
std::max(cMajorantSurfaceParameterTable[k][level],cMajorantSurfaceParameterTable[k+1][level]);
377 else if(k == indexMax)
378 cBeta =
std::max(cMajorantSurfaceParameterTable[k-1][level],cMajorantSurfaceParameterTable[k][level]);
380 cBeta =
std::max(cMajorantSurfaceParameterTable[k-1][level],cMajorantSurfaceParameterTable[k][level]);
381 cBeta =
std::max(cBeta,cMajorantSurfaceParameterTable[k+1][level]);
384 *majorantSurfaceParameterA = aBeta;
385 *majorantSurfaceParameterC = cBeta;
398 G4ThreeVector outgoingDirection = rotation*samplingDirection;
399 return outgoingDirection;
405 G4cout <<
"Polarized Photoelectric Angular Generator" <<
G4endl;
406 G4cout <<
"PhotoElectric Electron Angular Generator based on the general Gavrila photoelectron angular distribution" <<
G4endl;
407 G4cout <<
"Includes polarization effects for K and L1 atomic shells, according to Gavrilla (1959, 1961)." <<
G4endl;
408 G4cout <<
"For higher shells the L1 cross-section is used." <<
G4endl;
409 G4cout <<
"(see Physics Reference Manual) \n" <<
G4endl;
CLHEP::Hep3Vector G4ThreeVector
double dot(const Hep3Vector &) const
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
virtual G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double eKinEnergy, G4int shellId, const G4Material *mat=0)
double howOrthogonal(const Hep3Vector &v) const
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4ThreeVector PerpendicularVector(const G4ThreeVector &a) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
const G4ThreeVector & GetPolarization() const
~G4PhotoElectricAngularGeneratorPolarized()
Hep3Vector cross(const Hep3Vector &) const
G4ThreeVector fLocalDirection
G4PhotoElectricAngularGeneratorPolarized()
void PrintGeneratorInformation() const