OpenLB 1.8.1
Loading...
Searching...
No Matches
particleContact.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Jan E. Marquardt, Mathias J. Krause
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef PARTICLE_CONTACT_HH
25#define PARTICLE_CONTACT_HH
26
27#include "particleContact.h"
29
30namespace olb {
31namespace particles {
32namespace contact {
33
34template <typename T, unsigned D, bool CONVEX>
35ParticleContactArbitraryFromOverlapVolume<
36 T, D, CONVEX>::ParticleContactArbitraryFromOverlapVolume()
38 std::array<std::size_t, 2>())
39{}
40
41template <typename T, unsigned D, bool CONVEX>
44 const std::array<std::size_t, 2>& particleIDs)
45 : ids(sortParticleIDs(particleIDs))
46{
48}
49
50template <typename T, unsigned D, bool CONVEX>
54{
55 min = pc.getMin();
56 max = pc.getMax();
57 ids = pc.getIDs();
58 particlePositions = pc.getParticlePositions();
59 particlePositionUpdated[0] = pc.isParticlePositionUpdated();
60 dampingFactor[0] = pc.getDampingFactor();
61 newContact[0] = pc.isNew();
62 responsibleRank[0] = pc.getResponsibleRank();
63}
64
65template <typename T, unsigned D, bool CONVEX>
69{
70 min = std::move(pc.min);
71 max = std::move(pc.max);
72 ids = std::move(pc.ids);
73 particlePositions = std::move(pc.particlePositions);
74 particlePositionUpdated = std::move(pc.particlePositionUpdated);
75 dampingFactor = std::move(pc.dampingFactor);
76 newContact = std::move(pc.newContact);
77 responsibleRank = std::move(pc.responsibleRank);
78}
79
80template <typename T, unsigned D, bool CONVEX>
81constexpr const std::array<std::size_t, 2>&
86
87template <typename T, unsigned D, bool CONVEX>
88constexpr const std::array<PhysR<T, D>, 2>&
94
95template <typename T, unsigned D, bool CONVEX>
96constexpr void
98 const std::array<PhysR<T, D>, 2>& positions)
99{
100 particlePositions = positions;
101 particlePositionUpdated[0] = true;
102}
103
104template <typename T, unsigned D, bool CONVEX>
105constexpr const PhysR<T, D>&
107 const std::size_t& id) const
108{
109 if (id == ids[0]) {
110 return particlePositions[0];
111 }
112 return particlePositions[1];
113}
114
115template <typename T, unsigned D, bool CONVEX>
116constexpr void
118 const PhysR<T, D>& position, const std::size_t& id)
119{
120 particlePositions[id] = position;
121 particlePositionUpdated[0] = true;
122}
123
124template <typename T, unsigned D, bool CONVEX>
125constexpr void
127 const int& rank)
128{
129 responsibleRank[0] = rank;
130}
131
132template <typename T, unsigned D, bool CONVEX>
133constexpr const int&
135 const
136{
137 return responsibleRank[0];
138}
139
140template <typename T, unsigned D, bool CONVEX>
141constexpr const PhysR<T, D>&
146
147template <typename T, unsigned D, bool CONVEX>
148constexpr const PhysR<T, D>&
153
154template <typename T, unsigned D, bool CONVEX>
155constexpr const T
157 const
158{
159 return dampingFactor[0];
160}
161
162template <typename T, unsigned D, bool CONVEX>
163constexpr void
165 const T newDampingFactor)
166{
167 dampingFactor[0] = newDampingFactor;
168}
169
170template <typename T, unsigned D, bool CONVEX>
173 const T coefficientOfRestitution,
174 const T initialRelativeVelocityMagnitude)
175{
177 coefficientOfRestitution, initialRelativeVelocityMagnitude));
178}
179
180template <typename T, unsigned D, bool CONVEX>
181constexpr void
183{
184 for (unsigned iD = 0; iD < D; ++iD) {
185 min[iD] = std::numeric_limits<olb::BaseType<T>>::max();
186 max[iD] = -std::numeric_limits<olb::BaseType<T>>::max();
187 }
188 particlePositionUpdated[0] = false;
189}
190
191template <typename T, unsigned D, bool CONVEX>
192constexpr void
194 const PhysR<T, D>& positionInsideTheContact)
195{
196 particles::contact::updateMinMax(this->min, this->max,
197 positionInsideTheContact);
198}
199
200template <typename T, unsigned D, bool CONVEX>
201constexpr void
203 const Vector<T, D>& increaseBy)
204{
205 this->max += increaseBy;
206 this->min -= increaseBy;
207}
208
209template <typename T, unsigned D, bool CONVEX>
210constexpr void
213{
216 ids)) {
217 if(newContact[0] == pc.isNew()) {
218 newContact[0] = newContact[0] && pc.isNew();
219
220 // Determine bounding box of combined overlap area
221 for (unsigned iD = 0; iD < D; ++iD) {
222 min[iD] = util::min(min[iD], pc.getMin()[iD]);
223 max[iD] = util::max(max[iD], pc.getMax()[iD]);
224 }
225 // The damping factors should be either the same or one is -1 and the other has the correct value which is > 0
226 dampingFactor[0] = util::max(dampingFactor[0], pc.getDampingFactor());
227 responsibleRank[0] = util::min(responsibleRank[0], pc.getResponsibleRank());
228 particlePositionUpdated[0] =
229 particlePositionUpdated[0] || pc.isParticlePositionUpdated();
230 if (!particlePositionUpdated[0] && pc.isParticlePositionUpdated()) {
231 particlePositions = pc.getParticlePositions();
232 }
233 }
234 else {
235 if(!pc.isNew()) {
236 min = pc.getMin();
237 max = pc.getMax();
238 dampingFactor[0] = pc.getDampingFactor();
239 particlePositionUpdated[0] = pc.isParticlePositionUpdated();
240 particlePositions = pc.getParticlePositions();
241 }
242 responsibleRank[0] = util::min(responsibleRank[0], pc.getResponsibleRank());
243 newContact[0] = newContact[0] && pc.isNew();
244 }
245
246 // Ignore second contact by resetting it
247 pc.resetMinMax();
248 }
249}
250
251template <typename T, unsigned D, bool CONVEX>
252constexpr bool
254{
255 for (unsigned iD = 0; iD < D; ++iD) {
256 if (min[iD] > max[iD]) {
257 return true;
258 }
259 }
260 return false;
261}
262
263template <typename T, unsigned D, bool CONVEX>
264constexpr bool
266{
267 return newContact[0];
268}
269
270template <typename T, unsigned D, bool CONVEX>
272 const bool newContact)
273{
274 this->newContact[0] = newContact;
275}
276
277template <typename T, unsigned D, bool CONVEX>
279 T, D, CONVEX>::isParticlePositionUpdated() const
280{
281 return particlePositionUpdated[0];
282}
283
284template <typename T, unsigned D, bool CONVEX>
286 T, D, CONVEX>::setParticlePositionUpdated(bool updated)
287{
288 particlePositionUpdated[0] = updated;
289}
290
291template <typename T, unsigned D, bool CONVEX>
295{
296 min = pc.getMin();
297 max = pc.getMax();
298 ids = pc.getIDs();
299 particlePositions = pc.getParticlePositions();
300 particlePositionUpdated[0] = pc.isParticlePositionUpdated();
301 dampingFactor[0] = pc.getDampingFactor();
302 newContact[0] = pc.isNew();
303 responsibleRank[0] = pc.getResponsibleRank();
304
305 return *this;
306}
307
308template <typename T, unsigned D, bool CONVEX>
312{
313 min = std::move(pc.min);
314 max = std::move(pc.max);
315 ids = std::move(pc.ids);
316 particlePositions = std::move(pc.particlePositions);
317 particlePositionUpdated = std::move(pc.particlePositionUpdated);
318 dampingFactor = std::move(pc.dampingFactor);
319 newContact = std::move(pc.newContact);
320 responsibleRank = std::move(pc.responsibleRank);
321
322 return *this;
323}
324
325template <typename T, unsigned D, bool CONVEX>
326template <typename F>
328 T, D, CONVEX>::processWithCommunicatables(F f)
329{
330 //Create communicatables
331 auto communicatablePositions = ConcreteCommunicatable(particlePositions);
332 auto communicatableMin = ConcreteCommunicatable(min);
333 auto communicatableMax = ConcreteCommunicatable(max);
334 auto communicatableIDs = ConcreteCommunicatable(ids);
335 auto communicatableDamping = ConcreteCommunicatable(dampingFactor);
336 auto communicatableParticlePositionUpdated =
337 ConcreteCommunicatable(particlePositionUpdated);
338 auto communicatableIsNew = ConcreteCommunicatable(newContact);
339 auto communicatableRank = ConcreteCommunicatable(responsibleRank);
340
341 return f(communicatablePositions, communicatableMin, communicatableMax,
342 communicatableIDs, communicatableDamping,
343 communicatableParticlePositionUpdated, communicatableIsNew,
344 communicatableRank);
345}
346
347template <typename T, unsigned D, bool CONVEX>
349 std::uint8_t* buffer)
350{
351 return processWithCommunicatables(
352 [&](auto& communicatablePositions, auto& communicatableMin,
353 auto& communicatableMax, auto& communicatableIDs,
354 auto& communicatableDamping,
355 auto& communicatableParticlePositionUpdated,
356 auto& communicatableIsNew, auto& communicatableRank) {
357 std::size_t serialIdx =
358 communicatablePositions.serialize(this->indicesPart, buffer);
359 serialIdx +=
360 communicatableMin.serialize(this->indicesDim, &buffer[serialIdx]);
361 serialIdx +=
362 communicatableMax.serialize(this->indicesDim, &buffer[serialIdx]);
363 serialIdx +=
364 communicatableIDs.serialize(this->indicesPart, &buffer[serialIdx]);
365 serialIdx += communicatableDamping.serialize(this->indicesSingle,
366 &buffer[serialIdx]);
367 serialIdx += communicatableParticlePositionUpdated.serialize(
368 this->indicesSingle, &buffer[serialIdx]);
369 serialIdx += communicatableIsNew.serialize(this->indicesSingle,
370 &buffer[serialIdx]);
371 serialIdx += communicatableRank.serialize(this->indicesSingle,
372 &buffer[serialIdx]);
373
374 return serialIdx;
375 });
376}
377
378template <typename T, unsigned D, bool CONVEX>
379std::size_t
381 std::uint8_t* buffer)
382{
383 return processWithCommunicatables(
384 [&](auto& communicatablePositions, auto& communicatableMin,
385 auto& communicatableMax, auto& communicatableIDs,
386 auto& communicatableDamping,
387 auto& communicatableParticlePositionUpdated,
388 auto& communicatableIsNew, auto& communicatableRank) {
389 std::size_t serialIdx =
390 communicatablePositions.deserialize(this->indicesPart, buffer);
391 serialIdx +=
392 communicatableMin.deserialize(this->indicesDim, &buffer[serialIdx]);
393 serialIdx +=
394 communicatableMax.deserialize(this->indicesDim, &buffer[serialIdx]);
395 serialIdx += communicatableIDs.deserialize(this->indicesPart,
396 &buffer[serialIdx]);
397 serialIdx += communicatableDamping.deserialize(this->indicesSingle,
398 &buffer[serialIdx]);
399 serialIdx += communicatableParticlePositionUpdated.deserialize(
400 this->indicesSingle, &buffer[serialIdx]);
401 serialIdx += communicatableIsNew.deserialize(this->indicesSingle,
402 &buffer[serialIdx]);
403 serialIdx += communicatableRank.deserialize(this->indicesSingle,
404 &buffer[serialIdx]);
405
406 return serialIdx;
407 });
408}
409
410template <typename T, unsigned D, bool CONVEX>
412{
413 OstreamManager clout(std::cout, "ParticleContact");
414 clout.setMultiOutput(true);
415 int rank = singleton::mpi().getRank();
416 if (rank == responsibleRank[0]) {
417 clout << "Min=" << this->min << ", Max=" << this->max << std::endl;
418 clout << "IDs=" << this->ids << ", DampingFactor=" << dampingFactor[0]
419 << std::endl;
420 clout << "Positions=" << particlePositions << std::endl;
421 }
422 clout.setMultiOutput(false);
423}
424
425} // namespace contact
426} // namespace particles
427} // namespace olb
428#endif
class for marking output with some text
void setMultiOutput(bool b)
enable message output for all MPI processes, disabled by default
int getRank() const
Returns the process ID.
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)
void updateMinMax(PhysR< T, D > &min, PhysR< T, D > &max, const PhysR< T, D > &pos)
constexpr T evalDampingFactor(const T coefficientOfRestitution, const T initialRelativeVelocityMagnitude)
Calculates the damping factor according to Carvalho & Martins (2019) (10.1016/j.mechmachtheory....
MpiManager & mpi()
Expr min(Expr a, Expr b)
Definition expr.cpp:249
Expr max(Expr a, Expr b)
Definition expr.cpp:245
Top level namespace for all of OpenLB.
constexpr T max(const ScalarVector< T, D, IMPL > &v)
Definition vector.h:466
An object holding data for a contact which is described analog to Nassauer and Kuna (2013)
constexpr void setDampingFactor(const T dampingFactor)
Set damping factor for contact.
constexpr const std::array< std::size_t, 2 > & getIDs() const
Read access to particle IDs.
constexpr void increaseMinMax(const Vector< T, D > &increaseBy)
Increase bounding box size.
constexpr const PhysR< T, D > & getParticlePosition(const std::size_t &id) const
Return particle position.
constexpr void setParticlePositions(const std::array< PhysR< T, D >, 2 > &positions)
Set particle positions.
constexpr bool isNew() const
Returns if the contact is a new contact.
constexpr void updateMinMax(const PhysR< T, D > &positionInsideTheContact)
Update min and max with given position inside the contact.
constexpr const int & getResponsibleRank() const
Read access to the responsible rank.
constexpr void setDampingFactorFromInitialVelocity(const T coefficientOfRestitution, const T initialRelativeVelocityMagnitude)
Set damping factor from the magnitude of the initial relative impact velocity in direction of contact...
ParticleContactArbitraryFromOverlapVolume< T, D, CONVEX > & operator=(const ParticleContactArbitraryFromOverlapVolume< T, D, CONVEX > &pc)
Copy assignment.
constexpr bool isParticlePositionUpdated() const
Returns if the particle position is up-to-date.
constexpr void setParticlePosition(const PhysR< T, D > &position, const std::size_t &id)
Set position of specific particle.
constexpr const std::array< PhysR< T, D >, 2 > & getParticlePositions() const
Read access to particle positions.
constexpr const PhysR< T, D > & getMax() const
Read access to max.
constexpr bool isEmpty() const
Returns if contact holds data.
std::size_t deserialize(std::uint8_t *buffer)
Deserialize contact data and save in object.
constexpr const PhysR< T, D > & getMin() const
Read access to min.
constexpr void combineWith(ParticleContactArbitraryFromOverlapVolume< T, D, CONVEX > &pc)
Combining two contacts, if the particle ids are the same.
constexpr const T getDampingFactor() const
Read access to damping factor.
constexpr void resetMinMax()
Reset min and max to default values.
std::size_t serialize(std::uint8_t *buffer)
Serialize contact data.
constexpr void setResponsibleRank(const int &rank)
Set processor that is responsible for contact treatment.