psmile_mg_cells_1d_real.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_MG_cells_1d_real
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_mg_cells_1d_real (                &
00012                            nlev, found, loc, range,       &
00013                            search_grid_type,              &
00014                            corners1, search_dim,          &
00015                            shape, control,                &
00016                            grid_valid_shape, cyclic,      &
00017                            chmin, chmax,                  &
00018                            tol, ierror)
00019 !
00020 ! !USES:
00021 !
00022       use PRISM_constants
00023 !
00024       use PSMILe, dummy_interface => PSMILe_mg_cells_1d_real
00025 
00026       implicit none
00027 !
00028 ! !INPUT PARAMETERS:
00029 !
00030       Integer, Intent (In)            :: nlev
00031 
00032 !     Total number of levels
00033 
00034       Integer, Intent (In)            :: search_grid_type
00035 
00036 !     Type of source grid
00037 
00038       Integer, Intent (In)            :: range (2, ndim_3d)
00039 
00040 !     Dimension of loc and found
00041 
00042       Integer, Intent (In)            :: shape (2, ndim_3d)
00043 
00044 !     Dimension of coordinate arrays
00045 
00046       Integer, Intent (InOut)         :: found (range(1,1):range(2,1), 
00047                                                 range(1,2):range(2,2), 
00048                                                 range(1,3):range(2,3))
00049 
00050 !     Finest level number on which a grid cell was found for point i,j,k.
00051 !     Input :
00052 !     Level number < -1: Point was not found and
00053 !                        and last level number was (-found(i,j,k))
00054 !     Level number = -(nlev+1): Never found
00055 !     Output :
00056 !     found(i,j,k) = +1: Point (i,j,k) is located on a point
00057 !
00058 !     found(i,j,k) = -1: Point (i,j,k) is located in a cell
00059 !
00060 !     Otherwise, not contained in the cell grid.
00061 
00062       Integer, Intent (InOut)         :: loc   (range(1,1):range(2,1), 
00063                                                 range(1,2):range(2,2), 
00064                                                 range(1,3):range(2,3))
00065 
00066 !     Indices of the grid cell in which the point was found.
00067 !     The indices are relative to "shape".
00068 
00069       Real, Intent (In)               :: corners1 (shape(1,1):shape(2,1), 
00070                                                    shape(1,2):shape(2,2), 
00071                                                    shape(1,3):shape(2,3))
00072 
00073 !     Coordinates to be searched
00074 
00075       Integer, Intent (In)            :: control (2, ndim_3d)
00076 
00077 !     Input  value: index range in "coords" to be searched
00078 !     Output value: index range in "coords" for which a cell was found
00079 
00080       Integer,          Intent (In)   :: search_dim
00081 
00082 !     Dimension in which to be searched
00083 
00084       Integer,          Intent (In)   :: grid_valid_shape (2)
00085 
00086 !     Specifies the valid block shape for the "1d"-dimensional block
00087 !     Dimension of chmin and chmax
00088 
00089       Logical,          Intent (In)   :: cyclic
00090 
00091 !     Is this a (locally) cyclic coordinate
00092 
00093       Real, Intent (In)               :: chmin (grid_valid_shape(1): 
00094                                                 grid_valid_shape(2)+2)
00095 !
00096 !     Minimum value of bounding box of coordinate.
00097 ! chmin (grid_valid_shape(1)+i) contains the minimal value of bounding box of
00098 !                   cell (x_corners(grid_valid_shape(1)+i)  :
00099 !                         x_corners(grid_valid_shape(1)+i+1))
00100 !
00101 ! The first box
00102 ! chmin (grid_valid_shape(1)-1) contains the minimal value of
00103 !                                        the bounding box from
00104 !                    the virtual cell (x_corners(grid_valid_shape(1)):
00105 !                                               bounding box of
00106 !                                               corner control volume)
00107 ! The last box
00108 ! chmin (grid_valid_shape(2)) contains the minimal value of
00109 !                                      the bounding box from
00110 !                    the virtual cell (x_corners(grid_valid_shape(2)):
00111 !                                               bounding box of
00112 !                                               corner control volume)
00113 !
00114       Real, Intent (In)               :: chmax (grid_valid_shape(1): 
00115                                                 grid_valid_shape(2)+2)
00116 !
00117 !     Maximum value of bounding box of coordinate.
00118 !
00119       Real, Intent (In)               :: tol
00120 !
00121 !     Absolute tolerance for search of "identical" points
00122 !     TOL >= 0.0
00123 !
00124 ! !OUTPUT PARAMETERS:
00125 !
00126       integer, Intent (Out)           :: ierror
00127 
00128 !     Returns the error code of PSMILE_mg_cells_1d_real;
00129 !             ierror = 0 : No error
00130 !             ierror > 0 : Severe error
00131 !
00132 ! !DEFINED PARAMETERS:
00133 !
00134 !  NREFD = Number of method coordinates to be controlled.
00135 !  val_direct  = Code for locations which should to be directly transferred
00136 !                to the destination process.
00137 !  val_coupler = Code for locations which should to be transferred
00138 !                to the coupler process.
00139 
00140       Integer, Parameter              :: nrefd = 3
00141 !
00142       Integer, Parameter              :: val_direct  =  1
00143       Integer, Parameter              :: val_coupler = -1
00144 !
00145 !     ... for levels
00146 !
00147       Integer, Parameter              :: lev = 1
00148 !
00149 ! !LOCAL VARIABLES
00150 !
00151 !     ... for locations searched
00152 !
00153       Integer                         :: i, j, k, jj
00154       Integer                         :: ibegl, iendl
00155       Integer                         :: idim
00156       Integer                         :: ic
00157       Integer                         :: ijk(3)
00158 !
00159 !     ... For locations controlled
00160 !
00161       Integer                         :: irange (2)
00162       Integer                         :: ctrl(2, ndim_3d)
00163 !
00164 !     ... for search
00165 !
00166       Integer                         :: ii
00167 !
00168 #ifdef DEBUG
00169 !     ... for locations searched
00170 !
00171       Integer                         :: nfnd (0:3)
00172 #endif /* DEBUG */
00173 !
00174 ! !DESCRIPTION:
00175 !
00176 ! Subroutine "PSMILe_mg_cells_1d_real" searches the corresponding cells
00177 ! of the grid for the subgrid corners of the sending process.
00178 !
00179 ! TODO: Improve !!
00180 !       Use tol(erance) for overlap tests. Same tol has to be used later in
00181 !       PSMILe_Neigh_cells_*
00182 !
00183 ! !REVISION HISTORY:
00184 !
00185 !   Date      Programmer   Description
00186 ! ----------  ----------   -----------
00187 ! 06.07.21    R. Redler    created
00188 !
00189 !EOP
00190 !----------------------------------------------------------------------
00191 !
00192 !  $Id: psmile_mg_cells_1d_real.F90 2082 2009-10-21 13:31:19Z hanke $
00193 !  $Author: hanke $
00194 !
00195    Character(len=len_cvs_string), save :: mycvs = 
00196        '$Id: psmile_mg_cells_1d_real.F90 2082 2009-10-21 13:31:19Z hanke $'
00197 !----------------------------------------------------------------------
00198 !
00199 !  Initialization
00200 !
00201       ierror = 0
00202       ctrl = control
00203 
00204 #ifdef VERBOSE
00205       print 9990, trim(ch_id), lev, control
00206 
00207       call psmile_flushstd
00208 #endif /* VERBOSE */
00209 !
00210 #ifdef PRISM_ASSERTION
00211       if (tol < 0.0) then
00212          call psmile_assert (__FILE__, __LINE__, &
00213                              "tol must be >= 0.0")
00214       endif
00215 #endif
00216 !
00217 ! create temporary memory (control (2,1)-control(1,1)+1)*ndtry
00218 ! and do n =1,nref before i-loop ?!?
00219 !
00220 ! ? instead of controlling all nref, determine location in cell once
00221 !
00222 ! ? one-dimensional Loop instead of i,j loop
00223 !
00224 #ifdef DEBUG
00225       nfnd (:) = 0
00226 #endif /* DEBUG */
00227 
00228 #ifdef DEBUGX
00229       print *, 'begin ---'
00230       do k = control (1, 3), control (2,3)   
00231          do j = control(1,2), control (2,2) 
00232             do i = control(1,1), control (2,1) 
00233                print *, 'i, j, k, corner, loc, found', i,j,k, corners1 (i,j,k), &
00234                     loc(i,j,k), found (i,j,k)
00235             end do
00236          end do
00237       end do
00238 #endif
00239       if ( search_grid_type == PRISM_Gaussreduced_regvrt ) then
00240          idim = 1
00241       else
00242          idim = search_dim
00243       endif
00244       ijk = 0
00245       ijk(idim) = 1
00246       ctrl (2,idim) = control (2,idim) - 1
00247 !
00248 !===>
00249 !
00250       do k = ctrl (1, 3), ctrl (2,3)
00251          do j = ctrl(1,2), ctrl (2,2)
00252 !
00253 !-----------------------------------------------------------------------
00254 !        Look in the fine parts of the coarse grid cell loc(i)
00255 !-----------------------------------------------------------------------
00256 !
00257             ibegl = ctrl (1, 1)
00258 !
00259 !===> ... Look for the next cell to be controlled
00260 !
00261             do while (ibegl <= ctrl(2,1))
00262 !
00263 !cdir vector
00264                do i = ibegl, ctrl(2,1)
00265                   if (found(i, j, k) /= lev) exit
00266                end do
00267 !
00268             iendl = i - 1
00269 !
00270 !===> ... Look in the real cell (ic)
00271 !
00272             do i = ibegl, iendl
00273 !
00274                ic = loc (i,j,k)
00275 !
00276                irange (1) = max (ic-1, grid_valid_shape (1))
00277                irange (2) = min (ic+1, grid_valid_shape (2))
00278 
00279                do ii = irange (1), irange (2)
00280                   if ( chmin(ii) <= corners1(i,j,k) .and. &
00281                        chmax(ii) >= corners1(i,j,k) ) exit
00282                end do
00283 
00284                if ( chmin(ii) > corners1(i,j,k) ) ii = ii - 1
00285 
00286                if (ii <= irange(2)) then
00287 
00288                   loc (i,j,k) = ii
00289 #ifdef DEBUG
00290                   nfnd (1) = 0
00291                   nfnd (2) = nfnd (2) + 1
00292 #endif /* DEBUG */
00293                   found (i,j,k) = val_coupler
00294 
00295                else
00296 !
00297 !              Cell has no overlap with any other cell in the search grid,
00298 !              mark point as 0
00299 #ifdef DEBUG
00300                   nfnd (3) = nfnd (3) + 1
00301 !                 nfnd (2) = nfnd (2) - 1
00302 #endif /* DEBUG */
00303 !Todo             found (i,j,k) = 0
00304 
00305                endif
00306 
00307             end do ! i
00308 !
00309 !===> ... Is there an cyclic index
00310 !
00311             if (cyclic) then
00312 !
00313 !              This is an cyclic index;
00314 !              Move points, which are located in virtual cell 0
00315 !              into cell "grid_valid_shape(2)"
00316 !
00317 !cdir vector
00318                do i = ibegl, iendl
00319                   if ( loc (i,j,k) < grid_valid_shape (1) ) then
00320                        loc (i,j,k) = grid_valid_shape (2)
00321                   endif
00322                enddo
00323 !
00324             endif
00325 !
00326 !===> ... Start index of the next search
00327 !
00328             ibegl = iendl + 2
00329             end do ! while
00330 !
00331          end do ! j
00332       end do ! k
00333 !
00334 !===> Additional check for empty cells. The initial search with mg_method only searched
00335 !     for the minimum corners. Here we check whether the maximum falls into the valid
00336 !     area and in this case mark the cell as found. 
00337 !
00338       if ( search_grid_type == PRISM_Gaussreduced_regvrt ) then
00339 
00340          jj = (range(2,1)-range(1,1)+1)/2
00341          ibegl = range(1,1)
00342          iendl = range(1,1) + jj - 1
00343 
00344          do k = ctrl (1, 3), ctrl (2,3)
00345             do j = ctrl(1,2), ctrl (2,2)
00346 
00347                do i = ibegl, iendl
00348 
00349                   if ( abs(found(i   ,j,k)) /= 1 .and. &
00350                        abs(found(i+jj,j,k)) == 1 ) then
00351                      loc  (i,j,k) = loc  (i+jj,j,k)
00352                      found(i,j,k) = found(i+jj,j,k)
00353                   endif
00354 
00355                enddo
00356 
00357                do i = iendl+1, range(2,1)
00358                   found(i,j,k) = -(nlev+1)
00359                enddo
00360 
00361             enddo
00362          enddo
00363 
00364       else
00365 
00366          do k = ctrl (1,3), ctrl (2,3) 
00367             do j = ctrl (1,2), ctrl (2,2)
00368                do i = ctrl (1,1), ctrl (2,1)
00369                   if ( abs(found(i,j,k)) == 1 ) found(i,j,k) = val_coupler
00370                   if ( abs(found(i,j,k)) > 1 .and. abs(found(i+ijk(1),j+ijk(2),k+ijk(3))) == 1 ) then
00371                           found(i,j,k) = found(i+ijk(1),j+ijk(2),k+ijk(3))
00372                           loc(i,j,K)   = loc  (i+ijk(1),j+ijk(2),k+ijk(3))
00373                   endif
00374                enddo
00375             enddo
00376          enddo
00377 
00378       endif
00379 !
00380 !===> Check that location found are in the valid range, otherwise mark point as not found.
00381 !     Enforce to send all data through the coupler.
00382 !
00383       do k = range (1,3), range (2,3)   
00384          do j = range(1,2), range (2,2) 
00385             do i = range(1,1), range (2,1) 
00386                if ( abs(found(i,j,k)) == 1 ) found(i,j,k) = val_coupler
00387                if ( loc(i,j,k) < grid_valid_shape(1) .or. &
00388                     loc(i,j,k) > grid_valid_shape(2) )    &
00389                     found(i,j,k) = -(nlev+1)
00390             end do
00391          end do
00392       end do
00393 !
00394 !===> All done
00395 !
00396 
00397 #ifdef DEBUGX
00398       print *, 'end ---'
00399         do k = control (1, 3), control (2,3)
00400             do j = control(1,2), control (2,2)
00401                do i = control(1,1), control (2,1)
00402                print *, 'i, j, k, corner, loc, found', i,j,k, corners1 (i,j,k), &
00403                         loc(i,j,k), found (i,j,k)
00404                end do
00405             end do
00406         end do
00407 #endif
00408 
00409 #ifdef DEBUG
00410       print 9970, trim(ch_id), lev, nfnd
00411 9970  format (1x, a, ': psmile_mg_cells_1d_real: lev =', i3, &
00412               ': not :', i5, ', dir: ', i6, ', fnd :', i6, i5)
00413 #endif /* DEBUG */
00414 
00415 #ifdef VERBOSE
00416       print 9980, trim(ch_id), lev
00417 
00418       call psmile_flushstd
00419 #endif /* VERBOSE */
00420 !
00421 !  Formats:
00422 !
00423 9990 format (1x, a, ': psmile_mg_cells_1d_real: level', i3, &
00424                     ', control', 6i6)
00425 9980 format (1x, a, ': psmile_mg_cells_1d_real: eof, level', i3)
00426 
00427       end subroutine psmile_mg_cells_1d_real

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1