00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_hash_extra (search, locs, hash, nlocs, &
00012 mask_array, mask_shape, mask_available, &
00013 grid_valid_shape, ierror)
00014
00015
00016
00017 use PRISM
00018
00019 use PSMILe, dummy_interface => PSMILe_Hash_extra
00020
00021 Implicit none
00022
00023
00024
00025 Integer, Intent (in) :: nlocs
00026
00027
00028
00029 Integer, Intent (In) :: locs (ndim_3d, nlocs)
00030
00031
00032
00033
00034 Integer, Intent (In) :: mask_shape (2, ndim_3d)
00035
00036
00037
00038 Logical, Intent (In) :: mask_array (mask_shape (1,1):
00039 mask_shape (2,1),
00040 mask_shape (1,2):
00041 mask_shape (2,2),
00042 mask_shape (1,3):
00043 mask_shape (2,3))
00044
00045
00046 Logical, Intent (In) :: mask_available
00047
00048
00049
00050
00051
00052 Integer, Intent (In) :: grid_valid_shape (2,
00053 ndim_3d)
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 Type (Enddef_global_search), Intent (InOut) :: search
00064
00065
00066
00067
00068
00069 Integer, Intent (Out) :: hash (nlocs)
00070
00071
00072
00073
00074
00075
00076
00077
00078 Integer, Intent (Out) :: ierror
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 Integer, Parameter :: nd_hliste = 1024
00090
00091 Integer, Parameter :: outside_ng = -1
00092 Integer, Parameter :: masked_out = 0
00093
00094
00095
00096
00097
00098 Integer :: i, k, l, n, nf
00099 Integer :: nbeg, nend
00100
00101
00102
00103 Integer :: length (ndim_3d)
00104
00105
00106
00107 Integer, Allocatable :: locs2liste (:)
00108 Integer, Allocatable :: hash_liste (:)
00109 Integer, Allocatable :: liste (:)
00110 Integer, Allocatable :: next (:)
00111
00112
00113
00114 Integer :: n_liste, n_found
00115
00116 Integer, Pointer :: neigh (:, :)
00117 Integer, Pointer :: index_found (:)
00118
00119
00120
00121 Integer, parameter :: nerrp = 1
00122 Integer :: ierrp (nerrp)
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 Character(len=len_cvs_string), save :: mycvs =
00156 '$Id: psmile_hash_extra.F90 2082 2009-10-21 13:31:19Z hanke $'
00157
00158
00159
00160
00161
00162 #ifdef VERBOSE
00163 print 9990, trim(ch_id)
00164
00165 call psmile_flushstd
00166 #endif /* VERBOSE */
00167
00168 ierror = 0
00169
00170 length (1:ndim_3d) = grid_valid_shape(2,1:ndim_3d) - &
00171 grid_valid_shape(1,1:ndim_3d) + 1
00172
00173 #ifdef PRISM_ASSERTION
00174
00175
00176
00177 if (nlocs <= 0) then
00178 call psmile_assert ( __FILE__, __LINE__, &
00179 'Number of points to be searched == 0 ?!?')
00180 endif
00181
00182 if (mask_available) then
00183 if (grid_valid_shape (1,1) < mask_shape (1,1) .or. &
00184 grid_valid_shape (2,1) > mask_shape (2,1) .or. &
00185 grid_valid_shape (1,2) < mask_shape (1,2) .or. &
00186 grid_valid_shape (2,2) > mask_shape (2,2) .or. &
00187 grid_valid_shape (1,3) < mask_shape (1,3) .or. &
00188 grid_valid_shape (2,3) > mask_shape (2,3)) then
00189 print *, "grid_valid_shape", grid_valid_shape
00190 print *, "mask_shape ", mask_shape
00191
00192 call psmile_assert ( __FILE__, __LINE__, &
00193 'grid_valid_shape must be in mask_shape')
00194
00195 endif
00196 endif
00197 #endif
00198
00199
00200
00201
00202
00203
00204 do n = 1, nlocs
00205 hash(n) = ((locs (3,n) - grid_valid_shape(1,3)) * length(2) + &
00206 (locs (2,n) - grid_valid_shape(1,2))) * length(1) + &
00207 (locs (1,n) - grid_valid_shape(1,1)) + 1
00208 end do
00209
00210
00211
00212
00213
00214 do n = 1, nlocs
00215 if (locs(1,n) < grid_valid_shape(1,1) .or. &
00216 locs(1,n) > grid_valid_shape(2,1) .or. &
00217 locs(2,n) < grid_valid_shape(1,2) .or. &
00218 locs(2,n) > grid_valid_shape(2,2) .or. &
00219 locs(3,n) < grid_valid_shape(1,3) .or. &
00220 locs(3,n) > grid_valid_shape(2,3)) then
00221 hash (n) = outside_ng
00222 endif
00223 end do
00224
00225
00226
00227
00228 if (mask_available) then
00229
00230 do n = 1, nlocs
00231 if (hash (n) > 0) then
00232 if (.not. mask_array (locs(1, n), &
00233 locs(2, n), &
00234 locs(3, n)) ) then
00235 hash (n) = masked_out
00236 endif
00237 endif
00238 end do
00239 endif
00240
00241 #ifdef DEBUGX
00242 print *, 'hash values and locs ', grid_valid_shape
00243 do n = 1, nlocs
00244 print *, 'n, hash(n), locs(:,n) ', &
00245 n, hash(n), locs(:,n)
00246 end do
00247 #endif
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 Allocate (hash_liste (nd_hliste), stat = ierror)
00264 if (ierror /= 0) then
00265 ierrp (1) = nd_hliste
00266
00267 ierror = PRISM_Error_Alloc
00268
00269 call psmile_error ( ierror, 'nd_hliste', ierrp, 1, &
00270 __FILE__, __LINE__ )
00271 return
00272 endif
00273
00274 Allocate (next (nlocs), liste (nlocs), locs2liste (nlocs), &
00275 stat = ierror)
00276 if (ierror /= 0) then
00277 ierrp (1) = nlocs * 3
00278
00279 ierror = PRISM_Error_Alloc
00280
00281 call psmile_error ( ierror, 'next, liste, locs2liste', ierrp, 1, &
00282 __FILE__, __LINE__ )
00283 return
00284 endif
00285
00286 next (:) = 0
00287 hash_liste (:) = 0
00288
00289 #ifdef PRISM_ASSERTION
00290 locs2liste (:) = -11
00291 #endif
00292
00293
00294
00295
00296
00297
00298 do n = 1, nlocs
00299 if (hash (n) > 0) then
00300 i = mod (hash(n), nd_hliste) + 1
00301 if (hash_liste(i) > 0) then
00302 next (n) = hash_liste(i)
00303 endif
00304
00305 hash_liste(i) = n
00306 endif
00307 end do
00308
00309 #ifdef DEBUGX
00310 print *, 'length', length (:)
00311 print *, 'hash', hash (1:nlocs)
00312 print *, 'hashliste', hash_liste (1:nd_hliste)
00313 #endif
00314
00315
00316
00317
00318
00319
00320
00321 n = 0
00322
00323 do i = 1, nd_hliste
00324 if (hash_liste (i) > 0) then
00325 n = n + 1
00326
00327
00328
00329 liste (n) = hash_liste (i)
00330 locs2liste (hash_liste (i)) = n
00331
00332 nbeg = n
00333 nend = n
00334
00335 k = hash_liste (i)
00336 do while (next (k) > 0)
00337
00338
00339
00340
00341
00342 k = next (k)
00343 do l = nbeg, nend
00344 if (hash (k) == hash (liste(l))) exit
00345 end do
00346
00347 if (l > nend) then
00348 n = n + 1
00349
00350 liste (n) = k
00351 locs2liste (k) = n
00352 nend = nend + 1
00353 else
00354 locs2liste(k) = l
00355 endif
00356 end do
00357
00358 endif
00359 end do
00360
00361 n_liste = n
00362
00363 #ifdef PRISM_ASSERTION
00364
00365
00366
00367
00368 do n = 1, nlocs
00369 if (hash (n) > 0 .and. &
00370 (locs2liste (n) <= 0 .or. locs2liste(n) > n_liste)) exit
00371 end do
00372
00373 if (n < nlocs) then
00374 print *, 'n, nlocs, locs2liste (n)', n, nlocs, locs2liste (n)
00375 call psmile_assert ( __FILE__, __LINE__, &
00376 'locs2liste is not totally filled')
00377 endif
00378 #endif
00379
00380
00381
00382 Deallocate (hash_liste, next)
00383
00384
00385
00386 if (n_liste > 0) then
00387 #if 0
00388
00389
00390
00391 n = 0
00392 n_found = 0
00393 do j = 1, n_corners
00394
00395 do i = 1, n_send
00396 if (ijkmsk (i,j)) then
00397 n = n + 1
00398 if (hash(n) >= 0) n_found = n_found + 1
00399 endif
00400 end do
00401 end do
00402
00403 #ifdef PRISM_ASSERTION
00404 if (n /= nlocs) then
00405 print *, 'nlocs, n', nlocs, n
00406 call psmile_assert ( __FILE__, __LINE__, &
00407 'n /= nlocs')
00408 endif
00409
00410 if (n_found > nlocs) then
00411 print *, 'nlocs, n_found', nlocs, n_found
00412 call psmile_assert ( __FILE__, __LINE__, &
00413 'n_found > nlocs')
00414 endif
00415 #endif
00416 #else
00417 n_found = Count (hash(:) >= 0)
00418
00419
00420
00421
00422
00423 #endif
00424
00425
00426
00427 Allocate (neigh (ndim_3d, n_liste), index_found (n_found), &
00428 stat = ierror)
00429 if (ierror /= 0) then
00430 ierrp (1) = n_liste * ndim_3d + n_found
00431
00432 ierror = PRISM_Error_Alloc
00433
00434 call psmile_error ( ierror, 'n_liste', ierrp, 1, &
00435 __FILE__, __LINE__ )
00436 return
00437 endif
00438
00439
00440
00441
00442
00443 do n = 1, n_liste
00444 neigh (1, n) = locs (1, liste(n))
00445 neigh (2, n) = locs (2, liste(n))
00446 neigh (3, n) = locs (3, liste(n))
00447 end do
00448
00449 #ifdef DEBUGX
00450 print *, 'locations to be sent: nd_liste', n_liste
00451 do n = 1, n_liste
00452 print *, 'neigh', neigh (:, n)
00453 end do
00454 #endif
00455
00456
00457
00458
00459
00460 nf = 0
00461
00462 do n = 1, nlocs
00463 if (hash (n) >= 0) then
00464
00465
00466
00467
00468
00469 nf = nf + 1
00470
00471 if (hash(n) > 0) then
00472 index_found (nf) = locs2liste (n)
00473 else
00474 index_found (nf) = masked_out
00475 endif
00476 endif
00477
00478 end do
00479
00480 #ifdef PRISM_ASSERTION
00481 if (nf /= n_found) then
00482 print *, 'nf, n_found, index', nf, n_found
00483 call psmile_assert ( __FILE__, __LINE__, &
00484 'nf /= n_found')
00485 endif
00486
00487 do i = 1, n_found
00488 if (index_found(i) /= masked_out .and. &
00489 (index_found(i) < 1 .or. index_found(i) > n_liste)) exit
00490 end do
00491
00492 if (i < n_found) then
00493 print *, 'i, n_found, index', i, n_found, index_found (i)
00494 call psmile_assert ( __FILE__, __LINE__, &
00495 'invalid found index generated')
00496 endif
00497 #endif
00498
00499 #ifdef DEBUGX
00500 print *, 'index_found', n_found
00501 do i = 1, n_found
00502 print *, 'i', i, index_found (i)
00503 end do
00504 #endif
00505
00506 else
00507
00508
00509
00510 NULLIFY (neigh)
00511 NULLIFY (index_found)
00512
00513 n_found = 0
00514
00515 endif
00516
00517
00518
00519 Deallocate (locs2liste)
00520
00521
00522
00523 search%n_liste = n_liste
00524 search%neigh_3d => neigh
00525
00526 search%n_found = n_found
00527 search%index_found => index_found
00528
00529
00530
00531 #ifdef VERBOSE
00532 print 9980, trim(ch_id), ierror, n_found, nlocs
00533
00534 call psmile_flushstd
00535 #endif /* VERBOSE */
00536
00537 return
00538
00539
00540
00541 #ifdef VERBOSE
00542 9990 format (1x, a, ': psmile_hash_extra')
00543 9980 format (1x, a, ': psmile_hash_extra: eof', &
00544 ', ierror =', i4, ', n_found =', i8, i8)
00545 #endif /* VERBOSE */
00546
00547 end subroutine PSMILe_Hash_extra