Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VChannelingFastSimCrystalData.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
28#include "G4SystemOfUnits.hh"
30#include "G4Log.hh"
31
36
37//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
38
40
41//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
42
44 (const G4LogicalVolume *crystallogic)
45{
46 G4int crystalID = crystallogic->GetInstanceID();
47
48 //set bending angle if the it exists in the list, otherwise default = 0
49 (fMapBendingAngle.count(crystalID) > 0)
50 ? SetBendingAngle(fMapBendingAngle[crystalID],crystallogic)
51 : SetBendingAngle(0.,crystallogic);
52
53 //set miscut angle if the it exists in the list, otherwise default = 0
54 (fMapMiscutAngle.count(crystalID) > 0)
55 ? SetMiscutAngle(fMapMiscutAngle[crystalID],crystallogic)
56 : SetMiscutAngle(0.,crystallogic);
57
58 //set crystalline undulator parameters if they exist in the list,
59 //otherwise default = G4ThreeVector(0,0,0).
60 (fMapCUAmplitudePeriodPhase.count(crystalID) > 0)
61 ? SetCUParameters(fMapCUAmplitudePeriodPhase[crystalID],crystallogic)
62 : SetCUParameters(G4ThreeVector(0.,0.,0.),crystallogic);
63}
64
65//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
66
68 const G4LogicalVolume* crystallogic)
69{
70 G4int crystalID = crystallogic->GetInstanceID();
71
72 //set the bending angle for this logical volume
73 fMapBendingAngle[crystalID]=tetab;
74
75 G4ThreeVector limboxmin;//minimal limits of the box bounding the logical volume
76 G4ThreeVector limboxmax;//maximal limits of the box bounding the logical volume
77 //save the limits of the box bounding the logical volume
78 crystallogic->GetSolid()->BoundingLimits(limboxmin,limboxmax);
79
80 //bounding box half dimensions
81 fHalfDimBoundingBox = (limboxmax-limboxmin)/2.;
82
83 G4double lcr = limboxmax.getZ()-limboxmin.getZ();//crystal thickness
84
85 fBendingAngle=std::abs(tetab);
86 if (fBendingAngle<0.000001)//no bending less then 1 urad
87 {
89 {
90 G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
91 G4cout << "Warning: bending angle is lower than 1 urad => set to 0" << G4endl;
92 }
93
94 fBent=0;
96 fBendingR=0.;//just for convenience (infinity in reality)
97 fBending2R=0.;
99 fCurv=0.;
100
101 fCorrectionZ = 1.;
102 }
103 else
104 {
105 fBent=1;
109 fCurv=1./fBendingR;
110
111 if (tetab<0.)
112 {
113 G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
114 G4cout << "Warning: bending angle is negative => set to be positive" << G4endl;
115 }
116 }
117
118}
119
120//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
121
123 const G4LogicalVolume *crystallogic)
124{
125 G4int crystalID = crystallogic->GetInstanceID();
126
127 //set the bending angle for this logical volume
128 fMapMiscutAngle[crystalID]=tetam;
129
130 // fMiscutAngle>0: rotation of xz coordinate planes clockwise in the xz plane
131 fMiscutAngle=tetam;
132 if (std::abs(tetam)>1.*mrad)
133 {
134 G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
135 G4cout << "Warning: miscut angle is higher than 1 mrad => " << G4endl;
136 G4cout << "coordinate transformation routines may be unstable" << G4endl;
137 }
140}
141
142//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
143
145 G4double amplitude,
146 G4double period,
147 G4double phase,
148 const G4LogicalVolume *crystallogic)
149{
150 if (amplitude<DBL_EPSILON||period<DBL_EPSILON)
151 {
152 amplitude = 0.;
153 period=0.;
154 phase=0.;
155 G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
156 G4cout << "Warning: The crystalline undulator parameters are out of range "
157 "=> the crystalline undulator mode switched off" << G4endl;
158 }
159
160 SetCUParameters(G4ThreeVector(amplitude,period,phase),crystallogic);
161}
162
163//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
164
166 const G4ThreeVector &amplitudePeriodPhase,
167 const G4LogicalVolume *crystallogic)
168{
169 G4int crystalID = crystallogic->GetInstanceID();
170
171 //set the crystalline undulator parameters for this logical volume
172 fMapCUAmplitudePeriodPhase[crystalID]=amplitudePeriodPhase;
173 fCUAmplitude=amplitudePeriodPhase.x();
174 G4double period = amplitudePeriodPhase.y();
175 fCUPhase = amplitudePeriodPhase.z();
176
177 //if the amplidude of the crystalline undulator is 0 => no undulator
179 {
180 //crystalline undulator flag
181 fCU = true;
182
183 fCUK = CLHEP::twopi/period;
184
186 {
187 //bent and periodically bent crystal are not compatible
188 SetBendingAngle(0,crystallogic);
189
190 G4cout << "Channeling model: volume " << crystallogic->GetName() << G4endl;
191 G4cout << "Warning: crystalline undulator is not compatible with "
192 "a bent crystal mode => setting bending angle to 0." << G4endl;
193 }
194 }
195 else
196 {
197 fCU = false;
198 fCUAmplitude = 0.;
199 fCUK = 0.;
200 fCUPhase = 0.;
201 fMapCUAmplitudePeriodPhase[crystalID] = G4ThreeVector(0.,0.,0.);
202 }
203
204 fCUK2 = fCUK*fCUK;
206}
207
208//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
209
211 G4double mass,
212 G4double charge,
213 G4bool ifhadron)
214{
215 G4double teta1;
216 fZ2=charge;
217 G4double zz22=fZ2*fZ2;
218 fHadron=ifhadron;
219
220// particle momentum and energy
221 G4double t=etotal*etotal-mass*mass; // economy of operations
222 fPz=std::sqrt(t); // momentum of particle
223 fPV=t/etotal; // pv
224 fBeta=fPz/etotal; // velocity/c
225 fTetaL = std::sqrt(fVmax2/fPV); //Lindhard angle
226 fChannelingStep = fChangeStep/fTetaL; //standard simulation step
227
228// Energy losses
229 fV2 = fBeta*fBeta; // particle (velocity/c)^2
230 fGamma = etotal/mass; // Lorentz factor
231 fMe2Gamma = 2*CLHEP::electron_mass_c2*fGamma;
232// max ionization losses
233 fTmax = fMe2Gamma*fGamma*fV2/
234 (CLHEP::electron_mass_c2/mass*CLHEP::electron_mass_c2/mass +
235 1. + fMe2Gamma/mass);
236
237 for(G4int i=0; i<fNelements; i++)
238 {
239
240// minimal scattering angle by coulomb scattering on nuclei
241// defining by shielding by electrons
242// teta1=hdc/(fPz*fRF)*DSQRT(1.13D0+3.76D0*(alpha*fZ1*fZ2/fBeta)**2){ev*cm/(eV*cm)}
243 teta1=fTeta10[i]*std::sqrt(1.13+fK40[i]*zz22/fV2); // /fPz later to speed up
244 // the calculations
245
246// the coefficient for multiple scattering
247 fBB[i]=teta1*teta1*fPu11[i];
248 fE1XBbb[i]=expint(fBB[i]);
249 fBBDEXP[i]=(1.+fBB[i])*std::exp(fBB[i]);
250// necessary for suppression of incoherent scattering
251// by the atomic correlations in crystals for single scattering on nucleus
252// (screened atomic potential): EXP(-(fPz*teta*fU1)**2)=EXP(-fPzu11*teta**2).GE.ksi
253// =>no scattering
254 fPzu11[i]=fPu11[i]*fPz*fPz;
255
256 teta1=teta1/fPz; //
257 fTeta12[i]=teta1*teta1;
258// maximal scattering angle by coulomb scattering on nuclei
259// defining by nucleus radius
260// tetamax=hc/(fPz*1.D-6*fR0*fAN**(1.D0/3.D0))// {Mev*fermi/(MeV*fermi)}
261 G4double tetamax=fTetamax0[i]/fPz;
262 fTetamax2[i]=tetamax*tetamax;
264
265// a cofficient in a formula for scattering (for high speed of simulation)
266// fK2=(fZ2*alpha*hdc)**2*4.*pi*fN0*(fZ1/fPV)**2
267// fK3=(fZ2*alpha*hdc)**2*4.*pi*fN0/(fPV)**2
268 fK2[i]=fK20[i]*zz22/fPV/fPV;
269 }
270
271// nuclear diffractive scattering angle
272 //tetaQEL=1./sqrt(2.*(9.26-4.94/sqrt(fPz/GeV)+0.28*log(fPz/GeV)));
273
274 fK3=fK30/fV2;
275}
276
277//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
278
280{
281 G4double pv0 = etotal-mass*mass/etotal;
282 return std::sqrt(2*fVmax/pv0); //Calculate the value of the Lindhard angle
283 //(!!! the value for a straight crystal)
284}
285
286//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
287
289{
290 return fTetaL; //return the Lindhard angle value calculated in SetParticleProperties
291}
292
293//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
294
296{
297 G4double simulationstep;
298 //find angle of particle w.r.t. the plane or axis
299 G4double angle=0.;
300 if (iModel==1)//1D model
301 {
302 angle = std::abs(tx);
303 }
304 else if (iModel==2)//2D model
305 {
306 angle = std::sqrt(tx*tx+ty*ty);
307 }
308
309 //compare this angle with the Lindhard angle
310 if (angle<fTetaL)
311 {
312 simulationstep = fChannelingStep;
313 }
314 else
315 {
316 simulationstep = fChangeStep/angle;
317 }
318
319 return simulationstep;
320}
321
322//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
323
325 G4double mass)
326{
327 //standard value of step for channeling particles which is the maximal possible step
328 return fChangeStep/GetLindhardAngle(etotal, mass);
329}
330
331//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
332
334 G4double effectiveStep,
335 G4double step,
336 G4int ielement)
337{
338 G4double tx = 0.;//horizontal scattering angle
339 G4double ty = 0.;//vertical scattering angle
340
341 G4double ksi=0.1;
342
343// calculation of the teta2-minimal possible angle of a single scattering
344 G4double e1=fK2[ielement]*effectiveStep; //for high speed of a program
345// (real formula is (4*pi*fN0*wpl(x)*dz*fZ1*zz2*alpha*hdc/fPV)**2)
346 G4double teta122=fTetamax12[ielement]/(ksi*fTetamax12[ielement]/e1+1.);
347 // teta122=fTeta12+teta22=teta1^2+teta2^2
348
349 G4double teta22;
350 G4double t;
351// if the angle of a single scattering is less teta1 - minimal possible
352// angle of coulomb scattering defining by the electron shielding than
353// multiple scattering by both nuclei and electrons and electrons will not
354// occur => minimal possible angle of a single scattering is equal to teta1
355 if (teta122<=fTeta12[ielement]*1.000125)
356 {
357 teta22=0.;
358 teta122=fTeta12[ielement];
359 }
360 else
361 {
362 teta22=teta122-fTeta12[ielement];
363 G4double aa=teta22/fTeta12[ielement];
364 G4double aa1=1.+aa;
365
366// crystal, with scattering suppression
367 G4double tetamsi=e1*(G4Log(aa1)+
368 (1.-std::exp(-aa*fBB[ielement]))/aa1+
369 fBBDEXP[ielement]*
370 (expint(fBB[ielement]*aa1)-fE1XBbb[ielement]));
371
372// sumilation of multiple coulomb scattering by nuclei and electrons
373// for high speed of a program, real formula is
374// 4*pi*fN0*wpl(x)*dz*(fZ1*zz2*alpha*hdc/fPV)**2*
375// *(ln(1+a)+(1-exp(-a*b))/(1+a)+(1+b)*exp(b)*(E1XB(b*(1+a))-E1XB(b)))
376
377 ksi=G4UniformRand();
378 t=std::sqrt(-tetamsi*G4Log(ksi));
379
380 ksi=G4UniformRand();
381
382 tx+=t*std::cos(CLHEP::twopi*ksi);
383 ty+=t*std::sin(CLHEP::twopi*ksi);
384
385 }
386// simulation of single coulomb scattering by nuclei (with screened potential)
387 G4double zss=0.;
388 G4double dzss=step;
389
390// (calculation of a distance, at which another single scattering can happen)
391 ksi=G4UniformRand();
392
393 zss=-G4Log(ksi)*step/(e1*(1./teta122-1./fTetamax12[ielement]));
394 G4double tt;
395
396// At some step several single scattering can occur.
397// So,if the distance of the next scattering is less than the step,
398// another scattering can occur. If the distance of the next scattering
399// is less than the difference between the step and the distance of
400// the previous scattering, another scattering can occur. And so on, and so on.
401// In the cycle we simulate each of them. The cycle is finished, when
402// the remaining part of step is less than a distance of the next single scattering.
403//********************************************
404// if at a step a single scattering occurs
405 while (zss<dzss)
406 {
407
408// simulation by Monte-Carlo of angles of single scattering
409 ksi=G4UniformRand();
410
411 tt=fTetamax12[ielement]/(1.+ksi*(fTetamax2[ielement]-teta22)/teta122)-
412 fTeta12[ielement];
413
414 ksi=G4UniformRand();
415
416// suppression of incoherent scattering by the atomic correlations in crystals
417 t=fPzu11[ielement]*tt;
418 t=std::exp(-t);
419
420 if (t<ksi) //if scattering takes place
421 {
422 //scattering angle
423 t=std::sqrt(tt);
424 ksi=G4UniformRand();
425
426 tx+=t*std::cos(CLHEP::twopi*ksi);
427 ty+=t*std::sin(CLHEP::twopi*ksi);
428 }
429
430 dzss-=zss;
431// (calculation of a distance, at which another single scattering can happen)
432 ksi=G4UniformRand();
433
434 zss=-G4Log(ksi)*step/(e1*(1./teta122-1./fTetamax12[ielement]));
435 }
436//********************************************
437 return G4ThreeVector(tx,ty,0.);
438}
439
440//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
441
443 G4double eMinIonization,
444 G4double electronDensity,
445 G4double step)
446{
447
448 G4double zss=0.;
449 G4double dzss=step;
450 G4double ksi = 0.;
451
452 G4double tx = 0.;//horizontal scattering angle
453 G4double ty = 0.;//vertical scattering angle
454 G4double eloss = 0.;//energy loss
455
456 // eMinIonization - minimal energy transfered to electron
457 // a cut to reduce the number of calls of electron scattering
458 // is needed only at low density regions, in many cases does not do anything at all
459 if (eMinIonization<0.5*eV){eMinIonization=0.5*eV;}
460
461 // single scattering on electrons routine
462 if ((eMinIonization<fTmax)&&(electronDensity>DBL_EPSILON))
463 {
464
465// (calculation of a distance, at which another single scattering can happen)
466// simulation of scattering length (by the same way single scattering by nucleus
467 ksi=G4UniformRand();
468
469 zss=-1.0*G4Log(ksi)/(fK3*electronDensity)/(1./eMinIonization-1./fTmax);
470
471//********************************************
472// if at a step a single scattering occur
473 while (zss<dzss)
474 {
475// simulation by Monte-Carlo of angles of single scattering
476 ksi=G4UniformRand();
477
478// energy transfered to electron
479 G4double e1=eMinIonization/(1.-ksi*(1.-eMinIonization/fTmax));
480
481// scattering angle
482 G4double t=std::sqrt(e1*(e1+2.*CLHEP::electron_mass_c2))/fPz;
483
484 // energy losses
485 if (fHadron) {eloss=e1;} // we don't calculate ionization losses for e+-
486
487 ksi=G4UniformRand();
488
489 tx+=t*std::cos(CLHEP::twopi*ksi);
490 ty+=t*std::sin(CLHEP::twopi*ksi);
491
492 dzss-=zss;
493// (calculation of a distance, at which another single scattering can happen)
494// simulation of scattering length
495// (by the same way single scattering by nucleus
496 ksi=G4UniformRand();
497
498 zss=-1.0*G4Log(ksi)/(fK3*electronDensity)/(1./eMinIonization-1./fTmax);
499 }
500//********************************************
501 }
502 return G4ThreeVector(tx,ty,eloss);
503}
504
505//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
506
508 G4int ielement)
509{
510 G4double elosses = 0.;
511 if (fHadron) {elosses=fKD[ielement]/fV2*
512 (G4Log(fMe2Gamma*fV2/fI0[ielement]/fGamma) - fV2)*dz;}
513 return elosses;
514}
515
516//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
517
518G4double G4VChannelingFastSimCrystalData::expint(G4double X)
519{
520// ============================================
521// Purpose: Compute exponential integral E1(x)
522// Input : x --- Argument of E1(x)
523// Output: E1 --- E1(x)
524// ============================================
525
526G4double E1, R, T, T0;
527G4int M;
528
529if (X==0)
530{
531 E1=1.e300;
532}
533else if (X<=1.)
534{
535 E1=1.;
536 R=1.;
537
538
539 for(int K=1; K<=25; K++)
540 {
541 R=-R*K*X/std::pow(K+1.,2.);
542 E1=E1+R;
543 if (std::abs(R)<=std::abs(E1)*1.0e-15) {break;}
544 }
545
546 E1=-0.5772156649015328-G4Log(X)+X*E1;
547}
548else
549{
550 M=20+std::trunc(80.0/X);
551 T0=0.;
552
553 for(int K=M; K>=1; K--)
554 {
555 T0=K/(1.0+K/(X+T0));
556 }
557
558 T=1.0/(X+T0);
559 E1=std::exp(-X)*T;
560}
561
562return E1;
563}
G4double G4Log(G4double x)
Definition G4Log.hh:227
#define M(row, col)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
Definition of the G4VChannelingFastSimCrystalData class The class contains the data and properties re...
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
double z() const
double getZ() const
double x() const
double y() const
G4VSolid * GetSolid() const
G4int GetInstanceID() const
const G4String & GetName() const
G4double IonizationLosses(G4double dz, G4int ielement)
ionization losses
std::vector< G4double > fK20
coefficients necessary for multiple and single coulomb scattering
G4double GetLindhardAngle()
Calculate the value of the Lindhard angle (!!! the value for a straight crystal)
void SetGeometryParameters(const G4LogicalVolume *crystallogic)
set geometry parameters from current logical volume
void SetCUParameters(const G4ThreeVector &amplitudePeriodPhase, const G4LogicalVolume *crystallogic)
void SetCrystallineUndulatorParameters(G4double amplitude, G4double period, G4double phase, const G4LogicalVolume *crystallogic)
G4ThreeVector fHalfDimBoundingBox
values related to the crystal geometry
G4double GetSimulationStep(G4double tx, G4double ty)
void SetBendingAngle(G4double tetab, const G4LogicalVolume *crystallogic)
G4int fNelements
values related to the crystal lattice
G4ThreeVector CoulombElectronScattering(G4double eMinIonization, G4double electronDensity, G4double step)
multiple and single scattering on electrons
std::vector< G4double > fTeta10
angles necessary for multiple and single coulomb scattering
void SetParticleProperties(G4double etotal, G4double mp, G4double charge, G4bool ifhadron)
G4double GetMaxSimulationStep(G4double etotal, G4double mass)
Calculate maximal simulation step (standard value for channeling particles)
std::vector< G4double > fPu11
coefficients for multiple scattering suppression
G4ThreeVector CoulombAtomicScattering(G4double effectiveStep, G4double step, G4int ielement)
multiple and single scattering on screened potential
void SetMiscutAngle(G4double tetam, const G4LogicalVolume *crystallogic)
virtual void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const
Definition G4VSolid.cc:665
#define DBL_EPSILON
Definition templates.hh:66