p4zsms.F90 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. MODULE p4zsms
  2. !!======================================================================
  3. !! *** MODULE p4zsms ***
  4. !! TOP : PISCES Source Minus Sink manager
  5. !!======================================================================
  6. !! History : 1.0 ! 2004-03 (O. Aumont) Original code
  7. !! 2.0 ! 2007-12 (C. Ethe, G. Madec) F90
  8. !!----------------------------------------------------------------------
  9. #if defined key_pisces
  10. !!----------------------------------------------------------------------
  11. !! 'key_pisces' PISCES bio-model
  12. !!----------------------------------------------------------------------
  13. !! p4zsms : Time loop of passive tracers sms
  14. !!----------------------------------------------------------------------
  15. USE oce_trc ! shared variables between ocean and passive tracers
  16. USE trc ! passive tracers common variables
  17. USE trcdta
  18. USE sms_pisces ! PISCES Source Minus Sink variables
  19. USE p4zbio ! Biological model
  20. USE p4zche ! Chemical model
  21. USE p4zlys ! Calcite saturation
  22. USE p4zflx ! Gas exchange
  23. USE p4zsbc ! External source of nutrients
  24. USE p4zsed ! Sedimentation
  25. USE p4zint ! time interpolation
  26. USE p4zrem ! remineralisation
  27. USE iom ! I/O manager
  28. USE trd_oce ! Ocean trends variables
  29. USE trdtrc ! TOP trends variables
  30. USE sedmodel ! Sediment model
  31. USE prtctl_trc ! print control for debugging
  32. IMPLICIT NONE
  33. PRIVATE
  34. PUBLIC p4z_sms_init ! called in p4zsms.F90
  35. PUBLIC p4z_sms ! called in p4zsms.F90
  36. REAL(wp) :: alkbudget, no3budget, silbudget, ferbudget, po4budget
  37. REAL(wp) :: xfact, xfact1, xfact2, xfact3
  38. INTEGER :: numco2, numnut, numnit !: logical unit for co2 budget
  39. REAL(wp) :: alkmax = 3200.0e-6_wp ! max value of dic
  40. REAL(wp) :: dicmax = 2800e-6_wp ! mean value of alkalinity
  41. REAL(wp) :: po4max = 10.0e-6_wp ! mean value of phosphates
  42. REAL(wp) :: no3max = 50.0e-6_wp ! mean value of nitrate
  43. REAL(wp) :: silmax = 250.0e-6_wp ! mean value of silicate
  44. REAL(wp) :: fermax = 6.0e-8_wp
  45. REAL(wp) :: gocmax = 1.0e+3_wp ! max value of particules
  46. !!* Array used to indicate negative tracer values
  47. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: xnegtr !: ???
  48. !! * Substitutions
  49. # include "top_substitute.h90"
  50. !!----------------------------------------------------------------------
  51. !! NEMO/TOP 3.3 , NEMO Consortium (2010)
  52. !! $Id: p4zsms.F90 3320 2012-03-05 16:37:52Z cetlod $
  53. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  54. !!----------------------------------------------------------------------
  55. CONTAINS
  56. SUBROUTINE p4z_sms( kt )
  57. !!---------------------------------------------------------------------
  58. !! *** ROUTINE p4z_sms ***
  59. !!
  60. !! ** Purpose : Managment of the call to Biological sources and sinks
  61. !! routines of PISCES bio-model
  62. !!
  63. !! ** Method : - at each new day ...
  64. !! - several calls of bio and sed ???
  65. !! - ...
  66. !!---------------------------------------------------------------------
  67. !
  68. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  69. !!
  70. INTEGER :: ji, jj, jk, jnt, jn, jl
  71. REAL(wp) :: ztra
  72. #if defined key_kriest
  73. REAL(wp) :: zcoef1, zcoef2
  74. #endif
  75. CHARACTER (len=25) :: charout
  76. REAL(wp), POINTER, DIMENSION(:,:) :: zw2d
  77. REAL(wp), POINTER, DIMENSION(:,:,:,:) :: ztrdt ! 4D workspace
  78. !!---------------------------------------------------------------------
  79. !
  80. IF( nn_timing == 1 ) CALL timing_start('p4z_sms')
  81. !
  82. IF( kt == nittrc000 ) THEN
  83. !
  84. ALLOCATE( xnegtr(jpi,jpj,jpk) )
  85. !
  86. CALL p4z_che ! initialize the chemical constants
  87. !
  88. IF( .NOT. ln_rsttr ) THEN ; CALL p4z_che_ahini( hi ) ! set PH at kt=nit000
  89. ELSE ; CALL p4z_rst( nittrc000, 'READ' ) !* read or initialize all required fields
  90. ENDIF
  91. !
  92. ENDIF
  93. !
  94. IF( ln_pisdmp .AND. MOD( kt - nn_dttrc, nn_pisdmp ) == 0 ) CALL p4z_dmp( kt ) ! Relaxation of some tracers
  95. !
  96. ! ! set time step size (Euler/Leapfrog)
  97. IF( ( neuler == 0 .AND. kt == nittrc000 ) .OR. ln_top_euler ) THEN ; rfact = rdttrc(1) ! at nittrc000
  98. ELSEIF( kt <= nittrc000 + nn_dttrc ) THEN ; rfact = 2. * rdttrc(1) ! at nittrc000 or nittrc000+nn_dttrc (Leapfrog)
  99. ENDIF
  100. !
  101. ! trends computation initialisation
  102. IF( l_trdtrc ) THEN
  103. CALL wrk_alloc( jpi, jpj, jpk, jp_pisces, ztrdt ) !* store now fields before applying the Asselin filter
  104. ztrdt(:,:,:,:) = trn(:,:,:,:)
  105. ENDIF
  106. !
  107. IF( ( ln_top_euler .AND. kt == nittrc000 ) .OR. ( .NOT.ln_top_euler .AND. kt <= nittrc000 + nn_dttrc ) ) THEN
  108. rfactr = 1. / rfact
  109. rfact2 = rfact / FLOAT( nrdttrc )
  110. rfact2r = 1. / rfact2
  111. xstep = rfact2 / rday ! Time step duration for biology
  112. xfact = 1.e+3 * rfact2r
  113. IF(lwp) WRITE(numout,*)
  114. IF(lwp) WRITE(numout,*) ' Passive Tracer time step rfact = ', rfact, ' rdt = ', rdttra(1)
  115. IF(lwp) write(numout,*) ' PISCES Biology time step rfact2 = ', rfact2
  116. IF(lwp) WRITE(numout,*)
  117. ENDIF
  118. IF( ( neuler == 0 .AND. kt == nittrc000 ) .OR. ln_top_euler ) THEN
  119. DO jn = jp_pcs0, jp_pcs1 ! SMS on tracer without Asselin time-filter
  120. trb(:,:,:,jn) = trn(:,:,:,jn)
  121. END DO
  122. ENDIF
  123. !
  124. IF( ndayflxtr /= nday_year ) THEN ! New days
  125. !
  126. ndayflxtr = nday_year
  127. IF(lwp) write(numout,*)
  128. IF(lwp) write(numout,*) ' New chemical constants and various rates for biogeochemistry at new day : ', nday_year
  129. IF(lwp) write(numout,*) '~~~~~~'
  130. CALL p4z_che ! computation of chemical constants
  131. CALL p4z_int( kt ) ! computation of various rates for biogeochemistry
  132. !
  133. ENDIF
  134. IF( ll_sbc ) CALL p4z_sbc( kt ) ! external sources of nutrients
  135. DO jnt = 1, nrdttrc ! Potential time splitting if requested
  136. !
  137. CALL p4z_bio( kt, jnt ) ! Biology
  138. CALL p4z_lys( kt, jnt ) ! Compute CaCO3 saturation
  139. CALL p4z_sed( kt, jnt ) ! Surface and Bottom boundary conditions
  140. CALL p4z_flx( kt, jnt ) ! Compute surface fluxes
  141. !
  142. xnegtr(:,:,:) = 1.e0
  143. DO jn = jp_pcs0, jp_pcs1
  144. DO jk = 1, jpk
  145. DO jj = 1, jpj
  146. DO ji = 1, jpi
  147. IF( ( trb(ji,jj,jk,jn) + tra(ji,jj,jk,jn) ) < 0.e0 ) THEN
  148. ztra = ABS( trb(ji,jj,jk,jn) ) / ( ABS( tra(ji,jj,jk,jn) ) + rtrn )
  149. xnegtr(ji,jj,jk) = MIN( xnegtr(ji,jj,jk), ztra )
  150. ENDIF
  151. END DO
  152. END DO
  153. END DO
  154. END DO
  155. ! ! where at least 1 tracer concentration becomes negative
  156. ! !
  157. DO jn = jp_pcs0, jp_pcs1
  158. trb(:,:,:,jn) = trb(:,:,:,jn) + xnegtr(:,:,:) * tra(:,:,:,jn)
  159. END DO
  160. !
  161. ! Additional CMIP6 diagnostics : At this stage tra includes all terms
  162. IF( lk_iomput ) THEN
  163. CALL wrk_alloc( jpi, jpj, zw2d )
  164. !
  165. IF( iom_use( "INTdtAlk" ) ) THEN
  166. zw2d(:,:) = 0.
  167. DO jk = 1, jpkm1
  168. zw2d(:,:) = zw2d(:,:) &
  169. & + xnegtr(:,:,jk) * tra(:,:,jk,jptal) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  170. ENDDO
  171. CALL iom_put( "INTdtAlk", zw2d )
  172. ENDIF
  173. !
  174. IF( iom_use( "INTdtDIC" ) ) THEN
  175. zw2d(:,:) = 0.
  176. DO jk = 1, jpkm1
  177. zw2d(:,:) = zw2d(:,:) &
  178. & + xnegtr(:,:,jk) * tra(:,:,jk,jpdic) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  179. ENDDO
  180. CALL iom_put( "INTdtDIC", zw2d )
  181. ENDIF
  182. !
  183. IF( iom_use( "INTdtFer" ) ) THEN
  184. zw2d(:,:) = 0.
  185. DO jk = 1, jpkm1
  186. zw2d(:,:) = zw2d(:,:) &
  187. & + xnegtr(:,:,jk) * tra(:,:,jk,jpfer) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  188. ENDDO
  189. CALL iom_put( "INTdtFer", zw2d )
  190. ENDIF
  191. !
  192. IF( iom_use( "INTdtDIN" ) ) THEN
  193. zw2d(:,:) = 0.
  194. DO jk = 1, jpkm1
  195. zw2d(:,:) = zw2d(:,:) &
  196. & + xnegtr(:,:,jk) * ( tra(:,:,jk,jpno3) + tra(:,:,jk,jpnh4) ) &
  197. & * rno3 * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  198. ENDDO
  199. CALL iom_put( "INTdtDIN", zw2d )
  200. ENDIF
  201. !
  202. IF( iom_use( "INTdtDIP" ) ) THEN
  203. zw2d(:,:) = 0.
  204. DO jk = 1, jpkm1
  205. zw2d(:,:) = zw2d(:,:) &
  206. & + xnegtr(:,:,jk) * tra(:,:,jk,jppo4) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  207. ENDDO
  208. CALL iom_put( "INTdtDIP", zw2d )
  209. ENDIF
  210. !
  211. IF( iom_use( "INTdtSil" ) ) THEN
  212. zw2d(:,:) = 0.
  213. DO jk = 1, jpkm1
  214. zw2d(:,:) = zw2d(:,:) &
  215. & + xnegtr(:,:,jk) * tra(:,:,jk,jpsil) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  216. ENDDO
  217. CALL iom_put( "INTdtSil", zw2d )
  218. ENDIF
  219. CALL wrk_dealloc( jpi, jpj, zw2d )
  220. ENDIF
  221. !
  222. DO jn = jp_pcs0, jp_pcs1
  223. tra(:,:,:,jn) = 0._wp
  224. END DO
  225. !
  226. IF( ln_top_euler ) THEN
  227. DO jn = jp_pcs0, jp_pcs1
  228. trn(:,:,:,jn) = trb(:,:,:,jn)
  229. END DO
  230. ENDIF
  231. END DO
  232. ! threshold values to avoid huge concentration, especially on river mouths
  233. DO jk = 1,jpkm1
  234. trn(:,:,jk,jptal) = MIN( trn(:,:,jk,jptal), alkmax )
  235. trn(:,:,jk,jpdic) = MIN( trn(:,:,jk,jpdic), dicmax )
  236. trn(:,:,jk,jppo4) = MIN( trn(:,:,jk,jppo4), po4max / po4r )
  237. trn(:,:,jk,jpsil) = MIN( trn(:,:,jk,jpsil), silmax )
  238. trn(:,:,jk,jpfer) = MIN( trn(:,:,jk,jpfer), fermax )
  239. trn(:,:,jk,jpno3) = MIN( trn(:,:,jk,jpno3), no3max / rno3 )
  240. !
  241. trb(:,:,jk,jptal) = MIN( trb(:,:,jk,jptal), alkmax )
  242. trb(:,:,jk,jpdic) = MIN( trb(:,:,jk,jpdic), dicmax )
  243. trb(:,:,jk,jppo4) = MIN( trb(:,:,jk,jppo4), po4max / po4r )
  244. trb(:,:,jk,jpsil) = MIN( trb(:,:,jk,jpsil), silmax )
  245. trb(:,:,jk,jpfer) = MIN( trb(:,:,jk,jpfer), fermax )
  246. trb(:,:,jk,jpno3) = MIN( trb(:,:,jk,jpno3), no3max / rno3 )
  247. END DO
  248. #if defined key_kriest
  249. !
  250. zcoef1 = 1.e0 / xkr_massp
  251. zcoef2 = 1.e0 / xkr_massp / 1.1
  252. DO jk = 1,jpkm1
  253. trb(:,:,jk,jpnum) = MAX( trb(:,:,jk,jpnum), trb(:,:,jk,jppoc) * zcoef1 / xnumm(jk) )
  254. trb(:,:,jk,jpnum) = MIN( trb(:,:,jk,jpnum), trb(:,:,jk,jppoc) * zcoef2 )
  255. END DO
  256. !
  257. #endif
  258. !
  259. !
  260. IF( l_trdtrc ) THEN
  261. DO jn = jp_pcs0, jp_pcs1
  262. ztrdt(:,:,:,jn) = ( trb(:,:,:,jn) - ztrdt(:,:,:,jn) ) * rfact2r
  263. CALL trd_trc( ztrdt(:,:,:,jn), jn, jptra_sms, kt ) ! save trends
  264. END DO
  265. CALL wrk_dealloc( jpi, jpj, jpk, jp_pisces, ztrdt )
  266. END IF
  267. !
  268. IF( lk_sed ) THEN
  269. !
  270. CALL sed_model( kt ) ! Main program of Sediment model
  271. !
  272. DO jn = jp_pcs0, jp_pcs1
  273. CALL lbc_lnk( trb(:,:,:,jn), 'T', 1. )
  274. END DO
  275. !
  276. ENDIF
  277. !
  278. IF( lrst_trc ) CALL p4z_rst( kt, 'WRITE' ) !* Write PISCES informations in restart file
  279. !
  280. IF( lk_iomput .OR. ln_check_mass ) CALL p4z_chk_mass( kt ) ! Mass conservation checking
  281. IF ( lwm .AND. kt == nittrc000 ) CALL FLUSH ( numonp ) ! flush output namelist PISCES
  282. IF( nn_timing == 1 ) CALL timing_stop('p4z_sms')
  283. !
  284. !
  285. END SUBROUTINE p4z_sms
  286. SUBROUTINE p4z_sms_init
  287. !!----------------------------------------------------------------------
  288. !! *** p4z_sms_init ***
  289. !!
  290. !! ** Purpose : read PISCES namelist
  291. !!
  292. !! ** input : file 'namelist.trc.s' containing the following
  293. !! namelist: natext, natbio, natsms
  294. !! natkriest ("key_kriest")
  295. !!----------------------------------------------------------------------
  296. NAMELIST/nampisbio/ nrdttrc, wsbio, xkmort, ferat3, wsbio2, niter1max, niter2max
  297. #if defined key_kriest
  298. NAMELIST/nampiskrp/ xkr_eta, xkr_zeta, xkr_ncontent, xkr_mass_min, xkr_mass_max
  299. #endif
  300. NAMELIST/nampisdmp/ ln_pisdmp, nn_pisdmp
  301. NAMELIST/nampismass/ ln_check_mass
  302. INTEGER :: ios ! Local integer output status for namelist read
  303. !!----------------------------------------------------------------------
  304. REWIND( numnatp_ref ) ! Namelist nampisbio in reference namelist : Pisces variables
  305. READ ( numnatp_ref, nampisbio, IOSTAT = ios, ERR = 901)
  306. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisbio in reference namelist', lwp )
  307. REWIND( numnatp_cfg ) ! Namelist nampisbio in configuration namelist : Pisces variables
  308. READ ( numnatp_cfg, nampisbio, IOSTAT = ios, ERR = 902 )
  309. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisbio in configuration namelist', lwp )
  310. IF(lwm) WRITE ( numonp, nampisbio )
  311. IF(lwp) THEN ! control print
  312. WRITE(numout,*) ' Namelist : nampisbio'
  313. WRITE(numout,*) ' frequence pour la biologie nrdttrc =', nrdttrc
  314. WRITE(numout,*) ' POC sinking speed wsbio =', wsbio
  315. WRITE(numout,*) ' half saturation constant for mortality xkmort =', xkmort
  316. WRITE(numout,*) ' Fe/C in zooplankton ferat3 =', ferat3
  317. WRITE(numout,*) ' Big particles sinking speed wsbio2 =', wsbio2
  318. WRITE(numout,*) ' Maximum number of iterations for POC niter1max =', niter1max
  319. WRITE(numout,*) ' Maximum number of iterations for GOC niter2max =', niter2max
  320. ENDIF
  321. #if defined key_kriest
  322. ! ! nampiskrp : kriest parameters
  323. ! ! -----------------------------
  324. REWIND( numnatp_ref ) ! Namelist nampiskrp in reference namelist : Pisces Kriest
  325. READ ( numnatp_ref, nampiskrp, IOSTAT = ios, ERR = 903)
  326. 903 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampiskrp in reference namelist', lwp )
  327. REWIND( numnatp_cfg ) ! Namelist nampiskrp in configuration namelist : Pisces Kriest
  328. READ ( numnatp_cfg, nampiskrp, IOSTAT = ios, ERR = 904 )
  329. 904 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampiskrp in configuration namelist', lwp )
  330. IF(lwm) WRITE ( numonp, nampiskrp )
  331. IF(lwp) THEN
  332. WRITE(numout,*)
  333. WRITE(numout,*) ' Namelist : nampiskrp'
  334. WRITE(numout,*) ' Sinking exponent xkr_eta = ', xkr_eta
  335. WRITE(numout,*) ' N content exponent xkr_zeta = ', xkr_zeta
  336. WRITE(numout,*) ' N content factor xkr_ncontent = ', xkr_ncontent
  337. WRITE(numout,*) ' Minimum mass for Aggregates xkr_mass_min = ', xkr_mass_min
  338. WRITE(numout,*) ' Maximum mass for Aggregates xkr_mass_max = ', xkr_mass_max
  339. WRITE(numout,*)
  340. ENDIF
  341. ! Computation of some variables
  342. xkr_massp = xkr_ncontent * 7.625 * xkr_mass_min**xkr_zeta
  343. #endif
  344. REWIND( numnatp_ref ) ! Namelist nampisdmp in reference namelist : Pisces damping
  345. READ ( numnatp_ref, nampisdmp, IOSTAT = ios, ERR = 905)
  346. 905 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisdmp in reference namelist', lwp )
  347. REWIND( numnatp_cfg ) ! Namelist nampisdmp in configuration namelist : Pisces damping
  348. READ ( numnatp_cfg, nampisdmp, IOSTAT = ios, ERR = 906 )
  349. 906 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisdmp in configuration namelist', lwp )
  350. IF(lwm) WRITE ( numonp, nampisdmp )
  351. IF(lwp) THEN ! control print
  352. WRITE(numout,*)
  353. WRITE(numout,*) ' Namelist : nampisdmp'
  354. WRITE(numout,*) ' Relaxation of tracer to glodap mean value ln_pisdmp =', ln_pisdmp
  355. WRITE(numout,*) ' Frequency of Relaxation nn_pisdmp =', nn_pisdmp
  356. WRITE(numout,*) ' '
  357. ENDIF
  358. REWIND( numnatp_ref ) ! Namelist nampismass in reference namelist : Pisces mass conservation check
  359. READ ( numnatp_ref, nampismass, IOSTAT = ios, ERR = 907)
  360. 907 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampismass in reference namelist', lwp )
  361. REWIND( numnatp_cfg ) ! Namelist nampismass in configuration namelist : Pisces mass conservation check
  362. READ ( numnatp_cfg, nampismass, IOSTAT = ios, ERR = 908 )
  363. 908 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampismass in configuration namelist', lwp )
  364. IF(lwm) WRITE ( numonp, nampismass )
  365. IF(lwp) THEN ! control print
  366. WRITE(numout,*) ' '
  367. WRITE(numout,*) ' Namelist parameter for mass conservation checking'
  368. WRITE(numout,*) ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
  369. WRITE(numout,*) ' Flag to check mass conservation of NO3/Si/TALK ln_check_mass = ', ln_check_mass
  370. ENDIF
  371. END SUBROUTINE p4z_sms_init
  372. SUBROUTINE p4z_rst( kt, cdrw )
  373. !!---------------------------------------------------------------------
  374. !! *** ROUTINE p4z_rst ***
  375. !!
  376. !! ** Purpose : Read or write variables in restart file:
  377. !!
  378. !! WRITE(READ) mode:
  379. !! kt : number of time step since the begining of the experiment at the
  380. !! end of the current(previous) run
  381. !!---------------------------------------------------------------------
  382. INTEGER , INTENT(in) :: kt ! ocean time-step
  383. CHARACTER(len=*), INTENT(in) :: cdrw ! "READ"/"WRITE" flag
  384. INTEGER :: jk
  385. !!---------------------------------------------------------------------
  386. IF( TRIM(cdrw) == 'READ' ) THEN
  387. !
  388. IF(lwp) WRITE(numout,*)
  389. IF(lwp) WRITE(numout,*) ' p4z_rst : Read specific variables from pisces model '
  390. IF(lwp) WRITE(numout,*) ' ~~~~~~~~~~~~~~'
  391. !
  392. IF( iom_varid( numrtr, 'PH', ldstop = .FALSE. ) > 0 ) THEN
  393. CALL iom_get( numrtr, jpdom_autoglo, 'PH' , hi(:,:,:) )
  394. ELSE
  395. CALL p4z_che_ahini( hi )
  396. ENDIF
  397. CALL iom_get( numrtr, jpdom_autoglo, 'Silicalim', xksi(:,:) )
  398. IF( iom_varid( numrtr, 'Silicamax', ldstop = .FALSE. ) > 0 ) THEN
  399. CALL iom_get( numrtr, jpdom_autoglo, 'Silicamax' , xksimax(:,:) )
  400. ELSE
  401. xksimax(:,:) = xksi(:,:)
  402. ENDIF
  403. !
  404. IF( iom_varid( numrtr, 'tcflxcum', ldstop = .FALSE. ) > 0 ) THEN ! cumulative total flux of carbon
  405. CALL iom_get( numrtr, 'tcflxcum' , t_oce_co2_flx_cum )
  406. ELSE
  407. t_oce_co2_flx_cum = 0._wp
  408. ENDIF
  409. !
  410. ! threshold values to avoid huge concentration, especially on marginal seas
  411. DO jk = 1,jpkm1
  412. trn(:,:,jk,jpgoc) = MIN( trn(:,:,jk,jpgoc), gocmax )
  413. trn(:,:,jk,jppoc) = MIN( trn(:,:,jk,jppoc), gocmax )
  414. trn(:,:,jk,jpbfe) = MIN( trn(:,:,jk,jpbfe), gocmax )
  415. trn(:,:,jk,jpsfe) = MIN( trn(:,:,jk,jpsfe), gocmax )
  416. trn(:,:,jk,jpgsi) = MIN( trn(:,:,jk,jpgsi), gocmax )
  417. trn(:,:,jk,jpcal) = MIN( trn(:,:,jk,jpcal), gocmax )
  418. !
  419. trb(:,:,jk,jpgoc) = MIN( trb(:,:,jk,jpgoc), gocmax )
  420. trb(:,:,jk,jppoc) = MIN( trb(:,:,jk,jppoc), gocmax )
  421. trb(:,:,jk,jpbfe) = MIN( trb(:,:,jk,jpbfe), gocmax )
  422. trb(:,:,jk,jpsfe) = MIN( trb(:,:,jk,jpsfe), gocmax )
  423. trb(:,:,jk,jpgsi) = MIN( trb(:,:,jk,jpgsi), gocmax )
  424. trb(:,:,jk,jpcal) = MIN( trb(:,:,jk,jpcal), gocmax )
  425. END DO
  426. !
  427. ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN
  428. IF( kt == nitrst ) THEN
  429. IF(lwp) WRITE(numout,*)
  430. IF(lwp) WRITE(numout,*) 'p4z_rst : write pisces restart file kt =', kt
  431. IF(lwp) WRITE(numout,*) '~~~~~~~'
  432. ENDIF
  433. CALL iom_rstput( kt, nitrst, numrtw, 'PH', hi(:,:,:) )
  434. CALL iom_rstput( kt, nitrst, numrtw, 'Silicalim', xksi(:,:) )
  435. CALL iom_rstput( kt, nitrst, numrtw, 'Silicamax', xksimax(:,:) )
  436. CALL iom_rstput( kt, nitrst, numrtw, 'tcflxcum', t_oce_co2_flx_cum )
  437. ENDIF
  438. !
  439. END SUBROUTINE p4z_rst
  440. SUBROUTINE p4z_dmp( kt )
  441. !!----------------------------------------------------------------------
  442. !! *** p4z_dmp ***
  443. !!
  444. !! ** purpose : Relaxation of some tracers
  445. !!----------------------------------------------------------------------
  446. !
  447. INTEGER, INTENT( in ) :: kt ! time step
  448. !
  449. REAL(wp) :: alkmean = 2426. ! mean value of alkalinity ( Glodap ; for Goyet 2391. )
  450. REAL(wp) :: po4mean = 2.165 ! mean value of phosphates
  451. REAL(wp) :: no3mean = 30.90 ! mean value of nitrate
  452. REAL(wp) :: silmean = 91.51 ! mean value of silicate
  453. !
  454. REAL(wp) :: zarea, zalksumn, zpo4sumn, zno3sumn, zsilsumn
  455. REAL(wp) :: zalksumb, zpo4sumb, zno3sumb, zsilsumb
  456. !!---------------------------------------------------------------------
  457. IF(lwp) WRITE(numout,*)
  458. IF(lwp) WRITE(numout,*) ' p4z_dmp : Restoring of nutrients at time-step kt = ', kt
  459. IF(lwp) WRITE(numout,*)
  460. IF( cp_cfg == "orca" .AND. .NOT. lk_c1d ) THEN ! ORCA configuration (not 1D) !
  461. ! ! --------------------------- !
  462. ! set total alkalinity, phosphate, nitrate & silicate
  463. zarea = 1._wp / glob_sum( cvol(:,:,:) ) * 1e6
  464. zalksumn = glob_sum( trn(:,:,:,jptal) * cvol(:,:,:) ) * zarea
  465. zpo4sumn = glob_sum( trn(:,:,:,jppo4) * cvol(:,:,:) ) * zarea * po4r
  466. zno3sumn = glob_sum( trn(:,:,:,jpno3) * cvol(:,:,:) ) * zarea * rno3
  467. zsilsumn = glob_sum( trn(:,:,:,jpsil) * cvol(:,:,:) ) * zarea
  468. IF(lwp) WRITE(numout,*) ' TALKN mean : ', zalksumn
  469. trn(:,:,:,jptal) = trn(:,:,:,jptal) * alkmean / zalksumn
  470. IF(lwp) WRITE(numout,*) ' PO4N mean : ', zpo4sumn
  471. trn(:,:,:,jppo4) = trn(:,:,:,jppo4) * po4mean / zpo4sumn
  472. IF(lwp) WRITE(numout,*) ' NO3N mean : ', zno3sumn
  473. trn(:,:,:,jpno3) = trn(:,:,:,jpno3) * no3mean / zno3sumn
  474. IF(lwp) WRITE(numout,*) ' SiO3N mean : ', zsilsumn
  475. trn(:,:,:,jpsil) = MIN( 400.e-6,trn(:,:,:,jpsil) * silmean / zsilsumn )
  476. !
  477. !
  478. IF( .NOT. ln_top_euler ) THEN
  479. zalksumb = glob_sum( trb(:,:,:,jptal) * cvol(:,:,:) ) * zarea
  480. zpo4sumb = glob_sum( trb(:,:,:,jppo4) * cvol(:,:,:) ) * zarea * po4r
  481. zno3sumb = glob_sum( trb(:,:,:,jpno3) * cvol(:,:,:) ) * zarea * rno3
  482. zsilsumb = glob_sum( trb(:,:,:,jpsil) * cvol(:,:,:) ) * zarea
  483. IF(lwp) WRITE(numout,*) ' '
  484. IF(lwp) WRITE(numout,*) ' TALKB mean : ', zalksumb
  485. trb(:,:,:,jptal) = trb(:,:,:,jptal) * alkmean / zalksumb
  486. IF(lwp) WRITE(numout,*) ' PO4B mean : ', zpo4sumb
  487. trb(:,:,:,jppo4) = trb(:,:,:,jppo4) * po4mean / zpo4sumb
  488. IF(lwp) WRITE(numout,*) ' NO3B mean : ', zno3sumb
  489. trb(:,:,:,jpno3) = trb(:,:,:,jpno3) * no3mean / zno3sumb
  490. IF(lwp) WRITE(numout,*) ' SiO3B mean : ', zsilsumb
  491. trb(:,:,:,jpsil) = MIN( 400.e-6,trb(:,:,:,jpsil) * silmean / zsilsumb )
  492. ENDIF
  493. !
  494. ENDIF
  495. !
  496. END SUBROUTINE p4z_dmp
  497. SUBROUTINE p4z_chk_mass( kt )
  498. !!----------------------------------------------------------------------
  499. !! *** ROUTINE p4z_chk_mass ***
  500. !!
  501. !! ** Purpose : Mass conservation check
  502. !!
  503. !!---------------------------------------------------------------------
  504. !
  505. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  506. REAL(wp) :: zrdenittot, zsdenittot, znitrpottot
  507. CHARACTER(LEN=100) :: cltxt
  508. REAL(wp), DIMENSION(jpi,jpj,jpk) :: zvol
  509. INTEGER :: jk
  510. !!----------------------------------------------------------------------
  511. !
  512. !!---------------------------------------------------------------------
  513. IF( kt == nittrc000 ) THEN
  514. xfact1 = rfact2r * 12. / 1.e15 * ryyss ! conversion molC/kt --> PgC/yr
  515. xfact2 = 1.e+3 * rno3 * 14. / 1.e12 * ryyss ! conversion molC/l/s ----> TgN/m3/yr
  516. xfact3 = 1.e+3 * rfact2r * rno3 ! conversion molC/l/kt ----> molN/m3/s
  517. IF( ln_check_mass .AND. lwp) THEN ! Open budget file of NO3, ALK, Si, Fer
  518. CALL ctl_opn( numco2, 'carbon.budget' , 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea )
  519. CALL ctl_opn( numnut, 'nutrient.budget', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea )
  520. CALL ctl_opn( numnit, 'nitrogen.budget', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea )
  521. cltxt='time-step Alkalinity Nitrate Phosphorus Silicate Iron'
  522. IF( lwp ) WRITE(numnut,*) TRIM(cltxt)
  523. IF( lwp ) WRITE(numnut,*)
  524. ENDIF
  525. ENDIF
  526. !
  527. IF( iom_use( "pno3tot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  528. ! Compute the budget of NO3, ALK, Si, Fer
  529. no3budget = glob_sum( ( trn(:,:,:,jpno3) + trn(:,:,:,jpnh4) &
  530. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  531. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  532. & + trn(:,:,:,jppoc) &
  533. #if ! defined key_kriest
  534. & + trn(:,:,:,jpgoc) &
  535. #endif
  536. & + trn(:,:,:,jpdoc) ) * cvol(:,:,:) )
  537. !
  538. no3budget = no3budget / areatot
  539. CALL iom_put( "pno3tot", no3budget )
  540. ENDIF
  541. !
  542. IF( iom_use( "ppo4tot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  543. po4budget = glob_sum( ( trn(:,:,:,jppo4) &
  544. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  545. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  546. & + trn(:,:,:,jppoc) &
  547. #if ! defined key_kriest
  548. & + trn(:,:,:,jpgoc) &
  549. #endif
  550. & + trn(:,:,:,jpdoc) ) * cvol(:,:,:) )
  551. po4budget = po4budget / areatot
  552. CALL iom_put( "ppo4tot", po4budget )
  553. ENDIF
  554. !
  555. IF( iom_use( "psiltot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  556. silbudget = glob_sum( ( trn(:,:,:,jpsil) + trn(:,:,:,jpgsi) &
  557. & + trn(:,:,:,jpdsi) ) * cvol(:,:,:) )
  558. !
  559. silbudget = silbudget / areatot
  560. CALL iom_put( "psiltot", silbudget )
  561. ENDIF
  562. !
  563. IF( iom_use( "palktot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  564. alkbudget = glob_sum( ( trn(:,:,:,jpno3) * rno3 &
  565. & + trn(:,:,:,jptal) &
  566. & + trn(:,:,:,jpcal) * 2. ) * cvol(:,:,:) )
  567. !
  568. alkbudget = alkbudget / areatot
  569. CALL iom_put( "palktot", alkbudget )
  570. ENDIF
  571. !
  572. IF( iom_use( "pfertot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  573. ferbudget = glob_sum( ( trn(:,:,:,jpfer) + trn(:,:,:,jpnfe) &
  574. & + trn(:,:,:,jpdfe) &
  575. #if ! defined key_kriest
  576. & + trn(:,:,:,jpbfe) &
  577. #endif
  578. & + trn(:,:,:,jpsfe) &
  579. & + trn(:,:,:,jpzoo) * ferat3 &
  580. & + trn(:,:,:,jpmes) * ferat3 ) * cvol(:,:,:) )
  581. !
  582. ferbudget = ferbudget / areatot
  583. CALL iom_put( "pfertot", ferbudget )
  584. ENDIF
  585. !
  586. ! Global budget of N SMS : denitrification in the water column and in the sediment
  587. ! nitrogen fixation by the diazotrophs
  588. ! --------------------------------------------------------------------------------
  589. IF( iom_use( "tnfix" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  590. znitrpottot = glob_sum ( nitrpot(:,:,:) * nitrfix * cvol(:,:,:) )
  591. CALL iom_put( "tnfix" , znitrpottot * xfact3 ) ! Global nitrogen fixation molC/l to molN/m3
  592. ENDIF
  593. !
  594. IF( iom_use( "tdenit" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  595. zrdenittot = glob_sum ( denitr(:,:,:) * rdenit * xnegtr(:,:,:) * cvol(:,:,:) ) ! denitrification in the water column
  596. zsdenittot = glob_sum ( sdenit(:,:) * e1e2t(:,:) * tmask(:,:,1) ) ! denitrification in the sediments
  597. CALL iom_put( "tdenit" , ( zrdenittot + zsdenittot ) * xfact3 ) ! Total denitrification in molN/m3
  598. ENDIF
  599. IF( ln_check_mass .AND. kt == nitend ) THEN ! Compute the budget of NO3, ALK, Si, Fer
  600. t_atm_co2_flx = t_atm_co2_flx / glob_sum( e1e2t(:,:) )
  601. t_oce_co2_flx = t_oce_co2_flx * xfact1 * (-1 )
  602. tpp = tpp * 1000. * xfact1
  603. t_oce_co2_exp = t_oce_co2_exp * 1000. * xfact1
  604. IF( lwp ) WRITE(numco2,9000) ndastp, t_atm_co2_flx, t_oce_co2_flx, tpp, t_oce_co2_exp
  605. IF( lwp ) WRITE(numnut,9100) ndastp, alkbudget * 1.e+06, &
  606. & no3budget * rno3 * 1.e+06, &
  607. & po4budget * po4r * 1.e+06, &
  608. & silbudget * 1.e+06, &
  609. & ferbudget * 1.e+09
  610. !
  611. IF( lwp ) WRITE(numnit,9200) ndastp, znitrpottot * xfact2 , &
  612. & zrdenittot * xfact2 , &
  613. & zsdenittot * xfact2
  614. ENDIF
  615. !
  616. 9000 FORMAT(i8,f10.5,e18.10,f10.5,f10.5)
  617. 9100 FORMAT(i8,5e18.10)
  618. 9200 FORMAT(i8,3f10.5)
  619. !
  620. END SUBROUTINE p4z_chk_mass
  621. #else
  622. !!======================================================================
  623. !! Dummy module : No PISCES bio-model
  624. !!======================================================================
  625. CONTAINS
  626. SUBROUTINE p4z_sms( kt ) ! Empty routine
  627. INTEGER, INTENT( in ) :: kt
  628. WRITE(*,*) 'p4z_sms: You should not have seen this print! error?', kt
  629. END SUBROUTINE p4z_sms
  630. #endif
  631. !!======================================================================
  632. END MODULE p4zsms