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