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 10.3)


  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(-1),
                                                   >>  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(-1),
                                                   >>  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 {
                                                   >>  96   // -- Create ID for force collision:
                                                   >>  97   fForceCollisionModelID = G4PhysicsModelCatalog::Register("GenBiasForceCollision");
                                                   >>  98 
 92   // -- build free flight operations:              99   // -- build free flight operations:
 93   ConfigureForWorker();                           100   ConfigureForWorker();
 94 }                                                 101 }
 95                                                   102 
                                                   >> 103 
 96 void G4BOptrForceCollision::ConfigureForWorker    104 void G4BOptrForceCollision::ConfigureForWorker()
 97 {                                                 105 {
 98   // -- start by remembering processes under b << 106   // -- start by remembering processes under biasing, and create needed biasing operations:
 99   //    and create needed biasing operations:  << 
100   if ( fSetup )                                   107   if ( fSetup )
101   {                                            << 108     {
102     const G4ProcessManager* processManager = f << 109       // -- get back ID created in master thread in case of MT (or reget just created ID in sequential mode):
103     const G4BiasingProcessSharedData* interfac << 110       fForceCollisionModelID = G4PhysicsModelCatalog::Register("GenBiasForceCollision");
104     if ( interfaceProcessSharedData ) // -- sh << 111 
105                                 // -- to a vol << 112       const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
106     {                                          << 113       const G4BiasingProcessSharedData* interfaceProcessSharedData = G4BiasingProcessInterface::GetSharedData( processManager );
107       for ( std::size_t i = 0 ; i < (interface << 114       if ( interfaceProcessSharedData ) // -- sharedData tested, as is can happen a user attaches an operator
108       {                                        << 115                                   // -- to a volume but without defining BiasingProcessInterface processes.
109         const G4BiasingProcessInterface* wrapp << 116   {
110           (interfaceProcessSharedData->GetPhys << 117     for ( size_t i = 0 ; i < (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces()).size(); i++ )
111         const G4String& operationName = "FreeF << 118       {
112         fFreeFlightOperations[wrapperProcess]  << 119         const G4BiasingProcessInterface* wrapperProcess =
113       }                                        << 120     (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces())[i];
                                                   >> 121         G4String operationName = "FreeFlight-"+wrapperProcess->GetWrappedProcess()->GetProcessName();
                                                   >> 122         fFreeFlightOperations[wrapperProcess] = new G4BOptnForceFreeFlight(operationName);
                                                   >> 123       }
                                                   >> 124   }
                                                   >> 125       fSetup = false;
114     }                                             126     }
115     fSetup = false;                            << 
116   }                                            << 
117 }                                                 127 }
118                                                   128 
                                                   >> 129 
119 void G4BOptrForceCollision::StartRun()            130 void G4BOptrForceCollision::StartRun()
120 {                                                 131 {
121 }                                                 132 }
122                                                   133 
123 G4VBiasingOperation*                           << 134 
124 G4BOptrForceCollision::ProposeOccurenceBiasing << 135 G4VBiasingOperation* G4BOptrForceCollision::ProposeOccurenceBiasingOperation(const G4Track* track, const G4BiasingProcessInterface* callingProcess)
125                                const G4Biasing << 
126 {                                                 136 {
127   // -- does nothing if particle is not of req    137   // -- does nothing if particle is not of requested type:
128   if ( track->GetDefinition() != fParticleToBi << 138   if ( track->GetDefinition() != fParticleToBias ) return 0;
129                                                   139 
130   // -- trying to get auxiliary track data...     140   // -- trying to get auxiliary track data...
131   if ( fCurrentTrackData == nullptr )             141   if ( fCurrentTrackData == nullptr )
132   {                                            << 142     {
133     // ... and if the track has no aux. track  << 143       // ... 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 << 144       fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
135     if ( fCurrentTrackData == nullptr ) return << 145       if ( fCurrentTrackData == nullptr ) return nullptr;
136   }                                            << 146     }
137                                                   147 
                                                   >> 148   
138   // -- Send force free flight to the callingP    149   // -- Send force free flight to the callingProcess:
139   // -----------------------------------------    150   // ------------------------------------------------
140   // -- The track has been cloned in the previ    151   // -- The track has been cloned in the previous step, it has now to be
141   // -- forced for a free flight.                 152   // -- forced for a free flight.
142   // -- This track will fly with 0.0 weight du    153   // -- This track will fly with 0.0 weight during its forced flight:
143   // -- it is to forbid the double counting wi    154   // -- it is to forbid the double counting with the force interaction track.
144   // -- Its weight is restored at the end of i    155   // -- Its weight is restored at the end of its free flight, this weight
145   // -- being its initial weight * the weight     156   // -- being its initial weight * the weight for the free flight travel,
146   // -- this last one being per process. The i    157   // -- this last one being per process. The initial weight is common, and is
147   // -- arbitrary asked to the first operation    158   // -- arbitrary asked to the first operation to take care of it.
148   if ( fCurrentTrackData->fForceCollisionState    159   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     {                                             160     {
159       return nullptr;                          << 161       G4BOptnForceFreeFlight* operation =  fFreeFlightOperations[callingProcess];
                                                   >> 162       if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
                                                   >> 163   {
                                                   >> 164     // -- the initial track weight will be restored only by the first DoIt free flight:
                                                   >> 165     operation->ResetInitialTrackWeight(fInitialTrackWeight);
                                                   >> 166     return operation;
                                                   >> 167   }
                                                   >> 168       else
                                                   >> 169   {
                                                   >> 170     return nullptr;
                                                   >> 171   }
160     }                                             172     }
161   }                                            << 173 
162                                                   174 
163   // -- Send force interaction operation to th    175   // -- Send force interaction operation to the callingProcess:
164   // -----------------------------------------    176   // ----------------------------------------------------------
165   // -- at this level, a copy of the track ent    177   // -- at this level, a copy of the track entering the volume was
166   // -- generated (borned) earlier. This copy     178   // -- generated (borned) earlier. This copy will make the forced
167   // -- interaction in the volume.                179   // -- interaction in the volume.
168   if ( fCurrentTrackData->fForceCollisionState    180   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     {                                             181     {
177       // -- first step of cloned track, initia << 182       // -- Remember if this calling process is the first of the physics wrapper in
178       if ( track->GetCurrentStepNumber() == 1  << 183       // -- the PostStepGPIL loop (using default argument of method below):
179       {                                        << 184       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                                                   185       
202     // -- [*all processes*] Sanity check : it  << 186       // -- [*first process*] Initialize or update force interaction operation:
203     // -- out is zero, weight would be infinit << 187       if ( isFirstPhysGPIL )
204     // -- and abandon biasing.                 << 188   {
205     if ( fSharedForceInteractionOperation->Get << 189     // -- first step of cloned track, initialize the forced interaction operation:
206     {                                          << 190     if ( track->GetCurrentStepNumber() == 1 ) fSharedForceInteractionOperation->Initialize( track );
207       fCurrentTrackData->Reset();              << 191     else
208       return nullptr;                          << 192       {
209     }                                          << 193         if ( fSharedForceInteractionOperation->GetInitialMomentum() != track->GetMomentum() )
                                                   >> 194     {
                                                   >> 195       // -- means that some other physics process, not under control of the forced interaction operation,
                                                   >> 196       // -- has occured, need to re-initialize the operation as distance to boundary has changed.
                                                   >> 197       // -- [ Note the re-initialization is only possible for a Markovian law. ]
                                                   >> 198       fSharedForceInteractionOperation->Initialize( track );
                                                   >> 199     }
                                                   >> 200         else
                                                   >> 201     {
                                                   >> 202       // -- means that some other non-physics process (biasing or not, like step limit), has occured,
                                                   >> 203       // -- but track conserves its momentum direction, only need to reduced the maximum distance for
                                                   >> 204       // -- forced interaction.
                                                   >> 205       // -- [ Note the update is only possible for a Markovian law. ]
                                                   >> 206       fSharedForceInteractionOperation->UpdateForStep( track->GetStep() );
                                                   >> 207     }
                                                   >> 208       }
                                                   >> 209   }
210                                                   210       
211     // -- [* first process*] collect cross-sec << 211       // -- [*all processes*] Sanity check : it may happen in limit cases that distance to
212     // -- and winning process:                 << 212       // -- out is zero, weight would be infinite in this case: abort forced interaction
213     if ( isFirstPhysGPIL )                     << 213       // -- and abandon biasing.
214     {                                          << 214       if ( fSharedForceInteractionOperation->GetMaximumDistance() < DBL_MIN )
215       // -- collect cross-sections:            << 215   {
216       // -- ( Remember that the first of the G << 216     fCurrentTrackData->Reset();
217       // --   of these cross-sections )        << 217     return 0;
218       const G4BiasingProcessSharedData* shared << 218   }
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                                                   219       
233     // -- [*all processes*] Send operation for << 220       // -- [* first process*] collect cross-sections and sample force law to determine interaction length
234     G4VBiasingOperation* operationToReturn = n << 221       // -- and winning process:
235     if ( callingProcess->GetWrappedProcess()-> << 222       if ( isFirstPhysGPIL )
236       operationToReturn = fSharedForceInteract << 223   {
237     return operationToReturn;                  << 224     // -- collect cross-sections:
                                                   >> 225     // -- ( Remember that the first of the G4BiasingProcessInterface triggers the update
                                                   >> 226     // --   of these cross-sections )
                                                   >> 227     const G4BiasingProcessSharedData* sharedData = callingProcess->GetSharedData();
                                                   >> 228     for ( size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size() ; i++ )
                                                   >> 229       {
                                                   >> 230         const G4BiasingProcessInterface* wrapperProcess = ( sharedData->GetPhysicsBiasingProcessInterfaces() )[i];
                                                   >> 231         G4double interactionLength = wrapperProcess->GetWrappedProcess()->GetCurrentInteractionLength();
                                                   >> 232         // -- keep only well defined cross-sections, other processes are ignored. These are not pathological cases
                                                   >> 233         // -- but cases where a threhold effect par example (eg pair creation) may be at play. (**!**)
                                                   >> 234         if ( interactionLength < DBL_MAX/10. )
                                                   >> 235     fSharedForceInteractionOperation->AddCrossSection( wrapperProcess->GetWrappedProcess(),  1.0/interactionLength );
                                                   >> 236       }
                                                   >> 237     // -- sample the shared law (interaction length, and winning process):
                                                   >> 238     if ( fSharedForceInteractionOperation->GetNumberOfSharing() > 0 ) fSharedForceInteractionOperation->Sample();
                                                   >> 239   }
                                                   >> 240       
                                                   >> 241       // -- [*all processes*] Send operation for processes with well defined XS (see "**!**" above):
                                                   >> 242       G4VBiasingOperation* operationToReturn = nullptr;
                                                   >> 243       if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. ) operationToReturn = fSharedForceInteractionOperation;
                                                   >> 244       return operationToReturn;
                                                   >> 245 
238                                                   246 
239   } // -- end of "if ( fCurrentTrackData->fFor << 247     } // -- end of "if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )"
240                                                   248 
241                                                   249   
242   // -- other cases here: particle appearing i    250   // -- other cases here: particle appearing in the volume by some
243   // -- previous interaction : we decide to no    251   // -- previous interaction : we decide to not bias these.
244   return nullptr;                              << 252   return 0;
                                                   >> 253   
245 }                                                 254 }
246                                                   255 
247 G4VBiasingOperation* G4BOptrForceCollision::   << 256 
248 ProposeNonPhysicsBiasingOperation(const G4Trac << 257 G4VBiasingOperation* G4BOptrForceCollision::ProposeNonPhysicsBiasingOperation(const G4Track* track,
249                                   const G4Bias << 258                         const G4BiasingProcessInterface* /* callingProcess */)
250 {                                                 259 {
251   if ( track->GetDefinition() != fParticleToBi    260   if ( track->GetDefinition() != fParticleToBias ) return nullptr;
252                                                   261   
253   // -- Apply biasing scheme only to tracks en    262   // -- Apply biasing scheme only to tracks entering the volume.
254   // -- A "cloning" is done:                      263   // -- A "cloning" is done:
255   // --  - the primary will be forced flight u    264   // --  - the primary will be forced flight under a zero weight up to volume exit,
256   // --    where the weight will be restored w    265   // --    where the weight will be restored with proper weight for free flight
257   // --  - the clone will be forced to interac    266   // --  - the clone will be forced to interact in the volume.
258   if ( track->GetStep()->GetPreStepPoint()->Ge    267   if ( track->GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary ) // -- §§§ extent to case of a track shoot on the boundary ?
259   {                                            << 268     {
260     // -- check that track is free of undergoi << 269       // -- check that track is free of undergoing biasing scheme ( no biasing data, or no active active )
261     // -- Get possible track data:             << 270       // -- Get possible track data:
262     fCurrentTrackData = (G4BOptrForceCollision << 271       fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
263     if ( fCurrentTrackData != nullptr )        << 272       if ( fCurrentTrackData != nullptr )
264     {                                          << 273   {
265       if ( fCurrentTrackData->IsFreeFromBiasin << 274     if ( fCurrentTrackData->IsFreeFromBiasing() )
266       {                                        << 275       {
267         // -- takes "ownership" (some track da << 276         // -- takes "ownership" (some track data created before, left free, reuse it):
268         fCurrentTrackData->fForceCollisionOper << 277         fCurrentTrackData->fForceCollisionOperator = this ;
269       }                                        << 278       }
                                                   >> 279     else
                                                   >> 280       {
                                                   >> 281         // §§§ Would something be really wrong in this case ? Could this be that a process made a zero step ?
                                                   >> 282       }
                                                   >> 283   }
270       else                                        284       else
271       {                                        << 285   {
272         // Would something be really wrong in  << 286     fCurrentTrackData = new G4BOptrForceCollisionTrackData( this );
273         // Could this be that a process made a << 287     track->SetAuxiliaryTrackInformation(fForceCollisionModelID, fCurrentTrackData);
274       }                                        << 288   }
275     }                                          << 289       fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeCloned;
276     else                                       << 290       fInitialTrackWeight = track->GetWeight();
277     {                                          << 291       fCloningOperation->SetCloneWeights(0.0, fInitialTrackWeight);
278       fCurrentTrackData = new G4BOptrForceColl << 292       return fCloningOperation;
279       track->SetAuxiliaryTrackInformation(fFor << 293     }
280     }                                          << 
281     fCurrentTrackData->fForceCollisionState =  << 
282     fInitialTrackWeight = track->GetWeight();  << 
283     fCloningOperation->SetCloneWeights(0.0, fI << 
284                                                << 
285     return fCloningOperation;                  << 
286   }                                            << 
287                                                   294   
                                                   >> 295   // -- 
288   return nullptr;                                 296   return nullptr;
289 }                                                 297 }
290                                                   298 
291 G4VBiasingOperation* G4BOptrForceCollision::   << 299 
292 ProposeFinalStateBiasingOperation(const G4Trac << 300 G4VBiasingOperation* G4BOptrForceCollision::ProposeFinalStateBiasingOperation(const G4Track*, const G4BiasingProcessInterface* callingProcess)
293                                   const G4Bias << 
294 {                                                 301 {
295   // -- Propose at final state generation the     302   // -- Propose at final state generation the same operation which was proposed at GPIL level,
296   // -- (which is either the force free flight    303   // -- (which is either the force free flight or the force interaction operation).
297   // -- count on the process interface to coll    304   // -- count on the process interface to collect this operation:
298   return callingProcess->GetCurrentOccurenceBi    305   return callingProcess->GetCurrentOccurenceBiasingOperation();
299 }                                                 306 }
300                                                   307 
                                                   >> 308 
301 void G4BOptrForceCollision::StartTracking( con    309 void G4BOptrForceCollision::StartTracking( const G4Track* track )
302 {                                                 310 {
303   fCurrentTrack     = track;                      311   fCurrentTrack     = track;
304   fCurrentTrackData = nullptr;                    312   fCurrentTrackData = nullptr; 
305 }                                                 313 }
306                                                   314 
                                                   >> 315 
307 void G4BOptrForceCollision::EndTracking()         316 void G4BOptrForceCollision::EndTracking()
308 {                                                 317 {
309   // -- check for consistency, operator should    318   // -- check for consistency, operator should have cleaned the track:
310   if ( fCurrentTrackData != nullptr )             319   if ( fCurrentTrackData != nullptr )
311   {                                            << 
312     if ( !fCurrentTrackData->IsFreeFromBiasing << 
313     {                                             320     {
314       if ( (fCurrentTrack->GetTrackStatus() == << 321       if ( !fCurrentTrackData->IsFreeFromBiasing() )
315         || (fCurrentTrack->GetTrackStatus() == << 322   {
316       {                                        << 323     if ( (fCurrentTrack->GetTrackStatus() == fStopAndKill) || (fCurrentTrack->GetTrackStatus() == fKillTrackAndSecondaries) )
317         G4ExceptionDescription ed;             << 324       {
318   ed << "Current track deleted while under bia << 325         G4ExceptionDescription ed;
319            << GetName() << ". Will result in i << 326         ed << "Current track deleted while under biasing by " << GetName() << ". Will result in inconsistencies.";
320         G4Exception(" G4BOptrForceCollision::E << 327         G4Exception(" G4BOptrForceCollision::EndTracking()",
321                     "BIAS.GEN.18", JustWarning << 328         "BIAS.GEN.18",
322       }                                        << 329         JustWarning,
323     }                                          << 330         ed);
324   }                                            << 331       }
325 }                                              << 332   }
326                                                << 333     } 
327 void G4BOptrForceCollision::                   << 334 }
328 OperationApplied( const G4BiasingProcessInterf << 335 
329                         G4BiasingAppliedCase B << 336 
330                         G4VBiasingOperation* o << 337 void G4BOptrForceCollision::OperationApplied( const G4BiasingProcessInterface*   callingProcess,
331                   const G4VParticleChange* )   << 338                 G4BiasingAppliedCase                          BAC,
                                                   >> 339                 G4VBiasingOperation*             operationApplied,
                                                   >> 340                 const G4VParticleChange*                          )
332 {                                                 341 {
                                                   >> 342   
333   if ( fCurrentTrackData == nullptr )             343   if ( fCurrentTrackData == nullptr )
334   {                                            << 
335     if ( BAC != BAC_None )                     << 
336     {                                             344     {
337       G4ExceptionDescription ed;               << 345       if ( BAC != BAC_None )
338       ed << " Internal inconsistency : please  << 346   {
339       G4Exception(" G4BOptrForceCollision::Ope << 347     G4ExceptionDescription ed;
340                   "BIAS.GEN.20.1", JustWarning << 348     ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 349     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 350           "BIAS.GEN.20.1",
                                                   >> 351           JustWarning,
                                                   >> 352           ed); 
                                                   >> 353   }
                                                   >> 354       return;
341     }                                             355     }
342     return;                                    << 
343   }                                            << 
344                                                   356   
345   if ( fCurrentTrackData->fForceCollisionState << 357   if      ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeCloned )
346   {                                            << 358     {
347     fCurrentTrackData->fForceCollisionState =  << 359       fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeFreeFlight;
348     auto cloneData = new G4BOptrForceCollision << 360       auto cloneData                  = new G4BOptrForceCollisionTrackData( this );
349     cloneData->fForceCollisionState = ForceCol << 361       cloneData->fForceCollisionState = ForceCollisionState::toBeForced;
350     fCloningOperation->GetCloneTrack()->SetAux << 362       fCloningOperation->GetCloneTrack()->SetAuxiliaryTrackInformation(fForceCollisionModelID, cloneData);
351   }                                            << 363     }
352   else if ( fCurrentTrackData->fForceCollision    364   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     {                                             365     {
361       G4ExceptionDescription ed;               << 366       if ( fFreeFlightOperations[callingProcess]->OperationComplete() ) fCurrentTrackData->Reset(); // -- off biasing for this track
362       ed << " Internal inconsistency : please  << 367     }
363       G4Exception(" G4BOptrForceCollision::Ope << 368   else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
364                   "BIAS.GEN.20.2", JustWarning << 
365   }                                            << 
366     if ( fSharedForceInteractionOperation->Get << 
367     {                                             369     {
368       if ( operationApplied != fSharedForceInt    370       if ( operationApplied != fSharedForceInteractionOperation )
369       {                                        << 371   {
370         G4ExceptionDescription ed;             << 372     G4ExceptionDescription ed;
371         ed << " Internal inconsistency : pleas << 373     ed << " Internal inconsistency : please submit bug report. " << G4endl;
372         G4Exception(" G4BOptrForceCollision::O << 374     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
373                     "BIAS.GEN.20.3", JustWarni << 375           "BIAS.GEN.20.2",
374       }                                        << 376           JustWarning,
                                                   >> 377           ed); 
                                                   >> 378   }
                                                   >> 379       if ( fSharedForceInteractionOperation->GetInteractionOccured() )
                                                   >> 380   {
                                                   >> 381     if ( operationApplied != fSharedForceInteractionOperation )
                                                   >> 382       {
                                                   >> 383         G4ExceptionDescription ed;
                                                   >> 384         ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 385         G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 386         "BIAS.GEN.20.3",
                                                   >> 387         JustWarning,
                                                   >> 388         ed); 
                                                   >> 389       } 
                                                   >> 390   }
375     }                                             391     }
376   }                                            << 
377   else                                            392   else
378   {                                            << 
379     if ( fCurrentTrackData->fForceCollisionSta << 
380     {                                             393     {
381       G4ExceptionDescription ed;               << 394       if ( fCurrentTrackData->fForceCollisionState != ForceCollisionState::free )
382       ed << " Internal inconsistency : please  << 395   {
383       G4Exception(" G4BOptrForceCollision::Ope << 396     G4ExceptionDescription ed;
384                   "BIAS.GEN.20.4", JustWarning << 397     ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 398     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 399           "BIAS.GEN.20.4",
                                                   >> 400           JustWarning,
                                                   >> 401           ed); 
                                                   >> 402   }
385     }                                             403     }
386   }                                            << 
387 }                                                 404 }
388                                                   405 
389 void  G4BOptrForceCollision::                  << 406 
390 OperationApplied( const G4BiasingProcessInterf << 407 void  G4BOptrForceCollision::OperationApplied( const G4BiasingProcessInterface*        /*callingProcess*/, G4BiasingAppliedCase                  /*biasingCase*/,
391                         G4BiasingAppliedCase / << 408                  G4VBiasingOperation*         /*occurenceOperationApplied*/, G4double             /*weightForOccurenceInteraction*/,
392                         G4VBiasingOperation* / << 409                  G4VBiasingOperation*            finalStateOperationApplied, const G4VParticleChange*    /*particleChangeProduced*/ )
393                         G4double             / << 
394                         G4VBiasingOperation* f << 
395                   const G4VParticleChange*   / << 
396 {                                                 410 {
                                                   >> 411   
397   if ( fCurrentTrackData->fForceCollisionState    412   if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
398   {                                            << 413     {
399     if ( finalStateOperationApplied != fShared << 414       if ( finalStateOperationApplied != fSharedForceInteractionOperation )
                                                   >> 415   {
                                                   >> 416     G4ExceptionDescription ed;
                                                   >> 417     ed << " Internal inconsistency : please submit bug report. " << G4endl;
                                                   >> 418     G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
                                                   >> 419           "BIAS.GEN.20.5",
                                                   >> 420           JustWarning,
                                                   >> 421           ed); 
                                                   >> 422   }
                                                   >> 423       if ( fSharedForceInteractionOperation->GetInteractionOccured() ) fCurrentTrackData->Reset(); // -- off biasing for this track
                                                   >> 424     }
                                                   >> 425   else
400     {                                             426     {
401       G4ExceptionDescription ed;                  427       G4ExceptionDescription ed;
402       ed << " Internal inconsistency : please     428       ed << " Internal inconsistency : please submit bug report. " << G4endl;
403       G4Exception(" G4BOptrForceCollision::Ope    429       G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
404                   "BIAS.GEN.20.5", JustWarning << 430       "BIAS.GEN.20.6",
                                                   >> 431       JustWarning,
                                                   >> 432       ed);   
405     }                                             433     }
406     if ( fSharedForceInteractionOperation->Get << 434   
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 }                                                 435 }
                                                   >> 436 
417                                                   437