00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 subroutine psmile_trili_gauss2_extra (search, grid_id, mask_array, &
00013 mask_shape, mask_available, ibuf, len_item, &
00014 n_send, num_neigh, ierror)
00015
00016
00017
00018 use PRISM
00019 use PSMILe, dummy_interface => psmile_trili_gauss2_extra
00020 use psmile_grid_reduced_gauss
00021
00022 Implicit none
00023
00024
00025
00026 Integer, Intent (In) :: grid_id
00027
00028 Integer, Intent (In) :: mask_shape (2, ndim_3d)
00029
00030
00031
00032 Logical, Intent (In) ::
00033 mask_array ( mask_shape (1,1):mask_shape (2,1),
00034 mask_shape (1,2):mask_shape (2,2),
00035 mask_shape (1,3):mask_shape (2,3) )
00036
00037
00038 Logical, Intent (In) :: mask_available
00039
00040
00041
00042
00043
00044 Integer, Intent (In) :: len_item
00045
00046
00047
00048
00049
00050
00051 Integer, Intent (In) :: n_send
00052
00053
00054
00055 Integer, Intent (In) :: num_neigh
00056
00057
00058
00059
00060
00061 Type (Enddef_global_search), Intent (InOut) :: search
00062
00063
00064
00065 Integer, Intent (InOut) :: ibuf (len_item, n_send)
00066
00067
00068
00069
00070
00071
00072 Integer, Intent (Out) :: ierror
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 Integer, Parameter :: n_corners_3d = 2 * 2 * 2
00085
00086 Integer, Parameter :: masked_out = 0
00087
00088
00089
00090
00091
00092 Integer :: j, n, i, k
00093
00094
00095
00096 Type (Grid), Pointer :: grid_info
00097 Integer, Pointer :: grid_valid_shape (:, :)
00098
00099
00100
00101 Logical :: virtual_cell_available
00102
00103
00104
00105 Integer :: code, n_corners, outside
00106
00107 Integer, Allocatable :: locs (:, :)
00108 Integer, Allocatable :: neighbours_3d_extra (:, :, :)
00109 Integer, Allocatable :: hash (:)
00110
00111
00112
00113 Logical :: missing_points(num_neigh, n_send)
00114 Integer :: decode_mask(num_neigh)
00115 Integer :: num_missing_points
00116
00117 integer, parameter :: shift_3d(ndim_3d, 9) =
00118 reshape ((/-1,-1,0, 0,-1,0, +1,-1,0,
00119 -1, 0,0, 0, 0,0, +1, 0,0,
00120 -1,+1,0, 0,+1,0, +1,+1,0/),
00121 (/ndim_3d,9/))
00122
00123
00124
00125 Integer, parameter :: nerrp = 1
00126 Integer :: ierrp (nerrp)
00127
00128 #ifdef DEBUG_TRACE
00129 Integer :: ictl_req, ind_loc (n_corners_3d)
00130 #endif
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 Character(len=len_cvs_string), save :: mycvs =
00152 '$Id: psmile_trili_gauss2_extra.F90 3023 2011-03-17 10:21:20Z hanke $'
00153
00154
00155
00156
00157
00158 #ifdef VERBOSE
00159 print 9990, trim(ch_id), grids(grid_id)%comp_id
00160
00161 call psmile_flushstd
00162 #endif /* VERBOSE */
00163
00164 ierror = 0
00165 n_corners = num_neigh
00166
00167
00168
00169
00170
00171
00172
00173 grid_info => Grids(grid_id)
00174
00175 grid_valid_shape => grid_info%grid_shape
00176
00177 virtual_cell_available = len_item > ndim_3d + 2
00178
00179 if (grid_info%grid_type /= PRISM_Gaussreduced_Regvrt) then
00180 print *, "grid_type", grid_info%grid_type
00181 call psmile_assert (__FILE__, __LINE__, &
00182 "This routine is not designed for this grid type")
00183 endif
00184
00185 outside = grid_valid_shape (1, 1) - 11
00186
00187 #ifdef PRISM_ASSERTION
00188
00189 if (num_neigh < 1 .or. num_neigh > n_corners_3d) then
00190 print *, 'num_neigh', num_neigh, n_corners_3d
00191 call psmile_assert ( __FILE__, __LINE__, &
00192 'Invalid value for num_neigh (number of interpolation bases')
00193 endif
00194
00195
00196
00197
00198 do n = 1, n_send
00199 if (ibuf (2, n) < 1 .or. ibuf (2, n) > grid_info%nbr_latitudes) exit
00200 end do
00201
00202 if (n <= n_send) then
00203 print *, "i,j,k, gnbr_lats", ibuf(1:3,n), grid_info%nbr_latitudes
00204 call psmile_assert (__FILE__, __LINE__, &
00205 "second (virtual) index out of range")
00206 endif
00207
00208
00209 do n = 1, n_send
00210 if (ibuf (1, n) < 1 .or. &
00211 ibuf (1, n) > grid_info%nbr_points_per_lat(ibuf(2,n))) exit
00212 end do
00213
00214 if (n <= n_send) then
00215 print *, "i,j,k, points_per_lat", &
00216 ibuf(1:3,n), grid_info%nbr_points_per_lat(ibuf(2,n))
00217 call psmile_assert (__FILE__, __LINE__, &
00218 "first (virtual) index out of range")
00219 endif
00220 #endif
00221
00222 #ifdef DEBUG_TRACE
00223
00224 do ictl_req = 1, n_send
00225 if (ibuf (4, ictl_req) == 1) exit
00226 end do
00227 #endif
00228
00229
00230
00231
00232 allocate (neighbours_3d_extra (ndim_3d, n_send, 4), stat=ierror)
00233 if (ierror /= 0) then
00234 call psmile_error ( PRISM_Error_Alloc, 'locs', (/ndim_3d * n_send * 4/), 1, &
00235 __FILE__, __LINE__ )
00236 return
00237 endif
00238
00239 if (virtual_cell_available) then
00240
00241 do n = 1, n_send
00242
00243 if (ibuf(6, n) == 0) then
00244
00245 neighbours_3d_extra(:,n,1:4) = &
00246 psmile_gauss_get_bili_stencil (grid_id, ibuf(1:3,n))
00247
00248 else
00249
00250 neighbours_3d_extra(:,n,1:4) = &
00251 psmile_gauss_shift_bili_stencil (grid_id, ibuf(1:3,n), shift_3d(:,ibuf(6, n)))
00252
00253 endif
00254 enddo
00255 else
00256 neighbours_3d_extra(:,n,1:4) = psmile_gauss_get_bili_stencil (grid_id, ibuf(1:3,n))
00257 endif
00258
00259
00260
00261 do i = 1, num_neigh
00262 decode_mask(i) = ishft (1, i - 1)
00263 enddo
00264
00265 do n = 1, n_send
00266 missing_points(:, n) = iand (decode_mask(:), ibuf(5, n)) /= 0
00267 enddo
00268
00269
00270
00271 num_missing_points = count (missing_points)
00272 #ifdef PRISM_ASSERTION
00273 if (num_missing_points <= 0) then
00274 call psmile_assert ( __FILE__, __LINE__, &
00275 'Number of points to be searched == 0 ?!?')
00276 endif
00277 #endif
00278
00279 #ifdef DEBUGX
00280 print *, 'code for locations to be searched (n_send =', num_missing_points, ')'
00281 do n = 1, n_send
00282 print *, n, 'srcloc =', ibuf(1:3,n), 'code =', ibuf (5, n)
00283 print *, ' decoded =', missing_points(:,n)
00284 end do
00285 #endif
00286
00287 #ifdef DEBUG_TRACE
00288 if (ictl_req <= n_send) then
00289 print *, 'code for indices_req', ibuf (4, ictl_req)
00290 print *, 'ictl_req', ictl_req, 'srcloc', ibuf(1:3,ictl_req), &
00291 'code', ibuf (5, ictl_req), missing_points(:, ictl_req)
00292 endif
00293 #endif
00294
00295
00296
00297 Allocate (locs (ndim_3d, num_missing_points), stat = ierror)
00298 if (ierror /= 0) then
00299 call psmile_error ( PRISM_Error_Alloc, 'locs', (/ndim_3d * num_missing_points/), 1, &
00300 __FILE__, __LINE__ )
00301 return
00302 endif
00303
00304 k = 0
00305
00306 do i = 1, n_corners
00307
00308 do n = 1, n_send
00309 if (missing_points (i,n)) then
00310
00311 k = k + 1
00312
00313 locs (:, k) = neighbours_3d_extra(:, n, iand (i-1, 3)+1)
00314
00315 if (grid_valid_shape(2,3) - grid_valid_shape(1,3) >= ishft(n_corners, -2) - 1 .and. &
00316 n_corners > 4) then
00317 locs (3, k) = locs (3, k) + ishft (i-1, -2)
00318 endif
00319 end if
00320 end do
00321 end do
00322
00323 #ifdef PRISM_ASSERTION
00324 if (k /= num_missing_points) then
00325 print *, 'k, num_missing_points', k, num_missing_points
00326 call psmile_assert ( __FILE__, __LINE__, &
00327 'Inconsistent values of k and num_missing_points; must be same value')
00328 endif
00329 #endif
00330
00331 #ifdef DEBUG_TRACE
00332 if (ictl_req <= n_send) then
00333 ind_loc (:) = 0
00334 n = 0
00335 do j = 1, n_corners
00336
00337 do i = 1, n_send
00338 if (missing_points (j,i)) then
00339 n = n + 1
00340 if (i == ictl_req) ind_loc (j) = n
00341 end if
00342 end do
00343 end do
00344
00345 print *, 'locs searched for indices_req', ibuf (4, ictl_req)
00346 do j = 1, n_corners
00347 n = ind_loc (j)
00348 if (n > 0) &
00349 print *, 'ictl_req', ictl_req, ', n ', n, &
00350 ': locs', locs (1:ndim_3d, n)
00351 end do
00352 endif
00353 #endif
00354
00355
00356
00357
00358
00359 locs(1,:) = psmile_gauss_3d_to_local_1d (grid_id, locs(:,:), &
00360 num_missing_points, outside)
00361 locs(2,:) = 1
00362
00363
00364
00365
00366
00367 Allocate (hash (num_missing_points), stat = ierror)
00368 if (ierror /= 0) then
00369 ierrp (1) = num_missing_points
00370
00371 ierror = PRISM_Error_Alloc
00372
00373 call psmile_error ( ierror, 'hash', ierrp, 1, &
00374 __FILE__, __LINE__ )
00375 return
00376 endif
00377
00378 call psmile_hash_extra (search, locs, hash, num_missing_points, &
00379 mask_array, mask_shape, mask_available, grid_valid_shape, &
00380 ierror)
00381 if (ierror > 0) return
00382
00383 #ifdef DEBUGX
00384 print *, 'hash values and locs ', grid_valid_shape
00385 n = 0
00386 do j = 1, n_corners
00387
00388 do i = 1, n_send
00389 if (missing_points (j,i)) then
00390 n = n + 1
00391 print *, 'i, j, n, hash(n), locs(:,n) ', &
00392 i, j, n, hash(n), locs(:,n)
00393 end if
00394 end do
00395 end do
00396 #endif
00397
00398
00399
00400
00401 if (search%n_liste > 0) then
00402 ibuf (5, 1:n_send) = 0
00403
00404 n = 0
00405 code = 1
00406 do j = 1, n_corners
00407
00408 do i = 1, n_send
00409 if (missing_points (j,i)) then
00410
00411 n = n + 1
00412
00413 if (hash (n) >= 0) then
00414
00415
00416
00417
00418
00419 ibuf (5, i) = ibuf (5, i) + code
00420 endif
00421
00422 endif
00423 end do
00424
00425 code = code * 2
00426 end do
00427
00428 #ifdef PRISM_ASSERTION
00429 if (n /= num_missing_points) then
00430 print *, 'num_missing_points, n', num_missing_points, n
00431 call psmile_assert ( __FILE__, __LINE__, &
00432 'n /= num_missing_points')
00433 endif
00434 #endif
00435
00436 #ifdef DEBUGX
00437 print *, 'code for locations found', n_send
00438 do i = 1, n_send
00439 print *, 'code', i, ibuf (5, i), missing_points(:, i)
00440 end do
00441 #endif
00442
00443 #ifdef DEBUG_TRACE
00444 if (ictl_req <= n_send) then
00445 print *, 'code for locations found for indices_req', ibuf (4, ictl_req)
00446 print *, 'ictl_req', ictl_req, ': code', ibuf (5, ictl_req), missing_points(:, ictl_req)
00447 endif
00448 #endif
00449
00450 endif
00451
00452
00453
00454 Deallocate (locs, hash, neighbours_3d_extra)
00455
00456
00457
00458 #ifdef VERBOSE
00459 print 9980, trim(ch_id), ierror, search%n_found, n_send
00460
00461 call psmile_flushstd
00462 #endif /* VERBOSE */
00463
00464 return
00465
00466
00467
00468 #ifdef VERBOSE
00469 9990 format (1x, a, ': psmile_trili_gauss2_extra: comp_id =', i3)
00470 9980 format (1x, a, ': psmile_trili_gauss2_extra: eof', &
00471 ', ierror =', i4, ', n_found =', i8, i8)
00472 #endif /* VERBOSE */
00473
00474 end subroutine psmile_trili_gauss2_extra