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

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1