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

Last change on this file since 1745 was 1716, checked in by cetlod, 15 years ago

move daymod public variables in dom_oce for OFFLINE configuration, see ticket:590

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