Import Geant4 10.3.0 source tree
This commit is contained in:
@@ -51,36 +51,6 @@ const G4VBiasingInteractionLaw* G4BOptnForceFreeFlight::ProvideOccurenceBiasingI
|
||||
return fForceFreeFlightInteractionLaw;
|
||||
}
|
||||
|
||||
G4bool G4BOptnForceFreeFlight::DenyProcessPostStepDoIt( const G4BiasingProcessInterface*, const G4Track*, const G4Step* step, G4double& proposedWeight )
|
||||
{
|
||||
// -- force free flight always deny process to apply its doit.
|
||||
// -- if reaching boundary, track is restored with non-zero weight
|
||||
if ( fInitialTrackWeight <= DBL_MIN )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Initial track weight is null ! " << G4endl;
|
||||
G4Exception(" G4BOptnForceFreeFlight::DenyProcessPostStepDoIt(...)",
|
||||
"BIAS.GEN.05",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
if ( fCumulatedWeightChange <= DBL_MIN )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Cumulated weight is null ! " << G4endl;
|
||||
G4Exception(" G4BOptnForceFreeFlight::DenyProcessPostStepDoIt(...)",
|
||||
"BIAS.GEN.06",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
if ( step->GetPostStepPoint()->GetStepStatus() == fGeomBoundary )
|
||||
{
|
||||
if ( proposedWeight <= DBL_MIN ) proposedWeight = fCumulatedWeightChange * fInitialTrackWeight;
|
||||
else proposedWeight *= fCumulatedWeightChange;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4BOptnForceFreeFlight::ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4BiasingProcessInterface.hh"
|
||||
#include "G4ParallelGeometriesLimiterProcess.hh"
|
||||
|
||||
G4bool G4BiasingHelper::ActivatePhysicsBiasing(G4ProcessManager* pmanager,
|
||||
G4String physicsProcessToBias,
|
||||
@@ -102,3 +103,42 @@ void G4BiasingHelper::ActivateNonPhysicsBiasing(G4ProcessManager* pmanager,
|
||||
ordInActive,
|
||||
ordDefault);
|
||||
}
|
||||
|
||||
G4ParallelGeometriesLimiterProcess* G4BiasingHelper::AddLimiterProcess(G4ProcessManager* pmanager, const G4String& processName)
|
||||
{
|
||||
G4ParallelGeometriesLimiterProcess* toReturn = nullptr;
|
||||
|
||||
G4ProcessVector* processList = pmanager->GetProcessList();
|
||||
G4bool noInstance = true;
|
||||
for (G4int i = 0 ; i < processList->size() ; i++)
|
||||
{
|
||||
G4VProcess* process = (*processList)[i];
|
||||
if ( dynamic_cast< G4ParallelGeometriesLimiterProcess* >( process ) )
|
||||
{
|
||||
noInstance = false;
|
||||
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Trying to re-add a G4ParallelGeometriesLimiterProcess process to the process manager for '"<<
|
||||
pmanager->GetParticleType()->GetParticleName() << " (PDG : " << pmanager->GetParticleType()->GetPDGEncoding() << " )"
|
||||
<< " while one is already present." << G4endl;
|
||||
G4Exception("G4BiasingHelper::AddBiasingProcessLimiter(G4ProcessManager* pmanager)",
|
||||
"BIAS.GEN.28",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( noInstance )
|
||||
{
|
||||
G4ParallelGeometriesLimiterProcess* biasingLimiter = new G4ParallelGeometriesLimiterProcess(processName);
|
||||
pmanager->AddProcess ( biasingLimiter );
|
||||
pmanager->SetProcessOrderingToSecond( biasingLimiter, idxAlongStep );
|
||||
pmanager->SetProcessOrderingToLast ( biasingLimiter, idxPostStep );
|
||||
|
||||
toReturn = biasingLimiter;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
|
||||
}
|
||||
|
||||
@@ -32,13 +32,12 @@
|
||||
#include "G4InteractionLawPhysical.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4BiasingAppliedCase.hh"
|
||||
#include "G4ParallelGeometriesLimiterProcess.hh"
|
||||
|
||||
G4Cache<G4bool> G4BiasingProcessInterface::fResetInteractionLaws;// = true;
|
||||
G4Cache<G4bool> G4BiasingProcessInterface::fCommonStart;// = true;
|
||||
G4Cache<G4bool> G4BiasingProcessInterface::fCommonEnd;// = true;
|
||||
G4Cache<G4bool> G4BiasingProcessInterface::fDoCommonConfigure;
|
||||
G4MapCache< const G4ProcessManager*, G4BiasingProcessSharedData* > G4BiasingProcessInterface::fSharedDataMap;
|
||||
|
||||
|
||||
G4BiasingProcessInterface::G4BiasingProcessInterface(G4String name)
|
||||
: G4VProcess ( name ),
|
||||
@@ -139,8 +138,8 @@ G4BiasingProcessInterface::~G4BiasingProcessInterface()
|
||||
const G4BiasingProcessSharedData* G4BiasingProcessInterface::GetSharedData( const G4ProcessManager* mgr )
|
||||
{
|
||||
G4MapCache< const G4ProcessManager*,
|
||||
G4BiasingProcessSharedData* >::const_iterator itr = fSharedDataMap.Find( mgr );
|
||||
if ( itr != fSharedDataMap.End( ) )
|
||||
G4BiasingProcessSharedData* >::const_iterator itr = G4BiasingProcessSharedData::fSharedDataMap.Find( mgr );
|
||||
if ( itr != G4BiasingProcessSharedData::fSharedDataMap.End( ) )
|
||||
{
|
||||
return (*itr).second;
|
||||
}
|
||||
@@ -207,30 +206,96 @@ G4double G4BiasingProcessInterface::PostStepGetPhysicalInteractionLength( const
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition )
|
||||
{
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// -- The "biasing master" takes care for all biasing processes of update of biasing operators
|
||||
// -- and invokes all PostStepGPIL of physical wrapped processes (anticipate stepping manager
|
||||
// -- call ! ) so that all cross-sections are updated with current step, and available right
|
||||
// -- away to the biasing operator.
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------
|
||||
// -- The "biasing process master" takes care of updating the biasing operator, and for all biasing
|
||||
// -- processes it invokes the PostStepGPIL of physical wrapped processes (anticipate stepping manager
|
||||
// -- call ! ) to make all cross-sections updated with current step, and hence available before the
|
||||
// -- first call to the biasing operator.
|
||||
// ---------------------------------------------------------------------------------------------------
|
||||
if ( fIamFirstGPIL )
|
||||
{
|
||||
// -- Update previous biasing operator:
|
||||
// -- Update previous biasing operator, and assume the operator stays the same by
|
||||
// -- default and that it is not left at the beginning of this step. These
|
||||
// -- assumptions might be wrong if there is a volume change (in paralllel or
|
||||
// -- mass geometries) in what case the flags will be updated.
|
||||
fSharedData->fPreviousBiasingOperator = fSharedData->fCurrentBiasingOperator;
|
||||
// -- If new volume, get possible new biasing operator:
|
||||
// ----------------------------------------------------
|
||||
// -- [Note : bug with this first step ! Does not work if previous step was concurrently limited with geometry. Might make use of safety at last point ?]
|
||||
G4bool firstStepInVolume = ( (track.GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary) || (track.GetCurrentStepNumber() == 1) );
|
||||
fSharedData->fIsNewOperator = false;
|
||||
fSharedData->fLeavingPreviousOperator = false;
|
||||
// -- If new volume, either in mass or parallel geometries, get possible new biasing operator:
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// -- Get biasing operator in parallel geometries:
|
||||
G4bool firstStepInParallelVolume = false;
|
||||
if ( fSharedData->fParallelGeometriesLimiterProcess )
|
||||
{
|
||||
G4VBiasingOperator* newParallelOperator( nullptr );
|
||||
G4bool firstStep = ( track.GetCurrentStepNumber() == 1 );
|
||||
size_t iParallel = 0;
|
||||
for ( auto wasLimiting : fSharedData->fParallelGeometriesLimiterProcess->GetWasLimiting() )
|
||||
{
|
||||
if ( firstStep || wasLimiting )
|
||||
{
|
||||
firstStepInParallelVolume = true;
|
||||
|
||||
auto tmpParallelOperator = G4VBiasingOperator::GetBiasingOperator( (fSharedData->fParallelGeometriesLimiterProcess->GetCurrentVolumes()[iParallel])
|
||||
->GetLogicalVolume() );
|
||||
if ( newParallelOperator )
|
||||
{
|
||||
if ( tmpParallelOperator )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Several biasing operators are defined at the same place in parallel geometries ! Found:\n";
|
||||
ed << " - `" << newParallelOperator->GetName() << "' and \n";
|
||||
ed << " - `" << tmpParallelOperator->GetName() << "'.\n";
|
||||
ed << " Keeping `" << newParallelOperator->GetName() << "'. Behavior not guaranteed ! Please consider having only one operator at a place. " << G4endl;
|
||||
G4Exception(" G4BiasingProcessInterface::PostStepGetPhysicalInteractionLength(...)",
|
||||
"BIAS.GEN.30",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
}
|
||||
else newParallelOperator = tmpParallelOperator;
|
||||
}
|
||||
iParallel++;
|
||||
}
|
||||
fSharedData->fParallelGeometryOperator = newParallelOperator;
|
||||
} // -- end of " if ( fSharedData->fParallelGeometriesLimiterProcess )"
|
||||
|
||||
// -- Get biasing operator in mass geometry:
|
||||
// -- [§§ Note : bug with this first step ? Does not work if previous step was concurrently limited with geometry. Might make use of safety at last point ?]
|
||||
G4bool firstStepInVolume = ( (track.GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary) || (track.GetCurrentStepNumber() == 1) );
|
||||
// fSharedData->fIsNewOperator = false;
|
||||
// fSharedData->fLeavingPreviousOperator = false;
|
||||
if ( firstStepInVolume )
|
||||
{
|
||||
G4VBiasingOperator* newOperator = G4VBiasingOperator::GetBiasingOperator( track.GetVolume()->GetLogicalVolume() );
|
||||
fSharedData->fMassGeometryOperator = newOperator;
|
||||
if ( ( newOperator != nullptr ) && ( fSharedData->fParallelGeometryOperator != nullptr ) )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Biasing operators are defined at the same place in mass and parallel geometries ! Found:\n";
|
||||
ed << " - `" << fSharedData->fParallelGeometryOperator->GetName() << "' in parallel geometry and \n";
|
||||
ed << " - `" << newOperator->GetName() << "' in mass geometry.\n";
|
||||
ed << " Keeping `" << fSharedData->fParallelGeometryOperator->GetName() << "'. Behavior not guaranteed ! Please consider having only one operator at a place. " << G4endl;
|
||||
G4Exception(" G4BiasingProcessInterface::PostStepGetPhysicalInteractionLength(...)",
|
||||
"BIAS.GEN.31",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
}
|
||||
|
||||
// -- conclude the operator selection, giving priority to parallel geometry (as told in exception message BIAS.GEN.30):
|
||||
if ( firstStepInVolume || firstStepInParallelVolume )
|
||||
{
|
||||
G4VBiasingOperator* newOperator = fSharedData->fParallelGeometryOperator;
|
||||
if ( newOperator == nullptr ) newOperator = fSharedData->fMassGeometryOperator;
|
||||
|
||||
fSharedData->fCurrentBiasingOperator = newOperator ;
|
||||
|
||||
if ( newOperator != fSharedData->fPreviousBiasingOperator )
|
||||
{
|
||||
fSharedData->fLeavingPreviousOperator = ( fSharedData->fPreviousBiasingOperator != 0 ) ;
|
||||
fSharedData->fIsNewOperator = ( newOperator != 0 );
|
||||
fSharedData->fLeavingPreviousOperator = ( fSharedData->fPreviousBiasingOperator != nullptr ) ;
|
||||
fSharedData->fIsNewOperator = ( newOperator != nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,13 +307,14 @@ G4double G4BiasingProcessInterface::PostStepGetPhysicalInteractionLength( const
|
||||
// -- fWrappedProcessForceCondition ,
|
||||
// -- fWrappedProcessInteractionLength
|
||||
// -- updated.
|
||||
if ( fSharedData->fCurrentBiasingOperator != 0 )
|
||||
if ( fSharedData->fCurrentBiasingOperator != nullptr )
|
||||
{
|
||||
for ( size_t i = 0 ; i < (fSharedData->fPhysicsBiasingProcessInterfaces).size(); i++ )
|
||||
(fSharedData->fPhysicsBiasingProcessInterfaces)[i]->InvokeWrappedProcessPostStepGPIL( track, previousStepSize, condition );
|
||||
}
|
||||
}
|
||||
} // -- end of "if ( fIamFirstGPIL )"
|
||||
|
||||
|
||||
|
||||
// -- Remember previous operator and proposed operations, if any, and reset:
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -383,6 +449,7 @@ G4double G4BiasingProcessInterface::PostStepGetPhysicalInteractionLength( const
|
||||
G4VParticleChange* G4BiasingProcessInterface::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
|
||||
// ---------------------------------------
|
||||
// -- case outside of volume with biasing:
|
||||
// ---------------------------------------
|
||||
@@ -508,6 +575,7 @@ G4double G4BiasingProcessInterface::AlongStepGetPhysicalInteractionLen
|
||||
G4double& proposedSafety,
|
||||
G4GPILSelection* selection)
|
||||
{
|
||||
|
||||
// -- for helper methods:
|
||||
fCurrentMinimumStep = currentMinimumStep;
|
||||
fProposedSafety = proposedSafety;
|
||||
@@ -583,6 +651,7 @@ G4double G4BiasingProcessInterface::AlongStepGetPhysicalInteractionLen
|
||||
G4VParticleChange* G4BiasingProcessInterface::AlongStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
|
||||
// ---------------------------------------
|
||||
// -- case outside of volume with biasing:
|
||||
// ---------------------------------------
|
||||
@@ -738,12 +807,12 @@ void G4BiasingProcessInterface::SetProcessManager(const G4ProcessManager* mgr)
|
||||
else G4VProcess::SetProcessManager(mgr);
|
||||
|
||||
// -- initialize fSharedData pointer:
|
||||
if ( fSharedDataMap.Find(mgr) == fSharedDataMap.End() )
|
||||
if ( G4BiasingProcessSharedData::fSharedDataMap.Find(mgr) == G4BiasingProcessSharedData::fSharedDataMap.End() )
|
||||
{
|
||||
fSharedData = new G4BiasingProcessSharedData( mgr );
|
||||
fSharedDataMap[mgr] = fSharedData;
|
||||
G4BiasingProcessSharedData::fSharedDataMap[mgr] = fSharedData;
|
||||
}
|
||||
else fSharedData = fSharedDataMap[mgr] ;
|
||||
else fSharedData = G4BiasingProcessSharedData::fSharedDataMap[mgr] ;
|
||||
// -- augment list of co-operating processes:
|
||||
fSharedData-> fBiasingProcessInterfaces.push_back( this );
|
||||
fSharedData-> fPublicBiasingProcessInterfaces.push_back( this );
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
#include "G4BiasingProcessSharedData.hh"
|
||||
|
||||
G4MapCache< const G4ProcessManager*, G4BiasingProcessSharedData* > G4BiasingProcessSharedData::fSharedDataMap;
|
||||
@@ -0,0 +1,429 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4BiasingProcessLimiterForParallelGeometries.cc $
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4ParallelGeometriesLimiterProcess.hh"
|
||||
#include "G4BiasingProcessSharedData.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4PathFinder.hh"
|
||||
#include "G4FieldTrackUpdator.hh"
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4ParallelGeometriesLimiterProcess::G4ParallelGeometriesLimiterProcess(const G4String& processName) :
|
||||
G4VProcess(processName, fParallel),
|
||||
fParallelWorldSafety( 0.0 ),
|
||||
fIsTrackingTime ( false ),
|
||||
fFieldTrack ( '0' )
|
||||
{
|
||||
// -- Process Sub Type ? §§
|
||||
|
||||
fPathFinder = G4PathFinder::GetInstance();
|
||||
fTransportationManager = G4TransportationManager::GetTransportationManager();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------
|
||||
// -- Add/Remove world volumes:
|
||||
// ----------------------------
|
||||
void G4ParallelGeometriesLimiterProcess::AddParallelWorld(const G4String& parallelWorldName)
|
||||
{
|
||||
|
||||
// -- Refuse adding parallel geometry during tracking time:
|
||||
if (fIsTrackingTime)
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4ParallelGeometriesLimiterProcess `" << GetProcessName()
|
||||
<< "': adding a parallel world volume at tracking time is not allowed." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::AddParallelWorld(const G4String& parallelWorldName)",
|
||||
"BIAS.GEN.21",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting( parallelWorldName );
|
||||
|
||||
// -- Fatal exception if requested world does not exist:
|
||||
if (newWorld == 0)
|
||||
{
|
||||
G4ExceptionDescription tellWhatIsWrong;
|
||||
tellWhatIsWrong << "Volume `" << parallelWorldName
|
||||
<< "' is not a parallel world nor the mass world volume."
|
||||
<< G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::SetWorldVolume(const G4String)",
|
||||
"BIAS.GEN.22",
|
||||
FatalException,
|
||||
tellWhatIsWrong);
|
||||
}
|
||||
|
||||
// -- Protection against adding the mass geometry world as parallel world:
|
||||
if ( newWorld == fTransportationManager->GetNavigatorForTracking()->GetWorldVolume() )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4ParallelGeometriesLimiterProcess `" << GetProcessName()
|
||||
<< "': trying to add the world volume for tracking as a parallel world." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::AddParallelWorld(const G4String& parallelWorldName)",
|
||||
"BIAS.GEN.23",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
// -- Add parallel world, taking care it is not in the list yet:
|
||||
G4bool isNew = true;
|
||||
for ( auto knownWorld : fParallelWorlds )
|
||||
{
|
||||
if ( knownWorld == newWorld ) isNew = false;
|
||||
}
|
||||
if ( isNew ) fParallelWorlds.push_back( newWorld );
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4ParallelGeometriesLimiterProcess `" << GetProcessName()
|
||||
<< "': trying to re-add the parallel world volume `" << parallelWorldName << "'." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::AddParallelWorld(const G4String& parallelWorldName)",
|
||||
"BIAS.GEN.24",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4ParallelGeometriesLimiterProcess::RemoveParallelWorld(const G4String& parallelWorldName)
|
||||
{
|
||||
|
||||
// -- Refuse refuse removing parallel geometry during tracking time:
|
||||
if (fIsTrackingTime)
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4ParallelGeometriesLimiterProcess `" << GetProcessName()
|
||||
<< "': removing a parallel world volume at tracking time is not allowed." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::RemoveParallelWorld(const G4String& parallelWorldName)",
|
||||
"BIAS.GEN.25",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting( parallelWorldName );
|
||||
|
||||
if (newWorld == 0)
|
||||
{
|
||||
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4ParallelGeometriesLimiterProcess `" << GetProcessName()
|
||||
<< "': trying to remove an inexisting parallel world '" << parallelWorldName << "'." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::RemoveParallelWorld(const G4String& parallelWorldName)",
|
||||
"BIAS.GEN.26",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
// -- get position of world volume in list:
|
||||
size_t iWorld = 0;
|
||||
for ( auto knownWorld : fParallelWorlds )
|
||||
{
|
||||
if ( knownWorld == newWorld ) break;
|
||||
iWorld++;
|
||||
}
|
||||
|
||||
if ( iWorld == fParallelWorlds.size() )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "G4ParallelGeometriesLimiterProcess `" << GetProcessName()
|
||||
<< "': trying to remove an non-registerered parallel world '" << parallelWorldName << "'." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::RemoveParallelWorld(const G4String& parallelWorldName)",
|
||||
"BIAS.GEN.27",
|
||||
JustWarning, ed,
|
||||
"Call ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
// -- remove from vector:
|
||||
fParallelWorlds.erase( fParallelWorlds.begin() + iWorld );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------------
|
||||
// Start/End tracking:
|
||||
// --------------------
|
||||
void G4ParallelGeometriesLimiterProcess::StartTracking(G4Track* track)
|
||||
{
|
||||
fIsTrackingTime = true;
|
||||
|
||||
// -- fetch the navigators, their indeces, and activate:
|
||||
fParallelWorldNavigators .clear();
|
||||
fParallelWorldNavigatorIndeces.clear();
|
||||
fParallelWorldSafeties .clear();
|
||||
fParallelWorldIsLimiting .clear();
|
||||
fParallelWorldWasLimiting .clear();
|
||||
fCurrentVolumes .clear();
|
||||
fPreviousVolumes .clear();
|
||||
for ( auto parallelWorld : fParallelWorlds )
|
||||
{
|
||||
fParallelWorldNavigators .push_back( fTransportationManager-> GetNavigator( parallelWorld ) );
|
||||
fParallelWorldNavigatorIndeces.push_back( fTransportationManager->ActivateNavigator( fParallelWorldNavigators.back() ) );
|
||||
fParallelWorldSafeties .push_back( 0.0 );
|
||||
fParallelWorldIsLimiting .push_back( false );
|
||||
fParallelWorldWasLimiting .push_back( false );
|
||||
}
|
||||
|
||||
fPathFinder->PrepareNewTrack( track->GetPosition(), track->GetMomentumDirection() );
|
||||
// -- §§ does it work at this level, after "PrepareNewTrack" above ?
|
||||
for ( auto navigatorIndex : fParallelWorldNavigatorIndeces )
|
||||
{
|
||||
fPreviousVolumes.push_back( nullptr );
|
||||
fCurrentVolumes .push_back( fPathFinder->GetLocatedVolume( navigatorIndex ) );
|
||||
}
|
||||
|
||||
// -- will force updating safety:
|
||||
fParallelWorldSafety = 0.0;
|
||||
for ( size_t i = 0 ; i < fParallelWorldNavigatorIndeces.size() ; i++ ) fParallelWorldSafeties[i] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void G4ParallelGeometriesLimiterProcess::EndTracking()
|
||||
{
|
||||
fIsTrackingTime = false;
|
||||
for ( auto parallelWorldNavigator : fParallelWorldNavigators )
|
||||
fTransportationManager->DeActivateNavigator( parallelWorldNavigator );
|
||||
}
|
||||
|
||||
|
||||
G4double G4ParallelGeometriesLimiterProcess::PostStepGetPhysicalInteractionLength(const G4Track&, G4double, G4ForceCondition* condition)
|
||||
{
|
||||
|
||||
// -- push previous step limitation flags and volumes:
|
||||
// -- §§ consider switching pointers insteads of making copies of std::vector's:
|
||||
fParallelWorldWasLimiting = fParallelWorldIsLimiting;
|
||||
fPreviousVolumes = fCurrentVolumes;
|
||||
|
||||
// -- update volumes:
|
||||
size_t i = 0;
|
||||
for ( auto navigatorIndex : fParallelWorldNavigatorIndeces ) fCurrentVolumes[i++] = fPathFinder->GetLocatedVolume( navigatorIndex );
|
||||
|
||||
*condition = NotForced;
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
|
||||
G4double G4ParallelGeometriesLimiterProcess::AlongStepGetPhysicalInteractionLength(const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& proposedSafety,
|
||||
G4GPILSelection* selection)
|
||||
{
|
||||
|
||||
// -- Init:
|
||||
// -- Note that the returnedStep must be physically meaningful, even if we return NotCandidateForSelection as condition;
|
||||
// -- the reason is that the stepping manager always takes the smallest alongstep among the returned ones (point related
|
||||
// -- to geometry step length wrt to true path length).
|
||||
*selection = NotCandidateForSelection;
|
||||
G4double returnedStep = DBL_MAX;
|
||||
|
||||
// -- G4FieldTrack and ELimited:
|
||||
static G4ThreadLocal G4FieldTrack *endTrack_G4MT_TLS_ = 0 ;
|
||||
if (!endTrack_G4MT_TLS_) endTrack_G4MT_TLS_ = new G4FieldTrack ('0') ;
|
||||
G4FieldTrack &endTrack = *endTrack_G4MT_TLS_;
|
||||
|
||||
static G4ThreadLocal ELimited *eLimited_G4MT_TLS_ = 0 ;
|
||||
if (!eLimited_G4MT_TLS_) eLimited_G4MT_TLS_ = new ELimited ;
|
||||
ELimited &eLimited = *eLimited_G4MT_TLS_;
|
||||
|
||||
|
||||
// -------------------
|
||||
// -- Update safeties:
|
||||
// -------------------
|
||||
if ( previousStepSize > 0.0 )
|
||||
{
|
||||
for ( auto& parallelWorldSafety : fParallelWorldSafeties )
|
||||
{
|
||||
parallelWorldSafety -= previousStepSize;
|
||||
if ( parallelWorldSafety < 0. ) parallelWorldSafety = 0.0;
|
||||
fParallelWorldSafety = parallelWorldSafety < fParallelWorldSafety ? parallelWorldSafety : fParallelWorldSafety ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------
|
||||
// Determination of the proposed step length:
|
||||
// ------------------------------------------
|
||||
if ( ( currentMinimumStep <= fParallelWorldSafety ) && ( currentMinimumStep > 0. ) )
|
||||
{
|
||||
// -- No chance to limit the step, as proposed move inside safety
|
||||
|
||||
returnedStep = currentMinimumStep;
|
||||
proposedSafety = fParallelWorldSafety - currentMinimumStep;
|
||||
}
|
||||
else
|
||||
{
|
||||
// -- Proposed move exceeds common safety, need to state
|
||||
G4double smallestReturnedStep = -1.0;
|
||||
ELimited eLimitedForSmallestStep = kDoNot;
|
||||
for ( size_t i = 0 ; i < fParallelWorldNavigatorIndeces.size() ; i++ )
|
||||
{
|
||||
// -- Update safety of geometries having safety smaller than current minimum step
|
||||
if ( currentMinimumStep >= fParallelWorldSafeties[i] )
|
||||
{
|
||||
G4FieldTrackUpdator::Update(&fFieldTrack, &track);
|
||||
G4double tmpReturnedStep = fPathFinder->ComputeStep(fFieldTrack,
|
||||
currentMinimumStep,
|
||||
fParallelWorldNavigatorIndeces[i],
|
||||
track.GetCurrentStepNumber(),
|
||||
fParallelWorldSafeties[i],
|
||||
eLimited,
|
||||
endTrack,
|
||||
track.GetVolume());
|
||||
|
||||
if ( ( smallestReturnedStep < 0.0 ) || ( tmpReturnedStep <= smallestReturnedStep ) )
|
||||
{
|
||||
smallestReturnedStep = tmpReturnedStep;
|
||||
eLimitedForSmallestStep = eLimited;
|
||||
}
|
||||
|
||||
if (eLimited == kDoNot)
|
||||
{
|
||||
// -- Step not limited by this geometry
|
||||
fParallelWorldSafeties[i] = fParallelWorldNavigators[i]->ComputeSafety(endTrack.GetPosition());
|
||||
fParallelWorldIsLimiting[i] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fParallelWorldIsLimiting[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// -- update with smallest safety:
|
||||
fParallelWorldSafety = fParallelWorldSafeties[i] < fParallelWorldSafety ? fParallelWorldSafeties[i] : fParallelWorldSafety ;
|
||||
}
|
||||
|
||||
// -- no geometry limitation among all geometries, can return currentMinimumStep (or DBL_MAX):
|
||||
// -- Beware : the returnedStep must be physically meaningful, even if we say "NotCandidateForSelection" !
|
||||
if ( eLimitedForSmallestStep == kDoNot )
|
||||
{
|
||||
returnedStep = currentMinimumStep;
|
||||
}
|
||||
// -- proposed step length of limiting geometry:
|
||||
if ( eLimitedForSmallestStep == kUnique ||
|
||||
eLimitedForSmallestStep == kSharedOther )
|
||||
{
|
||||
*selection = CandidateForSelection;
|
||||
returnedStep = smallestReturnedStep;
|
||||
}
|
||||
else if ( eLimitedForSmallestStep == kSharedTransport)
|
||||
{
|
||||
returnedStep = smallestReturnedStep* (1.0 + 1.0e-9); // -- Expand to disable its selection in Step Manager comparison
|
||||
}
|
||||
|
||||
// -- and smallest safety among geometries:
|
||||
proposedSafety = fParallelWorldSafety ;
|
||||
}
|
||||
|
||||
// -- returns step length, and proposedSafety
|
||||
return returnedStep;
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4ParallelGeometriesLimiterProcess::AlongStepDoIt( const G4Track& track,
|
||||
const G4Step& )
|
||||
{
|
||||
|
||||
fDummyParticleChange.Initialize(track);
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
|
||||
|
||||
void G4ParallelGeometriesLimiterProcess::SetProcessManager(const G4ProcessManager* mgr)
|
||||
{
|
||||
G4BiasingProcessSharedData *sharedData(nullptr);
|
||||
|
||||
// -- initialize sharedData pointer:
|
||||
if ( G4BiasingProcessSharedData::fSharedDataMap.Find(mgr) == G4BiasingProcessSharedData::fSharedDataMap.End() )
|
||||
{
|
||||
sharedData = new G4BiasingProcessSharedData( mgr );
|
||||
G4BiasingProcessSharedData::fSharedDataMap[mgr] = sharedData;
|
||||
}
|
||||
else sharedData = G4BiasingProcessSharedData::fSharedDataMap[mgr] ;
|
||||
|
||||
// -- add itself to the shared data:
|
||||
if ( sharedData->fParallelGeometriesLimiterProcess == nullptr ) sharedData->fParallelGeometriesLimiterProcess = this;
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Trying to add more than one G4ParallelGeometriesLimiterProcess process to the process manager " << mgr
|
||||
<< " (process manager for `" << mgr->GetParticleType()->GetParticleName() << "'). Only one is needed. Call ignored." << G4endl;
|
||||
G4Exception(" G4ParallelGeometriesLimiterProcess::SetProcessManager(...)",
|
||||
"BIAS.GEN.29",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4int G4ParallelGeometriesLimiterProcess::GetParallelWorldIndex( const G4VPhysicalVolume* parallelWorld ) const
|
||||
{
|
||||
G4int toReturn = -1;
|
||||
G4int iWorld = 0;
|
||||
for ( auto world : fParallelWorlds )
|
||||
{
|
||||
if ( world == parallelWorld )
|
||||
{
|
||||
toReturn = iWorld;
|
||||
break;
|
||||
}
|
||||
iWorld++;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
G4int G4ParallelGeometriesLimiterProcess::GetParallelWorldIndex( G4String parallelWorldName ) const
|
||||
{
|
||||
G4VPhysicalVolume* aWorld = fTransportationManager->IsWorldExisting( parallelWorldName ); // note aWorld might be nullptr
|
||||
return GetParallelWorldIndex( aWorld );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user