Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/abrasion/src/G4WilsonAbrasionModel.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/abrasion/src/G4WilsonAbrasionModel.cc (Version 11.3.0) and /processes/hadronic/models/abrasion/src/G4WilsonAbrasionModel.cc (Version 5.2.p2)


  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 // *                                              
 21 // * Parts of this code which have been  devel    
 22 // * under contract to the European Space Agen    
 23 // * intellectual property of ESA. Rights to u    
 24 // * redistribute this software for general pu    
 25 // * in compliance with any licensing, distrib    
 26 // * policy adopted by the Geant4 Collaboratio    
 27 // * written by QinetiQ Ltd for the European S    
 28 // * contract 17191/03/NL/LvH (Aurora Programm    
 29 // *                                              
 30 // * By using,  copying,  modifying or  distri    
 31 // * any work based  on the software)  you  ag    
 32 // * use  in  resulting  scientific  publicati    
 33 // * acceptance of all terms of the Geant4 Sof    
 34 // *******************************************    
 35 //                                                
 36 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
 37 //                                                
 38 // MODULE:              G4WilsonAbrasionModel.    
 39 //                                                
 40 // Version:   1.0                                 
 41 // Date:    08/12/2009                            
 42 // Author:    P R Truscott                        
 43 // Organisation:  QinetiQ Ltd, UK                 
 44 // Customer:    ESA/ESTEC, NOORDWIJK              
 45 // Contract:    17191/03/NL/LvH                   
 46 //                                                
 47 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
 48 //                                                
 49 // CHANGE HISTORY                                 
 50 // --------------                                 
 51 //                                                
 52 // 6 October 2003, P R Truscott, QinetiQ Ltd,     
 53 // Created.                                       
 54 //                                                
 55 // 15 March 2004, P R Truscott, QinetiQ Ltd, U    
 56 // Beta release                                   
 57 //                                                
 58 // 18 January 2005, M H Mendenhall, Vanderbilt    
 59 // Pointers to theAbrasionGeometry and product    
 60 // handler deleted to prevent memory leaks.  A    
 61 // fragment previously not properly defined.      
 62 //                                                
 63 // 08 December 2009, P R Truscott, QinetiQ Ltd    
 64 // ver 1.0                                        
 65 // There was originally a possibility of the m    
 66 // considering Couloumb repulsion, rm, being t    
 67 //     rm >= fradius * (rP + rT)                  
 68 // where fradius is currently 0.99, then it is    
 69 // unchanged.  Additional conditions to escape    
 70 // parameter: if the loop counter evtcnt reach    
 71 // continued.                                     
 72 // Additional clauses have been included in       
 73 //    G4WilsonAbrasionModel::GetNucleonInduced    
 74 // Previously it was possible to get sqrt of n    
 75 // algorithm not properly defined if either:      
 76 //    rT > rP && rsq < rTsq - rPsq) or (rP > r    
 77 //                                                
 78 // 12 June 2012, A. Ribon, CERN, Switzerland      
 79 // Fixing trivial warning errors of shadowed v    
 80 //                                                
 81 // 4 August 2015, A. Ribon, CERN, Switzerland     
 82 // Replacing std::exp and std::pow with the fa    
 83 //                                                
 84 // 7 August 2015, A. Ribon, CERN, Switzerland     
 85 // Checking of 'while' loops.                     
 86 //                                                
 87 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
 88 //////////////////////////////////////////////    
 89                                                   
 90 #include "G4WilsonAbrasionModel.hh"               
 91 #include "G4WilsonRadius.hh"                      
 92 #include "G4NuclearAbrasionGeometry.hh"           
 93 #include "G4WilsonAblationModel.hh"               
 94                                                   
 95 #include "G4PhysicalConstants.hh"                 
 96 #include "G4SystemOfUnits.hh"                     
 97 #include "G4ExcitationHandler.hh"                 
 98 #include "G4Evaporation.hh"                       
 99 #include "G4ParticleDefinition.hh"                
100 #include "G4DynamicParticle.hh"                   
101 #include "Randomize.hh"                           
102 #include "G4Fragment.hh"                          
103 #include "G4ReactionProductVector.hh"             
104 #include "G4LorentzVector.hh"                     
105 #include "G4ParticleMomentum.hh"                  
106 #include "G4Poisson.hh"                           
107 #include "G4ParticleTable.hh"                     
108 #include "G4IonTable.hh"                          
109 #include "globals.hh"                             
110                                                   
111 #include "G4Exp.hh"                               
112 #include "G4Pow.hh"                               
113                                                   
114 #include "G4PhysicsModelCatalog.hh"               
115                                                   
116                                                   
117 G4WilsonAbrasionModel::G4WilsonAbrasionModel(G    
118   : G4HadronicInteraction("G4WilsonAbrasion"),    
119 {                                                 
120   // Send message to stdout to advise that the    
121   PrintWelcomeMessage();                          
122                                                   
123   // Set the default verbose level to 0 - no o    
124   verboseLevel = 0;                               
125   useAblation  = useAblation1;                    
126   theAblation  = nullptr;                         
127                                                   
128   // No de-excitation handler has been supplie    
129                                                   
130   theExcitationHandler = new G4ExcitationHandl    
131   if (useAblation)                                
132   {                                               
133     theAblation = new G4WilsonAblationModel;      
134     theAblation->SetVerboseLevel(verboseLevel)    
135     theExcitationHandler->SetEvaporation(theAb    
136   }                                               
137                                                   
138   // Set the minimum and maximum range for the    
139   // this is in energy per nucleon number).       
140                                                   
141   SetMinEnergy(70.0*MeV);                         
142   SetMaxEnergy(10.1*GeV);                         
143   isBlocked = false;                              
144                                                   
145   // npK, when mutiplied by the nuclear Fermi     
146   // momentum over which the secondary nucleon    
147                                                   
148   r0sq = 0.0;                                     
149   npK = 5.0;                                      
150   B = 10.0 * MeV;                                 
151   third = 1.0 / 3.0;                              
152   fradius = 0.99;                                 
153   conserveEnergy = false;                         
154   conserveMomentum = true;                        
155                                                   
156   // Creator model ID for the secondaries crea    
157   secID = G4PhysicsModelCatalog::GetModelID( "    
158 }                                                 
159                                                   
160 void G4WilsonAbrasionModel::ModelDescription(s    
161 {                                                 
162   outFile << "G4WilsonAbrasionModel is a macro    
163           << "nucleus-nucleus collisions using    
164           << "The smaller projectile nucleus g    
165           << "target nucleus, leaving a residu    
166           << "region where the projectile and     
167           << "is then treated as a highly exci    
168           << "model is based on the NUCFRG2 mo    
169           << "projectile energies between 70 M    
170 }                                                 
171                                                   
172 G4WilsonAbrasionModel::G4WilsonAbrasionModel(G    
173  G4HadronicInteraction("G4WilsonAbrasion"), se    
174 {                                                 
175 // Send message to stdout to advise that the G    
176                                                   
177   PrintWelcomeMessage();                          
178                                                   
179 // Set the default verbose level to 0 - no out    
180                                                   
181   verboseLevel = 0;                               
182                                                   
183   theAblation = nullptr;   //A.R. 26-Jul-2012     
184   useAblation = false;     //A.R. 14-Aug-2012     
185                                                   
186 //                                                
187 // The user is able to provide the excitation     
188 // which is provided in this instantiation is     
189 // whether the spectators of the interaction a    
190 //                                                
191   theExcitationHandler = aExcitationHandler;      
192 //                                                
193 //                                                
194 // Set the minimum and maximum range for the m    
195 // is in energy per nucleon number).              
196 //                                                
197   SetMinEnergy(70.0*MeV);                         
198   SetMaxEnergy(10.1*GeV);                         
199   isBlocked = false;                              
200 //                                                
201 //                                                
202 // npK, when mutiplied by the nuclear Fermi mo    
203 // momentum over which the secondary nucleon m    
204 //                                                
205   r0sq             = 0.0;                         
206   npK              = 5.0;                         
207   B                = 10.0 * MeV;                  
208   third            = 1.0 / 3.0;                   
209   fradius          = 0.99;                        
210   conserveEnergy   = false;                       
211   conserveMomentum = true;                        
212                                                   
213   // Creator model ID for the secondaries crea    
214   secID = G4PhysicsModelCatalog::GetModelID( "    
215 }                                                 
216 //////////////////////////////////////////////    
217 //                                                
218 G4WilsonAbrasionModel::~G4WilsonAbrasionModel(    
219 {                                                 
220   delete theExcitationHandler;                    
221 }                                                 
222 //////////////////////////////////////////////    
223 //                                                
224 G4HadFinalState *G4WilsonAbrasionModel::ApplyY    
225   const G4HadProjectile &theTrack, G4Nucleus &    
226 {                                                 
227 //                                                
228 //                                                
229 // The secondaries will be returned in G4HadFi    
230 // initialise this.  The original track will a    
231 // secondaries followed.                          
232 //                                                
233   theParticleChange.Clear();                      
234   theParticleChange.SetStatusChange(stopAndKil    
235 //                                                
236 //                                                
237 // Get relevant information about the projecti    
238 // momentum, etc).                                
239 //                                                
240   const G4ParticleDefinition *definitionP = th    
241   const G4double AP  = definitionP->GetBaryonN    
242   const G4double ZP  = definitionP->GetPDGChar    
243   G4LorentzVector pP = theTrack.Get4Momentum()    
244   G4double E         = theTrack.GetKineticEner    
245   G4double AT        = theTarget.GetA_asInt();    
246   G4double ZT        = theTarget.GetZ_asInt();    
247   G4double TotalEPre = theTrack.GetTotalEnergy    
248     theTarget.AtomicMass(AT, ZT) + theTarget.G    
249   G4double TotalEPost = 0.0;                      
250 //                                                
251 //                                                
252 // Determine the radii of the projectile and t    
253 //                                                
254   G4WilsonRadius aR;                              
255   G4double rP   = aR.GetWilsonRadius(AP);         
256   G4double rT   = aR.GetWilsonRadius(AT);         
257   G4double rPsq = rP * rP;                        
258   G4double rTsq = rT * rT;                        
259   if (verboseLevel >= 2)                          
260   {                                               
261     G4cout <<"################################    
262            <<"################################    
263            <<G4endl;                              
264     G4cout.precision(6);                          
265     G4cout <<"IN G4WilsonAbrasionModel" <<G4en    
266     G4cout <<"Initial projectile A=" <<AP         
267            <<", Z=" <<ZP                          
268            <<", radius = " <<rP/fermi <<" fm"     
269            <<G4endl;                              
270     G4cout <<"Initial target     A=" <<AT         
271            <<", Z=" <<ZT                          
272            <<", radius = " <<rT/fermi <<" fm"     
273            <<G4endl;                              
274     G4cout <<"Projectile momentum and Energy/n    
275   }                                               
276 //                                                
277 //                                                
278 // The following variables are used to determi    
279 // near-field (i.e. taking into consideration     
280 //                                                
281   G4double rm   = ZP * ZT * elm_coupling / (E     
282   G4double r    = 0.0;                            
283   G4double rsq  = 0.0;                            
284 //                                                
285 //                                                
286 // Initialise some of the variables which wll     
287 // length for nucleons in the projectile and t    
288 // number of abraded nucleons and the excitati    
289 //                                                
290   G4NuclearAbrasionGeometry *theAbrasionGeomet    
291   G4double CT   = 0.0;                            
292   G4double F    = 0.0;                            
293   G4int Dabr    = 0;                              
294 //                                                
295 //                                                
296 // The following loop is performed until the n    
297 // abraded by the process is >1, i.e. an inter    
298 //                                                
299   G4bool skipInteraction = false;  // It will     
300   const G4int maxNumberOfLoops = 1000;            
301   G4int loopCounter = -1;                         
302   while (Dabr == 0 && ++loopCounter < maxNumbe    
303   {                                               
304 //                                                
305 //                                                
306 // Sample the impact parameter.  For the momen    
307 // electrostatic effects on the impact paramet    
308 // does not make any correction for the effect    
309 //                                                
310     G4double rPT   = rP + rT;                     
311     G4double rPTsq = rPT * rPT;                   
312 //                                                
313 //                                                
314 // This is a "catch" to make sure we don't go     
315 // energy is too low to overcome nuclear repul    
316 // value of rm < fradius * rPT then we're unli    
317 // impact parameter (energy of incident partic    
318 //                                                
319     if (rm >= fradius * rPT) {                    
320       skipInteraction = true;                     
321     }                                             
322 //                                                
323 //                                                
324 // Now sample impact parameter until the crite    
325 // and target overlap, but repulsion is taken     
326 //                                                
327     G4int evtcnt   = 0;                           
328     r              = 1.1 * rPT;                   
329     while (r > rPT && ++evtcnt < 1000)  /* Loo    
330     {                                             
331       G4double bsq = rPTsq * G4UniformRand();     
332       r            = (rm + std::sqrt(rm*rm + 4    
333     }                                             
334 //                                                
335 //                                                
336 // We've tried to sample this 1000 times, but     
337 //                                                
338     if (evtcnt >= 1000) {                         
339       skipInteraction = true;                     
340     }                                             
341                                                   
342     rsq = r * r;                                  
343 //                                                
344 //                                                
345 // Now determine the chord-length through the     
346 //                                                
347     if (rT > rP)                                  
348     {                                             
349       G4double x = (rPsq + rsq - rTsq) / 2.0 /    
350       if (x > 0.0) CT = 2.0 * std::sqrt(rTsq -    
351       else         CT = 2.0 * std::sqrt(rTsq -    
352     }                                             
353     else                                          
354     {                                             
355       G4double x = (rTsq + rsq - rPsq) / 2.0 /    
356       if (x > 0.0) CT = 2.0 * std::sqrt(rTsq -    
357       else         CT = 2.0 * rT;                 
358     }                                             
359 //                                                
360 //                                                
361 // Determine the number of abraded nucleons.      
362 // abraded nucleons is used to sample the Pois    
363 // distribution is sampled only ten times with    
364 // and if it fails after this to find a case f    
365 // nucleons >1, the impact parameter is re-sam    
366 //                                                
367     delete theAbrasionGeometry;                   
368     theAbrasionGeometry = new G4NuclearAbrasio    
369     F                   = theAbrasionGeometry-    
370     G4double lambda     = 16.6*fermi / G4Pow::    
371     G4double Mabr       = F * AP * (1.0 - G4Ex    
372     G4long n            = 0;                      
373     for (G4int i = 0; i<10; ++i)                  
374     {                                             
375       n = G4Poisson(Mabr);                        
376       if (n > 0)                                  
377       {                                           
378         if (n>AP) Dabr = (G4int) AP;              
379         else      Dabr = (G4int) n;               
380         break;                                    
381       }                                           
382     }                                             
383   }  // End of while loop                         
384                                                   
385   if ( loopCounter >= maxNumberOfLoops || skip    
386     // Assume nuclei do not collide and return    
387     theParticleChange.SetStatusChange(isAlive)    
388     theParticleChange.SetEnergyChange(theTrack    
389     theParticleChange.SetMomentumChange(theTra    
390     if (verboseLevel >= 2) {                      
391       G4cout <<"Particle energy too low to ove    
392       G4cout <<"Event rejected and original tr    
393       G4cout <<"##############################    
394              <<"##############################    
395              <<G4endl;                            
396     }                                             
397     delete theAbrasionGeometry;                   
398     return &theParticleChange;                    
399   }                                               
400                                                   
401   if (verboseLevel >= 2)                          
402   {                                               
403     G4cout <<G4endl;                              
404     G4cout <<"Impact parameter    = " <<r/ferm    
405     G4cout <<"# Abraded nucleons  = " <<Dabr <    
406   }                                               
407 //                                                
408 //                                                
409 // The number of abraded nucleons must be no g    
410 // nucleons in either the projectile or the ta    
411 // AT - Dabr < 2 then either we have only a nu    
412 // projectile/target or we've tried to abrade     
413 // should be limited.                             
414 //                                                
415   if (AP - (G4double) Dabr < 2.0) Dabr = (G4in    
416   if (AT - (G4double) Dabr < 2.0) Dabr = (G4in    
417 //                                                
418 //                                                
419 // Determine the abraded secondary nucleons fr    
420 // is a pointer to the prefragment from the pr    
421 // of nucleons in theParticleChange which have    
422 // from these is determined.                      
423 //                                                
424   G4ThreeVector boost   = pP.findBoostToCM();     
425   G4Fragment *fragmentP = GetAbradedNucleons (    
426   G4int nSecP           = (G4int)theParticleCh    
427   G4int i               = 0;                      
428   for (i=0; i<nSecP; ++i)                         
429   {                                               
430     TotalEPost += theParticleChange.GetSeconda    
431       GetParticle()->GetTotalEnergy();            
432   }                                               
433 //                                                
434 //                                                
435 // Determine the number of spectators in the i    
436 // projectile.                                    
437 //                                                
438   G4int DspcP = (G4int) (AP*F) - Dabr;            
439   if (DspcP <= 0)           DspcP = 0;            
440   else if (DspcP > AP-Dabr) DspcP = ((G4int) A    
441 //                                                
442 //                                                
443 // Determine excitation energy associated with    
444 // projectile (EsP) and the excitation due to     
445 // retained within the projectile (ExP).  Add     
446 // nucleus to the total energy of the secondar    
447 //                                                
448   G4bool excitationAbsorbedByProjectile = fals    
449   if (fragmentP != nullptr)                       
450   {                                               
451     G4double EsP = theAbrasionGeometry->GetExc    
452     G4double ExP = 0.0;                           
453     if (Dabr < AT)                                
454       excitationAbsorbedByProjectile = G4Unifo    
455     if (excitationAbsorbedByProjectile)           
456       ExP = GetNucleonInducedExcitation(rP, rT    
457     G4double xP = EsP + ExP;                      
458     if (xP > B*(AP-Dabr)) xP = B*(AP-Dabr);       
459     G4LorentzVector lorentzVector = fragmentP-    
460     lorentzVector.setE(lorentzVector.e()+xP);     
461     fragmentP->SetMomentum(lorentzVector);        
462     TotalEPost += lorentzVector.e();              
463   }                                               
464   G4double EMassP = TotalEPost;                   
465 //                                                
466 //                                                
467 // Determine the abraded secondary nucleons fr    
468 // assumed that the same number of nucleons ar    
469 // the projectile, and obviously no boost is a    
470 // is a pointer to the prefragment from the ta    
471 // of nucleons in theParticleChange which have    
472 // from these is determined.                      
473 //                                                
474   G4Fragment *fragmentT = GetAbradedNucleons (    
475   G4int nSec = (G4int)theParticleChange.GetNum    
476   for (i=nSecP; i<nSec; ++i)                      
477   {                                               
478     TotalEPost += theParticleChange.GetSeconda    
479       GetParticle()->GetTotalEnergy();            
480   }                                               
481 //                                                
482 //                                                
483 // Determine the number of spectators in the i    
484 // target.                                        
485 //                                                
486   G4int DspcT = (G4int) (AT*F) - Dabr;            
487   if (DspcT <= 0)           DspcT = 0;            
488   else if (DspcT > AP-Dabr) DspcT = ((G4int) A    
489 //                                                
490 //                                                
491 // Determine excitation energy associated with    
492 // target (EsT) and the excitation due to scat    
493 // retained within the target (ExT).  Add the     
494 // nucleus to the total energy of the secondar    
495 //                                                
496   if (fragmentT != nullptr)                       
497   {                                               
498     G4double EsT = theAbrasionGeometry->GetExc    
499     G4double ExT = 0.0;                           
500     if (!excitationAbsorbedByProjectile)          
501       ExT = GetNucleonInducedExcitation(rT, rP    
502     G4double xT = EsT + ExT;                      
503     if (xT > B*(AT-Dabr)) xT = B*(AT-Dabr);       
504     G4LorentzVector lorentzVector = fragmentT-    
505     lorentzVector.setE(lorentzVector.e()+xT);     
506     fragmentT->SetMomentum(lorentzVector);        
507     TotalEPost += lorentzVector.e();              
508   }                                               
509 //                                                
510 //                                                
511 // Now determine the difference between the pr    
512 // energy - this will be used to determine the    
513 // of energy is to be imposed/attempted.          
514 //                                                
515   G4double deltaE = TotalEPre - TotalEPost;       
516   if (deltaE > 0.0 && conserveEnergy)             
517   {                                               
518     G4double beta = std::sqrt(1.0 - EMassP*EMa    
519     boost = boost / boost.mag() * beta;           
520   }                                               
521 //                                                
522 //                                                
523 // Now boost the secondaries from the projecti    
524 //                                                
525   G4ThreeVector pBalance = pP.vect();             
526   for (i=0; i<nSecP; ++i)                         
527   {                                               
528     G4DynamicParticle *dynamicP = theParticleC    
529       GetParticle();                              
530     G4LorentzVector lorentzVector = dynamicP->    
531     lorentzVector.boost(-boost);                  
532     dynamicP->Set4Momentum(lorentzVector);        
533     pBalance -= lorentzVector.vect();             
534   }                                               
535 //                                                
536 //                                                
537 // Set the boost for the projectile prefragmen    
538 // conservation of momentum.  However, if the     
539 // prefragment is not to be conserved this sim    
540 // original projectile times the ratio of the     
541 // of the prefragment (the excitation increase    
542 // prefragment, and therefore modifying the bo    
543 // the momentum of the prefragment being exces    
544 //                                                
545   if (fragmentP != nullptr)                       
546   {                                               
547     G4LorentzVector lorentzVector = fragmentP-    
548     G4double fragmentM            = lorentzVec    
549     if (conserveMomentum)                         
550       fragmentP->SetMomentum                      
551         (G4LorentzVector(pBalance,std::sqrt(pB    
552     else                                          
553     {                                             
554       G4double fragmentGroundStateM = fragment    
555       fragmentP->SetMomentum(lorentzVector.boo    
556     }                                             
557   }                                               
558 //                                                
559 //                                                
560 // Output information to user if verbose infor    
561 //                                                
562   if (verboseLevel >= 2)                          
563   {                                               
564     G4cout <<G4endl;                              
565     G4cout <<"--------------------------------    
566     G4cout <<"Secondary nucleons from projecti    
567     G4cout <<"--------------------------------    
568     G4cout.precision(7);                          
569     for (i=0; i<nSecP; ++i)                       
570     {                                             
571       G4cout <<"Particle # " <<i <<G4endl;        
572       theParticleChange.GetSecondary(i)->GetPa    
573       G4DynamicParticle *dyn = theParticleChan    
574       G4cout <<"New nucleon (P) " <<dyn->GetDe    
575              <<" : "              <<dyn->Get4M    
576              <<G4endl;                            
577     }                                             
578     G4cout <<"---------------------------" <<G    
579     G4cout <<"The projectile prefragment:" <<G    
580     G4cout <<"---------------------------" <<G    
581     if (fragmentP != nullptr)                     
582       G4cout <<*fragmentP <<G4endl;               
583     else                                          
584       G4cout <<"(No residual prefragment)" <<G    
585     G4cout <<G4endl;                              
586     G4cout <<"-------------------------------"    
587     G4cout <<"Secondary nucleons from target:"    
588     G4cout <<"-------------------------------"    
589     G4cout.precision(7);                          
590     for (i=nSecP; i<nSec; ++i)                    
591     {                                             
592       G4cout <<"Particle # " <<i <<G4endl;        
593       theParticleChange.GetSecondary(i)->GetPa    
594       G4DynamicParticle *dyn = theParticleChan    
595       G4cout <<"New nucleon (T) " <<dyn->GetDe    
596              <<" : "              <<dyn->Get4M    
597              <<G4endl;                            
598     }                                             
599     G4cout <<"-----------------------" <<G4end    
600     G4cout <<"The target prefragment:" <<G4end    
601     G4cout <<"-----------------------" <<G4end    
602     if (fragmentT != nullptr)                     
603       G4cout <<*fragmentT <<G4endl;               
604     else                                          
605       G4cout <<"(No residual prefragment)" <<G    
606   }                                               
607 //                                                
608 //                                                
609 // Now we can decay the nuclear fragments if p    
610 // collected and boosted as well.  This is per    
611 //                                                
612   if (fragmentP !=nullptr)                        
613   {                                               
614     G4ReactionProductVector *products = nullpt    
615     //    if (fragmentP->GetZ_asInt() != fragm    
616     products = theExcitationHandler->BreakItUp    
617     // else                                       
618     //   products = theExcitationHandlerx->Bre    
619     delete fragmentP;                             
620     fragmentP = nullptr;                          
621                                                   
622     G4ReactionProductVector::iterator iter;       
623     for (iter = products->begin(); iter != pro    
624     {                                             
625       G4DynamicParticle *secondary =              
626         new G4DynamicParticle((*iter)->GetDefi    
627         (*iter)->GetTotalEnergy(), (*iter)->Ge    
628       theParticleChange.AddSecondary (secondar    
629       G4String particleName = (*iter)->GetDefi    
630       delete (*iter); // get rid of leftover p    
631       if (verboseLevel >= 2 && particleName.fi    
632       {                                           
633         G4cout <<"------------------------" <<    
634         G4cout <<"The projectile fragment:" <<    
635         G4cout <<"------------------------" <<    
636         G4cout <<" fragmentP = " <<particleNam    
637                <<" Energy    = " <<secondary->    
638                <<G4endl;                          
639       }                                           
640     }                                             
641     delete products;                              
642   }                                               
643 //                                                
644 //                                                
645 // Now decay the target nucleus - no boost is     
646 // approximation it is assumed that there is n    
647 // the projectile.                                
648 //                                                
649   if (fragmentT != nullptr)                       
650   {                                               
651     G4ReactionProductVector *products = nullpt    
652     //    if (fragmentT->GetZ_asInt() != fragm    
653       products = theExcitationHandler->BreakIt    
654     // else                                       
655     //   products = theExcitationHandlerx->Bre    
656     // delete fragmentT;                          
657     fragmentT = nullptr;                          
658                                                   
659     G4ReactionProductVector::iterator iter;       
660     for (iter = products->begin(); iter != pro    
661     {                                             
662       G4DynamicParticle *secondary =              
663         new G4DynamicParticle((*iter)->GetDefi    
664         (*iter)->GetTotalEnergy(), (*iter)->Ge    
665       theParticleChange.AddSecondary (secondar    
666       G4String particleName = (*iter)->GetDefi    
667       delete (*iter); // get rid of leftover p    
668       if (verboseLevel >= 2 && particleName.fi    
669       {                                           
670         G4cout <<"--------------------" <<G4en    
671         G4cout <<"The target fragment:" <<G4en    
672         G4cout <<"--------------------" <<G4en    
673         G4cout <<" fragmentT = " <<particleNam    
674                <<" Energy    = " <<secondary->    
675                <<G4endl;                          
676       }                                           
677     }                                             
678     delete products;                              
679   }                                               
680                                                   
681   if (verboseLevel >= 2)                          
682      G4cout <<"###############################    
683             <<"###############################    
684             <<G4endl;                             
685                                                   
686   delete theAbrasionGeometry;                     
687   return &theParticleChange;                      
688 }                                                 
689 //////////////////////////////////////////////    
690 //                                                
691 G4Fragment *G4WilsonAbrasionModel::GetAbradedN    
692   G4double Z, G4double r)                         
693 {                                                 
694 //                                                
695 //                                                
696 // Initialise variables.  tau is the Fermi rad    
697 // p..., C... and gamma are used to help sampl    
698 // spectrum.                                      
699 //                                                
700                                                   
701   G4double pK   = hbarc * G4Pow::GetInstance()    
702   if (A <= 24.0) pK *= -0.229*G4Pow::GetInstan    
703   G4double pKsq = pK * pK;                        
704   G4double p1sq = 2.0/5.0 * pKsq;                 
705   G4double p2sq = 6.0/5.0 * pKsq;                 
706   G4double p3sq = 500.0 * 500.0;                  
707   G4double C1   = 1.0;                            
708   G4double C2   = 0.03;                           
709   G4double C3   = 0.0002;                         
710   G4double gamma = 90.0 * MeV;                    
711   G4double maxn = C1 + C2 + C3;                   
712 //                                                
713 //                                                
714 // initialise the number of secondary nucleons    
715 // the type of nucleon abraded to proton ... j    
716 //                                                
717   G4double Aabr                     = 0.0;        
718   G4double Zabr                     = 0.0;        
719   G4ParticleDefinition *typeNucleon = G4Proton    
720   G4DynamicParticle *dynamicNucleon = nullptr;    
721   G4ParticleMomentum pabr(0.0, 0.0, 0.0);         
722 //                                                
723 //                                                
724 // Now go through each abraded nucleon and sam    
725 //                                                
726   G4bool isForLoopExitAnticipated = false;        
727   for (G4int i=0; i<Dabr; ++i)                    
728   {                                               
729 //                                                
730 //                                                
731 // Sample the nucleon momentum distribution by    
732 // reject values of p == 0.0 since this causes    
733 //                                                
734     G4double p   = 0.0;                           
735     G4bool found = false;                         
736     const G4int maxNumberOfLoops = 100000;        
737     G4int loopCounter = -1;                       
738     while (!found && ++loopCounter < maxNumber    
739     {                                             
740       while (p <= 0.0) p = npK * pK * G4Unifor    
741       G4double psq = p * p;                       
742       found = maxn * G4UniformRand() < C1*G4Ex    
743         C2*G4Exp(-psq/p2sq/2.0) + C3*G4Exp(-ps    
744     }                                             
745     if ( loopCounter >= maxNumberOfLoops )        
746     {                                             
747       isForLoopExitAnticipated = true;            
748       break;                                      
749     }                                             
750 //                                                
751 //                                                
752 // Determine the type of particle abraded.  Ca    
753 // and the probability is determine to be prop    
754 // in the nucleus at each stage.                  
755 //                                                
756     G4double prob = (Z-Zabr)/(A-Aabr);            
757     if (G4UniformRand()<prob)                     
758     {                                             
759       Zabr++;                                     
760       typeNucleon = G4Proton::ProtonDefinition    
761     }                                             
762     else                                          
763       typeNucleon = G4Neutron::NeutronDefiniti    
764     Aabr++;                                       
765 //                                                
766 //                                                
767 // The angular distribution of the secondary n    
768 // isotropic distribution in the rest frame of    
769 // boosted later.                                 
770 //                                                
771     G4double costheta = 2.*G4UniformRand()-1.0    
772     G4double sintheta = std::sqrt((1.0 - costh    
773     G4double phi      = 2.0*pi*G4UniformRand()    
774     G4ThreeVector direction(sintheta*std::cos(    
775     G4double nucleonMass = typeNucleon->GetPDG    
776     G4double E           = std::sqrt(p*p + nuc    
777     dynamicNucleon = new G4DynamicParticle(typ    
778     theParticleChange.AddSecondary (dynamicNuc    
779     pabr += p*direction;                          
780   }                                               
781 //                                                
782 //                                                
783 // Next determine the details of the nuclear p    
784 // is one or more protons in the residue.  (No    
785 // energy is a safety factor to avoid any poss    
786 // energy.)                                       
787 //                                                
788   G4Fragment *fragment = nullptr;                 
789   if ( ! isForLoopExitAnticipated && Z-Zabr>=1    
790   {                                               
791     G4double ionMass = G4ParticleTable::GetPar    
792                        GetIonMass(G4lrint(Z-Za    
793     G4double E       = std::sqrt(pabr.mag2() +    
794     G4LorentzVector lorentzVector = G4LorentzV    
795     fragment =                                    
796       new G4Fragment((G4int) (A-Aabr), (G4int)    
797   }                                               
798                                                   
799   return fragment;                                
800 }                                                 
801 //////////////////////////////////////////////    
802 //                                                
803 G4double G4WilsonAbrasionModel::GetNucleonIndu    
804   (G4double rP, G4double rT, G4double r)          
805 {                                                 
806 //                                                
807 //                                                
808 // Initialise variables.                          
809 //                                                
810   G4double Cl   = 0.0;                            
811   G4double rPsq = rP * rP;                        
812   G4double rTsq = rT * rT;                        
813   G4double rsq  = r * r;                          
814 //                                                
815 //                                                
816 // Depending upon the impact parameter, a diff    
817 // is used.                                       
818 //                                                
819   if (r > rT) Cl = 2.0*std::sqrt(rPsq + 2.0*r*    
820   else        Cl = 2.0*rP;                        
821 //                                                
822 //                                                
823 // The next lines have been changed to include    
824 // projectile and target are too close, Ct is     
825 // Otherwise the standard Wilson algorithm sho    
826 // PRT 20091023.                                  
827 //                                                
828   G4double Ct = 0.0;                              
829   if      (rT > rP && rsq < rTsq - rPsq) Ct =     
830   else if (rP > rT && rsq < rPsq - rTsq) Ct =     
831   else {                                          
832     G4double bP = (rPsq+rsq-rTsq)/2.0/r;          
833     G4double x  = rPsq - bP*bP;                   
834     if (x < 0.0) {                                
835       G4cerr <<"##############################    
836              <<"##############################    
837              <<G4endl;                            
838       G4cerr <<"ERROR IN G4WilsonAbrasionModel    
839              <<G4endl;                            
840       G4cerr <<"rPsq - bP*bP < 0.0 and cannot     
841       G4cerr <<"Set to zero instead" <<G4endl;    
842       G4cerr <<"##############################    
843              <<"##############################    
844              <<G4endl;                            
845     }                                             
846     Ct = 2.0*std::sqrt(x);                        
847   }                                               
848                                                   
849   G4double Ex = 13.0 * Cl / fermi;                
850   if (Ct > 1.5*fermi)                             
851     Ex += 13.0 * Cl / fermi /3.0 * (Ct/fermi -    
852                                                   
853   return Ex;                                      
854 }                                                 
855 //////////////////////////////////////////////    
856 //                                                
857 void G4WilsonAbrasionModel::SetUseAblation (G4    
858 {                                                 
859   if (useAblation != useAblation1)                
860   {                                               
861     useAblation = useAblation1;                   
862     if (useAblation)                              
863     {                                             
864       theAblation = new G4WilsonAblationModel;    
865       theAblation->SetVerboseLevel(verboseLeve    
866       theExcitationHandler->SetEvaporation(the    
867     }                                             
868     else                                          
869     {                                             
870       delete theExcitationHandler;                
871       theAblation                      = nullp    
872       theExcitationHandler  = new G4Excitation    
873     }                                             
874   }                                               
875   return;                                         
876 }                                                 
877 //////////////////////////////////////////////    
878 //                                                
879 void G4WilsonAbrasionModel::PrintWelcomeMessag    
880 {                                                 
881   G4cout <<G4endl;                                
882   G4cout <<" *********************************    
883          <<G4endl;                                
884   G4cout <<" Nuclear abrasion model for nuclea    
885          <<G4endl;                                
886   G4cout <<" (Written by QinetiQ Ltd for the E    
887          <<G4endl;                                
888   G4cout <<" *********************************    
889          <<G4endl;                                
890   G4cout << G4endl;                               
891                                                   
892   return;                                         
893 }                                                 
894 //////////////////////////////////////////////    
895 //                                                
896