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

add ocean lag option, make cap consistent #33

Merged
merged 6 commits into from
Sep 9, 2020
Merged
Show file tree
Hide file tree
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
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