psmile_find_intersect.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_Find_Intersect
00008 !
00009 ! !INTERFACE:
00010 
00011       subroutine psmile_find_intersect (comp_info, global_index,     &
00012                                         num_intersect_per_grid,      &
00013                                         num_dummy_intersect_per_grid,&
00014                                         ninter, nmyint, nnull,       &
00015                                         lastag, ierror)
00016 !
00017 ! !USES:
00018 !
00019       use PRISM_constants
00020 !
00021       use psmile_grid, only : psmile_transform_extent_back, &
00022                               code_no_trans
00023 !
00024       use PSMILe, dummy_interface => PSMILe_Find_intersect
00025       use psmile_common, only : enddef_msg_intersections
00026 
00027       implicit none
00028 !
00029 ! !INPUT PARAMETERS:
00030 !
00031       Integer, Intent (In)               :: global_index
00032 
00033 !     Index of current comp_info in all_comp_infos (:)
00034 !
00035       Integer, Intent (In)               :: lastag
00036 
00037       Integer, Intent (InOut)            :: num_intersect_per_grid(:), 
00038                                             num_dummy_intersect_per_grid(:)
00039 
00040 !     Message tag to be used
00041 !
00042 ! !INPUT/OUTPUT PARAMETERS:
00043 !
00044       Type (Enddef_comp), Intent (InOut) :: comp_info
00045 
00046 !     Info on the component (located on the actual process)
00047 !     for which the intersections should be found.
00048 !
00049       Integer, Intent (InOut)           :: ninter
00050 
00051 !     Contains total number of intersections found for the
00052 !     actual process.
00053 
00054       Integer, Intent (InOut)           :: nmyint
00055 
00056 !     Contains total number of intersections found which are located
00057 !     also on the actual process.
00058 
00059       Integer, Intent (InOut)           :: nnull
00060 
00061 !     Contains total number of dummy (empty) intersections found
00062 !     which were sent to a destination process
00063 !
00064 ! !OUTPUT PARAMETERS:
00065 !
00066       Integer, Intent (Out)             :: ierror
00067 
00068 !     Returns the error code of PSMILe_Find_intersect;
00069 !             ierror = 0 : No error
00070 !             ierror > 0 : Severe error
00071 !
00072 ! !LOCAL VARIABLES
00073 !
00074 !  ... for components
00075 
00076       integer                         :: local_comp_id
00077 !     local comp id of component currently processed by psmile_find_intersect
00078       integer                         :: global_comp_id
00079 !     global comp id of component currently processed by psmile_find_intersect
00080       integer                         :: rank
00081 !     rank of this process in comm_psmile
00082       integer                         :: icomp
00083 !     loop variable for processing all collected component information
00084       type(enddef_comp), pointer      :: icomp_info
00085 !     pointer to component information currently checked agains comp_info
00086 
00087 !  ... for grids
00088 !  ... Note: mg_gen and range are currently dimensioned with
00089 !            Number_of_Grids_allocated. This could be decreased to the
00090 !            range of grid id's which are used for coupling.
00091 
00092       integer                         :: grid_id, grid_type, extent_id
00093       integer                         :: inum_total_extents
00094 !     number of extents in the currently checked component
00095       integer                         :: local_extents_range(2)
00096       integer                         :: local_grid_extents_range(2)
00097       integer                         :: jglob, jbeg, jend, n
00098       integer                         :: max_num_grids_per_comp
00099       integer                         :: global_dest_grid_id
00100 
00101       logical                         :: mg_gen (Number_of_Grids_allocated)
00102 
00103 !  ... for methods
00104 
00105       integer                         :: m, method_id, n_meths
00106       integer                         :: poss_meths (Number_of_Methods_allocated)
00107 
00108 !  ... for fields
00109 
00110       Integer                         :: ibeg, n_in_fields, n_out_fields
00111       Integer                         :: var_id, n_vars
00112       Integer                         :: poss_fields (Number_of_Fields_allocated)
00113       Type (ch_ptr), pointer          :: In_channel(:)
00114 
00115 !  ... for masks
00116 
00117       Integer                         :: defined, last_maskid
00118 
00119 !  ... for intersections
00120 
00121       Integer                         :: nbr_blocks
00122       Integer                         :: extent
00123       Integer                         :: idim(ndim_3d)
00124       Integer                         :: offset(ndim_3d)
00125       Integer                         :: addoffset(ndim_3d)
00126       Integer                         :: i, j, jj, jglob0
00127       Integer                         :: nb, ng, nl, npart, npartg
00128       Integer                         :: num_intersect, num_intersect_allocated
00129       Double Precision                :: transformed (2, ndim_3d)
00130       Integer                         :: range (2, ndim_3d, Number_of_Grids_allocated)
00131       Double Precision, Allocatable   :: dinter (:, :, :)
00132       Integer, Allocatable            :: inters      (:, :, :)
00133       Integer, Allocatable            :: inters_save (:, :, :)
00134       Integer, Allocatable            :: ids (:, :)
00135       Integer, Allocatable            :: found (:)
00136       Integer, Allocatable            :: buffer (:)
00137 !
00138       Type (enddef_field_info)        :: field_list (Number_of_Fields_allocated), 
00139                                          tmp_field_list (Number_of_Fields_allocated)
00140       Integer                         :: field_list_buf(nd_field_list, 
00141                                                         Number_of_Fields_allocated)
00142 
00143       Integer                         :: expand
00144 
00145 !  ... for messages containing intersections
00146 
00147       Integer                         :: ip
00148       Integer                         :: msgint  (nd_msgint)
00149       type (enddef_msg_intersections) :: msg_intersections
00150 
00151 !  ... for communication
00152 
00153       Integer                         :: dest
00154 
00155 !  ... for error parameters
00156 
00157       integer, parameter              :: nerrp = 3
00158       integer                         :: ierrp (nerrp)
00159 !
00160 ! !DESCRIPTION:
00161 !
00162 ! Subroutine "PSMILe_Find_intersect" looks for the intersections
00163 ! of the own grids with the grids of other components and
00164 ! sends the partner data on the extension of the intersection.
00165 !
00166 ! Doxygen documentation (requires mscgen tool)
00167 !> \file psmile_find_intersect.F90
00168 !! General overview on tasks performed and messages sent in this routine:\n
00169 !! \msc
00170 !!   # entities
00171 !!   Target,Source;
00172 !!   ||| ;
00173 !!   Target rbox Source [label="compute extents"] ;
00174 !!   Target rbox Source [label="exchange extents"] ;
00175 !!   Target rbox Target [label="find intersection"] ;
00176 !!   Target=>Source [label = "send intersection (lasttag(100) reqidx(2))"] ;
00177 !! \endmsc
00178 !<
00179 ! !REVISION HISTORY:
00180 !
00181 !   Date      Programmer   Description
00182 ! ----------  ----------   -----------
00183 ! 03.01.04    H. Ritzdorf  created
00184 !
00185 !EOP
00186 !----------------------------------------------------------------------
00187 !
00188 ! $Id: psmile_find_intersect.F90 3248 2011-06-23 13:03:19Z coquart $
00189 ! $Author: coquart $
00190 !
00191    Character(len=len_cvs_string), save :: mycvs = 
00192        '$Id: psmile_find_intersect.F90 3248 2011-06-23 13:03:19Z coquart $'
00193 !
00194 !----------------------------------------------------------------------
00195 !
00196 !WARNING: Workaround
00197 !
00198       double precision             :: tol = 1d-6 ! needs to be an argument
00199 
00200 #ifdef VERBOSE
00201       print 9990, trim(ch_id), comp_info%comp_id, comp_info%global_comp_id
00202 
00203       call psmile_flushstd
00204 #endif /* VERBOSE */
00205 !
00206 !  Initialization
00207 !
00208       ierror = 0
00209       call psmile_init_enddef_msg_inters (msg_intersections)
00210 !
00211       local_comp_id  = comp_info%comp_id
00212       global_comp_id = comp_info%global_comp_id
00213       rank           = Comps(local_comp_id)%rank
00214 !
00215 !     local_extents_range: index range for comp_info%all_extent_infos in which
00216 !                          the extents of the local process can be found
00217 !
00218       local_extents_range(1) = SUM (comp_info%Number_of_grids_vector(1:rank)) + 1
00219       local_extents_range(2) = local_extents_range(1) + comp_info%Number_of_grids_vector(rank+1) - 1
00220 !
00221 !      mg_gen : Does multigrid sequence have to be generated for grid "grid_id" ?
00222 !               mg_gen  = .false. : Multigrid sequence need not be generated
00223 !              ? ndlev (igrid) > 0 ? Number of possible grids
00224 !
00225       mg_gen (:) = .false.
00226 !
00227       num_intersect_allocated = 0
00228 !
00229 !===> Get maximal number of extents per component for all collected components
00230 !
00231       max_num_grids_per_comp = 0
00232       do icomp = 1, Number_of_coll_comps
00233          max_num_grids_per_comp = max (max_num_grids_per_comp, &
00234              SUM(all_comp_infos(icomp)%Number_of_grids_vector(1:all_comp_infos(icomp)%size)) )
00235       end do
00236 !
00237 !===> Allocate found vector
00238 !
00239       Allocate (found (1:max_num_grids_per_comp), stat = ierror)
00240       if (ierror > 0) then
00241 
00242          call psmile_error ( PRISM_Error_Alloc, 'found', &
00243                              (/ierror, max_num_grids_per_comp/), &
00244                              2, __FILE__, __LINE__ )
00245          return
00246       endif
00247 !
00248 !===> For all collected components
00249 !
00250       do icomp = 1, Number_of_coll_comps
00251 
00252          icomp_info => all_comp_infos(icomp)
00253 
00254 #ifdef DEBUG
00255          print *, "testing comp: ", icomp, " of ", Number_of_coll_comps, &
00256                   " (global comp_id ", icomp_info%global_comp_id, ")"
00257 #endif /* DEBUG */
00258          ! if the currently checked component information matches comp_info or
00259          ! if both components are not coupled, then we can skip this component
00260          if (global_comp_id == icomp_info%global_comp_id .or. &
00261              .not. psmile_to_be_coupled (global_comp_id, icomp_info%global_comp_id) ) cycle
00262 !
00263 !-----------------------------------------------------------------------
00264 !       Loop over all parts of grids
00265 ! Tol ? um extents
00266 !-----------------------------------------------------------------------
00267 !
00268 !  inum_total_extents = Total number of extents in component "icomp"
00269 !
00270          inum_total_extents = SUM(icomp_info%Number_of_grids_vector(1:icomp_info%size))
00271 !
00272          ! get the start index of the first grid of the current component
00273          local_grid_extents_range(1) = local_extents_range(1)
00274 !
00275 !        for all grids
00276          do while (local_grid_extents_range(1) <= local_extents_range(2))
00277             grid_id = comp_info%all_extent_infos(local_grid_extents_range(1))%local_grid_id
00278             grid_type = Grids(grid_id)%grid_type
00279 !
00280 #ifdef PRISM_ASSERTION
00281             if (grid_type /= comp_info%all_extent_infos(local_grid_extents_range(1))%grid_type) then
00282                print *, "grid_id, grid_type, comp_info%all_extent_infos%grid_type", &
00283                          grid_id, grid_type, comp_info%all_extent_infos(local_grid_extents_range(1))%grid_type
00284                call psmile_assert (__FILE__, __LINE__, &
00285                                    "Inconsistent grid type for grid grid_id")
00286             endif
00287 #endif
00288 !
00289 !===> ... Get index range of local extents of this grid
00290 !
00291             local_grid_extents_range(2) = local_grid_extents_range(1)
00292             do while (local_grid_extents_range(2) < local_extents_range(2))
00293                if (comp_info%all_extent_infos(local_grid_extents_range(2)+1)%local_grid_id /= grid_id) exit
00294                local_grid_extents_range(2) = local_grid_extents_range(2) + 1
00295             enddo
00296 !
00297 ! ... Look for an intersection of currently processed grid of actual component
00298 !                  with a grid of icomp-th component
00299 !
00300             found (1:inum_total_extents) = 0
00301 !
00302 !             do i = local_grid_extents_range(1), local_grid_extents_range(2)
00303             do i = local_grid_extents_range(1), local_grid_extents_range(2)
00304 !cdir vector
00305                ! for all extents of the other component (prism_gridless
00306                ! grids can only be coupled among themselves)
00307                do j = 1, inum_total_extents
00308                   if (grid_types_are_compatible(grid_type,                 &
00309                       icomp_info%all_extent_infos(j)%grid_type)      .and. &
00310                        comp_info%all_extent_infos(i)%extent(1, 1) <=       &
00311                       icomp_info%all_extent_infos(j)%extent(2, 1)    .and. &
00312                        comp_info%all_extent_infos(i)%extent(2, 1) >=       &
00313                       icomp_info%all_extent_infos(j)%extent(1, 1)    .and. &
00314                        comp_info%all_extent_infos(i)%extent(1, 2) <=       &
00315                       icomp_info%all_extent_infos(j)%extent(2, 2)    .and. &
00316                        comp_info%all_extent_infos(i)%extent(2, 2) >=       &
00317                       icomp_info%all_extent_infos(j)%extent(1, 2)    .and. &
00318                        comp_info%all_extent_infos(i)%extent(1, 3) <=       &
00319                       icomp_info%all_extent_infos(j)%extent(2, 3)    .and. &
00320                        comp_info%all_extent_infos(i)%extent(2, 3) >=       &
00321                       icomp_info%all_extent_infos(j)%extent(1, 3)) then
00322                      found (j) = found (j) + 1
00323 #ifdef DEBUG
00324                      print *, "extents intersect"
00325                      print "(a,6(' ',e13.6))", " local extent :", &
00326                         comp_info%all_extent_infos(i)%extent
00327                      print "(a,6(' ',e13.6))", " remote extent:", &
00328                         icomp_info%all_extent_infos(j)%extent
00329 #endif
00330                   endif
00331                end do ! j
00332             end do ! i
00333 #ifdef DEBUG
00334             print *, "-----------------------------------------------------"
00335 #endif
00336 !
00337 !===> Get total number of intersections
00338 !
00339             num_intersect = sum (found (1:inum_total_extents))
00340             if (num_intersect == 0) then
00341 !              ... no intersection found for grids local_grid_extents_range(1:2)
00342 !              => set start index of next grid range
00343                local_grid_extents_range(1) = local_grid_extents_range(2) + 1
00344                cycle ! do while (local_grid_extents_range(1) <= local_extents_range(2))
00345             endif
00346 !
00347 !===> Re-allocate working vectors "dinter, inters, ids, inters_save" if necessary
00348 !
00349             if (num_intersect > num_intersect_allocated) then
00350 
00351                if (num_intersect_allocated > 0) &
00352                   Deallocate (dinter, inters, ids, inters_save)
00353 !
00354                Allocate (dinter      (2, ndim_3d, num_intersect+1), &
00355                          inters      (2, ndim_3d, num_intersect),   &
00356                          inters_save (2, ndim_3d, num_intersect),   &
00357                          ids (num_intersect, 2), stat = ierror)
00358                if (ierror /= 0) then
00359                   call psmile_error (                                                &
00360                      PRISM_Error_Alloc, 'dinter,inters,ids, inters_save',            &
00361                      (/ierror, 3*(2*ndim_3d*(num_intersect+1))+num_intersect*2/), 2, &
00362                      __FILE__, __LINE__ )
00363                   return
00364                endif
00365                num_intersect_allocated = num_intersect
00366             endif
00367 !
00368 !===> ... Get list of methods id's which may be used for coupling.
00369 !
00370 !  n_in_fields  = Number of input  fields for this grid;
00371 !                 i.e. number of fields which receive data from
00372 !                      other applications.
00373 !  n_out_fields = Number of output fields for this grid;
00374 !                 i.e. number of fields for which data of other
00375 !                      applications must be searched and interpolated.
00376 !
00377             n_in_fields = 0
00378             n_out_fields = 0
00379             n_meths = 0
00380 !
00381 !cdir vector
00382             if (Grids(grid_id)%comp_id == local_comp_id) then
00383                do i = 1, Number_of_Methods_allocated
00384                   if (Methods(i)%grid_id == grid_id               .and. &
00385                      Methods(i)%status  == PSMILe_status_defined .and. &
00386                      Methods(i)%used_for_coupling ) then
00387                      n_meths = n_meths + 1
00388                      poss_meths (n_meths) = i
00389                   endif
00390                end do
00391             endif
00392 !
00393             if (n_meths == 0) then
00394 !                 Grid is not used for coupling
00395 !                 test before !!
00396 !                 Not so easy, as the Grid can be used as Taskout grid only
00397 #ifdef DEBUG
00398                print *, "n_meths ", n_meths
00399                write (*, 9960) trim(ch_id), local_comp_id, grid_id
00400 #endif /* DEBUG */
00401             endif
00402 !
00403 !===> ... Get list of input fields of grid "grid_id"
00404 !         which may be used for coupling
00405 !         (*) Look for a input field of component "local_comp_id" and grid "grid_id"
00406 !             which is used for coupling
00407 !         (*) Control whether this input field has to get data from component
00408 !             "icomp_info%local_comp_id"
00409 !             TODO: ?? Could we also check the Grid ID ?
00410 !                   ?? This is not contained in structure ch_ptr ! ?
00411 !
00412             if (n_meths > 0) then
00413 !cdir vector
00414                do i = 1, Number_of_Fields_allocated
00415                   if (Fields(i)%status  == PSMILe_status_defined) then
00416                      if ( Fields(i)%comp_id == local_comp_id                    .and. &
00417                         Methods(Fields(i)%method_id)%grid_id == grid_id .and. &
00418                         Fields(i)%used_for_coupling ) then
00419 
00420                         IF ( ASSOCIATED(Fields(i)%Taskin%In_channel) ) THEN
00421                             DO j = 1, SIZE(Fields(i)%Taskin%In_channel)
00422                               IF (Fields(i)%Taskin%In_channel(j)%remote_comp_id == &
00423                                  all_comp_infos(icomp)%global_comp_id ) THEN
00424                                   n_in_fields = n_in_fields + 1
00425                                   poss_fields (n_in_fields) = i
00426                               ENDIF
00427                             ENDDO
00428                         ENDIF
00429 !===>   Get number of output fields
00430                         if ( Associated(Fields(i)%Taskout) ) then
00431                             DO j = 1, SIZE(Fields(i)%Taskout)
00432                               IF (Fields(i)%Taskout(j)%remote_comp_id == &
00433                                  all_comp_infos(icomp)%global_comp_id ) THEN
00434                                   n_out_fields = n_out_fields + 1
00435                               ENDIF
00436                             ENDDO
00437                         endif
00438 
00439                      endif
00440                   endif
00441                enddo
00442 !
00443 #ifdef DEBUG
00444                if (n_in_fields + n_out_fields == 0) then
00445 !                 Grid is not used for coupling
00446 !                 test before !!
00447                   print *, "n_in_fields, n_out_fields ", n_in_fields, n_out_fields
00448                   write (*, 9960) trim(ch_id), local_comp_id, grid_id
00449                endif
00450 #endif /* DEBUG */
00451             endif
00452 !
00453 !===>
00454 !
00455             jbeg = 1
00456 
00457             do while ( jbeg <= inum_total_extents )
00458 !
00459                do jglob = jbeg, inum_total_extents
00460                   if (found (jglob) > 0) exit
00461                end do
00462 !
00463                if (jglob > inum_total_extents) exit
00464 !
00465 !===> ... non empty intersection between local grids "local_grid_extents_range(1:2)" and
00466 !                                        global grid "jglob" found
00467 !
00468 !===> ... Get destination process in communicator comm_psmile
00469 !         !!! We need something better !!!
00470 !
00471                n = 0
00472 !cdir vector
00473                do i = 1, icomp_info%size
00474                   if (jglob <= n+icomp_info%Number_of_grids_vector(i)) exit
00475                   n = n + icomp_info%Number_of_grids_vector(i)
00476                end do
00477 
00478                if (i > icomp_info%size) then
00479                   ierror = PRISM_Error_Internal
00480                   ierrp (1) = icomp
00481                   ierrp (2) = icomp_info%size
00482                   call psmile_error (ierror, "Cannot find grid", ierrp, 2, &
00483                                      __FILE__, __LINE__)
00484                   return
00485                endif
00486 !
00487                dest = icomp_info%psmile_ranks(i)
00488                jend = n + icomp_info%Number_of_grids_vector(i)
00489 !
00490 !===> ... Get number of (logical) partitions of global grid "jglob"
00491 !         (cf. psmile_enddef_comp.F90)
00492 !
00493                extent_id = icomp_info%all_extent_infos(jglob)%local_grid_id
00494 !
00495                do jbeg = jglob+1, jend
00496                   if (icomp_info%all_extent_infos(jbeg)%local_grid_id /= &
00497                       extent_id) exit
00498                end do
00499 !
00500                if (n_in_fields + n_out_fields == 0) then
00501                   npart = 0
00502                   go to 1000
00503                endif
00504 !
00505                npartg = jbeg - jglob
00506                jglob0 = jglob - 1
00507 !
00508                global_dest_grid_id = icomp_info%all_extent_infos(jglob)%global_grid_id
00509 !
00510 !===> ... Determine intersections
00511 ! minval > 0 leads to problems for 2d intersections
00512 ! therefore minval >= 0
00513 !
00514                n = 0
00515                do ng = 1, npartg
00516                   if (found (jglob0+ng) > 0) then
00517                      do i = local_grid_extents_range(1), local_grid_extents_range(2)
00518                         dinter (1,:, n+1) = max ( &
00519                                comp_info%all_extent_infos(i)%extent(1,:), &
00520                               icomp_info%all_extent_infos(jglob0+ng)%extent(1,:))
00521                         dinter (2,:, n+1) = min ( &
00522                                comp_info%all_extent_infos(i)%extent(2,:), &
00523                               icomp_info%all_extent_infos(jglob0+ng)%extent(2,:))
00524 
00525                         if (minval (dinter (2,:, n+1) - dinter (1,:, n+1)) >= 0.0d0) then
00526 !
00527                            n = n + 1
00528                            ids (n, 1) = i
00529                            ids (n, 2) = jglob0 + ng
00530 #ifdef DEBUG
00531                            print "(a,6(' ',e13.6))", "local extent :", &
00532                               comp_info%all_extent_infos(i)%extent(:,:)
00533                            print "(a,6(' ',e13.6))", "remote extent:", &
00534                               icomp_info%all_extent_infos(jglob0+ng)%extent(:,:)
00535                            print "(a,6(e13.6,' '))", "intersection: ", dinter (:,:, n)
00536 #endif
00537                         endif
00538                      end do !  i = local_grid_extents_range(1), local_grid_extents_range(2)
00539                   endif
00540                end do ! npartg
00541 !
00542 #ifdef PRISM_ASSERTION
00543                if (n > num_intersect) then
00544                   print *, 'n, num_intersect', n, num_intersect
00545                   call psmile_assert (__FILE__, __LINE__, 'n > num_intersect !')
00546                endif
00547 #endif
00548                npart = n
00549 !
00550 !===> ...  Transfer intersection of grid "grid_id" (igrid) back if necessary.
00551 !
00552                do n = 1, npart
00553                   if (comp_info%all_extent_infos(ids(n,1))%tr_code /= code_no_trans) then
00554                      call psmile_transform_extent_back ( &
00555                            (/comp_info%all_extent_infos(ids(n,1))%tr_code/), &
00556                            dinter(:, :, n), transformed, 1, ierror)
00557                      if ( ierror /= 0 ) return
00558                      dinter (:, :, n)  = transformed
00559 #ifdef DEBUG
00560                      print "(a,6(e13.6,' '),a)", "intersection: ", dinter (:,:, n), " (transformed)"
00561 #endif
00562                      endif
00563                end do
00564 !
00565 !===> ... Determine sub range of intersection "dinter" using grid coordinates
00566 !
00567 !  ?!? What about 8 subregions, and if we only send those subregions,
00568 !  which have an intersection ?!?!
00569 !
00570                if (grid_type == PRISM_Gridless) then
00571 !
00572 !===> ........... Gridless grid
00573 !                 Note: Initially, the send and receive areas should
00574 !                 be locally at this place. Since masks can be
00575 !                 assigned to gridless grids, the data on gridless
00576 !                 grids is sent as usual to the counterpart.
00577 !                 TODO: Send data only if masks are used on any process.
00578 !
00579                   inters (:, :, 1:npart) = nint (dinter (:, :, 1:npart))
00580 
00581                   inters_save = inters
00582 !
00583 !                 Transform intersection into local indices (move into a new subroutine)
00584 !                 ToDo: move into a new subroutine:
00585 !
00586 !                     functionality required by
00587 !                     - psmile_find_intersect
00588 !                     - psmile_search_donor_gridless
00589 !                     - psmile_get_locations_3d
00590 !
00591                   if (Associated (Grids(grid_id)%partition)) then
00592 
00593                      nbr_blocks = size(Grids(grid_id)%partition(:,1))
00594 
00595                      if ( nbr_blocks > 1 ) then
00596 
00597                         do n = 1, npart
00598 
00599                            ! find correct block
00600 
00601                            do nb = 1, nbr_blocks
00602 
00603                               if ( inters(2,1,n) >= Grids(grid_id)%partition(nb,1) + 1 .and. &
00604                                    inters(1,1,n) <= Grids(grid_id)%partition(nb,1) +         &
00605                                                     Grids(grid_id)%extent   (nb,1)     .and. &
00606                                    inters(2,2,n) >= Grids(grid_id)%partition(nb,2) + 1 .and. &
00607                                    inters(1,2,n) <= Grids(grid_id)%partition(nb,2) +         &
00608                                                     Grids(grid_id)%extent   (nb,2)     .and. &
00609                                    inters(2,3,n) >= Grids(grid_id)%partition(nb,3) + 1 .and. &
00610                                    inters(1,3,n) <= Grids(grid_id)%partition(nb,3) +         &
00611                                                     Grids(grid_id)%extent   (nb,3) ) exit
00612 
00613                            enddo
00614 
00615                            ! transform into local indices
00616 
00617                            if ( nb <= nbr_blocks ) then
00618 #ifdef DEBUG
00619                               print *, ' Transform block ', nb, Grids(grid_id)%partition(nb,1)+1 &
00620                                                    , ' - ',     Grids(grid_id)%partition(nb,1)+  &
00621                                                                 Grids(grid_id)%extent   (nb,1)
00622                               print *, ' global inter    ', nb, inters(:, :, n)
00623 #endif
00624                               offset    = 0
00625                               addoffset = 0
00626 
00627                               do i = 1, ndim_3d
00628                                  idim(i) = Grids(grid_id)%grid_shape(2,i) - &
00629                                            Grids(grid_id)%grid_shape(1,i)+1
00630                                  do nl = 1, nb-1
00631                                     addoffset(i) = Grids(grid_id)%extent(nl,i) + offset(i)
00632                                     if ( addoffset(i) < idim(i) ) &
00633                                          offset(i) = addoffset(i)
00634                                  enddo
00635                               enddo
00636 
00637                               do i = 1, ndim_3d
00638                                  extent = inters(2,i,n) - inters(1,i,n)
00639                                  inters(1, i, n) = inters(1, i, n) + offset(i) &
00640                                                  - Grids(grid_id)%partition(nb,i) &
00641                                                  + Grids(grid_id)%grid_shape(1,i) - 1
00642                                  inters(2, i, n) = inters(1, i, n) + extent
00643                               end do
00644 #ifdef DEBUG
00645                               print *, ' part offset ', nb, offset(:)
00646                               print *, ' local inter ', nb, inters(:, :, n)
00647 #endif
00648                            else
00649 
00650                               ierror = PRISM_Error_Internal
00651                               ierrp (1) = nb
00652                               ierrp (2) = nbr_blocks
00653                               call psmile_error (ierror, "No block found", ierrp, 2, &
00654                                    __FILE__, __LINE__)
00655                               return
00656 
00657                            endif
00658 
00659                         enddo
00660 
00661                      else
00662 
00663                         ! case for single block
00664 
00665                         do n = 1, npart
00666                            do i = 1, ndim_3d
00667                               inters (1:2, i, n) = &
00668                               inters (1:2, i, n) - Grids(grid_id)%partition (1,i) &
00669                                                  + Grids(grid_id)%grid_shape(1,i) - 1
00670                            end do
00671                         end do
00672 
00673                      endif
00674 
00675                   endif
00676 !
00677                   if (npart > 1) then
00678                      call psmile_remove_intersect_int (inters, ids(1:npart,1), &
00679                                                        ids(1:npart,2), npart, ierror)
00680                      if (ierror > 0) return
00681                   endif
00682 
00683 #ifdef PRISM_ASSERTION
00684                   if (icomp_info%all_extent_infos(jglob)%grid_type /= &
00685                       PRISM_Gridless) then
00686                      call psmile_assert (__FILE__, __LINE__, &
00687                       'Coupling of gridless grid with real grid is impossible !')
00688                   endif
00689 #endif
00690                else
00691 !
00692 !===> ........... Real grid
00693 !                 Remove common intersections
00694 !
00695                   if (npart > 1) then
00696                      call psmile_remove_intersect (dinter, ids(1:npart,1), &
00697                                ids(1:npart,2), npart,                      &
00698                                comp_info%all_extent_infos,                 &
00699                                icomp_info%all_extent_infos,                &
00700                                ierror)
00701                      if (ierror > 0) return
00702                   endif
00703 !
00704                   do n = 1, npart
00705 #ifdef DEBUG
00706                        PRINT *, ' In psmile_find_intersect intersection :',n,'over :',npart
00707 #endif
00708                      call psmile_sel_grid_range (grid_id, dinter (:, :, n), &
00709                                                  inters(:, :, n), ierror)
00710                      if ( ierror /= 0 ) return
00711                   end do
00712 !
00713                   n = 1
00714                   do while (n <= npart)
00715                      if (minval (inters(2, :, n) - inters (1, :, n)) < 0) then
00716                         if (n /= npart) then
00717                            inters (:, :, n) = inters (:, :, npart)
00718                            ids (n, 1) = ids (npart, 1)
00719                            ids (n, 2) = ids (npart, 2)
00720                         endif
00721 
00722                         npart = npart - 1
00723                      else
00724                         n = n + 1
00725                      endif
00726                   end do ! while (n <= nparts)
00727 #ifdef HUHU
00728 !
00729 !===> ... Remove common intersections in "inters"
00730 !         !!! Note: This was done for the reduced gaussian grid.
00731 !         !!! TODO
00732 !         !!! The better (correct) solution would be to generate
00733 !         !!! a list of points to be searched, which should be
00734 !         !!! created here in PSMILe_sel_grid_range and which
00735 !         !!! should be managed locally if possible.
00736 !         !!! Transformation code for list of point and removed
00737 !             intersections !!!
00738 !
00739                   if (npart > 1) then
00740                      call psmile_remove_intersect_int (inters, ids(1:npart,1), &
00741                                  ids(1:npart,2), npart, ierror)
00742                      if (ierror > 0) return
00743                   endif
00744 #endif
00745                endif
00746 !
00747 !===> ... Get list of varid's for each method in "list_of_methods"
00748 !         (*) Look for a input field of component "local_comp_id", grid "grid_id" and
00749 !                                       method "method_id",
00750 !             which is used for coupling
00751 !         (*) Control whether this input field has to get data from component
00752 !             "icomp_info%comp_id"
00753 !             TODO: ?? Could we also check the Grid ID ?
00754 !                   ?? This is not contained in structure ch_ptr ! ?
00755 !
00756                if (n_in_fields == 0) go to 1000
00757 !
00758                n_vars = 0
00759 !
00760                do m = 1, n_meths
00761                   ibeg = 1
00762                   method_id = poss_meths (m)
00763 !
00764 search_vars:      do while (ibeg <= n_in_fields)
00765 !
00766 !                    Look for a matching field
00767 !
00768 !cdir vector
00769                      do i = ibeg, n_in_fields
00770                         if (Fields(poss_fields(i))%method_id == method_id) exit
00771                      end do
00772 !
00773                      ibeg = i + 1
00774                      if (i > n_in_fields) exit search_vars
00775 !
00776 !                    Is this field input field of the component
00777 !                    "icomp_info%global_comp_id" ?
00778 !
00779 #ifdef DEBUG
00780                      print *, 'search Taskin for dest component', icomp_info%global_comp_id
00781 #endif /* DEBUG */
00782                      In_channel => Fields(poss_fields(i))%Taskin%In_channel
00783 !
00784                      do j = 1, size (In_channel)
00785 #ifdef DEBUG
00786                         print 9970, j, &
00787                                     In_channel(j)%origin_type, &
00788                                     In_channel(j)%remote_comp_id, &
00789                                     In_channel(j)%global_transi_id, &
00790                                     In_channel(j)%remote_transi_id, &
00791                                     global_dest_grid_id
00792 #endif /* DEBUG */
00793                         if (In_channel(j)%origin_type    == PSMILe_comp .and. &
00794                             In_channel(j)%remote_comp_id ==                   &
00795                                                    icomp_info%global_comp_id  &
00796                             .and.                                             &
00797                             field2grid(In_channel(j)%remote_transi_id) ==     &
00798                                         global_dest_grid_id) then
00799                            n_vars = n_vars + 1
00800                            tmp_field_list (n_vars)%tgt_method_id          = method_id
00801                            tmp_field_list (n_vars)%tgt_var_id             = poss_fields(i)
00802                            tmp_field_list (n_vars)%transient_in_id        = In_channel(j)%global_transi_id
00803                            tmp_field_list (n_vars)%transient_out_id       = In_channel(j)%remote_transi_id
00804                            tmp_field_list (n_vars)%requires_conserv_remap = 0
00805                            do jj = 1, 3
00806                              if ( In_channel(j)%interp%interp_meth(jj) == PSMILe_conserv2D .or. &
00807                                   In_channel(j)%interp%interp_meth(jj) == PSMILe_conserv3D ) then
00808                                   tmp_field_list (n_vars)%requires_conserv_remap = &
00809                                     In_channel(j)%interp%interp_meth(jj)
00810                              endif
00811                            enddo
00812                         endif
00813                      end do ! j
00814 !
00815                   end do search_vars ! while
00816                end do ! m
00817 !rr TODO:
00818 !rr silly sort of field_list to have conservative remapping first in the list
00819 !rr This list needs to be revised. It should be arranged by method_ids, where
00820 !rr for each method_id the conservative remapping is at the beginning.
00821 !rr
00822                j = 0
00823                do n = 1, n_vars
00824                   if ( tmp_field_list (n)%requires_conserv_remap == PSMILe_conserv2D .or. &
00825                         tmp_field_list (n)%requires_conserv_remap == PSMILe_conserv3D ) then
00826                      j = j + 1
00827                      field_list(j) = tmp_field_list(n)
00828                   endif
00829                enddo
00830                do n = 1, n_vars
00831                   if ( tmp_field_list (n)%requires_conserv_remap /= PSMILe_conserv2D .and. &
00832                         tmp_field_list (n)%requires_conserv_remap /= PSMILe_conserv3D ) then
00833                      j = j + 1
00834                      field_list(j) = tmp_field_list(n)
00835                   endif
00836                enddo
00837 !
00838                if (n_vars == 0) then
00839 !                 Grid is not used for coupling with component icomp_info%comp_id
00840 !                 test before !!
00841 #ifdef DEBUG
00842                   print *, "n_vars", n_vars
00843                   write (*, 9960) trim(ch_id), local_comp_id, grid_id
00844 #endif /* DEBUG */
00845 !
00846                   npart = 0
00847                endif
00848 !
00849 !===> ... Is it necessary to generate multi grids for search of donor cells ?
00850 !
00851 1000           continue
00852 !
00853 
00854                if (n_out_fields > 0 .and. npart > 0 .and. &
00855                   grid_type /= PRISM_Gridless) then
00856                   if (.not. mg_gen (grid_id)) then
00857                      mg_gen (grid_id) = .true.
00858                      range (:, :, grid_id) = inters (:, :, 1)
00859                   endif
00860 !
00861 !              ... Get bounding box for all intersections
00862 !                  TODO: Something better (for example several parts)
00863 !
00864                   do n = 1, npart
00865                      range (1, 1:ndim_3d, grid_id) = min ( &
00866                      range (1, 1:ndim_3d, grid_id), inters (1, 1:ndim_3d, n))
00867                      range (2, 1:ndim_3d, grid_id) = max ( &
00868                      range (2, 1:ndim_3d, grid_id), inters (2, 1:ndim_3d, n))
00869                   end do
00870                endif
00871 !
00872 !===> ... Dummy intersection found ?
00873 !         Increment number of intersections
00874 
00875 #ifdef DEBUG
00876                PRINT*, 'Number of input fields :',n_in_fields
00877                PRINT*, 'Number of output fields :',n_out_fields
00878                call psmile_flushstd
00879 #endif
00880 !
00881                if (npart == 0 .or. n_in_fields == 0) then
00882                   if (dest == psmile_rank) continue
00883 
00884                   nnull = nnull + 1
00885                   num_dummy_intersect_per_grid(grid_id) = &
00886                         num_dummy_intersect_per_grid(grid_id) + 1
00887                   n_vars = 0
00888                   npart = 0
00889                endif
00890 !
00891                ninter = ninter + 1
00892                num_intersect_per_grid(grid_id) = &
00893                      num_intersect_per_grid(grid_id) + 1
00894 #define CONS_REMAP_DEADLOCK_WORKAROUND
00895 #ifdef CONS_REMAP_DEADLOCK_WORKAROUND
00896                paction%intersect_ranks(ninter) = dest
00897 #endif
00898 !
00899                if (dest == psmile_rank) nmyint = nmyint + 1
00900 !
00901 !===> ... Send message to the destination process
00902 !
00903 !===> ... Relative tag/counter
00904 !
00905                msg_intersections%relative_msg_tag = ninter - nnull
00906 !
00907 !===> ... Info on target component and grid.
00908 !         This is the component which has put the field data.
00909 !
00910                msg_intersections%src_comp_id = icomp_info%comp_id
00911 !
00912 !===> ... Info on sending component and grid.
00913 !         This is the component which get the field data.
00914 !
00915                msg_intersections%tgt_comp_id = local_comp_id
00916                msg_intersections%tgt_grid_id = grid_id
00917 
00918                msg_intersections%all_comp_infos_comp_idx = global_index
00919 !
00920                msg_intersections%num_parts = npart
00921 !
00922                if (n_vars > 0) then
00923 !
00924 !         TODO: In der field_list fehlt noch der datentype der Methode !!!
00925                   do i = 1, n_vars
00926                      field_list (i)%tgt_mask_id = &
00927                         Fields(field_list(i)%tgt_var_id)%mask_id
00928                   end do
00929 !
00930 !              Control mask values in intersections
00931 !                 defined == 2: All mask values are true
00932 !                 defined == 0: All mask values are false
00933 !
00934 !              TODO: improve handling of already treated Masks (see last_maskid)
00935 !                    (already_controlled (1:nvars) or something like that)
00936 !              !!! For now this is only done for PRISM_Gridless, because it is
00937 !                  not clear to me how much CPU time this additional control will cost. !!!
00938 !rr            !rr For conservative remapping we have to send the mask only once.
00939 !rr                if we do it twice, once when sending the corners and a second time
00940 !rr                when sending to coords this will corrupt the memory. Therefore I
00941 !rr                activated the check for all grids.
00942 !rr
00943                   do n = 1, n_vars
00944                      if ( field_list(n)%requires_conserv_remap == PSMILe_conserv2D .or. &
00945                         field_list(n)%requires_conserv_remap == PSMILe_conserv3D ) then
00946                         last_maskid = field_list(n)%tgt_mask_id
00947                         do i = n+1, n_vars
00948                            if ( field_list(i)%tgt_mask_id == last_maskid ) then
00949                               field_list(i)%tgt_mask_id = PRISM_UNDEFINED
00950                            endif
00951                         enddo
00952                      endif
00953                   enddo
00954 
00955                   if (grid_type == PRISM_Gridless) then
00956                      last_maskid = PRISM_UNDEFINED
00957 !
00958                      do i = 1, n_vars
00959                      if (field_list (i)%tgt_mask_id /= PRISM_UNDEFINED) then
00960                         if (field_list (i)%tgt_mask_id == last_maskid) cycle
00961 
00962                         call psmile_is_mask_defined (                &
00963                            Masks(field_list (i)%tgt_mask_id)%mask_array, &
00964                            Masks(field_list (i)%tgt_mask_id)%mask_shape, &
00965                            inters, npart, defined, ierror)
00966                         if (ierror > 0) return
00967 
00968 !                 ?? Skip in case defined == 0 ??
00969 !
00970                         if (defined == 2) then
00971                               do j = i+1, n_vars
00972                               if (field_list (j)%tgt_mask_id == field_list (i)%tgt_mask_id) &
00973                                  field_list (j)%tgt_mask_id = PRISM_UNDEFINED
00974                               end do
00975 !
00976                            field_list (i)%tgt_mask_id = PRISM_UNDEFINED
00977                         else
00978                            last_maskid = field_list (i)%tgt_mask_id
00979                         endif
00980 
00981                      endif
00982                      end do
00983                   endif
00984 !
00985 !===> ...... Store data on the first field id
00986 !
00987                   method_id = field_list (1)%tgt_method_id
00988                   var_id    = field_list (1)%tgt_var_id
00989 !
00990                   msg_intersections%field_info = field_list(1)
00991                   msg_intersections%num_vars   = n_vars
00992 !
00993 !===> ..... Get method values
00994 !
00995                   msg_intersections%method_type = Methods (method_id)%method_type
00996 
00997                   select case (Methods (method_id)%method_type)
00998                   case (PSMILe_PointMethod)
00999                      msg_intersections%method_datatype = &
01000                            Methods (method_id)%coords_pointer%coords_datatype
01001 
01002                   case (PSMILe_VectorPointMethod)
01003 #ifdef TODO
01004                      msg_intersections%method_datatype = &
01005                            Methods (method_id)%vector_pointer%vector_datatype
01006 #else
01007                      ierrp (1) = Methods (method_id)%method_type
01008                      ierror = PRISM_Error_Internal
01009 
01010                      call psmile_error ( ierror, 'vector method type is currently not supported', &
01011                                       ierrp, 1, __FILE__, __LINE__ )
01012 #endif
01013 
01014                   case (PSMILe_SubgridMethod)
01015                      msg_intersections%method_datatype = &
01016                            Methods (method_id)%subgrid_pointer%subgrid_datatype
01017 
01018                   case default
01019                      ierrp (1) = Methods (method_id)%method_type
01020                      ierror = PRISM_Error_Internal
01021 
01022                      call psmile_error ( ierror, 'unsupported method type', &
01023                                        ierrp, 1, __FILE__, __LINE__ )
01024                   end select
01025 
01026                endif ! (n_vars > 0)
01027 !
01028 !===> ... Data on intersection
01029 !
01030                ip = ip_msgint_inter + npart*(2*ndim_3d)
01031 !
01032 ! The fields to be handled are ordered such that those requireing conservative remapping
01033 ! are listed first. For conservative remapping the intersections have to be increased by
01034 ! 1. When the non-conservative remapping fields are processed we have to switch back to
01035 ! the original intersections.
01036 !
01037                expand = PSMILe_Undef
01038 
01039                if (npart > 0) then
01040 
01041                   msg_intersections%first_src_all_extents_grid_id = ids (1, 2) ! jglob0 + ng
01042                   msg_intersections%first_tgt_all_extents_grid_id = ids (1, 1) ! local_grid_extents_range(1) + x
01043 
01044                   if (grid_type == PRISM_Gridless) then
01045                      allocate (msg_intersections%intersections(2*npart))
01046                   else
01047                      allocate (msg_intersections%intersections(npart))
01048                   endif
01049 !
01050 !              increase inters by one for exchange of corner info. For Gaussreduced grids
01051 !              we currently send complete (redundant corner information. The arrays sizes
01052 !              for Gaussreduced corners are adjusted in the repective routines.
01053 !
01054                   if ( grid_type /=  PRISM_Gaussreduced_regvrt ) then
01055 
01056                      if ( msg_intersections%field_info%requires_conserv_remap == PSMILe_conserv2D ) then
01057 
01058                         do n = 1, npart
01059                            inters (2, 1:ndim_2d, n) = inters (2, 1:ndim_2d, n) + 1
01060                         enddo
01061 
01062                         expand = PSMILe_conserv2D
01063 
01064                      else  if ( msg_intersections%field_info%requires_conserv_remap == PSMILe_conserv3D ) then
01065 
01066                         do n = 1, npart
01067                            inters (2, 1:ndim_3d, n) = inters (2, 1:ndim_3d, n) + 1
01068                         enddo
01069 
01070                         expand = PSMILe_conserv3D
01071 
01072                      endif
01073 
01074                      ! MoHa: is this ever executed?
01075                      if ( expand == PSMILe_conserv2D .and. &
01076                           msg_intersections%field_info%requires_conserv_remap /= PSMILe_conserv2D ) then
01077 
01078                         do n = 1, npart
01079                            inters (2, 1:ndim_2d, n) = inters (2, 1:ndim_2d, n) - 1
01080                         enddo
01081 
01082                      else  if ( expand == PSMILe_conserv3D .and. &
01083                                 msg_intersections%field_info%requires_conserv_remap /= PSMILe_conserv3D ) then
01084 
01085                         do n = 1, npart
01086                            inters (2, 1:ndim_3d, n) = inters (2, 1:ndim_3d, n) - 1
01087                         enddo
01088 
01089                      endif
01090 
01091                   endif ! ( grid_type /=  PRISM_Gaussreduced_regvrt )
01092 
01093                   do n = 1, npart
01094                      msg_intersections%intersections(n)%intersection = inters(:, :, n)
01095                      msg_intersections%intersections(n)%tgt_all_extents_grid_id = ids (n, 1)
01096                      msg_intersections%intersections(n)%src_all_extents_grid_id = ids (n, 2)
01097                   enddo
01098 !
01099                   ip = ip + 2 * npart
01100 
01101                   if (grid_type == PRISM_Gridless) then
01102 !
01103 !===>             Transfer offset
01104 !
01105                      if (Associated(Grids(grid_id)%partition)) then
01106 
01107                         do n = 1, npart
01108 
01109                            msg_intersections%intersections(n+npart)%intersection = inters_save(:, :, n)
01110                            msg_intersections%intersections(n+npart)%tgt_all_extents_grid_id = psmile_undef
01111                            msg_intersections%intersections(n+npart)%src_all_extents_grid_id = psmile_undef
01112                         enddo
01113                      endif
01114 
01115                      ip = ip + 1 + npart*2*ndim_3d
01116 
01117 !                      if (npart > maxpart ) then
01118 ! #ifdef DEBUG
01119 !                         print *, ' npart is ', npart , '!'
01120 !                         print *, ' Preparing send of an additional message! '
01121 ! #endif
01122 !                         allocate (buffer(2*ndim_3d*(npart-maxpart)), stat = ierror)
01123 !                         if (ierror > 0) then
01124 !                            ierrp (1) = ierror
01125 !                            ierrp (2) = 2*ndim_3d*(npart-maxpart)
01126 !
01127 !                            ierror = PRISM_Error_Alloc
01128 !
01129 !                            call psmile_error ( ierror, 'found', &
01130 !                               ierrp, 2, __FILE__, __LINE__ )
01131 !                            return
01132 !                         endif
01133 !
01134 !                         buffer(:) = pack (inters_save(:, :, npart-maxpart:npart), .true.)
01135 !
01136 !                      endif
01137 
01138                   endif
01139                else
01140                   msg_intersections%first_tgt_all_extents_grid_id = psmile_undef
01141                   msg_intersections%first_src_all_extents_grid_id = psmile_undef
01142                   nullify (msg_intersections%intersections)
01143                end if ! (npart > 0)
01144 !
01145 #ifdef DEBUG
01146                print *, "psmile_find_intersect: psmile_rank->dest, tag:", &
01147                         psmile_rank, dest, lastag
01148                PRINT *, "psmile_find_intersect: datatype, npart:", &
01149                         msg_intersections%method_datatype, npart
01150                PRINT*, 'psmile_find_intersect : ninter, nmyint , nnull:',ninter, nmyint , nnull
01151                call psmile_flushstd
01152                do n = 1, npart
01153                   print *, "psmile_find_intersect: ipart, inter", n, inters (:, :, n)
01154                   print *, "psmile_find_intersect: ipart, ids", n, ids(n, 1), ids (n,2)
01155                   call psmile_flushstd
01156                end do
01157 #endif /* DEBUG */
01158 !
01159 !===> ... Send data to the process which contains intersection
01160 !         The corresponding receive is found in psmile_enddef_action
01161 !
01162 #ifdef DEBUG
01163                print *, ' Sending tag ', lastag, ' to destination ', dest
01164 #endif /* DEBUG */
01165 
01166                ! copy collected data into a sendable buffer
01167                call psmile_pack_msg_intersections(msg_intersections, msgint)
01168 
01169                call psmile_bsend (msgint, ip, MPI_INTEGER, dest, lastag, &
01170                                   comm_psmile, ierror)
01171 
01172                if (ierror /= MPI_SUCCESS) then
01173                   ierrp (1) = ierror
01174                   ierrp (2) = dest
01175                   ierrp (3) = lastag
01176                   ierror = PRISM_Error_Send
01177 
01178                   call psmile_error (ierror, 'MPI_Send', &
01179                                     ierrp, 3, __FILE__, __LINE__ )
01180                   return
01181                endif
01182 
01183                if ( associated (msg_intersections%intersections)) &
01184                   deallocate (msg_intersections%intersections)
01185 
01186                if (grid_type == PRISM_Gridless .and. npart > maxpart ) then
01187 
01188 #ifdef PRISM_ASSERTION
01189                   call psmile_assert (__FILE__, __LINE__, &
01190                                    "This part of the code does not work. I am sorry.")
01191 #endif
01192 
01193 !                   call psmile_bsend (buffer, 2*ndim_3d*(npart-maxpart), &
01194 !                      MPI_INTEGER, dest, ind_msgint_tag, comm_psmile, ierror)
01195 !                   if (ierror /= MPI_SUCCESS) then
01196 !                      ierrp (1) = ierror
01197 !                      ierrp (2) = dest
01198 !                      ierrp (3) = lastag
01199 !                      ierror = PRISM_Error_Send
01200 !
01201 !                      call psmile_error (ierror, 'MPI_Send', &
01202 !                         ierrp, 3, __FILE__, __LINE__ )
01203 !                      return
01204 !                   endif
01205 
01206                endif
01207 !
01208 !===> ... Send data to the process containing data on further fields
01209 !         TODO: In field_list the datatype of Method is still missing !!!
01210 !
01211                if (n_vars > 1) then
01212 #ifdef DEBUG
01213                   print *, ' Sending tag ', vartag, ' to destination ', dest
01214 #endif /* DEBUG */
01215                   call psmile_pack_field_info (field_list(2:), field_list_buf, n_vars-1)
01216 
01217                   call psmile_bsend (field_list_buf(1,1), (n_vars-1)*nd_field_list, &
01218                                     MPI_INTEGER, dest, vartag, comm_psmile,  &
01219                                     ierror)
01220                   if (ierror /= MPI_SUCCESS) then
01221                      ierrp (1) = ierror
01222                      ierrp (2) = dest
01223                      ierrp (3) = vartag
01224                      ierror = PRISM_Error_Send
01225 
01226                      call psmile_error (ierror, 'MPI_Send', &
01227                                        ierrp, 3, __FILE__, __LINE__ )
01228                      return
01229                   endif
01230                endif
01231 
01232             end do ! while ( jbeg <= inum_total_extents )
01233 
01234             ! set index of next grid range
01235             local_grid_extents_range(1) = local_grid_extents_range(2) + 1
01236          enddo ! while (local_grid_extents_range(1) < local_extents_range(2))
01237 
01238       end do ! all components
01239 !
01240 !===> Prepare search for grid with id "grid_id"
01241 !     ? Delay until first receive ?
01242 !
01243       do grid_id = 1, Number_of_Grids_allocated
01244          if (mg_gen (grid_id)) then
01245 !
01246             call psmile_mg_setup (grid_id, range(1, 1, grid_id), &
01247                                  tol, ierror)
01248             if (ierror /= 0) return
01249 !
01250          endif
01251       end do
01252 !
01253 !=======================================================================
01254 !     Free
01255 !=======================================================================
01256 !
01257       Deallocate (found)
01258       if (num_intersect_allocated > 0) then
01259          Deallocate (dinter, inters, ids, inters_save)
01260       endif
01261 !
01262 !===> All done
01263 !
01264 #ifdef VERBOSE
01265       print 9980, trim(ch_id), ierror
01266       call psmile_flushstd
01267 #endif /* VERBOSE */
01268 
01269 !
01270 !  Formats:
01271 !
01272 
01273 #ifdef VERBOSE
01274 
01275 9990 format (1x, a, ': psmile_find_intersect: local comp_id', i3, ' global comp_id', i3)
01276 9980 format (1x, a, ': psmile_find_intersect: eof ierror =', i3)
01277 
01278 #endif /* VERBOSE */
01279 
01280 #ifdef DEBUG
01281 9970 format (1x, 'Taskin%In_channel(', i3, '): origin_type', i5, &
01282                  ', remote comp id', i4, &
01283                  ', global_transi_id', i4, ', remote_transi_id', i8, &
01284             /1x, 'global_dest_grid_id', i4)
01285 9960 format (1x, a, ': psmile_find_intersect: #### Grid is not used for coupling !', &
01286             /1x, 'Introduce test before !!! comp_id', i4, '; grid id', i4)
01287 #endif /* DEBUG */
01288 
01289       contains
01290 
01291          ! this function needs to be moved to a central place!
01292          function grid_types_are_compatible(type1, type2)
01293 
01294             use prism, only: prism_gridless
01295 
01296             integer, intent(in) :: type1, type2
01297             logical grid_types_are_compatible
01298 
01299             ! gridless grids can only be coupled among themselves
01300             grid_types_are_compatible = &
01301                type1 == prism_gridless .eqv. type2 == prism_gridless
01302 
01303          end function grid_types_are_compatible
01304 
01305       end subroutine PSMILe_Find_intersect

Generated on 1 Dec 2011 for Oasis4 by  doxygen 1.6.1