Peano
Loading...
Searching...
No Matches
swift2::kernels::ParticleBinaryOperator Concept Reference

Definition of particle-particle interaction. More...

#include <ParticleSetIterators.h>

Concept definition

template<typename F, typename LocalParticle, typename ActiveParticle>
concept swift2::kernels::ParticleBinaryOperator = requires (F f, const peano4::datamanagement::CellMarker& marker, LocalParticle& localParticle, ActiveParticle& activeParticle) {
{ f(marker, localParticle, activeParticle) } -> std::same_as<void>;
}
double f(double p4, double p1, double p5, double rho1, double rho5, double gamma)
Definition of particle-particle interaction.

Detailed Description

Definition of particle-particle interaction.

This definition works if LocalParticle is a real type, but it also works if it is a pointer, as we then get references to pointers in the signature which degenerates to the pointers in the source code. However, I usually use it without any pointer semantics.

The interface uses the marker, as it is the responsibility of anyupdate to check if the update is actually valid". That is, a binary operator should always use a UpdateParticlePairWithinCellPredicate internally to check if it actually should update. How this knowledge is taken into account is however up to the realisation. In the simplest case, it is just a mere enclosing if statement.

So one we assume that we employ localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle as update rule, a function implementing the concept of ParticleBinaryOperator resembles

void myParticleBinaryOperator(
globaldata::MyParticle& localParticle,
globaldata::MyParticle& activeParticle
) {
marker,
localParticle,
activeParticle
)) {
[...] // your code
}
}
bool localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle(const peano4::datamanagement::CellMarker &marker, const Particle &localParticle, const Particle &activeParticle)
Can we do work on this particle during a cell kernel sweep stage?

This function can now be used anywhere where a template expects a ParticleBinaryOperator.

Using the function

Once you have introduced your function (in a cpp file of your choice, e.g.), you can hand it in via a plain myParticleBinaryOperator argument.

For very simple interactions that you define only once, don't want to unit test, ... you might skip the explicit declaration and add the thing in directly as a functor:

[=](
globaldata::MyParticle& localParticle,
globaldata::MyParticle& activeParticle
) -> void {
marker,
localParticle,
activeParticle
)) {
[...] // your code
}
}

Type-generic interaction operators

Obviously, you might want to make this function a template, so it can be used for different particles. It might also be tempting to distinguish the type of active and local particles, so you can have interactions between different species:

template <typename LocalParticle, typename ActiveParticle>
void myParticleBinaryOperator(
LocalParticle& localParticle,
ActiveParticle& activeParticle
) {

The only thing to take into account is that the compiler now might struggle to deduce the type. If this happens, simply hand in

myParticleBinaryOperator<globaldata::MyType,globaldata::MyType>

as argument where myParticleBinaryOperator had been sufficient before.

Definition at line 163 of file ParticleSetIterators.h.