OpenLB 1.7
Loading...
Searching...
No Matches
hertzMindlinDeresiewiczForCombWithCollisionModel3D.hh
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Marie-Luise Maier, Mathias J. Krause, Sascha Janz
3 * E-mail contact: info@openlb.net
4 * The most recent release of OpenLB can be downloaded at
5 * <http://www.openlb.net/>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23/* Alberto Di Renzo, Francesco Paolo Di Maio:
24 * "Comparison of contact-force models for the simulation of collisions in
25 * DEM-based granular ow codes",
26 * Chemical Engineering Science 59 (2004) 525 - 541
27 */
28
29#ifndef HERTZMINDLINDERESIEWICZ3D_HH
30#define HERTZMINDLINDERESIEWICZ3D_HH
31
32#include "utilities/omath.h"
34
35namespace olb {
36
37template<typename T, template<typename U> class PARTICLETYPE, template<
38 typename W> class DESCRIPTOR>
39HertzMindlinDeresiewicz3D<T, PARTICLETYPE, DESCRIPTOR>::HertzMindlinDeresiewicz3D(
40 T G1, T G2, T v1, T v2, T scale1, T scale2, bool validationKruggelEmden) :
41 Force3D<T, PARTICLETYPE>(), _G1(G1), _G2(G2), _v1(v1), _v2(v2), _scale1(
42 scale1), _scale2(scale2), _validationKruggelEmden(validationKruggelEmden)
43{
44 // E-Modul Particle
45 E1 = 2 * (1 + _v1) * _G1;
46 E2 = 2 * (1 + _v2) * _G2;
47
48 // equivalent combined E-Modul
49 eE = (1 - util::pow(_v1, 2)) / E1 + (1 - util::pow(_v2, 2)) / E2;
50 eE = 1 / eE;
51
52 // equivalent combined E-Modul
53 eG = (2.0 - _v1) / _G1 + (2 - _v2) / _G2;
54 eG = 1. / eG;
55}
56
57template<typename T, template<typename U> class PARTICLETYPE, template<
58 typename W> class DESCRIPTOR>
59void HertzMindlinDeresiewicz3D<T, PARTICLETYPE, DESCRIPTOR>::applyForce(
60 typename std::deque<PARTICLETYPE<T> >::iterator p, int pInt,
61 ParticleSystem3D<T, PARTICLETYPE>& pSys)
62{
63 T force[3] = {T(), T(), T()};
64
65 computeForce(p, pInt, pSys, force);
66}
67
68
69template<typename T, template<typename U> class PARTICLETYPE, template<
70 typename W> class DESCRIPTOR>
71void HertzMindlinDeresiewicz3D<T, PARTICLETYPE, DESCRIPTOR>::computeForce(
72 typename std::deque<PARTICLETYPE<T> >::iterator p, int pInt,
73 ParticleSystem3D<T, PARTICLETYPE>& pSys, T force[3])
74{
75 if (p->getSActivity() > 1) {
76
77 std::vector<std::pair<size_t, T>> ret_matches;
78 // kind of contactDetection has to be chosen in application
79 pSys.getContactDetection()->getMatches(pInt, ret_matches);
80
81 PARTICLETYPE<T>* p2 = NULL;
82
83 // iterator walks through number of neighbored particles = ret_matches
84 for (const auto& it : ret_matches) {
85
86 if (!util::nearZero(it.second)) {
87
88 p2 = &pSys[it.first];
89
90 // overlap
91 T delta = (p2->getRad() + p->getRad()) - util::sqrt(it.second);
92
94 // T deltaMax = 0.03 * (p2->getRad() + p->getRad()) ;
95 // if (delta > deltaMax ) {
96
97 // T dpos[3] = {T(0), T(0), T(0) } ;
98
99 // for (int i = 0; i <= 2; i++) {
100
101 // dpos[i] = _normal[i] * 0.5 * (delta - deltaMax) ;
102 // p->getPos()[i] -= 1.* dpos[i];
103 // p2->getPos()[i] += 1.* dpos[i];
104 // }
105 // delta = deltaMax * (p2->getRad() + p->getRad());
106 // }
107
108 // equivalent mass
109 T M = p->getMass() * p2->getMass() / (p->getMass() + p2->getMass());
110 // equivalent radius
111 T R = p->getRad() * p2->getRad() / (p->getRad() + p2->getRad());
112 // relative velocity
113 std::vector < T > _velR(3, T());
114 _velR[0] = -(p2->getVel()[0] - p->getVel()[0]); // gehört das Minus hier hin?
115 _velR[1] = -(p2->getVel()[1] - p->getVel()[1]);
116 _velR[2] = -(p2->getVel()[2] - p->getVel()[2]);
117
118 std::vector < T > _d(3, T());
119 std::vector < T > _normal(3, T());
120
121 //_d: vector from particle1 to particle2
122 _d[0] = p2->getPos()[0] - p->getPos()[0];
123 _d[1] = p2->getPos()[1] - p->getPos()[1];
124 _d[2] = p2->getPos()[2] - p->getPos()[2];
125
126 if ( !util::nearZero(util::norm(_d)) ) {
127 _normal = util::normalize(_d);
128 }
129 else {
130 return;
131 }
132
133 Vector<T, 3> d_(_d);
134 Vector<T, 3> velR_(_velR);
135 T dot = velR_[0] * _normal[0] + velR_[1] * _normal[1] + velR_[2] * _normal[2];
136
137 // normal part of relative velocity
138 // normal relative to surface of particles at contact point
139 std::vector < T > _velN(3, T());
140 _velN[0] = dot * _normal[0];
141 _velN[1] = dot * _normal[1];
142 _velN[2] = dot * _normal[2];
143
144 // tangential part of relative velocity
145 // tangential relative to surface of particles at contact point
146 std::vector < T > _velT(3, T());
147 _velT[0] = _velR[0] - _velN[0];
148 _velT[1] = _velR[1] - _velN[1];
149 _velT[2] = _velR[2] - _velN[2];
150
151
152 if (delta > 0.) {
153
154 // Force normal
155 // spring constant in normal direction
156 // (Alberto Di Renzo, Francesco Paolo Di Maio, Chemical Engineering Science 59 (2004) 525 - 541)
157 // constant kn from H. Kruggel-Endem
158 T kn = 4 / 3. * util::sqrt(R) * eE;
159 if (_validationKruggelEmden) {
160 kn = 7.35e9; // to compare to Kruggel-Emden
161 }
162
163 // part of mechanical force of spring in normal direction
164 // Hertz Contact (P. A. Langston, Powder Technology 85 (1995))
165 std::vector < T > Fs_n(3, T());
166 Fs_n[0] = -kn * util::pow(delta, 1.5) * _normal[0];
167 Fs_n[1] = -kn * util::pow(delta, 1.5) * _normal[1];
168 Fs_n[2] = -kn * util::pow(delta, 1.5) * _normal[2];
169
170 // part of mechanical force of damper in normal direction
171 // damped linear spring (Cundall, Strack 1979)
172 // (K.W. Chu, A.B. Yu, Powder Technology 179 (2008) 104 – 114)
173 // damper constant in normal direction
174 // constant eta_n from H. Kruggel-Endem
175 T eta_n = 0.3 * util::sqrt(4.5 * M * util::sqrt(delta) * kn);
176 if (_validationKruggelEmden) {
177 eta_n = 1.96e5; // to compare to Kruggel-Emden
178 }
179
180 std::vector < T > Fd_n(3, T());
181 Fd_n[0] = -eta_n * _velN[0] * util::sqrt(delta);
182 Fd_n[1] = -eta_n * _velN[1] * util::sqrt(delta);
183 Fd_n[2] = -eta_n * _velN[2] * util::sqrt(delta);
184
185 std::vector < T > F_n(3, T());
186 F_n[0] = Fs_n[0] + Fd_n[0];
187 F_n[1] = Fs_n[1] + Fd_n[1];
188 F_n[2] = Fs_n[2] + Fd_n[2];
189
190 // Force tangential
191 // spring constant in tangential direction
192 // (N.G. Deen, Chemical Engineering Science 62 (2007) 28 - 44)
193 T kt = 2 * util::sqrt(2 * R) * _G1 / (2 - _v1) * util::pow(delta, 0.5);
194
195 // damper constant in normal direction
196 T eta_t = 2 * util::sqrt(2. / 7. * M * kt);
197
198 // part of mechanical force of damper in tangential direction
199 std::vector < T > F_t(3, T());
200 F_t[0] = -eta_t * _velT[0];
201 F_t[1] = -eta_t * _velT[1];
202 F_t[2] = -eta_t * _velT[2];
203
204 // entire force
205 // factor _scale to prevent instability
206 force[0] = _scale1 * F_n[0] + _scale2 * F_t[0];
207 force[1] = _scale1 * F_n[1] + _scale2 * F_t[1];
208 force[2] = _scale1 * F_n[2] + _scale2 * F_t[2];
209
210 p->getForce()[0] += force[0] * 0.5 ;
211 p->getForce()[1] += force[1] * 0.5 ;
212 p->getForce()[2] += force[2] * 0.5 ;
213 p2->getForce()[0] -= force[0] * 0.5 ;
214 p2->getForce()[1] -= force[1] * 0.5 ;
215 p2->getForce()[2] -= force[2] * 0.5 ;
216
217 if ((p->getSActivity() || p2->getSActivity()) == 3) {
218 p->setSActivity(3);
219 p2->setSActivity(3);
220 }
221 if ((p->getSActivity() == 4) && (p2->getSActivity() != (4 || 3))) {
222 p2->setSActivity(3);
223 }
224 if ((p2->getSActivity() == 4) && (p->getSActivity() != (4 || 3))) {
225 p->setSActivity(3);
226 }
227 }
228 }
229 }
230 }
231}
232
233#endif
234
235
platform_constant Fraction M[Q][Q]
Top level namespace for all of OpenLB.