psmile_neigh_tricu_irreg2.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_tricu_irreg2
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_neigh_tricu_irreg2 (                 &
00012                grid_valid_shape, interpolation_mode, cyclic, &
00013                srcloc, srclocz, nlocs, nloc, npreva,         &
00014                neighbors_3d, num_neigh, ierror)
00015 !
00016 ! !USES:
00017 !
00018       use PRISM_constants
00019 !
00020       use PSMILe, dummy_interface => PSMILe_Neigh_tricu_irreg2
00021 
00022       implicit none
00023 !
00024 ! !INPUT PARAMETERS:
00025 !
00026       Integer, Intent (In)            :: nloc
00027 !
00028 !     Total number of locations to be transferred
00029 !
00030       Integer, Intent (In)            :: nlocs (ndim_2d)
00031 !
00032 !     Number of locations in each direction
00033 !
00034       Integer, Intent (In)            :: srcloc  (ndim_2d, nlocs (1))
00035       Integer, Intent (In)            :: srclocz (nlocs (2))
00036 !
00037 !     Indices of the (method) grid cell in which the point was found.
00038 
00039       Integer, Intent (In)            :: npreva
00040 !
00041 !     Number of locations for which neighbours were already searched.
00042 !
00043       Integer, Intent (In)            :: grid_valid_shape (2, ndim_3d)
00044 
00045 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00046 !
00047       Integer, Intent (In)            :: interpolation_mode
00048 !
00049 !     Specifies the interpolation mode with
00050 !        interpolation_mode = 3 : Tri-linear or bilinear/linear interpolation
00051 !                                 (determines 8 corners)
00052 !        interpolation_mode = 2 : Bilinear interpolation
00053 !                                 (determines 4 corners)
00054 !        interpolation_mode = 1 : Linear   interpolation
00055 !                                 (determines 2 corners)
00056 !
00057       Logical, Intent (In)            :: cyclic (ndim_3d)
00058 !    
00059 !     Does the block have cyclic coordinates in the corresponding direction ?
00060 !
00061       Integer, Intent (In)            :: num_neigh
00062 !
00063 !     Last dimension of neighbors array "neighbors_3d"
00064 !
00065 ! !OUTPUT PARAMETERS:
00066 !
00067 !     Location of indices for neighbors_3d
00068 !
00069 !           13   14   15   16
00070 !
00071 !     ^      9   10   11   12
00072 !     |
00073 !     |      5    6    7    8
00074 !
00075 !     j      1    2    3    4
00076 !
00077 !       i ---->
00078 !
00079       Integer, Intent (Out)           :: neighbors_3d (ndim_3d, nloc, num_neigh)
00080 
00081 !     Indices of neighbor locations (interpolation bases)
00082 
00083       Integer, Intent (Out)           :: ierror
00084 
00085 !     Returns the error code of PSMILE_Neigh_tricu_irreg2;
00086 !             ierror = 0 : No error
00087 !             ierror > 0 : Severe error
00088 !
00089 ! !DEFINED PARAMETERS:
00090 !
00091 !  N_CORNERS_3D = Number of corners for a 3-d interpolation
00092 !               = 2 ** ndim_3d
00093 !  N_CORNERS_2D = Number of corners for a 2-d interpolation
00094 !               = 2 ** ndim_2d
00095 !
00096       Integer, parameter              :: n_corners_3d = 2 * 2 * 2 * 8
00097       Integer, parameter              :: n_corners_2d = 2 * 2 * 4
00098       Integer, parameter              :: n_corners_1d = 2 * 2
00099 !
00100 ! !LOCAL VARIABLES
00101 !
00102 !     ... for locations searched
00103 !
00104       Integer                         :: i, j, k, n
00105       Integer                         :: nbeg, nend, nprev
00106       Integer                         :: lenijk, n_corners
00107 !
00108 !     ... For locations controlled
00109 !
00110       Integer                         :: length (ndim_3d)
00111       Integer                         :: nca (ndim_3d)
00112 !
00113 !     ... for error handling
00114 !
00115       Integer, Parameter              :: nerrp = 2
00116       Integer                         :: ierrp (nerrp)
00117 !
00118 !
00119 ! !DESCRIPTION:
00120 !
00121 ! Subroutine "PSMILe_Neigh_tricu_irreg2" searches the "n_corners"
00122 ! (8, 4 or 2) neighbours (3d-indices of the interpolation bases) for the
00123 ! selected interpolation type (tri-, bi-linear or linear, respectively)
00124 ! on the the method-grid (x_coords, y_coords, z_coords)
00125 ! for the subgrid coords sent by the destination process.
00126 !
00127 ! Subroutine "PSMILe_Neigh_tricu_irreg2" is designed for (target) grids
00128 ! of type "PRISM_Irrlonlat_regvrt".
00129 !
00130 ! !REVISION HISTORY:
00131 !
00132 !   Date      Programmer   Description
00133 ! ----------  ----------   -----------
00134 ! 03.07.21    H. Ritzdorf  created for linear interpolation
00135 ! 05.05.09    R. Redler    modified for cubic interpolation
00136 !
00137 !EOP
00138 !----------------------------------------------------------------------
00139 !
00140 !  $Id: psmile_neigh_tricu_irreg2.F90 2687 2010-10-28 15:15:52Z coquart $
00141 !  $Author: coquart $
00142 !
00143    Character(len=len_cvs_string), save :: mycvs = 
00144        '$Id: psmile_neigh_tricu_irreg2.F90 2687 2010-10-28 15:15:52Z coquart $'
00145 !
00146 !----------------------------------------------------------------------
00147 !
00148       data nca /n_corners_1d, n_corners_2d, n_corners_3d/
00149 !
00150 !----------------------------------------------------------------------
00151 !
00152 !  Initialization
00153 !
00154 #ifdef VERBOSE
00155       print 9990, trim(ch_id)
00156 
00157       call psmile_flushstd
00158 #endif /* VERBOSE */
00159 !
00160 !===> Control interpolation mode
00161 !
00162       if (interpolation_mode < 1 .or. interpolation_mode > ndim_3d) then
00163          ierrp (1) = interpolation_mode
00164          ierror = PRISM_Error_Internal
00165 
00166          call psmile_error ( ierror, 'unsupported interpolation mode in psmile_neigh_tricu_irreg2', &
00167                              ierrp, 1, __FILE__, __LINE__ )
00168          return
00169       endif
00170 !
00171 !===> Initialization
00172 !
00173 !  lenijk = Number of entries in all   3 directions
00174 !
00175       ierror = 0
00176 !
00177       nprev = npreva
00178       n_corners = nca (interpolation_mode)
00179 !
00180       lenijk = nlocs (1) * nlocs (2)
00181       nbeg = nprev + 1
00182       nend = nprev + lenijk
00183 !
00184       length (1:ndim_3d) = grid_valid_shape(2,1:ndim_3d) - &
00185                            grid_valid_shape(1,1:ndim_3d) + 1
00186 !
00187 #ifdef PRISM_ASSERTION
00188 !
00189 !===> Is the dimension of array "neighbors_3d" sufficient
00190 !
00191       if (num_neigh < n_corners) then
00192          print 9970, trim(ch_id), num_neigh, n_corners
00193          call psmile_assert (__FILE__, __LINE__, &
00194                              'Number of neighbors is insufficient')
00195       endif
00196 !
00197 !===> 
00198 !
00199       if (nloc < nprev + nlocs (1) * nlocs (2) ) then
00200          print *, trim(ch_id), " nloc, nprev, nlocs ", nloc, nprev, nlocs
00201          call psmile_assert (__FILE__, __LINE__, &
00202                              'nloc < nprev + PRODUCT (nlocs) ')
00203       endif
00204 !
00205 !===> Are the locations within the correct shape ?
00206 !
00207 !cdir vector
00208          do i = 1, nlocs(1)
00209             if ( srcloc(1,i) < grid_valid_shape(1,1) -1 .or. &
00210                  srcloc(1,i) > grid_valid_shape(2,1)    .or. &
00211                  srcloc(2,i) < grid_valid_shape(1,2) -1 .or. &
00212                  srcloc(2,i) > grid_valid_shape(2,2) ) exit
00213          end do
00214 
00215          if (i <= nlocs(1)) then
00216             print *, "grid valid shape is ", grid_valid_shape
00217             print *, "Incorrect index in srcloc, i", i, srcloc(1,i), srcloc(2,i)
00218             call psmile_assert (__FILE__, __LINE__, 'wrong index')
00219          endif
00220 !
00221 !===> Are the z-locations within the correct shape ?
00222 !
00223 !cdir vector
00224          do i = 1, nlocs (2)
00225             if ( srclocz(i) < grid_valid_shape(1,3)-1 .or. &
00226                  srclocz(i) > grid_valid_shape(2,3)) exit
00227          end do
00228          if (i <= nlocs(2)) then
00229             print *, "Incorrect index in srclocz(i), i", i, srclocz(i)
00230             call psmile_assert (__FILE__, __LINE__, 'wrong index')
00231          endif
00232 #endif
00233 !
00234 !===> Control special cases (2d hyperplanes)
00235 !
00236          do i = 1, ndim_3d
00237          if (length(i) == 1) then
00238             neighbors_3d (i, nbeg:nend, 1:n_corners) = grid_valid_shape(1,i)
00239          endif
00240          end do
00241 !
00242 !===> Generate entries (assuming mask is not available or all
00243 !     mask points are defined)
00244 !
00245          neighbors_3d (1:2, nprev+1:nprev+nlocs(1), 6) = srcloc (1:2, 1:nlocs(1))
00246 !
00247 !===> Duplicate first 2 indices for third direction
00248 !
00249          do k = 2, nlocs (2)
00250             neighbors_3d (1:2, nprev+(k-1)*nlocs(1)+1:nprev+k*nlocs(1), 6) = &
00251             neighbors_3d (1:2, nprev+               1:nprev+  nlocs(1), 6)
00252          end do
00253 !
00254 !===> 
00255 !
00256          do k = 1, nlocs (2)
00257             neighbors_3d (3, nprev+(k-1)*nlocs(1)+1:nprev+k*nlocs(1), 6) = srclocz (k)     
00258          end do
00259 !
00260 !===> ... I indices of neighbour indices
00261 !
00262          if (length(1) > 1) then
00263             neighbors_3d (1, nbeg:nend, 2) = neighbors_3d (1, nbeg:nend, 6) + 1
00264 
00265             do n = 0, 3
00266                neighbors_3d (1, nbeg:nend, 1+(n*4) ) = neighbors_3d (1, nbeg:nend, 6) - 1
00267                neighbors_3d (1, nbeg:nend, 2+(n*4) ) = neighbors_3d (1, nbeg:nend, 6)
00268                neighbors_3d (1, nbeg:nend, 3+(n*4) ) = neighbors_3d (1, nbeg:nend, 6) + 1
00269                neighbors_3d (1, nbeg:nend, 4+(n*4) ) = neighbors_3d (1, nbeg:nend, 6) + 2
00270             enddo
00271 
00272             if (n_corners > 16) &
00273                  neighbors_3d (1, nbeg:nend, 17:32) = neighbors_3d (1, nbeg:nend,  1:16)
00274 
00275          endif
00276 !
00277 !===> ... J indices of neighbour indices
00278 !
00279          if (length(2) > 1) then
00280 
00281             do n = 1, 4
00282                neighbors_3d (2, nbeg:nend,    n) = neighbors_3d (2, nbeg:nend, 6) - 1
00283                neighbors_3d (2, nbeg:nend,  4+n) = neighbors_3d (2, nbeg:nend, 6)
00284                neighbors_3d (2, nbeg:nend,  8+n) = neighbors_3d (2, nbeg:nend, 6) + 1
00285                neighbors_3d (2, nbeg:nend, 12+n) = neighbors_3d (2, nbeg:nend, 6) + 2
00286             end do
00287 
00288             if (n_corners > 16) then
00289                neighbors_3d (2, nbeg:nend, 17:20) = neighbors_3d (2, nbeg:nend,  1: 4)
00290                neighbors_3d (2, nbeg:nend, 21:24) = neighbors_3d (2, nbeg:nend,  5: 8)
00291                neighbors_3d (2, nbeg:nend, 25:28) = neighbors_3d (2, nbeg:nend,  9:12)
00292                neighbors_3d (2, nbeg:nend, 29:32) = neighbors_3d (2, nbeg:nend, 13:16)
00293             endif
00294 
00295          endif
00296 !
00297 !===> ... K indices of neighbour indices
00298 !
00299          if (length(3) > 1) then
00300 
00301             do n = 1, 16
00302                neighbors_3d (3, nbeg:nend, n) = neighbors_3d (3, nbeg:nend, 6)
00303             enddo
00304 
00305             if (n_corners > 16) then
00306                do n = 17, 32
00307                   neighbors_3d (3, nbeg:nend,n) = neighbors_3d (3, nbeg:nend, 1) + 1
00308                enddo
00309             endif
00310 
00311          else
00312 
00313             neighbors_3d (3, nbeg:nend,2:16) = srclocz (1)
00314 
00315          endif
00316 !
00317 !===> ... set indices for cyclic coordinate directions
00318 !
00319          do j = 1, ndim_3d
00320          if (cyclic(j) .and. length(j) > 1) then
00321 !
00322                do n = 1, n_corners
00323 !cdir vector
00324                   do i = nbeg, nend
00325                      
00326                   if  ( neighbors_3d (j, i, n) > grid_valid_shape(2,j) ) then
00327 
00328                         neighbors_3d (j, i, n) = &
00329                         neighbors_3d (j, i, n) - length(j)
00330 
00331                   else if ( neighbors_3d (j, i, n) < grid_valid_shape(1,j) ) then
00332 
00333                         neighbors_3d (j, i, n) = &
00334                         neighbors_3d (j, i, n) + length(j)
00335 
00336                   endif
00337                   end do
00338                end do ! n
00339          endif
00340          end do ! j
00341 !
00342 !===> All done
00343 !
00344 #ifdef VERBOSE
00345       print 9980, trim(ch_id)
00346 
00347       call psmile_flushstd
00348 #endif /* VERBOSE */
00349 !
00350 !  Formats:
00351 !
00352 9990 format (1x, a, ': psmile_neigh_tricu_irreg2')
00353 9980 format (1x, a, ': psmile_neigh_tricu_irreg2: eof')
00354 
00355 #ifdef PRISM_ASSERTION
00356 9970 format (1x, a, ': number of neighbors', i2, '; expected at least', i2)
00357 #endif
00358 
00359       end subroutine psmile_neigh_tricu_irreg2

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1