New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
daymod.F90 in trunk/NEMO/OFF_SRC – NEMO

source: trunk/NEMO/OFF_SRC/daymod.F90 @ 1713

Last change on this file since 1713 was 1713, checked in by smasson, 15 years ago

suppress nbiss and nobis, see ticket:589

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.7 KB
Line 
1MODULE daymod
2   !!======================================================================
3   !!                       ***  MODULE  daymod  ***
4   !! Ocean        :  calendar
5   !!=====================================================================
6   !! History :        !  94-09  (M. Pontaud M. Imbard)  Original code
7   !!                  !  97-03  (O. Marti)
8   !!                  !  97-05  (G. Madec)
9   !!                  !  97-08  (M. Imbard)
10   !!             9.0  !  03-09  (G. Madec)  F90 + nyear, nmonth, nday
11   !!                  !  04-01  (A.M. Treguier) new calculation based on adatrj
12   !!                  !  06-08  (G. Madec)  surface module major update
13   !!----------------------------------------------------------------------     
14
15   !!----------------------------------------------------------------------
16   !!   day        : calendar
17   !! 
18   !!           -------------------------------
19   !!           ----------- WARNING -----------
20   !!
21   !!   we suppose that the time step is deviding the number of second of in a day
22   !!             ---> MOD( rday, rdttra(1) ) == 0
23   !!
24   !!           ----------- WARNING -----------
25   !!           -------------------------------
26   !! 
27   !!----------------------------------------------------------------------
28   USE dom_oce         ! ocean space and time domain
29   USE phycst          ! physical constants
30   USE in_out_manager  ! I/O manager
31   USE prtctl          ! Print control
32   USE ioipsl, ONLY :   ymds2ju        ! for calendar
33
34   IMPLICIT NONE
35   PRIVATE
36
37   PUBLIC day        ! called by step.F90
38   PUBLIC day_init   ! called by istate.F90
39
40   INTEGER , PUBLIC ::   nyear       !: current year
41   INTEGER , PUBLIC ::   nmonth      !: current month
42   INTEGER , PUBLIC ::   nday        !: current day of the month
43   INTEGER , PUBLIC ::   ndastp      !: time step date in yyyymmdd format
44   INTEGER , PUBLIC ::   nday_year   !: current day counted from jan 1st of the current year
45   REAL(wp), PUBLIC ::   rsec_year   !: current time step counted in second since 00h jan 1st of the current year
46   REAL(wp), PUBLIC ::   rsec_month  !: current time step counted in second since 00h 1st day of the current month
47   REAL(wp), PUBLIC ::   rsec_day    !: current time step counted in second since 00h of the current day
48
49   REAL(wp), PUBLIC ::   fjulday     !: julian day
50   REAL(wp), PUBLIC ::   adatrj      !: number of elapsed days since the begining of the run
51   !                                 !: it is the accumulated duration of previous runs
52   !                                 !: that may have been run with different time steps.
53   INTEGER , PUBLIC, DIMENSION(0:1)  ::   nyear_len    !: length in days of the previous/current year
54   INTEGER , PUBLIC, DIMENSION(0:13) ::   nmonth_len   !: length in days of the months of the current year
55   REAL(wp), PUBLIC, DIMENSION(0:13) ::   rmonth_half  !: second since the beginning of the year and the halft of the months
56   REAL(wp), PUBLIC, DIMENSION(0:13) ::   rmonth_end   !: second since the beginning of the year and the end of the months
57   REAL(wp), PUBLIC                  ::   sec1jan000   !: second since Jan. 1st 00h of nit000 year and Jan. 1st 00h of the current year
58
59   !!----------------------------------------------------------------------
60   !!  OPA 9.0 , LOCEAN-IPSL (2006)
61   !! $Id$
62   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
63   !!----------------------------------------------------------------------
64
65CONTAINS
66
67   SUBROUTINE day_init
68      !!----------------------------------------------------------------------
69      !!                   ***  ROUTINE day_init  ***
70      !!
71      !! ** Purpose :   Initialization of the calendar values to their values 1 time step before nit000
72      !!                because day will be called at the beginning of step
73      !!
74      !! ** Action  : - nyear        : current year
75      !!              - nmonth       : current month of the year nyear
76      !!              - nday         : current day of the month nmonth
77      !!              - nday_year    : current day of the year nyear
78      !!              - rsec_year    : current time step counted in second since 00h jan 1st of the current year
79      !!              - rsec_month   : current time step counted in second since 00h 1st day of the current month
80      !!              - rsec_day     : current time step counted in second since 00h of the current day
81      !!              - sec1jan000   : second since Jan. 1st 00h of nit000 year and Jan. 1st 00h of the current year
82      !!              - nmonth_len, nyear_len, rmonth_half, rmonth_end through day_mth
83      !!----------------------------------------------------------------------
84
85      ! all calendar staff is based on the fact that MOD( rday, rdttra(1) ) == 0
86      IF( MOD( rday, rdttra(1) ) /= 0 )   CALL ctl_stop( 'the time step must devide the number of second of in a day' )
87
88      ! set the calandar from ndastp (read in restart file and namelist)
89      nyear   =   ndastp / 10000
90      nmonth  = ( ndastp - (nyear * 10000) ) / 100
91      nday    =   ndastp - (nyear * 10000) - ( nmonth * 100 ) 
92
93      CALL ymds2ju( nyear, nmonth, nday, 0.0, fjulday )  ! we assume that we start run at 00:00
94      fjulday = fjulday + 1.                             ! move back to the day at nit000 (and not at nit000 - 1)
95
96
97      sec1jan000 = 0.e0
98      CALL day_mth
99     
100      IF ( nday == 0 ) THEN     !   for ex if ndastp = ndate0 - 1
101         nmonth = nmonth - 1 
102         nday = nmonth_len(nmonth)
103      ENDIF
104      IF ( nmonth == 0 ) THEN   ! go at the end of previous year
105         nmonth = 12
106         nyear = nyear - 1
107         sec1jan000 = sec1jan000 - rday * REAL( nyear_len(0), wp )
108         IF( nleapy == 1 )   CALL day_mth
109      ENDIF
110     
111      ! day since january 1st
112      nday_year = nday + SUM( nmonth_len(1:nmonth - 1) )
113     
114      ! number of seconds since the beginning of current year/month at the middle of the time-step
115      rsec_year  = REAL( nday_year, wp ) * rday - 0.5 * rdttra(1)   ! 1 time step before the middle of the first time step
116      rsec_month = REAL( nday     , wp ) * rday - 0.5 * rdttra(1)   ! because day will be called at the beginning of step
117      rsec_day   =                         rday - 0.5 * rdttra(1)
118
119      ! control print
120      IF(lwp) WRITE(numout,*)' ==============>> 1/2 time step before the start of the run DATE Y/M/D = ',   &
121           &                   nyear, '/', nmonth, '/', nday, '  rsec_day:', rsec_day
122     
123   END SUBROUTINE day_init
124
125
126   SUBROUTINE day_mth
127      !!----------------------------------------------------------------------
128      !!                   ***  ROUTINE day_init  ***
129      !!
130      !! ** Purpose :   calendar values related to the months
131      !!
132      !! ** Action  : - nmonth_len    : length in days of the months of the current year
133      !!              - nyear_len     : length in days of the previous/current year
134      !!              - rmonth_half   : second since the beginning of the year and the halft of the months
135      !!              - rmonth_end    : second since the beginning of the year and the end of the months
136      !!----------------------------------------------------------------------
137      INTEGER  ::   jm               ! dummy loop indice
138      !!----------------------------------------------------------------------
139
140      ! length of the month of the current year (from nleapy, read in namelist)
141      IF ( nleapy < 2 ) THEN
142         nmonth_len(:) = (/ 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31 /)
143         nyear_len(:) = 365
144         IF ( nleapy == 1 ) THEN   ! we are using calandar with leap years
145            IF ( MOD(nyear-1, 4) == 0 .AND. ( MOD(nyear-1, 400) == 0 .OR. MOD(nyear-1, 100) /= 0 ) ) THEN
146               nyear_len(0) = 366
147            ENDIF
148            IF ( MOD(nyear, 4) == 0 .AND. ( MOD(nyear, 400) == 0 .OR. MOD(nyear, 100) /= 0 ) ) THEN
149               nmonth_len(2) = 29
150               nyear_len(1) = 366
151            ENDIF
152         ENDIF
153      ELSE
154         nmonth_len(:) = nleapy   ! all months with nleapy days per year
155         nyear_len(:) = 12 * nleapy
156      ENDIF
157
158      ! half month in second since the begining of the year:
159      ! time since Jan 1st   0     1     2    ...    11    12    13
160      !          ---------*--|--*--|--*--| ... |--*--|--*--|--*--|--------------------------------------
161      !                 <---> <---> <--->  ...  <---> <---> <--->       
162      ! month number      0     1     2    ...    11    12    13
163      !
164      ! rmonth_half(jm) = rday * REAL( 0.5 * nmonth_len(jm) + SUM(nmonth_len(1:jm-1)) )
165      rmonth_half(0) = - 0.5 * rday * REAL( nmonth_len(0), wp )
166      DO jm = 1, 13
167         rmonth_half(jm) = rmonth_half(jm-1) + 0.5 * rday * REAL( nmonth_len(jm-1) + nmonth_len(jm), wp )
168      END DO
169
170      rmonth_end(0) = 0.
171      DO jm = 1, 13
172         rmonth_end(jm) = rmonth_end(jm-1) + rday * REAL( nmonth_len(jm), wp )
173      END DO
174                 
175   END SUBROUTINE
176
177
178   SUBROUTINE day( kt )
179      !!----------------------------------------------------------------------
180      !!                      ***  ROUTINE day  ***
181      !!
182      !! ** Purpose :   Compute the date with a day iteration IF necessary.
183      !!
184      !! ** Method  : - ???
185      !!
186      !! ** Action  : - nyear     : current year
187      !!              - nmonth    : current month of the year nyear
188      !!              - nday      : current day of the month nmonth
189      !!              - nday_year : current day of the year nyear
190      !!              - ndastp    : = nyear*10000 + nmonth*100 + nday
191      !!              - adatrj    : date in days since the beginning of the run
192      !!              - rsec_year : current time of the year (in second since 00h, jan 1st)
193      !!----------------------------------------------------------------------     
194      INTEGER, INTENT(in) ::   kt        ! ocean time-step indices
195      !
196      CHARACTER (len=25) ::   charout
197      !!----------------------------------------------------------------------
198
199      !                                                 ! New time-step
200      rsec_year  = rsec_year  + rdttra(1) 
201      rsec_month = rsec_month + rdttra(1)                 
202      rsec_day   = rsec_day   + rdttra(1)                 
203      adatrj = adatrj + rdttra(1) / rday
204      fjulday = fjulday + rdttra(1) / rday
205   
206      IF( rsec_day > rday ) THEN                        ! NEW day
207         !
208         nday      = nday + 1
209         nday_year = nday_year + 1
210         rsec_day  = 0.5 * rdttra(1)                 
211         !
212         IF( nday == nmonth_len(nmonth) + 1 ) THEN      ! NEW month
213            nday   = 1
214            nmonth = nmonth + 1
215            rsec_month = 0.5 * rdttra(1)
216            IF( nmonth == 13 ) THEN                     ! NEW year
217               nyear     = nyear + 1
218               nmonth    = 1
219               nday_year = 1
220               rsec_year = 0.5 * rdttra(1)
221               sec1jan000 = sec1jan000 + rday * REAL( nyear_len(1), wp )
222               IF( nleapy == 1 )   CALL day_mth
223            ENDIF
224         ENDIF
225         !
226         ndastp = nyear * 10000 + nmonth * 100 + nday   ! NEW date
227         !
228         IF(lwp) WRITE(numout,'(a,i8,a,i4.4,a,i2.2,a,i2.2,a,i3.3)') '======>> time-step =', kt,   &
229              &   '      New day, DATE Y/M/D = ', nyear, '/', nmonth, '/', nday, '      nday_year = ', nday_year
230         IF(lwp) WRITE(numout,'(a,F9.0,a,F9.0,a,F9.0)') '         rsec_year = ', rsec_year,   &
231              &   '   rsec_month = ', rsec_month, '   rsec_day = ', rsec_day
232      ENDIF
233     
234      IF(ln_ctl) THEN
235         WRITE(charout,FMT="('kt =', I4,'  d/m/y =',I2,I2,I4)") kt, nday, nmonth, nyear
236         CALL prt_ctl_info(charout)
237      ENDIF
238
239      !
240   END SUBROUTINE day
241   !!======================================================================
242END MODULE daymod
Note: See TracBrowser for help on using the repository browser.