00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_control_cell_2d_dble ( &
00012 chmin1, chmin2, &
00013 chmax1, chmax2, &
00014 midp1, midp2, levdim, &
00015 ijk, xyz, nold, ignore, wide, found, newijk)
00016
00017
00018
00019 use PRISM_constants
00020
00021 use PSMILe, dummy_interface => PSMILe_mg_control_cell_2d_dble
00022
00023 implicit none
00024
00025
00026
00027 Integer, Intent (In) :: levdim (ndim_2d)
00028
00029
00030
00031 Double Precision, Intent (In) :: chmin1 (0:levdim(1),
00032 0:levdim(2))
00033 Double Precision, Intent (In) :: chmin2 (0:levdim(1),
00034 0:levdim(2))
00035
00036
00037
00038 Double Precision, Intent (In) :: chmax1 (0:levdim(1),
00039 0:levdim(2))
00040 Double Precision, Intent (In) :: chmax2 (0:levdim(1),
00041 0:levdim(2))
00042
00043
00044
00045 Double Precision, Intent (In) :: midp1 (0:levdim(1),
00046 0:levdim(2))
00047 Double Precision, Intent (In) :: midp2 (0:levdim(1),
00048 0:levdim(2))
00049
00050
00051
00052 Integer, Intent (In) :: ijk (ndim_2d)
00053
00054
00055
00056
00057 Double Precision, Intent (In) :: xyz (ndim_2d)
00058
00059
00060
00061 Integer, Intent (In) :: nold
00062
00063
00064
00065
00066
00067
00068 Integer, Intent (In) :: ignore (ndim_2d)
00069
00070
00071
00072 logical, Intent (In) :: wide
00073
00074
00075
00076
00077
00078 integer, Intent (Out) :: found
00079
00080
00081
00082
00083
00084 integer, Intent (Out) :: newijk (ndim_2d)
00085
00086
00087
00088
00089
00090 Double Precision, Parameter :: remax = 1.0e20
00091
00092 Integer, Parameter :: ndtrys = 4
00093 Integer, Parameter :: ndtryw = 16
00094
00095
00096
00097 Double Precision :: dist (ndtryw)
00098 Integer :: i, n, ndtry
00099 Integer :: nmin (1)
00100
00101 Integer, Pointer :: ijkctl (:, :)
00102 Integer, Target :: ijkctls (ndim_2d, ndtrys)
00103 Integer, Target :: ijkctlw (ndim_2d, ndtryw)
00104 Integer :: ijkdst (ndim_2d, ndtryw)
00105 Logical :: within (ndtryw)
00106
00107 #ifdef DEBUGX
00108 logical control
00109 common /huhu1/ control
00110 #endif
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 Character(len=len_cvs_string), save :: mycvs =
00138 '$Id: psmile_mg_control_cell_2d_dble.F90 2325 2010-04-21 15:00:07Z valcke $'
00139
00140
00141
00142
00143
00144 data ((ijkctls (i, n), i=1,ndim_2d), n = 1,ndtrys) &
00145 / 0, 0, 1, 0, &
00146 0, 1, 1, 1/
00147
00148
00149
00150
00151
00152
00153 data ((ijkctlw (i, n), i=1,ndim_2d), n = 1,ndtryw) &
00154 / 0, 0, 1, 0, 0, 1, 1, 1, &
00155 -1,-1, 0,-1, 1,-1, 2,-1, &
00156 -1, 0, 2, 0, &
00157 -1, 1, 2, 1, &
00158 -1, 2, 0, 2, 1, 2, 2, 2/
00159
00160
00161
00162
00163
00164 #ifdef VERBOSE_extra
00165 print 9990, trim(ch_id)
00166
00167 call psmile_flushstd
00168 #endif /* VERBOSE */
00169
00170
00171
00172 if (wide) then
00173 ndtry = ndtryw
00174 ijkctl => ijkctlw
00175 else
00176 ndtry = ndtrys
00177 ijkctl => ijkctls
00178 endif
00179
00180 #ifdef PRISM_ASSERTION
00181 if (nold < 0 .or. nold > ndtry) then
00182 call psmile_assert (__FILE__, __LINE__, &
00183 'wrong nold')
00184 endif
00185
00186 if (minval(ijk(:)) < 0 .or. minval(levdim(:)-ijk(:)) < 0) then
00187 call psmile_assert (__FILE__, __LINE__, 'wrong ijk')
00188 endif
00189 #endif
00190
00191
00192
00193 do n = 1, ndtry
00194 ijkdst (:, n) = ijk(:) + ijkctl(:,n)
00195 end do
00196
00197
00198
00199 do n = 1, ndtry
00200 within (n) = ijkdst (1,n) >= 0 .and. ijkdst(1,n) <= levdim(1) .and. &
00201 ijkdst (2,n) >= 0 .and. ijkdst(2,n) <= levdim(2)
00202 end do
00203 #ifdef DEBUGX
00204 if (control) print *, 'within a:', within (1:ndtry)
00205 #endif
00206
00207
00208
00209
00210
00211
00212 do n = 1, ndtry
00213 if (within(n)) then
00214 within (n) = xyz(1) >= chmin1(ijkdst(1,n), ijkdst(2,n)) .and. &
00215 xyz(2) >= chmin2(ijkdst(1,n), ijkdst(2,n)) .and. &
00216 xyz(1) <= chmax1(ijkdst(1,n), ijkdst(2,n)) .and. &
00217 xyz(2) <= chmax2(ijkdst(1,n), ijkdst(2,n))
00218 endif
00219 end do
00220 #ifdef DEBUGX
00221 if (control) print *, 'within b:', within (1:ndtry)
00222 #endif
00223
00224
00225
00226
00227 do n = 1, ndtry
00228 if (within(n)) then
00229 dist (n) = (xyz(1) - midp1(ijkdst(1,n), ijkdst(2,n)))**2 &
00230 + (xyz(2) - midp2(ijkdst(1,n), ijkdst(2,n)))**2
00231
00232 else
00233
00234 dist (n) = remax
00235
00236 endif
00237 end do
00238
00239
00240
00241 if (nold > 0) then
00242
00243 #ifdef PRISM_ASSERTIONX
00244 if (dist(nold) .eq. remax) then
00245 write (*, 9970) xyz
00246 9970 format (1x, 1p, 3e18.9)
00247
00248 call psmile_assert (__FILE__, __LINE__, &
00249 'incorrect nold')
00250 endif
00251 #endif
00252
00253
00254
00255 do n = 1, nold-1
00256 if (dist(n) <= dist(nold)) dist (n) = remax
00257 end do
00258
00259 do n = nold+1, ndtry
00260 if (dist(n) < dist(nold)) dist (n) = remax
00261 end do
00262
00263 dist (nold) = remax
00264 endif
00265
00266
00267
00268 100 continue
00269
00270 nmin = MINLOC (dist(1:ndtry))
00271 #ifdef MINLOCFIX
00272 if (nmin(1).eq.0) nmin=1
00273 #endif /* MINLOCFIX */
00274
00275
00276
00277 if (dist(nmin(1)) == remax) then
00278 found = 0
00279 else
00280
00281 if (ijkdst(1, nmin(1)) == ignore (1) .and. &
00282 ijkdst(2, nmin(1)) == ignore (2)) then
00283
00284
00285 dist (nmin(1)) = remax
00286 go to 100
00287 endif
00288
00289 found = nmin (1)
00290
00291 newijk (:) = ijkdst (:, nmin(1))
00292
00293 #ifdef PRISM_ASSERTION
00294 if ( xyz(1) < chmin1(newijk(1), newijk(2)) .or. &
00295 xyz(1) > chmax1(newijk(1), newijk(2)) .or. &
00296 xyz(2) < chmin2(newijk(1), newijk(2)) .or. &
00297 xyz(2) > chmax2(newijk(1), newijk(2))) then
00298 print *, 'xyz', xyz
00299 print *, 'chmin', chmin1(newijk(1), newijk(2)), &
00300 chmin2(newijk(1), newijk(2))
00301 print *, 'chmax', chmax1(newijk(1), newijk(2)), &
00302 chmax2(newijk(1), newijk(2))
00303
00304 call psmile_assert (__FILE__, __LINE__, &
00305 'not contained in computed cell')
00306 endif
00307 #endif
00308 endif
00309
00310
00311
00312 #ifdef VERBOSE_extra
00313 print 9980, trim(ch_id)
00314
00315 call psmile_flushstd
00316 #endif /* VERBOSE */
00317
00318 return
00319
00320
00321
00322 9990 format (1x, a, ': PSMILe_mg_control_cell_2d_dble:')
00323 9980 format (1x, a, ': PSMILe_mg_control_cell_2d_dble: eof')
00324
00325 end subroutine PSMILe_mg_control_cell_2d_dble