Files
geant4/source/processes/parameterisation/src/G4FastSimulationManager.cc
T
2016-06-09 10:28:22 +02:00

468 lines
15 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * 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 1.8 2002/11/15 11:41:56 stesting Exp $
// GEANT4 tag $Name: geant4-05-02 $
//
//---------------------------------------------------------------
//
// 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(0),
fLastCrossedParticle(0)
{
// 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)
{
size_t iModel;
// If the model is already active, do nothing.
for (iModel=0; iModel<ModelList.size(); iModel++)
if(ModelList[iModel]->GetName() == aName)
return true;
// Look for in the fInactivatedModels list, if found push_back it back to
// the ModelList
for (iModel=0; iModel<fInactivatedModels.size(); iModel++)
if(fInactivatedModels[iModel]->GetName() == aName) {
ModelList.
push_back (fInactivatedModels.removeAt(iModel));
// forces the fApplicableModelList to be rebuild
fLastCrossedParticle=0;
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 (size_t iModel=0; iModel<ModelList.size(); iModel++)
if(ModelList[iModel]->GetName() == aName) {
fInactivatedModels.
push_back (ModelList.removeAt(iModel));
// forces the fApplicableModelList to be rebuild
fLastCrossedParticle=0;
return true;
}
return false;
}
G4VFastSimulationModel*
G4FastSimulationManager::GetFastSimulationModel(const G4String& modelName,
const G4VFastSimulationModel* previousFound,
bool &foundPrevious) const
{
G4VFastSimulationModel* model = 0;
for (size_t iModel=0; iModel<ModelList.size(); iModel++)
{
if(ModelList[iModel]->GetName() == modelName)
{
if (previousFound == 0)
{
model = ModelList[iModel];
break;
}
else
{
if (ModelList[iModel] == previousFound)
{
foundPrevious = true;
continue;
}
if (foundPrevious)
{
model = ModelList[iModel];
break;
}
}
}
}
return model;
}
//----------------------------------------
// 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.push_back (trans3d);
G4GlobalFastSimulationManager::GetGlobalFastSimulationManager()->
FastSimulationNeedsToBeClosed();
return trans3d;
}
G4bool
G4FastSimulationManager::RemoveGhostPlacement(const G4Transform3D *trans3d)
{
G4bool found;
if((found=(GhostPlacements.remove(trans3d) != 0)))
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)
{
size_t 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.size()==0) return false;
for (iModel=0; iModel<ModelList.size(); iModel++)
if(ModelList[iModel]->IsApplicable(*(track.GetDefinition())))
fApplicableModelList.push_back (ModelList[iModel]);
}
// If Applicable Model List is empty, do nothing !
if(fApplicableModelList.size()==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.size(); 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;
}
G4VParticleChange* G4FastSimulationManager::InvokePostStepDoIt()
{
// const G4FastTrack& parFastTrack=fFastTrack;
fTriggedFastSimulationModel->DoIt(fFastTrack,fFastStep);
return &fFastStep;
}
// -------------------------------------------------------------
// -- Mostly the same as above, in the case of AtRest particles:
// -------------------------------------------------------------
G4bool
G4FastSimulationManager::AtRestGetFastSimulationManagerTrigger(const G4Track& track,
const G4Navigator* theNavigator)
{
size_t 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.size()==0) return false;
for (iModel=0; iModel<ModelList.size(); iModel++)
if(ModelList[iModel]->IsApplicable(*(track.GetDefinition())))
fApplicableModelList.push_back (ModelList[iModel]);
}
// If Applicable Model List is empty, do nothing !
if(fApplicableModelList.size()==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.size(); iModel++)
if(fApplicableModelList[iModel]->AtRestModelTrigger(fFastTrack))
{
fFastStep.Initialize(fFastTrack);
fTriggedFastSimulationModel=fApplicableModelList[iModel];
return true;
}
//--------------------------------------------
// Nobody asks to gain control, returns false
//--------------------------------------------
return false;
}
G4VParticleChange* G4FastSimulationManager::InvokeAtRestDoIt()
{
fTriggedFastSimulationModel->AtRestDoIt(fFastTrack,fFastStep);
return &fFastStep;
}
G4bool
G4FastSimulationManager::
InsertGhostHereIfNecessary(G4VPhysicalVolume* theClone,
const G4ParticleDefinition& theParticle)
{
G4PVPlacement *GhostPhysical;
// Not to do if there aren't glost placements
if(GhostPlacements.size()==0) return false;
// If there are, verifies if at least one model is applicable
// for theParticle.
for (size_t iModel=0; iModel<ModelList.size(); iModel++)
if(ModelList[iModel]->IsApplicable(theParticle)) {
// Ok, we find one. Place the ghost(s).
for (size_t ighost=0; ighost<GhostPlacements.size(); 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.size()!=0) G4cout << " (ghost)";
}
void
G4FastSimulationManager::ListModels() const
{
size_t iModel;
G4cout << "Current Models for the ";
ListTitle();
G4cout << " Envelope:\n";
for (iModel=0; iModel<ModelList.size(); iModel++)
G4cout << " " << ModelList[iModel]->GetName() << "\n";
for (iModel=0; iModel<fInactivatedModels.size(); iModel++)
G4cout << " " << fInactivatedModels[iModel]->GetName()
<< "(inactivated)\n";
}
void
G4FastSimulationManager::ListModels(const G4String& aName) const
{
size_t iModel;
G4int titled = 0;
G4ParticleTable* theParticleTable=
G4ParticleTable::GetParticleTable();
// Active Models
for (iModel=0; iModel<ModelList.size(); 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 <<G4endl;
}
// Inactive Models
for (iModel=0; iModel<fInactivatedModels.size(); 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 <<G4endl;
}
}
void
G4FastSimulationManager::ListModels(const G4ParticleDefinition* aPD) const
{
size_t iModel;
G4bool unique=true;
// Active Models
for (iModel=0; iModel<ModelList.size(); iModel++)
if(ModelList[iModel]->IsApplicable(*aPD)) {
G4cout << "Envelope ";
ListTitle();
G4cout << ", Model "
<< ModelList[iModel]->GetName()
<< "." << G4endl;
}
// inactive Models
for (iModel=0; iModel<fInactivatedModels.size(); iModel++)
if(fInactivatedModels[iModel]->IsApplicable(*aPD)) {
G4cout << "Envelope ";
ListTitle();
G4cout << ", Model "
<< fInactivatedModels[iModel]->GetName()
<< " (inactivated)." << G4endl;
}
if(!unique)
G4cout << "\a\n >>>>>>Warning: two or more Models for the same "
<< "particle type attached to the same envelope!"
<< G4endl;
unique=false;
}