trcrst.F90 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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(LEN=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. !!!!Initialize trb and trn to avoid floating invalid with restarts rebuilt from land removal config - R. Bernardello Feb 2020
  103. trn(:,:,:,:) = 0._wp
  104. trb(:,:,:,:) = 0._wp
  105. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  106. ! READ prognostic variables and computes diagnostic variable
  107. IF( lk_pisces ) THEN
  108. DO jn = jp_pcs0, jp_pcs1
  109. CALL iom_get( numrtr, jpdom_autoglo, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
  110. END DO
  111. ENDIF
  112. IF( lk_cfc ) THEN
  113. IF( iom_varid( numrtr, 'TRN'//ctrcnm(jp_cfc0), ldstop = .FALSE. ) > 0 ) THEN
  114. DO jn = jp_cfc0, jp_cfc1
  115. CALL iom_get( numrtr, jpdom_autoglo, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
  116. ENDDO
  117. ELSE
  118. DO jn = jp_cfc0, jp_cfc1
  119. trn(:,:,:,jn) = 0._wp
  120. ENDDO
  121. ENDIF
  122. ENDIF
  123. IF( lk_age ) THEN
  124. IF( iom_varid( numrtr, 'TRNAge', ldstop = .FALSE. ) > 0 ) THEN
  125. jn = jp_age0
  126. CALL iom_get( numrtr, jpdom_autoglo, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
  127. ELSE
  128. jn = jp_age0
  129. trn(:,:,:,jn) = 0._wp
  130. ENDIF
  131. ENDIF
  132. IF( lk_pisces ) THEN
  133. DO jn = jp_pcs0, jp_pcs1
  134. CALL iom_get( numrtr, jpdom_autoglo, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
  135. END DO
  136. ENDIF
  137. IF( lk_cfc ) THEN
  138. IF( iom_varid( numrtr, 'TRB'//ctrcnm(jp_cfc0), ldstop = .FALSE. ) > 0 ) THEN
  139. DO jn = jp_cfc0, jp_cfc1
  140. CALL iom_get( numrtr, jpdom_autoglo, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
  141. ENDDO
  142. ELSE
  143. DO jn = jp_cfc0, jp_cfc1
  144. trb(:,:,:,jn) = 0._wp
  145. ENDDO
  146. ENDIF
  147. ENDIF
  148. IF( lk_age ) THEN
  149. IF( iom_varid( numrtr, 'TRBAge', ldstop = .FALSE. ) > 0 ) THEN
  150. jn = jp_age0
  151. CALL iom_get( numrtr, jpdom_autoglo, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
  152. ELSE
  153. jn = jp_age0
  154. trb(:,:,:,jn) = 0._wp
  155. ENDIF
  156. ENDIF
  157. !
  158. END SUBROUTINE trc_rst_read
  159. SUBROUTINE trc_rst_wri( kt )
  160. !!----------------------------------------------------------------------
  161. !! *** trc_rst_wri ***
  162. !!
  163. !! ** purpose : write passive tracer fields in restart files
  164. !!----------------------------------------------------------------------
  165. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  166. !!
  167. INTEGER :: jn
  168. REAL(wp) :: zarak0
  169. !!----------------------------------------------------------------------
  170. !
  171. CALL iom_rstput( kt, nitrst, numrtw, 'rdttrc1', rdttrc(1) ) ! surface passive tracer time step
  172. ! prognostic variables
  173. ! --------------------
  174. DO jn = 1, jptra
  175. CALL iom_rstput( kt, nitrst, numrtw, 'TRN'//ctrcnm(jn), trn(:,:,:,jn) )
  176. END DO
  177. DO jn = 1, jptra
  178. CALL iom_rstput( kt, nitrst, numrtw, 'TRB'//ctrcnm(jn), trb(:,:,:,jn) )
  179. END DO
  180. !
  181. IF( kt == nitrst ) THEN
  182. CALL trc_rst_stat ! statistics
  183. CALL iom_close( numrtw ) ! close the restart file (only at last time step)
  184. #if ! defined key_trdmxl_trc
  185. lrst_trc = .FALSE.
  186. #endif
  187. IF( lk_offline .AND. ln_rst_list ) THEN
  188. nrst_lst = nrst_lst + 1
  189. nitrst = nstocklist( nrst_lst )
  190. ENDIF
  191. ENDIF
  192. !
  193. END SUBROUTINE trc_rst_wri
  194. SUBROUTINE trc_rst_cal( kt, cdrw )
  195. !!---------------------------------------------------------------------
  196. !! *** ROUTINE trc_rst_cal ***
  197. !!
  198. !! ** Purpose : Read or write calendar in restart file:
  199. !!
  200. !! WRITE(READ) mode:
  201. !! kt : number of time step since the begining of the experiment at the
  202. !! end of the current(previous) run
  203. !! adatrj(0) : number of elapsed days since the begining of the experiment at the
  204. !! end of the current(previous) run (REAL -> keep fractions of day)
  205. !! ndastp : date at the end of the current(previous) run (coded as yyyymmdd integer)
  206. !!
  207. !! According to namelist parameter nrstdt,
  208. !! nn_rsttr = 0 no control on the date (nittrc000 is arbitrary).
  209. !! nn_rsttr = 1 we verify that nittrc000 is equal to the last
  210. !! time step of previous run + 1.
  211. !! In both those options, the exact duration of the experiment
  212. !! since the beginning (cumulated duration of all previous restart runs)
  213. !! is not stored in the restart and is assumed to be (nittrc000-1)*rdt.
  214. !! This is valid is the time step has remained constant.
  215. !!
  216. !! nn_rsttr = 2 the duration of the experiment in days (adatrj)
  217. !! has been stored in the restart file.
  218. !!----------------------------------------------------------------------
  219. INTEGER , INTENT(in) :: kt ! ocean time-step
  220. CHARACTER(len=*), INTENT(in) :: cdrw ! "READ"/"WRITE" flag
  221. !
  222. INTEGER :: jlibalt = jprstlib
  223. LOGICAL :: llok
  224. REAL(wp) :: zkt, zrdttrc1
  225. REAL(wp) :: zndastp
  226. ! Time domain : restart
  227. ! ---------------------
  228. IF( TRIM(cdrw) == 'READ' ) THEN
  229. IF(lwp) WRITE(numout,*)
  230. IF(lwp) WRITE(numout,*) 'trc_rst_cal : read the TOP restart file for calendar'
  231. IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~'
  232. IF ( jprstlib == jprstdimg ) THEN
  233. ! eventually read netcdf file (monobloc) for restarting on different number of processors
  234. ! if {cn_trcrst_in}.nc exists, then set jlibalt to jpnf90
  235. INQUIRE( FILE = TRIM(cn_trcrst_indir)//'/'//TRIM(cn_trcrst_in)//'.nc', EXIST = llok )
  236. IF ( llok ) THEN ; jlibalt = jpnf90 ; ELSE ; jlibalt = jprstlib ; ENDIF
  237. ENDIF
  238. IF( ln_rsttr ) THEN
  239. CALL iom_open( TRIM(cn_trcrst_indir)//'/'//cn_trcrst_in, numrtr, kiolib = jlibalt )
  240. CALL iom_get ( numrtr, 'kt', zkt ) ! last time-step of previous run
  241. IF(lwp) THEN
  242. WRITE(numout,*) ' *** Info read in restart : '
  243. WRITE(numout,*) ' previous time-step : ', NINT( zkt )
  244. WRITE(numout,*) ' *** restart option'
  245. SELECT CASE ( nn_rsttr )
  246. CASE ( 0 ) ; WRITE(numout,*) ' nn_rsttr = 0 : no control of nittrc000'
  247. CASE ( 1 ) ; WRITE(numout,*) ' nn_rsttr = 1 : no control the date at nittrc000 (use ndate0 read in the namelist)'
  248. CASE ( 2 ) ; WRITE(numout,*) ' nn_rsttr = 2 : calendar parameters read in restart'
  249. END SELECT
  250. WRITE(numout,*)
  251. ENDIF
  252. ! Control of date
  253. IF( nittrc000 - NINT( zkt ) /= nn_dttrc .AND. nn_rsttr /= 0 ) &
  254. & CALL ctl_stop( ' ===>>>> : problem with nittrc000 for the restart', &
  255. & ' verify the restart file or rerun with nn_rsttr = 0 (namelist)' )
  256. ENDIF
  257. !
  258. IF( lk_offline ) THEN
  259. ! ! set the date in offline mode
  260. IF( ln_rsttr .AND. nn_rsttr == 2 ) THEN
  261. CALL iom_get( numrtr, 'ndastp', zndastp )
  262. ndastp = NINT( zndastp )
  263. CALL iom_get( numrtr, 'adatrj', adatrj )
  264. ELSE
  265. ndastp = ndate0 - 1 ! ndate0 read in the namelist in dom_nam
  266. adatrj = ( REAL( nittrc000-1, wp ) * rdttra(1) ) / rday
  267. ! note this is wrong if time step has changed during run
  268. ENDIF
  269. !
  270. IF(lwp) THEN
  271. WRITE(numout,*) ' *** Info used values : '
  272. WRITE(numout,*) ' date ndastp : ', ndastp
  273. WRITE(numout,*) ' number of elapsed days since the begining of run : ', adatrj
  274. WRITE(numout,*)
  275. ENDIF
  276. !
  277. IF( ln_rsttr ) THEN ; neuler = 1
  278. ELSE ; neuler = 0
  279. ENDIF
  280. !
  281. CALL day_init ! compute calendar
  282. !
  283. ENDIF
  284. !
  285. ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN
  286. !
  287. IF( kt == nitrst ) THEN
  288. IF(lwp) WRITE(numout,*)
  289. IF(lwp) WRITE(numout,*) 'trc_wri : write the TOP restart file (NetCDF) at it= ', kt, ' date= ', ndastp
  290. IF(lwp) WRITE(numout,*) '~~~~~~~'
  291. ENDIF
  292. CALL iom_rstput( kt, nitrst, numrtw, 'kt' , REAL( kt , wp) ) ! time-step
  293. CALL iom_rstput( kt, nitrst, numrtw, 'ndastp' , REAL( ndastp, wp) ) ! date
  294. CALL iom_rstput( kt, nitrst, numrtw, 'adatrj' , adatrj ) ! number of elapsed days since
  295. ! ! the begining of the run [s]
  296. ENDIF
  297. END SUBROUTINE trc_rst_cal
  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. IF( lwp ) THEN
  309. WRITE(numout,*)
  310. WRITE(numout,*) ' ----TRACER STAT---- '
  311. WRITE(numout,*)
  312. ENDIF
  313. !
  314. DO jk = 1, jpk
  315. zvol(:,:,jk) = e1e2t(:,:) * fse3t_a(:,:,jk) * tmask(:,:,jk)
  316. END DO
  317. !
  318. DO jn = 1, jptra
  319. ztraf = glob_sum( trn(:,:,:,jn) * zvol(:,:,:) )
  320. zmin = MINVAL( trn(:,:,:,jn), mask= ((tmask*SPREAD(tmask_i,DIM=3,NCOPIES=jpk).NE.0.)) )
  321. zmax = MAXVAL( trn(:,:,:,jn), mask= ((tmask*SPREAD(tmask_i,DIM=3,NCOPIES=jpk).NE.0.)) )
  322. IF( lk_mpp ) THEN
  323. CALL mpp_min( zmin ) ! min over the global domain
  324. CALL mpp_max( zmax ) ! max over the global domain
  325. END IF
  326. zmean = ztraf / areatot
  327. zdrift = ( ( ztraf - trai(jn) ) / ( trai(jn) + 1.e-12 ) ) * 100._wp
  328. IF(lwp) WRITE(numout,9000) jn, TRIM( ctrcnm(jn) ), zmean, zmin, zmax, zdrift
  329. END DO
  330. IF(lwp) WRITE(numout,*)
  331. 9000 FORMAT(' tracer nb :',i2,' name :',a10,' mean :',e18.10,' min :',e18.10, &
  332. & ' max :',e18.10,' drift :',e18.10, ' %')
  333. !
  334. END SUBROUTINE trc_rst_stat
  335. #else
  336. !!----------------------------------------------------------------------
  337. !! Dummy module : No passive tracer
  338. !!----------------------------------------------------------------------
  339. CONTAINS
  340. SUBROUTINE trc_rst_read ! Empty routines
  341. END SUBROUTINE trc_rst_read
  342. SUBROUTINE trc_rst_wri( kt )
  343. INTEGER, INTENT ( in ) :: kt
  344. WRITE(*,*) 'trc_rst_wri: You should not have seen this print! error?', kt
  345. END SUBROUTINE trc_rst_wri
  346. #endif
  347. !!----------------------------------------------------------------------
  348. !! NEMO/TOP 3.3 , NEMO Consortium (2010)
  349. !! $Id: trcrst.F90 7052 2016-10-20 10:23:27Z acc $
  350. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  351. !!======================================================================
  352. END MODULE trcrst