psmile_control_cell_gauss2_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_Control_cell_gauss2_dble
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_control_cell_gauss2_dble (grid_id,           &
00012                       ic, nc, list, j, k,                            &
00013                       coords1,  coords2,  shape,                     &
00014                       corners1, corners2, corner_shape, nbr_corners, &
00015                       tol, fnd, ierror)
00016 !
00017 ! !USES:
00018 !
00019       use PRISM_constants
00020 !
00021       use PSMILe, dummy_interface => PSMILe_Control_cell_gauss2_dble
00022 #ifdef DEBUG_TRACE
00023       use psmile_debug_trace
00024 #endif
00025 
00026       Implicit none
00027 !
00028 ! !INPUT PARAMETERS:
00029 !
00030       Integer, Intent (In)            :: grid_id
00031 !
00032 !     Grid Id (for info degraded cells)
00033 !
00034       Integer, Intent (In)            :: nc
00035 !
00036 !     Number of cells (and points) to be controlled
00037 !
00038       Integer, Intent (In)            :: ic (nc)
00039 !
00040 !     Indices of the (corner) cells to be controlled
00041 !     Note: These indices are GaussReduced indices
00042 !
00043       Integer, Intent (In)            :: list (nc)
00044 !
00045 !     I-Indices of the points in to be controlled
00046 !
00047       Integer, Intent (In)            :: j
00048 !
00049 !     J-Index of the points in to be controlled
00050 !
00051       Integer, Intent (In)            :: k
00052 !
00053 !     K-Index of the points in to be controlled
00054 !     Note: list(:), j, k are indices of points to be searched !
00055 !
00056       Integer, Intent (In)            :: shape (2, ndim_3d)
00057 
00058 !     Dimension of coordinate arrays "coord1", "coord2"
00059 !     which contain the coordinates to be searched.
00060 
00061       Double Precision, Intent (In)   ::   
00062          coords1 (shape(1,1):shape(2,1), shape(1,2):shape(2,2), 
00063                   shape(1,3):shape(2,3))
00064 
00065       Double Precision, Intent (In)   ::   
00066          coords2 (shape(1,1):shape(2,1), shape(1,2):shape(2,2), 
00067                   shape(1,3):shape(2,3))
00068 
00069 !     Coordinates to be searched
00070 
00071       Integer, Intent (In)            :: corner_shape (2, ndim_2d)
00072 
00073 !     Dimension of corner coordinate arrays
00074 
00075       Integer, Intent (In)            :: nbr_corners
00076 
00077 !     Number of corners
00078 !     Note: This routine assumes nbr_corners == 2.
00079 
00080       Double Precision,   Intent (In) ::                 
00081          corners1 ( corner_shape(1,1):corner_shape(2,1), nbr_corners)
00082 
00083 !     Coordinates of corner points of control volume (Longitude)
00084 
00085       Double Precision,   Intent (In) ::                 
00086          corners2 ( corner_shape(1,1):corner_shape(2,1), nbr_corners)
00087 
00088 !     Coordinates of corner points of control volume (Latitude)
00089 
00090       Double Precision, Intent (In)   :: tol
00091 !
00092 !     Absolute tolerance for search of "identical" points
00093 !     TOL >= 0.0
00094 !
00095 ! !OUTPUT PARAMETERS:
00096 !
00097       Logical, Intent (Out)           :: fnd (nc)
00098 !
00099 !     Was the i-th point of "list" found within cell "ic"
00100 !
00101       Integer, Intent (Out)           :: ierror
00102 
00103 !     Returns the error code of PSMILe_Control_cell_gauss2_dble;
00104 !             ierror = 0 : No error
00105 !             ierror > 0 : Severe error
00106 !
00107 ! !DEFINED PARAMETERS:
00108 !
00109 !  NTET = Number of triangles used to determine whether
00110 !         point is within the grid cell
00111 !  EPS  = Tolerance for determinate of deformed grid cells
00112 !
00113       Integer, Parameter              :: ntet = 3
00114 !
00115       Double Precision, Parameter     :: eps = 1.0d-9
00116       Double Precision, Parameter     :: rmxeps = 1.0d30
00117       Double Precision, Parameter     :: dzero = 0.0
00118 !
00119 ! !LOCAL VARIABLES
00120 !
00121 !     ... for tolerances
00122 !
00123       Double Precision                :: tol1
00124 !
00125 !     ... for locations controlled
00126 !
00127       Integer                         :: i, jj, m, n
00128 !
00129 !     ... Logical reference point and edges (constant)
00130 ! 
00131       Integer, Save                   :: ijkedg (2, ntet)
00132 !
00133 !     ... Reference point and edges and distances
00134 ! 
00135       Double Precision                :: xyzpnt (nc, ntet, ndim_2d), 
00136                                          xyzref (nc, ntet+1, ndim_2d)
00137       Double Precision                :: xyzedg (nc, ntet, ndim_2d, 2)
00138       Double Precision                :: d1, d2
00139       Double Precision                :: det (nc, ntet)
00140       Double Precision                :: dnorm
00141 !
00142 ! !DESCRIPTION:
00143 !
00144 ! Subroutine "PSMILe_Control_cell_gauss2_dble" controls whether the point
00145 ! "(list(i),j,k)" is contained in the corner cell "ic(i)".
00146 ! The routine assumes that the number of corners for the 2-dimensional
00147 ! cell is 4 (2 in longitude and 2 in latitude direction).
00148 !
00149 ! Subroutine "PSMILe_Control_cell_gauss2_dble" is designed for grids of
00150 ! type "PRISM_Gaussreduced_regvrt".
00151 !
00152 !
00153 ! !REVISION HISTORY:
00154 !
00155 !   Date      Programmer   Description
00156 ! ----------  ----------   -----------
00157 ! 27.05.08    H. Ritzdorf  created
00158 !
00159 !EOP
00160 !----------------------------------------------------------------------
00161 !
00162 !  $Id: psmile_control_cell_gauss2_dble.F90 2927 2011-01-28 14:04:12Z hanke $
00163 !  $Author: hanke $
00164 !
00165    Character(len=len_cvs_string), save :: mycvs = 
00166        '$Id: psmile_control_cell_gauss2_dble.F90 2927 2011-01-28 14:04:12Z hanke $'
00167 !
00168 !----------------------------------------------------------------------
00169 !
00170 !  Relative indices of triangles
00171 !
00172 !     The cell is split into 3 triangles
00173 !
00174 !                   4-------3
00175 !                   !       !
00176 !                   !       !
00177 !            Corner 1 ----- 2
00178 !
00179       data ((ijkedg (jj, n), jj = 1, 2), n = 1, ntet) &
00180            / 2, 4,  3, 1,  4, 2/
00181 !   Corner    1      2      3
00182 !   Edges of corner 1 are connections to Corner 2 and Corner 4
00183 !
00184 !----------------------------------------------------------------------
00185 !
00186 !  Initialization
00187 !
00188 #ifdef VERBOSE
00189       print 9990, trim(ch_id), nc
00190 
00191       call psmile_flushstd
00192 #endif /* VERBOSE */
00193 !
00194 #ifdef PRISM_ASSERTION
00195       if (tol < 0.0) then
00196          call psmile_assert (__FILE__, __LINE__, &
00197                              "tol must be >= 0.0")
00198       endif
00199 !
00200 !cdir vector
00201          do i = 1, nc
00202          if (ic(i) < corner_shape(1,1) .or. ic(i) > corner_shape(2,1) ) then
00203             exit
00204          endif
00205          end do
00206 !
00207       if (i <= nc) then
00208          print *, 'i, ic', i, ic(i)
00209          print *, 'corner_shape', corner_shape
00210          call psmile_assert (__FILE__, __LINE__, &
00211                              'wrong index')
00212       endif
00213 #endif
00214 !
00215       ierror = 0
00216 !
00217 !===> Compute reference points, corners and edges of transformed
00218 !     triangles.
00219 !
00220       xyzref (:, 1, 1) = corners1 (ic(:), 1)
00221       xyzref (:, 1, 2) = corners2 (ic(:), 1)
00222 !
00223       xyzref (:, 2, 1) = corners1 (ic(:), 2)
00224       xyzref (:, 2, 2) = xyzref (:, 1, 2)
00225 !
00226       xyzref (:, 3, 1) = xyzref (:, 2, 1)
00227       xyzref (:, 3, 2) = corners2 (ic(:), 2)
00228 !
00229       xyzref (:, 4, 1) = xyzref (:, 1, 1)
00230       xyzref (:, 4, 2) = xyzref (:, 3, 2)
00231 !
00232 #ifdef DEBUG_TRACE
00233       do i = 1, nc
00234         if ( list(i) == ictl_ind(1) .and. j == ictl_ind(2) ) then
00235            print *, 'Search coords ', &
00236                coords1(list(i),j,shape(1,3)), coords2(list(i),j,shape(1,3))
00237            print *, 'Corners: '
00238            print *, '    C1 : ', xyzref (i, 1, 1), xyzref (i, 1, 2)
00239            print *, '    C2 : ', xyzref (i, 2, 1), xyzref (i, 2, 2)
00240            print *, '    C3 : ', xyzref (i, 3, 1), xyzref (i, 3, 2)
00241            print *, '    C4 : ', xyzref (i, 4, 1), xyzref (i, 4, 2)
00242         endif
00243       enddo
00244 #endif
00245         do n = 1, ntet
00246         xyzpnt (:, n, 1) = coords1 (list(:), j, k) - xyzref (:, n, 1)
00247         xyzpnt (:, n, 2) = coords2 (list(:), j, k) - xyzref (:, n, 2)
00248 !
00249            do m = 1, 2
00250 !cdir vector
00251               do i = 1, nc
00252               xyzedg (i, n, 1, m) = xyzref (i, ijkedg(m, n), 1) &
00253                                   - xyzref (i, n, 1)
00254 
00255               xyzedg (i, n, 2, m) = xyzref (i, ijkedg(m, n), 2) &
00256                                   - xyzref (i, n, 2)
00257               end do
00258            end do
00259         end do ! n
00260 !
00261 !===> Solve bilinear system; compute spat product
00262 !
00263 !   (xyzedg(*,1), xyzedg(*,2)) (x) = xyzpnt
00264 !
00265       det(:, :) = xyzedg(:, :, 1,1)*xyzedg(:, :, 2,2) &
00266                 - xyzedg(:, :, 1,2)*xyzedg(:, :, 2,1)
00267 !
00268 #define ALLOW_DEGRADED_CELL
00269 #ifdef ALLOW_DEGRADED_CELL
00270 !
00271 ! ??? ist das koscher ?? wird d1(n), d2(n), d3(n) == 0
00272 !
00273          do n = 1, ntet
00274 !cdir vector
00275             do i = 1, nc
00276             dnorm = abs(xyzedg(i, n,1,1)) + abs(xyzedg(i, n,2,1)) + &
00277                     abs(xyzedg(i, n,1,2)) + abs(xyzedg(i, n,2,2))
00278 
00279             if (abs(det(i, n)) < eps*dnorm*dnorm .or. dnorm == dzero) then
00280                det (i, n) = sign (rmxeps, det(i, n))
00281             else
00282                det (i, n) = 1.0d0 / det (i, n)
00283             endif
00284             end do ! i
00285          end do ! n
00286 
00287 #else 
00288 
00289 loop_n:  do n = 1, ntet
00290 !cdir vector
00291             do i = 1, nc
00292             dnorm = abs(xyzedg(i, n,1,1)) + abs(xyzedg(i, n,2,1)) + &
00293                     abs(xyzedg(i, n,1,2)) + abs(xyzedg(i, n,2,2))
00294 
00295             if (abs(det(i, n)) < eps*dnorm*dnorm .or. &
00296                 dnorm(i,n) == dzero) then
00297                det (i, n) = dnorm * 1e-25
00298 ! eigentlich exit loop_n und print_degraded cell
00299 ! ist bei vektorisierung verschwunden
00300 ! sollte man in part_list suchen
00301             endif
00302             end do ! i
00303          end do ! n
00304 !
00305 #ifdef PRINT_DEGRADED_CELL
00306       if (n < ntet) then
00307 !
00308 !===> cell is degraded
00309 !
00310          print 9960, trim(ch_id), grid_id, ic (i), &
00311                (xyzref (i, n, 1), xyzref (i, n, 2), n = 1, 4)
00312 !
00313             do n = 1, ntet
00314             if (abs(det(i, n)) < eps) then
00315                print 9950, n, det (i, n), dnorm, &
00316                  xyzedg (i, n,1, 1), xyzedg (i, n,1, 2), &
00317                  xyzedg (i, n,2, 1), xyzedg (i, n,2, 2)
00318             endif
00319             end do
00320 !
00321          nicht gefunden fnd (i) = .false. versucht, durch
00322          ganz kleine Determinante zu loesen
00323       endif
00324 #endif /* PRINT_DEGRADED_CELL */
00325 !
00326       det (:, :) = 1.0d0 / det (:, :)
00327 !
00328 #endif /* ALLOW_DEGRADED_CELL */
00329 !
00330 !===> Return mask for points "list(i)"
00331 !     which were found in the specific cell (ic(i,*), j,k)
00332 !
00333       tol1 = tol + 1.0
00334       fnd (:) = .false.
00335 !
00336          do n = 1, ntet
00337 !cdir vector
00338             do i = 1, nc
00339 
00340             d1 = (xyzpnt(i, n,1)*xyzedg(i, n,2,2)- &
00341                   xyzpnt(i, n,2)*xyzedg(i, n,1,2)) * det (i, n)
00342             d2 = (xyzpnt(i, n,2)*xyzedg(i, n,1,1)- &
00343                   xyzpnt(i, n,1)*xyzedg(i, n,2,1)) * det (i, n)
00344 !
00345             fnd (i) = fnd (i) .or. &
00346                (min(d1, d2) >= -tol .and. &
00347                 max(d1,dzero) + max(d2,dzero) <= tol1)
00348             end do ! nc
00349          end do ! ntet
00350 !
00351 !===> All done
00352 !
00353 #ifdef VERBOSE
00354       print 9980, trim(ch_id), count(fnd(:))
00355 
00356       call psmile_flushstd
00357 #endif /* VERBOSE */
00358 !
00359 !  Formats:
00360 !
00361 
00362 9990 format (1x, a, ': psmile_control_cell_gauss2_dble: nc', i5)
00363 9980 format (1x, a, ': psmile_control_cell_gauss2_dble: eof, suc', i5)
00364 
00365 #ifdef PRINT_DEGRADED_CELL
00366 9960 format (1x, a, ': psmile_control_cell_gauss2_dble: grid id =', i5, &
00367             /1x,  ' Grid cell (', i4,
00368                  ') is degraded! Cell coordinates are:', 1p,      &
00369             4 (/1x, '(', 1 (e17.9, ','), e17.9, ')'))
00370 9950 format (1x, i1, '-th spawn; det =', 1p, e17.9, ' (', e17.9, &
00371              ') of', 2 (/1x, 2e17.9, ','))
00372 #endif
00373 
00374       end subroutine psmile_control_cell_gauss2_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1