psmile_bbcells_virt_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_Bbcells_virt_2d_dble
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_bbcells_virt_2d_dble (method_id,                &
00012                       coords1, coords2, coords_shape, coords_range,     &
00013                       corners1, corners2, corner_shape, nbr_corners,    &
00014                       chmin1_corner, chmin2_corner,                     &
00015                       chmax1_corner, chmax2_corner, levdim_corner,      &
00016                       chmin1,  chmin2, chmax1, chmax2, midp1, midp2,    &
00017                       levdim,  period, bmaski, bmaskj, ierror)
00018 !
00019 ! !USES:
00020 !
00021       use PRISM_constants
00022       use psmile_grid, only : psmile_transform_cell_cyclic
00023       use PSMILe, dummy_interface => PSMILe_Bbcells_virt_2d_dble
00024 
00025       Implicit none
00026 !
00027 ! !INPUT PARAMETERS:
00028 !
00029       Integer,           Intent (In)  :: method_id
00030 
00031 !     Method id to access halo information
00032 
00033       Integer,           Intent (In)  :: coords_shape (2, ndim_2d)
00034 
00035 !     Dimension of (method/grid) coordinate "coords1", ...
00036 
00037       Integer,           Intent (In)  :: coords_range (2, ndim_2d)
00038 
00039 !     Definition of the subgrid for which the (bounding) cells should
00040 !     be computed.
00041 !     In general, this should be identical with "grid_valid_shape".
00042 
00043       Integer,           Intent (In)  :: corner_shape (2, ndim_2d)
00044 
00045 !     Dimension of the array "corners1" containing the corner points
00046 !     of the control volume (for a single coordinate).
00047 
00048       Integer,           Intent (In)  :: nbr_corners
00049 
00050 !     Number of corners per control volume
00051 
00052       Double Precision,  Intent (In)  :: 
00053          corners1 (corner_shape(1,1):corner_shape(2,1), 
00054                    corner_shape(1,2):corner_shape(2,2), 
00055                    nbr_corners)
00056       Double Precision,  Intent (In)  :: 
00057          corners2 (corner_shape(1,1):corner_shape(2,1), 
00058                    corner_shape(1,2):corner_shape(2,2), 
00059                    nbr_corners)
00060 
00061 !     Definition of the subgrid for which the (bounding)
00062 !     cells should be computed.
00063 
00064       Integer, Intent (In)            :: levdim_corner (2, ndim_2d)
00065 
00066 !     Dimensions of chmin, chmax and midp on level 1
00067 
00068       Double Precision,  Intent (In)  :: 
00069          chmin1_corner (levdim_corner(1,1):levdim_corner(2,1), 
00070                         levdim_corner(1,2):levdim_corner(2,2))
00071       Double Precision,  Intent (In)  :: 
00072          chmin2_corner (levdim_corner(1,1):levdim_corner(2,1), 
00073                         levdim_corner(1,2):levdim_corner(2,2))
00074       Double Precision,  Intent (In)  :: 
00075          chmax1_corner (levdim_corner(1,1):levdim_corner(2,1), 
00076                         levdim_corner(1,2):levdim_corner(2,2))
00077       Double Precision,  Intent (In)  :: 
00078          chmax2_corner (levdim_corner(1,1):levdim_corner(2,1), 
00079                         levdim_corner(1,2):levdim_corner(2,2))
00080 
00081 !     Bounding box info of corner cells
00082 
00083       Integer,           Intent (In)  :: levdim (ndim_2d)
00084 
00085 !     Dimension of output arrays "chmin1", "chmax1" and "midp1".
00086 !     For testing.
00087 !
00088       Double Precision,  Intent (In)  :: period
00089 !
00090 !     Type (Split_Information), Intent (InOut) :: split_info
00091 !
00092 ! !INPUT/OUTPUT PARAMETERS:
00093 !
00094       Double Precision, Intent (InOut) :: 
00095          chmin1 (coords_range(1,1)-1:coords_range(2,1), 
00096                  coords_range(1,2)-1:coords_range(2,2))
00097       Double Precision,  Intent (InOut) :: 
00098          chmin2 (coords_range(1,1)-1:coords_range(2,1), 
00099                  coords_range(1,2)-1:coords_range(2,2))
00100 !
00101 !     Minimum value of bounding box of method cell
00102 !        chmin1 (i,j) contains the minimal value of bounding box of
00103 !                     method cell ((i,j), (i+1,j), (i,j+1), (i+1,j+1))
00104 !                     of "coords1"
00105 !        chmin2 (i,j) contains the minimal value of bounding box of
00106 !                     method cell ((i,j), (i+1,j), (i,j+1), (i+1,j+1))
00107 !                     of "coords2"
00108 
00109       Double Precision, Intent (InOut) :: 
00110          chmax1 (coords_range(1,1)-1:coords_range(2,1), 
00111                  coords_range(1,2)-1:coords_range(2,2))
00112       Double Precision, Intent (InOut) :: 
00113          chmax2 (coords_range(1,1)-1:coords_range(2,1), 
00114                  coords_range(1,2)-1:coords_range(2,2))
00115 !
00116 !     Maximum value of bounding box of method cell
00117 !
00118       Double Precision, Intent (InOut) :: 
00119          midp1  (coords_range(1,1)-1:coords_range(2,1), 
00120                  coords_range(1,2)-1:coords_range(2,2))
00121       Double Precision, Intent (InOut) :: 
00122          midp2  (coords_range(1,1)-1:coords_range(2,1), 
00123                  coords_range(1,2)-1:coords_range(2,2))
00124 !
00125 !     Mid point of bounding box of method cell
00126 !
00127 ! !OUTPUT PARAMETERS:
00128 !
00129       Double Precision, Intent (InOut)   ::           
00130          coords1(coords_shape(1,1):coords_shape(2,1), 
00131                  coords_shape(1,2):coords_shape(2,2))
00132       Double Precision, Intent (InOut)   ::           
00133          coords2(coords_shape(1,1):coords_shape(2,1), 
00134                  coords_shape(1,2):coords_shape(2,2))
00135 
00136 !        Input: Coordinates of the method
00137 !
00138 !        Output:
00139 !        coords(coords_range(1,1)-1:coords_range(2,1)+1, coords_range(1,2)-1)
00140 !        coords(coords_range(1,1)-1:coords_range(2,1)+1, coords_range(2,2)+1)
00141 !        coords(coords_range(1,1)-1, coords_range(1,2)-1:coords_range(2,2)+1)
00142 !        coords(coords_range(2,1)+1, coords_range(1,2)-1:coords_range(2,2)+1)
00143 !
00144 !        Coordinates of the method points over the boundary
00145 !        which were received or inter/extrapolated.
00146 !
00147       Integer,           Intent (Out) :: 
00148          bmaski (coords_range(1,1)-1:coords_range(2,1)+1, 2)
00149       Integer,           Intent (Out) :: 
00150          bmaskj (coords_range(1,2)-1:coords_range(2,2)+1, 2)
00151 !
00152 !     Mask for virtual method cells with
00153 !     bmaski (i,lb) = Mask value for vitual method points
00154 !        coords(coords_range(1,1)-1:coords_range(2,1)+1, coords_range(1,2)-1)
00155 !                     and
00156 !        coords(coords_range(1,1)-1:coords_range(2,1)+1, coords_range(2,2)+1)
00157 !     bmaskj (j,lb) = Mask value for virtual method points
00158 !        coords(coords_range(1,1)-1, coords_range(1,2)-1:coords_range(2,2)+1)
00159 !                     and
00160 !        coords(coords_range(2,1)+1, coords_range(1,2)-1:coords_range(2,2)+1)
00161 !     bmask? (i,lb) =
00162 !         neighbour_value        : Value was received from neighbouring block
00163 !         neighbour_interpolated : Value was interpolated from
00164 !                                  neighbouring method points
00165 !         neighbour_extrapolated : Value was extrapolated from 
00166 !                                  interior method points
00167 !
00168       Integer,           Intent (Out) :: ierror
00169 
00170 !     Returns the error code of PSMILe_Bbcells_virt_2d_dble
00171 !             ierror = 0 : No error
00172 !             ierror > 0 : Severe error
00173 !
00174 ! !DEFINED PARAMETERS:
00175 !
00176 ! r_nbr = 1 / Number of corners1 per grid cell.
00177 !
00178       Integer,          Parameter  :: n_corners = 4
00179       Double Precision, Parameter  :: r_nbr = 0.25d0
00180 !
00181       Integer,          Parameter  :: no_value = 0
00182       Integer,          Parameter  :: neighbour_value = 1
00183       Integer,          Parameter  :: neighbour_interpolated = 2
00184       Integer,          Parameter  :: neighbour_extrapolated = 3
00185 !
00186 ! !LOCAL VARIABLES
00187 !
00188       Integer                      :: i, i1, i2, iv, ibeg, iend, ifirst
00189       Integer                      :: j, j1, j2, jv, jbeg, jend, jfirst
00190       Integer                      :: lb, l, n
00191 !
00192       Double Precision             :: dmn, dmx, fac, r
00193       Double Precision             :: d (ndim_2d)
00194 !
00195       Integer, Allocatable         :: liste(:)
00196 !
00197 !     Auxillary for halo regions
00198 !
00199       Integer                      :: grid_id
00200       Integer                      :: face
00201       Integer                      :: n_seg
00202       Integer                      :: ishift
00203       Integer                      :: nbr_halo_segments
00204       Integer                      :: halo_shape(2,ndim_3d)
00205       Type (Halo_Block), Pointer   :: halo_pointer
00206 !
00207 !     Auxiliary fields for cyclic method cells
00208 !
00209       Double Precision             :: cell (n_corners)
00210 !
00211       Double Precision             :: period2
00212 !
00213 ! Error parameters
00214 !
00215       Integer, Parameter           :: nerrp = 2
00216       Integer                      :: ierrp (nerrp)
00217 !
00218 !
00219 ! !DESCRIPTION:
00220 !
00221 ! Subroutine "PSMILe_Bbcells_virt_2d_dble" computes the bounding box
00222 ! for each virtual cell of the 2-dimensional block. The virtual cells
00223 ! of the block are the cells
00224 ! (coords_range(1,1)-1, :), (coords_range(2,1), :),
00225 ! (:, coords_range(1,2)-1), (:, coords_range(2,2))
00226 !
00227 ! chmin1 (i, j) returns the minimal value of bounding box of virtual
00228 !               method cell ((i,j), (i+1,j), (i,j+1), (i+1,j+1))
00229 !
00230 ! The first box
00231 ! chmin1 (coords_range(1,1)-1,j) returns the minimal value of the bounding box
00232 !                         of virtual cell
00233 !       (coords1(coords_range(1,1), j), coords1(coords_range(1,1), j+1),
00234 !        bounding box of corner control volume of (coords_range(1,1),j)
00235 !
00236 ! The last box
00237 ! chmin1 (coords_range(2,1),  j) returns the minimal value of the bounding box
00238 !                         of virtual cell
00239 !       (coords1(coords_range(2,1), j), coords1(coords_range(2,1), j+1),
00240 !        bounding box of corner control volume of (coords_range(2,1),j)
00241 !
00242 ! Corresponding values are returned for other virtual cells at block
00243 ! border.
00244 !
00245 ! In addition, the virtual method points (received from neighbouring
00246 ! block or inter/extrapolated) are returned together with a mask
00247 ! which contains a code how the virtual boundary point was created.
00248 !
00249 ! Subroutine "PSMILe_Bbcells_virt_2d_dble" is designed for grids of
00250 ! type "PRISM_Irrlonlat_regvrt".
00251 !
00252 ! !REVISION HISTORY:
00253 !
00254 !   Date      Programmer   Description
00255 ! ----------  ----------   -----------
00256 ! 05.05.09    H. Ritzdorf  created
00257 ! 13.10.10    M. Hanke     changed handling of cyclic coordinates
00258 !
00259 !EOP
00260 !----------------------------------------------------------------------
00261 !
00262 !  $Id: psmile_bbcells_virt_2d_dble.F90 2694 2010-10-29 14:58:50Z hanke $
00263 !  $Author: hanke $
00264 !
00265    Character(len=len_cvs_string), save :: mycvs = 
00266        '$Id: psmile_bbcells_virt_2d_dble.F90 2694 2010-10-29 14:58:50Z hanke $'
00267 !
00268 !----------------------------------------------------------------------
00269 !
00270 #ifdef VERBOSE
00271       print 9990, trim(ch_id)
00272 
00273       call psmile_flushstd
00274 #endif /* VERBOSE */
00275 !
00276 #ifdef PRISM_ASSERTION
00277       if (coords_range(1,1) < corner_shape(1,1) .or. &
00278           coords_range(2,1) > corner_shape(2,1) .or. &
00279           coords_range(1,2) < corner_shape(1,2) .or. &
00280           coords_range(2,2) > corner_shape(2,2)) then
00281          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: range", &
00282                   coords_range
00283          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: corner_shape", &
00284                   corner_shape
00285 
00286          call psmile_assert (__FILE__, __LINE__, &
00287               "range must be in corner_shape")
00288       endif
00289 !
00290       if (minval(levdim(:)-(coords_range(2,:)-coords_range(1,:)+2)) < 0) then
00291          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: levdim", levdim
00292          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: range ", &
00293                   coords_range
00294 
00295          call psmile_assert (__FILE__, __LINE__, &
00296               "levdim < coords_range(2,:)-coords_range(1,:)+2")
00297       endif
00298 
00299       if (coords_range(1,1)-1 < coords_shape (1,1) .or. &
00300           coords_range(2,1)+1 > coords_shape (2,1) .or. &
00301           coords_range(1,2)-1 < coords_shape (1,2) .or. &
00302           coords_range(2,2)+1 > coords_shape (2,2)) then
00303 
00304          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: coords_shape", &
00305                                coords_shape
00306          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: coords_range", &
00307                                coords_range
00308 
00309          call psmile_assert (__FILE__, __LINE__, &
00310               "coords_shape is not sufficent")
00311       endif
00312 
00313       if (coords_range(1,1) < levdim_corner (1,1) .or. &
00314           coords_range(2,1) > levdim_corner (2,1) .or. &
00315           coords_range(1,2) < levdim_corner (1,2) .or. &
00316           coords_range(2,2) > levdim_corner (2,2)) then
00317 
00318          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: levdim_corner", &
00319                                levdim_corner
00320          print *, trim(ch_id), "PSMILe_bbcells_virt_2d_dble: coords_range", &
00321                                coords_range
00322 
00323          call psmile_assert (__FILE__, __LINE__, &
00324               "levdim_corner is not sufficent")
00325       endif
00326 #endif
00327 !
00328 !  Initialization
00329 !
00330       ierror = 0
00331 !
00332 !  The corner cells (chmin?_corner, corners?, ...) are used in the
00333 !      range of (ibeg:iend, jbeg:jend).
00334 !  The method points (coords1, coords2) are used in the same range
00335 !      such as the corner cells.
00336 !  The method cells (chmin?, chmax?, ...) are used in the
00337 !      range of (ibeg-1:iend, jbeg-1:jend)
00338 !      where the cell (ibeg-1, :), (iend, :), (:, jbeg-1), (:. jend)
00339 !      are virtual method cells.
00340 !  The boundary (method) points are corners of the virtual method
00341 !      cells which are outside of the interior of corner cells and
00342 !      are used in the range of (ibeg-1:iend+1, *) and
00343 !      (jbeg-1:jend+1, *) where boundary? (:, ij, *) contains
00344 !      the coordinates of lower left corner of method cell 
00345 !      chmin? (i, j), ...
00346 !     
00347       ibeg = coords_range (1,1)
00348       iend = coords_range (2,1)
00349 !
00350       jbeg = coords_range (1,2)
00351       jend = coords_range (2,2)
00352 
00353 #ifdef DEBUG
00354       PRINT*, 'ibeg, iend :',ibeg,iend
00355       PRINT*, 'jbeg, jend :',jbeg,jend
00356       CALL psmile_flushstd
00357 #endif
00358 !
00359       period2 = period * 0.5d0
00360 !
00361       bmaski (:, :) = no_value
00362       bmaskj (:, :) = no_value
00363 !
00364       face = PSMILe_Undef
00365 !=======================================================================
00366 !     Apply halo information if available
00367 !
00368 !     (ibeg:iend,   jbeg:jend)  is the cell range
00369 !     (ibeg:iend+1, jbeg:jend+1) is the range for boundary points
00370 !=======================================================================
00371 !
00372       grid_id = Methods(method_id)%grid_id
00373       nbr_halo_segments = Grids(grid_id)%nbr_halo_segments
00374 !
00375 !
00376 !             face 3
00377 !          -------------
00378 !  face 4  |           |  face 2
00379 !          -------------
00380 !             face 1
00381 !
00382       do n_seg = 1, nbr_halo_segments
00383 
00384          halo_pointer => Methods(method_id)%halo_pointer(n_seg)
00385          halo_shape = halo_pointer%halo_shape
00386 #ifdef DEBUG
00387          PRINT*, 'number of halo segments :',nbr_halo_segments
00388          PRINT*, 'Halo_shape :',halo_shape
00389          call psmile_flushstd
00390 #endif
00391 
00392 ! UNSCHOEN !!
00393          if ( halo_shape(1,1) == PSMILe_Undef ) cycle
00394 
00395          if ( halo_shape(1,1) == halo_shape(2,1) ) then
00396             if ( halo_shape(1,1) == ibeg-1 ) then
00397                face = 4
00398             else if ( halo_shape(1,1) == iend+1 ) then
00399                face = 2
00400             endif
00401          else if ( halo_shape(1,2) == halo_shape(2,2) ) then
00402             if ( halo_shape(1,2) == jbeg-1 ) then
00403                face = 1
00404             else if ( halo_shape(1,2) == jend+1 ) then
00405                face = 3
00406             endif
00407          endif
00408 
00409 #ifdef PRISM_ASSERTION
00410          IF (face == PSMILe_Undef) THEN
00411 
00412              CALL psmile_assert (__FILE__, __LINE__, &
00413                 "face is undefined ! ")
00414          ENDIF
00415 #endif
00416 
00417 #ifdef DEBUG
00418          PRINT *, TRIM(ch_id), ' - applying halo for face ', face
00419          CALL psmile_flushstd
00420 #endif /* DEBUG */
00421 
00422          select case (face)
00423          case (1)
00424 
00425             ishift = 1-halo_shape(1,1)
00426 
00427 !cdir vector
00428 !DEC$ IVDEP
00429                do i = max(ibeg-1,halo_shape(1,1)), min(iend+1,halo_shape(2,1))
00430                bmaski  (i,1)  = neighbour_value
00431                coords1 (i,jbeg-1) = halo_pointer%halo_dble(1)%vector(i+ishift)
00432                coords2 (i,jbeg-1) = halo_pointer%halo_dble(2)%vector(i+ishift)
00433                end do
00434 
00435 #ifdef DEBUG
00436          print *, trim(ch_id), 'face ', face, 'ibeg:iend, jbeg-1', &
00437                   max(ibeg-1,halo_shape(1,1)), &
00438                   min(iend+1,halo_shape(2,1)), jbeg-1
00439 #endif /* DEBUG */
00440 
00441          case (2)
00442 
00443             ishift = 1-halo_shape(1,2)
00444 #ifdef DEBUG
00445          print *, trim(ch_id), 'face ', face, 'iend+1, jbeg:jend', &
00446                   iend+1, max(jbeg-1,halo_shape(1,2)), &
00447                           min(jend+1,halo_shape(2,2))
00448 #endif /* DEBUG */
00449 
00450 !cdir vector
00451 !DEC$ IVDEP
00452                do j = max(jbeg-1,halo_shape(1,2)), min(jend+1,halo_shape(2,2))
00453                bmaskj  (j,2) = neighbour_value
00454                coords1 (iend+1,j) = halo_pointer%halo_dble(1)%vector(j+ishift)
00455                coords2 (iend+1,j) = halo_pointer%halo_dble(2)%vector(j+ishift)
00456                end do
00457 
00458          case (3)
00459 
00460             ishift = 1-halo_shape(1,1)
00461 #ifdef DEBUG
00462          print *, trim(ch_id), 'face ', face, 'ibeg:iend, jend+1', &
00463                   max(ibeg-1,halo_shape(1,1)), &
00464                   min(iend+1,halo_shape(2,1)), jend+1
00465 #endif /* DEBUG */
00466 
00467 !cdir vector
00468 !DEC$ IVDEP
00469                do i = max(ibeg-1,halo_shape(1,1)), min(iend+1,halo_shape(2,1))
00470                bmaski  (i,2) = neighbour_value
00471                coords1 (i,jend+1) = halo_pointer%halo_dble(1)%vector(i+ishift)
00472                coords2 (i,jend+1) = halo_pointer%halo_dble(2)%vector(i+ishift)
00473                end do
00474 
00475          case (4)
00476 
00477             ishift = 1-halo_shape(1,2)
00478 #ifdef DEBUG
00479          print *, trim(ch_id), 'face ', face, 'ibeg-1, jbeg:jend', &
00480                   ibeg-1, max(jbeg-1,halo_shape(1,2)), &
00481                           min(jend+1,halo_shape(2,2))
00482 #endif /* DEBUG */
00483 
00484 !cdir vector
00485 !DEC$ IVDEP
00486                do j = max(jbeg-1,  halo_shape(1,2)), min(jend+1,halo_shape(2,2))
00487                bmaskj  (j,1) = neighbour_value
00488                coords1 (ibeg-1,j) = halo_pointer%halo_dble(1)%vector(j+ishift)
00489                coords2 (ibeg-1,j) = halo_pointer%halo_dble(2)%vector(j+ishift)
00490                end do
00491 
00492          end select
00493 
00494       enddo ! n_seg
00495 !
00496 ! Are values in the corners already available ?
00497 ! Currently not available.
00498 !
00499       if (bmaski (ibeg-1, 1) == neighbour_value) then
00500           bmaskj (jbeg-1, 1) = neighbour_value
00501       else if (bmaskj (jbeg-1, 1) == neighbour_value) then
00502           bmaski (ibeg-1, 1) = neighbour_value
00503       endif
00504 !
00505       if (bmaski (iend+1, 1) == neighbour_value) then
00506           bmaskj (jbeg-1, 2) = neighbour_value
00507       else if (bmaskj (jbeg-1, 2) == neighbour_value) then
00508           bmaski (iend+1, 1) = neighbour_value
00509       endif
00510 !
00511       if (bmaski (ibeg-1, 2) == neighbour_value) then
00512           bmaskj (jend+1, 1) = neighbour_value
00513       else if (bmaskj (jend+1, 1) == neighbour_value) then
00514           bmaski (ibeg-1, 2) = neighbour_value
00515       endif
00516 !
00517       if (bmaski (iend+1, 2) == neighbour_value) then
00518           bmaskj (jend+1, 2) = neighbour_value
00519       else if (bmaskj (jend+1, 2) == neighbour_value) then
00520           bmaski (iend+1, 2) = neighbour_value
00521       endif
00522 
00523 !-----------------------------------------------------------------------
00524 !     Interpolate missing virtual method cell points
00525 !     (*) which are not the corner points (i.e. from (ibeg:iend)) and
00526 !     (*) which are neighboured by 2 neighbouring values
00527 !     for faces 1 and 3 (j = jbeg and j = jend)
00528 !-----------------------------------------------------------------------
00529 !
00530       do lb = 1, 2
00531       if ( .not. ANY (bmaski(ibeg:iend, lb) == no_value) ) cycle
00532 
00533       if (lb == 1) then 
00534 !        Face 1 (j = jbeg)
00535 !        j  = Index of the first interior method points/corner cell
00536 !        jv = Index of the virtual method point
00537          j  = jbeg
00538          jv = j - 1
00539       else 
00540 !        Face 2 (j = jend);
00541 !        j = Index of last interior method point/corner cell
00542 !        jv = Index of the virtual method point
00543          j  = jend
00544          jv = j + 1
00545       endif
00546 
00547 !cdir vector
00548 !DEC$ IVDEP
00549          do i = ibeg, iend
00550          if (bmaski(i, lb) == no_value .and. &
00551             (bmaski(i-1, lb) == neighbour_value .and. &
00552              bmaski(i+1, lb) == neighbour_value)) then
00553 !        Interpolate missing point by neighboured method points
00554 ! bei der Interpolation koennte man noch den methodenpunkt (i,j)
00555 ! und (i-1,j) und (i+1, j) einfliessen lassen
00556 !
00557             bmaski  (i,lb) = neighbour_interpolated
00558             coords1 (i,jv) = (coords1 (i+1,jv) + coords1 (i-1,jv)) * 0.5
00559             coords2 (i,jv) = (coords2 (i+1,jv) + coords2 (i-1,jv)) * 0.5
00560          endif
00561          end do
00562 !
00563       end do ! lb
00564 !
00565 !-----------------------------------------------------------------------
00566 !     Interpolate missing virtual method cell points
00567 !     (*) which are not the corner points (i.e. from (jbeg:jend)) and
00568 !     (*) which are neighboured by 2 neighbouring values
00569 !     for faces 2 and 4 (i = ibeg and i = iend)
00570 !-----------------------------------------------------------------------
00571 !
00572          do lb = 1, 2
00573          if (.not. ANY (bmaskj(jbeg:jend, lb) == no_value)) cycle
00574 
00575          if (lb == 1) then 
00576 !           Face 3 (i = ibeg)
00577 !           i  = Index of the first interior method points/corner cell
00578 !           iv = Index of the virtual method point
00579             i  = ibeg
00580             iv = i - 1
00581          else 
00582 !           Face 4 (i = iend)
00583 !           i  = Index of the last interior method points/corner cell
00584 !           iv = Index of the virtual method point
00585             i  = iend
00586             iv = i + 1
00587          endif
00588 
00589 !cdir vector
00590 !DEC$ IVDEP
00591          do j = jbeg, jend
00592          if (bmaskj(j, lb) == no_value .and. &
00593             (bmaskj(j-1, lb) == neighbour_value .and. &
00594              bmaskj(j+1, lb) == neighbour_value)) then
00595 !        Interpolate missing point by neighboured method points
00596 ! bei der Interpolation koennte man noch den methodenpunkt (i,j)
00597 ! und (i,j-1) und (i, j+1) einfliessen lassen
00598 !
00599             bmaskj  (j,lb) = neighbour_interpolated
00600             coords1 (iv,j) = (coords1 (iv,j+1) + coords1 (iv,j-1)) * 0.5
00601             coords2 (iv,j) = (coords2 (iv,j+1) + coords2 (iv,j-1)) * 0.5
00602          endif
00603          end do
00604 !
00605       end do ! lb
00606 !
00607 !=======================================================================
00608 !     Special case: 1-dimensional
00609 !=======================================================================
00610 !
00611 !     if (coords_range(1,2) == coords_range (2,2)) then
00612       if (jbeg == jend) then
00613 !
00614          j = jbeg
00615          if (ibeg < iend) then
00616 !
00617 !  Try to interpolate all points
00618 !  Simple linear logical interpolation for this exotic case
00619 !  Implement something better if required
00620 !
00621            do lb = 1, 2
00622            if (lb == 1) then
00623               jv = j - 1
00624            else
00625               jv = j + 1
00626            endif
00627 !
00628            n = 0
00629 !
00630 !cdir vector
00631                do i1 = ibeg-1, iend+1
00632                if (bmaski(i1, lb) == neighbour_value) exit
00633                end do
00634 !
00635             if (i1 < iend+1) then
00636                ifirst = i1
00637                i2 = i1 + 1
00638                n = 1
00639 !
00640                do while (i2 < iend+1)
00641                   do i2 = i1+1, iend+1
00642                   if (bmaski(i2, lb) == neighbour_value) exit
00643                   end do
00644 !
00645                if (i2 > iend+1) exit
00646 
00647                n =  n + 1
00648 !
00649                if (i2 == i1 + 1) then 
00650                   i1 = i2
00651                   cycle
00652                endif
00653 !
00654                d(1) = (coords1 (i2, jv) - coords1 (i1, jv)) / (i2-i1)
00655                d(2) = (coords2 (i2, jv) - coords2 (i1, jv)) / (i2-i1)
00656 !
00657 !cdir vector
00658 !DEC$ IVDEP
00659                   do i = i1+1, i2-1
00660                   bmaski(i, lb) = neighbour_interpolated
00661                   coords1 (i,jv) = coords1 (i1,jv) + d(1)*(i-i1)
00662                   coords2 (i,jv) = coords2 (i1,jv) + d(2)*(i-i1)
00663                   end do
00664 !
00665                i1 = i2
00666                end do ! while
00667 !
00668             if (n > 1) then
00669                if (ifirst > ibeg-1) then
00670 !
00671                   d(1) = coords1 (ifirst+1, jv) - coords1 (ifirst, jv)
00672                   d(2) = coords2 (ifirst+1, jv) - coords2 (ifirst, jv)
00673 !cdir vector
00674 !DEC$ IVDEP
00675                      do i = ibeg-1, ifirst-1
00676                      bmaski(i, lb) = neighbour_extrapolated
00677                      coords1 (i,jv) = coords1 (ifirst,jv) - d(1)*(ifirst-i)
00678                      coords2 (i,jv) = coords2 (ifirst,jv) - d(2)*(ifirst-i)
00679                      end do
00680                endif
00681 !
00682                if (i2 < iend+1) then
00683 !
00684                   d(1) = coords1 (i2, jv) - coords1 (i2-1, jv)
00685                   d(2) = coords2 (i2, jv) - coords2 (i2-1, jv)
00686 !cdir vector
00687 !DEC$ IVDEP
00688                      do i = i2+1, iend+1
00689                      bmaski(i, lb) = neighbour_extrapolated
00690                      coords1 (i,jv) = coords1 (i2,jv) + d(1)*(i-iend)
00691                      coords2 (i,jv) = coords2 (i2,jv) + d(2)*(i-iend)
00692                      end do
00693                endif
00694             endif
00695          endif ! if (i1 < iend+1)
00696 !
00697          if (n <= 1) then
00698 
00699 !        Extrapolate method point to exterior in rectangular direction
00700 !cdir vector
00701 !DEC$ IVDEP
00702             do i = ibeg+1, iend-1
00703             if (bmaski(i, lb) == no_value) then
00704                d(1) = (coords1 (i+1, j) - coords1 (i-1, j)) * 0.5
00705                d(2) = (coords2 (i+1, j) - coords2 (i-1, j)) * 0.5
00706 
00707                coords1 (i,jv) = coords1 (i, j) - d(2)*(j-jv)
00708                coords2 (i,jv) = coords2 (i, j) + d(1)
00709             endif
00710             end do
00711 !
00712 !        Extrapolate method point to exterior in rectangular direction
00713 !
00714             i = ibeg
00715 !
00716             d(1) = coords1 (i+1, j) - coords1 (i, j)
00717             d(2) = coords2 (i+1, j) - coords2 (i, j)
00718 !
00719             if (bmaski(i, lb) == no_value) then
00720                coords1 (i,jv) = coords1 (i, j) - d(2)*(j-jv)
00721                coords2 (i,jv) = coords2 (i, j) + d(1)
00722             endif
00723 
00724             if (bmaskj (j, 1) == no_value) then
00725                coords1 (ibeg-1,j) = coords1 (i, j) - d(1)
00726                coords2 (ibeg-1,j) = coords2 (i, j) - d(2)
00727                bmaskj (j,1) = neighbour_extrapolated
00728             endif
00729 !
00730 !        Extrapolate method point to exterior in rectangular direction
00731 
00732             i = iend
00733             d(1) = coords1 (i, j) - coords1 (i-1, j)
00734             d(2) = coords2 (i, j) - coords2 (i-1, j)
00735 !
00736             if (bmaski(i, lb) == no_value) then
00737                coords1 (i,jv) = coords1 (i, j) - d(2)*(j-jv)
00738                coords2 (i,jv) = coords2 (i, j) + d(1)
00739             endif
00740 
00741             if (bmaskj (j, 2) == no_value) then
00742                coords1 (iend+1, j) = coords1 (i, j) + d(1)
00743                coords2 (iend+1, j) = coords2 (i, j) + d(2)
00744                bmaskj (j,2) = neighbour_extrapolated
00745             endif
00746 !
00747 ! corners (extrapolate virtual line)
00748 !
00749             if (bmaski(ibeg-1, lb) == no_value) then
00750                d(1) = coords1 (ibeg+1, jv) - coords1 (ibeg, jv)
00751                d(2) = coords2 (ibeg+1, jv) - coords2 (ibeg, jv)
00752 !
00753                coords1 (ibeg-1,jv) = coords1 (ibeg, jv) - d(1)
00754                coords2 (ibeg-1,jv) = coords2 (ibeg, jv) - d(2)
00755             endif
00756 
00757             if (bmaski(iend+1, lb) == no_value) then
00758                d(1) = coords1 (iend, jv) - coords1 (iend-1, jv)
00759                d(2) = coords2 (iend, jv) - coords2 (iend-1, jv)
00760 !
00761                coords1 (iend+1,jv) = coords1 (iend, jv) + d(1)
00762                coords2 (iend+1,jv) = coords2 (iend, jv) + d(2)
00763             endif
00764 
00765 !cdir vector
00766             do i = ibeg-1, iend+1
00767             if (bmaski(i, lb) == no_value) &
00768                 bmaski(i, lb) = neighbour_extrapolated
00769             end do
00770          endif
00771 !
00772          end do ! lb
00773 
00774 ! ??? Was ist mit den corners ??? TODO
00775 
00776          else
00777 !           ibeg == iend, jbeg == jend
00778 
00779             i = ibeg
00780 
00781             d(1) = chmax1_corner (i, j) - chmin1_corner (i, j)
00782             d(2) = chmax2_corner (i, j) - chmin2_corner (i, j)
00783 
00784             if (bmaski(i, 1) == no_value) then
00785                coords1 (i, j-1) = coords1 (i, j)
00786                coords2 (i, j-1) = coords2 (i, j) - d(2)
00787                bmaski (i, 1) = neighbour_extrapolated
00788             endif
00789 
00790             if (bmaski(i, 2) == no_value) then
00791                coords1 (i, j+1) = coords1 (i, j)
00792                coords2 (i, j+1) = coords2 (i, j) + d(2)
00793                bmaski (i, 2) = neighbour_extrapolated
00794             endif
00795 
00796             if (bmaskj(j, 1) == no_value) then
00797                coords1 (i-1, j) = coords1 (i, j) - d(1)
00798                coords2 (i-1, j) = coords2 (i, j)
00799                bmaskj (j, 1) = neighbour_extrapolated
00800             endif
00801 
00802             if (bmaskj(j, 2) == no_value) then
00803                coords1 (i+1, j) = coords1 (i, j) + d(1)
00804                coords2 (i+1, j) = coords2 (i, j)
00805                bmaskj (j, 2) = neighbour_extrapolated
00806             endif
00807 
00808          endif
00809 !
00810 !     else if (coords_range(1,1) == coords_range(2,1)) then
00811       else if (ibeg == iend) then
00812 !
00813          i = ibeg
00814 !
00815 !  Try to interpolate all points
00816 !  Simple linear logical interpolation for this exotic case
00817 !  Implement something better if required
00818 !
00819            do lb = 1, 2
00820            if (lb == 1) then
00821               iv = i - 1
00822            else
00823               iv = i + 1
00824            endif
00825 !
00826            n = 0
00827 !
00828 !cdir vector
00829                do j1 = jbeg-1, jend+1
00830                if (bmaskj(j1, lb) == neighbour_value) exit
00831                end do
00832 !
00833             if (j1 < jend+1) then
00834                jfirst = j1
00835                j2 = j1 + 1
00836                n = 1
00837 !
00838                do while (j2 < jend+1)
00839                   do j2 = j1+1, jend+1
00840                   if (bmaskj(j2, lb) == neighbour_value) exit
00841                   end do
00842 !
00843                if (j2 > jend+1) exit
00844 
00845                n =  n + 1
00846 !
00847                if (j2 == j1 + 1) then 
00848                   j1 = j2
00849                   cycle
00850                endif
00851 !
00852                d(1) = (coords1 (iv, j2) - coords1 (iv, j1)) / (j2-j1)
00853                d(2) = (coords2 (iv, j2) - coords2 (iv, j1)) / (j2-j1)
00854 !
00855 !cdir vector
00856 !DEC$ IVDEP
00857                   do j = j1+1, j2-1
00858                   bmaskj(j, lb) = neighbour_interpolated
00859                   coords1 (iv,j) = coords1 (iv,j1) + d(1)*(j-j1)
00860                   coords2 (iv,j) = coords2 (iv,j1) + d(2)*(j-j1)
00861                   end do
00862 !
00863                j1 = j2
00864                end do ! while
00865 !
00866             if (n > 1) then
00867                if (jfirst > jbeg-1) then
00868 !
00869                   d(1) = coords1 (iv, jfirst+1) - coords1 (iv, jfirst)
00870                   d(2) = coords2 (iv, jfirst+1) - coords2 (iv, jfirst)
00871 !cdir vector
00872 !DEC$ IVDEP
00873                      do j = jbeg-1, jfirst-1
00874                      bmaskj(j, lb) = neighbour_extrapolated
00875                      coords1 (iv,j) = coords1 (iv,jfirst) - d(1)*(jfirst-j)
00876                      coords2 (iv,j) = coords2 (iv,jfirst) - d(2)*(jfirst-j)
00877                      end do
00878                endif
00879 !
00880                if (j2 < jend+1) then
00881 !
00882                   d(1) = coords1 (iv, j2) - coords1 (iv, j2-1)
00883                   d(2) = coords2 (iv, j2) - coords2 (iv, j2-1)
00884 !cdir vector
00885 !DEC$ IVDEP
00886                      do j = j2+1, jend+1
00887                      bmaskj(j, lb) = neighbour_extrapolated
00888                      coords1 (iv,j) = coords1 (iv,j2) + d(1)*(j-jend)
00889                      coords2 (iv,j) = coords2 (iv,j2) + d(2)*(j-jend)
00890                      end do
00891                endif
00892             endif
00893          endif ! if (j1 < jend+1)
00894 !
00895          if (n <= 1) then
00896 
00897 !        Extrapolate method point to exterior in rectangular direction
00898 !cdir vector
00899 !DEC$ IVDEP
00900             do j = jbeg+1, jend-1
00901             if (bmaskj(j, lb) == no_value) then
00902                d(1) = (coords1 (i, j+1) - coords1 (i, j-1)) * 0.5
00903                d(2) = (coords2 (i, j+1) - coords2 (i, j-1)) * 0.5
00904 
00905                coords1 (iv,j) = coords1 (i, j) - d(2)*(i-iv)
00906                coords2 (iv,j) = coords2 (i, j) + d(1)
00907             endif
00908             end do
00909 !
00910 !        Extrapolate method point to exterior in rectangular direction
00911 !
00912             j = jbeg
00913 !
00914             d(1) = coords1 (i, j+1) - coords1 (i, j)
00915             d(2) = coords2 (i, j+1) - coords2 (i, j)
00916 !
00917             if (bmaskj(j, lb) == no_value) then
00918                coords1 (iv,j) = coords1 (i, j) - d(2)*(i-iv)
00919                coords2 (iv,j) = coords2 (i, j) + d(1)
00920             endif
00921 
00922             if (bmaski (i, 1) == no_value) then
00923                coords1 (i,jbeg-1) = coords1 (i, j) - d(1)
00924                coords2 (i,jbeg-1) = coords2 (i, j) - d(2)
00925                bmaski (i,1) = neighbour_extrapolated
00926             endif
00927 !
00928 !        Extrapolate method point to exterior in rectangular direction
00929 
00930             j = jend
00931             d(1) = coords1 (i, j) - coords1 (i, j-1)
00932             d(2) = coords2 (i, j) - coords2 (i, j-1)
00933 !
00934             if (bmaskj(j, lb) == no_value) then
00935                coords1 (iv,j) = coords1 (i, j) - d(2)*(i-iv)
00936                coords2 (iv,j) = coords2 (i, j) + d(1)
00937             endif
00938 
00939             if (bmaski (i, 2) == no_value) then
00940                coords1 (i, jend+1) = coords1 (i, j) + d(1)
00941                coords2 (i, jend+1) = coords2 (i, j) + d(2)
00942                bmaski (i,2) = neighbour_extrapolated
00943             endif
00944 !
00945 ! corners (extrapolate virtual line)
00946 !
00947             if (bmaskj(jbeg-1, lb) == no_value) then
00948                d(1) = coords1 (iv, jbeg+1) - coords1 (iv, jbeg)
00949                d(2) = coords2 (iv, jbeg+1) - coords2 (iv, jbeg)
00950 !
00951                coords1 (iv, jbeg-1) = coords1 (ibeg, jv) - d(1)
00952                coords2 (iv, jbeg-1) = coords2 (ibeg, jv) - d(2)
00953             endif
00954 
00955             if (bmaskj(jend+1, lb) == no_value) then
00956                d(1) = coords1 (iv, jend) - coords1 (iv, jend-1)
00957                d(2) = coords2 (iv, jend) - coords2 (iv, jend-1)
00958 !
00959                coords1 (iv, jend+1) = coords1 (iv, jend) + d(1)
00960                coords2 (iv, jend+1) = coords2 (iv, jend) + d(2)
00961             endif
00962 
00963 !cdir vector
00964             do j = jbeg-1, jend+1
00965             if (bmaskj(j, lb) == no_value) &
00966                 bmaskj(j, lb) = neighbour_extrapolated
00967             end do
00968          endif
00969 !
00970          end do ! lb
00971 !
00972       else
00973 !
00974 !=======================================================================
00975 !     Regular 2d array
00976 !=======================================================================
00977 !
00978 !-----------------------------------------------------------------------
00979 !     Interpolate missing virtual method cell points which are not
00980 !     the corner points (i.e. from (ibeg:iend))
00981 !     for faces 1 and 3 (j = jbeg and j = jend)
00982 !-----------------------------------------------------------------------
00983 !
00984          do lb = 1, 2
00985          n = Count (bmaski(ibeg:iend, lb) /= neighbour_value)
00986          if (n == 0) cycle
00987 
00988          Allocate (liste (n), STAT = ierror)
00989          if (ierror > 0) then
00990             ierrp (1) = ierror
00991             ierrp (2) = n
00992 
00993             ierror = PRISM_Error_Alloc
00994 
00995             call psmile_error ( ierror, 'liste', &
00996                                 ierrp, 2, __FILE__, __LINE__ )
00997             return
00998          endif
00999 
01000          if (lb == 1) then 
01001 !           Face 1 (j = jbeg)
01002 !           j  = Index of the first interior method points/corner cell
01003 !           j1 = Index of the next interior method point
01004 !           jv = Index of the virtual method point
01005             j  = jbeg
01006             j1 = j + 1
01007             jv = j - 1
01008          else 
01009 !           Face 2 (j = jend);
01010 !           j = Index of last interior method point/corner cell
01011 !           j1 = Index of the next interior method point
01012 !           jv = Index of the virtual method point
01013             j  = jend
01014             j1 = j - 1
01015             jv = j + 1
01016          endif
01017 
01018 !cdir vector
01019 !DEC$ IVDEP
01020          do i = ibeg, iend
01021          if (bmaski(i, lb) == no_value) then
01022 !        Extrapolate from interior method point to exterior
01023             bmaski  (i,lb) = neighbour_extrapolated
01024             coords1 (i,jv) = coords1 (i, j) - &
01025                             (coords1 (i, j1) - coords1 (i, j))
01026             coords2 (i,jv) = coords2 (i, j) - &
01027                             (coords2 (i, j1) - coords2 (i, j))
01028          endif
01029          end do
01030 !
01031 !   Get number and indices of inter/extrapolated points
01032 !   which are contained in the cell box.
01033 !
01034 !   HR: Handle extrapolated and interpolated values in a
01035 !       different way ?
01036 !
01037          n = 0
01038          do i = ibeg, iend
01039          if (bmaski(i, lb) /= neighbour_value .and. &
01040             (coords1(i,jv) >= chmin1_corner (i,j) .and. &
01041              coords1(i,jv) <= chmax1_corner (i,j) .and. &
01042              coords2(i,jv) >= chmin2_corner (i,j) .and. &
01043              coords2(i,jv) <= chmax2_corner (i,j)) ) then
01044             n = n + 1
01045             liste (n) = i
01046          endif
01047          end do
01048 !
01049 !   ... and move these points out of the box
01050 !
01051          do l = 1, n
01052          i = liste(n)
01053          d(1) = coords1(i,jv) - coords1 (i,j)
01054          d(2) = coords2(i,jv) - coords2 (i,j)
01055 !
01056          if (d(1) /= 0.0d0) then
01057             r = max (chmax1_corner (i,j) - coords1 (i,j), &
01058                      coords1 (i,j) - chmin1_corner (i,j))
01059 ! dangerous
01060             fac = r / d(1);
01061          else
01062             fac = 1.0d0
01063          endif
01064 !
01065          if (d(2) /= 0.0d0) then
01066             r = max (chmax2_corner (i,j) - coords2 (i,j), &
01067                      coords2 (i,j) - chmin2_corner (i,j))
01068 ! dangerous
01069             fac = max (fac, r/d(2))
01070          endif
01071 
01072          fac = fac * 1.0078125d0 ! Move it really outside
01073          coords1(i,jv) = coords1 (i,j) + fac*d(1)
01074          coords2(i,jv) = coords2 (i,j) + fac*d(2)
01075          end do ! l
01076 !
01077          Deallocate (liste)
01078 !
01079       end do ! lb
01080 !
01081 !-----------------------------------------------------------------------
01082 !     Interpolate missing virtual method cell points which are not
01083 !     the corner points (i.e. from (jbeg:jend))
01084 !     for faces 2 and 4 (i = ibeg and i = iend)
01085 !-----------------------------------------------------------------------
01086 !
01087          do lb = 1, 2
01088          n = Count (bmaskj(jbeg:jend, lb) /= neighbour_value)
01089          if (n == 0) cycle
01090 
01091          Allocate (liste (n), STAT = ierror)
01092          if (ierror > 0) then
01093             ierrp (1) = ierror
01094             ierrp (2) = n
01095 
01096             ierror = PRISM_Error_Alloc
01097 
01098             call psmile_error ( ierror, 'liste', &
01099                                 ierrp, 2, __FILE__, __LINE__ )
01100             return
01101          endif
01102 
01103          if (lb == 1) then 
01104 !           Face 3 (i = ibeg)
01105 !           i  = Index of the first interior method points/corner cell
01106 !           i1 = Index of the next interior method point
01107 !           iv = Index of the virtual method point
01108             i  = ibeg
01109             i1 = i + 1
01110             iv = i - 1
01111          else 
01112 !           Face 4 (i = iend)
01113 !           i  = Index of the last interior method points/corner cell
01114 !           i1 = Index of the next interior method point
01115 !           iv = Index of the virtual method point
01116             i  = iend
01117             i1 = i - 1
01118             iv = i + 1
01119          endif
01120 
01121 !cdir vector
01122 !DEC$ IVDEP
01123          do j = jbeg, jend
01124          if (bmaskj(j, lb) == no_value) then
01125 !        Extrapolate from interior method point to exterior
01126             bmaskj  (j,lb) = neighbour_extrapolated
01127             coords1 (iv,j) = coords1 (i,  j) - &
01128                             (coords1 (i1, j) - coords1 (i, j))
01129             coords2 (iv,j) = coords2 (i,  j) - &
01130                             (coords2 (i1, j) - coords2 (i, j))
01131          endif
01132          end do
01133 !
01134 !   Get number and indices of inter/extrapolated points
01135 !   which are contained in the cell box.
01136 !
01137 !   HR: Handle extrapolated and interpolated values in a
01138 !       different way ?
01139 !
01140          n = 0
01141          do j = jbeg, jend
01142          if (bmaskj(j, lb) /= neighbour_value .and. &
01143             (coords1(iv,j) >= chmin1_corner (i,j) .and. &
01144              coords1(iv,j) <= chmax1_corner (i,j) .and. &
01145              coords2(iv,j) >= chmin2_corner (i,j) .and. &
01146              coords2(iv,j) <= chmax2_corner (i,j)) ) then
01147             n = n + 1
01148             liste (n) = j
01149          endif
01150          end do
01151 !
01152 !   ... and move these points out of the box
01153 !
01154          do l = 1, n
01155          j = liste(n)
01156          d(1) = coords1(iv,j) - coords1 (i,j)
01157          d(2) = coords2(iv,j) - coords2 (i,j)
01158 !
01159          if (d(1) /= 0.0d0) then
01160             r = max (chmax1_corner (i,j) - coords1 (i,j), &
01161                      coords1 (i,j) - chmin1_corner (i,j))
01162 ! dangerous
01163             fac = r / d(1);
01164          else
01165             fac = 1.0d0
01166          endif
01167 !
01168          if (d(2) /= 0.0d0) then
01169             r = max (chmax2_corner (i,j) - coords2 (i,j), &
01170                      coords2 (i,j) - chmin2_corner (i,j))
01171 ! dangerous
01172             fac = max (fac, r/d(2))
01173          endif
01174 
01175          fac = fac * 1.0078125d0 ! Move it really outside
01176          coords1(iv,j) = coords1 (i,j) + fac*d(1)
01177          coords2(iv,j) = coords2 (i,j) + fac*d(2)
01178          end do ! l
01179 !
01180          Deallocate (liste)
01181          end do ! lb
01182 !
01183 !-----------------------------------------------------------------------
01184 !  .. for corners of Faces
01185 !     Extrapolate from the interior in diagonal direction
01186 !
01187 !     The virtual corner points to be determined are
01188 !     (ibeg-1, jbeg-1), (ibeg-1, jend+1),
01189 !     (iend-1, jbeg-1), (iend-1, jend+1)
01190 !-----------------------------------------------------------------------
01191 
01192 ! Extrapolate in diagonal direction
01193 ! Corner of Faces 1 and 3
01194 
01195       if (bmaski(ibeg-1, 1) == no_value) then
01196 !        ASSERT (bmaskj (jbeg-1,1) = no_value)
01197          bmaski (ibeg-1,1) = neighbour_extrapolated
01198          bmaskj (jbeg-1,1) = neighbour_extrapolated
01199 
01200          d(1) = coords1 (ibeg+1, jbeg+1) - coords1 (ibeg, jbeg)
01201          d(2) = coords2 (ibeg+1, jbeg+1) - coords2 (ibeg, jbeg)
01202          coords1 (ibeg-1,jbeg-1) = coords1 (ibeg, jbeg) - d(1)
01203          coords2 (ibeg-1,jbeg-1) = coords2 (ibeg, jbeg) - d(2)
01204 
01205          if (coords1(ibeg-1,jbeg-1) >= chmin1_corner (ibeg,jbeg) .and. &
01206              coords1(ibeg-1,jbeg-1) <= chmax1_corner (ibeg,jbeg) .and. &
01207              coords2(ibeg-1,jbeg-1) >= chmin2_corner (ibeg,jbeg) .and. &
01208              coords2(ibeg-1,jbeg-1) <= chmax2_corner (ibeg,jbeg)) then
01209 !
01210             if (d(1) /= 0.0d0) then
01211                r = max (chmax1_corner (ibeg,jbeg) - coords1 (ibeg,jbeg), &
01212                         coords1 (ibeg,jbeg) - chmin1_corner (ibeg,jbeg))
01213 ! dangerous
01214                fac = r / d(1);
01215             else
01216                fac = 1.0d0
01217             endif
01218 !
01219             if (d(2) /= 0.0d0) then
01220                r = max (chmax2_corner (ibeg,jbeg) - coords2 (ibeg,jbeg), &
01221                         coords2 (ibeg,jbeg) - chmin2_corner (ibeg,jbeg))
01222 ! dangerous
01223                fac = max (fac, r/d(2))
01224             endif
01225 
01226             fac = fac * 1.0078125d0 ! Move it really outside
01227             coords1(ibeg-1,jbeg-1) = coords1 (ibeg,jbeg) + fac*d(1)
01228             coords2(ibeg-1,jbeg-1) = coords2 (ibeg,jbeg) + fac*d(2)
01229          endif
01230       endif
01231 
01232 ! Corner of Faces 1 and 4
01233 
01234       if (bmaski(iend+1, 1) == no_value) then
01235 !        ASSERT (bmaskj (jbeg-1,2) = no_value)
01236          bmaski (iend+1,1) = neighbour_extrapolated
01237          bmaskj (jbeg-1,2) = neighbour_extrapolated
01238 
01239          d(1) = coords1 (iend-1, jbeg+1) - coords1 (iend, jbeg)
01240          d(2) = coords2 (iend-1, jbeg+1) - coords2 (iend, jbeg)
01241          coords1 (iend+1,jbeg-1) = coords1 (iend, jbeg) - d(1)
01242          coords2 (iend+1,jbeg-1) = coords2 (iend, jbeg) - d(2)
01243 
01244          if (coords1(iend+1,jbeg-1) >= chmin1_corner (iend,jbeg) .and. &
01245              coords1(iend+1,jbeg-1) <= chmax1_corner (iend,jbeg) .and. &
01246              coords2(iend+1,jbeg-1) >= chmin2_corner (iend,jbeg) .and. &
01247              coords2(iend+1,jbeg-1) <= chmax2_corner (iend,jbeg)) then
01248 !
01249             if (d(1) /= 0.0d0) then
01250                r = max (chmax1_corner (iend,jbeg) - coords1 (iend,jbeg), &
01251                         coords1 (iend,jbeg) - chmin1_corner (iend,jbeg))
01252 ! dangerous
01253                fac = r / d(1);
01254             else
01255                fac = 1.0d0
01256             endif
01257 !
01258             if (d(2) /= 0.0d0) then
01259                r = max (chmax2_corner (iend,jbeg) - coords2 (iend,jbeg), &
01260                         coords2 (iend,jbeg) - chmin2_corner (iend,jbeg))
01261 ! dangerous
01262                fac = max (fac, r/d(2))
01263             endif
01264 
01265             fac = fac * 1.0078125d0 ! Move it really outside
01266             coords1(iend+1,jbeg-1) = coords1 (iend,jbeg) + fac*d(1)
01267             coords2(iend+1,jbeg-1) = coords2 (iend,jbeg) + fac*d(2)
01268          endif
01269       endif
01270 
01271 ! Corner of Faces 2 and 3
01272 
01273       if (bmaski(ibeg-1, 2) == no_value) then
01274 !        ASSERT (bmaskj (jend+1,1) = no_value)
01275          bmaski (ibeg-1,2) = neighbour_extrapolated
01276          bmaskj (jend+1,1) = neighbour_extrapolated
01277 
01278          d(1) = coords1 (ibeg+1, jend-1) - coords1 (ibeg, jend)
01279          d(2) = coords2 (ibeg+1, jend-1) - coords2 (ibeg, jend)
01280          coords1 (ibeg-1,jend+1) = coords1 (ibeg, jend) - d(1)
01281          coords2 (ibeg-1,jend+1) = coords2 (ibeg, jend) - d(2)
01282 
01283          if (coords1(ibeg-1,jend+1) >= chmin1_corner (ibeg,jend) .and. &
01284              coords1(ibeg-1,jend+1) <= chmax1_corner (ibeg,jend) .and. &
01285              coords2(ibeg-1,jend+1) >= chmin2_corner (ibeg,jend) .and. &
01286              coords2(ibeg-1,jend+1) <= chmax2_corner (ibeg,jend)) then
01287 !
01288             if (d(1) /= 0.0d0) then
01289                r = max (chmax1_corner (ibeg,jend) - coords1 (ibeg,jend), &
01290                         coords1 (ibeg,jend) - chmin1_corner (ibeg,jend))
01291 ! dangerous
01292                fac = r / d(1);
01293             else
01294                fac = 1.0d0
01295             endif
01296 !
01297             if (d(2) /= 0.0d0) then
01298                r = max (chmax2_corner (ibeg,jend) - coords2 (ibeg,jend), &
01299                         coords2 (ibeg,jend) - chmin2_corner (ibeg,jend))
01300 ! dangerous
01301                fac = max (fac, r/d(2))
01302             endif
01303 
01304             fac = fac * 1.0078125d0 ! Move it really outside
01305             coords1(ibeg-1,jend+1) = coords1 (ibeg,jend) + fac*d(1)
01306             coords2(ibeg-1,jend+1) = coords2 (ibeg,jend) + fac*d(2)
01307          endif
01308       endif
01309 
01310 ! Corner of Faces 2 and 4
01311 
01312       if (bmaski(iend+1, 2) == no_value) then
01313 !        ASSERT (bmaskj (jend+1,2) = no_value)
01314          bmaski (iend+1,2) = neighbour_extrapolated
01315          bmaskj (jend+1,2) = neighbour_extrapolated
01316 
01317          d(1) = coords1 (iend-1, jend-1) - coords1 (iend, jend)
01318          d(2) = coords2 (iend-1, jend-1) - coords2 (iend, jend)
01319          coords1 (iend+1,jend+1) = coords1 (iend, jend) - d(1)
01320          coords2 (iend+1,jend+1) = coords2 (iend, jend) - d(2)
01321 
01322          if (coords1(iend+1,jend+1) >= chmin1_corner (iend,jend) .and. &
01323              coords1(iend+1,jend+1) <= chmax1_corner (iend,jend) .and. &
01324              coords2(iend+1,jend+1) >= chmin2_corner (iend,jend) .and. &
01325              coords2(iend+1,jend+1) <= chmax2_corner (iend,jend)) then
01326 !
01327             if (d(1) /= 0.0d0) then
01328                r = max (chmax1_corner (iend,jend) - coords1 (iend,jend), &
01329                         coords1 (iend,jend) - chmin1_corner (iend,jend))
01330 ! dangerous
01331                fac = r / d(1);
01332             else
01333                fac = 1.0d0
01334             endif
01335 !
01336             if (d(2) /= 0.0d0) then
01337                r = max (chmax2_corner (iend,jend) - coords2 (iend,jend), &
01338                         coords2 (iend,jend) - chmin2_corner (iend,jend))
01339 ! dangerous
01340                fac = max (fac, r/d(2))
01341             endif
01342 
01343             fac = fac * 1.0078125d0 ! Move it really outside
01344             coords1(iend+1,jend+1) = coords1 (iend,jend) + fac*d(1)
01345             coords2(iend+1,jend+1) = coords2 (iend,jend) + fac*d(2)
01346          endif
01347       endif !  if (bmaski(iend+1, 2) == no_value)
01348 !
01349       endif !  if (jbeg == jend)
01350 !
01351 !-----------------------------------------------------------------------
01352 !  ...... Set bounding box of virtual method cells
01353 !     for faces 1 and 3 (j = jbeg and j = jend)
01354 !
01355 !     The virtual corner cells are located in
01356 !     (ibeg-1, jbeg-1), (ibeg-1, jend),
01357 !     (iend,   jbeg-1), (iend,   jend)
01358 !-----------------------------------------------------------------------
01359 !
01360       do lb = 1, 2
01361       if (lb == 1) then 
01362 !        Face 1 (j = jbeg)
01363 !        j  = Index of the first interior method point/corner cell
01364 !        j1 = Index of the virtual method point
01365 !        jv = Index of the virtual cell
01366          j  = jbeg
01367          j1 = j - 1
01368          jv = j - 1
01369       else 
01370 !        Face 2 (j = jend)
01371 !        j  = Index of the last interior method point/corner cell
01372 !        j1 = Index of the virtual method point
01373 !        jv = Index of the virtual cell
01374          j  = jend
01375          j1 = j + 1
01376          jv = j
01377       endif
01378 !
01379 !     Note: This loop sets also the corner values
01380 !           chmin(ibeg-1, jv) and chmin1(iend, jv)
01381 !cdir vector
01382 !DEC$ IVDEP
01383       do i = ibeg-1, iend
01384          chmin1 (i, jv) = min (coords1(i,j),  coords1(i+1,j), &
01385                                coords1(i,j1), coords1(i+1,j1))
01386          chmax1 (i, jv) = max (coords1(i,j),  coords1(i+1,j), &
01387                                coords1(i,j1), coords1(i+1,j1))
01388       enddo
01389 
01390 !     Look for cyclic cells
01391 
01392 !cdir vector
01393 !DEC$ IVDEP
01394       do i = ibeg-1, iend
01395          ! if the bounding box is too big, we most probably need to apply cyclic coordinate handling
01396          if (chmax1(i,jv)-chmin1(i,jv) > period2) then
01397 
01398             ! get the cell
01399             cell(1) = coords1(i  ,j ); cell (2) = coords1(i+1,j )
01400             cell(3) = coords1(i  ,j1); cell (4) = coords1(i+1,j1)
01401 
01402             ! apply cyclic coordinate handling
01403             call psmile_transform_cell_cyclic(cell, period, ierror)
01404 
01405             ! get new bounding box
01406             chmin1 (i, jv) = minval (cell(:))
01407             chmax1 (i, jv) = maxval (cell(:))
01408          endif
01409       enddo
01410 !
01411 !        ... limit virtual cell volume by corner volumes
01412 !        ... HR: Soll man das wirklich machen ?
01413 !                Fuer die globale Suche waeren die echten Zellen besser.
01414 !                Sonst nimmt mg_method vielleicht eine andere Zelle ?
01415 !
01416 #define LIMIT
01417 #ifdef LIMIT
01418 !cdir vector
01419 !DEC$ IVDEP
01420       do i = ibeg, iend-1
01421          dmn = min (chmin1_corner(i,j), chmin1_corner (i+1,j))
01422          chmin1 (i, jv) = max (chmin1(i, jv), dmn)
01423 
01424          dmx = max (chmax1_corner(i,j), chmax1_corner (i+1,j))
01425          chmax1 (i, jv) = min (chmax1(i, jv), dmx)
01426       enddo
01427 
01428 !      Corners of Face 3 (ibeg) and Face 4 (iend)
01429 
01430        chmin1 (ibeg-1, jv) = max (chmin1 (ibeg-1, jv), &
01431                                   chmin1_corner (ibeg, j))
01432        chmax1 (ibeg-1, jv) = min (chmax1 (ibeg-1, jv), &
01433                                   chmax1_corner (ibeg, j))
01434 
01435        chmin1 (iend,   jv) = max (chmin1 (iend, jv), &
01436                                   chmin1_corner (iend, j))
01437        chmax1 (iend,   jv) = min (chmax1 (iend, jv), &
01438                                   chmax1_corner (iend, j))
01439 #endif
01440 !
01441 !cdir vector
01442 !DEC$ IVDEP
01443           do i = ibeg-1, iend
01444           chmin2 (i, jv) = min (coords2(i,j),  coords2(i+1,j), &
01445                                 coords2(i,j1), coords2(i+1,j1))
01446           chmax2 (i, jv) = max (coords2(i,j),  coords2(i+1,j), &
01447                                 coords2(i,j1), coords2(i+1,j1))
01448           enddo
01449 !
01450 #ifdef LIMIT
01451 !cdir vector
01452 !DEC$ IVDEP
01453           do i = ibeg, iend-1
01454           dmn = min (chmin2_corner(i,j), chmin2_corner (i+1,j))
01455           chmin2 (i, jv) = max (chmin2(i, jv), dmn)
01456 
01457           dmx = max (chmax2_corner(i,j), chmax2_corner (i+1,j))
01458           chmax2 (i, jv) = min (chmax2(i, jv), dmx)
01459           enddo
01460 
01461 !      Corners of Face 3 (ibeg) and Face 4 (iend)
01462 
01463       chmin2 (ibeg-1, jv) = max (chmin2 (ibeg-1, jv), &
01464                                  chmin2_corner (ibeg, j))
01465       chmax2 (ibeg-1, jv) = min (chmax2 (ibeg-1, jv), &
01466                                  chmax2_corner (ibeg, j))
01467 
01468       chmin2 (iend,   jv) = max (chmin2 (iend, jv), &
01469                                  chmin2_corner (iend, j))
01470       chmax2 (iend,   jv) = min (chmax2 (iend, jv), &
01471                                  chmax2_corner (iend, j))
01472 #endif
01473 
01474       end do ! lb
01475 !
01476 !-----------------------------------------------------------------------
01477 !  ...... Set bounding box of virtual method cells
01478 !     for faces 3 and 4 (i = ibeg and i = iend-1)
01479 !-----------------------------------------------------------------------
01480 !
01481       do lb = 1, 2
01482 
01483       if (lb == 1) then 
01484 !        Face 3 (i = ibeg)
01485 !        i  = Index of the first interior method point/corner cell
01486 !        j1 = Index of the virtual method point
01487 !        iv = Index of the virtual cell
01488          i  = ibeg
01489          i1 = i - 1
01490          iv = i - 1
01491       else 
01492 !        Face 4 (i = iend)
01493 !        i  = Index of the last interior method point/corner cell
01494 !        j1 = Index of the virtual method point
01495 !        iv = Index of the virtual cell
01496          i  = iend
01497          i1 = i + 1
01498          iv = iend
01499       endif
01500 !
01501 !     Note: chmin1(iv, jbeg-1) and chmin1(iv, jend)
01502 !           were already set in the loop above.
01503 !
01504 !cdir vector
01505 !DEC$ IVDEP
01506       do j = jbeg, jend-1
01507          chmin1 (iv, j) = min (coords1(i, j), coords1(i, j+1), &
01508                                coords1(i1,j), coords1(i1,j+1))
01509          chmax1 (iv, j) = max (coords1(i, j), coords1(i, j+1), &
01510                                coords1(i1,j), coords1(i1,j+1))
01511       enddo
01512 
01513 !     Look for cyclic cells
01514 
01515 !cdir vector
01516 !DEC$ IVDEP
01517       do j = jbeg, jend-1
01518          ! if the bounding box is too big, we most probably need to apply cyclic coordinate handling
01519          if (chmax1(iv,j)-chmin1(iv,j) > period2) then
01520 
01521             ! get the cell
01522             cell(1) = coords1(i  ,j  ); cell (2) = coords1(i1,j  )
01523             cell(3) = coords1(i  ,j+1); cell (4) = coords1(i1,j+1)
01524 
01525             ! apply cyclic coordinate handling
01526             call psmile_transform_cell_cyclic(cell, period, ierror)
01527 
01528             ! get new bounding box
01529             chmin1 (i, jv) = minval (cell(:))
01530             chmax1 (i, jv) = maxval (cell(:))
01531          endif
01532       enddo
01533 !
01534 !        ... limit virtual cell volume by corner volumes
01535 !
01536 #ifdef LIMIT
01537 !cdir vector
01538 !DEC$ IVDEP
01539       do j = jbeg, jend-1
01540          dmn = min (chmin1_corner(i,j), chmin1_corner (i,j+1))
01541          chmin1 (iv, j) = max (chmin1(iv, j), dmn)
01542 
01543          dmx = max (chmax1_corner(i,j), chmax1_corner (i,j+1))
01544          chmax1 (iv, j) = min (chmax1(iv, j), dmx)
01545       enddo
01546 #endif
01547 !
01548 !cdir vector
01549 !DEC$ IVDEP
01550          do j = jbeg, jend-1
01551             chmin2 (iv, j) = min (coords2(i,j),  coords2 (i,j+1), &
01552                                   coords2(i1,j), coords2(i1,j+1))
01553             chmax2 (iv, j) = max (coords2(i,j),  coords2 (i,j+1), &
01554                                   coords2(i1,j), coords2(i1,j+1))
01555          enddo
01556 !
01557 #ifdef LIMIT
01558 !cdir vector
01559 !DEC$ IVDEP
01560           do j = jbeg, jend-1
01561           dmn = min (chmin2_corner(i,j), chmin2_corner (i,j+1))
01562           chmin2 (iv, j) = max (chmin2(iv, j), dmn)
01563 
01564           dmx = max (chmax2_corner(i,j), chmax2_corner (i,j+1))
01565           chmax2 (iv, j) = min (chmax2(iv, j), dmx)
01566           enddo
01567 #endif
01568 
01569       end do ! lb
01570 !
01571 !-----------------------------------------------------------------------
01572 !  ... Set mid point of virtual method cells
01573 !-----------------------------------------------------------------------
01574 !
01575          j = jbeg-1
01576 !cdir vector
01577 !DEC$ IVDEP
01578             do i = ibeg-1, iend
01579             midp1  (i, j) = (chmin1(i,j) + chmax1 (i,j)) * 0.5
01580             midp2  (i, j) = (chmin2(i,j) + chmax2 (i,j)) * 0.5
01581             enddo
01582 !
01583 !        ... Move extrapolated points away
01584 !            to give other points higher preference
01585 
01586 !cdir vector
01587 !DEC$ IVDEP
01588             do i = ibeg-1, iend
01589             if (bmaski(i,  1) == neighbour_extrapolated .or. &
01590                 bmaski(i+1,1) == neighbour_extrapolated) then
01591                midp1  (i, j) = midp1 (i, j) + 720.0
01592             endif
01593             enddo
01594 !
01595          j = jend
01596 !cdir vector
01597 !DEC$ IVDEP
01598             do i = ibeg-1, iend
01599             midp1  (i, j) = (chmin1(i,j) + chmax1 (i,j)) * 0.5
01600             midp2  (i, j) = (chmin2(i,j) + chmax2 (i,j)) * 0.5
01601             enddo
01602 
01603 !cdir vector
01604 !DEC$ IVDEP
01605             do i = ibeg-1, iend
01606             if (bmaski(i,  2) == neighbour_extrapolated .or. &
01607                 bmaski(i+1,2) == neighbour_extrapolated) then
01608                midp1  (i, j) = midp1 (i, j) + 720.0
01609             endif
01610             enddo
01611 !
01612          i = ibeg-1
01613 !cdir vector
01614 !DEC$ IVDEP
01615             do j = jbeg, jend-1
01616             midp1  (i, j) = (chmin1(i,j) + chmax1 (i,j)) * 0.5
01617             midp2  (i, j) = (chmin2(i,j) + chmax2 (i,j)) * 0.5
01618             enddo
01619 
01620 !cdir vector
01621 !DEC$ IVDEP
01622             do j = jbeg-1, jend
01623             if (bmaskj(j,  1) == neighbour_extrapolated .or. &
01624                 bmaskj(j+1,1) == neighbour_extrapolated) then
01625                midp1  (i, j) = midp1 (i, j) + 720.0
01626             endif
01627             enddo
01628 !
01629          i = iend
01630 !cdir vector
01631 !DEC$ IVDEP
01632             do j = jbeg, jend-1
01633             midp1  (i, j) = (chmin1(i,j) + chmax1 (i,j)) * 0.5
01634             midp2  (i, j) = (chmin2(i,j) + chmax2 (i,j)) * 0.5
01635             enddo
01636 
01637 !cdir vector
01638 !DEC$ IVDEP
01639             do j = jbeg-1, jend
01640             if (bmaskj(j,  2) == neighbour_extrapolated .or. &
01641                 bmaskj(j+1,2) == neighbour_extrapolated) then
01642                midp1  (i, j) = midp1 (i, j) + 720.0
01643             endif
01644             enddo
01645 !
01646 !===> All done
01647 !
01648 #ifdef VERBOSE
01649       print 9980, trim(ch_id), ierror
01650 
01651       call psmile_flushstd
01652 #endif /* VERBOSE */
01653 !
01654 !  Formats:
01655 !
01656 9990 format (1x, a, ': psmile_bbcells_virt_2d_dble')
01657 9980 format (1x, a, ': psmile_bbcells_virt_2d_dble: eof ierror =', i3)
01658 !
01659       end subroutine PSMILe_Bbcells_virt_2d_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1