psmile_neigh_trili_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_trili_gauss2
00009 !
00010 ! !INTERFACE:
00011 
00012       subroutine psmile_neigh_trili_gauss2 (                       &
00013                grid_id, grid_valid_shape, interpolation_mode,      &
00014                srcloc, virtual_cell, nloc, virtual_cell_available, &
00015                neighbors_3d, num_neigh, ierror)
00016 !
00017 ! !USES:
00018 !
00019       use PRISM_constants
00020       use PSMILe, dummy_interface => PSMILe_Neigh_trili_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 8 corners)
00066 !        interpolation_mode = 2 : Bilinear interpolation
00067 !                                 (determines 4 corners)
00068 !        interpolation_mode = 1 : Linear   interpolation
00069 !                                 (determines 2 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 !     ^
00084 !     |  4    3
00085 !
00086 !     j  1    2
00087 !
00088 !       i ---->
00089 !
00090       Integer, Intent (Out)           :: neighbors_3d (ndim_3d, nloc, num_neigh)
00091 
00092 !     Indices of neighbor locations (interpolation bases)
00093 
00094       Integer, Intent (Out)           :: ierror
00095 
00096 !     Returns the error code of PSMILE_Neigh_tril_gauss2;
00097 !             ierror = 0 : No error
00098 !             ierror > 0 : Severe error
00099 !
00100 ! !DEFINED PARAMETERS:
00101 !
00102       integer, parameter              :: shift_3d(ndim_3d, 9) = 
00103                                              reshape ((/-1,-1,0, 0,-1,0, +1,-1,0,
00104                                                         -1, 0,0, 0, 0,0, +1, 0,0,
00105                                                         -1,+1,0, 0,+1,0, +1,+1,0/), 
00106                                                       (/ndim_3d,9/))
00107 !
00108 ! !LOCAL VARIABLES
00109 !
00110 !     ... for locations searched
00111 !
00112       Integer                         :: i, n
00113       Integer                         :: n_corners
00114 
00115 #ifdef DEBUG_TRACE
00116 !
00117 !     ... for debugging
00118 !
00119       integer                         :: ictl_neigh_global_1d(4), ictl_neigh_local_1d(4)
00120 #endif
00121 !
00122 ! !DESCRIPTION:
00123 !
00124 ! Subroutine "psmile_neigh_tricu_gauss2" generates the stencil for the cubic
00125 ! interpolation and stores the local 1d coordinates the stencil in neighbors_3d.
00126 !
00127 ! The subroutine is designed for (source) grids of type "PRISM_Gaussreduced_regvert".
00128 !
00129 ! !REVISION HISTORY:
00130 !
00131 !   Date      Programmer   Description
00132 ! ----------  ----------   -----------
00133 ! 03.07.21    H. Ritzdorf  created
00134 ! 12.01.11    M. Hanke     revisited
00135 ! 18.02.11    M. Hanke     rewritten
00136 !
00137 !EOP
00138 !----------------------------------------------------------------------
00139 !
00140 !  $Id: psmile_neigh_trili_gauss2.F90 3011 2011-03-10 17:50:02Z hanke $
00141 !  $Author: hanke $
00142 !
00143    Character(len=len_cvs_string), save :: mycvs = 
00144        '$Id: psmile_neigh_trili_gauss2.F90 3011 2011-03-10 17:50:02Z hanke $'
00145 !
00146 !----------------------------------------------------------------------
00147 !
00148 !===> Prologue
00149 !
00150 #ifdef VERBOSE
00151       print 9990, trim(ch_id)
00152       call psmile_flushstd
00153 #endif /* VERBOSE */
00154 
00155 !
00156 !===> Initialization
00157 !
00158       ierror  = 0
00159       if (interpolation_mode == 2) then
00160          n_corners = 4
00161       else if (interpolation_mode == 3) then
00162          n_corners = 8
00163       else
00164          ierror = PRISM_Error_Internal
00165          call psmile_error ( ierror, 'unsupported interpolation mode in psmile_neigh_trili', &
00166                              (/interpolation_mode/), 1, &
00167                              __FILE__, __LINE__ )
00168       endif
00169 !
00170 !===> inital checks
00171 !
00172 #ifdef PRISM_ASSERTION
00173 !
00174 !===> Is the dimension of array "neighbors_3d" sufficient
00175 !
00176        if (num_neigh < n_corners) then
00177          print 9970, trim(ch_id), num_neigh, n_corners
00178          call psmile_assert (__FILE__, __LINE__, &
00179                              'Number of neighbors is insufficient')
00180        endif
00181 !
00182 !===> Are the locations within the correct shape ?
00183 !
00184       do i = 1, nloc
00185 
00186          if (srcloc(1,i) < grid_valid_shape(1,1)   .or. &
00187              srcloc(1,i) > grid_valid_shape(2,1)   .or. &
00188              srcloc(2,i) < grid_valid_shape(1,2)   .or. &
00189              srcloc(2,i) > grid_valid_shape(2,2)   .or. &
00190              srcloc(3,i) < grid_valid_shape(1,3)-1 .or. &
00191              srcloc(3,i) > grid_valid_shape(2,3)) then
00192 
00193             print *, "Incorrect index in i", i, "src_loc(:,i)", srcloc (:, i)
00194             print *, "grid_valid_shape", grid_valid_shape
00195             call psmile_assert (__FILE__, __LINE__, &
00196                                 'wrong index')
00197          endif
00198       end do
00199 #endif
00200 
00201 !
00202 !==> Actual work
00203 !
00204       ! 1st generate the 3d stencil
00205 
00206       neighbors_3d(:,:,1) = psmile_gauss_local_1d_to_3d (grid_id, abs(srcloc(1,:)), nloc)
00207 
00208       if (virtual_cell_available) then
00209          ! for all locations
00210          do n = 1, nloc
00211 
00212             if (virtual_cell(n) == 0) then
00213 
00214                neighbors_3d(:,n,1:4) = psmile_gauss_get_bili_stencil (grid_id, neighbors_3d(:,n,1))
00215 
00216             else
00217 
00218                neighbors_3d(:,n,1:4) = psmile_gauss_shift_bili_stencil (grid_id, neighbors_3d(:,n,1), &
00219                                                                         shift_3d(:,virtual_cell(n)))
00220 
00221             endif
00222          enddo ! n
00223       else
00224          do n = 1, nloc
00225             neighbors_3d(:,n,1:4) = psmile_gauss_get_bili_stencil (grid_id, neighbors_3d(:,n,1))
00226          enddo ! n
00227       endif
00228 
00229 #ifdef DEBUG_TRACE
00230       if (ictl > 0 .and. ictl <= nloc) then
00231          print *, "neighbors_3d (3d):"
00232          do i = 1, 4
00233             print *, ' neighbors_3d (:,ictl,i) ', i, ':', neighbors_3d (:, ictl, i)
00234          enddo
00235       endif
00236 #endif
00237 
00238       ! 2nd transform the 3d coordinates into local 1d ones
00239 
00240       do i = 1, 4
00241 
00242          neighbors_3d(1,:,i) = psmile_gauss_3d_to_global_1d (grid_id, neighbors_3d(:,:,i), nloc)
00243          neighbors_3d(2:3,:,i) = 1
00244 #ifdef DEBUG_TRACE
00245          if (ictl > 0 .and. ictl < nloc) then
00246             ictl_neigh_global_1d(i) = neighbors_3d (1, ictl, i)
00247          endif
00248 #endif
00249 
00250          neighbors_3d(1,:,i) = psmile_gauss_1d_global_to_local (grid_id, neighbors_3d(1,:,i), nloc, 0)
00251 
00252 #ifdef DEBUG_TRACE
00253          if (ictl > 0 .and. ictl < nloc) then
00254             ictl_neigh_local_1d(i) = neighbors_3d (1, ictl, i)
00255          endif
00256 #endif
00257       enddo
00258 
00259 #ifdef DEBUG_TRACE
00260       if (ictl > 0 .and. ictl < nloc) then
00261          print *, "neighbors_3d (1d global):"
00262          print *, ' neighbors_3d (1,ictl,1:4) ', ictl_neigh_global_1d
00263          print *, "neighbors_3d (1d local):"
00264          print *, ' neighbors_3d (1,ictl,1:4) ', ictl_neigh_local_1d
00265       endif
00266 #endif
00267 
00268 !
00269       if ( interpolation_mode == ndim_3d ) then
00270 !cdir vector
00271          do i = 1, nloc
00272             neighbors_3d (1:2, i, 5:8) = neighbors_3d (1:2, i, 1:4)
00273          enddo
00274       endif
00275 !
00276 !===> ... K indices of neighbour indices
00277 !
00278       do i = 1, n_corners
00279          neighbors_3d (3, 1:nloc, i) = srcloc(3,1:nloc)
00280       enddo
00281 
00282       if (interpolation_mode == ndim_3d .and. &
00283           grid_valid_shape(2,3) - grid_valid_shape(1,3) > 0) then
00284 
00285          do i = 5, 8
00286             neighbors_3d (3, 1:nloc, i) = neighbors_3d (3, 1:nloc, i) + 1
00287          enddo
00288       endif
00289 !
00290 !===> All done
00291 !
00292 #ifdef VERBOSE
00293       print 9980, trim(ch_id)
00294 
00295       call psmile_flushstd
00296 #endif /* VERBOSE */
00297 !
00298 !  Formats:
00299 !
00300 9990 format (1x, a, ': psmile_neigh_trili_gauss2')
00301 9980 format (1x, a, ': psmile_neigh_trili_gauss2: eof')
00302 
00303 #ifdef PRISM_ASSERTION
00304 9970 format (1x, a, ': number of neighbors', i2, '; expected at least', i2)
00305 #endif
00306 
00307       end subroutine psmile_neigh_trili_gauss2

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1