Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 09:29:07

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