New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
zdfmxl.F90 in branches/UKMO/r8395_mix-lyr_diag/NEMOGCM/NEMO/OPA_SRC/ZDF – NEMO

source: branches/UKMO/r8395_mix-lyr_diag/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfmxl.F90

Last change on this file was 11347, checked in by jcastill, 5 years ago

Remove outdated comment

File size: 27.2 KB
Line 
1MODULE zdfmxl
2   !!======================================================================
3   !!                       ***  MODULE  zdfmxl  ***
4   !! Ocean physics: mixed layer depth
5   !!======================================================================
6   !! History :  1.0  ! 2003-08  (G. Madec)  original code
7   !!            3.2  ! 2009-07  (S. Masson, G. Madec)  IOM + merge of DO-loop
8   !!            3.7  ! 2012-03  (G. Madec)  make public the density criteria for trdmxl
9   !!             -   ! 2014-02  (F. Roquet)  mixed layer depth calculated using N2 instead of rhop
10   !!----------------------------------------------------------------------
11   !!   zdf_mxl      : Compute the turbocline and mixed layer depths.
12   !!----------------------------------------------------------------------
13   USE oce             ! ocean dynamics and tracers variables
14   USE dom_oce         ! ocean space and time domain variables
15   USE trc_oce, ONLY: l_offline         ! ocean space and time domain variables
16   USE zdf_oce         ! ocean vertical physics
17   USE in_out_manager  ! I/O manager
18   USE prtctl          ! Print control
19   USE phycst          ! physical constants
20   USE iom             ! I/O library
21   USE eosbn2          ! for zdf_mxl_zint
22   USE lib_mpp         ! MPP library
23   USE wrk_nemo        ! work arrays
24   USE timing          ! Timing
25
26   IMPLICIT NONE
27   PRIVATE
28
29   PUBLIC   zdf_mxl_tref  ! called by asminc.F90
30   PUBLIC   zdf_mxl       ! called by step.F90
31
32   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hmld_tref  !: mixed layer depth at t-points - temperature criterion [m]
33   INTEGER , PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   nmln       !: number of level in the mixed layer (used by TOP)
34   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hmld       !: mixing layer depth (turbocline)      [m]
35   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hmlp       !: mixed layer depth  (rho=rho0+zdcrit) [m]
36   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) ::   hmlpt      !: depth of the last T-point inside the mixed layer [m]
37   REAL(wp), PUBLIC, ALLOCATABLE,       DIMENSION(:,:) ::   hmld_zint  !: vertically-interpolated mixed layer depth   [m] 
38   REAL(wp), PUBLIC, ALLOCATABLE,       DIMENSION(:,:) ::   htc_mld    ! Heat content of hmld_zint
39   LOGICAL, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)  ::   ll_found   ! Is T_b to be found by interpolation ? 
40   LOGICAL, PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)::   ll_belowml ! Flag points below mixed layer when ll_found=F
41
42   REAL(wp), PUBLIC ::   rho_c = 0.01_wp    !: density criterion for mixed layer depth
43   REAL(wp)         ::   avt_c = 5.e-4_wp   ! Kz criterion for the turbocline depth
44
45   TYPE, PUBLIC :: MXL_ZINT   !: Structure for MLD defs
46      INTEGER   :: mld_type   ! mixed layer type     
47      REAL(wp)  :: zref       ! depth of initial T_ref
48      REAL(wp)  :: dT_crit    ! Critical temp diff
49      REAL(wp)  :: iso_frac   ! Fraction of rn_dT_crit used
50   END TYPE MXL_ZINT
51
52!Used for 25h mean
53   LOGICAL, PRIVATE :: mld_25h_init = .TRUE.    !Logical used to initalise 25h
54                                                !outputs. Necessary, because we need to
55                                                !initalise the mld_25h on the zeroth
56                                                !timestep (i.e in the nemogcm_init call)
57   LOGICAL, PRIVATE :: mld_25h_write = .FALSE.  !Logical confirm 25h calculating/processing
58   INTEGER, SAVE :: i_cnt_25h                   ! Counter for 25 hour means
59   REAL(wp),SAVE, ALLOCATABLE, DIMENSION(:,:,:) :: hmld_zint_25h
60
61   !!----------------------------------------------------------------------
62   !! NEMO/OPA 4.0 , NEMO Consortium (2011)
63   !! $Id$
64   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
65   !!----------------------------------------------------------------------
66CONTAINS
67
68   INTEGER FUNCTION zdf_mxl_alloc()
69      !!----------------------------------------------------------------------
70      !!               ***  FUNCTION zdf_mxl_alloc  ***
71      !!----------------------------------------------------------------------
72      zdf_mxl_alloc = 0      ! set to zero if no array to be allocated
73      IF( .NOT. ALLOCATED( nmln ) ) THEN
74      ALLOCATE( nmln(jpi,jpj), hmld(jpi,jpj), hmlp(jpi,jpj), hmlpt(jpi,jpj), hmld_zint(jpi,jpj),       &
75     &          htc_mld(jpi,jpj),                                                                      &
76     &          ll_found(jpi,jpj), ll_belowml(jpi,jpj,jpk), STAT= zdf_mxl_alloc )
77         !
78         ALLOCATE(hmld_tref(jpi,jpj))
79         IF( lk_mpp             )   CALL mpp_sum ( zdf_mxl_alloc )
80         IF( zdf_mxl_alloc /= 0 )   CALL ctl_warn('zdf_mxl_alloc: failed to allocate arrays.')
81         !
82      ENDIF
83   END FUNCTION zdf_mxl_alloc
84
85   SUBROUTINE zdf_mxl_tref() 
86      !!---------------------------------------------------------------------- 
87      !!                  ***  ROUTINE zdf_mxl_tref  *** 
88      !!                     
89      !! ** Purpose :   Compute the mixed layer depth with temperature criteria. 
90      !! 
91      !! ** Method  :   The temperature-defined mixed layer depth is required 
92      !!                   when assimilating SST in a 2D analysis.   
93      !! 
94      !! ** Action  :   hmld_tref 
95      !!---------------------------------------------------------------------- 
96     
97      INTEGER  ::   ji, jj, jk   ! dummy loop indices 
98      REAL(wp) ::   t_ref               ! Reference temperature   
99      REAL(wp) ::   temp_c = 0.2        ! temperature criterion for mixed layer depth   
100      !!---------------------------------------------------------------------- 
101     
102      ! Initialise array 
103      IF( zdf_mxl_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_mxl_tref : unable to allocate arrays' ) 
104       
105      DO jj = 1, jpj   
106         DO ji = 1, jpi   
107           hmld_tref(ji,jj)=gdept_n(ji,jj,1  )     
108           IF(ssmask(ji,jj) > 0.)THEN   
109             t_ref=tsn(ji,jj,1,jp_tem)   
110             DO jk=2,jpk   
111               IF(ssmask(ji,jj)==0.)THEN   
112                  hmld_tref(ji,jj)=gdept_n(ji,jj,jk )   
113                  EXIT   
114               ELSEIF( ABS(tsn(ji,jj,jk,jp_tem)-t_ref) < temp_c)THEN   
115                  hmld_tref(ji,jj)=gdept_n(ji,jj,jk )   
116               ELSE   
117                  EXIT   
118               ENDIF   
119             ENDDO   
120           ENDIF   
121         ENDDO   
122      ENDDO 
123   
124   END SUBROUTINE zdf_mxl_tref
125
126   SUBROUTINE zdf_mxl( kt )
127      !!----------------------------------------------------------------------
128      !!                  ***  ROUTINE zdfmxl  ***
129      !!                   
130      !! ** Purpose :   Compute the turbocline depth and the mixed layer depth
131      !!              with density criteria.
132      !!
133      !! ** Method  :   The mixed layer depth is the shallowest W depth with
134      !!      the density of the corresponding T point (just bellow) bellow a
135      !!      given value defined locally as rho(10m) + rho_c
136      !!               The turbocline depth is the depth at which the vertical
137      !!      eddy diffusivity coefficient (resulting from the vertical physics
138      !!      alone, not the isopycnal part, see trazdf.F) fall below a given
139      !!      value defined locally (avt_c here taken equal to 5 cm/s2 by default)
140      !!
141      !! ** Action  :   nmln, hmld, hmlp, hmlpt
142      !!----------------------------------------------------------------------
143      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
144      !
145      INTEGER  ::   ji, jj, jk      ! dummy loop indices
146      INTEGER  ::   iikn, iiki, ikt ! local integer
147      REAL(wp) ::   zN2_c           ! local scalar
148      INTEGER, POINTER, DIMENSION(:,:) ::   imld   ! 2D workspace
149      !!----------------------------------------------------------------------
150      !
151      IF( nn_timing == 1 )  CALL timing_start('zdf_mxl')
152      !
153      CALL wrk_alloc( jpi,jpj, imld )
154
155      IF( kt == nit000 ) THEN
156         IF(lwp) WRITE(numout,*)
157         IF(lwp) WRITE(numout,*) 'zdf_mxl : mixed layer depth'
158         IF(lwp) WRITE(numout,*) '~~~~~~~ '
159         !                             ! allocate zdfmxl arrays
160         IF( zdf_mxl_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_mxl : unable to allocate arrays' )
161      ENDIF
162
163      ! w-level of the mixing and mixed layers
164      nmln(:,:)  = nlb10               ! Initialization to the number of w ocean point
165      hmlp(:,:)  = 0._wp               ! here hmlp used as a dummy variable, integrating vertically N^2
166      zN2_c = grav * rho_c * r1_rau0   ! convert density criteria into N^2 criteria
167      DO jk = nlb10, jpkm1
168         DO jj = 1, jpj                ! Mixed layer level: w-level
169            DO ji = 1, jpi
170               ikt = mbkt(ji,jj)
171               hmlp(ji,jj) = hmlp(ji,jj) + MAX( rn2b(ji,jj,jk) , 0._wp ) * e3w_n(ji,jj,jk)
172               IF( hmlp(ji,jj) < zN2_c )   nmln(ji,jj) = MIN( jk , ikt ) + 1   ! Mixed layer level
173            END DO
174         END DO
175      END DO
176      !
177      ! w-level of the turbocline and mixing layer (iom_use)
178      imld(:,:) = mbkt(:,:) + 1        ! Initialization to the number of w ocean point
179      DO jk = jpkm1, nlb10, -1         ! from the bottom to nlb10
180         DO jj = 1, jpj
181            DO ji = 1, jpi
182               IF( avt (ji,jj,jk) < avt_c * wmask(ji,jj,jk) )   imld(ji,jj) = jk      ! Turbocline
183            END DO
184         END DO
185      END DO
186      ! depth of the mixing and mixed layers
187      DO jj = 1, jpj
188         DO ji = 1, jpi
189            iiki = imld(ji,jj)
190            iikn = nmln(ji,jj)
191            hmld (ji,jj) = gdepw_n(ji,jj,iiki  ) * ssmask(ji,jj)    ! Turbocline depth
192            hmlp (ji,jj) = gdepw_n(ji,jj,iikn  ) * ssmask(ji,jj)    ! Mixed layer depth
193            hmlpt(ji,jj) = gdept_n(ji,jj,iikn-1) * ssmask(ji,jj)    ! depth of the last T-point inside the mixed layer
194         END DO
195      END DO
196      !
197      IF( .NOT.l_offline ) THEN
198         IF( iom_use("mldr10_1") ) THEN
199            IF( ln_isfcav ) THEN  ;  CALL iom_put( "mldr10_1", hmlp - risfdep)   ! mixed layer thickness
200            ELSE                  ;  CALL iom_put( "mldr10_1", hmlp )            ! mixed layer depth
201            END IF
202         END IF
203         IF( iom_use("mldkz5") ) THEN
204            IF( ln_isfcav ) THEN  ;  CALL iom_put( "mldkz5"  , hmld - risfdep )   ! turbocline thickness
205            ELSE                  ;  CALL iom_put( "mldkz5"  , hmld )             ! turbocline depth
206            END IF
207         ENDIF
208      ENDIF
209     
210      ! Vertically-interpolated mixed-layer depth diagnostic
211      CALL zdf_mxl_zint( kt ) 
212
213      IF(ln_ctl)   CALL prt_ctl( tab2d_1=REAL(nmln,wp), clinfo1=' nmln : ', tab2d_2=hmlp, clinfo2=' hmlp : ', ovlap=1 )
214      !
215      CALL wrk_dealloc( jpi,jpj, imld )
216      !
217      IF( nn_timing == 1 )  CALL timing_stop('zdf_mxl')
218      !
219   END SUBROUTINE zdf_mxl
220
221   SUBROUTINE zdf_mxl_zint_mld( sf ) 
222      !!---------------------------------------------------------------------------------- 
223      !!                    ***  ROUTINE zdf_mxl_zint_mld  *** 
224      !                                                                         
225      !   Calculate vertically-interpolated mixed layer depth diagnostic. 
226      !             
227      !   This routine can calculate the mixed layer depth diagnostic suggested by
228      !   Kara et al, 2000, JGR, 105, 16803, but is more general and can calculate
229      !   vertically-interpolated mixed-layer depth diagnostics with other parameter
230      !   settings set in the namzdf_mldzint namelist.   
231     
232      !   If mld_type=1 the mixed layer depth is calculated as the depth at which the   
233      !   density has increased by an amount equivalent to a temperature difference of   
234      !   0.8C at the surface. 
235     
236      !   For other values of mld_type the mixed layer is calculated as the depth at   
237      !   which the temperature differs by 0.8C from the surface temperature.   
238      !                                                                         
239      !   David Acreman, Daley Calvert                                       
240     
241      !!----------------------------------------------------------------------------------- 
242 
243      TYPE(MXL_ZINT), INTENT(in)  :: sf 
244 
245      ! Diagnostic criteria
246      INTEGER   :: nn_mld_type   ! mixed layer type     
247      REAL(wp)  :: rn_zref       ! depth of initial T_ref
248      REAL(wp)  :: rn_dT_crit    ! Critical temp diff
249      REAL(wp)  :: rn_iso_frac   ! Fraction of rn_dT_crit used
250 
251      ! Local variables
252      REAL(wp), PARAMETER :: zepsilon = 1.e-30          ! local small value
253      INTEGER, POINTER, DIMENSION(:,:) :: ik_ref        ! index of reference level 
254      INTEGER, POINTER, DIMENSION(:,:) :: ik_iso        ! index of last uniform temp level 
255      REAL, POINTER, DIMENSION(:,:,:)  :: zT            ! Temperature or density 
256      REAL, POINTER, DIMENSION(:,:)    :: ppzdep        ! depth for use in calculating d(rho) 
257      REAL, POINTER, DIMENSION(:,:)    :: zT_ref        ! reference temperature 
258      REAL    :: zT_b                                   ! base temperature 
259      REAL, POINTER, DIMENSION(:,:,:)  :: zdTdz         ! gradient of zT 
260      REAL, POINTER, DIMENSION(:,:,:)  :: zmoddT        ! Absolute temperature difference 
261      REAL    :: zdz                                    ! depth difference 
262      REAL    :: zdT                                    ! temperature difference 
263      REAL, POINTER, DIMENSION(:,:)    :: zdelta_T      ! difference critereon 
264      REAL, POINTER, DIMENSION(:,:)    :: zRHO1, zRHO2  ! Densities 
265      INTEGER :: ji, jj, jk                             ! loop counter 
266 
267      !!------------------------------------------------------------------------------------- 
268      !   
269      CALL wrk_alloc( jpi, jpj, ik_ref, ik_iso) 
270      CALL wrk_alloc( jpi, jpj, ppzdep, zT_ref, zdelta_T, zRHO1, zRHO2 ) 
271      CALL wrk_alloc( jpi, jpj, jpk, zT, zdTdz, zmoddT ) 
272 
273      ! Unpack structure
274      nn_mld_type = sf%mld_type 
275      rn_zref     = sf%zref 
276      rn_dT_crit  = sf%dT_crit 
277      rn_iso_frac = sf%iso_frac 
278 
279      ! Set the mixed layer depth criterion at each grid point 
280      IF( nn_mld_type == 0 ) THEN
281         zdelta_T(:,:) = rn_dT_crit 
282         zT(:,:,:) = rhop(:,:,:) 
283      ELSE IF( nn_mld_type == 1 ) THEN
284         ppzdep(:,:)=0.0 
285         call eos ( tsn(:,:,1,:), ppzdep(:,:), zRHO1(:,:) ) 
286! Use zT temporarily as a copy of tsn with rn_dT_crit added to SST 
287! [assumes number of tracers less than number of vertical levels] 
288         zT(:,:,1:jpts)=tsn(:,:,1,1:jpts) 
289         zT(:,:,jp_tem)=zT(:,:,1)+rn_dT_crit 
290         CALL eos( zT(:,:,1:jpts), ppzdep(:,:), zRHO2(:,:) ) 
291         zdelta_T(:,:) = abs( zRHO1(:,:) - zRHO2(:,:) ) * rau0 
292         ! RHO from eos (2d version) doesn't calculate north or east halo: 
293         CALL lbc_lnk( zdelta_T, 'T', 1. ) 
294         zT(:,:,:) = rhop(:,:,:) 
295      ELSE 
296         zdelta_T(:,:) = rn_dT_crit                       
297         zT(:,:,:) = tsn(:,:,:,jp_tem)                           
298      END IF 
299 
300      ! Calculate the gradient of zT and absolute difference for use later 
301      DO jk = 1 ,jpk-2 
302         zdTdz(:,:,jk)  =    ( zT(:,:,jk+1) - zT(:,:,jk) ) / e3w_n(:,:,jk+1) 
303         zmoddT(:,:,jk) = abs( zT(:,:,jk+1) - zT(:,:,jk) ) 
304      END DO 
305 
306      ! Find density/temperature at the reference level (Kara et al use 10m).           
307      ! ik_ref is the index of the box centre immediately above or at the reference level 
308      ! Find rn_zref in the array of model level depths and find the ref     
309      ! density/temperature by linear interpolation.                                   
310      DO jk = jpkm1, 2, -1 
311         WHERE ( gdept_n(:,:,jk) > rn_zref ) 
312           ik_ref(:,:) = jk - 1 
313           zT_ref(:,:) = zT(:,:,jk-1) + zdTdz(:,:,jk-1) * ( rn_zref - gdept_n(:,:,jk-1) ) 
314         END WHERE 
315      END DO 
316 
317      ! If the first grid box centre is below the reference level then use the 
318      ! top model level to get zT_ref 
319      WHERE ( gdept_n(:,:,1) > rn_zref )   
320         zT_ref = zT(:,:,1) 
321         ik_ref = 1 
322      END WHERE 
323 
324      ! Initialize / reset
325      ll_found(:,:) = .false. 
326 
327      IF ( rn_iso_frac - zepsilon > 0. ) THEN 
328         ! Search for a uniform density/temperature region where adjacent levels           
329         ! differ by less than rn_iso_frac * deltaT.                                       
330         ! ik_iso is the index of the last level in the uniform layer   
331         ! ll_found indicates whether the mixed layer depth can be found by interpolation 
332         ik_iso(:,:)   = ik_ref(:,:) 
333         DO jj = 1, nlcj 
334            DO ji = 1, nlci 
335!CDIR NOVECTOR 
336               DO jk = ik_ref(ji,jj), mbkt(ji,jj)-1 
337                  IF ( zmoddT(ji,jj,jk) > ( rn_iso_frac * zdelta_T(ji,jj) ) ) THEN 
338                     ik_iso(ji,jj)   = jk 
339                     ll_found(ji,jj) = ( zmoddT(ji,jj,jk) > zdelta_T(ji,jj) ) 
340                     EXIT 
341                  END IF 
342               END DO 
343            END DO 
344         END DO 
345 
346         ! Use linear interpolation to find depth of mixed layer base where possible 
347         hmld_zint(:,:) = rn_zref 
348         DO jj = 1, jpj 
349            DO ji = 1, jpi 
350               IF (ll_found(ji,jj) .and. tmask(ji,jj,1) == 1.0) THEN 
351                  zdz =  abs( zdelta_T(ji,jj) / zdTdz(ji,jj,ik_iso(ji,jj)) ) 
352                  hmld_zint(ji,jj) = gdept_n(ji,jj,ik_iso(ji,jj)) + zdz 
353               END IF 
354            END DO 
355         END DO 
356      END IF 
357 
358      ! If ll_found = .false. then calculate MLD using difference of zdelta_T     
359      ! from the reference density/temperature 
360 
361! Prevent this section from working on land points 
362      WHERE ( tmask(:,:,1) /= 1.0 ) 
363         ll_found = .true. 
364      END WHERE 
365 
366      DO jk=1, jpk 
367         ll_belowml(:,:,jk) = abs( zT(:,:,jk) - zT_ref(:,:) ) >= zdelta_T(:,:)   
368      END DO 
369 
370! Set default value where interpolation cannot be used (ll_found=false)   
371      DO jj = 1, jpj 
372         DO ji = 1, jpi 
373            IF ( .not. ll_found(ji,jj) )  hmld_zint(ji,jj) = gdept_n(ji,jj,mbkt(ji,jj)) 
374         END DO 
375      END DO 
376 
377      DO jj = 1, jpj 
378         DO ji = 1, jpi 
379!CDIR NOVECTOR 
380            DO jk = ik_ref(ji,jj)+1, mbkt(ji,jj) 
381               IF ( ll_found(ji,jj) ) EXIT 
382               IF ( ll_belowml(ji,jj,jk) ) THEN                 
383                  zT_b = zT_ref(ji,jj) + zdelta_T(ji,jj) * SIGN(1.0, zdTdz(ji,jj,jk-1) ) 
384                  zdT  = zT_b - zT(ji,jj,jk-1)                                       
385                  zdz  = zdT / zdTdz(ji,jj,jk-1)                                       
386                  hmld_zint(ji,jj) = gdept_n(ji,jj,jk-1) + zdz 
387                  EXIT                                                   
388               END IF 
389            END DO 
390         END DO 
391      END DO 
392 
393      hmld_zint(:,:) = hmld_zint(:,:)*tmask(:,:,1) 
394      !   
395      CALL wrk_dealloc( jpi, jpj, ik_ref, ik_iso) 
396      CALL wrk_dealloc( jpi, jpj, ppzdep, zT_ref, zdelta_T, zRHO1, zRHO2 ) 
397      CALL wrk_dealloc( jpi,jpj, jpk, zT, zdTdz, zmoddT ) 
398     
399   END SUBROUTINE zdf_mxl_zint_mld 
400 
401   SUBROUTINE zdf_mxl_zint_htc( kt ) 
402      !!----------------------------------------------------------------------
403      !!                  ***  ROUTINE zdf_mxl_zint_htc  ***
404      !! 
405      !! ** Purpose :   
406      !!
407      !! ** Method  :   
408      !!----------------------------------------------------------------------
409 
410      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
411 
412      INTEGER :: ji, jj, jk 
413      INTEGER :: ikmax 
414      REAL(wp) :: zc, zcoef 
415      !
416      INTEGER,  ALLOCATABLE, DIMENSION(:,:) ::   ilevel 
417      REAL(wp), ALLOCATABLE, DIMENSION(:,:) ::   zthick_0, zthick 
418 
419      !!----------------------------------------------------------------------
420 
421      IF( .NOT. ALLOCATED(ilevel) ) THEN
422         ALLOCATE( ilevel(jpi,jpj), zthick_0(jpi,jpj), & 
423         &         zthick(jpi,jpj), STAT=ji ) 
424         IF( lk_mpp  )   CALL mpp_sum(ji) 
425         IF( ji /= 0 )   CALL ctl_stop( 'STOP', 'zdf_mxl_zint_htc : unable to allocate arrays' ) 
426      ENDIF 
427 
428      ! Find last whole model T level above the MLD
429      ilevel(:,:)   = 0 
430      zthick_0(:,:) = 0._wp 
431 
432      DO jk = 1, jpkm1   
433         DO jj = 1, jpj 
434            DO ji = 1, jpi                     
435               zthick_0(ji,jj) = zthick_0(ji,jj) + e3t_n(ji,jj,jk) 
436               IF( zthick_0(ji,jj) < hmld_zint(ji,jj) ) ilevel(ji,jj) = jk 
437            END DO
438         END DO
439         WRITE(numout,*) 'zthick_0(jk =',jk,') =',zthick_0(2,2) 
440         WRITE(numout,*) 'gdepw_n(jk+1 =',jk+1,') =',gdepw_n(2,2,jk+1) 
441      END DO 
442 
443      ! Surface boundary condition
444      IF(.NOT.ln_linssh) THEN   ;   zthick(:,:) = 0._wp       ; htc_mld(:,:) = 0._wp                                   
445      ELSE                      ;   zthick(:,:) = sshn(:,:)   ; htc_mld(:,:) = tsn(:,:,1,jp_tem) * sshn(:,:) * tmask(:,:,1)   
446      ENDIF 
447 
448      ! Deepest whole T level above the MLD
449      ikmax = MIN( MAXVAL( ilevel(:,:) ), jpkm1 ) 
450 
451      ! Integration down to last whole model T level
452      DO jk = 1, ikmax 
453         DO jj = 1, jpj 
454            DO ji = 1, jpi 
455               zc = e3t_n(ji,jj,jk) * REAL( MIN( MAX( 0, ilevel(ji,jj) - jk + 1 ) , 1  )  )    ! 0 below ilevel
456               zthick(ji,jj) = zthick(ji,jj) + zc 
457               htc_mld(ji,jj) = htc_mld(ji,jj) + zc * tsn(ji,jj,jk,jp_tem) * tmask(ji,jj,jk) 
458            END DO
459         END DO
460      END DO 
461 
462      ! Subsequent partial T level
463      zthick(:,:) = hmld_zint(:,:) - zthick(:,:)   !   remaining thickness to reach MLD
464 
465      DO jj = 1, jpj 
466         DO ji = 1, jpi 
467            htc_mld(ji,jj) = htc_mld(ji,jj) + tsn(ji,jj,ilevel(ji,jj)+1,jp_tem)  & 
468      &                      * MIN( e3t_n(ji,jj,ilevel(ji,jj)+1), zthick(ji,jj) ) * tmask(ji,jj,ilevel(ji,jj)+1) 
469         END DO
470      END DO
471 
472      WRITE(numout,*) 'htc_mld(after) =',htc_mld(2,2) 
473 
474      ! Convert to heat content
475      zcoef = rau0 * rcp 
476      htc_mld(:,:) = zcoef * htc_mld(:,:) 
477 
478   END SUBROUTINE zdf_mxl_zint_htc 
479 
480   SUBROUTINE zdf_mxl_zint( kt ) 
481      !!----------------------------------------------------------------------
482      !!                  ***  ROUTINE zdf_mxl_zint  ***
483      !! 
484      !! ** Purpose :   
485      !!
486      !! ** Method  :   
487      !!----------------------------------------------------------------------
488 
489      INTEGER, INTENT(in) ::   kt   ! ocean time-step index
490 
491      INTEGER :: ios 
492      INTEGER :: jn 
493 
494      INTEGER :: nn_mld_diag = 0    ! number of diagnostics
495
496      INTEGER :: i_steps            ! no of timesteps per hour
497      INTEGER :: ierror             ! logical error message   
498
499      REAL(wp) :: zdt               ! timestep variable
500 
501      CHARACTER(len=1) :: cmld 
502 
503      TYPE(MXL_ZINT) :: sn_mld1, sn_mld2, sn_mld3, sn_mld4, sn_mld5 
504      TYPE(MXL_ZINT), SAVE, DIMENSION(5) ::   mld_diags 
505 
506      NAMELIST/namzdf_mldzint/ nn_mld_diag, sn_mld1, sn_mld2, sn_mld3, sn_mld4, sn_mld5 
507 
508      !!----------------------------------------------------------------------
509       
510      IF( kt == nit000 ) THEN
511         REWIND( numnam_ref )              ! Namelist namzdf_mldzint in reference namelist 
512         READ  ( numnam_ref, namzdf_mldzint, IOSTAT = ios, ERR = 901) 
513901      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_mldzint in reference namelist', lwp ) 
514 
515         REWIND( numnam_cfg )              ! Namelist namzdf_mldzint in configuration namelist 
516         READ  ( numnam_cfg, namzdf_mldzint, IOSTAT = ios, ERR = 902 ) 
517902      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_mldzint in configuration namelist', lwp ) 
518         IF(lwm) WRITE ( numond, namzdf_mldzint ) 
519 
520         IF( nn_mld_diag > 5 )   CALL ctl_stop( 'STOP', 'zdf_mxl_ini: Specify no more than 5 MLD definitions' ) 
521 
522         mld_diags(1) = sn_mld1 
523         mld_diags(2) = sn_mld2 
524         mld_diags(3) = sn_mld3 
525         mld_diags(4) = sn_mld4 
526         mld_diags(5) = sn_mld5 
527 
528         IF( nn_mld_diag > 0 ) THEN
529            WRITE(numout,*) '=============== Vertically-interpolated mixed layer ================' 
530            WRITE(numout,*) '(Diagnostic number, nn_mld_type, rn_zref, rn_dT_crit, rn_iso_frac)' 
531            DO jn = 1, nn_mld_diag 
532               WRITE(numout,*) 'MLD criterion',jn,':' 
533               WRITE(numout,*) '    nn_mld_type =', mld_diags(jn)%mld_type 
534               WRITE(numout,*) '    rn_zref ='    , mld_diags(jn)%zref 
535               WRITE(numout,*) '    rn_dT_crit =' , mld_diags(jn)%dT_crit 
536               WRITE(numout,*) '    rn_iso_frac =', mld_diags(jn)%iso_frac 
537            END DO
538            WRITE(numout,*) '====================================================================' 
539         ENDIF
540      ENDIF
541 
542      IF( nn_mld_diag > 0 ) THEN
543         DO jn = 1, nn_mld_diag 
544            WRITE(cmld,'(I1)') jn 
545            IF( iom_use( "mldzint_"//cmld ) .OR. iom_use( "mldhtc_"//cmld ) ) THEN
546               CALL zdf_mxl_zint_mld( mld_diags(jn) ) 
547 
548               IF( iom_use( "mldzint_"//cmld ) ) THEN
549                  CALL iom_put( "mldzint_"//cmld, hmld_zint(:,:) ) 
550               ENDIF
551 
552               IF( iom_use( "mldhtc_"//cmld ) )  THEN
553                  CALL zdf_mxl_zint_htc( kt ) 
554                  CALL iom_put( "mldhtc_"//cmld , htc_mld(:,:) ) 
555               ENDIF
556
557               IF( iom_use( "mldzint25h_"//cmld ) ) THEN
558                  IF( .NOT. mld_25h_write ) mld_25h_write = .TRUE. 
559                  zdt = rdt 
560                  IF( MOD( 3600,INT(zdt) ) == 0 ) THEN
561                     i_steps = 3600/INT(zdt) 
562                  ELSE
563                     CALL ctl_stop('STOP', 'zdf_mxl_zint 25h: timestep must give MOD(3600,rdt) = 0 otherwise no hourly values are possible') 
564                  ENDIF
565                  IF( ( mld_25h_init ) .OR. ( kt == nit000 ) ) THEN
566                     i_cnt_25h = 1 
567                     IF( .NOT. ALLOCATED(hmld_zint_25h) ) THEN
568                        ALLOCATE( hmld_zint_25h(jpi,jpj,nn_mld_diag), STAT=ierror ) 
569                        IF( ierror > 0 )  CALL ctl_stop( 'zdf_mxl_zint 25h: unable to allocate hmld_zint_25h' )   
570                     ENDIF
571                     hmld_zint_25h(:,:,jn) = hmld_zint(:,:) 
572                  ENDIF
573                  IF( MOD( kt, i_steps ) == 0 .AND.  kt .NE. nn_it000 ) THEN
574                     hmld_zint_25h(:,:,jn) = hmld_zint_25h(:,:,jn) + hmld_zint(:,:) 
575                  ENDIF
576                  IF( i_cnt_25h .EQ. 25 .AND.  MOD( kt, i_steps*24) == 0 .AND. kt .NE. nn_it000 ) THEN
577                     CALL iom_put( "mldzint25h_"//cmld , hmld_zint_25h(:,:,jn) / 25._wp   ) 
578                  ENDIF
579               ENDIF
580
581            ENDIF
582         END DO
583
584         IF(  mld_25h_write  ) THEN
585            IF( ( MOD( kt, i_steps ) == 0 ) .OR.  mld_25h_init ) THEN
586               IF (lwp) THEN
587                  WRITE(numout,*) 'zdf_mxl_zint (25h) : Summed the following number of hourly values so far',i_cnt_25h 
588          ENDIF
589               i_cnt_25h = i_cnt_25h + 1 
590               IF( mld_25h_init ) mld_25h_init = .FALSE. 
591            ENDIF
592            IF( i_cnt_25h .EQ. 25 .AND.  MOD( kt, i_steps*24) == 0 .AND. kt .NE. nn_it000 ) THEN
593               i_cnt_25h = 1 
594               DO jn = 1, nn_mld_diag 
595                     hmld_zint_25h(:,:,jn) = hmld_zint(:,:) 
596               ENDDO
597            ENDIF
598         ENDIF
599
600      ENDIF
601 
602   END SUBROUTINE zdf_mxl_zint
603
604   !!======================================================================
605END MODULE zdfmxl
Note: See TracBrowser for help on using the repository browser.