Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/coherent_elastic/src/G4ChargeExchange.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 ]

Diff markup

Differences between /processes/hadronic/models/coherent_elastic/src/G4ChargeExchange.cc (Version 11.3.0) and /processes/hadronic/models/coherent_elastic/src/G4ChargeExchange.cc (Version 5.0.p1)


  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 // G4 Model: Charge and strangness exchange ba    
 27 //           28 May 2006 V.Ivanchenko             
 28 //                                                
 29 // Modified:                                      
 30 // 07-Jun-06 V.Ivanchenko fix problem of rotat    
 31 // 25-Jul-06 V.Ivanchenko add 19 MeV low energ    
 32 // 12-Jun-12 A.Ribon fix warnings of shadowed     
 33 // 06-Aug-15 A.Ribon migrating to G4Exp, G4Log    
 34 //                                                
 35                                                   
 36 #include "G4ChargeExchange.hh"                    
 37 #include "G4ChargeExchangeXS.hh"                  
 38 #include "G4PhysicalConstants.hh"                 
 39 #include "G4SystemOfUnits.hh"                     
 40 #include "G4ParticleTable.hh"                     
 41 #include "G4ParticleDefinition.hh"                
 42 #include "G4IonTable.hh"                          
 43 #include "Randomize.hh"                           
 44 #include "G4NucleiProperties.hh"                  
 45 #include "G4DecayTable.hh"                        
 46 #include "G4VDecayChannel.hh"                     
 47 #include "G4DecayProducts.hh"                     
 48 #include "G4NistManager.hh"                       
 49 #include "G4Fragment.hh"                          
 50 #include "G4ExcitationHandler.hh"                 
 51 #include "G4ReactionProductVector.hh"             
 52                                                   
 53 #include "G4Exp.hh"                               
 54 #include "G4Log.hh"                               
 55 #include "G4Pow.hh"                               
 56                                                   
 57 #include "G4HadronicParameters.hh"                
 58 #include "G4PhysicsModelCatalog.hh"               
 59                                                   
 60 namespace                                         
 61 {                                                 
 62   constexpr G4int maxN = 1000;                    
 63   constexpr G4double emin = 2*136.9*CLHEP::MeV    
 64 }                                                 
 65                                                   
 66 G4ChargeExchange::G4ChargeExchange(G4ChargeExc    
 67   : G4HadronicInteraction("ChargeExchange"),      
 68     fXSection(ptr), fXSWeightFactor(1.0)          
 69 {                                                 
 70   lowEnergyLimit = 1.*CLHEP::MeV;                 
 71   secID = G4PhysicsModelCatalog::GetModelID( "    
 72   nist = G4NistManager::Instance();               
 73   fHandler = new G4ExcitationHandler();           
 74   if (nullptr != fXSection) {                     
 75     fXSWeightFactor = 1.0/fXSection->GetCrossS    
 76   }                                               
 77 }                                                 
 78                                                   
 79 G4ChargeExchange::~G4ChargeExchange()             
 80 {                                                 
 81   delete fHandler;                                
 82 }                                                 
 83                                                   
 84 G4HadFinalState* G4ChargeExchange::ApplyYourse    
 85      const G4HadProjectile& aTrack, G4Nucleus&    
 86 {                                                 
 87   theParticleChange.Clear();                      
 88   auto part = aTrack.GetDefinition();             
 89   G4double ekin = aTrack.GetKineticEnergy();      
 90                                                   
 91   G4int A = targetNucleus.GetA_asInt();           
 92   G4int Z = targetNucleus.GetZ_asInt();           
 93                                                   
 94   if (ekin <= lowEnergyLimit) {                   
 95     return &theParticleChange;                    
 96   }                                               
 97   theParticleChange.SetWeightChange(fXSWeightF    
 98                                                   
 99   G4int projPDG = part->GetPDGEncoding();         
100                                                   
101   // for hydrogen targets and positive project    
102   // is not possible on proton, only on deuter    
103   if (1 == Z && (211 == projPDG || 321 == proj    
104                                                   
105   if (verboseLevel > 1)                           
106     G4cout << "G4ChargeExchange for " << part-    
107      << " PDGcode= " << projPDG << " on nucleu    
108      << " A= " << A << " N= " << A - Z            
109      << G4endl;                                   
110                                                   
111   G4double mass1 = G4NucleiProperties::GetNucl    
112   G4LorentzVector lv0 = aTrack.Get4Momentum();    
113   G4double etot = mass1 + lv0.e();                
114                                                   
115   // select final state                           
116   const G4ParticleDefinition* theSecondary =      
117     fXSection->SampleSecondaryType(part, Z, A)    
118   G4int pdg = theSecondary->GetPDGEncoding();     
119                                                   
120   // omega(782) and f2(1270)                      
121   G4bool isShortLived = (pdg == 223 || pdg ==     
122                                                   
123   // atomic number of the recoil nucleus          
124   if (projPDG == -211) { --Z; }                   
125   else if (projPDG == 211) { ++Z; }               
126   else if (projPDG == -321) { --Z; }              
127   else if (projPDG == 321) { ++Z; }               
128   else if (projPDG == 130) {                      
129     if (theSecondary->GetPDGCharge() > 0.0) {     
130     else { ++Z; }                                 
131   } else {                                        
132     // not ready for other projectile             
133     return &theParticleChange;                    
134   }                                               
135                                                   
136   // recoil nucleus                               
137   const G4ParticleDefinition* theRecoil = null    
138   if (Z == 0 && A == 1) { theRecoil = G4Neutro    
139   else if (Z == 1 && A == 1) { theRecoil = G4P    
140   else if (Z == 1 && A == 2) { theRecoil = G4D    
141   else if (Z == 1 && A == 3) { theRecoil = G4T    
142   else if (Z == 2 && A == 3) { theRecoil = G4H    
143   else if (Z == 2 && A == 4) { theRecoil = G4A    
144   else if (nist->GetIsotopeAbundance(Z, A) > 0    
145     theRecoil = G4ParticleTable::GetParticleTa    
146       ->GetIonTable()->GetIon(Z, A, 0.0);         
147   }                                               
148                                                   
149   // check if there is enough energy for the f    
150   // and sample mass of produced state            
151   const G4double mass0 = theSecondary->GetPDGM    
152   G4double mass3 = (nullptr == theRecoil) ?       
153     G4NucleiProperties::GetNuclearMass(A, Z) :    
154   G4double mass2 = mass0;                         
155   if (isShortLived &&                             
156       !SampleMass(mass2, theSecondary->GetPDGW    
157     return &theParticleChange;                    
158   }                                               
159                                                   
160   // not possible kinematically                   
161   if (etot <= mass2 + mass3) {                    
162     return &theParticleChange;                    
163   }                                               
164                                                   
165   // sample kinematics                            
166   G4LorentzVector lv1(0.0, 0.0, 0.0, mass1);      
167   G4LorentzVector lv = lv0 + lv1;                 
168   G4ThreeVector bst = lv.boostVector();           
169   G4double ss = lv.mag2();                        
170                                                   
171   // tmax = 4*momCMS^2                            
172   G4double e2 = ss + mass2*mass2 - mass3*mass3    
173   G4double tmax = e2*e2/ss - 4*mass2*mass2;       
174                                                   
175   G4double t = SampleT(theSecondary, A, tmax);    
176                                                   
177   G4double phi  = G4UniformRand()*CLHEP::twopi    
178   G4double cost = 1. - 2.0*t/tmax;                
179                                                   
180   if (cost > 1.0) { cost = 1.0; }                 
181   else if(cost < -1.0) { cost = -1.0; }           
182                                                   
183   G4double sint = std::sqrt((1.0-cost)*(1.0+co    
184                                                   
185   if (verboseLevel>1) {                           
186     G4cout << " t= " << t << " tmax(GeV^2)= "     
187      << " cos(t)=" << cost << " sin(t)=" << si    
188   }                                               
189   G4double momentumCMS = 0.5*std::sqrt(tmax);     
190   G4LorentzVector lv2(momentumCMS*sint*std::co    
191           momentumCMS*sint*std::sin(phi),         
192           momentumCMS*cost,                       
193           std::sqrt(momentumCMS*momentumCMS +     
194                                                   
195   // kinematics in the final state, may be a w    
196   lv2.boost(bst);                                 
197   if (lv2.e() < mass2) {                          
198     lv2.setE(mass2);                              
199   }                                               
200   lv -= lv2;                                      
201   if (lv.e() < mass3) {                           
202     lv.setE(mass3);                               
203   }                                               
204                                                   
205   // prepare secondary particles                  
206   theParticleChange.SetStatusChange(stopAndKil    
207   theParticleChange.SetEnergyChange(0.0);         
208                                                   
209   if (!isShortLived) {                            
210     auto aSec = new G4DynamicParticle(theSecon    
211     theParticleChange.AddSecondary(aSec, secID    
212   } else {                                        
213     auto channel = theSecondary->GetDecayTable    
214     auto products = channel->DecayIt(mass2);      
215     G4ThreeVector bst1 = lv2.boostVector();       
216     G4int N = products->entries();                
217     for (G4int i=0; i<N; ++i) {                   
218       auto p = (*products)[i];                    
219       auto lvp = p->Get4Momentum();               
220       lvp.boost(bst1);                            
221       p->Set4Momentum(lvp);                       
222       theParticleChange.AddSecondary(p, secID)    
223     }                                             
224     delete products;                              
225   }                                               
226                                                   
227   // recoil is a stable isotope                   
228   if (nullptr != theRecoil) {                     
229     auto aRec = new G4DynamicParticle(theRecoi    
230     theParticleChange.AddSecondary(aRec, secID    
231   } else {                                        
232     // recoil is an unstable fragment             
233     G4Fragment frag(A, Z, lv);                    
234     auto products = fHandler->BreakItUp(frag);    
235     for (auto & prod : *products) {               
236       auto dp = new G4DynamicParticle(prod->Ge    
237       theParticleChange.AddSecondary(dp, secID    
238       delete prod;                                
239     }                                             
240     delete products;                              
241   }                                               
242   return &theParticleChange;                      
243 }                                                 
244                                                   
245 G4double G4ChargeExchange::SampleT(const G4Par    
246                                    const G4int    
247 {                                                 
248   G4double aa, bb, cc, dd;                        
249   G4Pow* g4pow = G4Pow::GetInstance();            
250   if (A <= 62.) {                                 
251     aa = g4pow->powZ(A, 1.63);                    
252     bb = 14.5*g4pow->powZ(A, 0.66);               
253     cc = 1.4*g4pow->powZ(A, 0.33);                
254     dd = 10.;                                     
255   } else {                                        
256     aa = g4pow->powZ(A, 1.33);                    
257     bb = 60.*g4pow->powZ(A, 0.33);                
258     cc = 0.4*g4pow->powZ(A, 0.40);                
259     dd = 10.;                                     
260   }                                               
261   G4double x1 = (1.0 - G4Exp(-tmax*bb))*aa/bb;    
262   G4double x2 = (1.0 - G4Exp(-tmax*dd))*cc/dd;    
263                                                   
264   G4double t;                                     
265   G4double y = bb;                                
266   if(G4UniformRand()*(x1 + x2) < x2) y = dd;      
267                                                   
268   for (G4int i=0; i<maxN; ++i) {                  
269     t = -G4Log(G4UniformRand())/y;                
270     if (t <= tmax) { return t; }                  
271   }                                               
272   return 0.0;                                     
273 }                                                 
274                                                   
275 G4bool G4ChargeExchange::SampleMass(G4double&     
276 {                                                 
277   // +- 4 width but above 2 pion mass             
278   const G4double e1 = std::max(M - 4*G, emin);    
279   const G4double e2 = std::min(M + 4*G, elim)     
280   if (e2 <= 0.0) { return false; }                
281   const G4double M2 = M*M;                        
282   const G4double MG2 = M2*G*G;                    
283                                                   
284   // sampling Breit-Wigner function               
285   for (G4int i=0; i<maxN; ++i) {                  
286     G4double e = e1 + e2*G4UniformRand();         
287     G4double x = e*e - M2;                        
288     G4double y = MG2/(x*x + MG2);                 
289     if (y >= G4UniformRand()) {                   
290       M = e;                                      
291       return true;                                
292     }                                             
293   }                                               
294   return false;                                   
295 }                                                 
296