Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:54

0001 /// \file Scale3D.h
0002 /// \author Mihaela Gheata (mihaela.gheata@cern.ch)
0003 
0004 #ifndef VECGEOM_BASE_SCALE3D_H_
0005 #define VECGEOM_BASE_SCALE3D_H_
0006 
0007 #include "VecGeom/base/Cuda.h"
0008 #include "VecGeom/base/Global.h"
0009 
0010 #include "VecGeom/base/Vector3D.h"
0011 #ifdef VECGEOM_CUDA_INTERFACE
0012 #include "VecGeom/backend/cuda/Interface.h"
0013 #endif
0014 
0015 #include <algorithm>
0016 #include <cmath>
0017 #include <cstring>
0018 
0019 namespace vecgeom {
0020 
0021 VECGEOM_DEVICE_FORWARD_DECLARE(class Scale3D;);
0022 
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024 
0025 #ifndef VECCORE_CUDA
0026 }
0027 namespace cuda {
0028 class Scale3D;
0029 }
0030 inline namespace VECGEOM_IMPL_NAMESPACE {
0031 // class vecgeom::cuda::Scale3D;
0032 #endif
0033 
0034 class Scale3D {
0035 
0036 private:
0037   Vector3D<Precision> fScale;    /// scale transformation
0038   Vector3D<Precision> fInvScale; /// inverse scale (avoid divisions)
0039   Precision fSclLocal;           /// factor to apply to safety to convert to local frame
0040   Precision fSclMaster;          /// factor to apply to safety to convert to master frame
0041 
0042 public:
0043   /**
0044    * Default constructor
0045    */
0046   VECCORE_ATT_HOST_DEVICE
0047   Scale3D() : fScale(1., 1., 1.), fInvScale(1., 1., 1.), fSclLocal(1.), fSclMaster(1.) {}
0048 
0049   /**
0050    * Constructor with scale parameters on each axis
0051    * @param sx Scale value on x
0052    * @param sy Scale value on y
0053    * @param sz Scale value on z
0054    */
0055   VECCORE_ATT_HOST_DEVICE
0056   Scale3D(Precision sx, Precision sy, Precision sz) : fScale(sx, sy, sz), fInvScale(), fSclLocal(1.), fSclMaster(1.)
0057   {
0058     Update();
0059   }
0060 
0061   /**
0062    * Constructor with scale parameters in a Vector3D
0063    * @param scale Scale as Vector3D
0064    */
0065   VECCORE_ATT_HOST_DEVICE
0066   Scale3D(Vector3D<Precision> const &scale) : fScale(scale), fInvScale(), fSclLocal(1.), fSclMaster(1.) { Update(); }
0067 
0068   /**
0069    * Copy constructor.
0070    */
0071   VECCORE_ATT_HOST_DEVICE
0072   Scale3D(Scale3D const &other)
0073       : fScale(other.fScale), fInvScale(other.fInvScale), fSclLocal(other.fSclLocal), fSclMaster(other.fSclMaster)
0074   {
0075   }
0076 
0077   /**
0078    * Assignment operator
0079    */
0080   VECCORE_ATT_HOST_DEVICE
0081   Scale3D &operator=(Scale3D const &other)
0082   {
0083     fScale     = other.fScale;
0084     fInvScale  = other.fInvScale;
0085     fSclLocal  = other.fSclLocal;
0086     fSclMaster = other.fSclMaster;
0087     return *this;
0088   }
0089 
0090   /**
0091    * Update the backed-up inverse scale and special conversion factors based
0092    * on the values of the scale. Needed whenever the scale has changed value.
0093    */
0094   VECCORE_ATT_HOST_DEVICE
0095   VECGEOM_FORCE_INLINE
0096   void Update()
0097   {
0098     assert(((fScale[0] != 0) && (fScale[1] != 0) && (fScale[2] != 0)));
0099     fInvScale.Set(1. / fScale[0], 1. / fScale[1], 1. / fScale[2]);
0100     // Keep into account that scale components may be negative for reflections
0101     fSclLocal  = Min(Abs(fInvScale[0]), Abs(fInvScale[1]));
0102     fSclLocal  = Min(fSclLocal, Abs(fInvScale[2]));
0103     fSclMaster = Min(Abs(fScale[0]), Abs(fScale[1]));
0104     fSclMaster = Min(fSclMaster, Abs(fScale[2]));
0105   }
0106 
0107   /**
0108    * Get reference to the scale vector.
0109    */
0110   VECCORE_ATT_HOST_DEVICE
0111   VECGEOM_FORCE_INLINE
0112   const Vector3D<Precision> &Scale() const { return fScale; }
0113 
0114   /**
0115    * Get reference to the inverse scale vector.
0116    */
0117   VECCORE_ATT_HOST_DEVICE
0118   VECGEOM_FORCE_INLINE
0119   const Vector3D<Precision> &InvScale() const { return fInvScale; }
0120 
0121   /**
0122    * Set scale based on vector.
0123    */
0124   VECCORE_ATT_HOST_DEVICE
0125   VECGEOM_FORCE_INLINE
0126   void SetScale(Vector3D<Precision> const &scale)
0127   {
0128     fScale = scale;
0129     Update();
0130   }
0131 
0132   /**
0133    * Set scale based on values.
0134    */
0135   VECCORE_ATT_HOST_DEVICE
0136   VECGEOM_FORCE_INLINE
0137   void SetScale(Precision sx, Precision sy, Precision sz)
0138   {
0139     fScale.Set(sx, sy, sz);
0140     Update();
0141   }
0142 
0143   /**
0144    * Transform point from master to local frame
0145    */
0146   template <typename InputType>
0147   VECGEOM_FORCE_INLINE
0148   VECCORE_ATT_HOST_DEVICE
0149   void Transform(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0150   {
0151     local.Set(master[0] * fInvScale[0], master[1] * fInvScale[1], master[2] * fInvScale[2]);
0152   }
0153 
0154   template <typename InputType>
0155   VECGEOM_FORCE_INLINE
0156   VECCORE_ATT_HOST_DEVICE
0157   Vector3D<InputType> Transform(Vector3D<InputType> const &master) const
0158   {
0159     Vector3D<InputType> local(master[0] * fInvScale[0], master[1] * fInvScale[1], master[2] * fInvScale[2]);
0160     return local;
0161   }
0162 
0163   /**
0164    * Transform point from local to master frame
0165    */
0166   template <typename InputType>
0167   VECGEOM_FORCE_INLINE
0168   VECCORE_ATT_HOST_DEVICE
0169   void InverseTransform(Vector3D<InputType> const &local, Vector3D<InputType> &master) const
0170   {
0171     master.Set(local[0] * fScale[0], local[1] * fScale[1], local[2] * fScale[2]);
0172   }
0173 
0174   template <typename InputType>
0175   VECGEOM_FORCE_INLINE
0176   VECCORE_ATT_HOST_DEVICE
0177   Vector3D<InputType> InverseTransform(Vector3D<InputType> const &local) const
0178   {
0179     Vector3D<InputType> master(local[0] * fScale[0], local[1] * fScale[1], local[2] * fScale[2]);
0180     return master;
0181   }
0182 
0183   /**
0184    * Transform normal from master to local frame
0185    */
0186   template <typename InputType>
0187   VECGEOM_FORCE_INLINE
0188   VECCORE_ATT_HOST_DEVICE
0189   void TransformNormal(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0190   {
0191     local.Set(master[0] * fInvScale[1] * fInvScale[2], master[1] * fInvScale[2] * fInvScale[0],
0192               master[2] * fInvScale[0] * fInvScale[1]);
0193   }
0194 
0195   template <typename InputType>
0196   VECGEOM_FORCE_INLINE
0197   VECCORE_ATT_HOST_DEVICE
0198   Vector3D<InputType> TransformNormal(Vector3D<InputType> const &master) const
0199   {
0200     Vector3D<InputType> local(master[0] * fInvScale[1] * fInvScale[2], master[1] * fInvScale[2] * fInvScale[0],
0201                               master[2] * fInvScale[0] * fInvScale[1]);
0202     return local;
0203   }
0204 
0205   /**
0206    * Transform normal from local to master frame
0207    */
0208   template <typename InputType>
0209   VECGEOM_FORCE_INLINE
0210   VECCORE_ATT_HOST_DEVICE
0211   void InverseTransformNormal(Vector3D<InputType> const &local, Vector3D<InputType> &master) const
0212   {
0213     master.Set(local[0] * fScale[1] * fScale[2], local[1] * fScale[2] * fScale[0], local[2] * fScale[0] * fScale[1]);
0214   }
0215 
0216   template <typename InputType>
0217   VECGEOM_FORCE_INLINE
0218   VECCORE_ATT_HOST_DEVICE
0219   Vector3D<InputType> InverseTransformNormal(Vector3D<InputType> const &local) const
0220   {
0221     Vector3D<InputType> master(local[0] * fScale[1] * fScale[2], local[1] * fScale[2] * fScale[0],
0222                                local[2] * fScale[0] * fScale[1]);
0223     return master;
0224   }
0225 
0226   /**
0227    * Transform distance along given direction from master to local frame
0228    */
0229   template <typename InputType>
0230   VECGEOM_FORCE_INLINE
0231   VECCORE_ATT_HOST_DEVICE
0232   InputType TransformDistance(InputType const &dist, Vector3D<InputType> const &dir) const
0233   {
0234     Vector3D<InputType> v = dir * fInvScale;
0235     InputType scale       = Sqrt(Vector3D<InputType>::Dot(v, v));
0236     return (scale * dist);
0237   }
0238 
0239   /**
0240    * Transform safe distance from master to local frame (conservative)
0241    */
0242   template <typename InputType>
0243   VECGEOM_FORCE_INLINE
0244   VECCORE_ATT_HOST_DEVICE
0245   InputType TransformSafety(InputType safety) const
0246   {
0247     return (safety * fSclLocal);
0248   }
0249 
0250   /**
0251    * Transform distance along given direction from local to master frame
0252    */
0253   template <typename InputType>
0254   VECGEOM_FORCE_INLINE
0255   VECCORE_ATT_HOST_DEVICE
0256   InputType InverseTransformDistance(InputType const &dist, Vector3D<InputType> const &dir) const
0257   {
0258     Vector3D<InputType> v = dir * fScale;
0259     InputType scale       = Sqrt(Vector3D<InputType>::Dot(v, v));
0260     return (scale * dist);
0261   }
0262 
0263   /**
0264    * Transform safe distance from local to master frame (conservative)
0265    */
0266   template <typename InputType>
0267   VECGEOM_FORCE_INLINE
0268   VECCORE_ATT_HOST_DEVICE
0269   InputType InverseTransformSafety(InputType safety) const
0270   {
0271     return (safety * fSclMaster);
0272   }
0273 
0274 public:
0275   static const Scale3D kIdentity;
0276 
0277 }; // End class Scale3D
0278 
0279 std::ostream &operator<<(std::ostream &os, Scale3D const &scale);
0280 } // namespace VECGEOM_IMPL_NAMESPACE
0281 } // namespace vecgeom
0282 
0283 #endif // VECGEOM_BASE_SCALE3D_H_