Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4StatMFMicroCanonical.cc
Go to the documentation of this file.
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
35#include "G4SystemOfUnits.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(),
52 _ThePartitionManagerVector.end(),
53 DeleteFragment());
54 }
55}
56
57void G4StatMFMicroCanonical::Initialize(const G4Fragment & theFragment)
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
75 // Volume term (for T = 0)
77 // Symmetry term
79 ) +
80 // Surface term (for T = 0)
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
90
91 // Mean channel temperature
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(),
117 _ThePartitionManagerVector.end(),
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
132 __MeanMultiplicity += 1.0 * _WCompoundNucleus;
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
146G4double G4StatMFMicroCanonical::CalcFreeInternalEnergy(const G4Fragment & theFragment,
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
159 *(A - 2*Z)*(A - 2*Z)/G4double(A);
160
161 G4double SurfaceTerm = (G4StatMFParameters::Beta(T)
163
164 G4double CoulombTerm = elm_coupling*0.6*Z*Z/(G4StatMFParameters::Getr0()*A13);
165
166 return VolumeTerm + SymmetryTerm + SurfaceTerm + CoulombTerm;
167}
168
170G4StatMFMicroCanonical::CalcEntropyOfCompoundNucleus(const G4Fragment & theFragment,
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
265G4double G4StatMFMicroCanonical::CalcInvLevelDensity(G4int anA)
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}
#define A13
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
const G4double A[17]
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
G4double GetExcitationEnergy() const
G4int GetZ_asInt() const
G4int GetA_asInt() const
Definition G4Pow.hh:49
static G4Pow * GetInstance()
Definition G4Pow.cc:41
G4double Z13(G4int Z) const
Definition G4Pow.hh:123
G4double Z23(G4int Z) const
Definition G4Pow.hh:125
void CreateFragment(G4int A, G4int Z)
G4StatMFChannel * ChooseAandZ(const G4Fragment &theFragment)
G4StatMFMicroCanonical(const G4Fragment &theFragment)
static G4double DBetaDT(G4double T)
static G4double GetBeta0()
static G4double GetE0()
static G4double GetGamma0()
static G4double Beta(G4double T)
static G4double Getr0()
static G4double GetEpsilon0()
#define W
Definition crc32.c:85