305{
306
307
308
309
310
311
312 if (verboseLevel > 3)
313 G4cout <<
"Calling SampleSecondaries() of G4LivermorePolarizedComptonModel" <<
G4endl;
314
316
317
318
320 return ;
321
323
324
325
326
328
329
330
331 if(!(gammaPolarization0.
isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.
mag()==0))
332 {
333 gammaPolarization0 = GetRandomPolarization(gammaDirection0);
334 }
335 else
336 {
338 {
339 gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
340 }
341 }
342
343
344 G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
345
346
347
351
352
354
355 G4double epsilon0Local = 1./(1. + 2*E0_m);
356 G4double epsilon0Sq = epsilon0Local*epsilon0Local;
359
360 G4double wlGamma = h_Planck*c_light/gammaEnergy0;
363
364 do {
366 {
369 }
370 else
371 {
373 epsilon = std::sqrt(epsilonSq);
374 }
375
377 sinThetaSqr = onecost*(2.-onecost);
378
379
380 if (sinThetaSqr > 1.)
381 {
383 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
384 << "sin(theta)**2 = "
385 << sinThetaSqr
386 << "; set to 1"
388 sinThetaSqr = 1.;
389 }
390 if (sinThetaSqr < 0.)
391 {
393 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
394 << "sin(theta)**2 = "
395 << sinThetaSqr
396 << "; set to 0"
398 sinThetaSqr = 0.;
399 }
400
401
402 G4double x = std::sqrt(onecost/2.) / (wlGamma/cm);;
404 greject = (1. -
epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
405
407
408
409
410
411
413
414
415
416
418
419
420 if (cosTheta > 1.)
421 {
423 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
424 << "cosTheta = "
425 << cosTheta
426 << "; set to 1"
428 cosTheta = 1.;
429 }
430 if (cosTheta < -1.)
431 {
433 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
434 << "cosTheta = "
435 << cosTheta
436 << "; set to -1"
438 cosTheta = -1.;
439 }
440
441
442 G4double sinTheta = std::sqrt (sinThetaSqr);
443
444
445 if (sinTheta > 1.)
446 {
448 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
449 << "sinTheta = "
450 << sinTheta
451 << "; set to 1"
453 sinTheta = 1.;
454 }
455 if (sinTheta < -1.)
456 {
458 << " -- Warning -- G4LivermorePolarizedComptonModel::SampleSecondaries "
459 << "sinTheta = "
460 << sinTheta
461 << "; set to -1"
463 sinTheta = -1.;
464 }
465
466
467
468
469 const auto* auxInfo
471 if (auxInfo) {
473 if (entanglementAuxInfo) {
475 (entanglementAuxInfo->GetEntanglementClipBoard());
476 if (clipBoard) {
477
478
479
480
481
482
483 if (clipBoard->IsTrack1Measurement()) {
484
485
486
487
488
489
490
492
493
494
495
496
497
498
499
500
501
503
504 clipBoard->SetComptonCosTheta1(cosTheta);
505 clipBoard->SetComptonPhi1(phi);
506 }
507 } else if (clipBoard->IsTrack2Measurement()) {
508
509
511
512
513
514
515
516
517
518
519
520
521 clipBoard->ResetTrack2Measurement();
522
523
524 const G4double& cosTheta1 = clipBoard->GetComptonCosTheta1();
525 const G4double& phi1 = clipBoard->GetComptonPhi1();
526
527 const G4double& cosTheta2 = cosTheta;
529
530
531
532
533
534
535
536 const G4double sin2Theta1 = 1.-cosTheta1*cosTheta1;
537 const G4double sin2Theta2 = 1.-cosTheta2*cosTheta2;
538
539
542 ((g4Pow->powN(1.-cosTheta1,3))+2.)*(g4Pow->powN(1.-cosTheta2,3)+2.)/
543 ((g4Pow->powN(2.-cosTheta1,3)*g4Pow->powN(2.-cosTheta2,3)));
544 const G4double B = -(sin2Theta1*sin2Theta2)/
545 ((g4Pow->powN(2.-cosTheta1,2)*g4Pow->powN(2.-cosTheta2,2)));
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560 const G4double maxValue =
A + std::abs(B);
563
564
565
567 const G4int maxCount = 999999;
569 for (; iCount < maxCount; ++iCount) {
572 }
573 if (iCount >= maxCount ) {
574 G4cout <<
"G4LivermorePolarizedComptonModel::SampleSecondaries: "
575 << "Re-sampled delta phi not found in " << maxCount
576 <<
" tries - carrying on anyway." <<
G4endl;
577 }
578
579
580 phi2 = deltaPhi - phi1 + halfpi;
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 }
598 }
599 }
600 }
601 }
602
603
604
605 G4double dirx = sinTheta*std::cos(phi);
606 G4double diry = sinTheta*std::sin(phi);
608
609
610
611
612
613
614
615
616
617 static G4int maxDopplerIterations = 1000;
623
625
626 if (verboseLevel > 3) {
628 }
629
630 do
631 {
632 iteration++;
633
636
637 if (verboseLevel > 3) {
638 G4cout <<
"Shell ID= " << shellIdx
639 <<
" Ebind(keV)= " << bindingE/keV <<
G4endl;
640 }
641 eMax = gammaEnergy0 - bindingE;
642
643
645
646 if (verboseLevel > 3) {
648 }
649
650 G4double pDoppler = pSample * fine_structure_const;
651 G4double pDoppler2 = pDoppler * pDoppler;
652 G4double var2 = 1. + onecost * E0_m;
653 G4double var3 = var2*var2 - pDoppler2;
654 G4double var4 = var2 - pDoppler2 * cosTheta;
655 G4double var = var4*var4 - var3 + pDoppler2 * var3;
656 if (var > 0.)
657 {
659 G4double scale = gammaEnergy0 / var3;
660
661 if (
G4UniformRand() < 0.5) photonE = (var4 - varSqrt) * scale;
662 else photonE = (var4 + varSqrt) * scale;
663 }
664 else
665 {
666 photonE = -1.;
667 }
668 } while ( iteration <= maxDopplerIterations &&
669 (photonE < 0. || photonE > eMax || photonE < eMax*
G4UniformRand()) );
670
671
672
673 if (iteration >= maxDopplerIterations)
674 {
675 photonE = photonEoriginal;
676 bindingE = 0.;
677 }
678
679 gammaEnergy1 = photonE;
680
681
682
683
684
686 sinThetaSqr,
687 phi,
688 cosTheta);
689
690
692 gammaDirection1 = tmpDirection1;
693
694
695 SystemOfRefChange(gammaDirection0,gammaDirection1,
696 gammaPolarization0,gammaPolarization1);
697
698 if (gammaEnergy1 > 0.)
699 {
703 }
704 else
705 {
706 gammaEnergy1 = 0.;
709 }
710
711
712
713
714 G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 -bindingE;
715
716
717
718 if(ElecKineEnergy < 0.0) {
720 return;
721 }
722
723 G4double ElecMomentum = std::sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
724
725 G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
726 gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
727
730 fvect->push_back(dp);
731
732
733
734 if (verboseLevel > 3) {
735 G4cout <<
"Started atomic de-excitation " << fAtomDeexcitation <<
G4endl;
736 }
737
738 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
741 std::size_t nbefore = fvect->size();
745 std::size_t nafter = fvect->size();
746 if(nafter > nbefore) {
747 for (std::size_t i=nbefore; i<nafter; ++i) {
748
749 if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
750 {
751
752 bindingE -= ((*fvect)[i])->GetKineticEnergy();
753 }
754 else
755 {
756
757
758 delete (*fvect)[i];
759 (*fvect)[i]=0;
760 }
761 }
762 }
763 }
764 }
765
766 if(bindingE < 0.0)
767 G4Exception(
"G4LivermoreComptonModel::SampleSecondaries()",
769
771
772}
G4double epsilon(G4double density, G4double temperature)
G4double B(G4double temperature)
G4double D(G4double temp)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
double howOrthogonal(const Hep3Vector &v) const
virtual G4double FindValue(G4double x, G4int componentId=0) 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()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposePolarization(const G4ThreeVector &dir)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
static G4Pow * GetInstance()
G4double BindingEnergy(G4int Z, G4int shellIndex) const
G4int SelectRandomShell(G4int Z) const
G4VAuxiliaryTrackInformation * GetAuxiliaryTrackInformation(G4int id) 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 ResetTrack1Measurement()
void ProposeTrackStatus(G4TrackStatus status)
const G4Track * GetCurrentTrack() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)