From 9c4334a8d7a92cc2a4e4f263bc0e487b9bea87c2 Mon Sep 17 00:00:00 2001 From: Nicholas Szapiro <149816583+NickSzapiro-NOAA@users.noreply.github.com> Date: Fri, 16 Aug 2024 15:13:38 -0400 Subject: [PATCH] Write restart at end of run via NUOPC component attribute & Initialize cpl_scalar field when created for UFS (#969) These are two commits cherry-picked from as in UFS and needed to close NOAA-EMC#84. This PR adds the ability for CICE to write restart files at the end of the run (independent of other settings) and controlled via the CMEPS configuration option write_restart_at_endofrun. Setting this configuration option to True creates a restart file in the same way for CMEPS, MOM6, and CICE. This PR also initializes the scalar field value for the index for NTile (implemented for FV3) not used or set in CICE. In certain cases, the scalar field value for this index has been found to be non-zero (NaN in debug compiles). This is the cause of the failure reported in ufs-community/ufs-weather-model#2338. * Add end of run functionality to CICE (#77) * initialize cpl_scalar field when created (#83) --------- Co-authored-by: Daniel Sarmiento <42810219+dpsarmie@users.noreply.github.com> Co-authored-by: Denise Worthen --- .../drivers/nuopc/cmeps/cice_wrapper_mod.F90 | 2 +- .../drivers/nuopc/cmeps/ice_comp_nuopc.F90 | 23 +++++++++++++++++-- .../drivers/nuopc/cmeps/ice_import_export.F90 | 6 +++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/cicecore/drivers/nuopc/cmeps/cice_wrapper_mod.F90 b/cicecore/drivers/nuopc/cmeps/cice_wrapper_mod.F90 index 7d94ae8c5..db0140b3c 100644 --- a/cicecore/drivers/nuopc/cmeps/cice_wrapper_mod.F90 +++ b/cicecore/drivers/nuopc/cmeps/cice_wrapper_mod.F90 @@ -72,7 +72,7 @@ subroutine ufs_logfhour(msg,hour) real(dbl_kind), intent(in) :: hour character(len=char_len) :: filename integer(int_kind) :: nunit - write(filename,'(a,i3.3)')'log.ice.f',int(hour) + write(filename,'(a,i4.4)')'log.ice.f',int(hour) open(newunit=nunit,file=trim(filename)) write(nunit,'(a)')'completed: cice' write(nunit,'(a,f10.3)')'forecast hour:',hour diff --git a/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 b/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 index ea0191fa1..38053c5b9 100644 --- a/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 +++ b/cicecore/drivers/nuopc/cmeps/ice_comp_nuopc.F90 @@ -95,6 +95,7 @@ module ice_comp_nuopc logical :: profile_memory = .false. logical :: mastertask logical :: runtimelog = .false. + logical :: restart_eor = .false. !End of run restart flag integer :: start_ymd ! Start date (YYYYMMDD) integer :: start_tod ! start time of day (s) integer :: curr_ymd ! Current date (YYYYMMDD) @@ -316,6 +317,12 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logmsg,*) runtimelog call ESMF_LogWrite('CICE_cap:RunTimeLog = '//trim(logmsg), ESMF_LOGMSG_INFO) + call NUOPC_CompAttributeGet(gcomp, name="write_restart_at_endofrun", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + if (trim(cvalue) .eq. '.true.') restart_eor = .true. + endif + !---------------------------------------------------------------------------- ! generate local mpi comm !---------------------------------------------------------------------------- @@ -1139,6 +1146,8 @@ subroutine ModelAdvance(gcomp, rc) call ESMF_ClockGetAlarm(clock, alarmname='alarm_restart', alarm=alarm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + force_restart_now = .false. + if (ESMF_AlarmIsRinging(alarm, rc=rc)) then if (ChkErr(rc,__LINE__,u_FILE_u)) return force_restart_now = .true. @@ -1152,8 +1161,18 @@ subroutine ModelAdvance(gcomp, rc) write(restart_date,"(i4.4,a,i2.2,a,i2.2,a,i5.5)") yy, '-', mm, '-',dd,'-',tod write(restart_filename,'(4a)') trim(restart_dir), trim(restart_file), '.', trim(restart_date) - else - force_restart_now = .false. + endif + + ! Handle end of run restart + if (restart_eor) then + call ESMF_ClockGetAlarm(clock, alarmname='alarm_stop', alarm=alarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (ESMF_AlarmIsRinging(alarm, rc=rc)) then + if (ChkErr(rc,__LINE__,u_FILE_u)) return + force_restart_now = .true. + call ESMF_AlarmRingerOff( alarm, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif endif !-------------------------------- diff --git a/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 b/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 index 47abb0373..6b539a051 100644 --- a/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 +++ b/cicecore/drivers/nuopc/cmeps/ice_import_export.F90 @@ -1495,6 +1495,7 @@ subroutine SetScalarField(field, flds_scalar_name, flds_scalar_num, rc) ! local variables type(ESMF_Distgrid) :: distgrid type(ESMF_Grid) :: grid + real(ESMF_KIND_R8), pointer :: fldptr2d(:,:) character(len=*), parameter :: subname='(ice_import_export:SetScalarField)' ! ---------------------------------------------- @@ -1511,6 +1512,11 @@ subroutine SetScalarField(field, flds_scalar_name, flds_scalar_num, rc) ungriddedLBound=(/1/), ungriddedUBound=(/flds_scalar_num/), gridToFieldMap=(/2/), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! initialize fldptr to zero + call ESMF_FieldGet(field, farrayPtr=fldptr2d, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + fldptr2d(:,:) = 0.0 + end subroutine SetScalarField end subroutine fldlist_realize