File indexing completed on 2025-07-14 08:10:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Utilities/VectorHelpers.hpp"
0014
0015 #include <array>
0016
0017 namespace Acts {
0018
0019 class IVolumeMaterial;
0020
0021
0022
0023 struct EigenStepperDefaultExtension {
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 template <int i, typename stepper_t>
0041 bool k(const typename stepper_t::State& state, const stepper_t& stepper,
0042 const IVolumeMaterial* volumeMaterial, Vector3& knew,
0043 const Vector3& bField, std::array<double, 4>& kQoP,
0044 const double h = 0., const Vector3& kprev = Vector3::Zero())
0045 requires(i >= 0 && i <= 3)
0046 {
0047 (void)volumeMaterial;
0048
0049 auto qop = stepper.qOverP(state);
0050
0051 if constexpr (i == 0) {
0052 knew = qop * stepper.direction(state).cross(bField);
0053 kQoP = {0., 0., 0., 0.};
0054 } else {
0055 knew = qop * (stepper.direction(state) + h * kprev).cross(bField);
0056 }
0057 return true;
0058 }
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 template <typename stepper_t>
0073 bool finalize(typename stepper_t::State& state, const stepper_t& stepper,
0074 const IVolumeMaterial* volumeMaterial, const double h) const {
0075 (void)volumeMaterial;
0076
0077 propagateTime(state, stepper, h);
0078 return true;
0079 }
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 template <typename stepper_t>
0095 bool finalize(typename stepper_t::State& state, const stepper_t& stepper,
0096 const IVolumeMaterial* volumeMaterial, const double h,
0097 FreeMatrix& D) const {
0098 (void)volumeMaterial;
0099
0100 propagateTime(state, stepper, h);
0101 return transportMatrix(state, stepper, h, D);
0102 }
0103
0104 private:
0105
0106
0107
0108
0109
0110
0111
0112 template <typename stepper_t>
0113 void propagateTime(typename stepper_t::State& state, const stepper_t& stepper,
0114 const double h) const {
0115
0116
0117
0118 auto m = stepper.particleHypothesis(state).mass();
0119 auto p = stepper.absoluteMomentum(state);
0120 auto dtds = std::sqrt(1 + m * m / (p * p));
0121 state.pars[eFreeTime] += h * dtds;
0122 if (state.covTransport) {
0123 state.derivative(3) = dtds;
0124 }
0125 }
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 template <typename stepper_t>
0138 bool transportMatrix(typename stepper_t::State& state,
0139 const stepper_t& stepper, const double h,
0140 FreeMatrix& D) const {
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 auto m = state.particleHypothesis.mass();
0161 auto& sd = state.stepData;
0162 auto dir = stepper.direction(state);
0163 auto qop = stepper.qOverP(state);
0164 auto p = stepper.absoluteMomentum(state);
0165 auto dtds = std::sqrt(1 + m * m / (p * p));
0166
0167 D = FreeMatrix::Identity();
0168
0169 double half_h = h * 0.5;
0170
0171
0172 auto dFdT = D.block<3, 3>(0, 4);
0173 auto dFdL = D.block<3, 1>(0, 7);
0174
0175 auto dGdT = D.block<3, 3>(4, 4);
0176 auto dGdL = D.block<3, 1>(4, 7);
0177
0178 SquareMatrix3 dk1dT = SquareMatrix3::Zero();
0179 SquareMatrix3 dk2dT = SquareMatrix3::Identity();
0180 SquareMatrix3 dk3dT = SquareMatrix3::Identity();
0181 SquareMatrix3 dk4dT = SquareMatrix3::Identity();
0182
0183 Vector3 dk1dL = Vector3::Zero();
0184 Vector3 dk2dL = Vector3::Zero();
0185 Vector3 dk3dL = Vector3::Zero();
0186 Vector3 dk4dL = Vector3::Zero();
0187
0188
0189 dk1dL = dir.cross(sd.B_first);
0190 dk2dL = (dir + half_h * sd.k1).cross(sd.B_middle) +
0191 qop * half_h * dk1dL.cross(sd.B_middle);
0192 dk3dL = (dir + half_h * sd.k2).cross(sd.B_middle) +
0193 qop * half_h * dk2dL.cross(sd.B_middle);
0194 dk4dL =
0195 (dir + h * sd.k3).cross(sd.B_last) + qop * h * dk3dL.cross(sd.B_last);
0196
0197 dk1dT(0, 1) = sd.B_first.z();
0198 dk1dT(0, 2) = -sd.B_first.y();
0199 dk1dT(1, 0) = -sd.B_first.z();
0200 dk1dT(1, 2) = sd.B_first.x();
0201 dk1dT(2, 0) = sd.B_first.y();
0202 dk1dT(2, 1) = -sd.B_first.x();
0203 dk1dT *= qop;
0204
0205 dk2dT += half_h * dk1dT;
0206 dk2dT = qop * VectorHelpers::cross(dk2dT, sd.B_middle);
0207
0208 dk3dT += half_h * dk2dT;
0209 dk3dT = qop * VectorHelpers::cross(dk3dT, sd.B_middle);
0210
0211 dk4dT += h * dk3dT;
0212 dk4dT = qop * VectorHelpers::cross(dk4dT, sd.B_last);
0213
0214 dFdT.setIdentity();
0215 dFdT += h / 6. * (dk1dT + dk2dT + dk3dT);
0216 dFdT *= h;
0217
0218 dFdL = (h * h) / 6. * (dk1dL + dk2dL + dk3dL);
0219
0220 dGdT += h / 6. * (dk1dT + 2. * (dk2dT + dk3dT) + dk4dT);
0221
0222 dGdL = h / 6. * (dk1dL + 2. * (dk2dL + dk3dL) + dk4dL);
0223
0224 D(3, 7) = h * m * m * qop / dtds;
0225 return true;
0226 }
0227 };
0228
0229 }