- Timestamp:
- Apr 6, 2009, 12:21:12 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/electromagnetic/standard/src/G4CoulombScatteringModel.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4CoulombScatteringModel.cc,v 1. 29 2007/11/09 11:45:45vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4CoulombScatteringModel.cc,v 1.37 2008/07/31 13:11:34 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 44 44 // 19.10.06 V.Ivanchenko use inheritance from G4eCoulombScatteringModel 45 45 // 09.10.07 V.Ivanchenko reorganized methods, add cut dependence in scattering off e- 46 // 09.06.08 V.Ivanchenko SelectIsotope is moved to the base class 46 47 // 47 48 // Class Description: … … 55 56 #include "Randomize.hh" 56 57 #include "G4ParticleChangeForGamma.hh" 57 #include "G4NistManager.hh"58 58 #include "G4ParticleTable.hh" 59 59 #include "G4IonTable.hh" … … 64 64 using namespace std; 65 65 66 G4CoulombScatteringModel::G4CoulombScatteringModel( 67 G4double thetaMin, G4double thetaMax, G4bool build, 68 G4double tlim, const G4String& nam) 69 : G4eCoulombScatteringModel(thetaMin,thetaMax,build,tlim,nam) 70 { 71 theMatManager = G4NistManager::Instance(); 72 theParticleTable = G4ParticleTable::GetParticleTable(); 73 } 66 G4CoulombScatteringModel::G4CoulombScatteringModel(const G4String& nam) 67 : G4eCoulombScatteringModel(nam) 68 {} 74 69 75 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 84 79 G4double kinEnergy, 85 80 G4double Z, 86 G4double A,81 G4double, 87 82 G4double cutEnergy, 88 83 G4double) 89 84 { 90 if(p == particle && kinEnergy == tkin && Z == targetZ && 91 A == targetA && cutEnergy == ecut) return nucXSection; 92 93 // Lab system 94 G4double ekin = std::max(keV, kinEnergy); 95 nucXSection = ComputeElectronXSectionPerAtom(p,ekin,Z,A,cutEnergy); 85 SetupParticle(p); 86 G4double ekin = std::max(lowEnergyLimit, kinEnergy); 87 SetupKinematic(ekin, cutEnergy); 88 89 // save lab system kinematics 90 G4double xtkin = tkin; 91 G4double xmom2 = mom2; 92 G4double xinvb = invbeta2; 96 93 97 94 // CM system 98 95 G4int iz = G4int(Z); 99 G4double m 1 = theMatManager->GetAtomicMassAmu(iz)*amu_c2;96 G4double m2 = fNistManager->GetAtomicMassAmu(iz)*amu_c2; 100 97 G4double etot = tkin + mass; 101 98 G4double ptot = sqrt(mom2); 102 G4double bet = ptot/(etot + m1); 103 G4double gam = 1.0/sqrt((1.0 - bet)*(1.0 + bet)); 104 G4double momCM= gam*(ptot - bet*etot); 105 106 // G4cout << "ptot= " << ptot << " etot= " << etot << " beta= " 107 // << bet << " gam= " << gam << " Z= " << Z << " A= " << A << G4endl; 108 // G4cout << " CM. mom= " << momCM << " m= " << m 109 // << " m1= " << m1 << " iz= " << iz <<G4endl; 110 111 G4double momCM2 = momCM*momCM; 112 cosTetMaxNuc = std::max(cosThetaMax, 1.0 - 0.5*q2Limit/momCM2); 113 if(1.5 > targetA && p == theProton && cosTetMaxNuc < 0.0) cosTetMaxNuc = 0.0; 114 //G4cout << " ctmax= " << cosTetMaxNuc 115 //<< " ctmin= " << cosThetaMin << G4endl; 116 117 // Cross section in CM system 118 if(cosTetMaxNuc < cosThetaMin) { 119 G4double effmass = mass*m1/(mass + m1); 120 G4double x1 = 1.0 - cosThetaMin; 121 G4double x2 = 1.0 - cosTetMaxNuc; 122 G4double z1 = x1 + screenZ; 123 G4double z2 = x2 + screenZ; 124 G4double d = 1.0/formfactA; 125 G4double zn1= x1 + d; 126 G4double zn2= x2 + d; 127 nucXSection += coeff*Z*Z*chargeSquare*(1.0 + effmass*effmass/momCM2) 128 *(1./z1 - 1./z2 + 1./zn1 - 1./zn2 + 129 2.0*formfactA*std::log(z1*zn2/(z2*zn1)))/momCM2; 130 //G4cout << "XS: x1= " << x1 << " x2= " << x2 131 //<< " cross= " << cross << G4endl; 132 //G4cout << "momCM2= " << momCM2 << " invbeta2= " << invbeta2 133 // << " coeff= " << coeff << G4endl; 134 } 135 if(nucXSection < 0.0) nucXSection = 0.0; 136 return nucXSection; 137 } 138 139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 140 141 G4double G4CoulombScatteringModel::SelectIsotope(const G4Element* elm) 142 { 143 G4double N = elm->GetN(); 144 G4int ni = elm->GetNumberOfIsotopes(); 145 if(ni > 0) { 146 G4double* ab = elm->GetRelativeAbundanceVector(); 147 G4double x = G4UniformRand(); 148 G4int idx; 149 for(idx=0; idx<ni; idx++) { 150 x -= ab[idx]; 151 if (x <= 0.0) break; 152 } 153 if(idx >= ni) { 154 G4cout << "G4CoulombScatteringModel::SelectIsotope WARNING: " 155 << "abandance vector for" 156 << elm->GetName() << " is not normalised to unit" << G4endl; 157 } else { 158 N = G4double(elm->GetIsotope(idx)->GetN()); 159 } 160 } 161 return N; 99 100 G4double m12 = mass*mass; 101 G4double momCM= ptot*m2/sqrt(m12 + m2*m2 + 2.0*etot*m2); 102 103 mom2 = momCM*momCM; 104 tkin = sqrt(mom2 + m12) - mass; 105 invbeta2 = 1.0 + m12/mom2; 106 107 SetupTarget(Z, tkin); 108 109 G4double xsec = CrossSectionPerAtom(); 110 111 // restore Lab system kinematics 112 tkin = xtkin; 113 mom2 = xmom2; 114 invbeta2 = xinvb; 115 116 return xsec; 162 117 } 163 118 … … 169 124 const G4DynamicParticle* dp, 170 125 G4double cutEnergy, 171 G4double maxEnergy)126 G4double) 172 127 { 173 const G4Material* aMaterial = couple->GetMaterial();174 const G4ParticleDefinition* p = dp->GetDefinition();175 128 G4double kinEnergy = dp->GetKineticEnergy(); 176 177 // Select isotope and setup 178 SetupParticle(p); 179 const G4Element* elm = 180 SelectRandomAtom(aMaterial,p,kinEnergy,cutEnergy,maxEnergy); 181 G4double Z = elm->GetZ(); 182 G4double A = SelectIsotope(elm); 129 if(kinEnergy <= DBL_MIN) return; 130 DefineMaterial(couple); 131 SetupParticle(dp->GetDefinition()); 132 G4double ekin = std::max(lowEnergyLimit, kinEnergy); 133 SetupKinematic(ekin, cutEnergy); 134 135 // Choose nucleus 136 currentElement = SelectRandomAtom(couple,particle,ekin,ecut,tkin); 137 138 G4double Z = currentElement->GetZ(); 183 139 G4int iz = G4int(Z); 184 G4int ia = G4int(A + 0.5); 185 186 G4double cross = 187 ComputeCrossSectionPerAtom(p,kinEnergy,Z,A,cutEnergy,maxEnergy); 188 189 G4double costm = cosTetMaxNuc; 190 G4double formf = formfactA; 191 if(G4UniformRand()*cross < elecXSection) { 192 costm = cosTetMaxElec; 193 formf = 0.0; 194 } 195 196 // G4cout << "SampleSec: Ekin= " << kinEnergy << " m1= " << m1 197 // << " Z= "<< Z << " A= " <<A<< G4endl; 198 199 if(costm >= cosThetaMin) return; 200 201 // kinematics in CM system 202 G4double m1 = theParticleTable->GetIonTable()->GetNucleusMass(iz, ia); 203 G4double etot = kinEnergy + mass; 140 G4int ia = SelectIsotopeNumber(currentElement); 141 G4double m2 = theParticleTable->GetIonTable()->GetNucleusMass(iz, ia); 142 143 // CM system 144 G4double etot = tkin + mass; 204 145 G4double ptot = sqrt(mom2); 205 G4double bet = ptot/(etot + m1); 146 147 G4double momCM= ptot*m2/sqrt(mass*mass + m2*m2 + 2.0*etot*m2); 148 mom2 = momCM*momCM; 149 G4double m12 = mass*mass; 150 G4double eCM = sqrt(mom2 + m12); 151 152 // a correction for heavy projectile 153 G4double fm = m2/(mass + m2); 154 invbeta2 = 1.0 + m12*fm*fm/mom2; 155 156 // sample scattering angle in CM system 157 SetupTarget(Z, eCM - mass); 158 159 G4double cost = SampleCosineTheta(); 160 G4double z1 = 1.0 - cost; 161 if(z1 < 0.0) return; 162 163 G4double sint = sqrt(z1*(1.0 + cost)); 164 G4double phi = twopi * G4UniformRand(); 165 166 // kinematics in the Lab system 167 G4double bet = ptot/(etot + m2); 206 168 G4double gam = 1.0/sqrt((1.0 - bet)*(1.0 + bet)); 207 G4double pCM = gam*(ptot - bet*etot); 208 G4double eCM = gam*(etot - bet*ptot); 209 210 G4double x1 = 1. - cosThetaMin + screenZ; 211 G4double x2 = 1. - costm; 212 G4double x3 = cosThetaMin - costm; 213 214 G4double grej, z, z1; 215 do { 216 z = G4UniformRand()*x3; 217 z1 = (x1*x2 - screenZ*z)/(x1 + z); 218 if(z1 < 0.0) z1 = 0.0; 219 else if(z1 > 2.0) z1 = 2.0; 220 grej = 1.0/(1.0 + formf*z1); 221 } while ( G4UniformRand() > grej*grej ); 222 223 G4double cost = 1.0 - z1; 224 G4double sint= sqrt(z1*(2.0 - z1)); 225 226 G4double phi = twopi * G4UniformRand(); 227 228 // projectile after scattering 229 G4double pzCM = pCM*cost; 230 G4ThreeVector v1(pCM*cos(phi)*sint,pCM*sin(phi)*sint,gam*(pzCM + bet*eCM)); 169 G4double pzCM = momCM*cost; 170 171 G4ThreeVector v1(momCM*cos(phi)*sint,momCM*sin(phi)*sint,gam*(pzCM + bet*eCM)); 231 172 G4ThreeVector dir = dp->GetMomentumDirection(); 232 173 G4ThreeVector newDirection = v1.unit(); 233 174 newDirection.rotateUz(dir); 234 175 fParticleChange->ProposeMomentumDirection(newDirection); 176 235 177 G4double elab = gam*(eCM + bet*pzCM); 236 G4doubleekin = elab - mass;178 ekin = elab - mass; 237 179 if(ekin < 0.0) ekin = 0.0; 238 G4double plab = sqrt(ekin*(ekin + 2.0*mass));239 180 fParticleChange->SetProposedKineticEnergy(ekin); 240 181 241 182 // recoil 242 183 G4double erec = kinEnergy - ekin; 243 if(erec > Z*aMaterial->GetIonisation()->GetMeanExcitationEnergy()) { 184 G4double th = 185 std::min(recoilThreshold, 186 Z*currentElement->GetIonisation()->GetMeanExcitationEnergy()); 187 188 if(erec > th) { 244 189 G4ParticleDefinition* ion = theParticleTable->FindIon(iz, ia, 0, iz); 190 G4double plab = sqrt(ekin*(ekin + 2.0*mass)); 245 191 G4ThreeVector p2 = (ptot*dir - plab*newDirection).unit(); 246 192 G4DynamicParticle* newdp = new G4DynamicParticle(ion, p2, erec);
Note: See TracChangeset
for help on using the changeset viewer.