SUBROUTINE timin (idtwis, idtwie)
! ----------------------------------------------------------------------
!**** *TIMIN* - STEERING MODULE IF TIME INTERPOLATION IS WANTED.
!     H. GUNTHER    ECMWF    MAY 1990     MODIFIED FOR SUB VERSION.
!     H. GUNTHER    ECMWF    DECEMBER 90  MODIFIED FOR CYCLE_4.
!*    PURPOSE.
!     --------
!       TIME INTERPOLATION: PROCESS WINDFIELDS.
!**   INTERFACE.
!     ----------
!       *CALL* *TIMIN (IDTWIS, IDTWIE, NC, NR)*
!          *IDTWIS* - DATE OF FIRST WIND FIELD
!          *IDTWIE* - DATE OF LAST FIRST WIND FIELD
!          *NC*     - NUMBER OF COLUMNES IN INPUT WIND
!          *NR*     - NUMBER OF ROWS     IN INPUT WIND
!     METHOD.
!     -------
!       WINDFIELDS ARE READ IN EVERY IDELWI SECONDS (U,V),
!       INTERPOLATED IN SPACE, BLOCKED AND SAVED ON SCRATCH UNITS.
!       MAGNITUDE AND DIRECTION ARE INTERPOLATED LINEARLY IN TIME AND
!       WRITTEN TO THE OUTPUT FILES.
!     EXTERNALS.
!     ----------
!       *ABORT*     - TERMINATES PROCESSING.
!       *AIRSEA*    - TOTAL STRESS IN SURFACE LAYER.
!       *CREWFN*    - ASSIGN A FILE NAME.
!       *GETWND*    - READ A WINDFIELD (UWND,VWND) AND COMPUTE WIND
!                     FOR ALL BLOCKS (US,DS).
!       *INCDATE*   - INCREMENT DATE.
!       *LOCINT*    - SPACE INTERPOLATION.
!     REFERENCE.
!     ----------
!       NONE.
! ----------------------------------------------------------------------
USE params ; USE gridpar ; USE stat ; USE testo ; USE units ; USE wind ; USE wind1
IMPLICIT NONE

CHARACTER (LEN=12), INTENT(IN) :: idtwis, idtwie
INCLUDE'globals.h'
CHARACTER (LEN=12) :: idth, idt1, idt2
REAL :: uwnd(nc,nr)    , vwnd(nc,nr)
REAL :: us_eta(nc,nr)  , z0_eta(nc,nr)
REAL :: us(niblo,nblo) , ds(niblo,nblo)
REAL :: us2(niblo,nblo), ds2(niblo,nblo)
REAL :: us3(niblo)     , ds3(niblo)
!        *UWND*   REAL   INPUT WIND FIELD ARRAY (U COMPONENT)
!        *VWND    REAL   INPUT WIND FIELD ARRAY (V COMPONENT)
!        *US*     REAL   OUTPUT WIND FIELD (FRICTION VELOCITIES).
!        *DS*     REAL   OUTPUT WIND FIELD (DIRECTIONS).
INTEGER :: iareas, it1, it2
INTEGER :: i, m, n, ig, ij, mm, mp, igg, ios, nts, iunit, mstep
REAL    :: del, d
#ifdef _OPENMP
INTEGER           :: omp_get_thread_num
#endif
! ----------------------------------------------------------------------
!*    1. INITIALIZE TIMECOUNTER.
!        -----------------------
IF( ida .EQ. '000000000000' ) THEN
   idt1 = idtwis
   CALL getwnd(us, ds, idt1, uwnd, vwnd, nc, nr, us_eta, z0_eta)
   IF( ig > 1) THEN
      DO ig = 1, igl
         DO ij = ijs(ig), ijl(ig)
            u10old(ij,ig) = us(ij,ig)
            thwold(ij,ig) = ds(ij,ig)
         ENDDO
      ENDDO
   ELSE
!$OMP PARALLEL private(ij)
      DO ij = itask(1, omp_get_thread_num()+1),itask(2, omp_get_thread_num()+1)
         u10old(ij,ig) = us(ij,ig)
         thwold(ij,ig) = ds(ij,ig)
      ENDDO
      CALL airsea(u10old(1,1), tauw(1,1), usold(1,1), z0old(1,1), &
                  itask(1, omp_get_thread_num()+1),               &
                  itask(2, omp_get_thread_num()+1)               )
!$OMP END PARALLEL
      IF( itest .GE. 3 ) THEN
         WRITE(iu06, '(''       SUB. TIMIN: FIRST WIND FIELD '', &
&            ''SAVED IN COMMON WIND'')')
      ENDIF
   ENDIF
ELSE
   idt1 = ida
   DO ig = 1, igl
      DO ij = ijs(ig), ijl(ig)
         us(ij, ig) = u10old(ij, ig)
         ds(ij, ig) = thwold(ij, ig)
      ENDDO
   ENDDO
   idth = idt1
   CALL incdate(idth, idelwo)
   IF( idtwis .NE. idth ) THEN
      WRITE(iu06,*) ' *******************************************'
      WRITE(iu06,*) ' *                                         *'
      WRITE(iu06,*) ' *        FATAL ERROR IN --TIMIN--         *'
      WRITE(iu06,*) ' *        =========================        *'
      WRITE(iu06,*) ' * DATES DO NOT MATCH.                     *'
      WRITE(iu06,*) ' * START DATE FOR WIND IS       IDTWIS = ', idtwis
      WRITE(iu06,*) ' * LAST DATE SAVED IN COM WIND IS IDT1 = ', idt1
      WRITE(iu06,*) ' * PROCESSING WILL BE ABORTED              *'
      WRITE(iu06,*) ' *                                         *'
      WRITE(iu06,*) ' *******************************************'
      CALL ABORT
   ENDIF
ENDIF
idt2 = idt1
CALL incdate (idt2, idelwi)
nts = idelwi / idelwo
del = REAL (idelwo) / REAL (idelwi)
CALL crewfn(iuvelo, idtwie)
IF( itest .GE. 3 ) THEN
   WRITE(iu06,*) '       SUB. TIMIN: NEW WIND FILE '
   WRITE(iu06,*) '       UNIT IS IUVELO = ',iuvelo,' WIND FILE DATE IS IDTWIE = ',idtwie
ENDIF
REWIND (UNIT = iuvelo)
!*    2. LOOP OVER INPUT WINDFIELDS.
!        ---------------------------
2000 CONTINUE
!*    2.1 READ ONE WINDFIELD AND TRANSFORM ALL BLOCKS.
!         -------------------------------------------
idt2 = idt1
CALL incdate (idt2, idelwi)
CALL getwnd (us2, ds2, idt2, uwnd, vwnd, nc, nr, us_eta, z0_eta)
!*    2.2 SAVE BLOCKED WIND FIELD ON SCRATCH UNITS.
!         -----------------------------------------
DO ig = 1, igl
   iunit = iuscr(ig)
   idth = idt1
   DO n = 1, nts
      CALL incdate (idth, idelwo)
      DO ij = ijs(ig), ijl(ig)
         us3(ij) = us(ij,ig) + real(n) * del * (us2(ij,ig) - us(ij,ig))
         d       = ds2(ij,ig) - ds(ij,ig)
         IF( abs (d) .GT. pi)   d = d-zpi * SIGN(1., d)
         d       = ds(ij,ig) + REAL(n) * del * d
         ds3(ij) = MOD(d+zpi, zpi)
      ENDDO
      WRITE( iunit, ERR = 6100, IOSTAT = ios ) idth, ig, (us3(i), i = 1, niblo),&
                                               (ds3(i), i = 1, niblo)
   ENDDO
   DO ij = ijs(ig), ijl(ig)
      us(ij,ig) = us2(ij,ig)
      ds(ij,ig) = ds2(ij,ig)
   ENDDO
ENDDO
idt1 = idt2
IF( itest .GE. 3 ) THEN
   WRITE(iu06,*) '       SUB. TIMIN: LAST WIND FIELD AT ', 'IDTH= ', idth,&
                 ' WRITTEN TO SCRATCH UNITS'
ENDIF
!*    2.3 UPDATE WIND FIELD REQUEST TIME AND READ NEXT IF REQUESTED.
!         ----------------------------------------------------------
CALL incdate(idth, idelwi)
IF( idth .LE. idtwie ) GOTO 2000
! ----------------------------------------------------------------------
!*    3. REWIND SCRATCH UNITS.
!        ---------------------
3000 CONTINUE
DO ig = 1, igl
   iunit = iuscr(ig)
   REWIND(UNIT = iunit)
ENDDO
! ----------------------------------------------------------------------
!*    4. RE-ARRANG THE BLOCKS.
!        ---------------------
4000 CONTINUE
mp    = MAX (idelwi, idelpro) / idelwo
mstep = MAX (1, idelpro / idelwo)
!*    4.1 LOOP OVER WIND FILES.
!         ---------------------
DO m = 1, mp, mstep
!*    4.1.1 LOOP OVER BLOCKS.
!           -----------------
   DO ig = 1, igl
      iunit = iuscr(ig)
!*    4.1.1.1 LOOP OVER WIND FIELDS.
!             ----------------------
      DO mm = 1, mstep
         READ(iunit, END=6200, IOSTAT=ios) idth, igg, (us(i,ig),i=1,niblo),&
                                           (ds(i, ig), i = 1, niblo)
         IF( idth .GE. idtwis ) WRITE(iuvelo, ERR=6300, IOSTAT=ios) idth, igg, &
                                    (us(i, ig), i = 1, niblo), (ds(i, ig), i = 1, niblo)
      ENDDO
   ENDDO
ENDDO
DO ig = 1, igl
   CLOSE(UNIT = iuscr(ig) , STATUS = 'DELETE')
ENDDO
CLOSE(UNIT = iuvelo, STATUS = 'KEEP')
IF( itest .GE. 3 ) THEN
   WRITE(iu06,*) '       SUB. TIMIN: LAST WIND FIELD AT ', 'IDTH= ', idth, &
                 ' WRITTEN TO OUTPUT UNIT'
ENDIF
RETURN
! ----------------------------------------------------------------------
!*    6. ERROR MESSAGES
6100 CONTINUE
WRITE(iu06,*) ' '
WRITE(iu06,*) ' ********************************************'
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' *       FATAL ERROR IN SUB. TIMIN:         *'
WRITE(iu06,*) ' *       ==========================         *'
WRITE(iu06,*) ' * ERROR WHEN WRITTING ON SCRATCH UNIT      *'
WRITE(iu06,*) ' * FOR BLOCK NUMBER        IG = ', ig
WRITE(iu06,*) ' * NUMBER OF WIND FIELD IS  N = ', n
WRITE(iu06,*) ' * DATE OF WIND FIELD IS IDTH = ', idth
WRITE(iu06,*) ' * MESSAGE IS             IOS = ', ios
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' * PROGRAM ABORTS    PROGRAM ABORTS         *'
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' ********************************************'
CALL ABORT
6200 CONTINUE
WRITE(iu06,*) ' '
WRITE(iu06,*) ' ********************************************'
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' *       FATAL ERROR IN SUB. TIMIN:         *'
WRITE(iu06,*) ' *       ==========================         *'
WRITE(iu06,*) ' * ERROR WHEN READING FROM SCRATCH UNIT     *'
WRITE(iu06,*) ' * FOR BLOCK NUMBER        IG = ', ig
WRITE(iu06,*) ' * DATE OF WIND FIELD IS IDTH = ', idth
WRITE(iu06,*) ' * MESSAGE IS             IOS = ', ios
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' * PROGRAM ABORTS    PROGRAM ABORTS         *'
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' ********************************************'
CALL ABORT
6300 CONTINUE
WRITE(iu06,*) ' '
WRITE(iu06,*) ' ********************************************'
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' *       FATAL ERROR IN SUB. TIMIN:         *'
WRITE(iu06,*) ' *       ==========================         *'
WRITE(iu06,*) ' * ERROR WHEN WRITTING ON WIND OUTPUT FILE  *'
WRITE(iu06,*) ' * FOR BLOCK NUMBER       IG  = ', ig
WRITE(iu06,*) ' * DATE OF WIND FIELD IS IDTH = ', idth
WRITE(iu06,*) ' * MESSAGE IS            IOS  = ', ios
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' * PROGRAM ABORTS    PROGRAM ABORTS         *'
WRITE(iu06,*) ' *                                          *'
WRITE(iu06,*) ' ********************************************'
CALL ABORT

#ifndef _OPENMP
CONTAINS
INTEGER FUNCTION omp_get_thread_num
omp_get_thread_num=0
END FUNCTION omp_get_thread_num
#endif

END SUBROUTINE timin
