source: NEMO/trunk/src/TOP/trcrst.F90 @ 10425

Last change on this file since 10425 was 10425, checked in by smasson, 2 years ago

trunk: merge back dev_r10164_HPC09_ESIWACE_PREP_MERGE@10424 into the trunk

  • Property svn:keywords set to Id
File size: 16.0 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   !!   trc_rst        : Restart for passive tracer
17   !!   trc_rst_opn    : open  restart file
18   !!   trc_rst_read   : read  restart file
19   !!   trc_rst_wri    : write restart file
20   !!----------------------------------------------------------------------
21   USE oce_trc
22   USE trc
23   USE iom
24   USE daymod
25   USE lib_mpp
26   
27   IMPLICIT NONE
28   PRIVATE
29
30   PUBLIC   trc_rst_opn       ! called by ???
31   PUBLIC   trc_rst_read      ! called by ???
32   PUBLIC   trc_rst_wri       ! called by ???
33   PUBLIC   trc_rst_cal
34
35   !!----------------------------------------------------------------------
36   !! NEMO/TOP 4.0 , NEMO Consortium (2018)
37   !! $Id$
38   !! Software governed by the CeCILL license (see ./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. )
91         lrst_trc = .TRUE.
92      ENDIF
93      !
94   END SUBROUTINE trc_rst_opn
95
96   SUBROUTINE trc_rst_read
97      !!----------------------------------------------------------------------
98      !!                    ***  trc_rst_opn  ***
99      !!
100      !! ** purpose  :   read passive tracer fields in restart files
101      !!----------------------------------------------------------------------
102      INTEGER  ::  jn     
103
104      !!----------------------------------------------------------------------
105      !
106      IF(lwp) WRITE(numout,*)
107      IF(lwp) WRITE(numout,*) 'trc_rst_read : read data in the TOP restart file'
108      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
109
110      ! READ prognostic variables and computes diagnostic variable
111      DO jn = 1, jptra
112         CALL iom_get( numrtr, jpdom_autoglo, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
113      END DO
114
115      DO jn = 1, jptra
116         CALL iom_get( numrtr, jpdom_autoglo, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
117      END DO
118      !
119      CALL iom_delay_rst( 'READ', 'TOP', numrtr )   ! read only TOP delayed global communication variables
120     
121   END SUBROUTINE trc_rst_read
122
123   SUBROUTINE trc_rst_wri( kt )
124      !!----------------------------------------------------------------------
125      !!                    ***  trc_rst_wri  ***
126      !!
127      !! ** purpose  :   write passive tracer fields in restart files
128      !!----------------------------------------------------------------------
129      INTEGER, INTENT( in ) ::   kt    ! ocean time-step index
130      !!
131      INTEGER  :: jn
132      !!----------------------------------------------------------------------
133      !
134      CALL iom_rstput( kt, nitrst, numrtw, 'rdttrc1', rdttrc )   ! 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      CALL iom_delay_rst( 'WRITE', 'TOP', numrtw )   ! save only TOP delayed global communication variables
146   
147      IF( kt == nitrst ) THEN
148          CALL trc_rst_stat            ! statistics
149          CALL iom_close( numrtw )     ! close the restart file (only at last time step)
150#if ! defined key_trdmxl_trc
151          lrst_trc = .FALSE.
152#endif
153          IF( l_offline .AND. ln_rst_list ) THEN
154             nrst_lst = nrst_lst + 1
155             nitrst = nstocklist( nrst_lst )
156          ENDIF
157      ENDIF
158      !
159   END SUBROUTINE trc_rst_wri 
160
161
162   SUBROUTINE trc_rst_cal( kt, cdrw )
163      !!---------------------------------------------------------------------
164      !!                   ***  ROUTINE trc_rst_cal  ***
165      !!
166      !!  ** Purpose : Read or write calendar in restart file:
167      !!
168      !!  WRITE(READ) mode:
169      !!       kt        : number of time step since the begining of the experiment at the
170      !!                   end of the current(previous) run
171      !!       adatrj(0) : number of elapsed days since the begining of the experiment at the
172      !!                   end of the current(previous) run (REAL -> keep fractions of day)
173      !!       ndastp    : date at the end of the current(previous) run (coded as yyyymmdd integer)
174      !!
175      !!   According to namelist parameter nrstdt,
176      !!       nn_rsttr = 0  no control on the date (nittrc000 is  arbitrary).
177      !!       nn_rsttr = 1  we verify that nittrc000 is equal to the last
178      !!                   time step of previous run + 1.
179      !!       In both those options, the  exact duration of the experiment
180      !!       since the beginning (cumulated duration of all previous restart runs)
181      !!       is not stored in the restart and is assumed to be (nittrc000-1)*rdt.
182      !!       This is valid is the time step has remained constant.
183      !!
184      !!       nn_rsttr = 2  the duration of the experiment in days (adatrj)
185      !!                    has been stored in the restart file.
186      !!----------------------------------------------------------------------
187      INTEGER         , INTENT(in) ::   kt         ! ocean time-step
188      CHARACTER(len=*), INTENT(in) ::   cdrw       ! "READ"/"WRITE" flag
189      !
190      LOGICAL  ::  llok
191      REAL(wp) ::  zrdttrc1, zkt, zndastp, zdayfrac, ksecs, ktime
192      INTEGER  ::   ihour, iminute
193
194      ! Time domain : restart
195      ! ---------------------
196
197      IF( TRIM(cdrw) == 'READ' ) THEN
198
199         IF(lwp) WRITE(numout,*)
200         IF(lwp) WRITE(numout,*) 'trc_rst_cal : read the TOP restart file for calendar'
201         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
202
203         IF( ln_rsttr ) THEN
204            CALL iom_open( TRIM(cn_trcrst_indir)//'/'//cn_trcrst_in, numrtr )
205            CALL iom_get ( numrtr, 'kt', zkt )   ! last time-step of previous run
206
207            IF(lwp) THEN
208               WRITE(numout,*) ' *** Info read in restart : '
209               WRITE(numout,*) '   previous time-step                               : ', NINT( zkt )
210               WRITE(numout,*) ' *** restart option'
211               SELECT CASE ( nn_rsttr )
212               CASE ( 0 )   ;   WRITE(numout,*) ' nn_rsttr = 0 : no control of nittrc000'
213               CASE ( 1 )   ;   WRITE(numout,*) ' nn_rsttr = 1 : no control the date at nittrc000 (use ndate0 read in the namelist)'
214               CASE ( 2 )   ;   WRITE(numout,*) ' nn_rsttr = 2 : calendar parameters read in restart'
215               END SELECT
216               WRITE(numout,*)
217            ENDIF
218            ! Control of date
219            IF( nittrc000  - NINT( zkt ) /= nn_dttrc .AND.  nn_rsttr /= 0 )                                  &
220               &   CALL ctl_stop( ' ===>>>> : problem with nittrc000 for the restart',                 &
221               &                  ' verify the restart file or rerun with nn_rsttr = 0 (namelist)' )
222         ENDIF
223         !
224         IF( l_offline ) THEN   
225            !                                          ! set the date in offline mode
226            IF( ln_rsttr .AND. nn_rsttr == 2 ) THEN
227               CALL iom_get( numrtr, 'ndastp', zndastp )
228               ndastp = NINT( zndastp )
229               CALL iom_get( numrtr, 'adatrj', adatrj  )
230               CALL iom_get( numrtr, 'ntime' , ktime   )
231               nn_time0=INT(ktime)
232               ! calculate start time in hours and minutes
233               zdayfrac=adatrj-INT(adatrj)
234               ksecs = NINT(zdayfrac*86400)            ! Nearest second to catch rounding errors in adatrj             
235               ihour = INT(ksecs/3600)
236               iminute = ksecs/60-ihour*60
237               
238               ! Add to nn_time0
239               nhour   =   nn_time0 / 100
240               nminute = ( nn_time0 - nhour * 100 )
241               nminute=nminute+iminute
242               
243               IF( nminute >= 60 ) THEN
244                  nminute=nminute-60
245                  nhour=nhour+1
246               ENDIF
247               nhour=nhour+ihour
248               IF( nhour >= 24 ) THEN
249                  nhour=nhour-24
250                  adatrj=adatrj+1
251               ENDIF           
252               nn_time0 = nhour * 100 + nminute
253               adatrj = INT(adatrj)                    ! adatrj set to integer as nn_time0 updated           
254             ELSE
255               ! parameters corresponding to nit000 - 1 (as we start the step
256               ! loop with a call to day)
257               ndastp = ndate0 - 1       ! ndate0 read in the namelist in dom_nam
258               nhour   =   nn_time0 / 100
259               nminute = ( nn_time0 - nhour * 100 )
260               IF( nhour*3600+nminute*60-ndt05 .lt. 0 )  ndastp=ndastp-1      ! Start hour is specified in the namelist (default 0)
261               adatrj = ( REAL( nit000-1, wp ) * rdt ) / rday
262               ! note this is wrong if time step has changed during run
263            ENDIF
264            IF( ABS(adatrj  - REAL(NINT(adatrj),wp)) < 0.1 / rday )   adatrj = REAL(NINT(adatrj),wp)   ! avoid truncation error
265            !
266            IF(lwp) THEN
267              WRITE(numout,*) ' *** Info used values : '
268              WRITE(numout,*) '   date ndastp                                      : ', ndastp
269              WRITE(numout,*) '   number of elapsed days since the begining of run : ', adatrj
270              WRITE(numout,*) '   nn_time0                                         : ', nn_time0
271              WRITE(numout,*)
272            ENDIF
273            !
274            IF( ln_rsttr )  THEN   ;    neuler = 1
275            ELSE                   ;    neuler = 0
276            ENDIF
277            !
278            CALL day_init          ! compute calendar
279            !
280         ENDIF
281         !
282      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN
283         !
284         IF(  kt == nitrst ) THEN
285            IF(lwp) WRITE(numout,*)
286            IF(lwp) WRITE(numout,*) 'trc_wri : write the TOP restart file (NetCDF) at it= ', kt, ' date= ', ndastp
287            IF(lwp) WRITE(numout,*) '~~~~~~~'
288         ENDIF
289         CALL iom_rstput( kt, nitrst, numrtw, 'kt'     , REAL( kt    , wp) )   ! time-step
290         CALL iom_rstput( kt, nitrst, numrtw, 'ndastp' , REAL( ndastp, wp) )   ! date
291         CALL iom_rstput( kt, nitrst, numrtw, 'adatrj' , adatrj            )   ! number of elapsed days since
292         !                                                                     ! the begining of the run [s]
293         CALL iom_rstput( kt, nitrst, numrtw, 'ntime'  , REAL( nn_time0, wp)) ! time
294      ENDIF
295
296   END SUBROUTINE trc_rst_cal
297
298
299   SUBROUTINE trc_rst_stat
300      !!----------------------------------------------------------------------
301      !!                    ***  trc_rst_stat  ***
302      !!
303      !! ** purpose  :   Compute tracers statistics
304      !!----------------------------------------------------------------------
305      INTEGER  :: jk, jn
306      REAL(wp) :: ztraf, zmin, zmax, zmean, zdrift
307      REAL(wp), DIMENSION(jpi,jpj,jpk) :: zvol
308      !!----------------------------------------------------------------------
309
310      IF( lwp ) THEN
311         WRITE(numout,*) 
312         WRITE(numout,*) '           ----TRACER STAT----             '
313         WRITE(numout,*) 
314      ENDIF
315      !
316      DO jk = 1, jpk
317         zvol(:,:,jk) = e1e2t(:,:) * e3t_a(:,:,jk) * tmask(:,:,jk)
318      END DO
319      !
320      DO jn = 1, jptra
321         ztraf = glob_sum( 'trcrst', trn(:,:,:,jn) * zvol(:,:,:) )
322         zmin  = MINVAL( trn(:,:,:,jn), mask= ((tmask*SPREAD(tmask_i,DIM=3,NCOPIES=jpk).NE.0.)) )
323         zmax  = MAXVAL( trn(:,:,:,jn), mask= ((tmask*SPREAD(tmask_i,DIM=3,NCOPIES=jpk).NE.0.)) )
324         IF( lk_mpp ) THEN
325            CALL mpp_min( 'trcrst', zmin )      ! min over the global domain
326            CALL mpp_max( 'trcrst', zmax )      ! max over the global domain
327         END IF
328         zmean  = ztraf / areatot
329         zdrift = ( ( ztraf - trai(jn) ) / ( trai(jn) + 1.e-12 )  ) * 100._wp
330         IF(lwp) WRITE(numout,9000) jn, TRIM( ctrcnm(jn) ), zmean, zmin, zmax, zdrift
331      END DO
332      IF(lwp) WRITE(numout,*) 
3339000  FORMAT(' tracer nb :',i2,'    name :',a10,'    mean :',e18.10,'    min :',e18.10, &
334      &      '    max :',e18.10,'    drift :',e18.10, ' %')
335      !
336   END SUBROUTINE trc_rst_stat
337
338#else
339   !!----------------------------------------------------------------------
340   !!  Dummy module :                                     No passive tracer
341   !!----------------------------------------------------------------------
342CONTAINS
343   SUBROUTINE trc_rst_read                      ! Empty routines
344   END SUBROUTINE trc_rst_read
345   SUBROUTINE trc_rst_wri( kt )
346      INTEGER, INTENT ( in ) :: kt
347      WRITE(*,*) 'trc_rst_wri: You should not have seen this print! error?', kt
348   END SUBROUTINE trc_rst_wri   
349#endif
350
351   !!----------------------------------------------------------------------
352   !! NEMO/TOP 4.0 , NEMO Consortium (2018)
353   !! $Id$
354   !! Software governed by the CeCILL license (see ./LICENSE)
355   !!======================================================================
356END MODULE trcrst
Note: See TracBrowser for help on using the repository browser.