Import Geant4 11.3.0 source tree

This commit is contained in:
Gabriele Cosmo
2024-12-06 11:11:40 +01:00
parent e58e650b32
commit 32390e802b
1984 changed files with 98713 additions and 83996 deletions
+8
View File
@@ -6,6 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2024-07-18 Gabriele Cosmo (proc-biasgen-V11-02-01)
- Fixed reported Coverity defects, to use 'const G4String&' for avoiding
implicit copies.
- Basic C++11 corrections (use of nullptr, auto, etc...); code formatting.
## 2022-07-17 Vladimir Ivanchenko (proc-biasgen-V11-02-00)
- G4BOptnChangeCrossSection - fix Coverity warning
## 2022-11-23 Gabriele Cosmo (proc-biasgen-V11-00-02)
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
@@ -23,73 +23,66 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//---------------------------------------------------------------
//
// G4BOptnChangeCrossSection
//
// Class Description:
// A G4VBiasingOperation to change a process cross-section.
//
//
//---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingOperation to change a process cross-section.
//
// Author: Marc Verderi, November 2013
// --------------------------------------------------------------------
#ifndef G4BOptnChangeCrossSection_hh
#define G4BOptnChangeCrossSection_hh 1
#include "G4VBiasingOperation.hh"
class G4InteractionLawPhysical;
class G4BOptnChangeCrossSection : public G4VBiasingOperation {
public:
// -- Constructor :
G4BOptnChangeCrossSection(G4String name);
// -- destructor:
virtual ~G4BOptnChangeCrossSection();
public:
// -- Methods from G4VBiasingOperation interface:
// ----------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw* ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*,
G4ForceCondition& proposeForceCondition );
// -- Unused:
virtual G4VParticleChange* ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*,
const G4Step*,
G4bool& ) {return 0;}
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double,
G4ForceCondition*) {return DBL_MAX;}
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* ) {return 0;}
public:
// -- Additional methods, specific to this class:
// ----------------------------------------------
// -- return concrete type of interaction law:
G4InteractionLawPhysical* GetBiasedExponentialLaw() {return fBiasedExponentialLaw;}
// -- set biased cross-section:
void SetBiasedCrossSection(G4double xst, bool updateInteractionLength = false);
G4double GetBiasedCrossSection() const;
// -- Sample underneath distribution:
void Sample();
// -- Update for a made step, without resampling:
void UpdateForStep( G4double stepLength );
// -- set/get if interaction occured.
// -- Interaction flag turned off in "Sample()" method.
G4bool GetInteractionOccured() const { return fInteractionOccured; }
void SetInteractionOccured() { fInteractionOccured = true; }
class G4BOptnChangeCrossSection : public G4VBiasingOperation
{
public:
// -- Constructor :
G4BOptnChangeCrossSection(const G4String& name);
// -- destructor:
virtual ~G4BOptnChangeCrossSection();
// -- Methods from G4VBiasingOperation interface:
// ----------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw*
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*,
G4ForceCondition& proposeForceCondition );
// -- Unused:
virtual G4VParticleChange*
ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*, const G4Step*, G4bool& ) { return nullptr; }
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double, G4ForceCondition* ) { return DBL_MAX; }
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* ) { return nullptr; }
// -- Additional methods, specific to this class:
// ----------------------------------------------
// -- return concrete type of interaction law:
G4InteractionLawPhysical* GetBiasedExponentialLaw() { return fBiasedExponentialLaw; }
// -- set biased cross-section:
void SetBiasedCrossSection(G4double xst, G4bool updateInteractionLength=false);
G4double GetBiasedCrossSection() const;
// -- Sample underneath distribution:
void Sample();
// -- Update for a made step, without resampling:
void UpdateForStep( G4double stepLength );
// -- set/get if interaction occured.
// -- Interaction flag turned off in "Sample()" method.
G4bool GetInteractionOccured() const { return fInteractionOccured; }
void SetInteractionOccured() { fInteractionOccured = true; }
private:
G4InteractionLawPhysical* fBiasedExponentialLaw;
G4bool fInteractionOccured;
private:
G4InteractionLawPhysical* fBiasedExponentialLaw = nullptr;
G4bool fInteractionOccured = false;
};
#endif
@@ -23,65 +23,64 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//---------------------------------------------------------------
//
// G4BOptnCloning
//
// Class Description:
// A G4VBiasingOperation to clone a track, allowing to set
// weight arbitrary weights.
//
//
//---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingOperation to clone a track, allowing to set
// weight arbitrary weights.
//
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4BOptnCloning_hh
#define G4BOptnCloning_hh 1
#include "G4VBiasingOperation.hh"
#include "G4ParticleChange.hh"
class G4BOptnCloning : public G4VBiasingOperation {
public:
// -- Constructor :
G4BOptnCloning(G4String name);
// -- destructor:
virtual ~G4BOptnCloning();
public:
// -- Methods from G4VBiasingOperation interface:
// -------------------------------------------
// -- Unsed:
virtual const G4VBiasingInteractionLaw* ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& ) {return 0;}
virtual G4VParticleChange* ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*,
const G4Step*,
G4bool& ) {return 0;}
// -- Used:
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double,
G4ForceCondition* condition)
{
*condition = NotForced; return 0; // -- acts immediately
}
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* );
public:
// -- Additional methods, specific to this class:
// ----------------------------------------------
void SetCloneWeights(G4double clone1Weight, G4double clone2Weight) {fClone1W = clone1Weight ; fClone2W = clone2Weight;}
class G4BOptnCloning : public G4VBiasingOperation
{
public:
G4Track* GetCloneTrack() const { return fCloneTrack; }
// -- Constructor :
G4BOptnCloning(const G4String& name);
// -- destructor:
virtual ~G4BOptnCloning();
// -- Methods from G4VBiasingOperation interface:
// -------------------------------------------
// -- Unsed:
virtual const G4VBiasingInteractionLaw*
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*,
G4ForceCondition& ) { return nullptr; }
virtual G4VParticleChange*
ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*, const G4Step*, G4bool& ) { return nullptr; }
// -- Used:
virtual G4double
DistanceToApplyOperation( const G4Track*,
G4double, G4ForceCondition* condition )
{
*condition = NotForced; return 0.; // -- acts immediately
}
virtual G4VParticleChange*
GenerateBiasingFinalState( const G4Track*, const G4Step* );
private:
G4double fClone1W,
fClone2W;
G4ParticleChange fParticleChange;
G4Track* fCloneTrack;
// -- Additional methods, specific to this class:
// ----------------------------------------------
void SetCloneWeights( G4double clone1Weight, G4double clone2Weight )
{
fClone1W = clone1Weight;
fClone2W = clone2Weight;
}
G4Track* GetCloneTrack() const { return fCloneTrack; }
private:
G4double fClone1W = -1.0, fClone2W = -1.0;
G4ParticleChange fParticleChange;
G4Track* fCloneTrack = nullptr;
};
#endif
@@ -23,100 +23,99 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//---------------------------------------------------------------
//
// G4BOptnForceCommonTruncatedExp
//
// Class Description:
// A G4VBiasingOperation physics-based biasing operation. It
// handles several processes together, biasing on the total
// cross-section of these processes (instead of biasing them
// individually).
// The biasing interaction law is a truncated exponential
// one, driven by the total cross-section and which extends
// in the range [0,L].
// Process are registered with the AddCrossSection method.
// As cross-sections are all known at the end of the
// PostStepGPIL loop, the step limitation is made at the
// AlongStepGPIL level.
//
//---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingOperation physics-based biasing operation. It
// handles several processes together, biasing on the total
// cross-section of these processes (instead of biasing them
// individually).
// The biasing interaction law is a truncated exponential
// one, driven by the total cross-section and which extends
// in the range [0,L].
// Process are registered with the AddCrossSection() method.
// As cross-sections are all known at the end of the
// PostStepGPIL loop, the step limitation is made at the
// AlongStepGPIL level.
//
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4BOptnForceCommonTruncatedExp_hh
#define G4BOptnForceCommonTruncatedExp_hh 1
#include "G4VBiasingOperation.hh"
#include "G4ThreeVector.hh"
#include "G4ParticleChangeForNothing.hh"
class G4ILawCommonTruncatedExp;
class G4ILawForceFreeFlight;
#include <map>
class G4BOptnForceCommonTruncatedExp : public G4VBiasingOperation {
public:
// -- Constructor :
G4BOptnForceCommonTruncatedExp(G4String name);
// -- destructor:
virtual ~G4BOptnForceCommonTruncatedExp();
class G4ILawCommonTruncatedExp;
class G4ILawForceFreeFlight;
class G4BOptnForceCommonTruncatedExp : public G4VBiasingOperation
{
public:
// -- Constructor :
G4BOptnForceCommonTruncatedExp(const G4String& name);
// -- destructor:
virtual ~G4BOptnForceCommonTruncatedExp();
public:
// -- Methods from G4VBiasingOperation interface:
// -------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw* ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& );
virtual G4double ProposeAlongStepLimit( const G4BiasingProcessInterface* ) { return DBL_MAX; }
virtual G4GPILSelection ProposeGPILSelection( const G4GPILSelection processSelection );
virtual G4VParticleChange* ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*,
const G4Step*,
G4bool& );
// -- Unused:
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double,
G4ForceCondition*) {return DBL_MAX;}
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* ) {return 0;}
// -- Methods from G4VBiasingOperation interface:
// -------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw*
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& );
virtual G4double
ProposeAlongStepLimit( const G4BiasingProcessInterface* ) { return DBL_MAX; }
virtual G4GPILSelection
ProposeGPILSelection( const G4GPILSelection processSelection );
virtual G4VParticleChange*
ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*, const G4Step*, G4bool& );
// -- Unused:
virtual G4double
DistanceToApplyOperation( const G4Track*,
G4double, G4ForceCondition* ) { return DBL_MAX; }
virtual G4VParticleChange*
GenerateBiasingFinalState(const G4Track*, const G4Step*) { return nullptr; }
public:
// -- Additional methods, specific to this class:
// ----------------------------------------------
// -- return concrete type of interaction laws:
G4ILawCommonTruncatedExp* GetCommonTruncatedExpLaw()
{
return fCommonTruncatedExpLaw;
}
G4ILawForceFreeFlight* GetForceFreeFlightLaw()
{
return fForceFreeFlightLaw;
}
// -- Additional methods, specific to this class:
// ----------------------------------------------
// -- return concrete type of interaction laws:
G4ILawCommonTruncatedExp* GetCommonTruncatedExpLaw()
{
return fCommonTruncatedExpLaw;
}
G4ILawForceFreeFlight* GetForceFreeFlightLaw()
{
return fForceFreeFlightLaw;
}
void Initialize( const G4Track* );
void UpdateForStep( const G4Step* );
void Sample();
const G4ThreeVector& GetInitialMomentum() const { return fInitialMomentum; }
G4double GetMaximumDistance() const { return fMaximumDistance; }
void ChooseProcessToApply();
const G4VProcess* GetProcessToApply() const { return fProcessToApply; }
void AddCrossSection( const G4VProcess*, G4double );
std::size_t GetNumberOfSharing() const { return fNumberOfSharing; }
void SetInteractionOccured( G4bool b ) { fInteractionOccured = b; }
G4bool GetInteractionOccured() const { return fInteractionOccured; }
void Initialize( const G4Track* );
void UpdateForStep( const G4Step* );
void Sample();
const G4ThreeVector& GetInitialMomentum() const { return fInitialMomentum; }
G4double GetMaximumDistance() const { return fMaximumDistance; }
void ChooseProcessToApply();
const G4VProcess* GetProcessToApply() const { return fProcessToApply; }
void AddCrossSection( const G4VProcess*, G4double );
size_t GetNumberOfSharing() const { return fNumberOfSharing;}
void SetInteractionOccured( G4bool b ) { fInteractionOccured = b; }
G4bool GetInteractionOccured() const { return fInteractionOccured; }
private:
G4ILawCommonTruncatedExp* fCommonTruncatedExpLaw;
G4ILawForceFreeFlight* fForceFreeFlightLaw;
G4double fTotalCrossSection;
std::map < const G4VProcess*, G4double > fCrossSections;
size_t fNumberOfSharing;
const G4VProcess* fProcessToApply;
G4bool fInteractionOccured;
G4ThreeVector fInitialMomentum;
G4double fMaximumDistance;
G4ParticleChangeForNothing fDummyParticleChange;
private:
G4ILawCommonTruncatedExp* fCommonTruncatedExpLaw = nullptr;
G4ILawForceFreeFlight* fForceFreeFlightLaw = nullptr;
G4double fTotalCrossSection = 0.0;
std::map < const G4VProcess*, G4double > fCrossSections;
std::size_t fNumberOfSharing = 0;
const G4VProcess* fProcessToApply = nullptr;
G4bool fInteractionOccured = false;
G4ThreeVector fInitialMomentum;
G4double fMaximumDistance = -1.0;
G4ParticleChangeForNothing fDummyParticleChange;
};
#endif
@@ -23,75 +23,83 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//---------------------------------------------------------------
//
// G4BOptnForceFreeFlight
//
// Class Description:
// A G4VBiasingOperation physics-based biasing operation.
// If forces the physics process to not act on the track.
// In this implementation (meant for the ForceCollision
// operator) the free flight is done under zero weight for
// the track, and the action is meant to accumulate the weight
// change for making this uninteracting flight,
// cumulatedWeightChange.
// When the track reaches the current volume boundary, its
// weight is restored with value :
// initialWeight * cumulatedWeightChange
//
//---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingOperation physics-based biasing operation.
// If forces the physics process to not act on the track.
// In this implementation (meant for the ForceCollision
// operator) the free flight is done under zero weight for
// the track, and the action is meant to accumulate the weight
// change for making this uninteracting flight,
// cumulatedWeightChange.
// When the track reaches the current volume boundary, its
// weight is restored with value: initialWeight * cumulatedWeightChange
//
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4BOptnForceFreeFlight_hh
#define G4BOptnForceFreeFlight_hh 1
#include "G4VBiasingOperation.hh"
#include "G4ForceCondition.hh"
#include "G4ParticleChange.hh" // -- §§ should add a dedicated "weight change only" particle change
#include "G4ParticleChange.hh" // Should add a dedicated "weight change only"
// particle change
class G4ILawForceFreeFlight;
class G4BOptnForceFreeFlight : public G4VBiasingOperation
{
public:
class G4BOptnForceFreeFlight : public G4VBiasingOperation {
public:
// -- Constructor :
G4BOptnForceFreeFlight(G4String name);
// -- destructor:
virtual ~G4BOptnForceFreeFlight();
// -- Constructor :
G4BOptnForceFreeFlight(const G4String& name);
// -- destructor:
virtual ~G4BOptnForceFreeFlight();
public:
// -- Methods from G4VBiasingOperation interface:
// -------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw* ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& );
virtual void AlongMoveBy( const G4BiasingProcessInterface*, const G4Step*, G4double );
virtual G4VParticleChange* ApplyFinalStateBiasing( const G4BiasingProcessInterface*, const G4Track*, const G4Step*, G4bool&);
// -- Methods from G4VBiasingOperation interface:
// -------------------------------------------
// -- Used:
virtual const G4VBiasingInteractionLaw*
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*,
G4ForceCondition& );
virtual void AlongMoveBy( const G4BiasingProcessInterface*,
const G4Step*, G4double );
virtual G4VParticleChange*
ApplyFinalStateBiasing( const G4BiasingProcessInterface*,
const G4Track*, const G4Step*, G4bool& );
// -- Unused:
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double,
G4ForceCondition*) {return DBL_MAX;}
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* ) {return 0;}
// -- Unused:
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double, G4ForceCondition* ) { return DBL_MAX; }
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* ) { return nullptr; }
// -- Additional methods, specific to this class:
// ----------------------------------------------
// -- return concrete type of interaction law:
G4ILawForceFreeFlight* GetForceFreeFlightLaw()
{
return fForceFreeFlightInteractionLaw;
}
// -- initialization for weight:
void ResetInitialTrackWeight(G4double w)
{
fInitialTrackWeight = w;
fCumulatedWeightChange = 1.0;
}
G4bool OperationComplete() const
{
return fOperationComplete;
}
public:
// -- Additional methods, specific to this class:
// ----------------------------------------------
// -- return concrete type of interaction law:
G4ILawForceFreeFlight* GetForceFreeFlightLaw() {
return fForceFreeFlightInteractionLaw;
}
// -- initialization for weight:
void ResetInitialTrackWeight(G4double w) {fInitialTrackWeight = w; fCumulatedWeightChange = 1.0;}
G4bool OperationComplete() const { return fOperationComplete; }
private:
G4ILawForceFreeFlight* fForceFreeFlightInteractionLaw;
G4double fCumulatedWeightChange,
fInitialTrackWeight;
G4ParticleChange fParticleChange;
G4bool fOperationComplete;
private:
G4ILawForceFreeFlight* fForceFreeFlightInteractionLaw = nullptr;
G4double fCumulatedWeightChange = -1.0,
fInitialTrackWeight = -1.0;
G4ParticleChange fParticleChange;
G4bool fOperationComplete = true;
};
#endif
@@ -23,27 +23,24 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//---------------------------------------------------------------------
//
// G4BOptnLeadingParticle
//
// Class Description:
// A G4VBiasingOperation that implements the so-called "Leading
// particle biasing scheme". It is of interest in the shield problem
// to estimate the flux leaking from the shield.
// It works as follows:
// - it is intented for hadronic inelastic interaction
// - at each interaction, are kept:
// - the most energetic particle (the leading particle)
// - with unmodified weight
// - randomly one particle of each species
// - with this particle weight = n * primary_weight where
// n is the number of particles of this species
//---------------------------------------------------------------------
// Initial version Nov. 2019 M. Verderi
//
// A G4VBiasingOperation that implements the so-called "Leading
// particle biasing scheme". It is of interest in the shield problem
// to estimate the flux leaking from the shield.
// It works as follows:
// - it is intented for hadronic inelastic interaction
// - at each interaction, are kept:
// - the most energetic particle (the leading particle)
// - with unmodified weight
// - randomly one particle of each species
// - with this particle weight = n * primary_weight where
// n is the number of particles of this species
//
// Author: Marc Verderi, November 2019.
// --------------------------------------------------------------------
#ifndef G4BOptnLeadingParticle_hh
#define G4BOptnLeadingParticle_hh 1
@@ -51,46 +48,53 @@
#include "G4VBiasingOperation.hh"
#include "G4ParticleChange.hh"
class G4BOptnLeadingParticle : public G4VBiasingOperation {
public:
// -- Constructor :
G4BOptnLeadingParticle(G4String name);
// -- destructor:
virtual ~G4BOptnLeadingParticle();
public:
// -- Methods from G4VBiasingOperation interface:
// ----------------------------------------------
// -- Unused:
virtual const G4VBiasingInteractionLaw* ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*, G4ForceCondition& ) {return nullptr;}
// -- Used:
virtual G4VParticleChange* ApplyFinalStateBiasing( const G4BiasingProcessInterface*, // -- Method used for this biasing. The related biasing operator
const G4Track*, // -- returns this biasing operation at the post step do it level
const G4Step*, // -- when the wrapped process has won the interaction length race.
G4bool& ); // -- The wrapped process final state is then trimmed.
// -- Unused:
virtual G4double DistanceToApplyOperation( const G4Track*,
G4double,
G4ForceCondition*) {return 0;}
virtual G4VParticleChange* GenerateBiasingFinalState( const G4Track*,
const G4Step* ) {return nullptr;}
class G4BOptnLeadingParticle : public G4VBiasingOperation
{
public:
public:
// -- The possibility is given to further apply a Russian roulette on tracks that are accompagnying the leading particle
// -- after the classical leading particle biasing algorithm has been applied.
// -- This is of interest when applying the technique to e+ -> gamma gamma for example. Given one gamma is leading,
// -- the second one is alone in its category, hence selected. With the Russian roulette it is then possible to keep
// -- this one randomly. This is also of interest for pi0 decays, or for brem. e- -> e- gamma where the e- or gamma
// -- are alone in their category.
void SetFurtherKillingProbability( G4double p ) { fRussianRouletteKillingProbability = p; } // -- if p <= 0.0 the killing is ignored.
G4double GetFurtherKillingProbability() const { return fRussianRouletteKillingProbability; }
// -- Constructor :
G4BOptnLeadingParticle(const G4String& name);
// -- destructor:
virtual ~G4BOptnLeadingParticle();
private:
// -- Particle change used to return the trimmed final state:
G4ParticleChange fParticleChange;
G4double fRussianRouletteKillingProbability;
// -- Methods from G4VBiasingOperation interface:
// ----------------------------------------------
// -- Unused:
virtual const G4VBiasingInteractionLaw*
ProvideOccurenceBiasingInteractionLaw( const G4BiasingProcessInterface*,
G4ForceCondition& ) { return nullptr; }
// -- Used:
virtual G4VParticleChange*
ApplyFinalStateBiasing( const G4BiasingProcessInterface*, // -- Method used for this biasing. The related biasing operator
const G4Track*, // -- returns this biasing operation at the post step do it level
const G4Step*, // -- when the wrapped process has won the interaction length race.
G4bool& ); // -- The wrapped process final state is then trimmed.
// -- Unused:
virtual G4double
DistanceToApplyOperation( const G4Track*, G4double, G4ForceCondition* ) { return 0.0; }
virtual G4VParticleChange*
GenerateBiasingFinalState( const G4Track*, const G4Step* ) { return nullptr; }
// -- The possibility is given to further apply a Russian roulette on tracks that are accompagnying the leading particle
// -- after the classical leading particle biasing algorithm has been applied.
// -- This is of interest when applying the technique to e+ -> gamma gamma for example. Given one gamma is leading,
// -- the second one is alone in its category, hence selected. With the Russian roulette it is then possible to keep
// -- this one randomly. This is also of interest for pi0 decays, or for brem. e- -> e- gamma where the e- or gamma
// -- are alone in their category.
void SetFurtherKillingProbability( G4double p ) // -- if p <= 0.0 the killing is ignored.
{
fRussianRouletteKillingProbability = p;
}
G4double GetFurtherKillingProbability() const
{
return fRussianRouletteKillingProbability;
}
private:
// -- Particle change used to return the trimmed final state:
G4ParticleChange fParticleChange;
G4double fRussianRouletteKillingProbability = -1.0;
};
#endif
@@ -23,76 +23,88 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4BOptrForceCollision
//
// Class Description:
// A G4VBiasingOperator that implements a "force collision" a la
//
// A G4VBiasingOperator that implements a "force collision" a la
// MCNP. This is meant for neutral particles.
// When the track enters the volume, it is cloned. One copy makes
// When the track enters the volume, it is cloned. One copy makes
// a forced free flight up to the volume exit. The other copy makes
// a forced collision inside the volume.
//
// ---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4BOptrForceCollision_hh
#define G4BOptrForceCollision_hh 1
#include "G4VBiasingOperator.hh"
#include "G4ThreeVector.hh"
#include <vector>
#include <map>
class G4BOptnForceFreeFlight;
class G4BOptnForceCommonTruncatedExp;
class G4BOptnCloning;
class G4VProcess;
class G4BiasingProcessInterface;
class G4ParticleDefinition;
#include <vector>
#include <map>
#include "G4ThreeVector.hh"
class G4BOptrForceCollisionTrackData;
class G4BOptrForceCollision : public G4VBiasingOperator {
public:
G4BOptrForceCollision(G4String particleToForce, G4String name="ForceCollision");
G4BOptrForceCollision(const G4ParticleDefinition* particleToForce, G4String name="ForceCollision");
~G4BOptrForceCollision();
private:
// -- Mandatory from base class :
virtual G4VBiasingOperation* ProposeNonPhysicsBiasingOperation(const G4Track* track, const G4BiasingProcessInterface* callingProcess) final;
virtual G4VBiasingOperation* ProposeOccurenceBiasingOperation(const G4Track* track, const G4BiasingProcessInterface* callingProcess) final;
virtual G4VBiasingOperation* ProposeFinalStateBiasingOperation(const G4Track* track, const G4BiasingProcessInterface* callingProcess) final;
// -- optional methods from base class:
public:
virtual void Configure() final;
virtual void ConfigureForWorker() final;
virtual void StartRun() final;
virtual void StartTracking( const G4Track* track ) final;
virtual void ExitBiasing( const G4Track*, const G4BiasingProcessInterface* ) final {};
virtual void EndTracking() final;
class G4BOptrForceCollision : public G4VBiasingOperator
{
public:
// -- operation applied:
void OperationApplied( const G4BiasingProcessInterface* callingProcess, G4BiasingAppliedCase biasingCase,
G4VBiasingOperation* operationApplied, const G4VParticleChange* particleChangeProduced ) final;
void OperationApplied( const G4BiasingProcessInterface* callingProcess, G4BiasingAppliedCase biasingCase,
G4VBiasingOperation* occurenceOperationApplied, G4double weightForOccurenceInteraction,
G4VBiasingOperation* finalStateOperationApplied, const G4VParticleChange* particleChangeProduced ) final;
G4BOptrForceCollision(const G4String& particleToForce,
const G4String& name="ForceCollision");
G4BOptrForceCollision(const G4ParticleDefinition* particleToForce,
const G4String& name="ForceCollision");
~G4BOptrForceCollision();
virtual void Configure() final;
virtual void ConfigureForWorker() final;
virtual void StartRun() final;
virtual void StartTracking( const G4Track* track ) final;
virtual void ExitBiasing( const G4Track*, const G4BiasingProcessInterface* ) final {};
virtual void EndTracking() final;
private:
G4int fForceCollisionModelID;
const G4Track* fCurrentTrack;
G4BOptrForceCollisionTrackData* fCurrentTrackData;
std::map< const G4BiasingProcessInterface*, G4BOptnForceFreeFlight* > fFreeFlightOperations;
G4BOptnForceCommonTruncatedExp* fSharedForceInteractionOperation;
G4BOptnCloning* fCloningOperation;
G4double fInitialTrackWeight;
G4bool fSetup;
const G4ParticleDefinition* fParticleToBias;
// -- operation applied:
void OperationApplied( const G4BiasingProcessInterface* callingProcess,
G4BiasingAppliedCase biasingCase,
G4VBiasingOperation* operationApplied,
const G4VParticleChange* particleChangeProduced ) final;
void OperationApplied( const G4BiasingProcessInterface* callingProcess,
G4BiasingAppliedCase biasingCase,
G4VBiasingOperation* occurenceOperationApplied,
G4double weightForOccurenceInteraction,
G4VBiasingOperation* finalStateOperationApplied,
const G4VParticleChange* particleChangeProduced ) final;
private:
// -- Mandatory from base class :
virtual G4VBiasingOperation*
ProposeNonPhysicsBiasingOperation(const G4Track* track,
const G4BiasingProcessInterface* callingProcess) final;
virtual G4VBiasingOperation*
ProposeOccurenceBiasingOperation(const G4Track* track,
const G4BiasingProcessInterface* callingProcess) final;
virtual G4VBiasingOperation*
ProposeFinalStateBiasingOperation(const G4Track* track,
const G4BiasingProcessInterface* callingProcess) final;
private:
G4int fForceCollisionModelID = 0;
const G4Track* fCurrentTrack = nullptr;
G4BOptrForceCollisionTrackData* fCurrentTrackData = nullptr;
std::map< const G4BiasingProcessInterface*, G4BOptnForceFreeFlight* > fFreeFlightOperations;
G4BOptnForceCommonTruncatedExp* fSharedForceInteractionOperation = nullptr;
G4BOptnCloning* fCloningOperation = nullptr;
G4double fInitialTrackWeight = -1.0;
G4bool fSetup = true;
const G4ParticleDefinition* fParticleToBias = nullptr;
};
#endif
@@ -23,58 +23,60 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// --------------------------------------------------------------------
// GEANT 4 class header file
// G4BOptrForceCollisionTrackData
//
// Class Description:
// Extends G4Track properties with information needed for the
// force collision biasing operator.
// The G4BOptrForceCollision class is made friend of this one in
// order to keep unexposed to public most of the data members, as
// they are used to control the logic.
//
// ------------------ G4BOptrForceCollisionTrackData ------------------
//
// Author: M.Verderi (LLR), October 2015
// Extends G4Track properties with information needed for the
// force collision biasing operator.
// The G4BOptrForceCollision class is made friend of this one in
// order to keep unexposed to public most of the data members, as
// they are used to control the logic.
//
// Author: M.Verderi (LLR), October 2015.
// --------------------------------------------------------------------
#ifndef G4BOptrForceCollisionTrackData_hh
#define G4BOptrForceCollisionTrackData_hh
#define G4BOptrForceCollisionTrackData_hh 1
#include "G4VAuxiliaryTrackInformation.hh"
class G4BOptrForceCollision;
#include "G4VAuxiliaryTrackInformation.hh"
enum class ForceCollisionState { free, toBeCloned, toBeForced, toBeFreeFlight };
class G4BOptrForceCollisionTrackData : public G4VAuxiliaryTrackInformation {
class G4BOptrForceCollisionTrackData : public G4VAuxiliaryTrackInformation
{
friend class G4BOptrForceCollision;
public:
friend class G4BOptrForceCollision;
G4BOptrForceCollisionTrackData( const G4BOptrForceCollision* );
~G4BOptrForceCollisionTrackData();
public:
G4BOptrForceCollisionTrackData( const G4BOptrForceCollision* );
~G4BOptrForceCollisionTrackData();
// -- from base class:
void Print() const;
// -- from base class:
void Print() const;
// -- Get methods:
G4bool IsFreeFromBiasing() const
{ return ( fForceCollisionState == ForceCollisionState::free);}
// -- no set methods are provided : sets are made under exclusive control of G4BOptrForceCollision objects through friendness.
private:
const G4BOptrForceCollision* fForceCollisionOperator;
ForceCollisionState fForceCollisionState;
// -- Get methods:
G4bool IsFreeFromBiasing() const
{
return ( fForceCollisionState == ForceCollisionState::free);
}
void Reset()
{
fForceCollisionOperator = nullptr;
fForceCollisionState = ForceCollisionState::free;
}
// -- no set methods are provided : sets are made under exclusive
// control of G4BOptrForceCollision objects through friendness.
private:
void Reset()
{
fForceCollisionOperator = nullptr;
fForceCollisionState = ForceCollisionState::free;
}
private:
const G4BOptrForceCollision* fForceCollisionOperator = nullptr;
ForceCollisionState fForceCollisionState;
};
#endif
@@ -23,56 +23,49 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//---------------------------------------------------------------
//
// G4BiasingHelper
//
// Class Description:
// A utility class to help configuring code for biasing.
//
//
//---------------------------------------------------------------
// Initial version Sep. 2013 M. Verderi
// A utility class to help configuring code for biasing.
//
// Author: Marc Verderi, September 2013.
// --------------------------------------------------------------------
#ifndef G4BiasingHelper_h
#define G4BiasingHelper_h 1
#include "globals.hh"
#include <vector>
class G4ProcessManager;
class G4ParallelGeometriesLimiterProcess;
#include <vector>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4BiasingHelper
{
public:
// -- Substitute, in the process manager passed, physics process "physicsProcessToBias"
// -- with a version wrapped by a G4BiasingProcessInterface wrapped, to put this physics
// -- process under biasing.
// -- Only processes of process type 2 (EM), 3 (Optical), 4 (Had.) and 6 (Decay) will be
// -- wrapped.
// -- A name for this wrapped process can be given (otherwise a default one is provided:
// -- e.g. for process "phot" this will be "biasWrapper(phot)").
static G4bool ActivatePhysicsBiasing(G4ProcessManager* pmanager, G4String physicsProcessToBias,
G4String wrappedName = "");
// -- Insert, in the process manager passed, a G4BiasingProcessInterface process that
// -- will deal with non-modifying physics biasing (splitting, killing). A name for
// -- this process can be passed, otherwise the default name "biasWrapper(0)" is used.
static void ActivateNonPhysicsBiasing(G4ProcessManager* pmanager,
G4String nonPhysicsProcessName = "");
// -- Add a G4ParallelGeometriesLimiterProcess instance to the given process manager
// -- The pointer of the added process is returned.
static G4ParallelGeometriesLimiterProcess* AddLimiterProcess(G4ProcessManager* pmanager,
const G4String& processName = "biasLimiter");
public:
// -- Substitute, in the process manager passed, physics process "physicsProcessToBias"
// -- with a version wrapped by a G4BiasingProcessInterface wrapped, to put this physics
// -- process under biasing.
// -- Only processes of process type 2 (EM), 3 (Optical), 4 (Had.) and 6 (Decay) will be
// -- wrapped.
// -- A name for this wrapped process can be given (otherwise a default one is provided:
// -- e.g. for process "phot" this will be "biasWrapper(phot)").
static G4bool ActivatePhysicsBiasing(G4ProcessManager* pmanager,
const G4String& physicsProcessToBias,
const G4String& wrappedName = "");
// -- Insert, in the process manager passed, a G4BiasingProcessInterface process that
// -- will deal with non-modifying physics biasing (splitting, killing). A name for
// -- this process can be passed, otherwise the default name "biasWrapper(0)" is used.
static void ActivateNonPhysicsBiasing(G4ProcessManager* pmanager,
const G4String& nonPhysicsProcessName = "");
// -- Add a G4ParallelGeometriesLimiterProcess instance to the given process manager
// -- The pointer of the added process is returned.
static G4ParallelGeometriesLimiterProcess*
AddLimiterProcess(G4ProcessManager* pmanager,
const G4String& processName = "biasLimiter");
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -23,36 +23,30 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//--------------------------------------------------------------------
//
// G4BiasingProcessInterface
//
// Class Description:
// A wrapper process making the interface between the tracking
// and the G4VBiasingOperator objects attached to volumes.
// If this process holds a physics process, it forwards
// tracking calls to this process in volume where not biasing
// occurs. In volumes with biasing (with a G4VBiasingOperator
// attached) the process gets what to do messaging the biasing
// operator :
// - at the PostStepGPIL level, for getting an occurrence biasing
// operation. If such an operation is returned to the process
// this operation will be messaged at several places.
// - at the PostStepDoIt level, to get a possible final state
// biasing operation
// If the process does not hold a physics process, it is meant
// as handling "non physics" biasing operations: pure splitting
// or pure kiling for example (ie not brem splitting).
//
//--------------------------------------------------------------------
// Initial version Sep. 2013 M. Verderi
// Use of "shared data" class Sep. 2014 M. Verderi
// A wrapper process making the interface between the tracking
// and the G4VBiasingOperator objects attached to volumes.
// If this process holds a physics process, it forwards
// tracking calls to this process in volume where not biasing
// occurs. In volumes with biasing (with a G4VBiasingOperator
// attached) the process gets what to do messaging the biasing
// operator :
// - at the PostStepGPIL level, for getting an occurrence biasing
// operation. If such an operation is returned to the process
// this operation will be messaged at several places.
// - at the PostStepDoIt level, to get a possible final state
// biasing operation
// If the process does not hold a physics process, it is meant
// as handling "non physics" biasing operations: pure splitting
// or pure kiling for example (ie not brem splitting).
//
// Author: Marc Verderi, September 2013.
// --------------------------------------------------------------------
#ifndef G4BiasingProcessInterface_h
#define G4BiasingProcessInterface_h
#define G4BiasingProcessInterface_h 1
#include "globals.hh"
#include "G4VProcess.hh"
@@ -66,213 +60,218 @@ class G4VBiasingOperation;
class G4ParticleChangeForOccurenceBiasing;
class G4ParticleChangeForNothing;
class G4BiasingProcessInterface : public G4VProcess {
public:
// --------------------------------------------------------------------------------
// -- constructor for dealing with biasing options not affecting physics processes:
// --------------------------------------------------------------------------------
G4BiasingProcessInterface( G4String name = "biasWrapper(0)" );
// ---------------------------------------------------------------
// -- constructor to transform the behaviour of a physics process:
// ---------------------------------------------------------------
// -- wrappedProcess pointer MUST NOT be null.
G4BiasingProcessInterface(G4VProcess* wrappedProcess,
G4bool wrappedIsAtRest, G4bool wrappedIsAlongStep, G4bool wrappedIsPostStep,
G4String useThisName = "");
~G4BiasingProcessInterface();
// -- pointer of wrapped physics process:
G4VProcess* GetWrappedProcess() const {return fWrappedProcess;}
class G4BiasingProcessInterface : public G4VProcess
{
public:
// --------------------------------------------------------------------------------
// -- constructor for dealing with biasing options not affecting physics processes:
// --------------------------------------------------------------------------------
G4BiasingProcessInterface( const G4String& name = "biasWrapper(0)" );
// ---------------------------------------------------------------
// -- constructor to transform the behaviour of a physics process:
// ---------------------------------------------------------------
// -- wrappedProcess pointer MUST NOT be null.
G4BiasingProcessInterface(G4VProcess* wrappedProcess,
G4bool wrappedIsAtRest,
G4bool wrappedIsAlongStep,
G4bool wrappedIsPostStep,
G4String useThisName = "");
~G4BiasingProcessInterface();
// -- pointer of wrapped physics process:
G4VProcess* GetWrappedProcess() const { return fWrappedProcess; }
// ---------------------
// -- Biasing interface:
// ---------------------
// -- Helper methods:
// ------------------
// -- Current step and previous step biasing operator, if any:
G4VBiasingOperator* GetCurrentBiasingOperator() const {return fSharedData-> fCurrentBiasingOperator; }
G4VBiasingOperator* GetPreviousBiasingOperator() const {return fSharedData->fPreviousBiasingOperator; }
// -- current and previous operation:
G4VBiasingOperation* GetCurrentNonPhysicsBiasingOperation() const { return fNonPhysicsBiasingOperation; }
G4VBiasingOperation* GetPreviousNonPhysicsBiasingOperation() const { return fPreviousNonPhysicsBiasingOperation; }
G4VBiasingOperation* GetCurrentOccurenceBiasingOperation() const { return fOccurenceBiasingOperation; }
G4VBiasingOperation* GetPreviousOccurenceBiasingOperation() const { return fPreviousOccurenceBiasingOperation; }
G4VBiasingOperation* GetCurrentFinalStateBiasingOperation() const { return fFinalStateBiasingOperation; }
G4VBiasingOperation* GetPreviousFinalStateBiasingOperation() const { return fPreviousFinalStateBiasingOperation; }
// ---------------------
// -- Biasing interface:
// ---------------------
// -- Helper methods:
// ------------------
// -- Current step and previous step biasing operator, if any:
G4VBiasingOperator* GetCurrentBiasingOperator() const
{ return fSharedData->fCurrentBiasingOperator; }
G4VBiasingOperator* GetPreviousBiasingOperator() const
{ return fSharedData->fPreviousBiasingOperator; }
// -- current and previous operation:
G4VBiasingOperation* GetCurrentNonPhysicsBiasingOperation() const
{ return fNonPhysicsBiasingOperation; }
G4VBiasingOperation* GetPreviousNonPhysicsBiasingOperation() const
{ return fPreviousNonPhysicsBiasingOperation; }
G4VBiasingOperation* GetCurrentOccurenceBiasingOperation() const
{ return fOccurenceBiasingOperation; }
G4VBiasingOperation* GetPreviousOccurenceBiasingOperation() const
{ return fPreviousOccurenceBiasingOperation; }
G4VBiasingOperation* GetCurrentFinalStateBiasingOperation() const
{ return fFinalStateBiasingOperation; }
G4VBiasingOperation* GetPreviousFinalStateBiasingOperation() const
{ return fPreviousFinalStateBiasingOperation; }
// -- Lists of processes cooperating under a same particle type/G4ProcessManager.
// -- The vector ordering is:
// -- - random, before first "run/beamOn"
// -- - that of the PostStepGetPhysicalInteractionLength() once "/run/beamOn" has been issued
const std::vector< const G4BiasingProcessInterface* >& GetBiasingProcessInterfaces() const
{return fSharedData-> fPublicBiasingProcessInterfaces;}
const std::vector< const G4BiasingProcessInterface* >& GetPhysicsBiasingProcessInterfaces() const
{return fSharedData-> fPublicPhysicsBiasingProcessInterfaces;}
const std::vector< const G4BiasingProcessInterface* >& GetNonPhysicsBiasingProcessInterfaces() const
{return fSharedData->fPublicNonPhysicsBiasingProcessInterfaces;}
// -- Lists of processes cooperating under a same particle type/G4ProcessManager.
// -- The vector ordering is:
// -- - random, before first "run/beamOn"
// -- - that of the PostStepGetPhysicalInteractionLength() once "/run/beamOn" has been issued
const std::vector< const G4BiasingProcessInterface* >& GetBiasingProcessInterfaces() const
{ return fSharedData->fPublicBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetPhysicsBiasingProcessInterfaces() const
{ return fSharedData->fPublicPhysicsBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetNonPhysicsBiasingProcessInterfaces() const
{ return fSharedData->fPublicNonPhysicsBiasingProcessInterfaces; }
// -- Get shared data for this process:
const G4BiasingProcessSharedData* GetSharedData() const { return fSharedData; }
// -- Get shared data associated to a G4ProcessManager:
static const G4BiasingProcessSharedData* GetSharedData( const G4ProcessManager* );
// -- Get shared data for this process:
const G4BiasingProcessSharedData* GetSharedData() const
{ return fSharedData; }
// -- Get shared data associated to a G4ProcessManager:
static const G4BiasingProcessSharedData* GetSharedData( const G4ProcessManager* );
// ------------------
// -- Helper methods:
// ------------------
// ---- Tell is this process is first/last in the PostStep GPIL and DoIt lists.
// ---- If physOnly is true, only wrapper for physics processes are considered,
// ---- otherwise all G4BiasingProcessInterface processes of this particle are
// ---- considered.
// ---- These methods just return the corresponding flag values setup at
// ---- initialization phase by the next four ones.
// ---- Will not be updated if processes are activate/unactivated on the fly.
// ---- Use next methods (less fast) instead in this case.
G4bool GetIsFirstPostStepGPILInterface(G4bool physOnly = true) const;
G4bool GetIsLastPostStepGPILInterface(G4bool physOnly = true) const;
G4bool GetIsFirstPostStepDoItInterface(G4bool physOnly = true) const;
G4bool GetIsLastPostStepDoItInterface(G4bool physOnly = true) const;
// ---- Determine if the process is first/last in the PostStep GPIL and DoIt lists.
G4bool IsFirstPostStepGPILInterface(G4bool physOnly = true) const;
G4bool IsLastPostStepGPILInterface(G4bool physOnly = true) const;
G4bool IsFirstPostStepDoItInterface(G4bool physOnly = true) const;
G4bool IsLastPostStepDoItInterface(G4bool physOnly = true) const;
// -- Information about wrapped process:
G4bool GetWrappedProcessIsAtRest() const { return fWrappedProcessIsAtRest; }
G4bool GetWrappedProcessIsAlong() const { return fWrappedProcessIsAlong; }
G4bool GetWrappedProcessIsPost() const { return fWrappedProcessIsPost; }
// -- Information methods:
G4double GetPreviousStepSize() const { return fPreviousStepSize; }
G4double GetCurrentMinimumStep() const { return fCurrentMinimumStep; }
G4double GetProposedSafety() const { return fProposedSafety; }
void SetProposedSafety(G4double sft) { fProposedSafety = sft; }
// -- return the actual PostStep and AlongStep limits returned by the process to the tracking :
G4double GetPostStepGPIL() const { return fBiasingPostStepGPIL; }
G4double GetAlongStepGPIL() const { return fWrappedProcessAlongStepGPIL; }
// --------------------------------------------------------------
// -- G4VProcess interface --
// --------------------------------------------------------------
// -- Start/End tracking:
void StartTracking(G4Track* track);
void EndTracking();
// ------------------
// -- Helper methods:
// ------------------
// ---- Tell is this process is first/last in the PostStep GPIL and DoIt lists.
// ---- If physOnly is true, only wrapper for physics processes are considered,
// ---- otherwise all G4BiasingProcessInterface processes of this particle are
// ---- considered.
// ---- These methods just return the corresponding flag values setup at
// ---- initialization phase by the next four ones.
// ---- Will not be updated if processes are activate/unactivated on the fly.
// ---- Use next methods (less fast) instead in this case.
G4bool GetIsFirstPostStepGPILInterface(G4bool physOnly = true) const;
G4bool GetIsLastPostStepGPILInterface(G4bool physOnly = true) const;
G4bool GetIsFirstPostStepDoItInterface(G4bool physOnly = true) const;
G4bool GetIsLastPostStepDoItInterface(G4bool physOnly = true) const;
// ---- Determine if the process is first/last in the PostStep GPIL and DoIt lists.
G4bool IsFirstPostStepGPILInterface(G4bool physOnly = true) const;
G4bool IsLastPostStepGPILInterface(G4bool physOnly = true) const;
G4bool IsFirstPostStepDoItInterface(G4bool physOnly = true) const;
G4bool IsLastPostStepDoItInterface(G4bool physOnly = true) const;
// -- Information about wrapped process:
G4bool GetWrappedProcessIsAtRest() const { return fWrappedProcessIsAtRest; }
G4bool GetWrappedProcessIsAlong() const { return fWrappedProcessIsAlong; }
G4bool GetWrappedProcessIsPost() const { return fWrappedProcessIsPost; }
// -- PostStep methods:
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition);
virtual G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step);
// -- AlongStep methods:
virtual G4double AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection);
virtual G4VParticleChange* AlongStepDoIt(const G4Track& track,
const G4Step& step);
// -- AtRest methods
virtual G4double AtRestGetPhysicalInteractionLength(const G4Track&,
G4ForceCondition*);
virtual G4VParticleChange* AtRestDoIt(const G4Track&, const G4Step&);
// -- Information methods:
G4double GetPreviousStepSize() const { return fPreviousStepSize;}
G4double GetCurrentMinimumStep() const { return fCurrentMinimumStep;}
G4double GetProposedSafety() const { return fProposedSafety;}
void SetProposedSafety(G4double sft) { fProposedSafety = sft;}
// -- return the actual PostStep and AlongStep limits returned by the process to the tracking :
G4double GetPostStepGPIL() const { return fBiasingPostStepGPIL; }
G4double GetAlongStepGPIL() const { return fWrappedProcessAlongStepGPIL; }
// --------------------------------------------------------------
// -- G4VProcess interface --
// --------------------------------------------------------------
public:
// -- Start/End tracking:
void StartTracking(G4Track* track);
void EndTracking();
virtual G4bool IsApplicable(const G4ParticleDefinition& pd);
virtual void BuildPhysicsTable(const G4ParticleDefinition& pd);
virtual void PreparePhysicsTable(const G4ParticleDefinition& pd);
virtual G4bool StorePhysicsTable(const G4ParticleDefinition* pd,
const G4String& s, G4bool f);
virtual G4bool RetrievePhysicsTable(const G4ParticleDefinition* pd,
const G4String& s, G4bool f);
// --
virtual void SetProcessManager(const G4ProcessManager*);
virtual const G4ProcessManager* GetProcessManager();
// --
virtual void ResetNumberOfInteractionLengthLeft();
// -- PostStep methods:
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition);
virtual G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step);
// -- AlongStep methods:
virtual G4double AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection);
virtual G4VParticleChange* AlongStepDoIt(const G4Track& track,
const G4Step& step);
// -- AtRest methods
virtual G4double AtRestGetPhysicalInteractionLength(const G4Track&,
G4ForceCondition*);
virtual G4VParticleChange* AtRestDoIt(const G4Track&,
const G4Step&);
virtual G4bool IsApplicable(const G4ParticleDefinition& pd);
virtual void BuildPhysicsTable(const G4ParticleDefinition& pd);
virtual void PreparePhysicsTable(const G4ParticleDefinition& pd);
virtual G4bool StorePhysicsTable(const G4ParticleDefinition* pd,
const G4String& s, G4bool f);
virtual G4bool RetrievePhysicsTable(const G4ParticleDefinition* pd,
const G4String& s, G4bool f);
// --
virtual void SetProcessManager(const G4ProcessManager*);
virtual const G4ProcessManager* GetProcessManager();
// --
virtual void ResetNumberOfInteractionLengthLeft();
// virtual void ClearNumberOfInteractionLengthLeft();
// --
// virtual void DumpInfo() const;
virtual void SetMasterProcess(G4VProcess* masterP);
virtual void BuildWorkerPhysicsTable(const G4ParticleDefinition& pd);
virtual void PrepareWorkerPhysicsTable(const G4ParticleDefinition& pd);
virtual void SetMasterProcess(G4VProcess* masterP);
virtual void BuildWorkerPhysicsTable(const G4ParticleDefinition& pd);
virtual void PrepareWorkerPhysicsTable(const G4ParticleDefinition& pd);
private:
private:
// ---- Internal utility methods:
void SetUpFirstLastFlags();
void ResetForUnbiasedTracking();
void ReorderBiasingVectorAsGPIL();
// ---- Internal utility methods:
void SetUpFirstLastFlags();
void ResetForUnbiasedTracking();
void ReorderBiasingVectorAsGPIL();
G4Track* fCurrentTrack;
G4double fPreviousStepSize;
G4double fCurrentMinimumStep;
G4double fProposedSafety;
G4int IdxFirstLast(G4int firstLast, G4int GPILDoIt, G4int physAll) const
{
// -- be careful : all arguments are *assumed* to be 0 or 1. No check
// -- for that is provided. Should be of pure internal usage.
return 4*firstLast + 2*GPILDoIt + physAll;
}
G4VBiasingOperation* fOccurenceBiasingOperation;
G4VBiasingOperation* fFinalStateBiasingOperation;
G4VBiasingOperation* fNonPhysicsBiasingOperation;
G4VBiasingOperation* fPreviousOccurenceBiasingOperation;
G4VBiasingOperation* fPreviousFinalStateBiasingOperation;
G4VBiasingOperation* fPreviousNonPhysicsBiasingOperation;
// -- method used to anticipate stepping manager calls to PostStepGPIL
// -- of wrapped processes : this method calls wrapped process PostStepGPIL
// -- and caches results for PostStepGPIL and condition.
void InvokeWrappedProcessPostStepGPIL( const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition );
private:
G4bool fResetWrappedProcessInteractionLength;
G4Track* fCurrentTrack = nullptr;
G4double fPreviousStepSize = -1.0;
G4double fCurrentMinimumStep = -1.0;
G4double fProposedSafety = -1.0;
G4VProcess* fWrappedProcess;
const G4bool fIsPhysicsBasedBiasing;
const G4bool fWrappedProcessIsAtRest;
const G4bool fWrappedProcessIsAlong;
const G4bool fWrappedProcessIsPost;
G4VBiasingOperation* fOccurenceBiasingOperation = nullptr;
G4VBiasingOperation* fFinalStateBiasingOperation = nullptr;
G4VBiasingOperation* fNonPhysicsBiasingOperation = nullptr;
G4VBiasingOperation* fPreviousOccurenceBiasingOperation = nullptr;
G4VBiasingOperation* fPreviousFinalStateBiasingOperation = nullptr;
G4VBiasingOperation* fPreviousNonPhysicsBiasingOperation = nullptr;
G4bool fResetWrappedProcessInteractionLength = false;
G4double fWrappedProcessPostStepGPIL;
G4double fBiasingPostStepGPIL;
G4double fWrappedProcessInteractionLength; // -- inverse of analog cross-section
G4ForceCondition fWrappedProcessForceCondition;
G4ForceCondition fBiasingForceCondition;
G4double fWrappedProcessAlongStepGPIL;
G4double fBiasingAlongStepGPIL;
G4GPILSelection fWrappedProcessGPILSelection;
G4GPILSelection fBiasingGPILSelection;
G4VProcess* fWrappedProcess = nullptr;
const G4bool fIsPhysicsBasedBiasing = false;
const G4bool fWrappedProcessIsAtRest = false;
const G4bool fWrappedProcessIsAlong = false;
const G4bool fWrappedProcessIsPost = false;
const G4VBiasingInteractionLaw* fBiasingInteractionLaw;
const G4VBiasingInteractionLaw* fPreviousBiasingInteractionLaw;
G4InteractionLawPhysical* fPhysicalInteractionLaw;
G4ParticleChangeForOccurenceBiasing* fOccurenceBiasingParticleChange;
G4ParticleChangeForNothing* fDummyParticleChange;
G4bool fFirstLastFlags[8];
G4int IdxFirstLast(G4int firstLast, G4int GPILDoIt, G4int physAll) const
{
// -- be careful : all arguments are *assumed* to be 0 or 1. No check
// -- for that is provided. Should be of pure internal usage.
return 4*firstLast + 2*GPILDoIt + physAll;
}
// -- method used to anticipate stepping manager calls to PostStepGPIL
// -- of wrapped processes : this method calls wrapped process PostStepGPIL
// -- and caches results for PostStepGPIL and condition.
void InvokeWrappedProcessPostStepGPIL( const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition );
// -- the instance being "firstGPIL" does work shared by other instances:
G4bool fIamFirstGPIL;
G4double fWrappedProcessPostStepGPIL = -1.0;
G4double fBiasingPostStepGPIL = -1.0;
G4double fWrappedProcessInteractionLength = -1.0; // -- inverse of analog cross-section
G4ForceCondition fWrappedProcessForceCondition = NotForced;
G4ForceCondition fBiasingForceCondition = NotForced;
G4double fWrappedProcessAlongStepGPIL = -1.0;
G4double fBiasingAlongStepGPIL = -1.0;
G4GPILSelection fWrappedProcessGPILSelection = NotCandidateForSelection;
G4GPILSelection fBiasingGPILSelection = NotCandidateForSelection;
const G4VBiasingInteractionLaw* fBiasingInteractionLaw = nullptr;
const G4VBiasingInteractionLaw* fPreviousBiasingInteractionLaw = nullptr;
G4InteractionLawPhysical* fPhysicalInteractionLaw = nullptr;
G4ParticleChangeForOccurenceBiasing* fOccurenceBiasingParticleChange = nullptr;
G4ParticleChangeForNothing* fDummyParticleChange = nullptr;
G4bool fFirstLastFlags[8];
// -- MUST be **thread local**:
static G4Cache<G4bool> fResetInteractionLaws;
static G4Cache<G4bool> fCommonStart;
static G4Cache<G4bool> fCommonEnd;
static G4Cache<G4bool> fDoCommonConfigure;
// -- the instance being "firstGPIL" does work shared by other instances:
G4bool fIamFirstGPIL = false;
const G4ProcessManager* fProcessManager;
// -- MUST be **thread local**:
static G4Cache<G4bool> fResetInteractionLaws;
static G4Cache<G4bool> fCommonStart;
static G4Cache<G4bool> fCommonEnd;
static G4Cache<G4bool> fDoCommonConfigure;
const G4ProcessManager* fProcessManager = nullptr;
// -- the data shared among processes attached to a same process manager:
G4BiasingProcessSharedData* fSharedData;
// -- the data shared among processes attached to a same process manager:
G4BiasingProcessSharedData* fSharedData = nullptr;
};
#endif
@@ -23,30 +23,29 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//--------------------------------------------------------------------------
//
// G4BiasingProcessSharedData
//
// Class Description:
// This class represents the data that the G4BiasingProcessInterface
// objects attached to a same particle / hold by a same G4ProcessManager
// share. It allows the active G4BiasingProcessInterface objects to share
// information on operations that are common the these instances:
// - the current and previous G4VBiasingOperator objects (their
// pointers are collected once, at the beginning of the PostStepGPIL
// by the first interface invoked)
// - add the list of cooperating G4BiasingProcessInterface objects,
// acting on a same particle type.
// G4BiasingProcessInterface is friend class of this one.
//---------------------------------------------------------------------------
// Initial version Sep. 2014 M. Verderi
//
// This class represents the data that the G4BiasingProcessInterface
// objects attached to a same particle / hold by a same G4ProcessManager
// share. It allows the active G4BiasingProcessInterface objects to share
// information on operations that are common the these instances:
// - the current and previous G4VBiasingOperator objects (their
// pointers are collected once, at the beginning of the PostStepGPIL
// by the first interface invoked)
// - add the list of cooperating G4BiasingProcessInterface objects,
// acting on a same particle type.
// G4BiasingProcessInterface is friend class of this one.
//
// Author: Marc Verderi, September 2014.
// --------------------------------------------------------------------
#ifndef G4BiasingProcessSharedData_h
#define G4BiasingProcessSharedData_h
#define G4BiasingProcessSharedData_h 1
#include "globals.hh"
#include "G4Cache.hh"
#include <vector>
class G4VBiasingOperator;
@@ -54,81 +53,72 @@ class G4BiasingProcessInterface;
class G4ProcessManager;
class G4ParallelGeometriesLimiterProcess;
class G4BiasingProcessSharedData {
class G4BiasingProcessSharedData
{
friend class G4BiasingProcessInterface;
friend class G4ParallelGeometriesLimiterProcess;
friend class G4BiasingProcessInterface;
friend class G4ParallelGeometriesLimiterProcess;
public:
public:
// -------------------------
// -- Public access methods:
// -------------------------
// -- The biasing process interface objects sharing this shared data class:
const std::vector< const G4BiasingProcessInterface* >& GetBiasingProcessInterfaces() const
{ return fPublicBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetPhysicsBiasingProcessInterfaces() const
{ return fPublicPhysicsBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetNonPhysicsBiasingProcessInterfaces() const
{ return fPublicNonPhysicsBiasingProcessInterfaces; }
// -------------------------
// -- Public access methods:
// -------------------------
// -- The biasing process interface objects sharing this shared data class:
const std::vector< const G4BiasingProcessInterface* >& GetBiasingProcessInterfaces() const
{ return fPublicBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetPhysicsBiasingProcessInterfaces() const
{ return fPublicPhysicsBiasingProcessInterfaces; }
const std::vector< const G4BiasingProcessInterface* >& GetNonPhysicsBiasingProcessInterfaces() const
{ return fPublicNonPhysicsBiasingProcessInterfaces; }
// -- The possible geometry limiter process:
const G4ParallelGeometriesLimiterProcess* GetParallelGeometriesLimiterProcess() const
{ return fParallelGeometriesLimiterProcess; }
// -- The possible geometry limiter process:
const G4ParallelGeometriesLimiterProcess* GetParallelGeometriesLimiterProcess() const
{ return fParallelGeometriesLimiterProcess; }
private:
// -- Methods used by the G4BiasingProcessInterface objects.
// -- Object is created by G4BiasingProcessInterface object:
G4BiasingProcessSharedData( const G4ProcessManager* mgr)
: fProcessManager(mgr) {}
~G4BiasingProcessSharedData() {}
// -- biasing operators:
void CurrentBiasingOperator( G4VBiasingOperator* );
G4VBiasingOperator* CurrentBiasingOperator() const;
void PreviousBiasingOperator( G4VBiasingOperator* );
G4VBiasingOperator* PreviousBiasingOperator() const;
private:
const G4ProcessManager* fProcessManager;
// -- biasing operators:
G4VBiasingOperator* fCurrentBiasingOperator = nullptr;
G4VBiasingOperator* fPreviousBiasingOperator = nullptr;
G4VBiasingOperator* fParallelGeometryOperator = nullptr;
G4VBiasingOperator* fMassGeometryOperator = nullptr;
// --
G4bool fIsNewOperator = true;
G4bool fLeavingPreviousOperator = false;
// -- biasing process interfaces sharing this object:
std::vector < G4BiasingProcessInterface* > fBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fPhysicsBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fNonPhysicsBiasingProcessInterfaces;
// -- the same ones, for public use:
std::vector < const G4BiasingProcessInterface* > fPublicBiasingProcessInterfaces;
std::vector < const G4BiasingProcessInterface* > fPublicPhysicsBiasingProcessInterfaces;
std::vector < const G4BiasingProcessInterface* > fPublicNonPhysicsBiasingProcessInterfaces;
// -- possible process limiting step on parallel geometries:
G4ParallelGeometriesLimiterProcess* fParallelGeometriesLimiterProcess = nullptr;
private:
// -- Methods used by the G4BiasingProcessInterface objects, thanks to class friendness.
// -- Object is created by G4BiasingProcessInterface object:
G4BiasingProcessSharedData( const G4ProcessManager* mgr)
: fProcessManager (mgr),
fCurrentBiasingOperator ( nullptr ),
fPreviousBiasingOperator ( nullptr ),
fParallelGeometryOperator ( nullptr ),
fMassGeometryOperator ( nullptr ),
fIsNewOperator (true),
fLeavingPreviousOperator (false),
fParallelGeometriesLimiterProcess( nullptr )
{}
~G4BiasingProcessSharedData() {}
// -- biasing operators:
void CurrentBiasingOperator( G4VBiasingOperator* );
G4VBiasingOperator* CurrentBiasingOperator() const;
void PreviousBiasingOperator( G4VBiasingOperator* );
G4VBiasingOperator* PreviousBiasingOperator() const;
private:
// --
const G4ProcessManager* fProcessManager;
// -- biasing operators:
G4VBiasingOperator* fCurrentBiasingOperator;
G4VBiasingOperator* fPreviousBiasingOperator;
G4VBiasingOperator* fParallelGeometryOperator;
G4VBiasingOperator* fMassGeometryOperator;
// --
G4bool fIsNewOperator;
G4bool fLeavingPreviousOperator;
// -- biasing process interfaces sharing this object:
std::vector < G4BiasingProcessInterface* > fBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fPhysicsBiasingProcessInterfaces;
std::vector < G4BiasingProcessInterface* > fNonPhysicsBiasingProcessInterfaces;
// -- the same ones, for public use:
std::vector < const G4BiasingProcessInterface* > fPublicBiasingProcessInterfaces;
std::vector < const G4BiasingProcessInterface* > fPublicPhysicsBiasingProcessInterfaces;
std::vector < const G4BiasingProcessInterface* > fPublicNonPhysicsBiasingProcessInterfaces;
// -- possible process limiting step on parallel geometries:
G4ParallelGeometriesLimiterProcess* fParallelGeometriesLimiterProcess;
// -- thread local:
// -- Map between process managers and shared data. This map is made of
// -- pointers of G4BiasingSharedData instead of objects themselves :
// -- each process needs to keep a valid pointer of a shared data object
// -- but a map of object will make pointers invalid when map is increased.
static G4MapCache< const G4ProcessManager*,
G4BiasingProcessSharedData* > fSharedDataMap;
// -- thread local:
// -- Map between process managers and shared data. This map is made of
// -- pointers of G4BiasingSharedData instead of objects themselves :
// -- each process needs to keep a valid pointer of a shared data object
// -- but a map of object will make pointers invalid when map is increased.
static G4MapCache< const G4ProcessManager*, G4BiasingProcessSharedData* > fSharedDataMap;
};
#endif
@@ -23,23 +23,17 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4ILawCommonTruncatedExp
//
// Class Description:
// A G4VBiasingInteractionLaw representing a truncated exponential
// law : an exponential law acting on [0,L] segment. This law is
// Common as it collects several process cross-sections, which sum
// is used to drive the law.
//
// ---------------------------------------------------------------
// Refactored version Oct. 2014 M. Verderi
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingInteractionLaw representing a truncated exponential
// law : an exponential law acting on [0,L] segment. This law is
// Common as it collects several process cross-sections, which sum
// is used to drive the law.
//
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4ILawCommonTruncatedExp_hh
#define G4ILawCommonTruncatedExp_hh 1
@@ -49,38 +43,46 @@
class G4ILawCommonTruncatedExp : public G4VBiasingInteractionLaw
{
public:
G4ILawCommonTruncatedExp(G4String name = "expSharedForceInteractionLaw");
virtual ~G4ILawCommonTruncatedExp();
public:
G4ILawCommonTruncatedExp(const G4String& name = "expSharedForceInteractionLaw");
virtual ~G4ILawCommonTruncatedExp();
public:
virtual G4bool IsSingular() const
{return fExpInteractionLaw.IsSingular();}
virtual G4bool IsEffectiveCrossSectionInfinite() const
{return fExpInteractionLaw.IsEffectiveCrossSectionInfinite();}
private:
// -- sample the distribution:
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
// -- in this case, cheat by returning DBL_MAX, to let operation proposing the
// -- step length in the alongGPIL
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
public:
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
virtual G4bool IsSingular() const
{ return fExpInteractionLaw.IsSingular(); }
virtual G4bool IsEffectiveCrossSectionInfinite() const
{ return fExpInteractionLaw.IsEffectiveCrossSectionInfinite(); }
public:
void SetForceCrossSection( G4double xs ) { fExpInteractionLaw.SetForceCrossSection( xs ); }
void SetSelectedProcessXSfraction( G4double fXS ) { fSelectedProcessXSfraction = fXS; }
G4double SetSelectedProcessXSfraction() const { return fSelectedProcessXSfraction; }
void SetMaximumDistance(G4double d) { fExpInteractionLaw.SetMaximumDistance(d); }
G4double GetMaximumDistance() const { return fExpInteractionLaw.GetMaximumDistance(); }
G4double GetInteractionDistance() const { return fExpInteractionLaw.GetInteractionDistance(); }
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
private:
G4ILawTruncatedExp fExpInteractionLaw;
G4double fSelectedProcessXSfraction;
G4double fInteractionDistance;
void SetForceCrossSection( G4double xs )
{ fExpInteractionLaw.SetForceCrossSection( xs ); }
void SetSelectedProcessXSfraction( G4double fXS )
{ fSelectedProcessXSfraction = fXS; }
G4double SetSelectedProcessXSfraction() const
{ return fSelectedProcessXSfraction; }
void SetMaximumDistance(G4double d)
{ fExpInteractionLaw.SetMaximumDistance(d); }
G4double GetMaximumDistance() const
{ return fExpInteractionLaw.GetMaximumDistance(); }
G4double GetInteractionDistance() const
{ return fExpInteractionLaw.GetInteractionDistance(); }
private:
// -- sample the distribution:
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
// -- in this case, cheat by returning DBL_MAX, to let operation proposing the
// -- step length in the alongGPIL
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
private:
G4ILawTruncatedExp fExpInteractionLaw;
G4double fSelectedProcessXSfraction = 0.0;
G4double fInteractionDistance = 0.0;
};
#endif
@@ -23,23 +23,19 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4ILawForceFreeFlight
//
// Class Description:
// A G4VBiasingInteractionLaw representing the "interaction" law
// for a force free flight, ie, a particle which does not interact.
// It is a limit case for which the non-interaction probability over
// a segment is always 1, and the effective cross-section always
// zero.
// This singular behavior is signaled by the IsSingular()
// method returning always true.
//
// ---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingInteractionLaw representing the "interaction" law
// for a force free flight, ie, a particle which does not interact.
// It is a limit case for which the non-interaction probability over
// a segment is always 1, and the effective cross-section always
// zero. This singular behavior is signaled by the IsSingular()
// method returning always true.
//
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4ILawForceFreeFlight_hh
#define G4ILawForceFreeFlight_hh 1
@@ -47,18 +43,19 @@
class G4ILawForceFreeFlight : public G4VBiasingInteractionLaw
{
public:
G4ILawForceFreeFlight(G4String name = "forceFreeFlightLaw");
virtual ~G4ILawForceFreeFlight();
public:
G4ILawForceFreeFlight(const G4String& name = "forceFreeFlightLaw");
virtual ~G4ILawForceFreeFlight();
public:
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
// -- sample the distribution
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
virtual G4bool IsSingular() const {return true;}
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
// -- sample the distribution
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
virtual G4bool IsSingular() const { return true; }
};
#endif
@@ -23,20 +23,16 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4ILawTruncatedExp
//
// Class Description:
// A G4VBiasingInteractionLaw representing a truncated exponential
// law : an exponential law acting on [0,L] segment. The law is
// driven by a cross-section.
//
// ---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// A G4VBiasingInteractionLaw representing a truncated exponential
// law : an exponential law acting on [0,L] segment. The law is
// driven by a cross-section.
//
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4ILawTruncatedExp_hh
#define G4ILawTruncatedExp_hh 1
@@ -44,34 +40,32 @@
class G4ILawTruncatedExp : public G4VBiasingInteractionLaw
{
public:
G4ILawTruncatedExp(G4String name = "expForceInteractionLaw");
virtual ~G4ILawTruncatedExp();
public:
G4ILawTruncatedExp(const G4String& name = "expForceInteractionLaw");
virtual ~G4ILawTruncatedExp();
public:
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
// -- sample the distribution
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
virtual G4bool IsSingular() const {return fIsSingular;}
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
// -- sample the distribution
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
virtual G4bool IsSingular() const { return fIsSingular; }
public:
void SetForceCrossSection(G4double xs);
void SetForceCrossSection(G4double xs);
public:
void SetMaximumDistance(G4double d) { fMaximumDistance = d;}
G4double GetMaximumDistance() const { return fMaximumDistance;}
G4double GetInteractionDistance() const { return fInteractionDistance; }
void SetMaximumDistance(G4double d) { fMaximumDistance = d; }
G4double GetMaximumDistance() const { return fMaximumDistance; }
G4double GetInteractionDistance() const { return fInteractionDistance; }
private:
G4double fMaximumDistance;
G4double fCrossSection;
G4double fCrossSectionDefined;
G4bool fIsSingular;
G4double fInteractionDistance;
private:
G4double fMaximumDistance = 0.0;
G4double fCrossSection = 0.0;
G4bool fCrossSectionDefined = false;
G4bool fIsSingular = false;
G4double fInteractionDistance = 0.0;
};
#endif
@@ -23,19 +23,15 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4InteractionLawPhysical
//
// Class Description:
// A G4VBiasingInteractionLaw representing the usual
//
// A G4VBiasingInteractionLaw representing the usual
// physical exponential law, of constant cross-section of the step.
//
// ---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// Author: Marc Verderi, November 2013.
// --------------------------------------------------------------------
#ifndef G4InteractionLawPhysical_hh
#define G4InteractionLawPhysical_hh 1
@@ -43,28 +39,26 @@
class G4InteractionLawPhysical : public G4VBiasingInteractionLaw
{
public:
G4InteractionLawPhysical(G4String name = "exponentialLaw");
virtual ~G4InteractionLawPhysical();
public:
public:
void SetPhysicalCrossSection(G4double crossSection);
G4double GetPhysicalCrossSection() const {return fCrossSection;}
G4InteractionLawPhysical(const G4String& name = "exponentialLaw");
virtual ~G4InteractionLawPhysical();
void SetPhysicalCrossSection(G4double crossSection);
G4double GetPhysicalCrossSection() const { return fCrossSection; }
public:
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
// -- sample the distribution
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
virtual G4double ComputeEffectiveCrossSectionAt(G4double length) const;
virtual G4double ComputeNonInteractionProbabilityAt(G4double length) const;
// -- sample the distribution
virtual G4double SampleInteractionLength();
// -- move by true path length, this position becomes the new initial point
virtual G4double UpdateInteractionLengthForStep(G4double truePathLength);
private:
private:
G4double fCrossSection;
G4bool fCrossSectionDefined;
G4double fNumberOfInteractionLength;
G4double fCrossSection = 0.0;
G4bool fCrossSectionDefined = false;
G4double fNumberOfInteractionLength = -1.0;
};
#endif
@@ -23,25 +23,17 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4ParallelGeometriesLimiterProcess
//
// Description:
//
//
//---------------------------------------------------------------
// Process dedicated to limiting the step on boudaries of
// parallel geometries used for the generic biasing.
//
// G4ParallelGeometriesLimiterProcess.hh
//
// Description:
// Process dedicated to limiting the step on boudaries of
// parallel geometries used for the generic biasing.
//
// History:
// Sep 16: Creation.
//
//---------------------------------------------------------------
// Author: Marc Verderi, September 2016.
// --------------------------------------------------------------------
#ifndef G4ParallelGeometriesLimiterProcess_hh
#define G4ParallelGeometriesLimiterProcess_hh
#define G4ParallelGeometriesLimiterProcess_hh 1
#include "globals.hh"
#include "G4VProcess.hh"
@@ -50,133 +42,130 @@
#include "G4VPhysicalVolume.hh"
#include "G4ParticleChangeForNothing.hh"
#include "G4FieldTrack.hh"
class G4PathFinder;
class G4TransportationManager;
// Class Description:
// -- G4VProcess limiting the step on parallel geometries used by generic biasing.
class G4ParallelGeometriesLimiterProcess : public G4VProcess
{
public:
// --------------------------
// -- Constructor/Destructor:
// --------------------------
G4ParallelGeometriesLimiterProcess(const G4String& processName = "biasLimiter");
public:
public:
virtual ~G4ParallelGeometriesLimiterProcess()
{}
// ----------------------------------------------------
// -- Registration / deregistration of parallel worlds.
// -- Access to the list of registered parallel worlds.
// ----------------------------------------------------
void AddParallelWorld(const G4String& parallelWorldName);
void RemoveParallelWorld(const G4String& parallelWorldName);
// -- The list of registered parallel worlds:
const std::vector< G4VPhysicalVolume* >& GetParallelWorlds() const { return fParallelWorlds; }
// --------------------------
// -- Constructor/Destructor:
// --------------------------
G4ParallelGeometriesLimiterProcess(const G4String& processName = "biasLimiter");
// -- Get the parallel world volume index in the list of world volumes handled
// -- by the process. This index can then be used to access current volume and step
// -- limitation status below.
// -- If the world passed is unknown to the process, -1 is returned.
G4int GetParallelWorldIndex( const G4VPhysicalVolume* parallelWorld ) const;
G4int GetParallelWorldIndex( G4String parallelWorldName ) const;
virtual ~G4ParallelGeometriesLimiterProcess() = default;
// ----------------------------------------------------
// -- Registration / deregistration of parallel worlds.
// -- Access to the list of registered parallel worlds.
// ----------------------------------------------------
void AddParallelWorld(const G4String& parallelWorldName);
void RemoveParallelWorld(const G4String& parallelWorldName);
// -- The list of registered parallel worlds:
const std::vector< G4VPhysicalVolume* >& GetParallelWorlds() const
{ return fParallelWorlds; }
// ---------------------
// -- Active navigators:
// ---------------------
// -- The list of navigators handled by the process:
const std::vector< G4Navigator* >& GetActiveNavigators() const { return fParallelWorldNavigators; }
// -- The navigator used for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
const G4Navigator* GetNavigator( G4int worldIndex ) const { return fParallelWorldNavigators[size_t(worldIndex)]; }
// ---------------------------------------------------
// -- Previous and current steps geometry information:
// ---------------------------------------------------
// -- The "switch" between the previous and current step is done in the PostStepGPIL
// -- The update on the current step is done:
// -- - in the PostStepGPIL for the volumes
// -- - in the AlongStepGPIL for the step limitations
// --
// -- The list of previous step and current step volumes:
const std::vector< const G4VPhysicalVolume* >& GetCurrentVolumes() const { return fCurrentVolumes; }
const std::vector< const G4VPhysicalVolume* >& GetPreviousVolumes() const { return fPreviousVolumes; }
// -- The current and previous volume for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
const G4VPhysicalVolume* GetCurrentVolume( G4int worldIndex ) const { return fCurrentVolumes[size_t(worldIndex)]; }
const G4VPhysicalVolume* GetPreviousVolume( G4int worldIndex ) const { return fPreviousVolumes[size_t(worldIndex)]; }
// -- Flags telling about step limitation in previous and current step:
const std::vector< G4bool >& GetIsLimiting() const { return fParallelWorldIsLimiting; }
const std::vector< G4bool >& GetWasLimiting() const { return fParallelWorldWasLimiting; }
// -- The current and previous step limitation status for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
G4bool GetIsLimiting( G4int worldIndex ) const { return fParallelWorldIsLimiting[size_t(worldIndex)]; }
G4bool GetWasLimiting( G4int worldIndex ) const { return fParallelWorldWasLimiting[size_t(worldIndex)]; }
// --------------------------------------------------------------
// From process interface
// --------------------------------------------------------------
// -- Start/End tracking:
void StartTracking(G4Track*);
void EndTracking();
// -- Get the parallel world volume index in the list of world volumes handled
// -- by the process. This index can then be used to access current volume and step
// -- limitation status below.
// -- If the world passed is unknown to the process, -1 is returned.
G4int GetParallelWorldIndex( const G4VPhysicalVolume* parallelWorld ) const;
G4int GetParallelWorldIndex( const G4String& parallelWorldName ) const;
// --------------------
// -- PostStep methods:
// --------------------
// -- PostStepGPIL is used to collect up to date volumes in the parallel geometries:
G4double PostStepGetPhysicalInteractionLength(const G4Track&, G4double, G4ForceCondition*);
// -- PostStepDoIt is not used (never called):
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step& )
{ return nullptr; }
// ---------------------
// -- Active navigators:
// ---------------------
// -- The list of navigators handled by the process:
const std::vector< G4Navigator* >& GetActiveNavigators() const
{ return fParallelWorldNavigators; }
// -- The navigator used for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
const G4Navigator* GetNavigator( G4int worldIndex ) const
{ return fParallelWorldNavigators[std::size_t(worldIndex)]; }
// ---------------------------------------------------------------------------
// -- Along step used for limiting the step on parallel geometries boundaries:
// ---------------------------------------------------------------------------
G4double AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection);
G4VParticleChange* AlongStepDoIt(const G4Track& track,
const G4Step& step);
// ---------------------------
// -- AtRest methods not used:
// ---------------------------
G4double AtRestGetPhysicalInteractionLength(const G4Track&,
G4ForceCondition*)
{ return DBL_MAX; }
G4VParticleChange* AtRestDoIt(const G4Track&, const G4Step&)
{ return nullptr; }
// ---------------------------------------------------
// -- Previous and current steps geometry information:
// ---------------------------------------------------
// -- The "switch" between the previous and current step is done in the PostStepGPIL
// -- The update on the current step is done:
// -- - in the PostStepGPIL for the volumes
// -- - in the AlongStepGPIL for the step limitations
// --
// -- The list of previous step and current step volumes:
const std::vector< const G4VPhysicalVolume* >& GetCurrentVolumes() const
{ return fCurrentVolumes; }
const std::vector< const G4VPhysicalVolume* >& GetPreviousVolumes() const
{ return fPreviousVolumes; }
// -- The current and previous volume for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
const G4VPhysicalVolume* GetCurrentVolume( G4int worldIndex ) const
{ return fCurrentVolumes[std::size_t(worldIndex)]; }
const G4VPhysicalVolume* GetPreviousVolume( G4int worldIndex ) const
{ return fPreviousVolumes[std::size_t(worldIndex)]; }
// -- Flags telling about step limitation in previous and current step:
const std::vector< G4bool >& GetIsLimiting() const
{ return fParallelWorldIsLimiting; }
const std::vector< G4bool >& GetWasLimiting() const
{ return fParallelWorldWasLimiting; }
// -- The current and previous step limitation status for the passed parallel world index (obtained with GetParallelWorldIndex(...) above)
// -- Note that no boundary checks are done on the index passed.
G4bool GetIsLimiting( G4int worldIndex ) const
{ return fParallelWorldIsLimiting[std::size_t(worldIndex)]; }
G4bool GetWasLimiting( G4int worldIndex ) const
{ return fParallelWorldWasLimiting[std::size_t(worldIndex)]; }
// --
virtual void SetProcessManager(const G4ProcessManager*);
// --------------------------------------------------------------
// From process interface
// --------------------------------------------------------------
// -- Start/End tracking:
void StartTracking(G4Track*);
void EndTracking();
// --------------------
// -- PostStep methods:
// --------------------
// -- PostStepGPIL is used to collect up to date volumes in the parallel geometries:
G4double PostStepGetPhysicalInteractionLength(const G4Track&, G4double, G4ForceCondition*);
// -- PostStepDoIt is not used (never called):
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step& ) { return nullptr; }
// ---------------------------------------------------------------------------
// -- Along step used for limiting the step on parallel geometries boundaries:
// ---------------------------------------------------------------------------
G4double AlongStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize, G4double currentMinimumStep,
G4double& proposedSafety, G4GPILSelection* selection);
G4VParticleChange* AlongStepDoIt(const G4Track& track, const G4Step& step);
private:
std::vector< G4VPhysicalVolume* > fParallelWorlds;
std::vector< G4Navigator* > fParallelWorldNavigators;
std::vector< G4int > fParallelWorldNavigatorIndeces;
std::vector< G4double > fParallelWorldSafeties;
std::vector< G4bool > fParallelWorldIsLimiting;
std::vector< G4bool > fParallelWorldWasLimiting;
std::vector< const G4VPhysicalVolume* > fCurrentVolumes;
std::vector< const G4VPhysicalVolume* > fPreviousVolumes;
G4double fParallelWorldSafety;
G4bool fIsTrackingTime;
G4FieldTrack fFieldTrack;
G4ParticleChangeForNothing fDummyParticleChange;
G4PathFinder* fPathFinder;
G4TransportationManager* fTransportationManager;
// ---------------------------
// -- AtRest methods not used:
// ---------------------------
G4double AtRestGetPhysicalInteractionLength(const G4Track&, G4ForceCondition*)
{ return DBL_MAX; }
G4VParticleChange* AtRestDoIt(const G4Track&, const G4Step&)
{ return nullptr; }
// --
virtual void SetProcessManager(const G4ProcessManager*);
private:
std::vector< G4VPhysicalVolume* > fParallelWorlds;
std::vector< G4Navigator* > fParallelWorldNavigators;
std::vector< G4int > fParallelWorldNavigatorIndeces;
std::vector< G4double > fParallelWorldSafeties;
std::vector< G4bool > fParallelWorldIsLimiting;
std::vector< G4bool > fParallelWorldWasLimiting;
std::vector< const G4VPhysicalVolume* > fCurrentVolumes;
std::vector< const G4VPhysicalVolume* > fPreviousVolumes;
G4double fParallelWorldSafety = 0.0;
G4bool fIsTrackingTime = false;
G4FieldTrack fFieldTrack = '0';
G4ParticleChangeForNothing fDummyParticleChange;
G4PathFinder* fPathFinder = nullptr;
G4TransportationManager* fTransportationManager = nullptr;
};
#endif
@@ -23,38 +23,36 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4ParticleChangeForNothing
//
// Class Description:
// A G4VParticleChange used in case of no interaction.
//
// A G4VParticleChange used in case of no interaction.
//
// Author: Marc Verderi, November 2013.
// ---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
#ifndef G4ParticleChangeForNothing_hh
#define G4ParticleChangeForNothing_hh 1
#include "G4VParticleChange.hh"
class G4ParticleChangeForNothing : public G4VParticleChange {
public:
G4ParticleChangeForNothing() : G4VParticleChange() {}
~G4ParticleChangeForNothing() {}
class G4ParticleChangeForNothing : public G4VParticleChange
{
public:
public:
// -- from base class G4VParticleChange:
virtual void Initialize(const G4Track &track)
{
theStatusChange = track.GetTrackStatus();
theNumberOfSecondaries = 0;
}
virtual G4Step* UpdateStepForAtRest (G4Step* step) {return step;}
virtual G4Step* UpdateStepForAlongStep(G4Step* step) {return step;}
virtual G4Step* UpdateStepForPostStep (G4Step* step) {return step;}
G4ParticleChangeForNothing() = default;
~G4ParticleChangeForNothing() = default;
// -- from base class G4VParticleChange:
virtual void Initialize(const G4Track& track)
{
theStatusChange = track.GetTrackStatus();
theNumberOfSecondaries = 0;
}
virtual G4Step* UpdateStepForAtRest (G4Step* step) { return step; }
virtual G4Step* UpdateStepForAlongStep(G4Step* step) { return step; }
virtual G4Step* UpdateStepForPostStep (G4Step* step) { return step; }
};
#endif
@@ -23,62 +23,63 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// ---------------------------------------------------------------
//
// G4ParticleChangeForOccurenceBiasing
//
// Class Description:
// A G4VParticleChange dedicated to occurrence biasing : it
//
// A G4VParticleChange dedicated to occurrence biasing : it
// applies weights for non-interaction over a step, and for
// interaction at the end of the step (if interaction occurs) on
// top of a given particle change, that is the one produced by a
// physics process (biased in its final state or not).
//
// ---------------------------------------------------------------
// Initial version Nov. 2013 M. Verderi
// Author: Marc Verderi, November 2013.
//
// --------------------------------------------------------------------
#ifndef G4ParticleChangeForOccurenceBiasing_hh
#define G4ParticleChangeForOccurenceBiasing_hh 1
#include "G4VParticleChange.hh"
class G4ParticleChangeForOccurenceBiasing : public G4VParticleChange {
public:
G4ParticleChangeForOccurenceBiasing(G4String name);
~G4ParticleChangeForOccurenceBiasing();
class G4ParticleChangeForOccurenceBiasing : public G4VParticleChange
{
public:
public:
void SetOccurenceWeightForNonInteraction(G4double w) {fOccurenceWeightForNonInteraction = w;}
G4double GetOccurenceWeightForNonInteraction() const {return fOccurenceWeightForNonInteraction;}
void SetOccurenceWeightForInteraction(G4double w) {fOccurenceWeightForInteraction = w;}
G4double GetOccurenceWeightForInteraction() const {return fOccurenceWeightForInteraction;}
G4ParticleChangeForOccurenceBiasing(const G4String& name);
~G4ParticleChangeForOccurenceBiasing() = default;
public:
// -- set a wrapped particle change AND USE IT TO UPDATE this occurrence particle change state:
void SetWrappedParticleChange(G4VParticleChange* wpc);
G4VParticleChange* GetWrappedParticleChange() const {return fWrappedParticleChange;}
public:
// -- collect the secondaries from the wrapped particle change, apply weight correction, and clear wrapped particle change:
void StealSecondaries();
void SetOccurenceWeightForNonInteraction(G4double w)
{ fOccurenceWeightForNonInteraction = w; }
G4double GetOccurenceWeightForNonInteraction() const
{ return fOccurenceWeightForNonInteraction; }
void SetOccurenceWeightForInteraction(G4double w)
{ fOccurenceWeightForInteraction = w; }
G4double GetOccurenceWeightForInteraction() const
{ return fOccurenceWeightForInteraction; }
// -- set a wrapped particle change AND USE IT TO UPDATE this occurrence
// particle change state:
void SetWrappedParticleChange(G4VParticleChange* wpc);
G4VParticleChange* GetWrappedParticleChange() const
{ return fWrappedParticleChange; }
// -- collect the secondaries from the wrapped particle change,
// apply weight correction, and clear wrapped particle change:
void StealSecondaries();
public:
// -- from base class G4VParticleChange:
virtual G4Step* UpdateStepForAtRest (G4Step* step);
virtual G4Step* UpdateStepForAlongStep(G4Step* step);
virtual G4Step* UpdateStepForPostStep (G4Step* step);
// -- from base class G4VParticleChange:
virtual G4Step* UpdateStepForAtRest (G4Step* step);
virtual G4Step* UpdateStepForAlongStep(G4Step* step);
virtual G4Step* UpdateStepForPostStep (G4Step* step);
public:
const G4String& GetName() const {return fName;}
const G4String& GetName() const { return fName; }
private:
G4String fName;
G4VParticleChange* fWrappedParticleChange;
G4double fOccurenceWeightForNonInteraction;
G4double fOccurenceWeightForInteraction;
private:
G4String fName;
G4VParticleChange* fWrappedParticleChange = nullptr;
G4double fOccurenceWeightForNonInteraction = -1.0;
G4double fOccurenceWeightForInteraction = -1.0;
};
#endif
@@ -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;
}