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