Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-17 08:35:34

0001 #ifndef VECGEOM_SURFACE_TUBECONVERTER_H_
0002 #define VECGEOM_SURFACE_TUBECONVERTER_H_
0003 
0004 #include <VecGeom/surfaces/conv/Builder.h>
0005 #include <VecGeom/surfaces/Model.h>
0006 
0007 #include <VecGeom/volumes/Tube.h>
0008 
0009 namespace vgbrep {
0010 namespace conv {
0011 
0012 /// @brief Converter for Tube
0013 /// @tparam Real_t Precision type
0014 /// @param tube Tube solid to be converted
0015 /// @param logical_id Id of the logical volume
0016 /// @return Conversion success
0017 template <typename Real_t>
0018 bool CreateTubeSurfaces(vecgeom::UnplacedTube const &tube, int logical_id, bool intersection = false)
0019 {
0020   using RingMask_t   = RingMask<Real_t>;
0021   using ZPhiMask_t   = ZPhiMask<Real_t>;
0022   using WindowMask_t = WindowMask<Real_t>;
0023 
0024   LogicExpressionCPU logic; // top & bottom & [rmin] & rmax & (dphi < 180) ? sphi * ephi : sphi | ephi
0025   auto sphi = tube.sphi();
0026   auto dphi = tube.dphi();
0027   auto ephi = tube.sphi() + tube.dphi();
0028 
0029   VECGEOM_ASSERT(dphi > vecgeom::kTolerance);
0030 
0031   auto Rmean = (tube.rmin() + tube.rmax()) / 2;
0032   auto Rdiff = (tube.rmax() - tube.rmin()) / 2;
0033 
0034   VECGEOM_ASSERT(Rdiff > 0);
0035 
0036   bool fullCirc  = ApproxEqual(dphi, vecgeom::kTwoPi);
0037   bool smallerPi = dphi < (vecgeom::kPi - vecgeom::kTolerance);
0038 
0039   int isurf;
0040   vecgeom::Precision surfdata[2];
0041 
0042   // We need angles in degrees for transformations
0043   auto sphid = vecgeom::kRadToDeg * sphi;
0044   auto ephid = vecgeom::kRadToDeg * ephi;
0045   vecgeom::Transformation3DMP<Real_t> identity;
0046 
0047   // surface at +dz
0048   isurf = builder::CreateLocalSurface<Real_t>(
0049       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0050       builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{tube.rmin(), tube.rmax(), fullCirc, sphi, ephi}),
0051       vecgeom::Transformation3DMP<Precision>(0., 0., tube.z(), 0., 0., 0.));
0052   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0053   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0054   logic.push_back(isurf);
0055   // surface at -dz
0056   isurf = builder::CreateLocalSurface<Real_t>(
0057       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0058       builder::CreateFrame<Real_t>(FrameType::kRing, RingMask_t{tube.rmin(), tube.rmax(), fullCirc, sphi, ephi}),
0059       vecgeom::Transformation3DMP<Precision>(0., 0., -tube.z(), 0., 180., -sphid - ephid));
0060   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0061   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0062   logic.push_back(land);
0063   logic.push_back(isurf);
0064   // inner cylinder
0065   if (tube.rmin() > vecgeom::kTolerance) {
0066     surfdata[0] = tube.rmin();
0067     isurf       = builder::CreateLocalSurface<Real_t>(
0068         builder::CreateUnplacedSurface<Real_t>(SurfaceType::kCylindrical, surfdata, /*flipped=*/true),
0069         builder::CreateFrame<Real_t>(FrameType::kZPhi,
0070                                      ZPhiMask_t{-tube.z(), tube.z(), fullCirc, tube.rmin(), tube.rmin(), sphi, ephi}),
0071         /*identity transformation*/ identity);
0072     builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0073     if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0074     logic.push_back(land);
0075     logic.push_back(isurf);
0076   }
0077   // outer cylinder
0078   surfdata[0] = tube.rmax();
0079   isurf       = builder::CreateLocalSurface<Real_t>(
0080       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kCylindrical, surfdata),
0081       builder::CreateFrame<Real_t>(FrameType::kZPhi,
0082                                    ZPhiMask_t{-tube.z(), tube.z(), fullCirc, tube.rmax(), tube.rmax(), sphi, ephi}),
0083       /*identity transformation*/ identity);
0084   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0085   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0086   logic.push_back(land);
0087   logic.push_back(isurf);
0088 
0089   if (ApproxEqual(dphi, vecgeom::kTwoPi)) {
0090     builder::AddLogicToShell<Real_t>(logical_id, logic);
0091     return true;
0092   }
0093   // plane cap at Sphi
0094   isurf = builder::CreateLocalSurface<Real_t>(
0095       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0096       builder::CreateFrame<Real_t>(FrameType::kWindow, WindowMask_t{Rdiff, tube.z()}),
0097       vecgeom::Transformation3DMP<Precision>(Rmean * std::cos(sphi), Rmean * std::sin(sphi), 0., sphid, 90., 0.));
0098   if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0099   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0100   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0101   logic.push_back(land);
0102   logic.push_back(lplus); // '('
0103   logic.push_back(isurf);
0104 
0105   // plane cap at Sphi+Dphi
0106   isurf = builder::CreateLocalSurface<Real_t>(
0107       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0108       builder::CreateFrame<Real_t>(FrameType::kWindow, WindowMask_t{Rdiff, tube.z()}),
0109       vecgeom::Transformation3DMP<Precision>(Rmean * std::cos(ephi), Rmean * std::sin(ephi), 0., ephid, -90., 0.));
0110   if (!smallerPi) builder::GetSurface<Real_t>(isurf).fEmbedding = false;
0111   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0112   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0113   logic.push_back(smallerPi ? land : lor);
0114   logic.push_back(isurf);
0115   logic.push_back(lminus); // ')'
0116   builder::AddLogicToShell<Real_t>(logical_id, logic);
0117   return true;
0118 }
0119 
0120 } // namespace conv
0121 } // namespace vgbrep
0122 #endif