Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4CompetitiveFission.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// Hadronic Process: Nuclear De-excitations
28// by V. Lara (Oct 1998)
29//
30// J. M. Quesada (March 2009). Bugs fixed:
31// - Full relativistic calculation (Lorentz boosts)
32// - Fission pairing energy is included in fragment excitation energies
33// Now Energy and momentum are conserved in fission
34
37#include "G4ParticleMomentum.hh"
38#include "G4NuclearLevelData.hh"
39#include "G4VFissionBarrier.hh"
40#include "G4FissionBarrier.hh"
44#include "G4Pow.hh"
45#include "Randomize.hh"
46#include "G4RandomDirection.hh"
48
50{
51 theFissionBarrierPtr = new G4FissionBarrier;
52 myOwnFissionBarrier = true;
53
54 theFissionProbabilityPtr = new G4FissionProbability;
55 myOwnFissionProbability = true;
56
57 theLevelDensityPtr = new G4FissionLevelDensityParameter;
58 myOwnLevelDensity = true;
59
60 maxKineticEnergy = fissionBarrier = fissionProbability = 0.0;
62}
63
65{
66 if (myOwnFissionBarrier) delete theFissionBarrierPtr;
67 if (myOwnFissionProbability) delete theFissionProbabilityPtr;
68 if (myOwnLevelDensity) delete theLevelDensityPtr;
69}
70
72{
73 G4int Z = fragment->GetZ_asInt();
74 G4int A = fragment->GetA_asInt();
75 fissionProbability = 0.0;
76 // Saddle point excitation energy ---> A = 65
77 if (A >= 65 && Z > 16) {
78 G4double exEnergy = fragment->GetExcitationEnergy() -
79 pairingCorrection->GetFissionPairingCorrection(A, Z);
80
81 if (exEnergy > 0.0) {
82 fissionBarrier = theFissionBarrierPtr->FissionBarrier(A, Z, exEnergy);
83 maxKineticEnergy = exEnergy - fissionBarrier;
84 fissionProbability =
85 theFissionProbabilityPtr->EmissionProbability(*fragment,
86 maxKineticEnergy);
87 }
88 }
89 return fissionProbability;
90}
91
93{
94 G4Fragment * Fragment1 = nullptr;
95 // Nucleus data
96 // Atomic number of nucleus
97 G4int A = theNucleus->GetA_asInt();
98 // Charge of nucleus
99 G4int Z = theNucleus->GetZ_asInt();
100 // Excitation energy (in MeV)
101 G4double U = theNucleus->GetExcitationEnergy();
102 G4double pcorr = pairingCorrection->GetFissionPairingCorrection(A,Z);
103 if (U <= pcorr) { return Fragment1; }
104
105 // Atomic Mass of Nucleus (in MeV)
106 G4double M = theNucleus->GetGroundStateMass();
107
108 // Nucleus Momentum
109 G4LorentzVector theNucleusMomentum = theNucleus->GetMomentum();
110
111 // Calculate fission parameters
112 theParam.DefineParameters(A, Z, U-pcorr, fissionBarrier);
113
114 // First fragment
115 G4int A1 = 0;
116 G4int Z1 = 0;
117 G4double M1 = 0.0;
118
119 // Second fragment
120 G4int A2 = 0;
121 G4int Z2 = 0;
122 G4double M2 = 0.0;
123
124 G4double FragmentsExcitationEnergy = 0.0;
125 G4double FragmentsKineticEnergy = 0.0;
126
127 G4int Trials = 0;
128 do {
129
130 // First fragment
131 A1 = FissionAtomicNumber(A);
132 Z1 = FissionCharge(A, Z, A1);
134
135 // Second Fragment
136 A2 = A - A1;
137 Z2 = Z - Z1;
138 if (A2 < 1 || Z2 < 0 || Z2 > A2) {
139 FragmentsExcitationEnergy = -1.0;
140 continue;
141 }
143 // Maximal Kinetic Energy (available energy for fragments)
144 G4double Tmax = M + U - M1 - M2 - pcorr;
145
146 // Check that fragment masses are less or equal than total energy
147 if (Tmax < 0.0) {
148 FragmentsExcitationEnergy = -1.0;
149 continue;
150 }
151
152 FragmentsKineticEnergy = FissionKineticEnergy( A , Z,
153 A1, Z1,
154 A2, Z2,
155 U , Tmax);
156
157 // Excitation Energy
158 // FragmentsExcitationEnergy = Tmax - FragmentsKineticEnergy;
159 // JMQ 04/03/09 BUG FIXED: in order to fulfill energy conservation the
160 // fragments carry the fission pairing energy in form of
161 // excitation energy
162
163 FragmentsExcitationEnergy =
164 Tmax - FragmentsKineticEnergy + pcorr;
165
166 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
167 } while (FragmentsExcitationEnergy < 0.0 && ++Trials < 100);
168
169 if (FragmentsExcitationEnergy <= 0.0) {
170 throw G4HadronicException(__FILE__, __LINE__,
171 "G4CompetitiveFission::BreakItUp: Excitation energy for fragments < 0.0!");
172 }
173
174 // Fragment 1
175 M1 += FragmentsExcitationEnergy * A1/static_cast<G4double>(A);
176 // Fragment 2
177 M2 += FragmentsExcitationEnergy * A2/static_cast<G4double>(A);
178 // primary
179 M += U;
180
181 G4double etot1 = ((M - M2)*(M + M2) + M1*M1)/(2*M);
182 G4ParticleMomentum Momentum1 =
183 std::sqrt((etot1 - M1)*(etot1+M1))*G4RandomDirection();
184 G4LorentzVector FourMomentum1(Momentum1, etot1);
185 FourMomentum1.boost(theNucleusMomentum.boostVector());
186
187 // Create Fragments
188 Fragment1 = new G4Fragment( A1, Z1, FourMomentum1);
189 theNucleusMomentum -= FourMomentum1;
190 theNucleus->SetZandA_asInt(Z2, A2);
191 theNucleus->SetMomentum(theNucleusMomentum);
192 return Fragment1;
193}
194
195G4int
196G4CompetitiveFission::FissionAtomicNumber(G4int A)
197 // Calculates the atomic number of a fission product
198{
199
200 // For Simplicity reading code
201 G4int A1 = theParam.GetA1();
202 G4int A2 = theParam.GetA2();
203 G4double As = theParam.GetAs();
204 G4double Sigma2 = theParam.GetSigma2();
205 G4double SigmaS = theParam.GetSigmaS();
206 G4double w = theParam.GetW();
207
208 G4double C2A = A2 + 3.72*Sigma2;
209 G4double C2S = As + 3.72*SigmaS;
210
211 G4double C2 = 0.0;
212 if (w > 1000.0 ) { C2 = C2S; }
213 else if (w < 0.001) { C2 = C2A; }
214 else { C2 = std::max(C2A,C2S); }
215
216 G4double C1 = A-C2;
217 if (C1 < 30.0) {
218 C2 = A-30.0;
219 C1 = 30.0;
220 }
221
222 G4double Am1 = (As + A1)*0.5;
223 G4double Am2 = (A1 + A2)*0.5;
224
225 // Get Mass distributions as sum of symmetric and asymmetric Gasussians
226 G4double Mass1 = MassDistribution(As,A);
227 G4double Mass2 = MassDistribution(Am1,A);
228 G4double Mass3 = MassDistribution(G4double(A1),A);
229 G4double Mass4 = MassDistribution(Am2,A);
230 G4double Mass5 = MassDistribution(G4double(A2),A);
231 // get maximal value among Mass1,...,Mass5
232 G4double MassMax = Mass1;
233 if (Mass2 > MassMax) { MassMax = Mass2; }
234 if (Mass3 > MassMax) { MassMax = Mass3; }
235 if (Mass4 > MassMax) { MassMax = Mass4; }
236 if (Mass5 > MassMax) { MassMax = Mass5; }
237
238 // Sample a fragment mass number, which lies between C1 and C2
239 G4double xm;
240 G4double Pm;
241 do {
242 xm = C1+G4UniformRand()*(C2-C1);
243 Pm = MassDistribution(xm,A);
244 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
245 } while (MassMax*G4UniformRand() > Pm);
246 G4int ires = G4lrint(xm);
247
248 return ires;
249}
250
252G4CompetitiveFission::MassDistribution(G4double x, G4int A)
253 // This method gives mass distribution F(x) = F_{asym}(x)+w*F_{sym}(x)
254 // which consist of symmetric and asymmetric sum of gaussians components.
255{
256 G4double y0 = (x-theParam.GetAs())/theParam.GetSigmaS();
257 G4double Xsym = LocalExp(y0);
258
259 G4double y1 = (x - theParam.GetA1())/theParam.GetSigma1();
260 G4double y2 = (x - theParam.GetA2())/theParam.GetSigma2();
261 G4double z1 = (x - A + theParam.GetA1())/theParam.GetSigma1();
262 G4double z2 = (x - A + theParam.GetA2())/theParam.GetSigma2();
263 G4double Xasym = LocalExp(y1) + LocalExp(y2)
264 + 0.5*(LocalExp(z1) + LocalExp(z2));
265
266 G4double res;
267 G4double w = theParam.GetW();
268 if (w > 1000) { res = Xsym; }
269 else if (w < 0.001) { res = Xasym; }
270 else { res = w*Xsym+Xasym; }
271 return res;
272}
273
274G4int G4CompetitiveFission::FissionCharge(G4int A, G4int Z, G4double Af)
275 // Calculates the charge of a fission product for a given atomic number Af
276{
277 static const G4double sigma = 0.6;
278 G4double DeltaZ = 0.0;
279 if (Af >= 134.0) { DeltaZ = -0.45; }
280 else if (Af <= (A-134.0)) { DeltaZ = 0.45; }
281 else { DeltaZ = -0.45*(Af-A*0.5)/(134.0-A*0.5); }
282
283 G4double Zmean = (Af/A)*Z + DeltaZ;
284
285 G4double theZ;
286 do {
287 theZ = G4RandGauss::shoot(Zmean,sigma);
288 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
289 } while (theZ < 1.0 || theZ > (Z-1.0) || theZ > Af);
290
291 return G4lrint(theZ);
292}
293
295G4CompetitiveFission::FissionKineticEnergy(G4int A, G4int Z,
296 G4int Af1, G4int /*Zf1*/,
297 G4int Af2, G4int /*Zf2*/,
298 G4double /*U*/, G4double Tmax)
299 // Gives the kinetic energy of fission products
300{
301 // Find maximal value of A for fragments
302 G4int AfMax = std::max(Af1,Af2);
303
304 // Weights for symmetric and asymmetric components
305 G4double Pas = 0.0;
306 if (theParam.GetW() <= 1000) {
307 G4double x1 = (AfMax-theParam.GetA1())/theParam.GetSigma1();
308 G4double x2 = (AfMax-theParam.GetA2())/theParam.GetSigma2();
309 Pas = 0.5*LocalExp(x1) + LocalExp(x2);
310 }
311
312 G4double Ps = 0.0;
313 if (theParam.GetW() >= 0.001) {
314 G4double xs = (AfMax-theParam.GetAs())/theParam.GetSigmaS();
315 Ps = theParam.GetW()*LocalExp(xs);
316 }
317 G4double Psy = (Pas + Ps > 0.0) ? Ps/(Pas+Ps) : 0.5;
318
319 // Fission fractions Xsy and Xas formed in symmetric and asymmetric modes
320 G4double PPas = theParam.GetSigma1() + 2.0 * theParam.GetSigma2();
321 G4double PPsy = theParam.GetW() * theParam.GetSigmaS();
322 G4double Xas = (PPas + PPsy > 0.0) ? PPas/(PPas+PPsy) : 0.5;
323 G4double Xsy = 1.0 - Xas;
324
325 // Average kinetic energy for symmetric and asymmetric components
326 G4double Eaverage = (0.1071*(Z*Z)/G4Pow::GetInstance()->Z13(A) + 22.2)*CLHEP::MeV;
327
328 // Compute maximal average kinetic energy of fragments and Energy Dispersion
329 G4double TaverageAfMax;
330 G4double ESigma = 10*CLHEP::MeV;
331 // Select randomly fission mode (symmetric or asymmetric)
332 if (G4UniformRand() > Psy) { // Asymmetric Mode
333 G4double A11 = theParam.GetA1()-0.7979*theParam.GetSigma1();
334 G4double A12 = theParam.GetA1()+0.7979*theParam.GetSigma1();
335 G4double A21 = theParam.GetA2()-0.7979*theParam.GetSigma2();
336 G4double A22 = theParam.GetA2()+0.7979*theParam.GetSigma2();
337 // scale factor
338 G4double ScaleFactor = 0.5*theParam.GetSigma1()*
339 (AsymmetricRatio(A,A11)+AsymmetricRatio(A,A12))+
340 theParam.GetSigma2()*(AsymmetricRatio(A,A21)+AsymmetricRatio(A,A22));
341 // Compute average kinetic energy for fragment with AfMax
342 TaverageAfMax = (Eaverage + 12.5 * Xsy) * (PPas/ScaleFactor) *
343 AsymmetricRatio(A,G4double(AfMax));
344
345 } else { // Symmetric Mode
346 G4double As0 = theParam.GetAs() + 0.7979*theParam.GetSigmaS();
347 // Compute average kinetic energy for fragment with AfMax
348 TaverageAfMax = (Eaverage - 12.5*CLHEP::MeV*Xas)
349 *SymmetricRatio(A, G4double(AfMax))/SymmetricRatio(A, As0);
350 ESigma = 8.0*CLHEP::MeV;
351 }
352
353 // Select randomly, in accordance with Gaussian distribution,
354 // fragment kinetic energy
356 G4int i = 0;
357 do {
358 KineticEnergy = G4RandGauss::shoot(TaverageAfMax, ESigma);
359 if (++i > 100) return Eaverage;
360 // Loop checking, 05-Aug-2015, Vladimir Ivanchenko
361 } while (KineticEnergy < Eaverage-3.72*ESigma ||
362 KineticEnergy > Eaverage+3.72*ESigma ||
363 KineticEnergy > Tmax);
364
365 return KineticEnergy;
366}
367
369{
370 if (myOwnFissionBarrier) delete theFissionBarrierPtr;
371 theFissionBarrierPtr = aBarrier;
372 myOwnFissionBarrier = false;
373}
374
375void
377{
378 if (myOwnFissionProbability) delete theFissionProbabilityPtr;
379 theFissionProbabilityPtr = aFissionProb;
380 myOwnFissionProbability = false;
381}
382
383void
385{
386 if (myOwnLevelDensity) delete theLevelDensityPtr;
387 theLevelDensityPtr = aLevelDensity;
388 myOwnLevelDensity = false;
389}
390
double A(double temperature)
#define A22
#define A12
#define A21
#define A11
G4ThreeVector G4RandomDirection()
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
const double C2
#define C1
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
void SetEmissionStrategy(G4VEmissionProbability *aFissionProb)
void SetLevelDensityParameter(G4VLevelDensityParameter *aLevelDensity)
G4double GetEmissionProbability(G4Fragment *theNucleus) override
void SetFissionBarrier(G4VFissionBarrier *aBarrier)
G4Fragment * EmittedFragment(G4Fragment *theNucleus) override
G4double GetAs(void) const
G4double GetSigma1(void) const
G4double GetW(void) const
G4int GetA1(void) const
G4double GetSigmaS(void) const
void DefineParameters(G4int A, G4int Z, G4double ExEnergy, G4double FissionBarrier)
G4int GetA2(void) const
G4double GetSigma2(void) const
G4double GetGroundStateMass() const
Definition: G4Fragment.hh:280
G4double GetExcitationEnergy() const
Definition: G4Fragment.hh:275
const G4LorentzVector & GetMomentum() const
Definition: G4Fragment.hh:299
G4int GetZ_asInt() const
Definition: G4Fragment.hh:263
void SetMomentum(const G4LorentzVector &value)
Definition: G4Fragment.hh:304
void SetZandA_asInt(G4int Znew, G4int Anew)
Definition: G4Fragment.hh:268
G4int GetA_asInt() const
Definition: G4Fragment.hh:258
G4PairingCorrection * GetPairingCorrection()
static G4NuclearLevelData * GetInstance()
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4double GetFissionPairingCorrection(G4int A, G4int Z) const
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
G4double Z13(G4int Z) const
Definition: G4Pow.hh:123
virtual G4double EmissionProbability(const G4Fragment &fragment, G4double anEnergy)
virtual G4double FissionBarrier(G4int A, G4int Z, G4double U) const =0
int G4lrint(double ad)
Definition: templates.hh:134