Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Generator2BN Class Reference

#include <G4Generator2BN.hh>

+ Inheritance diagram for G4Generator2BN:

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 G4ThreeVectorSampleDirection (const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, const G4Material *)=0
 
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::G4Generator2BN ( const G4String name = "")

Definition at line 156 of file G4Generator2BN.cc.

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}

◆ ~G4Generator2BN()

G4Generator2BN::~G4Generator2BN ( )
virtual

Definition at line 180 of file G4Generator2BN.cc.

181{}

Member Function Documentation

◆ Calculatedsdkdt()

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

Definition at line 269 of file G4Generator2BN.cc.

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}
double G4double
Definition: G4Types.hh:64
const G4double pi

Referenced by ConstructMajorantSurface(), and SampleDirection().

◆ CalculateFkt()

G4double G4Generator2BN::CalculateFkt ( G4double  k,
G4double  theta,
G4double  A,
G4double  c 
) const
protected

Definition at line 262 of file G4Generator2BN.cc.

263{
264 G4double Fkt_value = 0;
265 Fkt_value = A*std::pow(k,-b)*theta/(1+c*theta*theta);
266 return Fkt_value;
267}

Referenced by ConstructMajorantSurface().

◆ ConstructMajorantSurface()

void G4Generator2BN::ConstructMajorantSurface ( )

Definition at line 335 of file G4Generator2BN.cc.

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:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
G4double CalculateFkt(G4double k, G4double theta, G4double A, G4double c) const
G4double Calculatedsdkdt(G4double kout, G4double theta, G4double Eel) const

◆ GetGammaCutValue()

G4double G4Generator2BN::GetGammaCutValue ( )
inline

Definition at line 84 of file G4Generator2BN.hh.

84{return kcut;};

◆ GetInterpolationThetaIncrement()

G4double G4Generator2BN::GetInterpolationThetaIncrement ( )
inline

Definition at line 81 of file G4Generator2BN.hh.

81{return dtheta;};

◆ PrintGeneratorInformation()

void G4Generator2BN::PrintGeneratorInformation ( ) const

Definition at line 427 of file G4Generator2BN.cc.

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}

◆ SampleDirection()

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.

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}
#define G4UniformRand()
Definition: Randomize.hh:53
void set(double x, double y, double z)
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4double GetTotalEnergy() const
virtual G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double out_energy, G4int Z, const G4Material *mat=0)

◆ SetGammaCutValue()

void G4Generator2BN::SetGammaCutValue ( G4double  cutValue)
inline

Definition at line 83 of file G4Generator2BN.hh.

83{kcut = cutValue;};

◆ SetInterpolationThetaIncrement()

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: