- Timestamp:
- Jun 18, 2010, 11:42:07 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/electromagnetic/standard/src/G4eCoulombScatteringModel.cc
r1228 r1315 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4eCoulombScatteringModel.cc,v 1. 78 2009/10/28 10:14:13vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 3$26 // $Id: G4eCoulombScatteringModel.cc,v 1.89 2010/05/27 14:22:05 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-04-beta-cand-01 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 47 47 // 09.06.08 V.Ivanchenko add SelectIsotope and sampling of the recoil ion 48 48 // 16.06.09 C.Consolandi fixed computation of effective mass 49 // 27.05.10 V.Ivanchenko added G4WentzelOKandVIxSection class to 50 // compute cross sections and sample scattering angle 49 51 // 50 52 // … … 60 62 #include "G4DataVector.hh" 61 63 #include "G4ElementTable.hh" 62 #include "G4PhysicsLogVector.hh"63 64 #include "G4ParticleChangeForGamma.hh" 64 #include "G4Electron.hh"65 #include "G4Positron.hh"66 65 #include "G4Proton.hh" 67 66 #include "G4ParticleTable.hh" 68 67 #include "G4ProductionCutsTable.hh" 69 68 #include "G4NucleiProperties.hh" 70 71 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 72 73 G4double G4eCoulombScatteringModel::ScreenRSquare[] = {0.0}; 74 G4double G4eCoulombScatteringModel::FormFactor[] = {0.0}; 69 #include "G4Pow.hh" 70 #include "G4LossTableManager.hh" 71 #include "G4NistManager.hh" 72 73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 75 74 76 75 using namespace std; … … 80 79 cosThetaMin(1.0), 81 80 cosThetaMax(-1.0), 82 q2Limit(TeV*TeV),83 alpha2(fine_structure_const*fine_structure_const),84 faclim(100.0),85 81 isInitialised(false) 86 82 { 87 83 fNistManager = G4NistManager::Instance(); 88 84 theParticleTable = G4ParticleTable::GetParticleTable(); 89 theElectron = G4Electron::Electron();90 thePositron = G4Positron::Positron();91 85 theProton = G4Proton::Proton(); 92 86 currentMaterial = 0; 93 87 currentElement = 0; 94 lowEnergyLimit = 0.1*keV; 95 G4double p0 = electron_mass_c2*classic_electr_radius; 96 coeff = twopi*p0*p0; 97 tkin = targetZ = mom2 = DBL_MIN; 98 elecXSection = nucXSection = 0.0; 88 lowEnergyLimit = 1*eV; 99 89 recoilThreshold = 0.*keV; 100 ecut = DBL_MAX;101 90 particle = 0; 102 91 currentCouple = 0; 103 104 // Thomas-Fermi screening radii 105 // Formfactors from A.V. Butkevich et al., NIM A 488 (2002) 282 106 107 if(0.0 == ScreenRSquare[0]) { 108 G4double a0 = electron_mass_c2/0.88534; 109 G4double constn = 6.937e-6/(MeV*MeV); 110 111 ScreenRSquare[0] = alpha2*a0*a0; 112 for(G4int j=1; j<100; j++) { 113 G4double x = a0*fNistManager->GetZ13(j); 114 ScreenRSquare[j] = alpha2*x*x; 115 x = fNistManager->GetA27(j); 116 FormFactor[j] = constn*x*x; 117 } 118 } 92 wokvi = new G4WentzelOKandVIxSection(); 119 93 } 120 94 … … 122 96 123 97 G4eCoulombScatteringModel::~G4eCoulombScatteringModel() 124 {} 98 { 99 delete wokvi; 100 } 125 101 126 102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 131 107 SetupParticle(p); 132 108 currentCouple = 0; 133 elecXSection = nucXSection = 0.0;134 tkin = targetZ = mom2 = DBL_MIN;135 ecut = etag = DBL_MAX;136 109 cosThetaMin = cos(PolarAngleLimit()); 110 wokvi->Initialise(p, cosThetaMin); 111 /* 112 G4cout << "G4eCoulombScatteringModel: factorA2(GeV^2) = " << factorA2/(GeV*GeV) 113 << " 1-cos(ThetaLimit)= " << 1 - cosThetaMin 114 << " cos(thetaMax)= " << cosThetaMax 115 << G4endl; 116 */ 137 117 pCuts = G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsVector(3); 138 118 //G4cout << "!!! G4eCoulombScatteringModel::Initialise for " … … 151 131 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 152 132 153 void G4eCoulombScatteringModel::ComputeMaxElectronScattering(G4double cutEnergy)154 {155 ecut = cutEnergy;156 G4double tmax = tkin;157 cosTetMaxElec = 1.0;158 if(mass > MeV) {159 G4double ratio = electron_mass_c2/mass;160 G4double tau = tkin/mass;161 tmax = 2.0*electron_mass_c2*tau*(tau + 2.)/162 (1.0 + 2.0*ratio*(tau + 1.0) + ratio*ratio);163 cosTetMaxElec = 1.0 - std::min(cutEnergy, tmax)*electron_mass_c2/mom2;164 } else {165 166 if(particle == theElectron) tmax *= 0.5;167 G4double t = std::min(cutEnergy, tmax);168 G4double mom21 = t*(t + 2.0*electron_mass_c2);169 G4double t1 = tkin - t;170 //G4cout << "tkin= " << tkin << " t= " << t << " t1= " << t1 << G4endl;171 if(t1 > 0.0) {172 G4double mom22 = t1*(t1 + 2.0*mass);173 G4double ctm = (mom2 + mom22 - mom21)*0.5/sqrt(mom2*mom22);174 //G4cout << "ctm= " << ctm << G4endl;175 if(ctm < 1.0) cosTetMaxElec = ctm;176 if(ctm < -1.0) cosTetMaxElec = -1.0;177 }178 }179 }180 181 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......182 183 133 G4double G4eCoulombScatteringModel::ComputeCrossSectionPerAtom( 184 134 const G4ParticleDefinition* p, … … 190 140 // << p->GetParticleName()<<" Z= "<<Z<<" e(MeV)= "<< kinEnergy/MeV << G4endl; 191 141 G4double xsec = 0.0; 192 SetupParticle(p); 193 if(kinEnergy < lowEnergyLimit) return xsec; 194 SetupKinematic(kinEnergy, cutEnergy); 195 if(cosTetMaxNuc < cosTetMinNuc) { 196 SetupTarget(Z, kinEnergy); 197 xsec = CrossSectionPerAtom(); 142 if(p != particle) { SetupParticle(p); } 143 144 // cross section is set to zero to avoid problems in sample secondary 145 if(kinEnergy < lowEnergyLimit) { return xsec; } 146 DefineMaterial(CurrentCouple()); 147 cosTetMinNuc = wokvi->SetupKinematic(kinEnergy, currentMaterial); 148 if(cosThetaMax < cosTetMinNuc) { 149 G4int iz = G4int(Z); 150 cosTetMinNuc = wokvi->SetupTarget(iz, cutEnergy); 151 cosTetMaxNuc = cosThetaMax; 152 if(iz == 1 && cosTetMaxNuc < 0.0 && particle == theProton) { 153 cosTetMaxNuc = 0.0; 154 } 155 xsec = wokvi->ComputeNuclearCrossSection(cosTetMinNuc, cosTetMaxNuc); 156 elecRatio = wokvi->ComputeElectronCrossSection(cosTetMinNuc, cosThetaMax); 157 xsec += elecRatio; 158 if(xsec > 0.0) { elecRatio /= xsec; } 198 159 } 199 160 /* 200 G4cout << "e(MeV)= " << ekin/MeV << "cosTetMinNuc= " << cosTetMinNuc 201 << " cosTetMaxNuc= " << cosTetMaxNuc 202 << " cosTetMaxElec= " << cosTetMaxElec 161 G4cout << "e(MeV)= " << kinEnergy/MeV << " xsec(b)= " << xsec/barn 162 << " 1-cosTetMinNuc= " << 1-cosTetMinNuc 163 << " 1-cosTetMaxNuc2= " << 1-cosTetMaxNuc2 164 << " 1-cosTetMaxElec= " << 1-cosTetMaxElec 203 165 << " screenZ= " << screenZ 204 166 << " formfactA= " << formfactA << G4endl; 205 167 */ 206 168 return xsec; 207 }208 209 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......210 211 G4double G4eCoulombScatteringModel::CrossSectionPerAtom()212 {213 // This method needs initialisation before be called214 //G4double fac = coeff*targetZ*chargeSquare*invbeta2/mom2;215 216 G4double meff = targetMass/(mass+targetMass);217 G4double fac = coeff*targetZ*chargeSquare*invbeta2/(mom2*meff*meff);218 219 elecXSection = 0.0;220 nucXSection = 0.0;221 222 G4double x = 1.0 - cosTetMinNuc;223 G4double x1 = x + screenZ;224 225 if(cosTetMaxElec2 < cosTetMinNuc) {226 elecXSection = fac*(cosTetMinNuc - cosTetMaxElec2)/227 (x1*(1.0 - cosTetMaxElec2 + screenZ));228 nucXSection = elecXSection;229 }230 231 //G4cout << "XS tkin(MeV)= " << tkin<<" xs= " <<nucXSection232 // << " costmax= " << cosTetMaxNuc2233 // << " costmin= " << cosTetMinNuc << " Z= " << targetZ <<G4endl;234 if(cosTetMaxNuc2 < cosTetMinNuc) {235 G4double s = screenZ*formfactA;236 G4double z1 = 1.0 - cosTetMaxNuc2 + screenZ;237 G4double s1 = 1.0 - s;238 G4double d = s1/formfactA;239 //G4cout <<"x1= "<<x1<<" z1= " <<z1<<" s= "<<s << " d= " <<d <<G4endl;240 if(d < 0.2*x1) {241 G4double x2 = x1*x1;242 G4double z2 = z1*z1;243 x = (1.0/(x1*x2) - 1.0/(z1*z2) - d*1.5*(1.0/(x2*x2) - 1.0/(z2*z2)))/244 (3.0*formfactA*formfactA);245 } else {246 G4double x2 = x1 + d;247 G4double z2 = z1 + d;248 x = (1.0/x1 - 1.0/z1 + 1.0/x2 - 1.0/z2 - 2.0*log(z1*x2/(z2*x1))/d)/(s1*s1);249 }250 nucXSection += fac*targetZ*x;251 }252 //G4cout<<" cross(bn)= "<<nucXSection/barn<<" xsElec(bn)= "<<elecXSection/barn253 // << " Asc= " << screenZ << G4endl;254 255 return nucXSection;256 169 } 257 170 … … 266 179 { 267 180 G4double kinEnergy = dp->GetKineticEnergy(); 268 if(kinEnergy < lowEnergyLimit) return; 269 DefineMaterial(couple); 181 if(kinEnergy < lowEnergyLimit) { return; } 270 182 SetupParticle(dp->GetDefinition()); 271 183 272 SetupKinematic(kinEnergy, cutEnergy);273 184 //G4cout << "G4eCoulombScatteringModel::SampleSecondaries e(MeV)= " 274 185 // << kinEnergy << " " << particle->GetParticleName() … … 279 190 kinEnergy,cutEnergy,kinEnergy); 280 191 281 SetupTarget(currentElement->GetZ(),kinEnergy); 282 192 G4double Z = currentElement->GetZ(); 193 194 if(ComputeCrossSectionPerAtom(particle,kinEnergy, Z, 195 kinEnergy, cutEnergy, kinEnergy) == 0.0) 196 { return; } 197 198 G4int iz = G4int(Z); 283 199 G4int ia = SelectIsotopeNumber(currentElement); 284 targetMass = G4NucleiProperties::GetNuclearMass(ia, iz); 285 286 G4double cost = SampleCosineTheta(); 287 G4double z1 = 1.0 - cost; 288 if(z1 < 0.0) return; 289 290 G4double sint = sqrt(z1*(1.0 + cost)); 291 292 //G4cout<<"## Sampled sint= " << sint << " Z= " << targetZ << " A= " << ia 293 // << " screenZ= " << screenZ << " cn= " << formfactA << G4endl; 294 295 G4double phi = twopi * G4UniformRand(); 200 G4double targetMass = G4NucleiProperties::GetNuclearMass(ia, iz); 201 202 G4ThreeVector newDirection = 203 wokvi->SampleSingleScattering(cosTetMinNuc, cosThetaMax, elecRatio); 204 G4double cost = newDirection.z(); 296 205 297 206 G4ThreeVector direction = dp->GetMomentumDirection(); 298 G4ThreeVector newDirection(cos(phi)*sint,sin(phi)*sint,cost);299 207 newDirection.rotateUz(direction); 300 208 … … 303 211 // recoil sampling assuming a small recoil 304 212 // and first order correction to primary 4-momentum 305 G4double q2 = 2*z1*mom2;306 G4double trec = q2/(sqrt(targetMass*targetMass + q2) + targetMass);213 G4double mom2 = wokvi->GetMomentumSquare(); 214 G4double trec = mom2*(1.0 - cost)/(targetMass + (mass + kinEnergy)*(1.0 + cost)); 307 215 G4double finalT = kinEnergy - trec; 308 216 //G4cout<<"G4eCoulombScatteringModel: finalT= "<<finalT<<" Trec= "<<trec<<G4endl; … … 332 240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 333 241 334 G4double G4eCoulombScatteringModel::SampleCosineTheta() 335 { 336 G4double costm = cosTetMaxNuc2; 337 G4double formf = formfactA; 338 G4double prob = 0.0; 339 G4double xs = CrossSectionPerAtom(); 340 if(xs > 0.0) prob = elecXSection/xs; 341 342 // scattering off e or A? 343 if(G4UniformRand() < prob) { 344 costm = cosTetMaxElec2; 345 formf = 0.0; 346 } 347 348 /* 349 G4cout << "SampleCost: e(MeV)= " << tkin 350 << " 1-ctmaxN= " << 1. - cosTetMinNuc 351 << " 1-ctmax= " << 1. - costm 352 << " Z= " << targetZ 353 << G4endl; 354 */ 355 356 if(costm >= cosTetMinNuc) return 2.0; 357 358 G4double x1 = 1. - cosTetMinNuc + screenZ; 359 G4double x2 = 1. - costm + screenZ; 360 G4double x3 = cosTetMinNuc - costm; 361 G4double grej, z1; 362 do { 363 z1 = x1*x2/(x1 + G4UniformRand()*x3) - screenZ; 364 grej = 1.0/(1.0 + formf*z1); 365 } while ( G4UniformRand() > grej*grej ); 366 367 if(mass > MeV) { 368 if(G4UniformRand() > (1. - z1*0.5)/(1.0 + z1*sqrt(mom2)/targetMass)) { 369 return 2.0; 370 } 371 } 372 //G4cout << "z1= " << z1 << " cross= " << nucXSection/barn 373 // << " crossE= " << elecXSection/barn << G4endl; 374 375 return 1.0 - z1; 376 } 377 378 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 379 380 242
Note: See TracChangeset
for help on using the changeset viewer.