Geant4 Cross Reference |
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