Skip to content

Commit

Permalink
Extend restart output controls, provide multiple frequency options (C…
Browse files Browse the repository at this point in the history
…ICE-Consortium#850)

* Extend restart output controls, provide multiple streams for possible
output frequencies.  Convert dumpfreq, dumpfreq_n, dumpfreq_base to
arrays.

Modify histfreq_base to make it an array as well.  Now each history stream
can have it's own base time (init or zero).

Update documentation.

* Clean up implementation and documentation

* Update PR to check github actions
  • Loading branch information
apcraig authored and TillRasmussen committed Sep 16, 2023
1 parent d2d7635 commit 493de4f
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 85 deletions.
69 changes: 35 additions & 34 deletions cicecore/cicedyn/general/ice_init.F90
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ subroutine input_data
histfreq(4) = 'm' ! output frequency option for different streams
histfreq(5) = 'y' ! output frequency option for different streams
histfreq_n(:) = 1 ! output frequency
histfreq_base = 'zero' ! output frequency reference date
histfreq_base(:) = 'zero' ! output frequency reference date
hist_avg(:) = .true. ! if true, write time-averages (not snapshots)
history_format = 'default' ! history file format
hist_time_axis = 'end' ! History file time axis averaging interval position
Expand All @@ -334,9 +334,11 @@ subroutine input_data
cpl_bgc = .false. ! couple bgc thru driver
incond_dir = history_dir ! write to history dir for default
incond_file = 'iceh_ic'! file prefix
dumpfreq='y' ! restart frequency option
dumpfreq_n = 1 ! restart frequency
dumpfreq_base = 'init' ! restart frequency reference date
dumpfreq(:)='x' ! restart frequency option
dumpfreq_n(:) = 1 ! restart frequency
dumpfreq_base(:) = 'init' ! restart frequency reference date
dumpfreq(1)='y' ! restart frequency option
dumpfreq_n(1) = 1 ! restart frequency
dump_last = .false. ! write restart on last time step
restart_dir = './' ! write to executable dir for default
restart_file = 'iced' ! restart file name prefix
Expand Down Expand Up @@ -901,10 +903,13 @@ subroutine input_data
call broadcast_scalar(diag_file, master_task)
do n = 1, max_nstrm
call broadcast_scalar(histfreq(n), master_task)
call broadcast_scalar(histfreq_base(n), master_task)
call broadcast_scalar(dumpfreq(n), master_task)
call broadcast_scalar(dumpfreq_base(n), master_task)
enddo
call broadcast_array(histfreq_n, master_task)
call broadcast_scalar(histfreq_base, master_task)
call broadcast_array(hist_avg, master_task)
call broadcast_array(histfreq_n, master_task)
call broadcast_array(dumpfreq_n, master_task)
call broadcast_scalar(history_dir, master_task)
call broadcast_scalar(history_file, master_task)
call broadcast_scalar(history_precision, master_task)
Expand All @@ -914,9 +919,6 @@ subroutine input_data
call broadcast_scalar(cpl_bgc, master_task)
call broadcast_scalar(incond_dir, master_task)
call broadcast_scalar(incond_file, master_task)
call broadcast_scalar(dumpfreq, master_task)
call broadcast_scalar(dumpfreq_n, master_task)
call broadcast_scalar(dumpfreq_base, master_task)
call broadcast_scalar(dump_last, master_task)
call broadcast_scalar(restart_file, master_task)
call broadcast_scalar(restart, master_task)
Expand Down Expand Up @@ -1569,33 +1571,32 @@ subroutine input_data
abort_list = trim(abort_list)//":22"
endif

if(histfreq_base /= 'init' .and. histfreq_base /= 'zero') then
write (nu_diag,*) subname//' ERROR: bad value for histfreq_base, allowed values: init, zero'
abort_list = trim(abort_list)//":24"
endif
do n = 1,max_nstrm
if(histfreq_base(n) /= 'init' .and. histfreq_base(n) /= 'zero') then
write (nu_diag,*) subname//' ERROR: bad value for histfreq_base, allowed values: init, zero: '//trim(histfreq_base(n))
abort_list = trim(abort_list)//":24"
endif

if(dumpfreq_base(n) /= 'init' .and. dumpfreq_base(n) /= 'zero') then
write (nu_diag,*) subname//' ERROR: bad value for dumpfreq_base, allowed values: init, zero: '//trim(dumpfreq_base(n))
abort_list = trim(abort_list)//":25"
endif

if (.not.(scan(dumpfreq(n)(1:1),'ymdhx1YMDHX') == 1 .and. (dumpfreq(n)(2:2) == '1' .or. dumpfreq(n)(2:2) == ' '))) then
if (my_task == master_task) then
write(nu_diag,*) subname//' WARNING: unrecognized dumpfreq=', trim(dumpfreq(n))
write(nu_diag,*) subname//' WARNING: No restarts files will be written for this stream'
write(nu_diag,*) subname//' WARNING: Allowed values : y,m,d,h,x,1 followed by an optional 1'
endif
dumpfreq(n) = 'x'
endif
enddo

if(trim(hist_time_axis) /= 'begin' .and. trim(hist_time_axis) /= 'middle' .and. trim(hist_time_axis) /= 'end') then
write (nu_diag,*) subname//' ERROR: hist_time_axis value not valid = '//trim(hist_time_axis)
abort_list = trim(abort_list)//":29"
endif

if(dumpfreq_base /= 'init' .and. dumpfreq_base /= 'zero') then
write (nu_diag,*) subname//' ERROR: bad value for dumpfreq_base, allowed values: init, zero'
abort_list = trim(abort_list)//":25"
endif

if (.not.(trim(dumpfreq) == 'y' .or. trim(dumpfreq) == 'Y' .or. &
trim(dumpfreq) == 'm' .or. trim(dumpfreq) == 'M' .or. &
trim(dumpfreq) == 'd' .or. trim(dumpfreq) == 'D' .or. &
trim(dumpfreq) == 'h' .or. trim(dumpfreq) == 'H' .or. &
trim(dumpfreq) == '1' )) then
if (my_task == master_task) then
write(nu_diag,*) subname//' WARNING: unrecognized dumpfreq=', trim(dumpfreq)
write(nu_diag,*) subname//' WARNING: No restarts files will be written'
write(nu_diag,*) subname//' WARNING: Allowed values : ''y'', ''m'', ''d'', ''h'', ''1'''
endif
endif

! Implicit solver input validation
if (kdyn == 3) then
if (.not. (trim(algo_nonlin) == 'picard' .or. trim(algo_nonlin) == 'anderson')) then
Expand Down Expand Up @@ -2323,7 +2324,7 @@ subroutine input_data
write(nu_diag,1021) ' numax = ', numax
write(nu_diag,1033) ' histfreq = ', histfreq(:)
write(nu_diag,1023) ' histfreq_n = ', histfreq_n(:)
write(nu_diag,1031) ' histfreq_base = ', trim(histfreq_base)
write(nu_diag,1033) ' histfreq_base = ', histfreq_base(:)
write(nu_diag,*) ' hist_avg = ', hist_avg(:)
write(nu_diag,1031) ' history_dir = ', trim(history_dir)
write(nu_diag,1031) ' history_file = ', trim(history_file)
Expand All @@ -2334,9 +2335,9 @@ subroutine input_data
write(nu_diag,1039) ' Initial condition will be written in ', &
trim(incond_dir)
endif
write(nu_diag,1031) ' dumpfreq = ', trim(dumpfreq)
write(nu_diag,1021) ' dumpfreq_n = ', dumpfreq_n
write(nu_diag,1031) ' dumpfreq_base = ', trim(dumpfreq_base)
write(nu_diag,1033) ' dumpfreq = ', dumpfreq(:)
write(nu_diag,1023) ' dumpfreq_n = ', dumpfreq_n(:)
write(nu_diag,1033) ' dumpfreq_base = ', dumpfreq_base(:)
write(nu_diag,1011) ' dump_last = ', dump_last
write(nu_diag,1011) ' restart = ', restart
write(nu_diag,1031) ' restart_dir = ', trim(restart_dir)
Expand Down
4 changes: 2 additions & 2 deletions cicecore/cicedyn/infrastructure/io/io_netcdf/ice_restart.F90
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ end subroutine write_restart_field

subroutine final_restart()

use ice_calendar, only: istep1, idate
use ice_calendar, only: istep1, myear, mmonth, mday, msec

integer (kind=int_kind) :: status

Expand All @@ -833,7 +833,7 @@ subroutine final_restart()
status = nf90_close(ncid)

if (my_task == master_task) &
write(nu_diag,*) 'Restart read/written ',istep1,idate
write(nu_diag,'(a,i8,4x,i4.4,a,i2.2,a,i2.2,a,i5.5)') 'Restart read/written ',istep1,myear,'-',mmonth,'-',mday,'-',msec

#else
call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined', &
Expand Down
9 changes: 5 additions & 4 deletions cicecore/cicedyn/infrastructure/io/io_pio2/ice_restart.F90
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ subroutine init_restart_read(ice_ic)
! endif

if (my_task == master_task) then
write(nu_diag,*) 'Restart read at istep=',istep0,myear,mmonth,mday,msec
write(nu_diag,'(a,i8,4x,i4.4,a,i2.2,a,i2.2,a,i5.5)') 'Restart read at istep=',istep0,myear,'-',mmonth,'-',mday,'-',msec
endif

call broadcast_scalar(istep0,master_task)
Expand Down Expand Up @@ -880,16 +880,17 @@ end subroutine write_restart_field

subroutine final_restart()

use ice_calendar, only: istep1, idate, msec
use ice_calendar, only: istep1, myear, mmonth, mday, msec

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

call PIO_freeDecomp(File,iodesc2d)
call PIO_freeDecomp(File,iodesc3d_ncat)
call pio_closefile(File)

if (my_task == master_task) &
write(nu_diag,*) 'Restart read/written ',istep1,idate,msec
if (my_task == master_task) then
write(nu_diag,'(a,i8,4x,i4.4,a,i2.2,a,i2.2,a,i5.5)') 'Restart read/written ',istep1,myear,'-',mmonth,'-',mday,'-',msec
endif

end subroutine final_restart

Expand Down
77 changes: 46 additions & 31 deletions cicecore/shared/ice_calendar.F90
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ module ice_calendar
stop_now , & ! if 1, end program execution
write_restart, & ! if 1, write restart now
diagfreq , & ! diagnostic output frequency (10 = once per 10 dt)
dumpfreq_n , & ! restart output frequency (10 = once per 10 d,m,y)
nstreams , & ! number of history output streams
histfreq_n(max_nstrm) ! history output frequency
dumpfreq_n(max_nstrm), & ! restart output frequency (10 = once per 10 d,m,y)
histfreq_n(max_nstrm) ! history output frequency

logical (kind=log_kind), public :: &
new_year , & ! new year = .true.
Expand All @@ -126,16 +126,18 @@ module ice_calendar
force_restart_now, & ! force a restart now
write_history(max_nstrm) ! write history now

character (len=1), public :: &
character (len=2), public :: &
npt_unit, & ! run length unit, 'y', 'm', 'd', 'h', 's', '1'
npt0_unit, & ! original run length unit, 'y', 'm', 'd', 'h', 's', '1'
histfreq(max_nstrm), & ! history output frequency, 'y','m','d','h','1'
dumpfreq ! restart frequency, 'y','m','d'
histfreq(max_nstrm), & ! history output frequency, 'y','m','d','h','1','x'
dumpfreq(max_nstrm) ! restart frequency, 'y','m','d', h', '1', 'x' followed by optional 1

character (len=char_len), public :: &
dumpfreq_base = 'zero', & ! restart frequency basetime ('zero', 'init')
histfreq_base = 'init', & ! history frequency basetime ('zero', 'init')
calendar_type ! define calendar type
dumpfreq_base(max_nstrm), & ! restart frequency basetime ('zero', 'init')
histfreq_base(max_nstrm), & ! history frequency basetime ('zero', 'init')
calendar_type ! define calendar type
data dumpfreq_base / 'init', 'init', 'init', 'init', 'init' /
data histfreq_base / 'zero', 'zero', 'zero', 'zero', 'zero' /

! PRIVATE

Expand Down Expand Up @@ -408,10 +410,10 @@ subroutine calendar()

! History writing flags

call compute_relative_elapsed(histfreq_base, elapsed_years, elapsed_months, elapsed_days, elapsed_hours)

do ns = 1, nstreams

call compute_relative_elapsed(histfreq_base(ns), elapsed_years, elapsed_months, elapsed_days, elapsed_hours)

select case (histfreq(ns))
case ("y", "Y")
if (new_year .and. histfreq_n(ns)/=0) then
Expand Down Expand Up @@ -442,27 +444,40 @@ subroutine calendar()

enddo

! Restart writing flag

call compute_relative_elapsed(dumpfreq_base, elapsed_years, elapsed_months, elapsed_days, elapsed_hours)

select case (dumpfreq)
case ("y", "Y")
if (new_year .and. mod(elapsed_years, dumpfreq_n)==0) &
write_restart = 1
case ("m", "M")
if (new_month .and. mod(elapsed_months,dumpfreq_n)==0) &
write_restart = 1
case ("d", "D")
if (new_day .and. mod(elapsed_days, dumpfreq_n)==0) &
write_restart = 1
case ("h", "H")
if (new_hour .and. mod(elapsed_hours, dumpfreq_n)==0) &
write_restart = 1
case ("1")
if (mod(istep1, dumpfreq_n)==0) &
write_restart = 1
end select
! Restart writing flag, set dumpfreq to 'x" if stream is written once

do ns = 1, max_nstrm

call compute_relative_elapsed(dumpfreq_base(ns), elapsed_years, elapsed_months, elapsed_days, elapsed_hours)

select case (dumpfreq(ns)(1:1))
case ("y", "Y")
if (new_year .and. mod(elapsed_years, dumpfreq_n(ns))==0) then
write_restart = 1
if (dumpfreq(ns)(2:2) == '1') dumpfreq(ns) = 'x'
endif
case ("m", "M")
if (new_month .and. mod(elapsed_months,dumpfreq_n(ns))==0) then
write_restart = 1
if (dumpfreq(ns)(2:2) == '1') dumpfreq(ns) = 'x'
endif
case ("d", "D")
if (new_day .and. mod(elapsed_days, dumpfreq_n(ns))==0) then
write_restart = 1
if (dumpfreq(ns)(2:2) == '1') dumpfreq(ns) = 'x'
endif
case ("h", "H")
if (new_hour .and. mod(elapsed_hours, dumpfreq_n(ns))==0) then
write_restart = 1
if (dumpfreq(ns)(2:2) == '1') dumpfreq(ns) = 'x'
endif
case ("1")
if (mod(istep1, dumpfreq_n(ns))==0) then
write_restart = 1
if (dumpfreq(ns)(2:2) == '1') dumpfreq(ns) = 'x'
endif
end select
enddo

if (force_restart_now) write_restart = 1

Expand Down
8 changes: 4 additions & 4 deletions configuration/scripts/ice_in
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
restart_dir = './restart/'
restart_file = 'iced'
pointer_file = './ice.restart_file'
dumpfreq = 'd'
dumpfreq_n = 1
dumpfreq_base = 'init'
dumpfreq = 'd','x','x','x','x'
dumpfreq_n = 1 , 1 , 1 , 1 , 1
dumpfreq_base = 'init','init','init','init','init'
dump_last = .false.
bfbflag = 'off'
diagfreq = 24
Expand All @@ -47,7 +47,7 @@
lonpnt(2) = -45.
histfreq = 'm','x','x','x','x'
histfreq_n = 1 , 1 , 1 , 1 , 1
histfreq_base = 'zero'
histfreq_base = 'zero','zero','zero','zero','zero'
hist_avg = .true.,.true.,.true.,.true.,.true.
history_dir = './history/'
history_file = 'iceh'
Expand Down
2 changes: 1 addition & 1 deletion configuration/scripts/options/set_nml.histall
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
histfreq = 'm','d','1','h','x'
histfreq_n = 1,2,6,4,1
histfreq_base = 'zero'
histfreq_base = 'zero','zero','zero','zero','zero'
write_ic = .true.
f_tmask = .true.
f_blkmask = .true.
Expand Down
2 changes: 1 addition & 1 deletion configuration/scripts/options/set_nml.histdbg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
histfreq = 'm','d','1','h','x'
histfreq_n = 1,1,1,1,1
histfreq_base = 'zero'
histfreq_base = 'zero','zero','zero','zero','zero'
write_ic = .true.
f_tmask = .true.
f_blkmask = .true.
Expand Down
4 changes: 2 additions & 2 deletions doc/source/cice_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ either Celsius or Kelvin units). Deprecated parameters are listed at the end.
"dtei", "1/dte, where dte is the EVP subcycling time step", "1/s"
"dump_file", "output file for restart dump", ""
"dumpfreq", "dump frequency for restarts, y, m, d, h or 1", ""
"dumpfreq_base", "reference date for restart output", ""
"dumpfreq_base", "reference date for restart output, zero or init", ""
"dumpfreq_n", "restart output frequency", ""
"dump_last", "if true, write restart on last time step of simulation", ""
"dwavefreq", "widths of wave frequency bins", "1/s"
Expand Down Expand Up @@ -316,7 +316,7 @@ either Celsius or Kelvin units). Deprecated parameters are listed at the end.
"hin_max", "category thickness limits", "m"
"hist_avg", "if true, write averaged data instead of snapshots", "T,T,T,T,T"
"histfreq", "units of history output frequency: y, m, w, d or 1", "m,x,x,x,x"
"histfreq_base", "reference date for history output", ""
"histfreq_base", "reference date for history output, zero or init", ""
"histfreq_n", "integer output frequency in histfreq units", "1,1,1,1,1"
"history_dir", "path to history output files", ""
"history_file", "history output file prefix", ""
Expand Down
15 changes: 10 additions & 5 deletions doc/source/user_guide/ug_case_settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,19 @@ setup_nml
"", "``file``", "write diagnostic output to file", ""
"``diag_file``", "string", "diagnostic output file", "'ice_diag.d'"
"``dt``", "real", "thermodynamics time step length in seconds", "3600."
"``dumpfreq``", "``d``", "write restart every ``dumpfreq_n`` days", "``y``"
"``dumpfreq``", "``d``", "write restart every ``dumpfreq_n`` days", "'y','x','x','x','x'"
"", "``d1``", "write restart once after ``dumpfreq_n`` days", ""
"", "``h``", "write restart every ``dumpfreq_n`` hours", ""
"", "``h1``", "write restart once after ``dumpfreq_n`` hours", ""
"", "``m``", "write restart every ``dumpfreq_n`` months", ""
"", "``m1``", "write restart once after ``dumpfreq_n`` months", ""
"", "``y``", "write restart every ``dumpfreq_n`` years", ""
"", "``1``", "write restart every ``dumpfreq_n`` time step", ""
"``dumpfreq_base``", "init", "restart output frequency relative to year_init, month_init, day_init", "init"
"", "``y1``", "write restart once after ``dumpfreq_n`` years", ""
"", "``1``", "write restart every ``dumpfreq_n`` time steps", ""
"", "``11``", "write restart once after ``dumpfreq_n`` time steps", ""
"``dumpfreq_base``", "init", "restart output frequency relative to year_init, month_init, day_init", "'init','init','init','init','init'"
"", "zero", "restart output frequency relative to year-month-day of 0000-01-01", ""
"``dumpfreq_n``", "integer", "write restart frequency with ``dumpfreq``", "1"
"``dumpfreq_n``", "integer array", "write restart frequency with ``dumpfreq``", "1,1,1,1,1"
"``dump_last``", "logical", "write restart on last time step of simulation", "``.false.``"
"``hist_avg``", "logical", "write time-averaged data", "``.true.,.true.,.true.,.true.,.true.``"
"``histfreq``", "``d``", "write history every ``histfreq_n`` days", "'1','h','d','m','y'"
Expand All @@ -183,7 +188,7 @@ setup_nml
"", "``x``", "unused frequency stream (not written)", ""
"", "``y``", "write history every ``histfreq_n`` years", ""
"", "``1``", "write history every ``histfreq_n`` time step", ""
"``histfreq_base``", "init", "history output frequency relative to year_init, month_init, day_init", "zero"
"``histfreq_base``", "init", "history output frequency relative to year_init, month_init, day_init", "'zero','zero','zero','zero','zero'"
"", "zero", "history output frequency relative to year-month-day of 0000-01-01", ""
"``histfreq_n``", "integer array", "frequency history output is written with ``histfreq``", "1,1,1,1,1"
"``history_dir``", "string", "path to history output directory", "'./'"
Expand Down
5 changes: 4 additions & 1 deletion doc/source/user_guide/ug_implementation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,8 @@ will be relative to the model initial date specified by ``year_init``,
in setting output frequencies. `init` is the default for
``dumpfreq_base`` and makes it easy to generate restarts
5 or 10 model days after startup as we often do in testing.
Both ``histfreq_base`` and ``dumpfreq_base`` are arrays
and can be set for each stream separately.

In general, output is always
written at the start of the year, month, day, or hour without
Expand Down Expand Up @@ -1408,7 +1410,8 @@ The restart files created by CICE contain all of the variables needed
for a full, exact restart. The filename begins with the character string
‘iced.’, and the restart dump frequency is given by the namelist
variables ``dumpfreq`` and ``dumpfreq_n`` relative to a reference date
specified by ``dumpfreq_base``. The pointer to the filename from
specified by ``dumpfreq_base``. Multiple restart frequencies are supported
in the code with a similar mechanism to history streams. The pointer to the filename from
which the restart data is to be read for a continuation run is set in
``pointer_file``. The code assumes that auxiliary binary tracer restart
files will be identified using the same pointer and file name prefix,
Expand Down

0 comments on commit 493de4f

Please sign in to comment.