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

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

Synchronisation of the OSMOSIS boundary layer scheme with the version developed in branch /NEMO/branches/NERC/dev_r11078_OSMOSIS_IMMERSE_Nurser_4.0: transfer of changesets [14677,14678,14699,14704,14705] (ticket #2353)

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