Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VEmissionProbability.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// 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"
36#include "Randomize.hh"
37#include "G4Pow.hh"
38#include "G4Log.hh"
39#include "G4Exp.hh"
40
42 : OPTxs(3), pVerbose(1), theZ(Z), theA(A), elimit(CLHEP::MeV)
43{
47}
48
50{
52 OPTxs = param->GetDeexModelType();
53 pVerbose = param->GetVerbose();
54 fFD = param->GetDiscreteExcitationFlag();
56}
57
59{
60 if(de > 0.0) { elimit = de; }
61 if(eps > 0.0) { accuracy = eps; }
62}
63
65{
66 return 0.0;
67}
68
70{
71 return 0.0;
72}
73
75 G4double ehigh,
76 G4double cb)
77{
78 pProbability = 0.0;
79 if(elow >= ehigh) { return pProbability; }
80
81 emin = elow;
82 emax = ehigh;
83 eCoulomb = cb;
84
85 const G4double edeltamin = 0.2*CLHEP::MeV;
86 const G4double edeltamax = 2*CLHEP::MeV;
87 G4double edelta = std::max(std::min(elimit, edeltamax), edeltamin);
88 G4double xbin = (emax - emin)/edelta + 1.0;
89 G4int ibin = xbin;
90 if(ibin < 4) ibin = 4;
91
92 // providing smart binning
93 G4int nbin = ibin*5;
94 edelta = (emax - emin)/ibin;
95
96 G4double x(emin), y(0.0);
97 G4double edelmicro = edelta*0.02;
98 probmax = ComputeProbability(x + edelmicro, eCoulomb);
99 G4double problast = probmax;
100 if(pVerbose > 1) {
101 G4cout << "### G4VEmissionProbability::IntegrateProbability: "
102 << "probmax=" << probmax << " Emin=" << emin
103 << " Emax=" << emax << " QB=" << cb << " nbin=" << nbin
104 << G4endl;
105 }
106 fE1 = fE2 = fP2 = 0.0;
107 G4double emax0 = emax - edelmicro;
108 G4bool endpoint = false;
109 for(G4int i=0; i<nbin; ++i) {
110 x += edelta;
111 if(x >= emax0) {
112 x = emax0;
113 endpoint = true;
114 }
115 y = ComputeProbability(x, eCoulomb);
116 if(pVerbose > 2) {
117 G4cout << " " << i << ". E= " << x << " prob= " << y
118 << " Edel= " << edelta << G4endl;
119 }
120 if(y >= probmax) {
121 probmax = y;
122 } else if(0.0 == fE1 && 2*y < probmax) {
123 fE1 = x;
124 }
125
126 G4double del = (y + problast)*edelta*0.5;
127 pProbability += del;
128 // end of the loop
129 if(del < accuracy*pProbability || endpoint) { break; }
130 problast = y;
131
132 // smart step definition
133 if(del != pProbability && del > 0.8*pProbability &&
134 0.7*edelta > edeltamin) {
135 edelta *= 0.7;
136 } else if(del < 0.1*pProbability && 1.5*edelta < edeltamax) {
137 edelta *= 1.5;
138 }
139 }
140 if(fE1 > emin && fE1 < emax) {
141 fE2 = std::max(0.5*(fE1 + emax), emax - edelta);
142 fP2 = 2*ComputeProbability(fE2, eCoulomb);
143 }
144
145 if(pVerbose > 1) {
146 G4cout << " Probability= " << pProbability << " probmax= "
147 << probmax << " emin=" << emin << " emax=" << emax
148 << " E1=" << fE1 << " E2=" << fE2 << G4endl;
149 }
150 return pProbability;
151}
152
154{
155 static const G4double fact = 1.05;
156 static const G4double alim = 0.05;
157 static const G4double blim = 20.;
158 probmax *= fact;
159
160 // two regions with flat and exponential majorant
161 G4double del = emax - emin;
162 G4double p1 = 1.0;
163 G4double p2 = 0.0;
164 G4double a0 = 0.0;
165 G4double a1 = 1.0;
166 G4double x;
167 if(fE1 > 0.0 && fP2 > 0.0 && fP2 < 0.5*probmax) {
168 a0 = G4Log(probmax/fP2)/(fE2 - fE1);
169 del= fE1 - emin;
170 p1 = del;
171 x = a0*(emax - fE1);
172 if(x < blim) {
173 a1 = (x > alim) ? 1.0 - G4Exp(-x) : x*(1.0 - 0.5*x);
174 }
175 p2 = a1/a0;
176 p1 /= (p1 + p2);
177 p2 = 1.0 - p1;
178 }
179
180 if(pVerbose > 1) {
181 G4cout << "### G4VEmissionProbability::SampleEnergy: "
182 << " Emin= " << emin << " Emax= " << emax
183 << "/n E1=" << fE1 << " p1=" << p1
184 << " probmax=" << probmax << " P2=" << fP2 << G4endl;
185 }
186
187 CLHEP::HepRandomEngine* rndm = G4Random::getTheEngine();
188 const G4int nmax = 1000;
189 G4double ekin, g, gmax;
190 G4int n = 0;
191 do {
192 ++n;
193 G4double q = rndm->flat();
194 if(q <= p1) {
195 gmax = probmax;
196 ekin = del*q/p1 + emin;
197 } else {
198 ekin = fE1 - G4Log(1.0 - (q - p1)*a1/p2)/a0;
199 x = a0*(ekin - fE1);
200 gmax = fP2;
201 if(x < blim) {
202 gmax = probmax*((x > alim) ? G4Exp(-x) : 1.0 - x*(1.0 - 0.5*x));
203 }
204 }
205 g = ComputeProbability(ekin, eCoulomb);
206 if(pVerbose > 2) {
207 G4cout << " " << n
208 << ". prob= " << g << " probmax= " << probmax
209 << " Ekin= " << ekin << G4endl;
210 }
211 if((g > gmax || n > nmax) && pVerbose > 1) {
212 G4cout << "### G4VEmissionProbability::SampleEnergy for Z= " << theZ
213 << " A= " << theA << " Eex(MeV)=" << fExc << " p1=" << p1
214 << "\n Warning n= " << n
215 << " prob/gmax=" << g/gmax
216 << " prob=" << g << " gmax=" << gmax << " probmax=" << probmax
217 << "\n Ekin= " << ekin << " Emin= " << emin
218 << " Emax= " << emax << G4endl;
219 }
220 } while(gmax*rndm->flat() > g && n < nmax);
221 G4double enew = FindRecoilExcitation(ekin);
222 if(pVerbose > 1) {
223 G4cout << "### SampleEnergy: Efinal= "
224 << enew << " E=" << ekin << " Eexc=" << fExcRes << G4endl;
225 }
226 return enew;
227}
228
229G4double G4VEmissionProbability::FindRecoilExcitation(const G4double e)
230{
231 G4double mass = pEvapMass + fExc;
232
233 G4double m02 = pMass*pMass;
234 G4double m12 = mass*mass;
236 G4double mres = std::sqrt(m02 + m12 - 2.*pMass*(mass + e));
237
238 fExcRes = mres - pResMass;
239
240 if(pVerbose > 1) {
241 G4cout << "### FindRecoilExcitation for resZ= "
242 << resZ << " resA= " << resA
243 << " evaporated Z= " << theZ << " A= " << theA
244 << " Ekin= " << e << " Eexc= " << fExcRes << G4endl;
245 }
246
247 // residual nucleus is in the ground state
248 if(fExcRes < pTolerance) {
249 fExcRes = 0.0;
250 return std::max(0.5*(m02 + m12 - m22)/pMass - mass, 0.0);
251 }
252 if(!fFD) { return e; }
253
254 // select final state excitation
255 auto lManager = pNuclearLevelData->GetLevelManager(resZ, resA);
256 if(nullptr == lManager) { return e; }
257
258 // levels are not known
259 if(fExcRes > lManager->MaxLevelEnergy() + pTolerance) { return e; }
260
261 // find level
262 G4double elevel = lManager->NearestLevelEnergy(fExcRes);
263
264 // excited level
265 if(pMass > mass + pResMass + elevel &&
266 std::abs(elevel - fExcRes) <= pTolerance) {
267 G4double massR = pResMass + elevel;
268 G4double mr2 = massR*massR;
269 fExcRes = elevel;
270 return std::max(0.5*(m02 + m12 - mr2)/pMass - mass, 0.0);
271 }
272 return e;
273}
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
const G4double a0
G4double G4Log(G4double x)
Definition: G4Log.hh:227
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
const G4double A[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
virtual double flat()=0
G4bool GetDiscreteExcitationFlag() const
G4double GetMinExcitation() const
G4double NearestLevelEnergy(const G4double energy, const std::size_t index=0) const
G4DeexPrecoParameters * GetParameters()
const G4LevelManager * GetLevelManager(G4int Z, G4int A)
static G4NuclearLevelData * GetInstance()
static G4double GetNuclearMass(const G4double A, const G4double Z)
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
G4VEmissionProbability(G4int Z, G4int A)
void ResetIntegrator(size_t nbin, G4double de, G4double eps)
G4double IntegrateProbability(G4double elow, G4double ehigh, G4double CB)
virtual G4double ComputeProbability(G4double anEnergy, G4double CB)
virtual G4double EmissionProbability(const G4Fragment &fragment, G4double anEnergy)
G4NuclearLevelData * pNuclearLevelData
Definition: DoubConv.h:17