// // ******************************************************************** // * This Software is part of the AIDA Unified Solids Library package * // * See: https://aidasoft.web.cern.ch/USolids * // ******************************************************************** // // $Id:$ // // -------------------------------------------------------------------- // // UTubs.icc // // Implementation of inline methods of UTubs // // 19.10.12 Marek Gayer // Created from original implementation in Geant4 // -------------------------------------------------------------------- inline double UTubs::GetInnerRadius() const { return fRMin; } inline double UTubs::GetOuterRadius() const { return fRMax; } inline double UTubs::GetZHalfLength() const { return fDz; } inline double UTubs::GetStartPhiAngle() const { return fSPhi; } inline double UTubs::GetDeltaPhiAngle() const { return fDPhi; } inline void UTubs::Initialize() { fCubicVolume = 0.; fSurfaceArea = 0.; } inline void UTubs::InitializeTrigonometry() { double hDPhi = 0.5 * fDPhi; // half delta phi double cPhi = fSPhi + hDPhi; double ePhi = fSPhi + fDPhi; fSinCPhi = std::sin(cPhi); fCosCPhi = std::cos(cPhi); fCosHDPhiIT = std::cos(hDPhi - 0.5 * kAngTolerance); // inner/outer tol half dphi fCosHDPhiOT = std::cos(hDPhi + 0.5 * kAngTolerance); fSinSPhi = std::sin(fSPhi); fCosSPhi = std::cos(fSPhi); fSinEPhi = std::sin(ePhi); fCosEPhi = std::cos(ePhi); fSinSPhiDPhi = std::sin(fSPhi + fDPhi); fCosSPhiDPhi = std::cos(fSPhi + fDPhi); } inline void UTubs::CheckSPhiAngle(double sPhi) { // Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0 if (sPhi < 0) { fSPhi = 2 * UUtils::kPi - std::fmod(std::fabs(sPhi), 2 * UUtils::kPi); } else { fSPhi = std::fmod(sPhi, 2 * UUtils::kPi) ; } if (fSPhi + fDPhi > 2 * UUtils::kPi) { fSPhi -= 2 * UUtils::kPi ; } } inline void UTubs::CheckDPhiAngle(double dPhi) { fPhiFullTube = true; if (dPhi >= 2 * UUtils::kPi - kAngTolerance * 0.5) { fDPhi = 2 * UUtils::kPi; fSPhi = 0; } else { fPhiFullTube = false; if (dPhi > 0) { fDPhi = dPhi; } else { std::ostringstream message; message << "Invalid dphi." << std::endl << "Negative or zero delta-Phi (" << dPhi << "), for solid: " << GetName(); UUtils::Exception("UTubs::CheckDPhiAngle()", "GeomSolids0002", FatalError, 1, message.str().c_str()); } } } inline void UTubs::CheckPhiAngles(double sPhi, double dPhi) { CheckDPhiAngle(dPhi); if ((fDPhi < 2 * UUtils::kPi) && (sPhi)) { CheckSPhiAngle(sPhi); } InitializeTrigonometry(); } inline void UTubs::SetInnerRadius(double newRMin) { if (newRMin < 0) // Check radii { std::ostringstream message; message << "Invalid radii." << std::endl << "Invalid values for radii in solid " << GetName() << std::endl << " newRMin = " << newRMin << ", fRMax = " << fRMax << std::endl << " Negative inner radius!"; UUtils::Exception("UTubs::SetInnerRadius()", "GeomSolids0002", FatalError, 1, message.str().c_str()); } fRMin = newRMin; Initialize(); } inline void UTubs::SetOuterRadius(double newRMax) { if (newRMax <= 0) // Check radii { std::ostringstream message; message << "Invalid radii." << std::endl << "Invalid values for radii in solid " << GetName() << std::endl << " fRMin = " << fRMin << ", newRMax = " << newRMax << std::endl << " Invalid outer radius!"; UUtils::Exception("UTubs::SetOuterRadius()", "GeomSolids0002", FatalError, 1, message.str().c_str()); } fRMax = newRMax; Initialize(); } inline void UTubs::SetZHalfLength(double newDz) { if (newDz <= 0) // Check z-len { std::ostringstream message; message << "Invalid Z half-length." << std::endl << "Negative Z half-length (" << newDz << "), for solid: " << GetName(); UUtils::Exception("UTubs::SetZHalfLength()", "GeomSolids0002", FatalError, 1, message.str().c_str()); } fDz = newDz; Initialize(); } inline void UTubs::SetStartPhiAngle(double newSPhi, bool compute) { // Flag 'compute' can be used to explicitely avoid recomputation of // trigonometry in case SetDeltaPhiAngle() is invoked afterwards CheckSPhiAngle(newSPhi); fPhiFullTube = false; if (compute) { InitializeTrigonometry(); } Initialize(); } inline void UTubs::SetDeltaPhiAngle(double newDPhi) { CheckPhiAngles(fSPhi, newDPhi); Initialize(); } // Older names for access functions inline double UTubs::GetRMin() const { return GetInnerRadius(); } inline double UTubs::GetRMax() const { return GetOuterRadius(); } inline double UTubs::GetDz() const { return GetZHalfLength() ; } inline double UTubs::GetSPhi() const { return GetStartPhiAngle(); } inline double UTubs::GetDPhi() const { return GetDeltaPhiAngle(); } inline double UTubs::Capacity() { if (fCubicVolume != 0.) { ; } else { fCubicVolume = fDPhi * fDz * (fRMax * fRMax - fRMin * fRMin); } return fCubicVolume; } inline double UTubs::SurfaceArea() { if (fSurfaceArea != 0.) { ; } else { fSurfaceArea = fDPhi * (fRMin + fRMax) * (2 * fDz + fRMax - fRMin); if (!fPhiFullTube) { fSurfaceArea = fSurfaceArea + 4 * fDz * (fRMax - fRMin); } } return fSurfaceArea; }