File: /nfs/home/0/users/jenkins/mfix.git/model/des/des_stl_functions_mod.f
1
2
3
4
5
6
7
8
9
10 MODULE des_stl_functions
11
12 IMPLICIT NONE
13
14
15 CONTAINS
16
17
18
19
20
21
22
23
24
25
26 SUBROUTINE TestTriangleAABB(vertices, tri_norm, box_origin, &
27 box_extents, sa_exist, sa, i,j,k)
28
29 USE stl
30
31 Implicit none
32
33
34
35 double precision, intent(in), dimension(3) :: tri_norm
36 double precision, intent(in), dimension(3,3) :: vertices
37 double precision, intent(in), dimension(3) :: box_origin, box_extents
38 logical, intent(out) :: sa_exist
39
40 Integer, intent(out) :: sa
41 Integer, intent(in) :: i,j,k
42
43 double precision :: p0, p1, p2, r, e0, e1, e2
44
45 double precision :: c_orig(3), c(3)
46 double precision, dimension(3) :: vert0, vert1, vert2
47
48
49 double precision, dimension(3) :: u0, u1, u2
50
51 double precision, dimension(3) :: v0, v1, v2
52 double precision, dimension(3) :: f0, f1, f2
53
54
55 double precision, dimension(9, 3) :: sep_axis
56
57 double precision :: tol_tri_aabb_proj
58
59 double precision :: axis_magsq, s
60 integer :: count
61 sa_exist = .false.
62 sa = 0
63 tol_tri_aabb_proj = 1e-06
64
65 vert0 = vertices(1,:)
66 vert1 = vertices(2,:)
67 vert2 = vertices(3,:)
68
69
70
71
72 (:) = box_origin(:) + box_extents(:)* 0.5d0
73
74
75
76 = vert0 - c_orig
77 v1 = vert1 - c_orig
78 v2 = vert2 - c_orig
79
80
81 (1) = v0(1)/box_extents(1)
82 v1(1) = v1(1)/box_extents(1)
83 v2(1) = v2(1)/box_extents(1)
84
85 v0(2) = v0(2)/box_extents(2)
86 v1(2) = v1(2)/box_extents(2)
87 v2(2) = v2(2)/box_extents(2)
88
89 v0(3) = v0(3)/box_extents(3)
90 v1(3) = v1(3)/box_extents(3)
91 v2(3) = v2(3)/box_extents(3)
92
93
94 = 0.d0
95
96 = 0.5d0
97 e1 = 0.5d0
98 e2 = 0.5d0
99 u0 = (/ 1.d0, 0.d0, 0.d0/)
100 u1 = (/ 0.d0, 1.d0, 0.d0/)
101 u2 = (/ 0.d0, 0.d0, 1.d0/)
102
103
104
105
106
107
108
109
110
111 = v1 - v0
112 f1 = v2 - v1
113 f2 = v0 - v2
114
115
116 (1, 1:3) = (/0.d0, -f0(3), f0(2)/)
117 sep_axis(2, 1:3) = (/0.d0, -f1(3), f1(2)/)
118 sep_axis(3, 1:3) = (/0.d0, -f2(3), f2(2)/)
119 sep_axis(4, 1:3) = (/f0(3), 0.d0, -f0(1)/)
120 sep_axis(5, 1:3) = (/f1(3), 0.d0, -f1(1)/)
121 sep_axis(6, 1:3) = (/f2(3), 0.d0, -f2(1)/)
122 sep_axis(7, 1:3) = (/-f0(2), f0(1), 0.d0/)
123 sep_axis(8, 1:3) = (/-f1(2), f1(1), 0.d0/)
124 sep_axis(9, 1:3) = (/-f2(2), f2(1), 0.d0/)
125
126 do count = 1, 9
127 axis_magsq = (sep_axis(count,1)**2+sep_axis(count,2)**2 &
128 +sep_axis(count,3)**2)
129 if(axis_magsq < TOL_STL*TOL_STL) THEN
130
131
132
133
134 CYCLE
135 endif
136
137 r = e0*abs(dot_product(u0(:), sep_axis(count,:))) &
138 + e1*abs(dot_product(u1(:), sep_axis(count,:))) &
139 + e2*abs(dot_product(u2(:), sep_axis(count,:)))
140
141 p0 = dot_product(v0(:), sep_axis(count, :))
142 p1 = dot_product(v1(:), sep_axis(count, :))
143 p2 = dot_product(v2(:), sep_axis(count, :))
144
145 IF(.FALSE.) THEN
146 WRITE(*,'(A6,5(2X,G17.8))')'C:',C_ORIG
147 WRITE(*,'(A6,5(2X,G17.8))')'VORIG:',VERT0
148 WRITE(*,'(A6,5(2X,G17.8))')'V0:',V0
149 WRITE(*,'(A6,5(2X,G17.8))')'V1:',V1
150 WRITE(*,'(A6,5(2X,G17.8))')'EXTENTS:',E0,E1,E2
151 WRITE(*,'(A6,5(2X,G17.8))')'SA:', COUNT, SEP_AXIS(COUNT,:)
152 WRITE(*,'(A6,5(2X,G17.8))')'DATA:', R, P0, P1, P2
153 WRITE(*,'(A6,(2X,G17.8),"<",2(2X,G17.8), ">", 2X,G17.8)') &
154 'DATA2:', MAX(P0, P1, P2)*1E8, -R*1E8, &
155 MIN(P0, P1, P2)*1E8,R*1E8
156
157 WRITE(*,'(A6,5(2X,L2))') 'DATA2:', MAX(P0, P1, P2)< -R,&
158 MIN(P0, P1, P2) > R
159
160 WRITE(*,'(A6,(2X,G17.8),"<",2(2X,G17.8), ">", 2X,G17.8)')&
161 'DATA2:', (MAX(P0, P1, P2)+TOL_TRI_AABB_PROJ)*1E8,&
162 -R*1E8, MIN(P0, P1, P2)*1E8, (R+TOL_TRI_AABB_PROJ)*1E8
163 WRITE(*,'(A6,5(2X,L2))') 'DATA2:', MAX(P0, P1, P2)+&
164 TOL_TRI_AABB_PROJ< -R, MIN(P0, P1, P2) > R+TOL_TRI_AABB_PROJ
165 ENDIF
166
167 IF (MAX(P0, P1, P2) +TOL_TRI_AABB_PROJ < -R .OR. &
168 MIN(P0,P1,P2) > R+TOL_TRI_AABB_PROJ) THEN
169 SA = COUNT
170 SA_EXIST = .TRUE.
171 RETURN
172 ENDIF
173 ENDDO
174
175
176
177
178
179
180
181
182 IF (MAX(V0(1), V1(1), V2(1)) + TOL_TRI_AABB_PROJ< -E0 .OR. &
183 MIN(V0(1), V1(1), V2(1)) > E0+TOL_TRI_AABB_PROJ) THEN
184 SA = 10
185 SA_EXIST = .TRUE.
186 RETURN
187 ENDIF
188
189
190 IF (MAX(V0(2), V1(2), V2(2)) +TOL_TRI_AABB_PROJ< -E1 .OR. &
191 MIN(V0(2), V1(2), V2(2)) > E1+TOL_TRI_AABB_PROJ) THEN
192 SA = 11
193 SA_EXIST = .TRUE.
194 RETURN
195 ENDIF
196
197
198 IF (MAX(V0(3), V1(3), V2(3)) +TOL_TRI_AABB_PROJ< -E2 .OR. &
199 MIN(V0(3), V1(3), V2(3)) > E2+TOL_TRI_AABB_PROJ) THEN
200 SA = 12
201 SA_EXIST = .TRUE.
202 RETURN
203 ENDIF
204
205 R = E0*ABS(DOT_PRODUCT(U0(:), TRI_NORM(:))) &
206 + E1*ABS(DOT_PRODUCT(U1(:), TRI_NORM(:))) &
207 + E2*ABS(DOT_PRODUCT(U2(:), TRI_NORM(:)))
208
209
210
211
212 = Dot_product(tri_norm(:), v0(:))
213
214
215 IF(ABS(S) > R+ TOL_TRI_AABB_PROJ) THEN
216
217 = .TRUE.
218 SA = 13
219 ENDIF
220 END SUBROUTINE TestTriangleAABB
221
222
223
224
225
226
227
228
229
230
231
232
233
234 Subroutine ClosestPtPointTriangle(pointp, points, closest_point)
235 USE param1, only: zero, one
236 USE discretelement, only: dimn
237
238 IMPLICIT NONE
239
240
241 double precision, intent(in), dimension(3,3) :: points
242 double precision, intent(in), dimension(dimn) :: pointp
243 double precision, intent(out), dimension(dimn) :: closest_point
244
245 double precision, dimension(3) :: pointa, pointb, pointc
246 double precision, dimension(dimn) :: ab, ac, ap, bp,cp
247 double precision :: d1, d2, d3, d4, vc, v, d5, d6, vb, w, va, denom
248
249 pointa = points(1,:)
250 pointb = points(2,:)
251 pointc = points(3,:)
252
253 ab = pointb - pointa
254 ac = pointc - pointa
255 ap = pointp - pointa
256 d1 = DOT_PRODUCT(ab, ap)
257 d2 = DOT_PRODUCT(ac, ap)
258
259 IF(d1 <= Zero .AND. d2 <= zero) then
260 closest_point = pointa
261 return
262 end if
263
264
265 = pointp - pointb
266 d3 = DOT_PRODUCT(ab, bp);
267 d4 = DOT_PRODUCT(ac, bp);
268 if (d3 >= zero .and. d4 <= d3) then
269 closest_point = pointb
270 return
271 endif
272
273
274 = d1*d4 - d3*d2;
275 if (vc <= zero .and. d1 >= zero .and. d3 <= zero) then
276 v = d1 / (d1 - d3);
277 closest_point = pointa + v * ab;
278 return
279 end if
280
281
282 = pointp - pointc
283 d5 = DOT_PRODUCT(ab, cp)
284 d6 = DOT_PRODUCT(ac, cp)
285 if (d6 >= zero .and. d5 <= d6) then
286 closest_point = pointc
287 return
288 endif
289
290
291 = d5*d2 - d1*d6
292
293 if (vb <= zero .and. d2 >= zero .and. d6 <= zero) then
294 w = d2 / (d2 - d6)
295 closest_point = pointa + w * ac
296 return
297 end if
298
299
300 = d3*d6 - d5*d4
301 if (va <= zero .and.(d4 - d3) >= zero .and. (d5 - d6) >= zero) then
302 w = (d4 - d3) / ((d4 - d3) + (d5 - d6))
303 closest_point = pointb + w * (pointc - pointb)
304 return
305 end if
306
307
308
309 = one / (va + vb + vc)
310 v = vb * denom
311 w = vc * denom
312 closest_point = pointa + ab * v + ac * w;
313 return
314 end Subroutine ClosestPtPointTriangle
315
316
317
318
319
320
321
322
323
324 SUBROUTINE CHECKPTONTRIANGLE(POINTP, POINTS, ON_TRIAN)
325
326
327
328
329 use discretelement, only: DIMN
330
331 use stl, only: tol_stl
332
333 use param1, only : ONE
334
335
336 IMPLICIT NONE
337
338
339
340
341
342 DOUBLE PRECISION, INTENT(IN) :: POINTS(3,3)
343
344 DOUBLE PRECISION, INTENT(IN) :: POINTP(DIMN)
345
346 LOGICAL, INTENT(OUT):: ON_TRIAN
347
348
349
350
351 DOUBLE PRECISION, DIMENSION(DIMN) :: V0, V1, V2
352 DOUBLE PRECISION :: D00, D01, D11, D20, D21, DENOM
353
354 DOUBLE PRECISION :: V, W
355
356
357 V0 = POINTS(2,:) - POINTS(1,:)
358 V1 = POINTS(3,:) - POINTS(1,:)
359 V2 = POINTP - POINTS(1,:)
360
361 D00 = dot_product(V0, V0)
362 D01 = dot_product(V0, V1)
363 D11 = dot_product(V1, V1)
364 D20 = dot_product(V2, V0)
365 D21 = dot_product(V2, V1)
366
367 DENOM = D00*D11 - D01*D01
368
369 V = (D11*D20 - D01*D21)/DENOM
370 W = (D00*D21 - D01*D20)/DENOM
371
372 ON_TRIAN = ((V>=-TOL_STL) .AND. (W>=-TOL_STL) .AND. &
373 ((V+W)<=ONE+TOL_STL))
374
375 RETURN
376 END SUBROUTINE CHECKPTONTRIANGLE
377
378
379
380
381
382
383
384
385
386
387 Subroutine intersectLnPlane(ref_line, dir_line, ref_plane, &
388 norm_plane, line_param)
389
390 USE discretelement, only: dimn
391 USE param1, only: zero
392 IMPLICIT NONE
393
394 double precision, intent(in), dimension(dimn) :: ref_line, dir_line
395
396 double precision, intent(in), dimension(dimn) :: ref_plane, norm_plane
397
398
399 double precision, intent(out) :: line_param
400
401
402 double precision :: denom
403
404 denom = DOT_PRODUCT(dir_line, norm_plane)
405 if(denom*denom.gt.zero) then
406 line_param = DOT_PRODUCT(ref_plane(:) - ref_line(:), norm_plane(:))
407 line_param = line_param/denom
408 endif
409 return
410 end subroutine intersectLnPlane
411
412 subroutine set_facet_type_normal(facet_type)
413 USE discretelement, only: Facet_type_normal
414 Implicit none
415 integer, intent(out) :: facet_type
416 facet_type = FACET_type_NORMAL
417 end subroutine set_facet_type_normal
418
419 subroutine set_facet_type_po(facet_type)
420 USE discretelement, only: Facet_type_po
421 Implicit none
422 integer, intent(out) :: facet_type
423 facet_type = FACET_type_PO
424 end subroutine set_facet_type_po
425
426 subroutine set_facet_type_mi(facet_type)
427 USE discretelement, only: Facet_type_mi
428 Implicit none
429 integer, intent(out) :: facet_type
430 facet_type = FACET_type_MI
431 end subroutine set_facet_type_mi
432
433
434 END MODULE DES_STL_FUNCTIONS
435
436
437