Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/im_r_matrix/src/G4MesonAbsorption.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 #include "G4MesonAbsorption.hh"
 28 #include "G4PhysicalConstants.hh"
 29 #include "G4SystemOfUnits.hh"
 30 #include "G4LorentzRotation.hh"
 31 #include "G4LorentzVector.hh"
 32 #include "Randomize.hh"
 33 #include "G4KineticTrackVector.hh"
 34 #include "G4CollisionInitialState.hh"
 35 #include <cmath>
 36 #include "G4PionPlus.hh"
 37 #include "G4PionMinus.hh"
 38 #include "G4ParticleDefinition.hh"
 39 #include "G4HadTmpUtil.hh"
 40 
 41 // first prototype
 42 
 43 const std::vector<G4CollisionInitialState *> & G4MesonAbsorption::
 44 GetCollisions(G4KineticTrack * aProjectile,
 45               std::vector<G4KineticTrack *> & someCandidates,
 46         G4double aCurrentTime)
 47 {
 48   theCollisions.clear();
 49   if(someCandidates.size() >1)
 50   {
 51     std::vector<G4KineticTrack *>::iterator j=someCandidates.begin();
 52     for(; j != someCandidates.end(); ++j)
 53     {
 54       G4double collisionTime = GetTimeToAbsorption(*aProjectile, **j);
 55       if(collisionTime == DBL_MAX)
 56       {
 57         continue;
 58       }
 59       G4KineticTrackVector aTarget;
 60       aTarget.push_back(*j);
 61       FindAndFillCluster(aTarget, aProjectile, someCandidates);
 62       if(aTarget.size()>=2)
 63       {
 64         theCollisions.push_back(
 65         new G4CollisionInitialState(collisionTime+aCurrentTime, aProjectile, aTarget, this) );
 66       }
 67     }
 68   }
 69   return theCollisions;
 70 }
 71 
 72 
 73 void G4MesonAbsorption::
 74 FindAndFillCluster(G4KineticTrackVector & result,
 75                    G4KineticTrack * aProjectile, std::vector<G4KineticTrack *> & someCandidates)
 76 {
 77   std::vector<G4KineticTrack *>::iterator j=someCandidates.begin();
 78   G4KineticTrack * aTarget = result[0];
 79   G4int chargeSum = G4lrint(aTarget->GetDefinition()->GetPDGCharge());
 80   chargeSum+=G4lrint(aProjectile->GetDefinition()->GetPDGCharge());
 81   G4ThreeVector firstBase = aTarget->GetPosition();
 82   G4double min = DBL_MAX;
 83   G4KineticTrack * partner = 0;
 84   for(; j != someCandidates.end(); ++j)
 85   {
 86     if(*j == aTarget) continue;
 87     G4int cCharge = G4lrint((*j)->GetDefinition()->GetPDGCharge());
 88     if (chargeSum+cCharge > 2) continue;
 89     if (chargeSum+cCharge < 0) continue;
 90     // get the one with the smallest distance.
 91     G4ThreeVector secodeBase = (*j)->GetPosition();
 92     if((firstBase+secodeBase).mag()<min)
 93     {
 94       min=(firstBase+secodeBase).mag();
 95       partner = *j;
 96     }
 97   }
 98   if(partner) result.push_back(partner);
 99   else result.clear();
100 }
101 
102 
103 G4KineticTrackVector * G4MesonAbsorption::
104 GetFinalState(G4KineticTrack * projectile,
105               std::vector<G4KineticTrack *> & targets)
106 {
107   // G4cout << "We have an absorption !!!!!!!!!!!!!!!!!!!!!!"<<G4endl;
108   // Only 2-body absorption for the time being.
109   // If insufficient, use 2-body absorption and clusterization to emulate 3-,4-,etc body absorption.
110   G4LorentzVector thePro = projectile->Get4Momentum();
111   G4LorentzVector theT1 = targets[0]->Get4Momentum();
112   G4LorentzVector theT2 = targets[1]->Get4Momentum();
113   G4LorentzVector incoming = thePro + theT1 + theT2;
114   G4double energyBalance = incoming.t();
115   G4int chargeBalance = G4lrint(projectile->GetDefinition()->GetPDGCharge()
116                        + targets[0]->GetDefinition()->GetPDGCharge()
117                        + targets[1]->GetDefinition()->GetPDGCharge());
118 
119   G4int baryonBalance = projectile->GetDefinition()->GetBaryonNumber()
120                        + targets[0]->GetDefinition()->GetBaryonNumber()
121                        + targets[1]->GetDefinition()->GetBaryonNumber();
122 
123 
124   // boost all to MMS
125   G4LorentzRotation toSPS((-1)*(thePro + theT1 + theT2).boostVector());
126   theT1 = toSPS * theT1;
127   theT2 = toSPS * theT2;
128   thePro = toSPS * thePro;
129   G4LorentzRotation fromSPS(toSPS.inverse());
130 
131   // rotate to z
132   G4LorentzRotation toZ;
133   G4LorentzVector Ptmp=projectile->Get4Momentum();
134   toZ.rotateZ(-1*Ptmp.phi());
135   toZ.rotateY(-1*Ptmp.theta());
136   theT1 = toZ * theT1;
137   theT2 = toZ * theT2;
138   thePro = toZ * thePro;
139   G4LorentzRotation toLab(toZ.inverse());
140 
141   // Get definitions
142   const G4ParticleDefinition * d1 = targets[0]->GetDefinition();
143   const G4ParticleDefinition * d2 = targets[1]->GetDefinition();
144   if(0.5>G4UniformRand())
145   {
146     const G4ParticleDefinition * temp;
147     temp=d1;d1=d2;d2=temp;
148   }
149   const G4ParticleDefinition * dp = projectile->GetDefinition();
150   if(dp->GetPDGCharge()<-.5)
151   {
152     if(d1->GetPDGCharge()>.5)
153     {
154       if(d2->GetPDGCharge()>.5 && 0.5>G4UniformRand())
155       {
156         d2 = G4Neutron::NeutronDefinition();
157       }
158       else
159       {
160         d1 = G4Neutron::NeutronDefinition();
161       }
162     }
163     else if(d2->GetPDGCharge()>.5)
164     {
165       d2 = G4Neutron::NeutronDefinition();
166     }
167   }
168   else if(dp->GetPDGCharge()>.5)
169   {
170     if(d1->GetPDGCharge()<.5)
171     {
172       if(d2->GetPDGCharge()<.5 && 0.5>G4UniformRand())
173       {
174         d2 = G4Proton::ProtonDefinition();
175       }
176       else
177       {
178         d1 = G4Proton::ProtonDefinition();
179       }
180     }
181     else if(d2->GetPDGCharge()<.5)
182     {
183       d2 = G4Proton::ProtonDefinition();
184     }
185   }
186 
187   // calculate the momenta.
188   G4double M_sq  = (thePro+theT1+theT2).mag2();
189   G4double m1_sq = sqr(d1->GetPDGMass());
190   G4double m2_sq = sqr(d2->GetPDGMass());
191   G4double m_sq  = M_sq-m1_sq-m2_sq;
192   G4double p = std::sqrt((m_sq*m_sq - 4.*m1_sq * m2_sq)/(4.*M_sq));
193   G4double costh = 2.*G4UniformRand()-1.;
194   G4double phi = 2.*pi*G4UniformRand();
195   G4ThreeVector pFinal(p*std::sin(std::acos(costh))*std::cos(phi), p*std::sin(std::acos(costh))*std::sin(phi), p*costh);
196 
197   // G4cout << "testing p "<<p-pFinal.mag()<<G4endl;
198   // construct the final state particles lorentz momentum.
199   G4double eFinal1 = std::sqrt(m1_sq+pFinal.mag2());
200   G4LorentzVector final1(pFinal, eFinal1);
201   G4double eFinal2 = std::sqrt(m2_sq+pFinal.mag2());
202   G4LorentzVector final2(-1.*pFinal, eFinal2);
203 
204   // rotate back.
205   final1 = toLab * final1;
206   final2 = toLab * final2;
207 
208   // boost back to LAB
209   final1 = fromSPS * final1;
210   final2 = fromSPS * final2;
211 
212   // make the final state
213   G4KineticTrack * f1 =
214       new G4KineticTrack(d1, 0., targets[0]->GetPosition(), final1);
215   G4KineticTrack * f2 =
216       new G4KineticTrack(d2, 0., targets[1]->GetPosition(), final2);
217   G4KineticTrackVector * result = new G4KineticTrackVector;
218   result->push_back(f1);
219   result->push_back(f2);
220 
221   for(size_t hpw=0; hpw<result->size(); hpw++)
222   {
223     energyBalance-=result->operator[](hpw)->Get4Momentum().t();
224     chargeBalance-=G4lrint(result->operator[](hpw)->GetDefinition()->GetPDGCharge());
225     baryonBalance-=result->operator[](hpw)->GetDefinition()->GetBaryonNumber();
226   }
227   if(std::getenv("AbsorptionEnergyBalanceCheck"))
228     std::cout << "DEBUGGING energy balance B: "
229               <<energyBalance<<" "
230         <<chargeBalance<<" "
231         <<baryonBalance<<" "
232           <<G4endl;
233   return result;
234 }
235 
236 
237 G4double G4MesonAbsorption::
238 GetTimeToAbsorption(const G4KineticTrack& trk1, const G4KineticTrack& trk2)
239 {
240   if(trk1.GetDefinition()!=G4PionPlus::PionPlusDefinition() &&
241      trk1.GetDefinition()!=G4PionMinus::PionMinusDefinition() &&
242      trk2.GetDefinition()!=G4PionPlus::PionPlusDefinition() &&
243      trk2.GetDefinition()!=G4PionMinus::PionMinusDefinition())
244   {
245     return DBL_MAX;
246   }
247   G4double time = DBL_MAX;
248   G4double sqrtS = (trk1.Get4Momentum() + trk2.Get4Momentum()).mag();
249 
250   // Check whether there is enough energy for elastic scattering
251   // (to put the particles on to mass shell
252 
253   if (trk1.GetActualMass() + trk2.GetActualMass() < sqrtS)
254   {
255     G4LorentzVector mom1 = trk1.GetTrackingMomentum();
256     G4ThreeVector position = trk1.GetPosition() - trk2.GetPosition();
257     if ( mom1.mag2() < -1.*eV )
258     {
259       G4cout << "G4MesonAbsorption::GetTimeToInteraction(): negative m2:" << mom1.mag2() << G4endl;
260     }
261     G4ThreeVector velocity = mom1.vect()/mom1.e() * c_light;
262     G4double collisionTime = - (position * velocity) / (velocity * velocity);
263 
264     if (collisionTime > 0)
265     {
266       G4LorentzVector mom2(0,0,0,trk2.Get4Momentum().mag());
267       G4LorentzRotation toCMSFrame((-1)*(mom1 + mom2).boostVector());
268       mom1 = toCMSFrame * mom1;
269       mom2 = toCMSFrame * mom2;
270 
271       G4LorentzVector coordinate1(trk1.GetPosition(), 100.);
272       G4LorentzVector coordinate2(trk2.GetPosition(), 100.);
273       G4ThreeVector pos = ((toCMSFrame * coordinate1).vect() -
274           (toCMSFrame * coordinate2).vect());
275       G4ThreeVector mom = mom1.vect() - mom2.vect();
276 
277       G4double distance = pos * pos - (pos*mom) * (pos*mom) / (mom*mom);
278 
279       // global optimization
280       static const G4double maxCrossSection = 500*millibarn;
281       if(pi*distance>maxCrossSection) return time;
282       // charged particles special optimization
283       static const G4double maxChargedCrossSection = 200*millibarn;
284       if(std::abs(trk1.GetDefinition()->GetPDGCharge())>0.1 &&
285          std::abs(trk2.GetDefinition()->GetPDGCharge())>0.1 &&
286         pi*distance>maxChargedCrossSection) return time;
287       // neutrons special optimization
288       if(( trk1.GetDefinition() == G4Neutron::Neutron() ||
289           trk2.GetDefinition() == G4Neutron::Neutron() ) &&
290           sqrtS>1.91*GeV && pi*distance>maxChargedCrossSection) return time;
291 
292       G4double totalCrossSection = AbsorptionCrossSection(trk1,trk2);
293       if ( totalCrossSection > 0 )
294       {
295   if (distance <= totalCrossSection / pi)
296   {
297     time = collisionTime;
298   }
299       }
300     }
301   }
302   return time;
303 }
304 
305 G4double G4MesonAbsorption::
306 AbsorptionCrossSection(const G4KineticTrack & aT, const G4KineticTrack & bT)
307 {
308   G4double t = 0;
309   if(aT.GetDefinition()==G4PionPlus::PionPlusDefinition() ||
310      aT.GetDefinition()==G4PionMinus::PionMinusDefinition() )
311   {
312     t = aT.Get4Momentum().t()-aT.Get4Momentum().mag()/MeV;
313   }
314   else if(bT.GetDefinition()==G4PionPlus::PionPlusDefinition() ||
315         bT.GetDefinition()!=G4PionMinus::PionMinusDefinition())
316   {
317     t = bT.Get4Momentum().t()-bT.Get4Momentum().mag()/MeV;
318   }
319 
320   static const G4double it [26] =
321         {0,4,50,5.5,75,8,95,10,120,11.5,140,12,160,11.5,180,10,190,8,210,6,235,4,260,3,300,2};
322 
323   G4double aCross(0);
324   if(t<=it[24])
325   {
326     G4int count = 0;
327     while(t>it[count])count+=2;              /* Loop checking, 30-Oct-2015, G.Folger */
328    
329     G4double x1 = it[count-2];
330     G4double x2 = it[count];
331     G4double y1 = it[count-1];
332     G4double y2 = it[count+1];
333     aCross = y1+(y2-y1)/(x2-x1)*(t-x1);
334     // G4cout << "Printing the absorption crosssection "
335     //        <<x1<< " "<<x2<<" "<<t<<" "<<y1<<" "<<y2<<" "<<0.5*aCross<<G4endl;
336   }
337   return .5*aCross*millibarn;
338 }
339