OpenLB 1.8.1
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){
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>
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>
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){
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>
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){
166}
167
169template<typename PARTICLETYPE>
170constexpr bool providesMassOrDensity()
171{
172 using namespace descriptors;
174}
175template<typename T, typename PARTICLETYPE>
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){
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>
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>
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){
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){
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>
251
253template<typename PARTICLETYPE>
255{
256 using namespace descriptors;
257 return PARTICLETYPE::template providesNested<PHYSPROPERTIES,MOFI>();
258}
259template<typename T, typename PARTICLETYPE>
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){
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>
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){
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>
311
313template<typename PARTICLETYPE>
315{
316 using namespace descriptors;
317 return PARTICLETYPE::template providesNested<DYNBEHAVIOUR,COMPUTE_CONTACT>();
318}
319template<typename T, typename PARTICLETYPE>
323
325template<typename PARTICLETYPE>
327{
328 using namespace descriptors;
329 return PARTICLETYPE::template providesNested<SURFACE,ROT_MATRIX>();
330}
331template<typename T, typename PARTICLETYPE>
335
337template<typename PARTICLETYPE>
338constexpr bool providesSurface()
339{
340 using namespace descriptors;
341 return PARTICLETYPE::template providesNested<SURFACE>();
342}
343template<typename T, typename 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>
360
362template<typename PARTICLETYPE>
364{
365 using namespace descriptors;
366 return PARTICLETYPE::template providesNested<PARALLELIZATION>();
367}
368template<typename T, typename PARTICLETYPE>
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>
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>
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>
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>
416
417template<typename PARTICLETYPE>
419{
420 using namespace descriptors;
421 return PARTICLETYPE::template providesNested<MOBILITY,ACCELERATION_STRD>();
422}
423template<typename T, typename PARTICLETYPE>
427
428template<typename PARTICLETYPE>
430{
431 using namespace descriptors;
432 return PARTICLETYPE::template providesNested<MOBILITY,ANG_ACC_STRD>();
433}
434template<typename T, typename PARTICLETYPE>
438
439template<typename PARTICLETYPE>
441{
442 using namespace descriptors;
443 return PARTICLETYPE::template providesNested<NUMERICPROPERTIES,ENLARGEMENT_FOR_CONTACT>();
444}
445template<typename T, typename PARTICLETYPE>
449
450template<typename PARTICLETYPE>
451constexpr bool providesIsInContact()
452{
453 using namespace descriptors;
454 return PARTICLETYPE::template providesNested<NUMERICPROPERTIES,IS_IN_CONTACT>();
455}
456template<typename T, typename PARTICLETYPE>
460
461template<typename PARTICLETYPE>
463{
464 using namespace descriptors;
465 return PARTICLETYPE::template providesNested<MECHPROPERTIES,MATERIAL>();
466}
467template<typename T, typename PARTICLETYPE>
471
472template<typename PARTICLETYPE>
473constexpr bool is2D()
474{
475 return (PARTICLETYPE::d==2);
476}
477template<typename T, typename PARTICLETYPE>
478constexpr bool is2D(Particle<T,PARTICLETYPE>& particle){
479 return is2D<PARTICLETYPE>();
480}
481
482template<typename PARTICLETYPE>
483constexpr bool is3D()
484{
485 return (PARTICLETYPE::d==3);
486}
487template<typename T, typename PARTICLETYPE>
488constexpr bool is3D(Particle<T,PARTICLETYPE>& particle){
489 return is3D<PARTICLETYPE>();
490}
491
493
494template<typename T, typename PARTICLETYPE>
496{
497 using namespace descriptors;
498 constexpr unsigned D = PARTICLETYPE::d;
499 static_assert(providesPosition<PARTICLETYPE>(),
500 "Field GENERAL:POSITION has to be provided");
501 Vector<T,D> position( particle.template getField<GENERAL,POSITION>() );
502 return position;
503}
504
505template<bool ensureAngularBounds=false, typename T, typename PARTICLETYPE>
507{
508 using namespace descriptors;
510 static_assert(providesAngle<PARTICLETYPE>(), "Field SURFACE:ANGLE has to be provided");
511 Vector<T,Drot> angle( particle.template getField<SURFACE,ANGLE>() );
512 if constexpr (ensureAngularBounds){
513 for (unsigned iRot=0; iRot<Drot; ++iRot) {
514 angle[iRot] = util::fmod( angle[iRot], 2.*M_PI );
515 }
516 }
517 return angle;
518}
519
520template<typename T, typename PARTICLETYPE>
522{
523 using namespace descriptors;
525 static_assert(providesRotationMatrix<PARTICLETYPE>(), "Field SURFACE:ROT_MATRIX has to be provided");
526 Vector<T,DrotMat> rotationMatrix( particle.template getField<SURFACE,ROT_MATRIX>() );
527 return rotationMatrix;
528}
529
530template<unsigned dir=2, typename T, typename PARTICLETYPE>
532{
533 using namespace descriptors;
534 constexpr unsigned D = PARTICLETYPE::d;
535 auto rotationMatrix = getRotationMatrix( particle );
536 //Note: Convention here, positively pointing towards dir (default z-dir)
537 Vector<T,D> normal;
538 for (unsigned iDim=0; iDim<D; ++iDim) {
539 unsigned iMat = D*iDim+dir;
540 normal[iDim] = rotationMatrix[iMat];
541 }
542 return normal;
543}
544
545template<typename T, typename PARTICLETYPE>
547{
548 using namespace descriptors;
549 constexpr unsigned D = PARTICLETYPE::d;
550 static_assert(providesVelocity<PARTICLETYPE>(), "Field MOBILITY:VELOCITY has to be provided");
551 Vector<T,D> velocity( particle.template getField<MOBILITY,VELOCITY>() );
552 return velocity;
553}
554
555template<typename T, typename PARTICLETYPE>
557{
558 using namespace descriptors;
560 static_assert(providesAngVelocity<PARTICLETYPE>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
561 Vector<T,Drot> angVelocity( particle.template getField<MOBILITY,ANG_VELOCITY>() );
562 return angVelocity;
563}
564
565template<typename T, typename PARTICLETYPE>
567{
568 using namespace descriptors;
569 constexpr unsigned D = PARTICLETYPE::d;
570 static_assert(providesForce<PARTICLETYPE>(), "Field FORCING:FORCE has to be provided");
571 Vector<T,D> force( particle.template getField<FORCING,FORCE>() );
572 return force;
573}
574
575template<typename T, typename PARTICLETYPE>
577{
578 using namespace descriptors;
580 static_assert(providesTorque<PARTICLETYPE>(), "Field FORCING:TORQUE has to be provided");
581 Vector<T,Drot> torque( particle.template getField<FORCING,TORQUE>() );
582 return torque;
583}
584
585template<typename T, typename PARTICLETYPE>
587{
588 using namespace descriptors;
590 static_assert(providesMomentOfInertia<PARTICLETYPE>(), "Field PHYSPROPERTIES:MOFI has to be provided");
591 Vector<T,Drot> mofi( particle.template getField<PHYSPROPERTIES,MOFI>() );
592 return mofi;
593}
594
595// Consisting of normal and tangential adhesion component of particle.
596template<typename T, typename PARTICLETYPE>
598{
599 using namespace descriptors;
600
601 static_assert(providesAdhesion<PARTICLETYPE>(), "Field FORCING:ADHESION has to be provided");
602 Vector<T,2> adhesion( particle.template getField<FORCING,ADHESION>() );
603 return adhesion;
604}
605
606template<typename T, typename PARTICLETYPE>
608{
609 using namespace descriptors;
610 bool valid = true;
611 if constexpr(providesValid<PARTICLETYPE>()) {
612 valid = !particle.template getField<GENERAL,INVALID>();
613 }
614 return valid;
615}
616
617template<typename T, typename PARTICLETYPE>
619{
620 using namespace descriptors;
621 bool active = true;
622 if constexpr(providesActive<PARTICLETYPE>()) {
623 active = particle.template getField<DYNBEHAVIOUR,ACTIVE>();
624 }
625 return active;
626}
627
628//Get smooth indicator pointer
629template<typename T, typename PARTICLETYPE>
631{
632 using namespace descriptors;
633 static_assert(providesSmoothIndicator<PARTICLETYPE>(), "Field FORCING:SINDICATOR has to be provided");
634 auto sIndicatorPtr = particle.template getField<SURFACE,SINDICATOR>();
635 return sIndicatorPtr;
636}
637
638//Get radius
639template<typename T, typename PARTICLETYPE>
641{
642 using namespace descriptors;
643 T radius;
644 if constexpr (providesSmoothIndicator<PARTICLETYPE>() ) {
645 radius = getSmoothIndicatorPtr(particle)->getCircumRadius();
646 }
647 else if constexpr ( providesRadius<PARTICLETYPE>() ) {
648 radius = particle.template getField<PHYSPROPERTIES,RADIUS>();
649 }
650 else {
651 std::cerr << "ERROR: no Field found providing radius!" << std::endl;
652 }
653 return radius;
654}
655
658template<typename T, typename PARTICLETYPE>
659T getVolume( Particle<T,PARTICLETYPE> particle, [[maybe_unused]] T shapeFactor = T{1} )
660{
661 using namespace descriptors;
662 constexpr unsigned D = PARTICLETYPE::d;
663 T volume;
664 if constexpr(providesSurface(particle)) {
665 if constexpr (D == 3) {
666 volume = getSmoothIndicatorPtr(particle)->getVolume();
667 }
668 else {
669 volume = getSmoothIndicatorPtr(particle)->getArea();
670 }
671 }
672 else {
673 const T radius = getRadius(particle);
674 if constexpr(D == 3) {
675 volume = (4./3.) * M_PI * util::pow(radius, D);
676 }
677 else {
678 volume = M_PI * util::pow(radius, D);
679 }
680 volume *= shapeFactor;
681 }
682 return volume;
683}
684
685template<typename T, typename PARTICLETYPE>
686T getDensity( Particle<T,PARTICLETYPE> particle, [[maybe_unused]] T shapeFactor = T{1} )
687{
688 using namespace descriptors;
689 static_assert(providesMassOrDensity(particle),
690 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
691 T density;
692 // Always rather use the density field than the mass field
693 if constexpr(providesDensity(particle)) {
694 density = particle.template getField<PHYSPROPERTIES, DENSITY>();
695 }
696 else {
697 const T mass = particle.template getField<PHYSPROPERTIES, MASS>();
698 density = mass / getVolume(particle, shapeFactor);
699 }
700 return density;
701}
702
703template<typename T, typename PARTICLETYPE>
704T getMass( Particle<T,PARTICLETYPE> particle, [[maybe_unused]] T shapeFactor = T{1} )
705{
706 using namespace descriptors;
707 static_assert(providesMassOrDensity(particle),
708 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
709 T mass;
710 // Always rather use the mass field than the density field
711 if constexpr(providesMass(particle)) {
712 mass = particle.template getField<PHYSPROPERTIES, MASS>();
713 }
714 else {
715 const T density = particle.template getField<PHYSPROPERTIES, DENSITY>();
716 mass = density * getVolume(particle, shapeFactor);
717 }
718 return mass;
719}
720
721template<typename T, typename PARTICLETYPE>
723{
724 using namespace descriptors;
725
726 if(providesAccelerationStrd(particle)){
727 return particle.template getField<MOBILITY,ACCELERATION_STRD>();
728 }
729}
730
731template<typename T, typename PARTICLETYPE>
733{
734 using namespace descriptors;
735 static_assert(providesAccelerationStrd<PARTICLETYPE>(), "Field MOBILITY:ACCELERATION has to be provided");
736 if constexpr(providesAccelerationStrd(particle)) {
737 particle.template setField<MOBILITY, ACCELERATION_STRD>(acceleration);
738 }
739}
740
741template<typename T, typename PARTICLETYPE>
743{
744 using namespace descriptors;
745 constexpr unsigned D = PARTICLETYPE::d;
746
747 static_assert(providesForce<PARTICLETYPE>(), "Field FORCING:FORCE has to be provided");
748 static_assert(providesMass<PARTICLETYPE>(), "Field PHYSPROPERTIES:MASS has to be provided");
749
750 Vector<T,D> acceleration;
751 Vector<T,D> force = getForce(particle);
752 T mass = getMass(particle);
753 for (unsigned iDim=0; iDim<D; ++iDim) {
754 acceleration[iDim] = force[iDim] / mass;
755 }
756 return acceleration;
757}
758
759// no need for setAcceleration (non-std) as it is calculated from force and mass
760
761template<typename T, typename PARTICLETYPE>
763 Particle<T,PARTICLETYPE> particle )
764{
765 using namespace descriptors;
766
768 static_assert(providesTorque<PARTICLETYPE>(), "Field FORCING:TORQUE has to be provided");
769 static_assert(providesMomentOfInertia<PARTICLETYPE>(), "Field PHYSPROPERTIES:MOFI has to be provided");
770 Vector<T,Drot> angularAcceleration;
771 Vector<T,Drot> torque( getTorque(particle));
772 Vector<T,Drot> momentOfInertia( getMomentOfInertia(particle) );
773 if constexpr (PARTICLETYPE::d == 3 && providesRotationMatrix<PARTICLETYPE>()) {
774 const Matrix<T,3,3> rotationMatrix(getRotationMatrix(particle));
775 angularAcceleration = calcAngAcceleration3D( torque, momentOfInertia, rotationMatrix );
776 } else {
777 for (unsigned iRot=0; iRot<Drot; ++iRot) {
778 angularAcceleration[iRot] = torque[iRot] / momentOfInertia[iRot];
779 }
780 }
781 return angularAcceleration;
782}
783
784template<typename T, typename PARTICLETYPE>
786{
787 using namespace descriptors;
788
789 if(providesAngAccelerationStrd(particle)){
790 return particle.template getField<MOBILITY,ANG_ACC_STRD>();
791 }
792}
793
794//Get global id
795template<typename T, typename PARTICLETYPE>
797{
798 using namespace descriptors;
799 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
800 auto globalID = particle.template getField<PARALLELIZATION,ID>();
801 return globalID;
802}
803
804//Get globiC (e.g allowing for the determination, whether dealing with particle centre)
805template<typename T, typename PARTICLETYPE>
807{
808 using namespace descriptors;
809 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
810 auto globalIC = particle.template getField<PARALLELIZATION,IC>();
811 return globalIC;
812}
813
814//Get dynamics id
815template<typename T, typename PARTICLETYPE>
816unsigned short getDynamicsID( Particle<T,PARTICLETYPE>& particle )
817{
818 using namespace descriptors;
819 static_assert(providesDynamicsID<PARTICLETYPE>(),
820 "Field DYNBEHAVIOUR:DYNAMICS_ID has to be provided");
821 unsigned short dynamicsID = particle.template getField<DYNBEHAVIOUR,DYNAMICS_ID>();
822 return dynamicsID;
823}
824
825//Get detaching state
826template<typename T, typename PARTICLETYPE>
828{
829 using namespace descriptors;
830 static_assert(providesDetaching<PARTICLETYPE>(),
831 "Field DYNBEHAVIOUR:DETACHING has to be provided");
832 bool detaching = particle.template getField<DYNBEHAVIOUR,DETACHING>();
833 return detaching;
834 }
835
836//Get extent of cuboid surface
837//- throws error during static_cast, when assumption of cuboid shape is false
838template<typename T, typename PARTICLETYPE>
840{
841 using namespace descriptors;
842 constexpr unsigned D = PARTICLETYPE::d;
843 static_assert(providesSmoothIndicator<PARTICLETYPE>(), "Field FORCING:SINDICATOR has to be provided");
844 using SIndicatorType = std::conditional_t<
845 D == 2,
848 >;
849 //Retrieve surface indicator
850 auto sIndicatorPtr = getSmoothIndicatorPtr(particle);
851 auto sIndicatorCuboidPtr = static_cast<SIndicatorType*>(sIndicatorPtr);
852 auto& indicatorCuboid = sIndicatorCuboidPtr->getIndicator();
853 //Retrieve extent
854 if constexpr(D==2){
855 Vector<T,D> extent(
856 indicatorCuboid.getxLength(),
857 indicatorCuboid.getyLength()
858 );
859 return extent;
860 } else {
861 Vector<T,D> extent(
862 indicatorCuboid.getxLength(),
863 indicatorCuboid.getyLength(),
864 indicatorCuboid.getzLength()
865 );
866 return extent;
867 }
868}
869
870template<typename T, typename PARTICLETYPE>
872{
873 using namespace descriptors;
874 constexpr unsigned D = PARTICLETYPE::d;
875 static_assert(providesCORoffset<PARTICLETYPE>(), "Field SURFACE:COR_OFFSET has to be provided");
876 Vector<T,D> offsetCOR( particle.template getField<SURFACE,COR_OFFSET>() );
877 return offsetCOR;
878}
879
880template<typename T, typename PARTICLETYPE>
882{
883 using namespace descriptors;
884 constexpr unsigned D = PARTICLETYPE::d;
885 static_assert(providesElongation<PARTICLETYPE>(), "Field SURFACE:ELONGATION has to be provided");
886 Vector<T,D> elongation( particle.template getField<SURFACE,ELONGATION>() );
887 return elongation;
888}
889
890// Get particle enlargement for contact treatment
891template<typename T, typename PARTICLETYPE>
893{
894 using namespace descriptors;
896 return particle.template getField<NUMERICPROPERTIES,ENLARGEMENT_FOR_CONTACT>();
897 }
898 else {
899 return T{0.};
900 }
901
902 __builtin_unreachable();
903}
904
905template<typename T, typename PARTICLETYPE>
907{
908 using namespace descriptors;
909 static_assert(providesContactMaterial(particle),
910 "Field MECHPROPERTIES::MATERIAL has to be provided");
911 return particle.template getField<MECHPROPERTIES, MATERIAL>();
912}
913
915
916template<typename T, typename PARTICLETYPE>
917void setDensity( Particle<T,PARTICLETYPE> particle, T density, [[maybe_unused]] T shapeFactor = T{1} )
918{
919 using namespace descriptors;
920 static_assert(providesMassOrDensity(particle),
921 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
922
923 if constexpr(providesDensity(particle)) {
924 particle.template setField<PHYSPROPERTIES, DENSITY>(density);
925 }
926 if constexpr(providesMass(particle)) {
927 const T mass = density * getVolume(particle, shapeFactor);
928 particle.template setField<PHYSPROPERTIES, MASS>(mass);
929 }
930}
931
932template<typename T, typename PARTICLETYPE>
933void setMass( Particle<T,PARTICLETYPE> particle, T mass, [[maybe_unused]] T shapeFactor = T{1} )
934{
935 using namespace descriptors;
936 static_assert(providesMassOrDensity(particle),
937 "Field PHYSPROPERTIES:MASS or PHYSPROPERTIES:DENSITY has to be provided");
938
939 if constexpr(providesMass(particle)) {
940 particle.template setField<PHYSPROPERTIES, MASS>(mass);
941 }
942 if constexpr(providesDensity(particle)){
943 const T density = mass / getVolume(particle, shapeFactor);
944 particle.template setField<PHYSPROPERTIES, DENSITY>(density);
945 }
946}
947
948template<typename T, typename PARTICLETYPE>
950{
951 using namespace descriptors;
952 static_assert(providesPosition(particle),
953 "Field GENERAL:POSITION has to be provided");
954 particle.template setField<GENERAL, POSITION>(position);
955}
956
957template<typename T, typename PARTICLETYPE>
958void setContactMaterial( Particle<T,PARTICLETYPE> particle, unsigned material )
959{
960 using namespace descriptors;
961 static_assert(providesContactMaterial(particle),
962 "Field MECHPROPERTIES::MATERIAL has to be provided");
963 particle.template setField<MECHPROPERTIES, MATERIAL>(material);
964}
965
966template<typename T, typename PARTICLETYPE>
968{
969 using namespace descriptors;
970 static_assert(providesAngle<PARTICLETYPE>(), "Field SURFACE:ANGLE has to be provided");
971 particle.template setField<SURFACE, ANGLE>(utilities::dimensions::convert<
972 PARTICLETYPE::d>::serialize_rotation(angle));
973}
974
975template<typename T, typename PARTICLETYPE>
977{
978 using namespace descriptors;
979 static_assert(providesRotationMatrix<PARTICLETYPE>(), "Field SURFACE:ROT_MATRIX has to be provided");
980 particle.template setField<SURFACE,ROT_MATRIX>(rotMatrix);
981}
982
983template<typename T, typename PARTICLETYPE>
985{
986 using namespace descriptors;
987 static_assert(providesVelocity<PARTICLETYPE>(), "Field MOBILITY:VELOCITY has to be provided");
988 particle.template setField<MOBILITY,VELOCITY>(velocity);
989}
990
991template<typename T, typename PARTICLETYPE>
993{
994 using namespace descriptors;
995 static_assert(providesAngVelocity<PARTICLETYPE>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
996 particle.template setField<MOBILITY,ANG_VELOCITY>(utilities::dimensions::convert<
997 PARTICLETYPE::d>::serialize_rotation(angVelocity));
998}
999
1000template<typename T, typename PARTICLETYPE>
1002{
1003 using namespace descriptors;
1004 static_assert(providesAngAccelerationStrd<PARTICLETYPE>(), "Field MOBILITY:ANG_ACC_STRD has to be provided");
1005 particle.template setField<MOBILITY,ANG_ACC_STRD>(utilities::dimensions::convert<
1006 PARTICLETYPE::d>::serialize_rotation(angAcceleration));
1007}
1008
1009// no need for setAngAcceleration (non-strd) as it is calculated from torque and moment of inertia
1010
1011template<typename T, typename PARTICLETYPE>
1013{
1014 using namespace descriptors;
1015 static_assert(providesForce<PARTICLETYPE>(), "Field FORCING:FORCE has to be provided");
1016 particle.template setField<FORCING,FORCE>(force);
1017}
1018
1019template<typename T, typename PARTICLETYPE>
1021{
1022 using namespace descriptors;
1023 static_assert(providesTorque<PARTICLETYPE>(), "Field FORCING:TORQUE has to be provided");
1024 particle.template setField<FORCING,TORQUE>(utilities::dimensions::convert<
1025 PARTICLETYPE::d>::serialize_rotation(torque));
1026}
1027
1028template<typename T, typename PARTICLETYPE>
1030{
1031 using namespace descriptors;
1032 static_assert(providesMomentOfInertia<PARTICLETYPE>(), "Field PHYSPROPERTIES:MOFI has to be provided");
1033 particle.template setField<PHYSPROPERTIES,MOFI>(utilities::dimensions::convert<
1034 PARTICLETYPE::d>::serialize_rotation(mofi));
1035}
1036
1037// Consisting of normal and tangential adhesion component of particle.
1038template<typename T, typename PARTICLETYPE>
1040{
1041 using namespace descriptors;
1042 static_assert(providesAdhesion<PARTICLETYPE>(), "Field FORCING:ADHESION has to be provided");
1043 particle.template setField<FORCING,ADHESION>(adhesion);
1044}
1045
1046template<typename T, typename PARTICLETYPE>
1047void setInvalid( Particle<T,PARTICLETYPE> particle, bool value=true )
1048{
1049 using namespace descriptors;
1050 static_assert(providesInvalid<PARTICLETYPE>(), "Field GENERAL:INVALID has to be provided");
1051 particle.template setField<GENERAL,INVALID>( value );
1052}
1053
1054template<typename T, typename PARTICLETYPE>
1055void setValid( Particle<T,PARTICLETYPE> particle, bool value=true )
1056{
1057 setInvalid(particle, !value);
1058}
1059
1060template<typename T, typename PARTICLETYPE>
1061void setActive( Particle<T,PARTICLETYPE> particle, bool value=true)
1062{
1063 using namespace descriptors;
1064 static_assert(providesActive<PARTICLETYPE>(), "Field DYNBEHAVIOUR:ACTIVE has to be provided");
1065 particle.template setField<DYNBEHAVIOUR,ACTIVE>( value );
1066}
1067
1068template<typename T, typename PARTICLETYPE>
1069void setInactive( Particle<T,PARTICLETYPE> particle, bool value=true)
1070{
1071 setActive(particle, !value);
1072}
1073
1074//Set smooth indicator pointer
1075template<typename T, typename PARTICLETYPE>
1078{
1079 using namespace descriptors;
1080 static_assert(providesSmoothIndicator<PARTICLETYPE>(), "Field FORCING:SINDICATOR has to be provided");
1081 particle.template setField<SURFACE,SINDICATOR>(sindicator);
1082}
1083
1084//Set radius
1085template<typename T, typename PARTICLETYPE>
1086void setRadius( Particle<T,PARTICLETYPE>& particle, T radius )
1087{
1088 using namespace descriptors;
1089 static_assert(providesRadius<PARTICLETYPE>(), "Field PHYSPROPERTIES:RADIUS has to be provided");
1090 particle.template setField<PHYSPROPERTIES,RADIUS>(radius);
1091}
1092
1093template<typename T, typename PARTICLETYPE>
1094void setGlobalID( Particle<T,PARTICLETYPE> particle, std::size_t id )
1095{
1096 using namespace descriptors;
1097 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
1098 particle.template setField<PARALLELIZATION,ID>(id);
1099}
1100
1101template<typename T, typename PARTICLETYPE>
1103{
1104 using namespace descriptors;
1105 static_assert(providesID<PARTICLETYPE>(), "Field PARALLELIZATION:ID has to be provided");
1106 particle.template setField<PARALLELIZATION,IC>(id);
1107}
1108
1109template<typename T, typename PARTICLETYPE>
1110void setDynamicsID( Particle<T,PARTICLETYPE>& particle, unsigned short dynamicsID )
1111{
1112 using namespace descriptors;
1113 static_assert(providesDynamicsID<PARTICLETYPE>(),
1114 "Field DYNBEHAVIOUR:DYNAMICS_ID has to be provided");
1115 particle.template setField<DYNBEHAVIOUR,DYNAMICS_ID>(dynamicsID);
1116}
1117
1118template<typename T, typename PARTICLETYPE>
1119void setDetaching( Particle<T,PARTICLETYPE>& particle, bool value)
1120{
1121 using namespace descriptors;
1122 static_assert(providesDetaching<PARTICLETYPE>(),
1123 "Field DYNBEHAVIOUR:DETACHING has to be provided");
1124 particle.template setField<DYNBEHAVIOUR,DETACHING>(value);
1125}
1126
1127template<typename T, typename PARTICLETYPE>
1129{
1130 using namespace descriptors;
1131 static_assert(providesCORoffset<PARTICLETYPE>(), "Field SURFACE:COR_OFFSET has to be provided");
1132 particle.template setField<SURFACE,COR_OFFSET>(offsetCOR);
1133}
1134
1135template<typename T, typename PARTICLETYPE>
1137{
1138 using namespace descriptors;
1139 static_assert(providesElongation<PARTICLETYPE>(), "Field SURFACE:ELONGATION has to be provided");
1140 particle.template setField<SURFACE,ELONGATION>(elongation);
1141}
1142
1143template<typename T, typename PARTICLETYPE>
1145{
1146 using namespace descriptors;
1147 static_assert(access::providesEnlargementForContactTreatment<PARTICLETYPE>(), "Field NUMERICPROPERTIES:ENLARGEMENT_FOR_CONTACT has to be provided");
1148 particle.template setField<NUMERICPROPERTIES, ENLARGEMENT_FOR_CONTACT>(value);
1149}
1150
1152template<typename T, typename PARTICLETYPE>
1154{
1155 using namespace descriptors;
1156
1157 // if the field is not provided, return true by default
1158 if constexpr(!providesComputeMotion<PARTICLETYPE>()) {
1159 return true;
1160 }
1161 else {
1162 return particle.template getField<DYNBEHAVIOUR,COMPUTE_MOTION>();
1163 }
1164
1165 __builtin_unreachable();
1166}
1167
1169template<typename T, typename PARTICLETYPE>
1171{
1172 using namespace descriptors;
1173
1174 // if the field is not provided, return true by default
1175 // (meaning that the contact forces are computed and applied to the force field)
1176 if constexpr(!providesComputeContact<PARTICLETYPE>()) {
1177 return true;
1178 }
1179 else {
1180 return particle.template getField<DYNBEHAVIOUR,COMPUTE_CONTACT>();
1181 }
1182
1183 __builtin_unreachable();
1184}
1185
1187template<typename T, typename PARTICLETYPE>
1189 Particle<T,PARTICLETYPE>& particleB)
1190{
1191 return (isContactComputationEnabled(particleA) || isContactComputationEnabled(particleB));
1192}
1193
1194template<typename T, typename PARTICLETYPE>
1195void enableMotionComputation(Particle<T, PARTICLETYPE>& particle, bool value = true)
1196{
1197 using namespace descriptors;
1198 static_assert(providesComputeMotion<PARTICLETYPE>(), "Field DYNBEHAVIOUR:COMPUTE_MOTION has to be provided");
1199 particle.template setField<DYNBEHAVIOUR, COMPUTE_MOTION>(value);
1200}
1201
1202template<typename T, typename PARTICLETYPE>
1203void enableContactComputation(Particle<T, PARTICLETYPE>& particle, bool value = true)
1204{
1205 using namespace descriptors;
1206 static_assert(providesComputeContact<PARTICLETYPE>(), "Field DYNBEHAVIOUR:COMPUTE_CONTACT has to be provided");
1207 particle.template setField<DYNBEHAVIOUR, COMPUTE_CONTACT>(value);
1208}
1209
1210template<typename T, typename PARTICLETYPE>
1211void disableMotionComputation(Particle<T, PARTICLETYPE>& particle, bool value = true)
1212{
1213 enableMotionComputation(particle, !value);
1214}
1215
1216template<typename T, typename PARTICLETYPE>
1218{
1219 enableContactComputation(particle, !value);
1220}
1221
1222template<typename T, typename PARTICLETYPE>
1224{
1225 if constexpr(providesVelocity(particle)){
1227 }
1228
1229 if constexpr(providesAccelerationStrd(particle)){
1231 }
1232
1233
1234 if constexpr(providesAngVelocity(particle)){
1236 }
1237
1238 if constexpr(providesAngAccelerationStrd(particle)){
1240 }
1241}
1242
1243} //namespace access
1244
1245} //namespace particles
1246
1247} //namespace olb
1248
1249
1250
1251
1252#endif
#define M_PI
Matrix with a defined number of ROWS and columns (COLS)
Definition matrix.h:33
constexpr Matrix< T, COLS, ROWS > transpose() const
Definition matrix.h:127
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.
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 providesIsInContact()
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
Expr pow(Expr base, Expr exp)
Definition expr.cpp:235
Top level namespace for all of OpenLB.
std::conditional_t< D==2, SmoothIndicatorF2D< T, T, PARTICLE >, SmoothIndicatorF3D< T, T, PARTICLE > > SmoothIndicatorF
Definition aliases.h:267
Converts dimensions by deriving from given cartesian dimension D.