155{
158 if((kineticEnergy <= 0.0) || (tPathLength <= tlimitminfix)||
160
161
162
164 if (tPathLength > currentRange*
dtrl) {
165 eloss = kineticEnergy -
166 GetEnergy(particle,currentRange-tPathLength,currentCouple);
167 } else {
168 eloss = tPathLength*
GetDEDX(particle,kineticEnergy,currentCouple);
169 }
170
171
172
173
174
175
176
177 kineticEnergy -= 0.5*eloss;
178
179
180
186 lambda0 = 0.0;
187 for(
G4int i=0;i<nelm;i++)
188 {
189 CalculateIntegrals(particle,(*theElementVector)[i]->GetZ(),kineticEnergy,s0,s1);
190 lambda0 += (theAtomNumDensityVector[i]*
s0);
191 }
192 if(lambda0>0.0) lambda0 =1./lambda0;
193
194
195
197 if(lambda1>0.0) { g1 = lambda0/lambda1; }
198
201
202 for(
G4int i=0;i<1000;++i)
203 {
204 logx0=std::log(1.+1./x0);
205 x1 = x0-(x0*((1.+x0)*logx0-1.0)-g1*0.5)/( (1.+2.*x0)*logx0-2.0);
206
207
208 if(x1 < 0.0) { x1 = 0.5*x0; }
209 else if(x1 > 2*x0) { x1 = 2*x0; }
210 else if(x1 < 0.5*x0) { x1 = 0.5*x0; }
211 delta = std::fabs( x1 - x0 );
212 x0 = x1;
213 if(delta < 1.0e-3*x1) { break;}
214 }
216
218
219 if(lambda0>0.0) { lambdan=tPathLength/lambda0; }
221
222
223
224
227
228 G4double cosTheta1,sinTheta1,cosTheta2,sinTheta2;
229 G4double cosPhi1=1.0,sinPhi1=0.0,cosPhi2=1.0,sinPhi2=0.0;
230 G4double us=0.0,vs=0.0,ws=1.0,wss=0.,x_coord=0.0,y_coord=0.0,z_coord=1.0;
231
234
235 if(epsilon1<expn)
237 else if((epsilon1<((1.+lambdan)*expn))||(lambdan<1.))
238 {
240 xi= 2.*scrA*xi/(1.-xi + scrA);
241 if(xi<0.)xi=0.;
242 else if(xi>2.)xi=2.;
243 ws=(1. - xi);
244 wss=std::sqrt(xi*(2.-xi));
246 us=wss*cos(phi0);
247 vs=wss*sin(phi0);
248 }
249 else
250 {
251
252
253 SampleCosineTheta(0.5*lambdan,scrA,cosTheta1,sinTheta1);
255 cosPhi1 = cos(phi1);
256 sinPhi1 = sin(phi1);
257
258
259 SampleCosineTheta(0.5*lambdan,scrA,cosTheta2,sinTheta2);
261 cosPhi2 = cos(phi2);
262 sinPhi2 = sin(phi2);
263
264
265 us = sinTheta2*(cosTheta1*cosPhi1*cosPhi2 - sinPhi1*sinPhi2) + cosTheta2*sinTheta1*cosPhi1;
266 vs = sinTheta2*(cosTheta1*sinPhi1*cosPhi2 + cosPhi1*sinPhi2) + cosTheta2*sinTheta1*sinPhi1;
267 ws = cosTheta1*cosTheta2 - sinTheta1*sinTheta2*cosPhi2;
269 if(acos(ws)<sqrtA)
270 {
272 do{i++;
274 }while((fabs(ws)>1.)&&(i<20));
275 if(i>=19)ws=cos(sqrtA);
276 wss=std::sqrt((1.-ws*ws));
277 us=wss*std::cos(phi1);
278 vs=wss*std::sin(phi1);
279 }
280 }
281
284 newDirection.rotateUz(oldDirection);
286
287
288 if(Qn1<0.02) { z_coord = 1.0 - Qn1*(0.5 - Qn1/6.); }
289 else { z_coord = (1.-std::exp(-Qn1))/Qn1; }
290 G4double rr = zPathLength*std::sqrt((1.- z_coord*z_coord)/(1.-ws*ws));
291 x_coord = rr*us;
292 y_coord = rr*vs;
293
294
295 z_coord -= 1.0;
296 z_coord *= zPathLength;
297
298
299
300
301
302
303
304
307
309}
std::vector< G4Element * > G4ElementVector
void set(double x, double y, double z)
Hep3Vector & rotateUz(const Hep3Vector &)
const G4ThreeVector & GetMomentumDirection() const
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
size_t GetNumberOfElements() const
const G4double * GetVecNbOfAtomsPerVolume() const
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
G4double GetDEDX(const G4ParticleDefinition *part, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4ThreeVector fDisplacement