293{
294
295
297 G4double g4d_limit = std::pow(10.,-g4d_order);
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
315
316 if (verboseLevel > 3) {
317 G4cout <<
"G4LowEPPolarizedComptonModel::SampleSecondaries() E(MeV)= "
320 }
321
322
324 return ;
325
326 G4double e0m = photonEnergy0 / electron_mass_c2 ;
328
329
330
331
332
334
335
336
337 if (!(photonPolarization0.
isOrthogonal(photonDirection0, 1e-6))||(photonPolarization0.
mag()==0))
338 {
339 photonPolarization0 = GetRandomPolarization(photonDirection0);
340 }
341
342 else
343 {
344 if ((photonPolarization0.
howOrthogonal(photonDirection0) !=0) && (photonPolarization0.
howOrthogonal(photonDirection0) > g4d_limit))
345 {
346 photonPolarization0 = GetPerpendicularPolarization(photonDirection0,photonPolarization0);
347 }
348 }
349
350
351
355
356 G4double LowEPPCepsilon0 = 1. / (1. + 2. * e0m);
357 G4double LowEPPCepsilon0Sq = LowEPPCepsilon0 * LowEPPCepsilon0;
358 G4double alpha1 = -std::log(LowEPPCepsilon0);
359 G4double alpha2 = 0.5 * (1. - LowEPPCepsilon0Sq);
360
361 G4double wlPhoton = h_Planck*c_light/photonEnergy0;
362
363
369
370 if (verboseLevel > 3) {
371 G4cout <<
"Started loop to sample gamma energy" <<
G4endl;
372 }
373
374 do
375 {
377 {
379 LowEPPCepsilonSq = LowEPPCepsilon * LowEPPCepsilon;
380 }
381 else
382 {
383 LowEPPCepsilonSq = LowEPPCepsilon0Sq + (1. - LowEPPCepsilon0Sq) *
G4UniformRand();
384 LowEPPCepsilon = std::sqrt(LowEPPCepsilonSq);
385 }
386
387 oneCosT = (1. - LowEPPCepsilon) / ( LowEPPCepsilon * e0m);
388 sinT2 = oneCosT * (2. - oneCosT);
389 G4double x = std::sqrt(oneCosT/2.) / (wlPhoton/cm);
390 G4double scatteringFunction = ComputeScatteringFunction(x, Z);
391 gReject = (1. - LowEPPCepsilon * sinT2 / (1. + LowEPPCepsilonSq)) * scatteringFunction;
392
394
396 G4double sinTheta = std::sqrt(sinT2);
397 G4double phi = SetPhi(LowEPPCepsilon,sinT2);
398 G4double dirx = sinTheta * std::cos(phi);
399 G4double diry = sinTheta * std::sin(phi);
401
402
403
404 G4ThreeVector photonPolarization1 = SetNewPolarization(LowEPPCepsilon,
405 sinT2,
406 phi,
407 cosTheta);
408
409
410
411
412
413
414
415
416 const G4double vel_c = c_light / (m/s);
417 const G4double momentum_au_to_nat = halfpi* hbar_Planck / Bohr_radius / (kg*m/s);
418 const G4double e_mass_kg = electron_mass_c2 / c_squared / kg ;
419
420 const G4int maxDopplerIterations = 1000;
422 G4double pEIncident = photonEnergy0 ;
427
436
437 if (verboseLevel > 3) {
438 G4cout <<
"Started loop to sample photon energy and electron direction" <<
G4endl;
439 }
440
441 do{
442
443
444
445
446
447
448 do
449 {
450 iteration++;
451
452
453
454
455
456
457
458
461
462
463
465
466
467 G4double ePSI = ePAU * momentum_au_to_nat;
468
469
470 u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / ((e_mass_kg*e_mass_kg)*(vel_c*vel_c)+(ePSI*ePSI)) )/vel_c;
471
472
473
476
477
478
479 G4double eEIncident = electron_mass_c2 / sqrt( 1 - (u_temp*u_temp));
480 G4double systemE = eEIncident + pEIncident;
481
482
483 G4double gamma_temp = 1.0 / sqrt( 1 - (u_temp*u_temp));
484 G4double numerator = gamma_temp*electron_mass_c2*(1 - u_temp * std::cos(e_alpha));
485 G4double subdenom1 = u_temp*cosTheta*std::cos(e_alpha);
486 G4double subdenom2 = u_temp*sinTheta*std::sin(e_alpha)*std::cos(e_beta);
487 G4double denominator = (1.0 - cosTheta) + (gamma_temp*electron_mass_c2*(1 - subdenom1 - subdenom2) / pEIncident);
488 pERecoil = (numerator/denominator);
489 eERecoil = systemE - pERecoil;
490 CE_emission_flag = pEIncident - pERecoil;
491 } while ( (iteration <= maxDopplerIterations) && (CE_emission_flag < bindingE));
492
493
494
495
496
497
498
499
500
501
502
503 G4double a_temp = eERecoil / electron_mass_c2;
504 G4double u_p_temp = sqrt(1 - (1 / (a_temp*a_temp)));
505
506
507
508 G4double sinAlpha = std::sin(e_alpha);
509 G4double cosAlpha = std::cos(e_alpha);
510 G4double sinBeta = std::sin(e_beta);
511 G4double cosBeta = std::cos(e_beta);
512
513 G4double gamma = 1.0 / sqrt(1 - (u_temp*u_temp));
514 G4double gamma_p = 1.0 / sqrt(1 - (u_p_temp*u_p_temp));
515
516 G4double var_A = pERecoil*u_p_temp*sinTheta;
517 G4double var_B = u_p_temp* (pERecoil*cosTheta-pEIncident);
518 G4double var_C = (pERecoil-pEIncident) - ( (pERecoil*pEIncident) / (gamma_p*electron_mass_c2))*(1 - cosTheta);
519
520 G4double var_D1 = gamma*electron_mass_c2*pERecoil;
521 G4double var_D2 = (1 - (u_temp*cosTheta*cosAlpha) - (u_temp*sinTheta*cosBeta*sinAlpha));
522 G4double var_D3 = ((electron_mass_c2*electron_mass_c2)*(gamma*gamma_p - 1)) - (gamma_p*electron_mass_c2*pERecoil);
523 G4double var_D = var_D1*var_D2 + var_D3;
524
525 G4double var_E1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosAlpha);
526 G4double var_E2 = gamma_p*electron_mass_c2*pERecoil*u_p_temp*cosTheta;
528
529 G4double var_F1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosBeta*sinAlpha);
530 G4double var_F2 = (gamma_p*electron_mass_c2*pERecoil*u_p_temp*sinTheta);
532
533 G4double var_G = (gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*sinBeta*sinAlpha;
534
535
536
537
538 G4double var_W1 = (var_F*var_B - var_E*var_A)*(var_F*var_B - var_E*var_A);
539 G4double var_W2 = (var_G*var_G)*(var_A*var_A) + (var_G*var_G)*(var_B*var_B);
541
542 G4double var_Y = 2.0*(((var_A*var_D-var_F*var_C)*(var_F*var_B-var_E*var_A)) - ((var_G*var_G)*var_B*var_C));
543
544 G4double var_Z1 = (var_A*var_D - var_F*var_C)*(var_A*var_D - var_F*var_C);
545 G4double var_Z2 = (var_G*var_G)*(var_C*var_C) - (var_G*var_G)*(var_A*var_A);
550
551
552
553
554
555
556
557 if ((diff < 0.0) && (abs(diff / diff1) < g4d_limit) && (abs(diff / diff2) < g4d_limit) )
558 {
559 diff = 0.0;
560 }
561
562
563 G4double X_p = (-var_Y + sqrt (diff))/(2*var_W);
564 G4double X_m = (-var_Y - sqrt (diff))/(2*var_W);
565
566
567
568
569
570
571 if(X_p >1){X_p=1;} if(X_p<-1){X_p=-1;}
572 if(X_m >1){X_m=1;} if(X_m<-1){X_m=-1;}
573
574
575
577
578
579
581
582 if (sol_select < 0.5)
583 {
584 ThetaE = std::acos(X_p);
585 }
586 if (sol_select > 0.5)
587 {
588 ThetaE = std::acos(X_m);
589 }
590
591 cosThetaE = std::cos(ThetaE);
592 sinThetaE = std::sin(ThetaE);
593 G4double Theta = std::acos(cosTheta);
594
595
596 G4double iSinThetaE = std::sqrt(1+std::tan((pi/2.0)-ThetaE)*std::tan((pi/2.0)-ThetaE));
597 G4double iSinTheta = std::sqrt(1+std::tan((pi/2.0)-Theta)*std::tan((pi/2.0)-Theta));
598 G4double ivar_A = iSinTheta/ (pERecoil*u_p_temp);
599
600 cosPhiE = (var_C - var_B*cosThetaE)*(ivar_A*iSinThetaE);
601
602
603
604
605
606 } while ( (iteration <= maxDopplerIterations) && (abs(cosPhiE) > 1));
607
608
609 if (iteration >= maxDopplerIterations)
610 {
611 pERecoil = photonEnergy0 ;
612 bindingE = 0.;
613 dirx=0.0;
614 diry=0.0;
615 dirz=1.0;
616 }
617
618
619
621 SystemOfRefChange(photonDirection0,photonDirection1,
622 photonPolarization0,photonPolarization1);
623
624
625 if (pERecoil > 0.)
626 {
630
631
633 G4double eDirX = sinThetaE * std::cos(phi+PhiE);
634 G4double eDirY = sinThetaE * std::sin(phi+PhiE);
636
637 G4double eKineticEnergy = pEIncident - pERecoil - bindingE;
638
640 SystemOfRefChangeElect(photonDirection0,eDirection,
641 photonPolarization0);
642
644 eDirection,eKineticEnergy) ;
645 fvect->push_back(dp);
646
647 }
648 else
649 {
652 }
653
654
655
656
657 if (verboseLevel > 3) {
658 G4cout <<
"Started atomic de-excitation " << fAtomDeexcitation <<
G4endl;
659 }
660
661 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
664 size_t nbefore = fvect->size();
668 size_t nafter = fvect->size();
669 if(nafter > nbefore) {
670 for (size_t i=nbefore; i<nafter; ++i) {
671
672 if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
673 {
674
675 bindingE -= ((*fvect)[i])->GetKineticEnergy();
676 }
677 else
678 {
679
680
681 delete (*fvect)[i];
682 (*fvect)[i]=0;
683 }
684 }
685 }
686 }
687 }
688
689
690 if(bindingE < 0.0)
691 G4Exception(
"G4LowEPPolarizedComptonModel::SampleSecondaries()",
693
695
696}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
double howOrthogonal(const Hep3Vector &v) const
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
static G4Electron * Electron()
const G4String & GetName() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposePolarization(const G4ThreeVector &dir)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double BindingEnergy(G4int Z, G4int shellIndex) const
G4int SelectRandomShell(G4int Z) const
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)