psmile_celltest_real.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2007-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PSMILe_Celltest_real
00008 !
00009 ! !INTERFACE:
00010 !
00011       subroutine psmile_celltest_real ( grid_id, range, sense, ierror )
00012 !
00013 ! !USES:
00014 !
00015       use PRISM_constants
00016 !
00017       use PSMILe, dummy_interface => PSMILe_Celltest_real
00018 
00019       implicit none
00020 !
00021 ! !INPUT PARAMETERS:
00022 !
00023       Integer, Intent (In)          :: grid_id
00024       Integer, Intent (In)          :: range(2,ndim_2d)
00025       Integer, Intent (Out)         :: sense
00026       Integer, Intent (Out)         :: ierror
00027 
00028 !     Returns the error code of PSMILe_Celltest_real
00029 !             ierror = 0 : No error
00030 !             ierror > 0 : Severe error
00031 !
00032 ! !LOCAL VARIABLES
00033 !
00034       Type (Corner_Block), Pointer  :: cp
00035 
00036       Integer                       :: i, j, index
00037       Integer                       :: ibeg, iend
00038       Integer                       :: jbeg, jend
00039 
00040       Integer                       :: n, np1, stride, isize
00041       Integer                       :: nbr_edges
00042 
00043       Integer                       :: sense_p
00044       Integer                       :: sense_n
00045 
00046       Real, Parameter               :: real_one  = 1.0
00047       Real, Parameter               :: real_zero = 0.0
00048       Real, Allocatable             :: edge(:,:)
00049       Real                          :: cross_prod
00050 !
00051       Integer, Parameter            :: nerrp = 3
00052       Integer                       :: ierrp (nerrp)
00053 !
00054 !
00055 ! !DESCRIPTION:
00056 !
00057 ! Subroutine "PSMILe_Celltest_real" checks whether the
00058 ! cell information is consistent with PSMILe internal
00059 ! assumptions. First we test the cell for convexity.
00060 ! Later we can expand this test for valid non-convex
00061 ! elements by evaluating the angles of non-convex elements.
00062 !
00063 ! !REVISION HISTORY:
00064 !
00065 !   Date      Programmer   Description
00066 ! ----------  ----------   -----------
00067 ! 05.11.19    R. Redler    created
00068 !
00069 !EOP
00070 !----------------------------------------------------------------------
00071 !
00072 !  $Id: psmile_celltest_real.F90 2325 2010-04-21 15:00:07Z valcke $
00073 !  $Author: valcke $
00074 !
00075    Character(len=len_cvs_string), save :: mycvs = 
00076        '$Id: psmile_celltest_real.F90 2325 2010-04-21 15:00:07Z valcke $'
00077 !
00078 !----------------------------------------------------------------------
00079 !
00080 #ifdef VERBOSE
00081       print 9990, trim(ch_id), range
00082       call psmile_flushstd
00083 #endif /* VERBOSE */
00084 !
00085 !  Initialization
00086 !
00087       ierror  = 0
00088       sense_p = 0
00089       sense_n = 0
00090 
00091       if ( Grids(grid_id)%grid_type /= PRISM_Irrlonlat_regvrt ) then
00092          ierrp (1) = Grids(grid_id)%grid_type
00093          ierror = PRISM_Error_Internal
00094          call psmile_error ( ierror, 'unsupported grid type', &
00095               ierrp, 1, __FILE__, __LINE__ )
00096          return
00097       endif
00098 
00099       cp => Grids(grid_id)%corner_pointer
00100 
00101       ibeg = range(1,1) - cp%corner_shape(1,1) + 1
00102       iend = range(2,1) - cp%corner_shape(1,1) + 1
00103       jbeg = range(1,2) - cp%corner_shape(1,2) + 1
00104       jend = range(2,2) - cp%corner_shape(1,2) + 1
00105 
00106       nbr_edges = cp%nbr_corners/2
00107       
00108       stride = (cp%corner_shape(2,1)-cp%corner_shape(1,1)+1) * &
00109                (cp%corner_shape(2,2)-cp%corner_shape(1,2)+1)
00110 
00111       isize  =  cp%corner_shape(2,1)-cp%corner_shape(1,1)+1
00112       !
00113       !----------------------------------
00114       ! Test for convexity of a the cells
00115       !   still needs to be vectorised.
00116       !----------------------------------
00117       !
00118 
00119       Allocate ( edge(2,nbr_edges) )
00120 
00121       do j = jbeg, jend
00122       do i = ibeg, iend
00123 
00124          index = (j-1)*isize+i
00125 
00126          do n = 1, nbr_edges-1
00127             edge(1,n) = cp%corners_real(1)%vector( n   *stride+index) - &
00128                         cp%corners_real(1)%vector((n-1)*stride+index)
00129             edge(2,n) = cp%corners_real(2)%vector( n   *stride+index) - &
00130                         cp%corners_real(2)%vector((n-1)*stride+index)
00131          enddo
00132 
00133          edge(1,nbr_edges) = cp%corners_real(1)%vector(index) - &
00134                              cp%corners_real(1)%vector((nbr_edges-1)*stride+index)
00135          edge(2,nbr_edges) = cp%corners_real(2)%vector(index) - &
00136                              cp%corners_real(2)%vector((nbr_edges-1)*stride+index)
00137          !
00138          !------------------------------------------------------
00139          ! get sign of cross products of egde vectors and sum up
00140          !------------------------------------------------------
00141          !
00142          sense    = 0
00143 
00144          do n = 1, nbr_edges
00145             np1 = mod(n, nbr_edges) + 1
00146             cross_prod = edge(1,n)*edge(2,np1) - edge(2,n)*edge(1,np1)
00147             if ( cross_prod /= real_zero ) &
00148             sense = sense + sign(real_one, cross_prod)
00149          enddo
00150 
00151          if ( abs(sense) /= nbr_edges ) then
00152 
00153             ierrp(1) = i + cp%corner_shape(1,1) - 1
00154             ierrp(2) = j + cp%corner_shape(1,2) - 1
00155 
00156             ierror = PRISM_Warn_Cell
00157             call psmile_warning ( ierror, 'Non-convex or degraded cell', &
00158                  ierrp, 2, __FILE__, __LINE__ )
00159             ierror = 0
00160 #ifdef DEBUG
00161             do n = 0, nbr_edges-1
00162              print *, ' corner: n, lon, lat', n+1, cp%corners_real(1)%vector(n*stride+index),  &
00163                                                    cp%corners_real(2)%vector(n*stride+index)
00164             enddo
00165             print *, ' calculated sense is ', sense
00166 #endif
00167          endif
00168 
00169          if ( sign(1,sense) > 0 ) then
00170             sense_p = sense_p + 1
00171          else
00172             sense_n = sense_n + 1
00173          endif
00174 
00175       enddo
00176       enddo
00177 
00178       Deallocate ( edge )
00179 
00180       if ( sense_p * sense_n /= 0 ) then
00181          ierror = PRISM_Warn_Cell
00182          ierrp(1) = sense_p
00183          ierrp(2) = sense_n
00184          call psmile_warning ( ierror, 'Sense of cells must be the same', &
00185             ierrp, 2, __FILE__, __LINE__ )
00186          ierror = 0
00187       endif
00188 
00189       sense = sign(1,sense)
00190 !
00191 !
00192 !===> All done
00193 !
00194 #ifdef VERBOSE
00195       print 9980, trim(ch_id), ierror
00196 
00197       call psmile_flushstd
00198 #endif /* VERBOSE */
00199 !
00200 !  Formats:
00201 !
00202 9990 format (1x, a, ': PSMILe_Celltest_real: range ', 4i8)
00203 9980 format (1x, a, ': PSMILe_Celltest_real: eof ierror =', i3)
00204 !
00205       end subroutine PSMILe_Celltest_real

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1