00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_next_level_2d_real ( &
00012 grid_id, lev, nlev, &
00013 chmin1, chmin2, &
00014 chmax1, chmax2, &
00015 midp1, midp2, &
00016 levdim, &
00017 found, loc, range, &
00018 coords1, coords2, &
00019 shape, control, &
00020 ijkinc, ijkcoa, ierror)
00021
00022
00023
00024 use PRISM_constants
00025
00026 use PSMILe, dummy_interface => PSMILe_mg_next_level_2d_real
00027 #ifdef DEBUG_TRACE
00028 use psmile_debug_trace
00029 #endif
00030
00031 implicit none
00032
00033
00034
00035 Integer, Intent (In) :: grid_id
00036
00037
00038
00039
00040 Integer, Intent (In) :: lev
00041
00042
00043
00044 Integer, Intent (In) :: nlev
00045
00046
00047
00048 Integer, Intent (In) :: levdim (ndim_2d)
00049
00050
00051
00052 Integer, Intent (In) :: range (2, ndim_3d)
00053
00054
00055
00056 Integer, Intent (In) :: shape (2, ndim_3d)
00057
00058
00059
00060 Real, Intent (In) :: chmin1 (0:levdim(1),
00061 0:levdim(2))
00062 Real, Intent (In) :: chmin2 (0:levdim(1),
00063 0:levdim(2))
00064
00065
00066
00067 Real, Intent (In) :: chmax1 (0:levdim(1),
00068 0:levdim(2))
00069 Real, Intent (In) :: chmax2 (0:levdim(1),
00070 0:levdim(2))
00071
00072
00073
00074 Real, Intent (In) :: midp1 (0:levdim(1),
00075 0:levdim(2))
00076 Real, Intent (In) :: midp2 (0:levdim(1),
00077 0:levdim(2))
00078
00079
00080
00081 Real, Intent (In) :: coords1 (shape(1,1):shape(2,1),
00082 shape(1,2):shape(2,2),
00083 shape(1,3):shape(2,3))
00084 Real, Intent (In) :: coords2 (shape(1,1):shape(2,1),
00085 shape(1,2):shape(2,2),
00086 shape(1,3):shape(2,3))
00087
00088
00089
00090 Integer, Intent (In) :: ijkinc (ndim_3d)
00091
00092
00093
00094 Integer, Intent (In) :: ijkcoa (ndim_2d)
00095
00096
00097
00098
00099
00100 Integer, Intent (InOut) :: found (range(1,1):range(2,1),
00101 range(1,2):range(2,2),
00102 range(1,3):range(2,3))
00103
00104
00105
00106
00107
00108
00109 Integer, Intent (InOut) :: loc (ndim_2d,
00110 range(1,1):range(2,1),
00111 range(1,2):range(2,2),
00112 range(1,3):range(2,3))
00113
00114
00115
00116 Integer, Intent (InOut) :: control (2, ndim_3d)
00117
00118
00119
00120
00121
00122
00123 integer, Intent (Out) :: ierror
00124
00125
00126
00127
00128
00129
00130
00131 Integer, parameter :: ndtry = 16
00132 Integer, parameter :: ntry1 = 4
00133 Integer, parameter :: ntry3 = 9
00134 Integer, parameter :: ntry2 = ndtry - ntry1
00135
00136 Integer, Parameter :: temp_len = 256
00137
00138 Real, parameter :: remax = 1.0e20
00139
00140
00141
00142
00143
00144 Integer :: levc
00145
00146
00147
00148 Integer :: i, j, k
00149 Integer :: ibegl, ibeglx, iendl, n, nprev
00150 Integer :: nmin (temp_len, 1)
00151 Integer :: ijkf(temp_len, ndim_2d)
00152 Integer :: ijkold(temp_len, ndim_2d)
00153 Integer :: newijk(ndim_2d, temp_len)
00154 Integer :: ijkctl (ndim_2d, ndtry)
00155 Integer :: ijkdst (temp_len, ndim_2d, ndtry)
00156 Integer :: ijkctl3 (ndim_2d, ndtry)
00157 Real :: dist (temp_len, ndtry)
00158 Real :: xyz (ndim_2d, temp_len)
00159
00160
00161
00162 Integer :: ii, nc, np, nc_part
00163 Integer :: list (temp_len*2)
00164 Integer :: part_list (temp_len)
00165 Integer :: loc2 (ndim_2d, temp_len)
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 Character(len=len_cvs_string), save :: mycvs =
00191 '$Id: psmile_mg_next_level_2d_real.F90 2927 2011-01-28 14:04:12Z hanke $'
00192
00193
00194
00195
00196
00197 data ((ijkctl (i, n), i=1,ndim_2d), n = 1,ntry1) &
00198 / 0, 0, 1, 0, &
00199 0, 1, 1, 1/
00200
00201
00202
00203 data ((ijkctl (i, n), i=1,ndim_2d), n = ntry1+1, ntry1+12) &
00204 /-1,-1, 0,-1, 1,-1, 2,-1, &
00205 -1, 0, 2, 0, &
00206 -1, 1, 2, 1, &
00207 -1, 2, 0, 2, 1, 2, 2, 2/
00208
00209
00210
00211 data ((ijkctl3 (i, n), i=1,ndim_2d), n = 1,ntry3) &
00212 / -1,-1, 0,-1, 1,-1, &
00213 -1, 0, 0, 0, 1, 0, &
00214 -1, 1, 0, 1, 1, 1/
00215
00216
00217
00218
00219
00220 #ifdef VERBOSE
00221 print 9990, trim(ch_id), lev, control
00222
00223 call psmile_flushstd
00224 #endif /* VERBOSE */
00225
00226 #ifdef PRISM_ASSERTION
00227 #endif
00228
00229 ierror = 0
00230 levc = lev + 1
00231
00232 iendl = control(2,1) + ijkinc(1)
00233
00234 #ifdef DEBUG
00235 nfnd (:) = 0
00236 #endif /* DEBUG */
00237
00238 do k = control(1,3), control (2,3), ijkinc (3)
00239 loop_j: do j = control(1,2), control (2,2), ijkinc (2)
00240
00241
00242
00243
00244
00245
00246
00247 nprev = 0
00248
00249 ibegl = control (1, 1)
00250
00251
00252
00253
00254 loop_i: do while (ibegl < iendl)
00255
00256 nc = 0
00257 i = ibegl
00258
00259 do while (nc < temp_len .and. i < iendl)
00260 ibegl = i
00261
00262 do i = ibegl, min (ibegl+((temp_len*2-1)-nc)*ijkinc(1), &
00263 control(2,1)), ijkinc(1)
00264 if (found(i, j, k) == levc) then
00265 nc = nc + 1
00266 list (nc) = i
00267 endif
00268 end do
00269
00270 if (nc < temp_len .and. &
00271 i > control(2,1) .and. i < iendl) then
00272 i = control(2,1)
00273 if (found (i,j,k) == levc) then
00274 nc = nc + 1
00275 list (nc) = i
00276
00277 exit
00278 endif
00279 endif
00280 end do
00281
00282 if (nc == 0) exit loop_i
00283
00284 if (nc < temp_len) then
00285 ibegl = iendl
00286 else if (nc > temp_len) then
00287 nc = temp_len
00288 ibegl = list (temp_len+1)
00289 else
00290 ibegl = list (temp_len) + ijkinc(1)
00291 endif
00292
00293
00294
00295 ijkf(1:nc, 1) = min (loc(1,list(1:nc),j,k) * ijkcoa(1), levdim(1))
00296 ijkf(1:nc, 2) = min (loc(2,list(1:nc),j,k) * ijkcoa(2), levdim(2))
00297
00298 do n = 1, ntry1
00299 do ii = 1, ndim_2d
00300 ijkdst (1:nc, ii, n) = max (min(ijkf(1:nc, ii)+ijkctl(ii,n), &
00301 levdim(ii)), 0)
00302 end do
00303 end do
00304
00305
00306 do n = 1, ntry1
00307 do i = 1, nc
00308 if (coords1(list(i),j,k) >= chmin1(ijkdst(i,1,n), &
00309 ijkdst(i,2,n)) .and. &
00310 coords2(list(i),j,k) >= chmin2(ijkdst(i,1,n), &
00311 ijkdst(i,2,n)) .and. &
00312 coords1(list(i),j,k) <= chmax1(ijkdst(i,1,n), &
00313 ijkdst(i,2,n)) .and. &
00314 coords2(list(i),j,k) <= chmax2(ijkdst(i,1,n), &
00315 ijkdst(i,2,n))) then
00316 dist (i, n) = (coords1(list(i),j,k) - &
00317 midp1(ijkdst(i,1,n), ijkdst(i,2,n)))**2 &
00318 + (coords2(list(i),j,k) - &
00319 midp2(ijkdst(i,1,n), ijkdst(i,2,n)))**2
00320
00321 else
00322
00323 dist (i, n) = remax
00324
00325 endif
00326 end do
00327 end do
00328
00329
00330
00331 #if 0
00332 do i = 1, nc
00333 nmin (i, :) = MINLOC (dist(i, 1:ntry1))
00334 end do
00335 #ifdef MINLOCFIX
00336 do i = 1, nc
00337 if (nmin(i, 1).eq.0) nmin (i, 1) = 1
00338 end do
00339 #endif /* MINLOCFIX */
00340 #else
00341 nmin (1:nc, 1) = 1
00342
00343 do n = 2, ntry1
00344
00345 do i = 1, nc
00346 if (dist(i, n) < dist(i, nmin(i,1))) then
00347 nmin (i,1) = n
00348 endif
00349 end do
00350 end do
00351 #endif
00352
00353
00354
00355 nc_part = 0
00356
00357 do i = 1, nc
00358 if (dist(i, nmin(i, 1)) /= remax) then
00359 nc_part = nc_part + 1
00360 part_list (nc_part) = i
00361 endif
00362 end do
00363
00364 if (nc_part > 0) then
00365
00366 do np = 1, nc_part
00367 i = part_list (np)
00368
00369 found (list(i),j,k) = lev
00370 loc (:, list(i),j,k) = ijkdst (i, :, nmin(i, 1))
00371 end do
00372
00373 #ifdef DEBUG
00374 nfnd (1) = nfnd (1) + nc_part
00375 #endif /* DEBUG */
00376
00377 if (nc == nc_part) cycle loop_i
00378
00379
00380
00381 nc_part = 0
00382
00383 do i = 1, nc
00384 if (dist(i, nmin(i, 1)) == remax) then
00385 nc_part = nc_part + 1
00386 part_list (nc_part) = i
00387 endif
00388 end do
00389
00390
00391
00392 nc = nc_part
00393
00394 do i = 1, nc
00395
00396 list (i) = list (part_list (i))
00397
00398 ijkf (i,1) = ijkf (part_list(i), 1)
00399 ijkf (i,2) = ijkf (part_list(i), 2)
00400 enddo
00401
00402 endif
00403
00404
00405
00406 if (levc == lev) then
00407
00408 do i = 1, nc
00409 found (list(i),j,k) = - found(list(i),j,k)
00410 end do
00411 #ifdef DEBUG
00412 nfnd (0) = nfnd (0) + nc
00413 #endif /* DEBUG */
00414
00415 cycle loop_i
00416 endif
00417
00418
00419
00420
00421
00422
00423 do n = ntry1+1, ndtry
00424
00425 do ii = 1, ndim_2d
00426 ijkdst (1:nc, ii, n) = max(0, min(ijkf(1:nc, ii)+ijkctl(ii,n), &
00427 levdim(ii)))
00428 end do
00429
00430 do i = 1, nc
00431 if (coords1(list(i),j,k) >= chmin1(ijkdst(i, 1,n), &
00432 ijkdst(i, 2,n)) .and. &
00433 coords2(list(i),j,k) >= chmin2(ijkdst(i, 1,n), &
00434 ijkdst(i, 2,n)) .and. &
00435 coords1(list(i),j,k) <= chmax1(ijkdst(i, 1,n), &
00436 ijkdst(i, 2,n)) .and. &
00437 coords2(list(i),j,k) <= chmax2(ijkdst(i, 1,n), &
00438 ijkdst(i, 2,n))) then
00439
00440 dist (i, n) = (coords1(list(i),j,k) - &
00441 midp1(ijkdst(i, 1,n), ijkdst(i, 2,n)))**2 &
00442 + (coords2(list(i),j,k) - &
00443 midp2(ijkdst(i, 1,n), ijkdst(i, 2,n)))**2
00444
00445 else
00446
00447 dist (i, n) = remax
00448
00449 endif
00450 end do
00451 end do
00452
00453
00454
00455 #if 0
00456 do i = 1, nc
00457 nmin(i,:) = MINLOC (dist(i, ntry1+1:ndtry))
00458 end do
00459
00460 #ifdef MINLOCFIX
00461 do i = 1, nc
00462 if (nmin(i, 1).eq.0) nmin (i, 1) = 1
00463 end do
00464
00465 #endif /* MINLOCFIX */
00466 #else
00467 nmin (1:nc, 1) = ntry1+1
00468
00469 do n = ntry1+2, ndtry
00470
00471 do i = 1, nc
00472 if (dist(i, n) < dist(i, nmin(i,1))) then
00473 nmin (i,1) = n
00474 endif
00475 end do
00476 end do
00477 #endif
00478
00479
00480
00481 nc_part = 0
00482
00483 do i = 1, nc
00484 if (dist(i, nmin(i, 1)) /= remax) then
00485 found (list(i),j,k) = lev
00486 loc (:, list(i),j,k) = ijkdst (i, :, nmin(i, 1))
00487
00488 nc_part = nc_part + 1
00489 endif
00490 end do
00491
00492 #ifdef DEBUG
00493 nfnd (2) = nfnd (2) + nc_part
00494 #endif /* DEBUG */
00495
00496 nprev = nprev + (nc - nc_part)
00497
00498 end do loop_i
00499
00500
00501
00502 if (nprev == 0) cycle loop_j
00503
00504
00505
00506
00507
00508
00509 ibeglx = control (1, 1) + ijkinc(1)
00510
00511
00512
00513
00514 loop_2: do while (ibeglx < iendl)
00515
00516 nc = 0
00517 i = ibeglx
00518
00519 do while (nc < temp_len .and. i < control(2,1))
00520 ibeglx = i
00521
00522 do i = ibeglx, &
00523 min (ibeglx+((temp_len*2-1)-nc)*ijkinc(1), &
00524 control(2,1)-ijkinc(1)), ijkinc(1)
00525 if (found (i, j, k) == levc .and. &
00526 found (i-ijkinc(1),j,k) == lev .and. &
00527 found (i+ijkinc(1),j,k) == lev) then
00528 nc = nc + 1
00529 list (nc) = i
00530 endif
00531 end do
00532
00533 if (nc < temp_len .and. &
00534 i > control(2,1)-ijkinc(1) .and. i < control(2,1)) then
00535 i = control(2,1) - ijkinc(1)
00536 if (found (i, j, k) == levc .and. &
00537 found (i-ijkinc(1),j,k) == lev .and. &
00538 found (i+ijkinc(1),j,k) == lev) then
00539 nc = nc + 1
00540 list (nc) = i
00541
00542 exit
00543 endif
00544 endif
00545 end do
00546
00547 if (nc == 0) exit loop_2
00548
00549 if (nc < temp_len) then
00550 ibeglx = control(2,1) + ijkinc (1)
00551 else if (nc > temp_len) then
00552 nc = temp_len
00553 ibeglx = list (temp_len+1)
00554 else
00555 ibeglx = list (temp_len) + ijkinc(1)
00556 endif
00557
00558 do ii = 1, ndim_2d
00559 ijkf (1:nc, ii) = min ((loc (ii, list(1:nc)-ijkinc(1),j,k) + &
00560 loc (ii, list(1:nc)+ijkinc(1),j,k))/2, &
00561 levdim(ii))
00562
00563 ijkold (1:nc, ii) = min (loc(ii, list(1:nc),j,k) * ijkcoa(ii), &
00564 levdim(ii))
00565 end do
00566
00567
00568
00569
00570 #ifdef HUHU
00571 do i = 1, nc
00572
00573
00574 if (ijkold(i, 1) == ijkf(i, 1) .and. &
00575 ijkold(i, 2) == ijkf(i, 2)) cycle
00576
00577 end do
00578 #endif
00579
00580 do n = 1, ntry3
00581
00582 do ii = 1, ndim_2d
00583 ijkdst (1:nc, ii, n) = max(0, min(ijkf(1:nc, ii) + ijkctl3(ii,n), &
00584 levdim(ii)))
00585 end do
00586
00587
00588
00589
00590 do i = 1, nc
00591 if (coords1(list(i),j,k) >= chmin1(ijkdst(i,1,n), &
00592 ijkdst(i,2,n)) .and. &
00593 coords2(list(i),j,k) >= chmin2(ijkdst(i,1,n), &
00594 ijkdst(i,2,n)) .and. &
00595 coords1(list(i),j,k) <= chmax1(ijkdst(i,1,n), &
00596 ijkdst(i,2,n)) .and. &
00597 coords2(list(i),j,k) <= chmax2(ijkdst(i,1,n), &
00598 ijkdst(i,2,n))) then
00599 dist (i, n) = (coords1(list(i),j,k) - midp1(ijkdst(i,1,n), &
00600 ijkdst(i,2,n)))**2 &
00601 + (coords2(list(i),j,k) - midp2(ijkdst(i,1,n), &
00602 ijkdst(i,2,n)))**2
00603
00604 else
00605
00606 dist (i, n) = remax
00607
00608 endif
00609 end do
00610 end do
00611
00612
00613
00614 #if 0
00615 do i = 1, nc
00616 nmin (i, :) = MINLOC (dist(i, 1:ntry3))
00617 end do
00618
00619 #ifdef MINLOCFIX
00620 do i = 1, nc
00621 if (nmin(i, 1).eq.0) nmin (i, 1) = 1
00622 end do
00623 #endif /* MINLOCFIX */
00624 #else
00625 nmin (1:nc, 1) = 1
00626
00627 do n = 2, ntry3
00628
00629 do i = 1, nc
00630 if (dist(i, n) < dist(i, nmin(i,1))) then
00631 nmin (i,1) = n
00632 endif
00633 end do
00634 end do
00635 #endif
00636
00637 nc_part = 0
00638
00639 do i = 1, nc
00640 if (dist(i, nmin(i, 1)) /= remax) then
00641 found ( list(i),j,k) = lev
00642 loc (:, list(i),j,k) = ijkdst (i, :, nmin(i, 1))
00643
00644 nc_part = nc_part + 1
00645 endif
00646 end do
00647
00648 nprev = nprev - nc_part
00649 #ifdef DEBUG
00650 nfnd (3) = nfnd (3) + nc_part
00651 #endif /* DEBUG */
00652
00653 end do loop_2
00654
00655 if (nprev == 0) cycle loop_j
00656
00657
00658
00659
00660
00661
00662
00663 if (lev+1 < nlev) then
00664
00665 ibeglx = control (1, 1)
00666
00667
00668
00669
00670 loop_3: do while (ibeglx < iendl)
00671
00672 nc = 0
00673 i = ibeglx
00674
00675 do while (nc < temp_len .and. i < iendl)
00676 ibeglx = i
00677
00678 do i = ibeglx, min (ibeglx+((temp_len*2-1)-nc)*ijkinc(1), &
00679 control(2,1)), ijkinc(1)
00680 if (found(i, j, k) == levc) then
00681 nc = nc + 1
00682 list (nc) = i
00683 endif
00684 end do
00685
00686 if (nc < temp_len .and. &
00687 i > control(2,1) .and. i < iendl) then
00688 i = control(2,1)
00689 if (found (i,j,k) == levc) then
00690 nc = nc + 1
00691 list (nc) = i
00692 endif
00693 endif
00694 end do
00695
00696 if (nc == 0) exit loop_3
00697
00698 if (nc < temp_len) then
00699 ibeglx = control(2,1) + ijkinc (1)
00700 else if (nc > temp_len) then
00701 nc = temp_len
00702 ibeglx = list (temp_len+1)
00703 else
00704 ibeglx = list (temp_len) + ijkinc(1)
00705 endif
00706
00707
00708
00709
00710
00711
00712 do i = 1, nc
00713 xyz (1, i) = coords1 (list(i),j,k)
00714 xyz (2, i) = coords2 (list(i),j,k)
00715
00716 loc2 (1, i) = loc(1,list(i),j,k)
00717 loc2 (2, i) = loc(2,list(i),j,k)
00718 end do
00719
00720 call psmile_mg_prev_levels_2d_real (grid_id, lev, nlev, &
00721 loc2, xyz, part_list, &
00722 newijk, nc)
00723
00724 do i = 1, nc
00725 if (part_list(i) > 0) then
00726
00727
00728
00729 loc (:, list(i),j,k) = newijk (:, i)
00730
00731 found (list(i),j,k) = lev
00732 #ifdef DEBUG
00733 nfnd (4) = nfnd (4) + 1
00734 #endif /* DEBUG */
00735 else
00736 found (list(i),j,k) = - found (list(i),j,k)
00737
00738 #ifdef DEBUG
00739 nfnd (0) = nfnd (0) + 1
00740 #endif /* DEBUG */
00741 endif
00742 end do
00743
00744 end do loop_3
00745 else
00746
00747
00748
00749
00750
00751 do i = control (1,1), control (2,1)
00752 if (found(i, j, k) == levc) then
00753 found(i, j, k) = -levc
00754
00755 #ifdef DEBUG
00756 nfnd (0) = nfnd (0) + 1
00757 #endif /* DEBUG */
00758 endif
00759 end do
00760 endif
00761
00762 end do loop_j
00763 end do
00764
00765
00766
00767 #ifdef DEBUG_TRACE
00768 if (range(1,1) <= ictl_ind(1) .and. range(2,1) >= ictl_ind(1) .and. &
00769 range(1,2) <= ictl_ind(2) .and. range(2,2) >= ictl_ind(2)) then
00770 i = ictl_ind(1)
00771 j = ictl_ind(2)
00772 k = control(1,3)
00773
00774 if ( found (i,j,k) == lev .or. found (i,j,k) == -levc) then
00775 print 8990, ictl_ind (1:ndim_2d), &
00776 found (i,j,k), loc(:, i,j,k)
00777
00778 if (found (i,j,k) == lev) then
00779 print *, 'chmin ', &
00780 chmin1 (loc(1,i,j,k), loc(2,i,j,k)), &
00781 chmin2 (loc(1,i,j,k), loc(2,i,j,k))
00782 print *, 'coords', coords1 (i,j,k), coords2 (i,j,k)
00783 print *, 'chmax ', &
00784 chmax1 (loc(1,i,j,k), loc(2,i,j,k)), &
00785 chmax2 (loc(1,i,j,k), loc(2,i,j,k))
00786 endif
00787
00788 8990 format (1x, '### mg_next ictl_ind', 2i5, '; found ', i3, &
00789 :, 1x, ', loc', 2i6)
00790 endif
00791 endif
00792 #endif
00793
00794 #ifdef DEBUG
00795 print 9970, trim(ch_id), lev, nfnd, ijkinc
00796 9970 format (1x, a, ': PSMILe_mg_next_level_2d_real: lev =', i3, &
00797 ': not fnd', i5, ', fnd =', i6, 3i5, ', ijkinc ', 3i4)
00798 #endif /* DEBUG */
00799
00800 #ifdef VERBOSE
00801 print 9980, trim(ch_id), lev
00802
00803 call psmile_flushstd
00804 #endif /* VERBOSE */
00805
00806
00807
00808 9990 format (1x, a, ': PSMILe_mg_next_level_2d_real: level', i3, &
00809 ', control', 6i6)
00810 9980 format (1x, a, ': PSMILe_mg_next_level_2d_real: eof, level', i3)
00811
00812 end subroutine PSMILe_mg_next_level_2d_real