26 type(time_type),
intent(in) :: Time
27 real(FMS_TI_KIND_),
intent(out) :: weight
29 integer :: yr, mo, dy, hour, minute, second
30 type(time_type) :: Year_beg, Year_end
33 if ( .not. module_is_initialized )
call time_interp_init
37 call get_date (time, yr, mo, dy, hour, minute, second)
39 year_beg = set_date(yr , 1, 1)
40 year_end = set_date(yr+1, 1, 1)
42 weight = real( (time - year_beg) // (year_end - year_beg) , kind=fms_ti_kind_)
50 type(time_type),
intent(in) :: Time
51 real(FMS_TI_KIND_),
intent(out) :: weight
52 integer ,
intent(out) :: year1, year2
54 integer :: yr, mo, dy, hour, minute, second
55 type (time_type) :: Mid_year, Mid_year1, Mid_year2
58 if ( .not. module_is_initialized )
call time_interp_init()
60 call get_date (time, yr, mo, dy, hour, minute, second)
63 mid_year = year_midpt(yr)
65 if ( time >= mid_year )
then
69 mid_year2 = year_midpt(year2)
70 weight = real( (time - mid_year) // (mid_year2 - mid_year) , kind=fms_ti_kind_ )
75 mid_year1 = year_midpt(year1)
76 weight = real( (time - mid_year1) // (mid_year - mid_year1), kind=fms_ti_kind_ )
84 type(time_type),
intent(in) :: Time
85 real(FMS_TI_KIND_) ,
intent(out) :: weight
86 integer ,
intent(out) :: year1, year2, month1, month2
88 integer :: yr, mo, dy, hour, minute, second, &
89 mid_month, cur_month, mid1, mid2
91 if ( .not. module_is_initialized )
call time_interp_init()
93 call get_date (time, yr, mo, dy, hour, minute, second)
96 mid_month = days_in_month(time) * halfday
98 cur_month = second + secmin*minute + sechour*hour + secday*(dy-1)
100 if ( cur_month >= mid_month )
then
102 year1 = yr; month1 = mo
103 year2 = yr; month2 = mo+1
104 if (month2 > monyear)
then
105 year2 = year2+1; month2 = 1
108 mid2 = days_in_month(set_date(year2,month2,2)) * halfday
109 weight = real(cur_month - mid1, fms_ti_kind_) / real(mid1+mid2, fms_ti_kind_)
112 year2 = yr; month2 = mo
113 year1 = yr; month1 = mo-1
115 year1 = year1-1; month1 = monyear
118 mid1 = days_in_month(set_date(year1,month1,2)) * halfday
123 mid1 = days_in_month(set_date(1,month1,2)) * halfday
126 weight = real(cur_month + mid1, fms_ti_kind_) / real(mid1+mid2, fms_ti_kind_)
134 type(time_type),
intent(in) :: Time
135 real(FMS_TI_KIND_),
intent(out) :: weight
136 integer ,
intent(out) :: year1, year2, month1, month2, day1, day2
138 integer :: yr, mo, dy, hour, minute, second, sday
140 if ( .not. module_is_initialized )
call time_interp_init()
142 call get_date (time, yr, mo, dy, hour, minute, second)
145 sday = second + secmin*minute + sechour*hour
147 if ( sday >= halfday )
then
149 year1 = yr; month1 = mo; day1 = dy
150 year2 = yr; month2 = mo; day2 = dy + 1
151 weight = real(sday - halfday, fms_ti_kind_) / real(secday, fms_ti_kind_)
153 if (day2 > days_in_month(time))
then
156 if (month2 > monyear)
then
157 month2 = 1; year2 = year2+1
162 year2 = yr; month2 = mo ; day2 = dy
163 year1 = yr; month1 = mo; day1 = dy - 1
164 weight = real(sday + halfday,fms_ti_kind_) / real(secday,fms_ti_kind_)
169 month1 = monyear; year1 = year1-1
171 day1 = days_in_month(set_date(year1,month1,2))
182 correct_leap_year_inconsistency, err_msg)
183 type(time_type),
intent(in) :: Time
184 type(time_type),
intent(in) :: Time_beg
185 type(time_type),
intent(in) :: Time_end
186 type(time_type),
intent(in) :: Timelist(:)
187 real(FMS_TI_KIND_) ,
intent(out) :: weight
188 integer ,
intent(out) :: index1, index2
189 logical,
intent(in),
optional :: correct_leap_year_inconsistency
197 character(len=*),
intent(out),
optional :: err_msg
199 type(time_type) :: Period, T
200 integer :: is, ie,i1,i2
201 integer :: ys,ms,ds,hs,mins,ss
202 integer :: ye,me,de,he,mine,se
203 integer :: yt,mt,dt,ht,mint,st
206 integer :: stdoutunit
207 logical :: correct_lyr, calendar_has_leap_years, do_the_lyr_correction
208 integer,
parameter :: kindl = fms_ti_kind_
210 if ( .not. module_is_initialized )
call time_interp_init
211 if(
present(err_msg) ) err_msg =
''
216 if (time_beg>=time_end)
then
217 if(fms_error_handler(
'time_interp_modulo', &
218 'end of the specified time loop interval must be later than its beginning',err_msg))
return
221 calendar_has_leap_years = (get_calendar_type() == julian .or. get_calendar_type() == gregorian)
223 period = time_end-time_beg
225 if(
present(correct_leap_year_inconsistency))
then
226 correct_lyr = correct_leap_year_inconsistency
228 correct_lyr = .false.
234 do_the_lyr_correction = .false.
243 if(calendar_has_leap_years .and. correct_lyr)
then
244 call get_date(time_beg,ys,ms,ds,hs,mins,ss)
245 call get_date(time_end,ye,me,de,he,mine,se)
246 if(ms==me.and.ds==de.and.hs==he.and.mins==mine.and.ss==se)
then
248 do_the_lyr_correction = .true.
252 if(do_the_lyr_correction)
then
253 call get_date(t,yt,mt,dt,ht,mint,st)
254 yt = ys+modulo(yt-ys,ye-ys)
257 if(mt==2.and.dt==29.and..not.leap_year(set_date(yt,1,1))) dt1=28
258 t = set_date(yt,mt,dt1,ht,mint,st)
259 if (t < time_beg)
then
262 if(mt==2.and.dt==29.and..not.leap_year(set_date(ye,1,1))) dt=28
263 t = set_date(ye,mt,dt,ht,mint,st)
266 do while ( t >= time_end )
269 do while ( t < time_beg )
276 if (time_end<=timelist(1).or.time_beg>=timelist(n))
then
277 if(get_calendar_type() == no_calendar)
then
278 call print_time(time_beg,
'Time_beg' )
279 call print_time(time_end,
'Time_end' )
280 call print_time(timelist(1),
'Timelist(1)' )
281 call print_time(timelist(n),
'Timelist(n)' )
283 call print_date(time_beg,
'Time_beg' )
284 call print_date(time_end,
'Time_end' )
285 call print_date(timelist(1),
'Timelist(1)' )
286 call print_date(timelist(n),
'Timelist(n)' )
288 write(stdoutunit,*)
'where n = size(Timelist) =',n
289 if(fms_error_handler(
'time_interp_modulo', &
290 'the entire time list is outside the specified time loop interval',err_msg))
return
293 call bisect(timelist,time_beg,index1=i1,index2=i2)
296 else if (time_beg == timelist(i1))
then
301 call bisect(timelist,time_end,index1=i1,index2=i2)
302 if (time_end > timelist(i1))
then
304 else if (time_end == timelist(i1))
then
305 if(time_beg == timelist(is))
then
317 if(get_calendar_type() == no_calendar)
then
318 call print_time(time_beg,
'Time_beg =')
319 call print_time(time_end,
'Time_end =')
320 call print_time(timelist(1),
'Timelist(1)=')
321 call print_time(timelist(n),
'Timelist(n)=')
323 call print_date(time_beg,
'Time_beg =')
324 call print_date(time_end,
'Time_end =')
325 call print_date(timelist(1),
'Timelist(1)=')
326 call print_date(timelist(n),
'Timelist(n)=')
328 write(stdoutunit,*)
'where n = size(Timelist) =',n
329 write(stdoutunit,*)
'is =',is,
'ie =',ie
330 if(fms_error_handler(
'time_interp_modulo', &
331 'error in calculation of time list bounds within the specified time loop interval',err_msg))
return
335 if( t>=timelist(ie) )
then
337 index1 = ie; index2 = is
338 weight = real((t-timelist(ie))//(period-(timelist(ie)-timelist(is))), fms_ti_kind_ )
339 else if (t<timelist(is))
then
341 index1 = ie; index2 = is
342 weight = 1.0_kindl - real(((timelist(is)-t)//(period-(timelist(ie)-timelist(is)))), fms_ti_kind_ )
344 call bisect(timelist,t,index1,index2)
345 weight = real((t-timelist(index1)) // (timelist(index2)-timelist(index1)), fms_ti_kind_ )
350 subroutine time_interp_list_ ( Time, Timelist, weight, index1, index2, modtime, err_msg )
351 type(time_type) ,
intent(in) :: Time, Timelist(:)
352 real(FMS_TI_KIND_) ,
intent(out) :: weight
353 integer ,
intent(out) :: index1, index2
354 integer,
optional,
intent(in) :: modtime
355 character(len=*),
intent(out),
optional :: err_msg
357 integer :: n, hr, mn, se, mtime
358 type(time_type) :: T, Ts, Te, Td, Period, Time_mod
359 character(len=:),
allocatable :: terr, tserr, teerr
360 integer,
parameter :: kindl = fms_ti_kind_
362 if ( .not. module_is_initialized )
call time_interp_init
364 if(
present(err_msg) ) err_msg =
''
366 weight = 0.0_kindl; index1 = 0; index2 = 0
367 n =
size(timelist(:))
371 if (
present(modtime))
then
373 time_mod = (timelist(1)+timelist(n))/2
374 call get_date (time_mod, yrmod, momod, dymod, hr, mn, se)
375 mod_leapyear = leap_year(time_mod)
383 period = set_time(0,days_in_year(time_mod))
386 if (days_in_month(time_mod) /= days_in_month(time))
then
387 if(fms_error_handler(
'time_interp_list',
'modulo months must have same length',err_msg))
return
389 period = set_time(0,days_in_month(time_mod))
391 period = set_time(0,1)
393 if(fms_error_handler(
'time_interp_list',
'invalid value for argument modtime',err_msg))
return
399 if (mtime /= none .and. timelist(
size(timelist))-timelist(1) == period)
then
400 n =
size(timelist) - 1
409 t = set_modtime(time,mtime)
412 if (mtime /= none)
then
413 if (td > period)
then
414 if(fms_error_handler(
'time_interp_list',
'period of list exceeds modulo period',err_msg))
return
419 if ( t >= ts .and. t < te )
then
420 call bisect(timelist(1:n),t,index1,index2)
421 weight = real( (t-timelist(index1)) // (timelist(index2)-timelist(index1)), fms_ti_kind_)
424 else if ( t < ts )
then
425 if (mtime == none)
then
426 call time_list_error(t,terr)
427 call time_list_error(ts,tserr)
428 call time_list_error(te,teerr)
429 if(fms_error_handler(
'time_interp_list',&
430 'time '//trim(terr)//
' ('//date_to_string(t)//
' is before range of list '//trim(tserr)//
'-'//trim(teerr)//&
431 '('//date_to_string(ts)//
' - '//date_to_string(te)//
')',&
433 deallocate(terr,tserr,teerr)
436 weight = 1.0_kindl - real(((ts-t) // (period-td)), fms_ti_kind_ )
441 else if ( t == te )
then
442 if(perthlike_behavior)
then
449 if (mtime == none)
then
457 else if ( t > te )
then
458 if (mtime == none)
then
459 call time_list_error(t,terr)
460 call time_list_error(ts,tserr)
461 call time_list_error(te,teerr)
462 if(fms_error_handler(
'time_interp_list',&
463 'time '//trim(terr)//
' ('//date_to_string(t)//
' is after range of list '//trim(tserr)//
'-'//trim(teerr)//&
464 '('//date_to_string(ts)//
' - '//date_to_string(te)//
')',&
466 deallocate(terr,tserr,teerr)
469 weight = real( (t-te) // (period-td), fms_ti_kind_)
474 end subroutine time_interp_list_
integer function stdout()
This function returns the current standard fortran unit numbers for output.
subroutine time_interp_year_(Time, weight, year1, year2)
Calculates fractional time between mid points of consecutive years.
subroutine time_interp_month_(Time, weight, year1, year2, month1, month2)
Calculates fractional time between mid points of consecutive months.
subroutine time_interp_frac_(Time, weight)
Calculates the fractional time into the current year.
subroutine time_interp_modulo_(Time, Time_beg, Time_end, Timelist, weight, index1, index2, correct_leap_year_inconsistency, err_msg)
Part of the time_interp interface, calculates for cyclical data Time_beg and Time_end mark a repeatin...
subroutine time_interp_day_(Time, weight, year1, year2, month1, month2, day1, day2)
Calculates fractional time between mid points of consecutive days.