 MODULE toolgeom
!!======================================================================
!!                   ***  MODULE toolgeom  ***
!! Mathematical functions
!!======================================================================
!! * Modules used
   USE parameters, ONLY : rsh

   IMPLICIT NONE
   PRIVATE

!! * Accessibility
   PUBLIC f_dzu,       &              ! layer thickness centered around T
          f_dzw,       &              ! layer thickness centered around W
          f_dzu_x,     &              ! layer thickness centered around U
          f_dzw_x,     &              ! layer thickness centered around W at U location
          f_dzu_y,     &              ! layer thickness centered around V
          f_dzw_y,     &              ! layer thickness centered around W at V location
          f_hzu,       &              ! vertical scale factor at T-location (Hz or H0+ssh)
          f_hzw,       &              ! vertical scale factor at w-location (interface)
          f_hzu_x,     &              ! vertical scale factor at u-location
          f_hzw_x,     &              ! vertical scale factor at the interface and u-location
          f_hzu_y,     &              ! vertical scale factor at v-location
          f_hzw_y,     &              ! vertical scale factor at the interface and v-location
          f_zu,        &              ! depth at T-location
          f_zw,        &              ! depth at w-location (interface)
          f_zu_x,      &              ! depth at U-location (middle of the cell along the z-axis)
          f_zu_y,      &              ! depth at V-location (middle of the cell along the z-axis)
          f_zw_x,      &              ! depth at the interface at hx-location (upper right corner along xz-slice)
          f_zw_y,      &              ! depth at the interface at hy-location (upper right corner along yz-slice)
          dist_circle                 ! circle distance from 2 longitude / latitude locations

!! * Shared or public module variables

!! * Private variables

 CONTAINS

!!======================================================================
 
  FUNCTION f_dzu(h0,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_dzu  ***
!&E
!&E ** Purpose : estimate the layer thickness between 2 interfaces (w-locations)
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E
!&E ** Called by : biolodynzwat
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2009-10  (M. Sourisseau)  Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig,dsigu


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: h0,xe
   REAL(KIND=rsh) :: f_dzu                       ! thickness

!! * Local declarations
   REAL(KIND=rsh) :: d,hz_u

!!----------------------------------------------------------------------
!! * Executable part


     d=h0+xe
     f_dzu=d*dsigu(k)


  END FUNCTION f_dzu

!!======================================================================
 
  FUNCTION f_dzw(h0,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_dzw  ***
!&E
!&E ** Purpose : estimate the layer thickness between 2 u-locations
!&E              (w location)
!&E
!&E ** Description :
!&E
!&E ** Called by : biolodynzwat
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2009-10  (M. Sourisseau)  Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sigw,dsigw


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: h0,xe
   REAL(KIND=rsh) :: f_dzw                       ! thickness

!! * Local declarations
   REAL(KIND=rsh) :: d,hz_w

!!----------------------------------------------------------------------
!! * Executable part


     d=h0+xe
     f_dzw=d*dsigw(k)


  END FUNCTION f_dzw

!!======================================================================
 
  FUNCTION f_dzu_x(hx,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_dzu_x  ***
!&E
!&E ** Purpose : estimate the layer thickness between 2 interfaces (w-locations)
!&E              at location u
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E
!&E ** Called by : waveqeuler.F90
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2015-06  (V. Garnier)   From f_dzu
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig,dsigu


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hx,xe
   REAL(KIND=rsh) :: f_dzu_x                     ! thickness

!! * Local declarations
   REAL(KIND=rsh) :: d,hz_u_x

!!----------------------------------------------------------------------
!! * Executable part


     d=hx+xe
     f_dzu_x=d*dsigu(k)


  END FUNCTION f_dzu_x

!!======================================================================
 
  FUNCTION f_dzw_x(hx,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_dzw_x  ***
!&E
!&E ** Purpose : estimate the layer thickness at the interface
!&E              and u-location along x axis
!&E
!&E ** Description :
!&E
!&E ** Called by : waveqeuler.F90
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2015-06  (V. Garnier)   From f_dzu
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig,dsigw


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hx,xe
   REAL(KIND=rsh) :: f_dzw_x                     ! thickness

!! * Local declarations
   REAL(KIND=rsh) :: d,hz_w_x

!!----------------------------------------------------------------------
!! * Executable part


     d=hx+xe
     f_dzw_x=d*dsigw(k)


  END FUNCTION f_dzw_x

!!======================================================================
 
  FUNCTION f_dzu_y(hy,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_dzu_y  ***
!&E
!&E ** Purpose : estimate the layer thickness between 2 interfaces (w-locations)
!&E              at location y
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E
!&E ** Called by : waveqeuler.F90
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2015-06  (V. Garnier)   From f_dzu
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig,dsigu


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hy,xe
   REAL(KIND=rsh) :: f_dzu_y                     ! thickness

!! * Local declarations
   REAL(KIND=rsh) :: d,hz_u_y

!!----------------------------------------------------------------------
!! * Executable part


     d=hy+xe
     f_dzu_y=d*dsigu(k)


  END FUNCTION f_dzu_y

!!======================================================================
 
  FUNCTION f_dzw_y(hy,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_dzw_y  ***
!&E
!&E ** Purpose : estimate the layer thickness at the interface
!&E              and v-location along y axis
!&E
!&E ** Description :
!&E
!&E ** Called by : waveqeuler.F90
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2015-06  (V. Garnier)   From f_dzu
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig,dsigw


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hy,xe
   REAL(KIND=rsh) :: f_dzw_y                     ! thickness

!! * Local declarations
   REAL(KIND=rsh) :: d,hz_w_y

!!----------------------------------------------------------------------
!! * Executable part


     d=hy+xe
     f_dzw_y=d*dsigw(k)


  END FUNCTION f_dzw_y

!!======================================================================
 
  FUNCTION f_hzu(h0,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_hzu  ***
!&E
!&E ** Purpose : estimate the vertical scale factor Hz at the middle of
!&E              cell (tracer location)
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2010-03  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: h0,xe
   REAL(KIND=rsh) :: f_hzu                       ! vertical scale factor

!! * Local declarations

!!----------------------------------------------------------------------
!! * Executable part


     f_hzu=0.0_rsh   ! il manque h0.
! Fonction bcp utilisee dans dyn3dheightmask, obcinitheight, initheight
! et ce seulement pour les siggen donc pas de modif generale pour l instant.


  END FUNCTION f_hzu

!!======================================================================
 
  FUNCTION f_hzw(h0,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_hzw  ***
!&E
!&E ** Purpose : estimate the vertical scale factor Hz at the w-location
!&E
!&E ** Description : the w-location (along z-axis) is at the interface
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2010-03  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: h0,xe
   REAL(KIND=rsh) :: f_hzw                       ! vertical scale factor

!! * Local declarations

!!----------------------------------------------------------------------
!! * Executable part


     f_hzw=0.0_rsh


  END FUNCTION f_hzw

!!======================================================================
 
  FUNCTION f_hzu_x(hx,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_hzu_x  ***
!&E
!&E ** Purpose : estimate the vertical scale factor Hz at the u-location
!&E              (along x and z axes)
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E                  and dx/2 at the right of the tracer
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2010-03  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hx,xe
   REAL(KIND=rsh) :: f_hzu_x                     ! vertical scale factor

!! * Local declarations

!!----------------------------------------------------------------------
!! * Executable part


     f_hzu_x=0.0_rsh


  END FUNCTION f_hzu_x

!!======================================================================
 
  FUNCTION f_hzw_x(hx,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_hzw_x  ***
!&E
!&E ** Purpose : estimate the vertical scale factor Hz at the interface
!&E              and u-location along x axis
!&E
!&E ** Description :
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2010-03  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hx,xe
   REAL(KIND=rsh) :: f_hzw_x                     ! vertical scale factor

!! * Local declarations

!!----------------------------------------------------------------------
!! * Executable part


     f_hzw_x=0.0_rsh


  END FUNCTION f_hzw_x

!!======================================================================

  FUNCTION f_hzu_y(hy,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_hzu_y  ***
!&E
!&E ** Purpose : estimate the vertical scale factor Hz at the v-location
!&E              (along y and z axes)
!&E
!&E ** Description : the v-location (along z-axis) is the middle of the cell
!&E                  and dy/2 up to the tracer
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2010-03  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hy,xe
   REAL(KIND=rsh) :: f_hzu_y                     ! vertical scale factor

!! * Local declarations

!!----------------------------------------------------------------------
!! * Executable part


     f_hzu_y=0.0_rsh


  END FUNCTION f_hzu_y

!!======================================================================
 
  FUNCTION f_hzw_y(hy,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_hzw_y  ***
!&E
!&E ** Purpose : estimate the vertical scale factor Hz at the interface
!&E              and u-location along x axis
!&E
!&E ** Description :
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2010-03  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j         ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hy,xe
   REAL(KIND=rsh) :: f_hzw_y                     ! vertical scale factor

!! * Local declarations

!!----------------------------------------------------------------------
!! * Executable part


     f_hzw_y=0.0_rsh


  END FUNCTION f_hzw_y

!!======================================================================
 
  FUNCTION f_zu(h0,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_zu  ***
!&E
!&E ** Purpose : estimate the depth at u level
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2009-10  (V. Garnier)  Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j        ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: h0,xe
   REAL(KIND=rsh) :: f_zu                       ! depth

!! * Local declarations
   REAL(KIND=rsh) :: d

!!----------------------------------------------------------------------
!! * Executable part


     d=h0+xe
     f_zu=d*sig(k)+xe


  END FUNCTION f_zu

!!======================================================================

  FUNCTION f_zu_x(hx,xe,k,i,j)

!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_zu_x  ***
!&E
!&E ** Purpose : estimate the depth at u level and u location
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E                  and at the right of the center of the cell (along x-axis)
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2011-12  (S. Petton)  Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j        ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hx,xe
   REAL(KIND=rsh) :: f_zu_x                     ! depth

!! * Local declarations
   REAL(KIND=rsh) :: d

!!----------------------------------------------------------------------
!! * Executable part


     d=hx+xe
     f_zu_x=d*sig(k)+xe


  END FUNCTION f_zu_x

!!======================================================================

  FUNCTION f_zu_y(hy,xe,k,i,j)

!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_zu_y  ***
!&E
!&E ** Purpose : estimate the depth at u level and u location
!&E
!&E ** Description : the u-location (along z-axis) is the middle of the cell
!&E                  and at the top of the center of the cell (along y-axis)
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2011-12  (S. Petton)  Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sig


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j        ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hy,xe
   REAL(KIND=rsh) :: f_zu_y                     ! depth

!! * Local declarations
   REAL(KIND=rsh) :: d

!!----------------------------------------------------------------------
!! * Executable part


     d=hy+xe
     f_zu_y=d*sig(k)+xe


  END FUNCTION f_zu_y

!!======================================================================

  FUNCTION f_zw(h0,xe,k,i,j)
 
!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_zw  ***
!&E
!&E ** Purpose : estimate the depth at w level
!&E
!&E ** Description : the w-location (along z-axis) is the upper interface
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2009-10  (V. Garnier)  Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sigw


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j        ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: h0,xe
   REAL(KIND=rsh) :: f_zw                       ! depth

!! * Local declarations
   REAL(KIND=rsh) :: d

!!----------------------------------------------------------------------
!! * Executable part


     d=h0+xe
     f_zw=d*sigw(k)+xe


  END FUNCTION f_zw

!!======================================================================

  FUNCTION f_zw_x(hx,xe,k,i,j)

!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_zw_x  ***
!&E
!&E ** Purpose : estimate the depth at w level (interface) and hx location
!&E
!&E ** Description : location : the upper right corner of the cell (along zx-slice)
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2012-02  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sigw


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j        ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hx,xe
   REAL(KIND=rsh) :: f_zw_x                     ! depth

!! * Local declarations
   REAL(KIND=rsh) :: d

!!----------------------------------------------------------------------
!! * Executable part


     d=hx+xe
     f_zw_x=d*sigw(k)+xe


  END FUNCTION f_zw_x

!!======================================================================

  FUNCTION f_zw_y(hy,xe,k,i,j)

!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION f_zw_y  ***
!&E
!&E ** Purpose : estimate the depth at w level (interface) and hy location
!&E
!&E ** Description : location : the upper right corner of the cell (along zy-slice)
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2012-02  (V. Garnier) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars3d,  ONLY : sigw


!! * Arguments
   INTEGER, INTENT( in )        :: k,i,j        ! indexes of the cell
   REAL(KIND=rsh), INTENT( in ) :: hy,xe
   REAL(KIND=rsh) :: f_zw_y                     ! depth

!! * Local declarations
   REAL(KIND=rsh) :: d

!!----------------------------------------------------------------------
!! * Executable part


     d=hy+xe
     f_zw_y=d*sigw(k)+xe


  END FUNCTION f_zw_y

!!======================================================================

  FUNCTION dist_circle(latp,latm,lonp,lonm)

!&E---------------------------------------------------------------------
!&E                 ***  FUNCTION dist_circle  ***
!&E
!&E ** Purpose : estimate the circle distance from 2 longitudes & latitudes
!&E
!&E ** Description : Haversine formula
!&E
!&E ** Called by :
!&E
!&E ** External calls :
!&E
!&E ** Used ij-arrays :
!&E
!&E ** Modified variables :
!&E
!&E ** Reference :
!&E
!&E ** History :
!&E       !  2015-04  (R. Le Gendre) Original code
!&E
!&E---------------------------------------------------------------------
!! * Modules used
   USE comvars2d,  ONLY : radearth
   USE parameters, ONLY : pi,rlg

!! * Arguments
   REAL(KIND=rlg), INTENT( in ) :: latp,latm,lonp,lonm
   REAL(KIND=rlg) :: dist_circle                     ! distance

!! * Local declarations
   REAL(KIND=rsh), PARAMETER :: radeg=pi/180.0_rsh
!!----------------------------------------------------------------------
!! * Executable part

   dist_circle = 2.0_rlg*radearth*asin(sqrt(sin(0.5_rlg*(latp-latm)*radeg)**2+ &
                 cos(latp*radeg)*cos(latm*radeg)*sin(0.5_rlg*(lonp-lonm)*radeg)**2))

  END FUNCTION dist_circle

!!======================================================================

 END MODULE
