Import Geant4 0.1.0 source tree
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4CashKarpRKF45.cc,v 2.7 1998/11/19 20:57:05 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4CashKarpRKF45.cc,v 1.3 1999/03/04 13:52:31 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
// The Cash-Karp Runge-Kutta-Fehlberg 4/5 method is an embedded fourth
|
||||
// order method (giving fifth-order accuracy) for the solution
|
||||
@@ -25,7 +25,7 @@
|
||||
// Constructor
|
||||
|
||||
G4CashKarpRKF45::G4CashKarpRKF45(G4Mag_EqRhs *EqRhs, G4int numberOfVariables):
|
||||
G4MagIntegratorStepper(EqRhs)
|
||||
G4MagIntegratorStepper(EqRhs, numberOfVariables)
|
||||
{
|
||||
fNumberOfVariables = numberOfVariables ;
|
||||
|
||||
@@ -44,14 +44,14 @@ G4MagIntegratorStepper(EqRhs)
|
||||
|
||||
G4CashKarpRKF45::~G4CashKarpRKF45()
|
||||
{
|
||||
delete ak2;
|
||||
delete ak3;
|
||||
delete ak4;
|
||||
delete ak5;
|
||||
delete ak6;
|
||||
delete ak7;
|
||||
delete yTemp;
|
||||
delete yIn;
|
||||
delete[] ak2;
|
||||
delete[] ak3;
|
||||
delete[] ak4;
|
||||
delete[] ak5;
|
||||
delete[] ak6;
|
||||
delete[] ak7;
|
||||
delete[] yTemp;
|
||||
delete[] yIn;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ChordFinder.cc,v 2.6 1998/11/13 14:30:21 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4ChordFinder.cc,v 1.6 1999/07/12 09:36:17 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
// 25.02.97 John Apostolakis, desigh and implimentation
|
||||
// 05.03.97 V. Grichine , makeup to G4 'standard'
|
||||
// 25.02.97 John Apostolakis, design and implimentation
|
||||
// 05.03.97 V. Grichine , style modification
|
||||
|
||||
#include "G4ChordFinder.hh"
|
||||
#include "G4MagIntegratorDriver.hh"
|
||||
@@ -48,8 +48,9 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
|
||||
{
|
||||
fAllocatedStepper= false;
|
||||
}
|
||||
fIntgrDriver = new G4MagInt_Driver(stepMinimum, pItsStepper);
|
||||
|
||||
fIntgrDriver = new G4MagInt_Driver(stepMinimum,
|
||||
pItsStepper,
|
||||
pItsStepper->GetNumberOfVariables() );
|
||||
}
|
||||
|
||||
// ......................................................................
|
||||
@@ -145,7 +146,8 @@ G4ChordFinder::FindNextChord( const G4FieldTrack yStart,
|
||||
#endif
|
||||
|
||||
// We check whether the criterion is met here.
|
||||
validEndPoint = AcceptableMissDist(dChordStep);
|
||||
validEndPoint = AcceptableMissDist(dChordStep);
|
||||
// && (dyErr < eps) ;
|
||||
|
||||
if( ! validEndPoint ) {
|
||||
// This is needed to decide new step size until QuickAdvance does it
|
||||
@@ -198,12 +200,6 @@ G4double G4ChordFinder::NewStep(
|
||||
return stepTrial;
|
||||
}
|
||||
|
||||
//
|
||||
// G4FieldTrack G4NewMagTr::ApproxCurvePointV(
|
||||
// const G4FieldTrack& CurveA_PointVelocity,
|
||||
// const G4FieldTrack& CurveB_PointVelocity,
|
||||
// const G4ThreeVector& CurrentE_Point,
|
||||
// const G4double eps_step)
|
||||
//
|
||||
// Given a starting curve point A (CurveA_PointVelocity), a later
|
||||
// curve point B (CurveB_PointVelocity) and a point E which is (generally)
|
||||
@@ -235,34 +231,57 @@ G4FieldTrack G4ChordFinder::ApproxCurvePointV(
|
||||
|
||||
curve_length=
|
||||
CurveB_PointVelocity.CurveS() - CurveA_PointVelocity.CurveS();
|
||||
#ifdef DEBUG
|
||||
const G4double per_million=1e-6;
|
||||
if( ABdist * > curve_length * (1. + per_million ) ){
|
||||
G4cerr << " Error in ApproxCurvePoint \n" <<
|
||||
|
||||
// const
|
||||
G4double integrationInaccuracyLimit= max( perMillion, 0.5*eps_step );
|
||||
if( curve_length < ABdist * (1. - integrationInaccuracyLimit) ){
|
||||
// #ifdef G4DEBUG
|
||||
G4cerr << " Warning in G4ChordFinder::ApproxCurvePoint: " << endl <<
|
||||
" The two points are further apart than the curve length " << endl <<
|
||||
" Dist = " << ABdist <<
|
||||
" curve length = " << curve_length << endl;
|
||||
" curve length = " << curve_length
|
||||
<< " relativeDiff = " << (curve_length-ABdist)/ABdist
|
||||
<< endl;
|
||||
// #endif
|
||||
if( curve_length < ABdist * (1. - 10*eps_step) ) {
|
||||
// #ifdef G4DEBUG
|
||||
G4cerr << " ERROR: the size of the above difference exceeds allowed limits. Aborting."
|
||||
<< endl;
|
||||
// #endif
|
||||
G4Exception("G4ChordFinder::ApproxCurvePoint> Unphysical curve length.");
|
||||
}
|
||||
// Take default corrective action:
|
||||
// --> adjust the maximum curve length.
|
||||
// NOTE: this case only happens for relatively straight paths.
|
||||
curve_length = ABdist;
|
||||
}
|
||||
#endif
|
||||
|
||||
G4double new_st_length;
|
||||
|
||||
if ( ABdist > 0.0 ){
|
||||
AE_fraction = ChordAE_Vector.mag() / ABdist;
|
||||
new_st_length= AE_fraction * curve_length;
|
||||
}else{
|
||||
G4cerr << " Error in ApproxCurvePoint: A and B are the same point\n" <<
|
||||
G4cerr << " Error in G4ChordFinder::ApproxCurvePoint: A and B are the same point\n" <<
|
||||
" Chord AB length = " << ChordAE_Vector.mag() << endl << endl;
|
||||
AE_fraction = 0.5; // Guess .. ?;
|
||||
new_st_length= AE_fraction * curve_length; // Is this correct ??
|
||||
}
|
||||
|
||||
if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) ){
|
||||
G4cerr << " Error in ApproxCurvePoint: AE > AB or AE/AB <= 0 " << endl <<
|
||||
G4cerr << " G4ChordFinder::ApproxCurvePointV: Warning: Anomalous condition:AE > AB or AE/AB <= 0 " << endl <<
|
||||
" AE_fraction = " << AE_fraction << endl <<
|
||||
" Chord AE length = " << ChordAE_Vector.mag() << endl <<
|
||||
" Chord AB length = " << ABdist << endl << endl;
|
||||
G4cerr << " OK if this condition occurs after a recalculation of 'B'" << endl
|
||||
<< " Otherwise it is an error. " << endl ;
|
||||
// This course can now result if B has been re-evaluated,
|
||||
// without E being recomputed (1 July 99)
|
||||
// In this case this is not a "real error" - but it undesired
|
||||
// and we cope with it by a default corrective action ...
|
||||
AE_fraction = 0.5; // Default value
|
||||
}
|
||||
|
||||
new_st_length= AE_fraction * curve_length;
|
||||
|
||||
if ( AE_fraction > 0.0 ) {
|
||||
G4bool good_advance =
|
||||
fIntgrDriver->AccurateAdvance(Current_PointVelocity,
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ClassicalRK4.cc,v 2.8 1998/11/17 18:20:10 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4ClassicalRK4.cc,v 1.1 1999/01/07 16:07:08 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4ClassicalRK4.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4EquationOfMotion.cc,v 2.3 1998/11/12 19:48:23 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4EquationOfMotion.cc,v 1.1 1999/01/07 16:07:08 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4EquationOfMotion.hh"
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ExplicitEuler.cc,v 2.6 1998/11/12 16:16:10 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4ExplicitEuler.cc,v 1.1 1999/01/07 16:07:08 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
// Explicit Euler: x_1 = x_0 + h * dx_0
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4FieldManager.cc,v 2.1 1998/07/12 02:55:15 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4FieldManager.cc,v 1.1 1999/01/07 16:07:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4FieldManager.hh"
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4FieldTrack.cc,v 2.3 1998/11/11 10:46:50 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4FieldTrack.cc,v 1.1 1999/01/07 16:07:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4HelixExplicitEuler.cc,v 2.3 1998/11/13 14:30:21 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4HelixExplicitEuler.cc,v 1.1 1999/01/07 16:07:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4HelixExplicitEuler.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4HelixHeum.cc,v 2.3 1998/11/10 18:17:14 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4HelixHeum.cc,v 1.1 1999/01/07 16:07:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4HelixHeum.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4HelixImplicitEuler.cc,v 2.2 1998/11/10 18:17:14 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4HelixImplicitEuler.cc,v 1.1 1999/01/07 16:07:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4HelixImplicitEuler.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4HelixSimpleRunge.cc,v 2.3 1998/11/13 14:30:22 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4HelixSimpleRunge.cc,v 1.1 1999/01/07 16:07:09 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4HelixSimpleRunge.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ImplicitEuler.cc,v 2.6 1998/11/12 16:16:10 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4ImplicitEuler.cc,v 1.1 1999/01/07 16:07:10 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
// Implicit Euler:
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4LineSection.cc,v 2.1 1998/07/12 02:55:20 urbi Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4LineSection.cc,v 1.1 1999/01/07 16:07:10 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
// typedef double G4double;
|
||||
#include "G4LineSection.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4MagErrorStepper.cc,v 2.3 1998/11/12 16:17:33 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4MagErrorStepper.cc,v 1.5 1999/04/19 17:20:30 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4MagErrorStepper.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
@@ -16,45 +16,42 @@ void
|
||||
G4MagErrorStepper::Stepper( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
G4double yOut[],
|
||||
G4double yErr[] )
|
||||
G4double yOutput[],
|
||||
G4double yError [] )
|
||||
{
|
||||
const G4int nvar = 6 ;
|
||||
const G4int nvar = this->GetNumberOfVariables() ;
|
||||
|
||||
G4int i;
|
||||
// correction for Richardson Extrapolation.
|
||||
G4double correction = 1. / ( (1 << IntegratorOrder()) -1 );
|
||||
|
||||
G4double yTemp[7], dydxTemp[6], yIn[7] ;
|
||||
// Saving yInput because yInput and yOutput can be aliases for same array
|
||||
|
||||
// Saving yInput because yInput and yOut can be aliases for same array
|
||||
for(i=0;i<nvar;i++) yInitial[i]=yInput[i];
|
||||
|
||||
for(i=0;i<nvar;i++) yIn[i]=yInput[i];
|
||||
|
||||
G4double h = hstep * 0.5;
|
||||
G4double halfStep = hstep * 0.5;
|
||||
|
||||
// Do two half steps
|
||||
|
||||
DumbStepper(yIn,dydx,h,yTemp);
|
||||
RightHandSide(yTemp,dydxTemp) ;
|
||||
DumbStepper(yTemp,dydxTemp,h,yOut);
|
||||
DumbStepper (yInitial, dydx, halfStep, yMiddle);
|
||||
RightHandSide(yMiddle, dydxMid);
|
||||
DumbStepper (yMiddle, dydxMid, halfStep, yOutput);
|
||||
|
||||
// Store midpoint, chord calculation
|
||||
|
||||
yMidPoint = G4ThreeVector( yTemp[0], yTemp[1], yTemp[2]);
|
||||
fMidPoint = G4ThreeVector( yMiddle[0], yMiddle[1], yMiddle[2]);
|
||||
|
||||
// Do a full Step
|
||||
h = hstep ;
|
||||
DumbStepper(yIn,dydx,h,yTemp);
|
||||
DumbStepper(yInitial, dydx, hstep, yOneStep);
|
||||
for(i=0;i<nvar;i++) {
|
||||
yErr[i] = yOut[i] - yTemp[i] ;
|
||||
yOut[i] += yErr[i]*correction ; // Provides by 1 increased
|
||||
// order of accuracy
|
||||
// Richardson Extrapolation
|
||||
yError [i] = yOutput[i] - yOneStep[i] ;
|
||||
yOutput[i] += yError[i]*correction ; // Provides accuracy increased
|
||||
// by 1 order via the
|
||||
// Richardson Extrapolation
|
||||
}
|
||||
|
||||
yInitial = G4ThreeVector( yIn[0], yIn[1], yIn[2]);
|
||||
yFinal = G4ThreeVector( yOut[0], yOut[1], yOut[2]);
|
||||
fInitialPoint = G4ThreeVector( yInitial[0], yInitial[1], yInitial[2]);
|
||||
fFinalPoint = G4ThreeVector( yOutput[0], yOutput[1], yOutput[2]);
|
||||
|
||||
return ;
|
||||
}
|
||||
@@ -67,7 +64,7 @@ G4MagErrorStepper::DistChord() const
|
||||
// Soon: must check whether h/R > 2 pi !!
|
||||
// Method below is good only for < 2 pi
|
||||
|
||||
return G4LineSection::Distline( yMidPoint, yInitial, yFinal );
|
||||
return G4LineSection::Distline( fMidPoint, fInitialPoint, fFinalPoint );
|
||||
// This is a class method that gives distance of Mid
|
||||
// from the Chord between the Initial and Final points.
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4MagHelicalStepper.cc,v 2.7 1998/11/13 14:30:23 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4MagHelicalStepper.cc,v 1.2 1999/02/12 12:38:50 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
@@ -19,7 +19,8 @@
|
||||
// current position
|
||||
|
||||
G4MagHelicalStepper::G4MagHelicalStepper(G4Mag_EqRhs *EqRhs)
|
||||
: G4MagIntegratorStepper(EqRhs)
|
||||
: G4MagIntegratorStepper(EqRhs, 6) // integrate over 6 variables only !!
|
||||
// position & velocity
|
||||
{
|
||||
fPtrMagEqOfMot = EqRhs;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4MagIntegratorDriver.cc,v 2.4 1998/11/11 18:51:48 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4MagIntegratorDriver.cc,v 1.4 1999/07/06 20:22:34 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "G4MagIntegratorDriver.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
// #define G4DEBUG 1
|
||||
|
||||
// Stepsize can increase by no more than 5.0
|
||||
// and decrease by no more than 1/10. = 0.1
|
||||
//
|
||||
@@ -51,7 +53,8 @@ G4MagInt_Driver::AccurateAdvance(
|
||||
{
|
||||
static const G4int maxstp = 5000;
|
||||
|
||||
G4int nstp, i ;
|
||||
G4int nstp, i;
|
||||
static G4int dbg=1;
|
||||
G4double x, hnext, hdid, h ;
|
||||
|
||||
// G4double yscal[ncompSVEC];
|
||||
@@ -73,29 +76,79 @@ G4MagInt_Driver::AccurateAdvance(
|
||||
h = hstep;
|
||||
x = x1;
|
||||
|
||||
G4int nOK =0, nBAD = 0 ;
|
||||
G4int noFullIntegr=0, noSmallIntegr = 0 ;
|
||||
static G4int noGoodSteps =0, noBadSteps = 0 ; // Bad = chord > curve-len
|
||||
|
||||
for(i=0;i<nvar;i++) y[i] = ystart[i] ;
|
||||
|
||||
nstp=1;
|
||||
do{
|
||||
#ifdef G4DEBUG
|
||||
G4ThreeVector StartPos( y[0], y[1], y[2] );
|
||||
#endif
|
||||
|
||||
pIntStepper->RightHandSide( y, dydx );
|
||||
|
||||
if( x+h > x2 ) h = x2 - x ; // When stepsize overshoots, decrease it!
|
||||
|
||||
OneGoodStep(y,dydx,x,h,eps,hdid,hnext) ;
|
||||
|
||||
if(hdid == h) nOK++ ; else nBAD++ ;
|
||||
#ifdef G4DEBUG
|
||||
if(hdid == h) noFullIntegr++ ; else noSmallIntegr++ ;
|
||||
G4ThreeVector EndPos( y[0], y[1], y[2] );
|
||||
|
||||
G4double endPointDist= (EndPos-StartPos).mag();
|
||||
if( endPointDist >= h*(1.+perMillion) ){
|
||||
static G4double maxRelError= 0.0;
|
||||
G4bool isNewMax;
|
||||
|
||||
noBadSteps ++;
|
||||
isNewMax = endPointDist > (1.0 + maxRelError) * h;
|
||||
if( isNewMax )
|
||||
maxRelError= endPointDist / h - 1.0;
|
||||
|
||||
if( dbg && ( isNewMax || (endPointDist >= h*(1.+eps) ) ) ){
|
||||
static G4int noWarnings = 0;
|
||||
if( (noWarnings ++ < 10) || (dbg>1) ){
|
||||
G4cerr << " Warning (G4MagIntergratorDriver): "
|
||||
<< " The integration produced an endpoint which " << endl
|
||||
<< " is further from the startpoint than the curve length." << endl;
|
||||
|
||||
G4cerr << " Distance of endpoints = " << endPointDist
|
||||
<< " curve length = " << h
|
||||
<< " Difference (curveLen-endpDist)= " << (h - endPointDist)
|
||||
<< " relative = " << (h-endPointDist) / h
|
||||
<< endl;
|
||||
}else{
|
||||
G4cerr << " EndpointDist = " << endPointDist
|
||||
<< " curve length = " << h
|
||||
<< " Diff (cl-ed)= " << (h - endPointDist)
|
||||
<< " rel = " << (h-endPointDist) / h
|
||||
<< endl;
|
||||
}
|
||||
} else { // ie (!dbg)
|
||||
noGoodSteps ++;
|
||||
} // end if (dbg)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fabs(hnext) <= Hmin())
|
||||
{
|
||||
succeeded = false;
|
||||
// If simply a very small interval is being integrated, ...
|
||||
if( (fabs(hstep) > Hmin()) || (hnext > h) ){
|
||||
// If simply a very small interval is being integrated, do not warn
|
||||
if( (x < x2 * (1-eps) ) && // The last step can be small: it's OK
|
||||
(fabs(hstep) > Hmin()) // and if we are asked, it's OK
|
||||
// && (hnext < hstep * PerThousand )
|
||||
)
|
||||
{
|
||||
G4cerr<< " Warning (G4MagIntergratorDriver): The stepsize for the "
|
||||
" next iteration=" << hnext << " is too small - in Step number "
|
||||
<<nstp << " . Minimum for driver = "<< Hmin() << endl ;
|
||||
<<nstp << "." << endl;
|
||||
G4cerr << " Requested step size was " << hstep << " ." << endl ;
|
||||
G4cerr << " Previous step size was " << h << " ." << endl ;
|
||||
G4cerr << " The minimum for the driver is " << Hmin() << endl ;
|
||||
}
|
||||
// else succeeded = false; // Not meaningful unless it is used to
|
||||
// break out of the loop.
|
||||
}
|
||||
|
||||
h = hnext ;
|
||||
@@ -150,23 +203,35 @@ G4MagInt_Driver::OneGoodStep( G4double y[],
|
||||
// 16.2 Adaptive StepSize Control for Runge-Kutta, p. 719
|
||||
|
||||
{
|
||||
G4double errpos_sq, errvel_sq, errmax_sq;
|
||||
G4double errmax, h, htemp, xnew ;
|
||||
G4int i;
|
||||
const G4double eps_vel_rel= eps; // The same relative error
|
||||
// (eps too is a pure number)
|
||||
|
||||
G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
|
||||
|
||||
h = htry ; // Set stepsize to the initial trial value
|
||||
|
||||
// G4double inv_epspos_sq= 1.0 / eps * eps;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
pIntStepper-> Stepper(y,dydx,h,ytemp,yerr) ;
|
||||
|
||||
pIntStepper-> Stepper(y,dydx,h,ytemp,yerr);
|
||||
G4double eps_pos = eps * h;
|
||||
// Evaluate accuracy
|
||||
//
|
||||
errmax = sqrt( sqr(yerr[0]) + sqr(yerr[1]) + sqr(yerr[2]) );
|
||||
errpos_sq = sqr(yerr[0]) + sqr(yerr[1]) + sqr(yerr[2]) ;
|
||||
errpos_sq /= eps_pos*eps_pos; // Scale relative to required tolerance
|
||||
|
||||
errmax /= eps; // Scale relative to required tolerance
|
||||
if(errmax <= 1.0 ) break ; // Step succeeded.
|
||||
// Accuracy for velocity
|
||||
errvel_sq = (sqr(yerr[3]) + sqr(yerr[4]) + sqr(yerr[5]) )
|
||||
/ (sqr(y[3]) + sqr(y[4]) + sqr(y[5]) );
|
||||
errvel_sq /= eps_vel_rel*eps_vel_rel;
|
||||
|
||||
errmax_sq = max( errpos_sq, errvel_sq ); // Square of maximum error
|
||||
errmax = sqrt( errmax_sq );
|
||||
if(errmax_sq <= 1.0 ) break ; // Step succeeded.
|
||||
|
||||
// Step failed; compute the size of retrial Step.
|
||||
htemp = GetSafety()*h*pow(errmax,GetPshrnk()) ;
|
||||
@@ -205,10 +270,11 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
const G4double dydx[],
|
||||
G4double hstep, // In
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_len )
|
||||
G4double& dyerr )
|
||||
{
|
||||
G4double yerr_vec[G4FieldTrack::ncompSVEC], yarrin[G4FieldTrack::ncompSVEC], yarrout[G4FieldTrack::ncompSVEC];
|
||||
G4double s_start;
|
||||
G4double dyerr_len, dyerr_vel, vel_mag;
|
||||
|
||||
// Move data into array
|
||||
y_posvel.DumpToArray( yarrin ); // yarrin <== y_posvel
|
||||
@@ -227,7 +293,15 @@ G4bool G4MagInt_Driver::QuickAdvance(
|
||||
// A single measure of the error
|
||||
// TO-DO : account for tangent vector, energy, spin, ... ?
|
||||
dyerr_len= sqrt( sqr(yerr_vec[0])+sqr(yerr_vec[1])+sqr(yerr_vec[2]));
|
||||
dyerr_vel= sqrt( sqr(yerr_vec[3])+sqr(yerr_vec[4])+sqr(yerr_vec[5]));
|
||||
vel_mag = sqrt( sqr(yarrout[3])+sqr(yarrout[4])+sqr(yarrout[5]) );
|
||||
|
||||
if( (dyerr_len / hstep) > (dyerr_vel / vel_mag) ) {
|
||||
dyerr = dyerr_len;
|
||||
}else{
|
||||
// Scale it to the position - for now
|
||||
dyerr = (dyerr_vel / vel_mag) * hstep;
|
||||
}
|
||||
#ifdef RETURN_A_NEW_STEP_LENGTH
|
||||
// The following step cannot be done here because "eps" is not known.
|
||||
dyerr_len /= eps;
|
||||
|
||||
@@ -5,19 +5,18 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4MagIntegratorStepper.cc,v 2.0 1998/07/02 16:56:24 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4MagIntegratorStepper.cc,v 1.2 1999/02/12 12:38:18 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
// Constructor for creation of coefficient in Lorentz motion equation
|
||||
// as well as initialisation of geometry constants.
|
||||
// particleCharge is the particle charge in the elementary charge
|
||||
// momentumXc is the particle momentum multiplied by the speed of light in MeV,
|
||||
// Constructor for stepper abstract base class.
|
||||
//
|
||||
|
||||
G4MagIntegratorStepper::G4MagIntegratorStepper(G4Mag_EqRhs *EqRhs)
|
||||
G4MagIntegratorStepper::G4MagIntegratorStepper(G4Mag_EqRhs *EqRhs,
|
||||
G4int num_var)
|
||||
{
|
||||
theEquation_Rhs= EqRhs;
|
||||
fEquation_Rhs= EqRhs;
|
||||
fNumberOfVariables = num_var;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Mag_EqRhs.cc,v 2.3 1998/11/12 16:19:40 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4Mag_EqRhs.cc,v 1.1 1999/01/07 16:07:11 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion
|
||||
// in a pure Magnetic Field .
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
// This version of the right-hand side includes
|
||||
// the three components of the particle's spin.
|
||||
//
|
||||
// J. Apostolakis, February 8th, 1999
|
||||
// P. Gumplinger, February 8th, 1999
|
||||
//
|
||||
#include "G4Mag_SpinEqRhs.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
void
|
||||
G4Mag_SpinEqRhs::SetChargeMomentumMass(const G4double particleCharge, // in e+ units
|
||||
const G4double MomentumXc,
|
||||
const G4double mass)
|
||||
{
|
||||
// To set fCof_val
|
||||
G4Mag_EqRhs::SetChargeMomentumMass(particleCharge, MomentumXc, mass);
|
||||
|
||||
omegac = 0.105658387*GeV/mass * 2.837374841e-3*(rad/cm/kilogauss);
|
||||
anomaly = 1.165923e-3;
|
||||
ParticleCharge = particleCharge;
|
||||
|
||||
// for testing only
|
||||
anomaly = 0.0;
|
||||
}
|
||||
|
||||
void
|
||||
G4Mag_SpinEqRhs::EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const
|
||||
{
|
||||
G4double velocity_mag_square = sqr(y[3]) + sqr(y[4]) + sqr(y[5]);
|
||||
G4double inv_velocity_magnitude = 1.0 / sqrt( velocity_mag_square );
|
||||
|
||||
dydx[0] = y[3] * inv_velocity_magnitude; // (d/ds)x = Vx/V
|
||||
dydx[1] = y[4] * inv_velocity_magnitude; // (d/ds)y = Vy/V
|
||||
dydx[2] = y[5] * inv_velocity_magnitude; // (d/ds)z = Vz/V
|
||||
dydx[3] = FCof()*(y[4]*B[2] - y[5]*B[1]) ; // Ax = a*(Vy*Bz - Vz*By)
|
||||
dydx[4] = FCof()*(y[5]*B[0] - y[3]*B[2]) ; // Ay = a*(Vz*Bx - Vx*Bz)
|
||||
dydx[5] = FCof()*(y[3]*B[1] - y[4]*B[0]) ; // Az = a*(Vx*By - Vy*Bx)
|
||||
|
||||
G4double beta_squared = velocity_mag_square/c_squared;
|
||||
G4double beta = sqrt(beta_squared);
|
||||
|
||||
G4double gamma;
|
||||
|
||||
if (beta < 1.0){
|
||||
gamma = 1. / sqrt( 1. - beta_squared);
|
||||
} else {
|
||||
beta = 1.0;
|
||||
gamma = DBL_MAX;
|
||||
}
|
||||
|
||||
G4ThreeVector u;
|
||||
u.setX(inv_velocity_magnitude*y[3]);
|
||||
u.setY(inv_velocity_magnitude*y[4]);
|
||||
u.setZ(inv_velocity_magnitude*y[5]);
|
||||
|
||||
G4ThreeVector BField(B[0],B[1],B[2]);
|
||||
|
||||
G4double udb = anomaly*beta*gamma/(1.+gamma) * (BField * u);
|
||||
G4double ucb = (anomaly+1./gamma)/beta;
|
||||
|
||||
G4ThreeVector Spin(y[9],y[10],y[11]);
|
||||
|
||||
G4ThreeVector dSpin;
|
||||
|
||||
dSpin = ParticleCharge*omegac*(ucb*(Spin.cross(BField))-udb*(Spin.cross(u)));
|
||||
|
||||
dydx[ 9] = dSpin.x();
|
||||
dydx[10] = dSpin.y();
|
||||
dydx[11] = dSpin.z();
|
||||
|
||||
return ;
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4Mag_UsualEqRhs.cc,v 2.2 1998/11/18 21:11:38 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4Mag_UsualEqRhs.cc,v 1.1 1999/01/07 16:07:11 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
// This is the standard right-hand side for equation of motion.
|
||||
|
||||
@@ -1,567 +0,0 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 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: G4PropagatorInField.cc,v 2.11 1998/11/24 19:17:32 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
//
|
||||
// This routine implements an algorithm to track a particle in a //
|
||||
// non-uniform magnetic field. It utilises an ODE solver (with //
|
||||
// the Runge - Kutta method) to evolve the particle, and drives it //
|
||||
// until the particle has traveled a set distance or it enters a new
|
||||
// volume.
|
||||
//
|
||||
// Caveat: tracking is not exact - volumes can be missed!
|
||||
//
|
||||
//
|
||||
// 14.10.96 John Apostolakis, design and implementation
|
||||
// 17.03.97 John Apostolakis, renaming new set functions being added
|
||||
//
|
||||
|
||||
#include "G4PropagatorInField.hh"
|
||||
#include "G4ios.hh"
|
||||
#include <iomanip.h>
|
||||
|
||||
const G4double G4PropagatorInField::delta_intersection_val= 0.1 * mm;
|
||||
const G4double G4PropagatorInField::delta_one_step_val = 0.25 * mm;
|
||||
|
||||
G4double
|
||||
G4PropagatorInField::
|
||||
ComputeStep(const G4ThreeVector & StartPointA,
|
||||
const G4ThreeVector & Velocity, // Unit or non
|
||||
G4double CurrentProposedStepLength,
|
||||
G4double ¤tSafety, // In/Out
|
||||
G4VPhysicalVolume *pPhysVol )
|
||||
// Compute the next geometric Step for simple magnetic field
|
||||
{
|
||||
G4FieldTrack aFieldTrack =
|
||||
G4FieldTrack( StartPointA,
|
||||
Velocity,
|
||||
0.0, // length of path
|
||||
0.0, // energy
|
||||
0.0, // lab tof
|
||||
0.0, // proper tof
|
||||
0 );
|
||||
|
||||
// Do the Transport in the field (non recti-linear)
|
||||
return this->ComputeStep( aFieldTrack,
|
||||
CurrentProposedStepLength,
|
||||
currentSafety );
|
||||
}
|
||||
|
||||
G4double
|
||||
G4PropagatorInField::
|
||||
ComputeStep(G4FieldTrack& pFieldTrack,
|
||||
G4double CurrentProposedStepLength,
|
||||
G4double& currentSafety, // IN/OUT
|
||||
G4VPhysicalVolume *pPhysVol)
|
||||
|
||||
// Compute the next geometric Step
|
||||
{
|
||||
// Parameters for adaptive Runge-Kutta integration
|
||||
//
|
||||
G4double h_TrialStepSize; // 1st Step Size
|
||||
G4double TruePathLength;
|
||||
G4double StepTaken= 0.0;
|
||||
G4double s_length_taken;
|
||||
G4bool intersects;
|
||||
G4bool first_substep= true;
|
||||
|
||||
G4double NewSafety;
|
||||
fParticleIsLooping= false;
|
||||
|
||||
G4FieldTrack CurrentState(pFieldTrack);
|
||||
|
||||
#if 0
|
||||
CurrentState.SetVelocity( pFieldTrack.GetMomentumDir() );
|
||||
// For now, must utilize unit "velocity" J.A. Nov 17, 98
|
||||
|
||||
// Problem in setting the energy in this case .... (and in E field)
|
||||
#endif
|
||||
|
||||
|
||||
G4FieldTrack OriginalState= CurrentState;
|
||||
|
||||
// If the Step length is "infinite", then an approximate-maximum Step lenght
|
||||
// (used to calculate the relative accuracy) must be guessed.
|
||||
//
|
||||
|
||||
if( CurrentProposedStepLength >= kInfinity ){
|
||||
G4ThreeVector StartPointA, VelocityUnit;
|
||||
StartPointA = pFieldTrack.GetPosition();
|
||||
VelocityUnit= pFieldTrack.GetMomentumDir();
|
||||
CurrentProposedStepLength= 1.e3 * ( 10.0 * cm +
|
||||
fNavigator->GetWorldVolume()->GetLogicalVolume()->
|
||||
GetSolid()->DistanceToOut(StartPointA, VelocityUnit) ) ;
|
||||
}
|
||||
this->SetEpsilonStep( DeltaOneStep() / CurrentProposedStepLength);
|
||||
|
||||
G4int do_loop_count=0;
|
||||
do
|
||||
{
|
||||
do_loop_count++;
|
||||
G4FieldTrack SubStepStartState= CurrentState;
|
||||
G4ThreeVector SubStartPoint= CurrentState.GetPosition();
|
||||
// WAS = G4Navigator::Locate...
|
||||
|
||||
if( !first_substep)
|
||||
{
|
||||
fNavigator->LocateGlobalPointWithinVolume( SubStartPoint );
|
||||
}
|
||||
|
||||
// First figure out how far to evolve the particle !
|
||||
// -------------------------------------------------
|
||||
// and (later) with what accuracy to calculate this path.
|
||||
//
|
||||
h_TrialStepSize= CurrentProposedStepLength - StepTaken ;
|
||||
|
||||
// Next evolve it as far as this allows.
|
||||
// ---------------------------------------
|
||||
//
|
||||
// B <- Integrator - limited by the "chord miss" rule.
|
||||
//
|
||||
|
||||
s_length_taken= GetChordFinder()->AdvanceChordLimited(
|
||||
CurrentState, // Position & velocity
|
||||
h_TrialStepSize,
|
||||
GetEpsilonStep() );
|
||||
|
||||
// On Exit:
|
||||
// CurrentState is updated with the final position and velocity.
|
||||
|
||||
G4ThreeVector EndPointB= CurrentState.Position();
|
||||
|
||||
// Calculate the direction and length of the chord AB
|
||||
|
||||
G4ThreeVector ChordAB_Vector= EndPointB - SubStartPoint;
|
||||
G4double ChordAB_Length= ChordAB_Vector.mag(); // Magnitude (norm)
|
||||
G4ThreeVector ChordAB_Dir= ChordAB_Vector.unit();
|
||||
|
||||
// Check whether any volumes are encountered by the chord AB
|
||||
|
||||
G4double LinearStepLength =
|
||||
fNavigator->ComputeStep( SubStartPoint, ChordAB_Dir,
|
||||
ChordAB_Length, NewSafety);
|
||||
if( first_substep )
|
||||
{
|
||||
currentSafety= NewSafety;
|
||||
}
|
||||
// It might also be possible to update safety in other steps, but
|
||||
// it must be Done with care. J.Apostolakis August 5th, 1997
|
||||
|
||||
intersects= (LinearStepLength <= ChordAB_Length);
|
||||
// G4Navigator contracts to return k_infinity if len==asked
|
||||
// and it did not find a surface boundary at that length
|
||||
LinearStepLength = min( LinearStepLength, ChordAB_Length);
|
||||
|
||||
if( intersects )
|
||||
{
|
||||
// E <- Intersection Point of chord AB and either volume A's surface
|
||||
// or a daughter volume's surface ..
|
||||
|
||||
G4ThreeVector pointE= SubStartPoint + LinearStepLength * ChordAB_Dir;
|
||||
|
||||
G4FieldTrack IntersectPointVelct_G(CurrentState); // FT-Def-Construct
|
||||
|
||||
// Find the intersection point of AB true path with the surface
|
||||
// of vol(A) given our current "estimate" point E.
|
||||
|
||||
G4bool found_intersection=
|
||||
LocateIntersectionPoint( SubStepStartState, CurrentState,
|
||||
pointE, IntersectPointVelct_G );
|
||||
|
||||
if( found_intersection )
|
||||
{
|
||||
// G is our EndPoint ...
|
||||
G4ThreeVector IntersectPoint_G = IntersectPointVelct_G.Position();
|
||||
|
||||
End_PointAndTangent= IntersectPointVelct_G;
|
||||
G4ThreeVector NewChord= IntersectPoint_G - SubStartPoint;
|
||||
// LinearStepLength= NewChord.mag();
|
||||
StepTaken =
|
||||
TruePathLength= IntersectPointVelct_G.CurveS()
|
||||
- OriginalState.CurveS(); // which is Zero now.
|
||||
#ifdef G4VERBOSE
|
||||
if( Verbose() > 0 ){
|
||||
G4cout << " Found an intersection after a Step of length " <<
|
||||
StepTaken << endl;
|
||||
}
|
||||
#endif
|
||||
// TruePathLength= StepTaken;
|
||||
}
|
||||
else
|
||||
{
|
||||
// "Minor" chords do not intersect
|
||||
intersects= false;
|
||||
}
|
||||
}
|
||||
if( ! intersects )
|
||||
{
|
||||
StepTaken += s_length_taken;
|
||||
}
|
||||
first_substep= false;
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if( Verbose() > 0 )
|
||||
printStatus( SubStepStartState, // or OriginalState,
|
||||
CurrentState,
|
||||
CurrentProposedStepLength,
|
||||
NewSafety,
|
||||
do_loop_count,
|
||||
pPhysVol);
|
||||
#endif
|
||||
|
||||
}
|
||||
while( (!intersects ) && (StepTaken < CurrentProposedStepLength)
|
||||
&& ( do_loop_count < GetMaxLoopCount() ) );
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if( do_loop_count >= GetMaxLoopCount() ){
|
||||
// G4cerr << "G4PropagateInField: Particle is looping - must be killed" << endl;
|
||||
G4cerr << "G4PropagateInField: Particle is looping - "
|
||||
<< " tracking in field will be stopped. " << endl;
|
||||
G4cerr << " Has performed " << do_loop_count << " steps in Field "
|
||||
<< " while a maximum of " << GetMaxLoopCount() << " are allowed. "
|
||||
<< endl;
|
||||
//G4cerr << " In future this will be treated better/quicker. " << endl;
|
||||
fParticleIsLooping= true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ! intersects )
|
||||
{
|
||||
// Chord AB or "minor chords" do not intersect
|
||||
|
||||
// B is the endpoint Step of the current Step.
|
||||
// [ But if we were angle limited we could use B
|
||||
// as a new starting point ? ]
|
||||
|
||||
// On return we specify the endpoint, point B
|
||||
End_PointAndTangent= CurrentState;
|
||||
// LinearStepLength= ChordAB_Length;
|
||||
TruePathLength= StepTaken;
|
||||
|
||||
} // end if(!intersects)
|
||||
|
||||
// Set pFieldTrack to the return value
|
||||
pFieldTrack =End_PointAndTangent;
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
// Check that "s" is correct
|
||||
if( fabs(OriginalState.CurveS() + TruePathLength
|
||||
- End_PointAndTangent.CurveS()) > 3.e-4 * TruePathLength )
|
||||
{
|
||||
G4cerr << " Error in G4PropagatorInField: Curve lenght mis-match, is advancement wrong ? ";
|
||||
G4cerr << " The curve length of the endpoint should be "
|
||||
<< OriginalState.CurveS() + TruePathLength
|
||||
<< " and is " << End_PointAndTangent.CurveS()
|
||||
<< " a difference of "
|
||||
<< OriginalState.CurveS() + TruePathLength
|
||||
- End_PointAndTangent.CurveS() << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TruePathLength;
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// G4bool
|
||||
// G4PropagatorInField::LocateIntersectionPoint(
|
||||
// const G4FieldTrack& CurveStartPointVelocity, // A
|
||||
// const G4FieldTrack& CurveEndPointVelocity, // B
|
||||
// const G4ThreeVector& TrialPoint, // E
|
||||
// G4FieldTrack& IntersectPointVelocity) // Output
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Function that returns the intersection of the true path with the surface
|
||||
// of the current volume (either the external one or the inner one with one
|
||||
// of the daughters
|
||||
//
|
||||
// A = Initial point
|
||||
// B = another point
|
||||
//
|
||||
// Both A and B are assumed to be on the true path.
|
||||
//
|
||||
// E is the first point of intersection of the chord AB with
|
||||
// a volume other than A (on the surface of A or of a daughter)
|
||||
//
|
||||
// First Version: October 16th, 1996 John Apostolakis, CERN CN/ASD
|
||||
// Modified: January 22nd, 1997 J.A. IT/ASD
|
||||
//
|
||||
// Convention of Use :
|
||||
// i) If it returns "true", then IntersectionPointVelocity is set
|
||||
// to the approximate intersection point.
|
||||
// ii) If it returns "false", no intersection was found and
|
||||
// IntersectionPointVelocity is invalid.
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
G4bool
|
||||
G4PropagatorInField::LocateIntersectionPoint(
|
||||
const G4FieldTrack& CurveStartPointVelocity, // A
|
||||
const G4FieldTrack& CurveEndPointVelocity, // B
|
||||
const G4ThreeVector& TrialPoint, // E
|
||||
G4FieldTrack& IntersectPointVelocity) // Output
|
||||
{
|
||||
// Find Intersection Point ( A, B, E ) of true path AB - start at E.
|
||||
|
||||
G4bool found_approximate_intersection = false;
|
||||
G4bool there_is_no_intersection = false;
|
||||
|
||||
G4FieldTrack CurrentA_PointVelocity= CurveStartPointVelocity;
|
||||
G4FieldTrack CurrentB_PointVelocity= CurveEndPointVelocity;
|
||||
G4ThreeVector CurrentE_Point= TrialPoint;
|
||||
|
||||
G4FieldTrack ApproxIntersecPointV(CurveEndPointVelocity); // FT-Def-Construct
|
||||
G4double NewSafety;
|
||||
G4bool first_step= true;
|
||||
G4int substep_no= 0;
|
||||
G4VPhysicalVolume *pPhysVol;
|
||||
|
||||
do{ // REPEAT
|
||||
|
||||
G4ThreeVector Point_A= CurrentA_PointVelocity.Position();
|
||||
G4ThreeVector Point_B= CurrentB_PointVelocity.Position();
|
||||
|
||||
// F = a point on true AB path close to point E (the closest if possible)
|
||||
//
|
||||
ApproxIntersecPointV= GetChordFinder()->ApproxCurvePointV(
|
||||
CurrentA_PointVelocity,
|
||||
CurrentB_PointVelocity,
|
||||
CurrentE_Point,
|
||||
this->GetEpsilonStep() );
|
||||
|
||||
// The above function is the most difficult part ...
|
||||
//
|
||||
// Another approach would be for the curved true path
|
||||
// to be an object and this should be a member function.
|
||||
// -> The Curve Start and End point would not be needed as arguments.
|
||||
//
|
||||
G4ThreeVector CurrentF_Point= ApproxIntersecPointV.Position();
|
||||
|
||||
// First check whether EF is small - then F is a good approx. point
|
||||
//
|
||||
// Calculate the length and direction of the chord AF
|
||||
|
||||
// ChordEF_Vector= Chord_Vector(CurrentE_Point, CurrentF_Point);
|
||||
// ------------
|
||||
G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point;
|
||||
|
||||
if ( ChordEF_Vector.mag2() <= sqr(DeltaIntersection()) ){
|
||||
|
||||
found_approximate_intersection = true;
|
||||
|
||||
// Create the "point" return value
|
||||
// IntersectPointVelocity.SetCurvePnt(
|
||||
// CurrentE_Point,
|
||||
// ApproxIntersecPointV.GetVelocity(),
|
||||
// ApproxIntersecPointV.CurveS() );
|
||||
IntersectPointVelocity = ApproxIntersecPointV;
|
||||
IntersectPointVelocity.SetPosition( CurrentE_Point );
|
||||
|
||||
// Note: in order to return a point on the boundary,
|
||||
// we must return E. But it is F on the curve.
|
||||
// So we must "cheat": we are using the position at point E and
|
||||
// the velocity at point F !!!
|
||||
//
|
||||
// This must limit the length we can allow for displacement!
|
||||
|
||||
}else{ // E is NOT close enough to the curve (ie point F).
|
||||
|
||||
if( !first_step){
|
||||
// Check whether any volumes are encountered by the chord AF
|
||||
//----------------------------------------------------------
|
||||
fNavigator->LocateGlobalPointWithinVolume( Point_A );
|
||||
// This locate is needed in all cases except for the
|
||||
// original point A, because - presumably - that was
|
||||
// called at the start of the physical Step
|
||||
}
|
||||
first_step= false;
|
||||
|
||||
// Calculate the length and direction of the chord AF
|
||||
G4ThreeVector ChordAF_Vector= CurrentF_Point - Point_A;
|
||||
G4double ChordAF_Length= ChordAF_Vector.mag();
|
||||
G4ThreeVector ChordAF_Dir= ChordAF_Vector.unit();
|
||||
|
||||
G4double stepLength =
|
||||
fNavigator->ComputeStep( Point_A, ChordAF_Dir,
|
||||
ChordAF_Length, NewSafety);
|
||||
|
||||
G4bool Intersects_AF = (stepLength <= ChordAF_Length);
|
||||
stepLength = min(stepLength, ChordAF_Length);
|
||||
if( Intersects_AF ){
|
||||
// There is an intersection of AF with a volume boundary
|
||||
|
||||
// G <- First Intersection of Chord AF
|
||||
//
|
||||
G4ThreeVector PointG= Point_A + stepLength * ChordAF_Dir;
|
||||
|
||||
// G is our new Candidate for the intersection point.
|
||||
// It replaces "E" and we will repeat the test to see if
|
||||
// it is a good enough approximate point for us.
|
||||
// B <- F
|
||||
// E <- G
|
||||
CurrentB_PointVelocity= ApproxIntersecPointV;
|
||||
CurrentE_Point= PointG;
|
||||
|
||||
// Else (not Intersects_AF)
|
||||
}else{
|
||||
// In this case:
|
||||
// There is NO intersection of AF with a volume boundary.
|
||||
// We must continue the search in the segment FB!
|
||||
|
||||
// Check whether any volumes are encountered by the chord FB
|
||||
//----------------------------------------------------------
|
||||
// Calculate the length and direction of the chord AF
|
||||
G4ThreeVector ChordFB_Vector= Point_B - CurrentF_Point;
|
||||
G4double ChordFB_Length= ChordFB_Vector.mag();
|
||||
G4ThreeVector ChordFB_Dir= ChordFB_Vector.unit();
|
||||
|
||||
fNavigator->LocateGlobalPointWithinVolume( CurrentF_Point );
|
||||
G4double stepLength =
|
||||
fNavigator->ComputeStep( CurrentF_Point, ChordFB_Dir,
|
||||
ChordFB_Length, NewSafety);
|
||||
|
||||
G4bool Intersects_FB = stepLength <= ChordFB_Length;
|
||||
stepLength = min(stepLength, ChordFB_Length);
|
||||
if( Intersects_FB ) {
|
||||
// There is an intersection of FB with a volume boundary
|
||||
// H <- First Intersection of Chord FB
|
||||
//
|
||||
G4ThreeVector PointH= CurrentF_Point + stepLength * ChordFB_Dir;
|
||||
|
||||
// H is our new Candidate for the intersection point.
|
||||
// It replaces "E" and we will repeat the test to see if
|
||||
// it is a good enough approximate point for us.
|
||||
|
||||
// Note that F must be in volume volA (the same as A)
|
||||
// (otherwise AF would meet a volume boundary!)
|
||||
// A <- F
|
||||
// E <- H
|
||||
CurrentA_PointVelocity= ApproxIntersecPointV;
|
||||
CurrentE_Point= PointH;
|
||||
|
||||
}else{ // (not Intersects_FB)
|
||||
//
|
||||
// There is NO intersection of FB with a volume boundary
|
||||
// This means that somehow a volume intersected the original
|
||||
// chord but misses the chord (or series of chords)
|
||||
// we have used.
|
||||
//
|
||||
there_is_no_intersection= true;
|
||||
//
|
||||
// the value of IntersectPointVelocity returned is not valid
|
||||
|
||||
} // Endif (Intersects_FB)
|
||||
|
||||
} // Endif (Intersects_AF)
|
||||
|
||||
} // EndIf ( E is close enough to the curve, ie point F. )
|
||||
// tests ChordAF_Vector.mag() <= maximum_lateral_displacement
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if( Verbose() > 1 )
|
||||
printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
|
||||
-1.0, NewSafety, substep_no, 0); // startVolume);
|
||||
#endif
|
||||
substep_no++;
|
||||
|
||||
} while ( ( ! found_approximate_intersection ) &&
|
||||
( ! there_is_no_intersection ) ); // UNTIL found or failed
|
||||
|
||||
return !there_is_no_intersection ; // Success or failure
|
||||
|
||||
}
|
||||
|
||||
void G4PropagatorInField::printStatus(
|
||||
const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
G4double safety,
|
||||
G4int Step,
|
||||
G4VPhysicalVolume* startVolume)
|
||||
// G4VPhysicalVolume* endVolume)
|
||||
{
|
||||
const G4int verboseLevel=1;
|
||||
const G4ThreeVector StartPosition= StartFT.GetPosition();
|
||||
const G4ThreeVector StartUnitVelocity= StartFT.GetMomentumDir();
|
||||
const G4ThreeVector CurrentPosition= CurrentFT.GetPosition();
|
||||
const G4ThreeVector CurrentUnitVelocity= CurrentFT.GetMomentumDir();
|
||||
|
||||
G4double step_len= CurrentFT.GetCurveLength()
|
||||
- StartFT.GetCurveLength();
|
||||
|
||||
if( (Step == 0) && (verboseLevel <= 3) )
|
||||
{
|
||||
G4cout.precision(3);
|
||||
// G4cout.setf(ios_base::fixed,ios_base::floatfield);
|
||||
G4cout << setw( 6) << " "
|
||||
<< setw( 25) << " Current Position and Direction" << " "
|
||||
<< endl;
|
||||
G4cout << setw( 5) << "Step#" << " "
|
||||
<< setw( 9) << "X(mm)" << " "
|
||||
<< setw( 9) << "Y(mm)" << " "
|
||||
<< setw( 9) << "Z(mm)" << " "
|
||||
<< setw( 7) << " N_x " << " "
|
||||
<< setw( 7) << " N_y " << " "
|
||||
<< setw( 7) << " N_z " << " "
|
||||
// << setw( 9) << "KinE(MeV)" << " "
|
||||
// << setw( 9) << "dE(MeV)" << " "
|
||||
<< setw( 9) << "StepLen" << " "
|
||||
<< setw( 9) << "PhsStep" << " "
|
||||
<< setw(12) << "StartSafety" << " "
|
||||
<< setw(18) << "NextVolume" << " "
|
||||
<< endl;
|
||||
}
|
||||
|
||||
//
|
||||
if( verboseLevel > 3 )
|
||||
{
|
||||
// G4cout << "Current Position is " << CurrentPosition << endl
|
||||
// << " and UnitVelocity is " << CurrentUnitVelocity << endl;
|
||||
G4cout << "Step taken was " << step_len
|
||||
<< " out of PhysicalStep= " << requestStep << endl;
|
||||
G4cout << "Final safety is: " << safety << endl;
|
||||
|
||||
G4cout << "Chord length = " << (CurrentPosition-StartPosition).mag() << endl;
|
||||
G4cout << endl;
|
||||
}
|
||||
else // if( verboseLevel > 0 )
|
||||
{
|
||||
G4cout.precision(3);
|
||||
G4cout << setw( 5) << Step << " "
|
||||
<< setw( 9) << CurrentPosition.x() << " "
|
||||
<< setw( 9) << CurrentPosition.y() << " "
|
||||
<< setw( 9) << CurrentPosition.z() << " "
|
||||
<< setw( 7) << CurrentUnitVelocity.x() << " "
|
||||
<< setw( 7) << CurrentUnitVelocity.y() << " "
|
||||
<< setw( 7) << CurrentUnitVelocity.z() << " "
|
||||
// << setw( 9) << KineticEnergy << " "
|
||||
// << setw( 9) << EnergyDifference << " "
|
||||
<< setw( 9) << step_len << " "
|
||||
<< setw( 9) << requestStep << " "
|
||||
<< setw(12) << safety << " ";
|
||||
if( startVolume != 0) {
|
||||
G4cout << setw(12) << startVolume->GetName() << " ";
|
||||
} else {
|
||||
G4cout << setw(12) << "OutOfWorld" << " ";
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( CurrentVolume != 0)
|
||||
{
|
||||
G4cout << setw(12) << CurrentVolume()->GetName() << " ";
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << setw(12) << "OutOfWorld or Unknown" << " ";
|
||||
}
|
||||
#endif
|
||||
G4cout << endl;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4RKG3_Stepper.cc,v 2.4 1998/11/12 17:20:41 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4RKG3_Stepper.cc,v 1.1 1999/01/07 16:07:12 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
#include "G4RKG3_Stepper.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4SimpleHeum.cc,v 2.6 1998/11/17 18:20:11 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4SimpleHeum.cc,v 1.2 1999/03/04 13:52:30 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
// Simple Heum:
|
||||
// x_1 = x_0 + h *
|
||||
@@ -43,10 +43,10 @@ G4SimpleHeum::G4SimpleHeum(G4Mag_EqRhs *EqRhs, G4int num_variables):
|
||||
|
||||
G4SimpleHeum::~G4SimpleHeum()
|
||||
{
|
||||
delete dydxTemp;
|
||||
delete dydxTemp2;
|
||||
delete yTemp;
|
||||
delete yTemp2;
|
||||
delete[] dydxTemp;
|
||||
delete[] dydxTemp2;
|
||||
delete[] yTemp;
|
||||
delete[] yTemp2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4SimpleRunge.cc,v 2.8 1998/11/19 20:54:58 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4SimpleRunge.cc,v 1.1 1999/01/07 16:07:12 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
// Simple Runge:
|
||||
//
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4UniformElectricField.cc,v 2.2 1998/11/19 20:45:22 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4UniformElectricField.cc,v 1.1 1999/01/07 16:07:12 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4UniformMagField.cc,v 2.4 1998/11/27 16:15:53 japost Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
// $Id: G4UniformMagField.cc,v 1.1 1999/01/07 16:07:12 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-00-01 $
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user