00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_global_search_dble (comp_info, &
00012 control, len_cpl, &
00013 var_id, grid_valid_shape, &
00014 search, tgt_grid, &
00015 neighbors_3d, nloc, num_neigh, &
00016 extra_search, &
00017 interpolation_methods, &
00018 interpolation_search, n_intmethods, &
00019 send_index, &
00020 mask_available, use_mask, use_how, &
00021 grid_type, ierror)
00022
00023
00024
00025 use PRISM
00026
00027 use psmile_grid, only : psmile_transform_extent_cyclic, &
00028 psmile_transform_extent_back, &
00029 max_num_trans_parts, &
00030 code_no_trans, &
00031 common_grid_range
00032
00033 use PSMILe, dummy_interface => PSMILe_global_search_dble
00034
00035 implicit none
00036
00037
00038
00039 Type (Enddef_comp), Intent (In) :: comp_info
00040
00041
00042
00043
00044 Type (Enddef_search), Intent (InOut) :: search
00045
00046
00047
00048 Type (dble_vector), Intent (In) :: tgt_grid (ndim_3d)
00049
00050
00051
00052 Integer, Intent (In) :: control (2, ndim_3d, search%search_data%npart)
00053
00054
00055
00056 Integer, Intent (In) :: len_cpl (search%search_data%npart)
00057
00058
00059
00060 Integer, Intent (In) :: var_id
00061
00062
00063
00064 Integer, Intent (In) :: grid_valid_shape (2, ndim_3d)
00065
00066
00067
00068 Integer, Intent (In) :: send_index
00069
00070
00071
00072 Integer, Intent (In) :: nloc
00073
00074
00075
00076 Integer, Intent (In) :: num_neigh
00077
00078
00079
00080
00081
00082 Integer, Intent (In) :: n_intmethods
00083
00084
00085
00086
00087 Integer, Intent (In) :: interpolation_methods (n_intmethods)
00088
00089
00090
00091 Logical, Intent (In) :: interpolation_search(n_intmethods)
00092
00093
00094
00095 Logical, Intent (In) :: mask_available
00096
00097
00098 Logical, Intent (In) :: use_mask
00099
00100 Integer, Intent (In) :: use_how
00101
00102
00103
00104 Integer, Intent (In) :: grid_type
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 Integer, Intent (InOut) :: neighbors_3d (ndim_3d, nloc,
00115 num_neigh)
00116
00117
00118
00119 Type (Extra_search_info), Intent (InOut) :: extra_search
00120
00121
00122
00123
00124
00125
00126 Integer, Intent (Out) :: ierror
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 Double Precision, Parameter :: eps = 0.0d0
00138
00139 Integer, Parameter :: nc_reg = 2
00140 Integer, Parameter :: masked_out = 0
00141
00142
00143
00144
00145
00146
00147 Integer :: comp_id, method_id
00148 Type (Method), Pointer :: mp
00149
00150 Type (Corner_Block), Pointer :: corner_pointer
00151
00152
00153
00154 Integer :: grid_id, global_grid_id
00155 Type(Grid), Pointer :: grid_info
00156
00157 Type (integer_vector), Pointer :: indices_req (:)
00158 Type (integer_vector), Pointer :: required (:)
00159 Integer, Pointer :: len_req (:)
00160
00161
00162
00163 Integer :: rank, igrid
00164
00165
00166
00167
00168 Integer, allocatable :: igrid_to_dest_comp(:)
00169
00170
00171
00172 Integer :: ipart, j, n
00173
00174
00175
00176 Logical :: mask_changed
00177 Integer :: nextra_prev, nreq, nx
00178
00179 Integer, Allocatable :: n_faces (:)
00180 Logical, Allocatable :: send_mask (:)
00181 Double Precision, Allocatable :: faces (:, :, :)
00182
00183
00184
00185 Integer :: n_trans, n_int
00186
00187 Integer :: tr_codes (max_num_trans_parts)
00188 Integer :: found (2*max_num_trans_parts)
00189 Real (PSMILe_float_kind) :: face_range (2, ndim_3d)
00190 Real (PSMILe_float_kind) :: dinter_trans (2, ndim_3d)
00191 Real (PSMILe_float_kind) :: face_range_transformed (2, ndim_3d,
00192 max_num_trans_parts),
00193 dinter (2, ndim_3d, 2*max_num_trans_parts)
00194
00195
00196
00197 Integer :: n_found, n_liste
00198
00199
00200
00201 Type (Send_information), Pointer :: send_info
00202 Type (enddef_msg_extra) :: extra_msg
00203 Integer :: extra_msg_buf (msg_extra_size)
00204 Integer :: answer (msg_extra_size)
00205 Logical :: virtual_cell_available
00206
00207 Integer :: interp
00208 Integer :: i, ip, ipi, ipi_prev, ireq
00209 Integer :: len_ibuf, len_item, ndibuf, n_send
00210 Integer :: len_rbuf, len_rtem, ndrbuf, nd_len
00211 Integer, Pointer :: len_nsend (:, :)
00212 Integer, Pointer :: old_len (:, :)
00213 Integer, Allocatable :: ibuf (:)
00214 Integer, Allocatable :: srcloc_ind (:, :)
00215 Integer, Pointer :: virtual_ind (:)
00216 Integer, Target :: dummy_virtual_ind (1)
00217 Double Precision, Pointer :: buf (:)
00218
00219
00220
00221
00222 Integer :: dest, index, dest_comp, sender
00223 Integer :: nrecv, nprev_recv, n_recv_req
00224 Integer :: recv_req
00225 Integer :: save_lreq (2:3)
00226 Integer :: status (MPI_STATUS_SIZE)
00227
00228
00229
00230 Integer, parameter :: nerrp = 3
00231 Integer :: ierrp (nerrp)
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 Character(len=len_cvs_string), save :: mycvs =
00257 '$Id: psmile_global_search_dble.F90 3174 2011-05-04 09:41:43Z hanke $'
00258
00259
00260
00261
00262
00263 #ifdef VERBOSE
00264 print 9990, trim(ch_id), var_id, search%msg_intersections%field_info%tgt_method_id, &
00265 search%sender
00266
00267 call psmile_flushstd
00268 #endif /* VERBOSE */
00269
00270 ierror = 0
00271
00272 ndrbuf = 0
00273 ndibuf = 0
00274 n_recv_req = 0
00275
00276 method_id = Fields(var_id)%method_id
00277 mp => Methods(method_id)
00278
00279 grid_id = mp%grid_id
00280 grid_info => Grids(grid_id)
00281
00282 global_grid_id = grid_info%global_grid_id
00283
00284
00285
00286 send_info => mp%send_infos_coupler(send_index)
00287 corner_pointer => grid_info%corner_pointer
00288
00289 comp_id = comp_info%comp_id
00290
00291 indices_req => extra_search%indices_req
00292 required => extra_search%required
00293 len_req => extra_search%len_req
00294 nreq = extra_search%n_req
00295
00296 virtual_cell_available = Associated (send_info%virtual)
00297
00298 #ifdef PRISM_ASSERTION
00299 if (grid_type /= grid_info%grid_type) then
00300
00301 print *, 'grid_type', grid_type, grid_info%grid_type
00302 call psmile_assert ( __FILE__, __LINE__, &
00303 'inconsistent grid types')
00304 endif
00305 #endif
00306
00307
00308
00309 rank = Comps(comp_id)%rank
00310
00311 if (count(interpolation_search(:)) > 1) then
00312 ierrp (1) = count(interpolation_search(:))
00313
00314 ierror = PRISM_Error_Internal
00315
00316 call psmile_error ( ierror, 'Global search currently supported only for one interpolation method', &
00317 ierrp, 1, __FILE__, __LINE__ )
00318
00319 return
00320 endif
00321
00322 do interp = 1, n_intmethods
00323 if (interpolation_search(interp) ) exit
00324 end do
00325
00326 if (interp > n_intmethods) then
00327 ierror = PRISM_Error_Internal
00328 ierrp (1) = n_intmethods
00329
00330 call psmile_error ( ierror, 'No Global search for interpolation methods', &
00331 ierrp, 1, __FILE__, __LINE__ )
00332 return
00333 endif
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 Allocate (faces (2, ndim_3d, nreq), STAT = ierror)
00346
00347 if ( ierror > 0 ) then
00348 ierrp (1) = ierror
00349 ierrp (2) = 2 * ndim_3d * nreq
00350
00351 ierror = PRISM_Error_Alloc
00352 call psmile_error ( ierror, 'faces', &
00353 ierrp, 2, __FILE__, __LINE__ )
00354 return
00355 endif
00356
00357 Allocate (n_faces (nreq), STAT = ierror)
00358
00359 if ( ierror > 0 ) then
00360 ierrp (1) = ierror
00361 ierrp (2) = nreq
00362
00363 ierror = PRISM_Error_Alloc
00364 call psmile_error ( ierror, 'n_faces', &
00365 ierrp, 2, __FILE__, __LINE__ )
00366 return
00367 endif
00368
00369 Allocate (send_mask (nreq), STAT = ierror)
00370
00371 if ( ierror > 0 ) then
00372 ierrp (1) = ierror
00373 ierrp (2) = nreq
00374
00375 ierror = PRISM_Error_Alloc
00376 call psmile_error ( ierror, 'send_mask', &
00377 ierrp, 2, __FILE__, __LINE__ )
00378 return
00379 endif
00380
00381 mask_changed = .true.
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 nx = nreq
00403
00404 len_item = ndim_3d + 2
00405
00406 select case (grid_type)
00407
00408 case (PRISM_Reglonlatvrt)
00409 len_rtem = ndim_3d * (nc_reg + 1)
00410
00411 call psmile_get_faces_3d_reg_dble ( &
00412 search, extra_search, &
00413 corner_pointer%corners_dble(1)%vector, &
00414 corner_pointer%corners_dble(2)%vector, &
00415 corner_pointer%corners_dble(3)%vector, &
00416 corner_pointer%corner_shape, &
00417 corner_pointer%nbr_corners, &
00418 grid_valid_shape, &
00419 neighbors_3d, nloc, num_neigh, &
00420 faces, n_faces, nreq, ierror)
00421
00422 case (PRISM_Irrlonlat_regvrt)
00423 len_rtem = ndim_3d + &
00424 (corner_pointer%nbr_corners/nc_reg)*ndim_2d + ndim_2d
00425
00426 call psmile_get_faces_irreg2_dble ( &
00427 search, extra_search, &
00428 corner_pointer%corners_dble(1)%vector, &
00429 corner_pointer%corners_dble(2)%vector, &
00430 corner_pointer%corners_dble(3)%vector, &
00431 corner_pointer%corner_shape, &
00432 corner_pointer%nbr_corners, &
00433 grid_valid_shape, &
00434 neighbors_3d, nloc, num_neigh, &
00435 faces, n_faces, nreq, ierror)
00436
00437 case (PRISM_Irrlonlatvrt)
00438 len_rtem = ndim_3d + corner_pointer%nbr_corners*ndim_3d
00439
00440 call psmile_get_faces_3d_dble ( &
00441 search, extra_search, &
00442 corner_pointer%corners_dble(1)%vector, &
00443 corner_pointer%corners_dble(2)%vector, &
00444 corner_pointer%corners_dble(3)%vector, &
00445 corner_pointer%corner_shape, &
00446 corner_pointer%nbr_corners, &
00447 grid_valid_shape, &
00448 neighbors_3d, nloc, num_neigh, &
00449 faces, n_faces, nreq, ierror)
00450
00451 case (PRISM_Gaussreduced_regvrt)
00452 if (virtual_cell_available) len_item = ndim_3d + 3
00453 len_rtem = ndim_3d * (nc_reg + 1)
00454
00455 call psmile_get_faces_gauss2_dble ( &
00456 search, extra_search, &
00457 corner_pointer%corners_dble(1)%vector, &
00458 corner_pointer%corners_dble(2)%vector, &
00459 corner_pointer%corners_dble(3)%vector, &
00460 corner_pointer%corner_shape, &
00461 corner_pointer%nbr_corners, &
00462 grid_valid_shape, &
00463 neighbors_3d, nloc, num_neigh, &
00464 faces, nreq, ierror)
00465
00466 case default
00467 ierrp (1) = grid_type
00468 ierror = PRISM_Error_Internal
00469
00470 call psmile_error ( ierror, 'unsupported grid type', &
00471 ierrp, 1, __FILE__, __LINE__ )
00472 return
00473
00474 end select
00475
00476 if (ierror > 0) return
00477
00478
00479
00480 face_range (1, 1) = minval (faces (1, 1, 1:nreq))
00481 face_range (2, 1) = maxval (faces (2, 1, 1:nreq))
00482 face_range (1, 2) = minval (faces (1, 2, 1:nreq))
00483 face_range (2, 2) = maxval (faces (2, 2, 1:nreq))
00484 face_range (1, 3) = minval (faces (1, 3, 1:nreq))
00485 face_range (2, 3) = maxval (faces (2, 3, 1:nreq))
00486
00487 call psmile_transform_extent_cyclic (grid_info%grid_type, face_range, &
00488 face_range_transformed, tr_codes, &
00489 n_trans, ierror)
00490 if (ierror > 0) return
00491
00492
00493
00494 nd_len = 8
00495 Allocate (len_nsend (search%search_data%npart, nd_len), stat = ierror)
00496
00497 if ( ierror > 0 ) then
00498 ierrp (1) = ierror
00499 ierrp (2) = search%search_data%npart * nd_len
00500
00501 ierror = PRISM_Error_Alloc
00502 call psmile_error ( ierror, 'len_nsend', &
00503 ierrp, 2, __FILE__, __LINE__ )
00504 return
00505 endif
00506
00507
00508
00509 Allocate (igrid_to_dest_comp(SUM(comp_info%Number_of_grids_vector)), stat = ierror)
00510
00511 if ( ierror > 0 ) then
00512 ierrp (1) = ierror
00513 ierrp (2) = SUM(comp_info%Number_of_grids_vector)
00514
00515 ierror = PRISM_Error_Alloc
00516 call psmile_error ( ierror, 'igrid_to_dest_comp', &
00517 ierrp, 2, __FILE__, __LINE__ )
00518 return
00519 endif
00520
00521 igrid = 0
00522 do dest_comp = 1, comp_info%size
00523 do j = 1, comp_info%Number_of_grids_vector(dest_comp)
00524 igrid = igrid + 1
00525 igrid_to_dest_comp(igrid) = dest_comp
00526 enddo
00527 enddo
00528
00529
00530
00531
00532
00533
00534 do igrid = 1, SUM(comp_info%Number_of_grids_vector)
00535
00536 dest_comp = igrid_to_dest_comp(igrid)
00537
00538 if (mask_changed) then
00539 send_mask (:) = .false.
00540 mask_changed = .false.
00541 endif
00542
00543
00544 if (global_grid_id /= comp_info%all_extent_infos(igrid)%global_grid_id) cycle
00545
00546
00547
00548 if (rank == dest_comp-1 .and. &
00549 comp_info%all_extent_infos(igrid)%local_grid_id == grid_id) cycle
00550
00551
00552
00553
00554
00555
00556 do i = 1, n_trans
00557
00558 dinter (1, :, i) = max (face_range_transformed(1,:,i), &
00559 comp_info%all_extent_infos(igrid)%extent(1,:))
00560 dinter (2, :, i) = min (face_range_transformed(2,:,i), &
00561 comp_info%all_extent_infos(igrid)%extent(2,:))
00562
00563
00564
00565
00566
00567 if ( face_range_transformed(1,1,i) == common_grid_range(1,1) .and. &
00568 .not. face_range_transformed(2,1,i) == common_grid_range(2,1)) then
00569
00570 dinter (:, :, i+n_trans) = dinter (:, :, i)
00571 dinter (:, 1, i+n_trans) = common_grid_range(1,1)
00572
00573 else if (.not. face_range_transformed(1,1,i) == common_grid_range(1,1) .and. &
00574 face_range_transformed(2,1,i) == common_grid_range(2,1)) then
00575
00576 dinter (:, :, i+n_trans) = dinter (:, :, i)
00577 dinter (:, 1, i+n_trans) = common_grid_range(2,1)
00578
00579 else
00580
00581 dinter (1,:,i+n_trans) = 0
00582 dinter (2,:,i+n_trans) = -1
00583 endif
00584 end do
00585
00586 n_int = 0
00587
00588 do i = 1, 2 * n_trans
00589 if (minval(dinter (2,:,i) - dinter (1,:,i)) >= 0.0d0) then
00590 n_int = n_int + 1
00591 found (n_int) = i
00592 endif
00593 end do
00594
00595 if (n_int == 0) cycle
00596
00597
00598
00599 do i = 1, n_int
00600 if (tr_codes(found(i)) /= code_no_trans) then
00601 call psmile_transform_extent_back (tr_codes(found(i)), &
00602 dinter(:, :, found(i)), dinter_trans, 1, ierror)
00603 if ( ierror /= 0 ) return
00604
00605 dinter (:, :, found(i)) = dinter_trans
00606 endif
00607 end do
00608
00609
00610
00611
00612
00613
00614 do i = 1, n_int
00615 #ifdef DEBUGX
00616 print *, 'extent controlled', i, n_int, dinter(:,:,found(i))
00617 #endif
00618
00619 do j = 1, nx
00620 send_mask (j) = send_mask (j) .or. &
00621 (faces(2,1,j) >= dinter(1,1,found(i)) .and. &
00622 faces(1,1,j) <= dinter(2,1,found(i)) .and. &
00623 faces(2,2,j) >= dinter(1,2,found(i)) .and. &
00624 faces(1,2,j) <= dinter(2,2,found(i)) .and. &
00625 faces(2,3,j) >= dinter(1,3,found(i)) .and. &
00626 faces(1,3,j) <= dinter(2,3,found(i)))
00627 #ifdef DEBUGX
00628 print *, j, faces(:,:,j)
00629 #endif
00630 end do
00631 end do
00632
00633
00634
00635 n_send = COUNT(send_mask)
00636 if (n_send == 0) cycle
00637
00638 mask_changed = .true.
00639
00640
00641
00642 dest = comp_info%psmile_ranks(dest_comp)
00643
00644 n_recv_req = n_recv_req + 1
00645 if (n_recv_req > nd_len) then
00646 nd_len = nd_len + 16
00647
00648
00649
00650 old_len => len_nsend
00651 Allocate (len_nsend (search%search_data%npart, nd_len), stat = ierror)
00652
00653 if ( ierror > 0 ) then
00654 ierrp (1) = ierror
00655 ierrp (2) = search%search_data%npart * nd_len
00656
00657 ierror = PRISM_Error_Alloc
00658 call psmile_error ( ierror, 'len_nsend', &
00659 ierrp, 2, __FILE__, __LINE__ )
00660 return
00661 endif
00662
00663 len_nsend (:, 1:n_recv_req-1) = old_len (:, 1:n_recv_req-1)
00664
00665 Deallocate (old_len)
00666 endif
00667
00668 #ifdef VERBOSE
00669 print 9970, trim(ch_id), rank, dest_comp, dest, n_send
00670
00671 call psmile_flushstd
00672 #endif /* VERBOSE */
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 len_rbuf = n_send * len_rtem
00692 len_ibuf = n_send * len_item
00693
00694 if (len_rbuf > ndrbuf) then
00695 if (ndrbuf > 0) then
00696 Deallocate (buf)
00697 endif
00698
00699 ndrbuf = len_rbuf
00700 Allocate (buf(ndrbuf), STAT = ierror)
00701
00702 if ( ierror > 0 ) then
00703 ierrp (1) = ierror
00704 ierrp (2) = ndrbuf
00705
00706 ierror = PRISM_Error_Alloc
00707 call psmile_error ( ierror, 'buf', &
00708 ierrp, 2, __FILE__, __LINE__ )
00709 return
00710 endif
00711 endif
00712
00713 if (len_ibuf > ndibuf) then
00714 if (ndibuf > 0) then
00715 Deallocate (ibuf)
00716 endif
00717
00718 ndibuf = len_ibuf
00719 Allocate (ibuf(ndibuf), STAT = ierror)
00720
00721 if ( ierror > 0 ) then
00722 ierrp (1) = ierror
00723 ierrp (2) = ndibuf
00724
00725 ierror = PRISM_Error_Alloc
00726 call psmile_error ( ierror, 'ibuf', &
00727 ierrp, 2, __FILE__, __LINE__ )
00728 return
00729 endif
00730 endif
00731
00732
00733
00734
00735 Allocate (srcloc_ind(ndim_3d, n_send), STAT = ierror)
00736
00737 if ( ierror > 0 ) then
00738 ierrp (1) = ierror
00739 ierrp (2) = ndim_3d * n_send
00740
00741 ierror = PRISM_Error_Alloc
00742 call psmile_error ( ierror, 'srcloc_ind', &
00743 ierrp, 2, __FILE__, __LINE__ )
00744 return
00745 endif
00746
00747 select case (send_info%nvec)
00748 case (1)
00749 call psmile_get_face_ind_3d (search, extra_search, &
00750 send_info, len_cpl, &
00751 send_mask, nreq, srcloc_ind, n_send, &
00752 ierror)
00753
00754 case (2)
00755 call psmile_get_face_ind_21d (search, extra_search, &
00756 send_info, len_cpl, &
00757 send_mask, nreq, srcloc_ind, n_send, &
00758 ierror)
00759
00760 case (ndim_3d)
00761 call psmile_get_face_ind_reg (search, extra_search, &
00762 send_info, len_cpl, &
00763 send_mask, nreq, srcloc_ind, n_send, &
00764 ierror)
00765 end select
00766
00767 if (ierror > 0) return
00768
00769 if (grid_type == PRISM_Gaussreduced_regvrt) then
00770 #ifdef DEBUG
00771
00772
00773 print *, '### psmile_global_search_dble.F90 raus damit !!', send_info%nvec
00774 #endif
00775 do i = 1, n_send
00776 srcloc_ind (1, i) = abs (srcloc_ind(1,i))
00777 end do
00778 endif
00779
00780 if (virtual_cell_available) then
00781 Allocate (virtual_ind(n_send), STAT = ierror)
00782
00783 if ( ierror > 0 ) then
00784 ierrp (1) = ierror
00785 ierrp (2) = n_send
00786
00787 ierror = PRISM_Error_Alloc
00788 call psmile_error ( ierror, 'virtual_ind', &
00789 ierrp, 2, __FILE__, __LINE__ )
00790 return
00791 endif
00792
00793 call psmile_get_faces_virtual_ind (search, extra_search, &
00794 send_info, len_cpl, &
00795 send_mask, nreq, virtual_ind, n_send, &
00796 ierror)
00797 if (ierror > 0) return
00798
00799 else
00800
00801 virtual_ind => dummy_virtual_ind
00802
00803 endif
00804
00805
00806
00807
00808
00809
00810
00811 nextra_prev = 0
00812 ipi = 0
00813 ip = 0
00814
00815 select case (grid_type)
00816
00817 case (PRISM_Reglonlatvrt)
00818 do ipart = 1, search%search_data%npart
00819
00820 ipi_prev = ipi
00821
00822 if (len_req (ipart) > 0) then
00823
00824 call psmile_store_faces_3d_reg_dble ( &
00825 indices_req(ipart)%vector, &
00826 required (ipart)%vector, &
00827 len_req (ipart), &
00828 tgt_grid (1)%vector, &
00829 tgt_grid (2)%vector, &
00830 tgt_grid (3)%vector, nloc, &
00831 corner_pointer%corners_dble(1)%vector, &
00832 corner_pointer%corners_dble(2)%vector, &
00833 corner_pointer%corners_dble(3)%vector, &
00834 corner_pointer%corner_shape, &
00835 corner_pointer%nbr_corners, &
00836 grid_valid_shape, &
00837 send_mask(nextra_prev+1:), &
00838 srcloc_ind, &
00839 ibuf, len_item, n_send, ipi, &
00840 buf, len_rtem, n_send, ip, ierror)
00841
00842 nextra_prev = nextra_prev + len_req (ipart)
00843 endif
00844
00845 len_nsend (ipart, n_recv_req) = ipi - ipi_prev
00846 end do
00847
00848 #ifdef PRISM_ASSERTION
00849 if (ipi /= n_send) then
00850 print *, 'ipi, n_send', ipi, n_send
00851 call psmile_assert ( __FILE__, __LINE__, &
00852 'inconsistent length for pack buffer ibuf')
00853 endif
00854
00855 if (ip /= n_send) then
00856 print *, 'ip, n_send', ip, n_send
00857 call psmile_assert ( __FILE__, __LINE__, &
00858 'inconsistent length for pack buffer buf')
00859 endif
00860 #endif
00861
00862 case (PRISM_Irrlonlat_regvrt)
00863
00864 do ipart = 1, search%search_data%npart
00865
00866 ipi_prev = ipi
00867
00868 if (len_req (ipart) > 0) then
00869
00870 call psmile_store_faces_irreg2_dble ( &
00871 indices_req(ipart)%vector, &
00872 required (ipart)%vector, &
00873 len_req (ipart), &
00874 tgt_grid (1)%vector, &
00875 tgt_grid (2)%vector, &
00876 tgt_grid (3)%vector, nloc, &
00877 corner_pointer%corners_dble(1)%vector, &
00878 corner_pointer%corners_dble(2)%vector, &
00879 corner_pointer%corners_dble(3)%vector, &
00880 corner_pointer%corner_shape, &
00881 corner_pointer%nbr_corners, &
00882 grid_valid_shape, &
00883 send_mask(nextra_prev+1:), &
00884 srcloc_ind, &
00885 ibuf, len_item, n_send, ipi, &
00886 buf, len_rtem, n_send, ip, ierror)
00887
00888 nextra_prev = nextra_prev + len_req (ipart)
00889 endif
00890
00891 len_nsend (ipart, n_recv_req) = ipi - ipi_prev
00892 end do
00893
00894 #ifdef PRISM_ASSERTION
00895 if (ipi /= n_send) then
00896 print *, 'ipi, n_send', ipi, n_send
00897 call psmile_assert ( __FILE__, __LINE__, &
00898 'inconsistent length for pack buffer ibuf')
00899 endif
00900
00901 if (ip /= n_send) then
00902 print *, 'ip, n_send', ip, n_send
00903 call psmile_assert ( __FILE__, __LINE__, &
00904 'inconsistent length for pack buffer buf')
00905 endif
00906 #endif
00907
00908 case (PRISM_Gaussreduced_regvrt)
00909
00910 do ipart = 1, search%search_data%npart
00911
00912 ipi_prev = ipi
00913
00914 if (len_req (ipart) > 0) then
00915
00916 call psmile_store_faces_gauss2_dble ( &
00917 indices_req(ipart)%vector, &
00918 required (ipart)%vector, &
00919 len_req (ipart), &
00920 tgt_grid (1)%vector, &
00921 tgt_grid (2)%vector, &
00922 tgt_grid (3)%vector, nloc, &
00923 corner_pointer%corners_dble(1)%vector, &
00924 corner_pointer%corners_dble(2)%vector, &
00925 corner_pointer%corners_dble(3)%vector, &
00926 corner_pointer%corner_shape, &
00927 corner_pointer%nbr_corners, &
00928 grid_id, grid_valid_shape, &
00929 send_mask(nextra_prev+1:), &
00930 srcloc_ind, virtual_ind, &
00931 virtual_cell_available, &
00932 ibuf, len_item, n_send, ipi, &
00933 buf, len_rtem, n_send, ip, ierror)
00934
00935 nextra_prev = nextra_prev + len_req (ipart)
00936 endif
00937
00938 len_nsend (ipart, n_recv_req) = ipi - ipi_prev
00939 end do
00940
00941 #ifdef PRISM_ASSERTION
00942 if (ipi /= n_send) then
00943 print *, 'ipi, n_send', ipi, n_send
00944 call psmile_assert ( __FILE__, __LINE__, &
00945 'inconsistent length for pack buffer ibuf')
00946 endif
00947
00948 if (ip /= n_send) then
00949 print *, 'ip, n_send', ip, n_send
00950 call psmile_assert ( __FILE__, __LINE__, &
00951 'inconsistent length for pack buffer buf')
00952 endif
00953 #endif
00954
00955 case (PRISM_Irrlonlatvrt)
00956 do ipart = 1, search%search_data%npart
00957
00958 ipi_prev = ipi
00959
00960 if (len_req (ipart) > 0) then
00961
00962 call psmile_store_faces_3d_dble ( &
00963 indices_req(ipart)%vector, &
00964 required (ipart)%vector, &
00965 len_req (ipart), &
00966 tgt_grid (1)%vector, &
00967 tgt_grid (2)%vector, &
00968 tgt_grid (3)%vector, nloc, &
00969 corner_pointer%corners_dble(1)%vector, &
00970 corner_pointer%corners_dble(2)%vector, &
00971 corner_pointer%corners_dble(3)%vector, &
00972 corner_pointer%corner_shape, &
00973 corner_pointer%nbr_corners, &
00974 grid_valid_shape, &
00975 send_mask(nextra_prev+1:), &
00976 srcloc_ind, &
00977 ibuf, len_item, n_send, ipi, &
00978 buf, len_rtem, n_send, ip, ierror)
00979
00980 nextra_prev = nextra_prev + len_req (ipart)
00981 endif
00982
00983 len_nsend (ipart, n_recv_req) = ipi - ipi_prev
00984 end do
00985
00986 case default
00987 ierrp (1) = grid_type
00988 ierror = PRISM_Error_Internal
00989
00990 call psmile_error ( ierror, 'unsupported grid type', &
00991 ierrp, 1, __FILE__, __LINE__ )
00992 return
00993
00994 end select
00995
00996 Deallocate (srcloc_ind)
00997 if (virtual_cell_available) Deallocate (virtual_ind)
00998
00999 #ifdef TODO
01000
01001 if (dest_comp == rank) then
01002
01003 search_global%sender = dest
01004 search_global%msg_extra = extra_msg
01005
01006 call psmile_search_donor_extra (search_global, tol, ierror)
01007 if (ierror > 0) return
01008
01009 endif
01010 #endif /* TODO */
01011
01012
01013
01014
01015
01016
01017 call psmile_init_enddef_msg_extra(extra_msg)
01018
01019 extra_msg%reqest_type = interpolation_methods (interp)
01020 extra_msg%datatype = PRISM_DOUBLE_PRECISION
01021 extra_msg%len_int_data = len_ibuf
01022 extra_msg%len_coord_data = len_rbuf
01023 extra_msg%global_comp_id = comp_info%global_comp_id
01024 extra_msg%transi_out_id = search%msg_intersections%field_info%transient_out_id
01025
01026 extra_msg%num_volumes = n_send
01027 extra_msg%num_int_per_vol = len_item
01028 extra_msg%num_items_per_coord = len_rtem
01029
01030 extra_msg%idx_req = n_recv_req
01031 extra_msg%num_neigh = num_neigh
01032
01033 extra_msg%local_grid_id = comp_info%all_extent_infos(igrid)%local_grid_id
01034
01035 #ifdef DEBUGX
01036 print *, 'grid shape', grid_valid_shape
01037 do i = 1, n_send
01038 print *, ibuf ((i-1)*len_item+1:i*len_item)
01039 end do
01040 #endif
01041
01042 if (Associated (grid_info%partition)) then
01043
01044
01045
01046 extra_msg%partition_avail = .true.
01047 extra_msg%partition(:) = grid_info%partition (1, 1:3)
01048
01049
01050
01051 if (grid_info%grid_type == PRISM_Gaussreduced_regvrt) then
01052
01053 call psmile_trans_loc2glob_gauss2 (grid_id, &
01054 ibuf, len_item, n_send, ierror)
01055
01056 else
01057
01058 call psmile_trans_loc2glob_3d (grid_id, &
01059 ibuf, len_item, n_send, ierror)
01060
01061 endif
01062
01063 if (ierror > 0) return
01064
01065 else
01066
01067
01068
01069 extra_msg%partition_avail = .false.
01070 endif
01071
01072 #ifdef DEBUG
01073 print *, ' Sending ', exttag, ' to destination ', dest
01074 #endif
01075 call psmile_pack_msg_extra (extra_msg, extra_msg_buf)
01076
01077 call psmile_bsend (extra_msg_buf, msg_extra_size, MPI_INTEGER, &
01078 dest, exttag, comm_psmile, ierror)
01079 if (ierror /= MPI_SUCCESS) then
01080 ierrp (1) = ierror
01081 ierrp (2) = dest
01082 ierrp (3) = exttag
01083
01084 ierror = PRISM_Error_Send
01085
01086 call psmile_error (ierror, 'psmile_bsend(msg)', &
01087 ierrp, 3, __FILE__, __LINE__ )
01088 return
01089 endif
01090
01091 #ifdef DEBUG
01092 print *, ' Sending ', exttag, ' to destination ', dest
01093 #endif
01094 call psmile_bsend (ibuf, len_ibuf, MPI_INTEGER, &
01095 dest, exttag, comm_psmile, ierror)
01096 if (ierror /= MPI_SUCCESS) then
01097 ierrp (1) = ierror
01098 ierrp (2) = dest
01099 ierrp (3) = exttag
01100
01101 ierror = PRISM_Error_Send
01102
01103 call psmile_error (ierror, 'psmile_bsend(ibuf)', &
01104 ierrp, 3, __FILE__, __LINE__ )
01105 return
01106 endif
01107
01108 #ifdef DEBUG
01109 print *, ' Sending ', exttag, ' to destination ', dest
01110 #endif
01111 call psmile_bsend (buf, len_rbuf, MPI_DOUBLE_PRECISION, &
01112 dest, exttag, comm_psmile, ierror)
01113 if (ierror /= MPI_SUCCESS) then
01114 ierrp (1) = ierror
01115 ierrp (2) = dest
01116 ierrp (3) = exttag
01117
01118 ierror = PRISM_Error_Send
01119
01120 call psmile_error (ierror, 'psmile_bsend(buf)', &
01121 ierrp, 3, __FILE__, __LINE__ )
01122 return
01123 endif
01124
01125
01126
01127
01128 if (n_recv_req == 1) then
01129
01130
01131
01132
01133
01134 call MPI_Irecv (answer, msg_extra_size, MPI_INTEGER, MPI_ANY_SOURCE, &
01135 rexttag, comm_psmile, recv_req, ierror)
01136 if (ierror /= MPI_SUCCESS) then
01137
01138 ierrp (1) = ierror
01139 ierrp (2) = dest
01140 ierrp (3) = rexttag
01141
01142 ierror = PRISM_Error_Recv
01143
01144 call psmile_error ( ierror, 'MPI_Irecv', &
01145 ierrp, 3, __FILE__, __LINE__ )
01146 return
01147
01148 endif
01149 endif
01150
01151 end do
01152
01153
01154
01155 Deallocate (send_mask, n_faces, faces, igrid_to_dest_comp)
01156
01157 if (ndrbuf > 0) Deallocate (buf)
01158 if (ndibuf > 0) Deallocate (ibuf)
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173 nprev_recv = 0
01174 nrecv = 0
01175
01176 if (n_recv_req > 0) then
01177 Allocate (extra_search%dble_bufs(n_recv_req), &
01178 send_info%sender_global(n_recv_req), &
01179 send_info%len_sent(n_recv_req), &
01180 send_info%msg_id(n_recv_req), &
01181 stat = ierror)
01182 if ( ierror > 0 ) then
01183 ierrp (1) = ierror
01184 ierrp (2) = n_recv_req
01185
01186 ierror = PRISM_Error_Alloc
01187 call psmile_error ( ierror, 'extra_search%dble_bufs', &
01188 ierrp, 2, __FILE__, __LINE__ )
01189 return
01190 endif
01191 endif
01192
01193 save_lreq (2:3) = paction%lrequest (2:3)
01194
01195 paction%lrequest (2) = MPI_REQUEST_NULL
01196
01197 do n = 1, n_recv_req
01198 paction%lrequest (3) = recv_req
01199
01200 index = 0
01201 do while (index /= 3)
01202 #ifdef DEBUG
01203 print *, trim(ch_id), ': psmile_global_search_dble: action%nreq, recv_req', &
01204 paction%nreq, recv_req
01205 call psmile_flushstd
01206 #endif
01207
01208 call MPI_Waitany (paction%nreq, paction%lrequest, index, status, ierror)
01209
01210 if ( ierror /= MPI_SUCCESS ) then
01211 ierrp (1) = ierror
01212 ierrp (2) = status (MPI_SOURCE)
01213 ierrp (3) = status (MPI_TAG)
01214
01215 ierror = PRISM_Error_MPI
01216
01217 call psmile_error ( ierror, 'MPI_Waitany', &
01218 ierrp, 3, __FILE__, __LINE__ )
01219 return
01220 endif
01221
01222 #ifdef PRISM_ASSERTION
01223 if (index == MPI_UNDEFINED) then
01224 call psmile_assert ( __FILE__, __LINE__, &
01225 'request list is empty')
01226 endif
01227 #endif
01228
01229 if (index /= 3) then
01230 call psmile_enddef_action (search, index, status, ierror)
01231 if (ierror > 0) return
01232 endif
01233 end do
01234
01235
01236
01237 sender = status (MPI_SOURCE)
01238 len_ibuf = answer (3)
01239 len_rbuf = answer (4)
01240
01241 #ifdef VERBOSE
01242 print 9960, trim(ch_id), sender, len_ibuf, len_rbuf
01243
01244 call psmile_flushstd
01245 #endif /* VERBOSE */
01246
01247 #ifdef PRISM_ASSERTION
01248 if (len_ibuf < 0) then
01249 print *, 'len_ibuf =', len_ibuf
01250 call psmile_assert (__FILE__, __LINE__, &
01251 "len_ibuf should be >= 0")
01252 endif
01253
01254 if (len_rbuf < 0) then
01255 print *, 'len_rbuf =', len_rbuf
01256 call psmile_assert (__FILE__, __LINE__, &
01257 "len_rbuf should be >= 0")
01258 endif
01259 #endif
01260
01261 if (len_ibuf > 0) then
01262 Allocate (ibuf (1:len_ibuf), stat = ierror)
01263
01264 if ( ierror > 0 ) then
01265 ierrp (1) = ierror
01266 ierrp (2) = len_ibuf
01267
01268 ierror = PRISM_Error_Alloc
01269 call psmile_error ( ierror, 'ibuf', &
01270 ierrp, 2, __FILE__, __LINE__ )
01271 return
01272 endif
01273
01274 call MPI_Recv (ibuf, len_ibuf, MPI_INTEGER, sender, &
01275 rexttag, comm_psmile, status, ierror)
01276 if (ierror /= MPI_SUCCESS) then
01277
01278 ierrp (1) = ierror
01279 ierrp (2) = sender
01280 ierrp (3) = rexttag
01281
01282 ierror = PRISM_Error_Recv
01283
01284 call psmile_error ( ierror, 'MPI_Recv(ibuf)', &
01285 ierrp, 3, __FILE__, __LINE__ )
01286 return
01287 endif
01288
01289 Allocate (buf (1:len_rbuf), stat = ierror)
01290
01291 if ( ierror > 0 ) then
01292 ierrp (1) = ierror
01293 ierrp (2) = len_rbuf
01294
01295 ierror = PRISM_Error_Alloc
01296 call psmile_error ( ierror, 'buf', &
01297 ierrp, 2, __FILE__, __LINE__ )
01298 return
01299 endif
01300
01301 call MPI_Recv (buf, len_rbuf, MPI_DOUBLE_PRECISION, sender, &
01302 rexttag, comm_psmile, status, ierror)
01303 if (ierror /= MPI_SUCCESS) then
01304
01305 ierrp (1) = ierror
01306 ierrp (2) = sender
01307 ierrp (3) = rexttag
01308
01309 ierror = PRISM_Error_Recv
01310
01311 call psmile_error ( ierror, 'MPI_Recv(rbuf)', &
01312 ierrp, 3, __FILE__, __LINE__ )
01313 return
01314 endif
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324 n_send = answer (7)
01325 n_liste = answer (8)
01326 n_found = answer (9)
01327 ireq = answer (15)
01328
01329 #ifdef PRISM_ASSERTION
01330 if (answer (1) /= interpolation_methods (interp)) then
01331 print *, 'answer(1)', answer (1), interpolation_methods (interp)
01332 call psmile_assert (__FILE__, __LINE__, &
01333 "incorrect message received ? interpolations doesn't fit")
01334 endif
01335
01336 if (ireq < 1 .or. ireq > n_recv_req) then
01337 print *, 'ireq, n_recv_req', ireq, n_recv_req
01338 call psmile_assert (__FILE__, __LINE__, &
01339 "ireq must be in range of 1:n_recv_req")
01340 endif
01341 #endif
01342
01343 nrecv = nrecv + 1
01344
01345 extra_search%dble_bufs (nrecv)%vector => buf
01346 send_info%sender_global (nrecv) = sender
01347 send_info%len_sent (nrecv) = n_liste
01348 send_info%msg_id (nrecv) = answer (16)
01349
01350 if (nprev_recv > 0) then
01351
01352
01353
01354 do i = 2*n_send+1, 2*n_send+n_found
01355 if (ibuf(i) /= masked_out) then
01356 ibuf (i) = ibuf (i) + nprev_recv
01357 endif
01358 end do
01359 endif
01360
01361 nprev_recv = nprev_recv + n_liste
01362
01363
01364
01365 call psmile_add_points_found (grid_id, search, extra_search, &
01366 ibuf (1:n_send), ibuf (n_send+1:2*n_send), &
01367 n_send, len_nsend(1:search%search_data%npart,ireq), &
01368 ibuf (2*n_send+1:2*n_send+n_found), n_found, &
01369 neighbors_3d, nloc, num_neigh, &
01370 grid_valid_shape, use_how, ierror)
01371 if (ierror > 0) return
01372
01373 Deallocate (ibuf)
01374 endif
01375
01376
01377
01378 if (n < n_recv_req) then
01379
01380
01381
01382
01383
01384 call MPI_Irecv (answer, msg_extra_size, MPI_INTEGER, MPI_ANY_SOURCE, &
01385 rexttag, comm_psmile, recv_req, &
01386 ierror)
01387 if (ierror /= MPI_SUCCESS) then
01388
01389 ierrp (1) = ierror
01390 ierrp (2) = dest
01391 ierrp (3) = rexttag
01392
01393 ierror = PRISM_Error_Recv
01394
01395 call psmile_error ( ierror, 'MPI_Irecv', &
01396 ierrp, 3, __FILE__, __LINE__ )
01397 return
01398 endif
01399 endif
01400 end do
01401
01402
01403
01404 #ifdef PRISM_ASSERTION
01405 if (paction%lrequest (2) /= MPI_REQUEST_NULL .or. &
01406 paction%lrequest (3) /= MPI_REQUEST_NULL) then
01407 print *, 'request: ', paction%lrequest (2:3)
01408 call psmile_assert ( __FILE__, __LINE__, &
01409 'Illegal request stored')
01410
01411 endif
01412 #endif
01413
01414 paction%lrequest (2:3) = save_lreq (2:3)
01415
01416 Deallocate (len_nsend)
01417
01418
01419
01420 send_info%nrecv = nrecv
01421 send_info%num2recv = nprev_recv
01422
01423 #ifdef PRISM_ASSERTION
01424 if (nrecv > 0) then
01425 if (send_info%num2recv /= SUM (send_info%len_sent(1:nrecv))) then
01426 print *, 'num2recv', send_info%num2recv, &
01427 SUM (send_info%len_sent(1:nrecv)), nrecv
01428 call psmile_assert (__FILE__, __LINE__, &
01429 "inconsistent num2recv")
01430 endif
01431 endif
01432 #endif
01433
01434
01435
01436
01437
01438 #ifdef VERBOSE
01439 print 9980, trim(ch_id), ierror
01440
01441 call psmile_flushstd
01442 #endif /* VERBOSE */
01443
01444
01445
01446
01447 #ifdef VERBOSE
01448
01449 9990 format (1x, a, ': psmile_global_search_dble: var_id', i3, &
01450 ' to ', i3, '(', i2, ')')
01451 9980 format (1x, a, ': psmile_global_search_dble: eof ierror =', i3)
01452 9970 format (1x, a, ': psmile_global_search_dble: send from', i3, &
01453 ' to', i3, '[', i3, '], n_send =', i6)
01454
01455 9960 format (1x, a, ': psmile_global_search_dble: got rexttag message:', &
01456 ' sender ', i4, ', len_ibuf, len_rbuf', 2i8)
01457 9950 format (1x, a, ': psmile_global_search_dble: before waitany :', &
01458 'nreq =', i4, ', recv_req ', i8)
01459 #endif /* VERBOSE */
01460
01461 #ifdef DEBUG
01462 #endif
01463
01464 end subroutine PSMILe_global_search_dble