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