Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ChannelingFastSimCrystalData.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// Author: Alexei Sytov
27// Co-author: Gianfranco PaternĂ² (modifications & testing)
28
30
32 const G4Material *crystal,
33 const G4String &lattice,
34 const G4String &filePath)
35{
36 G4String filename=crystal->GetName(); //input file
37 filename.erase(0,3);
38
39 if (fVerbosity)
40 {
41 G4cout <<
42 "======================================================================="
43 << G4endl;
44 G4cout <<
45 "====== Crystal lattice data ========"
46 << G4endl;
47 G4cout <<
48 "======================================================================="
49 << G4endl;
50 G4cout << "Crystal material: " << filename << G4endl;
51 }
52
53 //choice between planes (1D model) and axes (2D model)
54 if (lattice.compare(0,1,"(")==0)
55 {
56 iModel=1; //planes
57 filename = filename + "_planes_"; //temporary name
58 if (fVerbosity)
59 G4cout << "Crystal planes: " << lattice << G4endl;
60 }
61 else if (lattice.compare(0,1,"<")==0)
62 {
63 iModel=2; //axes
64 filename = filename + "_axes_"; //temporary name
65 if (fVerbosity)
66 G4cout << "Crystal axes: " << lattice << G4endl;
67 }
68
69 //input file:
70 filename = filename + lattice.substr(1,(lattice.length())-2) + ".dat";
71
72 if(filePath=="")
73 {
74 //standard file path if another one is not set
75 filename = "/" + filename;
76 filename = G4FindDataDir("G4CHANNELINGDATA") + filename;
77 }
78 else
79 {
80 //custom file path
81 filename = filePath + filename;
82 }
83
85 for(G4int i=0; i<fNelements; i++)
86 {
87 fZ1.push_back(crystal->GetElement(i)->GetZ());
88 fAN.push_back(crystal->GetElement(i)->GetAtomicMassAmu());
89 fI0.push_back(crystal->GetElement(i)->GetIonisation()->GetMeanExcitationEnergy());
90 }
91
92 G4double var;//just variable
93 G4double unitIF;//unit of interpolation function
94
95 std::ifstream vfilein;
96 vfilein.open(filename);
97 //check if the input file was found, otherwise return an exception
98 if(!vfilein.is_open())
99 {
100 G4String outputMessage="Input file " +
101 filename +
102 " is not found!";
103 G4Exception("SetMaterialProperties",
104 "001",
106 outputMessage);
107 }
108
109 //read nuclear concentration
110 for(G4int i=0; i<fNelements; i++)
111 {
112 vfilein >> var;
113 fN0.push_back(var/CLHEP::cm3);
114 }
115
116 //read amplitude of thermal oscillations
117 for(G4int i=0; i<fNelements; i++)
118 {
119 vfilein >> var;
120 fU1.push_back(var*CLHEP::cm);
121 }
122
123 if (iModel==1)
124 {
125 // read channel dimensions
126 vfilein >> fDx;
127 fDx*=CLHEP::cm;
128 // read interpolation step size
129 vfilein >> fNpointsx;
130
131 fDy = fDx;
132 fNpointsy = 0;
133 }
134 else if (iModel==2)
135 {
136 // read channel dimensions
137 vfilein >> fDx >> fDy;
138 fDx*=CLHEP::cm;
139 fDy*=CLHEP::cm;
140 // read the number of nodes of interpolation
141 vfilein >> fNpointsx >> fNpointsy;
142 }
143
144 //read the height of the potential well, necessary only for step length calculation
145 vfilein >> fVmax;
146 fVmax*=CLHEP::eV;
147 fVmax2=2.*fVmax;
148
149 //read the on-zero minimal potential inside the crystal,
150 //necessary for angle recalculation for entrance/exit through
151 //the crystal lateral surface
152 vfilein >> fVMinCrystal;
153 fVMinCrystal*=CLHEP::eV;
154
155 // to create the class of interpolation for any function
157 new G4ChannelingFastSimInterpolation(fDx,fDy,fNpointsx,fNpointsy,iModel);
158 if(iModel==2) {fElectricFieldY =
159 new G4ChannelingFastSimInterpolation(fDx,fDy,fNpointsx,fNpointsy,iModel);}
161 new G4ChannelingFastSimInterpolation(fDx,fDy,fNpointsx,fNpointsy,iModel);
163 new G4ChannelingFastSimInterpolation(fDx,fDy,fNpointsx,fNpointsy,iModel);
164
165 // do it for any element of crystal material
166 for(G4int i=0; i<fNelements; i++)
167 {
168 fNucleiDensity.push_back(
169 new G4ChannelingFastSimInterpolation(fDx,fDy,fNpointsx,fNpointsy,iModel));
170 }
171
172 if (iModel==1)
173 {
174 G4double ai, bi, ci, di;
175 for(G4int i=0; i<fNpointsx; i++)
176 {
177 //reading the coefficients of cubic spline
178 vfilein >> ai >> bi >> ci >> di;
179 //setting spline coefficients for electric field
180 unitIF=CLHEP::eV/CLHEP::cm;
181 fElectricFieldX->SetCoefficients1D(ai*unitIF, bi*unitIF,
182 ci*unitIF, di*unitIF, i);
183
184 //reading the coefficients of cubic spline
185 vfilein >> ai >> bi >> ci >> di;
186 //setting spline coefficients for nuclear density (first element)
187 unitIF=1.;
188 fNucleiDensity[0]->SetCoefficients1D(ai*unitIF, bi*unitIF,
189 ci*unitIF, di*unitIF, i);
190
191 //reading the coefficients of cubic spline
192 vfilein >> ai >> bi >> ci >> di;
193 //setting spline coefficients for electron density
194 unitIF=1./CLHEP::cm3;
195 fElectronDensity->SetCoefficients1D(ai*unitIF, bi*unitIF,
196 ci*unitIF, di*unitIF, i);
197
198 //reading the coefficients of cubic spline
199 vfilein >> ai >> bi >> ci >> di;
200 //setting spline coefficients for minimal ionization energy
201 unitIF=CLHEP::eV;
202 fMinIonizationEnergy->SetCoefficients1D(ai*unitIF, bi*unitIF,
203 ci*unitIF, di*unitIF, i);
204
205 for(G4int ii=1; ii<fNelements; ii++)
206 {
207 //reading the coefficients of cubic spline
208 vfilein >> ai >> bi >> ci >> di;
209 //setting spline coefficients for nuclear density (other elements if any)
210 unitIF=1.;
211 fNucleiDensity[ii]->SetCoefficients1D(ai*unitIF, bi*unitIF,
212 ci*unitIF, di*unitIF, i);
213 }
214 }
215 }
216 else if (iModel==2)
217 {
218 G4double ai3D, bi3D, ci3D;
219 for(G4int j=0; j<fNpointsy; j++)
220 {
221 for(G4int i=0; i<fNpointsx+1; i++)
222 {
223 for(G4int k=0; k<2; k++)
224 {
225 //reading the coefficients of cubic spline
226 vfilein >> ai3D >> bi3D >> ci3D;
227 unitIF=CLHEP::eV;
228 //setting spline coefficients for minimal ionization energy
229 fMinIonizationEnergy->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
230 i, j, k);
231
232 //reading the coefficients of cubic spline
233 vfilein >> ai3D >> bi3D >> ci3D;
234 //setting spline coefficients for horizontal electric field
235 unitIF=CLHEP::eV/CLHEP::cm;
236 fElectricFieldX->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
237 i, j, k);
238
239 //reading the coefficients of cubic spline
240 vfilein >> ai3D >> bi3D >> ci3D;
241 //setting spline coefficients for vertical electric field
242 unitIF=CLHEP::eV/CLHEP::cm;
243 fElectricFieldY->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
244 i, j, k);
245
246 //reading the coefficients of cubic spline
247 vfilein >> ai3D >> bi3D >> ci3D;
248 //setting spline coefficients for nuclear density (first element)
249 unitIF=1.;
250 fNucleiDensity[0]->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
251 i, j, k);
252
253 //reading the coefficients of cubic spline
254 vfilein >> ai3D >> bi3D >> ci3D;
255 //setting spline coefficients for electron density
256 unitIF=1./CLHEP::cm3;
257 fElectronDensity->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF, ci3D*unitIF,
258 i, j, k);
259
260 for(G4int ii=1; ii<fNelements; ii++)
261 {
262 //reading the coefficients of cubic spline
263 vfilein >> ai3D >> bi3D >> ci3D;
264 //setting spline coefficients for nuclear density (other elements if any)
265 unitIF=1.;
266 fNucleiDensity[ii]->SetCoefficients2D(ai3D*unitIF, bi3D*unitIF,
267 ci3D*unitIF,
268 i, j, k);
269 }
270
271 }
272 }
273 }
274 }
275
276 vfilein.close();
277
278 //set special values and coefficients
279 G4double alphahbarc2=std::pow(CLHEP::fine_structure_const*CLHEP::hbarc ,2.);
280 fK30=2.*CLHEP::pi*alphahbarc2/CLHEP::electron_mass_c2;
281
282 for(G4int i=0; i<fNelements; i++)
283 {
284 fRF.push_back((std::pow(9*CLHEP::pi*CLHEP::pi/128/fZ1[i],1/3.))
285 *0.5291772109217*CLHEP::angstrom);//Thomas-Fermi screening radius
286
287 fTetamax0.push_back(CLHEP::hbarc/(fR0*std::pow(fAN[i],1./3.)));
288 fTeta10.push_back(CLHEP::hbarc/fRF[i]);
289 fPu11.push_back(std::pow(fU1[i]/CLHEP::hbarc,2.));
290
291 fK20.push_back(alphahbarc2*4*CLHEP::pi*fN0[i]*fZ1[i]*fZ1[i]);
292
293 fK40.push_back(3.76*std::pow(CLHEP::fine_structure_const*fZ1[i],2.));
294
295 fKD.push_back(fK30*fZ1[i]*fN0[i]);
296
297 fLogPlasmaEdI0.push_back(G4Log((crystal->GetIonisation()->GetPlasmaEnergy())/fI0[i]));
298 }
299
300 fBB.resize(fNelements);
301 fE1XBbb.resize(fNelements);
302 fBBDEXP.resize(fNelements);
303 fPzu11.resize(fNelements);
304 fTeta12.resize(fNelements);
305 fTetamax2.resize(fNelements);
306 fTetamax12.resize(fNelements);
307 fK2.resize(fNelements);
308
309 fChangeStep = CLHEP::pi*std::min(fDx,fDy)/fNsteps;//necessary to define simulation
310 //step = fChannelingStep =
311 // = fChannelingStep0*sqrt(pv)
312}
313
314//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
315
317 (const G4ThreeVector &pos0)
318{
319 G4double x0=pos0.x(),y0=pos0.y(),z0=pos0.z();
320 z0+=fHalfDimBoundingBox.z();
321 G4double x,y,z;
322
323 if (fBent)
324 {
325 // for bent crystal
326 G4double rsqrt = std::sqrt(fBendingRsquare -
328 x0*x0 + z0*z0);
329 //transform to co-rotating reference system connected with "central plane/axis"
330 x = fBendingR - rsqrt;
331 y = y0;
332 z = fBendingR*std::asin((z0*fCosMiscutAngle + x0*fSinMiscutAngle)/rsqrt);
333 }
334 else
335 {
336 //for straight crystal
338 y = y0;
340
341 //for crystalline undulator
342 if(fCU){x-=GetCUx(z);}
343 }
344
345 //calculation of coordinates within a channel (periodic cell)
346 fNChannelx=std::floor(x/fDx); //remember the horizontal channel number
347 //to track the particle
348 x-=fNChannelx*fDx;
349 fNChannely=std::floor(y/fDy);//remember the vertical channel number
350 //to track the particle (=0 for planar case)
351 y-=fNChannely*fDy;
352 //correction of the longitudinal coordinate
353 if (fBent) {fCorrectionZ = fBendingR/(fBendingR-fNChannelx*fDx);}
354
355 return G4ThreeVector(x,y,z);
356}
357
358//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
359
361 const G4ThreeVector &pos)
362{
363 G4double x=pos.x(),y=pos.y(),z=pos.z();
364
365 //transform to co-rotating reference system connected with "central plane/axis"
366 x+=fNChannelx*fDx;
367 y+=fNChannely*fDy;
368
369 G4double x0,y0,z0;
370
371 if (fBent)
372 {
373 // for bent crystal
374 G4double rcos = (fBendingR - x)*(1. - std::cos(z/fBendingR));
375 G4double a = x + rcos;
376 G4double b = std::sqrt(x*x + fBending2R*rcos - a*a);
377
378 //transform to Box coordinates
380 y0 = y;
382 }
383 else
384 {
385 //for crystalline undulator
386 if(fCU){x+=GetCUx(z);}
387
388 //for straight crystal
390 y0 = y;
392 }
393
394 return G4ThreeVector(x0,y0,z0-fHalfDimBoundingBox.z());
395}
396
397//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
398
400 G4double& y,
401 G4double& z)
402{
403
404 //test of enter in other channel
405 if (x<0)
406 {
407 fNChannelx-=1;
408 x+=fDx; //enter in other channel
409 //correction of the longitudinal coordinate
410 if (fBent) {fCorrectionZ = fBendingR/(fBendingR-fNChannelx*fDx);}
411 }
412 else if (x>=fDx)
413 {
414 fNChannelx+=1;
415 x-=fDx; //enter in other channel
416 //correction of the longitudinal coordinate
417 if (fBent) {fCorrectionZ = fBendingR/(fBendingR-fNChannelx*fDx);}
418 }
419
420 //test of enter in other channel
421 if (y<0)
422 {
423 fNChannely-=1;
424 y+=fDy; //enter in other channel
425 }
426 else if (y>=fDy)
427 {
428 fNChannely+=1;
429 y-=fDy; //enter in other channel
430 }
431
432 return G4ThreeVector(x,y,z);
433}
434
435//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
Definition of the G4ChannelingFastSimCrystalData class The class inherits G4VChannelingFastSimCrystal...
const char * G4FindDataDir(const char *)
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Log(G4double x)
Definition G4Log.hh:169
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double y() const
G4ThreeVector CoordinatesFromBoxToLattice(const G4ThreeVector &pos0)
void SetMaterialProperties(const G4Material *crystal, const G4String &lattice, const G4String &filePath)
G4ThreeVector ChannelChange(G4double &x, G4double &y, G4double &z)
change the channel if necessary, recalculate x o y
G4ThreeVector CoordinatesFromLatticeToBox(const G4ThreeVector &pos)
G4double GetAtomicMassAmu() const
Definition G4Element.hh:124
G4double GetZ() const
Definition G4Element.hh:119
G4IonisParamElm * GetIonisation() const
Definition G4Element.hh:171
G4double GetMeanExcitationEnergy() const
G4double GetPlasmaEnergy() const
const G4Element * GetElement(G4int iel) const
G4IonisParamMat * GetIonisation() const
std::size_t GetNumberOfElements() const
const G4String & GetName() const
std::vector< G4double > fK20
coefficients necessary for multiple and single coulomb scattering
std::vector< G4ChannelingFastSimInterpolation * > fNucleiDensity
G4ChannelingFastSimInterpolation * fMinIonizationEnergy
G4ChannelingFastSimInterpolation * fElectricFieldY
G4ThreeVector fHalfDimBoundingBox
values related to the crystal geometry
G4ChannelingFastSimInterpolation * fElectricFieldX
classes containing interpolation coefficients
G4ChannelingFastSimInterpolation * fElectronDensity
G4int fNelements
values related to the crystal lattice
std::vector< G4double > fTeta10
angles necessary for multiple and single coulomb scattering
G4double GetCUx(G4double z)
get crystalline undulator wave function
std::vector< G4double > fPu11
coefficients for multiple scattering suppression