Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4FermiConfigurationList.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 // $Id: G4VFermiBreakUp.cc,v 1.5 2006-06-29 20:13:13 gunter Exp $
27 // GEANT4 tag $Name: not supported by cvs2svn $
28 //
29 // Hadronic Process: Nuclear De-excitations
30 // by V. Lara (Nov 1998)
31 //
32 // Modifications:
33 // 01.04.2011 General cleanup by V.Ivanchenko - more clean usage of static
34 // 23.04.2011 V.Ivanchenko: make this class to be responsible for
35 // selection of decay channel and decay
36 
37 #include <set>
38 
40 #include "G4FermiFragmentsPool.hh"
41 #include "G4PhysicalConstants.hh"
42 #include "Randomize.hh"
43 #include "G4Pow.hh"
44 
45 const G4double G4FermiConfigurationList::Kappa = 6.0;
46 const G4double G4FermiConfigurationList::r0 = 1.3*CLHEP::fermi;
47 
49 {
50  thePool = G4FermiFragmentsPool::Instance();
51  g4pow = G4Pow::GetInstance();
52  Coef = 0.6*(CLHEP::elm_coupling/r0)/g4pow->Z13(1+G4int(Kappa));
53  ConstCoeff = g4pow->powN(r0/hbarc,3)*Kappa*std::sqrt(2.0/pi)/3.0;
54 
55  // 16 is the max number
56  nmax = 50;
57  NormalizedWeights.resize(nmax,0.0);
58 }
59 
61 {}
62 
63 G4double
64 G4FermiConfigurationList::CoulombBarrier(
65  const std::vector<const G4VFermiFragment*>& conf)
66 {
67  // Calculates Coulomb Barrier (MeV) for given channel with K fragments.
68  G4int SumA = 0;
69  G4int SumZ = 0;
70  G4double CoulombEnergy = 0.;
71  size_t nn = conf.size();
72  for (size_t i=0; i<nn; ++i) {
73  G4int z = conf[i]->GetZ();
74  G4int a = conf[i]->GetA();
75  CoulombEnergy += G4double(z*z)/g4pow->Z13(a);
76  SumA += a;
77  SumZ += z;
78  }
79  CoulombEnergy -= SumZ*SumZ/g4pow->Z13(SumA);
80  return -Coef * CoulombEnergy;
81 }
82 
83 G4double
84 G4FermiConfigurationList::DecayProbability(G4int A, G4double TotalE,
86  // Decay probability for a given channel with K fragments
87 {
88  // A: Atomic Weight
89  // TotalE: Total energy of nucleus
90 
91  G4double KineticEnergy = TotalE; // MeV
92  G4double ProdMass = 1.0;
93  G4double SumMass = 0.0;
94  G4double S_n = 1.0;
95  std::set<G4int> combSet;
96  std::multiset<G4int> combmSet;
97 
98  const std::vector<const G4VFermiFragment*> flist =
99  conf->GetFragmentList();
100 
101  // Number of fragments
102  G4int K = flist.size();
103 
104  for (G4int i=0; i<K; ++i) {
105  G4int a = flist[i]->GetA();
106  combSet.insert(a);
107  combmSet.insert(a);
108  G4double mass = flist[i]->GetFragmentMass();
109  ProdMass *= mass;
110  SumMass += mass;
111  // Spin factor S_n
112  S_n *= flist[i]->GetPolarization();
113  KineticEnergy -= mass + flist[i]->GetExcitationEnergy();
114  }
115 
116  // Check that there is enough energy to produce K fragments
117  KineticEnergy -= CoulombBarrier(flist);
118  if (KineticEnergy <= 0.0) { return 0.0; }
119 
120  G4double MassFactor = ProdMass/SumMass;
121  MassFactor *= std::sqrt(MassFactor);
122 
123  // This is the constant (doesn't depend on nucleus) part
124  G4double Coeff = g4pow->powN(ConstCoeff*A, K-1);
125 
126  //JMQ 111009 Bug fixed: gamma function for odd K was wrong by a factor 2
127  // new implementation explicitely according to standard properties of Gamma function
128  // Calculation of 1/Gamma(3(k-1)/2)
129  G4double Gamma = 1.0;
130  // G4double arg = 3.0*(K-1)/2.0 - 1.0;
131  // while (arg > 1.1)
132  // {
133  // Gamma *= arg;
134  // arg--;
135  // }
136  // if ((K-1)%2 == 1) Gamma *= std::sqrt(pi);
137 
138  if ((K-1)%2 != 1)
139 
140  {
141  G4double arg = 3.0*(K-1)/2.0 - 1.0;
142  while (arg > 1.1)
143  {
144  Gamma *= arg;
145  arg--;
146  }
147  }
148  else {
149  G4double n= 3.0*K/2.0-2.0;
150  G4double arg2=2*n-1;
151  while (arg2>1.1)
152  {
153  Gamma *= arg2;
154  arg2 -= 2;
155  }
156  Gamma *= std::sqrt(pi)/g4pow->powZ(2,n);
157  }
158  // end of new implementation of Gamma function
159 
160 
161  // Permutation Factor G_n
162  G4double G_n = 1.0;
163  for (std::set<G4int>::iterator itr = combSet.begin();
164  itr != combSet.end(); ++itr)
165  {
166  for (G4int ni = combmSet.count(*itr); ni > 1; ni--) { G_n *= ni; }
167  }
168 
169  G4double Weight = Coeff * MassFactor * (S_n / G_n) / Gamma;
170  Weight *= std::sqrt(g4pow->powN(KineticEnergy,3*(K-1)))/KineticEnergy;
171 
172  return Weight;
173 }
174 
177 {
178  // Calculate Momenta of K fragments
179  G4double M = theNucleus.GetMomentum().m();
180  const std::vector<const G4VFermiFragment*>* conf =
181  SelectConfiguration(theNucleus.GetZ_asInt(),
182  theNucleus.GetA_asInt(), M);
183 
184 
185  G4FragmentVector* theResult = new G4FragmentVector();
186  size_t nn = conf->size();
187  if(1 >= nn) {
188  theResult->push_back(new G4Fragment(theNucleus));
189  delete conf;
190  return theResult;
191  }
192 
193  G4ThreeVector boostVector = theNucleus.GetMomentum().boostVector();
194  std::vector<G4double> mr;
195  mr.reserve(nn);
196  for(size_t i=0; i<nn; ++i) {
197  mr.push_back( (*conf)[i]->GetTotalEnergy() );
198  }
199  std::vector<G4LorentzVector*>* mom = thePhaseSpace.Decay(M,mr);
200  if(!mom) {
201  delete conf;
202  return theResult;
203  }
204 
205  size_t nmom = mom->size();
206 
207  // Go back to the Lab Frame
208  if(0 < nmom) {
209  for (size_t j=0; j<nmom; ++j) {
210  G4LorentzVector* FourMomentum = (*mom)[j];
211 
212  // Lorentz boost
213  FourMomentum->boost(boostVector);
214 
215  G4FragmentVector* fragment = (*conf)[j]->GetFragment(*FourMomentum);
216 
217  size_t nfrag = fragment->size();
218  for (size_t k=0; k<nfrag; ++k) { theResult->push_back((*fragment)[k]); }
219  delete fragment;
220  delete (*mom)[j];
221  }
222  }
223 
224  delete mom;
225  delete conf;
226  return theResult;
227 }
228 
229 const std::vector<const G4VFermiFragment*>*
230 G4FermiConfigurationList::SelectConfiguration(G4int Z, G4int A, G4double mass)
231 {
232  std::vector<const G4VFermiFragment*>* res =
233  new std::vector<const G4VFermiFragment*>;
234  const std::vector<G4FermiConfiguration*>* conflist =
235  thePool->GetConfigurationList(Z, A, mass);
236  if(!conflist) { return res; }
237  size_t nn = conflist->size();
238  if(0 < nn) {
239  size_t idx = 0;
240  if(1 < nn) {
241  if(nn > nmax) {
242  nmax = nn;
243  NormalizedWeights.resize(nmax,0.0);
244  }
245  G4double prob = 0.0;
246  for(size_t i=0; i<nn; ++i) {
247  prob += DecayProbability(A, mass, (*conflist)[i]);
248  NormalizedWeights[i] = prob;
249  }
250  prob *= G4UniformRand();
251  for(idx=0; idx<nn; ++idx) {
252  if(NormalizedWeights[idx] >= prob) { break; }
253  }
254  }
255  const std::vector<const G4VFermiFragment*> flist =
256  (*conflist)[idx]->GetFragmentList();
257  size_t nf = flist.size();
258  for(size_t i=0; i<nf; ++i) { res->push_back(flist[i]); }
259  //G4cout << "FermiBreakUp: " << nn << " conf; selected idx= "
260  // << idx << " Nprod= " << nf << G4endl;
261  }
262  delete conflist;
263  return res;
264 }