psmile_mg_srch_nneigh_reg_dble.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 !
00008 ! !ROUTINE: PSMILe_MG_srch_nneigh_reg_dble
00009 !
00010 subroutine psmile_mg_srch_nneigh_reg_dble (grid_id, nn_srch,    &
00011                 arrays, search_mode, nref_3d, grid_valid_shape, &
00012                 neighbors_3d, nloc, num_neigh,                  &
00013                 sin_search, cos_search, z_search,               &
00014                 dist_dble, dim1, indices, jbeg, jend,           &
00015                 mask_array, mask_shape, mask_available,         &
00016                 tol, ierror)
00017 !
00018 ! !USES:
00019 !
00020   use PRISM_constants
00021 !
00022   use PSMILe, dummy_interface => PSMILe_MG_srch_nneigh_reg_dble
00023 
00024   implicit none
00025 !
00026 ! !INPUT PARAMETERS:
00027 !
00028       Integer, Intent (In)            :: grid_id
00029 !
00030 !     Info on the component in which the donor cells
00031 !     should be searched.
00032 !
00033       Type (Extra_search_nn), Intent (In) :: nn_srch
00034 !
00035 !     Info about the size of the coarse grid problem
00036 !
00037       Type (Extra_search_dble)        :: arrays
00038 !
00039 !     Memory for metric information
00040 !
00041       Integer, Intent (In)            :: nref_3d
00042 !
00043 !     Something like the maximum number of neighbor to be searched for
00044 !
00045       Integer, Intent (In)            :: search_mode
00046 !
00047 !     Specifies the search mode for nearest neigbours with
00048 !        search_mode = 3 : Full 3d-search
00049 !        search_mode = 2 : Search in 2d-hyperplane (1st 2nd direction lon, lat)
00050 !        search_mode = 1 : Search in 1d-plane
00051 !
00052       Integer, Intent (In)            :: grid_valid_shape (2, ndim_3d)
00053 !
00054 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00055 
00056       Integer, Intent (In)            :: nloc
00057 !
00058 !     Second dimension of neighbors array "neighbors_3d" and
00059 !     Total number of locations to be transferred
00060 !
00061       Integer, Intent (In)            :: num_neigh
00062 !
00063 !     Number of neighbors to be searched.
00064 !     Last dimension of neighbors array "neighbors_3d" and
00065 !     number of neighbors to be searched.
00066 !
00067       Integer,          Intent (In)   :: jbeg, jend
00068 !
00069 !     Shape of input arrays
00070 !
00071       Integer, Parameter              :: lat = 2
00072       Double Precision, Intent (In)   :: sin_search (jbeg:jend, lat)
00073 !
00074 !     Sin values of the points for which the nearest neighbours
00075 !     should be searched.
00076 !
00077       Double Precision, Intent (In)   :: cos_search (jbeg:jend, lat)
00078 !
00079 !     Cos values of the points for which the nearest neighbours
00080 !     should be searched.
00081 !
00082       Double Precision, Intent (In)   :: z_search (jbeg:jend)
00083 !
00084 !     Z values of the points for which the nearest neighbours
00085 !     should be searched.
00086 !
00087       Integer, Intent (In)            :: dim1 (2)
00088 !
00089 !     Dimensions of "dist_dble" in first direction 
00090 !
00091       Integer, Intent (In)            :: indices (:)
00092 !
00093 !     Indices of the extra points in entire list of all points to be
00094 !     searched
00095 !
00096       Integer, Intent (In)            :: mask_shape (2, ndim_3d)
00097 !
00098 !    Dimension of (method) mask array
00099 !
00100       Logical, Intent (In)            :: 
00101          mask_array (mask_shape (1,1):mask_shape (2,1), 
00102                      mask_shape (1,2):mask_shape (2,2), 
00103                      mask_shape (1,3):mask_shape (2,3))
00104 !
00105 !    Mask of the method
00106 !
00107       Logical, Intent (In)             :: mask_available
00108 !
00109 !    Is mask specified in array "mask_array" ?
00110 !    mask_available = .false. : Mask is not available
00111 !                     .true.  : Mask is     available
00112 !
00113       Double Precision, Intent (In)    :: tol
00114 !
00115 !    Some tolerance may be used later to evaluate distances
00116 !
00117 ! !INPUT/OUTPUT PARAMETERS:
00118 !
00119       Double Precision, Intent (InOut) :: dist_dble (dim1(1):dim1(2), num_neigh)
00120 !
00121 !    Initial distances and final distances
00122 !
00123       Integer,           Intent (Out) :: neighbors_3d (ndim_3d, nloc, num_neigh)
00124 
00125 !     Indices of neighbor locations (interpolation bases)
00126 !     Index array for points that have been found
00127 !
00128 ! !OUTPUT PARAMETERS:
00129 !
00130      Integer, Intent (Out)           :: ierror
00131 
00132 !    Returns the error code of PSMILE_Neigh_nearx_sub_reg_dble;
00133 !            ierror = 0 : No error
00134 !            ierror > 0 : Severe error!
00135 !
00136 ! !DEFINED PARAMETERS:
00137 !
00138 !  dble_earth = Earth radius in meter
00139 !
00140   Double Precision, Parameter     :: dble_earth = 6400000.0
00141 !
00142   Double Precision, Parameter     :: acosp1 =  1.0
00143   Double Precision, Parameter     :: acosm1 = -1.0
00144 
00145   Integer, Parameter              :: lon = 1
00146   Integer, Parameter              :: maxlen = 64
00147 !
00148 ! !LOCAL VARIABLES
00149 !
00150   Double Precision                :: dist, maxdist, val, fac, fac2
00151 
00152   Double Precision                :: sin_corner_lat(8,3)
00153   Double Precision                :: cos_corner_lat(8,3)
00154   Double Precision                :: sin_corner_lon(8,3)
00155   Double Precision                :: cos_corner_lon(8,3)
00156 
00157   Double Precision                :: sin_midp_lat(3)
00158   Double Precision                :: cos_midp_lat(3)
00159   Double Precision                :: sin_midp_lon(3)
00160   Double Precision                :: cos_midp_lon(3)
00161 
00162   Double Precision                :: distrad(maxlen), radius (maxlen)
00163 
00164   Logical                         :: maskrad(maxlen)
00165 
00166   Integer                         :: ijk0 (ndim_3d)
00167   Integer                         :: ijk  (2,ndim_3d)
00168   Integer                         :: ii, jj, kk
00169   Integer                         :: inext, jnext, knext
00170   Integer                         :: i, j, k, n
00171   Integer                         :: ncount
00172   Integer                         :: iloc(1)
00173 
00174   Type (Grid), Pointer            :: grid_info
00175   Type (Enddef_mg_double), Pointer :: my_arrays
00176 !
00177 !     ... multi-grid control
00178 !
00179       Integer                         :: lev, nlev
00180       Integer, Allocatable            :: icoarse (:, :)
00181 !
00182 !     ... number of points in i, j, k directions
00183 !
00184       Integer                         :: leni, lenij, lenijk, lenj, lenk
00185 !
00186 !     ... loop indices in neighbors_3d and compact vector
00187 !
00188       Integer                         :: ind, jind
00189 !
00190 !     ... for error handling
00191 !
00192 !     Integer, Parameter              :: nerrp = 2
00193 !     Integer                         :: ierrp (nerrp)
00194 !
00195 ! !DESCRIPTION:
00196 !
00197 ! Subroutine "PSMILe_MG_srch_nneigh_reg_dble" searches the next "num_neigh"
00198 ! nearest neighbours on the method-grid. num_neigh = 1 for the moment only.
00199 !
00200 !
00201 ! !REVISION HISTORY:
00202 !
00203 !   Date      Programmer   Description
00204 ! ----------  ----------   -----------
00205 ! 05/02/01    R. Redler    created
00206 !
00207 !EOP
00208 !----------------------------------------------------------------------
00209 !
00210 !  Initialization
00211 
00212 #ifdef VERBOSE
00213   print 9990, trim(ch_id)
00214 
00215   call psmile_flushstd
00216 #endif /* VERBOSE */
00217 
00218   ierror = 0
00219 
00220   grid_info => Grids(grid_id)
00221   ijk0 = grid_info%ijk0
00222 
00223   nlev = grid_info%nlev - 3
00224 
00225 #ifdef PRISM_ASSERTION
00226 
00227 ! This should never happen
00228 
00229   if ( nn_srch%leni*nn_srch%lenj*nn_srch%lenk > maxlen ) then
00230      print *, "lenijk, maxlen", nn_srch%leni*nn_srch%lenj*nn_srch%lenk, maxlen
00231      call psmile_assert ( __FILE__, __LINE__, "lenijk > maxlen")
00232   endif
00233 #endif
00234 
00235 !
00236 !
00237 ! compute coarsening factor to get
00238 ! from level "lev" onto the finest level "1"
00239 !
00240   if (mask_available) then
00241      allocate (icoarse (ndim_3d, nlev), stat = ierror)
00242 !
00243      icoarse (1:ndim_3d, 1) = 1
00244 !
00245         do lev = 2, nlev
00246            do i = 1, ndim_3d
00247            if ( grid_info%mg_infos(lev  )%levdim(i) /= &
00248                 grid_info%mg_infos(lev-1)%levdim(i) ) then
00249               icoarse(i, lev) = icoarse(i, lev-1) * 2
00250            else
00251               icoarse(i, lev) = icoarse(i, lev-1)
00252            end if
00253            end do
00254         end do
00255    endif
00256 
00257 ! jind = loop index in compact vector "sin_search", "cos_search",
00258 !        "z_search" and "dist_dble"
00259 !
00260 ! ind  = Corresponding index in "neighbors_3d"
00261 !
00262   do jind = jbeg, jend
00263 
00264      ! reinitialise lengths and next indices
00265 
00266      inext = 0
00267      jnext = 0
00268      knext = 0
00269 !
00270 ! Get number of points in i,j,k direction on finest level
00271 !
00272      my_arrays => grid_info%mg_infos(nlev)%double_arrays
00273 !
00274      leni   = nn_srch%leni
00275      lenj   = nn_srch%lenj
00276      lenk   = nn_srch%lenk
00277 !
00278      lenij  = leni*lenj
00279      lenijk = lenij*lenk
00280 
00281      ind = indices (jind)
00282 
00283      maxdist = maxval (dist_dble (jind, 1:num_neigh) )
00284 
00285      ! distance from point to mid point of control volume on start level 
00286      ! Das ist zu teuer (lenijk !)
00287 
00288      fac = dble_earth + z_search (jind)
00289 !
00290      n = 0
00291         do j = 1, lenj
00292 
00293 !cdir vector
00294            do i = 1, leni
00295            n = n+1
00296 
00297            val = (  arrays%sin_cmidp_lat%vector(j) * sin_search(jind,lat)    &
00298                  +  arrays%cos_cmidp_lat%vector(j) * cos_search(jind,lat)    &
00299                  * (arrays%cos_cmidp_lon%vector(i) * cos_search(jind,lon)    &
00300                  +  arrays%sin_cmidp_lon%vector(i) * sin_search(jind,lon)) )
00301 
00302            val = min (acosp1, val)
00303            val = max (acosm1, val)
00304 
00305            dist = fac * acos (val)
00306            distrad (n) = dist * dist
00307            enddo
00308         enddo
00309 !
00310 !       Replicate distance for other k levels
00311 !
00312         do k = 2, lenk
00313         distrad ((k-1)*lenij+1:k*lenij) = distrad (1:lenij)
00314         enddo
00315 
00316         if ( search_mode == 3 ) then
00317            n = 0
00318               do k = 1, lenk
00319               distrad (n+1:n+lenij) = distrad (n+1:n+lenij) + &
00320                    (my_arrays%midp(3)%vector(k)-z_search(jind))**2
00321 
00322               n = n + lenij
00323               enddo
00324         endif
00325 
00326         distrad (1:lenijk) = sqrt (distrad (1:lenijk))
00327 
00328      ! distance from point to sphere
00329      ! Note: This distance may be negative.
00330      
00331      distrad(1:lenijk) = distrad(1:lenijk) - arrays%radius(1:lenijk)
00332 
00333      ! ignore control volumes that are farther away than what we have already
00334 
00335      maskrad (1:lenijk) = distrad (1:lenijk) < maxdist
00336 
00337      iloc(:) = minloc (distrad(1:lenijk), maskrad(1:lenijk))
00338 #ifdef MINLOCFIX
00339      if (iloc(1).eq.0) iloc(1)=1
00340 #endif /* MINLOCFIX */
00341 
00342      if ( iloc(1) > lenijk ) iloc(1) = 0
00343 
00344      do lev = nlev, 3, -1
00345 
00346         ! sphere around the control volume for all but the start level
00347 
00348         if ( lev < nlev ) then
00349 
00350         n = 0
00351 
00352         do k = 1, lenk
00353            fac2 = dble_earth + my_arrays%midp(3)%vector(k)
00354            do j = 1, lenj
00355 !cdir vector
00356               do i = 1, leni
00357                  n = n+1
00358 
00359                  val = (  sin_corner_lat(1,j) * sin_midp_lat(j)    &
00360                        +  cos_corner_lat(1,j) * cos_midp_lat(j)    &
00361                        * (cos_corner_lon(1,i) * cos_midp_lon(i)    &
00362                        +  sin_corner_lon(1,i) * sin_midp_lon(i)) )
00363 
00364                  val = min (acosp1, val)
00365                  val = max (acosm1, val)
00366 
00367                  dist = fac2 * acos (val)
00368                  radius (n) = dist * dist
00369 
00370               enddo ! i
00371            enddo ! j
00372         enddo ! k
00373 
00374         if ( search_mode == 3 ) then
00375            n = 0
00376 
00377            do k = 1, lenk
00378            radius(n+1:n+lenij) = radius(n+1:n+lenij) + &
00379               (my_arrays%midp(3)%vector(k) - my_arrays%chmin(3)%vector(k))**2
00380            n = n + lenij
00381            enddo
00382         endif
00383 !
00384         radius (1:lenijk) = sqrt (radius (1:lenijk))
00385 
00386            ! distance from point to mid point of control volume
00387            !  for all but the start level
00388 
00389         n = 0
00390 
00391            do j = 1, lenj
00392               do i = 1, leni
00393                  n = n+1
00394 
00395                  val = (  sin_midp_lat(j) * sin_search(jind,lat)    &
00396                        +  cos_midp_lat(j) * cos_search(jind,lat)    &
00397                        * (cos_midp_lon(i) * cos_search(jind,lon)    &
00398                        +  sin_midp_lon(i) * sin_search(jind,lon)) )
00399 
00400               val = min (acosp1, val)
00401               val = max (acosm1, val)
00402 
00403               dist = fac * acos (val)
00404               distrad (n) = dist * dist
00405            enddo
00406            enddo
00407 
00408            do k = 2, lenk
00409            distrad ((k-1)*lenij+1:k*lenij) = distrad (1:lenij)
00410            enddo
00411 
00412            if ( search_mode == 3 ) then
00413               n = 0
00414               do k = 1, lenk
00415                  distrad (n+1:n+lenij) = distrad (n+1:n+lenij) + &
00416                       (my_arrays%midp(3)%vector(k)-z_search(jind))**2
00417                  n = n + lenij
00418               end do
00419            endif
00420 
00421            distrad (1:lenijk) = sqrt (distrad (1:lenijk))
00422 
00423            ! distance from point to sphere
00424 
00425            distrad (1:lenijk) = distrad (1:lenijk) - radius(1:lenijk)
00426 
00427            ! ignore control volumes that are farther away than what we have already
00428 
00429            maskrad (1:lenijk) = distrad (1:lenijk) < maxdist
00430 
00431            iloc(:) = minloc(distrad(1:lenijk),maskrad(1:lenijk))
00432 #ifdef MINLOCFIX
00433            if (iloc(1).eq.0) iloc(1)=1
00434 #endif /* MINLOCFIX */
00435 
00436            if ( iloc(1) > lenijk ) iloc(1) = 0
00437 
00438         endif ! (lev < nlev)
00439 !
00440 !-------------------------------------------------------------------------
00441 !    Ignore points maked out
00442 !-------------------------------------------------------------------------
00443 !
00444         if ( mask_available .and. iloc(1) > 0 ) then
00445 
00446            ! check whether we have valid points in this volume
00447 
00448            do i = 1, lenijk
00449 
00450               kk = (iloc(1)                - 1) / lenij + 1
00451               jj = (iloc(1) - (kk-1)*lenij - 1) / leni  + 1
00452               ii =  iloc(1) - (kk-1)*lenij - (jj-1)*leni
00453 
00454               ii = ii - 1 + inext
00455               jj = jj - 1 + jnext
00456               kk = kk - 1 + knext
00457 
00458               ijk(1,1) = ijk0(1) + ii*icoarse(1,lev)
00459               ijk(1,2) = ijk0(2) + jj*icoarse(2,lev)
00460               ijk(1,3) = ijk0(3) + kk*icoarse(3,lev)
00461 
00462               ijk(2,1) = min (grid_valid_shape(2,1), ijk(1,1)+icoarse(1,lev)-1)
00463               ijk(2,2) = min (grid_valid_shape(2,2), ijk(1,2)+icoarse(2,lev)-1)
00464               ijk(2,3) = min (grid_valid_shape(2,3), ijk(1,3)+icoarse(3,lev)-1)
00465 
00466               ncount = count( mask_array(ijk(1,1):ijk(2,1), &
00467                                          ijk(1,2):ijk(2,2), &
00468                                          ijk(1,3):ijk(2,3)) )
00469 #ifdef DEBUGX
00470               print *, '     masks:                     ', maskrad(1:lenijk)
00471               print *, '     ii, jj, kk:                ', ii, jj, kk
00472               print *, '     lev, i, iloc(1), ncount : ', lev, i, iloc(1), ncount
00473               print *, '     => ijk                     ', ijk
00474 #endif
00475 
00476               if ( ncount > 0 ) exit
00477 
00478               ! reject control volume without any valid points
00479 
00480               maskrad (iloc(1)) = .false.
00481 
00482               iloc(:) = minloc (distrad(1:lenijk), maskrad(1:lenijk))
00483 #ifdef MINLOCFIX
00484               if (iloc(1).eq.0) iloc(1)=1
00485 #endif /* MINLOCFIX */
00486 
00487               if ( iloc(1) > lenijk ) then
00488                  iloc(1) = 0
00489                  exit
00490               endif
00491 
00492 !             if ( iloc(1) == 0 ) exit
00493               
00494            enddo
00495 
00496            if ( ncount == 1 ) then
00497               do k = ijk(1,3),ijk(2,3)
00498                  do j = ijk(1,2),ijk(2,2)
00499                     do i = ijk(1,1),ijk(2,1)
00500                        if ( mask_array(i,j,k) ) then
00501                           neighbors_3d (1, ind, 1) = i
00502                           neighbors_3d (2, ind, 1) = j
00503                           neighbors_3d (3, ind, 1) = k
00504                        endif
00505                     enddo
00506                  enddo
00507               enddo
00508 
00509 ! ist das korreckt ?
00510            if ( lev < nlev ) then
00511               dist_dble (jind, 1) = distrad (iloc(1)) + radius(iloc(1))
00512            else
00513               dist_dble (jind, 1) = distrad (iloc(1)) + arrays%radius(iloc(1))
00514            endif 
00515 
00516               iloc(1) = 0 ! do not enter level 3
00517 
00518               exit ! lev
00519 
00520            endif
00521 
00522         endif
00523 
00524         if ( iloc(1) == 0 ) exit
00525 !
00526 !----------------------------------------------------------------------
00527 !       Prepare next level
00528 !----------------------------------------------------------------------
00529 !
00530         if ( lev > 3 ) then 
00531 
00532            ! prepare next level
00533 
00534            inext = ii * (icoarse(1,lev)/icoarse(1,lev-1))
00535            jnext = jj * (icoarse(2,lev)/icoarse(2,lev-1))
00536            knext = kk * (icoarse(3,lev)/icoarse(3,lev-1))
00537 
00538            my_arrays => grid_info%mg_infos(lev-1)%double_arrays
00539 
00540            leni   = min(inext+2,grid_info%mg_infos(lev-1)%levdim(1)) - inext + 1
00541            lenj   = min(jnext+2,grid_info%mg_infos(lev-1)%levdim(2)) - jnext + 1
00542            lenk   = min(knext+2,grid_info%mg_infos(lev-1)%levdim(3)) - knext + 1
00543            lenij  = leni*lenj
00544            lenijk = lenij*lenk
00545 
00546 #ifdef PRISM_ASSERTION
00547 !HR ich halte die Assertion fuer falsch
00548            if ( lenijk > maxlen ) then
00549               print *, "lenijk, maxlen", lenijk, maxlen
00550               call psmile_assert ( __FILE__, __LINE__, "lenijk > maxlen")
00551            endif
00552 #endif
00553         sin_corner_lon(1,1:leni) = sin(my_arrays%chmin(1)%vector(inext+1:inext+leni)*dble_deg2rad)
00554         cos_corner_lon(1,1:leni) = cos(my_arrays%chmin(1)%vector(inext+1:inext+leni)*dble_deg2rad)
00555         sin_corner_lat(1,1:lenj) = sin(my_arrays%chmin(2)%vector(jnext+1:jnext+lenj)*dble_deg2rad)
00556         cos_corner_lat(1,1:lenj) = cos(my_arrays%chmin(2)%vector(jnext+1:jnext+lenj)*dble_deg2rad)
00557 
00558         sin_midp_lon(1:leni) = sin(my_arrays%midp(1)%vector(inext+1:inext+leni)*dble_deg2rad)
00559         cos_midp_lon(1:leni) = cos(my_arrays%midp(1)%vector(inext+1:inext+leni)*dble_deg2rad)
00560         sin_midp_lat(1:lenj) = sin(my_arrays%midp(2)%vector(jnext+1:jnext+lenj)*dble_deg2rad)
00561         cos_midp_lat(1:lenj) = cos(my_arrays%midp(2)%vector(jnext+1:jnext+lenj)*dble_deg2rad)
00562 
00563         endif
00564 
00565      enddo ! lev
00566 
00567 !=========================================================================
00568 ! go over all points of the final selected control volume on level 3
00569 ! and find the nearest points.
00570 !=========================================================================
00571      
00572      if ( iloc(1) > 0 ) then
00573 
00574         my_arrays => grid_info%mg_infos(1)%double_arrays
00575 
00576         inext  = ijk(1,1) - ijk0(1)
00577         jnext  = ijk(1,2) - ijk0(2)
00578         knext  = ijk(1,3) - ijk0(3)
00579 
00580         leni   = ijk(2,1) - ijk(1,1) + 1
00581         lenj   = ijk(2,2) - ijk(1,2) + 1
00582         lenk   = ijk(2,3) - ijk(1,3) + 1
00583 
00584         lenij  = leni*lenj
00585         lenijk = lenij*lenk
00586 
00587 #ifdef PRISM_ASSERTION
00588 !HR ich halte die Assertion fuer falsch
00589         if ( lenijk > maxlen ) then
00590            print *, "lenijk, maxlen", lenijk, maxlen
00591            call psmile_assert ( __FILE__, __LINE__, "lenijk > maxlen")
00592         endif
00593 #endif
00594 
00595      arrays%sin_fmidp_lon%vector(1:leni) = sin(my_arrays%midp(1)%vector(inext+1:inext+leni)*dble_deg2rad)
00596      arrays%cos_fmidp_lon%vector(1:leni) = cos(my_arrays%midp(1)%vector(inext+1:inext+leni)*dble_deg2rad)
00597      arrays%sin_fmidp_lat%vector(1:lenj) = sin(my_arrays%midp(2)%vector(jnext+1:jnext+lenj)*dble_deg2rad)
00598      arrays%cos_fmidp_lat%vector(1:lenj) = cos(my_arrays%midp(2)%vector(jnext+1:jnext+lenj)*dble_deg2rad)
00599 
00600      n = 0
00601 
00602         do j = 1, lenj
00603 !cdir vector
00604            do i = 1, leni
00605 
00606               n = n+1
00607 
00608            ! distance from point to potential neighbor
00609 
00610               val = (  arrays%sin_fmidp_lat%vector(j) * sin_search(jind,lat)    &
00611                     +  arrays%cos_fmidp_lat%vector(j) * cos_search(jind,lat)    &
00612                     * (arrays%cos_fmidp_lon%vector(i) * cos_search(jind,lon)    &
00613                     +  arrays%sin_fmidp_lon%vector(i) * sin_search(jind,lon)) )
00614 
00615            val = min (acosp1, val)
00616            val = max (acosm1, val)
00617 
00618            dist = fac * acos (val)
00619 
00620            distrad(n) = dist*dist
00621         end do
00622         enddo
00623 
00624      do k = 2, lenk
00625         distrad ((k-1)*lenij+1:k*lenij) = distrad (1:lenij)
00626      enddo
00627 
00628         if ( search_mode == 3 ) then
00629            n = 0
00630            do k = 1, lenk
00631               distrad (n+1:n+lenij) = distrad (n+1:n+lenij) + &
00632                                    (my_arrays%midp(3)%vector(k)-z_search(jind))**2
00633               n = n + lenij
00634            end do
00635         endif
00636 
00637         ! ignore invalid points
00638         if ( mask_available ) then
00639         n = 0
00640            do k = 1, lenk
00641            do j = 1, lenj
00642 !cdir vector
00643               do i = 1, leni
00644               n = n + 1
00645 
00646                  maskrad (n) = mask_array(ijk(1,1)+i-1, &
00647                                           ijk(1,2)+j-1, &
00648                                           ijk(1,3)+k-1) 
00649               end do
00650            end do
00651         end do
00652 
00653            i = min(num_neigh, count(maskrad(1:lenijk)))
00654         else
00655            maskrad (1:lenijk) = .true.
00656 
00657            i = min(num_neigh, lenijk)
00658         endif
00659 
00660         do n = 1, i
00661 
00662            iloc(:) = minloc (distrad(1:lenijk), maskrad(1:lenijk))
00663 #ifdef MINLOCFIX
00664            if (iloc(1).eq.0) iloc(1)=1
00665 #endif /* MINLOCFIX */
00666 
00667            kk = (iloc(1)                - 1) / lenij + 1
00668            jj = (iloc(1) - (kk-1)*lenij - 1) / leni  + 1
00669            ii =  iloc(1) - (kk-1)*lenij - (jj-1) * leni
00670 
00671            neighbors_3d (1, ind, n) = ijk(1,1)+ii-1
00672            neighbors_3d (2, ind, n) = ijk(1,2)+jj-1
00673            neighbors_3d (3, ind, n) = ijk(1,3)+kk-1
00674 
00675 ! ist das korrekt ?
00676            dist_dble (jind, n) = sqrt ( distrad(iloc(1)) )
00677 
00678            maskrad (iloc(1)) = .false.
00679 
00680            end do
00681 
00682      endif
00683   end do ! jind
00684  
00685   !
00686   !===> All done
00687   !
00688   if (mask_available) then
00689      Deallocate (icoarse)
00690   endif
00691 
00692 #ifdef VERBOSE
00693   print 9980, trim(ch_id), ierror
00694 
00695   call psmile_flushstd
00696 #endif /* VERBOSE */
00697   !
00698   !  Formats:
00699   !
00700 9990 format (1x, a, ': psmile_mg_srch_nneigh_reg_dble')
00701 9980 format (1x, a, ': psmile_mg_srch_nneigh_reg_dble: eof, ierror =', i3)
00702 
00703 end subroutine PSMILe_MG_srch_nneigh_reg_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1