psmile_enddef_appl.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 !
00006 #ifdef DONT_HAVE_STDMPI2
00007 #undef PRISM_with_MPI2
00008 #endif
00009 !
00010 !BOP
00011 !
00012 ! !ROUTINE: PSMILe_Enddef_appl
00013 !
00014 ! !INTERFACE:
00015 
00016       subroutine psmile_enddef_appl (tag, my_icomp0_coll_comps, &
00017                                      n_active, ierror)
00018 !
00019 ! !USES:
00020 !
00021       use PRISM_constants
00022 !
00023       use PSMILe, dummy_interface => PSMILe_enddef_appl
00024 
00025       implicit none
00026 !
00027 ! !INPUT PARAMETERS:
00028 !
00029       Integer,            Intent (In)  :: tag
00030 
00031 !     Message tag to be used for point-to-point communication
00032 !
00033 ! !OUTPUT PARAMETERS:
00034 !
00035       Integer,            Intent (Out) :: my_icomp0_coll_comps
00036 
00037 !     Index 0 of component information of actual application
00038 !     in collected component information "all_comp_infos";
00039 !     i.e. the component information of actual application is stored in
00040 !     all_comp_infos(my_icomp0_coll_comps+1:
00041 !                    my_icomp0_coll_comps+n_active)
00042 
00043       Integer,            Intent (Out) :: n_active
00044 !
00045 !     Number of components in actual application
00046 !     = Number_of_comps_per_appl(Appl%sequence_number)
00047 
00048       Integer,            Intent (Out) :: ierror
00049 
00050 !     Returns the error code of PSMILe_enddef_appl;
00051 !             ierror = 0 : No error
00052 !             ierror > 0 : Severe error
00053 !
00054 ! !LOCAL VARIABLES
00055 !
00056 !  ... for coloring
00057 
00058       integer                      :: color, key
00059       integer                      :: comm_appl_roots, rank, size
00060       integer                      :: master_rank ! rank of master in comm_psmile
00061       logical                      :: i_am_master
00062 
00063 !  ... for applications:
00064 
00065       integer                      :: iappl
00066       integer                      :: Number_of_comps_per_appl (noApplication)
00067       integer                      :: disp (noApplication)
00068       integer                      :: root_ranks (noApplication)
00069 
00070 !  ... for MPI_Gather
00071 
00072       Type (Enddef_comp)           :: dummy_comp_info
00073 
00074 !  ... for components:
00075 
00076       integer                      :: i, icomp, n, j
00077 
00078 !  ... for exchanging of extents
00079 
00080       Real (PSMILe_float_kind), allocatable :: extents_buf(:,:,:)
00081       Integer, allocatable                  :: extent_info_buf(:,:)
00082 
00083 !  ... Temporary vector in order to active component id's for the application
00084 
00085       Integer, allocatable         :: global_ids (:)
00086       Type (Enddef_comp), Pointer  :: b_comps (:)
00087       Integer                      :: comp_min, comp_max, n_miss
00088       Integer                      :: local_comp_min, local_comp_max
00089 
00090 #ifndef PRISM_with_MPI2
00091       Integer, allocatable         :: global_ids_in (:)
00092 #endif
00093 
00094 !  ... for error parameters:
00095 
00096       integer, parameter           :: nerrp = 3
00097       integer                      :: ierrp (nerrp)
00098 !
00099 ! !DESCRIPTION:
00100 !
00101 ! Subroutine "PSMILe_Enddef_appl" finishs the definition phase for the
00102 ! application. The data of all components is stored in global array
00103 ! "all_comp_infos".
00104 !
00105 ! !REVISION HISTORY:
00106 !
00107 !   Date      Programmer   Description
00108 ! ----------  ----------   -----------
00109 ! 03.05.16    H. Ritzdorf  created
00110 !
00111 !EOP
00112 !----------------------------------------------------------------------
00113 !
00114 ! $Id: psmile_enddef_appl.F90 3248 2011-06-23 13:03:19Z coquart $
00115 ! $Author: coquart $
00116 !
00117    Character(len=len_cvs_string), save :: mycvs = 
00118        '$Id: psmile_enddef_appl.F90 3248 2011-06-23 13:03:19Z coquart $'
00119 !
00120 !----------------------------------------------------------------------
00121 
00122 #ifdef VERBOSE
00123       print 9990, trim(ch_id)
00124       call psmile_flushstd
00125 #endif /* VERBOSE */
00126 !
00127 !  Initialization
00128 !
00129       ierror = 0
00130       master_rank = 0
00131       i_am_master = .false.
00132 !
00133 !-----------------------------------------------------------------------
00134 !  Collect the data of active components of all application processes
00135 !  within the application communicator "Appl%comm".
00136 !
00137 !  (*) Get comp_min = Minimum of global component id's
00138 !  (*) Get comp_max = Maximum of global component id's
00139 !  (*) Allocate vector global_ids (comp_min:comp_max)
00140 !  (*) Get global_ids vector with
00141 !      global_ids (comp_id) = Appl%rank: Component of global component id
00142 !                                        "comp_id" is     active
00143 !                                        in an application process.
00144 !      global_ids (comp_id) = Appl%size: Component of global component id
00145 !                                        "comp_id" is not active in an 
00146 !                                        in an application process.
00147 !-----------------------------------------------------------------------
00148 !
00149       if (n_act_comp > 0) then
00150          local_comp_min = comp_infos(1)%global_comp_id
00151          local_comp_max = comp_infos(n_act_comp)%global_comp_id
00152       else
00153 !
00154 ! hier gibt es doch bestimmt einen Wert aus der SCC info
00155 ! den man statt huge verwenden kann
00156 !
00157          local_comp_min = huge (local_comp_max)
00158          local_comp_max = - local_comp_min
00159       endif
00160 !
00161       call MPI_Allreduce (local_comp_min, comp_min, 1, &
00162                           MPI_INTEGER, MPI_MIN, Appl%comm, ierror)
00163       if ( ierror /= MPI_SUCCESS ) then
00164          ierrp (1) = ierror
00165          ierror = PRISM_Error_MPI
00166 
00167          call psmile_error ( ierror, 'MPI_Allreduce(MPI_MIN)', &
00168                              ierrp, 1, __FILE__, __LINE__ )
00169          return
00170       endif
00171 !
00172       call MPI_Allreduce (local_comp_max, comp_max, 1, &
00173                           MPI_INTEGER, MPI_MAX, Appl%comm, ierror)
00174       if ( ierror /= MPI_SUCCESS ) then
00175          ierrp (1) = ierror
00176          ierror = PRISM_Error_MPI
00177 
00178          call psmile_error ( ierror, 'MPI_Allreduce(MPI_MAX)', &
00179                              ierrp, 1, __FILE__, __LINE__ )
00180          return
00181       endif
00182 !
00183 !  ... Is there an active component in the application ?
00184 !
00185       if (comp_min > comp_max) then
00186          n_active = 0
00187       else
00188 !
00189 !  Allocate vector for all possible global comp id's
00190 !
00191       Allocate (global_ids(comp_min:comp_max), STAT = ierror)
00192       if ( ierror > 0 ) then
00193          ierrp (1) = ierror
00194          ierrp (2) = comp_max - comp_min + 1
00195          call psmile_error ( PRISM_Error_Alloc, 'global_ids', &
00196                              ierrp, 2, __FILE__, __LINE__ )
00197          return
00198       endif
00199 !
00200 !  Set Mask of global id's on local process
00201 !
00202       global_ids (:) = Appl%size
00203 !
00204       global_ids (comp_infos(1:n_act_comp)%global_comp_id) = Appl%rank
00205 !
00206 !  Get global id's on all PSMILe processes
00207 !
00208 #ifdef PRISM_with_MPI2
00209       call MPI_Allreduce (MPI_IN_PLACE, global_ids, comp_max-comp_min+1, &
00210                           MPI_INTEGER, MPI_MIN, Appl%comm, ierror)
00211 #else
00212       Allocate (global_ids_in(comp_min:comp_max), STAT = ierror)
00213       if ( ierror > 0 ) then
00214          ierrp (1) = ierror
00215          ierrp (2) = comp_max - comp_min + 1
00216          call psmile_error ( PRISM_Error_Alloc, 'global_ids_in', &
00217                              ierrp, 2, __FILE__, __LINE__ )
00218          return
00219       endif
00220 
00221       global_ids_in = global_ids
00222 
00223       call MPI_Allreduce (global_ids_in, global_ids, comp_max-comp_min+1, &
00224                           MPI_INTEGER, MPI_MIN, Appl%comm, ierror)
00225   
00226       Deallocate (global_ids_in)
00227 #endif
00228       if ( ierror /= MPI_SUCCESS ) then
00229          ierrp (1) = ierror
00230          ierror = PRISM_Error_MPI
00231 
00232          call psmile_error ( ierror, 'MPI_Allreduce(MPI_MAX)', &
00233                              ierrp, 1, __FILE__, __LINE__ )
00234          return
00235       endif
00236 !
00237 !  Create a_comps vector
00238 !
00239 !  n_active = Total number of active components
00240 !  n_miss   = Maximal number of unknown active components within an
00241 !             application process.
00242 !
00243       n_active = 0
00244          do i = comp_min, comp_max
00245          if (global_ids(i) /= Appl%size) n_active = n_active + 1
00246          end do
00247 
00248 #ifdef PRISM_ASSERTION
00249       if (n_active < n_act_comp .or. n_active > comp_max-comp_min+1) then
00250          print *, 'n_active', n_active, n_act_comp, comp_max-comp_min+1
00251 
00252          call psmile_assert ( __FILE__, __LINE__, &
00253              'Inconsistent number of active application components!')
00254       endif
00255 
00256       if (n_active > noComponents) then
00257          print *, 'n_active', n_active, noComponents
00258          call psmile_assert ( __FILE__, __LINE__, &
00259              'n_active > noComponents !')
00260       endif
00261 #endif
00262 
00263       call MPI_Allreduce (n_active-n_act_comp, n_miss, 1, &
00264                           MPI_INTEGER, MPI_MAX, Appl%comm, ierror)
00265       if ( ierror /= MPI_SUCCESS ) then
00266          ierrp (1) = ierror
00267          ierror = PRISM_Error_MPI
00268 
00269          call psmile_error ( ierror, 'MPI_Allreduce(MPI_MAX)', &
00270                              ierrp, 1, __FILE__, __LINE__ )
00271          return
00272       endif
00273 !
00274 !===> If a component is not known in all processes of an application,
00275 !     collect the data of all processes in the application on process 0.
00276 !     The data of the application is stored in "b_comps".
00277 !     "b_comps" is sorted relative to the global component id.
00278 !     (Brauch man die Sortierung wirklich ?)
00279 !
00280       if (n_miss > 0) then
00281          Allocate (b_comps(n_active), STAT = ierror)
00282          if ( ierror > 0 ) then
00283             ierrp (1) = ierror
00284             ierrp (2) = n_active
00285             call psmile_error ( PRISM_Error_Alloc, 'b_comps', &
00286                                 ierrp, 2, __FILE__, __LINE__ )
00287             return
00288          endif
00289 !
00290          call psmile_enddef_appl_miss (global_ids, comp_min, comp_max, &
00291                                        b_comps, n_active, tag, ierror)
00292          if (ierror > 0) return
00293 !
00294       else
00295          b_comps => comp_infos
00296       endif
00297 !
00298       Deallocate (global_ids)
00299       endif
00300 !
00301 !-----------------------------------------------------------------------
00302 ! Create communicator for roots of applications
00303 ! Sollte man den permanent machen ?
00304 !-----------------------------------------------------------------------
00305 !
00306       if (Appl%rank == PRISM_root) then
00307          color = 1
00308       else
00309          color = MPI_UNDEFINED
00310       endif
00311 !
00312       key = Appl%sequence_number - 1
00313 !
00314       call MPI_Comm_Split (comm_psmile, color, key, &
00315                            comm_appl_roots, ierror)
00316       if ( ierror /= MPI_SUCCESS ) then
00317          ierrp (1) = ierror
00318          ierror = PRISM_Error_MPI
00319 
00320          call psmile_error ( ierror, 'MPI_Comm_Split', &
00321                              ierrp, 1, __FILE__, __LINE__ )
00322          return
00323       endif 
00324 
00325       if (Appl%rank == PRISM_root) then
00326          call MPI_Comm_rank (comm_appl_roots, rank, ierror)
00327          if ( ierror /= MPI_SUCCESS ) then
00328             ierrp (1) = ierror
00329             ierror = PRISM_Error_MPI
00330 
00331             call psmile_error ( ierror, 'MPI_Comm_Rank', &
00332                                 ierrp, 1, __FILE__, __LINE__ )
00333             return
00334          endif 
00335 !
00336          i_am_master = (rank == PRISM_root)
00337          if (i_am_master) master_rank = psmile_rank
00338 
00339 #ifdef PRISM_ASSERTION
00340 !
00341 !     Internal Control
00342 !
00343          call MPI_Comm_size (comm_appl_roots, size, ierror)
00344          if ( ierror /= MPI_SUCCESS ) then
00345             ierrp (1) = ierror
00346             ierror = PRISM_Error_MPI
00347 
00348             call psmile_error ( ierror, 'MPI_Comm_size', &
00349                                 ierrp, 1, __FILE__, __LINE__ )
00350             return
00351          endif
00352 
00353          if (size /= noApplication) then
00354             write (*, 9970) size, noApplication
00355             call psmile_assert ( __FILE__, __LINE__, &
00356                                  'size /= noApplication')
00357          endif
00358 
00359          if (rank /= Appl%sequence_number-1) then
00360             write (*, 9960) rank, Appl%sequence_number
00361             call psmile_assert ( __FILE__, __LINE__, &
00362                                  'rank /= Appl%sequence_number-1')
00363          endif
00364 #endif /* PRISM_ASSERTION */
00365 
00366       endif
00367 !
00368 !  Broadcast master_rank to all processes
00369 !
00370       i = master_rank
00371 
00372       call MPI_Allreduce (i, master_rank, 1, MPI_INTEGER, &
00373                           MPI_SUM, comm_psmile, ierror)
00374       if ( ierror /= MPI_SUCCESS ) then
00375          ierrp (1) = ierror
00376          ierror = PRISM_Error_MPI
00377 
00378          call psmile_error ( ierror, 'MPI_Allreduce', &
00379                              ierrp, 1, __FILE__, __LINE__ )
00380          return
00381       endif 
00382 !
00383 !  Determine mapping of global var id's to global grid extension id's
00384 !  for variables which are used coupling.
00385 
00386       if ( .not. Appl%stand_alone ) then
00387          call psmile_field2grid (ierror)
00388          if (ierror > 0) return
00389       endif
00390 !
00391 !=======================================================================
00392 ! Collect the data within the roots of applications
00393 ! The data is collected on the root of communicator "comm_appl_roots"
00394 !
00395 ! Collected are:
00396 !
00397 ! Number_of_comps_per_appl : Number of active components per application.
00398 ! root_ranks               : Ranks of roots in psmile communicator
00399 !
00400 ! Number_of_Grids_Vector   : Number of grids per process for each component.
00401 ! psmile_ranks             : Rank in communicator "comm_psmile"
00402 !                            for each process in component.
00403 ! all_extent_infos         : All data about extensions
00404 !=======================================================================
00405 !
00406 !  For stand_alone applications without the driver
00407 !  process we can already return here 
00408 
00409       if ( Appl%stand_alone ) then
00410 #ifdef VERBOSE
00411          print 9980, trim(ch_id), ierror
00412 #endif
00413          return
00414       endif
00415 
00416       if (Appl%rank == PRISM_root) then
00417 !
00418 !      Collect the number of components in the master process
00419 !
00420 !        call MPI_Gather (n_act_comp,               1, MPI_INTEGER, &
00421          call MPI_Gather (n_active,                 1, MPI_INTEGER, &
00422                           Number_of_comps_per_appl, 1, MPI_INTEGER, &
00423                           PRISM_root, comm_appl_roots, ierror)
00424          if ( ierror /= MPI_SUCCESS ) then
00425             ierrp (1) = ierror
00426             ierror = PRISM_Error_MPI
00427 
00428             call psmile_error ( ierror, 'MPI_Gather', &
00429                                 ierrp, 1, __FILE__, __LINE__ )
00430             return
00431          endif 
00432 !
00433 !      Collect the psmile ranks of root processes
00434 !
00435          call MPI_Gather (psmile_rank, 1, MPI_INTEGER, &
00436                           root_ranks,  1, MPI_INTEGER, &
00437                           PRISM_root, comm_appl_roots, ierror)
00438          if ( ierror /= MPI_SUCCESS ) then
00439             ierrp (1) = ierror
00440             ierror = PRISM_Error_MPI
00441 
00442             call psmile_error ( ierror, 'MPI_Gather', &
00443                                 ierrp, 1, __FILE__, __LINE__ )
00444             return
00445          endif 
00446 !
00447 !-----------------------------------------------------------------------
00448 !      Collect the number of processes per component in the master process
00449 !-----------------------------------------------------------------------
00450 !
00451          if (i_am_master) then
00452 ! Number_of_coll_comps == 0: ende ?
00453             Number_of_coll_comps = SUM (Number_of_comps_per_appl(:))
00454 !
00455             if (Number_of_coll_comps < 2 ) &
00456                Appl%stand_alone = .true.
00457 
00458 #ifdef PRISM_ASSERTION_not_needed_anymore
00459             if (Number_of_coll_comps < 2) then
00460                call psmile_assert ( __FILE__, __LINE__, &
00461                  'Total number of active components < 2')
00462             endif
00463 #endif /* PRISM_ASSERTION */
00464 !
00465             Allocate (all_comp_infos(1:Number_of_coll_comps), STAT = ierror)
00466             if ( ierror > 0 ) then
00467                ierrp (1) = ierror
00468                ierrp (2) = Number_of_coll_comps
00469 
00470                ierror = PRISM_Error_Alloc
00471                call psmile_error ( ierror, 'all_comp_infos', &
00472                                    ierrp, 2, __FILE__, __LINE__ )
00473                return
00474             endif
00475 !
00476 !    Get displacement for Collection of components
00477 !
00478             disp (1) = 0
00479 !cdir vector
00480                do iappl = 2, noApplication
00481                disp (iappl) = disp (iappl-1) + Number_of_comps_per_appl (iappl-1)
00482                enddo
00483 
00484              call MPI_Gatherv (b_comps,  n_active, datatype_enddef_comp, &
00485                        all_comp_infos, Number_of_comps_per_appl,         &
00486                                        disp, datatype_enddef_comp,       &
00487                            PRISM_root, comm_appl_roots, ierror)
00488 
00489          else
00490 !
00491 !    ... Note: all_comp_info is not allocated at this time since
00492 !              all_comp_info is significant only on the root process.
00493 !              The SUN run time system doesn't like to transfer
00494 !              the all_comp_infos to MPI_Gatherv.
00495 !
00496              call MPI_Gatherv (b_comps,  n_active, datatype_enddef_comp, &
00497                          dummy_comp_info, Number_of_comps_per_appl,      &
00498                                        disp, datatype_enddef_comp,       &
00499                            PRISM_root, comm_appl_roots, ierror)
00500          endif
00501 
00502          if ( ierror /= MPI_SUCCESS ) then
00503             ierrp (1) = ierror
00504             ierror = PRISM_Error_MPI
00505 
00506             call psmile_error ( ierror, 'MPI_Gatherv', &
00507                                 ierrp, 1, __FILE__, __LINE__ )
00508             return
00509          endif 
00510 !
00511       endif
00512 
00513       call MPI_Bcast ( Appl%stand_alone,1, MPI_Logical, PRISM_Root, Appl%comm, ierror )
00514 
00515       if ( Appl%stand_alone ) then
00516          print 9950, trim(ch_id)
00517 #ifdef VERBOSE
00518          print 9980, trim(ch_id), ierror
00519          call psmile_flushstd
00520 #endif
00521          return
00522       endif
00523 !
00524 !=======================================================================
00525 ! The way back:
00526 !
00527 ! Distribute the data collected to all processes in communicator
00528 ! "comm_psmile".
00529 !
00530 ! (*) Broadcast Number of components "Number_of_coll_comps"
00531 ! (*) Broadcast non-pointers of "all_comp_infos"
00532 !
00533 ! (*) Broadcast vectors
00534 !     Number_of_Grids_Vector, psmile_ranks, all_extent_infos
00535 !     for all components from corresponding roots of applications.
00536 !
00537 ! In prism_enddef_comp koennte man nur in den roots sammeln !
00538 !
00539 !=======================================================================
00540 !
00541       call MPI_Bcast (Number_of_coll_comps, 1, MPI_INTEGER, &
00542                       master_rank, comm_psmile, ierror)
00543       if ( ierror /= MPI_SUCCESS ) then
00544          ierrp (1) = ierror
00545          ierror = PRISM_Error_MPI
00546 
00547          call psmile_error ( ierror, 'MPI_Bcast', &
00548                              ierrp, 1, __FILE__, __LINE__ )
00549          return
00550       endif 
00551 !
00552 ! WARNING: Not ideal. Should be removed.
00553 !
00554       call MPI_Bcast (Number_of_comps_per_appl, NoApplication, MPI_INTEGER, &
00555                       master_rank, comm_psmile, ierror)
00556       if ( ierror /= MPI_SUCCESS ) then
00557          ierrp (1) = ierror
00558          ierror = PRISM_Error_MPI
00559 
00560          call psmile_error ( ierror, 'MPI_Bcast', &
00561                              ierrp, 1, __FILE__, __LINE__ )
00562          return
00563       endif 
00564 !
00565       call MPI_Bcast (root_ranks, NoApplication, MPI_INTEGER, &
00566                       master_rank, comm_psmile, ierror)
00567       if ( ierror /= MPI_SUCCESS ) then
00568          ierrp (1) = ierror
00569          ierror = PRISM_Error_MPI
00570 
00571          call psmile_error ( ierror, 'MPI_Bcast', &
00572                              ierrp, 1, __FILE__, __LINE__ )
00573          return
00574       endif 
00575 !
00576       if (.not. i_am_master) then
00577          Allocate (all_comp_infos(1:Number_of_coll_comps), STAT = ierror)
00578          if ( ierror > 0 ) then
00579             ierrp (1) = ierror
00580             ierrp (2) = Number_of_coll_comps
00581 
00582             ierror = PRISM_Error_Alloc
00583             call psmile_error ( ierror, 'all_comp_infos', &
00584                                 ierrp, 2, __FILE__, __LINE__ )
00585             return
00586          endif
00587       endif
00588 !
00589       call MPI_Bcast (all_comp_infos, Number_of_coll_comps, datatype_enddef_comp, &
00590                       master_rank, comm_psmile, ierror)
00591       if ( ierror /= MPI_SUCCESS ) then
00592          ierrp (1) = ierror
00593          ierror = PRISM_Error_MPI
00594 
00595          call psmile_error ( ierror, 'MPI_Bcast', &
00596                              ierrp, 1, __FILE__, __LINE__ )
00597          return
00598       endif 
00599 !
00600 !  Share pointer for the components of the own application
00601 !
00602 #ifdef PRISM_ASSERTION
00603       if (n_active /= Number_of_comps_per_appl(Appl%sequence_number)) then
00604          print *, 'n_active, Number_of_comps_per_appl ', &
00605                    n_active, Number_of_comps_per_appl(Appl%sequence_number)
00606 
00607          call psmile_assert ( __FILE__, __LINE__, &
00608              'Inconsistent number of active application components in Number_of_comps_per_appl!')
00609       endif
00610 #endif
00611 
00612       my_icomp0_coll_comps = &
00613          SUM (Number_of_comps_per_appl(1:Appl%sequence_number-1))
00614 
00615          do i = 1, n_active
00616 
00617          all_comp_infos(my_icomp0_coll_comps+i)%Number_of_Grids_Vector => &
00618                                      b_comps(i)%Number_of_Grids_Vector
00619 
00620          all_comp_infos(my_icomp0_coll_comps+i)%psmile_ranks => &
00621                                      b_comps(i)%psmile_ranks
00622 
00623          all_comp_infos(my_icomp0_coll_comps+i)%all_extent_infos => &
00624                                      b_comps(i)%all_extent_infos
00625 
00626          end do
00627 !
00628       if (n_miss > 0) then
00629          Deallocate (b_comps)
00630       endif
00631 !
00632 !     Allocate vectors of global component information which are not 
00633 !     contained on the current process and
00634 !     broadcast the data from the root of the application to all processes.
00635 !
00636       icomp = 0
00637          do iappl = 1, NoApplication
00638             do i = 1, Number_of_comps_per_appl(iappl)
00639 
00640             icomp = icomp + 1
00641             size = all_comp_infos(icomp)%size
00642 !
00643             if (iappl /= Appl%sequence_number) then
00644                Allocate (all_comp_infos(icomp)%Number_of_Grids_Vector(1:size), &
00645                          STAT = ierror)
00646                if ( ierror > 0 ) then
00647                   ierrp (1) = ierror
00648                   ierrp (2) = size
00649 
00650                   ierror = PRISM_Error_Alloc
00651                   call psmile_error ( ierror, 'all_comp_infos()%Number_of_Grids_Vector', &
00652                                       ierrp, 2, __FILE__, __LINE__ )
00653                   return
00654                endif
00655                ! initialisation
00656                all_comp_infos(icomp)%Number_of_Grids_Vector(1:size) = 0
00657 !
00658                Allocate (all_comp_infos(icomp)%psmile_ranks(1:size), &
00659                          STAT = ierror)
00660                if ( ierror > 0 ) then
00661                   ierrp (1) = ierror
00662                   ierrp (2) = size
00663 
00664                   ierror = PRISM_Error_Alloc
00665                   call psmile_error ( ierror, 'all_comp_infos()%psmile_ranks', &
00666                                       ierrp, 2, __FILE__, __LINE__ )
00667                   return
00668                endif
00669                ! Initailisation
00670                all_comp_infos(icomp)%psmile_ranks(1:size) = 0
00671 
00672 #ifdef PRISM_ASSERTION
00673             else if (icomp /= my_icomp0_coll_comps+i) then
00674                print *, 'icomp, my_icomp0_coll_comps, i', &
00675                          icomp, my_icomp0_coll_comps, i
00676 
00677                call psmile_assert ( __FILE__, __LINE__, &
00678                                     'inconsistent indices')
00679 #endif
00680             endif
00681 !
00682 !     Broadcast the data which depends on the size of comp communicator
00683 !
00684             call MPI_Bcast (all_comp_infos(icomp)%Number_of_Grids_Vector, &
00685                             size, MPI_INTEGER, &
00686                             root_ranks(iappl), comm_psmile, ierror)
00687             if ( ierror /= MPI_SUCCESS ) then
00688                ierrp (1) = ierror
00689                ierror = PRISM_Error_MPI
00690 
00691                call psmile_error ( ierror, 'MPI_Bcast', &
00692                                    ierrp, 1, __FILE__, __LINE__ )
00693                return
00694             endif 
00695 
00696             call MPI_Bcast (all_comp_infos(icomp)%psmile_ranks, size, &
00697                             MPI_INTEGER, &
00698                             root_ranks(iappl), comm_psmile, ierror)
00699             if ( ierror /= MPI_SUCCESS ) then
00700                ierrp (1) = ierror
00701                ierror = PRISM_Error_MPI
00702 
00703                call psmile_error ( ierror, 'MPI_Bcast', &
00704                                    ierrp, 1, __FILE__, __LINE__ )
00705                return
00706             endif 
00707 !
00708 !     Allocate the data which depends on the number of grids
00709 !
00710             n = SUM (all_comp_infos(icomp)%Number_of_Grids_Vector(:))
00711 
00712             if (iappl /= Appl%sequence_number) then
00713 !
00714                Allocate (all_comp_infos(icomp)%all_extent_infos(n), STAT = ierror)
00715                if ( ierror > 0 ) then
00716                   ierrp (1) = ierror
00717                   ierrp (2) = n * nd_extent_infos
00718 
00719                   ierror = PRISM_Error_Alloc
00720                   call psmile_error ( ierror, 'all_comp_infos()%all_extent_infos', &
00721                                       ierrp, 2, __FILE__, __LINE__ )
00722                   return
00723                endif
00724                ! Initialisation
00725                do j = 1, n
00726                   all_comp_infos(icomp)%all_extent_infos(i)%extent(:,:) = 0
00727                enddo
00728                all_comp_infos(icomp)%all_extent_infos(:)%local_grid_id  = 0
00729                all_comp_infos(icomp)%all_extent_infos(:)%global_grid_id = 0
00730                all_comp_infos(icomp)%all_extent_infos(:)%grid_type      = 0
00731                all_comp_infos(icomp)%all_extent_infos(:)%tr_code        = 0
00732 
00733             endif
00734 !
00735 !     Broadcast the data which depends on the number of grids
00736 !
00737             Allocate (extents_buf(2, ndim_3d, n),                &
00738                       extent_info_buf(nd_extent_infos, n),       &
00739                       STAT = ierror)
00740             if ( ierror > 0 ) then
00741                ierrp (1) = ierror
00742                ierrp (2) = n * (2 * ndim_3d) + n * nd_extent_infos
00743 
00744                ierror = PRISM_Error_Alloc
00745                call psmile_error ( ierror, 'extents_buf, extent_info_buf', &
00746                                    ierrp, 2, __FILE__, __LINE__ )
00747                return
00748             endif
00749 
00750             if (root_ranks(iappl) == psmile_rank) then
00751                do j = 1, n
00752                   extents_buf(:,:,j)   = all_comp_infos(icomp)%all_extent_infos(j)%extent(:,:)
00753                   extent_info_buf(1,j) = all_comp_infos(icomp)%all_extent_infos(j)%local_grid_id
00754                   extent_info_buf(2,j) = all_comp_infos(icomp)%all_extent_infos(j)%global_grid_id
00755                   extent_info_buf(3,j) = all_comp_infos(icomp)%all_extent_infos(j)%grid_type
00756                   extent_info_buf(4,j) = all_comp_infos(icomp)%all_extent_infos(j)%tr_code
00757                enddo
00758             endif
00759 
00760             call MPI_Bcast (extent_info_buf, n*nd_extent_infos, MPI_INTEGER, &
00761                             root_ranks(iappl), comm_psmile, ierror)
00762             if ( ierror /= MPI_SUCCESS ) then
00763                ierrp (1) = ierror
00764                ierror = PRISM_Error_MPI
00765 
00766                call psmile_error ( ierror, 'MPI_Bcast', &
00767                                    ierrp, 1, __FILE__, __LINE__ )
00768                return
00769             endif 
00770 
00771             call MPI_Bcast (extents_buf, n*2*ndim_3d, PSMILe_float_datatype, &
00772                             root_ranks(iappl), comm_psmile, ierror)
00773             if ( ierror /= MPI_SUCCESS ) then
00774                ierrp (1) = ierror
00775                ierror = PRISM_Error_MPI
00776 
00777                call psmile_error ( ierror, 'MPI_Bcast', &
00778                                    ierrp, 1, __FILE__, __LINE__ )
00779                return
00780             endif
00781 
00782             if (root_ranks(iappl) /= psmile_rank) then
00783                do j = 1, n
00784                   all_comp_infos(icomp)%all_extent_infos(j)%extent(:,:)    = extents_buf(:,:,j)
00785                   all_comp_infos(icomp)%all_extent_infos(j)%local_grid_id  = extent_info_buf(1,j)
00786                   all_comp_infos(icomp)%all_extent_infos(j)%global_grid_id = extent_info_buf(2,j)
00787                   all_comp_infos(icomp)%all_extent_infos(j)%grid_type      = extent_info_buf(3,j)
00788                   all_comp_infos(icomp)%all_extent_infos(j)%tr_code        = extent_info_buf(4,j)
00789                enddo
00790             endif
00791 
00792             Deallocate (extents_buf, extent_info_buf)
00793 !
00794             end do ! Component
00795          end do ! Application
00796 !
00797 !=======================================================================
00798 !     Free
00799 !=======================================================================
00800 !
00801 !     Free communicator created (wirklich ? )
00802 !
00803       if (comm_appl_roots /= MPI_COMM_NULL) then
00804          call MPI_Comm_free (comm_appl_roots, ierror)
00805          if ( ierror /= MPI_SUCCESS ) then
00806             ierrp (1) = ierror
00807             ierror = PRISM_Error_MPI
00808 
00809             call psmile_error ( ierror, 'MPI_Comm_free', &
00810                                 ierrp, 1, __FILE__, __LINE__ )
00811             return
00812          endif 
00813       endif
00814 !
00815 !===> All done
00816 !
00817 #ifdef VERBOSE
00818       call psmile_print_comp_info ( all_comp_infos, Number_of_coll_comps, &
00819                                     'End of PSMILe_enddef_appl' )
00820 
00821       print 9980, trim(ch_id), ierror
00822       call psmile_flushstd
00823 #endif /* VERBOSE */
00824 !
00825 !  Formats
00826 !
00827 9990 format (1x, a, ': psmile_enddef_appl')
00828 9980 format (1x, a, ': psmile_enddef_appl: eof ierror =', i3)
00829 9950 format (1x, a, ': psmile_enddef_appl: WARNING: Reset Appl%stand_alone to .true.!')
00830 !
00831 #ifdef PRISM_ASSERTION
00832 
00833 9970 format (/1x, 'psmile_enddef_appl: inconsistent number of applications:', &
00834                   ' size = ', i7, '; noApplication =', i7)
00835 9960 format (/1x, 'psmile_enddef_appl: wrong rank: rank = ', i7, &
00836                   '; Appl%sequence_number =', i7)
00837 #endif /* PRISM_ASSERTION */
00838 !
00839       end subroutine PSMILe_enddef_appl

Generated on 1 Dec 2011 for Oasis4 by  doxygen 1.6.1