ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VEmissionProbability.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4VEmissionProbability.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 // Hadronic Process: Nuclear De-excitations
27 // by V. Lara (Oct 1998)
28 //
29 // Modifications:
30 // 28.10.2010 V.Ivanchenko defined members in constructor and cleaned up
31 
33 #include "G4NuclearLevelData.hh"
34 #include "G4LevelManager.hh"
35 #include "G4DeexPrecoParameters.hh"
36 #include "Randomize.hh"
37 #include "G4Pow.hh"
38 
40  : OPTxs(3),pVerbose(1),theZ(Z),theA(A),resZ(0),resA(0),
41  pMass(0.0),pEvapMass(0.0),pResMass(0.0),fExc(0.0),fExcRes(0.0),
42  elimit(CLHEP::MeV),accuracy(0.02),fFD(false)
43 {
47  // G4cout << "G4VEvaporationProbability: Z= " << theZ << " A= " << theA
48  // << " M(GeV)= " << pEvapMass/1000. << G4endl;
49  length = nbin = 0;
50  emin = emax = eCoulomb = pProbability = probmax = 0.0;
51 }
52 
54 {}
55 
57 {
59  OPTxs = param->GetDeexModelType();
60  pVerbose = param->GetVerbose();
61  fFD = param->GetDiscreteExcitationFlag();
62 }
63 
65 {
66  if(nbins > 0) { length = nbins; }
67  if(de > 0.0) { elimit = de; }
68  if(eps > 0.0) { accuracy = eps; }
69 }
70 
72 {
73  return 0.0;
74 }
75 
77 {
78  return 0.0;
79 }
80 
82  G4double ehigh,
83  G4double cb)
84 {
85  pProbability = 0.0;
86  if(elow >= ehigh) { return pProbability; }
87 
88  emin = elow;
89  emax = ehigh;
90  eCoulomb = cb;
91 
92  G4double edelta = elimit;
93  nbin = (size_t)((emax - emin)/edelta) + 1;
94  const G4double edeltamin = 0.2*CLHEP::MeV;
95  const G4double edeltamax = 2*CLHEP::MeV;
96  if(nbin < 4) {
97  nbin = 4;
98  edelta = (emax - emin)/(G4double)nbin;
99  } else if(nbin > length) {
100  nbin = length;
101  }
102 
103  G4double x(emin), del, y;
104  G4double edelmicro= edelta*0.02;
105  probmax = ComputeProbability(x + edelmicro, eCoulomb);
106  G4double problast = probmax;
107  if(pVerbose > 2) {
108  G4cout << "### G4VEmissionProbability::IntegrateProbability: "
109  << " Emax= " << emax << " QB= " << cb << " nbin= " << nbin
110  << G4endl;
111  G4cout << " 0. E= " << emin << " prob= " << probmax << G4endl;
112  }
113  for(size_t i=1; i<=nbin; ++i) {
114  x += edelta;
115  if(x > emax) {
116  edelta += (emax - x);
117  x = emax;
118  }
119  G4bool endpoint = (std::abs(x - emax) < edelmicro) ? true : false;
120  G4double xx = endpoint ? x - edelmicro : x;
121  y = ComputeProbability(xx, eCoulomb);
122  if(pVerbose > 2) {
123  G4cout << " " << i << ". E= " << x << " prob= " << y
124  << " Edel= " << edelta << G4endl;
125  }
126  probmax = std::max(probmax, y);
127  del = (y + problast)*edelta*0.5;
128  pProbability += del;
129  // end of the loop
130  if(del < accuracy*pProbability || endpoint) { break; }
131  problast = y;
132 
133  // smart step definition
134  if(del != pProbability && del > 0.8*pProbability &&
135  0.7*edelta > edeltamin) {
136  edelta *= 0.7;
137  } else if(del < 0.1*pProbability && 1.5*edelta < edeltamax) {
138  edelta *= 1.5;
139  }
140  }
141 
142  if(pVerbose > 1) {
143  G4cout << " Probability= " << pProbability << " probmax= "
144  << probmax << G4endl;
145  }
146  return pProbability;
147 }
148 
150 {
151  static const G4double fact = 1.05;
152  probmax *= fact;
153 
154  if(pVerbose > 1) {
155  G4cout << "### G4VEmissionProbability::SampleEnergy: "
156  << " Emin= " << emin << " Emax= " << emax
157  << " probmax= " << probmax << G4endl;
158  }
159 
160  CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
161  const G4int nmax = 100;
162  G4double del = emax - emin;
163  G4double ekin, g;
164  G4int n = 0;
165  do {
166  ekin = del*rndm->flat() + emin;
167  ++n;
168  g = ComputeProbability(ekin, eCoulomb);
169  if(pVerbose > 2) {
170  G4cout << " " << n
171  << ". prob= " << g << " probmax= " << probmax
172  << " Ekin= " << ekin << G4endl;
173  }
174  if((g > probmax || n > nmax) && pVerbose > 1) {
175  G4cout << "### G4VEmissionProbability::SampleEnergy for Z= " << theZ
176  << " A= " << theA
177  << "\n Warning n= " << n
178  << " prob/probmax= " << g/probmax
179  << " prob= " << g << " probmax= " << probmax
180  << "\n Ekin= " << ekin << " Emin= " << emin
181  << " Emax= " << emax << G4endl;
182  }
183  } while(probmax*rndm->flat() > g && n < nmax);
184  return (fFD) ? FindRecoilExcitation(ekin) : ekin;
185 }
186 
188 {
189  fExcRes = 0.0;
191  // abnormal case - should never happens
192  if(pMass < mass + pResMass) { return 0.0; }
193 
194  G4double m02 = pMass*pMass;
195  G4double m12 = mass*mass;
196  G4double m22 = pResMass*pResMass;
197  G4double mres = std::sqrt(m02 + m12 - 2.*pMass*(mass + e));
198 
199  fExcRes = mres - pResMass;
200  const G4double tolerance = 0.1*CLHEP::keV;
201 
202  if(pVerbose > 1) {
203  G4cout << "### G4VEmissionProbability::FindRecoilExcitation for resZ= "
204  << resZ << " resA= " << resA
205  << " evaporated Z= " << theZ << " A= " << theA
206  << " Ekin= " << e << " Eexc= " << fExcRes << G4endl;
207  }
208 
209  // residual nucleus is in the ground state
210  if(fExcRes < tolerance) {
211  fExcRes = 0.0;
212  //G4cout<<"Ground state Ekin= "<< 0.5*(m02 + m12 - m22)/pMass - mass<<G4endl;
213  return std::max(0.5*(m02 + m12 - m22)/pMass - mass,0.0);
214  }
215  // select final state excitation
216  auto lManager = pNuclearLevelData->GetLevelManager(resZ, resA);
217  if(!lManager) { return e; }
218 
219  //G4cout<<"ExcMax= "<< lManager->MaxLevelEnergy()<<" CB= "<<eCoulomb<<G4endl;
220  // levels are not known
221  if(fExcRes > lManager->MaxLevelEnergy() + tolerance) { return e; }
222 
223  // find level
224  auto idx = lManager->NearestLevelIndex(fExcRes);
225  //G4cout << "idx= " << idx << " Exc= " << fExcRes
226  // << " Elevel= " << lManager->LevelEnergy(idx) << G4endl;
227  for(; idx > 0; --idx) {
228  fExcRes = lManager->LevelEnergy(idx);
229  // excited level
230  if(pMass > mass + pResMass + fExcRes && lManager->FloatingLevel(idx) == 0) {
231  G4double massR = pResMass + fExcRes;
232  G4double mr2 = massR*massR;
233  //G4cout << "Result idx= " << idx << " Eexc= " << fExcRes
234  // << " Ekin= " << 0.5*(m02 + m12 - mr2)/pMass - mass << G4endl;
235  return std::max(0.5*(m02 + m12 - mr2)/pMass - mass,0.0);
236  }
237  }
238  // ground level
239  fExcRes = 0.0;
240  //G4cout << "Ground state Ekin= " << 0.5*(m02 + m12 - m22)/pMass - mass << G4endl;
241  return std::max(0.5*(m02 + m12 - m22)/pMass - mass,0.0);
242 }