Skip to content

Commit 1209d7c

Browse files
authored
Merge pull request #678 from beomki-yeo/fix-script3
Fix bug in the stepper and improve the validation scripts
2 parents 14f59f1 + 049c8e3 commit 1209d7c

File tree

7 files changed

+279
-238
lines changed

7 files changed

+279
-238
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
**/*.d
1616
**/*.so
1717
**/*C_ACLiC_dict*
18-
**/therad_*
18+
**/thread_*
19+
**/merged/

core/include/detray/propagator/rk_stepper.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class rk_stepper final
121121

122122
/// Evaluate dtds, where t is the unit tangential direction
123123
DETRAY_HOST_DEVICE
124-
inline vector3 dtds() const { return this->_step_data.dtds[3u]; }
124+
inline vector3 dtds() const;
125125

126126
/// Evaulate d(qop)/ds
127127
DETRAY_HOST_DEVICE

core/include/detray/propagator/rk_stepper.ipp

+58-19
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,8 @@ detray::rk_stepper<magnetic_field_t, transform3_t, constraint_t, policy_t,
137137
* [ Table for dqop_n/dqop1 ]
138138
* dqop1/dqop1 = 1
139139
* dqop2/dqop1 = 1 + h/2 * d(dqop1/ds)/dqop1
140-
* dqop3/dqop1 = 1 + h/2 * d(dqop1/ds)/dqop1 + h^2/4 d(d^2qop1/ds^2)/dqop1
141-
* dqop4/dqop1 = 1 + h * d(dqop1/ds)/dqop1 + h^2/2 d(d^2qop1/ds^2)/dqop1
142-
* + h^3/4 d(d^3qop1/ds^3)/dqop1
140+
* dqop3/dqop1 = 1 + h/2 * d(dqop2/ds)/dqop1
141+
* dqop4/dqop1 = 1 + h * d(dqop3/ds)/dqop1
143142
*
144143
* [ Table for dt_n/dqop1 ]
145144
* dt1/dqop1 = 0
@@ -176,31 +175,43 @@ detray::rk_stepper<magnetic_field_t, transform3_t, constraint_t, policy_t,
176175
/*---------------------------------------------------------------------------
177176
* d(dqop_n/ds)/dqop1
178177
*
179-
* [ Table for dqop_n/ds ]
180-
* dqop1/ds = qop1^3 * E * (-dE/ds) / q^2
181-
* dqop2/ds = d(qop1 + h/2 * dqop1/ds)/ds = dqop1/ds + h/2 * d^2(qop1)/ds^2
182-
* dqop3/ds = d(qop1 + h/2 * dqop2/ds)/ds = dqop1/ds + h/2 * d^2(qop2)/ds^2
183-
* dqop4/ds = d(qop1 + h * dqop3/ds)/ds = dqop1/ds + h * d^2(qop3)/ds^2
178+
* Useful equation:
179+
* dqop/ds = qop^3 * E * (-dE/ds) / q^2 = - qop^3 * E g / q^2
180+
181+
* [ Table for d(dqop_n/ds)/dqop1 ]
182+
* d(dqop1/ds)/dqop1 = dqop1/ds * (1/qop * (3 - p^2/E^2) + 1/g1 * dg1dqop1
183+
* d(dqop2/ds)/dqop1 = d(dqop2/ds)/dqop2 * (1 + h/2 * d(dqop1/ds)/dqop1)
184+
* d(dqop3/ds)/dqop1 = d(dqop3/ds)/dqop3 * (1 + h/2 * d(dqop2/ds)/dqop1)
185+
* d(dqop4/ds)/dqop1 = d(dqop4/ds)/dqop4 * (1 + h * d(dqop3/ds)/dqop1)
184186
---------------------------------------------------------------------------*/
185187

186188
if (!cfg.use_eloss_gradient) {
187189
getter::element(D, e_free_qoverp, e_free_qoverp) = 1.f;
188190
} else {
189191
// Pre-calculate dqop_n/dqop1
190-
// Note that terms with d^2/ds^2 or d^3/ds^3 are ignored
191192
const scalar_type d2qop1dsdqop1 = this->d2qopdsdqop(sd.qop[0u]);
193+
192194
dqopn_dqop[0u] = 1.f;
193195
dqopn_dqop[1u] = 1.f + half_h * d2qop1dsdqop1;
194-
dqopn_dqop[2u] = dqopn_dqop[1u];
195-
dqopn_dqop[3u] = 1.f + h * d2qop1dsdqop1;
196+
197+
const scalar_type d2qop2dsdqop1 =
198+
this->d2qopdsdqop(sd.qop[1u]) * (1.f + half_h * d2qop1dsdqop1);
199+
dqopn_dqop[2u] = 1.f + half_h * d2qop2dsdqop1;
200+
201+
const scalar_type d2qop3dsdqop1 =
202+
this->d2qopdsdqop(sd.qop[2u]) * (1.f + half_h * d2qop2dsdqop1);
203+
dqopn_dqop[3u] = 1.f + h * d2qop3dsdqop1;
204+
205+
const scalar_type d2qop4dsdqop1 =
206+
this->d2qopdsdqop(sd.qop[3u]) * (1.f + h * d2qop3dsdqop1);
196207

197208
/*-----------------------------------------------------------------
198209
* Calculate the first terms of d(dqop_n/ds)/dqop1
199210
-------------------------------------------------------------------*/
200211

201-
// Note that terms with d^2/ds^2 are ignored
202212
getter::element(D, e_free_qoverp, e_free_qoverp) =
203-
1.f + d2qop1dsdqop1 * h;
213+
1.f + h_6 * (d2qop1dsdqop1 + 2.f * (d2qop2dsdqop1 + d2qop3dsdqop1) +
214+
d2qop4dsdqop1);
204215
}
205216

206217
// Calculate in the case of not considering B field gradient
@@ -309,26 +320,26 @@ detray::rk_stepper<magnetic_field_t, transform3_t, constraint_t, policy_t,
309320
dqopn_dqop[1u] * vector::cross(sd.t[1u], sd.b_middle) +
310321
sd.qop[1u] * half_h * vector::cross(dkndqop[0u], sd.b_middle);
311322
dkndqop[1u] =
312-
dkndqop[1u] +
323+
dkndqop[1u] -
313324
sd.qop[1u] *
314-
vector::cross(sd.t[1u], h2 * 0.125f * dBdr[1u] * dkndqop[0u]);
325+
vector::cross(h2 * 0.125f * dBdr[1u] * dkndqop[0u], sd.t[1u]);
315326

316327
// dk3/dqop1
317328
dkndqop[2u] =
318329
dqopn_dqop[2u] * vector::cross(sd.t[2u], sd.b_middle) +
319330
sd.qop[2u] * half_h * vector::cross(dkndqop[1u], sd.b_middle);
320331
dkndqop[2u] =
321-
dkndqop[2u] +
332+
dkndqop[2u] -
322333
sd.qop[2u] *
323-
vector::cross(sd.t[2u], h2 * 0.125f * dBdr[2u] * dkndqop[0u]);
334+
vector::cross(h2 * 0.125f * dBdr[2u] * dkndqop[0u], sd.t[2u]);
324335

325336
// dk4/dqop1
326337
dkndqop[3u] = dqopn_dqop[3u] * vector::cross(sd.t[3u], sd.b_last) +
327338
sd.qop[3u] * h * vector::cross(dkndqop[2u], sd.b_last);
328339
dkndqop[3u] =
329-
dkndqop[3u] +
340+
dkndqop[3u] -
330341
sd.qop[3u] *
331-
vector::cross(sd.t[3u], h2 * 0.5f * dBdr[3u] * dkndqop[2u]);
342+
vector::cross(h2 * 0.5f * dBdr[3u] * dkndqop[2u], sd.t[3u]);
332343

333344
/*-----------------------------------------------------------------
334345
* Calculate all terms of dk_n/dr1
@@ -494,13 +505,41 @@ DETRAY_HOST_DEVICE auto detray::rk_stepper<
494505
return dBdr;
495506
}
496507

508+
template <typename magnetic_field_t, typename transform3_t,
509+
typename constraint_t, typename policy_t, typename inspector_t,
510+
template <typename, std::size_t> class array_t>
511+
DETRAY_HOST_DEVICE auto
512+
detray::rk_stepper<magnetic_field_t, transform3_t, constraint_t, policy_t,
513+
inspector_t, array_t>::state::dtds() const -> vector3 {
514+
515+
// In case there was no step before
516+
if (this->_path_length == 0.f) {
517+
const vector3 pos = this->_track.pos();
518+
519+
const auto bvec_tmp = this->_magnetic_field.at(pos[0], pos[1], pos[2]);
520+
vector3 bvec;
521+
bvec[0u] = bvec_tmp[0u];
522+
bvec[1u] = bvec_tmp[1u];
523+
bvec[2u] = bvec_tmp[2u];
524+
525+
return this->_track.qop() * vector::cross(this->_track.dir(), bvec);
526+
}
527+
return this->_step_data.dtds[3u];
528+
}
529+
497530
template <typename magnetic_field_t, typename transform3_t,
498531
typename constraint_t, typename policy_t, typename inspector_t,
499532
template <typename, std::size_t> class array_t>
500533
DETRAY_HOST_DEVICE auto
501534
detray::rk_stepper<magnetic_field_t, transform3_t, constraint_t, policy_t,
502535
inspector_t, array_t>::state::dqopds() const ->
503536
typename transform3_t::scalar_type {
537+
538+
// In case there was no step before
539+
if (this->_path_length == 0.f) {
540+
return this->dqopds(this->_track.qop());
541+
}
542+
504543
return this->_step_data.dqopds[3u];
505544
}
506545

tests/include/detray/test/utils/particle_gun.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "detray/utils/ranges.hpp"
1616

1717
// System include(s)
18+
#include <algorithm>
1819
#include <cmath>
1920
#include <type_traits>
2021

0 commit comments

Comments
 (0)