Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StepperExtensionList.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file StepperExtensionList.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2021 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 
17 
18 #include <array>
19 
20 namespace Acts {
21 
36 template <typename... extensions>
37 struct StepperExtensionList : private detail::Extendable<extensions...> {
38  private:
39  // Checkout for duplicates in the extensions
40  static_assert(not detail::has_duplicates_v<extensions...>,
41  "same extension type specified several times");
42 
43  static constexpr unsigned int nExtensions = sizeof...(extensions);
44 
45  static_assert(nExtensions != 0, "no extension type specified");
46 
47  // Access to all extensions
49 
50  // Vector of valid extensions for a step
51  std::array<bool, nExtensions> validExtensions{};
52 
53  public:
54  // Access to an extension
56 
67  template <typename propagator_state_t, typename stepper_t,
68  typename navigtor_t>
69  bool validExtensionForStep(const propagator_state_t& state,
70  const stepper_t& stepper,
71  const navigtor_t& navigator) {
72  const auto bids = std::apply(
73  [&](const auto&... ext) {
74  return std::array<int, nExtensions>{
75  ext.bid(state, stepper, navigator)...};
76  },
77  tuple());
78 
79  validExtensions = state.stepping.auctioneer(std::move(bids));
80 
81  return (std::find(validExtensions.begin(), validExtensions.end(), true) !=
82  validExtensions.end());
83  }
84 
89  template <typename propagator_state_t, typename stepper_t,
90  typename navigator_t>
91  bool k(const propagator_state_t& state, const stepper_t& stepper,
92  const navigator_t& navigator, Vector3& knew, const Vector3& bField,
93  std::array<double, 4>& kQoP, const int i, const double h = 0.,
94  const Vector3& kprev = Vector3::Zero()) {
95  // TODO replace with integer-templated lambda with C++20
96  auto impl = [&, i, h](auto intType, auto& implRef) {
97  constexpr int N = decltype(intType)::value;
98 
99  if constexpr (N == 0) {
100  return true;
101  } else {
102  // If element is invalid: continue
103  if (!std::get<N - 1>(validExtensions)) {
104  return implRef(std::integral_constant<int, N - 1>{}, implRef);
105  }
106  // Continue as long as evaluations are 'true'
107  if (std::get<N - 1>(this->tuple())
108  .template k(state, stepper, navigator, knew, bField, kQoP, i, h,
109  kprev)) {
110  return implRef(std::integral_constant<int, N - 1>{}, implRef);
111  } else {
112  // Break at false
113  return false;
114  }
115  }
116  };
117 
118  return impl(std::integral_constant<int, nExtensions>{}, impl);
119  }
120 
125  template <typename propagator_state_t, typename stepper_t,
126  typename navigator_t>
127  bool k1(const propagator_state_t& state, const stepper_t& stepper,
128  const navigator_t& navigator, Vector3& knew, const Vector3& bField,
129  std::array<double, 4>& kQoP) {
130  return k(state, stepper, navigator, knew, bField, kQoP, 0);
131  }
132 
136  template <typename propagator_state_t, typename stepper_t,
137  typename navigator_t>
138  bool k2(const propagator_state_t& state, const stepper_t& stepper,
139  const navigator_t& navigator, Vector3& knew, const Vector3& bField,
140  std::array<double, 4>& kQoP, const double h, const Vector3& kprev) {
141  return k(state, stepper, navigator, knew, bField, kQoP, 1, h, kprev);
142  }
143 
147  template <typename propagator_state_t, typename stepper_t,
148  typename navigator_t>
149  bool k3(const propagator_state_t& state, const stepper_t& stepper,
150  const navigator_t& navigator, Vector3& knew, const Vector3& bField,
151  std::array<double, 4>& kQoP, const double h, const Vector3& kprev) {
152  return k(state, stepper, navigator, knew, bField, kQoP, 2, h, kprev);
153  }
154 
158  template <typename propagator_state_t, typename stepper_t,
159  typename navigator_t>
160  bool k4(const propagator_state_t& state, const stepper_t& stepper,
161  const navigator_t& navigator, Vector3& knew, const Vector3& bField,
162  std::array<double, 4>& kQoP, const double h, const Vector3& kprev) {
163  return k(state, stepper, navigator, knew, bField, kQoP, 3, h, kprev);
164  }
165 
169  template <typename propagator_state_t, typename stepper_t,
170  typename navigator_t>
171  bool finalize(propagator_state_t& state, const stepper_t& stepper,
172  const navigator_t& navigator, const double h, FreeMatrix& D) {
173  // TODO replace with integer-templated lambda with C++20
174  auto impl = [&, h](auto intType, auto& implRef) {
175  constexpr int N = decltype(intType)::value;
176 
177  if constexpr (N == 0) {
178  return true;
179  } else {
180  // If element is invalid: continue
181  if (!std::get<N - 1>(validExtensions)) {
182  return implRef(std::integral_constant<int, N - 1>{}, implRef);
183  }
184  // Continue as long as evaluations are 'true'
185  if (std::get<N - 1>(this->tuple())
186  .finalize(state, stepper, navigator, h, D)) {
187  return implRef(std::integral_constant<int, N - 1>{}, implRef);
188  } else {
189  // Break at false
190  return false;
191  }
192  }
193  };
194 
195  return impl(std::integral_constant<int, nExtensions>{}, impl);
196  }
197 
201  template <typename propagator_state_t, typename stepper_t,
202  typename navigator_t>
203  bool finalize(propagator_state_t& state, const stepper_t& stepper,
204  const navigator_t& navigator, const double h) {
205  // TODO replace with integer-templated lambda with C++20
206  auto impl = [&, h](auto intType, auto& implRef) {
207  constexpr int N = decltype(intType)::value;
208 
209  if constexpr (N == 0) {
210  return true;
211  } else {
212  // If element is invalid: continue
213  if (!std::get<N - 1>(validExtensions)) {
214  return implRef(std::integral_constant<int, N - 1>{}, implRef);
215  }
216 
217  // Continue as long as evaluations are 'true'
218  if (std::get<N - 1>(this->tuple())
219  .finalize(state, stepper, navigator, h)) {
220  return implRef(std::integral_constant<int, N - 1>{}, implRef);
221  } else {
222  // Break at false
223  return false;
224  }
225  }
226  };
227 
228  return impl(std::integral_constant<int, nExtensions>{}, impl);
229  }
230 };
231 
232 } // namespace Acts