00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_celltest_real ( grid_id, range, sense, ierror )
00012
00013
00014
00015 use PRISM_constants
00016
00017 use PSMILe, dummy_interface => PSMILe_Celltest_real
00018
00019 implicit none
00020
00021
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
00029
00030
00031
00032
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
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
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
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
00115
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
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
00193
00194 #ifdef VERBOSE
00195 print 9980, trim(ch_id), ierror
00196
00197 call psmile_flushstd
00198 #endif /* VERBOSE */
00199
00200
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