EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DefaultExtension.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DefaultExtension.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-2019 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 #include <array>
12 
14 
15 namespace Acts {
16 
21  DefaultExtension() = default;
22 
28  template <typename propagator_state_t, typename stepper_t>
29  int bid(const propagator_state_t& /*unused*/,
30  const stepper_t& /*unused*/) const {
31  return 1;
32  }
33 
48  template <typename propagator_state_t, typename stepper_t>
49  bool k(const propagator_state_t& state, const stepper_t& stepper,
50  Vector3D& knew, const Vector3D& bField, std::array<double, 4>& kQoP,
51  const int i = 0, const double h = 0.,
52  const Vector3D& kprev = Vector3D()) {
53  auto qop =
54  stepper.charge(state.stepping) / stepper.momentum(state.stepping);
55  // First step does not rely on previous data
56  if (i == 0) {
57  knew = qop * stepper.direction(state.stepping).cross(bField);
58  kQoP = {0., 0., 0., 0.};
59  } else {
60  knew =
61  qop * (stepper.direction(state.stepping) + h * kprev).cross(bField);
62  }
63  return true;
64  }
65 
76  template <typename propagator_state_t, typename stepper_t>
77  bool finalize(propagator_state_t& state, const stepper_t& stepper,
78  const double h) const {
79  propagateTime(state, stepper, h);
80  return true;
81  }
82 
94  template <typename propagator_state_t, typename stepper_t>
95  bool finalize(propagator_state_t& state, const stepper_t& stepper,
96  const double h, FreeMatrix& D) const {
97  propagateTime(state, stepper, h);
98  return transportMatrix(state, stepper, h, D);
99  }
100 
101  private:
109  template <typename propagator_state_t, typename stepper_t>
110  void propagateTime(propagator_state_t& state, const stepper_t& stepper,
111  const double h) const {
115  auto derivative =
116  std::hypot(1, state.options.mass / stepper.momentum(state.stepping));
117  state.stepping.t += h * derivative;
118  if (state.stepping.covTransport) {
119  state.stepping.derivative(3) = derivative;
120  }
121  }
122 
132  template <typename propagator_state_t, typename stepper_t>
133  bool transportMatrix(propagator_state_t& state, const stepper_t& stepper,
134  const double h, FreeMatrix& D) const {
153 
154  auto& sd = state.stepping.stepData;
155  auto dir = stepper.direction(state.stepping);
156  auto qop =
157  stepper.charge(state.stepping) / stepper.momentum(state.stepping);
158 
159  D = FreeMatrix::Identity();
160 
161  double half_h = h * 0.5;
162  // This sets the reference to the sub matrices
163  // dFdx is already initialised as (3x3) idendity
164  auto dFdT = D.block<3, 3>(0, 4);
165  auto dFdL = D.block<3, 1>(0, 7);
166  // dGdx is already initialised as (3x3) zero
167  auto dGdT = D.block<3, 3>(4, 4);
168  auto dGdL = D.block<3, 1>(4, 7);
169 
174 
175  Vector3D dk1dL = Vector3D::Zero();
176  Vector3D dk2dL = Vector3D::Zero();
177  Vector3D dk3dL = Vector3D::Zero();
178  Vector3D dk4dL = Vector3D::Zero();
179 
180  // For the case without energy loss
181  dk1dL = dir.cross(sd.B_first);
182  dk2dL = (dir + half_h * sd.k1).cross(sd.B_middle) +
183  qop * half_h * dk1dL.cross(sd.B_middle);
184  dk3dL = (dir + half_h * sd.k2).cross(sd.B_middle) +
185  qop * half_h * dk2dL.cross(sd.B_middle);
186  dk4dL =
187  (dir + h * sd.k3).cross(sd.B_last) + qop * h * dk3dL.cross(sd.B_last);
188 
189  dk1dT(0, 1) = sd.B_first.z();
190  dk1dT(0, 2) = -sd.B_first.y();
191  dk1dT(1, 0) = -sd.B_first.z();
192  dk1dT(1, 2) = sd.B_first.x();
193  dk1dT(2, 0) = sd.B_first.y();
194  dk1dT(2, 1) = -sd.B_first.x();
195  dk1dT *= qop;
196 
197  dk2dT += half_h * dk1dT;
198  dk2dT = qop * VectorHelpers::cross(dk2dT, sd.B_middle);
199 
200  dk3dT += half_h * dk2dT;
201  dk3dT = qop * VectorHelpers::cross(dk3dT, sd.B_middle);
202 
203  dk4dT += h * dk3dT;
204  dk4dT = qop * VectorHelpers::cross(dk4dT, sd.B_last);
205 
206  dFdT.setIdentity();
207  dFdT += h / 6. * (dk1dT + dk2dT + dk3dT);
208  dFdT *= h;
209 
210  dFdL = (h * h) / 6. * (dk1dL + dk2dL + dk3dL);
211 
212  dGdT += h / 6. * (dk1dT + 2. * (dk2dT + dk3dT) + dk4dT);
213 
214  dGdL = h / 6. * (dk1dL + 2. * (dk2dL + dk3dL) + dk4dL);
215 
216  D(3, 7) =
217  h * state.options.mass * state.options.mass *
218  stepper.charge(state.stepping) /
219  (stepper.momentum(state.stepping) *
220  std::hypot(1., state.options.mass / stepper.momentum(state.stepping)));
221  return true;
222  }
223 };
224 } // namespace Acts