Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4StatMFMicroPartition.cc
이 파일의 문서화 페이지로 가기
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 // $Id: G4StatMFMicroPartition.cc 100379 2016-10-19 15:05:35Z gcosmo $
28 //
29 // by V. Lara
30 // --------------------------------------------------------------------
31 
33 #include "G4PhysicalConstants.hh"
34 #include "G4SystemOfUnits.hh"
35 #include "G4HadronicException.hh"
36 #include "Randomize.hh"
37 #include "G4Log.hh"
38 #include "G4Exp.hh"
39 #include "G4Pow.hh"
40 
41 // Copy constructor
43 {
44  throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::copy_constructor meant to not be accessable");
45 }
46 
47 // Operators
48 
51 {
52  throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::operator= meant to not be accessable");
53  return *this;
54 }
55 
56 
58 {
59  //throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::operator== meant to not be accessable");
60  return false;
61 }
62 
63 
65 {
66  //throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroPartition::operator!= meant to not be accessable");
67  return true;
68 }
69 
71 {
72  // This Z independent factor in the Coulomb free energy
73  G4double CoulombConstFactor = G4StatMFParameters::GetCoulomb();
74 
75  // We use the aproximation Z_f ~ Z/A * A_f
76 
78 
79  if (anA == 0 || anA == 1)
80  {
81  _theCoulombFreeEnergy.push_back(CoulombConstFactor*ZA*ZA);
82  }
83  else if (anA == 2 || anA == 3 || anA == 4)
84  {
85  // Z/A ~ 1/2
86  _theCoulombFreeEnergy.push_back(CoulombConstFactor*0.5
87  *anA*G4Pow::GetInstance()->Z23(anA));
88  }
89  else // anA > 4
90  {
91  _theCoulombFreeEnergy.push_back(CoulombConstFactor*ZA*ZA
92  *anA*G4Pow::GetInstance()->Z23(anA));
93  }
94 }
95 
97 {
98  G4Pow* g4calc = G4Pow::GetInstance();
99  G4double CoulombFactor = 1.0/g4calc->A13(1.0+G4StatMFParameters::GetKappaCoulomb());
100 
101  G4double CoulombEnergy = elm_coupling*0.6*theZ*theZ*CoulombFactor/
102  (G4StatMFParameters::Getr0()*g4calc->Z13(theA));
103 
105  for (unsigned int i = 0; i < _thePartition.size(); i++)
106  CoulombEnergy += _theCoulombFreeEnergy[i] - elm_coupling*0.6*
107  ZA*ZA*_thePartition[i]*g4calc->Z23(_thePartition[i])/
109 
110  return CoulombEnergy;
111 }
112 
114 {
115  G4Pow* g4calc = G4Pow::GetInstance();
116  G4double CoulombFactor = 1.0/g4calc->A13(1.0+G4StatMFParameters::GetKappaCoulomb());
117 
118  G4double PartitionEnergy = 0.0;
119 
120  // We use the aprox that Z_f ~ Z/A * A_f
121  for (unsigned int i = 0; i < _thePartition.size(); i++)
122  {
123  if (_thePartition[i] == 0 || _thePartition[i] == 1)
124  {
125  PartitionEnergy += _theCoulombFreeEnergy[i];
126  }
127  else if (_thePartition[i] == 2)
128  {
129  PartitionEnergy +=
130  -2.796 // Binding Energy of deuteron ??????
131  + _theCoulombFreeEnergy[i];
132  }
133  else if (_thePartition[i] == 3)
134  {
135  PartitionEnergy +=
136  -9.224 // Binding Energy of trtion/He3 ??????
137  + _theCoulombFreeEnergy[i];
138  }
139  else if (_thePartition[i] == 4)
140  {
141  PartitionEnergy +=
142  -30.11 // Binding Energy of ALPHA ??????
144  + 4.*T*T/InvLevelDensity(4.);
145  }
146  else
147  {
148  PartitionEnergy +=
149  //Volume term
152  *_thePartition[i] +
153 
154  // Symmetry term
156  (1.0-2.0*theZ/theA)*(1.0-2.0*theZ/theA)*_thePartition[i] +
157 
158  // Surface term
160  g4calc->Z23(_thePartition[i]) +
161 
162  // Coulomb term
164  }
165  }
166 
167  PartitionEnergy += elm_coupling*0.6*theZ*theZ*CoulombFactor/
168  (G4StatMFParameters::Getr0()*g4calc->Z13(theA))
169  + 1.5*T*(_thePartition.size()-1);
170 
171  return PartitionEnergy;
172 }
173 
175  G4double FreeInternalE0)
176 {
177  G4double PartitionEnergy = GetPartitionEnergy(0.0);
178 
179  // If this happens, T = 0 MeV, which means that probability for this
180  // partition will be 0
181  if (std::fabs(U + FreeInternalE0 - PartitionEnergy) < 0.003) return -1.0;
182 
183  // Calculate temperature by midpoint method
184 
185  // Bracketing the solution
186  G4double Ta = 0.001;
187  G4double Tb = std::max(std::sqrt(8.0*U/theA),0.0012*MeV);
188  G4double Tmid = 0.0;
189 
190  G4double Da = (U + FreeInternalE0 - GetPartitionEnergy(Ta))/U;
191  G4double Db = (U + FreeInternalE0 - GetPartitionEnergy(Tb))/U;
192 
193  G4int maxit = 0;
194  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
195  while (Da*Db > 0.0 && maxit < 1000)
196  {
197  ++maxit;
198  Tb += 0.5*Tb;
199  Db = (U + FreeInternalE0 - GetPartitionEnergy(Tb))/U;
200  }
201 
202  G4double eps = 1.0e-14*std::abs(Ta-Tb);
203 
204  for (G4int i = 0; i < 1000; i++)
205  {
206  Tmid = (Ta+Tb)/2.0;
207  if (std::fabs(Ta-Tb) <= eps) return Tmid;
208  G4double Dmid = (U + FreeInternalE0 - GetPartitionEnergy(Tmid))/U;
209  if (std::fabs(Dmid) < 0.003) return Tmid;
210  if (Da*Dmid < 0.0)
211  {
212  Tb = Tmid;
213  Db = Dmid;
214  }
215  else
216  {
217  Ta = Tmid;
218  Da = Dmid;
219  }
220  }
221  // if we arrive here the temperature could not be calculated
222  G4cout << "G4StatMFMicroPartition::CalcPartitionTemperature: I can't calculate the temperature"
223  << G4endl;
224  // and set probability to 0 returning T < 0
225  return -1.0;
226 
227 }
228 
230  G4double FreeInternalE0,
231  G4double SCompound)
232 {
233  G4double T = CalcPartitionTemperature(U,FreeInternalE0);
234  if ( T <= 0.0) return _Probability = 0.0;
235  _Temperature = T;
236 
237  G4Pow* g4calc = G4Pow::GetInstance();
238 
239  // Factorial of fragment multiplicity
240  G4double Fact = 1.0;
241  unsigned int i;
242  for (i = 0; i < _thePartition.size() - 1; i++)
243  {
244  G4double f = 1.0;
245  for (unsigned int ii = i+1; i< _thePartition.size(); i++)
246  {
247  if (_thePartition[i] == _thePartition[ii]) f++;
248  }
249  Fact *= f;
250  }
251 
252  G4double ProbDegeneracy = 1.0;
253  G4double ProbA32 = 1.0;
254 
255  for (i = 0; i < _thePartition.size(); i++)
256  {
257  ProbDegeneracy *= GetDegeneracyFactor(_thePartition[i]);
258  ProbA32 *= _thePartition[i]*std::sqrt((G4double)_thePartition[i]);
259  }
260 
261  // Compute entropy
262  G4double PartitionEntropy = 0.0;
263  for (i = 0; i < _thePartition.size(); i++)
264  {
265  // interaction entropy for alpha
266  if (_thePartition[i] == 4)
267  {
268  PartitionEntropy +=
270  }
271  // interaction entropy for Af > 4
272  else if (_thePartition[i] > 4)
273  {
274  PartitionEntropy +=
276  - G4StatMFParameters::DBetaDT(T) * g4calc->Z23(_thePartition[i]);
277  }
278  }
279 
280  // Thermal Wave Lenght = std::sqrt(2 pi hbar^2 / nucleon_mass T)
281  G4double ThermalWaveLenght3 = 16.15*fermi/std::sqrt(T);
282  ThermalWaveLenght3 = ThermalWaveLenght3*ThermalWaveLenght3*ThermalWaveLenght3;
283 
284  // Translational Entropy
285  G4double kappa = 1. + elm_coupling*(g4calc->Z13(_thePartition.size())-1.0)
286  /(G4StatMFParameters::Getr0()*g4calc->Z13(theA));
287  kappa = kappa*kappa*kappa;
288  kappa -= 1.;
291  G4double FreeVolume = kappa*V0;
292  G4double TranslationalS = std::max(0.0, G4Log(ProbA32/Fact) +
293  (_thePartition.size()-1.0)*G4Log(FreeVolume/ThermalWaveLenght3) +
294  1.5*(_thePartition.size()-1.0) - 1.5*g4calc->logZ(theA));
295 
296  PartitionEntropy += G4Log(ProbDegeneracy) + TranslationalS;
297  _Entropy = PartitionEntropy;
298 
299  // And finally compute probability of fragment configuration
300  G4double exponent = PartitionEntropy-SCompound;
301  if (exponent > 300.0) exponent = 300.0;
302  return _Probability = G4Exp(exponent);
303 }
304 
306 {
307  // Degeneracy factors are statistical factors
308  // DegeneracyFactor for nucleon is (2S_n + 1)(2I_n + 1) = 4
309  G4double DegFactor = 0;
310  if (A > 4) DegFactor = 1.0;
311  else if (A == 1) DegFactor = 4.0; // nucleon
312  else if (A == 2) DegFactor = 3.0; // Deuteron
313  else if (A == 3) DegFactor = 4.0; // Triton + He3
314  else if (A == 4) DegFactor = 1.0; // alpha
315  return DegFactor;
316 }
317 
319 // Gives fragments charges
320 {
321  std::vector<G4int> FragmentsZ;
322 
323  G4int ZBalance = 0;
324  do
325  {
327  G4int SumZ = 0;
328  for (unsigned int i = 0; i < _thePartition.size(); i++)
329  {
330  G4double ZMean;
331  G4double Af = _thePartition[i];
332  if (Af > 1.5 && Af < 4.5) ZMean = 0.5*Af;
333  else ZMean = Af*Z0/A0;
334  G4double ZDispersion = std::sqrt(Af * MeanT/CC);
335  G4int Zf;
336  do
337  {
338  Zf = static_cast<G4int>(G4RandGauss::shoot(ZMean,ZDispersion));
339  }
340  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
341  while (Zf < 0 || Zf > Af);
342  FragmentsZ.push_back(Zf);
343  SumZ += Zf;
344  }
345  ZBalance = Z0 - SumZ;
346  }
347  // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
348  while (std::abs(ZBalance) > 1);
349  FragmentsZ[0] += ZBalance;
350 
351  G4StatMFChannel * theChannel = new G4StatMFChannel;
352  for (unsigned int i = 0; i < _thePartition.size(); i++)
353  {
354  theChannel->CreateFragment(_thePartition[i],FragmentsZ[i]);
355  }
356 
357  return theChannel;
358 }
G4bool operator==(const G4StatMFMicroPartition &right) const
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4double logZ(G4int Z) const
Definition: G4Pow.hh:149
G4double GetDegeneracyFactor(G4int A)
G4double Z13(G4int Z) const
Definition: G4Pow.hh:132
G4double A13(G4double A) const
Definition: G4Pow.cc:138
static constexpr double MeV
Definition: G4SIunits.hh:214
static G4double GetKappaCoulomb()
G4double InvLevelDensity(G4double Af)
#define G4endl
Definition: G4ios.hh:61
static G4double GetE0()
static G4double GetCoulomb()
G4double G4Log(G4double x)
Definition: G4Log.hh:230
G4StatMFChannel * ChooseZ(G4int A0, G4int Z0, G4double MeanT)
static G4double Getr0()
void CreateFragment(G4int A, G4int Z)
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
static constexpr double fermi
Definition: G4SIunits.hh:103
static G4Pow * GetInstance()
Definition: G4Pow.cc:57
std::vector< G4int > _thePartition
static constexpr double elm_coupling
G4StatMFMicroPartition & operator=(const G4StatMFMicroPartition &right)
std::vector< G4double > _theCoulombFreeEnergy
G4double CalcPartitionTemperature(G4double U, G4double FreeInternalE0)
G4double GetPartitionEnergy(G4double T)
double A(double temperature)
ThreeVector shoot(const G4int Ap, const G4int Af)
static G4double Beta(G4double T)
G4double CalcPartitionProbability(G4double U, G4double FreeInternalE0, G4double SCompound)
int G4int
Definition: G4Types.hh:78
Definition: G4Pow.hh:56
G4GLOB_DLL std::ostream G4cout
G4bool operator!=(const G4StatMFMicroPartition &right) const
static constexpr double pi
Definition: G4SIunits.hh:75
static const G4double eps
static G4double DBetaDT(G4double T)
G4double Z23(G4int Z) const
Definition: G4Pow.hh:137
static G4double GetGamma0()