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 @ 1341

Last change on this file since 1341 was 1291, checked in by cetlod, 15 years ago

update modules, see ticket:320

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.8 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
33   IMPLICIT NONE
34   PRIVATE
35
36   PUBLIC day        ! called by step.F90
37   PUBLIC day_init   ! called by istate.F90
38
39   INTEGER , PUBLIC ::   nyear       !: current year
40   INTEGER , PUBLIC ::   nmonth      !: current month
41   INTEGER , PUBLIC ::   nday        !: current day of the month
42   INTEGER , PUBLIC ::   ndastp      !: time step date in yyyymmdd format
43   INTEGER , PUBLIC ::   nday_year   !: current day counted from jan 1st of the current year
44   REAL(wp), PUBLIC ::   rsec_year   !: current time step counted in second since 00h jan 1st of the current year
45   REAL(wp), PUBLIC ::   rsec_month  !: current time step counted in second since 00h 1st day of the current month
46   REAL(wp), PUBLIC ::   rsec_day    !: current time step counted in second since 00h of the current day
47
48   REAL(wp), PUBLIC ::   adatrj      !: number of elapsed days since the begining of the run
49   !                                 !: it is the accumulated duration of previous runs
50   !                                 !: that may have been run with different time steps.
51   INTEGER , PUBLIC, DIMENSION(0:1)  ::   nyear_len    !: length in days of the previous/current year
52   INTEGER , PUBLIC, DIMENSION(0:13) ::   nmonth_len   !: length in days of the months of the current year
53   REAL(wp), PUBLIC, DIMENSION(0:13) ::   rmonth_half  !: second since the beginning of the year and the halft of the months
54   REAL(wp), PUBLIC, DIMENSION(0:13) ::   rmonth_end   !: second since the beginning of the year and the end of the months
55   REAL(wp), PUBLIC                  ::   sec1jan000   !: second since Jan. 1st 00h of nit000 year and Jan. 1st 00h of the current year
56
57   ! this two variables are wrong DO NOT USE THEM !!!
58   INTEGER, PUBLIC, DIMENSION(12) ::   nbiss = (/ 31, 29, 31, 30, 31, 30,    &  !: number of days per month
59      &                                           31, 31, 30, 31, 30, 31 /)     !: (leap-year)
60   INTEGER, PUBLIC, DIMENSION(12) ::   nobis = (/ 31, 28, 31, 30, 31, 30,    &  !: number of days per month
61      &                                           31, 31, 30, 31, 30, 31 /)     !: (365 days a year)
62
63
64   !!----------------------------------------------------------------------
65   !!  OPA 9.0 , LOCEAN-IPSL (2006)
66   !! $Id$
67   !! Software governed by the CeCILL licence (modipsl/doc/NEMO_CeCILL.txt)
68   !!----------------------------------------------------------------------
69
70CONTAINS
71
72   SUBROUTINE day_init
73      !!----------------------------------------------------------------------
74      !!                   ***  ROUTINE day_init  ***
75      !!
76      !! ** Purpose :   Initialization of the calendar values to their values 1 time step before nit000
77      !!                because day will be called at the beginning of step
78      !!
79      !! ** Action  : - nyear        : current year
80      !!              - nmonth       : current month of the year nyear
81      !!              - nday         : current day of the month nmonth
82      !!              - nday_year    : current day of the year nyear
83      !!              - rsec_year    : current time step counted in second since 00h jan 1st of the current year
84      !!              - rsec_month   : current time step counted in second since 00h 1st day of the current month
85      !!              - rsec_day     : current time step counted in second since 00h of the current day
86      !!              - sec1jan000   : second since Jan. 1st 00h of nit000 year and Jan. 1st 00h of the current year
87      !!              - nmonth_len, nyear_len, rmonth_half, rmonth_end through day_mth
88      !!----------------------------------------------------------------------
89
90      ! all calendar staff is based on the fact that MOD( rday, rdttra(1) ) == 0
91      IF( MOD( rday, rdttra(1) ) /= 0 )   CALL ctl_stop( 'the time step must devide the number of second of in a day' )
92
93      ! set the calandar from ndastp (read in restart file and namelist)
94      nyear   =   ndastp / 10000
95      nmonth  = ( ndastp - (nyear * 10000) ) / 100
96      nday    =   ndastp - (nyear * 10000) - ( nmonth * 100 ) 
97
98      sec1jan000 = 0.e0
99      CALL day_mth
100     
101      IF ( nday == 0 ) THEN     !   for ex if ndastp = ndate0 - 1
102         nmonth = nmonth - 1 
103         nday = nmonth_len(nmonth)
104      ENDIF
105      IF ( nmonth == 0 ) THEN   ! go at the end of previous year
106         nmonth = 12
107         nyear = nyear - 1
108         sec1jan000 = sec1jan000 - rday * REAL( nyear_len(0), wp )
109         IF( nleapy == 1 )   CALL day_mth
110      ENDIF
111     
112      ! day since january 1st
113      nday_year = nday + SUM( nmonth_len(1:nmonth - 1) )
114     
115      ! number of seconds since the beginning of current year/month at the middle of the time-step
116      rsec_year  = REAL( nday_year, wp ) * rday - 0.5 * rdttra(1)   ! 1 time step before the middle of the first time step
117      rsec_month = REAL( nday     , wp ) * rday - 0.5 * rdttra(1)   ! because day will be called at the beginning of step
118      rsec_day   =                         rday - 0.5 * rdttra(1)
119
120      ! control print
121      IF(lwp) WRITE(numout,*)' ==============>> 1/2 time step before the start of the run DATE Y/M/D = ',   &
122           &                   nyear, '/', nmonth, '/', nday, '  rsec_day:', rsec_day
123     
124   END SUBROUTINE day_init
125
126
127   SUBROUTINE day_mth
128      !!----------------------------------------------------------------------
129      !!                   ***  ROUTINE day_init  ***
130      !!
131      !! ** Purpose :   calendar values related to the months
132      !!
133      !! ** Action  : - nmonth_len    : length in days of the months of the current year
134      !!              - nyear_len     : length in days of the previous/current year
135      !!              - rmonth_half   : second since the beginning of the year and the halft of the months
136      !!              - rmonth_end    : second since the beginning of the year and the end of the months
137      !!----------------------------------------------------------------------
138      INTEGER  ::   jm               ! dummy loop indice
139      !!----------------------------------------------------------------------
140
141      ! length of the month of the current year (from nleapy, read in namelist)
142      IF ( nleapy < 2 ) THEN
143         nmonth_len(:) = (/ 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31 /)
144         nyear_len(:) = 365
145         IF ( nleapy == 1 ) THEN   ! we are using calandar with leap years
146            IF ( MOD(nyear-1, 4) == 0 .AND. ( MOD(nyear-1, 400) == 0 .OR. MOD(nyear-1, 100) /= 0 ) ) THEN
147               nyear_len(0) = 366
148            ENDIF
149            IF ( MOD(nyear, 4) == 0 .AND. ( MOD(nyear, 400) == 0 .OR. MOD(nyear, 100) /= 0 ) ) THEN
150               nmonth_len(2) = 29
151               nyear_len(1) = 366
152            ENDIF
153         ENDIF
154      ELSE
155         nmonth_len(:) = nleapy   ! all months with nleapy days per year
156         nyear_len(:) = 12 * nleapy
157      ENDIF
158
159      ! half month in second since the begining of the year:
160      ! time since Jan 1st   0     1     2    ...    11    12    13
161      !          ---------*--|--*--|--*--| ... |--*--|--*--|--*--|--------------------------------------
162      !                 <---> <---> <--->  ...  <---> <---> <--->       
163      ! month number      0     1     2    ...    11    12    13
164      !
165      ! rmonth_half(jm) = rday * REAL( 0.5 * nmonth_len(jm) + SUM(nmonth_len(1:jm-1)) )
166      rmonth_half(0) = - 0.5 * rday * REAL( nmonth_len(0), wp )
167      DO jm = 1, 13
168         rmonth_half(jm) = rmonth_half(jm-1) + 0.5 * rday * REAL( nmonth_len(jm-1) + nmonth_len(jm), wp )
169      END DO
170
171      rmonth_end(0) = 0.
172      DO jm = 1, 13
173         rmonth_end(jm) = rmonth_end(jm-1) + rday * REAL( nmonth_len(jm), wp )
174      END DO
175                 
176   END SUBROUTINE
177
178
179   SUBROUTINE day( kt )
180      !!----------------------------------------------------------------------
181      !!                      ***  ROUTINE day  ***
182      !!
183      !! ** Purpose :   Compute the date with a day iteration IF necessary.
184      !!
185      !! ** Method  : - ???
186      !!
187      !! ** Action  : - nyear     : current year
188      !!              - nmonth    : current month of the year nyear
189      !!              - nday      : current day of the month nmonth
190      !!              - nday_year : current day of the year nyear
191      !!              - ndastp    : = nyear*10000 + nmonth*100 + nday
192      !!              - adatrj    : date in days since the beginning of the run
193      !!              - rsec_year : current time of the year (in second since 00h, jan 1st)
194      !!----------------------------------------------------------------------     
195      INTEGER, INTENT(in) ::   kt        ! ocean time-step indices
196      !
197      CHARACTER (len=25) ::   charout
198      !!----------------------------------------------------------------------
199
200      !                                                 ! New time-step
201      rsec_year  = rsec_year  + rdttra(1) 
202      rsec_month = rsec_month + rdttra(1)                 
203      rsec_day   = rsec_day   + rdttra(1)                 
204      adatrj = adatrj + 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.