Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-18 09:32:41

0001 /// \file vector3d.h
0002 /// \author Johannes de Fine Licht (johannes.definelicht@cern.ch)
0003 
0004 #ifndef VECGEOM_BASE_VECTOR3D_H_
0005 #define VECGEOM_BASE_VECTOR3D_H_
0006 
0007 #include "VecGeom/base/Global.h"
0008 #include "VecGeom/base/AlignedBase.h"
0009 #include "VecGeom/base/Vector2D.h"
0010 
0011 #include <cstdlib>
0012 #include <ostream>
0013 #include <string>
0014 
0015 namespace vecgeom {
0016 
0017 VECGEOM_DEVICE_FORWARD_DECLARE(template <typename Type> class Vector3D;);
0018 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, Vector3D, typename);
0019 
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021 
0022 /**
0023  * @brief Three dimensional vector class supporting most arithmetic operations.
0024  * @details If vector acceleration is enabled, the scalar template instantiation
0025  *          will use vector instructions for operations when possible.
0026  */
0027 template <typename Type>
0028 class Vector3D : public AlignedBase {
0029 
0030   typedef Vector3D<Type> VecType;
0031 
0032 private:
0033   Type vec[3];
0034 
0035 public:
0036   using value_type = Type;
0037 
0038   VECCORE_ATT_HOST_DEVICE
0039   VECGEOM_FORCE_INLINE
0040   Vector3D(const Type a, const Type b, const Type c)
0041   {
0042     vec[0] = a;
0043     vec[1] = b;
0044     vec[2] = c;
0045   }
0046 
0047   VECCORE_ATT_HOST_DEVICE
0048   VECGEOM_FORCE_INLINE
0049   Vector3D()
0050   {
0051     vec[0] = 0;
0052     vec[1] = 0;
0053     vec[2] = 0;
0054   }
0055 
0056   VECCORE_ATT_HOST_DEVICE
0057   VECGEOM_FORCE_INLINE
0058   Vector3D(const Type a)
0059   {
0060     vec[0] = a;
0061     vec[1] = a;
0062     vec[2] = a;
0063   }
0064 
0065   template <typename TypeOther>
0066   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D(Vector3D<TypeOther> const &other)
0067   {
0068     vec[0] = other[0];
0069     vec[1] = other[1];
0070     vec[2] = other[2];
0071   }
0072 
0073   /**
0074    * Constructs a vector from an std::string of the same format as output by the
0075    * "<<"-operator for outstreams.
0076    * @param str String formatted as "(%d, %d, %d)".
0077    */
0078   VECCORE_ATT_HOST
0079   Vector3D(std::string const &str)
0080   {
0081     int begin = 1, end = str.find(",");
0082     vec[0] = std::atof(str.substr(begin, end - begin).c_str());
0083     begin  = end + 2;
0084     end    = str.find(",", begin);
0085     vec[1] = std::atof(str.substr(begin, end - begin).c_str());
0086     begin  = end + 2;
0087     end    = str.find(")", begin);
0088     vec[2] = std::atof(str.substr(begin, end - begin).c_str());
0089   }
0090 
0091   /**
0092    * Contains no check for correct indexing to avoid impairing performance.
0093    * @param index Index of content in the range [0-2].
0094    */
0095   VECCORE_ATT_HOST_DEVICE
0096   VECGEOM_FORCE_INLINE
0097   Type &operator[](const int index) { return vec[index]; }
0098 
0099   /**
0100    * Contains no check for correct indexing to avoid impairing performance.
0101    * @param index Index of content in the range [0-2].
0102    */
0103   VECCORE_ATT_HOST_DEVICE
0104   VECGEOM_FORCE_INLINE
0105   Type const &operator[](const int index) const { return vec[index]; }
0106 
0107   VECCORE_ATT_HOST_DEVICE
0108   VECGEOM_FORCE_INLINE
0109   Type &x() { return vec[0]; }
0110 
0111   VECCORE_ATT_HOST_DEVICE
0112   VECGEOM_FORCE_INLINE
0113   Type const &x() const { return vec[0]; }
0114 
0115   VECCORE_ATT_HOST_DEVICE
0116   VECGEOM_FORCE_INLINE
0117   Type &y() { return vec[1]; }
0118 
0119   VECCORE_ATT_HOST_DEVICE
0120   VECGEOM_FORCE_INLINE
0121   Type const &y() const { return vec[1]; }
0122 
0123   VECCORE_ATT_HOST_DEVICE
0124   VECGEOM_FORCE_INLINE
0125   Type &z() { return vec[2]; }
0126 
0127   VECCORE_ATT_HOST_DEVICE
0128   VECGEOM_FORCE_INLINE
0129   Type const &z() const { return vec[2]; }
0130 
0131   /// @brief Create 2D vectors out of pairs of components
0132   VECCORE_ATT_HOST_DEVICE
0133   VECGEOM_FORCE_INLINE
0134   Vector2D<Type> XY() const { return {vec[0], vec[1]}; }
0135 
0136   VECCORE_ATT_HOST_DEVICE
0137   VECGEOM_FORCE_INLINE
0138   Vector2D<Type> YX() const { return {vec[1], vec[0]}; }
0139 
0140   VECCORE_ATT_HOST_DEVICE
0141   VECGEOM_FORCE_INLINE
0142   Vector2D<Type> XZ() const { return {vec[0], vec[2]}; }
0143 
0144   VECCORE_ATT_HOST_DEVICE
0145   VECGEOM_FORCE_INLINE
0146   Vector2D<Type> ZX() const { return {vec[2], vec[0]}; }
0147 
0148   VECCORE_ATT_HOST_DEVICE
0149   VECGEOM_FORCE_INLINE
0150   Vector2D<Type> YZ() const { return {vec[1], vec[2]}; }
0151 
0152   VECCORE_ATT_HOST_DEVICE
0153   VECGEOM_FORCE_INLINE
0154   Vector2D<Type> ZY() const { return {vec[2], vec[1]}; }
0155 
0156   VECCORE_ATT_HOST_DEVICE
0157   void Set(Type const &a, Type const &b, Type const &c)
0158   {
0159     vec[0] = a;
0160     vec[1] = b;
0161     vec[2] = c;
0162   }
0163 
0164   VECCORE_ATT_HOST_DEVICE
0165   void Set(const Type a) { Set(a, a, a); }
0166 
0167   /// \return the length squared perpendicular to z direction
0168   VECCORE_ATT_HOST_DEVICE
0169   VECGEOM_FORCE_INLINE
0170   Type Perp2() const { return vec[0] * vec[0] + vec[1] * vec[1]; }
0171 
0172   /// \return the length perpendicular to z direction
0173   VECCORE_ATT_HOST_DEVICE
0174   VECGEOM_FORCE_INLINE
0175   Type Perp() const { return Sqrt(Perp2()); }
0176 
0177   /// The dot product of two Vector3D<T> objects
0178   /// \return T (where T is float, double, or various SIMD vector types)
0179   template <typename Type2>
0180   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Type Dot(Vector3D<Type> const &left, Vector3D<Type2> const &right)
0181   {
0182     return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
0183   }
0184 
0185   /// The dot product of two Vector3D<T> objects
0186   /// \return T (where T is float, double, or various SIMD vector types)
0187   template <typename Type2>
0188   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Type Dot(Vector3D<Type2> const &right) const
0189   {
0190     return Dot(*this, right);
0191   }
0192 
0193   // For UVector3 compatibility. It is equal to normal multiplication.
0194   VECCORE_ATT_HOST_DEVICE
0195   VECGEOM_FORCE_INLINE
0196   VecType MultiplyByComponents(VecType const &other) const { return *this * other; }
0197 
0198   /// \return Squared magnitude of the vector.
0199   VECCORE_ATT_HOST_DEVICE
0200   VECGEOM_FORCE_INLINE
0201   Type Mag2() const { return Dot(*this, *this); }
0202 
0203   /// \return Magnitude of the vector.
0204   VECCORE_ATT_HOST_DEVICE
0205   VECGEOM_FORCE_INLINE
0206   Type Mag() const { return Sqrt(Mag2()); }
0207 
0208   VECCORE_ATT_HOST_DEVICE
0209   VECGEOM_FORCE_INLINE
0210   Type Length() const { return Mag(); }
0211 
0212   VECCORE_ATT_HOST_DEVICE
0213   VECGEOM_FORCE_INLINE
0214   Type Length2() const { return Mag2(); }
0215 
0216   VECCORE_ATT_HOST_DEVICE
0217   VECGEOM_FORCE_INLINE
0218   VecType Unit() const { return Type(1.) / Mag() * VecType(*this); }
0219 
0220   /// Normalizes the vector by dividing each entry by the length.
0221   /// \sa Vector3D::Length()
0222   VECCORE_ATT_HOST_DEVICE
0223   VECGEOM_FORCE_INLINE
0224   void Normalize() { *this *= (Type(1.) / Length()); }
0225 
0226   VECCORE_ATT_HOST_DEVICE
0227   VECGEOM_FORCE_INLINE
0228   VecType Normalized() const { return Unit(); }
0229 
0230   // checks if vector is normalized
0231   // only reasonable to call with standard scalare usage
0232   VECCORE_ATT_HOST_DEVICE
0233   VECGEOM_FORCE_INLINE
0234   bool IsNormalized() const
0235   {
0236     // static_assert here that Type should be primitive type
0237     Precision norm = Mag2();
0238     return Type(1.) - vecgeom::kTolerance < norm && norm < Type(1.) + vecgeom::kTolerance;
0239   }
0240 
0241   /// \return Azimuthal angle between -pi and pi.
0242   VECCORE_ATT_HOST_DEVICE
0243   VECGEOM_FORCE_INLINE
0244   Type Phi() const { return ATan2(vec[1], vec[0]); }
0245 
0246   /// \return Polar angle between 0 and pi.
0247   VECCORE_ATT_HOST_DEVICE
0248   VECGEOM_FORCE_INLINE
0249   Type Theta() const { return ACos(vec[2] / Mag()); }
0250 
0251   /// The cross (vector) product of two Vector3D<T> objects
0252   /// \return Type (where Type is float, double, or various SIMD vector types)
0253   template <class FirstType, class SecondType>
0254   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Vector3D<Type> Cross(Vector3D<FirstType> const &left,
0255                                                                            Vector3D<SecondType> const &right)
0256   {
0257     return Vector3D<Type>(left[1] * right[2] - left[2] * right[1], left[2] * right[0] - left[0] * right[2],
0258                           left[0] * right[1] - left[1] * right[0]);
0259   }
0260 
0261   /// The cross (vector) product of two Vector3D<T> objects
0262   /// \return Type (where Type is float, double, or various SIMD vector types)
0263   template <class OtherType>
0264   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> Cross(Vector3D<OtherType> const &right) const
0265   {
0266     return Cross<Type, OtherType>(*this, right);
0267   }
0268 
0269   /// The Z component of the cross (vector) product of two Vector3D<T> objects
0270   /// \return Type (where Type is float, double, or various SIMD vector types)
0271   template <class FirstType, class SecondType>
0272   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Type CrossZ(Vector3D<FirstType> const &left,
0273                                                                   Vector3D<SecondType> const &right)
0274   {
0275     return left[0] * right[1] - left[1] * right[0];
0276   }
0277 
0278   /// The Z component of the cross (vector) product of two Vector3D<T> objects
0279   /// \return Type (where Type is float, double, or various SIMD vector types)
0280   template <class OtherType>
0281   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Type CrossZ(Vector3D<OtherType> const &right) const
0282   {
0283     return CrossZ<Type, OtherType>(*this, right);
0284   }
0285 
0286   /// Maps each vector entry to a function that manipulates the entry type.
0287   /// \param f A function of type "Type f(const Type&)" to map over entries.
0288   VECCORE_ATT_HOST_DEVICE
0289   VECGEOM_FORCE_INLINE
0290   void Map(Type (*f)(const Type &))
0291   {
0292     vec[0] = f(vec[0]);
0293     vec[1] = f(vec[1]);
0294     vec[2] = f(vec[2]);
0295   }
0296 
0297   VECCORE_ATT_HOST_DEVICE
0298   VECGEOM_FORCE_INLINE
0299   VecType Abs() const
0300   {
0301     return VecType(vecCore::math::Abs(vec[0]), vecCore::math::Abs(vec[1]), vecCore::math::Abs(vec[2]));
0302   }
0303 
0304   template <typename BoolType>
0305   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void MaskedAssign(Vector3D<BoolType> const &condition,
0306                                                                  Vector3D<Type> const &value)
0307   {
0308     vec[0] = (condition[0]) ? value[0] : vec[0];
0309     vec[1] = (condition[1]) ? value[1] : vec[1];
0310     vec[2] = (condition[2]) ? value[2] : vec[2];
0311   }
0312 
0313   VECCORE_ATT_HOST_DEVICE
0314   VECGEOM_FORCE_INLINE
0315   Type Min() const { return vecCore::math::Min(vec[0], vec[1], vec[2]); }
0316 
0317   template <typename BoolVector>
0318   VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Type MinSkip(BoolVector const &skip) const
0319   {
0320     // Fast implementation that works if the vector elements are finite
0321     return (*this + kInfLength * Vector3D<Type>(skip[0], skip[1], skip[2])).Min();
0322   }
0323 
0324   VECCORE_ATT_HOST_DEVICE
0325   VECGEOM_FORCE_INLINE
0326   Type Max() const { return vecCore::math::Max(vec[0], vec[1], vec[2]); }
0327 
0328   template <typename BoolVector>
0329   VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Type MaxSkip(BoolVector const &skip) const
0330   {
0331     // Fast implementation that works if the vector elements are finite
0332     return (*this - kInfLength * Vector3D<Type>(skip[0], skip[1], skip[2])).Max();
0333   }
0334 
0335   VECCORE_ATT_HOST_DEVICE
0336   VECGEOM_FORCE_INLINE
0337   static VecType FromCylindrical(Type r, Type phi, Type z) { return VecType(r * cos(phi), r * sin(phi), z); }
0338 
0339   VECCORE_ATT_HOST_DEVICE
0340   VECGEOM_FORCE_INLINE
0341   VecType &FixZeroes()
0342   {
0343     using vecCore::math::Abs;
0344     for (int i = 0; i < 3; ++i) {
0345       vecCore::MaskedAssign(vec[i], Abs(vec[i]) < kTolerance, Type(0.0));
0346     }
0347     return *this;
0348   }
0349 
0350   // Inplace binary operators
0351 
0352 #define VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(OPERATOR)                                                       \
0353   VECCORE_ATT_HOST_DEVICE                                                                                   \
0354   VECGEOM_FORCE_INLINE                                                                                      \
0355   VecType &operator OPERATOR(const VecType & other)                                                         \
0356   {                                                                                                         \
0357     vec[0] OPERATOR other.vec[0];                                                                           \
0358     vec[1] OPERATOR other.vec[1];                                                                           \
0359     vec[2] OPERATOR other.vec[2];                                                                           \
0360     return *this;                                                                                           \
0361   }                                                                                                         \
0362   template <typename OtherType>                                                                             \
0363   VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE VecType &operator OPERATOR(const Vector3D<OtherType> &other) \
0364   {                                                                                                         \
0365     vec[0] OPERATOR other[0];                                                                               \
0366     vec[1] OPERATOR other[1];                                                                               \
0367     vec[2] OPERATOR other[2];                                                                               \
0368     return *this;                                                                                           \
0369   }                                                                                                         \
0370   VECCORE_ATT_HOST_DEVICE                                                                                   \
0371   VECGEOM_FORCE_INLINE                                                                                      \
0372   VecType &operator OPERATOR(const Type & scalar)                                                           \
0373   {                                                                                                         \
0374     vec[0] OPERATOR scalar;                                                                                 \
0375     vec[1] OPERATOR scalar;                                                                                 \
0376     vec[2] OPERATOR scalar;                                                                                 \
0377     return *this;                                                                                           \
0378   }
0379   VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(+=)
0380   VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(-=)
0381   VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(*=)
0382   VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(/=)
0383 #undef VECTOR3D_TEMPLATE_INPLACE_BINARY_OP
0384 
0385   VECCORE_ATT_HOST_DEVICE
0386   VECGEOM_FORCE_INLINE
0387   operator bool() const { return vec[0] && vec[1] && vec[2]; }
0388 };
0389 
0390 template <typename T>
0391 std::ostream &operator<<(std::ostream &os, Vector3D<T> const &vec)
0392 {
0393   os << "(" << vec[0] << ", " << vec[1] << ", " << vec[2] << ")";
0394   return os;
0395 }
0396 
0397 #define VECTOR3D_BINARY_OP(OPERATOR, INPLACE)                                                                   \
0398   template <typename Type, typename OtherType>                                                                  \
0399   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator OPERATOR(const Vector3D<Type> &lhs,      \
0400                                                                                 const Vector3D<OtherType> &rhs) \
0401   {                                                                                                             \
0402     Vector3D<Type> result(lhs);                                                                                 \
0403     result INPLACE rhs;                                                                                         \
0404     return result;                                                                                              \
0405   }                                                                                                             \
0406   template <typename Type, typename ScalarType>                                                                 \
0407   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator OPERATOR(Vector3D<Type> const &lhs,      \
0408                                                                                 const ScalarType rhs)           \
0409   {                                                                                                             \
0410     Vector3D<Type> result(lhs);                                                                                 \
0411     result INPLACE rhs;                                                                                         \
0412     return result;                                                                                              \
0413   }                                                                                                             \
0414   template <typename Type, typename ScalarType>                                                                 \
0415   VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator OPERATOR(const ScalarType lhs,           \
0416                                                                                 Vector3D<Type> const &rhs)      \
0417   {                                                                                                             \
0418     Vector3D<Type> result(lhs);                                                                                 \
0419     result INPLACE rhs;                                                                                         \
0420     return result;                                                                                              \
0421   }
0422 VECTOR3D_BINARY_OP(+, +=)
0423 VECTOR3D_BINARY_OP(-, -=)
0424 VECTOR3D_BINARY_OP(*, *=)
0425 VECTOR3D_BINARY_OP(/, /=)
0426 #undef VECTOR3D_BINARY_OP
0427 
0428 template <typename Type>
0429 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE bool operator==(Vector3D<Type> const &lhs, Vector3D<Type> const &rhs)
0430 {
0431   return Abs(lhs[0] - rhs[0]) < kToleranceDist<Type> && Abs(lhs[1] - rhs[1]) < kToleranceDist<Type> &&
0432          Abs(lhs[2] - rhs[2]) < kToleranceDist<Type>;
0433 }
0434 
0435 template <typename Type>
0436 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE bool operator!=(Vector3D<Type> const &lhs, Vector3D<Type> const &rhs)
0437 {
0438   return !(lhs == rhs);
0439 }
0440 
0441 template <typename Type>
0442 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator<(Vector3D<Type> const &lhs,
0443                                                                       Vector3D<Type> const &rhs)
0444 {
0445   return {lhs[0] < rhs[0], lhs[1] < rhs[1], lhs[2] < rhs[2]};
0446 }
0447 
0448 template <typename Type>
0449 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator<=(Vector3D<Type> const &lhs,
0450                                                                        Vector3D<Type> const &rhs)
0451 {
0452   return {lhs[0] <= rhs[0], lhs[1] <= rhs[1], lhs[2] <= rhs[2]};
0453 }
0454 
0455 template <typename Type>
0456 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator>(Vector3D<Type> const &lhs,
0457                                                                       Vector3D<Type> const &rhs)
0458 {
0459   return {lhs[0] > rhs[0], lhs[1] > rhs[1], lhs[2] > rhs[2]};
0460 }
0461 
0462 template <typename Type>
0463 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator>=(Vector3D<Type> const &lhs,
0464                                                                        Vector3D<Type> const &rhs)
0465 {
0466   return {lhs[0] >= rhs[0], lhs[1] >= rhs[1], lhs[2] >= rhs[2]};
0467 }
0468 
0469 template <typename Type>
0470 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator-(Vector3D<Type> const &vec)
0471 {
0472   return Vector3D<Type>(-vec[0], -vec[1], -vec[2]);
0473 }
0474 
0475 VECCORE_ATT_HOST_DEVICE
0476 VECGEOM_FORCE_INLINE
0477 Vector3D<bool> operator!(Vector3D<bool> const &vec) { return Vector3D<bool>(!vec[0], !vec[1], !vec[2]); }
0478 
0479 #pragma GCC diagnostic push
0480 #pragma GCC diagnostic ignored "-Weffc++"
0481 #define VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP(OPERATOR)                                               \
0482   VECCORE_ATT_HOST_DEVICE                                                                          \
0483   VECGEOM_FORCE_INLINE                                                                             \
0484   Vector3D<bool> operator OPERATOR(Vector3D<bool> const &lhs, Vector3D<bool> const &rhs)           \
0485   {                                                                                                \
0486     return Vector3D<bool>(lhs[0] OPERATOR rhs[0], lhs[1] OPERATOR rhs[1], lhs[2] OPERATOR rhs[2]); \
0487   }
0488 VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP(&&)
0489 VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP(||)
0490 #undef VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP
0491 #pragma GCC diagnostic pop
0492 } // namespace VECGEOM_IMPL_NAMESPACE
0493 } // namespace vecgeom
0494 
0495 namespace vecCore {
0496 
0497 template <typename T>
0498 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void MaskedAssign(vecgeom::Vector3D<T> &v, const vecCore::Mask<T> &mask,
0499                                                                const vecgeom::Vector3D<T> &val)
0500 {
0501   vecCore::MaskedAssign(v[0], mask, val[0]);
0502   vecCore::MaskedAssign(v[1], mask, val[1]);
0503   vecCore::MaskedAssign(v[2], mask, val[2]);
0504 }
0505 
0506 /// @brief Minimum between two vectors
0507 /// @tparam T Vector type
0508 /// @param v1 first vector
0509 /// @param v2 second vector
0510 /// @return Vector having the minimum of the two vector components
0511 inline namespace math {
0512 template <typename T>
0513 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE vecgeom::Vector3D<T> Min(vecgeom::Vector3D<T> const &v1,
0514                                                                       vecgeom::Vector3D<T> const &v2)
0515 {
0516   vecgeom::Vector3D<T> result(vecCore::math::Min(v1.x(), v2.x()), vecCore::math::Min(v1.y(), v2.y()),
0517                               vecCore::math::Min(v1.z(), v2.z()));
0518   return result;
0519 }
0520 
0521 /// @brief Maximum between two vectors
0522 /// @tparam T Vector type
0523 /// @param v1 first vector
0524 /// @param v2 second vector
0525 /// @return Vector having the maximum of the two vector components
0526 template <typename T>
0527 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE vecgeom::Vector3D<T> Max(vecgeom::Vector3D<T> const &v1,
0528                                                                       vecgeom::Vector3D<T> const &v2)
0529 {
0530   vecgeom::Vector3D<T> result(vecCore::math::Max(v1.x(), v2.x()), vecCore::math::Max(v1.y(), v2.y()),
0531                               vecCore::math::Max(v1.z(), v2.z()));
0532   return result;
0533 }
0534 } // namespace math
0535 } // namespace vecCore
0536 
0537 // for use in GEANT4
0538 using UVector3 = VECGEOM_NAMESPACE::Vector3D<double>;
0539 
0540 #endif // VECGEOM_BASE_VECTOR3D_H_