Files
geant4/source/geometry/solids/usolids/include/UTubs.icc
T
2016-06-10 11:51:14 +02:00

268 lines
5.5 KiB
Plaintext

//
// ********************************************************************
// * 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;
}