00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_global_search_nnx_dble (comp_info, search, &
00012 var_id, tgt_coords_x, tgt_coords_y, tgt_coords_z, &
00013 neighbors_3d, nloc, num_neigh, nb_extra, &
00014 extra_search, send_index, &
00015 ierror)
00016
00017
00018
00019 use PRISM
00020
00021 use psmile_grid, only : psmile_transform_extent_cyclic, &
00022 psmile_transform_extent_back, &
00023 max_num_trans_parts, &
00024 code_no_trans, &
00025 common_grid_range
00026
00027 use PSMILe, dummy_interface => PSMILe_global_search_nnx_dble
00028
00029 Implicit none
00030
00031
00032
00033 Type (Enddef_comp), Intent (In) :: comp_info
00034
00035
00036
00037
00038 Type (Enddef_search), Intent (InOut) :: search
00039
00040
00041
00042 Integer, Intent (In) :: var_id
00043
00044
00045
00046 Integer, Intent (In) :: send_index
00047
00048
00049
00050 Integer, Intent (In) :: nloc
00051
00052
00053
00054 Double Precision, Intent (In) :: tgt_coords_x (nloc)
00055 Double Precision, Intent (In) :: tgt_coords_y (nloc)
00056 Double Precision, Intent (In) :: tgt_coords_z (nloc)
00057
00058
00059
00060 Integer, Intent (In) :: num_neigh
00061
00062
00063
00064
00065
00066 Integer, Intent (In) :: nb_extra
00067
00068
00069
00070
00071
00072 Integer, Intent (InOut) :: neighbors_3d (ndim_3d, nloc,
00073 num_neigh)
00074
00075
00076
00077 Type (Extra_search_info), Intent (InOut) :: extra_search
00078
00079
00080
00081
00082
00083
00084 Integer, Intent (Out) :: ierror
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 Double Precision, Parameter :: dble_earth = 6400000.0d0
00104
00105 Integer, Parameter :: len_item = 1
00106
00107 Integer, Parameter :: inlp_len = 256
00108
00109 Integer, Parameter :: lon = 1
00110 Integer, Parameter :: lat = 2
00111 Integer, Parameter :: vrt = 3
00112
00113
00114
00115
00116
00117
00118 Integer :: comp_id, grid_id
00119 Integer :: global_grid_id
00120 Integer, Pointer :: indices (:)
00121
00122
00123
00124 Integer :: igrid, rank
00125 Integer :: n_total
00126 Integer :: grid_type
00127 Real (PSMILe_float_kind), Pointer :: extents (:, :, :)
00128
00129
00130
00131 Integer, allocatable :: igrid_to_dest_comp(:)
00132
00133
00134
00135 Integer :: j, n
00136 Integer :: ibeg, iend
00137
00138
00139
00140 Logical :: mask_changed
00141 Integer :: n_extra
00142
00143 Logical, Allocatable :: send_mask (:)
00144 Double Precision, Allocatable :: boxes (:, :, :)
00145 Real (PSMILe_float_kind) :: range_box (2, ndim_3d)
00146 Real (PSMILe_float_kind) :: dist_max (2)
00147 Double Precision :: dble_huge
00148
00149
00150
00151
00152
00153
00154 Double Precision, Pointer :: dist_dble (:, :)
00155 Double Precision :: r_earth2, r_lat
00156 Double Precision :: delta, sin_d, cos_lat
00157
00158
00159
00160 Integer :: n_trans, n_int
00161
00162 Integer :: tr_codes (max_num_trans_parts)
00163 Integer :: found (max_num_trans_parts)
00164 Real (PSMILe_float_kind) :: dinter_trans (2, ndim_3d)
00165 Real (PSMILe_float_kind) :: transformed (2, ndim_3d,
00166 max_num_trans_parts),
00167 dinter (2, ndim_3d, max_num_trans_parts)
00168
00169 Double Precision, Save :: period2 (ndim_3d)
00170
00171
00172
00173 Integer :: n_found, n_liste
00174 Integer :: ip_dist
00175
00176
00177
00178 Type (Send_information), Pointer :: send_info
00179 Integer :: extra_msg (nd_msgextra)
00180
00181 Integer :: i, ip, ipi, ireq
00182 Integer :: len_ibuf, ndibuf, n_send
00183 Integer :: len_rbuf, len_rtem, ndrbuf
00184 Integer, Allocatable :: ibuf (:)
00185 Double Precision, Pointer :: buf (:)
00186
00187
00188
00189 Integer :: answer (nd_msgextra)
00190 Integer, Allocatable :: selected (:, :)
00191 Type (Select_search_info), Pointer :: sel_info (:)
00192
00193
00194
00195 Integer :: dest, index, dest_comp, sender
00196 Integer :: nrecv, n_recv_req
00197 Integer :: recv_req
00198 Integer :: save_lreq (2:3)
00199 Integer :: status (MPI_STATUS_SIZE)
00200
00201
00202
00203 Integer, Parameter :: nerrp = 3
00204 Integer :: ierrp (nerrp)
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 Character(len=len_cvs_string), save :: mycvs =
00228 '$Id: psmile_global_search_nnx_dble.F90 2935 2011-02-03 07:52:41Z redler $'
00229
00230
00231
00232
00233
00234 #ifdef VERBOSE
00235 print 9990, trim(ch_id), var_id, search%msg_intersections%first_tgt_method_id, search%sender
00236 #endif /* VERBOSE */
00237
00238 call psmile_flushstd
00239
00240 ierror = 0
00241
00242 ndrbuf = 0
00243 ndibuf = 0
00244 n_recv_req = 0
00245
00246 r_earth2 = 1.0d0 / (dble_earth * 2.0)
00247 r_lat = 1.0d0 / (dble_earth * dble_deg2rad)
00248
00249 period2 = (common_grid_range(2,:) - common_grid_range(1,:)) / 2.0d0
00250
00251 grid_id = Methods(Fields(var_id)%method_id)%grid_id
00252 global_grid_id = Grids(grid_id)%global_grid_id
00253 grid_type = Grids(grid_id)%grid_type
00254
00255 comp_id = comp_info%comp_id
00256
00257
00258
00259 send_info => Methods(Fields(var_id)%method_id)%send_infos_coupler(send_index)
00260
00261 indices => extra_search%indices
00262 dist_dble => extra_search%dist_dble
00263
00264 n_extra = extra_search%n_extra
00265
00266 #ifdef PRISM_ASSERTION
00267 #ifdef HUHU
00268 sin_search => extra_search%sin_search_dble
00269 cos_search => extra_search%cos_search_dble
00270 z_search => extra_search%z_search_dble
00271 if ( .not. Associated (extra_search%dist_dble) .or. &
00272 .not. Associated (extra_search%cos_search_dble) .or. &
00273 .not. Associated (extra_search%sin_search_dble) .or. &
00274 .not. Associated (extra_search%z_search_dble) ) then
00275 #else
00276 if ( .not. Associated (extra_search%dist_dble) ) then
00277 #endif
00278
00279 call psmile_assert (__FILE__, __LINE__, &
00280 "arrays should be allocated and set")
00281 endif
00282 #endif
00283
00284
00285
00286 rank = Comps(comp_id)%rank
00287
00288
00289
00290
00291
00292 extents => comp_info%all_extents
00293
00294 n_total = SUM (comp_info%Number_of_grids_vector(:))
00295
00296 igrid = search%msg_intersections%first_src_all_extents_grid_id
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 Allocate (boxes (2, ndim_3d, n_extra), STAT = ierror)
00308
00309 if ( ierror > 0 ) then
00310 ierrp (1) = ierror
00311 ierrp (2) = n_extra * (2 * ndim_3d)
00312
00313 ierror = PRISM_Error_Alloc
00314 call psmile_error ( ierror, 'boxes', &
00315 ierrp, 2, __FILE__, __LINE__ )
00316 return
00317 endif
00318
00319 Allocate (send_mask (n_extra), STAT = ierror)
00320
00321 if ( ierror > 0 ) then
00322 ierrp (1) = ierror
00323 ierrp (2) = n_extra
00324
00325 ierror = PRISM_Error_Alloc
00326 call psmile_error ( ierror, 'send_mask', &
00327 ierrp, 2, __FILE__, __LINE__ )
00328 return
00329 endif
00330
00331 mask_changed = .true.
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 dble_huge = huge (dist_dble(1,1))
00344 dist_max (1) = extents (1, vrt, igrid)
00345 dist_max (2) = extents (2, vrt, igrid)
00346
00347 #ifdef DEBUGX
00348 print *, "dist_max", dist_max
00349 #endif
00350
00351 do n = 1, n_total
00352 if (global_grid_id == comp_info%all_extent_infos(4,n)) then
00353 dist_max (1) = min (dist_max(1), extents(1, vrt, n))
00354 dist_max (2) = max (dist_max(2), extents(2, vrt, n))
00355 endif
00356 end do
00357 #ifdef DEBUGX
00358 print *, "dist_max", dist_max
00359 #endif
00360
00361 do ibeg = 1, n_extra, inlp_len
00362 iend = min (n_extra, ibeg + inlp_len - 1)
00363
00364
00365
00366
00367
00368 do i = ibeg, iend
00369 if (dist_dble(i, nb_extra) * r_earth2 >= dble_pih) then
00370 sin_d = 1.0d0
00371 else
00372 sin_d = abs(sin(dist_dble(i, nb_extra) * r_earth2))
00373 endif
00374
00375 cos_lat = cos (tgt_coords_y(indices(i)) * dble_deg2rad)
00376
00377 if (sin_d >= cos_lat) then
00378 delta = period2(lon)
00379 else
00380 delta = 2.0d0 * asin (sin_d / cos_lat) / dble_deg2rad
00381 delta = min (period2(lon), delta)
00382 endif
00383
00384 boxes (1, lon, i) = tgt_coords_x(indices(i)) - delta
00385 boxes (2, lon, i) = tgt_coords_x(indices(i)) + delta
00386 end do
00387
00388
00389 do i = ibeg, iend
00390 if (boxes (2,lon,i) - boxes (1,lon,i) > period2(lon)*2) then
00391 boxes (1,lon,i) = -period2(lon)
00392 boxes (2,lon,i) = period2(lon)
00393 else if (boxes (1,lon,i) < -period2(lon)*2) then
00394 boxes (1,lon,i) = boxes (1,lon,i) + period2(lon)*2
00395 boxes (2,lon,i) = boxes (2,lon,i) + period2(lon)*2
00396 else if (boxes (2,lon,i) > period2(lon)*2) then
00397 boxes (1,lon,i) = boxes (1,lon,i) - period2(lon)*2
00398 boxes (2,lon,i) = boxes (2,lon,i) - period2(lon)*2
00399 endif
00400 end do
00401
00402
00403
00404
00405
00406 do i = ibeg, iend
00407 boxes (1, lat, i) = max (tgt_coords_y(indices(i)) - &
00408 min (period2(lat), dist_dble(i, nb_extra)*r_lat), &
00409 common_grid_range(1,lat))
00410 boxes (2, lat, i) = min (tgt_coords_y(indices(i)) + &
00411 min (period2(lat), dist_dble(i, nb_extra)*r_lat), &
00412 common_grid_range(2,lat))
00413 end do
00414 end do
00415
00416 range_box (1, lon) = minval (boxes (1, lon, :))
00417 range_box (2, lon) = maxval (boxes (2, lon, :))
00418
00419 range_box (1, lat) = minval (boxes (1, lat, :))
00420 range_box (2, lat) = maxval (boxes (2, lat, :))
00421
00422
00423
00424 do i = 1, n_extra
00425 if (dist_dble(i, nb_extra) == dble_huge) then
00426 boxes (1, vrt, i) = dist_max (1)
00427 boxes (2, vrt, i) = dist_max (2)
00428 else
00429 boxes (1, vrt, i) = tgt_coords_z(indices(i)) - &
00430 dist_dble(i, nb_extra)
00431 boxes (2, vrt, i) = tgt_coords_z(indices(i)) + &
00432 dist_dble(i, nb_extra)
00433 #ifdef DEBUGX
00434 print *, "dist_dble", i, indices(i), dist_dble(i, nb_extra)
00435 #endif
00436 endif
00437 end do
00438
00439 range_box (1, vrt) = minval (boxes (1, vrt, :))
00440 range_box (2, vrt) = maxval (boxes (2, vrt, :))
00441
00442 #ifdef PRISM_ASSERTION
00443 if (range_box (2,lon) - range_box (1,lon) > period2(lon)*4) then
00444 print *, 'range in lon direction', range_box (1:2,lon)
00445 call psmile_assert ( __FILE__, __LINE__, &
00446 'range_box too large in lon direction')
00447 endif
00448
00449 if (range_box (2,lat) - range_box (1,lat) > period2(lat)*4) then
00450 print *, 'range in lat direction', range_box (1:2,lat)
00451 call psmile_assert ( __FILE__, __LINE__, &
00452 'range_box too large in lat direction')
00453 endif
00454 #endif
00455
00456
00457
00458 call psmile_transform_extent_cyclic (grid_type, &
00459 range_box, transformed, tr_codes, n_trans, ierror)
00460 if (ierror > 0) return
00461
00462
00463
00464 Allocate (igrid_to_dest_comp(SUM(comp_info%Number_of_grids_vector)), stat = ierror)
00465
00466 if ( ierror > 0 ) then
00467 ierrp (1) = ierror
00468 ierrp (2) = SUM(comp_info%Number_of_grids_vector)
00469
00470 ierror = PRISM_Error_Alloc
00471 call psmile_error ( ierror, 'igrid_to_dest_comp', &
00472 ierrp, 2, __FILE__, __LINE__ )
00473 return
00474 endif
00475
00476 igrid = 0
00477 do dest_comp = 1, comp_info%size
00478 do j = 1, comp_info%Number_of_grids_vector(dest_comp)
00479 igrid = igrid + 1
00480 igrid_to_dest_comp(igrid) = dest_comp
00481 enddo
00482 enddo
00483
00484
00485
00486
00487
00488
00489 do igrid = 1, SUM(comp_info%Number_of_grids_vector)
00490
00491 dest_comp = igrid_to_dest_comp(igrid)
00492
00493 if (mask_changed) then
00494 mask_changed = .false.
00495 send_mask (:) = .false.
00496 endif
00497
00498
00499
00500
00501
00502
00503
00504 if (global_grid_id /= comp_info%all_extent_infos(4,igrid)) cycle
00505
00506
00507
00508
00509 if (rank == dest_comp-1 .and. &
00510 comp_info%all_extent_infos(1,igrid) == grid_id) cycle
00511
00512
00513
00514
00515
00516
00517
00518 do i = 1, n_trans
00519 dinter (1, :, i) = max (transformed(1,:,i), &
00520 extents(1,:,igrid))
00521 dinter (2, :, i) = min (transformed(2,:,i), &
00522 extents(2,:,igrid))
00523 end do
00524
00525 n_int = 0
00526
00527 do i = 1, n_trans
00528 if (minval(dinter (2,:,i) - dinter (1,:,i)) >= 0.0d0) then
00529 n_int = n_int + 1
00530 found (n_int) = i
00531 endif
00532 end do
00533
00534 if (n_int == 0) cycle
00535
00536
00537
00538 do i = 1, n_int
00539 if (tr_codes(found(i)) /= code_no_trans) then
00540 call psmile_transform_extent_back (tr_codes(found(i)), &
00541 dinter(:, :, found(i)), dinter_trans, 1, ierror)
00542 if ( ierror /= 0 ) return
00543
00544 dinter (:, :, found(i)) = dinter_trans
00545 endif
00546 end do
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 do i = 1, n_int
00560 #ifdef DEBUGX
00561 print *, 'extent controlled', i, n_int, dinter(:,:,found(i))
00562 #endif
00563
00564 do j = 1, n_extra
00565 send_mask (j) = send_mask (j) .or. &
00566 (boxes(2,lon,j) >= dinter(1,lon,found(i)) .and. &
00567 boxes(1,lon,j) <= dinter(2,lon,found(i)) .and. &
00568 boxes(2,lat,j) >= dinter(1,lat,found(i)) .and. &
00569 boxes(1,lat,j) <= dinter(2,lat,found(i)) .and. &
00570 boxes(2,vrt,j) >= dinter(1,vrt,found(i)) .and. &
00571 boxes(1,vrt,j) <= dinter(2,vrt,found(i)))
00572 #ifdef DEBUGX
00573 print *, j, boxes(:,:,j)
00574 #endif
00575 end do
00576 end do
00577
00578
00579
00580 n_send = COUNT(send_mask)
00581 if (n_send == 0) cycle
00582
00583 mask_changed = .true.
00584
00585
00586
00587 dest = comp_info%psmile_ranks(dest_comp)
00588
00589 n_recv_req = n_recv_req + 1
00590
00591 #ifdef VERBOSE
00592 print 9970, trim(ch_id), rank, dest_comp, dest, n_send
00593
00594 call psmile_flushstd
00595 #endif /* VERBOSE */
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 len_rtem = ndim_3d + 1
00616
00617 len_rbuf = n_send * len_rtem
00618 len_ibuf = n_send * len_item
00619
00620 if (len_rbuf > ndrbuf) then
00621 if (ndrbuf > 0) then
00622 Deallocate (buf)
00623 endif
00624
00625 ndrbuf = len_rbuf
00626 Allocate (buf(ndrbuf), STAT = ierror)
00627
00628 if ( ierror > 0 ) then
00629 ierrp (1) = ierror
00630 ierrp (2) = ndrbuf
00631
00632 ierror = PRISM_Error_Alloc
00633 call psmile_error ( ierror, 'buf', &
00634 ierrp, 2, __FILE__, __LINE__ )
00635 return
00636 endif
00637 endif
00638
00639 if (len_ibuf > ndibuf) then
00640 if (ndibuf > 0) then
00641 Deallocate (ibuf)
00642 endif
00643
00644 ndibuf = len_ibuf
00645 Allocate (ibuf(ndibuf), STAT = ierror)
00646
00647 if ( ierror > 0 ) then
00648 ierrp (1) = ierror
00649 ierrp (2) = ndibuf
00650
00651 ierror = PRISM_Error_Alloc
00652 call psmile_error ( ierror, 'ibuf', &
00653 ierrp, 2, __FILE__, __LINE__ )
00654 return
00655 endif
00656 endif
00657
00658
00659
00660
00661
00662
00663 #ifdef USE_PACK
00664 ibuf (1:n_send*len_item:len_item) = &
00665 PACK ((/ (i, i=1,n_extra) /), send_mask)
00666 #else
00667 ipi = 0
00668
00669
00670 do i = 1, n_extra
00671 if (send_mask (i)) then
00672 ibuf (ipi+1) = i
00673 ipi = ipi + len_item
00674 endif
00675 end do
00676 #endif /* USE_PACK */
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 #ifdef ALL_ITEM_PER_POINT
00694 ip = 0
00695
00696 do i = 1, n_extra
00697 if (send_mask (i)) then
00698
00699 buf (ip+1) = tgt_coords_x (indices(i))
00700 buf (ip+2) = tgt_coords_y (indices(i))
00701 buf (ip+3) = tgt_coords_z (indices(i))
00702
00703 buf (ip+4) = dist_dble (i, nb_extra)
00704 ip = ip + len_rtem
00705 endif
00706 end do
00707 #else
00708 ip = 0
00709
00710 do i = 1, n_extra
00711 if (send_mask (i)) then
00712 ip = ip + 1
00713 buf (ip ) = tgt_coords_x (indices(i))
00714 buf (ip+ n_send ) = tgt_coords_y (indices(i))
00715 buf (ip+(n_send*2)) = tgt_coords_z (indices(i))
00716 buf (ip+(n_send*3)) = dist_dble (i, nb_extra)
00717 endif
00718 end do
00719 #endif
00720
00721 #ifdef TODO
00722
00723 if (dest_comp == rank) then
00724
00725 search_global%sender = dest
00726 search_global%msg_extra = msg_extra (1:nd_msg)
00727
00728
00729 call psmile_search_donor_extra (search_global, tol, ierror)
00730 if (ierror > 0) return
00731
00732 endif
00733 #endif /* TODO */
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 extra_msg (1) = PSMILe_nnghbr3D
00764 extra_msg (2) = PRISM_DOUBLE_PRECISION
00765 extra_msg (3) = len_ibuf
00766 extra_msg (4) = len_rbuf
00767 extra_msg (5) = comp_info%global_comp_id
00768 extra_msg (6) = search%msg_intersections%transient_out_id
00769
00770 extra_msg (7) = grid_type
00771 extra_msg (8) = n_send
00772 extra_msg (9) = len_item
00773 extra_msg (10) = len_rtem
00774
00775
00776
00777
00778 extra_msg (11) = 0
00779
00780 extra_msg (15) = n_recv_req
00781 extra_msg (16) = nb_extra
00782
00783 extra_msg (17) = comp_info%all_extent_infos(1,igrid)
00784
00785 #ifdef DEBUGX
00786 print *, 'extra_msg (1:4)', extra_msg (1:4)
00787 do i = 1, n_send
00788 print *, ibuf ((i-1)*len_item+1:i*len_item)
00789 end do
00790 #endif
00791
00792 call psmile_bsend (extra_msg, nd_msgextra, MPI_INTEGER, &
00793 dest, exttag, comm_psmile, ierror)
00794 if (ierror /= MPI_SUCCESS) then
00795 ierrp (1) = ierror
00796 ierrp (2) = dest
00797 ierrp (3) = exttag
00798
00799 ierror = PRISM_Error_Send
00800
00801 call psmile_error (ierror, 'psmile_bsend(msg)', &
00802 ierrp, 3, __FILE__, __LINE__ )
00803 return
00804 endif
00805
00806 call psmile_bsend (ibuf, len_ibuf, MPI_INTEGER, &
00807 dest, exttag, comm_psmile, ierror)
00808 if (ierror /= MPI_SUCCESS) then
00809 ierrp (1) = ierror
00810 ierrp (2) = dest
00811 ierrp (3) = exttag
00812
00813 ierror = PRISM_Error_Send
00814
00815 call psmile_error (ierror, 'psmile_bsend(ibuf)', &
00816 ierrp, 3, __FILE__, __LINE__ )
00817 return
00818 endif
00819
00820 call psmile_bsend (buf, len_rbuf, MPI_DOUBLE_PRECISION, &
00821 dest, exttag, comm_psmile, ierror)
00822 if (ierror /= MPI_SUCCESS) then
00823 ierrp (1) = ierror
00824 ierrp (2) = dest
00825 ierrp (3) = exttag
00826
00827 ierror = PRISM_Error_Send
00828
00829 call psmile_error (ierror, 'psmile_bsend(buf)', &
00830 ierrp, 3, __FILE__, __LINE__ )
00831 return
00832 endif
00833
00834
00835
00836
00837 if (n_recv_req == 1) then
00838 call MPI_Irecv (answer, nd_msgextra, MPI_INTEGER, MPI_ANY_SOURCE, &
00839 rexttag, comm_psmile, recv_req, ierror)
00840 if (ierror /= MPI_SUCCESS) then
00841
00842 ierrp (1) = ierror
00843 ierrp (2) = dest
00844 ierrp (3) = rexttag
00845
00846 ierror = PRISM_Error_Recv
00847
00848 call psmile_error ( ierror, 'MPI_Irecv', &
00849 ierrp, 3, __FILE__, __LINE__ )
00850 return
00851
00852 endif
00853 endif
00854
00855 end do
00856
00857
00858
00859 Deallocate (send_mask, boxes, igrid_to_dest_comp)
00860
00861 if (ndrbuf > 0) Deallocate (buf)
00862 if (ndibuf > 0) Deallocate (ibuf)
00863
00864 #ifdef __BUG__
00865 if (n_recv_req == 0) then
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 send_info%nrecv = 0
00876 send_info%num2recv = 0
00877
00878 go to 1000
00879 endif
00880 #endif
00881
00882 if (n_recv_req == 0) go to 1000
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 nrecv = 0
00897
00898 Allocate (sel_info (n_recv_req), stat = ierror)
00899 if ( ierror > 0 ) then
00900 ierrp (1) = ierror
00901 ierrp (2) = n_recv_req
00902
00903 ierror = PRISM_Error_Alloc
00904 call psmile_error ( ierror, 'sel_info', ierrp, 2, &
00905 __FILE__, __LINE__ )
00906 return
00907 endif
00908
00909
00910
00911
00912
00913 save_lreq (2:3) = paction%lrequest (2:3)
00914 paction%lrequest (2) = MPI_REQUEST_NULL
00915
00916 do n = 1, n_recv_req
00917 paction%lrequest (3) = recv_req
00918
00919 index = 0
00920 do while (index /= 3)
00921 #ifdef DEBUG
00922 print *, trim(ch_id), paction%nreq, recv_req
00923 call psmile_flushstd
00924 #endif
00925
00926 call MPI_Waitany (paction%nreq, paction%lrequest, index, status, ierror)
00927
00928 if ( ierror /= MPI_SUCCESS ) then
00929 ierrp (1) = ierror
00930 ierrp (2) = status (MPI_SOURCE)
00931 ierrp (3) = status (MPI_TAG)
00932
00933 ierror = PRISM_Error_MPI
00934
00935 call psmile_error ( ierror, 'MPI_Waitany', &
00936 ierrp, 3, __FILE__, __LINE__ )
00937 return
00938 endif
00939
00940 #ifdef PRISM_ASSERTION
00941 if (index == MPI_UNDEFINED) then
00942 call psmile_assert ( __FILE__, __LINE__, &
00943 'request list is empty')
00944 endif
00945 #endif
00946
00947 if (index /= 3) then
00948 call psmile_enddef_action (search, index, status, ierror)
00949 if (ierror > 0) return
00950 endif
00951 end do
00952
00953
00954
00955 sender = status (MPI_SOURCE)
00956 len_ibuf = answer (3)
00957 len_rbuf = answer (4)
00958
00959 #ifdef VERBOSE
00960 print 9960, trim(ch_id), sender, len_ibuf, len_rbuf
00961
00962 call psmile_flushstd
00963 #endif /* VERBOSE */
00964
00965 #ifdef PRISM_ASSERTION
00966 if (len_ibuf < 0) then
00967 print *, 'len_ibuf =', len_ibuf
00968 call psmile_assert (__FILE__, __LINE__, &
00969 "len_ibuf should be >= 0")
00970 endif
00971
00972 if (len_rbuf < 0) then
00973 print *, 'len_rbuf =', len_rbuf
00974 call psmile_assert (__FILE__, __LINE__, &
00975 "len_rbuf should be >= 0")
00976 endif
00977 #endif
00978
00979 if (len_ibuf > 0) then
00980 Allocate (ibuf (1:len_ibuf), stat = ierror)
00981
00982 if ( ierror > 0 ) then
00983 ierrp (1) = ierror
00984 ierrp (2) = len_ibuf
00985
00986 ierror = PRISM_Error_Alloc
00987 call psmile_error ( ierror, 'ibuf', ierrp, 2, &
00988 __FILE__, __LINE__ )
00989 return
00990 endif
00991
00992 call MPI_Recv (ibuf, len_ibuf, MPI_INTEGER, sender, &
00993 rexttag, comm_psmile, status, ierror)
00994 if (ierror /= MPI_SUCCESS) then
00995
00996 ierrp (1) = ierror
00997 ierrp (2) = sender
00998 ierrp (3) = rexttag
00999
01000 ierror = PRISM_Error_Recv
01001
01002 call psmile_error ( ierror, 'MPI_Recv(ibuf)', ierrp, 3, &
01003 __FILE__, __LINE__ )
01004 return
01005 endif
01006
01007 Allocate (buf (1:len_rbuf), stat = ierror)
01008
01009 if ( ierror > 0 ) then
01010 ierrp (1) = ierror
01011 ierrp (2) = len_rbuf
01012
01013 ierror = PRISM_Error_Alloc
01014 call psmile_error ( ierror, 'buf', ierrp, 2, &
01015 __FILE__, __LINE__ )
01016 return
01017 endif
01018
01019 call MPI_Recv (buf, len_rbuf, MPI_DOUBLE_PRECISION, sender, &
01020 rexttag, comm_psmile, status, ierror)
01021 if (ierror /= MPI_SUCCESS) then
01022
01023 ierrp (1) = ierror
01024 ierrp (2) = sender
01025 ierrp (3) = rexttag
01026
01027 ierror = PRISM_Error_Recv
01028
01029 call psmile_error ( ierror, 'MPI_Recv(rbuf)', ierrp, 3, &
01030 __FILE__, __LINE__ )
01031 return
01032 endif
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 n_send = answer (7)
01043 n_liste = answer (8)
01044 n_found = answer (9)
01045 ireq = answer (15)
01046
01047 #ifdef PRISM_ASSERTION
01048 if (answer (1) /= PSMILe_nnghbr3D) then
01049 print *, 'answer(1)', answer(1), PSMILe_nnghbr3D
01050 call psmile_assert (__FILE__, __LINE__, &
01051 "expected nearest neighbour interpolation")
01052 endif
01053
01054 if (ireq < 1 .or. ireq > n_recv_req) then
01055 print *, 'ireq, n_recv_req', ireq, n_recv_req
01056 call psmile_assert (__FILE__, __LINE__, &
01057 "ireq must be in range of 1:n_recv_req")
01058 endif
01059 #endif
01060
01061 nrecv = nrecv + 1
01062
01063 sel_info(nrecv)%sender = sender
01064 sel_info(nrecv)%n_liste = n_liste
01065 sel_info(nrecv)%index = answer (10)
01066 sel_info(nrecv)%method_id = answer (11)
01067 sel_info(nrecv)%msg_id = answer (16)
01068
01069 sel_info(nrecv)%dble_buf => buf
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 if (.not. Allocated (selected)) then
01085 Allocate (selected(2, n_extra), stat = ierror)
01086
01087 if (ierror /= 0) then
01088 ierrp (1) = n_extra * 2
01089
01090 ierror = PRISM_Error_Alloc
01091
01092 call psmile_error ( ierror, 'selected', ierrp, 1, &
01093 __FILE__, __LINE__ )
01094 return
01095 endif
01096
01097 selected (1, :) = 0
01098 endif
01099
01100
01101
01102 ip_dist = n_liste * ndim_3d
01103
01104 call psmile_add_nn_found_dble (search, extra_search, &
01105 ibuf (1:n_send), &
01106 ibuf (n_send+1:2*n_send), n_send, &
01107 ibuf (2*n_send+1:2*n_send+n_found), &
01108 buf (ip_dist+1:ip_dist+n_found), n_found, &
01109 nb_extra, selected, sel_info, nrecv, ierror)
01110 if (ierror > 0) return
01111
01112 Deallocate (ibuf)
01113 endif
01114
01115
01116
01117 if (n < n_recv_req) then
01118 call MPI_Irecv (answer, nd_msgextra, MPI_INTEGER, MPI_ANY_SOURCE, &
01119 rexttag, comm_psmile, recv_req, &
01120 ierror)
01121 if (ierror /= MPI_SUCCESS) then
01122
01123 ierrp (1) = ierror
01124 ierrp (2) = dest
01125 ierrp (3) = rexttag
01126
01127 ierror = PRISM_Error_Recv
01128
01129 call psmile_error ( ierror, 'MPI_Irecv', &
01130 ierrp, 3, __FILE__, __LINE__ )
01131 return
01132 endif
01133 endif
01134 end do
01135
01136
01137
01138
01139 if (nrecv > 0) then
01140 call psmile_select_nn_found (search, extra_search, &
01141 send_info, &
01142 selected, sel_info, nrecv, nb_extra, &
01143 neighbors_3d, nloc, num_neigh, &
01144 Grids(grid_id)%grid_shape, ierror)
01145 if (ierror > 0) return
01146 endif
01147
01148
01149
01150 if (Allocated (selected)) then
01151 Deallocate (selected)
01152 endif
01153
01154 Deallocate (sel_info)
01155
01156
01157
01158 #ifdef PRISM_ASSERTION
01159 if (paction%lrequest (2) /= MPI_REQUEST_NULL .or. &
01160 paction%lrequest (3) /= MPI_REQUEST_NULL) then
01161 print *, 'request: ', paction%lrequest (2:3)
01162 call psmile_assert ( __FILE__, __LINE__, &
01163 'Illegal request stored')
01164
01165 endif
01166 #endif
01167
01168 paction%lrequest (2:3) = save_lreq (2:3)
01169
01170
01171
01172
01173
01174 1000 continue
01175 #ifdef VERBOSE
01176 print 9980, trim(ch_id), ierror
01177
01178 call psmile_flushstd
01179 #endif /* VERBOSE */
01180
01181
01182
01183
01184 #ifdef VERBOSE
01185
01186 9990 format (1x, a, ': psmile_global_search_nnx_dble: var_id', i3, &
01187 ' to ', i3, '(', i2, ')')
01188 9980 format (1x, a, ': psmile_global_search_nnx_dble: eof ierror =', i3)
01189 9970 format (1x, a, ': psmile_global_search_nnx_dble: send from', i3, &
01190 ' to', i3, '[', i3, '], n_send =', i6)
01191
01192 9960 format (1x, a, ': psmile_global_search_nnx_dble: got rexttag message:', &
01193 ' sender ', i4, ', len_ibuf, len_rbuf', 2i8)
01194 9950 format (1x, a, ': psmile_global_search_nnx_dble: before waitany :', &
01195 'nreq =', i4, ', recv_req ', i8)
01196 #endif /* VERBOSE */
01197
01198 #ifdef DEBUG
01199 #endif
01200
01201 end subroutine PSMILe_global_search_nnx_dble