00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_next_level_3d_real ( &
00012 grid_id, lev, nlev, &
00013 chmin1, chmin2, chmin3, &
00014 chmax1, chmax2, chmax3, &
00015 midp1, midp2, midp3, &
00016 levdim, &
00017 found, loc, range, &
00018 coords1, coords2, coords3, &
00019 shape, control, &
00020 ijkinc, ijkcoa, ierror)
00021
00022
00023
00024 use PRISM_constants
00025
00026 use PSMILe, dummy_interface => PSMILe_mg_next_level_3d_real
00027
00028 implicit none
00029
00030
00031
00032 Integer, Intent (In) :: grid_id
00033
00034
00035
00036
00037 Integer, Intent (In) :: lev
00038
00039
00040
00041 Integer, Intent (In) :: nlev
00042
00043
00044
00045 Integer, Intent (In) :: levdim (ndim_3d)
00046
00047
00048
00049 Integer, Intent (In) :: range (2, ndim_3d)
00050
00051
00052
00053 Integer, Intent (In) :: shape (2, ndim_3d)
00054
00055
00056
00057 Real, Intent (In) :: chmin1 (0:levdim(1),
00058 0:levdim(2),
00059 0:levdim(3))
00060 Real, Intent (In) :: chmin2 (0:levdim(1),
00061 0:levdim(2),
00062 0:levdim(3))
00063 Real, Intent (In) :: chmin3 (0:levdim(1),
00064 0:levdim(2),
00065 0:levdim(3))
00066
00067
00068
00069 Real, Intent (In) :: chmax1 (0:levdim(1),
00070 0:levdim(2),
00071 0:levdim(3))
00072 Real, Intent (In) :: chmax2 (0:levdim(1),
00073 0:levdim(2),
00074 0:levdim(3))
00075 Real, Intent (In) :: chmax3 (0:levdim(1),
00076 0:levdim(2),
00077 0:levdim(3))
00078
00079
00080
00081 Real, Intent (In) :: midp1 (0:levdim(1),
00082 0:levdim(2),
00083 0:levdim(3))
00084 Real, Intent (In) :: midp2 (0:levdim(1),
00085 0:levdim(2),
00086 0:levdim(3))
00087 Real, Intent (In) :: midp3 (0:levdim(1),
00088 0:levdim(2),
00089 0:levdim(3))
00090
00091
00092
00093 Integer, Intent (InOut) :: found (range(1,1):range(2,1),
00094 range(1,2):range(2,2),
00095 range(1,3):range(2,3))
00096
00097
00098
00099
00100
00101
00102 Integer, Intent (InOut) :: loc (ndim_3d,
00103 range(1,1):range(2,1),
00104 range(1,2):range(2,2),
00105 range(1,3):range(2,3))
00106
00107
00108
00109 Real, Intent (In) :: coords1 (shape(1,1):shape(2,1),
00110 shape(1,2):shape(2,2),
00111 shape(1,3):shape(2,3))
00112 Real, Intent (In) :: coords2 (shape(1,1):shape(2,1),
00113 shape(1,2):shape(2,2),
00114 shape(1,3):shape(2,3))
00115 Real, Intent (In) :: coords3 (shape(1,1):shape(2,1),
00116 shape(1,2):shape(2,2),
00117 shape(1,3):shape(2,3))
00118
00119
00120
00121 Integer, Intent (InOut) :: control (2, ndim_3d)
00122
00123
00124
00125
00126 Integer, Intent (In) :: ijkinc (ndim_3d)
00127
00128
00129
00130 Integer, Intent (In) :: ijkcoa (ndim_3d)
00131
00132
00133
00134
00135
00136 integer, Intent (Out) :: ierror
00137
00138
00139
00140
00141
00142
00143
00144 Integer, parameter :: ndtry = 64
00145 Integer, parameter :: ntry1 = 8
00146 Integer, parameter :: ntry3 = 27
00147 Integer, parameter :: ntry2 = ndtry - ntry1
00148 Real, parameter :: remax = 1.0e20
00149
00150
00151
00152
00153
00154 Integer :: levc
00155
00156
00157
00158 Integer :: i, j, k
00159 Integer :: ibegl, n, nprev
00160 Integer :: ifound, nmin(1)
00161 Integer :: ijkf(ndim_3d), ijkold(ndim_3d), newijk(ndim_3d)
00162 Integer :: ijkctl (ndim_3d, ndtry), ijkdst (ndim_3d, ndtry)
00163 Integer :: ijkctl3 (ndim_3d, ndtry)
00164 Real :: dist (ndtry)
00165 Real :: xyz (ndim_3d)
00166
00167 #ifdef DEBUG
00168
00169
00170 Integer :: nfnd (0:4)
00171 #endif /* DEBUG */
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 Character(len=len_cvs_string), save :: mycvs =
00192 '$Id: psmile_mg_next_level_3d_real.F90 2325 2010-04-21 15:00:07Z valcke $'
00193
00194
00195
00196
00197
00198 data ((ijkctl (i, n), i=1,ndim_3d), n = 1,ntry1) &
00199 / 0, 0, 0, 1, 0, 0, &
00200 0, 1, 0, 1, 1, 0, &
00201 0, 0, 1, 1, 0, 1, &
00202 0, 1, 1, 1, 1, 1 /
00203
00204
00205
00206 data ((ijkctl (i, n), i=1,ndim_3d), n = ntry1+1, ntry1+16) &
00207 /-1,-1,-1, 0,-1,-1, 1,-1,-1, 2,-1,-1, &
00208 -1, 0,-1, 0, 0,-1, 1, 0,-1, 2, 0,-1, &
00209 -1, 1,-1, 0, 1,-1, 1, 1,-1, 2, 1,-1, &
00210 -1, 2,-1, 0, 2,-1, 1, 2,-1, 2, 2,-1/
00211 data ((ijkctl (i, n), i=1,ndim_3d), n = ntry1+17, ntry1+28) &
00212 /-1,-1, 0, 0,-1, 0, 1,-1, 0, 2,-1, 0, &
00213 -1, 0, 0, 2, 0, 0, &
00214 -1, 1, 0, 2, 1, 0, &
00215 -1, 2, 0, 0, 2, 0, 1, 2, 0, 2, 2, 0/
00216 data ((ijkctl (i, n), i=1,ndim_3d), n = ntry1+29, ntry1+40) &
00217 /-1,-1, 1, 0,-1, 1, 1,-1, 1, 2,-1, 1, &
00218 -1, 0, 1, 2, 0, 1, &
00219 -1, 1, 1, 2, 1, 1, &
00220 -1, 2, 1, 0, 2, 1, 1, 2, 1, 2, 2, 1/
00221 data ((ijkctl (i, n), i=1,ndim_3d), n = ntry1+41, ntry1+56) &
00222 /-1,-1, 2, 0,-1, 2, 1,-1, 2, 2,-1, 2, &
00223 -1, 0, 2, 0, 0, 2, 1, 0, 2, 2, 0, 2, &
00224 -1, 1, 2, 0, 1, 2, 1, 1, 2, 2, 1, 2, &
00225 -1, 2, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2/
00226
00227
00228
00229 data ((ijkctl3 (i, n), i=1,ndim_3d), n = 1,ntry3) &
00230 / -1,-1,-1, 0,-1,-1, 1,-1,-1, &
00231 -1, 0,-1, 0, 0,-1, 1, 0,-1, &
00232 -1, 1,-1, 0, 1,-1, 1, 1,-1, &
00233 -1,-1, 0, 0,-1, 0, 1,-1, 0, &
00234 -1, 0, 0, 0, 0, 0, 1, 0, 0, &
00235 -1, 1, 0, 0, 1, 0, 1, 1, 0, &
00236 -1,-1, 1, 0,-1, 1, 1,-1, 1, &
00237 -1, 0, 1, 0, 0, 1, 1, 0, 1, &
00238 -1, 1, 1, 0, 1, 1, 1, 1, 1 /
00239
00240
00241
00242
00243
00244 #ifdef VERBOSE
00245 print 9990, trim(ch_id), lev, control
00246
00247 call psmile_flushstd
00248 #endif /* VERBOSE */
00249
00250 #ifdef PRISM_ASSERTION
00251 #endif
00252
00253 ierror = 0
00254 levc = lev + 1
00255
00256 #ifdef DEBUG
00257 nfnd (0) = 0
00258 nfnd (1) = 0
00259 nfnd (2) = 0
00260 nfnd (3) = 0
00261 nfnd (4) = 0
00262 #endif /* DEBUG */
00263
00264 do k = control(1,3), control(2,3), ijkinc (3)
00265 do j = control(1,2), control (2,2), ijkinc (2)
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 nprev = 0
00280
00281 ibegl = control (1, 1)
00282
00283
00284
00285 do while (ibegl <= control(2,1))
00286
00287 do i = ibegl, control(2,1), ijkinc(1)
00288 if (found (i,j,k) == levc) go to 11
00289 end do
00290
00291 if (i .lt. control(2,1)+ijkinc(1)) then
00292 i = control(2,1)
00293 if (found (i,j,k) == levc) go to 11
00294 endif
00295
00296 exit
00297
00298
00299
00300 11 continue
00301
00302 ijkf(:) = min (loc(:,i,j,k) * ijkcoa(:), levdim(:))
00303
00304
00305 do n = 1, ntry1
00306 ijkdst (:, n) = max(0, min(ijkf(:) + ijkctl(:,n), levdim(:)))
00307 end do
00308
00309
00310 do n = 1, ntry1
00311 if (coords1(i,j,k) >= chmin1(ijkdst(1,n), &
00312 ijkdst(2,n), &
00313 ijkdst(3,n)) .and. &
00314 coords2(i,j,k) >= chmin2(ijkdst(1,n), &
00315 ijkdst(2,n), &
00316 ijkdst(3,n)) .and. &
00317 coords3(i,j,k) >= chmin3(ijkdst(1,n), &
00318 ijkdst(2,n), &
00319 ijkdst(3,n)) .and. &
00320 coords1(i,j,k) <= chmax1(ijkdst(1,n), &
00321 ijkdst(2,n), &
00322 ijkdst(3,n)) .and. &
00323 coords2(i,j,k) <= chmax2(ijkdst(1,n), &
00324 ijkdst(2,n), &
00325 ijkdst(3,n)) .and. &
00326 coords3(i,j,k) <= chmax3(ijkdst(1,n), &
00327 ijkdst(2,n), &
00328 ijkdst(3,n))) then
00329 dist (n) = (coords1(i,j,k) - &
00330 midp1(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2 &
00331 + (coords2(i,j,k) - &
00332 midp2(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2 &
00333 + (coords3(i,j,k) - &
00334 midp3(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2
00335
00336 else
00337
00338 dist (n) = remax
00339
00340 endif
00341 end do
00342
00343
00344
00345 nmin = MINLOC (dist(1:ntry1))
00346 #ifdef MINLOCFIX
00347 if (nmin(1).eq.0) nmin=1
00348 #endif /* MINLOCFIX */
00349
00350 if (dist(nmin(1)) .ne. remax) then
00351 found (i,j,k) = lev
00352 loc (:,i,j,k) = ijkdst (:,nmin(1))
00353
00354 #ifdef DEBUG
00355 nfnd (1) = nfnd (1) + 1
00356 #endif /* DEBUG */
00357 go to 95
00358
00359 else
00360
00361 if (levc == nlev) then
00362 found (i,j,k) = - found(i,j,k)
00363 #ifdef DEBUG
00364 nfnd (0) = nfnd (0) + 1
00365 #endif /* DEBUG */
00366 go to 95
00367 endif
00368 endif
00369
00370
00371
00372
00373
00374
00375
00376 do n = ntry1+1, ndtry
00377 ijkdst (:, n) = max (0, min(ijkf(:) + ijkctl(:,n), levdim(:)))
00378 end do
00379
00380 do n = ntry1+1, ndtry
00381 if (coords1(i,j,k) >= chmin1(ijkdst(1,n), &
00382 ijkdst(2,n), &
00383 ijkdst(3,n)) .and. &
00384 coords2(i,j,k) >= chmin2(ijkdst(1,n), &
00385 ijkdst(2,n), &
00386 ijkdst(3,n)) .and. &
00387 coords3(i,j,k) >= chmin3(ijkdst(1,n), &
00388 ijkdst(2,n), &
00389 ijkdst(3,n)) .and. &
00390 coords1(i,j,k) <= chmax1(ijkdst(1,n), &
00391 ijkdst(2,n), &
00392 ijkdst(3,n)) .and. &
00393 coords2(i,j,k) <= chmax2(ijkdst(1,n), &
00394 ijkdst(2,n), &
00395 ijkdst(3,n)) .and. &
00396 coords3(i,j,k) <= chmax3(ijkdst(1,n), &
00397 ijkdst(2,n), &
00398 ijkdst(3,n))) then
00399 dist (n) = (coords1(i,j,k) - &
00400 midp1(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2 &
00401 + (coords2(i,j,k) - &
00402 midp2(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2 &
00403 + (coords3(i,j,k) - &
00404 midp3(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2
00405
00406 else
00407
00408 dist (n) = remax
00409
00410 endif
00411 end do
00412
00413
00414
00415 nmin = MINLOC (dist(ntry1+1:ndtry)) + ntry1
00416 #ifdef MINLOCFIX
00417 if (nmin(1).eq.ntry1) nmin=ntry1+1
00418 #endif /* MINLOCFIX */
00419
00420 if (dist(nmin(1)) .ne. remax) then
00421 found (i,j,k) = lev
00422 loc (:,i,j,k) = ijkdst (:,nmin(1))
00423
00424 #ifdef DEBUG
00425 nfnd (2) = nfnd (2) + 1
00426 #endif /* DEBUG */
00427
00428 else
00429
00430 nprev = nprev + 1
00431 endif
00432
00433
00434
00435 95 if (i == control(2,1)) exit
00436 ibegl = min (control(2,1), i+ijkinc(1))
00437
00438 end do
00439
00440
00441
00442 if (nprev == 0) go to 20
00443
00444
00445
00446
00447
00448
00449 ibegl = control (1, 1) + ijkinc(1)
00450
00451 do while (ibegl <= control(2,1))
00452
00453 do i = ibegl, control(2,1)-ijkinc(1), ijkinc(1)
00454 if (found (i,j,k) == levc .and. &
00455 found (i-ijkinc(1),j,k) == lev .and. &
00456 found (i+ijkinc(1),j,k) == lev) go to 211
00457 end do
00458
00459 if (i .lt. control(2,1)) then
00460 i = control(2,1) - ijkinc(1)
00461 if (found (i,j,k) == levc .and. &
00462 found (i-ijkinc(1),j,k) == lev .and. &
00463 found (i+ijkinc(1),j,k) == lev) go to 211
00464 endif
00465
00466 exit
00467
00468
00469
00470
00471 211 continue
00472
00473 ijkf (:) = min((loc (:, i-ijkinc(1),j,k) + loc (:, i+ijkinc(1),j,k))/2, &
00474 levdim(:))
00475
00476 ijkold (:) = min (loc(:, i,j,k) * ijkcoa(:), levdim(:))
00477
00478 if (ijkold(1) == ijkf(1) .and. &
00479 ijkold(2) == ijkf(2) .and. &
00480 ijkold(3) == ijkf(3)) go to 260
00481
00482
00483 do n = 1, ntry3
00484 ijkdst (:, n) = max (0, min(ijkf(:) + ijkctl3(:,n), levdim(:)))
00485 end do
00486
00487
00488
00489
00490 do n = 1, ntry3
00491 if (coords1(i,j,k) >= chmin1(ijkdst(1,n), &
00492 ijkdst(2,n), &
00493 ijkdst(3,n)) .and. &
00494 coords2(i,j,k) >= chmin2(ijkdst(1,n), &
00495 ijkdst(2,n), &
00496 ijkdst(3,n)) .and. &
00497 coords3(i,j,k) >= chmin3(ijkdst(1,n), &
00498 ijkdst(2,n), &
00499 ijkdst(3,n)) .and. &
00500 coords1(i,j,k) <= chmax1(ijkdst(1,n), &
00501 ijkdst(2,n), &
00502 ijkdst(3,n)) .and. &
00503 coords2(i,j,k) <= chmax2(ijkdst(1,n), &
00504 ijkdst(2,n), &
00505 ijkdst(3,n)) .and. &
00506 coords3(i,j,k) <= chmax3(ijkdst(1,n), &
00507 ijkdst(2,n), &
00508 ijkdst(3,n))) then
00509 dist (n) = (coords1(i,j,k) - &
00510 midp1(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2 &
00511 + (coords2(i,j,k) - &
00512 midp2(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2 &
00513 + (coords3(i,j,k) - &
00514 midp3(ijkdst(1,n), ijkdst(2,n), ijkdst(3,n)))**2
00515
00516 else
00517
00518 dist (n) = remax
00519
00520 endif
00521 end do
00522
00523
00524
00525 nmin = MINLOC (dist(1:ntry3))
00526 #ifdef MINLOCFIX
00527 if (nmin(1).eq.0) nmin=1
00528 #endif /* MINLOCFIX */
00529
00530 if (dist(nmin(1)) .ne. remax) then
00531 found (i,j,k) = lev
00532 loc (:, i,j,k) = ijkdst (:, nmin(1))
00533
00534 nprev = nprev - 1
00535
00536 #ifdef DEBUG
00537 nfnd (3) = nfnd (3) + 1
00538 #endif /* DEBUG */
00539 endif
00540
00541
00542
00543 260 if (i >= control(2,1)-ijkinc(1)) exit
00544 ibegl = min (control(2,1)-ijkinc(1), i+ijkinc(1))
00545
00546 end do
00547
00548 if (nprev == 0) go to 20
00549
00550
00551
00552
00553
00554
00555
00556 ibegl = control (1, 1)
00557
00558 do while (ibegl <= control(2,1))
00559
00560
00561
00562
00563 do i = ibegl, control(2,1), ijkinc(1)
00564 if (found (i,j,k) == levc) go to 311
00565 end do
00566
00567 if (i .lt. control(2,1)+ijkinc(1)) then
00568 i = control(2,1)
00569 if (found (i,j,k) == levc) go to 311
00570 endif
00571
00572 exit
00573
00574
00575
00576 311 continue
00577
00578 if (lev+1 < nlev) then
00579 xyz (1) = coords1 (i,j,k)
00580 xyz (2) = coords2 (i,j,k)
00581 xyz (3) = coords3 (i,j,k)
00582
00583 call psmile_mg_prev_levels_3d_real (grid_id, lev, nlev, &
00584 loc(1,i,j,k), xyz, ifound, newijk)
00585
00586 if (ifound .gt. 0) then
00587 loc (:, i,j,k) = newijk (:)
00588
00589 found (i,j,k) = lev
00590 #ifdef DEBUG
00591 nfnd (4) = nfnd (4) + 1
00592 #endif /* DEBUG */
00593 else
00594 found (i,j,k) = - found (i,j,k)
00595 #ifdef DEBUG
00596 nfnd (0) = nfnd (0) + 1
00597 #endif /* DEBUG */
00598 endif
00599 else
00600
00601
00602
00603
00604 found (i,j,k) = - found (i,j,k)
00605 #ifdef DEBUG
00606 nfnd (0) = nfnd (0) + 1
00607 #endif /* DEBUG */
00608
00609 endif
00610
00611
00612
00613 nprev = nprev - 1
00614 if (nprev == 0) go to 20
00615
00616
00617
00618 if (i == control(2,1)) exit
00619
00620 ibegl = min (control(2,1), i+ijkinc(1))
00621 end do
00622
00623 20 end do
00624 end do
00625
00626
00627
00628 #ifdef DEBUG
00629 print 9970, trim(ch_id), lev, nfnd, ijkinc
00630 9970 format (1x, a, ': PSMILe_mg_next_level_3d_real: lev =', i3, &
00631 ': fnd =', 5i5, ', ijkinc ', 3i4)
00632 #endif /* DEBUG */
00633
00634 #ifdef VERBOSE
00635 print 9980, trim(ch_id), lev
00636
00637 call psmile_flushstd
00638 #endif /* VERBOSE */
00639
00640
00641
00642 9990 format (1x, a, ': PSMILe_mg_next_level_3d_real: level', i3, &
00643 ', control', 6i6)
00644 9980 format (1x, a, ': PSMILe_mg_next_level_3d_real: eof, level', i3)
00645
00646 end subroutine PSMILe_mg_next_level_3d_real