36#if !(defined(G4GEOM_USE_UPARABOLOID) && defined(G4GEOM_USE_SYS_USOLIDS))
66 if( (pDz <= 0.) || (pR2 <= pR1) || (pR1 < 0.) )
68 std::ostringstream message;
69 message <<
"Invalid dimensions. Negative Input Values or R1>=R2 - "
71 G4Exception(
"G4Paraboloid::G4Paraboloid()",
"GeomSolids0002",
73 "Z half-length must be larger than zero or R1>=R2.");
85 k1 = (r2 * r2 - r1 * r1) / 2 / dz;
86 k2 = (r2 * r2 + r1 * r1) / 2;
88 fSurfaceArea = CalculateSurfaceArea();
107 delete fpPolyhedron; fpPolyhedron =
nullptr;
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;
139 fRebuildPolyhedron =
false;
140 delete fpPolyhedron; fpPolyhedron =
nullptr;
153 G4Exception(
"G4Paraboloid::SetZHalfLength()",
"GeomSolids0002",
159 k1 = (
sqr(r2) -
sqr(r1)) / (2 * dz);
160 k2 = (
sqr(r2) +
sqr(r1)) / 2;
161 fSurfaceArea = CalculateSurfaceArea();
163 fRebuildPolyhedron =
true;
173 if(pR2 <= 0 || pR2 <= r1)
175 G4Exception(
"G4Paraboloid::SetRadiusPlusZ()",
"GeomSolids0002",
181 k1 = (
sqr(r2) -
sqr(r1)) / (2 * dz);
182 k2 = (
sqr(r2) +
sqr(r1)) / 2;
183 fSurfaceArea = CalculateSurfaceArea();
185 fRebuildPolyhedron =
true;
195 if(pR1 < 0 || pR1 >= r2)
197 G4Exception(
"G4Paraboloid::SetRadiusMinusZ()",
"GeomSolids0002",
203 k1 = (
sqr(r2) -
sqr(r1)) / (2 * dz);
204 k2 = (
sqr(r2) +
sqr(r1)) / 2;
205 fSurfaceArea = CalculateSurfaceArea();
207 fRebuildPolyhedron =
true;
215G4double G4Paraboloid::CalculateSurfaceArea()
const
220 Amax *= std::sqrt(Amax);
221 Amax = CLHEP::pi * r2 / 6 /
sqr(hmax) * (Amax - r2 * r2 * r2);
228 Amin =
sqr(r1) + 4*
sqr(hmin);
229 Amin *= std::sqrt(Amin);
230 Amin = CLHEP::pi * r1 / 6 /
sqr(hmin) * (Amin - r1 * r1 * r1);
233 return Amax - Amin + (
sqr(r1) +
sqr(r2))*CLHEP::pi;
242 if (fSurfaceArea == 0)
245 fSurfaceArea = CalculateSurfaceArea();
257 if(fCubicVolume == 0)
260 fCubicVolume = CLHEP::pi * (
sqr(r1) +
sqr(r2)) * dz;
273 pMin.
set(-r2,-r2,-dz);
274 pMax.
set( r2, r2, dz);
278 if (pMin.
x() >= pMax.
x() || pMin.
y() >= pMax.
y() || pMin.
z() >= pMax.
z())
280 std::ostringstream message;
281 message <<
"Bad bounding box (min >= max) for solid: "
283 <<
"\npMin = " << pMin
284 <<
"\npMax = " << pMax;
285 G4Exception(
"G4Paraboloid::BoundingLimits()",
"GeomMgt0001",
325 if(
A < 0 &&
sqr(
A) > rhoSurfTimesTol2)
339 if(
A <= 0 ||
sqr(
A) < rhoSurfTimesTol2)
411 if(
A < 0 &&
sqr(
A) > rhoSurfTimesTol2)
418 else if(
A <= 0 ||
sqr(
A) < rhoSurfTimesTol2)
432 std::ostringstream message;
433 message <<
"No normal defined for this point p." <<
G4endl
434 <<
" p = " << 1 / mm * p <<
" mm";
435 G4Exception(
"G4Paraboloid::SurfaceNormal(p)",
"GeomSolids1002",
454 if((r2 != 0.0) && p.
z() > - tolh + dz)
461 if(
sqr(p.
x() + v.
x()*intersection)
464 if(p.
z() < tolh + dz) {
return 0; }
473 else if((r1 != 0.0) && p.
z() < tolh - dz)
479 G4double intersection = (-dz - p.
z()) / v.
z();
480 if(
sqr(p.
x() + v.
x()*intersection)
483 if(p.
z() > -tolh - dz) {
return 0; }
494 vRho2 = v.
perp2(), intersection,
495 B = (k1 * p.
z() + k2 - rho2) * vRho2;
497 if ( ( (rho2 > paraRho2) && (
sqr(rho2-paraRho2-0.25*tol2) > tol2*paraRho2) )
505 intersection = ((rho2 - k2)/k1 - p.
z())/v.
z();
506 if(intersection < 0) {
return kInfinity; }
507 if(std::fabs(p.
z() + v.
z() * intersection) <= dz) {
return intersection; }
516 intersection = (
A - std::sqrt(
B +
sqr(
A))) / vRho2;
522 if(std::fabs(p.
z() + intersection * v.
z()) < dz + tolh)
529 if(
sqr(rho2 - paraRho2 - .25 * tol2) <= tol2 * paraRho2)
534 if(normal.dot(v) <= 0) {
return 0; }
539 std::ostringstream message;
546 message <<
"Likely a problem in this function, for solid: " <<
GetName()
549 message <<
" p = " << p * (1/mm) <<
" mm" <<
G4endl
550 <<
" v = " << v * (1/mm) <<
" mm";
551 G4Exception(
"G4Paraboloid::DistanceToIn(p,v)",
"GeomSolids1002",
564 if(safz<0.) { safz=0.; }
574 if(safr>safz) { safz=safr; }
578 G4double sqprho = std::sqrt(paraRho);
580 if(dRho<0.) {
return safz; }
584 if(tmp<0.) {
return safz; }
586 G4double salf = talf/std::sqrt(tmp);
587 safr = std::fabs(dRho*salf);
588 if(safr>safz) { safz=safr; }
608 if(calcNorm) { *validNorm =
false; }
624 if ( rho2 < paraRho2 &&
sqr(rho2 - paraRho2 - 0.25 * tol2) > tol2 * paraRho2
636 intersection = (dz - p.
z()) / v.
z();
644 if(r2 < tolh || ip.
perp2() >
sqr(r2 - tolh))
661 intersection = (-dz - p.
z()) / v.
z();
669 if(r1 < tolh || ip.
perp2() >
sqr(r1 - tolh))
684 intersection = ((rho2 - k2)/k1 - p.
z())/v.
z();
695 if( ((
A <= 0) && (
B >=
sqr(
A) * (
sqr(vRho2) - 1))) || (
A >= 0))
702 B = (k1 * p.
z() + k2 - rho2)/vRho2;
703 intersection =
B/(-
A + std::sqrt(
B +
sqr(
A)));
713 std::ostringstream message;
714 message <<
"There is no intersection between given line and solid!"
718 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
724 ||
sqr(rho2 - paraRho2 - 0.25 * tol2) < tol2 * paraRho2 )
725 && std::fabs(p.
z()) < dz + tolh)
731 if(std::fabs(p.
z()) > dz - tolh)
735 if( ((v.
z() > 0) && (p.
z() > 0)) || ((v.
z() < 0) && (p.
z() < 0)) )
757 intersection = (-pDotV + std::sqrt(
A +
sqr(pDotV))) / vRho2;
765 * intersection, -k1/2).
unit()).unit();
795 intersection = (dz - p.
z()) / v.
z();
823 intersection = (-dz - p.
z()) / v.
z();
850 if(std::fabs(vRho2) > tol2)
853 B = (k1 * p.
z() + k2 - rho2);
857 intersection =
B/(-
A + std::sqrt(
B +
sqr(
A)));
861 if(normal.dot(v) >= 0)
875 intersection = ((rho2 - k2) / k1 - p.
z()) / v.
z();
882 + intersection * v.
y(), - k1 / 2);
891 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
894 G4Exception(
"G4Paraboloid::DistanceToOut(p,v,...)",
"GeomSolids1002",
895 JustWarning,
"There's an error in this functions code.");
914 std::ostringstream message;
915 G4long oldprc = message.precision(16);
916 message <<
"Point p is outside !?" <<
G4endl
918 <<
" p.x() = " << p.
x()/mm <<
" mm" <<
G4endl
919 <<
" p.y() = " << p.
y()/mm <<
" mm" <<
G4endl
920 <<
" p.z() = " << p.
z()/mm <<
" mm";
921 message.precision(oldprc) ;
922 G4Exception(
"G4Paraboloid::DistanceToOut(p)",
"GeomSolids1002",
928 safeZ = dz - std::fabs(p.
z()) ;
930 tanRMax = (r2 - r1)*0.5/dz ;
931 secRMax = std::sqrt(1.0 + tanRMax*tanRMax) ;
932 pRMax = tanRMax*p.
z() + (r1+r2)*0.5 ;
933 safeR = (pRMax - rho)/secRMax ;
935 if (safeZ < safeR) { safe = safeZ; }
936 else { safe = safeR; }
947 return {
"G4Paraboloid"};
965 G4long oldprc = os.precision(16);
966 os <<
"-----------------------------------------------------------\n"
967 <<
" *** Dump for solid - " <<
GetName() <<
" ***\n"
968 <<
" ===================================================\n"
969 <<
" Solid type: G4Paraboloid\n"
971 <<
" z half-axis: " << dz/mm <<
" mm \n"
972 <<
" radius at -dz: " << r1/mm <<
" mm \n"
973 <<
" radius at dz: " << r2/mm <<
" mm \n"
974 <<
"-----------------------------------------------------------\n";
975 os.precision(oldprc);
989 if (select < pi*(
sqr(r1) +
sqr(r2)))
991 if(select < pi*
sqr(r1))
1005 G4double mu_max = dz*k1 + k2 + 0.25*k1;
1006 for (
auto i = 0; i < 10000; ++i)
1012 rho = std::sqrt(z*k1 + k2);
1014 return { rho*std::cos(phi), rho*std::sin(phi), z };
1033 if (fpPolyhedron ==
nullptr ||
1034 fRebuildPolyhedron ||
1035 fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
1036 fpPolyhedron->GetNumberOfRotationSteps())
1039 delete fpPolyhedron;
1041 fRebuildPolyhedron =
false;
1044 return fpPolyhedron;
G4TemplateAutoLock< G4Mutex > G4AutoLock
G4double B(G4double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4QuickRand(uint32_t seed=0)
#define G4MUTEX_INITIALIZER
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
void set(double x, double y, double z)
G4BoundingEnvelope is a helper class to facilitate calculation of the extent of a solid within the li...
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimits, const G4Transform3D &pTransform3D, G4double &pMin, G4double &pMax) const
G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const override
G4ThreeVector GetPointOnSurface() const override
G4VSolid * Clone() const override
G4double GetSurfaceArea() override
G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const override
std::ostream & StreamInfo(std::ostream &os) const override
G4Polyhedron * GetPolyhedron() const override
void SetZHalfLength(G4double dz)
G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pmin, G4double &pmax) const override
G4double GetCubicVolume() override
G4Paraboloid(const G4String &pName, G4double pDz, G4double pR1, G4double pR2)
void SetRadiusPlusZ(G4double R2)
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 SetRadiusMinusZ(G4double R1)
void DescribeYourselfTo(G4VGraphicsScene &scene) const override
virtual void AddSolid(const G4Box &)=0
G4VSolid(const G4String &name)
G4VSolid & operator=(const G4VSolid &rhs)
G4VoxelLimits represents limitation/restrictions of space, where restrictions are only made perpendic...