00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_next_level_1d_real ( &
00012 grid_id, idim, lev, nlev, &
00013 chmin, chmax, midp, levdim, &
00014 found, loc, coords, ibeg, iend, &
00015 ijkinc, ijkcoa, ierror)
00016
00017
00018
00019 use PRISM_constants
00020
00021 use PSMILe, dummy_interface => psmile_mg_next_level_1d_real
00022
00023 implicit none
00024
00025
00026
00027 Integer, Intent (In) :: grid_id
00028
00029
00030
00031
00032 Integer, Intent (In) :: idim
00033
00034
00035
00036 Integer, Intent (In) :: lev
00037
00038
00039
00040 Integer, Intent (In) :: nlev
00041
00042
00043
00044 Integer, Intent (In) :: levdim
00045
00046
00047
00048 Integer, Intent (InOut) :: ibeg
00049
00050
00051
00052
00053 Integer, Intent (InOut) :: iend
00054
00055
00056
00057
00058
00059 Real, Intent (In) :: chmin (0:levdim)
00060
00061
00062
00063 Real, Intent (In) :: chmax (0:levdim)
00064
00065
00066
00067 Real, Intent (In) :: midp (0:levdim)
00068
00069
00070
00071 Integer, Intent (InOut) :: found (iend)
00072
00073
00074
00075
00076
00077
00078 Integer, Intent (InOut) :: loc (iend)
00079
00080
00081
00082 Real, Intent (In) :: coords (iend)
00083
00084
00085
00086 Integer, Intent (In) :: ijkinc
00087
00088
00089
00090 Integer, Intent (In) :: ijkcoa
00091
00092
00093
00094
00095
00096 integer, Intent (Out) :: ierror
00097
00098
00099
00100
00101
00102
00103
00104 Integer, parameter :: ntry1 = 3
00105 Integer, parameter :: ntry3 = 3
00106 Integer, parameter :: ndtry = 5
00107 Real, parameter :: remax = 1.0e20
00108
00109
00110
00111
00112
00113 Integer :: levc
00114
00115
00116
00117 Integer :: i, ibegl, n, nprev
00118 Integer :: ifound, nmin(1)
00119 Integer :: ijkf, ijkold, newijk
00120 Integer :: ijkdst (ndtry)
00121 Real :: dist (ndtry)
00122
00123 #ifdef DEBUG
00124
00125
00126 Integer :: nfnd (0:4)
00127 #endif /* DEBUG */
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 Character(len=len_cvs_string), save :: mycvs =
00148 '$Id: psmile_mg_next_level_1d_real.F90 2912 2011-01-25 09:21:26Z coquart $'
00149
00150
00151
00152
00153
00154 #ifdef VERBOSE
00155 print 9990, trim(ch_id), lev, ibeg, iend
00156
00157 call psmile_flushstd
00158 #endif /* VERBOSE */
00159
00160 #ifdef PRISM_ASSERTION
00161 #endif
00162
00163 ierror = 0
00164 levc = lev + 1
00165
00166 #ifdef DEBUG
00167 nfnd (0) = 0
00168 nfnd (1) = 0
00169 nfnd (2) = 0
00170 nfnd (3) = 0
00171 nfnd (4) = 0
00172
00173
00174
00175
00176 #endif /* DEBUG */
00177
00178 #ifdef DEBUGX
00179 print *, 'begin ---'
00180 do i = ibeg, iend
00181 print *, 'i, coord, found', i, coords (i), loc(i), found (i)
00182 end do
00183 #endif
00184
00185
00186
00187
00188
00189 nprev = 0
00190 ibegl = ibeg
00191
00192
00193
00194 do while (ibegl <= iend)
00195
00196 do i = ibegl, iend, ijkinc
00197 if (found (i) == levc) go to 11
00198 end do
00199
00200 if (i .lt. iend+ijkinc) then
00201 i = iend
00202 if (found (i) == levc) go to 11
00203 endif
00204
00205 exit
00206
00207
00208
00209 11 continue
00210
00211 ijkf = min (loc(i) * ijkcoa, levdim)
00212
00213 ijkdst (1) = max(ijkf - 1, 0)
00214 ijkdst (2) = ijkf
00215 ijkdst (3) = min(ijkf + 1, levdim)
00216
00217 do n = 1, ntry1
00218 if (coords(i) >= chmin(ijkdst(n)) .and. &
00219 coords(i) <= chmax(ijkdst(n))) then
00220 dist (n) = abs (coords(i) - midp (ijkdst(n)))
00221 else
00222 dist (n) = remax
00223 endif
00224 end do
00225
00226
00227
00228 nmin = MINLOC (dist(1:ntry1))
00229 #ifdef MINLOCFIX
00230 if (nmin(1).eq.0) nmin=1
00231 #endif /* MINLOCFIX */
00232
00233 if (dist(nmin(1)) .ne. remax) then
00234 found (i) = lev
00235 loc (i) = ijkdst (nmin(1))
00236
00237 #ifdef DEBUG
00238 nfnd (1) = nfnd (1) + 1
00239 #endif /* DEBUG */
00240 go to 95
00241
00242 else
00243
00244 if (levc == nlev) then
00245 found (i) = - found(i)
00246 #ifdef DEBUG
00247 nfnd (0) = nfnd (0) + 1
00248 #endif /* DEBUG */
00249 go to 95
00250 endif
00251 endif
00252
00253
00254
00255
00256
00257
00258 ijkdst (ntry1+1) = max(ijkf-2, 0)
00259 ijkdst (ntry1+2) = min(ijkf+2, levdim)
00260
00261 do n = ntry1+1, ndtry
00262 if (coords(i) >= chmin(ijkdst(n)) .and. &
00263 coords(i) <= chmax(ijkdst(n))) then
00264 dist (n) = abs (coords(i) - midp (ijkdst(n)))
00265 else
00266 dist (n) = remax
00267 endif
00268 end do
00269
00270
00271
00272 nmin = MINLOC (dist(ntry1+1:ndtry)) + ntry1
00273 #ifdef MINLOCFIX
00274 if (nmin(1).eq.ntry1) nmin=ntry1 + 1
00275 #endif /* MINLOCFIX */
00276
00277 if (dist(nmin(1)) .ne. remax) then
00278 found (i) = lev
00279 loc (i) = ijkdst (nmin(1))
00280
00281 #ifdef DEBUG
00282 nfnd (2) = nfnd (2) + 1
00283 #endif /* DEBUG */
00284
00285 else
00286
00287 nprev = nprev + 1
00288 endif
00289
00290
00291
00292 95 if (i == iend) exit
00293 ibegl = min (iend, i+ijkinc)
00294
00295 end do
00296
00297
00298
00299 if (nprev == 0) go to 20
00300
00301
00302
00303
00304
00305
00306 ibegl = ibeg+ijkinc
00307
00308 do while (ibegl <= iend)
00309
00310 do i = ibegl, iend-ijkinc, ijkinc
00311 if (found (i) == levc .and. &
00312 found (i-ijkinc) == lev .and. &
00313 found (i+ijkinc) == lev) go to 211
00314 end do
00315
00316 if (i .lt. iend) then
00317 i = iend - ijkinc
00318 if (found (i) == levc .and. &
00319 found (i-ijkinc) == lev .and. &
00320 found (i+ijkinc) == lev) go to 211
00321 endif
00322
00323 exit
00324
00325
00326
00327
00328 211 continue
00329 ijkf = min ((loc (i-ijkinc) + loc (i+ijkinc)) / 2, levdim)
00330
00331 ijkold = min (loc(i) * ijkcoa, levdim)
00332
00333 if (ijkold == ijkf) go to 260
00334
00335 ijkdst (1) = max(ijkf - 1, 0)
00336 ijkdst (2) = ijkf
00337 ijkdst (3) = min(ijkf + 1, levdim)
00338
00339
00340
00341
00342 do n = 1, ntry3
00343 if (coords(i) >= chmin(ijkdst(n)) .and. &
00344 coords(i) <= chmax(ijkdst(n))) then
00345 dist (n) = abs (coords(i) - midp (ijkdst(n)))
00346 else
00347 dist (n) = remax
00348 endif
00349 end do
00350
00351
00352
00353 nmin = MINLOC (dist(1:ntry3))
00354 #ifdef MINLOCFIX
00355 if (nmin(1).eq.0) nmin=1
00356 #endif /* MINLOCFIX */
00357
00358 if (dist(nmin(1)) .ne. remax) then
00359 found (i) = lev
00360 loc (i) = ijkdst (nmin(1))
00361
00362 nprev = nprev - 1
00363
00364 #ifdef DEBUG
00365 nfnd (3) = nfnd (3) + 1
00366 #endif /* DEBUG */
00367 endif
00368
00369
00370
00371 260 if (i >= iend-ijkinc) exit
00372 ibegl = min (iend-ijkinc, i+ijkinc)
00373
00374 end do
00375
00376 if (nprev == 0) go to 20
00377
00378
00379
00380
00381
00382
00383
00384 ibegl = ibeg
00385
00386 do while (ibegl <= iend)
00387
00388
00389
00390
00391 do i = ibegl, iend, ijkinc
00392 if (found (i) == levc) go to 311
00393 end do
00394
00395 if (i < iend+ijkinc) then
00396 i = iend
00397 if (found (i) == levc) go to 311
00398 endif
00399
00400 exit
00401
00402
00403
00404 311 continue
00405 #ifdef PRISM_ASSERTION
00406 if (loc(i) < 0) then
00407 print *, i, loc(i)
00408 call psmile_assert (__FILE__, __LINE__, 'incorrect loc(i)')
00409 endif
00410 #endif /* PRISM_ASSERTION */
00411
00412 if (lev+1 < nlev) then
00413 call psmile_mg_prev_levels_1d_real (grid_id, idim, lev, nlev, &
00414 loc(i), coords(i), ifound, newijk)
00415
00416 if (ifound .gt. 0) then
00417 loc (i) = newijk
00418
00419 found (i) = lev
00420 #ifdef DEBUG
00421 nfnd (4) = nfnd (4) + 1
00422 #endif /* DEBUG */
00423 else
00424 found (i) = - found (i)
00425 #ifdef DEBUG
00426 nfnd (0) = nfnd (0) + 1
00427 #endif /* DEBUG */
00428 endif
00429 else
00430 found (i) = - found (i)
00431 #ifdef DEBUG
00432 nfnd (0) = nfnd (0) + 1
00433 #endif /* DEBUG */
00434 endif
00435
00436
00437
00438 nprev = nprev - 1
00439 if (nprev == 0) go to 20
00440
00441
00442
00443 if (i == iend) exit
00444
00445 ibegl = min (iend, i+ijkinc)
00446 end do
00447
00448
00449
00450 20 continue
00451
00452 #ifdef DEBUGX
00453 print *, 'end ---'
00454 do i = ibeg, iend
00455 print *, 'i, coord, found', i, coords (i), loc(i), found (i), chmin(loc(i)), chmax(loc(i))
00456 end do
00457 #endif
00458
00459 #ifdef DEBUG
00460 print 9970, trim(ch_id), lev, nfnd, ijkinc
00461 9970 format (1x, a, ': psmile_mg_next_level_1d_real: lev =', i3, &
00462 ': fnd =', 5i8, ', ijkinc ', 3i4)
00463 #endif /* DEBUG */
00464
00465 #ifdef VERBOSE
00466 print 9980, trim(ch_id), lev
00467
00468 call psmile_flushstd
00469 #endif /* VERBOSE */
00470
00471
00472
00473 9990 format (1x, a, ': psmile_mg_next_level_1d_real: level', i3, &
00474 ', ibeg, iend', 2i6)
00475 9980 format (1x, a, ': psmile_mg_next_level_1d_real: eof, level', i3)
00476
00477 end subroutine psmile_mg_next_level_1d_real