ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4CompetitiveFission.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4CompetitiveFission.cc
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 
35 #include "G4CompetitiveFission.hh"
36 #include "G4PairingCorrection.hh"
37 #include "G4ParticleMomentum.hh"
38 #include "G4NuclearLevelData.hh"
39 #include "G4VFissionBarrier.hh"
40 #include "G4FissionBarrier.hh"
41 #include "G4FissionProbability.hh"
44 #include "G4Pow.hh"
45 #include "Randomize.hh"
46 #include "G4RandomDirection.hh"
47 #include "G4PhysicalConstants.hh"
48 
50 {
52  myOwnFissionBarrier = true;
53 
56 
58  myOwnLevelDensity = true;
59 
62 }
63 
65 {
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() -
80 
81  if (exEnergy > 0.0) {
83  maxKineticEnergy = exEnergy - fissionBarrier;
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();
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 
195 G4int
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 
251 G4double
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 {
257  G4double Xsym = LocalExp(y0);
258 
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 
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 
294 G4double
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
337  // scale factor
338  G4double ScaleFactor = 0.5*theParam.GetSigma1()*
339  (AsymmetricRatio(A,A11)+AsymmetricRatio(A,A12))+
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
355  G4double KineticEnergy;
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 {
371  theFissionBarrierPtr = aBarrier;
372  myOwnFissionBarrier = false;
373 }
374 
375 void
377 {
379  theFissionProbabilityPtr = aFissionProb;
380  myOwnFissionProbability = false;
381 }
382 
383 void
385 {
387  theLevelDensityPtr = aLevelDensity;
388  myOwnLevelDensity = false;
389 }
390