! Copyright 2022, Francois BOUCHUT, Anne MANGENEY, Marc PERUZZETTO, Antoine LUCAS,  Jacques SAINTE-MARIE
! This program is distributed under the terms of the Lesser GPL v3
! This file is part of SHALTOP.

module bound_conditions

  use parameters
  use states
  use topography
  use flux

  implicit double precision (a-h,o-z)

contains

  !------------------------------------------
  !Boundary conditions for rho, u and ut
  
  subroutine bound_conditions_variables
    
    !cconditions aux limites hyperboliques
    !cgauche
    !cperiodique
    if (limhypl.eq.-1) then
       do j=1,ny
          rho(0,j)=rho(nx,j)
          u(0,j)=u(nx,j)
          ut(0,j)=ut(nx,j)
       enddo
       !cdirichlet
    else if (limhypl.eq.0) then   ! Antoine 25/09/07
       do j=1,ny
          rho(0,j)=1.d0
          u(0,j)=1.d0
          ut(0,j)=0.d0
       enddo
       !cneumann
    else if (limhypl.eq.1) then
       do j=1,ny
          rho(0,j)=rho(1,j)
          u(0,j)=u(1,j)
          ut(0,j)=ut(1,j)
       enddo
       !cdensite imposee + neumann
    else if (limhypl.eq.2) then
       do j=1,ny
          rho(0,j)=rhogauche
          u(0,j)=rho(1,j)*u(1,j)/rho(0,j)
          ut(0,j)=ut(1,j)
       enddo
       !cdebit impose + neumann
    else if (limhypl.eq.3) then
       !      do j=1,ny Correction Anne
       do j=0,ny+1
          if ((abs(grilley(j)-milx).lt.wopen).and.(temps.lt.tpsopen)) then
             rho(0,j)=rhogauche!rho(1,j)
             !c     u(0,j)=qgauche/rho(0,j)
             otah=max(otad(0,j),otag(1,j))
             pth=.5d0*(ptd(0,j)+ptg(1,j))
             omeg=1.d0+pth**2
             u(0,j)=vitfluxentr(rho(0,j),rho(1,j),qgauche,u(1,j) &
                  & ,ckappa*rho(0,j)*otah*omeg &
                  & ,ckappa*rho(1,j)*otah*omeg)
          else
             rho(0,j)=0.d0
             u(0,j)=0.d0
          endif
          ut(0,j)=0.d0!ut(1,j)
       enddo
       !cmur vitesse normale nulle
    else if (limhypl.eq.4) then
       do j=1,ny
          rho(0,j)=rho(1,j)
          u(0,j)=-u(1,j)
          ut(0,j)=ut(1,j)
       enddo
    endif
    !cdroite
    !cperiodique
    if (limhypr.eq.-1) then
       do j=1,ny
          rho(nx+1,j)=rho(1,j)
          u(nx+1,j)=u(1,j)
          ut(nx+1,j)=ut(1,j)
       enddo
       !cdirichlet
    else if (limhypr.eq.0) then
       do j=1,ny
          rho(nx+1,j)=.1d0
          u(nx+1,j)=0.d0
          ut(nx+1,j)=-.1d0/(2.d0*pi)
       enddo
       !cneumann
    else if (limhypr.eq.1) then
       do j=1,ny
          rho(nx+1,j)=rho(nx,j)
          u(nx+1,j)=u(nx,j)
          ut(nx+1,j)=ut(nx,j)
       enddo
       !cdensite imposee + neumann
    else if (limhypr.eq.2) then
       do j=1,ny
          rho(nx+1,j)=rhodroite
          u(nx+1,j)=rho(nx,j)*u(nx,j)/rho(nx+1,j)
          ut(nx+1,j)=0.d0!ut(nx,j)
       enddo
       !cdebit impose + neumann
    else if (limhypr.eq.3) then
       do j=1,ny
          rho(nx+1,j)=rho(nx,j)
          u(nx+1,j)=qdroite/rho(nx+1,j)
          ut(nx+1,j)=ut(nx,j)
       enddo
       !cmur vitesse normale nulle
    else if (limhypr.eq.4) then
       do j=1,ny
          rho(nx+1,j)=rho(nx,j)
          u(nx+1,j)=-u(nx,j)
          ut(nx+1,j)=ut(nx,j)
       enddo
    endif
    !csud
    !cperiodique
    if (limhyps.eq.-1) then
       do i=1,nx
          rho(i,0)=rho(i,ny)
          u(i,0)=u(i,ny)
          ut(i,0)=ut(i,ny)
       enddo
       !cdirichlet
    else if (limhyps.eq.0) then
       do i=1,nx
          rho(i,0)=1.d0
          u(i,0)=1.d0
          ut(i,0)=0.d0
       enddo
       !cneumann
    else if (limhyps.eq.1) then
       do i=1,nx
          rho(i,0)=rho(i,1)
          u(i,0)=u(i,1)
          ut(i,0)=ut(i,1)
       enddo
       !cdensite imposee + neumann
    else if (limhyps.eq.2) then
       do i=1,nx
          rho(i,0)=rhosud
          ut(i,0)=rho(i,1)*ut(i,1)/rho(i,0)
          u(i,0)=u(i,1)
       enddo
       !cdebit impose + neumann
    else if (limhyps.eq.3) then
       do i=1,nx
          rho(i,0)=rho(i,1)
          ut(i,0)=qsud
          u(i,0)=u(i,1)
       enddo
       !cmur vitesse normale nulle
    else if (limhyps.eq.4) then
       do i=1,nx
          rho(i,0)=rho(i,1)
          u(i,0)=u(i,1)
          ut(i,0)=-ut(i,1)
       enddo
    endif
    !cnord
    !cperiodique
    if (limhypn.eq.-1) then
       do i=1,nx
          rho(i,ny+1)=rho(i,1)
          u(i,ny+1)=u(i,1)
          ut(i,ny+1)=ut(i,1)
       enddo
       !cdirichlet
    else if (limhypn.eq.0) then
       do i=1,nx
          rho(i,ny+1)=1.d0
          u(i,ny+1)=1.d0
          ut(i,ny+1)=0.d0
       enddo
       !cneumann
    else if (limhypn.eq.1) then
       do i=1,nx
          rho(i,ny+1)=rho(i,ny)
          u(i,ny+1)=u(i,ny)
          ut(i,ny+1)=ut(i,ny)
       enddo
       !cdensite imposee + neumann
    else if (limhypn.eq.2) then
       do i=1,nx
          rho(i,ny+1)=rhonord
          ut(i,ny+1)=rho(i,ny)*ut(i,ny)/rho(i,ny+1)
          u(i,ny+1)=0.d0!u(i,ny)
       enddo
       !cdebit impose + neumann
    else if (limhypn.eq.3) then
       do i=1,nx
          rho(i,ny+1)=rho(i,ny)
          ut(i,ny+1)=qnord
          u(i,ny+1)=u(i,ny)
       enddo
       !cmur vitesse normale nulle
    else if (limhypn.eq.4) then
       do i=1,nx
          rho(i,ny+1)=rho(i,ny)
          u(i,ny+1)=u(i,ny)
          ut(i,ny+1)=-ut(i,ny)
       enddo
    endif

  end subroutine bound_conditions_variables

  !--------------------------------------------------------
  
  !Boundary condition on reconstructed variables
  subroutine bound_conditions_reconstruct

    !cgauche
    !cperiodique
    if (limhypl.eq.-1) then
       do j=1,ny
          rhod(0,j)=rhod(nx,j)
          ud(0,j)=ud(nx,j)
          utd(0,j)=utd(nx,j)
       enddo
       !cdirichlet
    else if (limhypl.eq.0) then
       do j=1,ny
          rhod(0,j)=rho(0,j)
          ud(0,j)=u(0,j)
          utd(0,j)=ut(0,j)
       enddo
       !cneumann
    else if (limhypl.eq.1) then
       do j=1,ny
          rhod(0,j)=rhog(1,j)
          ud(0,j)=ug(1,j)
          utd(0,j)=utg(1,j)
       enddo
       !cdensite imposee + neumann
    else if (limhypl.eq.2) then
       do j=1,ny
          rhod(0,j)=rho(0,j)
          ud(0,j)=rhog(1,j)*ug(1,j)/rhod(0,j)
          utd(0,j)=utg(1,j)
       enddo
       !cdebit impose + neumann
    else if (limhypl.eq.3) then
       do j=1,ny
          if ((abs(grilley(j)-milx).lt.wopen).and.(temps.lt.tpsopen)) then
             rhod(0,j)=rhogauche!rhog(1,j)
             !c     ud(0,j)=rho(0,j)*u(0,j)/rhod(0,j)
             otah=max(otad(0,j),otag(1,j))
             pth=.5d0*(ptd(0,j)+ptg(1,j))
             omeg=1.d0+pth**2
             ud(0,j)=vitfluxentr(rhod(0,j),rhog(1,j),qgauche,ug(1,j)&
                  & ,ckappa*rhod(0,j)*otah*omeg&
                  & ,ckappa*rhog(1,j)*otah*omeg)
          else
             rhod(0,j)=0.d0!rhog(1,j)
             ud(0,j)=0.d0!rho(0,j)*u(0,j)/rhod(0,j)
          endif
          utd(0,j)=ut(0,j)
       enddo
       !cmur vitesse normale nulle
    else if (limhypl.eq.4) then
       do j=1,ny
          rhod(0,j)=rhog(1,j)
          ud(0,j)=-ug(1,j)
          utd(0,j)=utg(1,j)
       enddo
    endif
    !cdroite
    !cperiodique
    if (limhypr.eq.-1) then
       do j=1,ny
          rhog(nx+1,j)=rhog(1,j)
          ug(nx+1,j)=ug(1,j)
          utg(nx+1,j)=utg(1,j)
       enddo
       !cdirichlet
    else if (limhypr.eq.0) then
       do j=1,ny
          rhog(nx+1,j)=rho(nx+1,j)
          ug(nx+1,j)=u(nx+1,j)
          utg(nx+1,j)=ut(nx+1,j)
       enddo
       !cneumann
    else if (limhypr.eq.1) then
       do j=1,ny
          rhog(nx+1,j)=rhod(nx,j)
          ug(nx+1,j)=ud(nx,j)
          utg(nx+1,j)=utd(nx,j)
       enddo
       !cdensite imposee + neumann
    else if (limhypr.eq.2) then
       do j=1,ny
          rhog(nx+1,j)=rho(nx+1,j)
          ug(nx+1,j)=rhod(nx,j)*ud(nx,j)/rhog(nx+1,j)
          utg(nx+1,j)=ut(nx+1,j)
       enddo
       !cdebit impose + neumann
    else if (limhypr.eq.3) then
       do j=1,ny
          rhog(nx+1,j)=rhod(nx,j)
          ug(nx+1,j)=rho(nx+1,j)*u(nx+1,j)/rhog(nx+1,j)
          utg(nx+1,j)=utd(nx,j)
       enddo
       !cmur vitesse normale nulle
    else if (limhypr.eq.4) then
       do j=1,ny
          rhog(nx+1,j)=rhod(nx,j)
          ug(nx+1,j)=-ud(nx,j)
          utg(nx+1,j)=utd(nx,j)
       enddo
    endif
    !csud
    !cperiodique
    if (limhyps.eq.-1) then
       do i=1,nx
          rhon(i,0)=rhon(i,ny)
          un(i,0)=un(i,ny)
          utn(i,0)=utn(i,ny)
       enddo
       !cdirichlet
    else if (limhyps.eq.0) then
       do i=1,nx
          rhon(i,0)=rho(i,0)
          un(i,0)=u(i,0)
          utn(i,0)=ut(i,0)
       enddo
       !cneumann
    else if (limhyps.eq.1) then
       do i=1,nx
          rhon(i,0)=rhos(i,1)
          un(i,0)=us(i,1)
          utn(i,0)=uts(i,1)
       enddo
       !cdensite imposee + neumann
    else if (limhyps.eq.2) then
       do i=1,nx
          rhon(i,0)=rho(i,0)
          utn(i,0)=rhos(i,1)*uts(i,1)/rhon(i,0)
          un(i,0)=us(i,1)
       enddo
       !cdebit impose + neumann
    else if (limhyps.eq.3) then
       do i=1,nx
          rhon(i,0)=rhos(i,1)
          utn(i,0)=rho(i,0)*ut(i,0)/rhon(i,0)
          un(i,0)=u(i,0)
       enddo
       !cmur vitesse normale nulle
    else if (limhyps.eq.4) then
       do i=1,nx
          rhon(i,0)=rhos(i,1)
          un(i,0)=us(i,1)
          utn(i,0)=-uts(i,1)
       enddo
    endif
    !cnord
    !cperiodique
    if (limhypn.eq.-1) then
       do i=1,nx
          rhos(i,ny+1)=rhos(i,1)
          us(i,ny+1)=us(i,1)
          uts(i,ny+1)=uts(i,1)
       enddo
       !cdirichlet
    else if (limhypn.eq.0) then
       do i=1,nx
          rhos(i,ny+1)=rho(i,ny+1)
          us(i,ny+1)=u(i,ny+1)
          uts(i,ny+1)=ut(i,ny+1)
       enddo
       !cneumann
    else if (limhypn.eq.1) then
       do i=1,nx
          rhos(i,ny+1)=rhon(i,ny)
          us(i,ny+1)=un(i,ny)
          uts(i,ny+1)=utn(i,ny)
       enddo
       !cdensite imposee + neumann
    else if (limhypn.eq.2) then
       do i=1,nx
          rhos(i,ny+1)=rho(i,ny+1)
          uts(i,ny+1)=rhon(i,ny)*utn(i,ny)/rhos(i,ny+1)
          us(i,ny+1)=u(i,ny+1)
       enddo
       !cdebit impose + neumann
    else if (limhypn.eq.3) then
       do i=1,nx
          rhos(i,ny+1)=rhon(i,ny)
          uts(i,ny+1)=rho(i,ny+1)*ut(i,ny+1)/rhos(i,ny+1)
          us(i,ny+1)=un(i,ny)
       enddo
       !cmur vitesse normale nulle
    else if (limhypn.eq.4) then
       do i=1,nx
          rhos(i,ny+1)=rhon(i,ny)
          us(i,ny+1)=un(i,ny)
          uts(i,ny+1)=-utn(i,ny)
       enddo
    endif

  end subroutine bound_conditions_reconstruct

end module bound_conditions
