Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/biasing/generic/src/G4BOptrForceCollision.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 // G4BOptrForceCollision
 27 // --------------------------------------------------------------------
 28 
 29 #include "G4BOptrForceCollision.hh"
 30 #include "G4BOptrForceCollisionTrackData.hh"
 31 #include "G4BiasingProcessInterface.hh"
 32 #include "G4PhysicsModelCatalog.hh"
 33 
 34 #include "G4BOptnForceCommonTruncatedExp.hh"
 35 #include "G4ILawCommonTruncatedExp.hh"
 36 #include "G4BOptnForceFreeFlight.hh"
 37 #include "G4BOptnCloning.hh"
 38 
 39 #include "G4Step.hh"
 40 #include "G4StepPoint.hh"
 41 #include "G4VProcess.hh"
 42 
 43 #include "G4ParticleDefinition.hh"
 44 #include "G4ParticleTable.hh"
 45 
 46 #include "G4SystemOfUnits.hh"
 47 
 48 // -- Consider calling other constructor, thanks to C++11
 49 G4BOptrForceCollision::
 50 G4BOptrForceCollision(const G4String& particleName,
 51                       const G4String& name)
 52   : G4VBiasingOperator(name),
 53     fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision"))
 54 {
 55   fSharedForceInteractionOperation = new G4BOptnForceCommonTruncatedExp("SharedForceInteraction");
 56   fCloningOperation = new G4BOptnCloning("Cloning");
 57   fParticleToBias = G4ParticleTable::GetParticleTable()->FindParticle(particleName);
 58   
 59   if ( fParticleToBias == nullptr )
 60   {
 61     G4ExceptionDescription ed;
 62     ed << " Particle `" << particleName << "' not found !" << G4endl;
 63     G4Exception(" G4BOptrForceCollision::G4BOptrForceCollision(...)",
 64                 "BIAS.GEN.07", JustWarning, ed);
 65   }
 66 }
 67 
 68 G4BOptrForceCollision::
 69 G4BOptrForceCollision(const G4ParticleDefinition* particle,
 70                       const G4String& name)
 71   : G4VBiasingOperator(name),
 72     fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision"))
 73 {
 74   fSharedForceInteractionOperation = new G4BOptnForceCommonTruncatedExp("SharedForceInteraction");
 75   fCloningOperation = new G4BOptnCloning("Cloning");
 76   fParticleToBias = particle;
 77 }
 78 
 79 G4BOptrForceCollision::~G4BOptrForceCollision()
 80 {
 81   for ( auto it = fFreeFlightOperations.cbegin();
 82              it != fFreeFlightOperations.cend(); ++it )
 83   {
 84     delete (*it).second;
 85   }
 86   delete fSharedForceInteractionOperation;
 87   delete fCloningOperation;
 88 }
 89 
 90 void G4BOptrForceCollision::Configure()
 91 {
 92   // -- build free flight operations:
 93   ConfigureForWorker();
 94 }
 95 
 96 void G4BOptrForceCollision::ConfigureForWorker()
 97 {
 98   // -- start by remembering processes under biasing,
 99   //    and create needed biasing operations:
100   if ( fSetup )
101   {
102     const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
103     const G4BiasingProcessSharedData* interfaceProcessSharedData = G4BiasingProcessInterface::GetSharedData( processManager );
104     if ( interfaceProcessSharedData ) // -- sharedData tested, as is can happen a user attaches an operator
105                                 // -- to a volume but without defining BiasingProcessInterface processes.
106     {
107       for ( std::size_t i = 0 ; i < (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces()).size(); ++i )
108       {
109         const G4BiasingProcessInterface* wrapperProcess =
110           (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces())[i];
111         const G4String& operationName = "FreeFlight-"+wrapperProcess->GetWrappedProcess()->GetProcessName();
112         fFreeFlightOperations[wrapperProcess] = new G4BOptnForceFreeFlight(operationName);
113       }
114     }
115     fSetup = false;
116   }
117 }
118 
119 void G4BOptrForceCollision::StartRun()
120 {
121 }
122 
123 G4VBiasingOperation*
124 G4BOptrForceCollision::ProposeOccurenceBiasingOperation(const G4Track* track,
125                                const G4BiasingProcessInterface* callingProcess)
126 {
127   // -- does nothing if particle is not of requested type:
128   if ( track->GetDefinition() != fParticleToBias ) return nullptr;
129 
130   // -- trying to get auxiliary track data...
131   if ( fCurrentTrackData == nullptr )
132   {
133     // ... and if the track has no aux. track data, it means its biasing is not started yet (note that cloning is to happen first):
134     fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
135     if ( fCurrentTrackData == nullptr ) return nullptr;
136   }
137 
138   // -- Send force free flight to the callingProcess:
139   // ------------------------------------------------
140   // -- The track has been cloned in the previous step, it has now to be
141   // -- forced for a free flight.
142   // -- This track will fly with 0.0 weight during its forced flight:
143   // -- it is to forbid the double counting with the force interaction track.
144   // -- Its weight is restored at the end of its free flight, this weight
145   // -- being its initial weight * the weight for the free flight travel,
146   // -- this last one being per process. The initial weight is common, and is
147   // -- arbitrary asked to the first operation to take care of it.
148   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
149   {
150     G4BOptnForceFreeFlight* operation = fFreeFlightOperations[callingProcess];
151     if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
152     {
153       // -- the initial track weight will be restored only by the first DoIt free flight:
154       operation->ResetInitialTrackWeight(fInitialTrackWeight);
155       return operation;
156     }
157     else
158     {
159       return nullptr;
160     }
161   }
162 
163   // -- Send force interaction operation to the callingProcess:
164   // ----------------------------------------------------------
165   // -- at this level, a copy of the track entering the volume was
166   // -- generated (borned) earlier. This copy will make the forced
167   // -- interaction in the volume.
168   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
169   {
170     // -- Remember if this calling process is the first of the physics wrapper in
171     // -- the PostStepGPIL loop (using default argument of method below):
172     G4bool isFirstPhysGPIL = callingProcess-> GetIsFirstPostStepGPILInterface();
173       
174     // -- [*first process*] Initialize or update force interaction operation:
175     if ( isFirstPhysGPIL )
176     {
177       // -- first step of cloned track, initialize the forced interaction operation:
178       if ( track->GetCurrentStepNumber() == 1 )
179       {
180         fSharedForceInteractionOperation->Initialize( track );
181       }
182       else
183       {
184         if ( fSharedForceInteractionOperation->GetInitialMomentum() != track->GetMomentum() )
185         {
186           // -- means that some other physics process, not under control of the forced interaction operation,
187           // -- has occured, need to re-initialize the operation as distance to boundary has changed.
188           // -- [ Note the re-initialization is only possible for a Markovian law. ]
189           fSharedForceInteractionOperation->Initialize( track );
190         }
191         else
192         {
193           // -- means that some other non-physics process (biasing or not, like step limit), has occured,
194           // -- but track conserves its momentum direction, only need to reduced the maximum distance for
195           // -- forced interaction.
196           // -- [ Note the update is only possible for a Markovian law. ]
197           fSharedForceInteractionOperation->UpdateForStep( track->GetStep() );
198         }
199       }
200     }
201       
202     // -- [*all processes*] Sanity check : it may happen in limit cases that distance to
203     // -- out is zero, weight would be infinite in this case: abort forced interaction
204     // -- and abandon biasing.
205     if ( fSharedForceInteractionOperation->GetMaximumDistance() < DBL_MIN )
206     {
207       fCurrentTrackData->Reset();
208       return nullptr;
209     }
210       
211     // -- [* first process*] collect cross-sections and sample force law to determine interaction length
212     // -- and winning process:
213     if ( isFirstPhysGPIL )
214     {
215       // -- collect cross-sections:
216       // -- ( Remember that the first of the G4BiasingProcessInterface triggers the update
217       // --   of these cross-sections )
218       const G4BiasingProcessSharedData* sharedData = callingProcess->GetSharedData();
219       for ( std::size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size() ; ++i )
220       {
221         const G4BiasingProcessInterface* wrapperProcess = ( sharedData->GetPhysicsBiasingProcessInterfaces() )[i];
222         G4double interactionLength = wrapperProcess->GetWrappedProcess()->GetCurrentInteractionLength();
223         // -- keep only well defined cross-sections, other processes are ignored. These are not pathological cases
224         // -- but cases where a threhold effect par example (eg pair creation) may be at play. (**!**)
225         if ( interactionLength < DBL_MAX/10. )
226           fSharedForceInteractionOperation->AddCrossSection( wrapperProcess->GetWrappedProcess(),  1.0/interactionLength );
227       }
228       // -- sample the shared law (interaction length, and winning process):
229       if ( fSharedForceInteractionOperation->GetNumberOfSharing() > 0 )
230         fSharedForceInteractionOperation->Sample();
231     }
232       
233     // -- [*all processes*] Send operation for processes with well defined XS (see "**!**" above):
234     G4VBiasingOperation* operationToReturn = nullptr;
235     if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
236       operationToReturn = fSharedForceInteractionOperation;
237     return operationToReturn;
238 
239   } // -- end of "if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )"
240 
241   
242   // -- other cases here: particle appearing in the volume by some
243   // -- previous interaction : we decide to not bias these.
244   return nullptr;
245 }
246 
247 G4VBiasingOperation* G4BOptrForceCollision::
248 ProposeNonPhysicsBiasingOperation(const G4Track* track,
249                                   const G4BiasingProcessInterface* /* callingProcess */)
250 {
251   if ( track->GetDefinition() != fParticleToBias ) return nullptr;
252   
253   // -- Apply biasing scheme only to tracks entering the volume.
254   // -- A "cloning" is done:
255   // --  - the primary will be forced flight under a zero weight up to volume exit,
256   // --    where the weight will be restored with proper weight for free flight
257   // --  - the clone will be forced to interact in the volume.
258   if ( track->GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary ) // -- ยงยงยง extent to case of a track shoot on the boundary ?
259   {
260     // -- check that track is free of undergoing biasing scheme ( no biasing data, or no active active )
261     // -- Get possible track data:
262     fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
263     if ( fCurrentTrackData != nullptr )
264     {
265       if ( fCurrentTrackData->IsFreeFromBiasing() )
266       {
267         // -- takes "ownership" (some track data created before, left free, reuse it):
268         fCurrentTrackData->fForceCollisionOperator = this ;
269       }
270       else
271       {
272         // Would something be really wrong in this case ?
273         // Could this be that a process made a zero step ?
274       }
275     }
276     else
277     {
278       fCurrentTrackData = new G4BOptrForceCollisionTrackData( this );
279       track->SetAuxiliaryTrackInformation(fForceCollisionModelID, fCurrentTrackData);
280     }
281     fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeCloned;
282     fInitialTrackWeight = track->GetWeight();
283     fCloningOperation->SetCloneWeights(0.0, fInitialTrackWeight);
284 
285     return fCloningOperation;
286   }
287   
288   return nullptr;
289 }
290 
291 G4VBiasingOperation* G4BOptrForceCollision::
292 ProposeFinalStateBiasingOperation(const G4Track*,
293                                   const G4BiasingProcessInterface* callingProcess)
294 {
295   // -- Propose at final state generation the same operation which was proposed at GPIL level,
296   // -- (which is either the force free flight or the force interaction operation).
297   // -- count on the process interface to collect this operation:
298   return callingProcess->GetCurrentOccurenceBiasingOperation();
299 }
300 
301 void G4BOptrForceCollision::StartTracking( const G4Track* track )
302 {
303   fCurrentTrack     = track;
304   fCurrentTrackData = nullptr; 
305 }
306 
307 void G4BOptrForceCollision::EndTracking()
308 {
309   // -- check for consistency, operator should have cleaned the track:
310   if ( fCurrentTrackData != nullptr )
311   {
312     if ( !fCurrentTrackData->IsFreeFromBiasing() )
313     {
314       if ( (fCurrentTrack->GetTrackStatus() == fStopAndKill)
315         || (fCurrentTrack->GetTrackStatus() == fKillTrackAndSecondaries) )
316       {
317         G4ExceptionDescription ed;
318   ed << "Current track deleted while under biasing by "
319            << GetName() << ". Will result in inconsistencies.";
320         G4Exception(" G4BOptrForceCollision::EndTracking()",
321                     "BIAS.GEN.18", JustWarning, ed);
322       }
323     }
324   } 
325 }
326 
327 void G4BOptrForceCollision::
328 OperationApplied( const G4BiasingProcessInterface* callingProcess,
329                         G4BiasingAppliedCase BAC,
330                         G4VBiasingOperation* operationApplied,
331                   const G4VParticleChange* )
332 {
333   if ( fCurrentTrackData == nullptr )
334   {
335     if ( BAC != BAC_None )
336     {
337       G4ExceptionDescription ed;
338       ed << " Internal inconsistency : please submit bug report. " << G4endl;
339       G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
340                   "BIAS.GEN.20.1", JustWarning, ed); 
341     }
342     return;
343   }
344   
345   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeCloned )
346   {
347     fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeFreeFlight;
348     auto cloneData = new G4BOptrForceCollisionTrackData( this );
349     cloneData->fForceCollisionState = ForceCollisionState::toBeForced;
350     fCloningOperation->GetCloneTrack()->SetAuxiliaryTrackInformation(fForceCollisionModelID, cloneData);
351   }
352   else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
353   {
354     if ( fFreeFlightOperations[callingProcess]->OperationComplete() )
355       fCurrentTrackData->Reset(); // -- off biasing for this track
356   }
357   else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
358   {
359     if ( operationApplied != fSharedForceInteractionOperation )
360     {
361       G4ExceptionDescription ed;
362       ed << " Internal inconsistency : please submit bug report. " << G4endl;
363       G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
364                   "BIAS.GEN.20.2", JustWarning, ed); 
365   }
366     if ( fSharedForceInteractionOperation->GetInteractionOccured() )
367     {
368       if ( operationApplied != fSharedForceInteractionOperation )
369       {
370         G4ExceptionDescription ed;
371         ed << " Internal inconsistency : please submit bug report. " << G4endl;
372         G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
373                     "BIAS.GEN.20.3", JustWarning, ed); 
374       } 
375     }
376   }
377   else
378   {
379     if ( fCurrentTrackData->fForceCollisionState != ForceCollisionState::free )
380     {
381       G4ExceptionDescription ed;
382       ed << " Internal inconsistency : please submit bug report. " << G4endl;
383       G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
384                   "BIAS.GEN.20.4", JustWarning, ed); 
385     }
386   }
387 }
388 
389 void  G4BOptrForceCollision::
390 OperationApplied( const G4BiasingProcessInterface* /*callingProcess*/,
391                         G4BiasingAppliedCase /*biasingCase*/,
392                         G4VBiasingOperation* /*occurenceOperationApplied*/,
393                         G4double             /*weightForOccurenceInteraction*/,
394                         G4VBiasingOperation* finalStateOperationApplied,
395                   const G4VParticleChange*   /*particleChangeProduced*/ )
396 {
397   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
398   {
399     if ( finalStateOperationApplied != fSharedForceInteractionOperation )
400     {
401       G4ExceptionDescription ed;
402       ed << " Internal inconsistency : please submit bug report. " << G4endl;
403       G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
404                   "BIAS.GEN.20.5", JustWarning, ed); 
405     }
406     if ( fSharedForceInteractionOperation->GetInteractionOccured() )
407       fCurrentTrackData->Reset(); // -- off biasing for this track
408   }
409   else
410   {
411     G4ExceptionDescription ed;
412     ed << " Internal inconsistency : please submit bug report. " << G4endl;
413     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
414                 "BIAS.GEN.20.6", JustWarning, ed);   
415   }
416 }
417