Skip to content

Commit

Permalink
Fix history/restart frequency bugs and update scripts
Browse files Browse the repository at this point in the history
- Fix bugs in history/restart frequency associated with new calendar (CICE-Consortium#589)
- Define frequency in absolute terms relative to 0000-01-01-00000 and document (CICE-Consortium#589)
- Update set_nml.histall to include hourly output (CICE-Consortium#589)
- Update test scripts to cleanly abort if run fails where possible (CICE-Consortium#608)
- Update decomp test so it's rerunable, remove restart at start of run (CICE-Consortium#601)
- Add ability to do bfbcomp tests with additional options set on command line (CICE-Consortium#569)
- Update documentation of calendar frequency computation, calendar types, and closed boundaries (CICE-Consortium#541)
- Add optional doabort flag to abort_ice to control whether the method aborts.  This
  is useful for testing and code coverage statistics, although doabort=.false.
  will not call the actual abort method, but we can test the interfaces and
  rest of the code.
  • Loading branch information
apcraig committed Jun 18, 2021
1 parent ff88891 commit 92fa331
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 56 deletions.
28 changes: 23 additions & 5 deletions cice.setup
Original file line number Diff line number Diff line change
Expand Up @@ -644,11 +644,6 @@ EOF
set bfbcomp = "$bfbcomp_tmp"
endif
set fbfbcomp = ${spval}
if ($bfbcomp != ${spval}) then
set fbfbcomp = ${machcomp}_${bfbcomp}
endif
#------------------------------------------------------------
# Parse pesx with strict checking, limit pes for machine
Expand Down Expand Up @@ -768,6 +763,29 @@ EOF
set testname_base = "${machcomp}_${test}_${grid}_${pesx}${soptions}.${testid}"
set testname = "${tsdir}/${testname_base}"
set case = ${testname}
# Add -s flags in cice.setup to bfbcomp name
# Parse bfbcomp test_grid_pes and sets
# Add sets_base and sort unique
# Create fbfbcomp string that should be consistent with base casename
set bfbcomp_regex="\(.*_[0-9x]*\)_\(.*\)"
set bfbcomp_test_grid_pes=`echo ${bfbcomp} | sed "s/${bfbcomp_regex}/\1/"`
set bfbcomp_sets=`echo ${bfbcomp} | sed "s/${bfbcomp_regex}/\2/" | sed 's/_/,/g' `
set bfbcomp_sets="${bfbcomp_sets},${sets_base}"
set bfbcomp_soptions = ""
# Create sorted array and remove duplicates and "none"
set bfbcomp_setsarray = `echo ${bfbcomp_sets} | sed 's/,/ /g' | fmt -1 | sort -u`
if ("${bfbcomp_setsarray}" != "") then
foreach field (${bfbcomp_setsarray})
if (${field} != "none") then
set bfbcomp_soptions = ${bfbcomp_soptions}"_"${field}
endif
end
endif
set fbfbcomp = ${spval}
if ($bfbcomp != ${spval}) then
set fbfbcomp = ${machcomp}_${bfbcomp_test_grid_pes}${bfbcomp_soptions}
endif
endif
if (-d ${case}) then
Expand Down
22 changes: 14 additions & 8 deletions cicecore/cicedynB/infrastructure/comm/mpi/ice_exit.F90
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module ice_exit

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

subroutine abort_ice(error_message, file, line)
subroutine abort_ice(error_message, file, line, doabort)

! This routine aborts the ice model and prints an error message.

Expand All @@ -31,10 +31,10 @@ subroutine abort_ice(error_message, file, line)
use mpi ! MPI Fortran module
#endif

character (len=*), intent(in),optional :: error_message
character (len=*), intent(in),optional :: file
integer (kind=int_kind), intent(in), optional :: &
line ! line number
character (len=*), intent(in),optional :: error_message ! error message
character (len=*), intent(in),optional :: file ! file
integer (kind=int_kind), intent(in), optional :: line ! line number
logical (kind=log_kind), intent(in), optional :: doabort ! abort flag

! local variables

Expand All @@ -43,8 +43,12 @@ subroutine abort_ice(error_message, file, line)
ierr, & ! MPI error flag
error_code ! return code
#endif
logical (log_kind) :: ldoabort ! local doabort flag
character(len=*), parameter :: subname='(abort_ice)'

ldoabort = .true.
if (present(doabort)) ldoabort = doabort

#if (defined CESMCOUPLED)
call flush_fileunit(nu_diag)
call icepack_warnings_flush(nu_diag)
Expand All @@ -54,7 +58,7 @@ subroutine abort_ice(error_message, file, line)
if (present(line)) write (nu_diag,*) subname,' line number ',line
if (present(error_message)) write (nu_diag,*) subname,' error = ',trim(error_message)
call flush_fileunit(nu_diag)
call shr_sys_abort(subname//trim(error_message))
if (ldoabort) call shr_sys_abort(subname//trim(error_message))
#else
call flush_fileunit(nu_diag)
call icepack_warnings_flush(nu_diag)
Expand All @@ -65,8 +69,10 @@ subroutine abort_ice(error_message, file, line)
if (present(error_message)) write (ice_stderr,*) subname,' error = ',trim(error_message)
call flush_fileunit(ice_stderr)
error_code = 128
call MPI_ABORT(MPI_COMM_WORLD, error_code, ierr)
stop
if (ldoabort) then
call MPI_ABORT(MPI_COMM_WORLD, error_code, ierr)
stop
endif
#endif

end subroutine abort_ice
Expand Down
18 changes: 11 additions & 7 deletions cicecore/cicedynB/infrastructure/comm/serial/ice_exit.F90
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,29 @@ module ice_exit

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

subroutine abort_ice(error_message,file,line)
subroutine abort_ice(error_message,file,line,doabort)

! This routine aborts the ice model and prints an error message.

character (len=*), intent(in),optional :: error_message
character (len=*), intent(in),optional :: file
integer (kind=int_kind), intent(in), optional :: &
line ! line number
character (len=*), intent(in),optional :: error_message ! error message
character (len=*), intent(in),optional :: file ! file
integer (kind=int_kind), intent(in), optional :: line ! line number
logical (kind=log_kind), intent(in), optional :: doabort ! abort flag

logical (kind=log_kind) :: ldoabort ! local doabort
character(len=*), parameter :: subname='(abort_ice)'

ldoabort = .true.
if (present(doabort)) ldoabort = doabort

#ifdef CESMCOUPLED
call icepack_warnings_flush(nu_diag)
write(nu_diag,*) ' '
write(nu_diag,*) subname, 'ABORTED: '
if (present(file)) write (nu_diag,*) subname,' called from ',trim(file)
if (present(line)) write (nu_diag,*) subname,' line number ',line
if (present(error_message)) write (nu_diag,*) subname,' error = ',trim(error_message)
call shr_sys_abort(subname//trim(error_message))
if (ldoabort) call shr_sys_abort(subname//trim(error_message))
#else
call icepack_warnings_flush(nu_diag)
write(nu_diag,*) ' '
Expand All @@ -51,7 +55,7 @@ subroutine abort_ice(error_message,file,line)
if (present(line)) write (nu_diag,*) subname,' line number ',line
if (present(error_message)) write (nu_diag,*) subname,' error = ',trim(error_message)
call flush_fileunit(nu_diag)
stop
if (ldoabort) stop
#endif

end subroutine abort_ice
Expand Down
13 changes: 11 additions & 2 deletions cicecore/drivers/unittest/bcstchk/bcstchk.F90
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,20 @@ program bcstchk
endif

! Test abort_ice, regardless of test outcome
! Set doabort to false to support code coverage stats, aborted runs don't seem to generate
! gcov statistics

call flush_fileunit(6)
call ice_barrier()
call abort_ice(subname//' Test abort ',file=__FILE__,line=__LINE__, doabort=.false.)
call flush_fileunit(6)
call ice_barrier()
call abort_ice(subname//' Test abort ',file=__FILE__,line=__LINE__)

if (my_task == master_task) write(6,*) subname,'This line should not be written'
if (my_task == master_task) then
write(6,*) ' '
write(6,*) 'BCSTCHK abort test done'
write(6,*) ' '
endif

call end_run()

Expand Down
53 changes: 44 additions & 9 deletions cicecore/shared/ice_calendar.F90
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
! 2010 CM : Fixed support for Gregorian calendar: subroutines
! sec2time, time2sec and set_calendar added.
! 2020 TC : Significant refactor to move away from time as prognostic
! Note that the reference date is arbitrarily set to
! 0000-01-01-00000 and dates cannot be less than that.
! The implementation is also limited by some integer
! math to myear_max which is a parameter in this module.

module ice_calendar

Expand Down Expand Up @@ -130,6 +134,9 @@ module ice_calendar
integer (kind=int_kind) :: &
hour ! hour of the day

integer (kind=int_kind), parameter :: &
myear_max = 200000 ! maximum year, limited by integer overflow in elapsed_horus

! 360-day year data
integer (kind=int_kind) :: &
daymo360(months_per_year) ! number of days in each month
Expand Down Expand Up @@ -320,6 +327,20 @@ end subroutine advance_timestep

subroutine calendar()

! This sets a bunch of internal calendar stuff including history and
! restart frequencies. These frequencies are relative to the start
! of time which is arbitrarily set to year=0, month=1, day=1, sec=0.
! That means that the frequencies are repeatable between runs
! regardless of the initial model date.
! One thing to watch for is the size of elapsed hours. This will
! become a large integer and will overflow if the year is ever
! greater than about 200,000 years. A check has been added just
! to make sure this doesn't happen.
! The largest integer*4 is about 2^31 = 2*2^10^3 =~ 2*1000^3 = 2.e9
! 2.e9 (hours) / (365*24 hours/year) =~ 228,000 years
! The elapsed hours will overflow integers at some point after that.


! real (kind=dbl_kind), intent(in), optional :: &
! ttime ! time variable

Expand All @@ -328,9 +349,10 @@ subroutine calendar()
integer (kind=int_kind) :: &
ns , & ! loop index
yearp,monthp,dayp,hourp , & ! previous year, month, day, hour
elapsed_days , & ! since beginning this run
elapsed_months , & ! since beginning this run
elapsed_hours ! since beginning this run
elapsed_years , & ! since beginning of time
elapsed_months , & ! since beginning of time
elapsed_days , & ! since beginning of time
elapsed_hours ! since beginning of time
character(len=*),parameter :: subname='(calendar)'

yearp=myear
Expand All @@ -347,12 +369,18 @@ subroutine calendar()
call update_date(myear,mmonth,mday,msec)
call set_calendar(myear)

if (myear > myear_max) then
write(nu_diag,*) trim(subname),' ERROR year too large, ',myear,myear_max
call abort_ice(subname//'ERROR: model year too large')
endif

idate = (myear)*10000 + mmonth*100 + mday ! date (yyyymmdd)
yday = daycal(mmonth) + mday ! day of the year
hour = (msec+1)/(seconds_per_hour)
elapsed_months = (myear - year_init)*months_per_year + mmonth - month_init
elapsed_days = compute_days_between(year_init,month_init,day_init,myear,mmonth,mday)
elapsed_hours = elapsed_days * hours_per_day
hour = int(msec/seconds_per_hour)
elapsed_years = myear
elapsed_months = myear * months_per_year + mmonth - 1
elapsed_days = compute_days_between(0,1,1,myear,mmonth,mday)
elapsed_hours = elapsed_days * hours_per_day + hour
call calendar_date2time(myear,mmonth,mday,msec,timesecs)

!--- compute other stuff
Expand All @@ -368,12 +396,19 @@ subroutine calendar()

! History writing flags

! if (my_task == master_task) then
! write(nu_diag,*) subname,' elap_y',elapsed_years
! write(nu_diag,*) subname,' elap_m',elapsed_months
! write(nu_diag,*) subname,' elap_d',elapsed_days
! write(nu_diag,*) subname,' elap_h',elapsed_hours
! endif

do ns = 1, nstreams

select case (histfreq(ns))
case ("y", "Y")
if (new_year .and. histfreq_n(ns)/=0) then
if (mod(myear, histfreq_n(ns))==0) &
if (mod(elapsed_years, histfreq_n(ns))==0) &
write_history(ns) = .true.
endif
case ("m", "M")
Expand Down Expand Up @@ -404,7 +439,7 @@ subroutine calendar()

select case (dumpfreq)
case ("y", "Y")
if (new_year .and. mod(myear, dumpfreq_n)==0) &
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) &
Expand Down
10 changes: 5 additions & 5 deletions configuration/scripts/options/set_nml.histall
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
histfreq = 'm','d','1','x','x'
histfreq_n = 1,1,6,1,1
histfreq = 'm','d','1','h','x'
histfreq_n = 1,2,6,4,1
write_ic = .true.
f_tmask = .true.
f_blkmask = .true.
Expand All @@ -20,10 +20,10 @@
f_VGRDa = .true.
f_bounds = .true.
f_CMIP = 'm'
f_aice = 'md1'
f_hi = '1dm'
f_aice = 'md1h'
f_hi = 'h1dm'
f_hs = 'd1m'
f_Tsfc = 'md'
f_Tsfc = 'mdh'
f_sice = 'md'
f_uvel = 'md'
f_vvel = 'dm'
Expand Down
3 changes: 3 additions & 0 deletions configuration/scripts/tests/test_decomp.script
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ end
cp ice_in ice_in.0
set base_dir = ""

# clean up old restart dirs to support rerun
rm -rf ${ICE_RUNDIR}/restart.*

foreach decomp (${decomps})
${ICE_CASEDIR}/casescripts/parse_namelist.sh ice_in ${ICE_CASEDIR}/casescripts/set_nml.d${decomp}
cp ice_in ice_in.${decomp}
Expand Down
12 changes: 7 additions & 5 deletions configuration/scripts/tests/test_logbfb.script
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

# This is identical to a smoke test, but triggers bfbcompare with log files instead of restarts
#----------------------------------------------------
# Run the CICE model
# This is identical to a smoke test, but triggers bfbcompare with log files instead of restarts
# cice.run returns -1 if run did not complete successfully

./cice.run
Expand All @@ -21,9 +20,12 @@ mv -f ${ICE_CASEDIR}/test_output ${ICE_CASEDIR}/test_output.prev
cat ${ICE_CASEDIR}/test_output.prev | grep -iv "${ICE_TESTNAME} test" >! ${ICE_CASEDIR}/test_output
rm -f ${ICE_CASEDIR}/test_output.prev

set grade = FAIL
if ( $res == 0 ) then
set grade = PASS
set grade = PASS
if ( $res != 0 ) then
set grade = FAIL
echo "$grade ${ICE_TESTNAME} run ${ttimeloop} ${tdynamics} ${tcolumn}" >> ${ICE_CASEDIR}/test_output
echo "$grade ${ICE_TESTNAME} test " >> ${ICE_CASEDIR}/test_output
exit 99
endif

echo "$grade ${ICE_TESTNAME} run ${ttimeloop} ${tdynamics} ${tcolumn}" >> ${ICE_CASEDIR}/test_output
Expand Down
9 changes: 6 additions & 3 deletions configuration/scripts/tests/test_smoke.script
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ mv -f ${ICE_CASEDIR}/test_output ${ICE_CASEDIR}/test_output.prev
cat ${ICE_CASEDIR}/test_output.prev | grep -iv "${ICE_TESTNAME} test" >! ${ICE_CASEDIR}/test_output
rm -f ${ICE_CASEDIR}/test_output.prev

set grade = FAIL
if ( $res == 0 ) then
set grade = PASS
set grade = PASS
if ( $res != 0 ) then
set grade = FAIL
echo "$grade ${ICE_TESTNAME} run ${ttimeloop} ${tdynamics} ${tcolumn}" >> ${ICE_CASEDIR}/test_output
echo "$grade ${ICE_TESTNAME} test " >> ${ICE_CASEDIR}/test_output
exit 99
endif

echo "$grade ${ICE_TESTNAME} run ${ttimeloop} ${tdynamics} ${tcolumn}" >> ${ICE_CASEDIR}/test_output
Expand Down
9 changes: 6 additions & 3 deletions configuration/scripts/tests/test_unittest.script
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ mv -f ${ICE_CASEDIR}/test_output ${ICE_CASEDIR}/test_output.prev
cat ${ICE_CASEDIR}/test_output.prev | grep -iv "${ICE_TESTNAME} test" >! ${ICE_CASEDIR}/test_output
rm -f ${ICE_CASEDIR}/test_output.prev

set grade = FAIL
if ( $res == 0 ) then
set grade = PASS
set grade = PASS
if ( $res != 0 ) then
set grade = FAIL
echo "$grade ${ICE_TESTNAME} run " >> ${ICE_CASEDIR}/test_output
echo "$grade ${ICE_TESTNAME} test " >> ${ICE_CASEDIR}/test_output
exit 99
endif

echo "$grade ${ICE_TESTNAME} run " >> ${ICE_CASEDIR}/test_output
Expand Down
1 change: 1 addition & 0 deletions doc/source/cice_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ either Celsius or Kelvin units).
"mtask", "local processor number that writes debugging data", ""
"mu_rdg", ":math:`\bullet` e-folding scale of ridged ice", ""
"myear", "model year", ""
"myear_max", "maximum allowed model year", ""
"my_task", "task ID for the current processor", ""
"**N**", "", ""
"n_aero", "number of aerosol species", ""
Expand Down
Loading

0 comments on commit 92fa331

Please sign in to comment.