573{
574 if (!theSamplingTable)
575 theSamplingTable =
576 new std::map< std::pair<const G4Material*,G4double> ,
G4PhysicsTable*>;
577 if (!thePBcut)
578 thePBcut =
580
581 std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
582
583 if (!(theSamplingTable->count(theKey)))
584 {
585 InitializeEnergySampling(mat,cut);
586 if (!(theSamplingTable->count(theKey)) || !(thePBcut->count(theKey)))
587 {
589 ed << "Unable to create the SamplingTable: " <<
590 theSamplingTable->count(theKey) << " " <<
591 thePBcut->count(theKey) <<
G4endl;
592 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
594 }
595 }
596
597 G4PhysicsTable* theTableInte = theSamplingTable->find(theKey)->second;
598 G4PhysicsTable* theTableRed = theReducedXSTable->find(theKey)->second;
599
600
601 size_t eBin = 0;
602 G4bool firstOrLastBin =
false;
603
604 if (energy < theEGrid[0])
605 {
606 eBin = 0;
607 firstOrLastBin = true;
608 }
609 else if (energy > theEGrid[nBinsE-1])
610 {
611 eBin = nBinsE-1;
612 firstOrLastBin = true;
613 }
614 else
615 {
616 size_t i=0;
617 size_t j=nBinsE-1;
618 while ((j-i)>1)
619 {
620 size_t k = (i+j)/2;
621 if (energy > theEGrid[k])
622 i = k;
623 else
624 j = k;
625 }
626 eBin = i;
627 }
628
629
631
632
633
634
635
636
637 if (!firstOrLastBin)
638 {
640 for (size_t iloop=0;iloop<nBinsX;iloop++)
641 {
642 G4double val = (*theVec1)[iloop]+(((*theVec2)[iloop]-(*theVec1)[iloop]))*
643 (energy-theEGrid[eBin])/(theEGrid[eBin+1]-theEGrid[eBin]);
644 theTempVec->
PutValue(iloop,theXGrid[iloop],val);
645 }
646 }
647 else
648 {
649 for (size_t iloop=0;iloop<nBinsX;iloop++)
650 theTempVec->
PutValue(iloop,theXGrid[iloop],(*theVec1)[iloop]);
651 }
652
653
654 G4double pbcut = (*(thePBcut->find(theKey)->second))[eBin];
655
656 if (!firstOrLastBin)
657 {
658 pbcut = (*(thePBcut->find(theKey)->second))[eBin] +
659 ((*(thePBcut->find(theKey)->second))[eBin+1]-(*(thePBcut->find(theKey)->second))[eBin])*
660 (energy-theEGrid[eBin])/(theEGrid[eBin+1]-theEGrid[eBin]);
661 }
662
663 G4double pCumulative = (*theTempVec)[nBinsX-1];
664
666 do
667 {
669
670
671 size_t ibin = 0;
672 if (pt < (*theTempVec)[0])
673 ibin = 0;
674 else if (pt > (*theTempVec)[nBinsX-1])
675 {
676
677
678 G4double delta = pt-(*theTempVec)[nBinsX-1];
679 if (delta < pt*1e-10)
680 {
681 ibin = nBinsX-2;
683 ed << "Found that (pt > (*theTempVec)[nBinsX-1]) with pt = " << pt <<
684 " , (*theTempVec)[nBinsX-1] = " << (*theTempVec)[nBinsX-1] << " and delta = " <<
685 (pt-(*theTempVec)[nBinsX-1]) <<
G4endl;
686 ed <<
"Possible symptom of problem with numerical precision" <<
G4endl;
687 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
689 }
690 else
691 {
693 ed << "Crash at (pt > (*theTempVec)[nBinsX-1]) with pt = " << pt <<
694 " , (*theTempVec)[nBinsX-1]=" << (*theTempVec)[nBinsX-1] << " and nBinsX = " <<
696 ed <<
"Material: " << mat->
GetName() <<
", energy = " << energy/keV <<
" keV" <<
698 G4Exception(
"G4PenelopeBremsstrahlungFS::SampleGammaEnergy()",
700 }
701 }
702 else
703 {
704 size_t i=0;
705 size_t j=nBinsX-1;
706 while ((j-i)>1)
707 {
708 size_t k = (i+j)/2;
709 if (pt > (*theTempVec)[k])
710 i = k;
711 else
712 j = k;
713 }
714 ibin = i;
715 }
716
719
722
723
724 G4double pdf1 = std::exp((*v1)[eBin+1]);
725 G4double pdf2 = std::exp((*v2)[eBin+1]);
730
731
732 G4double wbcut = (cut < energy) ? cut/energy : 1.0;
733 if (firstOrLastBin)
734 wbcut = (cut < theEGrid[eBin]) ? cut/theEGrid[eBin] : 1.0;
735
736 if (w1 < wbcut)
737 w1 = wbcut;
738 if (w2 < w1)
739 {
740 G4cout <<
"Warning in G4PenelopeBremsstrahlungFS::SampleX()" <<
G4endl;
741 G4cout <<
"Conflicting end-point values: w1=" << w1 <<
"; w2 = " << w2 <<
G4endl;
742 G4cout <<
"wbcut = " << wbcut <<
" energy= " << energy/keV <<
" keV" <<
G4endl;
744 return w1*energy;
745 }
746
747 G4double pmax = std::max(A+B*w1,A+B*w2);
749 do
750 {
751 loopAgain = false;
754 loopAgain = true;
755 }while(loopAgain);
756 eGamma *= energy;
757 }while(eGamma < cut);
758
759 return eGamma;
760}
G4DLLIMPORT std::ostream G4cout
const G4String & GetName() const
void PutValue(size_t binNumber, G4double binValue, G4double dataValue)