From 2efc26cddef840801d5ed1e5322e6502f1120683 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Tue, 20 Jun 2023 15:53:54 -0600 Subject: [PATCH 1/5] Add option to change location in interval of time axis --- cicecore/cicedyn/analysis/ice_history_shared.F90 | 2 ++ cicecore/cicedyn/general/ice_init.F90 | 7 ++++++- .../io/io_netcdf/ice_history_write.F90 | 12 +++++++++--- .../infrastructure/io/io_pio2/ice_history_write.F90 | 12 +++++++++--- configuration/scripts/ice_in | 1 + doc/source/cice_index.rst | 1 + doc/source/user_guide/ug_case_settings.rst | 1 + doc/source/user_guide/ug_implementation.rst | 6 ++++-- 8 files changed, 33 insertions(+), 9 deletions(-) diff --git a/cicecore/cicedyn/analysis/ice_history_shared.F90 b/cicecore/cicedyn/analysis/ice_history_shared.F90 index f4e1f3ebf..3c31f23ca 100644 --- a/cicecore/cicedyn/analysis/ice_history_shared.F90 +++ b/cicecore/cicedyn/analysis/ice_history_shared.F90 @@ -132,6 +132,8 @@ module ice_history_shared time_end(max_nstrm), & time_bounds(2) + character (len=char_len), public :: hist_time_axis + real (kind=dbl_kind), allocatable, public :: & a2D (:,:,:,:) , & ! field accumulations/averages, 2D a3Dz(:,:,:,:,:) , & ! field accumulations/averages, 3D vertical diff --git a/cicecore/cicedyn/general/ice_init.F90 b/cicecore/cicedyn/general/ice_init.F90 index 1baaa95b3..62a46e2cb 100644 --- a/cicecore/cicedyn/general/ice_init.F90 +++ b/cicecore/cicedyn/general/ice_init.F90 @@ -81,7 +81,7 @@ subroutine input_data runid, runtype, use_restart_time, restart_format, lcdf64 use ice_history_shared, only: hist_avg, history_dir, history_file, & incond_dir, incond_file, version_name, & - history_precision, history_format + history_precision, history_format, hist_time_axis use ice_flux, only: update_ocn_f, l_mpond_fresh use ice_flux, only: default_season use ice_flux_bgc, only: cpl_bgc @@ -185,6 +185,7 @@ subroutine input_data restart_ext, use_restart_time, restart_format, lcdf64, & pointer_file, dumpfreq, dumpfreq_n, dump_last, & diagfreq, diag_type, diag_file, history_format,& + hist_time_axis, & print_global, print_points, latpnt, lonpnt, & debug_forcing, histfreq, histfreq_n, hist_avg, & history_dir, history_file, history_precision, cpl_bgc, & @@ -324,6 +325,8 @@ subroutine input_data 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 interval position + history_dir = './' ! write to executable dir for default history_file = 'iceh' ! history file name prefix history_precision = 4 ! precision of history files @@ -906,6 +909,7 @@ subroutine input_data call broadcast_scalar(history_file, master_task) call broadcast_scalar(history_precision, master_task) call broadcast_scalar(history_format, master_task) + call broadcast_scalar(hist_time_axis, master_task) call broadcast_scalar(write_ic, master_task) call broadcast_scalar(cpl_bgc, master_task) call broadcast_scalar(incond_dir, master_task) @@ -2316,6 +2320,7 @@ subroutine input_data write(nu_diag,1031) ' history_file = ', trim(history_file) write(nu_diag,1021) ' history_precision= ', history_precision write(nu_diag,1031) ' history_format = ', trim(history_format) + write(nu_diag,1031) ' hist_time_axis = ', trim(hist_time_axis) if (write_ic) then write(nu_diag,1039) ' Initial condition will be written in ', & trim(incond_dir) diff --git a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 index 25178ed6e..57978d7f6 100644 --- a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 @@ -21,7 +21,7 @@ module ice_history_write - use ice_constants, only: c0, c360, spval, spval_dbl + use ice_constants, only: c0, c360, p5, spval, spval_dbl use ice_fileunits, only: nu_diag use ice_exit, only: abort_ice use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted @@ -137,8 +137,6 @@ subroutine ice_write_hist (ns) if (my_task == master_task) then - ltime2 = timesecs/secday - call construct_filename(ncfile(ns),'nc',ns) ! add local directory path name to ncfile @@ -750,6 +748,14 @@ subroutine ice_write_hist (ns) ! write time variable !----------------------------------------------------------------- + if (trim(hist_time_axis) == 'begin') then + ltime2 = time_beg(ns) + elseif (trim(hist_time_axis) == 'middle') then + ltime2 = p5*(time_beg(ns)+time_end(ns)) + else ! hist_time_axis == 'end' (default) + ltime2 = timesecs/secday + endif + status = nf90_inq_varid(ncid,'time',varid) if (status /= nf90_noerr) call abort_ice(subname// & 'ERROR: getting time varid') diff --git a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 index 35ec7bed2..bbae5f5c2 100644 --- a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 @@ -18,7 +18,7 @@ module ice_history_write use ice_kinds_mod - use ice_constants, only: c0, c360, spval, spval_dbl + use ice_constants, only: c0, c360, p5, spval, spval_dbl use ice_fileunits, only: nu_diag use ice_exit, only: abort_ice use icepack_intfc, only: icepack_warnings_flush, icepack_warnings_aborted @@ -185,8 +185,6 @@ subroutine ice_write_hist (ns) call ice_pio_initdecomp(ndim3=nzslyr, ndim4=ncat_hist, iodesc=iodesc4ds, precision=history_precision) call ice_pio_initdecomp(ndim3=nfsd_hist, ndim4=ncat_hist, iodesc=iodesc4df, precision=history_precision) - ltime2 = timesecs/secday - ! option of turning on double precision history files lprecision = pio_real if (history_precision == 8) lprecision = pio_double @@ -706,6 +704,14 @@ subroutine ice_write_hist (ns) ! write time variable !----------------------------------------------------------------- + if (trim(hist_time_axis) == 'begin') then + ltime2 = time_beg(ns) + elseif (trim(hist_time_axis) == 'middle') then + ltime2 = p5*(time_beg(ns)+time_end(ns)) + else ! hist_time_axis == 'end' (default) + ltime2 = timesecs/secday + endif + status = pio_inq_varid(File,'time',varid) status = pio_put_var(File,varid,(/1/),ltime2) diff --git a/configuration/scripts/ice_in b/configuration/scripts/ice_in index 8dc046da5..e0e317e40 100644 --- a/configuration/scripts/ice_in +++ b/configuration/scripts/ice_in @@ -53,6 +53,7 @@ history_file = 'iceh' history_precision = 4 history_format = 'default' + hist_time_axis = 'end' write_ic = .true. incond_dir = './history/' incond_file = 'iceh_ic' diff --git a/doc/source/cice_index.rst b/doc/source/cice_index.rst index 0c0ab6971..36c772eff 100644 --- a/doc/source/cice_index.rst +++ b/doc/source/cice_index.rst @@ -322,6 +322,7 @@ either Celsius or Kelvin units). Deprecated parameters are listed at the end. "history_file", "history output file prefix", "" "history_format", "history file format", "" "history_precision", "history output precision: 4 or 8 byte", "4" + "hist_time_axis", "history file time axis interval location: begin, middle, end", "end" "hm", "land/boundary mask, thickness (T-cell)", "" "hmix", "ocean mixed layer depth", "20. m" "hour", "hour of the year", "" diff --git a/doc/source/user_guide/ug_case_settings.rst b/doc/source/user_guide/ug_case_settings.rst index 2a7240c78..d5ec89df1 100644 --- a/doc/source/user_guide/ug_case_settings.rst +++ b/doc/source/user_guide/ug_case_settings.rst @@ -191,6 +191,7 @@ setup_nml "``history_format``", "``default``", "read/write history files in default format", "``default``" "", "``pio_pnetcdf``", "read/write restart files with pnetcdf in pio", "" "``history_precision``", "integer", "history file precision: 4 or 8 byte", "4" + "``hist_time_axis``","character","history file time axis interval location: begin, middle, end","end" "``ice_ic``", "``default``", "equal to internal", "``default``" "", "``internal``", "initial conditions set based on ice\_data\_type,conc,dist inputs", "" "", "``none``", "no ice", "" diff --git a/doc/source/user_guide/ug_implementation.rst b/doc/source/user_guide/ug_implementation.rst index acc75b3d8..69cae5bcf 100644 --- a/doc/source/user_guide/ug_implementation.rst +++ b/doc/source/user_guide/ug_implementation.rst @@ -1197,8 +1197,10 @@ with a given ``histfreq`` value, or if an element of ``histfreq_n`` is 0, then no file will be written at that frequency. The output period can be discerned from the filenames. All history streams will be either instantaneous or averaged as specified by the ``hist_avg`` namelist setting and the frequency -will be relative to a reference date specified by ``histfreq_base``. More -information about how the frequency is computed is found in :ref:`timemanager`. +will be relative to a reference date specified by ``histfreq_base``. Also, some +Earth Sytem Models require the history file time axis to be centered in the averaging +interval. The flag ``hist_time_axis`` will allow the user to chose ``begin``, ``middle``, +or ``end``. More information about how the frequency is computed is found in :ref:`timemanager`. For example, in the namelist: From befc255371d25219e8c6ebb9beb248544349e6e0 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Wed, 21 Jun 2023 11:28:56 -0600 Subject: [PATCH 2/5] Only use hist_time_axis when hist_avg is true --- .../infrastructure/io/io_netcdf/ice_history_write.F90 | 11 +++++------ .../infrastructure/io/io_pio2/ice_history_write.F90 | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 index 57978d7f6..2f543bbd2 100644 --- a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 @@ -747,13 +747,12 @@ subroutine ice_write_hist (ns) !----------------------------------------------------------------- ! write time variable !----------------------------------------------------------------- + + ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) - if (trim(hist_time_axis) == 'begin') then - ltime2 = time_beg(ns) - elseif (trim(hist_time_axis) == 'middle') then - ltime2 = p5*(time_beg(ns)+time_end(ns)) - else ! hist_time_axis == 'end' (default) - ltime2 = timesecs/secday + if (hist_avg(ns)) then + if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) + if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) endif status = nf90_inq_varid(ncid,'time',varid) diff --git a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 index bbae5f5c2..a92326c58 100644 --- a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 @@ -704,12 +704,11 @@ subroutine ice_write_hist (ns) ! write time variable !----------------------------------------------------------------- - if (trim(hist_time_axis) == 'begin') then - ltime2 = time_beg(ns) - elseif (trim(hist_time_axis) == 'middle') then - ltime2 = p5*(time_beg(ns)+time_end(ns)) - else ! hist_time_axis == 'end' (default) - ltime2 = timesecs/secday + ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) + + if (hist_avg(ns)) then + if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) + if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) endif status = pio_inq_varid(File,'time',varid) From 8e30396df1f49bcb058b74f09074dca5337a060d Mon Sep 17 00:00:00 2001 From: David Bailey Date: Thu, 22 Jun 2023 09:51:28 -0600 Subject: [PATCH 3/5] Add more comments and information in the documentation --- cicecore/cicedyn/general/ice_init.F90 | 2 +- .../cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 | 2 ++ .../cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 | 2 ++ doc/source/user_guide/ug_implementation.rst | 3 ++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cicecore/cicedyn/general/ice_init.F90 b/cicecore/cicedyn/general/ice_init.F90 index 62a46e2cb..6313ffb37 100644 --- a/cicecore/cicedyn/general/ice_init.F90 +++ b/cicecore/cicedyn/general/ice_init.F90 @@ -325,7 +325,7 @@ subroutine input_data 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 interval position + hist_time_axis = 'end' ! History file time axis averaging interval position history_dir = './' ! write to executable dir for default history_file = 'iceh' ! history file name prefix diff --git a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 index 2f543bbd2..4134b5d3b 100644 --- a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 @@ -750,6 +750,8 @@ subroutine ice_write_hist (ns) ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) + ! Some coupled models require the time axis "stamp" to be in the middle + ! or even beginning of averaging interval. if (hist_avg(ns)) then if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) diff --git a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 index a92326c58..1cd0e1188 100644 --- a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 @@ -706,6 +706,8 @@ subroutine ice_write_hist (ns) ltime2 = timesecs/secday ! hist_time_axis = 'end' (default) + ! Some coupled models require the time axis "stamp" to be in the middle + ! or even beginning of averaging interval. if (hist_avg(ns)) then if (trim(hist_time_axis) == "begin" ) ltime2 = time_beg(ns) if (trim(hist_time_axis) == "middle") ltime2 = p5*(time_beg(ns)+time_end(ns)) diff --git a/doc/source/user_guide/ug_implementation.rst b/doc/source/user_guide/ug_implementation.rst index 69cae5bcf..f6327333c 100644 --- a/doc/source/user_guide/ug_implementation.rst +++ b/doc/source/user_guide/ug_implementation.rst @@ -1200,7 +1200,8 @@ or averaged as specified by the ``hist_avg`` namelist setting and the frequency will be relative to a reference date specified by ``histfreq_base``. Also, some Earth Sytem Models require the history file time axis to be centered in the averaging interval. The flag ``hist_time_axis`` will allow the user to chose ``begin``, ``middle``, -or ``end``. More information about how the frequency is computed is found in :ref:`timemanager`. +or ``end`` for the time stamp. More information about how the frequency is +computed is found in :ref:`timemanager`. For example, in the namelist: From af0c7e8c5cb61a2b747d09e61473638041b9ee43 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Thu, 22 Jun 2023 15:00:15 -0600 Subject: [PATCH 4/5] Add a check on hist_time_axis as well as a global attribute --- cicecore/cicedyn/general/ice_init.F90 | 4 ++++ .../infrastructure/io/io_netcdf/ice_history_write.F90 | 6 ++++++ .../cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 | 3 +++ 3 files changed, 13 insertions(+) diff --git a/cicecore/cicedyn/general/ice_init.F90 b/cicecore/cicedyn/general/ice_init.F90 index 6313ffb37..c6482de3b 100644 --- a/cicecore/cicedyn/general/ice_init.F90 +++ b/cicecore/cicedyn/general/ice_init.F90 @@ -1574,6 +1574,10 @@ subroutine input_data abort_list = trim(abort_list)//":24" endif + if(trim(hist_time_axis) /= 'begin' .and. trim(hist_time_axis) /= 'middle' .and. trim(hist_time_axis) /= 'end') then + write (nu_diag,*) subname//' WARNING: hist_time_axis set to default end ' + 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" diff --git a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 index 4134b5d3b..bfbe31707 100644 --- a/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_netcdf/ice_history_write.F90 @@ -716,6 +716,12 @@ subroutine ice_write_hist (ns) 'ERROR: global attribute time_period_freq') endif + if (hist_avg(ns)) then + status = nf90_put_att(ncid,nf90_global,'time_axis_position',trim(hist_time_axis)) + if (status /= nf90_noerr) call abort_ice(subname// & + 'ERROR: global attribute time axis position') + endif + title = 'CF-1.0' status = & nf90_put_att(ncid,nf90_global,'conventions',title) diff --git a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 index 1cd0e1188..877071a11 100644 --- a/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 +++ b/cicecore/cicedyn/infrastructure/io/io_pio2/ice_history_write.F90 @@ -676,6 +676,9 @@ subroutine ice_write_hist (ns) status = pio_put_att(File,pio_global,'time_period_freq',trim(time_period_freq)) endif + if (hist_avg(ns)) & + status = pio_put_att(File,pio_global,'time_axis_position',trim(hist_time_axis)) + title = 'CF-1.0' status = & pio_put_att(File,pio_global,'conventions',trim(title)) From d4b144bea9b521fcbc50b7f1fee1ad289fd20e38 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Fri, 23 Jun 2023 10:04:23 -0600 Subject: [PATCH 5/5] Abort if hist_time_axis is not set correctly. --- cicecore/cicedyn/general/ice_init.F90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cicecore/cicedyn/general/ice_init.F90 b/cicecore/cicedyn/general/ice_init.F90 index c6482de3b..2c8b1db3b 100644 --- a/cicecore/cicedyn/general/ice_init.F90 +++ b/cicecore/cicedyn/general/ice_init.F90 @@ -1575,7 +1575,8 @@ subroutine input_data endif if(trim(hist_time_axis) /= 'begin' .and. trim(hist_time_axis) /= 'middle' .and. trim(hist_time_axis) /= 'end') then - write (nu_diag,*) subname//' WARNING: hist_time_axis set to default end ' + 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