36#if !(defined(G4GEOM_USE_UPARABOLOID) && defined(G4GEOM_USE_SYS_USOLIDS))
68 if( (pDz <= 0.) || (pR2 <= pR1) || (pR1 < 0.) )
70 std::ostringstream message;
71 message <<
"Invalid dimensions. Negative Input Values or R1>=R2 - "
73 G4Exception(
"G4Paraboloid::G4Paraboloid()",
"GeomSolids0002",
75 "Z half-length must be larger than zero or R1>=R2.");
87 k1 = (r2 * r2 - r1 * r1) / 2 / dz;
88 k2 = (r2 * r2 + r1 * r1) / 2;
97 :
G4VSolid(a), dz(0.), r1(0.), r2(0.), k1(0.), k2(0.)
116 fSurfaceArea(rhs.fSurfaceArea), fCubicVolume(rhs.fCubicVolume),
117 dz(rhs.dz), r1(rhs.r1), r2(rhs.r2), k1(rhs.k1), k2(rhs.k2)
129 if (
this == &rhs) {
return *
this; }
137 fSurfaceArea = rhs.fSurfaceArea; fCubicVolume = rhs.fCubicVolume;
138 dz = rhs.dz; r1 = rhs.r1; r2 = rhs.r2; k1 = rhs.k1; k2 = rhs.k2;
152 pMin.
set(-r2,-r2,-dz);
153 pMax.
set( r2, r2, dz);
157 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
159 std::ostringstream message;
160 message <<
"Bad bounding box (min >= max) for solid: "
162 <<
"\npMin = " << pMin
163 <<
"\npMax = " << pMax;
164 G4Exception(
"G4Paraboloid::BoundingLimits()",
"GeomMgt0001",
204 if(
A < 0 &&
sqr(
A) > rhoSurfTimesTol2)
221 else if(
A <= 0 ||
sqr(
A) < rhoSurfTimesTol2)
295 if(
A < 0 &&
sqr(
A) > rhoSurfTimesTol2)
302 else if(
A <= 0 ||
sqr(
A) < rhoSurfTimesTol2)
316 std::ostringstream message;
317 message <<
"No normal defined for this point p." <<
G4endl
318 <<
" p = " << 1 / mm * p <<
" mm";
319 G4Exception(
"G4Paraboloid::SurfaceNormal(p)",
"GeomSolids1002",
338 if((r2 != 0.0) && p.
z() > - tolh + dz)
345 if(
sqr(p.
x() + v.
x()*intersection)
348 if(p.
z() < tolh + dz)
351 {
return intersection; }
359 else if((r1 != 0.0) && p.
z() < tolh - dz)
365 G4double intersection = (-dz - p.
z()) / v.
z();
366 if(
sqr(p.
x() + v.
x()*intersection)
369 if(p.
z() > -tolh - dz)
386 vRho2 = v.
perp2(), intersection,
387 B = (k1 * p.
z() + k2 - rho2) * vRho2;
389 if ( ( (rho2 > paraRho2) && (
sqr(rho2-paraRho2-0.25*tol2) > tol2*paraRho2) )
397 intersection = ((rho2 - k2)/k1 - p.
z())/v.
z();
398 if(intersection < 0) {
return kInfinity; }
399 else if(std::fabs(p.
z() + v.
z() * intersection) <= dz)
414 intersection = (
A - std::sqrt(
B +
sqr(
A))) / vRho2;
419 else if(std::fabs(p.
z() + intersection * v.
z()) < dz + tolh)
429 else if(
sqr(rho2 - paraRho2 - .25 * tol2) <= tol2 * paraRho2)
434 if(normal.
dot(v) <= 0)
437 {
return kInfinity; }
441 std::ostringstream message;
448 message <<
"Likely a problem in this function, for solid: " <<
GetName()
451 message <<
" p = " << p * (1/mm) <<
" mm" <<
G4endl
452 <<
" v = " << v * (1/mm) <<
" mm";
453 G4Exception(
"G4Paraboloid::DistanceToIn(p,v)",
"GeomSolids1002",
467 if(safz<0.) { safz=0.; }
477 if(safr>safz) { safz=safr; }
481 G4double sqprho = std::sqrt(paraRho);
483 if(dRho<0.) {
return safz; }
487 if(tmp<0.) {
return safz; }
489 G4double salf = talf/std::sqrt(tmp);
490 safr = std::fabs(dRho*salf);
491 if(safr>safz) { safz=safr; }
511 if(calcNorm) { *validNorm =
false; }
527 if ( rho2 < paraRho2 &&
sqr(rho2 - paraRho2 - 0.25 * tol2) > tol2 * paraRho2
539 intersection = (dz - p.
z()) / v.
z();
547 if(r2 < tolh || ip.
perp2() >
sqr(r2 - tolh))
564 intersection = (-dz - p.
z()) / v.
z();
572 if(r1 < tolh || ip.
perp2() >
sqr(r1 - tolh))
587 intersection = ((rho2 - k2)/k1 - p.
z())/v.
z();
598 else if( ((
A <= 0) && (
B >=
sqr(
A) * (
sqr(vRho2) - 1))) || (
A >= 0))
605 B = (k1 * p.
z() + k2 - rho2)/vRho2;
606 intersection =
B/(-
A + std::sqrt(
B +
sqr(
A)));
616 std::ostringstream message;
617 message <<
"There is no intersection between given line and solid!"
621 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
627 ||
sqr(rho2 - paraRho2 - 0.25 * tol2) < tol2 * paraRho2 )
628 && std::fabs(p.
z()) < dz + tolh)
634 if(std::fabs(p.
z()) > dz - tolh)
638 if( ((v.
z() > 0) && (p.
z() > 0)) || ((v.
z() < 0) && (p.
z() < 0)) )
660 intersection = (-pDotV + std::sqrt(
A +
sqr(pDotV))) / vRho2;
668 * intersection, -k1/2).
unit()).unit();
698 intersection = (dz - p.
z()) / v.
z();
710 else if(ip.
perp2() <
sqr(r2 + tolh))
726 intersection = (-dz - p.
z()) / v.
z();
738 else if(ip.
perp2() <
sqr(r1 + tolh))
753 if(std::fabs(vRho2) > tol2)
756 B = (k1 * p.
z() + k2 - rho2);
760 intersection =
B/(-
A + std::sqrt(
B +
sqr(
A)));
764 if(normal.
dot(v) >= 0)
778 intersection = ((rho2 - k2) / k1 - p.
z()) / v.
z();
785 + intersection * v.
y(), - k1 / 2);
795 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
799 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
800 JustWarning,
"There's an error in this functions code.");
821 std::ostringstream message;
822 G4long oldprc = message.precision(16);
823 message <<
"Point p is outside !?" <<
G4endl
825 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
826 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
827 <<
" p.z() = " << p.
z()/mm <<
" mm";
828 message.precision(oldprc) ;
829 G4Exception(
"G4Paraboloid::DistanceToOut(p)",
"GeomSolids1002",
835 safeZ = dz - std::fabs(p.
z()) ;
837 tanRMax = (r2 - r1)*0.5/dz ;
838 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
839 pRMax = tanRMax*p.
z() + (r1+r2)*0.5 ;
840 safeR = (pRMax - rho)/secRMax ;
842 if (safeZ < safeR) { safe = safeZ; }
843 else { safe = safeR; }
854 return {
"G4Paraboloid"};
872 G4long oldprc = os.precision(16);
873 os <<
"-----------------------------------------------------------\n"
874 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
875 <<
" ===================================================\n"
876 <<
" Solid type: G4Paraboloid\n"
878 <<
" z half-axis: " << dz/mm <<
" mm \n"
879 <<
" radius at -dz: " << r1/mm <<
" mm \n"
880 <<
" radius at dz: " << r2/mm <<
" mm \n"
881 <<
"-----------------------------------------------------------\n";
882 os.precision(oldprc);
894 G4double z = G4RandFlat::shoot(0.,1.);
895 G4double phi = G4RandFlat::shoot(0., twopi);
896 if(pi*(
sqr(r1) +
sqr(r2))/
A >= z)
899 if(pi *
sqr(r1) /
A > z)
901 rho = r1 * std::sqrt(G4RandFlat::shoot(0., 1.));
902 return { rho * std::cos(phi), rho * std::sin(phi), -dz };
906 rho = r2 * std::sqrt(G4RandFlat::shoot(0., 1));
907 return { rho * std::cos(phi), rho * std::sin(phi), dz };
912 z = G4RandFlat::shoot(0., 1.)*2*dz - dz;
913 return { std::sqrt(z*k1 + k2)*std::cos(phi),
914 std::sqrt(z*k1 + k2)*std::sin(phi), z};
G4double B(G4double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
void set(double x, double y, double z)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4bool fRebuildPolyhedron
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const override
G4double CalculateSurfaceArea() const
G4ThreeVector GetPointOnSurface() const override
G4VSolid * Clone() const override
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
std::ostream & StreamInfo(std::ostream &os) const override
G4Polyhedron * GetPolyhedron() const override
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
G4Paraboloid(const G4String &pName, G4double pDz, G4double pR1, G4double pR2)
G4Polyhedron * fpPolyhedron
G4GeometryType GetEntityType() const override
G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const override
G4Polyhedron * CreatePolyhedron() const override
G4Paraboloid & operator=(const G4Paraboloid &rhs)
EInside Inside(const G4ThreeVector &p) const override
void BoundingLimits(G4ThreeVector &pMin, G4ThreeVector &pMax) const override
void DescribeYourselfTo(G4VGraphicsScene &scene) const override
G4int GetNumberOfRotationStepsAtTimeOfCreation() const
virtual void AddSolid(const G4Box &)=0
G4VSolid & operator=(const G4VSolid &rhs)
static G4int GetNumberOfRotationSteps()