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: G4WentzelVIRelXSection.cc 74581 2013-10-15 12:03:25Z gcosmo $ 26 // 27 // 27 // ------------------------------------------- 28 // ------------------------------------------------------------------- 28 // 29 // 29 // GEANT4 Class file 30 // GEANT4 Class file 30 // 31 // 31 // 32 // 32 // File name: G4WentzelVIRelXSection 33 // File name: G4WentzelVIRelXSection 33 // 34 // 34 // Author: V.Ivanchenko 35 // Author: V.Ivanchenko 35 // 36 // 36 // Creation date: 08.06.2012 from G4WentzelOKa 37 // Creation date: 08.06.2012 from G4WentzelOKandVIxSection 37 // 38 // 38 // Modifications: 39 // Modifications: 39 // 40 // 40 // 41 // 41 42 42 // ------------------------------------------- 43 // ------------------------------------------------------------------- 43 // 44 // 44 45 45 //....oooOO0OOooo........oooOO0OOooo........oo 46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 46 //....oooOO0OOooo........oooOO0OOooo........oo 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 47 48 48 #include "G4WentzelVIRelXSection.hh" 49 #include "G4WentzelVIRelXSection.hh" >> 50 #include "G4PhysicalConstants.hh" >> 51 #include "G4SystemOfUnits.hh" >> 52 #include "Randomize.hh" >> 53 #include "G4Electron.hh" >> 54 #include "G4Positron.hh" >> 55 #include "G4Proton.hh" >> 56 #include "G4LossTableManager.hh" >> 57 #include "G4Log.hh" 49 58 50 //....oooOO0OOooo........oooOO0OOooo........oo 59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 51 60 52 G4WentzelVIRelXSection::G4WentzelVIRelXSection << 61 G4double G4WentzelVIRelXSection::ScreenRSquare[] = {0.0}; >> 62 G4double G4WentzelVIRelXSection::FormFactor[] = {0.0}; >> 63 >> 64 using namespace std; >> 65 >> 66 G4WentzelVIRelXSection::G4WentzelVIRelXSection() : >> 67 numlimit(0.1), >> 68 nwarnings(0), >> 69 nwarnlimit(50), >> 70 alpha2(fine_structure_const*fine_structure_const) >> 71 { >> 72 fNistManager = G4NistManager::Instance(); >> 73 fG4pow = G4Pow::GetInstance(); >> 74 theElectron = G4Electron::Electron(); >> 75 thePositron = G4Positron::Positron(); >> 76 theProton = G4Proton::Proton(); >> 77 lowEnergyLimit = 1.0*eV; >> 78 G4double p0 = electron_mass_c2*classic_electr_radius; >> 79 coeff = twopi*p0*p0; >> 80 particle = 0; >> 81 >> 82 // Thomas-Fermi screening radii >> 83 // Formfactors from A.V. Butkevich et al., NIM A 488 (2002) 282 >> 84 >> 85 if(0.0 == ScreenRSquare[0]) { >> 86 G4double a0 = electron_mass_c2/0.88534; >> 87 G4double constn = 6.937e-6/(MeV*MeV); >> 88 >> 89 ScreenRSquare[0] = alpha2*a0*a0; >> 90 for(G4int j=1; j<100; ++j) { >> 91 G4double x = a0*fG4pow->Z13(j); >> 92 //ScreenRSquare[j] = 0.5*(1 + exp(-j*j*0.001))*alpha2*x*x; >> 93 ScreenRSquare[j] = 0.5*alpha2*x*x; >> 94 x = fNistManager->GetA27(j); >> 95 FormFactor[j] = constn*x*x; >> 96 } >> 97 } >> 98 currentMaterial = 0; >> 99 elecXSRatio = factB = factD = formfactA = screenZ = 0.0; >> 100 cosTetMaxElec = cosTetMaxNuc = invbeta2 = kinFactor = gam0pcmp = pcmp2 = 1.0; >> 101 >> 102 factB1= 0.5*CLHEP::pi*fine_structure_const; >> 103 >> 104 Initialise(theElectron, 1.0); >> 105 targetMass = proton_mass_c2; >> 106 } 53 107 54 //....oooOO0OOooo........oooOO0OOooo........oo 108 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 55 109 56 G4WentzelVIRelXSection::~G4WentzelVIRelXSectio << 110 G4WentzelVIRelXSection::~G4WentzelVIRelXSection() >> 111 {} 57 112 58 //....oooOO0OOooo........oooOO0OOooo........oo 113 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 59 114 60 G4double G4WentzelVIRelXSection::SetupKinemati << 115 void G4WentzelVIRelXSection::Initialise(const G4ParticleDefinition* p, 61 cons << 116 G4double CosThetaLim) 62 { 117 { 63 if(kinEnergy != tkin || mat != currentMateri << 118 SetupParticle(p); >> 119 tkin = mom2 = momCM2 = 0.0; >> 120 ecut = etag = DBL_MAX; >> 121 targetZ = 0; >> 122 cosThetaMax = CosThetaLim; >> 123 G4double a = >> 124 G4LossTableManager::Instance()->FactorForAngleLimit()*CLHEP::hbarc/CLHEP::fermi; >> 125 factorA2 = 0.5*a*a; >> 126 currentMaterial = 0; >> 127 } 64 128 65 currentMaterial = mat; << 129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 66 tkin = kinEnergy; << 130 67 G4double momLab2 = tkin*(tkin + 2.0*mass) << 131 void G4WentzelVIRelXSection::SetupParticle(const G4ParticleDefinition* p) 68 << 132 { 69 G4double etot = tkin + mass; << 133 particle = p; 70 G4double ptot = std::sqrt(momLab2); << 134 mass = particle->GetPDGMass(); 71 G4double m12 = mass*mass; << 135 spin = particle->GetPDGSpin(); 72 << 136 if(0.0 != spin) { spin = 0.5; } 73 // relativistic reduced mass from publucat << 137 G4double q = std::fabs(particle->GetPDGCharge()/eplus); 74 // A.P. Martynenko, R.N. Faustov, Teoret. << 138 chargeSquare = q*q; 75 << 139 charge3 = chargeSquare*q; 76 //incident particle & target nucleus << 140 tkin = 0.0; 77 G4double Ecm = std::sqrt(m12 + targetMass* << 141 currentMaterial = 0; 78 G4double mu_rel = mass*targetMass/Ecm; << 142 targetZ = 0; 79 G4double momCM = ptot*targetMass/Ecm; << 80 // relative system << 81 mom2 = momCM*momCM; << 82 invbeta2 = 1.0 + mu_rel*mu_rel/mom2; << 83 << 84 factB = spin/invbeta2; << 85 factD = std::sqrt(mom2)/targetMass; << 86 cosTetMaxNuc = isCombined ? << 87 std::max(cosThetaMax, 1.-factorA2*mat->G << 88 : cosThetaMax; << 89 } << 90 return cosTetMaxNuc; << 91 } 143 } 92 144 >> 145 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 146 >> 147 G4double >> 148 G4WentzelVIRelXSection::SetupTarget(G4int Z, G4double cut) >> 149 { >> 150 G4double cosTetMaxNuc2 = cosTetMaxNuc; >> 151 if(Z != targetZ || tkin != etag) { >> 152 etag = tkin; >> 153 targetZ = Z; >> 154 if(targetZ > 99) { targetZ = 99; } >> 155 SetTargetMass(fNistManager->GetAtomicMassAmu(targetZ)*CLHEP::amu_c2); >> 156 //G4double tmass2 = targetMass*targetMass; >> 157 //G4double etot = tkin + mass; >> 158 //G4double invmass2 = mass*mass + tmass2 + 2*etot*targetMass; >> 159 //momCM2 = mom2*tmass2/invmass2; >> 160 //gam0pcmp = (etot + targetMass)*targetMass/invmass2; >> 161 //pcmp2 = tmass2/invmass2; >> 162 >> 163 kinFactor = coeff*targetZ*chargeSquare*invbeta2/mom2; >> 164 >> 165 screenZ = ScreenRSquare[targetZ]/mom2; >> 166 if(Z > 1) { >> 167 screenZ *= std::min(Z*1.13,1.13 +3.76*Z*Z*invbeta2*alpha2*chargeSquare); >> 168 /* >> 169 if(mass > MeV) { >> 170 screenZ *= std::min(Z*1.13,1.13 +3.76*Z*Z*invbeta2*alpha2*chargeSquare); >> 171 } else { >> 172 G4double tau = tkin/mass; >> 173 // screenZ *= std::min(Z*invbeta2, >> 174 screenZ *= std::min(Z*1.13, >> 175 (1.13 +3.76*Z*Z*invbeta2*alpha2*std::sqrt(tau/(tau + fG4pow->Z23(Z))))); >> 176 } >> 177 */ >> 178 } >> 179 if(targetZ == 1 && cosTetMaxNuc2 < 0.0 && particle == theProton) { >> 180 cosTetMaxNuc2 = 0.0; >> 181 } >> 182 formfactA = FormFactor[targetZ]*mom2; >> 183 >> 184 cosTetMaxElec = 1.0; >> 185 ComputeMaxElectronScattering(cut); >> 186 } >> 187 return cosTetMaxNuc2; >> 188 } >> 189 93 //....oooOO0OOooo........oooOO0OOooo........oo 190 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 94 191 >> 192 G4double >> 193 G4WentzelVIRelXSection::ComputeTransportCrossSectionPerAtom(G4double cosTMax) >> 194 { >> 195 G4double xsec = 0.0; >> 196 if(cosTMax >= 1.0) { return xsec; } >> 197 >> 198 G4double xSection = 0.0; >> 199 G4double x = 0; >> 200 G4double y = 0; >> 201 G4double x1= 0; >> 202 G4double x2= 0; >> 203 G4double xlog = 0.0; >> 204 >> 205 G4double costm = std::max(cosTMax,cosTetMaxElec); >> 206 G4double fb = screenZ*factB; >> 207 >> 208 // scattering off electrons >> 209 if(costm < 1.0) { >> 210 x = (1.0 - costm)/screenZ; >> 211 if(x < numlimit) { >> 212 x2 = 0.5*x*x; >> 213 y = x2*(1.0 - 1.3333333*x + 3*x2); >> 214 if(0.0 < factB) { y -= fb*x2*x*(0.6666667 - x); } >> 215 } else { >> 216 x1= x/(1 + x); >> 217 xlog = G4Log(1.0 + x); >> 218 y = xlog - x1; >> 219 if(0.0 < factB) { y -= fb*(x + x1 - 2*xlog); } >> 220 } >> 221 >> 222 if(y < 0.0) { >> 223 ++nwarnings; >> 224 if(nwarnings < nwarnlimit) { >> 225 G4cout << "G4WentzelVIRelXSection::ComputeTransportCrossSectionPerAtom scattering on e- <0" >> 226 << G4endl; >> 227 G4cout << "y= " << y >> 228 << " e(MeV)= " << tkin << " p(MeV/c)= " << sqrt(mom2) >> 229 << " Z= " << targetZ << " " >> 230 << particle->GetParticleName() << G4endl; >> 231 G4cout << " 1-costm= " << 1.0-costm << " screenZ= " << screenZ >> 232 << " x= " << x << G4endl; >> 233 } >> 234 y = 0.0; >> 235 } >> 236 xSection = y; >> 237 } >> 238 /* >> 239 G4cout << "G4WentzelVI:XS per A " << " Z= " << targetZ >> 240 << " e(MeV)= " << tkin/MeV << " XSel= " << xSection >> 241 << " cut(MeV)= " << ecut/MeV >> 242 << " zmaxE= " << (1.0 - cosTetMaxElec)/screenZ >> 243 << " zmaxN= " << (1.0 - cosThetaMax)/screenZ >> 244 << " 1-costm= " << 1.0 - cosThetaMax << G4endl; >> 245 */ >> 246 // scattering off nucleus >> 247 if(cosTMax < 1.0) { >> 248 x = (1.0 - cosTMax)/screenZ; >> 249 if(x < numlimit) { >> 250 x2 = 0.5*x*x; >> 251 y = x2*(1.0 - 1.3333333*x + 3*x2); >> 252 if(0.0 < factB) { y -= fb*x2*x*(0.6666667 - x); } >> 253 } else { >> 254 x1= x/(1 + x); >> 255 xlog = G4Log(1.0 + x); >> 256 y = xlog - x1; >> 257 if(0.0 < factB) { y -= fb*(x + x1 - 2*xlog); } >> 258 } >> 259 >> 260 if(y < 0.0) { >> 261 ++nwarnings; >> 262 if(nwarnings < nwarnlimit) { >> 263 G4cout << "G4WentzelVIRelXSection::ComputeTransportCrossSectionPerAtom scattering on e- <0" >> 264 << G4endl; >> 265 G4cout << "y= " << y >> 266 << " e(MeV)= " << tkin << " Z= " << targetZ << " " >> 267 << particle->GetParticleName() << G4endl; >> 268 G4cout << " formfactA= " << formfactA << " screenZ= " << screenZ >> 269 << " x= " << " x1= " << x1 <<G4endl; >> 270 } >> 271 y = 0.0; >> 272 } >> 273 xSection += y*targetZ; >> 274 } >> 275 xSection *= kinFactor; >> 276 /* >> 277 G4cout << "Z= " << targetZ << " XStot= " << xSection/barn >> 278 << " screenZ= " << screenZ << " formF= " << formfactA >> 279 << " for " << particle->GetParticleName() >> 280 << " m= " << mass << " 1/v= " << sqrt(invbeta2) << " p= " << sqrt(mom2) >> 281 << " x= " << x >> 282 << G4endl; >> 283 */ >> 284 return xSection; >> 285 } >> 286 >> 287 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 288 >> 289 G4ThreeVector >> 290 G4WentzelVIRelXSection::SampleSingleScattering(G4double cosTMin, >> 291 G4double cosTMax, >> 292 G4double elecRatio) >> 293 { >> 294 G4ThreeVector v(0.0,0.0,1.0); >> 295 >> 296 G4double formf = formfactA; >> 297 G4double cost1 = cosTMin; >> 298 G4double cost2 = cosTMax; >> 299 if(elecRatio > 0.0) { >> 300 if(G4UniformRand() <= elecRatio) { >> 301 formf = 0.0; >> 302 cost1 = std::max(cost1,cosTetMaxElec); >> 303 cost2 = std::max(cost2,cosTetMaxElec); >> 304 } >> 305 } >> 306 if(cost1 < cost2) { return v; } >> 307 >> 308 G4double w1 = 1. - cost1 + screenZ; >> 309 G4double w2 = 1. - cost2 + screenZ; >> 310 G4double z1 = w1*w2/(w1 + G4UniformRand()*(w2 - w1)) - screenZ; >> 311 >> 312 //G4double fm = 1.0 + formf*z1/(1.0 + (mass + tkin)*z1/targetMass); >> 313 G4double fm = 1.0 + formf*z1; >> 314 //G4double grej = (1. - z1*factB)/( (1.0 + z1*factD)*fm*fm ); >> 315 G4double grej = (1. - z1*factB + factB1*targetZ*sqrt(z1*factB)*(2 - z1))/( (1.0 + z1*factD)*fm*fm ); >> 316 // "false" scattering >> 317 if( G4UniformRand() > grej ) { return v; } >> 318 // } >> 319 G4double cost = 1.0 - z1; >> 320 >> 321 if(cost > 1.0) { cost = 1.0; } >> 322 else if(cost < -1.0) { cost =-1.0; } >> 323 G4double sint = sqrt((1.0 - cost)*(1.0 + cost)); >> 324 //G4cout << "sint= " << sint << G4endl; >> 325 G4double phi = twopi*G4UniformRand(); >> 326 G4double vx1 = sint*cos(phi); >> 327 G4double vy1 = sint*sin(phi); >> 328 >> 329 // only direction is changed >> 330 v.set(vx1,vy1,cost); >> 331 return v; >> 332 } >> 333 >> 334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... >> 335 >> 336 void >> 337 G4WentzelVIRelXSection::ComputeMaxElectronScattering(G4double cutEnergy) >> 338 { >> 339 if(mass > MeV) { >> 340 G4double ratio = electron_mass_c2/mass; >> 341 G4double tau = tkin/mass; >> 342 G4double tmax = 2.0*electron_mass_c2*tau*(tau + 2.)/ >> 343 (1.0 + 2.0*ratio*(tau + 1.0) + ratio*ratio); >> 344 //tmax = std::min(tmax, targetZ*targetZ*10*eV); >> 345 cosTetMaxElec = 1.0 - std::min(cutEnergy, tmax)*electron_mass_c2/mom2; >> 346 } else { >> 347 >> 348 G4double tmax = tkin; >> 349 if(particle == theElectron) { tmax *= 0.5; } >> 350 //tmax = std::min(tmax, targetZ*targetZ*10*eV); >> 351 G4double t = std::min(cutEnergy, tmax); >> 352 G4double mom21 = t*(t + 2.0*electron_mass_c2); >> 353 G4double t1 = tkin - t; >> 354 //G4cout <<"tkin=" <<tkin<<" tmax= "<<tmax<<" t= " >> 355 //<<t<< " t1= "<<t1<<" cut= "<<ecut<<G4endl; >> 356 if(t1 > 0.0) { >> 357 G4double mom22 = t1*(t1 + 2.0*mass); >> 358 G4double ctm = (mom2 + mom22 - mom21)*0.5/sqrt(mom2*mom22); >> 359 if(ctm < 1.0) { cosTetMaxElec = ctm; } >> 360 if(particle == theElectron && cosTetMaxElec < 0.0) { cosTetMaxElec = 0.0; } >> 361 } >> 362 } >> 363 } >> 364 >> 365 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 95 366