source: trunk/source/processes/parameterisation/src/G4FastSimulationManagerProcess.cc @ 963

Last change on this file since 963 was 963, checked in by garnier, 15 years ago

update processes

File size: 14.3 KB
Line 
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// $Id: G4FastSimulationManagerProcess.cc,v 1.18 2008/03/13 16:03:23 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-02-ref-02 $
29//
30//
31//---------------------------------------------------------------
32//
33//  G4FastSimulationProcess.cc
34//
35//  Description:
36//    The process that triggers the parameterised simulations,
37//    if any.
38//
39//  History:
40//    August 97: First implementation. Verderi && MoraDeFreitas.
41//    October 06: move to parallel geometry scheme, M. Verderi
42//---------------------------------------------------------------
43
44#include "G4ios.hh"
45#include "G4FastSimulationManagerProcess.hh"
46#include "G4GlobalFastSimulationManager.hh"
47#include "G4TransportationManager.hh"
48#include "G4PathFinder.hh"
49#include "G4ParticleChange.hh"
50#include "G4FieldTrackUpdator.hh"
51
52#define  PARANOIA
53
54G4FastSimulationManagerProcess::
55G4FastSimulationManagerProcess(const G4String& processName,
56                               G4ProcessType       theType) : 
57  G4VProcess(processName,theType),
58  fWorldVolume(0),
59  fIsTrackingTime(false),
60  fGhostNavigator(0),
61  fGhostNavigatorIndex(-1),
62  fIsGhostGeometry(false),
63  fGhostSafety(-1.0),
64  fFieldTrack('0'),
65  fFastSimulationManager(0),
66  fFastSimulationTrigger(false)
67{
68  fPathFinder            = G4PathFinder::GetInstance();
69  fTransportationManager = G4TransportationManager::GetTransportationManager();
70 
71  SetWorldVolume(fTransportationManager->GetNavigatorForTracking()->GetWorldVolume()->GetName());
72  if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName() 
73                             << "' is created, and will message geometry with world volume `" 
74                             << fWorldVolume->GetName() << "'." << G4endl;
75  G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->AddFSMP(this);
76}
77
78
79G4FastSimulationManagerProcess::
80G4FastSimulationManagerProcess(const G4String&     processName,
81                               const G4String& worldVolumeName,
82                               G4ProcessType           theType) :
83  G4VProcess(processName,theType),
84  fWorldVolume(0),
85  fIsTrackingTime(false),
86  fGhostNavigator(0),
87  fGhostNavigatorIndex(-1),
88  fIsGhostGeometry(false),
89  fGhostSafety(-1.0),
90  fFieldTrack('0'),
91  fFastSimulationManager(0),
92  fFastSimulationTrigger(false)
93{
94  fPathFinder            = G4PathFinder::GetInstance();
95  fTransportationManager = G4TransportationManager::GetTransportationManager();
96
97  SetWorldVolume(worldVolumeName);
98  if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName() 
99                             << "' is created, and will message geometry with world volume `" 
100                             << fWorldVolume->GetName() << "'." << G4endl;
101  G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->AddFSMP(this);
102}
103
104
105G4FastSimulationManagerProcess::
106G4FastSimulationManagerProcess(const G4String&    processName,
107                               G4VPhysicalVolume* worldVolume,
108                               G4ProcessType      theType) :
109  G4VProcess(processName,theType),
110  fWorldVolume(0),
111  fIsTrackingTime(false),
112  fGhostNavigator(0),
113  fGhostNavigatorIndex(-1),
114  fIsGhostGeometry(false),
115  fGhostSafety(-1.0),
116  fFieldTrack('0'),
117  fFastSimulationManager(0),
118  fFastSimulationTrigger(false)
119{
120  fPathFinder            = G4PathFinder::GetInstance();
121  fTransportationManager = G4TransportationManager::GetTransportationManager();
122
123  SetWorldVolume(worldVolume);
124  if (verboseLevel>0) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName() 
125                             << "' is created, and will message geometry with world volume `" 
126                             << fWorldVolume->GetName() << "'." << G4endl;
127  G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->AddFSMP(this);
128}
129
130
131G4FastSimulationManagerProcess::~G4FastSimulationManagerProcess()
132{
133  G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->RemoveFSMP(this);
134}
135
136
137// -----------------------
138//   User access methods:
139// -----------------------
140void
141G4FastSimulationManagerProcess::
142SetWorldVolume(G4String newWorldName)
143{
144  if (fIsTrackingTime)
145    G4cout << "!!! G4FastSimulationManagerProcess `" << GetProcessName() 
146           << "': changing world volume at tracking time is not allowed for now. Call ignored !!!" << G4endl;
147  else
148    {
149      G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting(newWorldName);
150      G4String tellWhatIsWrong;
151      tellWhatIsWrong = "Volume newWorldName = `"; tellWhatIsWrong +=  newWorldName; tellWhatIsWrong += "' is not a parallel world nor the mass world volume.";
152      if (newWorld == 0) G4Exception("G4FastSimulationManagerProcess::SetWorldVolume(const G4String&, G4bool verbose)",
153                                     "InvalidWorld",
154                                     FatalException,
155                                     tellWhatIsWrong);
156      if (verboseLevel>0)
157      {
158        if (fWorldVolume) G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
159                                 << "': changing world volume from '"  << fWorldVolume->GetName() 
160                                 << "' to `" << newWorld << "'." << G4endl;
161        else              G4cout << "G4FastSimulationManagerProcess `" << GetProcessName()
162                                 << "': setting world volume from to `"<< newWorld->GetName() << "'." << G4endl;
163      }
164      fWorldVolume = newWorld;
165    }
166}
167
168
169void
170G4FastSimulationManagerProcess::
171SetWorldVolume(G4VPhysicalVolume* newWorld)
172{
173  if (newWorld) SetWorldVolume(newWorld->GetName());
174  else G4Exception("!!! G4FastSimulationManagerProcess::SetWorldVolume(const G4VPhysicalVolume* newWorld) : null pointer passed. !!!");
175}
176
177
178// --------------------
179//  Start/End tracking:
180// --------------------
181void
182G4FastSimulationManagerProcess::
183StartTracking(G4Track* track)
184{
185  fIsTrackingTime = true;
186  fIsFirstStep    = true;
187 
188  // -- fetch the navigator (and its index) and activate it:
189  G4TransportationManager* transportationManager = G4TransportationManager::GetTransportationManager();
190  fGhostNavigator                            = transportationManager->GetNavigator(fWorldVolume);
191  fIsGhostGeometry                           = (fGhostNavigator != transportationManager->GetNavigatorForTracking());
192  if (fIsGhostGeometry) fGhostNavigatorIndex = transportationManager->ActivateNavigator(fGhostNavigator);
193  else                  fGhostNavigatorIndex = -1;
194
195  fPathFinder->PrepareNewTrack(track->GetPosition(), track->GetMomentumDirection());
196}
197
198
199void
200G4FastSimulationManagerProcess::
201EndTracking()
202{
203  fIsTrackingTime = false;
204  if ( fIsGhostGeometry ) fTransportationManager->DeActivateNavigator(fGhostNavigator); 
205}
206
207
208// ------------------------------------------
209//   PostStepGetPhysicalInteractionLength():
210// ------------------------------------------
211G4double
212G4FastSimulationManagerProcess::
213PostStepGetPhysicalInteractionLength(const G4Track&               track, 
214                                     G4double,
215                                     G4ForceCondition*        condition)
216{
217#ifdef PARANOIA
218  if ( fGhostNavigator->GetWorldVolume() != fWorldVolume ) G4Exception("!!! ??? INCONSISTENT NAVIGATORS/WORLD VOLUMES ??? !!!");
219#endif
220  // -- Get current volume, and check for presence of fast simulation manager.
221  // -- For the case of the navigator for tracking (fGhostNavigatorIndex == 0)
222  // -- we use the track volume. This allows the code to be valid for both
223  // -- cases where the PathFinder is used (G4CoupledTranportation) or not
224  // -- (G4Transportation).
225  const G4VPhysicalVolume* currentVolume(0);
226  if ( fIsGhostGeometry )  currentVolume = fPathFinder->GetLocatedVolume(fGhostNavigatorIndex);
227  else                     currentVolume = track.GetVolume();
228
229  if ( currentVolume )
230    {
231      fFastSimulationManager = currentVolume->GetLogicalVolume()->GetFastSimulationManager();
232      if( fFastSimulationManager )
233        {
234          // Ask for trigger:
235          fFastSimulationTrigger = fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track, fGhostNavigator);
236          if( fFastSimulationTrigger )
237            {
238              // Take control over stepping:
239              *condition = ExclusivelyForced;
240              return 0.0;
241            }
242        }     
243    }
244 
245  // -- no fast simulation occuring there:
246  *condition = NotForced;
247  return DBL_MAX;
248}
249
250//------------------------------------
251//             PostStepDoIt()
252//------------------------------------
253G4VParticleChange*
254G4FastSimulationManagerProcess::
255PostStepDoIt(const G4Track&,
256             const G4Step&)
257{
258  G4VParticleChange* finalState = fFastSimulationManager->InvokePostStepDoIt();
259 
260  // If the particle is still alive, suspend it to force physics re-initialisation:
261  if (finalState->GetTrackStatus() != fStopAndKill) finalState->ProposeTrackStatus(fSuspend);
262 
263  return finalState;
264}
265
266
267G4double
268G4FastSimulationManagerProcess::
269AlongStepGetPhysicalInteractionLength(const G4Track&                track,
270                                      G4double           previousStepSize,
271                                      G4double         currentMinimumStep, 
272                                      G4double&            proposedSafety, 
273                                      G4GPILSelection*          selection)
274{
275 
276  *selection            = NotCandidateForSelection;
277  G4double returnedStep = DBL_MAX;
278
279  // ---------------------------------------------------
280  // -- Below code valid for ghost geometry, otherwise
281  // -- useless for fast simulation attached to mass
282  // -- geometry. Warn user in case along used for
283  // -- mass geometry ?
284  // --------------------------------------------------
285  if ( fIsGhostGeometry )
286    {
287      static G4FieldTrack endTrack('0');
288      static ELimited eLimited;
289     
290      if (previousStepSize > 0.) fGhostSafety -= previousStepSize;
291      if (fGhostSafety < 0.)     fGhostSafety = 0.0;
292     
293      // ------------------------------------------
294      // Determination of the proposed step length:
295      // ------------------------------------------
296      if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
297        {
298          // -- No chance to limit the step, as proposed move inside safety
299          returnedStep   = currentMinimumStep;
300          proposedSafety = fGhostSafety - currentMinimumStep;
301        }
302      else
303        {
304          // -- Proposed move exceeds safety, need to state
305          G4FieldTrackUpdator::Update(&fFieldTrack, &track);
306          returnedStep = fPathFinder->ComputeStep(fFieldTrack,
307                                                  currentMinimumStep,
308                                                  fGhostNavigatorIndex,
309                                                  track.GetCurrentStepNumber(),
310                                                  fGhostSafety,
311                                                  eLimited,
312                                                  endTrack,
313                                                  track.GetVolume());
314         
315          if(eLimited == kDoNot) fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition()); // -- step no limited by ghost
316          proposedSafety = fGhostSafety;
317          if      (eLimited == kUnique || eLimited == kSharedOther) *selection     = CandidateForSelection;
318          else if (eLimited == kSharedTransport)                     returnedStep *= (1.0 + 1.0e-9);   // -- Expand to disable its selection in Step Manager comparison
319        }
320    }
321 
322
323  // ----------------------------------------------
324  // Returns the fGhostSafety as the proposedSafety
325  // The SteppingManager will take care of keeping
326  // the smallest one.
327  // ----------------------------------------------
328  return returnedStep;
329}
330
331G4VParticleChange*
332G4FastSimulationManagerProcess::
333AlongStepDoIt(const G4Track& track,
334              const G4Step&)
335{
336  fDummyParticleChange.Initialize(track);
337  return &fDummyParticleChange;
338}
339
340
341//--------------------------------------------
342//         At Rest parameterisation:
343//--------------------------------------------
344//   AtRestGetPhysiscalInteractionLength:
345//--------------------------------------------
346G4double
347G4FastSimulationManagerProcess::
348AtRestGetPhysicalInteractionLength(const G4Track&        track, 
349                                   G4ForceCondition* condition)
350{
351  const G4VPhysicalVolume* currentVolume(0);
352  if ( fIsGhostGeometry )  currentVolume = fPathFinder->GetLocatedVolume(fGhostNavigatorIndex);
353  else                     currentVolume = track.GetVolume();
354  fFastSimulationManager = currentVolume->GetLogicalVolume()->GetFastSimulationManager();
355  if( fFastSimulationManager )
356    {
357      // Ask for trigger:
358      fFastSimulationTrigger = fFastSimulationManager->AtRestGetFastSimulationManagerTrigger(track, fGhostNavigator);
359      if( fFastSimulationTrigger )
360        {
361          // Dirty trick to take control over stepping. Does anyone will ever use that ?
362          *condition = NotForced;
363          return -1.0;
364        }
365    }
366 
367  // -- no fast simulation occuring there:
368  *condition = NotForced;
369  return DBL_MAX;
370}
371
372//-----------------------------------------------
373//                  AtRestDoIt:
374//-----------------------------------------------
375G4VParticleChange* G4FastSimulationManagerProcess::AtRestDoIt(const G4Track&, const G4Step&)
376{
377  return fFastSimulationManager->InvokeAtRestDoIt();
378}
379
380
381void G4FastSimulationManagerProcess::Verbose() const
382{
383  /*  G4cout << "     >>>>> Trigger Status : ";
384  switch(fFastSimulationManager->GetTriggerStatus())
385    {
386    case NoModel:
387      G4cout << "NoModel" << G4endl;
388      break;
389    case OnBoundaryButLeaving:
390      G4cout << "OnBoundaryButLeaving" << G4endl;
391      break;
392    case OneModelTrigger:
393      G4cout << "OneModelTrigger" << G4endl;
394      break;
395    case NoModelTrigger:
396      G4cout << "NoModelTrigger" << G4endl;
397      break;
398    case Undefined:
399      G4cout << "Undefined" << G4endl;
400      break;
401    default:
402      G4cout << " Bizarre..." << G4endl;
403      break;
404    }*/
405}
406
407
Note: See TracBrowser for help on using the repository browser.