Index: /branches/nemo_v3_3_beta/DOC/TexFiles/Chapters/Chap_SBC.tex
===================================================================
--- /branches/nemo_v3_3_beta/DOC/TexFiles/Chapters/Chap_SBC.tex	(revision 2350)
+++ /branches/nemo_v3_3_beta/DOC/TexFiles/Chapters/Chap_SBC.tex	(revision 2351)
@@ -641,12 +641,16 @@
 if this is left as an empty string no action is taken.
 In the model, weights files are read in and stored in a structured type (WGT) in the fldread module, as and when they are first required.
-This initialisation procedure tries to determine whether the input data grid should be treated as cyclical or not.
+This initialisation procedure determines whether the input data grid should be treated as cyclical or not by inspecting a global attribute stored in the weights input file.
+This attribute must be called "ew_wrap" and be of integer type.
+If it is negative, the input non-model grid is assumed not to be cyclic.
+If zero or greater, then the value represents the number of columns that overlap.
+E.g. if the input grid has columns at longitudes 0, 1, 2, .... , 359, then ew_wrap should be set to 0;
+if longitudes are 0.5, 2.5, .... , 358.5, 360.5, 362.5, ew_wrap should be 2.
+If the model does not find attribute ew_wrap, then a value of -999 is assumed.
+In this case the fld_read routine defaults ew_wrap to value 0 and therefore the grid is assumed to be cyclic
+with no overlapping columns.
 (In fact this only matters when bicubic interpolation is required.)
-To do this the model looks in the input data file (i.e. the data to which the weights are to be applied) for a variable with name "nav\_lon" or "lon".
-If found, it checks the difference between the first and last values of longitude along a single row.
-If the absolute value of this difference is close to 360 degrees or less than twice the maximum spacing from 360 degrees, the grid is assumed to be cyclical, and the difference determines whether the first column is a repeat of the last one or not.
-If neither "nav\_lon" or "lon" can be found, the model resorts to looking at the first and last columns of data.
-If the sum of the absolute values of the differences between the columns is very small, then the grid is assumed to be cyclical with coincident first and last columns.
-If both of these tests fail, the grid is assumed not to be cyclical.
+Note that no testing is done to check the validity in the model, since there is no way of knowing the name used for the longitude variable,
+so it is up to the user to make sure his or her data is correctly represented.
 
 Next the routine reads in the weights.
@@ -655,5 +659,5 @@
 The size of the input data array is determined by examining the values in the "src" arrays to find the minimum and maximum i and j values required.
 Since bicubic interpolation requires the calculation of gradients at each point on the grid, the corresponding arrays are dimensioned with a halo of width one grid point all the way around.
-When the array of points from the data file is adjacent to an edge of the data grid, the halo is either a copy of the row/column next to it (non-cyclical case), or is a copy of one from the first two rows/columns on the opposite side of the grid (cyclical case with coincident end rows/columns, or cyclical case with non-coincident end rows/columns).
+When the array of points from the data file is adjacent to an edge of the data grid, the halo is either a copy of the row/column next to it (non-cyclical case), or is a copy of one from the first few columns on the opposite side of the grid (cyclical case).
 
 \subsection{Limitations}
@@ -662,5 +666,5 @@
 \begin{description}
 \item
-Input data grids must be logically rectangular.
+The case where input data grids are not logically rectangular has not been tested.
 \item
 This code is not guaranteed to produce positive definite answers from positive definite inputs.
Index: /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/IOM/iom.F90
===================================================================
--- /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/IOM/iom.F90	(revision 2350)
+++ /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/IOM/iom.F90	(revision 2351)
@@ -44,4 +44,5 @@
 #endif
    PUBLIC iom_init, iom_swap, iom_open, iom_close, iom_setkt, iom_varid, iom_get, iom_gettime, iom_rstput, iom_put
+   PUBLIC iom_getatt
 
    PRIVATE iom_rp0d, iom_rp1d, iom_rp2d, iom_rp3d
@@ -54,4 +55,7 @@
    INTERFACE iom_get
       MODULE PROCEDURE iom_g0d, iom_g1d, iom_g2d, iom_g3d
+   END INTERFACE
+   INTERFACE iom_getatt
+      MODULE PROCEDURE iom_g0d_intatt
    END INTERFACE
    INTERFACE iom_rstput
@@ -824,4 +828,26 @@
       !
    END SUBROUTINE iom_gettime
+
+
+   !!----------------------------------------------------------------------
+   !!                   INTERFACE iom_getatt
+   !!----------------------------------------------------------------------
+   SUBROUTINE iom_g0d_intatt( kiomid, cdatt, pvar )
+      INTEGER         , INTENT(in   )                 ::   kiomid    ! Identifier of the file
+      CHARACTER(len=*), INTENT(in   )                 ::   cdatt     ! Name of the attribute
+      INTEGER         , INTENT(  out)                 ::   pvar      ! read field
+      !
+      IF( kiomid > 0 ) THEN
+         IF( iom_file(kiomid)%nfid > 0 ) THEN
+            SELECT CASE (iom_file(kiomid)%iolib)
+            CASE (jpioipsl )   ;   CALL ctl_stop('iom_getatt: only nf90 available')
+            CASE (jpnf90   )   ;   CALL iom_nf90_getatt( kiomid, cdatt, pvar )
+            CASE (jprstdimg)   ;   CALL ctl_stop('iom_getatt: only nf90 available')
+            CASE DEFAULT    
+               CALL ctl_stop( 'iom_g0d_att: accepted IO library are only jpioipsl, jpnf90 and jprstdimg' )
+            END SELECT
+         ENDIF
+      ENDIF
+   END SUBROUTINE iom_g0d_intatt
 
 
Index: /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/IOM/iom_nf90.F90
===================================================================
--- /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/IOM/iom_nf90.F90	(revision 2350)
+++ /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/IOM/iom_nf90.F90	(revision 2351)
@@ -28,7 +28,11 @@
 
    PUBLIC iom_nf90_open, iom_nf90_close, iom_nf90_varid, iom_nf90_get, iom_nf90_gettime, iom_nf90_rstput
+   PUBLIC iom_nf90_getatt
 
    INTERFACE iom_nf90_get
       MODULE PROCEDURE iom_nf90_g0d, iom_nf90_g123d
+   END INTERFACE
+   INTERFACE iom_nf90_getatt
+      MODULE PROCEDURE iom_nf90_intatt
    END INTERFACE
    INTERFACE iom_nf90_rstput
@@ -288,4 +292,32 @@
 
 
+   SUBROUTINE iom_nf90_intatt( kiomid, cdatt, pvar )
+      !!-----------------------------------------------------------------------
+      !!                  ***  ROUTINE  iom_nf90_intatt  ***
+      !!
+      !! ** Purpose : read an integer attribute with NF90
+      !!-----------------------------------------------------------------------
+      INTEGER         , INTENT(in   ) ::   kiomid   ! Identifier of the file
+      CHARACTER(len=*), INTENT(in   ) ::   cdatt    ! attribute name
+      INTEGER         , INTENT(  out) ::   pvar     ! read field
+      !
+      INTEGER                         ::   if90id   ! temporary integer
+      LOGICAL                         ::   llok     ! temporary logical
+      CHARACTER(LEN=100)              ::   clinfo   ! info character
+      !---------------------------------------------------------------------
+      ! 
+      if90id = iom_file(kiomid)%nfid
+      llok = NF90_Inquire_attribute(if90id, NF90_GLOBAL, cdatt) == nf90_noerr
+      IF( llok) THEN
+         clinfo = 'iom_nf90_getatt, file: '//TRIM(iom_file(kiomid)%name)//', att: '//TRIM(cdatt)
+         CALL iom_nf90_check(NF90_GET_ATT(if90id, NF90_GLOBAL, cdatt, values=pvar), clinfo)
+      ELSE
+         CALL ctl_warn('iom_nf90_getatt: no attribute '//cdatt//' found')
+         pvar = -999
+      ENDIF
+      ! 
+   END SUBROUTINE iom_nf90_intatt
+
+
    SUBROUTINE iom_nf90_gettime( kiomid, kvid, ptime, cdunits, cdcalendar )
       !!--------------------------------------------------------------------
Index: /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90
===================================================================
--- /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90	(revision 2350)
+++ /branches/nemo_v3_3_beta/NEMOGCM/NEMO/OPA_SRC/SBC/fldread.F90	(revision 2351)
@@ -72,13 +72,13 @@
       INTEGER                                 ::   numwgt       ! number of weights (4=bilinear, 16=bicubic)
       INTEGER                                 ::   nestid       ! for agrif, keep track of nest we're in
-      INTEGER                                 ::   offset       ! =0 when cyclic grid has coincident first/last columns, 
-                                                                ! =1 when they assumed to be one grid spacing apart      
-                                                                ! =-1 otherwise
+      INTEGER                                 ::   overlap      ! =0 when cyclic grid has no overlapping EW columns
+                                                                ! =>1 when they have one or more overlapping columns      
+                                                                ! =-1 not cyclic
       LOGICAL                                 ::   cyclic       ! east-west cyclic or not
       INTEGER, DIMENSION(:,:,:), POINTER      ::   data_jpi     ! array of source integers
       INTEGER, DIMENSION(:,:,:), POINTER      ::   data_jpj     ! array of source integers
       REAL(wp), DIMENSION(:,:,:), POINTER     ::   data_wgt     ! array of weights on model grid
-      REAL(wp), DIMENSION(:,:,:), POINTER       ::   fly_dta      ! array of values on input grid
-      REAL(wp), DIMENSION(:,:,:), POINTER       ::   col2         ! temporary array for reading in columns
+      REAL(wp), DIMENSION(:,:,:), POINTER     ::   fly_dta      ! array of values on input grid
+      REAL(wp), DIMENSION(:,:,:), POINTER     ::   col          ! temporary array for reading in columns
    END TYPE WGT
 
@@ -807,5 +807,5 @@
          IF( ref_wgts(kw)%cyclic ) THEN
             WRITE(numout,*) '       cyclical'
-            IF( ref_wgts(kw)%offset > 0 ) WRITE(numout,*) '                 with offset'
+            IF( ref_wgts(kw)%overlap > 0 ) WRITE(numout,*) '              with overlap of ', ref_wgts(kw)%overlap
          ELSE
             WRITE(numout,*) '       not cyclical'
@@ -835,9 +835,7 @@
       INTEGER , DIMENSION(jpi, jpj)           ::   data_src
       REAL(wp), DIMENSION(jpi, jpj)           ::   data_tmp
-      REAL(wp), DIMENSION(:,:), ALLOCATABLE   ::   line2, lines  ! temporary array to read 2 lineumns
-      CHARACTER (len=34)                      ::   lonvar
       LOGICAL                                 ::   cyclical
-      REAL(wp)                                ::   resid, dlon   ! temporary array to read 2 lineumns
-      INTEGER                                 ::   offset        ! temporary integer
+      INTEGER                                 ::   zwrap         ! temporary integer
+      INTEGER                                 ::   overlap        ! temporary integer
       !!----------------------------------------------------------------------
       !
@@ -857,66 +855,4 @@
       id = iom_varid( inum, sd%clvar, ddims )
 
-      !! check for an east-west cyclic grid
-      !! try to guess name of longitude variable
-
-      lonvar = 'nav_lon'
-      id = iom_varid(inum, TRIM(lonvar), ldstop=.FALSE.)
-      IF( id <= 0 ) THEN
-         lonvar = 'lon'
-         id = iom_varid(inum, TRIM(lonvar), ldstop=.FALSE.)
-      ENDIF
-
-      offset = -1
-      cyclical = .FALSE.
-      IF( id > 0 ) THEN
-         !! found a longitude variable
-         !! now going to assume that grid is regular so we can read a single row
-
-         !! because input array is 2d, have to present iom with 2d array even though we only need 1d slice
-         !! worse, we cant pass line2(:,1) to iom_get since this is treated as a 1d array which doesnt match input file
-         ALLOCATE( lines(ddims(1),2) )
-         CALL iom_get(inum, jpdom_unknown, lonvar, lines(:,:), 1, kstart=(/1,1/), kcount=(/ddims(1),2/) )
-
-         !! find largest grid spacing
-         lines(1:ddims(1)-1,2) = lines(2:ddims(1),1) - lines(1:ddims(1)-1,1)
-         dlon = MAXVAL( lines(1:ddims(1)-1,2) )
-
-         resid = ABS(ABS(lines(ddims(1),1)-lines(1,1))-360.0)
-         IF( resid < rsmall ) THEN
-            !! end rows overlap in longitude
-            offset = 0
-            cyclical = .TRUE.
-         ELSEIF( resid < 2.0*dlon ) THEN
-            !! also call it cyclic if difference between end points is less than twice dlon from 360
-            offset = 1
-            cyclical = .TRUE.
-         ENDIF
-
-         DEALLOCATE( lines )
-
-      ELSE
-         !! guessing failed
-         !! read in first and last columns of data variable
-         !! since we dont know the name of the longitude variable (or even if there is one)
-         !! we assume that if these two columns are equal, file is cyclic east-west
-
-         !! because input array is 2d, have to present iom with 2d array even though we only need 1d slice
-         !! worse, we cant pass line2(1,:) to iom_get since this is treated as a 1d array which doesnt match input file
-         ALLOCATE( lines(2,ddims(2)), line2(2,ddims(2)) )
-         CALL iom_get(inum, jpdom_unknown, sd%clvar, line2(:,:), 1, kstart=(/1,1/), kcount=(/2,ddims(2)/) )
-         lines(2,:) = line2(1,:)
-
-         CALL iom_get(inum, jpdom_unknown, sd%clvar, line2(:,:), 1, kstart=(/ddims(1)-1,1/), kcount=(/2,ddims(2)/) )
-         lines(1,:) = line2(2,:)
-
-         resid = SUM( ABS(lines(1,:) - lines(2,:)) )
-         IF( resid < ddims(2)*rsmall ) THEN
-            offset = 0
-            cyclical = .TRUE.
-         ENDIF
-
-         DEALLOCATE( lines, line2 )
-      ENDIF
-
       !! close it
       CALL iom_close( inum )
@@ -926,14 +862,25 @@
       CALL iom_open ( sd%wgtname, inum )   ! interpolation weights
       IF ( inum > 0 ) THEN
+
+         !! determine whether we have an east-west cyclic grid
+         !! from global attribute called "ew_wrap" in the weights file
+         !! note that if not found, iom_getatt returns -999 and cyclic with no overlap is assumed
+         !! since this is the most common forcing configuration
+
+         CALL iom_getatt(inum, 'ew_wrap', zwrap)
+         IF( zwrap >= 0 ) THEN
+            cyclical = .TRUE.
+         ELSE IF( zwrap == -999 ) THEN
+            cyclical = .TRUE.
+            zwrap = 0
+         ELSE
+            cyclical = .FALSE.
+         ENDIF
 
          ref_wgts(nxt_wgt)%ddims(1) = ddims(1)
          ref_wgts(nxt_wgt)%ddims(2) = ddims(2)
          ref_wgts(nxt_wgt)%wgtname = sd%wgtname
-         ref_wgts(nxt_wgt)%offset = -1
-         ref_wgts(nxt_wgt)%cyclic = .FALSE.
-         IF( cyclical ) THEN
-            ref_wgts(nxt_wgt)%offset = offset
-            ref_wgts(nxt_wgt)%cyclic = .TRUE.
-         ENDIF
+         ref_wgts(nxt_wgt)%overlap = zwrap
+         ref_wgts(nxt_wgt)%cyclic = cyclical
          ref_wgts(nxt_wgt)%nestid = 0
 #if defined key_agrif
@@ -995,5 +942,5 @@
          ipk =  SIZE(sd%fnow,3)
          ALLOCATE( ref_wgts(nxt_wgt)%fly_dta(ref_wgts(nxt_wgt)%jpiwgt+3, ref_wgts(nxt_wgt)%jpjwgt+3 ,ipk) )
-         IF( ref_wgts(nxt_wgt)%cyclic ) ALLOCATE( ref_wgts(nxt_wgt)%col2(2,ref_wgts(nxt_wgt)%jpjwgt+3,ipk) )
+         IF( ref_wgts(nxt_wgt)%cyclic ) ALLOCATE( ref_wgts(nxt_wgt)%col(1,ref_wgts(nxt_wgt)%jpjwgt+3,ipk) )
 
          nxt_wgt = nxt_wgt + 1
@@ -1035,5 +982,5 @@
       !! so we need to have a 4 by 4 subgrid surrounding each model point to cover both cases
 
-      !! sub grid where we already have weights
+      !! sub grid from non-model input grid which encloses all grid points in this nemo process
       jpimin = ref_wgts(kw)%botleft(1)
       jpjmin = ref_wgts(kw)%botleft(2)
@@ -1041,5 +988,5 @@
       jpjwid = ref_wgts(kw)%jpjwgt
 
-      !! what we need to read into sub grid in order to calculate gradients
+      !! when reading in, expand this sub-grid by one halo point all the way round for calculating gradients
       rec1(1) = MAX( jpimin-1, 1 )
       rec1(2) = MAX( jpjmin-1, 1 )
@@ -1049,5 +996,7 @@
       recn(3) = kk
 
-      !! where we need to read it to
+      !! where we need to put it in the non-nemo grid fly_dta
+      !! note that jpi1 and jpj1 only differ from 1 when jpimin and jpjmin are 1
+      !! (ie at the extreme west or south of the whole input grid) and similarly for jpi2 and jpj2
       jpi1 = 2 + rec1(1) - jpimin
       jpj1 = 2 + rec1(2) - jpjmin
@@ -1064,9 +1013,10 @@
 
       !! first four weights common to both bilinear and bicubic
+      !! data_jpi, data_jpj have already been shifted to (1,1) corresponding to botleft
       !! note that we have to offset by 1 into fly_dta array because of halo
       dta(:,:,:) = 0.0
       DO jk = 1,4
-        DO jn = 1, nlcj
-          DO jm = 1,nlci
+        DO jn = 1, jpj
+          DO jm = 1,jpi
             ni = ref_wgts(kw)%data_jpi(jm,jn,jk)
             nj = ref_wgts(kw)%data_jpj(jm,jn,jk)
@@ -1096,27 +1046,27 @@
         IF( ref_wgts(kw)%cyclic ) THEN
            rec1(2) = MAX( jpjmin-1, 1 )
-           recn(1) = 2
+           recn(1) = 1
            recn(2) = MIN( jpjwid+2, ref_wgts(kw)%ddims(2)-rec1(2)+1 )
            jpj1 = 2 + rec1(2) - jpjmin
            jpj2 = jpj1 + recn(2) - 1
            IF( jpi1 == 2 ) THEN
-              rec1(1) = ref_wgts(kw)%ddims(1) - 1
-              SELECT CASE( SIZE( ref_wgts(kw)%col2(:,jpj1:jpj2,:),3) )
+              rec1(1) = ref_wgts(kw)%ddims(1) - ref_wgts(kw)%overlap
+              SELECT CASE( SIZE( ref_wgts(kw)%col(:,jpj1:jpj2,:),3) )
               CASE(1)
-                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col2(:,jpj1:jpj2,1), nrec, rec1, recn)
+                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,1), nrec, rec1, recn)
               CASE(jpk)         
-                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col2(:,jpj1:jpj2,:), nrec, rec1, recn)
+                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn)
               END SELECT      
-              ref_wgts(kw)%fly_dta(jpi1-1,jpj1:jpj2,:) = ref_wgts(kw)%col2(ref_wgts(kw)%offset+1,jpj1:jpj2,:)
+              ref_wgts(kw)%fly_dta(jpi1-1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:)
            ENDIF
            IF( jpi2 + jpimin - 1 == ref_wgts(kw)%ddims(1)+1 ) THEN
-              rec1(1) = 1
-              SELECT CASE( SIZE( ref_wgts(kw)%col2(:,jpj1:jpj2,:),3) )
+              rec1(1) = 1 + ref_wgts(kw)%overlap
+              SELECT CASE( SIZE( ref_wgts(kw)%col(:,jpj1:jpj2,:),3) )
               CASE(1)
-                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col2(:,jpj1:jpj2,1), nrec, rec1, recn)
+                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,1), nrec, rec1, recn)
               CASE(jpk)
-                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col2(:,jpj1:jpj2,:), nrec, rec1, recn)
+                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn)
               END SELECT
-              ref_wgts(kw)%fly_dta(jpi2+1,jpj1:jpj2,:) = ref_wgts(kw)%col2(2-ref_wgts(kw)%offset,jpj1:jpj2,:)
+              ref_wgts(kw)%fly_dta(jpi2+1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:)
            ENDIF
         ENDIF
@@ -1124,6 +1074,6 @@
         ! gradient in the i direction
         DO jk = 1,4
-          DO jn = 1, nlcj
-            DO jm = 1,nlci
+          DO jn = 1, jpj
+            DO jm = 1,jpi
               ni = ref_wgts(kw)%data_jpi(jm,jn,jk)
               nj = ref_wgts(kw)%data_jpj(jm,jn,jk)
@@ -1136,6 +1086,6 @@
         ! gradient in the j direction
         DO jk = 1,4
-          DO jn = 1, nlcj
-            DO jm = 1,nlci
+          DO jn = 1, jpj
+            DO jm = 1,jpi
               ni = ref_wgts(kw)%data_jpi(jm,jn,jk)
               nj = ref_wgts(kw)%data_jpj(jm,jn,jk)
