28#ifndef PARTICLE_CONTACT_DETECTION_FUNCTIONS_H
29#define PARTICLE_CONTACT_DETECTION_FUNCTIONS_H
37template <
typename CONTACTTYPE>
39 const std::function<
bool(
const CONTACTTYPE&)> condition)
41 auto contactIt = std::find_if(contacts.begin(), contacts.end(),
42 [&condition](
const auto& contact) ->
bool {
43 return condition(contact);
48std::array<std::size_t, 2>
51 return std::array<std::size_t, 2>(
55template <
typename T,
typename PARTICLETYPE,
typename F>
60 F getSetupPeriodicity,
64 using namespace descriptors;
73 if constexpr (
isPeriodic(getSetupPeriodicity())) {
76 auto sIndicator1 = particle1.template getField<SURFACE, SINDICATOR>();
77 const T circumRadius1 = sIndicator1->getCircumRadius() -
78 sIndicator1->getEpsilon() +
79 util::max(sIndicator1->getEpsilon(), 0.5 * deltaX);
80 auto sIndicator2 = particle2.template getField<SURFACE, SINDICATOR>();
81 const T circumRadius2 = sIndicator2->getCircumRadius() -
82 sIndicator2->getEpsilon() +
83 util::max(sIndicator2->getEpsilon(), 0.5 * deltaX);
87 for (
unsigned i = 0; i < PARTICLETYPE::d; ++i) {
88 T
const particleMin1 = pos1[i] - circumRadius1;
89 T
const particleMax1 = pos1[i] + circumRadius1;
90 T
const particleMin2 = pos2[i] - circumRadius2;
91 T
const particleMax2 = pos2[i] + circumRadius2;
94 if (particleMin1 < cellMin[i] &&
isPeriodic[i]) {
95 if (pos2[i] > middle[i]) {
97 pos2[i], cellMax[i], cellMin[i]);
100 else if (particleMax1 > cellMax[i] &&
isPeriodic[i]) {
101 if (pos2[i] < middle[i]) {
103 pos2[i], cellMax[i], cellMin[i]);
106 else if (particleMin2 < cellMin[i] &&
isPeriodic[i]) {
107 if (pos1[i] > middle[i]) {
109 pos2[i], cellMax[i], cellMin[i]);
112 else if (particleMax2 > cellMax[i] &&
isPeriodic[i]) {
113 if (pos1[i] < middle[i]) {
115 pos2[i], cellMax[i], cellMin[i]);
122template <
typename T,
typename PARTICLETYPE,
typename F>
129 using namespace descriptors;
134 if constexpr (
isPeriodic(getSetupPeriodicity())) {
137 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
138 const T circumRadius = sIndicator->getCircumRadius() -
139 sIndicator->getEpsilon() +
140 util::max(sIndicator->getEpsilon(), 0.5 * deltaX);
142 for (
unsigned i = 0; i < PARTICLETYPE::d; ++i) {
143 T
const particleMax = pos[i] + circumRadius;
146 if (particleMax > cellMax[i] &&
isPeriodic[i]) {
148 pos[i], cellMax[i], cellMin[i]);
157 return unifiedPosition;
160template <
typename T,
typename PARTICLETYPE,
typename F>
167 F getSetupPeriodicity, T deltaX)
169 using namespace descriptors;
171 if constexpr (!(
isPeriodic(getSetupPeriodicity()))) {
175 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
176 const T circumRadius = sIndicator->getCircumRadius() -
177 sIndicator->getEpsilon() +
178 util::max(sIndicator->getEpsilon(), 0.5 * deltaX);
181 for (
unsigned i = 0; i < PARTICLETYPE::d; ++i) {
182 T
const particleMin = particlePos[i] - circumRadius;
183 T
const particleMax = particlePos[i] + circumRadius;
184 if (particleMin > contactPos[i] && getSetupPeriodicity()[i]) {
186 contactPos[i], cellMax[i], cellMin[i]);
188 else if (particleMax < contactPos[i] && getSetupPeriodicity()[i]) {
190 contactPos[i], cellMax[i], cellMin[i]);
197template <
typename PARTICLECONTACTTYPE,
bool IS_INPUT_SORTED = false>
199 const std::array<size_t, 2>& ids)
201 if constexpr (!IS_INPUT_SORTED) {
202 return (particleContact.getIDs()[0] == ids[0] &&
203 particleContact.getIDs()[1] == ids[1]) ||
204 (particleContact.getIDs()[0] == ids[1] &&
205 particleContact.getIDs()[1] == ids[0]);
208 return particleContact.getIDs()[0] == ids[0] &&
209 particleContact.getIDs()[1] == ids[1];
211 __builtin_unreachable();
214template <
typename T,
typename PARTICLETYPE,
bool CONVEX,
typename F>
222 F getSetupPeriodicity, T deltaX)
224 if (!contact.isParticlePositionUpdated()) {
225 std::array<PhysR<T, PARTICLETYPE::d>, 2> positions;
226 unifyPositions(particle1, particle2, cellMin, cellMax, getSetupPeriodicity,
228 contact.setParticlePositions(positions);
232 particle1, contact.getParticlePosition(contact.getIDs()[0]),
233 contactPos, cellMin, cellMax, getSetupPeriodicity, deltaX));
236template <
typename T,
typename PARTICLETYPE,
bool CONVEX,
typename F>
243 F getSetupPeriodicity, T deltaX)
245 if (!contact.isParticlePositionUpdated()) {
246 contact.setParticlePosition(
247 unifyPosition(particle, cellMin, cellMax, getSetupPeriodicity, deltaX));
249 contact.updateMinMax(
251 cellMin, cellMax, getSetupPeriodicity, deltaX));
254template <
typename T,
typename PARTICLETYPE,
typename PARTICLECONTACTTYPE,
255 typename WALLCONTACTTYPE,
typename F>
265 const std::function<bool(
const PARTICLECONTACTTYPE&)> condition =
266 [&ids](
const PARTICLECONTACTTYPE& contact) {
274 if (contactIt->isNew()) {
275 if (particleContactConsistsOfIDs<PARTICLECONTACTTYPE, true>(
277 updateContact(*contactIt, particle1, particle2, pos, cellMin, cellMax,
278 getSetupPeriodicity, deltaX);
281 updateContact(*contactIt, particle2, particle1, pos, cellMin, cellMax,
282 getSetupPeriodicity, deltaX);
288 if (particleContactConsistsOfIDs<PARTICLECONTACTTYPE, true>(
291 particle2, pos, cellMin, cellMax, getSetupPeriodicity,
296 particle1, pos, cellMin, cellMax, getSetupPeriodicity,
302template <
typename T,
typename PARTICLETYPE,
typename PARTICLECONTACTTYPE,
303 typename WALLCONTACTTYPE,
typename F>
312 const std::function<bool(
const WALLCONTACTTYPE&)> condition =
313 [&particleID, &wallID](
const WALLCONTACTTYPE& contact) {
314 return particleID == contact.getParticleID() &&
315 wallID == contact.getWallID();
320 if (contactIt != std::end(contactContainer.
wallContacts)) {
321 if (contactIt->isNew()) {
323 getSetupPeriodicity, deltaX);
328 WALLCONTACTTYPE(particleID, wallID));
330 cellMin, cellMax, getSetupPeriodicity, deltaX);
Vector< T, PARTICLETYPE::d > getPosition(Particle< T, PARTICLETYPE > particle)
T movePositionToEnd(const T position, const T max, const T min)
T movePositionToStart(const T position, const T max, const T min)
void unifyPositions(Particle< T, PARTICLETYPE > &particle1, Particle< T, PARTICLETYPE > &particle2, const PhysR< T, PARTICLETYPE::d > &cellMin, const PhysR< T, PARTICLETYPE::d > &cellMax, F getSetupPeriodicity, std::array< PhysR< T, PARTICLETYPE::d >, 2 > &positions, T deltaX)
void updateContact(ParticleContactArbitraryFromOverlapVolume< T, PARTICLETYPE::d, CONVEX > &contact, Particle< T, PARTICLETYPE > &particle1, Particle< T, PARTICLETYPE > &particle2, const PhysR< T, PARTICLETYPE::d > &contactPos, const PhysR< T, PARTICLETYPE::d > &cellMin, const PhysR< T, PARTICLETYPE::d > &cellMax, F getSetupPeriodicity, T deltaX)
std::array< std::size_t, 2 > sortParticleIDs(const std::array< std::size_t, 2 > &ids)
bool particleContactConsistsOfIDs(PARTICLECONTACTTYPE &particleContact, const std::array< size_t, 2 > &ids)
PhysR< T, PARTICLETYPE::d > evalContactPosition(Particle< T, PARTICLETYPE > &particle, const PhysR< T, PARTICLETYPE::d > &particlePos, const PhysR< T, PARTICLETYPE::d > &contactPos, const PhysR< T, PARTICLETYPE::d > &cellMin, const PhysR< T, PARTICLETYPE::d > &cellMax, F getSetupPeriodicity, T deltaX)
auto getContactIterator(std::vector< CONTACTTYPE > &contacts, const std::function< bool(const CONTACTTYPE &)> condition)
void updateContacts(ContactContainer< T, PARTICLECONTACTTYPE, WALLCONTACTTYPE > &contactContainer, std::array< std::size_t, 2 > &&ids, const PhysR< T, PARTICLETYPE::d > &pos, Particle< T, PARTICLETYPE > &particle1, Particle< T, PARTICLETYPE > &particle2, const PhysR< T, PARTICLETYPE::d > &cellMin, const PhysR< T, PARTICLETYPE::d > &cellMax, F getSetupPeriodicity, T deltaX)
PhysR< T, PARTICLETYPE::d > unifyPosition(Particle< T, PARTICLETYPE > &particle, const PhysR< T, PARTICLETYPE::d > &cellMin, const PhysR< T, PARTICLETYPE::d > &cellMax, F getSetupPeriodicity, T deltaX)
constexpr bool isPeriodic(const Vector< bool, D > &periodic)
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Top level namespace for all of OpenLB.
std::vector< PARTICLECONTACTTYPE > particleContacts
resizeable vector containing all particle-particle contacts
std::vector< WALLCONTACTTYPE > wallContacts
resizeable vector containg all particle-wall contacts
An object holding data for a contact which is described analog to Nassauer and Kuna (2013)