*IF DEF,C96_1A,OR,DEF,C96_1B                                               GPB3F403.275    
*IF DEF,MPP                                                                GPB3F403.276    
C *****************************COPYRIGHT******************************     GATFLD1A.3      
C (c) CROWN COPYRIGHT 1996, METEOROLOGICAL OFFICE, All Rights Reserved.    GATFLD1A.4      
C                                                                          GATFLD1A.5      
C Use, duplication or disclosure of this code is subject to the            GATFLD1A.6      
C restrictions as set forth in the contract.                               GATFLD1A.7      
C                                                                          GATFLD1A.8      
C                Meteorological Office                                     GATFLD1A.9      
C                London Road                                               GATFLD1A.10     
C                BRACKNELL                                                 GATFLD1A.11     
C                Berkshire UK                                              GATFLD1A.12     
C                RG12 2SZ                                                  GATFLD1A.13     
C                                                                          GATFLD1A.14     
C If no contract has been raised with this copy of the code, the use,      GATFLD1A.15     
C duplication or disclosure of it is strictly prohibited.  Permission      GATFLD1A.16     
C to do so must first be obtained in writing from the Head of Numerical    GATFLD1A.17     
C Modelling at the above address.                                          GATFLD1A.18     
C ******************************COPYRIGHT******************************    GATFLD1A.19     
!+ Gathers a field from many processors to one processor                   GATFLD1A.20     
!                                                                          GATFLD1A.21     
! Subroutine Interface:                                                    GATFLD1A.22     

      SUBROUTINE GATHER_FIELD(LOCAL_FIELD,GLOBAL_FIELD,                     130GATFLD1A.23     
     &                        LOCAL_ROW_LEN,LOCAL_ROWS,                    GATFLD1A.24     
     &                        GLOBAL_ROW_LEN,GLOBAL_ROWS,                  GATFLD1A.25     
     &                        GATHER_PE,PROC_GROUP,                        GATFLD1A.26     
     &                        INFO)                                        GATFLD1A.27     
                                                                           GATFLD1A.28     
      IMPLICIT NONE                                                        GATFLD1A.29     
                                                                           GATFLD1A.30     
!                                                                          GATFLD1A.31     
! Description:                                                             GATFLD1A.32     
!  Takes a model field that has been decomposed over a group of            GATFLD1A.33     
!  processors, and gathers the data together so that one processor         GATFLD1A.34     
!  contains the entire global field.                                       GATFLD1A.35     
!                                                                          GATFLD1A.36     
! Method:                                                                  GATFLD1A.37     
!  A send and receive map is constructed which instructs the GCOM          GATFLD1A.38     
!  permute operation to do a gather from all processors in the             GATFLD1A.39     
!  group to the GATHER_PE                                                  GATFLD1A.40     
!                                                                          GATFLD1A.41     
! Current Code Owner: Paul Burton                                          GATFLD1A.42     
!                                                                          GATFLD1A.43     
! History:                                                                 GATFLD1A.44     
!  Model    Date      Modification history from model version 4.1          GATFLD1A.45     
!  version                                                                 GATFLD1A.46     
!    4.1    22/1/96   New DECK created for the Parallel Unified            GATFLD1A.47     
!                     Model. P.Burton                                      GATFLD1A.48     
!    4.2    17/10/96  Modify send/receive maps and change args to          GPB2F402.27     
!                     alltoall for GCOM/GCG v1.1     P.Burton              GPB2F402.28     
!    4.4    06/08/97  Recalculate maps if decomposition has changed        GPB1F404.115    
!                                                       Paul Burton        GPB1F404.116    
!                                                                          GATFLD1A.49     
! Subroutine Arguments:                                                    GATFLD1A.50     
                                                                           GATFLD1A.51     
      INTEGER                                                              GATFLD1A.52     
     &  LOCAL_ROW_LEN    ! IN length of rows in local part of field        GATFLD1A.53     
     &, LOCAL_ROWS       ! IN number of rows in local part of field        GATFLD1A.54     
     &, GLOBAL_ROW_LEN   ! IN length of rows in global field               GATFLD1A.55     
     &, GLOBAL_ROWS      ! IN number of rows in global field               GATFLD1A.56     
     &, GATHER_PE        ! IN processor to gather global field to          GATFLD1A.57     
     &, PROC_GROUP       ! IN group ID of processors involved here         GATFLD1A.58     
     &, INFO             ! OUT return code from comms                      GATFLD1A.59     
                                                                           GATFLD1A.60     
      REAL                                                                 GATFLD1A.61     
     &  LOCAL_FIELD(LOCAL_ROW_LEN*LOCAL_ROWS)                              GATFLD1A.62     
!                        ! IN local part of field                          GATFLD1A.63     
     &, GLOBAL_FIELD(GLOBAL_ROW_LEN*GLOBAL_ROWS)                           GATFLD1A.64     
!                        ! OUT (on PE GATHER_PE) global field              GATFLD1A.65     
                                                                           GATFLD1A.66     
! Parameters and Common blocks                                             GATFLD1A.67     
                                                                           GATFLD1A.68     
*CALL PARVARS                                                              GATFLD1A.69     
*CALL GCCOM                                                                GPB2F402.29     
                                                                           GATFLD1A.70     
! Local variables                                                          GATFLD1A.71     
                                                                           GATFLD1A.72     
      INTEGER                                                              GATFLD1A.73     
     &   send_map(7,1)                                                     GPB2F402.30     
     &,  receive_map(7,MAXPROC)                                            GPB2F402.31     
     &,  n_mess_to_rec                                                     GATFLD1A.76     
                                                                           GATFLD1A.77     
      INTEGER                                                              GATFLD1A.78     
     &  old_GLOBAL_ROW_LEN    ! value on last call                         GATFLD1A.79     
     &, old_GLOBAL_ROWS       ! value on last call                         GATFLD1A.80     
     &, old_PROC_GROUP        ! value on last call                         GATFLD1A.81     
     &, old_GATHER_PE         ! value on last call                         GATFLD1A.82     
     &, old_DECOMP            ! value on last call                         GPB1F404.117    
                                                                           GATFLD1A.83     
      SAVE send_map,receive_map,n_mess_to_rec,                             GATFLD1A.84     
     &     old_GLOBAL_ROW_LEN,old_GLOBAL_ROWS,old_PROC_GROUP,              GATFLD1A.85     
     &     old_GATHER_PE,old_DECOMP                                        GPB1F404.118    
      DATA old_GLOBAL_ROW_LEN,old_GLOBAL_ROWS,old_PROC_GROUP,              GATFLD1A.87     
     &     old_GATHER_PE,old_DECOMP                                        GPB1F404.119    
     &   / -1234, -1234, -1234, -1234, -1234/                              GPB1F404.120    
                                                                           GATFLD1A.90     
      INTEGER                                                              GATFLD1A.91     
     &  fld_type                                                           GATFLD1A.92     
     &, iproc                                                              GATFLD1A.93     
     &, flag                                                               GATFLD1A.94     
                                                                           GATFLD1A.95     
!-------------------------------------------------------                   GATFLD1A.96     
                                                                           GATFLD1A.97     
! 0.0 Can we use the same send/receive map that we calculated              GATFLD1A.98     
!     last time round?                                                     GATFLD1A.99     
                                                                           GATFLD1A.100    
      IF ((GLOBAL_ROW_LEN .NE. old_GLOBAL_ROW_LEN) .OR.                    GATFLD1A.101    
     &    (GLOBAL_ROWS    .NE. old_GLOBAL_ROWS   ) .OR.                    GATFLD1A.102    
     &    (PROC_GROUP     .NE. old_PROC_GROUP    ) .OR.                    GATFLD1A.103    
     &    (GATHER_PE     .NE. old_GATHER_PE    ) .OR.                      GPB1F404.121    
     &    (current_decomp_type .NE. old_DECOMP  )) THEN                    GPB1F404.122    
!       Different arguments from the last call so we need                  GATFLD1A.105    
!       to calculate a new send/receive map                                GATFLD1A.106    
                                                                           GATFLD1A.107    
! 1.0 Find the type of field (P or U) being done                           GATFLD1A.108    
                                                                           GATFLD1A.109    
        IF (GLOBAL_ROWS .EQ. glsize(2)) THEN                               GATFLD1A.110    
          fld_type=fld_type_p                                              GATFLD1A.111    
        ELSEIF (GLOBAL_ROWS .EQ. glsize(2)-1) THEN                         GATFLD1A.112    
          fld_type=fld_type_u                                              GATFLD1A.113    
        ELSE                                                               GATFLD1A.114    
          WRITE(6,*) 'Bad field type in GATHER_FIELD'                      GATFLD1A.115    
          info=-1                                                          GATFLD1A.116    
          GOTO 9999                                                        GATFLD1A.117    
        ENDIF                                                              GATFLD1A.118    
                                                                           GATFLD1A.119    
                                                                           GATFLD1A.120    
! 2.0 Set up send map                                                      GATFLD1A.121    
                                                                           GATFLD1A.122    
        send_map(S_DESTINATION_PE,1) = GATHER_PE                           GPB2F402.32     
!       processor to send to                                               GPB2F402.33     
                                                                           GPB2F402.34     
        send_map(S_BASE_ADDRESS_IN_SEND_ARRAY,1) =                         GPB2F402.35     
     &    Offy*LOCAL_ROW_LEN+1+Offx                                        GPB2F402.36     
!       first data to send                                                 GPB2F402.37     
                                                                           GPB2F402.38     
        IF (atbase) THEN                                                   GATFLD1A.125    
          IF (fld_type .EQ. fld_type_p) THEN                               GATFLD1A.126    
            send_map(S_NUMBER_OF_ELEMENTS_IN_ITEM,1)=LOCAL_ROWS-2*Offy     GPB2F402.39     
!           number of rows                                                 GPB2F402.40     
                                                                           GPB2F402.41     
          ELSE                                                             GATFLD1A.128    
            send_map(S_NUMBER_OF_ELEMENTS_IN_ITEM,1)=LOCAL_ROWS-2*Offy-1   GPB2F402.42     
                                                                           GPB2F402.43     
!           One less row at the bottom of a U field                        GATFLD1A.130    
          ENDIF                                                            GATFLD1A.131    
        ELSE                                                               GATFLD1A.132    
          send_map(S_NUMBER_OF_ELEMENTS_IN_ITEM,1) = LOCAL_ROWS-2*Offy     GPB2F402.44     
!         number of rows                                                   GPB2F402.45     
                                                                           GPB2F402.46     
        ENDIF                                                              GATFLD1A.134    
        send_map(S_STRIDE_IN_SEND_ARRAY,1) = LOCAL_ROW_LEN                 GPB2F402.47     
!       stride between row starts                                          GPB2F402.48     
                                                                           GPB2F402.49     
        send_map(S_ELEMENT_LENGTH,1) = LOCAL_ROW_LEN-2*Offx                GPB2F402.50     
!       length of local row minus halos                                    GPB2F402.51     
                                                                           GPB2F402.52     
        send_map(S_BASE_ADDRESS_IN_RECV_ARRAY,1) =                         GPB2F402.53     
     &    datastart(1)+(datastart(2)-1)*GLOBAL_ROW_LEN                     GPB2F402.54     
!       start position in global data of this local data                   GPB2F402.55     
                                                                           GPB2F402.56     
        send_map(S_STRIDE_IN_RECV_ARRAY,1) = GLOBAL_ROW_LEN                GPB2F402.57     
!       stride between rows in global data                                 GPB2F402.58     
                                                                           GPB2F402.59     
                                                                           GATFLD1A.142    
! 3.0 Set up the receive map (for PE GATHER_PE only)                       GATFLD1A.143    
                                                                           GATFLD1A.144    
! Assume here that this group consists of all processors                   GATFLD1A.145    
! We'll get some new GCG functionality soon to improve this                GATFLD1A.146    
                                                                           GATFLD1A.147    
        n_mess_to_rec=0                                                    GATFLD1A.148    
                                                                           GATFLD1A.149    
        IF (mype .EQ. GATHER_PE) THEN                                      GATFLD1A.150    
          DO iproc=0,nproc-1                                               GATFLD1A.151    
            receive_map(R_SOURCE_PE,iproc+1) = iproc                       GPB2F402.60     
                                                                           GPB2F402.61     
            receive_map(R_BASE_ADDRESS_IN_RECV_ARRAY,iproc+1) =            GPB2F402.62     
     &        g_datastart(1,iproc)+(g_datastart(2,iproc)-1)*glsize(1)      GPB2F402.63     
                                                                           GPB2F402.64     
            IF (fld_type .EQ. fld_type_p) THEN                             GATFLD1A.155    
              receive_map(R_NUMBER_OF_ELEMENTS_IN_ITEM,iproc+1) =          GPB2F402.65     
     &          g_blsizep(2,iproc)                                         GPB2F402.66     
                                                                           GPB2F402.67     
            ELSE                                                           GATFLD1A.157    
              receive_map(R_NUMBER_OF_ELEMENTS_IN_ITEM,iproc+1) =          GPB2F402.68     
     &          g_blsizeu(2,iproc)                                         GPB2F402.69     
            ENDIF                                                          GATFLD1A.159    
            receive_map(R_STRIDE_IN_RECV_ARRAY,iproc+1) =                  GPB2F402.70     
     &        GLOBAL_ROW_LEN                                               GPB2F402.71     
                                                                           GPB2F402.72     
            receive_map(R_ELEMENT_LENGTH,iproc+1) = g_blsizep(1,iproc)     GPB2F402.73     
                                                                           GPB2F402.74     
            receive_map(R_BASE_ADDRESS_IN_SEND_ARRAY,iproc+1) =            GPB2F402.75     
     &        Offy*g_lasize(1,iproc)+Offx+1                                GPB2F402.76     
                                                                           GPB2F402.77     
            receive_map(R_STRIDE_IN_SEND_ARRAY,iproc+1) =                  GPB2F402.78     
     &        g_lasize(1,iproc)                                            GPB2F402.79     
                                                                           GPB2F402.80     
          ENDDO                                                            GATFLD1A.164    
          n_mess_to_rec=nproc                                              GATFLD1A.165    
        ENDIF                                                              GATFLD1A.166    
                                                                           GATFLD1A.167    
        old_GLOBAL_ROW_LEN=GLOBAL_ROW_LEN                                  GATFLD1A.168    
        old_GLOBAL_ROWS=GLOBAL_ROWS                                        GATFLD1A.169    
        old_PROC_GROUP=PROC_GROUP                                          GATFLD1A.170    
        old_GATHER_PE=GATHER_PE                                            GATFLD1A.171    
        old_DECOMP=current_decomp_type                                     GPB1F404.123    
                                                                           GATFLD1A.172    
      ENDIF  ! we need to recalculate send/receive maps.                   GATFLD1A.173    
                                                                           GATFLD1A.174    
! 4.0 Do the exchange of data                                              GATFLD1A.175    
                                                                           GATFLD1A.176    
      flag=0  ! This is currently ignored at GCG v1.1                      GPB2F402.81     
                                                                           GPB2F402.82     
      CALL GC_SETOPT(GC_SHM_DIR,GC_SHM_PUT,info)  ! gather operation       GPB2F402.83     
      info=GC_NONE                                                         GPB2F402.84     
                                                                           GATFLD1A.178    
      CALL GCG_RALLTOALLE(LOCAL_FIELD,send_map,1,                          GATFLD1A.179    
     &                    LOCAL_ROW_LEN*LOCAL_ROWS,                        GPB2F402.85     
     &                    GLOBAL_FIELD,receive_map,n_mess_to_rec,          GATFLD1A.181    
     &                    GLOBAL_ROW_LEN*GLOBAL_ROWS,                      GPB2F402.86     
     &                    PROC_GROUP,flag,info)                            GATFLD1A.183    
                                                                           GATFLD1A.184    
 9999 CONTINUE                                                             GATFLD1A.185    
                                                                           GATFLD1A.186    
      RETURN                                                               GATFLD1A.187    
      END                                                                  GATFLD1A.188    
*ENDIF                                                                     GATFLD1A.189    
*ENDIF                                                                     GPB3F403.277