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.14 2006/11/03 17:26:04 mverderi Exp $ >> 28 // GEANT4 tag $Name: geant4-08-02-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; << 151 if (fGhostWorld == 0) fStartTracking = false; // -- case ghost world below 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 152 188 // -------------------- << 153 // ------------------------------------------------------- 189 // Start/End tracking: << 154 // 190 // -------------------- << 155 // Parameterisation Trigger invokation sequence : 191 void G4FastSimulationManagerProcess::StartTrac << 156 // 192 { << 157 // ------------------------------------------------------- 193 fIsTrackingTime = true; << 158 fFastSimulationTrigger = false; 194 fIsFirstStep = true; << 159 195 << 160 //--------------------------------------------- 196 // -- fetch the navigator (and its index) an << 161 // Normal Dispatcher (for tracking geometry) : 197 G4TransportationManager* transportationManag << 162 //--------------------------------------------- 198 G4TransportationManager::GetTransportation << 163 if( (fFastSimulationManager = 199 fGhostNavigator = transportationManager->Get << 164 track.GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) ) 200 fIsGhostGeometry = (fGhostNavigator != trans << 165 { 201 if (fIsGhostGeometry) << 166 // Yes, so should us trigger a fast simulation model now ? 202 fGhostNavigatorIndex = transportationManag << 167 if(fFastSimulationTrigger = 203 else << 168 fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track)) 204 fGhostNavigatorIndex = -1; << 169 { 205 << 170 // Yes, lets take the control over the stepping ! 206 fPathFinder->PrepareNewTrack(track->GetPosit << 171 *condition = ExclusivelyForced; 207 } << 172 return 0.0; 208 << 173 } 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 } 174 } 245 } << 175 246 << 176 //----------------------------------------- 247 // -- no fast simulation occuring there: << 177 // * Parallel geometry Dispatcher if any. >> 178 // * If no trigger in the parallel geometry >> 179 // returns the Conditionally forced signal. >> 180 //----------------------------------------- >> 181 if(fGhostWorld) >> 182 { >> 183 // First, update the touchable history of ghost if necessary, ie when: >> 184 // - this is first Step of tracking >> 185 // - the last Step was limited by ghost geometry >> 186 // otherwise performs a single Locate >> 187 if (fUpdateGhostTouchable) >> 188 { >> 189 fUpdateGhostTouchable=false; >> 190 if (fStartTracking) >> 191 { >> 192 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 193 track.GetPosition(), >> 194 track.GetMomentumDirection(), >> 195 fGhostTouchable, >> 196 false); >> 197 fStartTracking = false; >> 198 } >> 199 else >> 200 { >> 201 fGhostNavigator.SetGeometricallyLimitedStep(); >> 202 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 203 track.GetPosition(), >> 204 track.GetMomentumDirection(), >> 205 fGhostTouchable); >> 206 } >> 207 fOutOfGhostWorld = (fGhostTouchable->GetVolume() == 0); >> 208 } >> 209 else if (previousStepSize > 0.0) >> 210 { >> 211 // G4ThreeVector direction= track.GetMomentumDirection(); >> 212 // fGhostNavigator.LocateGlobalPointAndSetup(track.GetPosition(), &direction, true); >> 213 // The above looks not enough in case of mag-field, not clear why ?!? >> 214 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 215 track.GetPosition(), >> 216 track.GetMomentumDirection(), >> 217 fGhostTouchable); >> 218 } >> 219 >> 220 >> 221 if (!fOutOfGhostWorld) >> 222 { >> 223 if( (fFastSimulationManager = >> 224 fGhostTouchable->GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) ) >> 225 { >> 226 // Yes, so should us trigger a fast simulation model now ? >> 227 if(fFastSimulationTrigger = >> 228 fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track,&fGhostNavigator)) >> 229 { >> 230 // Yes, lets take the control over the stepping ! >> 231 *condition = ExclusivelyForced; >> 232 return 0.0; >> 233 } >> 234 } >> 235 // No ghost trigger has occured (ie no manager or a manager but no trigger) >> 236 // Informs the stepping that PostStepDoIt may be called if the AlongGPIL >> 237 // will limit the Step. >> 238 // PostStepDoIt will switch on fUpdateGhostTouchable flag, >> 239 // and eventually correct position and mometum in case of >> 240 // mag-field. >> 241 *condition = Conditionally; >> 242 return DBL_MAX; >> 243 } >> 244 } >> 245 248 *condition = NotForced; 246 *condition = NotForced; 249 return DBL_MAX; 247 return DBL_MAX; 250 } 248 } 251 249 252 //------------------------------------ 250 //------------------------------------ >> 251 // 253 // PostStepDoIt() 252 // PostStepDoIt() >> 253 // 254 //------------------------------------ 254 //------------------------------------ 255 G4VParticleChange* G4FastSimulationManagerProc << 255 G4VParticleChange* G4FastSimulationManagerProcess::PostStepDoIt( 256 { << 256 const G4Track& track, 257 G4VParticleChange* finalState = fFastSimulat << 257 const G4Step& ) 258 << 258 { 259 // If the particle is still alive, suspend i << 259 if (fFastSimulationTrigger) 260 if (finalState->GetTrackStatus() != fStopAnd << 260 { 261 << 261 // Executes the ParameterisedSimulation code. 262 return finalState; << 262 // and gets the ParameterisedSimulation response. >> 263 G4VParticleChange* Response= >> 264 fFastSimulationManager->InvokePostStepDoIt(); >> 265 >> 266 // If the particle is still alive, suspend it >> 267 // to re-initialise the other process. >> 268 if (Response->GetTrackStatus() != fStopAndKill) >> 269 Response->ProposeTrackStatus(fSuspend); >> 270 // Returns the Response >> 271 return Response; >> 272 } >> 273 else >> 274 { >> 275 if (fOutOfGhostWorld) G4cout << " ????????????? Problem of logic in GHOST param !!! " << G4endl; >> 276 // No FastSimulationManager has asked for trigger. That means here: >> 277 // - the PostStep is "Conditionally" forced because >> 278 // - the Step has been limited by the ALong of G4FSMP because >> 279 // - the track has reached a ghost boundary >> 280 // => the touchable history must be updated. >> 281 // fUpdateGhostTouchable = true; : MOVED BELOW: COMPLICATIONS WITH MAG-FIELD !! >> 282 >> 283 if (fFieldExertsForce) >> 284 { >> 285 // ----------------------------------------------------------- >> 286 // in case of field, correct for small discrepancy on position >> 287 // and momentum computed by the Transportation. >> 288 // HOWEVER, this correction can be somewhat problematic when >> 289 // the end point, which is close here to a Ghost boundary by >> 290 // construction, is also close to a boundary of the tracking >> 291 // geometry. >> 292 // Thus we correct when the safety in the tracking geometry >> 293 // allows to move the point enough. Otherwise we issue >> 294 // a warning. >> 295 // ---------------------------------------------------------- >> 296 fTrackingNavigator.SetWorldVolume(G4TransportationManager::GetTransportationManager()-> >> 297 GetNavigatorForTracking()->GetWorldVolume()); >> 298 fTrackingNavigator.LocateGlobalPointAndUpdateTouchable( >> 299 track.GetPosition(), >> 300 track.GetMomentumDirection(), >> 301 &fTrackingHistory); >> 302 // G4VPhysicalVolume* trackingVolume = fTrackingHistory.GetVolume(); >> 303 >> 304 G4double trackingSafety(0.0); >> 305 // G4double trackingLinearDistance = >> 306 fTrackingNavigator.ComputeStep( >> 307 track.GetPosition(), >> 308 track.GetMomentumDirection(), >> 309 DBL_MAX, >> 310 trackingSafety); >> 311 >> 312 xParticleChange.Initialize(track); >> 313 G4ThreeVector deltaPos = fGhostFieldPropagator->EndPosition() - track.GetPosition(); >> 314 if (trackingSafety < deltaPos.mag()) >> 315 { >> 316 fUpdateGhostTouchable = true; // What should we do here ?!? >> 317 // false => lot a microscopic steps >> 318 // is true rasonnably safe ? >> 319 G4cout << GetProcessName() << " : WARNING: Can not correct for\ndifference between tracking and ghost mag-field computations." << G4endl; >> 320 } >> 321 else >> 322 { >> 323 // easy case where we have enough room to displace the point where we need: >> 324 fUpdateGhostTouchable = true; >> 325 xParticleChange.ProposePosition (fGhostFieldPropagator->EndPosition() ); >> 326 xParticleChange.ProposeMomentumDirection(fGhostFieldPropagator->EndMomentumDir()); >> 327 } >> 328 return &xParticleChange; >> 329 } >> 330 else >> 331 { >> 332 fUpdateGhostTouchable = true; >> 333 pParticleChange->Initialize(track); >> 334 return pParticleChange; >> 335 } >> 336 } 263 } 337 } 264 338 >> 339 265 G4double G4FastSimulationManagerProcess::Along 340 G4double G4FastSimulationManagerProcess::AlongStepGetPhysicalInteractionLength( 266 const G4Track& track, G4double previousStepS << 341 const G4Track& track, 267 G4double& proposedSafety, G4GPILSelection* s << 342 G4double previousStepSize, 268 { << 343 G4double currentMinimumStep, 269 *selection = NotCandidateForSelection; << 344 G4double& proposedSafety, >> 345 G4GPILSelection* selection >> 346 ) >> 347 { >> 348 // Informs the stepping that G4FastsimulationProcess wants >> 349 // to be able to limit the Step. >> 350 *selection = CandidateForSelection; >> 351 270 G4double returnedStep = DBL_MAX; 352 G4double returnedStep = DBL_MAX; 271 353 272 // ----------------------------------------- << 354 if (!fOutOfGhostWorld) 273 // -- Below code valid for ghost geometry, o << 355 { 274 // -- useless for fast simulation attached t << 356 if (previousStepSize > 0.) fGhostSafety -= previousStepSize; 275 // -- geometry. Warn user in case along used << 357 else fGhostSafety = -1.; 276 // -- mass geometry ? << 358 if (fGhostSafety < 0.) fGhostSafety = 0.0; 277 // ----------------------------------------- << 359 278 if (fIsGhostGeometry) { << 360 // ------------------------------------------ 279 static G4ThreadLocal G4FieldTrack* endTrac << 361 // Determination of the proposed STEP LENGTH: 280 if (endTrack_G4MT_TLS_ == nullptr) endTrac << 362 // ------------------------------------------ 281 G4FieldTrack& endTrack = *endTrack_G4MT_TL << 363 if (currentMinimumStep <= fGhostSafety) 282 << 364 { 283 static G4ThreadLocal ELimited* eLimited_G4 << 365 returnedStep = currentMinimumStep; 284 if (eLimited_G4MT_TLS_ == nullptr) eLimite << 366 } 285 ELimited& eLimited = *eLimited_G4MT_TLS_; << 367 else // (currentMinimumStep > fGhostSafety: GFSMP may limit the Step) 286 << 368 { 287 if (previousStepSize > 0.) fGhostSafety -= << 369 fFieldExertsForce = (fParticleCharge != 0.0) && 288 if (fGhostSafety < 0.) fGhostSafety = 0.0; << 370 (G4TransportationManager::GetTransportationManager()-> 289 << 371 GetFieldManager()->DoesFieldExist()); 290 // --------------------------------------- << 372 if ( !fFieldExertsForce ) 291 // Determination of the proposed step leng << 373 { 292 // --------------------------------------- << 374 fGhostStepLength = fGhostNavigator.ComputeStep( 293 if (currentMinimumStep <= fGhostSafety && << 375 track.GetPosition(), 294 // -- No chance to limit the step, as pr << 376 track.GetMomentumDirection(), 295 returnedStep = currentMinimumStep; << 377 currentMinimumStep, 296 proposedSafety = fGhostSafety - currentM << 378 fGhostSafety); 297 } << 379 298 else { << 380 } 299 // -- Proposed move exceeds safety, need << 381 else 300 G4FieldTrackUpdator::Update(&fFieldTrack << 382 { 301 returnedStep = fPathFinder->ComputeStep( << 383 fGhostFieldPropagator->SetChargeMomentumMass( 302 << 384 fParticleCharge, 303 << 385 track.GetDynamicParticle()-> 304 << 386 GetTotalMomentum(), 305 if (eLimited == kDoNot) << 387 track.GetDynamicParticle()-> 306 fGhostSafety = << 388 GetMass()); 307 fGhostNavigator->ComputeSafety(endTr << 389 308 proposedSafety = fGhostSafety; << 390 G4double restMass= track.GetDynamicParticle()->GetMass(); 309 if (eLimited == kUnique || eLimited == k << 391 G4ThreeVector spin = track.GetPolarization() ; 310 *selection = CandidateForSelection; << 392 G4FieldTrack aFieldTrack = 311 else if (eLimited == kSharedTransport) << 393 G4FieldTrack( track.GetPosition(), 312 returnedStep *= << 394 track.GetMomentumDirection(), 313 (1.0 + 1.0e-9); // -- Expand to dis << 395 0.0, >> 396 track.GetKineticEnergy(), >> 397 restMass, >> 398 track.GetVelocity(), >> 399 track.GetLocalTime(), // tof lab ? >> 400 track.GetProperTime(), // tof proper >> 401 &spin ) ; >> 402 >> 403 fGhostStepLength = fGhostFieldPropagator->ComputeStep( >> 404 aFieldTrack, >> 405 currentMinimumStep, >> 406 fGhostSafety); >> 407 } >> 408 fPreSafety = fGhostSafety; >> 409 returnedStep = fGhostStepLength; >> 410 } >> 411 >> 412 // ---------------------------------------------- >> 413 // Returns the fGhostSafety as the proposedSafety >> 414 // The SteppingManager will take care of keeping >> 415 // the smallest one. >> 416 // ---------------------------------------------- >> 417 proposedSafety = fGhostSafety; 314 } 418 } 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; 419 return returnedStep; 323 } 420 } 324 421 325 G4VParticleChange* G4FastSimulationManagerProc << 422 G4VParticleChange* G4FastSimulationManagerProcess::AlongStepDoIt( 326 << 423 const G4Track& track, 327 { << 424 const G4Step& ) 328 fDummyParticleChange.Initialize(track); << 425 { 329 return &fDummyParticleChange; << 426 // Dummy ParticleChange ie: does nothing >> 427 pParticleChange->Initialize(track); >> 428 return pParticleChange; 330 } 429 } 331 430 332 //-------------------------------------------- 431 //-------------------------------------------- >> 432 // 333 // At Rest parameterisation: 433 // At Rest parameterisation: >> 434 // 334 //-------------------------------------------- 435 //-------------------------------------------- >> 436 // 335 // AtRestGetPhysiscalInteractionLength: 437 // AtRestGetPhysiscalInteractionLength: >> 438 // 336 //-------------------------------------------- 439 //-------------------------------------------- 337 G4double << 440 G4double 338 G4FastSimulationManagerProcess::AtRestGetPhysi << 441 G4FastSimulationManagerProcess::AtRestGetPhysicalInteractionLength( 339 << 442 const G4Track& track, 340 { << 443 G4ForceCondition* condition) 341 const G4VPhysicalVolume* currentVolume(nullp << 444 { 342 if (fIsGhostGeometry) << 445 if ( (fFastSimulationManager = 343 currentVolume = fPathFinder->GetLocatedVol << 446 track.GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) 344 else << 447 != 0 ) 345 currentVolume = track.GetVolume(); << 448 if (fFastSimulationManager->AtRestGetFastSimulationManagerTrigger(track)) 346 fFastSimulationManager = currentVolume->GetL << 449 { 347 if (fFastSimulationManager != nullptr) { << 450 // "*condition = ExclusivelyForced;" Not yet available 348 // Ask for trigger: << 451 // for AtRest actions, so we use the trick below. However 349 fFastSimulationTrigger = << 452 // it is not garantee to work in the situation the track is 350 fFastSimulationManager->AtRestGetFastSim << 453 // alive after parameterisation. 351 if (fFastSimulationTrigger) { << 454 // NOTE: Problem: the present stepping doesn't care if the particle 352 // Dirty trick to take control over step << 455 // has been killed between two AtRestDoIt() !!! 353 *condition = NotForced; << 456 *condition = NotForced; 354 return -1.0; << 457 return -1.0; // TEMPORARY TRICK TO TAKE CONTROL !!!! >> 458 } >> 459 >> 460 //----------------------------------------- >> 461 // * Parallel geometry Dispatcher if any. >> 462 // * If no trigger in the parallel geometry >> 463 // * returns DBL_MAX and NotForced signal. >> 464 //----------------------------------------- >> 465 if(fGhostWorld) >> 466 { >> 467 // First, update the touchable history of ghost if necessary, ie when: >> 468 // - this is first Step of tracking >> 469 // - the last Step was limited by ghost geometry >> 470 // otherwise performs a single Locate >> 471 if (fUpdateGhostTouchable) >> 472 { >> 473 fUpdateGhostTouchable=false; >> 474 if (fStartTracking) >> 475 { >> 476 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 477 track.GetPosition(), >> 478 fGhostTouchable, >> 479 false); >> 480 fStartTracking = false; >> 481 } >> 482 else >> 483 { >> 484 fGhostNavigator.SetGeometricallyLimitedStep(); >> 485 fGhostNavigator.LocateGlobalPointAndUpdateTouchable( >> 486 track.GetPosition(), >> 487 fGhostTouchable); >> 488 >> 489 } >> 490 fOutOfGhostWorld = (fGhostTouchable->GetVolume() == 0); >> 491 } >> 492 >> 493 if (!fOutOfGhostWorld) >> 494 { >> 495 if( (fFastSimulationManager = >> 496 fGhostTouchable->GetVolume()->GetLogicalVolume()->GetFastSimulationManager()) ) >> 497 { >> 498 // Should it trigger a fast simulation model now ? >> 499 if(fFastSimulationTrigger = >> 500 fFastSimulationManager-> >> 501 AtRestGetFastSimulationManagerTrigger(track,&fGhostNavigator)) >> 502 { >> 503 // "*condition = ExclusivelyForced;" Not yet available >> 504 // for AtRest actions, so we use the trick below. However >> 505 // it is not garantee to work in the situation the track is >> 506 // alive after parameterisation. >> 507 // NOTE: Problem: the present stepping doesn't care if the particle >> 508 // has been killed between two AtRestDoIt() !!! >> 509 *condition = NotForced; >> 510 return -1.0; // TEMPORARY TRICK TO TAKE CONTROL !!!! >> 511 } >> 512 } >> 513 } 355 } 514 } 356 } << 357 515 358 // -- no fast simulation occuring there: << 516 // No, avoid to take control over the PostStepDoIt methods. 359 *condition = NotForced; 517 *condition = NotForced; 360 return DBL_MAX; 518 return DBL_MAX; 361 } 519 } 362 520 363 //-------------------------------------------- 521 //----------------------------------------------- >> 522 // 364 // AtRestDoIt: 523 // AtRestDoIt: >> 524 // 365 //-------------------------------------------- 525 //----------------------------------------------- 366 G4VParticleChange* G4FastSimulationManagerProc << 526 G4VParticleChange* G4FastSimulationManagerProcess::AtRestDoIt( >> 527 const G4Track&, const G4Step&) 367 { 528 { 368 return fFastSimulationManager->InvokeAtRestD 529 return fFastSimulationManager->InvokeAtRestDoIt(); >> 530 } >> 531 >> 532 void G4FastSimulationManagerProcess::StartTracking(G4Track*) >> 533 { >> 534 fStartTracking = true; >> 535 } >> 536 >> 537 void G4FastSimulationManagerProcess::Verbose() const >> 538 { >> 539 /* G4cout << " >>>>> Trigger Status : "; >> 540 switch(fFastSimulationManager->GetTriggerStatus()) >> 541 { >> 542 case NoModel: >> 543 G4cout << "NoModel" << G4endl; >> 544 break; >> 545 case OnBoundaryButLeaving: >> 546 G4cout << "OnBoundaryButLeaving" << G4endl; >> 547 break; >> 548 case OneModelTrigger: >> 549 G4cout << "OneModelTrigger" << G4endl; >> 550 break; >> 551 case NoModelTrigger: >> 552 G4cout << "NoModelTrigger" << G4endl; >> 553 break; >> 554 case Undefined: >> 555 G4cout << "Undefined" << G4endl; >> 556 break; >> 557 default: >> 558 G4cout << " Bizarre..." << G4endl; >> 559 break; >> 560 }*/ 369 } 561 } 370 562