p4zsms.F90 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  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. PUBLIC trc_sms_cfix ! called in trcstp.F90
  37. REAL(wp) :: alkbudget, no3budget, silbudget, ferbudget, po4budget
  38. REAL(wp) :: xfact, xfact1, xfact2, xfact3
  39. REAL(wp) :: dicmasst0 ! EC-Earth C mass conservation correction
  40. REAL(wp) :: sedrivdicsum ! EC-Earth C mass conservation correction
  41. INTEGER :: numco2, numnut, numnit !: logical unit for co2 budget
  42. REAL(wp) :: alkmax = 3200.0e-6_wp ! max value of dic
  43. REAL(wp) :: dicmax = 2800e-6_wp ! mean value of alkalinity
  44. REAL(wp) :: po4max = 10.0e-6_wp ! mean value of phosphates
  45. REAL(wp) :: no3max = 50.0e-6_wp ! mean value of nitrate
  46. REAL(wp) :: silmax = 250.0e-6_wp ! mean value of silicate
  47. REAL(wp) :: fermax = 6.0e-8_wp
  48. REAL(wp) ::dicbudget ! EC-Earth change: add global carbon inventory
  49. !!* Array used to indicate negative tracer values
  50. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: xnegtr !: ???
  51. !! * Substitutions
  52. # include "top_substitute.h90"
  53. !!----------------------------------------------------------------------
  54. !! NEMO/TOP 3.3 , NEMO Consortium (2010)
  55. !! $Id: p4zsms.F90 3320 2012-03-05 16:37:52Z cetlod $
  56. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  57. !!----------------------------------------------------------------------
  58. CONTAINS
  59. SUBROUTINE p4z_sms( kt )
  60. !!---------------------------------------------------------------------
  61. !! *** ROUTINE p4z_sms ***
  62. !!
  63. !! ** Purpose : Managment of the call to Biological sources and sinks
  64. !! routines of PISCES bio-model
  65. !!
  66. !! ** Method : - at each new day ...
  67. !! - several calls of bio and sed ???
  68. !! - ...
  69. !!---------------------------------------------------------------------
  70. !
  71. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  72. !!
  73. INTEGER :: ji, jj, jk, jnt, jn, jl
  74. REAL(wp) :: ztra
  75. REAL(wp) :: dicmassbefore, dicmassafter ! EC-Earth C mass conservation correction
  76. #if defined key_kriest
  77. REAL(wp) :: zcoef1, zcoef2
  78. #endif
  79. CHARACTER (len=25) :: charout
  80. REAL(wp), POINTER, DIMENSION(:,:) :: zw2d
  81. REAL(wp), POINTER, DIMENSION(:,:,:,:) :: ztrdt ! 4D workspace
  82. !!---------------------------------------------------------------------
  83. !
  84. IF( nn_timing == 1 ) CALL timing_start('p4z_sms')
  85. !
  86. IF( kt == nittrc000 ) THEN
  87. !
  88. ALLOCATE( xnegtr(jpi,jpj,jpk) )
  89. !
  90. CALL p4z_che ! initialize the chemical constants
  91. !
  92. IF( .NOT. ln_rsttr ) THEN ; CALL p4z_che_ahini( hi ) ! set PH at kt=nit000
  93. ELSE ; CALL p4z_rst( nittrc000, 'READ' ) !* read or initialize all required fields
  94. ENDIF
  95. !
  96. ENDIF
  97. !
  98. IF( ln_pisdmp .AND. MOD( kt - nn_dttrc, nn_pisdmp ) == 0 ) CALL p4z_dmp( kt ) ! Relaxation of some tracers
  99. !
  100. ! ! set time step size (Euler/Leapfrog)
  101. IF( ( neuler == 0 .AND. kt == nittrc000 ) .OR. ln_top_euler ) THEN ; rfact = rdttrc(1) ! at nittrc000
  102. ELSEIF( kt <= nittrc000 + nn_dttrc ) THEN ; rfact = 2. * rdttrc(1) ! at nittrc000 or nittrc000+nn_dttrc (Leapfrog)
  103. ENDIF
  104. !
  105. ! trends computation initialisation
  106. IF( l_trdtrc ) THEN
  107. CALL wrk_alloc( jpi, jpj, jpk, jp_pisces, ztrdt ) !* store now fields before applying the Asselin filter
  108. ztrdt(:,:,:,:) = trn(:,:,:,:)
  109. ENDIF
  110. !
  111. IF( ( ln_top_euler .AND. kt == nittrc000 ) .OR. ( .NOT.ln_top_euler .AND. kt <= nittrc000 + nn_dttrc ) ) THEN
  112. rfactr = 1. / rfact
  113. rfact2 = rfact / FLOAT( nrdttrc )
  114. rfact2r = 1. / rfact2
  115. xstep = rfact2 / rday ! Time step duration for biology
  116. xfact = 1.e+3 * rfact2r
  117. IF(lwp) WRITE(numout,*)
  118. IF(lwp) WRITE(numout,*) ' Passive Tracer time step rfact = ', rfact, ' rdt = ', rdttra(1)
  119. IF(lwp) write(numout,*) ' PISCES Biology time step rfact2 = ', rfact2
  120. IF(lwp) WRITE(numout,*)
  121. ENDIF
  122. IF( ( neuler == 0 .AND. kt == nittrc000 ) .OR. ln_top_euler ) THEN
  123. DO jn = jp_pcs0, jp_pcs1 ! SMS on tracer without Asselin time-filter
  124. trb(:,:,:,jn) = trn(:,:,:,jn)
  125. END DO
  126. ENDIF
  127. !
  128. IF( ndayflxtr /= nday_year ) THEN ! New days
  129. !
  130. ndayflxtr = nday_year
  131. IF(lwp) write(numout,*)
  132. IF(lwp) write(numout,*) ' New chemical constants and various rates for biogeochemistry at new day : ', nday_year
  133. IF(lwp) write(numout,*) '~~~~~~'
  134. CALL p4z_che ! computation of chemical constants
  135. CALL p4z_int( kt ) ! computation of various rates for biogeochemistry
  136. !
  137. ENDIF
  138. IF( ll_sbc ) CALL p4z_sbc( kt ) ! external sources of nutrients
  139. DO jnt = 1, nrdttrc ! Potential time splitting if requested
  140. !
  141. CALL p4z_bio( kt, jnt ) ! Biology
  142. CALL p4z_lys( kt, jnt ) ! Compute CaCO3 saturation
  143. dicmassbefore = glob_sum( ( tra(:,:,:,jpdic) &
  144. & + tra(:,:,:,jpphy) + tra(:,:,:,jpdia) &
  145. & + tra(:,:,:,jpzoo) + tra(:,:,:,jpmes) &
  146. & + tra(:,:,:,jppoc) &
  147. & + tra(:,:,:,jpgoc) &
  148. & + tra(:,:,:,jpdoc) + tra(:,:,:,jpcal) ) * cvol(:,:,:) ) * 1.E3 ! mol C
  149. CALL p4z_sed( kt, jnt ) ! Surface and Bottom boundary conditions
  150. dicmassafter = glob_sum( ( tra(:,:,:,jpdic) &
  151. & + tra(:,:,:,jpphy) + tra(:,:,:,jpdia) &
  152. & + tra(:,:,:,jpzoo) + tra(:,:,:,jpmes) &
  153. & + tra(:,:,:,jppoc) &
  154. & + tra(:,:,:,jpgoc) &
  155. & + tra(:,:,:,jpdoc) + tra(:,:,:,jpcal) ) * cvol(:,:,:) ) * 1.E3 ! mol C
  156. sedrivdicsum = sedrivdicsum + dicmassafter - dicmassbefore
  157. CALL p4z_flx( kt, jnt ) ! Compute surface fluxes
  158. !
  159. xnegtr(:,:,:) = 1.e0
  160. DO jn = jp_pcs0, jp_pcs1
  161. DO jk = 1, jpk
  162. DO jj = 1, jpj
  163. DO ji = 1, jpi
  164. IF( ( trb(ji,jj,jk,jn) + tra(ji,jj,jk,jn) ) < 0.e0 ) THEN
  165. ztra = ABS( trb(ji,jj,jk,jn) ) / ( ABS( tra(ji,jj,jk,jn) ) + rtrn )
  166. xnegtr(ji,jj,jk) = MIN( xnegtr(ji,jj,jk), ztra )
  167. !!!!introducing a check to debug sedimentation problem, after O. Aumont suggestion. Raffa April 2019
  168. IF (mig(ji) == 64 .and. mjg(jj) == 203 .and. jk == 55 ) THEN
  169. write(0,*) 'error ',jn,xnegtr(ji,jj,jk)
  170. ENDIF
  171. IF (mig(ji) == 64 .and. mjg(jj) == 203 .and. jk == 56 ) THEN
  172. write(0,*) 'error ',jn,xnegtr(ji,jj,jk)
  173. ENDIF
  174. IF (mig(ji) == 64 .and. mjg(jj) == 203 .and. jk == 57 ) THEN
  175. write(0,*) 'error ',jn,xnegtr(ji,jj,jk)
  176. ENDIF
  177. IF (mig(ji) == 64 .and. mjg(jj) == 203 .and. jk == 58 ) THEN
  178. write(0,*) 'error ',jn,xnegtr(ji,jj,jk)
  179. ENDIF
  180. IF (mig(ji) == 64 .and. mjg(jj) == 203 .and. jk == 59 ) THEN
  181. write(0,*) 'error ',jn,xnegtr(ji,jj,jk)
  182. ENDIF
  183. !!!!!end of debugging
  184. ENDIF
  185. END DO
  186. END DO
  187. END DO
  188. END DO
  189. ! ! where at least 1 tracer concentration becomes negative
  190. ! !
  191. DO jn = jp_pcs0, jp_pcs1
  192. trb(:,:,:,jn) = trb(:,:,:,jn) + xnegtr(:,:,:) * tra(:,:,:,jn)
  193. END DO
  194. !
  195. ! Additional CMIP6 diagnostics : At this stage tra includes all terms
  196. IF( lk_iomput ) THEN
  197. CALL wrk_alloc( jpi, jpj, zw2d )
  198. !
  199. IF( iom_use( "INTdtAlk" ) ) THEN
  200. zw2d(:,:) = 0.
  201. DO jk = 1, jpkm1
  202. zw2d(:,:) = zw2d(:,:) &
  203. & + xnegtr(:,:,jk) * tra(:,:,jk,jptal) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  204. ENDDO
  205. CALL iom_put( "INTdtAlk", zw2d )
  206. ENDIF
  207. !
  208. IF( iom_use( "INTdtDIC" ) ) THEN
  209. zw2d(:,:) = 0.
  210. DO jk = 1, jpkm1
  211. zw2d(:,:) = zw2d(:,:) &
  212. & + xnegtr(:,:,jk) * tra(:,:,jk,jpdic) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  213. ENDDO
  214. CALL iom_put( "INTdtDIC", zw2d )
  215. ENDIF
  216. !
  217. IF( iom_use( "INTdtFer" ) ) THEN
  218. zw2d(:,:) = 0.
  219. DO jk = 1, jpkm1
  220. zw2d(:,:) = zw2d(:,:) &
  221. & + xnegtr(:,:,jk) * tra(:,:,jk,jpfer) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  222. ENDDO
  223. CALL iom_put( "INTdtFer", zw2d )
  224. ENDIF
  225. !
  226. IF( iom_use( "INTdtDIN" ) ) THEN
  227. zw2d(:,:) = 0.
  228. DO jk = 1, jpkm1
  229. zw2d(:,:) = zw2d(:,:) &
  230. & + xnegtr(:,:,jk) * ( tra(:,:,jk,jpno3) + tra(:,:,jk,jpnh4) ) &
  231. & * rno3 * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  232. ENDDO
  233. CALL iom_put( "INTdtDIN", zw2d )
  234. ENDIF
  235. !
  236. IF( iom_use( "INTdtDIP" ) ) THEN
  237. zw2d(:,:) = 0.
  238. DO jk = 1, jpkm1
  239. zw2d(:,:) = zw2d(:,:) &
  240. & + xnegtr(:,:,jk) * tra(:,:,jk,jppo4) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  241. ENDDO
  242. CALL iom_put( "INTdtDIP", zw2d )
  243. ENDIF
  244. !
  245. IF( iom_use( "INTdtSil" ) ) THEN
  246. zw2d(:,:) = 0.
  247. DO jk = 1, jpkm1
  248. zw2d(:,:) = zw2d(:,:) &
  249. & + xnegtr(:,:,jk) * tra(:,:,jk,jpsil) * xfact * fse3t(:,:,jk) * tmask(:,:,jk)
  250. ENDDO
  251. CALL iom_put( "INTdtSil", zw2d )
  252. ENDIF
  253. CALL wrk_dealloc( jpi, jpj, zw2d )
  254. ENDIF
  255. !
  256. DO jn = jp_pcs0, jp_pcs1
  257. tra(:,:,:,jn) = 0._wp
  258. END DO
  259. !
  260. IF( ln_top_euler ) THEN
  261. DO jn = jp_pcs0, jp_pcs1
  262. trn(:,:,:,jn) = trb(:,:,:,jn)
  263. END DO
  264. ENDIF
  265. END DO
  266. ! threshold values to avoid huge concentration, especially on river mouths
  267. DO jk = 1,jpkm1
  268. trn(:,:,jk,jptal) = MIN( trn(:,:,jk,jptal), alkmax )
  269. trn(:,:,jk,jpdic) = MIN( trn(:,:,jk,jpdic), dicmax )
  270. trn(:,:,jk,jppo4) = MIN( trn(:,:,jk,jppo4), po4max / po4r )
  271. trn(:,:,jk,jpsil) = MIN( trn(:,:,jk,jpsil), silmax )
  272. trn(:,:,jk,jpfer) = MIN( trn(:,:,jk,jpfer), fermax )
  273. trn(:,:,jk,jpno3) = MIN( trn(:,:,jk,jpno3), no3max / rno3 )
  274. !
  275. trb(:,:,jk,jptal) = MIN( trb(:,:,jk,jptal), alkmax )
  276. trb(:,:,jk,jpdic) = MIN( trb(:,:,jk,jpdic), dicmax )
  277. trb(:,:,jk,jppo4) = MIN( trb(:,:,jk,jppo4), po4max / po4r )
  278. trb(:,:,jk,jpsil) = MIN( trb(:,:,jk,jpsil), silmax )
  279. trb(:,:,jk,jpfer) = MIN( trb(:,:,jk,jpfer), fermax )
  280. trb(:,:,jk,jpno3) = MIN( trb(:,:,jk,jpno3), no3max / rno3 )
  281. END DO
  282. #if defined key_kriest
  283. !
  284. zcoef1 = 1.e0 / xkr_massp
  285. zcoef2 = 1.e0 / xkr_massp / 1.1
  286. DO jk = 1,jpkm1
  287. trb(:,:,jk,jpnum) = MAX( trb(:,:,jk,jpnum), trb(:,:,jk,jppoc) * zcoef1 / xnumm(jk) )
  288. trb(:,:,jk,jpnum) = MIN( trb(:,:,jk,jpnum), trb(:,:,jk,jppoc) * zcoef2 )
  289. END DO
  290. !
  291. #endif
  292. !
  293. !
  294. IF( l_trdtrc ) THEN
  295. DO jn = jp_pcs0, jp_pcs1
  296. ztrdt(:,:,:,jn) = ( trb(:,:,:,jn) - ztrdt(:,:,:,jn) ) * rfact2r
  297. CALL trd_trc( ztrdt(:,:,:,jn), jn, jptra_sms, kt ) ! save trends
  298. END DO
  299. CALL wrk_dealloc( jpi, jpj, jpk, jp_pisces, ztrdt )
  300. END IF
  301. !
  302. IF( lk_sed ) THEN
  303. !
  304. CALL sed_model( kt ) ! Main program of Sediment model
  305. !
  306. DO jn = jp_pcs0, jp_pcs1
  307. CALL lbc_lnk( trb(:,:,:,jn), 'T', 1. )
  308. END DO
  309. !
  310. ENDIF
  311. !
  312. IF( lrst_trc ) CALL p4z_rst( kt, 'WRITE' ) !* Write PISCES informations in restart file
  313. !
  314. IF( lk_iomput .OR. ln_check_mass ) CALL p4z_chk_mass( kt ) ! Mass conservation checking
  315. IF ( lwm .AND. kt == nittrc000 ) CALL FLUSH ( numonp ) ! flush output namelist PISCES
  316. IF( nn_timing == 1 ) CALL timing_stop('p4z_sms')
  317. !
  318. !
  319. END SUBROUTINE p4z_sms
  320. SUBROUTINE p4z_sms_init
  321. !!----------------------------------------------------------------------
  322. !! *** p4z_sms_init ***
  323. !!
  324. !! ** Purpose : read PISCES namelist
  325. !!
  326. !! ** input : file 'namelist.trc.s' containing the following
  327. !! namelist: natext, natbio, natsms
  328. !! natkriest ("key_kriest")
  329. !!----------------------------------------------------------------------
  330. NAMELIST/nampisbio/ nrdttrc, wsbio, xkmort, ferat3, wsbio2, niter1max, niter2max
  331. #if defined key_kriest
  332. NAMELIST/nampiskrp/ xkr_eta, xkr_zeta, xkr_ncontent, xkr_mass_min, xkr_mass_max
  333. #endif
  334. NAMELIST/nampisdmp/ ln_pisdmp, nn_pisdmp
  335. NAMELIST/nampismass/ ln_check_mass
  336. INTEGER :: ios ! Local integer output status for namelist read
  337. !!----------------------------------------------------------------------
  338. REWIND( numnatp_ref ) ! Namelist nampisbio in reference namelist : Pisces variables
  339. READ ( numnatp_ref, nampisbio, IOSTAT = ios, ERR = 901)
  340. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisbio in reference namelist', lwp )
  341. REWIND( numnatp_cfg ) ! Namelist nampisbio in configuration namelist : Pisces variables
  342. READ ( numnatp_cfg, nampisbio, IOSTAT = ios, ERR = 902 )
  343. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisbio in configuration namelist', lwp )
  344. IF(lwm) WRITE ( numonp, nampisbio )
  345. IF(lwp) THEN ! control print
  346. WRITE(numout,*) ' Namelist : nampisbio'
  347. WRITE(numout,*) ' frequence pour la biologie nrdttrc =', nrdttrc
  348. WRITE(numout,*) ' POC sinking speed wsbio =', wsbio
  349. WRITE(numout,*) ' half saturation constant for mortality xkmort =', xkmort
  350. WRITE(numout,*) ' Fe/C in zooplankton ferat3 =', ferat3
  351. WRITE(numout,*) ' Big particles sinking speed wsbio2 =', wsbio2
  352. WRITE(numout,*) ' Maximum number of iterations for POC niter1max =', niter1max
  353. WRITE(numout,*) ' Maximum number of iterations for GOC niter2max =', niter2max
  354. ENDIF
  355. #if defined key_kriest
  356. ! ! nampiskrp : kriest parameters
  357. ! ! -----------------------------
  358. REWIND( numnatp_ref ) ! Namelist nampiskrp in reference namelist : Pisces Kriest
  359. READ ( numnatp_ref, nampiskrp, IOSTAT = ios, ERR = 903)
  360. 903 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampiskrp in reference namelist', lwp )
  361. REWIND( numnatp_cfg ) ! Namelist nampiskrp in configuration namelist : Pisces Kriest
  362. READ ( numnatp_cfg, nampiskrp, IOSTAT = ios, ERR = 904 )
  363. 904 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampiskrp in configuration namelist', lwp )
  364. IF(lwm) WRITE ( numonp, nampiskrp )
  365. IF(lwp) THEN
  366. WRITE(numout,*)
  367. WRITE(numout,*) ' Namelist : nampiskrp'
  368. WRITE(numout,*) ' Sinking exponent xkr_eta = ', xkr_eta
  369. WRITE(numout,*) ' N content exponent xkr_zeta = ', xkr_zeta
  370. WRITE(numout,*) ' N content factor xkr_ncontent = ', xkr_ncontent
  371. WRITE(numout,*) ' Minimum mass for Aggregates xkr_mass_min = ', xkr_mass_min
  372. WRITE(numout,*) ' Maximum mass for Aggregates xkr_mass_max = ', xkr_mass_max
  373. WRITE(numout,*)
  374. ENDIF
  375. ! Computation of some variables
  376. xkr_massp = xkr_ncontent * 7.625 * xkr_mass_min**xkr_zeta
  377. #endif
  378. REWIND( numnatp_ref ) ! Namelist nampisdmp in reference namelist : Pisces damping
  379. READ ( numnatp_ref, nampisdmp, IOSTAT = ios, ERR = 905)
  380. 905 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisdmp in reference namelist', lwp )
  381. REWIND( numnatp_cfg ) ! Namelist nampisdmp in configuration namelist : Pisces damping
  382. READ ( numnatp_cfg, nampisdmp, IOSTAT = ios, ERR = 906 )
  383. 906 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisdmp in configuration namelist', lwp )
  384. IF(lwm) WRITE ( numonp, nampisdmp )
  385. IF(lwp) THEN ! control print
  386. WRITE(numout,*)
  387. WRITE(numout,*) ' Namelist : nampisdmp'
  388. WRITE(numout,*) ' Relaxation of tracer to glodap mean value ln_pisdmp =', ln_pisdmp
  389. WRITE(numout,*) ' Frequency of Relaxation nn_pisdmp =', nn_pisdmp
  390. WRITE(numout,*) ' '
  391. ENDIF
  392. REWIND( numnatp_ref ) ! Namelist nampismass in reference namelist : Pisces mass conservation check
  393. READ ( numnatp_ref, nampismass, IOSTAT = ios, ERR = 907)
  394. 907 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampismass in reference namelist', lwp )
  395. REWIND( numnatp_cfg ) ! Namelist nampismass in configuration namelist : Pisces mass conservation check
  396. READ ( numnatp_cfg, nampismass, IOSTAT = ios, ERR = 908 )
  397. 908 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampismass in configuration namelist', lwp )
  398. IF(lwm) WRITE ( numonp, nampismass )
  399. IF(lwp) THEN ! control print
  400. WRITE(numout,*) ' '
  401. WRITE(numout,*) ' Namelist parameter for mass conservation checking'
  402. WRITE(numout,*) ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
  403. WRITE(numout,*) ' Flag to check mass conservation of NO3/Si/TALK ln_check_mass = ', ln_check_mass
  404. ENDIF
  405. END SUBROUTINE p4z_sms_init
  406. SUBROUTINE p4z_rst( kt, cdrw )
  407. !!---------------------------------------------------------------------
  408. !! *** ROUTINE p4z_rst ***
  409. !!
  410. !! ** Purpose : Read or write variables in restart file:
  411. !!
  412. !! WRITE(READ) mode:
  413. !! kt : number of time step since the begining of the experiment at the
  414. !! end of the current(previous) run
  415. !!---------------------------------------------------------------------
  416. INTEGER , INTENT(in) :: kt ! ocean time-step
  417. CHARACTER(len=*), INTENT(in) :: cdrw ! "READ"/"WRITE" flag
  418. !!---------------------------------------------------------------------
  419. IF( TRIM(cdrw) == 'READ' ) THEN
  420. !
  421. IF(lwp) WRITE(numout,*)
  422. IF(lwp) WRITE(numout,*) ' p4z_rst : Read specific variables from pisces model '
  423. IF(lwp) WRITE(numout,*) ' ~~~~~~~~~~~~~~'
  424. !
  425. IF( iom_varid( numrtr, 'PH', ldstop = .FALSE. ) > 0 ) THEN
  426. CALL iom_get( numrtr, jpdom_autoglo, 'PH' , hi(:,:,:) )
  427. ELSE
  428. CALL p4z_che_ahini( hi )
  429. ENDIF
  430. CALL iom_get( numrtr, jpdom_autoglo, 'Silicalim', xksi(:,:) )
  431. IF( iom_varid( numrtr, 'Silicamax', ldstop = .FALSE. ) > 0 ) THEN
  432. CALL iom_get( numrtr, jpdom_autoglo, 'Silicamax' , xksimax(:,:) )
  433. ELSE
  434. xksimax(:,:) = xksi(:,:)
  435. ENDIF
  436. !
  437. ! IF( iom_varid( numrtr, 'tcflxcum', ldstop = .FALSE. ) > 0 ) THEN ! cumulative total flux of carbon
  438. ! CALL iom_get( numrtr, 'tcflxcum' , t_oce_co2_flx_cum )
  439. ! ELSE
  440. ! t_oce_co2_flx_cum = 0._wp
  441. ! ENDIF
  442. ! IF( iom_varid( numrtr, 'zsedccum', ldstop = .FALSE. ) > 0 ) THEN ! cumulative total flux of carbon
  443. ! CALL iom_get( numrtr, 'zsedccum' , zsedc_cum )
  444. ! ELSE
  445. ! zsedc_cum = 0._wp
  446. ! ENDIF
  447. ! IF( iom_varid( numrtr, 'dicmasst0', ldstop = .FALSE. ) > 0 ) THEN ! cumulative total flux of carbon
  448. ! CALL iom_get( numrtr, 'dicmasst0' , dicmasst0 )
  449. ! ELSE
  450. ! dicmasst0 = 0._wp
  451. ! ENDIF
  452. ! addying a printout - Raffa
  453. ! WRITE(numout,*) 't_oce_co2_flx_cum as read from restart file =', t_oce_co2_flx_cum
  454. ! WRITE(numout,*) 'zsedc_cum as read from restart file =', zsedc_cum
  455. ! WRITE(numout,*) 'dicmasst0 as read from restart file =', dicmasst0
  456. !
  457. ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN
  458. IF( kt == nitrst ) THEN
  459. IF(lwp) WRITE(numout,*)
  460. IF(lwp) WRITE(numout,*) 'p4z_rst : write pisces restart file kt =', kt
  461. IF(lwp) WRITE(numout,*) '~~~~~~~'
  462. ENDIF
  463. CALL iom_rstput( kt, nitrst, numrtw, 'PH', hi(:,:,:) )
  464. CALL iom_rstput( kt, nitrst, numrtw, 'Silicalim', xksi(:,:) )
  465. CALL iom_rstput( kt, nitrst, numrtw, 'Silicamax', xksimax(:,:) )
  466. ! CALL iom_rstput( kt, nitrst, numrtw, 'tcflxcum', t_oce_co2_flx_cum )
  467. ! CALL iom_rstput( kt, nitrst, numrtw, 'zsedccum', zsedc_cum )
  468. ! CALL iom_rstput( kt, nitrst, numrtw, 'dicmasst0', dicmasst0 )
  469. ENDIF
  470. !
  471. END SUBROUTINE p4z_rst
  472. SUBROUTINE p4z_dmp( kt )
  473. !!----------------------------------------------------------------------
  474. !! *** p4z_dmp ***
  475. !!
  476. !! ** purpose : Relaxation of some tracers
  477. !!----------------------------------------------------------------------
  478. !
  479. INTEGER, INTENT( in ) :: kt ! time step
  480. !
  481. REAL(wp) :: alkmean = 2426. ! mean value of alkalinity ( Glodap ; for Goyet 2391. )
  482. REAL(wp) :: po4mean = 2.165 ! mean value of phosphates
  483. REAL(wp) :: no3mean = 30.90 ! mean value of nitrate
  484. REAL(wp) :: silmean = 91.51 ! mean value of silicate
  485. !
  486. REAL(wp) :: zarea, zalksumn, zpo4sumn, zno3sumn, zsilsumn
  487. REAL(wp) :: zalksumb, zpo4sumb, zno3sumb, zsilsumb
  488. !!---------------------------------------------------------------------
  489. IF(lwp) WRITE(numout,*)
  490. IF(lwp) WRITE(numout,*) ' p4z_dmp : Restoring of nutrients at time-step kt = ', kt
  491. IF(lwp) WRITE(numout,*)
  492. IF( cp_cfg == "orca" .AND. .NOT. lk_c1d ) THEN ! ORCA configuration (not 1D) !
  493. ! ! --------------------------- !
  494. ! set total alkalinity, phosphate, nitrate & silicate
  495. zarea = 1._wp / glob_sum( cvol(:,:,:) ) * 1e6
  496. zalksumn = glob_sum( trn(:,:,:,jptal) * cvol(:,:,:) ) * zarea
  497. zpo4sumn = glob_sum( trn(:,:,:,jppo4) * cvol(:,:,:) ) * zarea * po4r
  498. zno3sumn = glob_sum( trn(:,:,:,jpno3) * cvol(:,:,:) ) * zarea * rno3
  499. zsilsumn = glob_sum( trn(:,:,:,jpsil) * cvol(:,:,:) ) * zarea
  500. IF(lwp) WRITE(numout,*) ' TALKN mean : ', zalksumn
  501. trn(:,:,:,jptal) = trn(:,:,:,jptal) * alkmean / zalksumn
  502. IF(lwp) WRITE(numout,*) ' PO4N mean : ', zpo4sumn
  503. trn(:,:,:,jppo4) = trn(:,:,:,jppo4) * po4mean / zpo4sumn
  504. IF(lwp) WRITE(numout,*) ' NO3N mean : ', zno3sumn
  505. trn(:,:,:,jpno3) = trn(:,:,:,jpno3) * no3mean / zno3sumn
  506. IF(lwp) WRITE(numout,*) ' SiO3N mean : ', zsilsumn
  507. trn(:,:,:,jpsil) = MIN( 400.e-6,trn(:,:,:,jpsil) * silmean / zsilsumn )
  508. !
  509. !
  510. IF( .NOT. ln_top_euler ) THEN
  511. zalksumb = glob_sum( trb(:,:,:,jptal) * cvol(:,:,:) ) * zarea
  512. zpo4sumb = glob_sum( trb(:,:,:,jppo4) * cvol(:,:,:) ) * zarea * po4r
  513. zno3sumb = glob_sum( trb(:,:,:,jpno3) * cvol(:,:,:) ) * zarea * rno3
  514. zsilsumb = glob_sum( trb(:,:,:,jpsil) * cvol(:,:,:) ) * zarea
  515. IF(lwp) WRITE(numout,*) ' '
  516. IF(lwp) WRITE(numout,*) ' TALKB mean : ', zalksumb
  517. trb(:,:,:,jptal) = trb(:,:,:,jptal) * alkmean / zalksumb
  518. IF(lwp) WRITE(numout,*) ' PO4B mean : ', zpo4sumb
  519. trb(:,:,:,jppo4) = trb(:,:,:,jppo4) * po4mean / zpo4sumb
  520. IF(lwp) WRITE(numout,*) ' NO3B mean : ', zno3sumb
  521. trb(:,:,:,jpno3) = trb(:,:,:,jpno3) * no3mean / zno3sumb
  522. IF(lwp) WRITE(numout,*) ' SiO3B mean : ', zsilsumb
  523. trb(:,:,:,jpsil) = MIN( 400.e-6,trb(:,:,:,jpsil) * silmean / zsilsumb )
  524. ENDIF
  525. !
  526. ENDIF
  527. !
  528. END SUBROUTINE p4z_dmp
  529. SUBROUTINE p4z_chk_mass( kt )
  530. !!----------------------------------------------------------------------
  531. !! *** ROUTINE p4z_chk_mass ***
  532. !!
  533. !! ** Purpose : Mass conservation check
  534. !!
  535. !!---------------------------------------------------------------------
  536. !
  537. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  538. REAL(wp) :: zrdenittot, zsdenittot, znitrpottot
  539. CHARACTER(LEN=100) :: cltxt
  540. REAL(wp), DIMENSION(jpi,jpj,jpk) :: zvol
  541. INTEGER :: jk
  542. !!----------------------------------------------------------------------
  543. !
  544. !!---------------------------------------------------------------------
  545. IF( kt == nittrc000 ) THEN
  546. xfact1 = rfact2r * 12. / 1.e15 * ryyss ! conversion molC/kt --> PgC/yr
  547. xfact2 = 1.e+3 * rno3 * 14. / 1.e12 * ryyss ! conversion molC/l/s ----> TgN/m3/yr
  548. xfact3 = 1.e+3 * rfact2r * rno3 ! conversion molC/l/kt ----> molN/m3/s
  549. IF( ln_check_mass .AND. lwp) THEN ! Open budget file of NO3, ALK, Si, Fer
  550. CALL ctl_opn( numco2, 'carbon.budget' , 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea )
  551. CALL ctl_opn( numnut, 'nutrient.budget', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea )
  552. CALL ctl_opn( numnit, 'nitrogen.budget', 'REPLACE', 'FORMATTED', 'SEQUENTIAL', -1, 6, .FALSE., narea )
  553. cltxt='time-step Alkalinity Nitrate Phosphorus Silicate Iron'
  554. IF( lwp ) WRITE(numnut,*) TRIM(cltxt)
  555. IF( lwp ) WRITE(numnut,*)
  556. ENDIF
  557. ENDIF
  558. ! BEGIN EC-Earth change: add global carbon inventory
  559. IF( iom_use( "dictot" ) .OR. (ln_check_mass .AND. kt == nitend ) ) THEN
  560. dicbudget = glob_sum( ( trn(:,:,:,jpdic) &
  561. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  562. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  563. & + trn(:,:,:,jppoc) &
  564. #if ! defined key_kriest
  565. & + trn(:,:,:,jpgoc) &
  566. #endif
  567. & + trn(:,:,:,jpdoc) ) * cvol(:,:,:) )
  568. CALL iom_put( "dictot", dicbudget )
  569. ENDIF
  570. ! END EC-Earth change
  571. !
  572. IF( iom_use( "pno3tot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  573. ! Compute the budget of NO3, ALK, Si, Fer
  574. no3budget = glob_sum( ( trn(:,:,:,jpno3) + trn(:,:,:,jpnh4) &
  575. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  576. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  577. & + trn(:,:,:,jppoc) &
  578. #if ! defined key_kriest
  579. & + trn(:,:,:,jpgoc) &
  580. #endif
  581. & + trn(:,:,:,jpdoc) ) * cvol(:,:,:) )
  582. !
  583. no3budget = no3budget / areatot
  584. CALL iom_put( "pno3tot", no3budget )
  585. ENDIF
  586. !
  587. IF( iom_use( "ppo4tot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  588. po4budget = glob_sum( ( trn(:,:,:,jppo4) &
  589. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  590. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  591. & + trn(:,:,:,jppoc) &
  592. #if ! defined key_kriest
  593. & + trn(:,:,:,jpgoc) &
  594. #endif
  595. & + trn(:,:,:,jpdoc) ) * cvol(:,:,:) )
  596. po4budget = po4budget / areatot
  597. CALL iom_put( "ppo4tot", po4budget )
  598. ENDIF
  599. !
  600. IF( iom_use( "psiltot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  601. silbudget = glob_sum( ( trn(:,:,:,jpsil) + trn(:,:,:,jpgsi) &
  602. & + trn(:,:,:,jpdsi) ) * cvol(:,:,:) )
  603. !
  604. silbudget = silbudget / areatot
  605. CALL iom_put( "psiltot", silbudget )
  606. ENDIF
  607. !
  608. IF( iom_use( "palktot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  609. alkbudget = glob_sum( ( trn(:,:,:,jpno3) * rno3 &
  610. & + trn(:,:,:,jptal) &
  611. & + trn(:,:,:,jpcal) * 2. ) * cvol(:,:,:) )
  612. !
  613. alkbudget = alkbudget / areatot
  614. CALL iom_put( "palktot", alkbudget )
  615. ENDIF
  616. !
  617. IF( iom_use( "pfertot" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  618. ferbudget = glob_sum( ( trn(:,:,:,jpfer) + trn(:,:,:,jpnfe) &
  619. & + trn(:,:,:,jpdfe) &
  620. #if ! defined key_kriest
  621. & + trn(:,:,:,jpbfe) &
  622. #endif
  623. & + trn(:,:,:,jpsfe) &
  624. & + trn(:,:,:,jpzoo) * ferat3 &
  625. & + trn(:,:,:,jpmes) * ferat3 ) * cvol(:,:,:) )
  626. !
  627. ferbudget = ferbudget / areatot
  628. CALL iom_put( "pfertot", ferbudget )
  629. ENDIF
  630. !
  631. ! Global budget of N SMS : denitrification in the water column and in the sediment
  632. ! nitrogen fixation by the diazotrophs
  633. ! --------------------------------------------------------------------------------
  634. IF( iom_use( "tnfix" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  635. znitrpottot = glob_sum ( nitrpot(:,:,:) * nitrfix * cvol(:,:,:) )
  636. CALL iom_put( "tnfix" , znitrpottot * xfact3 ) ! Global nitrogen fixation molC/l to molN/m3
  637. ENDIF
  638. !
  639. IF( iom_use( "tdenit" ) .OR. ( ln_check_mass .AND. kt == nitend ) ) THEN
  640. zrdenittot = glob_sum ( denitr(:,:,:) * rdenit * xnegtr(:,:,:) * cvol(:,:,:) ) ! denitrification in the water column
  641. zsdenittot = glob_sum ( sdenit(:,:) * e1e2t(:,:) * tmask(:,:,1) ) ! denitrification in the sediments
  642. CALL iom_put( "tdenit" , ( zrdenittot + zsdenittot ) * xfact3 ) ! Total denitrification in molN/m3
  643. ENDIF
  644. IF( ln_check_mass .AND. kt == nitend ) THEN ! Compute the budget of NO3, ALK, Si, Fer
  645. t_atm_co2_flx = t_atm_co2_flx / glob_sum( e1e2t(:,:) )
  646. t_oce_co2_flx = t_oce_co2_flx * xfact1 * (-1 )
  647. tpp = tpp * 1000. * xfact1
  648. t_oce_co2_exp = t_oce_co2_exp * 1000. * xfact1
  649. IF( lwp ) WRITE(numco2,9000) ndastp, t_atm_co2_flx, t_oce_co2_flx, tpp, t_oce_co2_exp
  650. IF( lwp ) WRITE(numnut,9100) ndastp, alkbudget * 1.e+06, &
  651. & no3budget * rno3 * 1.e+06, &
  652. & po4budget * po4r * 1.e+06, &
  653. & silbudget * 1.e+06, &
  654. & ferbudget * 1.e+09
  655. !
  656. IF( lwp ) WRITE(numnit,9200) ndastp, znitrpottot * xfact2 , &
  657. & zrdenittot * xfact2 , &
  658. & zsdenittot * xfact2
  659. ENDIF
  660. !
  661. 9000 FORMAT(i8,f10.5,e18.10,f10.5,f10.5)
  662. 9100 FORMAT(i8,5e18.10)
  663. 9200 FORMAT(i8,3f10.5)
  664. !
  665. END SUBROUTINE p4z_chk_mass
  666. SUBROUTINE trc_sms_cfix( kt )
  667. !!----------------------------------------------------------------------
  668. !! *** ROUTINE trc_sms_cfix ***
  669. !!
  670. !! ** Purpose : Correction for mass conservation of Carbon (EC-Earth fix)
  671. !!
  672. !!---------------------------------------------------------------------
  673. !
  674. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  675. REAL(wp) :: dicmasstend, dicres, totvol ! EC-Earth C mass conservation correction
  676. REAL(wp) :: dicend, docend, phyend, phy2end ! EC-Earth C mass conservation correction
  677. REAL(wp) :: pocend, gocend, zooend, zoo2end, caco3end ! EC-Earth C mass conservation correction
  678. INTEGER :: jk
  679. !!----------------------------------------------------------------------
  680. !
  681. !!---------------------------------------------------------------------
  682. !!!!Begin EC-Earth modification for mass conservation of carbon. Author Raffaele Bernardello, January 2019
  683. !
  684. ! We don't get satisfying mass conservation for passive tracers in NEMO. Drift in total mass is of
  685. ! the order of a few thousandths/year. Over a long spinup (thousands of years) this results in a drift of
  686. ! several points %. After much researching and asking around it seems we are not the only ones with this problem
  687. ! however, we haven't been able to find the reason. We need a workaround in order to run the ocean spinup needed for
  688. ! CMIP6. Unlike other tracers, DIC does not have a total mass correction available in PISCES
  689. ! code. So we are creating one here. Other tracers (NO3, Alk, PO4) are periodically adjusted in total mass to conserve
  690. ! the initial amount. This can't be done with DIC because the spun-up state will be used to run transient simulations
  691. ! with increase of atmospheric CO2 and consequent ocean uptake. So, the ocean DIC needs to be trully equilibrated.
  692. !
  693. ! Here, we compute the total amount of C in the ocean at the beginning of the leg. Then we do the same at the end
  694. ! of the leg. Plus, we consider the accumulated air-sea co2 flux, sedimentation of C and Cal, and river input during the leg.
  695. ! The change in internal mass has to equal the sum of sink and sources. The residual is used to compute a homogeneous
  696. ! global correction to be applied uniformly everywhere to DIC.
  697. !
  698. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  699. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  700. !
  701. IF( kt == nittrc000 ) THEN
  702. dicmasst0 = 0._wp
  703. ! total mass at initial time-step
  704. dicmasst0 = glob_sum( ( trn(:,:,:,jpdic) &
  705. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  706. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  707. & + trn(:,:,:,jppoc) &
  708. & + trn(:,:,:,jpgoc) &
  709. & + trn(:,:,:,jpdoc) + trn(:,:,:,jpcal) ) * cvol(:,:,:) ) * 1.E3 ! mol C
  710. ! Initialize t_oce_co2_flx_cum and zsedc_cum
  711. t_oce_co2_flx_cum = 0._wp
  712. zsedc_cum = 0._wp
  713. riverdicsum = 0._wp
  714. sedrivdicsum = 0._wp
  715. WRITE(numout,*) 't_oce_co2_flx_cum (mol C) as initialized in this chunk', t_oce_co2_flx_cum
  716. WRITE(numout,*) 'zsedc_cum (mol C) as initialized in this chunk', zsedc_cum
  717. WRITE(numout,*) 'riverdicsum (mol C) as initialized in this chunk', riverdicsum
  718. WRITE(numout,*) 'sedrivdicsum (mol C) as initialized in this chunk', sedrivdicsum
  719. WRITE(numout,*) 'dicmasst0 (mol C) as initialized in this chunk', dicmasst0
  720. END IF
  721. !
  722. !
  723. IF( kt == nitend ) THEN
  724. dicmasstend = glob_sum( ( trn(:,:,:,jpdic) &
  725. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  726. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  727. & + trn(:,:,:,jppoc) &
  728. & + trn(:,:,:,jpgoc) &
  729. & + trn(:,:,:,jpdoc) + trn(:,:,:,jpcal) ) * cvol(:,:,:) ) * 1.E3 ! mol C
  730. dicend = glob_sum( trn(:,:,:,jpdic) * cvol(:,:,:)) * 1.E3
  731. docend = glob_sum( trn(:,:,:,jpdoc) * cvol(:,:,:)) * 1.E3
  732. phyend = glob_sum( trn(:,:,:,jpphy) * cvol(:,:,:)) * 1.E3
  733. phy2end = glob_sum( trn(:,:,:,jpdia) * cvol(:,:,:)) * 1.E3
  734. zooend = glob_sum( trn(:,:,:,jpzoo) * cvol(:,:,:)) * 1.E3
  735. zoo2end = glob_sum( trn(:,:,:,jpmes) * cvol(:,:,:)) * 1.E3
  736. pocend = glob_sum( trn(:,:,:,jppoc) * cvol(:,:,:)) * 1.E3
  737. gocend = glob_sum( trn(:,:,:,jpgoc) * cvol(:,:,:)) * 1.E3
  738. caco3end = glob_sum( trn(:,:,:,jpcal) * cvol(:,:,:)) * 1.E3
  739. totvol = glob_sum( cvol(:,:,:) )
  740. ! dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum )/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  741. ! dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum - rivdicinput * 1.E3)/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  742. dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum - riverdicsum)/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  743. WRITE(numout,*) 'dicres (mol C/l) as calculated here with zsedc_cum=', dicres
  744. dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum - sedrivdicsum)/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  745. WRITE(numout,*) 'dicres (mol C/l) as calculated here with sedrivdicsum=', dicres
  746. !
  747. WRITE(numout,*) 'dicmasstend (mol C) =', dicmasstend
  748. WRITE(numout,*) 'dicmasst0 (mol C) =', dicmasst0
  749. WRITE(numout,*) 't_oce_co2_flx_cum (mol C) as calculated in this chunk', t_oce_co2_flx_cum
  750. WRITE(numout,*) 'zsedc_cum (mol C) as calculated in this chunk', zsedc_cum
  751. WRITE(numout,*) 'rivdicinput (mol C) as calculated at beginning', rivdicinput * 1.E3
  752. WRITE(numout,*) 'rivdicinput (mol C) as calculated in this chunk', riverdicsum
  753. WRITE(numout,*) 'sedrivdicsum (mol C) as calculated in this chunk', sedrivdicsum
  754. WRITE(numout,*) 'dicres (mol C/l) as calculated here =', dicres
  755. ! WRITE(numout,*) 'areatot =', areatot
  756. WRITE(numout,*) 'totvol =', totvol
  757. ! WRITE(numout,*) 'dicend (trn) =', dicend
  758. ! WRITE(numout,*) 'docend =', docend
  759. ! WRITE(numout,*) 'phyend =', phyend
  760. ! WRITE(numout,*) 'phy2end =', phy2end
  761. ! WRITE(numout,*) 'zooend =', zooend
  762. ! WRITE(numout,*) 'zoo2end =', zoo2end
  763. ! WRITE(numout,*) 'pocend =', pocend
  764. ! WRITE(numout,*) 'gocend =', gocend
  765. ! WRITE(numout,*) 'caco3end =', caco3end
  766. ! dicend = glob_sum( trb(:,:,:,jpdic) * cvol(:,:,:)) * 1.E3
  767. ! WRITE(numout,*) 'dicend (trb) =', dicend
  768. ! apply correction to dic
  769. trn(:,:,:,jpdic) = (trn(:,:,:,jpdic) - dicres) * tmask (:,:,:)
  770. trb(:,:,:,jpdic) = (trb(:,:,:,jpdic) - dicres) * tmask (:,:,:)
  771. dicmasstend = glob_sum( ( trn(:,:,:,jpdic) &
  772. & + trn(:,:,:,jpphy) + trn(:,:,:,jpdia) &
  773. & + trn(:,:,:,jpzoo) + trn(:,:,:,jpmes) &
  774. & + trn(:,:,:,jppoc) &
  775. & + trn(:,:,:,jpgoc) &
  776. & + trn(:,:,:,jpdoc) + trn(:,:,:,jpcal) ) * cvol(:,:,:) ) * 1.E3 ! mol C
  777. ! dicend = glob_sum( trn(:,:,:,jpdic) * cvol(:,:,:)) * 1.E3
  778. ! dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum - rivdicinput * 1.E3 )/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  779. ! dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum - riverdicsum )/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  780. dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum - sedrivdicsum)/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  781. WRITE(numout,*) 'dicmasstend (trn) after correction (mol C) =', dicmasstend
  782. ! WRITE(numout,*) 'dicend (trn) after correction (mol C) =', dicend
  783. WRITE(numout,*) 'dicres (trn) (mol C/l) as calculated here =', dicres
  784. dicmasstend = glob_sum( ( trb(:,:,:,jpdic) &
  785. & + trb(:,:,:,jpphy) + trb(:,:,:,jpdia) &
  786. & + trb(:,:,:,jpzoo) + trb(:,:,:,jpmes) &
  787. & + trb(:,:,:,jppoc) &
  788. & + trb(:,:,:,jpgoc) &
  789. & + trb(:,:,:,jpdoc) + trb(:,:,:,jpcal) ) * cvol(:,:,:) ) * 1.E3 ! mol C
  790. ! dicend = glob_sum( trb(:,:,:,jpdic) * cvol(:,:,:)) * 1.E3
  791. ! dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum - rivdicinput * 1.E3 )/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  792. ! dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum + zsedc_cum - riverdicsum)/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  793. dicres = (dicmasstend - dicmasst0 - t_oce_co2_flx_cum - sedrivdicsum)/(totvol * 1.E3) ! mol C/l (note: areatot is global volume (sic))
  794. WRITE(numout,*) 'dicmasstend (trb) after correction (mol C) =', dicmasstend
  795. ! WRITE(numout,*) 'dicend (trb) after correction (mol C) =', dicend
  796. WRITE(numout,*) 'dicres (trb) (mol C/l) as calculated here =', dicres
  797. END IF
  798. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  799. END SUBROUTINE trc_sms_cfix
  800. #else
  801. !!======================================================================
  802. !! Dummy module : No PISCES bio-model
  803. !!======================================================================
  804. CONTAINS
  805. SUBROUTINE p4z_sms( kt ) ! Empty routine
  806. INTEGER, INTENT( in ) :: kt
  807. WRITE(*,*) 'p4z_sms: You should not have seen this print! error?', kt
  808. END SUBROUTINE p4z_sms
  809. #endif
  810. !!======================================================================
  811. END MODULE p4zsms