Import Geant4 11.3.0 source tree
This commit is contained in:
@@ -23,21 +23,21 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptnChangeCrossSection
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BOptnChangeCrossSection.hh"
|
||||
#include "G4InteractionLawPhysical.hh"
|
||||
|
||||
|
||||
|
||||
G4BOptnChangeCrossSection::G4BOptnChangeCrossSection(G4String name)
|
||||
: G4VBiasingOperation( name ),
|
||||
fInteractionOccured( false )
|
||||
G4BOptnChangeCrossSection::G4BOptnChangeCrossSection(const G4String& name)
|
||||
: G4VBiasingOperation( name )
|
||||
{
|
||||
fBiasedExponentialLaw = new G4InteractionLawPhysical("LawForOperation"+name);
|
||||
}
|
||||
|
||||
G4BOptnChangeCrossSection::~G4BOptnChangeCrossSection()
|
||||
{
|
||||
if ( fBiasedExponentialLaw ) delete fBiasedExponentialLaw;
|
||||
delete fBiasedExponentialLaw;
|
||||
}
|
||||
|
||||
const G4VBiasingInteractionLaw* G4BOptnChangeCrossSection::ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& )
|
||||
@@ -45,7 +45,7 @@ const G4VBiasingInteractionLaw* G4BOptnChangeCrossSection::ProvideOccurenceBiasi
|
||||
return fBiasedExponentialLaw;
|
||||
}
|
||||
|
||||
void G4BOptnChangeCrossSection::SetBiasedCrossSection( G4double xst, bool updateInteractionLength )
|
||||
void G4BOptnChangeCrossSection::SetBiasedCrossSection( G4double xst, G4bool updateInteractionLength )
|
||||
{
|
||||
fBiasedExponentialLaw->SetPhysicalCrossSection( xst );
|
||||
if ( updateInteractionLength ) UpdateForStep( 0.0 );
|
||||
|
||||
@@ -23,22 +23,22 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptnCloning
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BOptnCloning.hh"
|
||||
|
||||
|
||||
G4BOptnCloning::G4BOptnCloning(G4String name)
|
||||
: G4VBiasingOperation( name ),
|
||||
fClone1W ( -1.0 ),
|
||||
fClone2W ( -1.0 ),
|
||||
fParticleChange(),
|
||||
fCloneTrack ( nullptr )
|
||||
G4BOptnCloning::G4BOptnCloning(const G4String& name)
|
||||
: G4VBiasingOperation( name ),
|
||||
fParticleChange()
|
||||
{}
|
||||
|
||||
G4BOptnCloning::~G4BOptnCloning()
|
||||
{}
|
||||
|
||||
G4VParticleChange* G4BOptnCloning::GenerateBiasingFinalState( const G4Track* track,
|
||||
const G4Step* )
|
||||
G4VParticleChange*
|
||||
G4BOptnCloning::GenerateBiasingFinalState( const G4Track* track,
|
||||
const G4Step* )
|
||||
{
|
||||
fParticleChange.Initialize(*track);
|
||||
fParticleChange.ProposeParentWeight( fClone1W );
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptnForceCommonTruncatedExp
|
||||
// --------------------------------------------------------------------
|
||||
#include "G4BOptnForceCommonTruncatedExp.hh"
|
||||
#include "G4ILawCommonTruncatedExp.hh"
|
||||
#include "G4ILawForceFreeFlight.hh"
|
||||
@@ -31,96 +33,92 @@
|
||||
#include "Randomize.hh"
|
||||
#include "G4BiasingProcessInterface.hh"
|
||||
|
||||
G4BOptnForceCommonTruncatedExp::G4BOptnForceCommonTruncatedExp(G4String name)
|
||||
: G4VBiasingOperation(name),
|
||||
fNumberOfSharing(0),
|
||||
fProcessToApply(nullptr),
|
||||
fInteractionOccured(false),
|
||||
fMaximumDistance(-1.0)
|
||||
G4BOptnForceCommonTruncatedExp::
|
||||
G4BOptnForceCommonTruncatedExp(const G4String& name)
|
||||
: G4VBiasingOperation(name)
|
||||
{
|
||||
fCommonTruncatedExpLaw = new G4ILawCommonTruncatedExp("ExpLawForOperation"+name);
|
||||
fForceFreeFlightLaw = new G4ILawForceFreeFlight ("FFFLawForOperation"+name);
|
||||
|
||||
fTotalCrossSection = 0.0;
|
||||
}
|
||||
|
||||
G4BOptnForceCommonTruncatedExp::~G4BOptnForceCommonTruncatedExp()
|
||||
{
|
||||
if ( fCommonTruncatedExpLaw ) delete fCommonTruncatedExpLaw;
|
||||
if ( fForceFreeFlightLaw ) delete fForceFreeFlightLaw;
|
||||
delete fCommonTruncatedExpLaw;
|
||||
delete fForceFreeFlightLaw;
|
||||
}
|
||||
|
||||
const G4VBiasingInteractionLaw* G4BOptnForceCommonTruncatedExp::
|
||||
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface* callingProcess,
|
||||
G4ForceCondition& proposeForceCondition )
|
||||
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface* callingProcess,
|
||||
G4ForceCondition& proposeForceCondition )
|
||||
{
|
||||
if ( callingProcess->GetWrappedProcess() == fProcessToApply )
|
||||
{
|
||||
proposeForceCondition = Forced;
|
||||
return fCommonTruncatedExpLaw;
|
||||
}
|
||||
{
|
||||
proposeForceCondition = Forced;
|
||||
return fCommonTruncatedExpLaw;
|
||||
}
|
||||
else
|
||||
{
|
||||
proposeForceCondition = Forced;
|
||||
return fForceFreeFlightLaw;
|
||||
}
|
||||
{
|
||||
proposeForceCondition = Forced;
|
||||
return fForceFreeFlightLaw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4GPILSelection G4BOptnForceCommonTruncatedExp::ProposeGPILSelection( const G4GPILSelection )
|
||||
G4GPILSelection G4BOptnForceCommonTruncatedExp::
|
||||
ProposeGPILSelection( const G4GPILSelection )
|
||||
{
|
||||
return NotCandidateForSelection;
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4BOptnForceCommonTruncatedExp::ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track,
|
||||
const G4Step* step,
|
||||
G4bool& forceFinalState )
|
||||
G4VParticleChange* G4BOptnForceCommonTruncatedExp::
|
||||
ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track,
|
||||
const G4Step* step,
|
||||
G4bool& forceFinalState )
|
||||
{
|
||||
if ( callingProcess->GetWrappedProcess() != fProcessToApply )
|
||||
{
|
||||
forceFinalState = true;
|
||||
fDummyParticleChange.Initialize( *track );
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
{
|
||||
forceFinalState = true;
|
||||
fDummyParticleChange.Initialize( *track );
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
if ( fInteractionOccured )
|
||||
{
|
||||
forceFinalState = true;
|
||||
fDummyParticleChange.Initialize( *track );
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
{
|
||||
forceFinalState = true;
|
||||
fDummyParticleChange.Initialize( *track );
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
|
||||
// -- checks if process won the GPIL race:
|
||||
G4double processGPIL = callingProcess->GetPostStepGPIL() < callingProcess->GetAlongStepGPIL() ?
|
||||
callingProcess->GetPostStepGPIL() : callingProcess->GetAlongStepGPIL() ;
|
||||
G4double processGPIL = callingProcess->GetPostStepGPIL()
|
||||
< callingProcess->GetAlongStepGPIL()
|
||||
? callingProcess->GetPostStepGPIL()
|
||||
: callingProcess->GetAlongStepGPIL();
|
||||
if ( processGPIL <= step->GetStepLength() )
|
||||
{
|
||||
// -- if process won, wrapped process produces the final state.
|
||||
// -- In this case, the weight for occurrence biasing is applied
|
||||
// -- by the callingProcess, at exit of present method. This is
|
||||
// -- selected by "forceFinalState = false":
|
||||
forceFinalState = false;
|
||||
fInteractionOccured = true;
|
||||
return callingProcess->GetWrappedProcess()->PostStepDoIt( *track, *step );
|
||||
}
|
||||
{
|
||||
// -- if process won, wrapped process produces the final state.
|
||||
// -- In this case, the weight for occurrence biasing is applied
|
||||
// -- by the callingProcess, at exit of present method. This is
|
||||
// -- selected by "forceFinalState = false":
|
||||
forceFinalState = false;
|
||||
fInteractionOccured = true;
|
||||
return callingProcess->GetWrappedProcess()->PostStepDoIt( *track, *step );
|
||||
}
|
||||
else
|
||||
{
|
||||
forceFinalState = true;
|
||||
fDummyParticleChange.Initialize( *track );
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
{
|
||||
forceFinalState = true;
|
||||
fDummyParticleChange.Initialize( *track );
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4BOptnForceCommonTruncatedExp::AddCrossSection( const G4VProcess* process, G4double crossSection )
|
||||
void G4BOptnForceCommonTruncatedExp::
|
||||
AddCrossSection( const G4VProcess* process, G4double crossSection )
|
||||
{
|
||||
fTotalCrossSection += crossSection;
|
||||
fCrossSections[process] = crossSection;
|
||||
fNumberOfSharing = fCrossSections.size();
|
||||
}
|
||||
|
||||
|
||||
void G4BOptnForceCommonTruncatedExp::Initialize( const G4Track* track )
|
||||
{
|
||||
fCrossSections.clear();
|
||||
@@ -132,17 +130,16 @@ void G4BOptnForceCommonTruncatedExp::Initialize( const G4Track* track )
|
||||
|
||||
G4VSolid* currentSolid = track->GetVolume()->GetLogicalVolume()->GetSolid();
|
||||
G4ThreeVector localPosition = (G4TransportationManager::GetTransportationManager()->
|
||||
GetNavigatorForTracking()->
|
||||
GetGlobalToLocalTransform()).TransformPoint(track->GetPosition());
|
||||
GetNavigatorForTracking()->
|
||||
GetGlobalToLocalTransform()).TransformPoint(track->GetPosition());
|
||||
G4ThreeVector localDirection = (G4TransportationManager::GetTransportationManager()->
|
||||
GetNavigatorForTracking()->
|
||||
GetGlobalToLocalTransform()).TransformAxis(track->GetMomentumDirection());
|
||||
GetNavigatorForTracking()->
|
||||
GetGlobalToLocalTransform()).TransformAxis(track->GetMomentumDirection());
|
||||
fMaximumDistance = currentSolid->DistanceToOut(localPosition, localDirection);
|
||||
if ( fMaximumDistance <= DBL_MIN ) fMaximumDistance = 0.0;
|
||||
if ( fMaximumDistance <= DBL_MIN ) { fMaximumDistance = 0.0; }
|
||||
fCommonTruncatedExpLaw->SetMaximumDistance( fMaximumDistance );
|
||||
}
|
||||
|
||||
|
||||
void G4BOptnForceCommonTruncatedExp::UpdateForStep( const G4Step* step )
|
||||
{
|
||||
fCrossSections.clear();
|
||||
@@ -154,7 +151,6 @@ void G4BOptnForceCommonTruncatedExp::UpdateForStep( const G4Step* step )
|
||||
fMaximumDistance = fCommonTruncatedExpLaw->GetMaximumDistance();
|
||||
}
|
||||
|
||||
|
||||
void G4BOptnForceCommonTruncatedExp::Sample()
|
||||
{
|
||||
fCommonTruncatedExpLaw->SetForceCrossSection( fTotalCrossSection );
|
||||
@@ -163,20 +159,17 @@ void G4BOptnForceCommonTruncatedExp::Sample()
|
||||
fCommonTruncatedExpLaw->SetSelectedProcessXSfraction(fCrossSections[fProcessToApply] / fTotalCrossSection);
|
||||
}
|
||||
|
||||
|
||||
void G4BOptnForceCommonTruncatedExp::ChooseProcessToApply()
|
||||
{
|
||||
G4double sigmaRand = G4UniformRand() * fTotalCrossSection;
|
||||
G4double sigmaSelect = 0.0;
|
||||
for ( std::map< const G4VProcess*, G4double>::const_iterator it = fCrossSections.begin();
|
||||
it != fCrossSections.end();
|
||||
it++)
|
||||
for ( auto it = fCrossSections.cbegin(); it != fCrossSections.cend(); ++it)
|
||||
{
|
||||
sigmaSelect += (*it).second;
|
||||
if ( sigmaRand <= sigmaSelect )
|
||||
{
|
||||
sigmaSelect += (*it).second;
|
||||
if ( sigmaRand <= sigmaSelect )
|
||||
{
|
||||
fProcessToApply = (*it).first;
|
||||
break;
|
||||
}
|
||||
fProcessToApply = (*it).first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,39 +23,37 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptnForceFreeFlight
|
||||
// --------------------------------------------------------------------
|
||||
#include "G4BOptnForceFreeFlight.hh"
|
||||
#include "G4ILawForceFreeFlight.hh"
|
||||
#include "G4BiasingProcessInterface.hh"
|
||||
#include "G4Step.hh"
|
||||
|
||||
|
||||
|
||||
G4BOptnForceFreeFlight::G4BOptnForceFreeFlight(G4String name)
|
||||
: G4VBiasingOperation ( name ),
|
||||
fCumulatedWeightChange ( -1.0 ),
|
||||
fInitialTrackWeight ( -1.0 ),
|
||||
fOperationComplete ( true )
|
||||
G4BOptnForceFreeFlight::G4BOptnForceFreeFlight(const G4String& name)
|
||||
: G4VBiasingOperation( name )
|
||||
{
|
||||
fForceFreeFlightInteractionLaw = new G4ILawForceFreeFlight("LawForOperation"+name);
|
||||
}
|
||||
|
||||
G4BOptnForceFreeFlight::~G4BOptnForceFreeFlight()
|
||||
{
|
||||
if ( fForceFreeFlightInteractionLaw ) delete fForceFreeFlightInteractionLaw;
|
||||
delete fForceFreeFlightInteractionLaw;
|
||||
}
|
||||
|
||||
const G4VBiasingInteractionLaw* G4BOptnForceFreeFlight::ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& proposeForceCondition )
|
||||
const G4VBiasingInteractionLaw* G4BOptnForceFreeFlight::
|
||||
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*,
|
||||
G4ForceCondition& proposeForceCondition )
|
||||
{
|
||||
fOperationComplete = false;
|
||||
proposeForceCondition = Forced;
|
||||
return fForceFreeFlightInteractionLaw;
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4BOptnForceFreeFlight::ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track,
|
||||
const G4Step* step,
|
||||
G4bool& forceFinalState)
|
||||
G4VParticleChange* G4BOptnForceFreeFlight::
|
||||
ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track, const G4Step* step,
|
||||
G4bool& forceFinalState)
|
||||
{
|
||||
// -- If the track is reaching the volume boundary, its free flight ends. In this case, its zero
|
||||
// -- weight is brought back to non-zero value: its initial weight is restored by the first
|
||||
@@ -64,41 +62,39 @@ G4VParticleChange* G4BOptnForceFreeFlight::ApplyFinalStateBiasing( const G4Biasi
|
||||
// -- If the track is not reaching the volume boundary, it zero weight flight continues.
|
||||
|
||||
fParticleChange.Initialize( *track );
|
||||
forceFinalState = true;
|
||||
forceFinalState = true;
|
||||
if ( step->GetPostStepPoint()->GetStepStatus() == fGeomBoundary )
|
||||
{
|
||||
// -- Sanity checks:
|
||||
if ( fInitialTrackWeight <= DBL_MIN )
|
||||
{
|
||||
// -- Sanity checks:
|
||||
if ( fInitialTrackWeight <= DBL_MIN )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Initial track weight is null ! " << G4endl;
|
||||
G4Exception(" G4BOptnForceFreeFlight::ApplyFinalStateBiasing(...)",
|
||||
"BIAS.GEN.05",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
if ( fCumulatedWeightChange <= DBL_MIN )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Cumulated weight is null ! " << G4endl;
|
||||
G4Exception(" G4BOptnForceFreeFlight::ApplyFinalStateBiasing(...)",
|
||||
"BIAS.GEN.06",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
|
||||
G4double proposedWeight = track->GetWeight();
|
||||
if ( callingProcess->GetIsFirstPostStepDoItInterface() ) proposedWeight = fCumulatedWeightChange * fInitialTrackWeight;
|
||||
else proposedWeight *= fCumulatedWeightChange;
|
||||
fParticleChange.ProposeWeight(proposedWeight);
|
||||
fOperationComplete = true;
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Initial track weight is null ! " << G4endl;
|
||||
G4Exception(" G4BOptnForceFreeFlight::ApplyFinalStateBiasing(...)",
|
||||
"BIAS.GEN.05", JustWarning, ed);
|
||||
}
|
||||
if ( fCumulatedWeightChange <= DBL_MIN )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Cumulated weight is null ! " << G4endl;
|
||||
G4Exception(" G4BOptnForceFreeFlight::ApplyFinalStateBiasing(...)",
|
||||
"BIAS.GEN.06", JustWarning, ed);
|
||||
}
|
||||
G4double proposedWeight = track->GetWeight();
|
||||
if ( callingProcess->GetIsFirstPostStepDoItInterface() )
|
||||
proposedWeight = fCumulatedWeightChange * fInitialTrackWeight;
|
||||
else
|
||||
proposedWeight *= fCumulatedWeightChange;
|
||||
fParticleChange.ProposeWeight(proposedWeight);
|
||||
fOperationComplete = true;
|
||||
}
|
||||
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
|
||||
void G4BOptnForceFreeFlight::AlongMoveBy( const G4BiasingProcessInterface*, const G4Step*, G4double weightChange )
|
||||
void G4BOptnForceFreeFlight::
|
||||
AlongMoveBy( const G4BiasingProcessInterface*,
|
||||
const G4Step*, G4double weightChange )
|
||||
{
|
||||
fCumulatedWeightChange *= weightChange;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptnLeadingParticle
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BOptnLeadingParticle.hh"
|
||||
#include "G4BiasingProcessInterface.hh"
|
||||
|
||||
@@ -30,9 +33,8 @@
|
||||
#include <map>
|
||||
|
||||
|
||||
G4BOptnLeadingParticle::G4BOptnLeadingParticle(G4String name)
|
||||
: G4VBiasingOperation ( name ),
|
||||
fRussianRouletteKillingProbability ( -1.0 )
|
||||
G4BOptnLeadingParticle::G4BOptnLeadingParticle(const G4String& name)
|
||||
: G4VBiasingOperation( name )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,10 +42,9 @@ G4BOptnLeadingParticle::~G4BOptnLeadingParticle()
|
||||
{
|
||||
}
|
||||
|
||||
G4VParticleChange* G4BOptnLeadingParticle::ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track,
|
||||
const G4Step* step,
|
||||
G4bool& )
|
||||
G4VParticleChange* G4BOptnLeadingParticle::
|
||||
ApplyFinalStateBiasing( const G4BiasingProcessInterface* callingProcess,
|
||||
const G4Track* track, const G4Step* step, G4bool& )
|
||||
{
|
||||
// -- collect wrapped process particle change:
|
||||
auto wrappedProcessParticleChange = callingProcess->GetWrappedProcess()->PostStepDoIt(*track,*step);
|
||||
@@ -66,148 +67,153 @@ G4VParticleChange* G4BOptnLeadingParticle::ApplyFinalStateBiasing( const G4Biasi
|
||||
G4ParticleChange* castParticleChange ( nullptr );
|
||||
G4Track* finalStatePrimary ( nullptr );
|
||||
if ( ( wrappedProcessParticleChange->GetTrackStatus() != fStopAndKill ) )
|
||||
{
|
||||
// fFakePrimaryTrack->CopyTrackInfo( *track );
|
||||
// fFakeStep ->InitializeStep( fFakePrimaryTrack );
|
||||
// wrappedProcessParticleChange->UpdateStepForPostStep( fFakeStep );
|
||||
// fFakeStep->UpdateTrack();
|
||||
castParticleChange = dynamic_cast< G4ParticleChange* >( wrappedProcessParticleChange );
|
||||
if ( castParticleChange == nullptr )
|
||||
{
|
||||
// fFakePrimaryTrack->CopyTrackInfo( *track );
|
||||
// fFakeStep ->InitializeStep( fFakePrimaryTrack );
|
||||
// wrappedProcessParticleChange->UpdateStepForPostStep( fFakeStep );
|
||||
// fFakeStep->UpdateTrack();
|
||||
castParticleChange = dynamic_cast< G4ParticleChange* >( wrappedProcessParticleChange );
|
||||
if ( castParticleChange == nullptr )
|
||||
{
|
||||
G4cout << " **** G4BOptnLeadingParticle::ApplyFinalStateBiasing(...) : can not bias for " << callingProcess->GetProcessName() << ", this is just a warning." << G4endl;
|
||||
return wrappedProcessParticleChange;
|
||||
}
|
||||
finalStatePrimary = new G4Track( *track );
|
||||
finalStatePrimary->SetKineticEnergy ( castParticleChange->GetEnergy() );
|
||||
finalStatePrimary->SetWeight ( castParticleChange->GetWeight() );
|
||||
finalStatePrimary->SetMomentumDirection( *(castParticleChange->GetMomentumDirection()) );
|
||||
// -- [**] push the primary as the last track in the vector of tracks:
|
||||
secondariesAndPrimary.push_back( finalStatePrimary );
|
||||
G4cout << " **** G4BOptnLeadingParticle::ApplyFinalStateBiasing(...) : can not bias for " << callingProcess->GetProcessName() << ", this is just a warning." << G4endl;
|
||||
return wrappedProcessParticleChange;
|
||||
}
|
||||
finalStatePrimary = new G4Track( *track );
|
||||
finalStatePrimary->SetKineticEnergy ( castParticleChange->GetEnergy() );
|
||||
finalStatePrimary->SetWeight ( castParticleChange->GetWeight() );
|
||||
finalStatePrimary->SetMomentumDirection( *(castParticleChange->GetMomentumDirection()) );
|
||||
// -- [**] push the primary as the last track in the vector of tracks:
|
||||
secondariesAndPrimary.push_back( finalStatePrimary );
|
||||
}
|
||||
|
||||
// -- Ensure the secondaries all have the primary weight:
|
||||
// ---- collect primary track weight, from updated by process if alive, or from original copy if died:
|
||||
G4double primaryWeight;
|
||||
G4double primaryWeight;
|
||||
if ( finalStatePrimary ) primaryWeight = finalStatePrimary->GetWeight();
|
||||
else primaryWeight = track ->GetWeight();
|
||||
else primaryWeight = track->GetWeight();
|
||||
// ---- now set this same weight to all secondaries:
|
||||
for ( auto i = 0 ; i < wrappedProcessParticleChange->GetNumberOfSecondaries() ; i++ ) secondariesAndPrimary[ i ]->SetWeight( primaryWeight );
|
||||
|
||||
for (auto i = 0; i < wrappedProcessParticleChange->GetNumberOfSecondaries(); ++i)
|
||||
secondariesAndPrimary[ i ]->SetWeight( primaryWeight );
|
||||
|
||||
// -- finds the leading particle, initialize a map of surviving tracks, tag as surviving the leading track:
|
||||
size_t leadingIDX = 0;
|
||||
std::size_t leadingIDX = 0;
|
||||
G4double leadingEnergy = -1;
|
||||
std::map< G4Track*, G4bool > survivingMap;
|
||||
for ( size_t idx = 0; idx < secondariesAndPrimary.size(); idx++ )
|
||||
for ( std::size_t idx = 0; idx < secondariesAndPrimary.size(); ++idx )
|
||||
{
|
||||
survivingMap[ secondariesAndPrimary[idx] ] = false;
|
||||
if ( secondariesAndPrimary[idx]->GetKineticEnergy() > leadingEnergy )
|
||||
{
|
||||
survivingMap[ secondariesAndPrimary[idx] ] = false;
|
||||
if ( secondariesAndPrimary[idx]->GetKineticEnergy() > leadingEnergy )
|
||||
{
|
||||
leadingEnergy = secondariesAndPrimary[idx]->GetKineticEnergy();
|
||||
leadingIDX = idx;
|
||||
}
|
||||
leadingEnergy = secondariesAndPrimary[idx]->GetKineticEnergy();
|
||||
leadingIDX = idx;
|
||||
}
|
||||
}
|
||||
survivingMap[ secondariesAndPrimary[leadingIDX] ] = true; // -- tag as surviving the leading particle
|
||||
|
||||
|
||||
|
||||
// -- now make track vectors of given types ( choose type = abs(PDG) ), excluding the leading particle:
|
||||
std::map < G4int, std::vector< G4Track* > > typesAndTracks;
|
||||
for ( size_t idx = 0; idx < secondariesAndPrimary.size(); idx++ )
|
||||
for ( std::size_t idx = 0; idx < secondariesAndPrimary.size(); ++idx )
|
||||
{
|
||||
if ( idx == leadingIDX ) continue; // -- excludes the leading particle
|
||||
auto currentTrack = secondariesAndPrimary[idx];
|
||||
auto GROUP = std::abs( currentTrack->GetDefinition()->GetPDGEncoding() ); // -- merge particles and anti-particles in the same category -- §§ this might be proposed as an option in future
|
||||
if ( currentTrack->GetDefinition()->GetBaryonNumber() >= 2 )
|
||||
GROUP = -1000; // -- merge all baryons above proton/neutron in one same group -- §§ might be proposed as an option too
|
||||
|
||||
if ( typesAndTracks.find( GROUP ) == typesAndTracks.cend() )
|
||||
{
|
||||
if ( idx == leadingIDX ) continue; // -- excludes the leading particle
|
||||
auto currentTrack = secondariesAndPrimary[idx];
|
||||
auto GROUP = std::abs( currentTrack->GetDefinition()->GetPDGEncoding() ); // -- merge particles and anti-particles in the same category -- §§ this might be proposed as an option in future
|
||||
if ( currentTrack->GetDefinition()->GetBaryonNumber() >= 2 ) GROUP = -1000; // -- merge all baryons above proton/neutron in one same group -- §§ might be proposed as an option too
|
||||
|
||||
if ( typesAndTracks.find( GROUP ) == typesAndTracks.end() )
|
||||
{
|
||||
std::vector< G4Track* > v;
|
||||
v.push_back( currentTrack );
|
||||
typesAndTracks[ GROUP ] = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
typesAndTracks[ GROUP ].push_back( currentTrack );
|
||||
}
|
||||
std::vector< G4Track* > v;
|
||||
v.push_back( currentTrack );
|
||||
typesAndTracks[ GROUP ] = std::move(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
typesAndTracks[ GROUP ].push_back( currentTrack );
|
||||
}
|
||||
}
|
||||
// -- and on these vectors, randomly select the surviving particles:
|
||||
// ---- randomly select one surviving track per species
|
||||
// ---- for this surviving track, further apply a Russian roulette
|
||||
G4int nSecondaries = 0; // -- the number of secondaries to be returned
|
||||
for ( auto& typeAndTrack : typesAndTracks )
|
||||
{
|
||||
std::size_t nTracks = (typeAndTrack.second).size();
|
||||
G4Track* keptTrack;
|
||||
// -- select one track among ones in same species:
|
||||
if ( nTracks > 1 )
|
||||
{
|
||||
size_t nTracks = (typeAndTrack.second).size();
|
||||
G4Track* keptTrack;
|
||||
// -- select one track among ones in same species:
|
||||
if ( nTracks > 1 )
|
||||
{
|
||||
auto keptTrackIDX = G4RandFlat::shootInt( nTracks );
|
||||
keptTrack = (typeAndTrack.second)[keptTrackIDX];
|
||||
keptTrack->SetWeight( keptTrack->GetWeight() * nTracks );
|
||||
}
|
||||
else
|
||||
{
|
||||
keptTrack = (typeAndTrack.second)[0];
|
||||
}
|
||||
// -- further apply a Russian Roulette on it:
|
||||
G4bool keepTrack = false;
|
||||
if ( fRussianRouletteKillingProbability > 0.0 )
|
||||
{
|
||||
if ( G4UniformRand() > fRussianRouletteKillingProbability )
|
||||
{
|
||||
keptTrack->SetWeight( keptTrack->GetWeight() / (1. - fRussianRouletteKillingProbability) );
|
||||
keepTrack = true;
|
||||
}
|
||||
}
|
||||
else keepTrack = true;
|
||||
if ( keepTrack )
|
||||
{
|
||||
survivingMap[ keptTrack ] = true;
|
||||
if ( keptTrack != finalStatePrimary ) nSecondaries++;
|
||||
}
|
||||
auto keptTrackIDX = G4RandFlat::shootInt( nTracks );
|
||||
keptTrack = (typeAndTrack.second)[keptTrackIDX];
|
||||
keptTrack->SetWeight( keptTrack->GetWeight() * nTracks );
|
||||
}
|
||||
else
|
||||
{
|
||||
keptTrack = (typeAndTrack.second)[0];
|
||||
}
|
||||
// -- further apply a Russian Roulette on it:
|
||||
G4bool keepTrack = false;
|
||||
if ( fRussianRouletteKillingProbability > 0.0 )
|
||||
{
|
||||
if ( G4UniformRand() > fRussianRouletteKillingProbability )
|
||||
{
|
||||
keptTrack->SetWeight( keptTrack->GetWeight() / (1. - fRussianRouletteKillingProbability) );
|
||||
keepTrack = true;
|
||||
}
|
||||
}
|
||||
else keepTrack = true;
|
||||
if ( keepTrack )
|
||||
{
|
||||
survivingMap[ keptTrack ] = true;
|
||||
if ( keptTrack != finalStatePrimary ) ++nSecondaries;
|
||||
}
|
||||
}
|
||||
// -- and if the leading is not the primary, we have to count it in nSecondaries:
|
||||
if ( secondariesAndPrimary[leadingIDX] != finalStatePrimary ) nSecondaries++;
|
||||
if ( secondariesAndPrimary[leadingIDX] != finalStatePrimary ) ++nSecondaries;
|
||||
|
||||
// -- verify if the primary is still alive or not after above selection:
|
||||
G4bool primarySurvived = false;
|
||||
if ( finalStatePrimary ) primarySurvived = survivingMap[ finalStatePrimary ];
|
||||
if ( finalStatePrimary )
|
||||
primarySurvived = survivingMap[ finalStatePrimary ];
|
||||
|
||||
|
||||
// -- fill the trimmed particle change:
|
||||
// ---- fill for the primary:
|
||||
fParticleChange.Initialize(*track);
|
||||
if ( primarySurvived )
|
||||
{
|
||||
fParticleChange.ProposeTrackStatus ( wrappedProcessParticleChange->GetTrackStatus() );
|
||||
fParticleChange.ProposeParentWeight ( finalStatePrimary->GetWeight() ); // -- take weight from copy of primary, this one being updated in the random selection loop above
|
||||
fParticleChange.ProposeEnergy ( finalStatePrimary->GetKineticEnergy() );
|
||||
fParticleChange.ProposeMomentumDirection ( finalStatePrimary->GetMomentumDirection() );
|
||||
}
|
||||
{
|
||||
fParticleChange.ProposeTrackStatus ( wrappedProcessParticleChange->GetTrackStatus() );
|
||||
fParticleChange.ProposeParentWeight ( finalStatePrimary->GetWeight() );
|
||||
// -- take weight from copy of primary, this one being updated in the
|
||||
// random selection loop above
|
||||
fParticleChange.ProposeEnergy ( finalStatePrimary->GetKineticEnergy() );
|
||||
fParticleChange.ProposeMomentumDirection ( finalStatePrimary->GetMomentumDirection() );
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleChange.ProposeTrackStatus ( fStopAndKill );
|
||||
fParticleChange.ProposeParentWeight( 0.0 );
|
||||
fParticleChange.ProposeEnergy ( 0.0 );
|
||||
{
|
||||
fParticleChange.ProposeTrackStatus ( fStopAndKill );
|
||||
fParticleChange.ProposeParentWeight( 0.0 );
|
||||
fParticleChange.ProposeEnergy ( 0.0 );
|
||||
}
|
||||
// -- fill for surviving secondaries:
|
||||
fParticleChange.SetSecondaryWeightByProcess(true);
|
||||
fParticleChange.SetNumberOfSecondaries(nSecondaries);
|
||||
// ---- note we loop up to on the number of secondaries, which excludes the primary, last in secondariesAndPrimary vector:
|
||||
////// G4cout << callingProcess->GetProcessName() << " :";
|
||||
for ( auto idx = 0 ; idx < wrappedProcessParticleChange->GetNumberOfSecondaries() ; idx++ )
|
||||
{
|
||||
G4Track* secondary = secondariesAndPrimary[idx];
|
||||
// ********************
|
||||
//// if ( !survivingMap[ secondary ] ) G4cout << " [";
|
||||
///// else G4cout << " ";
|
||||
///// G4cout << secondary->GetDefinition()->GetParticleName() << " " << secondary->GetKineticEnergy();
|
||||
///// if ( !survivingMap[ secondary ] ) G4cout << "]";
|
||||
//// if ( secondary == secondariesAndPrimary[leadingIDX] ) G4cout << " ***";
|
||||
// ******************
|
||||
if ( survivingMap[ secondary ] ) fParticleChange.AddSecondary( secondary );
|
||||
else delete secondary;
|
||||
}
|
||||
for ( auto idx = 0 ; idx < wrappedProcessParticleChange->GetNumberOfSecondaries() ; ++idx )
|
||||
{
|
||||
G4Track* secondary = secondariesAndPrimary[idx];
|
||||
// ********************
|
||||
//// if ( !survivingMap[ secondary ] ) G4cout << " [";
|
||||
///// else G4cout << " ";
|
||||
///// G4cout << secondary->GetDefinition()->GetParticleName() << " " << secondary->GetKineticEnergy();
|
||||
///// if ( !survivingMap[ secondary ] ) G4cout << "]";
|
||||
//// if ( secondary == secondariesAndPrimary[leadingIDX] ) G4cout << " ***";
|
||||
// ******************
|
||||
if ( survivingMap[ secondary ] )
|
||||
fParticleChange.AddSecondary( secondary );
|
||||
else
|
||||
delete secondary;
|
||||
}
|
||||
/// G4cout << G4endl;
|
||||
|
||||
// -- clean the wrapped process particle change:
|
||||
@@ -217,5 +223,4 @@ G4VParticleChange* G4BOptnLeadingParticle::ApplyFinalStateBiasing( const G4Biasi
|
||||
|
||||
// -- finally, returns the trimmed particle change:
|
||||
return &fParticleChange;
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptrForceCollision
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BOptrForceCollision.hh"
|
||||
#include "G4BOptrForceCollisionTrackData.hh"
|
||||
#include "G4BiasingProcessInterface.hh"
|
||||
@@ -42,104 +45,96 @@
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
// -- §§ consider calling other constructor, thanks to C++11
|
||||
G4BOptrForceCollision::G4BOptrForceCollision(G4String particleName, G4String name)
|
||||
// -- Consider calling other constructor, thanks to C++11
|
||||
G4BOptrForceCollision::
|
||||
G4BOptrForceCollision(const G4String& particleName,
|
||||
const G4String& name)
|
||||
: G4VBiasingOperator(name),
|
||||
fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision")),
|
||||
fCurrentTrack(nullptr),
|
||||
fCurrentTrackData(nullptr),
|
||||
fInitialTrackWeight(-1.0),
|
||||
fSetup(true)
|
||||
fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision"))
|
||||
{
|
||||
fSharedForceInteractionOperation = new G4BOptnForceCommonTruncatedExp("SharedForceInteraction");
|
||||
fCloningOperation = new G4BOptnCloning("Cloning");
|
||||
fCloningOperation = new G4BOptnCloning("Cloning");
|
||||
fParticleToBias = G4ParticleTable::GetParticleTable()->FindParticle(particleName);
|
||||
|
||||
if ( fParticleToBias == 0 )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Particle `" << particleName << "' not found !" << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::G4BOptrForceCollision(...)",
|
||||
"BIAS.GEN.07",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
if ( fParticleToBias == nullptr )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Particle `" << particleName << "' not found !" << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::G4BOptrForceCollision(...)",
|
||||
"BIAS.GEN.07", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4BOptrForceCollision::G4BOptrForceCollision(const G4ParticleDefinition* particle, G4String name)
|
||||
G4BOptrForceCollision::
|
||||
G4BOptrForceCollision(const G4ParticleDefinition* particle,
|
||||
const G4String& name)
|
||||
: G4VBiasingOperator(name),
|
||||
fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision")),
|
||||
fCurrentTrack(nullptr),
|
||||
fCurrentTrackData(nullptr),
|
||||
fInitialTrackWeight(-1.0),
|
||||
fSetup(true)
|
||||
fForceCollisionModelID(G4PhysicsModelCatalog::GetModelID("model_GenBiasForceCollision"))
|
||||
{
|
||||
fSharedForceInteractionOperation = new G4BOptnForceCommonTruncatedExp("SharedForceInteraction");
|
||||
fCloningOperation = new G4BOptnCloning("Cloning");
|
||||
fParticleToBias = particle;
|
||||
fCloningOperation = new G4BOptnCloning("Cloning");
|
||||
fParticleToBias = particle;
|
||||
}
|
||||
|
||||
|
||||
G4BOptrForceCollision::~G4BOptrForceCollision()
|
||||
{
|
||||
for ( std::map< const G4BiasingProcessInterface*, G4BOptnForceFreeFlight* >::iterator it = fFreeFlightOperations.begin() ;
|
||||
it != fFreeFlightOperations.end() ;
|
||||
it++ ) delete (*it).second;
|
||||
for ( auto it = fFreeFlightOperations.cbegin();
|
||||
it != fFreeFlightOperations.cend(); ++it )
|
||||
{
|
||||
delete (*it).second;
|
||||
}
|
||||
delete fSharedForceInteractionOperation;
|
||||
delete fCloningOperation;
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::Configure()
|
||||
{
|
||||
// -- build free flight operations:
|
||||
ConfigureForWorker();
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::ConfigureForWorker()
|
||||
{
|
||||
// -- start by remembering processes under biasing, and create needed biasing operations:
|
||||
// -- start by remembering processes under biasing,
|
||||
// and create needed biasing operations:
|
||||
if ( fSetup )
|
||||
{
|
||||
const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
|
||||
const G4BiasingProcessSharedData* interfaceProcessSharedData = G4BiasingProcessInterface::GetSharedData( processManager );
|
||||
if ( interfaceProcessSharedData ) // -- sharedData tested, as is can happen a user attaches an operator
|
||||
// -- to a volume but without defining BiasingProcessInterface processes.
|
||||
{
|
||||
const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
|
||||
const G4BiasingProcessSharedData* interfaceProcessSharedData = G4BiasingProcessInterface::GetSharedData( processManager );
|
||||
if ( interfaceProcessSharedData ) // -- sharedData tested, as is can happen a user attaches an operator
|
||||
// -- to a volume but without defining BiasingProcessInterface processes.
|
||||
{
|
||||
for ( size_t i = 0 ; i < (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces()).size(); i++ )
|
||||
{
|
||||
const G4BiasingProcessInterface* wrapperProcess =
|
||||
(interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces())[i];
|
||||
G4String operationName = "FreeFlight-"+wrapperProcess->GetWrappedProcess()->GetProcessName();
|
||||
fFreeFlightOperations[wrapperProcess] = new G4BOptnForceFreeFlight(operationName);
|
||||
}
|
||||
}
|
||||
fSetup = false;
|
||||
for ( std::size_t i = 0 ; i < (interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces()).size(); ++i )
|
||||
{
|
||||
const G4BiasingProcessInterface* wrapperProcess =
|
||||
(interfaceProcessSharedData->GetPhysicsBiasingProcessInterfaces())[i];
|
||||
const G4String& operationName = "FreeFlight-"+wrapperProcess->GetWrappedProcess()->GetProcessName();
|
||||
fFreeFlightOperations[wrapperProcess] = new G4BOptnForceFreeFlight(operationName);
|
||||
}
|
||||
}
|
||||
fSetup = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::StartRun()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
G4VBiasingOperation* G4BOptrForceCollision::ProposeOccurenceBiasingOperation(const G4Track* track, const G4BiasingProcessInterface* callingProcess)
|
||||
G4VBiasingOperation*
|
||||
G4BOptrForceCollision::ProposeOccurenceBiasingOperation(const G4Track* track,
|
||||
const G4BiasingProcessInterface* callingProcess)
|
||||
{
|
||||
// -- does nothing if particle is not of requested type:
|
||||
if ( track->GetDefinition() != fParticleToBias ) return 0;
|
||||
if ( track->GetDefinition() != fParticleToBias ) return nullptr;
|
||||
|
||||
// -- trying to get auxiliary track data...
|
||||
if ( fCurrentTrackData == nullptr )
|
||||
{
|
||||
// ... and if the track has no aux. track data, it means its biasing is not started yet (note that cloning is to happen first):
|
||||
fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
|
||||
if ( fCurrentTrackData == nullptr ) return nullptr;
|
||||
}
|
||||
{
|
||||
// ... and if the track has no aux. track data, it means its biasing is not started yet (note that cloning is to happen first):
|
||||
fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
|
||||
if ( fCurrentTrackData == nullptr ) return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// -- Send force free flight to the callingProcess:
|
||||
// ------------------------------------------------
|
||||
// -- The track has been cloned in the previous step, it has now to be
|
||||
@@ -151,20 +146,19 @@ G4VBiasingOperation* G4BOptrForceCollision::ProposeOccurenceBiasingOperation(con
|
||||
// -- this last one being per process. The initial weight is common, and is
|
||||
// -- arbitrary asked to the first operation to take care of it.
|
||||
if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
|
||||
{
|
||||
G4BOptnForceFreeFlight* operation = fFreeFlightOperations[callingProcess];
|
||||
if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
|
||||
{
|
||||
G4BOptnForceFreeFlight* operation = fFreeFlightOperations[callingProcess];
|
||||
if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
|
||||
{
|
||||
// -- the initial track weight will be restored only by the first DoIt free flight:
|
||||
operation->ResetInitialTrackWeight(fInitialTrackWeight);
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
// -- the initial track weight will be restored only by the first DoIt free flight:
|
||||
operation->ResetInitialTrackWeight(fInitialTrackWeight);
|
||||
return operation;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Send force interaction operation to the callingProcess:
|
||||
// ----------------------------------------------------------
|
||||
@@ -172,84 +166,87 @@ G4VBiasingOperation* G4BOptrForceCollision::ProposeOccurenceBiasingOperation(con
|
||||
// -- generated (borned) earlier. This copy will make the forced
|
||||
// -- interaction in the volume.
|
||||
if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
|
||||
{
|
||||
// -- Remember if this calling process is the first of the physics wrapper in
|
||||
// -- the PostStepGPIL loop (using default argument of method below):
|
||||
G4bool isFirstPhysGPIL = callingProcess-> GetIsFirstPostStepGPILInterface();
|
||||
|
||||
// -- [*first process*] Initialize or update force interaction operation:
|
||||
if ( isFirstPhysGPIL )
|
||||
{
|
||||
// -- Remember if this calling process is the first of the physics wrapper in
|
||||
// -- the PostStepGPIL loop (using default argument of method below):
|
||||
G4bool isFirstPhysGPIL = callingProcess-> GetIsFirstPostStepGPILInterface();
|
||||
// -- first step of cloned track, initialize the forced interaction operation:
|
||||
if ( track->GetCurrentStepNumber() == 1 )
|
||||
{
|
||||
fSharedForceInteractionOperation->Initialize( track );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fSharedForceInteractionOperation->GetInitialMomentum() != track->GetMomentum() )
|
||||
{
|
||||
// -- means that some other physics process, not under control of the forced interaction operation,
|
||||
// -- has occured, need to re-initialize the operation as distance to boundary has changed.
|
||||
// -- [ Note the re-initialization is only possible for a Markovian law. ]
|
||||
fSharedForceInteractionOperation->Initialize( track );
|
||||
}
|
||||
else
|
||||
{
|
||||
// -- means that some other non-physics process (biasing or not, like step limit), has occured,
|
||||
// -- but track conserves its momentum direction, only need to reduced the maximum distance for
|
||||
// -- forced interaction.
|
||||
// -- [ Note the update is only possible for a Markovian law. ]
|
||||
fSharedForceInteractionOperation->UpdateForStep( track->GetStep() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -- [*first process*] Initialize or update force interaction operation:
|
||||
if ( isFirstPhysGPIL )
|
||||
{
|
||||
// -- first step of cloned track, initialize the forced interaction operation:
|
||||
if ( track->GetCurrentStepNumber() == 1 ) fSharedForceInteractionOperation->Initialize( track );
|
||||
else
|
||||
{
|
||||
if ( fSharedForceInteractionOperation->GetInitialMomentum() != track->GetMomentum() )
|
||||
{
|
||||
// -- means that some other physics process, not under control of the forced interaction operation,
|
||||
// -- has occured, need to re-initialize the operation as distance to boundary has changed.
|
||||
// -- [ Note the re-initialization is only possible for a Markovian law. ]
|
||||
fSharedForceInteractionOperation->Initialize( track );
|
||||
}
|
||||
else
|
||||
{
|
||||
// -- means that some other non-physics process (biasing or not, like step limit), has occured,
|
||||
// -- but track conserves its momentum direction, only need to reduced the maximum distance for
|
||||
// -- forced interaction.
|
||||
// -- [ Note the update is only possible for a Markovian law. ]
|
||||
fSharedForceInteractionOperation->UpdateForStep( track->GetStep() );
|
||||
}
|
||||
}
|
||||
}
|
||||
// -- [*all processes*] Sanity check : it may happen in limit cases that distance to
|
||||
// -- out is zero, weight would be infinite in this case: abort forced interaction
|
||||
// -- and abandon biasing.
|
||||
if ( fSharedForceInteractionOperation->GetMaximumDistance() < DBL_MIN )
|
||||
{
|
||||
fCurrentTrackData->Reset();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// -- [*all processes*] Sanity check : it may happen in limit cases that distance to
|
||||
// -- out is zero, weight would be infinite in this case: abort forced interaction
|
||||
// -- and abandon biasing.
|
||||
if ( fSharedForceInteractionOperation->GetMaximumDistance() < DBL_MIN )
|
||||
{
|
||||
fCurrentTrackData->Reset();
|
||||
return 0;
|
||||
}
|
||||
// -- [* first process*] collect cross-sections and sample force law to determine interaction length
|
||||
// -- and winning process:
|
||||
if ( isFirstPhysGPIL )
|
||||
{
|
||||
// -- collect cross-sections:
|
||||
// -- ( Remember that the first of the G4BiasingProcessInterface triggers the update
|
||||
// -- of these cross-sections )
|
||||
const G4BiasingProcessSharedData* sharedData = callingProcess->GetSharedData();
|
||||
for ( std::size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size() ; ++i )
|
||||
{
|
||||
const G4BiasingProcessInterface* wrapperProcess = ( sharedData->GetPhysicsBiasingProcessInterfaces() )[i];
|
||||
G4double interactionLength = wrapperProcess->GetWrappedProcess()->GetCurrentInteractionLength();
|
||||
// -- keep only well defined cross-sections, other processes are ignored. These are not pathological cases
|
||||
// -- but cases where a threhold effect par example (eg pair creation) may be at play. (**!**)
|
||||
if ( interactionLength < DBL_MAX/10. )
|
||||
fSharedForceInteractionOperation->AddCrossSection( wrapperProcess->GetWrappedProcess(), 1.0/interactionLength );
|
||||
}
|
||||
// -- sample the shared law (interaction length, and winning process):
|
||||
if ( fSharedForceInteractionOperation->GetNumberOfSharing() > 0 )
|
||||
fSharedForceInteractionOperation->Sample();
|
||||
}
|
||||
|
||||
// -- [* first process*] collect cross-sections and sample force law to determine interaction length
|
||||
// -- and winning process:
|
||||
if ( isFirstPhysGPIL )
|
||||
{
|
||||
// -- collect cross-sections:
|
||||
// -- ( Remember that the first of the G4BiasingProcessInterface triggers the update
|
||||
// -- of these cross-sections )
|
||||
const G4BiasingProcessSharedData* sharedData = callingProcess->GetSharedData();
|
||||
for ( size_t i = 0 ; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size() ; i++ )
|
||||
{
|
||||
const G4BiasingProcessInterface* wrapperProcess = ( sharedData->GetPhysicsBiasingProcessInterfaces() )[i];
|
||||
G4double interactionLength = wrapperProcess->GetWrappedProcess()->GetCurrentInteractionLength();
|
||||
// -- keep only well defined cross-sections, other processes are ignored. These are not pathological cases
|
||||
// -- but cases where a threhold effect par example (eg pair creation) may be at play. (**!**)
|
||||
if ( interactionLength < DBL_MAX/10. )
|
||||
fSharedForceInteractionOperation->AddCrossSection( wrapperProcess->GetWrappedProcess(), 1.0/interactionLength );
|
||||
}
|
||||
// -- sample the shared law (interaction length, and winning process):
|
||||
if ( fSharedForceInteractionOperation->GetNumberOfSharing() > 0 ) fSharedForceInteractionOperation->Sample();
|
||||
}
|
||||
|
||||
// -- [*all processes*] Send operation for processes with well defined XS (see "**!**" above):
|
||||
G4VBiasingOperation* operationToReturn = nullptr;
|
||||
if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. ) operationToReturn = fSharedForceInteractionOperation;
|
||||
return operationToReturn;
|
||||
// -- [*all processes*] Send operation for processes with well defined XS (see "**!**" above):
|
||||
G4VBiasingOperation* operationToReturn = nullptr;
|
||||
if ( callingProcess->GetWrappedProcess()->GetCurrentInteractionLength() < DBL_MAX/10. )
|
||||
operationToReturn = fSharedForceInteractionOperation;
|
||||
return operationToReturn;
|
||||
|
||||
|
||||
} // -- end of "if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )"
|
||||
} // -- end of "if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )"
|
||||
|
||||
|
||||
// -- other cases here: particle appearing in the volume by some
|
||||
// -- previous interaction : we decide to not bias these.
|
||||
return 0;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
G4VBiasingOperation* G4BOptrForceCollision::ProposeNonPhysicsBiasingOperation(const G4Track* track,
|
||||
const G4BiasingProcessInterface* /* callingProcess */)
|
||||
G4VBiasingOperation* G4BOptrForceCollision::
|
||||
ProposeNonPhysicsBiasingOperation(const G4Track* track,
|
||||
const G4BiasingProcessInterface* /* callingProcess */)
|
||||
{
|
||||
if ( track->GetDefinition() != fParticleToBias ) return nullptr;
|
||||
|
||||
@@ -259,39 +256,41 @@ G4VBiasingOperation* G4BOptrForceCollision::ProposeNonPhysicsBiasingOperation(co
|
||||
// -- where the weight will be restored with proper weight for free flight
|
||||
// -- - the clone will be forced to interact in the volume.
|
||||
if ( track->GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary ) // -- §§§ extent to case of a track shoot on the boundary ?
|
||||
{
|
||||
// -- check that track is free of undergoing biasing scheme ( no biasing data, or no active active )
|
||||
// -- Get possible track data:
|
||||
fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
|
||||
if ( fCurrentTrackData != nullptr )
|
||||
{
|
||||
// -- check that track is free of undergoing biasing scheme ( no biasing data, or no active active )
|
||||
// -- Get possible track data:
|
||||
fCurrentTrackData = (G4BOptrForceCollisionTrackData*)(track->GetAuxiliaryTrackInformation(fForceCollisionModelID));
|
||||
if ( fCurrentTrackData != nullptr )
|
||||
{
|
||||
if ( fCurrentTrackData->IsFreeFromBiasing() )
|
||||
{
|
||||
// -- takes "ownership" (some track data created before, left free, reuse it):
|
||||
fCurrentTrackData->fForceCollisionOperator = this ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// §§§ Would something be really wrong in this case ? Could this be that a process made a zero step ?
|
||||
}
|
||||
}
|
||||
if ( fCurrentTrackData->IsFreeFromBiasing() )
|
||||
{
|
||||
// -- takes "ownership" (some track data created before, left free, reuse it):
|
||||
fCurrentTrackData->fForceCollisionOperator = this ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fCurrentTrackData = new G4BOptrForceCollisionTrackData( this );
|
||||
track->SetAuxiliaryTrackInformation(fForceCollisionModelID, fCurrentTrackData);
|
||||
}
|
||||
fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeCloned;
|
||||
fInitialTrackWeight = track->GetWeight();
|
||||
fCloningOperation->SetCloneWeights(0.0, fInitialTrackWeight);
|
||||
return fCloningOperation;
|
||||
{
|
||||
// Would something be really wrong in this case ?
|
||||
// Could this be that a process made a zero step ?
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fCurrentTrackData = new G4BOptrForceCollisionTrackData( this );
|
||||
track->SetAuxiliaryTrackInformation(fForceCollisionModelID, fCurrentTrackData);
|
||||
}
|
||||
fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeCloned;
|
||||
fInitialTrackWeight = track->GetWeight();
|
||||
fCloningOperation->SetCloneWeights(0.0, fInitialTrackWeight);
|
||||
|
||||
return fCloningOperation;
|
||||
}
|
||||
|
||||
// --
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
G4VBiasingOperation* G4BOptrForceCollision::ProposeFinalStateBiasingOperation(const G4Track*, const G4BiasingProcessInterface* callingProcess)
|
||||
G4VBiasingOperation* G4BOptrForceCollision::
|
||||
ProposeFinalStateBiasingOperation(const G4Track*,
|
||||
const G4BiasingProcessInterface* callingProcess)
|
||||
{
|
||||
// -- Propose at final state generation the same operation which was proposed at GPIL level,
|
||||
// -- (which is either the force free flight or the force interaction operation).
|
||||
@@ -299,132 +298,119 @@ G4VBiasingOperation* G4BOptrForceCollision::ProposeFinalStateBiasingOperation(co
|
||||
return callingProcess->GetCurrentOccurenceBiasingOperation();
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::StartTracking( const G4Track* track )
|
||||
{
|
||||
fCurrentTrack = track;
|
||||
fCurrentTrackData = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::EndTracking()
|
||||
{
|
||||
// -- check for consistency, operator should have cleaned the track:
|
||||
if ( fCurrentTrackData != nullptr )
|
||||
{
|
||||
if ( !fCurrentTrackData->IsFreeFromBiasing() )
|
||||
{
|
||||
if ( !fCurrentTrackData->IsFreeFromBiasing() )
|
||||
{
|
||||
if ( (fCurrentTrack->GetTrackStatus() == fStopAndKill) || (fCurrentTrack->GetTrackStatus() == fKillTrackAndSecondaries) )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Current track deleted while under biasing by " << GetName() << ". Will result in inconsistencies.";
|
||||
G4Exception(" G4BOptrForceCollision::EndTracking()",
|
||||
"BIAS.GEN.18",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( (fCurrentTrack->GetTrackStatus() == fStopAndKill)
|
||||
|| (fCurrentTrack->GetTrackStatus() == fKillTrackAndSecondaries) )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Current track deleted while under biasing by "
|
||||
<< GetName() << ". Will result in inconsistencies.";
|
||||
G4Exception(" G4BOptrForceCollision::EndTracking()",
|
||||
"BIAS.GEN.18", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::OperationApplied( const G4BiasingProcessInterface* callingProcess,
|
||||
G4BiasingAppliedCase BAC,
|
||||
G4VBiasingOperation* operationApplied,
|
||||
const G4VParticleChange* )
|
||||
void G4BOptrForceCollision::
|
||||
OperationApplied( const G4BiasingProcessInterface* callingProcess,
|
||||
G4BiasingAppliedCase BAC,
|
||||
G4VBiasingOperation* operationApplied,
|
||||
const G4VParticleChange* )
|
||||
{
|
||||
|
||||
if ( fCurrentTrackData == nullptr )
|
||||
{
|
||||
if ( BAC != BAC_None )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.1",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeCloned )
|
||||
{
|
||||
fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeFreeFlight;
|
||||
auto cloneData = new G4BOptrForceCollisionTrackData( this );
|
||||
cloneData->fForceCollisionState = ForceCollisionState::toBeForced;
|
||||
fCloningOperation->GetCloneTrack()->SetAuxiliaryTrackInformation(fForceCollisionModelID, cloneData);
|
||||
}
|
||||
else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
|
||||
{
|
||||
if ( fFreeFlightOperations[callingProcess]->OperationComplete() ) fCurrentTrackData->Reset(); // -- off biasing for this track
|
||||
}
|
||||
else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
|
||||
{
|
||||
if ( operationApplied != fSharedForceInteractionOperation )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.2",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
if ( fSharedForceInteractionOperation->GetInteractionOccured() )
|
||||
{
|
||||
if ( operationApplied != fSharedForceInteractionOperation )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.3",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fCurrentTrackData->fForceCollisionState != ForceCollisionState::free )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.4",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4BOptrForceCollision::OperationApplied( const G4BiasingProcessInterface* /*callingProcess*/, G4BiasingAppliedCase /*biasingCase*/,
|
||||
G4VBiasingOperation* /*occurenceOperationApplied*/, G4double /*weightForOccurenceInteraction*/,
|
||||
G4VBiasingOperation* finalStateOperationApplied, const G4VParticleChange* /*particleChangeProduced*/ )
|
||||
{
|
||||
|
||||
if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
|
||||
{
|
||||
if ( finalStateOperationApplied != fSharedForceInteractionOperation )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.5",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
if ( fSharedForceInteractionOperation->GetInteractionOccured() ) fCurrentTrackData->Reset(); // -- off biasing for this track
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( BAC != BAC_None )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.6",
|
||||
JustWarning,
|
||||
ed);
|
||||
"BIAS.GEN.20.1", JustWarning, ed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeCloned )
|
||||
{
|
||||
fCurrentTrackData->fForceCollisionState = ForceCollisionState::toBeFreeFlight;
|
||||
auto cloneData = new G4BOptrForceCollisionTrackData( this );
|
||||
cloneData->fForceCollisionState = ForceCollisionState::toBeForced;
|
||||
fCloningOperation->GetCloneTrack()->SetAuxiliaryTrackInformation(fForceCollisionModelID, cloneData);
|
||||
}
|
||||
else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeFreeFlight )
|
||||
{
|
||||
if ( fFreeFlightOperations[callingProcess]->OperationComplete() )
|
||||
fCurrentTrackData->Reset(); // -- off biasing for this track
|
||||
}
|
||||
else if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
|
||||
{
|
||||
if ( operationApplied != fSharedForceInteractionOperation )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.2", JustWarning, ed);
|
||||
}
|
||||
if ( fSharedForceInteractionOperation->GetInteractionOccured() )
|
||||
{
|
||||
if ( operationApplied != fSharedForceInteractionOperation )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.3", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fCurrentTrackData->fForceCollisionState != ForceCollisionState::free )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.4", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4BOptrForceCollision::
|
||||
OperationApplied( const G4BiasingProcessInterface* /*callingProcess*/,
|
||||
G4BiasingAppliedCase /*biasingCase*/,
|
||||
G4VBiasingOperation* /*occurenceOperationApplied*/,
|
||||
G4double /*weightForOccurenceInteraction*/,
|
||||
G4VBiasingOperation* finalStateOperationApplied,
|
||||
const G4VParticleChange* /*particleChangeProduced*/ )
|
||||
{
|
||||
if ( fCurrentTrackData->fForceCollisionState == ForceCollisionState::toBeForced )
|
||||
{
|
||||
if ( finalStateOperationApplied != fSharedForceInteractionOperation )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.5", JustWarning, ed);
|
||||
}
|
||||
if ( fSharedForceInteractionOperation->GetInteractionOccured() )
|
||||
fCurrentTrackData->Reset(); // -- off biasing for this track
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Internal inconsistency : please submit bug report. " << G4endl;
|
||||
G4Exception(" G4BOptrForceCollision::OperationApplied(...)",
|
||||
"BIAS.GEN.20.6", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,16 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BOptrForceCollisionTrackData
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BOptrForceCollisionTrackData.hh"
|
||||
#include "G4BOptrForceCollision.hh"
|
||||
|
||||
G4BOptrForceCollisionTrackData::G4BOptrForceCollisionTrackData( const G4BOptrForceCollision* optr )
|
||||
: G4VAuxiliaryTrackInformation(),
|
||||
fForceCollisionOperator( optr )
|
||||
G4BOptrForceCollisionTrackData::
|
||||
G4BOptrForceCollisionTrackData( const G4BOptrForceCollision* optr )
|
||||
: G4VAuxiliaryTrackInformation(),
|
||||
fForceCollisionOperator( optr )
|
||||
{
|
||||
fForceCollisionState = ForceCollisionState::free;
|
||||
}
|
||||
@@ -36,25 +40,35 @@ G4BOptrForceCollisionTrackData::G4BOptrForceCollisionTrackData( const G4BOptrFor
|
||||
G4BOptrForceCollisionTrackData::~G4BOptrForceCollisionTrackData()
|
||||
{
|
||||
if ( fForceCollisionState != ForceCollisionState::free )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Track deleted while under G4BOptrForceCollision biasing scheme of operator `";
|
||||
if ( fForceCollisionOperator == nullptr ) ed << "(none)"; else ed << fForceCollisionOperator->GetName();
|
||||
ed <<"'. Will result in inconsistencies.";
|
||||
G4Exception(" G4BOptrForceCollisionTrackData::~G4BOptrForceCollisionTrackData()",
|
||||
"BIAS.GEN.19",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Track deleted while under G4BOptrForceCollision biasing scheme of operator `";
|
||||
if ( fForceCollisionOperator == nullptr )
|
||||
ed << "(none)";
|
||||
else
|
||||
ed << fForceCollisionOperator->GetName();
|
||||
ed <<"'. Will result in inconsistencies.";
|
||||
G4Exception(" G4BOptrForceCollisionTrackData::~G4BOptrForceCollisionTrackData()",
|
||||
"BIAS.GEN.19", JustWarning, ed);
|
||||
}
|
||||
}
|
||||
|
||||
void G4BOptrForceCollisionTrackData::Print() const
|
||||
{
|
||||
G4cout << " G4BOptrForceCollisionTrackData object : " << this << G4endl;
|
||||
G4cout << " Force collision operator : "; if ( fForceCollisionOperator == nullptr ) G4cout << "(none)"; else G4cout << fForceCollisionOperator->GetName(); G4cout << G4endl;
|
||||
G4cout << " Force collision operator : ";
|
||||
if ( fForceCollisionOperator == nullptr )
|
||||
{
|
||||
G4cout << "(none)";
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << fForceCollisionOperator->GetName();
|
||||
}
|
||||
G4cout << G4endl;
|
||||
G4cout << " Force collision state : ";
|
||||
switch ( fForceCollisionState )
|
||||
{
|
||||
{
|
||||
case ForceCollisionState::free :
|
||||
G4cout << "free from biasing ";
|
||||
break;
|
||||
@@ -69,6 +83,6 @@ void G4BOptrForceCollisionTrackData::Print() const
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
G4cout << G4endl;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BiasingHelper
|
||||
// --------------------------------------------------------------------
|
||||
#include "G4BiasingHelper.hh"
|
||||
|
||||
#include "G4ProcessManager.hh"
|
||||
@@ -30,23 +32,23 @@
|
||||
#include "G4ParallelGeometriesLimiterProcess.hh"
|
||||
|
||||
G4bool G4BiasingHelper::ActivatePhysicsBiasing(G4ProcessManager* pmanager,
|
||||
G4String physicsProcessToBias,
|
||||
G4String wrappedName)
|
||||
const G4String& physicsProcessToBias,
|
||||
const G4String& wrappedName)
|
||||
{
|
||||
G4VProcess* physicsProcess(0);
|
||||
|
||||
G4ProcessVector* vprocess = pmanager->GetProcessList();
|
||||
for (G4int ip = 0 ; ip < (G4int)vprocess->size() ; ++ip)
|
||||
for (auto ip = 0 ; ip < (G4int)vprocess->size() ; ++ip)
|
||||
{
|
||||
if ( (*vprocess)[ip]->GetProcessName() == physicsProcessToBias )
|
||||
{
|
||||
if ( (*vprocess)[ip]->GetProcessName() == physicsProcessToBias )
|
||||
{
|
||||
physicsProcess = (*vprocess)[ip];
|
||||
break;
|
||||
}
|
||||
physicsProcess = (*vprocess)[ip];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// -- process not found, return "false" to tell about failure
|
||||
if ( physicsProcess == 0 ) return false;
|
||||
if ( physicsProcess == nullptr ) return false;
|
||||
|
||||
// -- process is not a physics one, return "false" to tell about failure
|
||||
G4int processType = physicsProcess->GetProcessType();
|
||||
@@ -57,87 +59,86 @@ G4bool G4BiasingHelper::ActivatePhysicsBiasing(G4ProcessManager* pmanager,
|
||||
return false;
|
||||
|
||||
// -- prevent wrapper of wrapper...
|
||||
if ( dynamic_cast< G4BiasingProcessInterface* >( physicsProcess ) ) return false;
|
||||
if ( dynamic_cast< G4BiasingProcessInterface* >( physicsProcess ) )
|
||||
return false;
|
||||
|
||||
// -- remember process indeces:
|
||||
G4int atRestIndex = pmanager->GetProcessOrdering(physicsProcess, idxAtRest );
|
||||
G4int atRestIndex = pmanager->GetProcessOrdering(physicsProcess, idxAtRest);
|
||||
G4int alongStepIndex = pmanager->GetProcessOrdering(physicsProcess, idxAlongStep);
|
||||
G4int postStepIndex = pmanager->GetProcessOrdering(physicsProcess, idxPostStep );
|
||||
G4int postStepIndex = pmanager->GetProcessOrdering(physicsProcess, idxPostStep);
|
||||
|
||||
// -- now remove the physic process, that will be replaced by a wrapped version:
|
||||
G4VProcess* removed = pmanager->RemoveProcess(physicsProcess);
|
||||
if ( removed != physicsProcess )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Internal inconsistency in processes handling. Please report !" << G4endl;
|
||||
G4Exception("G4BiasingHelper::ActivatePhysicsBiasing(...)",
|
||||
"BIAS.GEN.01",
|
||||
FatalException,
|
||||
ed);
|
||||
}
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Internal inconsistency in processes handling. Please report !" << G4endl;
|
||||
G4Exception("G4BiasingHelper::ActivatePhysicsBiasing(...)",
|
||||
"BIAS.GEN.01", FatalException, ed);
|
||||
}
|
||||
|
||||
G4BiasingProcessInterface* biasingWrapper = new G4BiasingProcessInterface( physicsProcess,
|
||||
atRestIndex != ordInActive,
|
||||
alongStepIndex != ordInActive,
|
||||
postStepIndex != ordInActive,
|
||||
wrappedName);
|
||||
G4BiasingProcessInterface* biasingWrapper =
|
||||
new G4BiasingProcessInterface( physicsProcess,
|
||||
atRestIndex != ordInActive,
|
||||
alongStepIndex != ordInActive,
|
||||
postStepIndex != ordInActive,
|
||||
wrappedName );
|
||||
|
||||
if ( alongStepIndex == -1 ) alongStepIndex = ordDefault;
|
||||
|
||||
pmanager->AddProcess( biasingWrapper,
|
||||
atRestIndex,
|
||||
alongStepIndex,
|
||||
postStepIndex);
|
||||
pmanager->AddProcess( biasingWrapper, atRestIndex, alongStepIndex, postStepIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void G4BiasingHelper::ActivateNonPhysicsBiasing(G4ProcessManager* pmanager,
|
||||
G4String nonPhysicsProcessName )
|
||||
const G4String& nonPhysicsProcessName )
|
||||
{
|
||||
G4BiasingProcessInterface* biasingNonPhys(nullptr);
|
||||
if ( nonPhysicsProcessName == "" ) biasingNonPhys = new G4BiasingProcessInterface();
|
||||
else biasingNonPhys = new G4BiasingProcessInterface(nonPhysicsProcessName );
|
||||
pmanager->AddProcess( biasingNonPhys,
|
||||
ordInActive,
|
||||
ordInActive,
|
||||
ordDefault);
|
||||
if ( nonPhysicsProcessName == "" )
|
||||
biasingNonPhys = new G4BiasingProcessInterface();
|
||||
else
|
||||
biasingNonPhys = new G4BiasingProcessInterface(nonPhysicsProcessName );
|
||||
|
||||
pmanager->AddProcess( biasingNonPhys, ordInActive, ordInActive, ordDefault);
|
||||
}
|
||||
|
||||
G4ParallelGeometriesLimiterProcess* G4BiasingHelper::AddLimiterProcess(G4ProcessManager* pmanager, const G4String& processName)
|
||||
G4ParallelGeometriesLimiterProcess*
|
||||
G4BiasingHelper::AddLimiterProcess(G4ProcessManager* pmanager,
|
||||
const G4String& processName)
|
||||
{
|
||||
G4ParallelGeometriesLimiterProcess* toReturn = nullptr;
|
||||
|
||||
G4ProcessVector* processList = pmanager->GetProcessList();
|
||||
G4bool noInstance = true;
|
||||
for (G4int i = 0 ; i < (G4int)processList->size() ; ++i)
|
||||
for (auto i = 0 ; i < (G4int)processList->size() ; ++i)
|
||||
{
|
||||
G4VProcess* process = (*processList)[i];
|
||||
if ( dynamic_cast< G4ParallelGeometriesLimiterProcess* >( process ) )
|
||||
{
|
||||
G4VProcess* process = (*processList)[i];
|
||||
if ( dynamic_cast< G4ParallelGeometriesLimiterProcess* >( process ) )
|
||||
{
|
||||
noInstance = false;
|
||||
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;
|
||||
}
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Trying to re-add a G4ParallelGeometriesLimiterProcess process \n"
|
||||
<< "to the process manager for '"
|
||||
<< pmanager->GetParticleType()->GetParticleName()
|
||||
<< " (PDG : " << pmanager->GetParticleType()->GetPDGEncoding() << " )"
|
||||
<< " while one is already present." << G4endl;
|
||||
G4Exception("G4BiasingHelper::AddBiasingProcessLimiter()",
|
||||
"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 );
|
||||
{
|
||||
G4ParallelGeometriesLimiterProcess* biasingLimiter = new G4ParallelGeometriesLimiterProcess(processName);
|
||||
pmanager->AddProcess ( biasingLimiter );
|
||||
pmanager->SetProcessOrderingToSecond( biasingLimiter, idxAlongStep );
|
||||
pmanager->SetProcessOrderingToLast ( biasingLimiter, idxPostStep );
|
||||
|
||||
toReturn = biasingLimiter;
|
||||
}
|
||||
toReturn = biasingLimiter;
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BiasingProcessSharedData
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4BiasingProcessSharedData.hh"
|
||||
|
||||
G4MapCache< const G4ProcessManager*, G4BiasingProcessSharedData* > G4BiasingProcessSharedData::fSharedDataMap;
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ILawCommonTruncatedExp
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ILawCommonTruncatedExp.hh"
|
||||
#include "G4Track.hh"
|
||||
|
||||
@@ -30,7 +33,7 @@
|
||||
#include "G4BiasingProcessInterface.hh"
|
||||
|
||||
|
||||
G4ILawCommonTruncatedExp::G4ILawCommonTruncatedExp(G4String name)
|
||||
G4ILawCommonTruncatedExp::G4ILawCommonTruncatedExp(const G4String& name)
|
||||
: G4VBiasingInteractionLaw(name),
|
||||
fExpInteractionLaw("expLawFor"+name)
|
||||
{}
|
||||
@@ -38,7 +41,6 @@ G4ILawCommonTruncatedExp::G4ILawCommonTruncatedExp(G4String name)
|
||||
G4ILawCommonTruncatedExp::~G4ILawCommonTruncatedExp()
|
||||
{}
|
||||
|
||||
|
||||
G4double G4ILawCommonTruncatedExp::ComputeEffectiveCrossSectionAt(G4double distance) const
|
||||
{
|
||||
return fExpInteractionLaw.ComputeEffectiveCrossSectionAt( distance ) * fSelectedProcessXSfraction;
|
||||
@@ -49,17 +51,14 @@ G4double G4ILawCommonTruncatedExp::ComputeNonInteractionProbabilityAt(G4double d
|
||||
G4double niProba = fExpInteractionLaw.ComputeNonInteractionProbabilityAt( distance );
|
||||
|
||||
if ( niProba <= 0.0 )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative probability for `" << GetName() << "' p = " << niProba << " distance = " << distance << " !!! " << G4endl;
|
||||
G4Exception(" G4ILawCommonTruncatedExp::ComputeNonInteractionProbabilityAt(...)",
|
||||
"BIAS.GEN.08",
|
||||
JustWarning,
|
||||
ed);
|
||||
}
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative probability for `" << GetName() << "' p = " << niProba << " distance = " << distance << " !!! " << G4endl;
|
||||
G4Exception(" G4ILawCommonTruncatedExp::ComputeNonInteractionProbabilityAt(...)",
|
||||
"BIAS.GEN.08", JustWarning, ed);
|
||||
}
|
||||
|
||||
return niProba;
|
||||
|
||||
}
|
||||
|
||||
G4double G4ILawCommonTruncatedExp::SampleInteractionLength()
|
||||
|
||||
@@ -23,9 +23,12 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ILawForceFreeFlight
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ILawForceFreeFlight.hh"
|
||||
|
||||
G4ILawForceFreeFlight::G4ILawForceFreeFlight(G4String name)
|
||||
G4ILawForceFreeFlight::G4ILawForceFreeFlight(const G4String& name)
|
||||
: G4VBiasingInteractionLaw(name)
|
||||
{}
|
||||
|
||||
|
||||
@@ -23,17 +23,16 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ILawTruncatedExp
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ILawTruncatedExp.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Track.hh"
|
||||
|
||||
|
||||
G4ILawTruncatedExp::G4ILawTruncatedExp(G4String name)
|
||||
: G4VBiasingInteractionLaw(name),
|
||||
fMaximumDistance(0.0),
|
||||
fCrossSection(0.0),
|
||||
fCrossSectionDefined(false),
|
||||
fIsSingular(false)
|
||||
G4ILawTruncatedExp::G4ILawTruncatedExp(const G4String& name)
|
||||
: G4VBiasingInteractionLaw(name)
|
||||
{}
|
||||
|
||||
G4ILawTruncatedExp::~G4ILawTruncatedExp()
|
||||
@@ -42,45 +41,45 @@ G4ILawTruncatedExp::~G4ILawTruncatedExp()
|
||||
void G4ILawTruncatedExp::SetForceCrossSection(G4double crossSection)
|
||||
{
|
||||
if (crossSection < 0.0)
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::SetForceCrossSection(..)",
|
||||
"BIAS.GEN.09",
|
||||
JustWarning,
|
||||
"Cross-section value passed is negative. It is set to zero !");
|
||||
fIsSingular = true;
|
||||
crossSection = 0.0;
|
||||
}
|
||||
fIsSingular = false;
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::SetForceCrossSection(..)",
|
||||
"BIAS.GEN.09", JustWarning,
|
||||
"Cross-section value passed is negative. It is set to zero !");
|
||||
fIsSingular = true;
|
||||
crossSection = 0.0;
|
||||
}
|
||||
fIsSingular = false;
|
||||
fCrossSectionDefined = true;
|
||||
fCrossSection = crossSection;
|
||||
fCrossSection = crossSection;
|
||||
}
|
||||
|
||||
G4double G4ILawTruncatedExp::ComputeEffectiveCrossSectionAt(G4double distance) const
|
||||
G4double G4ILawTruncatedExp::
|
||||
ComputeEffectiveCrossSectionAt(G4double distance) const
|
||||
{
|
||||
if ( !fCrossSectionDefined )
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::ComputeEffectiveCrossSection(..)",
|
||||
"BIAS.GEN.10",
|
||||
JustWarning,
|
||||
"Cross-section value requested, but has not been defined yet. Assumes 0 !");
|
||||
// -- zero cross-section, returns the limit form of the effective cross-section:
|
||||
return 1.0 / ( fMaximumDistance - distance );
|
||||
}
|
||||
G4double denum = 1.0 - std::exp( -fCrossSection * ( fMaximumDistance - distance) );
|
||||
return fCrossSection / denum;
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::ComputeEffectiveCrossSection(..)",
|
||||
"BIAS.GEN.10", JustWarning,
|
||||
"Cross-section value requested, but has not been defined yet. Assumes 0 !");
|
||||
// -- zero cross-section, returns the limit form of the effective cross-section:
|
||||
return 1.0 / ( fMaximumDistance - distance );
|
||||
}
|
||||
|
||||
G4double denum = 1.0 - std::exp(-fCrossSection *(fMaximumDistance-distance));
|
||||
return fCrossSection/denum;
|
||||
}
|
||||
|
||||
G4double G4ILawTruncatedExp::ComputeNonInteractionProbabilityAt(G4double distance) const
|
||||
G4double G4ILawTruncatedExp::
|
||||
ComputeNonInteractionProbabilityAt(G4double distance) const
|
||||
{
|
||||
if (!fCrossSectionDefined)
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::ComputeNonInteractionProbability(..)",
|
||||
"BIAS.GEN.11",
|
||||
JustWarning,
|
||||
"Non interaction probability value requested, but cross section has not been defined yet. Assumes it to be 0 !");
|
||||
// -- return limit case of null cross-section:
|
||||
return 1.0 - distance / fMaximumDistance;
|
||||
}
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::ComputeNonInteractionProbability(..)",
|
||||
"BIAS.GEN.11", JustWarning,
|
||||
"Non interaction probability value requested, but cross section has not been defined yet. Assumes it to be 0 !");
|
||||
// -- return limit case of null cross-section:
|
||||
return 1.0 - distance / fMaximumDistance;
|
||||
}
|
||||
G4double num = 1.0 - std::exp( -fCrossSection*distance );
|
||||
G4double denum = 1.0 - std::exp( -fCrossSection*fMaximumDistance );
|
||||
return 1.0 - num/denum;
|
||||
@@ -89,34 +88,33 @@ G4double G4ILawTruncatedExp::ComputeNonInteractionProbabilityAt(G4double distanc
|
||||
G4double G4ILawTruncatedExp::SampleInteractionLength()
|
||||
{
|
||||
if ( !fCrossSectionDefined )
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::Sample(..)",
|
||||
"BIAS.GEN.12",
|
||||
JustWarning,
|
||||
"Trying to sample while cross-section is not defined, assuming 0 !");
|
||||
fInteractionDistance = G4UniformRand() * fMaximumDistance;
|
||||
return fInteractionDistance;
|
||||
}
|
||||
fInteractionDistance = -std::log(1.0 - G4UniformRand()* (1.0 - std::exp(-fCrossSection*fMaximumDistance)))/fCrossSection;
|
||||
{
|
||||
G4Exception("G4ILawTruncatedExp::Sample(..)",
|
||||
"BIAS.GEN.12", JustWarning,
|
||||
"Trying to sample while cross-section is not defined, assuming 0 !");
|
||||
fInteractionDistance = G4UniformRand() * fMaximumDistance;
|
||||
return fInteractionDistance;
|
||||
}
|
||||
fInteractionDistance = -std::log(1.0-G4UniformRand()*(1.0-std::exp(-fCrossSection*fMaximumDistance)))/fCrossSection;
|
||||
return fInteractionDistance;
|
||||
}
|
||||
|
||||
|
||||
G4double G4ILawTruncatedExp::UpdateInteractionLengthForStep(G4double truePathLength)
|
||||
G4double G4ILawTruncatedExp::
|
||||
UpdateInteractionLengthForStep(G4double truePathLength)
|
||||
{
|
||||
fInteractionDistance -= truePathLength;
|
||||
fMaximumDistance -= truePathLength;
|
||||
|
||||
if ( fInteractionDistance < 0 )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative number of interaction length for `" << GetName() << "' " << fInteractionDistance << ", set it to zero !" << G4endl;
|
||||
G4Exception("G4ILawTruncatedExp::UpdateInteractionLengthForStep(...)",
|
||||
"BIAS.GEN.13",
|
||||
JustWarning,
|
||||
"Trying to sample while cross-section is not defined, assuming 0 !");
|
||||
fInteractionDistance = 0.;
|
||||
}
|
||||
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative number of interaction length for `" << GetName()
|
||||
<< "' " << fInteractionDistance << ", set it to zero !" << G4endl;
|
||||
G4Exception("G4ILawTruncatedExp::UpdateInteractionLengthForStep(...)",
|
||||
"BIAS.GEN.13", JustWarning,
|
||||
"Trying to sample while cross-section is not defined, assuming 0 !");
|
||||
fInteractionDistance = 0.;
|
||||
}
|
||||
|
||||
return fInteractionDistance;
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4InteractionLawPhysical
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4InteractionLawPhysical.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4InteractionLawPhysical::G4InteractionLawPhysical(G4String name)
|
||||
: G4VBiasingInteractionLaw(name),
|
||||
fCrossSection(0.0),
|
||||
fCrossSectionDefined(false),
|
||||
fNumberOfInteractionLength(-1.0)
|
||||
G4InteractionLawPhysical::G4InteractionLawPhysical(const G4String& name)
|
||||
: G4VBiasingInteractionLaw(name)
|
||||
{}
|
||||
|
||||
G4InteractionLawPhysical::~G4InteractionLawPhysical()
|
||||
@@ -39,32 +39,37 @@ G4InteractionLawPhysical::~G4InteractionLawPhysical()
|
||||
void G4InteractionLawPhysical::SetPhysicalCrossSection(G4double crossSection)
|
||||
{
|
||||
if (crossSection < 0.0)
|
||||
{
|
||||
G4Exception("G4InteractionLawPhysical::SetPhysicalCrossSection(..)",
|
||||
"BIAS.GEN.14",
|
||||
JustWarning,
|
||||
"Cross-section value passed is negative. It is set to zero !");
|
||||
crossSection = 0.0;
|
||||
}
|
||||
{
|
||||
G4Exception("G4InteractionLawPhysical::SetPhysicalCrossSection(..)",
|
||||
"BIAS.GEN.14", JustWarning,
|
||||
"Cross-section value passed is negative. It is set to zero !");
|
||||
crossSection = 0.0;
|
||||
}
|
||||
fCrossSectionDefined = true;
|
||||
fCrossSection = crossSection;
|
||||
fCrossSection = crossSection;
|
||||
}
|
||||
|
||||
G4double G4InteractionLawPhysical::ComputeEffectiveCrossSectionAt(G4double) const
|
||||
G4double G4InteractionLawPhysical::
|
||||
ComputeEffectiveCrossSectionAt(G4double) const
|
||||
{
|
||||
if (!fCrossSectionDefined) G4Exception("G4InteractionLawPhysical::ComputeEffectiveCrossSection(..)",
|
||||
"BIAS.GEN.15",
|
||||
JustWarning,
|
||||
"Cross-section value requested, but has not been defined yet. Assumes 0 !");
|
||||
if (!fCrossSectionDefined)
|
||||
{
|
||||
G4Exception("G4InteractionLawPhysical::ComputeEffectiveCrossSection(..)",
|
||||
"BIAS.GEN.15", JustWarning,
|
||||
"Cross-section value requested, but has not been defined yet. Assumes 0 !");
|
||||
}
|
||||
return fCrossSection;
|
||||
}
|
||||
|
||||
G4double G4InteractionLawPhysical::ComputeNonInteractionProbabilityAt(G4double stepLength) const
|
||||
G4double G4InteractionLawPhysical::
|
||||
ComputeNonInteractionProbabilityAt(G4double stepLength) const
|
||||
{
|
||||
if (!fCrossSectionDefined) G4Exception("G4InteractionLawPhysical::ComputeNonInteractionProbability(..)",
|
||||
"BIAS.GEN.16",
|
||||
JustWarning,
|
||||
"Non interaction probabitlity value requested, but cross section has not been defined yet. Assumes it to be 0 !");
|
||||
if (!fCrossSectionDefined)
|
||||
{
|
||||
G4Exception("G4InteractionLawPhysical::ComputeNonInteractionProbability(..)",
|
||||
"BIAS.GEN.16", JustWarning,
|
||||
"Non interaction probabitlity value requested, but cross section has not been defined yet. Assumes it to be 0 !");
|
||||
}
|
||||
// -- allows zero cross-section case, by convention:
|
||||
if ( fCrossSection == 0.0 ) return 1.0;
|
||||
else return std::exp(-fCrossSection*stepLength);
|
||||
@@ -72,30 +77,31 @@ G4double G4InteractionLawPhysical::ComputeNonInteractionProbabilityAt(G4double s
|
||||
|
||||
G4double G4InteractionLawPhysical::SampleInteractionLength()
|
||||
{
|
||||
if ( !fCrossSectionDefined || fCrossSection < 0.0 ) G4Exception("G4InteractionLawPhysical::Sample(..)",
|
||||
"BIAS.GEN.17",
|
||||
FatalException,
|
||||
"Trying to sample while cross-section is not defined or < 0 !");
|
||||
if ( !fCrossSectionDefined || fCrossSection < 0.0 )
|
||||
{
|
||||
G4Exception("G4InteractionLawPhysical::Sample(..)",
|
||||
"BIAS.GEN.17", FatalException,
|
||||
"Trying to sample while cross-section is not defined or < 0 !");
|
||||
}
|
||||
if ( fCrossSection == 0.0 ) return DBL_MAX;
|
||||
|
||||
fNumberOfInteractionLength = -std::log( G4UniformRand() );
|
||||
fNumberOfInteractionLength = -std::log( G4UniformRand() );
|
||||
return fNumberOfInteractionLength/fCrossSection;
|
||||
}
|
||||
|
||||
|
||||
G4double G4InteractionLawPhysical::UpdateInteractionLengthForStep(G4double truePathLength)
|
||||
G4double G4InteractionLawPhysical::
|
||||
UpdateInteractionLengthForStep(G4double truePathLength)
|
||||
{
|
||||
fNumberOfInteractionLength -= truePathLength*fCrossSection;
|
||||
|
||||
if ( fNumberOfInteractionLength < 0 )
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative number of interaction length for `" << GetName() << "' " << fNumberOfInteractionLength << ", set it to zero !" << G4endl;
|
||||
G4Exception("G4InteractionLawPhysical::UpdateInteractionLengthForStep(...)",
|
||||
"BIAS.GEN.13",
|
||||
JustWarning,
|
||||
ed);
|
||||
fNumberOfInteractionLength = 0.;
|
||||
}
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << " Negative number of interaction length for `" << GetName()
|
||||
<< "' " << fNumberOfInteractionLength << ", set it to zero !" << G4endl;
|
||||
G4Exception("G4InteractionLawPhysical::UpdateInteractionLengthForStep(...)",
|
||||
"BIAS.GEN.13", JustWarning, ed);
|
||||
fNumberOfInteractionLength = 0.;
|
||||
}
|
||||
return fNumberOfInteractionLength/fCrossSection;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// G4ParallelGeometriesLimiterProcess
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "G4ParallelGeometriesLimiterProcess.hh"
|
||||
@@ -37,155 +36,133 @@
|
||||
|
||||
#include "G4SystemOfUnits.hh"
|
||||
|
||||
G4ParallelGeometriesLimiterProcess::G4ParallelGeometriesLimiterProcess(const G4String& processName) :
|
||||
G4VProcess(processName, fParallel),
|
||||
fParallelWorldSafety( 0.0 ),
|
||||
fIsTrackingTime ( false ),
|
||||
fFieldTrack ( '0' )
|
||||
G4ParallelGeometriesLimiterProcess::
|
||||
G4ParallelGeometriesLimiterProcess(const G4String& processName)
|
||||
: G4VProcess(processName, fParallel)
|
||||
{
|
||||
// -- Process Sub Type ? §§
|
||||
// -- Process Sub Type ?
|
||||
|
||||
fPathFinder = G4PathFinder::GetInstance();
|
||||
fPathFinder = G4PathFinder::GetInstance();
|
||||
fTransportationManager = G4TransportationManager::GetTransportationManager();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------
|
||||
// -- Add/Remove world volumes:
|
||||
// ----------------------------
|
||||
void G4ParallelGeometriesLimiterProcess::AddParallelWorld(const G4String& parallelWorldName)
|
||||
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(..)",
|
||||
"BIAS.GEN.21", JustWarning, ed, "Call ignored.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting( parallelWorldName );
|
||||
|
||||
// -- Fatal exception if requested world does not exist:
|
||||
if (newWorld == nullptr)
|
||||
{
|
||||
G4ExceptionDescription tellWhatIsWrong;
|
||||
tellWhatIsWrong << "Volume `" << parallelWorldName
|
||||
<< "' is not a parallel world nor the mass world volume."
|
||||
<< G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::SetWorldVolume(..)",
|
||||
"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()
|
||||
<< "': 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.");
|
||||
<< "': trying to add the world volume for tracking as a parallel world."
|
||||
<< G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::AddParallelWorld(..)",
|
||||
"BIAS.GEN.23", JustWarning, ed, "Call ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
|
||||
// -- Add parallel world, taking care it is not in the list yet:
|
||||
G4bool isNew = true;
|
||||
for ( auto knownWorld : fParallelWorlds )
|
||||
{
|
||||
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;
|
||||
}
|
||||
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(..)",
|
||||
"BIAS.GEN.24", JustWarning, ed, "Call ignored.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void G4ParallelGeometriesLimiterProcess::RemoveParallelWorld(const G4String& parallelWorldName)
|
||||
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(..)",
|
||||
"BIAS.GEN.25", JustWarning, ed, "Call ignored.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4VPhysicalVolume* newWorld = fTransportationManager->IsWorldExisting( parallelWorldName );
|
||||
if (newWorld == nullptr)
|
||||
{
|
||||
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.");
|
||||
<< "': trying to remove an inexisting parallel world '"
|
||||
<< parallelWorldName << "'." << G4endl;
|
||||
G4Exception("G4ParallelGeometriesLimiterProcess::RemoveParallelWorld(..)",
|
||||
"BIAS.GEN.26", 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 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// -- get position of world volume in list:
|
||||
std::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(..)",
|
||||
"BIAS.GEN.27", JustWarning, ed, "Call ignored.");
|
||||
return;
|
||||
}
|
||||
// -- remove from vector:
|
||||
fParallelWorlds.erase( fParallelWorlds.begin() + iWorld );
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// Start/End tracking:
|
||||
@@ -195,234 +172,246 @@ void G4ParallelGeometriesLimiterProcess::StartTracking(G4Track* track)
|
||||
fIsTrackingTime = true;
|
||||
|
||||
// -- fetch the navigators, their indeces, and activate:
|
||||
fParallelWorldNavigators .clear();
|
||||
fParallelWorldNavigators.clear();
|
||||
fParallelWorldNavigatorIndeces.clear();
|
||||
fParallelWorldSafeties .clear();
|
||||
fParallelWorldIsLimiting .clear();
|
||||
fParallelWorldWasLimiting .clear();
|
||||
fCurrentVolumes .clear();
|
||||
fPreviousVolumes .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 );
|
||||
}
|
||||
{
|
||||
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 ?
|
||||
// -- Does it work at this level, after "PrepareNewTrack" above ?
|
||||
for ( auto navigatorIndex : fParallelWorldNavigatorIndeces )
|
||||
{
|
||||
fPreviousVolumes.push_back( nullptr );
|
||||
fCurrentVolumes .push_back( fPathFinder->GetLocatedVolume( navigatorIndex ) );
|
||||
{
|
||||
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;
|
||||
for ( std::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)
|
||||
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:
|
||||
// -- consider switching pointers insteads of making copies of std::vector's:
|
||||
fParallelWorldWasLimiting = fParallelWorldIsLimiting;
|
||||
fPreviousVolumes = fCurrentVolumes;
|
||||
fPreviousVolumes = fCurrentVolumes;
|
||||
|
||||
// -- update volumes:
|
||||
size_t i = 0;
|
||||
for ( auto navigatorIndex : fParallelWorldNavigatorIndeces ) fCurrentVolumes[i++] = fPathFinder->GetLocatedVolume( navigatorIndex );
|
||||
std::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)
|
||||
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
|
||||
// -- 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;
|
||||
*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 G4FieldTrack* endTrack_MT = nullptr;
|
||||
if (!endTrack_MT) endTrack_MT = new G4FieldTrack ('0');
|
||||
G4FieldTrack& endTrack = *endTrack_MT;
|
||||
|
||||
static G4ThreadLocal ELimited *eLimited_G4MT_TLS_ = 0 ;
|
||||
if (!eLimited_G4MT_TLS_) eLimited_G4MT_TLS_ = new ELimited ;
|
||||
ELimited &eLimited = *eLimited_G4MT_TLS_;
|
||||
|
||||
static G4ThreadLocal ELimited* eLimited_MT = nullptr;
|
||||
if (!eLimited_MT) eLimited_MT = new ELimited;
|
||||
ELimited &eLimited = *eLimited_MT;
|
||||
|
||||
// -------------------
|
||||
// -- Update safeties:
|
||||
// -------------------
|
||||
if ( previousStepSize > 0.0 )
|
||||
{
|
||||
for ( auto& parallelWorldSafety : fParallelWorldSafeties )
|
||||
{
|
||||
for ( auto& parallelWorldSafety : fParallelWorldSafeties )
|
||||
{
|
||||
parallelWorldSafety -= previousStepSize;
|
||||
if ( parallelWorldSafety < 0. ) parallelWorldSafety = 0.0;
|
||||
fParallelWorldSafety = parallelWorldSafety < fParallelWorldSafety ? parallelWorldSafety : fParallelWorldSafety ;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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 ( std::size_t i = 0 ; i < fParallelWorldNavigatorIndeces.size() ; ++i )
|
||||
{
|
||||
// -- 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 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());
|
||||
|
||||
// -- update with smallest safety:
|
||||
fParallelWorldSafety = fParallelWorldSafeties[i] < fParallelWorldSafety ? fParallelWorldSafeties[i] : fParallelWorldSafety ;
|
||||
}
|
||||
if ( ( smallestReturnedStep < 0.0 ) || ( tmpReturnedStep <= smallestReturnedStep ) )
|
||||
{
|
||||
smallestReturnedStep = tmpReturnedStep;
|
||||
eLimitedForSmallestStep = eLimited;
|
||||
}
|
||||
|
||||
// -- 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
|
||||
}
|
||||
if (eLimited == kDoNot)
|
||||
{
|
||||
// -- Step not limited by this geometry
|
||||
fParallelWorldSafeties[i] = fParallelWorldNavigators[i]->ComputeSafety(endTrack.GetPosition());
|
||||
fParallelWorldIsLimiting[i] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fParallelWorldIsLimiting[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// -- and smallest safety among geometries:
|
||||
proposedSafety = fParallelWorldSafety ;
|
||||
// -- 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 )
|
||||
{
|
||||
// -- Expand to disable its selection in Step Manager comparison
|
||||
returnedStep = smallestReturnedStep* (1.0 + 1.0e-9);
|
||||
}
|
||||
|
||||
// -- and smallest safety among geometries:
|
||||
proposedSafety = fParallelWorldSafety ;
|
||||
}
|
||||
|
||||
// -- returns step length, and proposedSafety
|
||||
return returnedStep;
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4ParallelGeometriesLimiterProcess::AlongStepDoIt( const G4Track& track,
|
||||
const G4Step& )
|
||||
G4VParticleChange* G4ParallelGeometriesLimiterProcess::
|
||||
AlongStepDoIt( const G4Track& track, const G4Step& )
|
||||
{
|
||||
|
||||
fDummyParticleChange.Initialize(track);
|
||||
return &fDummyParticleChange;
|
||||
}
|
||||
|
||||
|
||||
void G4ParallelGeometriesLimiterProcess::SetProcessManager(const G4ProcessManager* mgr)
|
||||
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;
|
||||
if ( G4BiasingProcessSharedData::fSharedDataMap.Find(mgr) == G4BiasingProcessSharedData::fSharedDataMap.End() )
|
||||
{
|
||||
sharedData = new G4BiasingProcessSharedData( mgr );
|
||||
G4BiasingProcessSharedData::fSharedDataMap[mgr] = sharedData;
|
||||
}
|
||||
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);
|
||||
}
|
||||
{
|
||||
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 G4ParallelGeometriesLimiterProcess::
|
||||
GetParallelWorldIndex( const G4VPhysicalVolume* parallelWorld ) const
|
||||
{
|
||||
G4int toReturn = -1;
|
||||
G4int iWorld = 0;
|
||||
for ( auto world : fParallelWorlds )
|
||||
{
|
||||
if ( world == parallelWorld )
|
||||
{
|
||||
if ( world == parallelWorld )
|
||||
{
|
||||
toReturn = iWorld;
|
||||
break;
|
||||
}
|
||||
iWorld++;
|
||||
toReturn = iWorld;
|
||||
break;
|
||||
}
|
||||
++iWorld;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
G4int G4ParallelGeometriesLimiterProcess::GetParallelWorldIndex( G4String parallelWorldName ) const
|
||||
G4int G4ParallelGeometriesLimiterProcess::
|
||||
GetParallelWorldIndex( const G4String& parallelWorldName ) const
|
||||
{
|
||||
G4VPhysicalVolume* aWorld = fTransportationManager->IsWorldExisting( parallelWorldName ); // note aWorld might be nullptr
|
||||
G4VPhysicalVolume* aWorld = fTransportationManager->IsWorldExisting( parallelWorldName );
|
||||
// note aWorld might be nullptr
|
||||
return GetParallelWorldIndex( aWorld );
|
||||
}
|
||||
|
||||
|
||||
@@ -23,20 +23,19 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ParticleChangeForOccurenceBiasing
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ParticleChangeForOccurenceBiasing.hh"
|
||||
|
||||
G4ParticleChangeForOccurenceBiasing::G4ParticleChangeForOccurenceBiasing(G4String name)
|
||||
G4ParticleChangeForOccurenceBiasing::
|
||||
G4ParticleChangeForOccurenceBiasing(const G4String& name)
|
||||
: G4VParticleChange(),
|
||||
fName(name),
|
||||
fWrappedParticleChange(0),
|
||||
fOccurenceWeightForNonInteraction(-1.0),
|
||||
fOccurenceWeightForInteraction(-1.0)
|
||||
fName(name)
|
||||
{}
|
||||
|
||||
G4ParticleChangeForOccurenceBiasing::~G4ParticleChangeForOccurenceBiasing()
|
||||
{}
|
||||
|
||||
void G4ParticleChangeForOccurenceBiasing::SetWrappedParticleChange(G4VParticleChange* wpc)
|
||||
void G4ParticleChangeForOccurenceBiasing::
|
||||
SetWrappedParticleChange(G4VParticleChange* wpc)
|
||||
{
|
||||
fWrappedParticleChange = wpc;
|
||||
}
|
||||
@@ -45,15 +44,14 @@ void G4ParticleChangeForOccurenceBiasing::StealSecondaries()
|
||||
{
|
||||
SetNumberOfSecondaries( fWrappedParticleChange->GetNumberOfSecondaries() );
|
||||
for (G4int isecond = 0; isecond < fWrappedParticleChange->GetNumberOfSecondaries(); isecond++)
|
||||
{
|
||||
G4Track* secondary = fWrappedParticleChange->GetSecondary(isecond);
|
||||
secondary->SetWeight ( secondary->GetWeight() * fOccurenceWeightForInteraction );
|
||||
AddSecondary( secondary );
|
||||
}
|
||||
{
|
||||
G4Track* secondary = fWrappedParticleChange->GetSecondary(isecond);
|
||||
secondary->SetWeight ( secondary->GetWeight() * fOccurenceWeightForInteraction );
|
||||
AddSecondary( secondary );
|
||||
}
|
||||
fWrappedParticleChange->Clear();
|
||||
}
|
||||
|
||||
|
||||
G4Step* G4ParticleChangeForOccurenceBiasing::UpdateStepForAtRest(G4Step* step)
|
||||
{
|
||||
return step;
|
||||
@@ -62,12 +60,13 @@ G4Step* G4ParticleChangeForOccurenceBiasing::UpdateStepForAtRest(G4Step* step)
|
||||
G4Step* G4ParticleChangeForOccurenceBiasing::UpdateStepForAlongStep(G4Step* step)
|
||||
{
|
||||
// -- make particle change of wrapped process to apply its changes:
|
||||
if ( fWrappedParticleChange ) fWrappedParticleChange->UpdateStepForAlongStep( step );
|
||||
|
||||
if ( fWrappedParticleChange )
|
||||
fWrappedParticleChange->UpdateStepForAlongStep( step );
|
||||
|
||||
// -- multiply parent weight by weight due to occurrence biasing:
|
||||
G4StepPoint* postStepPoint = step->GetPostStepPoint();
|
||||
postStepPoint->SetWeight( postStepPoint->GetWeight() * fOccurenceWeightForNonInteraction );
|
||||
|
||||
postStepPoint->SetWeight( postStepPoint->GetWeight()*fOccurenceWeightForNonInteraction );
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ G4Step* G4ParticleChangeForOccurenceBiasing::UpdateStepForPostStep(G4Step* step)
|
||||
fWrappedParticleChange->UpdateStepForPostStep(step);
|
||||
// -- then apply weight correction due to occurrence biasing:
|
||||
G4StepPoint* postStepPoint = step->GetPostStepPoint();
|
||||
postStepPoint->SetWeight( postStepPoint->GetWeight() * fOccurenceWeightForInteraction );
|
||||
postStepPoint->SetWeight( postStepPoint->GetWeight()*fOccurenceWeightForInteraction );
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user