Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/adjoint/src/G4AdjointPhotoElectricModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 27 #include "G4AdjointPhotoElectricModel.hh"
 28 
 29 #include "G4AdjointCSManager.hh"
 30 #include "G4AdjointElectron.hh"
 31 #include "G4AdjointGamma.hh"
 32 #include "G4Gamma.hh"
 33 #include "G4ParticleChange.hh"
 34 #include "G4PEEffectFluoModel.hh"
 35 #include "G4PhysicalConstants.hh"
 36 #include "G4TrackStatus.hh"
 37 
 38 ////////////////////////////////////////////////////////////////////////////////
 39 G4AdjointPhotoElectricModel::G4AdjointPhotoElectricModel()
 40   : G4VEmAdjointModel("AdjointPEEffect")
 41 
 42 {
 43   SetUseMatrix(false);
 44   SetApplyCutInRange(false);
 45 
 46   fAdjEquivDirectPrimPart   = G4AdjointGamma::AdjointGamma();
 47   fAdjEquivDirectSecondPart = G4AdjointElectron::AdjointElectron();
 48   fDirectPrimaryPart        = G4Gamma::Gamma();
 49   fSecondPartSameType       = false;
 50   fDirectModel              = new G4PEEffectFluoModel();
 51 }
 52 
 53 ////////////////////////////////////////////////////////////////////////////////
 54 G4AdjointPhotoElectricModel::~G4AdjointPhotoElectricModel() {}
 55 
 56 ////////////////////////////////////////////////////////////////////////////////
 57 void G4AdjointPhotoElectricModel::SampleSecondaries(
 58   const G4Track& aTrack, G4bool isScatProjToProj,
 59   G4ParticleChange* fParticleChange)
 60 {
 61   if(isScatProjToProj)
 62     return;
 63 
 64   // Compute the fTotAdjointCS vectors if not already done for the current
 65   // couple and electron energy
 66   const G4DynamicParticle* aDynPart = aTrack.GetDynamicParticle();
 67   G4double electronEnergy           = aDynPart->GetKineticEnergy();
 68   G4ThreeVector electronDirection   = aDynPart->GetMomentumDirection();
 69   fPreStepAdjointCS =
 70     fTotAdjointCS;  // The last computed CS was at pre step point
 71   AdjointCrossSection(aTrack.GetMaterialCutsCouple(), electronEnergy,
 72                       isScatProjToProj);
 73   fPostStepAdjointCS = fTotAdjointCS;
 74 
 75   // Sample element
 76   const G4ElementVector* theElementVector =
 77     fCurrentMaterial->GetElementVector();
 78   size_t nelm      = fCurrentMaterial->GetNumberOfElements();
 79   G4double rand_CS = G4UniformRand() * fXsec[nelm - 1];
 80   for(fIndexElement = 0; fIndexElement < nelm - 1; ++fIndexElement)
 81   {
 82     if(rand_CS < fXsec[fIndexElement])
 83       break;
 84   }
 85 
 86   // Sample shell and binding energy
 87   G4int nShells = (*theElementVector)[fIndexElement]->GetNbOfAtomicShells();
 88   rand_CS       = fShellProb[fIndexElement][nShells - 1] * G4UniformRand();
 89   G4int i;
 90   for(i = 0; i < nShells - 1; ++i)
 91   {
 92     if(rand_CS < fShellProb[fIndexElement][i])
 93       break;
 94   }
 95   G4double gammaEnergy =
 96     electronEnergy + (*theElementVector)[fIndexElement]->GetAtomicShell(i);
 97 
 98   // Sample cos theta
 99   // Copy of the G4PEEfectFluoModel cos theta sampling method
100   // ElecCosThetaDistribution. This method cannot be used directly from
101   // G4PEEffectFluoModel because it is a friend method.
102   G4double cos_theta = 1.;
103   G4double gamma     = 1. + electronEnergy / electron_mass_c2;
104   if(gamma <= 5.)
105   {
106     G4double beta = std::sqrt(gamma * gamma - 1.) / gamma;
107     G4double b    = 0.5 * gamma * (gamma - 1.) * (gamma - 2.);
108 
109     G4double rndm, term, greject, grejsup;
110     if(gamma < 2.)
111       grejsup = gamma * gamma * (1. + b - beta * b);
112     else
113       grejsup = gamma * gamma * (1. + b + beta * b);
114 
115     do
116     {
117       rndm      = 1. - 2. * G4UniformRand();
118       cos_theta = (rndm + beta) / (rndm * beta + 1.);
119       term      = 1. - beta * cos_theta;
120       greject = (1. - cos_theta * cos_theta) * (1. + b * term) / (term * term);
121       // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
122     } while(greject < G4UniformRand() * grejsup);
123   }
124 
125   // direction of the adjoint gamma electron
126   G4double sin_theta = std::sqrt(1. - cos_theta * cos_theta);
127   G4double phi       = twopi * G4UniformRand();
128   G4double dirx      = sin_theta * std::cos(phi);
129   G4double diry      = sin_theta * std::sin(phi);
130   G4double dirz      = cos_theta;
131   G4ThreeVector adjoint_gammaDirection(dirx, diry, dirz);
132   adjoint_gammaDirection.rotateUz(electronDirection);
133 
134   // Weight correction
135   CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(), electronEnergy,
136                         gammaEnergy, isScatProjToProj);
137 
138   // Create secondary and modify fParticleChange
139   G4DynamicParticle* anAdjointGamma = new G4DynamicParticle(
140     G4AdjointGamma::AdjointGamma(), adjoint_gammaDirection, gammaEnergy);
141 
142   fParticleChange->ProposeTrackStatus(fStopAndKill);
143   fParticleChange->AddSecondary(anAdjointGamma);
144 }
145 
146 ////////////////////////////////////////////////////////////////////////////////
147 void G4AdjointPhotoElectricModel::CorrectPostStepWeight(
148   G4ParticleChange* fParticleChange, G4double old_weight,
149   G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool)
150 {
151   G4double new_weight = old_weight;
152 
153   G4double w_corr =
154     G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection() /
155     fFactorCSBiasing;
156   w_corr *= fPostStepAdjointCS / fPreStepAdjointCS;
157 
158   new_weight *= w_corr * projectileKinEnergy / adjointPrimKinEnergy;
159   fParticleChange->SetParentWeightByProcess(false);
160   fParticleChange->SetSecondaryWeightByProcess(false);
161   fParticleChange->ProposeParentWeight(new_weight);
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 G4double G4AdjointPhotoElectricModel::AdjointCrossSection(
166   const G4MaterialCutsCouple* aCouple, G4double electronEnergy,
167   G4bool isScatProjToProj)
168 {
169   if(isScatProjToProj)
170     return 0.;
171 
172   G4double totBiasedAdjointCS = 0.;
173   if(aCouple != fCurrentCouple || fCurrenteEnergy != electronEnergy)
174   {
175     fTotAdjointCS = 0.;
176     DefineCurrentMaterialAndElectronEnergy(aCouple, electronEnergy);
177     const G4ElementVector* theElementVector =
178       fCurrentMaterial->GetElementVector();
179     const G4double* theAtomNumDensityVector =
180       fCurrentMaterial->GetVecNbOfAtomsPerVolume();
181     size_t nelm = fCurrentMaterial->GetNumberOfElements();
182     for(fIndexElement = 0; fIndexElement < nelm; ++fIndexElement)
183     {
184       fTotAdjointCS += AdjointCrossSectionPerAtom(
185                          (*theElementVector)[fIndexElement], electronEnergy) *
186                        theAtomNumDensityVector[fIndexElement];
187       fXsec[fIndexElement] = fTotAdjointCS;
188     }
189 
190     totBiasedAdjointCS = std::min(fTotAdjointCS, 0.01);
191     fFactorCSBiasing   = totBiasedAdjointCS / fTotAdjointCS;
192   }
193   return totBiasedAdjointCS;
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 G4double G4AdjointPhotoElectricModel::AdjointCrossSectionPerAtom(
198   const G4Element* anElement, G4double electronEnergy)
199 {
200   G4int nShells        = anElement->GetNbOfAtomicShells();
201   G4double Z           = anElement->GetZ();
202   G4double gammaEnergy = electronEnergy + anElement->GetAtomicShell(0);
203   G4double CS          = fDirectModel->ComputeCrossSectionPerAtom(
204     G4Gamma::Gamma(), gammaEnergy, Z, 0., 0., 0.);
205   G4double adjointCS = 0.;
206   if(CS > 0.)
207     adjointCS += CS / gammaEnergy;
208   fShellProb[fIndexElement][0] = adjointCS;
209   for(G4int i = 1; i < nShells; ++i)
210   {
211     G4double Bi1 = anElement->GetAtomicShell(i - 1);
212     G4double Bi  = anElement->GetAtomicShell(i);
213     if(electronEnergy < Bi1 - Bi)
214     {
215       gammaEnergy = electronEnergy + Bi;
216       CS          = fDirectModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),
217                                                     gammaEnergy, Z, 0., 0., 0.);
218       if(CS > 0.)
219         adjointCS += CS / gammaEnergy;
220     }
221     fShellProb[fIndexElement][i] = adjointCS;
222   }
223   adjointCS *= electronEnergy;
224   return adjointCS;
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 void G4AdjointPhotoElectricModel::DefineCurrentMaterialAndElectronEnergy(
229   const G4MaterialCutsCouple* couple, G4double anEnergy)
230 {
231   fCurrentCouple   = const_cast<G4MaterialCutsCouple*>(couple);
232   fCurrentMaterial = const_cast<G4Material*>(couple->GetMaterial());
233   fCurrenteEnergy = anEnergy;
234   fDirectModel->SetCurrentCouple(couple);
235 }
236