Geant4  10.01.p02
G4BOptrForceCollision.cc
Go to the documentation of this file.
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 #include "G4BOptrForceCollision.hh"
28 
32 #include "G4BOptnCloning.hh"
33 
34 #include "G4Step.hh"
35 #include "G4StepPoint.hh"
36 #include "G4VProcess.hh"
37 
38 #include "G4ParticleDefinition.hh"
39 #include "G4ParticleTable.hh"
40 
41 #include "G4SystemOfUnits.hh"
42 
43 
45  : G4VBiasingOperator(name),
46  fSetup(true)
47 {
49  fCloningOperation = new G4BOptnCloning("Cloning");
51 
52  if ( fParticleToBias == 0 )
53  {
55  ed << " Particle `" << particleName << "' not found !" << G4endl;
56  G4Exception(" G4BOptrForceCollision::G4BOptrForceCollision(...)",
57  "BIAS.GEN.07",
59  ed);
60  }
61 }
62 
63 
65  : G4VBiasingOperator(name),
66  fSetup(true)
67 {
69  fCloningOperation = new G4BOptnCloning("Cloning");
70  fParticleToBias = particle;
71 }
72 
73 
75 {
76  for ( std::map< const G4BiasingProcessInterface*, G4BOptnForceFreeFlight* >::iterator it = fFreeFlightOperations.begin() ;
77  it != fFreeFlightOperations.end() ;
78  it++ ) delete (*it).second;
80  delete fCloningOperation;
81 }
82 
83 
85 {
86  // -- start by remembering processes under biasing, and create needed biasing operations:
87  if ( fSetup )
88  {
89  const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
90  const G4BiasingProcessSharedData* sharedData =
92  if (sharedData ) // -- sharedData tested, as is can happen a user attaches an operator to a volume but without defined BiasingProcessInterface processes.
93  {
94  for ( size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size(); i++ )
95  {
96  const G4BiasingProcessInterface* wrapperProcess =
97  (sharedData->GetPhysicsBiasingProcessInterfaces())[i];
98  G4String operationName = "FreeFlight-"+wrapperProcess->GetWrappedProcess()->GetProcessName();
99  fFreeFlightOperations[wrapperProcess] = new G4BOptnForceFreeFlight(operationName);
100  }
101  }
102  fSetup = false;
103  }
104 }
105 
106 
108 {
109  if ( track->GetDefinition() != fParticleToBias ) return 0;
110 
111 
112  // -- Send force interaction operation to the callingProcess:
113  // ----------------------------------------------------------
114  // -- at this level, a copy of the track entering the volume was
115  // -- generated (borned) earlier. This copy will make the forced
116  // -- interaction in the volume.
117  if ( GetBirthOperation( track ) == fCloningOperation )
118  {
119  // -- forced interaction already occured, abort.
120  // -- [Note that if ones would redo a forced interaction, it
121  // -- would require an other cloning before, if one wants to conserve
122  // -- the weight.]
124 
125  // -- Remember if this calling process is the first of the physics wrapper in
126  // -- the PostStepGPIL loop (using default argument of method below):
127  G4bool isFirstPhysGPIL = callingProcess-> GetIsFirstPostStepGPILInterface();
128 
129  // -- [*first process*] Initialize or update force interaction operation:
130  if ( isFirstPhysGPIL )
131  {
132  // -- first step of cloned track, initialize the forced interaction operation:
134  else
135  {
137  {
138  // -- means that some other physics process, not under control of the forced interaction operation,
139  // -- has occured, need to re-initialize the operation as distance to boundary has changed.
140  // -- [ Note the re-initialization is only possible for a Markovian law. ]
142  }
143  else
144  {
145  // -- means that some other non-physics process (biasing or not, like step limit), has occured,
146  // -- but track conserves its momentum direction, only need to reduced the maximum distance for
147  // -- forced interaction.
148  // -- [ Note the update is only possible for a Markovian law. ]
150  }
151  }
152  }
153 
154  // -- [*all processes*] Sanity check : it may happen in limit cases that distance to
155  // -- out is zero, weight would be infinite in this case: abort forced interaction.
157 
158  // -- [* first process*] collect cross-sections and sample force law to determine interaction length
159  // -- and winning process:
160  if ( isFirstPhysGPIL )
161  {
162  // -- collect cross-sections:
163  // -- ( Remember that the first of the G4BiasingProcessInterface triggers the update
164  // -- of these cross-sections )
165  const G4BiasingProcessSharedData* sharedData = callingProcess->GetSharedData();
166  for ( size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size() ; i++ )
167  {
168  const G4BiasingProcessInterface* wrapperProcess = ( sharedData->GetPhysicsBiasingProcessInterfaces() )[i];
169  G4double interactionLength = wrapperProcess->GetWrappedProcess()->GetCurrentInteractionLength();
170  // -- keep only well defined cross-section (*§*):
171  if ( interactionLength < DBL_MAX/10. )
172  fSharedForceInteractionOperation->AddCrossSection( wrapperProcess->GetWrappedProcess(), 1.0/interactionLength );
173  }
174  // -- sample the shared law (interaction length, and winning process:
176  }
177 
178  // -- [*all processes*] Send operation, after sanity check (same criterium than (*§*) !):
179  G4double currentInteractionLength = callingProcess->GetWrappedProcess()->GetCurrentInteractionLength();
180  G4VBiasingOperation* operationToReturn = 0;
181  if ( currentInteractionLength < DBL_MAX/10. ) operationToReturn = fSharedForceInteractionOperation;
182 
183 
184  return operationToReturn;
185 
186  } // -- end of " if ( GetBirthOperation( track ) == fCloningOperation ) "
187 
188 
189 
190  // -- Send force free flight to the callingProcess:
191  // ------------------------------------------------
192  // -- At this point a track cloning happened in the previous step,
193  // -- we request the continuing/current track to be forced flight.
194  // -- Note this track will fly with 0.0 weight during its forced flight:
195  // -- it is to forbid the double counting with the force interaction track.
196  // -- Its weight is restored at the end of its free flight, this weight
197  // -- being its initial weight * the weight for the free flight travel,
198  // -- this last one being per process. The initial weight is common, and is
199  // -- arbitrary asked to the first operation to take care of it.
201  {
202  G4BOptnForceFreeFlight* operation = fFreeFlightOperations[callingProcess];
203  if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
204  {
205  // -- the initial track weight will be restored only by the first DoIt free flight:
207  return operation;
208  }
209  }
210  // -- If forced flight was already requested for the calling process, this flight
211  // -- may have been interupted by some other non-physics process : request
212  // -- process to continue with same forced flight:
213  // -- ** ?? ** Incorrect here in case of flight interrupted by a *physics process*. Ie case
214  // -- ** ?? ** of a subset of physics processes forced is not treated correctly here ** ?? **
215  else if ( callingProcess->GetPreviousOccurenceBiasingOperation() == fFreeFlightOperations[callingProcess] )
216  {
217  return fFreeFlightOperations[callingProcess];
218  }
219 
220  // -- other cases here: particle appearing in the volume by some
221  // -- previous interaction : we decide to not bias these.
222  return 0;
223 
224 }
225 
226 
228  const G4BiasingProcessInterface* /* callingProcess */)
229 {
230  if ( track->GetDefinition() != fParticleToBias ) return 0;
231 
232  // -- bias only tracks entering the volume.
233  // -- A "cloning" is done:
234  // -- - the primary will be forced flight under a zero weight up to volume exit,
235  // -- where the weight will be restored with proper weight for free flight
236  // -- - the clone will be forced to interact in the volume.
237  if ( track->GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary )
238  {
240  fInitialTrackWeight = track->GetWeight();
242  return fCloningOperation;
243  }
244 
245  // -- for all other cases: does nothing
246  return 0;
247 }
248 
249 
251 {
252  // -- Propose at final state generation the same operation which was proposed at GPIL level,
253  // -- (which is either the force free flight or the force interaction operation).
254  // -- count on the process interface to collect this operation:
255  return callingProcess->GetCurrentOccurenceBiasingOperation();
256 }
257 
258 
260 {
262 }
263 
264 
265 void G4BOptrForceCollision::ExitBiasing( const G4Track* track, const G4BiasingProcessInterface* /*callingProcess*/ )
266 {
268  // -- clean-up track for what happens with this operator:
269  ForgetTrack ( track );
270 }
271 
272 
274  G4VBiasingOperation* operationApplied, const G4VParticleChange* particleChangeProduced )
275 {
276  fPreviousOperationApplied = operationApplied;
277  if ( operationApplied == fCloningOperation )
278  RememberSecondaries( callingProcess, operationApplied, particleChangeProduced );
279 }
virtual void OperationApplied(const G4BiasingProcessInterface *callingProcess, G4BiasingAppliedCase biasingCase, G4VBiasingOperation *operationApplied, const G4VParticleChange *particleChangeProduced)
G4ParticleDefinition * GetDefinition() const
G4VBiasingOperation * GetCurrentOccurenceBiasingOperation() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
virtual void StartTracking(const G4Track *track)
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4String name
Definition: TRTMaterials.hh:40
G4StepStatus GetStepStatus() const
void AddCrossSection(const G4VProcess *, G4double)
G4VBiasingOperation * fPreviousOperationApplied
const std::vector< const G4BiasingProcessInterface * > & GetPhysicsBiasingProcessInterfaces() const
const G4ThreeVector & GetInitialMomentum() const
const G4Step * GetStep() const
G4ProcessManager * GetProcessManager() const
virtual G4VBiasingOperation * ProposeNonPhysicsBiasingOperation(const G4Track *track, const G4BiasingProcessInterface *callingProcess)
G4BOptrForceCollision(G4String particleToForce, G4String name="ForceCollision")
G4BiasingAppliedCase
G4VProcess * GetWrappedProcess() const
G4StepPoint * GetPreStepPoint() const
void ResetInitialTrackWeight(G4double w)
G4int GetCurrentStepNumber() const
G4BOptnForceCommonTruncatedExp * fSharedForceInteractionOperation
bool G4bool
Definition: G4Types.hh:79
G4double GetCurrentInteractionLength() const
Definition: G4VProcess.hh:462
G4BOptnCloning * fCloningOperation
const G4String & GetProcessName() const
Definition: G4VProcess.hh:408
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::map< const G4BiasingProcessInterface *, G4BOptnForceFreeFlight * > fFreeFlightOperations
void ForgetTrack(const G4Track *track)
void SetCloneWeights(G4double clone1Weight, G4double clone2Weight)
G4ThreeVector GetMomentum() const
static G4ParticleTable * GetParticleTable()
virtual G4VBiasingOperation * ProposeFinalStateBiasingOperation(const G4Track *track, const G4BiasingProcessInterface *callingProcess)
void RememberSecondaries(const G4BiasingProcessInterface *callingProcess, const G4VBiasingOperation *operationApplied, const G4VParticleChange *particleChangeProduced)
#define DBL_MIN
Definition: templates.hh:75
G4double GetWeight() const
#define G4endl
Definition: G4ios.hh:61
virtual G4VBiasingOperation * ProposeOccurenceBiasingOperation(const G4Track *track, const G4BiasingProcessInterface *callingProcess)
double G4double
Definition: G4Types.hh:76
#define DBL_MAX
Definition: templates.hh:83
const G4VBiasingOperation * GetBirthOperation(const G4Track *)
G4VBiasingOperation * GetPreviousOccurenceBiasingOperation() const
virtual void ExitBiasing(const G4Track *, const G4BiasingProcessInterface *)
const G4ParticleDefinition * fParticleToBias
const G4BiasingProcessSharedData * GetSharedData() const