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.
Changeset 15726 for NEMO/branches/UKMO – NEMO

Changeset 15726 for NEMO/branches/UKMO


Ignore:
Timestamp:
2022-02-23T16:54:01+01:00 (2 years ago)
Author:
dbruciaferri
Message:

adding V1 of DJR and FFR code - dynhpg_djr_ffr_smooth_v1.F90

File:
1 edited

Legend:

Unmodified
Added
Removed
  • NEMO/branches/UKMO/NEMO_4.0-TRUNK_r14960_HPG/src/OCE/DYN/dynhpg.F90

    r14834 r15726  
    2828   !!       hpg_sco  : s-coordinate (standard jacobian formulation) 
    2929   !!       hpg_isf  : s-coordinate (sco formulation) adapted to ice shelf 
    30    !!       hpg_djc  : s-coordinate (Density Jacobian with Cubic polynomial) 
     30   !!       hpg_djc  : s-coordinate (Density Jacobian with constrained cubic splines (ccs)) 
    3131   !!       hpg_prj  : s-coordinate (Pressure Jacobian with Cubic polynomial) 
     32   !!       hpg_djr  : s-coordinate (Density Jacobian with ccs subtracting a reference) 
     33   !!       hpg_ffr  : s-coordinate (Forces on faces subtracting a reference profile) 
    3234   !!---------------------------------------------------------------------- 
    3335   USE oce             ! ocean dynamics and tracers 
     
    6365   LOGICAL, PUBLIC ::   ln_hpg_prj   !: s-coordinate (Pressure Jacobian scheme) 
    6466   LOGICAL, PUBLIC ::   ln_hpg_isf   !: s-coordinate similar to sco modify for isf 
     67   LOGICAL, PUBLIC ::   ln_hpg_djr   !: s-coordinate (density Jacobian with cubic polynomial, subtracting a local reference profile) 
     68   LOGICAL, PUBLIC ::   ln_hpg_ffr   !: s-coordinate (forces on faces with subtraction of a local reference profile) 
    6569 
    6670   !                                !! Flag to control the type of hydrostatic pressure gradient 
     
    7276   INTEGER, PARAMETER ::   np_prj    =  4   ! s-coordinate (Pressure Jacobian scheme) 
    7377   INTEGER, PARAMETER ::   np_isf    =  5   ! s-coordinate similar to sco modify for isf 
     78   INTEGER, PARAMETER ::   np_djr    =  6   ! s-coordinate (density Jacobian with cubic polynomial, subtracting a local reference profile)  
     79   INTEGER, PARAMETER ::   np_ffr    =  7   ! s-coordinate (forces on faces with subtraction of a local reference profile)  
     80 
    7481   ! 
    7582   INTEGER, PUBLIC  ::   nhpg         !: type of pressure gradient scheme used ! (deduced from ln_hpg_... flags) (PUBLIC for TAM) 
    7683   ! 
    77    LOGICAL          ::   ln_hpg_djc_vnh, ln_hpg_djc_vnv                 ! flag to specify hpg_djc boundary condition type 
    78    REAL(wp), PUBLIC ::   aco_bc_hor, bco_bc_hor, aco_bc_vrt, bco_bc_vrt !: coefficients for hpg_djc hor and vert boundary conditions 
     84 
     85   LOGICAL     ::   ln_hpg_bcvN_rhd_hor, ln_hpg_bcvN_rhd_srf             ! flags to specify constrained cubic spline (ccs) bdy conditions for rhd & z 
     86   LOGICAL     ::   ln_hpg_bcvN_rhd_bot, ln_hpg_bcvN_z_hor               ! True implies von Neumann bcs; False implies linear extrapolation 
     87 
     88   REAL(wp)    ::   aco_bc_rhd_hor, bco_bc_rhd_hor, aco_bc_rhd_srf              ! coefficients for hpg_djc & hpg_djr boundary conditions  
     89   REAL(wp)    ::   bco_bc_rhd_srf, aco_bc_rhd_bot, bco_bc_rhd_bot              !    " 
     90   REAL(wp)    ::   aco_bc_z_hor, bco_bc_z_hor, aco_bc_z_srf                    !    "  
     91   REAL(wp)    ::   bco_bc_z_srf, aco_bc_z_bot, bco_bc_z_bot                    !    " 
     92 
     93   LOGICAL     ::   ln_hpg_djr_ref_ccs  ! T => constrained cubic, F => simple cubic used for interpolation of reference to target profiles 
     94   LOGICAL     ::   ln_hpg_ffr_ref      ! T => reference profile is subtracted; F => no reference profile subtracted 
     95   LOGICAL     ::   ln_hpg_ffr_ref_ccs  ! T => use constrained cubic spline to vertically interpolate reference to each profile    
     96   LOGICAL     ::   ln_hpg_ffr_hor_ccs  ! T => use constrained cubic spline to interpolate z_rhd_pmr along upper faces of cells 
     97   LOGICAL     ::   ln_hpg_ffr_hor_cub  ! T => use simple cubic polynomial to interpolate z_rhd_pmr along upper faces of cells 
     98   LOGICAL     ::   ln_hpg_ffr_vrt_quad ! T => use quadratic fit to z_rhd_pmr in vertical interpoln & integration; else standard 2nd order scheme 
     99 
     100   LOGICAL     ::   ln_dbg_hpg  ! T => debug outputs generated 
     101   LOGICAL     ::   ln_dbg_ij,  ln_dbg_ik,  ln_dbg_jk 
     102   INTEGER     ::   ki_dbg_min, ki_dbg_max, ki_dbg_cen 
     103   INTEGER     ::   kj_dbg_min, kj_dbg_max, kj_dbg_cen 
     104   INTEGER     ::   kk_dbg_min, kk_dbg_max, kk_dbg_cen  
     105 
    79106 
    80107   !! * Substitutions 
     
    121148      CASE ( np_prj )   ;   CALL hpg_prj    ( kt, Kmm, puu, pvv, Krhs )  ! s-coordinate (Pressure Jacobian scheme) 
    122149      CASE ( np_isf )   ;   CALL hpg_isf    ( kt, Kmm, puu, pvv, Krhs )  ! s-coordinate similar to sco modify for ice shelf 
     150      CASE ( np_djr )   ;   CALL hpg_djr    ( kt, Kmm, puu, pvv, Krhs )  ! s-coordinate (Density Jacobian with Cubic polynomial subtracting a local reference profile) 
     151      CASE ( np_ffr )   ;   CALL hpg_ffr    ( kt, Kmm, puu, pvv, Krhs )  ! s-coordinate (forces on faces with subtraction of a local reference profile) 
    123152      END SELECT 
    124153      ! 
     
    158187      REAL(wp), ALLOCATABLE, DIMENSION(:,:)   ::  ziceload       ! density at bottom of ISF 
    159188      !! 
    160       NAMELIST/namdyn_hpg/ ln_hpg_zco, ln_hpg_zps, ln_hpg_sco,     & 
    161          &                 ln_hpg_djc, ln_hpg_prj, ln_hpg_isf,     & 
    162          &                 ln_hpg_djc_vnh, ln_hpg_djc_vnv 
     189 
     190      NAMELIST/namdyn_hpg/ ln_hpg_zco, ln_hpg_zps, ln_hpg_sco, ln_hpg_isf,   & 
     191         &                 ln_hpg_djc, ln_hpg_prj, ln_hpg_djr, ln_hpg_ffr,   & 
     192         &                 ln_hpg_bcvN_rhd_hor,    ln_hpg_bcvN_rhd_srf,      &  
     193         &                 ln_hpg_bcvN_rhd_bot,    ln_hpg_bcvN_z_hor,        &                  
     194         &                 ln_hpg_djr_ref_ccs,     ln_hpg_ffr_vrt_quad,      &    
     195         &                 ln_hpg_ffr_ref,         ln_hpg_ffr_ref_ccs,       &  
     196         &                 ln_hpg_ffr_hor_ccs,     ln_hpg_ffr_hor_cub,       & 
     197         &                 ln_dbg_hpg, ln_dbg_ij,  ln_dbg_ik,  ln_dbg_jk,    & 
     198         &                 ki_dbg_min, ki_dbg_max, ki_dbg_cen,               &   
     199         &                 kj_dbg_min, kj_dbg_max, kj_dbg_cen,               & 
     200         &                 kk_dbg_min, kk_dbg_max, kk_dbg_cen            
     201 
    163202      !!---------------------------------------------------------------------- 
    164203      ! 
     
    175214         WRITE(numout,*) '~~~~~~~~~~~~' 
    176215         WRITE(numout,*) '   Namelist namdyn_hpg : choice of hpg scheme' 
    177          WRITE(numout,*) '      z-coord. - full steps                             ln_hpg_zco    = ', ln_hpg_zco 
    178          WRITE(numout,*) '      z-coord. - partial steps (interpolation)          ln_hpg_zps    = ', ln_hpg_zps 
    179          WRITE(numout,*) '      s-coord. (standard jacobian formulation)          ln_hpg_sco    = ', ln_hpg_sco 
    180          WRITE(numout,*) '      s-coord. (standard jacobian formulation) for isf  ln_hpg_isf    = ', ln_hpg_isf 
    181          WRITE(numout,*) '      s-coord. (Density Jacobian: Cubic polynomial)     ln_hpg_djc    = ', ln_hpg_djc 
    182          WRITE(numout,*) '      s-coord. (Pressure Jacobian: Cubic polynomial)    ln_hpg_prj    = ', ln_hpg_prj 
     216         WRITE(numout,*) '      z-coord. - full steps                              ln_hpg_zco    = ', ln_hpg_zco 
     217         WRITE(numout,*) '      z-coord. - partial steps (interpolation)           ln_hpg_zps    = ', ln_hpg_zps 
     218         WRITE(numout,*) '      s-coord. (standard jacobian formulation)           ln_hpg_sco    = ', ln_hpg_sco 
     219         WRITE(numout,*) '      s-coord. (standard jacobian formulation) for isf   ln_hpg_isf    = ', ln_hpg_isf 
     220         WRITE(numout,*) '      s-coord. (Density Jacobian: Cubic polynomial)      ln_hpg_djc    = ', ln_hpg_djc 
     221         WRITE(numout,*) '      s-coord. (Pressure Jacobian: Cubic polynomial)     ln_hpg_prj    = ', ln_hpg_prj 
     222         WRITE(numout,*) '      s-coord. (Density Jacobian: Cubic minus reference) ln_hpg_djr    = ', ln_hpg_djr 
     223         WRITE(numout,*) '      s-coord. (Density Jacobian: Cubic minus reference) ln_hpg_ffr    = ', ln_hpg_djr 
     224         WRITE(numout,*) '      s-coord. (forces on faces minus local reference)   ln_hpg_ffr    = ', ln_hpg_ffr 
    183225      ENDIF 
    184226      ! 
     
    188230      IF( (.NOT.ln_hpg_isf .AND. ln_isfcav) .OR. (ln_hpg_isf .AND. .NOT.ln_isfcav) )                  & 
    189231         &   CALL ctl_stop( 'dyn_hpg_init : ln_hpg_isf=T requires ln_isfcav=T and vice versa' )   
     232 
    190233      ! 
    191234#if defined key_qco 
     
    194237      ENDIF 
    195238#endif 
     239 
     240      IF( ln_hpg_djr .AND. nn_hls < 2) THEN 
     241         CALL ctl_stop( 'dyn_hpg_init : nn_hls < 2 and ln_hpg_djr not yet compatible' ) 
     242      ENDIF 
     243 
    196244      ! 
    197245      !                               ! Set nhpg from ln_hpg_... flags & consistency check 
     
    204252      IF( ln_hpg_prj ) THEN   ;   nhpg = np_prj   ;   ioptio = ioptio +1   ;   ENDIF 
    205253      IF( ln_hpg_isf ) THEN   ;   nhpg = np_isf   ;   ioptio = ioptio +1   ;   ENDIF 
     254      IF( ln_hpg_djr ) THEN   ;   nhpg = np_djr   ;   ioptio = ioptio +1   ;   ENDIF 
     255      IF( ln_hpg_ffr ) THEN   ;   nhpg = np_ffr   ;   ioptio = ioptio +1   ;   ENDIF 
    206256      ! 
    207257      IF( ioptio /= 1 )   CALL ctl_stop( 'NO or several hydrostatic pressure gradient options used' ) 
     
    216266         CASE( np_prj )   ;   WRITE(numout,*) '   ==>>>   s-coord. (Pressure Jacobian: Cubic polynomial)' 
    217267         CASE( np_isf )   ;   WRITE(numout,*) '   ==>>>   s-coord. (standard jacobian formulation) for isf' 
     268         CASE( np_djr )   ;   WRITE(numout,*) '   ==>>>   s-coord. (Density Jacobian: Cubic polynomial subtracting a local reference profile)' 
     269         CASE( np_ffr )   ;   WRITE(numout,*) '   ==>>>   s-coord. (forces on faces subtracting a local reference profile)' 
     270 
    218271         END SELECT 
    219272         WRITE(numout,*) 
    220273      ENDIF 
    221274      !                           
    222       IF ( ln_hpg_djc ) THEN 
    223          IF (ln_hpg_djc_vnh) THEN ! Von Neumann boundary condition 
    224            IF(lwp) WRITE(numout,*) '           horizontal bc: von Neumann ' 
    225            aco_bc_hor = 6.0_wp/5.0_wp 
    226            bco_bc_hor = 7.0_wp/15.0_wp 
     275      IF ( ln_hpg_djc .OR. ln_hpg_djr .OR. ln_hpg_ffr ) THEN 
     276         IF (ln_hpg_bcvN_rhd_hor) THEN ! Von Neumann boundary condition 
     277           IF(lwp) WRITE(numout,*) '           ccs rhd horizontal bc: von Neumann ' 
     278           aco_bc_rhd_hor = 6.0_wp/5.0_wp 
     279           bco_bc_rhd_hor = 7.0_wp/15.0_wp 
    227280         ELSE ! Linear extrapolation 
    228            IF(lwp) WRITE(numout,*) '           horizontal bc: linear extrapolation' 
    229            aco_bc_hor = 3.0_wp/2.0_wp 
    230            bco_bc_hor = 1.0_wp/2.0_wp 
     281           IF(lwp) WRITE(numout,*) '           ccs rhd horizontal bc: linear extrapolation' 
     282           aco_bc_rhd_hor = 3.0_wp/2.0_wp 
     283           bco_bc_rhd_hor = 1.0_wp/2.0_wp 
    231284         END IF 
    232          IF (ln_hpg_djc_vnv) THEN ! Von Neumann boundary condition 
    233            IF(lwp) WRITE(numout,*) '           vertical bc: von Neumann ' 
    234            aco_bc_vrt = 6.0_wp/5.0_wp 
    235            bco_bc_vrt = 7.0_wp/15.0_wp 
     285         IF (ln_hpg_bcvN_rhd_srf) THEN ! Von Neumann boundary condition 
     286           IF(lwp) WRITE(numout,*) '           ccs rhd surface bc: von Neumann ' 
     287           aco_bc_rhd_srf = 6.0_wp/5.0_wp 
     288           bco_bc_rhd_srf = 7.0_wp/15.0_wp 
    236289         ELSE ! Linear extrapolation 
    237            IF(lwp) WRITE(numout,*) '           vertical bc: linear extrapolation' 
    238            aco_bc_vrt = 3.0_wp/2.0_wp 
    239            bco_bc_vrt = 1.0_wp/2.0_wp 
     290           IF(lwp) WRITE(numout,*) '           ccs rhd surface bc: linear extrapolation' 
     291           aco_bc_rhd_srf = 3.0_wp/2.0_wp 
     292           bco_bc_rhd_srf = 1.0_wp/2.0_wp 
    240293         END IF 
     294         IF (ln_hpg_bcvN_rhd_bot) THEN ! Von Neumann boundary condition 
     295           IF(lwp) WRITE(numout,*) '           ccs rhd bottom bc: von Neumann ' 
     296           aco_bc_rhd_bot = 6.0_wp/5.0_wp 
     297           bco_bc_rhd_bot = 7.0_wp/15.0_wp 
     298         ELSE ! Linear extrapolation 
     299           IF(lwp) WRITE(numout,*) '           ccs rhd bottom bc: linear extrapolation' 
     300           aco_bc_rhd_bot = 3.0_wp/2.0_wp 
     301           bco_bc_rhd_bot = 1.0_wp/2.0_wp 
     302         END IF 
     303         IF (ln_hpg_bcvN_z_hor) THEN ! Von Neumann boundary condition 
     304           IF(lwp) WRITE(numout,*) '           ccs z horizontal bc: von Neumann ' 
     305           aco_bc_z_hor = 6.0_wp/5.0_wp 
     306           bco_bc_z_hor = 7.0_wp/15.0_wp 
     307         ELSE ! Linear extrapolation 
     308           IF(lwp) WRITE(numout,*) '           ccs z horizontal bc: linear extrapolation' 
     309           aco_bc_z_hor = 3.0_wp/2.0_wp 
     310           bco_bc_z_hor = 1.0_wp/2.0_wp 
     311         END IF 
     312 
     313! linear extrapolation used for z in the vertical (surface and bottom)    
     314         aco_bc_z_srf = 3.0_wp/2.0_wp 
     315         bco_bc_z_srf = 1.0_wp/2.0_wp 
     316         aco_bc_z_bot = 3.0_wp/2.0_wp 
     317         bco_bc_z_bot = 1.0_wp/2.0_wp 
     318 
    241319      END IF 
    242       ! 
     320 
     321      IF ( lwp .AND. ln_hpg_djr ) THEN 
     322         IF ( ln_hpg_djr_ref_ccs ) THEN  
     323       WRITE(numout,*) '           interpolation of reference profile by constrained cubic spline'                       
     324         ELSE  
     325       WRITE(numout,*) '           interpolation of reference profile by simple cubic spline with off-centring at boundaries'   
     326         END IF  
     327      END IF        
     328 
     329      IF ( lwp .AND. ln_hpg_ffr ) THEN 
     330         IF ( ln_hpg_ffr_ref_ccs ) THEN  
     331            IF ( ln_hpg_ffr_ref_ccs ) THEN  
     332          WRITE(numout,*) '           interpolation of reference profile in vertical by constrained cubic spline ' 
     333            ELSE  
     334          WRITE(numout,*) '           interpolation of reference profile in vertical by pure cubic polynomial fit '                    
     335            END IF        
     336         ELSE  
     337       WRITE(numout,*) '           no reference profile subtracted '                    
     338         END IF        
     339         IF ( ln_hpg_ffr_hor_ccs ) THEN  
     340       WRITE(numout,*) '           interpolation of z_rhd_pmr profile in horizontal by constrained cubic spline '     
     341         ELSE if ( ln_hpg_ffr_hor_cub ) THEN  
     342       WRITE(numout,*) '           interpolation of z_rhd_pmr profile in horizontal by simple cubic polynomial ' 
     343    ELSE  
     344       WRITE(numout,*) '           simple linear interpolation in horizontal of z_rhd_pmr profile'        
     345         END IF        
     346         IF ( ln_hpg_ffr_vrt_quad ) THEN  
     347       WRITE(numout,*) '           quadratic fit to z_rhd_pmr profile in vertical for interpolation and integration '     
     348         ELSE  
     349       WRITE(numout,*) '           simple second order accurate vertical integration of z_rhd_pmr profile in vertical'        
     350         END IF        
     351 
     352      END IF        
     353 
     354      ! 
     355      IF ( ln_dbg_hpg .AND. lwp ) THEN  
     356         WRITE(numout,*) '             dyn_hpg diagnostic settings'   
     357         WRITE(numout,*) ' ki_dbg_min = ', ki_dbg_min, '; ki_dbg_max = ', ki_dbg_max 
     358         WRITE(numout,*) ' kj_dbg_min = ', kj_dbg_min, '; kj_dbg_max = ', kj_dbg_max 
     359         WRITE(numout,*) ' kk_dbg_min = ', kk_dbg_min, '; kk_dbg_max = ', kk_dbg_max 
     360         WRITE(numout,*) ' ki_dbg_cen = ', ki_dbg_cen, '; kj_dbg_cen = ', kj_dbg_cen 
     361         WRITE(numout,*) ' kk_dbg_cen = ', kk_dbg_cen  
     362      END IF  
     363 
    243364   END SUBROUTINE dyn_hpg_init 
    244365 
     
    741862! mb for sea-ice shelves we will need to re-write this upper boundary condition in the same form as the lower boundary condition 
    742863      DO_2D( 1, 1, 1, 1 ) 
    743          zdrho_k(ji,jj,1) = aco_bc_vrt * ( rhd  (ji,jj,2) - rhd  (ji,jj,1) ) - bco_bc_vrt * zdrho_k(ji,jj,2) 
    744          zdz_k  (ji,jj,1) = aco_bc_vrt * (-gde3w(ji,jj,2) + gde3w(ji,jj,1) ) - bco_bc_vrt * zdz_k  (ji,jj,2) 
     864         zdrho_k(ji,jj,1) = aco_bc_rhd_srf * ( rhd  (ji,jj,2) - rhd  (ji,jj,1) ) - bco_bc_rhd_srf * zdrho_k(ji,jj,2) 
     865         zdz_k  (ji,jj,1) = aco_bc_z_srf   * (-gde3w(ji,jj,2) + gde3w(ji,jj,1) ) - bco_bc_z_srf  * zdz_k  (ji,jj,2) 
    745866      END_2D 
    746867 
     
    748869         IF ( mbkt(ji,jj)>1 ) THEN 
    749870            iktb = mbkt(ji,jj) 
    750             zdrho_k(ji,jj,iktb) = aco_bc_vrt * (     rhd(ji,jj,iktb) -     rhd(ji,jj,iktb-1) ) - bco_bc_vrt * zdrho_k(ji,jj,iktb-1) 
    751             zdz_k  (ji,jj,iktb) = aco_bc_vrt * (-gde3w(ji,jj,iktb) + gde3w(ji,jj,iktb-1) ) - bco_bc_vrt * zdz_k  (ji,jj,iktb-1)  
     871            zdrho_k(ji,jj,iktb) = aco_bc_rhd_bot * (    rhd(ji,jj,iktb) -   rhd(ji,jj,iktb-1) ) - bco_bc_rhd_bot * zdrho_k(ji,jj,iktb-1) 
     872            zdz_k  (ji,jj,iktb) = aco_bc_z_bot   * ( -gde3w(ji,jj,iktb) + gde3w(ji,jj,iktb-1) ) - bco_bc_z_bot  * zdz_k  (ji,jj,iktb-1)  
    752873         END IF 
    753874      END_2D 
     875 
     876      IF ( ln_dbg_hpg ) CALL dbg_3dr( '3. zdz_k', zdz_k )  
     877      IF ( ln_dbg_hpg ) CALL dbg_3dr( '3. zdrho_k', zdrho_k )  
    754878 
    755879      !-------------------------------------------------------------- 
     
    787911      END_3D 
    788912 
     913      IF ( ln_dbg_hpg ) CALL dbg_3dr( '4. z_rho_k', z_rho_k )  
     914 
    789915      !---------------------------------------------------------------------------------------- 
    790916      !  5. compute and store elementary horizontal differences in provisional arrays  
     
    840966         DO_2D( 0, 0, 0, 1 ) 
    841967            IF ( umask(ji,jj,jk) > 0.5_wp .AND. umask(ji-1,jj,jk) < 0.5_wp .AND. umask(ji+1,jj,jk) > 0.5_wp)  THEN 
    842                zz_drho_i(ji,jj) = aco_bc_hor * ( rhd    (ji+1,jj,jk) - rhd    (ji,jj,jk) ) - bco_bc_hor * zdrho_i(ji+1,jj,jk) 
    843                zz_dz_i  (ji,jj) = aco_bc_hor * (-gde3w(ji+1,jj,jk) + gde3w(ji,jj,jk) ) - bco_bc_hor * zdz_i  (ji+1,jj,jk) 
     968               zz_drho_i(ji,jj) = aco_bc_rhd_hor * ( rhd    (ji+1,jj,jk) - rhd  (ji,jj,jk) ) - bco_bc_rhd_hor * zdrho_i(ji+1,jj,jk) 
     969               zz_dz_i  (ji,jj) = aco_bc_z_hor   * (-gde3w(ji+1,jj,jk)   + gde3w(ji,jj,jk) ) - bco_bc_z_hor  * zdz_i  (ji+1,jj,jk) 
    844970            END IF 
    845971         END_2D 
     
    847973         DO_2D( -1, 1, 0, 1 ) 
    848974            IF ( umask(ji,jj,jk) < 0.5_wp .AND. umask(ji-1,jj,jk) > 0.5_wp .AND. umask(ji-2,jj,jk) > 0.5_wp) THEN 
    849                zz_drho_i(ji,jj) = aco_bc_hor * ( rhd    (ji,jj,jk) - rhd    (ji-1,jj,jk) ) - bco_bc_hor * zdrho_i(ji-1,jj,jk) 
    850                zz_dz_i  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj,jk) + gde3w(ji-1,jj,jk) ) - bco_bc_hor * zdz_i  (ji-1,jj,jk) 
     975               zz_drho_i(ji,jj) = aco_bc_rhd_hor * ( rhd  (ji,jj,jk) - rhd  (ji-1,jj,jk) ) - bco_bc_rhd_hor * zdrho_i(ji-1,jj,jk) 
     976               zz_dz_i  (ji,jj) = aco_bc_z_hor   * (-gde3w(ji,jj,jk) + gde3w(ji-1,jj,jk) ) - bco_bc_z_hor  * zdz_i  (ji-1,jj,jk) 
    851977            END IF 
    852978         END_2D 
     
    854980         DO_2D( 0, 1, 0, 0 ) 
    855981            IF ( vmask(ji,jj,jk) > 0.5_wp .AND. vmask(ji,jj-1,jk) < 0.5_wp .AND. vmask(ji,jj+1,jk) > 0.5_wp)  THEN 
    856                zz_drho_j(ji,jj) = aco_bc_hor * ( rhd    (ji,jj+1,jk) - rhd    (ji,jj,jk) ) - bco_bc_hor * zdrho_j(ji,jj+1,jk) 
    857                zz_dz_j  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj+1,jk) + gde3w(ji,jj,jk) ) - bco_bc_hor * zdz_j  (ji,jj+1,jk) 
     982               zz_drho_j(ji,jj) = aco_bc_rhd_hor * ( rhd  (ji,jj+1,jk) - rhd  (ji,jj,jk) ) - bco_bc_rhd_hor * zdrho_j(ji,jj+1,jk) 
     983               zz_dz_j  (ji,jj) = aco_bc_z_hor   * (-gde3w(ji,jj+1,jk) + gde3w(ji,jj,jk) ) - bco_bc_z_hor  * zdz_j  (ji,jj+1,jk) 
    858984            END IF 
    859985         END_2D 
     
    861987         DO_2D( 0, 1, -1, 1 ) 
    862988            IF ( vmask(ji,jj,jk) < 0.5_wp .AND. vmask(ji,jj-1,jk) > 0.5_wp .AND. vmask(ji,jj-2,jk) > 0.5_wp) THEN 
    863                zz_drho_j(ji,jj) = aco_bc_hor * ( rhd    (ji,jj,jk) - rhd    (ji,jj-1,jk) ) - bco_bc_hor * zdrho_j(ji,jj-1,jk) 
    864                zz_dz_j  (ji,jj) = aco_bc_hor * (-gde3w(ji,jj,jk) + gde3w(ji,jj-1,jk) ) - bco_bc_hor * zdz_j  (ji,jj-1,jk) 
     989               zz_drho_j(ji,jj) = aco_bc_rhd_hor * ( rhd  (ji,jj,jk) - rhd  (ji,jj-1,jk) ) - bco_bc_rhd_hor * zdrho_j(ji,jj-1,jk) 
     990               zz_dz_j  (ji,jj) = aco_bc_z_hor   * (-gde3w(ji,jj,jk) + gde3w(ji,jj-1,jk) ) - bco_bc_z_hor  * zdz_j  (ji,jj-1,jk) 
    865991            END IF 
    866992         END_2D 
     
    869995         zdrho_j(:,:,jk) = zz_drho_j(:,:) 
    870996         zdz_j  (:,:,jk) = zz_dz_j  (:,:) 
    871       END DO 
     997      END DO ! jk  
     998       
     999      IF ( ln_dbg_hpg ) THEN  
     1000         CALL dbg_3dr( '6. zdrho_i', zdrho_i )  
     1001         CALL dbg_3dr( '6. zdrho_j', zdrho_j )  
     1002      END IF        
    8721003 
    8731004      !-------------------------------------------------------------- 
    874       ! 7. Calculate integrals on side faces   
     1005      ! 7. Calculate integrals on upper/lower faces   
    8751006      !------------------------------------------------------------- 
    8761007 
     
    9001031      END_3D 
    9011032 
     1033      IF ( ln_dbg_hpg ) THEN  
     1034         CALL dbg_3dr( '7. z_rho_i', z_rho_i )  
     1035         CALL dbg_3dr( '7. z_rho_j', z_rho_j )  
     1036      END IF        
     1037 
    9021038      !-------------------------------------------------------------- 
    9031039      ! 8. Integrate in the vertical    
     
    9391075      END_3D 
    9401076      ! 
     1077 
     1078      IF ( ln_dbg_hpg ) THEN  
     1079         CALL dbg_3dr( '8. zhpi', zhpi )  
     1080         CALL dbg_3dr( '8. zhpj', zhpj )  
     1081      END IF        
     1082   
    9411083      IF( ln_wd_il )   DEALLOCATE( zcpx, zcpy ) 
    9421084      ! 
     
    14351577   END FUNCTION integ_spline 
    14361578 
     1579   SUBROUTINE hpg_djr( kt, Kmm, puu, pvv, Krhs ) 
     1580      !!--------------------------------------------------------------------- 
     1581      !!                  ***  ROUTINE hpg_djr  *** 
     1582      !! 
     1583      !! ** Method  :   Density Jacobian with Cubic polynomial scheme subtracting a local reference profile (pmr is profile minus reference)  
     1584      !!                This code assumes a 2-point halo  
     1585      !! 
     1586      !! Reference: Shchepetkin and McWilliams, J. Geophys. Res., 108(C3), 3090, 2003 
     1587      !!---------------------------------------------------------------------- 
     1588      INTEGER                             , INTENT( in )  ::  kt          ! ocean time-step index 
     1589      INTEGER                             , INTENT( in )  ::  Kmm, Krhs   ! ocean time level indices 
     1590      REAL(wp), DIMENSION(A2D(nn_hls),jpk,jpt), INTENT(inout) ::  puu, pvv    ! ocean velocities and RHS of momentum equation 
     1591      !! 
     1592      INTEGER  ::   ji, jj, jk, jr      ! loop indices 
     1593      INTEGER  ::   jn_hor_pts          ! number of points in the horizontal stencil 
     1594      INTEGER  ::   j_uv                ! 1 for u-cell; 2 for v-cell  
     1595      INTEGER  ::   iktb, iktt          ! jk indices at tracer points for top and bottom points  
     1596      INTEGER  ::   jia,  jib, jja, jjb !  
     1597      INTEGER  ::   jir, jjr            ! reference (expand) 
     1598      INTEGER  ::   jio, jjo            ! offset (expand) 
     1599       
     1600      REAL(wp) ::   z_grav_10, z1_12    ! constants  
     1601      REAL(wp) ::   zhta, zhtb          ! temporary scalars 
     1602      REAL(wp) ::   zcoef0, zep, cffw   !    "         " 
     1603      REAL(wp) ::   aco, bco            !    "         " 
     1604      REAL(wp) ::   cffu, cffx, z1_cff  !    "         " 
     1605      REAL(wp) ::   cffv, cffy          !    "         " 
     1606      REAL(wp) ::   cff_31, cff_42      !    "         " 
     1607      LOGICAL  ::   ll_tmp1, ll_tmp2    ! local logical variables 
     1608 
     1609      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   ztmp, zdz_i, zdz_j, zdz_k   ! Harmonic average of primitive grid differences 
     1610      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   zrhd_ref                    ! Reference density  
     1611      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   zz_ref                      ! Reference heights 
     1612      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   zdrhd_k_ref                 ! Harmonic average of primitive differences for reference field 
     1613      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4) ::   z_rhd_pmr                   ! rhd_prm = rhd - rhd_ref (values on the original grid)  
     1614      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   zdrhd_k_pmr                 !  
     1615      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   ::   z_lmr_k                     ! left minus right density integrals on vertical faces 
     1616 
     1617      INTEGER,  DIMENSION(A2D(nn_hls))       ::   jk_bot_ref                  ! bottom levels in the reference profile 
     1618      REAL(wp), DIMENSION(A2D(nn_hls))       ::   zdzx, zdzy                  ! primitive differences in x and y 
     1619      REAL(wp), DIMENSION(A2D(nn_hls))       ::   zz_dz_i, zz_dz_j 
     1620      REAL(wp), DIMENSION(A2D(nn_hls))       ::   zdrhd_21, zdrhd_32, zdrhd_43 
     1621      REAL(wp), DIMENSION(A2D(nn_hls),2)     ::   zz_drhd_ij, zdrhd_ij 
     1622      REAL(wp), DIMENSION(A2D(nn_hls))       ::   z_low_ij, z_upp_ij 
     1623      REAL(wp), DIMENSION(A2D(nn_hls))       ::   zhpi, zhpj 
     1624 
     1625      !!---------------------------------------------------------------------- 
     1626 
     1627      IF( kt == nit000 ) THEN 
     1628         IF(lwp) WRITE(numout,*) 
     1629         IF(lwp) WRITE(numout,*) 'dyn:hpg_djc : hydrostatic pressure gradient trend' 
     1630         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, density Jacobian with cubic polynomial scheme' 
     1631      ENDIF 
     1632 
     1633      ! Local constant initialization 
     1634      zcoef0 = - grav * 0.5_wp 
     1635      z_grav_10  = grav / 10._wp 
     1636      z1_12  = 1.0_wp / 12._wp 
     1637      zep = 1.e-15 
     1638 
     1639      jn_hor_pts = 4   ! 4 points in the horizontal stencil  
     1640 
     1641      !------------------------------------------------------------------------------------------------------ 
     1642      !  1. calculate harmonic averages of differences for z (grid heights) in i, j and k directions 
     1643      !------------------------------------------------------------------------------------------------------ 
     1644 
     1645      !------------------------------------------------------------------------------------------------------ 
     1646      !  1.1 compute and store elementary vertical differences then harmonic averages for z using eqn 5.18  
     1647      !      Full domain covered so that _ref profiles can be taken from zdz_k 
     1648      !------------------------------------------------------------------------------------------------------ 
     1649 
     1650      DO_3D( 2, 2, 2, 2, 2, jpk )   
     1651         ztmp  (ji,jj,jk) = - gde3w(ji  ,jj  ,jk) + gde3w(ji,jj,jk-1)     
     1652      END_3D 
     1653 
     1654      zdz_k  (:,:,1) = 0._wp  ! jk index changed from : to 1 to make computationally less wasteful  
     1655 
     1656      DO_3D( 2, 2, 2, 2, 2, jpk-1 )  
     1657         zdz_k(ji,jj,jk) = 2._wp *   ztmp(ji,jj,jk) * ztmp(ji,jj,jk+1)   & 
     1658            &                  / ( ztmp(ji,jj,jk) + ztmp(ji,jj,jk+1) ) 
     1659      END_3D 
     1660 
     1661      !---------------------------------------------------------------------------------- 
     1662      ! 1.2 apply boundary conditions at top and bottom using 5.36-5.37 
     1663      !---------------------------------------------------------------------------------- 
     1664 
     1665! mb for sea-ice shelves we will need to re-write this upper boundary condition in the same form as the lower boundary condition 
     1666      zdz_k  (:,:,1) = aco_bc_z_srf * (-gde3w(:,:,2) + gde3w(:,:,1) ) - bco_bc_z_srf * zdz_k  (:,:,2) 
     1667 
     1668      DO_2D( 2, 2, 2, 2 ) 
     1669         iktb = mbkt(ji,jj) 
     1670         IF ( iktb > 1 ) THEN 
     1671            zdz_k  (ji,jj,iktb) = aco_bc_z_bot * (-gde3w(ji,jj,iktb) + gde3w(ji,jj,iktb-1) ) - bco_bc_z_bot * zdz_k  (ji,jj,iktb-1)  
     1672         END IF 
     1673      END_2D 
     1674 
     1675      !---------------------------------------------------------------------------------------- 
     1676      !  1.3 compute and store elementary horizontal differences then harmonic averages for z using eqn 5.18 
     1677      !---------------------------------------------------------------------------------------- 
     1678 
     1679      DO jk = 1, jpkm1  
     1680         DO_2D( 1, 1, 1, 1 ) 
     1681            zdzx  (ji,jj) = - gde3w(ji+1,jj  ,jk) + gde3w(ji,jj,jk  ) 
     1682            zdzy  (ji,jj) = - gde3w(ji  ,jj+1,jk) + gde3w(ji,jj,jk  ) 
     1683         END_2D 
     1684 
     1685! this subroutine requires a 2-point halo      CALL lbc_lnk_multi( 'dynhpg', zdzx, 'U', 1., zdzy, 'V', 1. )  
     1686 
     1687         DO_2D( 0, 1, 0, 1 ) 
     1688            cffx = MAX( 2._wp * zdzx  (ji-1,jj) * zdzx  (ji,jj), 0._wp) 
     1689            z1_cff = zdzx(ji-1,jj)   + zdzx(ji,jj) 
     1690            zdz_i(ji,jj,jk)   = cffx / SIGN( MAX( ABS(z1_cff), zep ), z1_cff ) 
     1691 
     1692            cffy = 2._wp * zdzy  (ji  ,jj-1) * zdzy  (ji,jj  ) 
     1693            z1_cff = zdzy(ji,jj-1)   + zdzy(ji,jj) 
     1694            zdz_j(ji,jj,jk)   = cffy / SIGN( MAX( ABS(z1_cff), zep ), z1_cff ) 
     1695         END_2D 
     1696       
     1697      !---------------------------------------------------------------------------------- 
     1698      ! 1.4 apply boundary conditions at sides using 5.36-5.37 
     1699      !---------------------------------------------------------------------------------- 
     1700 
     1701         DO_2D( 0, 1, 0, 1) 
     1702            ! Walls coming from left: should check from 2 to jpi-1 (and jpj=2-jpj) 
     1703            IF ( umask(ji,jj,jk) > 0.5_wp .AND. umask(ji-1,jj,jk) < 0.5_wp .AND. umask(ji+1,jj,jk) > 0.5_wp)  THEN   
     1704               zdz_i(ji,jj,jk) = aco_bc_z_hor * (-gde3w(ji+1,jj,jk) + gde3w(ji,jj,jk) ) - bco_bc_z_hor * zz_dz_i(ji+1,jj) 
     1705            END IF 
     1706            ! Walls coming from right: should check from 3 to jpi (and jpj=2-jpj) 
     1707            IF ( umask(ji,jj,jk) < 0.5_wp .AND. umask(ji-1,jj,jk) > 0.5_wp .AND. umask(ji-2,jj,jk) > 0.5_wp) THEN 
     1708               zdz_i(ji,jj,jk) = aco_bc_z_hor * (-gde3w(ji,jj,jk) + gde3w(ji-1,jj,jk) ) - bco_bc_z_hor * zz_dz_i(ji-1,jj) 
     1709            END IF 
     1710            ! Walls coming from left: should check from 2 to jpj-1 (and jpi=2-jpi) 
     1711            IF ( vmask(ji,jj,jk) > 0.5_wp .AND. vmask(ji,jj-1,jk) < 0.5_wp .AND. vmask(ji,jj+1,jk) > 0.5_wp)  THEN 
     1712               zdz_j(ji,jj,jk) = aco_bc_z_hor * (-gde3w(ji,jj+1,jk) + gde3w(ji,jj,jk) ) - bco_bc_z_hor * zz_dz_j(ji,jj+1) 
     1713            END IF  
     1714            ! Walls coming from right: should check from 3 to jpj (and jpi=2-jpi) 
     1715            IF ( vmask(ji,jj,jk) < 0.5_wp .AND. vmask(ji,jj-1,jk) > 0.5_wp .AND. vmask(ji,jj-2,jk) > 0.5_wp) THEN  
     1716               zdz_j(ji,jj,jk) = aco_bc_z_hor * (-gde3w(ji,jj,jk) + gde3w(ji,jj-1,jk) ) - bco_bc_z_hor * zz_dz_j(ji,jj-1) 
     1717            END IF 
     1718         END_2D 
     1719      END DO  ! k  
     1720 
     1721      IF ( ln_dbg_hpg ) THEN  
     1722         CALL dbg_3dr( '1.4 gde3w', gde3w )  
     1723         CALL dbg_3dr( '1.4 zdz_i', zdz_i )  
     1724         CALL dbg_3dr( '1.4 zdz_j', zdz_j )  
     1725         CALL dbg_3dr( '1.4 zdz_k', zdz_k )  
     1726         CALL dbg_2di( 'mbkt', mbkt)  
     1727      END IF  
     1728      !---------------------------------------------------------------------------------------- 
     1729      ! 2.  Start loop over the u and v components and find the reference profile    
     1730      !     The loop ends in section 5.4 
     1731      !---------------------------------------------------------------------------------------- 
     1732 
     1733      DO j_uv = 1, 2     ! j_uv = 1 is for u-cell ; j_uv = 2 for v-cell 
     1734 
     1735      !---------------------------------------------------------------------------------------- 
     1736      !  2.1 find reference profiles zrhd_ref and zz_ref and the bottom level of the reference profile   
     1737      !---------------------------------------------------------------------------------------- 
     1738 
     1739         IF ( ln_dbg_hpg ) CALL dbg_2dr( '2.1 ht_0', ht_0 )  
     1740         CALL calc_rhd_ref(j_uv, jn_hor_pts, zrhd_ref, zz_ref, jk_bot_ref)   ! Uses rhd (IN) to calculate all other fields (OUT) 
     1741 
     1742         IF ( ln_dbg_hpg ) THEN  
     1743            CALL dbg_3dr( '2.1 rhd', rhd )  
     1744            CALL dbg_3dr( '2.1 zrhd_ref', zrhd_ref )  
     1745            CALL dbg_3dr( '2.1 zz_ref', zz_ref )  
     1746            CALL dbg_2di( '2.1 jk_bot_ref', jk_bot_ref )  
     1747         END IF  
     1748     
     1749      !-------------------------------------------------------------------------------------------------------- 
     1750      !  2.2  IF  ln_hpg_djr_ref_ccs compute zdrhd_k_ref then set bcs at top & bottom   
     1751      !                              (bcs not needed for simple cubic off-centred at boundaries) 
     1752      !-------------------------------------------------------------------------------------------------------- 
     1753 
     1754         IF ( ln_hpg_djr_ref_ccs ) THEN 
     1755            CALL calc_drhd_k(zrhd_ref, jk_bot_ref, zdrhd_k_ref)  
     1756            IF ( ln_dbg_hpg ) CALL dbg_3dr( '2.3 zdrhd_k_ref', zdrhd_k_ref )       
     1757         END IF  ! ln_hpg_djr_ref_ccs  
     1758 
     1759      !---------------------------------------------------------------------------------------- 
     1760      !  3. interpolate reference profiles to target profiles and form difference profiles z_rhd_pmr 
     1761      !---------------------------------------------------------------------------------------- 
     1762 
     1763         DO jr = 1, 4       
     1764            IF ( j_uv == 1 ) THEN  
     1765               jio = jr - 2         ! range of jio is -1 to 2  
     1766               jjo = 0  
     1767            ELSE  
     1768               jio = 0 
     1769               jjo = jr - 2  
     1770            END IF  
     1771 
     1772            IF ( ln_hpg_djr_ref_ccs ) THEN  
     1773               CALL ref_to_tgt_ccs ( jio, jjo, gde3w, rhd, zz_ref, zrhd_ref, zdrhd_k_ref, jk_bot_ref, z_rhd_pmr(:,:,:,jr) ) 
     1774            ELSE  
     1775               CALL ref_to_tgt_cub ( jio, jjo, gde3w, rhd, zz_ref, zrhd_ref, jk_bot_ref, z_rhd_pmr(:,:,:,jr) )   
     1776            END IF  
     1777  
     1778            IF ( ln_dbg_hpg ) CALL dbg_3dr( '3. z_rhd_pmr', z_rhd_pmr(:,:,:,jr) )  
     1779 
     1780         END DO      
     1781 
     1782      !---------------------------------------------------------------------------------------- 
     1783      ! 4. Calculations for side-face integrals 
     1784      !---------------------------------------------------------------------------------------- 
     1785     
     1786      !---------------------------------------------------------------------------------------- 
     1787      !  4.1 compute and store elementary vertical differences then harmonic averages  
     1788      !     based on z_rhd_pmr arrays (zdz_k has already been calculated)   
     1789      !---------------------------------------------------------------------------------------- 
     1790 
     1791! start loop over the two side faces jr = 2 "left" face; jr = 3 "right" face  
     1792         DO jr = 2, 3 
     1793 
     1794            IF ( j_uv == 1 ) THEN   
     1795               jio = jr - 2  
     1796               jjo = 0  
     1797            ELSE  
     1798               jio = 0  
     1799               jjo = jr - 2  
     1800            END IF  
     1801 
     1802            DO_3D( 0, 0, 0, 0, 2, jpk )   
     1803               ztmp(ji,jj,jk) =   z_rhd_pmr (ji,jj,jk,jr) - z_rhd_pmr(ji,jj,jk-1,jr) 
     1804            END_3D 
     1805 
     1806            zdrhd_k_pmr(:,:,:) = 0._wp   ! should be unnecessary  
     1807 
     1808            DO_3D( 0, 0, 0, 0, 2, jpk-1 )  
     1809               cffw = MAX( 2._wp * ztmp(ji,jj,jk) * ztmp(ji,jj,jk+1), 0._wp ) 
     1810               z1_cff = ztmp(ji,jj,jk) + ztmp(ji,jj,jk+1) 
     1811               zdrhd_k_pmr(ji,jj,jk) = cffw / SIGN( MAX( ABS(z1_cff), zep ), z1_cff ) 
     1812            END_3D 
     1813 
     1814! apply boundary conditions at top and bottom   
     1815            DO_2D( 0, 0, 0, 0 ) 
     1816               zdrhd_k_pmr(ji,jj,1) = aco_bc_rhd_srf * ( z_rhd_pmr(ji,jj,2,jr) - z_rhd_pmr(ji,jj,1,jr) ) - bco_bc_rhd_srf * zdrhd_k_pmr(ji,jj,2) 
     1817               iktb = mbkt(ji+jio,jj+jjo) 
     1818               IF ( iktb > 1 ) THEN 
     1819                  zdrhd_k_pmr(ji,jj,iktb) = aco_bc_rhd_bot * (z_rhd_pmr(ji,jj,iktb,jr) - z_rhd_pmr(ji,jj,iktb-1,jr) ) - bco_bc_rhd_bot * zdrhd_k_pmr(ji,jj,iktb-1) 
     1820               END IF 
     1821            END_2D 
     1822 
     1823 
     1824      !-------------------------------------------------------------- 
     1825      ! 4.2 Upper half of top-most grid box, compute and store 
     1826      !------------------------------------------------------------- 
     1827!! ssh replaces e3w_n ; gde3w is a depth; the formulae involve heights   
     1828!! rho_k stores grav * FX / rho_0   
     1829!! *** AY note: ssh(ji,jj,Kmm) + gde3w(ji,jj,1) = e3w(ji,jj,1,Kmm) 
     1830            DO_2D( 0, 0, 0, 0) 
     1831               ztmp(ji,jj,1) =  grav * ( ssh(ji+jio,jj+jjo,Kmm) + gde3w(ji+jio,jj+jjo,1) )            &  
     1832            &                           * (  z_rhd_pmr(ji,jj,1,jr)                                    & 
     1833            &                     + 0.5_wp * (   z_rhd_pmr(ji,jj,2,jr) - z_rhd_pmr(ji,jj,1,jr) )      & 
     1834            &                              * (   ssh   (ji+jio,jj+jjo,Kmm) + gde3w(ji+jio,jj+jjo,1) ) & 
     1835            &                              / ( - gde3w(ji+jio,jj+jjo,2) + gde3w(ji+jio,jj+jjo,1) )  ) 
     1836            END_2D 
     1837 
     1838      !-------------------------------------------------------------- 
     1839      ! 4.3 Interior faces, compute and store 
     1840      !------------------------------------------------------------- 
     1841 
     1842            DO_3D( 0, 0, 0, 0, 2, jpkm1 ) 
     1843               ztmp(ji,jj,jk) = zcoef0 * (   z_rhd_pmr(ji,jj,jk,jr) + z_rhd_pmr(ji,jj,jk-1,jr) )                             & 
     1844            &                             * ( - gde3w(ji+jio,jj+jjo,jk) + gde3w(ji+jio,jj+jjo,jk-1) )                            & 
     1845            &                 + z_grav_10 * (                                                                                    & 
     1846            &     (   zdrhd_k_pmr(ji,jj,jk)    - zdrhd_k_pmr(ji,jj,jk-1) )                                                          & 
     1847            &   * ( - gde3w(ji+jio,jj+jjo,jk)  + gde3w(ji+jio,jj+jjo,jk-1)  - z1_12 * ( zdz_k(ji+jio,jj+jjo,jk) + zdz_k  (ji+jio,jj+jjo,jk-1) ) ) & 
     1848            &   - (   zdz_k(ji+jio,jj+jjo,jk)  - zdz_k(ji+jio,jj+jjo,jk-1) )                                                                      & 
     1849            &   * (   z_rhd_pmr(ji,jj,jk,jr) - z_rhd_pmr(ji,jj,jk-1,jr) - z1_12 * ( zdrhd_k_pmr(ji,jj,jk) + zdrhd_k_pmr(ji,jj,jk-1) ) )               & 
     1850            &                             ) 
     1851            END_3D 
     1852 
     1853! the force on the right face could be set equal to the average of the right face for this cell and the left face for the cell to the right 
     1854! this would require an lbc_lnk call   
     1855 
     1856! lmr stands for left minus right  
     1857 
     1858            IF ( jr == 2 ) THEN   
     1859               DO_3D( 0, 0, 0, 0, 1, jpkm1 )  
     1860                  z_lmr_k(ji,jj,jk) =  ztmp(ji,jj,jk)   ! values on left face;  
     1861               END_3D  
     1862            ELSE  
     1863               DO_3D( 0, 0, 0, 0, 1, jpkm1 )  
     1864                  z_lmr_k(ji,jj,jk) = z_lmr_k(ji,jj,jk) - ztmp(ji,jj,jk)   ! subtract the values on the right face  
     1865               END_3D  
     1866            END IF  
     1867 
     1868            IF ( ln_dbg_hpg ) CALL dbg_3dr( '4. z_lmr_k', z_lmr_k )  
     1869 
     1870         END DO  ! jr  
     1871 
     1872 
     1873      !---------------------------------------------------------------------------------------- 
     1874      !  5. Calculations for upper and lower faces and the vertical integration  
     1875      !---------------------------------------------------------------------------------------- 
     1876 
     1877         z_upp_ij(:,:) = 0._wp 
     1878         zhpi(:,:)     = 0._wp 
     1879         zhpj(:,:)     = 0._wp 
     1880 
     1881         DO jk = 1, jpk -1  
     1882 
     1883            IF ( ln_dbg_hpg .AND. lwp ) THEN  
     1884               WRITE(numout,*)  
     1885               WRITE(numout,*) ' jk = ', jk  
     1886            END IF  
     1887 
     1888      !---------------------------------------------------------------------------------------- 
     1889      !  5.1 compute and store elementary horizontal differences zfor z_rhd_pmr arrays  
     1890      !---------------------------------------------------------------------------------------- 
     1891 
     1892            DO_2D( 0, 0, 0, 0 ) 
     1893               zdrhd_21(ji,jj) =   z_rhd_pmr(ji,jj,jk,2) - z_rhd_pmr(ji,jj,jk,1) 
     1894               zdrhd_32(ji,jj) =   z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) 
     1895               zdrhd_43(ji,jj) =   z_rhd_pmr(ji,jj,jk,4) - z_rhd_pmr(ji,jj,jk,3) 
     1896            END_2D 
     1897 
     1898            DO_2D( 0, 0, 0, 0 ) 
     1899               cff_31 = MAX( 2._wp * zdrhd_21(ji,jj) * zdrhd_32(ji,jj), 0._wp )  
     1900               z1_cff = zdrhd_21(ji,jj) + zdrhd_32(ji,jj) 
     1901               zz_drhd_ij(ji,jj,1) = cff_31 / SIGN( MAX( ABS(z1_cff), zep ), z1_cff ) 
     1902 
     1903               cff_42 = MAX( 2._wp * zdrhd_32(ji,jj) * zdrhd_43(ji,jj), 0._wp )  
     1904               z1_cff = zdrhd_32(ji,jj) + zdrhd_43(ji,jj) 
     1905               zz_drhd_ij(ji,jj,2) = cff_42 / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )  
     1906            END_2D 
     1907 
     1908      !---------------------------------------------------------------------------------- 
     1909      ! 5.2 apply boundary conditions at side boundaries using 5.36-5.37 
     1910      !---------------------------------------------------------------------------------- 
     1911 
     1912 
     1913! need to check this sub-section more carefully  
     1914 
     1915            zdrhd_ij(:,:,:) = zz_drhd_ij(:,:,:) 
     1916 
     1917            IF ( j_uv == 1 ) THEN  
     1918 
     1919               DO_2D( 0, 0, 0, 0)        
     1920            ! Walls coming from left: should check from 2 to jpi-1 (and jpj=2-jpj) 
     1921                  IF ( umask(ji,jj,jk) > 0.5_wp .AND. umask(ji-1,jj,jk) < 0.5_wp .AND. umask(ji+1,jj,jk) > 0.5_wp)  THEN   
     1922                     zdrhd_ij(ji,jj,1) = aco_bc_rhd_hor * ( z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) ) - bco_bc_rhd_hor * zz_drhd_ij(ji,jj,2)  
     1923                  END IF 
     1924            ! Walls coming from right: should check from 3 to jpi (and jpj=2-jpj) 
     1925                  IF ( umask(ji,jj,jk) < 0.5_wp .AND. umask(ji-1,jj,jk) > 0.5_wp .AND. umask(ji-2,jj,jk) > 0.5_wp) THEN 
     1926                     zdrhd_ij(ji,jj,2) = aco_bc_rhd_hor * ( z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) ) - bco_bc_rhd_hor * zz_drhd_ij(ji,jj,1)   
     1927                  END IF 
     1928               END_2D  
     1929 
     1930            ELSE ! j_uv == 2  
     1931         
     1932               DO_2D( 0, 0, 0, 0)     
     1933            ! Walls coming from left: should check from 2 to jpj-1 (and jpi=2-jpi) 
     1934                  IF ( vmask(ji,jj,jk) > 0.5_wp .AND. vmask(ji,jj-1,jk) < 0.5_wp .AND. vmask(ji,jj+1,jk) > 0.5_wp)  THEN 
     1935                     zdrhd_ij(ji,jj,1) = aco_bc_rhd_hor * ( z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) ) - bco_bc_rhd_hor * zz_drhd_ij(ji,jj,2) 
     1936                  END IF 
     1937            ! Walls coming from right: should check from 3 to jpj (and jpi=2-jpi) 
     1938                  IF ( vmask(ji,jj,jk) < 0.5_wp .AND. vmask(ji,jj-1,jk) > 0.5_wp .AND. vmask(ji,jj-2,jk) > 0.5_wp) THEN  
     1939                     zdrhd_ij(ji,jj,2) = aco_bc_rhd_hor * ( z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) ) - bco_bc_rhd_hor * zz_drhd_ij(ji,jj,1)  
     1940                  END IF 
     1941               END_2D 
     1942 
     1943            END IF ! j_uv == 2  
     1944 
     1945            IF ( ln_dbg_hpg ) THEN  
     1946               CALL dbg_2dr( '5.2 zdrhd_ij(:,:,1)', zdrhd_ij(:,:,1) )  
     1947               CALL dbg_2dr( '5.2 zdrhd_ij(:,:,2)', zdrhd_ij(:,:,2) )  
     1948            END IF           
     1949 
     1950      !-------------------------------------------------------------- 
     1951      ! 5.3 Calculate integrals on lower faces   
     1952      !------------------------------------------------------------- 
     1953 
     1954            IF ( j_uv == 1 ) THEN  
     1955 
     1956               DO_2D( 0, 0, 0, 0 ) 
     1957! two -ve signs cancel in next two lines (within zcoef0 and because gde3w is a depth not a height) 
     1958                  z_low_ij(ji,jj) = zcoef0 * ( z_rhd_pmr(ji,jj,jk,3) + z_rhd_pmr(ji,jj,jk,2) )                                    & 
     1959             &                               * ( gde3w(ji+1,jj,jk) - gde3w(ji,jj,jk) )                                     
     1960 
     1961                  IF ( umask(ji-1, jj, jk) > 0.5 .OR. umask(ji+1, jj, jk) > 0.5 ) THEN 
     1962                     z_low_ij(ji,jj) = z_low_ij(ji,jj) - z_grav_10 * (                                                            & 
     1963             &           (   zdrhd_ij(ji,jj,2) - zdrhd_ij(ji,jj,1) )                                                              & 
     1964             &         * ( - gde3w(ji+1,jj,jk) + gde3w(ji,jj,jk) - z1_12 * ( zdz_i(ji+1,jj,jk) + zdz_i(ji,jj,jk) ) )              & 
     1965             &         - (   zdz_i(ji+1,jj,jk) - zdz_i(ji,jj,jk) )                                                                & 
     1966             &         * (   z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) - z1_12 * ( zdrhd_ij(ji,jj,2) + zdrhd_ij(ji,jj,1) ) )  & 
     1967             &                                               ) 
     1968                  END IF 
     1969               END_2D 
     1970 
     1971               IF ( ln_dbg_hpg ) CALL dbg_2dr( '5.3 z_low_ij 1', z_low_ij )  
     1972           
     1973       ELSE ! j_uv == 2      
     1974             
     1975               DO_2D( 0, 0, 0, 0 ) 
     1976                  z_low_ij(ji,jj) = zcoef0 * ( z_rhd_pmr(ji,jj,jk,3) + z_rhd_pmr(ji,jj,jk,2) )                                    & 
     1977             &                    * ( gde3w(ji,jj+1,jk) - gde3w(ji,jj,jk) )                                   
     1978 
     1979                  IF ( vmask(ji, jj-1, jk) > 0.5 .OR. vmask(ji, jj+1, jk) > 0.5 ) THEN 
     1980                     z_low_ij(ji,jj) = z_low_ij(ji,jj) - z_grav_10 * (                                                            & 
     1981             &           (   zdrhd_ij(ji,jj,2) - zdrhd_ij(ji,jj,1) )                                                              & 
     1982             &         * ( - gde3w(ji,jj+1,jk) + gde3w(ji,jj,jk) - z1_12 * ( zdz_j(ji,jj+1,jk) + zdz_j(ji,jj,jk) ) )              & 
     1983             &         - (   zdz_j(ji,jj+1,jk) - zdz_j(ji,jj,jk) )                                                                & 
     1984             &         * (   z_rhd_pmr(ji,jj,jk,3) - z_rhd_pmr(ji,jj,jk,2) - z1_12 * ( zdrhd_ij(ji,jj,2) + zdrhd_ij(ji,jj,1) ) )  & 
     1985             &                                                 ) 
     1986                  END IF 
     1987               END_2D 
     1988 
     1989               IF ( ln_dbg_hpg ) CALL dbg_2dr( '5.3 z_low_ij 2', z_low_ij )  
     1990           
     1991       END IF ! j_uv       
     1992 
     1993      !-------------------------------------------------------------- 
     1994      ! 5.4 Integrate in the vertical (including contributions from both upper and lower and side-faces)     
     1995      !------------------------------------------------------------- 
     1996      ! 
     1997            IF ( j_uv == 1 ) THEN  
     1998 
     1999               DO_2D( 0, 0, 0, 0 ) 
     2000                  zhpi(ji,jj) = zhpi(ji,jj) +                                        & 
     2001               &            ( z_lmr_k(ji,jj,jk)  - ( z_low_ij(ji,jj) - z_upp_ij(ji,jj) ) ) * r1_e1u(ji,jj) 
     2002         ! add to the general momentum trend 
     2003                  puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + zhpi(ji,jj) 
     2004               END_2D 
     2005 
     2006               IF ( ln_dbg_hpg ) CALL dbg_2dr( '5.4 zhpi', zhpi )  
     2007 
     2008            ELSE ! j_uv == 2    
     2009 
     2010               DO_2D( 0, 0, 0, 0 ) 
     2011                  zhpj(ji,jj) = zhpj(ji,jj) +                                         & 
     2012               &            ( z_lmr_k(ji,jj,jk) - ( z_low_ij(ji,jj) - z_upp_ij(ji,jj) ) ) * r1_e2v(ji,jj) 
     2013         ! add to the general momentum trend 
     2014                  pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + zhpj(ji,jj) 
     2015               END_2D 
     2016 
     2017               IF ( ln_dbg_hpg ) CALL dbg_2dr( '5.4 zhpj', zhpj )  
     2018 
     2019            END IF ! j_uv   
     2020       
     2021            DO_2D( 0, 0, 0, 0 ) 
     2022               z_upp_ij(ji,jj) = z_low_ij(ji,jj) 
     2023            END_2D  
     2024 
     2025         END DO ! k  
     2026 
     2027      END DO ! j_uv   
     2028 
     2029   END SUBROUTINE hpg_djr 
     2030    
     2031!----------------------------------------------------------------------------------------------------------------- 
     2032    
     2033   SUBROUTINE ref_to_tgt_cub ( ki_off_tgt, kj_off_tgt, p_dep_tgt, p_fld_tgt, p_z_ref, p_fld_ref, kk_bot_ref, p_fld_tgt_ref)  
     2034        
     2035      INTEGER,                                INTENT(in)  :: ki_off_tgt    ! offset of points in target array in i-direction    
     2036      INTEGER,                                INTENT(in)  :: kj_off_tgt    ! offset of points in target array in j-direction    
     2037      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: p_dep_tgt     ! depths of target profiles        
     2038      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: p_fld_tgt     ! field values on the target grid  
     2039      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: p_z_ref       ! heights of reference  profiles        
     2040      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: p_fld_ref     ! field values to be interpolated (in the vertical) on reference grid 
     2041      INTEGER,  DIMENSION(A2D(nn_hls)),       INTENT(in)  :: kk_bot_ref    ! bottom levels in the reference profile 
     2042      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(OUT) :: p_fld_tgt_ref ! target minus reference on target grid          
     2043 
     2044      INTEGER,  DIMENSION(A2D(nn_hls),jpk) :: jk_ref_for_tgt   ! reference index for interpolation to target grid; target lies between jk_ref and jk_ref-1. 
     2045 
     2046!--------------------------------------------------------------------------------------------------------------- 
     2047 
     2048      INTEGER  :: ji, jj, jk                   ! loop indices  
     2049      INTEGER  :: jkr 
     2050      REAL(wp) :: z_r_6, z_r_24                ! constants 
     2051 
     2052      REAL(wp) :: zf_a, zf_b, zf_c, zf_d 
     2053      REAL(wp) :: zz_ref_jkr, zz_ref_jkrm1, zeta, zetasq  
     2054      REAL(wp) :: zf_0, zf_1, zf_2, zf_3 
     2055      REAL(wp) :: zave_bc, zave_ad, zdif_cb, zdif_da 
     2056       
     2057      REAL(wp) :: zz_tgt_lcl, zfld_ref_on_tgt  
     2058 
     2059!----------------------------------------------------------------------------------------------------------------- 
     2060 
     2061      z_r_6  = 1._wp / 6._wp  
     2062      z_r_24 = 1._wp / 24._wp  
     2063 
     2064! find jk_ref_for_tgt (bounding levels on reference grid for each target point 
     2065      CALL loc_ref_tgt ( ki_off_tgt, kj_off_tgt, p_dep_tgt, p_z_ref, kk_bot_ref, jk_ref_for_tgt ) 
     2066 
     2067      DO_3D( 0, 0, 0, 0, 1, jpk-1 )  
     2068         zz_tgt_lcl = - p_dep_tgt( ji+ki_off_tgt, jj+kj_off_tgt, jk ) 
     2069 
     2070! it would probably be better computationally for fld_ref to have the jk index first.  
     2071 
     2072!!! jkr >= 2 and p_fld_ref has jk = 0 available    
     2073  
     2074         jkr  = jk_ref_for_tgt(ji,jj,jk)    
     2075         zf_a = p_fld_ref(ji,jj,jkr-2) 
     2076    zf_b = p_fld_ref(ji,jj,jkr-1) 
     2077    zf_c = p_fld_ref(ji,jj,jkr  ) 
     2078    zf_d = p_fld_ref(ji,jj,jkr+1) 
     2079 
     2080         zz_ref_jkrm1 = p_z_ref( ji, jj, jkr - 1 )    
     2081         zz_ref_jkr = p_z_ref( ji, jj, jkr ) 
     2082         zeta = ( zz_tgt_lcl - 0.5_wp*(zz_ref_jkr+zz_ref_jkrm1) ) / ( zz_ref_jkr - zz_ref_jkrm1 )   
     2083         zetasq = zeta*zeta 
     2084 
     2085         zave_bc = 0.5_wp*(zf_b+zf_c)  
     2086         zave_ad = 0.5_wp*(zf_a+zf_d) 
     2087         zdif_cb = zf_c - zf_b 
     2088         zdif_da = zf_d - zf_a 
     2089 
     2090         zf_0 = 1.125_wp*zave_bc - 0.125_wp*zave_ad 
     2091         zf_1 = 1.125_wp*zdif_cb - z_r_24*zdif_da  
     2092         zf_2 = 0.5_wp*(zave_ad - zave_bc)             ! corrected 12/09/2021 
     2093         zf_3 = z_r_6 * zdif_da - 0.5_wp*zdif_cb       ! corrected 12/09/2021 
     2094 
     2095         zfld_ref_on_tgt = zf_0 + zeta*zf_1 + zetasq*(zf_2 + zeta*zf_3)  
     2096     
     2097! when zfld_ref_on_tgt is commented out in the next line, the results for hpg_djr should agree with those for hpg_djc.    
     2098         p_fld_tgt_ref(ji, jj, jk) = p_fld_tgt(ji+ki_off_tgt, jj+kj_off_tgt, jk) - zfld_ref_on_tgt 
     2099 
     2100      END_3D    
     2101 
     2102      RETURN         
     2103 
     2104   END SUBROUTINE ref_to_tgt_cub 
     2105 
     2106!----------------------------------------------------------------------------------------------------------------- 
     2107 
     2108   SUBROUTINE ref_to_tgt_ccs ( ki_off_tgt, kj_off_tgt, pdep_tgt, pfld_tgt, pz_ref, pfld_ref, pdfld_k_ref, kk_bot_ref, pfld_tgt_ref)  
     2109        
     2110      INTEGER,                      INTENT(in)  :: ki_off_tgt    ! offset of points in target array in i-direction    
     2111      INTEGER,                      INTENT(in)  :: kj_off_tgt    ! offset of points in target array in j-direction    
     2112      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: pdep_tgt      ! depths of target profiles        
     2113      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: pfld_tgt      ! field values on the target grid  
     2114      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: pz_ref        ! heights of reference  profiles        
     2115      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: pfld_ref      ! reference field values 
     2116      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(in)  :: pdfld_k_ref   ! harmonic averages of vertical differences of reference field 
     2117      INTEGER,  DIMENSION(A2D(nn_hls)),       INTENT(in)  :: kk_bot_ref    ! bottom levels in the reference profile 
     2118      REAL(wp), DIMENSION(A2D(nn_hls),jpk),   INTENT(OUT) :: pfld_tgt_ref  ! target minus reference on target grid          
     2119 
     2120!----------------------------------------------------------------------------------------------------------------- 
     2121      INTEGER,  DIMENSION(A2D(nn_hls),jpk) :: jk_ref_for_tgt   ! reference index for interpolation to target grid 
     2122 
     2123      INTEGER  :: ji, jj, jk                 ! DO loop indices   
     2124      INTEGER  :: jkr 
     2125      REAL(wp) :: z_r_6                      ! constant 
     2126      REAL(wp) :: zz_tgt_lcl, zz_ref_jkrm1, zz_ref_jkr, zeta, zetasq 
     2127      REAL(wp) :: zd_dif, zd_ave, zf_dif, zf_ave 
     2128      REAL(wp) :: zcoef_0, zcoef_1, zcoef_2, zcoef_3     
     2129      REAL(wp) :: zfld_ref_on_tgt 
     2130!----------------------------------------------------------------------------------------------------------------- 
     2131 
     2132      z_r_6  = 1._wp / 6._wp  
     2133 
     2134! find jk_ref_for_tgt (bounding levels on reference grid for each target point 
     2135      CALL loc_ref_tgt ( ki_off_tgt, kj_off_tgt, pdep_tgt, pz_ref, kk_bot_ref, jk_ref_for_tgt ) 
     2136 
     2137      DO_3D( 0, 0, 0, 0, 1, jpk-1 )  
     2138         zz_tgt_lcl =  - pdep_tgt( ji+ki_off_tgt, jj+kj_off_tgt, jk ) 
     2139         jkr = jk_ref_for_tgt( ji, jj, jk ) 
     2140         zz_ref_jkrm1 = pz_ref( ji, jj, jkr - 1 )    
     2141         zz_ref_jkr = pz_ref( ji, jj, jkr ) 
     2142         zeta = ( zz_tgt_lcl - 0.5_wp*(zz_ref_jkr+zz_ref_jkrm1) ) / ( zz_ref_jkr - zz_ref_jkrm1 )   
     2143         zetasq = zeta*zeta 
     2144 
     2145         zd_dif =            pdfld_k_ref(ji,jj,jkr) - pdfld_k_ref(ji,jj,jkr-1)   
     2146         zd_ave = 0.5_wp * ( pdfld_k_ref(ji,jj,jkr) + pdfld_k_ref(ji,jj,jkr-1) )    
     2147 
     2148         zf_dif =            pfld_ref(ji,jj,jkr) - pfld_ref(ji,jj,jkr-1)   
     2149         zf_ave = 0.5_wp * ( pfld_ref(ji,jj,jkr) + pfld_ref(ji,jj,jkr-1) )    
     2150 
     2151         zcoef_0 =          zf_ave - 0.125_wp * zd_dif 
     2152         zcoef_1 = 1.5_wp * zf_dif - 0.5_wp   * zd_ave 
     2153         zcoef_2 = 0.5_wp * zd_dif  
     2154         zcoef_3 = 2.0_wp * zd_ave - 2._wp    * zf_dif    
     2155     
     2156         zfld_ref_on_tgt = zcoef_0 + zeta*zcoef_1 + zetasq * ( zcoef_2 + zeta*zcoef_3 )   
     2157 
     2158! when zfld_ref_on_tgt is commented out in the next line, the results for hpg_djr should agree with those for hpg_djc.    
     2159  
     2160         pfld_tgt_ref(ji, jj, jk) = pfld_tgt(ji+ki_off_tgt, jj+kj_off_tgt, jk) - zfld_ref_on_tgt   
     2161 
     2162!         IF ( ln_dbg_hpg .AND. lwp .AND. ji == ki_dbg_cen .AND. jj == kj_dbg_cen .AND. jk == kk_dbg_cen ) THEN 
     2163!            WRITE(numout,*) ' zeta, zd_dif, zd_ave, zf_dif, zf_ave = ', zeta, zd_dif, zd_ave, zf_dif, zf_ave 
     2164!            WRITE(numout,*) ' zz_tgt_lcl, jkr, zz_ref_jkr, zz_ref_jkrm1 =', zz_tgt_lcl, jkr, zz_ref_jkr, zz_ref_jkrm1  
     2165!            WRITE(numout,*) ' pfld_ref(ji,jj,jkr), pfld_ref(ji,jj,jkr-1) = ', pfld_ref(ji,jj,jkr), pfld_ref(ji,jj,jkr-1) 
     2166!      WRITE(numout,*) ' zfld_ref_on_tgt = ', zfld_ref_on_tgt  
     2167!      WRITE(numout,*) ' pfld_tgt(ji+ki_off_tgt, jj+kj_off_tgt, jk) = ', pfld_tgt(ji+ki_off_tgt, jj+kj_off_tgt, jk) 
     2168!         END IF              
     2169       
     2170      END_3D    
     2171 
     2172      IF ( ln_dbg_hpg ) CALL dbg_3dr( 'ref_to_tgt_ccs: pfld_tgt_ref', pfld_tgt_ref )  
     2173 
     2174      RETURN         
     2175 
     2176   END SUBROUTINE ref_to_tgt_ccs 
     2177 
     2178!----------------------------------------------------------------------------------------------------------------- 
     2179 
     2180   SUBROUTINE loc_ref_tgt ( ki_off_tgt, kj_off_tgt, p_dep_tgt, p_z_ref, kk_bot_ref, kk_ref_for_tgt )  
     2181 
     2182      INTEGER,                    INTENT(in)   :: ki_off_tgt       ! offset of points in target array in i-direction    
     2183      INTEGER,                    INTENT(in)   :: kj_off_tgt       ! offset of points in target array in j-direction    
     2184      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in)   :: p_dep_tgt        ! depths of target profiles        
     2185      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in)   :: p_z_ref          ! heights of reference  profiles        
     2186      INTEGER,  DIMENSION(A2D(nn_hls)),     INTENT(in)   :: kk_bot_ref       ! bottom levels in the reference profile 
     2187      INTEGER,  DIMENSION(A2D(nn_hls),jpk), INTENT(OUT)  :: kk_ref_for_tgt   ! reference index for interpolation to target grid (the lower point) 
     2188                                                                             ! with jkr = kk_ref_for_tgt(ji,jj,jk) the reference levels are jkr-1 and jkr          
     2189!----------------------------------------------------------------------------------------------------------------- 
     2190 
     2191      INTEGER,  DIMENSION(A2D(nn_hls))             :: jk_tgt, jk_ref   ! vertical level being processed on target and reference grids respectively  
     2192 
     2193      INTEGER :: ji, jj, jk_comb, jk_bot   
     2194 
     2195      INTEGER :: jk, jkr, jcount             ! for debugging only  
     2196      REAL(wp):: z_tgt, z_below, z_above     ! for debugging only 
     2197 
     2198      INTEGER :: jk_init                  ! initial jk value for search  
     2199 
     2200      REAL(wp):: tol_wp                   ! this should be the working precision tolerance  
     2201 
     2202      tol_wp = 1.E-4                      ! the inferred bottom depth seems to be accurate to about 1.E-6.   
     2203 
     2204!----------------------------------------------------------------------------------------------------------------- 
     2205 
     2206! 1. Initialisation for search for points on reference grid bounding points on the target grid 
     2207! the first point on the target grid is assumed to lie between the first two points on the reference grid  
     2208      IF ( ln_hpg_djr_ref_ccs ) THEN 
     2209          jk_init = 2 
     2210      ELSE  
     2211          jk_init = 3      ! for simple cubic use off-centred interpolation near the surface  
     2212      END IF  
     2213 
     2214      jk_ref(:,:) = jk_init 
     2215      kk_ref_for_tgt(:,:,1) = jk_init 
     2216      jk_tgt(:,:) = 2  
     2217 
     2218! 2. Find kk_ref_for_tgt 
     2219 
     2220      DO jk_comb = 1, 2*(jpk-1)  
     2221 
     2222! if level jk_tgt in target profile is lower than jk_ref in reference profile add one to jk_ref  
     2223         DO_2D( 0, 0, 0, 0 )  
     2224            IF ( - p_dep_tgt( ji+ki_off_tgt, jj+kj_off_tgt, jk_tgt(ji,jj) ) <  p_z_ref( ji, jj, jk_ref(ji,jj) ) ) THEN  
     2225               IF ( jk_ref(ji,jj) < jpk-1 ) jk_ref(ji,jj) = jk_ref(ji,jj) + 1  
     2226            END IF   
     2227         END_2D 
     2228              
     2229! if level jk_tgt lies above or at same level as jk_ref, store jk_ref for this level and add one to jk_tgt 
     2230         DO_2D( 0, 0, 0, 0 )  
     2231            IF ( - p_dep_tgt( ji+ki_off_tgt, jj+kj_off_tgt, jk_tgt(ji,jj) ) + tol_wp > p_z_ref( ji, jj, jk_ref(ji,jj) ) ) THEN  
     2232               IF ( jk_tgt(ji,jj) < jpk ) THEN  
     2233                  kk_ref_for_tgt( ji, jj, jk_tgt(ji,jj) ) = jk_ref(ji,jj)      
     2234                  jk_tgt(ji,jj) = jk_tgt(ji,jj) + 1  
     2235               END IF  
     2236            END IF  
     2237         END_2D 
     2238 
     2239         IF ( lwp .AND. ln_dbg_hpg ) THEN  
     2240            CALL dbg_2di_k( 'jk_ref', jk_ref, jk_comb ) 
     2241            CALL dbg_2di_k( 'jk_tgt', jk_tgt, jk_comb ) 
     2242         END IF  
     2243 
     2244      END DO ! jk_comb  
     2245 
     2246       
     2247! 3. Checks to make sure we do not read or write out of bounds  
     2248 
     2249! 3.1 First test on jk_tgt to check that it reaches the bottom level mbkt  
     2250 
     2251      jcount = 0  
     2252      DO_2D(0,0,0,0)   
     2253         IF ( jk_tgt(ji,jj) <  (mbkt(ji+ki_off_tgt, jj+kj_off_tgt) + 1) ) jcount = jcount + 1  
     2254      END_2D 
     2255 
     2256      IF ( jcount > 0 ) THEN  
     2257         WRITE( numout,*) 'loc_ref_tgt: stopping because kk_ref_for_tgt will not cover all sea-points; jcount = ', jcount  
     2258         CALL ctl_stop( 'dyn_hpg_djr : kk_ref_for_tgt will not cover all sea-points' )  
     2259      END IF  
     2260 
     2261! 3.2 kk_ref_for_tgt pointing to invalid level in reference profile 
     2262 
     2263      jcount = 0  
     2264      DO_2D(0,0,0,0)   
     2265         jk_bot = mbkt(ji+ki_off_tgt, jj+kj_off_tgt)  
     2266    IF ( kk_ref_for_tgt (ji,jj,jk_bot) >  kk_bot_ref(ji,jj) ) jcount = jcount + 1   
     2267      END_2D 
     2268 
     2269      IF ( jcount > 0 ) THEN  
     2270         WRITE( numout,*) 'loc_ref_tgt: stopping because kk_ref_for_tgt points to a level below the bottom of the reference profile; jcount = ', jcount  
     2271         CALL ctl_stop( 'dyn_hpg_djr : kk_ref_for_tgt points to a level below the bottom of the reference profile' )  
     2272      END IF  
     2273 
     2274    
     2275! 3.3 diagnostic check that the right reference levels are chosen for the target profile     
     2276      IF ( lwp .AND. ln_dbg_hpg ) THEN  
     2277         WRITE( numout,*) 'loc_ref_tgt: ki_off_tgt, kj_off_tgt = ', ki_off_tgt, kj_off_tgt 
     2278         CALL dbg_3dr( '-p_dep_tgt', -p_dep_tgt )  
     2279         CALL dbg_3dr( 'p_z_ref', p_z_ref )  
     2280         CALL dbg_3di( 'kk_ref_for_tgt', kk_ref_for_tgt )  
     2281 
     2282         jcount = 0  
     2283         DO_3D(0,0,0,0,2,jpk-1)   
     2284       z_tgt = - p_dep_tgt( ji+ki_off_tgt, jj+kj_off_tgt, jk) 
     2285            jkr = kk_ref_for_tgt(ji,jj,jk) 
     2286            z_below = p_z_ref( ji, jj, jkr ) 
     2287            z_above = p_z_ref( ji, jj, jkr-1 ) 
     2288            IF ( ( z_above < z_tgt .AND. jkr > jk_init )  .OR. z_below > (z_tgt + tol_wp) ) THEN  
     2289               IF ( jcount < 10 ) THEN  
     2290                  WRITE(numout,*) 'loc_ref_tgt: ji, jj, jk, ki_off_tgt, kj_off_tgt, z_tgt, z_below, z_above '   
     2291                  WRITE(numout,*) ji, jj, jk, ki_off_tgt, kj_off_tgt, z_tgt, z_below, z_above   
     2292               END IF  
     2293               jcount = jcount + 1   
     2294            END IF  
     2295         END_3D 
     2296         WRITE(numout,*) 'loc_ref_tgt: jcount = ', jcount  
     2297      END IF  
     2298 
     2299! 3.4 Same check as in 4.2 but detailed diagnostics not written out.  
     2300      jcount = 0  
     2301      DO_3D(0,0,0,0,2,jpk-1)   
     2302    z_tgt = - p_dep_tgt( ji+ki_off_tgt, jj+kj_off_tgt, jk) 
     2303         jkr = kk_ref_for_tgt(ji,jj,jk) 
     2304         z_below = p_z_ref( ji, jj, jkr ) 
     2305         z_above = p_z_ref( ji, jj, jkr-1 ) 
     2306         IF ( ( z_above < z_tgt .AND. jkr > jk_init)  .OR. z_below > (z_tgt + tol_wp) ) THEN  
     2307            jcount = jcount + 1   
     2308         END IF  
     2309      END_3D 
     2310 
     2311      IF ( jcount > 0 ) THEN  
     2312         WRITE( numout,*) 'loc_ref_tgt: stopping because jcount is non-zero; jcount = ', jcount  
     2313         CALL ctl_stop( 'dyn_hpg_djr : loc_ref_tgt failed to locate target points correctly' ) 
     2314      END IF      
     2315       
     2316! 4. Adjust kk_ref_for_tgt so that interpolation of simple cubic is off-centred at the bottom (does not require boundary conditions)  
     2317! This assumes that every sea point has at least 4 levels.    
     2318 
     2319      IF ( .NOT. ln_hpg_djr_ref_ccs ) THEN 
     2320         DO_3D(0, 0, 0, 0, 2, jpk-1)  
     2321            IF ( kk_ref_for_tgt(ji,jj, jk) == kk_bot_ref(ji,jj) )  kk_ref_for_tgt(ji,jj, jk) = kk_ref_for_tgt(ji,jj, jk) - 1 
     2322         END_3D 
     2323      END IF  
     2324 
     2325      RETURN  
     2326 
     2327   END SUBROUTINE loc_ref_tgt 
     2328 
     2329!---------------------------------------------------------------------------- 
     2330 
     2331   SUBROUTINE hpg_ffr( kt, Kmm, puu, pvv, Krhs  ) 
     2332      !!--------------------------------------------------------------------- 
     2333      !!                  ***  ROUTINE hpg_ffr  *** 
     2334      !! 
     2335      !! ** Method  :   s-coordinate case forces on faces scheme.  
     2336      !!                Local density subtracted using cubic or constrained cubic splines (ccs)   
     2337      !!                Remaining densities interpolated to centre either linearly or with ccs   
     2338      !!                Vertical representation either using quadratic density or classic 2nd order accurate  
     2339      !! 
     2340      !! ** Action : - Update puu(..,Krhs) and pvv(..,Krhs)  with the now hydrastatic pressure trend 
     2341      !!---------------------------------------------------------------------- 
     2342      INTEGER                             , INTENT( in )  ::  kt          ! ocean time-step index 
     2343      INTEGER                             , INTENT( in )  ::  Kmm, Krhs   ! ocean time level indices 
     2344      REAL(wp), DIMENSION(jpi,jpj,jpk,jpt), INTENT(inout) ::  puu, pvv    ! ocean velocities and RHS of momentum equation 
     2345      !! 
     2346       
     2347      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   :: zrhd_ref, zdrhd_k_ref  ! densities (rhd) of reference profile 
     2348      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   :: zz_ref                 ! heights of reference profile  
     2349      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4) :: z_rhd_pmr              ! profiles minus reference    
     2350       
     2351      ! The following fields could probably be made single level or at most 2 level fields  
     2352      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4) :: z_e3t_pmr, z_depw_pmr  ! corresponding e3t and gdepw pmr profiles  
     2353      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   :: z_rhd_mid, z_e3t_mid   ! profiles and e3t interpolated to middle of cell (using ccs)   
     2354      REAL(wp), DIMENSION(A2D(nn_hls),jpk,3) :: z_ddepw_ij             ! constrained spline horizontal differences in gdepw  
     2355      REAL(wp), DIMENSION(A2D(nn_hls),jpk,3) :: z_p_pmr, z_F_pmr       ! pressures and forces on vertical faces   
     2356      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   :: z_F_upp                ! forces on upper faces 
     2357 
     2358      INTEGER,  DIMENSION(A2D(nn_hls))       :: jk_bot_ref             ! bottom level in reference profiles  
     2359      INTEGER,  DIMENSION(A2D(nn_hls),3)     :: j_mbkt                 ! bottom levels for the 3 profiles in the cell   
     2360  
     2361      REAL(wp), DIMENSION(A2D(nn_hls),jpk)   :: zpforces               ! total of forces  
     2362 
     2363      INTEGER  ::   ji, jj, jk, j_uv, jr        ! dummy loop indices 
     2364      INTEGER  ::   jio, jjo                    ! offsets for the 2 point stencil (0 or 1)   
     2365      INTEGER  ::   ji_ro, jj_ro, jr_offset     ! offsets for the reference profile  
     2366      INTEGER  ::   jn_hor_pts                  ! number of profiles required in horizontal (4 if cubic interpolarion or 2 if not)  
     2367 
     2368      REAL(wp) ::   z_r_6                       ! 1/6  
     2369      REAL(wp) ::   zr_a, zr_b, zr_c            ! rhd evaluated at i, i+1/2 and i+1   
     2370      REAL(wp) ::   za_0, za_1, za_2            ! polynomial coefficients 
     2371      !!---------------------------------------------------------------------- 
     2372 
     2373      IF( kt == nit000 ) THEN 
     2374         IF(lwp) WRITE(numout,*) 
     2375         IF(lwp) WRITE(numout,*) 'dyn:hpg_Lin : hydrostatic pressure gradient trend' 
     2376         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   s-coordinate case, forces on faces with reference removed' 
     2377      ENDIF 
     2378      ! 
     2379       
     2380      z_r_6 = 1.0_wp/6.0_wp 
     2381 
     2382      IF ( ln_hpg_ffr_hor_ccs .OR. ln_hpg_ffr_hor_cub ) THEN   
     2383         jn_hor_pts = 4 
     2384         jr_offset  = 2 
     2385      ELSE  
     2386         jn_hor_pts = 2 
     2387         jr_offset  = 1  
     2388      END IF  
     2389 
     2390!       WRITE( numout, *) ' hpg_ffr: kt, jn_hor_pts, jr_offset = ', kt, jn_hor_pts, jr_offset   
     2391 
     2392      DO j_uv = 1, 2  
     2393 
     2394         IF ( j_uv == 1 ) THEN  
     2395            jio = 1               ! set for the whole of the j_uv loop (loop ends near the bottom of the routine)  
     2396            jjo = 0  
     2397         ELSE  
     2398            jio = 0 
     2399            jjo = 1  
     2400         END IF  
     2401 
     2402! 1. Calculate the referene profile from all points in the stencil 
     2403 
     2404         IF ( ln_hpg_ffr_ref ) THEN  
     2405            CALL calc_rhd_ref(j_uv, jn_hor_pts, zrhd_ref, zz_ref, jk_bot_ref)   ! Uses rhd (IN) to calculate all other fields (OUT)   
     2406            IF ( ln_hpg_ffr_ref_ccs ) CALL calc_drhd_k(zrhd_ref, jk_bot_ref, zdrhd_k_ref)  
     2407         END IF  
     2408 
     2409         IF ( ln_dbg_hpg ) THEN  
     2410       CALL dbg_3dr( '2. rhd', rhd )  
     2411       CALL dbg_3dr( '2. gdept', gdept(:,:,:,Kmm) )  
     2412         END IF  
     2413 
     2414! 2. Interpolate reference profile to all points in the stencil and calculate z_rhd_pmr (profile minus reference) 
     2415 
     2416         DO jr = 1, jn_hor_pts        
     2417 
     2418 
     2419           IF ( j_uv == 1 ) THEN  
     2420             ji_ro = jr - jr_offset         ! range of jio: is -1 to 2 for jn_hor_pts = 4; is 0 to 1 for jn_hor_pts = 2 
     2421             jj_ro = 0  
     2422           ELSE  
     2423             ji_ro = 0 
     2424             jj_ro = jr - jr_offset  
     2425           END IF  
     2426 
     2427           IF ( ln_hpg_ffr_ref ) THEN       !!!! MJB  should gde3w below now be gdept ?? !!!!   
     2428 
     2429             IF ( ln_hpg_ffr_ref_ccs ) THEN  
     2430               CALL ref_to_tgt_ccs ( ji_ro, jj_ro, gde3w, rhd, zz_ref, zrhd_ref, zdrhd_k_ref, jk_bot_ref, z_rhd_pmr(:,:,:,jr) ) 
     2431             ELSE  
     2432               CALL ref_to_tgt_cub ( ji_ro, jj_ro, gde3w, rhd, zz_ref, zrhd_ref, jk_bot_ref, z_rhd_pmr(:,:,:,jr) )   
     2433             END IF  
     2434 
     2435           ELSE !  no subtraction of reference profile  
     2436 
     2437             DO_3D (0,0,0,0,1,jpk-1) 
     2438               z_rhd_pmr(ji,jj,jk,jr) = rhd(ji+ji_ro,jj+jj_ro,jk) 
     2439             END_3D 
     2440 
     2441           END IF ! ln_hpg_ffr_ref ) THEN  
     2442 
     2443           DO_3D (0,0,0,0,1,jpk) 
     2444               z_e3t_pmr (ji,jj,jk,jr) =   e3t(ji+ji_ro,jj+jj_ro,jk,Kmm) 
     2445               z_depw_pmr(ji,jj,jk,jr) = gdepw(ji+ji_ro,jj+jj_ro,jk,Kmm) 
     2446           END_3D 
     2447 
     2448           IF ( ln_dbg_hpg ) THEN  
     2449         CALL dbg_3dr( '2. z_rhd_pmr', z_rhd_pmr(:,:,:,jr) )  
     2450           END IF  
     2451 
     2452         END DO      
     2453 
     2454! 3. Do horizontal interpolation to form intermediate densities (either linear or cubic or constrained cubic)  
     2455!    Transfers data points from reference stencil (2 or 4 point) to a 3 point horizontal stencil 
     2456 
     2457         IF ( ln_hpg_ffr_hor_ccs .OR. ln_hpg_ffr_hor_cub) THEN   
     2458 
     2459            IF ( ln_hpg_ffr_hor_ccs ) THEN 
     2460          CALL calc_mid_ccs(j_uv, aco_bc_rhd_hor, bco_bc_rhd_hor, z_rhd_pmr, z_rhd_mid)   
     2461          CALL calc_mid_ccs(j_uv, aco_bc_z_hor,   bco_bc_z_hor,   z_e3t_pmr, z_e3t_mid)   
     2462               CALL calc_dz_dij_ccs( j_uv, z_depw_pmr, z_ddepw_ij ) 
     2463            ELSE ! ln_hpg_ffr_hor_cub 
     2464          CALL calc_mid_cub(j_uv, aco_bc_rhd_hor, bco_bc_rhd_hor, z_rhd_pmr, z_rhd_mid)   
     2465          CALL calc_mid_cub(j_uv, aco_bc_z_hor,   bco_bc_z_hor,   z_e3t_pmr, z_e3t_mid)   
     2466               CALL calc_dz_dij_cub( j_uv, z_depw_pmr, z_ddepw_ij ) 
     2467            END IF  
     2468 
     2469            DO_3D (0,0,0,0,1,jpk-1)   
     2470               z_rhd_pmr(ji,jj,jk,1) = z_rhd_pmr(ji,jj,jk,2)  
     2471               z_rhd_pmr(ji,jj,jk,2) = z_rhd_mid(ji,jj,jk) 
     2472               z_e3t_pmr(ji,jj,jk,1) = z_e3t_pmr(ji,jj,jk,2)  
     2473               z_e3t_pmr(ji,jj,jk,2) = z_e3t_mid(ji,jj,jk) 
     2474            END_3D 
     2475 
     2476         ELSE !  simple linear interpolation  
     2477 
     2478            DO_3D (0,0,0,0,1,jpk-1)   
     2479               z_rhd_pmr(ji,jj,jk,3) = z_rhd_pmr(ji,jj,jk,2)  
     2480               z_rhd_pmr(ji,jj,jk,2) = 0.5_wp*( z_rhd_pmr(ji,jj,jk,1) + z_rhd_pmr(ji,jj,jk,2) ) 
     2481            END_3D 
     2482            DO_3D (0,0,0,0,1,jpk-1)   
     2483               z_e3t_pmr(ji,jj,jk,1) =          e3t(ji, jj, jk, Kmm)     
     2484               z_e3t_pmr(ji,jj,jk,2) = 0.5_wp*( e3t(ji, jj, jk, Kmm) + e3t(ji+jio, jj+jjo, jk, Kmm)  )    
     2485               z_e3t_pmr(ji,jj,jk,3) =                                 e3t(ji+jio, jj+jjo, jk, Kmm)     
     2486            END_3D 
     2487    END IF  
     2488 
     2489    DO_2D (0,0,0,0)  
     2490            j_mbkt(ji,jj,1) = mbkt(ji, jj)  
     2491            j_mbkt(ji,jj,2) = MIN( mbkt(ji, jj), mbkt(ji+jio, jj+jjo) )  
     2492            j_mbkt(ji,jj,3) = mbkt(ji+jio, jj+jjo)  
     2493         END_2D 
     2494 
     2495         IF ( ln_dbg_hpg ) THEN  
     2496            CALL dbg_3dr( '3. e3t ',         e3t )  
     2497            CALL dbg_3dr( '3. z_rhd_pmr: 1', z_rhd_pmr(:,:,:,1) )  
     2498            CALL dbg_3dr( '3. z_rhd_pmr: 2', z_rhd_pmr(:,:,:,2) )  
     2499            CALL dbg_3dr( '3. z_rhd_pmr: 3', z_rhd_pmr(:,:,:,3) )  
     2500         END IF  
     2501 
     2502! 4. vertical interpolation of densities, calculating pressures and forces on vertical faces between w levels       
     2503 
     2504         IF ( ln_hpg_ffr_vrt_quad ) THEN  
     2505            DO jr = 1, 3  
     2506               CALL vrt_int_quad(j_mbkt(:,:,jr), z_rhd_pmr(:,:,:,jr), z_e3t_pmr(:,:,:,jr), z_p_pmr(:,:,:,jr), z_F_pmr(:,:,:,jr))  
     2507            END DO ! jr 
     2508 
     2509         ELSE  !  .NOT. ln_hpg_ffr_vrt_quad   (simplest vertical integration scheme)   
     2510 
     2511            DO jr = 1, 3  
     2512               DO_2D(0,0,0,0)  
     2513                  z_p_pmr(ji,jj,1,jr) = 0._wp  
     2514               END_2D 
     2515               DO jk = 1, jpk - 1 
     2516                  DO_2D(0,0,0,0)  
     2517                z_p_pmr(ji,jj,jk+1,jr) = z_p_pmr(ji,jj,jk,jr) + grav*z_e3t_pmr(ji,jj,jk,jr)*z_rhd_pmr(ji,jj,jk,jr) 
     2518                  END_2D 
     2519                  DO_2D(0,0,0,0)  
     2520                     z_F_pmr(ji,jj,jk,jr) = 0.5_wp*z_e3t_pmr(ji,jj,jk,jr)*( z_p_pmr(ji,jj,jk,jr) + z_p_pmr(ji,jj,jk+1,jr) )  
     2521                  END_2D 
     2522               END DO ! jk  
     2523            END DO ! jr 
     2524 
     2525         END IF  !  ln_hpg_ffr_vrt_quad    
     2526 
     2527         IF ( ln_dbg_hpg ) THEN  
     2528            CALL dbg_3dr( '4. z_p_pmr: 1', z_p_pmr(:,:,:,1) )  
     2529            CALL dbg_3dr( '4. z_p_pmr: 2', z_p_pmr(:,:,:,2) )  
     2530            CALL dbg_3dr( '4. z_p_pmr: 3', z_p_pmr(:,:,:,3) )  
     2531            CALL dbg_3dr( '4. z_F_pmr: 1', z_F_pmr(:,:,:,1) )  
     2532            CALL dbg_3dr( '4. z_F_pmr: 3', z_F_pmr(:,:,:,3) )  
     2533            CALL dbg_3dr( ' z_e3t_pmr: 1', z_e3t_pmr(:,:,:,1) ) 
     2534            CALL dbg_3dr( ' z_e3t_pmr: 2', z_e3t_pmr(:,:,:,2) ) 
     2535            CALL dbg_3dr( ' z_e3t_pmr: 3', z_e3t_pmr(:,:,:,3) ) 
     2536         END IF  
     2537 
     2538 
     2539! 5. Calculate forces on the upper faces and hence on the total forces on the cells (zpforces)   
     2540 
     2541         DO_2D(0,0,0,0)  
     2542            z_F_upp(ji,jj,1) = 0._wp 
     2543         END_2D  
     2544 
     2545         IF ( ln_hpg_ffr_hor_ccs .OR. ln_hpg_ffr_hor_cub ) THEN     ! use Simpson's rule  
     2546            DO_3D(0,0,0,0,2,jpk)  
     2547               z_F_upp(ji,jj,jk) = - z_r_6 * (         z_ddepw_ij(ji,jj,jk,1)*z_p_pmr(ji,jj,jk,1)                              &  
     2548     &                                    + 4._wp*z_ddepw_ij(ji,jj,jk,2)*z_p_pmr(ji,jj,jk,2)                              &  
     2549          &                                    +       z_ddepw_ij(ji,jj,jk,3)*z_p_pmr(ji,jj,jk,3)  )    
     2550            END_3D 
     2551         ELSE                               ! use trapezoidal rule  
     2552            DO_3D(0,0,0,0,2,jpk)  
     2553               z_F_upp(ji,jj,jk) = 0.5_wp * ( gdepw(ji,jj,jk,Kmm) - gdepw(ji+jio,jj+jjo,jk,Kmm) ) * ( z_p_pmr(ji,jj,jk,1) + z_p_pmr(ji,jj,jk,3) ) 
     2554     &                                 
     2555            END_3D 
     2556         END IF  
     2557     
     2558         IF ( ln_dbg_hpg ) THEN  
     2559            CALL dbg_3dr( '4. z_F_upp: ', z_F_upp )  
     2560            CALL dbg_3dr( '4. gdepw: ', gdepw )  
     2561            CALL dbg_3dr( '4. z_ddepw_ij 1: ', z_ddepw_ij(:,:,:,1) )  
     2562            CALL dbg_3dr( '4. z_ddepw_ij 2: ', z_ddepw_ij(:,:,:,2) )  
     2563            CALL dbg_3dr( '4. z_ddepw_ij 3: ', z_ddepw_ij(:,:,:,3) )  
     2564 
     2565         END IF  
     2566 
     2567         IF ( j_uv == 1 ) THEN  
     2568            DO_3D(0,0,0,0,1,jpk-1) 
     2569               zpforces(ji,jj,jk)  = z_F_pmr(ji,jj,jk,1) - z_F_pmr(ji,jj,jk,3) + z_F_upp(ji,jj,jk) - z_F_upp(ji,jj,jk+1)  
     2570               puu(ji,jj,jk,Krhs) = puu(ji,jj,jk,Krhs) + zpforces(ji,jj,jk) / (e1u(ji,jj)*e3u(ji,jj,jk,Kmm))  
     2571            END_3D 
     2572            IF ( ln_dbg_hpg ) CALL dbg_3dr( '5. u zpforces: ', zpforces )  
     2573 
     2574          ELSE  
     2575            DO_3D(0,0,0,0,1,jpk-1) 
     2576               zpforces(ji,jj,jk) = z_F_pmr(ji,jj,jk,1) - z_F_pmr(ji,jj,jk,3) + z_F_upp(ji,jj,jk) - z_F_upp(ji,jj,jk+1)  
     2577               pvv(ji,jj,jk,Krhs) = pvv(ji,jj,jk,Krhs) + zpforces(ji,jj,jk) / (e1v(ji,jj)*e3v(ji,jj,jk,Kmm))    
     2578            END_3D 
     2579            IF ( ln_dbg_hpg ) CALL dbg_3dr( '5. v zpforces: ', zpforces )  
     2580          END IF  
     2581 
     2582! temporary output of fields for debugging etc.  
     2583          IF ( j_uv == 1) THEN  
     2584             CALL iom_put( "gdepw_hpg", gdepw(:,:,:,Kmm) ) 
     2585             CALL iom_put( "rhd_hpg", rhd ) 
     2586             CALL iom_put( "pressure",  z_p_pmr(:,:,:,1) ) 
     2587             CALL iom_put( "u_force_west", z_F_pmr(:,:,:,1) ) 
     2588             CALL iom_put( "u_force_upper", z_F_upp ) 
     2589          ELSE  
     2590             CALL iom_put( "v_force_south", z_F_pmr(:,:,:,1) ) 
     2591             CALL iom_put( "v_force_upper", z_F_upp ) 
     2592          END IF  
     2593 
     2594      END DO  ! j_uv   
     2595      ! 
     2596   END SUBROUTINE hpg_ffr 
     2597 
     2598!------------------------------------------------------------------------------------------ 
     2599    
     2600   SUBROUTINE calc_rhd_ref (k_uv, kn_hor, prhd_ref, pz_ref, kk_bot_ref)  
     2601 
     2602      !!--------------------------------------------------------------------- 
     2603      !!                  ***  ROUTINE calc_rhd_ref  *** 
     2604      !! 
     2605      !! ** Method  :   Find the deepest cell within the stencil.  
     2606      !!                (Later will extend to producing a reference profile that spans the highest and lowest points in the stencil)    
     2607      !!                  
     2608      !!                  
     2609      !! 
     2610      !! ** Action : -  Set prhd_ref, pz_ref, kk_bot_ref 
     2611      !!---------------------------------------------------------------------- 
     2612      INTEGER                             , INTENT( in )  ::  k_uv        ! 1 for u-vel; 2 for v_vel 
     2613      INTEGER                             , INTENT( in )  ::  kn_hor      ! 4 for cubic; 2 for linear 
     2614 
     2615      REAL(wp), DIMENSION(:,:,:), INTENT(out) ::  prhd_ref   ! densities    of reference profile 
     2616      REAL(wp), DIMENSION(:,:,:), INTENT(out) ::  pz_ref     ! heights      of   "         "  
     2617      INTEGER,  DIMENSION(:,:),   INTENT(out) ::  kk_bot_ref ! bottom level of   "         "  
     2618 
     2619      INTEGER,  DIMENSION(A2D(nn_hls))     :: ji_ref, jj_ref       
     2620 
     2621      INTEGER  ji, jj, jk    ! standard loop indices 
     2622      INTEGER  jio, jjo      ! offsets  
     2623      INTEGER  jib, jjb      ! second set of indices to deeper points  
     2624      INTEGER  jir, jjr      ! indices of reference profile   
     2625      REAL(wp) zhta, zhtb 
     2626 
     2627   IF (k_uv == 1) THEN 
     2628      jio = 1 
     2629      jjo = 0  
     2630   ELSE  
     2631      jio = 0  
     2632      jjo = 1 
     2633   END IF  
     2634 
     2635 
     2636   DO_2D( 0, 0, 0, 0 )  
     2637 
     2638      IF ( ht_0(ji+jio,jj+jjo) >= ht_0(ji,jj) ) THEN   
     2639         zhta = ht_0(ji+jio,jj+jjo)  
     2640         ji_ref(ji,jj) = ji+jio 
     2641         jj_ref(ji,jj) = jj+jjo 
     2642      ELSE  
     2643         zhta = ht_0(ji,jj)  
     2644         ji_ref(ji,jj) = ji 
     2645         jj_ref(ji,jj) = jj 
     2646      END IF  
     2647       
     2648      IF ( kn_hor == 4 ) THEN  
     2649         IF ( ht_0(ji-jio,jj-jjo) >= ht_0(ji+2*jio,jj+2*jjo) ) THEN   
     2650            zhtb = ht_0(ji-jio,jj-jjo)  
     2651            jib = ji-jio 
     2652            jjb = jj-jjo 
     2653         ELSE  
     2654            zhtb = ht_0(ji+2*jio,jj+2*jjo)  
     2655            jib = ji+2*jio 
     2656            jjb = jj+2*jjo 
     2657         END IF 
     2658         IF ( zhta < zhtb ) THEN   
     2659            ji_ref(ji,jj) = jib  
     2660            jj_ref(ji,jj) = jjb  
     2661         END IF 
     2662      END IF  
     2663 
     2664   END_2D  
     2665 
     2666   DO_3D( 0, 0, 0, 0, 1, jpk-1)  
     2667      jir = ji_ref(ji,jj)  
     2668      jjr = jj_ref(ji,jj)  
     2669      prhd_ref (ji,jj,jk) =     rhd(jir, jjr, jk)  
     2670      pz_ref   (ji,jj,jk) = - gde3w(jir, jjr, jk)  
     2671   END_3D  
     2672 
     2673   DO_2D( 0, 0, 0, 0)  
     2674      jir = ji_ref(ji,jj)  
     2675      jjr = jj_ref(ji,jj)  
     2676      kk_bot_ref(ji,jj) = mbkt(jir,jjr) 
     2677   END_2D 
     2678 
     2679   END SUBROUTINE calc_rhd_ref 
     2680 
     2681!------------------------------------------------------------------------------------------ 
     2682    
     2683   SUBROUTINE calc_drhd_k(p_rhd, kk_bot, p_drhd_k)  
     2684 
     2685      !!--------------------------------------------------------------------- 
     2686      !!                  ***  ROUTINE calc_drhd_k  *** 
     2687      !! 
     2688      !! ** Method  :  Calculate harmonic averages of vertical differences and apply upper and lower boundary conditions  
     2689      !!                   
     2690      !! ** Action : - Set p_drhd_k 
     2691      !!---------------------------------------------------------------------- 
     2692 
     2693      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in)  ::  p_rhd    ! densities    of profile 
     2694      INTEGER,  DIMENSION(A2D(nn_hls)),     INTENT(in)  ::  kk_bot   ! bottom level of profile 
     2695      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(out) ::  p_drhd_k ! harmonic mean of vertical differences of profile 
     2696 
     2697      INTEGER  ji, jj, jk    ! standard loop indices 
     2698      INTEGER  jio, jjo      ! offsets  
     2699      INTEGER  iktb          ! index of the bottom of ref profile 
     2700      REAL(wp), DIMENSION(A2D(nn_hls),jpk)  ::  ztmp     ! primitive vertical differences  
     2701 
     2702      REAL(wp) cffw, z1_cff, zep 
     2703 
     2704      DO_3D( 0, 0, 0, 0, 2, jpk )   
     2705          ztmp(ji,jj,jk) = p_rhd(ji,jj,jk) - p_rhd(ji,jj,jk-1) 
     2706      END_3D 
     2707 
     2708      zep = 1.e-15 
     2709      DO_3D( 0, 0, 0, 0, 2, jpkm1 )  
     2710         cffw = MAX( 2._wp * ztmp(ji,jj,jk) * ztmp(ji,jj,jk+1), 0._wp ) 
     2711         z1_cff = ztmp(ji,jj,jk) + ztmp(ji,jj,jk+1)  
     2712         p_drhd_k(ji,jj,jk) = cffw / SIGN( MAX( ABS(z1_cff), zep ), z1_cff ) 
     2713      END_3D 
     2714 
     2715      DO_2D( 0, 0, 0, 0 ) 
     2716         p_drhd_k(ji,jj,1) = aco_bc_rhd_srf * ( p_rhd(ji,jj,2) - p_rhd(ji,jj,1) ) - bco_bc_rhd_srf * p_drhd_k(ji,jj,2) 
     2717         iktb = kk_bot(ji,jj)   
     2718         IF ( iktb > 1 ) THEN 
     2719            p_drhd_k(ji,jj,iktb) = aco_bc_rhd_bot * (p_rhd(ji,jj,iktb) - p_rhd(ji,jj,iktb-1) ) - bco_bc_rhd_bot * p_drhd_k(ji,jj,iktb-1) 
     2720         END IF 
     2721      END_2D 
     2722 
     2723   END SUBROUTINE calc_drhd_k 
     2724 
     2725!---------------------------------------------------------------------------- 
     2726  
     2727   SUBROUTINE calc_mid_ccs( k_uv, p_aco_bc_fld_hor, p_bco_bc_fld_hor, p_fld_pmr, p_fld_mid )  
     2728 
     2729      !!--------------------------------------------------------------------- 
     2730      !!                  ***  ROUTINE calc_mid_ccs  *** 
     2731      !! 
     2732      !! ** Method  :   Use constrained cubic spline to interpolate 4 profiles to their central point   
     2733      !!                This version can only be used to interpolate fields on tracer levels (not w-levels) 
     2734      !!                   
     2735      !! ** Action : - set p_fld_mid  
     2736      !!---------------------------------------------------------------------- 
     2737 
     2738      INTEGER                               , INTENT(in)  :: k_uv             ! 1 for u-vel; 2 for v_vel 
     2739      REAL(wp)                              , INTENT(in)  :: p_aco_bc_fld_hor ! a coeff for horizontal bc (von Neumann or linear extrapolation) 
     2740      REAL(wp)                              , INTENT(in)  :: p_bco_bc_fld_hor ! b coeff for horizontal bc (von Neumann or linear extrapolation) 
     2741      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4), INTENT(in)  :: p_fld_pmr        ! field in pmr form 
     2742      REAL(wp), DIMENSION(A2D(nn_hls),jpk)  , INTENT(out) :: p_fld_mid        ! field at mid-point 
     2743 
     2744      REAL(wp), DIMENSION(A2D(nn_hls),jpk,3) :: zz_dfld_ij    ! constrained spline horizontal differences (dimension 3 for consistency with calc_dfld_cen_dij) 
     2745 
     2746      INTEGER  ji, jj, jk    ! standard loop indices 
     2747      INTEGER  ::   j_t_levs ! indicator that field passed is on tracer levels  
     2748              
     2749         j_t_levs =  1 
     2750 
     2751         DO jk = 1, jpk   
     2752 
     2753            CALL calc_dfld_pmr_ij( k_uv, j_t_levs, jk, p_aco_bc_fld_hor, p_bco_bc_fld_hor, p_fld_pmr, zz_dfld_ij )   
     2754 
     2755! first contribution is simple centred average; p_rhd_pmr has 4 points; 2 and 3 are the central ones  
     2756            DO_2D( 0, 0, 0, 0)        
     2757                p_fld_mid(ji,jj,jk) =     0.5_wp * ( p_fld_pmr(ji,jj,jk,2) + p_fld_pmr(ji,jj,jk,3) )   
     2758            END_2D  
     2759 
     2760            IF ( k_uv == 1 ) THEN  
     2761               DO_2D( 0, 0, 0, 0)        
     2762                  IF ( umask(ji-1, jj, jk) > 0.5 .OR. umask(ji+1, jj, jk) > 0.5 ) THEN 
     2763                     p_fld_mid(ji,jj,jk) = p_fld_mid(ji,jj,jk) - 0.125_wp * ( zz_dfld_ij(ji,jj,jk,2) - zz_dfld_ij(ji,jj,jk,1) ) 
     2764                  END IF        
     2765               END_2D  
     2766            ELSE !  k_uv == 2  
     2767               DO_2D( 0, 0, 0, 0)        
     2768                  IF ( vmask(ji, jj-1, jk) > 0.5 .OR. vmask(ji, jj+1, jk) > 0.5 ) THEN 
     2769                     p_fld_mid(ji,jj,jk) = p_fld_mid(ji,jj,jk) - 0.125_wp * ( zz_dfld_ij(ji,jj,jk,2) - zz_dfld_ij(ji,jj,jk,1) ) 
     2770                  END IF        
     2771               END_2D  
     2772            END IF ! k_uv   
     2773 
     2774    END DO  ! jk  
     2775 
     2776   END SUBROUTINE calc_mid_ccs 
     2777 
     2778!---------------------------------------------------------------------------- 
     2779  
     2780   SUBROUTINE calc_mid_cub( k_uv, p_aco_bc_fld_hor, p_bco_bc_fld_hor, p_fld_pmr, p_fld_mid )  
     2781 
     2782      !!--------------------------------------------------------------------- 
     2783      !!                  ***  ROUTINE calc_mid_cub  *** 
     2784      !! 
     2785      !! ** Method  :   Use simple cubic polynomial to interpolate 4 profiles to their central point   
     2786      !!                The coefficients p_aco_bc_fld_hor, p_bco_bc_fld_hor are not currently used.   
     2787      !!                The simplest form of von Neumann conditions horizontal bc is used (one could off-centred polynomials)    
     2788      !! ** Action : - set p_fld_mid  
     2789      !!---------------------------------------------------------------------- 
     2790 
     2791      INTEGER                               , INTENT(in)  :: k_uv             ! 1 for u-vel; 2 for v_vel 
     2792      REAL(wp)                              , INTENT(in)  :: p_aco_bc_fld_hor ! a coeff for horizontal bc (von Neumann or linear extrapolation) 
     2793      REAL(wp)                              , INTENT(in)  :: p_bco_bc_fld_hor ! b coeff for horizontal bc (von Neumann or linear extrapolation) 
     2794      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4), INTENT(inout)  :: p_fld_pmr        ! field in pmr form 
     2795      REAL(wp), DIMENSION(A2D(nn_hls),jpk)  , INTENT(out) :: p_fld_mid        ! field at mid-point 
     2796 
     2797      REAL(wp), DIMENSION(A2D(nn_hls))   :: zdfld_21, zdfld_32, zdfld_43  ! primitive horizontal differences  
     2798      REAL(wp), DIMENSION(A2D(nn_hls),3) :: zz_dfld_ij                    ! constrained spline horizontal differences (dimension 3 for consistency with calc_dfld_cen_dij) 
     2799 
     2800      INTEGER  ji, jj, jk       ! standard loop indices 
     2801      REAL(wp) z_1_16, z_9_16   ! temporary sum and products 
     2802      REAL(wp) z_cor            ! correction to the central value   
     2803 
     2804         z_1_16 = 1._wp / 16._wp   ;    z_9_16 = 9._wp / 16._wp         
     2805 
     2806         DO jk = 1, jpk  
     2807 
     2808! first contribution is simple centred average plus 1/16 of it; p_rhd_pmr has 4 points; 2 and 3 are the central ones  
     2809            DO_2D( 0, 0, 0, 0)        
     2810                p_fld_mid(ji,jj,jk) =  z_9_16 * ( p_fld_pmr(ji,jj,jk,2) + p_fld_pmr(ji,jj,jk,3) )   
     2811            END_2D  
     2812 
     2813            IF ( k_uv == 1 ) THEN  
     2814               DO_2D( 0, 0, 0, 0)        
     2815                  IF ( umask(ji-1, jj, jk) > 0.5  ) THEN 
     2816                     z_cor = p_fld_pmr(ji,jj,jk,1) 
     2817                  ELSE       
     2818                     z_cor = p_fld_pmr(ji,jj,jk,2) 
     2819                  END IF        
     2820                  IF ( umask(ji+1, jj, jk) > 0.5  ) THEN 
     2821                     z_cor = z_cor + p_fld_pmr(ji,jj,jk,4) 
     2822                  ELSE       
     2823                     z_cor = z_cor + p_fld_pmr(ji,jj,jk,3) 
     2824                  END IF        
     2825                  p_fld_mid(ji,jj,jk) = p_fld_mid(ji,jj,jk) - z_1_16 * z_cor 
     2826               END_2D  
     2827            ELSE !  k_uv == 2  
     2828               DO_2D( 0, 0, 0, 0)        
     2829                  IF ( vmask(ji, jj-1, jk) > 0.5 ) THEN   
     2830                     z_cor = p_fld_pmr(ji,jj,jk,1) 
     2831                  ELSE       
     2832                     z_cor = p_fld_pmr(ji,jj,jk,2) 
     2833                  END IF        
     2834                  IF ( vmask(ji, jj+1, jk) > 0.5  ) THEN 
     2835                     z_cor = z_cor + p_fld_pmr(ji,jj,jk,4) 
     2836                  ELSE       
     2837                     z_cor = z_cor + p_fld_pmr(ji,jj,jk,3) 
     2838                  END IF        
     2839                  p_fld_mid(ji,jj,jk) = p_fld_mid(ji,jj,jk) - z_1_16 * z_cor 
     2840               END_2D  
     2841            END IF ! k_uv   
     2842 
     2843    END DO  ! jk  
     2844 
     2845   END SUBROUTINE calc_mid_cub 
     2846 
     2847!---------------------------------------------------------------------------- 
     2848  
     2849   SUBROUTINE calc_dz_dij_ccs( k_uv, p_z_pmr, p_dz_ij )  
     2850 
     2851      !!--------------------------------------------------------------------- 
     2852      !!                  ***  ROUTINE calc_dz_dij_ccs  *** 
     2853      !! 
     2854      !! ** Method  :   Use constrained cubic spline to determine horizontal derivatives of z at 3 central points    
     2855      !!                The routine is limited to z derivatives because the output is valid on w-levels       
     2856      !! ** Action : - set p_dz_ij  
     2857      !!---------------------------------------------------------------------- 
     2858 
     2859      INTEGER                               , INTENT(in)  :: k_uv             ! 1 for u-vel; 2 for v_vel 
     2860      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4), INTENT(in)  :: p_z_pmr          ! z field in pmr form 
     2861      REAL(wp), DIMENSION(A2D(nn_hls),jpk,3), INTENT(out) :: p_dz_ij          ! constrained cubic horizontal derivatives at -1/2, 0 and 1/2 
     2862 
     2863      REAL(wp), DIMENSION(A2D(nn_hls))   :: zdfld_21, zdfld_32, zdfld_43  ! primitive horizontal differences  
     2864 
     2865      INTEGER  ji, jj, jk    ! standard loop indices 
     2866      INTEGER  jk_msk                                        ! jk level to use for umask and vmask (we need z on the upper and lower faces)   
     2867      INTEGER  j_w_levs      ! indicator for data on w-levels    
     2868 
     2869         j_w_levs = 2  
     2870                
     2871         DO jk = 1, jpk  
     2872 
     2873            CALL calc_dfld_pmr_ij( k_uv, j_w_levs, jk, aco_bc_z_hor, bco_bc_z_hor, p_z_pmr, p_dz_ij )   
     2874 
     2875! copy the 2nd horizontal element to the 3rd element of the output array (for an isolated velocity cell p_dz_ij is the same for all 3 elements)  
     2876            DO_2D( 0, 0, 0, 0)        
     2877                p_dz_ij(ji,jj,jk,3) = p_dz_ij(ji,jj,jk,2)       
     2878            END_2D  
     2879 
     2880! set the central element if it is not an isolated velocity cell; this evaluates dz_dij at zeta = 0 ; that is f^{(1)}; and that is given by SMcW(5.8)   
     2881            IF ( jk == 1 ) THEN  
     2882               jk_msk = 1 
     2883       ELSE  
     2884          jk_msk = jk - 1  
     2885            END IF  
     2886 
     2887            IF ( k_uv == 1 ) THEN  
     2888               DO_2D( 0, 0, 0, 0)        
     2889                  IF ( umask(ji-1, jj, jk_msk) > 0.5 .OR. umask(ji+1, jj, jk_msk) > 0.5 ) THEN 
     2890                     p_dz_ij(ji,jj,jk,2) = 1.5_wp*( p_z_pmr(ji,jj,jk,3) - p_z_pmr(ji,jj,jk,2) ) - 0.25_wp * ( p_dz_ij(ji,jj,jk,3) + p_dz_ij(ji,jj,jk,1) ) 
     2891                  END IF        
     2892               END_2D  
     2893            ELSE !  k_uv == 2  
     2894               DO_2D( 0, 0, 0, 0)        
     2895                  IF ( vmask(ji, jj-1, jk_msk) > 0.5 .OR. vmask(ji, jj+1, jk_msk) > 0.5 ) THEN 
     2896                     p_dz_ij(ji,jj,jk,2) = 1.5_wp*( p_z_pmr(ji,jj,jk,3) - p_z_pmr(ji,jj,jk,2) ) - 0.25_wp * ( p_dz_ij(ji,jj,jk,3) + p_dz_ij(ji,jj,jk,1) ) 
     2897                  END IF        
     2898               END_2D  
     2899            END IF ! k_uv   
     2900          
     2901    END DO  ! jk  
     2902 
     2903   END SUBROUTINE calc_dz_dij_ccs 
     2904 
     2905!---------------------------------------------------------------------------- 
     2906  
     2907   SUBROUTINE calc_dz_dij_cub( k_uv, p_z_pmr, p_dz_ij )  
     2908 
     2909      !!--------------------------------------------------------------------- 
     2910      !!                  ***  ROUTINE calc_dz_dij_cub  *** 
     2911      !! 
     2912      !! ** Method  :   Use simple cubic polynomial to determine horizontal derivatives at 3 central points    
     2913      !!                based on equations (5.5) and (5.6) of SMcW 2003  
     2914      !!                The routine is limited to z derivatives because the output is valid on w-levels       
     2915      !! ** Action : - set p_dz_ij  
     2916      !!---------------------------------------------------------------------- 
     2917 
     2918      INTEGER                               , INTENT(in)  :: k_uv             ! 1 for u-vel; 2 for v_vel 
     2919      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4), INTENT(in)  :: p_z_pmr          ! z field in pmr form 
     2920      REAL(wp), DIMENSION(A2D(nn_hls),jpk,3), INTENT(out) :: p_dz_ij          ! horizontal derivatives at -1/2, 0 and 1/2 
     2921 
     2922      REAL(wp), DIMENSION(A2D(nn_hls)) :: z_z_a, z_z_d       ! z fields with boundary conditions applied  
     2923      REAL(wp) z_1_24                                        ! 1/24  
     2924      REAL(wp) z_a, z_b, z_c, z_d                            ! values of input field at the four points used (-3/2, -1/2, 1/2, 3/2)  
     2925      REAL(wp) z_c_m_b, z_d_m_a                              ! differences c - b   and d - a   
     2926      REAL(wp) z_co_1, z_co_2, z_co_3                        ! coefficients of polynomial (field = z_co_0 + z_co_1 zeta + .. )  
     2927      INTEGER  ji, jj, jk                                    ! standard loop indices 
     2928      INTEGER  jk_msk                                        ! jk level to use for umask and vmask (we need z on the upper and lower faces)   
     2929 
     2930         z_1_24 = 1.0_wp / 24.0_wp  
     2931        
     2932         DO jk = 1, jpk  
     2933 
     2934!------------------------------------------------------ 
     2935! 1. Use simple von Neumann conditions at the boundaries   
     2936!------------------------------------------------------ 
     2937            IF ( jk == 1 ) THEN  
     2938               jk_msk = 1 
     2939       ELSE  
     2940          jk_msk = jk - 1  
     2941            END IF  
     2942 
     2943            IF ( k_uv == 1 ) THEN  
     2944               DO_2D( 0, 0, 0, 0)        
     2945                  IF ( umask(ji-1, jj, jk_msk) > 0.5  ) THEN 
     2946                     z_z_a(ji,jj) = p_z_pmr(ji,jj,jk,1) 
     2947                  ELSE       
     2948                     z_z_a(ji,jj) = p_z_pmr(ji,jj,jk,2) 
     2949                  END IF        
     2950                  IF ( umask(ji+1, jj, jk_msk) > 0.5  ) THEN 
     2951                     z_z_d(ji,jj) = p_z_pmr(ji,jj,jk,4) 
     2952                  ELSE       
     2953                     z_z_d(ji,jj) = p_z_pmr(ji,jj,jk,3) 
     2954                  END IF        
     2955               END_2D  
     2956            ELSE !  k_uv == 2  
     2957               DO_2D( 0, 0, 0, 0)        
     2958                  IF ( vmask(ji, jj-1, jk_msk) > 0.5 ) THEN   
     2959                     z_z_a(ji,jj) = p_z_pmr(ji,jj,jk,1) 
     2960                  ELSE       
     2961                     z_z_a(ji,jj) = p_z_pmr(ji,jj,jk,2) 
     2962                  END IF        
     2963                  IF ( vmask(ji, jj+1, jk_msk) > 0.5  ) THEN 
     2964                     z_z_d(ji,jj) = p_z_pmr(ji,jj,jk,4) 
     2965                  ELSE       
     2966                     z_z_d(ji,jj) = p_z_pmr(ji,jj,jk,3) 
     2967                  END IF        
     2968               END_2D  
     2969            END IF ! k_uv   
     2970 
     2971!------------------------------------------------------ 
     2972! 2. calculate the coefficients for the polynomial fit (c_1, c_2 and c_3; we don't need c_0)   
     2973!------------------------------------------------------ 
     2974 
     2975            DO_2D( 0, 0, 0, 0)        
     2976                z_a = z_z_a(ji,jj)       
     2977                z_b = p_z_pmr(ji,jj,jk,2) 
     2978                z_c = p_z_pmr(ji,jj,jk,3)  
     2979                z_d = z_z_d(ji,jj)       
     2980 
     2981                z_c_m_b = z_c - z_b    ;   z_d_m_a = z_d - z_a  
     2982 
     2983! eqn (5.6) of SMcW 
     2984                z_co_1 = 1.125_wp *  z_c_m_b  - z_1_24 *  z_d_m_a  
     2985                z_co_2 =  -0.5_wp * (z_c+z_b) + 0.5_wp * (z_d+z_a)  
     2986                z_co_3 =  -3.0_wp *  z_c_m_b  +           z_d_m_a  
     2987 
     2988! eqn (5.5) of SMcW (first derivative of it)  
     2989                p_dz_ij(ji,jj,jk,1) = z_co_1 - 0.5_wp*z_co_2 + 0.125_wp*z_co_3   ! zeta = -0.5 
     2990                p_dz_ij(ji,jj,jk,2) = z_co_1                                     ! zeta =  0.0 
     2991                p_dz_ij(ji,jj,jk,3) = z_co_1 + 0.5_wp*z_co_2 + 0.125_wp*z_co_3   ! zeta =  0.5 
     2992 
     2993            END_2D  
     2994 
     2995    END DO  ! jk  
     2996 
     2997   END SUBROUTINE calc_dz_dij_cub 
     2998 
     2999!---------------------------------------------------------------------------- 
     3000  
     3001   SUBROUTINE calc_dfld_pmr_ij( k_uv, k_lev_type, kk, p_aco_bc_fld_hor, p_bco_bc_fld_hor, p_fld_pmr, p_dfld_ij )  
     3002 
     3003      !!--------------------------------------------------------------------- 
     3004      !!                  ***  ROUTINE calc_dfld_pmr_ij  *** 
     3005      !! 
     3006      !! ** Method  :   Calculate constrained spline horizontal derivatives    
     3007      !!                   
     3008      !! ** Action : - set p_dfld_ij  
     3009      !!---------------------------------------------------------------------- 
     3010 
     3011      INTEGER                               , INTENT(in)  :: k_uv             ! 1 for u-vel; 2 for v_vel 
     3012      INTEGER                               , INTENT(in)  :: k_lev_type       ! 1 for t-level data; 2 for w-level data; used with check of land/sea mask 
     3013      INTEGER                               , INTENT(in)  :: kk               ! vertical level 
     3014      REAL(wp)                              , INTENT(in)  :: p_aco_bc_fld_hor ! a coeff for horizontal bc (von Neumann or linear extrapolation) 
     3015      REAL(wp)                              , INTENT(in)  :: p_bco_bc_fld_hor ! b coeff for horizontal bc (von Neumann or linear extrapolation) 
     3016      REAL(wp), DIMENSION(A2D(nn_hls),jpk,4), INTENT(in)  :: p_fld_pmr        ! field in pmr form 
     3017      REAL(wp), DIMENSION(A2D(nn_hls),jpk,3), INTENT(out) :: p_dfld_ij        ! constrained spline horizontal derivatives of the field; only 1 and 2 are set!   
     3018 
     3019      REAL(wp), DIMENSION(A2D(nn_hls))   :: zdfld_21, zdfld_32, zdfld_43  ! primitive horizontal differences  
     3020 
     3021      INTEGER  ji, jj        ! standard loop indices 
     3022      INTEGER  jio, jjo      ! offsets  
     3023      INTEGER  iktb          ! index of the bottom of ref profile 
     3024 
     3025      REAL(wp) z1_cff, z_cff_31, z_cff_42  ! temporary sum and products 
     3026      REAL(wp) zep 
     3027 
     3028      INTEGER  ::   j_t_levs, jk_msk     ! indicators that field passed in is valid on t-levels or w-levels; jk to use with masks  
     3029        
     3030         j_t_levs =  1 
     3031        
     3032      !---------------------------------------------------------------------------------------- 
     3033      !  1. compute and store elementary horizontal differences zfor z_rhd_pmr arrays  
     3034      !---------------------------------------------------------------------------------------- 
     3035  
     3036         IF ( k_uv == 1) THEN  
     3037            jio = 1 
     3038            jjo = 0  
     3039         ELSE  
     3040            jio = 0  
     3041            jjo = 1 
     3042         END IF  
     3043 
     3044         IF ( k_lev_type == j_t_levs ) THEN  
     3045       jk_msk = kk  
     3046         ELSE  
     3047            IF ( kk == 1 ) THEN  
     3048               jk_msk = 1 
     3049       ELSE  
     3050          jk_msk = kk - 1  
     3051            END IF  
     3052         END IF 
     3053 
     3054         DO_2D( 0, 0, 0, 0 ) 
     3055            zdfld_21(ji,jj) =   p_fld_pmr(ji,jj,kk,2) - p_fld_pmr(ji,jj,kk,1) 
     3056            zdfld_32(ji,jj) =   p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) 
     3057            zdfld_43(ji,jj) =   p_fld_pmr(ji,jj,kk,4) - p_fld_pmr(ji,jj,kk,3) 
     3058         END_2D 
     3059 
     3060         zep = 1.e-15 
     3061         DO_2D( 0, 0, 0, 0 ) 
     3062            z_cff_31 = MAX( 2._wp * zdfld_21(ji,jj) * zdfld_32(ji,jj), 0._wp )  
     3063            z1_cff = zdfld_21(ji,jj) + zdfld_32(ji,jj) 
     3064            p_dfld_ij(ji,jj,kk,1) = z_cff_31 / SIGN( MAX( ABS(z1_cff), zep ), z1_cff ) 
     3065 
     3066            z_cff_42 = MAX( 2._wp * zdfld_32(ji,jj) * zdfld_43(ji,jj), 0._wp )  
     3067            z1_cff = zdfld_32(ji,jj) + zdfld_43(ji,jj) 
     3068            p_dfld_ij(ji,jj,kk,2) = z_cff_42 / SIGN( MAX( ABS(z1_cff), zep ), z1_cff )  
     3069         END_2D 
     3070 
     3071      !---------------------------------------------------------------------------------- 
     3072      ! 2. apply boundary conditions at side boundaries using 5.36-5.37     
     3073      !---------------------------------------------------------------------------------- 
     3074 
     3075         IF ( k_uv == 1 ) THEN  
     3076            DO_2D( 0, 0, 0, 0)        
     3077            ! Walls coming from left: should check from 2 to jpi-1 (and jpj=2-jpj) 
     3078               IF ( umask(ji,jj,jk_msk) > 0.5_wp .AND. umask(ji-1,jj,jk_msk) < 0.5_wp .AND. umask(ji+1,jj,jk_msk) > 0.5_wp)  THEN   
     3079                  p_dfld_ij(ji,jj,kk,1) = p_aco_bc_fld_hor * ( p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) ) - p_bco_bc_fld_hor * p_dfld_ij(ji,jj,kk,2)  
     3080               END IF 
     3081            ! Walls coming from right: should check from 3 to jpi (and jpj=2-jpj) 
     3082               IF ( umask(ji,jj,jk_msk) < 0.5_wp .AND. umask(ji-1,jj,jk_msk) > 0.5_wp .AND. umask(ji-2,jj,jk_msk) > 0.5_wp) THEN 
     3083                  p_dfld_ij(ji,jj,kk,2) = p_aco_bc_fld_hor * ( p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) ) - p_bco_bc_fld_hor * p_dfld_ij(ji,jj,kk,1)   
     3084               END IF 
     3085            END_2D  
     3086 
     3087            DO_2D( 0, 0, 0, 0)        
     3088            ! For an isolated velocity point use the central difference (this is important)  
     3089               IF ( umask(ji-1, jj, jk_msk) < 0.5 .AND. umask(ji+1, jj, jk_msk) < 0.5 ) THEN 
     3090                     p_dfld_ij(ji,jj,kk,1) = p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) 
     3091                     p_dfld_ij(ji,jj,kk,2) = p_dfld_ij(ji,jj,kk,1) 
     3092               END IF        
     3093            END_2D  
     3094 
     3095         ELSE !  k_uv == 2  
     3096 
     3097            DO_2D( 0, 0, 0, 0)        
     3098            ! Walls coming from left: should check from 2 to jpj-1 (and jpi=2-jpi) 
     3099               IF ( vmask(ji,jj,jk_msk) > 0.5_wp .AND. vmask(ji,jj-1,jk_msk) < 0.5_wp .AND. vmask(ji,jj+1,jk_msk) > 0.5_wp)  THEN 
     3100                  p_dfld_ij(ji,jj,kk,1) = p_aco_bc_fld_hor * (p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) ) - p_bco_bc_fld_hor * p_dfld_ij(ji,jj,kk,2) 
     3101               END IF  
     3102            ! Walls coming from right: should check from 3 to jpj (and jpi=2-jpi) 
     3103               IF ( vmask(ji,jj,jk_msk) < 0.5_wp .AND. vmask(ji,jj-1,jk_msk) > 0.5_wp .AND. vmask(ji,jj-2,jk_msk) > 0.5_wp) THEN  
     3104                  p_dfld_ij(ji,jj,kk,2) = p_aco_bc_fld_hor * (p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) ) - p_bco_bc_fld_hor * p_dfld_ij(ji,jj,kk,1) 
     3105               END IF 
     3106            END_2D  
     3107 
     3108            DO_2D( 0, 0, 0, 0)        
     3109            ! For an isolated velocity point use the central difference (this is important)  
     3110               IF ( vmask(ji, jj-1, jk_msk) < 0.5 .AND. vmask(ji, jj+1, jk_msk) < 0.5 ) THEN 
     3111                     p_dfld_ij(ji,jj,kk,1) = p_fld_pmr(ji,jj,kk,3) - p_fld_pmr(ji,jj,kk,2) 
     3112                     p_dfld_ij(ji,jj,kk,2) = p_dfld_ij(ji,jj,kk,1) 
     3113               END IF        
     3114            END_2D  
     3115 
     3116         END IF ! k_uv   
     3117 
     3118   END SUBROUTINE calc_dfld_pmr_ij 
     3119 
     3120!------------------------------------------------------------------------------------------ 
     3121 
     3122   SUBROUTINE vrt_int_quad(k_mbkt, p_rhd, p_e3t, p_p, p_F)  
     3123 
     3124      !!--------------------------------------------------------------------- 
     3125      !!                  ***  ROUTINE calc_rhd_k  *** 
     3126      !! 
     3127      !! ** Method  :   Use quadratic reconstruction of p_rhd (density profile) to calculate pressure profile and  
     3128      !!                forces on vertical faces between w levels    
     3129      !!                   
     3130      !! ** Action : - set p_p and p_F 
     3131      !!---------------------------------------------------------------------- 
     3132 
     3133      INTEGER,  DIMENSION(A2D(nn_hls)),     INTENT(in)  :: k_mbkt   ! bottom level 
     3134      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in)  :: p_rhd    ! densities on tracer levels 
     3135      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(in)  :: p_e3t    ! layer thickness between w levels 
     3136      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(out) :: p_p      ! pressures on w levels 
     3137      REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(out) :: p_F      ! force on the vertical face between w levels 
     3138 
     3139      INTEGER  ::   ji, jj, jk                  ! dummy loop indices 
     3140      REAL(wp) ::   z_2_3, z_4_3, z_8_3         ! 2/3 and 4/3 and 8/3 
     3141      REAL(wp) ::   z_22_3, z_28_3              ! 22/3 and 28/3  
     3142 
     3143      REAL(wp) ::   zr_a, zr_b, zr_c            ! rhd evaluated at i, i+1/2 and i+1   
     3144      REAL(wp) ::   za_0, za_1, za_2            ! polynomial coefficients 
     3145      REAL(wp) ::   ze3t                        !  
     3146 
     3147      z_2_3  = 2.0_wp/3.0_wp 
     3148      z_4_3  = 4.0_wp/3.0_wp 
     3149      z_8_3  = 8.0_wp/3.0_wp 
     3150      z_22_3 = 22.0_wp/3.0_wp 
     3151      z_28_3 = 28.0_wp/3.0_wp  
     3152 
     3153! Integrate densities in the vertical using quadratic fits to the densities  
     3154! zr_a is r_{-1}  zr_b is r_1 ; zr_c is r_3   
     3155 
     3156! one-sided quadratic at the upper boundary. pressure is zero at the upper surface 
     3157      DO_2D(0,0,0,0)  
     3158    zr_a = p_rhd(ji,jj,1)  
     3159    zr_b = p_rhd(ji,jj,2)  
     3160    zr_c = p_rhd(ji,jj,3)  
     3161    ze3t = p_e3t(ji,jj,1) 
     3162         za_0 = 0.125_wp * ( - zr_c + 6._wp*zr_b + 3._wp*zr_a )  
     3163         za_1 = 0.5_wp   * ( zr_b - zr_a )   
     3164         za_2 = 0.125_wp * (   zr_c - 2._wp*zr_b + zr_a )  
     3165         p_p(ji,jj,1) = 0.0_wp      
     3166         p_p(ji,jj,2) =        grav*ze3t*     ( za_0 -       za_1 + z_4_3*za_2 )   
     3167         p_F(ji,jj,1) = 0.5_wp*grav*ze3t*ze3t*( za_0 - z_4_3*za_1 + 2._wp*za_2 )  
     3168      END_2D  
     3169 
     3170! centred quadratic in the interior  
     3171      DO_3D(0,0,0,0,2,jpk-1)  
     3172    zr_a = p_rhd(ji,jj,jk-1)  
     3173    zr_b = p_rhd(ji,jj,jk)  
     3174    zr_c = p_rhd(ji,jj,jk+1)  
     3175    ze3t = p_e3t(ji,jj,jk) 
     3176         za_0 = 0.125_wp * ( - zr_c + 6._wp*zr_b + 3._wp*zr_a )  
     3177         za_1 = 0.5_wp   * ( zr_b - zr_a )   
     3178         za_2 = 0.125_wp * (   zr_c - 2._wp*zr_b + zr_a )   
     3179         p_p(ji,jj,jk+1) =      p_p(ji,jj,jk) +     grav*ze3t*     ( za_0 +       za_1 + z_4_3*za_2 )   
     3180         p_F(ji,jj,jk  ) = ze3t*p_p(ji,jj,jk) + 0.5*grav*ze3t*ze3t*( za_0 + z_2_3*za_1 + z_2_3*za_2 )  
     3181      END_3D  
     3182 
     3183! one-sided quadratic at the lower boundary 
     3184      DO_2D(0,0,0,0)  
     3185         jk   = k_mbkt(ji,jj)  
     3186    zr_a = p_rhd(ji,jj,jk-2)  
     3187    zr_b = p_rhd(ji,jj,jk-1)  
     3188    zr_c = p_rhd(ji,jj,jk)  
     3189    ze3t = p_e3t(ji,jj,jk) 
     3190         za_0 = 0.125_wp * ( - zr_c + 6._wp*zr_b + 3._wp*zr_a )  
     3191         za_1 = 0.5_wp   * ( zr_b - zr_a )   
     3192         za_2 = 0.125_wp * (   zr_c - 2._wp*zr_b + zr_a )   
     3193         p_p(ji,jj,jk+1) =      p_p(ji,jj,jk) +     grav*ze3t*     ( za_0 +    3.*za_1 + z_28_3*za_2 )   
     3194         p_F(ji,jj,jk  ) = ze3t*p_p(ji,jj,jk) + 0.5*grav*ze3t*ze3t*( za_0 + z_8_3*za_1 + z_22_3*za_2 )  
     3195      END_2D  
     3196 
     3197   RETURN     
     3198   END SUBROUTINE vrt_int_quad 
     3199    
     3200!------------------------------------------------------------------------------------------ 
     3201 
     3202   SUBROUTINE dbg_2di( cc_array, ki_2d )  
     3203   CHARACTER*(*),                   INTENT(IN) :: cc_array 
     3204   INTEGER, DIMENSION(A2D(nn_hls)), INTENT(IN) :: ki_2d    
     3205 
     3206   INTEGER ::  ji_prt_low, ji_prt_upp, jj_prt_low, jj_prt_upp  
     3207   INTEGER ::  ji_prt, jj_prt 
     3208 
     3209   IF( lwp ) THEN 
     3210      ji_prt_low = MAX( ntsi-nn_hls, ki_dbg_min )      
     3211      ji_prt_upp = MIN( ntei+nn_hls, ki_dbg_max )      
     3212      jj_prt_low = MAX( ntsj-nn_hls, kj_dbg_min )      
     3213      jj_prt_upp = MIN( ntej+nn_hls, kj_dbg_max )      
     3214 
     3215!     print out a 2D horizontal slice  
     3216 
     3217      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ij ) THEN  
     3218         IF ( jj_prt_low <= jj_prt_upp ) THEN  
     3219            WRITE(numout,*) 
     3220            WRITE(numout,*) cc_array  
     3221            WRITE(numout,*) ' ji_prt_low, ji_prt_upp = ', ji_prt_low, ji_prt_upp 
     3222            WRITE(numout,*) ' row/col ', ( ji_prt, ji_prt = ji_prt_low, ji_prt_upp ) 
     3223            DO jj_prt = jj_prt_low, jj_prt_upp 
     3224         WRITE(numout,*) jj_prt, ( ki_2d(ji_prt, jj_prt), ji_prt = ji_prt_low, ji_prt_upp )  
     3225            END DO  
     3226         END IF  
     3227      END IF  
     3228 
     3229   END IF  
     3230 
     3231   RETURN     
     3232   END SUBROUTINE dbg_2di 
     3233 
     3234!---------------------------------------------------------------------------- 
     3235 
     3236   SUBROUTINE dbg_2di_k( cc_array, ki_2d, kk )  
     3237   CHARACTER*(*),                   INTENT(IN) :: cc_array 
     3238   INTEGER, DIMENSION(A2D(nn_hls)), INTENT(IN) :: ki_2d    
     3239   INTEGER,                         INTENT(IN) :: kk    
     3240 
     3241   INTEGER ::  ji_prt_low, ji_prt_upp, jj_prt_low, jj_prt_upp  
     3242   INTEGER ::  ji_prt, jj_prt, jk_prt 
     3243 
     3244   IF( lwp ) THEN 
     3245      ji_prt_low = MAX( ntsi, ki_dbg_min )      
     3246      ji_prt_upp = MIN( ntei, ki_dbg_max )      
     3247      jj_prt_low = MAX( ntsj, kj_dbg_min )      
     3248      jj_prt_upp = MIN( ntej, kj_dbg_max )      
     3249 
     3250!     print out a 2D (ji, jk) slice  
     3251 
     3252      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ik ) THEN  
     3253         IF ( ntsj <= kj_dbg_cen .AND. kj_dbg_cen <= ntej ) THEN  
     3254            IF ( kk == kk_dbg_min ) THEN   
     3255               WRITE(numout,*) 
     3256               WRITE(numout,*) cc_array, ' kj = ', kj_dbg_cen 
     3257               WRITE(numout,*) 'ji_prt_low, ji_prt_upp = ', ji_prt_low, ji_prt_upp 
     3258               WRITE(numout,*) 'kk_dbg_min, kk_dbg_max = ',  kk_dbg_min, kk_dbg_max  
     3259            END IF  
     3260            IF ( kk_dbg_min <= kk .AND. kk <= kk_dbg_max )   &  
     3261     &         WRITE(numout,*) cc_array, kk, ( ki_2d(ji_prt, kj_dbg_cen), ji_prt = ji_prt_low, ji_prt_upp )  
     3262         END IF  
     3263      END IF  
     3264 
     3265!     print out a 2D (jj, jk) slice  
     3266 
     3267      IF ( jj_prt_low <= jj_prt_upp .AND. ln_dbg_jk ) THEN  
     3268         IF ( ntsi <= ki_dbg_cen .AND. ki_dbg_cen <= ntei ) THEN  
     3269            IF ( kk == kk_dbg_min ) THEN   
     3270               WRITE(numout,*) 
     3271               WRITE(numout,*) cc_array, ' ki = ', ki_dbg_cen 
     3272               WRITE(numout,*) 'jj_prt_low, jj_prt_upp = ', jj_prt_low, jj_prt_upp 
     3273               WRITE(numout,*) 'kk_dbg_min, kk_dbg_max = ',  kk_dbg_min, kk_dbg_max  
     3274            END IF  
     3275            IF ( kk_dbg_min <= kk .AND. kk <= kk_dbg_max )   &  
     3276     &         WRITE(numout,*) cc_array, kk, ( ki_2d(ki_dbg_cen, jj_prt), jj_prt = jj_prt_low, jj_prt_upp )  
     3277         END IF  
     3278      END IF  
     3279 
     3280   END IF  
     3281 
     3282   RETURN     
     3283   END SUBROUTINE dbg_2di_k 
     3284 
     3285!---------------------------------------------------------------------------- 
     3286 
     3287   SUBROUTINE dbg_2dr( cc_array, pr_2d )  
     3288   CHARACTER*(*),                    INTENT(IN) :: cc_array 
     3289   REAL(wp), DIMENSION(A2D(nn_hls)), INTENT(IN) :: pr_2d    
     3290 
     3291   INTEGER ::  ji_prt_low, ji_prt_upp, jj_prt_low, jj_prt_upp  
     3292   INTEGER ::  ji_prt, jj_prt 
     3293 
     3294   IF(lwp) THEN 
     3295      ji_prt_low = MAX( ntsi-nn_hls, ki_dbg_min )      
     3296      ji_prt_upp = MIN( ntei+nn_hls, ki_dbg_max )      
     3297      jj_prt_low = MAX( ntsj-nn_hls, kj_dbg_min )      
     3298      jj_prt_upp = MIN( ntej+nn_hls, kj_dbg_max )      
     3299 
     3300!     print out a 2D horizontal slice  
     3301 
     3302      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ij ) THEN  
     3303         IF ( jj_prt_low <= jj_prt_upp ) THEN  
     3304            WRITE(numout,*) 
     3305            WRITE(numout,*) cc_array  
     3306            WRITE(numout,*) ' row/col ', ( ji_prt, ji_prt = ji_prt_low, ji_prt_upp ) 
     3307            DO jj_prt = jj_prt_low, jj_prt_upp 
     3308         WRITE(numout,*) jj_prt, ( pr_2d(ji_prt, jj_prt), ji_prt = ji_prt_low, ji_prt_upp )  
     3309            END DO  
     3310         END IF  
     3311      END IF  
     3312 
     3313   END IF  
     3314 
     3315   RETURN     
     3316   END SUBROUTINE dbg_2dr 
     3317 
     3318!---------------------------------------------------------------------------- 
     3319 
     3320   SUBROUTINE dbg_3di( cc_array, ki_3d ) 
     3321     
     3322   CHARACTER*(*),                       INTENT(IN) :: cc_array 
     3323   INTEGER, DIMENSION(A2D(nn_hls),jpk), INTENT(IN) :: ki_3d    
     3324 
     3325   INTEGER ::  ji_prt_low, ji_prt_upp, jj_prt_low, jj_prt_upp  
     3326   INTEGER ::  ji_prt, jj_prt, jk_prt 
     3327 
     3328! output values  
     3329 
     3330 
     3331   IF(lwp) THEN 
     3332      ji_prt_low = MAX( ntsi-nn_hls, ki_dbg_min )      
     3333      ji_prt_upp = MIN( ntei+nn_hls, ki_dbg_max )      
     3334      jj_prt_low = MAX( ntsj-nn_hls, kj_dbg_min )      
     3335      jj_prt_upp = MIN( ntej+nn_hls, kj_dbg_max )      
     3336 
     3337!     print out a 2D horizontal slice  
     3338 
     3339      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ij ) THEN  
     3340         IF ( jj_prt_low <= jj_prt_upp ) THEN  
     3341            WRITE(numout,*) 
     3342            WRITE(numout,*) cc_array, ' level = ', kk_dbg_cen 
     3343            WRITE(numout,*) ' row/col ', ( ji_prt, ji_prt = ji_prt_low, ji_prt_upp ) 
     3344            DO jj_prt = jj_prt_low, jj_prt_upp 
     3345         WRITE(numout,*) jj_prt, ( ki_3d(ji_prt, jj_prt, kk_dbg_cen), ji_prt = ji_prt_low, ji_prt_upp )  
     3346            END DO  
     3347         END IF  
     3348      END IF  
     3349 
     3350!     print out a 2D (ji, jk) slice  
     3351 
     3352      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ik ) THEN  
     3353         IF ( ntsj <= kj_dbg_cen .AND. kj_dbg_cen <= ntej ) THEN  
     3354            WRITE(numout,*) 
     3355            WRITE(numout,*) cc_array, ' kj = ', kj_dbg_cen 
     3356            WRITE(numout,*) ' row/lev ', ( ji_prt, ji_prt = ji_prt_low, ji_prt_upp ) 
     3357            DO jk_prt = kk_dbg_min, kk_dbg_max 
     3358         WRITE(numout,*) jk_prt, ( ki_3d(ji_prt, kj_dbg_cen, jk_prt), ji_prt = ji_prt_low, ji_prt_upp )  
     3359            END DO  
     3360         END IF  
     3361      END IF  
     3362 
     3363!     print out a 2D (jj, jk) slice  
     3364 
     3365      IF ( jj_prt_low <= jj_prt_upp .AND. ln_dbg_jk ) THEN  
     3366         IF ( ntsi <= ki_dbg_cen .AND. ki_dbg_cen <= ntei ) THEN  
     3367            WRITE(numout,*) 
     3368            WRITE(numout,*) cc_array, ' ki = ', ki_dbg_cen 
     3369            WRITE(numout,*) ' col/lev ', ( jj_prt, jj_prt = jj_prt_low, jj_prt_upp ) 
     3370            DO jk_prt = kk_dbg_min, kk_dbg_max 
     3371         WRITE(numout,*) jk_prt, ( ki_3d(ki_dbg_cen, jj_prt, jk_prt), jj_prt = jj_prt_low, jj_prt_upp )  
     3372            END DO  
     3373         END IF  
     3374      END IF  
     3375 
     3376   END IF  
     3377 
     3378   RETURN     
     3379   END SUBROUTINE dbg_3di 
     3380 
     3381!---------------------------------------------------------------------------- 
     3382 
     3383   SUBROUTINE dbg_3dr( cc_array, pr_3d ) 
     3384     
     3385   CHARACTER*(*),                        INTENT(IN) :: cc_array 
     3386   REAL(wp), DIMENSION(A2D(nn_hls),jpk), INTENT(IN) :: pr_3d    
     3387 
     3388   INTEGER ::  ji_prt_low, ji_prt_upp, jj_prt_low, jj_prt_upp  
     3389   INTEGER ::  ji_prt, jj_prt, jk_prt 
     3390 
     3391! output values  
     3392 
     3393 
     3394   IF(lwp) THEN 
     3395      ji_prt_low = MAX( ntsi-nn_hls, ki_dbg_min )      
     3396      ji_prt_upp = MIN( ntei+nn_hls, ki_dbg_max )      
     3397      jj_prt_low = MAX( ntsj-nn_hls, kj_dbg_min )      
     3398      jj_prt_upp = MIN( ntej+nn_hls, kj_dbg_max )      
     3399 
     3400!     print out a 2D horizontal slice  
     3401 
     3402      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ij ) THEN  
     3403         IF ( jj_prt_low <= jj_prt_upp ) THEN  
     3404            WRITE(numout,*) 
     3405            WRITE(numout,*) cc_array, ' level = ', kk_dbg_cen 
     3406            WRITE(numout,*) ' row/col ', ( ji_prt, ji_prt = ji_prt_low, ji_prt_upp ) 
     3407            DO jj_prt = jj_prt_low, jj_prt_upp 
     3408         WRITE(numout,*) jj_prt, ( pr_3d(ji_prt, jj_prt, kk_dbg_cen), ji_prt = ji_prt_low, ji_prt_upp )  
     3409            END DO  
     3410         END IF  
     3411      END IF  
     3412 
     3413!     print out a 2D (ji, jk) slice  
     3414 
     3415      IF ( ji_prt_low <= ji_prt_upp .AND. ln_dbg_ik ) THEN  
     3416         IF ( ntsj <= kj_dbg_cen .AND. kj_dbg_cen <= ntej ) THEN  
     3417            WRITE(numout,*) 
     3418            WRITE(numout,*) cc_array, ' kj = ', kj_dbg_cen 
     3419            WRITE(numout,*) ' row/lev ', ( ji_prt, ji_prt = ji_prt_low, ji_prt_upp ) 
     3420            DO jk_prt = kk_dbg_min, kk_dbg_max 
     3421         WRITE(numout,*) jk_prt, ( pr_3d(ji_prt, kj_dbg_cen, jk_prt), ji_prt = ji_prt_low, ji_prt_upp )  
     3422            END DO  
     3423         END IF  
     3424      END IF  
     3425 
     3426!     print out a 2D (jj, jk) slice  
     3427 
     3428      IF ( jj_prt_low <= jj_prt_upp .AND. ln_dbg_jk ) THEN  
     3429         IF ( ntsi <= ki_dbg_cen .AND. ki_dbg_cen <= ntei ) THEN  
     3430            WRITE(numout,*) 
     3431            WRITE(numout,*) cc_array, ' ki = ', ki_dbg_cen 
     3432            WRITE(numout,*) ' col/lev ', ( jj_prt, jj_prt = jj_prt_low, jj_prt_upp ) 
     3433            DO jk_prt = kk_dbg_min, kk_dbg_max 
     3434         WRITE(numout,*) jk_prt, ( pr_3d(ki_dbg_cen, jj_prt, jk_prt), jj_prt = jj_prt_low, jj_prt_upp )  
     3435            END DO  
     3436         END IF  
     3437      END IF  
     3438 
     3439   END IF  
     3440 
     3441   RETURN     
     3442   END SUBROUTINE dbg_3dr 
     3443 
     3444 
    14373445   !!====================================================================== 
    14383446END MODULE dynhpg 
Note: See TracChangeset for help on using the changeset viewer.