Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4StatMFMacroCanonical.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// by V. Lara
30// --------------------------------------------------------------------
31//
32// Modified:
33// 25.07.08 I.Pshenichnov (in collaboration with Alexander Botvina and Igor
34// Mishustin (FIAS, Frankfurt, INR, Moscow and Kurchatov Institute,
35// Moscow, pshenich@fias.uni-frankfurt.de) fixed infinite loop for
36// a fagment with Z=A; fixed memory leak
37
40#include "G4SystemOfUnits.hh"
41#include "G4Pow.hh"
42
43// constructor
45{
46
47 // Get memory for clusters
48 _theClusters.push_back(new G4StatMFMacroNucleon); // Size 1
49 _theClusters.push_back(new G4StatMFMacroBiNucleon); // Size 2
50 _theClusters.push_back(new G4StatMFMacroTriNucleon); // Size 3
51 _theClusters.push_back(new G4StatMFMacroTetraNucleon); // Size 4
52 for (G4int i = 4; i < theFragment.GetA_asInt(); i++)
53 _theClusters.push_back(new G4StatMFMacroMultiNucleon(i+1)); // Size 5 ... A
54
55 // Perform class initialization
56 Initialize(theFragment);
57
58}
59
60// destructor
62{
63 // garbage collection
64 if (!_theClusters.empty())
65 {
66 std::for_each(_theClusters.begin(),_theClusters.end(),DeleteFragment());
67 }
68}
69
70// Initialization method
71void G4StatMFMacroCanonical::Initialize(const G4Fragment & theFragment)
72{
73
74 G4int A = theFragment.GetA_asInt();
75 G4int Z = theFragment.GetZ_asInt();
76 G4double x = 1.0 - 2.0*Z/G4double(A);
77 G4Pow* g4pow = G4Pow::GetInstance();
78
79 // Free Internal energy at T = 0
80 __FreeInternalE0 = A*( -G4StatMFParameters::GetE0() + // Volume term (for T = 0)
81 G4StatMFParameters::GetGamma0()*x*x) // Symmetry term
82 +
83 G4StatMFParameters::GetBeta0()*g4pow->Z23(A) + // Surface term (for T = 0)
84 (3.0/5.0)*elm_coupling*Z*Z/(G4StatMFParameters::Getr0()* // Coulomb term
85 g4pow->Z13(A));
86
87 CalculateTemperature(theFragment);
88
89 return;
90}
91
92void G4StatMFMacroCanonical::CalculateTemperature(const G4Fragment & theFragment)
93{
94 // Excitation Energy
95 G4double U = theFragment.GetExcitationEnergy();
96
97 G4int A = theFragment.GetA_asInt();
98 G4int Z = theFragment.GetZ_asInt();
99
100 // Fragment Multiplicity
101 G4double FragMult = std::max((1.0+(2.31/MeV)*(U/A - 3.5*MeV))*A/100.0, 2.0);
102
103
104 // Parameter Kappa
105 _Kappa = (1.0+elm_coupling*(std::pow(FragMult,1./3.)-1)/
107 _Kappa = _Kappa*_Kappa*_Kappa - 1.0;
108
109
110 G4StatMFMacroTemperature * theTemp = new
111 G4StatMFMacroTemperature(A,Z,U,__FreeInternalE0,_Kappa,&_theClusters);
112
114 _ChemPotentialNu = theTemp->GetChemicalPotentialNu();
115 _ChemPotentialMu = theTemp->GetChemicalPotentialMu();
117 __MeanEntropy = theTemp->GetEntropy();
118
119 delete theTemp;
120
121 return;
122}
123
124
125// --------------------------------------------------------------------------
126
128 // Calculate total fragments multiplicity, fragment atomic numbers and charges
129{
130 G4int A = theFragment.GetA_asInt();
131 G4int Z = theFragment.GetZ_asInt();
132
133 std::vector<G4int> ANumbers(A);
134
135 G4double Multiplicity = ChooseA(A,ANumbers);
136
137 std::vector<G4int> FragmentsA;
138
139 G4int i = 0;
140 for (i = 0; i < A; i++)
141 {
142 for (G4int j = 0; j < ANumbers[i]; j++) FragmentsA.push_back(i+1);
143 }
144
145 // Sort fragments in decreasing order
146 G4int im = 0;
147 for (G4int j = 0; j < Multiplicity; j++)
148 {
149 G4int FragmentsAMax = 0;
150 im = j;
151 for (i = j; i < Multiplicity; i++)
152 {
153 if (FragmentsA[i] <= FragmentsAMax) { continue; }
154 else
155 {
156 im = i;
157 FragmentsAMax = FragmentsA[im];
158 }
159 }
160
161 if (im != j)
162 {
163 FragmentsA[im] = FragmentsA[j];
164 FragmentsA[j] = FragmentsAMax;
165 }
166 }
167
168 return ChooseZ(Z,FragmentsA);
169}
170
171
172G4double G4StatMFMacroCanonical::ChooseA(G4int A, std::vector<G4int> & ANumbers)
173 // Determines fragments multiplicities and compute total fragment multiplicity
174{
175 G4double multiplicity = 0.0;
176 G4int i;
177
178 std::vector<G4double> AcumMultiplicity;
179 AcumMultiplicity.reserve(A);
180
181 AcumMultiplicity.push_back((*(_theClusters.begin()))->GetMeanMultiplicity());
182 for (std::vector<G4VStatMFMacroCluster*>::iterator it = _theClusters.begin()+1;
183 it != _theClusters.end(); ++it)
184 {
185 AcumMultiplicity.push_back((*it)->GetMeanMultiplicity()+AcumMultiplicity.back());
186 }
187
188 G4int CheckA;
189 do {
190 CheckA = -1;
191 G4int SumA = 0;
192 G4int ThisOne = 0;
193 multiplicity = 0.0;
194 for (i = 0; i < A; i++) ANumbers[i] = 0;
195 do {
197 for (i = 0; i < A; i++) {
198 if (RandNumber < AcumMultiplicity[i]) {
199 ThisOne = i;
200 break;
201 }
202 }
203 multiplicity++;
204 ANumbers[ThisOne] = ANumbers[ThisOne]+1;
205 SumA += ThisOne+1;
206 CheckA = A - SumA;
207
208 } while (CheckA > 0);
209
210 } while (CheckA < 0 || std::abs(__MeanMultiplicity - multiplicity) > std::sqrt(__MeanMultiplicity) + 1./2.);
211
212 return multiplicity;
213}
214
215
216G4StatMFChannel * G4StatMFMacroCanonical::ChooseZ(G4int & Z,
217 std::vector<G4int> & FragmentsA)
218 //
219{
220 G4Pow* g4pow = G4Pow::GetInstance();
221 std::vector<G4int> FragmentsZ;
222
223 G4int DeltaZ = 0;
224 G4double CP = (3./5.)*(elm_coupling/G4StatMFParameters::Getr0())*
225 (1.0 - 1.0/std::pow(1.0+G4StatMFParameters::GetKappaCoulomb(),1./3.));
226
227 G4int multiplicity = FragmentsA.size();
228
229 do
230 {
231 FragmentsZ.clear();
232 G4int SumZ = 0;
233 for (G4int i = 0; i < multiplicity; i++)
234 {
235 G4int A = FragmentsA[i];
236 if (A <= 1)
237 {
238 G4double RandNumber = G4UniformRand();
239 if (RandNumber < (*_theClusters.begin())->GetZARatio())
240 {
241 FragmentsZ.push_back(1);
242 SumZ += FragmentsZ[i];
243 }
244 else FragmentsZ.push_back(0);
245 }
246 else
247 {
248 G4double RandZ;
249 G4double CC = 8.0*G4StatMFParameters::GetGamma0()+2.0*CP*g4pow->Z23(FragmentsA[i]);
250 G4double ZMean;
251 if (FragmentsA[i] > 1 && FragmentsA[i] < 5) { ZMean = 0.5*FragmentsA[i]; }
252 else ZMean = FragmentsA[i]*(4.0*G4StatMFParameters::GetGamma0()+_ChemPotentialNu)/CC;
253 G4double ZDispersion = std::sqrt(FragmentsA[i]*__MeanTemperature/CC);
254 G4int z;
255 do
256 {
257 RandZ = G4RandGauss::shoot(ZMean,ZDispersion);
258 z = static_cast<G4int>(RandZ+0.5);
259 } while (z < 0 || z > A);
260 FragmentsZ.push_back(z);
261 SumZ += z;
262 }
263 }
264 DeltaZ = Z - SumZ;
265 }
266 while (std::abs(DeltaZ) > 1);
267
268 // DeltaZ can be 0, 1 or -1
269 G4int idx = 0;
270 if (DeltaZ < 0.0)
271 {
272 while (FragmentsZ[idx] < 1) { ++idx; }
273 }
274 FragmentsZ[idx] += DeltaZ;
275
276 G4StatMFChannel * theChannel = new G4StatMFChannel;
277 for (G4int i = multiplicity-1; i >= 0; i--)
278 {
279 theChannel->CreateFragment(FragmentsA[i],FragmentsZ[i]);
280 }
281
282 return theChannel;
283}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4UniformRand()
Definition: Randomize.hh:53
G4double GetExcitationEnergy() const
Definition: G4Fragment.hh:235
G4int GetZ_asInt() const
Definition: G4Fragment.hh:223
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)
G4StatMFMacroCanonical(G4Fragment const &theFragment)
G4StatMFChannel * ChooseAandZ(const G4Fragment &theFragment)
G4double GetChemicalPotentialMu(void) const
G4double GetChemicalPotentialNu(void) const
G4double GetMeanMultiplicity(void) const
static G4double Getr0()
static G4double GetGamma0()
static G4double GetKappaCoulomb()
static G4double GetBeta0()
static G4double GetE0()