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

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

tag geant4.9.4 beta 1 + modifs locales

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-04-beta-01 $
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.