p4zopt.F90 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. MODULE p4zopt
  2. !!======================================================================
  3. !! *** MODULE p4zopt ***
  4. !! TOP - PISCES : Compute the light availability in the water column
  5. !!======================================================================
  6. !! History : 1.0 ! 2004 (O. Aumont) Original code
  7. !! 2.0 ! 2007-12 (C. Ethe, G. Madec) F90
  8. !! 3.2 ! 2009-04 (C. Ethe, G. Madec) optimisation
  9. !! 3.4 ! 2011-06 (O. Aumont, C. Ethe) Improve light availability of nano & diat
  10. !!----------------------------------------------------------------------
  11. #if defined key_pisces
  12. !!----------------------------------------------------------------------
  13. !! 'key_pisces' PISCES bio-model
  14. !!----------------------------------------------------------------------
  15. !! p4z_opt : light availability in the water column
  16. !!----------------------------------------------------------------------
  17. USE trc ! tracer variables
  18. USE oce_trc ! tracer-ocean share variables
  19. USE sms_pisces ! Source Minus Sink of PISCES
  20. USE iom ! I/O manager
  21. USE fldread ! time interpolation
  22. USE prtctl_trc ! print control for debugging
  23. IMPLICIT NONE
  24. PRIVATE
  25. PUBLIC p4z_opt ! called in p4zbio.F90 module
  26. PUBLIC p4z_opt_init ! called in trcsms_pisces.F90 module
  27. PUBLIC p4z_opt_alloc
  28. !! * Shared module variables
  29. LOGICAL :: ln_varpar !: boolean for variable PAR fraction
  30. REAL(wp) :: parlux !: Fraction of shortwave as PAR
  31. REAL(wp) :: xparsw !: parlux/3
  32. REAL(wp) :: xsi0r !: 1. /rn_si0
  33. TYPE(FLD), ALLOCATABLE, DIMENSION(:) :: sf_par ! structure of input par
  34. INTEGER , PARAMETER :: nbtimes = 366 !: maximum number of times record in a file
  35. INTEGER :: ntimes_par ! number of time steps in a file
  36. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: par_varsw !: PAR fraction of shortwave
  37. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: enano, ediat !: PAR for phyto, nano and diat
  38. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: etot_ndcy !: PAR over 24h in case of diurnal cycle
  39. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: emoy !: averaged PAR in the mixed layer
  40. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: ekb, ekg, ekr !: wavelength (Red-Green-Blue)
  41. INTEGER :: nksrp ! levels below which the light cannot penetrate ( depth larger than 391 m)
  42. REAL(wp), DIMENSION(3,61), PUBLIC :: xkrgb !: tabulated attenuation coefficients for RGB absorption
  43. !!* Substitution
  44. # include "top_substitute.h90"
  45. !!----------------------------------------------------------------------
  46. !! NEMO/TOP 3.3 , NEMO Consortium (2010)
  47. !! $Id: p4zopt.F90 3160 2011-11-20 14:27:18Z cetlod $
  48. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  49. !!----------------------------------------------------------------------
  50. CONTAINS
  51. SUBROUTINE p4z_opt( kt, knt )
  52. !!---------------------------------------------------------------------
  53. !! *** ROUTINE p4z_opt ***
  54. !!
  55. !! ** Purpose : Compute the light availability in the water column
  56. !! depending on the depth and the chlorophyll concentration
  57. !!
  58. !! ** Method : - ???
  59. !!---------------------------------------------------------------------
  60. !
  61. INTEGER, INTENT(in) :: kt, knt ! ocean time step
  62. !
  63. INTEGER :: ji, jj, jk
  64. INTEGER :: irgb
  65. REAL(wp) :: zchl
  66. REAL(wp) :: zc0 , zc1 , zc2, zc3, z1_dep
  67. REAL(wp), POINTER, DIMENSION(:,: ) :: zdepmoy, zetmp1, zetmp2, zetmp3, zetmp4
  68. REAL(wp), POINTER, DIMENSION(:,: ) :: zqsr100, zqsr_corr
  69. REAL(wp), POINTER, DIMENSION(:,:,:) :: zpar, ze0, ze1, ze2, ze3
  70. !!---------------------------------------------------------------------
  71. !
  72. IF( nn_timing == 1 ) CALL timing_start('p4z_opt')
  73. !
  74. ! Allocate temporary workspace
  75. CALL wrk_alloc( jpi, jpj, zdepmoy, zetmp1, zetmp2, zetmp3, zetmp4 )
  76. CALL wrk_alloc( jpi, jpj, zqsr100, zqsr_corr )
  77. CALL wrk_alloc( jpi, jpj, jpk, zpar, ze0, ze1, ze2, ze3 )
  78. IF( knt == 1 .AND. ln_varpar ) CALL p4z_opt_sbc( kt )
  79. ! Initialisation of variables used to compute PAR
  80. ! -----------------------------------------------
  81. ze1(:,:,:) = 0._wp
  82. ze2(:,:,:) = 0._wp
  83. ze3(:,:,:) = 0._wp
  84. ! !* attenuation coef. function of Chlorophyll and wavelength (Red-Green-Blue)
  85. DO jk = 1, jpkm1 ! --------------------------------------------------------
  86. !CDIR NOVERRCHK
  87. DO jj = 1, jpj
  88. !CDIR NOVERRCHK
  89. DO ji = 1, jpi
  90. zchl = ( trb(ji,jj,jk,jpnch) + trb(ji,jj,jk,jpdch) + rtrn ) * 1.e6
  91. zchl = MIN( 10. , MAX( 0.05, zchl ) )
  92. irgb = NINT( 41 + 20.* LOG10( zchl ) + rtrn )
  93. !
  94. ekb(ji,jj,jk) = xkrgb(1,irgb) * fse3t(ji,jj,jk)
  95. ekg(ji,jj,jk) = xkrgb(2,irgb) * fse3t(ji,jj,jk)
  96. ekr(ji,jj,jk) = xkrgb(3,irgb) * fse3t(ji,jj,jk)
  97. END DO
  98. END DO
  99. END DO
  100. ! !* Photosynthetically Available Radiation (PAR)
  101. ! ! --------------------------------------
  102. IF( l_trcdm2dc ) THEN ! diurnal cycle
  103. !
  104. zqsr_corr(:,:) = qsr_mean(:,:) / ( 1. - fr_i(:,:) + rtrn )
  105. !
  106. CALL p4z_opt_par( kt, zqsr_corr, ze1, ze2, ze3, pqsr100 = zqsr100 )
  107. !
  108. DO jk = 1, nksrp
  109. etot_ndcy(:,:,jk) = ze1(:,:,jk) + ze2(:,:,jk) + ze3(:,:,jk)
  110. enano (:,:,jk) = 2.1 * ze1(:,:,jk) + 0.42 * ze2(:,:,jk) + 0.4 * ze3(:,:,jk)
  111. ediat (:,:,jk) = 1.6 * ze1(:,:,jk) + 0.69 * ze2(:,:,jk) + 0.7 * ze3(:,:,jk)
  112. END DO
  113. !
  114. zqsr_corr(:,:) = qsr(:,:) / ( 1. - fr_i(:,:) + rtrn )
  115. !
  116. CALL p4z_opt_par( kt, zqsr_corr, ze1, ze2, ze3 )
  117. !
  118. DO jk = 1, nksrp
  119. etot(:,:,jk) = ze1(:,:,jk) + ze2(:,:,jk) + ze3(:,:,jk)
  120. END DO
  121. !
  122. ELSE
  123. !
  124. zqsr_corr(:,:) = qsr(:,:) / ( 1. - fr_i(:,:) + rtrn )
  125. !
  126. CALL p4z_opt_par( kt, zqsr_corr, ze1, ze2, ze3, pqsr100 = zqsr100 )
  127. !
  128. DO jk = 1, nksrp
  129. etot (:,:,jk) = ze1(:,:,jk) + ze2(:,:,jk) + ze3(:,:,jk)
  130. enano(:,:,jk) = 2.1 * ze1(:,:,jk) + 0.42 * ze2(:,:,jk) + 0.4 * ze3(:,:,jk)
  131. ediat(:,:,jk) = 1.6 * ze1(:,:,jk) + 0.69 * ze2(:,:,jk) + 0.7 * ze3(:,:,jk)
  132. END DO
  133. etot_ndcy(:,:,:) = etot(:,:,:)
  134. ENDIF
  135. IF( ln_qsr_bio ) THEN !* heat flux accros w-level (used in the dynamics)
  136. ! ! ------------------------
  137. CALL p4z_opt_par( kt, qsr, ze1, ze2, ze3, pe0=ze0 )
  138. !
  139. etot3(:,:,1) = qsr(:,:) * tmask(:,:,1)
  140. DO jk = 2, nksrp + 1
  141. etot3(:,:,jk) = ( ze0(:,:,jk) + ze1(:,:,jk) + ze2(:,:,jk) + ze3(:,:,jk) ) * tmask(:,:,jk)
  142. END DO
  143. ! ! ------------------------
  144. ENDIF
  145. ! !* Euphotic depth and level
  146. neln(:,:) = 1 ! ------------------------
  147. heup(:,:) = 300.
  148. DO jk = 2, nksrp
  149. DO jj = 1, jpj
  150. DO ji = 1, jpi
  151. IF( etot_ndcy(ji,jj,jk) * tmask(ji,jj,jk) >= zqsr100(ji,jj) ) THEN
  152. neln(ji,jj) = jk+1 ! Euphotic level : 1rst T-level strictly below Euphotic layer
  153. ! ! nb: ensure the compatibility with nmld_trc definition in trd_mld_trc_zint
  154. heup(ji,jj) = fsdepw(ji,jj,jk+1) ! Euphotic layer depth
  155. ENDIF
  156. END DO
  157. END DO
  158. END DO
  159. !
  160. heup(:,:) = MIN( 300., heup(:,:) )
  161. ! !* mean light over the mixed layer
  162. zdepmoy(:,:) = 0.e0 ! -------------------------------
  163. zetmp1 (:,:) = 0.e0
  164. zetmp2 (:,:) = 0.e0
  165. zetmp3 (:,:) = 0.e0
  166. zetmp4 (:,:) = 0.e0
  167. DO jk = 1, nksrp
  168. !CDIR NOVERRCHK
  169. DO jj = 1, jpj
  170. !CDIR NOVERRCHK
  171. DO ji = 1, jpi
  172. IF( fsdepw(ji,jj,jk+1) <= hmld(ji,jj) ) THEN
  173. zetmp1 (ji,jj) = zetmp1 (ji,jj) + etot (ji,jj,jk) * fse3t(ji,jj,jk) ! remineralisation
  174. zetmp2 (ji,jj) = zetmp2 (ji,jj) + etot_ndcy(ji,jj,jk) * fse3t(ji,jj,jk) ! production
  175. zetmp3 (ji,jj) = zetmp3 (ji,jj) + enano (ji,jj,jk) * fse3t(ji,jj,jk) ! production
  176. zetmp4 (ji,jj) = zetmp4 (ji,jj) + ediat (ji,jj,jk) * fse3t(ji,jj,jk) ! production
  177. zdepmoy(ji,jj) = zdepmoy(ji,jj) + fse3t(ji,jj,jk)
  178. ENDIF
  179. END DO
  180. END DO
  181. END DO
  182. !
  183. emoy(:,:,:) = etot(:,:,:) ! remineralisation
  184. zpar(:,:,:) = etot_ndcy(:,:,:) ! diagnostic : PAR with no diurnal cycle
  185. !
  186. DO jk = 1, nksrp
  187. !CDIR NOVERRCHK
  188. DO jj = 1, jpj
  189. !CDIR NOVERRCHK
  190. DO ji = 1, jpi
  191. IF( fsdepw(ji,jj,jk+1) <= hmld(ji,jj) ) THEN
  192. z1_dep = 1. / ( zdepmoy(ji,jj) + rtrn )
  193. emoy (ji,jj,jk) = zetmp1(ji,jj) * z1_dep
  194. zpar (ji,jj,jk) = zetmp2(ji,jj) * z1_dep
  195. enano(ji,jj,jk) = zetmp3(ji,jj) * z1_dep
  196. ediat(ji,jj,jk) = zetmp4(ji,jj) * z1_dep
  197. ENDIF
  198. END DO
  199. END DO
  200. END DO
  201. !
  202. IF( lk_iomput ) THEN
  203. IF( knt == nrdttrc ) THEN
  204. IF( iom_use( "Heup" ) ) CALL iom_put( "Heup" , heup(:,: ) * tmask(:,:,1) ) ! euphotic layer deptht
  205. IF( iom_use( "PARDM" ) ) CALL iom_put( "PARDM", zpar(:,:,:) * tmask(:,:,:) ) ! Photosynthetically Available Radiation
  206. IF( iom_use( "PAR" ) ) CALL iom_put( "PAR" , emoy(:,:,:) * tmask(:,:,:) ) ! Photosynthetically Available Radiation
  207. ENDIF
  208. ELSE
  209. IF( ln_diatrc ) THEN ! save output diagnostics
  210. trc2d(:,:, jp_pcs0_2d + 10) = heup(:,: ) * tmask(:,:,1)
  211. trc3d(:,:,:,jp_pcs0_3d + 3) = etot(:,:,:) * tmask(:,:,:)
  212. ENDIF
  213. ENDIF
  214. !
  215. CALL wrk_dealloc( jpi, jpj, zdepmoy, zetmp1, zetmp2, zetmp3, zetmp4 )
  216. CALL wrk_dealloc( jpi, jpj, zqsr100, zqsr_corr )
  217. CALL wrk_dealloc( jpi, jpj, jpk, zpar, ze0, ze1, ze2, ze3 )
  218. !
  219. IF( nn_timing == 1 ) CALL timing_stop('p4z_opt')
  220. !
  221. END SUBROUTINE p4z_opt
  222. SUBROUTINE p4z_opt_par( kt, pqsr, pe1, pe2, pe3, pe0, pqsr100 )
  223. !!----------------------------------------------------------------------
  224. !! *** routine p4z_opt_par ***
  225. !!
  226. !! ** purpose : compute PAR of each wavelength (Red-Green-Blue)
  227. !! for a given shortwave radiation
  228. !!
  229. !!----------------------------------------------------------------------
  230. !! * arguments
  231. INTEGER, INTENT(in) :: kt ! ocean time-step
  232. REAL(wp), DIMENSION(jpi,jpj) , INTENT(in) :: pqsr ! shortwave
  233. REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) :: pe1 , pe2 , pe3 ! PAR ( R-G-B)
  234. REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout), OPTIONAL :: pe0
  235. REAL(wp), DIMENSION(jpi,jpj) , INTENT(out) , OPTIONAL :: pqsr100
  236. !! * local variables
  237. INTEGER :: ji, jj, jk ! dummy loop indices
  238. REAL(wp), DIMENSION(jpi,jpj) :: zqsr ! shortwave
  239. !!----------------------------------------------------------------------
  240. ! Real shortwave
  241. IF( ln_varpar ) THEN ; zqsr(:,:) = par_varsw(:,:) * pqsr(:,:)
  242. ELSE ; zqsr(:,:) = xparsw * pqsr(:,:)
  243. ENDIF
  244. ! Light at the euphotic depth
  245. IF( PRESENT( pqsr100 ) ) pqsr100(:,:) = 0.01 * 3. * zqsr(:,:)
  246. !
  247. IF( PRESENT( pe0 ) ) THEN ! W-level
  248. !
  249. pe0(:,:,1) = pqsr(:,:) - 3. * zqsr(:,:) ! ( 1 - 3 * alpha ) * q
  250. pe1(:,:,1) = zqsr(:,:)
  251. pe2(:,:,1) = zqsr(:,:)
  252. pe3(:,:,1) = zqsr(:,:)
  253. !
  254. DO jk = 2, nksrp + 1
  255. !CDIR NOVERRCHK
  256. DO jj = 1, jpj
  257. !CDIR NOVERRCHK
  258. DO ji = 1, jpi
  259. pe0(ji,jj,jk) = pe0(ji,jj,jk-1) * EXP( -fse3t(ji,jj,jk-1) * xsi0r )
  260. pe1(ji,jj,jk) = pe1(ji,jj,jk-1) * EXP( -ekb(ji,jj,jk-1 ) )
  261. pe2(ji,jj,jk) = pe2(ji,jj,jk-1) * EXP( -ekg(ji,jj,jk-1 ) )
  262. pe3(ji,jj,jk) = pe3(ji,jj,jk-1) * EXP( -ekr(ji,jj,jk-1 ) )
  263. END DO
  264. !
  265. END DO
  266. !
  267. END DO
  268. !
  269. ELSE ! T- level
  270. !
  271. pe1(:,:,1) = zqsr(:,:) * EXP( -0.5 * ekb(:,:,1) )
  272. pe2(:,:,1) = zqsr(:,:) * EXP( -0.5 * ekg(:,:,1) )
  273. pe3(:,:,1) = zqsr(:,:) * EXP( -0.5 * ekr(:,:,1) )
  274. !
  275. DO jk = 2, nksrp
  276. !CDIR NOVERRCHK
  277. DO jj = 1, jpj
  278. !CDIR NOVERRCHK
  279. DO ji = 1, jpi
  280. pe1(ji,jj,jk) = pe1(ji,jj,jk-1) * EXP( -0.5 * ( ekb(ji,jj,jk-1) + ekb(ji,jj,jk) ) )
  281. pe2(ji,jj,jk) = pe2(ji,jj,jk-1) * EXP( -0.5 * ( ekg(ji,jj,jk-1) + ekg(ji,jj,jk) ) )
  282. pe3(ji,jj,jk) = pe3(ji,jj,jk-1) * EXP( -0.5 * ( ekr(ji,jj,jk-1) + ekr(ji,jj,jk) ) )
  283. END DO
  284. END DO
  285. END DO
  286. !
  287. ENDIF
  288. !
  289. END SUBROUTINE p4z_opt_par
  290. SUBROUTINE p4z_opt_sbc( kt )
  291. !!----------------------------------------------------------------------
  292. !! *** routine p4z_opt_sbc ***
  293. !!
  294. !! ** purpose : read and interpolate the variable PAR fraction
  295. !! of shortwave radiation
  296. !!
  297. !! ** method : read the files and interpolate the appropriate variables
  298. !!
  299. !! ** input : external netcdf files
  300. !!
  301. !!----------------------------------------------------------------------
  302. !! * arguments
  303. INTEGER , INTENT(in) :: kt ! ocean time step
  304. !! * local declarations
  305. INTEGER :: ji,jj
  306. REAL(wp) :: zcoef
  307. !!---------------------------------------------------------------------
  308. !
  309. IF( nn_timing == 1 ) CALL timing_start('p4z_optsbc')
  310. !
  311. ! Compute par_varsw at nit000 or only if there is more than 1 time record in par coefficient file
  312. IF( ln_varpar ) THEN
  313. IF( kt == nit000 .OR. ( kt /= nit000 .AND. ntimes_par > 1 ) ) THEN
  314. CALL fld_read( kt, 1, sf_par )
  315. par_varsw(:,:) = ( sf_par(1)%fnow(:,:,1) ) / 3.0
  316. ENDIF
  317. ENDIF
  318. !
  319. IF( nn_timing == 1 ) CALL timing_stop('p4z_optsbc')
  320. !
  321. END SUBROUTINE p4z_opt_sbc
  322. SUBROUTINE p4z_opt_init
  323. !!----------------------------------------------------------------------
  324. !! *** ROUTINE p4z_opt_init ***
  325. !!
  326. !! ** Purpose : Initialization of tabulated attenuation coef
  327. !! and of the percentage of PAR in Shortwave
  328. !!
  329. !! ** Input : external ascii and netcdf files
  330. !!----------------------------------------------------------------------
  331. !
  332. INTEGER :: numpar
  333. INTEGER :: ierr
  334. INTEGER :: ios ! Local integer output status for namelist read
  335. REAL(wp), DIMENSION(nbtimes) :: zsteps ! times records
  336. !
  337. CHARACTER(len=100) :: cn_dir ! Root directory for location of ssr files
  338. TYPE(FLD_N) :: sn_par ! informations about the fields to be read
  339. !
  340. NAMELIST/nampisopt/cn_dir, sn_par, ln_varpar, parlux
  341. !!----------------------------------------------------------------------
  342. IF( nn_timing == 1 ) CALL timing_start('p4z_opt_init')
  343. REWIND( numnatp_ref ) ! Namelist nampisopt in reference namelist : Pisces attenuation coef. and PAR
  344. READ ( numnatp_ref, nampisopt, IOSTAT = ios, ERR = 901)
  345. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisopt in reference namelist', lwp )
  346. REWIND( numnatp_cfg ) ! Namelist nampisopt in configuration namelist : Pisces attenuation coef. and PAR
  347. READ ( numnatp_cfg, nampisopt, IOSTAT = ios, ERR = 902 )
  348. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nampisopt in configuration namelist', lwp )
  349. IF(lwm) WRITE ( numonp, nampisopt )
  350. IF(lwp) THEN
  351. WRITE(numout,*) ' '
  352. WRITE(numout,*) ' namelist : nampisopt '
  353. WRITE(numout,*) ' ~~~~~~~~~~~~~~~~~ '
  354. WRITE(numout,*) ' PAR as a variable fraction of SW ln_varpar = ', ln_varpar
  355. WRITE(numout,*) ' Default value for the PAR fraction parlux = ', parlux
  356. ENDIF
  357. !
  358. xparsw = parlux / 3.0
  359. xsi0r = 1.e0 / rn_si0
  360. !
  361. ! Variable PAR at the surface of the ocean
  362. ! ----------------------------------------
  363. IF( ln_varpar ) THEN
  364. IF(lwp) WRITE(numout,*) ' initialize variable par fraction '
  365. IF(lwp) WRITE(numout,*) ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
  366. !
  367. ALLOCATE( par_varsw(jpi,jpj) )
  368. !
  369. ALLOCATE( sf_par(1), STAT=ierr ) !* allocate and fill sf_sst (forcing structure) with sn_sst
  370. IF( ierr > 0 ) CALL ctl_stop( 'STOP', 'p4z_opt_init: unable to allocate sf_par structure' )
  371. !
  372. CALL fld_fill( sf_par, (/ sn_par /), cn_dir, 'p4z_opt_init', 'Variable PAR fraction ', 'nampisopt' )
  373. ALLOCATE( sf_par(1)%fnow(jpi,jpj,1) )
  374. IF( sn_par%ln_tint ) ALLOCATE( sf_par(1)%fdta(jpi,jpj,1,2) )
  375. CALL iom_open ( TRIM( sn_par%clname ) , numpar )
  376. CALL iom_gettime( numpar, zsteps, kntime=ntimes_par) ! get number of record in file
  377. ENDIF
  378. !
  379. CALL trc_oce_rgb( xkrgb ) ! tabulated attenuation coefficients
  380. nksrp = trc_oce_ext_lev( r_si2, 0.33e2 ) ! max level of light extinction (Blue Chl=0.01)
  381. !
  382. IF(lwp) WRITE(numout,*) ' level of light extinction = ', nksrp, ' ref depth = ', gdepw_1d(nksrp+1), ' m'
  383. !
  384. ekr (:,:,:) = 0._wp
  385. ekb (:,:,:) = 0._wp
  386. ekg (:,:,:) = 0._wp
  387. etot (:,:,:) = 0._wp
  388. etot_ndcy(:,:,:) = 0._wp
  389. enano (:,:,:) = 0._wp
  390. ediat (:,:,:) = 0._wp
  391. IF( ln_qsr_bio ) etot3 (:,:,:) = 0._wp
  392. !
  393. IF( nn_timing == 1 ) CALL timing_stop('p4z_opt_init')
  394. !
  395. END SUBROUTINE p4z_opt_init
  396. INTEGER FUNCTION p4z_opt_alloc()
  397. !!----------------------------------------------------------------------
  398. !! *** ROUTINE p4z_opt_alloc ***
  399. !!----------------------------------------------------------------------
  400. ALLOCATE( ekb(jpi,jpj,jpk) , ekr(jpi,jpj,jpk), ekg(jpi,jpj,jpk), &
  401. & enano(jpi,jpj,jpk) , ediat(jpi,jpj,jpk), &
  402. & etot_ndcy(jpi,jpj,jpk), emoy (jpi,jpj,jpk), STAT=p4z_opt_alloc )
  403. !
  404. IF( p4z_opt_alloc /= 0 ) CALL ctl_warn('p4z_opt_alloc : failed to allocate arrays.')
  405. !
  406. END FUNCTION p4z_opt_alloc
  407. #else
  408. !!----------------------------------------------------------------------
  409. !! Dummy module : No PISCES bio-model
  410. !!----------------------------------------------------------------------
  411. CONTAINS
  412. SUBROUTINE p4z_opt ! Empty routine
  413. END SUBROUTINE p4z_opt
  414. #endif
  415. !!======================================================================
  416. END MODULE p4zopt