Skip to content

Commit

Permalink
add ocean lag option, make cap consistent (#33)
Browse files Browse the repository at this point in the history
* use flag to control lag startup

* additional log msg cleanup

* clarify restart_mode control
  • Loading branch information
DeniseWorthen authored Sep 9, 2020
1 parent 7e1188c commit eb58a2e
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 91 deletions.
175 changes: 92 additions & 83 deletions config_src/nuopc_driver/mom_cap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ module MOM_cap_mod
use ESMF, only: ESMF_ArrayCreate
use ESMF, only: ESMF_RC_FILE_OPEN, ESMF_RC_FILE_READ, ESMF_RC_FILE_WRITE
use ESMF, only: ESMF_VMBroadcast
use ESMF, only: ESMF_AlarmCreate, ESMF_ClockGetAlarmList, ESMF_AlarmList_Flag
use ESMF, only: ESMF_AlarmCreate, ESMF_ClockGetAlarmList, ESMF_AlarmList_Flag
use ESMF, only: ESMF_AlarmGet, ESMF_AlarmIsCreated, ESMF_ALARMLIST_ALL, ESMF_AlarmIsEnabled
use ESMF, only: ESMF_STATEITEM_NOTFOUND, ESMF_FieldWrite
use ESMF, only: operator(==), operator(/=), operator(+), operator(-)
Expand Down Expand Up @@ -134,6 +134,7 @@ module MOM_cap_mod
integer :: logunit !< stdout logging unit number
logical :: profile_memory = .true.
logical :: grid_attach_area = .false.
logical :: use_coldstart = .true.
character(len=128) :: scalar_field_name = ''
integer :: scalar_field_count = 0
integer :: scalar_field_idx_grid_nx = 0
Expand All @@ -148,7 +149,7 @@ module MOM_cap_mod
logical :: cesm_coupled = .false.
type(ESMF_GeomType_Flag) :: geomtype = ESMF_GEOMTYPE_GRID
#endif
character(len=8) :: restart_mode = 'cmeps'
character(len=8) :: restart_mode = 'alarms'

contains

Expand Down Expand Up @@ -338,6 +339,14 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc)
call ESMF_LogWrite('MOM_cap:ScalarFieldIdxGridNY = '//trim(logmsg), ESMF_LOGMSG_INFO)
endif

use_coldstart = .true.
call NUOPC_CompAttributeGet(gcomp, name="use_coldstart", value=value, &
isPresent=isPresent, isSet=isSet, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (isPresent .and. isSet) use_coldstart=(trim(value)=="true")
write(logmsg,*) use_coldstart
call ESMF_LogWrite('MOM_cap:use_coldstart = '//trim(logmsg), ESMF_LOGMSG_INFO)

end subroutine

!> Called by NUOPC to advertise import and export fields. "Advertise"
Expand Down Expand Up @@ -389,6 +398,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
integer :: iostat
integer :: readunit
character(len=512) :: restartfile ! Path/Name of restart file
character(len=2048) :: restartfiles ! Path/Name of restart files
! (same as restartfile if single restart file)
character(len=*), parameter :: subname='(MOM_cap:InitializeAdvertise)'
character(len=32) :: calendar
!--------------------------------
Expand Down Expand Up @@ -420,6 +431,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
CALL ESMF_TimeIntervalGet(TINT, S=DT_OCEAN, RC=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

!TODO: next two lines not present in NCAR
call fms_init(mpi_comm_mom)
call constants_init
call field_manager_init
Expand Down Expand Up @@ -527,24 +539,24 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
call ESMF_LogWrite('MOM_cap:startup = '//trim(runtype), ESMF_LOGMSG_INFO)
endif

restartfile = ""
restartfile = ""; restartfiles = ""
if (runtype == "initial") then
if (cesm_coupled) then
restartfile = "n"
restartfiles = "n"
else
call get_MOM_input(dirs=dirs)
restartfile = dirs%input_filename(1:1)
restartfiles = dirs%input_filename(1:1)
endif
call ESMF_LogWrite('MOM_cap:restartfile = '//trim(restartfile), ESMF_LOGMSG_INFO)
call ESMF_LogWrite('MOM_cap:restartfile = '//trim(restartfiles), ESMF_LOGMSG_INFO)

else if (runtype == "continue") then ! hybrid or branch or continuos runs

if (cesm_coupled) then
call ESMF_LogWrite('MOM_cap: restart requested, using rpointer.ocn', ESMF_LOGMSG_WARNING)
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_VMGet(vm, localPet=localPet, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (localPet == 0) then
! this hard coded for rpointer.ocn right now
Expand All @@ -554,25 +566,36 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
line=__LINE__, file=u_FILE_u, rcToReturn=rc)
return
endif
read(readunit,'(a)', iostat=iostat) restartfile
if (iostat /= 0) then
call ESMF_LogSetError(ESMF_RC_FILE_READ, msg=subname//' ERROR reading rpointer.ocn', &
line=__LINE__, file=u_FILE_u, rcToReturn=rc)
return
endif
do
read(readunit,'(a)', iostat=iostat) restartfile
if (iostat /= 0) then
if (len(trim(restartfiles))>1 .and. iostat<0) then
exit ! done reading restart files list.
else
call ESMF_LogSetError(ESMF_RC_FILE_READ, msg=subname//' ERROR reading rpointer.ocn', &
line=__LINE__, file=u_FILE_u, rcToReturn=rc)
return
endif
endif
! check if the length of restartfiles variable is sufficient:
if (len(restartfiles)-len(trim(restartfiles)) < len(trim(restartfile))) then
call MOM_error(FATAL, "Restart file name(s) too long.")
endif
restartfiles = trim(restartfiles) // " " // trim(restartfile)
enddo
close(readunit)
endif
! broadcast attribute set on master task to all tasks
call ESMF_VMBroadcast(vm, restartfile, count=ESMF_MAXSTR-1, rootPet=0, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
call ESMF_VMBroadcast(vm, restartfiles, count=len(restartfiles), rootPet=0, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
call ESMF_LogWrite('MOM_cap: restart requested, use input.nml', ESMF_LOGMSG_WARNING)
endif

endif

ocean_public%is_ocean_pe = .true.
call ocean_model_init(ocean_public, ocean_state, time0, time_start, input_restart_file=trim(restartfile))
call ocean_model_init(ocean_public, ocean_state, time0, time_start, input_restart_file=trim(restartfiles))

call ocean_model_init_sfc(ocean_state, ocean_public)

Expand Down Expand Up @@ -1250,9 +1273,9 @@ subroutine DataInitialize(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_ClockGet(clock, currTime=currTime, timeStep=timeStep, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeGet(currTime, timestring=timestr, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_GridCompGetInternalState(gcomp, ocean_internalstate, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
Expand Down Expand Up @@ -1349,10 +1372,12 @@ subroutine ModelAdvance(gcomp, rc)
integer :: writeunit
integer :: localPet
type(ESMF_VM) :: vm
integer :: n
integer :: n, i
character(240) :: import_timestr, export_timestr
character(len=128) :: fldname
character(len=*),parameter :: subname='(MOM_cap:ModelAdvance)'
character(len=8) :: suffix
integer :: num_rest_files

rc = ESMF_SUCCESS
if(profile_memory) call ESMF_VMLogMemInfo("Entering MOM Model_ADVANCE: ")
Expand Down Expand Up @@ -1390,7 +1415,7 @@ subroutine ModelAdvance(gcomp, rc)
! Apply ocean lag for startup runs:
!---------------

if (cesm_coupled) then
if (cesm_coupled .or. (.not.use_coldstart)) then
if (trim(runtype) == "initial") then

! Do not call MOM6 timestepping routine if the first cpl tstep of a startup run
Expand Down Expand Up @@ -1489,55 +1514,42 @@ subroutine ModelAdvance(gcomp, rc)
!---------------

call ESMF_ClockGetAlarm(clock, alarmname='stop_alarm', alarm=stop_alarm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return

!---------------
! If restart alarm exists and is ringing - write restart file
!---------------

if (restart_mode == 'cmeps') then
if (restart_mode == 'alarms') then
call ESMF_ClockGetAlarm(clock, alarmname='restart_alarm', alarm=restart_alarm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (ESMF_AlarmIsRinging(restart_alarm, rc=rc)) then
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! turn off the alarm
call ESMF_AlarmRingerOff(restart_alarm, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! determine restart filename
call ESMF_ClockGetNextTime(clock, MyTime, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeGet (MyTime, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc )
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (cesm_coupled) then
call NUOPC_CompAttributeGet(gcomp, name='case_name', value=casename, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_VMGet(vm, localPet=localPet, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

write(restartname,'(A,".mom6.r.",I4.4,"-",I2.2,"-",I2.2,"-",I5.5)') &
trim(casename), year, month, day, seconds
call ESMF_LogWrite("MOM_cap: Writing restart : "//trim(restartname), ESMF_LOGMSG_INFO)
! write restart file(s)
call ocean_model_restart(ocean_state, restartname=restartname, num_rest_files=num_rest_files)
if (localPet == 0) then
! Write name of restart file in the rpointer file - this is currently hard-coded for the ocean
open(newunit=writeunit, file='rpointer.ocn', form='formatted', status='unknown', iostat=iostat)
Expand All @@ -1547,27 +1559,38 @@ subroutine ModelAdvance(gcomp, rc)
return
endif
write(writeunit,'(a)') trim(restartname)//'.nc'
if (num_rest_files > 1) then
! append i.th restart file name to rpointer
do i=1, num_rest_files-1
if (i < 10) then
write(suffix,'("_",I1)') i
else
write(suffix,'("_",I2)') i
endif
write(writeunit,'(a)') trim(restartname) // trim(suffix) // '.nc'
enddo
endif
close(writeunit)
endif
else
else ! not cesm_coupled
! write the final restart without a timestamp
if (ESMF_AlarmIsRinging(stop_alarm, rc=rc)) then
write(restartname,'(A)')"MOM.res"
else
write(restartname,'(A,I4.4,"-",I2.2,"-",I2.2,"-",I2.2,"-",I2.2,"-",I2.2)') &
"MOM.res.", year, month, day, hour, minute, seconds
endif
end if
call ESMF_LogWrite("MOM_cap: Writing restart : "//trim(restartname), ESMF_LOGMSG_INFO)
call ESMF_LogWrite("MOM_cap: Writing restart : "//trim(restartname), ESMF_LOGMSG_INFO)

! write restart file(s)
call ocean_model_restart(ocean_state, restartname=restartname)
! write restart file(s)
call ocean_model_restart(ocean_state, restartname=restartname)
endif

if (is_root_pe()) then
write(logunit,*) subname//' writing restart file ',trim(restartname)
endif
endif
end if ! end of restart_mode is cmeps
endif
end if ! restart_mode

!---------------
! Write diagnostics
Expand Down Expand Up @@ -1694,8 +1717,7 @@ subroutine ModelSetRunClock(gcomp, rc)
else
call NUOPC_CompAttributeGet(gcomp, name="restart_n", value=cvalue, &
isPresent=isPresent, isSet=isSet, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! If restart_n is set and non-zero, then restart_option must be available from config
if (isPresent .and. isSet) then
Expand All @@ -1704,8 +1726,7 @@ subroutine ModelSetRunClock(gcomp, rc)
if(restart_n /= 0)then
call NUOPC_CompAttributeGet(gcomp, name="restart_option", value=cvalue, &
isPresent=isPresent, isSet=isSet, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (isPresent .and. isSet) then
read(cvalue,*) restart_option
call ESMF_LogWrite(subname//" Restart_option = "//restart_option, &
Expand All @@ -1720,51 +1741,39 @@ subroutine ModelSetRunClock(gcomp, rc)
! not used in nems
call NUOPC_CompAttributeGet(gcomp, name="restart_ymd", value=cvalue, &
isPresent=isPresent, isSet=isSet, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (isPresent .and. isSet) then
read(cvalue,*) restart_ymd
call ESMF_LogWrite(subname//" Restart_ymd = "//trim(cvalue), ESMF_LOGMSG_INFO)
endif
else
! restart_n is zero, restart_mode will be nems
restart_mode = 'nems'
call ESMF_LogWrite(subname//" Set restart_mode to nems", ESMF_LOGMSG_INFO)
! restart_n is zero, restarts will be written at finalize only (no alarm control)
restart_mode = 'no_alarms'
call ESMF_LogWrite(subname//" Restarts will be written at finalize only", ESMF_LOGMSG_INFO)
endif
else
! restart_n is not set, restart_mode will be nems
restart_mode = 'nems'
call ESMF_LogWrite(subname//" Set restart_mode to nems", ESMF_LOGMSG_INFO)
endif
endif

if (restart_mode == 'cmeps') then
if (restart_mode == 'alarms') then
call AlarmInit(mclock, &
alarm = restart_alarm, &
option = trim(restart_option), &
opt_n = restart_n, &
opt_ymd = restart_ymd, &
RefTime = mcurrTime, &
alarmname = 'restart_alarm', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_AlarmSet(restart_alarm, clock=mclock, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, &
file=__FILE__)) &
return ! bail out
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_LogWrite(subname//" Restart alarm is Created and Set", ESMF_LOGMSG_INFO)
end if

! create a 1-shot alarm at the driver stop time
stop_alarm = ESMF_AlarmCreate(mclock, ringtime=dstopTime, name = "stop_alarm", rc=rc)
call ESMF_LogWrite(subname//" Create Stop alarm", ESMF_LOGMSG_INFO)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, &
line=__LINE__, file=__FILE__)) return

if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_TimeGet(dstoptime, timestring=timestr, rc=rc)
call ESMF_LogWrite("Stop Alarm will ring at : "//trim(timestr), ESMF_LOGMSG_INFO)

Expand Down Expand Up @@ -1822,8 +1831,8 @@ subroutine ocean_model_finalize(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
Time = esmf2fms_time(currTime)

! Do not write a restart unless mode is nems
if (restart_mode == 'nems') then
! Do not write a restart unless mode is no_alarms
if (restart_mode == 'no_alarms') then
write_restart = .true.
else
write_restart = .false.
Expand Down
Loading

0 comments on commit eb58a2e

Please sign in to comment.