12 template <
typename B,
typename E,
typename A>
14 : m_bField(std::move(bField)) {}
16 template <
typename B,
typename E,
typename A>
34 position(state), direction(state), boundParams);
35 state.
jacobian = BoundMatrix::Identity();
40 template <
typename B,
typename E,
typename A>
45 parameters << state.pos[0], state.pos[1], state.pos[2], state.t, state.dir[0],
46 state.dir[1], state.dir[2], state.q / state.p;
48 state.jacTransport, state.derivative,
49 state.jacToGlobal, parameters, state.covTransport,
50 state.pathAccumulated,
surface);
53 template <
typename B,
typename E,
typename A>
57 parameters << state.pos[0], state.pos[1], state.pos[2], state.t, state.dir[0],
58 state.dir[1], state.dir[2], state.q / state.p;
60 state.cov, state.jacobian, state.jacTransport, state.derivative,
61 state.jacToGlobal, parameters, state.covTransport, state.pathAccumulated);
64 template <
typename B,
typename E,
typename A>
69 state.
dir = parameters.template segment<3>(
eFreeDir0).normalized();
73 state.
cov = covariance;
76 template <
typename B,
typename E,
typename A>
79 const Vector3D& udirection,
double up,
81 state.
pos = uposition;
82 state.
dir = udirection;
87 template <
typename B,
typename E,
typename A>
93 template <
typename B,
typename E,
typename A>
97 parameters << state.
pos[0], state.
pos[1], state.
pos[2], state.
t, state.
dir[0],
98 state.
dir[1], state.
dir[2], state.
q / state.
p;
104 template <
typename B,
typename E,
typename A>
105 template <
typename propagator_state_t>
107 propagator_state_t& state)
const {
108 using namespace UnitLiterals;
111 auto& sd = state.stepping.stepData;
112 double error_estimate = 0.;
116 sd.B_first = getField(state.stepping, state.stepping.pos);
117 if (!state.stepping.extension.validExtensionForStep(state, *
this) ||
118 !state.stepping.extension.k1(state, *
this, sd.k1, sd.B_first, sd.kQoP)) {
133 state.stepping.pos + half_h * state.stepping.dir +
h2 * 0.125 * sd.k1;
134 sd.B_middle = getField(state.stepping, pos1);
135 if (!state.stepping.extension.k2(state, *
this, sd.k2, sd.B_middle, sd.kQoP,
141 if (!state.stepping.extension.k3(state, *
this, sd.k3, sd.B_middle, sd.kQoP,
148 state.stepping.pos + h * state.stepping.dir +
h2 * 0.5 * sd.k3;
149 sd.B_last = getField(state.stepping, pos2);
150 if (!state.stepping.extension.k4(state, *
this, sd.k4, sd.B_last, sd.kQoP, h,
157 h2 * ((sd.k1 - sd.k2 - sd.k3 + sd.k4).template lpNorm<1>() +
158 std::abs(sd.kQoP[0] - sd.kQoP[1] - sd.kQoP[2] + sd.kQoP[3])),
160 return (error_estimate <= state.options.tolerance);
163 double stepSizeScaling = 1.;
164 size_t nStepTrials = 0;
167 while (!tryRungeKuttaStep(state.stepping.stepSize)) {
174 state.stepping.stepSize = state.stepping.stepSize * stepSizeScaling;
178 if (state.stepping.stepSize * state.stepping.stepSize <
179 state.options.stepSizeCutOff * state.options.stepSizeCutOff) {
181 return EigenStepperError::StepSizeStalled;
186 if (nStepTrials > state.options.maxRungeKuttaStepTrials) {
188 return EigenStepperError::StepSizeAdjustmentFailed;
194 const double h = state.stepping.stepSize;
197 if (state.stepping.covTransport) {
200 if (!state.stepping.extension.finalize(state, *
this,
h, D)) {
201 return EigenStepperError::StepInvalid;
205 state.stepping.jacTransport = D * state.stepping.jacTransport;
207 if (!state.stepping.extension.finalize(state, *
this,
h)) {
208 return EigenStepperError::StepInvalid;
213 state.stepping.pos +=
214 h * state.stepping.dir +
h2 / 6. * (sd.k1 + sd.k2 + sd.k3);
215 state.stepping.dir +=
h / 6. * (sd.k1 + 2. * (sd.k2 + sd.k3) + sd.k4);
216 state.stepping.dir /= state.stepping.dir.norm();
217 if (state.stepping.covTransport) {
218 state.stepping.derivative.template head<3>() = state.stepping.dir;
219 state.stepping.derivative.template segment<3>(4) = sd.k4;
221 state.stepping.pathAccumulated +=
h;