File indexing completed on 2025-09-17 08:53:45
0001
0002
0003
0004
0005
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
0023
0024
0025
0026
0027
0028
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};
0037 real_type energy{0};
0038
0039
0040 template<class PTV>
0041 static inline CELER_FUNCTION FourVector
0042 from_particle(PTV const& particle, Real3 const& direction);
0043
0044
0045 static inline CELER_FUNCTION FourVector
0046 from_mass_momentum(Mass m, Momentum p, Real3 const& direction);
0047
0048
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
0059
0060
0061
0062
0063
0064
0065
0066
0067
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
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
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
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
0113
0114
0115
0116
0117
0118
0119
0120
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
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 }