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 // $Id: G4PAIPhotModel.cc 73607 2013-09-02 10:04:03Z gcosmo $ 26 // 27 // 27 // ------------------------------------------- 28 // ------------------------------------------------------------------- 28 // 29 // 29 // GEANT4 Class 30 // GEANT4 Class 30 // File name: G4PAIPhotModel.cc 31 // File name: G4PAIPhotModel.cc 31 // 32 // 32 // Author: Vladimir.Grichine@cern.ch on base o 33 // Author: Vladimir.Grichine@cern.ch on base of G4PAIModel MT interface 33 // 34 // 34 // Creation date: 07.10.2013 35 // Creation date: 07.10.2013 35 // 36 // 36 // Modifications: 37 // Modifications: 37 // 38 // 38 // 39 // 39 40 40 #include "G4PAIPhotModel.hh" 41 #include "G4PAIPhotModel.hh" 41 42 42 #include "G4SystemOfUnits.hh" 43 #include "G4SystemOfUnits.hh" 43 #include "G4PhysicalConstants.hh" 44 #include "G4PhysicalConstants.hh" 44 #include "G4Region.hh" 45 #include "G4Region.hh" >> 46 #include "G4PhysicsLogVector.hh" >> 47 #include "G4PhysicsFreeVector.hh" >> 48 #include "G4PhysicsTable.hh" 45 #include "G4ProductionCutsTable.hh" 49 #include "G4ProductionCutsTable.hh" 46 #include "G4MaterialCutsCouple.hh" 50 #include "G4MaterialCutsCouple.hh" 47 #include "G4MaterialTable.hh" 51 #include "G4MaterialTable.hh" >> 52 #include "G4SandiaTable.hh" >> 53 #include "G4OrderedTable.hh" 48 #include "G4RegionStore.hh" 54 #include "G4RegionStore.hh" 49 55 50 #include "Randomize.hh" 56 #include "Randomize.hh" 51 #include "G4Electron.hh" 57 #include "G4Electron.hh" 52 #include "G4Positron.hh" 58 #include "G4Positron.hh" 53 #include "G4Gamma.hh" 59 #include "G4Gamma.hh" 54 #include "G4Poisson.hh" 60 #include "G4Poisson.hh" 55 #include "G4Step.hh" 61 #include "G4Step.hh" 56 #include "G4Material.hh" 62 #include "G4Material.hh" 57 #include "G4DynamicParticle.hh" 63 #include "G4DynamicParticle.hh" 58 #include "G4ParticleDefinition.hh" 64 #include "G4ParticleDefinition.hh" 59 #include "G4ParticleChangeForLoss.hh" 65 #include "G4ParticleChangeForLoss.hh" 60 #include "G4PAIPhotData.hh" 66 #include "G4PAIPhotData.hh" 61 #include "G4DeltaAngle.hh" 67 #include "G4DeltaAngle.hh" 62 68 63 ////////////////////////////////////////////// 69 //////////////////////////////////////////////////////////////////////// 64 70 65 using namespace std; 71 using namespace std; 66 72 67 G4PAIPhotModel::G4PAIPhotModel(const G4Particl 73 G4PAIPhotModel::G4PAIPhotModel(const G4ParticleDefinition* p, const G4String& nam) 68 : G4VEmModel(nam),G4VEmFluctuationModel(nam) 74 : G4VEmModel(nam),G4VEmFluctuationModel(nam), 69 fVerbose(0), 75 fVerbose(0), 70 fModelData(nullptr), 76 fModelData(nullptr), 71 fParticle(nullptr) 77 fParticle(nullptr) 72 { 78 { 73 fElectron = G4Electron::Electron(); 79 fElectron = G4Electron::Electron(); 74 fPositron = G4Positron::Positron(); 80 fPositron = G4Positron::Positron(); 75 81 76 fParticleChange = nullptr; 82 fParticleChange = nullptr; 77 83 78 if(p) { SetParticle(p); } 84 if(p) { SetParticle(p); } 79 else { SetParticle(fElectron); } 85 else { SetParticle(fElectron); } 80 86 81 // default generator 87 // default generator 82 SetAngularDistribution(new G4DeltaAngle()); 88 SetAngularDistribution(new G4DeltaAngle()); 83 fLowestTcut = 12.5*CLHEP::eV; 89 fLowestTcut = 12.5*CLHEP::eV; 84 } 90 } 85 91 86 ////////////////////////////////////////////// 92 //////////////////////////////////////////////////////////////////////////// 87 93 88 G4PAIPhotModel::~G4PAIPhotModel() 94 G4PAIPhotModel::~G4PAIPhotModel() 89 { 95 { >> 96 //G4cout << "G4PAIPhotModel::~G4PAIPhotModel() " << this << G4endl; 90 if(IsMaster()) { delete fModelData; fModelDa 97 if(IsMaster()) { delete fModelData; fModelData = nullptr; } 91 } 98 } 92 99 93 ////////////////////////////////////////////// 100 //////////////////////////////////////////////////////////////////////////// 94 101 95 void G4PAIPhotModel::Initialise(const G4Partic 102 void G4PAIPhotModel::Initialise(const G4ParticleDefinition* p, 96 const G4DataVector& cuts) 103 const G4DataVector& cuts) 97 { 104 { 98 if(fVerbose > 1) << 105 if(fVerbose > 0) 99 { 106 { 100 G4cout<<"G4PAIPhotModel::Initialise for "< 107 G4cout<<"G4PAIPhotModel::Initialise for "<<p->GetParticleName()<<G4endl; 101 } 108 } 102 SetParticle(p); 109 SetParticle(p); 103 fParticleChange = GetParticleChangeForLoss() 110 fParticleChange = GetParticleChangeForLoss(); 104 111 105 if( IsMaster() ) 112 if( IsMaster() ) 106 { 113 { >> 114 >> 115 InitialiseElementSelectors(p, cuts); >> 116 107 delete fModelData; 117 delete fModelData; 108 fMaterialCutsCoupleVector.clear(); 118 fMaterialCutsCoupleVector.clear(); 109 119 110 G4double tmin = LowEnergyLimit()*fRatio; 120 G4double tmin = LowEnergyLimit()*fRatio; 111 G4double tmax = HighEnergyLimit()*fRatio; 121 G4double tmax = HighEnergyLimit()*fRatio; 112 fModelData = new G4PAIPhotData(tmin, tmax, 122 fModelData = new G4PAIPhotData(tmin, tmax, fVerbose); 113 123 114 // Prepare initialization 124 // Prepare initialization 115 const G4MaterialTable* theMaterialTable = 125 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable(); 116 size_t numOfMat = G4Material::GetNumberO 126 size_t numOfMat = G4Material::GetNumberOfMaterials(); 117 size_t numRegions = fPAIRegionVector.size( 127 size_t numRegions = fPAIRegionVector.size(); 118 128 119 // protect for unit tests 129 // protect for unit tests 120 if(0 == numRegions) { 130 if(0 == numRegions) { 121 G4Exception("G4PAIModel::Initialise()"," 131 G4Exception("G4PAIModel::Initialise()","em0106",JustWarning, 122 "no G4Regions are registered 132 "no G4Regions are registered for the PAI model - World is used"); 123 fPAIRegionVector.push_back(G4RegionStore 133 fPAIRegionVector.push_back(G4RegionStore::GetInstance() 124 ->GetRegion("DefaultRegionForTheWorld 134 ->GetRegion("DefaultRegionForTheWorld", false)); 125 numRegions = 1; 135 numRegions = 1; 126 } 136 } 127 137 128 for( size_t iReg = 0; iReg < numRegions; + 138 for( size_t iReg = 0; iReg < numRegions; ++iReg ) 129 { 139 { 130 const G4Region* curReg = fPAIRegionVecto 140 const G4Region* curReg = fPAIRegionVector[iReg]; 131 G4Region* reg = const_cast<G4Region*>(cu 141 G4Region* reg = const_cast<G4Region*>(curReg); 132 142 133 for(size_t jMat = 0; jMat < numOfMat; ++ 143 for(size_t jMat = 0; jMat < numOfMat; ++jMat) 134 { 144 { 135 G4Material* mat = (*theMaterialTable)[jMat]; 145 G4Material* mat = (*theMaterialTable)[jMat]; 136 const G4MaterialCutsCouple* cutCouple = reg- 146 const G4MaterialCutsCouple* cutCouple = reg->FindCouple(mat); 137 if(nullptr != cutCouple) << 147 //G4cout << "Couple <" << fCutCouple << G4endl; >> 148 if(cutCouple) 138 { 149 { 139 if(fVerbose > 1) << 150 if(fVerbose>0) 140 { 151 { 141 G4cout << "Reg <" <<curReg->GetName() << 152 G4cout << "Reg <" <<curReg->GetName() << "> mat <" 142 << mat->GetName() << "> fCouple= " 153 << mat->GetName() << "> fCouple= " 143 << cutCouple << ", idx= " << cutCouple-> 154 << cutCouple << ", idx= " << cutCouple->GetIndex() 144 <<" " << p->GetParticleName() 155 <<" " << p->GetParticleName() 145 <<", cuts.size() = " << cuts.size() << G 156 <<", cuts.size() = " << cuts.size() << G4endl; 146 } 157 } 147 // check if this couple is not already ini 158 // check if this couple is not already initialized 148 159 149 size_t n = fMaterialCutsCoupleVector.size( 160 size_t n = fMaterialCutsCoupleVector.size(); 150 161 151 G4bool isnew = true; 162 G4bool isnew = true; 152 if( 0 < n ) 163 if( 0 < n ) 153 { 164 { 154 for(size_t i=0; i<fMaterialCutsCoupleVec 165 for(size_t i=0; i<fMaterialCutsCoupleVector.size(); ++i) 155 { 166 { 156 if(cutCouple == fMaterialCutsCoupleVec 167 if(cutCouple == fMaterialCutsCoupleVector[i]) { 157 isnew = false; 168 isnew = false; 158 break; 169 break; 159 } 170 } 160 } 171 } 161 } 172 } 162 // initialise data banks 173 // initialise data banks 163 if(isnew) { 174 if(isnew) { 164 fMaterialCutsCoupleVector.push_back(cutC 175 fMaterialCutsCoupleVector.push_back(cutCouple); 165 G4double deltaCutInKinEnergy = cuts[cutC 176 G4double deltaCutInKinEnergy = cuts[cutCouple->GetIndex()]; 166 fModelData->Initialise(cutCouple, deltaC 177 fModelData->Initialise(cutCouple, deltaCutInKinEnergy, this); 167 } 178 } 168 } 179 } 169 } 180 } 170 } 181 } 171 InitialiseElementSelectors(p, cuts); << 172 } 182 } 173 } 183 } 174 184 175 ////////////////////////////////////////////// 185 ///////////////////////////////////////////////////////////////////////// 176 186 177 void G4PAIPhotModel::InitialiseLocal(const G4P 187 void G4PAIPhotModel::InitialiseLocal(const G4ParticleDefinition*, 178 G4VEmModel* masterModel) 188 G4VEmModel* masterModel) 179 { 189 { 180 fModelData = static_cast<G4PAIPhotModel*>(ma 190 fModelData = static_cast<G4PAIPhotModel*>(masterModel)->GetPAIPhotData(); 181 fMaterialCutsCoupleVector = static_cast<G4PA 191 fMaterialCutsCoupleVector = static_cast<G4PAIPhotModel*>(masterModel)->GetVectorOfCouples(); 182 SetElementSelectors( masterModel->GetElement 192 SetElementSelectors( masterModel->GetElementSelectors() ); 183 } 193 } 184 194 185 ////////////////////////////////////////////// 195 ////////////////////////////////////////////////////////////////////////////// 186 196 187 G4double G4PAIPhotModel::MinEnergyCut(const G4 197 G4double G4PAIPhotModel::MinEnergyCut(const G4ParticleDefinition*, 188 const G4MaterialCutsCouple*) 198 const G4MaterialCutsCouple*) 189 { 199 { 190 return fLowestTcut; 200 return fLowestTcut; 191 } 201 } 192 202 193 ////////////////////////////////////////////// 203 ////////////////////////////////////////////////////////////////////////////// 194 204 195 G4double G4PAIPhotModel::ComputeDEDXPerVolume( 205 G4double G4PAIPhotModel::ComputeDEDXPerVolume(const G4Material*, 196 const G4ParticleDefinition* p, 206 const G4ParticleDefinition* p, 197 G4double kineticEnergy, 207 G4double kineticEnergy, 198 G4double cutEnergy) 208 G4double cutEnergy) 199 { 209 { 200 G4int coupleIndex = FindCoupleIndex(CurrentC 210 G4int coupleIndex = FindCoupleIndex(CurrentCouple()); 201 if(0 > coupleIndex) { return 0.0; } 211 if(0 > coupleIndex) { return 0.0; } 202 212 203 G4double cut = std::min(MaxSecondaryEnergy(p 213 G4double cut = std::min(MaxSecondaryEnergy(p, kineticEnergy), cutEnergy); >> 214 204 G4double scaledTkin = kineticEnergy*fRatio; 215 G4double scaledTkin = kineticEnergy*fRatio; 205 G4double dedx = fChargeSquare*fModelData->DE << 216 206 return dedx; << 217 return fChargeSquare*fModelData->DEDXPerVolume(coupleIndex, scaledTkin, cut); 207 } 218 } 208 219 209 ////////////////////////////////////////////// 220 ///////////////////////////////////////////////////////////////////////// 210 221 211 G4double G4PAIPhotModel::CrossSectionPerVolume 222 G4double G4PAIPhotModel::CrossSectionPerVolume( const G4Material*, 212 const G4ParticleDefinition* p, 223 const G4ParticleDefinition* p, 213 G4double kineticEnergy, 224 G4double kineticEnergy, 214 G4double cutEnergy, 225 G4double cutEnergy, 215 G4double maxEnergy ) 226 G4double maxEnergy ) 216 { 227 { 217 G4int coupleIndex = FindCoupleIndex(CurrentC 228 G4int coupleIndex = FindCoupleIndex(CurrentCouple()); 218 if(0 > coupleIndex) { return 0.0; } << 229 >> 230 if(0 > coupleIndex) return 0.0; 219 231 220 G4double tmax = std::min(MaxSecondaryEnergy( 232 G4double tmax = std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy); 221 if(tmax <= cutEnergy) { return 0.0; } << 233 >> 234 if(tmax <= cutEnergy) return 0.0; 222 235 223 G4double scaledTkin = kineticEnergy*fRatio; 236 G4double scaledTkin = kineticEnergy*fRatio; 224 G4double xs = fChargeSquare*fModelData->Cros << 237 G4double xsc = fChargeSquare*fModelData->CrossSectionPerVolume(coupleIndex, 225 scal << 238 scaledTkin, 226 return xs; << 239 cutEnergy, tmax); >> 240 return xsc; 227 } 241 } 228 242 229 ////////////////////////////////////////////// 243 /////////////////////////////////////////////////////////////////////////// 230 // 244 // 231 // It is analog of PostStepDoIt in terms of se 245 // It is analog of PostStepDoIt in terms of secondary electron. 232 // 246 // 233 247 234 void G4PAIPhotModel::SampleSecondaries(std::ve 248 void G4PAIPhotModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp, 235 const G4MaterialCutsCouple* matCC, 249 const G4MaterialCutsCouple* matCC, 236 const G4DynamicParticle* dp, 250 const G4DynamicParticle* dp, 237 G4double tmin, 251 G4double tmin, 238 G4double maxEnergy) 252 G4double maxEnergy) 239 { 253 { 240 G4int coupleIndex = FindCoupleIndex(matCC); 254 G4int coupleIndex = FindCoupleIndex(matCC); 241 if(0 > coupleIndex) { return; } 255 if(0 > coupleIndex) { return; } 242 256 243 SetParticle(dp->GetDefinition()); 257 SetParticle(dp->GetDefinition()); 244 258 245 G4double kineticEnergy = dp->GetKineticEnerg 259 G4double kineticEnergy = dp->GetKineticEnergy(); 246 260 247 G4double tmax = MaxSecondaryEnergy(fParticle 261 G4double tmax = MaxSecondaryEnergy(fParticle, kineticEnergy); 248 262 249 if( maxEnergy < tmax) tmax = maxEnergy; 263 if( maxEnergy < tmax) tmax = maxEnergy; 250 if( tmin >= tmax) return; 264 if( tmin >= tmax) return; 251 265 252 G4ThreeVector direction = dp->GetMomentumDir 266 G4ThreeVector direction = dp->GetMomentumDirection(); 253 G4double scaledTkin = kineticEnergy*fRat 267 G4double scaledTkin = kineticEnergy*fRatio; 254 G4double totalEnergy = kineticEnergy + fM 268 G4double totalEnergy = kineticEnergy + fMass; 255 G4double totalMomentum = sqrt(kineticEnergy 269 G4double totalMomentum = sqrt(kineticEnergy*(totalEnergy + fMass)); 256 G4double plRatio = fModelData->GetPla 270 G4double plRatio = fModelData->GetPlasmonRatio(coupleIndex, scaledTkin); 257 271 258 if( G4UniformRand() <= plRatio ) 272 if( G4UniformRand() <= plRatio ) 259 { 273 { 260 G4double deltaTkin = fModelData->SamplePos 274 G4double deltaTkin = fModelData->SamplePostStepPlasmonTransfer(coupleIndex, scaledTkin); 261 275 262 // G4cout<<"G4PAIPhotModel::SampleSecondar 276 // G4cout<<"G4PAIPhotModel::SampleSecondaries; dp "<<dp->GetParticleDefinition()->GetParticleName() 263 // <<"; Tkin = "<<kineticEnergy/keV<<" keV 277 // <<"; Tkin = "<<kineticEnergy/keV<<" keV; transfer = "<<deltaTkin/keV<<" keV "<<G4endl; 264 278 265 if( deltaTkin <= 0. && fVerbose > 0) 279 if( deltaTkin <= 0. && fVerbose > 0) 266 { 280 { 267 G4cout<<"G4PAIPhotModel::SampleSecondary << 281 G4cout<<"G4PAIPhotModel::SampleSecondary e- deltaTkin = "<<deltaTkin<<G4endl; 268 } 282 } 269 if( deltaTkin <= 0.) { return; } << 283 if( deltaTkin <= 0.) return; 270 284 271 if( deltaTkin > tmax) { deltaTkin = tmax; << 285 if( deltaTkin > tmax) deltaTkin = tmax; 272 286 273 const G4Element* anElement = SelectTargetA << 287 const G4Element* anElement = SelectRandomAtom(matCC,fParticle,kineticEnergy); 274 << 288 G4int Z = G4lrint(anElement->GetZ()); 275 G4int Z = anElement->GetZasInt(); << 276 289 277 auto deltaRay = new G4DynamicParticle(fEle << 290 G4DynamicParticle* deltaRay = new G4DynamicParticle(fElectron, 278 GetAngularDistribution()->SampleDirectio 291 GetAngularDistribution()->SampleDirection(dp, deltaTkin, 279 Z, matCC->GetMaterial()), 292 Z, matCC->GetMaterial()), 280 deltaTkin); 293 deltaTkin); 281 294 282 // primary change 295 // primary change 283 296 284 kineticEnergy -= deltaTkin; 297 kineticEnergy -= deltaTkin; 285 298 286 if( kineticEnergy <= 0. ) // kill primary 299 if( kineticEnergy <= 0. ) // kill primary as local? energy deposition 287 { 300 { 288 fParticleChange->SetProposedKineticEnerg 301 fParticleChange->SetProposedKineticEnergy(0.0); 289 fParticleChange->ProposeLocalEnergyDepos 302 fParticleChange->ProposeLocalEnergyDeposit(kineticEnergy+deltaTkin); >> 303 // fParticleChange->ProposeTrackStatus(fStopAndKill); 290 return; 304 return; 291 } 305 } 292 else 306 else 293 { 307 { 294 G4ThreeVector dir = totalMomentum*direct 308 G4ThreeVector dir = totalMomentum*direction - deltaRay->GetMomentum(); 295 direction = dir.unit(); 309 direction = dir.unit(); 296 fParticleChange->SetProposedKineticEnerg 310 fParticleChange->SetProposedKineticEnergy(kineticEnergy); 297 fParticleChange->SetProposedMomentumDire 311 fParticleChange->SetProposedMomentumDirection(direction); 298 vdp->push_back(deltaRay); 312 vdp->push_back(deltaRay); 299 } 313 } 300 } 314 } 301 else // secondary X-ray CR photon 315 else // secondary X-ray CR photon 302 { 316 { 303 G4double deltaTkin = fModelData->Sampl 317 G4double deltaTkin = fModelData->SamplePostStepPhotonTransfer(coupleIndex, scaledTkin); 304 318 305 // G4cout<<"PAIPhotonModel PhotonPostStep 319 // G4cout<<"PAIPhotonModel PhotonPostStepTransfer = "<<deltaTkin/keV<<" keV"<<G4endl; 306 320 307 if( deltaTkin <= 0. ) 321 if( deltaTkin <= 0. ) 308 { 322 { 309 G4cout<<"G4PAIPhotonModel::SampleSeconda 323 G4cout<<"G4PAIPhotonModel::SampleSecondary gamma deltaTkin = "<<deltaTkin<<G4endl; 310 } 324 } 311 if( deltaTkin <= 0.) return; 325 if( deltaTkin <= 0.) return; 312 326 313 if( deltaTkin >= kineticEnergy ) // stop p 327 if( deltaTkin >= kineticEnergy ) // stop primary 314 { 328 { 315 deltaTkin = kineticEnergy; 329 deltaTkin = kineticEnergy; 316 kineticEnergy = 0.0; 330 kineticEnergy = 0.0; 317 } 331 } 318 G4double costheta = 0.; // G4UniformRand() 332 G4double costheta = 0.; // G4UniformRand(); // VG: ??? for start only 319 G4double sintheta = sqrt((1.+costheta)*(1. 333 G4double sintheta = sqrt((1.+costheta)*(1.-costheta)); 320 334 321 // direction of the 'Cherenkov' photon 335 // direction of the 'Cherenkov' photon 322 G4double phi = twopi*G4UniformRand(); 336 G4double phi = twopi*G4UniformRand(); 323 G4double dirx = sintheta*cos(phi), diry = 337 G4double dirx = sintheta*cos(phi), diry = sintheta*sin(phi), dirz = costheta; 324 338 325 G4ThreeVector deltaDirection(dirx,diry,dir 339 G4ThreeVector deltaDirection(dirx,diry,dirz); 326 deltaDirection.rotateUz(direction); 340 deltaDirection.rotateUz(direction); 327 341 328 if( kineticEnergy > 0.) // primary change 342 if( kineticEnergy > 0.) // primary change 329 { 343 { 330 kineticEnergy -= deltaTkin; 344 kineticEnergy -= deltaTkin; 331 fParticleChange->SetProposedKineticEnerg 345 fParticleChange->SetProposedKineticEnergy(kineticEnergy); 332 } 346 } 333 else // stop primary, but pass X-ray CR 347 else // stop primary, but pass X-ray CR 334 { 348 { 335 // fParticleChange->ProposeLocalEnergyDe 349 // fParticleChange->ProposeLocalEnergyDeposit(deltaTkin); 336 fParticleChange->SetProposedKineticEnerg 350 fParticleChange->SetProposedKineticEnergy(0.0); 337 } 351 } 338 // create G4DynamicParticle object for pho 352 // create G4DynamicParticle object for photon ray 339 353 340 auto photonRay = new G4DynamicParticle; << 354 G4DynamicParticle* photonRay = new G4DynamicParticle; 341 photonRay->SetDefinition( G4Gamma::Gamma() 355 photonRay->SetDefinition( G4Gamma::Gamma() ); 342 photonRay->SetKineticEnergy( deltaTkin ); 356 photonRay->SetKineticEnergy( deltaTkin ); 343 photonRay->SetMomentumDirection(deltaDirec 357 photonRay->SetMomentumDirection(deltaDirection); 344 358 345 vdp->push_back(photonRay); 359 vdp->push_back(photonRay); 346 } 360 } 347 return; 361 return; 348 } 362 } 349 363 350 ////////////////////////////////////////////// 364 /////////////////////////////////////////////////////////////////////// 351 365 352 G4double G4PAIPhotModel::SampleFluctuations( << 366 G4double G4PAIPhotModel::SampleFluctuations( const G4MaterialCutsCouple* matCC, 353 const G4MaterialCutsC << 367 const G4DynamicParticle* aParticle, 354 const G4DynamicPartic << 368 G4double, G4double step, 355 const G4double, const << 369 G4double eloss) 356 const G4double step, << 357 { 370 { 358 // return 0.; 371 // return 0.; 359 G4int coupleIndex = FindCoupleIndex(matCC); 372 G4int coupleIndex = FindCoupleIndex(matCC); 360 if(0 > coupleIndex) { return eloss; } 373 if(0 > coupleIndex) { return eloss; } 361 374 362 SetParticle(aParticle->GetDefinition()); 375 SetParticle(aParticle->GetDefinition()); 363 376 >> 377 364 // G4cout << "G4PAIPhotModel::SampleFluctuat 378 // G4cout << "G4PAIPhotModel::SampleFluctuations step(mm)= "<< step/mm 365 // << " Eloss(keV)= " << eloss/keV << " in 379 // << " Eloss(keV)= " << eloss/keV << " in " 366 // << matCC->GetMaterial()->GetName() << G4e 380 // << matCC->GetMaterial()->GetName() << G4endl; >> 381 367 382 368 G4double Tkin = aParticle->GetKineticE 383 G4double Tkin = aParticle->GetKineticEnergy(); 369 G4double scaledTkin = Tkin*fRatio; 384 G4double scaledTkin = Tkin*fRatio; 370 385 371 G4double loss = fModelData->SampleAlongStepP 386 G4double loss = fModelData->SampleAlongStepPhotonTransfer(coupleIndex, Tkin, 372 scaledTkin, << 387 scaledTkin, 373 step*fChargeSquare); << 388 step*fChargeSquare); 374 loss += fModelData->SampleAlongStepPlasmonTr << 389 loss += fModelData->SampleAlongStepPlasmonTransfer(coupleIndex, Tkin, 375 << 390 scaledTkin, >> 391 step*fChargeSquare); >> 392 376 393 377 // G4cout<<" PAIPhotModel::SampleFluctuatio 394 // G4cout<<" PAIPhotModel::SampleFluctuations loss = "<<loss/keV<<" keV, on step = " 378 // <<step/mm<<" mm"<<G4endl; 395 // <<step/mm<<" mm"<<G4endl; 379 return loss; 396 return loss; 380 397 381 } 398 } 382 399 383 ////////////////////////////////////////////// 400 ////////////////////////////////////////////////////////////////////// 384 // 401 // 385 // Returns the statistical estimation of the e 402 // Returns the statistical estimation of the energy loss distribution variance 386 // 403 // 387 404 388 405 389 G4double G4PAIPhotModel::Dispersion(const G4Ma << 406 G4double G4PAIPhotModel::Dispersion( const G4Material* material, 390 const G4Dy << 407 const G4DynamicParticle* aParticle, 391 const G4double tcut, << 408 G4double tmax, 392 const G4double tmax, << 409 G4double step ) 393 const G4double step) << 394 { 410 { 395 G4double particleMass = aParticle->GetMass( 411 G4double particleMass = aParticle->GetMass(); 396 G4double electronDensity = material->GetElec 412 G4double electronDensity = material->GetElectronDensity(); 397 G4double kineticEnergy = aParticle->GetKinet 413 G4double kineticEnergy = aParticle->GetKineticEnergy(); 398 G4double q = aParticle->GetCharge()/eplus; 414 G4double q = aParticle->GetCharge()/eplus; 399 G4double etot = kineticEnergy + particleMass 415 G4double etot = kineticEnergy + particleMass; 400 G4double beta2 = kineticEnergy*(kineticEnerg 416 G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*particleMass)/(etot*etot); 401 G4double siga = (tmax/beta2 - 0.5*tcut) * t << 417 G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * step 402 * electronDensity * q * q; 418 * electronDensity * q * q; 403 419 404 return siga; 420 return siga; >> 421 /* >> 422 G4double loss, sumLoss=0., sumLoss2=0., sigma2, meanLoss=0.; >> 423 for(G4int i = 0; i < fMeanNumber; i++) >> 424 { >> 425 loss = SampleFluctuations(material,aParticle,tmax,step,meanLoss); >> 426 sumLoss += loss; >> 427 sumLoss2 += loss*loss; >> 428 } >> 429 meanLoss = sumLoss/fMeanNumber; >> 430 sigma2 = meanLoss*meanLoss + (sumLoss2-2*sumLoss*meanLoss)/fMeanNumber; >> 431 return sigma2; >> 432 */ 405 } 433 } 406 434 407 ////////////////////////////////////////////// 435 ///////////////////////////////////////////////////////////////////// 408 436 409 G4double G4PAIPhotModel::MaxSecondaryEnergy( c 437 G4double G4PAIPhotModel::MaxSecondaryEnergy( const G4ParticleDefinition* p, 410 G4double kinEnergy) 438 G4double kinEnergy) 411 { 439 { 412 SetParticle(p); 440 SetParticle(p); 413 G4double tmax = kinEnergy; 441 G4double tmax = kinEnergy; 414 if(p == fElectron) { tmax *= 0.5; } 442 if(p == fElectron) { tmax *= 0.5; } 415 else if(p != fPositron) { 443 else if(p != fPositron) { 416 G4double ratio= electron_mass_c2/fMass; 444 G4double ratio= electron_mass_c2/fMass; 417 G4double gamma= kinEnergy/fMass + 1.0; 445 G4double gamma= kinEnergy/fMass + 1.0; 418 tmax = 2.0*electron_mass_c2*(gamma*gamma - 446 tmax = 2.0*electron_mass_c2*(gamma*gamma - 1.) / 419 (1. + 2.0*gamma*ratio + rati 447 (1. + 2.0*gamma*ratio + ratio*ratio); 420 } 448 } 421 return tmax; 449 return tmax; 422 } 450 } 423 451 424 ////////////////////////////////////////////// 452 /////////////////////////////////////////////////////////////// 425 453 426 void G4PAIPhotModel::DefineForRegion(const G4R 454 void G4PAIPhotModel::DefineForRegion(const G4Region* r) 427 { 455 { 428 fPAIRegionVector.push_back(r); 456 fPAIRegionVector.push_back(r); 429 } 457 } 430 458 431 // 459 // 432 // 460 // 433 ////////////////////////////////////////////// 461 ///////////////////////////////////////////////// 434 462