psmile_neigh_tricu_gauss2.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! Copyright 2011, DKRZ, Hamburg, Germany.
00004 ! All rights reserved. Use is subject to OASIS4 license terms.
00005 !-----------------------------------------------------------------------
00006 !BOP
00007 !
00008 ! !ROUTINE: psmile_neigh_tricu_gauss2
00009 !
00010 ! !INTERFACE:
00011 
00012       subroutine psmile_neigh_tricu_gauss2 (                       &
00013                grid_id, grid_valid_shape, interpolation_mode,      &
00014                srcloc, virtual_cell, nloc, virtual_cell_available, &
00015                neighbors_3d, num_neigh, neigh_bascule, ierror)
00016 !
00017 ! !USES:
00018 !
00019       use PRISM_constants
00020       use PSMILe, dummy_interface => PSMILe_Neigh_tricu_gauss2
00021       use psmile_grid_reduced_gauss
00022 #ifdef DEBUG_TRACE
00023       use psmile_debug_trace
00024 #endif
00025 
00026       Implicit none
00027 !
00028 ! !INPUT PARAMETERS:
00029 !
00030       Integer, Intent (In)            :: nloc
00031 !
00032 !     Total number of locations to be transferred
00033 !
00034       Integer, Intent (In)             :: srcloc (ndim_3d, nloc)
00035 !
00036 !     Indices of the (method) grid cell in which the point was found.
00037 
00038       Integer, Intent (In)            :: virtual_cell (nloc)
00039 
00040 !     Code whether destination point is located in virtual cell with
00041 !
00042 !     virtual_cell (n) = 0 : Not located in a virtual cell
00043 !     virtual_cell (n) > 0 :     Located in a virtual cell
00044 !                      = 1 : (-1,-1) direction
00045 !                      = 2 : ( 0,-1) direction
00046 !                      = 3 : ( 1,-1) direction
00047 !                      = 4 : (-1, 0) direction
00048 !                      = 6 : ( 1, 0) direction
00049 !                      = 7 : (-1, 1) direction
00050 !                      = 8 : ( 0, 1) direction
00051 !                      = 9 : ( 1, 1) direction
00052 
00053       Integer, Intent (In)            :: grid_id
00054 
00055 !     Grid handle
00056 
00057       Integer, Intent (In)            :: grid_valid_shape (2, ndim_3d)
00058 
00059 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00060 !
00061       Integer,            Intent (In) :: interpolation_mode
00062 !
00063 !     Specifies the interpolation mode with
00064 !        interpolation_mode = 3 : Tri-linear or bilinear/linear interpolation
00065 !                                 (determines 64 corners) not supported
00066 !        interpolation_mode = 2 : Bilinear or bicubic interpolation
00067 !                                 (determines 16 corners)
00068 !        interpolation_mode = 1 : Linear   interpolation
00069 !                                 (determines 4 corners) not supported
00070 !
00071       Integer,            Intent (In) :: num_neigh
00072 !
00073 !     Last dimension of neighbors array "neighbors_3d"
00074 !
00075       Logical,            Intent (In) :: virtual_cell_available
00076 !
00077 !     Is the virtual cell info available ?
00078 !
00079 ! !OUTPUT PARAMETERS:
00080 !
00081 !     Location of indices for neighbors_3d
00082 !
00083 !           13   14   15   16
00084 !
00085 !     ^      9   10   11   12
00086 !     |
00087 !     |      5    6    7    8
00088 !
00089 !     j      1    2    3    4
00090 !
00091 !       i ---->
00092 !
00093       Integer, Intent (Out)           :: neighbors_3d (ndim_3d, nloc, num_neigh)
00094 
00095 !     Indices of neighbor locations (interpolation bases)
00096 
00097       Integer, Intent (Out)           :: neigh_bascule(nloc)
00098 
00099 !     Indicator for special index ordering
00100 
00101       Integer, Intent (Out)           :: ierror
00102 
00103 !     Returns the error code of PSMILE_Neigh_tricu_gauss2;
00104 !             ierror = 0 : No error
00105 !             ierror > 0 : Severe error
00106 !
00107 ! !DEFINED PARAMETERS:
00108 !
00109       integer, parameter              :: shift_3d(ndim_3d, 9) = 
00110                                              reshape ((/-1,-1,0, 0,-1,0, +1,-1,0,
00111                                                         -1, 0,0, 0, 0,0, +1, 0,0,
00112                                                         -1,+1,0, 0,+1,0, +1,+1,0/), 
00113                                                       (/ndim_3d,9/))
00114 !
00115 ! !LOCAL VARIABLES
00116 !
00117 !     ... for locations searched
00118 !
00119       Integer                         :: i, n
00120 !
00121 !     ... for error handling
00122 !
00123       Integer, Parameter              :: nerrp = 2
00124       Integer                         :: ierrp (nerrp)
00125 
00126 #ifdef DEBUG_TRACE
00127 !
00128 !     ... for debugging
00129 !
00130       integer                         :: ictl_neigh_global_1d(16), ictl_neigh_local_1d(16)
00131 #endif
00132 !
00133 ! !DESCRIPTION:
00134 !
00135 ! Subroutine "psmile_neigh_tricu_gauss2" generates the stencil for the cubic
00136 ! interpolation and stores the local 1d coordinates the stencil in neighbors_3d.
00137 ! In addition it stores the information whether a stencil covers the pole or
00138 ! not in neigh_bascule.
00139 !
00140 ! The subroutine is designed for (source) grids of type "PRISM_Gaussreduced_regvert".
00141 !
00142 ! !REVISION HISTORY:
00143 !
00144 !   Date      Programmer   Description
00145 ! ----------  ----------   -----------
00146 ! 03.07.21    H. Ritzdorf  created for trili
00147 ! 05.05.09    R. Redler    modified for cubic interpolation
00148 ! 27.01.11    M. Hanke     rewritten
00149 !
00150 !EOP
00151 !----------------------------------------------------------------------
00152 !
00153 !  $Id: psmile_neigh_tricu_gauss2.F90 2968 2011-02-18 15:26:34Z hanke $
00154 !  $Author: hanke $
00155 !
00156    Character(len=len_cvs_string), save :: mycvs = 
00157        '$Id: psmile_neigh_tricu_gauss2.F90 2968 2011-02-18 15:26:34Z hanke $'
00158 !
00159 !----------------------------------------------------------------------
00160 !
00161 !===> Prologue
00162 !
00163 #ifdef VERBOSE
00164       print 9990, trim(ch_id)
00165       call psmile_flushstd
00166 #endif /* VERBOSE */
00167 
00168 
00169 !
00170 !===> inital checks
00171 !
00172 #ifdef PRISM_ASSERTION
00173 !
00174 !===> Control interpolation mode
00175 !
00176       if (interpolation_mode /= 2) then
00177          ierrp (1) = interpolation_mode
00178          ierror = PRISM_Error_Internal
00179 
00180          call psmile_error ( ierror, 'unsupported interpolation mode in psmile_neigh_tricu_gauss2', &
00181                              ierrp, 1, __FILE__, __LINE__ )
00182          return
00183       endif
00184 !
00185 !===> Is the dimension of array "neighbors_3d" sufficient
00186 !
00187       if (num_neigh < 16) then
00188          print 9970, trim(ch_id), num_neigh, 16
00189          call psmile_assert (__FILE__, __LINE__, &
00190                              'Number of neighbors is insufficient')
00191       endif
00192 !
00193 !===> Are the locations within the correct shape ?
00194 !     Note: the scrloc's are source locations in the
00195 !           method grid which has an virtual cell 0
00196 !           (negative for Gauss Grid).
00197 !
00198       do i = 1, nloc
00199 !
00200          if (abs(srcloc(1,i)) < grid_valid_shape(1,1)   .or. &
00201              abs(srcloc(1,i)) > grid_valid_shape(2,1)   .or. &
00202              abs(srcloc(2,i)) < grid_valid_shape(1,2)   .or. &
00203              abs(srcloc(2,i)) > grid_valid_shape(2,2)   .or. &
00204              abs(srcloc(3,i)) < grid_valid_shape(1,3)-1 .or. &
00205              abs(srcloc(3,i)) > grid_valid_shape(2,3)) exit
00206       end do
00207 !
00208       if (i <= nloc) then
00209          print *, "Incorrect index in i", i, srcloc (:, i)
00210          print *, grid_valid_shape
00211          call psmile_assert (__FILE__, __LINE__, &
00212                              'wrong index')
00213       endif
00214 #endif
00215 !
00216 !===> Initialization
00217 !
00218       ierror  = 0
00219 
00220 !
00221 !==> Actual work
00222 !
00223       ! 1st generate the 3d stencil
00224 
00225       if (virtual_cell_available) then
00226          ! for all locations
00227          do n = 1, nloc
00228 
00229             if (virtual_cell(n) == 0) then
00230 
00231                neighbors_3d(:,n,1:16) = psmile_gauss_get_bicu_stencil (grid_id, &
00232                                           psmile_gauss_local_1d_to_3d (grid_id, abs(srcloc(1,n))))
00233 
00234             else
00235 
00236                neighbors_3d(:,n,1:16) = psmile_gauss_shift_bicu_stencil (grid_id,                  &
00237                                           psmile_gauss_local_1d_to_3d (grid_id, abs(srcloc(1,n))), &
00238                                           shift_3d(:,virtual_cell(n)))
00239 
00240             endif
00241          enddo ! n
00242       else
00243          do n = 1, nloc
00244             neighbors_3d(:,n,1:16) = psmile_gauss_get_bicu_stencil (grid_id, &
00245                                        psmile_gauss_local_1d_to_3d (grid_id, abs(srcloc(1,n))))
00246          enddo ! n
00247       endif
00248 
00249 #ifdef DEBUG_TRACE
00250       if (ictl > 0 .and. ictl <= nloc) then
00251          print *, "neighbors_3d (3d):"
00252          do i = 1, 16
00253             print *, ' neighbors_3d (:,ictl,i) ', i, ':', neighbors_3d (:, ictl, i)
00254          enddo
00255       endif
00256 #endif
00257 
00258       ! 2nd check for stencils that go over the pole
00259 
00260       where (neighbors_3d(2,:,6) >= grids(grid_id)%nbr_latitudes-1 .or. &
00261              neighbors_3d(2,:,6) == 1)
00262 
00263          neigh_bascule(:) = 1
00264 
00265       else where
00266 
00267          neigh_bascule(:) = 0
00268 
00269       end where
00270 
00271 #ifdef DEBUG_TRACE
00272       if (ictl > 0 .and. ictl < nloc) then
00273          print *, "neigh_bascule(ictl)", neigh_bascule(ictl)
00274       endif
00275 #endif
00276 
00277       ! 3rd transform the 3d coordinates into local 1d ones
00278 
00279       do i = 1, 16
00280 
00281          neighbors_3d(1,:,i) = psmile_gauss_3d_to_global_1d (grid_id, neighbors_3d(:,:,i), nloc)
00282          neighbors_3d(2:3,:,i) = 1
00283 #ifdef DEBUG_TRACE
00284          if (ictl > 0 .and. ictl < nloc) then
00285             ictl_neigh_global_1d(i) = neighbors_3d (1, ictl, i)
00286          endif
00287 #endif
00288 
00289          neighbors_3d(1,:,i) = psmile_gauss_1d_global_to_local (grid_id, neighbors_3d(1,:,i), nloc, 0)
00290 
00291 #ifdef DEBUG_TRACE
00292          if (ictl > 0 .and. ictl < nloc) then
00293             ictl_neigh_local_1d(i) = neighbors_3d (1, ictl, i)
00294          endif
00295 #endif
00296       enddo
00297 
00298 #ifdef DEBUG_TRACE
00299       if (ictl > 0 .and. ictl < nloc) then
00300          print *, "neighbors_3d (1d global):"
00301          print *, ' neighbors_3d (1,ictl,1:16) ', ictl_neigh_global_1d
00302          print *, "neighbors_3d (1d local):"
00303          print *, ' neighbors_3d (1,ictl,1:16) ', ictl_neigh_local_1d
00304       endif
00305 #endif
00306 
00307 !
00308       if ( num_neigh == 32 ) then
00309 !cdir vector
00310          do i = 1, nloc
00311             neighbors_3d (1:2, i, 17:32) = neighbors_3d (1:2, i, 1:16)
00312          enddo
00313       endif
00314 !
00315 !===> ... K indices of neighbour indices
00316 !
00317       do i = 1, num_neigh
00318          neighbors_3d (3, 1:nloc, i) = srcloc(3,1:nloc)
00319       enddo
00320 
00321       if (grid_valid_shape(2,3) - grid_valid_shape(1,3) > 0) then
00322 
00323          if (num_neigh == 32) then
00324             do i = 17, 32
00325                neighbors_3d (3, 1:nloc, i) = neighbors_3d (3, 1:nloc, i) + 1
00326             enddo
00327          endif
00328       endif
00329 !
00330 !===> All done
00331 !
00332 #ifdef VERBOSE
00333       print 9980, trim(ch_id)
00334 
00335       call psmile_flushstd
00336 #endif /* VERBOSE */
00337 !
00338 !  Formats:
00339 !
00340 9990 format (1x, a, ': psmile_neigh_tricu_gauss2')
00341 9980 format (1x, a, ': psmile_neigh_tricu_gauss2: eof', i6)
00342 
00343 #ifdef PRISM_ASSERTION
00344 9970 format (1x, a, ': number of neighbors', i2, '; expected at least', i2)
00345 #endif
00346 
00347       end subroutine psmile_neigh_tricu_gauss2

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1