00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 subroutine psmile_mg_srch_nneigh_irr_real (grid_id, &
00011 arrays, search_mode, nref_3d, &
00012 sin_values, cos_values, grid_valid_shape, &
00013 z_coords, coords_shape, &
00014 neighbors_3d, nloc, num_neigh, &
00015 sin_search, cos_search, z_search, &
00016 dist_real, dim1, indices, jbeg, jend, &
00017 mask_ind, &
00018 mask_array, mask_shape, mask_available, &
00019 tol, ierror)
00020
00021
00022
00023 use PRISM_constants
00024
00025 use PSMILe, dummy_interface => PSMILe_MG_srch_nneigh_irr_real
00026
00027 implicit none
00028
00029
00030
00031 Integer, Intent (In) :: grid_id
00032
00033
00034
00035
00036 Type (Extra_search_real) :: arrays
00037
00038
00039
00040 Integer, Intent (In) :: nref_3d
00041
00042
00043
00044 Integer, Intent (In) :: search_mode
00045
00046
00047
00048
00049
00050
00051 Integer, Intent (In) :: grid_valid_shape (2, ndim_3d)
00052
00053
00054
00055 Real, Intent (In) ::
00056 sin_values (grid_valid_shape(1,1):grid_valid_shape(2,1),
00057 grid_valid_shape(1,2):grid_valid_shape(2,2), 2)
00058
00059
00060
00061 Real, Intent (In) ::
00062 cos_values (grid_valid_shape(1,1):grid_valid_shape(2,1),
00063 grid_valid_shape(1,2):grid_valid_shape(2,2), 2)
00064
00065
00066
00067 Integer, Intent (In) :: coords_shape (2, ndim_3d)
00068
00069
00070
00071 Real, Intent (In) :: z_coords(coords_shape(1,3):
00072 coords_shape(2,3))
00073
00074 Integer, Intent (In) :: nloc
00075
00076
00077
00078
00079 Integer, Intent (In) :: num_neigh
00080
00081
00082
00083
00084
00085 Integer, Intent (In) :: jbeg, jend
00086
00087
00088
00089 Integer, Parameter :: lat = 2
00090 Real, Intent (In) :: sin_search (jbeg:jend, lat)
00091
00092
00093
00094
00095 Real, Intent (In) :: cos_search (jbeg:jend, lat)
00096
00097
00098
00099
00100 Real, Intent (In) :: z_search (jbeg:jend)
00101
00102
00103
00104
00105 Integer, Intent (In) :: dim1 (2)
00106
00107
00108
00109
00110
00111
00112
00113
00114 Integer, Intent (In) :: indices (:)
00115
00116
00117
00118
00119 Integer, Intent (In) :: mask_shape (2, ndim_3d)
00120
00121
00122
00123 Logical, Intent (In) ::
00124 mask_array (mask_shape (1,1):mask_shape (2,1),
00125 mask_shape (1,2):mask_shape (2,2),
00126 mask_shape (1,3):mask_shape (2,3))
00127
00128
00129
00130 Logical, Intent (In) :: mask_available
00131
00132
00133
00134
00135
00136 Logical, Intent (In) :: mask_ind(jbeg:jend)
00137
00138
00139
00140 Real, Intent (In) :: tol
00141
00142
00143
00144
00145
00146 Real, Intent (InOut) :: dist_real (dim1(1):dim1(2), num_neigh)
00147
00148
00149
00150 Integer, Intent (Out) :: neighbors_3d (ndim_3d, nloc, num_neigh)
00151
00152
00153
00154
00155
00156
00157 Integer, Intent (Out) :: ierror
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 Real, Parameter :: real_earth = 6400000.0
00168
00169 Real, Parameter :: acosp1 = 1.0
00170 Real, Parameter :: acosm1 = -1.0
00171
00172 Integer, Parameter :: lon = 1
00173
00174
00175
00176 Real :: dist, dist1, distmax, val, fac, fac2
00177
00178 Real :: sin_corner_lat(4,8)
00179 Real :: cos_corner_lat(4,8)
00180 Real :: sin_corner_lon(4,8)
00181 Real :: cos_corner_lon(4,8)
00182
00183 Real :: sin_midp_lat(8)
00184 Real :: cos_midp_lat(8)
00185 Real :: sin_midp_lon(8)
00186 Real :: cos_midp_lon(8)
00187
00188 Real :: distc (4)
00189
00190 Real, Allocatable :: distrad_c(:), radius_c(:)
00191 Real, Allocatable :: distrad_f(:,:), radius_f(:,:)
00192
00193 Logical, Allocatable :: maskrad_c(:)
00194 Logical, Allocatable :: maskrad_f(:,:)
00195
00196 Integer, Allocatable :: ijk0 (:,:)
00197 Integer :: ijk (2,ndim_3d)
00198 Integer :: ii, jj, kk, nn
00199 Integer, Allocatable :: next(:,:)
00200 Integer :: i, j, k, n
00201 Integer :: ifix, jfix, kfix
00202 Integer :: ncount
00203 Integer :: iloc(1)
00204
00205 Type (Grid), Pointer :: grid_info
00206 Type (Enddef_mg_real), Pointer :: my_arrays
00207
00208
00209
00210 Integer :: level, nlev
00211 Integer, Allocatable :: boxsize (:, :)
00212
00213
00214
00215 Integer :: len, leni, lenij, lenijk, lenj, lenk
00216 Integer :: leni_level, lenij_level
00217 Integer :: len_alloc
00218
00219
00220
00221
00222
00223
00224 Integer :: ind, jind
00225
00226
00227
00228 Integer, parameter :: nerrp = 1
00229 Integer :: ierrp (nerrp)
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 #ifdef VERBOSE
00249 print 9990, trim(ch_id)
00250
00251 call psmile_flushstd
00252 #endif /* VERBOSE */
00253
00254
00255
00256
00257
00258 ierror = 0
00259
00260 grid_info => Grids(grid_id)
00261
00262 nlev = grid_info%nlev - 3
00263
00264 leni = grid_info%mg_infos(nlev)%levdim(1)+1
00265 lenj = grid_info%mg_infos(nlev)%levdim(2)+1
00266 lenk = grid_info%mg_infos(nlev)%levdim(3)+1
00267
00268 lenij = leni*lenj
00269 if ( search_mode == 3 ) then
00270 lenijk = lenij*lenk
00271 else
00272 lenijk = lenij
00273 endif
00274
00275
00276
00277
00278
00279 allocate (maskrad_c(lenijk), stat = ierror)
00280 if (ierror /= 0) then
00281 ierrp (1) = lenijk
00282 ierror = PRISM_Error_Alloc
00283 call psmile_error ( ierror, 'maskrad_f', ierrp, 1, &
00284 __FILE__, __LINE__ )
00285 return
00286 endif
00287
00288 allocate (distrad_c(lenijk), radius_c(lenijk), stat = ierror)
00289 if (ierror /= 0) then
00290 ierrp (1) = lenijk
00291 ierror = PRISM_Error_Alloc
00292 call psmile_error ( ierror, 'distrad_c, radius_c', ierrp, 1, &
00293 __FILE__, __LINE__ )
00294 return
00295 endif
00296
00297 if ( search_mode == 2 ) then
00298 len_alloc = 64
00299 else
00300 len_alloc = 64*8
00301 endif
00302
00303 allocate (maskrad_f(len_alloc,nlev), stat = ierror)
00304 if (ierror /= 0) then
00305 ierrp (1) = 2*ndim_3d*nlev
00306 ierror = PRISM_Error_Alloc
00307 call psmile_error ( ierror, 'maskrad_f', ierrp, 1, &
00308 __FILE__, __LINE__ )
00309 return
00310 endif
00311
00312 allocate (distrad_f(len_alloc,nlev), radius_f(64,nlev), stat = ierror)
00313 if (ierror /= 0) then
00314 ierrp (1) = 6*2*ndim_3d*nlev
00315 ierror = PRISM_Error_Alloc
00316 call psmile_error ( ierror, 'distrad_f, radius_f', ierrp, 1, &
00317 __FILE__, __LINE__ )
00318 return
00319 endif
00320
00321 allocate (boxsize(ndim_3d,nlev), ijk0(ndim_3d,nlev), stat = ierror)
00322 if (ierror /= 0) then
00323 ierrp (1) = 2*ndim_3d*nlev
00324 ierror = PRISM_Error_Alloc
00325 call psmile_error ( ierror, 'boxsize, ijk0', ierrp, 1, &
00326 __FILE__, __LINE__ )
00327 return
00328 endif
00329
00330 allocate (next(ndim_3d,nlev), stat = ierror)
00331 if (ierror /= 0) then
00332 ierrp (1) = ndim_3d*nlev
00333 ierror = PRISM_Error_Alloc
00334 call psmile_error ( ierror, 'next', ierrp, 1, &
00335 __FILE__, __LINE__ )
00336 return
00337 endif
00338
00339 ijk0(:,nlev) = grid_info%ijk0
00340
00341
00342
00343
00344
00345 boxsize (1:ndim_3d, 1) = 1
00346
00347 do level = 2, nlev
00348 do i = 1, ndim_3d
00349 if ( grid_info%mg_infos(level )%levdim(i) /= &
00350 grid_info%mg_infos(level-1)%levdim(i) ) then
00351 boxsize(i, level) = boxsize(i, level-1) * 2
00352 else
00353 boxsize(i, level) = boxsize(i, level-1)
00354 end if
00355 end do
00356 end do
00357
00358 do jind = jbeg, jend
00359
00360 if ( mask_ind(jind) ) then
00361
00362
00363
00364 leni = grid_info%mg_infos(nlev)%levdim(1)+1
00365 lenj = grid_info%mg_infos(nlev)%levdim(2)+1
00366 lenk = grid_info%mg_infos(nlev)%levdim(3)+1
00367
00368 lenij = leni*lenj
00369 if ( search_mode == 3 ) then
00370 lenijk = lenij*lenk
00371 else
00372 lenijk = lenij
00373 endif
00374
00375 maskrad_c = .true.
00376
00377 ind = indices (jind)
00378
00379 if ( search_mode == 2 ) then
00380
00381
00382
00383
00384 dist = huge(dist)
00385 do k = grid_valid_shape(1,3), grid_valid_shape(2,3)
00386 val = abs( z_search (jind) - z_coords(k) )
00387 if ( val < dist ) then
00388 val = dist
00389 kfix = k
00390 endif
00391 enddo
00392 endif
00393
00394 distmax = maxval (dist_real (jind, 1:num_neigh) )
00395
00396
00397
00398
00399 fac = real_earth + z_search (jind)
00400
00401
00402 do n = 1, lenijk
00403 val = ( arrays%sin_cmidp_lat%vector(n) * sin_search(jind, lat) &
00404 + arrays%cos_cmidp_lat%vector(n) * cos_search(jind, lat) &
00405 * (arrays%cos_cmidp_lon%vector(n) * cos_search(jind, lon) &
00406 + arrays%sin_cmidp_lon%vector(n) * sin_search(jind, lon)) )
00407
00408 val = min (acosp1, val)
00409 val = max (acosm1, val)
00410
00411 dist = fac * acos (val)
00412 distrad_c (n) = dist * dist
00413 enddo
00414
00415 if ( search_mode == 3 ) then
00416 my_arrays => grid_info%mg_infos(nlev)%real_arrays
00417 n = 0
00418 do k = 1, lenk
00419 distrad_c (n+1:n+lenij) = distrad_c (n+1:n+lenij) + &
00420 (my_arrays%midp(3)%vector(k)-z_search(jind))**2
00421 n = n + lenij
00422 enddo
00423 endif
00424
00425
00426
00427
00428 distrad_c (1:lenijk) = sqrt (distrad_c(1:lenijk)) - arrays%radius(1:lenijk)
00429
00430 200 continue
00431
00432
00433
00434 my_arrays => grid_info%mg_infos(nlev)%real_arrays
00435
00436 next = 0
00437
00438 leni = grid_info%mg_infos(nlev)%levdim(1)+1
00439 lenj = grid_info%mg_infos(nlev)%levdim(2)+1
00440 lenk = grid_info%mg_infos(nlev)%levdim(3)+1
00441
00442 lenij = leni*lenj
00443 if ( search_mode == 3 ) then
00444 lenijk = lenij*lenk
00445 else
00446 lenijk = lenij
00447 endif
00448
00449
00450
00451 do i = 1, lenijk
00452 maskrad_c (i) = maskrad_c(i) .and. (distrad_c(i) < distmax)
00453 enddo
00454
00455
00456
00457 if ( count(maskrad_c) < 1 ) cycle
00458
00459 ncount = 0
00460
00461 do i = 1, lenijk
00462
00463 if ( count(maskrad_c) < 1 ) exit
00464
00465 iloc(:) = minloc (distrad_c(1:lenijk), maskrad_c(1:lenijk))
00466 #ifdef MINLOCFIX
00467 if (iloc(1).eq.0) iloc(1)=1
00468 #endif /* MINLOCFIX */
00469
00470 kk = (iloc(1) - 1) / lenij + 1
00471 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
00472 ii = iloc(1) - (kk-1)*lenij - (jj-1)*leni
00473
00474 ijk(1,1) = ijk0(1,nlev) + (ii-1)*boxsize(1,nlev)
00475 ijk(1,2) = ijk0(2,nlev) + (jj-1)*boxsize(2,nlev)
00476
00477 ijk(2,1) = min (grid_valid_shape(2,1), ijk(1,1)+boxsize(1,nlev)-1)
00478 ijk(2,2) = min (grid_valid_shape(2,2), ijk(1,2)+boxsize(2,nlev)-1)
00479
00480 if ( search_mode == 2 ) then
00481 ijk(1,3) = kfix
00482 ijk(2,3) = kfix
00483 else
00484 ijk(1,3) = ijk0(3,nlev) + (kk-1)*boxsize(3,nlev)
00485 ijk(2,3) = min (grid_valid_shape(2,3), ijk(1,3)+boxsize(3,nlev)-1)
00486 endif
00487
00488 ncount = count( mask_array(ijk(1,1):ijk(2,1), &
00489 ijk(1,2):ijk(2,2), &
00490 ijk(1,3):ijk(2,3)) )
00491 if ( ncount > 0 ) exit
00492
00493 maskrad_c(iloc(1)) = .false.
00494
00495 enddo
00496
00497 if ( count(maskrad_c) < 1 ) cycle
00498
00499 maskrad_c(iloc(1)) = .false.
00500
00501 level = nlev
00502
00503 maskrad_f = .true.
00504
00505 100 continue
00506
00507
00508
00509 if ( level < nlev ) then
00510
00511
00512
00513
00514
00515
00516
00517 leni = boxsize(1,level+1)/boxsize(1,level)
00518 lenj = boxsize(2,level+1)/boxsize(2,level)
00519 lenk = boxsize(3,level+1)/boxsize(3,level)
00520
00521 lenij = leni*lenj
00522 if ( search_mode == 3 ) then
00523 lenijk = lenij*lenk
00524 else
00525 lenijk = lenij
00526 endif
00527
00528
00529
00530
00531 next(1,level) = (next(1,level+1)+ii-1) * leni
00532 next(2,level) = (next(2,level+1)+jj-1) * lenj
00533 next(3,level) = (next(3,level+1)+kk-1) * lenk
00534
00535
00536
00537 ijk0(1,level) = next(1,level)
00538 ijk0(2,level) = next(2,level)
00539 ijk0(3,level) = next(3,level)
00540
00541 do i = level-1, 1, -1
00542 ijk0(1,level) = ijk0(1,level)*boxsize(1,i+1)/boxsize(1,i)
00543 ijk0(2,level) = ijk0(2,level)*boxsize(2,i+1)/boxsize(2,i)
00544 ijk0(3,level) = ijk0(3,level)*boxsize(3,i+1)/boxsize(3,i)
00545 enddo
00546
00547 ijk0(1,level) = ijk0(1,level) + ijk0(1,nlev)
00548 ijk0(2,level) = ijk0(2,level) + ijk0(2,nlev)
00549 ijk0(3,level) = ijk0(3,level) + ijk0(3,nlev)
00550
00551
00552
00553 my_arrays => grid_info%mg_infos(level)%real_arrays
00554
00555 leni_level = grid_info%mg_infos(level)%levdim(1)+1
00556 lenij_level = leni_level * (grid_info%mg_infos(level)%levdim(2)+1)
00557
00558
00559
00560 if ( next(1,level)+leni > grid_info%mg_infos(level)%levdim(1)+1 ) &
00561 leni = grid_info%mg_infos(level)%levdim(1) + 1 - next(1,level)
00562
00563 if ( next(2,level)+lenj > grid_info%mg_infos(level)%levdim(2)+1 ) &
00564 lenj = grid_info%mg_infos(level)%levdim(2) + 1 - next(2,level)
00565
00566 if ( next(3,level)+lenk > grid_info%mg_infos(level)%levdim(3)+1 ) &
00567 lenk = grid_info%mg_infos(level)%levdim(3) + 1 - next(3,level)
00568
00569 lenij = leni*lenj
00570 if ( search_mode == 3 ) then
00571 lenijk = lenij*lenk
00572 else
00573 lenijk = lenij
00574 endif
00575
00576
00577
00578 do k = 1, lenk
00579 do j = 1, lenj
00580 do i = 1, leni
00581
00582 n = (k-1)*lenij + (j-1)*leni + i
00583
00584 nn = (next(3,level) + k-1)*lenij_level + &
00585 (next(2,level) + j-1)*leni_level + &
00586 next(1,level) + i
00587
00588 sin_corner_lon(1,n) = sin(my_arrays%chmin(lon)%vector(nn)*real_deg2rad)
00589 cos_corner_lon(1,n) = cos(my_arrays%chmin(lon)%vector(nn)*real_deg2rad)
00590 sin_corner_lat(1,n) = sin(my_arrays%chmin(lat)%vector(nn)*real_deg2rad)
00591 cos_corner_lat(1,n) = cos(my_arrays%chmin(lat)%vector(nn)*real_deg2rad)
00592
00593 sin_corner_lon(2,n) = sin(my_arrays%chmax(lon)%vector(nn)*real_deg2rad)
00594 cos_corner_lon(2,n) = cos(my_arrays%chmax(lon)%vector(nn)*real_deg2rad)
00595 sin_corner_lat(2,n) = sin(my_arrays%chmin(lat)%vector(nn)*real_deg2rad)
00596 cos_corner_lat(2,n) = cos(my_arrays%chmin(lat)%vector(nn)*real_deg2rad)
00597
00598 sin_corner_lon(3,n) = sin(my_arrays%chmax(lon)%vector(nn)*real_deg2rad)
00599 cos_corner_lon(3,n) = cos(my_arrays%chmax(lon)%vector(nn)*real_deg2rad)
00600 sin_corner_lat(3,n) = sin(my_arrays%chmax(lat)%vector(nn)*real_deg2rad)
00601 cos_corner_lat(3,n) = cos(my_arrays%chmax(lat)%vector(nn)*real_deg2rad)
00602
00603 sin_corner_lon(4,n) = sin(my_arrays%chmin(lon)%vector(nn)*real_deg2rad)
00604 cos_corner_lon(4,n) = cos(my_arrays%chmin(lon)%vector(nn)*real_deg2rad)
00605 sin_corner_lat(4,n) = sin(my_arrays%chmax(lat)%vector(nn)*real_deg2rad)
00606 cos_corner_lat(4,n) = cos(my_arrays%chmax(lat)%vector(nn)*real_deg2rad)
00607
00608 sin_midp_lon(n) = sin(my_arrays%midp(1)%vector(nn)*real_deg2rad)
00609 cos_midp_lon(n) = cos(my_arrays%midp(1)%vector(nn)*real_deg2rad)
00610 sin_midp_lat(n) = sin(my_arrays%midp(2)%vector(nn)*real_deg2rad)
00611 cos_midp_lat(n) = cos(my_arrays%midp(2)%vector(nn)*real_deg2rad)
00612
00613 enddo
00614 enddo
00615 enddo
00616
00617
00618
00619 dist1 = 0.0
00620
00621 do k = 1, lenk
00622 fac2 = real_earth + my_arrays%midp(3)%vector(k)
00623
00624 if ( search_mode == 3 ) then
00625 dist1 = max ( (my_arrays%midp (3)%vector(k) - &
00626 my_arrays%chmin(3)%vector(k))**2, &
00627 (my_arrays%midp (3)%vector(k) - &
00628 my_arrays%chmax(3)%vector(k))**2)
00629 endif
00630
00631 do n = (k-1)*lenij+1, k*lenij
00632
00633 do nn = 1, 4
00634 val = ( sin_corner_lat(nn,n) * sin_midp_lat(n) &
00635 + cos_corner_lat(nn,n) * cos_midp_lat(n) &
00636 * (cos_corner_lon(nn,n) * cos_midp_lon(n) &
00637 + sin_corner_lon(nn,n) * sin_midp_lon(n)) )
00638
00639 val = min (acosp1, val)
00640 val = max (acosm1, val)
00641
00642 dist = fac2 * acos (val)
00643
00644 distc (nn) = sqrt(dist*dist + dist1)
00645 enddo
00646
00647 radius_f(n,level) = maxval (distc)
00648 enddo
00649
00650 enddo
00651
00652
00653
00654
00655
00656 do n = 1, lenijk
00657 val = ( sin_midp_lat(n) * sin_search(jind,lat) &
00658 + cos_midp_lat(n) * cos_search(jind,lat) &
00659 * (cos_midp_lon(n) * cos_search(jind,lon) &
00660 + sin_midp_lon(n) * sin_search(jind,lon)) )
00661
00662 val = min (acosp1, val)
00663 val = max (acosm1, val)
00664
00665 dist = fac * acos (val)
00666 distrad_f(n,level) = dist * dist
00667 enddo
00668
00669 if ( search_mode == 3 ) then
00670 n = 0
00671 do k = 1, lenk
00672 distrad_f(n+1:n+lenij,level) = distrad_f (n+1:n+lenij,level) + &
00673 (my_arrays%midp(3)%vector(k)-z_search(jind))**2
00674 n = n + lenij
00675 end do
00676 endif
00677
00678 distrad_f (1:lenijk,level) = sqrt (distrad_f(1:lenijk,level))
00679
00680
00681
00682 distrad_f(1:lenijk,level) = distrad_f(1:lenijk,level) - radius_f(1:lenijk,level)
00683
00684
00685
00686 do i = 1, lenijk
00687 maskrad_f(i,level) = maskrad_f(i,level) .and. (distrad_f(i,level) <= distmax)
00688 enddo
00689
00690
00691
00692 if ( count(maskrad_f(1:lenijk,level)) < 1 ) then
00693
00694 500 continue
00695
00696
00697
00698 maskrad_f(:,level) = .true.
00699 distrad_f(:,level) = huge(dist)
00700
00701 level = level + 1
00702
00703 if ( level+1 > nlev ) go to 200
00704
00705 leni = boxsize(1,level+1)/boxsize(1,level)
00706 lenj = boxsize(2,level+1)/boxsize(2,level)
00707 lenk = boxsize(3,level+1)/boxsize(3,level)
00708
00709 lenij = leni*lenj
00710 if ( search_mode == 3 ) then
00711 lenijk = lenij*lenk
00712 else
00713 lenijk = lenij
00714 endif
00715
00716 if ( count(maskrad_f(1:lenijk,level)) < 1 ) go to 500
00717
00718 iloc(:) = minloc (distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
00719 #ifdef MINLOCFIX
00720 if (iloc(1).eq.0) iloc(1)=1
00721 #endif /* MINLOCFIX */
00722 kk = (iloc(1) - 1) / lenij + 1
00723 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
00724 ii = iloc(1) - (kk-1)*lenij - (jj-1) * leni
00725
00726 go to 100
00727
00728 else
00729
00730 iloc(:) = minloc (distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
00731 #ifdef MINLOCFIX
00732 if (iloc(1).eq.0) iloc(1)=1
00733 #endif /* MINLOCFIX */
00734 endif
00735
00736 maskrad_f(iloc(1),level) = .false.
00737
00738 endif
00739
00740 300 continue
00741
00742
00743
00744
00745
00746 if ( mask_available .and. iloc(1) > 0 ) then
00747
00748
00749
00750 do i = 1, lenijk
00751
00752 kk = (iloc(1) - 1) / lenij + 1
00753 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
00754 ii = iloc(1) - (kk-1)*lenij - (jj-1)*leni
00755
00756 ijk(1,1) = min (ijk0(1,level) + (ii-1)*boxsize(1,level), grid_valid_shape(2,1))
00757 ijk(1,2) = min (ijk0(2,level) + (jj-1)*boxsize(2,level), grid_valid_shape(2,2))
00758
00759 ijk(2,1) = min (grid_valid_shape(2,1), ijk(1,1)+boxsize(1,level)-1)
00760 ijk(2,2) = min (grid_valid_shape(2,2), ijk(1,2)+boxsize(2,level)-1)
00761
00762 if ( search_mode == 2 ) then
00763 ijk(1,3) = kfix
00764 ijk(2,3) = kfix
00765 else
00766 ijk(1,3) = min (ijk0(3,level) + (kk-1)*boxsize(3,level), grid_valid_shape(2,3))
00767 ijk(2,3) = min (grid_valid_shape(2,3), ijk(1,3)+boxsize(3,level)-1)
00768 endif
00769
00770 ncount = count( mask_array(ijk(1,1):ijk(2,1), &
00771 ijk(1,2):ijk(2,2), &
00772 ijk(1,3):ijk(2,3)) )
00773 if ( ncount > 0 ) exit
00774
00775
00776
00777 maskrad_f(iloc(1),level) = .false.
00778
00779 if ( count(maskrad_f(1:lenijk,level)) > 0 ) then
00780 iloc(:) = minloc (distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
00781 else
00782 iloc(1) = 0
00783 exit
00784 endif
00785
00786 enddo
00787
00788
00789
00790
00791
00792 if ( ncount == 1 ) then
00793
00794 do k = ijk(1,3),ijk(2,3)
00795 do j = ijk(1,2),ijk(2,2)
00796 do i = ijk(1,1),ijk(2,1)
00797 if ( mask_array(i,j,k) ) then
00798 ifix = i
00799 jfix = j
00800 kfix = k
00801 endif
00802 enddo
00803 enddo
00804 enddo
00805
00806
00807
00808 val = ( sin_values(ifix, jfix, lat) * sin_search(jind, lat) &
00809 + cos_values(ifix, jfix, lat) * cos_search(jind, lat) &
00810 * (cos_values(ifix, jfix, lon) * cos_search(jind, lon) &
00811 + sin_values(ifix, jfix, lon) * sin_search(jind, lon)) )
00812
00813 val = min (acosp1, val)
00814 val = max (acosm1, val)
00815
00816 dist = fac * acos (val)
00817
00818 if ( search_mode == 2 ) then
00819 dist = dist*dist
00820 else
00821 dist = dist*dist + ( z_search (jind)-z_coords(k) )**2
00822 endif
00823
00824
00825
00826
00827
00828 if ( sqrt ( dist ) < distmax ) then
00829
00830 neighbors_3d (1, ind, 1) = ifix
00831 neighbors_3d (2, ind, 1) = jfix
00832 neighbors_3d (3, ind, 1) = kfix
00833
00834 distmax = sqrt ( dist )
00835 dist_real(jind,1) = distmax
00836
00837 endif
00838
00839 maskrad_f(iloc(1),level) = .false.
00840
00841
00842
00843 700 continue
00844
00845 maskrad_f(:,level) = .true.
00846 distrad_f(:,level) = huge(dist)
00847
00848 level = level + 1
00849
00850 if ( level+1 > nlev ) go to 200
00851
00852 leni = boxsize(1,level+1)/boxsize(1,level)
00853 lenj = boxsize(2,level+1)/boxsize(2,level)
00854 lenk = boxsize(3,level+1)/boxsize(3,level)
00855
00856 lenij = leni*lenj
00857 if ( search_mode == 3 ) then
00858 lenijk = lenij*lenk
00859 else
00860 lenijk = lenij
00861 endif
00862
00863 do i = 1, lenijk
00864 maskrad_f(i,level) = maskrad_f(i,level) .and. (distrad_f(i,level) <= distmax)
00865 enddo
00866
00867 if ( count(maskrad_f(1:lenijk,level)) < 1 ) go to 700
00868
00869 iloc(:) = minloc (distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
00870 #ifdef MINLOCFIX
00871 if (iloc(1).eq.0) iloc(1)=1
00872 #endif /* MINLOCFIX */
00873 kk = (iloc(1) - 1) / lenij + 1
00874 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
00875 ii = iloc(1) - (kk-1)*lenij - (jj-1) * leni
00876
00877 go to 300
00878
00879 endif
00880
00881 endif
00882
00883 if ( iloc(1) > 0 ) then
00884 maskrad_f(iloc(1),level) = .false.
00885 else
00886
00887 800 continue
00888
00889 maskrad_f(:,level) = .true.
00890 distrad_f(:,level) = huge(dist)
00891
00892 level = level + 1
00893
00894 if ( level+1 > nlev ) go to 200
00895
00896 leni = boxsize(1,level+1)/boxsize(1,level)
00897 lenj = boxsize(2,level+1)/boxsize(2,level)
00898 lenk = boxsize(3,level+1)/boxsize(3,level)
00899
00900 lenij = leni*lenj
00901 if ( search_mode == 3 ) then
00902 lenijk = lenij*lenk
00903 else
00904 lenijk = lenij
00905 endif
00906
00907 do i = 1, lenijk
00908 maskrad_f(i,level) = maskrad_f(i,level) .and. (distrad_f(i,level) <= distmax)
00909 enddo
00910
00911 if ( count(maskrad_f(1:lenijk,level)) < 1 ) go to 800
00912
00913 iloc(:) = minloc (distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
00914 #ifdef MINLOCFIX
00915 if (iloc(1).eq.0) iloc(1)=1
00916 #endif /* MINLOCFIX */
00917 kk = (iloc(1) - 1) / lenij + 1
00918 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
00919 ii = iloc(1) - (kk-1)*lenij - (jj-1) * leni
00920
00921 go to 300
00922
00923 endif
00924
00925 level = level - 1
00926
00927 if ( level == 3 ) go to 400
00928
00929 go to 100
00930
00931 400 continue
00932
00933
00934
00935
00936
00937
00938 if ( iloc(1) > 0 ) then
00939
00940 leni = ijk(2,1) - ijk(1,1) + 1
00941 lenj = ijk(2,2) - ijk(1,2) + 1
00942 lenk = ijk(2,3) - ijk(1,3) + 1
00943
00944 lenij = leni*lenj
00945 lenijk = lenij*lenk
00946
00947
00948
00949 do k = ijk(1,3), ijk(2,3)
00950 do j = ijk(1,2), ijk(2,2)
00951 do i = ijk(1,1), ijk(2,1)
00952
00953 n = (k-ijk(1,3))*lenij + (j-ijk(1,2))*leni + i-ijk(1,1)+1
00954
00955 val = ( sin_values(i, j, lat) * sin_search(jind, lat) &
00956 + cos_values(i, j, lat) * cos_search(jind, lat) &
00957 * (cos_values(i, j, lon) * cos_search(jind, lon) &
00958 + sin_values(i, j, lon) * sin_search(jind, lon)) )
00959
00960 val = min (acosp1, val)
00961 val = max (acosm1, val)
00962
00963 dist = fac * acos (val)
00964
00965 distrad_f(n,level) = dist*dist
00966
00967 end do
00968 end do
00969 end do
00970
00971 if ( search_mode == 3 ) then
00972 n = 0
00973 do k = 1, lenk
00974 distrad_f(n+1:n+lenij,level) = distrad_f(n+1:n+lenij,level) + &
00975 ( z_search (jind)-z_coords(k) )**2
00976 n = n + lenij
00977 end do
00978 endif
00979
00980 distrad_f (1:lenijk,level) = sqrt (distrad_f(1:lenijk,level))
00981
00982
00983
00984 if ( mask_available ) then
00985
00986 n = 0
00987 do k = ijk(1,3), ijk(2,3)
00988 do j = ijk(1,2), ijk(2,2)
00989 do i = ijk(1,1), ijk(2,1)
00990 n = n+1
00991 maskrad_f(n,level) = mask_array(i,j,k)
00992 enddo
00993 enddo
00994 enddo
00995
00996 do i = 1, lenijk
00997 maskrad_f(i,level) = maskrad_f(i,level) .and. (distrad_f(i,level) <= distmax)
00998 enddo
00999
01000 ncount = count(maskrad_f(1:lenijk,level))
01001 len = min(num_neigh,ncount)
01002
01003 else
01004
01005 do i = 1, lenijk
01006 maskrad_f(i,level) = distrad_f(i,level) <= distmax
01007 enddo
01008
01009 len = min(num_neigh, lenijk)
01010
01011 endif
01012
01013
01014
01015
01016 do n = 1, len
01017
01018 do nn = 1, lenijk
01019
01020 iloc(:) = minloc(distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
01021 #ifdef MINLOCFIX
01022 if (iloc(1).eq.0) iloc(1)=1
01023 #endif /* MINLOCFIX */
01024 kk = (iloc(1) - 1) / lenij + 1
01025 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
01026 ii = iloc(1) - (kk-1)*lenij - (jj-1) * leni
01027
01028 i = max(grid_valid_shape(1,1),ijk(1,1)+ii-1)
01029 j = max(grid_valid_shape(1,2),ijk(1,2)+jj-1)
01030
01031 if ( search_mode == 2 ) then
01032 k = kfix
01033 else
01034 k = max(grid_valid_shape(1,3),ijk(1,3)+kk-1)
01035 endif
01036
01037 neighbors_3d (1, ind, n) = i
01038 neighbors_3d (2, ind, n) = j
01039 neighbors_3d (3, ind, n) = k
01040
01041 distmax = distrad_f(iloc(1),level)
01042 dist_real (jind, n) = distmax
01043
01044 maskrad_f(iloc(1),level) = .false.
01045 exit
01046
01047 enddo
01048
01049 enddo
01050
01051
01052
01053 600 continue
01054
01055 maskrad_f(:,level) = .true.
01056 distrad_f(:,level) = huge(dist)
01057
01058 level = level + 1
01059
01060 if ( level+1 > nlev ) go to 200
01061
01062 leni = boxsize(1,level+1)/boxsize(1,level)
01063 lenj = boxsize(2,level+1)/boxsize(2,level)
01064 lenk = boxsize(3,level+1)/boxsize(3,level)
01065
01066 lenij = leni*lenj
01067 if ( search_mode == 3 ) then
01068 lenijk = lenij*lenk
01069 else
01070 lenijk = lenij
01071 endif
01072
01073 do i = 1, lenijk
01074 maskrad_f(i,level) = maskrad_f(i,level) .and. (distrad_f(i,level) <= distmax)
01075 enddo
01076
01077 if ( count(maskrad_f(1:lenijk,level)) < 1 ) go to 600
01078
01079 iloc(:) = minloc (distrad_f(1:lenijk,level), maskrad_f(1:lenijk,level))
01080 #ifdef MINLOCFIX
01081 if (iloc(1).eq.0) iloc(1)=1
01082 #endif /* MINLOCFIX */
01083 kk = (iloc(1) - 1) / lenij + 1
01084 jj = (iloc(1) - (kk-1)*lenij - 1) / leni + 1
01085 ii = iloc(1) - (kk-1)*lenij - (jj-1) * leni
01086
01087 go to 300
01088
01089 endif
01090
01091 endif
01092
01093 enddo
01094
01095
01096
01097 if (mask_available) then
01098 Deallocate (boxsize)
01099 endif
01100
01101 #ifdef VERBOSE
01102 print 9980, trim(ch_id), ierror
01103
01104 call psmile_flushstd
01105 #endif /* VERBOSE */
01106
01107
01108
01109 9990 format (1x, a, ': psmile_mg_srch_nneigh_irr_real')
01110 9980 format (1x, a, ': psmile_mg_srch_nneigh_irr_real: eof, ierror =', i3)
01111
01112 end subroutine PSMILe_MG_srch_nneigh_irr_real