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

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1