psmile_mg_prev_levels_2d_dble.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_Prev_levels_2d_dble
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_mg_prev_levels_2d_dble (grid_id, lev, nlev, &
00012                       lstijk, xyz, found, newijk, nc)
00013 !
00014 ! !USES:
00015 !
00016       use PRISM_constants
00017 !
00018       use PSMILe, dummy_interface => PSMILe_mg_prev_levels_2d_dble
00019 
00020       Implicit none
00021 !
00022 ! !INPUT PARAMETERS:
00023 !
00024       Integer, Intent (In)            :: grid_id
00025 !
00026 !     Grid Id for which the donor cells should be searched.
00027 !
00028       Integer, Intent (In)            :: lev
00029 !
00030 !     Level number of the next (fine) grid
00031 !
00032       Integer, Intent (In)            :: nlev
00033 !
00034 !     Total number of levels
00035 !
00036       Integer, Intent (In)            :: nc
00037 !
00038 !     Number of points to be searched.
00039 !
00040       Integer, Intent (In)            :: lstijk (ndim_2d, nc)
00041 !
00042 !     Last indices of cell on coarse level LEV+1.
00043 !     !!! This routine assumes that all parts on the fine grid "LEV"
00044 !     of these cells, were already controlled and point "xyz"
00045 !     was not found.
00046 !
00047       Double Precision, Intent (In)   :: xyz (ndim_2d, nc)
00048 !
00049 !     Coordinates of the points to be searched
00050 !
00051 ! !OUTPUT PARAMETERS:
00052 !
00053       Integer, Intent (Out)           :: found (nc)
00054 !
00055 !     Was the point xyz found ?
00056 !     found = 0: Not found
00057 !     found > 0: Part of the cell where point XYZ was found.
00058 !
00059       Integer, Intent (Out)           :: newijk (ndim_2d, nc)
00060 !
00061 !     Indices on level LEV if found > 0 is returned.
00062 !
00063 ! !DEFINED PARAMETERS:
00064 !
00065       Logical, Parameter              :: wide = .true.
00066       Logical, Parameter              :: small = .false.
00067 !
00068 ! !LOCAL VARIABLES
00069 !
00070       Integer                         :: i, n
00071 
00072 !     ... for Grid
00073 
00074       Type (Grid), Pointer            :: grid_info
00075       Type (Enddef_mg), Pointer       :: mg_infos (:)
00076 
00077 !     ... for levels
00078 
00079       Integer                         :: levc, levd, levdbg, levu, levubg
00080       Integer                         :: nlev1
00081       Integer                         :: nold (nc, lev:nlev-1)
00082       Integer                         :: ijk (ndim_2d, nc, lev:nlev-1)
00083       Integer                         :: ignore (ndim_2d, lev:nlev-1)
00084       Integer                         :: coarsf (ndim_2d)
00085 !
00086 #ifdef DEBUGX
00087       logical                         :: control
00088       common /huhu1/ control
00089 #endif
00090 !
00091 ! !DESCRIPTION:
00092 !
00093 ! Subroutine "PSMILe_mg_prev_levels_2d_dble" searches for the donor cell
00094 ! of points "xyz (*, 1:nc)". The points was last found on coarse level
00095 ! "lev+1" in donor cell "lstijk (*, 1:nc)". 
00096 ! If the i-th point is found in another cell of the coarser grid,
00097 ! "found(i)" > 0 is returned and
00098 ! "newijk (*, i)" returns the donor cell index on level "lev".
00099 !
00100 ! !REVISION HISTORY:
00101 !
00102 !   Date      Programmer   Description
00103 ! ----------  ----------   -----------
00104 ! 03.07.05    H. Ritzdorf  created
00105 !
00106 !EOP
00107 !----------------------------------------------------------------------
00108 !
00109 !  $Id: psmile_mg_prev_levels_2d_dble.F90 2325 2010-04-21 15:00:07Z valcke $
00110 !  $Author: valcke $
00111 !
00112    Character(len=len_cvs_string), save :: mycvs = 
00113        '$Id: psmile_mg_prev_levels_2d_dble.F90 2325 2010-04-21 15:00:07Z valcke $'
00114 !
00115 !----------------------------------------------------------------------
00116 !
00117 !  Initialization
00118 !
00119 #ifdef VERBOSE
00120       print 9990, trim(ch_id), lev, nc
00121 
00122       call psmile_flushstd
00123 #endif /* VERBOSE */
00124 !
00125       grid_info => Grids(grid_id)
00126       mg_infos => grid_info%mg_infos
00127 
00128       levc = lev + 1
00129       nlev1 = nlev - 1
00130 
00131 #ifdef PRISM_ASSERTION
00132       if (levc >= nlev) then
00133          call psmile_assert (__FILE__, __LINE__, 'incorrect level')
00134       endif
00135 #endif
00136 !
00137 !     make sure that ijk lies on coarse grid line
00138 !     TODO: Store coarsening factor in grid info
00139 !
00140          do i = 1, ndim_2d
00141          if (mg_infos(lev )%levdim(i) /= &
00142              mg_infos(levc)%levdim(i) ) then
00143             ijk (i, :, levc) = (lstijk (i, :) / 2) * 2
00144             coarsf(i) = 2
00145          else
00146             ijk (i, :, levc) =  lstijk (i, :)
00147             coarsf(i) = 1
00148          endif
00149          end do
00150 !
00151          do levd = levc, nlev1
00152          nold (:, levd) = 0 ! not clear to which part "lstijk" belongs
00153          end do
00154 !
00155 !===> ... Compute indices on the coarser levels
00156 !         for coarsening factor 2 !
00157 !
00158          do levd = levc+1, nlev1
00159             do i = 1, ndim_2d
00160             if (mg_infos(levd  )%levdim(i) /= &
00161                 mg_infos(levd-1)%levdim(i) ) then
00162 !
00163 !              make sure that ijk lies on coarse grid line
00164 !
00165                ijk (i, :, levd) = (ijk (i, :, levd-1) / 4) * 2
00166             else
00167                ijk (i, :, levd) = ijk (i, :, levd-1)
00168             endif
00169             end do
00170          end do
00171 !
00172 !---------------------------------------------------------------------
00173 !     Go down in the level hierarchie
00174 !
00175 !     TODO: transfer nc loop into PSMILe_mg_control_cell_2d_dble
00176 !           Use mask for points to be controlled and/or
00177 !           gather/scatter of points to be controlled.
00178 !
00179 !     Note: The "wide" control may cause some additional work
00180 !           (repeated control of fine grid cells) 
00181 !           at 2**i boundaries.
00182 !           Otherwise, the "wide" control may find the correct
00183 !           cell faster instead of looping till to the coarsest level.
00184 !           It's not totally clear, whether "small" control would
00185 !           be better should.
00186 !           Should performance control done with example
00187 !           "simple-orca-atmland" since it generates many controls.
00188 !           Possibly, adaptive setting of "wide" or "small" control.
00189 !---------------------------------------------------------------------
00190 !
00191 loop_n: do n = 1, nc
00192 
00193       levdbg = levc
00194 
00195 !     Define cells to be ignored
00196 
00197          do i = 1, ndim_2d
00198          if (mg_infos(lev )%levdim(i) > &
00199              mg_infos(levc)%levdim(i)) then
00200             ignore (i, lev)  = lstijk (i, n) * 2
00201          else
00202             ignore (i, lev)  = lstijk (i, n)
00203          endif
00204          enddo
00205 !
00206       ignore (:, levc) = lstijk (:, n)
00207 !
00208          do i = 1, ndim_2d
00209             do levd = levc+1, nlev1
00210             if (mg_infos(levd-1)%levdim(i) > &
00211                 mg_infos(levd)%levdim(i)) then
00212                ignore (i, levd) = ignore (i, levd-1) / 2
00213             else
00214                ignore (i, levd) = ignore (i, levd-1)
00215             endif
00216             end do
00217          end do
00218 !
00219 #ifdef DEBUGX
00220       control = lev == 3 .and. n == 26
00221 !
00222       if (control) then
00223          do levd = lev, nlev1
00224          print *, 'ignore lev', levd, 'ignore ', ignore (:, levd)
00225          enddo
00226       endif 
00227 #endif
00228 !
00229 100   continue
00230 !
00231          do levd = levdbg, nlev1
00232 #ifdef DEBUGX
00233          if (control) then
00234             print *, 'levd', levd, ', ignore', ignore (:, levd), 'lstijk', lstijk (:, n)
00235          endif
00236 #endif
00237 !
00238          call psmile_mg_control_cell_2d_dble (                 &
00239              mg_infos(levd)%double_arrays%chmin(1)%vector,     &
00240              mg_infos(levd)%double_arrays%chmin(2)%vector,     &
00241              mg_infos(levd)%double_arrays%chmax(1)%vector,     &
00242              mg_infos(levd)%double_arrays%chmax(2)%vector,     &
00243              mg_infos(levd)%double_arrays%midp (1)%vector,     &
00244              mg_infos(levd)%double_arrays%midp (2)%vector,     &
00245              mg_infos(levd)%levdim,                            &
00246              ijk(1, n, levd), xyz(:,n), nold(n, levd),         &
00247              ignore (1, levd), wide, found (n), newijk (:, n))
00248 
00249 #ifdef DEBUGX
00250              if (control) then
00251                 print *, 'levd', levd, ', found', found(n), ', newijk', newijk (:, n)
00252              endif
00253 #endif
00254 !
00255          if (found (n) > 0) then
00256             go to 1990
00257          endif
00258 !
00259          end do
00260 !
00261 !===> Not found
00262 !
00263       cycle loop_n
00264 !
00265 !---------------------------------------------------------------------
00266 !     Up again; startpoint is newijk on level "levd"
00267 !---------------------------------------------------------------------
00268 !
00269 1990  nold (n, levd) = found (n)
00270 !
00271       levdbg = levd
00272       levubg = levd - 1
00273 !
00274       nold (n, levubg) = 0
00275 !
00276          do i = 1, ndim_2d
00277          if (mg_infos(levubg  )%levdim(i) > &
00278              mg_infos(levubg+1)%levdim(i)) then
00279             ijk (i, n, levubg) = min (newijk(i,n)*2, &
00280                                       mg_infos(levubg)%levdim(i))
00281          else
00282             ijk (i, n, levubg) = newijk (i,n)
00283          endif
00284          enddo
00285 !
00286 1995  continue
00287 !
00288          do levu = levubg, lev, -1
00289 !
00290 2000     continue
00291 !
00292 #ifdef DEBUGX
00293          if (control) then
00294             print *, 'levu', levu, ', ignore', ignore (:, levu)
00295          endif
00296 #endif
00297 !
00298          call psmile_mg_control_cell_2d_dble (                &
00299              mg_infos(levu)%double_arrays%chmin(1)%vector,    &
00300              mg_infos(levu)%double_arrays%chmin(2)%vector,    &
00301              mg_infos(levu)%double_arrays%chmax(1)%vector,    &
00302              mg_infos(levu)%double_arrays%chmax(2)%vector,    &
00303              mg_infos(levu)%double_arrays%midp (1)%vector,    &
00304              mg_infos(levu)%double_arrays%midp (2)%vector,    &
00305              mg_infos(levu)%levdim,                           &
00306              ijk(1, n, levu), xyz(:,n), nold(n, levu),        &
00307              ignore (1, levu), small, found(n), newijk (:,n))
00308 !
00309 #ifdef DEBUGX
00310          if (control) then
00311             print *, 'levu', levd, ', found', found(n)
00312          endif
00313 #endif
00314 !
00315          if (found(n) == 0) then
00316             if (levu < levd-1) then
00317 !
00318 !===> ... go back to the previous level; and try again
00319 !
00320                levubg = levu + 1
00321                go to 1995
00322             else
00323 !
00324 !===> ... go down
00325 !
00326                go to 100
00327             endif
00328 !
00329          else if (levu > lev) then
00330 !           Not the finest level
00331             nold (n, levu) = found (n)
00332 !
00333 !           Initialize search on next finer level "levu-1"
00334 !
00335             nold (n, levu-1) = 0
00336 !
00337                do i = 1, ndim_2d
00338                if (mg_infos(levu-1)%levdim(i) > &
00339                    mg_infos(levu  )%levdim(i)) then
00340                   ijk (i, n, levu-1) = min (newijk(i,n)*2, &
00341                                        mg_infos(levu-1)%levdim(i))
00342                else
00343                   ijk (i, n, levu-1) = newijk (i,n)
00344                endif
00345                enddo
00346 !
00347          else ! levu == lev
00348 !           Finest level
00349             if (lstijk(1, n) == newijk(1,n)/coarsf(1) .and. &
00350                 lstijk(2, n) == newijk(2,n)/coarsf(2)) then
00351 !                 Initial cell lstijk was found.
00352 !                 Search again on same level.
00353 !
00354                nold (n, levu) = found (n)
00355 !
00356                go to 2000
00357             endif
00358          endif
00359          end do ! levu
00360 !
00361          end do loop_n
00362 !
00363 !===> All done
00364 !
00365 #ifdef VERBOSE
00366       print 9980, trim(ch_id), lev
00367 
00368       call psmile_flushstd
00369 #endif /* VERBOSE */
00370 !
00371       return
00372 !
00373 !  Formats:
00374 !
00375 9990 format (1x, a, ': psmile_mg_prev_levels_2d_dble: level', i3, &
00376                     ', nc', i6)
00377 9980 format (1x, a, ': psmile_mg_prev_levels_2d_dble: eof, level', i3)
00378 
00379       end subroutine PSMILe_mg_prev_levels_2d_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1