LCOV - code coverage report
Current view: top level - chemistry/utils - input_data_utils.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 115 261 44.1 %
Date: 2024-12-17 17:57:11 Functions: 7 12 58.3 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! module where input data utility classes reside
       3             : !
       4             : ! classes:
       5             : !     time_coordinate -- manages the time coordinate of input data sets
       6             : !--------------------------------------------------------------------------------
       7             : module input_data_utils
       8             :   use shr_kind_mod,   only : r8 => shr_kind_r8, cs => shr_kind_cs, cl=> shr_kind_cl
       9             :   use cam_abortutils, only : endrun
      10             :   use cam_logfile,    only : iulog
      11             :   use pio,            only : file_desc_t, pio_inq_dimid, pio_inq_dimlen, pio_get_att
      12             :   use pio,            only : pio_seterrorhandling, pio_get_var, pio_inq_varid
      13             :   use pio,            only : PIO_NOWRITE, PIO_BCAST_ERROR, PIO_INTERNAL_ERROR, PIO_NOERR
      14             :   use time_manager,   only : timemgr_get_calendar_cf, set_time_float_from_date, get_curr_date
      15             :   use spmd_utils,     only : masterproc
      16             : 
      17             :   implicit none
      18             : 
      19             :   private
      20             :   public :: time_coordinate
      21             : 
      22             :   type :: time_coordinate
      23             :      integer :: ntimes
      24             :      real(r8) :: wghts(2)
      25             :      integer :: indxs(2)
      26             :      real(r8), allocatable :: times(:)
      27             :      real(r8), allocatable :: time_bnds(:,:)
      28             :      logical :: time_interp = .true.
      29             :      logical :: fixed = .false.
      30             :      integer :: fixed_ymd, fixed_tod
      31             :      character(len=cl) :: filename
      32             :      real(r8) :: dtime ! time shift in interpolation point (days)
      33             :    contains
      34             :      procedure :: initialize
      35             :      procedure :: advance
      36             :      procedure :: read_more
      37             :      procedure :: times_check
      38             :      procedure :: copy
      39             :      procedure :: destroy
      40             :   end type time_coordinate
      41             : 
      42             : contains
      43             : 
      44             :   !-----------------------------------------------------------------------------
      45             :   ! initializer
      46             :   !-----------------------------------------------------------------------------
      47        1536 :   subroutine initialize( this, filepath, fixed, fixed_ymd, fixed_tod, force_time_interp, set_weights, try_dates, delta_days )
      48             :     use ioFileMod,      only : getfil
      49             :     use cam_pio_utils,  only : cam_pio_openfile, cam_pio_closefile
      50             :     use string_utils,   only : to_upper
      51             :     use shr_const_mod,  only : SHR_CONST_CDAY
      52             : 
      53             :     class(time_coordinate), intent(inout) :: this
      54             :     character(len=*), intent(in) :: filepath
      55             :     logical, optional,intent(in) :: fixed
      56             :     integer, optional,intent(in) :: fixed_ymd
      57             :     integer, optional,intent(in) :: fixed_tod
      58             :     logical, optional,intent(in) :: force_time_interp
      59             :     logical, optional,intent(in) :: set_weights
      60             :     logical, optional,intent(in) :: try_dates
      61             :     real(r8), optional,intent(in) :: delta_days !  time shift in interpolation point (days) -- for previous day set this to -1.
      62             : 
      63             :     character(len=cl) :: filen
      64             :     character(len=cl) :: time_units, err_str
      65             :     character(len=cs) :: time_calendar, model_calendar
      66             :     character(len=4) :: yr_str
      67             :     character(len=2) :: mon_str, day_str, hr_str, min_str, sec_str
      68             :     integer :: ref_yr, ref_mon, ref_day, ref_hr, ref_min, ref_sec, tod
      69             :     integer :: varid, ierr
      70             :     real(r8) :: ref_time
      71             : 
      72        1536 :     integer,  allocatable :: dates(:)
      73        1536 :     integer,  allocatable :: datesecs(:)
      74        1536 :     integer,  allocatable :: year(:)
      75        1536 :     integer,  allocatable :: month(:)
      76        1536 :     integer,  allocatable :: day(:)
      77        1536 :     real(r8),  allocatable :: ut(:)
      78             : 
      79        1536 :     real(r8), allocatable :: times_file(:)
      80        1536 :     real(r8), allocatable :: times_modl(:)
      81        1536 :     real(r8), allocatable :: time_bnds_file(:,:)
      82             :     type(file_desc_t) :: fileid
      83             :     logical :: force_interp, time_in_secs
      84             :     logical :: set_wghts
      85             :     logical :: use_time, adj_times, use_time_bnds
      86             :     integer :: i, yri, moni, dayi, hri, mini, seci
      87             :     integer :: err_handling
      88             : 
      89             :     character(len=*), parameter :: prefix = 'time_coordinate%initialize: '
      90             : 
      91        1536 :     if (present(fixed)) this%fixed = fixed
      92        1536 :     if (present(fixed_ymd)) this%fixed_ymd = fixed_ymd
      93        1536 :     if (present(fixed_tod)) this%fixed_tod = fixed_tod
      94             : 
      95        1536 :     this%dtime = 0._r8
      96        1536 :     if (present(delta_days)) this%dtime = delta_days
      97             : 
      98        1536 :     if (present(force_time_interp)) then
      99        1536 :        force_interp = force_time_interp
     100             :     else
     101             :        force_interp = .false.
     102             :     endif
     103             : 
     104        1536 :     if (present(set_weights)) then
     105           0 :        set_wghts = set_weights
     106             :     else
     107             :        set_wghts = .true.
     108             :     endif
     109             : 
     110        1536 :     this%filename = trim(filepath)
     111             : 
     112        1536 :     call getfil( filepath, filen, 0 )
     113        1536 :     call cam_pio_openfile( fileid, filen, PIO_NOWRITE )
     114             : 
     115        1536 :     call pio_seterrorhandling( fileid, PIO_BCAST_ERROR, oldmethod=err_handling )
     116             : 
     117        1536 :     call get_dimension( fileid, 'time', this%ntimes )
     118        4608 :     allocate ( times_file( this%ntimes ) )
     119        4608 :     allocate ( times_modl( this%ntimes ) )
     120        4608 :     allocate ( this%times( this%ntimes ) )
     121             : 
     122        1536 :     ierr =  pio_inq_varid( fileid, 'time', varid )
     123        1536 :     use_time = ierr.eq.PIO_NOERR
     124        1536 :     ierr = pio_get_att( fileid, varid, 'calendar', time_calendar)
     125        1536 :     use_time = ierr.eq.PIO_NOERR .and. use_time
     126        1536 :     ierr = pio_get_att( fileid, varid, 'units', time_units)
     127        1536 :     use_time = ierr.eq.PIO_NOERR .and. use_time
     128        1536 :     if (use_time) then
     129             :        use_time = time_units(1:10) == 'days since' .or. &
     130        1536 :                   time_units(1:13) == 'seconds since'
     131             :     endif
     132             : 
     133        1536 :     if (present(try_dates)) then
     134        1536 :        if (try_dates) then
     135        1536 :           ierr = pio_inq_varid( fileid, 'date', varid  )
     136        1536 :           use_time = ierr .ne. PIO_NOERR
     137             :        endif
     138             :     endif
     139             : 
     140        1536 :     adj_times = .false.
     141        1536 :     use_time_bnds =  .false.
     142             : 
     143        1536 :     time_var_use: if (use_time) then
     144             : 
     145             :        ! check the calendar attribute - must match model calendar
     146           0 :        model_calendar = timemgr_get_calendar_cf()
     147             : 
     148           0 :        if (this%ntimes>2) then
     149             :           ! if only 2 time records then it is assumed that the input has 2 identical time records
     150             :           !  -- climatological or solar-cycle avaraged
     151             : 
     152           0 :           adj_times = (to_upper(time_calendar(1:6)) .ne. to_upper(model_calendar(1:6)))
     153             : 
     154           0 :           if (adj_times .and. masterproc) then
     155             :              write(iulog,*) prefix//'model calendar '//trim(model_calendar)// &
     156           0 :                             ' does not match input data calendar '//trim(time_calendar)
     157           0 :              write(iulog,*) ' -- will try to use date and datesec in the input file to adjust the time coordinate.'
     158             :           end if
     159             :        end if
     160             : 
     161           0 :        time_in_secs = .false.
     162             : 
     163           0 :        if (index( time_units, 'days since') > 0) then
     164             :           !  time:units = "days since YYYY-MM-DD hh:mm:ss"
     165             :           !                1234567890123456789012345678901234567890
     166             :           !                         1         2         3
     167             :           yri = 12
     168             :           moni = 17
     169             :           dayi = 20
     170             :           hri = 23
     171             :           mini = 26
     172             :           seci = 29
     173           0 :        else if(index( time_units, 'seconds since') > 0) then
     174             :           !  time:units = "seconds since YYYY-MM-DD hh:mm:ss"
     175             :           !                1234567890123456789012345678901234567890
     176             :           !                         1         2         3
     177             :           yri = 15
     178             :           moni = 20
     179             :           dayi = 23
     180             :           hri = 26
     181             :           mini = 29
     182             :           seci = 32
     183             :           time_in_secs = .true.
     184             :        else
     185           0 :           call endrun('time units not recognized')
     186             :        end if
     187             : 
     188             : 
     189             :        ! parse out ref date and time
     190             : 
     191           0 :        yr_str  = time_units(yri:yri+3)
     192           0 :        mon_str = time_units(moni:moni+1)
     193           0 :        day_str = time_units(dayi:dayi+1)
     194           0 :        hr_str  = time_units(hri:hri+1)
     195           0 :        min_str = time_units(mini:mini+1)
     196             : 
     197           0 :        read( yr_str,  * ) ref_yr
     198           0 :        read( mon_str, * ) ref_mon
     199           0 :        read( day_str, * ) ref_day
     200           0 :        read( hr_str,  * ) ref_hr
     201           0 :        read( min_str, * ) ref_min
     202           0 :        if (len_trim(time_units)>seci) then
     203           0 :           sec_str = time_units(seci:seci+1)
     204           0 :           read( sec_str, * ) ref_sec
     205             :        else
     206           0 :           ref_sec = 0
     207             :        endif
     208             : 
     209           0 :        tod = ref_hr*3600 + ref_min*60 + ref_sec
     210           0 :        call set_time_float_from_date( ref_time, ref_yr, ref_mon, ref_day, tod )
     211             : 
     212           0 :        ierr = pio_get_var( fileid, varid, times_file )
     213           0 :        if (time_in_secs) then
     214           0 :           times_file = times_file/SHR_CONST_CDAY
     215             :        endif
     216             : 
     217           0 :        if (ierr.ne.PIO_NOERR) then
     218           0 :           call endrun(prefix//'not able to read times')
     219             :        endif
     220             : 
     221           0 :        times_file = times_file + ref_time
     222             : 
     223           0 :        ierr =  pio_inq_varid( fileid, 'time_bnds', varid )
     224             : 
     225           0 :        use_time_bnds = (ierr==PIO_NOERR .and. .not.force_interp)
     226             : 
     227           0 :        if (use_time_bnds) then
     228           0 :           allocate ( this%time_bnds( 2, this%ntimes ) )
     229           0 :           allocate ( time_bnds_file( 2, this%ntimes ) )
     230           0 :           ierr =  pio_get_var( fileid, varid, time_bnds_file )
     231           0 :           time_bnds_file = time_bnds_file + ref_time
     232           0 :           this%time_interp = .false.
     233           0 :           do i = 1,this%ntimes
     234           0 :             if (.not. (time_bnds_file(1,i)<times_file(i) &
     235           0 :                  .and. time_bnds_file(2,i)>times_file(i)) ) then
     236           0 :                 write(err_str,*) 'incorrect time_bnds -- time index: ',i,' file: '//trim(filepath)
     237           0 :                 call endrun(err_str)
     238             :             endif
     239             :           enddo
     240             :        else
     241           0 :           this%time_interp = .true.
     242             :        endif
     243             :     else
     244        1536 :        this%time_interp = .true.
     245             :     endif time_var_use
     246             : 
     247        1536 :     read_dates: if (adj_times .or. .not.use_time) then
     248             : 
     249             :        ! try using date and datesec
     250        4608 :        allocate(dates(this%ntimes), stat=ierr )
     251        1536 :        if( ierr /= 0 ) then
     252           0 :           write(iulog,*) prefix//'failed to allocate dates; error = ',ierr
     253           0 :           call endrun(prefix//'failed to allocate dates')
     254             :        end if
     255             : 
     256        4608 :        allocate(datesecs(this%ntimes), stat=ierr )
     257        1536 :        if( ierr /= 0 ) then
     258           0 :           write(iulog,*) prefix//'failed to allocate datesecs; error = ',ierr
     259           0 :           call endrun(prefix//'failed to allocate datesecs')
     260             :        end if
     261             : 
     262        1536 :        ierr = pio_inq_varid( fileid, 'date', varid )
     263        1536 :        if (ierr==PIO_NOERR) then
     264        1536 :           ierr = pio_get_var( fileid, varid, dates )
     265        1536 :           if (ierr/=PIO_NOERR) then
     266           0 :              call endrun(prefix//' error reading date in '//trim(filepath))
     267             :           endif
     268             :        else
     269             :           ! try year, month, day
     270           0 :           allocate(year(this%ntimes), stat=ierr )
     271           0 :           if (ierr/=0) then
     272           0 :              call endrun(prefix//'issue with allocation of year array')
     273             :           endif
     274           0 :           allocate(month(this%ntimes), stat=ierr )
     275           0 :           if (ierr/=0) then
     276           0 :              call endrun(prefix//'issue with allocation of month array')
     277             :           endif
     278           0 :           allocate(day(this%ntimes), stat=ierr )
     279           0 :           if (ierr/=0) then
     280           0 :              call endrun(prefix//'issue with allocation of day array')
     281             :           endif
     282             : 
     283           0 :           ierr = pio_inq_varid( fileid, 'year', varid )
     284           0 :           if (ierr/=PIO_NOERR) then
     285           0 :              call endrun(prefix//' error inquiring year var in '//trim(filepath))
     286             :           endif
     287           0 :           ierr = pio_get_var( fileid, varid, year )
     288           0 :           if (ierr/=PIO_NOERR) then
     289           0 :              call endrun(prefix//' error reading year in '//trim(filepath))
     290             :           endif
     291             : 
     292           0 :           ierr = pio_inq_varid( fileid, 'month', varid  )
     293           0 :           if (ierr/=PIO_NOERR) then
     294           0 :              call endrun(prefix//' error inquiring month var in '//trim(filepath))
     295             :           endif
     296           0 :           ierr = pio_get_var( fileid, varid, month )
     297           0 :           if (ierr/=PIO_NOERR) then
     298           0 :              call endrun(prefix//' error reading month in '//trim(filepath))
     299             :           endif
     300             : 
     301           0 :           ierr = pio_inq_varid( fileid, 'day', varid  )
     302           0 :           if (ierr/=PIO_NOERR) then
     303           0 :              call endrun(prefix//' error inquiring day var in '//trim(filepath))
     304             :           endif
     305           0 :           ierr = pio_get_var( fileid, varid, day )
     306           0 :           if (ierr/=PIO_NOERR) then
     307           0 :              call endrun(prefix//' error reading day in '//trim(filepath))
     308             :           endif
     309             : 
     310           0 :           dates(:) = year(:)*10000 + month(:)*100 + day(:)
     311             : 
     312           0 :           deallocate(year,month,day)
     313             :        endif
     314        1536 :        ierr = pio_inq_varid( fileid, 'datesec', varid )
     315        1536 :        if (ierr==PIO_NOERR) then
     316        1536 :           ierr = pio_get_var( fileid, varid, datesecs )
     317        1536 :           if (ierr/=PIO_NOERR) then
     318           0 :              call endrun(prefix//' error reading datesec in '//trim(filepath))
     319             :           endif
     320             :        else
     321             :           ! try ut
     322             : 
     323           0 :           allocate(ut(this%ntimes), stat=ierr )
     324           0 :           ierr = pio_inq_varid( fileid, 'ut', varid ) ! fractional hours
     325           0 :           if (ierr==PIO_NOERR) then
     326           0 :              ierr = pio_get_var( fileid, varid, ut )
     327           0 :              if (ierr/=PIO_NOERR) then
     328           0 :                 call endrun(prefix//' error reading ut in '//trim(filepath))
     329             :              endif
     330           0 :              datesecs = int(3600._r8*ut) ! hours -> secs
     331             :           else
     332           0 :              datesecs(:) = 0
     333             :           endif
     334           0 :           deallocate(ut)
     335             :        endif
     336             : 
     337        1536 :        call convert_dates( dates, datesecs, times_modl )
     338             : 
     339        1536 :        deallocate( dates, datesecs )
     340             : 
     341             :     endif read_dates
     342             : 
     343        1536 :     if (adj_times) then
     344             :        ! time_bnds_modl - time_bnds_file = times_modl - times_file
     345             :        ! time_bnds_modl = time_bnds_file + times_modl - times_file
     346           0 :        this%times(:) = times_modl(:)
     347           0 :        if (use_time_bnds) then
     348           0 :           this%time_bnds(1,:) = time_bnds_file(1,:) + times_modl(:) - times_file(:)
     349           0 :           this%time_bnds(2,:) = time_bnds_file(2,:) + times_modl(:) - times_file(:)
     350             :        endif
     351        1536 :     else if (use_time) then
     352           0 :        this%times(:) = times_file(:)
     353           0 :        if (use_time_bnds) then
     354           0 :           this%time_bnds(1,:) = time_bnds_file(1,:)
     355           0 :           this%time_bnds(2,:) = time_bnds_file(2,:)
     356             :        endif
     357             :     else
     358   252463104 :        this%times(:) = times_modl(:)
     359             :     endif
     360             : 
     361        1536 :     deallocate( times_modl, times_file )
     362        1536 :     if (use_time_bnds) deallocate(time_bnds_file)
     363             : 
     364        1536 :     call pio_seterrorhandling( fileid, err_handling )
     365             : 
     366        1536 :     call cam_pio_closefile(fileid)
     367             : 
     368        1536 :     this%indxs(1)=1
     369        1536 :     if (set_wghts) call set_wghts_indices(this)
     370             : 
     371        3072 :   end subroutine initialize
     372             : 
     373             :   !-----------------------------------------------------------------------------
     374             :   ! advance the time coordinate
     375             :   !-----------------------------------------------------------------------------
     376      372480 :   subroutine advance( this )
     377             :     class(time_coordinate) :: this
     378             : 
     379      372480 :     if (.not.this%fixed) call set_wghts_indices(this)
     380             : 
     381        1536 :   end subroutine advance
     382             : 
     383             :   !-----------------------------------------------------------------------------
     384             :   ! determine if need to read more data from input data set
     385             :   !-----------------------------------------------------------------------------
     386      372480 :   function read_more(this) result(check)
     387             :     class(time_coordinate), intent(in) :: this
     388             :     logical :: check
     389             : 
     390             :     real(r8) :: model_time
     391             : 
     392      372480 :     model_time = get_model_time() + this%dtime
     393             : 
     394      372480 :     if (.not.this%fixed) then
     395      372480 :        if (allocated(this%time_bnds)) then
     396           0 :           check = model_time > this%time_bnds(2,this%indxs(1))
     397             :        else
     398      372480 :           check = model_time > this%times(this%indxs(2))
     399             :        endif
     400             :     else
     401             :        check = .false.
     402             :     endif
     403             : 
     404      372480 :   end function read_more
     405             : 
     406             :   !-----------------------------------------------------------------------------
     407             :   ! times_check -- returns timing status indicator
     408             :   !  -1 : current model time is before the data times
     409             :   !   0 : current model time is within the data times
     410             :   !   1 : current model time is after the data times
     411             :   !-----------------------------------------------------------------------------
     412           0 :   integer function times_check(this)
     413             :     class(time_coordinate), intent(in) :: this
     414             : 
     415             :     real(r8) :: model_time
     416             : 
     417           0 :     model_time = get_model_time()
     418             : 
     419           0 :     times_check = 0
     420           0 :     if (model_time<this%times(1)) then
     421             :        times_check = -1
     422           0 :     else if (model_time>this%times(this%ntimes)) then
     423           0 :        times_check = 1
     424             :     end if
     425             : 
     426           0 :   end function times_check
     427             : 
     428             :   !-----------------------------------------------------------------------------
     429             :   ! destroy method -- deallocate memory and revert to default settings
     430             :   !-----------------------------------------------------------------------------
     431           0 :   subroutine destroy( this )
     432             :         class(time_coordinate), intent(inout) :: this
     433             : 
     434           0 :     if (allocated(this%times)) deallocate(this%times)
     435           0 :     if (allocated(this%time_bnds)) deallocate(this%time_bnds)
     436           0 :     this%ntimes = 0
     437           0 :     this%filename='NONE'
     438             : 
     439           0 :   end subroutine destroy
     440             : 
     441             :   !-----------------------------------------------------------------------------
     442             :   ! produce a duplicate time coordinate object
     443             :   !-----------------------------------------------------------------------------
     444           0 :   subroutine copy( this, obj )
     445             :     class(time_coordinate), intent(inout) :: this
     446             :     class(time_coordinate), intent(in) :: obj
     447             : 
     448           0 :     call this%destroy()
     449             : 
     450           0 :     this%ntimes = obj%ntimes
     451           0 :     this%fixed  = obj%fixed
     452           0 :     this%fixed_ymd = obj%fixed_ymd
     453           0 :     this%fixed_tod = obj%fixed_tod
     454             : 
     455           0 :     allocate ( this%times( this%ntimes ) )
     456           0 :     this%times = obj%times
     457             : 
     458           0 :     if (allocated( obj%time_bnds )) then
     459           0 :        allocate ( this%time_bnds( 2, this%ntimes ) )
     460           0 :        this%time_bnds = obj%time_bnds
     461             :     endif
     462           0 :     this%filename = obj%filename
     463             : 
     464           0 :   end subroutine copy
     465             : 
     466             : ! private methods
     467             : 
     468             :   !-----------------------------------------------------------------------
     469             :   ! set time interpolation weights
     470             :   !-----------------------------------------------------------------------
     471      374016 :   subroutine set_wghts_indices(obj)
     472             : 
     473             :     class(time_coordinate), intent(inout) :: obj
     474             : 
     475             :     real(r8) :: model_time
     476             :     real(r8) :: datatm, datatp
     477             :     integer :: yr, mon, day
     478             :     integer :: index, i
     479             :     character(len=cl) :: errmsg
     480             : 
     481             :     ! set time indices and time-interpolation weights
     482      374016 :     fixed_time: if (obj%fixed) then
     483           0 :        yr = obj%fixed_ymd/10000
     484           0 :        mon = (obj%fixed_ymd-yr*10000) / 100
     485           0 :        day = obj%fixed_ymd-yr*10000-mon*100
     486           0 :        call set_time_float_from_date( model_time, yr, mon, day, obj%fixed_tod )
     487           0 :        model_time = model_time + obj%dtime
     488             :     else
     489      374016 :        model_time = get_model_time() + obj%dtime
     490             :     endif fixed_time
     491             : 
     492      374016 :     index = -1
     493             : 
     494    72757248 :     findtimes: do i = obj%indxs(1), obj%ntimes
     495    72757248 :        if (allocated(obj%time_bnds)) then
     496           0 :           datatm = obj%time_bnds(1,i)
     497           0 :           datatp = obj%time_bnds(2,i)
     498             :        else
     499    72757248 :           if (i .ge. obj%ntimes) then
     500             :              errmsg = 'input_data_utils::set_wghts_indices cannot not find model time in: '&
     501           0 :                     // trim(obj%filename)
     502           0 :              write(iulog,*) trim(errmsg)
     503           0 :              call endrun(trim(errmsg))
     504             :           endif
     505    72757248 :           datatm = obj%times(i)
     506    72757248 :           datatp = obj%times(i+1)
     507             :        endif
     508    72757248 :        if ( model_time .lt. datatm ) then
     509             :           errmsg = 'input_data_utils::set_wghts_indices cannot not find model time in: '&
     510           0 :                  // trim(obj%filename)
     511           0 :           write(iulog,*) trim(errmsg)
     512           0 :           call endrun(trim(errmsg))
     513             :        endif
     514    72757248 :        if ( model_time .ge. datatm .and. model_time .le. datatp ) then
     515      374016 :           index = i
     516      374016 :           obj%indxs(1) = i
     517      374016 :           obj%indxs(2) = i+1
     518      374016 :           exit findtimes
     519             :        endif
     520             :     enddo findtimes
     521             : 
     522      374016 :     if ((allocated(obj%time_bnds)) .and. (i<obj%ntimes)) then
     523           0 :        if (.not.(obj%time_bnds(1,i+1) > obj%time_bnds(1,i))) then
     524           0 :           obj%indxs = obj%indxs+1  ! skip 29 Feb when calendar is noleap
     525             :        endif
     526             :     endif
     527             : 
     528      374016 :     if (.not.(index>0.and.index<=obj%ntimes)) then
     529             :        errmsg = 'input_data_utils::set_wghts_indices cannot not find time indices for input file: '&
     530           0 :             // trim(obj%filename)
     531           0 :        write(iulog,*) trim(errmsg)
     532           0 :        call endrun(trim(errmsg))
     533             :     endif
     534             : 
     535      374016 :     if (obj%time_interp) then
     536      374016 :        obj%wghts(2) = ( model_time - obj%times(index) ) / ( obj%times(index+1) - obj%times(index) )
     537      374016 :        obj%wghts(1) = 1._r8 - obj%wghts(2)
     538             :     else
     539           0 :        obj%wghts(1) = 1._r8
     540           0 :        obj%wghts(2) = 0._r8
     541             :     endif
     542             : 
     543      374016 :   end subroutine set_wghts_indices
     544             : 
     545             :   !-----------------------------------------------------------------------
     546             :   ! returns dimension size
     547             :   !-----------------------------------------------------------------------
     548        1536 :   subroutine get_dimension( fid, dname, dsize )
     549             :     type(file_desc_t), intent(in) :: fid
     550             :     character(*), intent(in) :: dname
     551             :     integer, intent(out) :: dsize
     552             : 
     553             :     integer :: dimid, ierr
     554             : 
     555        1536 :     ierr = pio_inq_dimid( fid, dname, dimid )
     556        1536 :     ierr = pio_inq_dimlen( fid, dimid, dsize )
     557             : 
     558        1536 :   end subroutine get_dimension
     559             : 
     560             :   !-----------------------------------------------------------------------
     561             :   ! returns a real which represents the current model time
     562             :   !-----------------------------------------------------------------------
     563     1492992 :   function get_model_time() result(time)
     564             : 
     565             :     real(r8) :: time
     566             : 
     567             :     integer yr, mon, day, ncsec  ! components of a date
     568             : 
     569      746496 :     call get_curr_date(yr, mon, day, ncsec)
     570             : 
     571      746496 :     call set_time_float_from_date( time, yr, mon, day, ncsec )
     572             : 
     573      746496 :   end function get_model_time
     574             : 
     575             :   !---------------------------------------------------------------------------
     576             :   ! convert a collection of dates and times to reals
     577             :   !---------------------------------------------------------------------------
     578        1536 :   subroutine convert_dates( dates, secs, times )
     579             : 
     580             :     use time_manager, only: set_time_float_from_date
     581             : 
     582             :     integer,  intent(in)  :: dates(:)
     583             :     integer,  intent(in)  :: secs(:)
     584             : 
     585             :     real(r8), intent(out) :: times(:)
     586             : 
     587             :     integer :: year, month, day, sec,n ,i
     588             : 
     589        1536 :     n = size( dates )
     590             : 
     591   252463104 :     do i=1,n
     592   252461568 :        year = dates(i)/10000
     593   252461568 :        month = (dates(i)-year*10000)/100
     594   252461568 :        day = dates(i)-year*10000-month*100
     595   252461568 :        sec = secs(i)
     596   252463104 :        call set_time_float_from_date( times(i), year, month, day, sec )
     597             :     enddo
     598             : 
     599        1536 :   end subroutine convert_dates
     600             : 
     601        1536 : end module input_data_utils

Generated by: LCOV version 1.14