Skip to content

Commit

Permalink
Merge pull request #280 from ESCOMP/feature/update_docn
Browse files Browse the repository at this point in the history
add new multilevel ocean stream input
  • Loading branch information
jedwards4b committed May 14, 2024
2 parents 7476950 + 0f7e6c6 commit 4a745b8
Show file tree
Hide file tree
Showing 14 changed files with 746 additions and 157 deletions.
4 changes: 2 additions & 2 deletions dglc/cime_config/config_component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</desc>
</entry>

<entry id="DGLC_USE_GREENLAND">
<entry id="GLC_USE_GREENLAND">
<type>logical</type>
<default_value>FALSE</default_value>
<group>run_component_dglc</group>
Expand All @@ -58,7 +58,7 @@
</desc>
</entry>

<entry id="DGLC_USE_ANTARCTICA">
<entry id="GLC_USE_ANTARCTICA">
<type>logical</type>
<default_value>FALSE</default_value>
<group>run_component_dglc</group>
Expand Down
6 changes: 3 additions & 3 deletions dglc/cime_config/testdefs/testlist_dglc.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<testlist version="2.0">

<test compset="2000_SATM_SLND_SICE_SGLC_SROF_DGLC%NOEVOLVE_SWAV" grid="f10_f10_ais8gris4_mg37" name="SMS_Ln5">
<test compset="2000_SATM_SLND_SICE_SGLC_SROF_DGLC%NOEVOLVE_SWAV" grid="f10_f10_ais8gris4_mg37" name="SMS_Ly3">
<machines>
<machine name="derecho" compiler="intel" category="aux_cdeps"/>
<machine name="betzy" compiler="intel" category="aux_cdeps_noresm"/>
Expand All @@ -10,7 +10,7 @@
<option name="wallclock"> 00:10:00 </option>
</options>
</test>
<test compset="2000_SATM_SLND_SICE_SGLC_SROF_DGLC%NOEVOLVE_SWAV" grid="f10_f10_ais8_mg37" name="SMS_Ln5">
<test compset="2000_SATM_SLND_SICE_SGLC_SROF_DGLC%NOEVOLVE_SWAV" grid="f10_f10_ais8_mg37" name="SMS_Ly3">
<machines>
<machine name="derecho" compiler="intel" category="aux_cdeps"/>
<machine name="betzy" compiler="intel" category="aux_cdeps_noresm"/>
Expand All @@ -19,7 +19,7 @@
<option name="wallclock"> 00:10:00 </option>
</options>
</test>
<test compset="2000_SATM_SLND_SICE_SGLC_SROF_DGLC%NOEVOLVE_SWAV" grid="f19_g17_gris4" name="SMS_Ln5">
<test compset="2000_SATM_SLND_SICE_SGLC_SROF_DGLC%NOEVOLVE_SWAV" grid="f19_g17_gris4" name="SMS_Ly3">
<machines>
<machine name="derecho" compiler="intel" category="aux_cdeps"/>
<machine name="betzy" compiler="intel" category="aux_cdeps_noresm"/>
Expand Down
272 changes: 151 additions & 121 deletions dglc/dglc_datamode_noevolve_mod.F90

Large diffs are not rendered by default.

199 changes: 184 additions & 15 deletions dglc/glc_comp_nuopc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ module cdeps_dglc_comp
!----------------------------------------------------------------------------
use ESMF , only : ESMF_VM, ESMF_VmGet, ESMF_VMBroadcast, ESMF_GridCompGet
use ESMF , only : ESMF_Mesh, ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_Time
use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE
use ESMF , only : ESMF_TraceRegionEnter, ESMF_TraceRegionExit, ESMF_ClockGet
use ESMF , only : ESMF_TimeGet, ESMF_TimeInterval, ESMF_Field, ESMF_MAXSTR
use ESMF , only : ESMF_Alarm, ESMF_MethodRemove, ESMF_MethodAdd
use ESMF , only : ESMF_GridCompSetEntryPoint, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging
use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_METHOD_INITIALIZE
use ESMF , only : ESMF_TraceRegionEnter, ESMF_TraceRegionExit
use ESMF , only : ESMF_TimeGet, ESMF_TimeInterval, ESMF_TimeIntervalGet, ESMF_Field, ESMF_MAXSTR
use ESMF , only : ESMF_MethodRemove, ESMF_MethodAdd
use ESMF , only : ESMF_GridCompSetEntryPoint
use ESMF , only : ESMF_Alarm, ESMF_AlarmSet, ESMF_AlarmIsRinging, ESMF_ALARMLIST_ALL
use ESMF , only : ESMF_ClockGet, ESMF_ClockSet, ESMF_ClockAdvance, ESMF_ClockGetAlarm, ESMF_ClockGetAlarmList
use ESMF , only : ESMF_StateGet, operator(+), ESMF_AlarmRingerOff, ESMF_LogWrite
use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_VmLogMemInfo
use ESMF , only : ESMF_MeshCreate, ESMF_FILEFORMAT_ESMFMESH
Expand All @@ -35,7 +37,7 @@ module cdeps_dglc_comp
#endif
use dshr_methods_mod , only : dshr_state_diagnose, chkerr, memcheck
use dshr_strdata_mod , only : shr_strdata_type, shr_strdata_advance, shr_strdata_init_from_config
use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init
use dshr_mod , only : dshr_model_initphase, dshr_init, dshr_mesh_init, dshr_alarm_init
use dshr_mod , only : dshr_state_setscalar, dshr_set_runclock, dshr_check_restart_alarm
use dshr_dfield_mod , only : dfield_type, dshr_dfield_add, dshr_dfield_copy
use dshr_fldlist_mod , only : fldlist_type, dshr_fldlist_realize
Expand All @@ -52,6 +54,7 @@ module cdeps_dglc_comp
public :: SetVM
private :: InitializeAdvertise
private :: InitializeRealize
private :: ModelSetRunClock
private :: ModelAdvance
private :: dglc_comp_run
private :: ModelFinalize
Expand Down Expand Up @@ -157,7 +160,9 @@ subroutine SetServices(gcomp, rc)

call ESMF_MethodRemove(gcomp, label=model_label_SetRunClock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call NUOPC_CompSpecialize(gcomp, specLabel=model_label_SetRunClock, specRoutine=dshr_set_runclock, rc=rc)
! The following specialization does not use dshr_set_runclock since we also need to add an alarm
! to determine if the model inputs are valid
call NUOPC_CompSpecialize(gcomp, specLabel=model_label_SetRunClock, specRoutine=ModelSetRunClock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call NUOPC_CompSpecialize(gcomp, specLabel=model_label_Finalize, specRoutine=ModelFinalize, rc=rc)
Expand Down Expand Up @@ -425,7 +430,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc)
end do ! end loop over ice sheets

! Run dglc
call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., rc=rc)
call dglc_comp_run(clock, current_ymd, current_tod, restart_write=.false., valid_inputs=.true., rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_TraceRegionExit('dglc_strdata_init')
Expand All @@ -450,10 +455,12 @@ subroutine ModelAdvance(gcomp, rc)
integer :: mon ! month
integer :: day ! day in month
logical :: restart_write
type(ESMF_Alarm) :: valid_alarm
logical :: valid_inputs ! if true, inputs from mediator are valid
character(len=CS) :: timestring
character(len=*),parameter :: subname=trim(module_name)//':(ModelAdvance) '
!-------------------------------------------------------------------------------


rc = ESMF_SUCCESS
call shr_log_setLogUnit(logunit)

Expand All @@ -463,26 +470,41 @@ subroutine ModelAdvance(gcomp, rc)
call NUOPC_ModelGet(gcomp, modelClock=clock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! For nuopc - the component clock is advanced at the end of the time interval
! Determine if inputs from mediator are valid
call ESMF_ClockGetAlarm(clock, alarmname='alarm_valid_inputs', alarm=valid_alarm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (ESMF_AlarmIsRinging(valid_alarm, rc=rc)) then
valid_inputs = .true.
call ESMF_AlarmRingerOff( valid_alarm, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
valid_inputs = .false.
endif

! Need to advance nuopc one timestep ahead for shr_strdata time interpolation
call ESMF_ClockGet( clock, currTime=currTime, timeStep=timeStep, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
nextTime = currTime + timeStep
call ESMF_TimeGet( nextTime, yy=yr, mm=mon, dd=day, s=next_tod, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call shr_cal_ymd2date(yr, mon, day, next_ymd)
if (my_task == main_task) then
call ESMF_TimeGet(currTime, timestring=timestring, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
write(logunit,'(a,l)') trim(timestring)//': valid_input for dglc is ',valid_inputs
end if

! determine if will write restart
restart_write = dshr_check_restart_alarm(clock, rc=rc)

! run dglc
call dglc_comp_run(clock, next_ymd, next_tod, restart_write, rc=rc)
call dglc_comp_run(clock, next_ymd, next_tod, restart_write, valid_inputs, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end subroutine ModelAdvance

!===============================================================================
subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc)
subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, valid_inputs, rc)

! --------------------------
! advance dglc
Expand All @@ -493,6 +515,7 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc)
integer , intent(in) :: target_ymd ! model date
integer , intent(in) :: target_tod ! model sec into model date
logical , intent(in) :: restart_write
logical , intent(in) :: valid_inputs
integer , intent(out) :: rc

! local variables
Expand Down Expand Up @@ -565,9 +588,11 @@ subroutine dglc_comp_run(clock, target_ymd, target_tod, restart_write, rc)
! Perform data mode specific calculations
select case (trim(datamode))
case('noevolve')
call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, &
model_meshes, model_internal_gridsize, model_datafiles, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (valid_inputs) then
call dglc_datamode_noevolve_advance(sdat(1)%pio_subsystem, sdat(1)%io_type, sdat(1)%io_format, &
model_meshes, model_internal_gridsize, model_datafiles, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
end if
end select

! Write restarts if needed
Expand Down Expand Up @@ -632,6 +657,150 @@ end subroutine dglc_init_dfields

end subroutine dglc_comp_run

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

subroutine ModelSetRunClock(gcomp, rc)

! input/output variables
type(ESMF_GridComp) :: gcomp
integer, intent(out) :: rc

! local variables
type(ESMF_Clock) :: mclock, dclock
type(ESMF_Time) :: mcurrtime, dcurrtime
type(ESMF_Time) :: mstoptime
type(ESMF_TimeInterval) :: mtimestep, dtimestep
character(len=256) :: cvalue
character(len=256) :: restart_option ! Restart option units
integer :: restart_n ! Number until restart interval
integer :: restart_ymd ! Restart date (YYYYMMDD)
type(ESMF_ALARM) :: restart_alarm
character(len=256) :: stop_option ! Stop option units
integer :: stop_n ! Number until stop interval
integer :: stop_ymd ! Stop date (YYYYMMDD)
type(ESMF_ALARM) :: stop_alarm
integer :: alarmcount
character(len=CS) :: glc_avg_period ! averaging period in mediator
type(ESMF_ALARM) :: valid_alarm ! model alarm
integer :: dtime
character(len=*),parameter :: subname='glc_comp_nuopc:(dglc_set_runclock) '
!-------------------------------------------------------------------------------

rc = ESMF_SUCCESS

! query the Component for its clocks
call NUOPC_ModelGet(gcomp, driverClock=dclock, modelClock=mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_ClockGet(dclock, currTime=dcurrtime, timeStep=dtimestep, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_ClockGet(mclock, currTime=mcurrtime, timeStep=mtimestep, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! force model clock currtime and timestep to match driver and set stoptime
mstoptime = mcurrtime + dtimestep
call ESMF_ClockSet(mclock, currTime=dcurrtime, timeStep=dtimestep, stopTime=mstoptime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! determine number of alarms
call ESMF_ClockGetAlarmList(mclock, alarmlistflag=ESMF_ALARMLIST_ALL, alarmCount=alarmCount, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (alarmCount == 0) then

!----------------
! glc valid input alarm
!----------------
call NUOPC_CompAttributeGet(gcomp, name="glc_avg_period", value=glc_avg_period, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

if (trim(glc_avg_period) == 'hour') then
call dshr_alarm_init(mclock, valid_alarm, 'nhours', opt_n=1, alarmname='alarm_valid_inputs', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else if (trim(glc_avg_period) == 'day') then
call dshr_alarm_init(mclock, valid_alarm, 'ndays' , opt_n=1, alarmname='alarm_valid_inputs', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else if (trim(glc_avg_period) == 'yearly') then
call dshr_alarm_init(mclock, valid_alarm, 'yearly', alarmname='alarm_valid_inputs', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else if (trim(glc_avg_period) == 'glc_coupling_period') then
call ESMF_TimeIntervalGet(mtimestep, s=dtime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call dshr_alarm_init(mclock, valid_alarm, 'nseconds', opt_n=dtime, alarmname='alarm_valid_inputs', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
else
call ESMF_LogWrite(trim(subname)// ": ERROR glc_avg_period = "//trim(glc_avg_period)//" not supported", &
ESMF_LOGMSG_INFO, rc=rc)
rc = ESMF_FAILURE
RETURN
end if

call ESMF_AlarmSet(valid_alarm, clock=mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

!----------------
! Restart alarm
!----------------
call ESMF_LogWrite(subname//'setting restart alarm for dglc' , ESMF_LOGMSG_INFO)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call NUOPC_CompAttributeGet(gcomp, name="restart_option", value=restart_option, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call NUOPC_CompAttributeGet(gcomp, name="restart_n", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) restart_n

call NUOPC_CompAttributeGet(gcomp, name="restart_ymd", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) restart_ymd

call dshr_alarm_init(mclock, restart_alarm, restart_option, &
opt_n = restart_n, &
opt_ymd = restart_ymd, &
RefTime = mcurrTime, &
alarmname = 'alarm_restart', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_AlarmSet(restart_alarm, clock=mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

!----------------
! Stop alarm
!----------------
call ESMF_LogWrite(subname//'setting stop alarm for dglc' , ESMF_LOGMSG_INFO)
call NUOPC_CompAttributeGet(gcomp, name="stop_option", value=stop_option, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call NUOPC_CompAttributeGet(gcomp, name="stop_n", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) stop_n

call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) stop_ymd

call dshr_alarm_init(mclock, stop_alarm, stop_option, &
opt_n = stop_n, &
opt_ymd = stop_ymd, &
RefTime = mcurrTime, &
alarmname = 'alarm_stop', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_AlarmSet(stop_alarm, clock=mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end if

! Advance model clock to trigger alarms then reset model clock back to currtime
call ESMF_ClockAdvance(mclock,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_ClockSet(mclock, currTime=dcurrtime, timeStep=dtimestep, stopTime=mstoptime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end subroutine ModelSetRunClock

!===============================================================================
subroutine ModelFinalize(gcomp, rc)
type(ESMF_GridComp) :: gcomp
Expand Down
1 change: 1 addition & 0 deletions docn/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(SRCFILES ocn_comp_nuopc.F90
docn_datamode_aquaplanet_mod.F90
docn_datamode_iaf_mod.F90
docn_datamode_cplhist_mod.F90
docn_datamode_multilev_mod.F90
docn_import_data_mod.F90)

foreach(FILE ${SRCFILES})
Expand Down
6 changes: 4 additions & 2 deletions docn/cime_config/config_component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
This file may have ocn desc entries.
-->
<description modifier_mode="1">
<desc ocn="DOCN[%DOM][%SOM][%SOMAQP][%IAF][%SST_AQUAP][%AQP1][%AQP2][%AQP3][%AQP4][%AQP5][%AQP6][%AQP7][%AQP8][%AQP9][%AQP10][%AQPFILE][%AQPCONST][%CPLHIST]">DOCN </desc>
<desc ocn="DOCN[%DOM][%SOM][%SOMAQP][%IAF][%SST_AQUAP][%AQP1][%AQP2][%AQP3][%AQP4][%AQP5][%AQP6][%AQP7][%AQP8][%AQP9][%AQP10][%AQPFILE][%AQPCONST][%CPLHIST][%MULTILEV]">DOCN </desc>
<desc option="DOM"> prescribed ocean mode</desc>
<desc option="SOM"> slab ocean mode</desc>
<desc option="SOMAQP"> aquaplanet slab ocean mode</desc>
Expand All @@ -32,6 +32,7 @@
<desc option="AQPFILE"> file input aquaplanet sst </desc>
<desc option="AQPCONST"> globally constant SST for idealized experiments, such as RCE </desc>
<desc option="CPLHIST"> mediator history output for ocean fields imported to mediator </desc>
<desc option="MULTILEV"> input stream files have multi level data</desc>
</description>

<entry id="COMP_OCN">
Expand All @@ -45,7 +46,7 @@

<entry id="DOCN_MODE">
<type>char</type>
<valid_values>prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,cplhist</valid_values>
<valid_values>prescribed,sst_aquap1,sst_aquap2,sst_aquap3,sst_aquap4,sst_aquap5,sst_aquap6,sst_aquap7,sst_aquap8,sst_aquap9,sst_aquap10,sst_aquapfile,som,som_aquap,sst_aquap_constant,interannual,cplhist,multilev</valid_values>
<default_value>prescribed</default_value>
<values match="last">
<value compset="_DOCN%DOM_" >prescribed</value>
Expand All @@ -65,6 +66,7 @@
<value compset="_DOCN%AQPFILE_">sst_aquapfile</value>
<value compset="_DOCN%AQPCONST_">sst_aquap_constant</value>
<value compset="_DOCN%CPLHIST">cplhist</value>
<value compset="_DOCN%MULTILEV">multilev</value>
</values>
<group>run_component_docn</group>
<file>env_run.xml</file>
Expand Down
Loading

0 comments on commit 4a745b8

Please sign in to comment.