diff --git a/examples/external_fields/pgen.hpp b/examples/external_fields/pgen.hpp index ac4f6faed..30fb2473d 100644 --- a/examples/external_fields/pgen.hpp +++ b/examples/external_fields/pgen.hpp @@ -40,7 +40,8 @@ namespace user { */ // f_ext: external force-field (acceleration): - Inline auto fx1(const coord_t&) const -> real_t { + Inline auto fx1(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const + -> real_t { return (sp % 2u == 0u) ? -HALF : HALF; } diff --git a/src/global/traits/archetypes.h b/src/global/traits/archetypes.h index e170170fb..c5582e74b 100644 --- a/src/global/traits/archetypes.h +++ b/src/global/traits/archetypes.h @@ -4,7 +4,7 @@ * @implements * - EnrgDistClass<> - checks if a class can be used as an energy distribution * - SpatialDistClass<> - checks if a class can be used as a spatial distribution - * - traits::fieldsetter::HasFx1, ::HasFx2, ::HasFx3 - checks for F functions in field setter class + * - traits::fieldsetter::HasFx1, ::HasFx2, ::HasFx3 - checks for particle-aware F functions fx*(x, particles, p) * - traits::fieldsetter::HasEx1, ::HasEx2, ::HasEx3 - checks for E functions in field setter class * - traits::fieldsetter::HasBx1, ::HasBx2, ::HasBx3 - checks for B functions in field setter class * - traits::fieldsetter::HasDx1, ::HasDx2, ::HasDx3 - checks for D functions in field setter class @@ -26,6 +26,10 @@ #include +namespace ntt { + struct ParticleArrays; +} // namespace ntt + template concept EnrgDistClass = requires(const ED& edist, const coord_t& x_Ph, @@ -50,18 +54,27 @@ concept SpatialDistClass = SimpleSpatialDistClass or namespace traits::fieldsetter { template - concept HasFx1 = requires(const T& t, const coord_t& x_Ph) { - { t.fx1(x_Ph) } -> std::convertible_to; + concept HasFx1 = requires(const T& t, + const coord_t& x_Ph, + const ntt::ParticleArrays& prtls, + prtlidx_t p) { + { t.fx1(x_Ph, prtls, p) } -> std::convertible_to; }; template - concept HasFx2 = requires(const T& t, const coord_t& x_Ph) { - { t.fx2(x_Ph) } -> std::convertible_to; + concept HasFx2 = requires(const T& t, + const coord_t& x_Ph, + const ntt::ParticleArrays& prtls, + prtlidx_t p) { + { t.fx2(x_Ph, prtls, p) } -> std::convertible_to; }; template - concept HasFx3 = requires(const T& t, const coord_t& x_Ph) { - { t.fx3(x_Ph) } -> std::convertible_to; + concept HasFx3 = requires(const T& t, + const coord_t& x_Ph, + const ntt::ParticleArrays& prtls, + prtlidx_t p) { + { t.fx3(x_Ph, prtls, p) } -> std::convertible_to; }; template diff --git a/src/kernels/pushers/sr.hpp b/src/kernels/pushers/sr.hpp index 78b5c4916..bc7d79f08 100644 --- a/src/kernels/pushers/sr.hpp +++ b/src/kernels/pushers/sr.hpp @@ -245,7 +245,7 @@ namespace kernel::sr { // compute the external force either user-provided or from the atmosphere model if constexpr (HasExtForce or Atm) { - getExternalForce(xp_Cd, xp_Ph, external_force_Cart); + getExternalForce(xp_Cd, xp_Ph, p, external_force_Cart); } if (ctx.pusher_flags & ParticlePusher::GCA) { @@ -1425,18 +1425,19 @@ namespace kernel::sr { Inline void getExternalForce(const coord_t& xp_Cd, const coord_t& xp_Ph, + [[maybe_unused]] prtlidx_t p, vec_t& external_force_Cart) const requires(Atm or HasExtForce) { real_t f_x1 = ZERO, f_x2 = ZERO, f_x3 = ZERO; if constexpr (HasExtFx1) { - f_x1 = policies.external_fields_policy.fx1(xp_Ph); + f_x1 = policies.external_fields_policy.fx1(xp_Ph, particles, p); } if constexpr (HasExtFx2) { - f_x2 = policies.external_fields_policy.fx2(xp_Ph); + f_x2 = policies.external_fields_policy.fx2(xp_Ph, particles, p); } if constexpr (HasExtFx3) { - f_x3 = policies.external_fields_policy.fx3(xp_Ph); + f_x3 = policies.external_fields_policy.fx3(xp_Ph, particles, p); } if constexpr (Atm) { if constexpr (D == Dim::_1D or D == Dim::_2D or D == Dim::_3D) { diff --git a/tests/archetypes/pgen.cpp b/tests/archetypes/pgen.cpp index d95e9cf9c..fb428493b 100644 --- a/tests/archetypes/pgen.cpp +++ b/tests/archetypes/pgen.cpp @@ -25,7 +25,8 @@ struct CustomFieldsetter { template struct ExtForce { - Inline auto fx1(const coord_t&) const -> real_t { + Inline auto fx1(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const + -> real_t { return ZERO; } diff --git a/tests/global/traits_archetypes.cpp b/tests/global/traits_archetypes.cpp index d72545102..575b7abe5 100644 --- a/tests/global/traits_archetypes.cpp +++ b/tests/global/traits_archetypes.cpp @@ -89,15 +89,15 @@ struct WithDx1Dx2Dx3 { }; struct WithFx1Fx2Fx3 { - real_t fx1(const coord_t&) const { + real_t fx1(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const { return ZERO; } - real_t fx2(const coord_t&) const { + real_t fx2(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const { return ZERO; } - real_t fx3(const coord_t&) const { + real_t fx3(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const { return ZERO; } }; diff --git a/tests/global/traits_policies.cpp b/tests/global/traits_policies.cpp index 5f5a83f9f..82ceb7e12 100644 --- a/tests/global/traits_policies.cpp +++ b/tests/global/traits_policies.cpp @@ -105,7 +105,7 @@ static_assert(not EmissionPolicyClass); // --- ExtFieldsPolicyClass --- struct WithFx1 { - real_t fx1(const coord_t&) const { + real_t fx1(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const { return ZERO; } }; diff --git a/tests/kernels/ext_force.cpp b/tests/kernels/ext_force.cpp index 69d773d10..d9e8203a5 100644 --- a/tests/kernels/ext_force.cpp +++ b/tests/kernels/ext_force.cpp @@ -54,15 +54,18 @@ void put_value(array_t& arr, T v, prtlidx_t p) { struct Force { Force(real_t force) : force { force } {} - Inline auto fx1(const coord_t&) const -> real_t { + Inline auto fx1(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const + -> real_t { return force * math::sin(ONE) * math::sin(ONE); } - Inline auto fx2(const coord_t&) const -> real_t { + Inline auto fx2(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const + -> real_t { return force * math::sin(ONE) * math::cos(ONE); } - Inline auto fx3(const coord_t&) const -> real_t { + Inline auto fx3(const coord_t&, const ntt::ParticleArrays&, prtlidx_t) const + -> real_t { return force * math::cos(ONE); }