psmile_trili_3d_extra_off.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_Trili_3d_extra_off
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_trili_3d_extra_off (comp_info, search,         &
00012                       grid_id, mask_array, mask_shape, mask_available, &
00013                       ibuf, len_item, n_send, num_neigh,               &
00014                       ierror)
00015 !
00016 ! !USES:
00017 !
00018       use PRISM
00019 !
00020       use PSMILe, dummy_interface => PSMILe_Trili_3d_extra_off
00021 
00022       implicit none
00023 !
00024 ! !INPUT PARAMETERS:
00025 !
00026       Type (Enddef_comp),           Intent (In)    :: comp_info
00027 !
00028 !     Info on the component in which the donor cells
00029 !     should be searched.
00030 
00031       Integer,                      Intent (In)    :: grid_id
00032 
00033 !     Grid Id of the source grid (grid on which the points are searched)
00034 !
00035       Integer,                      Intent (In)    :: mask_shape (2, ndim_3d)
00036 
00037 !     Dimension of (method) mask array
00038 
00039       Logical,                      Intent (In)    ::     
00040           mask_array ( mask_shape (1,1):mask_shape (2,1), 
00041                        mask_shape (1,2):mask_shape (2,2), 
00042                        mask_shape (1,3):mask_shape (2,3) )
00043 !     Mask of the method
00044 
00045       Logical,                     Intent (In)     :: mask_available
00046 
00047 !     Is mask specified in array "mask_array" ?
00048 !     mask_available = .false. : Mask is not available
00049 !                      .true.  : Mask is     available
00050 
00051       Integer,                     Intent (In)     :: len_item
00052 !
00053 !     Number of pieces of information in integer buffer "ibuf".
00054 !        1:3: (i,j,k) index of lower left corner
00055 !        4  : Index in
00056 !        5  : Code for points required
00057 !
00058       Integer,                     Intent (In)    :: n_send
00059 !
00060 !     Number of extra points sent
00061 
00062       Integer,                     Intent (In)    :: num_neigh
00063 !
00064 !     (Maximal) Number of interpolations bases required.
00065 !     Need to be the first "num_neigh" bases in "ijkstd" (see below).
00066 !
00067 !
00068 ! !INPUT/OUTPUT PARAMETERS:
00069 !
00070       Type (Enddef_global_search), Intent (InOut) :: search
00071 
00072 !     Data on the points to be searched
00073 
00074       Integer,                     Intent (InOut) :: ibuf (len_item, n_send)
00075 !
00076 !     Integer buffer containing the packed integer data.
00077 !     On return, ibuf (5, *) contains the code of the points found.
00078 !
00079 ! !OUTPUT PARAMETERS:
00080 !
00081       Integer,                     Intent (Out)   :: ierror
00082 
00083 !     Returns the error code of PSMILe_Search_donor_extra_off;
00084 !             ierror = 0 : No error
00085 !             ierror > 0 : Severe error
00086 !
00087 ! !LOCAL PARAMETERS:
00088 !
00089 ! n_corners_3d = Number of interpolation bases in 3d case
00090 !
00091 ! masked_out   = Hash value for a point which is masked out
00092 !
00093       Integer, Parameter           :: n_corners_3d = 2 * 2 * 2
00094 !
00095       Integer, Parameter           :: masked_out = 0
00096 !
00097 ! !LOCAL VARIABLES
00098 !
00099 !     ... loop variables
00100 !
00101       Integer                      :: i, j, n
00102 !
00103 !     ... 
00104 !
00105       Integer                      :: index0
00106       Integer                      :: length (ndim_3d)
00107 !
00108 !     ... For Grids
00109 !
00110       Type (Grid), Pointer         :: grid_info
00111       Integer,     Pointer         :: grid_valid_shape (:, :)
00112       Logical,     Pointer         :: cyclic (:)
00113 !
00114 !     ... For searched points of control volume
00115 !
00116       Integer                      :: code, n_corners, nlocs
00117 !
00118       Integer                      :: ijkstd (ndim_3d, n_corners_3d)
00119       Integer                      :: ijkctl (ndim_3d, n_corners_3d)
00120       Integer, Allocatable         :: locs (:, :)
00121       Integer, Allocatable         :: hash (:)
00122       Logical, Allocatable         :: ijkmsk (:, :)
00123 !
00124 !     ... for error parameters
00125 !
00126       Integer, parameter           :: nerrp = 1
00127       Integer                      :: ierrp (nerrp)
00128 !
00129 ! !DESCRIPTION:
00130 !
00131 ! Subroutine "PSMILe_Trili_3d_extra_off" performs the additional (global)
00132 ! search for
00133 !
00134 ! TODO: PSMILe_Trili_3d_extra_off und PSMILe_Tricu_3d_extra_off vereinigen
00135 !       locs alloziieren und ausrechnen und danach gleiche Routine
00136 !       verwenden
00137 !       
00138 !
00139 ! !REVISION HISTORY:
00140 !
00141 !   Date      Programmer   Description
00142 ! ----------  ----------   -----------
00143 ! 03.07.05    H. Ritzdorf  created
00144 !
00145 !EOP
00146 !----------------------------------------------------------------------
00147 !
00148 ! $Id: psmile_trili_3d_extra_off.F90 2082 2009-10-21 13:31:19Z hanke $
00149 ! $Author: hanke $
00150 !
00151    Character(len=len_cvs_string), save :: mycvs = 
00152        '$Id: psmile_trili_3d_extra_off.F90 2082 2009-10-21 13:31:19Z hanke $'
00153 !
00154 !----------------------------------------------------------------------
00155 !
00156 !  Relative indices of corner
00157 !
00158 #ifdef FORTRAN_ORDER
00159       data ((ijkstd (i, n), i=1,ndim_3d), n = 1, n_corners_3d) &
00160                             /  0, 0, 0,   1, 0, 0, &
00161                                0, 1, 0,   1, 1, 0, &
00162                                0, 0, 1,   1, 0, 1, &
00163                                0, 1, 1,   1, 1, 1/
00164 
00165 #else
00166 !huhu Offenbar erwartet Damien's Routine eine andere Ordnung
00167       data ((ijkstd (i, n), i=1,ndim_3d), n = 1, n_corners_3d) &
00168                             /  0, 0, 0,   1, 0, 0, &
00169                                1, 1, 0,   0, 1, 0, &
00170                                0, 0, 1,   1, 0, 1, &
00171                                1, 1, 1,   0, 1, 1/
00172 #endif
00173 !
00174 !----------------------------------------------------------------------
00175 !
00176 !  Initialization
00177 !
00178 #ifdef VERBOSE
00179       print 9990, trim(ch_id), comp_info%comp_id
00180 
00181       call psmile_flushstd
00182 #endif /* VERBOSE */
00183 !
00184       ierror = 0
00185       n_corners = num_neigh
00186 !
00187 !===> Get grid info
00188 !
00189 !  grid_valid_shape (2, ndim_3d) : Specifies the valid block shape
00190 !                                  for the "ndim_3d"-dimensional block
00191 !                                  (without halo/overlap regions)
00192 !  cyclic (ndim_3d) : Does the block have cyclic coordinates
00193 !                     in the corresponding direction ?
00194 !
00195       grid_info        => Grids(grid_id)
00196 !
00197       grid_valid_shape => grid_info%grid_shape
00198       cyclic           => grid_info%cyclic
00199 !
00200       length (1:ndim_3d) = grid_valid_shape(2,1:ndim_3d) - &
00201                            grid_valid_shape(1,1:ndim_3d) + 1
00202 !
00203 #ifdef PRISM_ASSERTION
00204       if (grid_info%grid_type /= PRISM_Reglonlatvrt     .and. &
00205           grid_info%grid_type /= PRISM_Irrlonlat_Regvrt .and. &
00206           grid_info%grid_type /= PRISM_Irrlonlatvrt) then
00207 !
00208          print *, "grid_type", grid_info%grid_type
00209          call psmile_assert (__FILE__, __LINE__, &
00210                    "This routine is not designed for this grid type")
00211       endif
00212 !
00213       if (num_neigh < 1 .or. num_neigh > n_corners_3d) then
00214          print *, 'num_neigh', num_neigh, n_corners_3d
00215          call psmile_assert ( __FILE__, __LINE__, &
00216                 'Invalid value for num_neigh (number of interpolation bases')
00217       endif
00218 #endif
00219 !
00220 !===> Allocate mask "ijkmsk" for points to be searched.
00221 !     This corresponds to the decoded code "code".
00222 !
00223       Allocate (ijkmsk (n_send, n_corners), stat = ierror)
00224       if (ierror /= 0) then
00225          ierrp (1) = n_send * n_corners
00226 
00227          ierror = PRISM_Error_Alloc
00228 
00229          call psmile_error ( ierror, 'ijkmsk', ierrp, 1, &
00230                  __FILE__, __LINE__ )
00231          return
00232       endif
00233 !
00234 !===> Decode code for searched points and
00235 !     create list of locations "locs" of points required
00236 !
00237       code = 1
00238 !
00239          do j = 1, n_corners
00240 !cdir vector
00241             do i = 1, n_send
00242             ijkmsk (i,j) = IAND (code, ibuf (5, i)) /= 0
00243             end do
00244 
00245          code = code * 2
00246          end do
00247 !
00248       nlocs = Count (ijkmsk(:,:))
00249 !
00250 #ifdef PRISM_ASSERTION
00251       if (nlocs <= 0) then
00252          call psmile_assert ( __FILE__, __LINE__, &
00253                              'Number of points to be searched == 0 ?!?')
00254       endif
00255 #endif
00256 !
00257 #ifdef DEBUGX
00258       print *, 'code for locations searched', n_send
00259          do i = 1, n_send
00260          print *, 'code', ibuf (5, i), ijkmsk(i, :)
00261          end do
00262 #endif
00263 !
00264       Allocate (locs (ndim_3d, nlocs), hash (nlocs), stat = ierror)
00265       if (ierror /= 0) then
00266          ierrp (1) = (ndim_3d+1) * nlocs
00267 
00268          ierror = PRISM_Error_Alloc
00269 
00270          call psmile_error ( ierror, 'locs, hash', ierrp, 1, &
00271                  __FILE__, __LINE__ )
00272          return
00273       endif
00274 !
00275 !===> For special cases (2d Hyperplanes)
00276 !     ??? Braucht man hier nicht ein spezielles Flag,
00277 !         dass das globale Gebiet eine Hyperplane ist ?
00278 !
00279       ijkctl = ijkstd
00280 !
00281          do j = 1, ndim_3d
00282          if (length(j) == 1) ijkctl (j, :) = 0
00283          end do
00284 !
00285       n = 0
00286          do j = 1, n_corners
00287 !cdir vector
00288             do i = 1, n_send
00289             if (ijkmsk (i,j)) then
00290                n = n + 1
00291                locs (1, n) = ibuf (1, i) + ijkctl (1, j)
00292                locs (2, n) = ibuf (2, i) + ijkctl (2, j)
00293                locs (3, n) = ibuf (3, i) + ijkctl (3, j)
00294             end if
00295             end do ! i
00296          end do ! j
00297 !
00298 #ifdef PRISM_ASSERTION
00299       if (n /= nlocs) then
00300          print *, 'n, nlocs', n, nlocs
00301          call psmile_assert ( __FILE__, __LINE__, &
00302                 'Inconsistent values of n and nlocs; must be same value')
00303       endif
00304 #endif
00305 !
00306 !===> Set indices for cyclic coordinate directions
00307 !
00308          do i = 1, ndim_3d
00309          if (cyclic(i) .and. length(i) > 1) then
00310             index0 = grid_valid_shape(1,i)
00311 !
00312 !cdir vector
00313                do n = 1, nlocs
00314                locs (i, n) = index0 + mod (locs(i, n) - index0, length(i))
00315                end do
00316          endif
00317          end do
00318 !
00319 !===> Create compact list of points to be sent and 
00320 !     return hash value "hash" (index in fortran order) for each location
00321 !
00322       call psmile_hash_extra (search, locs, hash, nlocs,                &
00323               mask_array, mask_shape, mask_available, grid_valid_shape, &
00324               ierror)
00325       if (ierror > 0) return
00326 !
00327 #ifdef DEBUGX
00328       print *, 'hash values and locs ', grid_valid_shape
00329       n = 0
00330          do j = 1, n_corners
00331 !cdir vector
00332             do i = 1, n_send
00333             if (ijkmsk (i,j)) then
00334                n = n + 1
00335                print *, 'i, j, n, hash(n), locs(:,n) ', &
00336                          i, j, n, hash(n), locs(:,n)
00337             end if
00338             end do ! i
00339          end do ! j
00340 #endif
00341 !
00342 !===> Save coded mask of points found in "ibuf"
00343 !     ??? Ob das so clever ist ?
00344 !
00345       if (search%n_liste > 0) then
00346          ibuf (5, 1:n_send) = 0
00347 !
00348          n = 0
00349          code = 1
00350             do j = 1, n_corners
00351 !cdir vector
00352                do i = 1, n_send
00353                if (ijkmsk (i,j)) then
00354 
00355                   n = n + 1
00356 !
00357                   if (hash (n) >= 0) then
00358 !
00359 !===> ...... Required "j-th" interpolation base was found
00360 !            (may be masked out (hash(n) == masked_out == 0).
00361 !            Corresponding value is stored in position "index_found(n)".
00362 !
00363                      ibuf (5, i) = ibuf (5, i) + code
00364                   endif
00365 !
00366                endif
00367                end do ! i
00368 
00369             code = code * 2
00370             end do ! j
00371 
00372 #ifdef PRISM_ASSERTION
00373          if (n /= nlocs) then
00374             print *, 'nlocs, n', nlocs, n
00375             call psmile_assert ( __FILE__, __LINE__, &
00376                                 'n /= nlocs')
00377          endif
00378 #endif
00379 !
00380 #ifdef DEBUGX
00381         print *, 'code for locations found', n_send
00382             do i = 1, n_send
00383             print *, 'code', i, ibuf (5, i), ijkmsk(i, :)
00384             end do
00385 #endif 
00386 
00387       endif
00388 !
00389 !===> Deallocate memory allocated
00390 !
00391       Deallocate (locs, hash, ijkmsk)
00392 !
00393 !===> All done
00394 !
00395 #ifdef VERBOSE
00396       print 9980, trim(ch_id), ierror, search%n_found, n_send
00397 
00398       call psmile_flushstd
00399 #endif /* VERBOSE */
00400 !
00401       return
00402 !
00403 !  Formats:
00404 !
00405 #ifdef VERBOSE
00406 9990 format (1x, a, ': psmile_trili_3d_extra_off: comp_id =', i3)
00407 9980 format (1x, a, ': psmile_trili_3d_extra_off: eof', &
00408                     ', ierror =', i4, ', n_found =', i5, i5)
00409 #endif /* VERBOSE */
00410 
00411       end subroutine PSMILe_Trili_3d_extra_off

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1