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 header file 30 // 31 // 32 // File name: G4MuBetheBlochModel 33 // 34 // Author: Vladimir Ivanchenko on base 35 // 36 // Creation date: 09.08.2002 37 // 38 // Modifications: 39 // 40 // 04-12-02 Fix problem of G4DynamicParticle c 41 // 23-12-02 Change interface in order to move 42 // 27-01-03 Make models region aware (V.Ivanch 43 // 13-02-03 Add name (V.Ivanchenko) 44 // 10-02-04 Calculation of radiative correctio 45 // 08-04-05 Major optimisation of internal int 46 // 12-04-05 Add usage of G4EmCorrections (V.Iv 47 // 13-02-06 ComputeCrossSectionPerElectron, Co 48 // 49 50 // 51 // ------------------------------------------- 52 // 53 54 //....oooOO0OOooo........oooOO0OOooo........oo 55 //....oooOO0OOooo........oooOO0OOooo........oo 56 57 #include "G4MuBetheBlochModel.hh" 58 #include "G4PhysicalConstants.hh" 59 #include "G4SystemOfUnits.hh" 60 #include "Randomize.hh" 61 #include "G4Electron.hh" 62 #include "G4LossTableManager.hh" 63 #include "G4EmCorrections.hh" 64 #include "G4ParticleChangeForLoss.hh" 65 #include "G4Log.hh" 66 #include "G4Exp.hh" 67 #include "G4DeltaAngle.hh" 68 69 G4double G4MuBetheBlochModel::xgi[]={ 0.0199, 70 0.7628, 71 72 G4double G4MuBetheBlochModel::wgi[]={ 0.0506, 73 0.1569, 74 75 //....oooOO0OOooo........oooOO0OOooo........oo 76 77 G4MuBetheBlochModel::G4MuBetheBlochModel(const 78 const 79 : G4VEmModel(nam), 80 limitRadCorrection(250.*CLHEP::MeV), 81 limitKinEnergy(100.*CLHEP::keV), 82 logLimitKinEnergy(G4Log(limitKinEnergy)), 83 twoln10(2.0*G4Log(10.0)), 84 alphaprime(CLHEP::fine_structure_const/CLH 85 { 86 theElectron = G4Electron::Electron(); 87 corr = G4LossTableManager::Instance()->EmCor 88 if(nullptr != p) { SetParticle(p); } 89 } 90 91 //....oooOO0OOooo........oooOO0OOooo........oo 92 93 G4double G4MuBetheBlochModel::MinEnergyCut(con 94 con 95 { 96 return couple->GetMaterial()->GetIonisation( 97 } 98 99 //....oooOO0OOooo........oooOO0OOooo........oo 100 101 G4double G4MuBetheBlochModel::MaxSecondaryEner 102 103 { 104 G4double tau = kinEnergy/mass; 105 G4double tmax = 2.0*CLHEP::electron_mass_c2* 106 (1. + 2.0*(tau + 1.)*ratio + 107 return tmax; 108 } 109 110 //....oooOO0OOooo........oooOO0OOooo........oo 111 112 void G4MuBetheBlochModel::SetParticle(const G4 113 { 114 if(nullptr == particle) { 115 particle = p; 116 mass = particle->GetPDGMass(); 117 massSquare = mass*mass; 118 ratio = CLHEP::electron_mass_c2/mass; 119 } 120 } 121 122 //....oooOO0OOooo........oooOO0OOooo........oo 123 124 void G4MuBetheBlochModel::Initialise(const G4P 125 const G4D 126 { 127 SetParticle(p); 128 if(nullptr == fParticleChange) { 129 fParticleChange = GetParticleChangeForLoss 130 if(UseAngularGeneratorFlag() && nullptr == 131 SetAngularDistribution(new G4DeltaAngle( 132 } 133 } 134 } 135 136 //....oooOO0OOooo........oooOO0OOooo........oo 137 138 G4double G4MuBetheBlochModel::ComputeCrossSect 139 con 140 141 142 143 { 144 G4double cross = 0.0; 145 G4double tmax = MaxSecondaryEnergy(p, kineti 146 G4double maxEnergy = std::min(tmax, maxKinEn 147 if(cutEnergy < maxEnergy) { 148 149 G4double totEnergy = kineticEnergy + mass; 150 G4double energy2 = totEnergy*totEnergy; 151 G4double beta2 = kineticEnergy*(kineticEne 152 153 cross = 1.0/cutEnergy - 1.0/maxEnergy - 154 beta2*G4Log(maxEnergy/cutEnergy)/tmax + 155 0.5*(maxEnergy - cutEnergy)/energy2; 156 157 // radiative corrections of R. Kokoulin 158 if (maxEnergy > limitKinEnergy && kineticE 159 160 G4double logtmax = G4Log(maxEnergy); 161 G4double logtmin = G4Log(std::max(cutEne 162 G4double logstep = logtmax - logtmin; 163 G4double dcross = 0.0; 164 165 for (G4int ll=0; ll<8; ++ll) { 166 G4double ep = G4Exp(logtmin + xgi[ll]* 167 G4double a1 = G4Log(1.0 + 2.0*ep/CLHEP 168 G4double a3 = G4Log(4.0*totEnergy*(tot 169 dcross += wgi[ll]*(1.0/ep - beta2/tmax 170 } 171 cross += dcross*logstep*alphaprime; 172 } 173 cross *= CLHEP::twopi_mc2_rcl2/beta2; 174 } 175 // G4cout << "tmin= " << cutEnergy << " tma 176 // << " cross= " << cross << G4endl; 177 return cross; 178 } 179 180 //....oooOO0OOooo........oooOO0OOooo........oo 181 182 G4double G4MuBetheBlochModel::ComputeCrossSect 183 con 184 185 186 187 188 { 189 G4double cross = Z*ComputeCrossSectionPerEle 190 (p,ki 191 return cross; 192 } 193 194 //....oooOO0OOooo........oooOO0OOooo........oo 195 196 G4double G4MuBetheBlochModel::CrossSectionPerV 197 con 198 con 199 200 201 202 { 203 G4double eDensity = material->GetElectronDen 204 G4double cross = eDensity*ComputeCrossSectio 205 (p,ki 206 return cross; 207 } 208 209 //....oooOO0OOooo........oooOO0OOooo........oo 210 211 G4double G4MuBetheBlochModel::ComputeDEDXPerVo 212 213 214 215 { 216 G4double tmax = MaxSecondaryEnergy(p, kinet 217 G4double tau = kineticEnergy/mass; 218 G4double cutEnergy = std::min(cut, tmax); 219 G4double gam = tau + 1.0; 220 G4double bg2 = tau * (tau+2.0); 221 G4double beta2 = bg2/(gam*gam); 222 223 G4double eexc = material->GetIonisation()-> 224 G4double eexc2 = eexc*eexc; 225 226 G4double eDensity = material->GetElectronDen 227 228 G4double dedx = G4Log(2.0*CLHEP::electron_ma 229 -(1.0 + cutEnergy/tmax)*beta2 230 231 G4double totEnergy = kineticEnergy + mass; 232 G4double del = 0.5*cutEnergy/totEnergy; 233 dedx += del*del; 234 235 // density correction 236 G4double x = G4Log(bg2)/twoln10; 237 dedx -= material->GetIonisation()->DensityCo 238 239 // shell and high order corrections 240 dedx -= 2.0*corr->ShellCorrection(p,material 241 242 // radiative corrections of R. Kokoulin 243 if (cutEnergy > limitKinEnergy && kineticEne 244 245 G4double logtmax = G4Log(cutEnergy); 246 G4double logstep = logtmax - logLimitKinEn 247 G4double dloss = 0.0; 248 G4double ftot2= 0.5/(totEnergy*totEnergy); 249 250 for (G4int ll=0; ll<8; ++ll) { 251 G4double ep = G4Exp(logLimitKinEnergy + 252 G4double a1 = G4Log(1.0 + 2.0*ep/CLHEP:: 253 G4double a3 = G4Log(4.0*totEnergy*(totEn 254 dloss += wgi[ll]*(1.0 - beta2*ep/tmax + 255 } 256 dedx += dloss*logstep*alphaprime; 257 } 258 dedx *= CLHEP::twopi_mc2_rcl2*eDensity/beta2 259 260 //High order corrections 261 dedx += corr->HighOrderCorrections(p,materia 262 dedx = std::max(dedx, 0.); 263 return dedx; 264 } 265 266 //....oooOO0OOooo........oooOO0OOooo........oo 267 268 void G4MuBetheBlochModel::SampleSecondaries( 269 std::vector<G4Dynami 270 const G4MaterialCutsCouple* couple, 271 const G4DynamicParticle* dp, 272 G4double minKinEnergy, 273 G4double maxEnergy) 274 { 275 G4double kineticEnergy = dp->GetKineticEnerg 276 G4double tmax = MaxSecondaryEnergy(dp->GetDe 277 G4double maxKinEnergy = std::min(maxEnergy, 278 if(minKinEnergy >= maxKinEnergy) { return; } 279 280 G4double totEnergy = kineticEnergy + mass; 281 G4double etot2 = totEnergy*totEnergy; 282 G4double beta2 = kineticEnergy*(kineticEnerg 283 284 G4double grej = 1.; 285 G4bool radC = (tmax > limitKinEnergy && kine 286 if(radC) { 287 G4double a0 = G4Log(2.*totEnergy/mass); 288 grej += alphaprime*a0*a0; 289 } 290 291 G4double tkin, f; 292 293 // sampling follows ... 294 do { 295 G4double q = G4UniformRand(); 296 tkin = minKinEnergy*maxKinEnergy/(minKinEn 297 f = 1.0 - beta2*tkin/tmax + 0.5*tkin*tkin/ 298 299 if(radC && tkin > limitKinEnergy) { 300 G4double a1 = G4Log(1.0 + 2.0*tkin/CLHEP 301 G4double a3 = G4Log(4.0*totEnergy*(totEn 302 f *= (1. + alphaprime*a1*(a3 - a1)); 303 } 304 305 if(f > grej) { 306 G4cout << "G4MuBetheBlochModel::Sample 307 << "Majorant " << grej << " < " 308 << f << " for edelta= " << tkin 309 << " tmin= " << minKinEnergy << 310 << G4endl; 311 } 312 // Loop checking, 03-Aug-2015, Vladimir Iv 313 } while( grej*G4UniformRand() > f ); 314 315 G4ThreeVector deltaDirection; 316 317 if(UseAngularGeneratorFlag()) { 318 const G4Material* mat = couple->GetMateria 319 deltaDirection = GetAngularDistribution()- 320 SelectRandomAtomNumber(ma 321 } else { 322 323 G4double deltaMom = std::sqrt(tkin * (tkin 324 G4double totalMom = totEnergy*std::sqrt(be 325 G4double cost = tkin * (totEnergy + CLHEP: 326 (deltaMom * totalMom); 327 cost = std::min(cost, 1.0); 328 const G4double sint = std::sqrt((1.0 - cos 329 const G4double phi = twopi*G4UniformRand() 330 331 deltaDirection.set(sint*std::cos(phi),sint 332 deltaDirection.rotateUz(dp->GetMomentumDir 333 } 334 // create G4DynamicParticle object for delta 335 auto delta = new G4DynamicParticle(theElectr 336 vdp->push_back(delta); 337 338 // primary change 339 kineticEnergy -= tkin; 340 G4ThreeVector dir = dp->GetMomentum() - delt 341 dir = dir.unit(); 342 fParticleChange->SetProposedKineticEnergy(ki 343 fParticleChange->SetProposedMomentumDirectio 344 } 345 346 //....oooOO0OOooo........oooOO0OOooo........oo 347