|
Peano
|
Namespaces | |
| namespace | gravity |
| namespace | internal |
| namespace | kernelrealisation |
| Different (generic) kernel realisations. | |
| namespace | legacy |
| Legacy SPH implementation. | |
Concepts | |
| concept | ParticleUnaryOperatorOnVertex |
| Definition of particle update (unary operation) | |
| concept | ParticleUnaryOperatorOnCell |
| concept | ParticleBinaryOperator |
| Definition of particle-particle interaction. | |
Typedefs | |
| template<typename ParticleContainer > | |
| using | PCParticle = typename std::remove_pointer<typename ParticleContainer::value_type>::type |
| template<typename Particle > | |
| using | UpdateParticlePairWithinCellPredicate |
| template<typename Particle > | |
| using | UpdateParticleAssignedToCellPredicate |
| template<typename Particle > | |
| using | UpdateParticleAssignedToVertexPredicate |
Functions | |
| template<typename ParticleA , typename ParticleB = ParticleA> | |
| bool | forceKernelDistanceCheck (ParticleA &__restrict__ localParticle, const ParticleB &__restrict__ activeParticle) |
| template<typename Particle > | |
| void | adoptInteractionRadiusAndTriggerRerun (const std::list< Particle * > &localParticles, const std::list< Particle * > &activeParticles, int targetNumberOfNeighbourParticles, double maxGrowthPerSweep=2.0, double shrinkingFactor=0.8) |
| This routine runs over all the local particles and tries to ensure that the number of particles equals roughly targetNumberOfNeighbourParticles. | |
| template<typename ParticleContainer > | |
| void | flagBoundaryParticles (const ParticleContainer &localParticles, const double nparts) |
| Flag boundary particles. | |
| template<typename ParticleContainer > | |
| void | flagBoundaryParticles (const ParticleContainer &localParticles, const double nparts, const tarch::la::Vector< Dimensions, double > &domainSize, const tarch::la::Vector< Dimensions, double > &domainOffset) |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::VertexMarker &marker, auto &assignedParticles, int numberOfCoalescedAssignedParticles, ::swift2::kernels::kernelrealisation::GenericRealisation realisation) |
| Run over all particles and update them independent of each other. | |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::VertexMarker &marker, auto &assignedParticles, int numberOfCoalescedAssignedParticles, ::swift2::kernels::kernelrealisation::GenericOffloadRealisation) |
| Exactly the same version as the generic variant, but we use the offload attribute. | |
| template<auto PairOperator, auto LocalPredicate, auto PairPredicate> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::GenericRealisation realisation) |
| Run over all local particle-active particle combinations. | |
| template<auto PairOperator, auto LocalPredicate, auto PairPredicate> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::GenericOffloadRealisation) |
| Exactly the same version as the generic variant, but with an additional offload annotation. | |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::VertexMarker &marker, auto &assignedParticles, int numberOfAssignedParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryRealisation realisation) |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::CellMarker &marker, auto &localParticles, const std::vector< int > &numberOfLocalParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryRealisation realisation) |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::VertexMarker &marker, auto &assignedParticles, int numberOfAssignedParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryOffloadRealisation realisation) |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::CellMarker &marker, auto &localParticles, const std::vector< int > &numberOfLocalParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryOffloadRealisation realisation) |
| template<auto PairOperator, auto LocalPredicate, auto PairPredicate> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryActiveLocalRealisation realisation) |
| Alternative implementation of CoalescedMemoryActiveLocalRealisation. | |
| template<auto PairOperator, auto LocalPredicate, auto PairPredicate> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryActiveLocalOffloadRealisation realisation) |
| template<auto PairOperator, auto LocalPredicate, auto PairPredicate> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueActiveLocalRealisation realisation) |
| template<auto PairOperator, auto LocalPredicate, auto PairPredicate> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueLocalActiveRealisation realisation) |
| template<auto ParticlePairOp, auto LocalPredicateOp, auto ParticlePairPredicateOp> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryLocalActiveRealisation realisation) |
| template<auto ParticlePairOp, auto LocalPredicateOp, auto ParticlePairPredicateOp> | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::CoalescedMemoryLocalActiveOffloadRealisation realisation) |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::VertexMarker &marker, auto &assignedParticles, int numberOfCoalescedAssignedParticles, ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueRealisation) |
| We split up the loop into two loops: The first one runs over the predicates and collects all the results in one large bit field. | |
| template<auto ParticleOp, auto PredicateOp> | |
| void | forAllParticles (const peano4::datamanagement::CellMarker &marker, auto &localParticles, const std::vector< int > &numberOfCoalescedLocalParticles, ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueRealisation) |
| template<typename LocalParticleContainer , typename ActiveParticleContainer > | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueActiveLocalRealisation realisation) |
| Move all the predicate evaluations into dedicated prologue. | |
| template<typename LocalParticleContainer , typename ActiveParticleContainer > | |
| void | forAllParticlePairs (const swift2::CellMetaData &cellMetaData, auto &localParticles, auto &activeParticles, ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueLocalActiveRealisation realisation) |
| template<typename Particle > | |
| bool | alwaysUpdateInVertexKernel (const peano4::datamanagement::VertexMarker &marker, const Particle &localParticle) |
| Degenerated predicate which always allows for an update. | |
| template<typename Particle > | |
| bool | alwaysUpdateInCellKernel (const peano4::datamanagement::CellMarker &marker, const bool &localParticleIsContainedInCell, const Particle &localParticle) |
| Degenerated update in cell predicate. | |
| template<typename ParticleA , typename ParticleB = ParticleA> | |
| bool | alwaysUpdateParticlePairs (const peano4::datamanagement::CellMarker &marker, const ParticleA &localParticle, const ParticleB &activeParticle) |
| Degenerated update in cell predicate. | |
| template<typename Particle > | |
| bool | particleIsLocal (const peano4::datamanagement::VertexMarker &marker, const Particle &localParticle) |
| Is a particle local. | |
| template<typename Particle > | |
| bool | localParticleCanBeUpdatedAndMovedInVertexKernel (const peano4::datamanagement::VertexMarker &marker, const Particle &localParticle) |
| Can we move (drift) this particle? | |
| template<typename ParticleA , typename ParticleB = ParticleA> | |
| bool | localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle (const peano4::datamanagement::CellMarker &marker, const ParticleA &localParticle, const ParticleB &activeParticle) |
| Can we do work on this particle during a cell kernel sweep stage? | |
| template<typename ParticleA , typename ParticleB = ParticleA> | |
| bool | updateFromAnyOtherParticle (const peano4::datamanagement::CellMarker &marker, const ParticleA &localParticle, const ParticleB &activeParticle) |
| template<typename ParticleA , typename ParticleB = ParticleA> | |
| bool | localParticleCanBeUpdatedInCellKernelFromAnyOtherParticleWithinIterationRange (const peano4::datamanagement::CellMarker &marker, const ParticleA &localParticle, const ParticleB &activeParticle) |
| template<typename Particle > | |
| bool | localParticleCanBeUpdatedInCellKernel (const peano4::datamanagement::CellMarker &marker, const bool &localParticleIsContainedInCell, const Particle &localParticle) |
| template<typename Particle > | |
| bool | localParticleCanBeUpdatedInVertexKernel (const peano4::datamanagement::VertexMarker &marker, const Particle &localParticle) |
| Can we do work on this particle during a vertex kernel sweep stage? | |
| using swift2::kernels::PCParticle = typename std::remove_pointer<typename ParticleContainer::value_type>::type |
Definition at line 17 of file ParticleSetIterators.h.
| using swift2::kernels::UpdateParticleAssignedToCellPredicate |
Definition at line 17 of file ParticleUpdatePredicates.h.
| using swift2::kernels::UpdateParticleAssignedToVertexPredicate |
Definition at line 24 of file ParticleUpdatePredicates.h.
| using swift2::kernels::UpdateParticlePairWithinCellPredicate |
Definition at line 10 of file ParticleUpdatePredicates.h.
| void swift2::kernels::adoptInteractionRadiusAndTriggerRerun | ( | const std::list< Particle * > & | localParticles, |
| const std::list< Particle * > & | activeParticles, | ||
| int | targetNumberOfNeighbourParticles, | ||
| double | maxGrowthPerSweep = 2.0, | ||
| double | shrinkingFactor = 0.8 ) |
This routine runs over all the local particles and tries to ensure that the number of particles equals roughly targetNumberOfNeighbourParticles.
The algorithm is fairly simple:
The reduction starts from the assumption that we should be careful with reducing the search radii. So we only slightly decrease the search radius. If we could have reduced it more aggressively, we accept that and hope that subsequent time steps or sweeps will eventually bring the search radius down. But we do not enforce it here, which might mean that we work with too big interaction sets.
The increase is different: If we
If an interaction radius has to be increased, the code sets the flag setRerunPreviousGridSweep() on the underlying particle species.
In prin
| bool swift2::kernels::alwaysUpdateInCellKernel | ( | const peano4::datamanagement::CellMarker & | marker, |
| const bool & | localParticleIsContainedInCell, | ||
| const Particle & | localParticle ) |
Degenerated update in cell predicate.
See comment on alwaysUpdateInVertexKernel(), which also holds for this predicate.
Definition at line 55 of file ParticleUpdatePredicates.h.
| bool swift2::kernels::alwaysUpdateInVertexKernel | ( | const peano4::datamanagement::VertexMarker & | marker, |
| const Particle & | localParticle ) |
Degenerated predicate which always allows for an update.
This predicate is a prototype of what predicated look like. It rarely is used directly as it is. Typically, you have a kernel called ABC and then you write ABCUpdateParticlePredicate() with the same signature as alwaysUpdateInVertexKernel() aka UpdateParticleAssignedToVertexPredicate().
Definition at line 40 of file ParticleUpdatePredicates.h.
| bool swift2::kernels::alwaysUpdateParticlePairs | ( | const peano4::datamanagement::CellMarker & | marker, |
| const ParticleA & | localParticle, | ||
| const ParticleB & | activeParticle ) |
Degenerated update in cell predicate.
See comment on alwaysUpdateInVertexKernel(), which also holds for this predicate.
Definition at line 71 of file ParticleUpdatePredicates.h.
| void swift2::kernels::flagBoundaryParticles | ( | const ParticleContainer & | localParticles, |
| const double | nparts ) |
Flag boundary particles.
These particles we will not be updated by any algorithmic step.
| ParticleContainer | Typicaly either std::list<Particle *> or std::unordered_set<Particle *> |
| void swift2::kernels::flagBoundaryParticles | ( | const ParticleContainer & | localParticles, |
| const double | nparts, | ||
| const tarch::la::Vector< Dimensions, double > & | domainSize, | ||
| const tarch::la::Vector< Dimensions, double > & | domainOffset ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryActiveLocalOffloadRealisation | realisation ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryActiveLocalRealisation | realisation ) |
Alternative implementation of CoalescedMemoryActiveLocalRealisation.
Simple version of pair-wise comparison exploiting coalesced memory Please consult the generic cousin (with a generic template argument) for an explanation of the semantics. @image html coalesced-memory.png Before you continue to read, please read also the documentation of forAllParticles() that accepts
swift2::kernels::kernelrealisation::CoalescedMemoryRealisation as argument. This routine mirrors all ideas described there. The only "difference" is that both the local and active particle sets are clustered, i.e. we get sequences of pointers, but we know that these sequences are split into chunks with consecutive memory regions.
We know in this case that activeParticles is clustered into chunks described by numberOfCoalescedActiveParticlesPerVertex. The same reasoning holds for localParticles. Per local particles it has to loop over all active particles. We employ exactly the techniques described for forAllParticles(), but we run over the active/local particle set chunk-wisely. Per chunk, we exploit the fact that particles are stored continuously.
In principle, the counters over active and local particles run independent of each other, while the active set always contains the local set. If we assume that the update function can be vectorised, we see that the active set has to be the outer loop: We fix the particle that works on a chunk of local particles. If we made the active set the inner loop, i.e. evaluated all the impacts of a set of active particles onto one local particle, we would have a write conflict if vectorised.
We have to check if a particle is to be updated. If so, we also have to check if the symmetric evaluation has to be performed: By default, we do not exploit any force symmetry on one level, as it makes bookkeeping more complicated. However, coarser active particles act on finer particles and immediately receive their update back, i.e. between scales we exploit the symmetry.
The generic implementation does these checks within one loop, i.e. once we have found an active particle excerting a force onto a local one, we immediately check if they reside on different levels and, if so, do the symmetric calculation. We may assume that such multiscale relations are rare. Furthermore, they have the potential to stop vectorisation as we have concurrent writes to an active particle. Therefore, we could split the check into two separate loops, where the second will rarely ever trigger any calculation.
While a valid rationale, we found the split version to perform significantly slower than a fused one.
The outer loop is kind of trivial:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int firstActiveParticleOfCurrentChunk = 0; for (auto& activeParticleChunk: numberOfActiveParticlesPerVertex) { typename ActiveParticleContainer::value_type pFirstActiveParticleOfCurrentChunk = *activeParticles.begin() + firstActiveParticleOfCurrentChunk; firstActiveParticleOfCurrentChunk += activeParticleChunk; for (int iActiveParticle=0; iActiveParticle<activeParticleChunk; iActiveParticle++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iterates over the chunks within the active sets. Per chunk, it creates a pointer to the first active particles within this chunk. From hereon, we know that the particles are stored continuously (in this chunk) and hence can use
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PCParticle<ActiveParticleContainer>& activeParticle = *(pFirstActiveParticleOfCurrentChunk+iActiveParticle); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
later on the reconstruct the correct active particle.
In the variant with CoalescedMemoryActiveLocalRealisation, the outer loop runs over the active particles, while the inner loop runs over the local ones. Here, we invert these two loops.
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryLocalActiveOffloadRealisation | realisation ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryLocalActiveRealisation | realisation ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueActiveLocalRealisation | realisation ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueActiveLocalRealisation | realisation ) |
Move all the predicate evaluations into dedicated prologue.
Alternative implementation to the one with swift2::kernels::kernelrealisation::CoalescedMemoryRealisation. We run over the particles and first
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueLocalActiveRealisation | realisation ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueLocalActiveRealisation | realisation ) |
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::GenericOffloadRealisation | ) |
Exactly the same version as the generic variant, but with an additional offload annotation.
| void swift2::kernels::forAllParticlePairs | ( | const swift2::CellMetaData & | cellMetaData, |
| auto & | localParticles, | ||
| auto & | activeParticles, | ||
| ::swift2::kernels::kernelrealisation::GenericRealisation | realisation ) |
Run over all local particle-active particle combinations.
The generic implementation realises a nested loop: We call interaction per pair of local and active particles. The interaction functor may modify the local particle. It is the responsibility of the update predicate to ensure that no particle is updated twice: For example, most users will look whether a particle is contained within the local cell, so we do not update it when actually the neighbour should do that job, but if it is sitting right at the face in-between two cells, then we also have to check a boolean that tells us where we are regarding updates. The predicate also should check if there's a self-interaction and mask it out if appropriate.
In Swift's terminology, we rely on a non-symmetric XXX calculation where XXX is the compute kernel (such as density): Our implementations loops over all local particles (outer loop) and, per local particle then over all active particles (inner loop). Inside this second loop, we compute a force acting from the active particle onto the local particle, but if and only if the PairPredicate holds. But this knowledge is not used to update the active particle in an way.
This might seem to be a missed tuning opportunity: If a local and an active particle reside on the same level, we know that the symmetric force component will be computed later on, i.e. either in a subsequent step of the present loop or later on when the other cell hosting the other particle invokes the update kernel.
Let L be the local one and A the active one, we have
\( f(L,A) = -f(A,L). \)
Following the description above, this antisymmetry is not exploited in the kernel. We know that there will be another loop iteration or cell interaction kernel call which takes care of the negative complementary force.
It is subject (and possible) to inject the antisymmetry optimisation later in the user kernel, but that's beyond scope here.
If A resides on a coarser level than L, then we have to exploit the antisymmetry. We need to add the force explicitly as discussed in Mesh traversal.
This routine follows Peano's generic multiscale discussion, where we point out that we have correctly take particles into account which reside on coarser levels. This is necessary if some particles have larger cut-off radii than the others or if we work with adaptive meshes.
The routine accepts a container over particle pointers. The functor f however accepts references. It is the responsibility of this routine to map pointers onto references. We use
This would be the generic predicates as most kernels require it:
However, you can use a more bespoke version as follows:
| LocalParticleContainer | A subtype of std::list<Particle *>. You have no guarantee of the pointers in the list, i.e. that they are in any way consecutive. |
| ActiveParticleContainer | A subtype of std::list<Particle *>. You have no guarantee of the pointers in the list, i.e. that they are in any way consecutive. |
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::CellMarker & | marker, |
| auto & | localParticles, | ||
| const std::vector< int > & | numberOfCoalescedLocalParticles, | ||
| ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueRealisation | ) |
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::CellMarker & | marker, |
| auto & | localParticles, | ||
| const std::vector< int > & | numberOfLocalParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryOffloadRealisation | realisation ) |
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::CellMarker & | marker, |
| auto & | localParticles, | ||
| const std::vector< int > & | numberOfLocalParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryRealisation | realisation ) |
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::VertexMarker & | marker, |
| auto & | assignedParticles, | ||
| int | numberOfAssignedParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryOffloadRealisation | realisation ) |
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::VertexMarker & | marker, |
| auto & | assignedParticles, | ||
| int | numberOfAssignedParticles, | ||
| ::swift2::kernels::kernelrealisation::CoalescedMemoryRealisation | realisation ) |
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::VertexMarker & | marker, |
| auto & | assignedParticles, | ||
| int | numberOfCoalescedAssignedParticles, | ||
| ::swift2::kernels::kernelrealisation::EvaluatePredicateInPrologueRealisation | ) |
We split up the loop into two loops: The first one runs over the predicates and collects all the results in one large bit field.
The idea/hope is that this part vectorises. After that, we run over the particle set again, but only evaluate those guys where the bitfield is actually set.
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::VertexMarker & | marker, |
| auto & | assignedParticles, | ||
| int | numberOfCoalescedAssignedParticles, | ||
| ::swift2::kernels::kernelrealisation::GenericOffloadRealisation | ) |
Exactly the same version as the generic variant, but we use the offload attribute.
| void swift2::kernels::forAllParticles | ( | const peano4::datamanagement::VertexMarker & | marker, |
| auto & | assignedParticles, | ||
| int | numberOfCoalescedAssignedParticles, | ||
| ::swift2::kernels::kernelrealisation::GenericRealisation | realisation ) |
Run over all particles and update them independent of each other.
The routine accepts a container over particle pointers, but the functor f actually accepts references. It is the responsibility of this routine to map pointers onto references.
The predicate can be used to mask out certain updates.
We distinguish two use cases for the particle self-interactions:
The most popular predicates therefore are:
and
In order to ensure the self-interaction kernels execute consistently during the mesh traversals for these type of operations, the user should bear in mind the difference between these two cases:
This routine does not vectorise over the particles. If any vectorisation is used, you'll see the vector instructions arise from the actual compute kernel.
| ParticleContainer | A subtype of std::list<Particle *> |
| bool swift2::kernels::forceKernelDistanceCheck | ( | ParticleA &__restrict__ | localParticle, |
| const ParticleB &__restrict__ | activeParticle ) |
| bool swift2::kernels::localParticleCanBeUpdatedAndMovedInVertexKernel | ( | const peano4::datamanagement::VertexMarker & | marker, |
| const Particle & | localParticle ) |
Can we move (drift) this particle?
This is a more restrictive version compared to localParticleCanBeUpdatedInVertexKernel(), as it allows the underlying kernel to move a particle, too. Hence, the particle has to be local, and we have to check if it has not been moved yet. It is important that we distinguish this more restrictive version from its counterpart, as not each and every mesh traversal might reset the moved marker.
| localParticle | Particle to check for |
| marker | Identifier for this vertex |
Definition at line 113 of file ParticleUpdatePredicates.h.
References particleIsLocal().

| bool swift2::kernels::localParticleCanBeUpdatedInCellKernel | ( | const peano4::datamanagement::CellMarker & | marker, |
| const bool & | localParticleIsContainedInCell, | ||
| const Particle & | localParticle ) |
Definition at line 232 of file ParticleUpdatePredicates.h.
References assertionEquals2, and tarch::la::NUMERICAL_ZERO_DIFFERENCE.
| bool swift2::kernels::localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle | ( | const peano4::datamanagement::CellMarker & | marker, |
| const ParticleA & | localParticle, | ||
| const ParticleB & | activeParticle ) |
Can we do work on this particle during a cell kernel sweep stage?
A particle is to be updated if and only if
The second point is important. A particle might be located right at the face in-between two cells. In this case, it is not clear to which cell is actually belong to. So we are fine if either cell updates it, but it should be only one cel at a time.
I originally thought that this predicate should resemble
However, that's a poor idea, as it does not work along AMR boundaries for particles which reside in a refined cell yet would be dropped into a hanging vertex (which we don't). The file peano4.toolbox.particles.api.AbstractParticleGridAssociation provides some examples on this.
This routine looks if a particle is contained in a cell. This is slow. Usually, you would do this check once in an outer loop via the is local flag, and then you can skip it here.
Usually, it is a poor idea to use this routine. It is brutally slow to check a local particle whether it is really contained within a cell per particle-particle interaction. I rather prefer to use
::swift2::kernels::localParticleCanBeUpdatedInCellKernel<globaldata::HydroPart>,
once in an outer loop and then to apply
updateFromAnyOtherParticle
as predicate (or something more restrictive such as densityKernelEvaluatePairInteractionPredicate but never this one).
| localParticle | particle to check for |
| marker | the cell's CellMarker |
Definition at line 188 of file ParticleUpdatePredicates.h.
References tarch::la::NUMERICAL_ZERO_DIFFERENCE, and toolbox::particles::internal::relativeGrabOwnershipSpatialSortingTolerance().

| bool swift2::kernels::localParticleCanBeUpdatedInCellKernelFromAnyOtherParticleWithinIterationRange | ( | const peano4::datamanagement::CellMarker & | marker, |
| const ParticleA & | localParticle, | ||
| const ParticleB & | activeParticle ) |
Definition at line 213 of file ParticleUpdatePredicates.h.
References tarch::la::NUMERICAL_ZERO_DIFFERENCE, and toolbox::particles::internal::relativeGrabOwnershipSpatialSortingTolerance().

| bool swift2::kernels::localParticleCanBeUpdatedInVertexKernel | ( | const peano4::datamanagement::VertexMarker & | marker, |
| const Particle & | localParticle ) |
Can we do work on this particle during a vertex kernel sweep stage?
This predicate filters out all halo (virtual) particle. It implicitly assumes that the particle-vertex association is correct. Therefore, we really only have to mask out virtual particles. The predicate breaks down if the association is not correct, which means it does not work if particles move.
| localParticle | Particle to check for |
| marker | Identifier for this vertex |
Definition at line 270 of file ParticleUpdatePredicates.h.
References particleIsLocal().
Referenced by swift2::kernels::legacy::firstInitParticleParticleUpdatePredicate().


| bool swift2::kernels::particleIsLocal | ( | const peano4::datamanagement::VertexMarker & | marker, |
| const Particle & | localParticle ) |
Is a particle local.
is this localParticle a local particle (in the ParallelState sense)?
Helper routine which is used by a lot of predicates in their decision making process. Is usually not used directly and hence could be moved into an "internal" namespace as well.
Definition at line 91 of file ParticleUpdatePredicates.h.
Referenced by localParticleCanBeUpdatedAndMovedInVertexKernel(), and localParticleCanBeUpdatedInVertexKernel().

| bool swift2::kernels::updateFromAnyOtherParticle | ( | const peano4::datamanagement::CellMarker & | marker, |
| const ParticleA & | localParticle, | ||
| const ParticleB & | activeParticle ) |
Definition at line 206 of file ParticleUpdatePredicates.h.