 MODULE obcapplyssh

   !!======================================================================
   !!                   ***  MODULE  obcapplyssh  ***
   !! Ocean dynamics:  apply sea surface height open boundary conditions
   !!======================================================================

#include "toolcpp.h"

   !! * Modules used
   USE obccombine, ONLY : obc_sshs,obc_sshn,obc_sshe,obc_sshw,              &
                          l_obc_west,l_obc_east,l_obc_north,l_obc_south

   IMPLICIT NONE
   PRIVATE

   !! * Accessibility
   PUBLIC obc_apply_ssh                ! routine called by stepu*.F90 stepv*.F90

   !! * Interface
   INTERFACE obc_apply_ssh
#ifdef key_lagoon
     MODULE PROCEDURE obc_apply_ssh_lagoon
#else
     MODULE PROCEDURE obc_apply_ssh_ref 
#endif
   END INTERFACE

   !! * Shared module variables

   !! * Private variables

 CONTAINS
   !!======================================================================

#if ! defined key_lagoon
   SUBROUTINE obc_apply_ssh_ref(xe)

   !&E---------------------------------------------------------------------
   !&E                 ***  ROUTINE obc_apply_ssh  ***
   !&E
   !&E ** Purpose : save sea surface height open boundary into xe
   !&E
   !&E ** Description : open boundary sea surface heights (combination of ogcm !and tide)
   !&E                  are saved in variables obc_sshs
   !&E
   !&E ** Called by :
   !&E
   !&E ** External calls :
   !&E
   !&E ** Reference :
   !&E
   !&E ** History :
   !&E       !  2008-04 (V. Garnier) Original code
   !&E       !  2009-05  (F. Dumas)  AGRIF
   !&E       !  2011-11  (V. Garnier) Spatial extension of ssh(liminm2:limaxp2,ljminm2:ljmaxp2)
   !&E
   !&E ** RQ : this routine can not be parallelized at all until xe is not in dyn3dy.F90
   !&E
   !&E---------------------------------------------------------------------

   !! * Modules used
   USE parameters, ONLY : grav,imin,imax,jmin,jmax,liminp1,limax,ljminp1,ljmax, &
                          limin,liminm2,limaxp2,ljmin,ljminm2,ljmaxp2,rsh,valmanq, &
                          ishift_obc_west,ishift_obc_east,jshift_obc_south,jshift_obc_north
   USE comvars2d,  ONLY : h0,ig,id,jb,jh
#ifdef key_wave_qeuler_dynamics
   USE wave,       ONLY : wave_bhd
#endif

   !! * Declaration Subroutine

   !! * Arguments
   REAL(KIND=rsh),DIMENSION(liminm2:limaxp2,ljminm2:ljmaxp2),INTENT( out )   :: xe

   !! * Local declarations
   INTEGER :: i,j

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

   ! western boundary

   IF ( l_obc_west ) THEN
     DO j=ljminm2,ljmaxp2
       IF (j >= 7 .and. j<= 161) then
       i=ig(j)
       !print*,"j,ig=",j,i
       !IF_MPI (i==imin+ishift_obc_west .AND. limin<=i .AND. i<=limax) THEN
       IF_MPI (i==imin+31 .AND. limin<=i .AND. i<=limax) THEN
       IF (h0(i,j)/=-valmanq) THEN
         xe(i,j) = obc_sshw(j)
         !if (i==31 .and. j==100) print*,"xe west",j,i,h0(i,j),xe(i,j)
#ifdef key_wave_qeuler_dynamics
         xe(i,j) = xe(i,j)-wave_bhd(i,j)/grav
#endif
       END IF
       ENDIF_MPI
      ENDIF
      !IF (j>160) THEN
       !i=ig(j)
       !IF (h0(i,j)/=-valmanq) print*,"xe>160",j,i,h0(i,j),xe(i,j)
      !ENDIF
     END DO
   ENDIF

   ! eastern boundary
   IF ( l_obc_east ) THEN
     DO j=ljminm2,ljmaxp2
       i=id(j)
       IF_MPI (i==imax-ishift_obc_east .AND. limin<=i .AND. i<=limax) THEN
       IF  (h0(i,j)/=-valmanq) THEN
         xe(i,j) = obc_sshe(j)
#ifdef key_wave_qeuler_dynamics
         xe(i,j) = xe(i,j)-wave_bhd(i,j)/grav
#endif
       END IF
       ENDIF_MPI
     END DO
   ENDIF

   ! southern boundary
   IF ( l_obc_south ) THEN
     DO i=liminm2,limaxp2
       j=jb(i)
       IF_MPI (j==jmin+1+jshift_obc_south .AND. ljmin<=j .AND. j<=ljmax) THEN
       IF (h0(i,j)/=-valmanq) THEN
         xe(i,j) = obc_sshs(i)
#ifdef key_wave_qeuler_dynamics
         xe(i,j) = xe(i,j)-wave_bhd(i,j)/grav
#endif
       END IF
       ENDIF_MPI
     END DO
   ENDIF

   ! northern boundary
   IF ( l_obc_north ) THEN
     DO i=liminm2,limaxp2
       j=jh(i)
       IF_MPI (j==jmax-jshift_obc_north .AND. ljmin<=j .AND. j<=ljmax) THEN
       IF (h0(i,j)/=-valmanq) THEN
         xe(i,j) = obc_sshn(i)
#ifdef key_wave_qeuler_dynamics
         xe(i,j) = xe(i,j)-wave_bhd(i,j)/grav
#endif
       END IF
       ENDIF_MPI
     END DO
   ENDIF

   END SUBROUTINE obc_apply_ssh_ref
#endif

   !!======================================================================
#ifdef key_lagoon
   SUBROUTINE obc_apply_ssh_lagoon(xe)

   !&E---------------------------------------------------------------------
   !&E                 ***  ROUTINE obc_apply_ssh_lagoon  ***
   !&E
   !&E ** Purpose : save sea surface height open boundary into xe only for LAGOON
   !&E
   !&E ** Description : open boundary sea surface heights (combination of ogcm !and tide)
   !&E                  are saved in variables obc_sshs
   !&E
   !&E ** Called by :
   !&E
   !&E ** External calls :
   !&E
   !&E ** Reference :
   !&E
   !&E ** History :
   !&E       !  2008-04 (V. Garnier) Original code
   !&E       !  2009-05  (F. Dumas)  AGRIF
   !&E
   !&E ** RQ : this routine can not be parallelized at all until xe is not in dyn3dy.F90
   !&E
   !&E---------------------------------------------------------------------

   !! * Modules used
   USE parameters, ONLY : liminm2,limaxp2,ljmin,ljminm2,ljmaxp2,rsh,valmanq
   USE comvars2d,  ONLY : igrau,jgrau,nbgrau,type_grau
   
   !! * Arguments
   REAL(KIND=rsh),DIMENSION(liminm2:limaxp2,ljminm2:ljmaxp2),INTENT( out )   :: xe

   !! * Local declarations
   INTEGER              :: ng,i0,j0

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

    DO ng=1,nbgrau
      i0=igrau(ng)
      j0=jgrau(ng)

      ! western boundary
      IF (type_grau(ng)==4) THEN
      !! grau sur la frontiere Ouest
        IF_MPI ( (i0 >= liminm2) .AND. (i0 <= limaxp2) .AND.(j0 >= ljminm2) .AND. (j0 <= ljmaxp2) ) THEN
          xe(i0,j0) = obc_sshw(j0)
        ENDIF_MPI       
      END IF

      ! eastern boundary
      IF (type_grau(ng)==2) THEN
      !! grau sur la frontiere Est
        IF_MPI ( (i0 >= liminm2) .AND. (i0 <= limaxp2) .AND.(j0 >= ljminm2) .AND. (j0 <= ljmaxp2) ) THEN
          xe(i0,j0) = obc_sshe(j0)
      !    obc_tide_sshe(j0)= dt1*cl_heau(indchrono+1)+(1.d0-dt1)*cl_heau(indchrono) &
        ENDIF_MPI       
      END IF

      ! southern boundary
      IF (type_grau(ng)==3) THEN
      !! grau sur la frontiere Sud
        IF_MPI ( (i0 >= liminm2) .AND. (i0 <= limaxp2) .AND.(j0 >= ljminm2) .AND. (j0 <= ljmaxp2) ) THEN
          xe(i0,j0) = obc_sshs(i0)
        ENDIF_MPI       
      END IF

      ! northern boundary
      IF (type_grau(ng)==1) THEN
      !! grau sur la frontiere Nord
        IF_MPI ( (i0 >= liminm2) .AND. (i0 <= limaxp2) .AND.(j0 >= ljminm2) .AND. (j0 <= ljmaxp2) ) THEN
          xe(i0,j0) = obc_sshn(i0)
        ENDIF_MPI       
      END IF
    END DO

   END SUBROUTINE obc_apply_ssh_lagoon
#endif

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

 END MODULE obcapplyssh
