psmile_global_search_dble.F90

Go to the documentation of this file.
00001 !-----------------------------------------------------------------------
00002 ! Copyright 2006-2010, NEC Europe Ltd., London, UK.
00003 ! All rights reserved. Use is subject to OASIS4 license terms.
00004 !-----------------------------------------------------------------------
00005 !BOP
00006 !
00007 ! !ROUTINE: PSMILe_global_search_dble
00008 !
00009 ! !INTERFACE:
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 ! !USES:
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 ! !INPUT PARAMETERS:
00038 
00039       Type (Enddef_comp), Intent (In) :: comp_info
00040 !
00041 !     Info on the component in which the donor cells
00042 !     should be searched.
00043 !
00044       Type (Enddef_search), Intent (InOut) :: search
00045 
00046 !     Info's on coordinates to be searched
00047 !
00048       Type (dble_vector), Intent (In) :: tgt_grid (ndim_3d)
00049 
00050 !     Coordinates to be searched
00051 
00052       Integer,            Intent (In) :: control (2, ndim_3d, search%search_data%npart)
00053 
00054 !     Index range found for partition "ipart".
00055 
00056       Integer,            Intent (In) :: len_cpl (search%search_data%npart)
00057 
00058 !     Number of points to be sent to the coupler for each partition.
00059 
00060       Integer,            Intent (In) :: var_id
00061 
00062 !     Handle to the grid function
00063 
00064       Integer,            Intent (In) :: grid_valid_shape (2, ndim_3d)
00065       
00066 !     Specifies the valid block shape for the "ndim_3d"-dimensional block
00067 
00068       Integer,            Intent (In) :: send_index
00069 
00070 !     Send index of coupler send for the method and coordinates
00071 !
00072       Integer,            Intent (In) :: nloc
00073 !
00074 !     Total  Number of locations to be transferred
00075 !
00076       Integer,            Intent (In) :: num_neigh
00077 !
00078 !     Last dimension of neighbors array "neighbors_3d" and
00079 !     number of neighbors to be searched.
00080 !     besser n_corners
00081 
00082       Integer,            Intent (In) :: n_intmethods
00083 !
00084 !     Number of interpolations methods used to interpolate the data.
00085 !     Dimension of vectors "interpolation_methods" and "interpolation_search".
00086 
00087       Integer,            Intent (In) :: interpolation_methods (n_intmethods)
00088 !
00089 !     Codes for the interpolation methods
00090 !
00091       Logical,            Intent (In) :: interpolation_search(n_intmethods)
00092 !
00093 !     Is global search required for corresponding interpolation method ?
00094 
00095       Logical,            Intent (In) :: mask_available
00096 !  !!!!! Fehlt da nicht noch ein "globales" mask_available !!!!
00097 !
00098       Logical,            Intent (In) :: use_mask
00099 
00100       Integer,            Intent (In) :: use_how
00101 
00102 !     Information about how to apply the mask
00103 
00104       Integer,            Intent (In) :: grid_type
00105 !
00106 !     Code for the type of grid generation
00107 !     PRISM_Reglonlatvrt            = Regular grid in all directions
00108 !     PRISM_Irrlonlat_regvrt        = Horizontal irregular, regular in the vertical
00109 !     PRISM_Irrlonlatvrt            = Irregular grid in all directions
00110 !     PRISM_Gaussreduced_regvrt     = Gaussian reduced grid with regular vertical
00111 !
00112 ! !INPUT/OUTPUT PARAMETERS:
00113 !
00114       Integer,            Intent (InOut) :: neighbors_3d (ndim_3d, nloc, 
00115                                                           num_neigh)
00116 
00117 !     Indices of neighbor locations (interpolation bases)
00118 !
00119       Type (Extra_search_info), Intent (InOut) :: extra_search
00120 !
00121 !     Number of locations where
00122 !       (*) required mask values were not true
00123 
00124 ! !OUTPUT PARAMETERS:
00125 !
00126       Integer,           Intent (Out) :: ierror
00127 
00128 !     Returns the error code of PSMILe_global_search_dble;
00129 !             ierror = 0 : No error
00130 !             ierror > 0 : Severe error
00131 !
00132 ! !LOCAL PARAMETERS
00133 !
00134 !  NC_REG = Number of corners for regular directions
00135 !  masked_out = Hash value for a point which is masked out
00136 !
00137       Double Precision, Parameter  :: eps = 0.0d0
00138 !
00139       Integer, Parameter           :: nc_reg = 2
00140       Integer, Parameter           :: masked_out = 0
00141 
00142 !
00143 ! !LOCAL VARIABLES
00144 !
00145 !     ... Method pointer
00146 !
00147       Integer                         :: comp_id, method_id
00148       Type (Method), Pointer          :: mp
00149 !
00150       Type (Corner_Block), Pointer    :: corner_pointer
00151 !
00152 !     ... for the grid
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 !     ... Info's on actual component
00162 !
00163       Integer                         :: rank, igrid
00164 
00165 !
00166 !     ... lookup table
00167 !
00168       Integer, allocatable            :: igrid_to_dest_comp(:)
00169 !
00170 !     ... loop variables
00171 !
00172       Integer                         :: ipart, j, n
00173 !
00174 !     ... for data on faces to other processes
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 !     ... transformed faces
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 !     ... for points found
00196 !
00197       Integer                         :: n_found, n_liste
00198 !
00199 !     ... for send to partners
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 !     ... for communication
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 !     ... for error handling
00229 !
00230       Integer, parameter              :: nerrp = 3
00231       Integer                         :: ierrp (nerrp)
00232 !
00233 ! !DESCRIPTION:
00234 !
00235 ! Subroutine "PSMILe_global_search_dble" performs a global search
00236 ! for the interpolation points not found in the local search.
00237 !
00238 ! TODO: tgt_grid statt coords uebergeben;
00239 !       kann man sich dann die unterschiedlichen Routine fuer
00240 !       Get_faces_..., store_faces__ sparen !?!?
00241 !
00242 ! !REVISION HISTORY:
00243 !
00244 !   Date      Programmer   Description
00245 ! ----------  ----------   -----------
00246 ! 11.11.04    H. Ritzdorf  created
00247 ! 06.04.10    M. Hanke     adjusted in order to support multiple
00248 !                          local grid id's for a single global grid id
00249 !
00250 !EOP
00251 !----------------------------------------------------------------------
00252 !
00253 !  $Id: psmile_global_search_dble.F90 3174 2011-05-04 09:41:43Z hanke $
00254 !  $Author: hanke $
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 !  Initialization
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 ! Uebergeben oder ein-dimensional
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 ! nicht uebergeben !
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 !  Rank of actual process in Component communicator
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 ! Can man die offset und partition information ausnutzen ?
00336 !
00337 !===> Allocate work vectors
00338 !
00339 !  n_faces = Number of block faces on which cell/control volume "i" is
00340 !            located.
00341 !  !!! n_faces wieder raus !!!
00342 !  faces   = Range on block faces which interfere with faces of
00343 !            cell/control volume "i".
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 !===> Get number of faces and intersection with block boundary
00384 !     for each cell to be searched
00385 !
00386 !  len_item = Number of pieces of information
00387 !             in integer buffer "ibuf"
00388 !             ibuf(1:3) = srcloc of extra point
00389 !                     (index of lower left corner)
00390 !             ibuf(4)   = Index of the extra point to be searched
00391 !                         This is a local index in the vectors
00392 !                         "required" and "indices_req" of the actual
00393 !                         partition "ipart".
00394 !             ibuf(5)   = Code for interpolation bases required
00395 !             ibuf(6)   = Virtual cell info (Only GaussReduced)
00396 !             TODO: ibuf (4, *) raus
00397 !  len_rtem = Number of pieces of information
00398 !             per point in Double Precison buffer "rbuf"
00399 !
00400 ! Ausserdem sollte man mehrfache srclocs rausfiltern
00401 !
00402       nx = nreq ! oder weniger, wenn nicht alle
00403                 ! cellen gesucht werden sollen
00404       len_item = ndim_3d + 2 ! default
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 !===> Get range of faces and transform range into cyclic range
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 !     create lookup table for translating igrid into a icomp
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 !===> Control extents of other domains in order to find partner
00530 !
00531 ! igrid = current grid
00532 !
00533 !     loop over all grids/blocks (local and remote ones)
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 !        if current block is not part of the same global grid
00544          if (global_grid_id /= comp_info%all_extent_infos(igrid)%global_grid_id) cycle
00545 !
00546 !        if the current block is the one we are doing the global search for
00547 !        (note ranks start with 0, ...)
00548          if (rank == dest_comp-1 .and. &
00549                comp_info%all_extent_infos(igrid)%local_grid_id == grid_id) cycle
00550 !
00551 !===> ... Does the "igrid"-th grid and the range of faces coincide ?
00552 !
00553 !  n_int = Number of significant intersections
00554 !
00555 !cdir vector
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             ! in addition to the intersections we need to check whether the grid
00564             ! extent and the transformed face range has a common face at the
00565             ! common_grid_range boundaries (normally at -180/180)
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                ! set dummy data
00581                dinter (1,:,i+n_trans) = 0
00582                dinter (2,:,i+n_trans) = -1
00583             endif
00584          end do ! i = 1, n_trans
00585 !
00586          n_int = 0
00587 !cdir vector
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 !===> ... Transform intersections back into original range
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 !===> ... Get control volumes which
00610 !         have intersection with the extent of the "n"-th grid
00611 !???  What about cyclic boundaries ????
00612 !???  use global offsets here !
00613 !
00614          do i = 1, n_int
00615 #ifdef DEBUGX
00616             print *, 'extent controlled', i, n_int, dinter(:,:,found(i))
00617 #endif
00618 !cdir vector
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 ! j
00631          end do ! i
00632 !
00633 !===> ... Get number of points to be sent
00634 !
00635          n_send = COUNT(send_mask)
00636          if (n_send == 0) cycle
00637 !
00638          mask_changed = .true.
00639 !
00640 !===> ... A grid of process "dest_comp" is a potential partner
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 !           Reallocate len_nsend
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 !===> ... Allocate send buffers
00675 !
00676 !  cf. subroutine PSMILe_Store_faces_3d_reg_dble
00677 !
00678 !  Double precision vector buf (1:ndrbuf):
00679 !  buf (:) = Coordinates of the point to be searched
00680 !            ndim_3d data items
00681 !  buf (:) = Coordinates of corners of control volume/cell
00682 !            "len_rtem" data items
00683 !
00684 !  Integer buffer ibuf (1:ndibuf):
00685 !
00686 !  ibuf (:) = srcloc of extra point
00687 !             ndim_3d data items
00688 !  ibuf (:) = Index of the extra point to be searched
00689 !             1       data items
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 !===> Get Indices (in srclocs) of points to be sent
00733 !     TODO: Direkt in ibuf speichern !
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 ! das wurde fuer die alten Gaussreduced Gird (vor virtual_cell info)
00772 ! gebraucht; derzeit noch drin wg. conservative
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 !===> Store data in send buffers
00806 !     ??? compact machen !?!?
00807 !         Mehrfache Zellen Info's in ibuf und corner volumen
00808 !         eliminieren ?
00809 !     TODO: ipi und ip wieder vereinigen
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 ! TODO: If dest_comp == rank, direct call of psmile_search_donor_extra()
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 !===> ... Send request to destination process
01013 !         extra_msg is received by routine PSMILe_Enddef_extra and
01014 !         the other buffer are received by routine
01015 !         PSMILe_Enddef_action_extra.
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 !           First dimension: Blocks
01044 !           Last  dimension: Global indices of partition
01045 !
01046             extra_msg%partition_avail = .true.
01047             extra_msg%partition(:)    = grid_info%partition (1, 1:3)
01048 !
01049 !===> ... Transfer local coordinates into global coordinates
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 !           ... No partition info
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 !===> ... Setup request for answer of destination process
01126 !         ??? wirklich; sollte wohl von dem normalen abgehandelt werden
01127 !
01128          if (n_recv_req == 1) then
01129             ! MoHa: Be carefull even though this message uses rexttag and the size
01130             ! msg_extra_size it does not contain the same information as
01131             ! enddef_msg_extra! This messages is sent by psmile_return_extra_off.
01132             ! There is no documentation on the exact content of this message!
01133             ! (From my point of view, this is "no good" programming style.)
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 ! igrid
01152 !
01153 !===> Deallocate
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 !     Wait for answers
01162 !      Note: (2) Message from a partner with an intersection is disabled
01163 !                since request for grid receive (lrequest (3)) is setup
01164 !                if such a message is found.
01165 !            ??? Koennte man enablen wenn lrequest(3) == MPI_REQUEST_NULL
01166 !            (3) Old receive of grid data (paction%lrequest (3)) is disabled
01167 !-------------------------------------------------------------------------
01168 !
01169 ! nrecv      = Number of significant messages received
01170 ! nprev_recv = Number of data items (per coordinate) received
01171 !              in prevoius receives.
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 ! while
01234 !
01235 !===> ... Get 
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 ! n_send  = Number of cells to be searched
01319 ! n_found = Number of interpolation bases found
01320 ! n_liste = Number of data items to be used for interpolation
01321 !           n_liste <= n_found since a data item can be used
01322 !           multiply for interpolation.
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 !              Increment index_found (for collected list of buf's)
01352 !              except for point masked out
01353 !cdir vector
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 !===> ... Add information on points found by global search 
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 !===> ... Setup new request
01377 !
01378          if (n < n_recv_req) then
01379             ! MoHa: Be carefull even though this message uses rexttag and the size
01380             ! msg_extra_size it does not contain the same information as
01381             ! enddef_msg_extra! This messages is sent by psmile_return_extra_off.
01382             ! There is no documentation on the exact content of this message!
01383             ! (From my point of view, this is "no good" programming style.)
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 !    ... Restore original requests (2:3)
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 !===> Save number of data to be received in "extra_search"
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 !===> All done
01436 !-------------------------------------------------------------------------
01437 !
01438 #ifdef VERBOSE
01439       print 9980, trim(ch_id), ierror
01440 
01441       call psmile_flushstd
01442 #endif /* VERBOSE */
01443 !
01444 !  Formats:
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

Generated on 1 Dec 2011 for Oasis4 by  doxygen 1.6.1