psmile_mg_next_level_2d_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_Next_level_2d_real
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_mg_next_level_2d_real (            &
00012                            grid_id, lev, nlev,             &
00013                            chmin1, chmin2,                 &
00014                            chmax1, chmax2,                 &
00015                            midp1,  midp2,                  &
00016                            levdim,                         &
00017                            found, loc, range,              &
00018                            coords1, coords2,               &
00019                            shape, control,                 &
00020                            ijkinc, ijkcoa, ierror)
00021 !
00022 ! !USES:
00023 !
00024       use PRISM_constants
00025 !
00026       use PSMILe, dummy_interface => PSMILe_mg_next_level_2d_real
00027 #ifdef DEBUG_TRACE
00028       use psmile_debug_trace
00029 #endif
00030 
00031       implicit none
00032 !
00033 ! !INPUT PARAMETERS:
00034 !
00035       Integer, Intent (In)            :: grid_id
00036 
00037 !     Info on the component in which the donor
00038 !     should be searched.
00039 
00040       Integer, Intent (In)            :: lev
00041 
00042 !     Level number of the next grid
00043 
00044       Integer, Intent (In)            :: nlev
00045 
00046 !     Total number of levels
00047 
00048       Integer, Intent (In)            :: levdim (ndim_2d)
00049 
00050 !     Dimension of chmin, chmax and midp
00051 
00052       Integer, Intent (In)            :: range (2, ndim_3d)
00053 
00054 !     Dimension of loc and found
00055 
00056       Integer, Intent (In)            :: shape (2, ndim_3d)
00057 
00058 !     Dimension of coordinate arrays
00059 
00060       Real, Intent (In)               :: chmin1 (0:levdim(1), 
00061                                                  0:levdim(2))
00062       Real, Intent (In)               :: chmin2 (0:levdim(1), 
00063                                                  0:levdim(2))
00064 
00065 !     Minimum of grid coordinates per grid cell
00066 
00067       Real, Intent (In)               :: chmax1 (0:levdim(1), 
00068                                                  0:levdim(2))
00069       Real, Intent (In)               :: chmax2 (0:levdim(1), 
00070                                                  0:levdim(2))
00071 
00072 !     Maximum of grid coordinates per grid cell
00073 
00074       Real, Intent (In)               ::  midp1 (0:levdim(1), 
00075                                                  0:levdim(2))
00076       Real, Intent (In)               ::  midp2 (0:levdim(1), 
00077                                                  0:levdim(2))
00078 !     Mid point of the cell
00079 
00080 
00081       Real, Intent (In)               :: coords1 (shape(1,1):shape(2,1), 
00082                                                   shape(1,2):shape(2,2), 
00083                                                   shape(1,3):shape(2,3))
00084       Real, Intent (In)               :: coords2 (shape(1,1):shape(2,1), 
00085                                                   shape(1,2):shape(2,2), 
00086                                                   shape(1,3):shape(2,3))
00087 
00088 !     Coordinates to be searched
00089 
00090       Integer, Intent (In)            :: ijkinc (ndim_3d)
00091 
00092 !     Increment for each coordinate direction to be searched
00093 
00094       Integer, Intent (In)            :: ijkcoa (ndim_2d)
00095 
00096 !     Coarsening of source grid
00097 !
00098 ! !INPUT/OUTPUT PARAMETERS:
00099 !
00100       Integer, Intent (InOut)         :: found (range(1,1):range(2,1), 
00101                                                 range(1,2):range(2,2), 
00102                                                 range(1,3):range(2,3))
00103 
00104 !     Finest level number on which a grid cell was found for point i,j.
00105 !     Level number < -1: Point was not found and
00106 !                        and last level number was (-found(i,j,k))
00107 !     Level number = (-nlev+1): Never found (input value)
00108 
00109       Integer, Intent (InOut)         :: loc   (ndim_2d,               
00110                                                 range(1,1):range(2,1), 
00111                                                 range(1,2):range(2,2), 
00112                                                 range(1,3):range(2,3))
00113 
00114 !     Indices of the grid cell in which the point was found.
00115 
00116       Integer, Intent (InOut)         :: control (2, ndim_3d)
00117 
00118 !     Input  value: index range in "coords" to be searched
00119 !     Output value: index range in "coords" for which a cell was found
00120 !
00121 ! !OUTPUT PARAMETERS:
00122 !
00123       integer, Intent (Out)           :: ierror
00124 
00125 !     Returns the error code of PSMILe_mg_next_level_2d_real;
00126 !             ierror = 0 : No error
00127 !             ierror > 0 : Severe error
00128 !
00129 ! !DEFINED PARAMETERS:
00130 !
00131       Integer, parameter              :: ndtry = 16
00132       Integer, parameter              :: ntry1 = 4
00133       Integer, parameter              :: ntry3 = 9
00134       Integer, parameter              :: ntry2 = ndtry - ntry1
00135 !
00136       Integer, Parameter              :: temp_len = 256
00137 !
00138       Real, parameter                 :: remax = 1.0e20
00139 !
00140 ! !LOCAL VARIABLES
00141 !
00142 !     ... for levels
00143 
00144       Integer                         :: levc
00145 
00146 !     ... for locations searched
00147 
00148       Integer                         :: i, j, k
00149       Integer                         :: ibegl, ibeglx, iendl, n, nprev
00150       Integer                         :: nmin (temp_len, 1)
00151       Integer                         :: ijkf(temp_len, ndim_2d)
00152       Integer                         :: ijkold(temp_len, ndim_2d)
00153       Integer                         :: newijk(ndim_2d, temp_len)
00154       Integer                         :: ijkctl (ndim_2d, ndtry)
00155       Integer                         :: ijkdst (temp_len, ndim_2d, ndtry)
00156       Integer                         :: ijkctl3 (ndim_2d, ndtry)
00157       Real                            :: dist (temp_len, ndtry)
00158       Real                            :: xyz (ndim_2d, temp_len)
00159 !
00160 !     ...
00161 !
00162       Integer                         :: ii, nc, np, nc_part
00163       Integer                         :: list (temp_len*2)
00164       Integer                         :: part_list (temp_len)
00165       Integer                         :: loc2 (ndim_2d, temp_len)
00166 !
00167 #ifdef DEBUG
00168 !     ... for locations searched
00169 !
00170       Integer                         :: nfnd (0:4)
00171 #endif /* DEBUG */
00172 !
00173 ! !DESCRIPTION:
00174 !
00175 ! Subroutine "PSMILe_mg_next_level_2d_real" searches the donor cells
00176 ! on the next MG grid for the subgrid coords by the sending process.
00177 !
00178 !
00179 ! !REVISION HISTORY:
00180 !   Date      Programmer   Description
00181 ! ----------  ----------   -----------
00182 ! 03.07.21    H. Ritzdorf  created
00183 !
00184 !EOP
00185 !----------------------------------------------------------------------
00186 !
00187 !  $Id: psmile_mg_next_level_2d_real.F90 2927 2011-01-28 14:04:12Z hanke $
00188 !  $Author: hanke $
00189 !
00190    Character(len=len_cvs_string), save :: mycvs = 
00191        '$Id: psmile_mg_next_level_2d_real.F90 2927 2011-01-28 14:04:12Z hanke $'
00192 !
00193 !----------------------------------------------------------------------
00194 !
00195 !  Relative control indices for sub-cells of coarse grid cells
00196 !
00197       data ((ijkctl (i, n), i=1,ndim_2d), n = 1,ntry1) &
00198                              / 0, 0,   1, 0,    &
00199                                0, 1,   1, 1/
00200 !
00201 !  Relative control indices for neighbour cells
00202 !
00203       data ((ijkctl (i, n), i=1,ndim_2d), n = ntry1+1, ntry1+12) &
00204                   /-1,-1,   0,-1,   1,-1,   2,-1,    &
00205                    -1, 0,                   2, 0,    &
00206                    -1, 1,                   2, 1,    &
00207                    -1, 2,   0, 2,   1, 2,   2, 2/
00208 !
00209 !  Relative control indices for computed cells
00210 !
00211       data ((ijkctl3 (i, n), i=1,ndim_2d), n = 1,ntry3) &
00212                  / -1,-1,   0,-1,   1,-1,     &
00213                    -1, 0,   0, 0,   1, 0,     &
00214                    -1, 1,   0, 1,   1, 1/
00215 !
00216 !----------------------------------------------------------------------
00217 !
00218 !  Initialization
00219 !
00220 #ifdef VERBOSE
00221       print 9990, trim(ch_id), lev, control
00222 
00223       call psmile_flushstd
00224 #endif /* VERBOSE */
00225 !
00226 #ifdef PRISM_ASSERTION
00227 #endif
00228 !
00229       ierror = 0
00230       levc = lev + 1
00231 !
00232       iendl = control(2,1) + ijkinc(1)
00233 !
00234 #ifdef DEBUG
00235       nfnd (:) = 0
00236 #endif /* DEBUG */
00237 
00238          do k = control(1,3), control (2,3), ijkinc (3)
00239 loop_j:     do j = control(1,2), control (2,2), ijkinc (2)
00240 !
00241 !-----------------------------------------------------------------------
00242 !     Look in the fine parts of the coarse grid cell loc(:,i,j,k)
00243 !
00244 !     TODO: List "uber 1-dimensionalen Vector (i,j,k)
00245 !-----------------------------------------------------------------------
00246 !
00247             nprev = 0
00248 
00249             ibegl = control (1, 1)
00250 !
00251 !===> ... Look for the next cells to be controlled
00252 !         Store indices of cells in list "list"
00253 !
00254 loop_i:        do while (ibegl < iendl)
00255 !
00256                nc = 0
00257                i = ibegl
00258 !
00259                   do while (nc < temp_len .and. i < iendl)
00260                      ibegl = i
00261 !cdir vector
00262                         do i = ibegl, min (ibegl+((temp_len*2-1)-nc)*ijkinc(1), &
00263                                            control(2,1)), ijkinc(1)
00264                         if (found(i, j, k) == levc) then
00265                            nc = nc + 1
00266                            list (nc) = i
00267                         endif
00268                         end do
00269 !
00270                      if (nc < temp_len .and. &
00271                          i > control(2,1) .and. i < iendl) then
00272                         i = control(2,1)
00273                         if (found (i,j,k) == levc) then
00274                            nc = nc + 1
00275                            list (nc) = i
00276 !
00277                            exit ! do while (nc < temp_len .and.
00278                         endif
00279                      endif
00280                   end do
00281 !
00282                if (nc == 0) exit loop_i ! exit while loop (ibegl < ...)
00283 !
00284                if (nc < temp_len) then
00285                   ibegl = iendl
00286                else if (nc > temp_len) then
00287                   nc = temp_len
00288                   ibegl = list (temp_len+1)
00289                else
00290                   ibegl = list (temp_len) + ijkinc(1)
00291                endif
00292 !
00293 !===> ... Look in the fine parts of cell loc(:,i,j,k)
00294 !
00295                ijkf(1:nc, 1) = min (loc(1,list(1:nc),j,k) * ijkcoa(1), levdim(1))
00296                ijkf(1:nc, 2) = min (loc(2,list(1:nc),j,k) * ijkcoa(2), levdim(2))
00297 !
00298                   do n = 1, ntry1
00299                      do ii = 1, ndim_2d
00300                      ijkdst (1:nc, ii, n) = max (min(ijkf(1:nc, ii)+ijkctl(ii,n), &
00301                                                      levdim(ii)), 0)
00302                      end do ! ii
00303                   end do ! n
00304 !
00305 !cdir vector
00306                   do n = 1, ntry1
00307                      do i = 1, nc
00308                      if (coords1(list(i),j,k) >= chmin1(ijkdst(i,1,n),         &
00309                                                         ijkdst(i,2,n)) .and.   &
00310                          coords2(list(i),j,k) >= chmin2(ijkdst(i,1,n),         &
00311                                                         ijkdst(i,2,n)) .and.   &
00312                          coords1(list(i),j,k) <= chmax1(ijkdst(i,1,n),         &
00313                                                         ijkdst(i,2,n)) .and.   &
00314                          coords2(list(i),j,k) <= chmax2(ijkdst(i,1,n),         &
00315                                                         ijkdst(i,2,n))) then
00316                         dist (i, n) = (coords1(list(i),j,k) -                  &
00317                                        midp1(ijkdst(i,1,n), ijkdst(i,2,n)))**2 &
00318                                     + (coords2(list(i),j,k) -                  &
00319                                        midp2(ijkdst(i,1,n), ijkdst(i,2,n)))**2
00320 
00321                      else
00322 
00323                         dist (i, n) = remax
00324 
00325                      endif
00326                      end do ! i
00327                   end do ! n
00328 !
00329 !===> ... Look for the minimum distance
00330 !
00331 #if 0
00332                   do i = 1, nc
00333                   nmin (i, :) = MINLOC (dist(i, 1:ntry1))
00334                   end do
00335 #ifdef MINLOCFIX
00336                   do i = 1, nc
00337                   if (nmin(i, 1).eq.0) nmin (i, 1) = 1
00338                   end do
00339 #endif /* MINLOCFIX */
00340 #else
00341                nmin (1:nc, 1) = 1
00342 !
00343                   do n = 2, ntry1
00344 !cdir vector
00345                      do i = 1, nc
00346                      if (dist(i, n) < dist(i, nmin(i,1))) then
00347                         nmin (i,1) = n
00348                      endif
00349                      end do
00350                   end do
00351 #endif 
00352 !
00353 !     ... Look for points which were found in a fine grid cell
00354 !
00355                nc_part = 0
00356 !cdir vector
00357                   do i = 1, nc
00358                   if (dist(i, nmin(i, 1)) /= remax) then
00359                      nc_part = nc_part + 1
00360                      part_list (nc_part) = i
00361                   endif
00362                   end do
00363 !
00364                if (nc_part > 0) then
00365 !cdir vector
00366                      do np = 1, nc_part
00367                      i = part_list (np)
00368 
00369                      found  (list(i),j,k) = lev
00370                      loc (:, list(i),j,k) = ijkdst (i, :, nmin(i, 1))
00371                      end do
00372 
00373 #ifdef DEBUG
00374                   nfnd (1) = nfnd (1) + nc_part
00375 #endif /* DEBUG */
00376 !
00377                   if (nc == nc_part) cycle loop_i
00378 !
00379 !     ... Get list of points which require further search
00380 !
00381                   nc_part = 0
00382 !cdir vector
00383                      do i = 1, nc
00384                      if (dist(i, nmin(i, 1)) == remax) then
00385                         nc_part = nc_part + 1
00386                         part_list (nc_part) = i
00387                      endif
00388                      end do
00389 !
00390 !===> ...... Get data on remaining points out of previous list
00391 !
00392                   nc = nc_part
00393 !cdir vector
00394                      do i = 1, nc
00395 ! Hilfsvector einfuehren
00396                      list (i) = list (part_list (i))
00397 !
00398                      ijkf (i,1) = ijkf (part_list(i), 1)
00399                      ijkf (i,2) = ijkf (part_list(i), 2)
00400                      enddo
00401 !
00402                endif
00403 !
00404 !     ... Is the coarse grid the coarsest grid ?
00405 !
00406                if (levc == lev) then
00407 !cdir vector
00408                      do i = 1, nc
00409                      found (list(i),j,k) = - found(list(i),j,k)
00410                      end do
00411 #ifdef DEBUG
00412                   nfnd (0) = nfnd (0) + nc
00413 #endif /* DEBUG */
00414 
00415                   cycle loop_i
00416                endif
00417 !
00418 !-----------------------------------------------------------------------
00419 !          Look in the neigbourhood of the coarse grid cell
00420 !          loc(:,list(i),j,k)
00421 !-----------------------------------------------------------------------
00422 !
00423                  do n = ntry1+1, ndtry
00424 !cdir vector
00425                     do ii = 1, ndim_2d
00426                     ijkdst (1:nc, ii, n) = max(0, min(ijkf(1:nc, ii)+ijkctl(ii,n), &
00427                                                       levdim(ii)))
00428                     end do
00429 !
00430                     do i = 1, nc
00431                     if (coords1(list(i),j,k) >= chmin1(ijkdst(i, 1,n),         &
00432                                                        ijkdst(i, 2,n)) .and.   &
00433                         coords2(list(i),j,k) >= chmin2(ijkdst(i, 1,n),         &
00434                                                        ijkdst(i, 2,n)) .and.   &
00435                         coords1(list(i),j,k) <= chmax1(ijkdst(i, 1,n),         &
00436                                                        ijkdst(i, 2,n)) .and.   &
00437                         coords2(list(i),j,k) <= chmax2(ijkdst(i, 1,n),         &
00438                                                        ijkdst(i, 2,n))) then
00439 
00440                     dist (i, n) = (coords1(list(i),j,k) -                    &
00441                                    midp1(ijkdst(i, 1,n), ijkdst(i, 2,n)))**2 &
00442                                 + (coords2(list(i),j,k) -                    &
00443                                    midp2(ijkdst(i, 1,n), ijkdst(i, 2,n)))**2
00444 
00445                  else
00446 
00447                     dist (i, n) = remax
00448 
00449                  endif
00450                  end do ! i
00451               end do ! n
00452 !
00453 !===> ... Look for the minimum distance
00454 !
00455 #if 0
00456               do i = 1, nc
00457               nmin(i,:) = MINLOC (dist(i, ntry1+1:ndtry))
00458               end do
00459 !
00460 #ifdef MINLOCFIX
00461               do i = 1, nc
00462               if (nmin(i, 1).eq.0) nmin (i, 1) = 1
00463               end do
00464 
00465 #endif /* MINLOCFIX */
00466 #else
00467                nmin (1:nc, 1) = ntry1+1
00468 !
00469                   do n = ntry1+2, ndtry
00470 !cdir vector
00471                      do i = 1, nc
00472                      if (dist(i, n) < dist(i, nmin(i,1))) then
00473                         nmin (i,1) = n
00474                      endif
00475                      end do
00476                   end do
00477 #endif
00478 !
00479 !     ... Look for points which were found in a fine grid cell
00480 !
00481             nc_part = 0
00482 !cdir vector
00483                do i = 1, nc
00484                if (dist(i, nmin(i, 1)) /= remax) then
00485                   found  (list(i),j,k) = lev
00486                   loc (:, list(i),j,k) = ijkdst (i, :, nmin(i, 1))
00487 !
00488                   nc_part = nc_part + 1
00489                endif
00490                end do
00491 !
00492 #ifdef DEBUG
00493             nfnd (2) = nfnd (2) + nc_part
00494 #endif /* DEBUG */
00495 !
00496             nprev = nprev + (nc - nc_part)
00497 !
00498          end do loop_i ! while
00499 !
00500 !===> ... Have points to be controlled o a coarser level ?
00501 !
00502          if (nprev == 0) cycle loop_j
00503 !
00504 !-----------------------------------------------------------------------
00505 !          Some points were not found.
00506 !          Try to interpolate the fine point from neighbouring points
00507 !-----------------------------------------------------------------------
00508 !
00509             ibeglx = control (1, 1) +  ijkinc(1)
00510 !
00511 !===> ... Look for the next cells to be controlled
00512 !         Store indices of cells in list "list"
00513 !
00514 loop_2:        do while (ibeglx < iendl)
00515 !
00516                nc = 0
00517                i = ibeglx
00518 !
00519                   do while (nc < temp_len .and. i < control(2,1))
00520                      ibeglx = i
00521 !cdir vector
00522                         do i = ibeglx, &
00523                                min (ibeglx+((temp_len*2-1)-nc)*ijkinc(1), &
00524                                     control(2,1)-ijkinc(1)), ijkinc(1)
00525                         if (found (i, j, k) == levc .and.        &
00526                             found (i-ijkinc(1),j,k) == lev .and. &
00527                             found (i+ijkinc(1),j,k) == lev) then
00528                            nc = nc + 1
00529                            list (nc) = i
00530                         endif
00531                         end do
00532 !
00533                      if (nc < temp_len .and. &
00534                          i > control(2,1)-ijkinc(1) .and. i < control(2,1)) then
00535                         i = control(2,1) - ijkinc(1)
00536                         if (found (i, j, k) == levc .and.        &
00537                             found (i-ijkinc(1),j,k) == lev .and. &
00538                             found (i+ijkinc(1),j,k) == lev) then
00539                            nc = nc + 1
00540                            list (nc) = i
00541 !
00542                            exit ! while (nc < temp_len .and. ...)
00543                         endif
00544                      endif
00545                   end do
00546 !
00547                if (nc == 0) exit loop_2 ! exit while loop (ibeglx < ...)
00548 !
00549                if (nc < temp_len) then
00550                   ibeglx = control(2,1) + ijkinc (1)
00551                else if (nc > temp_len) then
00552                   nc = temp_len
00553                   ibeglx = list (temp_len+1)
00554                else
00555                   ibeglx = list (temp_len) + ijkinc(1)
00556                endif
00557 !
00558               do ii = 1, ndim_2d
00559               ijkf (1:nc, ii) = min ((loc (ii, list(1:nc)-ijkinc(1),j,k) +   &
00560                                       loc (ii, list(1:nc)+ijkinc(1),j,k))/2, &
00561                                      levdim(ii))
00562 !
00563               ijkold (1:nc, ii) = min (loc(ii, list(1:nc),j,k) * ijkcoa(ii), &
00564                                        levdim(ii))
00565               end do
00566 !
00567 !===> ... Interpolate cell IJKF and
00568 !         look in the neighbourhood of cell IJKF
00569 !
00570 #ifdef HUHU
00571               do i = 1, nc
00572 !
00573 !! rausnehmen aus der liste gar nicht erzeugen ? oder ignorieren
00574                  if (ijkold(i, 1) == ijkf(i, 1) .and. &
00575                      ijkold(i, 2) == ijkf(i, 2)) cycle
00576 !
00577               end do
00578 #endif
00579 
00580               do n = 1, ntry3
00581 !cdir vector
00582                  do ii = 1, ndim_2d
00583                  ijkdst (1:nc, ii, n) = max(0, min(ijkf(1:nc, ii) + ijkctl3(ii,n), &
00584                                                    levdim(ii)))
00585                  end do
00586 !
00587 !===> ... Compute distances to the cell midpoints
00588 !
00589 !cdir vector
00590                  do i = 1, nc
00591                  if (coords1(list(i),j,k) >= chmin1(ijkdst(i,1,n),         &
00592                                                     ijkdst(i,2,n)) .and.   &
00593                      coords2(list(i),j,k) >= chmin2(ijkdst(i,1,n),         &
00594                                                     ijkdst(i,2,n)) .and.   &
00595                      coords1(list(i),j,k) <= chmax1(ijkdst(i,1,n),         &
00596                                                     ijkdst(i,2,n)) .and.   &
00597                      coords2(list(i),j,k) <= chmax2(ijkdst(i,1,n),         &
00598                                                     ijkdst(i,2,n))) then
00599                     dist (i, n) = (coords1(list(i),j,k) - midp1(ijkdst(i,1,n),     &
00600                                                                 ijkdst(i,2,n)))**2 &
00601                                 + (coords2(list(i),j,k) - midp2(ijkdst(i,1,n),     &
00602                                                                 ijkdst(i,2,n)))**2
00603 
00604                  else
00605 
00606                     dist (i, n) = remax
00607 
00608                  endif
00609                  end do
00610               end do ! n
00611 !
00612 !===> ... Look for the minimum distance
00613 !
00614 #if 0
00615               do i = 1, nc
00616               nmin (i, :) = MINLOC (dist(i, 1:ntry3))
00617               end do
00618 !
00619 #ifdef MINLOCFIX
00620               do i = 1, nc
00621               if (nmin(i, 1).eq.0) nmin (i, 1) = 1
00622               end do
00623 #endif /* MINLOCFIX */
00624 #else
00625               nmin (1:nc, 1) = 1
00626 !
00627                  do n = 2, ntry3
00628 !cdir vector
00629                     do i = 1, nc
00630                     if (dist(i, n) < dist(i, nmin(i,1))) then
00631                        nmin (i,1) = n
00632                     endif
00633                     end do
00634                  end do
00635 #endif
00636 !
00637               nc_part = 0
00638 !cdir vector
00639                  do i = 1, nc
00640                  if (dist(i, nmin(i, 1)) /= remax) then
00641                     found ( list(i),j,k) = lev
00642                     loc (:, list(i),j,k) = ijkdst (i, :, nmin(i, 1))
00643    
00644                     nc_part = nc_part + 1
00645                  endif
00646                  end do
00647 !
00648                  nprev = nprev - nc_part
00649 #ifdef DEBUG
00650               nfnd (3) = nfnd (3) + nc_part
00651 #endif /* DEBUG */
00652 !
00653               end do loop_2 ! while
00654 !
00655            if (nprev == 0) cycle loop_j
00656 
00657 !-----------------------------------------------------------------------
00658 !     Some points were still not found.
00659 !     Look again on the next coarser level whether the points
00660 !     are located in other cells.
00661 !-----------------------------------------------------------------------
00662 !
00663            if (lev+1 < nlev) then
00664 !
00665          ibeglx = control (1, 1)
00666 !
00667 !===> ... Look for the next cells to be controlled
00668 !         Store indices of cells in list "list"
00669 !
00670 loop_3:        do while (ibeglx < iendl)
00671 !
00672                nc = 0
00673                i = ibeglx
00674 !
00675                   do while (nc < temp_len .and. i < iendl)
00676                      ibeglx = i
00677 !cdir vector
00678                         do i = ibeglx, min (ibeglx+((temp_len*2-1)-nc)*ijkinc(1), &
00679                                            control(2,1)), ijkinc(1)
00680                         if (found(i, j, k) == levc) then
00681                            nc = nc + 1
00682                            list (nc) = i
00683                         endif
00684                         end do
00685 !
00686                      if (nc < temp_len .and. &
00687                          i > control(2,1) .and. i < iendl) then
00688                         i = control(2,1)
00689                         if (found (i,j,k) == levc) then
00690                            nc = nc + 1
00691                            list (nc) = i
00692                         endif
00693                      endif
00694                   end do
00695 !
00696                if (nc == 0) exit loop_3 ! exit while loop (ibeglx < ...)
00697 !
00698                if (nc < temp_len) then
00699                   ibeglx = control(2,1) + ijkinc (1)
00700                else if (nc > temp_len) then
00701                   nc = temp_len
00702                   ibeglx = list (temp_len+1)
00703                else
00704                   ibeglx = list (temp_len) + ijkinc(1)
00705                endif
00706 !
00707 !===> ... Look in the coarser parts of cell loc(:,list(i),j,k)
00708 !     !!! TODO: collect xyz and reduce number of subroutine calls
00709 !               to PSMILE_mg_prev_levels_2d_real
00710 ! 3d loop mit nprev ?
00711 !cdir vector
00712                   do i = 1, nc
00713                   xyz (1, i) = coords1 (list(i),j,k)
00714                   xyz (2, i) = coords2 (list(i),j,k)
00715 !
00716                   loc2 (1, i) = loc(1,list(i),j,k)
00717                   loc2 (2, i) = loc(2,list(i),j,k)
00718                   end do
00719 !
00720                call psmile_mg_prev_levels_2d_real (grid_id, lev, nlev, &
00721                                  loc2, xyz, part_list, &
00722                                  newijk, nc)
00723 !
00724                do i = 1, nc
00725                if (part_list(i) > 0) then
00726 !
00727 !                 Point (list(i), j, k) was found in cell newijk (*, i)
00728 !
00729                   loc (:, list(i),j,k) = newijk (:, i)
00730 !
00731                   found (list(i),j,k) = lev
00732 #ifdef DEBUG
00733                   nfnd (4) = nfnd (4) + 1
00734 #endif /* DEBUG */
00735                else
00736                   found (list(i),j,k) = - found (list(i),j,k)
00737 !                 print *, 'not found a', list(i),j,k, coords1 (list(i),j,k), coords2 (list(i),j,k)
00738 #ifdef DEBUG
00739                   nfnd (0) = nfnd (0) + 1
00740 #endif /* DEBUG */
00741                endif
00742                end do
00743 !
00744             end do loop_3 ! while
00745             else
00746 !              This is the second coarsest level.
00747 !              The coarsest level contains only 1 cell.
00748 !              All points which are not found are outside.
00749 
00750 !cdir vector
00751                do i = control (1,1), control (2,1)
00752                if (found(i, j, k) == levc) then
00753                   found(i, j, k) = -levc
00754 !                 print *, 'not found b', i,j,k
00755 #ifdef DEBUG
00756                   nfnd (0) = nfnd (0) + 1
00757 #endif /* DEBUG */
00758                endif
00759                end do
00760             endif ! if (lev+1 < nlev)
00761 !
00762          end do loop_j ! j
00763       end do ! k
00764 !
00765 !===> All done
00766 !
00767 #ifdef DEBUG_TRACE
00768       if (range(1,1) <= ictl_ind(1) .and. range(2,1) >= ictl_ind(1) .and. &
00769           range(1,2) <= ictl_ind(2) .and. range(2,2) >= ictl_ind(2)) then
00770          i = ictl_ind(1)
00771          j = ictl_ind(2)
00772          k = control(1,3)
00773 
00774          if ( found (i,j,k) == lev .or. found (i,j,k) == -levc) then
00775             print 8990, ictl_ind (1:ndim_2d), &
00776                      found (i,j,k), loc(:, i,j,k)
00777 !
00778             if (found (i,j,k) == lev) then
00779                print *, 'chmin ', &
00780                         chmin1 (loc(1,i,j,k), loc(2,i,j,k)), &
00781                         chmin2 (loc(1,i,j,k), loc(2,i,j,k))
00782                print *, 'coords', coords1 (i,j,k), coords2 (i,j,k)
00783                print *, 'chmax ', &
00784                         chmax1 (loc(1,i,j,k), loc(2,i,j,k)), &
00785                         chmax2 (loc(1,i,j,k), loc(2,i,j,k))
00786             endif
00787 
00788 8990  format (1x, '### mg_next ictl_ind', 2i5, '; found ', i3, &
00789               :, 1x, ', loc', 2i6)
00790          endif
00791       endif
00792 #endif
00793 !
00794 #ifdef DEBUG
00795       print 9970, trim(ch_id), lev, nfnd, ijkinc
00796 9970  format (1x, a, ': PSMILe_mg_next_level_2d_real: lev =', i3, &
00797               ': not fnd', i5, ', fnd =', i6, 3i5, ', ijkinc ', 3i4)
00798 #endif /* DEBUG */
00799 
00800 #ifdef VERBOSE
00801       print 9980, trim(ch_id), lev
00802 
00803       call psmile_flushstd
00804 #endif /* VERBOSE */
00805 !
00806 !  Formats:
00807 !
00808 9990 format (1x, a, ': PSMILe_mg_next_level_2d_real: level', i3, &
00809                     ', control', 6i6)
00810 9980 format (1x, a, ': PSMILe_mg_next_level_2d_real: eof, level', i3)
00811 
00812       end subroutine PSMILe_mg_next_level_2d_real

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1