Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/de_excitation/multifragmentation/src/G4StatMFMicroPartition.cc

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

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 //
 27 //
 28 // by V. Lara
 29 // --------------------------------------------------------------------
 30 
 31 #include "G4StatMFMicroPartition.hh"
 32 #include "G4PhysicalConstants.hh"
 33 #include "G4SystemOfUnits.hh"
 34 #include "G4HadronicException.hh"
 35 #include "Randomize.hh"
 36 #include "G4Log.hh"
 37 #include "G4Exp.hh"
 38 #include "G4Pow.hh"
 39 
 40 // Copy constructor
 41 G4StatMFMicroPartition::G4StatMFMicroPartition(const G4StatMFMicroPartition & )
 42 {
 43   throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::copy_constructor meant to not be accessible");
 44 }
 45 
 46 // Operators
 47 
 48 G4StatMFMicroPartition & G4StatMFMicroPartition::
 49 operator=(const G4StatMFMicroPartition & )
 50 {
 51   throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::operator= meant to not be accessible");
 52   return *this;
 53 }
 54 
 55 
 56 G4bool G4StatMFMicroPartition::operator==(const G4StatMFMicroPartition & ) const
 57 {
 58   //throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::operator== meant to not be accessible");
 59   return false;
 60 }
 61  
 62 
 63 G4bool G4StatMFMicroPartition::operator!=(const G4StatMFMicroPartition & ) const
 64 {
 65   //throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::operator!= meant to not be accessible");
 66   return true;
 67 }
 68 
 69 void G4StatMFMicroPartition::CoulombFreeEnergy(G4int anA)
 70 {
 71   // This Z independent factor in the Coulomb free energy 
 72   G4double  CoulombConstFactor = G4StatMFParameters::GetCoulomb();
 73 
 74   // We use the aproximation Z_f ~ Z/A * A_f
 75 
 76   G4double ZA = G4double(theZ)/G4double(theA);
 77                     
 78   if (anA == 0 || anA == 1) 
 79     {
 80       _theCoulombFreeEnergy.push_back(CoulombConstFactor*ZA*ZA);
 81     } 
 82   else if (anA == 2 || anA == 3 || anA == 4) 
 83     {
 84       // Z/A ~ 1/2
 85       _theCoulombFreeEnergy.push_back(CoulombConstFactor*0.5
 86               *anA*G4Pow::GetInstance()->Z23(anA));
 87     } 
 88   else  // anA > 4
 89     {
 90       _theCoulombFreeEnergy.push_back(CoulombConstFactor*ZA*ZA  
 91               *anA*G4Pow::GetInstance()->Z23(anA));
 92     }
 93 }
 94 
 95 G4double G4StatMFMicroPartition::GetCoulombEnergy(void)
 96 {
 97   G4Pow* g4calc = G4Pow::GetInstance();
 98   G4double  CoulombFactor = 1.0/g4calc->A13(1.0+G4StatMFParameters::GetKappaCoulomb()); 
 99       
100   G4double CoulombEnergy = elm_coupling*0.6*theZ*theZ*CoulombFactor/
101     (G4StatMFParameters::Getr0()*g4calc->Z13(theA));
102   
103   G4double ZA = G4double(theZ)/G4double(theA);
104   for (unsigned int i = 0; i < _thePartition.size(); i++) 
105     CoulombEnergy += _theCoulombFreeEnergy[i] - elm_coupling*0.6*
106       ZA*ZA*_thePartition[i]*g4calc->Z23(_thePartition[i])/
107       G4StatMFParameters::Getr0();
108     
109   return CoulombEnergy;
110 }
111 
112 G4double G4StatMFMicroPartition::GetPartitionEnergy(G4double T)
113 {
114   G4Pow* g4calc = G4Pow::GetInstance();
115   G4double  CoulombFactor = 1.0/g4calc->A13(1.0+G4StatMFParameters::GetKappaCoulomb()); 
116   
117   G4double PartitionEnergy = 0.0;
118   
119   // We use the aprox that Z_f ~ Z/A * A_f
120   for (unsigned int i = 0; i < _thePartition.size(); i++) 
121     {
122       if (_thePartition[i] == 0 || _thePartition[i] == 1) 
123         { 
124           PartitionEnergy += _theCoulombFreeEnergy[i];
125         }
126       else if (_thePartition[i] == 2) 
127         {   
128           PartitionEnergy +=  
129             -2.796 // Binding Energy of deuteron ??????
130             + _theCoulombFreeEnergy[i];   
131   }
132       else if (_thePartition[i] == 3) 
133         { 
134           PartitionEnergy +=  
135             -9.224 // Binding Energy of trtion/He3 ??????
136             + _theCoulombFreeEnergy[i];   
137   } 
138       else if (_thePartition[i] == 4) 
139         { 
140           PartitionEnergy +=
141             -30.11 // Binding Energy of ALPHA ??????
142             + _theCoulombFreeEnergy[i] 
143             + 4.*T*T/InvLevelDensity(4.);
144   } 
145       else 
146         {
147           PartitionEnergy +=
148             //Volume term           
149             (- G4StatMFParameters::GetE0() + 
150              T*T/InvLevelDensity(_thePartition[i]))
151             *_thePartition[i] + 
152             
153             // Symmetry term
154             G4StatMFParameters::GetGamma0()*
155             (1.0-2.0*theZ/theA)*(1.0-2.0*theZ/theA)*_thePartition[i] +  
156             
157             // Surface term
158             (G4StatMFParameters::Beta(T) - T*G4StatMFParameters::DBetaDT(T))*
159             g4calc->Z23(_thePartition[i]) +
160             
161             // Coulomb term 
162             _theCoulombFreeEnergy[i];
163   }
164     }
165   
166   PartitionEnergy += elm_coupling*0.6*theZ*theZ*CoulombFactor/
167     (G4StatMFParameters::Getr0()*g4calc->Z13(theA))
168     + 1.5*T*(_thePartition.size()-1);
169   
170   return PartitionEnergy;
171 }
172 
173 G4double G4StatMFMicroPartition::CalcPartitionTemperature(G4double U,
174                 G4double FreeInternalE0)
175 {
176   G4double PartitionEnergy = GetPartitionEnergy(0.0);
177   
178   // If this happens, T = 0 MeV, which means that probability for this
179   // partition will be 0
180   if (std::fabs(U + FreeInternalE0 - PartitionEnergy) < 0.003) return -1.0;
181     
182   // Calculate temperature by midpoint method
183   
184   // Bracketing the solution
185   G4double Ta = 0.001;
186   G4double Tb = std::max(std::sqrt(8.0*U/theA),0.0012*MeV);
187   G4double Tmid = 0.0;
188   
189   G4double Da = (U + FreeInternalE0 - GetPartitionEnergy(Ta))/U;
190   G4double Db = (U + FreeInternalE0 - GetPartitionEnergy(Tb))/U;
191   
192   G4int maxit = 0;
193   // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
194   while (Da*Db > 0.0 && maxit < 1000) 
195     {
196       ++maxit;
197       Tb += 0.5*Tb;   
198       Db = (U + FreeInternalE0 - GetPartitionEnergy(Tb))/U;
199     }
200   
201   G4double eps = 1.0e-14*std::abs(Ta-Tb);
202   
203   for (G4int i = 0; i < 1000; i++) 
204     {
205       Tmid = (Ta+Tb)/2.0;
206       if (std::fabs(Ta-Tb) <= eps) return Tmid;
207       G4double Dmid = (U + FreeInternalE0 - GetPartitionEnergy(Tmid))/U;
208       if (std::fabs(Dmid) < 0.003) return Tmid;
209       if (Da*Dmid < 0.0) 
210         {
211           Tb = Tmid;
212           Db = Dmid;
213         } 
214       else 
215         {
216           Ta = Tmid;
217           Da = Dmid;
218         } 
219     }
220   // if we arrive here the temperature could not be calculated
221   G4cout << "G4StatMFMicroPartition::CalcPartitionTemperature: I can't calculate the temperature"  
222          << G4endl;
223   // and set probability to 0 returning T < 0
224   return -1.0;
225   
226 }
227 
228 G4double G4StatMFMicroPartition::CalcPartitionProbability(G4double U,
229                 G4double FreeInternalE0,
230                 G4double SCompound)
231 { 
232   G4double T = CalcPartitionTemperature(U,FreeInternalE0);
233   if ( T <= 0.0) return _Probability = 0.0;
234   _Temperature = T;
235   
236   G4Pow* g4calc = G4Pow::GetInstance();
237   
238   // Factorial of fragment multiplicity
239   G4double Fact = 1.0;
240   unsigned int i;
241   for (i = 0; i < _thePartition.size() - 1; i++) 
242     {
243       G4double f = 1.0;
244       for (unsigned int ii = i+1; i< _thePartition.size(); i++) 
245         {
246           if (_thePartition[i] == _thePartition[ii]) f++;
247         }
248       Fact *= f;
249   }
250   
251   G4double ProbDegeneracy = 1.0;
252   G4double ProbA32 = 1.0; 
253   
254   for (i = 0; i < _thePartition.size(); i++) 
255     {
256       ProbDegeneracy *= GetDegeneracyFactor(_thePartition[i]);
257       ProbA32 *= _thePartition[i]*std::sqrt((G4double)_thePartition[i]);
258     }
259   
260   // Compute entropy
261   G4double PartitionEntropy = 0.0;
262   for (i = 0; i < _thePartition.size(); i++) 
263     {
264       // interaction entropy for alpha
265       if (_thePartition[i] == 4) 
266         {
267           PartitionEntropy += 
268             2.0*T*_thePartition[i]/InvLevelDensity(_thePartition[i]);
269         }
270       // interaction entropy for Af > 4
271       else if (_thePartition[i] > 4) 
272         {
273           PartitionEntropy += 
274             2.0*T*_thePartition[i]/InvLevelDensity(_thePartition[i])
275             - G4StatMFParameters::DBetaDT(T) * g4calc->Z23(_thePartition[i]);
276         } 
277     }
278   
279   // Thermal Wave Lenght = std::sqrt(2 pi hbar^2 / nucleon_mass T)
280   G4double ThermalWaveLenght3 = 16.15*fermi/std::sqrt(T);
281   ThermalWaveLenght3 = ThermalWaveLenght3*ThermalWaveLenght3*ThermalWaveLenght3;
282   
283   // Translational Entropy
284   G4double kappa = 1. + elm_coupling*(g4calc->Z13((G4int)_thePartition.size())-1.0)
285                     /(G4StatMFParameters::Getr0()*g4calc->Z13(theA));
286   kappa = kappa*kappa*kappa;
287   kappa -= 1.;
288   G4double V0 = (4./3.)*pi*theA*G4StatMFParameters::Getr0()*G4StatMFParameters::Getr0()*
289     G4StatMFParameters::Getr0();
290   G4double FreeVolume = kappa*V0;
291   G4double TranslationalS = std::max(0.0, G4Log(ProbA32/Fact) +
292       (_thePartition.size()-1.0)*G4Log(FreeVolume/ThermalWaveLenght3) +
293       1.5*(_thePartition.size()-1.0) - 1.5*g4calc->logZ(theA));
294   
295   PartitionEntropy += G4Log(ProbDegeneracy) + TranslationalS;
296   _Entropy = PartitionEntropy;
297   
298   // And finally compute probability of fragment configuration
299   G4double exponent = PartitionEntropy-SCompound;
300   if (exponent > 300.0) exponent = 300.0;
301   return _Probability = G4Exp(exponent);
302 }
303 
304 G4double G4StatMFMicroPartition::GetDegeneracyFactor(G4int A)
305 {
306   // Degeneracy factors are statistical factors
307   // DegeneracyFactor for nucleon is (2S_n + 1)(2I_n + 1) = 4
308   G4double DegFactor = 0;
309   if (A > 4) DegFactor = 1.0;
310   else if (A == 1) DegFactor = 4.0;     // nucleon
311   else if (A == 2) DegFactor = 3.0;     // Deuteron
312   else if (A == 3) DegFactor = 4.0;     // Triton + He3
313   else if (A == 4) DegFactor = 1.0;     // alpha
314   return DegFactor;
315 }
316 
317 G4StatMFChannel * G4StatMFMicroPartition::ChooseZ(G4int A0, G4int Z0, G4double MeanT)
318 // Gives fragments charges
319 {
320   std::vector<G4int> FragmentsZ;
321   
322   G4int ZBalance = 0;
323   do 
324     {
325       G4double CC = G4StatMFParameters::GetGamma0()*8.0;
326       G4int SumZ = 0;
327       for (unsigned int i = 0; i < _thePartition.size(); i++) 
328         {
329           G4double ZMean;
330           G4double Af = _thePartition[i];
331           if (Af > 1.5 && Af < 4.5) ZMean = 0.5*Af;
332           else ZMean = Af*Z0/A0;
333           G4double ZDispersion = std::sqrt(Af * MeanT/CC);
334           G4int Zf;
335           do 
336             {
337               Zf = static_cast<G4int>(G4RandGauss::shoot(ZMean,ZDispersion));
338       } 
339           // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
340           while (Zf < 0 || Zf > Af);
341           FragmentsZ.push_back(Zf);
342           SumZ += Zf;
343   }
344       ZBalance = Z0 - SumZ;
345     } 
346   // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
347   while (std::abs(ZBalance) > 1);
348   FragmentsZ[0] += ZBalance;
349   
350   G4StatMFChannel * theChannel = new G4StatMFChannel;
351   for (unsigned int i = 0; i < _thePartition.size(); i++)
352     {
353       theChannel->CreateFragment(_thePartition[i],FragmentsZ[i]);
354     }
355 
356   return theChannel;
357 }
358