205 lines
6.9 KiB
C++
205 lines
6.9 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.5 2002/05/31 08:07:06 dressel Exp $
|
|
// GEANT4 tag $Name: geant4-04-01 $
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
// GEANT 4 class source file
|
|
//
|
|
// G4ParallelNavigator.cc
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
|
|
#include "g4std/strstream"
|
|
|
|
#include "G4ParallelNavigator.hh"
|
|
|
|
#include "G4VTouchable.hh"
|
|
#include "G4Navigator.hh"
|
|
#include "G4PTouchableKey.hh"
|
|
#include "G4VParallelStepper.hh"
|
|
|
|
G4ParallelNavigator::G4ParallelNavigator(G4VPhysicalVolume &aWorldVolume)
|
|
: fNavigator(*(new G4Navigator)), fNlocated(0)
|
|
{
|
|
fNavigator.SetWorldVolume(&aWorldVolume);
|
|
fCurrentTouchable = fNavigator.CreateTouchableHistory();
|
|
}
|
|
|
|
G4ParallelNavigator::~G4ParallelNavigator()
|
|
{
|
|
delete fCurrentTouchable;
|
|
delete &fNavigator;
|
|
}
|
|
|
|
// public functions
|
|
|
|
G4PTouchableKey G4ParallelNavigator::
|
|
LocateOnBoundary(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
Locate(aPosition, aDirection, true);
|
|
// since the track crosses a boundary ipdate stepper
|
|
return GetCurrentTouchableKey();
|
|
}
|
|
|
|
G4double G4ParallelNavigator::
|
|
ComputeStepLengthInit(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
G4double newSafety;
|
|
G4double stepLength;
|
|
|
|
// initialization
|
|
fNlocated = 0;
|
|
|
|
// first try
|
|
Locate(aPosition, aDirection, false);
|
|
stepLength = fNavigator.ComputeStep( aPosition, aDirection,
|
|
kInfinity, newSafety);
|
|
if (stepLength<=0.0) {
|
|
// second try with schifted position
|
|
stepLength = ComputeStepLengthShifted("ComputeStepLengthInit",
|
|
aPosition, aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
G4double G4ParallelNavigator::
|
|
ComputeStepLengthCrossBoundary(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
if (fNlocated == 0 ) {
|
|
Error("ComputeStepLengthCrossBoundary: no location done before call",
|
|
aPosition, aDirection);
|
|
}
|
|
|
|
// if the track is on boundary the location was done
|
|
// in the DOIT of the ImportanceSplitExaminer
|
|
|
|
G4double newSafety;
|
|
G4double stepLength = fNavigator.ComputeStep( aPosition, aDirection,
|
|
kInfinity, newSafety);
|
|
if (stepLength<=0.) {
|
|
// second try with schifted position
|
|
G4cout << "Warning: G4ParallelNavigator::ComputeStepLengthCrossBoundary: "
|
|
<< G4endl;
|
|
G4cout << "stepLength<=0." << ", pos = " << aPosition
|
|
<< ", dir = " << aDirection << G4endl;
|
|
G4cout << "try ComputeStepLengthShifted" << G4endl;
|
|
stepLength = ComputeStepLengthShifted("ComputeStepLengthCrossBoundary",
|
|
aPosition, aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
G4double G4ParallelNavigator::
|
|
ComputeStepLengthInVolume(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
if (fNlocated == 0 ) {
|
|
Error("ComputeStepLengthInVolume, no location done before call",
|
|
aPosition, aDirection);
|
|
}
|
|
|
|
// 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);
|
|
G4double newSafety;
|
|
G4double stepLength = fNavigator.ComputeStep( aPosition, aDirection,
|
|
kInfinity, newSafety);
|
|
if (stepLength<=0.) {
|
|
// second try with schifted position
|
|
G4cout << "Warning: G4ParallelNavigator::ComputeStepLengthInVolume: "
|
|
<< G4endl;
|
|
G4cout << "stepLength<=0." << ", pos = " << aPosition
|
|
<< ", dir = " << aDirection << G4endl;
|
|
G4cout << "try ComputeStepLengthShifted" << G4endl;
|
|
stepLength = ComputeStepLengthShifted("ComputeStepLengthInVolume",
|
|
aPosition, aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
// private functions
|
|
|
|
void G4ParallelNavigator::Locate(const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection,
|
|
G4bool histsearch)
|
|
{
|
|
fNavigator.SetGeometricallyLimitedStep();
|
|
fNavigator.
|
|
LocateGlobalPointAndUpdateTouchable( aPosition, aDirection,
|
|
fCurrentTouchable, histsearch);
|
|
fNlocated++;
|
|
|
|
return;
|
|
}
|
|
|
|
G4double
|
|
G4ParallelNavigator::ComputeStepLengthShifted(const G4String &m,
|
|
const G4ThreeVector &aPosition,
|
|
const G4ThreeVector &aDirection)
|
|
{
|
|
G4ThreeVector shift_pos(aPosition);
|
|
shift_pos+=G4ThreeVector(Shift(aDirection.x()),
|
|
Shift(aDirection.y()),
|
|
Shift(aDirection.z()));
|
|
Locate(shift_pos, aDirection, false);
|
|
G4double newSafety;
|
|
G4double stepLength = fNavigator.ComputeStep( shift_pos, aDirection,
|
|
kInfinity, newSafety);
|
|
if (stepLength<=0.0) {
|
|
G4std::ostrstream os;
|
|
os << "ComputeStepLengthShifted: called by " << m << "\n";
|
|
os << "shifted positio in second try: " << shift_pos << '\0' << G4endl;
|
|
Error(os.str() , aPosition, aDirection);
|
|
}
|
|
return stepLength;
|
|
}
|
|
|
|
G4PTouchableKey G4ParallelNavigator::GetCurrentTouchableKey() const
|
|
{
|
|
return G4PTouchableKey(*fCurrentTouchable->GetVolume(),
|
|
fCurrentTouchable->GetReplicaNumber());
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (d>0) return 2 * kCarTolerance;
|
|
if (d<0) return -2 * kCarTolerance;
|
|
return 0.;
|
|
}
|