Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4LivermorePolarizedGammaConversionModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// $Id: G4LivermorePolarizedGammaConversionModel.hh,v 1.2 2010-11-23 16:42:15 flongo Exp $
27// GEANT4 tag $Name: not supported by cvs2svn $
28//
29// Authors: G.Depaola & F.Longo
30//
31//
32
35#include "G4SystemOfUnits.hh"
36
37//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
38
39using namespace std;
40
41//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
42
44 const G4ParticleDefinition*, const G4String& nam)
45 :G4VEmModel(nam),fParticleChange(0),
46 isInitialised(false),meanFreePathTable(0),crossSectionHandler(0)
47{
48 lowEnergyLimit = 2*electron_mass_c2;
49 highEnergyLimit = 100 * GeV;
50 SetLowEnergyLimit(lowEnergyLimit);
51 SetHighEnergyLimit(highEnergyLimit);
52 smallEnergy = 2.*MeV;
53
54 Phi=0.;
55 Psi=0.;
56
57 verboseLevel= 0;
58 // Verbosity scale:
59 // 0 = nothing
60 // 1 = warning for energy non-conservation
61 // 2 = details of energy budget
62 // 3 = calculation of cross sections, file openings, samping of atoms
63 // 4 = entering in methods
64
65 if(verboseLevel > 0) {
66 G4cout << "Livermore Polarized GammaConversion is constructed " << G4endl
67 << "Energy range: "
68 << lowEnergyLimit / keV << " keV - "
69 << highEnergyLimit / GeV << " GeV"
70 << G4endl;
71 }
72
73 crossSectionHandler = new G4CrossSectionHandler();
74 crossSectionHandler->Initialise(0,lowEnergyLimit,highEnergyLimit,400);
75}
76
77//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
78
80{
81 delete crossSectionHandler;
82}
83
84
85
86//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
87
89 const G4DataVector& cuts)
90{
91 if (verboseLevel > 3)
92 G4cout << "Calling G4LivermorePolarizedGammaConversionModel::Initialise()" << G4endl;
93
94 if (crossSectionHandler)
95 {
96 crossSectionHandler->Clear();
97 delete crossSectionHandler;
98 }
99
100 // Energy limits
101 /*
102 // V.Ivanchenko: this was meanless check
103 if (LowEnergyLimit() < lowEnergyLimit)
104 {
105 G4cout << "G4LivermorePolarizedGammaConversionModel: low energy limit increased from " <<
106 LowEnergyLimit()/eV << " eV to " << lowEnergyLimit << " eV" << G4endl;
107 // SetLowEnergyLimit(lowEnergyLimit);
108 }
109 */
110 if (HighEnergyLimit() > highEnergyLimit)
111 {
112 G4cout << "G4LivermorePolarizedGammaConversionModel: high energy limit decreased from " <<
113 HighEnergyLimit()/GeV << " GeV to " << highEnergyLimit << " GeV" << G4endl;
114 // V.Ivanchenko: this is forbidden
115 // SetHighEnergyLimit(highEnergyLimit);
116 }
117
118 // Reading of data files - all materials are read
119
120 crossSectionHandler = new G4CrossSectionHandler;
121 crossSectionHandler->Clear();
122 G4String crossSectionFile = "pair/pp-cs-";
123 crossSectionHandler->LoadData(crossSectionFile);
124
125 //
126 if (verboseLevel > 2) {
127 G4cout << "Loaded cross section files for Livermore Polarized GammaConversion model"
128 << G4endl;
129 }
130 InitialiseElementSelectors(particle,cuts);
131
132 if(verboseLevel > 0) {
133 G4cout << "Livermore Polarized GammaConversion model is initialized " << G4endl
134 << "Energy range: "
135 << LowEnergyLimit() / keV << " keV - "
136 << HighEnergyLimit() / GeV << " GeV"
137 << G4endl;
138 }
139
140 //
141 if(!isInitialised) {
142 isInitialised = true;
144 }
145}
146
147//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
148
151 G4double GammaEnergy,
154{
155 if (verboseLevel > 3) {
156 G4cout << "G4LivermorePolarizedGammaConversionModel::ComputeCrossSectionPerAtom()"
157 << G4endl;
158 }
159 if(Z < 0.9 || GammaEnergy <= lowEnergyLimit) { return 0.0; }
160 G4double cs = crossSectionHandler->FindValue(G4int(Z), GammaEnergy);
161 return cs;
162}
163
164//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
165
166void
168 const G4MaterialCutsCouple* couple,
169 const G4DynamicParticle* aDynamicGamma,
170 G4double,
171 G4double)
172{
173
174 // Fluorescence generated according to:
175 // J. Stepanek ,"A program to determine the radiation spectra due to a single atomic
176 // subshell ionisation by a particle or due to deexcitation or decay of radionuclides",
177 // Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
178
179 if (verboseLevel > 3)
180 G4cout << "Calling SampleSecondaries() of G4LivermorePolarizedGammaConversionModel" << G4endl;
181
182 G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
183 // Within energy limit?
184
185 if(photonEnergy <= lowEnergyLimit)
186 {
189 return;
190 }
191
192
193 G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
194 G4ThreeVector gammaDirection0 = aDynamicGamma->GetMomentumDirection();
195
196 // Make sure that the polarization vector is perpendicular to the
197 // gamma direction. If not
198
199 if(!(gammaPolarization0.isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.mag()==0))
200 { // only for testing now
201 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
202 }
203 else
204 {
205 if ( gammaPolarization0.howOrthogonal(gammaDirection0) != 0)
206 {
207 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
208 }
209 }
210
211 // End of Protection
212
213
214 G4double epsilon ;
215 G4double epsilon0Local = electron_mass_c2 / photonEnergy ;
216
217 // Do it fast if photon energy < 2. MeV
218
219 if (photonEnergy < smallEnergy )
220 {
221 epsilon = epsilon0Local + (0.5 - epsilon0Local) * G4UniformRand();
222 }
223 else
224 {
225
226 // Select randomly one element in the current material
227
228 // G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
229 //const G4Element* element = crossSectionHandler->SelectRandomElement(couple,photonEnergy);
230
231 const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
232 const G4Element* element = SelectRandomAtom(couple,particle,photonEnergy);
233
234 /*
235 if (element == 0)
236 {
237 G4cout << "G4LivermorePolarizedGammaConversionModel::PostStepDoIt - element = 0" << G4endl;
238 }
239 */
240
241 G4IonisParamElm* ionisation = element->GetIonisation();
242
243 /*
244 if (ionisation == 0)
245 {
246 G4cout << "G4LivermorePolarizedGammaConversionModel::PostStepDoIt - ionisation = 0" << G4endl;
247 }
248 */
249
250
251 // Extract Coulomb factor for this Element
252
253 G4double fZ = 8. * (ionisation->GetlogZ3());
254 if (photonEnergy > 50. * MeV) fZ += 8. * (element->GetfCoulomb());
255
256 // Limits of the screening variable
257 G4double screenFactor = 136. * epsilon0Local / (element->GetIonisation()->GetZ3()) ;
258 G4double screenMax = exp ((42.24 - fZ)/8.368) - 0.952 ;
259 G4double screenMin = std::min(4.*screenFactor,screenMax) ;
260
261 // Limits of the energy sampling
262 G4double epsilon1 = 0.5 - 0.5 * sqrt(1. - screenMin / screenMax) ;
263 G4double epsilonMin = std::max(epsilon0Local,epsilon1);
264 G4double epsilonRange = 0.5 - epsilonMin ;
265
266 // Sample the energy rate of the created electron (or positron)
267 G4double screen;
268 G4double gReject ;
269
270 G4double f10 = ScreenFunction1(screenMin) - fZ;
271 G4double f20 = ScreenFunction2(screenMin) - fZ;
272 G4double normF1 = std::max(f10 * epsilonRange * epsilonRange,0.);
273 G4double normF2 = std::max(1.5 * f20,0.);
274
275 do {
276 if (normF1 / (normF1 + normF2) > G4UniformRand() )
277 {
278 epsilon = 0.5 - epsilonRange * pow(G4UniformRand(), 0.3333) ;
279 screen = screenFactor / (epsilon * (1. - epsilon));
280 gReject = (ScreenFunction1(screen) - fZ) / f10 ;
281 }
282 else
283 {
284 epsilon = epsilonMin + epsilonRange * G4UniformRand();
285 screen = screenFactor / (epsilon * (1 - epsilon));
286 gReject = (ScreenFunction2(screen) - fZ) / f20 ;
287
288
289 }
290 } while ( gReject < G4UniformRand() );
291
292 } // End of epsilon sampling
293
294 // Fix charges randomly
295
296 G4double electronTotEnergy;
297 G4double positronTotEnergy;
298
299
300 if (G4int(2*G4UniformRand()))
301 {
302 electronTotEnergy = (1. - epsilon) * photonEnergy;
303 positronTotEnergy = epsilon * photonEnergy;
304 }
305 else
306 {
307 positronTotEnergy = (1. - epsilon) * photonEnergy;
308 electronTotEnergy = epsilon * photonEnergy;
309 }
310
311 // Scattered electron (positron) angles. ( Z - axis along the parent photon)
312 // Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
313 // derived from Tsai distribution (Rev. Mod. Phys. 49, 421 (1977)
314
315/*
316 G4double u;
317 const G4double a1 = 0.625;
318 G4double a2 = 3. * a1;
319
320 if (0.25 > G4UniformRand())
321 {
322 u = - log(G4UniformRand() * G4UniformRand()) / a1 ;
323 }
324 else
325 {
326 u = - log(G4UniformRand() * G4UniformRand()) / a2 ;
327 }
328*/
329
330 G4double Ene = electronTotEnergy/electron_mass_c2; // Normalized energy
331
332 G4double cosTheta = 0.;
333 G4double sinTheta = 0.;
334
335 SetTheta(&cosTheta,&sinTheta,Ene);
336
337 // G4double theta = u * electron_mass_c2 / photonEnergy ;
338 // G4double phi = twopi * G4UniformRand() ;
339
340 G4double phi,psi=0.;
341
342 //corrected e+ e- angular angular distribution //preliminary!
343
344 // if(photonEnergy>50*MeV)
345 // {
346 phi = SetPhi(photonEnergy);
347 psi = SetPsi(photonEnergy,phi);
348 // }
349 //else
350 // {
351 //psi = G4UniformRand()*2.*pi;
352 //phi = pi; // coplanar
353 // }
354
355 Psi = psi;
356 Phi = phi;
357 //G4cout << "PHI " << phi << G4endl;
358 //G4cout << "PSI " << psi << G4endl;
359
360 G4double phie = psi; //azimuthal angle for the electron
361
362 G4double dirX = sinTheta*cos(phie);
363 G4double dirY = sinTheta*sin(phie);
364 G4double dirZ = cosTheta;
365 G4ThreeVector electronDirection(dirX,dirY,dirZ);
366 // Kinematics of the created pair:
367 // the electron and positron are assumed to have a symetric angular
368 // distribution with respect to the Z axis along the parent photon
369
370 //G4double localEnergyDeposit = 0. ;
371
372 G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
373
374 SystemOfRefChange(gammaDirection0,electronDirection,
375 gammaPolarization0);
376
378 electronDirection,
379 electronKineEnergy);
380
381 // The e+ is always created (even with kinetic energy = 0) for further annihilation
382
383 Ene = positronTotEnergy/electron_mass_c2; // Normalized energy
384
385 cosTheta = 0.;
386 sinTheta = 0.;
387
388 SetTheta(&cosTheta,&sinTheta,Ene);
389 G4double phip = phie+phi; //azimuthal angle for the positron
390
391 dirX = sinTheta*cos(phip);
392 dirY = sinTheta*sin(phip);
393 dirZ = cosTheta;
394 G4ThreeVector positronDirection(dirX,dirY,dirZ);
395
396 G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
397 SystemOfRefChange(gammaDirection0,positronDirection,
398 gammaPolarization0);
399
400 // Create G4DynamicParticle object for the particle2
402 positronDirection, positronKineEnergy);
403
404
405 fvect->push_back(particle1);
406 fvect->push_back(particle2);
407
408
409
410 // Kill the incident photon
411
412
413
414 // Create lists of pointers to DynamicParticles (photons and electrons)
415 // (Is the electron vector necessary? To be checked)
416 // std::vector<G4DynamicParticle*>* photonVector = 0;
417 //std::vector<G4DynamicParticle*> electronVector;
418
422
423}
424
425//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
426
427G4double G4LivermorePolarizedGammaConversionModel::ScreenFunction1(G4double screenVariable)
428{
429 // Compute the value of the screening function 3*phi1 - phi2
430
431 G4double value;
432
433 if (screenVariable > 1.)
434 value = 42.24 - 8.368 * log(screenVariable + 0.952);
435 else
436 value = 42.392 - screenVariable * (7.796 - 1.961 * screenVariable);
437
438 return value;
439}
440
441
442
443G4double G4LivermorePolarizedGammaConversionModel::ScreenFunction2(G4double screenVariable)
444{
445 // Compute the value of the screening function 1.5*phi1 - 0.5*phi2
446
447 G4double value;
448
449 if (screenVariable > 1.)
450 value = 42.24 - 8.368 * log(screenVariable + 0.952);
451 else
452 value = 41.405 - screenVariable * (5.828 - 0.8945 * screenVariable);
453
454 return value;
455}
456
457
458void G4LivermorePolarizedGammaConversionModel::SetTheta(G4double* p_cosTheta, G4double* p_sinTheta, G4double Energy)
459{
460
461 // to avoid computational errors since Theta could be very small
462 // Energy in Normalized Units (!)
463
464 G4double Momentum = sqrt(Energy*Energy -1);
465 G4double Rand = G4UniformRand();
466
467 *p_cosTheta = (Energy*((2*Rand)- 1) + Momentum)/((Momentum*(2*Rand-1))+Energy);
468 *p_sinTheta = (2*sqrt(Rand*(1-Rand)))/(Momentum*(2*Rand-1)+Energy);
469}
470
471
472
473G4double G4LivermorePolarizedGammaConversionModel::SetPhi(G4double Energy)
474{
475
476
477 G4double value = 0.;
478 G4double Ene = Energy/MeV;
479
480 G4double pl[4];
481
482
483 G4double pt[2];
484 G4double xi = 0;
485 G4double xe = 0.;
486 G4double n1=0.;
487 G4double n2=0.;
488
489
490 if (Ene>=50.)
491 {
492 const G4double ay0=5.6, by0=18.6, aa0=2.9, ba0 = 8.16E-3;
493 const G4double aw = 0.0151, bw = 10.7, cw = -410.;
494
495 const G4double axc = 3.1455, bxc = -1.11, cxc = 310.;
496
497 pl[0] = Fln(ay0,by0,Ene);
498 pl[1] = aa0 + ba0*(Ene);
499 pl[2] = Poli(aw,bw,cw,Ene);
500 pl[3] = Poli(axc,bxc,cxc,Ene);
501
502 const G4double abf = 3.1216, bbf = 2.68;
503 pt[0] = -1.4;
504 pt[1] = abf + bbf/Ene;
505
506
507
508 //G4cout << "PL > 50. "<< pl[0] << " " << pl[1] << " " << pl[2] << " " <<pl[3] << " " << G4endl;
509
510 xi = 3.0;
511 xe = Encu(pl,pt,xi);
512 //G4cout << "ENCU "<< xe << G4endl;
513 n1 = Fintlor(pl,pi) - Fintlor(pl,xe);
514 n2 = Finttan(pt,xe) - Finttan(pt,0.);
515 }
516 else
517 {
518 const G4double ay0=0.144, by0=0.11;
519 const G4double aa0=2.7, ba0 = 2.74;
520 const G4double aw = 0.21, bw = 10.8, cw = -58.;
521 const G4double axc = 3.17, bxc = -0.87, cxc = -6.;
522
523 pl[0] = Fln(ay0, by0, Ene);
524 pl[1] = Fln(aa0, ba0, Ene);
525 pl[2] = Poli(aw,bw,cw,Ene);
526 pl[3] = Poli(axc,bxc,cxc,Ene);
527
528 //G4cout << "PL < 50."<< pl[0] << " " << pl[1] << " " << pl[2] << " " <<pl[3] << " " << G4endl;
529 //G4cout << "ENCU "<< xe << G4endl;
530 n1 = Fintlor(pl,pi) - Fintlor(pl,xe);
531
532 }
533
534
535 G4double n=0.;
536 n = n1+n2;
537
538 G4double c1 = 0.;
539 c1 = Glor(pl, xe);
540
541/*
542 G4double xm = 0.;
543 xm = Flor(pl,pl[3])*Glor(pl,pl[3]);
544*/
545
546 G4double r1,r2,r3;
547 G4double xco=0.;
548
549 if (Ene>=50.)
550 {
551 r1= G4UniformRand();
552 if( r1>=n2/n)
553 {
554 do
555 {
556 r2 = G4UniformRand();
557 value = Finvlor(pl,xe,r2);
558 xco = Glor(pl,value)/c1;
559 r3 = G4UniformRand();
560 } while(r3>=xco);
561 }
562 else
563 {
564 value = Finvtan(pt,n,r1);
565 }
566 }
567 else
568 {
569 do
570 {
571 r2 = G4UniformRand();
572 value = Finvlor(pl,xe,r2);
573 xco = Glor(pl,value)/c1;
574 r3 = G4UniformRand();
575 } while(r3>=xco);
576 }
577
578 // G4cout << "PHI = " <<value << G4endl;
579 return value;
580}
581G4double G4LivermorePolarizedGammaConversionModel::SetPsi(G4double Energy, G4double PhiLocal)
582{
583
584 G4double value = 0.;
585 G4double Ene = Energy/MeV;
586
587 G4double p0l[4];
588 G4double ppml[4];
589 G4double p0t[2];
590 G4double ppmt[2];
591
592 G4double xi = 0.;
593 G4double xe0 = 0.;
594 G4double xepm = 0.;
595
596 if (Ene>=50.)
597 {
598 const G4double ay00 = 3.4, by00 = 9.8, aa00 = 1.34, ba00 = 5.3;
599 const G4double aw0 = 0.014, bw0 = 9.7, cw0 = -2.E4;
600 const G4double axc0 = 3.1423, bxc0 = -2.35, cxc0 = 0.;
601 const G4double ay0p = 1.53, by0p = 3.2, aap = 0.67, bap = 8.5E-3;
602 const G4double awp = 6.9E-3, bwp = 12.6, cwp = -3.8E4;
603 const G4double axcp = 2.8E-3,bxcp = -3.133;
604 const G4double abf0 = 3.1213, bbf0 = 2.61;
605 const G4double abfpm = 3.1231, bbfpm = 2.84;
606
607 p0l[0] = Fln(ay00, by00, Ene);
608 p0l[1] = Fln(aa00, ba00, Ene);
609 p0l[2] = Poli(aw0, bw0, cw0, Ene);
610 p0l[3] = Poli(axc0, bxc0, cxc0, Ene);
611
612 ppml[0] = Fln(ay0p, by0p, Ene);
613 ppml[1] = aap + bap*(Ene);
614 ppml[2] = Poli(awp, bwp, cwp, Ene);
615 ppml[3] = Fln(axcp,bxcp,Ene);
616
617 p0t[0] = -0.81;
618 p0t[1] = abf0 + bbf0/Ene;
619 ppmt[0] = -0.6;
620 ppmt[1] = abfpm + bbfpm/Ene;
621
622 //G4cout << "P0L > 50"<< p0l[0] << " " << p0l[1] << " " << p0l[2] << " " <<p0l[3] << " " << G4endl;
623 //G4cout << "PPML > 50"<< ppml[0] << " " << ppml[1] << " " << ppml[2] << " " <<ppml[3] << " " << G4endl;
624
625 xi = 3.0;
626 xe0 = Encu(p0l, p0t, xi);
627 //G4cout << "ENCU1 "<< xe0 << G4endl;
628 xepm = Encu(ppml, ppmt, xi);
629 //G4cout << "ENCU2 "<< xepm << G4endl;
630 }
631 else
632 {
633 const G4double ay00 = 2.82, by00 = 6.35;
634 const G4double aa00 = -1.75, ba00 = 0.25;
635
636 const G4double aw0 = 0.028, bw0 = 5., cw0 = -50.;
637 const G4double axc0 = 3.14213, bxc0 = -2.3, cxc0 = 5.7;
638 const G4double ay0p = 1.56, by0p = 3.6;
639 const G4double aap = 0.86, bap = 8.3E-3;
640 const G4double awp = 0.022, bwp = 7.4, cwp = -51.;
641 const G4double xcp = 3.1486;
642
643 p0l[0] = Fln(ay00, by00, Ene);
644 p0l[1] = aa00+pow(Ene, ba00);
645 p0l[2] = Poli(aw0, bw0, cw0, Ene);
646 p0l[3] = Poli(axc0, bxc0, cxc0, Ene);
647 ppml[0] = Fln(ay0p, by0p, Ene);
648 ppml[1] = aap + bap*(Ene);
649 ppml[2] = Poli(awp, bwp, cwp, Ene);
650 ppml[3] = xcp;
651
652 }
653
654 G4double a,b=0.;
655
656 if (Ene>=50.)
657 {
658 if (PhiLocal>xepm)
659 {
660 b = (ppml[0]+2*ppml[1]*ppml[2]*Flor(ppml,PhiLocal));
661 }
662 else
663 {
664 b = Ftan(ppmt,PhiLocal);
665 }
666 if (PhiLocal>xe0)
667 {
668 a = (p0l[0]+2*p0l[1]*p0l[2]*Flor(p0l,PhiLocal));
669 }
670 else
671 {
672 a = Ftan(p0t,PhiLocal);
673 }
674 }
675 else
676 {
677 b = (ppml[0]+2*ppml[1]*ppml[2]*Flor(ppml,PhiLocal));
678 a = (p0l[0]+2*p0l[1]*p0l[2]*Flor(p0l,PhiLocal));
679 }
680 G4double nr =0.;
681
682 if (b>a)
683 {
684 nr = 1./b;
685 }
686 else
687 {
688 nr = 1./a;
689 }
690
691 G4double r1,r2=0.;
692 G4double r3 =-1.;
693 do
694 {
695 r1 = G4UniformRand();
696 r2 = G4UniformRand();
697 value = r2*pi;
698 r3 = nr*(a*cos(value)*cos(value) + b*sin(value)*sin(value));
699 }while(r1>r3);
700
701 return value;
702}
703
704
705G4double G4LivermorePolarizedGammaConversionModel::Poli
707{
708 G4double value=0.;
709 if(x>0.)
710 {
711 value =(a + b/x + c/(x*x*x));
712 }
713 else
714 {
715 //G4cout << "ERROR in Poli! " << G4endl;
716 }
717 return value;
718}
719G4double G4LivermorePolarizedGammaConversionModel::Fln
720(G4double a, G4double b, G4double x)
721{
722 G4double value=0.;
723 if(x>0.)
724 {
725 value =(a*log(x)-b);
726 }
727 else
728 {
729 //G4cout << "ERROR in Fln! " << G4endl;
730 }
731 return value;
732}
733
734
735G4double G4LivermorePolarizedGammaConversionModel::Encu
736(G4double* p_p1, G4double* p_p2, G4double x0)
737{
738 G4int i=0;
739 G4double fx = 1.;
740 G4double x = x0;
741 const G4double xmax = 3.0;
742
743 for(i=0; i<100; ++i)
744 {
745 fx = (Flor(p_p1,x)*Glor(p_p1,x) - Ftan(p_p2, x))/
746 (Fdlor(p_p1,x) - Fdtan(p_p2,x));
747 x -= fx;
748 if(x > xmax) { return xmax; }
749 // x -= (Flor(p_p1, x)*Glor(p_p1,x) - Ftan(p_p2, x))/
750 // (Fdlor(p_p1,x) - Fdtan(p_p2,x));
751 // fx = Flor(p_p1,x)*Glor(p_p1,x) - Ftan(p_p2, x);
752 // G4cout << std::fabs(fx) << " " << i << " " << x << "dentro ENCU " << G4endl;
753 if(std::fabs(fx) <= x*1.0e-6) { break; }
754 }
755
756 if(x < 0.0) { x = 0.0; }
757 return x;
758}
759
760
761G4double G4LivermorePolarizedGammaConversionModel::Flor(G4double* p_p1, G4double x)
762{
763 G4double value =0.;
764 // G4double y0 = p_p1[0];
765 // G4double A = p_p1[1];
766 G4double w = p_p1[2];
767 G4double xc = p_p1[3];
768
769 value = 1./(pi*(w*w + 4.*(x-xc)*(x-xc)));
770 return value;
771}
772
773
774G4double G4LivermorePolarizedGammaConversionModel::Glor(G4double* p_p1, G4double x)
775{
776 G4double value =0.;
777 G4double y0 = p_p1[0];
778 G4double A = p_p1[1];
779 G4double w = p_p1[2];
780 G4double xc = p_p1[3];
781
782 value = (y0 *pi*(w*w + 4.*(x-xc)*(x-xc)) + 2.*A*w);
783 return value;
784}
785
786
787G4double G4LivermorePolarizedGammaConversionModel::Fdlor(G4double* p_p1, G4double x)
788{
789 G4double value =0.;
790 //G4double y0 = p_p1[0];
791 G4double A = p_p1[1];
792 G4double w = p_p1[2];
793 G4double xc = p_p1[3];
794
795 value = (-16.*A*w*(x-xc))/
796 (pi*(w*w+4.*(x-xc)*(x-xc))*(w*w+4.*(x-xc)*(x-xc)));
797 return value;
798}
799
800
801G4double G4LivermorePolarizedGammaConversionModel::Fintlor(G4double* p_p1, G4double x)
802{
803 G4double value =0.;
804 G4double y0 = p_p1[0];
805 G4double A = p_p1[1];
806 G4double w = p_p1[2];
807 G4double xc = p_p1[3];
808
809 value = y0*x + A*atan( 2*(x-xc)/w) / pi;
810 return value;
811}
812
813
814G4double G4LivermorePolarizedGammaConversionModel::Finvlor(G4double* p_p1, G4double x, G4double r)
815{
816 G4double value = 0.;
817 G4double nor = 0.;
818 //G4double y0 = p_p1[0];
819 // G4double A = p_p1[1];
820 G4double w = p_p1[2];
821 G4double xc = p_p1[3];
822
823 nor = atan(2.*(pi-xc)/w)/(2.*pi*w) - atan(2.*(x-xc)/w)/(2.*pi*w);
824 value = xc - (w/2.)*tan(-2.*r*nor*pi*w+atan(2*(xc-x)/w));
825
826 return value;
827}
828
829
830G4double G4LivermorePolarizedGammaConversionModel::Ftan(G4double* p_p1, G4double x)
831{
832 G4double value =0.;
833 G4double a = p_p1[0];
834 G4double b = p_p1[1];
835
836 value = a /(x-b);
837 return value;
838}
839
840
841G4double G4LivermorePolarizedGammaConversionModel::Fdtan(G4double* p_p1, G4double x)
842{
843 G4double value =0.;
844 G4double a = p_p1[0];
845 G4double b = p_p1[1];
846
847 value = -1.*a / ((x-b)*(x-b));
848 return value;
849}
850
851
852G4double G4LivermorePolarizedGammaConversionModel::Finttan(G4double* p_p1, G4double x)
853{
854 G4double value =0.;
855 G4double a = p_p1[0];
856 G4double b = p_p1[1];
857
858
859 value = a*log(b-x);
860 return value;
861}
862
863
864G4double G4LivermorePolarizedGammaConversionModel::Finvtan(G4double* p_p1, G4double cnor, G4double r)
865{
866 G4double value =0.;
867 G4double a = p_p1[0];
868 G4double b = p_p1[1];
869
870 value = b*(1-exp(r*cnor/a));
871
872 return value;
873}
874
875
876
877
878//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
879
880G4ThreeVector G4LivermorePolarizedGammaConversionModel::SetPerpendicularVector(G4ThreeVector& a)
881{
882 G4double dx = a.x();
883 G4double dy = a.y();
884 G4double dz = a.z();
885 G4double x = dx < 0.0 ? -dx : dx;
886 G4double y = dy < 0.0 ? -dy : dy;
887 G4double z = dz < 0.0 ? -dz : dz;
888 if (x < y) {
889 return x < z ? G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
890 }else{
891 return y < z ? G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
892 }
893}
894
895//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
896
897G4ThreeVector G4LivermorePolarizedGammaConversionModel::GetRandomPolarization(G4ThreeVector& direction0)
898{
899 G4ThreeVector d0 = direction0.unit();
900 G4ThreeVector a1 = SetPerpendicularVector(d0); //different orthogonal
901 G4ThreeVector a0 = a1.unit(); // unit vector
902
903 G4double rand1 = G4UniformRand();
904
905 G4double angle = twopi*rand1; // random polar angle
906 G4ThreeVector b0 = d0.cross(a0); // cross product
907
909
910 c.setX(std::cos(angle)*(a0.x())+std::sin(angle)*b0.x());
911 c.setY(std::cos(angle)*(a0.y())+std::sin(angle)*b0.y());
912 c.setZ(std::cos(angle)*(a0.z())+std::sin(angle)*b0.z());
913
914 G4ThreeVector c0 = c.unit();
915
916 return c0;
917
918}
919
920//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
921
922G4ThreeVector G4LivermorePolarizedGammaConversionModel::GetPerpendicularPolarization
923(const G4ThreeVector& gammaDirection, const G4ThreeVector& gammaPolarization) const
924{
925
926 //
927 // The polarization of a photon is always perpendicular to its momentum direction.
928 // Therefore this function removes those vector component of gammaPolarization, which
929 // points in direction of gammaDirection
930 //
931 // Mathematically we search the projection of the vector a on the plane E, where n is the
932 // plains normal vector.
933 // The basic equation can be found in each geometry book (e.g. Bronstein):
934 // p = a - (a o n)/(n o n)*n
935
936 return gammaPolarization - gammaPolarization.dot(gammaDirection)/gammaDirection.dot(gammaDirection) * gammaDirection;
937}
938
939//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
940
941
942void G4LivermorePolarizedGammaConversionModel::SystemOfRefChange
943 (G4ThreeVector& direction0,G4ThreeVector& direction1,
944 G4ThreeVector& polarization0)
945{
946 // direction0 is the original photon direction ---> z
947 // polarization0 is the original photon polarization ---> x
948 // need to specify y axis in the real reference frame ---> y
949 G4ThreeVector Axis_Z0 = direction0.unit();
950 G4ThreeVector Axis_X0 = polarization0.unit();
951 G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_X0)).unit(); // to be confirmed;
952
953 G4double direction_x = direction1.getX();
954 G4double direction_y = direction1.getY();
955 G4double direction_z = direction1.getZ();
956
957 direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
958
959}
960
961
962
963
CLHEP::Hep3Vector G4ThreeVector
@ fStopAndKill
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
double z() const
Hep3Vector unit() const
double getZ() const
double x() const
void setY(double)
double y() const
Hep3Vector cross(const Hep3Vector &) const
double dot(const Hep3Vector &) const
void setZ(double)
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
Definition: SpaceVector.cc:237
double mag() const
double getX() const
double howOrthogonal(const Hep3Vector &v) const
Definition: SpaceVector.cc:219
void setX(double)
double getY() const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
G4double GetfCoulomb() const
Definition: G4Element.hh:201
G4IonisParamElm * GetIonisation() const
Definition: G4Element.hh:209
G4double GetlogZ3() const
G4double GetZ3() const
G4LivermorePolarizedGammaConversionModel(const G4ParticleDefinition *p=0, const G4String &nam="LivermorePolarizedGammaConversion")
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
static G4Positron * Positron()
Definition: G4Positron.cc:94
G4double FindValue(G4int Z, G4double e) const
void LoadData(const G4String &dataFile)
void Initialise(G4VDataSetAlgorithm *interpolation=0, G4double minE=250 *CLHEP::eV, G4double maxE=100 *CLHEP::GeV, G4int numberOfBins=200, G4double unitE=CLHEP::MeV, G4double unitData=CLHEP::barn, G4int minZ=1, G4int maxZ=99)
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:585
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:109
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:529
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:522
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:459
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:592
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
Definition: G4VEmModel.cc:123
void ProposeTrackStatus(G4TrackStatus status)
const G4double pi