Files
geant4/source/geometry/biasing/src/G4ParallelNavigator.cc
T
2016-06-08 16:57:27 +02:00

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;
}