From 596c4ce40cba382c6602dd05ff477fa9dc693c5a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Sep 2022 07:48:04 -0600 Subject: [PATCH 01/12] correct mismatch of leap year --- streams/dshr_strdata_mod.F90 | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index cabe05f7f1..75943904f2 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -19,7 +19,7 @@ module dshr_strdata_mod use ESMF , only : ESMF_FieldReGridStore, ESMF_FieldRedistStore, ESMF_UNMAPPEDACTION_IGNORE use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_FieldRegrid, ESMF_FieldFill, ESMF_FieldIsCreated use ESMF , only : ESMF_REGION_TOTAL, ESMF_FieldGet, ESMF_TraceRegionExit, ESMF_TraceRegionEnter - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_RC_ARG_VALUE + use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_RC_ARG_OUTOFRANGE use shr_kind_mod , only : r8=>shr_kind_r8, r4=>shr_kind_r4, i2=>shr_kind_I2 use shr_kind_mod , only : cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx use shr_sys_mod , only : shr_sys_abort @@ -948,11 +948,25 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) if (newData(ns)) then ! Reset time bounds if newdata read in - call shr_cal_date2ymd(sdat%pstrm(ns)%ymdLB,year,month,day) + call shr_cal_date2ymd(sdat%pstrm(ns)%ymdUB,year,month,day) + print *,__FILE__,__LINE__,'Upper bound:',sdat%pstrm(ns)%ymdUB,year,month,day + call shr_cal_timeSet(timeLB,sdat%pstrm(ns)%ymdLB,0,sdat%stream(ns)%calendar,rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,sdat%stream(ns)%calendar,rc=rc) + if(rc .ne. ESMF_SUCCESS) then + if(month .eq. 2 .and. day .eq. 29) then + ! Change the date to 0301 (0229 + 72) + write(sdat%stream(1)%logunit, *) trim(subname),': Leap year date conflict, adjusting time upper bound' + sdat%pstrm(ns)%ymdUB = sdat%pstrm(ns)%ymdUB + 72 + call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,sdat%stream(ns)%calendar,rc=rc) + endif + endif + print *,__FILE__,__LINE__,rc if (ChkErr(rc,__LINE__,u_FILE_u)) return + timeint = timeUB-timeLB call ESMF_TimeIntervalGet(timeint, StartTimeIn=timeLB, d=dday) if (ChkErr(rc,__LINE__,u_FILE_u)) return From 9433e3ae09567b6e39154833bf2a0420bc66abf7 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Sep 2022 16:07:18 -0600 Subject: [PATCH 02/12] a better fix for leap year mismatch --- streams/dshr_strdata_mod.F90 | 13 ------------- streams/dshr_stream_mod.F90 | 6 ++++++ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 75943904f2..de2417b166 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -948,23 +948,10 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) if (newData(ns)) then ! Reset time bounds if newdata read in - call shr_cal_date2ymd(sdat%pstrm(ns)%ymdUB,year,month,day) - print *,__FILE__,__LINE__,'Upper bound:',sdat%pstrm(ns)%ymdUB,year,month,day - call shr_cal_timeSet(timeLB,sdat%pstrm(ns)%ymdLB,0,sdat%stream(ns)%calendar,rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,sdat%stream(ns)%calendar,rc=rc) - if(rc .ne. ESMF_SUCCESS) then - if(month .eq. 2 .and. day .eq. 29) then - ! Change the date to 0301 (0229 + 72) - write(sdat%stream(1)%logunit, *) trim(subname),': Leap year date conflict, adjusting time upper bound' - sdat%pstrm(ns)%ymdUB = sdat%pstrm(ns)%ymdUB + 72 - call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,sdat%stream(ns)%calendar,rc=rc) - endif - endif - print *,__FILE__,__LINE__,rc if (ChkErr(rc,__LINE__,u_FILE_u)) return timeint = timeUB-timeLB diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index 301718133a..95bc6e8196 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -25,6 +25,7 @@ module dshr_stream_mod use shr_cal_mod , only : shr_cal_calendarName use shr_cal_mod , only : shr_cal_advDate use shr_cal_mod , only : shr_cal_advdateint + use shr_cal_mod , only : shr_cal_leapyear use dshr_methods_mod , only : chkerr use pio , only : pio_noerr, pio_seterrorhandling, pio_inq_att, pio_openfile, pio_closefile use pio , only : file_desc_t, pio_inq_varid, iosystem_desc_t, pio_file_is_open @@ -1159,6 +1160,11 @@ subroutine shr_stream_findBounds(strm, mDateIn, secIn, isroot_task, & dDateUB = strm%file(k_ub)%date(n_ub) call shr_cal_date2ymd(dDateUB,yy,mm,dd) yy = yy + (mYear-dYear) + if(mm == 2 .and. dd==29 .and. .not. shr_cal_leapyear(yy)) then + if(isroot_task) write(strm%logunit, *) 'Found leapyear mismatch', myear, dyear + mm = 3 + dd = 1 + endif call shr_cal_ymd2date(yy,mm,dd,mDateUB) secUB = strm%file(k_ub)%secs(n_ub) fileUB = strm%file(k_ub)%name From 9039bccfda63809fd25f36abc20b5ddcf50045f7 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Sep 2022 16:21:40 -0600 Subject: [PATCH 03/12] add standalone function --- share/shr_cal_mod.F90 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/share/shr_cal_mod.F90 b/share/shr_cal_mod.F90 index 086fbec537..73380cf91b 100644 --- a/share/shr_cal_mod.F90 +++ b/share/shr_cal_mod.F90 @@ -89,6 +89,7 @@ module shr_cal_mod public :: shr_cal_ymdtod2string ! translate ymdtod to string for filenames public :: shr_cal_datetod2string ! translate date to string for filenames public :: shr_cal_ymds2rday_offset ! translate yr,month,day,sec offset to a fractional day offset + public :: shr_cal_leapyear ! logical function: is this a leap year? ! !PUBLIC DATA MEMBERS: @@ -1410,5 +1411,18 @@ subroutine shr_cal_ymds2rday_offset(etime, rdays_offset, & if(rc /= ESMF_SUCCESS) call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) end subroutine shr_cal_ymds2rday_offset + logical function shr_cal_leapyear(yr) + integer, intent(in) :: yr + shr_cal_leapyear = .false. + if (real(yr)/4.0 == yr/4) then + if (real(yr)/100.0 == yr/100) then + if(real(yr)/400.0 == yr/400) then + shr_cal_leapyear = .true. + endif + else + shr_cal_leapyear = .true. + endif + endif + end function shr_cal_leapyear !=============================================================================== end module shr_cal_mod From f8f441687d3cb87eddc6fab29fe85467bee1571e Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Sep 2022 11:54:39 -0600 Subject: [PATCH 04/12] now handling all edge cases --- datm/atm_comp_nuopc.F90 | 3 ++- streams/dshr_strdata_mod.F90 | 35 ++++++++++++++++++++++++++++++++--- streams/dshr_stream_mod.F90 | 5 ++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 99a91841b5..285ac33564 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -445,7 +445,7 @@ end subroutine InitializeRealize !=============================================================================== subroutine ModelAdvance(gcomp, rc) - + use shr_file_mod, only : shr_file_setlogunit ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -472,6 +472,7 @@ subroutine ModelAdvance(gcomp, rc) !------------------------------------------------------------------------------- rc = ESMF_SUCCESS + call shr_file_setlogunit(logunit) call ESMF_TraceRegionEnter(subname) call memcheck(subname, 5, my_task==main_task) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index de2417b166..07e8a93b47 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -26,7 +26,7 @@ module dshr_strdata_mod use shr_const_mod , only : shr_const_pi, shr_const_cDay, shr_const_spval use shr_cal_mod , only : shr_cal_calendarname, shr_cal_timeSet use shr_cal_mod , only : shr_cal_noleap, shr_cal_gregorian - use shr_cal_mod , only : shr_cal_date2ymd, shr_cal_ymd2date + use shr_cal_mod , only : shr_cal_date2ymd, shr_cal_ymd2date, shr_cal_leapyear use shr_orb_mod , only : shr_orb_decl, shr_orb_cosz, shr_orb_undef_real #ifdef CESMCOUPLED use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat @@ -846,9 +846,11 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) real(r8), pointer :: data_v_dst(:) ! pointer into field bundle type(ESMF_Time) :: timeLB, timeUB ! lb and ub times type(ESMF_TimeInterval) :: timeint ! delta time + character(CL) :: calendar integer :: dday ! delta days real(r8) :: dtime ! delta time integer :: year,month,day ! date year month day + integer :: datayear,datamonth,dataday ! data date year month day integer :: nstreams integer :: stream_index integer :: lsize @@ -900,6 +902,7 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) ymdmod(ns) = ymd todmod = tod if (trim(sdat%model_calendar) /= trim(sdat%stream(ns)%calendar)) then + calendar = shr_cal_noleap if (( trim(sdat%model_calendar) == trim(shr_cal_gregorian)) .and. & (trim(sdat%stream(ns)%calendar) == trim(shr_cal_noleap))) then ! case (1), set feb 29 = feb 28 @@ -916,6 +919,31 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) trim(sdat%model_calendar),':',trim(sdat%stream(ns)%calendar) call shr_sys_abort(trim(subname)//' ERROR: mismatch calendar ') endif + else ! calendars are the same + if(trim(sdat%model_calendar) == trim(shr_cal_gregorian)) then + ! Both are in gregorian - but it's possible that there is a mismatch + ! such that the model is in leapyear but the data is not + call shr_cal_date2ymd (ymd,year,month,day) + call shr_cal_date2ymd(sdat%pstrm(ns)%ymdUB, datayear, datamonth, dataday) + + if(month == 2 .and. day==29) then + if(.not. shr_cal_leapyear(datayear)) then + ! model is in leap year but data is not + calendar = shr_cal_noleap + endif + else if(datamonth == 2) then + if(.not. shr_cal_leapyear(year)) then + if(debug .and. sdat%mainproc) then + write(logunit, *) subname,' dataday = ', dataday + endif + calendar = shr_cal_noleap + endif + else + calendar = sdat%model_calendar + endif + else + calendar = sdat%model_calendar + endif endif ! --------------------------------------------------------- @@ -948,10 +976,10 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) if (newData(ns)) then ! Reset time bounds if newdata read in - call shr_cal_timeSet(timeLB,sdat%pstrm(ns)%ymdLB,0,sdat%stream(ns)%calendar,rc=rc) + call shr_cal_timeSet(timeLB,sdat%pstrm(ns)%ymdLB,0,calendar,rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,sdat%stream(ns)%calendar,rc=rc) + call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,calendar,rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return timeint = timeUB-timeLB @@ -965,6 +993,7 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) if ((sdat%pstrm(ns)%dtmax/sdat%pstrm(ns)%dtmin) > sdat%stream(ns)%dtlimit) then if (sdat%mainproc) then write(sdat%stream(1)%logunit,*) trim(subname),' ERROR: for stream ',ns + write(sdat%stream(1)%logunit,*) trim(subname),' ERROR: dday = ',dday write(sdat%stream(1)%logunit,*) trim(subName),' ERROR: dtime, dtmax, dtmin, dtlimit = ',& dtime, sdat%pstrm(ns)%dtmax, sdat%pstrm(ns)%dtmin, sdat%stream(ns)%dtlimit write(sdat%stream(1)%logunit,*) trim(subName),' ERROR: ymdLB, todLB, ymdUB, todUB = ', & diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index 95bc6e8196..ca8342749b 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -819,6 +819,9 @@ subroutine shr_stream_findBounds(strm, mDateIn, secIn, isroot_task, & if (cycle) then dYear = yrFirst + modulo(mYear-yrAlign+(2*nYears),nYears) ! current data year + if(debug .and. isroot_task) then + write(strm%logunit, *) trim(subname), ' dyear, yrfirst, myear, yralign, nyears =', dyear, yrfirst, myear, yralign, nyears + endif else dYear = yrFirst + mYear - yrAlign endif @@ -1161,7 +1164,7 @@ subroutine shr_stream_findBounds(strm, mDateIn, secIn, isroot_task, & call shr_cal_date2ymd(dDateUB,yy,mm,dd) yy = yy + (mYear-dYear) if(mm == 2 .and. dd==29 .and. .not. shr_cal_leapyear(yy)) then - if(isroot_task) write(strm%logunit, *) 'Found leapyear mismatch', myear, dyear + if(isroot_task) write(strm%logunit, *) 'Found leapyear mismatch', myear, dyear, yy mm = 3 dd = 1 endif From 622a4184d28d3744f305bbd6c7358ab75e09071a Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Sep 2022 11:58:01 -0600 Subject: [PATCH 05/12] fix issue with gnu compiler --- streams/dshr_stream_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/streams/dshr_stream_mod.F90 b/streams/dshr_stream_mod.F90 index ca8342749b..63d9cdb05f 100644 --- a/streams/dshr_stream_mod.F90 +++ b/streams/dshr_stream_mod.F90 @@ -819,7 +819,7 @@ subroutine shr_stream_findBounds(strm, mDateIn, secIn, isroot_task, & if (cycle) then dYear = yrFirst + modulo(mYear-yrAlign+(2*nYears),nYears) ! current data year - if(debug .and. isroot_task) then + if(debug>0 .and. isroot_task) then write(strm%logunit, *) trim(subname), ' dyear, yrfirst, myear, yralign, nyears =', dyear, yrfirst, myear, yralign, nyears endif else From 0f3f7070c208a5de221577566b50e6dcfa6e7766 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Sep 2022 12:01:06 -0600 Subject: [PATCH 06/12] fix issue with gnu compiler --- streams/dshr_strdata_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 07e8a93b47..4c9eb26669 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -933,7 +933,7 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) endif else if(datamonth == 2) then if(.not. shr_cal_leapyear(year)) then - if(debug .and. sdat%mainproc) then + if(debug>0 .and. sdat%mainproc) then write(logunit, *) subname,' dataday = ', dataday endif calendar = shr_cal_noleap From 1480393892413c5e5d1a05d418318816c16c4fef Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Sep 2022 12:11:13 -0600 Subject: [PATCH 07/12] undo rework of logging, needs to be in a seperate pr --- datm/atm_comp_nuopc.F90 | 43 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 285ac33564..2c2a8825d8 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -122,9 +122,7 @@ module cdeps_datm_comp integer :: iradsw = 0 ! radiation interval (input namelist) character(CL) :: factorFn_mesh = 'null' ! file containing correction factors mesh character(CL) :: factorFn_data = 'null' ! file containing correction factors data - logical :: flds_presaero = .false. ! true => send valid prescribed aero fields to mediator - logical :: flds_presndep = .false. ! true => send valid prescribed ndep fields to mediator - logical :: flds_preso3 = .false. ! true => send valid prescribed ozone fields to mediator + logical :: flds_presaero = .false. ! true => send valid prescribe aero fields to mediator logical :: flds_co2 = .false. ! true => send prescribed co2 to mediator logical :: flds_wiso = .false. ! true => send water isotopes to mediator character(CL) :: bias_correct = nullstr ! send bias correction fields to coupler @@ -133,7 +131,6 @@ module cdeps_datm_comp character(CL) :: restfilm = nullstr ! model restart file namelist integer :: nx_global ! global nx integer :: ny_global ! global ny - logical :: skip_restart_read = .false. ! true => skip restart read in continuation run ! linked lists type(fldList_type) , pointer :: fldsImport => null() @@ -230,8 +227,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) namelist / datm_nml / datamode, & model_meshfile, model_maskfile, & nx_global, ny_global, restfilm, iradsw, factorFn_data, factorFn_mesh, & - flds_presaero, flds_co2, flds_wiso, bias_correct, anomaly_forcing, & - skip_restart_read, flds_presndep, flds_preso3 + flds_presaero, flds_co2, flds_wiso, bias_correct, anomaly_forcing rc = ESMF_SUCCESS @@ -270,11 +266,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call shr_mpi_bcast(factorFn_mesh , mpicom, 'factorFn_mesh') call shr_mpi_bcast(restfilm , mpicom, 'restfilm') call shr_mpi_bcast(flds_presaero , mpicom, 'flds_presaero') - call shr_mpi_bcast(flds_presndep , mpicom, 'flds_presndep') - call shr_mpi_bcast(flds_preso3 , mpicom, 'flds_preso3') call shr_mpi_bcast(flds_co2 , mpicom, 'flds_co2') call shr_mpi_bcast(flds_wiso , mpicom, 'flds_wiso') - call shr_mpi_bcast(skip_restart_read , mpicom, 'skip_restart_read') ! write namelist input to standard out if (my_task == main_task) then @@ -289,11 +282,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F00)' factorFn_data = ',trim(factorFn_data) write(logunit,F00)' factorFn_mesh = ',trim(factorFn_mesh) write(logunit,F02)' flds_presaero = ',flds_presaero - write(logunit,F02)' flds_presndep = ',flds_presndep - write(logunit,F02)' flds_preso3 = ',flds_preso3 write(logunit,F02)' flds_co2 = ',flds_co2 write(logunit,F02)' flds_wiso = ',flds_wiso - write(logunit,F02)' skip_restart_read = ',skip_restart_read end if ! Validate sdat datamode @@ -314,19 +304,19 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) select case (trim(datamode)) case ('CORE2_NYF', 'CORE2_IAF') call datm_datamode_core2_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, flds_presndep, rc) + flds_co2, flds_wiso, flds_presaero, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('CORE_IAF_JRA') call datm_datamode_jra_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, flds_presndep, rc) + flds_co2, flds_wiso, flds_presaero, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('CLMNCEP') call datm_datamode_clmncep_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, flds_presndep, flds_preso3, rc) + flds_co2, flds_wiso, flds_presaero, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('CPLHIST') call datm_datamode_cplhist_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, flds_presndep, rc) + flds_co2, flds_wiso, flds_presaero, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('ERA5') call datm_datamode_era5_advertise(exportState, fldsExport, flds_scalar_name, rc) @@ -413,7 +403,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Initialize and update orbital values call dshr_orbital_init(gcomp, logunit, my_task == main_task, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call dshr_orbital_update(currTime, logunit, my_task == main_task, & + call dshr_orbital_update(clock, logunit, my_task == main_task, & orbEccen, orbObliqr, orbLambm0, orbMvelpp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -445,7 +435,7 @@ end subroutine InitializeRealize !=============================================================================== subroutine ModelAdvance(gcomp, rc) - use shr_file_mod, only : shr_file_setlogunit + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -472,7 +462,6 @@ subroutine ModelAdvance(gcomp, rc) !------------------------------------------------------------------------------- rc = ESMF_SUCCESS - call shr_file_setlogunit(logunit) call ESMF_TraceRegionEnter(subname) call memcheck(subname, 5, my_task==main_task) @@ -492,13 +481,13 @@ subroutine ModelAdvance(gcomp, rc) call shr_cal_ymd2date(yr, mon, day, next_ymd) ! Update the orbital values - call dshr_orbital_update(nextTime, logunit, my_task == main_task, & + call dshr_orbital_update(clock, logunit, my_task == main_task, & orbEccen, orbObliqr, orbLambm0, orbMvelpp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return restart_write = dshr_check_restart_alarm(clock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! Run datm call ESMF_TraceRegionEnter('datm_run') call datm_comp_run(importstate, exportstate, next_ymd, next_tod, mon, & @@ -584,7 +573,7 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe end select ! Read restart if needed - if (restart_read .and. .not. skip_restart_read) then + if (restart_read) then select case (trim(datamode)) case('CORE2_NYF','CORE2_IAF') call datm_datamode_core2_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) @@ -712,7 +701,6 @@ subroutine datm_init_dfields(rc) ! local variables integer :: n - character(CS) :: strm_flds2(2) character(CS) :: strm_flds3(3) character(CS) :: strm_flds4(4) integer :: rank @@ -739,10 +727,6 @@ subroutine datm_init_dfields(rc) exportState, logunit, mainproc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return else if (rank == 2) then - ! The following maps stream input fields to export fields that have an ungridded dimension - ! TODO: in the future it might be better to change the format of the streams file to have two more entries - ! that could denote how the stream variables are mapped to export fields that have an ungridded dimension - select case (trim(lfieldnames(n))) case('Faxa_bcph') strm_flds3 = (/'Faxa_bcphidry', 'Faxa_bcphodry', 'Faxa_bcphiwet'/) @@ -776,11 +760,6 @@ subroutine datm_init_dfields(rc) strm_flds3 = (/'Faxa_snowl_16O', 'Faxa_snowl_18O', 'Faxa_snowl_HDO'/) call dshr_dfield_add(dfields, sdat, trim(lfieldnames(n)), strm_flds3, exportState, logunit, mainproc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - case('Faxa_ndep') - strm_flds2 = (/'Faxa_ndep_nhx', 'Faxa_ndep_noy'/) - call dshr_dfield_add(dfields, sdat, trim(lfieldnames(n)), strm_flds2, exportState, logunit, mainproc, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end select end if end do From a82c9b7dc4f91c1f949f808b6c3c997712da5e31 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Sep 2022 12:15:30 -0600 Subject: [PATCH 08/12] get the base version correctly --- datm/atm_comp_nuopc.F90 | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/datm/atm_comp_nuopc.F90 b/datm/atm_comp_nuopc.F90 index 2c2a8825d8..99a91841b5 100644 --- a/datm/atm_comp_nuopc.F90 +++ b/datm/atm_comp_nuopc.F90 @@ -122,7 +122,9 @@ module cdeps_datm_comp integer :: iradsw = 0 ! radiation interval (input namelist) character(CL) :: factorFn_mesh = 'null' ! file containing correction factors mesh character(CL) :: factorFn_data = 'null' ! file containing correction factors data - logical :: flds_presaero = .false. ! true => send valid prescribe aero fields to mediator + logical :: flds_presaero = .false. ! true => send valid prescribed aero fields to mediator + logical :: flds_presndep = .false. ! true => send valid prescribed ndep fields to mediator + logical :: flds_preso3 = .false. ! true => send valid prescribed ozone fields to mediator logical :: flds_co2 = .false. ! true => send prescribed co2 to mediator logical :: flds_wiso = .false. ! true => send water isotopes to mediator character(CL) :: bias_correct = nullstr ! send bias correction fields to coupler @@ -131,6 +133,7 @@ module cdeps_datm_comp character(CL) :: restfilm = nullstr ! model restart file namelist integer :: nx_global ! global nx integer :: ny_global ! global ny + logical :: skip_restart_read = .false. ! true => skip restart read in continuation run ! linked lists type(fldList_type) , pointer :: fldsImport => null() @@ -227,7 +230,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) namelist / datm_nml / datamode, & model_meshfile, model_maskfile, & nx_global, ny_global, restfilm, iradsw, factorFn_data, factorFn_mesh, & - flds_presaero, flds_co2, flds_wiso, bias_correct, anomaly_forcing + flds_presaero, flds_co2, flds_wiso, bias_correct, anomaly_forcing, & + skip_restart_read, flds_presndep, flds_preso3 rc = ESMF_SUCCESS @@ -266,8 +270,11 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) call shr_mpi_bcast(factorFn_mesh , mpicom, 'factorFn_mesh') call shr_mpi_bcast(restfilm , mpicom, 'restfilm') call shr_mpi_bcast(flds_presaero , mpicom, 'flds_presaero') + call shr_mpi_bcast(flds_presndep , mpicom, 'flds_presndep') + call shr_mpi_bcast(flds_preso3 , mpicom, 'flds_preso3') call shr_mpi_bcast(flds_co2 , mpicom, 'flds_co2') call shr_mpi_bcast(flds_wiso , mpicom, 'flds_wiso') + call shr_mpi_bcast(skip_restart_read , mpicom, 'skip_restart_read') ! write namelist input to standard out if (my_task == main_task) then @@ -282,8 +289,11 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) write(logunit,F00)' factorFn_data = ',trim(factorFn_data) write(logunit,F00)' factorFn_mesh = ',trim(factorFn_mesh) write(logunit,F02)' flds_presaero = ',flds_presaero + write(logunit,F02)' flds_presndep = ',flds_presndep + write(logunit,F02)' flds_preso3 = ',flds_preso3 write(logunit,F02)' flds_co2 = ',flds_co2 write(logunit,F02)' flds_wiso = ',flds_wiso + write(logunit,F02)' skip_restart_read = ',skip_restart_read end if ! Validate sdat datamode @@ -304,19 +314,19 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) select case (trim(datamode)) case ('CORE2_NYF', 'CORE2_IAF') call datm_datamode_core2_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, rc) + flds_co2, flds_wiso, flds_presaero, flds_presndep, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('CORE_IAF_JRA') call datm_datamode_jra_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, rc) + flds_co2, flds_wiso, flds_presaero, flds_presndep, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('CLMNCEP') call datm_datamode_clmncep_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, rc) + flds_co2, flds_wiso, flds_presaero, flds_presndep, flds_preso3, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('CPLHIST') call datm_datamode_cplhist_advertise(exportState, fldsExport, flds_scalar_name, & - flds_co2, flds_wiso, flds_presaero, rc) + flds_co2, flds_wiso, flds_presaero, flds_presndep, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return case ('ERA5') call datm_datamode_era5_advertise(exportState, fldsExport, flds_scalar_name, rc) @@ -403,7 +413,7 @@ subroutine InitializeRealize(gcomp, importState, exportState, clock, rc) ! Initialize and update orbital values call dshr_orbital_init(gcomp, logunit, my_task == main_task, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call dshr_orbital_update(clock, logunit, my_task == main_task, & + call dshr_orbital_update(currTime, logunit, my_task == main_task, & orbEccen, orbObliqr, orbLambm0, orbMvelpp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -481,13 +491,13 @@ subroutine ModelAdvance(gcomp, rc) call shr_cal_ymd2date(yr, mon, day, next_ymd) ! Update the orbital values - call dshr_orbital_update(clock, logunit, my_task == main_task, & + call dshr_orbital_update(nextTime, logunit, my_task == main_task, & orbEccen, orbObliqr, orbLambm0, orbMvelpp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return restart_write = dshr_check_restart_alarm(clock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! Run datm call ESMF_TraceRegionEnter('datm_run') call datm_comp_run(importstate, exportstate, next_ymd, next_tod, mon, & @@ -573,7 +583,7 @@ subroutine datm_comp_run(importState, exportState, target_ymd, target_tod, targe end select ! Read restart if needed - if (restart_read) then + if (restart_read .and. .not. skip_restart_read) then select case (trim(datamode)) case('CORE2_NYF','CORE2_IAF') call datm_datamode_core2_restart_read(restfilm, inst_suffix, logunit, my_task, mpicom, sdat) @@ -701,6 +711,7 @@ subroutine datm_init_dfields(rc) ! local variables integer :: n + character(CS) :: strm_flds2(2) character(CS) :: strm_flds3(3) character(CS) :: strm_flds4(4) integer :: rank @@ -727,6 +738,10 @@ subroutine datm_init_dfields(rc) exportState, logunit, mainproc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return else if (rank == 2) then + ! The following maps stream input fields to export fields that have an ungridded dimension + ! TODO: in the future it might be better to change the format of the streams file to have two more entries + ! that could denote how the stream variables are mapped to export fields that have an ungridded dimension + select case (trim(lfieldnames(n))) case('Faxa_bcph') strm_flds3 = (/'Faxa_bcphidry', 'Faxa_bcphodry', 'Faxa_bcphiwet'/) @@ -760,6 +775,11 @@ subroutine datm_init_dfields(rc) strm_flds3 = (/'Faxa_snowl_16O', 'Faxa_snowl_18O', 'Faxa_snowl_HDO'/) call dshr_dfield_add(dfields, sdat, trim(lfieldnames(n)), strm_flds3, exportState, logunit, mainproc, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + case('Faxa_ndep') + strm_flds2 = (/'Faxa_ndep_nhx', 'Faxa_ndep_noy'/) + call dshr_dfield_add(dfields, sdat, trim(lfieldnames(n)), strm_flds2, exportState, logunit, mainproc, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end select end if end do From b0870996d759a9109dbb3076a8a021ccd456ab25 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 23 Sep 2022 13:54:47 -0600 Subject: [PATCH 09/12] use modulo here --- share/shr_cal_mod.F90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/share/shr_cal_mod.F90 b/share/shr_cal_mod.F90 index 73380cf91b..a562306f4b 100644 --- a/share/shr_cal_mod.F90 +++ b/share/shr_cal_mod.F90 @@ -1411,18 +1411,21 @@ subroutine shr_cal_ymds2rday_offset(etime, rdays_offset, & if(rc /= ESMF_SUCCESS) call ESMF_Finalize(rc=rc, endflag=ESMF_END_ABORT) end subroutine shr_cal_ymds2rday_offset + !=============================================================================== logical function shr_cal_leapyear(yr) integer, intent(in) :: yr shr_cal_leapyear = .false. - if (real(yr)/4.0 == yr/4) then - if (real(yr)/100.0 == yr/100) then - if(real(yr)/400.0 == yr/400) then + if (modulo(yr, 4) == 0) then + if (modulo(yr, 100) == 0) then + if(modulo(yr, 400) == 0) then shr_cal_leapyear = .true. endif else shr_cal_leapyear = .true. endif endif + end function shr_cal_leapyear + !=============================================================================== end module shr_cal_mod From 413c55122b3d7879f233a9a468548af712d2ee2f Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 27 Sep 2022 07:46:08 -0600 Subject: [PATCH 10/12] remove unused ESMF variable --- streams/dshr_strdata_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 4c9eb26669..9e58fac0b0 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -19,7 +19,7 @@ module dshr_strdata_mod use ESMF , only : ESMF_FieldReGridStore, ESMF_FieldRedistStore, ESMF_UNMAPPEDACTION_IGNORE use ESMF , only : ESMF_TERMORDER_SRCSEQ, ESMF_FieldRegrid, ESMF_FieldFill, ESMF_FieldIsCreated use ESMF , only : ESMF_REGION_TOTAL, ESMF_FieldGet, ESMF_TraceRegionExit, ESMF_TraceRegionEnter - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_RC_ARG_OUTOFRANGE + use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite use shr_kind_mod , only : r8=>shr_kind_r8, r4=>shr_kind_r4, i2=>shr_kind_I2 use shr_kind_mod , only : cs=>shr_kind_cs, cl=>shr_kind_cl, cxx=>shr_kind_cxx use shr_sys_mod , only : shr_sys_abort From e3d1a6790d86b5376ca4456c9b6d97d6d35269c9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 27 Sep 2022 08:03:44 -0600 Subject: [PATCH 11/12] add further documentation --- streams/dshr_strdata_mod.F90 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 9e58fac0b0..64fff9aebf 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -786,7 +786,14 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) ! on the time series input data. ! ! (0) The stream calendar and model calendar are identical: - ! Proceed in the standard way. + ! In this case it is still possible to have a mismatch if both are gregorian. + ! These cases are: + ! - Model is no_leap, data is Gregorian and leapyear date 2/29 is encountered in data - skip date + ! - Model is Gregorian, data is no_leap and leapyear date 2/29 is encountered in model - repeat 2/28 data + ! - Model is Gregorian, data is gregorian but leapyears do not align. + ! - if in model leap year repeat data from 2/28 + ! - if in data leap year skip date 2/29 + ! ! ! (1) The stream is a no leap calendar and the model is gregorian: ! Time interpolate on the noleap calendar. If the model date is Feb 29, From 4f30632cec329ca87136fabbaccbd99b48ca8290 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 29 Sep 2022 08:54:05 -0600 Subject: [PATCH 12/12] one more calendar mod --- streams/dshr_strdata_mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/streams/dshr_strdata_mod.F90 b/streams/dshr_strdata_mod.F90 index 64fff9aebf..53e68d808f 100644 --- a/streams/dshr_strdata_mod.F90 +++ b/streams/dshr_strdata_mod.F90 @@ -908,8 +908,8 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) ! case(0) ymdmod(ns) = ymd todmod = tod + calendar = trim(sdat%stream(ns)%calendar) if (trim(sdat%model_calendar) /= trim(sdat%stream(ns)%calendar)) then - calendar = shr_cal_noleap if (( trim(sdat%model_calendar) == trim(shr_cal_gregorian)) .and. & (trim(sdat%stream(ns)%calendar) == trim(shr_cal_noleap))) then ! case (1), set feb 29 = feb 28 @@ -917,6 +917,7 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) if (month == 2 .and. day == 29) then call shr_cal_ymd2date(year,2,28,ymdmod(ns)) endif + calendar = shr_cal_noleap else if ((trim(sdat%model_calendar) == trim(shr_cal_noleap)) .and. & (trim(sdat%stream(ns)%calendar) == trim(shr_cal_gregorian))) then ! case (2), feb 29 input data will be skipped automatically @@ -985,7 +986,6 @@ subroutine shr_strdata_advance(sdat, ymd, tod, logunit, istr, timers, rc) ! Reset time bounds if newdata read in call shr_cal_timeSet(timeLB,sdat%pstrm(ns)%ymdLB,0,calendar,rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call shr_cal_timeSet(timeUB,sdat%pstrm(ns)%ymdUB,0,calendar,rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return