Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4UniversalFluctuation.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 // $Id: G4UniversalFluctuation.cc 106265 2017-09-26 23:32:49Z gcosmo $
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class file
31 //
32 //
33 // File name: G4UniversalFluctuation
34 //
35 // Author: V. Ivanchenko for Laszlo Urban
36 //
37 // Creation date: 03.01.2002
38 //
39 // Modifications:
40 //
41 //
42 
43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
45 
47 #include "G4PhysicalConstants.hh"
48 #include "G4SystemOfUnits.hh"
49 #include "Randomize.hh"
50 #include "G4Poisson.hh"
51 #include "G4Step.hh"
52 #include "G4Material.hh"
53 #include "G4MaterialCutsCouple.hh"
54 #include "G4DynamicParticle.hh"
55 #include "G4ParticleDefinition.hh"
56 #include "G4Log.hh"
57 #include "G4Exp.hh"
58 
59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
60 
61 using namespace std;
62 
65  particle(nullptr),
66  minNumberInteractionsBohr(10.0),
67  minLoss(10.*eV),
68  nmaxCont(16.),
69  rate(0.56),
70  a0(50.),
71  fw(4.00)
72 {
73  lastMaterial = nullptr;
76  = e1 = e2 = 0.0;
78  sizearray = 30;
79  rndmarray = new G4double[30];
80 }
81 
82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83 
85 {
86  delete [] rndmarray;
87 }
88 
89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90 
92 {
93  particle = part;
94  particleMass = part->GetPDGMass();
95  G4double q = part->GetPDGCharge()/eplus;
96 
97  // Derived quantities
100  chargeSquare = q*q;
101 }
102 
103 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
104 
105 G4double
107  const G4DynamicParticle* dp,
108  G4double tmax,
109  G4double length,
110  G4double averageLoss)
111 {
112  // Calculate actual loss from the mean loss.
113  // The model used to get the fluctuations is essentially the same
114  // as in Glandz in Geant3 (Cern program library W5013, phys332).
115  // L. Urban et al. NIM A362, p.416 (1995) and Geant4 Physics Reference Manual
116 
117  // shortcut for very small loss or from a step nearly equal to the range
118  // (out of validity of the model)
119  //
120  G4double meanLoss = averageLoss;
121  G4double tkin = dp->GetKineticEnergy();
122  //G4cout<< "Emean= "<< meanLoss<< " tmax= "<< tmax<< " L= "<<length<<G4endl;
123  if (meanLoss < minLoss) { return meanLoss; }
124 
125  if(dp->GetDefinition() != particle) { InitialiseMe(dp->GetDefinition()); }
126 
127  CLHEP::HepRandomEngine* rndmEngineF = G4Random::getTheEngine();
128 
129  G4double tau = tkin * m_Inv_particleMass;
130  G4double gam = tau + 1.0;
131  G4double gam2 = gam*gam;
132  G4double beta2 = tau*(tau + 2.0)/gam2;
133 
134  G4double loss(0.), siga(0.);
135 
136  const G4Material* material = couple->GetMaterial();
137 
138  // Gaussian regime
139  // for heavy particles only and conditions
140  // for Gauusian fluct. has been changed
141  //
142  if ((particleMass > electron_mass_c2) &&
143  (meanLoss >= minNumberInteractionsBohr*tmax))
144  {
145  G4double tmaxkine = 2.*electron_mass_c2*beta2*gam2/
146  (1.+m_massrate*(2.*gam+m_massrate)) ;
147  if (tmaxkine <= 2.*tmax)
148  {
149  electronDensity = material->GetElectronDensity();
150  siga = sqrt((1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
152 
153  G4double sn = meanLoss/siga;
154 
155  // thick target case
156  if (sn >= 2.0) {
157 
158  G4double twomeanLoss = meanLoss + meanLoss;
159  do {
160  loss = G4RandGauss::shoot(rndmEngineF,meanLoss,siga);
161  // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
162  } while (0.0 > loss || twomeanLoss < loss);
163 
164  // Gamma distribution
165  } else {
166 
167  G4double neff = sn*sn;
168  loss = meanLoss*G4RandGamma::shoot(rndmEngineF,neff,1.0)/neff;
169  }
170  //G4cout << "Gauss: " << loss << G4endl;
171  return loss;
172  }
173  }
174 
175  // Glandz regime : initialisation
176  //
177  if (material != lastMaterial) {
178  f1Fluct = material->GetIonisation()->GetF1fluct();
179  f2Fluct = material->GetIonisation()->GetF2fluct();
180  e1Fluct = material->GetIonisation()->GetEnergy1fluct();
181  e2Fluct = material->GetIonisation()->GetEnergy2fluct();
186  e0 = material->GetIonisation()->GetEnergy0fluct();
187  esmall = 0.5*sqrt(e0*ipotFluct);
188  lastMaterial = material;
189  }
190 
191  // very small step or low-density material
192  if(tmax <= e0) { return meanLoss; }
193 
194  // width correction for small cuts
195  G4double scaling = std::min(1.+0.5*CLHEP::keV/tmax,1.50);
196  meanLoss /= scaling;
197 
198  G4double a1(0.0), a2(0.0), a3(0.0);
199 
200  loss = 0.0;
201 
202  e1 = e1Fluct;
203  e2 = e2Fluct;
204 
205  if(tmax > ipotFluct) {
206  G4double w2 = G4Log(2.*electron_mass_c2*beta2*gam2)-beta2;
207 
208  if(w2 > ipotLogFluct) {
209  if(w2 > e2LogFluct) {
210  G4double C = meanLoss*(1.-rate)/(w2-ipotLogFluct);
211  a1 = C*f1Fluct*(w2-e1LogFluct)/e1Fluct;
212  a2 = C*f2Fluct*(w2-e2LogFluct)/e2Fluct;
213  } else {
214  a1 = meanLoss*(1.-rate)/e1;
215  }
216  if(a1 < a0) {
217  G4double fwnow = 0.5+(fw-0.5)*sqrt(a1/a0);
218  a1 /= fwnow;
219  e1 *= fwnow;
220  } else {
221  a1 /= fw;
222  e1 = fw*e1Fluct;
223  }
224  }
225  }
226 
227  G4double w1 = tmax/e0;
228  if(tmax > e0) {
229  a3 = rate*meanLoss*(tmax-e0)/(e0*tmax*G4Log(w1));
230  if(a1+a2 <= 0.) {
231  a3 /= rate;
232  }
233  }
234  //'nearly' Gaussian fluctuation if a1>nmaxCont&&a2>nmaxCont&&a3>nmaxCont
235  G4double emean = 0.;
236  G4double sig2e = 0.;
237 
238  // excitation of type 1
239  if(a1 > 0.0) { AddExcitation(rndmEngineF, a1, e1, emean, loss, sig2e); }
240 
241  // excitation of type 2
242  if(a2 > 0.0) { AddExcitation(rndmEngineF, a2, e2, emean, loss, sig2e); }
243 
244  if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
245 
246  // ionisation
247  if(a3 > 0.) {
248  emean = 0.;
249  sig2e = 0.;
250  G4double p3 = a3;
251  G4double alfa = 1.;
252  if(a3 > nmaxCont)
253  {
254  alfa = w1*(nmaxCont+a3)/(w1*nmaxCont+a3);
255  G4double alfa1 = alfa*G4Log(alfa)/(alfa-1.);
256  G4double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
257  emean += namean*e0*alfa1;
258  sig2e += e0*e0*namean*(alfa-alfa1*alfa1);
259  p3 = a3-namean;
260  }
261 
262  G4double w2 = alfa*e0;
263  if(tmax > w2) {
264  G4double w = (tmax-w2)/tmax;
265  G4int nnb = G4Poisson(p3);
266  if(nnb > 0) {
267  if(nnb > sizearray) {
268  sizearray = nnb;
269  delete [] rndmarray;
270  rndmarray = new G4double[nnb];
271  }
272  rndmEngineF->flatArray(nnb, rndmarray);
273  for (G4int k=0; k<nnb; ++k) { loss += w2/(1.-w*rndmarray[k]); }
274  }
275  }
276  if(sig2e > 0.0) { SampleGauss(rndmEngineF, emean, sig2e, loss); }
277  }
278 
279  loss *= scaling;
280 
281  return loss;
282 
283 }
284 
285 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
286 
287 
289  const G4Material* material,
290  const G4DynamicParticle* dp,
291  G4double tmax,
292  G4double length)
293 {
294  if(dp->GetDefinition() != particle) { InitialiseMe(dp->GetDefinition()); }
295 
296  electronDensity = material->GetElectronDensity();
297 
299  G4double beta2 = 1.0 - 1.0/(gam*gam);
300 
301  G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
303 
304  return siga;
305 }
306 
307 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
308 
309 void
311  G4double q2)
312 {
313  if(part != particle) {
314  particle = part;
315  particleMass = part->GetPDGMass();
316 
317  // Derived quantities
318  if( particleMass != 0.0 ){
321  }else{
324  }
325  }
326  chargeSquare = q2;
327 }
328 
329 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
virtual void InitialiseMe(const G4ParticleDefinition *) final
G4double GetLogEnergy1fluct() const
G4double GetEnergy1fluct() const
const G4Material * lastMaterial
G4double GetF1fluct() const
virtual G4double Dispersion(const G4Material *, const G4DynamicParticle *, G4double, G4double) override
static constexpr double twopi_mc2_rcl2
virtual G4double SampleFluctuations(const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double, G4double, G4double) override
G4double GetLogMeanExcEnergy() const
G4double GetPDGCharge() const
virtual void flatArray(const int size, double *vect)=0
void AddExcitation(CLHEP::HepRandomEngine *rndm, G4double a, G4double e, G4double &eav, G4double &eloss, G4double &esig2)
G4double GetPDGMass() const
G4double G4Log(G4double x)
Definition: G4Log.hh:230
G4double GetEnergy0fluct() const
double G4double
Definition: G4Types.hh:76
TString part[npart]
Definition: Style.C:32
G4ParticleDefinition * GetDefinition() const
static constexpr double electron_mass_c2
virtual void SetParticleAndCharge(const G4ParticleDefinition *, G4double q2) final
G4double GetEnergy2fluct() const
static constexpr double eV
Definition: G4SIunits.hh:215
G4double GetMeanExcitationEnergy() const
ThreeVector shoot(const G4int Ap, const G4int Af)
static constexpr double eplus
Definition: G4SIunits.hh:199
const G4double a0
int G4int
Definition: G4Types.hh:78
const G4ParticleDefinition * particle
double C(double temp)
G4IonisParamMat * GetIonisation() const
Definition: G4Material.hh:227
void SampleGauss(CLHEP::HepRandomEngine *rndm, G4double eav, G4double esig2, G4double &eloss)
G4double GetLogEnergy2fluct() const
G4double GetKineticEnergy() const
G4UniversalFluctuation(const G4String &nam="UniFluc")
G4long G4Poisson(G4double mean)
Definition: G4Poisson.hh:51
const G4Material * GetMaterial() const
G4double GetF2fluct() const
static constexpr double keV
#define DBL_MAX
Definition: templates.hh:83
G4double GetElectronDensity() const
Definition: G4Material.hh:218
T min(const T t1, const T t2)
brief Return the smallest of the two arguments