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 // G4 Low energy model: n-p scattering 28 // F.W. Jones, L.G. Greeniaus, H.P. Wellisch 29 30 // 11-OCT-2007 F.W. Jones: removed erroneous c 31 // exchange of particles. 32 // FWJ 27-AUG-2010: extended to 5 GeV by Tony 33 // 06-Aug-15 A.Ribon migrating to G4Pow 34 35 #include "G4LEHadronProtonElastic.hh" 36 #include "G4PhysicalConstants.hh" 37 #include "G4SystemOfUnits.hh" 38 #include "Randomize.hh" 39 #include "G4ios.hh" 40 #include "G4Pow.hh" 41 #include "G4PhysicsModelCatalog.hh" 42 43 44 G4LEHadronProtonElastic::G4LEHadronProtonElast 45 G4HadronElastic("G4LEHadronProtonElastic") 46 { 47 secID = G4PhysicsModelCatalog::GetModelID( " 48 SetMinEnergy(0.); 49 SetMaxEnergy(20.*MeV); 50 } 51 52 G4LEHadronProtonElastic::~G4LEHadronProtonElas 53 { 54 theParticleChange.Clear(); 55 } 56 57 G4HadFinalState* 58 G4LEHadronProtonElastic::ApplyYourself(const G 59 G4Nucleus& targetN 60 { 61 theParticleChange.Clear(); 62 const G4HadProjectile* aParticle = &aTrack 63 64 G4double P = aParticle->GetTotalMomentum() 65 G4double Px = aParticle->Get4Momentum().x( 66 G4double Py = aParticle->Get4Momentum().y( 67 G4double Pz = aParticle->Get4Momentum().z( 68 G4double ek = aParticle->GetKineticEnergy( 69 G4ThreeVector theInitial = aParticle->Get4 70 71 if (verboseLevel > 1) 72 { 73 G4double E = aParticle->GetTotalEnergy() 74 G4double E0 = aParticle->GetDefinition() 75 G4double Q = aParticle->GetDefinition()- 76 G4int A = targetNucleus.GetA_asInt(); 77 G4int Z = targetNucleus.GetZ_asInt(); 78 G4cout << "G4LEHadronProtonElastic:Apply 79 << aParticle->GetDefinition()->Ge 80 G4cout << "P = " << P/GeV << " GeV/c" 81 << ", Px = " << Px/GeV << " GeV/c 82 << ", Py = " << Py/GeV << " GeV/c 83 << ", Pz = " << Pz/GeV << " GeV/c 84 G4cout << "E = " << E/GeV << " GeV" 85 << ", kinetic energy = " << ek/Ge 86 << ", mass = " << E0/GeV << " GeV 87 << ", charge = " << Q << G4endl; 88 G4cout << "G4LEHadronProtonElastic:Apply 89 G4cout << "A = " << A 90 << ", Z = " << Z 91 << ", atomic mass " 92 << G4Proton::Proton()->GetPDGMas 93 << G4endl; 94 // 95 // GHEISHA ADD operation to get total en 96 // 97 E += proton_mass_c2; 98 G4double E02 = E*E - P*P; 99 E0 = std::sqrt(std::abs(E02)); 100 if (E02 < 0)E0 *= -1; 101 Q += Z; 102 G4cout << "G4LEHadronProtonElastic:Apply 103 G4cout << "E = " << E/GeV << " GeV" 104 << ", mass = " << E0/GeV << " GeV 105 << ", charge = " << Q << G4endl; 106 } 107 108 G4double theta = (0.5)*pi/180.; 109 110 // Get the target particle 111 112 G4DynamicParticle* targetParticle = target 113 114 G4double E1 = aParticle->GetTotalEnergy(); 115 G4double M1 = aParticle->GetDefinition()-> 116 G4double E2 = targetParticle->GetTotalEner 117 G4double M2 = targetParticle->GetDefinitio 118 G4double totalEnergy = E1 + E2; 119 G4double pseudoMass = std::sqrt(totalEnerg 120 121 // Transform into centre of mass system 122 123 G4double px = (M2/pseudoMass)*Px; 124 G4double py = (M2/pseudoMass)*Py; 125 G4double pz = (M2/pseudoMass)*Pz; 126 G4double p = std::sqrt(px*px + py*py + pz* 127 128 if (verboseLevel > 1) { 129 G4cout << " E1, M1 (GeV) " << E1/GeV << 130 G4cout << " E2, M2 (GeV) " << E2/GeV << 131 G4cout << " particle 1 momentum in CM 132 << pz/GeV << " " << p/GeV << G4endl 133 } 134 135 // First scatter w.r.t. Z axis 136 G4double phi = G4UniformRand()*twopi; 137 G4double pxnew = p*std::sin(theta)*std::co 138 G4double pynew = p*std::sin(theta)*std::si 139 G4double pznew = p*std::cos(theta); 140 141 // Rotate according to the direction of th 142 if (px*px + py*py > 0) 143 { 144 G4double cost, sint, ph, cosp, sinp; 145 cost = pz/p; 146 sint = (std::sqrt(std::fabs((1-cost)*(1+ 147 + std::sqrt(px*px+py*py)/p)/2; 148 py < 0 ? ph = 3*halfpi : ph = halfpi; 149 if (std::abs(px) > 0.000001*GeV) ph = st 150 cosp = std::cos(ph); 151 sinp = std::sin(ph); 152 px = (cost*cosp*pxnew - sinp*pynew + sin 153 py = (cost*sinp*pxnew + cosp*pynew + sin 154 pz = (-sint*pxnew + cos 155 } 156 else { 157 px = pxnew; 158 py = pynew; 159 pz = pznew; 160 } 161 162 if (verboseLevel > 1) { 163 G4cout << " AFTER SCATTER..." << G4endl 164 G4cout << " particle 1 momentum in CM " 165 << " " << py/GeV << " " << pz/GeV 166 << G4endl; 167 } 168 169 // Transform to lab system 170 171 G4double E1pM2 = E1 + M2; 172 G4double betaCM = P/E1pM2; 173 G4double betaCMx = Px/E1pM2; 174 G4double betaCMy = Py/E1pM2; 175 G4double betaCMz = Pz/E1pM2; 176 G4double gammaCM = E1pM2/std::sqrt(E1pM2*E 177 178 if (verboseLevel > 1) { 179 G4cout << " betaCM " << betaCMx << " " 180 << betaCMz << " " << betaCM << G4 181 G4cout << " gammaCM " << gammaCM << G4e 182 } 183 184 // Now following GLOREN... 185 186 G4double BETA[5], PA[5], PB[5]; 187 BETA[1] = -betaCMx; 188 BETA[2] = -betaCMy; 189 BETA[3] = -betaCMz; 190 BETA[4] = gammaCM; 191 192 //The incident particle... 193 194 PA[1] = px; 195 PA[2] = py; 196 PA[3] = pz; 197 PA[4] = std::sqrt(M1*M1 + p*p); 198 199 G4double BETPA = BETA[1]*PA[1] + BETA[2]* 200 G4double BPGAM = (BETPA * BETA[4]/(BETA[4 201 202 PB[1] = PA[1] + BPGAM * BETA[1]; 203 PB[2] = PA[2] + BPGAM * BETA[2]; 204 PB[3] = PA[3] + BPGAM * BETA[3]; 205 PB[4] = (PA[4] - BETPA) * BETA[4]; 206 207 G4DynamicParticle* newP = new G4DynamicPar 208 newP->SetDefinition(aParticle->GetDefiniti 209 newP->SetMomentum(G4ThreeVector(PB[1], PB[ 210 211 //The target particle... 212 213 PA[1] = -px; 214 PA[2] = -py; 215 PA[3] = -pz; 216 PA[4] = std::sqrt(M2*M2 + p*p); 217 218 BETPA = BETA[1]*PA[1] + BETA[2]*PA[2] + B 219 BPGAM = (BETPA * BETA[4]/(BETA[4] + 1.) - 220 221 PB[1] = PA[1] + BPGAM * BETA[1]; 222 PB[2] = PA[2] + BPGAM * BETA[2]; 223 PB[3] = PA[3] + BPGAM * BETA[3]; 224 PB[4] = (PA[4] - BETPA) * BETA[4]; 225 226 targetParticle->SetMomentum(G4ThreeVector( 227 228 if (verboseLevel > 1) { 229 G4cout << " particle 1 momentum in LAB 230 << newP->GetMomentum()*(1./GeV) 231 << " " << newP->GetTotalMomentum()/ 232 G4cout << " particle 2 momentum in LAB 233 << targetParticle->GetMomentum()*(1 234 << " " << targetParticle->GetTotalM 235 G4cout << " TOTAL momentum in LAB " 236 << (newP->GetMomentum()+targetParti 237 << " " 238 << (newP->GetMomentum()+targetParti 239 << G4endl; 240 } 241 242 theParticleChange.SetMomentumChange(newP-> 243 theParticleChange.SetEnergyChange(newP->Ge 244 delete newP; 245 theParticleChange.AddSecondary(targetParti 246 247 return &theParticleChange; 248 } 249 250 ////////////////////////////////////////////// 251 // 252 // sample momentum transfer using Lab. momentu 253 254 G4double 255 G4LEHadronProtonElastic::SampleInvariantT(cons 256 G4double plab, G4int , G4int ) 257 { 258 G4double hMass = p->GetPDGMass(); 259 G4double pCMS = 0.5*plab; 260 // pCMS *= 50; 261 G4double hEcms = std::sqrt(pCMS*pCMS+hMass*h 262 // G4double gamma = hEcms/hMass; 263 // gamma *= 15; 264 G4double beta = pCMS/hEcms; // std::sqrt(1- 265 // beta /= 0.8; // 0.95; // 1.0; // 1.1 // 0 266 G4double cosDipole = RandCosThetaDipPen(); 267 G4double cosTheta = cosDipole + beta; 268 cosTheta /= 1. + cosDipole*beta; 269 G4double t = 2.*pCMS*pCMS*(1.-cosTheta); 270 return t; 271 272 } 273 274 ////////////////////////////////////////////// 275 // 276 // 1 + cos^2(theta) random distribution in the 277 278 G4double G4LEHadronProtonElastic::RandCosTheta 279 { 280 G4double x, cosTheta, signX, modX, power = 1 281 282 if( G4UniformRand() > 0.25) 283 { 284 cosTheta = 2.*G4UniformRand()-1.; 285 } 286 else 287 { 288 x = 2.*G4UniformRand()-1.; 289 290 if ( x < 0. ) 291 { 292 modX = -x; 293 signX = -1.; 294 } 295 else 296 { 297 modX = x; 298 signX = 1.; 299 } 300 cosTheta = signX*G4Pow::GetInstance()->pow 301 } 302 return cosTheta; 303 } 304 305 // end of file 306