Import Geant4 11.1.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2022-07-01 10:44:02 +02:00
parent b3bf75a2a1
commit c07cea1fe0
2172 changed files with 183300 additions and 123938 deletions
@@ -21,7 +21,6 @@ CPPFLAGS += \
-I$(G4BASE)/geometry/biasing/include \
-I$(G4BASE)/track/include \
-I$(G4BASE)/processes/management/include \
-I$(G4BASE)/processes/electromagnetic/utils/include \
-I$(G4BASE)/processes/cuts/include \
-I$(G4BASE)/particles/management/include \
-I$(G4BASE)/materials/include \
+39 -18
View File
@@ -1,26 +1,47 @@
-------------------------------------------------------------------
# Category transport History
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
See `CONTRIBUTING.rst` for details of **required** info/format for each entry,
which **must** added in reverse chronological order (newest at the top).
It must **not** be used as a substitute for writing good git commit messages!
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
-------------------------------------------------------------------------------
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
May 5th 2022, Gabriele Cosmo transport-V10-07-04
----------------------------
- G4Transportation, G4CoupledTransportation: fixed misuse of bitwise '|'
## 2022-05-18 Gabriele Cosmo (transport-V11-00-06)
- `G4Transportation`, `G4CoupledTransportation`: fixed misuse of bitwise '|'
operator instead of logical.
## 2022-05-11 Jonas Hahnfeld (transport-V11-00-05)
- `G4Transportation`: Remove non-working check for any field
- Remove `PUBLIC` dependency on `G4magneticfield`, `G4navigation`
## 2022-04-24 Vladimir Ivanchenko (transport-V11-00-04)
- moved G4UserSpecialCuts to physics_lists/constructors/limiters
- GNUmakefile, source.cmake - removed dependence on electromagnetic/utils
## 2022-04-20 Jonas Hahnfeld (transport-V11-00-03)
- `G4CoupledTransportation`: Set flags from `G4Transportation`
* Replace `fFirstStepInAnyVolume` with `fFirstStepInVolume`
* Replace `fAnyGeometryLimitedStep` with `fGeometryLimitedStep`
* Remove wrong check in case of zero steps
- `G4Transportation`:
* Remove wrong check in case of zero steps
* Set step status on volume boundary
## 2022-01-17 Jonas Hahnfeld (transport-V11-00-02)
- Remove useless `const_cast` of `G4VSensitiveDetector`
## 2022-01-05 Jonas Hahnfeld (transport-V11-00-01)
- `G4CoupledTransportation`:
* Use new constant `G4TransportationManager::kMassNavigatorId`
* Inherit from `G4Transportation`, remove duplicated variables and methods
## 2021-12-10 Ben Morgan (transport-V11-00-00)
- Change to new Markdown History format
---
# History entries prior to 11.0
Sep 23rd 2021, Alberto Ribon transport-V10-07-03
----------------------------
- Added PARALLEL_WORLD_PROCESS to G4TransportationProcessType
@@ -46,25 +46,15 @@
#ifndef G4CoupledTransportation_hh
#define G4CoupledTransportation_hh 1
#include "G4VProcess.hh"
#include "G4FieldManager.hh"
#include "G4Navigator.hh"
#include "G4TransportationManager.hh"
#include "G4PropagatorInField.hh"
#include "G4PathFinder.hh"
#include "G4Transportation.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleChangeForTransport.hh"
class G4SafetyHelper;
class G4TransportationLogger;
class G4PathFinder;
class G4CoupledTransportation : public G4VProcess
class G4CoupledTransportation : public G4Transportation
{
// Concrete class that does the geometrical transport
public: // with description
@@ -79,10 +69,7 @@ class G4CoupledTransportation : public G4VProcess
G4GPILSelection* selection
);
G4VParticleChange* AlongStepDoIt(
const G4Track& track,
const G4Step& stepData
);
// AlongStepDoIt is implemented by G4Transportation.
G4VParticleChange* PostStepDoIt(
const G4Track& track,
@@ -90,51 +77,9 @@ class G4CoupledTransportation : public G4VProcess
);
// Responsible for the relocation
G4double PostStepGetPhysicalInteractionLength(
const G4Track& ,
G4double previousStepSize,
G4ForceCondition* pForceCond
);
// Forces the PostStepDoIt action to be called,
// but does not limit the step
// PostStepGetPhysicalInteractionLength is implemented by
// G4Transportation to force PostStepDoIt, but not limiting the step.
G4PropagatorInField* GetPropagatorInField();
void SetPropagatorInField( G4PropagatorInField* pFieldPropagator);
// Access/set the assistant class that Propagate in a Field
inline G4double GetThresholdWarningEnergy() const;
inline G4double GetThresholdImportantEnergy() const;
inline G4int GetThresholdTrials() const;
inline void SetThresholdWarningEnergy( G4double newEnWarn );
inline void SetThresholdImportantEnergy( G4double newEnImp );
inline void SetThresholdTrials(G4int newMaxTrials );
void SetHighLooperThresholds(); // Shortcut method - old values (meant for HEP)
void SetLowLooperThresholds(); // Set low thresholds - for low-E applications
void PushThresholdsToLogger(); // Inform logger of current thresholds
void ReportLooperThresholds(); // Print values of looper thresholds
// Get/Set parameters for killing loopers:
// Above 'important' energy a 'looping' particle in field will
// *NOT* be abandoned, except after fThresholdTrials attempts.
// Below Warning energy, no verbosity for looping particles is issued
inline G4double GetMaxEnergyKilled() const;
inline G4double GetSumEnergyKilled() const;
inline void ResetKilledStatistics( G4int report = 1);
// Statistics for tracks killed (currently due to looping in field)
static G4bool EnableMagneticMoment(G4bool useMoment=true);
// Whether to deflect particles with force due to magnetic moment
static G4bool EnableGravity(G4bool useGravity);
// Turn on the capability to deflect particles with a gravity field
static void SetSilenceLooperWarnings( G4bool val);
// Do not warn (or throw exception) about 'looping' particles
static G4bool GetSilenceLooperWarnings();
static void SetSignifyStepsInAnyVolume( G4bool anyVol )
{ fSignifyStepInAnyVolume = anyVol; }
static G4bool GetSignifyStepsInAnyVolume()
@@ -146,8 +91,8 @@ class G4CoupledTransportation : public G4VProcess
// The following methods give access to first/last step in particular
// geometry *independent* of the choice of the 'Signify' flag
//
G4bool IsFirstStepInAnyVolume() const { return fFirstStepInAnyVolume; }
G4bool IsLastStepInAnyVolume() const { return fAnyGeometryLimitedStep; }
G4bool IsFirstStepInAnyVolume() const { return fFirstStepInVolume; }
G4bool IsLastStepInAnyVolume() const { return fGeometryLimitedStep; }
G4bool IsFirstStepInMassVolume() const { return fFirstStepInMassVolume; }
G4bool IsLastStepInMassVolume() const { return fMassGeometryLimitedStep; }
@@ -160,130 +105,33 @@ class G4CoupledTransportation : public G4VProcess
{ return EnableMagneticMoment(useMoment); }
// Old name ... obsolete
G4double AtRestGetPhysicalInteractionLength( const G4Track& ,
G4ForceCondition* )
{ return -1.0; } // No operation in AtRestGPIL
G4VParticleChange* AtRestDoIt( const G4Track&, const G4Step&)
{ return 0; } // No operation in AtRestDoIt
void PrintStatistics( std::ostream& outStr) const;
protected:
G4bool DoesAnyFieldExist();
// Check whether any field exists in the geometry
// - replaces method that checked only whether a field for the world volume
void ReportInexactEnergy(G4double startEnergy, G4double endEnergy);
// Issue warning
void ReportMove( G4ThreeVector OldVector, G4ThreeVector NewVector,
const G4String& Quantity );
void ReportMissingLogger(const char * methodName);
private:
G4Navigator* fMassNavigator;
// The navigator for the 'mass' geometry
// (the real one, that physics occurs in)
G4PathFinder* fPathFinder;
G4int fNavigatorId;
// The PathFinder used to transport the particle
G4PropagatorInField* fFieldPropagator;
// Still required in order to find/set the fieldmanager
G4bool fAnyFieldExists;
// G4bool fStartedNewTrack; // True for first step or restarted tracking
// until first step's AlongStepGPIL
G4ThreeVector fTransportEndPosition;
G4ThreeVector fTransportEndMomentumDir;
G4double fTransportEndKineticEnergy;
G4ThreeVector fTransportEndSpin;
G4bool fMomentumChanged;
// The particle's state after this Step, Store for DoIt
G4bool fEndGlobalTimeComputed;
G4double fCandidateEndGlobalTime;
G4bool fParticleIsLooping;
G4bool fNewTrack;
G4ThreeVector fPreviousSftOrigin;
G4double fPreviousMassSafety;
G4double fPreviousFullSafety;
G4TouchableHandle fCurrentTouchableHandle;
// G4bool fFieldExists;
// Whether a magnetic field exists ...
// A data member for this is problematic: it is useful only if it
// can be initialised and updated -- and a scheme is not yet possible.
G4bool fMassGeometryLimitedStep;
// Flag to determine whether a 'mass' boundary was reached.
G4bool fAnyGeometryLimitedStep;
// Did any geometry limit the step ?
G4ParticleChangeForTransport fParticleChange;
// New ParticleChange
G4double fEndpointDistance;
// Thresholds for looping particles:
//
G4double fThreshold_Warning_Energy = 1.0 * CLHEP::keV; // Warn above this energy
G4double fThreshold_Important_Energy = 1.0 * CLHEP::MeV; // Give a few trial above this E
G4int fThresholdTrials = 10; // Number of trials an important looper survives
// Above 'important' energy a 'looping' particle in field will
// *NOT* be abandoned, except after fThresholdTrials attempts.
// Counter for steps in which particle reports 'looping',
// if it is above 'Important' Energy
//
G4int fNoLooperTrials=0;
// Statistics for tracks abandoned
//
G4double fSumEnergyKilled= 0.0;
G4double fSumEnerSqKilled= 0.0;
G4double fMaxEnergyKilled= -1.0;
G4int fMaxEnergyKilledPDG= 0;
unsigned long fNumLoopersKilled= 0;
G4double fSumEnergyKilled_NonElectron= 0.0;
G4double fSumEnerSqKilled_NonElectron= 0.0;
G4double fMaxEnergyKilled_NonElectron= -1.0;
G4int fMaxEnergyKilled_NonElecPDG= 0;
unsigned long fNumLoopersKilled_NonElectron= 0;
G4double fSumEnergySaved= 0.0;
G4double fMaxEnergySaved= -1.0;
G4double fSumEnergyUnstableSaved = 0.0;
G4SafetyHelper* fpSafetyHelper; // To pass it the safety value obtained
G4TransportationLogger* fpLogger; // Reports issues / raises warnings
private:
friend class G4Transportation;
static G4bool fUseMagneticMoment;
static G4bool fUseGravity;
static G4bool fSilenceLooperWarnings; // Flag to *Supress* all 'looper' warnings
private:
G4bool fFirstStepInMassVolume;
G4bool fFirstStepInAnyVolume;
// G4bool fLastStepInMassVolume; => use fMassGeometryLimitedStep
// G4bool fLastStepInAnyVolume; => use fAnyGeometryLimitedStep
static G4bool fSignifyStepInAnyVolume;
// True: First/Last step in any one of the geometries
// False: First/Last step in volume of 'mass' geometry
};
#include "G4CoupledTransportation.icc"
#endif
@@ -1,141 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// Inline function implementation.
// =======================================================================
// Created: 9 June 1998, J. Apostolakis
// =======================================================================
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4TransportationLogger.hh"
#include "G4FieldManagerStore.hh"
inline void G4CoupledTransportation::
SetPropagatorInField( G4PropagatorInField* pFieldPropagator)
{
fFieldPropagator= pFieldPropagator;
}
inline G4PropagatorInField* G4CoupledTransportation::GetPropagatorInField()
{
return fFieldPropagator;
}
inline G4bool G4CoupledTransportation::DoesAnyFieldExist()
{
G4FieldManagerStore* fieldMgrStore= G4FieldManagerStore::GetInstance();
return fieldMgrStore->size() > 0;
}
inline G4double G4CoupledTransportation::GetThresholdWarningEnergy() const
{
return fThreshold_Warning_Energy;
}
inline G4double G4CoupledTransportation::GetThresholdImportantEnergy() const
{
return fThreshold_Important_Energy;
}
inline G4int G4CoupledTransportation::GetThresholdTrials() const
{
return fThresholdTrials;
}
inline void G4CoupledTransportation::SetThresholdWarningEnergy( G4double newEnWarn )
{
fThreshold_Warning_Energy= newEnWarn;
if( fpLogger ) {
fpLogger->SetThresholdWarningEnergy( newEnWarn );
} else {
ReportMissingLogger("SetThresholdWarningEnergy");
}
// Update the information for correct reporting
}
inline void G4CoupledTransportation::SetThresholdImportantEnergy( G4double newEnImp )
{
fThreshold_Important_Energy = newEnImp;
if( fpLogger ) {
fpLogger->SetThresholdImportantEnergy( newEnImp );
// Update the information for correct reporting
} else {
ReportMissingLogger("SetThresholdImportantEnergy");
}
}
inline void G4CoupledTransportation::SetThresholdTrials(G4int newMaxTrials )
{
fThresholdTrials = newMaxTrials;
if( fpLogger ) {
fpLogger->SetThresholdTrials(newMaxTrials );
// Update the information for correct reporting
} else {
ReportMissingLogger("SetThresholdTrials");
}
}
inline G4double G4CoupledTransportation::GetMaxEnergyKilled() const
{
return fMaxEnergyKilled;
}
inline G4double G4CoupledTransportation::GetSumEnergyKilled() const
{
return fSumEnergyKilled;
}
inline void G4CoupledTransportation::ResetKilledStatistics(G4int report)
{
// Statistics for tracks killed (currently due to looping in field)
if( report )
{
G4cout << " G4CoupledTransportation: Statistics for looping particles "
<< G4endl;
G4cout << " Sum of energy of loopers killed: " << fSumEnergyKilled
<< G4endl;
G4cout << " Max energy of loopers killed: " << fMaxEnergyKilled
<< G4endl;
}
fSumEnergyKilled= 0;
fMaxEnergyKilled= -1.0*CLHEP::GeV;
}
inline void
G4CoupledTransportation::PushThresholdsToLogger()
{
if( fpLogger )
fpLogger->SetThresholds( GetThresholdWarningEnergy(),
GetThresholdImportantEnergy(),
GetThresholdTrials() );
else
ReportMissingLogger("PushThresholdsToLogger()");
}
@@ -44,17 +44,14 @@
#define G4Transportation_hh 1
#include "G4VProcess.hh"
#include "G4FieldManager.hh"
#include "G4Navigator.hh"
#include "G4TransportationManager.hh"
#include "G4PropagatorInField.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleChangeForTransport.hh"
class G4Navigator;
class G4PropagatorInField;
class G4SafetyHelper;
class G4CoupledTransportation;
class G4TransportationLogger;
class G4Transportation : public G4VProcess
@@ -63,7 +60,7 @@ class G4Transportation : public G4VProcess
public: // with description
G4Transportation( G4int verbosityLevel= 1);
G4Transportation( G4int verbosityLevel= 1, const G4String& aName = "Transportation");
~G4Transportation();
G4double AlongStepGetPhysicalInteractionLength(
@@ -155,15 +152,15 @@ class G4Transportation : public G4VProcess
protected:
G4bool DoesAnyFieldExist();
// Check whether any field exists in the geometry
// - replaces method that checked only whether a field for the world volume
void SetTouchableInformation(const G4TouchableHandle& touchable);
void ReportMissingLogger(const char * methodName);
private:
protected:
G4Navigator* fLinearNavigator;
// The navigator for the 'mass' geometry
// (the real one, that physics occurs in)
G4PropagatorInField* fFieldPropagator;
// The Propagators used to transport the particle
@@ -235,9 +232,8 @@ class G4Transportation : public G4VProcess
G4SafetyHelper* fpSafetyHelper; // To pass it the safety value obtained
G4TransportationLogger* fpLogger; // Reports issues / raises warnings
private:
protected:
friend class G4CoupledTransportation;
static G4bool fUseMagneticMoment;
static G4bool fUseGravity;
static G4bool fSilenceLooperWarnings; // Flag to *Supress* all 'looper' warnings
@@ -35,7 +35,6 @@
#include <CLHEP/Units/SystemOfUnits.h>
#include "G4TransportationLogger.hh"
#include "G4FieldManagerStore.hh"
inline void
G4Transportation::SetPropagatorInField( G4PropagatorInField* pFieldPropagator)
@@ -48,12 +47,6 @@ inline G4PropagatorInField* G4Transportation::GetPropagatorInField()
return fFieldPropagator;
}
inline G4bool G4Transportation::DoesAnyFieldExist()
{
G4FieldManagerStore* fieldMgrStore= G4FieldManagerStore::GetInstance();
return fieldMgrStore->size() > 0;
}
inline G4double G4Transportation::GetThresholdWarningEnergy() const
{
return fThreshold_Warning_Energy;
@@ -1,107 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// class description
//
// A "process" to be registered to the process manager of each particle,
// in the UserPhysicsList, in order to take into account the user limits
// defined in the G4UserLimits object attached to a logical volume.
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#ifndef G4UserSpecialCuts_h
#define G4UserSpecialCuts_h 1
#include "G4ios.hh"
#include "globals.hh"
#include "G4VProcess.hh"
class G4LossTableManager;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
class G4UserSpecialCuts : public G4VProcess
{
public: // with description
G4UserSpecialCuts(const G4String& processName ="UserSpecialCut" );
virtual ~G4UserSpecialCuts();
virtual G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition
);
virtual G4VParticleChange* PostStepDoIt(
const G4Track& ,
const G4Step&
);
public: // without description
// no operation in AtRestGPIL
virtual G4double AtRestGetPhysicalInteractionLength(
const G4Track& ,
G4ForceCondition*
){ return -1.0; };
// no operation in AtRestDoIt
virtual G4VParticleChange* AtRestDoIt(
const G4Track& ,
const G4Step&
){return 0;};
// no operation in AlongStepGPIL
virtual G4double AlongStepGetPhysicalInteractionLength(
const G4Track&,
G4double ,
G4double ,
G4double& ,
G4GPILSelection*
){ return -1.0; };
// no operation in AlongStepDoIt
virtual G4VParticleChange* AlongStepDoIt(
const G4Track& ,
const G4Step&
) {return 0;};
private:
// hide assignment operator as private
G4UserSpecialCuts(G4UserSpecialCuts&);
G4UserSpecialCuts& operator=(const G4UserSpecialCuts& right);
G4LossTableManager* theLossTableManager;
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#endif
@@ -4,14 +4,12 @@
geant4_add_module(G4transportation
PUBLIC_HEADERS
G4CoupledTransportation.hh
G4CoupledTransportation.icc
G4NeutronKiller.hh
G4NeutronKillerMessenger.hh
G4StepLimiter.hh
G4TrackTerminator.hh
G4Transportation.hh
G4Transportation.icc
G4UserSpecialCuts.hh
G4VTrackTerminator.hh
G4TransportationLogger.hh
G4TransportationProcessType.hh
@@ -22,18 +20,16 @@ geant4_add_module(G4transportation
G4StepLimiter.cc
G4Transportation.cc
G4TransportationLogger.cc
G4UserSpecialCuts.cc
G4VTrackTerminator.cc)
geant4_module_link_libraries(G4transportation
PUBLIC
G4globman
G4intercoms
G4magneticfield
G4navigation
G4partman
G4procman
G4track
PRIVATE
G4cuts
G4emutils)
G4magneticfield
G4navigation)
@@ -44,114 +44,45 @@
#include "G4Field.hh"
#include "G4FieldTrack.hh"
#include "G4FieldManagerStore.hh"
#include "G4PathFinder.hh"
#include "G4Transportation.hh" // In order to use fUseMagneticMoment
#include "G4PropagatorInField.hh"
#include "G4TransportationManager.hh"
class G4VSensitiveDetector;
G4bool G4CoupledTransportation::fSignifyStepInAnyVolume= false;
// This mode must apply to all threads
G4bool G4CoupledTransportation::fUseMagneticMoment=false;
G4bool G4CoupledTransportation::fUseGravity= false;
G4bool G4CoupledTransportation::fSilenceLooperWarnings= false;
//////////////////////////////////////////////////////////////////////////
//
// Constructor
G4CoupledTransportation::G4CoupledTransportation( G4int verbosity )
: G4VProcess( G4String("CoupledTransportation"), fTransportation ),
fTransportEndPosition(0.0, 0.0, 0.0),
fTransportEndMomentumDir(0.0, 0.0, 0.0),
fTransportEndKineticEnergy(0.0),
fTransportEndSpin(0.0, 0.0, 0.0),
fMomentumChanged(false),
fEndGlobalTimeComputed(false),
fCandidateEndGlobalTime(0.0),
fParticleIsLooping( false ),
fNewTrack( true ),
fPreviousSftOrigin( 0.,0.,0. ),
: G4Transportation( verbosity, "CoupledTransportation" ),
fPreviousMassSafety( 0.0 ),
fPreviousFullSafety( 0.0 ),
fMassGeometryLimitedStep( false ),
fAnyGeometryLimitedStep( false ),
fEndpointDistance( -1.0 ),
fSumEnergyKilled( 0.0 ), fMaxEnergyKilled( 0.0 ),
fFirstStepInMassVolume( true ),
fFirstStepInAnyVolume( true )
fFirstStepInMassVolume( true )
{
SetProcessSubType(static_cast<G4int>(COUPLED_TRANSPORTATION));
SetVerboseLevel(verbosity);
// SetVerboseLevel is called in the constructor of G4Transportation
G4TransportationManager* transportMgr ;
transportMgr = G4TransportationManager::GetTransportationManager() ;
fMassNavigator = transportMgr->GetNavigatorForTracking() ;
fFieldPropagator = transportMgr->GetPropagatorInField() ;
// fGlobalFieldMgr = transportMgr->GetFieldManager() ;
fNavigatorId= transportMgr->ActivateNavigator( fMassNavigator );
if( verboseLevel > 0 )
{
G4cout << " G4CoupledTransportation constructor: ----- " << G4endl;
G4cout << " Verbose level is " << verboseLevel << G4endl;
G4cout << " Navigator Id obtained in G4CoupledTransportation constructor "
<< fNavigatorId << G4endl;
G4cout << " Reports First/Last in "
<< (fSignifyStepInAnyVolume ? " any " : " mass " )
<< " geometry " << G4endl;
}
fPathFinder= G4PathFinder::GetInstance();
fpSafetyHelper = transportMgr->GetSafetyHelper(); // New
fpLogger = new G4TransportationLogger("G4Transportation", verbosity);
SetHighLooperThresholds();
// Use the old defaults: Warning = 100 MeV, Important = 250 MeV, No Trials = 10;
PushThresholdsToLogger();
// Should be done by Set methods in SetHighLooperThresholds -- making sure
static G4ThreadLocal G4TouchableHandle* pNullTouchableHandle = 0;
if ( !pNullTouchableHandle) { pNullTouchableHandle = new G4TouchableHandle; }
fCurrentTouchableHandle = *pNullTouchableHandle;
// Points to (G4VTouchable*) 0
fAnyFieldExists= DoesAnyFieldExist();
}
//////////////////////////////////////////////////////////////////////////
G4CoupledTransportation::~G4CoupledTransportation()
{
if( fSumEnergyKilled > 0.0 )
{
PrintStatistics( G4cout );
}
delete fpLogger;
}
//////////////////////////////////////////////////////////////////////////
void
G4CoupledTransportation::PrintStatistics( std::ostream& outStr) const
{
if( fSumEnergyKilled > 0.0 )
{
outStr << " G4CoupledTransportation: Statistics for looping particles "
<< G4endl;
outStr << " Sum of energy of loopers killed: "
<< fSumEnergyKilled / MeV << " MeV " << G4endl;
outStr << " Max energy of loopers killed: "
<< fMaxEnergyKilled / MeV << " MeV " << G4endl;
outStr << " Max energy of loopers 'saved': " << fMaxEnergySaved << G4endl;
outStr << " Sum of energy of loopers 'saved': "
<< fSumEnergySaved << G4endl;
outStr << " Sum of energy of unstable loopers 'saved': "
<< fSumEnergyUnstableSaved << G4endl;
}
}
//////////////////////////////////////////////////////////////////////////
@@ -169,7 +100,6 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
G4GPILSelection* selection )
{
G4double geometryStepLength;
G4double startMassSafety= 0.0; // estimated safety for start point (mass geometry)
G4double startFullSafety= 0.0; // estimated safety for start point (all geometries)
G4double safetyProposal= -1.0; // local copy of proposal
@@ -190,12 +120,12 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
*selection = CandidateForSelection ;
fFirstStepInMassVolume = fNewTrack || fMassGeometryLimitedStep ;
fFirstStepInAnyVolume = fNewTrack || fAnyGeometryLimitedStep ;
fFirstStepInVolume = fNewTrack || fGeometryLimitedStep ;
#ifdef G4DEBUG_TRANSPORT
G4cout << " CoupledTransport::AlongStep GPIL: "
<< " 1st-step: any= " <<fFirstStepInAnyVolume << " ( geom= "
<< fAnyGeometryLimitedStep << " ) "
<< " 1st-step: any= " <<fFirstStepInVolume << " ( geom= "
<< fGeometryLimitedStep << " ) "
<< " mass= " << fFirstStepInMassVolume << " ( geom= "
<< fMassGeometryLimitedStep << " ) "
<< " newTrack= " << fNewTrack << G4endl;
@@ -227,7 +157,6 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
//
G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin ;
G4double MagSqShift = OriginShift.mag2() ;
startMassSafety = 0.0;
startFullSafety= 0.0;
// Recall that FullSafety <= MassSafety
@@ -235,7 +164,6 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
if( MagSqShift < sqr(fPreviousFullSafety) )
{
G4double mag_shift= std::sqrt(MagSqShift);
startMassSafety = std::max( (fPreviousMassSafety - mag_shift), 0.0);
startFullSafety = std::max( (fPreviousFullSafety - mag_shift), 0.0);
// Need to be consistent between full safety with Mass safety
// in order reproduce results in simple case
@@ -252,7 +180,7 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
G4double restMass = pParticle->GetMass() ;
fMassGeometryLimitedStep = false ; // Set default - alex
fAnyGeometryLimitedStep = false;
fGeometryLimitedStep = false;
// There is no need to locate the current volume. It is Done elsewhere:
// On track construction
@@ -329,8 +257,8 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
ELimited limitedStep;
G4FieldTrack endTrackState('a'); // Default values
fMassGeometryLimitedStep = false ; // default
fAnyGeometryLimitedStep = false ;
fMassGeometryLimitedStep = false ; // default
fGeometryLimitedStep = false;
if( currentMinimumStep > 0 )
{
G4double newMassSafety= 0.0; // temp. for recalculation
@@ -339,7 +267,7 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
//
lengthAlongCurve = fPathFinder->ComputeStep( aFieldTrack,
currentMinimumStep,
fNavigatorId,
G4TransportationManager::kMassNavigatorId,
stepNo,
newMassSafety,
limitedStep,
@@ -354,15 +282,15 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
fMassGeometryLimitedStep = true ;
}
fAnyGeometryLimitedStep = (fPathFinder->GetNumberGeometriesLimitingStep() != 0);
fGeometryLimitedStep = (fPathFinder->GetNumberGeometriesLimitingStep() != 0);
#ifdef G4DEBUG_TRANSPORT
if( fMassGeometryLimitedStep && !fAnyGeometryLimitedStep )
if( fMassGeometryLimitedStep && !fGeometryLimitedStep )
{
std::ostringstream message;
message << " ERROR in determining geometries limiting the step" << G4endl;
message << " Limiting: mass=" << fMassGeometryLimitedStep
<< " any= " << fAnyGeometryLimitedStep << G4endl;
<< " any= " << fGeometryLimitedStep << G4endl;
message << "Incompatible conditions - by which geometries was it limited ?";
G4Exception("G4CoupledTransportation::AlongStepGetPhysicalInteractionLength()",
"PathFinderConfused", FatalException, message);
@@ -388,13 +316,11 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
G4cout << "G4Transport:CompStep> "
<< " called the pathfinder for a new step at " << startPosition
<< " and obtained step = " << lengthAlongCurve << G4endl;
G4cout << " New safety (preStep) = " << newMassSafety
<< " versus precalculated = " << startMassSafety << G4endl;
G4cout << " New safety (preStep) = " << newMassSafety << G4endl;
}
#endif
// Store as best estimate value
startMassSafety = newMassSafety ;
startFullSafety = newFullSafety ;
// Get the End-Position and End-Momentum (Dir-ection)
@@ -406,22 +332,13 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
geometryStepLength = lengthAlongCurve= 0.0 ;
fMomentumChanged = false ;
// fMassGeometryLimitedStep = false ; // --- ???
// fAnyGeometryLimitedStep = true;
// fGeometryLimitedStep = true;
fTransportEndMomentumDir = track.GetMomentumDirection();
fTransportEndKineticEnergy = track.GetKineticEnergy();
fTransportEndPosition = startPosition;
endTrackState= aFieldTrack; // Ensures that time is updated
// If the step length requested is 0, and we are on a boundary
// then a boundary will also limit the step.
if( startMassSafety == 0.0 )
{
fMassGeometryLimitedStep = true ;
fAnyGeometryLimitedStep = true;
}
// TODO: Add explicit logical status for being at a boundary
}
// G4FieldTrack aTrackState(endTrackState);
@@ -488,7 +405,7 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
}
}
fEndpointDistance = (fTransportEndPosition - startPosition).mag() ;
fEndPointDistance = (fTransportEndPosition - startPosition).mag() ;
fTransportEndSpin = endTrackState.GetSpin();
// Calculate the safety
@@ -498,14 +415,14 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
// Update safety for the end-point, if becomes negative at the end-point.
if( (startFullSafety < fEndpointDistance )
if( (startFullSafety < fEndPointDistance )
&& ( particleCharge != 0.0 ) ) // Only needed to prepare for MSC
// && !fAnyGeometryLimitedStep ) // To-Try: No safety update if at boundary
// && !fGeometryLimitedStep ) // To-Try: No safety update if at boundary
{
G4double endFullSafety =
fPathFinder->ComputeSafety( fTransportEndPosition);
// Expected mission -- only mass geometry's safety
// fMassNavigator->ComputeSafety( fTransportEndPosition) ;
// fLinearNavigator->ComputeSafety( fTransportEndPosition) ;
// Yet discrete processes only have poststep -- and this cannot
// currently revise the safety
// ==> so we use the all-geometry safety as a precaution
@@ -514,7 +431,7 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
// Pushing safety to Helper avoids recalculation at this point
G4ThreeVector centerPt= G4ThreeVector(0.0, 0.0, 0.0); // Used for return value
G4double endMassSafety= fPathFinder->ObtainSafety( fNavigatorId, centerPt);
G4double endMassSafety= fPathFinder->ObtainSafety( G4TransportationManager::kMassNavigatorId, centerPt);
// Retrieves the mass value from PathFinder (it calculated it)
fPreviousMassSafety = endMassSafety ;
@@ -523,7 +440,7 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
// The convention (Stepping Manager's) is safety from the start point
//
safetyProposal = endFullSafety + fEndpointDistance;
safetyProposal = endFullSafety + fEndPointDistance;
// --> was endMassSafety
// Changed to accomodate processes that cannot update the safety
@@ -533,7 +450,7 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
G4cout << " Revised Safety at endpoint " << fTransportEndPosition
<< " give safety values: Mass= " << endMassSafety
<< " All= " << endFullSafety << G4endl ;
G4cout << " Adding endpoint distance " << fEndpointDistance
G4cout << " Adding endpoint distance " << fEndPointDistance
<< " to obtain pseudo-safety= " << safetyProposal << G4endl ;
G4cout.precision(prec);
}
@@ -544,9 +461,9 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
G4cout << " Quick Safety estimate at endpoint "
<< fTransportEndPosition
<< " gives safety endpoint value = "
<< startFullSafety - fEndpointDistance
<< startFullSafety - fEndPointDistance
<< " using start-point value " << startFullSafety
<< " and endpointDistance " << fEndpointDistance << G4endl;
<< " and endpointDistance " << fEndPointDistance << G4endl;
G4cout.precision(prec);
#endif
}
@@ -557,189 +474,6 @@ AlongStepGetPhysicalInteractionLength( const G4Track& track,
return geometryStepLength ;
}
//////////////////////////////////////////////////////////////////////////
G4VParticleChange*
G4CoupledTransportation::AlongStepDoIt( const G4Track& track,
const G4Step& stepData )
{
static G4ThreadLocal G4long noCallsCT_ASDI=0;
const char *methodName= "AlongStepDoIt";
noCallsCT_ASDI++;
fParticleChange.Initialize(track) ;
// sets all its members to the value of corresponding members in G4Track
// Code specific for Transport
//
fParticleChange.ProposePosition(fTransportEndPosition) ;
fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir) ;
fParticleChange.ProposeEnergy(fTransportEndKineticEnergy) ;
fParticleChange.SetMomentumChanged(fMomentumChanged) ;
fParticleChange.ProposePolarization(fTransportEndSpin);
G4double deltaTime = 0.0 ;
// Calculate Lab Time of Flight (ONLY if field Equations used it!)
// G4double endTime = fCandidateEndGlobalTime;
// G4double delta_time = endTime - startTime;
G4double startTime = track.GetGlobalTime() ;
if (!fEndGlobalTimeComputed)
{
G4double finalInverseVel= DBL_MAX, initialInverseVel=DBL_MAX;
// The time was not integrated .. make the best estimate possible
//
G4double finalVelocity = track.GetVelocity() ;
if( finalVelocity > 0.0 ) { finalInverseVel= 1.0 / finalVelocity; }
G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity() ;
if( initialVelocity > 0.0 ) { initialInverseVel= 1.0 / initialVelocity; }
G4double stepLength = track.GetStepLength() ;
if (finalVelocity > 0.0)
{
// deltaTime = stepLength/finalVelocity ;
G4double meanInverseVelocity = 0.5
* (initialInverseVel + finalInverseVel);
deltaTime = stepLength * meanInverseVelocity ;
}
else
{
deltaTime = stepLength * initialInverseVel ;
} // Could do with better estimate for final step (finalVelocity = 0) ?
fCandidateEndGlobalTime = startTime + deltaTime ;
fParticleChange.ProposeLocalTime( track.GetLocalTime() + deltaTime) ;
}
else
{
deltaTime = fCandidateEndGlobalTime - startTime ;
fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ;
}
// Now Correct by Lorentz factor to get "proper" deltaTime
G4double restMass = track.GetDynamicParticle()->GetMass() ;
G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
// fParticleChange. ProposeTrueStepLength( track.GetStepLength() ) ;
// If the particle is caught looping or is stuck (in very difficult
// boundaries) in a magnetic field (doing many steps) THEN this kills it ...
//
if ( fParticleIsLooping )
{
G4double endEnergy= fTransportEndKineticEnergy;
const G4ParticleDefinition* particleType=
track.GetDynamicParticle() -> GetParticleDefinition();
G4bool stable = particleType->GetPDGStable();
G4bool candidateForEnd = (endEnergy < fThreshold_Important_Energy)
|| (fNoLooperTrials >= fThresholdTrials) ;
if( candidateForEnd && stable )
{
const G4int electronPDG= 11; // G4Electron::G4Electron()->GetPDGEncoding();
G4int particlePDG= particleType->GetPDGEncoding();
// Kill the looping particle
//
fParticleChange.ProposeTrackStatus( fStopAndKill ) ;
// Simple statistics
fSumEnergyKilled += endEnergy;
fSumEnerSqKilled = endEnergy * endEnergy;
fNumLoopersKilled++;
if( endEnergy > fMaxEnergyKilled ) {
fMaxEnergyKilled = endEnergy;
fMaxEnergyKilledPDG = particlePDG;
}
if( particleType->GetPDGEncoding() != electronPDG )
{
fSumEnergyKilled_NonElectron += endEnergy;
fSumEnerSqKilled_NonElectron += endEnergy * endEnergy;
fNumLoopersKilled_NonElectron++;
if( endEnergy > fMaxEnergyKilled_NonElectron )
{
fMaxEnergyKilled_NonElectron = endEnergy;
fMaxEnergyKilled_NonElecPDG = particlePDG;
}
}
if( endEnergy > fThreshold_Warning_Energy && ! fSilenceLooperWarnings )
{
fpLogger->ReportLoopingTrack( track, stepData, fNoLooperTrials,
noCallsCT_ASDI, methodName );
}
fNoLooperTrials=0;
}
else
{
fNoLooperTrials ++;
fMaxEnergySaved = std::max( endEnergy, fMaxEnergySaved);
if( fNoLooperTrials == 1 ) {
fSumEnergySaved += endEnergy;
if ( !stable )
fSumEnergyUnstableSaved += endEnergy;
}
#ifdef G4VERBOSE
if( verboseLevel > 2 && ! fSilenceLooperWarnings )
{
G4cout << " ** G4CoupledTransportation::AlongStepDoIt():"
<< " Particle is looping but is saved ..." << G4endl
<< " Number of trials (this track) = " << fNoLooperTrials
<< G4endl
<< " Steps by this track: " << track.GetCurrentStepNumber()
<< G4endl
<< " Total no of calls to this method (all tracks) = "
<< noCallsCT_ASDI << G4endl;
}
#endif
}
}
else
{
fNoLooperTrials=0;
}
// Another (sometimes better way) is to use a user-limit maximum Step size
// to alleviate this problem ..
// Introduce smooth curved trajectories to particle-change
//
fParticleChange.SetPointerToVectorOfAuxiliaryPoints
(fFieldPropagator->GimmeTrajectoryVectorAndForgetIt() );
return &fParticleChange ;
}
//////////////////////////////////////////////////////////////////////////
//
// This ensures that the PostStep action is always called,
// so that it can do the relocation if it is needed.
//
G4double G4CoupledTransportation::
PostStepGetPhysicalInteractionLength( const G4Track&,
G4double, // previousStepSize
G4ForceCondition* pForceCond )
{
// Must act as PostStep action -- to relocate particle
*pForceCond = Forced ;
return DBL_MAX ;
}
/////////////////////////////////////////////////////////////////////////////
void G4CoupledTransportation::
@@ -775,7 +509,7 @@ G4VParticleChange* G4CoupledTransportation::PostStepDoIt( const G4Track& track,
if( fSignifyStepInAnyVolume )
{
fParticleChange.ProposeFirstStepInVolume( fFirstStepInAnyVolume );
fParticleChange.ProposeFirstStepInVolume( fFirstStepInVolume );
}
else
{
@@ -801,13 +535,11 @@ G4VParticleChange* G4CoupledTransportation::PostStepDoIt( const G4Track& track,
{
G4cout << " Calling PathFinder::Locate() from "
<< " G4CoupledTransportation::PostStepDoIt " << G4endl;
G4cout << " fAnyGeometryLimitedStep is " << fAnyGeometryLimitedStep
<< G4endl;
G4cout << " fGeometryLimitedStep is " << fGeometryLimitedStep << G4endl;
}
#endif
if(fAnyGeometryLimitedStep)
if(fGeometryLimitedStep)
{
fPathFinder->Locate( track.GetPosition(),
track.GetMomentumDirection(),
@@ -818,14 +550,9 @@ G4VParticleChange* G4CoupledTransportation::PostStepDoIt( const G4Track& track,
// (Needed because the preStepPoint can point to the previous touchable)
fCurrentTouchableHandle=
fPathFinder->CreateTouchableHandle( fNavigatorId );
fPathFinder->CreateTouchableHandle( G4TransportationManager::kMassNavigatorId );
#ifdef G4DEBUG_TRANSPORT
if( verboseLevel > 0 )
{
G4cout << "G4CoupledTransportation::PostStepDoIt --- fNavigatorId = "
<< fNavigatorId << G4endl;
}
if( verboseLevel > 1 )
{
G4VPhysicalVolume* vol= fCurrentTouchableHandle->GetVolume();
@@ -846,14 +573,14 @@ G4VParticleChange* G4CoupledTransportation::PostStepDoIt( const G4Track& track,
retCurrentTouchable = fCurrentTouchableHandle ;
// fParticleChange.SetTouchableHandle( fCurrentTouchableHandle ) ;
}
else // fAnyGeometryLimitedStep is false
else // fGeometryLimitedStep is false
{
#ifdef G4DEBUG_TRANSPORT
if( verboseLevel > 1 )
{
G4cout << "G4CoupledTransportation::PostStepDoIt -- "
<< " fAnyGeometryLimitedStep = " << fAnyGeometryLimitedStep
<< " must be false " << G4endl;
G4cout << "G4CoupledTransportation::PostStepDoIt -- "
<< " fGeometryLimitedStep = " << fGeometryLimitedStep
<< " must be false " << G4endl;
}
#endif
// This serves only to move each of the Navigator's location
@@ -870,58 +597,20 @@ G4VParticleChange* G4CoupledTransportation::PostStepDoIt( const G4Track& track,
//
retCurrentTouchable = track.GetTouchableHandle() ;
// fParticleChange.SetTouchableHandle( track.GetTouchableHandle() ) ;
} // endif ( fAnyGeometryLimitedStep )
} // endif ( fGeometryLimitedStep )
#ifdef G4DEBUG_NAVIGATION
G4cout << " CoupledTransport::AlongStep GPIL: "
<< " last-step: any= " << fAnyGeometryLimitedStep
<< " . ..... x . "
<< " mass= " << fMassGeometryLimitedStep
<< G4endl;
<< " last-step: any= " << fGeometryLimitedStep << " . ..... x . "
<< " mass= " << fMassGeometryLimitedStep << G4endl;
#endif
if( fSignifyStepInAnyVolume )
fParticleChange.ProposeLastStepInVolume(fAnyGeometryLimitedStep);
fParticleChange.ProposeLastStepInVolume(fGeometryLimitedStep);
else
fParticleChange.ProposeLastStepInVolume(fMassGeometryLimitedStep);
const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
const G4Material* pNewMaterial = 0 ;
const G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
if( pNewVol != 0 )
{
pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
}
// ( const_cast<G4Material *> pNewMaterial ) ;
// ( const_cast<G4VSensitiveDetetor *> pNewSensitiveDetector) ;
fParticleChange.SetMaterialInTouchable( (G4Material *) pNewMaterial ) ;
fParticleChange.SetSensitiveDetectorInTouchable( (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
// "temporarily" until Get/Set Material of ParticleChange,
// and StepPoint can be made const.
const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
if( pNewVol != 0 )
{
pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
if( pNewMaterialCutsCouple!=0
&& pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
{
// for parametrized volume
//
pNewMaterialCutsCouple = G4ProductionCutsTable::GetProductionCutsTable()
->GetMaterialCutsCouple(pNewMaterial,
pNewMaterialCutsCouple->GetProductionCuts());
}
}
fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
// Must always set the touchable in ParticleChange, whether relocated or not
//
fParticleChange.SetTouchableHandle(retCurrentTouchable) ;
SetTouchableInformation(retCurrentTouchable);
return &fParticleChange ;
}
@@ -935,70 +624,19 @@ G4VParticleChange* G4CoupledTransportation::PostStepDoIt( const G4Track& track,
void
G4CoupledTransportation::StartTracking(G4Track* aTrack)
{
G4TransportationManager* transportMgr =
G4TransportationManager::GetTransportationManager();
// G4VProcess::StartTracking(aTrack);
fNewTrack= true;
G4Transportation::StartTracking(aTrack);
// The 'initialising' actions
// once taken in AlongStepGPIL -- if ( track.GetCurrentStepNumber()==1 )
// fStartedNewTrack= true;
fMassNavigator = transportMgr->GetNavigatorForTracking() ;
fNavigatorId= transportMgr->ActivateNavigator( fMassNavigator );
G4ThreeVector position = aTrack->GetPosition();
G4ThreeVector direction = aTrack->GetMomentumDirection();
fPathFinder->PrepareNewTrack( position, direction);
// This implies a call to fPathFinder->Locate( position, direction );
// Whether field exists should be determined at run level -- TODO
fAnyFieldExists= DoesAnyFieldExist();
// reset safety value and center
//
fPreviousMassSafety = 0.0 ;
fPreviousFullSafety = 0.0 ;
fPreviousSftOrigin = G4ThreeVector(0.,0.,0.) ;
// reset looping counter -- for motion in field
fNoLooperTrials= 0;
// Must clear this state .. else it depends on last track's value
// --> a better solution would set this from state of suspended track TODO ?
// Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
// ChordFinder reset internal state
//
if( fFieldPropagator && fAnyFieldExists )
{
fFieldPropagator->ClearPropagatorState();
// Resets safety values, in case of overlaps.
G4ChordFinder* chordF= fFieldPropagator->GetChordFinder();
if( chordF ) { chordF->ResetStepEstimate(); }
}
// Clear the chord finders of all fields (ie managers) derived objects
//
G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance();
fieldMgrStore->ClearAllChordFindersState();
#ifdef G4DEBUG_TRANSPORT
if( verboseLevel > 1 )
{
G4cout << " Returning touchable handle " << fCurrentTouchableHandle
<< G4endl;
}
#endif
// Update the current touchable handle (from the track's)
//
fCurrentTouchableHandle = aTrack->GetTouchableHandle();
}
/////////////////////////////////////////////////////////////////////////////
@@ -1060,90 +698,3 @@ ReportInexactEnergy(G4double startEnergy, G4double endEnergy)
}
}
}
/////////////////////////////////////////////////////////////////////////////
G4bool G4CoupledTransportation::EnableMagneticMoment(G4bool useMoment)
{
G4bool lastValue= fUseMagneticMoment;
fUseMagneticMoment= useMoment;
G4Transportation::fUseMagneticMoment= useMoment;
return lastValue;
}
/////////////////////////////////////////////////////////////////////////////
//
G4bool G4CoupledTransportation::EnableGravity(G4bool useGravity)
{
G4bool lastValue= fUseGravity;
fUseGravity= useGravity;
G4Transportation::fUseGravity= useGravity;
return lastValue;
}
/////////////////////////////////////////////////////////////////////////////
//
// Supress (or not) warnings about 'looping' particles
void G4CoupledTransportation::SetSilenceLooperWarnings( G4bool val)
{
fSilenceLooperWarnings= val; // Flag to *Supress* all 'looper' warnings
// G4CoupledTransportation::fSilenceLooperWarnings= val;
}
/////////////////////////////////////////////////////////////////////////////
//
G4bool G4CoupledTransportation::GetSilenceLooperWarnings()
{
return fSilenceLooperWarnings;
}
/////////////////////////////////////////////////////////////////////////////
//
void G4CoupledTransportation::SetHighLooperThresholds()
{
// Setting old 'high' values for thresholds - old values, potentially appropriate
// for the energy frontier HEP experiments
SetThresholdWarningEnergy( 100.0 * CLHEP::MeV ); // Warn above this energy
SetThresholdImportantEnergy( 250.0 * CLHEP::MeV ); // Give a few trial above this E);
G4int maxTrials = 10;
SetThresholdTrials( maxTrials );
if( verboseLevel ) ReportLooperThresholds();
}
/////////////////////////////////////////////////////////////////////////////
void G4CoupledTransportation::SetLowLooperThresholds() // Values for low-E applications
{
// These values were the default in Geant4 10.5 - beta
SetThresholdWarningEnergy( 1.0 * CLHEP::keV ); // Warn above this En
SetThresholdImportantEnergy( 1.0 * CLHEP::MeV ); // Extra trials above it
G4int maxTrials = 30; // A new value - was 10
SetThresholdTrials( maxTrials );
if( verboseLevel ) ReportLooperThresholds();
}
/////////////////////////////////////////////////////////////////////////////
//
void
G4CoupledTransportation::ReportMissingLogger( const char* methodName )
{
const char* message= "Logger object missing from G4CoupledTransportation";
G4String classAndMethod= G4String("G4CoupledTransportation") + G4String( methodName );
G4Exception(classAndMethod, "Missing Logger", JustWarning, message);
if( verboseLevel ) ReportLooperThresholds();
}
/////////////////////////////////////////////////////////////////////////////
//
void
G4CoupledTransportation::ReportLooperThresholds()
{
PushThresholdsToLogger(); // To be absolutely certain they are in sync
fpLogger->ReportLooperThresholds("G4CoupledTransportation");
}
@@ -54,7 +54,10 @@
#include "G4EquationOfMotion.hh"
#include "G4FieldManagerStore.hh"
#include "G4CoupledTransportation.hh"
#include "G4Navigator.hh"
#include "G4PropagatorInField.hh"
#include "G4TransportationManager.hh"
class G4VSensitiveDetector;
@@ -66,8 +69,8 @@ G4bool G4Transportation::fSilenceLooperWarnings= false;
//
// Constructor
G4Transportation::G4Transportation( G4int verbosity )
: G4VProcess( G4String("Transportation"), fTransportation ),
G4Transportation::G4Transportation( G4int verbosity, const G4String& aName )
: G4VProcess( aName, fTransportation ),
fFieldExertedForce( false ),
fPreviousSftOrigin( 0.,0.,0. ),
fPreviousSafety( 0.0 ),
@@ -96,13 +99,6 @@ G4Transportation::G4Transportation( G4int verbosity )
PushThresholdsToLogger();
// Should be done by Set methods in SetHighLooperThresholds -- making sure
// Cannot determine whether a field exists here, as it would
// depend on the relative order of creating the detector's
// field and this process. That order is not guaranted.
fAnyFieldExists= DoesAnyFieldExist();
// This value must be updated using DoesAnyFieldExist() at least at the
// start of each Run -- for now this is at the Start of every Track. TODO
static G4ThreadLocal G4TouchableHandle* pNullTouchableHandle = 0;
if ( !pNullTouchableHandle)
{
@@ -259,8 +255,7 @@ G4double G4Transportation::AlongStepGetPhysicalInteractionLength(
if(currentMinimumStep == 0.0)
{
fEndPointDistance = 0.0;
// flag step as geometry limited if current safety is also zero
fGeometryLimitedStep = (currentSafety == 0.0);
fGeometryLimitedStep = false;
fMomentumChanged = false;
fParticleIsLooping = false;
@@ -499,6 +494,11 @@ G4VParticleChange* G4Transportation::AlongStepDoIt( const G4Track& track,
#define noCallsASDI 0
#endif
if(fGeometryLimitedStep)
{
stepData.GetPostStepPoint()->SetStepStatus(fGeomBoundary);
}
fParticleChange.Initialize(track) ;
// Code for specific process
@@ -571,7 +571,7 @@ G4VParticleChange* G4Transportation::AlongStepDoIt( const G4Track& track,
// Simple statistics
fSumEnergyKilled += endEnergy;
fSumEnerSqKilled = endEnergy * endEnergy;
fSumEnerSqKilled += endEnergy * endEnergy;
fNumLoopersKilled++;
if( endEnergy > fMaxEnergyKilled ) {
@@ -649,6 +649,50 @@ PostStepGetPhysicalInteractionLength( const G4Track&,
return DBL_MAX ; // was kInfinity ; but convention now is DBL_MAX
}
/////////////////////////////////////////////////////////////////////////////
void G4Transportation::SetTouchableInformation(const G4TouchableHandle& touchable)
{
const G4VPhysicalVolume* pNewVol = touchable->GetVolume() ;
const G4Material* pNewMaterial = 0 ;
G4VSensitiveDetector* pNewSensitiveDetector = 0;
if( pNewVol != 0 )
{
pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
}
fParticleChange.SetMaterialInTouchable( (G4Material *) pNewMaterial ) ;
fParticleChange.SetSensitiveDetectorInTouchable( pNewSensitiveDetector ) ;
// temporarily until Get/Set Material of ParticleChange,
// and StepPoint can be made const.
const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
if( pNewVol != 0 )
{
pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
}
if ( pNewVol!=0 && pNewMaterialCutsCouple!=0
&& pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
{
// for parametrized volume
//
pNewMaterialCutsCouple =
G4ProductionCutsTable::GetProductionCutsTable()
->GetMaterialCutsCouple(pNewMaterial,
pNewMaterialCutsCouple->GetProductionCuts());
}
fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
// Set the touchable in ParticleChange
// this must always be done because the particle change always
// uses this value to overwrite the current touchable pointer.
//
fParticleChange.SetTouchableHandle(touchable) ;
}
/////////////////////////////////////////////////////////////////////////////
//
@@ -717,44 +761,7 @@ G4VParticleChange* G4Transportation::PostStepDoIt( const G4Track& track,
fParticleChange.ProposeFirstStepInVolume(fFirstStepInVolume);
fParticleChange.ProposeLastStepInVolume(isLastStep);
const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
const G4Material* pNewMaterial = 0 ;
const G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
if( pNewVol != 0 )
{
pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
}
fParticleChange.SetMaterialInTouchable( (G4Material *) pNewMaterial ) ;
fParticleChange.SetSensitiveDetectorInTouchable( (G4VSensitiveDetector *) pNewSensitiveDetector ) ;
const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
if( pNewVol != 0 )
{
pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
}
if ( pNewVol!=0 && pNewMaterialCutsCouple!=0
&& pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
{
// for parametrized volume
//
pNewMaterialCutsCouple =
G4ProductionCutsTable::GetProductionCutsTable()
->GetMaterialCutsCouple(pNewMaterial,
pNewMaterialCutsCouple->GetProductionCuts());
}
fParticleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
// temporarily until Get/Set Material of ParticleChange,
// and StepPoint can be made const.
// Set the touchable in ParticleChange
// this must always be done because the particle change always
// uses this value to overwrite the current touchable pointer.
//
fParticleChange.SetTouchableHandle(retCurrentTouchable) ;
SetTouchableInformation(retCurrentTouchable);
return &fParticleChange ;
}
@@ -777,7 +784,8 @@ G4Transportation::StartTracking(G4Track* aTrack)
// when track.GetCurrentStepNumber()==1
// Whether field exists should be determined at run level -- TODO
fAnyFieldExists= DoesAnyFieldExist();
G4FieldManagerStore* fieldMgrStore= G4FieldManagerStore::GetInstance();
fAnyFieldExists = fieldMgrStore->size() > 0;
// reset safety value and center
//
@@ -801,7 +809,6 @@ G4Transportation::StartTracking(G4Track* aTrack)
// Make sure to clear the chord finders of all fields (i.e. managers)
//
G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance();
fieldMgrStore->ClearAllChordFindersState();
// Update the current touchable handle (from the track's)
@@ -820,7 +827,6 @@ G4bool G4Transportation::EnableMagneticMoment(G4bool useMoment)
{
G4bool lastValue= fUseMagneticMoment;
fUseMagneticMoment= useMoment;
G4CoupledTransportation::fUseMagneticMoment= useMoment;
return lastValue;
}
@@ -831,7 +837,6 @@ G4bool G4Transportation::EnableGravity(G4bool useGravity)
{
G4bool lastValue= fUseGravity;
fUseGravity= useGravity;
G4CoupledTransportation::fUseGravity= useGravity;
return lastValue;
}
@@ -842,7 +847,6 @@ G4bool G4Transportation::EnableGravity(G4bool useGravity)
void G4Transportation::SetSilenceLooperWarnings( G4bool val)
{
fSilenceLooperWarnings= val; // Flag to *Supress* all 'looper' warnings
// G4CoupledTransportation::fSilenceLooperWarnings= val;
}
/////////////////////////////////////////////////////////////////////////////
@@ -1,164 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
// --------------------------------------------------------------
// History
//
// 15-04-98 first implementation, mma
// 07-04-03 migrade to cut per region (V.Ivanchenko)
// 18-09-03 substitute manager for the loss tables (V.Ivanchenko)
// 23-01-04 add protection for charged geantino in range cut (H.Kurashige)
// 09-09-04 tracking cut applied only if Rmin or Emin > DBL_MIN
// 21-01-11 changed order of checks: 1st energy tracking cut, 2nd track
// length, 3d time cut, 4th range for charged particles
// with non-zero mass; removed string comparisons (V.Ivanchenko)
// --------------------------------------------------------------
#include "G4UserSpecialCuts.hh"
#include "G4TransportationProcessType.hh"
#include "G4PhysicalConstants.hh"
#include "G4Step.hh"
#include "G4UserLimits.hh"
#include "G4VParticleChange.hh"
#include "G4LossTableManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UserSpecialCuts::G4UserSpecialCuts(const G4String& aName)
: G4VProcess(aName, fGeneral )
{
// set Process Sub Type
SetProcessSubType(static_cast<int>(USER_SPECIAL_CUTS));
if (verboseLevel>0)
{
G4cout << GetProcessName() << " is created "<< G4endl;
}
theLossTableManager = G4LossTableManager::Instance();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UserSpecialCuts::~G4UserSpecialCuts()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4UserSpecialCuts::G4UserSpecialCuts(G4UserSpecialCuts& right)
: G4VProcess(right)
{
theLossTableManager = G4LossTableManager::Instance();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4UserSpecialCuts::
PostStepGetPhysicalInteractionLength( const G4Track& aTrack,
G4double, // previousStepSize
G4ForceCondition* condition )
{
// condition is set to "Not Forced"
*condition = NotForced;
G4double ProposedStep = DBL_MAX;
G4UserLimits* pUserLimits =
aTrack.GetVolume()->GetLogicalVolume()->GetUserLimits();
if (pUserLimits)
{
// check max kinetic energy first
//
G4double Ekine = aTrack.GetKineticEnergy();
if(Ekine <= pUserLimits->GetUserMinEkine(aTrack)) { return 0.; }
// max track length
//
ProposedStep = (pUserLimits->GetUserMaxTrackLength(aTrack)
- aTrack.GetTrackLength());
if (ProposedStep < 0.) { return 0.; }
// max time limit
//
G4double tlimit = pUserLimits->GetUserMaxTime(aTrack);
if(tlimit < DBL_MAX) {
G4double beta = (aTrack.GetDynamicParticle()->GetTotalMomentum())
/(aTrack.GetTotalEnergy());
G4double dTime = (tlimit - aTrack.GetGlobalTime());
G4double temp = beta*c_light*dTime;
if (temp < 0.) { return 0.; }
if (ProposedStep > temp) { ProposedStep = temp; }
}
// min remaining range
// (only for charged particle except for chargedGeantino)
//
G4double Rmin = pUserLimits->GetUserMinRange(aTrack);
if (Rmin > DBL_MIN) {
G4ParticleDefinition* Particle = aTrack.GetDefinition();
if ( (Particle->GetPDGCharge() != 0.) && (Particle->GetPDGMass() > 0.0))
{
const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
G4double RangeNow = theLossTableManager->GetRange(Particle,Ekine,couple);
G4double temp = RangeNow - Rmin;
if (temp < 0.) { return 0.; }
if (ProposedStep > temp) { ProposedStep = temp; }
}
}
}
return ProposedStep;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VParticleChange*
G4UserSpecialCuts::PostStepDoIt( const G4Track& aTrack,
const G4Step& )
//
// Kill the current particle, if requested by G4UserLimits
//
{
aParticleChange.Initialize(aTrack);
aParticleChange.ProposeEnergy(0.) ;
aParticleChange.ProposeLocalEnergyDeposit(aTrack.GetKineticEnergy()) ;
aParticleChange.ProposeTrackStatus(fStopAndKill);
return &aParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......