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

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1