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,417 @@
// 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: G4FastSimulationManager.cc,v 2.7 1998/10/26 14:31:36 mora Exp $
// GEANT4 tag $Name: geant4-00 $
//
//$Id:
//---------------------------------------------------------------
//
// G4FastSimulationManager.cc
//
// Description:
// Manages the Fast Simulation models attached to a envelope.
//
// History:
// Oct 97: Verderi && MoraDeFreitas - First Implementation.
//
//---------------------------------------------------------------
#include "G4FastSimulationManager.hh"
#include "G4GlobalFastSimulationManager.hh"
#include "G4PVPlacement.hh"
// --------------------------------------------------
// Constructor with envelope and IsUnique flag :
// --------------------------------------------------
//
G4FastSimulationManager::
G4FastSimulationManager(G4Envelope *anEnvelope,
G4bool IsUnique) :
fFastTrack(anEnvelope,IsUnique),fTriggedFastSimulationModel(NULL),
fLastCrossedParticle(NULL)
{
// Communicates to the Logical Volume that it becomes a
// envelope and with this fast simulation manager.
anEnvelope->BecomeEnvelopeForFastSimulation(this);
// Add itself to the GlobalFastSimulationManager
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->
AddFastSimulationManager(this);
}
// -----------
// Destructor:
// -----------
G4FastSimulationManager::~G4FastSimulationManager()
{
//
// Check out the Envelope about this pointer. If in use,
// resets the Logical Volume IsEnvelope flag to avoid clash.
//
if(fFastTrack.GetEnvelope()->GetFastSimulationManager()==this)
fFastTrack.GetEnvelope()->ClearEnvelopeForFastSimulation();
// Remove itself from the GlobalFastSimulationManager
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->
RemoveFastSimulationManager(this);
}
// ---------------------------------------
// Methods to activate/inactivate models
//----------------------------------------
G4bool
G4FastSimulationManager::ActivateFastSimulationModel(const G4String& aName)
{
G4int iModel;
// If the model is already active, do nothing.
for (iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->GetName() == aName)
return true;
// Look for in the fInactivatedModels list, if found insert it back to
// the ModelList
for (iModel=0; iModel<fInactivatedModels.length(); iModel++)
if(fInactivatedModels(iModel)->GetName() == aName) {
ModelList.
insert(fInactivatedModels.removeAt(iModel));
// forces the fApplicableModelList to be rebuild
fLastCrossedParticle=NULL;
return true;
}
return false;
}
G4bool
G4FastSimulationManager::InActivateFastSimulationModel(const G4String& aName)
{
// Look for in the ModelList, if found remove from it and keep the pointer
// on the fInactivatedModels list.
for (G4int iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->GetName() == aName) {
fInactivatedModels.
insert(ModelList.removeAt(iModel));
// forces the fApplicableModelList to be rebuild
fLastCrossedParticle=NULL;
return true;
}
return false;
}
//----------------------------------------
// Methods to add/remove GhostPlacements
//----------------------------------------
G4Transform3D*
G4FastSimulationManager::AddGhostPlacement(G4RotationMatrix *prot,
const G4ThreeVector &tlate)
{
G4Transform3D* newghostplace;
if(prot==0) prot = new G4RotationMatrix();
newghostplace = new G4Transform3D(*prot,tlate);
AddGhostPlacement(newghostplace);
return newghostplace;
}
G4Transform3D*
G4FastSimulationManager::AddGhostPlacement(G4Transform3D *trans3d)
{
GhostPlacements.insert(trans3d);
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->
FastSimulationNeedsToBeClosed();
return trans3d;
}
G4bool
G4FastSimulationManager::RemoveGhostPlacement(const G4Transform3D *trans3d)
{
G4bool found;
if((found=(GhostPlacements.remove(trans3d) != NULL)))
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->
FastSimulationNeedsToBeClosed();
return found;
}
//
//-------------------------------------
// Interface trigger method for the
// G4ParameterisationManagerProcess
//-------------------------------------
// G4bool GetFastSimulationManagerTrigger(const G4Track &);
//
// This method is used to interface the G4FastSimulationManagerProcess
// with the user Fast Simulation Models. It's called when the particle
// is inside the envelope.
//
// It :
//
// 1) initialises the private members (fFastTrack and so
// on);
// 2) loops on the IsApplicable() methods to find out the
// ones should be applied.
// 2) for these, loops on the ModelTrigger() methods to find out
// perhaps one that must be applied just now.
//
// If the a Fast Simulation Model is triggered then it returns
// true, false otherwise.
//
//-----------------------------------------------------------
G4bool
G4FastSimulationManager::
PostStepGetFastSimulationManagerTrigger(const G4Track& track,
const G4Navigator* theNavigator)
{
G4int iModel;
// If particle type changed re-build the fApplicableModelList.
if(fLastCrossedParticle!=track.GetDefinition()) {
fLastCrossedParticle=track.GetDefinition();
fApplicableModelList.clear();
// If Model List is empty, do nothing !
if(ModelList.length()==0) return false;
for (iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->IsApplicable(*(track.GetDefinition())))
fApplicableModelList.insert(ModelList(iModel));
}
// If Applicable Model List is empty, do nothing !
if(fApplicableModelList.length()==0) return false;
// -- Register current track
fFastTrack.SetCurrentTrack(track,theNavigator);
// tests if particle are on the boundary and leaving,
// in this case do nothing !
if(fFastTrack.OnTheBoundaryButExiting()) return false;
// Loops on the ModelTrigger() methods
for (iModel=0; iModel<fApplicableModelList.length(); iModel++)
//---------------------------------------------------
// Asks the ModelTrigger method if it must be trigged now.
//---------------------------------------------------
if(fApplicableModelList(iModel)->ModelTrigger(fFastTrack)) {
//--------------------------------------------------
// The model will be applied. Initializes the G4FastStep
// with the current state of the G4Track and
// same usefull parameters.
// In particular it does SetLocalEnergyDeposit(0.0).
//--------------------------------------------------
fFastStep.Initialize(fFastTrack);
// Keeps the FastSimulationModel pointer to call the
// DoIt() method.
fTriggedFastSimulationModel=fApplicableModelList(iModel);
return true;
}
//--------------------------------------------
// Nobody asks to gain control, returns false
//--------------------------------------------
return false;
}
void G4FastSimulationManager::InvokePostStepDoIt()
{
// const G4FastTrack& parFastTrack=fFastTrack;
fTriggedFastSimulationModel->DoIt(fFastTrack,fFastStep);
}
// -------------------------------------------------------------
// -- Mostly the same as above, in the case of AtRest particles:
// -------------------------------------------------------------
G4bool
G4FastSimulationManager::AtRestGetFastSimulationManagerTrigger(const G4Track& track,
const G4Navigator* theNavigator)
{
G4int iModel;
// If particle type changed re-build the fApplicableModelList.
if(fLastCrossedParticle!=track.GetDefinition()) {
fLastCrossedParticle=track.GetDefinition();
fApplicableModelList.clear();
// If Model List is empty, do nothing !
if(ModelList.length()==0) return false;
for (iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->IsApplicable(*(track.GetDefinition())))
fApplicableModelList.insert(ModelList(iModel));
}
// If Applicable Model List is empty, do nothing !
if(fApplicableModelList.length()==0) return false;
// -- Register current track
fFastTrack.SetCurrentTrack(track,theNavigator);
// -- (note: compared to the PostStepGetFastSimulationManagerTrigger,
// -- the test to see if the particle is on the boundary but leaving
// -- is irrelevant here)
// Loops on the models to see if one of them wants to trigger:
for (iModel=0; iModel < fApplicableModelList.length(); iModel++)
if(fApplicableModelList(iModel)->AtRestModelTrigger(fFastTrack))
{
fFastStep.Initialize(fFastTrack);
fTriggedFastSimulationModel=fApplicableModelList(iModel);
return true;
}
//--------------------------------------------
// Nobody asks to gain control, returns false
//--------------------------------------------
return false;
}
void G4FastSimulationManager::InvokeAtRestDoIt()
{
fTriggedFastSimulationModel->AtRestDoIt(fFastTrack,fFastStep);
}
G4bool
G4FastSimulationManager::
InsertGhostHereIfNecessary(G4VPhysicalVolume* theClone,
const G4ParticleDefinition& theParticle)
{
G4PVPlacement *GhostPhysical;
// Not to do if there aren't glost placements
if(GhostPlacements.length()==0) return false;
// If there are, verifies if at least one model is applicable
// for theParticle.
for (G4int iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->IsApplicable(theParticle)) {
// Ok, we find one. Place the ghost(s).
for (G4int ighost=0; ighost<GhostPlacements.length(); ighost++)
GhostPhysical=new
G4PVPlacement(*(GhostPlacements(ighost)),
fFastTrack.GetEnvelope()->GetName(),
fFastTrack.GetEnvelope(),
theClone,
false,0);
// And answer true
return true;
}
//otherwise answer false
return false;
}
void
G4FastSimulationManager::ListTitle() const
{
G4cout << fFastTrack.GetEnvelope()->GetName();
if(GhostPlacements.length()!=0) G4cout << " (ghost)";
}
void
G4FastSimulationManager::ListModels() const
{
G4int iModel;
G4cout << "Current Models for the ";
ListTitle();
G4cout << " Envelope:\n";
for (iModel=0; iModel<ModelList.length(); iModel++)
G4cout << " " << ModelList(iModel)->GetName() << "\n";
for (iModel=0; iModel<fInactivatedModels.length(); iModel++)
G4cout << " " << fInactivatedModels(iModel)->GetName()
<< "(inactivated)\n";
}
void
G4FastSimulationManager::ListModels(const G4String& aName) const
{
G4int iModel;
G4int titled = 0;
G4ParticleTable* theParticleTable=
G4ParticleTable::GetParticleTable();
// Active Models
for (iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->GetName() == aName ||
aName == "all" ) {
if(!(titled++)){
G4cout << "In the envelope ";
ListTitle();
G4cout << ",\n";
}
G4cout << " the model " << ModelList(iModel)->GetName()
<< " is applicable for :\n ";
G4int list_started=0;
for (G4int iParticle=0; iParticle<theParticleTable->entries();
iParticle++)
if(ModelList(iModel)->
IsApplicable(*(theParticleTable->
GetParticle(iParticle)))) {
if(list_started++) G4cout << ", ";
G4cout << theParticleTable->
GetParticle(iParticle)->GetParticleName();
}
G4cout <<endl;
}
// Inactive Models
for (iModel=0; iModel<fInactivatedModels.length(); iModel++)
if(fInactivatedModels(iModel)->GetName() == aName ||
aName == "all" ) {
if(!(titled++)){
G4cout << "In the envelope ";
ListTitle();
G4cout << ",\n";
}
G4cout << " the model " << fInactivatedModels(iModel)->GetName()
<< " (inactivated) is applicable for :\n ";
G4int list_started=0;
for (G4int iParticle=0; iParticle<theParticleTable->entries();
iParticle++)
if(fInactivatedModels(iModel)->
IsApplicable(*(theParticleTable->
GetParticle(iParticle)))) {
if(list_started++) G4cout << ", ";
G4cout << theParticleTable->
GetParticle(iParticle)->GetParticleName();
}
G4cout <<endl;
}
}
void
G4FastSimulationManager::ListModels(const G4ParticleDefinition* aPD) const
{
G4int iModel;
G4bool unique=true;
// Active Models
for (iModel=0; iModel<ModelList.length(); iModel++)
if(ModelList(iModel)->IsApplicable(*aPD)) {
G4cout << "Envelope ";
ListTitle();
G4cout << ", Model "
<< ModelList(iModel)->GetName()
<< "." << endl;
}
// inactive Models
for (iModel=0; iModel<fInactivatedModels.length(); iModel++)
if(fInactivatedModels(iModel)->IsApplicable(*aPD)) {
G4cout << "Envelope ";
ListTitle();
G4cout << ", Model "
<< fInactivatedModels(iModel)->GetName()
<< " (inactivated)." << endl;
}
if(!unique)
G4cout << "\a\n >>>>>>Warning: two or more Models for the same "
<< "particle type attached to the same envelope!"
<< endl;
unique=false;
}
@@ -0,0 +1,530 @@
// 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: G4FastSimulationManagerProcess.cc,v 2.14 1998/12/08 04:06:48 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//---------------------------------------------------------------
//
// G4FastSimulationProcess.cc
//
// Description:
// The process that triggers the parameterised simulations,
// if any.
//
// History:
// August 97: First implementation. Verderi && MoraDeFreitas.
//---------------------------------------------------------------
#include "G4ios.hh"
#include "G4FastSimulationManagerProcess.hh"
#include "G4GlobalFastSimulationManager.hh"
#include "G4TransportationManager.hh"
#include "G4ParticleChange.hh"
//----------------------------
// Constructor with only name:
//----------------------------
G4FastSimulationManagerProcess::
G4FastSimulationManagerProcess(const G4String& processName,
G4ProcessType theType) :
G4VProcess(processName,theType)
{
pParticleChange = &aDummyParticleChange;
fGhostTouchable = new G4TouchableHistory();
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created " << endl;
}
fGhostFieldPropagator = new G4PropagatorInField(&fGhostNavigator,
G4TransportationManager::
GetTransportationManager()->
GetFieldManager());
}
// -----------
// Destructor:
// -----------
G4FastSimulationManagerProcess::~G4FastSimulationManagerProcess()
{
delete fGhostTouchable;
delete fGhostFieldPropagator;
}
//----------------------------------------------------------
//
// PostStepGetPhysicalInteractionLength()
//
// This method is used to trigger the parameterised
// simulation.
//
//----------------------------------------------------------
//
// To be triggered the conditions that must be
// fullfilled are :
//
// 1) a call to track->GetVolume()->GetLogicalVolume()->
// GetFastSimulationManager() returns a G4FastSimulationManager
// not NULL pointer (kept in fFastSimulationManager);
//
// AND
//
// 2)a call to this fFastSimulationManager->GetTrigger() method
/// returns a G4bool True.
//
//
// If the fFastSimulationManager* is triggered then:
//
// * condition = ExclusivelyForced
// * returns 0.0
//
// else:
// * condition = NotForced
// * returns DBL_MAX
//
//-----------------------------------------------------------
G4double
G4FastSimulationManagerProcess::PostStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition)
{
// ------------------------------
// Prelude for initial Step only:
// ------------------------------
// ----------------------------------------------------------
// -- If starting a track, check if there is a parallel World
// -- for the new particle being tracked.
// -- (may be Done more than once in very special cases,
// -- since the fStarTracking is switched off lower.)
// ----------------------------------------------------------
if(fStartTracking)
{
G4FlavoredParallelWorld* flavoredWorld =
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->
GetFlavoredWorldForThis(track.GetDynamicParticle()->GetDefinition());
fGhostWorld = NULL;
if (flavoredWorld)
fGhostWorld = flavoredWorld->GetThePhysicalVolumeWorld();
if (fGhostWorld)
{
fGhostNavigator.SetWorldVolume(fGhostWorld);
fUpdateGhostTouchable = true;
fGhostSafety = -1.;
// Navigation in Field:
fParticleCharge = track.GetDynamicParticle()->GetDefinition()->GetPDGCharge();
}
else
{
fOutOfGhostWorld = true;
}
}
// -------------------------------------------------------
//
// Parameterisation Trigger invokation sequence :
//
// -------------------------------------------------------
fFastSimulationTrigger = false;
//---------------------------------------------
// Normal Dispatcher (for tracking geometry) :
//---------------------------------------------
if(fFastSimulationManager =
track.GetVolume()->GetLogicalVolume()->GetFastSimulationManager())
{
// Yes, so should us trigger a fast simulation model now ?
if(fFastSimulationTrigger =
fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track))
{
// Yes, lets take the control over the stepping !
*condition = ExclusivelyForced;
return 0.0;
}
}
//-----------------------------------------
// * Parallel geometry Dispatcher if any.
// * If no trigger in the parallel geometry
// returns the Conditionally forced signal.
//-----------------------------------------
if(fGhostWorld)
{
// First, update the touchable history of ghost if necessary, ie when:
// - this is first Step of tracking
// - the last Step was limited by ghost geometry
// otherwise performs a single Locate
if (fUpdateGhostTouchable)
{
fUpdateGhostTouchable=false;
if (fStartTracking)
{
fGhostNavigator.LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
fGhostTouchable,
false);
fStartTracking = false;
}
else
{
fGhostNavigator.SetGeometricallyLimitedStep();
fGhostNavigator.LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
fGhostTouchable);
}
fOutOfGhostWorld = (fGhostTouchable->GetVolume() == NULL);
}
else if (previousStepSize > 0.0)
{
// G4ThreeVector direction= track.GetMomentumDirection();
// fGhostNavigator.LocateGlobalPointAndSetup(track.GetPosition(), &direction, true);
// The above looks not enough in case of mag-field, not clear why ?!?
fGhostNavigator.LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
fGhostTouchable);
}
if (!fOutOfGhostWorld)
{
if(fFastSimulationManager =
fGhostTouchable->GetVolume()->GetLogicalVolume()->GetFastSimulationManager())
{
// Yes, so should us trigger a fast simulation model now ?
if(fFastSimulationTrigger =
fFastSimulationManager->PostStepGetFastSimulationManagerTrigger(track,&fGhostNavigator))
{
// Yes, lets take the control over the stepping !
*condition = ExclusivelyForced;
return 0.0;
}
}
// No ghost trigger has occured (ie no manager or a manager but no trigger)
// Informs the stepping that PostStepDoIt may be called if the AlongGPIL
// will limit the Step.
// PostStepDoIt will switch on fUpdateGhostTouchable flag,
// and eventually correct position and mometum in case of
// mag-field.
*condition = Conditionally;
return DBL_MAX;
}
}
*condition = NotForced;
return DBL_MAX;
}
//------------------------------------
//
// PostStepDoIt()
//
//------------------------------------
G4VParticleChange* G4FastSimulationManagerProcess::PostStepDoIt(
const G4Track& track,
const G4Step& Step)
{
if (fFastSimulationTrigger)
{
// Executes the ParameterisedSimulation code.
fFastSimulationManager->InvokePostStepDoIt();
// Gets the ParameterisedSimulation response.
G4VParticleChange* Response=fFastSimulationManager->GettheParticleChange();
// If the particle is still alive, suspend it
// to re-initialise the other process.
if (Response->GetStatusChange() != fStopAndKill)
Response->SetStatusChange(fSuspend);
// Returns the Response
return Response;
}
else
{
if (fOutOfGhostWorld) G4cout << " ????????????? Problem of logic in GHOST param !!! " << endl;
// No FastSimulationManager has asked for trigger. That means here:
// - the PostStep is "Conditionally" forced because
// - the Step has been limited by the ALong of G4FSMP because
// - the track has reached a ghost boundary
// => the touchable history must be updated.
// fUpdateGhostTouchable = true; : MOVED BELOW: COMPLICATIONS WITH MAG-FIELD !!
if (fFieldExertsForce)
{
// -----------------------------------------------------------
// in case of field, correct for small discrepancy on position
// and momentum computed by the Transportation.
// HOWEVER, this correction can be somewhat problematic when
// the end point, which is close here to a Ghost boundary by
// construction, is also close to a boundary of the tracking
// geometry.
// Thus we correct when the safety in the tracking geometry
// allows to move the point enough. Otherwise we issue
// a warning.
// ----------------------------------------------------------
fTrackingNavigator.SetWorldVolume(G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking()->GetWorldVolume());
fTrackingNavigator.LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
track.GetMomentumDirection(),
&fTrackingHistory);
G4VPhysicalVolume* trackingVolume = fTrackingHistory.GetVolume();
G4double trackingSafety(0.0);
G4double trackingLinearDistance =
fTrackingNavigator.ComputeStep(
track.GetPosition(),
track.GetMomentumDirection(),
DBL_MAX,
trackingSafety);
xParticleChange.Initialize(track);
G4ThreeVector deltaPos = fGhostFieldPropagator->EndPosition() - track.GetPosition();
if (trackingSafety < deltaPos.mag())
{
fUpdateGhostTouchable = true; // What should we do here ?!?
// false => lot a microscopic steps
// is true rasonnably safe ?
G4cout << GetProcessName() << " : WARNING: Can not correct for\ndifference between tracking and ghost mag-field computations." << endl;
}
else
{
// easy case where we have enough room to displace the point where we need:
fUpdateGhostTouchable = true;
xParticleChange.SetPositionChange(fGhostFieldPropagator->EndPosition());
xParticleChange.SetMomentumChange(fGhostFieldPropagator->EndMomentumDir());
}
return &xParticleChange;
}
else
{
fUpdateGhostTouchable = true;
pParticleChange->Initialize(track);
return pParticleChange;
}
}
}
G4double G4FastSimulationManagerProcess::AlongStepGetPhysicalInteractionLength(
const G4Track& track,
G4double previousStepSize,
G4double currentMinimumStep,
G4double& proposedSafety,
G4GPILSelection* selection
)
{
// Informs the stepping that G4FastsimulationProcess wants
// to be able to limit the Step.
*selection = CandidateForSelection;
G4double returnedStep = DBL_MAX;
if (!fOutOfGhostWorld)
{
if (previousStepSize > 0.) fGhostSafety -= previousStepSize;
else fGhostSafety = -1.;
if (fGhostSafety < 0.) fGhostSafety = 0.0;
// ------------------------------------------
// Determination of the proposed STEP LENGTH:
// ------------------------------------------
if (currentMinimumStep <= fGhostSafety)
{
returnedStep = currentMinimumStep;
}
else // (currentMinimumStep > fGhostSafety: GFSMP may limit the Step)
{
fFieldExertsForce = (fParticleCharge != 0.0) &&
(G4TransportationManager::GetTransportationManager()->
GetFieldManager()->DoesFieldExist());
if ( !fFieldExertsForce )
{
fGhostStepLength = fGhostNavigator.ComputeStep(
track.GetPosition(),
track.GetMomentumDirection(),
currentMinimumStep,
fGhostSafety);
}
else
{
fGhostFieldPropagator->SetChargeMomentumMass(
fParticleCharge,
track.GetDynamicParticle()->
GetTotalMomentum(),
track.GetDynamicParticle()->
GetMass());
fGhostStepLength = fGhostFieldPropagator->ComputeStep(
track.GetPosition(),
track.GetMomentumDirection(),
currentMinimumStep,
fGhostSafety);
}
fPreSafety = fGhostSafety;
returnedStep = fGhostStepLength;
}
// ----------------------------------------------
// Returns the fGhostSafety as the proposedSafety
// The SteppingManager will take care of keeping
// the smallest one.
// ----------------------------------------------
proposedSafety = fGhostSafety;
}
return returnedStep;
}
G4VParticleChange* G4FastSimulationManagerProcess::AlongStepDoIt(
const G4Track& track,
const G4Step& Step
)
{
// Dummy ParticleChange ie: does nothing
pParticleChange->Initialize(track);
return pParticleChange;
}
//--------------------------------------------
//
// At Rest parameterisation:
//
//--------------------------------------------
//
// AtRestGetPhysiscalInteractionLength:
//
//--------------------------------------------
G4double
G4FastSimulationManagerProcess::AtRestGetPhysicalInteractionLength(
const G4Track& track,
G4ForceCondition* condition)
{
if ( (fFastSimulationManager =
track.GetVolume()->GetLogicalVolume()->GetFastSimulationManager())
!= NULL )
if (fFastSimulationManager->AtRestGetFastSimulationManagerTrigger(track))
{
// "*condition = ExclusivelyForced;" Not yet available
// for AtRest actions, so we use the trick below. However
// it is not garantee to work in the situation the track is
// alive after parameterisation.
// NOTE: Problem: the present stepping doesn't care if the particle
// has been killed between two AtRestDoIt() !!!
*condition = NotForced;
return -1.0; // TEMPORARY TRICK TO TAKE CONTROL !!!!
}
//-----------------------------------------
// * Parallel geometry Dispatcher if any.
// * If no trigger in the parallel geometry
// * returns DBL_MAX and NotForced signal.
//-----------------------------------------
if(fGhostWorld)
{
// First, update the touchable history of ghost if necessary, ie when:
// - this is first Step of tracking
// - the last Step was limited by ghost geometry
// otherwise performs a single Locate
if (fUpdateGhostTouchable)
{
fUpdateGhostTouchable=false;
if (fStartTracking)
{
fGhostNavigator.LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
fGhostTouchable,
false);
fStartTracking = false;
}
else
{
fGhostNavigator.SetGeometricallyLimitedStep();
fGhostNavigator.LocateGlobalPointAndUpdateTouchable(
track.GetPosition(),
fGhostTouchable);
}
fOutOfGhostWorld = (fGhostTouchable->GetVolume() == NULL);
}
if (!fOutOfGhostWorld)
{
if(fFastSimulationManager =
fGhostTouchable->GetVolume()->GetLogicalVolume()->GetFastSimulationManager())
{
// Should it trigger a fast simulation model now ?
if(fFastSimulationTrigger =
fFastSimulationManager->
AtRestGetFastSimulationManagerTrigger(track,&fGhostNavigator))
{
// "*condition = ExclusivelyForced;" Not yet available
// for AtRest actions, so we use the trick below. However
// it is not garantee to work in the situation the track is
// alive after parameterisation.
// NOTE: Problem: the present stepping doesn't care if the particle
// has been killed between two AtRestDoIt() !!!
*condition = NotForced;
return -1.0; // TEMPORARY TRICK TO TAKE CONTROL !!!!
}
}
}
}
// No, avoid to take control over the PostStepDoIt methods.
*condition = NotForced;
return DBL_MAX;
}
//-----------------------------------------------
//
// AtRestDoIt:
//
//-----------------------------------------------
G4VParticleChange* G4FastSimulationManagerProcess::AtRestDoIt(
const G4Track& track,
const G4Step& Step)
{
fFastSimulationManager->InvokeAtRestDoIt();
G4VParticleChange* Response = fFastSimulationManager->GettheParticleChange();
return Response;
}
void G4FastSimulationManagerProcess::StartTracking()
{
fStartTracking = true;
}
void G4FastSimulationManagerProcess::Verbose() const
{
/* G4cout << " >>>>> Trigger Status : ";
switch(fFastSimulationManager->GetTriggerStatus())
{
case NoModel:
G4cout << "NoModel" << endl;
break;
case OnBoundaryButLeaving:
G4cout << "OnBoundaryButLeaving" << endl;
break;
case OneModelTrigger:
G4cout << "OneModelTrigger" << endl;
break;
case NoModelTrigger:
G4cout << "NoModelTrigger" << endl;
break;
case Undefined:
G4cout << "Undefined" << endl;
break;
default:
G4cout << " Bizarre..." << endl;
break;
}*/
}
@@ -0,0 +1,87 @@
// 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: G4FastSimulationMessenger.cc,v 2.3 1998/10/13 09:54:40 mora Exp $
// GEANT4 tag $Name: geant4-00 $
//
#include "G4FastSimulationMessenger.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4ios.hh"
G4FastSimulationMessenger::
G4FastSimulationMessenger(G4GlobalFastSimulationManager* theGFSM)
: fGlobalFastSimulationManager(theGFSM)
{
fFSDirectory = new G4UIdirectory("/param/");
fFSDirectory->SetGuidance("Fast Simulation print/control commands.");
fListEnvelopesCmd =
new G4UIcmdWithAString("/param/listEnvelopes", this);
fListEnvelopesCmd->SetParameterName("ParticleName",true);
fListEnvelopesCmd->SetDefaultValue("all");
fListEnvelopesCmd->SetGuidance("List all the envelope names for a given Particle");
fListEnvelopesCmd->SetGuidance("(or for all particles if without parameters).");
fListEnvelopesCmd->AvailableForStates(PreInit,Idle);
fListModelsCmd =
new G4UIcmdWithAString("/param/listModels", this);
fListModelsCmd->SetParameterName("EnvelopeName",true);
fListModelsCmd->SetDefaultValue("all");
fListModelsCmd->SetGuidance("List all the Model names for a given Envelope");
fListModelsCmd->SetGuidance("(or for all envelopes if without parameters).");
fListModelsCmd->AvailableForStates(PreInit,Idle);
fListIsApplicableCmd =
new G4UIcmdWithAString("/param/listIsApplicable", this);
fListIsApplicableCmd->SetParameterName("ModelName",true);
fListIsApplicableCmd->SetDefaultValue("all");
fListIsApplicableCmd->SetGuidance("List all the Particle names a given Model is applicable");
fListIsApplicableCmd->SetGuidance("(or for all Models if without parameters).");
fActivateModel =
new G4UIcmdWithAString("/param/ActivateModel", this);
fActivateModel->SetParameterName("ModelName",false);
fActivateModel->SetGuidance("Activate a given Model.");
fInActivateModel =
new G4UIcmdWithAString("/param/InActivateModel", this);
fInActivateModel->SetParameterName("ModelName",false);
fInActivateModel->SetGuidance("InActivate a given Model.");
}
G4FastSimulationMessenger::~G4FastSimulationMessenger()
{
delete fListIsApplicableCmd;
delete fActivateModel;
delete fInActivateModel;
delete fListModelsCmd;
delete fListEnvelopesCmd;
delete fFSDirectory;
}
void G4FastSimulationMessenger::SetNewValue(G4UIcommand * command,G4String newValue)
{
if( command == fListEnvelopesCmd)
if(newValue == "all")
fGlobalFastSimulationManager->ListEnvelopes();
else
fGlobalFastSimulationManager->
ListEnvelopes(G4ParticleTable::GetParticleTable()->
FindParticle(newValue));
if( command == fListModelsCmd)
fGlobalFastSimulationManager->ListEnvelopes(newValue, MODELS);
if( command == fListIsApplicableCmd)
fGlobalFastSimulationManager->ListEnvelopes(newValue, ISAPPLICABLE);
if( command == fActivateModel)
fGlobalFastSimulationManager->ActivateFastSimulationModel(newValue);
if( command == fInActivateModel)
fGlobalFastSimulationManager->InActivateFastSimulationModel(newValue);
}
@@ -0,0 +1,450 @@
// 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: G4FastStep.cc,v 2.8 1998/11/20 19:00:46 verderi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//$Id:
//---------------------------------------------------------------
//
// G4FastStep.cc
//
// Description:
// Encapsulates a G4ParticleChange and insure friendly interface
// methods to manage the primary/secondaries final state for
// Fast Simulation Models.
//
// History:
// Oct 97: Verderi && MoraDeFreitas - First Implementation.
// Apr 98: MoraDeFreitas - G4FastStep becomes the G4ParticleChange
// for the Fast Simulation Process.
//
//---------------------------------------------------------------
#include "G4FastStep.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4TrackFastVector.hh"
#include "G4DynamicParticle.hh"
void G4FastStep::Initialize(const G4FastTrack& fastTrack)
{
// keeps the fastTrack reference
fFastTrack=&fastTrack;
// currentTrack will be used to Initialize the other data members
const G4Track& currentTrack = *(fFastTrack->GetPrimaryTrack());
// use base class's method at first
G4VParticleChange::Initialize(currentTrack);
// set Energy/Momentum etc. equal to those of the parent particle
const G4DynamicParticle* pParticle = currentTrack.GetDynamicParticle();
theEnergyChange = pParticle->GetKineticEnergy();
theMomentumChange = pParticle->GetMomentumDirection();
thePolarizationChange = pParticle->GetPolarization();
theProperTimeChange = pParticle->GetProperTime();
// set Position/Time etc. equal to those of the parent track
thePositionChange = currentTrack.GetPosition();
theTimeChange = currentTrack.GetGlobalTime();
// switch off stepping hit invokation by default:
theSteppingControlFlag = AvoidHitInvocation;
// event biasing weigth:
theWeightChange = currentTrack.GetWeight();
}
//----------------------------------------
// -- Set the StopAndKilled signal
// -- and put kinetic energy to 0.0. in the
// -- G4ParticleChange.
//----------------------------------------
void G4FastStep::KillPrimaryTrack()
{
SetPrimaryTrackFinalKineticEnergy(0.) ;
SetStatusChange(fStopAndKill) ;
}
//--------------------
//
//--------------------
void
G4FastStep::
SetPrimaryTrackFinalPosition(const G4ThreeVector &position,
G4bool localCoordinates)
{
// Compute the position coordinate in global
// reference system if needed ...
G4ThreeVector globalPosition = position;
if (localCoordinates)
globalPosition = fFastTrack->GetInverseAffineTransformation()->
TransformPoint(position);
// ...and feed the globalPosition:
thePositionChange = globalPosition;
}
//--------------------
//
//--------------------
void
G4FastStep::
SetPrimaryTrackFinalMomentum(const G4ThreeVector &momentum,
G4bool localCoordinates)
{
// Compute the momentum in global reference
// system if needed ...
G4ThreeVector globalMomentum = momentum;
if (localCoordinates)
globalMomentum = fFastTrack->GetInverseAffineTransformation()->
TransformAxis(momentum);
// ...and feed the globalMomentum (ensuring unitarity)
SetMomentumChange(globalMomentum.unit());
}
//--------------------
//
//--------------------
void
G4FastStep::
SetPrimaryTrackFinalKineticEnergyAndDirection(G4double kineticEnergy,
const G4ThreeVector &direction,
G4bool localCoordinates)
{
// Compute global direction if needed...
G4ThreeVector globalDirection = direction;
if (localCoordinates)
globalDirection =fFastTrack->GetInverseAffineTransformation()->
TransformAxis(direction);
// ...and feed the globalMomentum (ensuring unitarity)
SetMomentumChange(globalDirection.unit());
SetPrimaryTrackFinalKineticEnergy(kineticEnergy);
}
//--------------------
//
//--------------------
void
G4FastStep::
SetPrimaryTrackFinalPolarization(const G4ThreeVector &polarization,
G4bool localCoordinates)
{
// Compute polarization in global system if needed:
G4ThreeVector globalPolarization(polarization);
if (localCoordinates)
globalPolarization = fFastTrack->GetInverseAffineTransformation()->
TransformAxis(globalPolarization);
// Feed the particle globalPolarization:
thePolarizationChange = globalPolarization;
}
//--------------------
//
//--------------------
G4Track* G4FastStep::
CreateSecondaryTrack(const G4DynamicParticle& dynamics,
G4ThreeVector polarization,
G4ThreeVector position,
G4double time,
G4bool localCoordinates )
{
G4DynamicParticle dummyDynamics(dynamics);
// ------------------------------------------
// Add the polarization to the dummyDynamics:
// ------------------------------------------
dummyDynamics.SetPolarization(polarization.x(),
polarization.y(),
polarization.z());
return CreateSecondaryTrack(dummyDynamics, position, time, localCoordinates);
}
//--------------------
//
//--------------------
G4Track* G4FastStep::
CreateSecondaryTrack(const G4DynamicParticle& dynamics,
G4ThreeVector position,
G4double time,
G4bool localCoordinates )
{
// ----------------------------------------
// Quantities in global coordinates system.
//
// The allocated globalDynamics is deleted
// by the destructor of the G4Track.
// ----------------------------------------
G4DynamicParticle* globalDynamics =
new G4DynamicParticle(dynamics);
G4ThreeVector globalPosition(position);
// -----------------------------------
// Convert to global system if needed:
// -----------------------------------
if (localCoordinates)
{
// -- Momentum Direction:
globalDynamics->SetMomentumDirection(fFastTrack->
GetInverseAffineTransformation()->
TransformAxis(globalDynamics->
GetMomentumDirection()));
// -- Polarization:
G4ThreeVector globalPolarization;
globalPolarization = fFastTrack->GetInverseAffineTransformation()->
TransformAxis(globalDynamics->GetPolarization());
globalDynamics->SetPolarization(
globalPolarization.x(),
globalPolarization.y(),
globalPolarization.z()
);
// -- Position:
globalPosition = fFastTrack->GetInverseAffineTransformation()->
TransformPoint(globalPosition);
}
//-------------------------------------
// Create the G4Track of the secondary:
//-------------------------------------
G4Track* secondary = new G4Track(
globalDynamics,
time,
globalPosition
);
//-------------------------------
// and feed the changes:
//-------------------------------
AddSecondary(secondary);
//--------------------------------------
// returns the pointer on the secondary:
//--------------------------------------
return secondary;
}
// G4FastStep should never be Initialized in this way
// but we must define it to avoid warnings.
void G4FastStep::Initialize(const G4Track&) {
G4Exception("G4FastStep::Initialize(const G4Track&) should never be called,\nyou must use instead the G4FastStep::Initialize(const G4FastTrack&)\nmethod!");
}
G4FastStep::G4FastStep():G4VParticleChange()
{
debugFlag = true;
if (verboseLevel>2) {
G4cerr << "G4FastStep::G4FastStep() " << endl;
}
}
G4FastStep::~G4FastStep()
{
if (verboseLevel>2) {
G4cerr << "G4FastStep::~G4FastStep() " << endl;
}
}
// copy and assignment operators are implemented as "shallow copy"
G4FastStep::G4FastStep(const G4FastStep &right)
{
*this = right;
}
G4FastStep & G4FastStep::operator=(const G4FastStep &right)
{
if (this != &right)
{
theListOfSecondaries = right.theListOfSecondaries;
theSizeOftheListOfSecondaries = right.theSizeOftheListOfSecondaries;
theNumberOfSecondaries = right.theNumberOfSecondaries;
theStatusChange = right.theStatusChange;
theMomentumChange = right.theMomentumChange;
thePolarizationChange = right.thePolarizationChange;
thePositionChange = right.thePositionChange;
theTimeChange = right.theTimeChange;
theEnergyChange = right.theEnergyChange;
theTrueStepLength = right.theTrueStepLength;
theLocalEnergyDeposit = right.theLocalEnergyDeposit;
theSteppingControlFlag = right.theSteppingControlFlag;
theWeightChange = right.theWeightChange;
}
return *this;
}
G4bool G4FastStep::operator==(const G4FastStep &right) const
{
return ((G4VParticleChange *)this == (G4VParticleChange *) &right);
}
G4bool G4FastStep::operator!=(const G4FastStep &right) const
{
return ((G4VParticleChange *)this != (G4VParticleChange *) &right);
}
//----------------------------------------------------------------
// methods for updating G4Step
//
G4Step* G4FastStep::UpdateStepForPostStep(G4Step* pStep)
{
// A physics process always calculates the final state of the particle
// Take note that the return type of GetMomentumChange is a
// pointer to G4ParticleMometum. Also it is a normalized
// momentum vector.
G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
G4Track* aTrack = pStep->GetTrack();
G4double mass = aTrack->GetDynamicParticle()->GetMass();
// update kinetic energy and momentum direction
pPostStepPoint->SetMomentumDirection(theMomentumChange);
pPostStepPoint->SetKineticEnergy( theEnergyChange );
// update polarization
pPostStepPoint->SetPolarization( thePolarizationChange );
// update position and time
pPostStepPoint->SetPosition( thePositionChange );
pPostStepPoint->SetGlobalTime( theTimeChange );
pPostStepPoint->AddLocalTime( theTimeChange
- aTrack->GetGlobalTime());
pPostStepPoint->SetProperTime( theProperTimeChange );
// update weight
pPostStepPoint->SetWeight( theWeightChange );
if (debugFlag) CheckIt(*aTrack);
// Update the G4Step specific attributes
return UpdateStepInfo(pStep);
}
G4Step* G4FastStep::UpdateStepForAtRest(G4Step* pStep)
{
// A physics process always calculates the final state of the particle
G4StepPoint* pPreStepPoint = pStep->GetPreStepPoint();
G4StepPoint* pPostStepPoint = pStep->GetPostStepPoint();
G4Track* aTrack = pStep->GetTrack();
G4double mass = mass = aTrack->GetDynamicParticle()->GetMass();
// update kinetic energy and momentum direction
pPostStepPoint->SetMomentumDirection(theMomentumChange);
pPostStepPoint->SetKineticEnergy( theEnergyChange );
// update polarization
pPostStepPoint->SetPolarization( thePolarizationChange );
// update position and time
pPostStepPoint->SetPosition( thePositionChange );
pPostStepPoint->SetGlobalTime( theTimeChange );
pPostStepPoint->AddLocalTime( theTimeChange
- aTrack->GetGlobalTime());
pPostStepPoint->SetProperTime( theProperTimeChange );
// update weight
pPostStepPoint->SetWeight( theWeightChange );
if (debugFlag) CheckIt(*aTrack);
// Update the G4Step specific attributes
return UpdateStepInfo(pStep);
}
//----------------------------------------------------------------
// methods for printing messages
//
void G4FastStep::DumpInfo() const
{
// use base-class DumpInfo
G4VParticleChange::DumpInfo();
G4cout.precision(3);
G4cout << " Position - x (mm) : "
<< setw(20) << thePositionChange.x()/mm
<< endl;
G4cout << " Position - y (mm) : "
<< setw(20) << thePositionChange.y()/mm
<< endl;
G4cout << " Position - z (mm) : "
<< setw(20) << thePositionChange.z()/mm
<< endl;
G4cout << " Time (ns) : "
<< setw(20) << theTimeChange/ns
<< endl;
G4cout << " Proper Time (ns) : "
<< setw(20) << theProperTimeChange/ns
<< endl;
G4cout << " Momentum Direct - x : "
<< setw(20) << theMomentumChange.x()
<< endl;
G4cout << " Momentum Direct - y : "
<< setw(20) << theMomentumChange.y()
<< endl;
G4cout << " Momentum Direct - z : "
<< setw(20) << theMomentumChange.z()
<< endl;
G4cout << " Kinetic Energy (MeV): "
<< setw(20) << theEnergyChange/MeV
<< endl;
G4cout << " Polarization - x : "
<< setw(20) << thePolarizationChange.x()
<< endl;
G4cout << " Polarization - y : "
<< setw(20) << thePolarizationChange.y()
<< endl;
G4cout << " Polarization - z : "
<< setw(20) << thePolarizationChange.z()
<< endl;
}
G4bool G4FastStep::CheckIt(const G4Track& aTrack)
{
G4bool itsOK = true;
if (theEnergyChange > aTrack.GetKineticEnergy()) {
G4cout << " !!! the energy becomes larger than the initial energy !!!"
<< " : " << (theEnergyChange -aTrack.GetKineticEnergy())/MeV
<< "MeV " <<endl;
itsOK = false;
}
if ( (theEnergyChange >0.) &&
( abs(theMomentumChange.mag2()-1.0) > 1.0e-5 ) ){
G4cout << " !!! the Momentum Change is not unit vector !!!!"
<< " : " << theMomentumChange.mag()
<< endl;
itsOK = false;
}
if (theTimeChange < aTrack.GetGlobalTime()) {
G4cout << " !!! the global time goes back !!!"
<< " : " << aTrack.GetGlobalTime()/ns
<< " -> " << theTimeChange/ns
<< "[ns] " <<endl;
itsOK = false;
}
if (theProperTimeChange < aTrack.GetProperTime()) {
G4cout << " !!! the poper time goes back !!!"
<< " : " << aTrack.GetProperTime()/ns
<< " -> " << theProperTimeChange/ns
<< "[ns] " <<endl;
itsOK = false;
}
if (!itsOK) {
G4cout << " G4FastStep::CheckIt " <<endl;
G4cout << " pointer : " << this <<endl ;
DumpInfo();
}
return itsOK;
}
@@ -0,0 +1,152 @@
// 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: G4FastTrack.cc,v 2.3 1998/10/13 09:54:43 mora Exp $
// GEANT4 tag $Name: geant4-00 $
//
//$Id:
//---------------------------------------------------------------
//
// G4FastTrack.cc
//
// Description:
// Keeps the current track information and special features
// for Parameterised Simulation Models.
//
// History:
// Oct 97: Verderi && MoraDeFreitas - First Implementation.
//
//---------------------------------------------------------------
#include "G4ios.hh"
#include "G4FastTrack.hh"
#include "G4TransportationManager.hh"
// -----------
// Constructor
// -----------
//
G4FastTrack::G4FastTrack(G4Envelope *anEnvelope,
G4bool IsUnique) :
fEnvelope(anEnvelope),fEnvelopeSolid(fEnvelope->GetSolid()),
fIsUnique(IsUnique), fAffineTransformationDefined(false)
{}
// -----------
// Destructor:
// -----------
G4FastTrack::~G4FastTrack()
{}
//------------------------------------------------------------
// The parameterised simulation manager uses the SetCurrentTrack
// method to setup the current G4FastTrack object
//------------------------------------------------------------
void G4FastTrack::SetCurrentTrack(const G4Track& track,
const G4Navigator* theNavigator)
{
// -- Register track pointer (used everywhere):
fTrack = &track;
//-----------------------------------------------------
// First time the track enters the volume or if the
// Logical Volume was placed n-Times in the geometry :
//
// Records the Rotation+Translation for the Envelope !
// When the particle is inside or on the boundary, the
// NavigationHistory IS UP TO DATE.
//------------------------------------------------------
if (!fAffineTransformationDefined || !fIsUnique)
FRecordsAffineTransformation(theNavigator);
//-------------------------------------------
// Records local position/momentum/direction
// of the Track.
// They are accessible to the user through a
// set of Get functions and should be useful
// to decide to trigger or not.
//-------------------------------------------
// -- local position:
fLocalTrackPosition = fAffineTransformation.
TransformPoint(fTrack->GetPosition());
// -- local momentum:
fLocalTrackMomentum = fAffineTransformation.
TransformAxis(fTrack->GetMomentum());
// -- local direction:
fLocalTrackDirection = fLocalTrackMomentum.unit();
// -- local polarization:
fLocalTrackPolarization = fAffineTransformation.
TransformAxis(fTrack->GetPolarization());
}
//------------------------------------
//
// 3D transformation of the envelope
// This is Done only one time.
//
//------------------------------------
void
G4FastTrack::FRecordsAffineTransformation(const G4Navigator* theNavigator)
{
//--------------------------------------------------------
// Get the touchable history which represents the current
// volume hierachy the particle is in.
// Note that TouchableHistory allocated by the Navigator
// must be deleted by G4FastTrack.
//--------------------------------------------------------
const G4Navigator* NavigatorToUse;
if(theNavigator != NULL ) NavigatorToUse=theNavigator;
else
NavigatorToUse=
G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking();
G4TouchableHistory *history =
NavigatorToUse->CreateTouchableHistory();
//-----------------------------------------------------
// Run accross the hierarchy to find the physical volume
// associated with the envelope
//-----------------------------------------------------
int depth = history->GetHistory()->GetDepth();
int idepth, Done = 0;
for (idepth = 0; idepth <= depth; idepth++) {
if (history->GetHistory()->GetVolume(idepth)->GetLogicalVolume() ==
fEnvelope) {
fEnvelopePhysicalVolume=history->GetHistory()->GetVolume(idepth);
Done = 1;
break;
}
}
//---------------------------------------------
//-- Verification: should be removed in future:
//---------------------------------------------
if ( !Done )
{
G4cout << "\n\nERROR !!! can't find Transform for " <<
fEnvelopePhysicalVolume->GetName() << "\n\n" << endl;
}
else
{
//-------------------------------------------------------
// Records the transformation and inverse transformation:
//-------------------------------------------------------
fAffineTransformation = history->GetHistory()->GetTransform(idepth);
fInverseAffineTransformation = fAffineTransformation.Inverse();
fAffineTransformationDefined = true;
}
//------------------------------------------------------
// Delete the TouchableHistory created by the Navigator:
//------------------------------------------------------
delete history;
}
@@ -0,0 +1,236 @@
// 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: G4GlobalFastSimulationManager.cc,v 2.6 1998/10/13 09:54:44 mora Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//---------------------------------------------------------------
//
// G4GlobalFastSimulationManager.cc
//
// Description:
// A singleton class which manages the Fast Simulation managers
// attached to envelopes. Implementation.
//
// History:
// June 98: Verderi && MoraDeFreitas - "G4ParallelWorld" becomes
// "G4FlavoredParallelWorld"; some method name changes;
// GetFlavoredWorldForThis now returns a
// G4FlavoredParallelWorld pointer.
// Feb 98: Verderi && MoraDeFreitas - First Implementation.
// March 98: correction to instanciate dynamically the manager
//
//---------------------------------------------------------------
#include "G4GlobalFastSimulationManager.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4Material.hh"
#include "G4ThreeVector.hh"
#include "G4PVPlacement.hh"
#include "G4TransportationManager.hh"
#include "G4FastSimulationMessenger.hh"
G4GlobalFastSimulationManager*
G4GlobalFastSimulationManager::fGlobalFastSimulationManager = 0;
G4GlobalFastSimulationManager*
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()
{
if(!fGlobalFastSimulationManager)
{
fGlobalFastSimulationManager = new G4GlobalFastSimulationManager;
}
return fGlobalFastSimulationManager;
}
G4GlobalFastSimulationManager::G4GlobalFastSimulationManager()
{
// It starts closed.
fClosed=true;
// Initialises the G4FastSimulationMessenger
fTheFastSimulationMessenger=new G4FastSimulationMessenger(this);
}
G4GlobalFastSimulationManager::~G4GlobalFastSimulationManager()
{
delete fTheFastSimulationMessenger;
}
void G4GlobalFastSimulationManager::FastSimulationNeedsToBeClosed()
{
fClosed=false;
}
void G4GlobalFastSimulationManager::
AddFastSimulationManager(G4FastSimulationManager* fsmanager)
{
ManagedManagers.insert(fsmanager);
}
void G4GlobalFastSimulationManager::
RemoveFastSimulationManager(G4FastSimulationManager* fsmanager)
{
ManagedManagers.remove(fsmanager);
}
void G4GlobalFastSimulationManager::CloseFastSimulation()
{
if(fClosed) return;
G4ParticleTable* theParticleTable;
// Reset the NeededFlavoredWorlds List
NeededFlavoredWorlds.clearAndDestroy();
// We'll look for models for all particle types
theParticleTable=G4ParticleTable::GetParticleTable();
// Creates the first world volume clone.
G4VPhysicalVolume* aClone=GiveMeAWorldVolumeClone();
G4cout << "Closing FastSimulation\n";
for (G4int iParticle=0; iParticle<theParticleTable->entries(); iParticle++) {
G4bool Needed = false;
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++)
Needed = Needed || ManagedManagers(ifsm)->
InsertGhostHereIfNecessary(aClone,
*(theParticleTable->
GetParticle(iParticle)));
// if some FSM inserted a ghost, keep this clone.
if(Needed) {
NeededFlavoredWorlds.insert(new
G4FlavoredParallelWorld(theParticleTable->
GetParticle(iParticle),
aClone));
// and prepare a new one.
aClone=GiveMeAWorldVolumeClone();
}
}
fClosed=true;
}
G4FlavoredParallelWorld*
G4GlobalFastSimulationManager::
GetFlavoredWorldForThis(G4ParticleDefinition* particle)
{
for (G4int ipw=0; ipw<NeededFlavoredWorlds.length(); ipw++)
if(NeededFlavoredWorlds(ipw)->GetTheParticleType()==particle)
return NeededFlavoredWorlds(ipw);
return NULL;
}
void
G4GlobalFastSimulationManager::ActivateFastSimulationModel(const G4String& aName)
{
G4bool result = false;
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++)
result = result || ManagedManagers(ifsm)->ActivateFastSimulationModel(aName);
if(result)
G4cout << "Model " << aName << " activated.";
else
G4cout << "Model " << aName << " not found.";
G4cout << endl;
}
void
G4GlobalFastSimulationManager::InActivateFastSimulationModel(const G4String& aName)
{
G4bool result = false;
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++)
result = result || ManagedManagers(ifsm)->InActivateFastSimulationModel(aName);
if(result)
G4cout << "Model " << aName << " inactivated.";
else
G4cout << "Model " << aName << " not found.";
G4cout << endl;
}
void
G4GlobalFastSimulationManager::ListEnvelopes(const G4String& aName,
listType theType)
{
if(theType == ISAPPLICABLE) {
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++)
ManagedManagers(ifsm)->ListModels(aName);
return;
}
if(aName == "all") {
G4int titled = 0;
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++) {
if(theType == NAMES_ONLY) {
if(!(titled++))
G4cout << "Current Envelopes for Fast Simulation:\n";
G4cout << " ";
ManagedManagers(ifsm)->ListTitle();
G4cout << endl;
}
else ManagedManagers(ifsm)->ListModels();
}
}
else {
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++)
if(aName == ManagedManagers(ifsm)->
GetEnvelope()->GetName()){
ManagedManagers(ifsm)->ListModels();
break;
}
}
}
void
G4GlobalFastSimulationManager::ListEnvelopes(const G4ParticleDefinition* aPD)
{
for (G4int ifsm=0; ifsm<ManagedManagers.length(); ifsm++)
ManagedManagers(ifsm)->ListModels(aPD);
}
G4VPhysicalVolume*
G4GlobalFastSimulationManager::GiveMeAWorldVolumeClone()
{
G4VPhysicalVolume* theParallelWorldPhysical;
G4TransportationManager *transportationManager=
G4TransportationManager::GetTransportationManager();
G4VSolid *parallelWorldSolid=transportationManager->
GetNavigatorForTracking()->GetWorldVolume()->
GetLogicalVolume()->GetSolid();
G4Material *parallelWorldMaterial=transportationManager->
GetNavigatorForTracking()->GetWorldVolume()->
GetLogicalVolume()->GetMaterial();
G4LogicalVolume *parallelWorldLog =
new G4LogicalVolume(parallelWorldSolid,
parallelWorldMaterial,
"ParallelWorldLogical",
0, 0, 0);
theParallelWorldPhysical= new G4PVPlacement(0,G4ThreeVector(),
"ParallelWorldPhysical",
parallelWorldLog,
0,false,0);
return theParallelWorldPhysical;
}
G4bool
G4GlobalFastSimulationManager::Notify(G4ApplicationState requestedState)
{
G4StateManager * stateManager = G4StateManager::GetStateManager();
if((stateManager->GetPreviousState()==Idle) &&
(requestedState==GeomClosed) &&
(!fClosed))
G4Exception("G4GlobalFastSimulationManager fatal error : \n1) you are using ghost volumes;\n2) In this case the G4GlobalFastSimulationManager MUST be closed BEFORE\n closing the geometry;\n3) To do this put in your code the call \n G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->\n CloseFastSimulation();\n just before closing the geometry.");
return true;
}
@@ -0,0 +1,50 @@
// 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: G4VFastSimulationModel.cc,v 2.1 1998/10/13 09:54:45 mora Exp $
// GEANT4 tag $Name: geant4-00 $
//
// $Id:
//---------------------------------------------------------------
//
// G4VFastSimulationModel.cc
//
// Description:
// Base class for fast simulation models.
//
// History:
// Oct 97: Verderi && MoraDeFreitas - First Implementation.
//
//---------------------------------------------------------------
#include "G4VFastSimulationModel.hh"
#include "G4FastSimulationManager.hh"
//
// Simple constructor.
//
G4VFastSimulationModel::
G4VFastSimulationModel(const G4String& aName) : theModelName(aName) {}
//
// Constructor for beginners. We do all the job, no matters...
//
G4VFastSimulationModel::
G4VFastSimulationModel(const G4String& aName,
G4Envelope* anEnvelope,
G4bool IsUnique) : theModelName(aName)
{
// Retrieves the Fast Simulation Manager ou creates one
// if needed.
G4FastSimulationManager* theFastSimulationManager;
if ((theFastSimulationManager=anEnvelope->GetFastSimulationManager())
==NULL) theFastSimulationManager=
new G4FastSimulationManager(anEnvelope,IsUnique);
// adds this model to the Fast Simulation Manager.
theFastSimulationManager->AddFastSimulationModel(this);
}