OpenLB 1.7
Loading...
Searching...
No Matches
particleMotionFunctions.h
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
25/* This file contains functions used for the calculation of particle related dynamics.
26 *
27*/
28
29#ifndef PARTICLE_MOTION_FUNCTIONS_H
30#define PARTICLE_MOTION_FUNCTIONS_H
31
32
33namespace olb {
34
35namespace particles {
36
37namespace dynamics {
38
40
41// Velocity verlet integration according to
42// Verlet1967 (https://doi.org/10.1103/PhysRev.159.98)
43// Swope1982 (https://doi.org/10.1063/1.442716)
44template<typename T, typename PARTICLETYPE>
45void velocityVerletTranslation( Particle<T,PARTICLETYPE>& particle, T delTime, T delTime2,
46 Vector<T,PARTICLETYPE::d> acceleration )
47{
48 using namespace descriptors;
49 constexpr unsigned D = PARTICLETYPE::d;
50 //Check field existence
51 static_assert(PARTICLETYPE::template providesNested<GENERAL,POSITION>(), "Field POSITION has to be provided");
52 static_assert(PARTICLETYPE::template providesNested<MOBILITY,VELOCITY>(), "Field VELOCITY has to be provided");
53 static_assert(PARTICLETYPE::template providesNested<MOBILITY,ACCELERATION_STRD>(), "Field ACCELERATION_STRD has to be provided");
54 //Calculate quantities
55 Vector<T,D> position( particle.template getField<GENERAL,POSITION>()
56 + particle.template getField<MOBILITY,VELOCITY>() * delTime
57 + (0.5 * particle.template getField<MOBILITY,ACCELERATION_STRD>() * delTime2) );
58 Vector<T,D> avgAcceleration( .5*(particle.template getField<MOBILITY,ACCELERATION_STRD>() + acceleration) );
59 Vector<T,D> velocity( particle.template getField<MOBILITY,VELOCITY>() + avgAcceleration * delTime );
60 //Update values
61 particle.template setField<GENERAL,POSITION>( position );
62 particle.template setField<MOBILITY,VELOCITY>( velocity );
63 particle.template setField<MOBILITY,ACCELERATION_STRD>( acceleration );
64}
65
66template<typename T, typename PARTICLETYPE>
67void velocityVerletRotation( Particle<T,PARTICLETYPE>& particle, T delTime, T delTime2,
69{
70 using namespace descriptors;
71 constexpr unsigned D = PARTICLETYPE::d;
72 constexpr unsigned Drot = utilities::dimensions::convert<D>::rotation;
73 //Check field existence
74 static_assert(PARTICLETYPE::template providesNested<SURFACE,ANGLE>(), "Field SURFACE:ANGLE has to be provided");
75 static_assert(PARTICLETYPE::template providesNested<MOBILITY,ANG_VELOCITY>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
76 static_assert(PARTICLETYPE::template providesNested<MOBILITY,ANG_ACC_STRD>(), "Field MOBILITY:ANG_ACC_STRD has to be provided");
77 //Calculate quantities
78 Vector<T,Drot> angle( particle.template getField<SURFACE,ANGLE>()
79 + particle.template getField<MOBILITY,ANG_VELOCITY>() * delTime
80 + (0.5 * particle.template getField<MOBILITY,ANG_ACC_STRD>() * delTime2) );
81 Vector<T,Drot> avgAngularAcceleration( .5*(particle.template getField<MOBILITY,ANG_ACC_STRD>() + angularAcceleration) );
82 Vector<T,Drot> angularVelocity( particle.template getField<MOBILITY,ANG_VELOCITY>() + avgAngularAcceleration * delTime );
83 //Treat full rotation
84 angle = util::fmod( angle, 2.*M_PI );
85 //Update values
86 particle.template setField<SURFACE,ANGLE>(
88 particle.template setField<MOBILITY,ANG_VELOCITY>(
90 particle.template setField<MOBILITY,ANG_ACC_STRD>(
92
93}
94
95template<typename T, typename PARTICLETYPE>
97{
98 using namespace descriptors;
99 constexpr unsigned D = PARTICLETYPE::d;
100 constexpr unsigned Drot = utilities::dimensions::convert<D>::rotation;
101 //Check field existence
102 static_assert(PARTICLETYPE::template providesNested<SURFACE,ANGLE>(), "Field SURFACE:ANGLE has to be provided");
103 static_assert(PARTICLETYPE::template providesNested<MOBILITY,ANG_VELOCITY>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
104 static_assert(PARTICLETYPE::template providesNested<MOBILITY,ANG_ACC_STRD>(), "Field MOBILITY:ANG_ACC_STRD has to be provided");
105 //Calculate quantities
106 Vector<T,Drot> angle( particle.template getField<SURFACE,ANGLE>() + angVel * delTime);
107 Vector<T,Drot> avgAngularAcceleration({0.});
108 Vector<T,Drot> angularVelocity( angVel );
109 //Treat full rotation
110 angle = util::fmod( angle, 2.*M_PI );
111 //Update values
112 particle.template setField<SURFACE,ANGLE>(
114 particle.template setField<MOBILITY,ANG_VELOCITY>(
116 particle.template setField<MOBILITY,ANG_ACC_STRD>(
118
119}
120
121template<typename T, typename PARTICLETYPE>
123 Vector<T,PARTICLETYPE::d> acceleration,
125{
126 //Calculate squared time step
127 T delTime2 = delTime*delTime;
128 //Calculate cartesian directions
129 velocityVerletTranslation( particle, delTime, delTime2, acceleration );
130 //Calculate rotational directions
131 if constexpr ( access::providesSurface<PARTICLETYPE>() ) {
132 velocityVerletRotation( particle, delTime, delTime2, angularAcceleration );
133 }
134}
135
136
137
138
139
141template<typename T, typename PARTICLETYPE>
143 Particle<T,PARTICLETYPE>& particle, T delTime,
144 Vector<T,PARTICLETYPE::d> acceleration )
145{
146 using namespace descriptors;
147 constexpr unsigned D = PARTICLETYPE::d;
148 //Check field existence
149 static_assert(PARTICLETYPE::template providesNested<GENERAL,POSITION>(), "Field POSITION has to be provided");
150 static_assert(PARTICLETYPE::template providesNested<MOBILITY,VELOCITY>(), "Field VELOCITY has to be provided");
151 //Calculate quantities
152 Vector<T,D> velocity( particle.template getField<MOBILITY,VELOCITY>() + acceleration * delTime );
153 Vector<T,D> position( particle.template getField<GENERAL,POSITION>() + velocity * delTime );
154 //Update values
155 particle.template setField<GENERAL,POSITION>( position );
156 particle.template setField<MOBILITY,VELOCITY>( velocity );
157}
158
159template<typename T, typename PARTICLETYPE>
161 Particle<T,PARTICLETYPE>& particle, T delTime,
163{
164 using namespace descriptors;
165 constexpr unsigned D = PARTICLETYPE::d;
167 //Check field existence
168 static_assert(PARTICLETYPE::template providesNested<SURFACE,ANGLE>(), "Field SURFACE:ANGLE has to be provided");
169 static_assert(PARTICLETYPE::template providesNested<MOBILITY,ANG_VELOCITY>(), "Field MOBILITY:ANG_VELOCITY has to be provided");
170 //Calculate quantities
171 Vector<T,Drot> angularVelocity( particle.getMobility().getAngularVelocity()
172 + angularAcceleration * delTime );
173 Vector<T,Drot> angle( particle.getSurface().getAngle() + angularVelocity * delTime );
174 //Update values
175 particle.template setField<SURFACE,ANGLE>( angle );
176 particle.template setField<MOBILITY,ANG_VELOCITY>( angularVelocity );
177}
178
179template<typename T, typename PARTICLETYPE>
181 Vector<T,PARTICLETYPE::d> acceleration,
183{
184 //Calculate cartesian directions
185 eulerIntegrationTranslation( particle, delTime, acceleration );
186 //Calculate rotational directions
187 if constexpr ( access::providesSurface<PARTICLETYPE>() ) {
188 eulerIntegrationRotation( particle, delTime, angularAcceleration );
189 }
190}
191
192//from FLUENT theory guide
193//TODO: Check and include into unit tests
194template<typename T, typename PARTICLETYPE>
196 Particle<T,PARTICLETYPE>& particle, Vector <T,PARTICLETYPE::d> acceleration, T delTime,
197 Vector <T,PARTICLETYPE::d> fluid_vel )
198{
199
200 using namespace descriptors;
201 constexpr unsigned D = PARTICLETYPE::d;
202 //Check field existence
203 static_assert(PARTICLETYPE::template providesNested<GENERAL,POSITION>(), "Field POSITION has to be provided");
204 static_assert(PARTICLETYPE::template providesNested<MOBILITY,VELOCITY>(), "Field VELOCITY has to be provided");
205 //Calculate quant accelearation[0]
206 if (acceleration[0]!=0){
207 T tau_p0 = 1./(acceleration[0])*(fluid_vel[0]-particle.template getField<MOBILITY,VELOCITY>()[0]);
208 Vector<T,D> velocity( fluid_vel+ std::exp((-delTime/tau_p0))*(particle.template getField<MOBILITY,VELOCITY>()- fluid_vel));
209 Vector<T,D> position( particle.template getField<GENERAL,POSITION>() + delTime*(fluid_vel) + tau_p0*(1- std::exp((-delTime/tau_p0)))*(particle.template getField<MOBILITY,VELOCITY>()-fluid_vel));
210 //Update values
211 particle.template setField<GENERAL,POSITION>( position );
212 particle.template setField<MOBILITY,VELOCITY>( velocity );
213 } else {
214 Vector<T,D> position( particle.template getField<GENERAL,POSITION>() + delTime*particle.template getField<MOBILITY,VELOCITY>());
215 //Update values
216 particle.template setField<GENERAL,POSITION>( position );
217 //particle.template setField<MOBILITY,VELOCITY>( velocity );
218 }
219}
220
221
222
223} //namespace dynamics
224
225} //namespace particles
226
227} //namespace olb
228
229
230#endif
#define M_PI
Plain old scalar vector.
Definition vector.h:47
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 eulerIntegrationRotation(Particle< T, PARTICLETYPE > &particle, T delTime, Vector< T, utilities::dimensions::convert< PARTICLETYPE::d >::rotation > angularAcceleration)
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)
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)
ADf< T, DIM > fmod(const ADf< T, DIM > &a, const ADf< T, DIM > &b)
Definition aDiff.h:703
Top level namespace for all of OpenLB.
Converts dimensions by deriving from given cartesian dimension D.