Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/util/src/G4Fancy3DNucleus.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/util/src/G4Fancy3DNucleus.cc (Version 11.3.0) and /processes/hadronic/util/src/G4Fancy3DNucleus.cc (Version 6.2.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 // -------------------------------------------    
 27 //      GEANT 4 class implementation file         
 28 //                                                
 29 //      ---------------- G4Fancy3DNucleus ----    
 30 //             by Gunter Folger, May 1998.        
 31 //       class for a 3D nucleus, arranging nuc    
 32 // -------------------------------------------    
 33 // 20110805  M. Kelsey -- Remove C-style array    
 34 //    make vector a container of objects.  Mov    
 35 //    to .hh.  Move testSums, places, momentum    
 36 //    class data members for reuse.               
 37                                                   
 38 #include <algorithm>                              
 39                                                   
 40 #include "G4Fancy3DNucleus.hh"                    
 41 #include "G4Fancy3DNucleusHelper.hh"              
 42 #include "G4NuclearFermiDensity.hh"               
 43 #include "G4NuclearShellModelDensity.hh"          
 44 #include "G4NucleiProperties.hh"                  
 45 #include "G4HyperNucleiProperties.hh"             
 46 #include "G4Nucleon.hh"                           
 47 #include "G4SystemOfUnits.hh"                     
 48 #include "Randomize.hh"                           
 49 #include "G4ios.hh"                               
 50 #include "G4Pow.hh"                               
 51 #include "G4HadronicException.hh"                 
 52                                                   
 53 #include "Randomize.hh"                           
 54 #include "G4ThreeVector.hh"                       
 55 #include "G4RandomDirection.hh"                   
 56 #include "G4LorentzRotation.hh"                   
 57 #include "G4RotationMatrix.hh"                    
 58 #include "G4PhysicalConstants.hh"                 
 59                                                   
 60 G4Fancy3DNucleus::G4Fancy3DNucleus()              
 61   : myA(0), myZ(0), myL(0), theNucleons(250),     
 62     nucleondistance(0.8*fermi),excitationEnerg    
 63     places(250), momentum(250), fermiM(250), t    
 64 {                                                 
 65 }                                                 
 66                                                   
 67 G4Fancy3DNucleus::~G4Fancy3DNucleus()             
 68 {                                                 
 69   if(theDensity) delete theDensity;               
 70 }                                                 
 71                                                   
 72 #if defined(NON_INTEGER_A_Z)                      
 73 void G4Fancy3DNucleus::Init(G4double theA, G4d    
 74 {                                                 
 75   G4int intZ = G4int(theZ);                       
 76   G4int intA= ( G4UniformRand()>theA-G4int(the    
 77    // forward to integer Init()                   
 78   Init(intA, intZ, std::max(numberOfLambdas, 0    
 79                                                   
 80 }                                                 
 81 #endif                                            
 82                                                   
 83 void G4Fancy3DNucleus::Init(G4int theA, G4int     
 84 {                                                 
 85   currentNucleon=-1;                              
 86   theNucleons.clear();                            
 87   nucleondistance = 0.8*fermi;                    
 88   places.clear();                                 
 89   momentum.clear();                               
 90   fermiM.clear();                                 
 91   testSums.clear();                               
 92                                                   
 93   myZ = theZ;                                     
 94   myA = theA;                                     
 95   myL = std::max(numberOfLambdas, 0);  // Cann    
 96   excitationEnergy=0;                             
 97                                                   
 98   theNucleons.resize(myA);  // Pre-loads vecto    
 99                                                   
100   // For simplicity, we neglect eventual Lambd    
101   // density of nucler levels and the Fermi le    
102                                                   
103   if(theDensity) delete theDensity;               
104   if ( myA < 17 ) {                               
105      theDensity = new G4NuclearShellModelDensi    
106      if( myA == 12 ) nucleondistance=0.9*fermi    
107   } else {                                        
108      theDensity = new G4NuclearFermiDensity(my    
109   }                                               
110                                                   
111   theFermi.Init(myA, myZ);                        
112                                                   
113   ChooseNucleons();                               
114                                                   
115   ChoosePositions();                              
116                                                   
117   if( myA == 12 ) CenterNucleons();   // This     
118                                                   
119   ChooseFermiMomenta();                           
120                                                   
121   G4double Ebinding= BindingEnergy()/myA;         
122                                                   
123   for (G4int aNucleon=0; aNucleon < myA; aNucl    
124   {                                               
125   theNucleons[aNucleon].SetBindingEnergy(Ebind    
126   }                                               
127                                                   
128   return;                                         
129 }                                                 
130                                                   
131 G4bool G4Fancy3DNucleus::StartLoop()              
132 {                                                 
133   currentNucleon=0;                               
134   return (theNucleons.size()>0);                  
135 }                                                 
136                                                   
137 // Returns by pointer; null pointer indicates     
138 G4Nucleon * G4Fancy3DNucleus::GetNextNucleon()    
139 {                                                 
140   return ( (currentNucleon>=0 && currentNucleo    
141      &theNucleons[currentNucleon++] : 0 );        
142 }                                                 
143                                                   
144 const std::vector<G4Nucleon> & G4Fancy3DNucleu    
145 {                                                 
146   return theNucleons;                             
147 }                                                 
148                                                   
149                                                   
150 // Class-scope function to sort nucleons by Z     
151 bool G4Fancy3DNucleusHelperForSortInZ(const G4    
152 {                                                 
153   return nuc1.GetPosition().z() < nuc2.GetPosi    
154 }                                                 
155                                                   
156 void G4Fancy3DNucleus::SortNucleonsIncZ()         
157 {                                                 
158   if (theNucleons.size() < 2 ) return;    // A    
159                                                   
160   std::sort(theNucleons.begin(), theNucleons.e    
161       G4Fancy3DNucleusHelperForSortInZ);          
162 }                                                 
163                                                   
164 void G4Fancy3DNucleus::SortNucleonsDecZ()         
165 {                                                 
166   if (theNucleons.size() < 2 ) return;    // A    
167   SortNucleonsIncZ();                             
168                                                   
169   std::reverse(theNucleons.begin(), theNucleon    
170 }                                                 
171                                                   
172                                                   
173 G4double G4Fancy3DNucleus::BindingEnergy()        
174 {                                                 
175   return G4NucleiProperties::GetBindingEnergy(    
176 }                                                 
177                                                   
178                                                   
179 G4double G4Fancy3DNucleus::GetNuclearRadius()     
180 {                                                 
181   return GetNuclearRadius(0.5);                   
182 }                                                 
183                                                   
184 G4double G4Fancy3DNucleus::GetNuclearRadius(co    
185 {                                                 
186   return theDensity->GetRadius(maxRelativeDens    
187 }                                                 
188                                                   
189 G4double G4Fancy3DNucleus::GetOuterRadius()       
190 {                                                 
191   G4double maxradius2=0;                          
192                                                   
193   for (int i=0; i<myA; i++)                       
194   {                                               
195      if ( theNucleons[i].GetPosition().mag2()     
196      {                                            
197       maxradius2=theNucleons[i].GetPosition().    
198      }                                            
199   }                                               
200   return std::sqrt(maxradius2)+nucleondistance    
201 }                                                 
202                                                   
203 G4double G4Fancy3DNucleus::GetMass()              
204 {                                                 
205   if ( myL <= 0 ) return myZ*G4Proton::Proton(    
206                          (myA-myZ)*G4Neutron::    
207                          BindingEnergy();         
208   else            return G4HyperNucleiProperti    
209 }                                                 
210                                                   
211                                                   
212                                                   
213 void G4Fancy3DNucleus::DoLorentzBoost(const G4    
214 {                                                 
215   for (G4int i=0; i<myA; i++){                    
216       theNucleons[i].Boost(theBoost);             
217   }                                               
218 }                                                 
219                                                   
220 void G4Fancy3DNucleus::DoLorentzBoost(const G4    
221 {                                                 
222   for (G4int i=0; i<myA; i++){                    
223       theNucleons[i].Boost(theBeta);              
224   }                                               
225 }                                                 
226                                                   
227 void G4Fancy3DNucleus::DoLorentzContraction(co    
228 {                                                 
229   G4double beta2=theBeta.mag2();                  
230   if (beta2 > 0) {                                
231      G4double factor=(1-std::sqrt(1-beta2))/be    
232      G4ThreeVector rprime;                        
233      for (G4int i=0; i< myA; i++) {               
234        rprime = theNucleons[i].GetPosition() -    
235          factor * (theBeta*theNucleons[i].GetP    
236        theNucleons[i].SetPosition(rprime);        
237      }                                            
238   }                                               
239 }                                                 
240                                                   
241 void G4Fancy3DNucleus::DoLorentzContraction(co    
242 {                                                 
243   if (theBoost.e() !=0 ) {                        
244      G4ThreeVector beta = theBoost.vect()/theB    
245      DoLorentzContraction(beta);                  
246   }                                               
247 }                                                 
248                                                   
249                                                   
250                                                   
251 void G4Fancy3DNucleus::CenterNucleons()           
252 {                                                 
253   G4ThreeVector center;                           
254                                                   
255   for (G4int i=0; i<myA; i++ )                    
256   {                                               
257      center+=theNucleons[i].GetPosition();        
258   }                                               
259   center /= -myA;                                 
260   DoTranslation(center);                          
261 }                                                 
262                                                   
263 void G4Fancy3DNucleus::DoTranslation(const G4T    
264 {                                                 
265   G4ThreeVector tempV;                            
266   for (G4int i=0; i<myA; i++ )                    
267     {                                             
268       tempV = theNucleons[i].GetPosition() + t    
269       theNucleons[i].SetPosition(tempV);          
270     }                                             
271 }                                                 
272                                                   
273 const G4VNuclearDensity * G4Fancy3DNucleus::Ge    
274 {                                                 
275   return theDensity;                              
276 }                                                 
277                                                   
278 //----------------------- private Implementati    
279                                                   
280 void G4Fancy3DNucleus::ChooseNucleons()           
281 {                                                 
282   G4int protons=0, nucleons=0, lambdas=0;         
283   G4double probProton = ( G4double(myZ) )/( G4    
284   G4double probLambda = myL > 0 ? ( G4double(m    
285   while ( nucleons < myA ) {  /* Loop checking    
286     G4double rnd = G4UniformRand();               
287     if ( rnd < probProton ) {                     
288       if ( protons < myZ ) {                      
289   protons++;                                      
290   theNucleons[nucleons++].SetParticleType(G4Pr    
291       }                                           
292     } else if ( rnd < probProton + probLambda     
293       if ( lambdas < myL ) {                      
294   lambdas++;                                      
295   theNucleons[nucleons++].SetParticleType(G4La    
296       }                                           
297     } else {                                      
298       if ( (nucleons - protons - lambdas) < (m    
299   theNucleons[nucleons++].SetParticleType(G4Ne    
300       }                                           
301     }                                             
302   }                                               
303   return;                                         
304 }                                                 
305                                                   
306 void G4Fancy3DNucleus::ChoosePositions()          
307 {                                                 
308   if( myA != 12) {                                
309                                                   
310     G4int i=0;                                    
311     G4ThreeVector aPos, delta;                    
312     G4bool    freeplace;                          
313     const G4double nd2=sqr(nucleondistance);      
314     G4double maxR=GetNuclearRadius(0.001);   /    
315                                        //  rel    
316     G4int jr=0;                                   
317     G4int jx,jy;                                  
318     G4double arand[600];                          
319     G4double *prand=arand;                        
320     places.clear();       // Reset data buffer    
321     G4int interationsLeft=1000*myA;               
322     while ( (i < myA) && (--interationsLeft>0)    
323     {                                             
324       do                                          
325       {                                           
326         if ( jr < 3 )                             
327   {                                               
328           jr=std::min(600,9*(myA - i));           
329           G4RandFlat::shootArray(jr,prand);       
330     //CLHEP::RandFlat::shootArray(jr, prand );    
331   }                                               
332   jx=--jr;                                        
333   jy=--jr;                                        
334   aPos.set((2*arand[jx]-1.), (2*arand[jy]-1.),    
335       } while (aPos.mag2() > 1. );  /* Loop ch    
336       aPos *=maxR;                                
337       G4double density=theDensity->GetRelative    
338       if (G4UniformRand() < density)              
339       {                                           
340         freeplace= true;                          
341   std::vector<G4ThreeVector>::iterator iplace;    
342   for( iplace=places.begin(); iplace!=places.e    
343   {                                               
344     delta = *iplace - aPos;                       
345     freeplace= delta.mag2() > nd2;                
346   }                                               
347   if ( freeplace ) {                              
348           G4double pFermi=theFermi.GetFermiMom    
349           // protons must at least have bindin    
350           //  assuming the Fermi energy corres    
351           //  that the Fermi Energy > CoulombB    
352     if (theNucleons[i].GetDefinition() == G4Pr    
353           {                                       
354             G4double nucMass = theNucleons[i].    
355             G4double eFermi= std::sqrt( sqr(pF    
356       if (eFermi <= CoulombBarrier() ) freepla    
357     }                                             
358   }                                               
359   if ( freeplace ) {                              
360           theNucleons[i].SetPosition(aPos);       
361     places.push_back(aPos);                       
362     ++i;                                          
363   }                                               
364       }                                           
365     }                                             
366     if (interationsLeft<=0) {                     
367       G4Exception("model/util/G4Fancy3DNucleus    
368                   "Problem to place nucleons")    
369     }                                             
370                                                   
371   } else {                                        
372     // Start insertion                            
373     // Alpha cluster structure of carbon nucle    
374     //       P. Bozek, W. Broniowski, E.R. Arr    
375     //                Phys. Rev. C90, 064902 (    
376     const G4double Lbase=3.05*fermi;              
377     const G4double Disp=0.552;        // 0.91^    
378     const G4double nd2=sqr(nucleondistance);      
379     const G4ThreeVector Corner1=G4ThreeVector(    
380     const G4ThreeVector Corner2=G4ThreeVector(    
381     const G4ThreeVector Corner3=G4ThreeVector(    
382     G4ThreeVector R1;                             
383     R1=G4ThreeVector(G4RandGauss::shoot(0.,Dis    
384     theNucleons[0].SetPosition(R1); // First n    
385     G4int loopCounterLeft = 10000;                
386     for(G4int ii=1; ii<4; ii++)     // 2 - 4 n    
387     {                                             
388       G4bool Continue;                            
389       do                                          
390       {                                           
391         R1=G4ThreeVector(G4RandGauss::shoot(0.    
392         theNucleons[ii].SetPosition(R1);          
393         Continue=false;                           
394         for(G4int jj=0; jj < ii; jj++)            
395         {                                         
396           if( (theNucleons[ii].GetPosition() -    
397         }                                         
398       } while( Continue && --loopCounterLeft >    
399     }                                             
400     if ( loopCounterLeft <= 0 ) {                 
401       G4Exception("model/util/G4Fancy3DNucleus    
402                   "Unable to find a good posit    
403     }                                             
404     loopCounterLeft = 10000;                      
405     for(G4int ii=4; ii<8; ii++)     // 5 - 8 n    
406     {                                             
407       G4bool Continue;                            
408       do                                          
409       {                                           
410         R1=G4ThreeVector(G4RandGauss::shoot(0.    
411         theNucleons[ii].SetPosition(R1);          
412         Continue=false;                           
413         for(G4int jj=0; jj < ii; jj++)            
414         {                                         
415           if( (theNucleons[ii].GetPosition() -    
416         }                                         
417       } while( Continue && --loopCounterLeft >    
418     }                                             
419     if ( loopCounterLeft <= 0 ) {                 
420       G4Exception("model/util/G4Fancy3DNucleus    
421                   "Unable to find a good posit    
422     }                                             
423     loopCounterLeft = 10000;                      
424     for(G4int ii=8; ii<12; ii++)    // 9 - 12     
425     {                                             
426       G4bool Continue;                            
427       do                                          
428       {                                           
429         R1=G4ThreeVector(G4RandGauss::shoot(0.    
430         theNucleons[ii].SetPosition(R1);          
431         Continue=false;                           
432         for(G4int jj=0; jj < ii; jj++)            
433         {                                         
434           if( (theNucleons[ii].GetPosition() -    
435         }                                         
436       } while( Continue && --loopCounterLeft >    
437     }                                             
438     if ( loopCounterLeft <= 0 ) {                 
439       G4Exception("model/util/G4Fancy3DNucleus    
440                   "Unable to find a good posit    
441     }                                             
442     G4LorentzRotation RandomRotation;             
443     RandomRotation.rotateZ(2.*pi*G4UniformRand    
444     RandomRotation.rotateY(std::acos(2.*G4Unif    
445     // Randomly rotation of the created nucleu    
446     G4LorentzVector Pos;                          
447     for(G4int ii=0; ii<myA; ii++ )                
448     {                                             
449       Pos=G4LorentzVector(theNucleons[ii].GetP    
450       G4ThreeVector NewPos = Pos.vect();          
451       theNucleons[ii].SetPosition(NewPos);        
452     }                                             
453                                                   
454   }                                               
455 }                                                 
456                                                   
457 void G4Fancy3DNucleus::ChooseFermiMomenta()       
458 {                                                 
459     G4int i;                                      
460     G4double density;                             
461                                                   
462     // Pre-allocate buffers for filling by ind    
463     momentum.resize(myA, G4ThreeVector(0.,0.,0    
464     fermiM.resize(myA, 0.*GeV);                   
465                                                   
466     for (G4int ntry=0; ntry<1 ; ntry ++ )         
467     {                                             
468   for (i=0; i < myA; i++ )    // momenta for a    
469   {                                               
470      density = theDensity->GetDensity(theNucle    
471      fermiM[i] = theFermi.GetFermiMomentum(den    
472      G4ThreeVector mom=theFermi.GetMomentum(de    
473      if (theNucleons[i].GetDefinition() == G4P    
474      {                                            
475         G4double eMax = std::sqrt(sqr(fermiM[i    
476                         - CoulombBarrier();       
477         if ( eMax > theNucleons[i].GetDefiniti    
478         {                                         
479             G4double pmax2= sqr(eMax) - sqr(th    
480       fermiM[i] = std::sqrt(pmax2);               
481       while ( mom.mag2() > pmax2 )  /* Loop ch    
482       {                                           
483           mom=theFermi.GetMomentum(density, fe    
484       }                                           
485         }  else                                   
486         {                                         
487                   //AR-21Dec2017 : emit a "Jus    
488             //G4cerr << "G4Fancy3DNucleus: dif    
489                   G4ExceptionDescription ed;      
490                   ed << "Nucleus Z A " << my    
491                   ed << "proton with eMax=" <<    
492                   G4Exception( "G4Fancy3DNucle    
493                                "HAD_FANCY3DNUC    
494       mom=G4ThreeVector(0,0,0);                   
495         }                                         
496                                                   
497      }                                            
498      momentum[i]= mom;                            
499   }                                               
500                                                   
501   if ( ReduceSum() ) break;                       
502 //       G4cout <<" G4FancyNucleus: iterating     
503     }                                             
504                                                   
505 //     G4ThreeVector sum;                         
506 //     for (G4int index=0; index<myA;sum+=mome    
507 //     ;                                          
508 //     G4cout << "final sum / mag() " << sum <    
509                                                   
510     G4double energy;                              
511     for ( i=0; i< myA ; i++ )                     
512     {                                             
513        energy = theNucleons[i].GetParticleType    
514           - BindingEnergy()/myA;                  
515        G4LorentzVector tempV(momentum[i],energ    
516        theNucleons[i].SetMomentum(tempV);         
517        // GF 11-05-2011: set BindingEnergy to     
518        //theNucleons[i].SetBindingEnergy(         
519        //     0.5*sqr(fermiM[i])/theNucleons[i    
520     }                                             
521 }                                                 
522                                                   
523                                                   
524 G4bool G4Fancy3DNucleus::ReduceSum()              
525 {                                                 
526   G4ThreeVector sum;                              
527   G4double PFermi=fermiM[myA-1];                  
528                                                   
529   for (G4int i=0; i < myA-1 ; i++ )               
530        { sum+=momentum[i]; }                      
531                                                   
532 // check if have to do anything at all..          
533   if ( sum.mag() <= PFermi )                      
534   {                                               
535     momentum[myA-1]=-sum;                         
536     return true;                                  
537   }                                               
538                                                   
539 // find all possible changes in momentum, chan    
540   G4ThreeVector testDir=sum.unit();               
541   testSums.clear();                               
542   testSums.resize(myA-1);   // Allocate block     
543                                                   
544   G4ThreeVector delta;                            
545   for (G4int aNucleon=0; aNucleon < myA-1; ++a    
546     delta = 2.*((momentum[aNucleon]*testDir)*t    
547                                                   
548     testSums[aNucleon].Fill(delta, delta.mag()    
549   }                                               
550                                                   
551   std::sort(testSums.begin(), testSums.end());    
552                                                   
553 //    reduce Momentum Sum until the next would    
554   G4int index=(G4int)testSums.size();             
555   while ( (sum-testSums[--index].Vector).mag()    
556   {                                               
557     // Only take one which improve, ie. don't     
558     if ( sum.mag() > (sum-testSums[index].Vect    
559       momentum[testSums[index].Index]-=testSum    
560       sum-=testSums[index].Vector;                
561     }                                             
562   }                                               
563                                                   
564   if ( (sum-testSums[index].Vector).mag() <= P    
565   {                                               
566     G4int best=-1;                                
567     G4double pBest=2*PFermi; // anything large    
568     for ( G4int aNucleon=0; aNucleon<=index; a    
569     {                                             
570       // find the momentum closest to choosen     
571       G4double pTry=(testSums[aNucleon].Vector    
572       if ( pTry < PFermi                          
573        &&  std::abs(momentum[myA-1].mag() - pT    
574             {                                     
575          pBest=std::abs(momentum[myA-1].mag()     
576          best=aNucleon;                           
577       }                                           
578     }                                             
579     if ( best < 0 )                               
580     {                                             
581       const G4String& text = "G4Fancy3DNucleus    
582               throw G4HadronicException(__FILE    
583     }                                             
584     momentum[testSums[best].Index]-=testSums[b    
585     momentum[myA-1]=testSums[best].Vector-sum;    
586                                                   
587     return true;                                  
588                                                   
589   }                                               
590                                                   
591   // try to compensate momentum using another     
592   G4int swapit=-1;                                
593   while (swapit<myA-1)  /* Loop checking, 30-O    
594   {                                               
595     if ( fermiM[++swapit] > PFermi ) break;       
596   }                                               
597   if (swapit == myA-1 ) return false;             
598                                                   
599   // Now we have a nucleon with a bigger Fermi    
600   // Exchange with last nucleon.. and iterate.    
601   std::swap(theNucleons[swapit], theNucleons[m    
602   std::swap(momentum[swapit], momentum[myA-1])    
603   std::swap(fermiM[swapit], fermiM[myA-1]);       
604   return ReduceSum();                             
605 }                                                 
606                                                   
607 G4double G4Fancy3DNucleus::CoulombBarrier()       
608 {                                                 
609   static const G4double cfactor = (1.44/1.14)     
610   return cfactor*myZ/(1.0 + G4Pow::GetInstance    
611 }                                                 
612