ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4StatMFMicroCanonical.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4StatMFMicroCanonical.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 //
28 // Hadronic Process: Nuclear De-excitations
29 // by V. Lara
30 
31 #include <numeric>
32 
34 #include "G4PhysicalConstants.hh"
35 #include "G4SystemOfUnits.hh"
36 #include "G4HadronicException.hh"
37 #include "G4Pow.hh"
38 
39 // constructor
41 {
42  // Perform class initialization
43  Initialize(theFragment);
44 }
45 
46 // destructor
48 {
49  // garbage collection
50  if (!_ThePartitionManagerVector.empty()) {
51  std::for_each(_ThePartitionManagerVector.begin(),
53  DeleteFragment());
54  }
55 }
56 
58 {
59 
60  std::vector<G4StatMFMicroManager*>::iterator it;
61 
62  // Excitation Energy
63  G4double U = theFragment.GetExcitationEnergy();
64 
65  G4int A = theFragment.GetA_asInt();
66  G4int Z = theFragment.GetZ_asInt();
67  G4double x = 1.0 - 2.0*Z/G4double(A);
68  G4Pow* g4calc = G4Pow::GetInstance();
69 
70  // Configuration temperature
71  G4double TConfiguration = std::sqrt(8.0*U/G4double(A));
72 
73  // Free internal energy at Temperature T = 0
74  __FreeInternalE0 = A*(
75  // Volume term (for T = 0)
77  // Symmetry term
79  ) +
80  // Surface term (for T = 0)
81  G4StatMFParameters::GetBeta0()*g4calc->Z23(A) +
82  // Coulomb term
83  elm_coupling*0.6*Z*Z/(G4StatMFParameters::Getr0()*g4calc->Z13(A));
84 
85  // Statistical weight
86  G4double W = 0.0;
87 
88  // Mean breakup multiplicity
89  __MeanMultiplicity = 0.0;
90 
91  // Mean channel temperature
92  __MeanTemperature = 0.0;
93 
94  // Mean channel entropy
95  __MeanEntropy = 0.0;
96 
97  // Calculate entropy of compound nucleus
98  G4double SCompoundNucleus = CalcEntropyOfCompoundNucleus(theFragment,TConfiguration);
99 
100  // Statistical weight of compound nucleus
101  _WCompoundNucleus = 1.0;
102 
103  W += _WCompoundNucleus;
104 
105  // Maximal fragment multiplicity allowed in direct simulation
107  if (A > 110) MaxMult -= 1;
108 
109  for (G4int im = 2; im <= MaxMult; im++) {
110  G4StatMFMicroManager * aMicroManager =
111  new G4StatMFMicroManager(theFragment,im,__FreeInternalE0,SCompoundNucleus);
112  _ThePartitionManagerVector.push_back(aMicroManager);
113  }
114 
115  // W is the total probability
116  W = std::accumulate(_ThePartitionManagerVector.begin(),
118  W, [](const G4double& running_total,
119  G4StatMFMicroManager*& manager)
120  {
121  return running_total + manager->GetProbability();
122  } );
123 
124  // Normalization of statistical weights
125  for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it)
126  {
127  (*it)->Normalize(W);
128  }
129 
130  _WCompoundNucleus /= W;
131 
133  __MeanTemperature += TConfiguration * _WCompoundNucleus;
134  __MeanEntropy += SCompoundNucleus * _WCompoundNucleus;
135 
136  for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it)
137  {
138  __MeanMultiplicity += (*it)->GetMeanMultiplicity();
139  __MeanTemperature += (*it)->GetMeanTemperature();
140  __MeanEntropy += (*it)->GetMeanEntropy();
141  }
142 
143  return;
144 }
145 
147  G4double T)
148 {
149  G4int A = theFragment.GetA_asInt();
150  G4int Z = theFragment.GetZ_asInt();
152 
153  G4double InvLevelDensityPar = G4StatMFParameters::GetEpsilon0()
154  *(1.0 + 3.0/G4double(A-1));
155 
156  G4double VolumeTerm = (-G4StatMFParameters::GetE0()+T*T/InvLevelDensityPar)*A;
157 
158  G4double SymmetryTerm = G4StatMFParameters::GetGamma0()
159  *(A - 2*Z)*(A - 2*Z)/G4double(A);
160 
161  G4double SurfaceTerm = (G4StatMFParameters::Beta(T)
162  - T*G4StatMFParameters::DBetaDT(T))*A13*A13;
163 
164  G4double CoulombTerm = elm_coupling*0.6*Z*Z/(G4StatMFParameters::Getr0()*A13);
165 
166  return VolumeTerm + SymmetryTerm + SurfaceTerm + CoulombTerm;
167 }
168 
169 G4double
171  G4double & TConf)
172  // Calculates Temperature and Entropy of compound nucleus
173 {
174  G4int A = theFragment.GetA_asInt();
175  G4double U = theFragment.GetExcitationEnergy();
177 
178  G4double Ta = std::max(std::sqrt(U/(0.125*A)),0.0012*MeV);
179  G4double Tb = Ta;
180 
181  G4double ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Ta);
182  G4double Da = (U+__FreeInternalE0-ECompoundNucleus)/U;
183  G4double Db = 0.0;
184 
185  G4double InvLevelDensity = CalcInvLevelDensity(A);
186 
187  // bracketing the solution
188  if (Da == 0.0) {
189  TConf = Ta;
190  return 2*Ta*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Ta)*A13*A13;
191  } else if (Da < 0.0) {
192  do {
193  Tb -= 0.5*Tb;
194  ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
195  Db = (U+__FreeInternalE0-ECompoundNucleus)/U;
196  } while (Db < 0.0);
197  } else {
198  do {
199  Tb += 0.5*Tb;
200  ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
201  Db = (U+__FreeInternalE0-ECompoundNucleus)/U;
202  } while (Db > 0.0);
203  }
204 
205  G4double eps = 1.0e-14 * std::abs(Tb-Ta);
206 
207  for (G4int i = 0; i < 1000; i++) {
208  G4double Tc = (Ta+Tb)*0.5;
209  if (std::abs(Ta-Tb) <= eps) {
210  TConf = Tc;
211  return 2*Tc*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Tc)*A13*A13;
212  }
213  ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tc);
214  G4double Dc = (U+__FreeInternalE0-ECompoundNucleus)/U;
215 
216  if (Dc == 0.0) {
217  TConf = Tc;
218  return 2*Tc*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Tc)*A13*A13;
219  }
220 
221  if (Da*Dc < 0.0) {
222  Tb = Tc;
223  Db = Dc;
224  } else {
225  Ta = Tc;
226  Da = Dc;
227  }
228  }
229 
230  G4cout <<
231  "G4StatMFMicrocanoncal::CalcEntropyOfCompoundNucleus: I can't calculate the temperature"
232  << G4endl;
233 
234  return 0.0;
235 }
236 
238  // Choice of fragment atomic numbers and charges
239 {
240  // We choose a multiplicity (1,2,3,...) and then a channel
241  G4double RandNumber = G4UniformRand();
242 
243  if (RandNumber < _WCompoundNucleus) {
244 
245  G4StatMFChannel * aChannel = new G4StatMFChannel;
246  aChannel->CreateFragment(theFragment.GetA_asInt(),theFragment.GetZ_asInt());
247  return aChannel;
248 
249  } else {
250 
251  G4double AccumWeight = _WCompoundNucleus;
252  std::vector<G4StatMFMicroManager*>::iterator it;
253  for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it) {
254  AccumWeight += (*it)->GetProbability();
255  if (RandNumber < AccumWeight) {
256  return (*it)->ChooseChannel(theFragment.GetA_asInt(),theFragment.GetZ_asInt(),__MeanTemperature);
257  }
258  }
259  throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroCanonical::ChooseAandZ: wrong normalization!");
260  }
261 
262  return 0;
263 }
264 
266 {
267  G4double res = 0.0;
268  if (anA > 1) {
269  res = G4StatMFParameters::GetEpsilon0()*(1.0+3.0/(anA - 1.0));
270  }
271  return res;
272 }