File: N:\mfix\model\des\multisap.f
1
2
3
4
5
6
7
8
9
10
11
12 #include "version.inc"
13
14 module multi_sweep_and_prune
15
16 use sweep_and_prune
17
18 type multisap_t
19
20 integer :: grid(3)
21
22
23 real :: minbounds(3), maxbounds(3)
24
25
26 real :: one_over_cell_length(3)
27
28
29 type(sap_t), dimension(:), allocatable :: saps
30
31
32 type(hashtable_t) :: hashtable
33 end type multisap_t
34
35
36
37
38
39
40
41
42
43
44 type boxhandle_t
45 integer :: sap_id
46 integer :: box_id
47 end type boxhandle_t
48
49
50
51
52
53
54
55
56
57
58
59
60 integer, parameter :: MAX_SAPS = 8
61
62 type boxhandlelist_t
63 integer :: particle_id
64 type(boxhandle_t) :: list(MAX_SAPS)
65 end type boxhandlelist_t
66
67 public :: init_multisap, multisap_add, multisap_del, multisap_update, multisap_sort, multisap_quicksort, multisap_sweep, boxhandle_grow
68 private :: multisap_raster
69
70 contains
71
72
73
74
75
76
77
78
79 subroutine init_multisap(this,x_grid,y_grid,z_grid2,minbounds,maxbounds)
80 use geometry
81 implicit none
82 type(multisap_t), intent(inout) :: this
83 integer, intent(in) :: x_grid,y_grid, z_grid2
84 real, dimension(3), intent(in) :: minbounds, maxbounds
85 integer :: ii,jj,kk, z_grid, sap_id
86
87 if (NO_K) then
88 z_grid = 1
89 else
90 z_grid = z_grid2
91 endif
92
93 this%grid(1) = max(x_grid,1)
94 this%grid(2) = max(y_grid,1)
95 this%grid(3) = max(z_grid,1)
96
97 allocate(this%saps(0:this%grid(1)*this%grid(2)*this%grid(3)-1))
98 do ii=0,this%grid(1)-1
99 do jj=0,this%grid(2)-1
100 do kk=0,this%grid(3)-1
101 sap_id = (ii*this%grid(2)+jj)*this%grid(3)+kk
102 call init_sap(this%saps(sap_id),sap_id)
103 enddo
104 enddo
105 enddo
106
107 this%one_over_cell_length(:) = this%grid(:)/(maxbounds(:)-minbounds(:))
108
109 this%minbounds(:) = minbounds(:)
110 this%maxbounds(:) = maxbounds(:)
111
112 end subroutine init_multisap
113
114
115
116
117
118
119
120
121
122
123
124 subroutine multisap_raster(this,aabb,sap_ids)
125 implicit none
126 type(multisap_t), intent(inout) :: this
127 type(aabb_t), intent(in) :: aabb
128 integer, intent(out) :: sap_ids(MAX_SAPS)
129 integer :: max_grid(3),min_grid(3)
130
131 sap_ids(:) = -1
132
133
134 (:) = floor((aabb%minendpoint(:)-this%minbounds(:))*this%one_over_cell_length(:))
135 max_grid(:) = floor((aabb%maxendpoint(:)-this%minbounds(:))*this%one_over_cell_length(:))
136
137 min_grid(1) = min(max(min_grid(1),0),this%grid(1)-1)
138 min_grid(2) = min(max(min_grid(2),0),this%grid(2)-1)
139 min_grid(3) = min(max(min_grid(3),0),this%grid(3)-1)
140 max_grid(1) = min(max(max_grid(1),0),this%grid(1)-1)
141 max_grid(2) = min(max(max_grid(2),0),this%grid(2)-1)
142 max_grid(3) = min(max(max_grid(3),0),this%grid(3)-1)
143
144 call add_to_set((min_grid(1)*this%grid(2) + min_grid(2))*this%grid(3) + min_grid(3))
145 call add_to_set((min_grid(1)*this%grid(2) + min_grid(2))*this%grid(3) + max_grid(3))
146 call add_to_set((min_grid(1)*this%grid(2) + max_grid(2))*this%grid(3) + min_grid(3))
147 call add_to_set((min_grid(1)*this%grid(2) + max_grid(2))*this%grid(3) + max_grid(3))
148 call add_to_set((max_grid(1)*this%grid(2) + min_grid(2))*this%grid(3) + min_grid(3))
149 call add_to_set((max_grid(1)*this%grid(2) + min_grid(2))*this%grid(3) + max_grid(3))
150 call add_to_set((max_grid(1)*this%grid(2) + max_grid(2))*this%grid(3) + min_grid(3))
151 call add_to_set((max_grid(1)*this%grid(2) + max_grid(2))*this%grid(3) + max_grid(3))
152
153 contains
154
155
156
157
158
159
160
161
162
163 subroutine add_to_set(sap_id)
164 integer, intent(in) :: sap_id
165 integer :: mm
166
167 do mm=1, size(sap_ids)
168 if (sap_ids(mm).eq.sap_id) then
169
170 return
171 endif
172 if (sap_ids(mm).eq.-1) then
173 sap_ids(mm) = sap_id
174 return
175 endif
176 enddo
177
178 end subroutine add_to_set
179
180 end subroutine multisap_raster
181
182
183
184
185
186
187
188
189
190
191
192 subroutine multisap_add(this,aabb,particle_id,handlelist)
193 implicit none
194 type(multisap_t), intent(inout) :: this
195 type(aabb_t), intent(in) :: aabb
196 integer, intent(in) :: particle_id
197 type(boxhandlelist_t), intent(out) :: handlelist
198 integer :: sap_ids(MAX_SAPS)
199 integer :: nn
200
201 call multisap_raster(this,aabb,sap_ids)
202
203 handlelist%particle_id = particle_id
204
205
206 do nn=1, size(sap_ids)
207 handlelist%list(nn)%sap_id = sap_ids(nn)
208 if (sap_ids(nn) >= 0) then
209 call add_box(this%saps(sap_ids(nn)),aabb,particle_id,handlelist%list(nn)%box_id)
210 endif
211 enddo
212
213 end subroutine multisap_add
214
215
216
217
218
219
220
221
222
223 subroutine multisap_del(this,handlelist)
224 implicit none
225 type(multisap_t), intent(inout) :: this
226 type(boxhandlelist_t), intent(in) :: handlelist
227 integer :: nn
228
229
230 do nn=1, size(handlelist%list)
231 if (handlelist%list(nn)%sap_id >= 0) then
232 call del_box(this%saps(handlelist%list(nn)%sap_id),handlelist%list(nn)%box_id)
233 endif
234 enddo
235
236 end subroutine multisap_del
237
238
239
240
241
242
243
244
245
246
247
248 subroutine multisap_update(this,aabb,handlelist)
249 implicit none
250 type(multisap_t), intent(inout) :: this
251 type(aabb_t), intent(in) :: aabb
252 type(boxhandlelist_t), intent(inout) :: handlelist
253 integer, DIMENSION(MAX_SAPS) :: new_sap_ids
254 logical :: found
255 integer :: mm,nn,first_blank, box_id
256
257 call multisap_raster(this,aabb,new_sap_ids)
258
259
260 do nn=1, size(new_sap_ids)
261 if (new_sap_ids(nn) < 0) exit
262
263 found = .false.
264 first_blank = -1
265 do mm=1, size(handlelist%list)
266 if (handlelist%list(mm)%sap_id < 0) first_blank = mm
267
268 if (handlelist%list(mm)%sap_id .eq. new_sap_ids(nn)) then
269
270 = handlelist%list(mm)%box_id
271 call update_box(this%saps(new_sap_ids(nn)),handlelist%list(mm)%box_id,aabb)
272 found = .true.
273 exit
274 endif
275 enddo
276 if (.not.found) then
277
278
279 if (first_blank .eq. -1) then
280 print *,"AABB is in more than 8 saps? Something is wrong: ",first_blank,handlelist%list
281 ERROR_STOP __LINE__
282 endif
283 call add_box(this%saps(new_sap_ids(nn)),aabb,handlelist%particle_id,handlelist%list(first_blank)%box_id)
284 handlelist%list(first_blank)%sap_id = new_sap_ids(nn)
285 endif
286 enddo
287
288 do mm=1, size(handlelist%list)
289 if (handlelist%list(mm)%sap_id < 0) cycle
290
291 found = .false.
292 do nn=1, size(new_sap_ids)
293 if (new_sap_ids(nn) < 0) exit
294
295 if (handlelist%list(mm)%sap_id .eq. new_sap_ids(nn)) then
296 found = .true.
297 exit
298 endif
299 enddo
300
301 if (.not.found) then
302
303 call del_box(this%saps(handlelist%list(mm)%sap_id),handlelist%list(mm)%box_id)
304 handlelist%list(mm)%sap_id = -1
305 endif
306
307 enddo
308
309 end subroutine multisap_update
310
311
312
313
314
315
316
317
318
319
320
321 subroutine multisap_sort(this)
322
323
324 implicit none
325 type(multisap_t), intent(inout) :: this
326 integer :: ii, jj, kk, sap_id
327 integer :: pair(2)
328 integer :: sighs, cc,ll,i, cc_start, cc_end
329
330 call init_pairs(this%hashtable)
331
332
333
334 do ii=0,this%grid(1)-1
335 do jj=0,this%grid(2)-1
336 do kk=0,this%grid(3)-1
337 sap_id = ii*this%grid(2)*this%grid(3)+jj*this%grid(3)+kk
338 call sort(this%saps(sap_id))
339 enddo
340 enddo
341 enddo
342
343
344 print *," NUMBER OF DESGRIDS IS: ",this%grid(1)*this%grid(2)*this%grid(3)
345
346 sighs = 0
347
348 open (unit=235,file="pairs.txt",action="write",status="replace")
349
350 do ii=0,this%grid(1)-1
351 do jj=0,this%grid(2)-1
352 do kk=0,this%grid(3)-1
353 sap_id = ii*this%grid(2)*this%grid(3)+jj*this%grid(3)+kk
354 call reset_pairs(this%saps(sap_id)%hashtable)
355 sighs = sighs + this%saps(sap_id)%hashtable%table_size
356 do
357 call get_pair(this%saps(sap_id)%hashtable,pair)
358 if (pair(1).eq.0 .and. pair(2).eq.0) exit
359 write (235,*) pair(1),pair(2)
360 call add_pair(this%hashtable,pair(1),pair(2))
361
362 enddo
363 enddo
364 enddo
365 enddo
366
367 close (unit=235)
368
369
370
371
372
373
374
375
376
377
378
379
380
381 end subroutine multisap_sort
382
383
384
385
386
387
388
389
390
391 subroutine multisap_quicksort(this)
392 implicit none
393 type(multisap_t), intent(inout) :: this
394 integer :: ii, jj, kk
395 integer :: sap_id, boxcount
396
397 boxcount = 0
398
399 do ii=0,this%grid(1)-1
400 do jj=0,this%grid(2)-1
401 do kk=0,this%grid(3)-1
402 sap_id = ii*this%grid(2)*this%grid(3)+jj*this%grid(3)+kk
403 call quicksort(this%saps(sap_id))
404 boxcount = boxcount + this%saps(sap_id)%boxes_len
405 enddo
406 enddo
407 enddo
408
409 end subroutine multisap_quicksort
410
411
412
413
414
415
416
417
418
419 subroutine multisap_sweep(this)
420 implicit none
421 type(multisap_t), intent(inout) :: this
422 integer :: ii, jj, kk
423 integer :: sap_id
424
425 do ii=0,this%grid(1)-1
426 do jj=0,this%grid(2)-1
427 do kk=0,this%grid(3)-1
428 sap_id = (ii*this%grid(2)+jj)*this%grid(3)+kk
429 call sweep(this%saps(sap_id))
430 enddo
431 enddo
432 enddo
433
434 end subroutine multisap_sweep
435
436 subroutine multisap_check(this)
437 implicit none
438 type(multisap_t), intent(inout) :: this
439 integer :: ii, jj, kk
440 integer :: sap_id
441
442 do ii=0,this%grid(1)-1
443 do jj=0,this%grid(2)-1
444 do kk=0,this%grid(3)-1
445 sap_id = (ii*this%grid(2)+jj)*this%grid(3)+kk
446
447 call check(this%saps(sap_id))
448 enddo
449 enddo
450 enddo
451
452 end subroutine multisap_check
453
454
455
456
457
458
459
460
461
462 subroutine boxhandle_GROW(boxhandles,new_size)
463 IMPLICIT NONE
464
465 INTEGER, INTENT(IN) :: new_size
466 type(boxhandlelist_t), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: boxhandles
467 type(boxhandlelist_t), DIMENSION(:), ALLOCATABLE :: boxhandle_tmp
468 INTEGER lSIZE
469
470 lSIZE = size(boxhandles,1)
471 allocate(boxhandle_tmp(new_size))
472 boxhandle_tmp(1:lSIZE) = boxhandles(1:lSIZE)
473 call move_alloc(boxhandle_tmp,boxhandles)
474
475 end subroutine boxhandle_GROW
476
477 end module multi_sweep_and_prune
478