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)), stat=i)
198 write(*,*)
'Allocation error: bktdb%buckets', bktdb%ndiv
199 call hecmw_abort(hecmw_comm_get_comm())
201 do k = 1, bktdb%ndiv(3)
202 do j = 1, bktdb%ndiv(2)
203 do i = 1, bktdb%ndiv(1)
204 call bucket_init(bktdb%buckets(i,j,k))
208 if (bktdb%n_tot /= n_tot)
then
209 if (
associated(bktdb%member_all))
deallocate(bktdb%member_all)
210 allocate(bktdb%member_all(n_tot))
216 function encode_bid(bktdb, baddr)
218 integer(kind=kint) :: encode_bid
219 type(bucketdb),
intent(in) :: bktdb
220 integer(kind=kint),
intent(in) :: baddr(3)
221 if (any(baddr <= 0) .or. any(baddr > bktdb%ndiv))
then
225 (baddr(3)-1) * bktdb%ndiv(1) * bktdb%ndiv(2) + (baddr(2)-1) * bktdb%ndiv(1) + baddr(1)
227 end function encode_bid
230 function decode_bid(bktdb, bid)
232 integer(kind=kint) :: decode_bid(3)
233 type(bucketdb),
intent(in) :: bktdb
234 integer(kind=kint),
intent(in) :: bid
235 call assert(bid <= bktdb%ndiv(1)*bktdb%ndiv(2)*bktdb%ndiv(3),
'decode_bid: out of range')
239 decode_bid(1) = mod(bid-1, bktdb%ndiv(1)) + 1
240 decode_bid(2) = mod((bid-1)/bktdb%ndiv(1), bktdb%ndiv(2)) + 1
241 decode_bid(3) = (bid-1)/(bktdb%ndiv(1) * bktdb%ndiv(2)) + 1
242 call assert(encode_bid(bktdb, decode_bid) == bid,
'decode_bid')
244 end function decode_bid
250 type(bucketdb),
intent(in) :: bktdb
251 real(kind=kreal),
intent(in) :: x(3)
252 integer(kind=kint) :: baddr(3)
253 integer(kind=kint) :: i
254 if (bktdb%n_tot == 0)
then
259 call assert(bktdb%d(i) > 0.d0,
'bucketDB_getBucketID: bktdb%d(i) is zero')
260 baddr(i) = floor((x(i) - bktdb%x_min(i)) / bktdb%d(i)) + 1
262 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_getBucketID: ',x,baddr
270 type(bucketdb),
intent(inout) :: bktdb
271 integer(kind=kint),
intent(in) :: bid
272 integer(kind=kint) :: baddr(3)
273 baddr = decode_bid(bktdb, bid)
274 call assert(all(baddr > 0) .and. all(baddr <= bktdb%ndiv),
'bucketDB_register_pre: block ID out of range')
275 call bucket_incr_count(bktdb%buckets(baddr(1),baddr(2),baddr(3)))
276 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_registerPre: ', baddr
283 type(bucketdb),
intent(inout) :: bktdb
284 integer(kind=kint) :: i, j, k, count, n
285 integer(kind=kint),
pointer :: pmemb(:)
287 do k = 1, bktdb%ndiv(3)
288 do j = 1, bktdb%ndiv(2)
289 do i = 1, bktdb%ndiv(1)
291 n = bucket_get_n(bktdb%buckets(i,j,k))
292 pmemb => bktdb%member_all(count+1:count+n)
293 call bucket_assign(bktdb%buckets(i,j,k), pmemb)
304 type(bucketdb),
intent(inout) :: bktdb
305 integer(kind=kint),
intent(in) :: bid
306 integer(kind=kint),
intent(in) :: sid
307 integer(kind=kint) :: baddr(3)
308 baddr = decode_bid(bktdb, bid)
309 call assert(all(baddr > 0) .and. all(baddr <= bktdb%ndiv),
'bucketDB_register: block ID our of range')
310 call bucket_register(bktdb%buckets(baddr(1),baddr(2),baddr(3)), sid)
311 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_register: ', baddr, sid
319 type(bucketdb),
intent(in) :: bktdb
320 integer(kind=kint),
intent(in) :: bid
321 integer(kind=kint) :: baddr(3), ncand, i, j, k, is, ie, js, je, ks, ke
326 baddr = decode_bid(bktdb, bid)
328 is = max(baddr(1)-1, 1)
329 ie = min(baddr(1)+1, bktdb%ndiv(1))
330 js = max(baddr(2)-1, 1)
331 je = min(baddr(2)+1, bktdb%ndiv(2))
332 ks = max(baddr(3)-1, 1)
333 ke = min(baddr(3)+1, bktdb%ndiv(3))
337 ncand = ncand + bucket_get_n(bktdb%buckets(i,j,k))
342 if (debug >= 2)
write(0,*)
' DEBUG: bucketDB_getNumCand: ',ncand
349 type(bucketdb),
intent(in) :: bktdb
350 integer(kind=kint),
intent(in) :: bid
351 integer(kind=kint),
intent(in) :: ncand
352 integer(kind=kint),
intent(out),
target :: cand(ncand)
353 integer(kind=kint) :: baddr(3), i, j, k, n, cnt, is, ie, js, je, ks, ke
354 integer(kind=kint),
pointer :: pcand(:)
355 if (bid < 0 .or. ncand == 0)
return
356 baddr = decode_bid(bktdb, bid)
358 is = max(baddr(1)-1, 1)
359 ie = min(baddr(1)+1, bktdb%ndiv(1))
360 js = max(baddr(2)-1, 1)
361 je = min(baddr(2)+1, bktdb%ndiv(2))
362 ks = max(baddr(3)-1, 1)
363 ke = min(baddr(3)+1, bktdb%ndiv(3))
367 n = bucket_get_n(bktdb%buckets(i,j,k))
368 pcand => cand(cnt+1:cnt+n)
369 call bucket_get_member(bktdb%buckets(i,j,k), n, pcand)
371 call assert(cnt <= ncand,
'bucketDB_get_cand: array overflow')
375 call assert(cnt == ncand,
'bucketDB_get_cand: count mismatch')
376 if (debug >= 3)
write(0,*)
' DEBUG: bucketDB_getCand: ',cand
This module provides bucket-search functionality It provides definition of bucket info and its access...
subroutine, public bucketdb_allocate(bktdb)
Allocate memory before actually registering members Before allocating memory, bucketDB_registerPre ha...
subroutine, public bucketdb_registerpre(bktdb, bid)
Pre-register for just counting members to be actually registered Bucket ID has to be obtained with bu...
integer(kind=kint) function, public bucketdb_getbucketid(bktdb, x)
Get bucket ID that includes given point.
subroutine, public bucketdb_register(bktdb, bid, sid)
Register member Before actually register, bucketDB_allocate has to be called.
subroutine, public bucketdb_finalize(bktdb)
Finalizer.
integer(kind=kint) function, public bucketdb_getnumcand(bktdb, bid)
Get number of candidates within neighboring buckets of a given bucket Bucket ID has to be obtained wi...
subroutine, public bucketdb_init(bktdb)
Initializer.
subroutine, public bucketdb_getcand(bktdb, bid, ncand, cand)
Get candidates within neighboring buckets of a given bucket Number of candidates has to be obtained w...
subroutine, public bucketdb_setup(bktdb, x_min, x_max, dmin, n_tot)
Setup basic info of buckets.