Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Member Functions
G4Generator2BN Class Reference

#include <G4Generator2BN.hh>

Inheritance diagram for G4Generator2BN:
G4VEmAngularDistribution

Public Member Functions

 G4Generator2BN (const G4String &name="")
 
virtual ~G4Generator2BN ()
 
virtual G4ThreeVectorSampleDirection (const G4DynamicParticle *dp, G4double out_energy, G4int Z, const G4Material *mat=0)
 
void PrintGeneratorInformation () const
 
void SetInterpolationThetaIncrement (G4double increment)
 
G4double GetInterpolationThetaIncrement ()
 
void SetGammaCutValue (G4double cutValue)
 
G4double GetGammaCutValue ()
 
void ConstructMajorantSurface ()
 
- Public Member Functions inherited from G4VEmAngularDistribution
 G4VEmAngularDistribution (const G4String &name)
 
virtual ~G4VEmAngularDistribution ()
 
virtual G4ThreeVectorSampleDirectionForShell (const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, G4int shellID, const G4Material *)
 
const G4StringGetName () const
 

Protected Member Functions

G4double CalculateFkt (G4double k, G4double theta, G4double A, G4double c) const
 
G4double Calculatedsdkdt (G4double kout, G4double theta, G4double Eel) const
 

Additional Inherited Members

- Protected Attributes inherited from G4VEmAngularDistribution
G4ThreeVector fLocalDirection
 

Detailed Description

Definition at line 62 of file G4Generator2BN.hh.

Constructor & Destructor Documentation

G4Generator2BN::G4Generator2BN ( const G4String name = "")

Definition at line 156 of file G4Generator2BN.cc.

References python.hepunit::eV, and python.hepunit::rad.

157  : G4VEmAngularDistribution("AngularGen2BN")
158 {
159  b = 1.2;
160  index_min = -300;
161  index_max = 319;
162 
163  // Set parameters minimum limits Ekelectron = 250 eV and kphoton = 100 eV
164  kmin = 100*eV;
165  Ekmin = 250*eV;
166  kcut = 100*eV;
167 
168  // Increment Theta value for surface interpolation
169  dtheta = 0.1*rad;
170 
171  nwarn = 0;
172 
173  // Construct Majorant Surface to 2BN cross-section
174  // (we dont need this. Pre-calculated values are used instead due to performance issues
175  // ConstructMajorantSurface();
176 }
G4VEmAngularDistribution(const G4String &name)
G4Generator2BN::~G4Generator2BN ( )
virtual

Definition at line 180 of file G4Generator2BN.cc.

181 {}

Member Function Documentation

G4double G4Generator2BN::Calculatedsdkdt ( G4double  kout,
G4double  theta,
G4double  Eel 
) const
protected

Definition at line 269 of file G4Generator2BN.cc.

References python.hepunit::electron_mass_c2, python.hepunit::MeV, and python.hepunit::pi.

Referenced by ConstructMajorantSurface(), and SampleDirection().

270 {
271 
272  G4double dsdkdt_value = 0.;
273  G4double Z = 1;
274  // classic radius (in cm)
275  G4double r0 = 2.82E-13;
276  //squared classic radius (in barn)
277  G4double r02 = r0*r0*1.0E+24;
278 
279  // Photon energy cannot be greater than electron kinetic energy
280  if(kout > (Eel-electron_mass_c2)){
281  dsdkdt_value = 0;
282  return dsdkdt_value;
283  }
284 
285  G4double E0 = Eel/electron_mass_c2;
286  G4double k = kout/electron_mass_c2;
287  G4double E = E0 - k;
288 
289  if(E <= 1*MeV ){ // Kinematic limit at 1 MeV !!
290  dsdkdt_value = 0;
291  return dsdkdt_value;
292  }
293 
294 
295  G4double p0 = std::sqrt(E0*E0-1);
296  G4double p = std::sqrt(E*E-1);
297  G4double L = std::log((E*E0-1+p*p0)/(E*E0-1-p*p0));
298  G4double delta0 = E0 - p0*std::cos(theta);
299  G4double epsilon = std::log((E+p)/(E-p));
300  G4double Z2 = Z*Z;
301  G4double sintheta2 = std::sin(theta)*std::sin(theta);
302  G4double E02 = E0*E0;
303  G4double E2 = E*E;
304  G4double p02 = E0*E0-1;
305  G4double k2 = k*k;
306  G4double delta02 = delta0*delta0;
307  G4double delta04 = delta02* delta02;
308  G4double Q = std::sqrt(p02+k2-2*k*p0*std::cos(theta));
309  G4double Q2 = Q*Q;
310  G4double epsilonQ = std::log((Q+p)/(Q-p));
311 
312 
313  dsdkdt_value = Z2 * (r02/(8*pi*137)) * (1/k) * (p/p0) *
314  ( (8 * (sintheta2*(2*E02+1))/(p02*delta04)) -
315  ((2*(5*E02+2*E*E0+3))/(p02 * delta02)) -
316  ((2*(p02-k2))/((Q2*delta02))) +
317  ((4*E)/(p02*delta0)) +
318  (L/(p*p0))*(
319  ((4*E0*sintheta2*(3*k-p02*E))/(p02*delta04)) +
320  ((4*E02*(E02+E2))/(p02*delta02)) +
321  ((2-2*(7*E02-3*E*E0+E2))/(p02*delta02)) +
322  (2*k*(E02+E*E0-1))/((p02*delta0))
323  ) -
324  ((4*epsilon)/(p*delta0)) +
325  ((epsilonQ)/(p*Q))*
326  (4/delta02-(6*k/delta0)-(2*k*(p02-k2))/(Q2*delta0))
327  );
328 
329 
330 
331  dsdkdt_value = dsdkdt_value*std::sin(theta);
332  return dsdkdt_value;
333 }
const char * p
Definition: xmltok.h:285
float electron_mass_c2
Definition: hepunit.py:274
double G4double
Definition: G4Types.hh:76
G4double G4Generator2BN::CalculateFkt ( G4double  k,
G4double  theta,
G4double  A,
G4double  c 
) const
protected

Definition at line 262 of file G4Generator2BN.cc.

Referenced by ConstructMajorantSurface().

263 {
264  G4double Fkt_value = 0;
265  Fkt_value = A*std::pow(k,-b)*theta/(1+c*theta*theta);
266  return Fkt_value;
267 }
double G4double
Definition: G4Types.hh:76
void G4Generator2BN::ConstructMajorantSurface ( )

Definition at line 335 of file G4Generator2BN.cc.

References test::c, Calculatedsdkdt(), CalculateFkt(), python.hepunit::electron_mass_c2, G4cout, G4endl, G4InuclParticleNames::k0, python.hepunit::pi, and test::v.

336 {
337 
338  G4double Eel;
339  G4int vmax;
340  G4double Ek;
341  G4double k, theta, k0, theta0, thetamax;
342  G4double ds, df, dsmax, dk, dt;
343  G4double ratmin;
344  G4double ratio = 0;
345  G4double Vds, Vdf;
346  G4double A, c;
347 
348  G4cout << "**** Constructing Majorant Surface for 2BN Distribution ****" << G4endl;
349 
350  if(kcut > kmin) kmin = kcut;
351 
352  G4int i = 0;
353  // Loop on energy index
354  for(G4int index = index_min; index < index_max; index++){
355 
356  G4double fraction = index/100.;
357  Ek = std::pow(10.,fraction);
358  Eel = Ek + electron_mass_c2;
359 
360  // find x-section maximum at k=kmin
361  dsmax = 0.;
362  thetamax = 0.;
363 
364  for(theta = 0.; theta < pi; theta = theta + dtheta){
365 
366  ds = Calculatedsdkdt(kmin, theta, Eel);
367 
368  if(ds > dsmax){
369  dsmax = ds;
370  thetamax = theta;
371  }
372  }
373 
374  // Compute surface paremeters at kmin
375  if(Ek < kmin || thetamax == 0){
376  c = 0;
377  A = 0;
378  }else{
379  c = 1/(thetamax*thetamax);
380  A = 2*std::sqrt(c)*dsmax/(std::pow(kmin,-b));
381  }
382 
383  // look for correction factor to normalization at kmin
384  ratmin = 1.;
385 
386  // Volume under surfaces
387  Vds = 0.;
388  Vdf = 0.;
389  k0 = 0.;
390  theta0 = 0.;
391 
392  vmax = G4int(100.*std::log10(Ek/kmin));
393 
394  for(G4int v = 0; v < vmax; v++){
395  G4double fractionLocal = (v/100.);
396  k = std::pow(10.,fractionLocal)*kmin;
397 
398  for(theta = 0.; theta < pi; theta = theta + dtheta){
399  dk = k - k0;
400  dt = theta - theta0;
401  ds = Calculatedsdkdt(k,theta, Eel);
402  Vds = Vds + ds*dk*dt;
403  df = CalculateFkt(k,theta, A, c);
404  Vdf = Vdf + df*dk*dt;
405 
406  if(ds != 0.){
407  if(df != 0.) ratio = df/ds;
408  }
409 
410  if(ratio < ratmin && ratio != 0.){
411  ratmin = ratio;
412  }
413  }
414  }
415 
416 
417  // sampling efficiency
418  Atab[i] = A/ratmin * 1.04;
419  ctab[i] = c;
420 
421 // G4cout << Ek << " " << i << " " << index << " " << Atab[i] << " " << ctab[i] << " " << G4endl;
422  i++;
423  }
424 
425 }
int G4int
Definition: G4Types.hh:78
G4double Calculatedsdkdt(G4double kout, G4double theta, G4double Eel) const
G4GLOB_DLL std::ostream G4cout
float electron_mass_c2
Definition: hepunit.py:274
G4double CalculateFkt(G4double k, G4double theta, G4double A, G4double c) const
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4double G4Generator2BN::GetGammaCutValue ( )
inline

Definition at line 84 of file G4Generator2BN.hh.

84 {return kcut;};
G4double G4Generator2BN::GetInterpolationThetaIncrement ( )
inline

Definition at line 81 of file G4Generator2BN.hh.

81 {return dtheta;};
void G4Generator2BN::PrintGeneratorInformation ( ) const

Definition at line 427 of file G4Generator2BN.cc.

References G4cout, and G4endl.

428 {
429  G4cout << "\n" << G4endl;
430  G4cout << "Bremsstrahlung Angular Generator is 2BN Generator from 2BN Koch & Motz distribution (Rev Mod Phys 31(4), 920 (1959))" << G4endl;
431  G4cout << "\n" << G4endl;
432 }
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
G4ThreeVector & G4Generator2BN::SampleDirection ( const G4DynamicParticle dp,
G4double  out_energy,
G4int  Z,
const G4Material mat = 0 
)
virtual

Implements G4VEmAngularDistribution.

Definition at line 183 of file G4Generator2BN.cc.

References test::c, Calculatedsdkdt(), G4VEmAngularDistribution::fLocalDirection, G4cout, G4endl, G4UniformRand, G4DynamicParticle::GetKineticEnergy(), G4DynamicParticle::GetMomentumDirection(), G4DynamicParticle::GetTotalEnergy(), G4INCL::Math::max(), python.hepunit::MeV, python.hepunit::pi2, CLHEP::Hep3Vector::rotateUz(), G4Generator2BS::SampleDirection(), CLHEP::Hep3Vector::set(), and python.hepunit::twopi.

187 {
188  G4double Ek = dp->GetKineticEnergy();
189  G4double Eel = dp->GetTotalEnergy();
190  if(Eel > 2*MeV) {
191  return fGenerator2BS.SampleDirection(dp, out_energy, 0);
192  }
193 
194  G4double k = Eel - out_energy;
195 
196  G4double t;
197  G4double cte2;
198  G4double y, u;
199  G4double ds;
200  G4double dmax;
201 
202  G4int trials = 0;
203 
204  // find table index
205  G4int index = G4int(std::log10(Ek/MeV)*100) - index_min;
206  if(index > index_max) { index = index_max; }
207  else if(index < 0) { index = 0; }
208 
209  //kmax = Ek;
210  //kmin2 = kcut;
211 
212  G4double c = ctab[index];
213  G4double A = Atab[index];
214  if(index < index_max) { A = std::max(A, Atab[index+1]); }
215 
216  do{
217  // generate k accordimg to std::pow(k,-b)
218  trials++;
219 
220  // normalization constant
221  // cte1 = (1-b)/(std::pow(kmax,(1-b))-std::pow(kmin2,(1-b)));
222  // y = G4UniformRand();
223  // k = std::pow(((1-b)/cte1*y+std::pow(kmin2,(1-b))),(1/(1-b)));
224 
225  // generate theta accordimg to theta/(1+c*std::pow(theta,2)
226  // Normalization constant
227  cte2 = 2*c/std::log(1+c*pi2);
228 
229  y = G4UniformRand();
230  t = std::sqrt((std::exp(2*c*y/cte2)-1)/c);
231  u = G4UniformRand();
232 
233  // point acceptance algorithm
234  //fk = std::pow(k,-b);
235  //ft = t/(1+c*t*t);
236  dmax = A*std::pow(k,-b)*t/(1+c*t*t);
237  ds = Calculatedsdkdt(k,t,Eel);
238 
239  // violation point
240  if(ds > dmax && nwarn >= 20) {
241  ++nwarn;
242  G4cout << "### WARNING in G4Generator2BN: Ekin(MeV)= " << Ek/MeV
243  << " D(Ekin,k)/Dmax-1= " << (ds/dmax - 1)
244  << " results are not reliable!"
245  << G4endl;
246  if(20 == nwarn) {
247  G4cout << " WARNING in G4Generator2BN is closed" << G4endl;
248  }
249  }
250 
251  } while(u*dmax > ds || t > CLHEP::pi);
252 
253  G4double sint = std::sin(t);
254  G4double phi = twopi*G4UniformRand();
255 
256  fLocalDirection.set(sint*std::cos(phi), sint*std::sin(phi),std::cos(t));
258 
259  return fLocalDirection;
260 }
void set(double x, double y, double z)
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
int G4int
Definition: G4Types.hh:78
G4double Calculatedsdkdt(G4double kout, G4double theta, G4double Eel) const
#define G4UniformRand()
Definition: Randomize.hh:87
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
T max(const T t1, const T t2)
brief Return the largest of the two arguments
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
virtual G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double out_energy, G4int Z, const G4Material *mat=0)
void G4Generator2BN::SetGammaCutValue ( G4double  cutValue)
inline

Definition at line 83 of file G4Generator2BN.hh.

83 {kcut = cutValue;};
void G4Generator2BN::SetInterpolationThetaIncrement ( G4double  increment)
inline

Definition at line 80 of file G4Generator2BN.hh.

80 {dtheta = increment;};

The documentation for this class was generated from the following files: