Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 << 26 // $Id: G4AdjointPhotoElectricModel.cc 91870 2015-08-07 15:21:40Z gcosmo $ >> 27 // 27 #include "G4AdjointPhotoElectricModel.hh" 28 #include "G4AdjointPhotoElectricModel.hh" 28 << 29 #include "G4AdjointCSManager.hh" 29 #include "G4AdjointCSManager.hh" 30 #include "G4AdjointElectron.hh" << 30 31 #include "G4AdjointGamma.hh" << 32 #include "G4Gamma.hh" << 33 #include "G4ParticleChange.hh" << 34 #include "G4PEEffectFluoModel.hh" << 35 #include "G4PhysicalConstants.hh" 31 #include "G4PhysicalConstants.hh" >> 32 #include "G4Integrator.hh" 36 #include "G4TrackStatus.hh" 33 #include "G4TrackStatus.hh" >> 34 #include "G4ParticleChange.hh" >> 35 #include "G4AdjointElectron.hh" >> 36 #include "G4Gamma.hh" >> 37 #include "G4AdjointGamma.hh" >> 38 37 39 38 ////////////////////////////////////////////// 40 //////////////////////////////////////////////////////////////////////////////// 39 G4AdjointPhotoElectricModel::G4AdjointPhotoEle << 41 // 40 : G4VEmAdjointModel("AdjointPEEffect") << 42 G4AdjointPhotoElectricModel::G4AdjointPhotoElectricModel(): >> 43 G4VEmAdjointModel("AdjointPEEffect") 41 44 42 { << 45 { SetUseMatrix(false); 43 SetUseMatrix(false); << 44 SetApplyCutInRange(false); 46 SetApplyCutInRange(false); 45 47 46 fAdjEquivDirectPrimPart = G4AdjointGamma:: << 48 //Initialization 47 fAdjEquivDirectSecondPart = G4AdjointElectro << 49 current_eEnergy =0.; 48 fDirectPrimaryPart = G4Gamma::Gamma() << 50 totAdjointCS=0.; 49 fSecondPartSameType = false; << 51 factorCSBiasing =1.; 50 fDirectModel = new G4PEEffectFl << 52 post_step_AdjointCS =0.; >> 53 pre_step_AdjointCS =0.; >> 54 totBiasedAdjointCS =0.; >> 55 >> 56 index_element=0; >> 57 >> 58 theAdjEquivOfDirectPrimPartDef =G4AdjointGamma::AdjointGamma(); >> 59 theAdjEquivOfDirectSecondPartDef=G4AdjointElectron::AdjointElectron(); >> 60 theDirectPrimaryPartDef=G4Gamma::Gamma(); >> 61 second_part_of_same_type=false; >> 62 theDirectPEEffectModel = new G4PEEffectFluoModel(); 51 } 63 } 52 << 53 ////////////////////////////////////////////// 64 //////////////////////////////////////////////////////////////////////////////// 54 G4AdjointPhotoElectricModel::~G4AdjointPhotoEl << 65 // 55 << 66 G4AdjointPhotoElectricModel::~G4AdjointPhotoElectricModel() 56 ////////////////////////////////////////////// << 67 {;} 57 void G4AdjointPhotoElectricModel::SampleSecond << 68 58 const G4Track& aTrack, G4bool isScatProjToPr << 69 //////////////////////////////////////////////////////////////////////////////// 59 G4ParticleChange* fParticleChange) << 70 // 60 { << 71 void G4AdjointPhotoElectricModel::SampleSecondaries(const G4Track& aTrack, 61 if(isScatProjToProj) << 72 G4bool IsScatProjToProjCase, 62 return; << 73 G4ParticleChange* fParticleChange) 63 << 74 { if (IsScatProjToProjCase) return ; 64 // Compute the fTotAdjointCS vectors if not << 75 65 // couple and electron energy << 76 //Compute the totAdjointCS vectors if not already done for the current couple and electron energy 66 const G4DynamicParticle* aDynPart = aTrack.G << 77 //----------------------------------------------------------------------------------------------- 67 G4double electronEnergy = aDynPart << 78 const G4MaterialCutsCouple* aCouple = aTrack.GetMaterialCutsCouple(); 68 G4ThreeVector electronDirection = aDynPart << 79 const G4DynamicParticle* aDynPart = aTrack.GetDynamicParticle() ; 69 fPreStepAdjointCS = << 80 G4double electronEnergy = aDynPart->GetKineticEnergy(); 70 fTotAdjointCS; // The last computed CS wa << 81 G4ThreeVector electronDirection= aDynPart->GetMomentumDirection() ; 71 AdjointCrossSection(aTrack.GetMaterialCutsCo << 82 pre_step_AdjointCS = totAdjointCS; //The last computed CS was at pre step point 72 isScatProjToProj); << 83 post_step_AdjointCS = AdjointCrossSection(aCouple, electronEnergy,IsScatProjToProjCase); 73 fPostStepAdjointCS = fTotAdjointCS; << 84 post_step_AdjointCS = totAdjointCS; 74 << 85 75 // Sample element << 86 76 const G4ElementVector* theElementVector = << 87 77 fCurrentMaterial->GetElementVector(); << 88 78 size_t nelm = fCurrentMaterial->GetNumb << 89 //Sample element 79 G4double rand_CS = G4UniformRand() * fXsec[n << 90 //------------- 80 for(fIndexElement = 0; fIndexElement < nelm << 91 const G4ElementVector* theElementVector = currentMaterial->GetElementVector(); 81 { << 92 size_t nelm = currentMaterial->GetNumberOfElements(); 82 if(rand_CS < fXsec[fIndexElement]) << 93 G4double rand_CS= G4UniformRand()*xsec[nelm-1]; 83 break; << 94 for (index_element=0; index_element<nelm-1; index_element++){ 84 } << 95 if (rand_CS<xsec[index_element]) break; 85 << 96 } 86 // Sample shell and binding energy << 97 87 G4int nShells = (*theElementVector)[fIndexEl << 98 //Sample shell and binding energy 88 rand_CS = fShellProb[fIndexElement][nS << 99 //------------- 89 G4int i; << 100 G4int nShells = (*theElementVector)[index_element]->GetNbOfAtomicShells(); 90 for(i = 0; i < nShells - 1; ++i) << 101 rand_CS= shell_prob[index_element][nShells-1]*G4UniformRand(); 91 { << 102 G4int i = 0; 92 if(rand_CS < fShellProb[fIndexElement][i]) << 103 for (i=0; i<nShells-1; i++){ 93 break; << 104 if (rand_CS<shell_prob[index_element][i]) break; 94 } << 105 } 95 G4double gammaEnergy = << 106 G4double gammaEnergy= electronEnergy+(*theElementVector)[index_element]->GetAtomicShell(i); 96 electronEnergy + (*theElementVector)[fInde << 107 97 << 108 //Sample cos theta 98 // Sample cos theta << 109 //Copy of the G4PEEfectFluoModel cos theta sampling method ElecCosThetaDistribution. 99 // Copy of the G4PEEfectFluoModel cos theta << 110 //This method cannot be used directly from G4PEEfectFluoModel because it is a friend method. I should ask Vladimir to change that 100 // ElecCosThetaDistribution. This method can << 111 //------------------------------------------------------------------------------------------------ 101 // G4PEEffectFluoModel because it is a frien << 112 //G4double cos_theta = theDirectPEEffectModel->ElecCosThetaDistribution(electronEnergy); 102 G4double cos_theta = 1.; << 113 103 G4double gamma = 1. + electronEnergy / e << 114 G4double cos_theta = 1.; 104 if(gamma <= 5.) << 115 G4double gamma = 1. + electronEnergy/electron_mass_c2; 105 { << 116 if (gamma <= 5.) { 106 G4double beta = std::sqrt(gamma * gamma - << 117 G4double beta = std::sqrt(gamma*gamma-1.)/gamma; 107 G4double b = 0.5 * gamma * (gamma - 1.) << 118 G4double b = 0.5*gamma*(gamma-1.)*(gamma-2); 108 << 119 109 G4double rndm, term, greject, grejsup; << 120 G4double rndm,term,greject,grejsup; 110 if(gamma < 2.) << 121 if (gamma < 2.) grejsup = gamma*gamma*(1.+b-beta*b); 111 grejsup = gamma * gamma * (1. + b - beta << 122 else grejsup = gamma*gamma*(1.+b+beta*b); 112 else << 123 113 grejsup = gamma * gamma * (1. + b + beta << 124 do { rndm = 1.-2*G4UniformRand(); 114 << 125 cos_theta = (rndm+beta)/(rndm*beta+1.); 115 do << 126 term = 1.-beta*cos_theta; 116 { << 127 greject = (1.-cos_theta*cos_theta)*(1.+b*term)/(term*term); 117 rndm = 1. - 2. * G4UniformRand(); << 128 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko 118 cos_theta = (rndm + beta) / (rndm * beta << 129 } while(greject < G4UniformRand()*grejsup); 119 term = 1. - beta * cos_theta; << 120 greject = (1. - cos_theta * cos_theta) * << 121 // Loop checking, 07-Aug-2015, Vladimir << 122 } while(greject < G4UniformRand() * grejsu << 123 } 130 } 124 << 131 125 // direction of the adjoint gamma electron 132 // direction of the adjoint gamma electron 126 G4double sin_theta = std::sqrt(1. - cos_thet << 133 //--------------------------------------- 127 G4double phi = twopi * G4UniformRand() << 134 128 G4double dirx = sin_theta * std::cos(ph << 135 129 G4double diry = sin_theta * std::sin(ph << 136 G4double sin_theta = std::sqrt(1.-cos_theta*cos_theta); 130 G4double dirz = cos_theta; << 137 G4double Phi = twopi * G4UniformRand(); 131 G4ThreeVector adjoint_gammaDirection(dirx, d << 138 G4double dirx = sin_theta*std::cos(Phi),diry = sin_theta*std::sin(Phi),dirz = cos_theta; >> 139 G4ThreeVector adjoint_gammaDirection(dirx,diry,dirz); 132 adjoint_gammaDirection.rotateUz(electronDire 140 adjoint_gammaDirection.rotateUz(electronDirection); 133 << 141 134 // Weight correction << 142 135 CorrectPostStepWeight(fParticleChange, aTrac << 143 136 gammaEnergy, isScatPro << 144 //Weight correction 137 << 145 //----------------------- 138 // Create secondary and modify fParticleChan << 146 CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(), electronEnergy,gammaEnergy,IsScatProjToProjCase); 139 G4DynamicParticle* anAdjointGamma = new G4Dy << 147 140 G4AdjointGamma::AdjointGamma(), adjoint_ga << 148 141 << 149 >> 150 //Create secondary and modify fParticleChange >> 151 //-------------------------------------------- >> 152 G4DynamicParticle* anAdjointGamma = new G4DynamicParticle ( >> 153 G4AdjointGamma::AdjointGamma(),adjoint_gammaDirection, gammaEnergy); >> 154 >> 155 >> 156 >> 157 >> 158 142 fParticleChange->ProposeTrackStatus(fStopAnd 159 fParticleChange->ProposeTrackStatus(fStopAndKill); 143 fParticleChange->AddSecondary(anAdjointGamma << 160 fParticleChange->AddSecondary(anAdjointGamma); 144 } << 161 145 162 146 ////////////////////////////////////////////// << 163 147 void G4AdjointPhotoElectricModel::CorrectPostS << 148 G4ParticleChange* fParticleChange, G4double << 149 G4double adjointPrimKinEnergy, G4double proj << 150 { << 151 G4double new_weight = old_weight; << 152 164 153 G4double w_corr = << 154 G4AdjointCSManager::GetAdjointCSManager()- << 155 fFactorCSBiasing; << 156 w_corr *= fPostStepAdjointCS / fPreStepAdjoi << 157 << 158 new_weight *= w_corr * projectileKinEnergy / << 159 fParticleChange->SetParentWeightByProcess(fa << 160 fParticleChange->SetSecondaryWeightByProcess << 161 fParticleChange->ProposeParentWeight(new_wei << 162 } 165 } 163 166 164 ////////////////////////////////////////////// 167 //////////////////////////////////////////////////////////////////////////////// 165 G4double G4AdjointPhotoElectricModel::AdjointC << 168 // 166 const G4MaterialCutsCouple* aCouple, G4doubl << 169 void G4AdjointPhotoElectricModel::CorrectPostStepWeight(G4ParticleChange* fParticleChange, 167 G4bool isScatProjToProj) << 170 G4double old_weight, 168 { << 171 G4double adjointPrimKinEnergy, 169 if(isScatProjToProj) << 172 G4double projectileKinEnergy , 170 return 0.; << 173 G4bool ) 171 << 174 { 172 G4double totBiasedAdjointCS = 0.; << 175 G4double new_weight=old_weight; 173 if(aCouple != fCurrentCouple || fCurrenteEne << 176 174 { << 177 G4double w_corr =G4AdjointCSManager::GetAdjointCSManager()->GetPostStepWeightCorrection()/factorCSBiasing; 175 fTotAdjointCS = 0.; << 178 w_corr*=post_step_AdjointCS/pre_step_AdjointCS; 176 DefineCurrentMaterialAndElectronEnergy(aCo << 179 177 const G4ElementVector* theElementVector = << 180 178 fCurrentMaterial->GetElementVector(); << 181 new_weight*=w_corr; 179 const G4double* theAtomNumDensityVector = << 182 new_weight*=projectileKinEnergy/adjointPrimKinEnergy; 180 fCurrentMaterial->GetVecNbOfAtomsPerVolu << 183 fParticleChange->SetParentWeightByProcess(false); 181 size_t nelm = fCurrentMaterial->GetNumberO << 184 fParticleChange->SetSecondaryWeightByProcess(false); 182 for(fIndexElement = 0; fIndexElement < nel << 185 fParticleChange->ProposeParentWeight(new_weight); 183 { << 186 } 184 fTotAdjointCS += AdjointCrossSectionPerA << 187 185 (*theElementVector)[f << 188 //////////////////////////////////////////////////////////////////////////////// 186 theAtomNumDensityVector << 189 // 187 fXsec[fIndexElement] = fTotAdjointCS; << 190 188 } << 191 G4double G4AdjointPhotoElectricModel::AdjointCrossSection(const G4MaterialCutsCouple* aCouple, 189 << 192 G4double electronEnergy, 190 totBiasedAdjointCS = std::min(fTotAdjointC << 193 G4bool IsScatProjToProjCase) 191 fFactorCSBiasing = totBiasedAdjointCS / << 194 { >> 195 >> 196 >> 197 if (IsScatProjToProjCase) return 0.; >> 198 >> 199 >> 200 if (aCouple !=currentCouple || current_eEnergy !=electronEnergy) { >> 201 totAdjointCS = 0.; >> 202 DefineCurrentMaterialAndElectronEnergy(aCouple, electronEnergy); >> 203 const G4ElementVector* theElementVector = currentMaterial->GetElementVector(); >> 204 const double* theAtomNumDensityVector = currentMaterial->GetVecNbOfAtomsPerVolume(); >> 205 size_t nelm = currentMaterial->GetNumberOfElements(); >> 206 for (index_element=0;index_element<nelm;index_element++){ >> 207 >> 208 totAdjointCS +=AdjointCrossSectionPerAtom((*theElementVector)[index_element],electronEnergy)*theAtomNumDensityVector[index_element]; >> 209 xsec[index_element] = totAdjointCS; >> 210 } >> 211 >> 212 totBiasedAdjointCS=std::min(totAdjointCS,0.01); >> 213 // totBiasedAdjointCS=totAdjointCS; >> 214 factorCSBiasing = totBiasedAdjointCS/totAdjointCS; >> 215 lastCS=totBiasedAdjointCS; >> 216 >> 217 192 } 218 } 193 return totBiasedAdjointCS; 219 return totBiasedAdjointCS; >> 220 >> 221 194 } 222 } >> 223 //////////////////////////////////////////////////////////////////////////////// >> 224 // 195 225 >> 226 G4double G4AdjointPhotoElectricModel::GetAdjointCrossSection(const G4MaterialCutsCouple* aCouple, >> 227 G4double electronEnergy, >> 228 G4bool IsScatProjToProjCase) >> 229 { return AdjointCrossSection(aCouple,electronEnergy,IsScatProjToProjCase); >> 230 } 196 ////////////////////////////////////////////// 231 //////////////////////////////////////////////////////////////////////////////// 197 G4double G4AdjointPhotoElectricModel::AdjointC << 232 // 198 const G4Element* anElement, G4double electro << 233 199 { << 234 G4double G4AdjointPhotoElectricModel::AdjointCrossSectionPerAtom(const G4Element* anElement,G4double electronEnergy) 200 G4int nShells = anElement->GetNbOfAto << 235 { 201 G4double Z = anElement->GetZ(); << 236 G4int nShells = anElement->GetNbOfAtomicShells(); 202 G4double gammaEnergy = electronEnergy + anEl << 237 G4double Z= anElement->GetZ(); 203 G4double CS = fDirectModel->Compute << 238 G4int i = 0; 204 G4Gamma::Gamma(), gammaEnergy, Z, 0., 0., << 239 G4double B0=anElement->GetAtomicShell(0); 205 G4double adjointCS = 0.; << 240 G4double gammaEnergy = electronEnergy+B0; 206 if(CS > 0.) << 241 G4double CS= theDirectPEEffectModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),gammaEnergy,Z,0.,0.,0.); 207 adjointCS += CS / gammaEnergy; << 242 G4double adjointCS =0.; 208 fShellProb[fIndexElement][0] = adjointCS; << 243 if (CS >0) adjointCS += CS/gammaEnergy; 209 for(G4int i = 1; i < nShells; ++i) << 244 shell_prob[index_element][0] = adjointCS; 210 { << 245 for (i=1;i<nShells;i++){ 211 G4double Bi1 = anElement->GetAtomicShell(i << 246 //G4cout<<i<<G4endl; 212 G4double Bi = anElement->GetAtomicShell(i << 247 G4double Bi_= anElement->GetAtomicShell(i-1); 213 if(electronEnergy < Bi1 - Bi) << 248 G4double Bi = anElement->GetAtomicShell(i); 214 { << 249 //G4cout<<Bi_<<'\t'<<Bi<<G4endl; 215 gammaEnergy = electronEnergy + Bi; << 250 if (electronEnergy <Bi_-Bi) { 216 CS = fDirectModel->ComputeCross << 251 gammaEnergy = electronEnergy+Bi; 217 << 252 218 if(CS > 0.) << 253 CS=theDirectPEEffectModel->ComputeCrossSectionPerAtom(G4Gamma::Gamma(),gammaEnergy,Z,0.,0.,0.); 219 adjointCS += CS / gammaEnergy; << 254 if (CS>0) adjointCS +=CS/gammaEnergy; 220 } << 255 } 221 fShellProb[fIndexElement][i] = adjointCS; << 256 shell_prob[index_element][i] = adjointCS; >> 257 222 } 258 } 223 adjointCS *= electronEnergy; << 259 adjointCS*=electronEnergy; 224 return adjointCS; 260 return adjointCS; 225 } << 261 226 << 262 } 227 ////////////////////////////////////////////// 263 //////////////////////////////////////////////////////////////////////////////// 228 void G4AdjointPhotoElectricModel::DefineCurren << 264 // 229 const G4MaterialCutsCouple* couple, G4double << 265 230 { << 266 void G4AdjointPhotoElectricModel::DefineCurrentMaterialAndElectronEnergy(const G4MaterialCutsCouple* couple, G4double anEnergy) 231 fCurrentCouple = const_cast<G4MaterialCuts << 267 { currentCouple = const_cast<G4MaterialCutsCouple*> (couple); 232 fCurrentMaterial = const_cast<G4Material*>(c << 268 currentMaterial = const_cast<G4Material*> (couple->GetMaterial()); 233 fCurrenteEnergy = anEnergy; << 269 currentCoupleIndex = couple->GetIndex(); 234 fDirectModel->SetCurrentCouple(couple); << 270 currentMaterialIndex = currentMaterial->GetIndex(); >> 271 current_eEnergy = anEnergy; >> 272 theDirectPEEffectModel->SetCurrentCouple(couple); 235 } 273 } 236 274