EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EigenStepper.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EigenStepper.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
11 // Workaround for building on clang+libstdc++
13 
23 #include "Acts/Utilities/Units.hpp"
24 
25 #include <cmath>
26 #include <functional>
27 #include <limits>
28 
29 namespace Acts {
30 
31 using namespace Acts::UnitLiterals;
32 
45 template <typename bfield_t,
46  typename extensionlist_t = StepperExtensionList<DefaultExtension>,
47  typename auctioneer_t = detail::VoidAuctioneer>
48 class EigenStepper {
49  public:
53  using BoundState = std::tuple<BoundTrackParameters, Jacobian, double>;
54  using CurvilinearState =
55  std::tuple<CurvilinearTrackParameters, Jacobian, double>;
56  using BField = bfield_t;
57 
62  struct State {
64  State() = delete;
65 
76  template <typename parameters_t>
77  explicit State(std::reference_wrapper<const GeometryContext> gctx,
78  std::reference_wrapper<const MagneticFieldContext> mctx,
79  const parameters_t& par, NavigationDirection ndir = forward,
80  double ssize = std::numeric_limits<double>::max(),
81  double stolerance = s_onSurfaceTolerance)
82  : pos(par.position(gctx)),
83  dir(par.unitDirection()),
84  p(par.absoluteMomentum()),
85  q(par.charge()),
86  t(par.time()),
87  navDir(ndir),
88  stepSize(ndir * std::abs(ssize)),
89  tolerance(stolerance),
90  fieldCache(mctx),
91  geoContext(gctx) {
92  // Init the jacobian matrix if needed
93  if (par.covariance()) {
94  // Get the reference surface for navigation
95  const auto& surface = par.referenceSurface();
96  // set the covariance transport flag to true and copy
97  covTransport = true;
98  cov = BoundSymMatrix(*par.covariance());
99  surface.initJacobianToGlobal(gctx, jacToGlobal, pos, dir,
100  par.parameters());
101  }
102  }
103 
105  Vector3D pos = Vector3D(0., 0., 0.);
106 
108  Vector3D dir = Vector3D(1., 0., 0.);
109 
111  double p = 0.;
112 
114  double q = 1.;
115 
117  double t = 0.;
118 
121 
123  Jacobian jacobian = Jacobian::Identity();
124 
126  BoundToFreeMatrix jacToGlobal = BoundToFreeMatrix::Zero();
127 
129  FreeMatrix jacTransport = FreeMatrix::Identity();
130 
132  FreeVector derivative = FreeVector::Zero();
133 
136  bool covTransport = false;
137  Covariance cov = Covariance::Zero();
138 
140  double pathAccumulated = 0.;
141 
144 
146  double previousStepSize = 0.;
147 
150 
154  typename BField::Cache fieldCache;
155 
157  std::reference_wrapper<const GeometryContext> geoContext;
158 
160  extensionlist_t extension;
161 
163  auctioneer_t auctioneer;
164 
166  struct {
168  Vector3D B_first, B_middle, B_last;
170  Vector3D k1, k2, k3, k4;
172  std::array<double, 4> kQoP;
173  } stepData;
174  };
175 
178 
187  void resetState(
188  State& state, const BoundVector& boundParams, const BoundSymMatrix& cov,
190  const double stepSize = std::numeric_limits<double>::max()) const;
191 
198  Vector3D getField(State& state, const Vector3D& pos) const {
199  // get the field from the cell
200  return m_bField.getField(pos, state.fieldCache);
201  }
202 
206  Vector3D position(const State& state) const { return state.pos; }
207 
211  Vector3D direction(const State& state) const { return state.dir; }
212 
216  double momentum(const State& state) const { return state.p; }
217 
221  double charge(const State& state) const { return state.q; }
222 
226  double time(const State& state) const { return state.t; }
227 
236  Intersection3D::Status updateSurfaceStatus(
237  State& state, const Surface& surface, const BoundaryCheck& bcheck) const {
238  return detail::updateSingleSurfaceStatus<EigenStepper>(*this, state,
239  surface, bcheck);
240  }
241 
252  template <typename object_intersection_t>
253  void updateStepSize(State& state, const object_intersection_t& oIntersection,
254  bool release = true) const {
255  detail::updateSingleStepSize<EigenStepper>(state, oIntersection, release);
256  }
257 
263  void setStepSize(State& state, double stepSize,
265  state.previousStepSize = state.stepSize;
266  state.stepSize.update(stepSize, stype, true);
267  }
268 
272  void releaseStepSize(State& state) const {
274  }
275 
279  std::string outputStepSize(const State& state) const {
280  return state.stepSize.toString();
281  }
282 
286  double overstepLimit(const State& /*state*/) const {
287  // A dynamic overstep limit could sit here
288  return -m_overstepLimit;
289  }
290 
305  BoundState boundState(State& state, const Surface& surface) const;
306 
318  CurvilinearState curvilinearState(State& state) const;
319 
324  void update(State& state, const FreeVector& parameters,
325  const Covariance& covariance) const;
326 
333  void update(State& state, const Vector3D& uposition,
334  const Vector3D& udirection, double up, double time) const;
335 
343  void covarianceTransport(State& state) const;
344 
354  void covarianceTransport(State& state, const Surface& surface) const;
355 
366  template <typename propagator_state_t>
367  Result<double> step(propagator_state_t& state) const;
368 
369  private:
372 
374  double m_overstepLimit = 100_um;
375 };
376 } // namespace Acts
377