Files
geant4/source/geometry/volumes/src/G4NormalNavigation.cc
T
2016-06-08 15:28:20 +02:00

196 lines
5.0 KiB
C++

// 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: G4NormalNavigation.cc,v 1.1.10.1 1999/12/07 20:48:43 gunter Exp $
// GEANT4 tag $Name: geant4-01-00 $
//
//
// class G4NormalNavigation Implementation
//
#include "G4NormalNavigation.hh"
G4double G4NormalNavigation::ComputeStep(const G4ThreeVector &localPoint,
const G4ThreeVector &localDirection,
const G4double currentProposedStepLength,
G4double &newSafety,
G4NavigationHistory &history,
G4bool &validExitNormal,
G4ThreeVector &exitNormal,
G4bool &exiting,
G4bool &entering,
G4VPhysicalVolume *(*pBlockedPhysical),
G4int &blockedReplicaNo)
{
G4VPhysicalVolume *motherPhysical,*samplePhysical,*blockedExitedVol=0;
G4LogicalVolume *motherLogical;
G4VSolid *motherSolid;
G4ThreeVector sampleDirection;
G4double ourStep=currentProposedStepLength,motherSafety,ourSafety;
G4int localNoDaughters,sampleNo;
motherPhysical=history.GetTopVolume();
motherLogical=motherPhysical->GetLogicalVolume();
motherSolid=motherLogical->GetSolid();
//
// Compute mother safety
//
motherSafety=motherSolid->DistanceToOut(localPoint);
ourSafety=motherSafety; // Working isotropic safety
//
// Compute daughter safeties & intersections
//
// Exiting normal optimisation
if (exiting&&validExitNormal)
{
if (localDirection.dot(exitNormal)>=kMinExitingNormalCosine)
{
// Block exited daughter volume
blockedExitedVol=*pBlockedPhysical;
ourSafety=0;
}
}
exiting=false;
entering=false;
localNoDaughters=motherLogical->GetNoDaughters();
for (sampleNo=localNoDaughters-1;sampleNo>=0;sampleNo--)
{
samplePhysical=motherLogical->GetDaughter(sampleNo);
if (samplePhysical!=blockedExitedVol)
{
samplePhysical->Setup(motherPhysical);
G4AffineTransform sampleTf(samplePhysical->GetRotation(),
samplePhysical->GetTranslation());
sampleTf.Invert();
const G4ThreeVector samplePoint=sampleTf.TransformPoint(localPoint);
const G4VSolid *sampleSolid=samplePhysical
->GetLogicalVolume()
->GetSolid();
const G4double sampleSafety=sampleSolid
->DistanceToIn(samplePoint);
if (sampleSafety<ourSafety)
{
ourSafety=sampleSafety;
}
if (sampleSafety<=ourStep)
{
sampleDirection=sampleTf.TransformAxis(localDirection);
const G4double sampleStep=sampleSolid
->DistanceToIn(samplePoint,
sampleDirection);
if (sampleStep<=ourStep)
{
ourStep=sampleStep;
entering=true;
exiting=false;
*pBlockedPhysical=samplePhysical;
blockedReplicaNo=-1;
}
}
}
}
if (currentProposedStepLength<ourSafety)
{
//
// Guaranteed physics limited
//
entering=false;
exiting=false;
*pBlockedPhysical=0;
ourStep=kInfinity;
}
else
{
//
// Compute mother intersection if required
//
if (motherSafety<=ourStep)
{
G4double motherStep=motherSolid
->DistanceToOut(localPoint,
localDirection,
true,
&validExitNormal,
&exitNormal);
if (motherStep<=ourStep)
{
ourStep=motherStep;
exiting=true;
entering=false;
if (validExitNormal)
{
const G4RotationMatrix *rot=motherPhysical->GetRotation();
if (rot)
{
exitNormal*=rot->inverse();
}
}
}
else
{
validExitNormal=false;
}
}
}
newSafety=ourSafety;
return ourStep;
}
G4double G4NormalNavigation::ComputeSafety(const G4ThreeVector &localPoint,
const G4NavigationHistory &history,
const G4double currentProposedStepLength)
{
G4VPhysicalVolume *motherPhysical,*samplePhysical;
G4LogicalVolume *motherLogical;
G4VSolid *motherSolid;
G4double ourStep=currentProposedStepLength,motherSafety,ourSafety;
G4int localNoDaughters,sampleNo;
motherPhysical=history.GetTopVolume();
motherLogical=motherPhysical->GetLogicalVolume();
motherSolid=motherLogical->GetSolid();
//
// Compute mother safety
//
motherSafety=motherSolid->DistanceToOut(localPoint);
ourSafety=motherSafety; // Working isotropic safety
//
// Compute daughter safeties
//
localNoDaughters=motherLogical->GetNoDaughters();
for (sampleNo=localNoDaughters-1;sampleNo>=0;sampleNo--)
{
samplePhysical=motherLogical->GetDaughter(sampleNo);
samplePhysical->Setup(motherPhysical);
G4AffineTransform sampleTf(samplePhysical->GetRotation(),
samplePhysical->GetTranslation());
sampleTf.Invert();
const G4ThreeVector samplePoint=sampleTf.TransformPoint(localPoint);
const G4VSolid *sampleSolid=samplePhysical
->GetLogicalVolume()
->GetSolid();
const G4double sampleSafety=sampleSolid
->DistanceToIn(samplePoint);
if (sampleSafety<ourSafety)
{
ourSafety=sampleSafety;
}
}
return ourSafety;
}