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.
zdfosm.F90 in NEMO/branches/2021/dev_r14122_HPC-08_Mueller_OSMOSIS_streamlining/src/OCE/ZDF – NEMO

source: NEMO/branches/2021/dev_r14122_HPC-08_Mueller_OSMOSIS_streamlining/src/OCE/ZDF/zdfosm.F90 @ 14802

Last change on this file since 14802 was 14802, checked in by smueller, 3 years ago

Upgrade of a range of local arrays to module arrays, various adjustments to improve compliance with coding conventions, and removal of unused variables (ticket #2353)

  • Property svn:keywords set to Id
File size: 235.7 KB
Line 
1MODULE zdfosm
2   !!======================================================================
3   !!                       ***  MODULE  zdfosm  ***
4   !! Ocean physics:  vertical mixing coefficient compute from the OSMOSIS
5   !!                 turbulent closure parameterization
6   !!=====================================================================
7   !!  History : NEMO 4.0  ! A. Grant, G. Nurser
8   !! 15/03/2017  Changed calculation of pycnocline thickness in unstable conditions and stable conditions AG
9   !! 15/03/2017  Calculation of pycnocline gradients for stable conditions changed. Pycnocline gradients now depend on stability of the OSBL. A.G
10   !! 06/06/2017  (1) Checks on sign of buoyancy jump in calculation of  OSBL depth.  A.G.
11   !!             (2) Removed variable zbrad0, zbradh and zbradav since they are not used.
12   !!             (3) Approximate treatment for shear turbulence.
13   !!                        Minimum values for zustar and zustke.
14   !!                        Add velocity scale, zvstr, that tends to zustar for large Langmuir numbers.
15   !!                        Limit maximum value for Langmuir number.
16   !!                        Use zvstr in definition of stability parameter zhol.
17   !!             (4) Modified parametrization of entrainment flux, changing original coefficient 0.0485 for Langmuir contribution to 0.135 * zla
18   !!             (5) For stable boundary layer add factor that depends on length of timestep to 'slow' collapse and growth. Make sure buoyancy jump not negative.
19   !!             (6) For unstable conditions when growth is over multiple levels, limit change to maximum of one level per cycle through loop.
20   !!             (7) Change lower limits for loops that calculate OSBL averages from 1 to 2. Large gradients between levels 1 and 2 can cause problems.
21   !!             (8) Change upper limits from ibld-1 to ibld.
22   !!             (9) Calculation of pycnocline thickness in unstable conditions. Check added to ensure that buoyancy jump is positive before calculating Ri.
23   !!            (10) Thickness of interface layer at base of the stable OSBL set by Richardson number. Gives continuity in transition from unstable OSBL.
24   !!            (11) Checks that buoyancy jump is poitive when calculating pycnocline profiles.
25   !!            (12) Replace zwstrl with zvstr in calculation of eddy viscosity.
26   !! 27/09/2017 (13) Calculate Stokes drift and Stokes penetration depth from wave information
27   !!            (14) Buoyancy flux due to entrainment changed to include contribution from shear turbulence.
28   !! 28/09/2017 (15) Calculation of Stokes drift moved into separate do-loops to allow for different options for the determining the Stokes drift to be added.
29   !!            (16) Calculation of Stokes drift from windspeed for PM spectrum (for testing, commented out)
30   !!            (17) Modification to Langmuir velocity scale to include effects due to the Stokes penetration depth (for testing, commented out)
31   !! ??/??/2018 (18) Revision to code structure, selected using key_osmldpth1. Inline code moved into subroutines. Changes to physics made,
32   !!                  (a) Pycnocline temperature and salinity profies changed for unstable layers
33   !!                  (b) The stable OSBL depth parametrization changed.
34   !! 16/05/2019 (19) Fox-Kemper parametrization of restratification through mixed layer eddies added to revised code.
35   !! 23/05/19   (20) Old code where key_osmldpth1` is *not* set removed, together with the key key_osmldpth1
36   !!----------------------------------------------------------------------
37
38   !!----------------------------------------------------------------------
39   !!   'ln_zdfosm'                                             OSMOSIS scheme
40   !!----------------------------------------------------------------------
41   !!   zdf_osm        : update momentum and tracer Kz from osm scheme
42   !!      zdf_osm_vertical_average             : compute vertical averages over boundary layers
43   !!      zdf_osm_velocity_rotation            : rotate velocity components
44   !!         zdf_osm_velocity_rotation_2d      :    rotation of 2d fields
45   !!         zdf_osm_velocity_rotation_3d      :    rotation of 3d fields
46   !!      zdf_osm_osbl_state                   : determine the state of the OSBL
47   !!      zdf_osm_external_gradients           : calculate gradients below the OSBL
48   !!      zdf_osm_calculate_dhdt               : calculate rate of change of hbl
49   !!      zdf_osm_timestep_hbl                 : hbl timestep
50   !!      zdf_osm_pycnocline_thickness         : calculate thickness of pycnocline
51   !!      zdf_osm_pycnocline_buoyancy_profiles : calculate pycnocline buoyancy profiles
52   !!      zdf_osm_diffusivity_viscosity        : compute eddy diffusivity and viscosity profiles
53   !!      zdf_osm_fgr_terms                    : compute flux-gradient relationship terms
54   !!      zdf_osm_zmld_horizontal_gradients    : calculate horizontal buoyancy gradients for use with Fox-Kemper parametrization
55   !!      zdf_osm_osbl_state_fk                : determine state of OSBL and MLE layers
56   !!      zdf_osm_mle_parameters               : timestep MLE depth and calculate MLE fluxes
57   !!   zdf_osm_init   : initialization, namelist read, and parameters control
58   !!      zdf_osm_alloc                        : memory allocation
59   !!   osm_rst        : read (or initialize) and write osmosis restart fields
60   !!   tra_osm        : compute and add to the T & S trend the non-local flux
61   !!   trc_osm        : compute and add to the passive tracer trend the non-local flux (TBD)
62   !!   dyn_osm        : compute and add to u & v trensd the non-local flux
63   !!----------------------------------------------------------------------
64   USE oce                                        ! Ocean dynamics and active tracers
65                                                  ! Uses ww from previous time step (which is now wb) to calculate hbl
66   USE dom_oce                                    ! Ocean space and time domain
67   USE zdf_oce                                    ! Ocean vertical physics
68   USE sbc_oce                                    ! Surface boundary condition: ocean
69   USE sbcwave                                    ! Surface wave parameters
70   USE phycst                                     ! Physical constants
71   USE eosbn2                                     ! Equation of state
72   USE traqsr                                     ! Details of solar radiation absorption
73   USE zdfdrg, ONLY : rCdU_bot                    ! Bottom friction velocity
74   USE zdfddm                                     ! Double diffusion mixing (avs array)
75   USE iom                                        ! I/O library
76   USE lib_mpp                                    ! MPP library
77   USE trd_oce                                    ! Ocean trends definition
78   USE trdtra                                     ! Tracers trends
79   USE in_out_manager                             ! I/O manager
80   USE lbclnk                                     ! Ocean lateral boundary conditions (or mpp link)
81   USE prtctl                                     ! Print control
82   USE lib_fortran                                ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
83   USE timing, ONLY : timing_start, timing_stop   ! Timer
84   !
85   IMPLICIT NONE
86   PRIVATE
87   !
88   ! Public subroutines
89   PUBLIC zdf_osm        ! Routine called by step.F90
90   PUBLIC zdf_osm_init   ! Routine called by nemogcm.F90
91   PUBLIC osm_rst        ! Routine called by step.F90
92   PUBLIC tra_osm        ! Routine called by step.F90
93   PUBLIC trc_osm        ! Routine called by trcstp.F90
94   PUBLIC dyn_osm        ! Routine called by step.F90
95   !
96   ! Public variables
97   LOGICAL,  PUBLIC                                      ::   ln_osm_mle   !: Flag to activate the Mixed Layer Eddy (MLE)
98   !                                                                       !     parameterisation, needed by tra_mle_init in
99   !                                                                       !     tramle.F90
100   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghamu        !: Non-local u-momentum flux
101   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghamv        !: Non-local v-momentum flux
102   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghamt        !: Non-local temperature flux (gamma/<ws>o)
103   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghams        !: Non-local salinity flux (gamma/<ws>o)
104   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hbl          !: Boundary layer depth
105   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hml          !: ML depth
106   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hmle         !: Depth of layer affexted by mixed layer eddies in Fox-Kemper parametrization
107   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dbdx_mle     !: Zonal buoyancy gradient in ML
108   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dbdy_mle     !: Meridional buoyancy gradient in ML
109   INTEGER,  PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   mld_prof     !: Level of base of MLE layer
110   !
111   INTERFACE zdf_osm_velocity_rotation
112      !!---------------------------------------------------------------------
113      !!              ***  INTERFACE zdf_velocity_rotation  ***
114      !!---------------------------------------------------------------------
115      MODULE PROCEDURE zdf_osm_velocity_rotation_2d
116      MODULE PROCEDURE zdf_osm_velocity_rotation_3d
117   END INTERFACE
118   !
119   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   etmean   ! Averaging operator for avt
120   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dh       ! Depth of pycnocline
121   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   r1_ft    ! Inverse of the modified Coriolis parameter at t-pts
122   !
123   ! Layer indices
124   INTEGER,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   nbld   ! Level of boundary layer base
125   INTEGER,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   nmld   ! Level of mixed-layer depth (pycnocline top)
126   !
127   ! Layer type
128   INTEGER,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   n_ddh   ! Type of shear layer
129   !                                                        !    n_ddh=0: active shear layer
130   !                                                        !    n_ddh=1: shear layer not active
131   !                                                        !    n_ddh=2: shear production low
132   !
133   ! Layer flags
134   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   l_conv    ! Unstable/stable bl
135   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   l_shear   ! Shear layers
136   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   l_coup    ! Coupling to bottom
137   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   l_pyc     ! OSBL pycnocline present
138   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   l_flux    ! Surface flux extends below OSBL into MLE layer
139   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:) ::   l_mle     ! MLE layer increases in hickness.
140   !
141   ! Scales
142   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swth0       ! Surface heat flux (Kinematic)
143   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sws0        ! Surface freshwater flux
144   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swb0        ! Surface buoyancy flux
145   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   suw0        ! Surface u-momentum flux
146   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sustar      ! Friction velocity
147   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   scos_wind   ! Cos angle of surface stress
148   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   ssin_wind   ! Sin angle of surface stress
149   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swthav      ! Heat flux - bl average
150   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swsav       ! Freshwater flux - bl average
151   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swbav       ! Buoyancy flux - bl average
152   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sustke      ! Surface Stokes drift
153   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   dstokes     ! Penetration depth of the Stokes drift
154   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swstrl      ! Langmuir velocity scale
155   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   swstrc      ! Convective velocity scale
156   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   sla         ! Trubulent Langmuir number
157   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   svstr       ! Velocity scale that tends to sustar for large Langmuir number
158   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   shol        ! Stability parameter for boundary layer
159   !
160   ! Layer averages: BL
161   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_t_bl   ! Temperature average
162   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_s_bl   ! Salinity average
163   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_u_bl   ! Velocity average (u)
164   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_v_bl   ! Velocity average (v)
165   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_b_bl   ! Buoyancy
166   !
167   ! Layer averages: ML
168   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_t_ml   ! Temperature average
169   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_s_ml   ! Salinity average
170   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_u_ml   ! Velocity average (u)
171   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_v_ml   ! Velocity average (v)
172   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_b_ml   ! Buoyancy
173   !
174   ! Layer averages: MLE
175   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_t_mle  ! Temperature average
176   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_s_mle  ! Salinity average
177   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_u_mle  ! Velocity average (u)
178   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_v_mle  ! Velocity average (v)
179   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) ::   av_b_mle  ! Buoyancy
180   !
181   !            ** Namelist  namzdf_osm  **
182   LOGICAL  ::   ln_use_osm_la                      ! Use namelist rn_osm_la
183   REAL(wp) ::   rn_osm_la                          ! Turbulent Langmuir number
184   REAL(wp) ::   rn_osm_dstokes                     ! Depth scale of Stokes drift
185   REAL(wp) ::   rn_zdfosm_adjust_sd   = 1.0_wp     ! Factor to reduce Stokes drift by
186   REAL(wp) ::   rn_osm_hblfrac        = 0.1_wp     ! For nn_osm_wave = 3/4 specify fraction in top of hbl
187   LOGICAL  ::   ln_zdfosm_ice_shelter              ! Flag to activate ice sheltering
188   REAL(wp) ::   rn_osm_hbl0           = 10.0_wp    ! Initial value of hbl for 1D runs
189   INTEGER  ::   nn_ave                             ! = 0/1 flag for horizontal average on avt
190   INTEGER  ::   nn_osm_wave = 0                    ! = 0/1/2 flag for getting stokes drift from La# / PM wind-waves/Inputs into
191   !                                                !    sbcwave
192   INTEGER  ::   nn_osm_SD_reduce                   ! = 0/1/2 flag for getting effective stokes drift from surface value
193   LOGICAL  ::   ln_dia_osm                         ! Use namelist  rn_osm_la
194   LOGICAL  ::   ln_dia_pyc_scl        = .FALSE.    ! Output of pycnocline scalar-gradient profiles
195   LOGICAL  ::   ln_dia_pyc_shr        = .FALSE.    ! Output of pycnocline velocity-shear  profiles
196   LOGICAL  ::   ln_kpprimix           = .TRUE.     ! Shear instability mixing
197   REAL(wp) ::   rn_riinfty            = 0.7_wp     ! Local Richardson Number limit for shear instability
198   REAL(wp) ::   rn_difri              = 0.005_wp   ! Maximum shear mixing at Rig = 0    (m2/s)
199   LOGICAL  ::   ln_convmix            = .TRUE.     ! Convective instability mixing
200   REAL(wp) ::   rn_difconv            = 1.0_wp     ! Diffusivity when unstable below BL  (m2/s)
201   !
202#ifdef key_osm_debug
203   INTEGER :: nn_idb = 297, nn_jdb = 193, nn_kdb = 35, nn_narea_db = 109
204   INTEGER :: iloc_db, jloc_db
205#endif
206   !
207   ! OSMOSIS mixed layer eddy parametrization constants
208   INTEGER  ::   nn_osm_mle          ! = 0/1 flag for horizontal average on avt
209   REAL(wp) ::   rn_osm_mle_ce       ! MLE coefficient
210   !   ! Parameters used in nn_osm_mle = 0 case
211   REAL(wp) ::   rn_osm_mle_lf       ! Typical scale of mixed layer front
212   REAL(wp) ::   rn_osm_mle_time     ! Time scale for mixing momentum across the mixed layer
213   !   ! Parameters used in nn_osm_mle = 1 case
214   REAL(wp) ::   rn_osm_mle_lat      ! Reference latitude for a 5 km scale of ML front
215   LOGICAL  ::   ln_osm_hmle_limit   ! If true arbitrarily restrict hmle to rn_osm_hmle_limit*zmld
216   REAL(wp) ::   rn_osm_hmle_limit   ! If ln_osm_hmle_limit true arbitrarily restrict hmle to rn_osm_hmle_limit*zmld
217   REAL(wp) ::   rn_osm_mle_rho_c    ! Density criterion for definition of MLD used by FK
218   REAL(wp) ::   rb_c                ! ML buoyancy criteria = g rho_c /rho0 where rho_c is defined in zdfmld
219   REAL(wp) ::   rc_f                ! MLE coefficient (= rn_ce / (5 km * fo) ) in nn_osm_mle=1 case
220   REAL(wp) ::   rn_osm_mle_thresh   ! Threshold buoyancy for deepening of MLE layer below OSBL base
221   REAL(wp) ::   rn_osm_bl_thresh    ! Threshold buoyancy for deepening of OSBL base
222   REAL(wp) ::   rn_osm_mle_tau      ! Adjustment timescale for MLE
223   !
224   !             ** General constants  **
225   REAL(wp) ::   epsln     = 1.0e-20_wp      ! A small positive number to ensure no div by zero
226   REAL(wp) ::   depth_tol = 1.0e-6_wp       ! A small-ish positive number to give a hbl slightly shallower than gdepw
227   REAL(wp) ::   pthird    = 1.0_wp/3.0_wp   ! 1/3
228   REAL(wp) ::   p2third   = 2.0_wp/3.0_wp   ! 2/3
229   !
230   !! * Substitutions
231#  include "do_loop_substitute.h90"
232#  include "domzgr_substitute.h90"
233   !!----------------------------------------------------------------------
234   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
235   !! $Id$
236   !! Software governed by the CeCILL license (see ./LICENSE)
237   !!----------------------------------------------------------------------
238CONTAINS
239
240   INTEGER FUNCTION zdf_osm_alloc()
241      !!----------------------------------------------------------------------
242      !!                 ***  FUNCTION zdf_osm_alloc  ***
243      !!----------------------------------------------------------------------
244      INTEGER ::   ierr
245      !
246      zdf_osm_alloc = 0
247      !
248      ALLOCATE( ghamu(jpi,jpj,jpk), ghamv(jpi,jpj,jpk), ghamt(jpi,jpj,jpk), ghams(jpi,jpj,jpk), hbl(jpi,jpj), hml(jpi,jpj),   &
249         &      hmle(jpi,jpj),      dbdx_mle(jpi,jpj),  dbdy_mle(jpi,jpj),  mld_prof(jpi,jpj),  STAT=ierr )
250      zdf_osm_alloc = zdf_osm_alloc + ierr
251      !
252      ALLOCATE( etmean(jpi,jpj,jpk), dh(jpi,jpj), r1_ft(jpi,jpj), STAT=ierr )
253      zdf_osm_alloc = zdf_osm_alloc + ierr
254      !
255      ALLOCATE( nbld(jpi,jpj), nmld(jpi,jpj), STAT=ierr )
256      zdf_osm_alloc = zdf_osm_alloc + ierr
257      !
258      ALLOCATE( n_ddh(jpi,jpj), STAT=ierr )
259      zdf_osm_alloc = zdf_osm_alloc + ierr
260      !
261      ALLOCATE( l_conv(jpi,jpj), l_shear(jpi,jpj), l_coup(jpi,jpj), l_pyc(jpi,jpj), l_flux(jpi,jpj), l_mle(jpi,jpj), STAT=ierr )
262      zdf_osm_alloc = zdf_osm_alloc + ierr
263      !
264      ALLOCATE( swth0(jpi,jpj),     sws0(jpi,jpj),   swb0(jpi,jpj),  suw0(jpi,jpj),  sustar(jpi,jpj), scos_wind(jpi,jpj),   &
265         &      ssin_wind(jpi,jpj), swthav(jpi,jpj), swsav(jpi,jpj), swbav(jpi,jpj), sustke(jpi,jpj), dstokes(jpi,jpj),     &
266         &      swstrl(jpi,jpj),    swstrc(jpi,jpj), sla(jpi,jpj),   svstr(jpi,jpj), shol(jpi,jpj),   STAT=ierr )
267      zdf_osm_alloc = zdf_osm_alloc + ierr
268      !
269      ALLOCATE( av_t_bl(jpi,jpj), av_s_bl(jpi,jpj), av_u_bl(jpi,jpj), av_v_bl(jpi,jpj), av_b_bl(jpi,jpj), STAT=ierr)
270      zdf_osm_alloc = zdf_osm_alloc + ierr
271      !
272      ALLOCATE( av_t_ml(jpi,jpj), av_s_ml(jpi,jpj), av_u_ml(jpi,jpj), av_v_ml(jpi,jpj), av_b_ml(jpi,jpj), STAT=ierr)
273      zdf_osm_alloc = zdf_osm_alloc + ierr
274      !
275      ALLOCATE( av_t_mle(jpi,jpj), av_s_mle(jpi,jpj), av_u_mle(jpi,jpj), av_v_mle(jpi,jpj), av_b_mle(jpi,jpj), STAT=ierr)
276      zdf_osm_alloc = zdf_osm_alloc + ierr
277      !
278      CALL mpp_sum ( 'zdfosm', zdf_osm_alloc )
279      IF( zdf_osm_alloc /= 0 ) CALL ctl_warn( 'zdf_osm_alloc: failed to allocate zdf_osm arrays' )
280      !
281   END FUNCTION zdf_osm_alloc
282
283   SUBROUTINE zdf_osm( kt, Kbb, Kmm, Krhs, p_avm,   &
284      &                p_avt )
285      !!----------------------------------------------------------------------
286      !!                   ***  ROUTINE zdf_osm  ***
287      !!
288      !! ** Purpose :   Compute the vertical eddy viscosity and diffusivity
289      !!      coefficients and non local mixing using the OSMOSIS scheme
290      !!
291      !! ** Method :   The boundary layer depth hosm is diagnosed at tracer points
292      !!      from profiles of buoyancy, and shear, and the surface forcing.
293      !!      Above hbl (sigma=-z/hbl <1) the mixing coefficients are computed from
294      !!
295      !!                      Kx =  hosm  Wx(sigma) G(sigma)
296      !!
297      !!             and the non local term ghamt = Cs / Ws(sigma) / hosm
298      !!      Below hosm  the coefficients are the sum of mixing due to internal waves
299      !!      shear instability and double diffusion.
300      !!
301      !!      -1- Compute the now interior vertical mixing coefficients at all depths.
302      !!      -2- Diagnose the boundary layer depth.
303      !!      -3- Compute the now boundary layer vertical mixing coefficients.
304      !!      -4- Compute the now vertical eddy vicosity and diffusivity.
305      !!      -5- Smoothing
306      !!
307      !!        N.B. The computation is done from jk=2 to jpkm1
308      !!             Surface value of avt are set once a time to zero
309      !!             in routine zdf_osm_init.
310      !!
311      !! ** Action  :   update the non-local terms ghamts
312      !!                update avt (before vertical eddy coef.)
313      !!
314      !! References : Large W.G., Mc Williams J.C. and Doney S.C.
315      !!         Reviews of Geophysics, 32, 4, November 1994
316      !!         Comments in the code refer to this paper, particularly
317      !!         the equation number. (LMD94, here after)
318      !!----------------------------------------------------------------------
319      INTEGER                   , INTENT(in   ) ::  kt               ! Ocean time step
320      INTEGER                   , INTENT(in   ) ::  Kbb, Kmm, Krhs   ! Ocean time level indices
321      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::  p_avm, p_avt     ! Momentum and tracer Kz (w-points)
322      !
323      ! Local variables
324      INTEGER ::   ji, jj, jk, jl, jm, jkflt   ! Dummy loop indices
325      !
326      REAL(wp) ::   zthermal, zbeta
327      REAL(wp) ::   zesh2, zri, zfri   ! Interior Richardson mixing
328      !
329      ! Scales
330      REAL(wp), DIMENSION(A2D(0))  ::   zrad0       ! Surface solar temperature flux (deg m/s)
331      REAL(wp), DIMENSION(A2D(0))  ::   zradh       ! Radiative flux at bl base (Buoyancy units)
332      REAL(wp)                     ::   zradav      ! Radiative flux, bl average (Buoyancy Units)
333      REAL(wp)                     ::   zvw0        ! Surface v-momentum flux
334      REAL(wp), DIMENSION(A2D(0))  ::   zwb0tot     ! Total surface buoyancy flux including insolation
335      REAL(wp), DIMENSION(jpi,jpj) ::   zwb_ent     ! Buoyancy entrainment flux
336      REAL(wp), DIMENSION(jpi,jpj) ::   zwb_min
337      REAL(wp), DIMENSION(jpi,jpj) ::   zwb_fk_b    ! MLE buoyancy flux averaged over OSBL
338      REAL(wp), DIMENSION(jpi,jpj) ::   zwb_fk      ! Max MLE buoyancy flux
339      REAL(wp), DIMENSION(jpi,jpj) ::   zdiff_mle   ! Extra MLE vertical diff
340      REAL(wp), DIMENSION(jpi,jpj) ::   zvel_mle    ! Velocity scale for dhdt with stable ML and FK
341      !
342      ! mixed-layer variables
343      INTEGER,  DIMENSION(jpi,jpj) ::   jp_ext   ! Offset for external level
344      !
345      REAL(wp), DIMENSION(jpi,jpj) ::   zhbl   ! BL depth - grid
346      REAL(wp), DIMENSION(jpi,jpj) ::   zhml   ! ML depth - grid
347      !
348      REAL(wp), DIMENSION(jpi,jpj) ::   zhmle   ! MLE depth - grid
349      REAL(wp), DIMENSION(jpi,jpj) ::   zmld   ! ML depth on grid
350      !
351      REAL(wp), DIMENSION(jpi,jpj) ::   zdh   ! Pycnocline depth - grid
352      REAL(wp), DIMENSION(A2D(0))  ::   zdhdt   ! BL depth tendency
353      REAL(wp), DIMENSION(A2D(0))  ::   zdtdz_bl_ext, zdsdz_bl_ext, zdbdz_bl_ext   ! External temperature/salinity and buoyancy gradients
354      REAL(wp), DIMENSION(jpi,jpj) ::   zdtdx, zdtdy, zdsdx, zdsdy   ! Horizontal gradients for Fox-Kemper parametrization.
355      !
356      REAL(wp), DIMENSION(jpi,jpj)     ::   zdt_bl,zds_bl,zdu_bl,zdv_bl,zdb_bl   ! Difference between blayer average and parameter at base of blayer
357      REAL(wp), DIMENSION(jpi,jpj)     ::   zdt_ml,zds_ml,zdu_ml,zdv_ml,zdb_ml   ! Difference between mixed layer average and parameter at base of blayer
358      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdbdz_pyc    ! parametrised gradient of buoyancy in the pycnocline
359      REAL(wp), DIMENSION(jpi,jpj)     ::   zdbds_mle    ! Magnitude of horizontal buoyancy gradient.
360      ! Flux-gradient relationship variables
361      REAL(wp), DIMENSION(jpi,jpj) ::   zshear   ! Shear production
362      !
363      REAL(wp), DIMENSION(jpi,jpj) ::   zhbl_t   ! Holds boundary layer depth updated by full timestep
364      !
365      ! For calculating Ri#-dependent mixing
366      REAL(wp), DIMENSION(jpi,jpj) ::   z2du     ! u-shear^2
367      REAL(wp), DIMENSION(jpi,jpj) ::   z2dv     ! v-shear^2
368      REAL(wp)                     ::   zrimix   ! Spatial form of ri#-induced diffusion
369      !
370      ! Temporary variables
371      REAL(wp)                         ::   znd   ! Temporary non-dimensional depth
372      REAL(wp)                         ::   zz0, zz1, zfac
373      REAL(wp)                         ::   zus_x, zus_y   ! Temporary Stokes drift
374      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zviscos   ! Viscosity
375      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zdiffut   ! t-diffusivity
376      REAL(wp), DIMENSION(jpi,jpj)     ::   zalpha_pyc
377      REAL(wp)                         ::   zabsstke
378      REAL(wp)                         ::   zsqrtpi, z_two_thirds, zthickness
379      REAL(wp)                         ::   z2k_times_thickness, zsqrt_depth, zexp_depth, zf, zexperfc
380      !
381      ! For debugging
382      REAL(wp), PARAMETER ::   pp_large = -1e10_wp
383      !
384      IF( ln_timing ) CALL timing_start('zdf_osm')
385      !
386      nbld(:,:)   = 0        ; nmld(:,:)  = 0
387      sustar(:,:) = pp_large
388      swstrl(:,:) = pp_large ; svstr(:,:)      = pp_large ; swstrc(:,:)     = pp_large ; suw0(:,:)      = pp_large
389      swth0(:,:)  = pp_large ; sws0(:,:)       = pp_large ; swb0(:,:)       = pp_large
390      swthav(:,:) = pp_large ; swsav(:,:)      = pp_large ; swbav(:,:)      = pp_large
391      sustke(:,:) = pp_large ; sla(:,:)        = pp_large ; scos_wind(:,:)  = pp_large ; ssin_wind(:,:) = pp_large
392      shol(:,:)   = pp_large ; zalpha_pyc(:,:) = pp_large
393      l_pyc(:,:)  = .FALSE.  ; l_flux(:,:)     = .FALSE.  ; l_mle(:,:)      = .FALSE.
394      ! Mixed layer
395      ! No initialization of zhbl or zhml (or zdh?)
396      zhbl(:,:)     = pp_large ; zhml(:,:)     = pp_large ; zdh(:,:)      = pp_large
397      av_t_bl(:,:)  = pp_large ; av_s_bl(:,:)  = pp_large ; av_u_bl(:,:)  = pp_large
398      av_v_bl(:,:)  = pp_large ; av_b_bl(:,:)  = pp_large ; av_t_ml(:,:)  = pp_large
399      av_s_ml(:,:)  = pp_large ; av_u_ml(:,:)  = pp_large ; av_v_ml(:,:)  = pp_large
400      av_b_ml(:,:)  = pp_large ; av_t_mle(:,:) = pp_large ; av_s_mle(:,:) = pp_large
401      av_u_mle(:,:) = pp_large ; av_v_mle(:,:) = pp_large ; av_b_mle(:,:) = pp_large
402      zdt_bl(:,:)   = pp_large ; zds_bl(:,:)   = pp_large ; zdu_bl(:,:)   = pp_large
403      zdv_bl(:,:)   = pp_large ; zdb_bl(:,:)   = pp_large ; zdt_ml(:,:)   = pp_large
404      zds_ml(:,:)   = pp_large ; zdu_ml(:,:)   = pp_large ; zdv_ml(:,:)   = pp_large
405      zdb_ml(:,:)   = pp_large
406      !
407      zdbdz_pyc(:,:,:)    = pp_large
408      zdbdz_pyc(A2D(0),:) = 0.0_wp
409      !
410      IF ( ln_osm_mle ) THEN   ! Only initialise arrays if needed
411         zdtdx(:,:)  = pp_large ; zdtdy(:,:)    = pp_large ; zdsdx(:,:)     = pp_large
412         zdsdy(:,:)  = pp_large ; dbdx_mle(:,:) = pp_large ; dbdy_mle(:,:)  = pp_large
413         zwb_fk(:,:) = pp_large ; zvel_mle(:,:) = pp_large ; zdiff_mle(:,:) = pp_large
414         zhmle(:,:)  = pp_large ; zmld(:,:)     = pp_large
415      ENDIF
416      zhbl_t(:,:)   = pp_large
417      !
418      zdiffut(:,:,:)    = pp_large ; zviscos(:,:,:)    = pp_large
419      zdiffut(A2D(0),:) = 0.0_wp   ; zviscos(A2D(0),:) = 0.0_wp
420      ghamt(:,:,:)      = pp_large ; ghams(:,:,:)      = pp_large
421      ghamt(A2D(0),:)   = 0.0_wp   ; ghams(A2D(0),:)   = 0.0_wp
422      ghamu(:,:,:)      = pp_large ; ghamv(:,:,:)      = pp_large
423      ghamu(A2D(0),:)   = 0.0_wp   ; ghamv(A2D(0),:)   = 0.0_wp
424      zdiff_mle(A2D(0)) = 0.0_wp
425      !
426#ifdef key_osm_debug
427      IF(mi0(nn_idb)==mi1(nn_idb) .AND. mj0(nn_jdb)==mj1(nn_jdb) .AND. &
428         & mi0(nn_idb) > 1 .AND. mi0(nn_idb) < jpi .AND. mj0(nn_jdb) > 1 .AND. mj0(nn_jdb) < jpj) THEN
429         nn_narea_db = narea
430         iloc_db=mi0(nn_idb); jloc_db=mj0(nn_jdb)
431         WRITE(narea+100,*)
432         WRITE(narea+100,'(a,i7)')'timestep=',kt
433         WRITE(narea+100,'(3(a,i7))')'narea=',narea,' nn_idb',nn_idb,' nn_jdb=',nn_jdb
434         WRITE(narea+100,'(4(a,i7))')'iloc_db=',iloc_db,' jloc_db',jloc_db,' jpi=',jpi,' jpj=',jpj 
435         ji=iloc_db; jj=jloc_db
436         WRITE(narea+100,'(a,i7,5(a,g10.2))')'mbkt=',mbkt(ji,jj),' ht_n',ht(ji,jj),&
437            &' hu_n-',hu(ji-1,jj,Kmm),' hu_n+',hu(ji,jj,Kmm), ' hv_n-',hv(ji,jj-1,Kmm),' hv_n+',hv(ji,jj,Kmm)
438         WRITE(narea+100,*)
439         FLUSH(narea+100)
440      ELSE
441         nn_narea_db = -1000
442      END IF
443#endif
444      !
445      ! hbl = MAX(hbl,epsln)
446      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
447      ! Calculate boundary layer scales
448      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
449      !
450      ! Turbulent surface fluxes and fluxes averaged over depth of the OSBL
451      zz0 =           rn_abs   ! Assume two-band radiation model for depth of OSBL - surface equi-partition in 2-bands
452      zz1 =  1.0_wp - rn_abs
453      DO_2D( 0, 0, 0, 0 )
454         zrad0(ji,jj)  = qsr(ji,jj) * r1_rho0_rcp   ! Surface downward irradiance (so always +ve)
455         zradh(ji,jj)  = zrad0(ji,jj) *                                &   ! Downwards irradiance at base of boundary layer
456            &            ( zz0 * EXP( -1.0_wp * hbl(ji,jj) / rn_si0 ) + zz1 * EXP( -1.0_wp * hbl(ji,jj) / rn_si1 ) )
457         zradav        = zrad0(ji,jj) *                                              &            ! Downwards irradiance averaged
458            &            ( zz0 * ( 1.0_wp - EXP( -hbl(ji,jj)/rn_si0 ) ) * rn_si0 +   &            !    over depth of the OSBL
459            &              zz1 * ( 1.0_wp - EXP( -hbl(ji,jj)/rn_si1 ) ) * rn_si1 ) / hbl(ji,jj)
460         swth0(ji,jj)  = - qns(ji,jj) * r1_rho0_rcp * tmask(ji,jj,1)   ! Upwards surface Temperature flux for non-local term
461         swthav(ji,jj) = 0.5_wp * swth0(ji,jj) - ( 0.5_wp * ( zrad0(ji,jj) + zradh(ji,jj) ) -   &   ! Turbulent heat flux averaged
462            &                                                 zradav )                              !    over depth of OSBL
463      END_2D
464      DO_2D( 0, 0, 0, 0 )
465         sws0(ji,jj)    = -1.0_wp * ( ( emp(ji,jj) - rnf(ji,jj) ) * ts(ji,jj,1,jp_sal,Kmm) +   &   ! Upwards surface salinity flux
466            &                         sfx(ji,jj) ) * r1_rho0 * tmask(ji,jj,1)                      !    for non-local term
467         zthermal       = rab_n(ji,jj,1,jp_tem)
468         zbeta          = rab_n(ji,jj,1,jp_sal)
469         swb0(ji,jj)    = grav * zthermal * swth0(ji,jj) - grav * zbeta * sws0(ji,jj)   ! Non radiative upwards surface buoyancy flux
470         zwb0tot(ji,jj) = swb0(ji,jj) - grav * zthermal * ( zrad0(ji,jj) - zradh(ji,jj) )   ! Total upwards surface buoyancy flux
471         swsav(ji,jj)   = 0.5_wp * sws0(ji,jj)                              ! Turbulent salinity flux averaged over depth of the OBSL
472         swbav(ji,jj)   = grav  * zthermal * swthav(ji,jj) -            &   ! Turbulent buoyancy flux averaged over the depth of the
473            &             grav  * zbeta * swsav(ji,jj)                      ! OBSBL
474      END_2D
475      DO_2D( 0, 0, 0, 0 )
476         suw0(ji,jj)    = -0.5_wp * (utau(ji-1,jj) + utau(ji,jj)) * r1_rho0 * tmask(ji,jj,1)   ! Surface upward velocity fluxes
477         zvw0           = -0.5_wp * (vtau(ji,jj-1) + vtau(ji,jj)) * r1_rho0 * tmask(ji,jj,1)
478         sustar(ji,jj)  = MAX( SQRT( SQRT( suw0(ji,jj) * suw0(ji,jj) + zvw0 * zvw0 ) ),   &   ! Friction velocity (sustar), at
479            &                  1e-8_wp )                                                      !    T-point : LMD94 eq. 2
480         scos_wind(ji,jj) = -1.0_wp * suw0(ji,jj) / ( sustar(ji,jj) * sustar(ji,jj) )
481         ssin_wind(ji,jj) = -1.0_wp * zvw0        / ( sustar(ji,jj) * sustar(ji,jj) )
482#ifdef key_osm_debug
483         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
484            zthermal = rab_n(ji,jj,1,jp_tem)
485            zbeta    = rab_n(ji,jj,1,jp_sal)
486            zradav   = zrad0(ji,jj) * ( zz0 * ( 1.0_wp - EXP( -hbl(ji,jj)/rn_si0 ) ) * rn_si0 +   &
487               &                        zz1 * ( 1.0_wp - EXP( -hbl(ji,jj)/rn_si1 ) ) * rn_si1 ) / hbl(ji,jj)
488            WRITE(narea+100,'(4(3(a,g11.3),/), 2(a,g11.3),/)') &
489               & 'after calculating fluxes:  hbl=', hbl(ji,jj),' zthermal=',zthermal, ' zbeta=', zbeta,&
490               & ' zrad0=', zrad0(ji,jj),' zradh=', zradh(ji,jj), ' zradav=', zradav,                  &
491               & ' swth0=', swth0(ji,jj), '  swthav=', swthav(ji,jj), ' sws0=', sws0(ji,jj),           &
492               & ' swb0=', swb0(ji,jj), ' zwb0tot=', zwb0tot(ji,jj), ' zwb0tot_in hbl=', zwb0tot(ji,jj) + grav * zthermal * zradh(ji,jj),&
493               & ' swbav=', swbav(ji,jj)
494            FLUSH(narea+100)
495         END IF
496#endif
497      END_2D
498      ! Calculate Stokes drift in direction of wind (sustke) and Stokes penetration depth (dstokes)
499      SELECT CASE (nn_osm_wave)
500         ! Assume constant La#=0.3
501      CASE(0)
502         DO_2D( 0, 0, 0, 0 )
503            zus_x = scos_wind(ji,jj) * sustar(ji,jj) / 0.3_wp**2
504            zus_y = ssin_wind(ji,jj) * sustar(ji,jj) / 0.3_wp**2
505            ! Linearly
506            sustke(ji,jj)  = MAX( SQRT( zus_x * zus_x + zus_y * zus_y ), 1e-8_wp )
507            dstokes(ji,jj) = rn_osm_dstokes
508         END_2D
509         ! Assume Pierson-Moskovitz wind-wave spectrum
510      CASE(1)
511         DO_2D( 0, 0, 0, 0 )
512            ! Use wind speed wndm included in sbc_oce module
513            sustke(ji,jj)  = MAX ( 0.016_wp * wndm(ji,jj), 1e-8_wp )
514            dstokes(ji,jj) = MAX ( 0.12_wp * wndm(ji,jj)**2 / grav, 5e-1_wp )
515         END_2D
516         ! Use ECMWF wave fields as output from SBCWAVE
517      CASE(2)
518         zfac =  2.0_wp * rpi / 16.0_wp
519         !
520         DO_2D( 0, 0, 0, 0 )
521            IF ( hsw(ji,jj) > 1e-4_wp ) THEN
522               ! Use  wave fields
523               zabsstke = SQRT( ut0sd(ji,jj)**2 + vt0sd(ji,jj)**2 )
524               sustke(ji,jj)  = MAX( ( scos_wind(ji,jj) * ut0sd(ji,jj) + ssin_wind(ji,jj)  * vt0sd(ji,jj) ), 1e-8_wp )
525               dstokes(ji,jj) = MAX( zfac * hsw(ji,jj) * hsw(ji,jj) / ( MAX( zabsstke * wmp(ji,jj), 1e-7 ) ), 5e-1_wp )
526            ELSE
527               ! Assume masking issue (e.g. ice in ECMWF reanalysis but not in model run)
528               ! .. so default to Pierson-Moskowitz
529               sustke(ji,jj)  = MAX( 0.016_wp * wndm(ji,jj), 1e-8_wp )
530               dstokes(ji,jj) = MAX( 0.12_wp * wndm(ji,jj)**2 / grav, 5e-1_wp )
531            END IF
532         END_2D
533      END SELECT
534#ifdef key_osm_debug
535      IF(narea==nn_narea_db)THEN
536         WRITE(narea+100,'(2(a,g11.3))') &
537            & 'Before reduction:  sustke=', sustke(iloc_db,jloc_db),' dstokes =',dstokes(iloc_db,jloc_db)
538         FLUSH(narea+100)
539      END IF
540#endif
541      !
542      IF (ln_zdfosm_ice_shelter) THEN
543         ! Reduce both Stokes drift and its depth scale by ocean fraction to represent sheltering by ice
544         DO_2D( 0, 0, 0, 0 )
545            sustke(ji,jj)  = sustke(ji,jj)  * ( 1.0_wp - fr_i(ji,jj) )
546            dstokes(ji,jj) = dstokes(ji,jj) * ( 1.0_wp - fr_i(ji,jj) )
547         END_2D
548      END IF
549      !
550      SELECT CASE (nn_osm_SD_reduce)
551         ! Reduce surface Stokes drift by a constant factor or following Breivik (2016) + van Roekel (2012) or Grant (2020).
552      CASE(0)
553         ! The Langmur number from the ECMWF model (or from PM) appears to give La<0.3 for wind-driven seas.
554         ! The coefficient rn_zdfosm_adjust_sd = 0.8 gives La=0.3 in this situation.
555         ! It could represent the effects of the spread of wave directions around the mean wind. The effect of this adjustment needs to be tested.
556         IF(nn_osm_wave > 0) THEN
557            sustke(A2D(0)) = rn_zdfosm_adjust_sd * sustke(A2D(0))
558         END IF
559      CASE(1)
560         ! Van Roekel (2012): consider average SD over top 10% of boundary layer
561         ! Assumes approximate depth profile of SD from Breivik (2016)
562         zsqrtpi = SQRT(rpi)
563         z_two_thirds = 2.0_wp / 3.0_wp
564         DO_2D( 0, 0, 0, 0 )
565            zthickness = rn_osm_hblfrac*hbl(ji,jj)
566            z2k_times_thickness =  zthickness * 2.0_wp / MAX( ABS( 5.97_wp * dstokes(ji,jj) ), 1e-7_wp )
567            zsqrt_depth = SQRT( z2k_times_thickness )
568            zexp_depth  = EXP( -1.0_wp * z2k_times_thickness )
569            sustke(ji,jj) = sustke(ji,jj) * ( 1.0_wp - zexp_depth -   &
570               &                              z_two_thirds * ( zsqrtpi * zsqrt_depth * z2k_times_thickness * ERFC(zsqrt_depth) +   &
571               &                                               1.0_wp - ( 1.0_wp + z2k_times_thickness ) * zexp_depth ) ) /        &
572               &            z2k_times_thickness
573         END_2D
574      CASE(2)
575         ! Grant (2020): Match to exponential with same SD and d/dz(Sd) at depth 10% of boundary layer
576         ! Assumes approximate depth profile of SD from Breivik (2016)
577         zsqrtpi = SQRT(rpi)
578         DO_2D( 0, 0, 0, 0 )
579            zthickness = rn_osm_hblfrac*hbl(ji,jj)
580            z2k_times_thickness =  zthickness * 2.0_wp / MAX( ABS( 5.97_wp * dstokes(ji,jj) ), 1e-7_wp )
581            IF( z2k_times_thickness < 50.0_wp ) THEN
582               zsqrt_depth = SQRT( z2k_times_thickness )
583               zexperfc    = zsqrtpi * zsqrt_depth * ERFC(zsqrt_depth) * EXP( z2k_times_thickness )
584            ELSE
585               ! Asymptotic expansion of sqrt(pi)*zsqrt_depth*EXP(z2k_times_thickness)*ERFC(zsqrt_depth) for large z2k_times_thickness
586               ! See Abramowitz and Stegun, Eq. 7.1.23
587               ! zexperfc = 1._wp - (1/2)/(z2k_times_thickness) + (3/4)/(z2k_times_thickness**2) - (15/8)/(z2k_times_thickness**3)
588               zexperfc = ( ( -1.875_wp / z2k_times_thickness + 0.75_wp ) / z2k_times_thickness - 0.5_wp ) /   &
589                  &       z2k_times_thickness + 1.0_wp
590            END IF
591            zf = z2k_times_thickness * ( 1.0_wp / zexperfc - 1.0_wp )
592            dstokes(ji,jj) = 5.97_wp * zf * dstokes(ji,jj)
593            sustke(ji,jj)  = sustke(ji,jj) * EXP( z2k_times_thickness * ( 1.0_wp / ( 2.0_wp * zf ) - 1.0_wp ) ) *   &
594               &             ( 1.0_wp - zexperfc )
595         END_2D
596      END SELECT
597      !
598      ! Langmuir velocity scale (swstrl), La # (sla)
599      ! Mixed scale (svstr), convective velocity scale (swstrc)
600      DO_2D( 0, 0, 0, 0 )
601         ! Langmuir velocity scale (swstrl), at T-point
602         swstrl(ji,jj) = ( sustar(ji,jj) * sustar(ji,jj) * sustke(ji,jj) )**pthird
603         sla(ji,jj)    = MAX( MIN( SQRT( sustar(ji,jj) / ( swstrl(ji,jj) + epsln ) )**3, 4.0_wp ), 0.2_wp )
604         IF ( sla(ji,jj) > 0.45_wp ) dstokes(ji,jj) = MIN( dstokes(ji,jj), 0.5_wp * hbl(ji,jj) )
605         ! Velocity scale that tends to sustar for large Langmuir numbers
606         svstr(ji,jj) = ( swstrl(ji,jj)**3 + ( 1.0_wp - EXP( -0.5_wp * sla(ji,jj)**2 ) ) * sustar(ji,jj) * sustar(ji,jj) *   &
607            &                                sustar(ji,jj) )**pthird
608         !
609         ! Limit maximum value of Langmuir number as approximate treatment for shear turbulence
610         ! Note sustke and swstrl are not amended
611         !
612         ! Get convective velocity (swstrc), stabilty scale (shol) and logical conection flag l_conv
613         IF ( swbav(ji,jj) > 0.0_wp ) THEN
614            swstrc(ji,jj) = ( 2.0_wp * swbav(ji,jj) * 0.9_wp * hbl(ji,jj) )**pthird
615            shol(ji,jj)   = -0.9_wp * hbl(ji,jj) * 2.0_wp * swbav(ji,jj) / ( svstr(ji,jj)**3 + epsln )
616         ELSE
617            swstrc(ji,jj) = 0.0_wp
618            shol(ji,jj)   = -1.0_wp * hbl(ji,jj) * 2.0_wp * swbav(ji,jj) / ( svstr(ji,jj)**3  + epsln )
619         ENDIF
620#ifdef key_osm_debug
621         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
622            WRITE(narea+100,'(2(a,g11.3),/,3(a,g11.3),/,3(a,g11.3),/)') &
623               & 'After reduction: sustke=', sustke(ji,jj), ' dstokes=', dstokes(ji,jj), &
624               & ' zustar =', sustar(ji,jj), ' swstrl=', swstrl(ji,jj), ' swstrc=', swstrc(ji,jj),&
625               & ' shol=', shol(ji,jj), ' sla=', sla(ji,jj), ' svstr=', svstr(ji,jj)
626            FLUSH(narea+100)
627         END IF
628#endif
629      END_2D
630      !
631      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
632      ! Mixed-layer model - calculate averages over the boundary layer, and the change in the boundary layer depth
633      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
634      ! BL must be always 4 levels deep.
635      ! For calculation of lateral buoyancy gradients for FK in
636      ! zdf_osm_zmld_horizontal_gradients need halo values for nbld, so must
637      ! previously exist for hbl also.
638      !
639      ! agn 23/6/20: not clear all this is needed, as hbl checked after it is re-calculated anyway
640      ! ##########################################################################
641      hbl(:,:) = MAX(hbl(:,:), gdepw(:,:,4,Kmm) )
642      nbld(:,:) = 4
643      DO_3D( 1, 1, 1, 1, 5, jpkm1 )
644         IF ( hbl(ji,jj) >= gdepw(ji,jj,jk,Kmm) ) THEN
645            nbld(ji,jj) = MIN(mbkt(ji,jj)-2, jk)
646         ENDIF
647      END_3D
648      ! ##########################################################################
649      !
650      DO_2D( 0, 0, 0, 0 )
651         zhbl(ji,jj) = gdepw(ji,jj,nbld(ji,jj),Kmm)
652         nmld(ji,jj) = MAX( 3, nbld(ji,jj) - MAX( INT( dh(ji,jj) / e3t(ji,jj,nbld(ji,jj)-1,Kmm) ), 1 ) )
653         zhml(ji,jj) = gdepw(ji,jj,nmld(ji,jj),Kmm)
654         zdh(ji,jj) = zhbl(ji,jj) - zhml(ji,jj)
655      END_2D
656#ifdef key_osm_debug
657      IF(narea==nn_narea_db) THEN
658         ji=iloc_db; jj=jloc_db
659         WRITE(narea+100,'(2(a,g11.3),/,3(a,g11.3),/,2(a,i7),/)') &
660            & 'Before updating hbl: hbl=', hbl(ji,jj), ' dh=', dh(ji,jj), &
661            &' zhbl =',zhbl(ji,jj) , ' zhml=', zhml(ji,jj), ' zdh=', zdh(ji,jj),&
662            &' imld=', nmld(ji,jj), ' ibld=', nbld(ji,jj)
663         WRITE(narea+100,'(a,g11.3,a,2g11.3)') 'Physics: ssh ',ssh(ji,jj,Kmm),' T S surface=',ts(ji,jj,1,jp_tem,Kmm),ts(ji,jj,1,jp_sal,Kmm)
664         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
665         WRITE(narea+100,'(a,*(g11.3))') ' T[imld-1..ibld+2] =', ( ts(ji,jj,jk,jp_tem,Kmm), jk=jl,jm )
666         WRITE(narea+100,'(a,*(g11.3))') ' S[imld-1..ibld+2] =', ( ts(ji,jj,jk,jp_sal,Kmm), jk=jl,jm )
667         WRITE(narea+100,'(a,*(g11.3))') ' U+[imld-1..ibld+2] =', ( uu(ji,jj,jk,Kmm), jk=jl,jm )
668         WRITE(narea+100,'(a,*(g11.3))') ' U-[imld-1..ibld+2] =', ( uu(ji-1,jj,jk,Kmm), jk=jl,jm )
669         WRITE(narea+100,'(a,*(g11.3))') ' V+[imld-1..ibld+2] =', ( vv(ji,jj,jk,Kmm), jk=jl,jm )
670         WRITE(narea+100,'(a,*(g11.3))') ' V-[imld-1..ibld+2] =', ( vv(ji,jj-1,jk,Kmm), jk=jl,jm )
671         WRITE(narea+100,'(a,*(g11.3))') ' W[imld-1..ibld+2] =', ( ww(ji,jj-1,jk), jk=jl,jm )
672         WRITE(narea+100,*)
673         FLUSH(narea+100)
674      END IF
675#endif
676      !
677      ! Averages over well-mixed and boundary layer, note BL averages use jp_ext=2 everywhere
678      jp_ext(:,:) = 1   ! ag 19/03
679      CALL zdf_osm_vertical_average( Kbb, Kmm, nbld, av_t_bl, av_s_bl,   &
680         &                           av_b_bl, av_u_bl, av_v_bl, jp_ext, zdt_bl,  &
681         &                           zds_bl, zdb_bl, zdu_bl, zdv_bl )
682      jp_ext(:,:) = nbld(:,:) - nmld(:,:) + jp_ext(:,:) + 1   ! ag 19/03
683      CALL zdf_osm_vertical_average( Kbb, Kmm, nmld - 1, av_t_ml, av_s_ml,    &
684         &                           av_b_ml, av_u_ml, av_v_ml, jp_ext, zdt_ml,   &
685         &                           zds_ml, zdb_ml, zdu_ml, zdv_ml )
686#ifdef key_osm_debug
687      IF(narea==nn_narea_db) THEN
688         ji=iloc_db; jj=jloc_db
689         WRITE(narea+100,'(4(3(a,g11.3),/), 2(4(a,g11.3),/))') &
690            & 'After averaging, with old hbl (& jp_ext==2), hml: zt_bl=', av_t_bl(ji,jj),&
691            & ' zs_bl=', av_s_bl(ji,jj),  ' zb_bl=', av_b_bl(ji,jj),&
692            & 'zdt_bl=', zdt_bl(ji,jj), ' zds_bl=', zds_bl(ji,jj),  ' zdb_bl=', zdb_bl(ji,jj),&
693            & 'zt_ml=', av_t_ml(ji,jj), ' zs_ml=', av_s_ml(ji,jj),  ' zb_ml=', av_b_ml(ji,jj),&
694            & 'zdt_ml=', zdt_ml(ji,jj), ' zds_ml=', zds_ml(ji,jj),  ' zdb_ml=', zdb_ml(ji,jj),&
695            & 'zu_bl =', av_u_bl(ji,jj) , ' zv_bl=', av_v_bl(ji,jj), ' zdu_bl=', zdu_bl(ji,jj), ' zdv_bl=', zdv_bl(ji,jj),&
696            & 'zu_ml =', av_u_ml(ji,jj) , ' zv_ml=', av_v_ml(ji,jj), ' zdu_ml=', zdu_ml(ji,jj), ' zdv_ml=', zdv_ml(ji,jj)
697         FLUSH(narea+100)
698      END IF
699#endif
700      ! Velocity components in frame aligned with surface stress
701      CALL zdf_osm_velocity_rotation( av_u_ml, av_v_ml  )
702      CALL zdf_osm_velocity_rotation( zdu_ml, zdv_ml )
703      CALL zdf_osm_velocity_rotation( av_u_bl, av_v_bl  )
704      CALL zdf_osm_velocity_rotation( zdu_bl, zdv_bl )
705#ifdef key_osm_debug
706      IF(narea==nn_narea_db) THEN
707         ji=iloc_db; jj=jloc_db
708         WRITE(narea+100,'(a,/, 2(4(a,g11.3),/))') &
709            & 'After rotation, with old hbl (& jp_ext==2), hml:', &
710            & 'zu_bl =', av_u_bl(ji,jj) , ' zv_bl=', av_v_bl(ji,jj), ' zdu_bl=', zdu_bl(ji,jj), ' zdv_bl=', zdv_bl(ji,jj),&
711            & 'zu_ml =', av_u_ml(ji,jj) , ' zv_ml=', av_v_ml(ji,jj), ' zdu_ml=', zdu_ml(ji,jj), ' zdv_ml=', zdv_ml(ji,jj)
712         FLUSH(narea+100)
713      END IF
714#endif
715      !
716      ! Determine the state of the OSBL, stable/unstable, shear/no shear
717      CALL zdf_osm_osbl_state( Kmm,    zwb_ent, zwb_min, zshear, zhbl,     &
718         &                     zhml,   zdh,     zdb_bl,  zdu_bl, zdv_bl,   &
719         &                     zdb_ml, zdu_ml,  zdv_ml )
720      !
721#ifdef key_osm_debug
722      IF(narea==nn_narea_db) THEN
723         ji=iloc_db; jj=jloc_db
724         WRITE(narea+100,'(2(a,l7),a, i7,/,3(a,g11.3),/)') &
725            & 'After zdf_osm_osbl_state: lconv=', l_conv(ji,jj), ' lshear=', l_shear(ji,jj),  ' j_ddh=', n_ddh(ji,jj),&
726            & 'zwb_ent=', zwb_ent(ji,jj), ' zwb_min=', zwb_min(ji,jj),  ' zshear=', zshear(ji,jj)
727         FLUSH(narea+100)
728      END IF
729#endif
730      IF ( ln_osm_mle ) THEN
731         ! Fox-Kemper Scheme
732         mld_prof = 4
733         DO_3D( 0, 0, 0, 0, 5, jpkm1 )
734            IF ( hmle(ji,jj) >= gdepw(ji,jj,jk,Kmm) ) mld_prof(ji,jj) = MIN(mbkt(ji,jj), jk)
735         END_3D
736         CALL zdf_osm_vertical_average( Kbb, Kmm, mld_prof, av_t_mle, av_s_mle,   &
737            &                           av_b_mle, av_u_mle, av_v_mle )
738         !
739         DO_2D( 0, 0, 0, 0 )
740            zhmle(ji,jj) = gdepw(ji,jj,mld_prof(ji,jj),Kmm)
741         END_2D
742#ifdef key_osm_debug
743         IF(narea==nn_narea_db) THEN
744            ji=iloc_db; jj=jloc_db
745            WRITE(narea+100,'(2(a,g11.3), a, i7,/,(3(a,g11.3),/),2(a,g11.3),/)') &
746               & 'Before updating hmle: hmle =',hmle(ji,jj) , ' zhmle=', zhmle(ji,jj), ' mld_prof=', mld_prof(ji,jj), &
747               & 'averaging over hmle: zt_mle=', av_t_mle(ji,jj), ' zs_mle=', av_s_mle(ji,jj),  ' zb_mle=', av_b_mle(ji,jj),&
748               & 'zu_mle =', av_u_mle(ji,jj), ' zv_mle=', av_v_mle(ji,jj)
749            FLUSH(narea+100)
750         END IF
751#endif
752         !
753         ! Calculate fairly-well-mixed depth zmld & its index mld_prof + lateral zmld-averaged gradients
754         CALL zdf_osm_zmld_horizontal_gradients( Kmm, zmld, zdtdx, zdtdy, zdsdx,   &
755            &                                    zdsdy, dbdx_mle, dbdy_mle, zdbds_mle )
756         ! Calculate max vertical FK flux zwb_fk & set logical descriptors
757         CALL zdf_osm_osbl_state_fk( Kmm, zwb_fk, zhbl, zhmle, zwb_ent,   &
758            &                        zdb_bl, zdbds_mle )
759         ! Recalculate hmle, zmle, zvel_mle, zdiff_mle & redefine mld_proc to be index for new hmle
760         CALL zdf_osm_mle_parameters( Kmm, mld_prof, zmld, zhmle, zvel_mle,   &
761            &                         zdiff_mle, zdbds_mle, zhbl, zwb0tot )
762#ifdef key_osm_debug
763         IF(narea==nn_narea_db) THEN
764            ji=iloc_db; jj=jloc_db
765            WRITE(narea+100,'(a,g11.3,a,i7,/, 2(4(a,g11.3),/),2(a,g11.3),/,2(3(a,g11.3),/),a,i7,2(a,g11.3),/,3(a,g11.3),/,/)') &
766               & 'Before updating hmle: zmld =',zmld(ji,jj),' mld_prof=', mld_prof(ji,jj), &
767               & 'zdtdx+=', zdtdx(ji,jj),' zdtdx-=', zdtdx(ji-1,jj),' zdsdx+=', zdsdx(ji,jj),' zdsdx-=',zdsdx(ji-1,jj), &
768               & 'zdtdy+=', zdtdy(ji,jj),' zdtdy-=', zdtdy(ji,jj-1),' zdsdy+=', zdsdy(ji,jj),' zdsdy-=',zdsdy(ji,jj-1), &
769               & 'dbdx_mle+=', dbdx_mle(ji,jj),' dbdx_mle-=', dbdx_mle(ji-1,jj),&
770               & 'dbdy_mle+=', dbdy_mle(ji,jj),' dbdy_mle-=',dbdy_mle(ji,jj-1),' zdbds_mle=',zdbds_mle(ji,jj), &
771               & 'After updating hmle: mld_prof=', mld_prof(ji,jj),' hmle=', hmle(ji,jj), ' zhmle=', zhmle(ji,jj),&
772               & 'zvel_mle =', zvel_mle(ji,jj), ' zdiff_mle=', zdiff_mle(ji,jj), ' zwb_fk=', zwb_fk(ji,jj)
773            FLUSH(narea+100)
774         END IF
775#endif
776      ELSE    ! ln_osm_mle
777         ! FK not selected, Boundary Layer only.
778         l_pyc(:,:)  = .TRUE.
779         l_flux(:,:) = .FALSE.
780         l_mle(:,:)  = .FALSE.
781         DO_2D( 0, 0, 0, 0 )
782            IF ( l_conv(ji,jj) .AND. zdb_bl(ji,jj) < rn_osm_bl_thresh ) l_pyc(ji,jj) = .FALSE.
783         END_2D
784      ENDIF   ! ln_osm_mle
785      !
786      !! External gradient below BL needed both with and w/o FK
787      CALL zdf_osm_external_gradients( Kmm, nbld + 1, zdtdz_bl_ext, zdsdz_bl_ext, zdbdz_bl_ext )   ! ag 19/03
788      !
789      ! Test if pycnocline well resolved
790      !      DO_2D( 0, 0, 0, 0 )                                         Removed with ag 19/03 changes. A change in eddy diffusivity/viscosity
791      !         IF (l_conv(ji,jj) ) THEN                                  should account for this.
792      !            ztmp = 0.2 * zhbl(ji,jj) / e3w(ji,jj,nbld(ji,jj),Kmm)
793      !            IF ( ztmp > 6 ) THEN
794      !               ! pycnocline well resolved
795      !               jp_ext(ji,jj) = 1
796      !            ELSE
797      !               ! pycnocline poorly resolved
798      !               jp_ext(ji,jj) = 0
799      !            ENDIF
800      !         ELSE
801      !            ! Stable conditions
802      !            jp_ext(ji,jj) = 0
803      !         ENDIF
804      !      END_2D
805#ifdef key_osm_debug
806      IF(narea==nn_narea_db) THEN
807         ji=iloc_db; jj=jloc_db
808         WRITE(narea+100,'(4(a,l7),a,i7,/, 3(a,g11.3),/)') &
809            & 'BL logical descriptors: lconv =',l_conv(ji,jj),' lpyc=', l_pyc(ji,jj),' lflux=', l_flux(ji,jj),' lmle=', l_mle(ji,jj),&
810            & ' jp_ext=', jp_ext(ji,jj), &
811            & 'sub-BL strat: zdtdz_bl_ext=', zdtdz_bl_ext(ji,jj),' zdsdz_bl_ext=', zdsdz_bl_ext(ji,jj),' zdbdz_bl_ext=', zdbdz_bl_ext(ji,jj)
812         FLUSH(narea+100)
813      END IF
814#endif
815      !
816      ! Recalculate bl averages using jp_ext & ml averages .... note no rotation of u & v here..
817      jp_ext(:,:) = 1   ! ag 19/03
818      CALL zdf_osm_vertical_average( Kbb, Kmm, nbld, av_t_bl, av_s_bl,    &
819         &                           av_b_bl, av_u_bl, av_v_bl, jp_ext, zdt_bl,   &
820         &                           zds_bl, zdb_bl, zdu_bl, zdv_bl )
821      jp_ext(:,:) = nbld(:,:) - nmld(:,:) + jp_ext(:,:) + 1   ! ag 19/03
822      CALL zdf_osm_vertical_average( Kbb, Kmm, nmld - 1, av_t_ml, av_s_ml,    &
823         &                           av_b_ml, av_u_ml, av_v_ml, jp_ext, zdt_ml,   &
824         &                           zds_ml, zdb_ml, zdu_ml, zdv_ml )   ! ag 19/03
825#ifdef key_osm_debug
826      IF(narea==nn_narea_db) THEN
827         ji=iloc_db; jj=jloc_db
828         WRITE(narea+100,'(4(3(a,g11.3),/), 2(4(a,g11.3),/))') &
829            & 'After averaging, with old hbl (&correct jp_ext), hml: zt_bl=', av_t_bl(ji,jj),&
830            & ' zs_bl=', av_s_bl(ji,jj),  ' zb_bl=', av_b_bl(ji,jj),&
831            & 'zdt_bl=', zdt_bl(ji,jj), ' zds_bl=', zds_bl(ji,jj),  ' zdb_bl=', zdb_bl(ji,jj),&
832            & 'zt_ml=', av_t_ml(ji,jj), ' zs_ml=', av_s_ml(ji,jj),  ' zb_ml=', av_b_ml(ji,jj),&
833            & 'zdt_ml=', zdt_ml(ji,jj), ' zds_ml=', zds_ml(ji,jj),  ' zdb_ml=', zdb_ml(ji,jj),&
834            & 'zu_bl =', av_u_bl(ji,jj) , ' zv_bl=', av_v_bl(ji,jj), ' zdu_bl=', zdu_bl(ji,jj), ' zdv_bl=', zdv_bl(ji,jj),&
835            & 'zu_ml =', av_u_ml(ji,jj) , ' zv_ml=', av_v_ml(ji,jj), ' zdu_ml=', zdu_ml(ji,jj), ' zdv_ml=', zdv_ml(ji,jj)
836         FLUSH(narea+100)
837      END IF
838#endif
839      !
840      ! Rate of change of hbl
841      CALL zdf_osm_calculate_dhdt( zdhdt, zhbl, zdh, zwb_ent, zwb_min,               &
842         &                         zdb_bl, zdbdz_bl_ext, zdb_ml, zwb_fk_b, zwb_fk,   &
843         &                         zvel_mle )
844      ! Test if surface boundary layer coupled to bottom
845      l_coup(:,:) = .FALSE.   ! ag 19/03
846      DO_2D( 0, 0, 0, 0 )
847         zhbl_t(ji,jj) = hbl(ji,jj) + ( zdhdt(ji,jj) - ww(ji,jj,nbld(ji,jj)) ) * rn_Dt   ! Certainly need ww here, so subtract it
848         ! Adjustment to represent limiting by ocean bottom
849         IF ( mbkt(ji,jj) > 2 ) THEN   ! To ensure mbkt(ji,jj) - 2 > 0 so no incorrect array access
850            IF ( zhbl_t(ji,jj) > gdepw(ji, jj,mbkt(ji,jj)-2,Kmm) ) THEN
851               zhbl_t(ji,jj) = MIN( zhbl_t(ji,jj), gdepw(ji,jj,mbkt(ji,jj)-2,Kmm) )   ! ht(:,:))
852               l_pyc(ji,jj)  = .FALSE.
853               l_coup(ji,jj) = .TRUE.   ! ag 19/03
854            END IF
855         END IF
856#ifdef key_osm_debug
857         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
858            WRITE(narea+100,'(2(a,g11.3),/,2(a,g11.3)),2(a,l7)')'after zdf_osm_calculate_dhdt: zhbl_t=',zhbl_t(ji,jj), 'hbl=', hbl(ji,jj),&
859               & 'delta hbl from dzdhdt', zdhdt(ji,jj)*rn_Dt,' delta hbl from w ', ww(ji,jj,nbld(ji,jj))*rn_Dt,   &
860               & ' lcoup= ', l_coup(ji,jj), ' lpyc= ', l_pyc(ji,jj)
861            FLUSH(narea+100)
862         END IF
863#endif
864      END_2D
865      !
866      nmld(:,:) = nbld(:,:)           ! use nmld to hold previous blayer index
867      nbld(:,:) = 4
868      !
869      DO_3D( 0, 0, 0, 0, 4, jpkm1 )
870         IF ( zhbl_t(ji,jj) >= gdepw(ji,jj,jk,Kmm) ) THEN
871            nbld(ji,jj) = jk
872         END IF
873      END_3D
874      !
875      !
876      ! Step through model levels taking account of buoyancy change to determine the effect on dhdt
877      !
878      CALL zdf_osm_timestep_hbl( Kmm, zdhdt, zhbl, zhbl_t, zwb_ent,   &
879         &                       zwb_fk_b )
880      ! Is external level in bounds?
881      !
882      ! Recalculate BL averages and differences using new BL depth
883      jp_ext(:,:) = 1   ! ag 19/03
884      CALL zdf_osm_vertical_average( Kbb, Kmm, nbld, av_t_bl, av_s_bl,    &
885         &                           av_b_bl, av_u_bl, av_v_bl, jp_ext, zdt_bl,   &
886         &                           zds_bl, zdb_bl, zdu_bl, zdv_bl )
887      !
888      CALL zdf_osm_pycnocline_thickness( Kmm, zdh, zhml, zdhdt, zdb_bl,   &
889         &                               zhbl, zwb_ent, zdbdz_bl_ext, zwb_fk_b )
890      !
891      ! Reset l_pyc before calculating terms in the flux-gradient relationship
892      DO_2D( 0, 0, 0, 0 )
893         IF ( zdb_bl(ji,jj) < rn_osm_bl_thresh .OR. nbld(ji,jj) >= mbkt(ji,jj) - 2 .OR.   &
894            & nbld(ji,jj) - nmld(ji,jj) == 1   .OR. zdhdt(ji,jj) < 0.0_wp ) THEN   ! ag 19/03
895            l_pyc(ji,jj) = .FALSE.   ! ag 19/03
896            IF ( nbld(ji,jj) >= mbkt(ji,jj) -2 ) THEN
897               nmld(ji,jj) = nbld(ji,jj) - 1                                               ! ag 19/03
898               zdh(ji,jj)  = gdepw(ji,jj,nbld(ji,jj),Kmm) - gdepw(ji,jj,nmld(ji,jj),Kmm)   ! ag 19/03
899               zhml(ji,jj) = gdepw(ji,jj,nmld(ji,jj),Kmm)                                  ! ag 19/03
900               dh(ji,jj)   = zdh(ji,jj)                                                    ! ag 19/03 
901               hml(ji,jj)  = hbl(ji,jj) - dh(ji,jj)                                        ! ag 19/03
902#ifdef key_osm_debug
903               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
904                  WRITE(narea+100,'(a)')'After setting pycnocline thickness BL running aground: lpyc= F5: ibld(ji,jj) >= mbkt(ji,jj) -2'
905                  WRITE(narea+100,'(2(a,i7),2(a,g11.3))')' ibld=',nbld(ji,jj),' imld=',nmld(ji,jj), ' zdh=',zdh(ji,jj), ' zhml=',zhml(ji,jj)
906                  WRITE(narea+100,'(2(a,g11.3))')'dh=',dh(ji,jj),' hml=',hml(ji,jj)
907                  FLUSH(narea+100)
908               END IF
909#endif
910            ENDIF
911         ENDIF                                              ! ag 19/03
912      END_2D
913      !
914      dstokes(:,:) = MIN ( dstokes(:,:), hbl(:,:)/ 3.0_wp )   ! Limit delta for shallow boundary layers for calculating
915      !                                                       !    flux-gradient terms
916      !
917      ! Average over the depth of the mixed layer in the convective boundary layer
918      !      jp_ext = nbld - nmld + 1
919      ! Recalculate ML averages and differences using new ML depth
920      jp_ext(:,:) = nbld(:,:) - nmld(:,:) + jp_ext(:,:) + 1   ! ag 19/03
921      CALL zdf_osm_vertical_average( Kbb, Kmm, nmld - 1, av_t_ml, av_s_ml,    &
922         &                           av_b_ml, av_u_ml, av_v_ml, jp_ext, zdt_ml,   &
923         &                           zds_ml, zdb_ml, zdu_ml, zdv_ml )
924      !
925      CALL zdf_osm_external_gradients( Kmm, nbld + 1, zdtdz_bl_ext, zdsdz_bl_ext, zdbdz_bl_ext )
926#ifdef key_osm_debug
927      IF(narea==nn_narea_db) THEN
928         ji=iloc_db; jj=jloc_db
929         WRITE(narea+100,'(4(3(a,g11.3),/), 2(4(a,g11.3),/))') &
930            & 'After averaging, with new hbl (&correct jp_ext), hml: zt_bl=', av_t_bl(ji,jj),&
931            & ' zs_bl=', av_s_bl(ji,jj),  ' zb_bl=', av_b_bl(ji,jj),&
932            & 'zdt_bl=', zdt_bl(ji,jj), ' zds_bl=', zds_bl(ji,jj),  ' zdb_bl=', zdb_bl(ji,jj),&
933            & 'zt_ml=', av_t_ml(ji,jj), ' zs_ml=', av_s_ml(ji,jj),  ' zb_ml=', av_b_ml(ji,jj),&
934            & 'zdt_ml=', zdt_ml(ji,jj), ' zds_ml=', zds_ml(ji,jj),  ' zdb_ml=', zdb_ml(ji,jj),&
935            & 'zu_bl =', av_u_bl(ji,jj) , ' zv_bl=', av_v_bl(ji,jj), ' zdu_bl=', zdu_bl(ji,jj), ' zdv_bl=', zdv_bl(ji,jj),&
936            & 'zu_ml =', av_u_ml(ji,jj) , ' zv_ml=', av_v_ml(ji,jj), ' zdu_ml=', zdu_ml(ji,jj), ' zdv_ml=', zdv_ml(ji,jj)
937         FLUSH(narea+100)
938      END IF
939#endif
940      ! Rotate mean currents and changes onto wind aligned co-ordinates
941      CALL zdf_osm_velocity_rotation( av_u_ml, av_v_ml )
942      CALL zdf_osm_velocity_rotation( zdu_ml, zdv_ml )
943      CALL zdf_osm_velocity_rotation( av_u_bl, av_v_bl )
944      CALL zdf_osm_velocity_rotation( zdu_bl, zdv_bl )
945#ifdef key_osm_debug
946      IF(narea==nn_narea_db) THEN
947         ji=iloc_db; jj=jloc_db
948         WRITE(narea+100,'(a,/, 2(4(a,g11.3),/))') &
949            & 'After rotation, with new hbl (& correct jp_ext), hml:', &
950            & 'zu_bl =', av_u_bl(ji,jj) , ' zv_bl=', av_v_bl(ji,jj), ' zdu_bl=', zdu_bl(ji,jj), ' zdv_bl=', zdv_bl(ji,jj),&
951            & 'zu_ml =', av_u_ml(ji,jj) , ' zv_ml=', av_v_ml(ji,jj), ' zdu_ml=', zdu_ml(ji,jj), ' zdv_ml=', zdv_ml(ji,jj)
952         FLUSH(narea+100)
953      END IF
954#endif
955      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
956      !  Pycnocline gradients for scalars and velocity
957      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
958      jp_ext(:,:) = 1   ! ag 19/03
959      CALL zdf_osm_pycnocline_buoyancy_profiles( Kmm, jp_ext, zdbdz_pyc, zalpha_pyc, zdh,    &
960         &                                       zdb_bl, zhbl, zdbdz_bl_ext, zhml, zdb_ml,   &
961         &                                       zdhdt )
962#ifdef key_osm_debug
963      IF(narea==nn_narea_db) THEN
964         ji=iloc_db; jj=jloc_db
965         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
966         WRITE(narea+100,'(a,l7,/,3(a,g11.3),/)') &
967            & 'After pycnocline profiles BL  lpyc=', l_pyc(ji,jj),&
968            & 'sub-BL strat: zdtdz_bl_ext=', zdtdz_bl_ext(ji,jj),' zdsdz_bl_ext=', zdsdz_bl_ext(ji,jj),' zdbdz_bl_ext=', zdbdz_bl_ext(ji,jj), &
969            & 'Pycnocline: zalpha_pyc=', zalpha_pyc(ji,jj)
970         !       WRITE(narea+100,'(a,*(g11.3))') ' zdtdz_pyc[imld-1..ibld+2] =', ( zdtdz_pyc(ji,jj,jk), jk=jl,jm )
971         !       WRITE(narea+100,'(a,*(g11.3))') ' zdsdz_pyc[imld-1..ibld+2] =', ( zdsdz_pyc(ji,jj,jk), jk=jl,jm )
972         WRITE(narea+100,'(a,*(g11.3))') ' zdbdz_pyc[imld-1..ibld+2] =', ( zdbdz_pyc(ji,jj,jk), jk=jl,jm )
973         !       WRITE(narea+100,'(a,*(g11.3))') ' zdudz_pyc[imld-1..ibld+2] =', ( zdudz_pyc(ji,jj,jk), jk=jl,jm )
974         !       WRITE(narea+100,'(a,*(g11.3))') ' zdvdz_pyc[imld-1..ibld+2] =', ( zdvdz_pyc(ji,jj,jk), jk=jl,jm )
975         WRITE(narea+100,*)
976         FLUSH(narea+100)
977      END IF
978#endif
979      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
980      ! Eddy viscosity/diffusivity and non-gradient terms in the flux-gradient relationship
981      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
982      CALL zdf_osm_diffusivity_viscosity( Kbb, Kmm, zdiffut, zviscos, zhbl,    &
983         &                                zhml, zdh, zdhdt, zshear, zwb_ent,   &
984         &                                zwb_min )
985#ifdef key_osm_debug
986      IF(narea==nn_narea_db) THEN
987         ji=iloc_db; jj=jloc_db
988         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
989         WRITE(narea+100,'(a,*(g11.3))') ' zdiffut[imld-1..ibld+2] =', ( zdiffut(ji,jj,jk), jk=jl,jm )
990         WRITE(narea+100,'(a,*(g11.3))') ' zviscos[imld-1..ibld+2] =', ( zviscos(ji,jj,jk), jk=jl,jm )
991         WRITE(narea+100,*)
992         FLUSH(narea+100)
993      END IF
994#endif
995      !
996      ! Calculate non-gradient components of the flux-gradient relationships
997      ! --------------------------------------------------------------------
998      CALL zdf_osm_fgr_terms( Kmm, jp_ext, zhbl, zhml, zdh,                            &
999         &                    zdhdt, zshear, zdt_bl, zds_bl, zdb_bl,                   &
1000         &                    zdu_bl, zdv_bl, zdt_ml, zds_ml, zdb_ml,                  &
1001         &                    zdu_ml, zdv_ml, zdtdz_bl_ext, zdsdz_bl_ext, zdbdz_pyc,   &
1002         &                    zalpha_pyc, zdiffut, zviscos )
1003      !
1004      !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1005      ! Need to put in code for contributions that are applied explicitly to
1006      ! the prognostic variables
1007      !  1. Entrainment flux
1008      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1009      !
1010      ! Rotate non-gradient velocity terms back to model reference frame
1011      CALL zdf_osm_velocity_rotation( ghamu, ghamv, .FALSE., 2, nbld )
1012      !
1013      ! KPP-style Ri# mixing
1014      IF ( ln_kpprimix ) THEN
1015         jkflt = jpk
1016         DO_2D( 0, 0, 0, 0 )
1017            IF ( nbld(ji,jj) < jkflt ) jkflt = nbld(ji,jj)
1018         END_2D
1019         DO jk = jkflt+1, jpkm1
1020            ! Shear production at uw- and vw-points (energy conserving form)
1021            DO_2D( 1, 0, 1, 0 )
1022               z2du(ji,jj) = 0.5_wp * ( uu(ji,jj,jk-1,Kmm) - uu(ji,jj,jk,Kmm) ) * ( uu(ji,jj,jk-1,Kbb) - uu(ji,jj,jk,Kbb) ) *   &
1023                  &          wumask(ji,jj,jk) / ( e3uw(ji,jj,jk,Kmm) * e3uw(ji,jj,jk,Kbb) )
1024               z2dv(ji,jj) = 0.5_wp * ( vv(ji,jj,jk-1,Kmm) - vv(ji,jj,jk,Kmm) ) * ( vv(ji,jj,jk-1,Kbb) - vv(ji,jj,jk,Kbb) ) *   &
1025                  &          wvmask(ji,jj,jk) / ( e3vw(ji,jj,jk,Kmm) * e3vw(ji,jj,jk,Kbb) )
1026            END_2D
1027            DO_2D( 0, 0, 0, 0 )
1028               IF ( jk > nbld(ji,jj) ) THEN
1029                  ! Shear prod. at w-point weightened by mask
1030                  zesh2 = ( z2du(ji-1,jj) + z2du(ji,jj) ) / MAX( 1.0_wp , umask(ji-1,jj,jk) + umask(ji,jj,jk) ) +   &
1031                     &    ( z2dv(ji,jj-1) + z2dv(ji,jj) ) / MAX( 1.0_wp , vmask(ji,jj-1,jk) + vmask(ji,jj,jk) )
1032                  ! Local Richardson number
1033                  zri     = MAX( rn2b(ji,jj,jk), 0.0_wp ) / MAX( zesh2, epsln )
1034                  zfri    = MIN( zri / rn_riinfty, 1.0_wp )
1035                  zfri    = ( 1.0_wp - zfri * zfri )
1036                  zrimix  =  zfri * zfri  * zfri * wmask(ji, jj, jk)
1037                  zdiffut(ji,jj,jk) = MAX( zdiffut(ji,jj,jk), zrimix*rn_difri )
1038                  zviscos(ji,jj,jk) = MAX( zviscos(ji,jj,jk), zrimix*rn_difri )
1039               END IF
1040            END_2D
1041         END DO
1042      END IF   ! ln_kpprimix = .true.
1043      !
1044      ! KPP-style set diffusivity large if unstable below BL
1045      IF ( ln_convmix) THEN
1046         DO_2D( 0, 0, 0, 0 )
1047            DO jk = nbld(ji,jj) + 1, jpkm1
1048               IF ( MIN( rn2(ji,jj,jk), rn2b(ji,jj,jk) ) <= -1e-12_wp ) zdiffut(ji,jj,jk) = MAX( rn_difconv, zdiffut(ji,jj,jk) )
1049            END DO
1050         END_2D
1051      END IF   ! ln_convmix = .true.
1052#ifdef key_osm_debug
1053      IF(narea==nn_narea_db) THEN
1054         ji=iloc_db; jj=jloc_db
1055         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
1056         WRITE(narea+100,'(a)') ' After including KPP Ri# diffusivity & viscosity'
1057         WRITE(narea+100,'(a,*(g11.3))') ' zdiffut[imld-1..ibld+2] =', ( zdiffut(ji,jj,jk), jk=jl,jm )
1058         WRITE(narea+100,'(a,*(g11.3))') ' zviscos[imld-1..ibld+2] =', ( zviscos(ji,jj,jk), jk=jl,jm )
1059         WRITE(narea+100,*)
1060         FLUSH(narea+100)
1061      END IF
1062#endif
1063      !
1064      IF ( ln_osm_mle ) THEN   ! Set up diffusivity and non-gradient mixing
1065         DO_2D( 0, 0, 0, 0 )
1066            IF ( l_flux(ji,jj) ) THEN   ! MLE mixing extends below boundary layer
1067               ! Calculate MLE flux contribution from surface fluxes
1068               DO jk = 1, nbld(ji,jj)
1069                  znd = gdepw(ji,jj,jk,Kmm) / MAX( zhbl(ji,jj), epsln )
1070                  ghamt(ji,jj,jk) = ghamt(ji,jj,jk) - ( swth0(ji,jj) - zrad0(ji,jj) + zradh(ji,jj) ) * ( 1.0_wp - znd )
1071                  ghams(ji,jj,jk) = ghams(ji,jj,jk) - sws0(ji,jj) * ( 1.0_wp - znd )
1072               END DO
1073               DO jk = 1, mld_prof(ji,jj)
1074                  znd = gdepw(ji,jj,jk,Kmm) / MAX( zhmle(ji,jj), epsln )
1075                  ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + ( swth0(ji,jj) - zrad0(ji,jj) + zradh(ji,jj) ) * ( 1.0_wp - znd )
1076                  ghams(ji,jj,jk) = ghams(ji,jj,jk) + sws0(ji,jj) * ( 1.0_wp -znd )
1077               END DO
1078               ! Viscosity for MLEs
1079               DO jk = 1, mld_prof(ji,jj)
1080                  znd = -1.0_wp * gdepw(ji,jj,jk,Kmm) / MAX( zhmle(ji,jj), epsln )
1081                  zdiffut(ji,jj,jk) = zdiffut(ji,jj,jk) + zdiff_mle(ji,jj) * ( 1.0_wp - ( 2.0_wp * znd + 1.0_wp )**2 ) *   &
1082                     &                                    ( 1.0_wp + 5.0_wp / 21.0_wp * ( 2.0_wp * znd + 1.0_wp )**2 )
1083               END DO
1084            ELSE   ! Surface transports limited to OSBL
1085               ! Viscosity for MLEs
1086               DO jk = 1, mld_prof(ji,jj)
1087                  znd = -1.0_wp * gdepw(ji,jj,jk,Kmm) / MAX( zhmle(ji,jj), epsln )
1088                  zdiffut(ji,jj,jk) = zdiffut(ji,jj,jk) + zdiff_mle(ji,jj) * ( 1.0_wp - ( 2.0_wp * znd + 1.0_wp )**2 ) *   &
1089                     &                                    ( 1.0_wp + 5.0_wp / 21.0_wp * ( 2.0_wp * znd + 1.0_wp )**2 )
1090               END DO
1091            END IF
1092         END_2D
1093#ifdef key_osm_debug
1094         IF(narea==nn_narea_db) THEN
1095            ji=iloc_db; jj=jloc_db
1096            jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
1097            WRITE(narea+100,'(a)') ' After including FK diffusivity & non-local terms'
1098            WRITE(narea+100,'(a,*(g11.3))') ' zdiffut[imld-1..ibld+2] =', ( zdiffut(ji,jj,jk), jk=jl,jm )
1099            WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
1100            WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
1101            WRITE(narea+100,*)
1102            FLUSH(narea+100)
1103         END IF
1104#endif
1105      ENDIF
1106      !
1107      ! Lateral boundary conditions on zvicos (sign unchanged), needed to caclulate viscosities on u and v grids
1108      ! CALL lbc_lnk( 'zdfosm', zviscos(:,:,:), 'W', 1.0_wp )
1109      ! GN 25/8: need to change tmask --> wmask
1110      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
1111         p_avt(ji,jj,jk) = MAX( zdiffut(ji,jj,jk), avtb(jk) ) * tmask(ji,jj,jk)
1112         p_avm(ji,jj,jk) = MAX( zviscos(ji,jj,jk), avmb(jk) ) * tmask(ji,jj,jk)
1113      END_3D
1114      ! Lateral boundary conditions on ghamu and ghamv, currently on W-grid (sign unchanged), needed to caclulate gham[uv] on u and
1115      !    v grids
1116      CALL lbc_lnk_multi( 'zdfosm', p_avt, 'W', 1.0_wp,   &
1117         &                          p_avm, 'W', 1.0_wp,   &
1118         &                          ghamu, 'W', 1.0_wp,   &
1119         &                          ghamv, 'W', 1.0_wp )
1120      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
1121         ghamu(ji,jj,jk) = ( ghamu(ji,jj,jk) + ghamu(ji+1,jj,jk) ) / MAX( 1.0_wp, tmask(ji,jj,jk) + tmask (ji+1,jj,jk) ) *   &
1122            &              umask(ji,jj,jk)
1123         ghamv(ji,jj,jk) = ( ghamv(ji,jj,jk) + ghamv(ji,jj+1,jk) ) / MAX( 1.0_wp, tmask(ji,jj,jk) + tmask (ji,jj+1,jk) ) *   &
1124            &              vmask(ji,jj,jk)
1125         ghamt(ji,jj,jk) =  ghamt(ji,jj,jk) * tmask(ji,jj,jk)
1126         ghams(ji,jj,jk) =  ghams(ji,jj,jk) * tmask(ji,jj,jk)
1127      END_3D
1128      ! Lateral boundary conditions on final outputs for hbl, on T-grid (sign unchanged)
1129      CALL lbc_lnk_multi( 'zdfosm', hbl,  'T', 1.0_wp,   &
1130         &                          dh,   'T', 1.0_wp,   &
1131         &                          hmle, 'T', 1.0_wp )
1132      ! Lateral boundary conditions on final outputs for gham[ts], on W-grid  (sign unchanged)
1133      ! Lateral boundary conditions on final outputs for gham[uv], on [UV]-grid  (sign changed)
1134      CALL lbc_lnk_multi( 'zdfosm', ghamt, 'W',  1.0_wp,   &
1135         &                          ghams, 'W',  1.0_wp,   &
1136         &                          ghamu, 'U', -1.0_wp,   &
1137         &                          ghamv, 'V', -1.0_wp )
1138#ifdef key_osm_debug
1139      IF(narea==nn_narea_db) THEN
1140         ji=iloc_db; jj=jloc_db
1141         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
1142         WRITE(narea+100,'(a)') ' Final diffusivity & viscosity, & non-local terms'
1143         WRITE(narea+100,'(a,*(g11.3))') ' p_avt[imld-1..ibld+2] =', ( p_avt(ji,jj,jk), jk=jl,jm )
1144         WRITE(narea+100,'(a,*(g11.3))') ' p_avm[imld-1..ibld+2] =', ( p_avm(ji,jj,jk), jk=jl,jm )
1145         WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
1146         WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
1147         WRITE(narea+100,'(a,*(g11.3))') ' ghamu[imld-1..ibld+2] =', ( ghamu(ji,jj,jk), jk=jl,jm )
1148         WRITE(narea+100,'(a,*(g11.3))') ' ghamv[imld-1..ibld+2] =', ( ghamv(ji,jj,jk), jk=jl,jm )
1149         WRITE(narea+100,*)
1150         FLUSH(narea+100)
1151      END IF
1152#endif
1153      !
1154      IF(ln_dia_osm) THEN
1155         SELECT CASE (nn_osm_wave)
1156            ! Stokes drift set by assumimg onstant La#=0.3 (=0) or Pierson-Moskovitz spectrum (=1)
1157         CASE(0:1)
1158            IF ( iom_use("us_x") ) CALL iom_put( "us_x", tmask(:,:,1)*sustke*scos_wind )          ! x surface Stokes drift
1159            IF ( iom_use("us_y") ) CALL iom_put( "us_y", tmask(:,:,1)*sustke*ssin_wind )          ! y surface Stokes drift
1160            IF ( iom_use("wind_wave_abs_power") ) CALL iom_put( "wind_wave_abs_power", 1000.0_wp * rho0 * tmask(:,:,1) *   &
1161               &                                                                       sustar**2 * sustke )
1162            ! Stokes drift read in from sbcwave  (=2).
1163         CASE(2:3)
1164            IF ( iom_use("us_x") ) CALL iom_put( "us_x", ut0sd*umask(:,:,1) )                     ! x surface Stokes drift
1165            IF ( iom_use("us_y") ) CALL iom_put( "us_y", vt0sd*vmask(:,:,1) )                     ! y surface Stokes drift
1166            IF ( iom_use("wmp") ) CALL iom_put( "wmp", wmp*tmask(:,:,1) )                         ! Wave mean period
1167            IF ( iom_use("hsw") ) CALL iom_put( "hsw", hsw*tmask(:,:,1) )                         ! Significant wave height
1168            IF ( iom_use("wmp_NP") ) CALL iom_put( "wmp_NP", ( 2.0_wp * rpi * 1.026_wp /      &   ! Wave mean period from NP
1169               &                                               ( 0.877_wp * grav ) ) *        &   !    spectrum
1170               &                                               wndm * tmask(:,:,1) )
1171            IF ( iom_use("hsw_NP") ) CALL iom_put( "hsw_NP", ( 0.22_wp / grav ) * wndm**2 *   &   ! Significant wave
1172               &                                             tmask(:,:,1) )                       !    height from NP spectrum
1173            IF ( iom_use("wndm") ) CALL iom_put( "wndm", wndm*tmask(:,:,1) )                      ! U_10
1174            IF ( iom_use("wind_wave_abs_power") ) CALL iom_put( "wind_wave_abs_power",                          &
1175               &                                                1000.0_wp * rho0 * tmask(:,:,1) * sustar**2 *   &
1176               &                                                SQRT( ut0sd**2 + vt0sd**2 ) )
1177         END SELECT
1178         IF ( iom_use("ghamt") ) CALL iom_put( "ghamt", tmask*ghamt )                      ! <Tw_NL>
1179         IF ( iom_use("ghams") ) CALL iom_put( "ghams", tmask*ghams )                      ! <Sw_NL>
1180         IF ( iom_use("ghamu") ) CALL iom_put( "ghamu", umask*ghamu )                      ! <uw_NL>
1181         IF ( iom_use("ghamv") ) CALL iom_put( "ghamv", vmask*ghamv )                      ! <vw_NL>
1182         IF ( iom_use("zwth0") ) CALL iom_put( "zwth0", tmask(:,:,1)*swth0 )               ! <Tw_0>
1183         IF ( iom_use("zws0") ) CALL iom_put( "zws0", tmask(:,:,1)*sws0 )                  ! <Sw_0>
1184         IF ( iom_use("zwb0") ) CALL iom_put( "zwb0", tmask(:,:,1)*swb0 )                  ! <Sw_0>
1185         IF ( iom_use("zwbav") ) CALL iom_put( "zwbav", tmask(:,:,1)*swth0 )               ! Upward BL-avged turb buoyancy flux
1186         IF ( iom_use("hbl") ) CALL iom_put( "hbl", tmask(:,:,1)*hbl )                     ! Boundary-layer depth
1187         IF ( iom_use("ibld") ) CALL iom_put( "ibld", tmask(:,:,1)*nbld )                  ! Boundary-layer max k
1188         IF ( iom_use("zdt_bl") ) CALL iom_put( "zdt_bl", tmask(:,:,1)*zdt_bl )            ! dt at ml base
1189         IF ( iom_use("zds_bl") ) CALL iom_put( "zds_bl", tmask(:,:,1)*zds_bl )            ! ds at ml base
1190         IF ( iom_use("zdb_bl") ) CALL iom_put( "zdb_bl", tmask(:,:,1)*zdb_bl )            ! db at ml base
1191         IF ( iom_use("zdu_bl") ) CALL iom_put( "zdu_bl", tmask(:,:,1)*zdu_bl )            ! du at ml base
1192         IF ( iom_use("zdv_bl") ) CALL iom_put( "zdv_bl", tmask(:,:,1)*zdv_bl )            ! dv at ml base
1193         IF ( iom_use("dh") ) CALL iom_put( "dh", tmask(:,:,1)*dh )                        ! Initial boundary-layer depth
1194         IF ( iom_use("hml") ) CALL iom_put( "hml", tmask(:,:,1)*hml )                     ! Initial boundary-layer depth
1195         IF ( iom_use("zdt_ml") ) CALL iom_put( "zdt_ml", tmask(:,:,1)*zdt_ml )            ! dt at ml base
1196         IF ( iom_use("zds_ml") ) CALL iom_put( "zds_ml", tmask(:,:,1)*zds_ml )            ! ds at ml base
1197         IF ( iom_use("zdb_ml") ) CALL iom_put( "zdb_ml", tmask(:,:,1)*zdb_ml )            ! db at ml base
1198         IF ( iom_use("dstokes") ) CALL iom_put( "dstokes", tmask(:,:,1)*dstokes )         ! Stokes drift penetration depth
1199         IF ( iom_use("zustke") ) CALL iom_put( "zustke", tmask(:,:,1)*sustke )            ! Stokes drift magnitude at T-points
1200         IF ( iom_use("zwstrc") ) CALL iom_put( "zwstrc", tmask(:,:,1)*swstrc )            ! Convective velocity scale
1201         IF ( iom_use("zwstrl") ) CALL iom_put( "zwstrl", tmask(:,:,1)*swstrl )            ! Langmuir velocity scale
1202         IF ( iom_use("zustar") ) CALL iom_put( "zustar", tmask(:,:,1)*sustar )            ! Friction velocity scale
1203         IF ( iom_use("zvstr") ) CALL iom_put( "zvstr", tmask(:,:,1)*svstr )               ! Mixed velocity scale
1204         IF ( iom_use("zla") ) CALL iom_put( "zla", tmask(:,:,1)*sla )                     ! Langmuir #
1205         IF ( iom_use("wind_power") ) CALL iom_put( "wind_power", 1000.0_wp * rho0 *   &   ! BL depth internal to zdf_osm routine
1206            &                                                     tmask(:,:,1) * sustar**3 ) 
1207         IF ( iom_use("wind_wave_power") ) CALL iom_put( "wind_wave_power", 1000.0_wp * rho0 * tmask(:,:,1) * sustar**2 * sustke )
1208         IF ( iom_use("zhbl") ) CALL iom_put( "zhbl", tmask(:,:,1)*zhbl )                  ! BL depth internal to zdf_osm routine
1209         IF ( iom_use("zhml") ) CALL iom_put( "zhml", tmask(:,:,1)*zhml )                  ! ML depth internal to zdf_osm routine
1210         IF ( iom_use("imld") ) CALL iom_put( "imld", tmask(:,:,1)*nmld )                  ! Index for ML depth internal to zdf_osm routine
1211         IF ( iom_use("jp_ext") ) CALL iom_put( "jp_ext", tmask(:,:,1)*jp_ext )            ! =1 if pycnocline resolved internal to zdf_osm routine
1212         IF ( iom_use("j_ddh") ) CALL iom_put( "j_ddh", tmask(:,:,1)*n_ddh )               ! Index forpyc thicknessh internal to zdf_osm routine
1213         IF ( iom_use("zshear") ) CALL iom_put( "zshear", tmask(:,:,1)*zshear )            ! Shear production of TKE internal to zdf_osm routine
1214         IF ( iom_use("zdh") ) CALL iom_put( "zdh", tmask(:,:,1)*zdh )                     ! Pyc thicknessh internal to zdf_osm routine
1215         IF ( iom_use("zhol") ) CALL iom_put( "zhol", tmask(:,:,1)*shol )                  ! ML depth internal to zdf_osm routine
1216         IF ( iom_use("zwb_ent") ) CALL iom_put( "zwb_ent", tmask(:,:,1)*zwb_ent )         ! Upward turb buoyancy entrainment flux
1217         IF ( iom_use("zt_ml") ) CALL iom_put( "zt_ml", tmask(:,:,1)*av_t_ml )             ! Average T in ML
1218         IF ( iom_use("hmle") ) CALL iom_put( "hmle", tmask(:,:,1)*hmle )                  ! FK layer depth
1219         IF ( iom_use("zmld") ) CALL iom_put( "zmld", tmask(:,:,1)*zmld )                  ! FK target layer depth
1220         IF ( iom_use("zwb_fk") ) CALL iom_put( "zwb_fk", tmask(:,:,1)*zwb_fk )            ! FK b flux
1221         IF ( iom_use("zwb_fk_b") ) CALL iom_put( "zwb_fk_b", tmask(:,:,1)*zwb_fk_b )      ! FK b flux averaged over ML
1222         IF ( iom_use("mld_prof") ) CALL iom_put( "mld_prof", tmask(:,:,1)*mld_prof )      ! FK layer max k
1223         IF ( iom_use("zdtdx") ) CALL iom_put( "zdtdx", umask(:,:,1)*zdtdx )               ! FK dtdx at u-pt
1224         IF ( iom_use("zdtdy") ) CALL iom_put( "zdtdy", vmask(:,:,1)*zdtdy )               ! FK dtdy at v-pt
1225         IF ( iom_use("zdsdx") ) CALL iom_put( "zdsdx", umask(:,:,1)*zdsdx )               ! FK dtdx at u-pt
1226         IF ( iom_use("zdsdy") ) CALL iom_put( "zdsdy", vmask(:,:,1)*zdsdy )               ! FK dsdy at v-pt
1227         IF ( iom_use("dbdx_mle") ) CALL iom_put( "dbdx_mle", umask(:,:,1)*dbdx_mle )      ! FK dbdx at u-pt
1228         IF ( iom_use("dbdy_mle") ) CALL iom_put( "dbdy_mle", vmask(:,:,1)*dbdy_mle )      ! FK dbdy at v-pt
1229         IF ( iom_use("zdiff_mle") ) CALL iom_put( "zdiff_mle", tmask(:,:,1)*zdiff_mle )   ! FK diff in MLE at t-pt
1230         IF ( iom_use("zvel_mle") ) CALL iom_put( "zvel_mle", tmask(:,:,1)*zdiff_mle )     ! FK diff in MLE at t-pt
1231
1232      END IF
1233      IF( ln_timing ) CALL timing_stop('zdf_osm')
1234
1235   END SUBROUTINE zdf_osm
1236
1237   SUBROUTINE zdf_osm_vertical_average( Kbb, Kmm, knlev, pt, ps,    &
1238      &                                 pb, pu, pv, kp_ext, pdt,   &
1239      &                                 pds, pdb, pdu, pdv )
1240      !!---------------------------------------------------------------------
1241      !!                ***  ROUTINE zdf_vertical_average  ***
1242      !!
1243      !! ** Purpose : Determines vertical averages from surface to knlev,
1244      !!              and optionally the differences between these vertical
1245      !!              averages and values at an external level
1246      !!
1247      !! ** Method  : Averages are calculated from the surface to knlev.
1248      !!              The external level used to calculate differences is
1249      !!              knlev+kp_ext
1250      !!----------------------------------------------------------------------
1251      INTEGER,                      INTENT(in   )           ::   Kbb, Kmm   ! Ocean time-level indices
1252      INTEGER,  DIMENSION(jpi,jpj), INTENT(in   )           ::   knlev      ! Number of levels to average over.
1253      REAL(wp), DIMENSION(jpi,jpj), INTENT(  out)           ::   pt, ps     ! Average temperature and salinity
1254      REAL(wp), DIMENSION(jpi,jpj), INTENT(  out)           ::   pb         ! Average buoyancy
1255      REAL(wp), DIMENSION(jpi,jpj), INTENT(  out)           ::   pu, pv     ! Average current components
1256      INTEGER,  DIMENSION(jpi,jpj), INTENT(in   ), OPTIONAL ::   kp_ext     ! External-level offsets
1257      REAL(wp), DIMENSION(jpi,jpj), INTENT(  out), OPTIONAL ::   pdt, pds   ! Difference between average temperature, salinity,
1258      REAL(wp), DIMENSION(jpi,jpj), INTENT(  out), OPTIONAL ::   pdb        ! buoyancy,
1259      REAL(wp), DIMENSION(jpi,jpj), INTENT(  out), OPTIONAL ::   pdu, pdv   ! velocity components and the OSBL
1260      !
1261      INTEGER                      ::   jk, jkflt, jkmax, ji, jj   ! Loop indices
1262      INTEGER                      ::   ibld_ext                   ! External-layer index
1263      REAL(wp), DIMENSION(jpi,jpj) ::   zthick                     ! Layer thickness
1264      REAL(wp)                     ::   zthermal, zbeta            ! Thermal/haline expansion/contraction coefficients
1265      !!----------------------------------------------------------------------
1266      !
1267      IF( ln_timing ) CALL timing_start('zdf_osm_va')
1268      !
1269      ! Averages over depth of boundary layer
1270      pt(A2D(0))     = 0.0_wp
1271      ps(A2D(0))     = 0.0_wp
1272      pu(A2D(0))     = 0.0_wp
1273      pv(A2D(0))     = 0.0_wp
1274      zthick(:,:) = epsln
1275      jkflt = jpk
1276      jkmax = 0
1277      DO_2D( 0, 0, 0, 0 )
1278         IF ( knlev(ji,jj) < jkflt ) jkflt = knlev(ji,jj)
1279         IF ( knlev(ji,jj) > jkmax ) jkmax = knlev(ji,jj)
1280      END_2D
1281      DO_3D( 0, 0, 0, 0, 2, jkflt )   ! Upper, flat part of layer
1282         zthick(ji,jj) = zthick(ji,jj) + e3t(ji,jj,jk,Kmm)
1283         pt(ji,jj)     = pt(ji,jj)     + e3t(ji,jj,jk,Kmm) * ts(ji,jj,jk,jp_tem,Kmm)
1284         ps(ji,jj)     = ps(ji,jj)     + e3t(ji,jj,jk,Kmm) * ts(ji,jj,jk,jp_sal,Kmm)
1285         pu(ji,jj)     = pu(ji,jj)     + e3t(ji,jj,jk,Kmm) *                                        &
1286            &                               ( uu(ji,jj,jk,Kbb) + uu(ji - 1,jj,jk,Kbb) ) /           &
1287            &                               MAX( 1.0_wp , umask(ji,jj,jk) + umask(ji - 1,jj,jk) )
1288         pv(ji,jj)     = pv(ji,jj)     + e3t(ji,jj,jk,Kmm) *                                        &
1289            &                               ( vv(ji,jj,jk,Kbb) + vv(ji,jj - 1,jk,Kbb) ) /           &
1290            &                               MAX( 1.0_wp , vmask(ji,jj,jk) + vmask(ji,jj - 1,jk) )         
1291      END_3D
1292      DO_3D( 0, 0, 0, 0, jkflt+1, jkmax )   ! Lower, non-flat part of layer
1293         IF ( knlev(ji,jj) >= jk ) THEN
1294            zthick(ji,jj) = zthick(ji,jj) + e3t(ji,jj,jk,Kmm)
1295            pt(ji,jj)     = pt(ji,jj)     + e3t(ji,jj,jk,Kmm) * ts(ji,jj,jk,jp_tem,Kmm)
1296            ps(ji,jj)     = ps(ji,jj)     + e3t(ji,jj,jk,Kmm) * ts(ji,jj,jk,jp_sal,Kmm)
1297            pu(ji,jj)     = pu(ji,jj)     + e3t(ji,jj,jk,Kmm) *                                        &
1298               &                               ( uu(ji,jj,jk,Kbb) + uu(ji - 1,jj,jk,Kbb) ) /           &
1299               &                               MAX( 1.0_wp , umask(ji,jj,jk) + umask(ji - 1,jj,jk) )
1300            pv(ji,jj)     = pv(ji,jj)     + e3t(ji,jj,jk,Kmm) *                                        &
1301               &                               ( vv(ji,jj,jk,Kbb) + vv(ji,jj - 1,jk,Kbb) ) /           &
1302               &                               MAX( 1.0_wp , vmask(ji,jj,jk) + vmask(ji,jj - 1,jk) )
1303         END IF
1304      END_3D
1305      DO_2D( 0, 0, 0, 0 )
1306         pt(ji,jj) = pt(ji,jj) / zthick(ji,jj)
1307         ps(ji,jj) = ps(ji,jj) / zthick(ji,jj)
1308         pu(ji,jj) = pu(ji,jj) / zthick(ji,jj)
1309         pv(ji,jj) = pv(ji,jj) / zthick(ji,jj)
1310         zthermal  = rab_n(ji,jj,1,jp_tem)   ! ideally use nbld not 1??
1311         zbeta     = rab_n(ji,jj,1,jp_sal)
1312         pb(ji,jj) = grav * zthermal * pt(ji,jj) - grav * zbeta * ps(ji,jj)
1313      END_2D
1314      !
1315      ! Differences between vertical averages and values at an external layer
1316      IF ( PRESENT( kp_ext ) ) THEN
1317         DO_2D( 0, 0, 0, 0 )
1318            ibld_ext = knlev(ji,jj) + kp_ext(ji,jj)
1319            IF ( ibld_ext <= mbkt(ji,jj)-1 ) THEN   ! ag 09/03
1320               ! Two external levels are available
1321               pdt(ji,jj) = pt(ji,jj) - ts(ji,jj,ibld_ext,jp_tem,Kmm)
1322               pds(ji,jj) = ps(ji,jj) - ts(ji,jj,ibld_ext,jp_sal,Kmm)
1323               pdu(ji,jj) = pu(ji,jj) - ( uu(ji,jj,ibld_ext,Kbb) + uu(ji-1,jj,ibld_ext,Kbb ) ) /              &
1324                  &                        MAX(1.0_wp , umask(ji,jj,ibld_ext ) + umask(ji-1,jj,ibld_ext ) )
1325               pdv(ji,jj) = pv(ji,jj) - ( vv(ji,jj,ibld_ext,Kbb) + vv(ji,jj-1,ibld_ext,Kbb ) ) /              &
1326                  &                        MAX(1.0_wp , vmask(ji,jj,ibld_ext ) + vmask(ji,jj-1,ibld_ext ) )
1327               zthermal   = rab_n(ji,jj,1,jp_tem)   ! ideally use nbld not 1??
1328               zbeta      = rab_n(ji,jj,1,jp_sal)
1329               pdb(ji,jj) = grav * zthermal * pdt(ji,jj) - grav * zbeta * pds(ji,jj)
1330            ELSE
1331               pdt(ji,jj) = 0.0_wp
1332               pds(ji,jj) = 0.0_wp
1333               pdu(ji,jj) = 0.0_wp
1334               pdv(ji,jj) = 0.0_wp
1335               pdb(ji,jj) = 0.0_wp
1336            ENDIF
1337         END_2D
1338      END IF
1339      !
1340      IF( ln_timing ) CALL timing_stop('zdf_osm_va')
1341      !
1342   END SUBROUTINE zdf_osm_vertical_average
1343
1344   SUBROUTINE zdf_osm_velocity_rotation_2d( pu, pv, fwd )
1345      !!---------------------------------------------------------------------
1346      !!            ***  ROUTINE zdf_velocity_rotation_2d  ***
1347      !!
1348      !! ** Purpose : Rotates frame of reference of velocity components pu and
1349      !!              pv (2d)
1350      !!
1351      !! ** Method : The velocity components are rotated into (fwd=.TRUE.) or
1352      !!             from (fwd=.FALSE.) the frame specified by scos_wind and
1353      !!             ssin_wind
1354      !!
1355      !!----------------------------------------------------------------------     
1356      REAL(wp),           INTENT(inout), DIMENSION(jpi,jpj) ::   pu, pv           ! Components of current
1357      LOGICAL,  OPTIONAL, INTENT(in   )                     ::   fwd              ! Forward (default) or reverse rotation
1358      !
1359      INTEGER  ::   ji, jj       ! Loop indices
1360      REAL(wp) ::   ztmp, zfwd   ! Auxiliary variables
1361      !
1362      IF( ln_timing ) CALL timing_start('zdf_osm_vr')
1363      !
1364      zfwd = 1.0_wp
1365      IF( PRESENT(fwd) .AND. ( fwd==.FALSE. ) ) zfwd = -1.0_wp
1366      DO_2D( 0, 0, 0, 0 )
1367         ztmp      = pu(ji,jj)
1368         pu(ji,jj) = pu(ji,jj) * scos_wind(ji,jj) + zfwd * pv(ji,jj) * ssin_wind(ji,jj)
1369         pv(ji,jj) = pv(ji,jj) * scos_wind(ji,jj) - zfwd * ztmp      * ssin_wind(ji,jj)
1370      END_2D
1371      !
1372      IF( ln_timing ) CALL timing_stop('zdf_osm_vr')
1373      !
1374   END SUBROUTINE zdf_osm_velocity_rotation_2d
1375
1376   SUBROUTINE zdf_osm_velocity_rotation_3d( pu, pv, fwd, ktop, knlev )
1377      !!---------------------------------------------------------------------
1378      !!            ***  ROUTINE zdf_velocity_rotation_3d  ***
1379      !!
1380      !! ** Purpose : Rotates frame of reference of velocity components pu and
1381      !!              pv (3d)
1382      !!
1383      !! ** Method : The velocity components are rotated into (fwd=.TRUE.) or
1384      !!             from (fwd=.FALSE.) the frame specified by scos_wind and
1385      !!             ssin_wind; optionally, the rotation can be restricted at
1386      !!             each water column to span from the a minimum index ktop to
1387      !!             the depth index specified in array knlev
1388      !!
1389      !!----------------------------------------------------------------------     
1390      REAL(wp),           INTENT(inout), DIMENSION(jpi,jpj,jpk) ::   pu, pv           ! Components of current
1391      LOGICAL,  OPTIONAL, INTENT(in   )                         ::   fwd              ! Forward (default) or reverse rotation
1392      INTEGER,  OPTIONAL, INTENT(in   )                         ::   ktop             ! Minimum depth index
1393      INTEGER,  OPTIONAL, INTENT(in   ), DIMENSION(jpi,jpj)     ::   knlev            ! Array of maximum depth indices
1394      !
1395      INTEGER  ::   ji, jj, jk, jktop, jkmax   ! Loop indices
1396      REAL(wp) ::   ztmp, zfwd                 ! Auxiliary variables
1397      LOGICAL  ::   llkbot                     ! Auxiliary variable
1398      !
1399      IF( ln_timing ) CALL timing_start('zdf_osm_vr')
1400      !
1401      zfwd = 1.0_wp
1402      IF( PRESENT(fwd) .AND. ( fwd==.FALSE. ) ) zfwd = -1.0_wp
1403      jktop = 1
1404      IF( PRESENT(ktop) ) jktop = ktop
1405      IF( PRESENT(knlev) ) THEN
1406         jkmax = 0
1407         DO_2D( 0, 0, 0, 0 )
1408            IF ( knlev(ji,jj) > jkmax ) jkmax = knlev(ji,jj)
1409         END_2D
1410         llkbot = .FALSE.
1411      ELSE
1412         jkmax = jpk
1413         llkbot = .TRUE.
1414      END IF
1415      DO_3D( 0, 0, 0, 0, jktop, jkmax )
1416         IF ( llkbot .OR. knlev(ji,jj) >= jk ) THEN
1417            ztmp         = pu(ji,jj,jk)
1418            pu(ji,jj,jk) = pu(ji,jj,jk) * scos_wind(ji,jj) + zfwd * pv(ji,jj,jk) * ssin_wind(ji,jj)
1419            pv(ji,jj,jk) = pv(ji,jj,jk) * scos_wind(ji,jj) - zfwd * ztmp         * ssin_wind(ji,jj)
1420         END IF
1421      END_3D
1422      !
1423      IF( ln_timing ) CALL timing_stop('zdf_osm_vr')
1424      !
1425   END SUBROUTINE zdf_osm_velocity_rotation_3d
1426
1427   SUBROUTINE zdf_osm_osbl_state( Kmm, pwb_ent, pwb_min, pshear, phbl,   &
1428      &                           phml, pdh, pdb_bl, pdu_bl, pdv_bl,     &
1429      &                           pdb_ml, pdu_ml, pdv_ml )
1430      !!---------------------------------------------------------------------
1431      !!                 ***  ROUTINE zdf_osm_osbl_state  ***
1432      !!
1433      !! ** Purpose : Determines the state of the OSBL, stable/unstable,
1434      !!              shear/ noshear. Also determines shear production,
1435      !!              entrainment buoyancy flux and interfacial Richardson
1436      !!              number
1437      !!
1438      !! ** Method  :
1439      !!
1440      !!----------------------------------------------------------------------
1441      INTEGER,                  INTENT(in   ) ::   Kmm       ! Ocean time-level index
1442      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pwb_ent   ! Buoyancy fluxes at base
1443      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pwb_min   !    of well-mixed layer
1444      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pshear    ! Production of TKE due to shear across the pycnocline
1445      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   phbl      ! BL depth
1446      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   phml      ! ML depth
1447      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdh       ! Pycnocline depth
1448      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdb_bl    ! Buoyancy diff. between BL average and basal value
1449      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdu_bl    ! Velocity diff. (u) between BL average and basal value
1450      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdv_bl    ! Velocity diff. (v) between BL average and basal value
1451      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdb_ml    ! Buoyancy diff. between mixed-layer average and basal value
1452      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdu_ml    ! Velocity diff. (u) between mixed-layer average and basal value
1453      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdv_ml    ! Velocity diff. (v) between mixed-layer average and basal value
1454      !
1455      ! Local variables
1456      INTEGER :: jj, ji   ! Loop indices
1457      !
1458      REAL(wp), DIMENSION(A2D(0)) ::   zekman
1459      REAL(wp), DIMENSION(A2D(0)) ::   zri_p, zri_b   ! Richardson numbers
1460      REAL(wp)                    ::   zshear_u, zshear_v, zwb_shr
1461      REAL(wp)                    ::   zwcor, zrf_conv, zrf_shear, zrf_langmuir, zr_stokes
1462      !
1463      REAL(wp), PARAMETER ::   pp_a_shr         = 0.4_wp,  pp_b_shr    = 6.5_wp,  pp_a_wb_s = 0.8_wp
1464      REAL(wp), PARAMETER ::   pp_alpha_c       = 0.2_wp,  pp_alpha_lc = 0.03_wp
1465      REAL(wp), PARAMETER ::   pp_alpha_ls      = 0.06_wp, pp_alpha_s  = 0.15_wp
1466      REAL(wp), PARAMETER ::   pp_ri_p_thresh   = 27.0_wp
1467      REAL(wp), PARAMETER ::   pp_ri_c          = 0.25_wp
1468      REAL(wp), PARAMETER ::   pp_ek            = 4.0_wp
1469      REAL(wp), PARAMETER ::   pp_large         = -1e10_wp
1470      !
1471      IF( ln_timing ) CALL timing_start('zdf_osm_os')
1472      !
1473      ! Initialise INTENT(  out) arrays
1474      l_conv(:,:)  = .FALSE.
1475      l_shear(:,:) = .FALSE.
1476      n_ddh(:,:)   = 1
1477      pwb_ent(:,:) = pp_large
1478      pwb_min(:,:) = pp_large
1479      pshear(:,:)  = pp_large
1480      !
1481      ! Determins stability and set flag l_conv
1482      DO_2D( 0, 0, 0, 0 )
1483         IF ( shol(ji,jj) < 0._wp ) THEN
1484            l_conv(ji,jj) = .TRUE.
1485         ELSE
1486            l_conv(ji,jj) = .FALSE.
1487         ENDIF
1488      END_2D
1489      !
1490      pshear(A2D(0)) = 0._wp
1491      zekman(:,:) = EXP( -1.0_wp * pp_ek * ABS( ff_t(A2D(0)) ) * phbl(A2D(0)) / MAX(sustar(A2D(0)), 1.e-8 ) )
1492      !
1493#ifdef key_osm_debug
1494      IF(narea==nn_narea_db) THEN
1495         ji=iloc_db; jj=jloc_db
1496         WRITE(narea+100,'(a,g11.3)') &
1497            & 'zdf_osm_osbl_state start: zekman=', zekman(ji,jj)
1498         FLUSH(narea+100)
1499      END IF
1500#endif
1501      !
1502      DO_2D( 0, 0, 0, 0 )
1503         IF ( l_conv(ji,jj) ) THEN
1504            IF ( pdb_bl(ji,jj) > 0.0_wp ) THEN
1505               zri_p(ji,jj) = MAX (  SQRT( pdb_bl(ji,jj) * pdh(ji,jj) / MAX( pdu_bl(ji,jj)**2 + pdv_bl(ji,jj)**2, 1e-8_wp ) ) *   &
1506                  &                  ( phbl(ji,jj) / pdh(ji,jj) ) * ( svstr(ji,jj) / MAX( sustar(ji,jj), 1e-6_wp ) )**2 /         &
1507                  &                  MAX( zekman(ji,jj), 1.0e-6_wp )  , 5.0_wp )
1508               IF ( ff_t(ji,jj) >= 0.0_wp ) THEN   ! Northern hemisphere
1509                  zri_b(ji,jj) = pdb_ml(ji,jj) * pdh(ji,jj) / ( MAX( pdu_ml(ji,jj), 1e-5_wp )**2 +   &
1510                     &                                          MAX( -1.0_wp * pdv_ml(ji,jj), 1e-5_wp)**2 )
1511               ELSE                                ! Southern hemisphere
1512                  zri_b(ji,jj) = pdb_ml(ji,jj) * pdh(ji,jj) / ( MAX( pdu_ml(ji,jj), 1e-5_wp )**2 +   &
1513                     &                                          MAX(           pdv_ml(ji,jj), 1e-5_wp)**2 )
1514               END IF
1515               pshear(ji,jj) = pp_a_shr * zekman(ji,jj) *                                                   &
1516                  &            ( MAX( sustar(ji,jj)**2 * pdu_ml(ji,jj) / phbl(ji,jj), 0.0_wp ) +          &
1517                  &              pp_b_shr * MAX( -1.0_wp * ff_t(ji,jj) * sustke(ji,jj) * dstokes(ji,jj) *   &
1518                  &                            pdv_ml(ji,jj) / phbl(ji,jj), 0.0_wp ) )
1519#ifdef key_osm_debug
1520               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1521                  WRITE(narea+100,'(a,g11.3)')'zdf_osm_osbl_state 1st zshear: zshear=',pshear(ji,jj)
1522                  WRITE(narea+100,'(2(a,g11.3))')'zdf_osm_osbl_state 1st zshear: zri_b=',zri_b(ji,jj),' zri_p=',zri_p(ji,jj)
1523                  FLUSH(narea+100)
1524               END IF
1525#endif
1526               ! Stability dependence
1527               pshear(ji,jj) = pshear(ji,jj) * EXP( -0.75_wp * MAX( 0.0_wp, ( zri_b(ji,jj) - pp_ri_c ) / pp_ri_c ) )
1528#ifdef key_osm_debug
1529               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1530                  WRITE(narea+100,'(a,g11.3)')'zdf_osm_osbl_state 1st zshear: zshear inc ri part=',pshear(ji,jj)
1531                  FLUSH(narea+100)
1532               END IF
1533#endif
1534               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1535               ! Test ensures n_ddh=0 is not selected. Change to zri_p<27 when  !
1536               ! full code available                                          !
1537               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1538               IF ( pshear(ji,jj) > 1e-10 ) THEN
1539                  IF ( zri_p(ji,jj) < pp_ri_p_thresh .AND. MIN( hu(ji,jj,Kmm), hu(ji-1,jj,Kmm), hv(ji,jj,Kmm), hv(ji,jj-1,Kmm) ) > 100.0_wp ) THEN
1540                     ! Growing shear layer
1541                     n_ddh(ji,jj) = 0
1542                     l_shear(ji,jj) = .TRUE.
1543                  ELSE
1544                     n_ddh(ji,jj) = 1
1545                     !             IF ( zri_b <= 1.5 .and. pshear(ji,jj) > 0._wp ) THEN
1546                     ! Shear production large enough to determine layer charcteristics, but can't maintain a shear layer
1547                     l_shear(ji,jj) = .TRUE.
1548                     !             ELSE
1549                  END IF
1550               ELSE
1551                  n_ddh(ji,jj) = 2
1552                  l_shear(ji,jj) = .FALSE.
1553               END IF
1554               ! Shear production may not be zero, but is small and doesn't determine characteristics of pycnocline
1555               !               pshear(ji,jj) = 0.5 * pshear(ji,jj)
1556               !               l_shear(ji,jj) = .FALSE.
1557               !            ENDIF
1558            ELSE   ! pdb_bl test, note pshear set to zero
1559               n_ddh(ji,jj) = 2
1560               l_shear(ji,jj) = .FALSE.
1561            ENDIF
1562         ENDIF
1563      END_2D
1564      !
1565      ! Calculate entrainment buoyancy flux due to surface fluxes.
1566      DO_2D( 0, 0, 0, 0 )
1567         IF ( l_conv(ji,jj) ) THEN
1568            zwcor        = ABS( ff_t(ji,jj) ) * phbl(ji,jj) + epsln
1569            zrf_conv     = TANH( ( swstrc(ji,jj) / zwcor )**0.69_wp )
1570            zrf_shear    = TANH( ( sustar(ji,jj) / zwcor )**0.69_wp )
1571            zrf_langmuir = TANH( ( swstrl(ji,jj) / zwcor )**0.69_wp )
1572            IF ( nn_osm_SD_reduce > 0 ) THEN
1573               ! Effective Stokes drift already reduced from surface value
1574               zr_stokes = 1.0_wp
1575            ELSE
1576               ! Effective Stokes drift only reduced by factor rn_zdfodm_adjust_sd,
1577               ! requires further reduction where BL is deep
1578               zr_stokes = 1.0 - EXP( -25.0_wp * dstokes(ji,jj) / hbl(ji,jj) * ( 1.0_wp + 4.0_wp * dstokes(ji,jj) / hbl(ji,jj) ) )
1579            END IF
1580            pwb_ent(ji,jj) = -2.0_wp * pp_alpha_c * zrf_conv * swbav(ji,jj) -                                          &
1581               &             pp_alpha_s * zrf_shear * sustar(ji,jj)**3 / phml(ji,jj) +                                 &
1582               &             zr_stokes * ( pp_alpha_s * EXP( -1.5_wp * sla(ji,jj) ) * zrf_shear * sustar(ji,jj)**3 -   &
1583               &                           zrf_langmuir * pp_alpha_lc * swstrl(ji,jj)**3 ) / phml(ji,jj)
1584#ifdef key_osm_debug
1585            IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1586               WRITE(narea+100,'(a,g11.3)')'zdf_osm_osbl_state conv+shear0/lang: zwb_ent=',pwb_ent(ji,jj)
1587               FLUSH(narea+100)
1588            END IF
1589#endif
1590         ENDIF
1591      END_2D
1592      !
1593      DO_2D( 0, 0, 0, 0 )
1594         IF ( l_shear(ji,jj) ) THEN
1595            IF ( l_conv(ji,jj) ) THEN
1596               ! Unstable OSBL
1597               zwb_shr = -1.0_wp * pp_a_wb_s * zri_b(ji,jj) * pshear(ji,jj)
1598#ifdef key_osm_debug
1599               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1600                  WRITE(narea+100,'(a,g11.3)')'zdf_osm_osbl_state 1st zwb_shr: zwb_shr=',zwb_shr
1601                  FLUSH(narea+100)
1602               END IF
1603#endif
1604               IF ( n_ddh(ji,jj) == 0 ) THEN
1605                  ! Developing shear layer, additional shear production possible.
1606
1607                  !              pshear_u = MAX( zustar(ji,jj)**2 * MAX( pdu_ml(ji,jj), 0._wp ) /  phbl(ji,jj), 0._wp )
1608                  !              pshear(ji,jj) = pshear(ji,jj) + pshear_u * ( 1.0 - MIN( zri_p(ji,jj) / pp_ri_p_thresh, 1.d0 )**2 )
1609                  !              pshear(ji,jj) = MIN( pshear(ji,jj), pshear_u )
1610
1611                  !              zwb_shr = zwb_shr - 0.25 * MAX ( pshear_u, 0._wp) * ( 1.0 - MIN( zri_p(ji,jj) / pp_ri_p_thresh, 1._wp )**2 )
1612                  !              zwb_shr = MAX( zwb_shr, -0.25 * pshear_u )
1613#ifdef key_osm_debug
1614                  IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1615                     WRITE(narea+100,'(3(a,g11.3))')'zdf_osm_osbl_state j_ddh(ji,jj) == 0:zwb_shr=',zwb_shr, &
1616                        & '  zshear=',pshear(ji,jj),'  zshear_u=', pshear_u
1617                     FLUSH(narea+100)
1618                  END IF
1619#endif
1620               ENDIF
1621               pwb_ent(ji,jj) = pwb_ent(ji,jj) + zwb_shr
1622               !           pwb_min(ji,jj) = pwb_ent(ji,jj) + pdh(ji,jj) / phbl(ji,jj) * zwb0(ji,jj)
1623            ELSE   ! IF ( l_conv ) THEN - ENDIF
1624               ! Stable OSBL  - shear production not coded for first attempt.
1625            ENDIF   ! l_conv
1626         END IF   ! l_shear
1627         IF ( l_conv(ji,jj) ) THEN
1628            ! Unstable OSBL
1629            pwb_min(ji,jj) = pwb_ent(ji,jj) + pdh(ji,jj) / phbl(ji,jj) * 2.0_wp * swbav(ji,jj)
1630         END IF  ! l_conv
1631#ifdef key_osm_debug
1632         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1633            WRITE(narea+100,'(3(a,g11.3))')'end of zdf_osm_osbl_state:zwb_ent=',pwb_ent(ji,jj), &
1634               & '  zwb_min=',pwb_min(ji,jj), '  zwb0tot=', zwb0tot(ji,jj), '  swbav= ', swbav(ji,jj)
1635            FLUSH(narea+100)
1636         END IF
1637#endif
1638      END_2D
1639      !
1640      IF( ln_timing ) CALL timing_stop('zdf_osm_os')
1641      !
1642   END SUBROUTINE zdf_osm_osbl_state
1643
1644   SUBROUTINE zdf_osm_external_gradients( Kmm, kbase, pdtdz, pdsdz, pdbdz )
1645      !!---------------------------------------------------------------------
1646      !!                   ***  ROUTINE zdf_osm_external_gradients  ***
1647      !!
1648      !! ** Purpose : Calculates the gradients below the OSBL
1649      !!
1650      !! ** Method  : Uses nbld and ibld_ext to determine levels to calculate the gradient.
1651      !!
1652      !!----------------------------------------------------------------------   
1653      INTEGER,                      INTENT(in   ) ::   Kmm                   ! Ocean time-level index
1654      INTEGER,  DIMENSION(jpi,jpj), INTENT(in   ) ::   kbase                 ! OSBL base layer index
1655      REAL(wp), DIMENSION(A2D(0)),  INTENT(  out) ::   pdtdz, pdsdz, pdbdz   ! External gradients of temperature, salinity and buoyancy
1656      !
1657      ! Local variables
1658      INTEGER  ::   ji, jj, jkb, jkb1
1659      REAL(wp) ::   zthermal, zbeta
1660      !
1661      REAL(wp), PARAMETER ::   pp_large = -1e10_wp
1662      !
1663      IF( ln_timing ) CALL timing_start('zdf_osm_eg')
1664      !
1665      pdtdz(:,:) = pp_large
1666      pdsdz(:,:) = pp_large
1667      pdbdz(:,:) = pp_large
1668      !
1669      DO_2D( 0, 0, 0, 0 )
1670         IF ( kbase(ji,jj)+1 < mbkt(ji,jj) ) THEN
1671            zthermal = rab_n(ji,jj,1,jp_tem)   ! Ideally use nbld not 1??
1672            zbeta    = rab_n(ji,jj,1,jp_sal)
1673            jkb = kbase(ji,jj)
1674            jkb1 = MIN( jkb + 1, mbkt(ji,jj) )
1675            pdtdz(ji,jj) = -1.0_wp * ( ts(ji,jj,jkb1,jp_tem,Kmm) - ts(ji,jj,jkb,jp_tem,Kmm ) ) / e3w(ji,jj,jkb1,Kmm)
1676            pdsdz(ji,jj) = -1.0_wp * ( ts(ji,jj,jkb1,jp_sal,Kmm) - ts(ji,jj,jkb,jp_sal,Kmm ) ) / e3w(ji,jj,jkb1,Kmm)
1677            pdbdz(ji,jj) = grav * zthermal * pdtdz(ji,jj) - grav * zbeta * pdsdz(ji,jj)
1678         ELSE
1679            pdtdz(ji,jj) = 0.0_wp
1680            pdsdz(ji,jj) = 0.0_wp
1681            pdbdz(ji,jj) = 0.0_wp
1682         END IF
1683      END_2D
1684      !
1685      IF( ln_timing ) CALL timing_stop('zdf_osm_eg')
1686      !
1687   END SUBROUTINE zdf_osm_external_gradients
1688
1689   SUBROUTINE zdf_osm_calculate_dhdt( pdhdt, phbl, pdh, pwb_ent, pwb_min,               &
1690      &                               pdb_bl, pdbdz_bl_ext, pdb_ml, pwb_fk_b, pwb_fk,   &
1691      &                               pvel_mle )
1692      !!---------------------------------------------------------------------
1693      !!                   ***  ROUTINE zdf_osm_calculate_dhdt  ***
1694      !!
1695      !! ** Purpose : Calculates the rate at which hbl changes.
1696      !!
1697      !! ** Method  :
1698      !!
1699      !!----------------------------------------------------------------------
1700      REAL(wp), DIMENSION(A2D(0)), INTENT(  out) ::   pdhdt          ! Rate of change of hbl
1701      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl           ! BL depth
1702      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdh            ! Pycnocline depth
1703      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_ent        ! Buoyancy entrainment flux
1704      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_min
1705      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_bl         ! Buoyancy diff. between BL average and basal value
1706      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdbdz_bl_ext   ! External buoyancy gradients
1707      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_ml         ! Buoyancy diff. between mixed-layer average and basal value
1708      REAL(wp), DIMENSION(:,:),    INTENT(  out) ::   pwb_fk_b       ! MLE buoyancy flux averaged over OSBL
1709      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_fk         ! Max MLE buoyancy flux
1710      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pvel_mle       ! Vvelocity scale for dhdt with stable ML and FK
1711      !
1712      ! Local variables
1713      INTEGER  ::   jj, ji
1714      REAL(wp) ::   zgamma_b_nd, zgamma_dh_nd, zpert, zpsi, zari
1715      REAL(wp) ::   zvel_max, zddhdt
1716      !
1717      REAL(wp), PARAMETER ::   pp_alpha_b = 0.3_wp
1718      REAL(wp), PARAMETER ::   pp_ddh     = 2.5_wp, pp_ddh_2 = 3.5_wp   ! Also in pycnocline_depth
1719      REAL(wp), PARAMETER ::   pp_large   = -1e10_wp
1720      !
1721      IF( ln_timing ) CALL timing_start('zdf_osm_cd')
1722      !
1723      pdhdt(:,:)    = pp_large
1724      pwb_fk_b(:,:) = pp_large
1725      !
1726      DO_2D( 0, 0, 0, 0 )
1727         !
1728         IF ( l_shear(ji,jj) ) THEN
1729            !
1730            IF ( l_conv(ji,jj) ) THEN   ! Convective
1731               !
1732               IF ( ln_osm_mle ) THEN
1733                  IF ( hmle(ji,jj) > hbl(ji,jj) ) THEN   ! Fox-Kemper buoyancy flux average over OSBL
1734                     pwb_fk_b(ji,jj) = pwb_fk(ji,jj) * ( 1.0_wp + hmle(ji,jj) / ( 6.0_wp * hbl(ji,jj) ) *   &
1735                        &                                         ( -1.0_wp + ( 1.0_wp - 2.0_wp * hbl(ji,jj) / hmle(ji,jj) )**3 ) )
1736                  ELSE
1737                     pwb_fk_b(ji,jj) = 0.5_wp * pwb_fk(ji,jj) * hmle(ji,jj) / hbl(ji,jj)
1738                  ENDIF
1739                  zvel_max = ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**p2third / hbl(ji,jj)
1740                  IF ( ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) < 0.0_wp ) THEN   ! OSBL is deepening,
1741                     !                                                                 !    entrainment > restratification
1742                     IF ( pdb_bl(ji,jj) > 1e-15_wp ) THEN
1743                        zgamma_b_nd = MAX( pdbdz_bl_ext(ji,jj), 0.0_wp ) * pdh(ji,jj) / ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1744                        zpsi = ( 1.0_wp - 0.5_wp * pdh(ji,jj) / phbl(ji,jj) ) *   &
1745                           &   ( swb0(ji,jj) - MIN( ( pwb_min(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ), 0.0_wp ) ) * pdh(ji,jj) / phbl(ji,jj)
1746                        zpsi = zpsi + 1.75_wp * ( 1.0_wp - 0.5_wp * pdh(ji,jj) / phbl(ji,jj) ) *   &
1747                           &   ( pdh(ji,jj) / phbl(ji,jj) + zgamma_b_nd ) * MIN( ( pwb_min(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ), 0.0_wp )
1748                        zpsi = pp_alpha_b * MAX( zpsi, 0.0_wp )
1749                        pdhdt(ji,jj) = -1.0_wp * ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) /   &
1750                           &                      ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) ) +   &
1751                           &            zpsi / ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1752#ifdef key_osm_debug
1753                        IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1754                           WRITE(narea+100,'(a,g11.3)')'Inside 1st major loop of zdf_osm_calculate_dhdt, OSBL is deepening, entrainment > restratification:  zdhdt=',pdhdt(ji,jj)
1755                           WRITE(narea+100,'(3(a,g11.3))') '  zpsi=',zpsi, '  zgamma_b_nd=', zgamma_b_nd, '  zdh=', pdh(ji,jj)
1756                           FLUSH(narea+100)
1757                        END IF
1758#endif
1759                        IF ( n_ddh(ji,jj) == 1 ) THEN
1760                           IF ( ( swstrc(ji,jj) / svstr(ji,jj) )**3 <= 0.5_wp ) THEN
1761                              zari = MIN( 1.5_wp * pdb_bl(ji,jj) /                                                   &
1762                                 &        ( phbl(ji,jj) * ( MAX( pdbdz_bl_ext(ji,jj), 0.0_wp ) +                     &
1763                                 &                               pdb_bl(ji,jj)**2 / MAX( 4.5_wp * svstr(ji,jj)**2,   &
1764                                 &                                                       1e-12_wp ) ) ), 0.2_wp )
1765                           ELSE
1766                              zari = MIN( 1.5_wp * pdb_bl(ji,jj) /                                                    &
1767                                 &        ( phbl(ji,jj) * ( MAX( pdbdz_bl_ext(ji,jj), 0.0_wp ) +                      &
1768                                 &                               pdb_bl(ji,jj)**2 / MAX( 4.5_wp * swstrc(ji,jj)**2,   &
1769                                 &                                                       1e-12_wp ) ) ), 0.2_wp )
1770                           ENDIF
1771                           ! Relaxation to dh_ref = zari * hbl
1772                           zddhdt = -1.0_wp * pp_ddh_2 * ( 1.0_wp - pdh(ji,jj) / ( zari * phbl(ji,jj) ) ) * pwb_ent(ji,jj) /   &
1773                              &     ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1774#ifdef key_osm_debug
1775                           IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1776                              WRITE(narea+100,'(a,g11.3)')'Inside 1st major loop of zdf_osm_calculate_dhdt,j_ddh(ji,jj) == 1:  zari=',zari
1777                              FLUSH(narea+100)
1778                           END IF
1779#endif
1780                        ELSE IF ( n_ddh(ji,jj) == 0 ) THEN   ! Growing shear layer
1781                           zddhdt = -1.0_wp * pp_ddh * ( 1.0_wp - 1.6_wp * pdh(ji,jj) / phbl(ji,jj) ) * pwb_ent(ji,jj) /   &
1782                              &     ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1783                           zddhdt = EXP( -4.0_wp * ABS( ff_t(ji,jj) ) * phbl(ji,jj) / MAX(sustar(ji,jj), 1e-8_wp ) ) * zddhdt
1784                        ELSE
1785                           zddhdt = 0.0_wp
1786                        ENDIF   ! n_ddh
1787                        pdhdt(ji,jj) = pdhdt(ji,jj) + pp_alpha_b * ( 1.0_wp - 0.5_wp * pdh(ji,jj) / phbl(ji,jj) ) *   &
1788                           &                            pdb_ml(ji,jj) * MAX( zddhdt, 0.0_wp ) /   &
1789                           &                            ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1790                     ELSE   ! pdb_bl >0
1791                        pdhdt(ji,jj) = -1.0_wp * ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) /  MAX( zvel_max, 1e-15_wp )
1792                     ENDIF
1793                  ELSE   ! pwb_min + 2*pwb_fk_b < 0
1794                     ! OSBL shoaling due to restratification flux. This is the velocity defined in Fox-Kemper et al (2008)
1795                     pdhdt(ji,jj) = -1.0_wp * MIN( pvel_mle(ji,jj), hbl(ji,jj) / 10800.0_wp )
1796                  ENDIF
1797               ELSE   ! Fox-Kemper not used.
1798                  zvel_max = -1.0_wp * ( 1.0_wp + 1.0_wp * ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird *     &
1799                     &                                                         rn_Dt / hbl(ji,jj) ) * pwb_ent(ji,jj) /   &
1800                     &       MAX( ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird, epsln )
1801                  pdhdt(ji,jj) = -1.0_wp * pwb_ent(ji,jj) / ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1802                  ! added ajgn 23 July as temporay fix
1803               ENDIF   ! ln_osm_mle
1804               !
1805            ELSE   ! l_conv - Stable
1806               !
1807               pdhdt(ji,jj) = ( 0.06_wp + 0.52_wp * shol(ji,jj) / 2.0_wp ) * svstr(ji,jj)**3 / hbl(ji,jj) + swbav(ji,jj)
1808               IF ( pdhdt(ji,jj) < 0.0_wp ) THEN   ! For long timsteps factor in brackets slows the rapid collapse of the OSBL
1809                  zpert = 2.0_wp * ( 1.0_wp + 0.0_wp * 2.0_wp * svstr(ji,jj) * rn_Dt / hbl(ji,jj) ) * svstr(ji,jj)**2 / hbl(ji,jj)
1810               ELSE
1811                  zpert = MAX( svstr(ji,jj)**2 / hbl(ji,jj), pdb_bl(ji,jj) )
1812               ENDIF
1813               pdhdt(ji,jj) = 2.0_wp * pdhdt(ji,jj) / MAX( zpert, epsln )
1814               pdhdt(ji,jj) = MAX( pdhdt(ji,jj), -1.0_wp * hbl(ji,jj) / 5400.0_wp )
1815               !
1816            ENDIF   ! l_conv
1817            !
1818         ELSE   ! l_shear
1819            !
1820            IF ( l_conv(ji,jj) ) THEN   ! Convective
1821               !
1822               IF ( ln_osm_mle ) THEN
1823                  IF ( hmle(ji,jj) > hbl(ji,jj) ) THEN   ! Fox-Kemper buoyancy flux average over OSBL
1824                     pwb_fk_b(ji,jj) = pwb_fk(ji,jj) *                       &
1825                        ( 1.0_wp + hmle(ji,jj) / ( 6.0_wp * hbl(ji,jj) ) *   &
1826                        &          ( -1.0_wp + ( 1.0_wp - 2.0_wp * hbl(ji,jj) / hmle(ji,jj))**3) )
1827                  ELSE
1828                     pwb_fk_b(ji,jj) = 0.5_wp * pwb_fk(ji,jj) * hmle(ji,jj) / hbl(ji,jj)
1829                  ENDIF
1830                  zvel_max = ( swstrl(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**p2third / hbl(ji,jj)
1831                  IF ( ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) < 0.0_wp ) THEN   ! OSBL is deepening,
1832                     !                                                                 !    entrainment > restratification
1833                     IF ( pdb_bl(ji,jj) > 0.0_wp .AND. pdbdz_bl_ext(ji,jj) > 0.0_wp ) THEN
1834                        pdhdt(ji,jj) = -1.0_wp * ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) /   &
1835                           &            ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1836                     ELSE
1837                        pdhdt(ji,jj) = -1.0_wp * ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) / MAX( zvel_max, 1e-15_wp )
1838                     ENDIF
1839                  ELSE   ! OSBL shoaling due to restratification flux. This is the velocity defined in Fox-Kemper et al (2008)
1840                     pdhdt(ji,jj) = -1.0_wp * MIN( pvel_mle(ji,jj), hbl(ji,jj) / 10800.0_wp )
1841                  ENDIF
1842               ELSE   ! Fox-Kemper not used
1843                  zvel_max = -1.0_wp * pwb_ent(ji,jj) / MAX( ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird, epsln )
1844                  pdhdt(ji,jj) = -1.0_wp * pwb_ent(ji,jj) / ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15_wp ) )
1845                  ! added ajgn 23 July as temporay fix
1846               ENDIF  ! ln_osm_mle
1847               !
1848            ELSE                        ! Stable
1849               !
1850               pdhdt(ji,jj) = ( 0.06_wp + 0.52_wp * shol(ji,jj) / 2.0_wp ) * svstr(ji,jj)**3 / hbl(ji,jj) + swbav(ji,jj)
1851               IF ( pdhdt(ji,jj) < 0.0_wp ) THEN
1852                  ! For long timsteps factor in brackets slows the rapid collapse of the OSBL
1853                  zpert = 2.0_wp * svstr(ji,jj)**2 / hbl(ji,jj)
1854               ELSE
1855                  zpert = MAX( svstr(ji,jj)**2 / hbl(ji,jj), pdb_bl(ji,jj) )
1856               ENDIF
1857               pdhdt(ji,jj) = 2.0_wp * pdhdt(ji,jj) / MAX(zpert, epsln)
1858               pdhdt(ji,jj) = MAX( pdhdt(ji,jj), -1.0_wp * hbl(ji,jj) / 5400.0_wp )
1859               !
1860            ENDIF  ! l_conv
1861            !
1862         ENDIF ! l_shear
1863#ifdef key_osm_debug
1864         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1865            WRITE(narea+100,'(4(a,g11.3))')'end of 1st major loop of zdf_osm_calculate_dhdt:  zdhdt=',pdhdt(ji,jj), &
1866               &  '  zpert=', zpert, '  zddhdt=', zddhdt, '  zvel_max=', zvel_max
1867            IF ( ln_osm_mle ) THEN
1868               WRITE(narea+100,'(3(a,g11.3),/)') 'zvel_mle=',pvel_mle(ji,jj), ' zwb_fk_b=', pwb_fk_b(ji,jj), &
1869                  & '  zwb_ent + 2*zwb_fk_b =', pwb_ent(ji,jj) + 2.0 * pwb_fk_b(ji,jj)
1870               FLUSH(narea+100)
1871            END IF
1872         END IF
1873#endif
1874         !
1875      END_2D
1876      !
1877      IF( ln_timing ) CALL timing_stop('zdf_osm_cd')
1878      !
1879   END SUBROUTINE zdf_osm_calculate_dhdt
1880
1881   SUBROUTINE zdf_osm_timestep_hbl( Kmm, pdhdt, phbl, phbl_t, pwb_ent,   &
1882      &                             pwb_fk_b )
1883      !!---------------------------------------------------------------------
1884      !!                ***  ROUTINE zdf_osm_timestep_hbl  ***
1885      !!
1886      !! ** Purpose : Increments hbl.
1887      !!
1888      !! ** Method  : If the change in hbl exceeds one model level the change is
1889      !!              is calculated by moving down the grid, changing the
1890      !!              buoyancy jump. This is to ensure that the change in hbl
1891      !!              does not overshoot a stable layer.
1892      !!
1893      !!----------------------------------------------------------------------
1894      INTEGER,                     INTENT(in   ) ::   Kmm        ! Ocean time-level index
1895      REAL(wp), DIMENSION(A2D(0)), INTENT(inout) ::   pdhdt      ! Rates of change of hbl
1896      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   phbl       ! BL depth
1897      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl_t     ! BL depth
1898      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_ent    ! Buoyancy entrainment flux
1899      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_fk_b   ! MLE buoyancy flux averaged over OSBL
1900      !
1901      ! Local variables
1902      INTEGER  ::   jk, jj, ji, jm
1903      REAL(wp) ::   zhbl_s, zvel_max, zdb
1904      REAL(wp) ::   zthermal, zbeta
1905      !
1906      IF( ln_timing ) CALL timing_start('zdf_osm_th')
1907      !
1908      DO_2D( 0, 0, 0, 0 )
1909#ifdef key_osm_debug
1910         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1911            WRITE(narea+100,'(2(a,i7))')'start of zdf_osm_timestep_hbl: old ibld=',nmld(ji,jj),' trial ibld=', nbld(ji,jj)
1912            FLUSH(narea+100)
1913         END IF
1914#endif
1915         IF ( nbld(ji,jj) - nmld(ji,jj) > 1 ) THEN
1916            !
1917            ! If boundary layer changes by more than one level, need to check for stable layers between initial and final depths.
1918            !
1919            zhbl_s   = hbl(ji,jj)
1920            jm       = nmld(ji,jj)
1921            zthermal = rab_n(ji,jj,1,jp_tem)
1922            zbeta    = rab_n(ji,jj,1,jp_sal)
1923            !
1924            IF ( l_conv(ji,jj) ) THEN   ! Unstable
1925               !
1926               IF( ln_osm_mle ) THEN
1927                  zvel_max = ( swstrl(ji,jj)**3 + swstrc(ji,jj)**3 )**p2third / hbl(ji,jj)
1928               ELSE
1929                  zvel_max = -1.0_wp * ( 1.0_wp + 1.0_wp * ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird * rn_Dt /   &
1930                     &                                     hbl(ji,jj) ) * pwb_ent(ji,jj) /                                     &
1931                     &       ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird
1932               ENDIF
1933#ifdef key_osm_debug
1934               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1935                  WRITE(narea+100,'(a,g11.3)')'In zdf_osm_timestep_hbl, ibld - imld > 1, lconv=T: zvel_max=',zvel_max
1936                  FLUSH(narea+100)
1937               END IF
1938#endif
1939               DO jk = nmld(ji,jj), nbld(ji,jj)
1940                  zdb = MAX( grav * ( zthermal * ( av_t_bl(ji,jj) - ts(ji,jj,jm,jp_tem,Kmm) ) -   &
1941                     &                zbeta    * ( av_s_bl(ji,jj) - ts(ji,jj,jm,jp_sal,Kmm) ) ), 0.0_wp ) + zvel_max
1942                  !
1943                  IF ( ln_osm_mle ) THEN
1944                     zhbl_s = zhbl_s + MIN( rn_Dt * ( ( -1.0_wp * pwb_ent(ji,jj) - 2.0_wp * pwb_fk_b(ji,jj) ) / zdb ) /   &
1945                        &                   REAL( nbld(ji,jj) - nmld(ji,jj), KIND=wp ), e3w(ji,jj,jm,Kmm) )
1946                  ELSE
1947                     zhbl_s = zhbl_s + MIN( rn_Dt * ( -1.0_wp * pwb_ent(ji,jj) / zdb ) /   &
1948                        &                   REAL( nbld(ji,jj) - nmld(ji,jj), KIND=wp ), e3w(ji,jj,jm,Kmm) )
1949                  ENDIF
1950                  !                    zhbl_s = MIN(zhbl_s,  gdepw(ji,jj, mbkt(ji,jj) + 1,Kmm) - depth_tol)
1951                  IF ( zhbl_s >= gdepw(ji,jj,mbkt(ji,jj) + 1,Kmm) ) THEN
1952                     zhbl_s = MIN( zhbl_s, gdepw(ji,jj, mbkt(ji,jj) + 1, Kmm ) - depth_tol )
1953                     l_pyc(ji,jj) = .FALSE.
1954                  ENDIF
1955                  IF ( zhbl_s >= gdepw(ji,jj,jm+1,Kmm) ) jm = jm + 1
1956#ifdef key_osm_debug
1957                  IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1958                     WRITE(narea+100,'(2(a,i7))')' jk=',jk,' jm=', jm
1959                     WRITE(narea+100,'(2(a,g11.3),a,l7)')'zdb=',zdb,' zhbl_s=', zhbl_s,' lpyc=',l_pyc(ji,jj)
1960                     FLUSH(narea+100)
1961                  END IF
1962#endif
1963               END DO
1964               hbl(ji,jj)  = zhbl_s
1965               nbld(ji,jj) = jm
1966            ELSE   ! Stable
1967#ifdef key_osm_debug
1968               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1969                  WRITE(narea+100,'(a)')'In zdf_osm_timestep_hbl, ibld - imld > 1, lconv=F'
1970                  FLUSH(narea+100)
1971               END IF
1972#endif
1973               DO jk = nmld(ji,jj), nbld(ji,jj)
1974                  zdb = MAX(  grav * ( zthermal * ( av_t_bl(ji,jj) - ts(ji,jj,jm,jp_tem,Kmm) ) -               &
1975                     &                 zbeta    * ( av_s_bl(ji,jj) - ts(ji,jj,jm,jp_sal,Kmm) ) ), 0.0_wp ) +   &
1976                     &  2.0 * svstr(ji,jj)**2 / zhbl_s
1977                  !
1978                  ! Alan is thuis right? I have simply changed hbli to hbl
1979                  shol(ji,jj)  = -1.0_wp * zhbl_s / ( ( svstr(ji,jj)**3 + epsln ) / swbav(ji,jj) )
1980                  pdhdt(ji,jj) = -1.0_wp * ( swbav(ji,jj) - 0.04_wp / 2.0_wp * swstrl(ji,jj)**3 / zhbl_s -   &
1981                     &                       0.15_wp / 2.0_wp * ( 1.0_wp - EXP( -1.5_wp * sla(ji,jj) ) ) *   &
1982                     &                                 sustar(ji,jj)**3 / zhbl_s ) *                         &
1983                     &           ( 0.725_wp + 0.225_wp * EXP( -7.5_wp * shol(ji,jj) ) )
1984                  pdhdt(ji,jj) = pdhdt(ji,jj) + swbav(ji,jj)
1985                  zhbl_s = zhbl_s + MIN( pdhdt(ji,jj) / zdb * rn_Dt / REAL( nbld(ji,jj) - nmld(ji,jj), KIND=wp ),   &
1986                     &                   e3w(ji,jj,jm,Kmm) )
1987                 
1988                  !                    zhbl_s = MIN(zhbl_s, gdepw(ji,jj, mbkt(ji,jj) + 1,Kmm) - depth_tol)
1989                  IF ( zhbl_s >= mbkt(ji,jj) + 1 ) THEN
1990                     zhbl_s      = MIN( zhbl_s,  gdepw(ji,jj,mbkt(ji,jj)+1,Kmm) - depth_tol )
1991                     l_pyc(ji,jj) = .FALSE.
1992                  ENDIF
1993                  IF ( zhbl_s >= gdepw(ji,jj,jm,Kmm) ) jm = jm + 1
1994#ifdef key_osm_debug
1995                  IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
1996                     WRITE(narea+100,'(2(a,i7))')' jk=',jk,' jm=', jm
1997                     WRITE(narea+100,'(4(a,g11.3),a,l7)')'zdb=',zdb,' shol',shol(ji,jj),' zdhdt',pdhdt(ji,jj),' zhbl_s=', zhbl_s,' lpyc=',l_pyc(ji,jj)
1998                     FLUSH(narea+100)
1999                  END IF
2000#endif
2001               END DO
2002            ENDIF   ! IF ( l_conv )
2003            hbl(ji,jj)  = MAX( zhbl_s, gdepw(ji,jj,4,Kmm) )
2004            nbld(ji,jj) = MAX( jm, 4 )
2005         ELSE
2006            ! change zero or one model level.
2007            hbl(ji,jj) = MAX( phbl_t(ji,jj), gdepw(ji,jj,4,Kmm) )
2008         ENDIF
2009         phbl(ji,jj) = gdepw(ji,jj,nbld(ji,jj),Kmm)
2010#ifdef key_osm_debug
2011         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2012            WRITE(narea+100,'(2(a,g11.3),a,i7,/)')'end of zdf_osm_timestep_hbl: hbl=', hbl(ji,jj),' zhbl=', phbl(ji,jj),' ibld=', nbld(ji,jj)
2013            FLUSH(narea+100)
2014         END IF
2015#endif
2016      END_2D
2017      !
2018      IF( ln_timing ) CALL timing_stop('zdf_osm_th')
2019      !
2020   END SUBROUTINE zdf_osm_timestep_hbl
2021
2022   SUBROUTINE zdf_osm_pycnocline_thickness( Kmm, pdh, phml, pdhdt, pdb_bl,   &
2023      &                                     phbl, pwb_ent, pdbdz_bl_ext, pwb_fk_b )
2024      !!---------------------------------------------------------------------
2025      !!            ***  ROUTINE zdf_osm_pycnocline_thickness  ***
2026      !!
2027      !! ** Purpose : Calculates thickness of the pycnocline
2028      !!
2029      !! ** Method  : The thickness is calculated from a prognostic equation
2030      !!              that relaxes the pycnocine thickness to a diagnostic
2031      !!              value. The time change is calculated assuming the
2032      !!              thickness relaxes exponentially. This is done to deal
2033      !!              with large timesteps.
2034      !!
2035      !!----------------------------------------------------------------------
2036      INTEGER,                     INTENT(in   ) ::   Kmm            ! Ocean time-level index
2037      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   pdh            ! Pycnocline thickness
2038      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   phml           ! ML depth
2039      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdhdt          ! BL depth tendency
2040      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_bl         ! Buoyancy diff. between BL average and basal value
2041      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl           ! BL depth
2042      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_ent        ! Buoyancy entrainment flux
2043      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdbdz_bl_ext   ! External buoyancy gradients
2044      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_fk_b       ! MLE buoyancy flux averaged over OSBL
2045
2046      !
2047      ! Local variables
2048      INTEGER  ::   jj, ji
2049      INTEGER  ::   inhml
2050      REAL(wp) ::   zari, ztau, zdh_ref, zddhdt, zvel_max
2051      REAL(wp) ::   ztmp   ! Auxiliary variable
2052      !
2053      REAL, PARAMETER ::   pp_ddh = 2.5_wp, pp_ddh_2 = 3.5_wp   ! Also in pycnocline_depth
2054      !
2055      IF( ln_timing ) CALL timing_start('zdf_osm_pt')
2056      !
2057      DO_2D( 0, 0, 0, 0 )
2058         !
2059         IF ( l_shear(ji,jj) ) THEN
2060            !
2061            IF ( l_conv(ji,jj) ) THEN
2062               !
2063               IF ( pdb_bl(ji,jj) > 1e-15_wp ) THEN
2064                  IF ( n_ddh(ji,jj) == 0 ) THEN
2065                     zvel_max = ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**p2third / hbl(ji,jj)
2066                     ! ddhdt for pycnocline determined in osm_calculate_dhdt
2067                     zddhdt = -1.0_wp * pp_ddh * ( 1.0_wp - 1.6_wp * pdh(ji,jj) / phbl(ji,jj) ) * pwb_ent(ji,jj) /   &
2068                        &     ( zvel_max + MAX( pdb_bl(ji,jj), 1e-15 ) )
2069                     zddhdt = EXP( -4.0_wp * ABS( ff_t(ji,jj) ) * phbl(ji,jj) / MAX( sustar(ji,jj), 1e-8 ) ) * zddhdt
2070                     ! Maximum limit for how thick the shear layer can grow relative to the thickness of the boundary layer
2071                     dh(ji,jj) = MIN( dh(ji,jj) + zddhdt * rn_Dt, 0.625_wp * hbl(ji,jj) )
2072                  ELSE   ! Need to recalculate because hbl has been updated
2073                     IF ( ( swstrc(ji,jj) / svstr(ji,jj) )**3 <= 0.5_wp ) THEN
2074                        ztmp = svstr(ji,jj)
2075                     ELSE
2076                        ztmp = swstrc(ji,jj)
2077                     END IF
2078                     zari = MIN( 1.5_wp * pdb_bl(ji,jj) / ( phbl(ji,jj) * ( MAX( pdbdz_bl_ext(ji,jj), 0.0_wp ) +        &
2079                        &                                                   pdb_bl(ji,jj)**2 / MAX( 4.5_wp * ztmp**2,   &
2080                        &                                                                           1e-12_wp ) ) ), 0.2_wp )
2081                     ztau = MAX( pdb_bl(ji,jj) * ( zari * hbl(ji,jj) ) / ( pp_ddh_2 * MAX( -1.0_wp * pwb_ent(ji,jj), 1e-12_wp ) ),   &
2082                        &        2.0_wp * rn_Dt )
2083                     dh(ji,jj) = dh(ji,jj) * EXP( -1.0_wp * rn_Dt / ztau ) +   &
2084                        &        zari * phbl(ji,jj) * ( 1.0_wp - EXP( -1.0_wp * rn_Dt / ztau ) )
2085                     IF ( dh(ji,jj) >= hbl(ji,jj) ) dh(ji,jj) = zari * phbl(ji,jj)
2086                  END IF
2087               ELSE
2088                  ztau = MAX( MAX( hbl(ji,jj) / ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird, epsln), 2.0_wp * rn_Dt )
2089                  dh(ji,jj) = dh(ji,jj) * EXP( -1.0_wp * rn_Dt / ztau ) +   &
2090                     &        0.2_wp * phbl(ji,jj) * ( 1.0_wp - EXP( -1.0_wp * rn_Dt / ztau ) )
2091                  IF ( dh(ji,jj) > hbl(ji,jj) ) dh(ji,jj) = 0.2_wp * hbl(ji,jj)
2092               END IF
2093               !
2094            ELSE   ! l_conv
2095               ! Initially shear only for entraining OSBL. Stable code will be needed if extended to stable OSBL
2096               ztau = hbl(ji,jj) / MAX(svstr(ji,jj), epsln)
2097               IF ( pdhdt(ji,jj) >= 0.0_wp ) THEN   ! Probably shouldn't include wm here
2098                  ! Boundary layer deepening
2099                  IF ( pdb_bl(ji,jj) > 0.0_wp ) THEN
2100                     ! Pycnocline thickness set by stratification - use same relationship as for neutral conditions
2101                     zari    = MIN( 4.5_wp * ( svstr(ji,jj)**2 ) / MAX( pdb_bl(ji,jj) * phbl(ji,jj), epsln ) + 0.01_wp, 0.2_wp )
2102                     zdh_ref = MIN( zari, 0.2_wp ) * hbl(ji,jj)
2103                  ELSE
2104                     zdh_ref = 0.2_wp * hbl(ji,jj)
2105                  ENDIF
2106               ELSE   ! IF(dhdt < 0)
2107                  zdh_ref = 0.2_wp * hbl(ji,jj)
2108               ENDIF   ! IF (dhdt >= 0)
2109               dh(ji,jj) = dh(ji,jj) * EXP( -1.0_wp * rn_Dt / ztau ) + zdh_ref * ( 1.0_wp - EXP( -1.0_wp * rn_Dt / ztau ) )
2110               IF ( pdhdt(ji,jj) < 0.0_wp .AND. dh(ji,jj) >= hbl(ji,jj) ) dh(ji,jj) = zdh_ref   ! Can be a problem with dh>hbl for
2111               !                                                                                !    rapid collapse
2112            ENDIF
2113            !
2114         ELSE   ! l_shear = .FALSE., calculate ddhdt here
2115            !
2116            IF ( l_conv(ji,jj) ) THEN
2117               !
2118               IF( ln_osm_mle ) THEN
2119                  IF ( ( pwb_ent(ji,jj) + 2.0_wp * pwb_fk_b(ji,jj) ) < 0.0_wp ) THEN   ! OSBL is deepening. Note wb_fk_b is zero if
2120                     !                                                                 !    ln_osm_mle=F
2121                     IF ( pdb_bl(ji,jj) > 0.0_wp .AND. pdbdz_bl_ext(ji,jj) > 0.0_wp ) THEN
2122                        IF ( ( swstrc(ji,jj) / MAX( svstr(ji,jj), epsln) )**3 <= 0.5_wp ) THEN   ! Near neutral stability
2123                           ztmp = svstr(ji,jj)
2124                        ELSE   ! Unstable
2125                           ztmp = swstrc(ji,jj)
2126                        END IF
2127                        zari = MIN( 1.5_wp * pdb_bl(ji,jj) / ( phbl(ji,jj) *                           &
2128                           &                                   ( MAX( pdbdz_bl_ext(ji,jj), 0.0_wp) +   &
2129                           &                                     pdb_bl(ji,jj)**2 / MAX(4.5_wp * ztmp**2 , 1e-12_wp ) ) ), 0.2_wp )
2130                     ELSE
2131                        zari = 0.2_wp
2132                     END IF
2133                  ELSE
2134                     zari = 0.2_wp
2135                  END IF
2136                  ztau    = 0.2_wp * hbl(ji,jj) / MAX( epsln, ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird )
2137                  zdh_ref = zari * hbl(ji,jj)
2138               ELSE   ! ln_osm_mle
2139                  IF ( pdb_bl(ji,jj) > 0.0_wp .AND. pdbdz_bl_ext(ji,jj) > 0.0_wp ) THEN
2140                     IF ( ( swstrc(ji,jj) / MAX( svstr(ji,jj), epsln ) )**3 <= 0.5_wp ) THEN   ! Near neutral stability
2141                        ztmp = svstr(ji,jj)
2142                     ELSE   ! Unstable
2143                        ztmp = swstrc(ji,jj)
2144                     END IF
2145                     zari    = MIN( 1.5_wp * pdb_bl(ji,jj) / ( phbl(ji,jj) *                            &
2146                        &                                      ( MAX( pdbdz_bl_ext(ji,jj), 0.0_wp ) +   &
2147                        &                                        pdb_bl(ji,jj)**2 / MAX( 4.5_wp * ztmp**2 , 1e-12_wp ) ) ), 0.2_wp )
2148                  ELSE
2149                     zari    = 0.2_wp
2150                  END IF
2151                  ztau    = hbl(ji,jj) / MAX( epsln, ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird )
2152                  zdh_ref = zari * hbl(ji,jj)
2153               END IF   ! ln_osm_mle
2154               dh(ji,jj) = dh(ji,jj) * EXP( -1.0_wp * rn_Dt / ztau ) + zdh_ref * ( 1.0_wp - EXP( -1.0_wp * rn_Dt / ztau ) )
2155               !               IF ( pdhdt(ji,jj) < 0._wp .and. dh(ji,jj) >= hbl(ji,jj) ) dh(ji,jj) = zdh_ref
2156               IF ( dh(ji,jj) >= hbl(ji,jj) ) dh(ji,jj) = zdh_ref
2157               ! Alan: this hml is never defined or used
2158            ELSE   ! IF (l_conv)
2159               !
2160               ztau = hbl(ji,jj) / MAX( svstr(ji,jj), epsln )
2161               IF ( pdhdt(ji,jj) >= 0.0_wp ) THEN   ! Probably shouldn't include wm here
2162                  ! Boundary layer deepening
2163                  IF ( pdb_bl(ji,jj) > 0.0_wp ) THEN
2164                     ! Pycnocline thickness set by stratification - use same relationship as for neutral conditions.
2165                     zari    = MIN( 4.5_wp * ( svstr(ji,jj)**2 ) / MAX( pdb_bl(ji,jj) * phbl(ji,jj), epsln ) + 0.01_wp , 0.2_wp )
2166                     zdh_ref = MIN( zari, 0.2_wp ) * hbl(ji,jj)
2167                  ELSE
2168                     zdh_ref = 0.2_wp * hbl(ji,jj)
2169                  END IF
2170               ELSE   ! IF(dhdt < 0)
2171                  zdh_ref = 0.2_wp * hbl(ji,jj)
2172               END IF   ! IF (dhdt >= 0)
2173               dh(ji,jj) = dh(ji,jj) * EXP( -1.0_wp * rn_Dt / ztau ) + zdh_ref * ( 1.0_wp - EXP( -1.0_wp * rn_Dt / ztau ) )
2174               IF ( pdhdt(ji,jj) < 0.0_wp .AND. dh(ji,jj) >= hbl(ji,jj) ) dh(ji,jj) = zdh_ref   ! Can be a problem with dh>hbl for
2175               !                                                                                !    rapid collapse
2176            END IF   ! IF (l_conv)
2177            !
2178         END IF   ! l_shear
2179         !
2180         hml(ji,jj)  = hbl(ji,jj) - dh(ji,jj)
2181         inhml       = MAX( INT( dh(ji,jj) / MAX( e3t(ji,jj,nbld(ji,jj)-1,Kmm), 1e-3_wp ) ), 1 )
2182         nmld(ji,jj) = MAX( nbld(ji,jj) - inhml, 3 )
2183         phml(ji,jj) = gdepw(ji,jj,nmld(ji,jj),Kmm)
2184         pdh(ji,jj)  = phbl(ji,jj) - phml(ji,jj)
2185#ifdef key_osm_debug
2186         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2187            WRITE(narea+100,'(4(a,g11.3),2(a,i7),/,5(a,g11.3),/)') 'end of zdf_osm_pycnocline_thickness:hml=',hml(ji,jj), &
2188               & '  zhml=',phml(ji,jj),' zdh=', pdh(ji,jj), '  dh=', dh(ji,jj), ' imld=', nmld(ji,jj), ' inhml=', inhml, &
2189               & 'zvel_max=', zvel_max, ' ztau=', ztau,' zdh_ref=', zdh_ref, ' zar=', zari, ' zddhdt=', zddhdt
2190            FLUSH(narea+100)
2191         END IF
2192#endif
2193         !
2194      END_2D
2195      !
2196      IF( ln_timing ) CALL timing_stop('zdf_osm_pt')
2197      !
2198   END SUBROUTINE zdf_osm_pycnocline_thickness
2199
2200   SUBROUTINE zdf_osm_pycnocline_buoyancy_profiles( Kmm, kp_ext, pdbdz, palpha, pdh,            &
2201      &                                             pdb_bl, phbl, pdbdz_bl_ext, phml, pdb_ml,   &
2202      &                                             pdhdt )
2203      !!---------------------------------------------------------------------
2204      !!       ***  ROUTINE zdf_osm_pycnocline_buoyancy_profiles  ***
2205      !!
2206      !! ** Purpose : calculate pycnocline buoyancy profiles
2207      !!
2208      !! ** Method  :
2209      !!
2210      !!----------------------------------------------------------------------
2211      INTEGER,                     INTENT(in   ) ::   Kmm            ! Ocean time-level index
2212      INTEGER,  DIMENSION(:,:),    INTENT(in   ) ::   kp_ext         ! External-level offsets
2213      REAL(wp), DIMENSION(:,:,:),  INTENT(inout) ::   pdbdz          ! Gradients in the pycnocline
2214      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   palpha
2215      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdh            ! Pycnocline thickness
2216      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_bl         ! Buoyancy diff. between BL average and basal value
2217      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl           ! BL depth
2218      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdbdz_bl_ext   ! External buoyancy gradients
2219      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phml           ! ML depth
2220      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_ml         ! Buoyancy diff. between mixed-layer average and basal value
2221      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdhdt          ! Rates of change of hbl
2222      !
2223      ! Local variables
2224      INTEGER  ::   jk, jj, ji
2225      REAL(wp) ::   zbgrad
2226      REAL(wp) ::   zgamma_b_nd, znd
2227      REAL(wp) ::   zzeta_m
2228      REAL(wp) ::   ztmp   ! Auxiliary variable
2229      !
2230      REAL(wp), PARAMETER ::   pp_gamma_b = 2.25_wp
2231      !
2232      IF( ln_timing ) CALL timing_start('zdf_osm_pscp')
2233      !
2234      DO_2D( 0, 0, 0, 0 )
2235         !
2236         IF ( nbld(ji,jj) + kp_ext(ji,jj) < mbkt(ji,jj) ) THEN
2237            !
2238            IF ( l_conv(ji,jj) ) THEN   ! Convective conditions
2239               !
2240               IF ( l_pyc(ji,jj) ) THEN
2241                  !
2242                  zzeta_m = 0.1_wp + 0.3_wp / ( 1.0_wp + EXP( -3.5_wp * LOG10( -1.0_wp * shol(ji,jj) ) ) )
2243                  palpha(ji,jj) = 2.0_wp * ( 1.0_wp - ( 0.80_wp * zzeta_m + 0.5_wp * SQRT( 3.14159_wp / pp_gamma_b ) ) *   &
2244                     &                                pdbdz_bl_ext(ji,jj) * pdh(ji,jj) / pdb_ml(ji,jj) ) /                &
2245                     &            ( 0.723_wp + SQRT( 3.14159_wp / pp_gamma_b ) )
2246                  palpha(ji,jj) = MAX( palpha(ji,jj), 0.0_wp )
2247                  ztmp = 1.0_wp / MAX( pdh(ji,jj), epsln )
2248                  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2249                  ! Commented lines in this section are not needed in new code, once tested !
2250                  ! can be removed                                                          !
2251                  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2252                  ! ztgrad = zalpha * zdt_ml(ji,jj) * ztmp + zdtdz_bl_ext(ji,jj)
2253                  ! zsgrad = zalpha * zds_ml(ji,jj) * ztmp + zdsdz_bl_ext(ji,jj)
2254                  zbgrad = palpha(ji,jj) * pdb_ml(ji,jj) * ztmp + pdbdz_bl_ext(ji,jj)
2255                  zgamma_b_nd = pdbdz_bl_ext(ji,jj) * pdh(ji,jj) / MAX( pdb_ml(ji,jj), epsln )
2256                  DO jk = 2, nbld(ji,jj)
2257                     znd = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) * ztmp
2258                     IF ( znd <= zzeta_m ) THEN
2259                        ! zdtdz(ji,jj,jk) = zdtdz_bl_ext(ji,jj) + zalpha * zdt_ml(ji,jj) * ztmp * &
2260                        ! &        EXP( -6.0 * ( znd -zzeta_m )**2 )
2261                        ! zdsdz(ji,jj,jk) = zdsdz_bl_ext(ji,jj) + zalpha * zds_ml(ji,jj) * ztmp * &
2262                        ! & EXP( -6.0 * ( znd -zzeta_m )**2 )
2263                        pdbdz(ji,jj,jk) = pdbdz_bl_ext(ji,jj) + palpha(ji,jj) * pdb_ml(ji,jj) * ztmp * &
2264                           & EXP( -6.0_wp * ( znd -zzeta_m )**2 )
2265                     ELSE
2266                        ! zdtdz(ji,jj,jk) =  ztgrad * EXP( -pp_gamma_b * ( znd - zzeta_m )**2 )
2267                        ! zdsdz(ji,jj,jk) =  zsgrad * EXP( -pp_gamma_b * ( znd - zzeta_m )**2 )
2268                        pdbdz(ji,jj,jk) =  zbgrad * EXP( -1.0_wp * pp_gamma_b * ( znd - zzeta_m )**2 )
2269                     END IF
2270                  END DO
2271#ifdef key_osm_debug
2272                  IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2273                     WRITE(narea+100,'(a,/,3(a,g11.3),/,2(a,g11.3),/)')'end of zdf_osm_pycnocline_buoyancy_profiles:lconv=lpyc=T',&
2274                        & 'zzeta_m=', zzeta_m, ' zalpha=', palpha(ji,jj), ' ztmp=', ztmp,&
2275                        & ' zbgrad=', zbgrad, ' zgamma_b_nd=', zgamma_b_nd
2276                     FLUSH(narea+100)
2277                  END IF
2278#endif
2279               END IF   ! If no pycnocline pycnocline gradients set to zero
2280               !
2281            ELSE   ! Stable conditions
2282               ! If pycnocline profile only defined when depth steady of increasing.
2283               IF ( pdhdt(ji,jj) > 0.0_wp ) THEN   ! Depth increasing, or steady.
2284                  IF ( pdb_bl(ji,jj) > 0.0_wp ) THEN
2285                     IF ( shol(ji,jj) >= 0.5_wp ) THEN   ! Very stable - 'thick' pycnocline
2286                        ztmp = 1.0_wp / MAX( phbl(ji,jj), epsln )
2287                        zbgrad = pdb_bl(ji,jj) * ztmp
2288                        DO jk = 2, nbld(ji,jj)
2289                           znd = gdepw(ji,jj,jk,Kmm) * ztmp
2290                           pdbdz(ji,jj,jk) =  zbgrad * EXP( -15.0_wp * ( znd - 0.9_wp )**2 )
2291                        END DO
2292                     ELSE   ! Slightly stable - 'thin' pycnoline - needed when stable layer begins to form.
2293                        ztmp = 1.0_wp / MAX( pdh(ji,jj), epsln )
2294                        zbgrad = pdb_bl(ji,jj) * ztmp
2295                        DO jk = 2, nbld(ji,jj)
2296                           znd = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phml(ji,jj) ) * ztmp
2297                           pdbdz(ji,jj,jk) =  zbgrad * EXP( -1.75_wp * ( znd + 0.75_wp )**2 )
2298                        END DO
2299                     END IF   ! IF (shol >=0.5)
2300#ifdef key_osm_debug
2301                     IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2302                        WRITE(narea+100,'(1(a,g11.3))')'end of zdf_osm_pycnocline_buoyancy_profiles:lconv=F zbgrad=', zbgrad
2303                        !                           WRITE(narea+100,'(1(a,g11.3))')'end of zdf_osm_pycnocline_scalar_profiles:lconv=F ztgrad=',&
2304                        !                                & ztgrad, ' zsgrad=', zsgrad, ' zbgrad=', zbgrad
2305                        FLUSH(narea+100)
2306                     END IF
2307#endif
2308                  END IF      ! IF (pdb_bl> 0.)
2309               END IF         ! IF (pdhdt >= 0) pdhdt < 0 not considered since pycnocline profile is zero and profile arrays are intialized to zero
2310               !
2311            END IF            ! IF (l_conv)
2312            !
2313         END IF   ! IF ( nbld(ji,jj) < mbkt(ji,jj) )
2314         !
2315      END_2D
2316      !
2317      IF ( ln_dia_pyc_scl ) THEN   ! Output of pycnocline gradient profiles
2318         IF ( iom_use("zdbdz_pyc") ) CALL iom_put( "zdbdz_pyc", wmask(:,:,:) * pdbdz(:,:,:) )
2319      END IF
2320      !
2321      IF( ln_timing ) CALL timing_stop('zdf_osm_pscp')
2322      !
2323   END SUBROUTINE zdf_osm_pycnocline_buoyancy_profiles
2324
2325   SUBROUTINE zdf_osm_diffusivity_viscosity( Kbb, Kmm, pdiffut, pviscos, phbl,   &
2326      &                                      phml, pdh, pdhdt, pshear,           &
2327      &                                      pwb_ent, pwb_min )
2328      !!---------------------------------------------------------------------
2329      !!           ***  ROUTINE zdf_osm_diffusivity_viscosity  ***
2330      !!
2331      !! ** Purpose : Determines the eddy diffusivity and eddy viscosity
2332      !!              profiles in the mixed layer and the pycnocline.
2333      !!
2334      !! ** Method  :
2335      !!
2336      !!----------------------------------------------------------------------
2337      INTEGER,                     INTENT(in   ) ::   Kbb, Kmm       ! Ocean time-level indices
2338      REAL(wp), DIMENSION(:,:,:),  INTENT(inout) ::   pdiffut        ! t-diffusivity
2339      REAL(wp), DIMENSION(:,:,:),  INTENT(inout) ::   pviscos        ! Viscosity
2340      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl           ! BL depth
2341      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phml           ! ML depth
2342      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdh            ! Pycnocline depth
2343      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdhdt          ! BL depth tendency
2344      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pshear         ! Shear production
2345      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_ent        ! Buoyancy entrainment flux
2346      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pwb_min
2347      !
2348      ! Local variables
2349      INTEGER ::   ji, jj, jk   ! Loop indices
2350      !
2351      ! Scales used to calculate eddy diffusivity and viscosity profiles
2352      REAL(wp), DIMENSION(A2D(0)) ::   zdifml_sc,    zvisml_sc
2353      REAL(wp), DIMENSION(A2D(0)) ::   zdifpyc_n_sc, zdifpyc_s_sc
2354      REAL(wp), DIMENSION(A2D(0)) ::   zvispyc_n_sc, zvispyc_s_sc
2355      REAL(wp), DIMENSION(A2D(0)) ::   zbeta_d_sc,   zbeta_v_sc
2356      REAL(wp), DIMENSION(A2D(0)) ::   zb_coup,      zc_coup_vis,  zc_coup_dif
2357      !
2358      REAL(wp) ::   zvel_sc_pyc, zvel_sc_ml, zstab_fac, zz_b
2359      REAL(wp) ::   za_cubic, zb_d_cubic, zc_d_cubic, zd_d_cubic,   &   ! Coefficients in cubic polynomial specifying diffusivity
2360         &                    zb_v_cubic, zc_v_cubic, zd_v_cubic        ! and viscosity in pycnocline
2361      REAL(wp) ::   zznd_ml, zznd_pyc, ztmp
2362      REAL(wp) ::   zmsku, zmskv
2363      !
2364      REAL(wp), PARAMETER ::   pp_dif_ml     = 0.8_wp,  pp_vis_ml  = 0.375_wp
2365      REAL(wp), PARAMETER ::   pp_dif_pyc    = 0.15_wp, pp_vis_pyc = 0.142_wp
2366      REAL(wp), PARAMETER ::   pp_vispyc_shr = 0.15_wp
2367      !
2368      IF( ln_timing ) CALL timing_start('zdf_osm_dv')
2369      !
2370      zb_coup(:,:) = 0.0_wp
2371      !
2372      DO_2D( 0, 0, 0, 0 )
2373         IF ( l_conv(ji,jj) ) THEN
2374            !
2375            zvel_sc_pyc = ( 0.15_wp * svstr(ji,jj)**3 + swstrc(ji,jj)**3 + 4.25_wp * pshear(ji,jj) * phbl(ji,jj) )**pthird
2376            zvel_sc_ml  = ( svstr(ji,jj)**3 + 0.5_wp * swstrc(ji,jj)**3 )**pthird
2377            zstab_fac   = ( phml(ji,jj) / zvel_sc_ml *   &
2378               &            ( 1.4_wp - 0.4_wp / ( 1.0_wp + EXP(-3.5_wp * LOG10(-shol(ji,jj) ) ) )**1.25_wp ) )**2
2379            !
2380            zdifml_sc(ji,jj) = pp_dif_ml * phml(ji,jj) * zvel_sc_ml
2381            zvisml_sc(ji,jj) = pp_vis_ml * zdifml_sc(ji,jj)
2382#ifdef key_osm_debug
2383            IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2384               WRITE(narea+100,'(2(a,g11.3))')'Start of 1st major loop of osm_diffusivity_viscositys, ldconv=T: zdifml_sc=',zdifml_sc(ji,jj),' zvisml_sc=',zvisml_sc(ji,jj)
2385               WRITE(narea+100,'(3(a,g11.3))')'zvel_sc_pyc=',zvel_sc_pyc,' zvel_sc_ml=',zvel_sc_ml,' zstab_fac=',zstab_fac
2386               FLUSH(narea+100)
2387            END IF
2388#endif
2389            !
2390            IF ( l_pyc(ji,jj) ) THEN
2391               zdifpyc_n_sc(ji,jj) = pp_dif_pyc * zvel_sc_ml * pdh(ji,jj)
2392               zvispyc_n_sc(ji,jj) = 0.09_wp * zvel_sc_pyc * ( 1.0_wp - phbl(ji,jj) / pdh(ji,jj) )**2 *   &
2393                  &                  ( 0.005_wp  * ( av_u_ml(ji,jj) - av_u_bl(ji,jj) )**2 +     &
2394                  &                    0.0075_wp * ( av_v_ml(ji,jj) - av_v_bl(ji,jj) )**2 ) /   &
2395                  &                  pdh(ji,jj)
2396               zvispyc_n_sc(ji,jj) = pp_vis_pyc * zvel_sc_ml * pdh(ji,jj) + zvispyc_n_sc(ji,jj) * zstab_fac
2397#ifdef key_osm_debug
2398               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2399                  WRITE(narea+100,'(2(a,g11.3))')' lpyc=ldconv=T, variables w/o shear contributions: zdifpyc_n_sc',zdifpyc_n_sc(ji,jj) ,' zvispyc_n_sc=',zvispyc_n_sc(ji,jj)
2400                  FLUSH(narea+100)
2401               END IF
2402#endif
2403               !
2404               IF ( l_shear(ji,jj) .AND. n_ddh(ji,jj) /= 2 ) THEN
2405                  ztmp = pp_vispyc_shr * ( pshear(ji,jj) * phbl(ji,jj) )**pthird * phbl(ji,jj)
2406                  zdifpyc_n_sc(ji,jj) = zdifpyc_n_sc(ji,jj) + ztmp
2407                  zvispyc_n_sc(ji,jj) = zvispyc_n_sc(ji,jj) + ztmp
2408               ENDIF
2409#ifdef key_osm_debug
2410               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2411                  WRITE(narea+100,'(2(a,g11.3))')' lpyc=ldconv=T, variables w shear contributions: zdifpyc_n_sc',zdifpyc_n_sc(ji,jj) ,' zvispyc_n_sc=',zvispyc_n_sc(ji,jj)
2412                  FLUSH(narea+100)
2413               END IF
2414#endif
2415               !
2416               zdifpyc_s_sc(ji,jj) = pwb_ent(ji,jj) + 0.0025_wp * zvel_sc_pyc * ( phbl(ji,jj) / pdh(ji,jj) - 1.0_wp ) *   &
2417                  &                                   ( av_b_ml(ji,jj) - av_b_bl(ji,jj) )
2418               zvispyc_s_sc(ji,jj) = 0.09_wp * ( pwb_min(ji,jj) + 0.0025_wp * zvel_sc_pyc *                 &
2419                  &                                               ( phbl(ji,jj) / pdh(ji,jj) - 1.0_wp ) *   &
2420                  &                                               ( av_b_ml(ji,jj) - av_b_bl(ji,jj) ) )
2421#ifdef key_osm_debug
2422               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2423                  WRITE(narea+100,'(2(a,g11.3))')' 1st shot at: zdifpyc_s_sc',zdifpyc_s_sc(ji,jj) ,' zvispyc_s_sc=',zvispyc_s_sc(ji,jj)
2424                  FLUSH(narea+100)
2425               END IF
2426#endif
2427               zdifpyc_s_sc(ji,jj) = 0.09_wp * zdifpyc_s_sc(ji,jj) * zstab_fac
2428               zvispyc_s_sc(ji,jj) = zvispyc_s_sc(ji,jj) * zstab_fac
2429#ifdef key_osm_debug
2430               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2431                  WRITE(narea+100,'(2(a,g11.3))')' 2nd shot at: zdifpyc_s_sc',zdifpyc_s_sc(ji,jj) ,' zvispyc_s_sc=',zvispyc_s_sc(ji,jj)
2432                  FLUSH(narea+100)
2433               END IF
2434#endif
2435               !
2436               zdifpyc_s_sc(ji,jj) = MAX( zdifpyc_s_sc(ji,jj), -0.5_wp * zdifpyc_n_sc(ji,jj) )
2437               zvispyc_s_sc(ji,jj) = MAX( zvispyc_s_sc(ji,jj), -0.5_wp * zvispyc_n_sc(ji,jj) )
2438               
2439               zbeta_d_sc(ji,jj) = 1.0_wp - ( ( zdifpyc_n_sc(ji,jj) + 1.4_wp * zdifpyc_s_sc(ji,jj) ) /   &
2440                  &                           ( zdifml_sc(ji,jj) + epsln ) )**p2third
2441               zbeta_v_sc(ji,jj) = 1.0_wp - 2.0_wp * ( zvispyc_n_sc(ji,jj) + zvispyc_s_sc(ji,jj) ) / ( zvisml_sc(ji,jj) + epsln )
2442            ELSE
2443               zdifpyc_n_sc(ji,jj) = pp_dif_pyc * zvel_sc_ml * pdh(ji,jj)   ! ag 19/03
2444               zdifpyc_s_sc(ji,jj) = 0.0_wp   ! ag 19/03
2445               zvispyc_n_sc(ji,jj) = pp_vis_pyc * zvel_sc_ml * pdh(ji,jj)   ! ag 19/03
2446               zvispyc_s_sc(ji,jj) = 0.0_wp   ! ag 19/03
2447               IF(l_coup(ji,jj) ) THEN   ! ag 19/03
2448                  ! code from SUBROUTINE tke_tke zdftke.F90; uses bottom drag velocity rCdU_bot(ji,jj) = -Cd|ub|
2449                  !     already calculated at T-points in SUBROUTINE zdf_drg from zdfdrg.F90
2450                  !  Gives friction velocity sqrt bottom drag/rho_0 i.e. u* = SQRT(rCdU_bot*ub)
2451                  ! wet-cell averaging ..
2452                  zmsku = 0.5_wp * ( 2.0_wp - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
2453                  zmskv = 0.5_wp * ( 2.0_wp - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )
2454                  zb_coup(ji,jj) = 0.4_wp * SQRT(-1.0_wp * rCdU_bot(ji,jj) *   &
2455                     &             SQRT(  ( zmsku*( uu(ji,jj,mbkt(ji,jj),Kbb)+uu(ji-1,jj,mbkt(ji,jj),Kbb) ) )**2   &
2456                     &                  + ( zmskv*( vv(ji,jj,mbkt(ji,jj),Kbb)+vv(ji,jj-1,mbkt(ji,jj),Kbb) ) )**2  ) )
2457                 
2458                  zz_b = -1.0_wp * gdepw(ji,jj,mbkt(ji,jj)+1,Kmm)   ! ag 19/03
2459                  zc_coup_vis(ji,jj) = -0.5_wp * ( 0.5_wp * zvisml_sc(ji,jj) / phml(ji,jj) - zb_coup(ji,jj) ) /   &
2460                     &                 ( phml(ji,jj) + zz_b )   ! ag 19/03
2461#ifdef key_osm_debug
2462                  IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2463                     WRITE(narea+100,'(4(a,g11.3))')' lcoup = T; 1st pz_b= ', zz_b, ' pb_coup ', zb_coup(ji,jj),   &
2464                        &                           ' pc_coup_vis ', zc_coup_vis(ji,jj), ' rCdU_bot ',rCdU_bot(ji,jj)
2465                     WRITE(narea+100,'(2(a,g11.3))')' zmsku ', zmsku, ' zmskv ', zmskv
2466                     FLUSH(narea+100)
2467                  END IF
2468#endif
2469                  zz_b = -1.0_wp * phml(ji,jj) + gdepw(ji,jj,mbkt(ji,jj)+1,Kmm)   ! ag 19/03
2470                  zbeta_v_sc(ji,jj) = 1.0_wp - 2.0_wp * ( zb_coup(ji,jj) * zz_b + zc_coup_vis(ji,jj) * zz_b**2 ) /   &
2471                     &                                  zvisml_sc(ji,jj)   ! ag 19/03
2472                  zbeta_d_sc(ji,jj) = 1.0_wp - ( ( zb_coup(ji,jj) * zz_b + zc_coup_vis(ji,jj) * zz_b**2 ) /   &
2473                     &                           zdifml_sc(ji,jj) )**p2third
2474                  zc_coup_dif(ji,jj) = 0.5_wp * ( -zdifml_sc(ji,jj) / phml(ji,jj) * ( 1.0_wp - zbeta_d_sc(ji,jj) )**1.5_wp +   &
2475                     &                 1.5_wp * ( zdifml_sc(ji,jj) / phml(ji,jj) ) * zbeta_d_sc(ji,jj) *   &
2476                     &                          SQRT( 1.0_wp - zbeta_d_sc(ji,jj) ) - zb_coup(ji,jj) ) / zz_b   ! ag 19/03
2477#ifdef key_osm_debug
2478                  IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2479                     WRITE(narea+100,'(2(a,g11.3))')' 2nd pz_b= ', zz_b, ' pc_coup_dif', zc_coup_dif(ji,jj)
2480                     FLUSH(narea+100)
2481                  END IF
2482#endif
2483               ELSE   ! ag 19/03
2484                  zbeta_d_sc(ji,jj) = 1.0_wp - ( ( zdifpyc_n_sc(ji,jj) + 1.4_wp * zdifpyc_s_sc(ji,jj) ) /   &
2485                     &                           ( zdifml_sc(ji,jj) + epsln ) )**p2third   ! ag 19/03
2486                  zbeta_v_sc(ji,jj) = 1.0_wp - 2.0_wp * ( zvispyc_n_sc(ji,jj) + zvispyc_s_sc(ji,jj) ) /   &
2487                     &                         ( zvisml_sc(ji,jj) + epsln )   ! ag 19/03
2488               ENDIF   ! ag 19/03
2489            ENDIF      ! ag 19/03
2490#ifdef key_osm_debug
2491            IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2492               WRITE(narea+100,'(2(a,g11.3))')'ldconv=T: zbeta_d_sc',zbeta_d_sc(ji,jj) ,' zbeta_v_sc=',zbeta_v_sc(ji,jj)
2493               WRITE(narea+100,'(2(a,g11.3))')' Final zdifpyc_n_sc',zdifpyc_n_sc(ji,jj) ,' zvispyc_n_sc=',zvispyc_n_sc(ji,jj)
2494               WRITE(narea+100,'(2(a,g11.3))')' Final zdifpyc_s_sc',zdifpyc_s_sc(ji,jj) ,' zvispyc_s_sc=',zvispyc_s_sc(ji,jj)
2495               FLUSH(narea+100)
2496            END IF
2497#endif
2498         ELSE
2499            zdifml_sc(ji,jj) = svstr(ji,jj) * phbl(ji,jj) * MAX( EXP ( -( shol(ji,jj) / 0.6_wp )**2 ), 0.2_wp)
2500            zvisml_sc(ji,jj) = zdifml_sc(ji,jj)
2501#ifdef key_osm_debug
2502            IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2503               WRITE(narea+100,'(a,g11.3)')'End of 1st major loop of osm_diffusivity_viscositys, ldconv=F: zdifml_sc=',zdifml_sc(ji,jj),' zvisml_sc=',zvisml_sc(ji,jj)
2504               FLUSH(narea+100)
2505            END IF
2506#endif
2507         END IF
2508      END_2D
2509      !
2510      DO_2D( 0, 0, 0, 0 )
2511      IF ( l_conv(ji,jj) ) THEN
2512         DO jk = 2, nmld(ji,jj)   ! Mixed layer diffusivity
2513            zznd_ml = gdepw(ji,jj,jk,Kmm) / phml(ji,jj)
2514            pdiffut(ji,jj,jk) = zdifml_sc(ji,jj) * zznd_ml * ( 1.0_wp - zbeta_d_sc(ji,jj) * zznd_ml )**1.5
2515            pviscos(ji,jj,jk) = zvisml_sc(ji,jj) * zznd_ml * ( 1.0_wp - zbeta_v_sc(ji,jj) * zznd_ml ) *   &
2516               &                ( 1.0_wp - 0.5_wp * zznd_ml**2 )
2517         END DO
2518         !
2519         ! Coupling to bottom
2520         !
2521         IF ( l_coup(ji,jj) ) THEN                                                         ! ag 19/03
2522            DO jk = mbkt(ji,jj), nmld(ji,jj), -1                                           ! ag 19/03
2523               zz_b = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - gdepw(ji,jj,mbkt(ji,jj)+1,Kmm) )   ! ag 19/03
2524               pviscos(ji,jj,jk) = zb_coup(ji,jj) * zz_b + zc_coup_vis(ji,jj) * zz_b**2    ! ag 19/03
2525               pdiffut(ji,jj,jk) = zb_coup(ji,jj) * zz_b + zc_coup_dif(ji,jj) * zz_b**2    ! ag 19/03
2526            END DO                                                                         ! ag 19/03
2527         ENDIF                                                                             ! ag 19/03
2528         ! Pycnocline
2529         IF ( l_pyc(ji,jj) ) THEN 
2530            ! Diffusivity and viscosity profiles in the pycnocline given by
2531            ! cubic polynomial. Note, if l_pyc TRUE can't be coupled to seabed.
2532            za_cubic = 0.5_wp
2533            zb_d_cubic = -1.75_wp * zdifpyc_s_sc(ji,jj) / zdifpyc_n_sc(ji,jj)
2534            zd_d_cubic = ( pdh(ji,jj) * zdifml_sc(ji,jj) / phml(ji,jj) * SQRT( 1.0_wp - zbeta_d_sc(ji,jj) ) *   &
2535               &           ( 2.5_wp * zbeta_d_sc(ji,jj) - 1.0_wp ) - 0.85_wp * zdifpyc_s_sc(ji,jj) ) /            &
2536               &           MAX( zdifpyc_n_sc(ji,jj), 1.0e-8_wp )
2537            zd_d_cubic = zd_d_cubic - zb_d_cubic - 2.0_wp * ( 1.0_wp - za_cubic  - zb_d_cubic )
2538            zc_d_cubic = 1.0_wp - za_cubic - zb_d_cubic - zd_d_cubic
2539            zb_v_cubic = -1.75_wp * zvispyc_s_sc(ji,jj) / zvispyc_n_sc(ji,jj)
2540            zd_v_cubic = ( 0.5_wp * zvisml_sc(ji,jj) * pdh(ji,jj) / phml(ji,jj) - 0.85_wp * zvispyc_s_sc(ji,jj) ) /   &
2541               &           MAX( zvispyc_n_sc(ji,jj), 1.0e-8_wp )
2542            zd_v_cubic = zd_v_cubic - zb_v_cubic - 2.0_wp * ( 1.0_wp - za_cubic - zb_v_cubic )
2543            zc_v_cubic = 1.0_wp - za_cubic - zb_v_cubic - zd_v_cubic
2544            DO jk = nmld(ji,jj) , nbld(ji,jj)
2545               zznd_pyc = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) / MAX(pdh(ji,jj), 1.0e-6_wp )
2546               ztmp = ( 1.75_wp * zznd_pyc - 0.15_wp * zznd_pyc**2 - 0.2_wp * zznd_pyc**3 )
2547               !
2548               pdiffut(ji,jj,jk) = zdifpyc_n_sc(ji,jj) *   &
2549                  &                ( za_cubic + zb_d_cubic * zznd_pyc + zc_d_cubic * zznd_pyc**2 + zd_d_cubic * zznd_pyc**3 )
2550               !
2551               pdiffut(ji,jj,jk) = pdiffut(ji,jj,jk) + zdifpyc_s_sc(ji,jj) * ztmp
2552               pviscos(ji,jj,jk) = zvispyc_n_sc(ji,jj) *   &
2553                  &                ( za_cubic + zb_v_cubic * zznd_pyc + zc_v_cubic * zznd_pyc**2 + zd_v_cubic * zznd_pyc**3 )
2554               pviscos(ji,jj,jk) = pviscos(ji,jj,jk) + zvispyc_s_sc(ji,jj) * ztmp
2555            END DO
2556!                  IF ( pdhdt(ji,jj) > 0._wp ) THEN
2557!                     zdiffut(ji,jj,nbld(ji,jj)+1) = MAX( 0.5 * pdhdt(ji,jj) * e3w(ji,jj,nbld(ji,jj)+1,Kmm), 1.0e-6 )
2558!                     zviscos(ji,jj,nbld(ji,jj)+1) = MAX( 0.5 * pdhdt(ji,jj) * e3w(ji,jj,nbld(ji,jj)+1,Kmm), 1.0e-6 )
2559!                  ELSE
2560!                     zdiffut(ji,jj,nbld(ji,jj)) = 0._wp
2561!                     zviscos(ji,jj,nbld(ji,jj)) = 0._wp
2562!                  ENDIF
2563         ENDIF
2564      ELSE
2565         ! Stable conditions
2566         DO jk = 2, nbld(ji,jj)
2567            zznd_ml = gdepw(ji,jj,jk,Kmm) / phbl(ji,jj)
2568            pdiffut(ji,jj,jk) = 0.75_wp * zdifml_sc(ji,jj) * zznd_ml * ( 1.0_wp - zznd_ml )**1.5_wp
2569            pviscos(ji,jj,jk) = 0.375_wp * zvisml_sc(ji,jj) * zznd_ml * ( 1.0_wp - zznd_ml ) * ( 1.0_wp - zznd_ml**2 )
2570         END DO
2571         !
2572         IF ( pdhdt(ji,jj) > 0.0_wp ) THEN
2573            pdiffut(ji,jj,nbld(ji,jj)) = MAX( pdhdt(ji,jj), 1.0e-6_wp) * e3w(ji, jj, nbld(ji,jj), Kmm)
2574            pviscos(ji,jj,nbld(ji,jj)) = pdiffut(ji,jj,nbld(ji,jj))
2575         ENDIF
2576      ENDIF   ! End if ( l_conv )
2577      !
2578      END_2D
2579      IF( iom_use("pb_coup") ) CALL iom_put( "pb_coup", tmask(:,:,1) * zb_coup(:,:) )   ! BBL-coupling velocity scale
2580      IF( ln_timing ) CALL timing_stop('zdf_osm_dv')
2581      !
2582   END SUBROUTINE zdf_osm_diffusivity_viscosity
2583
2584   SUBROUTINE zdf_osm_fgr_terms( Kmm, kp_ext, phbl, phml, pdh,                            &
2585      &                          pdhdt, pshear, pdt_bl, pds_bl, pdb_bl,                   &
2586      &                          pdu_bl, pdv_bl, pdt_ml, pds_ml, pdb_ml,                  &
2587      &                          pdu_ml, pdv_ml, pdtdz_bl_ext, pdsdz_bl_ext, pdbdz_pyc,   &
2588      &                          palpha_pyc, pdiffut, pviscos )
2589      !!---------------------------------------------------------------------
2590      !!                 ***  ROUTINE zdf_osm_fgr_terms ***
2591      !!
2592      !! ** Purpose : Compute non-gradient terms in flux-gradient relationship
2593      !!
2594      !! ** Method  :
2595      !!
2596      !!----------------------------------------------------------------------
2597      INTEGER,                     INTENT(in   ) ::   Kmm            ! Time-level index
2598      INTEGER,  DIMENSION(:,:),    INTENT(in   ) ::   kp_ext         ! Offset for external level
2599      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl           ! BL depth
2600      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phml           ! ML depth
2601      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdh            ! Pycnocline depth
2602      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdhdt          ! BL depth tendency
2603      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pshear         ! Shear production
2604      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdt_bl         ! Temperature diff. between BL average and basal value
2605      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pds_bl         ! Salinity diff. between BL average and basal value
2606      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_bl         ! Buoyancy diff. between BL average and basal value
2607      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdu_bl         ! Velocity diff. (u) between BL average and basal value
2608      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdv_bl         ! Velocity diff. (v) between BL average and basal value
2609      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdt_ml         ! Temperature diff. between mixed-layer average and basal value
2610      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pds_ml         ! Salinity diff. between mixed-layer average and basal value
2611      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdb_ml         ! Buoyancy diff. between mixed-layer average and basal value
2612      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdu_ml         ! Velocity diff. (u) between mixed-layer average and basal value
2613      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdv_ml         ! Velocity diff. (v) between mixed-layer average and basal value
2614      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdtdz_bl_ext   ! External temperature gradients
2615      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pdsdz_bl_ext   ! External salinity gradients
2616      REAL(wp), DIMENSION(:,:,:),  INTENT(in   ) ::   pdbdz_pyc      ! Pycnocline buoyancy gradients
2617      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   palpha_pyc     !
2618      REAL(wp), DIMENSION(:,:,:),  INTENT(in   ) ::   pdiffut        ! t-diffusivity
2619      REAL(wp), DIMENSION(:,:,:),  INTENT(in   ) ::   pviscos        ! Viscosity
2620      !
2621      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   z3ddz_pyc_1, z3ddz_pyc_2   ! Pycnocline gradient/shear profiles
2622      !
2623      INTEGER                     ::   ji, jj, jk, jkm_bld, jkf_mld, jkm_mld   ! Loop indices
2624#ifdef key_osm_debug
2625      INTEGER                     ::   jl, jm
2626#endif
2627      INTEGER                     ::   istat                                   ! Memory allocation status
2628      REAL(wp)                    ::   zznd_d, zznd_ml, zznd_pyc, znd          ! Temporary non-dimensional depths
2629      REAL(wp), DIMENSION(A2D(0)) ::   zsc_wth_1,zsc_ws_1                      ! Temporary scales
2630      REAL(wp), DIMENSION(A2D(0)) ::   zsc_uw_1, zsc_uw_2                      ! Temporary scales
2631      REAL(wp), DIMENSION(A2D(0)) ::   zsc_vw_1, zsc_vw_2                      ! Temporary scales
2632      REAL(wp), DIMENSION(A2D(0)) ::   ztau_sc_u                               ! Dissipation timescale at base of WML
2633      REAL(wp)                    ::   zbuoy_pyc_sc, zdelta_pyc                !
2634      REAL(wp)                    ::   zl_c,zl_l,zl_eps                        ! Used to calculate turbulence length scale
2635      REAL(wp), DIMENSION(A2D(0)) ::   za_cubic, zb_cubic                      ! Coefficients in cubic polynomial specifying
2636      REAL(wp), DIMENSION(A2D(0)) ::   zc_cubic, zd_cubic                      ! diffusivity in pycnocline
2637      REAL(wp), DIMENSION(A2D(0)) ::   zwt_pyc_sc_1, zws_pyc_sc_1              !
2638      REAL(wp), DIMENSION(A2D(0)) ::   zzeta_pyc                               !
2639      REAL(wp)                    ::   zomega, zvw_max                         !
2640      REAL(wp), DIMENSION(A2D(0)) ::   zuw_bse,zvw_bse                         ! Momentum, heat, and salinity fluxes
2641      REAL(wp), DIMENSION(A2D(0)) ::   zwth_ent,zws_ent                        ! at the top of the pycnocline
2642      REAL(wp), DIMENSION(A2D(0)) ::   zsc_wth_pyc, zsc_ws_pyc                 ! Scales for pycnocline transport term
2643      REAL(wp)                    ::   ztmp                                    !
2644      REAL(wp)                    ::   ztgrad, zsgrad, zbgrad                  ! Variables used to calculate pycnocline gradients
2645      REAL(wp)                    ::   zugrad, zvgrad                          ! Variables for calculating pycnocline shear
2646      REAL(wp)                    ::   zdtdz_pyc                               ! Parametrized gradient of temperature in pycnocline
2647      REAL(wp)                    ::   zdsdz_pyc                               ! Parametrised gradient of salinity in pycnocline
2648      REAL(wp)                    ::   zdudz_pyc                               ! u-shear across the pycnocline
2649      REAL(wp)                    ::   zdvdz_pyc                               ! v-shear across the pycnocline
2650      !!----------------------------------------------------------------------
2651      !
2652      IF( ln_timing ) CALL timing_start('zdf_osm_ft')
2653      !
2654      ! Auxiliary indices
2655      ! -----------------
2656      jkm_bld = 0
2657      jkf_mld = jpk
2658      jkm_mld = 0
2659      DO_2D( 0, 0, 0, 0 )
2660         IF ( nbld(ji,jj) > jkm_bld ) jkm_bld = nbld(ji,jj)
2661         IF ( nmld(ji,jj) < jkf_mld ) jkf_mld = nmld(ji,jj)
2662         IF ( nmld(ji,jj) > jkm_mld ) jkm_mld = nmld(ji,jj)
2663      END_2D
2664      !
2665      ! Stokes term in scalar flux, flux-gradient relationship
2666      ! ------------------------------------------------------
2667      WHERE ( l_conv(A2D(0)) )
2668         zsc_wth_1(:,:) = swstrl(A2D(0))**3 * swth0(A2D(0)) / ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 + epsln )
2669         zsc_ws_1(:,:)  = swstrl(A2D(0))**3 * sws0(A2D(0))  / ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 + epsln )
2670      ELSEWHERE
2671         zsc_wth_1(:,:) = 2.0_wp * swthav(A2D(0))
2672         zsc_ws_1(:,:)  = 2.0_wp * swsav(A2D(0))
2673      ENDWHERE
2674      DO_3D( 0, 0, 0, 0, 2, MAX( jkm_mld, jkm_bld ) )
2675         IF ( l_conv(ji,jj) ) THEN
2676            IF ( jk <= nmld(ji,jj) ) THEN
2677               zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2678               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 1.35_wp * EXP( -1.0_wp * zznd_d ) *   &
2679                  &                                ( 1.0_wp - EXP( -2.0_wp * zznd_d ) ) * zsc_wth_1(ji,jj)
2680               ghams(ji,jj,jk) = ghams(ji,jj,jk) + 1.35_wp * EXP( -1.0_wp * zznd_d ) *   &
2681                  &                                ( 1.0_wp - EXP( -2.0_wp * zznd_d ) ) * zsc_ws_1(ji,jj)
2682            END IF
2683         ELSE   ! Stable conditions
2684            IF ( jk <= nbld(ji,jj) ) THEN
2685               zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2686               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 2.15_wp * EXP( -0.85_wp * zznd_d ) *   &
2687                  &                                ( 1.0_wp - EXP( -4.0_wp * zznd_d ) ) * zsc_wth_1(ji,jj)
2688               ghams(ji,jj,jk) = ghams(ji,jj,jk) + 2.15_wp * EXP( -0.85_wp * zznd_d ) *   &
2689                  &                                ( 1.0_wp - EXP( -4.0_wp * zznd_d ) ) * zsc_ws_1(ji,jj)
2690            END IF
2691         END IF   ! Check on l_conv
2692      END_3D
2693      !
2694      IF ( ln_dia_osm ) THEN
2695         IF ( iom_use("ghamu_00") ) CALL iom_put( "ghamu_00", wmask*ghamu )
2696         IF ( iom_use("ghamv_00") ) CALL iom_put( "ghamv_00", wmask*ghamv )
2697      END IF
2698      !
2699      ! Stokes term in flux-gradient relationship (note in zsc_uw_n don't use
2700      ! svstr since term needs to go to zero as swstrl goes to zero)
2701      ! ---------------------------------------------------------------------
2702      WHERE ( l_conv(A2D(0)) )
2703         zsc_uw_1(:,:) = ( swstrl(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 )**pthird * sustke(A2D(0)) /   &
2704            &                                  MAX( ( 1.0_wp - 1.0_wp * 6.5_wp * sla(A2D(0))**( 8.0_wp / 3.0_wp ) ), 0.2_wp )
2705         zsc_uw_2(:,:) = ( swstrl(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 )**pthird * sustke(A2D(0)) /   &
2706            &                                  MIN( sla(A2D(0))**( 8.0_wp / 3.0_wp ) + epsln, 0.12_wp )
2707         zsc_vw_1(:,:) = ff_t(A2D(0)) * phml(A2D(0)) * sustke(A2D(0))**3 * MIN( sla(A2D(0))**( 8.0_wp / 3.0_wp ), 0.12_wp ) /   &
2708            &            ( ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 )**( 2.0_wp / 3.0_wp ) + epsln )
2709      ELSEWHERE
2710         zsc_uw_1(:,:) = sustar(A2D(0))**2
2711         zsc_vw_1(:,:) = ff_t(A2D(0)) * phbl(A2D(0)) * sustke(A2D(0))**3 * MIN( sla(A2D(0))**( 8.0_wp / 3.0_wp ), 0.12_wp ) /   &
2712            &            ( svstr(A2D(0))**2 + epsln )
2713      ENDWHERE
2714      DO_3D( 0, 0, 0, 0, 2, MAX( jkm_mld, jkm_bld ) )
2715         IF ( l_conv(ji,jj) ) THEN
2716            IF ( jk <= nmld(ji,jj) ) THEN
2717               zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2718               ghamu(ji,jj,jk) = ghamu(ji,jj,jk) + ( -0.05_wp   * EXP( -0.4_wp * zznd_d ) * zsc_uw_1(ji,jj) +     &
2719                  &                                  0.00125_wp * EXP( -1.0_wp * zznd_d ) * zsc_uw_2(ji,jj) ) *   &
2720                  &                                ( 1.0_wp - EXP( -2.0_wp * zznd_d ) )
2721               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) - 0.65_wp *  0.15_wp * EXP( -1.0_wp * zznd_d ) *                 &
2722                  &                                ( 1.0_wp - EXP( -2.0_wp * zznd_d ) ) * zsc_vw_1(ji,jj)
2723            END IF
2724         ELSE   ! Stable conditions
2725            IF ( jk <= nbld(ji,jj) ) THEN   ! Corrected to nbld
2726               zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2727               ghamu(ji,jj,jk) = ghamu(ji,jj,jk) - 0.75_wp * 1.3_wp * EXP( -0.5_wp * zznd_d ) *             &
2728                  &                                ( 1.0_wp - EXP( -4.0_wp * zznd_d ) ) * zsc_uw_1(ji,jj)
2729            END IF
2730         END IF
2731      END_3D
2732#ifdef key_osm_debug
2733      IF(narea==nn_narea_db) THEN
2734         ji=iloc_db; jj=jloc_db
2735         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
2736         WRITE(narea+100,'(a,g11.3)')'Stokes contrib to ghamt/s:  zsc_wth_1=',zsc_wth_1(ji,jj), '  zsc_ws_1=',zsc_ws_1(ji,jj)
2737         WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
2738         WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
2739         IF( l_conv(ji,jj) ) THEN
2740            WRITE(narea+100,'(3(a,g11.3))')'Stokes contrib to ghamu/v:  zsc_uw_1=',zsc_uw_1(ji,jj), '  zsc_vw_1=',zsc_vw_1(ji,jj), &
2741               &' zsc_uw_2=',zsc_uw_2(ji,jj)
2742         ELSE
2743            WRITE(narea+100,'(2(a,g11.3))')'Stokes contrib to ghamu/v:  zsc_uw_1=',zsc_uw_1(ji,jj), '  zsc_vw_1=',zsc_vw_1(ji,jj)
2744         END IF
2745         WRITE(narea+100,'(a,*(g11.3))') ' ghamu[imld-1..ibld+2] =', ( ghamu(ji,jj,jk), jk=jl,jm )
2746         WRITE(narea+100,'(a,*(g11.3))') ' ghamv[imld-1..ibld+2] =', ( ghamv(ji,jj,jk), jk=jl,jm )
2747         WRITE(narea+100,*)
2748         FLUSH(narea+100)
2749      END IF
2750#endif
2751      !
2752      ! Buoyancy term in flux-gradient relationship [note : includes ROI ratio
2753      ! (X0.3) and pressure (X0.5)]
2754      ! ----------------------------------------------------------------------
2755      WHERE ( l_conv(A2D(0)) )
2756         zsc_wth_1(:,:) = swbav(A2D(0)) * swth0(A2D(0)) * ( 1.0_wp + EXP( 0.2_wp * shol(A2D(0)) ) ) * phml(A2D(0)) /   &
2757            &             ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 + epsln )
2758         zsc_ws_1(:,:)  = swbav(A2D(0)) * sws0(A2D(0))  * ( 1.0_wp + EXP( 0.2_wp * shol(A2D(0)) ) ) * phml(A2D(0)) /   &
2759            &             ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 + epsln )
2760      ELSEWHERE
2761         zsc_wth_1(:,:) = 0.0_wp
2762         zsc_ws_1(:,:)  = 0.0_wp
2763      ENDWHERE
2764      DO_3D( 0, 0, 0, 0, 2, MAX( jkm_mld, jkm_bld ) )
2765         IF ( l_conv(ji,jj) ) THEN
2766            IF ( jk <= nmld(ji,jj) ) THEN
2767               zznd_ml = gdepw(ji,jj,jk,Kmm) / phml(ji,jj)
2768               ! Calculate turbulent time scale
2769               zl_c   = 0.9_wp * ( 1.0_wp - EXP( -5.0_wp * ( zznd_ml + zznd_ml**3 / 3.0_wp ) ) ) *                         &
2770                  &     ( 1.0_wp - EXP( -15.0_wp * ( 1.2_wp - zznd_ml ) ) )
2771               zl_l   = 2.0_wp * ( 1.0_wp - EXP( -2.0_wp * ( zznd_ml + zznd_ml**3 / 3.0_wp ) ) ) *                         &
2772                  &     ( 1.0_wp - EXP( -8.0_wp  * ( 1.15_wp - zznd_ml ) ) ) * ( 1.0_wp + dstokes(ji,jj) / phml (ji,jj) )
2773               zl_eps = zl_l + ( zl_c - zl_l ) / ( 1.0_wp + EXP( -3.0_wp * LOG10( -1.0_wp * shol(ji,jj) ) ) )**( 3.0_wp / 2.0_wp )
2774               ! Non-gradient buoyancy terms
2775               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 0.3_wp * 0.4_wp * zsc_wth_1(ji,jj) * zl_eps / ( 0.15_wp + zznd_ml )
2776               ghams(ji,jj,jk) = ghams(ji,jj,jk) + 0.3_wp * 0.4_wp *  zsc_ws_1(ji,jj) * zl_eps / ( 0.15_wp + zznd_ml )
2777            END IF
2778         ELSE   ! Stable conditions
2779            IF ( jk <= nbld(ji,jj) ) THEN
2780               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + zsc_wth_1(ji,jj)
2781               ghams(ji,jj,jk) = ghams(ji,jj,jk) +  zsc_ws_1(ji,jj)
2782            END IF
2783         END IF
2784      END_3D
2785      DO_2D( 0, 0, 0, 0 )
2786         IF ( l_conv(ji,jj) .AND. l_pyc(ji,jj) ) THEN
2787            ztau_sc_u(ji,jj)    = phml(ji,jj) / ( svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**pthird *                             &
2788               &                ( 1.4_wp - 0.4_wp / ( 1.0_wp + EXP( -3.5_wp * LOG10( -1.0_wp * shol(ji,jj) ) ) )**1.5_wp )
2789            zwth_ent(ji,jj)     = -0.003_wp * ( 0.15_wp * svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**pthird *   &
2790               &                ( 1.0_wp - pdh(ji,jj) / phbl(ji,jj) ) * pdt_ml(ji,jj)
2791            zws_ent(ji,jj)      = -0.003_wp * ( 0.15_wp * svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**pthird *   &
2792               &                ( 1.0_wp - pdh(ji,jj) / phbl(ji,jj) ) * pds_ml(ji,jj)
2793            IF ( dh(ji,jj) < 0.2_wp * hbl(ji,jj) ) THEN
2794               zbuoy_pyc_sc        = 2.0_wp * MAX( pdb_ml(ji,jj), 0.0_wp ) / pdh(ji,jj)
2795               zdelta_pyc          = ( svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**pthird /   &
2796                  &                       SQRT( MAX( zbuoy_pyc_sc, ( svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**p2third / pdh(ji,jj)**2 ) )
2797               zwt_pyc_sc_1(ji,jj) = 0.325_wp * ( palpha_pyc(ji,jj) * pdt_ml(ji,jj) / pdh(ji,jj) + pdtdz_bl_ext(ji,jj) ) *   &
2798                  &                     zdelta_pyc**2 / pdh(ji,jj)
2799               zws_pyc_sc_1(ji,jj) = 0.325_wp * ( palpha_pyc(ji,jj) * pds_ml(ji,jj) / pdh(ji,jj) + pdsdz_bl_ext(ji,jj) ) *   &
2800                  &                     zdelta_pyc**2 / pdh(ji,jj)
2801               zzeta_pyc(ji,jj)    = 0.15_wp - 0.175_wp / ( 1.0_wp + EXP( -3.5_wp * LOG10( -1.0_wp * shol(ji,jj) ) ) )
2802#ifdef key_osm_debug
2803               IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2804                  WRITE(narea+100,'(2(a,g11.3))')'lpyc= lconv=T,dh<0.2*hbl: zbuoy_pyc_sc=',zbuoy_pyc_sc,' zdelta_pyc=',zdelta_pyc
2805                  WRITE(narea+100,'(3(a,g11.3))')'zwt_pyc_sc_1=',zwt_pyc_sc_1(ji,jj),' zws_pyc_sc_1=',zws_pyc_sc_1(ji,jj),   &
2806                     &                           ' zzeta_pyc=',zzeta_pyc(ji,jj)
2807                  FLUSH(narea+100)
2808               END IF
2809#endif
2810            END IF
2811         END IF
2812      END_2D
2813      DO_3D( 0, 0, 0, 0, 2, jkm_bld )
2814         IF ( l_conv(ji,jj) .AND. l_pyc(ji,jj) .AND. ( jk <= nbld(ji,jj) ) ) THEN
2815            zznd_pyc = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) / pdh(ji,jj)
2816            ghamt(ji,jj,jk) = ghamt(ji,jj,jk) -                                                                                &
2817               &              0.045_wp * ( ( zwth_ent(ji,jj) * pdbdz_pyc(ji,jj,jk) ) * ztau_sc_u(ji,jj)**2 ) *                 &
2818               &                         MAX( ( 1.75_wp * zznd_pyc -0.15_wp * zznd_pyc**2 - 0.2_wp * zznd_pyc**3 ), 0.0_wp )
2819            ghams(ji,jj,jk) = ghams(ji,jj,jk) -                                                                                &
2820               &              0.045_wp * ( ( zws_ent(ji,jj)  * pdbdz_pyc(ji,jj,jk) ) * ztau_sc_u(ji,jj)**2 ) *                 &
2821               &                         MAX( ( 1.75_wp * zznd_pyc -0.15_wp * zznd_pyc**2 - 0.2_wp * zznd_pyc**3 ), 0.0_wp )
2822#ifdef key_osm_debug
2823         END IF
2824      END_3D
2825      jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
2826      IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
2827         WRITE(narea+100,'(3(a,g11.3))')'lpyc= lconv=T: ztau_sc_u=',ztau_sc_u(ji,jj),' zwth_ent=',zwth_ent(ji,jj),   &
2828            &                           ' zws_ent=',zws_ent(ji,jj)
2829         WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
2830         WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
2831         WRITE(narea+100,*)
2832         FLUSH(narea+100)
2833      END IF
2834      DO_3D( 0, 0, 0, 0, 2, jkm_bld )
2835         IF ( l_conv(ji,jj) .AND. l_pyc(ji,jj) .AND. ( jk <= nbld(ji,jj) ) ) THEN
2836            zznd_pyc = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) / pdh(ji,jj)
2837#endif
2838            IF ( dh(ji,jj) < 0.2_wp * hbl(ji,jj) .AND. nbld(ji,jj) - nmld(ji,jj) > 3 ) THEN
2839               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 0.05_wp  * zwt_pyc_sc_1(ji,jj) *                              &
2840                  &                                EXP( -0.25_wp * ( zznd_pyc / zzeta_pyc(ji,jj) )**2 ) *        &
2841                  &                                pdh(ji,jj) / ( svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**pthird
2842               ghams(ji,jj,jk) = ghams(ji,jj,jk) + 0.05_wp  * zws_pyc_sc_1(ji,jj) *                              &
2843                  &                                EXP( -0.25_wp * ( zznd_pyc / zzeta_pyc(ji,jj) )**2 ) *        &
2844                  &                                pdh(ji,jj) / ( svstr(ji,jj)**3 + swstrc(ji,jj)**3 )**pthird
2845            END IF
2846         END IF   ! End of pycnocline
2847      END_3D
2848      !
2849      IF(ln_dia_osm) THEN
2850         IF ( iom_use("zwth_ent") ) CALL iom_put( "zwth_ent", tmask(:,:,1)*zwth_ent )   ! Upward turb. temperature entrainment flux
2851         IF ( iom_use("zws_ent")  ) CALL iom_put( "zws_ent",  tmask(:,:,1)*zws_ent  )   ! Upward turb. salinity    entrainment flux
2852      END IF
2853      !
2854      zsc_vw_1(:,:) = 0.0_wp
2855      WHERE ( l_conv(A2D(0)) )
2856         zsc_uw_1(:,:) = -1.0_wp * swb0(A2D(0)) * sustar(A2D(0))**2 * phml(A2D(0)) /   &
2857            &            ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 + epsln )
2858         zsc_uw_2(:,:) =           swb0(A2D(0)) * sustke(A2D(0))    * phml(A2D(0)) /   &
2859            &            ( svstr(A2D(0))**3 + 0.5_wp * swstrc(A2D(0))**3 + epsln )**( 2.0_wp / 3.0_wp )
2860      ELSEWHERE
2861         zsc_uw_1(:,:) = 0.0_wp
2862      ENDWHERE
2863      DO_3D( 0, 0, 0, 0, 2, MAX( jkm_mld, jkm_bld ) )
2864         IF ( l_conv(ji,jj) ) THEN
2865            IF ( jk <= nmld(ji,jj) ) THEN
2866               zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2867               ghamu(ji,jj,jk) = ghamu(ji,jj,jk) + 0.3_wp * 0.5_wp *   &
2868                  &                                ( zsc_uw_1(ji,jj) + 0.125_wp * EXP( -0.5_wp * zznd_d ) *       &
2869                  &                                  (   1.0_wp - EXP( -0.5_wp * zznd_d ) ) * zsc_uw_2(ji,jj) )
2870               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) + zsc_vw_1(ji,jj)
2871            END IF
2872         ELSE   ! Stable conditions
2873            IF ( jk <= nbld(ji,jj) ) THEN
2874               ghamu(ji,jj,jk) = ghamu(ji,jj,jk) + zsc_uw_1(ji,jj)
2875               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) + zsc_vw_1(ji,jj)
2876            END IF
2877         ENDIF
2878      END_3D
2879      !
2880      DO_2D( 0, 0, 0, 0 )
2881         IF ( l_conv(ji,jj) .AND. l_pyc(ji,jj) ) THEN
2882            IF ( n_ddh(ji,jj) == 0 ) THEN
2883               ! Place holding code. Parametrization needs checking for these conditions.
2884               zomega = ( 0.15_wp * swstrl(ji,jj)**3 + swstrc(ji,jj)**3 + 4.75_wp * ( pshear(ji,jj) * phbl(ji,jj) ) )**pthird
2885               zuw_bse(ji,jj) = -0.0035_wp * zomega * ( 1.0_wp - pdh(ji,jj) / phbl(ji,jj) ) * pdu_ml(ji,jj)
2886               zvw_bse(ji,jj) = -0.0075_wp * zomega * ( 1.0_wp - pdh(ji,jj) / phbl(ji,jj) ) * pdv_ml(ji,jj)
2887            ELSE
2888               zomega = ( 0.15_wp * swstrl(ji,jj)**3 + swstrc(ji,jj)**3 + 4.75_wp * ( pshear(ji,jj) * phbl(ji,jj) ) )**pthird
2889               zuw_bse(ji,jj) = -0.0035_wp * zomega * ( 1.0_wp - pdh(ji,jj) / phbl(ji,jj) ) * pdu_ml(ji,jj)
2890               zvw_bse(ji,jj) = -0.0075_wp * zomega * ( 1.0_wp - pdh(ji,jj) / phbl(ji,jj) ) * pdv_ml(ji,jj)
2891            ENDIF
2892            zb_cubic(ji,jj) = pdh(ji,jj) / phbl(ji,jj) * suw0(ji,jj) - ( 2.0 + pdh(ji,jj) / phml(ji,jj) ) * zuw_bse(ji,jj)
2893            za_cubic(ji,jj) = zuw_bse(ji,jj) - zb_cubic(ji,jj)
2894            zvw_max = 0.7_wp * ff_t(ji,jj) * ( sustke(ji,jj) * dstokes(ji,jj) + 0.7_wp * sustar(ji,jj) * phml(ji,jj) )
2895            zd_cubic(ji,jj) = zvw_max * pdh(ji,jj) / phml(ji,jj) - ( 2.0_wp + pdh(ji,jj) / phml(ji,jj) ) * zvw_bse(ji,jj)
2896            zc_cubic(ji,jj) = zvw_bse(ji,jj) - zd_cubic(ji,jj)
2897         END IF
2898      END_2D
2899      DO_3D( 0, 0, 0, 0, jkf_mld, jkm_bld )   ! Need ztau_sc_u to be available. Change to array.
2900         IF ( l_conv(ji,jj) .AND. l_pyc(ji,jj) .AND. ( jk >= nmld(ji,jj) ) .AND. ( jk <= nbld(ji,jj) ) ) THEN
2901            zznd_pyc = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) / pdh(ji,jj)
2902            ghamu(ji,jj,jk) = ghamu(ji,jj,jk) - 0.045_wp * ( ztau_sc_u(ji,jj)**2 ) * zuw_bse(ji,jj) *                 &
2903               &                                ( za_cubic(ji,jj) * zznd_pyc**2 + zb_cubic(ji,jj) * zznd_pyc**3 ) *   &
2904               &                                ( 0.75_wp + 0.25_wp * zznd_pyc )**2 * pdbdz_pyc(ji,jj,jk)
2905            ghamv(ji,jj,jk) = ghamv(ji,jj,jk) - 0.045_wp * ( ztau_sc_u(ji,jj)**2 ) * zvw_bse(ji,jj) *                 &
2906               &                                ( zc_cubic(ji,jj) * zznd_pyc**2 + zd_cubic(ji,jj) * zznd_pyc**3 ) *   &
2907               &                                ( 0.75_wp + 0.25_wp * zznd_pyc )**2 * pdbdz_pyc(ji,jj,jk)
2908         END IF   ! l_conv .AND. l_pyc
2909      END_3D
2910      !
2911#ifdef key_osm_debug
2912      IF(narea==nn_narea_db) THEN
2913         ji=iloc_db; jj=jloc_db
2914         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
2915         WRITE(narea+100,'(2(a,g11.3))')'Stokes + buoy + pyc contribs to ghamt/s:  zsc_wth_1=',zsc_wth_1(ji,jj), '  zsc_ws_1=',zsc_ws_1(ji,jj)
2916         WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
2917         WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
2918         IF( l_conv(ji,jj) ) THEN
2919            WRITE(narea+100,'(3(a,g11.3))')'Stokes + buoy + pyc contribs to ghamu/v:  zsc_uw_1=',zsc_uw_1(ji,jj), '  zsc_vw_1=',zsc_vw_1(ji,jj), &
2920               &' zsc_uw_2=',zsc_uw_2(ji,jj)
2921         ELSE
2922            WRITE(narea+100,'(2(a,g11.3))')'Stokes + buoy + pyc contribs to ghamu/v:  zsc_uw_1=',zsc_uw_1(ji,jj), '  zsc_vw_1=',zsc_vw_1(ji,jj)
2923         END IF
2924         WRITE(narea+100,'(a,*(g11.3))') ' ghamu[imld-1..ibld+2] =', ( ghamu(ji,jj,jk), jk=jl,jm )
2925         WRITE(narea+100,'(a,*(g11.3))') ' ghamv[imld-1..ibld+2] =', ( ghamv(ji,jj,jk), jk=jl,jm )
2926         WRITE(narea+100,*)
2927         FLUSH(narea+100)
2928      END IF
2929#endif
2930
2931      IF(ln_dia_osm) THEN
2932         IF ( iom_use("ghamu_0") )    CALL iom_put( "ghamu_0",    wmask*ghamu           )
2933         IF ( iom_use("zsc_uw_1_0") ) CALL iom_put( "zsc_uw_1_0", tmask(:,:,1)*zsc_uw_1 )
2934      END IF
2935      !
2936      ! Transport term in flux-gradient relationship [note : includes ROI ratio
2937      ! (X0.3) ]
2938      ! -----------------------------------------------------------------------
2939      WHERE ( l_conv(A2D(0)) )
2940         zsc_wth_1(:,:) = swth0(A2D(0)) / ( 1.0_wp - 0.56_wp * EXP( shol(A2D(0)) ) )
2941         zsc_ws_1(:,:)  = sws0(A2D(0))  / ( 1.0_wp - 0.56_wp * EXP( shol(A2D(0)) ) )
2942         WHERE ( l_pyc(A2D(0)) )   ! Pycnocline scales
2943            zsc_wth_pyc(:,:) = -0.003_wp * swstrc(A2D(0)) * ( 1.0_wp - pdh(A2D(0)) / phbl(A2D(0)) ) * pdt_ml(A2D(0))
2944            zsc_ws_pyc(:,:)  = -0.003_wp * swstrc(A2D(0)) * ( 1.0_wp - pdh(A2D(0)) / phbl(A2D(0)) ) * pds_ml(A2D(0))
2945         END WHERE
2946      ELSEWHERE
2947         zsc_wth_1(:,:) = 2.0 * swthav(A2D(0))
2948         zsc_ws_1(:,:)  =       sws0(A2D(0))
2949      END WHERE
2950      DO_3D( 0, 0, 0, 0, 1, MAX( jkm_mld, jkm_bld ) )
2951         IF ( l_conv(ji,jj) ) THEN
2952            IF ( ( jk > 1 ) .AND. ( jk <= nmld(ji,jj) ) ) THEN
2953               zznd_ml = gdepw(ji,jj,jk,Kmm) / phml(ji,jj)
2954               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 0.3_wp * zsc_wth_1(ji,jj) * ( -2.0_wp + 2.75_wp * ( ( 1.0_wp + 0.6_wp * zznd_ml**4 ) - EXP( -6.0_wp * zznd_ml ) ) ) *   &
2955                  &      ( 1.0_wp - EXP( -15.0_wp * ( 1.0_wp - zznd_ml ) ) )
2956               ghams(ji,jj,jk) = ghams(ji,jj,jk) + 0.3_wp * zsc_ws_1(ji,jj)  * ( -2.0_wp + 2.75_wp * ( ( 1.0_wp + 0.6_wp * zznd_ml**4 ) - EXP( -6.0_wp * zznd_ml ) ) ) *   &
2957                  &      ( 1.0_wp - EXP( -15.0_wp * ( 1.0_wp - zznd_ml ) ) )
2958            END IF
2959            !
2960            ! may need to comment out lpyc block
2961            IF ( l_pyc(ji,jj) .AND. ( jk >= nmld(ji,jj) ) .AND. ( jk <= nbld(ji,jj) ) ) THEN   ! Pycnocline
2962               zznd_pyc = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) / pdh(ji,jj)
2963               ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 4.0_wp * zsc_wth_pyc(ji,jj) * ( 0.48_wp - EXP( -1.5_wp * ( zznd_pyc - 0.3_wp )**2 ) )
2964               ghams(ji,jj,jk) = ghams(ji,jj,jk) + 4.0_wp * zsc_ws_pyc(ji,jj)  * ( 0.48_wp - EXP( -1.5_wp * ( zznd_pyc - 0.3_wp )**2 ) )
2965            END IF
2966         ELSE
2967            IF( pdhdt(ji,jj) > 0. ) THEN
2968               IF ( ( jk > 1 ) .AND. ( jk <= nbld(ji,jj) ) ) THEN
2969                  zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2970                  znd    = gdepw(ji,jj,jk,Kmm) / phbl(ji,jj)
2971                  ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + 0.3_wp * ( -4.06_wp * EXP( -2.0_wp * zznd_d ) * ( 1.0_wp - EXP( -4.0_wp * zznd_d ) ) +   &
2972                     7.5_wp * EXP ( -10.0_wp * ( 0.95_wp - znd )**2 ) * ( 1.0_wp - znd ) ) * zsc_wth_1(ji,jj)
2973                  ghams(ji,jj,jk) = ghams(ji,jj,jk) + 0.3_wp * ( -4.06_wp * EXP( -2.0_wp * zznd_d ) * ( 1.0_wp - EXP( -4.0_wp * zznd_d ) ) +   &
2974                     7.5_wp * EXP ( -10.0_wp * ( 0.95_wp - znd )**2 ) * ( 1.0_wp - znd ) ) * zsc_ws_1(ji,jj)
2975               END IF
2976            ENDIF
2977         ENDIF
2978      END_3D
2979      !
2980      WHERE ( l_conv(A2D(0)) )
2981         zsc_uw_1(:,:) = sustar(A2D(0))**2
2982         zsc_vw_1(:,:) = ff_t(A2D(0)) * sustke(A2D(0)) * phml(A2D(0))
2983      ELSEWHERE
2984         zsc_uw_1(:,:) = sustar(A2D(0))**2
2985         zsc_uw_2(:,:) = ( 2.25_wp - 3.0_wp * ( 1.0_wp - EXP( -1.25_wp * 2.0_wp ) ) ) * ( 1.0_wp - EXP( -4.0_wp * 2.0_wp ) ) *   &
2986            &            zsc_uw_1(:,:)
2987         zsc_vw_1(:,:) = ff_t(A2D(0)) * sustke(A2D(0)) * phbl(A2D(0))
2988         zsc_vw_2(:,:) = -0.11_wp * SIN( 3.14159_wp * ( 2.0_wp + 0.4_wp ) ) * EXP( -1.0_wp * ( 1.5_wp + 2.0_wp )**2 ) *   &
2989            &            zsc_vw_1(:,:)
2990      ENDWHERE
2991      DO_3D( 0, 0, 0, 0, 2, MAX( jkm_mld, jkm_bld ) )
2992         IF ( l_conv(ji,jj) ) THEN
2993            IF ( jk <= nmld(ji,jj) ) THEN
2994               zznd_ml = gdepw(ji,jj,jk,Kmm) / phml(ji,jj)
2995               zznd_d  = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
2996               ghamu(ji,jj,jk) = ghamu(ji,jj,jk) +   &
2997                  &              0.3_wp * ( -2.0_wp + 2.5_wp * ( 1.0_wp + 0.1_wp * zznd_ml**4 ) - EXP( -8.0_wp * zznd_ml ) ) *   &
2998                  &              zsc_uw_1(ji,jj)
2999               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) +   &
3000                  &              0.3_wp * 0.1_wp * ( EXP( -1.0_wp * zznd_d ) + EXP( -5.0_wp * ( 1.0_wp - zznd_ml ) ) ) *   &
3001                  &              zsc_vw_1(ji,jj)
3002            END IF
3003         ELSE
3004            IF ( jk <= nbld(ji,jj) ) THEN
3005               znd    = gdepw(ji,jj,jk,Kmm) / phbl(ji,jj)
3006               zznd_d = gdepw(ji,jj,jk,Kmm) / dstokes(ji,jj)
3007               IF ( zznd_d <= 2.0 ) THEN
3008                  ghamu(ji,jj,jk) = ghamu(ji,jj,jk) + 0.5_wp * 0.3_wp *                                              &
3009                     &                                ( 2.25_wp - 3.0_wp * ( 1.0_wp - EXP( -1.25_wp * zznd_d ) ) *   &
3010                     &                                  ( 1.0_wp - EXP( -2.0_wp * zznd_d ) ) ) * zsc_uw_1(ji,jj)
3011               ELSE
3012                  ghamu(ji,jj,jk) = ghamu(ji,jj,jk) + 0.5_wp * 0.3_wp *   &
3013                     &                                ( 1.0_wp - EXP( -5.0_wp * ( 1.0_wp - znd ) ) ) * zsc_uw_2(ji,jj)
3014               ENDIF
3015               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) + 0.3_wp * 0.15_wp * SIN( 3.14159_wp * ( 0.65_wp * zznd_d ) ) *   &
3016                  &                                EXP( -0.25_wp * zznd_d**2 ) * zsc_vw_1(ji,jj)
3017               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) + 0.3_wp * 0.15_wp * EXP( -5.0 * ( 1.0 - znd ) ) * ( 1.0 - EXP( -20.0 * ( 1.0 - znd ) ) ) * zsc_vw_2(ji,jj)
3018            END IF
3019         END IF
3020      END_3D
3021#ifdef key_osm_debug
3022      IF(narea==nn_narea_db) THEN
3023         ji=iloc_db; jj=jloc_db
3024         jl = nmld(ji,jj) - 1; jm = MIN( nbld(ji,jj) + 2, mbkt(ji,jj) )
3025         WRITE(narea+100,'(2(a,g11.3))')'Stokes + buoy + pyc + transport contribs to ghamt/s:  zsc_wth_1=',zsc_wth_1(ji,jj), '  zsc_ws_1=',zsc_ws_1(ji,jj)
3026         IF (l_pyc(ji,jj)) WRITE(narea+100,'(2(a,g11.3))') 'zsc_wth_pyc=', zsc_wth_pyc(ji,jj), '  zsc_wth_pyc=',zsc_wth_pyc(ji,jj)
3027         WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
3028         WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
3029         IF( l_conv(ji,jj) ) THEN
3030            WRITE(narea+100,'(2(a,g11.3))')'Unstable; transport contrib to ghamu/v:  zsc_uw_1=',zsc_uw_1(ji,jj), '  zsc_vw_1=',zsc_vw_1(ji,jj)
3031         ELSE
3032            WRITE(narea+100,'(3(a,g11.3))')'Stable; transport contrib to ghamu/v:  zsc_uw_1=',zsc_uw_1(ji,jj), '  zsc_vw_1=',zsc_vw_1(ji,jj), &
3033               &' zsc_uw_2=',zsc_uw_2(ji,jj)
3034         END IF
3035         WRITE(narea+100,'(a,*(g11.3))') ' ghamu[imld-1..ibld+2] =', ( ghamu(ji,jj,jk), jk=jl,jm )
3036         WRITE(narea+100,*)
3037         FLUSH(narea+100)
3038      END IF
3039#endif
3040      !
3041      IF(ln_dia_osm) THEN
3042         IF ( iom_use("ghamu_f") )    CALL iom_put( "ghamu_f",    wmask       *ghamu    )
3043         IF ( iom_use("ghamv_f") )    CALL iom_put( "ghamv_f",    wmask       *ghamv    )
3044         IF ( iom_use("zsc_uw_1_f") ) CALL iom_put( "zsc_uw_1_f", tmask(:,:,1)*zsc_uw_1 )
3045         IF ( iom_use("zsc_vw_1_f") ) CALL iom_put( "zsc_vw_1_f", tmask(:,:,1)*zsc_vw_1 )
3046         IF ( iom_use("zsc_uw_2_f") ) CALL iom_put( "zsc_uw_2_f", tmask(:,:,1)*zsc_uw_2 )
3047         IF ( iom_use("zsc_vw_2_f") ) CALL iom_put( "zsc_vw_2_f", tmask(:,:,1)*zsc_vw_2 )
3048      END IF
3049      !
3050      ! Make surface forced velocity non-gradient terms go to zero at the base
3051      ! of the mixed layer.
3052      !
3053      ! Make surface forced velocity non-gradient terms go to zero at the base
3054      ! of the boundary layer.
3055      DO_3D( 0, 0, 0, 0, 2, jkm_bld )
3056         IF ( ( .NOT. l_conv(ji,jj) ) .AND. ( jk <= nbld(ji,jj) ) ) THEN
3057            znd = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) / phbl(ji,jj)   ! ALMG to think about
3058            IF ( znd >= 0.0_wp ) THEN
3059               ghamu(ji,jj,jk) = ghamu(ji,jj,jk) * ( 1.0_wp - EXP( -10.0_wp * znd**2 ) )
3060               ghamv(ji,jj,jk) = ghamv(ji,jj,jk) * ( 1.0_wp - EXP( -10.0_wp * znd**2 ) )
3061            ELSE
3062               ghamu(ji,jj,jk) = 0.0_wp
3063               ghamv(ji,jj,jk) = 0.0_wp
3064            ENDIF
3065         END IF
3066      END_3D
3067      !
3068      ! Pynocline contributions
3069      !
3070      IF ( ln_dia_pyc_scl .OR. ln_dia_pyc_shr ) THEN   ! Allocate arrays for output of pycnocline gradient/shear profiles
3071         ALLOCATE( z3ddz_pyc_1(jpi,jpj,jpk), z3ddz_pyc_2(jpi,jpj,jpk), STAT=istat )
3072         IF ( istat /= 0 ) CALL ctl_stop( 'zdf_osm: failed to allocate temporary arrays' )
3073         z3ddz_pyc_1(:,:,:) = 0.0_wp
3074         z3ddz_pyc_2(:,:,:) = 0.0_wp
3075      END IF
3076      DO_3D( 0, 0, 0, 0, 2, jkm_bld )
3077         IF ( l_conv (ji,jj) ) THEN
3078            ! Unstable conditions. Shouldn;t be needed with no pycnocline code.
3079            !                  zugrad = 0.7 * zdu_ml(ji,jj) / zdh(ji,jj) + 0.3 * zustar(ji,jj)*zustar(ji,jj) / &
3080            !                       &      ( ( ( zvstr(ji,jj)**3 + 0.5 * zwstrc(ji,jj)**3 )**pthird * zhml(ji,jj) ) * &
3081            !                      &      MIN(zla(ji,jj)**(8.0/3.0) + epsln, 0.12 ))
3082            !Alan is this right?
3083            !                  zvgrad = ( 0.7 * zdv_ml(ji,jj) + &
3084            !                       &    2.0 * ff_t(ji,jj) * zustke(ji,jj) * dstokes(ji,jj) / &
3085            !                       &          ( ( zvstr(ji,jj)**3 + 0.5 * zwstrc(ji,jj)**3 )**pthird  + epsln ) &
3086            !                       &      )/ (zdh(ji,jj)  + epsln )
3087            !                  DO jk = 2, nbld(ji,jj) - 1 + ibld_ext
3088            !                     znd = -( gdepw(ji,jj,jk,Kmm) - zhbl(ji,jj) ) / (zdh(ji,jj) + epsln ) - zzeta_v
3089            !                     IF ( znd <= 0.0 ) THEN
3090            !                        zdudz(ji,jj,jk) = 1.25 * zugrad * EXP( 3.0 * znd )
3091            !                        zdvdz(ji,jj,jk) = 1.25 * zvgrad * EXP( 3.0 * znd )
3092            !                     ELSE
3093            !                        zdudz(ji,jj,jk) = 1.25 * zugrad * EXP( -2.0 * znd )
3094            !                        zdvdz(ji,jj,jk) = 1.25 * zvgrad * EXP( -2.0 * znd )
3095            !                     ENDIF
3096            !                  END DO
3097         ELSE   ! Stable conditions
3098            IF ( nbld(ji,jj) + kp_ext(ji,jj) < mbkt(ji,jj) ) THEN
3099               ! Pycnocline profile only defined when depth steady of increasing.
3100               IF ( pdhdt(ji,jj) > 0.0_wp ) THEN   ! Depth increasing, or steady.
3101                  IF ( pdb_bl(ji,jj) > 0.0_wp ) THEN
3102                     IF ( shol(ji,jj) >= 0.5_wp ) THEN   ! Very stable - 'thick' pycnocline
3103                        ztmp = 1.0_wp / MAX( phbl(ji,jj), epsln )
3104                        ztgrad = pdt_bl(ji,jj) * ztmp
3105                        zsgrad = pds_bl(ji,jj) * ztmp
3106                        zbgrad = pdb_bl(ji,jj) * ztmp
3107                        IF ( jk <= nbld(ji,jj) ) THEN
3108                           znd = gdepw(ji,jj,jk,Kmm) * ztmp
3109                           zdtdz_pyc =  ztgrad * EXP( -15.0_wp * ( znd - 0.9_wp )**2 )
3110                           zdsdz_pyc =  zsgrad * EXP( -15.0_wp * ( znd - 0.9_wp )**2 )
3111                           ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + pdiffut(ji,jj,jk) * zdtdz_pyc
3112                           ghams(ji,jj,jk) = ghams(ji,jj,jk) + pdiffut(ji,jj,jk) * zdsdz_pyc
3113                           IF ( ln_dia_pyc_scl ) THEN
3114                              z3ddz_pyc_1(ji,jj,jk) = zdtdz_pyc
3115                              z3ddz_pyc_2(ji,jj,jk) = zdsdz_pyc
3116                           END IF
3117                        END IF
3118                     ELSE   ! Slightly stable - 'thin' pycnoline - needed when stable layer begins to form.
3119                        ztmp = 1.0_wp / MAX( pdh(ji,jj), epsln )
3120                        ztgrad = pdt_bl(ji,jj) * ztmp
3121                        zsgrad = pds_bl(ji,jj) * ztmp
3122                        zbgrad = pdb_bl(ji,jj) * ztmp
3123                        IF ( jk <= nbld(ji,jj) ) THEN
3124                           znd = -1.0_wp * ( gdepw(ji,jj,jk,Kmm) - phml(ji,jj) ) * ztmp
3125                           zdtdz_pyc =  ztgrad * EXP( -1.75_wp * ( znd + 0.75_wp )**2 )
3126                           zdsdz_pyc =  zsgrad * EXP( -1.75_wp * ( znd + 0.75_wp )**2 )
3127                           ghamt(ji,jj,jk) = ghamt(ji,jj,jk) + pdiffut(ji,jj,jk) * zdtdz_pyc
3128                           ghams(ji,jj,jk) = ghams(ji,jj,jk) + pdiffut(ji,jj,jk) * zdsdz_pyc
3129                           IF ( ln_dia_pyc_scl ) THEN
3130                              z3ddz_pyc_1(ji,jj,jk) = zdtdz_pyc
3131                              z3ddz_pyc_2(ji,jj,jk) = zdsdz_pyc
3132                           END IF
3133                        END IF
3134                     ENDIF   ! IF (shol >=0.5)
3135                  ENDIF      ! IF (zdb_bl> 0.)
3136               ENDIF         ! IF (zdhdt >= 0) zdhdt < 0 not considered since pycnocline profile is zero and profile arrays are intialized to zero
3137            END IF
3138         END IF
3139      END_3D
3140      IF ( ln_dia_pyc_scl ) THEN   ! Output of pycnocline gradient profiles
3141         IF ( iom_use("zdtdz_pyc") ) CALL iom_put( "zdtdz_pyc", wmask(:,:,:) * z3ddz_pyc_1(:,:,:) )
3142         IF ( iom_use("zdsdz_pyc") ) CALL iom_put( "zdsdz_pyc", wmask(:,:,:) * z3ddz_pyc_2(:,:,:) )
3143      END IF
3144      DO_3D( 0, 0, 0, 0, 2, jkm_bld )
3145         IF ( .NOT. l_conv (ji,jj) ) THEN
3146            IF ( nbld(ji,jj) + kp_ext(ji,jj) < mbkt(ji,jj) ) THEN
3147               zugrad = 3.25_wp * pdu_bl(ji,jj) / phbl(ji,jj)
3148               zvgrad = 2.75_wp * pdv_bl(ji,jj) / phbl(ji,jj)
3149               IF ( jk <= nbld(ji,jj) ) THEN
3150                  znd = gdepw(ji,jj,jk,Kmm) / phbl(ji,jj)
3151                  IF ( znd < 1.0 ) THEN
3152                     zdudz_pyc = zugrad * EXP( -40.0_wp * ( znd - 1.0_wp )**2 )
3153                  ELSE
3154                     zdudz_pyc = zugrad * EXP( -20.0_wp * ( znd - 1.0_wp )**2 )
3155                  ENDIF
3156                  zdvdz_pyc = zvgrad * EXP( -20.0_wp * ( znd - 0.85_wp )**2 )
3157                  ghamu(ji,jj,jk) = ghamu(ji,jj,jk) + pviscos(ji,jj,jk) * zdudz_pyc
3158                  ghamv(ji,jj,jk) = ghamv(ji,jj,jk) + pviscos(ji,jj,jk) * zdvdz_pyc
3159                  IF ( ln_dia_pyc_shr ) THEN
3160                     z3ddz_pyc_1(ji,jj,jk) = zdudz_pyc
3161                     z3ddz_pyc_2(ji,jj,jk) = zdvdz_pyc
3162                  END IF
3163               END IF
3164            END IF
3165         END IF
3166      END_3D
3167      IF ( ln_dia_pyc_shr ) THEN   ! Output of pycnocline shear profiles
3168         IF ( iom_use("dudz_pyc") ) CALL iom_put( "zdudz_pyc", wmask(:,:,:) * z3ddz_pyc_1(:,:,:) )
3169         IF ( iom_use("dvdz_pyc") ) CALL iom_put( "zdvdz_pyc", wmask(:,:,:) * z3ddz_pyc_2(:,:,:) )
3170      END IF
3171      IF(ln_dia_osm) THEN
3172         IF ( iom_use("ghamu_b") ) CALL iom_put( "ghamu_b", wmask*ghamu )
3173         IF ( iom_use("ghamv_b") ) CALL iom_put( "ghamv_b", wmask*ghamv )
3174      END IF
3175      IF ( ln_dia_pyc_scl .OR. ln_dia_pyc_shr ) THEN   ! Deallocate arrays used for output of pycnocline gradient/shear profiles
3176         DEALLOCATE( z3ddz_pyc_1, z3ddz_pyc_2 )
3177      END IF
3178      !
3179      DO_2D( 0, 0, 0, 0 )
3180         ghamt(ji,jj,nbld(ji,jj)) = 0.0_wp
3181         ghams(ji,jj,nbld(ji,jj)) = 0.0_wp
3182         ghamu(ji,jj,nbld(ji,jj)) = 0.0_wp
3183         ghamv(ji,jj,nbld(ji,jj)) = 0.0_wp
3184      END_2D
3185#ifdef key_osm_debug
3186      IF(narea==nn_narea_db) THEN
3187         ji=iloc_db; jj=jloc_db
3188         jl = nmld(ji,jj) - 1; jm = MIN(nbld(ji,jj) + 2, mbkt(ji,jj) )
3189         WRITE(narea+100,'(a)')'Tweak gham[uv] to go to zero near surface, add pycnocline viscosity/diffusivity  & set=0 at ibld'
3190         WRITE(narea+100,'(a,*(g11.3))') ' ghamt[imld-1..ibld+2] =', ( ghamt(ji,jj,jk), jk=jl,jm )
3191         WRITE(narea+100,'(a,*(g11.3))') ' ghams[imld-1..ibld+2] =', ( ghams(ji,jj,jk), jk=jl,jm )
3192         WRITE(narea+100,'(a,*(g11.3))') ' ghamu[imld-1..ibld+2] =', ( ghamu(ji,jj,jk), jk=jl,jm )
3193         WRITE(narea+100,'(a,*(g11.3))') ' ghamv[imld-1..ibld+2] =', ( ghamv(ji,jj,jk), jk=jl,jm )
3194         WRITE(narea+100,*)
3195         FLUSH(narea+100)
3196      END IF
3197#endif
3198      !
3199      IF(ln_dia_osm) THEN
3200         IF ( iom_use("ghamu_1") ) CALL iom_put( "ghamu_1", wmask*ghamu   )
3201         IF ( iom_use("ghamv_1") ) CALL iom_put( "ghamv_1", wmask*ghamv   )
3202         IF ( iom_use("zviscos") ) CALL iom_put( "zviscos", wmask*pviscos )
3203      END IF
3204      !
3205      IF( ln_timing ) CALL timing_stop('zdf_osm_ft')
3206      !
3207   END SUBROUTINE zdf_osm_fgr_terms
3208
3209   SUBROUTINE zdf_osm_zmld_horizontal_gradients( Kmm, pmld, pdtdx, pdtdy, pdsdx,   &
3210      &                                          pdsdy, pdbdx_mle, pdbdy_mle, pdbds_mle )
3211      !!----------------------------------------------------------------------
3212      !!          ***  ROUTINE zdf_osm_zmld_horizontal_gradients  ***
3213      !!
3214      !! ** Purpose : Calculates horizontal gradients of buoyancy for use with
3215      !!              Fox-Kemper parametrization
3216      !!
3217      !! ** Method  :
3218      !!
3219      !! References: Fox-Kemper et al., JPO, 38, 1145-1165, 2008
3220      !!             Fox-Kemper and Ferrari, JPO, 38, 1166-1179, 2008
3221      !!
3222      !!----------------------------------------------------------------------
3223      INTEGER,                  INTENT(in   ) ::   Kmm          ! Time-level index
3224      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   pmld         ! == Estimated FK BLD used for MLE horizontal gradients == !
3225      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdtdx        ! Horizontal gradient for Fox-Kemper parametrization
3226      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdtdy        ! Horizontal gradient for Fox-Kemper parametrization
3227      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdsdx        ! Horizontal gradient for Fox-Kemper parametrization
3228      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdsdy        ! Horizontal gradient for Fox-Kemper parametrization
3229      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdbdx_mle    ! MLE horiz gradients at u points
3230      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdbdy_mle    ! MLE horiz gradients at v points
3231      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pdbds_mle    ! Magnitude of horizontal buoyancy gradient
3232      !
3233      ! Local variables
3234      INTEGER                          ::   ji, jj, jk   ! Dummy loop indices
3235      INTEGER                          ::   ikt, ikmax   ! Local integers     
3236      REAL(wp)                         ::   zc
3237      REAL(wp)                         ::   zN2_c        ! Local buoyancy difference from 10m value
3238      REAL(wp), DIMENSION(A2D(1))      ::   ztm
3239      REAL(wp), DIMENSION(A2D(1))      ::   zsm
3240      REAL(wp), DIMENSION(A2D(1),jpts) ::   ztsm_midu
3241      REAL(wp), DIMENSION(A2D(1),jpts) ::   ztsm_midv
3242      REAL(wp), DIMENSION(A2D(1),jpts) ::   zabu
3243      REAL(wp), DIMENSION(A2D(1),jpts) ::   zabv
3244      REAL(wp), DIMENSION(A2D(1))      ::   zmld_midu
3245      REAL(wp), DIMENSION(A2D(1))      ::   zmld_midv
3246      !
3247      IF( ln_timing ) CALL timing_start('zdf_osm_zhg')
3248      !
3249      ! ==  MLD used for MLE  ==!
3250      mld_prof(:,:) = nlb10   ! Initialization to the number of w ocean point
3251      pmld(:,:)  = 0.0_wp     ! Here hmlp used as a dummy variable, integrating vertically N^2
3252      zN2_c = grav * rn_osm_mle_rho_c * r1_rho0   ! Convert density criteria into N^2 criteria
3253      DO_3D( 1, 1, 1, 1, nlb10, jpkm1 )
3254         ikt = mbkt(ji,jj)
3255         pmld(ji,jj) = pmld(ji,jj) + MAX( rn2b(ji,jj,jk), 0.0_wp ) * e3w(ji,jj,jk,Kmm)
3256         IF( pmld(ji,jj) < zN2_c ) mld_prof(ji,jj) = MIN( jk , ikt ) + 1   ! Mixed layer level
3257      END_3D
3258      DO_2D( 1, 1, 1, 1 )
3259         mld_prof(ji,jj) = MAX( mld_prof(ji,jj), nbld(ji,jj) )   ! Ensure mld_prof .ge. nbld
3260         pmld(ji,jj)     = gdepw(ji,jj,mld_prof(ji,jj),Kmm)
3261      END_2D
3262      !
3263      ikmax = MIN( MAXVAL( mld_prof(:,:) ), jpkm1 )   ! Max level of the computation
3264      ztm(:,:) = 0.0_wp
3265      zsm(:,:) = 0.0_wp
3266      DO_3D( 1, 1, 1, 1, 1, ikmax )
3267         zc = e3t(ji,jj,jk,Kmm) * REAL( MIN( MAX( 0, mld_prof(ji,jj) - jk ), 1  ), KIND=wp )   ! zc being 0 outside the ML t-points
3268         ztm(ji,jj) = ztm(ji,jj) + zc * ts(ji,jj,jk,jp_tem,Kmm)
3269         zsm(ji,jj) = zsm(ji,jj) + zc * ts(ji,jj,jk,jp_sal,Kmm)
3270      END_3D
3271      ! Average temperature and salinity
3272      ztm(:,:) = ztm(:,:) / MAX( e3t(:,:,1,Kmm), pmld(:,:) )
3273      zsm(:,:) = zsm(:,:) / MAX( e3t(:,:,1,Kmm), pmld(:,:) )
3274      ! Calculate horizontal gradients at u & v points
3275      zmld_midu(:,:)   =  0.0_wp
3276      ztsm_midu(:,:,:) = 10.0_wp
3277      DO_2D( 0, 0, 1, 0 )
3278         pdtdx(ji,jj)            = ( ztm(ji+1,jj) - ztm(ji,jj) )  * umask(ji,jj,1) / e1u(ji,jj)
3279         pdsdx(ji,jj)            = ( zsm(ji+1,jj) - zsm(ji,jj) )  * umask(ji,jj,1) / e1u(ji,jj)
3280         zmld_midu(ji,jj)        = 0.25_wp * ( pmld(ji+1,jj) + pmld(ji,jj))
3281         ztsm_midu(ji,jj,jp_tem) =  0.5_wp * ( ztm( ji+1,jj)  + ztm( ji,jj) )
3282         ztsm_midu(ji,jj,jp_sal) =  0.5_wp * ( zsm( ji+1,jj)  + zsm( ji,jj) )
3283      END_2D
3284      zmld_midv(:,:)   =  0.0_wp
3285      ztsm_midv(:,:,:) = 10.0_wp
3286      DO_2D( 1, 0, 0, 0 )
3287         pdtdy(ji,jj)            = ( ztm(ji,jj+1) - ztm(ji,jj) ) * vmask(ji,jj,1) / e1v(ji,jj)
3288         pdsdy(ji,jj)            = ( zsm(ji,jj+1) - zsm(ji,jj) ) * vmask(ji,jj,1) / e1v(ji,jj)
3289         zmld_midv(ji,jj)        = 0.25_wp * ( pmld(ji,jj+1) + pmld( ji,jj) )
3290         ztsm_midv(ji,jj,jp_tem) =  0.5_wp * ( ztm( ji,jj+1)  + ztm( ji,jj) )
3291         ztsm_midv(ji,jj,jp_sal) =  0.5_wp * ( zsm( ji,jj+1)  + zsm( ji,jj) )
3292      END_2D
3293      CALL eos_rab( ztsm_midu, zmld_midu, zabu, Kmm )
3294      CALL eos_rab( ztsm_midv, zmld_midv, zabv, Kmm )
3295      DO_2D( 0, 0, 1, 0 )
3296         pdbdx_mle(ji,jj) = grav * ( pdtdx(ji,jj) * zabu(ji,jj,jp_tem) - pdsdx(ji,jj) * zabu(ji,jj,jp_sal) )
3297      END_2D
3298      DO_2D( 1, 0, 0, 0 )
3299         pdbdy_mle(ji,jj) = grav * ( pdtdy(ji,jj) * zabv(ji,jj,jp_tem) - pdsdy(ji,jj) * zabv(ji,jj,jp_sal) )
3300      END_2D
3301      DO_2D( 0, 0, 0, 0 )
3302         pdbds_mle(ji,jj) = SQRT( 0.5_wp * ( pdbdx_mle(ji,  jj) * pdbdx_mle(ji,  jj) + pdbdy_mle(ji,jj  ) * pdbdy_mle(ji,jj  ) +   &
3303            &                                pdbdx_mle(ji-1,jj) * pdbdx_mle(ji-1,jj) + pdbdy_mle(ji,jj-1) * pdbdy_mle(ji,jj-1) ) )
3304      END_2D
3305      !
3306      IF( ln_timing ) CALL timing_stop('zdf_osm_zhg')
3307      !
3308   END SUBROUTINE zdf_osm_zmld_horizontal_gradients
3309
3310   SUBROUTINE zdf_osm_osbl_state_fk( Kmm, pwb_fk, phbl, phmle, pwb_ent,   &
3311      &                              pdb_bl, pdbds_mle )
3312      !!---------------------------------------------------------------------
3313      !!               ***  ROUTINE zdf_osm_osbl_state_fk  ***
3314      !!
3315      !! ** Purpose : Determines the state of the OSBL and MLE layer. Info is
3316      !!              returned in the logicals l_pyc, l_flux and ldmle. Used
3317      !!              with Fox-Kemper scheme.
3318      !!                l_pyc  :: determines whether pycnocline flux-grad
3319      !!                          relationship needs to be determined
3320      !!                l_flux :: determines whether effects of surface flux
3321      !!                          extend below the base of the OSBL
3322      !!                ldmle  :: determines whether the layer with MLE is
3323      !!                          increasing with time or if base is relaxing
3324      !!                          towards hbl
3325      !!
3326      !! ** Method  :
3327      !!
3328      !!----------------------------------------------------------------------     
3329      ! Outputs
3330      INTEGER,                  INTENT(in   ) ::   Kmm         ! Time-level index
3331      REAL(wp), DIMENSION(:,:), INTENT(inout) ::   pwb_fk
3332      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   phbl        ! BL depth
3333      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   phmle       ! MLE depth
3334      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pwb_ent     ! Buoyancy entrainment flux
3335      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdb_bl      ! Difference between blayer average and parameter at base of blayer
3336      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   pdbds_mle   ! Magnitude of horizontal buoyancy gradient
3337      !
3338      ! Local variables
3339      INTEGER                     ::   ji, jj, jk        ! Dummy loop indices
3340      REAL(wp), DIMENSION(A2D(0)) ::   znd_param
3341      REAL(wp)                    ::   zthermal, zbeta
3342      REAL(wp)                    ::   zbuoy
3343      REAL(wp)                    ::   ztmp
3344      REAL(wp)                    ::   zpe_mle_layer
3345      REAL(wp)                    ::   zpe_mle_ref
3346      REAL(wp)                    ::   zdbdz_mle_int
3347      !
3348      IF( ln_timing ) CALL timing_start('zdf_osm_osf')
3349      !
3350      znd_param(A2D(0)) = 0.0_wp
3351      !
3352      DO_2D( 0, 0, 0, 0 )
3353         ztmp =  r1_ft(ji,jj) *  MIN( 111.e3_wp , e1u(ji,jj) ) / rn_osm_mle_lf
3354         pwb_fk(ji,jj) = rn_osm_mle_ce * hmle(ji,jj) * hmle(ji,jj) * ztmp * pdbds_mle(ji,jj) * pdbds_mle(ji,jj)
3355      END_2D
3356      !
3357      DO_2D( 0, 0, 0, 0 )
3358         !
3359         IF ( l_conv(ji,jj) ) THEN
3360            IF ( phmle(ji,jj) > 1.2_wp * phbl(ji,jj) ) THEN
3361               av_t_mle(ji,jj) = ( av_t_mle(ji,jj) * phmle(ji,jj) - av_t_bl(ji,jj) * phbl(ji,jj) ) / ( phmle(ji,jj) - phbl(ji,jj) )
3362               av_s_mle(ji,jj) = ( av_s_mle(ji,jj) * phmle(ji,jj) - av_s_bl(ji,jj) * phbl(ji,jj) ) / ( phmle(ji,jj) - phbl(ji,jj) )
3363               av_b_mle(ji,jj) = ( av_b_mle(ji,jj) * phmle(ji,jj) - av_b_bl(ji,jj) * phbl(ji,jj) ) / ( phmle(ji,jj) - phbl(ji,jj) )
3364               zdbdz_mle_int = ( av_b_bl(ji,jj) - ( 2.0_wp * av_b_mle(ji,jj) - av_b_bl(ji,jj) ) ) / ( phmle(ji,jj) - phbl(ji,jj) )
3365               ! Calculate potential energies of actual profile and reference profile
3366               zpe_mle_layer = 0.0_wp
3367               zpe_mle_ref   = 0.0_wp
3368               zthermal = rab_n(ji,jj,1,jp_tem)
3369               zbeta    = rab_n(ji,jj,1,jp_sal)
3370               DO jk = nbld(ji,jj), mld_prof(ji,jj)
3371                  zbuoy         = grav * ( zthermal * ts(ji,jj,jk,jp_tem,Kmm) - zbeta * ts(ji,jj,jk,jp_sal,Kmm) )
3372                  zpe_mle_layer = zpe_mle_layer + zbuoy * gdepw(ji,jj,jk,Kmm) * e3w(ji,jj,jk,Kmm)
3373                  zpe_mle_ref   = zpe_mle_ref   + ( av_b_bl(ji,jj) - zdbdz_mle_int * ( gdepw(ji,jj,jk,Kmm) - phbl(ji,jj) ) ) *   &
3374                     &                            gdepw(ji,jj,jk,Kmm) * e3w(ji,jj,jk,Kmm)
3375               END DO
3376               ! Non-dimensional parameter to diagnose the presence of thermocline
3377               znd_param(ji,jj) = ( zpe_mle_layer - zpe_mle_ref ) * ABS( ff_t(ji,jj) ) /   &
3378                  &               ( MAX( pwb_fk(ji,jj), 1e-10 ) * phmle(ji,jj) )
3379            END IF
3380         END IF
3381#ifdef key_osm_debug
3382         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
3383            WRITE(narea+100,'(4(a,g11.3))')'start of zdf_osm_osbl_state_fk: zwb_fk=',pwb_fk(ji,jj), &
3384               & '  znd_param=',znd_param(ji,jj), ' zpe_mle_ref=', zpe_mle_ref,  ' zpe_mle_layer=', zpe_mle_layer
3385            FLUSH(narea+100)
3386         END IF
3387#endif
3388         !
3389      END_2D
3390      !
3391      ! Diagnosis
3392      DO_2D( 0, 0, 0, 0 )
3393         !
3394         IF ( l_conv(ji,jj) ) THEN
3395            IF ( -2.0_wp * pwb_fk(ji,jj) / pwb_ent(ji,jj) > 0.5_wp ) THEN
3396               IF ( phmle(ji,jj) > 1.2_wp * phbl(ji,jj) ) THEN   ! MLE layer growing
3397                  IF ( znd_param (ji,jj) > 100.0_wp ) THEN   ! Thermocline present
3398                     l_flux(ji,jj) = .FALSE.
3399                     l_mle(ji,jj)  = .FALSE.
3400                  ELSE   ! Thermocline not present
3401                     l_flux(ji,jj) = .TRUE.
3402                     l_mle(ji,jj)  = .TRUE.
3403                  ENDIF  ! znd_param > 100
3404                  !
3405                  IF ( pdb_bl(ji,jj) < rn_osm_bl_thresh ) THEN
3406                     l_pyc(ji,jj) = .FALSE.
3407                  ELSE
3408                     l_pyc(ji,jj) = .TRUE.
3409                  ENDIF
3410               ELSE   ! MLE layer restricted to OSBL or just below
3411                  IF ( pdb_bl(ji,jj) < rn_osm_bl_thresh ) THEN   ! Weak stratification MLE layer can grow
3412                     l_pyc(ji,jj)  = .FALSE.
3413                     l_flux(ji,jj) = .TRUE.
3414                     l_mle(ji,jj)  = .TRUE.
3415                  ELSE   ! Strong stratification
3416                     l_pyc(ji,jj)  = .TRUE.
3417                     l_flux(ji,jj) = .FALSE.
3418                     l_mle(ji,jj)  = .FALSE.
3419                  END IF   ! pdb_bl < rn_mle_thresh_bl and
3420               END IF   ! phmle > 1.2 phbl
3421            ELSE
3422               l_pyc(ji,jj)  = .TRUE.
3423               l_flux(ji,jj) = .FALSE.
3424               l_mle(ji,jj)  = .FALSE.
3425               IF ( pdb_bl(ji,jj) < rn_osm_bl_thresh ) l_pyc(ji,jj) = .FALSE.
3426            END IF   !  -2.0 * pwb_fk(ji,jj) / pwb_ent > 0.5
3427         ELSE   ! Stable Boundary Layer
3428            l_pyc(ji,jj)  = .FALSE.
3429            l_flux(ji,jj) = .FALSE.
3430            l_mle(ji,jj)  = .FALSE.
3431         END IF   ! l_conv
3432#ifdef key_osm_debug
3433         IF(narea==nn_narea_db.and.ji==iloc_db.and.jj==jloc_db)THEN
3434            WRITE(narea+100,'(3(a,g11.3),/,4(a,l2))')'end of zdf_osm_osbl_state_fk:zwb_ent=',pwb_ent(ji,jj), &
3435               & '  zhmle=',phmle(ji,jj), ' zhbl=', phbl(ji,jj), &
3436               & ' lpyc= ', l_pyc(ji,jj), ' lflux= ', l_flux(ji,jj),  ' lmle= ', l_mle(ji,jj), ' lconv= ', l_conv(ji,jj)
3437            FLUSH(narea+100)
3438         END IF
3439#endif
3440         !
3441      END_2D
3442      !
3443      IF( ln_timing ) CALL timing_stop('zdf_osm_osf')
3444      !
3445   END SUBROUTINE zdf_osm_osbl_state_fk
3446
3447   SUBROUTINE zdf_osm_mle_parameters( Kmm, kmld_prof, pmld, phmle, pvel_mle,   &
3448      &                               pdiff_mle, pdbds_mle, phbl, pwb0tot )
3449      !!----------------------------------------------------------------------
3450      !!               ***  ROUTINE zdf_osm_mle_parameters  ***
3451      !!
3452      !! ** Purpose : Timesteps the mixed layer eddy depth, hmle and calculates
3453      !!              the mixed layer eddy fluxes for buoyancy, heat and
3454      !!              salinity.
3455      !!
3456      !! ** Method  :
3457      !!
3458      !! References: Fox-Kemper et al., JPO, 38, 1145-1165, 2008
3459      !!             Fox-Kemper and Ferrari, JPO, 38, 1166-1179, 2008
3460      !!
3461      !!----------------------------------------------------------------------
3462      INTEGER,                     INTENT(in   ) ::   Kmm         ! Time-level index
3463      INTEGER,  DIMENSION(:,:),    INTENT(inout) ::   kmld_prof
3464      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pmld        ! == Estimated FK BLD used for MLE horiz gradients == !
3465      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   phmle       ! MLE depth
3466      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   pvel_mle    ! Velocity scale for dhdt with stable ML and FK
3467      REAL(wp), DIMENSION(:,:),    INTENT(inout) ::   pdiff_mle   ! Extra MLE vertical diff
3468      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   pdbds_mle   ! Magnitude of horizontal buoyancy gradient
3469      REAL(wp), DIMENSION(:,:),    INTENT(in   ) ::   phbl        ! BL depth
3470      REAL(wp), DIMENSION(A2D(0)), INTENT(in   ) ::   pwb0tot     ! Total surface buoyancy flux including insolation
3471      !
3472      ! Local variables
3473      INTEGER  ::   ji, jj, jk   ! Dummy loop indices
3474      REAL(wp) ::   ztmp
3475      REAL(wp) ::   zdbdz
3476      REAL(wp) ::   zdtdz
3477      REAL(wp) ::   zdsdz
3478      REAL(wp) ::   zthermal
3479      REAL(wp) ::   zbeta
3480      REAL(wp) ::   zbuoy
3481      REAL(wp) ::   zdb_mle
3482      !
3483      IF( ln_timing ) CALL timing_start('zdf_osm_mp')
3484      !
3485      ! Calculate vertical buoyancy, heat and salinity fluxes due to MLE
3486      DO_2D( 0, 0, 0, 0 )
3487         IF ( l_conv(ji,jj) ) THEN
3488            ztmp =  r1_ft(ji,jj) * MIN( 111e3_wp, e1u(ji,jj) ) / rn_osm_mle_lf
3489            ! This velocity scale, defined in Fox-Kemper et al (2008), is needed for calculating dhdt
3490            pvel_mle(ji,jj)  = pdbds_mle(ji,jj) * ztmp * hmle(ji,jj) * tmask(ji,jj,1)
3491            pdiff_mle(ji,jj) = 5e-4_wp * rn_osm_mle_ce * ztmp * pdbds_mle(ji,jj) * phmle(ji,jj)**2
3492         END IF
3493      END_2D
3494      ! Timestep mixed layer eddy depth
3495      DO_2D( 0, 0, 0, 0 )
3496         IF ( l_mle(ji,jj) ) THEN   ! MLE layer growing
3497            ! Buoyancy gradient at base of MLE layer
3498            zthermal = rab_n(ji,jj,1,jp_tem)
3499            zbeta    = rab_n(ji,jj,1,jp_sal)
3500            zbuoy = grav * ( zthermal * ts(ji,jj,kmld_prof(ji,jj)+2,jp_tem,Kmm) -   &
3501               &             zbeta    * ts(ji,jj,kmld_prof(ji,jj)+2,jp_sal,Kmm) )
3502            zdb_mle = av_b_bl(ji,jj) - zbuoy
3503            ! Timestep hmle
3504            hmle(ji,jj) = hmle(ji,jj) + pwb0tot(ji,jj) * rn_Dt / zdb_mle
3505         ELSE
3506            IF ( phmle(ji,jj) > phbl(ji,jj) ) THEN
3507               hmle(ji,jj) = hmle(ji,jj) - ( hmle(ji,jj) - hbl(ji,jj) ) * rn_Dt / rn_osm_mle_tau
3508            ELSE
3509               hmle(ji,jj) = hmle(ji,jj) - 10.0_wp * ( hmle(ji,jj) - hbl(ji,jj) ) * rn_Dt / rn_osm_mle_tau
3510            END IF
3511         END IF
3512         hmle(ji,jj) = MAX( MIN( hmle(ji,jj), ht(ji,jj) ), gdepw(ji,jj,4,Kmm) )
3513         IF ( ln_osm_hmle_limit ) hmle(ji,jj) = MIN( hmle(ji,jj), rn_osm_hmle_limit*hbl(ji,jj) )
3514         hmle(ji,jj) = pmld(ji,jj)   ! For now try just set hmle to pmld
3515      END_2D
3516      !
3517      kmld_prof(:,:) = 4
3518      DO_3D( 0, 0, 0, 0, 5, jpkm1 )
3519         IF ( hmle(ji,jj) >= gdepw(ji,jj,jk,Kmm) ) kmld_prof(ji,jj) = MIN( mbkt(ji,jj), jk )
3520      END_3D
3521      DO_2D( 0, 0, 0, 0 )
3522         phmle(ji,jj) = gdepw(ji,jj,kmld_prof(ji,jj),Kmm)
3523      END_2D
3524      !
3525      IF( ln_timing ) CALL timing_stop('zdf_osm_mp')
3526      !
3527   END SUBROUTINE zdf_osm_mle_parameters
3528
3529   SUBROUTINE zdf_osm_init( Kmm )
3530      !!----------------------------------------------------------------------
3531      !!                  ***  ROUTINE zdf_osm_init  ***
3532      !!
3533      !! ** Purpose :   Initialization of the vertical eddy diffivity and
3534      !!      viscosity when using a osm turbulent closure scheme
3535      !!
3536      !! ** Method  :   Read the namosm namelist and check the parameters
3537      !!      called at the first timestep (nit000)
3538      !!
3539      !! ** input   :   Namlists namzdf_osm and namosm_mle
3540      !!
3541      !!----------------------------------------------------------------------
3542      INTEGER, INTENT(in   ) ::   Kmm   ! Time level
3543      !
3544      ! Local variables
3545      INTEGER  ::   ios            ! Local integer
3546      INTEGER  ::   ji, jj, jk     ! Dummy loop indices
3547      REAL(wp) ::   z1_t2
3548      !
3549      REAL(wp), PARAMETER ::   pp_large = -1e10_wp
3550      !
3551      NAMELIST/namzdf_osm/ ln_use_osm_la,    rn_osm_la,      rn_osm_dstokes,      nn_ave,                nn_osm_wave,        &
3552         &                 ln_dia_osm,       rn_osm_hbl0,    rn_zdfosm_adjust_sd, ln_kpprimix,           rn_riinfty,         &
3553         &                 rn_difri,         ln_convmix,     rn_difconv,          nn_osm_wave,           nn_osm_SD_reduce,   &
3554         &                 ln_osm_mle,       rn_osm_hblfrac, rn_osm_bl_thresh,    ln_zdfosm_ice_shelter
3555#ifdef key_osm_debug
3556      NAMELIST/namzdf_osm/ nn_idb, nn_jdb, nn_kdb, nn_narea_db
3557#endif
3558      ! Namelist for Fox-Kemper parametrization
3559      NAMELIST/namosm_mle/ nn_osm_mle,       rn_osm_mle_ce,     rn_osm_mle_lf,  rn_osm_mle_time,  rn_osm_mle_lat,   &
3560         &                 rn_osm_mle_rho_c, rn_osm_mle_thresh, rn_osm_mle_tau, ln_osm_hmle_limit, rn_osm_hmle_limit
3561      !
3562      IF( ln_timing ) CALL timing_start('zdf_osm_init')
3563      READ  ( numnam_ref, namzdf_osm, IOSTAT = ios, ERR = 901)
3564901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_osm in reference namelist' )
3565
3566      READ  ( numnam_cfg, namzdf_osm, IOSTAT = ios, ERR = 902 )
3567902   IF( ios >  0 ) CALL ctl_nam ( ios , 'namzdf_osm in configuration namelist' )
3568      IF(lwm) WRITE ( numond, namzdf_osm )
3569
3570      IF(lwp) THEN                    ! Control print
3571         WRITE(numout,*)
3572         WRITE(numout,*) 'zdf_osm_init : OSMOSIS Parameterisation'
3573         WRITE(numout,*) '~~~~~~~~~~~~'
3574         WRITE(numout,*) '   Namelist namzdf_osm : set osm mixing parameters'
3575         WRITE(numout,*) '      Use  rn_osm_la                                     ln_use_osm_la         = ', ln_use_osm_la
3576         WRITE(numout,*) '      Use  MLE in OBL, i.e. Fox-Kemper param             ln_osm_mle            = ', ln_osm_mle
3577         WRITE(numout,*) '      Turbulent Langmuir number                          rn_osm_la             = ', rn_osm_la
3578         WRITE(numout,*) '      Stokes drift reduction factor                      rn_zdfosm_adjust_sd   = ', rn_zdfosm_adjust_sd
3579         WRITE(numout,*) '      Initial hbl for 1D runs                            rn_osm_hbl0           = ', rn_osm_hbl0
3580         WRITE(numout,*) '      Depth scale of Stokes drift                        rn_osm_dstokes        = ', rn_osm_dstokes
3581         WRITE(numout,*) '      Horizontal average flag                            nn_ave                = ', nn_ave
3582         WRITE(numout,*) '      Stokes drift                                       nn_osm_wave           = ', nn_osm_wave
3583         SELECT CASE (nn_osm_wave)
3584         CASE(0)
3585            WRITE(numout,*) '      Calculated assuming constant La#=0.3'
3586         CASE(1)
3587            WRITE(numout,*) '      Calculated from Pierson Moskowitz wind-waves'
3588         CASE(2)
3589            WRITE(numout,*) '      Calculated from ECMWF wave fields'
3590         END SELECT
3591         WRITE(numout,*) '      Stokes drift reduction                             nn_osm_SD_reduce      = ', nn_osm_SD_reduce
3592         WRITE(numout,*) '      Fraction of hbl to average SD over/fit'
3593         WRITE(numout,*) '      Exponential with nn_osm_SD_reduce = 1 or 2         rn_osm_hblfrac        = ', rn_osm_hblfrac
3594         SELECT CASE (nn_osm_SD_reduce)
3595         CASE(0)
3596            WRITE(numout,*) '     No reduction'
3597         CASE(1)
3598            WRITE(numout,*) '     Average SD over upper rn_osm_hblfrac of BL'
3599         CASE(2)
3600            WRITE(numout,*) '     Fit exponential to slope rn_osm_hblfrac of BL'
3601         END SELECT
3602         WRITE(numout,*) '     Reduce surface SD and depth scale under ice         ln_zdfosm_ice_shelter = ', ln_zdfosm_ice_shelter
3603         WRITE(numout,*) '     Output osm diagnostics                              ln_dia_osm            = ', ln_dia_osm
3604         WRITE(numout,*) '         Threshold used to define BL                     rn_osm_bl_thresh      = ', rn_osm_bl_thresh,   &
3605            &            'm^2/s'
3606         WRITE(numout,*) '     Use KPP-style shear instability mixing              ln_kpprimix           = ', ln_kpprimix
3607         WRITE(numout,*) '     Local Richardson Number limit for shear instability rn_riinfty            = ', rn_riinfty
3608         WRITE(numout,*) '     Maximum shear diffusivity at Rig = 0 (m2/s)         rn_difri              = ', rn_difri
3609         WRITE(numout,*) '     Use large mixing below BL when unstable             ln_convmix            = ', ln_convmix
3610         WRITE(numout,*) '     Diffusivity when unstable below BL (m2/s)           rn_difconv            = ', rn_difconv
3611#ifdef key_osm_debug
3612         WRITE(numout,*) 'nn_idb', nn_idb, 'nn_jdb', nn_jdb, 'nn_kdb', nn_kdb, 'nn_narea_db', nn_narea_db
3613         iloc_db = mi0(nn_idb)
3614         jloc_db = mj0(nn_jdb)
3615         WRITE(numout,*) 'iloc_db ', iloc_db , 'jloc_db', jloc_db
3616#endif
3617      ENDIF
3618      !
3619      !                              ! Check wave coupling settings !
3620      !                         ! Further work needed - see ticket #2447 !
3621      IF ( nn_osm_wave == 2 ) THEN
3622         IF (.NOT. ( ln_wave .AND. ln_sdw )) &
3623            & CALL ctl_stop( 'zdf_osm_init : ln_zdfosm and nn_osm_wave=2, ln_wave and ln_sdw must be true' )
3624      END IF
3625      !
3626      ! Flags associated with diagnostic output
3627      IF ( ln_dia_osm .AND. ( iom_use("zdudz_pyc") .OR. iom_use("zdvdz_pyc") ) )                            ln_dia_pyc_shr = .TRUE.
3628      IF ( ln_dia_osm .AND. ( iom_use("zdtdz_pyc") .OR. iom_use("zdsdz_pyc") .OR. iom_use("zdbdz_pyc" ) ) ) ln_dia_pyc_scl = .TRUE.
3629      !
3630      ! Allocate zdfosm arrays
3631      IF( zdf_osm_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'zdf_osm_init : unable to allocate arrays' )
3632      !
3633      IF( ln_osm_mle ) THEN   ! Initialise Fox-Kemper parametrization
3634         READ  ( numnam_ref, namosm_mle, IOSTAT = ios, ERR = 903)
3635903      IF( ios /= 0 ) CALL ctl_nam( ios, 'namosm_mle in reference namelist' )
3636         READ  ( numnam_cfg, namosm_mle, IOSTAT = ios, ERR = 904 )
3637904      IF( ios >  0 ) CALL ctl_nam( ios, 'namosm_mle in configuration namelist' )
3638         IF(lwm) WRITE ( numond, namosm_mle )
3639         !
3640         IF(lwp) THEN   ! Namelist print
3641            WRITE(numout,*)
3642            WRITE(numout,*) 'zdf_osm_init : initialise mixed layer eddy (MLE)'
3643            WRITE(numout,*) '~~~~~~~~~~~~~'
3644            WRITE(numout,*) '   Namelist namosm_mle : '
3645            WRITE(numout,*) '      MLE type: =0 standard Fox-Kemper ; =1 new formulation   nn_osm_mle        = ', nn_osm_mle
3646            WRITE(numout,*) '      Magnitude of the MLE (typical value: 0.06 to 0.08)      rn_osm_mle_ce     = ', rn_osm_mle_ce
3647            WRITE(numout,*) '      Scale of ML front (ML radius of deform.) (nn_osm_mle=0) rn_osm_mle_lf     = ', rn_osm_mle_lf,    &
3648               &            'm'
3649            WRITE(numout,*) '      Maximum time scale of MLE                (nn_osm_mle=0) rn_osm_mle_time   = ',   &
3650               &            rn_osm_mle_time, 's'
3651            WRITE(numout,*) '      Reference latitude (deg) of MLE coef.    (nn_osm_mle=1) rn_osm_mle_lat    = ', rn_osm_mle_lat,   &
3652               &            'deg'
3653            WRITE(numout,*) '      Density difference used to define ML for FK             rn_osm_mle_rho_c  = ', rn_osm_mle_rho_c
3654            WRITE(numout,*) '      Threshold used to define MLE for FK                     rn_osm_mle_thresh = ',   &
3655               &            rn_osm_mle_thresh, 'm^2/s'
3656            WRITE(numout,*) '      Timescale for OSM-FK                                    rn_osm_mle_tau    = ', rn_osm_mle_tau, 's'
3657            WRITE(numout,*) '      Switch to limit hmle                                    ln_osm_hmle_limit = ', ln_osm_hmle_limit
3658            WRITE(numout,*) '      hmle limit (fraction of zmld) (ln_osm_hmle_limit = .T.) rn_osm_hmle_limit = ', rn_osm_hmle_limit
3659         END IF
3660      END IF
3661      !
3662      IF(lwp) THEN
3663         WRITE(numout,*)
3664         IF ( ln_osm_mle ) THEN
3665            WRITE(numout,*) '   ==>>>   Mixed Layer Eddy induced transport added to OSMOSIS BL calculation'
3666            IF( nn_osm_mle == 0 )   WRITE(numout,*) '              Fox-Kemper et al 2010 formulation'
3667            IF( nn_osm_mle == 1 )   WRITE(numout,*) '              New formulation'
3668         ELSE
3669            WRITE(numout,*) '   ==>>>   Mixed Layer induced transport NOT added to OSMOSIS BL calculation'
3670         END IF
3671      END IF
3672      !
3673      IF( ln_osm_mle ) THEN   ! MLE initialisation
3674         !
3675         rb_c = grav * rn_osm_mle_rho_c / rho0   ! Mixed Layer buoyancy criteria
3676         IF(lwp) WRITE(numout,*)
3677         IF(lwp) WRITE(numout,*) '      ML buoyancy criteria = ', rb_c, ' m/s2 '
3678         IF(lwp) WRITE(numout,*) '      associated ML density criteria defined in zdfmxl = ', rn_osm_mle_rho_c, 'kg/m3'
3679         !
3680         IF( nn_osm_mle == 1 ) THEN
3681            rc_f = rn_osm_mle_ce / ( 5e3_wp * 2.0_wp * omega * SIN( rad * rn_osm_mle_lat ) )
3682         END IF
3683         ! 1/(f^2+tau^2)^1/2 at t-point (needed in both nn_osm_mle case)
3684         z1_t2 = 2e-5_wp
3685         DO_2D( 1, 1, 1, 1 )
3686            r1_ft(ji,jj) = MIN( 1.0_wp / ( ABS( ff_t(ji,jj)) + epsln ), ABS( ff_t(ji,jj) ) / z1_t2**2 )
3687         END_2D
3688         ! z1_t2 = 1._wp / ( rn_osm_mle_time * rn_osm_mle_timeji,jj )
3689         ! r1_ft(:,:) = 1._wp / SQRT(  ff_t(:,:) * ff_t(:,:) + z1_t2  )
3690         !
3691      END IF
3692      !
3693      CALL osm_rst( nit000, Kmm,  'READ' )   ! Read or initialize hbl, dh, hmle
3694      !
3695      IF ( ln_zdfddm ) THEN
3696         IF(lwp) THEN
3697            WRITE(numout,*)
3698            WRITE(numout,*) '    Double diffusion mixing on temperature and salinity '
3699            WRITE(numout,*) '    CAUTION : done in routine zdfosm, not in routine zdfddm '
3700         END IF
3701      END IF
3702      !
3703      ! Set constants not in namelist
3704      ! -----------------------------
3705      IF(lwp) THEN
3706         WRITE(numout,*)
3707      END IF
3708      !
3709      dstokes(:,:) = pp_large
3710      IF (nn_osm_wave == 0) THEN
3711         dstokes(:,:) = rn_osm_dstokes
3712      END IF
3713      !
3714      ! Horizontal average : initialization of weighting arrays
3715      ! -------------------
3716      SELECT CASE ( nn_ave )
3717      CASE ( 0 )                ! no horizontal average
3718         IF(lwp) WRITE(numout,*) '          no horizontal average on avt'
3719         IF(lwp) WRITE(numout,*) '          only in very high horizontal resolution !'
3720         ! Weighting mean arrays etmean
3721         !           ( 1  1 )
3722         ! avt = 1/4 ( 1  1 )
3723         !
3724         etmean(:,:,:) = 0.0_wp
3725         !
3726         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
3727            etmean(ji,jj,jk) = tmask(ji,jj,jk) / MAX( 1.0_wp, umask(ji-1,jj,  jk) + umask(ji,jj,jk) +   &
3728               &                                              vmask(ji,  jj-1,jk) + vmask(ji,jj,jk) )
3729         END_3D
3730      CASE ( 1 )                ! horizontal average
3731         IF(lwp) WRITE(numout,*) '          horizontal average on avt'
3732         ! Weighting mean arrays etmean
3733         !           ( 1/2  1  1/2 )
3734         ! avt = 1/8 ( 1    2  1   )
3735         !           ( 1/2  1  1/2 )
3736         etmean(:,:,:) = 0.0_wp
3737         !
3738         DO_3D( 0, 0, 0, 0, 1, jpkm1 )
3739            etmean(ji,jj,jk) = tmask(ji, jj,jk) / MAX( 1.0_wp, 2.0_wp *   tmask(ji,jj,jk) +                               &
3740               &                                               0.5_wp * ( tmask(ji-1,jj+1,jk) + tmask(ji-1,jj-1,jk) +     &
3741               &                                                          tmask(ji+1,jj+1,jk) + tmask(ji+1,jj-1,jk) ) +   &
3742               &                                               1.0_wp * ( tmask(ji-1,jj,  jk) + tmask(ji,  jj+1,jk) +     &
3743               &                                                          tmask(ji,  jj-1,jk) + tmask(ji+1,jj,  jk) ) )
3744         END_3D
3745      CASE DEFAULT
3746         WRITE(ctmp1,*) '          bad flag value for nn_ave = ', nn_ave
3747         CALL ctl_stop( ctmp1 )
3748      END SELECT
3749      !
3750      ! Initialization of vertical eddy coef. to the background value
3751      ! -------------------------------------------------------------
3752      DO jk = 1, jpk
3753         avt(:,:,jk) = avtb(jk) * tmask(:,:,jk)
3754      END DO
3755      !
3756      ! Zero the surface flux for non local term and osm mixed layer depth
3757      ! ------------------------------------------------------------------
3758      ghamt(:,:,:) = 0.0_wp
3759      ghams(:,:,:) = 0.0_wp
3760      ghamu(:,:,:) = 0.0_wp
3761      ghamv(:,:,:) = 0.0_wp
3762      !
3763      IF( ln_timing ) CALL timing_stop('zdf_osm_init')
3764      !
3765   END SUBROUTINE zdf_osm_init
3766
3767   SUBROUTINE osm_rst( kt, Kmm, cdrw )
3768      !!---------------------------------------------------------------------
3769      !!                   ***  ROUTINE osm_rst  ***
3770      !!
3771      !! ** Purpose :   Read or write BL fields in restart file
3772      !!
3773      !! ** Method  :   use of IOM library. If the restart does not contain
3774      !!                required fields, they are recomputed from stratification
3775      !!
3776      !!----------------------------------------------------------------------
3777      INTEGER         , INTENT(in   ) ::   kt     ! Ocean time step index
3778      INTEGER         , INTENT(in   ) ::   Kmm    ! Ocean time level index (middle)
3779      CHARACTER(len=*), INTENT(in   ) ::   cdrw   ! "READ"/"WRITE" flag
3780      !
3781      ! Local variables
3782      INTEGER  ::   id1, id2, id3                 ! iom enquiry index
3783      INTEGER  ::   ji, jj, jk                    ! Dummy loop indices
3784      INTEGER  ::   iiki, ikt                     ! Local integer
3785      REAL(wp) ::   zhbf                          ! Tempory scalars
3786      REAL(wp) ::   zN2_c                         ! Local scalar
3787      REAL(wp) ::   rho_c = 0.01_wp               ! Density criterion for mixed layer depth
3788      INTEGER, DIMENSION(jpi,jpj) ::   imld_rst   ! Level of mixed-layer depth (pycnocline top)
3789      !
3790      IF( ln_timing ) CALL timing_start('osm_rst')
3791      !
3792      !!-----------------------------------------------------------------------------
3793      ! If READ/WRITE Flag is 'READ', try to get hbl from restart file. If successful then return
3794      !!-----------------------------------------------------------------------------
3795      IF( TRIM(cdrw) == 'READ' .AND. ln_rstart) THEN
3796         id1 = iom_varid( numror, 'wn', ldstop = .FALSE. )
3797         IF( id1 > 0 ) THEN   ! 'wn' exists; read
3798            CALL iom_get( numror, jpdom_auto, 'wn', ww )
3799            WRITE(numout,*) ' ===>>>> :  wn read from restart file'
3800         ELSE
3801            ww(:,:,:) = 0.0_wp
3802            WRITE(numout,*) ' ===>>>> :  wn not in restart file, set to zero initially'
3803         END IF
3804         !
3805         id1 = iom_varid( numror, 'hbl', ldstop = .FALSE. )
3806         id2 = iom_varid( numror, 'dh',  ldstop = .FALSE. )
3807         IF( id1 > 0 .AND. id2 > 0 ) THEN   ! 'hbl' exists; read and return
3808            CALL iom_get( numror, jpdom_auto, 'hbl', hbl  )
3809            CALL iom_get( numror, jpdom_auto, 'dh',  dh   )
3810            hml(:,:) = hbl(:,:) - dh(:,:)   ! Initialise ML depth
3811            WRITE(numout,*) ' ===>>>> :  hbl & dh read from restart file'
3812            IF( ln_osm_mle ) THEN
3813               id3 = iom_varid( numror, 'hmle', ldstop = .FALSE. )
3814               IF( id3 > 0 ) THEN
3815                  CALL iom_get( numror, jpdom_auto, 'hmle', hmle )
3816                  WRITE(numout,*) ' ===>>>> :  hmle read from restart file'
3817               ELSE
3818                  WRITE(numout,*) ' ===>>>> :  hmle not found, set to hbl'
3819                  hmle(:,:) = hbl(:,:)   ! Initialise MLE depth
3820               END IF
3821            END IF
3822            RETURN
3823         ELSE   ! 'hbl' & 'dh' not in restart file, recalculate
3824            WRITE(numout,*) ' ===>>>> : previous run without osmosis scheme, hbl computed from stratification'
3825         END IF
3826      END IF
3827      !
3828      !!-----------------------------------------------------------------------------
3829      ! If READ/WRITE Flag is 'WRITE', write hbl into the restart file, then return
3830      !!-----------------------------------------------------------------------------
3831      IF ( TRIM(cdrw) == 'WRITE' ) THEN
3832         IF(lwp) WRITE(numout,*) '---- osm-rst ----'
3833         CALL iom_rstput( kt, nitrst, numrow, 'wn',  ww  )
3834         CALL iom_rstput( kt, nitrst, numrow, 'hbl', hbl )
3835         CALL iom_rstput( kt, nitrst, numrow, 'dh',  dh  )
3836         IF ( ln_osm_mle ) THEN
3837            CALL iom_rstput( kt, nitrst, numrow, 'hmle', hmle )
3838         END IF
3839         RETURN
3840      END IF
3841      !
3842      !!-----------------------------------------------------------------------------
3843      ! Getting hbl, no restart file with hbl, so calculate from surface stratification
3844      !!-----------------------------------------------------------------------------
3845      IF( lwp ) WRITE(numout,*) ' ===>>>> : calculating hbl computed from stratification'
3846      ! w-level of the mixing and mixed layers
3847      CALL eos_rab( ts(:,:,:,:,Kmm), rab_n, Kmm )
3848      CALL bn2( ts(:,:,:,:,Kmm), rab_n, rn2, Kmm )
3849      imld_rst(:,:) = nlb10            ! Initialization to the number of w ocean point
3850      hbl(:,:) = 0.0_wp                ! Here hbl used as a dummy variable, integrating vertically N^2
3851      zN2_c = grav * rho_c * r1_rho0   ! Convert density criteria into N^2 criteria
3852      !
3853      hbl(:,:)  = 0.0_wp   ! Here hbl used as a dummy variable, integrating vertically N^2
3854      DO_3D( 1, 1, 1, 1, 1, jpkm1 )
3855         ikt = mbkt(ji,jj)
3856         hbl(ji,jj) = hbl(ji,jj) + MAX( rn2(ji,jj,jk) , 0.0_wp ) * e3w(ji,jj,jk,Kmm)
3857         IF ( hbl(ji,jj) < zN2_c ) imld_rst(ji,jj) = MIN( jk , ikt ) + 1   ! Mixed layer level
3858      END_3D
3859      !
3860      DO_2D( 1, 1, 1, 1 )
3861         iiki = MAX( 4, imld_rst(ji,jj) )
3862         hbl(ji,jj) = gdepw(ji,jj,iiki,Kmm  )   ! Turbocline depth
3863         dh(ji,jj)  = e3t(ji,jj,iiki-1,Kmm  )   ! Turbocline depth
3864         hml(ji,jj) = hbl(ji,jj) - dh(ji,jj)
3865      END_2D
3866      !
3867      WRITE(numout,*) ' ===>>>> : hbl computed from stratification'
3868      !
3869      IF( ln_osm_mle ) THEN
3870         hmle(:,:) = hbl(:,:)            ! Initialise MLE depth.
3871         WRITE(numout,*) ' ===>>>> : hmle set = to hbl'
3872      END IF
3873      !
3874      ww(:,:,:) = 0._wp
3875      WRITE(numout,*) ' ===>>>> :  wn not in restart file, set to zero initially'
3876      !
3877      IF( ln_timing ) CALL timing_stop('osm_rst')
3878      !
3879   END SUBROUTINE osm_rst
3880
3881   SUBROUTINE tra_osm( kt, Kmm, pts, Krhs )
3882      !!----------------------------------------------------------------------
3883      !!                  ***  ROUTINE tra_osm  ***
3884      !!
3885      !! ** Purpose :   compute and add to the tracer trend the non-local tracer flux
3886      !!
3887      !! ** Method  :   ???
3888      !!
3889      !!----------------------------------------------------------------------
3890      INTEGER                                  , INTENT(in   ) ::   kt          ! Time step index
3891      INTEGER                                  , INTENT(in   ) ::   Kmm, Krhs   ! Time level indices
3892      REAL(wp), DIMENSION(jpi,jpj,jpk,jpts,jpt), INTENT(inout) ::   pts         ! Active tracers and RHS of tracer equation
3893      !
3894      ! Local variables
3895      INTEGER                                 ::   ji, jj, jk
3896      REAL(wp), DIMENSION(:,:,:), ALLOCATABLE ::   ztrdt, ztrds   ! 3D workspace
3897      !
3898      IF( ln_timing ) CALL timing_start('tra_osm')
3899      !
3900      IF ( kt == nit000 ) THEN
3901         IF ( ntile == 0 .OR. ntile == 1 ) THEN   ! Do only on the first tile
3902            IF(lwp) WRITE(numout,*)
3903            IF(lwp) WRITE(numout,*) 'tra_osm : OSM non-local tracer fluxes'
3904            IF(lwp) WRITE(numout,*) '~~~~~~~   '
3905         END IF
3906      END IF
3907      !
3908      IF ( l_trdtra ) THEN   ! Save ta and sa trends
3909         ALLOCATE( ztrdt(jpi,jpj,jpk), ztrds(jpi,jpj,jpk) )
3910         ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs)
3911         ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs)
3912      END IF
3913      !
3914      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
3915         pts(ji,jj,jk,jp_tem,Krhs) =  pts(ji,jj,jk,jp_tem,Krhs)                      &
3916            &                 - (  ghamt(ji,jj,jk  )  &
3917            &                    - ghamt(ji,jj,jk+1) ) /e3t(ji,jj,jk,Kmm)
3918         pts(ji,jj,jk,jp_sal,Krhs) =  pts(ji,jj,jk,jp_sal,Krhs)                      &
3919            &                 - (  ghams(ji,jj,jk  )  &
3920            &                    - ghams(ji,jj,jk+1) ) / e3t(ji,jj,jk,Kmm)
3921      END_3D
3922      !
3923      IF ( l_trdtra ) THEN   ! Save the non-local tracer flux trends for diagnostics
3924         ztrdt(:,:,:) = pts(:,:,:,jp_tem,Krhs) - ztrdt(:,:,:)
3925         ztrds(:,:,:) = pts(:,:,:,jp_sal,Krhs) - ztrds(:,:,:)
3926         CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_tem, jptra_osm, ztrdt )
3927         CALL trd_tra( kt, Kmm, Krhs, 'TRA', jp_sal, jptra_osm, ztrds )
3928         DEALLOCATE( ztrdt, ztrds )
3929      END IF
3930      !
3931      IF ( sn_cfctl%l_prtctl ) THEN
3932         CALL prt_ctl( tab3d_1=pts(:,:,:,jp_tem,Krhs), clinfo1=' osm  - Ta: ', mask1=tmask,   &
3933            &          tab3d_2=pts(:,:,:,jp_sal,Krhs), clinfo2=       ' Sa: ', mask2=tmask, clinfo3='tra' )
3934      END IF
3935      !
3936      IF( ln_timing ) CALL timing_stop('tra_osm')
3937      !
3938   END SUBROUTINE tra_osm
3939
3940   SUBROUTINE trc_osm( kt )   ! Dummy routine
3941      !!----------------------------------------------------------------------
3942      !!                  ***  ROUTINE trc_osm  ***
3943      !!
3944      !! ** Purpose :   compute and add to the passive tracer trend the non-local
3945      !!                 passive tracer flux
3946      !!
3947      !!
3948      !! ** Method  :   ???
3949      !!
3950      !!----------------------------------------------------------------------
3951      INTEGER, INTENT(in) :: kt
3952      !
3953      IF( ln_timing ) CALL timing_start('trc_osm')
3954      !
3955      WRITE(*,*) 'trc_osm: Not written yet', kt
3956      !
3957      IF( ln_timing ) CALL timing_stop('trc_osm')
3958      !
3959   END SUBROUTINE trc_osm
3960
3961   SUBROUTINE dyn_osm( kt, Kmm, puu, pvv, Krhs )
3962      !!----------------------------------------------------------------------
3963      !!                  ***  ROUTINE dyn_osm  ***
3964      !!
3965      !! ** Purpose :   compute and add to the velocity trend the non-local flux
3966      !! copied/modified from tra_osm
3967      !!
3968      !! ** Method  :   ???
3969      !!
3970      !!----------------------------------------------------------------------
3971      INTEGER                             , INTENT(in   ) ::   kt          ! Ocean time step index
3972      INTEGER                             , INTENT(in   ) ::   Kmm, Krhs   ! Ocean time level indices
3973      REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT(inout) ::   puu, pvv    ! Ocean velocities and RHS of momentum equation
3974      !
3975      INTEGER :: ji, jj, jk   ! dummy loop indices
3976      !!----------------------------------------------------------------------
3977      !
3978      IF( ln_timing ) CALL timing_start('dyn_osm')
3979      !
3980      IF ( kt == nit000 ) THEN
3981         IF(lwp) WRITE(numout,*)
3982         IF(lwp) WRITE(numout,*) 'dyn_osm : OSM non-local velocity'
3983         IF(lwp) WRITE(numout,*) '~~~~~~~   '
3984      END IF
3985      !
3986      ! Code saving tracer trends removed, replace with trdmxl_oce
3987      !
3988      DO_3D( 0, 0, 0, 0, 1, jpkm1 )   ! Add non-local u and v fluxes
3989         puu(ji,jj,jk,Krhs) =  puu(ji,jj,jk,Krhs) - ( ghamu(ji,jj,jk  ) -   &
3990            &                                         ghamu(ji,jj,jk+1) ) / e3u(ji,jj,jk,Kmm)
3991         pvv(ji,jj,jk,Krhs) =  pvv(ji,jj,jk,Krhs) - ( ghamv(ji,jj,jk  ) -   &
3992            &                                         ghamv(ji,jj,jk+1) ) / e3v(ji,jj,jk,Kmm)
3993      END_3D
3994      !
3995      ! Code for saving tracer trends removed
3996      !
3997      IF( ln_timing ) CALL timing_stop('dyn_osm')
3998      !
3999   END SUBROUTINE dyn_osm
4000
4001   !!======================================================================
4002
4003END MODULE zdfosm
Note: See TracBrowser for help on using the repository browser.