module upper_boundary_slip
  use datatype
  use model_info
  use mem_manager
  implicit none

	interface upper_boundary_slip_x 
		module procedure upper_boundary_slip_x_x, upper_boundary_slip_x_xy, upper_boundary_slip_x_xz, upper_boundary_slip_x_xyz 
	end interface

	interface upper_boundary_slip_y 
		module procedure upper_boundary_slip_y_y, upper_boundary_slip_y_xy, upper_boundary_slip_y_yz, upper_boundary_slip_y_xyz 
	end interface

	interface upper_boundary_slip_z 
		module procedure upper_boundary_slip_z_z, upper_boundary_slip_z_xz, upper_boundary_slip_z_yz, upper_boundary_slip_z_xyz
	end interface
	

contains
	subroutine upper_boundary_slip_x_x(var) 
		type(var_x), intent(inout) :: var
		integer :: i

		if (var%grid(1) == 0) then 
			do i = 1, margin_1 
				work_x(pub1+i,:,:,var%id) = work_x(pub1-i,:,:,var%id) 
			end do

		else if (var%grid(1) == 1) then 
			do i = 1, margin_1
				work_x(pub1+i,:,:,var%id) = work_x(pub1-i+1,:,:,var%id) 
			end do
		
		end if
	
	end subroutine upper_boundary_slip_x_x


	subroutine upper_boundary_slip_x_xy(var) 
		type(var_xy), intent(inout) :: var
		integer :: i

		if (var%grid(1) == 0) then 
			do i = 1, margin_1
				work_xy(pub1+i,:,:,var%id) = work_xy(pub1-i,:,:,var%id) 
			end do

		else if (var%grid(1) == 1) then 
			do i = 1, margin_1
				work_xy(pub1+i,:,:,var%id) = work_xy(pub1-i+1,:,:,var%id) 
			end do
   
  		end if
  
	end subroutine upper_boundary_slip_x_xy


	subroutine upper_boundary_slip_x_xz(var) 
		type(var_xz), intent(inout) :: var
		integer :: i

		if (var%grid(1) == 0) then 
			do i = 1, margin_1
				work_xz(pub1+i,:,:,var%id) = work_xz(pub1-i,:,:,var%id) 
			end do

		else if (var%grid(1) == 1) then 
			do i = 1, margin_1
				work_xz(pub1+i,:,:,var%id) = work_xz(pub1-i+1,:,:,var%id) 
			end do
     
		end if
	 
	end subroutine upper_boundary_slip_x_xz


	subroutine upper_boundary_slip_x_xyz(var) 
   	type(var_xyz), intent(inout) :: var
   	integer :: i
 
		if (var%grid(1) == 0) then 
     		do i = 1, margin_1
       		work_xyz(pub1+i,:,:,var%id) = work_xyz(pub1-i,:,:,var%id) 
     		end do

   	else if (var%grid(1) == 1) then 
      	do i = 1, margin_1
        	work_xyz(pub1+i,:,:,var%id) = work_xyz(pub1-i+1,:,:,var%id) 
       	end do
     
		end if		

 	end subroutine upper_boundary_slip_x_xyz


	subroutine upper_boundary_slip_y_y(var) 
   	type(var_y), intent(inout) :: var
    	integer :: i

   	if (var%grid(2) == 0) then 
      	do i = 1, margin_2
        	work_y(:,pub2+i,:,var%id) = work_y(:,pub2-i,:,var%id) 
     		end do

   	else if (var%grid(2) == 1) then 
     		do i = 1, margin_2
       		work_y(:,pub2+i,:,var%id) = work_y(:,pub2-i+1,:,var%id) 
     		end do
     
		end if

 	end subroutine upper_boundary_slip_y_y


	subroutine upper_boundary_slip_y_xy(var) 
   	type(var_xy), intent(inout) :: var
   	integer :: i

  		if (var%grid(2) == 0) then 
    		do i = 1, margin_2
     			work_xy(:,pub2+i,:,var%id) = work_xy(:,pub2-i,:,var%id) 
     		end do

   	else if (var%grid(2) == 1) then 
   		do i = 1, margin_2
  				work_xy(:,pub2+i,:,var%id) = work_xy(:,pub2-i+1,:,var%id) 
    		end do
    
		end if

 	end subroutine upper_boundary_slip_y_xy


	subroutine upper_boundary_slip_y_yz(var) 
   	type(var_yz), intent(inout) :: var
   	integer :: i

   	if (var%grid(2) == 0) then 
     		do i = 1, margin_2 
       		work_yz(:,pub2+i,:,var%id) = work_yz(:,pub2-i,:,var%id) 
    		end do

   	else if (var%grid(2) == 1) then 
    		do i = 1, margin_2
     			work_yz(:,pub2+i,:,var%id) = work_yz(:,pub2-i+1,:,var%id) 
   		end do
     
		end if

 	end subroutine upper_boundary_slip_y_yz
	

	subroutine upper_boundary_slip_y_xyz(var) 
    	type(var_xyz), intent(inout) :: var
   	integer :: i

 		if (var%grid(2) == 0) then 
    		do i = 1, margin_2
      		work_xyz(:,pub2+i,:,var%id) = work_xyz(:,pub2-i,:,var%id) 
   		end do

  		else if (var%grid(2) == 1) then 
  			do i = 1, margin_2
  				work_xyz(:,pub2+i,:,var%id) = work_xyz(:,pub2-i+1,:,var%id) 
  			end do
     
		end if
     
	end subroutine upper_boundary_slip_y_xyz


	subroutine upper_boundary_slip_z_z(var) 
  		type(var_z), intent(inout) :: var
  		integer :: i

  		if (var%grid(3) == 0) then 
   		do i = 1, margin_3
  				work_z(:,:,pub3+i,var%id) = work_z(:,:,pub3-i,var%id) 
  			end do

  		else if (var%grid(3) == 1) then 
   		do i = 1, margin_3
  				work_z(:,:,pub3+i,var%id) = work_z(:,:,pub3-i+1,var%id) 
  			end do
     
		end if

	end subroutine upper_boundary_slip_z_z


	subroutine upper_boundary_slip_z_xz(var) 
   	type(var_xz), intent(inout) :: var
   	integer :: i

  		if (var%grid(3) == 0) then 
     		do i = 1, margin_3
      		work_xz(:,:,pub3+i,var%id) = work_xz(:,:,pub3-i,var%id) 
    		end do

   	else if (var%grid(3) == 1) then 
    		do i = 1, margin_3
      		work_xz(:,:,pub3+i,var%id) = work_xz(:,:,pub3-i+1,var%id) 
    		end do
     
		end if

 	end subroutine upper_boundary_slip_z_xz


	subroutine upper_boundary_slip_z_yz(var) 
   	type(var_yz), intent(inout) :: var
   	integer :: i

  		if (var%grid(3) == 0) then 
   		do i = 1, margin_3
  				work_yz(:,:,pub3+i,var%id) = work_yz(:,:,pub3-i,var%id) 
    		end do

  		else if (var%grid(3) == 1) then 
    		do i = 1, margin_3
        	work_yz(:,:,pub3+i,var%id) = work_yz(:,:,pub3-i+1,var%id) 
      	end do
 
   	end if

 	end subroutine upper_boundary_slip_z_yz


	subroutine upper_boundary_slip_z_xyz(var) 
   	type(var_xyz), intent(inout) :: var
   	integer :: i

     	if (var%grid(3) == 0) then 
   		do i = 1, margin_3
        	work_xyz(:,:,pub3+i,var%id) = work_xyz(:,:,pub3-i,var%id) 
      	end do

   	else if (var%grid(3) == 1) then 
      	do i = 1, margin_3
        	work_xyz(:,:,pub3+i,var%id) = work_xyz(:,:,pub3-i+1,var%id) 
       	end do
     
		end if
     
	end subroutine upper_boundary_slip_z_xyz


end module upper_boundary_slip
