Index: NEMO/trunk/src/OCE/SBC/fldread.F90
===================================================================
--- NEMO/trunk/src/OCE/SBC/fldread.F90	(revision 12367)
+++ NEMO/trunk/src/OCE/SBC/fldread.F90	(revision 12377)
@@ -13,9 +13,9 @@
    !!   fld_read      : read input fields used for the computation of the surface boundary condition
    !!   fld_init      : initialization of field read
-   !!   fld_rec       : determined the record(s) to be read
+   !!   fld_def       : define the record(s) of the file and its name
    !!   fld_get       : read the data
    !!   fld_map       : read global data from file and map onto local data using a general mapping (use for open boundaries)
    !!   fld_rot       : rotate the vector fields onto the local grid direction
-   !!   fld_clopn     : update the data file name and close/open the files
+   !!   fld_clopn     : close/open the files
    !!   fld_fill      : fill the data structure with the associated information read in namelist
    !!   wgt_list      : manage the weights used for interpolation
@@ -25,5 +25,6 @@
    !!   seaoverland   : create shifted matrices for seaoverland application
    !!   fld_interp    : apply weights to input gridded data to create data on model grid
-   !!   ksec_week     : function returning the first 3 letters of the first day of the weekly file
+   !!   fld_filename  : define the filename according to a given date
+   !!   ksec_week     : function returning seconds between 00h of the beginning of the week and half of the current time step
    !!----------------------------------------------------------------------
    USE oce            ! ocean dynamics and tracers
@@ -44,5 +45,5 @@
    PUBLIC   fld_map    ! routine called by tides_init
    PUBLIC   fld_read, fld_fill   ! called by sbc... modules
-   PUBLIC   fld_clopn
+   PUBLIC   fld_def
 
    TYPE, PUBLIC ::   FLD_N      !: Namelist field informations
@@ -72,6 +73,7 @@
       INTEGER , DIMENSION(2)          ::   nrec_b       ! before record (1: index, 2: second since Jan. 1st 00h of nit000 year)
       INTEGER , DIMENSION(2)          ::   nrec_a       ! after  record (1: index, 2: second since Jan. 1st 00h of nit000 year)
-      REAL(wp) , ALLOCATABLE, DIMENSION(:,:,:  ) ::   fnow   ! input fields interpolated to now time step
-      REAL(wp) , ALLOCATABLE, DIMENSION(:,:,:,:) ::   fdta   ! 2 consecutive record of input fields
+      INTEGER , ALLOCATABLE, DIMENSION(:      ) ::   nrecsec   ! 
+      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:  ) ::   fnow   ! input fields interpolated to now time step
+      REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) ::   fdta   ! 2 consecutive record of input fields
       CHARACTER(len = 256)            ::   wgtname      ! current name of the NetCDF weight file acting as a key
       !                                                 ! into the WGTLIST structure
@@ -118,8 +120,11 @@
    TYPE( WGT ), DIMENSION(tot_wgts)   ::   ref_wgts     ! array of wgts
    INTEGER                            ::   nxt_wgt = 1  ! point to next available space in ref_wgts array
+   INTEGER                            ::   nflag = 0
    REAL(wp), PARAMETER                ::   undeff_lsm = -999.00_wp
 
 !$AGRIF_END_DO_NOT_TREAT
 
+   !! * Substitutions
+#  include "do_loop_substitute.h90"
    !!----------------------------------------------------------------------
    !! NEMO/OCE 4.0 , NEMO Consortium (2018)
@@ -129,5 +134,5 @@
 CONTAINS
 
-   SUBROUTINE fld_read( kt, kn_fsbc, sd, kit, kt_offset )
+   SUBROUTINE fld_read( kt, kn_fsbc, sd, kit, pt_offset, Kmm )
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE fld_read  ***
@@ -145,19 +150,12 @@
       TYPE(FLD), INTENT(inout), DIMENSION(:) ::   sd        ! input field related variables
       INTEGER  , INTENT(in   ), OPTIONAL     ::   kit       ! subcycle timestep for timesplitting option
-      INTEGER  , INTENT(in   ), OPTIONAL     ::   kt_offset ! provide fields at time other than "now"
-      !                                                     !   kt_offset = -1 => fields at "before" time level
-      !                                                     !   kt_offset = +1 => fields at "after"  time level
-      !                                                     !   etc.
-      !!
-      INTEGER  ::   itmp         ! local variable
+      REAL(wp) , INTENT(in   ), OPTIONAL     ::   pt_offset ! provide fields at time other than "now"
+      INTEGER  , INTENT(in   ), OPTIONAL     ::   Kmm       ! ocean time level index
+      !!
       INTEGER  ::   imf          ! size of the structure sd
       INTEGER  ::   jf           ! dummy indices
-      INTEGER  ::   isecend      ! number of second since Jan. 1st 00h of nit000 year at nitend
       INTEGER  ::   isecsbc      ! number of seconds between Jan. 1st 00h of nit000 year and the middle of sbc time step
-      INTEGER  ::   it_offset    ! local time offset variable
-      LOGICAL  ::   llnxtyr      ! open next year  file?
-      LOGICAL  ::   llnxtmth     ! open next month file?
-      LOGICAL  ::   llstop       ! stop is the file does not exist
       LOGICAL  ::   ll_firstcall ! true if this is the first call to fld_read for this set of fields
+      REAL(wp) ::   zt_offset    ! local time offset variable
       REAL(wp) ::   ztinta       ! ratio applied to after  records when doing time interpolation
       REAL(wp) ::   ztintb       ! ratio applied to before records when doing time interpolation
@@ -167,14 +165,15 @@
       IF( PRESENT(kit) )   ll_firstcall = ll_firstcall .and. kit == 1
 
-      IF ( nn_components == jp_iam_sas ) THEN   ;   it_offset = nn_fsbc
-      ELSE                                      ;   it_offset = 0
-      ENDIF
-      IF( PRESENT(kt_offset) )   it_offset = kt_offset
-
-      ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 
-      IF( present(kit) ) THEN   ! ignore kn_fsbc in this case
-         isecsbc = nsec_year + nsec1jan000 + (kit+it_offset)*NINT( rdt/REAL(nn_baro,wp) )
+      IF( nn_components == jp_iam_sas ) THEN   ;   zt_offset = REAL( nn_fsbc, wp )
+      ELSE                                     ;   zt_offset = 0.
+      ENDIF
+      IF( PRESENT(pt_offset) )   zt_offset = pt_offset
+
+      ! Note that all varibles starting by nsec_* are shifted time by +1/2 time step to be centrered
+      IF( PRESENT(kit) ) THEN   ! ignore kn_fsbc in this case
+         isecsbc = nsec_year + nsec1jan000 + NINT( (     REAL(      kit,wp) + zt_offset ) * rdt / REAL(nn_baro,wp) )
       ELSE                      ! middle of sbc time step
-         isecsbc = nsec_year + nsec1jan000 + NINT(0.5 * REAL(kn_fsbc - 1,wp) * rdt) + it_offset * NINT(rdt)
+         ! note: we use kn_fsbc-1 because nsec_year is defined at the middle of the current time step
+         isecsbc = nsec_year + nsec1jan000 + NINT( ( 0.5*REAL(kn_fsbc-1,wp) + zt_offset ) * rdt )
       ENDIF
       imf = SIZE( sd )
@@ -183,5 +182,5 @@
          DO jf = 1, imf 
             IF( TRIM(sd(jf)%clrootname) == 'NOT USED' )   CYCLE
-            CALL fld_init( kn_fsbc, sd(jf) )       ! read each before field (put them in after as they will be swapped)
+            CALL fld_init( isecsbc, sd(jf) )       ! read each before field (put them in after as they will be swapped)
          END DO
          IF( lwp ) CALL wgt_print()                ! control print
@@ -192,90 +191,8 @@
          !
          DO jf = 1, imf                            ! ---   loop over field   --- !
-
+            !
             IF( TRIM(sd(jf)%clrootname) == 'NOT USED' )   CYCLE
-                      
-            IF( isecsbc > sd(jf)%nrec_a(2) .OR. ll_firstcall ) THEN    ! read/update the after data?
-
-               sd(jf)%nrec_b(:) = sd(jf)%nrec_a(:)                                  ! swap before record informations
-               sd(jf)%rotn(1) = sd(jf)%rotn(2)                                      ! swap before rotate informations
-               IF( sd(jf)%ln_tint )   sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2)   ! swap before record field
-
-               CALL fld_rec( kn_fsbc, sd(jf), kt_offset = it_offset, kit = kit )    ! update after record informations
-
-               ! if kn_fsbc*rdt is larger than freqh (which is kind of odd),
-               ! it is possible that the before value is no more the good one... we have to re-read it
-               ! if before is not the last record of the file currently opened and after is the first record to be read
-               ! in a new file which means after = 1 (the file to be opened corresponds to the current time)
-               ! or after = nreclast + 1 (the file to be opened corresponds to a future time step)
-               IF( .NOT. ll_firstcall .AND. sd(jf)%ln_tint .AND. sd(jf)%nrec_b(1) /= sd(jf)%nreclast &
-                  &                   .AND. MOD( sd(jf)%nrec_a(1), sd(jf)%nreclast ) == 1 ) THEN
-                  itmp = sd(jf)%nrec_a(1)                       ! temporary storage
-                  sd(jf)%nrec_a(1) = sd(jf)%nreclast            ! read the last record of the file currently opened
-                  CALL fld_get( sd(jf) )                        ! read after data
-                  sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2)   ! re-swap before record field
-                  sd(jf)%nrec_b(1) = sd(jf)%nrec_a(1)           ! update before record informations
-                  sd(jf)%nrec_b(2) = sd(jf)%nrec_a(2) - NINT( sd(jf)%freqh * 3600. )  ! assume freq to be in hours in this case
-                  sd(jf)%rotn(1)   = sd(jf)%rotn(2)             ! update before rotate informations
-                  sd(jf)%nrec_a(1) = itmp                       ! move back to after record 
-               ENDIF
-
-               CALL fld_clopn( sd(jf) )   ! Do we need to open a new year/month/week/day file?
-               
-               IF( sd(jf)%ln_tint ) THEN
-                  
-                  ! if kn_fsbc*rdt is larger than freqh (which is kind of odd),
-                  ! it is possible that the before value is no more the good one... we have to re-read it
-                  ! if before record is not just just before the after record...
-                  IF( .NOT. ll_firstcall .AND. MOD( sd(jf)%nrec_a(1), sd(jf)%nreclast ) /= 1 &
-                     &                   .AND. sd(jf)%nrec_b(1) /= sd(jf)%nrec_a(1) - 1 ) THEN   
-                     sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) - 1       ! move back to before record
-                     CALL fld_get( sd(jf) )                        ! read after data
-                     sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2)   ! re-swap before record field
-                     sd(jf)%nrec_b(1) = sd(jf)%nrec_a(1)           ! update before record informations
-                     sd(jf)%nrec_b(2) = sd(jf)%nrec_a(2) - NINT( sd(jf)%freqh * 3600. )  ! assume freq to be in hours in this case
-                     sd(jf)%rotn(1)   = sd(jf)%rotn(2)             ! update before rotate informations
-                     sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) + 1       ! move back to after record
-                  ENDIF
-               ENDIF ! temporal interpolation?
-
-               ! do we have to change the year/month/week/day of the forcing field?? 
-               ! if we do time interpolation we will need to open next year/month/week/day file before the end of the current
-               ! one. If so, we are still before the end of the year/month/week/day when calling fld_rec so sd(jf)%nrec_a(1)
-               ! will be larger than the record number that should be read for current year/month/week/day
-               ! do we need next file data?
-               ! This applies to both cases with or without time interpolation
-               IF( sd(jf)%nrec_a(1) > sd(jf)%nreclast ) THEN
-                  
-                  sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) - sd(jf)%nreclast   ! 
-                  
-                  IF( .NOT. ( sd(jf)%ln_clim .AND. sd(jf)%cltype == 'yearly' ) ) THEN   ! close/open the current/new file
-                     
-                     llnxtmth = sd(jf)%cltype == 'monthly' .OR. nday == nmonth_len(nmonth)      ! open next month file?
-                     llnxtyr  = sd(jf)%cltype == 'yearly'  .OR. (nmonth == 12 .AND. llnxtmth)   ! open next year  file?
-
-                     ! if the run finishes at the end of the current year/month/week/day, we will allow next
-                     ! year/month/week/day file to be not present. If the run continue further than the current
-                     ! year/month/week/day, next year/month/week/day file must exist
-                     isecend = nsec_year + nsec1jan000 + (nitend - kt) * NINT(rdt)   ! second at the end of the run
-                     llstop = isecend > sd(jf)%nrec_a(2)                             ! read more than 1 record of next year
-                     ! we suppose that the date of next file is next day (should be ok even for weekly files...)
-                     CALL fld_clopn( sd(jf), nyear  + COUNT((/llnxtyr /))                                           ,         &
-                        &                    nmonth + COUNT((/llnxtmth/)) - 12                 * COUNT((/llnxtyr /)),         &
-                        &                    nday   + 1                   - nmonth_len(nmonth) * COUNT((/llnxtmth/)), llstop )
-
-                     IF( sd(jf)%num <= 0 .AND. .NOT. llstop ) THEN    ! next year file does not exist
-                        CALL ctl_warn('next year/month/week/day file: '//TRIM(sd(jf)%clname)//     &
-                           &     ' not present -> back to current year/month/day')
-                        CALL fld_clopn( sd(jf) )               ! back to the current year/month/day
-                        sd(jf)%nrec_a(1) = sd(jf)%nreclast     ! force to read the last record in the current year file
-                     ENDIF
-                     
-                  ENDIF
-               ENDIF   ! open need next file?
-                  
-               ! read after data
-               CALL fld_get( sd(jf) )
-               
-            ENDIF   ! read new data?
+            CALL fld_update( isecsbc, sd(jf), Kmm )
+            !
          END DO                                    ! --- end loop over field --- !
 
@@ -292,5 +209,5 @@
                   WRITE(numout, clfmt)  TRIM( sd(jf)%clvar ), kt, REAL(isecsbc,wp)/rday, nyear, nmonth, nday,   &            
                      & sd(jf)%nrec_b(1), sd(jf)%nrec_a(1), REAL(sd(jf)%nrec_b(2),wp)/rday, REAL(sd(jf)%nrec_a(2),wp)/rday
-                  WRITE(numout, *) '      it_offset is : ',it_offset
+                  WRITE(numout, *) '      zt_offset is : ',zt_offset
                ENDIF
                ! temporal interpolation weights
@@ -316,121 +233,29 @@
 
 
-   SUBROUTINE fld_init( kn_fsbc, sdjf )
+   SUBROUTINE fld_init( ksecsbc, sdjf )
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE fld_init  ***
       !!
-      !! ** Purpose :  - first call to fld_rec to define before values
-      !!               - if time interpolation, read before data 
-      !!----------------------------------------------------------------------
-      INTEGER  , INTENT(in   ) ::   kn_fsbc      ! sbc computation period (in time step) 
+      !! ** Purpose :  - first call(s) to fld_def to define before values
+      !!               - open file
+      !!----------------------------------------------------------------------
+      INTEGER  , INTENT(in   ) ::   ksecsbc   ! 
       TYPE(FLD), INTENT(inout) ::   sdjf         ! input field related variables
-      !!
-      LOGICAL :: llprevyr              ! are we reading previous year  file?
-      LOGICAL :: llprevmth             ! are we reading previous month file?
-      LOGICAL :: llprevweek            ! are we reading previous week  file?
-      LOGICAL :: llprevday             ! are we reading previous day   file?
-      LOGICAL :: llprev                ! llprevyr .OR. llprevmth .OR. llprevweek .OR. llprevday
-      INTEGER :: idvar                 ! variable id 
-      INTEGER :: inrec                 ! number of record existing for this variable
-      INTEGER :: iyear, imonth, iday   ! first day of the current file in yyyy mm dd
-      INTEGER :: isec_week             ! number of seconds since start of the weekly file
-      CHARACTER(LEN=1000) ::   clfmt   ! write format
-      !!---------------------------------------------------------------------
-      !
-      llprevyr   = .FALSE.
-      llprevmth  = .FALSE.
-      llprevweek = .FALSE.
-      llprevday  = .FALSE.
-      isec_week  = 0
-      !
-      ! define record informations
-      CALL fld_rec( kn_fsbc, sdjf, ldbefore = .TRUE. )  ! return before values in sdjf%nrec_a (as we will swap it later)
-      !
-      ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 
-      !
-      IF( sdjf%ln_tint ) THEN ! we need to read the previous record and we will put it in the current record structure
-         !
-         IF( sdjf%nrec_a(1) == 0  ) THEN   ! we redefine record sdjf%nrec_a(1) with the last record of previous year file
-            IF    ( NINT(sdjf%freqh) == -12 ) THEN   ! yearly mean
-               IF( sdjf%cltype == 'yearly' ) THEN             ! yearly file
-                  sdjf%nrec_a(1) = 1                                                       ! force to read the unique record
-                  llprevyr  = .NOT. sdjf%ln_clim                                           ! use previous year  file?
-               ELSE
-                  CALL ctl_stop( "fld_init: yearly mean file must be in a yearly type of file: "//TRIM(sdjf%clrootname) )
-               ENDIF
-            ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN   ! monthly mean
-               IF( sdjf%cltype == 'monthly' ) THEN            ! monthly file
-                  sdjf%nrec_a(1) = 1                                                       ! force to read the unique record
-                  llprevmth = .TRUE.                                                       ! use previous month file?
-                  llprevyr  = llprevmth .AND. nmonth == 1                                  ! use previous year  file?
-               ELSE                                           ! yearly file
-                  sdjf%nrec_a(1) = 12                                                      ! force to read december mean
-                  llprevyr = .NOT. sdjf%ln_clim                                            ! use previous year  file?
-               ENDIF
-            ELSE                                     ! higher frequency mean (in hours) 
-               IF    ( sdjf%cltype      == 'monthly' ) THEN   ! monthly file
-                  sdjf%nrec_a(1) = NINT( 24. * REAL(nmonth_len(nmonth-1),wp) / sdjf%freqh )! last record of previous month
-                  llprevmth = .TRUE.                                                       ! use previous month file?
-                  llprevyr  = llprevmth .AND. nmonth == 1                                  ! use previous year  file?
-               ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ! weekly file
-                  llprevweek = .TRUE.                                                      ! use previous week  file?
-                  sdjf%nrec_a(1) = NINT( 24. * 7. / sdjf%freqh )                           ! last record of previous week
-                  isec_week = NINT(rday) * 7                                               ! add a shift toward previous week
-               ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ! daily file
-                  sdjf%nrec_a(1) = NINT( 24. / sdjf%freqh )                                ! last record of previous day
-                  llprevday = .TRUE.                                                       ! use previous day   file?
-                  llprevmth = llprevday .AND. nday   == 1                                  ! use previous month file?
-                  llprevyr  = llprevmth .AND. nmonth == 1                                  ! use previous year  file?
-               ELSE                                           ! yearly file
-                  sdjf%nrec_a(1) = NINT( 24. * REAL(nyear_len(0),wp) / sdjf%freqh )        ! last record of previous year 
-                  llprevyr = .NOT. sdjf%ln_clim                                            ! use previous year  file?
-               ENDIF
-            ENDIF
-         ENDIF
-         !
-         IF ( sdjf%cltype(1:4) == 'week' ) THEN
-            isec_week = isec_week + ksec_week( sdjf%cltype(6:8) )   ! second since the beginning of the week
-            llprevmth = isec_week > nsec_month                      ! longer time since the beginning of the week than the month
-            llprevyr  = llprevmth .AND. nmonth == 1
-         ENDIF
-         llprev = llprevyr .OR. llprevmth .OR. llprevweek .OR. llprevday
-         !
-         iyear  = nyear  - COUNT((/llprevyr /))
-         imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /))
-         iday   = nday   - COUNT((/llprevday/)) + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday)
-         !
-         CALL fld_clopn( sdjf, iyear, imonth, iday, .NOT. llprev )
-         !
-         ! if previous year/month/day file does not exist, we switch to the current year/month/day
-         IF( llprev .AND. sdjf%num <= 0 ) THEN
-            CALL ctl_warn( 'previous year/month/week/day file: '//TRIM(sdjf%clrootname)//   &
-               &           ' not present -> back to current year/month/week/day' )
-            ! we force to read the first record of the current year/month/day instead of last record of previous year/month/day
-            llprev = .FALSE.
-            sdjf%nrec_a(1) = 1
-            CALL fld_clopn( sdjf )
-         ENDIF
-         !
-         IF( llprev ) THEN   ! check if the record sdjf%nrec_a(1) exists in the file
-            idvar = iom_varid( sdjf%num, sdjf%clvar )                                        ! id of the variable sdjf%clvar
-            IF( idvar <= 0 )   RETURN
-            inrec = iom_file( sdjf%num )%dimsz( iom_file( sdjf%num )%ndims(idvar), idvar )   ! size of the last dim of idvar
-            sdjf%nrec_a(1) = MIN( sdjf%nrec_a(1), inrec )   ! make sure we select an existing record
-         ENDIF
-         !
-         ! read before data in after arrays(as we will swap it later)
-         CALL fld_get( sdjf )
-         !
-         clfmt = "('   fld_init : time-interpolation for ', a, ' read previous record = ', i6, ' at time = ', f7.2, ' days')"
-         IF(lwp) WRITE(numout, clfmt) TRIM(sdjf%clvar), sdjf%nrec_a(1), REAL(sdjf%nrec_a(2),wp)/rday
-         !
-      ENDIF
+      !!---------------------------------------------------------------------
+      !
+      IF( nflag == 0 )   nflag = -( HUGE(0) - 10 )
+      !
+      CALL fld_def( sdjf )
+      IF( sdjf%ln_tint .AND. ksecsbc < sdjf%nrecsec(1) )   CALL fld_def( sdjf, ldprev = .TRUE. )
+      !
+      CALL fld_clopn( sdjf )
+      sdjf%nrec_a(:) = (/ 1, nflag /)  ! default definition to force flp_update to read the file.
       !
    END SUBROUTINE fld_init
 
 
-   SUBROUTINE fld_rec( kn_fsbc, sdjf, ldbefore, kit, kt_offset )
-      !!---------------------------------------------------------------------
-      !!                    ***  ROUTINE fld_rec  ***
+   SUBROUTINE fld_update( ksecsbc, sdjf, Kmm )
+      !!---------------------------------------------------------------------
+      !!                    ***  ROUTINE fld_update  ***
       !!
       !! ** Purpose : Compute
@@ -441,162 +266,74 @@
       !!                  nrec_b(2) and nrec_a(2): time of the beginning and end of the record
       !!----------------------------------------------------------------------
-      INTEGER  , INTENT(in   )           ::   kn_fsbc   ! sbc computation period (in time step) 
-      TYPE(FLD), INTENT(inout)           ::   sdjf      ! input field related variables
-      LOGICAL  , INTENT(in   ), OPTIONAL ::   ldbefore  ! sent back before record values (default = .FALSE.)
-      INTEGER  , INTENT(in   ), OPTIONAL ::   kit       ! index of barotropic subcycle
-      !                                                 ! used only if sdjf%ln_tint = .TRUE.
-      INTEGER  , INTENT(in   ), OPTIONAL ::   kt_offset ! Offset of required time level compared to "now"
-      !                                                 !   time level in units of time steps.
-      !
-      LOGICAL  ::   llbefore    ! local definition of ldbefore
-      INTEGER  ::   iendrec     ! end of this record (in seconds)
-      INTEGER  ::   imth        ! month number
-      INTEGER  ::   ifreq_sec   ! frequency mean (in seconds)
-      INTEGER  ::   isec_week   ! number of seconds since the start of the weekly file
-      INTEGER  ::   it_offset   ! local time offset variable
-      REAL(wp) ::   ztmp        ! temporary variable
-      !!----------------------------------------------------------------------
-      !
-      ! Note that shifting time to be centrered in the middle of sbc time step impacts only nsec_* variables of the calendar 
-      !
-      IF( PRESENT(ldbefore) ) THEN   ;   llbefore = ldbefore .AND. sdjf%ln_tint   ! needed only if sdjf%ln_tint = .TRUE.
-      ELSE                           ;   llbefore = .FALSE.
-      ENDIF
-      !
-      IF ( nn_components == jp_iam_sas ) THEN   ;   it_offset = nn_fsbc
-      ELSE                                      ;   it_offset = 0
-      ENDIF
-      IF( PRESENT(kt_offset) )      it_offset = kt_offset
-      IF( PRESENT(kit) ) THEN   ;   it_offset = ( kit + it_offset ) * NINT( rdt/REAL(nn_baro,wp) )
-      ELSE                      ;   it_offset =         it_offset   * NINT(       rdt            )
-      ENDIF
-      !
-      !                                           ! =========== !
-      IF    ( NINT(sdjf%freqh) == -12 ) THEN      ! yearly mean
-         !                                        ! =========== !
-         !
-         IF( sdjf%ln_tint ) THEN                  ! time interpolation, shift by 1/2 record
-            !
-            !                  INT( ztmp )
-            !                     /|\
-            !                    1 |    *----
-            !                    0 |----(              
-            !                      |----+----|--> time
-            !                      0   /|\   1   (nday/nyear_len(1))
-            !                           |   
-            !                           |   
-            !       forcing record :    1 
-            !                            
-            ztmp =  REAL( nsec_year, wp ) / ( REAL( nyear_len(1), wp ) * rday ) + 0.5 &
-               &  + REAL( it_offset, wp ) / ( REAL( nyear_len(1), wp ) * rday )
-            sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/))
-            ! swap at the middle of the year
-            IF( llbefore ) THEN   ;   sdjf%nrec_a(2) = nsec1jan000 - (1 - INT(ztmp)) * NINT(0.5 * rday) * nyear_len(0) + &
-                                    & INT(ztmp) * NINT( 0.5 * rday) * nyear_len(1) 
-            ELSE                  ;   sdjf%nrec_a(2) = nsec1jan000 + (1 - INT(ztmp)) * NINT(0.5 * rday) * nyear_len(1) + &
-                                    & INT(ztmp) * INT(rday) * nyear_len(1) + INT(ztmp) * NINT( 0.5 * rday) * nyear_len(2) 
+      INTEGER  ,           INTENT(in   ) ::   ksecsbc   ! 
+      TYPE(FLD),           INTENT(inout) ::   sdjf      ! input field related variables
+      INTEGER  , OPTIONAL, INTENT(in   ) ::   Kmm    ! ocean time level index
+      !
+      INTEGER  ::   ja     ! end of this record (in seconds)
+      !!----------------------------------------------------------------------
+      !
+      IF( ksecsbc > sdjf%nrec_a(2) ) THEN     ! --> we need to update after data
+        
+         ! find where is the new after record... (it is not necessary sdjf%nrec_a(1)+1 )
+         ja = sdjf%nrec_a(1)
+         DO WHILE ( ksecsbc >= sdjf%nrecsec(ja) .AND. ja < sdjf%nreclast )   ! Warning: make sure ja <= sdjf%nreclast in this test
+            ja = ja + 1
+         END DO
+         IF( ksecsbc > sdjf%nrecsec(ja) )   ja = ja + 1   ! in case ksecsbc > sdjf%nrecsec(sdjf%nreclast)
+
+         ! if ln_tint and if the new after is not ja+1, we need also to update after data before the swap
+         ! so, after the swap, sdjf%nrec_b(2) will still be the closest value located just before ksecsbc
+         IF( sdjf%ln_tint .AND. ( ja > sdjf%nrec_a(1) + 1 .OR. sdjf%nrec_a(2) == nflag ) ) THEN
+            sdjf%nrec_a(:) = (/ ja-1, sdjf%nrecsec(ja-1) /)   ! update nrec_a with before information
+            CALL fld_get( sdjf, Kmm )                         ! read after data that will be used as before data
+         ENDIF
+            
+         ! if after is in the next file...
+         IF( ja > sdjf%nreclast ) THEN
+            
+            CALL fld_def( sdjf )
+            IF( ksecsbc > sdjf%nrecsec(sdjf%nreclast) )   CALL fld_def( sdjf, ldnext = .TRUE. )
+            CALL fld_clopn( sdjf )           ! open next file
+            
+            ! find where is after in this new file
+            ja = 1
+            DO WHILE ( ksecsbc > sdjf%nrecsec(ja) .AND. ja < sdjf%nreclast )
+               ja = ja + 1
+            END DO
+            IF( ksecsbc > sdjf%nrecsec(ja) )   ja = ja + 1   ! in case ksecsbc > sdjf%nrecsec(sdjf%nreclast)
+            
+            IF( ja > sdjf%nreclast ) THEN
+               CALL ctl_stop( "STOP", "fld_def: need next-next file? we should not be there... file: "//TRIM(sdjf%clrootname) )
             ENDIF
-         ELSE                                     ! no time interpolation
-            sdjf%nrec_a(1) = 1
-            sdjf%nrec_a(2) = NINT(rday) * nyear_len(1) + nsec1jan000   ! swap at the end    of the year
-            sdjf%nrec_b(2) = nsec1jan000                               ! beginning of the year (only for print)
-         ENDIF
-         !
-         !                                        ! ============ !
-      ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN      ! monthly mean !
-         !                                        ! ============ !
-         !
-         IF( sdjf%ln_tint ) THEN                  ! time interpolation, shift by 1/2 record
-            !
-            !                  INT( ztmp )
-            !                     /|\
-            !                    1 |    *----
-            !                    0 |----(              
-            !                      |----+----|--> time
-            !                      0   /|\   1   (nday/nmonth_len(nmonth))
-            !                           |   
-            !                           |   
-            !       forcing record :  nmonth 
-            !                            
-            ztmp =  REAL( nsec_month, wp ) / ( REAL( nmonth_len(nmonth), wp ) * rday ) + 0.5 &
-           &      + REAL(  it_offset, wp ) / ( REAL( nmonth_len(nmonth), wp ) * rday )
-            imth = nmonth + INT( ztmp ) - COUNT((/llbefore/))
-            IF( sdjf%cltype == 'monthly' ) THEN   ;   sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/))
-            ELSE                                  ;   sdjf%nrec_a(1) = imth
+            
+            ! if ln_tint and if after is not the first record, we must (potentially again) update after data before the swap
+            IF( sdjf%ln_tint .AND. ja > 1 ) THEN
+               IF( sdjf%nrecsec(0) /= nflag ) THEN                  ! no trick used: after file is not the current file
+                  sdjf%nrec_a(:) = (/ ja-1, sdjf%nrecsec(ja-1) /)   ! update nrec_a with before information
+                  CALL fld_get( sdjf, Kmm )                         ! read after data that will be used as before data
+               ENDIF
             ENDIF
-            sdjf%nrec_a(2) = nmonth_half(   imth ) + nsec1jan000   ! swap at the middle of the month
-         ELSE                                    ! no time interpolation
-            IF( sdjf%cltype == 'monthly' ) THEN   ;   sdjf%nrec_a(1) = 1
-            ELSE                                  ;   sdjf%nrec_a(1) = nmonth
-            ENDIF
-            sdjf%nrec_a(2) =  nmonth_end(nmonth  ) + nsec1jan000   ! swap at the end    of the month
-            sdjf%nrec_b(2) =  nmonth_end(nmonth-1) + nsec1jan000   ! beginning of the month (only for print)
-         ENDIF
-         !
-         !                                        ! ================================ !
-      ELSE                                        ! higher frequency mean (in hours)
-         !                                        ! ================================ !
-         !
-         ifreq_sec = NINT( sdjf%freqh * 3600. )                                         ! frequency mean (in seconds)
-         IF( sdjf%cltype(1:4) == 'week' )   isec_week = ksec_week( sdjf%cltype(6:8) )   ! since the first day of the current week
-         ! number of second since the beginning of the file
-         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   ztmp = REAL(nsec_month,wp)  ! since the first day of the current month
-         ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   ztmp = REAL(isec_week ,wp)  ! since the first day of the current week
-         ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   ztmp = REAL(nsec_day  ,wp)  ! since 00h of the current day
-         ELSE                                           ;   ztmp = REAL(nsec_year ,wp)  ! since 00h on Jan 1 of the current year
-         ENDIF
-         ztmp = ztmp + 0.5 * REAL(kn_fsbc - 1, wp) * rdt + REAL( it_offset, wp )        ! centrered in the middle of sbc time step
-         ztmp = ztmp + 0.01 * rdt                                                       ! avoid truncation error 
-         IF( sdjf%ln_tint ) THEN                 ! time interpolation, shift by 1/2 record
-            !
-            !          INT( ztmp/ifreq_sec + 0.5 )
-            !                     /|\
-            !                    2 |        *-----(
-            !                    1 |  *-----(
-            !                    0 |--(              
-            !                      |--+--|--+--|--+--|--> time
-            !                      0 /|\ 1 /|\ 2 /|\ 3    (ztmp/ifreq_sec)
-            !                         |     |     |
-            !                         |     |     |
-            !       forcing record :  1     2     3
-            !                   
-            ztmp= ztmp / REAL(ifreq_sec, wp) + 0.5
-         ELSE                                    ! no time interpolation
-            !
-            !           INT( ztmp/ifreq_sec )
-            !                     /|\
-            !                    2 |           *-----(
-            !                    1 |     *-----(
-            !                    0 |-----(              
-            !                      |--+--|--+--|--+--|--> time
-            !                      0 /|\ 1 /|\ 2 /|\ 3    (ztmp/ifreq_sec)
-            !                         |     |     |
-            !                         |     |     |
-            !       forcing record :  1     2     3
-            !                            
-            ztmp= ztmp / REAL(ifreq_sec, wp)
-         ENDIF
-         sdjf%nrec_a(1) = 1 + INT( ztmp ) - COUNT((/llbefore/))   ! record number to be read
-
-         iendrec = ifreq_sec * sdjf%nrec_a(1) + nsec1jan000       ! end of this record (in second)
-         ! add the number of seconds between 00h Jan 1 and the end of previous month/week/day (ok if nmonth=1)
-         IF( sdjf%cltype      == 'monthly' )   iendrec = iendrec + NINT(rday) * SUM(nmonth_len(1:nmonth -1))
-         IF( sdjf%cltype(1:4) == 'week'    )   iendrec = iendrec + ( nsec_year - isec_week )
-         IF( sdjf%cltype      == 'daily'   )   iendrec = iendrec + NINT(rday) * ( nday_year - 1 )
-         IF( sdjf%ln_tint ) THEN
-             sdjf%nrec_a(2) = iendrec - ifreq_sec / 2        ! swap at the middle of the record
+            
+         ENDIF
+
+         IF( sdjf%ln_tint ) THEN 
+            ! Swap data
+            sdjf%nrec_b(:)     = sdjf%nrec_a(:)                     ! swap before record informations
+            sdjf%rotn(1)       = sdjf%rotn(2)                       ! swap before rotate informations
+            sdjf%fdta(:,:,:,1) = sdjf%fdta(:,:,:,2)                 ! swap before record field
          ELSE
-             sdjf%nrec_a(2) = iendrec                        ! swap at the end    of the record
-             sdjf%nrec_b(2) = iendrec - ifreq_sec            ! beginning of the record (only for print)
-         ENDIF
-         !
-      ENDIF
-      !
-      IF( .NOT. sdjf%ln_tint ) sdjf%nrec_a(2) = sdjf%nrec_a(2) - 1   ! last second belongs to bext record : *----(
-      !
-   END SUBROUTINE fld_rec
-
-
-   SUBROUTINE fld_get( sdjf )
+            sdjf%nrec_b(:) = (/ ja-1, sdjf%nrecsec(ja-1) /)         ! only for print 
+         ENDIF
+            
+         ! read new after data
+         sdjf%nrec_a(:) = (/ ja, sdjf%nrecsec(ja) /)                ! update nrec_a as it is used by fld_get
+         CALL fld_get( sdjf, Kmm )                                  ! read after data (with nrec_a informations)
+        
+      ENDIF
+      !
+   END SUBROUTINE fld_update
+
+
+   SUBROUTINE fld_get( sdjf, Kmm )
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE fld_get  ***
@@ -604,5 +341,6 @@
       !! ** Purpose :   read the data
       !!----------------------------------------------------------------------
-      TYPE(FLD)        , INTENT(inout) ::   sdjf   ! input field related variables
+      TYPE(FLD),           INTENT(inout) ::   sdjf   ! input field related variables
+      INTEGER  , OPTIONAL, INTENT(in   ) ::   Kmm    ! ocean time level index
       !
       INTEGER ::   ipk      ! number of vertical levels of sdjf%fdta ( 2D: ipk=1 ; 3D: ipk=jpk )
@@ -618,7 +356,7 @@
       IF( ASSOCIATED(sdjf%imap) ) THEN
          IF( sdjf%ln_tint ) THEN   ;   CALL fld_map( sdjf%num, sdjf%clvar, sdjf%fdta(:,:,:,2), sdjf%nrec_a(1),   &
-            &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint )
+            &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint, Kmm )
          ELSE                      ;   CALL fld_map( sdjf%num, sdjf%clvar, sdjf%fnow(:,:,:  ), sdjf%nrec_a(1),   &
-            &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint )
+            &                                        sdjf%imap, sdjf%igrd, sdjf%ibdy, sdjf%ltotvel, sdjf%lzint, Kmm )
          ENDIF
       ELSE IF( LEN(TRIM(sdjf%wgtname)) > 0 ) THEN
@@ -656,5 +394,5 @@
             ENDIF
          CASE DEFAULT
-            IF (lk_c1d .AND. lmoor ) THEN
+            IF(lk_c1d .AND. lmoor ) THEN
                IF( sdjf%ln_tint ) THEN
                   CALL iom_get( sdjf%num, jpdom_unknown, sdjf%clvar, sdjf%fdta(2,2,:,2), sdjf%nrec_a(1) )
@@ -677,5 +415,5 @@
 
    
-   SUBROUTINE fld_map( knum, cdvar, pdta, krec, kmap, kgrd, kbdy, ldtotvel, ldzint )
+   SUBROUTINE fld_map( knum, cdvar, pdta, krec, kmap, kgrd, kbdy, ldtotvel, ldzint, Kmm )
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE fld_map  ***
@@ -694,4 +432,5 @@
       LOGICAL, OPTIONAL         , INTENT(in   ) ::   ldtotvel     ! true if total ( = barotrop + barocline) velocity
       LOGICAL, OPTIONAL         , INTENT(in   ) ::   ldzint       ! true if 3D variable requires a vertical interpolation
+      INTEGER, OPTIONAL         , INTENT(in   ) ::   Kmm          ! ocean time level index 
       !!
       INTEGER                                   ::   ipi          ! length of boundary data on local process
@@ -758,5 +497,5 @@
                
                CALL iom_getatt(knum, '_FillValue', zfv, cdvar=cdvar )
-               CALL fld_bdy_interp(zdta_read, zdta_read_z, zdta_read_dz, pdta, kgrd, kbdy, zfv, ldtotvel)
+               CALL fld_bdy_interp(zdta_read, zdta_read_z, zdta_read_dz, pdta, kgrd, kbdy, zfv, ldtotvel, Kmm)
                DEALLOCATE( zdta_read, zdta_read_z, zdta_read_dz )
                
@@ -822,6 +561,5 @@
    END SUBROUTINE fld_map_core
    
-   
-   SUBROUTINE fld_bdy_interp(pdta_read, pdta_read_z, pdta_read_dz, pdta, kgrd, kbdy, pfv, ldtotvel)
+   SUBROUTINE fld_bdy_interp(pdta_read, pdta_read_z, pdta_read_dz, pdta, kgrd, kbdy, pfv, ldtotvel, Kmm )
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE fld_bdy_interp  ***
@@ -840,4 +578,5 @@
       INTEGER                   , INTENT(in   ) ::   kgrd            ! grid type (t, u, v)
       INTEGER                   , INTENT(in   ) ::   kbdy            ! bdy number
+      INTEGER, OPTIONAL         , INTENT(in   ) ::   Kmm             ! ocean time level index
       !!
       INTEGER                  ::   ipi                 ! length of boundary data on local process
@@ -866,9 +605,9 @@
          SELECT CASE( kgrd )                         
          CASE(1)            ! depth of T points:
-            zdepth(:) = gdept_n(ji,jj,:)
+            zdepth(:) = gdept(ji,jj,:,Kmm)
          CASE(2)            ! depth of U points: we must not use gdept_n as we don't want to do a communication
             !                 --> copy what is done for gdept_n in domvvl...
             zdhalf(1) = 0.0_wp
-            zdepth(1) = 0.5_wp * e3uw_n(ji,jj,1)
+            zdepth(1) = 0.5_wp * e3uw(ji,jj,1,Kmm)
             DO jk = 2, jpk                               ! vertical sum
                !    zcoef = umask - wumask    ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt
@@ -877,12 +616,12 @@
                !!gm ???????   BUG ?  gdept_n as well as gde3w_n  does not include the thickness of ISF ??
                zcoef = ( umask(ji,jj,jk) - wumask(ji,jj,jk) )
-               zdhalf(jk) = zdhalf(jk-1) + e3u_n(ji,jj,jk-1)
-               zdepth(jk) =       zcoef  * ( zdhalf(jk  ) + 0.5 * e3uw_n(ji,jj,jk))  &
-                  &         + (1.-zcoef) * ( zdepth(jk-1) +       e3uw_n(ji,jj,jk))
+               zdhalf(jk) = zdhalf(jk-1) + e3u(ji,jj,jk-1,Kmm)
+               zdepth(jk) =          zcoef  * ( zdhalf(jk  ) + 0.5_wp * e3uw(ji,jj,jk,Kmm))  &
+                  &         + (1._wp-zcoef) * ( zdepth(jk-1) +          e3uw(ji,jj,jk,Kmm))
             END DO
          CASE(3)            ! depth of V points: we must not use gdept_n as we don't want to do a communication
             !                 --> copy what is done for gdept_n in domvvl...
             zdhalf(1) = 0.0_wp
-            zdepth(1) = 0.5_wp * e3vw_n(ji,jj,1)
+            zdepth(1) = 0.5_wp * e3vw(ji,jj,1,Kmm)
             DO jk = 2, jpk                               ! vertical sum
                !    zcoef = vmask - wvmask    ! 0 everywhere tmask = wmask, ie everywhere expect at jk = mikt
@@ -891,7 +630,7 @@
                !!gm ???????   BUG ?  gdept_n as well as gde3w_n  does not include the thickness of ISF ??
                zcoef = ( vmask(ji,jj,jk) - wvmask(ji,jj,jk) )
-               zdhalf(jk) = zdhalf(jk-1) + e3v_n(ji,jj,jk-1)
-               zdepth(jk) =       zcoef  * ( zdhalf(jk  ) + 0.5 * e3vw_n(ji,jj,jk))  &
-                  &         + (1.-zcoef) * ( zdepth(jk-1) +       e3vw_n(ji,jj,jk))
+               zdhalf(jk) = zdhalf(jk-1) + e3v(ji,jj,jk-1,Kmm)
+               zdepth(jk) =          zcoef  * ( zdhalf(jk  ) + 0.5_wp * e3vw(ji,jj,jk,Kmm))  &
+                  &         + (1._wp-zcoef) * ( zdepth(jk-1) +          e3vw(ji,jj,jk,Kmm))
             END DO
          END SELECT
@@ -911,5 +650,5 @@
                END DO
             ENDIF
-         END DO
+         END DO   ! jpk
          !
       END DO   ! ipi
@@ -937,11 +676,11 @@
             ztrans_new = 0._wp
             DO jk = 1, jpk                                ! calculate transport on model grid
-               ztrans_new = ztrans_new + pdta(jb,1,jk ) * e3u_n(ji,jj,jk) * umask(ji,jj,jk)
+               ztrans_new = ztrans_new +      pdta(jb,1,jk ) * e3u(ji,jj,jk,Kmm ) * umask(ji,jj,jk)
             ENDDO
             DO jk = 1, jpk                                ! make transport correction
                IF(ldtotvel) THEN ! bdy data are total velocity so adjust bt transport term to match input data
-                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hu_n(ji,jj) ) * umask(ji,jj,jk)
+                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hu(ji,jj,Kmm) ) * umask(ji,jj,jk)
                ELSE              ! we're just dealing with bc velocity so bt transport term should sum to zero
-                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hu_n(ji,jj) ) * umask(ji,jj,jk)
+                  pdta(jb,1,jk) =   pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hu(ji,jj,Kmm)   * umask(ji,jj,jk)
                ENDIF
             ENDDO
@@ -958,19 +697,19 @@
             ztrans_new = 0._wp
             DO jk = 1, jpk                                ! calculate transport on model grid
-               ztrans_new = ztrans_new + pdta(jb,1,jk ) * e3v_n(ji,jj,jk) * vmask(ji,jj,jk)
+               ztrans_new = ztrans_new +      pdta(jb,1,jk ) * e3v(ji,jj,jk,Kmm ) * vmask(ji,jj,jk)
             ENDDO
             DO jk = 1, jpk                                ! make transport correction
                IF(ldtotvel) THEN ! bdy data are total velocity so adjust bt transport term to match input data
-                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hv_n(ji,jj) ) * vmask(ji,jj,jk)
+                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + ( ztrans - ztrans_new ) * r1_hv(ji,jj,Kmm) ) * vmask(ji,jj,jk)
                ELSE              ! we're just dealing with bc velocity so bt transport term should sum to zero
-                  pdta(jb,1,jk) = ( pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hv_n(ji,jj) ) * vmask(ji,jj,jk)
+                  pdta(jb,1,jk) =   pdta(jb,1,jk) + (  0._wp - ztrans_new ) * r1_hv(ji,jj,Kmm)   * vmask(ji,jj,jk)
                ENDIF
             ENDDO
          ENDDO
       END SELECT
-
+      
    END SUBROUTINE fld_bdy_interp
 
-   
+
    SUBROUTINE fld_rot( kt, sd )
       !!---------------------------------------------------------------------
@@ -1013,6 +752,6 @@
                            sd(ju)%fdta(:,:,jk,jn) = utmp(:,:)   ;   sd(iv)%fdta(:,:,jk,jn) = vtmp(:,:)
                         ELSE 
-                           CALL rot_rep( sd(ju)%fnow(:,:,jk  ), sd(iv)%fnow(:,:,jk  ), 'T', 'en->i', utmp(:,:) )
-                           CALL rot_rep( sd(ju)%fnow(:,:,jk  ), sd(iv)%fnow(:,:,jk  ), 'T', 'en->j', vtmp(:,:) )
+                           CALL rot_rep( sd(ju)%fnow(:,:,jk   ), sd(iv)%fnow(:,:,jk   ), 'T', 'en->i', utmp(:,:) )
+                           CALL rot_rep( sd(ju)%fnow(:,:,jk   ), sd(iv)%fnow(:,:,jk   ), 'T', 'en->j', vtmp(:,:) )
                            sd(ju)%fnow(:,:,jk   ) = utmp(:,:)   ;   sd(iv)%fnow(:,:,jk   ) = vtmp(:,:)
                         ENDIF
@@ -1030,93 +769,199 @@
 
 
-   SUBROUTINE fld_clopn( sdjf, kyear, kmonth, kday, ldstop )
+   SUBROUTINE fld_def( sdjf, ldprev, ldnext )
+      !!---------------------------------------------------------------------
+      !!                    ***  ROUTINE fld_def  ***
+      !!
+      !! ** Purpose :   define the record(s) of the file and its name
+      !!----------------------------------------------------------------------
+      TYPE(FLD)        , INTENT(inout) ::   sdjf       ! input field related variables
+      LOGICAL, OPTIONAL, INTENT(in   ) ::   ldprev     ! 
+      LOGICAL, OPTIONAL, INTENT(in   ) ::   ldnext     ! 
+      !
+      INTEGER  :: jt
+      INTEGER  :: idaysec               ! number of seconds in 1 day = NINT(rday)
+      INTEGER  :: iyr, imt, idy, isecwk
+      INTEGER  :: indexyr, indexmt
+      INTEGER  :: ireclast
+      INTEGER  :: ishift, istart
+      INTEGER, DIMENSION(2)  :: isave
+      REAL(wp) :: zfreqs
+      LOGICAL  :: llprev, llnext, llstop
+      LOGICAL  :: llprevmt, llprevyr
+      LOGICAL  :: llnextmt, llnextyr
+      !!----------------------------------------------------------------------
+      idaysec = NINT(rday)
+      !
+      IF( PRESENT(ldprev) ) THEN   ;   llprev = ldprev
+      ELSE                         ;   llprev = .FALSE.
+      ENDIF
+      IF( PRESENT(ldnext) ) THEN   ;   llnext = ldnext
+      ELSE                         ;   llnext = .FALSE.
+      ENDIF
+
+      ! current file parameters
+      IF( sdjf%cltype(1:4) == 'week' ) THEN          ! find the day of the beginning of the current week
+         isecwk = ksec_week( sdjf%cltype(6:8) )     ! seconds between the beginning of the week and half of current time step
+         llprevmt = isecwk > nsec_month               ! longer time since beginning of the current week than the current month
+         llprevyr = llprevmt .AND. nmonth == 1
+         iyr = nyear  - COUNT((/llprevyr/))
+         imt = nmonth - COUNT((/llprevmt/)) + 12 * COUNT((/llprevyr/))
+         idy = nday + nmonth_len(nmonth-1) * COUNT((/llprevmt/)) - isecwk / idaysec
+         isecwk = nsec_year - isecwk              ! seconds between 00h jan 1st of current year and current week beginning
+      ELSE
+         iyr = nyear
+         imt = nmonth
+         idy = nday
+         isecwk  = 0
+      ENDIF
+
+      ! previous file parameters
+      IF( llprev ) THEN
+         IF( sdjf%cltype(1:4) == 'week'    ) THEN     ! find the day of the beginning of previous week
+            isecwk = isecwk + 7 * idaysec         ! seconds between the beginning of previous week and half of the time step
+            llprevmt = isecwk > nsec_month            ! longer time since beginning of the previous week than the current month
+            llprevyr = llprevmt .AND. nmonth == 1
+            iyr = nyear  - COUNT((/llprevyr/))
+            imt = nmonth - COUNT((/llprevmt/)) + 12 * COUNT((/llprevyr/))
+            idy = nday + nmonth_len(nmonth-1) * COUNT((/llprevmt/)) - isecwk / idaysec
+            isecwk = nsec_year - isecwk           ! seconds between 00h jan 1st of current year and previous week beginning
+         ELSE
+            idy = nday   - COUNT((/ sdjf%cltype == 'daily'                 /))
+            imt = nmonth - COUNT((/ sdjf%cltype == 'monthly' .OR. idy == 0 /))
+            iyr = nyear  - COUNT((/ sdjf%cltype == 'yearly'  .OR. imt == 0 /))
+            IF( idy == 0 ) idy = nmonth_len(imt)
+            IF( imt == 0 ) imt = 12
+            isecwk = 0
+         ENDIF
+      ENDIF
+
+      ! next file parameters
+      IF( llnext ) THEN
+         IF( sdjf%cltype(1:4) == 'week'    ) THEN     ! find the day of the beginning of next week
+            isecwk = 7 * idaysec - isecwk         ! seconds between half of the time step and the beginning of next week
+            llnextmt = isecwk > ( nmonth_len(nmonth)*idaysec - nsec_month )   ! larger than the seconds to the end of the month
+            llnextyr = llnextmt .AND. nmonth == 12
+            iyr = nyear  + COUNT((/llnextyr/))
+            imt = nmonth + COUNT((/llnextmt/)) - 12 * COUNT((/llnextyr/))
+            idy = nday - nmonth_len(nmonth) * COUNT((/llnextmt/)) + isecwk / idaysec + 1
+            isecwk = nsec_year + isecwk           ! seconds between 00h jan 1st of current year and next week beginning
+         ELSE
+            idy = nday   + COUNT((/ sdjf%cltype == 'daily'                                 /))
+            imt = nmonth + COUNT((/ sdjf%cltype == 'monthly' .OR. idy > nmonth_len(nmonth) /))
+            iyr = nyear  + COUNT((/ sdjf%cltype == 'yearly'  .OR. imt == 13                /))
+            IF( idy > nmonth_len(nmonth) )   idy = 1
+            IF( imt == 13                )   imt = 1
+            isecwk = 0
+         ENDIF
+      ENDIF
+      !
+      ! find the last record to be read -> update sdjf%nreclast
+      indexyr = iyr - nyear + 1                 ! which  year are we looking for? previous(0), current(1) or next(2)?
+      indexmt = imt + 12 * ( indexyr - 1 )      ! which month are we looking for (relatively to current year)? 
+      !
+      ! Last record to be read in the current file
+      ! Predefine the number of record in the file according of its type.
+      ! We could compare this number with the number of records in the file and make a stop if the 2 numbers do not match...
+      ! However this would be much less fexible (e.g. for tests) and will force to rewite input files according to nleapy...
+      IF    ( NINT(sdjf%freqh) == -12 ) THEN            ;   ireclast = 1    ! yearly mean: consider only 1 record
+      ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN                                ! monthly mean:
+         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   ireclast = 1    !  consider that the file has  1 record
+         ELSE                                           ;   ireclast = 12   !  consider that the file has 12 record
+         ENDIF
+      ELSE                                                                  ! higher frequency mean (in hours)
+         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   ireclast = NINT( 24. * REAL(nmonth_len(indexmt), wp) / sdjf%freqh )
+         ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   ireclast = NINT( 24. * 7.                            / sdjf%freqh )
+         ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   ireclast = NINT( 24.                                 / sdjf%freqh )
+         ELSE                                           ;   ireclast = NINT( 24. * REAL( nyear_len(indexyr), wp) / sdjf%freqh )
+         ENDIF
+      ENDIF
+
+      sdjf%nreclast = ireclast
+      ! Allocate arrays for beginning/middle/end of each record (seconds since Jan. 1st 00h of nit000 year)
+      IF( ALLOCATED(sdjf%nrecsec) )   DEALLOCATE( sdjf%nrecsec )
+      ALLOCATE( sdjf%nrecsec( 0:ireclast ) )
+      !
+      IF    ( NINT(sdjf%freqh) == -12 ) THEN                                     ! yearly mean and yearly file
+         SELECT CASE( indexyr )
+         CASE(0)   ;   sdjf%nrecsec(0) = nsec1jan000 - nyear_len( 0 ) * idaysec
+         CASE(1)   ;   sdjf%nrecsec(0) = nsec1jan000
+         CASE(2)   ;   sdjf%nrecsec(0) = nsec1jan000 + nyear_len( 1 ) * idaysec
+         ENDSELECT
+         sdjf%nrecsec(1) = sdjf%nrecsec(0) + nyear_len( indexyr ) * idaysec
+      ELSEIF( NINT(sdjf%freqh) ==  -1 ) THEN                                     ! monthly mean:
+         IF(     sdjf%cltype      == 'monthly' ) THEN                            !    monthly file
+            sdjf%nrecsec(0   ) = nsec1jan000 + nmonth_beg(indexmt  )
+            sdjf%nrecsec(1   ) = nsec1jan000 + nmonth_beg(indexmt+1)
+         ELSE                                                                    !    yearly  file
+            ishift = 12 * ( indexyr - 1 )
+            sdjf%nrecsec(0:12) = nsec1jan000 + nmonth_beg(1+ishift:13+ishift)
+         ENDIF
+      ELSE                                                                       ! higher frequency mean (in hours)
+         IF(     sdjf%cltype      == 'monthly' ) THEN   ;   istart = nsec1jan000 + nmonth_beg(indexmt)
+         ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   istart = nsec1jan000 + isecwk
+         ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   istart = nsec1jan000 + nmonth_beg(indexmt) + ( idy - 1 ) * idaysec
+         ELSEIF( indexyr          == 0         ) THEN   ;   istart = nsec1jan000 - nyear_len( 0 ) * idaysec
+         ELSEIF( indexyr          == 2         ) THEN   ;   istart = nsec1jan000 + nyear_len( 1 ) * idaysec
+         ELSE                                           ;   istart = nsec1jan000
+         ENDIF
+         zfreqs = sdjf%freqh * rhhmm * rmmss
+         DO jt = 0, sdjf%nreclast
+            sdjf%nrecsec(jt) = istart + NINT( zfreqs * REAL(jt,wp) )
+         END DO
+      ENDIF
+      !
+      IF( sdjf%ln_tint ) THEN   ! record time defined in the middle of the record, computed using an implementation
+                                ! of the rounded average that is valid over the full integer range
+         sdjf%nrecsec(1:sdjf%nreclast) = sdjf%nrecsec(0:sdjf%nreclast-1) / 2 + sdjf%nrecsec(1:sdjf%nreclast) / 2 + &
+            & MAX( MOD( sdjf%nrecsec(0:sdjf%nreclast-1), 2 ), MOD( sdjf%nrecsec(1:sdjf%nreclast), 2 ) )
+      END IF
+      !
+      sdjf%clname = fld_filename( sdjf, idy, imt, iyr )
+      !
+   END SUBROUTINE fld_def
+
+   
+   SUBROUTINE fld_clopn( sdjf )
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE fld_clopn  ***
       !!
-      !! ** Purpose :   update the file name and close/open the files
-      !!----------------------------------------------------------------------
-      TYPE(FLD)        , INTENT(inout) ::   sdjf     ! input field related variables
-      INTEGER, OPTIONAL, INTENT(in   ) ::   kyear    ! year value
-      INTEGER, OPTIONAL, INTENT(in   ) ::   kmonth   ! month value
-      INTEGER, OPTIONAL, INTENT(in   ) ::   kday     ! day value
-      LOGICAL, OPTIONAL, INTENT(in   ) ::   ldstop   ! stop if open to read a non-existing file (default = .TRUE.)
-      !
-      LOGICAL  :: llprevyr              ! are we reading previous year  file?
-      LOGICAL  :: llprevmth             ! are we reading previous month file?
-      INTEGER  :: iyear, imonth, iday   ! first day of the current file in yyyy mm dd
-      INTEGER  :: isec_week             ! number of seconds since start of the weekly file
-      INTEGER  :: indexyr               ! year undex (O/1/2: previous/current/next)
-      REAL(wp) :: zyear_len, zmonth_len ! length (days) of iyear and imonth             ! 
-      CHARACTER(len = 256) ::   clname  ! temporary file name
-      !!----------------------------------------------------------------------
-      IF( PRESENT(kyear) ) THEN                             ! use given values 
-         iyear = kyear
-         imonth = kmonth
-         iday = kday
-         IF ( sdjf%cltype(1:4) == 'week' ) THEN             ! find the day of the beginning of the week
-            isec_week = ksec_week( sdjf%cltype(6:8) )- (86400 * 8 )  
-            llprevmth  = isec_week > nsec_month             ! longer time since beginning of the week than the month
-            llprevyr   = llprevmth .AND. nmonth == 1
-            iyear  = nyear  - COUNT((/llprevyr /))
-            imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /))
-            iday   = nday   + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday)
-         ENDIF
-      ELSE                                                  ! use current day values
-         IF ( sdjf%cltype(1:4) == 'week' ) THEN             ! find the day of the beginning of the week
-            isec_week  = ksec_week( sdjf%cltype(6:8) )      ! second since the beginning of the week
-            llprevmth  = isec_week > nsec_month             ! longer time since beginning of the week than the month
-            llprevyr   = llprevmth .AND. nmonth == 1
-         ELSE
-            isec_week  = 0
-            llprevmth  = .FALSE.
-            llprevyr   = .FALSE.
-         ENDIF
-         iyear  = nyear  - COUNT((/llprevyr /))
-         imonth = nmonth - COUNT((/llprevmth/)) + 12 * COUNT((/llprevyr /))
-         iday   = nday   + nmonth_len(nmonth-1) * COUNT((/llprevmth/)) - isec_week / NINT(rday)
-      ENDIF
-
-      ! build the new filename if not climatological data
-      clname=TRIM(sdjf%clrootname)
-      !
-      ! note that sdjf%ln_clim is is only acting on the presence of the year in the file name
-      IF( .NOT. sdjf%ln_clim ) THEN   
-                                         WRITE(clname, '(a,"_y",i4.4)' ) TRIM( sdjf%clrootname ), iyear    ! add year
-         IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a,"m" ,i2.2)' ) TRIM( clname          ), imonth   ! add month
-      ELSE
-         ! build the new filename if climatological data
-         IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a,"_m",i2.2)' ) TRIM( sdjf%clrootname ), imonth   ! add month
-      ENDIF
-      IF( sdjf%cltype == 'daily' .OR. sdjf%cltype(1:4) == 'week' ) &
-            &                            WRITE(clname, '(a,"d" ,i2.2)' ) TRIM( clname          ), iday     ! add day
-      !
-      IF( TRIM(clname) /= TRIM(sdjf%clname) .OR. sdjf%num == 0 ) THEN   ! new file to be open 
-         !
-         sdjf%clname = TRIM(clname)
-         IF( sdjf%num /= 0 )   CALL iom_close( sdjf%num )   ! close file if already open
-         CALL iom_open( sdjf%clname, sdjf%num, ldstop = ldstop, ldiof =  LEN(TRIM(sdjf%wgtname)) > 0 )
-         !
-         ! find the last record to be read -> update sdjf%nreclast
-         indexyr = iyear - nyear + 1
-         zyear_len = REAL(nyear_len( indexyr ), wp)
-         SELECT CASE ( indexyr )
-         CASE ( 0 )   ;   zmonth_len = 31.   ! previous year -> imonth = 12
-         CASE ( 1 )   ;   zmonth_len = REAL(nmonth_len(imonth), wp)
-         CASE ( 2 )   ;   zmonth_len = 31.   ! next     year -> imonth = 1
-         END SELECT
-         !
-         ! last record to be read in the current file
-         IF    ( sdjf%freqh == -12. ) THEN                 ;   sdjf%nreclast = 1    !  yearly mean
-         ELSEIF( sdjf%freqh ==  -1. ) THEN                                          ! monthly mean
-            IF(     sdjf%cltype      == 'monthly' ) THEN   ;   sdjf%nreclast = 1
-            ELSE                                           ;   sdjf%nreclast = 12
-            ENDIF
-         ELSE                                                                       ! higher frequency mean (in hours)
-            IF(     sdjf%cltype      == 'monthly' ) THEN   ;   sdjf%nreclast = NINT( 24. * zmonth_len / sdjf%freqh )
-            ELSEIF( sdjf%cltype(1:4) == 'week'    ) THEN   ;   sdjf%nreclast = NINT( 24. * 7.         / sdjf%freqh )
-            ELSEIF( sdjf%cltype      == 'daily'   ) THEN   ;   sdjf%nreclast = NINT( 24.              / sdjf%freqh )
-            ELSE                                           ;   sdjf%nreclast = NINT( 24. * zyear_len  / sdjf%freqh )
-            ENDIF
-         ENDIF
+      !! ** Purpose :   close/open the files
+      !!----------------------------------------------------------------------
+      TYPE(FLD)        , INTENT(inout) ::   sdjf       ! input field related variables
+      !
+      INTEGER, DIMENSION(2)  :: isave
+      LOGICAL  :: llprev, llnext, llstop
+      !!----------------------------------------------------------------------
+      !
+      llprev = sdjf%nrecsec(sdjf%nreclast) < nsec000_1jan000   ! file ends before the beginning of the job -> file may not exist
+      llnext = sdjf%nrecsec(       0     ) > nsecend_1jan000   ! file begins after the end of the job -> file may not exist 
+
+      llstop = sdjf%ln_clim .OR. .NOT. ( llprev .OR. llnext )
+
+      IF( sdjf%num <= 0 .OR. .NOT. sdjf%ln_clim  ) THEN
+         IF( sdjf%num > 0 )   CALL iom_close( sdjf%num )   ! close file if already open
+         CALL iom_open( sdjf%clname, sdjf%num, ldstop = llstop, ldiof = LEN(TRIM(sdjf%wgtname)) > 0 )
+      ENDIF
+      !
+      IF( sdjf%num <= 0 .AND. .NOT. llstop ) THEN   ! file not found but we do accept this...
+         !
+         IF( llprev ) THEN   ! previous file does not exist : go back to current and accept to read only the first record
+            CALL ctl_warn('previous file: '//TRIM(sdjf%clname)//' not found -> go back to current year/month/week/day file')
+            isave(1:2) = sdjf%nrecsec(sdjf%nreclast-1:sdjf%nreclast)   ! save previous file info
+            CALL fld_def( sdjf )   ! go back to current file
+            sdjf%nreclast = 1   ! force to use only the first record (do as if other were not existing...)
+            sdjf%nrecsec(0:1) = isave(1:2)
+         ENDIF
+         !
+         IF( llnext ) THEN   ! next     file does not exist : go back to current and accept to read only the last  record 
+            CALL ctl_warn('next file: '//TRIM(sdjf%clname)//' not found -> go back to current year/month/week/day file')
+            isave(1:2) = sdjf%nrecsec(0:1)    ! save next file info
+            CALL fld_def( sdjf )   ! go back to current file
+            ! -> read last record but keep record info from the first record of next file
+            sdjf%nrecsec(sdjf%nreclast-1:sdjf%nreclast) = isave(1:2)
+            sdjf%nrecsec(0:sdjf%nreclast-2) = nflag
+         ENDIF
+         !
+         CALL iom_open( sdjf%clname, sdjf%num, ldiof = LEN(TRIM(sdjf%wgtname)) > 0 )   
          !
       ENDIF
@@ -1300,6 +1145,6 @@
       CALL iom_open( sd%clname, inum, ldiof =  LEN(TRIM(sd%wgtname)) > 0 )
 
-      !! get dimensions
-      IF ( SIZE(sd%fnow, 3) > 1 ) THEN
+      !! get dimensions: we consider 2D data as 3D data with vertical dim size = 1
+      IF( SIZE(sd%fnow, 3) > 0 ) THEN
          ALLOCATE( ddims(4) )
       ELSE
@@ -1314,5 +1159,5 @@
 
       CALL iom_open ( sd%wgtname, inum )   ! interpolation weights
-      IF ( inum > 0 ) THEN
+      IF( inum > 0 ) THEN
 
          !! determine whether we have an east-west cyclic grid
@@ -1623,10 +1468,5 @@
          
          ref_wgts(kw)%fly_dta(:,:,:) = 0.0
-         SELECT CASE( SIZE(ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:),3) )
-         CASE(1)
-              CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,1), nrec, rec1, recn)
-         CASE DEFAULT
-              CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:), nrec, rec1, recn)
-         END SELECT 
+         CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%fly_dta(jpi1:jpi2,jpj1:jpj2,:), nrec, rec1, recn)
       ENDIF
       
@@ -1646,5 +1486,5 @@
       END DO
 
-      IF (ref_wgts(kw)%numwgt .EQ. 16) THEN
+      IF(ref_wgts(kw)%numwgt .EQ. 16) THEN
 
         !! fix up halo points that we couldnt read from file
@@ -1672,20 +1512,10 @@
            IF( jpi1 == 2 ) THEN
               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)%col(:,jpj1:jpj2,1), nrec, rec1, recn)
-              CASE DEFAULT
-                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn)
-              END SELECT      
+              CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn)
               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 + 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)%col(:,jpj1:jpj2,1), nrec, rec1, recn)
-              CASE DEFAULT
-                   CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn)
-              END SELECT
+              CALL iom_get( num, jpdom_unknown, clvar, ref_wgts(kw)%col(:,jpj1:jpj2,:), nrec, rec1, recn)
               ref_wgts(kw)%fly_dta(jpi2+1,jpj1:jpj2,:) = ref_wgts(kw)%col(1,jpj1:jpj2,:)
            ENDIF
@@ -1729,14 +1559,46 @@
          END DO
          !
-      END IF
+      ENDIF
       !
    END SUBROUTINE fld_interp
 
 
+   FUNCTION fld_filename( sdjf, kday, kmonth, kyear )
+      !!---------------------------------------------------------------------
+      !!                    ***  FUNCTION fld_filename *** 
+      !!
+      !! ** Purpose :   define the filename according to a given date
+      !!---------------------------------------------------------------------
+      TYPE(FLD), INTENT(in) ::   sdjf         ! input field related variables
+      INTEGER  , INTENT(in) ::   kday, kmonth, kyear
+      !
+      CHARACTER(len = 256) ::   clname, fld_filename
+      !!---------------------------------------------------------------------
+
+      
+      ! build the new filename if not climatological data
+      clname=TRIM(sdjf%clrootname)
+      !
+      ! note that sdjf%ln_clim is is only acting on the presence of the year in the file name
+      IF( .NOT. sdjf%ln_clim ) THEN   
+                                         WRITE(clname, '(a,"_y",i4.4)' ) TRIM( sdjf%clrootname ), kyear    ! add year
+         IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a, "m",i2.2)' ) TRIM( clname          ), kmonth   ! add month
+      ELSE
+         ! build the new filename if climatological data
+         IF( sdjf%cltype /= 'yearly' )   WRITE(clname, '(a,"_m",i2.2)' ) TRIM( sdjf%clrootname ), kmonth   ! add month
+      ENDIF
+      IF(    sdjf%cltype == 'daily' .OR. sdjf%cltype(1:4) == 'week' ) &
+         &                               WRITE(clname, '(a,"d" ,i2.2)' ) TRIM( clname          ), kday     ! add day
+
+      fld_filename = clname
+      
+   END FUNCTION fld_filename
+
+
    FUNCTION ksec_week( cdday )
       !!---------------------------------------------------------------------
-      !!                    ***  FUNCTION kshift_week *** 
-      !!
-      !! ** Purpose :   return the first 3 letters of the first day of the weekly file
+      !!                    ***  FUNCTION ksec_week *** 
+      !!
+      !! ** Purpose :   seconds between 00h of the beginning of the week and half of the current time step
       !!---------------------------------------------------------------------
       CHARACTER(len=*), INTENT(in)   ::   cdday   ! first 3 letters of the first day of the weekly file
@@ -1754,5 +1616,5 @@
       ishift = ijul * NINT(rday)
       ! 
-      ksec_week = nsec_week + ishift
+      ksec_week = nsec_monday + ishift
       ksec_week = MOD( ksec_week, 7*NINT(rday) )
       ! 
