Geant4  10.02
G4LivermorePolarizedPhotoElectricGDModel.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: G4LivermorePolarizedPhotoElectricGDModel.hh,v 1.2 2010-11-23 16:42:15 flongo Exp $
27 //
28 // Authors: G.Depaola & F.Longo
29 //
30 
32 #include "G4PhysicalConstants.hh"
33 #include "G4SystemOfUnits.hh"
34 #include "G4LossTableManager.hh"
35 #include "G4VAtomDeexcitation.hh"
36 #include "G4AtomicShell.hh"
37 #include "G4Gamma.hh"
38 #include "G4Electron.hh"
39 #include "G4LPhysicsFreeVector.hh"
41 //#include "G4ProductionCutsTable.hh"
42 
43 #include <vector>
44 
45 
48 std::vector<G4double>* G4LivermorePolarizedPhotoElectricGDModel::fParam[] = {0};
54 
55 
56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
57 
58 using namespace std;
59 
60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
61 
63  const G4String& nam)
64  :G4VEmModel(nam),fParticleChange(0),maxZ(99),
65  nShellLimit(100), fDeexcitationActive(false), isInitialised(false), fAtomDeexcitation(0)
66  // crossSectionHandler(0), shellCrossSectionHandler(0)
67 {
68 
69  // lowEnergyLimit = 10 * eV; // SI - Could be 10 eV ?
70  // highEnergyLimit = 100 * GeV;
71 
72  verboseLevel= 0;
73  // Verbosity scale:
74  // 0 = nothing
75  // 1 = warning for energy non-conservation
76  // 2 = details of energy budget
77  // 3 = calculation of cross sections, file openings, sampling of atoms
78  // 4 = entering in methods
79 
82 
83 
84  SetDeexcitationFlag(true);
85  fSandiaCof.resize(4,0.0);
86  fCurrSection = 0.0;
87 
88  if (verboseLevel > 0) {
89  G4cout << "Livermore Polarized PhotoElectric is constructed "
90  << " nShellLimit "
91  << nShellLimit << G4endl;
92  }
93 
94 
95 }
96 
97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
98 
100 {
101  // delete crossSectionHandler;
102  //delete shellCrossSectionHandler;
103  if(IsMaster()) {
104  delete fShellCrossSection;
105  for(G4int i=0; i<maxZ; ++i) {
106  delete fParam[i];
107  fParam[i] = 0;
108  delete fCrossSection[i];
109  fCrossSection[i] = 0;
110  delete fCrossSectionLE[i];
111  fCrossSectionLE[i] = 0;
112  }
113  }
114 }
115 
116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
117 
118 void
120  const G4ParticleDefinition*,
121  const G4DataVector&)
122 {
123  if (verboseLevel > 2) {
124  G4cout << "Calling G4LivermorePolarizedPhotoElectricGDModel::Initialise()" << G4endl;
125  }
126 
127 
128 
129  if(IsMaster()) {
130 
131  if(!fWater) {
132  fWater = G4Material::GetMaterial("G4_WATER", false);
133  if(fWater) { fWaterEnergyLimit = 13.6*eV; }
134  }
135 
137 
138  char* path = getenv("G4LEDATA");
139 
140  G4ProductionCutsTable* theCoupleTable =
142  G4int numOfCouples = theCoupleTable->GetTableSize();
143 
144  for(G4int i=0; i<numOfCouples; ++i) {
145  const G4MaterialCutsCouple* couple =
146  theCoupleTable->GetMaterialCutsCouple(i);
147  const G4Material* material = couple->GetMaterial();
148  const G4ElementVector* theElementVector = material->GetElementVector();
149  G4int nelm = material->GetNumberOfElements();
150 
151  for (G4int j=0; j<nelm; ++j) {
152  G4int Z = (G4int)(*theElementVector)[j]->GetZ();
153  if(Z < 1) { Z = 1; }
154  else if(Z > maxZ) { Z = maxZ; }
155  if(!fCrossSection[Z]) { ReadData(Z, path); }
156  }
157  }
158  }
159  //
160  if (verboseLevel > 2) {
161  G4cout << "Loaded cross section files for LivermorePhotoElectric model"
162  << G4endl;
163  }
164  if(!isInitialised) {
165  isInitialised = true;
167 
169  }
170  fDeexcitationActive = false;
171  if(fAtomDeexcitation) {
173  }
174 
175  if (verboseLevel > 0) {
176  G4cout << "LivermorePolarizedPhotoElectric model is initialized " << G4endl
177  << G4endl;
178  }
179 }
180 
181 
182 
183 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
184 
186  const G4ParticleDefinition*,
187  G4double GammaEnergy,
188  G4double ZZ, G4double,
190 {
191  if (verboseLevel > 3) {
192  G4cout << "G4LivermorePolarizedPhotoElectricGDModel::ComputeCrossSectionPerAtom():"
193  << " Z= " << ZZ << " R(keV)= " << GammaEnergy/keV << G4endl;
194  }
195  G4double cs = 0.0;
196  G4int Z = G4lrint(ZZ);
197  if(Z < 1 || Z >= maxZ) { return cs; }
198 
199  // if element was not initialised
200  // do initialisation safely for MT mode
201  if(!fCrossSection[Z]) {
202  InitialiseForElement(0, Z);
203  if(!fCrossSection[Z]) { return cs; }
204  }
205 
206  G4int idx = fNShells[Z]*6 - 4;
207  if (GammaEnergy < (*(fParam[Z]))[idx-1]) { GammaEnergy = (*(fParam[Z]))[idx-1]; }
208 
209  G4double x1 = 1.0/GammaEnergy;
210  G4double x2 = x1*x1;
211  G4double x3 = x2*x1;
212 
213  // parameterisation
214  if(GammaEnergy >= (*(fParam[Z]))[0]) {
215  G4double x4 = x2*x2;
216  cs = x1*((*(fParam[Z]))[idx] + x1*(*(fParam[Z]))[idx+1]
217  + x2*(*(fParam[Z]))[idx+2] + x3*(*(fParam[Z]))[idx+3]
218  + x4*(*(fParam[Z]))[idx+4]);
219  // high energy part
220  } else if (GammaEnergy >= (*(fParam[Z]))[1]) {
221  cs = x3*(fCrossSection[Z])->Value(GammaEnergy);
222 
223  // low energy part
224  } else {
225  cs = x3*(fCrossSectionLE[Z])->Value(GammaEnergy);
226  }
227  if (verboseLevel > 1) {
228  G4cout << "LivermorePolarizedPhotoElectricGDModel: E(keV)= " << GammaEnergy/keV
229  << " Z= " << Z << " cross(barn)= " << cs/barn << G4endl;
230  }
231  return cs;
232 }
233 
234 
235 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
236 
238  std::vector<G4DynamicParticle*>* fvect,
239  const G4MaterialCutsCouple* couple,
240  const G4DynamicParticle* aDynamicGamma,
241  G4double,
242  G4double)
243 {
244  if (verboseLevel > 3) {
245  G4cout << "Calling SampleSecondaries() of G4LivermorePolarizedPhotoElectricGDModel"
246  << G4endl;
247  }
248 
249  G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
250  if (verboseLevel > 3) {
251  G4cout << "G4LivermorePolarizedPhotoElectricGDModel::SampleSecondaries() Egamma(keV)= "
252  << photonEnergy/keV << G4endl;
253  }
254 
255  G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
256  G4ThreeVector photonDirection = aDynamicGamma->GetMomentumDirection();
257 
258  // kill incident photon
261 
262  // low-energy photo-effect in water - full absorption
263 
264  const G4Material* material = couple->GetMaterial();
265  if(fWater && (material == fWater ||
266  material->GetBaseMaterial() == fWater)) {
267  if(photonEnergy <= fWaterEnergyLimit) {
269  return;
270  }
271  }
272 
273  // Protection: a polarisation parallel to the
274  // direction causes problems;
275  // in that case find a random polarization
276 
277  // Make sure that the polarization vector is perpendicular to the
278  // gamma direction. If not
279 
280  if(!(gammaPolarization0.isOrthogonal(photonDirection, 1e-6))||(gammaPolarization0.mag()==0))
281  { // only for testing now
282  gammaPolarization0 = GetRandomPolarization(photonDirection);
283  }
284  else
285  {
286  if ( gammaPolarization0.howOrthogonal(photonDirection) != 0)
287  {
288  gammaPolarization0 = GetPerpendicularPolarization(photonDirection, gammaPolarization0);
289  }
290  }
291 
292  // End of Protection
293 
294  // G4double E0_m = photonEnergy / electron_mass_c2 ;
295 
296  // Shell
297 
298  // Select randomly one element in the current material
299  //G4cout << "Select random atom Egamma(keV)= " << photonEnergy/keV << G4endl;
300  const G4Element* elm = SelectRandomAtom(material, theGamma, photonEnergy);
301  G4int Z = G4lrint(elm->GetZ());
302 
303 
304  // Select the ionised shell in the current atom according to shell
305  // cross sections
306  // G4cout << "Select random shell Z= " << Z << G4endl;
307 
308  if(Z >= maxZ) { Z = maxZ-1; }
309 
310  // element was not initialised gamma should be absorbed
311  if(!fCrossSection[Z]) {
313  return;
314  }
315 
316  // shell index
317  size_t shellIdx = 0;
318  size_t nn = fNShellsUsed[Z];
319 
320  if(nn > 1) {
321  if(photonEnergy >= (*(fParam[Z]))[0]) {
322  G4double x1 = 1.0/photonEnergy;
323  G4double x2 = x1*x1;
324  G4double x3 = x2*x1;
325  G4double x4 = x3*x1;
326  G4int idx = nn*6 - 4;
327  // when do sampling common factors are not taken into account
328  // so cross section is not real
329  G4double cs0 = G4UniformRand()*((*(fParam[Z]))[idx]
330  + x1*(*(fParam[Z]))[idx+1]
331  + x2*(*(fParam[Z]))[idx+2]
332  + x3*(*(fParam[Z]))[idx+3]
333  + x4*(*(fParam[Z]))[idx+4]);
334  for(shellIdx=0; shellIdx<nn; ++shellIdx) {
335  idx = shellIdx*6 + 2;
336  if(photonEnergy > (*(fParam[Z]))[idx-1]) {
337  G4double cs = (*(fParam[Z]))[idx] + x1*(*(fParam[Z]))[idx+1]
338  + x2*(*(fParam[Z]))[idx+2] + x3*(*(fParam[Z]))[idx+3]
339  + x4*(*(fParam[Z]))[idx+4];
340  if(cs >= cs0) { break; }
341  }
342  }
343  if(shellIdx >= nn) { shellIdx = nn-1; }
344 
345  } else {
346 
347  // when do sampling common factors are not taken into account
348  // so cross section is not real
349  G4double cs = G4UniformRand();
350 
351  if(photonEnergy >= (*(fParam[Z]))[1]) {
352  cs *= (fCrossSection[Z])->Value(photonEnergy);
353  } else {
354  cs *= (fCrossSectionLE[Z])->Value(photonEnergy);
355  }
356 
357  for(size_t j=0; j<nn; ++j) {
358  shellIdx = (size_t)fShellCrossSection->GetComponentID(Z, j);
359  if(photonEnergy > (*(fParam[Z]))[6*shellIdx+1]) {
360  cs -= fShellCrossSection->GetValueForComponent(Z, j, photonEnergy);
361  }
362  if(cs <= 0.0 || j+1 == nn) { break; }
363  }
364  }
365  }
366 
367  G4double bindingEnergy = (*(fParam[Z]))[shellIdx*6 + 1];
368  //G4cout << "Z= " << Z << " shellIdx= " << shellIdx
369  // << " nShells= " << fNShells[Z]
370  // << " Ebind(keV)= " << bindingEnergy/keV
371  // << " Egamma(keV)= " << photonEnergy/keV << G4endl;
372 
373  const G4AtomicShell* shell = 0;
374 
375  // no de-excitation from the last shell
376  if(fDeexcitationActive && shellIdx + 1 < nn) {
378  shell = fAtomDeexcitation->GetAtomicShell(Z, as);
379  }
380 
381  // If binding energy of the selected shell is larger than photon energy
382  // do not generate secondaries
383  if(photonEnergy < bindingEnergy) {
385  return;
386  }
387 
388 
389  // Electron
390 
391  G4double eKineticEnergy = photonEnergy - bindingEnergy;
392  G4double edep = bindingEnergy;
393 
394  G4double costheta = SetCosTheta(eKineticEnergy);
395  G4double sintheta = sqrt(1. - costheta*costheta);
396  G4double phi = SetPhi(photonEnergy,eKineticEnergy,costheta);
397  G4double dirX = sintheta*cos(phi);
398  G4double dirY = sintheta*sin(phi);
399  G4double dirZ = costheta;
400  G4ThreeVector electronDirection(dirX, dirY, dirZ);
401  SystemOfRefChange(photonDirection, electronDirection, gammaPolarization0);
403  electronDirection,
404  eKineticEnergy);
405  fvect->push_back(electron);
406 
407 
408 // Deexcitation
409 // Sample deexcitation
410  if(shell) {
411  G4int index = couple->GetIndex();
413  G4int nbefore = fvect->size();
414 
415  fAtomDeexcitation->GenerateParticles(fvect, shell, Z, index);
416  G4int nafter = fvect->size();
417  if(nafter > nbefore) {
418  G4double esec = 0.0;
419  for (G4int j=nbefore; j<nafter; ++j) {
420 
421  G4double e = ((*fvect)[j])->GetKineticEnergy();
422  if(esec + e > edep) {
423  // correct energy in order to have energy balance
424  e = edep - esec;
425  ((*fvect)[j])->SetKineticEnergy(e);
426  esec += e;
427  // delete the rest of secondaries (should not happens)
428  for (G4int jj=nafter-1; jj>j; --jj) {
429  delete (*fvect)[jj];
430  fvect->pop_back();
431  }
432  break;
433  }
434  esec += e;
435  }
436  edep -= esec;
437  }
438  }
439  }
440  // energy balance - excitation energy left
441  if(edep > 0.0) {
443  }
444 }
445 
446 
447 
448 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
450 {
451  if (verboseLevel > 1)
452  {
453  G4cout << "Calling ReadData() of G4LivermorePolarizedPhotoElectricGDModel"
454  << G4endl;
455  }
456 
457  if(fCrossSection[Z]) { return; }
458 
459  const char* datadir = path;
460 
461  if(!datadir)
462  {
463  datadir = getenv("G4LEDATA");
464  if(!datadir)
465  {
466  G4Exception("G4LivermorePhotoElectricModel::ReadData()",
467  "em0006",FatalException,
468  "Environment variable G4LEDATA not defined");
469  return;
470  }
471  }
472 
473  // spline for photoeffect total x-section above K-shell
475  fCrossSection[Z]->SetSpline(true);
476 
477  std::ostringstream ost;
478  ost << datadir << "/livermore/phot/pe-cs-" << Z <<".dat";
479  std::ifstream fin(ost.str().c_str());
480  if( !fin.is_open()) {
482  ed << "G4LivermorePolarizedPhotoElectricGDModel data file <" << ost.str().c_str()
483  << "> is not opened!" << G4endl;
484  G4Exception("G4LivermorePolarizedPhotoElectricGDModel::ReadData()",
485  "em0003",FatalException,
486  ed,"G4LEDATA version should be G4EMLOW6.32 or later.");
487  return;
488  } else {
489  if(verboseLevel > 3) { G4cout << "File " << ost.str().c_str()
490  << " is opened by G4LivermorePolarizedPhotoElectricGDModel" << G4endl;}
491  fCrossSection[Z]->Retrieve(fin, true);
493  fin.close();
494  }
495 
496  fParam[Z] = new std::vector<G4double>;
497 
498  // read fit parameters
499  G4int n1 = 0;
500  G4int n2 = 0;
501  G4double x;
502  std::ostringstream ost1;
503  ost1 << datadir << "/livermore/phot/pe-" << Z <<".dat";
504  std::ifstream fin1(ost1.str().c_str());
505  if( !fin1.is_open()) {
507  ed << "G4LivermorePolarizedPhotoElectricGDModel data file <" << ost1.str().c_str()
508  << "> is not opened!" << G4endl;
509  G4Exception("G4LivermorePolarizedPhotoElectricGDModel::ReadData()",
510  "em0003",FatalException,
511  ed,"G4LEDATA version should be G4EMLOW6.32 or later.");
512  return;
513  } else {
514  if(verboseLevel > 3) {
515  G4cout << "File " << ost1.str().c_str()
516  << " is opened by G4LivermorePolarizedPhotoElectricGDModel" << G4endl;
517  }
518  fin1 >> n1;
519  if(fin1.fail()) { return; }
520  if(0 > n1 || n1 >= INT_MAX) { n1 = 0; }
521 
522  fin1 >> n2;
523  if(fin1.fail()) { return; }
524  if(0 > n2 || n2 >= INT_MAX) { n2 = 0; }
525 
526  fin1 >> x;
527  if(fin1.fail()) { return; }
528 
529  fNShells[Z] = n1;
530  fParam[Z]->reserve(6*n1+1);
531  fParam[Z]->push_back(x*MeV);
532  for(G4int i=0; i<n1; ++i) {
533  for(G4int j=0; j<6; ++j) {
534  fin1 >> x;
535  if(0 == j) { x *= MeV; }
536  else { x *= barn; }
537  fParam[Z]->push_back(x);
538  }
539  }
540  fin1.close();
541  }
542  // there is a possibility to used only main shells
543  if(nShellLimit < n2) { n2 = nShellLimit; }
545  fNShellsUsed[Z] = n2;
546 
547  if(1 < n2) {
548  std::ostringstream ost2;
549  ost2 << datadir << "/livermore/phot/pe-ss-cs-" << Z <<".dat";
550  std::ifstream fin2(ost2.str().c_str());
551  if( !fin2.is_open()) {
553  ed << "G4LivermorePolarizedPhotoElectricGDModel data file <" << ost2.str().c_str()
554  << "> is not opened!" << G4endl;
555  G4Exception("G4LivermorePolarizedPhotoElectricGDModel::ReadData()",
556  "em0003",FatalException,
557  ed,"G4LEDATA version should be G4EMLOW6.32 or later.");
558  return;
559  } else {
560  if(verboseLevel > 3) {
561  G4cout << "File " << ost2.str().c_str()
562  << " is opened by G4LivermorePolarizedPhotoElectricGDModel" << G4endl;
563  }
564 
565  G4int n3, n4;
566  G4double y;
567  for(G4int i=0; i<n2; ++i) {
568  fin2 >> x >> y >> n3 >> n4;
569  G4LPhysicsFreeVector* v = new G4LPhysicsFreeVector(n3, x, y);
570  for(G4int j=0; j<n3; ++j) {
571  fin2 >> x >> y;
572  v->PutValues(j, x*MeV, y*barn);
573  }
574  fShellCrossSection->AddComponent(Z, n4, v);
575  }
576  fin2.close();
577  }
578  }
579 
580  // no spline for photoeffect total x-section below K-shell
581  if(1 < fNShells[Z]) {
583 
584  std::ostringstream ost3;
585  ost3 << datadir << "/livermore/phot/pe-le-cs-" << Z <<".dat";
586  std::ifstream fin3(ost3.str().c_str());
587  if( !fin3.is_open()) {
589  ed << "G4LivermorePolarizedPhotoElectricGDModel data file <" << ost3.str().c_str()
590  << "> is not opened!" << G4endl;
591  G4Exception("G4LivermorePolarizedPhotoElectricGDModel::ReadData()",
592  "em0003",FatalException,
593  ed,"G4LEDATA version should be G4EMLOW6.32 or later.");
594  return;
595  } else {
596  if(verboseLevel > 3) {
597  G4cout << "File " << ost3.str().c_str()
598  << " is opened by G4LivermorePolarizedPhotoElectricGDModel" << G4endl;
599  }
600  fCrossSectionLE[Z]->Retrieve(fin3, true);
602  fin3.close();
603  }
604  }
605 }
606 
607 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
608 
609 
611 {
612  G4double rand1,rand2,onemcost,greject;
613  G4double masarep = 510.99906*keV;
614 
615  G4double gamma = 1. + energyE/masarep;
616  G4double gamma2 = gamma*gamma;
617 
618  G4double beta = sqrt((gamma2 - 1.)/gamma2);
619 
620  G4double alfa = 1./beta - 1.;
621 
622  G4double g1 = 0.5*beta*gamma*(gamma-1.)*(gamma-2.);
623 
624  G4double alfap2 = alfa+2.;
625 
626  G4double grejectmax = 2.*(g1+1./alfa);
627 
628  do
629  {
630  rand1 = G4UniformRand();
631  onemcost = 2.*alfa*(2.*rand1 + alfap2 * sqrt(rand1))/
632  (alfap2*alfap2 - 4.*rand1);
633  greject = (2. - onemcost)*(g1+1./(alfa+onemcost));
634  rand2 = G4UniformRand();
635  }
636  while (rand2*grejectmax > greject);
637  G4double cosTheta = 1. - onemcost;
638  return cosTheta;
639 }
640 
641 
643  G4double E_energy,
644  G4double costheta)
645 {
646  G4double epsilon = E_energy/electron_mass_c2;
647  G4double k = Ph_energy/electron_mass_c2;
648  G4double gamma = 1. + epsilon;
649  G4double gamma2 = gamma*gamma;
650  G4double beta = sqrt((gamma2 - 1.)/gamma2);
651 
652  G4double d = (2./(k*gamma*(1-beta*costheta))-1)*(1/k);
653 
654  G4double norm_factor = 1 +2*d;
655 
656  G4double rnd1;
657  G4double rnd2;
658  G4double phi, phiprob;
659 
660  do
661  {
662  rnd1 =G4UniformRand();
663  rnd2 =G4UniformRand();
664  phi = rnd1*twopi;
665  phiprob = 1 +2*d*cos(phi)*cos(phi);
666  }
667  while (rnd2*norm_factor > phiprob);
668  return phi;
669 }
670 
671 
672 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
673 
675 {
676  G4double dx = a.x();
677  G4double dy = a.y();
678  G4double dz = a.z();
679  G4double x = dx < 0.0 ? -dx : dx;
680  G4double y = dy < 0.0 ? -dy : dy;
681  G4double z = dz < 0.0 ? -dz : dz;
682  if (x < y) {
683  return x < z ? G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
684  }else{
685  return y < z ? G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
686  }
687 }
688 
689 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
690 
692 {
693  G4ThreeVector d0 = direction0.unit();
694  G4ThreeVector a1 = SetPerpendicularVector(d0); //different orthogonal
695  G4ThreeVector a0 = a1.unit(); // unit vector
696 
697  G4double rand1 = G4UniformRand();
698 
699  G4double angle = twopi*rand1; // random polar angle
700  G4ThreeVector b0 = d0.cross(a0); // cross product
701 
702  G4ThreeVector c;
703 
704  c.setX(std::cos(angle)*(a0.x())+std::sin(angle)*b0.x());
705  c.setY(std::cos(angle)*(a0.y())+std::sin(angle)*b0.y());
706  c.setZ(std::cos(angle)*(a0.z())+std::sin(angle)*b0.z());
707 
708  G4ThreeVector c0 = c.unit();
709 
710  return c0;
711 
712 }
713 
714 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
715 
717 (const G4ThreeVector& gammaDirection, const G4ThreeVector& gammaPolarization) const
718 {
719 
720  //
721  // The polarization of a photon is always perpendicular to its momentum direction.
722  // Therefore this function removes those vector component of gammaPolarization, which
723  // points in direction of gammaDirection
724  //
725 
726  // Mathematically we search the projection of the vector a on the plane E, where n is the
727  // plains normal vector.
728  // The basic equation can be found in each geometry book (e.g. Bronstein):
729  // p = a - (a o n)/(n o n)*n
730 
731  return gammaPolarization - gammaPolarization.dot(gammaDirection)/gammaDirection.dot(gammaDirection) * gammaDirection;
732 
733 }
734 
735 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
736 
737 
739 (G4ThreeVector& direction0,G4ThreeVector& direction1,
740  G4ThreeVector& polarization0)
741 {
742  // direction0 is the original photon direction ---> z
743  // polarization0 is the original photon polarization ---> x
744  // need to specify y axis in the real reference frame ---> y
745  G4ThreeVector Axis_Z0 = direction0.unit();
746  G4ThreeVector Axis_X0 = polarization0.unit();
747  G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_X0)).unit(); // to be confirmed;
748 
749  G4double direction_x = direction1.getX();
750  G4double direction_y = direction1.getY();
751  G4double direction_z = direction1.getZ();
752 
753  direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
754 
755 }
756 
757 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
758 
759 #include "G4AutoLock.hh"
760 namespace { G4Mutex LivermorePolarizedPhotoElectricGDModelMutex = G4MUTEX_INITIALIZER; }
761 
763  const G4ParticleDefinition*, G4int Z)
764 {
765  G4AutoLock l(&LivermorePolarizedPhotoElectricGDModelMutex);
766  // G4cout << "G4LivermorePhotoElectricModel::InitialiseForElement Z= "
767  // << Z << G4endl;
768  if(!fCrossSection[Z]) { ReadData(Z); }
769  l.unlock();
770 }
771 
772 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
773 
774 
const G4double a0
void SystemOfRefChange(G4ThreeVector &direction0, G4ThreeVector &direction1, G4ThreeVector &polarization0)
void PutValues(size_t binNumber, G4double binValue, G4double dataValue)
static const double MeV
Definition: G4SIunits.hh:211
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
static G4LossTableManager * Instance()
G4bool IsFluoActive() const
void AddComponent(G4int Z, G4int id, G4PhysicsVector *v)
std::vector< G4Element * > G4ElementVector
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4double GetKineticEnergy() const
CLHEP::Hep3Vector G4ThreeVector
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:604
G4double z
Definition: TRTMaterials.hh:39
static const G4double a1
G4double GetZ() const
Definition: G4Element.hh:131
G4bool IsMaster() const
Definition: G4VEmModel.hh:718
G4double a
Definition: TRTMaterials.hh:39
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:190
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetSpline(G4bool)
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
G4int GetComponentID(G4int Z, size_t idx)
#define G4UniformRand()
Definition: Randomize.hh:97
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
static const double twopi
Definition: G4SIunits.hh:75
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
virtual void ScaleVector(G4double factorE, G4double factorV)
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define INT_MAX
Definition: templates.hh:111
static G4ProductionCutsTable * GetProductionCutsTable()
static const double eV
Definition: G4SIunits.hh:212
G4int G4Mutex
Definition: G4Threading.hh:173
virtual void InitialiseForElement(const G4ParticleDefinition *, G4int Z)
G4ThreeVector GetRandomPolarization(G4ThreeVector &direction0)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
int G4lrint(double ad)
Definition: templates.hh:163
static const G4double c0
G4ThreeVector GetPerpendicularPolarization(const G4ThreeVector &direction0, const G4ThreeVector &polarization0) const
const G4double x[NPOINTSGL]
const G4ThreeVector & GetPolarization() const
virtual G4bool Retrieve(std::ifstream &fIn, G4bool ascii=false)
G4double GetValueForComponent(G4int Z, size_t idx, G4double kinEnergy)
const G4Material * GetBaseMaterial() const
Definition: G4Material.hh:233
static G4Electron * Electron()
Definition: G4Electron.cc:94
void SetProposedKineticEnergy(G4double proposedKinEnergy)
#define G4endl
Definition: G4ios.hh:61
size_t GetNumberOfElements() const
Definition: G4Material.hh:186
G4VAtomDeexcitation * AtomDeexcitation()
static const double barn
Definition: G4SIunits.hh:104
static const double keV
Definition: G4SIunits.hh:213
double G4double
Definition: G4Types.hh:76
void ProposeTrackStatus(G4TrackStatus status)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
void SetDeexcitationFlag(G4bool val)
Definition: G4VEmModel.hh:781
G4LivermorePolarizedPhotoElectricGDModel(const G4String &nam="LivermorePolarizedPhotoElectric")
G4double bindingEnergy(G4int A, G4int Z)
void InitialiseForComponent(G4int Z, G4int nComponents=0)
static const G4double b0
double epsilon(double density, double temperature)
G4AtomicShellEnumerator
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:544
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:134
virtual G4double Value(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
Definition: G4VEmModel.cc:369
const G4Material * GetMaterial() const