psmile_add_nn_found_dble.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PSMILe_Add_nn_found_dble
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_add_nn_found_dble (search, extra_search,  &
00012                         index_sent, found, n_send,                &
00013                         index_found, distance, n_found, nb_extra, &
00014                         selected, sel_info, nrecv, ierror)
00015 !
00016 ! !USES:
00017 !
00018       use PRISM
00019 !
00020       use PSMILe, dummy_interface => PSMILe_Add_nn_found_dble
00021 
00022       Implicit none
00023 !
00024 ! !INPUT PARAMETERS:
00025 !
00026       Type (Enddef_search),     Intent (In) :: search
00027 
00028 !     Info's on coordinates to be searched
00029 !
00030       Integer,           Intent (In)     :: n_send
00031 !
00032 !     Number of points for which additional interpolation data was found.
00033 !     Dimension "indices_returned".
00034 
00035       Integer,            Intent (In)    :: index_sent (n_send)
00036 !
00037 !     Indices (in dist_dble/indices) of points which were 
00038 !     transferred to neighbour process for global search.
00039 !     1 <= index_sent (i) <= search%n_extra
00040 !
00041       Integer,            Intent (In)    :: found (n_send)
00042 !
00043 !     Number of nearest neighbours found for each point sent.
00044 
00045       Integer,            Intent (In)    :: n_found
00046 !
00047 !     Total number of points found which are used for interpolation.
00048 !     Dimension of "index_found" and "distance".
00049 !
00050       Integer,            Intent (In)    :: index_found (n_found)
00051 !
00052 !     Index of n-th point in compact list "liste"
00053 !     Mapping of sequence of points found (1:n_found) to (1:n_liste)
00054 !
00055       Double Precision,   Intent (In)    :: distance (n_found)
00056 !
00057 !     Nearest neighbour distance for each point found,
00058 
00059       Integer,            Intent (In)    :: nb_extra
00060 !
00061 !     Number of nearest neigbhbours to be searched per extra point
00062 !
00063 !     Integer,            Intent (In)    :: use_how
00064 
00065 !     Information about how to apply the mask
00066 
00067       Integer,            Intent (InOut) :: nrecv
00068 
00069 !     Number of the request received
00070 
00071 ! !INPUT/OUTPUT PARAMETERS:
00072 !
00073       Type (Extra_search_info), Intent (InOut) :: extra_search
00074 !
00075 !     Number of locations where
00076 !       (*) required mask values were not true
00077 !
00078       Integer,                  Intent (InOut) :: selected (2, extra_search%n_extra)
00079 !
00080 !     Vector for global nearest neighbour search of extra points with
00081 !        selected (1, *) = Number (index) of the receive
00082 !                          from which the nearest neigbour was selected.
00083 !                          = 0 : Nearest neighour was found locally
00084 !        selected (2, *) = Index in list of points 
00085 !                          (sent by neighbouring process)
00086 !
00087 
00088       Type (Select_search_info),    Intent (InOut) :: sel_info (nrecv)
00089 !
00090 !     Info on the data received which is used to select 
00091 !     the appropriate points.
00092 !     
00093 !
00094 ! !OUTPUT PARAMETERS:
00095 !
00096       Integer,            Intent (Out)   :: ierror
00097 
00098 !     Returns the error code of PSMILe_Add_nn_found_dble;
00099 !             ierror = 0 : No error
00100 !             ierror > 0 : Severe error
00101 !
00102 ! !LOCAL PARAMETERS:
00103 !
00104 ! masked_out   = Hash value for a point which is masked out
00105 !
00106       Integer, Parameter           :: masked_out = 0
00107 !
00108 ! !LOCAL VARIABLES
00109 !
00110 !     ... loop variables
00111 !
00112       Integer                         :: i, j, n
00113 !
00114 !     ... 
00115 !
00116       Integer                         :: n_liste, nsel
00117       Integer                         :: prev
00118       Integer,          Pointer       :: used (:)
00119       Double Precision, Pointer       :: dist_dble (:, :)
00120 !
00121 !     ... for communication
00122 !
00123       Integer                         :: msg_sel (nd_msgsel)
00124 !
00125 !     ... for error handling
00126 !
00127       Integer, Parameter              :: nerrp = 3
00128       Integer                         :: ierrp (nerrp)
00129 !
00130 ! !DESCRIPTION:
00131 !
00132 ! Subroutine "PSMILe_Add_nn_found_dble" add information on
00133 ! points found by global search to the already existing information.
00134 !
00135 ! !REVISION HISTORY:
00136 !
00137 !   Date      Programmer   Description
00138 ! ----------  ----------   -----------
00139 ! 02.11.06    H. Ritzdorf  created
00140 !
00141 !EOP
00142 !----------------------------------------------------------------------
00143 !
00144 !  $Id: psmile_add_nn_found_dble.F90 2082 2009-10-21 13:31:19Z hanke $
00145 !  $Author: hanke $
00146 !
00147    Character(len=len_cvs_string), save :: mycvs = 
00148        '$Id: psmile_add_nn_found_dble.F90 2082 2009-10-21 13:31:19Z hanke $'
00149 !
00150 !----------------------------------------------------------------------
00151 !
00152 !  Initialization
00153 !
00154 #ifdef VERBOSE
00155       print 9990, trim(ch_id), n_send, n_found, sel_info(nrecv)%n_liste
00156 
00157       call psmile_flushstd
00158 #endif /* VERBOSE */
00159 !
00160       ierror = 0
00161 !
00162       dist_dble => extra_search%dist_dble
00163 !
00164 !  n_liste = Number of points in the compact list
00165 !
00166       n_liste = sel_info(nrecv)%n_liste
00167 !
00168 #ifdef PRISM_ASSERTION
00169 !
00170 !===> Internal control
00171 !
00172 !     n_liste <= n_found <= n_send
00173 !
00174 !cdir vector
00175          do i = 1, n_found
00176          if (index_found (i) <= 0 .and. &
00177              index_found (i) /= masked_out) exit
00178          end do
00179 !
00180       if (i <= n_found) then
00181          print *, 'i, n_found, index_found', i, n_found, index_found (i)
00182          call psmile_assert ( __FILE__, __LINE__, &
00183                  'invalid index in found list')
00184       endif
00185 !
00186 !cdir vector
00187          do i = 1, n_found
00188          if (index_found (i) > n_liste) exit
00189          end do
00190 !
00191       if (i <= n_found) then
00192          print *, 'i, n_found, index_found, n_liste', &
00193                    i, n_found, index_found (i), n_liste
00194          call psmile_assert ( __FILE__, __LINE__, &
00195                  'invalid index (> n_liste) in found list')
00196       endif
00197 !
00198 #endif
00199 !
00200 !===> Allocate and initialize vector "used" for compact list
00201 !     of points sent.
00202 !
00203       Allocate (sel_info(nrecv)%used(n_liste), stat = ierror)
00204       if (ierror /= 0) then
00205          ierrp (1) = n_liste
00206 
00207          ierror = PRISM_Error_Alloc
00208 
00209          call psmile_error ( ierror, 'sel_info(nrecv)%used', ierrp, 1, &
00210                      __FILE__, __LINE__ )
00211          return
00212       endif
00213 !
00214       used => sel_info(nrecv)%used
00215 !
00216       used (:) = 0
00217 !
00218 !cdir vector
00219          do n = 1, n_found
00220          if (index_found(n) > 0) then
00221             used (index_found(n)) = used (index_found(n)) + 1
00222          endif
00223          end do 
00224 !
00225 !===> Control distances found in neighbouring block
00226 !
00227 ! 1 <= i <= n_extra : Index in list of extra points for
00228 !                     which nearest neighbours have to be found.
00229 ! 1 <= j <= n_send  : Index in list of points sent (to the process
00230 !                     which should search for nearest neighbours)
00231 ! 1 <= n <= n_found : Index in sequence of points found (by the process
00232 !                     which has searched for nearest neigbours)
00233 !                    
00234 ! nsel = Number of points selected from the list of points found
00235 !
00236       nsel = 0
00237       n = 0
00238          do j = 1, n_send
00239          if (found (j) > 0) then
00240             n = n + 1
00241             if (index_found(n) > 0) then
00242                i = index_sent (j)
00243 
00244 #ifdef DEBUGX
00245                print *, 'psmile_add_nn_found_dble: n, j, i, i_liste, dists', &
00246                         n, j, i, index_found(n), dist_dble (i,1), distance (n)
00247 #endif
00248 
00249                if (dist_dble (i,1) <= distance (n)) then
00250 !
00251 !===> ... Distance is not smaller than distance which was already found.
00252 !         Remove point from list of points.
00253 !         Index_found(n) is index in compact list of points
00254 !
00255                   used (index_found(n)) = used (index_found(n)) - 1
00256 
00257                else
00258 
00259 !           Select this point
00260 !           If previous point was already selected by
00261 !           another global search, remove this point
00262 !
00263                   if (selected (1, i) > 0) then
00264                      prev = selected (1, i)
00265 
00266 #ifdef PRISM_ASSERTION
00267                      if (prev > nrecv) then
00268                         print *, trim(ch_id), "prev, nrecv", prev, nrecv
00269                         call psmile_assert ( __FILE__, __LINE__, &
00270                                 'invalid recv request')
00271                      endif
00272 #endif
00273 
00274                      sel_info(prev)%used (selected (2, i)) =   &
00275                      sel_info(prev)%used (selected (2, i)) - 1
00276                   endif
00277 !
00278                   nsel = nsel + 1
00279 !
00280                   dist_dble (i,1) = distance (n)
00281                   selected (1, i) = nrecv
00282                   selected (2, i) = index_found(n)
00283                endif
00284             endif
00285          endif
00286          end do
00287 !
00288 !===> Remove points which are masked out
00289 !
00290 !     if (use_how /= PSMILE_novalue) then
00291 !     endif
00292 !
00293 !===> If no point was selected, remove vector "used"
00294 !
00295       if (nsel == 0) then
00296 !
00297 !        Return answer to sending process
00298 !
00299 !  msg_sel (1) = Code
00300 !  msg_sel (2) = Number of entries in original compact list
00301 !  msg_sel (3) = Number of entries in new      compact list
00302 !  msg_sel (4) = index
00303 !  msg_sel (5) = method id
00304 !
00305          msg_sel (1) = PSMILe_nnghbr3D
00306          msg_sel (2) = n_liste
00307          msg_sel (3) = 0
00308          msg_sel (4) = sel_info(nrecv)%index
00309          msg_sel (5) = sel_info(nrecv)%method_id
00310 !
00311 !===> ... Send message header to destination process
00312 !
00313          call MPI_Send (msg_sel, nd_msgsel, MPI_INTEGER, &
00314                         sel_info(nrecv)%sender, seltag, comm_psmile, ierror)
00315 !
00316          if (ierror /= MPI_SUCCESS) then
00317             ierrp (1) = ierror
00318             ierrp (2) = sel_info(nrecv)%sender
00319             ierrp (3) = seltag
00320 
00321             ierror = PRISM_Error_Send
00322 
00323             call psmile_error (ierror, 'MPI_send (msg_sel)', ierrp, 3, &
00324                         __FILE__, __LINE__ )
00325             return
00326          endif
00327 !
00328 !===> ... Free memory
00329 !
00330          Deallocate (sel_info(nrecv)%used)
00331          Deallocate (sel_info(nrecv)%dble_buf)
00332 !
00333 !===> ... Decrement number of recv's
00334 !
00335          nrecv = nrecv - 1
00336       endif
00337 !
00338 !===> All done
00339 !
00340 #ifdef VERBOSE
00341       print 9980, trim(ch_id), ierror, nsel
00342 
00343       call psmile_flushstd
00344 #endif /* VERBOSE */
00345 !
00346 !  Formats:
00347 !
00348 
00349 #ifdef VERBOSE
00350 
00351 9990 format (1x, a, ': psmile_add_nn_found_dble: n_send', i7, &
00352              '; n_found', i7, '; n_liste ', i7)
00353 9980 format (1x, a, ': psmile_add_nn_found_dble: eof ierror =', i3, &
00354              '; nsel', i7)
00355 
00356 #endif /* VERBOSE */
00357 
00358 #ifdef DEBUG
00359 #endif
00360 
00361       end subroutine PSMILe_Add_nn_found_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1