Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 // ------------------------------------------- 28 // 29 // GEANT4 Class 30 // File name: G4PAIModel.cc 31 // 32 // Author: Vladimir.Grichine@cern.ch on base o 33 // 34 // Creation date: 05.10.2003 35 // 36 // Modifications: 37 // 38 // 17.08.04 V.Grichine, bug fixed for Tkin<=0 39 // 16.08.04 V.Grichine, bug fixed in massRatio 40 // SampleSecondary 41 // 08.04.05 Major optimisation of internal int 42 // 26.07.09 Fixed logic to work with several m 43 // 21.11.10 V. Grichine verbose flag for proto 44 // check sandia table 45 // 12.06.13 V. Grichine Bug fixed in SampleSec 46 // (fMass -> proton_mass_c2) 47 // 19.08.13 V.Ivanchenko extract data handling 48 // added sharing of internal data bet 49 // 50 51 #include "G4PAIModel.hh" 52 53 #include "G4SystemOfUnits.hh" 54 #include "G4PhysicalConstants.hh" 55 #include "G4Region.hh" 56 #include "G4MaterialCutsCouple.hh" 57 #include "G4MaterialTable.hh" 58 #include "G4RegionStore.hh" 59 60 #include "Randomize.hh" 61 #include "G4Electron.hh" 62 #include "G4Positron.hh" 63 #include "G4Poisson.hh" 64 #include "G4Step.hh" 65 #include "G4Material.hh" 66 #include "G4DynamicParticle.hh" 67 #include "G4ParticleDefinition.hh" 68 #include "G4ParticleChangeForLoss.hh" 69 #include "G4PAIModelData.hh" 70 #include "G4DeltaAngle.hh" 71 72 ////////////////////////////////////////////// 73 74 using namespace std; 75 76 G4PAIModel::G4PAIModel(const G4ParticleDefinit 77 : G4VEmModel(nam),G4VEmFluctuationModel(nam) 78 fVerbose(0), 79 fModelData(nullptr), 80 fParticle(nullptr) 81 { 82 fElectron = G4Electron::Electron(); 83 fPositron = G4Positron::Positron(); 84 85 fParticleChange = nullptr; 86 87 if(p) { SetParticle(p); } 88 else { SetParticle(fElectron); } 89 90 // default generator 91 SetAngularDistribution(new G4DeltaAngle()); 92 fLowestTcut = 12.5*CLHEP::eV; 93 } 94 95 ////////////////////////////////////////////// 96 97 G4PAIModel::~G4PAIModel() 98 { 99 if(IsMaster()) { delete fModelData; } 100 } 101 102 ////////////////////////////////////////////// 103 104 void G4PAIModel::Initialise(const G4ParticleDe 105 const G4DataVector& cuts) 106 { 107 if(fVerbose > 1) { 108 G4cout<<"G4PAIModel::Initialise for "<<p-> 109 } 110 SetParticle(p); 111 fParticleChange = GetParticleChangeForLoss() 112 113 if(IsMaster()) { 114 115 delete fModelData; 116 fMaterialCutsCoupleVector.clear(); 117 if(fVerbose > 1) { 118 G4cout << "G4PAIModel instantiates data 119 << G4endl; 120 } 121 G4double tmin = LowEnergyLimit()*fRatio; 122 G4double tmax = HighEnergyLimit()*fRatio; 123 fModelData = new G4PAIModelData(tmin, tmax 124 125 // Prepare initialization 126 const G4MaterialTable* theMaterialTable = 127 std::size_t numOfMat = G4Material::GetNu 128 std::size_t numRegions = fPAIRegionVector. 129 130 // protect for unit tests 131 if(0 == numRegions) { 132 G4Exception("G4PAIModel::Initialise()"," 133 "no G4Regions are registered 134 fPAIRegionVector.push_back(G4RegionStore 135 ->GetRegion("DefaultRegionForTheWorld 136 numRegions = 1; 137 } 138 139 if(fVerbose > 1) { 140 G4cout << "G4PAIModel is defined for " < 141 << "; number of materials " << numOfMat 142 } 143 for(std::size_t iReg = 0; iReg<numRegions; 144 const G4Region* curReg = fPAIRegionVecto 145 G4Region* reg = const_cast<G4Region*>(cu 146 147 for(std::size_t jMat = 0; jMat<numOfMat; 148 G4Material* mat = (*theMaterialTable)[jMat]; 149 const G4MaterialCutsCouple* cutCouple = reg- 150 std::size_t n = fMaterialCutsCoupleVector.si 151 if(nullptr != cutCouple) { 152 if(fVerbose > 1) { 153 G4cout << "Region <" << curReg->GetName( 154 << mat->GetName() << "> CoupleIndex= " 155 << cutCouple->GetIndex() 156 << " " << p->GetParticleName() 157 << " cutsize= " << cuts.size() << G4end 158 } 159 // check if this couple is not already ini 160 G4bool isnew = true; 161 if(0 < n) { 162 for(std::size_t i=0; i<n; ++i) { 163 G4cout << i << G4endl; 164 if(cutCouple == fMaterialCutsCoupleVec 165 isnew = false; 166 break; 167 } 168 } 169 } 170 // initialise data banks 171 // G4cout << " isNew: " << isnew << " " 172 if(isnew) { 173 fMaterialCutsCoupleVector.push_back(cutC 174 fModelData->Initialise(cutCouple, this); 175 } 176 } 177 } 178 } 179 InitialiseElementSelectors(p, cuts); 180 } 181 } 182 183 ////////////////////////////////////////////// 184 185 void G4PAIModel::InitialiseLocal(const G4Parti 186 G4VEmModel* masterModel) 187 { 188 fModelData = static_cast<G4PAIModel*>(master 189 fMaterialCutsCoupleVector = 190 static_cast<G4PAIModel*>(masterModel)->Get 191 SetElementSelectors(masterModel->GetElementS 192 } 193 194 ////////////////////////////////////////////// 195 196 G4double G4PAIModel::MinEnergyCut(const G4Part 197 const G4MaterialCutsCouple*) 198 { 199 return fLowestTcut; 200 } 201 202 ////////////////////////////////////////////// 203 204 G4double G4PAIModel::ComputeDEDXPerVolume(cons 205 const G4ParticleDefinition* p, 206 G4double kineticEnergy, 207 G4double cutEnergy) 208 { 209 G4int coupleIndex = FindCoupleIndex(CurrentC 210 if(0 > coupleIndex) { return 0.0; } 211 212 G4double cut = std::min(MaxSecondaryEnergy(p 213 G4double scaledTkin = kineticEnergy*fRatio; 214 G4double dedx = fChargeSquare*fModelData->DE 215 return dedx; 216 } 217 218 ////////////////////////////////////////////// 219 220 G4double G4PAIModel::CrossSectionPerVolume( co 221 const G4ParticleDefinition* p, 222 G4double kineticEnergy, 223 G4double cutEnergy, 224 G4double maxEnergy ) 225 { 226 G4int coupleIndex = FindCoupleIndex(CurrentC 227 if(0 > coupleIndex) { return 0.0; } 228 229 G4double tmax = std::min(MaxSecondaryEnergy( 230 if(tmax <= cutEnergy) { return 0.0; } 231 232 G4double scaledTkin = kineticEnergy*fRatio; 233 G4double xs = fChargeSquare*fModelData->Cros 234 scal 235 return xs; 236 } 237 238 ////////////////////////////////////////////// 239 // 240 // It is analog of PostStepDoIt in terms of se 241 // 242 243 void G4PAIModel::SampleSecondaries(std::vector 244 const G4MaterialCutsCouple* matCC, 245 const G4DynamicParticle* dp, 246 G4double tmin, 247 G4double maxEnergy) 248 { 249 G4int coupleIndex = FindCoupleIndex(matCC); 250 251 //G4cout << "G4PAIModel::SampleSecondaries: 252 if(0 > coupleIndex) { return; } 253 254 SetParticle(dp->GetDefinition()); 255 G4double kineticEnergy = dp->GetKineticEnerg 256 257 G4double tmax = MaxSecondaryEnergy(fParticle 258 if(maxEnergy < tmax) { tmax = maxEnergy; } 259 if(tmin >= tmax) { return; } 260 261 G4ThreeVector direction= dp->GetMomentumDire 262 G4double scaledTkin = kineticEnergy*fRati 263 G4double totalEnergy = kineticEnergy + fMa 264 G4double totalMomentum = sqrt(kineticEnergy* 265 266 G4double deltaTkin = 267 fModelData->SamplePostStepTransfer(coupleI 268 269 //G4cout<<"G4PAIModel::SampleSecondaries; de 270 // <<" keV "<< " Escaled(MeV)= " << scaledT 271 272 if( !(deltaTkin <= 0.) && !(deltaTkin > 0)) 273 G4cout<<"G4PAIModel::SampleSecondaries; de 274 <<" keV "<< " Escaled(MeV)= " << scaledTki 275 return; 276 } 277 if( deltaTkin <= 0.) { return; } 278 279 if( deltaTkin > tmax) { deltaTkin = tmax; } 280 281 const G4Element* anElement = SelectTargetAto 282 283 284 G4int Z = anElement->GetZasInt(); 285 286 auto deltaRay = new G4DynamicParticle(fElect 287 GetAngularDistribution()->SampleDirectio 288 Z, matCC->GetMaterial()), 289 deltaTkin); 290 291 // primary change 292 kineticEnergy -= deltaTkin; 293 G4ThreeVector dir = totalMomentum*direction 294 direction = dir.unit(); 295 fParticleChange->SetProposedKineticEnergy(ki 296 fParticleChange->SetProposedMomentumDirectio 297 298 vdp->push_back(deltaRay); 299 } 300 301 ////////////////////////////////////////////// 302 303 G4double G4PAIModel::SampleFluctuations(const 304 const 305 const 306 const G4double, 307 const 308 const G4double eloss) 309 { 310 G4int coupleIndex = FindCoupleIndex(matCC); 311 if(0 > coupleIndex) { return eloss; } 312 313 SetParticle(aParticle->GetDefinition()); 314 315 /* 316 G4cout << "G4PAIModel::SampleFluctuations st 317 << " Eloss(keV)= " << eloss/keV << " in " 318 << matCC->Getmaterial()->GetName() << G4end 319 */ 320 321 G4double Tkin = aParticle->GetKineticE 322 G4double scaledTkin = Tkin*fRatio; 323 324 G4double loss = fModelData->SampleAlongStepT 325 scaledTkin, tcut, 326 step*fChargeSquare); 327 328 // G4cout<<"PAIModel AlongStepLoss = "<<loss 329 //<<step/mm<<" mm"<<G4endl; 330 return loss; 331 332 } 333 334 ////////////////////////////////////////////// 335 // 336 // Returns the statistical estimation of the e 337 // 338 339 340 G4double G4PAIModel::Dispersion( const G4Mater 341 const G4Dynam 342 const G4double tcut, 343 const G4double tmax, 344 const G4double step ) 345 { 346 G4double particleMass = aParticle->GetMass( 347 G4double electronDensity = material->GetElec 348 G4double kineticEnergy = aParticle->GetKinet 349 G4double q = aParticle->GetCharge()/eplus; 350 G4double etot = kineticEnergy + particleMass 351 G4double beta2 = kineticEnergy*(kineticEnerg 352 G4double siga = (tmax/beta2 - 0.5*tcut) * t 353 * electronDensity * q * q; 354 355 return siga; 356 } 357 358 ////////////////////////////////////////////// 359 360 G4double G4PAIModel::MaxSecondaryEnergy( const 361 G4double kinEnergy) 362 { 363 SetParticle(p); 364 G4double tmax = kinEnergy; 365 if(p == fElectron) { tmax *= 0.5; } 366 else if(p != fPositron) { 367 G4double ratio= electron_mass_c2/fMass; 368 G4double gamma= kinEnergy/fMass + 1.0; 369 tmax = 2.0*electron_mass_c2*(gamma*gamma - 370 (1. + 2.0*gamma*ratio + rati 371 } 372 return tmax; 373 } 374 375 ////////////////////////////////////////////// 376 377 void G4PAIModel::DefineForRegion(const G4Regio 378 { 379 fPAIRegionVector.push_back(r); 380 } 381 382 ////////////////////////////////////////////// 383 384