-
Notifications
You must be signed in to change notification settings - Fork 248
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
Flexible restart write times (restart_fh) for med, ocn, ice, wav #2419
base: develop
Are you sure you want to change the base?
Changes from all commits
efb9646
2bd58ee
051ad6c
944454a
2a65120
824706e
a24a0eb
a570f32
85a1dbe
e70b4a5
3f22e99
ba7eec6
12cf89c
a5525d4
d190908
2daced1
352623d
0b9f6e0
ec854eb
ae98062
4a335f8
28e4930
901ed87
e909d8e
9a8710e
c976b02
9ecb1f0
6f01def
aafd075
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
module shr_is_restart_fh_mod | ||
|
||
! Common methods for components to check if it's time to write forecast hour-based restarts | ||
|
||
!use dshr_methods_mod , only : chkerr | ||
use ESMF, only : ESMF_ConfigCreate, ESMF_ConfigDestroy, ESMF_ConfigLoadFile, & | ||
ESMF_ConfigGetLen, ESMF_ConfigGetAttribute, ESMF_TimePrint, & | ||
ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_TimeInterval, & | ||
ESMF_Time, ESMF_KIND_R8, ESMF_Config, ESMF_Clock, & | ||
ESMF_TimeIntervalSet, ESMF_TimePrint, operator(+), operator(==), & | ||
ESMF_LogFoundError, ESMF_LOGERR_PASSTHRU | ||
|
||
implicit none | ||
private | ||
|
||
type :: is_restart_fh_type | ||
logical :: write_restartfh = .false. | ||
type(ESMF_Time), allocatable :: restartFhTimes(:) | ||
end type is_restart_fh_type | ||
|
||
public :: init_is_restart_fh, is_restart_fh, finalize_restart_fh, is_restart_fh_type | ||
|
||
contains | ||
|
||
!----------------------------------------------------------------------- | ||
subroutine init_is_restart_fh(currentTime, dtime, lLog, restartfh_info) | ||
! | ||
! !DESCRIPTION: | ||
! Process restart_fh attribute from model_configure in UFS | ||
! | ||
! !USES: | ||
! | ||
! !ARGUMENTS: | ||
type(ESMF_Time), intent(in) :: currentTime | ||
integer, intent(in) :: dtime ! time step (s) | ||
logical, intent(in) :: lLog ! If true, this task logs restart_fh info | ||
type(is_restart_fh_type), intent(out) :: restartfh_info !restart_fh info for each task | ||
! | ||
! !LOCAL VARIABLES: | ||
character(len=256) :: timestr | ||
integer :: n, nfh, fh_s, rc | ||
logical :: isPresent | ||
real(kind=ESMF_KIND_R8), allocatable :: restart_fh(:) | ||
type(ESMF_TimeInterval) :: fhInterval | ||
type(ESMF_Config) :: CF_mc | ||
!----------------------------------------------------------------------- | ||
|
||
! set up Times to write non-interval restarts | ||
inquire(FILE='model_configure', EXIST=isPresent) | ||
if (isPresent) then !model_configure exists. this is ufs run | ||
CF_mc = ESMF_ConfigCreate(rc=rc) | ||
call ESMF_ConfigLoadFile(config=CF_mc,filename='model_configure' ,rc=rc) | ||
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return | ||
|
||
nfh = ESMF_ConfigGetLen(config=CF_mc, label ='restart_fh:',rc=rc) | ||
if (nfh .gt. 0) then | ||
allocate(restart_fh(1:nfh)) | ||
allocate(restartfh_info%restartFhTimes(1:nfh)) !not deallocated here | ||
|
||
call ESMF_ConfigGetAttribute(CF_mc,valueList=restart_fh,label='restart_fh:', rc=rc) | ||
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return | ||
! create a list of times at each restart_fh | ||
do n = 1,nfh | ||
fh_s = NINT(3600*restart_fh(n)) | ||
call ESMF_TimeIntervalSet(fhInterval, s=fh_s, rc=rc) | ||
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return | ||
restartfh_info%restartFhTimes(n) = currentTime + fhInterval | ||
call ESMF_TimePrint(restartfh_info%restartFhTimes(n), options="string", & | ||
preString="restart_fh at ", unit=timestr, rc=rc) | ||
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return | ||
if (lLog) then | ||
if (mod(fh_s,dtime) /= 0) then | ||
call ESMF_LogWrite('restart time NOT to be written for '//trim(timestr), ESMF_LOGMSG_INFO) | ||
else | ||
call ESMF_LogWrite('restart time to be written for '//trim(timestr), ESMF_LOGMSG_INFO) | ||
end if | ||
end if | ||
end do | ||
deallocate(restart_fh) | ||
end if !nfh>0 | ||
call ESMF_ConfigDestroy(CF_mc, rc=rc) | ||
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return | ||
end if !model_configure | ||
|
||
end subroutine init_is_restart_fh | ||
|
||
subroutine is_restart_fh(clock, restartfh_info, lWrite) | ||
! | ||
! !DESCRIPTION: | ||
! True/false if time to write restart | ||
! | ||
! !USES: | ||
use ESMF, only : ESMF_ClockGetNextTime | ||
|
||
! | ||
! !ARGUMENTS: | ||
type(ESMF_Clock), intent(in) :: clock | ||
type(is_restart_fh_type), intent(inout) :: restartfh_info | ||
logical, intent(out) :: lWrite ! time to write? | ||
! | ||
! !LOCAL VARIABLES: | ||
integer :: nfh, rc | ||
type(ESMF_Time) :: nextTime | ||
!----------------------------------------------------------------------- | ||
|
||
restartfh_info%write_restartfh = .false. | ||
if (allocated(restartfh_info%restartFhTimes)) then | ||
! check if next time is == to any restartfhtime | ||
do nfh = 1,size(restartfh_info%restartFhTimes) | ||
call ESMF_ClockGetNextTime(clock, nextTime=nexttime, rc=rc) | ||
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return | ||
if (nextTime == restartfh_info%restartFhTimes(nfh)) restartfh_info%write_restartfh = .true. | ||
end do | ||
end if | ||
|
||
lWrite = restartfh_info%write_restartfh | ||
|
||
end subroutine is_restart_fh | ||
|
||
subroutine finalize_restart_fh(restartfh_info) | ||
! | ||
! !DESCRIPTION: | ||
! Clean-up...release allocated memory | ||
! | ||
! !USES: | ||
! | ||
! !ARGUMENTS: | ||
type(is_restart_fh_type), intent(inout) :: restartfh_info | ||
! | ||
! !LOCAL VARIABLES: | ||
!----------------------------------------------------------------------- | ||
|
||
if (allocated(restartfh_info%restartFhTimes)) deallocate(restartfh_info%restartFhTimes) | ||
|
||
end subroutine finalize_restart_fh | ||
|
||
end module shr_is_restart_fh_mod |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,7 +63,7 @@ list(APPEND lib_src_files | |
${icepack_files} | ||
${cice_mpi_comm_files} | ||
${cice_nuopc_cmeps_driver_files} | ||
${cice_cdeps_inline_files}) | ||
${cice_cdeps_share_files}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this is a temporary solution. Does this mean that now cice/mom/ww3 caps now have dependency on the CDEPS share code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. CICE and CMEPS already have dependency for CDEPS inline functionality. MOM6 and WW3 now have restart_fh module in cmakes. While this is currently under CDEPS-interface, it is a ufs-weather-model file (not a CDEPS subcomponent file) |
||
|
||
list(APPEND _cice_defs FORTRANUNDERSCORE | ||
coupled) | ||
|
+2 −0 | model/src/cmake/src_list.cmake | |
+14 −1 | model/src/wav_comp_nuopc.F90 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't you use the cleaner form ? I see it commented out.
Add
use dshr_methods_mod , only : chkerr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can, but that brings additional dependencies into this module besides ESMF. There are also quite some duplicate ChkErr functions floating around all just wrapping an ESMF function