*IF DEF,A10_1B                                                             SETFIL1B.2      
C ******************************COPYRIGHT******************************    SETFIL1B.3      
C (c) CROWN COPYRIGHT 1996, METEOROLOGICAL OFFICE, All Rights Reserved.    SETFIL1B.4      
C                                                                          SETFIL1B.5      
C Use, duplication or disclosure of this code is subject to the            SETFIL1B.6      
C restrictions as set forth in the contract.                               SETFIL1B.7      
C                                                                          SETFIL1B.8      
C                Meteorological Office                                     SETFIL1B.9      
C                London Road                                               SETFIL1B.10     
C                BRACKNELL                                                 SETFIL1B.11     
C                Berkshire UK                                              SETFIL1B.12     
C                RG12 2SZ                                                  SETFIL1B.13     
C                                                                          SETFIL1B.14     
C If no contract has been raised with this copy of the code, the use,      SETFIL1B.15     
C duplication or disclosure of it is strictly prohibited.  Permission      SETFIL1B.16     
C to do so must first be obtained in writing from the Head of Numerical    SETFIL1B.17     
C Modelling at the above address.                                          SETFIL1B.18     
C ******************************COPYRIGHT******************************    SETFIL1B.19     
C                                                                          SETFIL1B.20     
CLL  SUBROUTINE SET_FIL     -----------------------------------------      SETFIL1B.21     
CLL                                                                        SETFIL1B.22     
CLL  PURPOSE: CALCULATES THE WAVE-NUMBER ON EACH ROW AT WHICH FOURIER      SETFIL1B.23     
CLL           FILTERING SHOULD BEGIN. AS FOURIER CHOPPING IS BEING USED    SETFIL1B.24     
CLL           THIS WAVE-NUMBER ONLY AND NO WEIGHTS ARE RETURNED. THE       SETFIL1B.25     
CLL           ROW IN EACH HEMISPHERE ON WHICH FILTERING ENDS IS ALSO       SETFIL1B.26     
CLL           RETURNED.                                                    SETFIL1B.27     
CLL  N.B.     CODE WILL ALWAYS FILTER 1 ROW IN NORTHERN HEMISPHERE.        SETFIL1B.28     
CLL           THIS DOES NOT IMPLY THAT SOME WAVE NUMBERS ON THAT ROW       SETFIL1B.29     
CLL           ARE CHOPPED, IT IS MERELY A WAY OF AVOIDING ALLOCATING A     SETFIL1B.30     
CLL           ZERO LENGTH ARRAY IN FILTER WHICH CAUSES A FAILURE.          SETFIL1B.31     
CLL  NOT SUITABLE FOR I.B.M USE.                                           SETFIL1B.32     
CLL                                                                        SETFIL1B.33     
CLL  WRITTEN BY M.H MAWSON.                                                SETFIL1B.34     
CLL                                                                        SETFIL1B.35     
CLL  MODEL            MODIFICATION HISTORY:                                SETFIL1B.36     
CLL VERSION  DATE                                                          SETFIL1B.37     
!LL   4.2   25/10/96  New deck for HADCM2-specific section A10_1B,         SETFIL1B.38     
!LL                   as SETFIL1A but with reintroduced error in           SETFIL1B.39     
!LL                   computation of SH filter row.       T.Johns          SETFIL1B.40     
!LL   4.3   14/04/97  Print warning if filtering entire area.  T Johns     ATJ0F403.45     
!LL                   Correct HADCM2-specific code to use global row.      ATJ0F403.46     
!LL   4.4   08/08/97  Remove FFT filter data common block,                 GPB2F404.291    
!LL                   Add code for chunking optimisation                   GPB2F404.292    
!LL                                                         P.Burton       GPB2F404.293    
!LL   4.5   24/02/98  Catch error when whole model is filtered.            GPB0F405.53     
!LL                                                 Paul Burton            GPB0F405.54     
CLL                                                                        SETFIL1B.41     
CLL  PROGRAMMING STANDARD: UNIFIED MODEL DOCUMENTATION PAPER NO. 4,        SETFIL1B.42     
CLL                         STANDARD B.                                    SETFIL1B.43     
CLL                                                                        SETFIL1B.44     
CLL  SYSTEM COMPONENTS COVERED: P141                                       SETFIL1B.45     
CLL                                                                        SETFIL1B.46     
CLL  SYSTEM TASK: P1                                                       SETFIL1B.47     
CLL                                                                        SETFIL1B.48     
CLL  DOCUMENTATION:        EQUATIONS (50) TO (52) IN SECTION 3.5           SETFIL1B.49     
CLL                        OF UNIFIED MODEL DOCUMENTATION PAPER            SETFIL1B.50     
CLL                        NO. 10 M.J.P. CULLEN,T.DAVIES AND M.H.MAWSON    SETFIL1B.51     
CLL                                                                        SETFIL1B.52     
CLLEND-------------------------------------------------------------        SETFIL1B.53     
                                                                           SETFIL1B.54     
C                                                                          SETFIL1B.55     
C*L  ARGUMENTS:---------------------------------------------------         SETFIL1B.56     

      SUBROUTINE SET_FIL                                                    1,4SETFIL1B.57     
     1                  (U,C,ADJUSTMENT_TIMESTEP,ADVECTION_TIMESTEP,       SETFIL1B.58     
     2                   SEC_P_LATITUDE,FILTER_WAVE_NUMBER_P_ROWS,         SETFIL1B.59     
     3                   FILTER_WAVE_NUMBER_U_ROWS,                        SETFIL1B.60     
     4                   LONGITUDE_STEP_INVERSE,NORTHERN_FILTERED_P_ROW,   SETFIL1B.61     
     5                   SOUTHERN_FILTERED_P_ROW,P_FIELD,U_FIELD,          SETFIL1B.62     
     6                   P_LEVELS,ROW_LENGTH,                              SETFIL1B.63     
*CALL ARGFLDPT                                                             SETFIL1B.64     
     7                   FILTERING_SAFETY_FACTOR,TWO_D_GRID_CORRECTION)    SETFIL1B.65     
                                                                           SETFIL1B.66     
      IMPLICIT NONE                                                        SETFIL1B.67     
                                                                           SETFIL1B.68     
! All FLDPTR arguments are intent IN                                       SETFIL1B.69     
*CALL TYPFLDPT                                                             SETFIL1B.70     
                                                                           SETFIL1B.71     
      INTEGER                                                              SETFIL1B.72     
     *  P_FIELD            !IN DIMENSION OF FIELDS ON PRESSURE GRID        SETFIL1B.73     
     *, U_FIELD            !IN DIMENSION OF FIELDS ON VELOCITY GRID        SETFIL1B.74     
     *, P_LEVELS           !IN NUMBER OF MODEL LEVELS.                     SETFIL1B.75     
     *, ROW_LENGTH         !IN NUMBER OF POINTS ON A ROW.                  SETFIL1B.76     
     *, NORTHERN_FILTERED_P_ROW !IN LAST ROW, MOVING EQUATORWARDS,         SETFIL1B.77     
     *                          ! IN NORTHERN HEMISPHERE                   SETFIL1B.78     
     *                          ! ON WHICH FILTERING IS PERFORMED.         SETFIL1B.79     
     *, SOUTHERN_FILTERED_P_ROW !IN LAST ROW, MOVING EQUATORWARDS,         SETFIL1B.80     
     *                          ! IN SOUTHERN HEMISPHERE                   SETFIL1B.81     
     *                          ! ON WHICH FILTERING IS PERFORMED.         SETFIL1B.82     
                                                                           SETFIL1B.83     
      INTEGER                                                              SETFIL1B.84     
     &  FILTER_WAVE_NUMBER_P_ROWS(GLOBAL_P_FIELD/GLOBAL_ROW_LENGTH)        SETFIL1B.85     
     &      ! LARGEST WAVE NUMBER ON EACH P ROW WHICH IS NOT FILTERED      SETFIL1B.86     
     &, FILTER_WAVE_NUMBER_U_ROWS(GLOBAL_U_FIELD/GLOBAL_ROW_LENGTH)        SETFIL1B.87     
     &      ! LARGEST WAVE NUMBER ON EACH U ROW WHICH IS NOT FILTERED      SETFIL1B.88     
                                                                           SETFIL1B.89     
                                                                           SETFIL1B.90     
      REAL                                                                 SETFIL1B.91     
     * U(U_FIELD,P_LEVELS)     !IN ZONAL WIND COMPONENT.                   SETFIL1B.92     
     *,SEC_P_LATITUDE(P_FIELD) !IN 1/(COS(LAT)) AT P POINTS.               SETFIL1B.93     
     *,ADJUSTMENT_TIMESTEP     !IN                                         SETFIL1B.94     
     *,ADVECTION_TIMESTEP      !IN                                         SETFIL1B.95     
     *,C                       !IN EXTENAL GRAVITY WAVE SPEED.             SETFIL1B.96     
     *,LONGITUDE_STEP_INVERSE  !IN 1/(DELTA LAMDA)                         SETFIL1B.97     
     *,TWO_D_GRID_CORRECTION(P_FIELD/ROW_LENGTH) !IN TERM REPRESENTING     SETFIL1B.98     
     *                         ! 2-D EFFECT OF WAVES COMPARED TO 1D        SETFIL1B.99     
     *                         ! REPRESENTATION USED HERE.                 SETFIL1B.100    
     *,FILTERING_SAFETY_FACTOR !IN TERM REPRESENTING SAFETY MARGIN TO      SETFIL1B.101    
     *                         ! ADD TO GRID_CORRECTION                    SETFIL1B.102    
C*---------------------------------------------------------------------    SETFIL1B.103    
*IF DEF,MPP                                                                SETFIL1B.104    
! Common blocks and parameters for MPP code                                SETFIL1B.105    
*CALL PARVARS                                                              SETFIL1B.106    
*CALL PARFFTS                                                              SETFIL1B.107    
*CALL GCCOM                                                                SETFIL1B.108    
*ENDIF                                                                     SETFIL1B.109    
                                                                           SETFIL1B.110    
C*L  DEFINE ARRAYS AND VARIABLES USED IN THIS ROUTINE-----------------     SETFIL1B.111    
C   DEFINE LOCAL ARRAYS: NONE ARE REQUIRED                                 SETFIL1B.112    
                                                                           SETFIL1B.113    
C*---------------------------------------------------------------------    SETFIL1B.114    
C   DEFINE LOCAL VARIABLES                                                 SETFIL1B.115    
                                                                           SETFIL1B.116    
      REAL                                                                 SETFIL1B.117    
     *  COURANT         !HOLDS MAXIMUM COURANT NUMBER.                     SETFIL1B.118    
     *, ADVECTION_COURANT ! HOLDS ADVECTION COURANT NUMBER.                SETFIL1B.119    
     *, ADJUSTMENT_COURANT ! HOLDS ADJUSTMENT COURANT NUMBER.              SETFIL1B.120    
     *, C_TERM          ! HOLDS TERM WHICH MULTIPLIES EPSI_J IN            SETFIL1B.121    
     *                  ! EQUATION 50.                                     SETFIL1B.122    
     *, C_CONST         ! HOLDS CONSTANT PART OF C_TERM                    SETFIL1B.123    
                                                                           SETFIL1B.124    
      REAL                                                                 SETFIL1B.125    
     *  SCALAR1                                                            SETFIL1B.126    
     *, SCALAR2                                                            SETFIL1B.127    
     *, ALPHA           ! HOLDS DELTA LAMDA / COS(LAT)                     SETFIL1B.128    
      REAL                                                                 SETFIL1B.129    
     &  U_MAX_INITIAL(P_FIELD/ROW_LENGTH)                                  SETFIL1B.130    
! Holds maximum windspeed along each U row                                 SETFIL1B.131    
     &,    U_MAX(P_FIELD/ROW_LENGTH)  ! Holds maximum windspeed            SETFIL1B.132    
                                      ! along each P row                   SETFIL1B.133    
C TWO DIFFERENT NAMES NEEDED WHERE ONE WOULD SUFFICE TO STRICTLY CONFORM   SETFIL1B.134    
C WITH CRAY'S CASE CONSTRUCT. SEE ALSO CUT_OFF_N AND CUT_OFF_S.            SETFIL1B.135    
                                                                           SETFIL1B.136    
C   COUNT VARIABLES FOR DO LOOPS ETC.                                      SETFIL1B.137    
      INTEGER                                                              SETFIL1B.138    
     *  I,K                                                                SETFIL1B.139    
     &, CUT_OFF         ! HOLDS SMALLEST WAVE NUMBER FILTERED.             SETFIL1B.140    
     *, P_ROWS          ! HOLDS NUMBER OF ROWS OF DATA ON P_GRID           SETFIL1B.141    
     *, HALF_P_ROWS     ! HOLDS HALF NUMBER OF ROWS OF DATA ON P_GRID      SETFIL1B.142    
     *, ROW             ! LOOP COUNTER WHICH IS THE ROW ON WHICH           SETFIL1B.143    
     *                  ! CALCULATION IS TAKING PLACE.                     SETFIL1B.144    
*IF DEF,MPP                                                                SETFIL1B.145    
      INTEGER                                                              SETFIL1B.146    
     &  ROW_START,ROW_END     ! Start and end points for loop over rows    SETFIL1B.147    
     &, global_row            ! global row number of local row             SETFIL1B.148    
     &, local_row             ! local row number of global row             SETFIL1B.149    
     &, glob_filterable_rows  ! Global number of rows for filtering        SETFIL1B.150    
     &, approx_ffts_per_proc  ! Rough estimate of number of ffts/proc      SETFIL1B.151    
     &, remainder_ffts        ! "Spare" ffts to be added on                SETFIL1B.152    
     &, filt_row_number       ! filterable row number                      SETFIL1B.153    
     &, filt_row_index        ! index for a (row,level) to be fft'd        SETFIL1B.154    
     &, change_pt             ! used in calculation of decomposition       SETFIL1B.155    
     &, proc_row              ! Current processor row                      SETFIL1B.156    
     &, proc_dest             ! Processor to send a row to                 SETFIL1B.157    
     &, n_send                ! No. of fft data blocks I will send         SETFIL1B.158    
     &, n_recv                ! No. of fft data blocks I will receive      SETFIL1B.159    
     &, fld_type              ! indicator of field type (P or U)           SETFIL1B.160    
     &, north_filt_row        ! local vn for fld_type                      SETFIL1B.161    
     &, south_filt_row        ! local vn for fld_type                      SETFIL1B.162    
     &, n_glob_rows           ! number of global rows for fld_type         SETFIL1B.163    
     &, oproc_dest            ! destination of last previous row           SETFIL1B.164    
     &, sourcepe              ! processor this row comes from              SETFIL1B.165    
     &, row_number            ! row number of this row                     SETFIL1B.166    
     &, fft_row_len           ! row length of fft data (glsize(1)+2)       GPB2F404.294    
     &, J                     ! loop counter                               SETFIL1B.167    
     &, info                  ! return code for comms                      SETFIL1B.168    
                                                                           SETFIL1B.169    
                                                                           SETFIL1B.170    
      LOGICAL                                                              SETFIL1B.171    
     &  sending               ! Am I sending this row?                     SETFIL1B.172    
                                                                           SETFIL1B.173    
      LOGICAL called_before                                                SETFIL1B.174    
      DATA called_before/.FALSE./                                          SETFIL1B.175    
      INTEGER old_northern_filt,old_southern_filt                          SETFIL1B.176    
      SAVE called_before,old_northern_filt,old_southern_filt               SETFIL1B.177    
                                                                           SETFIL1B.178    
*ENDIF                                                                     SETFIL1B.179    
                                                                           SETFIL1B.180    
                                                                           SETFIL1B.181    
C*L  EXTERNAL SUBROUTINE CALLS:------------------------------------        SETFIL1B.182    
*IF DEF,CRAY                                                               SETFIL1B.183    
*IF -DEF,MPP                                                               SETFIL1B.184    
      INTEGER index                                                        SETFIL1B.185    
*ENDIF                                                                     SETFIL1B.186    
      INTEGER ISAMAX                                                       SETFIL1B.187    
      EXTERNAL ISAMAX                                                      SETFIL1B.188    
*ELSE                                                                      SETFIL1B.189    
C NO EXTERNAL SUBROUTINE CALLS                                             SETFIL1B.190    
*ENDIF                                                                     SETFIL1B.191    
C*---------------------------------------------------------------------    SETFIL1B.192    
CL CALL COMDECK TO GET CONSTANTS USED.                                     SETFIL1B.193    
                                                                           SETFIL1B.194    
*CALL C_SETFIL                                                             SETFIL1B.195    
                                                                           SETFIL1B.196    
CL  MAXIMUM VECTOR LENGTH ASSUMED IS ROW_LENGTH                            SETFIL1B.197    
CL---------------------------------------------------------------------    SETFIL1B.198    
CL    INTERNAL STRUCTURE.                                                  SETFIL1B.199    
CL---------------------------------------------------------------------    SETFIL1B.200    
CL                                                                         SETFIL1B.201    
                                                                           SETFIL1B.202    
*IF DEF,MPP                                                                SETFIL1B.203    
                                                                           SETFIL1B.204    
      IF (.NOT. called_before) THEN                                        SETFIL1B.205    
        called_before=.TRUE.                                               SETFIL1B.206    
        old_northern_filt=-1                                               SETFIL1B.207    
        old_southern_filt=-1                                               SETFIL1B.208    
      ENDIF                                                                SETFIL1B.209    
                                                                           SETFIL1B.210    
*ENDIF                                                                     SETFIL1B.211    
                                                                           SETFIL1B.212    
      C_CONST = C* ADJUSTMENT_TIMESTEP * LONGITUDE_STEP_INVERSE / A        SETFIL1B.213    
      C_CONST = C_CONST * C_CONST                                          SETFIL1B.214    
      ALPHA=1.0/LONGITUDE_STEP_INVERSE                                     SETFIL1B.215    
      P_ROWS=P_FIELD/ROW_LENGTH                                            SETFIL1B.216    
*IF -DEF,MPP                                                               SETFIL1B.217    
      HALF_P_ROWS=P_ROWS/2                                                 SETFIL1B.218    
*ELSE                                                                      SETFIL1B.219    
      HALF_P_ROWS=glsize(2)/2    ! half number of global rows              SETFIL1B.220    
*ENDIF                                                                     SETFIL1B.221    
                                                                           SETFIL1B.222    
! Caculate the local maximum U along each row                              SETFIL1B.223    
                                                                           SETFIL1B.224    
*IF -DEF,MPP                                                               SETFIL1B.225    
      U_MAX_INITIAL(1)=0.0                                                 SETFIL1B.226    
      U_MAX_INITIAL(P_ROWS)=0.0                                            SETFIL1B.227    
      DO ROW=2,P_ROWS-1                                                    SETFIL1B.228    
*ELSE                                                                      SETFIL1B.229    
      DO ROW=1,Offy                                                        SETFIL1B.230    
        U_MAX_INITIAL(ROW)=0.0                                             SETFIL1B.231    
        U_MAX_INITIAL(P_ROWS+1-ROW)=0.0                                    SETFIL1B.232    
      ENDDO                                                                SETFIL1B.233    
      DO ROW=1+Offy,P_ROWS-Offy  ! loop over local rows, missing halos     SETFIL1B.234    
*ENDIF                                                                     SETFIL1B.235    
        SCALAR1=0.0                                                        SETFIL1B.236    
        DO K=1,P_LEVELS                                                    SETFIL1B.237    
*IF DEF,CRAY,AND,-DEF,MPP                                                  SETFIL1B.238    
          index=ISAMAX(ROW_LENGTH,U((ROW-1)*ROW_LENGTH+1,K),1)             SETFIL1B.239    
          SCALAR1=                                                         SETFIL1B.240    
     &      MAX(ABS(U((ROW-1)*ROW_LENGTH+index,K)),SCALAR1)                SETFIL1B.241    
*ELSE                                                                      SETFIL1B.242    
*IF -DEF,MPP                                                               SETFIL1B.243    
          DO I=(ROW-1)*ROW_LENGTH+1,ROW*ROW_LENGTH                         SETFIL1B.244    
*ELSE                                                                      SETFIL1B.245    
          DO I=(ROW-1)*ROW_LENGTH+1+Offx,ROW*ROW_LENGTH-Offx               SETFIL1B.246    
*ENDIF                                                                     SETFIL1B.247    
            SCALAR1=MAX(ABS(U(I,K)),SCALAR1)                               SETFIL1B.248    
          ENDDO                                                            SETFIL1B.249    
*ENDIF                                                                     SETFIL1B.250    
        ENDDO  ! loop over levels                                          SETFIL1B.251    
        U_MAX_INITIAL(ROW)=SCALAR1                                         SETFIL1B.252    
      ENDDO  ! loop over rows                                              SETFIL1B.253    
                                                                           SETFIL1B.254    
*IF DEF,MPP                                                                SETFIL1B.255    
! We only have the local maximum so far. We must now do a maximum          SETFIL1B.256    
! along each global row.                                                   SETFIL1B.257    
                                                                           SETFIL1B.258    
       CALL GCG_RMAX(P_ROWS-2*Offy,gc_proc_row_group,info,                 SETFIL1B.259    
     &               U_MAX_INITIAL(1+Offy))                                SETFIL1B.260    
                                                                           SETFIL1B.261    
! We need to know the values of the rows above and below us, so            SETFIL1B.262    
! fill in the halos with this information                                  SETFIL1B.263    
      CALL SWAPBOUNDS(U_MAX_INITIAL,1,P_ROWS,0,Offy,1)                     SETFIL1B.264    
*ENDIF                                                                     SETFIL1B.265    
                                                                           SETFIL1B.266    
! Now calculate the maximum "wind" along each P_ROW, by taking the         SETFIL1B.267    
! maximum wind of the U_ROW either side of it:                             SETFIL1B.268    
! MAX_WIND(P_ROW)=MAX(U_MAX(P_ROW),U_MAX(P_ROW-1))                         SETFIL1B.269    
                                                                           SETFIL1B.270    
*IF -DEF,MPP                                                               SETFIL1B.271    
      DO ROW=2,P_ROWS-1                                                    SETFIL1B.272    
*ELSE                                                                      SETFIL1B.273    
      IF (attop) THEN                                                      SETFIL1B.274    
        ROW_START=Offy+2                                                   SETFIL1B.275    
      ELSE                                                                 SETFIL1B.276    
        ROW_START=Offy+1                                                   SETFIL1B.277    
      ENDIF                                                                SETFIL1B.278    
      IF (atbase) THEN                                                     SETFIL1B.279    
        ROW_END= P_ROWS-Offy-1                                             SETFIL1B.280    
      ELSE                                                                 SETFIL1B.281    
        ROW_END=P_ROWS-Offy                                                SETFIL1B.282    
      ENDIF                                                                SETFIL1B.283    
                                                                           SETFIL1B.284    
      DO ROW=ROW_START,ROW_END  ! loop over local rows                     SETFIL1B.285    
*ENDIF                                                                     SETFIL1B.286    
! Deliberately reintroduce error in computation of SH filter row           SETFIL1B.287    
*IF DEF,MPP                                                                ATJ0F403.47     
! Must use the global rather than local row number to decide if MPP        ATJ0F403.48     
        IF (ROW+datastart(2)-Offy-1 .GE. HALF_P_ROWS+2) THEN               ATJ0F403.49     
*ELSE                                                                      ATJ0F403.50     
        IF (ROW .GE. HALF_P_ROWS+2) THEN                                   SETFIL1B.288    
*ENDIF                                                                     ATJ0F403.51     
! This is the error; 0.0 implies only one row is considered in SH          SETFIL1B.289    
          U_MAX(ROW)=MAX(U_MAX_INITIAL(ROW),0.0)                           SETFIL1B.290    
        ELSE                                                               SETFIL1B.291    
! This is the correct code; two adjacent rows are considered in NH         SETFIL1B.292    
          U_MAX(ROW)=                                                      SETFIL1B.293    
     &      MAX(U_MAX_INITIAL(ROW),U_MAX_INITIAL(ROW-1))                   SETFIL1B.294    
        ENDIF                                                              SETFIL1B.295    
! and scale U_MAX                                                          SETFIL1B.296    
        U_MAX(ROW)=U_MAX(ROW)*ADVECTION_TIMESTEP*                          SETFIL1B.297    
     &    LONGITUDE_STEP_INVERSE*SEC_P_LATITUDE(ROW*ROW_LENGTH)/A          SETFIL1B.298    
     &    *(TWO_D_GRID_CORRECTION(ROW)+FILTERING_SAFETY_FACTOR)            SETFIL1B.299    
! and square it                                                            SETFIL1B.300    
        U_MAX(ROW)=U_MAX(ROW)*U_MAX(ROW)                                   SETFIL1B.301    
      ENDDO                                                                SETFIL1B.302    
                                                                           SETFIL1B.303    
! Now loop round each row, setting the filter_wave_number, and             SETFIL1B.304    
! calculating NORTHERN/SOUTHERN_FILTERED_P_ROW.                            SETFIL1B.305    
*IF DEF,MPP                                                                SETFIL1B.306    
! These values are an initial guess, and will have to be MAX/MINed in      SETFIL1B.307    
! the North/South direction in order to get the correct global values.     SETFIL1B.308    
*ENDIF                                                                     SETFIL1B.309    
                                                                           SETFIL1B.310    
      NORTHERN_FILTERED_P_ROW=2                                            SETFIL1B.311    
*IF -DEF,MPP                                                               SETFIL1B.312    
      SOUTHERN_FILTERED_P_ROW=P_ROWS                                       SETFIL1B.313    
      CUT_OFF=ROW_LENGTH/2                                                 SETFIL1B.314    
                                                                           SETFIL1B.315    
      DO ROW=2,P_ROWS-1                                                    SETFIL1B.316    
*ELSE                                                                      SETFIL1B.317    
      SOUTHERN_FILTERED_P_ROW=glsize(2)                                    SETFIL1B.318    
      CUT_OFF=glsize(1)/2                                                  SETFIL1B.319    
                                                                           SETFIL1B.320    
      DO ROW=ROW_START,ROW_END  ! loop over local rows                     SETFIL1B.321    
        global_row=ROW+datastart(2)-Offy-1  ! global row number            SETFIL1B.322    
*ENDIF                                                                     SETFIL1B.323    
        C_TERM=SEC_P_LATITUDE(ROW*ROW_LENGTH)*                             SETFIL1B.324    
     &    SEC_P_LATITUDE(ROW*ROW_LENGTH)*C_CONST*                          SETFIL1B.325    
     &    TWO_D_GRID_CORRECTION(ROW)*                                      SETFIL1B.326    
     &    TWO_D_GRID_CORRECTION(ROW)                                       SETFIL1B.327    
                                                                           SETFIL1B.328    
        DO I=2,CUT_OFF                                                     SETFIL1B.329    
          SCALAR1= SIN(ALPHA*(I+1))  ! EPSI_V                              SETFIL1B.330    
          SCALAR2 = SIN(I*ALPHA*.5)  ! EPSI_J                              SETFIL1B.331    
! First term in eqn 50 - Advection Courant Number                          SETFIL1B.332    
          ADVECTION_COURANT = U_MAX(ROW)*SCALAR1*SCALAR1                   SETFIL1B.333    
! Second term in eqn 50 - Adjustment Courant Number                        SETFIL1B.334    
          ADJUSTMENT_COURANT = C_TERM*SCALAR2*SCALAR2                      SETFIL1B.335    
          COURANT = MAX(ADJUSTMENT_COURANT,ADVECTION_COURANT)              SETFIL1B.336    
          IF (COURANT .GT. 1.0) THEN  ! violated stability criteria        SETFIL1B.337    
                                                                           SETFIL1B.338    
! If Northern hemisphere:                                                  SETFIL1B.339    
*IF -DEF,MPP                                                               SETFIL1B.340    
            IF (ROW .LE. HALF_P_ROWS+1)                                    SETFIL1B.341    
     &        NORTHERN_FILTERED_P_ROW=ROW                                  SETFIL1B.342    
*ELSE                                                                      SETFIL1B.343    
            IF (global_row .LE. HALF_P_ROWS+1)                             SETFIL1B.344    
     &        NORTHERN_FILTERED_P_ROW=global_row                           SETFIL1B.345    
*ENDIF                                                                     SETFIL1B.346    
! If Southern hemisphere:                                                  SETFIL1B.347    
*IF -DEF,MPP                                                               SETFIL1B.348    
            IF ((ROW .GE. HALF_P_ROWS+2) .AND.                             SETFIL1B.349    
     &          (SOUTHERN_FILTERED_P_ROW .EQ. P_ROWS))                     SETFIL1B.350    
     &        SOUTHERN_FILTERED_P_ROW=ROW                                  SETFIL1B.351    
                                                                           SETFIL1B.352    
            FILTER_WAVE_NUMBER_P_ROWS(ROW) = I-1                           SETFIL1B.353    
*ELSE                                                                      SETFIL1B.354    
            IF ((global_row .GE. HALF_P_ROWS+2) .AND.                      SETFIL1B.355    
     &          (SOUTHERN_FILTERED_P_ROW .EQ. glsize(2)))                  SETFIL1B.356    
     &        SOUTHERN_FILTERED_P_ROW=global_row                           SETFIL1B.357    
                                                                           SETFIL1B.358    
            FILTER_WAVE_NUMBER_P_ROWS(global_row) = I-1                    SETFIL1B.359    
*ENDIF                                                                     SETFIL1B.360    
                                                                           SETFIL1B.361    
            GOTO 100                                                       SETFIL1B.362    
          ENDIF ! if stability criteria violated                           SETFIL1B.363    
        ENDDO ! loop over wave-numbers                                     SETFIL1B.364    
! If stability criteria not violated, set FILTER_WAVE_NUMBER               SETFIL1B.365    
! to CUT_OFF                                                               SETFIL1B.366    
*IF -DEF,MPP                                                               SETFIL1B.367    
        FILTER_WAVE_NUMBER_P_ROWS(ROW) = CUT_OFF                           SETFIL1B.368    
*ELSE                                                                      SETFIL1B.369    
        FILTER_WAVE_NUMBER_P_ROWS(global_row) = CUT_OFF                    SETFIL1B.370    
                                                                           SETFIL1B.371    
*ENDIF                                                                     SETFIL1B.372    
 100    CONTINUE                                                           SETFIL1B.373    
      ENDDO ! loop over local rows                                         SETFIL1B.374    
                                                                           SETFIL1B.375    
*IF DEF,MPP                                                                SETFIL1B.376    
! Work out the correct global values for FILTERED_P_ROWs                   SETFIL1B.377    
                                                                           SETFIL1B.378    
      CALL GC_IMAX(1,nproc,info,NORTHERN_FILTERED_P_ROW)                   SETFIL1B.379    
      CALL GC_IMIN(1,nproc,info,SOUTHERN_FILTERED_P_ROW)                   SETFIL1B.380    
                                                                           SETFIL1B.381    
! Keep a copy of SOUTHERN_FILTERED_P_ROW - we'll use this to decide        SETFIL1B.382    
! if the field we're filtering is a U_FIELD or P_FIELD                     SETFIL1B.383    
      south_filt_p_row=SOUTHERN_FILTERED_P_ROW                             SETFIL1B.384    
                                                                           SETFIL1B.385    
*ENDIF                                                                     SETFIL1B.386    
! We have to enforce the condition that the FILTER_WAVE_NUMBER_P_ROWS      SETFIL1B.387    
! cannot increase as we move towards the pole.                             SETFIL1B.388    
*IF DEF,MPP                                                                SETFIL1B.389    
! This is easiest if all the data is available on each processor           SETFIL1B.390    
                                                                           SETFIL1B.391    
! First, broadcast my local part of the filt_wave_number array             SETFIL1B.392    
                                                                           SETFIL1B.393    
      DO I=0,nproc-1,nproc_x                                               SETFIL1B.394    
        CALL GC_IBCAST(I,g_blsizep(2,I),I,nproc,info,                      SETFIL1B.395    
     &                 FILTER_WAVE_NUMBER_P_ROWS(g_datastart(2,I)))        SETFIL1B.396    
      ENDDO                                                                SETFIL1B.397    
*ENDIF                                                                     SETFIL1B.398    
                                                                           SETFIL1B.399    
! Northern hemisphere first:                                               SETFIL1B.400    
      DO ROW=HALF_P_ROWS,2,-1                                              SETFIL1B.401    
        FILTER_WAVE_NUMBER_P_ROWS(ROW) =                                   SETFIL1B.402    
     &    MIN(FILTER_WAVE_NUMBER_P_ROWS(ROW),                              SETFIL1B.403    
     &        FILTER_WAVE_NUMBER_P_ROWS(ROW+1))                            SETFIL1B.404    
      ENDDO                                                                SETFIL1B.405    
                                                                           SETFIL1B.406    
! And similarly for the Southern hemisphere                                SETFIL1B.407    
*IF -DEF,MPP                                                               SETFIL1B.408    
      DO ROW=HALF_P_ROWS+2,P_ROWS-1                                        SETFIL1B.409    
*ELSE                                                                      SETFIL1B.410    
      DO ROW=HALF_P_ROWS+2,glsize(2)-1                                     SETFIL1B.411    
*ENDIF                                                                     SETFIL1B.412    
        FILTER_WAVE_NUMBER_P_ROWS(ROW) =                                   SETFIL1B.413    
     &    MIN(FILTER_WAVE_NUMBER_P_ROWS(ROW),                              SETFIL1B.414    
     &        FILTER_WAVE_NUMBER_P_ROWS(ROW-1))                            SETFIL1B.415    
      ENDDO                                                                SETFIL1B.416    
                                                                           SETFIL1B.417    
! And set the values at the poles:                                         SETFIL1B.418    
*IF -DEF,MPP                                                               SETFIL1B.419    
      FILTER_WAVE_NUMBER_P_ROWS(1) = 0                                     SETFIL1B.420    
      FILTER_WAVE_NUMBER_P_ROWS(P_ROWS) = 0                                SETFIL1B.421    
*ELSE                                                                      SETFIL1B.422    
      FILTER_WAVE_NUMBER_P_ROWS(1) = 0                                     SETFIL1B.423    
      FILTER_WAVE_NUMBER_P_ROWS(glsize(2)) = 0                             SETFIL1B.424    
*ENDIF                                                                     SETFIL1B.425    
                                                                           SETFIL1B.426    
! Make the U_FIELD version                                                 SETFIL1B.427    
      DO I=1,HALF_P_ROWS                                                   SETFIL1B.428    
        FILTER_WAVE_NUMBER_U_ROWS(I) = FILTER_WAVE_NUMBER_P_ROWS(I)        SETFIL1B.429    
*IF -DEF,MPP                                                               SETFIL1B.430    
        FILTER_WAVE_NUMBER_U_ROWS(P_ROWS-I) =                              SETFIL1B.431    
     &    FILTER_WAVE_NUMBER_P_ROWS(P_ROWS+1-I)                            SETFIL1B.432    
*ELSE                                                                      SETFIL1B.433    
        FILTER_WAVE_NUMBER_U_ROWS(glsize(2)-I) =                           SETFIL1B.434    
     &    FILTER_WAVE_NUMBER_P_ROWS(glsize(2)+1-I)                         SETFIL1B.435    
*ENDIF                                                                     SETFIL1B.436    
      ENDDO                                                                SETFIL1B.437    
                                                                           ATJ0F403.52     
      IF ((NORTHERN_FILTERED_P_ROW .EQ. HALF_P_ROWS+1) .AND.               ATJ0F403.53     
     &    (SOUTHERN_FILTERED_P_ROW .EQ. HALF_P_ROWS+2)) THEN               ATJ0F403.54     
        WRITE(6,*) '*** SETFIL : WARNING *** ',                            ATJ0F403.55     
     &             'Filtering entire model domain.'                        ATJ0F403.56     
        WRITE(6,*) 'Timestep should be reduced.'                           GPB0F405.55     
*IF DEF,MPP                                                                GPB0F405.56     
        WRITE(6,*) 'Filtering has been switched off.'                      GPB0F405.57     
*IF DEF,T3E                                                                GPB0F405.58     
        WRITE(0,*) '*** SETFIL : WARNING *** Filtering turned off'         GPB0F405.59     
*ENDIF                                                                     GPB0F405.60     
        filter_off=.TRUE.                                                  GPB0F405.61     
        GOTO 9999                                                          GPB0F405.62     
*ENDIF                                                                     GPB0F405.63     
      ENDIF                                                                ATJ0F403.57     
                                                                           ATJ0F403.58     
*IF DEF,MPP                                                                SETFIL1B.438    
! --------------------------------------------------------------------     SETFIL1B.439    
                                                                           SETFIL1B.440    
      IF ((old_northern_filt .NE. NORTHERN_FILTERED_P_ROW) .OR.            SETFIL1B.441    
     &    (old_southern_filt .NE. SOUTHERN_FILTERED_P_ROW)) THEN           SETFIL1B.442    
        old_northern_filt = NORTHERN_FILTERED_P_ROW                        SETFIL1B.443    
        old_southern_filt = SOUTHERN_FILTERED_P_ROW                        SETFIL1B.444    
                                                                           SETFIL1B.445    
                                                                           ATJ0F403.59     
!     WRITE(6,*) 'SETFIL : Updating filtering area to ',                   ATJ0F403.60     
!    &           '2 - > ',NORTHERN_FILTERED_P_ROW,' and ',                 ATJ0F403.61     
!    &           SOUTHERN_FILTERED_P_ROW,' -> ',glsize(2)-1                ATJ0F403.62     
!     WRITE(6,*) 'SETFIL: Filtering ',                                     ATJ0F403.63     
!    &  REAL((glsize(2)-2)-                                                ATJ0F403.64     
!    &  (SOUTHERN_FILTERED_P_ROW-NORTHERN_FILTERED_P_ROW-1))/              ATJ0F403.65     
!    &  REAL(glsize(2)-2),' % of grid (not counting polar rows)'           ATJ0F403.66     
      fft_row_len=glsize(1)+2                                              GPB2F404.295    
      DO fld_type=1,2  ! 1=P_FIELD and 2=U_FIELD                           SETFIL1B.446    
                                                                           SETFIL1B.447    
        north_filt_row=NORTHERN_FILTERED_P_ROW                             SETFIL1B.448    
        IF (fld_type .EQ. 1) THEN                                          SETFIL1B.449    
          south_filt_row=SOUTHERN_FILTERED_P_ROW                           SETFIL1B.450    
          n_glob_rows=glsize(2)                                            SETFIL1B.451    
        ELSE                                                               SETFIL1B.452    
          south_filt_row=SOUTHERN_FILTERED_P_ROW-1                         SETFIL1B.453    
          n_glob_rows=glsize(2)-1                                          SETFIL1B.454    
        ENDIF                                                              SETFIL1B.455    
                                                                           SETFIL1B.456    
! Set up all the information required for decomposing the ffts             SETFIL1B.457    
! The information is passed to the filter routine via the                  SETFIL1B.458    
! PAR_FFT common block                                                     SETFIL1B.459    
                                                                           SETFIL1B.460    
        glob_filterable_rows=n_glob_rows-(south_filt_row-                  SETFIL1B.461    
     &                       north_filt_row-1)-2                           SETFIL1B.462    
! The "-2" arises because we don't want to filter the polar                SETFIL1B.463    
! rows.                                                                    SETFIL1B.464    
                                                                           SETFIL1B.465    
        approx_ffts_per_proc=(glob_filterable_rows*P_LEVELS)/nproc         GPB2F404.296    
        remainder_ffts=(glob_filterable_rows*P_LEVELS)-                    GPB2F404.297    
     &                  approx_ffts_per_proc*nproc                         SETFIL1B.468    
                                                                           SETFIL1B.469    
        filter_off=.FALSE.                                                 SETFIL1B.470    
        IF (REAL(glob_filterable_rows*P_LEVELS)/REAL(nproc) .GT.           GPB2F404.298    
     &    MAX_ROWS_TO_FILTER) THEN                                         SETFIL1B.472    
          WRITE(6,*) 'Error : Too many rows to filter'                     SETFIL1B.473    
          WRITE(6,*) 'Increase MAX_ROWS_TO_FILTER in comdeck ',            SETFIL1B.474    
     &                       'PARFFTS.'                                    SETFIL1B.475    
          filter_off=.TRUE.                                                SETFIL1B.476    
          GOTO 9999                                                        SETFIL1B.477    
        ENDIF                                                              SETFIL1B.478    
! approx_ffts_per_proc is the number of rows each processor would have     SETFIL1B.479    
! to fft, if the total number of fft rows divided exactly between          SETFIL1B.480    
! the total number of processors.                                          SETFIL1B.481    
! remainder_ffts is the number of fft rows left unassigned, if each        SETFIL1B.482    
! processor takes on approx_ffts_per_proc rows to do.                      SETFIL1B.483    
                                                                           SETFIL1B.484    
! The rows are distributed like this:                                      SETFIL1B.485    
! The first "remainder_ffts" processors are given                          SETFIL1B.486    
! approx_ffts_per_proc+1 rows each to fft                                  SETFIL1B.487    
! All the other processors are given approx_ffts_per_proc rows each.       SETFIL1B.488    
! The indexing of the filterable rows is like this:                        SETFIL1B.489    
! index  global_row_number  level                                          SETFIL1B.490    
! 1      2                  1                                              SETFIL1B.491    
! 2      2                  2                                              SETFIL1B.492    
! :      2                  :                                              SETFIL1B.493    
! :      2                  maxlevel                                       SETFIL1B.494    
! :      3                  1                                              SETFIL1B.495    
! etc.                                                                     SETFIL1B.496    
                                                                           SETFIL1B.497    
        n_send=0      ! number of rows I will send                         SETFIL1B.498    
        n_recv=0   ! number of processor rows I will receive from          SETFIL1B.499    
        fft_rows(fld_type)=0    ! total number of rows I will fft          SETFIL1B.500    
        proc_dest = -1                                                     SETFIL1B.503    
        change_pt=(approx_ffts_per_proc+1)*remainder_ffts                  SETFIL1B.504    
                                                                           SETFIL1B.505    
                                                                           SETFIL1B.506    
        DO ROW=2,n_glob_rows-1  ! loop over global rows, missing poles     SETFIL1B.507    
                                                                           SETFIL1B.508    
          IF ((ROW .LE. north_filt_row) .OR.                               SETFIL1B.509    
     &        (ROW .GE. south_filt_row)) THEN                              SETFIL1B.510    
! This row needs to be filtered                                            SETFIL1B.511    
                                                                           SETFIL1B.512    
            IF (ROW .LE. north_filt_row) THEN                              SETFIL1B.513    
            ! Northern hemisphere                                          SETFIL1B.514    
              filt_row_number=ROW-1                                        SETFIL1B.515    
            ELSE                                                           SETFIL1B.516    
            ! Southern hemisphere                                          SETFIL1B.517    
              filt_row_number=ROW-                                         SETFIL1B.518    
     &                       (south_filt_row-                              SETFIL1B.519    
     &                        north_filt_row-1)-1                          SETFIL1B.520    
            ENDIF                                                          SETFIL1B.521    
                                                                           SETFIL1B.522    
! Is this row of data on my processor?                                     SETFIL1B.523    
            sending=.FALSE.                                                SETFIL1B.524    
            IF ((ROW .GE. datastart(2)) .AND.                              SETFIL1B.525    
     &          (ROW .LE. datastart(2)+blsizep(2)-1)) sending=.TRUE.       SETFIL1B.526    
                                                                           SETFIL1B.527    
! Which processor row does it live on?                                     SETFIL1B.528    
            DO I=0,nproc_y-1  ! loop over processor row                    SETFIL1B.529    
              local_row=ROW-g_datastart(2,I*nproc_x)+1                     SETFIL1B.530    
              IF ((local_row .LE. g_blsizep(2,I*nproc_x)) .AND.            SETFIL1B.531    
     &            (local_row .GT. 0)) proc_row=I                           SETFIL1B.532    
            ENDDO                                                          SETFIL1B.533    
                                                                           SETFIL1B.534    
            DO K=1,P_LEVELS                                                GPB2F404.299    
              filt_row_index=(K+(filt_row_number-1)*P_LEVELS)              GPB2F404.300    
                                                                           SETFIL1B.537    
! Which processor is it going to?                                          SETFIL1B.538    
              oproc_dest = proc_dest                                       SETFIL1B.539    
              IF (filt_row_index .LE. change_pt) THEN                      SETFIL1B.540    
! It's a processor with approx_ffts_per_proc+1 rows to do                  SETFIL1B.541    
                proc_dest=(filt_row_index-1)/(approx_ffts_per_proc+1)      SETFIL1B.542    
              ELSE                                                         SETFIL1B.543    
! It's a processor with approx_ffts_per_proc rows to do                    SETFIL1B.544    
                proc_dest=remainder_ffts+                                  SETFIL1B.545    
     &            (filt_row_index-1-change_pt)/approx_ffts_per_proc        SETFIL1B.546    
              ENDIF                                                        SETFIL1B.547    
                                                                           SETFIL1B.548    
! Am I sending it?                                                         SETFIL1B.549    
              IF (sending) THEN                                            SETFIL1B.550    
                 if (proc_dest .eq. oproc_dest .and. k .ge. 2) then        SETFIL1B.551    
                    filt_send_max(n_send,fld_type) =                       SETFIL1B.552    
     &                   filt_send_max(n_send,fld_type) + 1                SETFIL1B.553    
                 else                                                      SETFIL1B.554    
                    n_send = n_send + 1                                    SETFIL1B.555    
                    filt_send_start(n_send,fld_type) = K                   SETFIL1B.556    
                    filt_send_max(n_send,fld_type) = 1                     SETFIL1B.557    
                    filt_send_map(S_DESTINATION_PE,n_send,fld_type) =      SETFIL1B.558    
     &                proc_dest                                            SETFIL1B.559    
                                                                           SETFIL1B.560    
                    filt_send_map(S_BASE_ADDRESS_IN_SEND_ARRAY,            SETFIL1B.561    
     &                            n_send,fld_type) =                       SETFIL1B.562    
     &                (K-1)*p_field +                                      SETFIL1B.563    
     &                (ROW-datastart(2)+offy)*lasize(1) + offx + 1         SETFIL1B.564    
                                                                           SETFIL1B.565    
                    filt_send_map(S_STRIDE_IN_SEND_ARRAY,                  SETFIL1B.566    
     &                            n_send,fld_type) =                       SETFIL1B.567    
     &                p_field                                              SETFIL1B.568    
                                                                           SETFIL1B.569    
                    filt_send_map(S_ELEMENT_LENGTH,n_send,fld_type) =      SETFIL1B.570    
     &                blsizep(1)                                           SETFIL1B.571    
! Calculate the number of this fft within the receiving processor          SETFIL1B.572    
! We do this by calculating the first fft the receiving processor does     SETFIL1B.573    
! and taking this number away from the filt_row_index                      SETFIL1B.574    
                    IF (proc_dest .LE. remainder_ffts-1) THEN              SETFIL1B.575    
                                                                           SETFIL1B.576    
                       filt_send_map(S_BASE_ADDRESS_IN_RECV_ARRAY,         SETFIL1B.577    
     &                               n_send,fld_type)=                     SETFIL1B.578    
     &                      (filt_row_index                                SETFIL1B.579    
     &                      +1-(proc_dest*(approx_ffts_per_proc+1)+1)-1)   SETFIL1B.580    
     &                      *fft_row_len + datastart(1)                    GPB2F404.301    
                    ELSE                                                   SETFIL1B.582    
                                                                           SETFIL1B.583    
                       filt_send_map(S_BASE_ADDRESS_IN_RECV_ARRAY,         SETFIL1B.584    
     &                               n_send,fld_type)=                     SETFIL1B.585    
     &                      (filt_row_index+                               SETFIL1B.586    
     &                      1-((remainder_ffts*(approx_ffts_per_proc+1))   SETFIL1B.587    
     &                      +(proc_dest-remainder_ffts)                    SETFIL1B.588    
     &                      *approx_ffts_per_proc+1)                       SETFIL1B.589    
     &                      -1)*fft_row_len + datastart(1)                 GPB2F404.302    
                    ENDIF                                                  SETFIL1B.591    
                                                                           SETFIL1B.592    
                    filt_send_map(S_STRIDE_IN_RECV_ARRAY,                  SETFIL1B.593    
     &                            n_send,fld_type) =                       SETFIL1B.594    
     &                fft_row_len                                          GPB2F404.303    
                                                                           SETFIL1B.596    
                 endif                                                     SETFIL1B.597    
              ENDIF ! IF sending                                           SETFIL1B.598    
                                                                           SETFIL1B.599    
! Am I receiving it?                                                       SETFIL1B.600    
              IF (proc_dest .EQ. mype) THEN  ! Is this my row to fft?      SETFIL1B.601    
                fft_rows(fld_type)=fft_rows(fld_type)+1                    SETFIL1B.602    
                filt_info(fft_rows(fld_type),fld_type) = row               SETFIL1B.603    
                                                                           SETFIL1B.604    
                if (proc_dest .eq. oproc_dest .and. k .ge. 2) then         SETFIL1B.605    
                   do j = 0,nproc_x-1                                      SETFIL1B.606    
                      filt_recv_max(n_recv-j,fld_type) =                   SETFIL1B.607    
     &                     filt_recv_max(n_recv-j,fld_type) + 1            SETFIL1B.608    
                   enddo                                                   SETFIL1B.609    
                else                                                       SETFIL1B.610    
                   DO J=0,nproc_x-1 ! loop over processor row              SETFIL1B.611    
                                                                           SETFIL1B.612    
                      sourcepe=proc_row*nproc_x+J                          SETFIL1B.613    
                      row_number=                                          SETFIL1B.614    
     &                     ROW-g_datastart(2,proc_row*nproc_x)+Offy+1      SETFIL1B.615    
! The following loop could be replaced with a strided receive              SETFIL1B.616    
                                                                           SETFIL1B.617    
                      n_recv = n_recv + 1                                  SETFIL1B.618    
                      filt_recv_start(n_recv,fld_type) = K                 SETFIL1B.619    
                      filt_recv_max(n_recv,fld_type) = 1                   SETFIL1B.620    
                      filt_recv_map(R_SOURCE_PE,n_recv,fld_type) =         SETFIL1B.621    
     &                  sourcepe                                           SETFIL1B.622    
                                                                           SETFIL1B.623    
                      filt_recv_map(R_BASE_ADDRESS_IN_RECV_ARRAY,          SETFIL1B.624    
     &                              n_recv,fld_type) =                     SETFIL1B.625    
     &                  (fft_rows(fld_type)-1)*fft_row_len +               GPB2F404.304    
     &                  g_datastart(1,sourcepe)                            SETFIL1B.627    
                                                                           SETFIL1B.628    
                      filt_recv_map(R_STRIDE_IN_RECV_ARRAY,                SETFIL1B.629    
     &                              n_recv,fld_type) =                     SETFIL1B.630    
     &                  fft_row_len                                        GPB2F404.305    
                                                                           SETFIL1B.632    
                      filt_recv_map(R_ELEMENT_LENGTH,                      SETFIL1B.633    
     &                              n_recv,fld_type) =                     SETFIL1B.634    
     &                  g_blsizep(1,sourcepe)                              SETFIL1B.635    
                                                                           SETFIL1B.636    
                      filt_recv_map(R_BASE_ADDRESS_IN_SEND_ARRAY,          SETFIL1B.637    
     &                              n_recv,fld_type) =                     SETFIL1B.638    
     &                  (K-1)*g_lasize(1,sourcepe)*g_lasize(2,sourcepe)    SETFIL1B.639    
     &                  + 1 + offx + (row_number-1)*                       SETFIL1B.640    
     &                  g_lasize(1,sourcepe)                               SETFIL1B.641    
                                                                           SETFIL1B.642    
                      filt_recv_map(R_STRIDE_IN_SEND_ARRAY,                SETFIL1B.643    
     &                              n_recv,fld_type) =                     SETFIL1B.644    
     &                  g_lasize(1,sourcepe)*g_lasize(2,sourcepe)          SETFIL1B.645    
                                                                           SETFIL1B.646    
                   ENDDO        ! J                                        SETFIL1B.647    
                endif                                                      SETFIL1B.648    
                                                                           SETFIL1B.649    
              ENDIF  ! IF my row to fft                                    SETFIL1B.650    
                                                                           SETFIL1B.651    
            ENDDO  ! loop over levels (K)                                  SETFIL1B.652    
          ENDIF  ! IF this row needs to be filtered                        SETFIL1B.653    
        ENDDO  ! loop over rows (ROW)                                      SETFIL1B.654    
                                                                           SETFIL1B.655    
      n_items_to_send(fld_type) = n_send                                   GJC0F405.53     
      n_items_to_recv(fld_type) = n_recv                                   GJC0F405.54     
                                                                           SETFIL1B.658    
      ENDDO  ! loop over field types (fld_type)                            SETFIL1B.659    
      ENDIF  ! IF we need to update fft decomposition                      SETFIL1B.660    
                                                                           SETFIL1B.661    
!                                                                          SETFIL1B.662    
!      WRITE(6,*) 'Processor ',mype                                        SETFIL1B.663    
!      WRITE(6,*) 'Sending ',n_items_to_send,' chunks.'                    SETFIL1B.664    
!      WRITE(6,*) 'Receiving ',n_items_to_recv,' chunks.'                  SETFIL1B.665    
!       WRITE(6,*) 'Doing ',fft_rows,' ffts.'                              SETFIL1B.666    
!                                                                          SETFIL1B.667    
!       write(6,*) 'filter wave nos:'                                      SETFIL1B.668    
!       do i=1,glsize(2)                                                   SETFIL1B.669    
!          write(6,*) i,filt_wave_number(i)                                SETFIL1B.670    
!       enddo                                                              SETFIL1B.671    
                                                                           SETFIL1B.672    
 9999   CONTINUE                                                           SETFIL1B.673    
                                                                           SETFIL1B.674    
*ENDIF                                                                     SETFIL1B.675    
                                                                           SETFIL1B.676    
! END OF ROUTINE SET_FIL                                                   SETFIL1B.677    
                                                                           SETFIL1B.678    
      RETURN                                                               SETFIL1B.679    
      END                                                                  SETFIL1B.680    
*ENDIF                                                                     SETFIL1B.681