12#include "detray/core/concepts.hpp"
13#include "detray/definitions/algebra.hpp"
14#include "detray/definitions/detail/qualifiers.hpp"
15#include "detray/definitions/units.hpp"
16#include "detray/material/interaction.hpp"
17#include "detray/material/material.hpp"
18#include "detray/navigation/policies.hpp"
19#include "detray/propagator/base_stepper.hpp"
20#include "detray/propagator/detail/codegen/update_rk_transport_jacobian.hpp"
21#include "detray/propagator/transport_jacobian.hpp"
22#include "detray/tracks/tracks.hpp"
41template <
typename magnetic_field_t, concepts::algebra algebra_t,
42 typename constraint_t = unconstrained_step<dscalar<algebra_t>>,
43 typename policy_t = stepper_rk_policy<dscalar<algebra_t>>,
44 typename inspector_t = stepping::void_inspector,
45 std::uint32_t flags_v =
46 (
static_cast<std::uint32_t
>(
48 static_cast<std::uint32_t
>(
51 : public
base_stepper<algebra_t, constraint_t, policy_t, inspector_t> {
80 template <std::
size_t ROWS, std::
size_t COLS>
85 detail::transport_jacobian_matrix_with_gradient<algebra_type>,
86 detail::transport_jacobian_matrix_without_gradient<algebra_type>>;
88 rk_stepper() =
default;
109 struct state :
public base_type::template
state<transport_jacobian_type> {
111 static constexpr const stepping::id
id = stepping::id::e_rk;
122 const magnetic_field_t& mag_field)
123 :
base_state(t), m_magnetic_field(mag_field) {}
130 template <concepts::detector detector_t>
132 const magnetic_field_t& mag_field,
133 const detector_t& det,
134 const typename detector_t::geometry_context& ctx)
135 :
base_state(bound_params, det, ctx), m_magnetic_field(mag_field) {}
146 m_next_step_size =
step;
158 if (this->path_length() == 0.f) [[unlikely]] {
161 const auto bvec_tmp = this->
field().at(pos[0], pos[1], pos[2]);
163 bvec[0u] = bvec_tmp[0u];
164 bvec[1u] = bvec_tmp[1u];
165 bvec[2u] = bvec_tmp[2u];
168 "--> dtds: " << (*
this)().qop() *
169 vector::cross((*
this)().dir(), bvec));
171 return (*
this)().qop() * vector::cross((*
this)().dir(), bvec);
188 if (this->path_length() == 0.f) [[unlikely]] {
189 return this->
dqopds((*
this)().qop(), vol_mat_ptr);
203 if (vol_mat_ptr ==
nullptr) {
208 assert(std::isfinite(qop));
209 const scalar_type q = this->particle_hypothesis().charge();
211 const scalar_type mass = this->particle_hypothesis().mass();
212 const scalar_type E = math::sqrt(p * p + mass * mass);
217 *vol_mat_ptr, this->particle_hypothesis(), {mass, qop, q});
223 DETRAY_DEBUG_HOST_DEVICE(
"--> dqopds: %f",
224 qop * qop * qop * E * stopping_power / (q * q));
228 return qop * qop * qop * E * stopping_power / (q * q);
242 if (vol_mat_ptr ==
nullptr) {
246 const scalar_type q = this->particle_hypothesis().charge();
250 const auto& mass = this->particle_hypothesis().mass();
257 const detail::relativistic_quantities<scalar_type> rq(mass, qop, q);
260 this->particle_hypothesis(), rq);
265 this->particle_hypothesis(), rq);
274 return dqopds * (1.f / qop * (3.f - p2 / E2) + 1.f / g * dgdqop);
282 template <
typename... Args>
285 [[maybe_unused]]
const char* message,
287 [[maybe_unused]] Args&&... args) {
288 if constexpr (!std::is_same_v<inspector_t, stepping::void_inspector>) {
289 this->inspector()(*
this, cfg, message, dist,
290 std::forward<Args>(args)...);
293 if constexpr (
sizeof...(Args) > 0u) {
294 DETRAY_DEBUG_HOST(
"" << message <<
"\n"
295 << detray::stepping::print_state(
296 *
this, std::forward<Args>(args)...));
308 const magnetic_field_type& m_magnetic_field;
324 DETRAY_DEBUG_HOST(
"Before: " << stepping());
328 DETRAY_VERBOSE_HOST_DEVICE(
"Zero stepsize...");
331 if (math::fabs(stepping.next_step_size()) < cfg.
min_stepsize) {
332 stepping.set_next_step_size(math::copysign(
335 DETRAY_DEBUG_HOST_DEVICE(
"Setting next stepsize: %f mm",
336 stepping.next_step_size());
338 stepping.run_inspector(cfg,
"Step skipped (Overlap): ", dist_to_next);
340 DETRAY_DEBUG_HOST(
"After: " << stepping());
345 math::fabs(stepping.next_step_size()) >= cfg.
min_stepsize)) {
346 DETRAY_INFO_HOST(
"Next stepsize: " << stepping.next_step_size() <<
", "
351 assert(math::fabs(dist_to_next) != 0.f);
353 math::fabs(stepping.next_step_size()) >= cfg.
min_stepsize);
354 assert(!stepping().is_invalid());
357 auto& magnetic_field = stepping.field();
360 stepping.set_step_size(dist_to_next);
361 }
else if (stepping.next_step_size() > 0) {
362 assert(math::fabs(stepping.next_step_size()) >= cfg.
min_stepsize);
363 stepping.set_step_size(
364 math::min(stepping.next_step_size(), dist_to_next));
366 assert(math::fabs(stepping.next_step_size()) >= cfg.
min_stepsize);
367 stepping.set_step_size(
368 math::max(stepping.next_step_size(), dist_to_next));
371 DETRAY_VERBOSE_HOST_DEVICE(
"Distance to nex: %f mm", dist_to_next);
372 DETRAY_VERBOSE_HOST_DEVICE(
"Initial stepsize: %f mm", stepping.step_size());
376 math::min(math::fabs(stepping.step_size()),
383 auto bvec = magnetic_field.at(pos[0], pos[1], pos[2]);
384 assert(math::isfinite(bvec[0]));
385 assert(math::isfinite(bvec[1]));
386 assert(math::isfinite(bvec[2]));
391 DETRAY_DEBUG_HOST_DEVICE(
"First stage:");
392 DETRAY_DEBUG_HOST_DEVICE(
"-> B-field: [%f, %f, %f]", bvec[0], bvec[1],
403 const auto estimate_error = [&](
const scalar_type& h) {
413 pos + half_h * sd.
t[0u] + h2 * 0.125f * sd.
dtds[0u];
414 bvec = magnetic_field.at(pos1[0], pos1[1], pos1[2]);
415 assert(math::isfinite(bvec[0]));
416 assert(math::isfinite(bvec[1]));
417 assert(math::isfinite(bvec[2]));
421 DETRAY_DEBUG_HOST_DEVICE(
"Second stage:");
422 DETRAY_DEBUG_HOST_DEVICE(
"-> B-field: [%f, %f, %f]", bvec[0], bvec[1],
426 stepping, 1u, half_h, sd.
dqopds[0u], vol_mat_ptr, cfg);
435 stepping, 2u, half_h, sd.
dqopds[1u], vol_mat_ptr, cfg);
443 bvec = magnetic_field.at(pos2[0], pos2[1], pos2[2]);
444 assert(math::isfinite(bvec[0]));
445 assert(math::isfinite(bvec[1]));
446 assert(math::isfinite(bvec[2]));
451 DETRAY_DEBUG_HOST_DEVICE(
"Third stage:");
452 DETRAY_DEBUG_HOST_DEVICE(
"-> B-field: [%f, %f, %f]", bvec[0], bvec[1],
462 constexpr auto one_sixth{
static_cast<scalar_type>(1. / 6.)};
467 DETRAY_DEBUG_HOST(
"-> Integration error vector: " << err_vec);
469 return vector::norm(err_vec);
474 const auto step_size_scaling =
478 math::min(math::max(math::sqrt(math::sqrt(cfg.
rk_error_tol / err)),
488 for (
unsigned int i = 0u; i < n_trials; i++) {
489 stepping.count_trials();
491 error = math::max(estimate_error(stepping.step_size()),
494 DETRAY_DEBUG_HOST_DEVICE(
"-> Integration error: %f", error);
495 assert(math::isfinite(error));
505 stepping.set_step_size(stepping.step_size() * step_size_scaling(error));
508 stepping.run_inspector(cfg,
"Adjust stepsize: ", dist_to_next, i,
509 step_size_scaling(error));
513 stepping.dtds(sd.
dtds[3u]);
514 stepping.dqopds(sd.
dqopds[3u]);
518 stepping.constraints().template size<>(stepping.direction());
519 math::fabs(stepping.step_size()) > math::fabs(max_step)) {
521 stepping.run_inspector(cfg,
"Before constraint: ", dist_to_next);
523 stepping.set_step_size(max_step);
527 if (math::fabs(stepping.step_size()) < min_stepsize) {
528 stepping.set_step_size(
529 math::copysign(min_stepsize, stepping.step_size()));
532 DETRAY_VERBOSE_HOST_DEVICE(
"Take step: %f mm", stepping.step_size());
535 stepping.set_next_step_size(stepping.step_size() *
536 step_size_scaling(error));
539 if (math::fabs(stepping.next_step_size()) < cfg.
min_stepsize) {
540 stepping.set_next_step_size(
542 stepping.next_step_size()));
545 DETRAY_DEBUG_HOST_DEVICE(
"Estimated next stepsize: %f mm",
546 stepping.next_step_size());
548 assert(math::fabs(stepping.next_step_size()) >= cfg.
min_stepsize);
549 assert(math::fabs(stepping.step_size()) >= cfg.
min_stepsize);
553 assert(!stepping().is_invalid());
556 if constexpr ((flags_v &
static_cast<std::uint32_t
>(
557 detray::rk_stepper_flags::
558 e_allow_covariance_transport)) != 0u) {
567 stepping.run_inspector(cfg,
"Step complete: ", dist_to_next);
569 DETRAY_DEBUG_HOST(
"After: " << stepping());
584 inspector_t, flags_v>
::state& stepping,
588 const auto& track = stepping();
590 if (vol_mat_ptr ==
nullptr) {
592 DETRAY_DEBUG_HOST_DEVICE(
"-> qop: %f", qop);
593 DETRAY_DEBUG_HOST_DEVICE(
"-> dqopds: 0");
603 const scalar_type qop = track.qop() + h * dqopds_prev;
604 DETRAY_DEBUG_HOST_DEVICE(
"-> qop: %f", qop);
609 DETRAY_DEBUG_HOST_DEVICE(
"-> qop: %f", qop);
626 inspector_t, flags_v>
::state& stepping,
629 auto& track = stepping();
630 const auto dir = track.dir();
632 assert(std::isfinite(qop));
641 "-> evaluate dtds: " <<
vector3_type{qop * vector::cross(t, b_field)});
653 inspector_t, flags_v>
::state& stepping,
658 auto& track = stepping();
659 auto pos = track.pos();
660 auto dir = track.dir();
664 pos = pos + h * (sd.
t[0u] + h_6 * (sd.
dtds[0] + sd.
dtds[1] + sd.
dtds[2]));
670 dir = vector::normalize(dir);
673 auto qop = track.qop();
674 if (vol_mat_ptr !=
nullptr) {
683 stepping.update_path_lengths(h);
694 inspector_t, flags_v>
::state& stepping,
697 DETRAY_VERBOSE_HOST_DEVICE(
"-> Advance Jacobian...");
833 stepping.d2qopdsdqop(sd.
qop[0u], vol_mat_ptr);
835 dqopn_dqop[0u] = 1.f;
836 dqopn_dqop[1u] = 1.f + half_h * d2qop1dsdqop1;
839 stepping.d2qopdsdqop(sd.
qop[1u], vol_mat_ptr) * dqopn_dqop[1u];
840 dqopn_dqop[2u] = 1.f + half_h * d2qop2dsdqop1;
843 stepping.d2qopdsdqop(sd.
qop[2u], vol_mat_ptr) * dqopn_dqop[2u];
844 dqopn_dqop[3u] = 1.f + h * d2qop3dsdqop1;
847 stepping.d2qopdsdqop(sd.
qop[3u], vol_mat_ptr) * dqopn_dqop[3u];
854 1.f + h_6 * (d2qop1dsdqop1 + 2.f * (d2qop2dsdqop1 + d2qop3dsdqop1) +
866 dkndqop[0u] = dqopn_dqop[0u] * vector::cross(sd.
t[0u], sd.
b_first);
870 dqopn_dqop[1u] * vector::cross(sd.
t[1u], sd.
b_middle) +
871 sd.
qop[1u] * half_h * vector::cross(dkndqop[0u], sd.
b_middle);
875 dqopn_dqop[2u] * vector::cross(sd.
t[2u], sd.
b_middle) +
876 sd.
qop[2u] * half_h * vector::cross(dkndqop[1u], sd.
b_middle);
879 dkndqop[3u] = dqopn_dqop[3u] * vector::cross(sd.
t[3u], sd.
b_last) +
880 sd.
qop[3u] * h * vector::cross(dkndqop[2u], sd.
b_last);
883 dFdqop = h * h_6 * (dkndqop[0u] + dkndqop[1u] + dkndqop[2u]);
884 dGdqop = h_6 * (dkndqop[0u] + 2.f * (dkndqop[1u] + dkndqop[2u]) +
893 auto dFdt = matrix::identity<matrix_type<3, 3>>();
894 auto dGdt = matrix::identity<matrix_type<3, 3>>();
897 const auto I33 = matrix::identity<matrix_type<3, 3>>();
901 dkndt[0u] = sd.
qop[0u] * matrix::column_wise_cross(dkndt[0u], sd.
b_first);
904 dkndt[1u] = dkndt[1u] + half_h * dkndt[0u];
906 sd.
qop[1u] * matrix::column_wise_cross(dkndt[1u], sd.
b_middle);
909 dkndt[2u] = dkndt[2u] + half_h * dkndt[1u];
911 sd.
qop[2u] * matrix::column_wise_cross(dkndt[2u], sd.
b_middle);
914 dkndt[3u] = dkndt[3u] + h * dkndt[2u];
915 dkndt[3u] = sd.
qop[3u] * matrix::column_wise_cross(dkndt[3u], sd.
b_last);
917 dFdt = dFdt + h_6 * (dkndt[0u] + dkndt[1u] + dkndt[2u]);
920 dGdt + h_6 * (dkndt[0u] + 2.f * (dkndt[1u] + dkndt[2u]) + dkndt[3u]);
924 auto dFdr = matrix::identity<matrix_type<3, 3>>();
925 auto dGdr = matrix::zero<matrix_type<3, 3>>();
927 if constexpr ((flags_v &
static_cast<std::uint32_t
>(
932 auto& track = stepping();
938 r_ini + half_h * sd.
t[0u] + h2 * 0.125f * sd.
dtds[0u];
948 const auto I33 = matrix::identity<matrix_type<3, 3>>();
951 dkndr[0u] = -sd.
qop[0u] * matrix::column_wise_cross(dBdr_ini, sd.
t[0u]);
953 const auto dkndr0_tmp = (I33 + h2 * 0.125f * dkndr[0u]);
956 dkndr[1u] = sd.
qop[1u] *
957 matrix::column_wise_cross(half_h * dkndr[0u], sd.
b_middle);
959 dkndr[1u] - sd.
qop[1u] * matrix::column_wise_cross(
960 dBdr_mid * dkndr0_tmp, sd.
t[1u]);
963 dkndr[2u] = sd.
qop[2u] *
964 matrix::column_wise_cross(half_h * dkndr[1u], sd.
b_middle);
966 dkndr[2u] - sd.
qop[2u] * matrix::column_wise_cross(
967 dBdr_mid * dkndr0_tmp, sd.
t[2u]);
971 sd.
qop[3u] * matrix::column_wise_cross(h * dkndr[2u], sd.
b_last);
972 dkndr[3u] = dkndr[3u] -
974 matrix::column_wise_cross(
975 dBdr_fin * (I33 + h2 * 0.5f * dkndr[2u]), sd.
t[3u]);
978 dFdr = dFdr + h * h_6 * (dkndr[0u] + dkndr[1u] + dkndr[2u]);
979 dGdr = h_6 * (dkndr[0u] + 2.f * (dkndr[1u] + dkndr[2u]) + dkndr[3u]);
985 const auto old_jacobian = stepping.internal_transport_jacobian();
987 if constexpr ((flags_v &
static_cast<std::uint32_t
>(
990 detail::update_transport_jacobian_with_gradient_impl(
991 old_jacobian, dFdt, dGdt, dFdr, dGdr, dFdqop, dGdqop, dqopqop,
992 stepping.internal_transport_jacobian());
996 detail::update_transport_jacobian_without_gradient_impl(
997 old_jacobian, dFdt, dGdt, dFdqop, dGdqop, dqopqop,
998 stepping.internal_transport_jacobian());
1009 inspector_t, flags_v>
::state& stepping,
1011 auto dBdr = matrix::zero<matrix_type<3, 3>>();
1015 for (
unsigned int i = 0; i < 3; i++) {
1018 const auto bvec1_tmp = stepping.field().at(dpos1[0], dpos1[1], dpos1[2]);
1020 bvec1[0u] = bvec1_tmp[0u];
1021 bvec1[1u] = bvec1_tmp[1u];
1022 bvec1[2u] = bvec1_tmp[2u];
1026 const auto bvec2_tmp = stepping.field().at(dpos2[0], dpos2[1], dpos2[2]);
1028 bvec2[0u] = bvec2_tmp[0u];
1029 bvec2[1u] = bvec2_tmp[1u];
1030 bvec2[2u] = bvec2_tmp[2u];
1032 assert(delta != 0.f);
1033 const vector3_type gradient = (bvec1 - bvec2) * (1.f / (2.f * delta));
1035 getter::element(dBdr, 0u, i) = gradient[0u];
1036 getter::element(dBdr, 1u, i) = gradient[1u];
1037 getter::element(dBdr, 2u, i) = gradient[2u];
Base stepper implementation.
Definition base_stepper.hpp:49
bound_track_parameters< algebra_t > bound_track_parameters_type
Definition base_stepper.hpp:57
free_track_parameters< algebra_t > free_track_parameters_type
Definition base_stepper.hpp:55
Runge-Kutta-Nystrom 4th order stepper implementation.
Definition rk_stepper.hpp:51
dscalar< algebra_t > scalar_type
Scalar type associated with the algebra backend.
Definition rk_stepper.hpp:64
void advance_jacobian(detray::rk_stepper< magnetic_field_t, algebra_t, constraint_t, policy_t, inspector_t, flags_v >::state &stepping, const stepping::config &cfg, const intermediate_state &sd, const material< scalar_type > *vol_mat_ptr) const
Update the jacobian transport from free propagation.
Definition rk_stepper.hpp:692
algebra_t algebra_type
Algebra backend used by this stepper.
Definition rk_stepper.hpp:62
std::conditional_t< uses_gradient, detail::transport_jacobian_matrix_with_gradient< algebra_type >, detail::transport_jacobian_matrix_without_gradient< algebra_type > > transport_jacobian_type
Transport Jacobian representation selected by the flags.
Definition rk_stepper.hpp:83
matrix_type< 3, 3 > evaluate_field_gradient(detray::rk_stepper< magnetic_field_t, algebra_t, constraint_t, policy_t, inspector_t, flags_v >::state &stepping, const point3_type &pos) const
Estimate the magnetic-field spatial gradient by centered differences.
Definition rk_stepper.hpp:1007
detray::pair< vector3_type, vector3_type > evaluate_dtds(detray::rk_stepper< magnetic_field_t, algebra_t, constraint_t, policy_t, inspector_t, flags_v >::state &stepping, const vector3_type &b_field, const std::size_t i, const scalar_type h, const vector3_type &dtds_prev, const scalar_type qop) const
Evaluate dtds for Runge-Kutta stepping.
Definition rk_stepper.hpp:624
static constexpr bool uses_gradient
True when field-gradient terms are available for transport.
Definition rk_stepper.hpp:57
dtransform3D< algebra_t > transform3_type
Three-dimensional transform type.
Definition rk_stepper.hpp:70
dpoint3D< algebra_t > point3_type
Three-dimensional point type.
Definition rk_stepper.hpp:66
dmatrix< algebra_t, ROWS, COLS > matrix_type
Matrix type with the requested dimensions.
Definition rk_stepper.hpp:81
detray::pair< scalar_type, scalar_type > evaluate_dqopds(detray::rk_stepper< magnetic_field_t, algebra_t, constraint_t, policy_t, inspector_t, flags_v >::state &stepping, const std::size_t i, const scalar_type h, const scalar_type dqopds_prev, const material< scalar_type > *vol_mat_ptr, const detray::stepping::config &cfg) const
evaluate dqopds for a given step size and material
Definition rk_stepper.hpp:582
dvector3D< algebra_t > vector3_type
Three-dimensional vector type.
Definition rk_stepper.hpp:68
typename base_type::bound_track_parameters_type bound_track_parameters_type
Bound track parameter type accepted by the stepper.
Definition rk_stepper.hpp:75
void advance_track(detray::rk_stepper< magnetic_field_t, algebra_t, constraint_t, policy_t, inspector_t, flags_v >::state &stepping, const intermediate_state &sd, const material< scalar_type > *vol_mat_ptr) const
Update the track state by Runge-Kutta-Nystrom integration.
Definition rk_stepper.hpp:651
magnetic_field_t magnetic_field_type
Magnetic field representation used by the stepper.
Definition rk_stepper.hpp:78
bool step(const scalar_type dist_to_next, state &stepping, const stepping::config &cfg, bool do_reset, const material< scalar_type > *vol_mat_ptr=nullptr) const
Take a step, using an adaptive Runge-Kutta algorithm.
Definition rk_stepper.hpp:320
typename base_type::free_track_parameters_type free_track_parameters_type
Free track parameter type advanced by the stepper.
Definition rk_stepper.hpp:72
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
tuple< T1, T2 > pair
A two-element tuple alias.
Definition tuple.hpp:145
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
rk_stepper_flags
Optional capabilities enabled in an RK stepper.
Definition rk_stepper.hpp:26
@ e_allow_field_gradient
Allow use of magnetic-field gradients in Jacobian transport.
Definition rk_stepper.hpp:30
@ e_allow_covariance_transport
Allow transport of the track covariance.
Definition rk_stepper.hpp:28
constexpr detray::tuple< Ts &... > tie(Ts &...args)
Create a tuple of references to the supplied objects.
Definition tuple.hpp:211
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
get_matrix_t< A, R, C, T > dmatrix
R by C matrix type for algebra A and value type T.
Definition algebra.hpp:88
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
constexpr detray::pair< std::decay_t< T1 >, std::decay_t< T2 > > make_pair(T1 &&v1, T2 &&v2)
Construct a pair by decaying and forwarding its two arguments.
Definition tuple.hpp:230
Computes energy loss and multiple scattering in detector material.
Definition interaction.hpp:23
scalar_type compute_stopping_power(const detray::material< scalar_type > &mat, const pdg_particle< scalar_type > &ptc, const relativistic_quantities &rq) const
Sum collisional and radiative stopping-power contributions.
Definition interaction.hpp:36
scalar_type derive_stopping_power(const detray::material< scalar_type > &mat, const pdg_particle< scalar_type > &ptc, const relativistic_quantities &rq) const
Differentiate the total stopping power with respect to q/p.
Definition interaction.hpp:116
Material composition properties and density data used by interactions.
Definition material.hpp:36
Per-track integration state maintained by the stepper.
Definition rk_stepper.hpp:109
void run_inspector(const stepping::config &cfg, const char *message, const scalar_type dist, Args &&... args)
Call the stepping inspector.
Definition rk_stepper.hpp:283
scalar_type d2qopdsdqop(const scalar_type qop, const material< scalar_type > *vol_mat_ptr) const
Evaluate d(d(qop)/ds)dqop.
Definition rk_stepper.hpp:240
vector3_type dtds() const
Evaluate dtds, where t is the unit tangential direction.
Definition rk_stepper.hpp:156
state(const free_track_parameters_type &t, const magnetic_field_t &mag_field)
Construct from free parameters and a magnetic field.
Definition rk_stepper.hpp:121
typename base_type::template state< transport_jacobian_type > base_state
Base state holding common track and transport data.
Definition rk_stepper.hpp:114
scalar_type dqopds(const material< scalar_type > *vol_mat_ptr) const
Evaluate d(qop)/ds.
Definition rk_stepper.hpp:186
scalar_type dqopds(const scalar_type qop, const material< scalar_type > *vol_mat_ptr) const
Evaluate the charge-over-momentum derivative at a supplied value.
Definition rk_stepper.hpp:200
void dtds(const vector3_type &v)
Set dtds, where t is the unit tangential direction.
Definition rk_stepper.hpp:180
void dqopds(const scalar_type &s)
Set d(qop)/ds.
Definition rk_stepper.hpp:233
scalar_type next_step_size() const
Definition rk_stepper.hpp:151
state(const bound_track_parameters_type &bound_params, const magnetic_field_t &mag_field, const detector_t &det, const typename detector_t::geometry_context &ctx)
Construct from bound parameters, field, and detector geometry.
Definition rk_stepper.hpp:131
const magnetic_field_type & field() const
Definition rk_stepper.hpp:139
void set_next_step_size(const scalar_type step)
Set the next step size.
Definition rk_stepper.hpp:144
Configuration flags and limits consumed by a stepper.
Definition stepping_config.hpp:29
bool use_field_gradient
Use b field gradient in error propagation.
Definition stepping_config.hpp:46
bool use_mean_loss
Use mean energy loss (Bethe) if false, most probable energy loss (Landau) will be used.
Definition stepping_config.hpp:42
float rk_error_tol
Runge-Kutta numeric error tolerance.
Definition stepping_config.hpp:33
float min_stepsize
Minimum step size.
Definition stepping_config.hpp:31
std::size_t max_rk_updates
Maximum number of Runge-Kutta step trials.
Definition stepping_config.hpp:39
bool do_covariance_transport
Do covariance transport.
Definition stepping_config.hpp:48
bool use_eloss_gradient
Use eloss gradient in error propagation.
Definition stepping_config.hpp:44
static constexpr scalar_t um
Length, native unit mm.
Definition units.hpp:25
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27