Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update nuopc_shr_methods to match share code #318

Merged
merged 3 commits into from
Dec 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 40 additions & 102 deletions share/nuopc_shr_methods.F90
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module nuopc_shr_methods

use ESMF , only : operator(<), operator(/=), operator(+)
use ESMF , only : operator(-), operator(*) , operator(>=)
use ESMF , only : operator(<=), operator(>), operator(==), MOD
Expand Down Expand Up @@ -501,7 +500,7 @@ end subroutine field_getfldptr

subroutine alarmInit( clock, alarm, option, &
opt_n, opt_ymd, opt_tod, RefTime, alarmname, advance_clock, rc)
use ESMF, only : ESMF_AlarmPrint
use ESMF, only : ESMF_AlarmPrint, ESMF_ClockGetAlarm
! Setup an alarm in a clock
! Notes: The ringtime sent to AlarmCreate MUST be the next alarm
! time. If you send an arbitrary but proper ringtime from the
Expand Down Expand Up @@ -595,39 +594,41 @@ subroutine alarmInit( clock, alarm, option, &
return
end if
end if
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return

! Determine inputs for call to create alarm
selectcase (trim(option))

case (optNONE)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
if (chkerr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optNever)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
if (chkerr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optDate)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call timeInit(NextAlarm, lymd, cal, ltod, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optNSteps,trim(optNSteps)//'s')
call ESMF_ClockGet(clock, TimeStep=TimestepInterval, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeIntervalSet(AlarmInterval, s=dtime_drv, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if(dtime_drv > 0) then
call ESMF_TimeIntervalSet(AlarmInterval, s=dtime_drv, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
endif

AlarmInterval = AlarmInterval * opt_n
! timestepinterval*0 is 0 of kind ESMF_TimeStepInterval
if (mod(AlarmInterval, TimestepInterval) /= (timestepinterval*0)) then
if (mod(AlarmInterval, TimestepInterval) /= (TimestepInterval*0)) then
call ESMF_LogWrite(subname//'illegal Alarm setting for '//trim(alarmname), ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
Expand Down Expand Up @@ -682,6 +683,13 @@ subroutine alarmInit( clock, alarm, option, &
call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .true.

case (optEnd)
call ESMF_ClockGetAlarm(clock, alarmname="alarm_stop", alarm=alarm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_AlarmGet(alarm, ringTime=NextAlarm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

case default
call ESMF_LogWrite(subname//'unknown option '//trim(option), ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
Expand Down Expand Up @@ -762,114 +770,45 @@ end subroutine timeInit

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

integer function get_minimum_timestep(gcomp, rc)
integer function get_minimum_timestep(gcomp, rc)
! Get the minimum timestep interval in seconds based on the nuopc.config variables *_cpl_dt,
! if none of these variables are defined this routine will throw an error
type(ESMF_GridComp), intent(in) :: gcomp
integer, intent(out) :: rc

character(len=CS) :: cvalue
integer :: atm_cpl_dt ! Atmosphere coupling interval
integer :: lnd_cpl_dt ! Land coupling interval
integer :: ice_cpl_dt ! Sea-Ice coupling interval
integer :: ocn_cpl_dt ! Ocean coupling interval
integer :: glc_cpl_dt ! Glc coupling interval
integer :: rof_cpl_dt ! Runoff coupling interval
integer :: wav_cpl_dt ! Wav coupling interval
logical :: is_present, is_set ! determine if these variables are used
integer :: esp_cpl_dt ! Esp coupling interval

character(len=CS) :: cvalue
integer :: comp_dt ! coupling interval of component
integer, parameter :: ncomps = 8
character(len=3),dimension(ncomps) :: compname
character(len=10) :: comp
logical :: is_present, is_set ! determine if these variables are used
integer :: i
!---------------------------------------------------------------------------
! Determine driver clock timestep
!---------------------------------------------------------------------------
compname = (/"atm", "lnd", "ice", "ocn", "rof", "glc", "wav", "esp"/)
get_minimum_timestep = huge(1)

call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) atm_cpl_dt
get_minimum_timestep = min(atm_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) lnd_cpl_dt
get_minimum_timestep = min(lnd_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) ice_cpl_dt
get_minimum_timestep = min(ice_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) ocn_cpl_dt
get_minimum_timestep = min(ocn_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) glc_cpl_dt
get_minimum_timestep = min(glc_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) rof_cpl_dt
get_minimum_timestep = min(rof_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", value=cvalue, rc=rc)
do i=1,ncomps
comp = compname(i)//"_cpl_dt"

call NUOPC_CompAttributeGet(gcomp, name=comp, isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) wav_cpl_dt
get_minimum_timestep = min(wav_cpl_dt, get_minimum_timestep)
endif

call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", isPresent=is_present, isSet=is_set, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name=comp, value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) comp_dt
get_minimum_timestep = min(comp_dt, get_minimum_timestep)
endif
enddo

if (is_present .and. is_set) then
call NUOPC_CompAttributeGet(gcomp, name="esp_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) esp_cpl_dt
get_minimum_timestep = min(esp_cpl_dt, get_minimum_timestep)
endif
if(get_minimum_timestep == huge(1)) then
call ESMF_LogWrite('minimum_timestep_error: this option is not supported ', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
endif
if(get_minimum_timestep <= 0) then
print *,__FILE__,__LINE__,atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt
call ESMF_LogWrite('minimum_timestep_error ERROR ', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
Expand All @@ -890,7 +829,6 @@ subroutine shr_get_rpointer_name(gcomp, compname, ymd, time, rpfile, mode, rc)
character(len=16) timestr
logical :: isPresent
character(len=ESMF_MAXSTR) :: inst_suffix

character(len=*), parameter :: subname='shr_get_rpointer_name'

rc = ESMF_SUCCESS
Expand All @@ -904,8 +842,8 @@ subroutine shr_get_rpointer_name(gcomp, compname, ymd, time, rpfile, mode, rc)
mon = (ymd - yr*10000)/100
day = (ymd - yr*10000 - mon*100)
write(timestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',time

write(rpfile,*) "rpointer."//compname//trim(inst_suffix)//'.'//trim(timestr)
rpfile = adjustl(rpfile)
if (mode.eq.'read') then
inquire(file=trim(rpfile), exist=isPresent)
if(.not. isPresent) then
Expand Down
Loading