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_r10164_HPC09_ESIWACE_PREP_MERGE/src/TOP – NEMO

source: NEMO/branches/2018/dev_r10164_HPC09_ESIWACE_PREP_MERGE/src/TOP/trcrst.F90 @ 10380

Last change on this file since 10380 was 10380, checked in by smasson, 5 years ago

dev_r10164_HPC09_ESIWACE_PREP_MERGE: iom cleaning: (1) get rid of jpnf90, jprstlib, jlibalt, iolib and (2) improve iom_getatt and iom_putatt, see #2133

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