Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/interface/src/G4INCLXXInterface.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/inclxx/interface/src/G4INCLXXInterface.cc (Version 11.3.0) and /processes/hadronic/models/inclxx/interface/src/G4INCLXXInterface.cc (Version 7.1)


  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 // INCL++ intra-nuclear cascade model             
 27 // Alain Boudard, CEA-Saclay, France              
 28 // Joseph Cugnon, University of Liege, Belgium    
 29 // Jean-Christophe David, CEA-Saclay, France      
 30 // Pekka Kaitaniemi, CEA-Saclay, France, and H    
 31 // Sylvie Leray, CEA-Saclay, France               
 32 // Davide Mancusi, CEA-Saclay, France             
 33 //                                                
 34 #define INCLXX_IN_GEANT4_MODE 1                   
 35                                                   
 36 #include "globals.hh"                             
 37                                                   
 38 #include <cmath>                                  
 39                                                   
 40 #include "G4PhysicalConstants.hh"                 
 41 #include "G4SystemOfUnits.hh"                     
 42 #include "G4INCLXXInterface.hh"                   
 43 #include "G4GenericIon.hh"                        
 44 #include "G4INCLCascade.hh"                       
 45 #include "G4ReactionProductVector.hh"             
 46 #include "G4ReactionProduct.hh"                   
 47 #include "G4HadSecondary.hh"                      
 48 #include "G4ParticleTable.hh"                     
 49 #include "G4INCLXXInterfaceStore.hh"              
 50 #include "G4INCLXXVInterfaceTally.hh"             
 51 #include "G4String.hh"                            
 52 #include "G4PhysicalConstants.hh"                 
 53 #include "G4SystemOfUnits.hh"                     
 54 #include "G4HadronicInteractionRegistry.hh"       
 55 #include "G4INCLVersion.hh"                       
 56 #include "G4VEvaporation.hh"                      
 57 #include "G4VEvaporationChannel.hh"               
 58 #include "G4CompetitiveFission.hh"                
 59 #include "G4FissionLevelDensityParameterINCLXX    
 60 #include "G4PhysicsModelCatalog.hh"               
 61                                                   
 62 #include "G4HyperNucleiProperties.hh"             
 63 #include "G4HyperTriton.hh"                       
 64 #include "G4HyperH4.hh"                           
 65 #include "G4HyperAlpha.hh"                        
 66 #include "G4DoubleHyperH4.hh"                     
 67 #include "G4DoubleHyperDoubleNeutron.hh"          
 68 #include "G4HyperHe5.hh"                          
 69                                                   
 70 G4INCLXXInterface::G4INCLXXInterface(G4VPreCom    
 71   G4VIntraNuclearTransportModel(G4INCLXXInterf    
 72   theINCLModel(NULL),                             
 73   thePreCompoundModel(aPreCompound),              
 74   theInterfaceStore(G4INCLXXInterfaceStore::Ge    
 75   theTally(NULL),                                 
 76   complainedAboutBackupModel(false),              
 77   complainedAboutPreCompound(false),              
 78   theIonTable(G4IonTable::GetIonTable()),         
 79   theINCLXXLevelDensity(NULL),                    
 80   theINCLXXFissionProbability(NULL),              
 81   secID(-1)                                       
 82 {                                                 
 83   if(!thePreCompoundModel) {                      
 84     G4HadronicInteraction* p =                    
 85       G4HadronicInteractionRegistry::Instance(    
 86     thePreCompoundModel = static_cast<G4VPreCo    
 87     if(!thePreCompoundModel) { thePreCompoundM    
 88   }                                               
 89                                                   
 90   // Use the environment variable G4INCLXX_NO_    
 91   if(std::getenv("G4INCLXX_NO_DE_EXCITATION"))    
 92     G4String message = "de-excitation is compl    
 93     theInterfaceStore->EmitWarning(message);      
 94     theDeExcitation = 0;                          
 95   } else {                                        
 96     G4HadronicInteraction* p =                    
 97       G4HadronicInteractionRegistry::Instance(    
 98     theDeExcitation = static_cast<G4VPreCompou    
 99     if(!theDeExcitation) { theDeExcitation = n    
100                                                   
101     // set the fission parameters for G4Excita    
102     G4VEvaporationChannel * const theFissionCh    
103       theDeExcitation->GetExcitationHandler()-    
104     G4CompetitiveFission * const theFissionCha    
105     if(theFissionChannelCast) {                   
106       theINCLXXLevelDensity = new G4FissionLev    
107       theFissionChannelCast->SetLevelDensityPa    
108       theINCLXXFissionProbability = new G4Fiss    
109       theINCLXXFissionProbability->SetFissionL    
110       theFissionChannelCast->SetEmissionStrate    
111       theInterfaceStore->EmitBigWarning("INCL+    
112     } else {                                      
113       theInterfaceStore->EmitBigWarning("INCL+    
114     }                                             
115   }                                               
116                                                   
117   // use the envvar G4INCLXX_DUMP_REMNANT to d    
118   // remnants on stdout                           
119   if(std::getenv("G4INCLXX_DUMP_REMNANT"))        
120     dumpRemnantInfo = true;                       
121   else                                            
122     dumpRemnantInfo = false;                      
123                                                   
124   theBackupModel = new G4BinaryLightIonReactio    
125   theBackupModelNucleon = new G4BinaryCascade;    
126   secID = G4PhysicsModelCatalog::GetModelID( "    
127 }                                                 
128                                                   
129 G4INCLXXInterface::~G4INCLXXInterface()           
130 {                                                 
131   delete theINCLXXLevelDensity;                   
132   delete theINCLXXFissionProbability;             
133 }                                                 
134                                                   
135 G4bool G4INCLXXInterface::AccurateProjectile(c    
136   // Use direct kinematics if the projectile i    
137   const G4ParticleDefinition *projectileDef =     
138   if(std::abs(projectileDef->GetBaryonNumber()    
139     return false;                                 
140                                                   
141   // Here all projectiles should be nuclei        
142   const G4int pA = projectileDef->GetAtomicMas    
143   if(pA<=0) {                                     
144     std::stringstream ss;                         
145     ss << "the model does not know how to hand    
146       << projectileDef->GetParticleName() << "    
147       << theNucleus.GetZ_asInt() << ", A=" <<     
148     theInterfaceStore->EmitBigWarning(ss.str()    
149     return true;                                  
150   }                                               
151                                                   
152   // If either nucleus is a LCP (A<=4), run th    
153   const G4int tA = theNucleus.GetA_asInt();       
154   if(tA<=4 || pA<=4) {                            
155     if(pA<tA)                                     
156       return false;                               
157     else                                          
158       return true;                                
159   }                                               
160                                                   
161   // If one of the nuclei is heavier than theM    
162   // as light on heavy.                           
163   // Note that here we are sure that either th    
164   // smaller than theMaxProjMass; otherwise th    
165   // called.                                      
166   const G4int theMaxProjMassINCL = theInterfac    
167   if(pA > theMaxProjMassINCL)                     
168     return true;                                  
169   else if(tA > theMaxProjMassINCL)                
170     return false;                                 
171   else                                            
172     // In all other cases, use the global sett    
173     return theInterfaceStore->GetAccurateProje    
174 }                                                 
175                                                   
176 G4HadFinalState* G4INCLXXInterface::ApplyYours    
177 {                                                 
178   G4ParticleDefinition const * const trackDefi    
179   const G4bool isIonTrack = trackDefinition->G    
180   const G4int trackA = trackDefinition->GetAto    
181   const G4int trackZ = (G4int) trackDefinition    
182   const G4int trackL = trackDefinition->GetNum    
183   const G4int nucleusA = theNucleus.GetA_asInt    
184   const G4int nucleusZ = theNucleus.GetZ_asInt    
185                                                   
186   // For reactions induced by weird projectile    
187   if((isIonTrack && ((trackZ<=0 && trackL==0)     
188                     (nucleusA>1 && (nucleusZ<=    
189     theResult.Clear();                            
190     theResult.SetStatusChange(isAlive);           
191     theResult.SetEnergyChange(aTrack.GetKineti    
192     theResult.SetMomentumChange(aTrack.Get4Mom    
193     return &theResult;                            
194   }                                               
195                                                   
196   // For reactions on nucleons, use the backup    
197   // except for anti_proton projectile (in thi    
198   if(trackA<=1 && nucleusA<=1 && (trackZ>=0 ||    
199     return theBackupModelNucleon->ApplyYoursel    
200   }                                               
201                                                   
202   // For systems heavier than theMaxProjMassIN    
203   // BIC)                                         
204   const G4int theMaxProjMassINCL = theInterfac    
205   if(trackA > theMaxProjMassINCL && nucleusA >    
206     if(!complainedAboutBackupModel) {             
207       complainedAboutBackupModel = true;          
208       std::stringstream ss;                       
209       ss << "INCL++ refuses to handle reaction    
210         << theMaxProjMassINCL                     
211         << ". A backup model ("                   
212         << theBackupModel->GetModelName()         
213         << ") will be used instead.";             
214       theInterfaceStore->EmitBigWarning(ss.str    
215     }                                             
216     return theBackupModel->ApplyYourself(aTrac    
217   }                                               
218                                                   
219   // For energies lower than cascadeMinEnergyP    
220   const G4double cascadeMinEnergyPerNucleon =     
221   const G4double trackKinE = aTrack.GetKinetic    
222   if((trackDefinition==G4Neutron::NeutronDefin    
223       && trackKinE < cascadeMinEnergyPerNucleo    
224     if(!complainedAboutPreCompound) {             
225       complainedAboutPreCompound = true;          
226       std::stringstream ss;                       
227       ss << "INCL++ refuses to handle nucleon-    
228         << cascadeMinEnergyPerNucleon / MeV       
229         << " MeV. A PreCoumpound model ("         
230         << thePreCompoundModel->GetModelName()    
231         << ") will be used instead.";             
232       theInterfaceStore->EmitBigWarning(ss.str    
233     }                                             
234     return thePreCompoundModel->ApplyYourself(    
235   }                                               
236                                                   
237   // Calculate the total four-momentum in the     
238   const G4double theNucleusMass = theIonTable-    
239   const G4double theTrackMass = trackDefinitio    
240   const G4double theTrackEnergy = trackKinE +     
241   const G4double theTrackMomentumAbs2 = theTra    
242   const G4double theTrackMomentumAbs = ((theTr    
243   const G4ThreeVector theTrackMomentum = aTrac    
244                                                   
245   G4LorentzVector goodTrack4Momentum(theTrackM    
246   G4LorentzVector fourMomentumIn;                 
247   fourMomentumIn.setE(theTrackEnergy + theNucl    
248   fourMomentumIn.setVect(theTrackMomentum);       
249                                                   
250   // Check if inverse kinematics should be use    
251   const G4bool inverseKinematics = AccuratePro    
252                                                   
253   // If we are running in inverse kinematics,     
254   G4LorentzRotation *toInverseKinematics = NUL    
255   G4LorentzRotation *toDirectKinematics = NULL    
256   G4HadProjectile const *aProjectileTrack = &a    
257   G4Nucleus *theTargetNucleus = &theNucleus;      
258   if(inverseKinematics) {                         
259     G4ParticleDefinition *oldTargetDef = theIo    
260     const G4ParticleDefinition *oldProjectileD    
261                                                   
262     if(oldProjectileDef != 0 && oldTargetDef !    
263       const G4int newTargetA = oldProjectileDe    
264       const G4int newTargetZ = oldProjectileDe    
265       const G4int newTargetL = oldProjectileDe    
266       if(newTargetA > 0 && newTargetZ > 0) {      
267         // This should give us the same energy    
268         theTargetNucleus = new G4Nucleus(newTa    
269         toInverseKinematics = new G4LorentzRot    
270         G4LorentzVector theProjectile4Momentum    
271         G4DynamicParticle swappedProjectilePar    
272         aProjectileTrack = new G4HadProjectile    
273       } else {                                    
274         G4String message = "badly defined targ    
275         theInterfaceStore->EmitWarning(message    
276         toInverseKinematics = new G4LorentzRot    
277       }                                           
278     } else {                                      
279       G4String message = "oldProjectileDef or     
280       theInterfaceStore->EmitWarning(message);    
281       toInverseKinematics = new G4LorentzRotat    
282     }                                             
283   }                                               
284                                                   
285   // INCL assumes the projectile particle is g    
286   // the Z-axis. Here we construct proper rota    
287   // momentum vectors of the outcoming particl    
288   // coordinate system.                           
289   G4LorentzVector projectileMomentum = aProjec    
290                                                   
291   // INCL++ assumes that the projectile is goi    
292   // the z-axis. In principle, if the coordina    
293   // hadronic framework is defined differently    
294   // transform the INCL++ reaction products to    
295   // frame. Please note that it isn't necessar    
296   // transform to the projectile because when     
297   // projectile particle; \see{toINCLKineticEn    
298   // projectile energy (direction is simply as    
299   G4RotationMatrix toZ;                           
300   toZ.rotateZ(-projectileMomentum.phi());         
301   toZ.rotateY(-projectileMomentum.theta());       
302   G4RotationMatrix toLabFrame3 = toZ.inverse()    
303   G4LorentzRotation toLabFrame(toLabFrame3);      
304   // However, it turns out that the projectile    
305   // hadronic framework is already going in th    
306   // z-axis so this rotation is actually unnec    
307   // toLabFrame turn out to be unit matrices a    
308   // uncommenting the folowing two lines:         
309   // G4cout <<"toZ = " << toZ << G4endl;          
310   // G4cout <<"toLabFrame = " << toLabFrame <<    
311                                                   
312   theResult.Clear(); // Make sure the output d    
313   theResult.SetStatusChange(stopAndKill);         
314                                                   
315   std::list<G4Fragment> remnants;                 
316                                                   
317   const G4int maxTries = 200;                     
318   G4int nTries = 0;                               
319   // INCL can generate transparent events. How    
320   // only in the standalone code. In Geant4 we    
321   // produce a valid cascade.                     
322   G4bool eventIsOK = false;                       
323   do {                                            
324     const G4INCL::ParticleSpecies theSpecies =    
325     const G4double kineticEnergy = toINCLKinet    
326                                                   
327     // The INCL model will be created at the f    
328     theINCLModel = G4INCLXXInterfaceStore::Get    
329                                                   
330     const G4INCL::EventInfo eventInfo = theINC    
331                    theTargetNucleus->GetA_asIn    
332                    theTargetNucleus->GetZ_asIn    
333                    -theTargetNucleus->GetL());    
334     //    eventIsOK = !eventInfo.transparent &    
335     eventIsOK = !eventInfo.transparent;           
336     if(eventIsOK) {                               
337                                                   
338       // If the collision was run in inverse k    
339       // all the reaction products                
340       if(inverseKinematics) {                     
341         toDirectKinematics = new G4LorentzRota    
342       }                                           
343                                                   
344       G4LorentzVector fourMomentumOut;            
345                                                   
346       for(G4int i = 0; i < eventInfo.nParticle    
347         G4int A = eventInfo.A[i];                 
348         G4int Z = eventInfo.Z[i];                 
349         G4int S = eventInfo.S[i];  // Strangen    
350         G4int PDGCode = eventInfo.PDGCode[i];     
351         G4double kinE = eventInfo.EKin[i];        
352         G4double px = eventInfo.px[i];            
353         G4double py = eventInfo.py[i];            
354         G4double pz = eventInfo.pz[i];            
355         G4DynamicParticle *p = toG4Particle(A,    
356         if(p != 0) {                              
357           G4LorentzVector momentum = p->Get4Mo    
358                                                   
359           // Apply the toLabFrame rotation        
360           momentum *= toLabFrame;                 
361           // Apply the inverse-kinematics boos    
362           if(inverseKinematics) {                 
363             momentum *= *toDirectKinematics;      
364             momentum.setVect(-momentum.vect())    
365           }                                       
366                                                   
367     // Set the four-momentum of the reaction p    
368           p->Set4Momentum(momentum);              
369           fourMomentumOut += momentum;            
370                                                   
371     // Propagate the particle's parent resonan    
372           G4HadSecondary secondary(p, 1.0, sec    
373           G4ParticleDefinition* parentResonanc    
374           if ( eventInfo.parentResonancePDGCod    
375             parentResonanceDef = G4ParticleTab    
376           }                                       
377           secondary.SetParentResonanceDef(pare    
378           secondary.SetParentResonanceID(event    
379                                                   
380           theResult.AddSecondary(secondary);      
381                                                   
382         } else {                                  
383           G4String message = "the model produc    
384           theInterfaceStore->EmitWarning(messa    
385         }                                         
386       }                                           
387                                                   
388       for(G4int i = 0; i < eventInfo.nRemnants    
389         const G4int A = eventInfo.ARem[i];        
390         const G4int Z = eventInfo.ZRem[i];        
391         const G4int S = eventInfo.SRem[i];        
392         // Check that the remnant is a physica    
393         if(( Z == 0  &&  S == 0  &&  A > 1 ) |    
394            ( Z == 0  &&  S != 0  &&  A < 4 ) |    
395            ( Z != 0  &&  S != 0  &&  A == Z +     
396           std::stringstream ss;                   
397           ss << "unphysical residual fragment     
398              << "  skipping it and resampling     
399           theInterfaceStore->EmitWarning(ss.st    
400           eventIsOK = false;                      
401           continue;                               
402         }                                         
403         const G4double kinE = eventInfo.EKinRe    
404         const G4double px = eventInfo.pxRem[i]    
405         const G4double py = eventInfo.pyRem[i]    
406         const G4double pz = eventInfo.pzRem[i]    
407         G4ThreeVector spin(                       
408             eventInfo.jxRem[i]*hbar_Planck,       
409             eventInfo.jyRem[i]*hbar_Planck,       
410             eventInfo.jzRem[i]*hbar_Planck        
411             );                                    
412         const G4double excitationE = eventInfo    
413         G4double nuclearMass = excitationE;       
414         if ( S == 0 ) {                           
415           nuclearMass += G4NucleiProperties::G    
416         } else {                                  
417     // Assumed that the opposite of the strang    
418           nuclearMass += G4HyperNucleiProperti    
419         }                                         
420         const G4double scaling = remnant4Momen    
421         G4LorentzVector fourMomentum(scaling *    
422              nuclearMass + kinE);                 
423         if(std::abs(scaling - 1.0) > 0.01) {      
424           std::stringstream ss;                   
425           ss << "momentum scaling = " << scali    
426              << "\n                Lorentz vec    
427              << ")\n                A = " << A    
428              << "\n                E* = " << e    
429              << "\n                remnant i="    
430              << "\n                Reaction wa    
431              << "-MeV " << trackDefinition->Ge    
432              << theIonTable->GetIonName(theNuc    
433              << ", in " << (inverseKinematics     
434           theInterfaceStore->EmitWarning(ss.st    
435         }                                         
436                                                   
437         // Apply the toLabFrame rotation          
438         fourMomentum *= toLabFrame;               
439         spin *= toLabFrame3;                      
440         // Apply the inverse-kinematics boost     
441         if(inverseKinematics) {                   
442           fourMomentum *= *toDirectKinematics;    
443           fourMomentum.setVect(-fourMomentum.v    
444         }                                         
445                                                   
446         fourMomentumOut += fourMomentum;          
447         G4Fragment remnant(A, Z, std::abs(S),     
448         remnant.SetAngularMomentum(spin);         
449         remnant.SetCreatorModelID(secID);         
450         if(dumpRemnantInfo) {                     
451           G4cerr << "G4INCLXX_DUMP_REMNANT: "     
452         }                                         
453         remnants.push_back(remnant);              
454       }                                           
455                                                   
456       // Give up is the event is not ok (e.g.     
457       if(!eventIsOK) {                            
458         const G4int nSecondaries = (G4int)theR    
459         for(G4int j=0; j<nSecondaries; ++j) de    
460         theResult.Clear();                        
461         theResult.SetStatusChange(stopAndKill)    
462         remnants.clear();                         
463       } else {                                    
464         // Check four-momentum conservation       
465         const G4LorentzVector violation4Moment    
466         const G4double energyViolation = std::    
467         const G4double momentumViolation = vio    
468         if(energyViolation > G4INCLXXInterface    
469           std::stringstream ss;                   
470           ss << "energy conservation violated     
471              << aTrack.GetKineticEnergy()/MeV     
472              << " + " << theIonTable->GetIonNa    
473              << " inelastic reaction, in " <<     
474           theInterfaceStore->EmitWarning(ss.st    
475           eventIsOK = false;                      
476           const G4int nSecondaries = (G4int)th    
477           for(G4int j=0; j<nSecondaries; ++j)     
478           theResult.Clear();                      
479           theResult.SetStatusChange(stopAndKil    
480           remnants.clear();                       
481         } else if(momentumViolation > G4INCLXX    
482           std::stringstream ss;                   
483           ss << "momentum conservation violate    
484              << aTrack.GetKineticEnergy()/MeV     
485              << " + " << theIonTable->GetIonNa    
486              << " inelastic reaction, in " <<     
487           theInterfaceStore->EmitWarning(ss.st    
488           eventIsOK = false;                      
489           const G4int nSecondaries = (G4int)th    
490           for(G4int j=0; j<nSecondaries; ++j)     
491           theResult.Clear();                      
492           theResult.SetStatusChange(stopAndKil    
493           remnants.clear();                       
494         }                                         
495       }                                           
496     }                                             
497     nTries++;                                     
498   } while(!eventIsOK && nTries < maxTries); /*    
499                                                   
500   // Clean up the objects that we created for     
501   if(inverseKinematics) {                         
502     delete aProjectileTrack;                      
503     delete theTargetNucleus;                      
504     delete toInverseKinematics;                   
505     delete toDirectKinematics;                    
506   }                                               
507                                                   
508   if(!eventIsOK) {                                
509     std::stringstream ss;                         
510     ss << "maximum number of tries exceeded fo    
511     << aTrack.GetKineticEnergy()/MeV << "-MeV     
512     << " + " << theIonTable->GetIonName(nucleu    
513     << " inelastic reaction, in " << (inverseK    
514     theInterfaceStore->EmitWarning(ss.str());     
515     theResult.SetStatusChange(isAlive);           
516     theResult.SetEnergyChange(aTrack.GetKineti    
517     theResult.SetMomentumChange(aTrack.Get4Mom    
518     return &theResult;                            
519   }                                               
520                                                   
521   // De-excitation:                               
522                                                   
523   if(theDeExcitation != 0) {                      
524     for(std::list<G4Fragment>::iterator i = re    
525   i != remnants.end(); ++i) {                     
526       G4ReactionProductVector *deExcitationRes    
527                                                   
528       for(G4ReactionProductVector::iterator fr    
529     fragment != deExcitationResult->end(); ++f    
530   const G4ParticleDefinition *def = (*fragment    
531   if(def != 0) {                                  
532     G4DynamicParticle *theFragment = new G4Dyn    
533     theResult.AddSecondary(theFragment, (*frag    
534   }                                               
535       }                                           
536                                                   
537       for(G4ReactionProductVector::iterator fr    
538     fragment != deExcitationResult->end(); ++f    
539   delete (*fragment);                             
540       }                                           
541       deExcitationResult->clear();                
542       delete deExcitationResult;                  
543     }                                             
544   }                                               
545                                                   
546   remnants.clear();                               
547                                                   
548   if((theTally = theInterfaceStore->GetTally()    
549     theTally->Tally(aTrack, theNucleus, theRes    
550                                                   
551   return &theResult;                              
552 }                                                 
553                                                   
554 G4ReactionProductVector* G4INCLXXInterface::Pr    
555   return 0;                                       
556 }                                                 
557                                                   
558 G4INCL::ParticleType G4INCLXXInterface::toINCL    
559   if(     pdef == G4Proton::Proton())             
560   else if(pdef == G4Neutron::Neutron())           
561   else if(pdef == G4PionPlus::PionPlus())         
562   else if(pdef == G4PionMinus::PionMinus())       
563   else if(pdef == G4PionZero::PionZero())         
564   else if(pdef == G4KaonPlus::KaonPlus())         
565   else if(pdef == G4KaonZero::KaonZero())         
566   else if(pdef == G4KaonMinus::KaonMinus())       
567   else if(pdef == G4AntiKaonZero::AntiKaonZero    
568   // For K0L & K0S we do not take into account    
569   else if(pdef == G4KaonZeroLong::KaonZeroLong    
570   else if(pdef == G4KaonZeroShort::KaonZeroSho    
571   else if(pdef == G4Deuteron::Deuteron())         
572   else if(pdef == G4Triton::Triton())             
573   else if(pdef == G4He3::He3())                   
574   else if(pdef == G4Alpha::Alpha())               
575   else if(pdef == G4AntiProton::AntiProton())     
576   else if(pdef->GetParticleType() == G4Generic    
577   else                                            
578 }                                                 
579                                                   
580 G4INCL::ParticleSpecies G4INCLXXInterface::toI    
581   const G4ParticleDefinition *pdef = aTrack.Ge    
582   const G4INCL::ParticleType theType = toINCLP    
583   if(theType!=G4INCL::Composite)                  
584     return G4INCL::ParticleSpecies(theType);      
585   else {                                          
586     G4INCL::ParticleSpecies theSpecies;           
587     theSpecies.theType=theType;                   
588     theSpecies.theA=pdef->GetAtomicMass();        
589     theSpecies.theZ=pdef->GetAtomicNumber();      
590     return theSpecies;                            
591   }                                               
592 }                                                 
593                                                   
594 G4double G4INCLXXInterface::toINCLKineticEnerg    
595   return aTrack.GetKineticEnergy();               
596 }                                                 
597                                                   
598 G4ParticleDefinition *G4INCLXXInterface::toG4P    
599   if       (PDGCode == 2212) { return G4Proton    
600   } else if(PDGCode == 2112) { return G4Neutro    
601   } else if(PDGCode == 211)  { return G4PionPl    
602   } else if(PDGCode == 111)  { return G4PionZe    
603   } else if(PDGCode == -211) { return G4PionMi    
604                                                   
605   } else if(PDGCode == 221)  { return G4Eta::E    
606   } else if(PDGCode == 22)   { return G4Gamma:    
607                                                   
608   } else if(PDGCode == 3122) { return G4Lambda    
609   } else if(PDGCode == 3222) { return G4SigmaP    
610   } else if(PDGCode == 3212) { return G4SigmaZ    
611   } else if(PDGCode == 3112) { return G4SigmaM    
612   } else if(PDGCode == 321)  { return G4KaonPl    
613   } else if(PDGCode == -321) { return G4KaonMi    
614   } else if(PDGCode == 130)  { return G4KaonZe    
615   } else if(PDGCode == 310)  { return G4KaonZe    
616                                                   
617   } else if(PDGCode == 1002) { return G4Deuter    
618   } else if(PDGCode == 1003) { return G4Triton    
619   } else if(PDGCode == 2003) { return G4He3::H    
620   } else if(PDGCode == 2004) { return G4Alpha:    
621                                                   
622   } else if(PDGCode == -2212) { return G4AntiP    
623   } else if(S != 0) {  // Assumed that -S give    
624     if (A == 3 && Z == 1 && S == -1 ) return G    
625     if (A == 4 && Z == 1 && S == -1 ) return G    
626     if (A == 4 && Z == 2 && S == -1 ) return G    
627     if (A == 4 && Z == 1 && S == -2 ) return G    
628     if (A == 4 && Z == 0 && S == -2 ) return G    
629     if (A == 5 && Z == 2 && S == -1 ) return G    
630   } else if(A > 0 && Z > 0 && A > Z) { // Retu    
631     return theIonTable->GetIon(Z, A, 0);          
632   }                                               
633   return 0; // Error, unrecognized particle       
634 }                                                 
635                                                   
636 G4DynamicParticle *G4INCLXXInterface::toG4Part    
637                G4double kinE, G4double px,        
638                                                   
639   const G4ParticleDefinition *def = toG4Partic    
640   if(def == 0) { // Check if we have a valid p    
641     return 0;                                     
642   }                                               
643   const G4double energy = kinE * MeV;             
644   const G4ThreeVector momentum(px, py, pz);       
645   const G4ThreeVector momentumDirection = mome    
646   G4DynamicParticle *p = new G4DynamicParticle    
647   return p;                                       
648 }                                                 
649                                                   
650 G4double G4INCLXXInterface::remnant4MomentumSc    
651               G4double kineticE,                  
652               G4double px, G4double py,           
653               G4double pz) const {                
654   const G4double p2 = px*px + py*py + pz*pz;      
655   if(p2 > 0.0) {                                  
656     const G4double pnew2 = kineticE*kineticE +    
657     return std::sqrt(pnew2)/std::sqrt(p2);        
658   } else {                                        
659     return 1.0;                                   
660   }                                               
661 }                                                 
662                                                   
663 void G4INCLXXInterface::ModelDescription(std::    
664    outFile                                        
665      << "The Liège Intranuclear Cascade (INCL    
666      << "by nucleons, pions and light ion on a    
667      << "described as an avalanche of binary n    
668      << "lead to the emission of energetic par    
669      << "excited thermalised nucleus (remnant)    
670      << "outside the scope of INCL++ and is ty    
671      << "INCL++ has been reasonably well teste    
672      << "pion (idem) and light-ion projectiles    
673      << "Most tests involved target nuclei clo    
674      << "numbers between 4 and 250.\n\n"          
675      << "Reference: D. Mancusi et al., Phys. R    
676 }                                                 
677                                                   
678 G4String const &G4INCLXXInterface::GetDeExcita    
679   return theDeExcitation->GetModelName();         
680 }                                                 
681