Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// by V. Lara
27// --------------------------------------------------------------------
28//
29// Modified:
30// 25.07.08 I.Pshenichnov (in collaboration with Alexander Botvina and Igor
31// Mishustin (FIAS, Frankfurt, INR, Moscow and Kurchatov Institute,
32// Moscow, pshenich@fias.uni-frankfurt.de) fixed infinite loop for
33// a fagment with Z=A; fixed memory leak
34// 13.08.25 V.Ivanchenko rewrite
35
36
39#include "G4SystemOfUnits.hh"
40#include "G4Pow.hh"
41
42// constructor
44{
45 theTemp = new G4StatMFMacroTemperature();
46 fClusters.reserve(220);
47 fAcumMultiplicity.reserve(220);
48
49 // Get memory for clusters
50 fClusters.push_back(new G4StatMFMacroNucleon);
51 fClusters.push_back(new G4StatMFMacroBiNucleon);
52 fClusters.push_back(new G4StatMFMacroTriNucleon);
53 fClusters.push_back(new G4StatMFMacroTetraNucleon);
54}
55
56// destructor
58{
59 // garbage collection
60 if (!fClusters.empty()) {
61 for(auto const & p : fClusters) { delete p; }
62 }
63 delete theTemp;
64}
65
66// Initialization method
68{
73
74 G4int A = theFragment.GetA_asInt();
75 G4int Z = theFragment.GetZ_asInt();
76 G4double x = 1.0 - (2*Z)/G4double(A);
77 G4Pow* g4calc = G4Pow::GetInstance();
78 G4double a13 = g4calc->Z13(A);
79
80 // Free Internal energy at T = 0
81 pFreeInternalE0 = A*(Gamma0*x*x - E0) // Symmetry term & Volume term (for T = 0)
82 + Beta0*a13*a13 + // Surface term (for T = 0)
83 0.6*CLHEP::elm_coupling*(Z*Z)/(R0*a13); // Coulomb term
84
85 G4int n = (G4int)fClusters.size();
86 for (G4int i = n; i < A; ++i) {
87 fClusters.push_back(new G4StatMFMacroMultiNucleon(i+1)); // Size 5 ... A
88 }
89 // Excitation Energy
90 G4double U = theFragment.GetExcitationEnergy();
91
92 // Fragment Multiplicity
93 G4double FragMult = std::max((1.0+2.31*(U/CLHEP::MeV - 3.5*A))/100.0, 2.0);
94
95 // Parameter Kappa
96 fKappa = (1.0 + CLHEP::elm_coupling*(g4calc->A13(FragMult) - 1.0)/(R0*a13));
97 fKappa = fKappa*fKappa*fKappa - 1.0;
98
99 theTemp->Initialise(A, Z, U, pFreeInternalE0, fKappa, &fClusters);
100
101 pMeanTemperature = theTemp->CalcTemperature();
102 fChemPotentialNu = theTemp->GetChemicalPotentialNu();
103 fChemPotentialMu = theTemp->GetChemicalPotentialMu();
104 pMeanMultiplicity = theTemp->GetMeanMultiplicity();
105 pMeanEntropy = theTemp->GetEntropy();
106}
107
108// --------------------------------------------------------------------------
109
111// Calculate total fragments multiplicity, fragment atomic numbers and charges
112{
113 G4int A = theFragment.GetA_asInt();
114 G4int Z = theFragment.GetZ_asInt();
115
116 std::vector<G4int> ANumbers(A);
117
118 G4double Multiplicity = ChooseA(A, ANumbers);
119
120 std::vector<G4int> FragmentsA;
121
122 G4int i = 0;
123 for (i = 0; i < A; i++)
124 {
125 for (G4int j = 0; j < ANumbers[i]; j++) FragmentsA.push_back(i+1);
126 }
127
128 // Sort fragments in decreasing order
129 G4int im = 0;
130 for (G4int j = 0; j < Multiplicity; j++)
131 {
132 G4int FragmentsAMax = 0;
133 im = j;
134 for (i = j; i < Multiplicity; ++i)
135 {
136 if (FragmentsA[i] <= FragmentsAMax) { continue; }
137 else
138 {
139 im = i;
140 FragmentsAMax = FragmentsA[im];
141 }
142 }
143 if (im != j)
144 {
145 FragmentsA[im] = FragmentsA[j];
146 FragmentsA[j] = FragmentsAMax;
147 }
148 }
149 return ChooseZ(Z,FragmentsA);
150}
151
152G4double G4StatMFMacroCanonical::ChooseA(G4int A, std::vector<G4int>& ANumbers)
153 // Determines fragments multiplicities and compute total fragment multiplicity
154{
155 G4double multiplicity = 0.0;
156
157 fAcumMultiplicity.resize(A);
158 for (G4int i=0; i<A; ++i) {
159 G4double x = fClusters[i]->GetMeanMultiplicity();
160 multiplicity += x;
161 fAcumMultiplicity[i] = multiplicity;
162 }
163
164 G4int CheckA;
165 do {
166 CheckA = -1;
167 G4int SumA = 0;
168 G4int ThisOne = 0;
169 multiplicity = 0.0;
170 ANumbers.resize(A, 0);
171 do {
173 for (G4int i = 0; i < A; ++i) {
174 if (RandNumber < fAcumMultiplicity[i]) {
175 ThisOne = i;
176 break;
177 }
178 }
179 multiplicity++;
180 ANumbers[ThisOne] = ANumbers[ThisOne]+1;
181 SumA += ThisOne+1;
182 CheckA = A - SumA;
183
184 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
185 } while (CheckA > 0);
186
187 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
188 } while (CheckA < 0 || std::abs(pMeanMultiplicity - multiplicity) > std::sqrt(pMeanMultiplicity) + 0.5);
189
190 return multiplicity;
191}
192
193G4StatMFChannel* G4StatMFMacroCanonical::ChooseZ(G4int Z, std::vector<G4int>& FragmentsA)
194{
195 G4Pow* g4calc = G4Pow::GetInstance();
196 std::vector<G4int> FragmentsZ;
197
198 G4int DeltaZ = 0;
200 G4int multiplicity = (G4int)FragmentsA.size();
201
202 do {
203 FragmentsZ.clear();
204 G4int SumZ = 0;
205 for (G4int i = 0; i < multiplicity; ++i) {
206 G4int A = FragmentsA[i];
207 if (A <= 1) {
208 G4double RandNumber = G4UniformRand();
209 if (RandNumber < fClusters[0]->GetZARatio()) {
210 FragmentsZ.push_back(1);
211 SumZ += FragmentsZ[i];
212 }
213 else FragmentsZ.push_back(0);
214 }
215 else {
216 G4double RandZ;
218 + 2*CP*g4calc->Z23(FragmentsA[i]);
219 G4double ZMean;
220 if (FragmentsA[i] > 1 && FragmentsA[i] < 5) { ZMean = 0.5*FragmentsA[i]; }
221 else {
222 ZMean = FragmentsA[i]*(4.0*G4StatMFParameters::GetGamma0()
223 + fChemPotentialNu)/CC;
224 }
225 G4double ZDispersion = std::sqrt(FragmentsA[i]*pMeanTemperature/CC);
226 G4int z;
227 do {
228 RandZ = G4RandGauss::shoot(ZMean,ZDispersion);
229 z = G4lrint(RandZ);
230 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
231 } while (z < 0 || z > A);
232 FragmentsZ.push_back(z);
233 SumZ += z;
234 }
235 }
236 DeltaZ = Z - SumZ;
237 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
238 } while (std::abs(DeltaZ) > 1);
239
240 // DeltaZ can be 0, 1 or -1
241 G4int idx = 0;
242 if (DeltaZ < 0.0) {
243 while (FragmentsZ[idx] < 1) { ++idx; }
244 }
245 FragmentsZ[idx] += DeltaZ;
246
247 G4StatMFChannel* theChannel = new G4StatMFChannel();
248 for (G4int i = multiplicity-1; i >= 0; --i) {
249 theChannel->CreateFragment(FragmentsA[i], FragmentsZ[i]);
250 }
251
252 return theChannel;
253}
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
const G4double A[17]
#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 A13(G4double A) const
Definition G4Pow.cc:116
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) override
void Initialise(const G4Fragment &theFragment) override
static G4double GetBeta0()
static G4double GetE0()
static G4double GetGamma0()
static G4double GetCoulomb()
static G4double Getr0()
int G4lrint(double ad)
Definition templates.hh:134