Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // @hpw@ misses the sampling of two breit wign 23 // @hpw@ misses the sampling of two breit wigner in a corelated fashion, 27 // @hpw@ to be usefull for resonance resonance 24 // @hpw@ to be usefull for resonance resonance scattering. 28 25 29 #include <typeinfo> 26 #include <typeinfo> 30 << 31 #include "globals.hh" 27 #include "globals.hh" 32 #include "G4SystemOfUnits.hh" << 33 #include "G4VScatteringCollision.hh" 28 #include "G4VScatteringCollision.hh" 34 #include "G4KineticTrack.hh" 29 #include "G4KineticTrack.hh" 35 #include "G4VCrossSectionSource.hh" 30 #include "G4VCrossSectionSource.hh" 36 #include "G4Proton.hh" 31 #include "G4Proton.hh" 37 #include "G4Neutron.hh" 32 #include "G4Neutron.hh" 38 #include "G4XNNElastic.hh" 33 #include "G4XNNElastic.hh" 39 #include "G4AngularDistribution.hh" 34 #include "G4AngularDistribution.hh" 40 #include "G4ThreeVector.hh" 35 #include "G4ThreeVector.hh" 41 #include "G4LorentzVector.hh" 36 #include "G4LorentzVector.hh" 42 #include "G4LorentzRotation.hh" 37 #include "G4LorentzRotation.hh" 43 #include "G4KineticTrackVector.hh" 38 #include "G4KineticTrackVector.hh" 44 #include "Randomize.hh" 39 #include "Randomize.hh" 45 #include "G4PionPlus.hh" 40 #include "G4PionPlus.hh" 46 41 47 G4VScatteringCollision::G4VScatteringCollision 42 G4VScatteringCollision::G4VScatteringCollision() 48 { 43 { 49 theAngularDistribution = new G4AngularDistri 44 theAngularDistribution = new G4AngularDistribution(true); 50 } 45 } 51 46 52 47 53 G4VScatteringCollision::~G4VScatteringCollisio 48 G4VScatteringCollision::~G4VScatteringCollision() 54 { 49 { 55 delete theAngularDistribution; 50 delete theAngularDistribution; 56 theAngularDistribution=0; << 57 } 51 } 58 52 59 53 60 G4KineticTrackVector* G4VScatteringCollision:: 54 G4KineticTrackVector* G4VScatteringCollision::FinalState(const G4KineticTrack& trk1, 61 const G4KineticTrack& trk2) 55 const G4KineticTrack& trk2) const 62 { 56 { 63 const G4VAngularDistribution* angDistributio 57 const G4VAngularDistribution* angDistribution = GetAngularDistribution(); 64 G4LorentzVector p = trk1.Get4Momentum() + tr 58 G4LorentzVector p = trk1.Get4Momentum() + trk2.Get4Momentum(); 65 G4double sqrtS = p.m(); 59 G4double sqrtS = p.m(); 66 G4double S = sqrtS * sqrtS; << 60 G4double s = sqrtS * sqrtS; >> 61 >> 62 G4double m1 = trk1.GetActualMass(); >> 63 G4double m2 = trk2.GetActualMass(); 67 64 68 std::vector<const G4ParticleDefinition*> Out 65 std::vector<const G4ParticleDefinition*> OutputDefinitions = GetOutgoingParticles(); 69 if (OutputDefinitions.size() != 2) 66 if (OutputDefinitions.size() != 2) 70 throw G4HadronicException(__FILE__, __LINE 67 throw G4HadronicException(__FILE__, __LINE__, "G4VScatteringCollision: Too many output particles!"); 71 68 72 if (OutputDefinitions[0]->IsShortLived() && 69 if (OutputDefinitions[0]->IsShortLived() && OutputDefinitions[1]->IsShortLived()) 73 { 70 { 74 if(std::getenv("G4KCDEBUG")) G4cerr << "tw << 71 if(getenv("G4KCDEBUG")) G4cerr << "two shortlived for Type = "<<typeid(*this).name()<<G4endl; 75 // throw G4HadronicException(__FILE__, __L 72 // throw G4HadronicException(__FILE__, __LINE__, "G4VScatteringCollision: can't handle two shortlived particles!"); // @hpw@ 76 } 73 } 77 74 78 G4double outm1 = OutputDefinitions[0]->GetPD 75 G4double outm1 = OutputDefinitions[0]->GetPDGMass(); 79 G4double outm2 = OutputDefinitions[1]->GetPD 76 G4double outm2 = OutputDefinitions[1]->GetPDGMass(); 80 77 81 if (OutputDefinitions[0]->IsShortLived()) 78 if (OutputDefinitions[0]->IsShortLived()) 82 { 79 { 83 outm1 = SampleResonanceMass(outm1, 80 outm1 = SampleResonanceMass(outm1, 84 OutputDefinitions[0]->GetPDGWi 81 OutputDefinitions[0]->GetPDGWidth(), 85 G4Neutron::NeutronDefinition()->GetPDGMass 82 G4Neutron::NeutronDefinition()->GetPDGMass()+G4PionPlus::PionPlus()->GetPDGMass(), 86 sqrtS-(G4Neutron::NeutronDefinition()->Get 83 sqrtS-(G4Neutron::NeutronDefinition()->GetPDGMass()+G4PionPlus::PionPlus()->GetPDGMass())); 87 84 88 } 85 } 89 if (OutputDefinitions[1]->IsShortLived()) 86 if (OutputDefinitions[1]->IsShortLived()) 90 { 87 { 91 outm2 = SampleResonanceMass(outm2, OutputD 88 outm2 = SampleResonanceMass(outm2, OutputDefinitions[1]->GetPDGWidth(), 92 G4Neutron::NeutronDefinition()->GetPDGMa 89 G4Neutron::NeutronDefinition()->GetPDGMass()+G4PionPlus::PionPlus()->GetPDGMass(), 93 sqrtS-outm1); 90 sqrtS-outm1); 94 } 91 } 95 92 96 // Angles of outgoing particles 93 // Angles of outgoing particles 97 G4double cosTheta = angDistribution->CosThet << 94 G4double cosTheta = angDistribution->CosTheta(s,m1,m2); 98 G4double phi = angDistribution->Phi(); 95 G4double phi = angDistribution->Phi(); 99 96 100 // Unit vector of three-momentum 97 // Unit vector of three-momentum 101 G4LorentzRotation fromCMSFrame(p.boostVector 98 G4LorentzRotation fromCMSFrame(p.boostVector()); 102 G4LorentzRotation toCMSFrame(fromCMSFrame.in 99 G4LorentzRotation toCMSFrame(fromCMSFrame.inverse()); 103 G4LorentzVector TempPtr = toCMSFrame*trk1.Ge 100 G4LorentzVector TempPtr = toCMSFrame*trk1.Get4Momentum(); 104 G4LorentzRotation toZ; 101 G4LorentzRotation toZ; 105 toZ.rotateZ(-1*TempPtr.phi()); 102 toZ.rotateZ(-1*TempPtr.phi()); 106 toZ.rotateY(-1*TempPtr.theta()); 103 toZ.rotateY(-1*TempPtr.theta()); 107 G4LorentzRotation toCMS(toZ.inverse()); 104 G4LorentzRotation toCMS(toZ.inverse()); 108 105 109 G4ThreeVector pFinal1(std::sin(std::acos(cos 106 G4ThreeVector pFinal1(std::sin(std::acos(cosTheta))*std::cos(phi), std::sin(std::acos(cosTheta))*std::sin(phi), cosTheta); 110 107 111 // Three momentum in cm system 108 // Three momentum in cm system 112 G4double pCM = std::sqrt( (S-(outm1+outm2)*( << 109 G4double pCM = std::sqrt( (s-(outm1+outm2)*(outm1+outm2)) * (s-(outm1-outm2)*(outm1-outm2)) /(4.*s)); 113 pFinal1 = pFinal1 * pCM; 110 pFinal1 = pFinal1 * pCM; 114 G4ThreeVector pFinal2 = -pFinal1; 111 G4ThreeVector pFinal2 = -pFinal1; 115 112 116 G4double eFinal1 = std::sqrt(pFinal1.mag2() 113 G4double eFinal1 = std::sqrt(pFinal1.mag2() + outm1*outm1); 117 G4double eFinal2 = std::sqrt(pFinal2.mag2() 114 G4double eFinal2 = std::sqrt(pFinal2.mag2() + outm2*outm2); 118 115 119 G4LorentzVector p4Final1(pFinal1, eFinal1); 116 G4LorentzVector p4Final1(pFinal1, eFinal1); 120 G4LorentzVector p4Final2(pFinal2, eFinal2); 117 G4LorentzVector p4Final2(pFinal2, eFinal2); 121 p4Final1 = toCMS*p4Final1; 118 p4Final1 = toCMS*p4Final1; 122 p4Final2 = toCMS*p4Final2; 119 p4Final2 = toCMS*p4Final2; 123 120 124 121 125 // Lorentz transformation 122 // Lorentz transformation 126 G4LorentzRotation toLabFrame(p.boostVector() 123 G4LorentzRotation toLabFrame(p.boostVector()); 127 p4Final1 *= toLabFrame; 124 p4Final1 *= toLabFrame; 128 p4Final2 *= toLabFrame; 125 p4Final2 *= toLabFrame; 129 126 130 // Final tracks are copies of incoming ones, 127 // Final tracks are copies of incoming ones, with modified 4-momenta 131 128 132 G4double chargeBalance = OutputDefinitions[0 129 G4double chargeBalance = OutputDefinitions[0]->GetPDGCharge()+OutputDefinitions[1]->GetPDGCharge(); 133 chargeBalance-= trk1.GetDefinition()->GetPDG 130 chargeBalance-= trk1.GetDefinition()->GetPDGCharge(); 134 chargeBalance-= trk2.GetDefinition()->GetPDG 131 chargeBalance-= trk2.GetDefinition()->GetPDGCharge(); 135 if(std::abs(chargeBalance) >.1) 132 if(std::abs(chargeBalance) >.1) 136 { 133 { 137 G4cout << "Charges in "<<typeid(*this).nam 134 G4cout << "Charges in "<<typeid(*this).name()<<G4endl; 138 G4cout << OutputDefinitions[0]->GetPDGChar 135 G4cout << OutputDefinitions[0]->GetPDGCharge()<<" "<<OutputDefinitions[0]->GetParticleName() 139 << OutputDefinitions[1]->GetPDGChar 136 << OutputDefinitions[1]->GetPDGCharge()<<" "<<OutputDefinitions[1]->GetParticleName() 140 << trk1.GetDefinition()->GetPDGCharge()<< 137 << trk1.GetDefinition()->GetPDGCharge()<<" "<<trk1.GetDefinition()->GetParticleName() 141 << trk2.GetDefinition()->GetPDGCharge()<< 138 << trk2.GetDefinition()->GetPDGCharge()<<" "<<trk2.GetDefinition()->GetParticleName()<<G4endl; 142 } 139 } 143 G4KineticTrack* final1 = new G4KineticTrack( << 140 G4KineticTrack* final1 = new G4KineticTrack(const_cast<G4ParticleDefinition *>(OutputDefinitions[0]), 0.0, 144 G4KineticTrack* final2 = new G4KineticTrack( << 141 trk1.GetPosition(), p4Final1); >> 142 G4KineticTrack* final2 = new G4KineticTrack(const_cast<G4ParticleDefinition *>(OutputDefinitions[1]), 0.0, >> 143 trk2.GetPosition(), p4Final2); 145 144 146 G4KineticTrackVector* finalTracks = new G4Ki 145 G4KineticTrackVector* finalTracks = new G4KineticTrackVector; 147 146 148 finalTracks->push_back(final1); 147 finalTracks->push_back(final1); 149 finalTracks->push_back(final2); 148 finalTracks->push_back(final2); 150 149 151 return finalTracks; 150 return finalTracks; 152 } 151 } 153 152 154 153 155 154 156 double G4VScatteringCollision::SampleResonance 155 double G4VScatteringCollision::SampleResonanceMass(const double poleMass, 157 const double gamma, 156 const double gamma, 158 const double aMinMass, 157 const double aMinMass, 159 const double maxMass) const 158 const double maxMass) const 160 { 159 { 161 // Chooses a mass randomly between minMass a 160 // Chooses a mass randomly between minMass and maxMass 162 // according to a Breit-Wigner function 161 // according to a Breit-Wigner function with constant 163 // width gamma and pole poleMass 162 // width gamma and pole poleMass 164 163 165 G4double minMass = aMinMass; 164 G4double minMass = aMinMass; 166 if (minMass > maxMass) G4cerr << "########## 165 if (minMass > maxMass) G4cerr << "##################### SampleResonanceMass: particle out of mass range" << G4endl; 167 if(minMass > maxMass) minMass -= G4PionPlus: 166 if(minMass > maxMass) minMass -= G4PionPlus::PionPlus()->GetPDGMass(); 168 if(minMass > maxMass) minMass = 0; 167 if(minMass > maxMass) minMass = 0; 169 168 170 if (gamma < 1E-10*GeV) 169 if (gamma < 1E-10*GeV) 171 return std::max(minMass,std::min(maxMass, 170 return std::max(minMass,std::min(maxMass, poleMass)); 172 else { 171 else { 173 double fmin = BrWigInt0(minMass, gamma, po 172 double fmin = BrWigInt0(minMass, gamma, poleMass); 174 double fmax = BrWigInt0(maxMass, gamma, po 173 double fmax = BrWigInt0(maxMass, gamma, poleMass); 175 double f = fmin + (fmax-fmin)*G4UniformRan 174 double f = fmin + (fmax-fmin)*G4UniformRand(); 176 return BrWigInv(f, gamma, poleMass); 175 return BrWigInv(f, gamma, poleMass); 177 } 176 } 178 } << 179 << 180 void G4VScatteringCollision::establish_G4MT_TL << 181 { << 182 establish_G4MT_TLS_G4VCollision(); << 183 if ( theAngularDistribution ) delete theAngu << 184 theAngularDistribution = new G4AngularDistri << 185 } 177 } 186 178