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 ]

Diff markup

Differences between /processes/biasing/generic/src/G4BOptrForceCollision.cc (Version 11.3.0) and /processes/biasing/generic/src/G4BOptrForceCollision.cc (Version 11.2.1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4BOptrForceCollision                       << 
 27 // ------------------------------------------- << 
 28                                                << 
 29 #include "G4BOptrForceCollision.hh"                26 #include "G4BOptrForceCollision.hh"
 30 #include "G4BOptrForceCollisionTrackData.hh"       27 #include "G4BOptrForceCollisionTrackData.hh"
 31 #include "G4BiasingProcessInterface.hh"            28 #include "G4BiasingProcessInterface.hh"
 32 #include "G4PhysicsModelCatalog.hh"                29 #include "G4PhysicsModelCatalog.hh"
 33                                                    30 
 34 #include "G4BOptnForceCommonTruncatedExp.hh"       31 #include "G4BOptnForceCommonTruncatedExp.hh"
 35 #include "G4ILawCommonTruncatedExp.hh"             32 #include "G4ILawCommonTruncatedExp.hh"
 36 #include "G4BOptnForceFreeFlight.hh"               33 #include "G4BOptnForceFreeFlight.hh"
 37 #include "G4BOptnCloning.hh"                       34 #include "G4BOptnCloning.hh"
 38                                                    35 
 39 #include "G4Step.hh"                               36 #include "G4Step.hh"
 40 #include "G4StepPoint.hh"                          37 #include "G4StepPoint.hh"
 41 #include "G4VProcess.hh"                           38 #include "G4VProcess.hh"
 42                                                    39 
 43 #include "G4ParticleDefinition.hh"                 40 #include "G4ParticleDefinition.hh"
 44 #include "G4ParticleTable.hh"                      41 #include "G4ParticleTable.hh"
 45                                                    42 
 46 #include "G4SystemOfUnits.hh"                      43 #include "G4SystemOfUnits.hh"
 47                                                    44 
 48 // -- Consider calling other constructor, than <<  45 // -- §§ consider calling other constructor, thanks to C++11
 49 G4BOptrForceCollision::                        <<  46 G4BOptrForceCollision::G4BOptrForceCollision(G4String particleName, G4String name)
 50 G4BOptrForceCollision(const G4String& particle << 
 51                       const G4String& name)    << 
 52   : G4VBiasingOperator(name),                      47   : G4VBiasingOperator(name),
 53     fForceCollisionModelID(G4PhysicsModelCatal <<  48     fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision")),
                                                   >>  49     fCurrentTrack(nullptr),
                                                   >>  50     fCurrentTrackData(nullptr),
                                                   >>  51     fInitialTrackWeight(-1.0),
                                                   >>  52     fSetup(true)
 54 {                                                  53 {
 55   fSharedForceInteractionOperation = new G4BOp     54   fSharedForceInteractionOperation = new G4BOptnForceCommonTruncatedExp("SharedForceInteraction");
 56   fCloningOperation = new G4BOptnCloning("Clon <<  55   fCloningOperation                = new G4BOptnCloning("Cloning");
 57   fParticleToBias = G4ParticleTable::GetPartic     56   fParticleToBias = G4ParticleTable::GetParticleTable()->FindParticle(particleName);
 58                                                    57   
 59   if ( fParticleToBias == nullptr )            <<  58   if ( fParticleToBias == 0 )
 60   {                                            <<  59     {
 61     G4ExceptionDescription ed;                 <<  60       G4ExceptionDescription ed;
 62     ed << " Particle `" << particleName << "'  <<  61       ed << " Particle `" << particleName << "' not found !" << G4endl;
 63     G4Exception(" G4BOptrForceCollision::G4BOp <<  62       G4Exception(" G4BOptrForceCollision::G4BOptrForceCollision(...)",
 64                 "BIAS.GEN.07", JustWarning, ed <<  63       "BIAS.GEN.07",
 65   }                                            <<  64       JustWarning,
                                                   >>  65       ed);
                                                   >>  66     }
 66 }                                                  67 }
 67                                                    68 
 68 G4BOptrForceCollision::                        <<  69 
 69 G4BOptrForceCollision(const G4ParticleDefiniti <<  70 G4BOptrForceCollision::G4BOptrForceCollision(const G4ParticleDefinition* particle, G4String name)
 70                       const G4String& name)    << 
 71   : G4VBiasingOperator(name),                      71   : G4VBiasingOperator(name),
 72     fForceCollisionModelID(G4PhysicsModelCatal <<  72     fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision")),
                                                   >>  73     fCurrentTrack(nullptr),
                                                   >>  74     fCurrentTrackData(nullptr),
                                                   >>  75     fInitialTrackWeight(-1.0),
                                                   >>  76     fSetup(true)
 73 {                                                  77 {
 74   fSharedForceInteractionOperation = new G4BOp     78   fSharedForceInteractionOperation = new G4BOptnForceCommonTruncatedExp("SharedForceInteraction");
 75   fCloningOperation = new G4BOptnCloning("Clon <<  79   fCloningOperation                = new G4BOptnCloning("Cloning");
 76   fParticleToBias = particle;                  <<  80   fParticleToBias                  = particle;
 77 }                                                  81 }
 78                                                    82 
                                                   >>  83 
 79 G4BOptrForceCollision::~G4BOptrForceCollision(     84 G4BOptrForceCollision::~G4BOptrForceCollision()
 80 {                                                  85 {
 81   for ( auto it = fFreeFlightOperations.cbegin <<  86   for ( std::map< const G4BiasingProcessInterface*, G4BOptnForceFreeFlight* >::iterator it = fFreeFlightOperations.begin() ;
 82              it != fFreeFlightOperations.cend( <<  87   it != fFreeFlightOperations.end() ;
 83   {                                            <<  88   it++ ) delete (*it).second;
 84     delete (*it).second;                       << 
 85   }                                            << 
 86   delete fSharedForceInteractionOperation;         89   delete fSharedForceInteractionOperation;
 87   delete fCloningOperation;                        90   delete fCloningOperation;
 88 }                                                  91 }
 89                                                    92 
                                                   >>  93 
 90 void G4BOptrForceCollision::Configure()            94 void G4BOptrForceCollision::Configure()
 91 {                                                  95 {
 92   // -- build free flight operations:              96   // -- build free flight operations:
 93   ConfigureForWorker();                            97   ConfigureForWorker();
 94 }                                                  98 }
 95                                                    99 
                                                   >> 100 
 96 void G4BOptrForceCollision::ConfigureForWorker    101 void G4BOptrForceCollision::ConfigureForWorker()
 97 {                                                 102 {
 98   // -- start by remembering processes under b << 103   // -- start by remembering processes under biasing, and create needed biasing operations:
 99   //    and create needed biasing operations:  << 
100   if ( fSetup )                                   104   if ( fSetup )
101   {                                            << 105     {
102     const G4ProcessManager* processManager = f << 106       const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
103     const G4BiasingProcessSharedData* interfac << 107       const G4BiasingProcessSharedData* interfaceProcessSharedData = G4BiasingProcessInterface::GetSharedData( processManager );
104     if ( interfaceProcessSharedData ) // -- sh << 108       if ( interfaceProcessSharedData ) // -- sharedData tested, as is can happen a user attaches an operator
105                                 // -- to a vol << 109                                   // -- to a volume but without defining BiasingProcessInterface processes.
106     {                                          << 110   {
107       for ( std::size_t i = 0 ; i < (interface << 111     for ( size_t i = 0 ; i < (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces()).size(); i++ )
108       {                                        << 112       {
109         const G4BiasingProcessInterface* wrapp << 113         const G4BiasingProcessInterface* wrapperProcess =
110           (interfaceProcessSharedData->GetPhys << 114     (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces())[i];
111         const G4String& operationName = "FreeF << 115         G4String operationName = "FreeFlight-"+wrapperProcess->GetWrappedProcess()->GetProcessName();
112         fFreeFlightOperations[wrapperProcess]  << 116         fFreeFlightOperations[wrapperProcess] = new G4BOptnForceFreeFlight(operationName);
113       }                                        << 117       }
                                                   >> 118   }
                                                   >> 119       fSetup = false;
114     }                                             120     }
115     fSetup = false;                            << 
116   }                                            << 
117 }                                                 121 }
118                                                   122 
                                                   >> 123 
119 void G4BOptrForceCollision::StartRun()            124 void G4BOptrForceCollision::StartRun()
120 {                                                 125 {
121 }                                                 126 }
122                                                   127 
123 G4VBiasingOperation*                           << 128 
124 G4BOptrForceCollision::ProposeOccurenceBiasing << 129 G4VBiasingOperation* G4BOptrForceCollision::ProposeOccurenceBiasingOperation(const G4Track* track, const G4BiasingProcessInterface* callingProcess)
125                                const G4Biasing << 
126 {                                                 130 {
127   // -- does nothing if particle is not of req    131   // -- does nothing if particle is not of requested type:
128   if ( track->GetDefinition() != fParticleToBi << 132   if ( track->GetDefinition() != fParticleToBias ) return 0;
129                                                   133 
130   // -- trying to get auxiliary track data...     134   // -- trying to get auxiliary track data...
131   if ( fCurrentTrackData == nullptr )             135   if ( fCurrentTrackData == nullptr )
132   {                                            << 136     {
133     // ... and if the track has no aux. track  << 137       // ... 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 = (G4BOptrForceCollision << 138       fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
135     if ( fCurrentTrackData == nullptr ) return << 139       if ( fCurrentTrackData == nullptr ) return nullptr;
136   }                                            << 140     }
137                                                   141 
                                                   >> 142   
138   // -- Send force free flight to the callingP    143   // -- Send force free flight to the callingProcess:
139   // -----------------------------------------    144   // ------------------------------------------------
140   // -- The track has been cloned in the previ    145   // -- The track has been cloned in the previous step, it has now to be
141   // -- forced for a free flight.                 146   // -- forced for a free flight.
142   // -- This track will fly with 0.0 weight du    147   // -- This track will fly with 0.0 weight during its forced flight:
143   // -- it is to forbid the double counting wi    148   // -- it is to forbid the double counting with the force interaction track.
144   // -- Its weight is restored at the end of i    149   // -- Its weight is restored at the end of its free flight, this weight
145   // -- being its initial weight * the weight     150   // -- being its initial weight * the weight for the free flight travel,
146   // -- this last one being per process. The i    151   // -- this last one being per process. The initial weight is common, and is
147   // -- arbitrary asked to the first operation    152   // -- arbitrary asked to the first operation to take care of it.
148   if ( fCurrentTrackData->fForceCollisionState    153   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
149   {                                            << 
150     G4BOptnForceFreeFlight* operation = fFreeF << 
151     if ( callingProcess->GetWrappedProcess()-> << 
152     {                                          << 
153       // -- the initial track weight will be r << 
154       operation->ResetInitialTrackWeight(fInit << 
155       return operation;                        << 
156     }                                          << 
157     else                                       << 
158     {                                             154     {
159       return nullptr;                          << 155       G4BOptnForceFreeFlight* operation =  fFreeFlightOperations[callingProcess];
                                                   >> 156       if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
                                                   >> 157   {
                                                   >> 158     // -- the initial track weight will be restored only by the first DoIt free flight:
                                                   >> 159     operation->ResetInitialTrackWeight(fInitialTrackWeight);
                                                   >> 160     return operation;
                                                   >> 161   }
                                                   >> 162       else
                                                   >> 163   {
                                                   >> 164     return nullptr;
                                                   >> 165   }
160     }                                             166     }
161   }                                            << 167 
162                                                   168 
163   // -- Send force interaction operation to th    169   // -- Send force interaction operation to the callingProcess:
164   // -----------------------------------------    170   // ----------------------------------------------------------
165   // -- at this level, a copy of the track ent    171   // -- at this level, a copy of the track entering the volume was
166   // -- generated (borned) earlier. This copy     172   // -- generated (borned) earlier. This copy will make the forced
167   // -- interaction in the volume.                173   // -- interaction in the volume.
168   if ( fCurrentTrackData->fForceCollisionState    174   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
169   {                                            << 
170     // -- Remember if this calling process is  << 
171     // -- the PostStepGPIL loop (using default << 
172     G4bool isFirstPhysGPIL = callingProcess->  << 
173                                                << 
174     // -- [*first process*] Initialize or upda << 
175     if ( isFirstPhysGPIL )                     << 
176     {                                             175     {
177       // -- first step of cloned track, initia << 176       // -- Remember if this calling process is the first of the physics wrapper in
178       if ( track->GetCurrentStepNumber() == 1  << 177       // -- the PostStepGPIL loop (using default argument of method below):
179       {                                        << 178       G4bool isFirstPhysGPIL = callingProcess-> GetIsFirstPostStepGPILInterface();
180         fSharedForceInteractionOperation->Init << 
181       }                                        << 
182       else                                     << 
183       {                                        << 
184         if ( fSharedForceInteractionOperation- << 
185         {                                      << 
186           // -- means that some other physics  << 
187           // -- has occured, need to re-initia << 
188           // -- [ Note the re-initialization i << 
189           fSharedForceInteractionOperation->In << 
190         }                                      << 
191         else                                   << 
192         {                                      << 
193           // -- means that some other non-phys << 
194           // -- but track conserves its moment << 
195           // -- forced interaction.            << 
196           // -- [ Note the update is only poss << 
197           fSharedForceInteractionOperation->Up << 
198         }                                      << 
199       }                                        << 
200     }                                          << 
201                                                   179       
202     // -- [*all processes*] Sanity check : it  << 180       // -- [*first process*] Initialize or update force interaction operation:
203     // -- out is zero, weight would be infinit << 181       if ( isFirstPhysGPIL )
204     // -- and abandon biasing.                 << 182   {
205     if ( fSharedForceInteractionOperation->Get << 183     // -- first step of cloned track, initialize the forced interaction operation:
206     {                                          << 184     if ( track->GetCurrentStepNumber() == 1 ) fSharedForceInteractionOperation->Initialize( track );
207       fCurrentTrackData->Reset();              << 185     else
208       return nullptr;                          << 186       {
209     }                                          << 187         if ( fSharedForceInteractionOperation->GetInitialMomentum() != track->GetMomentum() )
                                                   >> 188     {
                                                   >> 189       // -- means that some other physics process, not under control of the forced interaction operation,
                                                   >> 190       // -- has occured, need to re-initialize the operation as distance to boundary has changed.
                                                   >> 191       // -- [ Note the re-initialization is only possible for a Markovian law. ]
                                                   >> 192       fSharedForceInteractionOperation->Initialize( track );
                                                   >> 193     }
                                                   >> 194         else
                                                   >> 195     {
                                                   >> 196       // -- means that some other non-physics process (biasing or not, like step limit), has occured,
                                                   >> 197       // -- but track conserves its momentum direction, only need to reduced the maximum distance for
                                                   >> 198       // -- forced interaction.
                                                   >> 199       // -- [ Note the update is only possible for a Markovian law. ]
                                                   >> 200       fSharedForceInteractionOperation->UpdateForStep( track->GetStep() );
                                                   >> 201     }
                                                   >> 202       }
                                                   >> 203   }
210                                                   204       
211     // -- [* first process*] collect cross-sec << 205       // -- [*all processes*] Sanity check : it may happen in limit cases that distance to
212     // -- and winning process:                 << 206       // -- out is zero, weight would be infinite in this case: abort forced interaction
213     if ( isFirstPhysGPIL )                     << 207       // -- and abandon biasing.
214     {                                          << 208       if ( fSharedForceInteractionOperation->GetMaximumDistance() < DBL_MIN )
215       // -- collect cross-sections:            << 209   {
216       // -- ( Remember that the first of the G << 210     fCurrentTrackData->Reset();
217       // --   of these cross-sections )        << 211     return 0;
218       const G4BiasingProcessSharedData* shared << 212   }
219       for ( std::size_t i = 0 ; i < (sharedDat << 
220       {                                        << 
221         const G4BiasingProcessInterface* wrapp << 
222         G4double interactionLength = wrapperPr << 
223         // -- keep only well defined cross-sec << 
224         // -- but cases where a threhold effec << 
225         if ( interactionLength < DBL_MAX/10. ) << 
226           fSharedForceInteractionOperation->Ad << 
227       }                                        << 
228       // -- sample the shared law (interaction << 
229       if ( fSharedForceInteractionOperation->G << 
230         fSharedForceInteractionOperation->Samp << 
231     }                                          << 
232                                                   213       
233     // -- [*all processes*] Send operation for << 214       // -- [* first process*] collect cross-sections and sample force law to determine interaction length
234     G4VBiasingOperation* operationToReturn = n << 215       // -- and winning process:
235     if ( callingProcess->GetWrappedProcess()-> << 216       if ( isFirstPhysGPIL )
236       operationToReturn = fSharedForceInteract << 217   {
237     return operationToReturn;                  << 218     // -- collect cross-sections:
                                                   >> 219     // -- ( Remember that the first of the G4BiasingProcessInterface triggers the update
                                                   >> 220     // --   of these cross-sections )
                                                   >> 221     const G4BiasingProcessSharedData* sharedData = callingProcess->GetSharedData();
                                                   >> 222     for ( size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size() ; i++ )
                                                   >> 223       {
                                                   >> 224         const G4BiasingProcessInterface* wrapperProcess = ( sharedData->GetPhysicsBiasingProcessInterfaces() )[i];
                                                   >> 225         G4double interactionLength = wrapperProcess->GetWrappedProcess()->GetCurrentInteractionLength();
                                                   >> 226         // -- keep only well defined cross-sections, other processes are ignored. These are not pathological cases
                                                   >> 227         // -- but cases where a threhold effect par example (eg pair creation) may be at play. (**!**)
                                                   >> 228         if ( interactionLength < DBL_MAX/10. )
                                                   >> 229     fSharedForceInteractionOperation->AddCrossSection( wrapperProcess->GetWrappedProcess(),  1.0/interactionLength );
                                                   >> 230       }
                                                   >> 231     // -- sample the shared law (interaction length, and winning process):
                                                   >> 232     if ( fSharedForceInteractionOperation->GetNumberOfSharing() > 0 ) fSharedForceInteractionOperation->Sample();
                                                   >> 233   }
                                                   >> 234       
                                                   >> 235       // -- [*all processes*] Send operation for processes with well defined XS (see "**!**" above):
                                                   >> 236       G4VBiasingOperation* operationToReturn = nullptr;
                                                   >> 237       if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. ) operationToReturn = fSharedForceInteractionOperation;
                                                   >> 238       return operationToReturn;
                                                   >> 239 
238                                                   240 
239   } // -- end of "if ( fCurrentTrackData->fFor << 241     } // -- end of "if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )"
240                                                   242 
241                                                   243   
242   // -- other cases here: particle appearing i    244   // -- other cases here: particle appearing in the volume by some
243   // -- previous interaction : we decide to no    245   // -- previous interaction : we decide to not bias these.
244   return nullptr;                              << 246   return 0;
                                                   >> 247   
245 }                                                 248 }
246                                                   249 
247 G4VBiasingOperation* G4BOptrForceCollision::   << 250 
248 ProposeNonPhysicsBiasingOperation(const G4Trac << 251 G4VBiasingOperation* G4BOptrForceCollision::ProposeNonPhysicsBiasingOperation(const G4Track* track,
249                                   const G4Bias << 252                         const G4BiasingProcessInterface* /* callingProcess */)
250 {                                                 253 {
251   if ( track->GetDefinition() != fParticleToBi    254   if ( track->GetDefinition() != fParticleToBias ) return nullptr;
252                                                   255   
253   // -- Apply biasing scheme only to tracks en    256   // -- Apply biasing scheme only to tracks entering the volume.
254   // -- A "cloning" is done:                      257   // -- A "cloning" is done:
255   // --  - the primary will be forced flight u    258   // --  - the primary will be forced flight under a zero weight up to volume exit,
256   // --    where the weight will be restored w    259   // --    where the weight will be restored with proper weight for free flight
257   // --  - the clone will be forced to interac    260   // --  - the clone will be forced to interact in the volume.
258   if ( track->GetStep()->GetPreStepPoint()->Ge    261   if ( track->GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary ) // -- §§§ extent to case of a track shoot on the boundary ?
259   {                                            << 262     {
260     // -- check that track is free of undergoi << 263       // -- check that track is free of undergoing biasing scheme ( no biasing data, or no active active )
261     // -- Get possible track data:             << 264       // -- Get possible track data:
262     fCurrentTrackData = (G4BOptrForceCollision << 265       fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
263     if ( fCurrentTrackData != nullptr )        << 266       if ( fCurrentTrackData != nullptr )
264     {                                          << 267   {
265       if ( fCurrentTrackData->IsFreeFromBiasin << 268     if ( fCurrentTrackData->IsFreeFromBiasing() )
266       {                                        << 269       {
267         // -- takes "ownership" (some track da << 270         // -- takes "ownership" (some track data created before, left free, reuse it):
268         fCurrentTrackData->fForceCollisionOper << 271         fCurrentTrackData->fForceCollisionOperator = this ;
269       }                                        << 272       }
                                                   >> 273     else
                                                   >> 274       {
                                                   >> 275         // §§§ Would something be really wrong in this case ? Could this be that a process made a zero step ?
                                                   >> 276       }
                                                   >> 277   }
270       else                                        278       else
271       {                                        << 279   {
272         // Would something be really wrong in  << 280     fCurrentTrackData = new G4BOptrForceCollisionTrackData( this );
273         // Could this be that a process made a << 281     track->SetAuxiliaryTrackInformation(fForceCollisionModelID, fCurrentTrackData);
274       }                                        << 282   }
275     }                                          << 283       fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeCloned;
276     else                                       << 284       fInitialTrackWeight = track->GetWeight();
277     {                                          << 285       fCloningOperation->SetCloneWeights(0.0, fInitialTrackWeight);
278       fCurrentTrackData = new G4BOptrForceColl << 286       return fCloningOperation;
279       track->SetAuxiliaryTrackInformation(fFor << 287     }
280     }                                          << 
281     fCurrentTrackData->fForceCollisionState =  << 
282     fInitialTrackWeight = track->GetWeight();  << 
283     fCloningOperation->SetCloneWeights(0.0, fI << 
284                                                << 
285     return fCloningOperation;                  << 
286   }                                            << 
287                                                   288   
                                                   >> 289   // -- 
288   return nullptr;                                 290   return nullptr;
289 }                                                 291 }
290                                                   292 
291 G4VBiasingOperation* G4BOptrForceCollision::   << 293 
292 ProposeFinalStateBiasingOperation(const G4Trac << 294 G4VBiasingOperation* G4BOptrForceCollision::ProposeFinalStateBiasingOperation(const G4Track*, const G4BiasingProcessInterface* callingProcess)
293                                   const G4Bias << 
294 {                                                 295 {
295   // -- Propose at final state generation the     296   // -- Propose at final state generation the same operation which was proposed at GPIL level,
296   // -- (which is either the force free flight    297   // -- (which is either the force free flight or the force interaction operation).
297   // -- count on the process interface to coll    298   // -- count on the process interface to collect this operation:
298   return callingProcess->GetCurrentOccurenceBi    299   return callingProcess->GetCurrentOccurenceBiasingOperation();
299 }                                                 300 }
300                                                   301 
                                                   >> 302 
301 void G4BOptrForceCollision::StartTracking( con    303 void G4BOptrForceCollision::StartTracking( const G4Track* track )
302 {                                                 304 {
303   fCurrentTrack     = track;                      305   fCurrentTrack     = track;
304   fCurrentTrackData = nullptr;                    306   fCurrentTrackData = nullptr; 
305 }                                                 307 }
306                                                   308 
                                                   >> 309 
307 void G4BOptrForceCollision::EndTracking()         310 void G4BOptrForceCollision::EndTracking()
308 {                                                 311 {
309   // -- check for consistency, operator should    312   // -- check for consistency, operator should have cleaned the track:
310   if ( fCurrentTrackData != nullptr )             313   if ( fCurrentTrackData != nullptr )
311   {                                            << 
312     if ( !fCurrentTrackData->IsFreeFromBiasing << 
313     {                                             314     {
314       if ( (fCurrentTrack->GetTrackStatus() == << 315       if ( !fCurrentTrackData->IsFreeFromBiasing() )
315         || (fCurrentTrack->GetTrackStatus() == << 316   {
316       {                                        << 317     if ( (fCurrentTrack->GetTrackStatus() == fStopAndKill) || (fCurrentTrack->GetTrackStatus() == fKillTrackAndSecondaries) )
317         G4ExceptionDescription ed;             << 318       {
318   ed << "Current track deleted while under bia << 319         G4ExceptionDescription ed;
319            << GetName() << ". Will result in i << 320         ed << "Current track deleted while under biasing by " << GetName() << ". Will result in inconsistencies.";
320         G4Exception(" G4BOptrForceCollision::E << 321         G4Exception(" G4BOptrForceCollision::EndTracking()",
321                     "BIAS.GEN.18", JustWarning << 322         "BIAS.GEN.18",
322       }                                        << 323         JustWarning,
323     }                                          << 324         ed);
324   }                                            << 325       }
325 }                                              << 326   }
326                                                << 327     } 
327 void G4BOptrForceCollision::                   << 328 }
328 OperationApplied( const G4BiasingProcessInterf << 329 
329                         G4BiasingAppliedCase B << 330 
330                         G4VBiasingOperation* o << 331 void G4BOptrForceCollision::OperationApplied( const G4BiasingProcessInterface*   callingProcess,
331                   const G4VParticleChange* )   << 332                 G4BiasingAppliedCase                          BAC,
                                                   >> 333                 G4VBiasingOperation*             operationApplied,
                                                   >> 334                 const G4VParticleChange*                          )
332 {                                                 335 {
                                                   >> 336   
333   if ( fCurrentTrackData == nullptr )             337   if ( fCurrentTrackData == nullptr )
334   {                                            << 
335     if ( BAC != BAC_None )                     << 
336     {                                             338     {
337       G4ExceptionDescription ed;               << 339       if ( BAC != BAC_None )
338       ed << " Internal inconsistency : please  << 340   {
339       G4Exception(" G4BOptrForceCollision::Ope << 341     G4ExceptionDescription ed;
340                   "BIAS.GEN.20.1", JustWarning << 342     ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 343     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 344           "BIAS.GEN.20.1",
                                                   >> 345           JustWarning,
                                                   >> 346           ed); 
                                                   >> 347   }
                                                   >> 348       return;
341     }                                             349     }
342     return;                                    << 
343   }                                            << 
344                                                   350   
345   if ( fCurrentTrackData->fForceCollisionState << 351   if      ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeCloned )
346   {                                            << 352     {
347     fCurrentTrackData->fForceCollisionState =  << 353       fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeFreeFlight;
348     auto cloneData = new G4BOptrForceCollision << 354       auto cloneData                  = new G4BOptrForceCollisionTrackData( this );
349     cloneData->fForceCollisionState = ForceCol << 355       cloneData->fForceCollisionState = ForceCollisionState::toBeForced;
350     fCloningOperation->GetCloneTrack()->SetAux << 356       fCloningOperation->GetCloneTrack()->SetAuxiliaryTrackInformation(fForceCollisionModelID, cloneData);
351   }                                            << 357     }
352   else if ( fCurrentTrackData->fForceCollision    358   else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
353   {                                            << 
354     if ( fFreeFlightOperations[callingProcess] << 
355       fCurrentTrackData->Reset(); // -- off bi << 
356   }                                            << 
357   else if ( fCurrentTrackData->fForceCollision << 
358   {                                            << 
359     if ( operationApplied != fSharedForceInter << 
360     {                                             359     {
361       G4ExceptionDescription ed;               << 360       if ( fFreeFlightOperations[callingProcess]->OperationComplete() ) fCurrentTrackData->Reset(); // -- off biasing for this track
362       ed << " Internal inconsistency : please  << 361     }
363       G4Exception(" G4BOptrForceCollision::Ope << 362   else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
364                   "BIAS.GEN.20.2", JustWarning << 
365   }                                            << 
366     if ( fSharedForceInteractionOperation->Get << 
367     {                                             363     {
368       if ( operationApplied != fSharedForceInt    364       if ( operationApplied != fSharedForceInteractionOperation )
369       {                                        << 365   {
370         G4ExceptionDescription ed;             << 366     G4ExceptionDescription ed;
371         ed << " Internal inconsistency : pleas << 367     ed << " Internal inconsistency : please submit bug report. " << G4endl;
372         G4Exception(" G4BOptrForceCollision::O << 368     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
373                     "BIAS.GEN.20.3", JustWarni << 369           "BIAS.GEN.20.2",
374       }                                        << 370           JustWarning,
                                                   >> 371           ed); 
                                                   >> 372   }
                                                   >> 373       if ( fSharedForceInteractionOperation->GetInteractionOccured() )
                                                   >> 374   {
                                                   >> 375     if ( operationApplied != fSharedForceInteractionOperation )
                                                   >> 376       {
                                                   >> 377         G4ExceptionDescription ed;
                                                   >> 378         ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 379         G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 380         "BIAS.GEN.20.3",
                                                   >> 381         JustWarning,
                                                   >> 382         ed); 
                                                   >> 383       } 
                                                   >> 384   }
375     }                                             385     }
376   }                                            << 
377   else                                            386   else
378   {                                            << 
379     if ( fCurrentTrackData->fForceCollisionSta << 
380     {                                             387     {
381       G4ExceptionDescription ed;               << 388       if ( fCurrentTrackData->fForceCollisionState != ForceCollisionState::free )
382       ed << " Internal inconsistency : please  << 389   {
383       G4Exception(" G4BOptrForceCollision::Ope << 390     G4ExceptionDescription ed;
384                   "BIAS.GEN.20.4", JustWarning << 391     ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 392     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 393           "BIAS.GEN.20.4",
                                                   >> 394           JustWarning,
                                                   >> 395           ed); 
                                                   >> 396   }
385     }                                             397     }
386   }                                            << 
387 }                                                 398 }
388                                                   399 
389 void  G4BOptrForceCollision::                  << 400 
390 OperationApplied( const G4BiasingProcessInterf << 401 void  G4BOptrForceCollision::OperationApplied( const G4BiasingProcessInterface*        /*callingProcess*/, G4BiasingAppliedCase                  /*biasingCase*/,
391                         G4BiasingAppliedCase / << 402                  G4VBiasingOperation*         /*occurenceOperationApplied*/, G4double             /*weightForOccurenceInteraction*/,
392                         G4VBiasingOperation* / << 403                  G4VBiasingOperation*            finalStateOperationApplied, const G4VParticleChange*    /*particleChangeProduced*/ )
393                         G4double             / << 
394                         G4VBiasingOperation* f << 
395                   const G4VParticleChange*   / << 
396 {                                                 404 {
                                                   >> 405   
397   if ( fCurrentTrackData->fForceCollisionState    406   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
398   {                                            << 407     {
399     if ( finalStateOperationApplied != fShared << 408       if ( finalStateOperationApplied != fSharedForceInteractionOperation )
                                                   >> 409   {
                                                   >> 410     G4ExceptionDescription ed;
                                                   >> 411     ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 412     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 413           "BIAS.GEN.20.5",
                                                   >> 414           JustWarning,
                                                   >> 415           ed); 
                                                   >> 416   }
                                                   >> 417       if ( fSharedForceInteractionOperation->GetInteractionOccured() ) fCurrentTrackData->Reset(); // -- off biasing for this track
                                                   >> 418     }
                                                   >> 419   else
400     {                                             420     {
401       G4ExceptionDescription ed;                  421       G4ExceptionDescription ed;
402       ed << " Internal inconsistency : please     422       ed << " Internal inconsistency : please submit bug report. " << G4endl;
403       G4Exception(" G4BOptrForceCollision::Ope    423       G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
404                   "BIAS.GEN.20.5", JustWarning << 424       "BIAS.GEN.20.6",
                                                   >> 425       JustWarning,
                                                   >> 426       ed);   
405     }                                             427     }
406     if ( fSharedForceInteractionOperation->Get << 428   
407       fCurrentTrackData->Reset(); // -- off bi << 
408   }                                            << 
409   else                                         << 
410   {                                            << 
411     G4ExceptionDescription ed;                 << 
412     ed << " Internal inconsistency : please su << 
413     G4Exception(" G4BOptrForceCollision::Opera << 
414                 "BIAS.GEN.20.6", JustWarning,  << 
415   }                                            << 
416 }                                                 429 }
                                                   >> 430 
417                                                   431