From f5cebc7825c319b62c022ba1eb6fa1be999f5eb5 Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Fri, 23 Feb 2024 09:23:23 +0000 Subject: [PATCH 1/7] Initial version of 360 day calendar support in ww3_prnc --- model/src/ww3_prnc.F90 | 102 +++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/model/src/ww3_prnc.F90 b/model/src/ww3_prnc.F90 index 59747d32ab..c15b065dd9 100644 --- a/model/src/ww3_prnc.F90 +++ b/model/src/ww3_prnc.F90 @@ -245,7 +245,7 @@ PROGRAM W3PRNC NDSLL, IDLALL, IDFMLL, NCID, IRET, & MXM, MYM, DATTYP, RECLDT, IDAT, & NDIMSGRID, NDIMSVAR, VARIDTMP, & - NUMDIMS, I, ITIME + NUMDIMS, I, ITIME, SECS INTEGER :: ILAND = -999 INTEGER :: GTYPEDUM = 0 @@ -594,10 +594,19 @@ PROGRAM W3PRNC ! Check time start and stop READ(NML_FORCING%TIMESTART,*) TIMESTART CALL T2D(TIMESTART,STARTDATE,IERR) - CALL D2J(STARTDATE,STARTJULDAY,IERR) READ(NML_FORCING%TIMESTOP,*) TIMESTOP CALL T2D(TIMESTOP,STPDATE,IERR) - CALL D2J(STPDATE,STPJULDAY,IERR) + + IF(TRIM(CALTYPE) .EQ. "standard") THEN + CALL D2J(STARTDATE,STARTJULDAY,IERR) + CALL D2J(STPDATE,STPJULDAY,IERR) + ELSE IF(TRIM(CALTYPE) .EQ. "360_day") THEN + CALL D2J_360(STARTDATE,STARTJULDAY,IERR) + CALL D2J_360(STPDATE,STPJULDAY,IERR) + ELSE + PRINT*,'INTERNAL ERROR - UKNOWN CALENDAR TYPE: ', CALTYPE + CALL EXTCDE(99) + ENDIF ! Check time shift FLHDR = .TRUE. @@ -766,6 +775,9 @@ PROGRAM W3PRNC CALL STME21 ( TIMESTOP , IDTIME ) IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,2931) IDTIME END IF + IF(CALTYPE .NE. 'standard') THEN + IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,2932) CALTYPE + ENDIF END IF IF (.NOT. FLTIME) THEN CALL STME21 ( TIMESHIFT , IDTIME ) @@ -798,14 +810,34 @@ PROGRAM W3PRNC IRET=NF90_GET_ATT(NCID,VARIDTMP,"calendar",CALENDAR) IF ( IRET/=NF90_NOERR ) THEN WRITE(NDSE,1028) - ELSE IF ((INDEX(CALENDAR, "standard").EQ.0) .AND. & - (INDEX(CALENDAR, "gregorian").EQ.0)) THEN - WRITE(NDSE,1029) + ELSE IF ((INDEX(CALENDAR, "standard") .GT. 0) .OR. & + (INDEX(CALENDAR, "gregorian") .GT. 0)) THEN + CALENDAR = "standard" + ELSE IF (INDEX(CALENDAR, "360_day") .GT. 0) THEN + CALENDAR = "360_day" + ELSE + WRITE(NDSE,1029) CALENDAR + CALENDAR = "standard" ! Default to standard calendar. Better to maybe fail? END IF + + ! Check input calendar compatible with expected calendar + IF(CALENDAR .NE. CALTYPE) THEN + WRITE(NDSE,1027) CALTYPE, CALENDAR + CALL EXTCDE( 26 ) + ENDIF + IRET=NF90_GET_ATT(NCID,VARIDTMP,"units",TIMEUNITS) CALL CHECK_ERR(IRET) CALL U2D(TIMEUNITS,REFDATE,IERR) - CALL D2J(REFDATE,REFJULDAY,IERR) + + IF(CALENDAR .EQ. "standard") THEN + CALL D2J(REFDATE,REFJULDAY,IERR) + ELSE IF(CALENDAR .EQ. "360_day") THEN + CALL D2J_360(REFDATE, REFJULDAY, IERR) + ELSE + PRINT*,'INTERNAL ERROR, CALENDAR=',CALENDAR + CALL EXTCDE( 99 ) + ENDIF ! gets variables ids, dimensions and fillvalue DO I=1,NFIELDS @@ -821,7 +853,7 @@ PROGRAM W3PRNC END DO IRET=NF90_GET_ATT(NCID,VARIDF(I),"_FillValue", FILLVALUE) IF ( IRET/=NF90_NOERR ) THEN - WRITE(NDSE,1027) TRIM(FIELDSNAME(I)) + WRITE(NDSE,1026) TRIM(FIELDSNAME(I)) CALL EXTCDE ( 27 ) END IF END DO @@ -1796,6 +1828,7 @@ PROGRAM W3PRNC ! IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,972) TIMEDELAY = 0 + print*,'[CB] NTI',NTI DO ITIME=1,NTI ! ! 8.a Read new time and fields @@ -1805,6 +1838,7 @@ PROGRAM W3PRNC CALL CHECK_ERR(IRET) IRET=NF90_GET_VAR(NCID,VARIDTMP,CURJULDAY,start=(/ITIME/)) call CHECK_ERR(IRET) + print*,'Got time',itime,curjulday IF (INDEX(TIMEUNITS, "seconds").NE.0) CURJULDAY=CURJULDAY/86400. IF (INDEX(TIMEUNITS, "minutes").NE.0) CURJULDAY=CURJULDAY/1440. IF (INDEX(TIMEUNITS, "hours").NE.0) CURJULDAY=CURJULDAY/24. @@ -1817,7 +1851,17 @@ PROGRAM W3PRNC IF (STPJULDAY.LT.CURJULDAY) EXIT ! convert julday to date and time - CALL J2D(CURJULDAY,CURDATE,IERR) + IF(CALTYPE .EQ. 'standard') THEN + CALL J2D(CURJULDAY,CURDATE,IERR) + ELSE IF(CALTYPE .EQ. '360_day') THEN + CURDATE(1) = INT(CURJULDAY / 360) + 1800 ! (base year is 1800) + CURDATE(2) = MOD(INT(CURJULDAY / 30), 12) + 1 + CURDATE(3) = MOD(INT(CURJULDAY), 30) + 1 + SECS = (CURJULDAY - IDINT(CURJULDAY)) * 86400 + CURDATE(5) = SECS / 3600 + CURDATE(6) = MOD(SECS, 3600) / 60 + CURDATE(7) = MOD(SECS, 60) + ENDIF CALL D2T(CURDATE,TIME,IERR) CALL STME21 (TIME,IDTIME) @@ -2317,6 +2361,7 @@ PROGRAM W3PRNC 2930 FORMAT ( ' Field corrected for energy conservation.') 1931 FORMAT ( ' Start time : ',A) 2931 FORMAT ( ' Stop time : ',A) +2932 FORMAT ( ' Calendar : ',A) 3931 FORMAT ( ' Shifted time : ',A) 932 FORMAT (/' Input grid dim. :',I9,3X,I5) 1933 FORMAT ( ' Longitude range :',2F8.2,' (deg)'/ & @@ -2404,15 +2449,21 @@ PROGRAM W3PRNC 1011 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & ' NO GRID SELECTED'/) ! -1027 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & +1026 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & ' _FillValue ATTRIBUTE NOT DEFINED FOR : ',A/) - ! + ! +1027 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & + ' INCOMPATIBLE CALENDARS:' / & + ' MODEL CALENDAR : ', A / & + ' INPUT FILE CALENDAR : ', A /) 1028 FORMAT (/' *** WAVEWATCH III WARNING IN W3PRNC : '/ & ' calendar ATTRIBUTE NOT DEFINED'/ & - ' IT MUST RESPECT STANDARD OR GREGORIAN CALENDAR') + ' DEFAULTING TO "standard" CALENDAR'/ & + ' INPUT FILE MUST RESPECT STANDARD/GREGORIAN CALENDAR') 1029 FORMAT (/' *** WAVEWATCH III WARNING IN W3PRNC : '/ & - ' CALENDAR ATTRIBUTE NOT MATCH'/ & - ' IT MUST RESPECT STANDARD OR GREGORIAN CALENDAR') + ' UNKNOWN CALENDAR TYPE: ', A / & + ' DEFAULTING TO "standard" CALENDAR'/ & + ' INPUT FILE MUST RESPECT STANDARD/GREGORIAN CALENDAR') 1030 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & ' ILLEGAL FIELD ID -->',A,'<--'/) 1031 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & @@ -2712,4 +2763,27 @@ SUBROUTINE CHECK_ERROR(IRET, ILINE) END SUBROUTINE CHECK_ERROR +!> @brief Convert a "360 day" calendar date to a pseudo-Julian date +!> @details Convert a date based on a "360 day" climate calendar (30 days +!> per month) to a pseudo-Julian date (number of days since +!> 1800-01-01 00:00:00) +!> @param DAT(8) Date/Time components, as returned from DATE_AND_TIME(3f). +!> @param JUL360 Pseudo-Julian day based on 360 day calendar +!> @author Chris Bunney @date 22 Feb 2022 +SUBROUTINE D2J_360(DAT, JUL360, IERR) + INTEGER,INTENT(IN) :: DAT(8) + DOUBLE PRECISION,INTENT(OUT) :: JUL360 + INTEGER, INTENT(OUT) :: IERR + + + JUL360 = (DAT(1) - 1800) * 360.0 + & ! Years (since 1800) + (DAT(2) - 1 ) * 30.0 + & ! Month + (DAT(3) - 1) + & ! Day + DAT(5)/24.0_8 + & ! Hour + DAT(6)/1440.0_8 + & ! Minute + DAT(7)/86400.0_8 ! Second + + IERR = 0 ! TODO! +END SUBROUTINE D2J_360 + !============================================================================== From e498895cbafe4869583e08adbd93819932e10b4c Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Fri, 23 Feb 2024 10:16:22 +0000 Subject: [PATCH 2/7] Moved 360day calendar pseudo-Julian day calculations to w3timemd. --- model/src/w3timemd.F90 | 89 ++++++++++++++++++++++++++++-------------- model/src/ww3_prnc.F90 | 68 ++++++-------------------------- 2 files changed, 72 insertions(+), 85 deletions(-) diff --git a/model/src/w3timemd.F90 b/model/src/w3timemd.F90 index 11376969fb..d2c52af077 100644 --- a/model/src/w3timemd.F90 +++ b/model/src/w3timemd.F90 @@ -6,7 +6,7 @@ MODULE W3TIMEMD !/ | WAVEWATCH III NOAA/NCEP | !/ | H. L. Tolman | !/ | FORTRAN 90 | - !/ | Last update : 12-Jan-2021 | + !/ | Last update : 23-Feb-2024 | !/ +-----------------------------------+ !/ !/ Copyright 2009 National Weather Service (NWS), @@ -1233,6 +1233,7 @@ SUBROUTINE D2J(DAT,JULIAN,IERR) !/ +-----------------------------------+ !/ !/ 04-Jan-2018 : Origination from m_time library ( version 6.04 ) + !/ 23-Feb-2024 : Updated to handle 360_day calendar ( version 7.14 ) !/ ! 1. Purpose : ! @@ -1251,6 +1252,8 @@ SUBROUTINE D2J(DAT,JULIAN,IERR) ! * There is no year zero ! * Julian Day must be non-negative ! * Julian Day starts at noon; while Civil Calendar date starts at midnight + ! * If CALTYPE is "360_day" a simpler calculation is used (30 days in every + ! month) with a reference date of 1800-01-01. ! ! 3. Parameters : ! @@ -1313,6 +1316,21 @@ SUBROUTINE D2J(DAT,JULIAN,IERR) JULIAN = -HUGE(99999) ! this is the date if an error occurs and IERR is < 0 + ! Special case for 360 day climate calendar; return a pseudo-Julian day + ! Assumes a reference date of 1800-01-01 00:00:00 + IF( CALTYPE .EQ. "360_day" ) THEN + JULIAN = (YEAR - 1800) * 360.0 + & ! Years since 1800 + (MONTH - 1) * 30.0 + & + (DAY - 1) + & + HOUR / 24.0_8 + & + MINUTE / 1440.0_8 + & + SECOND / 86400.0_8 + + IERR = 0 + RETURN + ENDIF + + ! Standard/Gregorian calenday - return standrd Julian day calculation: IF(YEAR==0 .or. YEAR .lt. -4713) THEN IERR=-1 RETURN @@ -1356,6 +1374,7 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) !/ +-----------------------------------+ !/ !/ 04-Jan-2018 : Origination from m_time library ( version 6.04 ) + !/ 23-Feb-2024 : Upated to handle 360_day calendar ( version 7.14 ) !/ ! 1. Purpose : ! @@ -1364,6 +1383,8 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) ! * There is no year zero ! * Julian Day must be non-negative ! * Julian Day starts at noon; while Civil Calendar date starts at midnight + ! * If CALTYPE is "360_day" a simpler calculation is used (30 days in every + ! month) with a reference date of 1800-01-01. ! ! 3. Parameters : ! @@ -1397,7 +1418,7 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) DOUBLE PRECISION,INTENT(IN) :: JULIAN ! Julian Day (non-negative, but may be non-integer) INTEGER,INTENT(OUT) :: DAT(8) ! array like returned by DATE_AND_TIME(3f) INTEGER,INTENT(OUT) :: IERR ! Error return, 0 for successful execution - ! Otherwise returnb 1 + ! ! otherwise return 1 !/ !/ ------------------------------------------------------------------- / !/ Local parameters @@ -1417,27 +1438,29 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) #ifdef W3_S CALL STRACE (IENT, 'J2D') #endif + ! - IF(JULIAN.LT.0.d0) THEN ! Negative Julian Day not allowed + IF(CALTYPE .EQ. 'standard' .AND. JULIAN .LT. 0.d0) THEN + ! Negative Julian Day not allowed IERR=1 RETURN - ELSE - IERR=0 END IF !CALL DATE_AND_TIME(values=TIMEZONE) ! Get the timezone !TZ=TIMEZONE(4) TZ=0 ! Force to UTC timezone + ! Calculation for time (hour,min,sec) same for Julian + ! and 360_day calendars: IJUL=IDINT(JULIAN) ! Integral Julian Day SECOND=SNGL((JULIAN-DBLE(IJUL))*SECDAY) ! Seconds from beginning of Jul. Day SECOND=SECOND+(tz*60) IF(SECOND.GE.(SECDAY/2.0d0)) THEN ! In next calendar day IJUL=IJUL+1 - SECOND=SECOND-(SECDAY/2.0d0) ! Adjust from noon to midnight + SECOND=SECOND-(SECDAY/2.0d0) ! Adjust from noon to midnight ELSE ! In same calendar day - SECOND=SECOND+(SECDAY/2.0d0) ! Adjust from noon to midnight + SECOND=SECOND+(SECDAY/2.0d0) ! Adjust from noon to midnight END IF IF(SECOND.GE.SECDAY) THEN ! Final check to prevent time 24:00:00 @@ -1450,31 +1473,38 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) HOUR=MINUTE/60 ! Integral hours from beginning of day MINUTE=MINUTE-HOUR*60 ! Integral minutes from beginning of hour - !--------------------------------------------- - JALPHA=IDINT((DBLE(IJUL-1867216)-0.25d0)/36524.25d0) ! Correction for Gregorian Calendar - JA=IJUL+1+JALPHA-IDINT(0.25d0*DBLE(JALPHA)) - !--------------------------------------------- + IF(CALTYPE .EQ. '360_day') THEN + ! Calcalate date parts for 360 day climate calendar + YEAR = INT(JULIAN / 360) + 1800 ! (base year is 1800) + MONTH = MOD(INT(JULIAN / 30), 12) + 1 + DAY = MOD(INT(JULIAN), 30) + 1 + ELSE ! Stardard Julian day calculation + !--------------------------------------------- + JALPHA=IDINT((DBLE(IJUL-1867216)-0.25d0)/36524.25d0) ! Correction for Gregorian Calendar + JA=IJUL+1+JALPHA-IDINT(0.25d0*DBLE(JALPHA)) + !--------------------------------------------- - JB=JA+1524 - JC=IDINT(6680.d0+(DBLE(JB-2439870)-122.1d0)/365.25d0) - JD=365*JC+IDINT(0.25d0*DBLE(JC)) - JE=IDINT(DBLE(JB-JD)/30.6001d0) - DAY=JB-JD-IDINT(30.6001d0*DBLE(JE)) - MONTH=JE-1 + JB=JA+1524 + JC=IDINT(6680.d0+(DBLE(JB-2439870)-122.1d0)/365.25d0) + JD=365*JC+IDINT(0.25d0*DBLE(JC)) + JE=IDINT(DBLE(JB-JD)/30.6001d0) + DAY=JB-JD-IDINT(30.6001d0*DBLE(JE)) + MONTH=JE-1 - IF(MONTH.GT.12) THEN - MONTH=MONTH-12 - END IF - - YEAR=jc-4715 - IF(MONTH.GT.2) THEN - YEAR=YEAR-1 - END IF - - IF(YEAR.LE.0) THEN - YEAR=YEAR-1 - END IF + IF(MONTH.GT.12) THEN + MONTH=MONTH-12 + END IF + YEAR=jc-4715 + IF(MONTH.GT.2) THEN + YEAR=YEAR-1 + END IF + + IF(YEAR.LE.0) THEN + YEAR=YEAR-1 + END IF + ENDIF + DAT(1)=YEAR DAT(2)=MONTH DAT(3)=DAY @@ -1487,7 +1517,6 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) ! RETURN !/ - !/ End of J2D ----------------------------------------------------- / !/ END SUBROUTINE J2D diff --git a/model/src/ww3_prnc.F90 b/model/src/ww3_prnc.F90 index c15b065dd9..6bcec65cde 100644 --- a/model/src/ww3_prnc.F90 +++ b/model/src/ww3_prnc.F90 @@ -594,19 +594,10 @@ PROGRAM W3PRNC ! Check time start and stop READ(NML_FORCING%TIMESTART,*) TIMESTART CALL T2D(TIMESTART,STARTDATE,IERR) + CALL D2J(STARTDATE,STARTJULDAY,IERR) READ(NML_FORCING%TIMESTOP,*) TIMESTOP CALL T2D(TIMESTOP,STPDATE,IERR) - - IF(TRIM(CALTYPE) .EQ. "standard") THEN - CALL D2J(STARTDATE,STARTJULDAY,IERR) - CALL D2J(STPDATE,STPJULDAY,IERR) - ELSE IF(TRIM(CALTYPE) .EQ. "360_day") THEN - CALL D2J_360(STARTDATE,STARTJULDAY,IERR) - CALL D2J_360(STPDATE,STPJULDAY,IERR) - ELSE - PRINT*,'INTERNAL ERROR - UKNOWN CALENDAR TYPE: ', CALTYPE - CALL EXTCDE(99) - ENDIF + CALL D2J(STPDATE,STPJULDAY,IERR) ! Check time shift FLHDR = .TRUE. @@ -829,15 +820,7 @@ PROGRAM W3PRNC IRET=NF90_GET_ATT(NCID,VARIDTMP,"units",TIMEUNITS) CALL CHECK_ERR(IRET) CALL U2D(TIMEUNITS,REFDATE,IERR) - - IF(CALENDAR .EQ. "standard") THEN - CALL D2J(REFDATE,REFJULDAY,IERR) - ELSE IF(CALENDAR .EQ. "360_day") THEN - CALL D2J_360(REFDATE, REFJULDAY, IERR) - ELSE - PRINT*,'INTERNAL ERROR, CALENDAR=',CALENDAR - CALL EXTCDE( 99 ) - ENDIF + CALL D2J(REFDATE,REFJULDAY,IERR) ! gets variables ids, dimensions and fillvalue DO I=1,NFIELDS @@ -1828,7 +1811,6 @@ PROGRAM W3PRNC ! IF ( IAPROC .EQ. NAPOUT ) WRITE (NDSO,972) TIMEDELAY = 0 - print*,'[CB] NTI',NTI DO ITIME=1,NTI ! ! 8.a Read new time and fields @@ -1838,7 +1820,6 @@ PROGRAM W3PRNC CALL CHECK_ERR(IRET) IRET=NF90_GET_VAR(NCID,VARIDTMP,CURJULDAY,start=(/ITIME/)) call CHECK_ERR(IRET) - print*,'Got time',itime,curjulday IF (INDEX(TIMEUNITS, "seconds").NE.0) CURJULDAY=CURJULDAY/86400. IF (INDEX(TIMEUNITS, "minutes").NE.0) CURJULDAY=CURJULDAY/1440. IF (INDEX(TIMEUNITS, "hours").NE.0) CURJULDAY=CURJULDAY/24. @@ -1851,17 +1832,17 @@ PROGRAM W3PRNC IF (STPJULDAY.LT.CURJULDAY) EXIT ! convert julday to date and time - IF(CALTYPE .EQ. 'standard') THEN +! IF(CALTYPE .EQ. 'standard') THEN CALL J2D(CURJULDAY,CURDATE,IERR) - ELSE IF(CALTYPE .EQ. '360_day') THEN - CURDATE(1) = INT(CURJULDAY / 360) + 1800 ! (base year is 1800) - CURDATE(2) = MOD(INT(CURJULDAY / 30), 12) + 1 - CURDATE(3) = MOD(INT(CURJULDAY), 30) + 1 - SECS = (CURJULDAY - IDINT(CURJULDAY)) * 86400 - CURDATE(5) = SECS / 3600 - CURDATE(6) = MOD(SECS, 3600) / 60 - CURDATE(7) = MOD(SECS, 60) - ENDIF +! ELSE IF(CALTYPE .EQ. '360_day') THEN +! CURDATE(1) = INT(CURJULDAY / 360) + 1800 ! (base year is 1800) +! CURDATE(2) = MOD(INT(CURJULDAY / 30), 12) + 1 +! CURDATE(3) = MOD(INT(CURJULDAY), 30) + 1 +! SECS = (CURJULDAY - IDINT(CURJULDAY)) * 86400 +! CURDATE(5) = SECS / 3600 +! CURDATE(6) = MOD(SECS, 3600) / 60 +! CURDATE(7) = MOD(SECS, 60) +! ENDIF CALL D2T(CURDATE,TIME,IERR) CALL STME21 (TIME,IDTIME) @@ -2763,27 +2744,4 @@ SUBROUTINE CHECK_ERROR(IRET, ILINE) END SUBROUTINE CHECK_ERROR -!> @brief Convert a "360 day" calendar date to a pseudo-Julian date -!> @details Convert a date based on a "360 day" climate calendar (30 days -!> per month) to a pseudo-Julian date (number of days since -!> 1800-01-01 00:00:00) -!> @param DAT(8) Date/Time components, as returned from DATE_AND_TIME(3f). -!> @param JUL360 Pseudo-Julian day based on 360 day calendar -!> @author Chris Bunney @date 22 Feb 2022 -SUBROUTINE D2J_360(DAT, JUL360, IERR) - INTEGER,INTENT(IN) :: DAT(8) - DOUBLE PRECISION,INTENT(OUT) :: JUL360 - INTEGER, INTENT(OUT) :: IERR - - - JUL360 = (DAT(1) - 1800) * 360.0 + & ! Years (since 1800) - (DAT(2) - 1 ) * 30.0 + & ! Month - (DAT(3) - 1) + & ! Day - DAT(5)/24.0_8 + & ! Hour - DAT(6)/1440.0_8 + & ! Minute - DAT(7)/86400.0_8 ! Second - - IERR = 0 ! TODO! -END SUBROUTINE D2J_360 - !============================================================================== From bd90fffcecc93f642f3f0644dd29267df6da853a Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Fri, 23 Feb 2024 10:42:28 +0000 Subject: [PATCH 3/7] Removed commented out code --- model/src/ww3_prnc.F90 | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/model/src/ww3_prnc.F90 b/model/src/ww3_prnc.F90 index 6bcec65cde..24c78bf0a1 100644 --- a/model/src/ww3_prnc.F90 +++ b/model/src/ww3_prnc.F90 @@ -245,7 +245,7 @@ PROGRAM W3PRNC NDSLL, IDLALL, IDFMLL, NCID, IRET, & MXM, MYM, DATTYP, RECLDT, IDAT, & NDIMSGRID, NDIMSVAR, VARIDTMP, & - NUMDIMS, I, ITIME, SECS + NUMDIMS, I, ITIME INTEGER :: ILAND = -999 INTEGER :: GTYPEDUM = 0 @@ -1832,17 +1832,7 @@ PROGRAM W3PRNC IF (STPJULDAY.LT.CURJULDAY) EXIT ! convert julday to date and time -! IF(CALTYPE .EQ. 'standard') THEN - CALL J2D(CURJULDAY,CURDATE,IERR) -! ELSE IF(CALTYPE .EQ. '360_day') THEN -! CURDATE(1) = INT(CURJULDAY / 360) + 1800 ! (base year is 1800) -! CURDATE(2) = MOD(INT(CURJULDAY / 30), 12) + 1 -! CURDATE(3) = MOD(INT(CURJULDAY), 30) + 1 -! SECS = (CURJULDAY - IDINT(CURJULDAY)) * 86400 -! CURDATE(5) = SECS / 3600 -! CURDATE(6) = MOD(SECS, 3600) / 60 -! CURDATE(7) = MOD(SECS, 60) -! ENDIF + CALL J2D(CURJULDAY,CURDATE,IERR) CALL D2T(CURDATE,TIME,IERR) CALL STME21 (TIME,IDTIME) From 24f881a781b30dfde103cd7bbdabf300bbee2c8d Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Fri, 23 Feb 2024 11:56:18 +0000 Subject: [PATCH 4/7] Bugfix - no midday correction needed fro 360_day calendar --- model/src/w3timemd.F90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/model/src/w3timemd.F90 b/model/src/w3timemd.F90 index d2c52af077..a6c6ab5d82 100644 --- a/model/src/w3timemd.F90 +++ b/model/src/w3timemd.F90 @@ -1456,11 +1456,13 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) SECOND=SNGL((JULIAN-DBLE(IJUL))*SECDAY) ! Seconds from beginning of Jul. Day SECOND=SECOND+(tz*60) - IF(SECOND.GE.(SECDAY/2.0d0)) THEN ! In next calendar day - IJUL=IJUL+1 - SECOND=SECOND-(SECDAY/2.0d0) ! Adjust from noon to midnight - ELSE ! In same calendar day - SECOND=SECOND+(SECDAY/2.0d0) ! Adjust from noon to midnight + IF(CALTYPE .EQ. "standard") THEN + IF(SECOND.GE.(SECDAY/2.0d0)) THEN ! In next calendar day + IJUL=IJUL+1 + SECOND=SECOND-(SECDAY/2.0d0) ! Adjust from noon to midnight + ELSE ! In same calendar day + SECOND=SECOND+(SECDAY/2.0d0) ! Adjust from noon to midnight + END IF END IF IF(SECOND.GE.SECDAY) THEN ! Final check to prevent time 24:00:00 From 4747a2ca06cd279cfdbe9460e5898c86ac0e5769 Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Fri, 23 Feb 2024 17:02:21 +0000 Subject: [PATCH 5/7] forgot to set default for missing calendar attribute --- model/src/ww3_prnc.F90 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/model/src/ww3_prnc.F90 b/model/src/ww3_prnc.F90 index 24c78bf0a1..c22f65cbb5 100644 --- a/model/src/ww3_prnc.F90 +++ b/model/src/ww3_prnc.F90 @@ -800,13 +800,16 @@ PROGRAM W3PRNC CALL CHECK_ERR(IRET) IRET=NF90_GET_ATT(NCID,VARIDTMP,"calendar",CALENDAR) IF ( IRET/=NF90_NOERR ) THEN + ! No calendar attribute - default to "standard" WRITE(NDSE,1028) + CALENDAR = "standard" ELSE IF ((INDEX(CALENDAR, "standard") .GT. 0) .OR. & (INDEX(CALENDAR, "gregorian") .GT. 0)) THEN CALENDAR = "standard" ELSE IF (INDEX(CALENDAR, "360_day") .GT. 0) THEN CALENDAR = "360_day" ELSE + ! Calendar attribute set, but not a recognised calendar. WRITE(NDSE,1029) CALENDAR CALENDAR = "standard" ! Default to standard calendar. Better to maybe fail? END IF From 91efa3b61a73e461d213f38c22b506e91c7c7a02 Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Fri, 23 Feb 2024 17:06:43 +0000 Subject: [PATCH 6/7] Fixed typos found in review --- model/src/w3timemd.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/src/w3timemd.F90 b/model/src/w3timemd.F90 index a6c6ab5d82..0041866dbf 100644 --- a/model/src/w3timemd.F90 +++ b/model/src/w3timemd.F90 @@ -1330,7 +1330,7 @@ SUBROUTINE D2J(DAT,JULIAN,IERR) RETURN ENDIF - ! Standard/Gregorian calenday - return standrd Julian day calculation: + ! Standard/Gregorian calendar - return standard Julian day calculation: IF(YEAR==0 .or. YEAR .lt. -4713) THEN IERR=-1 RETURN @@ -1476,7 +1476,7 @@ SUBROUTINE J2D(JULIAN,DAT,IERR) MINUTE=MINUTE-HOUR*60 ! Integral minutes from beginning of hour IF(CALTYPE .EQ. '360_day') THEN - ! Calcalate date parts for 360 day climate calendar + ! Calculate date parts for 360 day climate calendar YEAR = INT(JULIAN / 360) + 1800 ! (base year is 1800) MONTH = MOD(INT(JULIAN / 30), 12) + 1 DAY = MOD(INT(JULIAN), 30) + 1 From 6630084de2a5cfc20c75b9cbe46b02d7b4ea9f84 Mon Sep 17 00:00:00 2001 From: "ukmo-chris.bunney" Date: Tue, 27 Feb 2024 09:33:02 +0000 Subject: [PATCH 7/7] Made unknown calendar a fatal error --- model/src/ww3_prnc.F90 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/model/src/ww3_prnc.F90 b/model/src/ww3_prnc.F90 index c22f65cbb5..e107a1f431 100644 --- a/model/src/ww3_prnc.F90 +++ b/model/src/ww3_prnc.F90 @@ -811,7 +811,7 @@ PROGRAM W3PRNC ELSE ! Calendar attribute set, but not a recognised calendar. WRITE(NDSE,1029) CALENDAR - CALENDAR = "standard" ! Default to standard calendar. Better to maybe fail? + CALL EXTCDE( 25 ) END IF ! Check input calendar compatible with expected calendar @@ -2434,10 +2434,12 @@ PROGRAM W3PRNC ' calendar ATTRIBUTE NOT DEFINED'/ & ' DEFAULTING TO "standard" CALENDAR'/ & ' INPUT FILE MUST RESPECT STANDARD/GREGORIAN CALENDAR') -1029 FORMAT (/' *** WAVEWATCH III WARNING IN W3PRNC : '/ & +1029 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & ' UNKNOWN CALENDAR TYPE: ', A / & - ' DEFAULTING TO "standard" CALENDAR'/ & - ' INPUT FILE MUST RESPECT STANDARD/GREGORIAN CALENDAR') + ' "calendar" ATTRIBUTE MUST BE ONE OF: '/ & + ' - standard'/ & + ' - gregorian'/ & + ' - 360_day'/ ) 1030 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ & ' ILLEGAL FIELD ID -->',A,'<--'/) 1031 FORMAT (/' *** WAVEWATCH III ERROR IN W3PRNC : '/ &