00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "G4ios.hh"
00044 #include "G4FastSimulationManagerProcess.hh"
00045 #include "G4GlobalFastSimulationManager.hh"
00046 #include "G4TransportationManager.hh"
00047 #include "G4PathFinder.hh"
00048 #include "G4ParticleChange.hh"
00049 #include "G4FieldTrackUpdator.hh"
00050
00051 #define PARANOIA
00052
00053 G4FastSimulationManagerProcess::
00054 G4FastSimulationManagerProcess(const G4String& processName,
00055 G4ProcessType theType) :
00056 G4VProcess(processName,theType),
00057 fWorldVolume(0),
00058 fIsTrackingTime(false),
00059 fGhostNavigator(0),
00060 fGhostNavigatorIndex(-1),
00061 fIsGhostGeometry(false),
00062 fGhostSafety(-1.0),
00063 fFieldTrack('0'),
00064 fFastSimulationManager(0),
00065 fFastSimulationTrigger(false)
00066 {
00067
00068 SetProcessSubType(static_cast<int>(FASTSIM_ManagerProcess));
00069
00070
00071 fPathFinder = G4PathFinder::GetInstance();
00072 fTransportationManager = G4TransportationManager::GetTransportationManager();
00073
00074 SetWorldVolume(fTransportationManager->GetNavigatorForTracking()->GetWorldVolume()->GetName());
00075 if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
00076 << "' is created, and will message geometry with world volume `"
00077 << fWorldVolume->GetName() << "'." << G4endl;
00078 G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->AddFSMP(this);
00079 }
00080
00081
00082 G4FastSimulationManagerProcess::
00083 G4FastSimulationManagerProcess(const G4String& processName,
00084 const G4String& worldVolumeName,
00085 G4ProcessType theType) :
00086 G4VProcess(processName,theType),
00087 fWorldVolume(0),
00088 fIsTrackingTime(false),
00089 fGhostNavigator(0),
00090 fGhostNavigatorIndex(-1),
00091 fIsGhostGeometry(false),
00092 fGhostSafety(-1.0),
00093 fFieldTrack('0'),
00094 fFastSimulationManager(0),
00095 fFastSimulationTrigger(false)
00096 {
00097
00098 SetProcessSubType(static_cast<int>(FASTSIM_ManagerProcess));
00099
00100
00101 fPathFinder = G4PathFinder::GetInstance();
00102 fTransportationManager = G4TransportationManager::GetTransportationManager();
00103
00104 SetWorldVolume(worldVolumeName);
00105 if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
00106 << "' is created, and will message geometry with world volume `"
00107 << fWorldVolume->GetName() << "'." << G4endl;
00108 G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->AddFSMP(this);
00109 }
00110
00111
00112 G4FastSimulationManagerProcess::
00113 G4FastSimulationManagerProcess(const G4String& processName,
00114 G4VPhysicalVolume* worldVolume,
00115 G4ProcessType theType) :
00116 G4VProcess(processName,theType),
00117 fWorldVolume(0),
00118 fIsTrackingTime(false),
00119 fGhostNavigator(0),
00120 fGhostNavigatorIndex(-1),
00121 fIsGhostGeometry(false),
00122 fGhostSafety(-1.0),
00123 fFieldTrack('0'),
00124 fFastSimulationManager(0),
00125 fFastSimulationTrigger(false)
00126 {
00127
00128 SetProcessSubType(static_cast<int>(FASTSIM_ManagerProcess));
00129
00130
00131 fPathFinder = G4PathFinder::GetInstance();
00132 fTransportationManager = G4TransportationManager::GetTransportationManager();
00133
00134 SetWorldVolume(worldVolume);
00135 if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
00136 << "' is created, and will message geometry with world volume `"
00137 << fWorldVolume->GetName() << "'." << G4endl;
00138 G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->AddFSMP(this);
00139 }
00140
00141
00142 G4FastSimulationManagerProcess::~G4FastSimulationManagerProcess()
00143 {
00144 G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->RemoveFSMP(this);
00145 }
00146
00147
00148
00149
00150
00151 void G4FastSimulationManagerProcess::SetWorldVolume(G4String newWorldName)
00152 {
00153 if (fIsTrackingTime)
00154 {
00155 G4ExceptionDescription ed;
00156 ed << "G4FastSimulationManagerProcess `" << GetProcessName()
00157 << "': changing of world volume at tracking time is not allowed." << G4endl;
00158 G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4String)",
00159 "FastSim002",
00160 JustWarning, ed,
00161 "Call ignored.");
00162 }
00163 else
00164 {
00165 G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting(newWorldName);
00166 if (newWorld == 0)
00167 {
00168 G4ExceptionDescription tellWhatIsWrong;
00169 tellWhatIsWrong << "Volume newWorldName = `" << newWorldName
00170 << "' is not a parallel world nor the mass world volume."
00171 << G4endl;
00172 G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4String)",
00173 "FastSim003",
00174 FatalException,
00175 tellWhatIsWrong);
00176 }
00177 if (verboseLevel>0)
00178 {
00179 if (fWorldVolume) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
00180 << "': changing world volume from '" << fWorldVolume->GetName()
00181 << "' to `" << newWorld << "'." << G4endl;
00182 else G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
00183 << "': setting world volume from to `"<< newWorld->GetName() << "'." << G4endl;
00184 }
00185 fWorldVolume = newWorld;
00186 }
00187 }
00188
00189
00190 void G4FastSimulationManagerProcess::SetWorldVolume(G4VPhysicalVolume* newWorld)
00191 {
00192 if (newWorld) SetWorldVolume(newWorld->GetName());
00193 else
00194 {
00195 G4ExceptionDescription tellWhatIsWrong;
00196 tellWhatIsWrong << "Null pointer passed for world volume." << G4endl;
00197 G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4VPhysicalVolume* newWorld)",
00198 "FastSim004",
00199 FatalException,
00200 tellWhatIsWrong);
00201 }
00202 }
00203
00204
00205
00206
00207
00208 void
00209 G4FastSimulationManagerProcess::
00210 StartTracking(G4Track* track)
00211 {
00212 fIsTrackingTime = true;
00213 fIsFirstStep = true;
00214
00215
00216 G4TransportationManager* transportationManager = G4TransportationManager::GetTransportationManager();
00217 fGhostNavigator = transportationManager->GetNavigator(fWorldVolume);
00218 fIsGhostGeometry = (fGhostNavigator != transportationManager->GetNavigatorForTracking());
00219 if (fIsGhostGeometry) fGhostNavigatorIndex = transportationManager->ActivateNavigator(fGhostNavigator);
00220 else fGhostNavigatorIndex = -1;
00221
00222 fPathFinder->PrepareNewTrack(track->GetPosition(), track->GetMomentumDirection());
00223 }
00224
00225
00226 void
00227 G4FastSimulationManagerProcess::
00228 EndTracking()
00229 {
00230 fIsTrackingTime = false;
00231 if ( fIsGhostGeometry ) fTransportationManager->DeActivateNavigator(fGhostNavigator);
00232 }
00233
00234
00235
00236
00237
00238 G4double
00239 G4FastSimulationManagerProcess::
00240 PostStepGetPhysicalInteractionLength(const G4Track& track,
00241 G4double,
00242 G4ForceCondition* condition)
00243 {
00244
00245
00246
00247
00248
00249 const G4VPhysicalVolume* currentVolume(0);
00250 if ( fIsGhostGeometry ) currentVolume = fPathFinder->GetLocatedVolume(fGhostNavigatorIndex);
00251 else currentVolume = track.GetVolume();
00252
00253 if ( currentVolume )
00254 {
00255 fFastSimulationManager = currentVolume->GetLogicalVolume()->GetFastSimulationManager();
00256 if( fFastSimulationManager )
00257 {
00258
00259 fFastSimulationTrigger = fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track, fGhostNavigator);
00260 if( fFastSimulationTrigger )
00261 {
00262
00263 *condition = ExclusivelyForced;
00264 return 0.0;
00265 }
00266 }
00267 }
00268
00269
00270 *condition = NotForced;
00271 return DBL_MAX;
00272 }
00273
00274
00275
00276
00277 G4VParticleChange*
00278 G4FastSimulationManagerProcess::
00279 PostStepDoIt(const G4Track&,
00280 const G4Step&)
00281 {
00282 G4VParticleChange* finalState = fFastSimulationManager->InvokePostStepDoIt();
00283
00284
00285 if (finalState->GetTrackStatus() != fStopAndKill) finalState->ProposeTrackStatus(fSuspend);
00286
00287 return finalState;
00288 }
00289
00290
00291 G4double
00292 G4FastSimulationManagerProcess::
00293 AlongStepGetPhysicalInteractionLength(const G4Track& track,
00294 G4double previousStepSize,
00295 G4double currentMinimumStep,
00296 G4double& proposedSafety,
00297 G4GPILSelection* selection)
00298 {
00299
00300 *selection = NotCandidateForSelection;
00301 G4double returnedStep = DBL_MAX;
00302
00303
00304
00305
00306
00307
00308
00309 if ( fIsGhostGeometry )
00310 {
00311 static G4FieldTrack endTrack('0');
00312 static ELimited eLimited;
00313
00314 if (previousStepSize > 0.) fGhostSafety -= previousStepSize;
00315 if (fGhostSafety < 0.) fGhostSafety = 0.0;
00316
00317
00318
00319
00320 if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
00321 {
00322
00323 returnedStep = currentMinimumStep;
00324 proposedSafety = fGhostSafety - currentMinimumStep;
00325 }
00326 else
00327 {
00328
00329 G4FieldTrackUpdator::Update(&fFieldTrack, &track);
00330 returnedStep = fPathFinder->ComputeStep(fFieldTrack,
00331 currentMinimumStep,
00332 fGhostNavigatorIndex,
00333 track.GetCurrentStepNumber(),
00334 fGhostSafety,
00335 eLimited,
00336 endTrack,
00337 track.GetVolume());
00338
00339 if(eLimited == kDoNot) fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition());
00340 proposedSafety = fGhostSafety;
00341 if (eLimited == kUnique || eLimited == kSharedOther) *selection = CandidateForSelection;
00342 else if (eLimited == kSharedTransport) returnedStep *= (1.0 + 1.0e-9);
00343 }
00344 }
00345
00346
00347
00348
00349
00350
00351
00352 return returnedStep;
00353 }
00354
00355 G4VParticleChange*
00356 G4FastSimulationManagerProcess::
00357 AlongStepDoIt(const G4Track& track,
00358 const G4Step&)
00359 {
00360 fDummyParticleChange.Initialize(track);
00361 return &fDummyParticleChange;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370 G4double
00371 G4FastSimulationManagerProcess::
00372 AtRestGetPhysicalInteractionLength(const G4Track& track,
00373 G4ForceCondition* condition)
00374 {
00375 const G4VPhysicalVolume* currentVolume(0);
00376 if ( fIsGhostGeometry ) currentVolume = fPathFinder->GetLocatedVolume(fGhostNavigatorIndex);
00377 else currentVolume = track.GetVolume();
00378 fFastSimulationManager = currentVolume->GetLogicalVolume()->GetFastSimulationManager();
00379 if( fFastSimulationManager )
00380 {
00381
00382 fFastSimulationTrigger = fFastSimulationManager->AtRestGetFastSimulationManagerTrigger(track, fGhostNavigator);
00383 if( fFastSimulationTrigger )
00384 {
00385
00386 *condition = NotForced;
00387 return -1.0;
00388 }
00389 }
00390
00391
00392 *condition = NotForced;
00393 return DBL_MAX;
00394 }
00395
00396
00397
00398
00399 G4VParticleChange* G4FastSimulationManagerProcess::AtRestDoIt(const G4Track&, const G4Step&)
00400 {
00401 return fFastSimulationManager->InvokeAtRestDoIt();
00402 }
00403
00404
00405 void G4FastSimulationManagerProcess::Verbose() const
00406 {
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 }
00430
00431