psmile_neigh_near_3d_irr3_dble.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_irr3_dble
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_neigh_near_3d_irr3_dble (          &
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                            srcloc, nsearch,                &
00021                            nloc, nprev,                    &
00022                            neighbors_3d, num_neigh,        &
00023                            extra_search, ierror)
00024 !
00025 ! !USES:
00026 !
00027       use PRISM_constants
00028 !
00029       use PSMILe, dummy_interface => PSMILe_Neigh_near_3d_irr3_dble
00030 
00031       implicit none
00032 !
00033 ! !INPUT PARAMETERS:
00034 !
00035       Integer, Intent (In)            :: grid_id
00036 
00037 !     Link to the info on the component in which the donor cells
00038 !     should be searched.
00039 
00040       Integer, Intent (In)            :: nloc
00041 !
00042 !     Total number of locations to be transferred
00043 !
00044       Integer, Intent (In)            :: nprev
00045 !
00046 !     Number of locations for which neighbours were already searched.
00047 !
00048       Integer, Intent (In)            :: nsearch
00049 !
00050 !     Number of locations for which neighbours should be searched in this
00051 !     sweep.
00052 !
00053       Integer, Intent (In)            :: srcloc (ndim_3d, nloc)
00054 
00055 !     Indices of the grid cell in which the point was found.
00056 !
00057       Double Precision, Intent (In)   :: coords1 (nloc)
00058       Double Precision, Intent (In)   :: coords2 (nloc)
00059       Double Precision, Intent (In)   :: coords3 (nloc)
00060 
00061 !     Coordinates of the target points (which were searched and found)
00062 
00063       Integer, Intent (In)            :: coords_shape (2, ndim_3d)
00064 
00065 !     Dimension of coordinates (method) x_coords, ...
00066 
00067       Double Precision, Intent (In)   :: x_coords(coords_shape(1,1): 
00068                                                   coords_shape(2,1))
00069       Double Precision, Intent (In)   :: y_coords(coords_shape(1,2): 
00070                                                   coords_shape(2,2))
00071       Double Precision, Intent (In)   :: z_coords(coords_shape(1,3): 
00072                                                   coords_shape(2,3))
00073 
00074 !     Coordinates of the method
00075 
00076       Integer, Intent (In)            :: mask_shape (2, ndim_3d)
00077 
00078 !     Dimension of (method) mask array
00079 
00080       Logical, Intent (In)            :: mask_array (mask_shape (1,1): 
00081                                                      mask_shape (2,1), 
00082                                                      mask_shape (1,2): 
00083                                                      mask_shape (2,2), 
00084                                                      mask_shape (1,3): 
00085                                                      mask_shape (2,3))
00086 !     Mask of the method
00087 
00088       Logical, Intent (In)            :: mask_available
00089 
00090 !     Is mask specified in array "mask_array" ?
00091 !     mask_available = .false. : Mask is not available
00092 !                      .true.  : Mask is     available
00093 
00094       Integer, Intent (In)            :: grid_valid_shape (2, ndim_3d)
00095 
00096 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00097 
00098       Double Precision, Intent (In)   :: sin_values_lon (grid_valid_shape(1,1): 
00099                                                          grid_valid_shape(2,1))
00100       Double Precision, Intent (In)   :: sin_values_lat (grid_valid_shape(1,2): 
00101                                                          grid_valid_shape(2,2))
00102 !
00103 !     Sin values of Longitudes and Latitudes (x_coords, y_coords)
00104 !
00105       Double Precision, Intent (In)   :: cos_values_lon (grid_valid_shape(1,1): 
00106                                                          grid_valid_shape(2,1))
00107       Double Precision, Intent (In)   :: cos_values_lat (grid_valid_shape(1,2): 
00108                                                          grid_valid_shape(2,2))
00109 !    
00110 !     Cos values of Longitudes and Latitudes (x_coords, y_coords)
00111 !
00112       Integer, Intent (In)            :: search_mode
00113 !
00114 !     Specifies the search mode for nearest neigbours with
00115 !        search_mode = 3 : Full 3d-search
00116 !        search_mode = 2 : Search in 2d-hyperplane (1st 2 direction lon, lat)
00117 !        search_mode = 1 : Search in 1d-plane
00118 !
00119       Integer, Intent (In)            :: num_neigh
00120 !
00121 !     Last dimension of neighbors array "neighbors_3d" and
00122 !     number of neighbors to be searched.
00123 !
00124 ! !INPUT/OUTPUT PARAMETERS:
00125 !
00126       Type (Extra_search_info)        :: extra_search
00127 !
00128 !     Number of locations where
00129 !       (*) required mask values were not true
00130 !
00131 ! !OUTPUT PARAMETERS:
00132 !
00133       Integer, Intent (Out)           :: neighbors_3d (ndim_3d, nloc, num_neigh)
00134 
00135 !     Indices of neighbor locations (interpolation bases)
00136 !
00137       Integer, Intent (Out)           :: ierror
00138 
00139 !     Returns the error code of PSMILe_Neigh_near_3d_irr3_dble;
00140 !             ierror = 0 : No error
00141 !             ierror > 0 : Severe error
00142 !
00143 ! !DEFINED PARAMETERS:
00144 !
00145 !  NREF_3D = Number of locations in 3d to be controlled
00146 !          = 4 ** ndim_3d
00147 !  NREF_2D = Number of locations in 2d to be controlled
00148 !          = 4 ** ndim_2d
00149 !  NREF_1D = Number of locations in 1d to be controlled
00150 !          = 4 ** ndim_1d
00151 !
00152 !  lon   = Index of Longitudes in arrays "sin_values" and "cos_values"
00153 !  lat   = Index of Latitudes  in arrays "sin_values" and "cos_values"
00154 !  REAL_EARTH = Earth radius
00155 !
00156       Integer, Parameter              :: nref_3d = 4 * 4 * 4
00157       Integer, Parameter              :: nref_2d = 4 * 4
00158       Integer, Parameter              :: nref_1d = 4
00159       Integer, Parameter              :: lon = 1
00160       Integer, Parameter              :: lat = 2
00161 !
00162       Double Precision, Parameter     :: dble_earth = 6400.0
00163 !
00164       Double Precision, Parameter     :: tol = 1d-6 ! muss argument werden
00165       Double Precision, Parameter     :: eps = 1d-6
00166       Double Precision, Parameter     :: acosp1 =  1.0d0
00167       Double Precision, Parameter     :: acosm1 = -1.0d0
00168 !
00169 ! !LOCAL VARIABLES
00170 !
00171 !     ... For locations controlled
00172 !
00173       Double Precision, Pointer       :: sin_search (:, :)
00174       Double Precision, Pointer       :: cos_search (:, :)
00175 !
00176       Integer                         :: nrefv (1:ndim_3d)
00177 !
00178 !     ... (1d) Indices in (entire) data to be extra searched
00179 !
00180       Integer                         :: ibeg, iend
00181       Integer                         :: leni, lenij
00182 !
00183 !     ... 3d Indices in local data to be extra searched
00184 !
00185       Integer                         :: i, ipart
00186       Integer                         :: ii, jj, kk
00187       Integer                         :: n, nref, nrefd, sd
00188 !
00189       Integer, Pointer                :: ijk (:, :)
00190       Integer                         :: ijk0 (ndim_3d)
00191       Integer                         :: ijkdst (ndim_3d, nref_3d)
00192       Integer                         :: ijkctl (ndim_3d, nref_3d)
00193       Integer                         :: irange (2, ndim_3d)
00194       Integer                         :: width (ndim_3d)
00195 !
00196 !     ... auxiliary arrays
00197 !
00198       Integer                         :: itemp (ndim_3d)
00199 !
00200 !     ... for mask values
00201 !
00202       Logical                         :: mask_dist (nref_3d)
00203 !
00204 !     ... for nearest neighbour control
00205 !
00206       Integer                         :: nfound
00207       Integer                         :: nmin (1)
00208 !
00209       Double Precision                :: dble_huge
00210       Double Precision                :: dist, fac, val
00211       Double Precision                :: distance (nref_3d)
00212 #ifdef TODO
00213       Double Precision                :: dist_control
00214 #endif
00215 !
00216 !     ... for error handling
00217 !
00218       Integer, Parameter              :: nerrp = 2
00219       Integer                         :: ierrp (nerrp)
00220 !
00221 ! !DESCRIPTION:
00222 !
00223 ! Subroutine "PSMILe_Neigh_near_3d_irr3_dble" searches the next "num_neigh"
00224 ! nearest neighbours on 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_irr3_dble" is designed for
00236 ! (*) grids of type "PRISM_Reglonlatvrt" and
00237 ! (*) source locations "srcloc" which are stored as
00238 !     3-dimensional vector
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_irr3_dble.F90 2868 2011-01-10 15:45:22Z hanke $
00253 !  $Author: hanke $
00254 !
00255    Character(len=len_cvs_string), save :: mycvs = 
00256        '$Id: psmile_neigh_near_3d_irr3_dble.F90 2868 2011-01-10 15:45:22Z hanke $'
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       ibeg = nprev + 1
00316       iend = nprev + nsearch
00317 !
00318 #ifdef PRISM_ASSERTION
00319 !
00320 !===> Internal control
00321 !
00322       if (search_mode < 1 .or. search_mode > ndim_3d) then
00323          print *, trim(ch_id), " search_mode ", search_mode
00324          call psmile_assert (__FILE__, __LINE__, &
00325                              'search_mode is out of range ')
00326       endif
00327 !
00328       if (nloc < iend ) then
00329          print *, trim(ch_id), " nloc, nprev, nsearch ", nloc, nprev, nsearch
00330          call psmile_assert (__FILE__, __LINE__, &
00331                              'nloc < nprev + PRODUCT (nlocs) ')
00332       endif
00333 !
00334 !===> Are the locations within the correct shape ?
00335 !
00336 !cdir vector
00337       do i = ibeg, iend
00338 !
00339          if (srcloc(1,i) < coords_shape(1,1) - 1 .or. &
00340              srcloc(1,i) > coords_shape(2,1)     .or. &
00341              srcloc(2,i) < coords_shape(1,2) - 1 .or. &
00342              srcloc(2,i) > coords_shape(2,2)     .or. &
00343              srcloc(3,i) < coords_shape(1,3)     .or. &
00344              srcloc(3,i) > coords_shape(2,3)) exit
00345       end do
00346 !
00347       if (i <= iend) then
00348          print *, "i, ibeg, iend", i, ibeg, iend
00349          print *, "srcloc ", srcloc(:, i)
00350          print *, "shape  ", coords_shape
00351          call psmile_assert (__FILE__, __LINE__, &
00352                              'wrong index in srcloc')
00353       endif
00354 #endif
00355 !
00356       dble_huge = huge (distance(1))
00357 !
00358 !===> Get number of reference points
00359 !
00360       nrefd = nrefv (search_mode)
00361 !
00362 !-----------------------------------------------------------------------
00363 !     Allocate and set temporary array which is used to transform
00364 !     the coordinates of poinst to be searched.
00365 !     (*) Longitudes and Latitudes are transformed
00366 !         from degrees into radients.
00367 !     (*) The z-values are currently not transformed
00368 !         ??? Whats about PRISM_Irrlonlat_sigmavrt, ...
00369 !
00370 !     Is it possible to save the values, in order to be reused.
00371 !-----------------------------------------------------------------------
00372 !
00373       Allocate (sin_search(ibeg:iend, lat), STAT = ierror)
00374 
00375       if ( ierror > 0 ) then
00376          ierrp (1) = ierror
00377          ierrp (2) = nsearch * lat
00378 
00379          ierror = PRISM_Error_Alloc
00380          call psmile_error ( ierror, 'sin_search', &
00381                              ierrp, 2, __FILE__, __LINE__ )
00382          return
00383       endif
00384 
00385       Allocate (cos_search(ibeg:iend, lat), STAT = ierror)
00386 
00387       if ( ierror > 0 ) then
00388          ierrp (1) = ierror
00389          ierrp (2) = nsearch * lat
00390 
00391          ierror = PRISM_Error_Alloc
00392          call psmile_error ( ierror, 'cos_search', &
00393                              ierrp, 2, __FILE__, __LINE__ )
00394          return
00395       endif
00396 
00397       Allocate (ijk(ndim_3d, ibeg:iend), STAT = ierror)
00398 
00399       if ( ierror > 0 ) then
00400          ierrp (1) = ierror
00401          ierrp (2) = nsearch * ndim_3d
00402 
00403          ierror = PRISM_Error_Alloc
00404          call psmile_error ( ierror, 'ijk', &
00405                              ierrp, 2, __FILE__, __LINE__ )
00406          return
00407       endif
00408 !
00409 !===> Compute values required to compute distances
00410 !
00411 !cdir vector
00412       do i = ibeg, iend
00413          sin_search (i, lon) = coords1 (i) * dble_deg2rad
00414       end do
00415 !
00416 !cdir vector
00417       do i = ibeg, iend
00418          sin_search (i, lat) = coords2 (i) * dble_deg2rad
00419       end do
00420 !
00421       cos_search = cos (sin_search)
00422       sin_search = sin (sin_search)
00423 !
00424 !-----------------------------------------------------------------------
00425 !     Compute distances
00426 !
00427 !     dist = (dble_earth + coords3)*ACOS ( SIN(lat_coords)*SIN(lat_search) +
00428 !                                          COS(lat_coords)*COS(lat_search) *
00429 !                                         (COS(lon_coords)*COS(lon_search) +
00430 !                                          SIN(lon_coords)*SIN(lon_search)) )
00431 !     dist = SQRT(dist**2 + (coords3-z_coords) ** 2)
00432 !
00433 !     with xxx_search = Coordinates to be searched
00434 !     and  xxx_coords = Grid (Methods) coordinates (transformed)
00435 !
00436 ! Suchen mit 
00437 !                    nlev = Grids(grid_id)%nlev
00438 !                    Grids(grid_id)%mg_infos(lev)%double_arrays%chmin, &
00439 !                    Grids(grid_id)%mg_infos(lev)%double_arrays%chmax, &
00440 !
00441 !-----------------------------------------------------------------------
00442 !
00443       ijk0 = Grids(grid_id)%ijk0
00444       sd = search_mode
00445 !
00446       width (1:sd) = 3
00447 !
00448 !===> Get coarse grid index on level nlev-2
00449 !
00450       do i = 1, sd
00451          ijk (i, ibeg:iend) = ijk0(i) + &
00452                               ((srcloc(i, ibeg:iend) - ijk0(i)) / 4) * 4
00453       end do ! i
00454 !
00455       do i = sd+1, ndim_3d
00456             ijk (i, ibeg:iend) = srcloc (i, ibeg:iend)
00457             width (i) = 0
00458       end do ! i
00459 !
00460 !===> Compute distances for each point in (ibeg:iend)
00461 !
00462       do ipart = ibeg, iend, 5000
00463 !cdir vector loopcnt=5000
00464       do i = ipart, min(iend, ipart+5000-1)
00465 !
00466 !===> ... Get standard range to be controlled
00467 !
00468          irange (1, :) = max (ijk(:,i),          grid_valid_shape (1, :))
00469          irange (2, :) = min (ijk(:,i)+width(:), grid_valid_shape (2, :))
00470 !
00471          nref = (irange (2,1) - irange (1,1) + 1) * &
00472                 (irange (2,2) - irange (1,2) + 1) * &
00473                 (irange (2,3) - irange (1,3) + 1)
00474 !
00475 !===> ... Set indices to be controlled
00476 !
00477          if (nref == nrefd) then
00478             do n = 1, nref
00479                ijkdst (:, n) = ijk (:, i) + ijkctl (:, n)
00480             end do
00481          else
00482 ! 
00483             leni  =  irange (2, 1) - irange (1, 1) + 1
00484             lenij = (irange (2, 2) - irange (1, 2) + 1) * leni 
00485 !
00486             do kk = 1, irange (2,3)-irange(1,3) + 1
00487                n = (kk-1)*lenij
00488                do jj = 1, irange (2,2)-irange(1,2) + 1
00489 
00490                   do ii = 1, leni
00491                      ijkdst (1, n+ii) = irange(1,1) + ii - 1
00492                   end do ! ii
00493 
00494                   ijkdst (2, n+1:n+leni) = irange (1,2) + jj - 1
00495                   n = n + leni
00496                end do ! jj
00497 
00498                ijkdst (3, (kk-1)*lenij+1:kk*lenij) = irange (1,3) + kk - 1
00499             end do ! kk
00500          endif
00501 !
00502 !====> ... Get Mask values if necessary
00503 !
00504          if (mask_available) then
00505 !cdir vector
00506             do n = 1, nref
00507                mask_dist (n) = mask_array (ijkdst (1,n), ijkdst (2,n), &
00508                                            ijkdst (3,n))
00509             end do
00510 !
00511             n = count (mask_dist(1:nref))
00512 !
00513             if (n == 0) then
00514 !              no value available
00515 !
00516                nref = 0
00517                go to 10
00518             endif
00519 !
00520             if (n < nref) then
00521                n = 0
00522                do ii = 1, nref
00523                   if (mask_dist (ii)) then
00524                       n = n + 1
00525                       if (n /= ii) ijkdst (:, n) = ijkdst (:, ii)
00526                   endif
00527                end do
00528                nref = n
00529             endif
00530          endif
00531 !
00532 !===> ... Compute distances to points
00533 !
00534          fac = dble_earth + coords3 (i)
00535 !
00536 !cdir vector
00537          do n = 1, nref
00538             val = (  sin_values_lat(ijkdst (2,n)) * sin_search(i,lat)  &
00539                   +  cos_values_lat(ijkdst (2,n)) * cos_search(i,lat)  &
00540                   * (cos_values_lon(ijkdst (1,n)) * cos_search(i,lon)  &
00541                      +sin_values_lon(ijkdst (1,n)) * sin_search(i,lon)) )
00542 
00543 #ifdef PRISM_ASSERTION
00544             if (val < acosm1 - eps .or. val > acosp1 + eps) then
00545                print *, i, val
00546                call psmile_assert (__FILE__, __LINE__, &
00547                                    'invalid value for acos')
00548             endif
00549 #endif
00550             val = min (acosp1, val)
00551             val = max (acosm1, val)
00552 
00553             dist = fac * acos (val)
00554 
00555             distance (n) = dist*dist +                                 &
00556                            ( coords3 (i)-z_coords(ijkdst (3,n)))**2
00557 #ifdef DEBUG2
00558             if (i == 2) then
00559                print *, 'dist, diff', dist, &
00560                      coords3 (i)-z_coords(ijkdst (3,n))
00561             endif
00562 #endif
00563          end do ! n
00564 !
00565          nmin = minloc (distance(1:nref))
00566 #ifdef MINLOCFIX
00567          if (nmin(1).eq.0) nmin=1
00568 #endif /* MINLOCFIX */
00569 !
00570 #ifdef DEBUG2
00571          if (i == 2) then
00572             print *, 'psmile_neigh_near_3d_irr3_dble: ictl =', i
00573             print *, 'ijkdst and distance:'
00574             do n = 1, nref
00575                print *, ijkdst (:, n), distance (n)
00576             end do
00577          endif
00578 #endif
00579 !
00580 !===> ... Special case: Minimal distance == 0
00581 !
00582          if (distance(nmin(1)) <= tol) then
00583             neighbors_3d (:, i, 1) = ijkdst (:, nmin(1))
00584 !
00585             do n = 2, num_neigh
00586                neighbors_3d (:, i, n) = grid_valid_shape (1, :) - 1
00587             end do
00588 !
00589             cycle
00590          endif
00591 !
00592 !===> ... Sort distances (silly sort)
00593 !         Da muss noch etwas besseres her !
00594 !
00595 10       continue
00596 !
00597          nfound = min (num_neigh, nref)
00598          if (nfound < num_neigh) then
00599             distance(nfound+1:num_neigh) = dble_huge
00600 
00601             do n = nfound+1, num_neigh
00602                ijkdst (:, n) = grid_valid_shape (1, :) - 1
00603             end do
00604          endif
00605 !
00606          do n = 1, nfound
00607 !
00608             nmin = minloc (distance(n:nref))
00609 #ifdef MINLOCFIX
00610             if (nmin(1).eq.0) nmin=1
00611 #endif /* MINLOCFIX */
00612 !
00613             if (nmin(1) /= 1) then
00614                jj = n + nmin (1) - 1
00615 !
00616                itemp  (:)    = ijkdst (:, n)
00617                ijkdst (:, n) = ijkdst (:, jj)
00618                ijkdst (:, jj) = itemp  (:)
00619 !
00620                dist = distance (n)
00621                distance (n) = distance (jj)
00622                distance (jj) = dist
00623             endif
00624          end do ! n
00625 !
00626 #ifdef PRISM_ASSERTION
00627          do n = 1, nfound-1
00628             if (distance(n) > distance (n+1)) exit
00629          end do
00630 !
00631          if (n <= nfound-1) then
00632             print *, 'n =' , n
00633             print *, 'distance (n)  ', distance (n)
00634             print *, 'distance (n+1)', distance (n+1)
00635             print *, 'distance', distance (1:nfound)
00636             call psmile_assert (__FILE__, __LINE__, &
00637                                 'incorrect sort')
00638          endif
00639 #endif
00640 !
00641 !===> ... Use multigrid info for search in order regions
00642 !
00643 #ifdef TODO
00644          dist_control = distance (num_neigh)
00645 !
00646          call psmile_mg_search_nneigh_3d_irr3_dble (distance, ijkdst, num_neigh, &
00647                   grid_id, ierror)
00648 #endif /* TODO */
00649 !
00650 !===> ... End of search; fill neighbors_3d
00651 !
00652          do n = 1, num_neigh
00653             neighbors_3d (:, i, n) = ijkdst (:, n)
00654          end do
00655 !
00656       end do ! i
00657       end do
00658 !
00659 !===> Deallocate memory
00660 !
00661       Deallocate (ijk)
00662       Deallocate (cos_search)
00663       Deallocate (sin_search)
00664 !
00665 !===> All done
00666 !
00667 #ifdef VERBOSE
00668       print 9980, trim(ch_id), ierror
00669 
00670       call psmile_flushstd
00671 #endif /* VERBOSE */
00672 !
00673 !  Formats:
00674 !
00675 9990 format (1x, a, ': psmile_neigh_near_3d_irr3_dble')
00676 9980 format (1x, a, ': psmile_neigh_near_3d_irr3_dble: eof, ierror =', i3)
00677 
00678       end subroutine PSMILe_Neigh_near_3d_irr3_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1