OpenLB 1.8.1
Loading...
Searching...
No Matches
particleDynamicsBase.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Nicolas Hafen, Mathias J. Krause
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef PARTICLE_DYNAMICS_BASE_HH
25#define PARTICLE_DYNAMICS_BASE_HH
26
27
28namespace olb {
29
30namespace particles {
31
32namespace dynamics {
33
34template <typename T, typename PARTICLETYPE>
36{
37 return _name;
38}
39
40template <typename T, typename PARTICLETYPE>
42{
43 return _name;
44}
45
46
47template<typename T, typename PARTICLETYPE>
49{
50 this->getName() = "NoParticleDynamics";
51}
52
53template<typename T, typename PARTICLETYPE>
57
58
59
60template<typename T, typename PARTICLETYPE, typename PCONDITION>
66template<typename T, typename PARTICLETYPE, typename PCONDITION>
68 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
69{
70 using namespace particles::access;
71 //Check for particle condition
73 //Calculate acceleration
74 auto acceleration = getAcceleration( particle );
75 //Check for angular components
76 if constexpr ( providesAngle<PARTICLETYPE>() ) {
77 //Calculate angular acceleration
78 auto angularAcceleration = getAngAcceleration( particle );
79 //Verlet algorithm
81 particle, timeStepSize, acceleration, angularAcceleration );
82 //Check if rotation matrix provided
83 if constexpr ( providesRotationMatrix<PARTICLETYPE>() ) {
84 //Update rotation matrix
85 updateRotationMatrix( particle );
86 }
87 }
88 else {
89 //Verlet algorithm without rotation
91 timeStepSize, timeStepSize*timeStepSize, acceleration );
92 }
93 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
94}
95
96
97template<typename T, typename PARTICLETYPE, typename PCONDITION>
102
103template<typename T, typename PARTICLETYPE, typename PCONDITION>
105 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
106{
107 using namespace particles::access;
108 //Check for particle condition
110 //Calculate acceleration
111 auto acceleration = getAcceleration( particle );
112 //Verlet algorithm without rotation
114 particle, timeStepSize, timeStepSize*timeStepSize, acceleration );
115 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
116}
117
118
119template<typename T, typename PARTICLETYPE, typename PCONDITION>
124
125template<typename T, typename PARTICLETYPE, typename PCONDITION>
127 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
128{
129 using namespace particles::access;
130 //Check for particle condition
132 //Calculate angular acceleration
133 auto angularAcceleration = getAngAcceleration( particle );
134 //Verlet algorithm
136 particle, timeStepSize, timeStepSize*timeStepSize, angularAcceleration );
137 //Check if rotation matrix provided
138 if constexpr ( providesRotationMatrix<PARTICLETYPE>() ) {
139 //Update rotation matrix
140 updateRotationMatrix( particle );
141 }
142 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
143}
144
145template<typename T, typename PARTICLETYPE, typename PCONDITION>
147{
148 _angVel = angVel;
149 this->getName() = "VerletParticleDynamicsRotor";
150}
151
152template<typename T, typename PARTICLETYPE, typename PCONDITION>
154 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
155{
156 using namespace particles::access;
157 //Check for particle condition
159 //Verlet algorithm
161 particle, timeStepSize, _angVel );
162 //Check if rotation matrix provided
163 if constexpr ( providesRotationMatrix<PARTICLETYPE>() ) {
164 //Update rotation matrix
165 updateRotationMatrix( particle );
166 }
167 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
168}
169
170
171template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
174 SolidBoundary<T,PARTICLETYPE::d>& solidBoundary )
175 : _solidBoundary(solidBoundary)
176{
177 this->getName() = "VerletParticleDynamicsVelocityWallReflection";
178}
179
180
181template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
183 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
184{
185 //Execute process of VerletParticleDynamcis
187 //Apply wall reflection
189}
190
191
192template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
195 SolidBoundary<T,PARTICLETYPE::d>& solidBoundary )
196 : _solidBoundary(solidBoundary)
197{
198 this->getName() = "VerletParticleDynamicsWallCapture";
199}
200
201
202template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
204 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
205{
206 //Execute process of VerletParticleDynamcis
208 //Apply wall capture
209 boundaries::wallCapture<useCubicBounds>(particle, _solidBoundary);
210}
211
212
213template<typename T, typename PARTICLETYPE, typename PCONDITION>
216 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> materialIndicator )
217 : _materialIndicator(materialIndicator)
218{
219 this->getName() = "VerletParticleDynamicsMaterialCapture";
220}
221
222
223template<typename T, typename PARTICLETYPE, typename PCONDITION>
225 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
226{
227 //Execute process of VerletParticleDynamcis
229 //Apply material capture
230 boundaries::materialCapture(particle, *_materialIndicator);
231}
232
233
234template<typename T, typename PARTICLETYPE, typename PCONDITION>
238 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> materialIndicator )
239 : _solidBoundary(solidBoundary), _materialIndicator(materialIndicator)
240{
241 this->getName() = "VerletParticleDynamicsMaterialAwareWallCapture";
242}
243
244
245template<typename T, typename PARTICLETYPE, typename PCONDITION>
247 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
248{
249 //Execute process of VerletParticleDynamcis
251 //Apply wall capture
252 boundaries::wallCaptureMaterialAware(particle, _solidBoundary, *_materialIndicator);
253}
254
255
256template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
259 SolidBoundary<T,PARTICLETYPE::d>& solidBoundary )
260 : _solidBoundary(solidBoundary)
261{
262 this->getName() = "VerletParticleDynamicsEscape";
263}
264
265
266template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
268 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
269{
270 //Execute process of VerletParticleDynamcis
272 //Apply escape boundary
273 boundaries::escape<useCubicBounds>(particle, _solidBoundary);
275
277template<typename T, typename PARTICLETYPE, typename PCONDITION>
280 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> materialIndicator )
281 : _materialIndicator(materialIndicator)
282{
283 this->getName() = "VerletParticleDynamicsMaterialEscape";
284}
285
286
287template<typename T, typename PARTICLETYPE, typename PCONDITION>
289 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
290{
291 //Execute process of VerletParticleDynamcis
293 //Apply material escape
294 boundaries::materialEscape(particle, *_materialIndicator);
295}
296
297
298template<typename T, typename PARTICLETYPE, typename PCONDITION>
302 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> materialIndicator )
303 : _solidBoundary(solidBoundary), _materialIndicator(materialIndicator)
304{
305 this->getName() = "VerletParticleDynamicsMaterialAwareEscape";
306}
307
308
309template<typename T, typename PARTICLETYPE, typename PCONDITION>
311 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
312{
313 //Execute process of VerletParticleDynamcis
315 //Apply escape boundary
316 boundaries::escapeMaterialAware(particle, _solidBoundary, *_materialIndicator);
317}
318
319
320
321template<typename T, typename PARTICLETYPE, typename PCONDITION>
324 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> captureMaterialIndicator,
325 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> escapeMaterialIndicator )
326 : _captureMaterialIndicator(captureMaterialIndicator),
327 _escapeMaterialIndicator(escapeMaterialIndicator)
328{
329 this->getName() = "VerletParticleDynamicsMaterialCaptureAndEscape";
330}
331
332
333template<typename T, typename PARTICLETYPE, typename PCONDITION>
335 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
336{
337 //Execute process of VerletParticleDynamcis
339 //Apply material escape
340 boundaries::materialCaptureAndEscape(particle, *_captureMaterialIndicator,
341 *_escapeMaterialIndicator);
342}
344
345template<typename T, typename PARTICLETYPE, typename PCONDITION>
349 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> captureMaterialIndicator,
350 std::shared_ptr<SuperIndicatorMaterial<T,PARTICLETYPE::d>> escapeMaterialIndicator )
351 : _solidBoundary(solidBoundary),
352 _captureMaterialIndicator(captureMaterialIndicator),
353 _escapeMaterialIndicator(escapeMaterialIndicator)
355 this->getName() = "VerletParticleDynamicsMaterialAwareWallCaptureAndEscape";
357
358
359template<typename T, typename PARTICLETYPE, typename PCONDITION>
361 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
362{
363 //Execute process of VerletParticleDynamcis
365 //Apply escape boundary
366 boundaries::wallCaptureAndEscapeMaterialAware(particle, _solidBoundary,
367 *_captureMaterialIndicator, *_escapeMaterialIndicator);
368}
369
370
371
372template<typename T, typename PARTICLETYPE>
374 SolidBoundary<T,PARTICLETYPE::d>& solidBoundary, Vector<T,PARTICLETYPE::d>& mainFlowDirection,
375 T tiltThreshold )
376 : _solidBoundary(solidBoundary), _mainFlowDirection(mainFlowDirection), _tiltThreshold(tiltThreshold)
377{
378 this->getName() = "ParticleDetachmentDynamics";
379 static_assert(PARTICLETYPE::template providesNested<descriptors::SURFACE,descriptors::ANGLE>(),
380 "Field SURFACE:ANGLE has to be provided");
381 static_assert(PARTICLETYPE::template providesNested<descriptors::DYNBEHAVIOUR,descriptors::DETACHING>(),
382 "Field DYNBEHAVIOUR:DETACHING has to be provided");
383}
384
385template<typename T, typename PARTICLETYPE>
387 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
388{
389 using namespace particles::access;
390 using namespace descriptors;
391
392 //Check for valid particles condition
394 //Check current dynamic state
395 bool detaching = isDetaching( particle );
396 //State: Normal motion
397 if (!detaching){
398 //Execute process of VerletParticleDynamcis (valid, not detaching, active)
400 ::process(particle,timeStepSize);
401 }
402 //State: Detaching
403 else{
404 //Check adhesion threshold (set active, if passed once)
405 bool isAdhering = interaction::checkAdhesion( _solidBoundary, _mainFlowDirection, particle );
406 //Perform detachment dynamics (valid, detaching, adhering)
407 if (!isAdhering){
408 //Calculate angular acceleration
409 auto angularAcceleration = getAngAcceleration( particle );
410 //Verlet algorithm
412 particle, timeStepSize, timeStepSize*timeStepSize, angularAcceleration );
413 //Check if rotation matrix provided and update
414 if constexpr ( providesRotationMatrix<PARTICLETYPE>() ) {
415 updateRotationMatrix( particle );
416 }
417 //Handle detachment from surface
418 interaction::handleDetachment( _solidBoundary, _mainFlowDirection, particle );
419 //Reevaluate state: Check, whether state has to be changed (e.g. detachment finished)
420 interaction::evaluateDetachmentState( _solidBoundary, particle, _tiltThreshold );
421 } //if (!isAdhering)
422 }
423 }); //doWhenMeetingCondition<T,PARTICLETYPE,conditions::valid_particles>
424}
425
426
427
428
429
430//TODO: REWORK FOLLOWING DYNAMICS ACCORDING TO OBOVE ONES
431
432
433
434//TODO: remove for release
435//TODO: rework according to CubicBoundsCheck
436template<typename T, typename PARTICLETYPE>
438 PhysR<T,PARTICLETYPE::d>& domainMin,
439 PhysR<T,PARTICLETYPE::d>& domainMax
440)
441 : _domainMin(domainMin), _domainMax(domainMax)
442{
443 this->getName() = "VerletParticleDynamicsCubicBoundsAdhesion";
444}
445
446
455//TODO: remove for release
456template<typename T, typename PARTICLETYPE>
458 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
459{
460 using namespace particles::access;
461 //Calculate acceleration
462 auto acceleration = getAcceleration( particle );
463 //Note position before calculating movement (and store in dynStatePre)
464 DynState<T,PARTICLETYPE> dynStatePre( getPosition(particle) );
465
466 //Check for angular components
467 if constexpr ( providesAngle<PARTICLETYPE>() ) {
468 //Calculate angular acceleration
469 auto angularAcceleration = getAngAcceleration( particle );
470 //Note angle before calculating rotation (and store in dynStatePre)
471 dynStatePre.angle = getAngle( particle );
472 //Verlet algorithm
474 particle, timeStepSize, acceleration, angularAcceleration );
475 } else {
476 //Verlet algorithm
478 particle, timeStepSize, acceleration);
479 }
480
481 //Retrieve force and adhesion threshold
482 auto force = getForce( particle );
483 auto adhesionThreshold = getAdhesion( particle );
484
485 //Check domain contact and potentially reset to positionPre and velocity zero
486 bool adhesionSuperior = false;
487 doAtCubicBoundPenetration( particle, _domainMin, _domainMax,
488 [&](unsigned iDim, Vector<T,PARTICLETYPE::d>& normal, T distToBound ) {
489 //Reset (only!) penetration direction
490 resetDirection( particle, dynStatePre.position, iDim );
491 //Check adhesion in normal direction
492 //-only consider contributions pointing from the surface (normalForce > 0)
493 // to ensure, that pressing on particles does not release them
494 T normalForce = force[iDim]*normal[iDim];
495 if (normalForce > 0 && normalForce < adhesionThreshold[0] ){
496 adhesionSuperior = true;
497 }
498 //Check adhesion in all tangential directions
499 // - info: checks in both directions in both positive and negative direction
500 bool bothTangentalSuperior = true;
501 for (int iDimT=1; iDimT<PARTICLETYPE::d; ++iDimT) {
502 int jDim = (iDim+iDimT)%PARTICLETYPE::d;
503 if (std::abs(force[jDim]) >= adhesionThreshold[1]){ //Tangential direction (absolute)
504 bothTangentalSuperior = false;
505 }
506 }
507 //Combine normal and tangential evaluation
508 adhesionSuperior = adhesionSuperior || bothTangentalSuperior;
509 });
510
511 if constexpr ( providesAngle<PARTICLETYPE>() ) {
512 //Check whether adhesion is superior
513 if (adhesionSuperior){
514 resetMovement( particle, dynStatePre.position, dynStatePre.angle );
515 }
516 //Update rotation matrix
517 updateRotationMatrix( particle );
518 } else {
519 //Check whether adhesion is superior
520 if (adhesionSuperior){ resetMovement( particle, dynStatePre.position); }
521 }
522
523}
524
525
526//TODO: remove for release
527template<typename T, typename PARTICLETYPE, typename DEPOSITION_MODEL>
530 PhysR<T,PARTICLETYPE::d>& domainMin,
531 PhysR<T,PARTICLETYPE::d>& domainMax,
532 DEPOSITION_MODEL& depositionModel
533)
534 : _domainMin(domainMin), _domainMax(domainMax),
535 _depositionModel( depositionModel )
536{
537 this->getName() = "VerletParticleDynamicsCubicBoundsDeposition";
538}
539
540//TODO: remove for release
541template<typename T, typename PARTICLETYPE, typename DEPOSITION_MODEL>
543 ::process (Particle<T,PARTICLETYPE>& particle, T timeStepSize )
544{
545 using namespace particles::access;
546 static_assert( providesActive<PARTICLETYPE>(), "Field ACTIVE has to be provided");
547
548 //Check if active
549 if (particle.template getField<descriptors::DYNBEHAVIOUR,descriptors::ACTIVE>()) {
550
551 auto force = getForce( particle );
552 auto velocity = getVelocity( particle );
553
554 //Check domain contact and check deposition
555 bool deposition = false;
556 doAtCubicBoundPenetration( particle, _domainMin, _domainMax,
557 [&](unsigned iDim, Vector<T,PARTICLETYPE::d>& normal, T distToBound ) {
558 //Check deposition
559 deposition = deposition || _depositionModel.checkDeposition(velocity,normal);
560 //Wall contact treatment
561 if (!deposition) {
562 auto radius = getRadius( particle );
563 T penetrationDepth = -distToBound;
564 T velNormal = -normal[iDim]*velocity[iDim]; //Necessary for damping
565 T forceNormal = _depositionModel.contactForceSphereHalfSpaceDampened(
566 radius, penetrationDepth, velNormal );
567 force[iDim] = forceNormal*normal[iDim];
568 }
569 });
570 particle.template setField<descriptors::FORCING,descriptors::FORCE>( force );
571
572 //Run verlet or deactivate depending on deposition
573 if (!deposition) {
574 //Calculate acceleration
575 auto acceleration = getAcceleration( particle );
576 //Note position before calculating movement
577 auto positionPre = getPosition( particle );
578 //Check for angular components
579 if constexpr ( providesAngle<PARTICLETYPE>() ) {
580 //Calculate angular acceleration
581 auto angularAcceleration = getAngAcceleration( particle );
582 //Verlet algorithm
584 particle, timeStepSize, acceleration, angularAcceleration );
585 //Update rotation matrix
586 updateRotationMatrix( particle );
587 }
588 else {
589 //Verlet algorithm without angle
591 particle, timeStepSize, acceleration );
592 }
593 }
594 else {
595 particle.template setField<descriptors::DYNBEHAVIOUR,descriptors::ACTIVE>( false );
596 particle.template setField<descriptors::MOBILITY,descriptors::VELOCITY>( 0. );
597 particle.template setField<descriptors::MOBILITY,descriptors::ACCELERATION_STRD>( 0. );
598 if constexpr ( providesAngle<PARTICLETYPE>() ) {
599 particle.template setField<descriptors::MOBILITY,descriptors::ANG_VELOCITY>( 0. );
600 particle.template setField<descriptors::MOBILITY,descriptors::ANG_ACC_STRD>( 0. );
601 }
602 }
603 }
604}
605
606
607//this could be used for inner iteration to reduce computational costs when calling the signedDistance function for the particle deposition!
608//meaning not every inner iteration the wall particle distance and orientation is computed!
609#ifdef SIMPLE_DEPO
610extern int depo;
611#endif
612
613
614template<typename T, typename PARTICLETYPE, typename PCONDITION>
616{
617 this->getName() = "EulerParticleDynamics";
618}
619
620
621template<typename T, typename PARTICLETYPE, typename PCONDITION>
626
627template<typename T, typename PARTICLETYPE, typename PCONDITION>
629 : _periodic_direction(periodic_dierection)
630{
631 this->getName() = "EulerSpheroidParticleDynamicsPeriodic";
632}
633
634template<typename T, typename PARTICLETYPE, typename PCONDITION>
636 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
637{
638 using namespace particles::access;
639 //Check for particle condition
641 //Calculate acceleration
642 auto acceleration = getAcceleration( particle );
643 //Check for angular components
644 if constexpr ( providesAngle<PARTICLETYPE>() ) {
645 //Calculate angular acceleration
646 auto angularAcceleration = getAngAcceleration( particle );
647 //Euler algorithm
649 particle, timeStepSize, acceleration, angularAcceleration );
650 //Check if rotation matrix provided
651 if constexpr ( providesRotationMatrix<PARTICLETYPE>() ) {
652 //Update rotation matrix
653 updateRotationMatrix( particle );
654 }
655 }
656 else {
657 //Euler algorithm without rotation
659 timeStepSize, acceleration );
660 }
661 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
662}
663
664template<typename T, typename PARTICLETYPE, typename PCONDITION>
666 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
667{
668 using namespace particles::access;
669 //Check for particle condition
671 //Calculate acceleration
672 auto acceleration = getAcceleration( particle );
673using namespace olb::descriptors;
674Vector<T,4> quat = particle.template getField<NUMERICPROPERTIES,QUATERNION>();
675Vector<T,3> ang_vel =particle.template getField<NUMERICPROPERTIES, ANG_VELOCITY>();
676
677 eler::computeAngularVelocityLeapFrog(ang_vel, particle.template getField<FORCING,TORQUE>(), particle.template getField<NUMERICPROPERTIES,MOMENT_OF_INERTIA> (),timeStepSize);
678 //the RungeKutta scheme not suitable for non linear equations...
679 //eler::computeAngularVelocityRungeKutta(ang_vel, particle.template getField<FORCING,TORQUE>(), particle.template getField<NUMERICPROPERTIES,MOMENT_OF_INERTIA> (),timeStepSize);
680 //eler::computeAngularVelocity(ang_vel, particle.template getField<FORCING,TORQUE>(), particle.template getField<NUMERICPROPERTIES,MOMENT_OF_INERTIA> (),timeStepSize);
681 particle.template setField<NUMERICPROPERTIES,ANG_VELOCITY>(ang_vel);
682
683
685 timeStepSize, acceleration, _periodic_direction );
686
687 //eler::quaternionRotate(quat, timeStepSize, ang_vel);
688 //eler::quaternionRotateLeapFrog(quat, timeStepSize, ang_vel);
689 eler::quaternionRotateRungeKutta(quat, timeStepSize, ang_vel);
690 particle.template setField<NUMERICPROPERTIES,QUATERNION>(quat);
691 particle.template setField<NUMERICPROPERTIES,PARAQUATERNION> (eler::getParaquaternion(quat));
692 particle.template setField<NUMERICPROPERTIES,ROT_MATRIX>(eler::computeTransformMatrixFromEulQuat(quat));
693 particle.template setField<NUMERICPROPERTIES,ORIENTATION>(eler::rotate(eler::inverseTransformMatrix(particle.template getField<NUMERICPROPERTIES,ROT_MATRIX>()), Vector<T,3> (0.,0.,1.)));
694
695
696
697
698 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
699}
700
701template<typename T, typename PARTICLETYPE, typename PCONDITION>
703 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
704{
705 using namespace particles::access;
706 //Check for particle condition
708 //Calculate acceleration
709 auto acceleration = getAcceleration( particle );
710using namespace olb::descriptors;
711Vector<T,4> quat = particle.template getField<NUMERICPROPERTIES,QUATERNION>();
712Vector<T,3> ang_vel =particle.template getField<NUMERICPROPERTIES, ANG_VELOCITY>();
713
714 eler::computeAngularVelocityLeapFrog(ang_vel, particle.template getField<FORCING,TORQUE>(), particle.template getField<NUMERICPROPERTIES,MOMENT_OF_INERTIA> (),timeStepSize);
715 //the RungeKutta scheme not suitable for non linear equations...
716 //eler::computeAngularVelocityRungeKutta(ang_vel, particle.template getField<FORCING,TORQUE>(), particle.template getField<NUMERICPROPERTIES,MOMENT_OF_INERTIA> (),timeStepSize);
717 //eler::computeAngularVelocity(ang_vel, particle.template getField<FORCING,TORQUE>(), particle.template getField<NUMERICPROPERTIES,MOMENT_OF_INERTIA> (),timeStepSize);
718 particle.template setField<NUMERICPROPERTIES,ANG_VELOCITY>(ang_vel);
720 timeStepSize, acceleration );
721
722 //eler::quaternionRotate(quat, timeStepSize, ang_vel);
723 //eler::quaternionRotateLeapFrog(quat, timeStepSize, ang_vel);
724 eler::quaternionRotateRungeKutta(quat, timeStepSize, ang_vel);
725 particle.template setField<NUMERICPROPERTIES,QUATERNION>(quat);
726 particle.template setField<NUMERICPROPERTIES,PARAQUATERNION> (eler::getParaquaternion(quat));
727 particle.template setField<NUMERICPROPERTIES,ROT_MATRIX>(eler::computeTransformMatrixFromEulQuat(quat));
728 particle.template setField<NUMERICPROPERTIES,ORIENTATION>(eler::rotate(eler::inverseTransformMatrix(particle.template getField<NUMERICPROPERTIES,ROT_MATRIX>()), Vector<T,3> (0.,0.,1.)));
729
730
731
732
733 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
734}
735
736
737
738
739template<typename T, typename PARTICLETYPE, typename PCONDITION>
741 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
742{
743
744 //Execute process of eulerParticleDynamcis
746 //Apply wall capture
747 boundaries::wallCaptureMaterialAware(particle, _solidBoundary, _materialIndicator);
748
749}
750
751template<typename T, typename PARTICLETYPE, typename PCONDITION>
756 : _solidBoundary(solidBoundary), _materialIndicator(materialIndicator)
757{
758 this->getName() = "EulerParticleDynamicsMaterialAwareWallCapture";
759
760}
761
762
763
764
765template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
768 SolidBoundary<T,PARTICLETYPE::d>& solidBoundary )
769 : _solidBoundary(solidBoundary)
770{
771 this->getName() = "EulerSpheroidParticleDynamicsWallCapture";
772}
773
774template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
784
785
786template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
790 : _solidBoundary(solidBoundary), _materialIndicator(materialIndicator)
791{
792 this->getName() = "EulerSpheroidParticleDynamicsMaterialAwareWallCapture";
793}
794
795template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
797 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
798{
799
801
802 #ifdef SIMPLE_DEPO
803 if (depo==0)
804 {
805 boundaries::wallCaptureMaterialAwareSpheroidSubgrid(particle, _solidBoundary, _materialIndicator);
806 }
807#endif
808 #ifndef SIMPLE_DEPO
809 boundaries::wallCaptureMaterialAwareSpheroidSubgrid(particle, _solidBoundary, _materialIndicator);
810 #endif
811}
812
813
814template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
818 : EulerSpheroidParticleDynamicsPeriodic<T,PARTICLETYPE,PCONDITION>{direction}, _solidBoundary{solidBoundary}, _materialIndicator{materialIndicator}, _direction{direction}
819{
820 //EulerSpheroidParticleDynamicsPeriodic<T,PARTICLETYPE,PCONDITION>(direction);
821 this->getName() = "EulerSpheroidParticleDynamicsMaterialAwareWallCapture";
822}
823
824
825template<typename T, typename PARTICLETYPE, bool useCubicBounds, typename PCONDITION>
833
834
835
836
837
838template<typename T, typename PARTICLETYPE, typename PCONDITION>
844
845template<typename T, typename PARTICLETYPE, typename PCONDITION>
847 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
848{
849 using namespace particles::access;
850 //Check for particle condition
852 //Calculate acceleration
853 auto acceleration = getAcceleration( particle );
854 //Check for angular components
855 if constexpr ( providesAngle<PARTICLETYPE>() ) {
856 //Calculate angular acceleration
857 auto angularAcceleration = getAngAcceleration( particle );
858 //Euler algorithm
860 particle, timeStepSize, acceleration, angularAcceleration );
861 //Check if rotation matrix provided
862 if constexpr ( providesRotationMatrix<PARTICLETYPE>() ) {
863 //Update rotation matrix
864 updateRotationMatrix( particle );
865 }
866 }
867 else {
868 //Euler algorithm without rotation
869 particles::dynamics::analyticalTranslation( particle, acceleration,
870 timeStepSize, particle. template getField<descriptors::MOBILITY, descriptors::FLUIDVEL>());
871 }
872 }); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
873}
874
875template<typename T, typename PARTICLETYPE, typename PCONDITION>
878 : _solidBoundary(solidBoundary), _materialIndicator(materialIndicator)
879{
880 this->getName() = "AnalyticalParticleDynamicsTranslationOnlyMaterialAwareWallCapture";
881}
882
883template<typename T, typename PARTICLETYPE,typename PCONDITION>
885 Particle<T,PARTICLETYPE>& particle, T timeStepSize )
886{
887
889 boundaries::wallCaptureMaterialAware(particle, _solidBoundary, _materialIndicator); //doWhenMeetingCondition<T,PARTICLETYPE,PCONDITION>
890}
891
892
893
894
895} //namespace dynamics
896
897} //namespace particles
898
899} //namespace olb
900
901#endif
Plain old scalar vector.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
AnalyticalParticleDynamicsTranslationOnlyMaterialAwareWallCapture(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
EulerParticleDynamicsMaterialAwareWallCapture(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
EulerSpheroidParticleDynamicsMaterialAwareWallCapturePeriodic(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator, Vector< int, 3 > direction)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
EulerSpheroidParticleDynamicsMaterialAwareWallCapture(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
Standard dynamics for ELER particles with periodicity in given direction (infinite pipe flow applicat...
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
EulerSpheroidParticleDynamicsPeriodic(Vector< int, 3 > periodic_direction)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
EulerSpheroidParticleDynamicsWallCapture(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Processing step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
ParticleDetachmentDynamics(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, Vector< T, PARTICLETYPE::d > &mainFlowDirection, T tiltThreshold=0.3 *M_PI)
Constructor.
VerletParticleDynamicsCubicBoundsAdhesion(PhysR< T, PARTICLETYPE::d > &domainMin, PhysR< T, PARTICLETYPE::d > &domainMax)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
Velocity verlet particle dynamics with deposition modelling by checking domain bounds in cartesion di...
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsEscape(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
Constructor.
VerletParticleDynamicsMaterialAwareEscape(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > > materialIndicator)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsMaterialAwareWallCaptureAndEscape(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > > captureMaterialIndicator, std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > > escapeMaterialIndicator)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsMaterialAwareWallCapture(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > >)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsMaterialCaptureAndEscape(std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > > captureMaterialIndicator, std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > > escapeMaterialIndicator)
Constructor.
VerletParticleDynamicsMaterialCapture(std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > >)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsMaterialEscape(std::shared_ptr< SuperIndicatorMaterial< T, PARTICLETYPE::d > > materialIndicator)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsRotor(Vector< T, PARTICLETYPE::d > angVel)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsVelocityWallReflection(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
VerletParticleDynamicsWallCapture(SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
Constructor.
void process(Particle< T, PARTICLETYPE > &particle, T timeStepSize) override
Procesisng step.
Descriptors for the 2D and 3D lattices.
void materialCaptureAndEscape(Particle< T, PARTICLETYPE > &particle, SuperIndicatorMaterial< T, PARTICLETYPE::d > &captureMaterialIndicator, SuperIndicatorMaterial< T, PARTICLETYPE::d > &escapeMaterialIndicator)
Escape and capture based on material rather than SolidBoundary.
void wallCaptureMaterialAware(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Wall capture with material awareness.
void escapeMaterialAware(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Escape boundary with material awareness.
void materialEscape(Particle< T, PARTICLETYPE > &particle, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Escape boundary based on material rather than SolidBoundary.
void wallCaptureAndEscapeMaterialAware(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &captureMaterialIndicator, SuperIndicatorMaterial< T, PARTICLETYPE::d > &escapeMaterialIndicator)
Escape boundary with material awareness.
void velocityWallReflection(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, T coefficientOfRestitution=1.0)
Velocity wall reflection.
void wallCapture(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
Wall capture.
void materialCapture(Particle< T, PARTICLETYPE > &particle, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Wall capture based on material rather than SolidBoundary.
void escape(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
Escape.
void wallCaptureMaterialAwareSpheroidSubgrid(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, SuperIndicatorMaterial< T, PARTICLETYPE::d > &materialIndicator)
Wall capture with material awareness.
void wallCaptureSpheroidSubgrid(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary)
void eulerIntegration(Particle< T, PARTICLETYPE > &particle, T delTime, Vector< T, PARTICLETYPE::d > acceleration, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angularAcceleration)
void velocityVerletRotor(Particle< T, PARTICLETYPE > &particle, T delTime, Vector< T, PARTICLETYPE::d > angVel)
void resetMovement(Particle< T, PARTICLETYPE > &particle, Vector< T, PARTICLETYPE::d > positionPre, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > anglePre=Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation >(0.))
void velocityVerletTranslation(Particle< T, PARTICLETYPE > &particle, T delTime, T delTime2, Vector< T, PARTICLETYPE::d > acceleration)
void analyticalTranslation(Particle< T, PARTICLETYPE > &particle, Vector< T, PARTICLETYPE::d > acceleration, T delTime, Vector< T, PARTICLETYPE::d > fluid_vel)
std::conditional_t< PARTICLETYPE::template providesNested< descriptors::SURFACE, descriptors::ANGLE >(), ParticleDynamicStateAngle< T, PARTICLETYPE >, ParticleDynamicStateNoAngle< T, PARTICLETYPE > > DynState
void velocityVerletRotation(Particle< T, PARTICLETYPE > &particle, T delTime, T delTime2, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angularAcceleration)
void eulerIntegrationTranslation(Particle< T, PARTICLETYPE > &particle, T delTime, Vector< T, PARTICLETYPE::d > acceleration)
Euler integration.
void velocityVerletIntegration(Particle< T, PARTICLETYPE > &particle, T delTime, Vector< T, PARTICLETYPE::d > acceleration, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angularAcceleration)
void resetDirection(Particle< T, PARTICLETYPE > &particle, Vector< T, PARTICLETYPE::d > positionPre, int iDir)
void eulerIntegrationTranslationPeriodic(Particle< T, PARTICLETYPE > &particle, T delTime, Vector< T, PARTICLETYPE::d > acceleration, Vector< int, PARTICLETYPE::d > periodicity)
Euler integration.
void updateRotationMatrix(Particle< T, PARTICLETYPE > &particle)
void doAtCubicBoundPenetration(Particle< T, PARTICLETYPE > &particle, Vector< T, PARTICLETYPE::d > domainMin, Vector< T, PARTICLETYPE::d > domainMax, F boundTreatment)
Helper functions.
bool checkAdhesion(SolidBoundary< T, PARTICLETYPE::d > &wall, Vector< T, PARTICLETYPE::d > &mainFlowDirection, Particle< T, PARTICLETYPE > &particle)
Check adhesion and return true if still adhering.
void evaluateDetachmentState(SolidBoundary< T, PARTICLETYPE::d > &wall, Particle< T, PARTICLETYPE > &particle, T tiltThreshold=0.3 *M_PI)
void handleDetachment(SolidBoundary< T, PARTICLETYPE::d > &wall, Vector< T, PARTICLETYPE::d > &mainFlowDirection, Particle< T, PARTICLETYPE > &particle)
void doWhenMeetingCondition(Particle< T, PARTICLETYPE > &particle, F f)
Definition lambdaLoops.h:55
Top level namespace for all of OpenLB.
std::conditional_t< D==2, SuperIndicatorMaterial2D< T >, SuperIndicatorMaterial3D< T > > SuperIndicatorMaterial
Definition aliases.h:287
std::string getName(OperatorScope scope)
Returns human-readable name of scope.
std::string & getName()
read and write access to name