Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef VECGEOM_SURFACE_ELLIPTICALTUBECONVERTER_H_
0002 #define VECGEOM_SURFACE_ELLIPTICALTUBECONVERTER_H_
0003 
0004 #include <VecGeom/surfaces/conv/Builder.h>
0005 #include <VecGeom/surfaces/Model.h>
0006 
0007 #include <VecGeom/volumes/EllipticalTube.h>
0008 
0009 namespace vgbrep {
0010 namespace conv {
0011 
0012 /// @brief Converter for elliptical 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 CreateEllipticalTubeSurfaces(vecgeom::UnplacedEllipticalTube const &tube, int logical_id,
0019                                   bool intersection = false)
0020 {
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 
0026   int isurf;
0027   vecgeom::Precision surfdata[3];
0028 
0029   auto &cpudata = CPUsurfData<Real_t>::Instance();
0030 
0031   // surface at +dz
0032   // due to the cut the top and bottom caps are elliptical, which is handled by using a rectangle frame
0033   // that fully contains the ellipse and making the surface logical such that the full boolean expression
0034   // must be evaluated to decide whether it is a hit or not.
0035   // As a consequence, all surfaces of this volume must be logical surfaces.
0036   isurf = builder::CreateLocalSurface<Real_t>(
0037       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0038       builder::CreateFrame<Real_t>(FrameType::kWindow, WindowMask_t{tube.GetDx(), tube.GetDy()}),
0039       vecgeom::Transformation3DMP<Precision>(0., 0., tube.GetDz(), 0., 0., 0.));
0040   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0041   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0042   builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0043   // Make the surface "logical"
0044   VECGEOM_ASSERT(isurf >= 0);
0045   cpudata.fLocalSurfaces[isurf].fLogicId = isurf;
0046   logic.push_back(isurf);
0047   logic.push_back(land);
0048 
0049   // surface at -dz
0050   isurf = builder::CreateLocalSurface<Real_t>(
0051       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kPlanar),
0052       builder::CreateFrame<Real_t>(FrameType::kWindow, WindowMask_t{tube.GetDx(), tube.GetDy()}),
0053       vecgeom::Transformation3DMP<Precision>(0., 0., -tube.GetDz(), 0., 180., 0.));
0054   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0055   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0056   builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0057   // Make the surface "logical"
0058   VECGEOM_ASSERT(isurf >= 0);
0059   cpudata.fLocalSurfaces[isurf].fLogicId = isurf;
0060   logic.push_back(isurf);
0061   logic.push_back(land);
0062 
0063   vecgeom::Transformation3DMP<Real_t> identity;
0064 
0065   // outer cylinder
0066   surfdata[0] = tube.GetDx();
0067   surfdata[1] = tube.GetDy();
0068   surfdata[2] = tube.GetDz();
0069   auto rmax   = vecCore::math::Max(tube.GetDx(), tube.GetDy());
0070   isurf       = builder::CreateLocalSurface<Real_t>(
0071       builder::CreateUnplacedSurface<Real_t>(SurfaceType::kElliptical, surfdata),
0072       builder::CreateFrame<Real_t>(FrameType::kZPhi, ZPhiMask_t{-surfdata[2], surfdata[2], /* full_circle=*/1, rmax,
0073                                                                 rmax, static_cast<vecgeom::Precision>(0),
0074                                                                 static_cast<vecgeom::Precision>(360)}),
0075       /*identity transformation*/ identity);
0076   builder::AddSurfaceToShell<Real_t>(logical_id, isurf);
0077   if (intersection) builder::GetSurface<Real_t>(isurf).fSkipConvexity = true;
0078   // Make the surface "logical"
0079   VECGEOM_ASSERT(isurf >= 0);
0080   cpudata.fLocalSurfaces[isurf].fLogicId = isurf;
0081   logic.push_back(isurf);
0082 
0083   builder::AddLogicToShell<Real_t>(logical_id, logic);
0084 
0085   return true;
0086 }
0087 
0088 } // namespace conv
0089 } // namespace vgbrep
0090 #endif