Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user