23 integer(kind=kint),
parameter :: DEBUG = 0
27 integer(kind=kint) :: n
28 integer(kind=kint) :: n_max
29 integer(kind=kint),
pointer :: member(:) => null()
35 real(kind=kreal) :: x_min(3)
36 real(kind=kreal) :: x_max(3)
37 real(kind=kreal) :: d(3)
38 integer(kind=kint) :: ndiv(3)
39 type(bucket),
pointer :: buckets(:,:,:) => null()
40 integer(kind=kint) :: n_tot
41 integer(kind=kint),
pointer :: member_all(:) => null()
47 subroutine assert(cond, mesg)
49 logical,
intent(in) :: cond
50 character(len=*) :: mesg
53 write(0,*)
'ASSERTION FAILED: ',mesg
54 call hecmw_abort( hecmw_comm_get_comm() )
64 subroutine bucket_init(bkt)
66 type(bucket),
intent(inout) :: bkt
70 end subroutine bucket_init
73 subroutine bucket_finalize(bkt)
75 type(bucket),
intent(inout) :: bkt
80 end subroutine bucket_finalize
83 subroutine bucket_incr_count(bkt)
85 type(bucket),
intent(inout) :: bkt
88 end subroutine bucket_incr_count
91 subroutine bucket_assign(bkt, mem)
93 type(bucket),
intent(inout) :: bkt
94 integer(kind=kint),
pointer :: mem(:)
98 end subroutine bucket_assign
101 subroutine bucket_register(bkt, sid)
103 type(bucket),
intent(inout) :: bkt
104 integer(kind=kint),
intent(in) :: sid
105 integer(kind=kint) :: idx
110 call assert(idx <= bkt%n_max,
'bucket_register: too many members')
111 bkt%member(idx) = sid
112 end subroutine bucket_register
115 function bucket_get_n(bkt)
117 integer(kind=kint) :: bucket_get_n
118 type(bucket),
intent(in) :: bkt
120 end function bucket_get_n
123 subroutine bucket_get_member(bkt, n, memb)
125 type(bucket),
intent(in) :: bkt
126 integer(kind=kint),
intent(in) :: n
127 integer(kind=kint),
intent(out) :: memb(n)
128 call assert(n == bkt%n,
'bucket_get_member: wrong n')
129 memb(1:n) = bkt%member(1:n)
130 end subroutine bucket_get_member
139 type(bucketdb),
intent(inout) :: bktdb
140 bktdb%x_min(:) = 0.d0
141 bktdb%x_max(:) = 0.d0
144 nullify(bktdb%buckets)
146 nullify(bktdb%member_all)
152 type(bucketdb),
intent(inout) :: bktdb
153 integer(kind=kint) :: i, j, k
154 if (bktdb%n_tot > 0)
then
155 deallocate(bktdb%member_all)
158 if (any(bktdb%ndiv == 0))
then
162 do k = 1, bktdb%ndiv(3)
163 do j = 1, bktdb%ndiv(2)
164 do i = 1, bktdb%ndiv(1)
165 call bucket_finalize(bktdb%buckets(i,j,k))
169 deallocate(bktdb%buckets)
176 type(bucketdb),
intent(inout) :: bktdb
177 real(kind=kreal),
intent(in) :: x_min(3)
178 real(kind=kreal),
intent(in) :: x_max(3)
179 real(kind=kreal),
intent(in) :: dmin
180 integer(kind=kint),
intent(in) :: n_tot
181 real(kind=kreal) :: xrange(3)
182 integer(kind=kint) :: i, j, k
183 real(kind=kreal),
parameter ::
eps = 1.d-6
184 if (debug >= 1)
write(0,*)
'DEBUG: bucketDB_setup', x_min, x_max, dmin, n_tot
185 if (
associated(bktdb%buckets))
deallocate(bktdb%buckets)
186 bktdb%x_min(:) = x_min(:)
187 bktdb%x_max(:) = x_max(:)
188 xrange(:) = x_max(:) - x_min(:)
189 call assert(all(xrange > 0.d0),
'bucketDB_setup: invalid x_min, x_max')
191 bktdb%ndiv(i) = max(floor(xrange(i) / dmin), 1)
192 bktdb%d(i) = xrange(i) / bktdb%ndiv(i) * (1.d0 +
eps)
194 if (debug >= 1)
write(0,*)
'DEBUG: bucketDB_setup: ndiv, d: ', bktdb%ndiv, bktdb%d
195 call assert(all(bktdb%d > 0.d0),
'bucketDB_setup: invalid bktdb%d')
196 allocate(bktdb%buckets(bktdb%ndiv(1), bktdb%ndiv(2), bktdb%ndiv(3)))
197 do k = 1, bktdb%ndiv(3)
198 do j = 1, bktdb%ndiv(2)
199 do i = 1, bktdb%ndiv(1)
200 call bucket_init(bktdb%buckets(i,j,k))
204 if (bktdb%n_tot /= n_tot)
then
205 if (
associated(bktdb%member_all))
deallocate(bktdb%member_all)
206 allocate(bktdb%member_all(n_tot))
212 function encode_bid(bktdb, baddr)
214 integer(kind=kint) :: encode_bid
215 type(bucketdb),
intent(in) :: bktdb
216 integer(kind=kint),
intent(in) :: baddr(3)
217 if (any(baddr <= 0) .or. any(baddr > bktdb%ndiv))
then
221 (baddr(3)-1) * bktdb%ndiv(1) * bktdb%ndiv(2) + (baddr(2)-1) * bktdb%ndiv(1) + baddr(1)
223 end function encode_bid
226 function decode_bid(bktdb, bid)
228 integer(kind=kint) :: decode_bid(3)
229 type(bucketdb),
intent(in) :: bktdb
230 integer(kind=kint),
intent(in) :: bid
231 call assert(bid <= bktdb%ndiv(1)*bktdb%ndiv(2)*bktdb%ndiv(3),
'decode_bid: out of range')
235 decode_bid(1) = mod(bid-1, bktdb%ndiv(1)) + 1
236 decode_bid(2) = mod((bid-1)/bktdb%ndiv(1), bktdb%ndiv(2)) + 1
237 decode_bid(3) = (bid-1)/(bktdb%ndiv(1) * bktdb%ndiv(2)) + 1
238 call assert(encode_bid(bktdb, decode_bid) == bid,
'decode_bid')
240 end function decode_bid
246 type(bucketdb),
intent(in) :: bktdb
247 real(kind=kreal),
intent(in) :: x(3)
248 integer(kind=kint) :: baddr(3)
249 integer(kind=kint) :: i
250 if (bktdb%n_tot == 0)
then
255 call assert(bktdb%d(i) > 0.d0,
'bucketDB_getBucketID: bktdb%d(i) is zero')
256 baddr(i) = floor((x(i) - bktdb%x_min(i)) / bktdb%d(i)) + 1
258 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_getBucketID: ',x,baddr
266 type(bucketdb),
intent(inout) :: bktdb
267 integer(kind=kint),
intent(in) :: bid
268 integer(kind=kint) :: baddr(3)
269 baddr = decode_bid(bktdb, bid)
270 call assert(all(baddr > 0) .and. all(baddr <= bktdb%ndiv),
'bucketDB_register_pre: block ID out of range')
271 call bucket_incr_count(bktdb%buckets(baddr(1),baddr(2),baddr(3)))
272 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_registerPre: ', baddr
279 type(bucketdb),
intent(inout) :: bktdb
280 integer(kind=kint) :: i, j, k, count, n
281 integer(kind=kint),
pointer :: pmemb(:)
283 do k = 1, bktdb%ndiv(3)
284 do j = 1, bktdb%ndiv(2)
285 do i = 1, bktdb%ndiv(1)
287 n = bucket_get_n(bktdb%buckets(i,j,k))
288 pmemb => bktdb%member_all(count+1:count+n)
289 call bucket_assign(bktdb%buckets(i,j,k), pmemb)
300 type(bucketdb),
intent(inout) :: bktdb
301 integer(kind=kint),
intent(in) :: bid
302 integer(kind=kint),
intent(in) :: sid
303 integer(kind=kint) :: baddr(3)
304 baddr = decode_bid(bktdb, bid)
305 call assert(all(baddr > 0) .and. all(baddr <= bktdb%ndiv),
'bucketDB_register: block ID our of range')
306 call bucket_register(bktdb%buckets(baddr(1),baddr(2),baddr(3)), sid)
307 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_register: ', baddr, sid
315 type(bucketdb),
intent(in) :: bktdb
316 integer(kind=kint),
intent(in) :: bid
317 integer(kind=kint) :: baddr(3), ncand, i, j, k, is, ie, js, je, ks, ke
322 baddr = decode_bid(bktdb, bid)
324 is = max(baddr(1)-1, 1)
325 ie = min(baddr(1)+1, bktdb%ndiv(1))
326 js = max(baddr(2)-1, 1)
327 je = min(baddr(2)+1, bktdb%ndiv(2))
328 ks = max(baddr(3)-1, 1)
329 ke = min(baddr(3)+1, bktdb%ndiv(3))
333 ncand = ncand + bucket_get_n(bktdb%buckets(i,j,k))
338 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_getNumCand: ',ncand
345 type(bucketdb),
intent(in) :: bktdb
346 integer(kind=kint),
intent(in) :: bid
347 integer(kind=kint),
intent(in) :: ncand
348 integer(kind=kint),
intent(out),
target :: cand(ncand)
349 integer(kind=kint) :: baddr(3), i, j, k, n, cnt, is, ie, js, je, ks, ke
350 integer(kind=kint),
pointer :: pcand(:)
351 if (bid < 0 .or. ncand == 0)
return
352 baddr = decode_bid(bktdb, bid)
354 is = max(baddr(1)-1, 1)
355 ie = min(baddr(1)+1, bktdb%ndiv(1))
356 js = max(baddr(2)-1, 1)
357 je = min(baddr(2)+1, bktdb%ndiv(2))
358 ks = max(baddr(3)-1, 1)
359 ke = min(baddr(3)+1, bktdb%ndiv(3))
363 n = bucket_get_n(bktdb%buckets(i,j,k))
364 pcand => cand(cnt+1:cnt+n)
365 call bucket_get_member(bktdb%buckets(i,j,k), n, pcand)
367 call assert(cnt <= ncand,
'bucketDB_get_cand: array overflow')
371 call assert(cnt == ncand,
'bucketDB_get_cand: count mismatch')
372 if (debug >= 3)
write(0,*)
' DEBUG: bucketDB_getCand: ',cand