Import Geant4 0.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-01 15:25:35 +02:00
parent 54d6b71f95
commit b97f8d0df7
3237 changed files with 807095 additions and 0 deletions
@@ -0,0 +1,26 @@
# $Id: GNUmakefile,v 2.0 1998/07/02 16:41:48 gunter Exp $
# ------------------------------------------------------------
# GNUmakefile for transportation library. G.Folger 10-Dec-97.
# ------------------------------------------------------------
name := G4transportation
ifndef G4INSTALL
G4INSTALL = ../../..
endif
include $(G4INSTALL)/config/architecture.gmk
CPPFLAGS += -I$(G4BASE)/global/management/include \
-I$(G4BASE)/global/HEPRandom/include \
-I$(G4BASE)/global/HEPGeometry/include \
-I$(G4BASE)/geometry/management/include \
-I$(G4BASE)/geometry/volumes/include \
-I$(G4BASE)/geometry/magneticfield/include \
-I$(G4BASE)/track/include \
-I$(G4BASE)/processes/management/include \
-I$(G4BASE)/processes/electromagnetic/utils/include \
-I$(G4BASE)/particles/management/include \
-I$(G4BASE)/materials/include
include $(G4INSTALL)/config/common.gmk
+119
View File
@@ -0,0 +1,119 @@
$Id: History,v 2.4 1998/12/04 19:18:08 japost Exp $
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
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 *
----------------------------------------------------------
Dec 4, 1998 J. Apostolakis transport-00-04-01
The Velocity Vector for Transport in a magnetic field is now set correctly.
--> previously the scalar velocity was automatically promoted to a 3-vector
Nov 25, 1998 J. Apostolakis
Added the direction to LocateGlobalPointAndUpdateTouchable.
Nov 19, 1998 J. Apostolakis transport-00-03-04
Fixes:
1) The final energy is set equal to the initial energy, because
the PropagatorInField does not calculate it correctly yet. NEEDS Fix
2) If the requested step size is zero and safety is zero, the
step is now considered geometry limited. (This can happen
if a discrete process tries to take a step that is very small
compared to the mean free path.) Problem observed by Laszlo in EM tests.
3) PostStepGetInteractionLength now returns DBL_MAX, not kInfinity.
Nov 11, 1998 J. Apostolakis transport-00-03-03
Changes to accomodate new interface of Field:
(G4PropagatorInField and G4FieldTrack. )
Oct 30, 1998 J. Apostolakis transport-00-03-02
In the case of magnetic field, a flag that determines whether the
geometry limited the step was not set.
---------------------------- next two entries recorded Nov 25th :
Sep 16, 1998 J. Apostolakis transport-00-03-01
Checks whether the particle is out of the world volume
If so it has exited and must be killed.
Aug 28, 1998 J. Apostolakis
The PostStepGetPhysicalInteractionLength has fixed (to return kInf)
The boolean flags for touchables are now initialised. & Other small fixes ?
Test code for non-relocating case added (for debugging).
==================================================================================
June 08, 1998 J. Apostolakis (trans-06-04)
Corrected Safety computation for the case of the field (adding endpoint
distance instead of curve length.)
Added PostStepDoIt method that tries to relocate the particle using
G4ParticleChangeForTransport
Transportation is no longer a G4ContinuousProcess.
June 08, 1998 J. Apostolakis (trans-06-03)
Modified it to recomputate Safety at the start of a step. To do this
it uses the previous step's calculated safety and endpoint.
June 08, 1998 J. Apostolakis (trans-06-02)
Modified it to add re-computation of Safety at the endpoint of a step,
when the safety would become negative. This is done to allow processes
to benefit from a realistic (geometrical) value of the safety. The
request to do this was from EM physics
June 03, 1998 J. Apostolakis (trans-06-01)
The safety we is now generalised to mean the limit of assumption of all
processes. The AlongStepGPIL input value is not the remainder from the
previous step's geometrical safety.
So the transportation must recalculate the starting point's safety here.
As a zeroeth order approximation we set it to zero.
April 17, 1998 M. Maire (recorded by John Apostolakis )
A new process, G4UserSpecialCuts, was added to allow the
user an alternative method to set some user cuts.
April 15, 1998 H. Kurasige (recorded by John Apostolakis )
The transportation does the absolute minimum required to conform to
the new scheme for ParticleChange: G4VParticleChange is used in signature.
[ But default G4ParticleChange is still used ].
April 14, 1998 John Apostolakis (recorded April 20th).
History file Created
@@ -0,0 +1,166 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Transportation.hh,v 2.4 1998/11/11 20:03:58 japost Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 include file implementation
//
// For information related to this code contact:
// CERN, IT Division (formely CN), ASD group
// ------------------------------------------------------------
//
// This class' object is a process responsible for the transportation of
// a particle, ie the geometrical propagation that encounters the
// geometrical sub-volumes of the detectors.
//
// It is also tasked with part of updating the "safety".
//
// =======================================================================
// Created: 19 March 1997, J. Apostolakis
// =======================================================================
#ifndef G4Transportation_hh
#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 G4Transportation : public G4VProcess
{
// Concrete class that does the geometrical transport
public:
G4Transportation();
~G4Transportation();
// G4double GetContinuousStepLimit (
G4double AlongStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& currentSafety,
G4GPILSelection* selection
);
G4VParticleChange* AlongStepDoIt(
const G4Track& track,
const G4Step& stepData
);
// This only does the relocation
//
G4VParticleChange* PostStepDoIt(
const G4Track& track,
const G4Step& stepData
);
// This forces the PostStepDoIt action to be called,
// but does not limit the step.
//
G4double PostStepGetPhysicalInteractionLength(
const G4Track& ,
G4double previousStepSize,
G4ForceCondition* pForceCond
);
// Access/set the assistant class that Propagate in a Field
G4PropagatorInField* GetPropagatorInField();
void SetPropagatorInField( G4PropagatorInField* pFieldPropagator);
// no operation in AtRestDoIt
G4double AtRestGetPhysicalInteractionLength(
const G4Track& ,
G4ForceCondition*
) { return -1.0; };
// no operation in AtRestDoIt
G4VParticleChange* AtRestDoIt(
const G4Track& ,
const G4Step&
) {return NULL;};
protected:
// Checks whether a field exists for the "global" field manager.
G4bool DoesGlobalFieldExist();
private:
// Needed to add the Relocation in the PostStepDoIt
// Copied from SteppingManager
G4VTouchable* GetFreeTouchable();
// Get Touchable which is free, i.e. not assigined to Track/StepPoint
// If no free touchable is availabe, the NULL will be returned
// Once you get a Touchable, it will be set to NotFree.
void SetTheOtherTouchableFree(G4VTouchable* pTouch);
// Set the partner of the given Touchable to be free. For example,
// the argument has fTouchable1, then fTouchable2 will be set to
private:
// The Propagators used to transport the particle
G4Navigator* fLinearNavigator;
G4PropagatorInField* fFieldPropagator;
// Field Manager for the whole Detector
// G4FieldManager* fGlobalFieldMgr; // Used MagneticField CC
// The particle's state after this Step, Store for DoIt
G4ThreeVector fTransportEndPosition;
G4ThreeVector fTransportEndMomentumDir;
G4double fTransportEndKineticEnergy;
G4ThreeVector fTransportEndSpin;
G4bool fMomentumChanged;
G4bool fEnergyChanged;
G4bool fParticleIsLooping;
G4VTouchable* fCurrentTouchable;
// Whether a magnetic field exists ...
// G4bool fFieldExists;
// The above data member is problematic: it is useful only if
// it is initialised. However the transportation process(es) are not
// capable of doing this initialisation itself (themselves) and there
// seems no alternative agent capable of doing it right now.
// Eg, at construction time it is likely that the field manager has
// not yet been informed about the detector's field
// I cannot foresee how the transportation can be informed later. JA
// The current answer is to ignore this data member and use
// the member function DoesGlobalFieldExist() in its place ...
// John Apostolakis, July 7, 1997
// Needed for the relocation - Copied from SteppingManager
G4VTouchable* fTouchable1;
G4VTouchable* fTouchable2;
G4bool fIsTouchable1Free;
G4bool fIsTouchable2Free;
// Flag to determine whether a boundary was reached.
G4bool fGeometryLimitedStep;
// Remember last safety origin & value.
G4ThreeVector fPreviousSftOrigin;
G4double fPreviousSafety;
// New ParticleChange
G4ParticleChangeForTransport fParticleChange;
G4double endpointDistance;
};
#include "G4Transportation.icc"
#endif
// End of G4Transportation.hh
@@ -0,0 +1,63 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Transportation.icc,v 2.1 1998/07/12 03:08:20 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//
// Inline function implementation.
//
// =======================================================================
// Created: 9 June 1998, J. Apostolakis
// =======================================================================
//
inline void G4Transportation::SetPropagatorInField( G4PropagatorInField* pFieldPropagator)
{
fFieldPropagator= pFieldPropagator;
}
inline G4PropagatorInField* G4Transportation::GetPropagatorInField()
{
return fFieldPropagator;
}
inline G4bool G4Transportation::DoesGlobalFieldExist()
{
G4TransportationManager* transportMgr;
transportMgr= G4TransportationManager::GetTransportationManager();
// fFieldExists= transportMgr->GetFieldManager()->DoesFieldExist();
// return fFieldExists;
return transportMgr->GetFieldManager()->DoesFieldExist();
}
inline void G4Transportation::SetTheOtherTouchableFree(G4VTouchable* value)
{
if(value == fTouchable1){
fIsTouchable2Free = true;
}
else if(value == fTouchable2){
fIsTouchable1Free = true;
}
}
inline G4VTouchable* G4Transportation::GetFreeTouchable(){
if(fIsTouchable1Free){
fIsTouchable1Free = false;
return fTouchable1;
}
else if(fIsTouchable2Free){
fIsTouchable2Free = false;
return fTouchable2;
}
else {
return NULL;
}
}
@@ -0,0 +1,84 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4UserSpecialCuts.hh,v 2.1 1998/07/13 17:28:12 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// ------------------------------------------------------------
// 15 April 1998 M.Maire
// ------------------------------------------------------------
#ifndef G4UserSpecialCuts_h
#define G4UserSpecialCuts_h 1
#include "G4ios.hh"
#include "globals.hh"
#include "G4VProcess.hh"
class G4UserSpecialCuts : public G4VProcess
{
public:
G4UserSpecialCuts(const G4String& processName ="UserSpecialCut" );
~G4UserSpecialCuts();
virtual G4double PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition
);
virtual G4VParticleChange* PostStepDoIt(
const G4Track& ,
const G4Step&
);
// 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 NULL;};
// 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 NULL;};
private:
// hide assignment operator as private
G4UserSpecialCuts(G4UserSpecialCuts&);
G4UserSpecialCuts& operator=(const G4UserSpecialCuts& right);
};
#endif
@@ -0,0 +1,471 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Transportation.cc,v 2.18 1998/12/14 18:27:32 japost Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 include file implementation
//
// For information related to this code contact:
// CERN, IT Division (formely CN), ASD group
// ------------------------------------------------------------
//
// This class is a process responsible for the transportation of
// a particle, ie the geometrical propagation that encounters the
// geometrical sub-volumes of the detectors.
//
// It is also tasked with part of updating the "safety".
//
// =======================================================================
// Created: 19 March 1997, J. Apostolakis
// =======================================================================
#include "G4Transportation.hh"
G4Transportation::G4Transportation() :
G4VProcess(G4String("Transportation") )
{
G4TransportationManager* transportMgr;
transportMgr= G4TransportationManager::GetTransportationManager();
fLinearNavigator= transportMgr->GetNavigatorForTracking();
fFieldPropagator= 0;
// fFieldExists= false;
fParticleIsLooping = false;
// fGlobalFieldMgr= transportMgr->GetFieldManager();
fFieldPropagator= transportMgr->GetPropagatorInField();
// Find out if an electromagnetic field exists
//
// fFieldExists= transportMgr->GetFieldManager()->DoesFieldExist();
//
// The above code is problematic, because it only works if
// the field manager has informed about the detector's field
// before this transportation process is constructed.
// I cannot foresee how the transportation can be informed later. JA
// The current answer is to ignore this data member and use
// the member function DoesGlobalFieldExist() in its place ...
// John Apostolakis, July 7, 1997
fTouchable1 = new G4TouchableHistory();
fTouchable2 = new G4TouchableHistory();
fIsTouchable1Free= true;
fIsTouchable2Free= true;
// Initial value for safety and point-of-origin of safety
fPreviousSafety=0.0;
fPreviousSftOrigin= G4ThreeVector(0.,0.,0.);
}
G4Transportation::~G4Transportation()
{
delete fTouchable1;
delete fTouchable2;
}
// ------------------------------------------------------------------
// G4double G4Transportation::GetContinuousStepLimit (
G4double G4Transportation::AlongStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& currentSafety,
G4GPILSelection* selection
)
// ------------------------------------------------------------------
{
// Responsibilities:
// Find whether the geometry limits the Step, and to what length
// Calculate the new value of the safety and return it.
// Store the final time, position and momentum.
G4double geometryStepLength, newSafety;
fParticleIsLooping = false;
// GPILSelection is set to defaule value of CandidateForSelection
// It is a return value
*selection = CandidateForSelection;
// Get initial Energy/Momentum of the track
//
const G4DynamicParticle* pParticle = track.GetDynamicParticle();
G4double startEnergy = pParticle->GetKineticEnergy();
G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection();
G4ThreeVector startPosition = track.GetPosition();
// G4double theTime = track.GetGlobalTime();
// The Step Point safety is now generalised to mean the limit of assumption
// of all processes, so it is not the previous Step's geometrical safety.
//
// We calculate the starting point's safety here.
G4ThreeVector OriginShift= startPosition - fPreviousSftOrigin;
G4double MagSqShift= OriginShift.mag2();
if( MagSqShift >= sqr(fPreviousSafety) ){
currentSafety = 0.0;
}else{
currentSafety = fPreviousSafety - sqrt(MagSqShift);
}
// Is the particle charged ?
G4ParticleDefinition* pParticleDef= pParticle->GetDefinition();
G4double particleCharge= pParticleDef->GetPDGCharge();
G4bool fieldExertsForce= false;
fGeometryLimitedStep= false;
// There is no need to locate the current volume. It is Done elsewhere:
// On track construction
// By the tracking, after all AlongStepDoIts, in "Relocation"
//
// Does the particle have an (EM) field force exerting upon it?
//
if( (particleCharge!=0.0) ){
fieldExertsForce= this->DoesGlobalFieldExist();
// Future: will/can also check whether current volume's field is Zero or
// set by the user (in the logical volume) to be zero.
}
// Choose the calculation of the transportation: Field or not
//
if( !fieldExertsForce )
{
G4double linearStepLength;
if( currentMinimumStep <= currentSafety )
{
// The Step is guaranteed to be taken
geometryStepLength=currentMinimumStep;
fGeometryLimitedStep= false;
}
else
{
// Find whether the straight path intersects a volume
linearStepLength= fLinearNavigator->ComputeStep(
startPosition, startMomentumDir,
currentMinimumStep, newSafety);
// Remember last safety origin & value.
fPreviousSftOrigin = startPosition;
fPreviousSafety= newSafety;
// The safety at the initial point has been re-calculated:
currentSafety= newSafety;
if( linearStepLength <= currentMinimumStep){
// The geometry limits the Step size (an intersection was found.)
geometryStepLength=linearStepLength;
fGeometryLimitedStep= true;
}else{
// The full Step is taken.
geometryStepLength=currentMinimumStep;
fGeometryLimitedStep= false;
}
}
endpointDistance= geometryStepLength;
// Calculate final position
fTransportEndPosition= startPosition+geometryStepLength*startMomentumDir;
// Momentum (& its direction) is unchanged
fTransportEndMomentumDir= startMomentumDir;
fTransportEndKineticEnergy= track.GetKineticEnergy();
fParticleIsLooping = false;
fMomentumChanged = false;
}
else
{
G4double momentumMagnitude=pParticle->GetTotalMomentum();
G4ThreeVector EndUnitMomentum;
G4double lengthAlongCurve;
G4double restMass= pParticleDef->GetPDGMass();
fFieldPropagator->SetChargeMomentumMass(
particleCharge, // charge in e+ units
momentumMagnitude, // Momentum in Mev/c
restMass );
G4ThreeVector spin = track.GetPolarization(); // Does it have it ?
G4ThreeVector velocityVector = track.GetVelocity()
* track.GetMomentumDirection();
G4FieldTrack aFieldTrack =
G4FieldTrack( startPosition,
velocityVector,
0.0,
track.GetKineticEnergy(),
track.GetLocalTime(), // tof lab ?
track.GetProperTime(), // tof proper
&spin );
// Do the Transport in the field (non recti-linear)
lengthAlongCurve=fFieldPropagator->ComputeStep( aFieldTrack,
currentMinimumStep,
currentSafety,
track.GetVolume() );
// ----------------
if( lengthAlongCurve< currentMinimumStep){
geometryStepLength=lengthAlongCurve;
fGeometryLimitedStep= true;
}else{
geometryStepLength=currentMinimumStep;
fGeometryLimitedStep= false;
}
// Remember last safety origin & value.
fPreviousSftOrigin = startPosition;
fPreviousSafety= currentSafety;
// Get the End-Position and End-Momentum (Dir-ection)
fTransportEndPosition= aFieldTrack.GetPosition();
// Momentum: Magnitude and direction can be changed too now ...
fMomentumChanged = true;
fTransportEndMomentumDir= aFieldTrack.GetMomentumDir();
// fTransportEndKineticEnergy= aFieldTrack.GetEnergy(); // Energy is wrong
#if 0
G4ThreeVector endVelocity = aFieldTrack.GetVelocity();
G4double veloc_sq = endVelocity.mag2();
fTransportEndKineticEnergy = 0.5 * restMass * veloc_sq /
( 1 - veloc_sq / c_squared ); // Lorentz correction
#endif
fTransportEndKineticEnergy = track.GetKineticEnergy();
// fTransportEndPolarization= aFieldTrack.GetSpin(); // Not yet possible
fParticleIsLooping = fFieldPropagator->IsParticleLooping();
endpointDistance= (fTransportEndPosition-startPosition).mag();
}
// If we are asked to go a step length of 0, and we are on a boundary
// then a boundary will also limit the step -> we must flag this.
if (currentMinimumStep == 0.0 ) {
if( currentSafety == 0.0 ){
fGeometryLimitedStep= true;
}
}
// Update the safety starting from the end-point, if it will become
// negative at the end-point.
//
if( currentSafety < endpointDistance ) {
G4double endSafety;
endSafety = fLinearNavigator->ComputeSafety( fTransportEndPosition);
currentSafety= endSafety;
fPreviousSftOrigin = fTransportEndPosition;
fPreviousSafety= currentSafety;
// Because the Stepping Manager assumes it is from the start point,
// add the StepLength
currentSafety += endpointDistance;
#ifdef G4DEBUG_TRANSPORT
cout.precision(5);
cout << "***Transportation::AlongStepGPIL ** " << endl ;
cout << " Called Navigator->ComputeSafety " << endl
<< " with position = " << fTransportEndPosition << endl
<< " and it returned safety= " << endSafety << endl;
cout << " I add the endpoint distance " << endpointDistance
<< " to it "
<< " to obtain a pseudo-safety= " << currentSafety
<< " which I return." << endl;
#endif
}
return geometryStepLength;
}
G4VParticleChange* G4Transportation::AlongStepDoIt(
const G4Track& track,
const G4Step& stepData
)
{
// Initialize ParticleChange (by setting all its members equal
// to corresponding members in G4Track)
fParticleChange.Initialize(track);
//
// Code for specific process
fParticleChange.SetPositionChange(fTransportEndPosition);
fParticleChange.SetMomentumChange(fTransportEndMomentumDir);
fParticleChange.SetEnergyChange(fTransportEndKineticEnergy);
fParticleChange.SetMomentumChanged(fMomentumChanged);
G4double deltaTime=0.0;
#if HARMONIC_MEAN_VELOCITY
G4double meanInverseVelocity;
meanInverseVelocity= 0.5/stepData.GetPreStepPoint()->GetVelocity()+
0.5/stepData.GetPostStepPoint()->GetVelocity();
if ( meanInverseVelocity < kInfinity ) {
deltaTime= track.GetStepLength() * meanInverseVelocity;
}
#endif
G4double finalVelocity= track.GetVelocity();
if ( finalVelocity > 0.0 ) {
deltaTime= track.GetStepLength() / finalVelocity;
}
fParticleChange. SetTimeChange( track.GetGlobalTime() + deltaTime );
// Now Correct by Lorentz factor to get "proper" deltaTime
//
G4double restMass = track.GetDynamicParticle()->GetMass();
G4double deltaProperTime= deltaTime * (restMass / track.GetTotalEnergy());
fParticleChange. SetProperTimeChange(track.GetProperTime()
+ deltaProperTime );
// fParticleChange.SetEnergyChange( Energy );
//fParticleChange. SetTrueStepLength( track.GetStepLength() );
#ifdef DETECT_LOOPER
// If the particle is caught looping in a magnetic field (doing many steps)
// this kills it ...
// But currently a user-limit maximum Step size alleviates this problem,
// so this code is no longer used.
if ( fParticleIsLooping ){
// Kill the looping particle
fParticleChange.SetStatusChange( fStopAndKill ) ;
// ClearNumberOfInteractionLengthLeft();
}
#endif
return &fParticleChange;
}
// This ensures that the PostStep action is always called,
// so that it can do the relocation if it is needed.
//
G4double
G4Transportation::PostStepGetPhysicalInteractionLength(
const G4Track& ,
G4double previousStepSize,
G4ForceCondition* pForceCond
)
{
*pForceCond= Forced;
return DBL_MAX; // was kInfinity; but convention now is DBL_MAX
}
G4VParticleChange* G4Transportation::PostStepDoIt(
const G4Track& track,
const G4Step& stepData
)
{
G4VTouchable* retCurrentTouchable; // The one to return
// Initialize ParticleChange (by setting all its members equal
// to corresponding members in G4Track)
//
// fParticleChange.Initialize(track); // To initialise TouchableChange
fParticleChange.SetStatusChange(track.GetTrackStatus());
// fCurrentTouchable will now become the previous touchable,
// and what was the previous will be freed.
// (We need this because the preStepPoint can point to the previous
// touchable)
//
// SetTheOtherTouchableFree(fCurrentTouchable); // Do it only if needed.
// fCurrentTouchable= GetFreeTouchable(); // Do it only if needed.
// If the Step was determined by the volume boundary,
// logically relocate the particle
// if( stepData.GetPostStepPoint()->GetStepStatus() == fGeomBoundary ){
// If the use of fGeomBoundary is suppressed, we can probably change this to:
// if( stepData.GetPostStepPoint()->GetProcessDefinedStep() == this ){
//
if( fGeometryLimitedStep ){
SetTheOtherTouchableFree(fCurrentTouchable);
fCurrentTouchable= GetFreeTouchable();
fLinearNavigator->SetGeometricallyLimitedStep();
fLinearNavigator-> LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
fCurrentTouchable,
true);
// Check whether the particle is out of the world volume
// If so it has exited and must be killed.
if( fCurrentTouchable->GetVolume() == 0 ){
fParticleChange.SetStatusChange( fStopAndKill ) ;
}
retCurrentTouchable= fCurrentTouchable;
}
else{
#ifdef G4VERBOSE
// fCurrentTouchable will now become the previous touchable,
SetTheOtherTouchableFree(fCurrentTouchable);
fCurrentTouchable= GetFreeTouchable();
// Although the location is changed, we know that the physical
// volume remains constant.
// Currently a pseudo-relocation is/was required here:
fLinearNavigator-> LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
fCurrentTouchable,
true);
if( fCurrentTouchable->GetVolume() != track.GetVolume() ){
//
G4cerr << " ERROR: A relocation within safety has caused a volume change! " << endl ;
G4cerr << " The old volume is called "
<< track.GetVolume()->GetName() << endl;
G4cerr << " The new volume is called ";
if ( fCurrentTouchable->GetVolume() != 0 )
G4cerr << fCurrentTouchable->GetVolume()->GetName() << endl;
else
G4cerr << "Out of World" << endl;
G4cerr.precision(7);
G4cerr << " The position is " << track.GetPosition() << endl;
// Let us relocate again, for debuging
fLinearNavigator-> LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
fCurrentTouchable,
true);
G4cerr << " The newer volume is called " ;
if ( fCurrentTouchable->GetVolume() != 0 )
G4cerr << fCurrentTouchable->GetVolume()->GetName() << endl;
else
G4cerr << "Out of World" << endl;
}
assert( fCurrentTouchable->GetVolume()->GetName() ==
track.GetVolume()->GetName() );
retCurrentTouchable = fCurrentTouchable;
#else
// ie #ifndef G4VERBOSE does a quick relocation
// The serves only to move the Navigator's location
fLinearNavigator->LocateGlobalPointWithinVolume( track.GetPosition());
// The value of the track's current Touchable is retained.
// (and it must be correct because we must use it below to
// overwrite the (unset) one in particle change)
// Although in general this is fCurrentTouchable, at the start of
// a step it could be different ... ??
retCurrentTouchable = track.GetTouchable();
#endif
}
// 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.SetTouchableChange(retCurrentTouchable);
return &fParticleChange;
}
@@ -0,0 +1,98 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4UserSpecialCuts.cc,v 2.2 1998/08/14 10:24:52 maire Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD Group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// --------------------------------------------------------------
// 15 April 1998 M.Maire
// --------------------------------------------------------------
#include "G4UserSpecialCuts.hh"
#include "G4Step.hh"
#include "G4UserLimits.hh"
#include "G4VParticleChange.hh"
#include "G4EnergyLossTables.hh"
G4UserSpecialCuts::G4UserSpecialCuts(const G4String& aName)
: G4VProcess(aName)
{
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created "<< endl;
}
}
G4UserSpecialCuts::~G4UserSpecialCuts()
{}
G4UserSpecialCuts::G4UserSpecialCuts(G4UserSpecialCuts& right)
: G4VProcess(right)
{}
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)
{ //max track length
ProposedStep = (pUserLimits->GetUserMaxTrackLength(aTrack) - aTrack.GetTrackLength());
if (ProposedStep < 0.) return 0.;
//max time limit
G4double beta = (aTrack.GetDynamicParticle()->GetTotalMomentum())/(aTrack.GetTotalEnergy());
G4double dTime= (pUserLimits->GetUserMaxTime(aTrack) - aTrack.GetGlobalTime());
G4double temp = beta*c_light*dTime;
if (temp < 0.) return 0.;
if (ProposedStep > temp) ProposedStep = temp;
//min remaining range
G4ParticleDefinition* Particle = aTrack.GetDefinition();
G4double Ekine = aTrack.GetKineticEnergy();
G4Material* Material = aTrack.GetMaterial();
G4double RangeNow = G4EnergyLossTables::GetRange(Particle,Ekine,Material);
temp = (RangeNow - pUserLimits->GetUserMinRange(aTrack));
if (temp < 0.) return 0.;
if (ProposedStep > temp) ProposedStep = temp;
//min kinetic energy
G4double Emin = pUserLimits->GetUserMinEkine(aTrack);
G4double Rmin = G4EnergyLossTables::GetRange(Particle,Emin,Material);
temp = RangeNow - Rmin;
if (temp < 0.) return 0.;
if (ProposedStep > temp) ProposedStep = temp;
}
return ProposedStep;
}
G4VParticleChange* G4UserSpecialCuts::PostStepDoIt(
const G4Track& aTrack,
const G4Step&
)
//
// Kill the current particle, if requested by G4UserLimits
//
{
aParticleChange.Initialize(aTrack);
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetLocalEnergyDeposit (aTrack.GetKineticEnergy()) ;
aParticleChange.SetStatusChange(fStopAndKill);
return &aParticleChange;
}