OpenLB 1.7
Loading...
Searching...
No Matches
dataAccessWrappers.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 Nicolas Hafen, Jan E. Marquardt, Martin Sadric, 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
25/* Wrappers for simplified access of particle data.
26 * - features automatic differentiation for different particle types (e.g. radius)
27 * - includes asserts for respective field access
28 *
29*/
30
31#ifndef PARTICLE_DATA_ACCESS_WRAPPERS_H
32#define PARTICLE_DATA_ACCESS_WRAPPERS_H
33
34#include <cassert>
35
36namespace olb {
37
38namespace particles {
39
40namespace access {
41
42//Calculate angular acceleration when considering 3 dimensions
43//TODO: remove to separate location
44template<typename T>
46 const Matrix<T, 3, 3>& rotationMatrix )
47{
48 T data[3][3] = {
49 {momentOfInertia[0], T {0}, T {0}},
50 { T {0}, momentOfInertia[1], T {0}},
51 { T {0}, T {0}, momentOfInertia[2]}
52 };
53 Matrix<T, 3, 3> inertiaTensor(data);
54 inertiaTensor = (rotationMatrix * inertiaTensor) * (rotationMatrix.transpose());
55
56 /*
57 * In the following, we use the solution of a linear equation system
58 * torque = inertia tensor * angular acceleration + angular velocity x (inertia tensor * angular velocity)
59 * Here, we want to know the components of the angular acceleration
60 * In the following, left = torque - angular velocity x (inertia tensor * angular velocity)
61 */
62
63 // const Vector<T,3> angularVelocity = getAngularVelocity(particle);
64 // Using Euler's equation for rigid body dynamics
65 // Currently not, as it leads to inaccurate results of some tests
66 // Add the cross product to use Euler's equation for rigid body dynamics
67 const Vector<T,3> left = torque;//- crossProduct3D(angularVelocity, (inertiaTensor * angularVelocity));
68
69 const T denominator = util::pow(inertiaTensor[0][2], 2) * inertiaTensor[1][1]
70 + inertiaTensor[0][0] * util::pow(inertiaTensor[1][2], 2)
71 - 2 * inertiaTensor[0][1] * inertiaTensor[0][2] * inertiaTensor[1][2]
72 + util::pow(inertiaTensor[0][1], 2) * inertiaTensor[2][2]
73 - inertiaTensor[0][0] * inertiaTensor[1][1] * inertiaTensor[2][2];
74 const T factor = T{1} / denominator;
75
76 Vector<T,3> angularAcceleration;
77 angularAcceleration[0] = (util::pow(inertiaTensor[1][2], 2) - inertiaTensor[1][1] * inertiaTensor[2][2]) * left[0]
78 + (- inertiaTensor[0][2] * inertiaTensor[1][2] + inertiaTensor[0][1] * inertiaTensor[2][2]) * left[1]
79 + (inertiaTensor[0][2] * inertiaTensor[1][1] - inertiaTensor[0][1] * inertiaTensor[1][2]) * left[2];
80 angularAcceleration[1] = (- inertiaTensor[0][2] * inertiaTensor[1][2] + inertiaTensor[0][1] * inertiaTensor[2][2]) * left[0]
81 + (util::pow(inertiaTensor[0][2], 2) - inertiaTensor[0][0] * inertiaTensor[2][2]) * left[1]
82 + (- inertiaTensor[0][1] * inertiaTensor[0][2] + inertiaTensor[0][0] * inertiaTensor[1][2]) * left[2];
83 angularAcceleration[2] = (inertiaTensor[0][2] * inertiaTensor[1][1] - inertiaTensor[0][1] * inertiaTensor[1][2]) * left[0]
84 + (- inertiaTensor[0][1] * inertiaTensor[0][2] + inertiaTensor[0][0] * inertiaTensor[1][2]) * left[1]
85 + (util::pow(inertiaTensor[0][1], 2) - inertiaTensor[0][0] * inertiaTensor[1][1]) * left[2];
86
87 for(unsigned iDim = 0; iDim < 3; ++iDim) {
88 angularAcceleration[iDim] *= factor;
89 }
90
91 return angularAcceleration;
92}
93
95
97template<typename PARTICLETYPE>
98constexpr bool providesID()
99{
100 using namespace descriptors;
101 return PARTICLETYPE::template providesNested<PARALLELIZATION,ID>();
102}
103template<typename T, typename PARTICLETYPE>
104constexpr bool providesID(Particle<T,PARTICLETYPE>& particle){
105 return providesID<PARTICLETYPE>();
106}
107
109template<typename PARTICLETYPE>
110constexpr bool providesInvalid()
111{
112 using namespace descriptors;
113 return PARTICLETYPE::template providesNested<GENERAL,INVALID>();
114}
115template<typename T, typename PARTICLETYPE>
117 return providesInvalid<PARTICLETYPE>();
118}
119
121template<typename PARTICLETYPE>
122constexpr bool providesPosition()
123{
124 using namespace descriptors;
125 return PARTICLETYPE::template providesNested<GENERAL,POSITION>();
126}
127template<typename T, typename PARTICLETYPE>
129 return providesPosition<PARTICLETYPE>();
130}
131
133template<typename PARTICLETYPE>
134constexpr bool providesRadius()
135{
136 using namespace descriptors;
137 return PARTICLETYPE::template providesNested<PHYSPROPERTIES,RADIUS>();
138}
139template<typename T, typename PARTICLETYPE>
140constexpr bool providesRadius(Particle<T,PARTICLETYPE>& particle){
141 return providesRadius<PARTICLETYPE>();
142}
143
145template<typename PARTICLETYPE>
146constexpr bool providesDensity()
147{
148 using namespace descriptors;
149 return PARTICLETYPE::template providesNested<PHYSPROPERTIES,DENSITY>();
150}
151template<typename T, typename PARTICLETYPE>
153 return providesDensity<PARTICLETYPE>();
154}
155
157template<typename PARTICLETYPE>
158constexpr bool providesMass()
159{
160 using namespace descriptors;
161 return PARTICLETYPE::template providesNested<PHYSPROPERTIES,MASS>();
162}
163template<typename T, typename PARTICLETYPE>
164constexpr bool providesMass(Particle<T,PARTICLETYPE>& particle){
165 return providesMass<PARTICLETYPE>();
166}
167
169template<typename PARTICLETYPE>
170constexpr bool providesMassOrDensity()
171{
172 using namespace descriptors;
173 return providesMass<PARTICLETYPE>() || providesDensity<PARTICLETYPE>();
174}
175template<typename T, typename PARTICLETYPE>
177 return providesMassOrDensity<PARTICLETYPE>();
178}
179
181template<typename PARTICLETYPE>
182constexpr bool providesAngle()
183{
184 using namespace descriptors;
185 return PARTICLETYPE::template providesNested<SURFACE,ANGLE>();
186}
187template<typename T, typename PARTICLETYPE>
188constexpr bool providesAngle(Particle<T,PARTICLETYPE>& particle){
189 return providesAngle<PARTICLETYPE>();
190}
191
193template<typename PARTICLETYPE>
194constexpr bool providesVelocity()
195{
196 using namespace descriptors;
197 return PARTICLETYPE::template providesNested<MOBILITY,VELOCITY>();
198}
199template<typename T, typename PARTICLETYPE>
201 return providesVelocity<PARTICLETYPE>();
202}
203
205template<typename PARTICLETYPE>
206constexpr bool providesAngVelocity()
207{
208 using namespace descriptors;
209 return PARTICLETYPE::template providesNested<MOBILITY,ANG_VELOCITY>();
210}
211template<typename T, typename PARTICLETYPE>
213 return providesAngVelocity<PARTICLETYPE>();
214}
215
217template<typename PARTICLETYPE>
218constexpr bool providesForce()
219{
220 using namespace descriptors;
221 return PARTICLETYPE::template providesNested<FORCING,FORCE>();
222}
223template<typename T, typename PARTICLETYPE>
224constexpr bool providesForce(Particle<T,PARTICLETYPE>& particle){
225 return providesForce<PARTICLETYPE>();
226}
227
229template<typename PARTICLETYPE>
230constexpr bool providesTorque()
231{
232 using namespace descriptors;
233 return PARTICLETYPE::template providesNested<FORCING,TORQUE>();
234}
235template<typename T, typename PARTICLETYPE>
236constexpr bool providesTorque(Particle<T,PARTICLETYPE>& particle){
237 return providesTorque<PARTICLETYPE>();
238}
239
241template<typename PARTICLETYPE>
242constexpr bool providesAdhesion()
243{
244 using namespace descriptors;
245 return PARTICLETYPE::template providesNested<FORCING,ADHESION>();
246}
247template<typename T, typename PARTICLETYPE>
249 return providesAdhesion<PARTICLETYPE>();
250}
251
253template<typename PARTICLETYPE>
255{
256 using namespace descriptors;
257 return PARTICLETYPE::template providesNested<PHYSPROPERTIES,MOFI>();
258}
259template<typename T, typename PARTICLETYPE>
261 return providesMomentOfInertia<PARTICLETYPE>();
262}
263
265template<typename PARTICLETYPE>
266constexpr bool providesValid()
267{
268 using namespace descriptors;
269 return PARTICLETYPE::template providesNested<GENERAL,INVALID>();
270}
271template<typename T, typename PARTICLETYPE>
272constexpr bool providesValid(Particle<T,PARTICLETYPE>& particle){
273 return providesValid<PARTICLETYPE>();
274}
275
277template<typename PARTICLETYPE>
278constexpr bool providesDynamicsID()
279{
280 using namespace descriptors;
281 return PARTICLETYPE::template providesNested<DYNBEHAVIOUR,DYNAMICS_ID>();
282}
283template<typename T, typename PARTICLETYPE>
285 return providesDynamicsID<PARTICLETYPE>();
286}
287
289template<typename PARTICLETYPE>
290constexpr bool providesActive()
291{
292 using namespace descriptors;
293 return PARTICLETYPE::template providesNested<DYNBEHAVIOUR,ACTIVE>();
294}
295template<typename T, typename PARTICLETYPE>
296constexpr bool providesActive(Particle<T,PARTICLETYPE>& particle){
297 return providesActive<PARTICLETYPE>();
298}
299
301template<typename PARTICLETYPE>
302constexpr bool providesComputeMotion()
303{
304 using namespace descriptors;
305 return PARTICLETYPE::template providesNested<DYNBEHAVIOUR,COMPUTE_MOTION>();
306}
307template<typename T, typename PARTICLETYPE>
309 return providesComputeMotion<PARTICLETYPE>();
310}
311
313template<typename PARTICLETYPE>
315{
316 using namespace descriptors;
317 return PARTICLETYPE::template providesNested<DYNBEHAVIOUR,COMPUTE_CONTACT>();
318}
319template<typename T, typename PARTICLETYPE>
321 return providesComputeContact<PARTICLETYPE>();
322}
323
325template<typename PARTICLETYPE>
327{
328 using namespace descriptors;
329 return PARTICLETYPE::template providesNested<SURFACE,ROT_MATRIX>();
330}
331template<typename T, typename PARTICLETYPE>
333 return providesRotationMatrix<PARTICLETYPE>();
334}
335
337template<typename PARTICLETYPE>
338constexpr bool providesSurface()
339{
340 using namespace descriptors;
341 return PARTICLETYPE::template providesNested<SURFACE>();
342}
343template<typename T, typename PARTICLETYPE>
345 return providesSurface<PARTICLETYPE>();
346}
347
348// Provides field SINDICATOR
349template<typename PARTICLETYPE>
351{
352 using namespace descriptors;
353 return PARTICLETYPE::template providesNested<SURFACE,SINDICATOR>();
354}
355template<typename T, typename PARTICLETYPE>
357{
358 return providesSmoothIndicator<PARTICLETYPE>();
359}
360
362template<typename PARTICLETYPE>
364{
365 using namespace descriptors;
366 return PARTICLETYPE::template providesNested<PARALLELIZATION>();
367}
368template<typename T, typename PARTICLETYPE>
370 return providesParallelization<PARTICLETYPE>();
371}
372
373template<typename PARTICLETYPE>
374constexpr bool providesSpecies()
375{
376 using namespace descriptors;
377 return PARTICLETYPE::template providesNested<PHYSPROPERTIES,SPECIES>();
378}
379template<typename T, typename PARTICLETYPE>
381 return providesSpecies<PARTICLETYPE>();
382}
383
384template<typename PARTICLETYPE>
385constexpr bool providesDetaching()
386{
387 using namespace descriptors;
388 return PARTICLETYPE::template providesNested<DYNBEHAVIOUR,DETACHING>();
389}
390template<typename T, typename PARTICLETYPE>
392 return providesDetaching<PARTICLETYPE>();
393}
394
395template<typename PARTICLETYPE>
396constexpr bool providesCORoffset()
397{
398 using namespace descriptors;
399 return PARTICLETYPE::template providesNested<SURFACE,COR_OFFSET>();
400}
401template<typename T, typename PARTICLETYPE>
403 return providesCORoffset<PARTICLETYPE>();
404}
405
406template<typename PARTICLETYPE>
407constexpr bool providesElongation()
408{
409 using namespace descriptors;
410 return PARTICLETYPE::template providesNested<SURFACE,ELONGATION>();
411}
412template<typename T, typename PARTICLETYPE>
414 return providesElongation<PARTICLETYPE>();
415}
416
417template<typename PARTICLETYPE>
419{
420 using namespace descriptors;
421 return PARTICLETYPE::template providesNested<MOBILITY,ACCELERATION_STRD>();
422}
423template<typename T, typename PARTICLETYPE>
425 return providesAccelerationStrd<PARTICLETYPE>();
426}
427
428template<typename PARTICLETYPE>
430{
431 using namespace descriptors;
432 return PARTICLETYPE::template providesNested<MOBILITY,ANG_ACC_STRD>();
433}
434template<typename T, typename PARTICLETYPE>
436 return providesAngAccelerationStrd<PARTICLETYPE>();
437}
438
439template<typename PARTICLETYPE>
441{
442 using namespace descriptors;
443 return PARTICLETYPE::template providesNested<NUMERICPROPERTIES,ENLARGEMENT_FOR_CONTACT>();
444}
445template<typename T, typename PARTICLETYPE>
447 return providesEnlargementForContactTreatment<PARTICLETYPE>();
448}
449
450template<typename PARTICLETYPE>
452{
453 using namespace descriptors;
454 return PARTICLETYPE::template providesNested<MECHPROPERTIES,MATERIAL>();
455}
456template<typename T, typename PARTICLETYPE>
458 return providesContactMaterial<PARTICLETYPE>();
459}
460
461template<typename PARTICLETYPE>
462constexpr bool is2D()
463{
464 return (PARTICLETYPE::d==2);
465}
466template<typename T, typename PARTICLETYPE>
467constexpr bool is2D(Particle<T,PARTICLETYPE>& particle){
468 return is2D<PARTICLETYPE>();
469}
470
471template<typename PARTICLETYPE>
472constexpr bool is3D()
473{
474 return (PARTICLETYPE::d==3);
475}
476template<typename T, typename PARTICLETYPE>
477constexpr bool is3D(Particle<T,PARTICLETYPE>& particle){
478 return is3D<PARTICLETYPE>();
479}
480
482
483template<typename T, typename PARTICLETYPE>
485{
486 using namespace descriptors;
487 constexpr unsigned D = PARTICLETYPE::d;
488 static_assert(providesPosition<PARTICLETYPE>(),
489 "Field GENERAL:POSITION has to be provided");
490 Vector<T,D> position( particle.template getField<GENERAL,POSITION>() );
491 return position;
492}
493
494template<bool ensureAngularBounds=false, typename T, typename PARTICLETYPE>
496{
497 using namespace descriptors;
499 static_assert(providesAngle<PARTICLETYPE>(), "Field SURFACE:ANGLE has to be provided");
500 Vector<T,Drot> angle( particle.template getField<SURFACE,ANGLE>() );
501 if constexpr (ensureAngularBounds){
502 for (unsigned iRot=0; iRot<Drot; ++iRot) {
503 angle[iRot] = util::fmod( angle[iRot], 2.*M_PI );
504 }
505 }
506 return angle;
507}
508
509template<typename T, typename PARTICLETYPE>
511{
512 using namespace descriptors;
514 static_assert(providesRotationMatrix<PARTICLETYPE>(), "Field SURFACE:ROT_MATRIX has to be provided");
515 Vector<T,DrotMat> rotationMatrix( particle.template getField<SURFACE,ROT_MATRIX>() );
516 return rotationMatrix;
517}
518
519template<unsigned dir=2, typename T, typename PARTICLETYPE>
521{
522 using namespace descriptors;
523 constexpr unsigned D = PARTICLETYPE::d;
524 auto rotationMatrix = getRotationMatrix( particle );
525 //Note: Convention here, positively pointing towards dir (default z-dir)
526 Vector<T,D> normal;
527 for (unsigned iDim=0; iDim<D; ++iDim) {
528 unsigned iMat = D*iDim+dir;
529 normal[iDim] = rotationMatrix[iMat];
530 }
531 return normal;
532}
533
534template<typename T, typename PARTICLETYPE>
536{
537 using namespace descriptors;
538 constexpr unsigned D = PARTICLETYPE::d;
539 static_assert(providesVelocity<PARTICLETYPE>(), "Field MOBILITY:VELOCITY has to be provided");
540 Vector<T,D> velocity( particle.template getField<MOBILITY,VELOCITY>() );
541 return velocity;
542}
543
544template<typename T, typename PARTICLETYPE>
546{
547 using namespace descriptors;
549 static_assert(providesAngVelocity<PARTICLETYPE>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
550 Vector<T,Drot> angVelocity( particle.template getField<MOBILITY,ANG_VELOCITY>() );
551 return angVelocity;
552}
553
554template<typename T, typename PARTICLETYPE>
556{
557 using namespace descriptors;
558 constexpr unsigned D = PARTICLETYPE::d;
559 static_assert(providesForce<PARTICLETYPE>(), "Field FORCING:FORCE has to be provided");
560 Vector<T,D> force( particle.template getField<FORCING,FORCE>() );
561 return force;
562}
563
564template<typename T, typename PARTICLETYPE>
566{
567 using namespace descriptors;
569 static_assert(providesTorque<PARTICLETYPE>(), "Field FORCING:TORQUE has to be provided");
570 Vector<T,Drot> torque( particle.template getField<FORCING,TORQUE>() );
571 return torque;
572}
573
574template<typename T, typename PARTICLETYPE>
576{
577 using namespace descriptors;
579 static_assert(providesMomentOfInertia<PARTICLETYPE>(), "Field PHYSPROPERTIES:MOFI has to be provided");
580 Vector<T,Drot> mofi( particle.template getField<PHYSPROPERTIES,MOFI>() );
581 return mofi;
582}
583
584// Consisting of normal and tangential adhesion component of particle.
585template<typename T, typename PARTICLETYPE>
587{
588 using namespace descriptors;
589
590 static_assert(providesAdhesion<PARTICLETYPE>(), "Field FORCING:ADHESION has to be provided");
591 Vector<T,2> adhesion( particle.template getField<FORCING,ADHESION>() );
592 return adhesion;
593}
594
595template<typename T, typename PARTICLETYPE>
597{
598 using namespace descriptors;
599 bool valid = true;
600 if constexpr(providesValid<PARTICLETYPE>()) {
601 valid = !particle.template getField<GENERAL,INVALID>();
602 }
603 return valid;
604}
605
606template<typename T, typename PARTICLETYPE>
608{
609 using namespace descriptors;
610 bool active = true;
611 if constexpr(providesActive<PARTICLETYPE>()) {
612 active = particle.template getField<DYNBEHAVIOUR,ACTIVE>();
613 }
614 return active;
615}
616
617//Get smooth indicator pointer
618template<typename T, typename PARTICLETYPE>
620{
621 using namespace descriptors;
622 static_assert(providesSmoothIndicator<PARTICLETYPE>(), "Field FORCING:SINDICATOR has to be provided");
623 auto sIndicatorPtr = particle.template getField<SURFACE,SINDICATOR>();
624 return sIndicatorPtr;
625}
626
627//Get radius
628template<typename T, typename PARTICLETYPE>
630{
631 using namespace descriptors;
632 T radius;
633 if constexpr (providesSmoothIndicator<PARTICLETYPE>() ) {
634 radius = getSmoothIndicatorPtr(particle)->getCircumRadius();
635 }
636 else if constexpr ( providesRadius<PARTICLETYPE>() ) {
637 radius = particle.template getField<PHYSPROPERTIES,RADIUS>();
638 }
639 else {
640 std::cerr << "ERROR: no Field found providing radius!" << std::endl;
641 }
642 return radius;
643}
644
647template<typename T, typename PARTICLETYPE>
648T getVolume( Particle<T,PARTICLETYPE> particle, [[maybe_unused]] T shapeFactor = T{1} )
649{
650 using namespace descriptors;
651 constexpr unsigned D = PARTICLETYPE::d;
652 T volume;
653 if constexpr(providesSurface(particle)) {
654 if constexpr (D == 3) {
655 volume = getSmoothIndicatorPtr(particle)->getVolume();
656 }
657 else {
658 volume = getSmoothIndicatorPtr(particle)->getArea();
659 }
660 }
661 else {
662 const T radius = getRadius(particle);
663 if constexpr(D == 3) {
664 volume = (4./3.) * M_PI * util::pow(radius, D);
665 }
666 else {
667 volume = M_PI * util::pow(radius, D);
668 }
669 volume *= shapeFactor;
670 }
671 return volume;
672}
673
674template<typename T, typename PARTICLETYPE>
675T getDensity( Particle<T,PARTICLETYPE> particle, [[maybe_unused]] T shapeFactor = T{1} )
676{
677 using namespace descriptors;
678 static_assert(providesMassOrDensity(particle),
679 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
680 T density;
681 // Always rather use the density field than the mass field
682 if constexpr(providesDensity(particle)) {
683 density = particle.template getField<PHYSPROPERTIES, DENSITY>();
684 }
685 else {
686 const T mass = particle.template getField<PHYSPROPERTIES, MASS>();
687 density = mass / getVolume(particle, shapeFactor);
688 }
689 return density;
690}
691
692template<typename T, typename PARTICLETYPE>
693T getMass( Particle<T,PARTICLETYPE> particle, [[maybe_unused]] T shapeFactor = T{1} )
694{
695 using namespace descriptors;
696 static_assert(providesMassOrDensity(particle),
697 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
698 T mass;
699 // Always rather use the mass field than the density field
700 if constexpr(providesMass(particle)) {
701 mass = particle.template getField<PHYSPROPERTIES, MASS>();
702 }
703 else {
704 const T density = particle.template getField<PHYSPROPERTIES, DENSITY>();
705 mass = density * getVolume(particle, shapeFactor);
706 }
707 return mass;
708}
709
710template<typename T, typename PARTICLETYPE>
712{
713 using namespace descriptors;
714
715 if(providesAccelerationStrd(particle)){
716 return particle.template getField<MOBILITY,ACCELERATION_STRD>();
717 }
718}
719
720template<typename T, typename PARTICLETYPE>
722{
723 using namespace descriptors;
724 static_assert(providesAccelerationStrd<PARTICLETYPE>(), "Field MOBILITY:ACCELERATION has to be provided");
725 if constexpr(providesAccelerationStrd(particle)) {
726 particle.template setField<MOBILITY, ACCELERATION_STRD>(acceleration);
727 }
728}
729
730template<typename T, typename PARTICLETYPE>
732{
733 using namespace descriptors;
734 constexpr unsigned D = PARTICLETYPE::d;
735
736 static_assert(providesForce<PARTICLETYPE>(), "Field FORCING:FORCE has to be provided");
737 static_assert(providesMass<PARTICLETYPE>(), "Field PHYSPROPERTIES:MASS has to be provided");
738
739 Vector<T,D> acceleration;
740 Vector<T,D> force = getForce(particle);
741 T mass = getMass(particle);
742 for (unsigned iDim=0; iDim<D; ++iDim) {
743 acceleration[iDim] = force[iDim] / mass;
744 }
745 return acceleration;
746}
747
748// no need for setAcceleration (non-std) as it is calculated from force and mass
749
750template<typename T, typename PARTICLETYPE>
752 Particle<T,PARTICLETYPE> particle )
753{
754 using namespace descriptors;
755
757 static_assert(providesTorque<PARTICLETYPE>(), "Field FORCING:TORQUE has to be provided");
758 static_assert(providesMomentOfInertia<PARTICLETYPE>(), "Field PHYSPROPERTIES:MOFI has to be provided");
759 Vector<T,Drot> angularAcceleration;
760 Vector<T,Drot> torque( getTorque(particle));
761 Vector<T,Drot> momentOfInertia( getMomentOfInertia(particle) );
762 if constexpr (PARTICLETYPE::d == 3 && providesRotationMatrix<PARTICLETYPE>()) {
763 const Matrix<T,3,3> rotationMatrix(getRotationMatrix(particle));
764 angularAcceleration = calcAngAcceleration3D( torque, momentOfInertia, rotationMatrix );
765 } else {
766 for (unsigned iRot=0; iRot<Drot; ++iRot) {
767 angularAcceleration[iRot] = torque[iRot] / momentOfInertia[iRot];
768 }
769 }
770 return angularAcceleration;
771}
772
773template<typename T, typename PARTICLETYPE>
775{
776 using namespace descriptors;
777
778 if(providesAngAccelerationStrd(particle)){
779 return particle.template getField<MOBILITY,ANG_ACC_STRD>();
780 }
781}
782
783//Get global id
784template<typename T, typename PARTICLETYPE>
786{
787 using namespace descriptors;
788 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
789 auto globalID = particle.template getField<PARALLELIZATION,ID>();
790 return globalID;
791}
792
793//Get globiC (e.g allowing for the determination, whether dealing with particle centre)
794template<typename T, typename PARTICLETYPE>
796{
797 using namespace descriptors;
798 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
799 auto globalIC = particle.template getField<PARALLELIZATION,IC>();
800 return globalIC;
801}
802
803//Get dynamics id
804template<typename T, typename PARTICLETYPE>
805unsigned short getDynamicsID( Particle<T,PARTICLETYPE>& particle )
806{
807 using namespace descriptors;
808 static_assert(providesDynamicsID<PARTICLETYPE>(),
809 "Field DYNBEHAVIOUR:DYNAMICS_ID has to be provided");
810 unsigned short dynamicsID = particle.template getField<DYNBEHAVIOUR,DYNAMICS_ID>();
811 return dynamicsID;
812}
813
814//Get detaching state
815template<typename T, typename PARTICLETYPE>
817{
818 using namespace descriptors;
819 static_assert(providesDetaching<PARTICLETYPE>(),
820 "Field DYNBEHAVIOUR:DETACHING has to be provided");
821 bool detaching = particle.template getField<DYNBEHAVIOUR,DETACHING>();
822 return detaching;
823 }
824
825//Get extent of cuboid surface
826//- throws error during static_cast, when assumption of cuboid shape is false
827template<typename T, typename PARTICLETYPE>
829{
830 using namespace descriptors;
831 constexpr unsigned D = PARTICLETYPE::d;
832 static_assert(providesSmoothIndicator<PARTICLETYPE>(), "Field FORCING:SINDICATOR has to be provided");
833 using SIndicatorType = std::conditional_t<
834 D == 2,
837 >;
838 //Retrieve surface indicator
839 auto sIndicatorPtr = getSmoothIndicatorPtr(particle);
840 auto sIndicatorCuboidPtr = static_cast<SIndicatorType*>(sIndicatorPtr);
841 auto& indicatorCuboid = sIndicatorCuboidPtr->getIndicator();
842 //Retrieve extent
843 if constexpr(D==2){
844 Vector<T,D> extent(
845 indicatorCuboid.getxLength(),
846 indicatorCuboid.getyLength()
847 );
848 return extent;
849 } else {
850 Vector<T,D> extent(
851 indicatorCuboid.getxLength(),
852 indicatorCuboid.getyLength(),
853 indicatorCuboid.getzLength()
854 );
855 return extent;
856 }
857}
858
859template<typename T, typename PARTICLETYPE>
861{
862 using namespace descriptors;
863 constexpr unsigned D = PARTICLETYPE::d;
864 static_assert(providesCORoffset<PARTICLETYPE>(), "Field SURFACE:COR_OFFSET has to be provided");
865 Vector<T,D> offsetCOR( particle.template getField<SURFACE,COR_OFFSET>() );
866 return offsetCOR;
867}
868
869template<typename T, typename PARTICLETYPE>
871{
872 using namespace descriptors;
873 constexpr unsigned D = PARTICLETYPE::d;
874 static_assert(providesElongation<PARTICLETYPE>(), "Field SURFACE:ELONGATION has to be provided");
875 Vector<T,D> elongation( particle.template getField<SURFACE,ELONGATION>() );
876 return elongation;
877}
878
879// Get particle enlargement for contact treatment
880template<typename T, typename PARTICLETYPE>
882{
883 using namespace descriptors;
884 if constexpr (access::providesEnlargementForContactTreatment<PARTICLETYPE>()) {
885 return particle.template getField<NUMERICPROPERTIES,ENLARGEMENT_FOR_CONTACT>();
886 }
887 else {
888 return T{0.};
889 }
890
891 __builtin_unreachable();
892}
893
894template<typename T, typename PARTICLETYPE>
896{
897 using namespace descriptors;
898 static_assert(providesContactMaterial(particle),
899 "Field MECHPROPERTIES::MATERIAL has to be provided");
900 return particle.template getField<MECHPROPERTIES, MATERIAL>();
901}
902
904
905template<typename T, typename PARTICLETYPE>
906void setDensity( Particle<T,PARTICLETYPE> particle, T density, [[maybe_unused]] T shapeFactor = T{1} )
907{
908 using namespace descriptors;
909 static_assert(providesMassOrDensity(particle),
910 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
911
912 if constexpr(providesDensity(particle)) {
913 particle.template setField<PHYSPROPERTIES, DENSITY>(density);
914 }
915 if constexpr(providesMass(particle)) {
916 const T mass = density * getVolume(particle, shapeFactor);
917 particle.template setField<PHYSPROPERTIES, MASS>(mass);
918 }
919}
920
921template<typename T, typename PARTICLETYPE>
922void setMass( Particle<T,PARTICLETYPE> particle, T mass, [[maybe_unused]] T shapeFactor = T{1} )
923{
924 using namespace descriptors;
925 static_assert(providesMassOrDensity(particle),
926 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
927
928 if constexpr(providesMass(particle)) {
929 particle.template setField<PHYSPROPERTIES, MASS>(mass);
930 }
931 if constexpr(providesDensity(particle)){
932 const T density = mass / getVolume(particle, shapeFactor);
933 particle.template setField<PHYSPROPERTIES, DENSITY>(density);
934 }
935}
936
937template<typename T, typename PARTICLETYPE>
939{
940 using namespace descriptors;
941 static_assert(providesPosition(particle),
942 "Field GENERAL:POSITION has to be provided");
943 particle.template setField<GENERAL, POSITION>(position);
944}
945
946template<typename T, typename PARTICLETYPE>
947void setContactMaterial( Particle<T,PARTICLETYPE> particle, unsigned material )
948{
949 using namespace descriptors;
950 static_assert(providesContactMaterial(particle),
951 "Field MECHPROPERTIES::MATERIAL has to be provided");
952 particle.template setField<MECHPROPERTIES, MATERIAL>(material);
953}
954
955template<typename T, typename PARTICLETYPE>
957{
958 using namespace descriptors;
959 static_assert(providesAngle<PARTICLETYPE>(), "Field SURFACE:ANGLE has to be provided");
960 particle.template setField<SURFACE, ANGLE>(utilities::dimensions::convert<
961 PARTICLETYPE::d>::serialize_rotation(angle));
962}
963
964template<typename T, typename PARTICLETYPE>
966{
967 using namespace descriptors;
968 static_assert(providesRotationMatrix<PARTICLETYPE>(), "Field SURFACE:ROT_MATRIX has to be provided");
969 particle.template setField<SURFACE,ROT_MATRIX>(rotMatrix);
970}
971
972template<typename T, typename PARTICLETYPE>
974{
975 using namespace descriptors;
976 static_assert(providesVelocity<PARTICLETYPE>(), "Field MOBILITY:VELOCITY has to be provided");
977 particle.template setField<MOBILITY,VELOCITY>(velocity);
978}
979
980template<typename T, typename PARTICLETYPE>
982{
983 using namespace descriptors;
984 static_assert(providesAngVelocity<PARTICLETYPE>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
985 particle.template setField<MOBILITY,ANG_VELOCITY>(utilities::dimensions::convert<
986 PARTICLETYPE::d>::serialize_rotation(angVelocity));
987}
988
989template<typename T, typename PARTICLETYPE>
991{
992 using namespace descriptors;
993 static_assert(providesAngAccelerationStrd<PARTICLETYPE>(), "Field MOBILITY:ANG_ACC_STRD has to be provided");
994 particle.template setField<MOBILITY,ANG_ACC_STRD>(utilities::dimensions::convert<
995 PARTICLETYPE::d>::serialize_rotation(angAcceleration));
996}
997
998// no need for setAngAcceleration (non-strd) as it is calculated from torque and moment of inertia
999
1000template<typename T, typename PARTICLETYPE>
1002{
1003 using namespace descriptors;
1004 static_assert(providesForce<PARTICLETYPE>(), "Field FORCING:FORCE has to be provided");
1005 particle.template setField<FORCING,FORCE>(force);
1006}
1007
1008template<typename T, typename PARTICLETYPE>
1010{
1011 using namespace descriptors;
1012 static_assert(providesTorque<PARTICLETYPE>(), "Field FORCING:TORQUE has to be provided");
1013 particle.template setField<FORCING,TORQUE>(utilities::dimensions::convert<
1014 PARTICLETYPE::d>::serialize_rotation(torque));
1015}
1016
1017template<typename T, typename PARTICLETYPE>
1019{
1020 using namespace descriptors;
1021 static_assert(providesMomentOfInertia<PARTICLETYPE>(), "Field PHYSPROPERTIES:MOFI has to be provided");
1022 particle.template setField<PHYSPROPERTIES,MOFI>(utilities::dimensions::convert<
1023 PARTICLETYPE::d>::serialize_rotation(mofi));
1024}
1025
1026// Consisting of normal and tangential adhesion component of particle.
1027template<typename T, typename PARTICLETYPE>
1029{
1030 using namespace descriptors;
1031 static_assert(providesAdhesion<PARTICLETYPE>(), "Field FORCING:ADHESION has to be provided");
1032 particle.template setField<FORCING,ADHESION>(adhesion);
1033}
1034
1035template<typename T, typename PARTICLETYPE>
1036void setInvalid( Particle<T,PARTICLETYPE> particle, bool value=true )
1037{
1038 using namespace descriptors;
1039 static_assert(providesInvalid<PARTICLETYPE>(), "Field GENERAL:INVALID has to be provided");
1040 particle.template setField<GENERAL,INVALID>( value );
1041}
1042
1043template<typename T, typename PARTICLETYPE>
1044void setValid( Particle<T,PARTICLETYPE> particle, bool value=true )
1045{
1046 setInvalid(particle, !value);
1047}
1048
1049template<typename T, typename PARTICLETYPE>
1050void setActive( Particle<T,PARTICLETYPE> particle, bool value=true)
1051{
1052 using namespace descriptors;
1053 static_assert(providesActive<PARTICLETYPE>(), "Field DYNBEHAVIOUR:ACTIVE has to be provided");
1054 particle.template setField<DYNBEHAVIOUR,ACTIVE>( value );
1055}
1056
1057template<typename T, typename PARTICLETYPE>
1058void setInactive( Particle<T,PARTICLETYPE> particle, bool value=true)
1059{
1060 setActive(particle, !value);
1061}
1062
1063//Set smooth indicator pointer
1064template<typename T, typename PARTICLETYPE>
1067{
1068 using namespace descriptors;
1069 static_assert(providesSmoothIndicator<PARTICLETYPE>(), "Field FORCING:SINDICATOR has to be provided");
1070 particle.template setField<SURFACE,SINDICATOR>(sindicator);
1071}
1072
1073//Set radius
1074template<typename T, typename PARTICLETYPE>
1075void setRadius( Particle<T,PARTICLETYPE>& particle, T radius )
1076{
1077 using namespace descriptors;
1078 static_assert(providesRadius<PARTICLETYPE>(), "Field PHYSPROPERTIES:RADIUS has to be provided");
1079 particle.template setField<PHYSPROPERTIES,RADIUS>(radius);
1080}
1081
1082template<typename T, typename PARTICLETYPE>
1083void setGlobalID( Particle<T,PARTICLETYPE> particle, std::size_t id )
1084{
1085 using namespace descriptors;
1086 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
1087 particle.template setField<PARALLELIZATION,ID>(id);
1088}
1089
1090template<typename T, typename PARTICLETYPE>
1092{
1093 using namespace descriptors;
1094 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
1095 particle.template setField<PARALLELIZATION,IC>(id);
1096}
1097
1098template<typename T, typename PARTICLETYPE>
1099void setDynamicsID( Particle<T,PARTICLETYPE>& particle, unsigned short dynamicsID )
1100{
1101 using namespace descriptors;
1102 static_assert(providesDynamicsID<PARTICLETYPE>(),
1103 "Field DYNBEHAVIOUR:DYNAMICS_ID has to be provided");
1104 particle.template setField<DYNBEHAVIOUR,DYNAMICS_ID>(dynamicsID);
1105}
1106
1107template<typename T, typename PARTICLETYPE>
1108void setDetaching( Particle<T,PARTICLETYPE>& particle, bool value)
1109{
1110 using namespace descriptors;
1111 static_assert(providesDetaching<PARTICLETYPE>(),
1112 "Field DYNBEHAVIOUR:DETACHING has to be provided");
1113 particle.template setField<DYNBEHAVIOUR,DETACHING>(value);
1114}
1115
1116template<typename T, typename PARTICLETYPE>
1118{
1119 using namespace descriptors;
1120 static_assert(providesCORoffset<PARTICLETYPE>(), "Field SURFACE:COR_OFFSET has to be provided");
1121 particle.template setField<SURFACE,COR_OFFSET>(offsetCOR);
1122}
1123
1124template<typename T, typename PARTICLETYPE>
1126{
1127 using namespace descriptors;
1128 static_assert(providesElongation<PARTICLETYPE>(), "Field SURFACE:ELONGATION has to be provided");
1129 particle.template setField<SURFACE,ELONGATION>(elongation);
1130}
1131
1132template<typename T, typename PARTICLETYPE>
1134{
1135 using namespace descriptors;
1136 static_assert(access::providesEnlargementForContactTreatment<PARTICLETYPE>(), "Field NUMERICPROPERTIES:ENLARGEMENT_FOR_CONTACT has to be provided");
1137 particle.template setField<NUMERICPROPERTIES, ENLARGEMENT_FOR_CONTACT>(value);
1138}
1139
1141template<typename T, typename PARTICLETYPE>
1143{
1144 using namespace descriptors;
1145
1146 // if the field is not provided, return true by default
1147 if constexpr(!providesComputeMotion<PARTICLETYPE>()) {
1148 return true;
1149 }
1150 else {
1151 return particle.template getField<DYNBEHAVIOUR,COMPUTE_MOTION>();
1152 }
1153
1154 __builtin_unreachable();
1155}
1156
1158template<typename T, typename PARTICLETYPE>
1160{
1161 using namespace descriptors;
1162
1163 // if the field is not provided, return true by default
1164 // (meaning that the contact forces are computed and applied to the force field)
1165 if constexpr(!providesComputeContact<PARTICLETYPE>()) {
1166 return true;
1167 }
1168 else {
1169 return particle.template getField<DYNBEHAVIOUR,COMPUTE_CONTACT>();
1170 }
1171
1172 __builtin_unreachable();
1173}
1174
1176template<typename T, typename PARTICLETYPE>
1178 Particle<T,PARTICLETYPE>& particleB)
1179{
1180 return (isContactComputationEnabled(particleA) || isContactComputationEnabled(particleB));
1181}
1182
1183template<typename T, typename PARTICLETYPE>
1184void enableMotionComputation(Particle<T, PARTICLETYPE>& particle, bool value = true)
1185{
1186 using namespace descriptors;
1187 static_assert(providesComputeMotion<PARTICLETYPE>(), "Field DYNBEHAVIOUR:COMPUTE_MOTION has to be provided");
1188 particle.template setField<DYNBEHAVIOUR, COMPUTE_MOTION>(value);
1189}
1190
1191template<typename T, typename PARTICLETYPE>
1192void enableContactComputation(Particle<T, PARTICLETYPE>& particle, bool value = true)
1193{
1194 using namespace descriptors;
1195 static_assert(providesComputeContact<PARTICLETYPE>(), "Field DYNBEHAVIOUR:COMPUTE_CONTACT has to be provided");
1196 particle.template setField<DYNBEHAVIOUR, COMPUTE_CONTACT>(value);
1197}
1198
1199template<typename T, typename PARTICLETYPE>
1200void disableMotionComputation(Particle<T, PARTICLETYPE>& particle, bool value = true)
1201{
1202 enableMotionComputation(particle, !value);
1203}
1204
1205template<typename T, typename PARTICLETYPE>
1207{
1208 enableContactComputation(particle, !value);
1209}
1210
1211template<typename T, typename PARTICLETYPE>
1213{
1214 if constexpr(providesVelocity(particle)){
1216 }
1217
1218 if constexpr(providesAccelerationStrd(particle)){
1220 }
1221
1222
1223 if constexpr(providesAngVelocity(particle)){
1225 }
1226
1227 if constexpr(providesAngAccelerationStrd(particle)){
1229 }
1230}
1231
1232} //namespace access
1233
1234} //namespace particles
1235
1236} //namespace olb
1237
1238
1239
1240
1241#endif
#define M_PI
Matrix with a defined number of ROWS and columns (COLS)
Definition matrix.h:31
constexpr Matrix< T, COLS, ROWS > transpose() const
Definition matrix.h:125
implements a smooth cuboid in 2D with an _epsilon sector.
implements a smooth particle cuboid in 3D with an _epsilon sector.
Plain old scalar vector.
Definition vector.h:47
void setRotationMatrix(Particle< T, PARTICLETYPE > particle, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::matrix > rotMatrix)
void setAccelerationStrd(Particle< T, PARTICLETYPE > particle, Vector< T, PARTICLETYPE::d > acceleration)
constexpr bool providesInvalid()
Provides field ID.
constexpr bool providesPosition()
Provides field POSITION.
constexpr bool providesParallelization()
Provides group PARALLELIZATION.
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::matrix > getRotationMatrix(Particle< T, PARTICLETYPE > particle)
constexpr bool providesMassOrDensity()
Provides field MASS or DENSITY.
void setRadius(Particle< T, PARTICLETYPE > &particle, T radius)
void setAngAccelerationStrd(Particle< T, PARTICLETYPE > particle, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angAcceleration)
constexpr bool providesTorque()
Provides field TORQUE.
constexpr bool providesAccelerationStrd()
constexpr bool providesValid()
Provides field INVALID.
constexpr bool providesComputeContact()
Provides field COMPUTE_CONTACT.
Vector< T, PARTICLETYPE::d > getForce(Particle< T, PARTICLETYPE > particle)
constexpr bool providesComputeMotion()
Provides field COMPUTE_MOTION.
void setDynamicsID(Particle< T, PARTICLETYPE > &particle, unsigned short dynamicsID)
void disableContactComputation(Particle< T, PARTICLETYPE > &particle, bool value=true)
constexpr bool providesSurface()
Provides group SURFACE.
T getDensity(Particle< T, PARTICLETYPE > particle, T shapeFactor=T{1})
void setMass(Particle< T, PARTICLETYPE > particle, T mass, T shapeFactor=T{1})
void setAngularVelocity(Particle< T, PARTICLETYPE > particle, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angVelocity)
void setAngle(Particle< T, PARTICLETYPE > particle, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angle)
constexpr bool providesMass()
Provides field MASS.
Vector< T, PARTICLETYPE::d > getCORoffset(Particle< T, PARTICLETYPE > particle)
constexpr bool providesRadius()
Provides field RADIUS.
bool isMotionComputationEnabled(Particle< T, PARTICLETYPE > &particle)
Check if motion is enabled.
bool isActive(Particle< T, PARTICLETYPE > particle)
void setInvalid(Particle< T, PARTICLETYPE > particle, bool value=true)
auto getGlobalID(Particle< T, PARTICLETYPE > particle)
constexpr bool providesAngle()
Provides field ANGLE.
void setValid(Particle< T, PARTICLETYPE > particle, bool value=true)
bool isValid(Particle< T, PARTICLETYPE > particle)
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getAngAcceleration(Particle< T, PARTICLETYPE > particle)
auto getGlobalIC(Particle< T, PARTICLETYPE > particle)
unsigned short getDynamicsID(Particle< T, PARTICLETYPE > &particle)
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getMomentOfInertia(Particle< T, PARTICLETYPE > particle)
Vector< T, 3 > calcAngAcceleration3D(Vector< T, 3 > &torque, Vector< T, 3 > &momentOfInertia, const Matrix< T, 3, 3 > &rotationMatrix)
constexpr bool providesSpecies()
Vector< T, PARTICLETYPE::d > getElongation(Particle< T, PARTICLETYPE > particle)
void setGlobalID(Particle< T, PARTICLETYPE > particle, std::size_t id)
void setCORoffset(Particle< T, PARTICLETYPE > particle, Vector< T, PARTICLETYPE::d > offsetCOR)
void setRestingParticle(Particle< T, PARTICLETYPE > particle)
void setDensity(Particle< T, PARTICLETYPE > particle, T density, T shapeFactor=T{1})
constexpr bool providesActive()
Provides field ACTIVE.
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getAngAccelerationStrd(Particle< T, PARTICLETYPE > particle)
void setEnlargementForContact(Particle< T, PARTICLETYPE > &particle, T value)
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getTorque(Particle< T, PARTICLETYPE > particle)
constexpr bool providesEnlargementForContactTreatment()
constexpr bool providesAdhesion()
Provides field ADHESION.
T getRadius(Particle< T, PARTICLETYPE > &particle)
constexpr bool providesForce()
Provides field FORCE.
void enableMotionComputation(Particle< T, PARTICLETYPE > &particle, bool value=true)
constexpr bool providesRotationMatrix()
Provides field ROT_MATRIX.
void setMomentOfInertia(Particle< T, PARTICLETYPE > particle, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > mofi)
Vector< T, PARTICLETYPE::d > getVelocity(Particle< T, PARTICLETYPE > particle)
void setElongation(Particle< T, PARTICLETYPE > particle, Vector< T, PARTICLETYPE::d > elongation)
auto getSmoothIndicatorPtr(Particle< T, PARTICLETYPE > particle)
unsigned getContactMaterial(Particle< T, PARTICLETYPE > particle)
constexpr bool providesID()
Provides field ID.
void setVelocity(Particle< T, PARTICLETYPE > particle, Vector< T, PARTICLETYPE::d > velocity)
void setDetaching(Particle< T, PARTICLETYPE > &particle, bool value)
constexpr bool providesDensity()
Provides field DENSITY.
bool isContactComputationEnabled(Particle< T, PARTICLETYPE > &particle)
Check if contact should be regarded (specification for a single particle)
Vector< T, PARTICLETYPE::d > getAcceleration(Particle< T, PARTICLETYPE > particle)
constexpr bool providesVelocity()
Provides field VELOCITY.
constexpr bool providesDetaching()
constexpr bool providesMomentOfInertia()
Provides field MOFI.
T getVolume(Particle< T, PARTICLETYPE > particle, T shapeFactor=T{1})
Returns the volume of a particle (for subgrid the volume of a sphere/circle is multiplied by the shap...
T getMass(Particle< T, PARTICLETYPE > particle, T shapeFactor=T{1})
void setInactive(Particle< T, PARTICLETYPE > particle, bool value=true)
void setAdhesion(Particle< T, PARTICLETYPE > &particle, Vector< T, 2 > adhesion)
auto getCuboidSurfaceExtent(Particle< T, PARTICLETYPE > particle)
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getAngle(Particle< T, PARTICLETYPE > particle)
void enableContactComputation(Particle< T, PARTICLETYPE > &particle, bool value=true)
constexpr bool providesElongation()
constexpr bool providesAngVelocity()
Provides field VELOCITY.
constexpr bool providesSmoothIndicator()
void setActive(Particle< T, PARTICLETYPE > particle, bool value=true)
constexpr bool providesCORoffset()
void setGlobalIC(Particle< T, PARTICLETYPE > particle, int id)
void setPosition(Particle< T, PARTICLETYPE > particle, Vector< T, PARTICLETYPE::d > position)
constexpr bool providesDynamicsID()
Provides field DYNAMICS_ID.
constexpr bool providesAngAccelerationStrd()
void setForce(Particle< T, PARTICLETYPE > particle, Vector< T, PARTICLETYPE::d > force)
T getEnlargementForContact(Particle< T, PARTICLETYPE > particle)
Vector< T, PARTICLETYPE::d > getPosition(Particle< T, PARTICLETYPE > particle)
constexpr bool providesContactMaterial()
Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > getAngularVelocity(Particle< T, PARTICLETYPE > particle)
Vector< T, PARTICLETYPE::d > getAccelerationStrd(Particle< T, PARTICLETYPE > particle)
void disableMotionComputation(Particle< T, PARTICLETYPE > &particle, bool value=true)
void setSmoothIndicatorPtr(Particle< T, PARTICLETYPE > particle, SmoothIndicatorF< T, T, PARTICLETYPE::d, true > *sindicator)
bool isDetaching(Particle< T, PARTICLETYPE > &particle)
Vector< T, PARTICLETYPE::d > getSurfaceNormal(Particle< T, PARTICLETYPE > particle)
void setContactMaterial(Particle< T, PARTICLETYPE > particle, unsigned material)
Vector< T, 2 > getAdhesion(Particle< T, PARTICLETYPE > particle)
void setTorque(Particle< T, PARTICLETYPE > particle, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > torque)
ADf< T, DIM > fmod(const ADf< T, DIM > &a, const ADf< T, DIM > &b)
Definition aDiff.h:703
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
Top level namespace for all of OpenLB.
std::conditional_t< D==2, SmoothIndicatorF2D< T, T, PARTICLE >, SmoothIndicatorF3D< T, T, PARTICLE > > SmoothIndicatorF
Definition aliases.h:278
Converts dimensions by deriving from given cartesian dimension D.