165{
166 G4double geometryStepLength, newSafety ;
168
169
170
171
172
173
174
175
176
177
179
180
181
182 const G4DynamicParticle* pParticle =
track.GetDynamicParticle() ;
183 const G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ;
184 const G4ThreeVector& startMomentumDir = pParticle->GetMomentumDirection() ;
185 G4ThreeVector startPosition =
track.GetPosition() ;
186
187
188
189
190
191
192
194 G4double MagSqShift = OriginShift.mag2() ;
196 {
197 currentSafety = 0.0 ;
198 }
199 else
200 {
202 }
203
204
205
206 G4double particleMagCharge =
mplParticle->MagneticCharge();
207 G4double particleElCharge = pParticle->GetCharge() ;
208
209
210
211
212
214
215
216
217
218
219
220
221
222 G4FieldManager* fieldMgr=0;
223 G4bool fieldExertsForce = false ;
224 if( (particleElCharge != 0.0) || (particleMagCharge!=0.0) )
225 {
227
229
230
231
232 if (fieldMgr != oldFieldMgr) {
234
236 }
237
238 if (fieldMgr != nullptr) {
239
240 fieldMgr->ConfigureForTrack( &track );
241
242
243
244
245 if (particleMagCharge!=0.0) fieldMgr->SetFieldChangesEnergy(true);
246
247
248 fieldExertsForce = (fieldMgr->GetDetectorField() != nullptr);
249
250 if( fieldExertsForce)
251 fEquationSetup->SwitchStepperAndChordFinder( (particleMagCharge != 0.0), fieldMgr );
252
253
254 }
255
256 }
257
258
259
260 if( !fieldExertsForce )
261 {
262 G4double linearStepLength ;
264 {
265
266
267 geometryStepLength = currentMinimumStep ;
269 }
270 else
271 {
272
273
275 startMomentumDir,
276 currentMinimumStep,
277 newSafety) ;
278
279
282
283
284
285
286 currentSafety = newSafety ;
287
290 {
291
292 geometryStepLength = linearStepLength ;
293 }
294 else
295 {
296
297 geometryStepLength = currentMinimumStep ;
298 }
299 }
301
302
303
305
306
307
314 }
315 else
316 {
317 G4ThreeVector EndUnitMomentum ;
318 G4double lengthAlongCurve ;
319 G4double restMass = pParticleDef->GetPDGMass() ;
320#if G4VERSION_NUMBER > 1009
321 G4double momentumMagnitude = pParticle->GetTotalMomentum();
322 G4ChargeState chargeState(particleElCharge,
323 pParticleDef->GetPDGSpin(),
324 0,
325 0,
326 particleMagCharge);
327 G4EquationOfMotion* equationOfMotion = (
fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())->GetEquationOfMotion();
328 equationOfMotion->SetChargeMomentumMass(chargeState,
329 momentumMagnitude,
330 -restMass );
331#else
333 particleMagCharge,
334 -restMass );
335#endif
336
337 G4ThreeVector
spin =
track.GetPolarization() ;
338 G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
339 track.GetMomentumDirection(),
340 0.0,
341 track.GetKineticEnergy(),
342 restMass,
344 track.GetGlobalTime(),
345 track.GetProperTime(),
347 if( currentMinimumStep > 0 )
348 {
349
350
351
353 currentMinimumStep,
354 currentSafety,
355 track.GetVolume() ) ;
358 geometryStepLength = lengthAlongCurve ;
359 } else {
360 geometryStepLength = currentMinimumStep ;
361 }
362 }
363 else
364 {
365 geometryStepLength = lengthAlongCurve= 0.0 ;
367 }
369
370
371
373
375
376
377
378
380
381
382
385
387
389 {
390
391
392
395
396
397
398 }
399 else
400 {
401
402
404
405
406
407 G4double startEnergy=
track.GetKineticEnergy();
409
410 static std::atomic<G4int> no_inexact_steps=0, no_large_ediff;
411 G4double absEdiff = std::fabs(startEnergy- endEnergy);
412 if( absEdiff > CLHEP::perMillion * endEnergy )
413 {
414 no_inexact_steps++;
415
416 }
418 {
419 if( std::fabs(startEnergy- endEnergy) > CLHEP::perThousand * endEnergy )
420 {
421 static std::atomic<G4int> no_warnings= 0, warnModulo=1, moduloFactor= 10;
422 no_large_ediff ++;
423 if( (no_large_ediff% warnModulo) == 0 )
424 {
425 no_warnings++;
426 G4cout << "WARNING - G4mplAtlasTransportation::AlongStepGetPIL() "
427 << " Energy change in Step is above 1^-3 relative value. " << G4endl
428 << " Relative change in 'tracking' step = "
429 << std::setw(15) << (endEnergy-startEnergy)/startEnergy << G4endl
430 << " Starting E= " << std::setw(12) << startEnergy / CLHEP::MeV << " MeV " << G4endl
431 << " Ending E= " << std::setw(12) << endEnergy / CLHEP::MeV << " MeV " << G4endl;
432 G4cout << " Energy has been corrected -- however, review"
433 << " field propagation parameters for accuracy." << G4endl;
434 if( (
fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) ){
435 G4cout << " These include EpsilonStepMax(/Min) in G4FieldManager "
436 << " which determine fractional error per step for integrated quantities. " << G4endl
437 << " Note also the influence of the permitted number of integration steps."
438 << G4endl;
439 }
440 G4cerr << "ERROR - G4mplAtlasTransportation::AlongStepGetPIL()" << G4endl
441 << " Bad 'endpoint'. Energy change detected"
442 << " and corrected. "
443 << " Has occurred already "
444 << no_large_ediff << " times." << G4endl;
445 if( no_large_ediff == warnModulo * moduloFactor )
446 {
447 warnModulo = warnModulo * moduloFactor;
448 }
449 }
450 }
451 }
452
453
454
455
457 }
458
462
463 fieldMgr->SetFieldChangesEnergy(false);
464
465 }
466
467
468
469
470 if( currentMinimumStep == 0.0 )
471 {
473 }
474
475
476
477
479 {
480
481
482
483
484
485 G4double endSafety =
487 currentSafety = endSafety ;
491
492
493
494
496
497#ifdef G4DEBUG_TRANSPORT
498 G4cout.precision(12) ;
499 G4cout << "***G4mplAtlasTransportation::AlongStepGPIL ** " << G4endl ;
501 << " and it returned safety= " << endSafety << G4endl ;
503 << " to obtain pseudo-safety= " << currentSafety << G4endl ;
504#endif
505
506 }
507
508
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
529 }
531
532 return geometryStepLength ;
533}
Scalar mag() const
mag method
const std::string selection