Skip to content
Snippets Groups Projects
zdfosm.F90 213 KiB
Newer Older
Guillaume Samson's avatar
Guillaume Samson committed
MODULE zdfosm
   !!======================================================================
   !!                       ***  MODULE  zdfosm  ***
   !! Ocean physics:  vertical mixing coefficient compute from the OSMOSIS
   !!                 turbulent closure parameterization
   !!=====================================================================
   !!  History : NEMO 4.0  ! A. Grant, G. Nurser
   !! 15/03/2017  Changed calculation of pycnocline thickness in unstable conditions and stable conditions AG
   !! 15/03/2017  Calculation of pycnocline gradients for stable conditions changed. Pycnocline gradients now depend on stability of the OSBL. A.G
   !! 06/06/2017  (1) Checks on sign of buoyancy jump in calculation of  OSBL depth.  A.G.
   !!             (2) Removed variable zbrad0, zbradh and zbradav since they are not used.
   !!             (3) Approximate treatment for shear turbulence.
   !!                        Minimum values for zustar and zustke.
   !!                        Add velocity scale, zvstr, that tends to zustar for large Langmuir numbers.
   !!                        Limit maximum value for Langmuir number.
   !!                        Use zvstr in definition of stability parameter zhol.
   !!             (4) Modified parametrization of entrainment flux, changing original coefficient 0.0485 for Langmuir contribution to 0.135 * zla
   !!             (5) For stable boundary layer add factor that depends on length of timestep to 'slow' collapse and growth. Make sure buoyancy jump not negative.
   !!             (6) For unstable conditions when growth is over multiple levels, limit change to maximum of one level per cycle through loop.
   !!             (7) Change lower limits for loops that calculate OSBL averages from 1 to 2. Large gradients between levels 1 and 2 can cause problems.
   !!             (8) Change upper limits from ibld-1 to ibld.
   !!             (9) Calculation of pycnocline thickness in unstable conditions. Check added to ensure that buoyancy jump is positive before calculating Ri.
   !!            (10) Thickness of interface layer at base of the stable OSBL set by Richardson number. Gives continuity in transition from unstable OSBL.
   !!            (11) Checks that buoyancy jump is poitive when calculating pycnocline profiles.
   !!            (12) Replace zwstrl with zvstr in calculation of eddy viscosity.
   !! 27/09/2017 (13) Calculate Stokes drift and Stokes penetration depth from wave information
   !!            (14) Buoyancy flux due to entrainment changed to include contribution from shear turbulence.
   !! 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.
   !!            (16) Calculation of Stokes drift from windspeed for PM spectrum (for testing, commented out)
   !!            (17) Modification to Langmuir velocity scale to include effects due to the Stokes penetration depth (for testing, commented out)
   !! ??/??/2018 (18) Revision to code structure, selected using key_osmldpth1. Inline code moved into subroutines. Changes to physics made,
   !!                  (a) Pycnocline temperature and salinity profies changed for unstable layers
   !!                  (b) The stable OSBL depth parametrization changed.
   !! 16/05/2019 (19) Fox-Kemper parametrization of restratification through mixed layer eddies added to revised code.
   !! 23/05/19   (20) Old code where key_osmldpth1` is *not* set removed, together with the key key_osmldpth1
   !!             4.2  !  2021-05  (S. Mueller)  Efficiency improvements, source-code clarity enhancements, and adaptation to tiling
   !!----------------------------------------------------------------------

   !!----------------------------------------------------------------------
   !!   'ln_zdfosm'                                          OSMOSIS scheme
   !!----------------------------------------------------------------------
   !!   zdf_osm        : update momentum and tracer Kz from osm scheme
   !!      zdf_osm_vertical_average             : compute vertical averages over boundary layers
   !!      zdf_osm_velocity_rotation            : rotate velocity components
   !!         zdf_osm_velocity_rotation_2d      :    rotation of 2d fields
   !!         zdf_osm_velocity_rotation_3d      :    rotation of 3d fields
   !!      zdf_osm_osbl_state                   : determine the state of the OSBL
   !!      zdf_osm_external_gradients           : calculate gradients below the OSBL
   !!      zdf_osm_calculate_dhdt               : calculate rate of change of hbl
   !!      zdf_osm_timestep_hbl                 : hbl timestep
   !!      zdf_osm_pycnocline_thickness         : calculate thickness of pycnocline
   !!      zdf_osm_diffusivity_viscosity        : compute eddy diffusivity and viscosity profiles
   !!      zdf_osm_fgr_terms                    : compute flux-gradient relationship terms
   !!         zdf_osm_pycnocline_buoyancy_profiles : calculate pycnocline buoyancy profiles
   !!      zdf_osm_zmld_horizontal_gradients    : calculate horizontal buoyancy gradients for use with Fox-Kemper parametrization
   !!      zdf_osm_osbl_state_fk                : determine state of OSBL and MLE layers
   !!      zdf_osm_mle_parameters               : timestep MLE depth and calculate MLE fluxes
   !!   zdf_osm_init   : initialization, namelist read, and parameters control
   !!      zdf_osm_alloc                        : memory allocation
   !!   osm_rst        : read (or initialize) and write osmosis restart fields
   !!   tra_osm        : compute and add to the T & S trend the non-local flux
   !!   trc_osm        : compute and add to the passive tracer trend the non-local flux (TBD)
   !!   dyn_osm        : compute and add to u & v trensd the non-local flux
   !!   zdf_osm_iomput : iom_put wrapper that accepts arrays without halo
   !!      zdf_osm_iomput_2d                    : iom_put wrapper for 2D fields
   !!      zdf_osm_iomput_3d                    : iom_put wrapper for 3D fields
   !!----------------------------------------------------------------------
   USE oce                       ! Ocean dynamics and active tracers
   !                             ! Uses ww from previous time step (which is now wb) to calculate hbl
   USE dom_oce                   ! Ocean space and time domain
   USE domtile, ONLY : dom_tile_init
Guillaume Samson's avatar
Guillaume Samson committed
   USE zdf_oce                   ! Ocean vertical physics
   USE sbc_oce                   ! Surface boundary condition: ocean
   USE sbcwave                   ! Surface wave parameters
   USE phycst                    ! Physical constants
   USE eosbn2                    ! Equation of state
   USE traqsr                    ! Details of solar radiation absorption
   USE zdfdrg, ONLY : rCdU_bot   ! Bottom friction velocity
   USE zdfddm                    ! Double diffusion mixing (avs array)
   USE iom                       ! I/O library
   USE lib_mpp                   ! MPP library
   USE trd_oce                   ! Ocean trends definition
   USE trdtra                    ! Tracers trends
   USE in_out_manager            ! I/O manager
   USE lbclnk                    ! Ocean lateral boundary conditions (or mpp link)
   USE prtctl                    ! Print control
   USE lib_fortran               ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)

   IMPLICIT NONE
   PRIVATE

   ! Public subroutines
   PUBLIC zdf_osm        ! Routine called by step.F90
   PUBLIC zdf_osm_init   ! Routine called by nemogcm.F90
   PUBLIC osm_rst        ! Routine called by step.F90
   PUBLIC tra_osm        ! Routine called by step.F90
   PUBLIC trc_osm        ! Routine called by trcstp.F90
   PUBLIC dyn_osm        ! Routine called by step.F90

   ! Public variables
   LOGICAL,  PUBLIC                                      ::   ln_osm_mle   !: Flag to activate the Mixed Layer Eddy (MLE)
   !                                                                       !     parameterisation, needed by tra_mle_init in
   !                                                                       !     tramle.F90
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghamu        !: Non-local u-momentum flux
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghamv        !: Non-local v-momentum flux
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghamt        !: Non-local temperature flux (gamma/<ws>o)
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ghams        !: Non-local salinity flux (gamma/<ws>o)
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hbl          !: Boundary layer depth
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hml          !: ML depth
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hmle         !: Depth of layer affexted by mixed layer eddies in Fox-Kemper parametrization
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dbdx_mle     !: Zonal buoyancy gradient in ML
   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dbdy_mle     !: Meridional buoyancy gradient in ML
   INTEGER,  PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   mld_prof     !: Level of base of MLE layer

   INTERFACE zdf_osm_velocity_rotation
      !!---------------------------------------------------------------------
      !!              ***  INTERFACE zdf_velocity_rotation  ***
      !!---------------------------------------------------------------------
      MODULE PROCEDURE zdf_osm_velocity_rotation_2d
      MODULE PROCEDURE zdf_osm_velocity_rotation_3d
   END INTERFACE
   !
   INTERFACE zdf_osm_iomput
      !!---------------------------------------------------------------------
      !!                 ***  INTERFACE zdf_osm_iomput  ***
      !!---------------------------------------------------------------------
      MODULE PROCEDURE zdf_osm_iomput_2d
      MODULE PROCEDURE zdf_osm_iomput_3d
   END INTERFACE

   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   etmean      ! Averaging operator for avt
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dh          ! Depth of pycnocline
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   r1_ft       ! Inverse of the modified Coriolis parameter at t-pts
   ! Layer indices
   INTEGER,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   nbld        ! Level of boundary layer base
   INTEGER,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   nmld        ! Level of mixed-layer depth (pycnocline top)
   ! Layer type
   INTEGER,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   n_ddh       ! Type of shear layer
   !                                                              !    n_ddh=0: active shear layer
   !                                                              !    n_ddh=1: shear layer not active
   !                                                              !    n_ddh=2: shear production low
   ! Layer flags
   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   l_conv      ! Unstable/stable bl
   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   l_shear     ! Shear layers
   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   l_coup      ! Coupling to bottom
   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   l_pyc       ! OSBL pycnocline present
   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   l_flux      ! Surface flux extends below OSBL into MLE layer
   LOGICAL,  ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   l_mle       ! MLE layer increases in hickness.
   ! Scales
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swth0       ! Surface heat flux (Kinematic)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sws0        ! Surface freshwater flux
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swb0        ! Surface buoyancy flux
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   suw0        ! Surface u-momentum flux
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sustar      ! Friction velocity
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   scos_wind   ! Cos angle of surface stress
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ssin_wind   ! Sin angle of surface stress
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swthav      ! Heat flux - bl average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swsav       ! Freshwater flux - bl average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swbav       ! Buoyancy flux - bl average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sustke      ! Surface Stokes drift
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   dstokes     ! Penetration depth of the Stokes drift
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swstrl      ! Langmuir velocity scale
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   swstrc      ! Convective velocity scale
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   sla         ! Trubulent Langmuir number
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   svstr       ! Velocity scale that tends to sustar for large Langmuir number
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   shol        ! Stability parameter for boundary layer
   ! Layer averages: BL
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_t_bl     ! Temperature average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_s_bl     ! Salinity average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_u_bl     ! Velocity average (u)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_v_bl     ! Velocity average (v)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_b_bl     ! Buoyancy average
   ! Difference between layer average and parameter at the base of the layer: BL
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_dt_bl    ! Temperature difference
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_ds_bl    ! Salinity difference
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_du_bl    ! Velocity difference (u)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_dv_bl    ! Velocity difference (v)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_db_bl    ! Buoyancy difference
   ! Layer averages: ML
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_t_ml     ! Temperature average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_s_ml     ! Salinity average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_u_ml     ! Velocity average (u)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_v_ml     ! Velocity average (v)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_b_ml     ! Buoyancy average
   ! Difference between layer average and parameter at the base of the layer: ML
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_dt_ml    ! Temperature difference
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_ds_ml    ! Salinity difference
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_du_ml    ! Velocity difference (u)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_dv_ml    ! Velocity difference (v)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_db_ml    ! Buoyancy difference
   ! Layer averages: MLE
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_t_mle    ! Temperature average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_s_mle    ! Salinity average
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_u_mle    ! Velocity average (u)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_v_mle    ! Velocity average (v)
   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   av_b_mle    ! Buoyancy average
   ! Diagnostic output
   REAL(WP), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   osmdia2d    ! Auxiliary array for diagnostic output
   REAL(WP), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   osmdia3d    ! Auxiliary array for diagnostic output
   LOGICAL  ::   ln_dia_pyc_scl = .FALSE.                         ! Output of pycnocline scalar-gradient profiles
Loading
Loading full blame...