Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// $Id$
28//
29// Hadronic Process: Nuclear De-excitations
30// by V. Lara
31
32#include <numeric>
33
36#include "G4SystemOfUnits.hh"
38#include "G4Pow.hh"
39
40// constructor
42{
43 // Perform class initialization
44 Initialize(theFragment);
45
46}
47
48
49// destructor
51{
52 // garbage collection
53 if (!_ThePartitionManagerVector.empty()) {
54 std::for_each(_ThePartitionManagerVector.begin(),
55 _ThePartitionManagerVector.end(),
56 DeleteFragment());
57 }
58}
59
60
61
62// Initialization method
63
64void G4StatMFMicroCanonical::Initialize(const G4Fragment & theFragment)
65{
66
67 std::vector<G4StatMFMicroManager*>::iterator it;
68
69 // Excitation Energy
70 G4double U = theFragment.GetExcitationEnergy();
71
72 G4int A = theFragment.GetA_asInt();
73 G4int Z = theFragment.GetZ_asInt();
74 G4double x = 1.0 - 2.0*Z/G4double(A);
75 G4Pow* g4pow = G4Pow::GetInstance();
76
77 // Configuration temperature
78 G4double TConfiguration = std::sqrt(8.0*U/G4double(A));
79
80 // Free internal energy at Temperature T = 0
81 __FreeInternalE0 = A*(
82 // Volume term (for T = 0)
84 // Symmetry term
86 ) +
87 // Surface term (for T = 0)
89 // Coulomb term
90 elm_coupling*(3.0/5.0)*Z*Z/(G4StatMFParameters::Getr0()*g4pow->Z13(A));
91
92 // Statistical weight
93 G4double W = 0.0;
94
95
96 // Mean breakup multiplicity
98
99 // Mean channel temperature
100 __MeanTemperature = 0.0;
101
102 // Mean channel entropy
103 __MeanEntropy = 0.0;
104
105 // Calculate entropy of compound nucleus
106 G4double SCompoundNucleus = CalcEntropyOfCompoundNucleus(theFragment,TConfiguration);
107
108 // Statistical weight of compound nucleus
109 _WCompoundNucleus = 1.0; // std::exp(SCompoundNucleus - SCompoundNucleus);
110
111 W += _WCompoundNucleus;
112
113
114
115 // Maximal fragment multiplicity allowed in direct simulation
117 if (A > 110) MaxMult -= 1;
118
119
120
121 for (G4int im = 2; im <= MaxMult; im++) {
122 G4StatMFMicroManager * aMicroManager =
123 new G4StatMFMicroManager(theFragment,im,__FreeInternalE0,SCompoundNucleus);
124 _ThePartitionManagerVector.push_back(aMicroManager);
125 }
126
127 // W is the total probability
128 W = std::accumulate(_ThePartitionManagerVector.begin(),
129 _ThePartitionManagerVector.end(),
130 W,SumProbabilities());
131
132 // Normalization of statistical weights
133 for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it)
134 {
135 (*it)->Normalize(W);
136 }
137
138 _WCompoundNucleus /= W;
139
140 __MeanMultiplicity += 1.0 * _WCompoundNucleus;
141 __MeanTemperature += TConfiguration * _WCompoundNucleus;
142 __MeanEntropy += SCompoundNucleus * _WCompoundNucleus;
143
144
145 for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it)
146 {
147 __MeanMultiplicity += (*it)->GetMeanMultiplicity();
148 __MeanTemperature += (*it)->GetMeanTemperature();
149 __MeanEntropy += (*it)->GetMeanEntropy();
150 }
151
152 return;
153}
154
155
156G4double G4StatMFMicroCanonical::CalcFreeInternalEnergy(const G4Fragment & theFragment,
157 G4double T)
158{
159 G4int A = theFragment.GetA_asInt();
160 G4int Z = theFragment.GetZ_asInt();
162
163 G4double InvLevelDensityPar = G4StatMFParameters::GetEpsilon0()*(1.0 + 3.0/G4double(A-1));
164
165 G4double VolumeTerm = (-G4StatMFParameters::GetE0()+T*T/InvLevelDensityPar)*A;
166
167 G4double SymmetryTerm = G4StatMFParameters::GetGamma0()*(A - 2*Z)*(A - 2*Z)/G4double(A);
168
170
171 G4double CoulombTerm = elm_coupling*(3.0/5.0)*Z*Z/(G4StatMFParameters::Getr0()*A13);
172
173 return VolumeTerm + SymmetryTerm + SurfaceTerm + CoulombTerm;
174}
175
177G4StatMFMicroCanonical::CalcEntropyOfCompoundNucleus(const G4Fragment & theFragment,
178 G4double & TConf)
179 // Calculates Temperature and Entropy of compound nucleus
180{
181 G4int A = theFragment.GetA_asInt();
182 // const G4double Z = theFragment.GetZ();
183 G4double U = theFragment.GetExcitationEnergy();
185
186 G4double Ta = std::max(std::sqrt(U/(0.125*A)),0.0012*MeV);
187 G4double Tb = Ta;
188
189 G4double ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Ta);
190 G4double Da = (U+__FreeInternalE0-ECompoundNucleus)/U;
191 G4double Db = 0.0;
192
193 G4double InvLevelDensity = CalcInvLevelDensity(static_cast<G4int>(A));
194
195 // bracketing the solution
196 if (Da == 0.0) {
197 TConf = Ta;
198 return 2*Ta*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Ta)*A13*A13;
199 } else if (Da < 0.0) {
200 do {
201 Tb -= 0.5*Tb;
202 ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
203 Db = (U+__FreeInternalE0-ECompoundNucleus)/U;
204 } while (Db < 0.0);
205 } else {
206 do {
207 Tb += 0.5*Tb;
208 ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tb);
209 Db = (U+__FreeInternalE0-ECompoundNucleus)/U;
210 } while (Db > 0.0);
211 }
212
213 G4double eps = 1.0e-14 * std::fabs(Tb-Ta);
214
215 for (G4int i = 0; i < 1000; i++) {
216 G4double Tc = (Ta+Tb)/2.0;
217 if (std::abs(Ta-Tb) <= eps) {
218 TConf = Tc;
219 return 2*Tc*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Tc)*A13*A13;
220 }
221 ECompoundNucleus = CalcFreeInternalEnergy(theFragment,Tc);
222 G4double Dc = (U+__FreeInternalE0-ECompoundNucleus)/U;
223
224 if (Dc == 0.0) {
225 TConf = Tc;
226 return 2*Tc*A/InvLevelDensity - G4StatMFParameters::DBetaDT(Tc)*A13*A13;
227 }
228
229 if (Da*Dc < 0.0) {
230 Tb = Tc;
231 Db = Dc;
232 } else {
233 Ta = Tc;
234 Da = Dc;
235 }
236 }
237
238 G4cerr <<
239 "G4StatMFMicrocanoncal::CalcEntropyOfCompoundNucleus: I can't calculate the temperature"
240 << G4endl;
241
242 return 0.0;
243}
244
246 // Choice of fragment atomic numbers and charges
247{
248 // We choose a multiplicity (1,2,3,...) and then a channel
249 G4double RandNumber = G4UniformRand();
250
251 if (RandNumber < _WCompoundNucleus) {
252
253 G4StatMFChannel * aChannel = new G4StatMFChannel;
254 aChannel->CreateFragment(theFragment.GetA_asInt(),theFragment.GetZ_asInt());
255 return aChannel;
256
257 } else {
258
259 G4double AccumWeight = _WCompoundNucleus;
260 std::vector<G4StatMFMicroManager*>::iterator it;
261 for (it = _ThePartitionManagerVector.begin(); it != _ThePartitionManagerVector.end(); ++it) {
262 AccumWeight += (*it)->GetProbability();
263 if (RandNumber < AccumWeight) {
264 return (*it)->ChooseChannel(theFragment.GetA(),theFragment.GetZ(),__MeanTemperature);
265 }
266 }
267 throw G4HadronicException(__FILE__, __LINE__, "G4StatMFMicroCanonical::ChooseAandZ: wrong normalization!");
268 }
269
270 return 0;
271}
272
273G4double G4StatMFMicroCanonical::CalcInvLevelDensity(G4int anA)
274{
275 // Calculate Inverse Density Level
276 // Epsilon0*(1 + 3 /(Af - 1))
277 if (anA == 1) return 0.0;
278 else return
279 G4StatMFParameters::GetEpsilon0()*(1.0+3.0/(anA - 1.0));
280}
#define A13
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
#define G4UniformRand()
Definition: Randomize.hh:53
G4double GetExcitationEnergy() const
Definition: G4Fragment.hh:235
G4double GetZ() const
Definition: G4Fragment.hh:278
G4int GetZ_asInt() const
Definition: G4Fragment.hh:223
G4double GetA() const
Definition: G4Fragment.hh:283
G4int GetA_asInt() const
Definition: G4Fragment.hh:218
Definition: G4Pow.hh:54
static G4Pow * GetInstance()
Definition: G4Pow.cc:50
G4double Z23(G4int Z)
Definition: G4Pow.hh:134
G4double Z13(G4int Z)
Definition: G4Pow.hh:110
void CreateFragment(G4int A, G4int Z)
G4StatMFChannel * ChooseAandZ(const G4Fragment &theFragment)
G4StatMFMicroCanonical(const G4Fragment &theFragment)
static G4double Getr0()
static G4double GetEpsilon0()
static G4double GetGamma0()
static G4double GetBeta0()
static G4double GetE0()
static G4double DBetaDT(const G4double T)
static G4double Beta(const G4double T)