196 lines
5.0 KiB
C++
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;
|
|
}
|