
! local defines : (should be set by Makefile)
c#define  drive_tmngr

       module time_manager_module
c
c-------------------------------------------------------------------------
c      use this module as a time manager of a complete integration.
c      time derivatives could be written like:
c      h(::,taup1) = h(::,taum1) + c2dt* forcing(tau,taum1)
c
c      a typical main loop of a model could look like:
c
c       call init_time_manager(dt_in,runlen,snap_int,restart_stamp )
c 10    continue
c 20     call time_step_begin()
c        ... stuff to integrate the model ...
c        if (snapshot_time_step) diagnose the model
c        call time_step_end()
c        if (eulerback2) goto 20    ! do the second part of the euler backw. 
c       if (.not. eorun ) goto 10
c                                         aug 2001  c. eden
c-------------------------------------------------------------------------
c
       use time_type_module
       implicit none

       integer             :: mixing_freq = 17     ! freq. in time steps of 
                                                   ! mixing time steps
       character (len=80)  :: mixing_type = 'euler_backward' 
                     ! type of mixing time step
                     ! 'euler_backward' and 'euler_foreward' are implemented
                     ! note that euler_backward is more dissipative and
                     ! damps also spatial scales ...
       type( time_type )          :: initial_time    ! the initial time, for which
                                                     ! the model was started
       type( time_type )          :: current_time    ! the current model time
       type( time_type )          :: restart_time    ! the time of the last restart
       type( time_type )          :: stop_time       ! the time of the end of
                                                     ! the present integration
       type( time_type )          :: snapshot_time   ! the time for the next
                                                     ! snapshot to write
       type( time_type )          :: snapshot_inctime! the interval between 
                                                     ! snapshots
       integer          :: initial_year  = 1900      ! initial date
       integer          :: initial_month = 01
       integer          :: initial_day   = 01
       integer          :: initial_hour  = 00
       integer          :: initial_min   = 00
       integer          :: initial_sec   = 00
       real             :: dt,c2dt           ! time step in secs and 2*dt
                                             ! or 1*dt for an euler step
       integer          :: itt = 1           ! number of time steps
                                             ! in present integration
       integer          :: taum1=0,tau=1,taup1=2 ! pointer to data
                                                 ! which depends on time
           ! tau points to the present time step, taum1, taup1 to the
           ! previous and next time step. For an euler time step, taum1
           ! equals tau.
       integer,private  :: otaum1=0, intermediate ! pointer for eulerbackward
       character        :: current_stamp*32       ! current time stamp 
       logical          :: eulerback1= .false.    ! is this the first part of
                                                  ! an euler backward step?
       logical          :: eulerback2= .false.    ! is this the second part of
                                                  ! an euler backward step?
       logical          :: eulerfore = .false.    ! is this an euler foreward step?
       logical          :: end_of_run           = .false. ! is the end of run reached
       logical          :: last_time_step       = .false. ! is this the last time step
       logical          :: snapshot_time_step   = .false. ! write a snapshots?
       logical          :: end_of_year          = .false. ! end of year
       logical          :: end_of_season        = .false.
       logical          :: end_of_month         = .false.
       logical          :: end_of_day           = .false.
       logical          :: time_manager_verbose = .true.  ! be verbose
       logical          :: tmngr_initialized    = .false.
       logical   :: enable_mixing_time_steps = .true.
c
c      time interpolator stuff
c
       type forcing_time_type
         integer :: ntimes  
         logical :: periodical
         logical :: busy 
         type(time_type), pointer :: mid_points(:)
         type(time_type), pointer :: str_points(:)
         type(time_type), pointer :: end_points(:)
       end type
       integer, parameter :: max_forcings = 100
       integer :: nr_forcings = 0
       type( forcing_time_type ) :: forcing(max_forcings)

       contains

       subroutine init_time_manager(dt_in,runlen_in,snap_int_in,
     &                              restart_stamp_in,itt_in)
c
c-------------------------------------------------------------------------
c      initialze the whole time manager
c-------------------------------------------------------------------------
c 
       real, intent(in) :: dt_in    ! time step in seconds
       real, intent(in) :: runlen_in   ! length of run in days
       real, intent(in) :: snap_int_in ! snapshot interval in days
       character, intent(in) ::  restart_stamp_in*32
                                    ! year,months, etc of restart
       integer, intent(in) :: itt_in! counter of time steps
                                    ! of the restart
       type( time_type ):: time  
       integer :: n

      if (.not. tmngr_initialized ) then
         tmngr_initialized = .true.
         do n=1,max_forcings
           forcing(n)%busy=.false.
           forcing(n)%ntimes=0
         enddo
       endif

!      set the time step counter
       itt=itt_in

!      set the time steps
       dt=dt_in
       c2dt=2.*dt
       if (int(dt)*1. /= dt) then
         print*,' ERROR: use of timesteps with fractional seconds'
         call halt_stop(' in init_time_manager')
       endif

!      default calendar type to be used
       call set_calendar_type(no_leap)

!      set initial time
       initial_time = set_date(initial_year, initial_month, initial_day,
     &                         initial_hour, initial_min, initial_sec)

!      set restart time
       restart_time = get_stamp(restart_stamp_in)

!      update current time
       current_time = restart_time
       call set_stamp(current_stamp, current_time )

!      set end of integration
       call set_time ( time,
     &        nint( (runlen_in-int(runlen_in))*60*60*24 ), 
     &        int(runlen_in))
       stop_time = current_time + time 

!      set next snapshot time
       snapshot_time = initial_time

       call set_time(snapshot_inctime ,
     &        nint( (snap_int_in-int(snap_int_in))*60*60*24 ), 
     &        int(snap_int_in))

       if (snap_int_in>0.) then
 20     snapshot_time = snapshot_time + snapshot_inctime
        if (snapshot_time < current_time ) goto 20
       else
        snapshot_time=current_time
       endif

       if ( time_manager_verbose ) then
        print*,' '
        print*,' setting up the model integration for'
        print*,' ',runlen_in,' days, snapshot interval is ',
     &          snap_int_in,' days'
        print*,' time step will be ',dt,' seconds'
        print*,' '
       endif

       end subroutine init_time_manager

       subroutine disable_mixing_time_steps
       enable_mixing_time_steps = .false.
       end subroutine disable_mixing_time_steps

       subroutine time_step_begin()
c
c-------------------------------------------------------------------------
c      set up some things for each time step
c      use this before doing stuff in the present time step
c-------------------------------------------------------------------------
c
       type( time_type ):: time  

       if (mod(itt,mixing_freq) == 0 .and. 
     &            enable_mixing_time_steps) then ! start a mixing time step
c       if (mod(itt,mixing_freq) == 0) then ! start a mixing time step

         c2dt  = 1.0*dt

         if     (mixing_type == 'euler_backward') then

          if (eulerback2) then

           eulerback1 = .false. ! second part of euler backward step
           eulerback2 = .true.  ! second part of euler backward step
           eulerfore  = .false.
           c2dt  = 1.0*dt

          else

           eulerback1=.true. ! first part of euler backward step
           eulerback2=.false.
           eulerfore =.false.
           otaum1=taum1           ! we do not need this pointer, but remember it
           taum1=tau              ! set tau and taum1 to the same arrays
                                  ! and compute intermediate step in taup1
                                  ! see in time_step_end what happens next
          endif
         elseif (mixing_type == 'euler_foreward') then

          otaum1=taum1      ! remember that pointer which is not needed here
          taum1=tau         ! simple euler foreward step
          eulerback1=.false.
          eulerback2=.false.
          eulerfore =.true.

         else
          call halt_stop(' other mixing time steps than'//
     &                   ' euler backward and euler foreward'//
     &                   ' are not implemented so for ')
         endif

       else

         eulerfore =.false.
         eulerback1=.false.
         eulerback2=.false.
         c2dt  = 2.0*dt

       endif

c      is this the last time step ? 

       call set_time(time,nint(dt),0)
       if ( current_time + time >= stop_time) last_time_step = .true.
c      do nothing if this is the first part of an eulerbackward step
       if (eulerback1) last_time_step = .false.

c      is this a snapshot time step ?

       if ( current_time >= snapshot_time .and. .not. eulerback1  ) then 
        snapshot_time_step = .true.
        snapshot_time = snapshot_time + snapshot_inctime
        if (snapshot_time <= current_time) then
         snapshot_time = current_time
        endif
       else
        snapshot_time_step = .false.
       endif

       call set_time(time,nint(dt),0)
       time=current_time+time

c      is this the end of the year ?
       end_of_year= .false.
       if (get_year(time) /= get_year( current_time) )
     &     end_of_year = .true.
       if (eulerback1) end_of_year=.false.

c      is this the end of the season ?
       end_of_season= .false.
       if (get_season_of_year(time) /= get_season_of_year(current_time))
     &     end_of_season = .true.
       if (eulerback1) end_of_season=.false.

c      is this the end of the month ?
       end_of_month= .false.
       if (get_month_of_year(time) /= get_month_of_year(current_time))
     &     end_of_month = .true.
       if (eulerback1) end_of_month=.false.

c      is this the end of the day ?
       end_of_day= .false.
       if (get_day_of_month(time) /= get_day_of_month( current_time))
     &     end_of_day = .true.
       if (eulerback1) end_of_day=.false.

c      implement other switches here

       end subroutine time_step_begin



       subroutine time_step_end()
c
c-------------------------------------------------------------------------
c      increments all pointers and the time
c      use this after done all stuff in the present time step
c-------------------------------------------------------------------------
c

       if (eulerfore) then
c
c       end of an euler foreward step
c
        eulerback1=.false.
        eulerback2=.false.
        eulerfore =.false.
c        taum1=tau   ! was already set to this value
        tau=taup1
        taup1=otaum1
        call time_goes_by()

       elseif (eulerback1) then
c
c       end of the first part of an euler backward step
c
        eulerback1=.false.        ! start now the second part of the backward step
        eulerback2=.true.         ! start now the second part of the backward step
        eulerfore =.false.
        tau=taup1                 ! in taup1 the intermediate step was computed
                                  ! now compute the end result: taum1 
                                  ! stays the same and forcing at tau becomes now
                                  ! the intermediate result, forcing at taum1
                                  ! is still the tau from previous leapfrog step
        intermediate = taup1      ! we have to remember that pointer
        taup1=otaum1              ! store the end result of this step
                                  ! in the so far unused array

       elseif (eulerback2) then
c
c       end of the second part of an euler backward step
c
        eulerback1=.false.
        eulerback2=.false.
        eulerfore =.false.
        tau  =taup1               ! taum1 was unchanged during the backward step
                                  ! and still points to tau of the previous
                                  ! leapfrog step
        taup1=intermediate        ! store future results in an array which is not
                                  ! needed anymore.
        call time_goes_by()

       else
c
c       end of a leapfrog time step
c
        eulerback1=.false.
        eulerback2=.false.
        eulerfore =.false.

        otaum1=taum1
        taum1= tau
        tau  = taup1
        taup1= otaum1
        call time_goes_by()
       endif

       end subroutine time_step_end


       subroutine time_goes_by
c
c-------------------------------------------------------------------------
c      as times goes by
c-------------------------------------------------------------------------
c
       type( time_type ):: time  
       itt=itt+1
       call set_time(time,nint(dt),0)
       current_time = current_time + time 
       call set_stamp(current_stamp, current_time )
       if ( current_time >= stop_time) end_of_run = .true.
       end subroutine time_goes_by


       subroutine set_stamp (stamp, time)
c
c-------------------------------------------------------------------------
c      converts time to character string
c-------------------------------------------------------------------------
c
       implicit none
       type( time_type ), intent(in) :: time
       character, intent(out) :: stamp*32
c     author:       R.C. Pacanowski     e-mail=>  rcp@gfdl.gov
       integer year, month, day, hour, min, sec
       call get_date(time,year,month,day,hour,min,sec)
       if (year .le. 9999) then
         write (stamp,'(a6,i2,a1,i2,a1,i4,a8,i2,a1,i2,a1,i2)') 
     &                'm/d/y=',month,'/',day,'/'
     &,                year,', h:m:s=', hour,':', min,':', sec
       elseif (year .ge. 10000 .and. year .le. 99999) then
         write (stamp,'(a6,i2,a1,i2,a1,i5,a7,i2,a1,i2,a1,i2)')
     &            'm/d/y=',month,'/',day,'/'
     &,           year,',h:m:s=', hour,':', min,':', sec
       elseif (year .ge. 100000 .and. year .le. 999999) then
         write (stamp,'(a6,i2,a1,i2,a1,i6,a6,i2,a1,i2,a1,i2)')
     &            'm/d/y=',month,'/',day,'/'
     &,           year,'h:m:s=', hour,':',  min,':', sec
       else
         write (*,*) '=>Error: year=',year,',is too large in set_stamp.'
         call halt_stop(' in set_stamp')
       endif
       end subroutine set_stamp


       function get_stamp (stamp)
c
c-------------------------------------------------------------------------
c       converts character string to time type
c-------------------------------------------------------------------------
c
       implicit none
       type( time_type ) :: get_stamp
       character, intent(in) ::  stamp*32
       integer   year, month, day, hour, min, sec
       character skip6*6, skip7*7, skip8*8, skip1*1
c      author:       R.C. Pacanowski     e-mail=>  rcp@gfdl.gov
c
c      for years: 0..9999
       if (stamp(17:17) .eq. ',') then 
        read  (stamp, '(a6,i2,a1,i2,a1,i4,a8,i2,a1,i2,a1,i2)')
     &      skip6, month, skip1, day, skip1, year, skip8, hour
     &,     skip1, min, skip1, sec
c      for years:  10000..99999
       elseif (stamp(18:18) .eq. ',') then
        read  (stamp, '(a6,i2,a1,i2,a1,i5,a7,i2,a1,i2,a1,i2)')
     &      skip6, month, skip1, day, skip1, year, skip7, hour
     &,     skip1, min, skip1, sec
c      for years:  100000..999999
       elseif (stamp(19:19) .eq. 'h') then
        read  (stamp, '(a6,i2,a1,i2,a1,i6,a6,i2,a1,i2,a1,i2)')
     &      skip6, month, skip1, day, skip1, year, skip6, hour
     &,     skip1, min, skip1, sec
       else
        write (*,*) '=>Error: year is too large in get_stamp.'
        call halt_stop(' in get_stamp')
       endif
       get_stamp = set_date(year,month,day,hour,min,sec)
       end function get_stamp

       function get_current_time()
c-------------------------------------------------------------------------
c      get the current model time
c-------------------------------------------------------------------------
       type (time_type) :: get_current_time
       get_current_time = current_time
       end function get_current_time

       function get_stop_time()
c-------------------------------------------------------------------------
c      get the time of the en of run
c-------------------------------------------------------------------------
       type (time_type) :: get_stop_time
       get_stop_time = stop_time
       end function get_stop_time

       function get_itts_til_eorun()
c-------------------------------------------------------------------------
c      get number of time steps til end of run
c-------------------------------------------------------------------------
       integer :: get_itts_til_eorun
       type (time_type) :: time
       call set_time(time,nint(dt),0)
       get_itts_til_eorun=(stop_time - current_time)/time
       end function get_itts_til_eorun

       function get_initial_time()
c-------------------------------------------------------------------------
c      get the initial model time
c-------------------------------------------------------------------------
       type (time_type) :: get_initial_time
       get_initial_time = initial_time
       end function get_initial_time

       function get_month_of_year(time)
       integer get_month_of_year
       type (time_type) :: time
       integer year, month, day, hour, min, sec
       call get_date(time,year,month,day,hour,min,sec)
       get_month_of_year=month
       end function get_month_of_year

       function get_day_of_month(time)
       integer get_day_of_month
       type (time_type) :: time
       integer year, month, day, hour, min, sec
       call get_date(time,year,month,day,hour,min,sec)
       get_day_of_month = day
       end function get_day_of_month

       function get_season_of_year(time)
       integer get_season_of_year
       type (time_type) :: time
       integer year, month, day, hour, min, sec
       call get_date(time,year,month,day,hour,min,sec)
       if (month >=1 .and. month <= 3 ) get_season_of_year=1 ! J/F/M
       if (month >=4 .and. month <= 6 ) get_season_of_year=2 ! A/M/J
       if (month >=7 .and. month <= 9 ) get_season_of_year=3 ! J/A/S
       if (month >=10.and. month <= 12) get_season_of_year=4 ! O/N/D
       end function get_season_of_year

       function get_year(time)
       integer get_year
       type (time_type) :: time
       integer year, month, day, hour, min, sec
       call get_date(time,year,month,day,hour,min,sec)
       get_year=year
       end function get_year


       function get_day_of_year(time)
       real :: get_day_of_year
       type (time_type) :: time
       integer year, month, day, hour, min, sec
       call get_date(time,year,month,day,hour,min,sec)
       get_day_of_year = time_in_days(time - set_date(year,1,1,0,0,0) )
       end function get_day_of_year


       subroutine init_forcing_interp(nr,p,sp,interval,index)
c
c-------------------------------------------------------------------------
c      initialize forcing interpolation slots
c      input:
c      nr: number of time steps for the forcing data
c      p:  periodical data?
c      sp: start time of the averarging period of the 1. time step
c      interval : averaging periods for all time steps
c      output:
c      index: index of slot for further references
c-------------------------------------------------------------------------
c
       integer, intent(in) :: nr
       logical, intent(in) :: p
       type( time_type), intent(in) :: sp,interval(nr)
       integer, intent(out) :: index
       integer :: n
       character*32 s1

       if (time_manager_verbose) then
        print*,''
        print*,'Initializing time interpolation slot #',
     &            nr_forcings+1
        print*,'periodical : ',p
       endif

       nr_forcings=nr_forcings+1
       index = nr_forcings
       if (index > max_forcings) then
         print*, ' Number of slots for forcing interpolation ' 
         print*, ' exceeds max_forcings=',max_forcings
         call halt_stop(' in init_interp_forcing')
       endif

       if (p .and. get_calendar_type() == Julian ) then
        print*,''
        print*,' WARNING: '
        print*,' you are trying to use periodical forcing '
        print*,' and a calendar with leap year '
        print*,' that may result in wrong interpolations'
        print*,''
       endif

       forcing(index)%busy = .true.
       forcing(index)%ntimes = nr
       forcing(index)%periodical = p

       allocate( forcing(index)%mid_points(nr) )
       allocate( forcing(index)%str_points(nr) )
       allocate( forcing(index)%end_points(nr) )
       forcing(index)%str_points(1)=sp
       forcing(index)%end_points(1)=sp+interval(1)
       forcing(index)%mid_points(1)=sp+interval(1)/2
       do n=2,nr
        forcing(index)%str_points(n)=forcing(index)%end_points(n-1)
        forcing(index)%end_points(n)=forcing(index)%end_points(n-1)+
     &                               interval(n)
        forcing(index)%mid_points(n)=forcing(index)%str_points(n)+
     &                               interval(n)/2
       enddo     

       if (time_manager_verbose) then
        do n=1,nr
         call set_stamp(s1,forcing(index)%str_points(n))
         print*,'time step #',n,' starts at ',s1,' ave.period=',
     &     time_in_days(interval(n)),' days'
        enddo
        print*,'ok done'
        print*,''
       endif

       end subroutine init_forcing_interp


       subroutine forcing_interp(index,data1,data2,fac1,fac2)
c
c-------------------------------------------------------------------------
c      get indeeces to time steps in forcing data 
c      and interpolation factors, such that the current forcing
c      becomes   f_data(...,data1)*fac1+f_data(...,data2)*fac2
c-------------------------------------------------------------------------
c
       integer, intent(in) :: index 
       integer, intent(out) ::  data1,data2
       real, intent(out) ::  fac1,fac2
       type( time_type) ::  t1,t2,tcov
       integer n,nr

       if (.not.forcing(index)%busy) then
         print*,' ERROR: you are trying to access '
         print*,'   forcing interpolation with index ',index
         print*,'   which was not intialized yet '
         call halt_stop(' in forcing_inertp')
       endif

       nr = forcing(index)%ntimes 
       tcov=forcing(index)%end_points(nr)-forcing(index)%str_points(1)

       if ( forcing(index)%periodical ) then
c       shift all times by tcov if they do not fit into current_time
 10     if ( current_time > forcing(index)%end_points(nr) ) then
         do n=1,nr
          forcing(index)%mid_points(n)=forcing(index)%mid_points(n)+tcov
          forcing(index)%str_points(n)=forcing(index)%str_points(n)+tcov
          forcing(index)%end_points(n)=forcing(index)%end_points(n)+tcov
         enddo
         goto 10
        elseif ( current_time < forcing(index)%str_points(1) ) then
         do n=1,forcing(index)%ntimes
          forcing(index)%mid_points(n)=forcing(index)%mid_points(n)-tcov
          forcing(index)%str_points(n)=forcing(index)%str_points(n)-tcov
          forcing(index)%end_points(n)=forcing(index)%end_points(n)-tcov
         enddo
         goto 10
        endif
       endif

c      increment data2 til it is just greater than current_time
       data2=1
 20    if ( data2 <= nr ) then
        if (forcing(index)%mid_points(data2) < current_time ) then
         data2=data2+1
         go to 20
        endif
       endif

c      get the interpolation factors and data pointers
       if (data2 == 1) then
          if ( forcing(index)%periodical ) then
           data1=nr
           t1 = current_time-(forcing(index)%mid_points(data1)-tcov)
           t2 = forcing(index)%mid_points(data2) - current_time
           fac2=time_in_days(t1)/time_in_days(t1+t2)
           fac1=time_in_days(t2)/time_in_days(t1+t2)
          else
           data1=1
           fac1=0.
           fac2=1.
          endif
       elseif (data2 <= nr ) then
          data1=data2-1
          t1 = current_time - forcing(index)%mid_points(data1)
          t2 = forcing(index)%mid_points(data2) - current_time
          fac2=time_in_days(t1)/time_in_days(t1+t2)
          fac1=time_in_days(t2)/time_in_days(t1+t2)
       else
          if ( forcing(index)%periodical ) then
           data2=1
           data1=nr
           t1 = current_time - forcing(index)%mid_points(data1)
           t2 = forcing(index)%mid_points(data2)+tcov - current_time
           fac2=time_in_days(t1)/time_in_days(t1+t2)
           fac1=time_in_days(t2)/time_in_days(t1+t2)
          else
           data1 = nr
           data2 = nr
           fac1=0.
           fac2=1.
          endif
       endif
       end subroutine forcing_interp


       subroutine get_forcing_interp_stamps(index,p,ss,se,sm)
c
c-------------------------------------------------------------------------
c      returns the start, end and mid time in stamps for
c      the interpolation slot index for time step p
c-------------------------------------------------------------------------
c
       integer, intent(in) :: index,p
       character, intent(out) :: ss*32
       character, intent(out),optional :: se*32
       character, intent(out),optional :: sm*32

       if (.not.forcing(index)%busy) then
         print*,' ERROR: you are trying to access '
         print*,'   forcing interpolation with index ',index
         print*,'   which was not intialized yet '
         call halt_stop(' in get_forcing_inertp_stamps')
       endif

       call set_stamp(ss,forcing(index)%str_points(p))
       if (present(se)) call set_stamp(se,forcing(index)%end_points(p))
       if (present(sm)) call set_stamp(sm,forcing(index)%mid_points(p))

       end subroutine get_forcing_interp_stamps



       subroutine update_forcing_cache(index,p1,p2,pointer,load,tname)
c
c-------------------------------------------------------------------------
c      translate time steps p1 and p2 in forcing data set 
c      forcing(:,p1) and forcing(:,p2) to
c      positions of a cache for the forcing such that 
c      cache(:,p1)=forcing(:,pointer(p1)) and 
c      cache(:,p2)=forcing(:,pointer(p2))
c      (p1 and p2 will be changed on output)
c      logical load(2) is true if forcing data has to be load
c      into the cache , which is not done here.
c      After loading the cache the forcing for the current model time step
c      becomes cache(:,p1)*fac1+cache(:,p2)*fac2, the factors
c      has to be determined with subr. forcing_interp
c-------------------------------------------------------------------------
c
       implicit none
       integer :: pointer(2),index
       integer :: p1,p2,ipos1,ipos2
       logical :: load(2)
       character(len=32) :: ss,se,sm,tname

       if (p1 /= pointer(1) .and. p1 /= pointer(2) ) then
        ipos1=1; if (p2 == pointer(1) ) ipos1=2
        pointer(ipos1) = p1
        load(ipos1) = .true.
       else
        if (p1 == pointer(1)) ipos1=1
        if (p1 == pointer(2)) ipos1=2
        load(ipos1) = .false.
       endif

       if (p2 /= pointer(1) .and. p2 /= pointer(2) ) then
        ipos2=1; if (p1 == pointer(1) ) ipos2=2
        pointer(ipos2) = p2
        load(ipos2) = .true.
       else
        if (p2 == pointer(1)) ipos2=1
        if (p2 == pointer(2)) ipos2=2
        load(ipos2) = .false.
       endif

       if (load(ipos1).and. time_manager_verbose ) then 
        call get_forcing_interp_stamps(index,p1,ss,se,sm)
        print*,' reading data for ',tname,' for time step #',p1,
     &          ' to cache position',ipos1
        print*,' time step #',p1,' begins at ',ss
        print*,' time step #',p1,' ends at   ',se
        print*,' time step #',p1,' middle at ',sm
       endif

       if (load(ipos2).and. time_manager_verbose ) then 
        call get_forcing_interp_stamps(index,p2,ss,se,sm)
        print*,' reading data for ',tname,' for time step #',p2,
     &          ' to cache position',ipos2
        print*,' time step #',p2,' begins at ',ss
        print*,' time step #',p2,' ends at   ',se
        print*,' time step #',p2,' middle at ',sm
       endif

       p1=ipos1; p2=ipos2
       end subroutine update_forcing_cache

       end module time_manager_module


#ifdef drive_tmngr
c
c      test the time manager here
c
       subroutine halt_stop(s)
       character (len=*) :: s
       print*,s
       stop
       end subroutine halt_stop

       program test_tmngr
       use time_manager_module
       implicit none
       real :: dt_in=1200., runlen=0.25, snap_int=0.0
       character (len=32) :: 
     &      stamp ='m/d/y= 1/ 1/1900, h:m:s= 0: 0: 0' 
       type( time_type) :: start,interval(12)
       integer :: p1,p2,pointer(2),index
       real    :: f1,f2
       character(len=80) :: text = 'test data set'
       logical load(2)

       time_manager_verbose=.true.  ! be verbose
       call init_time_manager(dt_in,runlen,snap_int,stamp,1 )

       start= get_stamp(stamp)
       interval(:)%days=365
       interval(:)%seconds=0
       call init_forcing_interp(2,.true.,start,interval,index)

  20   continue
      
        call time_step_begin()
        print*,'date: ',current_stamp,' itt=',itt
c        print*,'taum1=',taum1,' tau=',tau,' taup1=',taup1,eulerback1
        if (snapshot_time_step) print*,' writing a snapshot'

        call forcing_interp(index,p1,p2,f1,f2)
        call update_forcing_cache(index,p1,p2,pointer,load,text)

        print*,''
        print*,' data in cache at pos #1 point to data(',pointer(1),')'
        if (load(1)) print*,' data has to be loaded to cache pos #1'
        print*,' data in cache at pos #2 point to data(',pointer(2),')'
        if (load(2)) print*,' data has to be loaded to cache pos #1'
        print*,' interpolated data for this time step:'
        print*,' cache pos #',p1,'*',f1,'+ cache pos #',p2,'*',f2
        print*,'  = data(',pointer(p1),')*',f1,
     &         '+ data(',pointer(p2),')*',f2
        print*,''

        call time_step_end()

       if (.not. end_of_run ) goto 20

       end program test_tmngr

#endif
