280 lines
8.5 KiB
C++
280 lines
8.5 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: G4ParallelNavigator.cc,v 1.14 2002/11/04 10:43:07 dressel Exp $
|
|
// GEANT4 tag $Name: geant4-05-00 $
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
// GEANT 4 class source file
|
|
//
|
|
// G4ParallelNavigator.cc
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
|
|
#include "G4ParallelNavigator.hh"
|
|
|
|
#include "g4std/strstream"
|
|
#include "G4VParallelStepper.hh"
|
|
|
|
|
|
G4ParallelNavigator::G4ParallelNavigator(G4VPhysicalVolume &aWorldVolume)
|
|
:
|
|
fNlocated(0),
|
|
fMaxShiftedTrys(10),
|
|
fCurrentTouchableH((fNavigator.SetWorldVolume(&aWorldVolume),
|
|
fNavigator.CreateTouchableHistory())),
|
|
fVerbose(1)
|
|
{}
|
|
|
|
G4ParallelNavigator::~G4ParallelNavigator()
|
|
{
|
|
}
|
|
|
|
// public functions
|
|
|
|
G4GeometryCell G4ParallelNavigator::
|
|
LocateOnBoundary(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{/*
|
|
fNavigator->SetGeometricallyLimitedStep();
|
|
fNavigator->
|
|
LocateGlobalPointAndUpdateTouchableHandle( aPosition,
|
|
aDirection,
|
|
fCurrentTouchableH,
|
|
true);
|
|
fNlocated++;
|
|
*/
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "LOB: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
fNavigator.SetGeometricallyLimitedStep();
|
|
Locate(aPosition, aDirection, true, false);
|
|
// since the track crosses a boundary ipdate stepper
|
|
G4GeometryCell g= GetCurrentGeometryCell();
|
|
return g;
|
|
}
|
|
|
|
G4double G4ParallelNavigator::
|
|
ComputeStepLengthInit(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
// initialization
|
|
fNlocated = 0;
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "CSInit: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
Locate(aPosition, aDirection, false, false);
|
|
return GetStepLength("ComputeStepLengthInit",
|
|
aPosition, aDirection);
|
|
}
|
|
|
|
G4double G4ParallelNavigator::
|
|
ComputeStepLengthCrossBoundary(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
if (fNlocated == 0 ) {
|
|
Error("ComputeStepLengthCrossBoundary: no location done before call",
|
|
aPosition, aDirection);
|
|
}
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "CSCB: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
// if the track is on boundary the LocateOnBoundary was called
|
|
// in the DOIT of the ParalleTransport
|
|
|
|
// but location in volume overcomes a problem with spheres
|
|
// fNavigator->LocateGlobalPointWithinVolume(aPosition);
|
|
return GetStepLength("ComputeStepLengthCrossBoundary",
|
|
aPosition, aDirection);
|
|
}
|
|
|
|
|
|
G4double G4ParallelNavigator::
|
|
ComputeStepLengthInVolume(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
if (fNlocated == 0 ) {
|
|
Error("ComputeStepLengthInVolume, no location done before call",
|
|
aPosition, aDirection);
|
|
}
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "CSinV: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
// if the track is not on the boundary and it's
|
|
// not the first step, the location must be inside the
|
|
// volume
|
|
|
|
fNavigator.LocateGlobalPointWithinVolume(aPosition);
|
|
// Locate(aPosition, aDirection, true); // reduces stepLength<=0. calls
|
|
return GetStepLengthUseLocate("ComputeStepLengthInVolume",
|
|
aPosition, aDirection);
|
|
}
|
|
|
|
// private functions
|
|
|
|
void G4ParallelNavigator::Locate(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection,
|
|
G4bool historysearch,
|
|
G4bool useDirection)
|
|
{
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "Locate: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
fNavigator.LocateGlobalPointAndSetup( aPosition,
|
|
&aDirection,
|
|
historysearch,
|
|
!useDirection);
|
|
fCurrentTouchableH = fNavigator.CreateTouchableHistory();
|
|
|
|
fNlocated++;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
G4double G4ParallelNavigator::
|
|
GetStepLength(const G4String &methodname,
|
|
const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection) {
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "GetSL: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
G4double newSafety = 0.;
|
|
G4double stepLength = fNavigator.ComputeStep( aPosition,
|
|
aDirection,
|
|
kInfinity,
|
|
newSafety);
|
|
// if stepLength = 0 try shifting
|
|
if (stepLength<=2*kCarTolerance) {
|
|
stepLength =
|
|
ComputeStepLengthShifted(methodname,
|
|
aPosition, aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
G4double G4ParallelNavigator::
|
|
GetStepLengthUseLocate(const G4String &methodname,
|
|
const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection) {
|
|
if (fVerbose>=2) {
|
|
G4cout.precision(12);
|
|
G4cout << "GetSLuseLocate: " << aPosition << ", " << aDirection << G4endl;
|
|
}
|
|
G4double newSafety = 0;
|
|
G4double stepLength = fNavigator.ComputeStep( aPosition, aDirection,
|
|
kInfinity, newSafety);
|
|
// if stepLength = 0 try locate
|
|
if (stepLength<=2*kCarTolerance) {
|
|
Locate(aPosition, aDirection, true, true);
|
|
stepLength = GetStepLength(methodname +
|
|
"form GetStepLengthUseLocate",
|
|
aPosition,
|
|
aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
|
|
G4double
|
|
G4ParallelNavigator::
|
|
ComputeStepLengthShifted(const G4String &m,
|
|
const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
if (fVerbose>=1) {
|
|
G4cout.precision(12);
|
|
G4cout << "G4ParallelNavigator::ComputeStepLengthShifted: invoked by: "
|
|
<< m << G4endl;
|
|
}
|
|
G4ThreeVector shift_pos(aPosition);
|
|
shift_pos+=G4ThreeVector(Shift(aDirection.x()),
|
|
Shift(aDirection.y()),
|
|
Shift(aDirection.z()));
|
|
G4double stepLength = 0.;
|
|
G4int trys = 0;
|
|
while (stepLength<=2*kCarTolerance && trys < fMaxShiftedTrys) {
|
|
if (fVerbose>=1) {
|
|
G4cout << "G4ParallelNavigator::ComputeStepLengthShifted: trys = "
|
|
<< ++trys << G4endl;
|
|
G4cout << "shifted position: " << shift_pos
|
|
<< ", direction: " << aDirection << G4endl;
|
|
}
|
|
Locate(shift_pos, aDirection, true, true); // to get into the correct volume
|
|
G4double newSafety = 0;
|
|
fNavigator.LocateGlobalPointWithinVolume(aPosition); // to place at the correct position
|
|
stepLength = fNavigator.ComputeStep( aPosition, aDirection,
|
|
kInfinity, newSafety);
|
|
}
|
|
if (stepLength<=kCarTolerance) {
|
|
char st[200];
|
|
G4std::ostrstream os(st,200);
|
|
os << "still got stepLength<=kCarTolerance: "
|
|
<< shift_pos
|
|
<< "\n"
|
|
<< '\0';
|
|
G4String m(st);
|
|
Error(m, aPosition, aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
G4GeometryCell G4ParallelNavigator::GetCurrentGeometryCell() const
|
|
{
|
|
return G4GeometryCell(*fCurrentTouchableH->GetVolume(),
|
|
fCurrentTouchableH->GetReplicaNumber());
|
|
}
|
|
|
|
|
|
void G4ParallelNavigator::SetVerboseity(G4int v) {
|
|
fVerbose = v;
|
|
}
|
|
|
|
void G4ParallelNavigator::Error(const G4String &m,
|
|
const G4ThreeVector &pos,
|
|
const G4ThreeVector &dir)
|
|
{
|
|
G4cout << "ERROR - G4ParallelNavigator::" << m << G4endl;
|
|
G4cout << "aPosition: " << pos << G4endl;
|
|
G4cout << "dir: " << dir << G4endl;
|
|
G4Exception("Program aborted.");
|
|
}
|
|
|
|
G4double G4ParallelNavigator::Shift(G4double d)
|
|
{
|
|
G4double s=0;
|
|
if (d>0){
|
|
s = 2 * kCarTolerance;
|
|
}
|
|
else if (d<0) {
|
|
s = -2 * kCarTolerance;
|
|
}
|
|
return s;
|
|
}
|