Skip to content

External force extension - #222

Open
LudwigBoess wants to merge 3 commits into
1.5.0rcfrom
dev/external_force_particleprops
Open

External force extension#222
LudwigBoess wants to merge 3 commits into
1.5.0rcfrom
dev/external_force_particleprops

Conversation

@LudwigBoess

Copy link
Copy Markdown
Collaborator

Added the option to access particle properties in the external force computation. This allows to compute more than just external force fields.

@LudwigBoess
LudwigBoess requested a review from haykh July 28, 2026 23:24
@LudwigBoess
LudwigBoess marked this pull request as ready for review August 7, 2026 20:30
@haykh

haykh commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

@LudwigBoess i think this is a bit too destructive and backwards incompatible. let's go with something like this:

define a new trait in global/traits/archetypes.h:

namespace traits::fieldsetter {
  template <class T, Dimension D>
  concept HasFx1WithIndex = requires(const T& t, const coord_t<D>& x_Ph, prtlidx_t p) { ... };
  // note that we are NOT passing particle arrays here.
}

change the ExtFieldPolicyClass to reflect this new trait:

concept ExtFieldPolicyClass = ... or ::traits::fieldsetter::HasFx1WithIndex<F, D> ...;

then in the pusher you can have:

static constexpr auto HasExtFx1 = ::traits::fieldsetter::HasFx1<F, D>;
static constexpr auto HasExtFx1WithIndex = ::traits::fieldsetter::HasFx1WithIndex<F, D>;

// ... then when calling in the `getExternalForce`:

if constexpr (HasExtFx1WithIndex) {
  f_x1 = policies.external_fields_policy.fx1(x_Ph, p);
} else if constexpr (HasExtFx1) {
  f_x1 = policies.external_fields_policy.fx1(x_Ph);
} ...

Now in the problem generator, when you define the external fields class with the new caller:

template <Dimension D>
class MyExtField {
  ParticleArrays prtls;
  
  MyExtField(const ParticleArrays& prtls) : prtls { prtls } {}

public:
  Inline auto fx1(const coord_t<D>&, prtlidx_t p) const -> real_t { ... }
};

// then in pgen class:

auto ExternalFields(simtime_t time, spidx_t sp, const Domain<S, M>& domain) const -> std::pair<bool, MyExtFields<M::Dim> {
  return { true, MyExtFields<M::Dim> { domain.species[sp - 1] } }; // this will cast Particles object to ParticleArrays which is serializable
}

And that should be it. the old functionality will still work while allowing for additional flexibility. Do you wanna give it a shot, or should i do that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants