50 operator(+),
operator(-),
operator(>), &
51 operator(<),
operator( // ),
operator( / ), &
52 operator(>=),
operator(<=),
operator( * ), &
56 use fms_mod,
only: write_version_number, &
219 #include<file_version.h> 230 integer :: ierr, io, namelist_unit, logunit
234 #ifdef INTERNAL_FILE_NML 238 namelist_unit = open_namelist_file()
241 read(namelist_unit, nml=time_interp_nml, iostat=io, end=20)
244 20
call close_file (namelist_unit)
247 call write_version_number(
"TIME_INTERP_MOD", version)
249 write(logunit,time_interp_nml)
265 type(time_type),
intent(in) :: Time
266 real ,
intent(out) :: weight
268 integer :: year, month, day, hour, minute, second
269 type(time_type) :: Year_beg, Year_end
276 call get_date (time, year, month, day, hour, minute, second)
281 weight = (time - year_beg) // (year_end - year_beg)
311 type(time_type),
intent(in) :: Time
312 real ,
intent(out) :: weight
313 integer ,
intent(out) :: year1, year2
315 integer :: year, month, day, hour, minute, second
316 type(
time_type) :: mid_year, mid_year1, mid_year2
321 call get_date (time, year, month, day, hour, minute, second)
326 if ( time >= mid_year )
then 331 weight = (time - mid_year) // (mid_year2 - mid_year)
337 weight = (time - mid_year1) // (mid_year - mid_year1)
355 type(time_type),
intent(in) :: Time
356 real ,
intent(out) :: weight
357 integer ,
intent(out) :: year1, year2, month1, month2
359 integer :: year, month, day, hour, minute, second, &
360 mid_month, cur_month, mid1, mid2
364 call get_date (time, year, month, day, hour, minute, second)
371 if ( cur_month >= mid_month )
then 373 year1 = year; month1 = month
374 year2 = year; month2 = month+1
376 year2 = year2+1; month2 = 1
380 weight =
real(cur_month - mid1) /
real(mid1+mid2)
383 year2 = year; month2 = month
384 year1 = year; month1 = month-1
386 year1 = year1-1; month1 =
monyear 397 weight =
real(cur_month + mid1) /
real(mid1+mid2)
415 subroutine time_interp_day ( Time, weight, year1, year2, month1, month2, day1, day2 )
417 type(time_type),
intent(in) :: Time
418 real ,
intent(out) :: weight
419 integer ,
intent(out) :: year1, year2, month1, month2, day1, day2
421 integer :: year, month, day, hour, minute, second, sday
425 call get_date (time, year, month, day, hour, minute, second)
432 year1 = year; month1 = month; day1 = day
433 year2 = year; month2 = month; day2 = day + 1
434 weight =
real(sday - halfday) /
real(secday)
440 month2 = 1; year2 = year2+1
445 year2 = year; month2 = month; day2 = day
446 year1 = year; month1 = month; day1 = day - 1
447 weight =
real(sday + halfday) /
real(secday)
452 month1 =
monyear; year1 = year1-1
479 subroutine time_interp_modulo(Time, Time_beg, Time_end, Timelist, weight, index1, index2, &
480 correct_leap_year_inconsistency, err_msg)
481 type(time_type),
intent(in) :: Time, Time_beg, Time_end, Timelist(:)
482 real ,
intent(out) :: weight
483 integer ,
intent(out) :: index1, index2
484 logical,
intent(in),
optional :: correct_leap_year_inconsistency
485 character(len=*),
intent(out),
optional :: err_msg
487 type(time_type) :: Period, T
488 integer :: is, ie,i1,i2
489 integer :: ys,ms,ds,hs,mins,ss
490 integer :: ye,me,de,he,mine,se
491 integer :: yt,mt,dt,ht,mint,st
494 integer :: stdoutunit
495 logical :: correct_lyr, calendar_has_leap_years, do_the_lyr_correction
498 if(
present(err_msg) ) err_msg =
'' 500 stdoutunit = stdout()
503 if (time_beg>=time_end)
then 505 'end of the specified time loop interval must be later than its beginning',err_msg))
return 510 period = time_end-time_beg
512 if(
present(correct_leap_year_inconsistency))
then 513 correct_lyr = correct_leap_year_inconsistency
515 correct_lyr = .false.
521 do_the_lyr_correction = .false.
530 if(calendar_has_leap_years .and. correct_lyr)
then 531 call get_date(time_beg,ys,ms,ds,hs,mins,ss)
532 call get_date(time_end,ye,me,de,he,mine,se)
533 if(ms==me.and.ds==de.and.hs==he.and.mins==mine.and.ss==se)
then 535 do_the_lyr_correction = .true.
539 if(do_the_lyr_correction)
then 540 call get_date(t,yt,mt,dt,ht,mint,st)
541 yt = ys+modulo(yt-ys,ye-ys)
546 if (t < time_beg)
then 553 do while ( t >= time_end )
556 do while ( t < time_beg )
563 if (time_end<=timelist(1).or.time_beg>=timelist(n))
then 575 write(stdoutunit,*)
'where n = size(Timelist) =',n
577 'the entire time list is outside the specified time loop interval',err_msg))
return 580 call bisect(timelist,time_beg,index1=i1,index2=i2)
583 else if (time_beg == timelist(i1))
then 588 call bisect(timelist,time_end,index1=i1,index2=i2)
589 if (time_end > timelist(i1))
then 591 else if (time_end == timelist(i1))
then 592 if(time_beg == timelist(is))
then 615 write(stdoutunit,*)
'where n = size(Timelist) =',n
616 write(stdoutunit,*)
'is =',is,
'ie =',ie
618 'error in calculation of time list bounds within the specified time loop interval',err_msg))
return 622 if( t>=timelist(ie) )
then 624 index1 = ie; index2 = is
625 weight = (t-timelist(ie))//(period-(timelist(ie)-timelist(is)))
626 else if (t<timelist(is))
then 628 index1 = ie; index2 = is
629 weight = 1.0-((timelist(is)-t)//(period-(timelist(ie)-timelist(is))))
631 call bisect(timelist,t,index1,index2)
632 weight = (t-timelist(index1)) // (timelist(index2)-timelist(index1))
643 subroutine bisect(Timelist,Time,index1,index2)
644 type(time_type) ,
intent(in) :: Timelist(:)
645 type(time_type) ,
intent(in) :: Time
646 integer,
optional,
intent(out) :: index1, index2
648 integer :: i,il,iu,n,i1,i2
650 n =
size(timelist(:))
652 if (time==timelist(1))
then 654 else if (time==timelist(n))
then 660 if(timelist(i) > time)
then 669 if(
PRESENT(index1)) index1 = i1
670 if(
PRESENT(index2)) index2 = i2
684 subroutine time_interp_list ( Time, Timelist, weight, index1, index2, modtime, err_msg )
685 type(time_type) ,
intent(in) :: Time, Timelist(:)
686 real ,
intent(out) :: weight
687 integer ,
intent(out) :: index1, index2
688 integer,
optional,
intent(in) :: modtime
689 character(len=*),
intent(out),
optional :: err_msg
691 integer :: n, hr, mn, se, mtime
692 type(time_type) :: T, Ts, Te, Td, Period, Time_mod
693 character(len=:),
allocatable :: terr, tserr, teerr
697 if(
present(err_msg) ) err_msg =
'' 699 weight = 0.; index1 = 0; index2 = 0
700 n =
size(timelist(:))
704 if (
present(modtime))
then 706 time_mod = (timelist(1)+timelist(n))/2
720 if(
fms_error_handler(
'time_interp_list',
'modulo months must have same length',err_msg))
return 726 if(
fms_error_handler(
'time_interp_list',
'invalid value for argument modtime',err_msg))
return 732 if (mtime /=
none .and. timelist(
size(timelist))-timelist(1) == period)
then 733 n =
size(timelist) - 1
745 if (mtime /=
none)
then 746 if (td > period)
then 747 if(
fms_error_handler(
'time_interp_list',
'period of list exceeds modulo period',err_msg))
return 752 if ( t >= ts .and. t < te )
then 753 call bisect(timelist(1:n),t,index1,index2)
754 weight = (t-timelist(index1)) // (timelist(index2)-timelist(index1))
757 else if ( t < ts )
then 758 if (mtime ==
none)
then 763 'time '//trim(terr)//
' ('//
date_to_string(t)//
' is before range of list '//trim(tserr)//
'-'//trim(teerr)//&
766 deallocate(terr,tserr,teerr)
769 weight = 1. - ((ts-t) // (period-td))
774 else if ( t == te )
then 782 if (mtime ==
none)
then 790 else if ( t > te )
then 791 if (mtime ==
none)
then 796 'time '//trim(terr)//
' ('//
date_to_string(t)//
' is after range of list '//trim(tserr)//
'-'//trim(teerr)//&
799 deallocate(terr,tserr,teerr)
802 weight = (t-te) // (period-td)
815 integer,
intent(in) ::
year 851 integer,
intent(in),
optional :: modtime
853 integer :: yr, mo, dy, hr, mn, se, mtime
855 if(
present(modtime))
then 865 call get_date (tin, yr, mo, dy, hr, mn, se)
871 tout =
set_date(yr, mo, dy, hr, mn, se)
873 call get_date (tin, yr, mo, dy, hr, mn, se)
875 tout =
set_date(yr, mo, dy, hr, mn, se)
877 call get_date (tin, yr, mo, dy, hr, mn, se)
879 tout =
set_date(yr, mo, dy, hr, mn, se)
887 character(len=*),
intent(in) :: string
940 #ifdef test_time_interp_ 941 program test_time_interp
949 integer,
parameter :: num_Time=6
950 type(time_type) :: Time_beg, Time_end, Time(num_Time)
951 type(time_type),
allocatable,
dimension(:) :: Timelist
952 integer :: index1, index2, mo, yr, timelist_len, outunit, ntest, nline
955 integer :: nmin, nmax
957 namelist / test_time_interp_nml / timelist_len
961 call set_calendar_type(
julian)
976 allocate(timelist(12))
980 else if(nline == 2)
then 981 allocate(timelist(13))
986 else if(nline == 3)
then 987 allocate(timelist(12))
995 call diagram(nline,ntest,modulo_time=.true.)
996 call time_interp(time(ntest), time_beg, time_end, timelist, weight, index1, index2)
997 write(outunit,*)
'time_interp_modulo:' 1003 call print_date(timelist(
size(timelist(:))),
'Timelist(n)=')
1004 write(outunit,99) index1,index2,weight
1007 call time_interp(time(ntest), timelist, weight, index1, index2, modtime=
year)
1008 write(outunit,*)
'time_interp_list with modtime=YEAR:' 1012 call print_date(timelist(
size(timelist(:))),
'Timelist(n)=')
1013 write(outunit,99) index1,index2,weight
1015 deallocate(timelist)
1021 allocate(timelist(12))
1025 else if(nline == 2)
then 1026 allocate(timelist(13))
1031 else if(nline == 3)
then 1032 allocate(timelist(12))
1034 timelist(mo-1) =
set_date(1, mo, 1)
1041 else if(nline == 2)
then 1042 nmin = 1; nmax = num_time
1043 else if(nline == 3)
then 1044 nmin = 3; nmax = num_time
1047 call diagram(nline,ntest,modulo_time=.false.)
1048 call time_interp(time(ntest), timelist, weight, index1, index2, modtime=
none)
1049 write(outunit,*)
'time_interp_list with modtime=NONE:' 1053 call print_date(timelist(
size(timelist(:))),
'Timelist(n)=')
1054 write(outunit,99) index1,index2,weight
1056 deallocate(timelist)
1069 allocate(timelist(13))
1071 timelist(mo) =
set_date(1999, mo, 1)
1073 timelist(13) =
set_date(2000, 1, 1)
1075 write(outunit,
'("<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>",/)')
1077 write(outunit,*)
'time_interp_modulo with correct_leap_year_inconsistency=.true.' 1079 write(outunit,
'(" Jan 1 1999 Jan 1 2000")')
1080 write(outunit,
'(" | |")')
1081 write(outunit,
'(" v v")')
1082 write(outunit,
'(" x---x---x---x---x---x---x---x---x---x---x---x---x")')
1083 write(outunit,
'(" ^ ^")')
1084 write(outunit,
'(" | |")')
1085 write(outunit,
'(" Time_beg Time_end ")')
1089 call time_interp(time(ntest), time_beg, time_end, timelist, weight, index1, index2, correct_leap_year_inconsistency=.true.)
1091 write(outunit,99) index1,index2,weight
1094 deallocate(timelist)
1105 allocate(timelist(37))
1108 timelist(12*(yr-1978)+mo) =
set_date(yr, mo, 1)
1111 timelist(37) =
set_date(1981, 1, 1)
1113 write(outunit,
'("<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>")')
1115 write(outunit,*)
'time_interp_modulo with correct_leap_year_inconsistency=.true.' 1117 write(outunit,
'(" Jan 1 1978 Jan 1 1979 Jan 1 1980 Jan 1 1981")')
1118 write(outunit,
'(" | | | <---- leap year ----> |")')
1119 write(outunit,
'(" v v v v")')
1120 write(outunit,
'(" x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x")')
1121 write(outunit,
'(" ^ ^")')
1122 write(outunit,
'(" | |")')
1123 write(outunit,
'(" Time_beg Time_end")')
1127 call time_interp(time(ntest), time_beg, time_end, timelist, weight, index1, index2, correct_leap_year_inconsistency=.true.)
1129 write(outunit,99) index1,index2,weight
1132 deallocate(timelist)
1134 allocate(timelist(12))
1135 timelist( 1) =
set_date(1, 1, 16, hour=12)
1136 timelist( 2) =
set_date(1, 2, 15, hour= 0)
1137 timelist( 3) =
set_date(1, 3, 16, hour=12)
1138 timelist( 4) =
set_date(1, 4, 16, hour= 0)
1139 timelist( 5) =
set_date(1, 5, 16, hour=12)
1140 timelist( 6) =
set_date(1, 6, 16, hour= 0)
1141 timelist( 7) =
set_date(1, 7, 16, hour=12)
1142 timelist( 8) =
set_date(1, 8, 16, hour=12)
1143 timelist( 9) =
set_date(1, 9, 16, hour= 0)
1144 timelist(10) =
set_date(1, 10, 16, hour=12)
1145 timelist(11) =
set_date(1, 11, 16, hour= 0)
1146 timelist(12) =
set_date(1, 12, 16, hour=12)
1149 call diagram(nline=4, ntest=0, modulo_time=.true.)
1153 call time_interp(time(1), timelist, weight, index1, index2, modtime=
year)
1154 write(outunit,89)
'time_interp_list with modtime=YEAR: ', index1,index2,weight
1155 call time_interp(time(1), time_beg, time_end, timelist, weight, index1, index2, correct_leap_year_inconsistency=.true.)
1156 write(outunit,89)
'time_interp_modulo: ', index1,index2,weight
1160 99
format(
' index1=',i3,
' index2=',i3,
' weight=',f18.15)
1161 89
format(a20,
' index1=',i3,
' index2=',i3,
' weight=',f18.15)
1166 subroutine diagram(nline,ntest,modulo_time)
1167 integer,
intent(in) :: nline,ntest
1168 logical,
intent(in) :: modulo_time
1170 write(outunit,
'("<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>")')
1172 if(modulo_time)
then 1173 write(outunit,
'(" Time_beg Time_end")')
1174 write(outunit,
'(" | |")')
1175 write(outunit,
'(" v v")')
1179 write(outunit,
'(" x---x---x---x---x---x---x---x---x---x---x---x----")')
1180 else if(nline == 2)
then 1181 write(outunit,
'(" x---x---x---x---x---x---x---x---x---x---x---x---x")')
1182 else if(nline == 3)
then 1183 write(outunit,
'(" ----x---x---x---x---x---x---x---x---x---x---x---x")')
1184 else if(nline == 4)
then 1185 write(outunit,
'(" --x---x---x---x---x---x---x---x---x---x---x---x--")')
1189 write(outunit,
'(" ^") ')
1190 write(outunit,
'(" |") ')
1191 write(outunit,
'(" Time")')
1192 else if(ntest == 2)
then 1193 write(outunit,
'(" ^") ')
1194 write(outunit,
'(" |") ')
1195 write(outunit,
'(" Time")')
1196 else if(ntest == 3)
then 1197 write(outunit,
'(" ^") ')
1198 write(outunit,
'(" |") ')
1199 write(outunit,
'(" Time")')
1200 else if(ntest == 4)
then 1201 write(outunit,
'(" ^") ')
1202 write(outunit,
'(" |") ')
1203 write(outunit,
'(" Time")')
1204 else if(ntest == 5)
then 1205 write(outunit,
'(" ^") ')
1206 write(outunit,
'(" |") ')
1207 write(outunit,
'(" Time")')
1208 else if(ntest == 6)
then 1209 write(outunit,
'(" ^") ')
1210 write(outunit,
'(" |") ')
1211 write(outunit,
'(" Time")')
1215 end subroutine diagram
1217 end program test_time_interp
subroutine, public time_interp_init()
type(time_type) function, public increment_time(Time, seconds, days, ticks, err_msg, allow_neg_inc)
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
integer, parameter, public gregorian
void error_handler(const char *msg)
integer, parameter, public noleap
subroutine time_interp_day(Time, weight, year1, year2, month1, month2, day1, day2)
integer, parameter secmin
subroutine time_interp_year(Time, weight, year1, year2)
logical function, public fms_error_handler(routine, message, err_msg)
integer, parameter, public none
integer, parameter secday
integer function, public check_nml_error(IOSTAT, NML_NAME)
logical perthlike_behavior
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
integer, parameter, public month
subroutine, public set_calendar_type(type, err_msg)
integer, parameter, public day
subroutine time_interp_list(Time, Timelist, weight, index1, index2, modtime, err_msg)
subroutine, public fms_init(localcomm)
character(len=15) function, public date_to_string(time, err_msg)
integer, parameter monyear
integer function, public days_in_month(Time, err_msg)
integer, parameter, public julian
subroutine, public time_list_error(T, Terr)
This routine converts the integer tdays to a string.
integer function, public get_calendar_type()
integer, parameter hourday
integer, parameter minhour
integer, parameter halfday
type(time_type) function year_midpt(year)
subroutine, public time_manager_init()
type(time_type) function set_modtime(Tin, modtime)
real function, public fraction_of_year(Time)
integer, parameter, public year
logical module_is_initialized
integer, parameter, public no_calendar
subroutine time_interp_modulo(Time, Time_beg, Time_end, Timelist, weight, index1, index2, correct_leap_year_inconsistency, err_msg)
logical function, public leap_year(Time, err_msg)
subroutine, public fms_end()
type(time_type) function, public real_to_time_type(x, err_msg)
subroutine time_interp_month(Time, weight, year1, year2, month1, month2)
subroutine bisect(Timelist, Time, index1, index2)
real(double_kind) function, public time_type_to_real(time)
integer, parameter sechour
subroutine time_interp_frac(Time, weight)
type(time_type) function month_midpt(year, month)
integer function, public days_in_year(Time)
subroutine, public error_mesg(routine, message, level)
subroutine, public print_time(Time, str, unit)
subroutine, public print_date(Time, str, unit)