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.
trcrst.F90 in NEMO/branches/2018/dev_r9838_ENHANCE04_MLF/src/TOP – NEMO

source: NEMO/branches/2018/dev_r9838_ENHANCE04_MLF/src/TOP/trcrst.F90 @ 9923

Last change on this file since 9923 was 9923, checked in by gm, 6 years ago

#1911 (ENHANCE-04): step I.2: dev_r9838_ENHANCE04_MLF

  • Property svn:keywords set to Id
File size: 15.8 KB
Line 
1MODULE trcrst
2   !!======================================================================
3   !!                         ***  MODULE trcrst  ***
4   !! TOP :   Manage the passive tracer restart
5   !!======================================================================
6   !! History :   -   !  1991-03  ()  original code
7   !!            1.0  !  2005-03 (O. Aumont, A. El Moussaoui) F90
8   !!             -   !  2005-10 (C. Ethe) print control
9   !!            2.0  !  2005-10 (C. Ethe, G. Madec) revised architecture
10   !!----------------------------------------------------------------------
11#if defined key_top
12   !!----------------------------------------------------------------------
13   !!   'key_top'                                                TOP models
14   !!----------------------------------------------------------------------
15   
16   !!----------------------------------------------------------------------
17   !!   trc_rst       : Restart for passive tracer
18   !!   trc_rst_opn   : open  restart file
19   !!   trc_rst_read  : read  restart file
20   !!   trc_rst_wri   : write restart file
21   !!----------------------------------------------------------------------
22   USE oce_trc        !
23   USE trc            !
24   USE daymod         !
25   USE iom            !
26   
27   IMPLICIT NONE
28   PRIVATE
29
30   PUBLIC   trc_rst_opn    ! called by trcstp
31   PUBLIC   trc_rst_read   ! called by trcini
32   PUBLIC   trc_rst_wri    ! called by trcstp
33   PUBLIC   trc_rst_cal    ! called by trcstp & trcini (and OFF/nemogcm)
34
35   !!----------------------------------------------------------------------
36   !! NEMO/TOP 4.0 , NEMO Consortium (2018)
37   !! $Id$
38   !! Software governed by the CeCILL licence (./LICENSE)
39   !!----------------------------------------------------------------------
40CONTAINS
41   
42   SUBROUTINE trc_rst_opn( kt )
43      !!----------------------------------------------------------------------
44      !!                    ***  trc_rst_opn  ***
45      !!
46      !! ** purpose  :   output of sea-trc variable in a netcdf file
47      !!----------------------------------------------------------------------
48      INTEGER, INTENT(in) ::   kt       ! number of iteration
49      !
50      CHARACTER(LEN=20)   ::   clkt     ! ocean time-step define as a character
51      CHARACTER(LEN=50)   ::   clname   ! trc output restart file name
52      CHARACTER(LEN=256)  ::   clpath   ! full path to ocean output restart file
53      !!----------------------------------------------------------------------
54      !
55      IF( l_offline ) THEN
56         IF( kt == nittrc000 ) THEN
57            lrst_trc = .FALSE.
58            IF( ln_rst_list ) THEN
59               nrst_lst = 1
60               nitrst = nstocklist( nrst_lst )
61            ELSE
62               nitrst = nitend
63            ENDIF
64         ENDIF
65
66         IF( .NOT. ln_rst_list .AND. MOD( kt - 1, nstock ) == 0 ) THEN
67            ! we use kt - 1 and not kt - nittrc000 to keep the same periodicity from the beginning of the experiment
68            nitrst = kt + nstock - 1                  ! define the next value of nitrst for restart writing
69            IF( nitrst > nitend )   nitrst = nitend   ! make sure we write a restart at the end of the run
70         ENDIF
71      ELSE
72         IF( kt == nittrc000 ) lrst_trc = .FALSE.
73      ENDIF
74
75      ! to get better performances with NetCDF format:
76      ! we open and define the tracer restart file one tracer time step before writing the data (-> at nitrst - 2*nn_dttrc + 1)
77      ! except if we write tracer restart files every tracer time step or if a tracer restart file was writen at nitend - 2*nn_dttrc + 1
78      IF( kt == nitrst - 2*nn_dttrc .OR. nstock == nn_dttrc .OR. ( kt == nitend - nn_dttrc .AND. .NOT. lrst_trc ) ) THEN
79         ! beware of the format used to write kt (default is i8.8, that should be large enough)
80         IF( nitrst > 1.0e9 ) THEN   ;   WRITE(clkt,*       ) nitrst
81         ELSE                        ;   WRITE(clkt,'(i8.8)') nitrst
82         ENDIF
83         ! create the file
84         IF(lwp) WRITE(numout,*)
85         clname = TRIM(cexper)//"_"//TRIM(ADJUSTL(clkt))//"_"//TRIM(cn_trcrst_out)
86         clpath = TRIM(cn_trcrst_outdir)
87         IF( clpath(LEN_TRIM(clpath):) /= '/' ) clpath = TRIM(clpath) // '/'
88         IF(lwp) WRITE(numout,*) &
89             '             open trc restart.output NetCDF file: ',TRIM(clpath)//clname
90         CALL iom_open( TRIM(clpath)//TRIM(clname), numrtw, ldwrt = .TRUE., kiolib = jprstlib )
91         lrst_trc = .TRUE.
92      ENDIF
93      !
94   END SUBROUTINE trc_rst_opn
95
96
97   SUBROUTINE trc_rst_read
98      !!----------------------------------------------------------------------
99      !!                    ***  trc_rst_opn  ***
100      !!
101      !! ** purpose  :   read passive tracer fields in restart files
102      !!----------------------------------------------------------------------
103      INTEGER  ::  jn     
104
105      !!----------------------------------------------------------------------
106      !
107      IF(lwp) WRITE(numout,*)
108      IF(lwp) WRITE(numout,*) 'trc_rst_read : read data in the TOP restart file'
109      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
110
111      ! READ prognostic variables and computes diagnostic variable
112      DO jn = 1, jptra
113         CALL iom_get( numrtr, jpdom_autoglo, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
114      END DO
115
116      DO jn = 1, jptra
117         CALL iom_get( numrtr, jpdom_autoglo, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
118      END DO
119      !
120   END SUBROUTINE trc_rst_read
121
122   SUBROUTINE trc_rst_wri( kt )
123      !!----------------------------------------------------------------------
124      !!                    ***  trc_rst_wri  ***
125      !!
126      !! ** purpose  :   write passive tracer fields in restart files
127      !!----------------------------------------------------------------------
128      INTEGER, INTENT( in ) ::   kt    ! ocean time-step index
129      !!
130      INTEGER  :: jn
131      REAL(wp) :: zarak0
132      !!----------------------------------------------------------------------
133      !
134      CALL iom_rstput( kt, nitrst, numrtw, 'rdttrc1', rn_Dt_trc )   ! passive tracer time step
135      ! prognostic variables
136      ! --------------------
137      DO jn = 1, jptra
138         CALL iom_rstput( kt, nitrst, numrtw, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
139      END DO
140
141      DO jn = 1, jptra
142         CALL iom_rstput( kt, nitrst, numrtw, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
143      END DO
144      !
145      IF( kt == nitrst ) THEN
146          CALL trc_rst_stat            ! statistics
147          CALL iom_close( numrtw )     ! close the restart file (only at last time step)
148#if ! defined key_trdmxl_trc
149          lrst_trc = .FALSE.
150#endif
151          IF( l_offline .AND. ln_rst_list ) THEN
152             nrst_lst = nrst_lst + 1
153             nitrst = nstocklist( nrst_lst )
154          ENDIF
155      ENDIF
156      !
157   END SUBROUTINE trc_rst_wri 
158
159
160   SUBROUTINE trc_rst_cal( kt, cdrw )
161      !!---------------------------------------------------------------------
162      !!                   ***  ROUTINE trc_rst_cal  ***
163      !!
164      !!  ** Purpose : Read or write calendar in restart file:
165      !!
166      !!  WRITE(READ) mode:
167      !!       kt        : number of time step since the begining of the experiment at the
168      !!                   end of the current(previous) run
169      !!       adatrj(0) : number of elapsed days since the begining of the experiment at the
170      !!                   end of the current(previous) run (REAL -> keep fractions of day)
171      !!       ndastp    : date at the end of the current(previous) run (coded as yyyymmdd integer)
172      !!
173      !!   According to namelist parameter nrstdt,
174      !!       nn_rsttr = 0  no control on the date (nittrc000 is  arbitrary).
175      !!       nn_rsttr = 1  we verify that nittrc000 is equal to the last
176      !!                   time step of previous run + 1.
177      !!       In both those options, the  exact duration of the experiment
178      !!       since the beginning (cumulated duration of all previous restart runs)
179      !!       is not stored in the restart and is assumed to be (nittrc000-1)*rn_Dt.
180      !!       This is valid is the time step has remained constant.
181      !!
182      !!       nn_rsttr = 2  the duration of the experiment in days (adatrj)
183      !!                    has been stored in the restart file.
184      !!----------------------------------------------------------------------
185      INTEGER         , INTENT(in) ::   kt         ! ocean time-step
186      CHARACTER(len=*), INTENT(in) ::   cdrw       ! "READ"/"WRITE" flag
187      !
188      INTEGER  ::  jlibalt = jprstlib
189      LOGICAL  ::  llok
190      REAL(wp) ::  zkt, zndastp, zdayfrac, ksecs, ktime
191      INTEGER  ::   ihour, iminute
192
193      ! Time domain : restart
194      ! ---------------------
195
196      IF( TRIM(cdrw) == 'READ' ) THEN
197
198         IF(lwp) WRITE(numout,*)
199         IF(lwp) WRITE(numout,*) 'trc_rst_cal : read the TOP restart file for calendar'
200         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
201
202         IF( ln_rsttr ) THEN
203            CALL iom_open( TRIM(cn_trcrst_indir)//'/'//cn_trcrst_in, numrtr, kiolib = jlibalt )
204            CALL iom_get ( numrtr, 'kt', zkt )   ! last time-step of previous run
205
206            IF(lwp) THEN
207               WRITE(numout,*) ' *** Info read in restart : '
208               WRITE(numout,*) '   previous time-step                               : ', NINT( zkt )
209               WRITE(numout,*) ' *** restart option'
210               SELECT CASE ( nn_rsttr )
211               CASE ( 0 )   ;   WRITE(numout,*) ' nn_rsttr = 0 : no control of nittrc000'
212               CASE ( 1 )   ;   WRITE(numout,*) ' nn_rsttr = 1 : no control the date at nittrc000 (use ndate0 read in the namelist)'
213               CASE ( 2 )   ;   WRITE(numout,*) ' nn_rsttr = 2 : calendar parameters read in restart'
214               END SELECT
215               WRITE(numout,*)
216            ENDIF
217            ! Control of date
218            IF( nittrc000  - NINT( zkt ) /= nn_dttrc .AND.  nn_rsttr /= 0 )                                  &
219               &   CALL ctl_stop( ' ===>>>> : problem with nittrc000 for the restart',                 &
220               &                  ' verify the restart file or rerun with nn_rsttr = 0 (namelist)' )
221         ENDIF
222         !
223         IF( l_offline ) THEN   
224            !                                          ! set the date in offline mode
225            IF( ln_rsttr .AND. nn_rsttr == 2 ) THEN
226               CALL iom_get( numrtr, 'ndastp', zndastp )
227               ndastp = NINT( zndastp )
228               CALL iom_get( numrtr, 'adatrj', adatrj  )
229               CALL iom_get( numrtr, 'ntime' , ktime   )
230               nn_time0=INT(ktime)
231               ! calculate start time in hours and minutes
232               zdayfrac=adatrj-INT(adatrj)
233               ksecs = NINT(zdayfrac*86400)            ! Nearest second to catch rounding errors in adatrj             
234               ihour = INT(ksecs/3600)
235               iminute = ksecs/60-ihour*60
236               
237               ! Add to nn_time0
238               nhour   =   nn_time0 / 100
239               nminute = ( nn_time0 - nhour * 100 )
240               nminute=nminute+iminute
241               
242               IF( nminute >= 60 ) THEN
243                  nminute=nminute-60
244                  nhour=nhour+1
245               ENDIF
246               nhour=nhour+ihour
247               IF( nhour >= 24 ) THEN
248                  nhour=nhour-24
249                  adatrj=adatrj+1
250               ENDIF           
251               nn_time0 = nhour * 100 + nminute
252               adatrj = INT(adatrj)                    ! adatrj set to integer as nn_time0 updated           
253             ELSE
254               ! parameters corresponding to nit000 - 1 (as we start the step
255               ! loop with a call to day)
256               ndastp = ndate0        ! ndate0 read in the namelist in dom_nam
257               nhour   =   nn_time0 / 100
258               nminute = ( nn_time0 - nhour * 100 )
259               IF( nhour*3600+nminute*60-ndt05 .lt. 0 )  ndastp=ndastp-1      ! Start hour is specified in the namelist (default 0)
260               adatrj = ( REAL( nit000-1, wp ) * rn_Dt ) / rday
261               ! note this is wrong if time step has changed during run
262            ENDIF
263            IF( ABS(adatrj  - REAL(NINT(adatrj),wp)) < 0.1 / rday )   adatrj = REAL(NINT(adatrj),wp)   ! avoid truncation error
264            !
265            IF(lwp) THEN
266              WRITE(numout,*) ' *** Info used values : '
267              WRITE(numout,*) '   date ndastp                                      : ', ndastp
268              WRITE(numout,*) '   number of elapsed days since the begining of run : ', adatrj
269              WRITE(numout,*) '   nn_time0                                         : ', nn_time0
270              WRITE(numout,*)
271            ENDIF
272            !
273            IF( ln_rsttr )  THEN   ;    l_1st_euler = .FALSE.     ! OFF restart: no Euler 1st time-step
274            ELSE                   ;    l_1st_euler = .TRUE.      ! OFF cold start: Euler 1st time-step is used
275            ENDIF
276            !
277            CALL day_init          ! compute calendar
278            !
279         ENDIF
280         !
281      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN
282         !
283         IF(  kt == nitrst ) THEN
284            IF(lwp) WRITE(numout,*)
285            IF(lwp) WRITE(numout,*) 'trc_wri : write the TOP restart file (NetCDF) at it= ', kt, ' date= ', ndastp
286            IF(lwp) WRITE(numout,*) '~~~~~~~'
287         ENDIF
288         CALL iom_rstput( kt, nitrst, numrtw, 'kt'     , REAL( kt    , wp) )   ! time-step
289         CALL iom_rstput( kt, nitrst, numrtw, 'ndastp' , REAL( ndastp, wp) )   ! date
290         CALL iom_rstput( kt, nitrst, numrtw, 'adatrj' , adatrj            )   ! number of elapsed days since
291         !                                                                     ! the begining of the run [s]
292         CALL iom_rstput( kt, nitrst, numrtw, 'ntime'  , REAL( nn_time0, wp)) ! time
293      ENDIF
294
295   END SUBROUTINE trc_rst_cal
296
297
298   SUBROUTINE trc_rst_stat
299      !!----------------------------------------------------------------------
300      !!                    ***  trc_rst_stat  ***
301      !!
302      !! ** purpose  :   Compute tracers statistics
303      !!----------------------------------------------------------------------
304      INTEGER  :: jk, jn
305      REAL(wp) :: ztraf, zmin, zmax, zmean, zdrift
306      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zvol
307      !!----------------------------------------------------------------------
308
309      IF( lwp ) THEN
310         WRITE(numout,*) 
311         WRITE(numout,*) '           ----TRACER STAT----             '
312         WRITE(numout,*) 
313      ENDIF
314      !
315      DO jk = 1, jpk
316         zvol(:,:,jk) = e1e2t(:,:) * e3t_a(:,:,jk) * tmask(:,:,jk)
317      END DO
318      !
319      DO jn = 1, jptra
320         ztraf = glob_sum( trn(:,:,:,jn) * zvol(:,:,:) )
321         zmin  = MINVAL( trn(:,:,:,jn), mask= ((tmask*SPREAD(tmask_i,DIM=3,NCOPIES=jpk).NE.0.)) )
322         zmax  = MAXVAL( trn(:,:,:,jn), mask= ((tmask*SPREAD(tmask_i,DIM=3,NCOPIES=jpk).NE.0.)) )
323         IF( lk_mpp ) THEN
324            CALL mpp_min( zmin )      ! min over the global domain
325            CALL mpp_max( zmax )      ! max over the global domain
326         END IF
327         zmean  = ztraf / areatot
328         zdrift = ( ( ztraf - trai(jn) ) / ( trai(jn) + 1.e-12 )  ) * 100._wp
329         IF(lwp) WRITE(numout,9000) jn, TRIM( ctrcnm(jn) ), zmean, zmin, zmax, zdrift
330      END DO
331      IF(lwp) WRITE(numout,*) 
3329000  FORMAT(' tracer nb :',i2,'    name :',a10,'    mean :',e18.10,'    min :',e18.10, &
333      &      '    max :',e18.10,'    drift :',e18.10, ' %')
334      !
335   END SUBROUTINE trc_rst_stat
336
337#else
338   !!----------------------------------------------------------------------
339   !!  Dummy module :                                     No passive tracer
340   !!----------------------------------------------------------------------
341CONTAINS
342   SUBROUTINE trc_rst_read                      ! Empty routines
343   END SUBROUTINE trc_rst_read
344   SUBROUTINE trc_rst_wri( kt )
345      INTEGER, INTENT ( in ) :: kt
346      WRITE(*,*) 'trc_rst_wri: You should not have seen this print! error?', kt
347   END SUBROUTINE trc_rst_wri   
348#endif
349
350   !!======================================================================
351END MODULE trcrst
Note: See TracBrowser for help on using the repository browser.