Skip to content

Commit

Permalink
Add get_average_days_per_year function
Browse files Browse the repository at this point in the history
For now, use hard-coded parameters (see ESCOMP#1624).
  • Loading branch information
billsacks committed Feb 1, 2022
1 parent bf365e0 commit 0044189
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions src/utils/clm_time_manager.F90
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module clm_time_manager
get_curr_calday, &! return calendar day at end of current timestep
get_calday, &! return calendar day from input date
get_calendar, &! return calendar
get_average_days_per_year,&! return the average number of days per year for the given calendar
get_curr_days_per_year, &! return the days per year for year as of the end of the current time step
get_prev_days_per_year, &! return the days per year for year as of the beginning of the current time step
get_curr_yearfrac, &! return the fractional position in the current year, as of the end of the current timestep
Expand Down Expand Up @@ -122,6 +123,9 @@ module clm_time_manager
private :: TimeGetymd
private :: check_timemgr_initialized

character(len=*), parameter, private :: sourcefile = &
__FILE__

!=========================================================================================
contains
!=========================================================================================
Expand Down Expand Up @@ -1229,6 +1233,63 @@ end function get_calendar

!=========================================================================================

real(r8) function get_average_days_per_year()

!---------------------------------------------------------------------------------
! Get the average number of days per year for the given calendar.
!
! This should be used, for example, when converting a parameter from units of
! per-year to units of per-second (so that the parameter will have a fixed, constant
! value rather than a slightly different value on leap years vs. non-leap years).

real(r8) :: avg_days_per_year
real(r8) :: curr_days_per_year

real(r8), parameter :: days_per_year_noleap = 365._r8

! From the definition of ESMF_CALKIND_GREGORIAN in
! https://earthsystemmodeling.org/docs/release/latest/ESMF_refdoc/node6.html: "In the
! Gregorian calendar every fourth year is a leap year in which February has 29 and not
! 28 days; however, years divisible by 100 are not leap years unless they are also
! divisible by 400." This results in an average number of days per year of 365.2425.
real(r8), parameter :: days_per_year_gregorian = 365.2425_r8

character(len=*), parameter :: subname = 'get_average_days_per_year'
!---------------------------------------------------------------------------------

! BUG(wjs, 2022-02-01, ESCOMP/CTSM#1624) Ideally we would use ESMF_CalendarGet here,
! but that currently isn't possible (see notes in issue 1624 for details)
if (to_upper(calendar) == NO_LEAP_C) then
avg_days_per_year = days_per_year_noleap
else if (to_upper(calendar) == GREGORIAN_C) then
avg_days_per_year = days_per_year_gregorian
else
call shr_sys_abort(subname//' ERROR: unrecognized calendar specified= '//trim(calendar))
end if

! Paranoia: Since we're using a hard-coded value, let's make sure that the user hasn't
! done some customizations to the calendar that change the days per year from what we
! expect: Compare the hard-coded value with the number of days per year in the
! current year, which comes from the actual ESMF calendar; the two should be close.
! (This check can be removed once we address issue 1624, making the results of this
! function depend on the actual ESMF calendar instead of a hard-coded value.)
curr_days_per_year = get_curr_days_per_year()
if (abs(avg_days_per_year - curr_days_per_year) > 1._r8) then
write(iulog,*) 'ERROR: hard-coded average days per year differs by more than expected'
write(iulog,*) 'from current days per year. Are you using a non-standard calendar?'
write(iulog,*) 'avg_days_per_year (hard-coded) = ', avg_days_per_year
write(iulog,*) 'curr_days_per_year (from ESMF calendar) = ', curr_days_per_year
write(iulog,*) 'You can fix this by changing the hard-coded parameters in '//subname
write(iulog,*) 'in file: '//sourcefile
call shr_sys_abort(subname//' ERROR: hard-coded average days per year differs by more than expected')
end if

get_average_days_per_year = avg_days_per_year

end function get_average_days_per_year

!=========================================================================================

integer function get_curr_days_per_year( offset )

!---------------------------------------------------------------------------------
Expand Down

0 comments on commit 0044189

Please sign in to comment.