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

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1