Import Geant4 0.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-01 15:25:35 +02:00
parent 54d6b71f95
commit b97f8d0df7
3237 changed files with 807095 additions and 0 deletions
@@ -0,0 +1,488 @@
// 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: G4FConicalSurface.cc,v 2.16 1998/12/10 17:26:41 broglia Exp $
// GEANT4 tag $Name: geant4-00 $
//
/* /usr/local/gismo/repo/geometry/G4FConicalSurface.cc,v 1.2 1993/02/05 00:38:39 alanb Exp */
// File: G4FConicalSurface.cc
// Author: Alan Breakstone
// Contents ----------------------------------------------------------
//
// G4FConicalSurface::G4FConicalSurface( const G4Point3D& o,
// const G4Vector3D& a,
// G4double l, G4double sr, G4double lr )
// G4FConicalSurface::G4FConicalSurface( const G4FConicalSurface& c )
// G4FConicalSurface::PrintOn( ostream& os ) const
// G4FConicalSurface::operator==( const G4FConicalSurface& c )
// G4FConicalSurface::WithinBoundary( const G4Vector3D& x ) const
// G4FConicalSurface::Scale() const
// G4FConicalSurface::Area() const
// G4FConicalSurface::resize( G4double l, G4double sr, G4double lr )
//
// End ---------------------------------------------------------------
#include "G4FConicalSurface.hh"
#include "G4Sort.hh"
#include "G4CircularCurve.hh"
G4FConicalSurface::G4FConicalSurface(const G4Point3D& o,
const G4Vector3D& a,
G4double l,
G4double sr,
G4double lr
) //: G4ConicalSurface( o, a, 1.0 )
//: G4Surface( o ) doesn`t exist
{
// Make a G4FConicalSurface with origin o, axis a, length l, small radius
// sr, and large radius lr. The angle is calculated below and the SetAngle
// function of G4ConicalSurface is used to set it properly from the default
// value used above in the initialization.
// L. Broglia
// Position.SetSrfPoint(o);
// Position.SetAxis(a);
// Create the position with origin o, axis a, and a direction wich
// is not important
G4Vector3D dir(1,1,1);
Position.Init(dir, a, o);
origin = o;
// Require length to be nonnegative
// if ( l > 0.0 )
if (l >=0)
length = l;
else
{
G4cerr << "Error in G4FConicalSurface::G4FConicalSurface"
<< "--asked for negative length\n"
<< "\tDefault length of 0.0 is used.\n";
length = 0.0;
}
// Require small radius to be non-negative (i.e., allow zero)
if ( sr >= 0.0 )
small_radius = sr;
else
{
G4cerr << "Error in G4FConicalSurface::G4FConicalSurface"
<< "--asked for negative small radius\n"
<< "\tDefault value of 0.0 is used.\n";
small_radius = 0.0;
}
// Require large radius to exceed small radius
if ( lr > small_radius )
large_radius = lr;
else
{
G4cerr << "Error in G4FConicalSurface::G4FConicalSurface"
<< "--large radius must exceed small radius\n"
<< "\tDefault value of small radius +1 is used.\n";
large_radius = small_radius + 1.0;
}
// Calculate the angle of the G4ConicalSurface from the length and radii
tan_angle = ( large_radius - small_radius ) / length ;
}
G4FConicalSurface::G4FConicalSurface( const G4FConicalSurface& c )
//: G4ConicalSurface( c.origin, c.GetAxis(), c.GetAngle() )
{
// copy constructor
small_radius = c.small_radius;
large_radius = c.large_radius;
length = c.length;
tan_angle = c.tan_angle;
}
// Modified by L. Broglia (01/12/98)
void G4FConicalSurface::CalcBBox()
{
G4Point3D Max = -PINFINITY;
G4Point3D Min = PINFINITY;
G4Point3D Tmp;
G4double delta = small_radius / tan_angle;
G4Point3D Origin = Position.GetLocation();
G4Point3D EndOrigin = Origin + (length * Position.GetAxis());
G4double radius = large_radius;
G4Point3D Radius(radius, radius, 0);
// Default BBox
G4Point3D Tolerance(kCarTolerance, kCarTolerance, kCarTolerance);
G4Point3D BoxMin(Origin-Tolerance);
G4Point3D BoxMax(Origin+Tolerance);
bbox = new G4BoundingBox3D();
bbox->Init(BoxMin, BoxMax);
Tmp = (Origin - Radius);
bbox->Extend(Tmp);
Tmp = Origin + Radius;
bbox->Extend(Tmp);
Tmp = EndOrigin - Radius;
bbox->Extend(Tmp);
Tmp = EndOrigin + Radius;
bbox->Extend(Tmp);
}
void G4FConicalSurface::PrintOn( ostream& os ) const
{
// printing function using C++ ostream class
os << "G4FConicalSurface with origin: " << origin << "\t"
<< "and axis: " << Position.GetAxis() << "\n"
<< "\t small radius: " << small_radius
<< "\t large radius: " << large_radius
<< "\t and length: " << length << "\n";
}
int G4FConicalSurface::operator==( const G4FConicalSurface& c )
{
return ( origin == c.origin &&
Position.GetAxis() == c.Position.GetAxis() &&
small_radius == c.small_radius &&
large_radius == c.large_radius &&
length == c.length &&
tan_angle == c.tan_angle );
}
int G4FConicalSurface::WithinBoundary( const G4Vector3D& x ) const
{
// return 1 if point x is within the boundaries of the G4FConicalSurface
// return 0 otherwise (assume it is on the G4ConicalSurface)
G4Vector3D q = x - origin;
G4double qmag = q.mag();
G4double s = sin( atan2(large_radius-small_radius, length) );
G4double ls = small_radius / s;
G4double ll = large_radius / s;
if ( ( qmag >= ls ) && ( qmag <= ll ) )
return 1;
else
return 0;
}
G4double G4FConicalSurface::Scale() const
{
// Returns the small radius of a G4FConicalSurface unless it is zero, in
// which case returns the large radius.
// Used for Scale-invariant tests of surface thickness.
if ( small_radius == 0.0 )
return large_radius;
else
return small_radius;
}
G4double G4FConicalSurface::Area() const
{
// Returns the Area of a G4FConicalSurface
G4double rdif = large_radius - small_radius;
return ( M_PI * ( small_radius + large_radius ) *
sqrt( length * length + rdif * rdif ) );
}
void G4FConicalSurface::resize( G4double l, G4double sr, G4double lr )
{
// Resize a G4FConicalSurface to a new length l, and new radii sr and lr.
// Must Reset angle of the G4ConicalSurface as well based on these new
// values.
// Require length to be non-negative
// if ( l > 0.0 )
if ( l >= 0.0 )
length = l;
else
{
G4cerr << "Error in G4FConicalSurface::resize"
<< "--asked for negative length\n"
<< "\tOriginal value of " << length << " is retained.\n";
}
// Require small radius to be non-negative (i.e., allow zero)
if ( sr >= 0.0 )
small_radius = sr;
else
{
G4cerr << "Error in G4FConicalSurface::resize"
<< "--asked for negative small radius\n"
<< "\tOriginal value of " << small_radius
<< " is retained.\n";
}
// Require large radius to exceed small radius
if ( lr > small_radius )
large_radius = lr;
else
{
G4double r = small_radius + 1.0;
lr = ( large_radius <= small_radius ) ? r : large_radius;
large_radius = lr;
G4cerr << "Error in G4FConicalSurface::G4FConicalSurface"
<< "--large radius must exceed small radius\n"
<< "\tDefault value of " << large_radius << " is used.\n";
}
// Calculate the angle of the G4ConicalSurface from the length and radii
tan_angle = ( large_radius - small_radius ) / length ;
}
int G4FConicalSurface::Intersect(const G4Ray& ry )
{
// Distance along a Ray (straight line with G4Vector3D) to leave or enter
// a G4FConicalSurface. The input variable which_way should be set to +1 to
// indicate leaving a G4ConicalSurface, -1 to indicate entering a
// G4ConicalSurface.
// p is the point of intersection of the Ray with the G4ConicalSurface.
// If the G4Vector3D of the Ray is opposite to that of the Normal to
// the G4FConicalSurface at the intersection point, it will not leave the
// G4FConicalSurface.
// Similarly, if the G4Vector3D of the Ray is along that of the Normal
// to the G4ConicalSurface at the intersection point, it will not enter the
// G4ConicalSurface.
// This method is called by all finite shapes sub-classed to
// G4ConicalSurface.
// Use the virtual function table to check if the intersection point
// is within the boundary of the finite shape.
// A negative result means no intersection.
// If no valid intersection point is found, set the distance
// and intersection point to large numbers.
int which_way;
if(Inside(ry.GetStart()))
which_way = 1;
else
which_way = -1;
distance = FLT_MAXX;
G4Vector3D lv ( FLT_MAXX, FLT_MAXX, FLT_MAXX );
closest_hit = lv;
// Origin and G4Vector3D unit vector of Ray.
G4Vector3D x = ry.GetStart();
G4Vector3D dhat = ry.GetDir();
// Cone angle and axis unit vector.
G4double ta = tan_angle;
G4Vector3D ahat = Position.GetAxis();
int isoln = 0, maxsoln = 2;
// array of solutions in distance along the Ray
G4double s[2];
s[0]=-1.0;
s[1]=-1.0;
// L. Broglia
// calculate the two solutions (quadratic equation)
G4Vector3D gamma = x - Position.GetLocation();
G4double T = 1.0 + ta * ta;
G4double ga = gamma * ahat;
G4double da = dhat * ahat;
/*
G4double A = 1.0 - T * da * da;
G4double B = 2.0 * ( gamma * dhat - T * ga * da );
G4double C = gamma * gamma - T * ga * ga;
*/
G4double A = - 1.0 + T * da * da;
G4double B = 2 * ( -gamma * dhat + T * ga * da - large_radius * ta * da);
G4double C = ( -gamma * gamma + T * ga * ga
- 2 * large_radius * ta * ga
+ large_radius * large_radius );
// if quadratic term vanishes, just do the simple solution
if ( fabs( A ) < FLT_EPSILO )
if ( B == 0.0 )
return 1;
else
s[0] = -C / B;
// Normal quadratic case, no intersection if radical is less than zero
else
{
G4double radical = B * B - 4.0 * A * C;
if ( radical < 0.0 )
return 0;
else
{
G4double root = sqrt( radical );
s[0] = ( - B + root ) / ( 2. * A );
s[1] = ( - B - root ) / ( 2. * A );
}
}
// order the possible solutions by increasing distance along the Ray
// (G4Sorting routines are in support/G4Sort.h)
G4Sort_double( s, isoln, maxsoln-1 );
// now loop over each positive solution, keeping the first one (smallest
// distance along the Ray) which is within the boundary of the sub-shape
// and which also has the correct G4Vector3D with respect to the Normal to
// the G4ConicalSurface at the intersection point
for ( isoln = 0; isoln < maxsoln; isoln++ )
{
if ( s[isoln] >= kCarTolerance*0.5 )
{
if ( s[isoln] >= FLT_MAXX ) // quit if too large
return 0;
distance = s[isoln];
closest_hit = ry.GetPoint( distance );
// Following line necessary to select non-reflective solutions.
if ((( ahat * ( closest_hit - Position.GetLocation() ) > 0.0 ) &&
((( dhat * SurfaceNormal( closest_hit ) * which_way ) >= 0.0 )) &&
( fabs(HowNear( closest_hit )) < 0.1)) )
{
if ( WithinBoundary ( closest_hit ) == 1 )
{
distance = distance*distance;
return 1;
}
}
distance = distance*distance;
return 1;
}
else
if ( s[isoln] >= -kCarTolerance*0.5 )
{
// the point is on the surface
distance = 0;
return 1;
}
}
// get here only if there was no solution within the boundary, Reset
// distance and intersection point to large numbers
distance = FLT_MAXX;
closest_hit = lv;
return 0;
}
G4double G4FConicalSurface::HowNear( const G4Vector3D& x ) const
{
// Distance from the point x to the semi-infinite G4FConicalSurface.
// The distance will be positive if the point is Inside the G4ConicalSurface,
// negative if the point is outside.
// Note that this may not be correct for a bounded conical object
// subclassed to G4ConicalSurface.
G4Vector3D d = x - origin;
G4double dA = d * Position.GetAxis();
G4double rad = sqrt( d.mag2() - dA*dA );
G4double teta = atan2( (large_radius - small_radius) , length );
G4double radiu = fabs( rad - large_radius + dA*tan_angle );
G4double hownear ;
if (dA > length)
hownear =dA - length;
else if (dA < 0)
hownear =dA;
else
hownear = radiu * cos(teta);
return hownear;
}
// Add by L. Broglia
// Verify this function
G4Vector3D G4FConicalSurface::SurfaceNormal( const G4Point3D& p ) const
{
// return the Normal unit vector to the G4ConicalSurface at a point p
// on (or nearly on) the G4ConicalSurface
G4Vector3D s = p - origin;
G4double smag = s.mag2();
// if the point happens to be at the origin, calculate a unit vector Normal
// to the axis, with zero z component
if ( smag == 0.0 )
{
G4double ax = Position.GetAxis().x();
G4double ay = Position.GetAxis().y();
G4double ap = sqrt( ax * ax + ay * ay );
if ( ap == 0.0 )
return G4Vector3D( 1.0, 0.0, 0.0 );
else
return G4Vector3D( ay / ap, -ax / ap, 0.0 );
}
// otherwise do the calculation of the Normal to the conical surface
else
{
G4double l = s * Position.GetAxis();
s = s*(1/smag);
G4Vector3D q = origin + l * Position.GetAxis();
G4Vector3D v = p - q;
G4double sl = v.mag2() *
sin( atan2((large_radius - small_radius), length) );
G4Vector3D n = v - sl * s;
G4double nmag = n.mag2();
if ( nmag != 0.0 )
n=n*(1/nmag);
return n;
}
}
// Add by L. Broglia
int G4FConicalSurface::Inside ( const G4Vector3D& x ) const
{
// Return 0 if point x is outside G4ConicalSurface, 1 if Inside.
// Outside means that the distance to the G4ConicalSurface would be negative.
// Use the HowNear function to calculate this distance.
if ( HowNear( x ) >= -0.5*kCarTolerance )
return 1;
else
return 0;
}