psmile_neigh_trili_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_trili_3d
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_neigh_trili_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_trili_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 8 corners)
00042 !        interpolation_mode = 2 : Bilinear interpolation
00043 !                                 (determines 4 corners)
00044 !        interpolation_mode = 1 : Linear   interpolation
00045 !                                 (determines 2 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       Integer, Intent (Out)           :: neighbors_3d (ndim_3d, nloc, num_neigh)
00058 
00059 !     Indices of neighbor locations (interpolation bases)
00060 
00061       Integer, Intent (Out)           :: ierror
00062 
00063 !     Returns the error code of PSMILE_Neigh_trili_3d;
00064 !             ierror = 0 : No error
00065 !             ierror > 0 : Severe error
00066 !
00067 ! !DEFINED PARAMETERS:
00068 !
00069 !  N_CORNERS_3D = Number of corners for a 3-d interpolation
00070 !               = 2 ** ndim_3d
00071 !  N_CORNERS_2D = Number of corners for a 2-d interpolation
00072 !               = 2 ** ndim_2d
00073 !
00074       Integer, Parameter              :: n_corners_3d = 2 * 2 * 2
00075       Integer, Parameter              :: n_corners_2d = 2 * 2
00076       Integer, Parameter              :: n_corners_1d = 2
00077 !
00078 ! !LOCAL VARIABLES
00079 !
00080 !     ... for locations searched
00081 !
00082       Integer                         :: i, j, n
00083       Integer                         :: n_corners
00084 !
00085 !     ... For locations controlled
00086 !
00087       Integer, Save                   :: ijkstd (ndim_3d, 2:n_corners_3d)
00088       Integer                         :: ijkctl (ndim_3d, 2:n_corners_3d)
00089 !
00090       Integer                         :: length (ndim_3d)
00091       Integer                         :: nca (ndim_3d)
00092 !
00093 !     ... for error handling
00094 !
00095       Integer, parameter              :: nerrp = 2
00096       Integer                         :: ierrp (nerrp)
00097 !
00098 !
00099 ! !DESCRIPTION:
00100 !
00101 ! Subroutine "PSMILe_Neigh_trili_3d" searches the "n_corners"
00102 ! (8, 4 or 2) neighbours (3d-indices of the interpolation bases) for the
00103 ! selected interpolation type (tri-, bi-linear or linear, respectively)
00104 ! on the the method-grid (x_coords, y_coords, z_coords)
00105 ! for the subgrid coords sent by the destination process.
00106 !
00107 ! Subroutine "PSMILe_Neigh_trili_3d" is designed for (source) grids
00108 ! of type "PRISM_Irrlonlatvrt".
00109 !
00110 ! !REVISION HISTORY:
00111 !
00112 !   Date      Programmer   Description
00113 ! ----------  ----------   -----------
00114 ! 03.07.21    H. Ritzdorf  created
00115 !
00116 !EOP
00117 !----------------------------------------------------------------------
00118 !
00119 !  $Id: psmile_neigh_trili_3d.F90 2687 2010-10-28 15:15:52Z coquart $
00120 !  $Author: coquart $
00121 !
00122    Character(len=len_cvs_string), save :: mycvs = 
00123        '$Id: psmile_neigh_trili_3d.F90 2687 2010-10-28 15:15:52Z coquart $'
00124 !
00125 !----------------------------------------------------------------------
00126 !
00127 !  Relative indices of corner
00128 !
00129 #ifdef FORTRAN_ORDER
00130       data ((ijkstd (i, n), i=1,ndim_3d), n = 2, n_corners_3d) &
00131                             /             1, 0, 0, &
00132                                0, 1, 0,   1, 1, 0, &
00133                                0, 0, 1,   1, 0, 1, &
00134                                0, 1, 1,   1, 1, 1/
00135 
00136 #else
00137 !huhu Offenbar erwartet Damien's Routine eine andere Ordnung
00138       data ((ijkstd (i, n), i=1,ndim_3d), n = 2, n_corners_3d) &
00139                             /             1, 0, 0, &
00140                                1, 1, 0,   0, 1, 0, &
00141                                0, 0, 1,   1, 0, 1, &
00142                                1, 1, 1,   0, 1, 1/
00143 #endif
00144 !
00145       data nca /n_corners_1d, n_corners_2d, n_corners_3d/
00146 !
00147 !----------------------------------------------------------------------
00148 !
00149 !===> Prologue
00150 !
00151 #ifdef VERBOSE
00152       print 9990, trim(ch_id)
00153       call psmile_flushstd
00154 #endif /* VERBOSE */
00155 !
00156 !===> Control interpolation mode
00157 !
00158       if (interpolation_mode < 1 .or. interpolation_mode > ndim_3d) then
00159          ierrp (1) = interpolation_mode
00160          ierror = PRISM_Error_Internal
00161 
00162          call psmile_error ( ierror, 'unsupported interpolation mode in psmile_neigh_trili', &
00163                              ierrp, 1, __FILE__, __LINE__ )
00164          return
00165       endif
00166 !
00167 !===> Initialization
00168 !
00169       ierror  = 0
00170 !
00171       n_corners = nca (interpolation_mode)
00172 !
00173       length (1:ndim_3d) = grid_valid_shape(2,1:ndim_3d) - &
00174                            grid_valid_shape(1,1:ndim_3d) + 1
00175 !
00176 #ifdef PRISM_ASSERTION
00177 !
00178 !===> Is the dimension of array "neighbors_3d" sufficient
00179 !
00180       if (num_neigh < n_corners) then
00181          print 9970, trim(ch_id), num_neigh, n_corners
00182          call psmile_assert (__FILE__, __LINE__, &
00183                              'Number of neighbors is insufficient')
00184       endif
00185 !
00186 !===> Are the locations within the correct shape ?
00187 !     Note: the scrloc's are source locations in the 
00188 !           method grid which has an virtual cell 0.
00189 !
00190 !cdir vector
00191          do i = 1, nloc
00192 !
00193          if (srcloc(1,i) < grid_valid_shape(1,1)-1 .or. &
00194              srcloc(1,i) > grid_valid_shape(2,1)   .or. &
00195              srcloc(2,i) < grid_valid_shape(1,2)-1 .or. &
00196              srcloc(2,i) > grid_valid_shape(2,2)   .or. &
00197              srcloc(3,i) < grid_valid_shape(1,3)-1 .or. &
00198              srcloc(3,i) > grid_valid_shape(2,3)) exit
00199          end do
00200 !
00201       if (i <= nloc) then
00202          print *, "Incorrect index in i", i, srcloc (:, i)
00203          print *, grid_valid_shape
00204          call psmile_assert (__FILE__, __LINE__, &
00205                              'wrong index')
00206       endif
00207 #endif
00208 !
00209 !===> For special cases (2d Hyperplanes)
00210 !     ??? Braucht man hier nicht ein spezielles Flag,
00211 !         dass das globale Gebiet eine Hyperplane ist ?
00212 !
00213       ijkctl = ijkstd
00214 !
00215          do j = 1, ndim_3d
00216          if (length(j) == 1) ijkctl (j, :) = 0
00217          end do
00218 !
00219 !===> Generate entries (assuming mask is not available or all
00220 !     mask points are defined)
00221 !
00222 #define TRANSF_SUP_2D_INTERP
00223 !
00224 #ifdef TRANSF_SUP_2D_INTERP
00225 !
00226 ! Note: The transformer doesn't currently perform 2d interpolation
00227 !       for a point which lies on the face of the "last cell"
00228 
00229       neighbors_3d (:, 1:nloc, 1) = srcloc (:, 1:nloc)
00230 #else
00231 
00232       if ( n_corners == N_CORNERS_2D ) then
00233 !
00234 !           ... 2-dimensional interpolation
00235 !
00236             do j = 1, ndim_2d
00237             if (cyclic (j) .or. length(j) == 1) then
00238                neighbors_3d (j, :, 1) = srcloc (j, :)
00239             else
00240 !cdir vector
00241                do i = 1, nloc
00242                   neighbors_3d (j, i, 1) = min (srcloc (j, i), &
00243                      grid_valid_shape(2,j)-1)
00244                end do
00245 
00246             endif
00247             end do ! j
00248 
00249 !           Index in z-direction
00250             
00251          neighbors_3d (3, :, 1) = srcloc (3, :)
00252 
00253       else
00254 
00255             do j = 1, ndim_3d
00256             if (cyclic (j) .or. length(j) == 1) then
00257                neighbors_3d (j, :, 1) = srcloc (j, :)
00258             else
00259 !cdir vector
00260                do i = 1, nloc
00261                   neighbors_3d (j, i, 1) = min (srcloc (j, i), &
00262                        grid_valid_shape(2,j)-1)
00263                end do
00264             endif
00265             end do
00266 
00267       endif
00268 
00269 #endif /* TRANSF_SUP_2D_INTERP */
00270 !
00271          do n = 2, n_corners
00272 !cdir vector
00273             do i = 1, nloc
00274 !           neighbors_3d (:, i, n) = srcloc (:, i) + ijkctl (:, n)
00275             neighbors_3d (:, i, n) = neighbors_3d (:, i, 1) + ijkctl (:, n)
00276             end do
00277          end do
00278 !
00279 !===> ... set indices for cyclic coordinate directions
00280 !
00281          do j = 1, ndim_3d
00282          if (cyclic(j) .and. length(j) > 1) then
00283 !
00284                do n = 1, n_corners
00285 !cdir vector
00286                   do i = 1, nloc
00287                   if (neighbors_3d (j, i, n) < grid_valid_shape(1,j)) then
00288                       neighbors_3d (j, i, n) = &
00289                       neighbors_3d (j, i, n) + length (j)
00290 
00291                   else if ( neighbors_3d (j, i, n) > grid_valid_shape(2,j)) then
00292                       neighbors_3d (j, i, n) = &
00293                       neighbors_3d (j, i, n) - length (j)
00294                   endif
00295                   end do
00296                end do ! n
00297             endif
00298          end do ! j
00299 !
00300 !===> All done
00301 !
00302 #ifdef VERBOSE
00303       print 9980, trim(ch_id)
00304 
00305       call psmile_flushstd
00306 #endif /* VERBOSE */
00307 !
00308 !  Formats:
00309 !
00310 9990 format (1x, a, ': psmile_neigh_trili_3d')
00311 9980 format (1x, a, ': psmile_neigh_trili_3d: eof')
00312 
00313 #ifdef PRISM_ASSERTION
00314 9970 format (1x, a, ': number of neighbors', i2, '; expected at least', i2)
00315 #endif
00316 
00317       end subroutine psmile_neigh_trili_3d

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1