psmile_control_cell_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_Control_cell_2d_dble
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_control_cell_2d_dble (grid_id,               &
00012                       ic, nc, icdim1, 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_2d_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)            :: icdim1
00039 !
00040 !     First dimension of "ic"
00041 !
00042       Integer, Intent (In)            :: ic (icdim1, ndim_2d)
00043 !
00044 !     Indices of the (corner) cells to be controlled
00045 !     ic (1:nc, 1) = 1st index (i-index) of the corner cell
00046 !     ic (1:nc, 2) = 2nd index (j-index) of the corner cell
00047 !
00048       Integer, Intent (In)            :: list (nc)
00049 !
00050 !     I-Indices of the points in to be controlled
00051 !
00052       Integer, Intent (In)            :: j
00053 !
00054 !     J-Index of the points in to be controlled
00055 !
00056       Integer, Intent (In)            :: k
00057 !
00058 !     K-Index of the points in to be controlled
00059 !
00060       Integer, Intent (In)            :: shape (2, ndim_3d)
00061 
00062 !     Dimension of coordinate arrays "coord1" and "coord2"
00063 !     which contain the coordinates to be searched.
00064 
00065       Double Precision, Intent (In)   :: coords1 (shape(1,1):shape(2,1), 
00066                                                   shape(1,2):shape(2,2), 
00067                                                   shape(1,3):shape(2,3))
00068       Double Precision, Intent (In)   :: coords2 (shape(1,1):shape(2,1), 
00069                                                   shape(1,2):shape(2,2), 
00070                                                   shape(1,3):shape(2,3))
00071 
00072 !     Coordinates to be searched
00073 
00074       Integer, Intent (In)            :: corner_shape (2, ndim_2d)
00075 
00076 !     Dimension of corner coordinate arrays
00077 
00078       Integer, Intent (In)            :: nbr_corners
00079 
00080 !     Number of corners
00081 !     Note: This routine assumes nbr_corners == 4.
00082 
00083       Double Precision,   Intent (In) ::                 
00084          corners1 ( corner_shape(1,1):corner_shape(2,1), 
00085                     corner_shape(1,2):corner_shape(2,2), nbr_corners)
00086 
00087       Double Precision,   Intent (In) ::                 
00088          corners2 ( corner_shape(1,1):corner_shape(2,1), 
00089                     corner_shape(1,2):corner_shape(2,2), nbr_corners)
00090 
00091 !     Corner coordinates
00092 
00093       Double Precision, Intent (In)   :: tol
00094 !
00095 !     Absolute tolerance for search of "identical" points
00096 !     TOL >= 0.0
00097 !
00098 ! !OUTPUT PARAMETERS:
00099 !
00100       Logical, Intent (Out)           :: fnd (nc)
00101 !
00102 !     Was the i-th point of "list" found within cell "ic"
00103 !
00104       Integer, Intent (Out)           :: ierror
00105 
00106 !     Returns the error code of PSMILe_Control_cell_2d_dble;
00107 !             ierror = 0 : No error
00108 !             ierror > 0 : Severe error
00109 !
00110 ! !DEFINED PARAMETERS:
00111 !
00112 !  NTET = Number of triangles used to determine whether
00113 !         point is within the grid cell
00114 !  EPS  = Tolerance for determinate of deformed grid cells
00115 !
00116       Integer, Parameter              :: ntet = 3
00117 !
00118       Double Precision, Parameter     :: eps = 1.0d-9
00119       Double Precision, Parameter     :: rmxeps = 1.0d30
00120       Double Precision, Parameter     :: dzero = 0.0
00121 !
00122 ! !LOCAL VARIABLES
00123 !
00124 !     ... for tolerances
00125 !
00126       Double Precision                :: tol1
00127 !
00128 !     ... for locations controlled
00129 !
00130       Integer                         :: i, jj, m, n
00131 !
00132 !     ... Logical reference point and edges (constant)
00133 ! 
00134       Integer, Save                   :: ijkedg (2, ntet)
00135 !
00136 !     ... Reference point and edges and distances
00137 ! 
00138       Double Precision                :: xyzpnt (nc, ntet, ndim_2d), 
00139                                          xyzref (nc, ntet, ndim_2d)
00140       Double Precision                :: xyzedg (nc, ntet, ndim_2d, 2)
00141       Double Precision                :: d1, d2
00142       Double Precision                :: det (nc, ntet)
00143       Double Precision                :: dnorm
00144 !
00145 ! !DESCRIPTION:
00146 !
00147 ! Subroutine "PSMILe_Control_cell_2d_dble" controls whether the point
00148 ! "(list(i),j,k)" is contained in the corner cell "ic(i,*)".
00149 ! The routine assumes that the number of corners for the 2-dimensional
00150 ! cell is 4.
00151 !
00152 !
00153 ! !REVISION HISTORY:
00154 !
00155 !   Date      Programmer   Description
00156 ! ----------  ----------   -----------
00157 ! 12.03.07    H. Ritzdorf  created
00158 !
00159 !EOP
00160 !----------------------------------------------------------------------
00161 !
00162 !  $Id: psmile_control_cell_2d_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_2d_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,1) < corner_shape(1,1) .or. ic(i,1) > corner_shape(2,1) .or. &
00203              ic(i,2) < corner_shape(1,2) .or. ic(i,2) > corner_shape(2,2) ) then
00204             exit
00205          endif
00206          end do
00207 !
00208       if (i <= nc) then
00209          print *, 'i, ic', i, ic(i, :)
00210          print *, 'corner_shape', corner_shape
00211          call psmile_assert (__FILE__, __LINE__, &
00212                              'wrong index')
00213       endif
00214 #endif
00215 !
00216       ierror = 0
00217 !
00218 !===> Compute reference points, corners and edges of transformed
00219 !     triangles.
00220 !
00221         do n = 1, ntet
00222 !cdir vector
00223            do i = 1, nc
00224            xyzref (i, n, 1) = corners1 (ic(i,1), ic(i,2), n)
00225            xyzref (i, n, 2) = corners2 (ic(i,1), ic(i,2), n)
00226            end do
00227 !
00228         xyzpnt (:, n, 1) = coords1 (list(:), j, k) - xyzref (:, n, 1)
00229         xyzpnt (:, n, 2) = coords2 (list(:), j, k) - xyzref (:, n, 2)
00230 !
00231            do m = 1, 2
00232 !cdir vector
00233               do i = 1, nc
00234               xyzedg (i, n, 1, m) = corners1 (ic(i,1), ic(i,2), ijkedg(m, n)) &
00235                                   - xyzref (i, n, 1)
00236 
00237               xyzedg (i, n, 2, m) = corners2 (ic(i,1), ic(i,2), ijkedg(m, n)) &
00238                                   - xyzref (i, n, 2)
00239               end do
00240            end do
00241         end do ! n
00242 !
00243 !===> Solve bilinear system; compute spat product
00244 !
00245 !   (xyzedg(*,1), xyzedg(*,2)) (x) = xyzpnt
00246 !
00247       det(:, :) = xyzedg(:, :, 1,1)*xyzedg(:, :, 2,2) &
00248                 - xyzedg(:, :, 1,2)*xyzedg(:, :, 2,1)
00249 
00250 #ifdef DEBUG_TRACE
00251       if (j == ictl_ind(2)) then
00252 !cdir vector
00253             do i = 1, nc
00254             if ( list(i) == ictl_ind(1) ) exit
00255             end do
00256 
00257          if (i <= nc) then
00258             print *, 'ictl: i,j', list(i), j, coords1 (list(i), j, k), coords2 (list(i), j, k)
00259             do n = 1, 4
00260                print *, corners1 (ic(i,1), ic(i,2), n), corners2 (ic(i,1), ic(i,2), n)
00261             enddo
00262             print *, '#################################################'
00263             print *, ' i, nc ', i, nc
00264             print *, ' det', det (i, :)
00265          end if
00266       end if
00267 #endif
00268 !
00269 #define ALLOW_DEGRADED_CELL
00270 #ifdef ALLOW_DEGRADED_CELL
00271 !
00272 ! ??? ist das koscher ?? wird d1(n), d2(n), d3(n) == 0
00273 !
00274          do n = 1, ntet
00275 !cdir vector
00276             do i = 1, nc
00277             dnorm = abs(xyzedg(i, n,1,1)) + abs(xyzedg(i, n,2,1)) + &
00278                     abs(xyzedg(i, n,1,2)) + abs(xyzedg(i, n,2,2))
00279 
00280             if (abs(det(i, n)) < eps*dnorm*dnorm .or. dnorm == dzero) then
00281                det (i, n) = sign (rmxeps, det(i, n))
00282             else
00283                det (i, n) = 1.0d0 / det (i, n)
00284             endif
00285             end do ! i
00286          end do ! n
00287 
00288 #else 
00289 
00290 loop_n:  do n = 1, ntet
00291 !cdir vector
00292             do i = 1, nc
00293             dnorm = abs(xyzedg(i, n,1,1)) + abs(xyzedg(i, n,2,1)) + &
00294                     abs(xyzedg(i, n,1,2)) + abs(xyzedg(i, n,2,2))
00295 
00296             if (abs(det(i, n)) < eps*dnorm*dnorm .or. &
00297                 dnorm(i,n) == dzero) then
00298                det (i, n) = dnorm * 1e-25
00299 ! eigentlich exit loop_n und print_degraded cell
00300 ! ist bei vektorisierung verschwunden
00301 ! sollte man in part_list suchen
00302             endif
00303             end do ! i
00304          end do ! n
00305 !
00306 #ifdef PRINT_DEGRADED_CELL
00307       if (n < ntet) then
00308 !
00309 !===> cell is degraded
00310 !
00311          print 9960, trim(ch_id), grid_id, ic (i, :), &
00312                corners1(ic(i,1), ic(i,2), 1),  &
00313                corners2(ic(i,1), ic(i,2), 1),  &
00314                corners1(ic(i,1), ic(i,2), 2),  &
00315                corners2(ic(i,1), ic(i,2), 2),  &
00316                corners1(ic(i,1), ic(i,2), 3),  &
00317                corners2(ic(i,1), ic(i,2), 3),  &
00318                corners1(ic(i,1), ic(i,2), 4),  &
00319                corners2(ic(i,1), ic(i,2), 4)
00320 !
00321             do n = 1, ntet
00322             if (abs(det(i, n)) < eps) then
00323                print 9950, n, det (i, n), dnorm, &
00324                  xyzedg (i, n,1, 1), xyzedg (i, n,1, 2), &
00325                  xyzedg (i, n,2, 1), xyzedg (i, n,2, 2)
00326             endif
00327             end do
00328 !
00329          nicht gefunden fnd (i) = .false. versucht, durch
00330          ganz kleine Determinante zu loesen
00331       endif
00332 #endif /* PRINT_DEGRADED_CELL */
00333 !
00334       det (:, :) = 1.0d0 / det (:, :)
00335 !
00336 #endif /* ALLOW_DEGRADED_CELL */
00337 !
00338 !===> Return mask for points "list(i)"
00339 !     which were found in the specific cell (ic(i,*), j,k)
00340 !
00341       tol1 = tol + 1.0
00342       fnd (:) = .false.
00343 !
00344          do n = 1, ntet
00345 !cdir vector
00346             do i = 1, nc
00347 
00348             d1 = (xyzpnt(i, n,1)*xyzedg(i, n,2,2)- &
00349                   xyzpnt(i, n,2)*xyzedg(i, n,1,2)) * det (i, n)
00350             d2 = (xyzpnt(i, n,2)*xyzedg(i, n,1,1)- &
00351                   xyzpnt(i, n,1)*xyzedg(i, n,2,1)) * det (i, n)
00352 !
00353             fnd (i) = fnd (i) .or. &
00354                (min(d1, d2) >= -tol .and. &
00355                 max(d1,dzero) + max(d2,dzero) <= tol1)
00356             end do ! nc
00357          end do ! ntet
00358 !
00359 !===> All done
00360 !
00361 #ifdef VERBOSE
00362       print 9980, trim(ch_id), count(fnd(:))
00363 
00364       call psmile_flushstd
00365 #endif /* VERBOSE */
00366 !
00367 !  Formats:
00368 !
00369 
00370 9990 format (1x, a, ': psmile_control_cell_2d_dble: nc', i5)
00371 9980 format (1x, a, ': psmile_control_cell_2d_dble: eof, suc', i5)
00372 
00373 #ifdef PRINT_DEGRADED_CELL
00374 9960 format (1x, a, ': psmile_control_cell_2d_dble: grid id =', i5, &
00375             /1x,  ' Grid cell (', i4, ',', i4,                    &
00376                  ') is degraded! Cell coordinates are:', 1p,      &
00377             4 (/1x, '(', 1 (e17.9, ','), e17.9, ')'))
00378 9950 format (1x, i1, '-th spawn; det =', 1p, e17.9, ' (', e17.9, &
00379              ') of', 2 (/1x, 2e17.9, ','))
00380 #endif
00381 
00382       end subroutine psmile_control_cell_2d_dble

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1