Geant4  10.00.p02
G4CollisionComposite.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4CollisionComposite.cc,v 1.9 2010-03-12 15:45:18 gunter Exp $ //
28 
29 #include "globals.hh"
30 #include "G4SystemOfUnits.hh"
31 #include "G4CollisionComposite.hh"
32 #include "G4VCollision.hh"
33 #include "G4CollisionVector.hh"
34 #include "G4KineticTrack.hh"
35 #include "G4KineticTrackVector.hh"
36 #include "G4VCrossSectionSource.hh"
37 #include "G4HadTmpUtil.hh"
38 
40 
41 const G4double G4CollisionComposite::theT[nPoints] =
42 {.01, .03, .05, .1, .15, .2, .3, .4, .5, .6, .7, .8, .9, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10., 15, 20, 50, 100};
43 
45 {
46 }
47 
48 
50 {
51  std::for_each(components.begin(), components.end(), G4Delete());
52 }
53 
54 
56  const G4KineticTrack& trk2) const
57 {
58  G4double crossSect = 0.;
60  if (xSource != 0)
61  // There is a total cross section for this Collision
62  {
63  crossSect = xSource->CrossSection(trk1,trk2);
64  }
65  else
66  {
67  // waiting for mutable to enable buffering.
68  const_cast<G4CollisionComposite *>(this)->BufferCrossSection(trk1.GetDefinition(), trk2.GetDefinition());
69 // G4cerr << "Buffer filled, reying with sqrts = "<< (trk1.Get4Momentum()+trk2.Get4Momentum()).mag() <<G4endl;
70  crossSect = BufferedCrossSection(trk1,trk2);
71  }
72  return crossSect;
73 }
74 
75 
77  const G4KineticTrack& trk2) const
78 {
79  std::vector<G4double> cxCache;
80  G4double partialCxSum = 0.0;
81 
82  size_t i;
83  for (i=0; i<components.size(); i++)
84  {
85  G4double partialCx;
86 // cout << "comp" << i << " " << components[i]()->GetName();
87  if (components[i]->IsInCharge(trk1,trk2))
88  {
89  partialCx = components[i]->CrossSection(trk1,trk2);
90  }
91  else
92  {
93  partialCx = 0.0;
94  }
95 // cout << " cx=" << partialCx << endl;
96  partialCxSum += partialCx;
97  cxCache.push_back(partialCx);
98  }
99 
100  G4double random = G4UniformRand()*partialCxSum;
101  G4double running = 0;
102  for (i=0; i<cxCache.size(); i++)
103  {
104  running += cxCache[i];
105  if (running > random)
106  {
107  return components[i]->FinalState(trk1, trk2);
108  }
109  }
110 // G4cerr <<"in charge = "<<IsInCharge(trk1, trk2)<<G4endl;
111 // G4cerr <<"Cross-section = "<<CrossSection(trk1, trk2)/millibarn<<" "<<running<<" "<<cxCache.size()<<G4endl;
112 // G4cerr <<"Names = "<<trk1.GetDefinition()->GetParticleName()<<", "<<trk2.GetDefinition()->GetParticleName()<<G4endl;
113 // throw G4HadronicException(__FILE__, __LINE__, "G4CollisionComposite: no final state found!");
114  return NULL;
115 }
116 
117 
119  const G4KineticTrack& trk2) const
120 {
121  G4bool isInCharge = false;
122 
123  // The composite is in charge if any of its components is in charge
124 
125  const G4CollisionVector* comps = GetComponents();
126  if (comps)
127  {
128  G4CollisionVector::const_iterator iter;
129  for (iter = comps->begin(); iter != comps->end(); ++iter)
130  {
131  if ( ((*iter))->IsInCharge(trk1,trk2) ) isInCharge = true;
132  }
133  }
134 
135  return isInCharge;
136 }
137 
140 {
141  // check if already buffered
142  size_t i;
143  for(i=0; i<theBuffer.size(); i++)
144  {
145  if(theBuffer[i].InCharge(aP, bP)) return;
146  }
147 // G4cerr << "Buffering for "<<aP->GetParticleName()<<" "<<bP->GetParticleName()<<G4endl;
148 
149  // buffer the new one.
150  G4CrossSectionBuffer aNewBuff(aP, bP);
151  size_t maxE=nPoints;
152  for(size_t tt=0; tt<maxE; tt++)
153  {
154  G4double aT = theT[tt]*GeV;
155  G4double crossSect = 0;
156  // The total cross-section is summed over all the component channels
157 
158  //A.R. 28-Sep-2012 Fix reproducibility problem
159  // Assign the kinetic energy to the lightest of the
160  // two particles, instead to the first one always.
161  G4double atime = 0;
162  G4double btime = 0;
163  G4ThreeVector aPosition(0,0,0);
164  G4ThreeVector bPosition(0,0,0);
165  G4double aM = aP->GetPDGMass();
166  G4double bM = bP->GetPDGMass();
167  G4double aE = aM;
168  G4double bE = bM;
169  G4ThreeVector aMom(0,0,0);
170  G4ThreeVector bMom(0,0,0);
171  if ( aM <= bM ) {
172  aE += aT;
173  aMom = G4ThreeVector(0,0,std::sqrt(aE*aE-aM*aM));
174  } else {
175  bE += aT;
176  bMom = G4ThreeVector(0,0,std::sqrt(bE*bE-bM*bM));
177  }
178  G4LorentzVector a4Momentum(aE, aMom);
179  G4LorentzVector b4Momentum(bE, bMom);
180  G4KineticTrack a(const_cast<G4ParticleDefinition *>(aP), atime, aPosition, a4Momentum);
181  G4KineticTrack b(const_cast<G4ParticleDefinition *>(bP), btime, bPosition, b4Momentum);
182 
183  for (i=0; i<components.size(); i++)
184  {
185  if(components[i]->IsInCharge(a,b))
186  {
187  crossSect += components[i]->CrossSection(a,b);
188  }
189  }
190  G4double sqrts = (a4Momentum+b4Momentum).mag();
191  aNewBuff.push_back(sqrts, crossSect);
192  }
193  theBuffer.push_back(aNewBuff);
194 // theBuffer.back().Print();
195 }
196 
197 
199 BufferedCrossSection(const G4KineticTrack& trk1, const G4KineticTrack& trk2) const
200 {
201  for(size_t i=0; i<theBuffer.size(); i++)
202  {
203  if(theBuffer[i].InCharge(trk1.GetDefinition(), trk2.GetDefinition()))
204  {
205  return theBuffer[i].CrossSection(trk1, trk2);
206  }
207  }
208  throw G4HadronicException(__FILE__, __LINE__, "G4CollisionComposite::BufferedCrossSection - Blitz !!");
209  return 0;
210 }
211 
virtual const G4CollisionVector * GetComponents() const
std::vector< G4CrossSectionBuffer > theBuffer
CLHEP::Hep3Vector G4ThreeVector
virtual const G4VCrossSectionSource * GetCrossSectionSource() const
static const G4int nPoints
G4CollisionVector components
G4double BufferedCrossSection(const G4KineticTrack &trk1, const G4KineticTrack &trk2) const
G4double a
Definition: TRTMaterials.hh:39
virtual G4double CrossSection(const G4KineticTrack &trk1, const G4KineticTrack &trk2) const
int G4int
Definition: G4Types.hh:78
void BufferCrossSection(const G4ParticleDefinition *aP, const G4ParticleDefinition *bP)
G4ParticleDefinition * GetDefinition() const
#define G4UniformRand()
Definition: Randomize.hh:87
bool G4bool
Definition: G4Types.hh:79
std::vector< G4VCollision * > G4CollisionVector
static const double GeV
Definition: G4SIunits.hh:196
virtual G4KineticTrackVector * FinalState(const G4KineticTrack &trk1, const G4KineticTrack &trk2) const
G4double GetPDGMass() const
virtual G4bool IsInCharge(const G4KineticTrack &trk1, const G4KineticTrack &trk2) const
void push_back(G4double S, G4double x)
double G4double
Definition: G4Types.hh:76
static const G4double theT[]
virtual G4double CrossSection(const G4KineticTrack &trk1, const G4KineticTrack &trk2) const =0
CLHEP::HepLorentzVector G4LorentzVector