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 // 26 // 27 // Geant4 Header : G4NeutrinoElectronCcModel 27 // Geant4 Header : G4NeutrinoElectronCcModel 28 // 28 // 29 // Author : V.Grichine 26.4.17 29 // Author : V.Grichine 26.4.17 30 // 30 // 31 31 32 #include "G4NeutrinoElectronCcModel.hh" 32 #include "G4NeutrinoElectronCcModel.hh" 33 #include "G4SystemOfUnits.hh" 33 #include "G4SystemOfUnits.hh" 34 #include "G4ParticleTable.hh" 34 #include "G4ParticleTable.hh" 35 #include "G4ParticleDefinition.hh" 35 #include "G4ParticleDefinition.hh" 36 #include "G4IonTable.hh" 36 #include "G4IonTable.hh" 37 #include "Randomize.hh" 37 #include "Randomize.hh" 38 #include "G4NeutrinoE.hh" 38 #include "G4NeutrinoE.hh" 39 #include "G4AntiNeutrinoE.hh" 39 #include "G4AntiNeutrinoE.hh" 40 40 41 #include "G4NeutrinoMu.hh" 41 #include "G4NeutrinoMu.hh" 42 #include "G4AntiNeutrinoMu.hh" 42 #include "G4AntiNeutrinoMu.hh" 43 #include "G4NeutrinoTau.hh" 43 #include "G4NeutrinoTau.hh" 44 #include "G4AntiNeutrinoTau.hh" 44 #include "G4AntiNeutrinoTau.hh" 45 #include "G4MuonMinus.hh" 45 #include "G4MuonMinus.hh" 46 #include "G4TauMinus.hh" 46 #include "G4TauMinus.hh" 47 #include "G4HadronicParameters.hh" 47 #include "G4HadronicParameters.hh" 48 #include "G4PhysicsModelCatalog.hh" << 49 48 50 using namespace std; 49 using namespace std; 51 using namespace CLHEP; 50 using namespace CLHEP; 52 51 53 G4NeutrinoElectronCcModel::G4NeutrinoElectronC 52 G4NeutrinoElectronCcModel::G4NeutrinoElectronCcModel(const G4String& name) 54 : G4HadronicInteraction(name) 53 : G4HadronicInteraction(name) 55 { 54 { 56 SetMinEnergy( 0.0*GeV ); 55 SetMinEnergy( 0.0*GeV ); 57 SetMaxEnergy( G4HadronicParameters::Instance 56 SetMaxEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() ); 58 SetMinEnergy(1.e-6*eV); 57 SetMinEnergy(1.e-6*eV); 59 58 60 theNeutrinoE = G4NeutrinoE::NeutrinoE(); 59 theNeutrinoE = G4NeutrinoE::NeutrinoE(); 61 theAntiNeutrinoE = G4AntiNeutrinoE::AntiNeut 60 theAntiNeutrinoE = G4AntiNeutrinoE::AntiNeutrinoE(); 62 61 63 theNeutrinoMu = G4NeutrinoMu::NeutrinoMu(); 62 theNeutrinoMu = G4NeutrinoMu::NeutrinoMu(); 64 theAntiNeutrinoMu = G4AntiNeutrinoMu::AntiNe 63 theAntiNeutrinoMu = G4AntiNeutrinoMu::AntiNeutrinoMu(); 65 64 66 theNeutrinoTau = G4NeutrinoTau::NeutrinoTau( 65 theNeutrinoTau = G4NeutrinoTau::NeutrinoTau(); 67 theAntiNeutrinoTau = G4AntiNeutrinoTau::Anti 66 theAntiNeutrinoTau = G4AntiNeutrinoTau::AntiNeutrinoTau(); 68 67 69 theMuonMinus = G4MuonMinus::MuonMinus(); 68 theMuonMinus = G4MuonMinus::MuonMinus(); 70 theTauMinus = G4TauMinus::TauMinus(); 69 theTauMinus = G4TauMinus::TauMinus(); 71 70 72 // PDG2016: sin^2 theta Weinberg 71 // PDG2016: sin^2 theta Weinberg 73 72 74 fSin2tW = 0.23129; // 0.2312; 73 fSin2tW = 0.23129; // 0.2312; 75 74 76 fCutEnergy = 0.; // default value 75 fCutEnergy = 0.; // default value 77 76 78 // Creator model ID << 79 secID = G4PhysicsModelCatalog::GetModelID( " << 80 } 77 } 81 78 82 79 83 G4NeutrinoElectronCcModel::~G4NeutrinoElectron 80 G4NeutrinoElectronCcModel::~G4NeutrinoElectronCcModel() 84 {} 81 {} 85 82 86 83 87 void G4NeutrinoElectronCcModel::ModelDescripti 84 void G4NeutrinoElectronCcModel::ModelDescription(std::ostream& outFile) const 88 { 85 { 89 86 90 outFile << "G4NeutrinoElectronCcModel is a 87 outFile << "G4NeutrinoElectronCcModel is a neutrino-electron (neutral current) elastic scattering\n" 91 << "model which uses the standard 88 << "model which uses the standard model \n" 92 << "transfer parameterization. Th 89 << "transfer parameterization. The model is fully relativistic\n"; 93 90 94 } 91 } 95 92 96 ////////////////////////////////////////////// 93 ///////////////////////////////////////////////////////// 97 94 98 G4bool G4NeutrinoElectronCcModel::IsApplicable 95 G4bool G4NeutrinoElectronCcModel::IsApplicable(const G4HadProjectile & aPart, 99 G4Nucleus & ) << 96 G4Nucleus & targetNucleus) 100 { 97 { 101 G4bool result = false; 98 G4bool result = false; 102 G4String pName = aPart.GetDefinition()->GetP 99 G4String pName = aPart.GetDefinition()->GetParticleName(); 103 if(pName == "anti_nu_mu" || pName == "anti_n 100 if(pName == "anti_nu_mu" || pName == "anti_nu_tau") return result; // no cc for anti_nu_(mu,tau) 104 G4double minEnergy = 0., energy = aPart.GetT 101 G4double minEnergy = 0., energy = aPart.GetTotalEnergy(); 105 G4double fmass, emass = electron_mass_c2; 102 G4double fmass, emass = electron_mass_c2; 106 103 107 if( pName == "nu_mu" ) fmass = theMuon 104 if( pName == "nu_mu" ) fmass = theMuonMinus->GetPDGMass(); 108 else if( pName == "nu_tau" ) fmass = theTauM 105 else if( pName == "nu_tau" ) fmass = theTauMinus->GetPDGMass(); 109 else fmass = emass; 106 else fmass = emass; 110 107 111 minEnergy = (fmass-emass)*(fmass+emass)/emas 108 minEnergy = (fmass-emass)*(fmass+emass)/emass; 112 SetMinEnergy( minEnergy ); 109 SetMinEnergy( minEnergy ); 113 110 114 if( ( pName == "nu_mu" || pName == "nu_tau 111 if( ( pName == "nu_mu" || pName == "nu_tau" || pName == "anti_nu_e" ) && energy > minEnergy ) 115 { 112 { 116 result = true; 113 result = true; 117 } 114 } >> 115 G4int Z = targetNucleus.GetZ_asInt(); >> 116 Z *= 1; 118 117 119 return result; 118 return result; 120 } 119 } 121 120 122 ////////////////////////////////////////////// 121 //////////////////////////////////////////////// 123 // 122 // 124 // 123 // 125 124 126 G4HadFinalState* G4NeutrinoElectronCcModel::Ap 125 G4HadFinalState* G4NeutrinoElectronCcModel::ApplyYourself( 127 const G4HadProjectile& aTrack, G4Nucleus& << 126 const G4HadProjectile& aTrack, G4Nucleus& targetNucleus) 128 { 127 { 129 theParticleChange.Clear(); 128 theParticleChange.Clear(); 130 129 131 const G4HadProjectile* aParticle = &aTrack; 130 const G4HadProjectile* aParticle = &aTrack; 132 G4double energy = aParticle->GetTotalEnergy( 131 G4double energy = aParticle->GetTotalEnergy(); 133 132 134 G4String pName = aParticle->GetDefinition() 133 G4String pName = aParticle->GetDefinition()->GetParticleName(); 135 G4double minEnergy(0.), fmass(0.), emass = e 134 G4double minEnergy(0.), fmass(0.), emass = electron_mass_c2; 136 135 137 if( pName == "nu_mu" ) fmass = theMu 136 if( pName == "nu_mu" ) fmass = theMuonMinus->GetPDGMass(); 138 else if( pName == "nu_tau" ) fmass = theTa 137 else if( pName == "nu_tau" ) fmass = theTauMinus->GetPDGMass(); 139 else fmass = emass 138 else fmass = emass; 140 139 141 minEnergy = (fmass-emass)*(fmass+emass)/emas 140 minEnergy = (fmass-emass)*(fmass+emass)/emass; 142 141 143 if( energy <= minEnergy ) 142 if( energy <= minEnergy ) 144 { 143 { 145 theParticleChange.SetEnergyChange(energy); 144 theParticleChange.SetEnergyChange(energy); 146 theParticleChange.SetMomentumChange(aTrack 145 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 147 return &theParticleChange; 146 return &theParticleChange; 148 } 147 } 149 G4double massf(0.), massf2(0.); // , emass = 148 G4double massf(0.), massf2(0.); // , emass = electron_mass_c2; 150 G4double sTot = 2.*energy*emass + emass*emas 149 G4double sTot = 2.*energy*emass + emass*emass; 151 150 152 G4LorentzVector lvp1 = aParticle->Get4Moment 151 G4LorentzVector lvp1 = aParticle->Get4Momentum(); 153 G4LorentzVector lvt1(0.,0.,0.,electron_mass_ 152 G4LorentzVector lvt1(0.,0.,0.,electron_mass_c2); 154 G4LorentzVector lvsum = lvp1+lvt1; 153 G4LorentzVector lvsum = lvp1+lvt1; 155 G4ThreeVector bst = lvsum.boostVector(); 154 G4ThreeVector bst = lvsum.boostVector(); 156 155 157 // sample and make final state in CMS frame 156 // sample and make final state in CMS frame 158 157 159 G4double cost = SampleCosCMS( aParticle ); 158 G4double cost = SampleCosCMS( aParticle ); 160 G4double sint = std::sqrt( (1.0 - cost)*(1.0 159 G4double sint = std::sqrt( (1.0 - cost)*(1.0 + cost) ); 161 G4double phi = G4UniformRand()*CLHEP::twopi 160 G4double phi = G4UniformRand()*CLHEP::twopi; 162 161 163 G4ThreeVector eP( sint*std::cos(phi), sint*s 162 G4ThreeVector eP( sint*std::cos(phi), sint*std::sin(phi), cost ); 164 163 165 if( pName == "nu_mu" ) massf = theMuon 164 if( pName == "nu_mu" ) massf = theMuonMinus->GetPDGMass(); 166 else if( pName == "nu_tau" ) massf = theTauM 165 else if( pName == "nu_tau" ) massf = theTauMinus->GetPDGMass(); 167 166 168 massf2 = massf*massf; 167 massf2 = massf*massf; 169 168 170 G4double epf = 0.5*(sTot - massf2)/sqrt(sTot 169 G4double epf = 0.5*(sTot - massf2)/sqrt(sTot); 171 // G4double etf = epf*(sTot + massf2)/(sTot 170 // G4double etf = epf*(sTot + massf2)/(sTot - massf2); 172 171 173 eP *= epf; 172 eP *= epf; 174 G4LorentzVector lvp2( eP, epf ); 173 G4LorentzVector lvp2( eP, epf ); 175 lvp2.boost(bst); // back to lab frame 174 lvp2.boost(bst); // back to lab frame 176 175 177 G4LorentzVector lvt2 = lvsum - lvp2; // ? 176 G4LorentzVector lvt2 = lvsum - lvp2; // ? 178 177 179 G4DynamicParticle* aNu = nullptr; 178 G4DynamicParticle* aNu = nullptr; 180 G4DynamicParticle* aLept = nullptr; 179 G4DynamicParticle* aLept = nullptr; 181 180 182 if( pName == "nu_mu" || pName == "nu_tau") 181 if( pName == "nu_mu" || pName == "nu_tau") 183 { 182 { 184 aNu = new G4DynamicParticle( theNeutrinoE, 183 aNu = new G4DynamicParticle( theNeutrinoE, lvp2 ); 185 } 184 } 186 else if( pName == "anti_nu_e" ) aNu = new 185 else if( pName == "anti_nu_e" ) aNu = new G4DynamicParticle( theAntiNeutrinoMu, lvp2 ); // s-channel for mu (tau later) 187 186 188 if( pName == "nu_mu" || pName == "anti_nu_e 187 if( pName == "nu_mu" || pName == "anti_nu_e") 189 { 188 { 190 aLept = new G4DynamicParticle( theMuonMinu 189 aLept = new G4DynamicParticle( theMuonMinus, lvt2 ); 191 } 190 } 192 else if( pName == "nu_tau" ) // || pName == 191 else if( pName == "nu_tau" ) // || pName == "anti_nu_tau") 193 { 192 { 194 aLept = new G4DynamicParticle( theTauMinus 193 aLept = new G4DynamicParticle( theTauMinus, lvt2 ); 195 } 194 } 196 if(aNu) { theParticleChange.AddSecondary( << 195 if(aNu) { theParticleChange.AddSecondary( aNu ); } 197 if(aLept) { theParticleChange.AddSecondary( << 196 if(aLept) { theParticleChange.AddSecondary( aLept ); } >> 197 >> 198 G4int Z = targetNucleus.GetZ_asInt(); >> 199 Z *= 1; 198 200 199 return &theParticleChange; 201 return &theParticleChange; 200 } 202 } 201 203 202 ////////////////////////////////////////////// 204 ////////////////////////////////////////////////////// 203 // 205 // 204 // sample recoil electron energy in lab frame 206 // sample recoil electron energy in lab frame 205 207 206 G4double G4NeutrinoElectronCcModel::SampleCosC 208 G4double G4NeutrinoElectronCcModel::SampleCosCMS(const G4HadProjectile* aParticle) 207 { 209 { 208 G4double result = 0., cofL, cofR, cofLR, mas 210 G4double result = 0., cofL, cofR, cofLR, massf2, sTot, emass = electron_mass_c2, emass2; 209 211 210 G4double energy = aParticle->GetTotalEnergy( 212 G4double energy = aParticle->GetTotalEnergy(); 211 213 212 if( energy == 0.) return result; // vmg: < t 214 if( energy == 0.) return result; // vmg: < th?? as in xsc 213 215 214 G4String pName = aParticle->GetDefinition() 216 G4String pName = aParticle->GetDefinition()->GetParticleName(); 215 217 216 if( pName == "nu_mu" || pName == "nu_tau") 218 if( pName == "nu_mu" || pName == "nu_tau") 217 { 219 { 218 return 2.*G4UniformRand()-1.; // uniform s 220 return 2.*G4UniformRand()-1.; // uniform scattering cos in CMS 219 } 221 } 220 else if( pName == "anti_nu_mu" || pName == " 222 else if( pName == "anti_nu_mu" || pName == "anti_nu_tau") 221 { 223 { 222 emass2 = emass*emass; 224 emass2 = emass*emass; 223 sTot = 2.*energy*emass + emass2; 225 sTot = 2.*energy*emass + emass2; 224 226 225 cofL = (sTot-emass2)/(sTot+emass2); 227 cofL = (sTot-emass2)/(sTot+emass2); 226 228 227 if(pName == "anti_nu_mu") massf2 = theMuon 229 if(pName == "anti_nu_mu") massf2 = theMuonMinus->GetPDGMass()*theMuonMinus->GetPDGMass(); 228 else massf2 = theTauM 230 else massf2 = theTauMinus->GetPDGMass()*theTauMinus->GetPDGMass(); 229 231 230 cofR = (sTot-massf2)/(sTot+massf2); 232 cofR = (sTot-massf2)/(sTot+massf2); 231 233 232 cofLR = cofL*cofR/3.; 234 cofLR = cofL*cofR/3.; 233 235 234 // cofs of cos 3rd equation 236 // cofs of cos 3rd equation 235 237 236 G4double a = cofLR; 238 G4double a = cofLR; 237 G4double b = 0.5*(cofR+cofL); 239 G4double b = 0.5*(cofR+cofL); 238 G4double c = 1.; 240 G4double c = 1.; 239 241 240 G4double d = -G4UniformRand()*2.*(1.+ cof 242 G4double d = -G4UniformRand()*2.*(1.+ cofLR); 241 d += c - b + a; 243 d += c - b + a; 242 244 243 // G4cout<<a<<" "<<b<<" "<<c<<" "<<d 245 // G4cout<<a<<" "<<b<<" "<<c<<" "<<d<<G4endl<<G4endl; 244 246 245 // cofs of the incomplete 3rd equation 247 // cofs of the incomplete 3rd equation 246 248 247 G4double p = c/a; 249 G4double p = c/a; 248 p -= b*b/a/a/3.; 250 p -= b*b/a/a/3.; 249 251 250 G4double q = d/a; 252 G4double q = d/a; 251 q -= b*c/a/a/3.; 253 q -= b*c/a/a/3.; 252 q += 2*b*b*b/a/a/a/27.; 254 q += 2*b*b*b/a/a/a/27.; 253 255 254 256 255 // cofs for the incomplete colutions 257 // cofs for the incomplete colutions 256 258 257 G4double D = p*p*p/3./3./3.; 259 G4double D = p*p*p/3./3./3.; 258 D += q*q/2./2.; 260 D += q*q/2./2.; 259 261 260 // G4cout<<"D = "<<D<<G4endl; 262 // G4cout<<"D = "<<D<<G4endl; 261 if(D < 0.) D = -D; 263 if(D < 0.) D = -D; 262 // G4complex A1 = G4complex(- q/2., std:: 264 // G4complex A1 = G4complex(- q/2., std::sqrt(-D) ); 263 // G4complex A = std::pow(A1,1./3.); 265 // G4complex A = std::pow(A1,1./3.); 264 266 265 // G4complex B1 = G4complex(- q/2., -std: 267 // G4complex B1 = G4complex(- q/2., -std::sqrt(-D) ); 266 // G4complex B = std::pow(B1,1./3.); 268 // G4complex B = std::pow(B1,1./3.); 267 269 268 G4double A, B; 270 G4double A, B; 269 271 270 G4double A1 = - q/2. + std::sqrt(D); 272 G4double A1 = - q/2. + std::sqrt(D); 271 if (A1 < 0.) A1 = -A1; 273 if (A1 < 0.) A1 = -A1; 272 A = std::pow(A1,1./3.); 274 A = std::pow(A1,1./3.); 273 if (A1 < 0.) A = -A; 275 if (A1 < 0.) A = -A; 274 276 275 G4double B1 = - q/2. - std::sqrt(D); 277 G4double B1 = - q/2. - std::sqrt(D); 276 // G4double B = std::pow(-B1,1./3.); 278 // G4double B = std::pow(-B1,1./3.); 277 if(B1 < 0.) B1 = -B1; 279 if(B1 < 0.) B1 = -B1; 278 B = std::pow(B1,1./3.); 280 B = std::pow(B1,1./3.); 279 if(B1 < 0.) B = -B; 281 if(B1 < 0.) B = -B; 280 // G4cout<<"A1 = "<<A1<<"; A = "<<A<<"; B1 282 // G4cout<<"A1 = "<<A1<<"; A = "<<A<<"; B1 = "<<B1<<"; B = "<<B<<G4endl; 281 // roots of the incomplete 3rd equation 283 // roots of the incomplete 3rd equation 282 284 283 G4complex y1 = A + B; 285 G4complex y1 = A + B; 284 // G4complex y2 = -0.5*(A + B) + 0.5*std:: 286 // G4complex y2 = -0.5*(A + B) + 0.5*std::sqrt(3.)*(A - B)*G4complex(0.,1.); 285 // G4complex y3 = -0.5*(A + B) - 0.5*std:: 287 // G4complex y3 = -0.5*(A + B) - 0.5*std::sqrt(3.)*(A - B)*G4complex(0.,1.); 286 288 287 G4complex x1 = y1 - b/a/3.; 289 G4complex x1 = y1 - b/a/3.; 288 // G4complex x2 = y2 - b/a/3.; 290 // G4complex x2 = y2 - b/a/3.; 289 // G4complex x3 = y3 - b/a/3.; 291 // G4complex x3 = y3 - b/a/3.; 290 // G4cout<<"re_x1 = "<<real(x1)<<" + i*"<< 292 // G4cout<<"re_x1 = "<<real(x1)<<" + i*"<<imag(x1)<<G4endl; 291 // G4cout<<"re_x1 = "<<real(x1)<<"; re_x2 293 // G4cout<<"re_x1 = "<<real(x1)<<"; re_x2 = "<<real(x2)<<"; re_x3 = "<<real(x3)<<G4endl; 292 // G4cout<<"im_x1 = "<<imag(x1)<<"; im_x2 294 // G4cout<<"im_x1 = "<<imag(x1)<<"; im_x2 = "<<imag(x2)<<"; im_x3 = "<<imag(x3)<<G4endl<<G4endl; 293 295 294 result = real(x1); 296 result = real(x1); 295 } 297 } 296 else 298 else 297 { 299 { 298 return result; 300 return result; 299 } 301 } 300 return result; 302 return result; 301 } 303 } 302 304 303 // 305 // 304 // 306 // 305 /////////////////////////// 307 /////////////////////////// 306 308