Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // >> 27 // $Id: G4FastSimulationManagerProcess.cc,v 1.13 2006/06/29 21:09:28 gunter Exp $ >> 28 // GEANT4 tag $Name: geant4-08-01-patch-01 $ 27 // 29 // 28 // 30 // 29 //-------------------------------------------- 31 //--------------------------------------------------------------- 30 // 32 // 31 // G4FastSimulationProcess.cc 33 // G4FastSimulationProcess.cc 32 // 34 // 33 // Description: 35 // Description: 34 // The process that triggers the parameteri 36 // The process that triggers the parameterised simulations, 35 // if any. 37 // if any. 36 // 38 // 37 // History: 39 // History: 38 // August 97: First implementation. Verderi 40 // August 97: First implementation. Verderi && MoraDeFreitas. 39 // October 06: move to parallel geometry sc << 40 //-------------------------------------------- 41 //--------------------------------------------------------------- 41 42 >> 43 #include "G4ios.hh" 42 #include "G4FastSimulationManagerProcess.hh" 44 #include "G4FastSimulationManagerProcess.hh" 43 << 44 #include "G4FieldTrackUpdator.hh" << 45 #include "G4GlobalFastSimulationManager.hh" 45 #include "G4GlobalFastSimulationManager.hh" 46 #include "G4ParticleChange.hh" << 47 #include "G4PathFinder.hh" << 48 #include "G4TransportationManager.hh" 46 #include "G4TransportationManager.hh" 49 #include "G4ios.hh" << 47 #include "G4ParticleChange.hh" 50 << 51 G4FastSimulationManagerProcess::G4FastSimulati << 52 << 53 : G4VProcess(processName, theType), << 54 fWorldVolume(nullptr), << 55 fIsTrackingTime(false), << 56 fIsFirstStep(false), << 57 fGhostNavigator(nullptr), << 58 fGhostNavigatorIndex(-1), << 59 fIsGhostGeometry(false), << 60 fGhostSafety(-1.0), << 61 fFieldTrack('0'), << 62 fFastSimulationManager(nullptr), << 63 fFastSimulationTrigger(false) << 64 { << 65 // -- set Process Sub Type << 66 SetProcessSubType(static_cast<int>(FASTSIM_M << 67 << 68 fPathFinder = G4PathFinder::GetInstance(); << 69 fTransportationManager = G4TransportationMan << 70 << 71 SetWorldVolume(fTransportationManager->GetNa << 72 if (verboseLevel > 0) << 73 G4cout << "G4FastSimulationManagerProcess << 74 << "' is created, and will message << 75 << fWorldVolume->GetName() << "'." << 76 G4GlobalFastSimulationManager::GetGlobalFast << 77 } << 78 << 79 G4FastSimulationManagerProcess::G4FastSimulati << 80 << 81 << 82 : G4VProcess(processName, theType), << 83 fWorldVolume(nullptr), << 84 fIsTrackingTime(false), << 85 fIsFirstStep(false), << 86 fGhostNavigator(nullptr), << 87 fGhostNavigatorIndex(-1), << 88 fIsGhostGeometry(false), << 89 fGhostSafety(-1.0), << 90 fFieldTrack('0'), << 91 fFastSimulationManager(nullptr), << 92 fFastSimulationTrigger(false) << 93 { << 94 // -- set Process Sub Type << 95 SetProcessSubType(static_cast<int>(FASTSIM_M << 96 << 97 fPathFinder = G4PathFinder::GetInstance(); << 98 fTransportationManager = G4TransportationMan << 99 << 100 SetWorldVolume(worldVolumeName); << 101 if (verboseLevel > 0) << 102 G4cout << "G4FastSimulationManagerProcess << 103 << "' is created, and will message << 104 << fWorldVolume->GetName() << "'." << 105 G4GlobalFastSimulationManager::GetGlobalFast << 106 } << 107 << 108 G4FastSimulationManagerProcess::G4FastSimulati << 109 << 110 << 111 : G4VProcess(processName, theType), << 112 fWorldVolume(nullptr), << 113 fIsTrackingTime(false), << 114 fIsFirstStep(false), << 115 fGhostNavigator(nullptr), << 116 fGhostNavigatorIndex(-1), << 117 fIsGhostGeometry(false), << 118 fGhostSafety(-1.0), << 119 fFieldTrack('0'), << 120 fFastSimulationManager(nullptr), << 121 fFastSimulationTrigger(false) << 122 { << 123 // -- set Process Sub Type << 124 SetProcessSubType(static_cast<int>(FASTSIM_M << 125 << 126 fPathFinder = G4PathFinder::GetInstance(); << 127 fTransportationManager = G4TransportationMan << 128 48 129 SetWorldVolume(worldVolume); << 49 //---------------------------- 130 if (verboseLevel > 0) << 50 // Constructor with only name: 131 G4cout << "G4FastSimulationManagerProcess << 51 //---------------------------- 132 << "' is created, and will message << 52 G4FastSimulationManagerProcess:: 133 << fWorldVolume->GetName() << "'." << 53 G4FastSimulationManagerProcess(const G4String& processName, 134 G4GlobalFastSimulationManager::GetGlobalFast << 54 G4ProcessType theType) : >> 55 G4VProcess(processName,theType) >> 56 { >> 57 pParticleChange = &aDummyParticleChange; >> 58 >> 59 fGhostTouchable = new G4TouchableHistory(); >> 60 if (verboseLevel>0) { >> 61 G4cout << GetProcessName() << " is created " << G4endl; >> 62 } >> 63 fGhostFieldPropagator = new G4PropagatorInField(&fGhostNavigator, >> 64 G4TransportationManager:: >> 65 GetTransportationManager()-> >> 66 GetFieldManager()); 135 } 67 } 136 68 >> 69 // ----------- >> 70 // Destructor: >> 71 // ----------- 137 G4FastSimulationManagerProcess::~G4FastSimulat 72 G4FastSimulationManagerProcess::~G4FastSimulationManagerProcess() 138 { 73 { 139 G4GlobalFastSimulationManager::GetGlobalFast << 74 delete fGhostTouchable; >> 75 fGhostTouchable = 0; >> 76 delete fGhostFieldPropagator; >> 77 fGhostFieldPropagator = 0; 140 } 78 } 141 79 142 // ----------------------- << 80 143 // User access methods: << 81 //---------------------------------------------------------- 144 // ----------------------- << 82 // 145 void G4FastSimulationManagerProcess::SetWorldV << 83 // PostStepGetPhysicalInteractionLength() 146 { << 84 // 147 if (fIsTrackingTime) { << 85 // This method is used to trigger the parameterised 148 G4ExceptionDescription ed; << 86 // simulation. 149 ed << "G4FastSimulationManagerProcess `" < << 87 // 150 << "': changing of world volume at trac << 88 //---------------------------------------------------------- 151 G4Exception("G4FastSimulationManagerProces << 89 // 152 JustWarning, ed, "Call ignored << 90 // To be triggered the conditions that must be 153 } << 91 // fullfilled are : 154 else { << 92 // 155 G4VPhysicalVolume* newWorld = fTransportat << 93 // 1) a call to track->GetVolume()->GetLogicalVolume()-> 156 if (newWorld == nullptr) { << 94 // GetFastSimulationManager() returns a G4FastSimulationManager 157 G4ExceptionDescription tellWhatIsWrong; << 95 // not NULL pointer (kept in fFastSimulationManager); 158 tellWhatIsWrong << "Volume newWorldName << 96 // 159 << "' is not a parallel << 97 // AND 160 G4Exception("G4FastSimulationManagerProc << 98 // 161 FatalException, tellWhatIsWr << 99 // 2)a call to this fFastSimulationManager->GetTrigger() method 162 } << 100 /// returns a G4bool True. 163 if (verboseLevel > 0) { << 101 // 164 if (fWorldVolume != nullptr) << 102 // 165 G4cout << "G4FastSimulationManagerProc << 103 // If the fFastSimulationManager* is triggered then: 166 << "': changing world volume fr << 104 // 167 << newWorld << "'." << G4endl; << 105 // * condition = ExclusivelyForced >> 106 // * returns 0.0 >> 107 // >> 108 // else: >> 109 // * condition = NotForced >> 110 // * returns DBL_MAX >> 111 // >> 112 //----------------------------------------------------------- >> 113 G4double >> 114 G4FastSimulationManagerProcess::PostStepGetPhysicalInteractionLength( >> 115 const G4Track& track, >> 116 G4double previousStepSize, >> 117 G4ForceCondition* condition) >> 118 { >> 119 // ------------------------------ >> 120 // Prelude for initial Step only: >> 121 // ------------------------------ >> 122 // ---------------------------------------------------------- >> 123 // -- If starting a track, check if there is a parallel World >> 124 // -- for the new particle being tracked. >> 125 // -- (may be Done more than once in very special cases, >> 126 // -- since the fStarTracking is switched off lower.) >> 127 // ---------------------------------------------------------- >> 128 if(fStartTracking) >> 129 { >> 130 G4VFlavoredParallelWorld* flavoredWorld = >> 131 G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()-> >> 132 GetFlavoredWorldForThis(track.GetDynamicParticle()->GetDefinition()); >> 133 >> 134 fGhostWorld = 0; >> 135 if (flavoredWorld) >> 136 fGhostWorld = flavoredWorld->GetThePhysicalVolumeWorld(); >> 137 >> 138 if (fGhostWorld) >> 139 { >> 140 fGhostNavigator.SetWorldVolume(fGhostWorld); >> 141 fUpdateGhostTouchable = true; >> 142 fGhostSafety = -1.; >> 143 // Navigation in Field: >> 144 fParticleCharge = track.GetDynamicParticle()->GetDefinition()->GetPDGCharge(); >> 145 } 168 else 146 else 169 G4cout << "G4FastSimulationManagerProc << 147 { 170 << "': setting world volume fro << 148 fOutOfGhostWorld = true; >> 149 } 171 } 150 } 172 fWorldVolume = newWorld; << 173 } << 174 } << 175 << 176 void G4FastSimulationManagerProcess::SetWorldV << 177 { << 178 if (newWorld != nullptr) << 179 SetWorldVolume(newWorld->GetName()); << 180 else { << 181 G4ExceptionDescription tellWhatIsWrong; << 182 tellWhatIsWrong << "Null pointer passed fo << 183 G4Exception("G4FastSimulationManagerProces << 184 "FastSim004", FatalException, << 185 } << 186 } << 187 151 188 // -------------------- << 152 // ------------------------------------------------------- 189 // Start/End tracking: << 153 // 190 // -------------------- << 154 // Parameterisation Trigger invokation sequence : 191 void G4FastSimulationManagerProcess::StartTrac << 155 // 192 { << 156 // ------------------------------------------------------- 193 fIsTrackingTime = true; << 157 fFastSimulationTrigger = false; 194 fIsFirstStep = true; << 158 195 << 159 //--------------------------------------------- 196 // -- fetch the navigator (and its index) an << 160 // Normal Dispatcher (for tracking geometry) : 197 G4TransportationManager* transportationManag << 161 //--------------------------------------------- 198 G4TransportationManager::GetTransportation << 162 if( (fFastSimulationManager = 199 fGhostNavigator = transportationManager->Get << 163 track.GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) ) 200 fIsGhostGeometry = (fGhostNavigator != trans << 164 { 201 if (fIsGhostGeometry) << 165 // Yes, so should us trigger a fast simulation model now ? 202 fGhostNavigatorIndex = transportationManag << 166 if(fFastSimulationTrigger = 203 else << 167 fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track)) 204 fGhostNavigatorIndex = -1; << 168 { 205 << 169 // Yes, lets take the control over the stepping ! 206 fPathFinder->PrepareNewTrack(track->GetPosit << 170 *condition = ExclusivelyForced; 207 } << 171 return 0.0; 208 << 172 } 209 void G4FastSimulationManagerProcess::EndTracki << 210 { << 211 fIsTrackingTime = false; << 212 if (fIsGhostGeometry) fTransportationManager << 213 } << 214 << 215 // ------------------------------------------ << 216 // PostStepGetPhysicalInteractionLength(): << 217 // ------------------------------------------ << 218 G4double << 219 G4FastSimulationManagerProcess::PostStepGetPhy << 220 << 221 { << 222 // -- Get current volume, and check for pres << 223 // -- For the case of the navigator for trac << 224 // -- we use the track volume. This allows t << 225 // -- cases where the PathFinder is used (G4 << 226 // -- (G4Transportation). << 227 const G4VPhysicalVolume* currentVolume(nullp << 228 if (fIsGhostGeometry) << 229 currentVolume = fPathFinder->GetLocatedVol << 230 else << 231 currentVolume = track.GetVolume(); << 232 << 233 if (currentVolume != nullptr) { << 234 fFastSimulationManager = currentVolume->Ge << 235 if (fFastSimulationManager != nullptr) { << 236 // Ask for trigger: << 237 fFastSimulationTrigger = << 238 fFastSimulationManager->PostStepGetFas << 239 if (fFastSimulationTrigger) { << 240 // Take control over stepping: << 241 *condition = ExclusivelyForced; << 242 return 0.0; << 243 } << 244 } 173 } 245 } << 174 246 << 175 //----------------------------------------- 247 // -- no fast simulation occuring there: << 176 // * Parallel geometry Dispatcher if any. >> 177 // * If no trigger in the parallel geometry >> 178 // returns the Conditionally forced signal. >> 179 //----------------------------------------- >> 180 if(fGhostWorld) >> 181 { >> 182 // First, update the touchable history of ghost if necessary, ie when: >> 183 // - this is first Step of tracking >> 184 // - the last Step was limited by ghost geometry >> 185 // otherwise performs a single Locate >> 186 if (fUpdateGhostTouchable) >> 187 { >> 188 fUpdateGhostTouchable=false; >> 189 if (fStartTracking) >> 190 { >> 191 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 192 track.GetPosition(), >> 193 track.GetMomentumDirection(), >> 194 fGhostTouchable, >> 195 false); >> 196 fStartTracking = false; >> 197 } >> 198 else >> 199 { >> 200 fGhostNavigator.SetGeometricallyLimitedStep(); >> 201 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 202 track.GetPosition(), >> 203 track.GetMomentumDirection(), >> 204 fGhostTouchable); >> 205 } >> 206 fOutOfGhostWorld = (fGhostTouchable->GetVolume() == 0); >> 207 } >> 208 else if (previousStepSize > 0.0) >> 209 { >> 210 // G4ThreeVector direction= track.GetMomentumDirection(); >> 211 // fGhostNavigator.LocateGlobalPointAndSetup(track.GetPosition(), &direction, true); >> 212 // The above looks not enough in case of mag-field, not clear why ?!? >> 213 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 214 track.GetPosition(), >> 215 track.GetMomentumDirection(), >> 216 fGhostTouchable); >> 217 } >> 218 >> 219 >> 220 if (!fOutOfGhostWorld) >> 221 { >> 222 if( (fFastSimulationManager = >> 223 fGhostTouchable->GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) ) >> 224 { >> 225 // Yes, so should us trigger a fast simulation model now ? >> 226 if(fFastSimulationTrigger = >> 227 fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track,&fGhostNavigator)) >> 228 { >> 229 // Yes, lets take the control over the stepping ! >> 230 *condition = ExclusivelyForced; >> 231 return 0.0; >> 232 } >> 233 } >> 234 // No ghost trigger has occured (ie no manager or a manager but no trigger) >> 235 // Informs the stepping that PostStepDoIt may be called if the AlongGPIL >> 236 // will limit the Step. >> 237 // PostStepDoIt will switch on fUpdateGhostTouchable flag, >> 238 // and eventually correct position and mometum in case of >> 239 // mag-field. >> 240 *condition = Conditionally; >> 241 return DBL_MAX; >> 242 } >> 243 } >> 244 248 *condition = NotForced; 245 *condition = NotForced; 249 return DBL_MAX; 246 return DBL_MAX; 250 } 247 } 251 248 252 //------------------------------------ 249 //------------------------------------ >> 250 // 253 // PostStepDoIt() 251 // PostStepDoIt() >> 252 // 254 //------------------------------------ 253 //------------------------------------ 255 G4VParticleChange* G4FastSimulationManagerProc << 254 G4VParticleChange* G4FastSimulationManagerProcess::PostStepDoIt( 256 { << 255 const G4Track& track, 257 G4VParticleChange* finalState = fFastSimulat << 256 const G4Step& ) 258 << 257 { 259 // If the particle is still alive, suspend i << 258 if (fFastSimulationTrigger) 260 if (finalState->GetTrackStatus() != fStopAnd << 259 { 261 << 260 // Executes the ParameterisedSimulation code. 262 return finalState; << 261 // and gets the ParameterisedSimulation response. >> 262 G4VParticleChange* Response= >> 263 fFastSimulationManager->InvokePostStepDoIt(); >> 264 >> 265 // If the particle is still alive, suspend it >> 266 // to re-initialise the other process. >> 267 if (Response->GetTrackStatus() != fStopAndKill) >> 268 Response->ProposeTrackStatus(fSuspend); >> 269 // Returns the Response >> 270 return Response; >> 271 } >> 272 else >> 273 { >> 274 if (fOutOfGhostWorld) G4cout << " ????????????? Problem of logic in GHOST param !!! " << G4endl; >> 275 // No FastSimulationManager has asked for trigger. That means here: >> 276 // - the PostStep is "Conditionally" forced because >> 277 // - the Step has been limited by the ALong of G4FSMP because >> 278 // - the track has reached a ghost boundary >> 279 // => the touchable history must be updated. >> 280 // fUpdateGhostTouchable = true; : MOVED BELOW: COMPLICATIONS WITH MAG-FIELD !! >> 281 >> 282 if (fFieldExertsForce) >> 283 { >> 284 // ----------------------------------------------------------- >> 285 // in case of field, correct for small discrepancy on position >> 286 // and momentum computed by the Transportation. >> 287 // HOWEVER, this correction can be somewhat problematic when >> 288 // the end point, which is close here to a Ghost boundary by >> 289 // construction, is also close to a boundary of the tracking >> 290 // geometry. >> 291 // Thus we correct when the safety in the tracking geometry >> 292 // allows to move the point enough. Otherwise we issue >> 293 // a warning. >> 294 // ---------------------------------------------------------- >> 295 fTrackingNavigator.SetWorldVolume(G4TransportationManager::GetTransportationManager()-> >> 296 GetNavigatorForTracking()->GetWorldVolume()); >> 297 fTrackingNavigator.LocateGlobalPointAndUpdateTouchable( >> 298 track.GetPosition(), >> 299 track.GetMomentumDirection(), >> 300 &fTrackingHistory); >> 301 // G4VPhysicalVolume* trackingVolume = fTrackingHistory.GetVolume(); >> 302 >> 303 G4double trackingSafety(0.0); >> 304 // G4double trackingLinearDistance = >> 305 fTrackingNavigator.ComputeStep( >> 306 track.GetPosition(), >> 307 track.GetMomentumDirection(), >> 308 DBL_MAX, >> 309 trackingSafety); >> 310 >> 311 xParticleChange.Initialize(track); >> 312 G4ThreeVector deltaPos = fGhostFieldPropagator->EndPosition() - track.GetPosition(); >> 313 if (trackingSafety < deltaPos.mag()) >> 314 { >> 315 fUpdateGhostTouchable = true; // What should we do here ?!? >> 316 // false => lot a microscopic steps >> 317 // is true rasonnably safe ? >> 318 G4cout << GetProcessName() << " : WARNING: Can not correct for\ndifference between tracking and ghost mag-field computations." << G4endl; >> 319 } >> 320 else >> 321 { >> 322 // easy case where we have enough room to displace the point where we need: >> 323 fUpdateGhostTouchable = true; >> 324 xParticleChange.ProposePosition (fGhostFieldPropagator->EndPosition() ); >> 325 xParticleChange.ProposeMomentumDirection(fGhostFieldPropagator->EndMomentumDir()); >> 326 } >> 327 return &xParticleChange; >> 328 } >> 329 else >> 330 { >> 331 fUpdateGhostTouchable = true; >> 332 pParticleChange->Initialize(track); >> 333 return pParticleChange; >> 334 } >> 335 } 263 } 336 } 264 337 >> 338 265 G4double G4FastSimulationManagerProcess::Along 339 G4double G4FastSimulationManagerProcess::AlongStepGetPhysicalInteractionLength( 266 const G4Track& track, G4double previousStepS << 340 const G4Track& track, 267 G4double& proposedSafety, G4GPILSelection* s << 341 G4double previousStepSize, 268 { << 342 G4double currentMinimumStep, 269 *selection = NotCandidateForSelection; << 343 G4double& proposedSafety, >> 344 G4GPILSelection* selection >> 345 ) >> 346 { >> 347 // Informs the stepping that G4FastsimulationProcess wants >> 348 // to be able to limit the Step. >> 349 *selection = CandidateForSelection; >> 350 270 G4double returnedStep = DBL_MAX; 351 G4double returnedStep = DBL_MAX; 271 352 272 // ----------------------------------------- << 353 if (!fOutOfGhostWorld) 273 // -- Below code valid for ghost geometry, o << 354 { 274 // -- useless for fast simulation attached t << 355 if (previousStepSize > 0.) fGhostSafety -= previousStepSize; 275 // -- geometry. Warn user in case along used << 356 else fGhostSafety = -1.; 276 // -- mass geometry ? << 357 if (fGhostSafety < 0.) fGhostSafety = 0.0; 277 // ----------------------------------------- << 358 278 if (fIsGhostGeometry) { << 359 // ------------------------------------------ 279 static G4ThreadLocal G4FieldTrack* endTrac << 360 // Determination of the proposed STEP LENGTH: 280 if (endTrack_G4MT_TLS_ == nullptr) endTrac << 361 // ------------------------------------------ 281 G4FieldTrack& endTrack = *endTrack_G4MT_TL << 362 if (currentMinimumStep <= fGhostSafety) 282 << 363 { 283 static G4ThreadLocal ELimited* eLimited_G4 << 364 returnedStep = currentMinimumStep; 284 if (eLimited_G4MT_TLS_ == nullptr) eLimite << 365 } 285 ELimited& eLimited = *eLimited_G4MT_TLS_; << 366 else // (currentMinimumStep > fGhostSafety: GFSMP may limit the Step) 286 << 367 { 287 if (previousStepSize > 0.) fGhostSafety -= << 368 fFieldExertsForce = (fParticleCharge != 0.0) && 288 if (fGhostSafety < 0.) fGhostSafety = 0.0; << 369 (G4TransportationManager::GetTransportationManager()-> 289 << 370 GetFieldManager()->DoesFieldExist()); 290 // --------------------------------------- << 371 if ( !fFieldExertsForce ) 291 // Determination of the proposed step leng << 372 { 292 // --------------------------------------- << 373 fGhostStepLength = fGhostNavigator.ComputeStep( 293 if (currentMinimumStep <= fGhostSafety && << 374 track.GetPosition(), 294 // -- No chance to limit the step, as pr << 375 track.GetMomentumDirection(), 295 returnedStep = currentMinimumStep; << 376 currentMinimumStep, 296 proposedSafety = fGhostSafety - currentM << 377 fGhostSafety); 297 } << 378 298 else { << 379 } 299 // -- Proposed move exceeds safety, need << 380 else 300 G4FieldTrackUpdator::Update(&fFieldTrack << 381 { 301 returnedStep = fPathFinder->ComputeStep( << 382 fGhostFieldPropagator->SetChargeMomentumMass( 302 << 383 fParticleCharge, 303 << 384 track.GetDynamicParticle()-> 304 << 385 GetTotalMomentum(), 305 if (eLimited == kDoNot) << 386 track.GetDynamicParticle()-> 306 fGhostSafety = << 387 GetMass()); 307 fGhostNavigator->ComputeSafety(endTr << 388 308 proposedSafety = fGhostSafety; << 389 G4double restMass= track.GetDynamicParticle()->GetMass(); 309 if (eLimited == kUnique || eLimited == k << 390 G4ThreeVector spin = track.GetPolarization() ; 310 *selection = CandidateForSelection; << 391 G4FieldTrack aFieldTrack = 311 else if (eLimited == kSharedTransport) << 392 G4FieldTrack( track.GetPosition(), 312 returnedStep *= << 393 track.GetMomentumDirection(), 313 (1.0 + 1.0e-9); // -- Expand to dis << 394 0.0, >> 395 track.GetKineticEnergy(), >> 396 restMass, >> 397 track.GetVelocity(), >> 398 track.GetLocalTime(), // tof lab ? >> 399 track.GetProperTime(), // tof proper >> 400 &spin ) ; >> 401 >> 402 fGhostStepLength = fGhostFieldPropagator->ComputeStep( >> 403 aFieldTrack, >> 404 currentMinimumStep, >> 405 fGhostSafety); >> 406 } >> 407 fPreSafety = fGhostSafety; >> 408 returnedStep = fGhostStepLength; >> 409 } >> 410 >> 411 // ---------------------------------------------- >> 412 // Returns the fGhostSafety as the proposedSafety >> 413 // The SteppingManager will take care of keeping >> 414 // the smallest one. >> 415 // ---------------------------------------------- >> 416 proposedSafety = fGhostSafety; 314 } 417 } 315 } << 316 << 317 // ----------------------------------------- << 318 // Returns the fGhostSafety as the proposedS << 319 // The SteppingManager will take care of kee << 320 // the smallest one. << 321 // ----------------------------------------- << 322 return returnedStep; 418 return returnedStep; 323 } 419 } 324 420 325 G4VParticleChange* G4FastSimulationManagerProc << 421 G4VParticleChange* G4FastSimulationManagerProcess::AlongStepDoIt( 326 << 422 const G4Track& track, 327 { << 423 const G4Step& ) 328 fDummyParticleChange.Initialize(track); << 424 { 329 return &fDummyParticleChange; << 425 // Dummy ParticleChange ie: does nothing >> 426 pParticleChange->Initialize(track); >> 427 return pParticleChange; 330 } 428 } 331 429 332 //-------------------------------------------- 430 //-------------------------------------------- >> 431 // 333 // At Rest parameterisation: 432 // At Rest parameterisation: >> 433 // 334 //-------------------------------------------- 434 //-------------------------------------------- >> 435 // 335 // AtRestGetPhysiscalInteractionLength: 436 // AtRestGetPhysiscalInteractionLength: >> 437 // 336 //-------------------------------------------- 438 //-------------------------------------------- 337 G4double << 439 G4double 338 G4FastSimulationManagerProcess::AtRestGetPhysi << 440 G4FastSimulationManagerProcess::AtRestGetPhysicalInteractionLength( 339 << 441 const G4Track& track, 340 { << 442 G4ForceCondition* condition) 341 const G4VPhysicalVolume* currentVolume(nullp << 443 { 342 if (fIsGhostGeometry) << 444 if ( (fFastSimulationManager = 343 currentVolume = fPathFinder->GetLocatedVol << 445 track.GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) 344 else << 446 != 0 ) 345 currentVolume = track.GetVolume(); << 447 if (fFastSimulationManager->AtRestGetFastSimulationManagerTrigger(track)) 346 fFastSimulationManager = currentVolume->GetL << 448 { 347 if (fFastSimulationManager != nullptr) { << 449 // "*condition = ExclusivelyForced;" Not yet available 348 // Ask for trigger: << 450 // for AtRest actions, so we use the trick below. However 349 fFastSimulationTrigger = << 451 // it is not garantee to work in the situation the track is 350 fFastSimulationManager->AtRestGetFastSim << 452 // alive after parameterisation. 351 if (fFastSimulationTrigger) { << 453 // NOTE: Problem: the present stepping doesn't care if the particle 352 // Dirty trick to take control over step << 454 // has been killed between two AtRestDoIt() !!! 353 *condition = NotForced; << 455 *condition = NotForced; 354 return -1.0; << 456 return -1.0; // TEMPORARY TRICK TO TAKE CONTROL !!!! >> 457 } >> 458 >> 459 //----------------------------------------- >> 460 // * Parallel geometry Dispatcher if any. >> 461 // * If no trigger in the parallel geometry >> 462 // * returns DBL_MAX and NotForced signal. >> 463 //----------------------------------------- >> 464 if(fGhostWorld) >> 465 { >> 466 // First, update the touchable history of ghost if necessary, ie when: >> 467 // - this is first Step of tracking >> 468 // - the last Step was limited by ghost geometry >> 469 // otherwise performs a single Locate >> 470 if (fUpdateGhostTouchable) >> 471 { >> 472 fUpdateGhostTouchable=false; >> 473 if (fStartTracking) >> 474 { >> 475 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 476 track.GetPosition(), >> 477 fGhostTouchable, >> 478 false); >> 479 fStartTracking = false; >> 480 } >> 481 else >> 482 { >> 483 fGhostNavigator.SetGeometricallyLimitedStep(); >> 484 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 485 track.GetPosition(), >> 486 fGhostTouchable); >> 487 >> 488 } >> 489 fOutOfGhostWorld = (fGhostTouchable->GetVolume() == 0); >> 490 } >> 491 >> 492 if (!fOutOfGhostWorld) >> 493 { >> 494 if( (fFastSimulationManager = >> 495 fGhostTouchable->GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) ) >> 496 { >> 497 // Should it trigger a fast simulation model now ? >> 498 if(fFastSimulationTrigger = >> 499 fFastSimulationManager-> >> 500 AtRestGetFastSimulationManagerTrigger(track,&fGhostNavigator)) >> 501 { >> 502 // "*condition = ExclusivelyForced;" Not yet available >> 503 // for AtRest actions, so we use the trick below. However >> 504 // it is not garantee to work in the situation the track is >> 505 // alive after parameterisation. >> 506 // NOTE: Problem: the present stepping doesn't care if the particle >> 507 // has been killed between two AtRestDoIt() !!! >> 508 *condition = NotForced; >> 509 return -1.0; // TEMPORARY TRICK TO TAKE CONTROL !!!! >> 510 } >> 511 } >> 512 } 355 } 513 } 356 } << 357 514 358 // -- no fast simulation occuring there: << 515 // No, avoid to take control over the PostStepDoIt methods. 359 *condition = NotForced; 516 *condition = NotForced; 360 return DBL_MAX; 517 return DBL_MAX; 361 } 518 } 362 519 363 //-------------------------------------------- 520 //----------------------------------------------- >> 521 // 364 // AtRestDoIt: 522 // AtRestDoIt: >> 523 // 365 //-------------------------------------------- 524 //----------------------------------------------- 366 G4VParticleChange* G4FastSimulationManagerProc << 525 G4VParticleChange* G4FastSimulationManagerProcess::AtRestDoIt( >> 526 const G4Track&, const G4Step&) 367 { 527 { 368 return fFastSimulationManager->InvokeAtRestD 528 return fFastSimulationManager->InvokeAtRestDoIt(); >> 529 } >> 530 >> 531 void G4FastSimulationManagerProcess::StartTracking(G4Track*) >> 532 { >> 533 fStartTracking = true; >> 534 } >> 535 >> 536 void G4FastSimulationManagerProcess::Verbose() const >> 537 { >> 538 /* G4cout << " >>>>> Trigger Status : "; >> 539 switch(fFastSimulationManager->GetTriggerStatus()) >> 540 { >> 541 case NoModel: >> 542 G4cout << "NoModel" << G4endl; >> 543 break; >> 544 case OnBoundaryButLeaving: >> 545 G4cout << "OnBoundaryButLeaving" << G4endl; >> 546 break; >> 547 case OneModelTrigger: >> 548 G4cout << "OneModelTrigger" << G4endl; >> 549 break; >> 550 case NoModelTrigger: >> 551 G4cout << "NoModelTrigger" << G4endl; >> 552 break; >> 553 case Undefined: >> 554 G4cout << "Undefined" << G4endl; >> 555 break; >> 556 default: >> 557 G4cout << " Bizarre..." << G4endl; >> 558 break; >> 559 }*/ 369 } 560 } 370 561