1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | #include "G4Transportation.hh" |
61 | #include "G4TransportationProcessType.hh" |
62 | |
63 | #include "G4PhysicalConstants.hh" |
64 | #include "G4SystemOfUnits.hh" |
65 | #include "G4ProductionCutsTable.hh" |
66 | #include "G4ParticleTable.hh" |
67 | |
68 | #include "G4ChargeState.hh" |
69 | #include "G4EquationOfMotion.hh" |
70 | |
71 | #include "G4FieldManagerStore.hh" |
72 | |
73 | class G4VSensitiveDetector; |
74 | |
75 | G4bool G4Transportation::fUseMagneticMoment=false; |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | G4Transportation::G4Transportation( G4int verbosity ) |
84 | : G4VProcess( G4String("Transportation"), fTransportation ), |
85 | fTransportEndPosition( 0.0, 0.0, 0.0 ), |
86 | fTransportEndMomentumDir( 0.0, 0.0, 0.0 ), |
87 | fTransportEndKineticEnergy( 0.0 ), |
88 | fTransportEndSpin( 0.0, 0.0, 0.0 ), |
89 | fMomentumChanged(true), |
90 | fEndGlobalTimeComputed(false), |
91 | fCandidateEndGlobalTime(0.0), |
92 | fParticleIsLooping( false ), |
93 | fNewTrack( true ), |
94 | fFirstStepInVolume( true ), |
95 | fLastStepInVolume( false ), |
96 | fGeometryLimitedStep(true), |
97 | fFieldExertedForce( false ), |
98 | fPreviousSftOrigin( 0.,0.,0. ), |
99 | fPreviousSafety( 0.0 ), |
100 | |
101 | fEndPointDistance( -1.0 ), |
102 | fThreshold_Warning_Energy( 100 * MeV ), |
103 | fThreshold_Important_Energy( 250 * MeV ), |
104 | fThresholdTrials( 10 ), |
105 | fNoLooperTrials( 0 ), |
106 | fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ), |
107 | fShortStepOptimisation( false ), |
108 | fVerboseLevel( verbosity ) |
109 | { |
110 | |
111 | SetProcessSubType(static_cast<G4int>(TRANSPORTATION)); |
112 | pParticleChange= &fParticleChange; |
113 | |
114 | G4TransportationManager* transportMgr ; |
115 | |
116 | transportMgr = G4TransportationManager::GetTransportationManager() ; |
117 | |
118 | fLinearNavigator = transportMgr->GetNavigatorForTracking() ; |
119 | |
120 | fFieldPropagator = transportMgr->GetPropagatorInField() ; |
121 | |
122 | fpSafetyHelper = transportMgr->GetSafetyHelper(); |
123 | |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | static G4ThreadLocalthread_local G4TouchableHandle* pNullTouchableHandle = 0; |
130 | if ( !pNullTouchableHandle) { pNullTouchableHandle = new G4TouchableHandle; } |
131 | fCurrentTouchableHandle = *pNullTouchableHandle; |
132 | |
133 | |
134 | #ifdef G4VERBOSE1 |
135 | if( fVerboseLevel > 0) |
136 | { |
137 | G4cout(*G4cout_p) << " G4Transportation constructor> set fShortStepOptimisation to "; |
138 | if ( fShortStepOptimisation ) G4cout(*G4cout_p) << "true" << G4endlstd::endl; |
139 | else G4cout(*G4cout_p) << "false" << G4endlstd::endl; |
140 | } |
141 | #endif |
142 | } |
143 | |
144 | |
145 | |
146 | G4Transportation::~G4Transportation() |
147 | { |
148 | if( (fVerboseLevel > 0) && (fSumEnergyKilled > 0.0 ) ) |
149 | { |
150 | G4cout(*G4cout_p) << " G4Transportation: Statistics for looping particles " << G4endlstd::endl; |
151 | G4cout(*G4cout_p) << " Sum of energy of loopers killed: " << fSumEnergyKilled << G4endlstd::endl; |
152 | G4cout(*G4cout_p) << " Max energy of loopers killed: " << fMaxEnergyKilled << G4endlstd::endl; |
153 | } |
154 | } |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | G4double G4Transportation:: |
164 | AlongStepGetPhysicalInteractionLength( const G4Track& track, |
165 | G4double, |
166 | G4double currentMinimumStep, |
167 | G4double& currentSafety, |
168 | G4GPILSelection* selection ) |
169 | { |
170 | G4double geometryStepLength= -1.0, newSafety= -1.0; |
171 | fParticleIsLooping = false ; |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | *selection = CandidateForSelection ; |
183 | |
184 | fFirstStepInVolume= fNewTrack || fLastStepInVolume; |
185 | |
186 | fLastStepInVolume= false; |
187 | fNewTrack = false; |
188 | |
189 | fParticleChange.ProposeFirstStepInVolume(fFirstStepInVolume); |
190 | |
191 | |
192 | |
193 | const G4DynamicParticle* pParticle = track.GetDynamicParticle() ; |
194 | const G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ; |
195 | G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection() ; |
196 | G4ThreeVector startPosition = track.GetPosition() ; |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ; |
205 | G4double MagSqShift = OriginShift.mag2() ; |
206 | if( MagSqShift >= sqr(fPreviousSafety) ) |
207 | { |
208 | currentSafety = 0.0 ; |
209 | } |
210 | else |
211 | { |
212 | currentSafety = fPreviousSafety - std::sqrt(MagSqShift) ; |
213 | } |
214 | |
215 | |
216 | |
217 | G4double particleCharge = pParticle->GetCharge() ; |
218 | G4double magneticMoment = pParticle->GetMagneticMoment() ; |
219 | G4double restMass = pParticle->GetMass() ; |
220 | |
221 | fGeometryLimitedStep = false ; |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | |
230 | G4FieldManager* fieldMgr=0; |
231 | G4bool fieldExertsForce = false ; |
232 | |
233 | G4bool gravityOn = false; |
234 | G4bool fieldExists= false; |
235 | |
236 | fieldMgr = fFieldPropagator->FindAndSetFieldManager( track.GetVolume() ); |
237 | if( fieldMgr != 0 ) |
238 | { |
239 | |
240 | fieldMgr->ConfigureForTrack( &track ); |
241 | |
242 | |
243 | |
244 | |
245 | |
246 | const G4Field* ptrField= fieldMgr->GetDetectorField(); |
247 | fieldExists = (ptrField!=0) ; |
248 | if( fieldExists ) |
249 | { |
250 | gravityOn= ptrField->IsGravityActive(); |
251 | |
252 | if( (particleCharge != 0.0) |
253 | || (fUseMagneticMoment && (magneticMoment != 0.0) ) |
254 | || (gravityOn && (restMass != 0.0) ) |
255 | ) |
256 | { |
257 | fieldExertsForce = fieldExists; |
258 | } |
259 | } |
260 | } |
261 | |
262 | |
263 | fFieldExertedForce = fieldExertsForce; |
264 | |
265 | if( !fieldExertsForce ) |
266 | { |
267 | G4double linearStepLength ; |
268 | if( fShortStepOptimisation && (currentMinimumStep <= currentSafety) ) |
269 | { |
270 | |
271 | |
272 | geometryStepLength = currentMinimumStep ; |
273 | fGeometryLimitedStep = false ; |
274 | } |
275 | else |
276 | { |
277 | |
278 | |
279 | linearStepLength = fLinearNavigator->ComputeStep( startPosition, |
280 | startMomentumDir, |
281 | currentMinimumStep, |
282 | newSafety) ; |
283 | |
284 | |
285 | fPreviousSftOrigin = startPosition ; |
286 | fPreviousSafety = newSafety ; |
287 | fpSafetyHelper->SetCurrentSafety( newSafety, startPosition); |
288 | |
289 | currentSafety = newSafety ; |
290 | |
291 | fGeometryLimitedStep= (linearStepLength <= currentMinimumStep); |
292 | if( fGeometryLimitedStep ) |
293 | { |
294 | |
295 | geometryStepLength = linearStepLength ; |
296 | } |
297 | else |
298 | { |
299 | |
300 | geometryStepLength = currentMinimumStep ; |
301 | } |
302 | } |
303 | fEndPointDistance = geometryStepLength ; |
304 | |
305 | |
306 | |
307 | fTransportEndPosition = startPosition+geometryStepLength*startMomentumDir ; |
308 | |
309 | |
310 | |
311 | fTransportEndMomentumDir = startMomentumDir ; |
312 | fTransportEndKineticEnergy = track.GetKineticEnergy() ; |
313 | fTransportEndSpin = track.GetPolarization(); |
314 | fParticleIsLooping = false ; |
315 | fMomentumChanged = false ; |
316 | fEndGlobalTimeComputed = false ; |
317 | } |
318 | else |
319 | { |
320 | G4double momentumMagnitude = pParticle->GetTotalMomentum() ; |
321 | G4ThreeVector EndUnitMomentum ; |
322 | G4double lengthAlongCurve ; |
323 | |
324 | G4ChargeState chargeState(particleCharge, |
325 | magneticMoment, |
326 | pParticleDef->GetPDGSpin() ); |
327 | |
328 | |
329 | |
330 | G4EquationOfMotion* equationOfMotion = |
331 | (fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper()) |
332 | ->GetEquationOfMotion(); |
333 | |
334 | |
335 | equationOfMotion->SetChargeMomentumMass( chargeState, |
336 | momentumMagnitude, |
337 | restMass); |
338 | |
339 | G4FieldTrack aFieldTrack = G4FieldTrack( startPosition, |
340 | track.GetGlobalTime(), |
341 | |
342 | track.GetMomentumDirection(), |
343 | track.GetKineticEnergy(), |
344 | restMass, |
345 | particleCharge, |
346 | track.GetPolarization(), |
347 | pParticleDef->GetPDGMagneticMoment(), |
348 | 0.0, |
349 | pParticleDef->GetPDGSpin() |
350 | ) ; |
351 | |
352 | if( currentMinimumStep > 0 ) |
353 | { |
354 | |
355 | |
356 | lengthAlongCurve = fFieldPropagator->ComputeStep( aFieldTrack, |
357 | currentMinimumStep, |
358 | currentSafety, |
359 | track.GetVolume() ) ; |
360 | |
361 | fGeometryLimitedStep= fFieldPropagator->IsLastStepInVolume(); |
362 | |
363 | |
364 | |
365 | |
366 | geometryStepLength = std::min( lengthAlongCurve, currentMinimumStep ); |
367 | |
368 | |
369 | |
370 | fPreviousSftOrigin = startPosition ; |
371 | fPreviousSafety = currentSafety ; |
372 | fpSafetyHelper->SetCurrentSafety( currentSafety, startPosition); |
373 | } |
374 | else |
375 | { |
376 | geometryStepLength = lengthAlongCurve= 0.0 ; |
377 | fGeometryLimitedStep = false ; |
378 | } |
379 | |
380 | |
381 | |
382 | fTransportEndPosition = aFieldTrack.GetPosition() ; |
383 | |
384 | |
385 | |
386 | fMomentumChanged = true ; |
387 | fTransportEndMomentumDir = aFieldTrack.GetMomentumDir() ; |
388 | |
389 | fTransportEndKineticEnergy = aFieldTrack.GetKineticEnergy() ; |
390 | |
391 | if( fFieldPropagator->GetCurrentFieldManager()->DoesFieldChangeEnergy() ) |
392 | { |
393 | |
394 | |
395 | |
396 | fCandidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight(); |
397 | fEndGlobalTimeComputed = true; |
398 | |
399 | |
400 | |
401 | } |
402 | else |
403 | { |
404 | |
405 | |
406 | |
407 | fEndGlobalTimeComputed = false; |
408 | |
409 | |
410 | |
411 | G4double startEnergy= track.GetKineticEnergy(); |
412 | G4double endEnergy= fTransportEndKineticEnergy; |
413 | |
414 | static G4ThreadLocalthread_local G4int no_inexact_steps=0, no_large_ediff; |
415 | G4double absEdiff = std::fabs(startEnergy- endEnergy); |
416 | if( absEdiff > perMillion * endEnergy ) |
417 | { |
418 | no_inexact_steps++; |
419 | |
420 | } |
421 | if( fVerboseLevel > 1 ) |
422 | { |
423 | if( std::fabs(startEnergy- endEnergy) > perThousand * endEnergy ) |
424 | { |
425 | static G4ThreadLocalthread_local G4int no_warnings= 0, warnModulo=1, |
426 | moduloFactor= 10; |
427 | no_large_ediff ++; |
428 | if( (no_large_ediff% warnModulo) == 0 ) |
429 | { |
430 | no_warnings++; |
431 | G4cout(*G4cout_p) << "WARNING - G4Transportation::AlongStepGetPIL() " |
432 | << " Energy change in Step is above 1^-3 relative value. " << G4endlstd::endl |
433 | << " Relative change in 'tracking' step = " |
434 | << std::setw(15) << (endEnergy-startEnergy)/startEnergy << G4endlstd::endl |
435 | << " Starting E= " << std::setw(12) << startEnergy / MeV << " MeV " << G4endlstd::endl |
436 | << " Ending E= " << std::setw(12) << endEnergy / MeV << " MeV " << G4endlstd::endl; |
437 | G4cout(*G4cout_p) << " Energy has been corrected -- however, review" |
438 | << " field propagation parameters for accuracy." << G4endlstd::endl; |
439 | if( (fVerboseLevel > 2 ) || (no_warnings<4) || (no_large_ediff == warnModulo * moduloFactor) ) |
440 | { |
441 | G4cout(*G4cout_p) << " These include EpsilonStepMax(/Min) in G4FieldManager " |
442 | << " which determine fractional error per step for integrated quantities. " << G4endlstd::endl |
443 | << " Note also the influence of the permitted number of integration steps." |
444 | << G4endlstd::endl; |
445 | } |
446 | G4cerr(*G4cerr_p) << "ERROR - G4Transportation::AlongStepGetPIL()" << G4endlstd::endl |
447 | << " Bad 'endpoint'. Energy change detected" |
448 | << " and corrected. " |
449 | << " Has occurred already " |
450 | << no_large_ediff << " times." << G4endlstd::endl; |
451 | if( no_large_ediff == warnModulo * moduloFactor ) |
452 | { |
453 | warnModulo *= moduloFactor; |
454 | } |
455 | } |
456 | } |
457 | } |
458 | |
459 | |
460 | |
461 | |
462 | fTransportEndKineticEnergy= track.GetKineticEnergy(); |
463 | } |
464 | |
465 | fTransportEndSpin = aFieldTrack.GetSpin(); |
466 | fParticleIsLooping = fFieldPropagator->IsParticleLooping() ; |
467 | fEndPointDistance = (fTransportEndPosition - startPosition).mag() ; |
468 | } |
469 | |
470 | |
471 | |
472 | |
473 | if( currentMinimumStep == 0.0 ) |
474 | { |
475 | if( currentSafety == 0.0 ) { fGeometryLimitedStep = true; } |
476 | } |
477 | |
478 | |
479 | |
480 | |
481 | if( currentSafety < fEndPointDistance ) |
482 | { |
483 | if( particleCharge != 0.0 ) |
484 | { |
485 | G4double endSafety = |
486 | fLinearNavigator->ComputeSafety( fTransportEndPosition) ; |
487 | currentSafety = endSafety ; |
488 | fPreviousSftOrigin = fTransportEndPosition ; |
489 | fPreviousSafety = currentSafety ; |
490 | fpSafetyHelper->SetCurrentSafety( currentSafety, fTransportEndPosition); |
491 | |
492 | |
493 | |
494 | |
495 | currentSafety += fEndPointDistance ; |
496 | |
497 | #ifdef G4DEBUG_TRANSPORT |
498 | G4cout(*G4cout_p).precision(12) ; |
499 | G4cout(*G4cout_p) << "***G4Transportation::AlongStepGPIL ** " << G4endlstd::endl ; |
500 | G4cout(*G4cout_p) << " Called Navigator->ComputeSafety at " << fTransportEndPosition |
501 | << " and it returned safety= " << endSafety << G4endlstd::endl ; |
502 | G4cout(*G4cout_p) << " Adding endpoint distance " << fEndPointDistance |
503 | << " to obtain pseudo-safety= " << currentSafety << G4endlstd::endl ; |
504 | } |
505 | else |
506 | { |
507 | G4cout(*G4cout_p) << "***G4Transportation::AlongStepGPIL ** " << G4endlstd::endl ; |
508 | G4cout(*G4cout_p) << " Avoiding call to ComputeSafety : " << G4endlstd::endl; |
509 | G4cout(*G4cout_p) << " charge = " << particleCharge << G4endlstd::endl; |
510 | G4cout(*G4cout_p) << " mag moment = " << magneticMoment << G4endlstd::endl; |
511 | #endif |
512 | } |
513 | } |
514 | |
515 | fParticleChange.ProposeTrueStepLength(geometryStepLength) ; |
516 | |
517 | return geometryStepLength ; |
518 | } |
519 | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 | G4VParticleChange* G4Transportation::AlongStepDoIt( const G4Track& track, |
526 | const G4Step& stepData ) |
527 | { |
528 | static G4ThreadLocalthread_local G4int noCalls=0; |
529 | noCalls++; |
530 | |
531 | fParticleChange.Initialize(track) ; |
532 | |
533 | |
534 | |
535 | fParticleChange.ProposePosition(fTransportEndPosition) ; |
536 | fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir) ; |
537 | fParticleChange.ProposeEnergy(fTransportEndKineticEnergy) ; |
538 | fParticleChange.SetMomentumChanged(fMomentumChanged) ; |
539 | |
540 | fParticleChange.ProposePolarization(fTransportEndSpin); |
541 | |
542 | G4double deltaTime = 0.0 ; |
543 | |
544 | |
545 | |
546 | |
547 | |
548 | G4double startTime = track.GetGlobalTime() ; |
549 | |
550 | if (!fEndGlobalTimeComputed) |
551 | { |
552 | |
553 | |
554 | G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity(); |
555 | G4double stepLength = track.GetStepLength(); |
556 | |
557 | deltaTime= 0.0; |
558 | if ( initialVelocity > 0.0 ) { deltaTime = stepLength/initialVelocity; } |
559 | |
560 | fCandidateEndGlobalTime = startTime + deltaTime ; |
561 | fParticleChange.ProposeLocalTime( track.GetLocalTime() + deltaTime) ; |
562 | } |
563 | else |
564 | { |
565 | deltaTime = fCandidateEndGlobalTime - startTime ; |
566 | fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ; |
567 | } |
568 | |
569 | |
570 | |
571 | |
572 | G4double restMass = track.GetDynamicParticle()->GetMass() ; |
573 | G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ; |
574 | |
575 | fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ; |
576 | |
577 | |
578 | |
579 | |
580 | |
581 | |
582 | if ( fParticleIsLooping ) |
583 | { |
584 | G4double endEnergy= fTransportEndKineticEnergy; |
585 | |
586 | if( (endEnergy < fThreshold_Important_Energy) |
587 | || (fNoLooperTrials >= fThresholdTrials ) ) |
588 | { |
589 | |
590 | |
591 | fParticleChange.ProposeTrackStatus( fStopAndKill ) ; |
592 | |
593 | |
594 | fSumEnergyKilled += endEnergy; |
595 | if( endEnergy > fMaxEnergyKilled) { fMaxEnergyKilled= endEnergy; } |
596 | |
597 | #ifdef G4VERBOSE1 |
598 | if( (fVerboseLevel > 1) && |
599 | ( endEnergy > fThreshold_Warning_Energy ) ) |
600 | { |
601 | G4cout(*G4cout_p) << " G4Transportation is killing track that is looping or stuck " |
602 | << G4endlstd::endl |
603 | << " This track has " << track.GetKineticEnergy() / MeV |
604 | << " MeV energy." << G4endlstd::endl; |
605 | G4cout(*G4cout_p) << " Number of trials = " << fNoLooperTrials |
606 | << " No of calls to AlongStepDoIt = " << noCalls |
607 | << G4endlstd::endl; |
608 | } |
609 | #endif |
610 | fNoLooperTrials=0; |
611 | } |
612 | else |
613 | { |
614 | fNoLooperTrials ++; |
615 | #ifdef G4VERBOSE1 |
616 | if( (fVerboseLevel > 2) ) |
617 | { |
618 | G4cout(*G4cout_p) << " G4Transportation::AlongStepDoIt(): Particle looping - " |
619 | << " Number of trials = " << fNoLooperTrials |
620 | << " No of calls to = " << noCalls |
621 | << G4endlstd::endl; |
622 | } |
623 | #endif |
624 | } |
625 | } |
626 | else |
627 | { |
628 | fNoLooperTrials=0; |
629 | } |
630 | |
631 | |
632 | |
633 | |
634 | |
635 | |
636 | fParticleChange.SetPointerToVectorOfAuxiliaryPoints |
637 | (fFieldPropagator->GimmeTrajectoryVectorAndForgetIt() ); |
638 | |
639 | return &fParticleChange ; |
640 | } |
641 | |
642 | |
643 | |
644 | |
645 | |
646 | |
647 | |
648 | G4double G4Transportation:: |
649 | PostStepGetPhysicalInteractionLength( const G4Track&, |
650 | G4double, |
651 | G4ForceCondition* pForceCond ) |
652 | { |
653 | fFieldExertedForce = false; |
654 | *pForceCond = Forced ; |
655 | return DBL_MAXstd::numeric_limits<double>::max() ; |
656 | } |
657 | |
658 | |
659 | |
660 | |
661 | G4VParticleChange* G4Transportation::PostStepDoIt( const G4Track& track, |
662 | const G4Step& ) |
663 | { |
664 | G4TouchableHandle retCurrentTouchable ; |
665 | G4bool isLastStep= false; |
666 | |
667 | |
668 | |
669 | |
670 | |
671 | fParticleChange.ProposeTrackStatus(track.GetTrackStatus()) ; |
672 | |
673 | |
674 | |
675 | |
676 | if(fGeometryLimitedStep) |
677 | { |
678 | |
679 | |
680 | |
681 | |
682 | fLinearNavigator->SetGeometricallyLimitedStep() ; |
683 | fLinearNavigator-> |
684 | LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(), |
685 | track.GetMomentumDirection(), |
686 | fCurrentTouchableHandle, |
687 | true ) ; |
688 | |
689 | |
690 | |
691 | if( fCurrentTouchableHandle->GetVolume() == 0 ) |
692 | { |
693 | fParticleChange.ProposeTrackStatus( fStopAndKill ) ; |
694 | } |
695 | retCurrentTouchable = fCurrentTouchableHandle ; |
696 | fParticleChange.SetTouchableHandle( fCurrentTouchableHandle ) ; |
697 | |
698 | |
699 | if( !fFieldExertedForce ) |
700 | isLastStep = fLinearNavigator->ExitedMotherVolume() |
701 | | fLinearNavigator->EnteredDaughterVolume() ; |
702 | else |
703 | isLastStep = fFieldPropagator->IsLastStepInVolume(); |
704 | } |
705 | else |
706 | { |
707 | |
708 | |
709 | fLinearNavigator->LocateGlobalPointWithinVolume( track.GetPosition() ) ; |
710 | |
711 | |
712 | |
713 | |
714 | |
715 | |
716 | fParticleChange.SetTouchableHandle( track.GetTouchableHandle() ) ; |
717 | retCurrentTouchable = track.GetTouchableHandle() ; |
718 | |
719 | isLastStep= false; |
720 | } |
721 | fLastStepInVolume= isLastStep; |
722 | |
723 | fParticleChange.ProposeFirstStepInVolume(fFirstStepInVolume); |
724 | fParticleChange.ProposeLastStepInVolume(isLastStep); |
725 | |
726 | const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ; |
727 | const G4Material* pNewMaterial = 0 ; |
728 | const G4VSensitiveDetector* pNewSensitiveDetector = 0 ; |
729 | |
730 | if( pNewVol != 0 ) |
731 | { |
732 | pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial(); |
733 | pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector(); |
734 | } |
735 | |
736 | |
737 | |
738 | |
739 | fParticleChange.SetMaterialInTouchable( (G4Material *) pNewMaterial ) ; |
740 | fParticleChange.SetSensitiveDetectorInTouchable( (G4VSensitiveDetector *) pNewSensitiveDetector ) ; |
741 | |
742 | const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0; |
743 | if( pNewVol != 0 ) |
744 | { |
745 | pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple(); |
746 | } |
747 | |
748 | if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial ) |
749 | { |
750 | |
751 | |
752 | pNewMaterialCutsCouple = |
753 | G4ProductionCutsTable::GetProductionCutsTable() |
754 | ->GetMaterialCutsCouple(pNewMaterial, |
755 | pNewMaterialCutsCouple->GetProductionCuts()); |
756 | } |
757 | fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple ); |
758 | |
759 | |
760 | |
761 | |
762 | |
763 | |
764 | |
765 | fParticleChange.SetTouchableHandle(retCurrentTouchable) ; |
766 | |
767 | return &fParticleChange ; |
768 | } |
769 | |
770 | |
771 | |
772 | |
773 | void |
774 | G4Transportation::StartTracking(G4Track* aTrack) |
775 | { |
776 | G4VProcess::StartTracking(aTrack); |
| 1 | Value assigned to field 'fFieldPropagator' | |
|
777 | fNewTrack= true; |
778 | fFirstStepInVolume= true; |
779 | fLastStepInVolume= false; |
780 | |
781 | |
782 | |
783 | |
784 | |
785 | |
786 | fPreviousSafety = 0.0 ; |
787 | fPreviousSftOrigin = G4ThreeVector(0.,0.,0.) ; |
788 | |
789 | |
790 | fNoLooperTrials= 0; |
791 | |
792 | |
793 | |
794 | |
795 | |
796 | |
797 | if( fFieldPropagator ) |
| 2 | | Assuming pointer value is null | |
|
| |
798 | { |
799 | fFieldPropagator->ClearPropagatorState(); |
800 | |
801 | |
802 | |
803 | |
804 | |
805 | } |
806 | |
807 | |
808 | |
809 | G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance(); |
810 | fieldMgrStore->ClearAllChordFindersState(); |
811 | |
812 | |
813 | |
814 | fCurrentTouchableHandle = aTrack->GetTouchableHandle(); |
815 | |
816 | |
817 | fFieldPropagator->PrepareNewTrack(); |
| 4 | | Called C++ object pointer is null |
|
818 | } |
819 | |
820 | #include "G4CoupledTransportation.hh" |
821 | G4bool G4Transportation::EnableUseMagneticMoment(G4bool useMoment) |
822 | { |
823 | G4bool lastValue= fUseMagneticMoment; |
824 | fUseMagneticMoment= useMoment; |
825 | G4CoupledTransportation::fUseMagneticMoment= useMoment; |
826 | return lastValue; |
827 | } |