psmile_add_points_found.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_points_found
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_add_points_found (grid_id, search,   &
00012                            extra_search, indices_returned,   &
00013                            found, n_send, len_nsend,         &
00014                            index_found, n_found,             &
00015                            neighbors_3d, nloc, num_neigh,    &
00016                            grid_valid_shape, use_how, ierror)
00017 !
00018 ! !USES:
00019 !
00020       use PRISM
00021 !
00022       use PSMILe, dummy_interface => PSMILe_Add_points_found
00023 #ifdef DEBUG_TRACE
00024       use psmile_debug_trace
00025 #endif
00026 
00027       Implicit none
00028 !
00029 ! !INPUT PARAMETERS:
00030 !
00031       Integer,           Intent (In)     :: grid_id
00032 !
00033 !     Handle to the pointer to the receive list
00034 !
00035       Type (Enddef_search),     Intent (InOut) :: search
00036 
00037 !     Info's on coordinates to be searched
00038 !
00039       Integer,           Intent (In)     :: n_send
00040 !
00041 !     Number of points for which additional interpolation data was found.
00042 !     Dimension of "found" and "indices_returned".
00043 
00044       Integer,            Intent (In)    :: indices_returned (n_send)
00045 !
00046 !     Indices of the extra points in vectors "required" and
00047 !     "indices_req" for which interpolation data was found.
00048 !     This is a local index of the partition "ipart".
00049 !     (cf. routine PSMILe_Store_faces_3d_reg_dble)
00050 
00051       Integer,            Intent (In)    :: n_found
00052 !
00053 !     Total number of points found which are used for interpolation.
00054 !     Dimension of "index_found".
00055 !
00056       Integer,            Intent (In)    :: index_found (n_found)
00057 !
00058 !     Index of point in compact list "liste"
00059 !
00060       Integer,            Intent (In)    :: len_nsend (search%npart)
00061 !
00062 !     Number of points for which additional interpolation data was required
00063 !     per partition.
00064 !
00065       Integer,            Intent (In)    :: nloc
00066 !
00067 !     Total  Number of locations to be transferred
00068 !     Last dimension of neighbors array "neighbors_3d" and
00069 !     number of neighbors to be searched.
00070 
00071       Integer,            Intent (In)    :: num_neigh
00072 !
00073 !     Last dimension of neighbors array "neighbors_3d" and
00074 !     number of neighbors to be searched.
00075 
00076       Integer,            Intent (In)    :: grid_valid_shape (2, ndim_3d)
00077 
00078 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00079 
00080       Integer,            Intent (In)    :: use_how
00081 
00082 !     Information about how to apply the mask
00083 
00084 ! !INPUT/OUTPUT PARAMETERS:
00085 !
00086       Type (Extra_search_info), Intent (InOut) :: extra_search
00087 !
00088 !     Number of locations where
00089 !       (*) required mask values were not true
00090 
00091       Integer,            Intent (InOut) :: found    (n_send)
00092 !
00093 !     Input: Code of the interpolation bases found for corresponding point.
00094 !            (cf. "required")
00095 !     Output: Code cleaned by points masked out.
00096 
00097       Integer,            Intent (InOut) :: neighbors_3d (ndim_3d, nloc, 
00098                                                           num_neigh)
00099 !
00100 ! !OUTPUT PARAMETERS:
00101 !
00102       Integer,            Intent (Out)   :: ierror
00103 
00104 !     Returns the error code of PSMILe_Add_points_found;
00105 !             ierror = 0 : No error
00106 !             ierror > 0 : Severe error
00107 !
00108 ! !LOCAL PARAMETERS:
00109 !
00110 ! masked_out   = Hash value for a point which is masked out
00111 !
00112       Integer, Parameter           :: masked_out = 0
00113       Integer, Parameter           :: undef      = -12
00114 !
00115 ! !LOCAL VARIABLES
00116 !
00117 !     ... loop variables
00118 !
00119       Integer                         :: i, k, n
00120 !
00121 !     ... Bit value for found points
00122 !
00123       Integer                         :: iband (n_send)
00124       Integer                         :: code
00125 !
00126 !     ... 
00127 !
00128       Integer, Allocatable            :: corner2ind (:, :)
00129       Integer                         :: n_corners
00130       Integer                         :: outside
00131       Integer, Pointer                :: recv_list(:)
00132 !
00133 !     ... for partitions
00134 !
00135       Integer                         :: ipart, ip
00136       Integer, Pointer                :: indices_req (:)
00137       Integer, Pointer                :: required (:)
00138       Integer, Pointer                :: len_req (:)
00139 !
00140 !     ... for error handling
00141 !
00142       Integer, Parameter              :: nerrp = 2
00143       Integer                         :: ierrp (nerrp)
00144 !
00145 ! !DESCRIPTION:
00146 !
00147 ! Subroutine "PSMILe_Add_points_found" add information on
00148 ! points found by global search to the already existing information.
00149 !
00150 ! !REVISION HISTORY:
00151 !
00152 !   Date      Programmer   Description
00153 ! ----------  ----------   -----------
00154 ! 02.02.06    H. Ritzdorf  created
00155 !
00156 !EOP
00157 !----------------------------------------------------------------------
00158 !
00159 !  $Id: psmile_add_points_found.F90 2935 2011-02-03 07:52:41Z redler $
00160 !  $Author: redler $
00161 !
00162    Character(len=len_cvs_string), save :: mycvs = 
00163        '$Id: psmile_add_points_found.F90 2935 2011-02-03 07:52:41Z redler $'
00164 !
00165 !----------------------------------------------------------------------
00166 !
00167 !  Initialization
00168 !
00169 #ifdef VERBOSE
00170       print 9990, trim(ch_id), n_send, n_found
00171 
00172       call psmile_flushstd
00173 #endif /* VERBOSE */
00174 !
00175       ierror = 0
00176 !
00177       if (associated(Grids(grid_id)%recv_list)) then
00178           !
00179           ! in particular for Gauss-reduced grids
00180           !
00181           recv_list => Grids(grid_id)%recv_list
00182           outside   = grid_valid_shape(2,1) + sum(recv_list) + 11
00183       else
00184           outside   = grid_valid_shape(2,1) + 11
00185       endif
00186 
00187       n_corners = num_neigh
00188 !
00189       len_req     => extra_search%len_req
00190 !
00191 #ifdef PRISM_ASSERTION
00192       do i = 1, n_found
00193          if (index_found (i) <= 0 .and. &
00194              index_found (i) /= masked_out) exit
00195       end do
00196 !
00197       if (i <= n_found) then
00198          print *, 'i, n_found, index_found', i, n_found, index_found (i)
00199          call psmile_assert ( __FILE__, __LINE__, &
00200                  'invalid index in found list')
00201       endif
00202 
00203       ip = 0
00204       do ipart = 1, search%npart
00205          do i = 1, len_nsend (ipart)
00206             if (indices_returned (ip+i) < 1 .or. &
00207                 indices_returned (ip+i) > len_req(ipart)) exit
00208          end do
00209 !
00210          if (i <= len_nsend (ipart)) then
00211             print *, 'ipart, ip, i, nreq, indices_returned(ip+i)', &
00212                      ipart, ip, i, len_req(ipart),                 &
00213                      indices_returned (ip+i)
00214             call psmile_assert ( __FILE__, __LINE__, &
00215                      'invalid index in indices_returned')
00216          endif
00217 !
00218          ip = ip + len_nsend (ipart)
00219       end do
00220 #endif
00221 !
00222 #ifdef DEBUGX
00223       do i = 1, n_found
00224          print *, 'i index_found', i, index_found(i)
00225       end do
00226 
00227       code = 1
00228       k = 0
00229       do i = 1, n_corners
00230 
00231          do n = 1, n_send
00232             if (IAND (found(n), code) /= 0) then
00233                k = k + 1
00234                print *, 'found: n', n, code, index_found (k)
00235             endif
00236          end do
00237          code = code * 2
00238       end do ! i
00239 
00240       ip = 0
00241       do ipart = 1, search%npart
00242          do i = 1, len_nsend (ipart)
00243                print *, 'ip i indices_returned', ip, i, indices_returned (ip+i), found (ip+i)
00244 ! indices_req(indices_returned (ip+i))
00245          end do
00246             ip = ip + len_nsend (ipart)
00247       end do
00248 #endif
00249 !
00250 !===> Allocate array in order to store the indices of
00251 !     of the compact list of "interpolation bases found"
00252 !     (cf. PSMILe_Trili_3d_extra_off)
00253 !
00254       Allocate (corner2ind (n_send, n_corners), stat = ierror)
00255       if ( ierror > 0 ) then
00256          ierrp (1) = ierror
00257          ierrp (2) = n_send * n_corners
00258 
00259          ierror = PRISM_Error_Alloc
00260          call psmile_error ( ierror, 'corner2ind', &
00261                              ierrp, 2, __FILE__, __LINE__ )
00262          return
00263       endif
00264 !
00265       corner2ind (:, :) = undef
00266 !
00267 !===> Decode mask "found" of points found
00268 !     (cf. PSMILe_Trili_3d_extra_off)
00269 !
00270       code = 1
00271       k = 0
00272       do i = 1, n_corners
00273 
00274          do n = 1, n_send
00275             if (IAND (found(n), code) /= 0) then
00276 !
00277 !===> ...... Required "i-th" interpolation base was found.
00278 !            Corresponding value is stored in position "index_found(k)".
00279 !            index_found (k) == masked_out : Point is masked out
00280 !
00281                k = k + 1
00282                corner2ind (n, i) = index_found (k)
00283 !
00284             endif
00285          end do
00286 !
00287 !===> ... next interpolation base
00288 !
00289          code = code * 2
00290       end do ! i
00291 !
00292 #ifdef PRISM_ASSERTION
00293       if (k /= n_found) then
00294          print *, 'k, n_found', k, n_found
00295          call psmile_assert ( __FILE__, __LINE__, &
00296                  'k /= n_found')
00297       endif
00298 #endif
00299 !
00300 !===> Remove points from code "found" which are masked out
00301 !
00302       if (use_how /= PSMILE_novalue) then
00303 !
00304          code = 1
00305          do i = 1, n_corners
00306             do n = 1, n_send
00307                if (corner2ind (n,i) == masked_out) then
00308                   found (n) = found (n) - code
00309                endif
00310             end do
00311             code = code * 2
00312          end do ! i
00313       endif
00314 !
00315 !===> For each part
00316 !
00317 !     indices_req = Indices of the extra points in entire (!) list of
00318 !                   all points to be searched.
00319 !     required    = Code for the extra points
00320 !                   which are additionally required.
00321 !
00322       ip = 0
00323       do ipart = 1, search%npart
00324          if (len_req (ipart) > 0 .and. &
00325              len_nsend (ipart) > 0) then
00326 !
00327             indices_req => extra_search%indices_req(ipart)%vector
00328             required    => extra_search%required   (ipart)%vector
00329 !
00330 !===> ... Apply rules for points masked out
00331 !
00332             if (use_how == PSMILE_novalue) then
00333 !
00334 !                 If one neighbor is invalid reject all 
00335 !                 by moving all neighbors out of the valid range.
00336 
00337                do i = 1, n_corners
00338 !cdir vector
00339                   do n = 1, len_nsend (ipart)
00340                      if (corner2ind (ip+n,i) == masked_out) then
00341 !                       This point is not required any more
00342                         required (indices_returned (ip+n)) = 0
00343                         neighbors_3d (1, indices_req(indices_returned (ip+n)), &
00344                                       1:n_corners) = outside
00345                      endif
00346                   end do
00347                end do
00348             else 
00349 !
00350 ! HR: This should be work also for "use_how == PSMILE_novalue"
00351 !     "psmile_neigh_extra_points" should do the correct things in this case.
00352 !     TODO: TEST whether this statement is really correct.
00353 !
00354                do i = 1, n_corners
00355 !cdir vector
00356                   do n = 1, len_nsend (ipart)
00357 #ifdef DEBUG
00358                         print *, 'indices_returned', ip+n, indices_returned (ip+n), indices_req(indices_returned (ip+n))
00359                         print *, 'corner info', i, corner2ind (ip+n,i)
00360 #endif
00361                      if (corner2ind (ip+n,i) == masked_out) then
00362                         neighbors_3d (1, indices_req(indices_returned (ip+n)), &
00363                                       i) = outside
00364 #ifdef DEBUG_TRACE
00365                         if (indices_req(indices_returned (ip+n)) == ictl) then
00366                            print *, '#### psmile_add_points_found outside: ', outside
00367                            print *, '#### psmile_add_points_found ictl: set outside for ictl', ictl
00368                            print *, '#### psmile_add_points_found corner ', i
00369                            print *, ' -> neigh 1 ', neighbors_3d (1,indices_req(indices_returned (ip+n)),:)
00370                            print *, ' -> neigh 2 ', neighbors_3d (2,indices_req(indices_returned (ip+n)),:)
00371                            print *, ' -> neigh 3 ', neighbors_3d (3,indices_req(indices_returned (ip+n)),:)
00372                         endif
00373 #endif
00374                      endif
00375                   end do
00376                end do
00377             endif
00378 !
00379 !===> ... Get common points required by "found" and "required" and
00380 !         remove them from the coded list.
00381 !
00382 !cdir vector
00383             do n = 1, len_nsend (ipart)
00384                iband (n) = IAND (found (ip+n), required(indices_returned (ip+n)))
00385             end do
00386 !
00387 !cdir vector
00388             do n = 1, len_nsend (ipart)
00389                required(indices_returned (ip+n)) = &
00390                required(indices_returned (ip+n)) - iband (n)
00391             end do
00392 !
00393 !===> ... Set
00394 !         neighbors_3d (1, i) = "extra_search%global_marker" in order to mark
00395 !         that this is a point out of list of globally searched bases.
00396 !         neighbors_3d (2, i) = Index in list of globally searched bases.
00397 !
00398             code = 1
00399             do i = 1, n_corners
00400 !
00401 !cdir vector
00402                do n = 1, len_nsend (ipart)
00403                   if (IAND (iband(n), code) /= 0) then
00404 #ifdef DEBUG_TRACE
00405                      if (indices_req(indices_returned (ip+n)) == ictl) then
00406                         print *, '#### ictl:', ictl, ' set global marker and', corner2ind(ip+n, i)
00407                         print *, 'i, ip, indices_returned', &
00408                                   i, ip, indices_returned (ip+n), iband (n)
00409                      endif
00410 #endif
00411                      neighbors_3d (1,                              & 
00412                         indices_req(indices_returned (ip+n)), i) = &
00413                         extra_search%global_marker
00414 !
00415                      neighbors_3d (2,                              & 
00416                         indices_req(indices_returned (ip+n)), i) = &
00417                         corner2ind(ip+n, i)
00418                   else
00419 #ifdef DEBUG_TRACE
00420                      if (indices_req(indices_returned (ip+n)) == ictl) then
00421                         print *, '#### ictl:', ictl, ' global marker not set'
00422                         print *, 'i, ip, indices_returned', &
00423                                   i, ip, indices_returned (ip+n), iband (n), code
00424                      endif
00425 #endif
00426                   endif
00427                end do
00428 !
00429 !===> ... next interpolation base
00430 !
00431                code = code * 2
00432             end do
00433 !
00434 #ifdef PRISM_ASSERTION
00435 assert1:    do i = 1, n_corners
00436 !cdir vector
00437                do n = 1, len_nsend (ipart)
00438                   if (neighbors_3d (1, indices_req(indices_returned (ip+n)), i) &
00439                       == extra_search%global_marker .and. &
00440                       neighbors_3d (2, indices_req(indices_returned (ip+n)), i) &
00441                       <= 0)  exit assert1
00442                end do
00443             end do assert1
00444 !
00445             if (i <= n_corners) then
00446                print *, 'ipart, i, n', ipart, i, n, corner2ind(ip+n, i), &
00447                                        found(ip+n), iband(n)
00448                call psmile_assert ( __FILE__, __LINE__, &
00449                         'invalid index for interpolation base generated')
00450             endif
00451 #endif
00452          endif
00453 !
00454          ip = ip + len_nsend (ipart)
00455       end do ! ipart 
00456 !
00457 !===> All done
00458 !
00459 #ifdef VERBOSE
00460       print 9980, trim(ch_id), ierror
00461 
00462       call psmile_flushstd
00463 #endif /* VERBOSE */
00464 !
00465 !  Formats:
00466 !
00467 #ifdef VERBOSE
00468 
00469 9990 format (1x, a, ': psmile_add_points_found: n_send ', i6, &
00470              '; n_found ', i6)
00471 9980 format (1x, a, ': psmile_add_points_found: eof ierror =', i3)
00472 
00473 #endif /* VERBOSE */
00474 
00475 #ifdef DEBUG
00476 #endif
00477 
00478       end subroutine PSMILe_Add_points_found

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1