OpenLB 1.8.1
Loading...
Searching...
No Matches
wallContact.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 WALL_CONTACT_HH
25#define WALL_CONTACT_HH
26
27#include "wallContact.h"
28
29namespace olb {
30namespace particles {
31namespace contact {
32
33template <typename T, unsigned D, bool CONVEX>
34WallContactArbitraryFromOverlapVolume<
35 T, D, CONVEX>::WallContactArbitraryFromOverlapVolume()
36 : WallContactArbitraryFromOverlapVolume<T, D, CONVEX>(std::size_t(),
37 unsigned())
38{}
39
40template <typename T, unsigned D, bool CONVEX>
42 T, D, CONVEX>::WallContactArbitraryFromOverlapVolume(std::size_t particleID,
43 unsigned wallID)
44 : particleID(std::array<std::size_t, 1>({particleID}))
45 , wallID(std::array<unsigned, 1>({wallID}))
46
47{
48 resetMinMax();
49}
50
51template <typename T, unsigned D, bool CONVEX>
55{
56 min = contact.min;
57 max = contact.max;
58 particleID[0] = contact.particleID[0];
59 wallID[0] = contact.wallID[0];
60 particlePosition = contact.particlePosition;
61 particlePositionUpdated[0] = contact.isParticlePositionUpdated();
62 dampingFactor[0] = contact.getDampingFactor();
63 newContact[0] = contact.isNew();
64 responsibleRank[0] = contact.getResponsibleRank();
65}
66
67template <typename T, unsigned D, bool CONVEX>
71{
72 min = std::move(contact.min);
73 max = std::move(contact.max);
74 particleID = std::move(contact.particleID);
75 wallID = std::move(contact.wallID);
76 particlePosition = std::move(contact.particlePosition);
77 particlePositionUpdated = std::move(contact.particlePositionUpdated);
78 dampingFactor = std::move(contact.dampingFactor);
79 newContact = std::move(contact.newContact);
80 responsibleRank = std::move(contact.responsibleRank);
81}
82
83template <typename T, unsigned D, bool CONVEX>
84constexpr const std::size_t&
86{
87 return this->particleID[0];
88}
89
90template <typename T, unsigned D, bool CONVEX>
91constexpr unsigned
93{
94 return this->wallID[0];
95}
96
97template <typename T, unsigned D, bool CONVEX>
98constexpr const PhysR<T, D>&
103
104template <typename T, unsigned D, bool CONVEX>
105constexpr void
107 const PhysR<T, D>& position)
108{
109 particlePosition = position;
110 particlePositionUpdated[0] = true;
111}
112
113template <typename T, unsigned D, bool CONVEX>
114constexpr void
116 const int& rank)
117{
118 responsibleRank[0] = rank;
119}
120
121template <typename T, unsigned D, bool CONVEX>
122constexpr const int&
124{
125 return responsibleRank[0];
126}
127
128template <typename T, unsigned D, bool CONVEX>
129constexpr const PhysR<T, D>&
134
135template <typename T, unsigned D, bool CONVEX>
136constexpr const PhysR<T, D>&
141
142template <typename T, unsigned D, bool CONVEX>
143constexpr T
148
149template <typename T, unsigned D, bool CONVEX>
150constexpr void
152 const T newDampingFactor)
153{
154 dampingFactor[0] = newDampingFactor;
155}
156
157template <typename T, unsigned D, bool CONVEX>
160 const T coefficientOfRestitution,
161 const T initialRelativeVelocityMagnitude)
162{
164 coefficientOfRestitution, initialRelativeVelocityMagnitude));
165}
166
167template <typename T, unsigned D, bool CONVEX>
168constexpr void
170{
171 for (unsigned iD = 0; iD < D; ++iD) {
172 min[iD] = std::numeric_limits<olb::BaseType<T>>::max();
173 max[iD] = -std::numeric_limits<olb::BaseType<T>>::max();
174 }
175 particlePositionUpdated[0] = false;
176}
177
178template <typename T, unsigned D, bool CONVEX>
179constexpr void
181 const PhysR<T, D>& positionInsideTheContact)
182{
183 particles::contact::updateMinMax(this->min, this->max,
184 positionInsideTheContact);
185}
186
187template <typename T, unsigned D, bool CONVEX>
188constexpr void
190 const Vector<T, D>& increaseBy)
191{
192 this->max += increaseBy;
193 this->min -= increaseBy;
194}
195
196template <typename T, unsigned D, bool CONVEX>
199{
200 if (particleID[0] == contact.particleID[0] &&
201 wallID[0] == contact.wallID[0]) {
202 if(contact.isNew() == newContact[0]) {
203 // Determine bounding box of combined overlap area
204 for (unsigned iD = 0; iD < D; ++iD) {
205 min[iD] = util::min(min[iD], contact.min[iD]);
206 max[iD] = util::max(max[iD], contact.max[iD]);
207 }
208 // The damping factors should be either the same or one is -1 and the other has the correct value which is > 0
209 dampingFactor[0] = util::max(dampingFactor[0], contact.getDampingFactor());
210 responsibleRank[0] =
211 util::min(responsibleRank[0], contact.getResponsibleRank());
212 particlePositionUpdated[0] =
213 particlePositionUpdated[0] || contact.isParticlePositionUpdated();
214 if (!particlePositionUpdated[0] && contact.isParticlePositionUpdated()) {
215 particlePosition = contact.getParticlePosition();
216 }
217 }
218 else {
219 if(!contact.isNew()) {
220 min = contact.getMin();
221 max = contact.getMax();
222 dampingFactor[0] = contact.getDampingFactor();
223 particlePositionUpdated[0] = contact.isParticlePositionUpdated();
224 particlePosition = contact.getParticlePosition();
225 }
226 responsibleRank[0] =
227 util::min(responsibleRank[0], contact.getResponsibleRank());
228 newContact[0] = newContact[0] && contact.isNew();
229 }
230
231 // Ignore second contact by resetting it
232 contact.resetMinMax();
233 }
234}
235
236template <typename T, unsigned D, bool CONVEX>
237constexpr bool
239{
240 for (unsigned iD = 0; iD < D; ++iD) {
241 if (min[iD] > max[iD]) {
242 return true;
243 }
244 }
245 return false;
246}
247
248template <typename T, unsigned D, bool CONVEX>
249constexpr bool
251{
252 return newContact[0];
253}
254
255template <typename T, unsigned D, bool CONVEX>
257 const bool newContact)
258{
259 this->newContact[0] = newContact;
260}
261
262template <typename T, unsigned D, bool CONVEX>
263constexpr bool
265 const
266{
267 return particlePositionUpdated[0];
268}
269
270template <typename T, unsigned D, bool CONVEX>
271constexpr void
273 bool updated)
274{
275 particlePositionUpdated[0] = updated;
276}
277
278template <typename T, unsigned D, bool CONVEX>
282{
283 min = contact.min;
284 max = contact.max;
285 particleID[0] = contact.particleID[0];
286 wallID[0] = contact.wallID[0];
287 particlePosition = contact.particlePosition;
288 particlePositionUpdated[0] = contact.isParticlePositionUpdated();
289 dampingFactor[0] = contact.getDampingFactor();
290 newContact[0] = contact.isNew();
291 responsibleRank[0] = contact.getResponsibleRank();
292
293 return *this;
294}
295
296template <typename T, unsigned D, bool CONVEX>
300{
301 min = std::move(contact.min);
302 max = std::move(contact.max);
303 particleID = std::move(contact.particleID);
304 wallID = std::move(contact.wallID);
305 particlePosition = std::move(contact.particlePosition);
306 particlePositionUpdated = std::move(contact.particlePositionUpdated);
307 dampingFactor = std::move(contact.dampingFactor);
308 newContact = std::move(contact.newContact);
309 responsibleRank = std::move(contact.responsibleRank);
310
311 return *this;
312}
313
314template <typename T, unsigned D, bool CONVEX>
315template <typename F>
316std::size_t
318 F f)
319{
320 //Create communicatables
321 auto communicatablePosition = ConcreteCommunicatable(particlePosition);
322 auto communicatableMin = ConcreteCommunicatable(min);
323 auto communicatableMax = ConcreteCommunicatable(max);
324 auto communicatableID = ConcreteCommunicatable(particleID);
325 auto communicatableMaterial = ConcreteCommunicatable(wallID);
326 auto communicatableDamping = ConcreteCommunicatable(dampingFactor);
327 auto communicatableParticlePositionUpdated =
328 ConcreteCommunicatable(particlePositionUpdated);
329 auto communicatableIsNew = ConcreteCommunicatable(newContact);
330 auto communicatableRank = ConcreteCommunicatable(responsibleRank);
331
332 return f(communicatablePosition, communicatableMin, communicatableMax,
333 communicatableID, communicatableMaterial, communicatableDamping,
334 communicatableParticlePositionUpdated, communicatableIsNew,
335 communicatableRank);
336}
337
338template <typename T, unsigned D, bool CONVEX>
340 std::uint8_t* buffer)
341{
342 return processWithCommunicatables(
343 [&](auto& communicatablePosition, auto& communicatableMin,
344 auto& communicatableMax, auto& communicatableID,
345 auto& communicatableMaterial, auto& communicatableDamping,
346 auto& communicatableParticlePositionUpdated,
347 auto& communicatableIsNew, auto& communicatableRank) {
348 std::size_t serialIdx =
349 communicatablePosition.serialize(this->indicesDim, buffer);
350 serialIdx +=
351 communicatableMin.serialize(this->indicesDim, &buffer[serialIdx]);
352 serialIdx +=
353 communicatableMax.serialize(this->indicesDim, &buffer[serialIdx]);
354 serialIdx +=
355 communicatableID.serialize(this->indicesSingle, &buffer[serialIdx]);
356 serialIdx += communicatableMaterial.serialize(this->indicesSingle,
357 &buffer[serialIdx]);
358 serialIdx += communicatableDamping.serialize(this->indicesSingle,
359 &buffer[serialIdx]);
360 serialIdx += communicatableParticlePositionUpdated.serialize(
361 this->indicesSingle, &buffer[serialIdx]);
362 serialIdx += communicatableIsNew.serialize(this->indicesSingle,
363 &buffer[serialIdx]);
364 serialIdx += communicatableRank.serialize(this->indicesSingle,
365 &buffer[serialIdx]);
366
367 return serialIdx;
368 });
369}
370
371template <typename T, unsigned D, bool CONVEX>
373 std::uint8_t* buffer)
374{
375 return processWithCommunicatables(
376 [&](auto& communicatablePosition, auto& communicatableMin,
377 auto& communicatableMax, auto& communicatableID,
378 auto& communicatableMaterial, auto& communicatableDamping,
379 auto& communicatableParticlePositionUpdated,
380 auto& communicatableIsNew, auto& communicatableRank) {
381 std::size_t serialIdx =
382 communicatablePosition.deserialize(this->indicesDim, buffer);
383 serialIdx +=
384 communicatableMin.deserialize(this->indicesDim, &buffer[serialIdx]);
385 serialIdx +=
386 communicatableMax.deserialize(this->indicesDim, &buffer[serialIdx]);
387 serialIdx += communicatableID.deserialize(this->indicesSingle,
388 &buffer[serialIdx]);
389 serialIdx += communicatableMaterial.deserialize(this->indicesSingle,
390 &buffer[serialIdx]);
391 serialIdx += communicatableDamping.deserialize(this->indicesSingle,
392 &buffer[serialIdx]);
393 serialIdx += communicatableParticlePositionUpdated.deserialize(
394 this->indicesSingle, &buffer[serialIdx]);
395 serialIdx += communicatableIsNew.deserialize(this->indicesSingle,
396 &buffer[serialIdx]);
397 serialIdx += communicatableRank.deserialize(this->indicesSingle,
398 &buffer[serialIdx]);
399
400 return serialIdx;
401 });
402}
403
404template <typename T, unsigned D, bool CONVEX>
406{
407 OstreamManager clout(std::cout, "WallContact");
408 clout.setMultiOutput(true);
409#ifdef PARALLEL_MODE_MPI
410 int rank = singleton::mpi().getRank();
411 if (rank == responsibleRank[0]) {
412#endif
413 clout << "Min=" << this->min << ", Max=" << this->max << std::endl;
414 clout << "particle ID=" << this->particleID[0]
415 << ", wall ID=" << this->wallID[0]
416 << ", DampingFactor=" << dampingFactor[0] << std::endl;
417 clout << "Position=" << particlePosition << std::endl;
418#ifdef PARALLEL_MODE_MPI
419 }
420#endif
421 clout.setMultiOutput(false);
422}
423
424} // namespace contact
425} // namespace particles
426} // namespace olb
427#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.
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
constexpr bool isParticlePositionUpdated() const
Returns if the particle position is up-to-date.
constexpr void setResponsibleRank(const int &rank)
Set processor that is responsible for contact treatment.
constexpr void setDampingFactor(const T dampingFactor)
Set damping factor for contact.
constexpr void setParticlePosition(const PhysR< T, D > &particlePosition)
Set particle position.
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...
constexpr const std::size_t & getParticleID() const
Read access to particle ID.
constexpr const PhysR< T, D > & getMin() const
Read access to min.
constexpr T getDampingFactor() const
Read access to damping factor.
std::size_t serialize(std::uint8_t *buffer)
Serialize contact data.
constexpr void resetMinMax()
Reset min and max to default values.
constexpr unsigned getWallID() const
Read access to wall matreial.
constexpr const int & getResponsibleRank() const
Read access to the responsible rank.
constexpr const PhysR< T, D > & getParticlePosition() const
Return particle position.
WallContactArbitraryFromOverlapVolume< T, D, CONVEX > & operator=(const WallContactArbitraryFromOverlapVolume< T, D, CONVEX > &contact)
Copy assignment.
constexpr bool isEmpty() const
Returns if contact holds data.
constexpr const PhysR< T, D > & getMax() const
Read access to max.
std::size_t deserialize(std::uint8_t *buffer)
Deserialize contact data and save in object.
constexpr void combineWith(WallContactArbitraryFromOverlapVolume< T, D, CONVEX > &contact)
Combining two contacts, if the particle IDs are the same.
constexpr bool isNew() const
Returns if the contact is a new contact.
constexpr void increaseMinMax(const Vector< T, D > &increaseBy)
Increase bounding box size.
constexpr void updateMinMax(const PhysR< T, D > &positionInsideTheContact)
Update min and max with given position inside the contact.