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 @ 14816

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

Slight rearrangement of the subroutine structure and removal of the halo regions from the majority of arrays in module zdfosm (ticket #2353)

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