Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Paraboloid Class Reference

#include <G4Paraboloid.hh>

+ Inheritance diagram for G4Paraboloid:

Public Member Functions

 G4Paraboloid (const G4String &pName, G4double pDz, G4double pR1, G4double pR2)
 
virtual ~G4Paraboloid ()
 
G4double GetZHalfLength () const
 
G4double GetRadiusMinusZ () const
 
G4double GetRadiusPlusZ () const
 
G4double GetCubicVolume ()
 
G4double GetSurfaceArea ()
 
G4double CalculateSurfaceArea () const
 
void SetZHalfLength (G4double dz)
 
void SetRadiusMinusZ (G4double R1)
 
void SetRadiusPlusZ (G4double R2)
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const
 
EInside Inside (const G4ThreeVector &p) const
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 
G4double DistanceToIn (const G4ThreeVector &p) const
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=G4bool(false), G4bool *validNorm=0, G4ThreeVector *n=0) const
 
G4double DistanceToOut (const G4ThreeVector &p) const
 
G4GeometryType GetEntityType () const
 
G4VSolidClone () const
 
std::ostream & StreamInfo (std::ostream &os) const
 
G4ThreeVector GetPointOnSurface () const
 
void DescribeYourselfTo (G4VGraphicsScene &scene) const
 
G4PolyhedronCreatePolyhedron () const
 
G4PolyhedronGetPolyhedron () const
 
G4NURBSCreateNURBS () const
 
 G4Paraboloid (__void__ &)
 
 G4Paraboloid (const G4Paraboloid &rhs)
 
G4Paraboloidoperator= (const G4Paraboloid &rhs)
 
- Public Member Functions inherited from G4VSolid
 G4VSolid (const G4String &name)
 
virtual ~G4VSolid ()
 
G4bool operator== (const G4VSolid &s) const
 
G4String GetName () const
 
void SetName (const G4String &name)
 
G4double GetTolerance () const
 
virtual G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
 
virtual EInside Inside (const G4ThreeVector &p) const =0
 
virtual G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const =0
 
virtual G4double DistanceToIn (const G4ThreeVector &p) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
 
virtual G4double DistanceToOut (const G4ThreeVector &p) const =0
 
virtual void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 
virtual G4double GetCubicVolume ()
 
virtual G4double GetSurfaceArea ()
 
virtual G4GeometryType GetEntityType () const =0
 
virtual G4ThreeVector GetPointOnSurface () const
 
virtual G4VSolidClone () const
 
virtual std::ostream & StreamInfo (std::ostream &os) const =0
 
void DumpInfo () const
 
virtual void DescribeYourselfTo (G4VGraphicsScene &scene) const =0
 
virtual G4VisExtent GetExtent () const
 
virtual G4PolyhedronCreatePolyhedron () const
 
virtual G4NURBSCreateNURBS () const
 
virtual G4PolyhedronGetPolyhedron () const
 
virtual const G4VSolidGetConstituentSolid (G4int no) const
 
virtual G4VSolidGetConstituentSolid (G4int no)
 
virtual const G4DisplacedSolidGetDisplacedSolidPtr () const
 
virtual G4DisplacedSolidGetDisplacedSolidPtr ()
 
 G4VSolid (__void__ &)
 
 G4VSolid (const G4VSolid &rhs)
 
G4VSolidoperator= (const G4VSolid &rhs)
 

Protected Attributes

G4PolyhedronfpPolyhedron
 
- Protected Attributes inherited from G4VSolid
G4double kCarTolerance
 

Additional Inherited Members

- Protected Member Functions inherited from G4VSolid
void CalculateClippedPolygonExtent (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipCrossSection (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipBetweenSections (G4ThreeVectorList *pVertices, const G4int pSectionIndex, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis, G4double &pMin, G4double &pMax) const
 
void ClipPolygon (G4ThreeVectorList &pPolygon, const G4VoxelLimits &pVoxelLimit, const EAxis pAxis) const
 
G4double EstimateCubicVolume (G4int nStat, G4double epsilon) const
 
G4double EstimateSurfaceArea (G4int nStat, G4double ell) const
 

Detailed Description

Definition at line 64 of file G4Paraboloid.hh.

Constructor & Destructor Documentation

◆ G4Paraboloid() [1/3]

G4Paraboloid::G4Paraboloid ( const G4String pName,
G4double  pDz,
G4double  pR1,
G4double  pR2 
)

Definition at line 59 of file G4Paraboloid.cc.

63 : G4VSolid(pName), fpPolyhedron(0), fSurfaceArea(0.), fCubicVolume(0.)
64
65{
66 if( (pDz <= 0.) || (pR2 <= pR1) || (pR1 < 0.) )
67 {
68 std::ostringstream message;
69 message << "Invalid dimensions. Negative Input Values or R1>=R2 - "
70 << GetName();
71 G4Exception("G4Paraboloid::G4Paraboloid()", "GeomSolids0002",
72 FatalErrorInArgument, message,
73 "Z half-length must be larger than zero or R1>=R2.");
74 }
75
76 r1 = pR1;
77 r2 = pR2;
78 dz = pDz;
79
80 // r1^2 = k1 * (-dz) + k2
81 // r2^2 = k1 * ( dz) + k2
82 // => r1^2 + r2^2 = k2 + k2 => k2 = (r2^2 + r1^2) / 2
83 // and r2^2 - r1^2 = k1 * dz - k1 * (-dz) => k1 = (r2^2 - r1^2) / 2 / dz
84
85 k1 = (r2 * r2 - r1 * r1) / 2 / dz;
86 k2 = (r2 * r2 + r1 * r1) / 2;
87}
@ FatalErrorInArgument
G4Polyhedron * fpPolyhedron
G4String GetName() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41

◆ ~G4Paraboloid()

G4Paraboloid::~G4Paraboloid ( )
virtual

Definition at line 104 of file G4Paraboloid.cc.

105{
106}

◆ G4Paraboloid() [2/3]

G4Paraboloid::G4Paraboloid ( __void__ &  a)

Definition at line 94 of file G4Paraboloid.cc.

95 : G4VSolid(a), fpPolyhedron(0), fSurfaceArea(0.), fCubicVolume(0.),
96 dz(0.), r1(0.), r2(0.), k1(0.), k2(0.)
97{
98}

◆ G4Paraboloid() [3/3]

G4Paraboloid::G4Paraboloid ( const G4Paraboloid rhs)

Definition at line 112 of file G4Paraboloid.cc.

113 : G4VSolid(rhs), fpPolyhedron(0),
114 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume),
115 dz(rhs.dz), r1(rhs.r1), r2(rhs.r2), k1(rhs.k1), k2(rhs.k2)
116{
117}

Member Function Documentation

◆ CalculateExtent()

G4bool G4Paraboloid::CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits pVoxelLimit,
const G4AffineTransform pTransform,
G4double pmin,
G4double pmax 
) const
virtual

Implements G4VSolid.

Definition at line 161 of file G4Paraboloid.cc.

165{
166 G4double xMin = -r2 + pTransform.NetTranslation().x(),
167 xMax = r2 + pTransform.NetTranslation().x(),
168 yMin = -r2 + pTransform.NetTranslation().y(),
169 yMax = r2 + pTransform.NetTranslation().y(),
170 zMin = -dz + pTransform.NetTranslation().z(),
171 zMax = dz + pTransform.NetTranslation().z();
172
173 if(!pTransform.IsRotated()
174 || pTransform.NetRotation()(G4ThreeVector(0, 0, 1)) == G4ThreeVector(0, 0, 1))
175 {
176 if(pVoxelLimit.IsXLimited())
177 {
178 if(pVoxelLimit.GetMaxXExtent() < xMin - 0.5 * kCarTolerance
179 || pVoxelLimit.GetMinXExtent() > xMax + 0.5 * kCarTolerance)
180 {
181 return false;
182 }
183 else
184 {
185 if(pVoxelLimit.GetMinXExtent() > xMin)
186 {
187 xMin = pVoxelLimit.GetMinXExtent();
188 }
189 if(pVoxelLimit.GetMaxXExtent() < xMax)
190 {
191 xMax = pVoxelLimit.GetMaxXExtent();
192 }
193 }
194 }
195 if(pVoxelLimit.IsYLimited())
196 {
197 if(pVoxelLimit.GetMaxYExtent() < yMin - 0.5 * kCarTolerance
198 || pVoxelLimit.GetMinYExtent() > yMax + 0.5 * kCarTolerance)
199 {
200 return false;
201 }
202 else
203 {
204 if(pVoxelLimit.GetMinYExtent() > yMin)
205 {
206 yMin = pVoxelLimit.GetMinYExtent();
207 }
208 if(pVoxelLimit.GetMaxYExtent() < yMax)
209 {
210 yMax = pVoxelLimit.GetMaxYExtent();
211 }
212 }
213 }
214 if(pVoxelLimit.IsZLimited())
215 {
216 if(pVoxelLimit.GetMaxZExtent() < zMin - 0.5 * kCarTolerance
217 || pVoxelLimit.GetMinZExtent() > zMax + 0.5 * kCarTolerance)
218 {
219 return false;
220 }
221 else
222 {
223 if(pVoxelLimit.GetMinZExtent() > zMin)
224 {
225 zMin = pVoxelLimit.GetMinZExtent();
226 }
227 if(pVoxelLimit.GetMaxZExtent() < zMax)
228 {
229 zMax = pVoxelLimit.GetMaxZExtent();
230 }
231 }
232 }
233 switch(pAxis)
234 {
235 case kXAxis:
236 pMin = xMin;
237 pMax = xMax;
238 break;
239 case kYAxis:
240 pMin = yMin;
241 pMax = yMax;
242 break;
243 case kZAxis:
244 pMin = zMin;
245 pMax = zMax;
246 break;
247 default:
248 pMin = 0;
249 pMax = 0;
250 return false;
251 }
252 }
253 else
254 {
255 G4bool existsAfterClip=true;
256
257 // Calculate rotated vertex coordinates
258
259 G4int noPolygonVertices=0;
260 G4ThreeVectorList* vertices
261 = CreateRotatedVertices(pTransform,noPolygonVertices);
262
263 if(pAxis == kXAxis || pAxis == kYAxis || pAxis == kZAxis)
264 {
265
266 pMin = kInfinity;
267 pMax = -kInfinity;
268
269 for(G4ThreeVectorList::iterator it = vertices->begin();
270 it < vertices->end(); it++)
271 {
272 if(pMin > (*it)[pAxis]) pMin = (*it)[pAxis];
273 if((*it)[pAxis] < pVoxelLimit.GetMinExtent(pAxis))
274 {
275 pMin = pVoxelLimit.GetMinExtent(pAxis);
276 }
277 if(pMax < (*it)[pAxis])
278 {
279 pMax = (*it)[pAxis];
280 }
281 if((*it)[pAxis] > pVoxelLimit.GetMaxExtent(pAxis))
282 {
283 pMax = pVoxelLimit.GetMaxExtent(pAxis);
284 }
285 }
286
287 if(pMin > pVoxelLimit.GetMaxExtent(pAxis)
288 || pMax < pVoxelLimit.GetMinExtent(pAxis)) { existsAfterClip = false; }
289 }
290 else
291 {
292 pMin = 0;
293 pMax = 0;
294 existsAfterClip = false;
295 }
296 delete vertices;
297 return existsAfterClip;
298 }
299 return true;
300}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
std::vector< G4ThreeVector > G4ThreeVectorList
Definition: G4VSolid.hh:85
double z() const
double x() const
double y() const
G4bool IsRotated() const
G4ThreeVector NetTranslation() const
G4RotationMatrix NetRotation() const
G4double kCarTolerance
Definition: G4VSolid.hh:307
G4double GetMinExtent(const EAxis pAxis) const
G4bool IsYLimited() const
G4double GetMinZExtent() const
G4bool IsXLimited() const
G4double GetMaxExtent(const EAxis pAxis) const
G4double GetMaxYExtent() const
G4double GetMaxZExtent() const
G4double GetMinYExtent() const
G4double GetMinXExtent() const
G4bool IsZLimited() const
G4double GetMaxXExtent() const
@ kYAxis
Definition: geomdefs.hh:54
@ kXAxis
Definition: geomdefs.hh:54
@ kZAxis
Definition: geomdefs.hh:54

◆ CalculateSurfaceArea()

G4double G4Paraboloid::CalculateSurfaceArea ( ) const
inline

Referenced by GetPointOnSurface().

◆ Clone()

G4VSolid * G4Paraboloid::Clone ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 972 of file G4Paraboloid.cc.

973{
974 return new G4Paraboloid(*this);
975}

◆ CreateNURBS()

G4NURBS * G4Paraboloid::CreateNURBS ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1149 of file G4Paraboloid.cc.

1150{
1151 // Box for now!!!
1152 //
1153 return new G4NURBSbox(r1, r1, dz);
1154}

◆ CreatePolyhedron()

G4Polyhedron * G4Paraboloid::CreatePolyhedron ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1156 of file G4Paraboloid.cc.

1157{
1158 return new G4PolyhedronParaboloid(r1, r2, dz, 0., twopi);
1159}

Referenced by GetPolyhedron().

◆ DescribeYourselfTo()

void G4Paraboloid::DescribeYourselfTo ( G4VGraphicsScene scene) const
virtual

Implements G4VSolid.

Definition at line 1144 of file G4Paraboloid.cc.

1145{
1146 scene.AddSolid(*this);
1147}
virtual void AddSolid(const G4Box &)=0

◆ DistanceToIn() [1/2]

G4double G4Paraboloid::DistanceToIn ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 575 of file G4Paraboloid.cc.

576{
577 G4double safz = -dz+std::fabs(p.z());
578 if(safz<0) { safz=0; }
579 G4double safr = kInfinity;
580
581 G4double rho = p.x()*p.x()+p.y()*p.y();
582 G4double paraRho = (p.z()-k2)/k1;
583 G4double sqrho = std::sqrt(rho);
584
585 if(paraRho<0)
586 {
587 safr=sqrho-r2;
588 if(safr>safz) { safz=safr; }
589 return safz;
590 }
591
592 G4double sqprho = std::sqrt(paraRho);
593 G4double dRho = sqrho-sqprho;
594 if(dRho<0) { return safz; }
595
596 G4double talf = -2.*k1*sqprho;
597 G4double tmp = 1+talf*talf;
598 if(tmp<0.) { return safz; }
599
600 G4double salf = talf/std::sqrt(tmp);
601 safr = std::fabs(dRho*salf);
602 if(safr>safz) { safz=safr; }
603
604 return safz;
605}

◆ DistanceToIn() [2/2]

G4double G4Paraboloid::DistanceToIn ( const G4ThreeVector p,
const G4ThreeVector v 
) const
virtual

Implements G4VSolid.

Definition at line 442 of file G4Paraboloid.cc.

444{
445 G4double rho2 = p.perp2(), paraRho2 = std::fabs(k1 * p.z() + k2);
447 G4double tolh = 0.5*kCarTolerance;
448
449 if(r2 && p.z() > - tolh + dz)
450 {
451 // If the points is above check for intersection with upper edge.
452
453 if(v.z() < 0)
454 {
455 G4double intersection = (dz - p.z()) / v.z(); // With plane z = dz.
456 if(sqr(p.x() + v.x()*intersection)
457 + sqr(p.y() + v.y()*intersection) < sqr(r2 + 0.5 * kCarTolerance))
458 {
459 if(p.z() < tolh + dz)
460 { return 0; }
461 else
462 { return intersection; }
463 }
464 }
465 else // Direction away, no possibility of intersection
466 {
467 return kInfinity;
468 }
469 }
470 else if(r1 && p.z() < tolh - dz)
471 {
472 // If the points is belove check for intersection with lower edge.
473
474 if(v.z() > 0)
475 {
476 G4double intersection = (-dz - p.z()) / v.z(); // With plane z = -dz.
477 if(sqr(p.x() + v.x()*intersection)
478 + sqr(p.y() + v.y()*intersection) < sqr(r1 + 0.5 * kCarTolerance))
479 {
480 if(p.z() > -tolh - dz)
481 {
482 return 0;
483 }
484 else
485 {
486 return intersection;
487 }
488 }
489 }
490 else // Direction away, no possibility of intersection
491 {
492 return kInfinity;
493 }
494 }
495
496 G4double A = k1 / 2 * v.z() - p.x() * v.x() - p.y() * v.y(),
497 vRho2 = v.perp2(), intersection,
498 B = (k1 * p.z() + k2 - rho2) * vRho2;
499
500 if ( ( (rho2 > paraRho2) && (sqr(rho2-paraRho2-0.25*tol2) > tol2*paraRho2) )
501 || (p.z() < - dz+kCarTolerance)
502 || (p.z() > dz-kCarTolerance) ) // Make sure it's safely outside.
503 {
504 // Is there a problem with squaring rho twice?
505
506 if(vRho2<tol2) // Needs to be treated seperately.
507 {
508 intersection = ((rho2 - k2)/k1 - p.z())/v.z();
509 if(intersection < 0) { return kInfinity; }
510 else if(std::fabs(p.z() + v.z() * intersection) <= dz)
511 {
512 return intersection;
513 }
514 else
515 {
516 return kInfinity;
517 }
518 }
519 else if(A*A + B < 0) // No real intersections.
520 {
521 return kInfinity;
522 }
523 else
524 {
525 intersection = (A - std::sqrt(B + sqr(A))) / vRho2;
526 if(intersection < 0)
527 {
528 return kInfinity;
529 }
530 else if(std::fabs(p.z() + intersection * v.z()) < dz + tolh)
531 {
532 return intersection;
533 }
534 else
535 {
536 return kInfinity;
537 }
538 }
539 }
540 else if(sqr(rho2 - paraRho2 - .25 * tol2) <= tol2 * paraRho2)
541 {
542 // If this is true we're somewhere in the border.
543
544 G4ThreeVector normal(p.x(), p.y(), -k1/2);
545 if(normal.dot(v) <= 0)
546 { return 0; }
547 else
548 { return kInfinity; }
549 }
550 else
551 {
552 std::ostringstream message;
553 if(Inside(p) == kInside)
554 {
555 message << "Point p is inside! - " << GetName() << G4endl;
556 }
557 else
558 {
559 message << "Likely a problem in this function, for solid: " << GetName()
560 << G4endl;
561 }
562 message << " p = " << p * (1/mm) << " mm" << G4endl
563 << " v = " << v * (1/mm) << " mm";
564 G4Exception("G4Paraboloid::DistanceToIn(p,v)", "GeomSolids1002",
565 JustWarning, message);
566 return 0;
567 }
568}
@ JustWarning
#define G4endl
Definition: G4ios.hh:52
double perp2() const
EInside Inside(const G4ThreeVector &p) const
@ kInside
Definition: geomdefs.hh:58
T sqr(const T &x)
Definition: templates.hh:145

◆ DistanceToOut() [1/2]

G4double G4Paraboloid::DistanceToOut ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 922 of file G4Paraboloid.cc.

923{
924 G4double safe=0.0,rho,safeR,safeZ ;
925 G4double tanRMax,secRMax,pRMax ;
926
927#ifdef G4SPECSDEBUG
928 if( Inside(p) == kOutside )
929 {
930 G4cout << G4endl ;
931 DumpInfo();
932 std::ostringstream message;
933 G4int oldprc = message.precision(16);
934 message << "Point p is outside !?" << G4endl
935 << "Position:" << G4endl
936 << " p.x() = " << p.x()/mm << " mm" << G4endl
937 << " p.y() = " << p.y()/mm << " mm" << G4endl
938 << " p.z() = " << p.z()/mm << " mm";
939 message.precision(oldprc) ;
940 G4Exception("G4Paraboloid::DistanceToOut(p)", "GeomSolids1002",
941 JustWarning, message);
942 }
943#endif
944
945 rho = p.perp();
946 safeZ = dz - std::fabs(p.z()) ;
947
948 tanRMax = (r2 - r1)*0.5/dz ;
949 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
950 pRMax = tanRMax*p.z() + (r1+r2)*0.5 ;
951 safeR = (pRMax - rho)/secRMax ;
952
953 if (safeZ < safeR) { safe = safeZ; }
954 else { safe = safeR; }
955 if ( safe < 0.5 * kCarTolerance ) { safe = 0; }
956 return safe ;
957}
G4DLLIMPORT std::ostream G4cout
double perp() const
void DumpInfo() const
@ kOutside
Definition: geomdefs.hh:58

◆ DistanceToOut() [2/2]

G4double G4Paraboloid::DistanceToOut ( const G4ThreeVector p,
const G4ThreeVector v,
const G4bool  calcNorm = G4bool(false),
G4bool validNorm = 0,
G4ThreeVector n = 0 
) const
virtual

Implements G4VSolid.

Definition at line 611 of file G4Paraboloid.cc.

616{
617 G4double rho2 = p.perp2(), paraRho2 = std::fabs(k1 * p.z() + k2);
618 G4double vRho2 = v.perp2(), intersection;
620 G4double tolh = 0.5*kCarTolerance;
621
622 if(calcNorm) { *validNorm = false; }
623
624 // We have that the particle p follows the line x = p + s * v
625 // meaning x = p.x() + s * v.x(), y = p.y() + s * v.y() and
626 // z = p.z() + s * v.z()
627 // The equation for all points on the surface (surface expanded for
628 // to include all z) x^2 + y^2 = k1 * z + k2 => .. =>
629 // => s = (A +- std::sqrt(A^2 + B)) / vRho2
630 // where:
631 //
632 G4double A = k1 / 2 * v.z() - p.x() * v.x() - p.y() * v.y();
633 //
634 // and:
635 //
636 G4double B = (-rho2 + paraRho2) * vRho2;
637
638 if ( rho2 < paraRho2 && sqr(rho2 - paraRho2 - 0.25 * tol2) > tol2 * paraRho2
639 && std::fabs(p.z()) < dz - kCarTolerance)
640 {
641 // Make sure it's safely inside.
642
643 if(v.z() > 0)
644 {
645 // It's heading upwards, check where it colides with the plane z = dz.
646 // When it does, is that in the surface of the paraboloid.
647 // z = p.z() + variable * v.z() for all points the particle can go.
648 // => variable = (z - p.z()) / v.z() so intersection must be:
649
650 intersection = (dz - p.z()) / v.z();
651 G4ThreeVector ip = p + intersection * v; // Point of intersection.
652
653 if(ip.perp2() < sqr(r2 + kCarTolerance))
654 {
655 if(calcNorm)
656 {
657 *n = G4ThreeVector(0, 0, 1);
658 if(r2 < tolh || ip.perp2() > sqr(r2 - tolh))
659 {
660 *n += G4ThreeVector(ip.x(), ip.y(), - k1 / 2).unit();
661 *n = n->unit();
662 }
663 *validNorm = true;
664 }
665 return intersection;
666 }
667 }
668 else if(v.z() < 0)
669 {
670 // It's heading downwards, check were it colides with the plane z = -dz.
671 // When it does, is that in the surface of the paraboloid.
672 // z = p.z() + variable * v.z() for all points the particle can go.
673 // => variable = (z - p.z()) / v.z() so intersection must be:
674
675 intersection = (-dz - p.z()) / v.z();
676 G4ThreeVector ip = p + intersection * v; // Point of intersection.
677
678 if(ip.perp2() < sqr(r1 + tolh))
679 {
680 if(calcNorm)
681 {
682 *n = G4ThreeVector(0, 0, -1);
683 if(r1 < tolh || ip.perp2() > sqr(r1 - tolh))
684 {
685 *n += G4ThreeVector(ip.x(), ip.y(), - k1 / 2).unit();
686 *n = n->unit();
687 }
688 *validNorm = true;
689 }
690 return intersection;
691 }
692 }
693
694 // Now check for collisions with paraboloid surface.
695
696 if(vRho2 == 0) // Needs to be treated seperately.
697 {
698 intersection = ((rho2 - k2)/k1 - p.z())/v.z();
699 if(calcNorm)
700 {
701 G4ThreeVector intersectionP = p + v * intersection;
702 *n = G4ThreeVector(intersectionP.x(), intersectionP.y(), -k1/2);
703 *n = n->unit();
704
705 *validNorm = true;
706 }
707 return intersection;
708 }
709 else if( ((A <= 0) && (B >= sqr(A) * (sqr(vRho2) - 1))) || (A >= 0))
710 {
711 // intersection = (A + std::sqrt(B + sqr(A))) / vRho2;
712 // The above calculation has a precision problem:
713 // known problem of solving quadratic equation with small A
714
715 A = A/vRho2;
716 B = (k1 * p.z() + k2 - rho2)/vRho2;
717 intersection = B/(-A + std::sqrt(B + sqr(A)));
718 if(calcNorm)
719 {
720 G4ThreeVector intersectionP = p + v * intersection;
721 *n = G4ThreeVector(intersectionP.x(), intersectionP.y(), -k1/2);
722 *n = n->unit();
723 *validNorm = true;
724 }
725 return intersection;
726 }
727 std::ostringstream message;
728 message << "There is no intersection between given line and solid!"
729 << G4endl
730 << " p = " << p << G4endl
731 << " v = " << v;
732 G4Exception("G4Paraboloid::DistanceToOut(p,v,...)", "GeomSolids1002",
733 JustWarning, message);
734
735 return kInfinity;
736 }
737 else if ( (rho2 < paraRho2 + kCarTolerance
738 || sqr(rho2 - paraRho2 - 0.25 * tol2) < tol2 * paraRho2 )
739 && std::fabs(p.z()) < dz + tolh)
740 {
741 // If this is true we're somewhere in the border.
742
743 G4ThreeVector normal = G4ThreeVector (p.x(), p.y(), -k1/2);
744
745 if(std::fabs(p.z()) > dz - tolh)
746 {
747 // We're in the lower or upper edge
748 //
749 if( ((v.z() > 0) && (p.z() > 0)) || ((v.z() < 0) && (p.z() < 0)) )
750 { // If we're heading out of the object that is treated here
751 if(calcNorm)
752 {
753 *validNorm = true;
754 if(p.z() > 0)
755 { *n = G4ThreeVector(0, 0, 1); }
756 else
757 { *n = G4ThreeVector(0, 0, -1); }
758 }
759 return 0;
760 }
761
762 if(v.z() == 0)
763 {
764 // Case where we're moving inside the surface needs to be
765 // treated separately.
766 // Distance until it goes out through a side is returned.
767
768 G4double r = (p.z() > 0)? r2 : r1;
769 G4double pDotV = p.dot(v);
770 A = vRho2 * ( sqr(r) - sqr(p.x()) - sqr(p.y()));
771 intersection = (-pDotV + std::sqrt(A + sqr(pDotV))) / vRho2;
772
773 if(calcNorm)
774 {
775 *validNorm = true;
776
777 *n = (G4ThreeVector(0, 0, p.z()/std::fabs(p.z()))
778 + G4ThreeVector(p.x() + v.x() * intersection, p.y() + v.y()
779 * intersection, -k1/2).unit()).unit();
780 }
781 return intersection;
782 }
783 }
784 //
785 // Problem in the Logic :: Following condition for point on upper surface
786 // and Vz<0 will return 0 (Problem #1015), but
787 // it has to return intersection with parabolic
788 // surface or with lower plane surface (z = -dz)
789 // The logic has to be :: If not found intersection until now,
790 // do not exit but continue to search for possible intersection.
791 // Only for point situated on both borders (Z and parabolic)
792 // this condition has to be taken into account and done later
793 //
794 //
795 // else if(normal.dot(v) >= 0)
796 // {
797 // if(calcNorm)
798 // {
799 // *validNorm = true;
800 // *n = normal.unit();
801 // }
802 // return 0;
803 // }
804
805 if(v.z() > 0)
806 {
807 // Check for collision with upper edge.
808
809 intersection = (dz - p.z()) / v.z();
810 G4ThreeVector ip = p + intersection * v;
811
812 if(ip.perp2() < sqr(r2 - tolh))
813 {
814 if(calcNorm)
815 {
816 *validNorm = true;
817 *n = G4ThreeVector(0, 0, 1);
818 }
819 return intersection;
820 }
821 else if(ip.perp2() < sqr(r2 + tolh))
822 {
823 if(calcNorm)
824 {
825 *validNorm = true;
826 *n = G4ThreeVector(0, 0, 1)
827 + G4ThreeVector(ip.x(), ip.y(), - k1 / 2).unit();
828 *n = n->unit();
829 }
830 return intersection;
831 }
832 }
833 if( v.z() < 0)
834 {
835 // Check for collision with lower edge.
836
837 intersection = (-dz - p.z()) / v.z();
838 G4ThreeVector ip = p + intersection * v;
839
840 if(ip.perp2() < sqr(r1 - tolh))
841 {
842 if(calcNorm)
843 {
844 *validNorm = true;
845 *n = G4ThreeVector(0, 0, -1);
846 }
847 return intersection;
848 }
849 else if(ip.perp2() < sqr(r1 + tolh))
850 {
851 if(calcNorm)
852 {
853 *validNorm = true;
854 *n = G4ThreeVector(0, 0, -1)
855 + G4ThreeVector(ip.x(), ip.y(), - k1 / 2).unit();
856 *n = n->unit();
857 }
858 return intersection;
859 }
860 }
861
862 // Note: comparison with zero below would not be correct !
863 //
864 if(std::fabs(vRho2) > tol2) // precision error in the calculation of
865 { // intersection = (A+std::sqrt(B+sqr(A)))/vRho2
866 A = A/vRho2;
867 B = (k1 * p.z() + k2 - rho2);
868 if(std::fabs(B)>kCarTolerance)
869 {
870 B = (B)/vRho2;
871 intersection = B/(-A + std::sqrt(B + sqr(A)));
872 }
873 else // Point is On both borders: Z and parabolic
874 { // solution depends on normal.dot(v) sign
875 if(normal.dot(v) >= 0)
876 {
877 if(calcNorm)
878 {
879 *validNorm = true;
880 *n = normal.unit();
881 }
882 return 0;
883 }
884 intersection = 2.*A;
885 }
886 }
887 else
888 {
889 intersection = ((rho2 - k2) / k1 - p.z()) / v.z();
890 }
891
892 if(calcNorm)
893 {
894 *validNorm = true;
895 *n = G4ThreeVector(p.x() + intersection * v.x(), p.y()
896 + intersection * v.y(), - k1 / 2);
897 *n = n->unit();
898 }
899 return intersection;
900 }
901 else
902 {
903#ifdef G4SPECSDEBUG
904 if(kOutside == Inside(p))
905 {
906 G4Exception("G4Paraboloid::DistanceToOut(p,v,...)", "GeomSolids1002",
907 JustWarning, "Point p is outside!");
908 }
909 else
910 G4Exception("G4Paraboloid::DistanceToOut(p,v,...)", "GeomSolids1002",
911 JustWarning, "There's an error in this functions code.");
912#endif
913 return kInfinity;
914 }
915 return 0;
916}
Hep3Vector unit() const
double dot(const Hep3Vector &) const

◆ GetCubicVolume()

G4double G4Paraboloid::GetCubicVolume ( )
inlinevirtual

Reimplemented from G4VSolid.

◆ GetEntityType()

G4GeometryType G4Paraboloid::GetEntityType ( ) const
virtual

Implements G4VSolid.

Definition at line 963 of file G4Paraboloid.cc.

964{
965 return G4String("G4Paraboloid");
966}

◆ GetPointOnSurface()

G4ThreeVector G4Paraboloid::GetPointOnSurface ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1002 of file G4Paraboloid.cc.

1003{
1004 G4double A = (fSurfaceArea == 0)? CalculateSurfaceArea(): fSurfaceArea;
1005 G4double z = RandFlat::shoot(0.,1.);
1006 G4double phi = RandFlat::shoot(0., twopi);
1007 if(pi*(sqr(r1) + sqr(r2))/A >= z)
1008 {
1009 G4double rho;
1010 if(pi * sqr(r1) / A > z)
1011 {
1012 rho = r1 * std::sqrt(RandFlat::shoot(0., 1.));
1013 return G4ThreeVector(rho * std::cos(phi), rho * std::sin(phi), -dz);
1014 }
1015 else
1016 {
1017 rho = r2 * std::sqrt(RandFlat::shoot(0., 1));
1018 return G4ThreeVector(rho * std::cos(phi), rho * std::sin(phi), dz);
1019 }
1020 }
1021 else
1022 {
1023 z = RandFlat::shoot(0., 1.)*2*dz - dz;
1024 return G4ThreeVector(std::sqrt(z*k1 + k2)*std::cos(phi),
1025 std::sqrt(z*k1 + k2)*std::sin(phi), z);
1026 }
1027}
static double shoot()
Definition: RandFlat.cc:59
G4double CalculateSurfaceArea() const

◆ GetPolyhedron()

G4Polyhedron * G4Paraboloid::GetPolyhedron ( ) const
virtual

Reimplemented from G4VSolid.

Definition at line 1162 of file G4Paraboloid.cc.

1163{
1164 if (!fpPolyhedron ||
1167 {
1168 delete fpPolyhedron;
1170 }
1171 return fpPolyhedron;
1172}
G4Polyhedron * CreatePolyhedron() const
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
static G4int GetNumberOfRotationSteps()

◆ GetRadiusMinusZ()

G4double G4Paraboloid::GetRadiusMinusZ ( ) const
inline

◆ GetRadiusPlusZ()

G4double G4Paraboloid::GetRadiusPlusZ ( ) const
inline

◆ GetSurfaceArea()

G4double G4Paraboloid::GetSurfaceArea ( )
inlinevirtual

Reimplemented from G4VSolid.

◆ GetZHalfLength()

G4double G4Paraboloid::GetZHalfLength ( ) const
inline

◆ Inside()

EInside G4Paraboloid::Inside ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 306 of file G4Paraboloid.cc.

307{
308 // First check is the point is above or below the solid.
309 //
310 if(std::fabs(p.z()) > dz + 0.5 * kCarTolerance) { return kOutside; }
311
312 G4double rho2 = p.perp2(),
313 rhoSurfTimesTol2 = (k1 * p.z() + k2) * sqr(kCarTolerance),
314 A = rho2 - ((k1 *p.z() + k2) + 0.25 * kCarTolerance * kCarTolerance);
315
316 if(A < 0 && sqr(A) > rhoSurfTimesTol2)
317 {
318 // Actually checking rho < radius of paraboloid at z = p.z().
319 // We're either inside or in lower/upper cutoff area.
320
321 if(std::fabs(p.z()) > dz - 0.5 * kCarTolerance)
322 {
323 // We're in the upper/lower cutoff area, sides have a paraboloid shape
324 // maybe further checks should be made to make these nicer
325
326 return kSurface;
327 }
328 else
329 {
330 return kInside;
331 }
332 }
333 else if(A <= 0 || sqr(A) < rhoSurfTimesTol2)
334 {
335 // We're in the parabolic surface.
336
337 return kSurface;
338 }
339 else
340 {
341 return kOutside;
342 }
343}
@ kSurface
Definition: geomdefs.hh:58

Referenced by DistanceToIn(), and DistanceToOut().

◆ operator=()

G4Paraboloid & G4Paraboloid::operator= ( const G4Paraboloid rhs)

Definition at line 124 of file G4Paraboloid.cc.

125{
126 // Check assignment to self
127 //
128 if (this == &rhs) { return *this; }
129
130 // Copy base class data
131 //
133
134 // Copy data
135 //
136 fpPolyhedron = 0;
137 fSurfaceArea = rhs.fSurfaceArea; fCubicVolume = rhs.fCubicVolume;
138 dz = rhs.dz; r1 = rhs.r1; r2 = rhs.r2; k1 = rhs.k1; k2 = rhs.k2;
139
140 return *this;
141}
G4VSolid & operator=(const G4VSolid &rhs)
Definition: G4VSolid.cc:110

◆ SetRadiusMinusZ()

void G4Paraboloid::SetRadiusMinusZ ( G4double  R1)
inline

◆ SetRadiusPlusZ()

void G4Paraboloid::SetRadiusPlusZ ( G4double  R2)
inline

◆ SetZHalfLength()

void G4Paraboloid::SetZHalfLength ( G4double  dz)
inline

◆ StreamInfo()

std::ostream & G4Paraboloid::StreamInfo ( std::ostream &  os) const
virtual

Implements G4VSolid.

Definition at line 981 of file G4Paraboloid.cc.

982{
983 G4int oldprc = os.precision(16);
984 os << "-----------------------------------------------------------\n"
985 << " *** Dump for solid - " << GetName() << " ***\n"
986 << " ===================================================\n"
987 << " Solid type: G4Paraboloid\n"
988 << " Parameters: \n"
989 << " z half-axis: " << dz/mm << " mm \n"
990 << " radius at -dz: " << r1/mm << " mm \n"
991 << " radius at dz: " << r2/mm << " mm \n"
992 << "-----------------------------------------------------------\n";
993 os.precision(oldprc);
994
995 return os;
996}

◆ SurfaceNormal()

G4ThreeVector G4Paraboloid::SurfaceNormal ( const G4ThreeVector p) const
virtual

Implements G4VSolid.

Definition at line 348 of file G4Paraboloid.cc.

349{
350 G4ThreeVector n(0, 0, 0);
351 if(std::fabs(p.z()) > dz + 0.5 * kCarTolerance)
352 {
353 // If above or below just return normal vector for the cutoff plane.
354
355 n = G4ThreeVector(0, 0, p.z()/std::fabs(p.z()));
356 }
357 else if(std::fabs(p.z()) > dz - 0.5 * kCarTolerance)
358 {
359 // This means we're somewhere in the plane z = dz or z = -dz.
360 // (As far as the program is concerned anyway.
361
362 if(p.z() < 0) // Are we in upper or lower plane?
363 {
364 if(p.perp2() > sqr(r1 + 0.5 * kCarTolerance))
365 {
366 n = G4ThreeVector(p.x(), p.y(), -k1 / 2).unit();
367 }
368 else if(r1 < 0.5 * kCarTolerance
369 || p.perp2() > sqr(r1 - 0.5 * kCarTolerance))
370 {
371 n = G4ThreeVector(p.x(), p.y(), 0.).unit()
372 + G4ThreeVector(0., 0., -1.).unit();
373 n = n.unit();
374 }
375 else
376 {
377 n = G4ThreeVector(0., 0., -1.);
378 }
379 }
380 else
381 {
382 if(p.perp2() > sqr(r2 + 0.5 * kCarTolerance))
383 {
384 n = G4ThreeVector(p.x(), p.y(), 0.).unit();
385 }
386 else if(r2 < 0.5 * kCarTolerance
387 || p.perp2() > sqr(r2 - 0.5 * kCarTolerance))
388 {
389 n = G4ThreeVector(p.x(), p.y(), 0.).unit()
390 + G4ThreeVector(0., 0., 1.).unit();
391 n = n.unit();
392 }
393 else
394 {
395 n = G4ThreeVector(0., 0., 1.);
396 }
397 }
398 }
399 else
400 {
401 G4double rho2 = p.perp2();
402 G4double rhoSurfTimesTol2 = (k1 * p.z() + k2) * sqr(kCarTolerance);
403 G4double A = rho2 - ((k1 *p.z() + k2)
404 + 0.25 * kCarTolerance * kCarTolerance);
405
406 if(A < 0 && sqr(A) > rhoSurfTimesTol2)
407 {
408 // Actually checking rho < radius of paraboloid at z = p.z().
409 // We're inside.
410
411 if(p.mag2() != 0) { n = p.unit(); }
412 }
413 else if(A <= 0 || sqr(A) < rhoSurfTimesTol2)
414 {
415 // We're in the parabolic surface.
416
417 n = G4ThreeVector(p.x(), p.y(), - k1 / 2).unit();
418 }
419 else
420 {
421 n = G4ThreeVector(p.x(), p.y(), - k1 / 2).unit();
422 }
423 }
424
425 if(n.mag2() == 0)
426 {
427 std::ostringstream message;
428 message << "No normal defined for this point p." << G4endl
429 << " p = " << 1 / mm * p << " mm";
430 G4Exception("G4Paraboloid::SurfaceNormal(p)", "GeomSolids1002",
431 JustWarning, message);
432 }
433 return n;
434}
double mag2() const

Member Data Documentation

◆ fpPolyhedron

G4Polyhedron* G4Paraboloid::fpPolyhedron
mutableprotected

Definition at line 140 of file G4Paraboloid.hh.

Referenced by GetPolyhedron(), and operator=().


The documentation for this class was generated from the following files: