Import Geant4 10.3.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-12-09 12:35:28 +01:00
parent 4ec577e5c4
commit a3452e42ac
3514 changed files with 210500 additions and 89628 deletions
+27 -2
View File
@@ -1,4 +1,4 @@
$Id: History 96031 2016-03-09 08:23:10Z gcosmo $
$Id: History 101363 2016-11-15 15:27:42Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,31 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
November 15th, 2016, M. Verderi
- Fix one Coverity warning in G4ParallelGeometriesLimiterProcess.
- proc-biasgen-V10-02-06
November 3rd, 2016, M. Verderi
- Remove reference to obsolete G4BiasingAppliedCase BAC_DenyInteraction enum value
and related logic. DenyProcessPostStepDoIt(..) method in G4BOptnForceFreeFlight
was concerned by this logic change. (The related case has been merged and
is handled by ApplyFinalStateBiasing(...) in a more general manner since
proc-biasgen-V10-00-00.)
- proc-biasgen-V10-02-05
October 26th, 2016, M. Verderi
- Development tag for introducing parallel geometry capability in generic biasing:
- G4BiasingProcessInterface : checks for biasing operator in mass and parallel geometries
- G4ParallelGeometriesLimiterProcess : a new process that limits the step on the boundaries
of the parallel geometries (one instance handles all parallel geometries)
- G4BiasingProcessSharedData : data shared among biasing processes related to a same
G4ParticleDefinition ; extended to cary information related to parallel geometries.
G4BiasingProcessSharedData now also holds the static map of shared data and process
managers, this was held before by G4BiasingProcessInterface.
- G4BiasingHelper : extended to handle addition of G4ParallelGeometriesLimiterProcess
to process manager.
- proc-biasgen-V10-02-04
March 8th, 2016, M. Verderi
- Clean up for unused variable fParticleChange in G4BiasingProcessInterface
- proc-biasgen-V10-02-03
@@ -53,7 +78,7 @@ November 6th, 2015, M. Verderi
- proc-biasgen-V10-01-01
November 6th, 2015, M. Verderi
- adaptation to using G4VAuxuliaryTrackInformation:
- adaptation to using G4VAuxiliaryTrackInformation:
o creation of G4BOptrForceCollisionTrackData
o quite rewriting of G4BOptrForceCollision biasing operator,
removing many state variables used for bookeeping of tracks
@@ -65,7 +65,6 @@ public:
// -------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw* ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& );
virtual G4bool DenyProcessPostStepDoIt( const G4BiasingProcessInterface*, const G4Track*, const G4Step*, G4double& );
virtual void AlongMoveBy( const G4BiasingProcessInterface*, const G4Step*, G4double );
virtual G4VParticleChange* ApplyFinalStateBiasing( const G4BiasingProcessInterface*, const G4Track*, const G4Step*, G4bool&);
@@ -44,6 +44,7 @@
#include "globals.hh"
class G4ProcessManager;
class G4ParallelGeometriesLimiterProcess;
#include <vector>
@@ -66,6 +67,11 @@ public:
// -- this process can be passed, otherwise the default name "biasWrapper(0)" is used.
static void ActivateNonPhysicsBiasing(G4ProcessManager* pmanager,
G4String nonPhysicsProcessName = "");
// -- Add a G4ParallelGeometriesLimiterProcess instance to the given process manager
// -- The pointer of the added process is returned.
static G4ParallelGeometriesLimiterProcess* AddLimiterProcess(G4ProcessManager* pmanager,
const G4String& processName = "biasLimiter");
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -273,15 +273,7 @@ private:
// -- the data shared among processes attached to a same process manager:
G4BiasingProcessSharedData* fSharedData;
// -- thread local:
// -- Map between process managers and shared data. This map is made of
// -- pointers of G4BiasingSharedData instead of objects themselves :
// -- each process needs to keep a valid pointer of a shared data object
// -- but a map of object will make pointers invalid when map is increaded.
static G4MapCache< const G4ProcessManager*,
G4BiasingProcessSharedData* > fSharedDataMap;
};
#endif
@@ -47,15 +47,18 @@
#define G4BiasingProcessSharedData_h
#include "globals.hh"
#include "G4Cache.hh"
#include <vector>
class G4VBiasingOperator;
class G4BiasingProcessInterface;
class G4ProcessManager;
class G4ParallelGeometriesLimiterProcess;
class G4BiasingProcessSharedData {
friend class G4BiasingProcessInterface;
friend class G4ParallelGeometriesLimiterProcess;
public:
// -------------------------
@@ -63,24 +66,30 @@ public:
// -------------------------
// -- The biasing process interface objects sharing this shared data class:
const std::vector< const G4BiasingProcessInterface* >& GetBiasingProcessInterfaces() const
{return fPublicBiasingProcessInterfaces;}
{ return fPublicBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetPhysicsBiasingProcessInterfaces() const
{return fPublicPhysicsBiasingProcessInterfaces;}
{ return fPublicPhysicsBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetNonPhysicsBiasingProcessInterfaces() const
{return fPublicNonPhysicsBiasingProcessInterfaces;}
{ return fPublicNonPhysicsBiasingProcessInterfaces; }
// -- The possible geometry limiter process:
const G4ParallelGeometriesLimiterProcess* GetParallelGeometriesLimiterProcess() const
{ return fParallelGeometriesLimiterProcess; }
private:
// -- Methods used by the G4BiasingProcessInterface objects, thanks to class friendness.
// -- Object is created by G4BiasingProcessInterface object:
G4BiasingProcessSharedData( const G4ProcessManager* mgr)
: fProcessManager (mgr),
fCurrentBiasingOperator (0),
fPreviousBiasingOperator(0),
fIsNewOperator (true),
fLeavingPreviousOperator(false)
{}
: fProcessManager (mgr),
fCurrentBiasingOperator ( nullptr ),
fPreviousBiasingOperator ( nullptr ),
fParallelGeometryOperator ( nullptr ),
fMassGeometryOperator ( nullptr ),
fIsNewOperator (true),
fLeavingPreviousOperator (false),
fParallelGeometriesLimiterProcess( nullptr )
{}
~G4BiasingProcessSharedData() {}
// -- biasing operators:
void CurrentBiasingOperator( G4VBiasingOperator* );
@@ -94,19 +103,33 @@ private:
// -- biasing operators:
G4VBiasingOperator* fCurrentBiasingOperator;
G4VBiasingOperator* fPreviousBiasingOperator;
G4VBiasingOperator* fParallelGeometryOperator;
G4VBiasingOperator* fMassGeometryOperator;
// --
G4bool fIsNewOperator;
G4bool fLeavingPreviousOperator;
// -- biaising process interfaces sharing this object:
std::vector < G4BiasingProcessInterface* > fBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fPhysicsBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fNonPhysicsBiasingProcessInterfaces;
// -- biasing process interfaces sharing this object:
std::vector < G4BiasingProcessInterface* > fBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fPhysicsBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fNonPhysicsBiasingProcessInterfaces;
// -- the same ones, for public use:
std::vector < const G4BiasingProcessInterface* > fPublicBiasingProcessInterfaces;
std::vector < const G4BiasingProcessInterface* > fPublicPhysicsBiasingProcessInterfaces;
std::vector < const G4BiasingProcessInterface* > fPublicNonPhysicsBiasingProcessInterfaces;
// -- possible process limiting step on parallel geometries:
G4ParallelGeometriesLimiterProcess* fParallelGeometriesLimiterProcess;
// -- thread local:
// -- Map between process managers and shared data. This map is made of
// -- pointers of G4BiasingSharedData instead of objects themselves :
// -- each process needs to keep a valid pointer of a shared data object
// -- but a map of object will make pointers invalid when map is increased.
static G4MapCache< const G4ProcessManager*,
G4BiasingProcessSharedData* > fSharedDataMap;
};
#endif
@@ -0,0 +1,183 @@
//
// ********************************************************************
// * 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: G4ParallelGeometriesLimiterProcess.hh $
//
//
//---------------------------------------------------------------
//
// G4ParallelGeometriesLimiterProcess.hh
//
// Description:
// Process dedicated to limiting the step on boudaries of
// parallel geometries used for the generic biasing.
//
// History:
// Sep 16: Creation.
//
//---------------------------------------------------------------
#ifndef G4ParallelGeometriesLimiterProcess_hh
#define G4ParallelGeometriesLimiterProcess_hh
#include "globals.hh"
#include "G4VProcess.hh"
#include "G4Step.hh"
#include "G4Navigator.hh"
#include "G4VPhysicalVolume.hh"
#include "G4ParticleChangeForNothing.hh"
#include "G4FieldTrack.hh"
class G4PathFinder;
class G4TransportationManager;
// Class Description:
// -- G4VProcess limiting the step on parallel geometries used by generic biasing.
class G4ParallelGeometriesLimiterProcess : public G4VProcess
{
public:
// --------------------------
// -- Constructor/Destructor:
// --------------------------
G4ParallelGeometriesLimiterProcess(const G4String& processName = "biasLimiter");
public:
virtual ~G4ParallelGeometriesLimiterProcess()
{}
// ----------------------------------------------------
// -- Registration / deregistration of parallel worlds.
// -- Access to the list of registered parallel worlds.
// ----------------------------------------------------
void AddParallelWorld(const G4String& parallelWorldName);
void RemoveParallelWorld(const G4String& parallelWorldName);
// -- The list of registered parallel worlds:
const std::vector< G4VPhysicalVolume* >& GetParallelWorlds() const { return fParallelWorlds; }
// -- Get the parallel world volume index in the list of world volumes handled
// -- by the process. This index can then be used to access current volume and step
// -- limitation status below.
// -- If the world passed is unknown to the process, -1 is returned.
G4int GetParallelWorldIndex( const G4VPhysicalVolume* parallelWorld ) const;
G4int GetParallelWorldIndex( G4String parallelWorldName ) const;
// ---------------------
// -- Active navigators:
// ---------------------
// -- The list of navigators handled by the process:
const std::vector< G4Navigator* >& GetActiveNavigators() const { return fParallelWorldNavigators; }
// -- The navigator used for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
const G4Navigator* GetNavigator( G4int worldIndex ) const { return fParallelWorldNavigators[size_t(worldIndex)]; }
// ---------------------------------------------------
// -- Previous and current steps geometry information:
// ---------------------------------------------------
// -- The "switch" between the previous and current step is done in the PostStepGPIL
// -- The update on the current step is done:
// -- - in the PostStepGPIL for the volumes
// -- - in the AlongStepGPIL for the step limitations
// --
// -- The list of previous step and current step volumes:
const std::vector< const G4VPhysicalVolume* >& GetCurrentVolumes() const { return fCurrentVolumes; }
const std::vector< const G4VPhysicalVolume* >& GetPreviousVolumes() const { return fPreviousVolumes; }
// -- The current and previous volume for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
const G4VPhysicalVolume* GetCurrentVolume( G4int worldIndex ) const { return fCurrentVolumes[size_t(worldIndex)]; }
const G4VPhysicalVolume* GetPreviousVolume( G4int worldIndex ) const { return fPreviousVolumes[size_t(worldIndex)]; }
// -- Flags telling about step limitation in previous and current step:
const std::vector< G4bool >& GetIsLimiting() const { return fParallelWorldIsLimiting; }
const std::vector< G4bool >& GetWasLimiting() const { return fParallelWorldWasLimiting; }
// -- The current and previous step limitation status for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
G4bool GetIsLimiting( G4int worldIndex ) const { return fParallelWorldIsLimiting[size_t(worldIndex)]; }
G4bool GetWasLimiting( G4int worldIndex ) const { return fParallelWorldWasLimiting[size_t(worldIndex)]; }
// --------------------------------------------------------------
// From process interface
// --------------------------------------------------------------
// -- Start/End tracking:
void StartTracking(G4Track*);
void EndTracking();
// --------------------
// -- PostStep methods:
// --------------------
// -- PostStepGPIL is used to collect up to date volumes in the parallel geometries:
G4double PostStepGetPhysicalInteractionLength(const G4Track&, G4double, G4ForceCondition*);
// -- PostStepDoIt is not used (never called):
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step& )
{ return nullptr; }
// ---------------------------------------------------------------------------
// -- Along step used for limiting the step on parallel geometries boundaries:
// ---------------------------------------------------------------------------
G4double AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection);
G4VParticleChange* AlongStepDoIt(const G4Track& track,
const G4Step& step);
// ---------------------------
// -- AtRest methods not used:
// ---------------------------
G4double AtRestGetPhysicalInteractionLength(const G4Track&,
G4ForceCondition*)
{ return DBL_MAX; }
G4VParticleChange* AtRestDoIt(const G4Track&, const G4Step&)
{ return nullptr; }
// --
virtual void SetProcessManager(const G4ProcessManager*);
private:
std::vector< G4VPhysicalVolume* > fParallelWorlds;
std::vector< G4Navigator* > fParallelWorldNavigators;
std::vector< G4int > fParallelWorldNavigatorIndeces;
std::vector< G4double > fParallelWorldSafeties;
std::vector< G4bool > fParallelWorldIsLimiting;
std::vector< G4bool > fParallelWorldWasLimiting;
std::vector< const G4VPhysicalVolume* > fCurrentVolumes;
std::vector< const G4VPhysicalVolume* > fPreviousVolumes;
G4double fParallelWorldSafety;
G4bool fIsTrackingTime;
G4FieldTrack fFieldTrack;
G4ParticleChangeForNothing fDummyParticleChange;
G4PathFinder* fPathFinder;
G4TransportationManager* fTransportationManager;
};
#endif
@@ -11,7 +11,7 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 94220 2015-11-09 08:26:57Z gcosmo $
# $Id: sources.cmake 100675 2016-10-31 10:44:51Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -57,11 +57,13 @@ GEANT4_DEFINE_MODULE(NAME G4biasing_gen
G4ILawForceFreeFlight.hh
G4ILawTruncatedExp.hh
G4InteractionLawPhysical.hh
G4ParallelGeometriesLimiterProcess.hh
G4ParticleChangeForNothing.hh
G4ParticleChangeForOccurenceBiasing.hh
SOURCES
G4BiasingHelper.cc
G4BiasingProcessInterface.cc
G4BiasingProcessSharedData.cc
G4BOptnChangeCrossSection.cc
G4BOptnCloning.cc
G4BOptnForceCommonTruncatedExp.cc
@@ -72,6 +74,7 @@ GEANT4_DEFINE_MODULE(NAME G4biasing_gen
G4ILawForceFreeFlight.cc
G4ILawTruncatedExp.cc
G4InteractionLawPhysical.cc
G4ParallelGeometriesLimiterProcess.cc
G4ParticleChangeForOccurenceBiasing.cc
GRANULAR_DEPENDENCIES
G4cuts
@@ -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 );
}