psmile_neigh_near_3d_reg_real.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2007-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PSMILe_Neigh_near_3d_reg_real
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_neigh_near_3d_reg_real (           &
00012                            grid_id,                        &
00013                            coords1, coords2, coords3,      &
00014                            x_coords, y_coords, z_coords,   &
00015                            coords_shape,                   &
00016                            mask_array, mask_shape,  mask_available,    &
00017                            sin_values_lon, cos_values_lon, &
00018                            sin_values_lat, cos_values_lat, &
00019                            grid_valid_shape, search_mode,  &
00020                            srclocs, nlocs, nloc, nprev,    &
00021                            neighbors_3d, num_neigh,        &
00022                            extra_search, ierror)
00023 !
00024 ! !USES:
00025 !
00026       use PRISM_constants
00027 !
00028       use PSMILe, dummy_interface => PSMILe_Neigh_near_3d_reg_real
00029 
00030       implicit none
00031 !
00032 ! !INPUT PARAMETERS:
00033 !
00034       Integer, Intent (In)            :: grid_id
00035 
00036 !     Link to the info on the component in which the donor cells
00037 !     should be searched.
00038 
00039       Integer, Intent (In)            :: nloc
00040 !
00041 !     Total number of locations to be transferred
00042 !
00043       Integer, Intent (In)            :: nlocs (ndim_3d)
00044 !
00045 !     Number of locations to be transferred with
00046 !     nlocs (1) = Number of locations in lon direction
00047 !     nlocs (2) = Number of locations in lat direction
00048 !     nlocs (3) = Number of locations in z   direction
00049 
00050       Integer, Intent (In)            :: nprev
00051 !
00052 !     Number of locations for which neighbours were already searched.
00053 !
00054       Type (integer_vector), Intent (In) :: srclocs (ndim_3d)
00055 
00056 !     Indices of the grid cell in which the point was found.
00057 !
00058       Real, Intent (In)               :: coords1 (nlocs(1),nlocs(2),nlocs(3))
00059       Real, Intent (In)               :: coords2 (nlocs(1),nlocs(2),nlocs(3))
00060       Real, Intent (In)               :: coords3 (nlocs(1),nlocs(2),nlocs(3))
00061 
00062 !     Coordinates of the target points (which were searched and found)
00063 !     Note: Target grids are full arrays which were generated 
00064 !           out of partial arrays.
00065 
00066       Integer, Intent (In)            :: coords_shape (2, ndim_3d)
00067 
00068 !     Dimension of coordinates (method) x_coords, ...
00069 
00070       Real, Intent (In)               :: x_coords(coords_shape(1,1): 
00071                                                   coords_shape(2,1))
00072       Real, Intent (In)               :: y_coords(coords_shape(1,2): 
00073                                                   coords_shape(2,2))
00074       Real, Intent (In)               :: z_coords(coords_shape(1,3): 
00075                                                   coords_shape(2,3))
00076 
00077 !     Coordinates of the method
00078 
00079       Integer, Intent (In)            :: mask_shape (2, ndim_3d)
00080 
00081 !     Dimension of (method) mask array
00082 
00083       Logical, Intent (In)            :: mask_array (mask_shape (1,1): 
00084                                                      mask_shape (2,1), 
00085                                                      mask_shape (1,2): 
00086                                                      mask_shape (2,2), 
00087                                                      mask_shape (1,3): 
00088                                                      mask_shape (2,3))
00089 !     Mask of the method
00090 
00091       Logical, Intent (In)            :: mask_available
00092 
00093 !     Is mask specified in array "mask_array" ?
00094 !     mask_available = .false. : Mask is not available
00095 !                      .true.  : Mask is     available
00096 
00097       Integer, Intent (In)            :: grid_valid_shape (2, ndim_3d)
00098 
00099 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00100 
00101       Real, Intent (In)               :: sin_values_lon (grid_valid_shape(1,1): 
00102                                                          grid_valid_shape(2,1))
00103       Real, Intent (In)               :: sin_values_lat (grid_valid_shape(1,2): 
00104                                                          grid_valid_shape(2,2))
00105 !
00106 !     Sin values of Longitudes and Latitudes (x_coords, y_coords)
00107 !
00108       Real, Intent (In)               :: cos_values_lon (grid_valid_shape(1,1): 
00109                                                          grid_valid_shape(2,1))
00110       Real, Intent (In)               :: cos_values_lat (grid_valid_shape(1,2): 
00111                                                          grid_valid_shape(2,2))
00112 !    
00113 !     Cos values of Longitudes and Latitudes (x_coords, y_coords)
00114 !
00115       Integer, Intent (In)            :: search_mode
00116 !
00117 !     Specifies the search mode for nearest neigbours with
00118 !        search_mode = 3 : Full 3d-search
00119 !        search_mode = 2 : Search in 2d-hyperplane (1st 2 direction lon, lat)
00120 !        search_mode = 1 : Search in 1d-plane
00121 !
00122       Integer, Intent (In)            :: num_neigh
00123 !
00124 !     Last dimension of neighbors array "neighbors_3d" and
00125 !     number of neighbors to be searched.
00126 !
00127 ! !INPUT/OUTPUT PARAMETERS:
00128 !
00129       Type (Extra_search_info)        :: extra_search
00130 !
00131 !     Number of locations where
00132 !       (*) required mask values were not true
00133 !
00134 ! !OUTPUT PARAMETERS:
00135 !
00136       Integer, Intent (Out)           :: neighbors_3d (ndim_3d, nloc, num_neigh)
00137 
00138 !     Indices of neighbor locations (interpolation bases)
00139 !
00140       integer, Intent (Out)           :: ierror
00141 
00142 !     Returns the error code of PSMILE_Neigh_near_3d_reg_real;
00143 !             ierror = 0 : No error
00144 !             ierror > 0 : Severe error
00145 !
00146 ! !DEFINED PARAMETERS:
00147 !
00148 !  NREF_3D = Number of locations in 3d to be controlled
00149 !          = 4 ** ndim_3d
00150 !  NREF_2D = Number of locations in 2d to be controlled
00151 !          = 4 ** ndim_2d
00152 !  NREF_1D = Number of locations in 1d to be controlled
00153 !          = 4 ** ndim_1d
00154 !
00155 !  lon   = Index of Longitudes in arrays "sin_values" and "cos_values"
00156 !  lat   = Index of Latitudes  in arrays "sin_values" and "cos_values"
00157 !  REAL_EARTH = Earth radius
00158 !
00159       Integer, Parameter              :: nref_3d = 4 * 4 * 4
00160       Integer, Parameter              :: nref_2d = 4 * 4
00161       Integer, Parameter              :: nref_1d = 4
00162       Integer, Parameter              :: lon = 1
00163       Integer, Parameter              :: lat = 2
00164 !
00165       Real, Parameter                 :: real_earth = 6400.0
00166 !
00167       Real, Parameter                 :: tol = 1d-6 ! muss argument werden
00168       Real, Parameter                 :: eps = 1d-6
00169       Real, Parameter                 :: acosp1 =  1.0
00170       Real, Parameter                 :: acosm1 = -1.0
00171 !
00172 ! !LOCAL VARIABLES
00173 !
00174 !     ... For locations controlled
00175 !
00176       Real                            :: sin_search_lon (nlocs(1))
00177       Real                            :: cos_search_lon (nlocs(1))
00178       Real                            :: sin_search_lat (nlocs(2))
00179       Real                            :: cos_search_lat (nlocs(2))
00180 !
00181       Integer                         :: nrefv (1:ndim_3d)
00182 !
00183 !     ... (1d) Indices in (entire) data to be extra searched
00184 !
00185       Integer                         :: leni, lenij
00186       Integer                         :: np
00187 !
00188 !     ... 3d Indices in local data to be extra searched
00189 !
00190       Integer                         :: i, j, k
00191       Integer                         :: ii, jj, kk
00192       Integer                         :: n, nref, nrefd
00193 !
00194       Integer                         :: ijk (ndim_3d)
00195       Integer                         :: ijk0 (ndim_3d)
00196       Integer                         :: ijkdst (ndim_3d, nref_3d)
00197       Integer                         :: ijkctl (ndim_3d, nref_3d)
00198       Integer                         :: irange (2, ndim_3d)
00199 !
00200 !     ... auxiliary arrays
00201 !
00202       Integer                         :: itemp (ndim_3d)
00203 !
00204 !     ... for mask values
00205 !
00206       Logical                         :: mask_dist (nref_3d)
00207 !
00208 !     ... for nearest neighbour control
00209 !
00210       Integer                         :: nfound
00211       Integer                         :: nmin (1)
00212 !
00213       Real                            :: real_huge
00214       Real                            :: dist, fac, val, z
00215       Real                            :: distance (nref_3d)
00216 #ifdef TODO
00217       Real                            :: dist_control
00218 #endif
00219 !
00220 ! !DESCRIPTION:
00221 !
00222 ! Subroutine "PSMILe_Neigh_near_3d_reg_real" searches the next "num_neigh"
00223 ! nearest neighbours on the method-grid (x_coords, y_coords, z_coords)
00224 ! on the the method-grid (x_coords, y_coords, z_coords)
00225 ! for the subgrid coords sent by the destination process.
00226 !
00227 ! There are 3 different of search modes supported by the routine:
00228 ! search_mode = 3: The nearest neighbours are searched are searched
00229 !                  within the 3d region.
00230 ! search_mode = 2: The nearest neighbours are searched only in the
00231 !                  2d hyperplane (lon- and lat-direction).
00232 ! search_mode = 1: The nearest neighbours are searched only in the
00233 !                  1d plane
00234 !
00235 ! Subroutine "PSMILe_Neigh_near_3d_reg_real" is designed for
00236 ! (*) grids of type "PRISM_Reglonlatvrt" and
00237 ! (*) source locations "srclocs" which are separately stored as
00238 !     3 1-dimensional vectors
00239 !     containing the 3d indices of the cells found for the target points
00240 !     "coords1, coords2, coords3" to be searched.
00241 
00242 !
00243 ! !REVISION HISTORY:
00244 !
00245 !   Date      Programmer   Description
00246 ! ----------  ----------   -----------
00247 ! 03.07.21    H. Ritzdorf  created
00248 !
00249 !EOP
00250 !----------------------------------------------------------------------
00251 !
00252 !  $Id: psmile_neigh_near_3d_reg_real.F90 2325 2010-04-21 15:00:07Z valcke $
00253 !  $Author: valcke $
00254 !
00255    Character(len=len_cvs_string), save :: mycvs = 
00256        '$Id: psmile_neigh_near_3d_reg_real.F90 2325 2010-04-21 15:00:07Z valcke $'
00257 !
00258 !----------------------------------------------------------------------
00259 !
00260 !  Relative control indices 
00261 !      
00262 #ifdef OLD
00263       Integer, Parameter              :: nrefd = 3 * 3 * 3
00264 !
00265       data ((ijkctl (i, n), i=1,ndim_3d), n = 1,nref_3d) &
00266                             /  0, 0, 0,                       &
00267                                1, 0, 0,   0, 1, 0,   0, 0, 1, &
00268                               -1, 0, 0,   0,-1, 0,   0, 0,-1, &
00269                               -1,-1, 0,   1,-1, 0,            &
00270                               -1, 1, 0,   1, 1, 0,            &
00271                               -1, 0,-1,   1, 0,-1,            &
00272                               -1, 0, 1,   1, 0, 1,            &
00273                                0,-1,-1,   0, 1,-1,            &
00274                                0,-1, 1,   0, 1, 1,            &
00275                               -1,-1,-1,   1,-1,-1,            &
00276                               -1, 1,-1,   1, 1,-1, &
00277                               -1,-1, 1,   1,-1, 1, &
00278                               -1, 1, 1,   1, 1, 1/
00279 #endif
00280 ! schoener waere eine liste, die weniger sortierung (s.o.) nachher verlangt
00281 ! veielleicht sollte man immer annehmen, dass ijk in der "Mitte" liegt
00282 !
00283       data ((ijkctl (i, n), i=1,ndim_3d), n = 1,nref_3d) &
00284             /  0, 0, 0,   1, 0, 0,   2, 0, 0,   3, 0, 0, &
00285                0, 1, 0,   1, 1, 0,   2, 1, 0,   3, 1, 0, &
00286                0, 2, 0,   1, 2, 0,   2, 2, 0,   3, 2, 0, &
00287                0, 3, 0,   1, 3, 0,   2, 3, 0,   3, 3, 0, &
00288                0, 0, 1,   1, 0, 1,   2, 0, 1,   3, 0, 1, &
00289                0, 1, 1,   1, 1, 1,   2, 1, 1,   3, 1, 1, &
00290                0, 2, 1,   1, 2, 1,   2, 2, 1,   3, 2, 1, &
00291                0, 3, 1,   1, 3, 1,   2, 3, 1,   3, 3, 1, &
00292                0, 0, 2,   1, 0, 2,   2, 0, 2,   3, 0, 2, &
00293                0, 1, 2,   1, 1, 2,   2, 1, 2,   3, 1, 2, &
00294                0, 2, 2,   1, 2, 2,   2, 2, 2,   3, 2, 2, &
00295                0, 3, 2,   1, 3, 2,   2, 3, 2,   3, 3, 2, &
00296                0, 0, 3,   1, 0, 3,   2, 0, 3,   3, 0, 3, &
00297                0, 1, 3,   1, 1, 3,   2, 1, 3,   3, 1, 3, &
00298                0, 2, 3,   1, 2, 3,   2, 2, 3,   3, 2, 3, &
00299                0, 3, 3,   1, 3, 3,   2, 3, 3,   3, 3, 3/
00300 !
00301       data nrefv /nref_1d, nref_2d, nref_3d/
00302 !                            
00303 !----------------------------------------------------------------------
00304 !
00305 !  Initialization
00306 !
00307 #ifdef VERBOSE
00308       print 9990, trim(ch_id)
00309 
00310       call psmile_flushstd
00311 #endif /* VERBOSE */
00312 !
00313       ierror = 0
00314 !
00315 #ifdef PRISM_ASSERTION
00316 !
00317 !===> Internal control
00318 !
00319       if (search_mode < 1 .or. search_mode > ndim_3d) then
00320          print *, trim(ch_id), " search_mode ", search_mode
00321          call psmile_assert (__FILE__, __LINE__, &
00322                              'search_mode is out of range ')
00323       endif
00324 !
00325       if (nloc < nprev + nlocs (1) * nlocs (2) * nlocs (3)) then
00326          print *, trim(ch_id), " nloc, nprev, nlocs ", nloc, nprev, nlocs
00327          call psmile_assert (__FILE__, __LINE__, &
00328                              'nloc < nprev + PRODUCT (nlocs) ')
00329       endif
00330 !
00331 !===> Are the locations within the correct shape ?
00332 !
00333          do j = 1, ndim_3d
00334 !cdir vector
00335             do i = 1, nlocs (j)
00336 !
00337             if (srclocs(j)%vector(i) < grid_valid_shape(1,j) - 1 .or. &
00338                 srclocs(j)%vector(i) > grid_valid_shape(2,j)) exit
00339             end do
00340 !
00341          if (i <= nlocs(j)) then
00342             print *, "Incorrect index in j, i", j, i, srclocs(j)%vector(i)
00343             call psmile_assert (__FILE__, __LINE__, &
00344                                 'wrong index')
00345          endif
00346          end do
00347 #endif
00348 !
00349       real_huge = huge (distance(1))
00350 !
00351 !===> Get number of reference points
00352 !
00353       nrefd = nrefv (search_mode)
00354 !
00355 !-----------------------------------------------------------------------
00356 !     Allocate and set temporary array which is used to transform
00357 !     the coordinates of poinst to be searched.
00358 !     (*) Longitudes and Latitudes are transformed
00359 !         from degrees into radients.
00360 !     (*) The z-values are currently not transformed
00361 !         ??? Whats about PRISM_Irrlonlat_sigmavrt, ...
00362 !
00363 !     Is it possible to save the values, in order to be reused.
00364 !-----------------------------------------------------------------------
00365 !
00366 !===> Note: It's used that the 3d-array coords? were generated by
00367 !           3 single regular vectors for PRISM Driver routines
00368 !
00369 !===> Compute values required to compute distances
00370 !
00371 !cdir vector
00372          do i = 1, nlocs (1)
00373          sin_search_lon (i) = coords1 (i, 1, 1) * real_deg2rad
00374          end do
00375 !
00376 !cdir vector
00377          do j = 1, nlocs (2)
00378          sin_search_lat (j) = coords2 (1, j, 1) * real_deg2rad
00379          end do
00380 !
00381       cos_search_lon = cos (sin_search_lon)
00382       cos_search_lat = cos (sin_search_lat)
00383 !
00384       sin_search_lon = sin (sin_search_lon)
00385       sin_search_lat = sin (sin_search_lat)
00386 !
00387 !-----------------------------------------------------------------------
00388 !     Compute distances
00389 !
00390 !     dist = (real_earth + coords3)*ACOS ( SIN(lat_coords)*SIN(lat_search) +
00391 !                                          COS(lat_coords)*COS(lat_search) *
00392 !                                         (COS(lon_coords)*COS(lon_search) +
00393 !                                          SIN(lon_coords)*SIN(lon_search)) )
00394 !     dist = SQRT(dist**2 + (coords3-z_coords) ** 2)
00395 !
00396 !     with xxx_search = Coordinates to be searched
00397 !     and  xxx_coords = Grid (Methods) coordinates (transformed)
00398 !
00399 ! Suchen mit 
00400 !                    nlev = Grids(grid_id)%nlev
00401 !                    Grids(grid_id)%mg_infos(lev)%real_arrays%chmin, &
00402 !                    Grids(grid_id)%mg_infos(lev)%real_arrays%chmax, &
00403 !
00404 !-----------------------------------------------------------------------
00405 !
00406       ijk0 = Grids(grid_id)%ijk0
00407       np = nprev
00408 !
00409          do k = 1, nlocs (3)
00410 !
00411 !
00412 !===>    ... Get coarse grid index on level nlev-2 and
00413 !            standard range to be controlled
00414 !
00415          if (search_mode < 3) then
00416             ijk(3) = srclocs(3)%vector(k)
00417             irange (:, 3) = ijk (3)
00418          else
00419             ijk(3) = ijk0(3) + ((srclocs(3)%vector(k) - ijk0(3)) / 4) * 4
00420             irange (1, 3) = max (ijk (3),   grid_valid_shape (1, 3))
00421             irange (2, 3) = min (ijk (3)+3, grid_valid_shape (2, 3))
00422          endif
00423 !
00424          z = coords3 (1, 1, k)
00425          fac = real_earth + z
00426 !
00427             do j = 1, nlocs (2)
00428 !
00429 !===>       ... Get coarse grid index on level nlev-2 and
00430 !               standard range to be controlled
00431 !
00432             if (search_mode < 2) then
00433                ijk(2) = srclocs(2)%vector(j)
00434                irange (:, 2) = ijk (2)
00435             else
00436                ijk(2) = ijk0(2) + ((srclocs(2)%vector(j) - ijk0(2)) / 4) * 4
00437                irange (1, 2) = max (ijk (2),   grid_valid_shape (1, 2))
00438                irange (2, 2) = min (ijk (2)+3, grid_valid_shape (2, 2))
00439             endif
00440 !
00441                do i = 1, nlocs (1)
00442 !
00443 !===>          ... Get coarse grid index on level nlev-2 and
00444 !                  standard range to be controlled
00445 !
00446                ijk(1) = ijk0(1) + ((srclocs(1)%vector(i) - ijk0(1)) / 4) * 4
00447 !
00448                irange (1, 1) = max (ijk(1),   grid_valid_shape (1, 1))
00449                irange (2, 1) = min (ijk(1)+3, grid_valid_shape (2, 1))
00450 !
00451                nref = (irange (2,1) - irange (1,1) + 1) * &
00452                       (irange (2,2) - irange (1,2) + 1) * &
00453                       (irange (2,3) - irange (1,3) + 1)
00454 !
00455                if (nref == nrefd) then
00456                      do n = 1, nrefd
00457                      ijkdst (:, n) = ijk + ijkctl (:, n)
00458                      end do
00459                else
00460 ! 
00461                   leni  =  irange (2, 1) - irange (1, 1) + 1
00462                   lenij = (irange (2, 2) - irange (1, 2) + 1) * leni 
00463 !
00464                      do kk = 1, irange (2,3)-irange(1,3) + 1
00465                      n = (kk-1)*lenij
00466                         do jj = 1, irange (2,2)-irange(1,2) + 1
00467 
00468                            do ii = 1, leni
00469                            ijkdst (1, n+ii) = irange(1,1) + ii - 1
00470                            end do ! ii
00471 
00472                         ijkdst (2, n+1:n+leni) = irange (1,2) + jj - 1
00473                         n = n + leni
00474                         end do ! jj
00475 
00476                      ijkdst (3, (kk-1)*lenij+1:kk*lenij) = irange (1,3) + kk - 1
00477                      end do ! kk
00478                endif
00479 !
00480 !====> ... Get Mask values if necessary
00481 !
00482                if (mask_available) then
00483 !cdir vector
00484                      do n = 1, nref
00485                      mask_dist (n) = mask_array (ijkdst (1,n), ijkdst (2,n), &
00486                                                  ijkdst (3,n))
00487                      end do
00488 !
00489                   n = count (mask_dist(1:nref))
00490 !
00491                   if (n == 0) then
00492 !                    no value available
00493 !
00494                      nref = 0
00495                      go to 10
00496                   endif
00497 !
00498                   if (n < nref) then
00499                      n = 0
00500                         do ii = 1, nref
00501                         if (mask_dist (ii)) then
00502                             n = n + 1
00503                             if (n /= ii) ijkdst (:, n) = ijkdst (:, ii)
00504                         endif
00505                         end do
00506                      nref = n
00507                   endif
00508                endif
00509 !
00510 !===> ... Compute distances to points
00511 !
00512 !cdir vector
00513                   do n = 1, nref
00514                   val = (  sin_values_lat(ijkdst (2,n)) * sin_search_lat(j)  &
00515                         +  cos_values_lat(ijkdst (2,n)) * cos_search_lat(j)  &
00516                         * (cos_values_lon(ijkdst (1,n)) * cos_search_lon(i)  &
00517                           +sin_values_lon(ijkdst (1,n)) * sin_search_lon(i)) )
00518    
00519 #ifdef PRISM_ASSERTION
00520                   if (val < acosm1 - eps .or. val > acosp1 + eps) then
00521                      print *, i, j, k, val
00522                      call psmile_assert (__FILE__, __LINE__, &
00523                                          'invalid value for acos')
00524                   endif
00525 #endif
00526                   val = min (acosp1, val)
00527                   val = max (acosm1, val)
00528 
00529                   dist = fac * acos (val)
00530 
00531                   distance (n) = dist*dist + (z-z_coords(ijkdst (3,n)))**2
00532 #ifdef DEBUG2
00533                   if (i == 1 .and. j == 1 .and. k == 1) then
00534                      print *, 'dist, diff', dist, &
00535                               z-z_coords(ijkdst (3,n))
00536                   endif
00537 #endif
00538                   end do ! n
00539 !
00540                nmin = minloc (distance(1:nref))
00541 #ifdef MINLOCFIX
00542                if (nmin(1).eq.0) nmin=1
00543 #endif /* MINLOCFIX */
00544 !
00545 #ifdef DEBUG2
00546                if (i == 1 .and. j == 1 .and. k == 1) then
00547                   print *, 'psmile_neigh_near_3d_reg_real: ictl =', i, j, k, np
00548                   print *, 'ijkdst and distance:'
00549                      do n = 1, nref
00550                      print *, ijkdst (:, n), distance (n)
00551                      end do
00552                endif
00553 #endif
00554 !
00555 !===> ... Special case: Minimal distance == 0
00556 !
00557                if (distance(nmin(1)) <= tol) then
00558                   neighbors_3d (:, np+i, 1) = ijkdst (:, nmin(1))
00559 !
00560                      do n = 2, num_neigh
00561                      neighbors_3d (:, np+i, n) = grid_valid_shape (1, :) - 1
00562                      end do
00563 !
00564                   cycle
00565                endif
00566 !
00567 !===> ... Sort distances (silly sort)
00568 !         Da muss noch etwas besseres her !
00569 !
00570 10             continue
00571 !
00572                nfound = min (num_neigh, nref)
00573                if (nfound < num_neigh) then
00574                   distance(nfound+1:num_neigh) = real_huge
00575 
00576                      do n = nfound+1, num_neigh
00577                      ijkdst (:, n) = grid_valid_shape (1, :) - 1
00578                      end do
00579                endif
00580 !
00581                   do n = 1, nfound
00582 !
00583                   nmin = minloc (distance(n:nref))
00584 #ifdef MINLOCFIX
00585                   if (nmin(1).eq.0) nmin=1
00586 #endif /* MINLOCFIX */
00587 !
00588                   if (nmin(1) /= 1) then
00589                      jj = n + nmin (1) - 1
00590 !
00591                      itemp  (:)    = ijkdst (:, n)
00592                      ijkdst (:, n) = ijkdst (:, jj)
00593                      ijkdst (:, jj) = itemp  (:)
00594 !
00595                      dist = distance (n)
00596                      distance (n) = distance (jj)
00597                      distance (jj) = dist
00598                   endif
00599                   end do
00600 !
00601 #ifdef PRISM_ASSERTION
00602                   do n = 1, nfound-1
00603                   if (distance(n) > distance (n+1)) exit
00604                   end do
00605 !
00606                if (n <= nfound-1) then
00607                   print *, 'n =' , n
00608                   print *, 'distance (n)  ', distance (n)
00609                   print *, 'distance (n+1)', distance (n+1)
00610                   print *, 'distance', distance (1:nfound)
00611                   call psmile_assert (__FILE__, __LINE__, &
00612                                       'incorrect sort')
00613                endif
00614 #endif
00615 !
00616 !===> ... Use multigrid info for search in order regions
00617 !
00618 #ifdef TODO
00619                dist_control = distance (num_neigh)
00620 !
00621                call psmile_mg_search_nneigh_3d_reg_real (distance, ijkdst, num_neigh, &
00622                            grid_id, ierror)
00623 #endif /* TODO */
00624 !
00625 !===> ... End of search; fill neighbors_3d
00626 !
00627                   do n = 1, num_neigh
00628                   neighbors_3d (:, np+i, n) = ijkdst (:, n)
00629                   end do
00630 !
00631                end do ! i
00632 
00633             np = np + nlocs (1)
00634             end do ! j
00635          end do ! k
00636 !
00637 !===> All done
00638 !
00639 #ifdef VERBOSE
00640       print 9980, trim(ch_id), ierror
00641 
00642       call psmile_flushstd
00643 #endif /* VERBOSE */
00644 !
00645 !  Formats:
00646 !
00647 9990 format (1x, a, ': psmile_neigh_near_3d_reg_real')
00648 9980 format (1x, a, ': psmile_neigh_near_3d_reg_real: eof, ierror =', i3)
00649 
00650       end subroutine PSMILe_Neigh_near_3d_reg_real

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1