trcrst.F90 16 KB

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