Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:45

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/phys/FourVector.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cmath>
0010 
0011 #include "corecel/cont/Array.hh"
0012 #include "corecel/math/Algorithms.hh"
0013 #include "corecel/math/ArrayOperators.hh"
0014 #include "corecel/math/ArrayUtils.hh"
0015 #include "geocel/Types.hh"
0016 #include "celeritas/Quantities.hh"
0017 #include "celeritas/Types.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 // STRUCTS
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * The momentum-energy four-vector (Lorentz vector).
0026  *
0027  * The units of this class are implicit: momentum is \c MevMomentum
0028  * and energy is \c MevEnergy.
0029  */
0030 struct FourVector
0031 {
0032     using Energy = units::MevEnergy;
0033     using Momentum = units::MevMomentum;
0034     using Mass = units::MevMass;
0035 
0036     Real3 mom{0, 0, 0};  //!< Particle momentum
0037     real_type energy{0};  //!< Particle total energy (\f$\sqrt{p^2 + m^2}\f$)
0038 
0039     // Construct from a particle and direction
0040     template<class PTV>
0041     static inline CELER_FUNCTION FourVector
0042     from_particle(PTV const& particle, Real3 const& direction);
0043 
0044     // Construct from momentum, rest mass, direction
0045     static inline CELER_FUNCTION FourVector
0046     from_mass_momentum(Mass m, Momentum p, Real3 const& direction);
0047 
0048     //! In-place addition
0049     CELER_FUNCTION FourVector& operator+=(FourVector const& v)
0050     {
0051         mom += v.mom;
0052         energy += v.energy;
0053         return *this;
0054     }
0055 };
0056 
0057 //---------------------------------------------------------------------------//
0058 // INLINE UTILITY FUNCTIONS
0059 //---------------------------------------------------------------------------//
0060 /*!
0061  * Construct from rest mass, momentum, direction.
0062  *
0063  * Note that this could be improved by using \c std::hypot which yields more
0064  * accurate answers if the magnitudes of the momentum and mass are very
0065  * different. However, differences in the implementation of that function can
0066  * lead to differences across platforms, compilers, and architectures, so for
0067  * now we use a naive sqrt+ipow.
0068  */
0069 CELER_FUNCTION FourVector FourVector::from_mass_momentum(Mass m,
0070                                                          Momentum p,
0071                                                          Real3 const& direction)
0072 {
0073     return {p.value() * direction,
0074             std::sqrt(ipow<2>(p.value()) + ipow<2>(m.value()))};
0075 }
0076 
0077 //---------------------------------------------------------------------------//
0078 /*!
0079  * Construct from a particle and direction.
0080  */
0081 template<class PTV>
0082 CELER_FUNCTION FourVector FourVector::from_particle(PTV const& particle,
0083                                                     Real3 const& direction)
0084 {
0085     return {direction * value_as<Momentum>(particle.momentum()),
0086             value_as<Energy>(particle.total_energy())};
0087 }
0088 
0089 //---------------------------------------------------------------------------//
0090 /*!
0091  * Add two four-vectors.
0092  */
0093 inline CELER_FUNCTION FourVector operator+(FourVector const& lhs,
0094                                            FourVector const& rhs)
0095 {
0096     FourVector result = lhs;
0097     return result += rhs;
0098 }
0099 
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Get the boost vector (\f$ \frac{\vec{mom}}/{energy} \f$) of a four-vector.
0103  */
0104 inline CELER_FUNCTION Real3 boost_vector(FourVector const& p)
0105 {
0106     CELER_EXPECT(p.energy > 0);
0107     return (real_type{1} / p.energy) * p.mom;
0108 }
0109 
0110 //---------------------------------------------------------------------------//
0111 /*!
0112  * Perform the Lorentz transformation along a boost vector.
0113  *
0114  * The transformation (\f$ \Lambda^{\alpha}_{\beta} \f$) along
0115  * the boost vector (\f$ \vec{v} \f$) for a four-vector \f$ p^{\beta} \f$ is:
0116  *
0117  * \f[ p^{\prime \beta} = \Lambda^{\alpha}_{\beta} (\vec{v}) p^{\beta} \f].
0118  *
0119  * \todo Define a boost function that takes a second FourVector for reduced
0120  * register usage
0121  */
0122 inline CELER_FUNCTION void boost(Real3 const& v, FourVector* p)
0123 {
0124     real_type const v_sq = dot_product(v, v);
0125     CELER_EXPECT(v_sq < real_type{1});
0126 
0127     real_type const vp = dot_product(v, p->mom);
0128     real_type const gamma = real_type{1} / std::sqrt(1 - v_sq);
0129     real_type const lambda = (v_sq > 0 ? (gamma - 1) * vp / v_sq : 0)
0130                              + gamma * p->energy;
0131 
0132     axpy(lambda, v, &(p->mom));
0133     p->energy = gamma * (p->energy + vp);
0134 }
0135 
0136 //---------------------------------------------------------------------------//
0137 /*!
0138  * Calculate the magnitude of a four vector.
0139  */
0140 inline CELER_FUNCTION real_type norm(FourVector const& a)
0141 {
0142     return std::sqrt(std::fabs(ipow<2>(a.energy) - dot_product(a.mom, a.mom)));
0143 }
0144 
0145 //---------------------------------------------------------------------------//
0146 }  // namespace celeritas