ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4FastSimulationManagerProcess.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4FastSimulationManagerProcess.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 //
29 //---------------------------------------------------------------
30 //
31 // G4FastSimulationProcess.cc
32 //
33 // Description:
34 // The process that triggers the parameterised simulations,
35 // if any.
36 //
37 // History:
38 // August 97: First implementation. Verderi && MoraDeFreitas.
39 // October 06: move to parallel geometry scheme, M. Verderi
40 //---------------------------------------------------------------
41 
42 #include "G4ios.hh"
46 #include "G4PathFinder.hh"
47 #include "G4ParticleChange.hh"
48 #include "G4FieldTrackUpdator.hh"
49 
50 #define PARANOIA
51 
54  G4ProcessType theType) :
55  G4VProcess(processName,theType),
56  fWorldVolume ( nullptr ),
57  fIsTrackingTime ( false ),
58  fIsFirstStep ( false ),
59  fGhostNavigator ( nullptr ),
60  fGhostNavigatorIndex ( -1 ),
61  fIsGhostGeometry ( false ),
62  fGhostSafety ( -1.0 ),
63  fFieldTrack ( '0' ),
64  fFastSimulationManager( nullptr ),
65  fFastSimulationTrigger( false )
66 {
67  // -- set Process Sub Type
68  SetProcessSubType(static_cast<int>(FASTSIM_ManagerProcess));
69 
70 
73 
75  if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
76  << "' is created, and will message geometry with world volume `"
77  << fWorldVolume->GetName() << "'." << G4endl;
79 }
80 
81 
84  const G4String& worldVolumeName,
85  G4ProcessType theType) :
86  G4VProcess(processName,theType),
87  fWorldVolume ( nullptr ),
88  fIsTrackingTime ( false ),
89  fIsFirstStep ( false ),
90  fGhostNavigator ( nullptr ),
91  fGhostNavigatorIndex ( -1 ),
92  fIsGhostGeometry ( false ),
93  fGhostSafety ( -1.0 ),
94  fFieldTrack ( '0' ),
95  fFastSimulationManager( nullptr ),
96  fFastSimulationTrigger( false )
97 {
98  // -- set Process Sub Type
99  SetProcessSubType(static_cast<int>(FASTSIM_ManagerProcess));
100 
101 
104 
105  SetWorldVolume(worldVolumeName);
106  if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
107  << "' is created, and will message geometry with world volume `"
108  << fWorldVolume->GetName() << "'." << G4endl;
110 }
111 
112 
115  G4VPhysicalVolume* worldVolume,
116  G4ProcessType theType) :
117  G4VProcess(processName,theType),
118  fWorldVolume ( nullptr ),
119  fIsTrackingTime ( false ),
120  fIsFirstStep ( false ),
121  fGhostNavigator ( nullptr ),
122  fGhostNavigatorIndex ( -1 ),
123  fIsGhostGeometry ( false ),
124  fGhostSafety ( -1.0 ),
125  fFieldTrack ( '0' ),
126  fFastSimulationManager( nullptr ),
127  fFastSimulationTrigger( false )
128 {
129  // -- set Process Sub Type
130  SetProcessSubType(static_cast<int>(FASTSIM_ManagerProcess));
131 
132 
135 
136  SetWorldVolume(worldVolume);
137  if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
138  << "' is created, and will message geometry with world volume `"
139  << fWorldVolume->GetName() << "'." << G4endl;
141 }
142 
143 
145 {
147 }
148 
149 
150 // -----------------------
151 // User access methods:
152 // -----------------------
154 {
155  if (fIsTrackingTime)
156  {
158  ed << "G4FastSimulationManagerProcess `" << GetProcessName()
159  << "': changing of world volume at tracking time is not allowed." << G4endl;
160  G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4String)",
161  "FastSim002",
162  JustWarning, ed,
163  "Call ignored.");
164  }
165  else
166  {
167  G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting(newWorldName);
168  if (newWorld == 0)
169  {
170  G4ExceptionDescription tellWhatIsWrong;
171  tellWhatIsWrong << "Volume newWorldName = `" << newWorldName
172  << "' is not a parallel world nor the mass world volume."
173  << G4endl;
174  G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4String)",
175  "FastSim003",
177  tellWhatIsWrong);
178  }
179  if (verboseLevel>0)
180  {
181  if (fWorldVolume) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
182  << "': changing world volume from '" << fWorldVolume->GetName()
183  << "' to `" << newWorld << "'." << G4endl;
184  else G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
185  << "': setting world volume from to `"<< newWorld->GetName() << "'." << G4endl;
186  }
187  fWorldVolume = newWorld;
188  }
189 }
190 
191 
193 {
194  if (newWorld) SetWorldVolume(newWorld->GetName());
195  else
196  {
197  G4ExceptionDescription tellWhatIsWrong;
198  tellWhatIsWrong << "Null pointer passed for world volume." << G4endl;
199  G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4VPhysicalVolume* newWorld)",
200  "FastSim004",
202  tellWhatIsWrong);
203  }
204 }
205 
206 
207 // --------------------
208 // Start/End tracking:
209 // --------------------
211 {
212  fIsTrackingTime = true;
213  fIsFirstStep = true;
214 
215  // -- fetch the navigator (and its index) and activate it:
217  fGhostNavigator = transportationManager->GetNavigator(fWorldVolume);
218  fIsGhostGeometry = (fGhostNavigator != transportationManager->GetNavigatorForTracking());
220  else fGhostNavigatorIndex = -1;
221 
223 }
224 
225 
226 void
229 {
230  fIsTrackingTime = false;
232 }
233 
234 
235 // ------------------------------------------
236 // PostStepGetPhysicalInteractionLength():
237 // ------------------------------------------
238 G4double
241  G4double,
243 {
244  // -- Get current volume, and check for presence of fast simulation manager.
245  // -- For the case of the navigator for tracking (fGhostNavigatorIndex == 0)
246  // -- we use the track volume. This allows the code to be valid for both
247  // -- cases where the PathFinder is used (G4CoupledTranportation) or not
248  // -- (G4Transportation).
249  const G4VPhysicalVolume* currentVolume(0);
251  else currentVolume = track.GetVolume();
252 
253  if ( currentVolume )
254  {
257  {
258  // Ask for trigger:
261  {
262  // Take control over stepping:
263  *condition = ExclusivelyForced;
264  return 0.0;
265  }
266  }
267  }
268 
269  // -- no fast simulation occuring there:
270  *condition = NotForced;
271  return DBL_MAX;
272 }
273 
274 //------------------------------------
275 // PostStepDoIt()
276 //------------------------------------
280  const G4Step&)
281 {
283 
284  // If the particle is still alive, suspend it to force physics re-initialisation:
285  if (finalState->GetTrackStatus() != fStopAndKill) finalState->ProposeTrackStatus(fSuspend);
286 
287  return finalState;
288 }
289 
290 
291 G4double
294  G4double previousStepSize,
295  G4double currentMinimumStep,
296  G4double& proposedSafety,
297  G4GPILSelection* selection)
298 {
299 
300  *selection = NotCandidateForSelection;
301  G4double returnedStep = DBL_MAX;
302 
303  // ---------------------------------------------------
304  // -- Below code valid for ghost geometry, otherwise
305  // -- useless for fast simulation attached to mass
306  // -- geometry. Warn user in case along used for
307  // -- mass geometry ?
308  // --------------------------------------------------
309  if ( fIsGhostGeometry )
310  {
311  static G4ThreadLocal G4FieldTrack *endTrack_G4MT_TLS_ = 0 ;
312  if (!endTrack_G4MT_TLS_) endTrack_G4MT_TLS_ = new G4FieldTrack ('0') ;
313  G4FieldTrack &endTrack = *endTrack_G4MT_TLS_;
314 
315  static G4ThreadLocal ELimited *eLimited_G4MT_TLS_ = 0 ;
316  if (!eLimited_G4MT_TLS_) eLimited_G4MT_TLS_ = new ELimited ;
317  ELimited &eLimited = *eLimited_G4MT_TLS_;
318 
319  if (previousStepSize > 0.) fGhostSafety -= previousStepSize;
320  if (fGhostSafety < 0.) fGhostSafety = 0.0;
321 
322  // ------------------------------------------
323  // Determination of the proposed step length:
324  // ------------------------------------------
325  if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
326  {
327  // -- No chance to limit the step, as proposed move inside safety
328  returnedStep = currentMinimumStep;
329  proposedSafety = fGhostSafety - currentMinimumStep;
330  }
331  else
332  {
333  // -- Proposed move exceeds safety, need to state
335  returnedStep = fPathFinder->ComputeStep(fFieldTrack,
336  currentMinimumStep,
338  track.GetCurrentStepNumber(),
339  fGhostSafety,
340  eLimited,
341  endTrack,
342  track.GetVolume());
343 
344  if(eLimited == kDoNot) fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition()); // -- step no limited by ghost
345  proposedSafety = fGhostSafety;
346  if (eLimited == kUnique || eLimited == kSharedOther) *selection = CandidateForSelection;
347  else if (eLimited == kSharedTransport) returnedStep *= (1.0 + 1.0e-9); // -- Expand to disable its selection in Step Manager comparison
348  }
349  }
350 
351 
352  // ----------------------------------------------
353  // Returns the fGhostSafety as the proposedSafety
354  // The SteppingManager will take care of keeping
355  // the smallest one.
356  // ----------------------------------------------
357  return returnedStep;
358 }
359 
363  const G4Step&)
364 {
366  return &fDummyParticleChange;
367 }
368 
369 
370 //--------------------------------------------
371 // At Rest parameterisation:
372 //--------------------------------------------
373 // AtRestGetPhysiscalInteractionLength:
374 //--------------------------------------------
375 G4double
379 {
380  const G4VPhysicalVolume* currentVolume(0);
382  else currentVolume = track.GetVolume();
385  {
386  // Ask for trigger:
389  {
390  // Dirty trick to take control over stepping. Does anyone will ever use that ?
391  *condition = NotForced;
392  return -1.0;
393  }
394  }
395 
396  // -- no fast simulation occuring there:
397  *condition = NotForced;
398  return DBL_MAX;
399 }
400 
401 //-----------------------------------------------
402 // AtRestDoIt:
403 //-----------------------------------------------
405 {
407 }
408 
409 
411 {
412  /* G4cout << " >>>>> Trigger Status : ";
413  switch(fFastSimulationManager->GetTriggerStatus())
414  {
415  case NoModel:
416  G4cout << "NoModel" << G4endl;
417  break;
418  case OnBoundaryButLeaving:
419  G4cout << "OnBoundaryButLeaving" << G4endl;
420  break;
421  case OneModelTrigger:
422  G4cout << "OneModelTrigger" << G4endl;
423  break;
424  case NoModelTrigger:
425  G4cout << "NoModelTrigger" << G4endl;
426  break;
427  case Undefined:
428  G4cout << "Undefined" << G4endl;
429  break;
430  default:
431  G4cout << " Bizarre..." << G4endl;
432  break;
433  }*/
434 }
435 
436