module same_value_boundary
	use datatype
	use model_info
	use mem_manager
	implicit none

	interface same_value_boundary_x 
		module procedure same_value_boundary_x_x
		module procedure same_value_boundary_x_xy
		module procedure same_value_boundary_x_xz
		module procedure same_value_boundary_x_xyz
	end interface

	interface same_value_boundary_y 
		module procedure same_value_boundary_y_y
		module procedure same_value_boundary_y_xy
		module procedure same_value_boundary_y_yz
		module procedure same_value_boundary_y_xyz
	end interface

	interface same_value_boundary_z 
		module procedure same_value_boundary_z_z
		module procedure same_value_boundary_z_xz
		module procedure same_value_boundary_z_yz
		module procedure same_value_boundary_z_xyz
	end interface

contains
	subroutine same_value_boundary_x_x(var, input1, input2) 
		type(var_x), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(1) == 0) then 
			do i = 1, margin_1
				work_x(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_x(plb1+i,:,:,var%id) 
				work_x(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_x(pub1-i,:,:,var%id) 
			end do

		else if (var%grid(1) == 1) then 
			do i = 0, margin_1
				work_x(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_x(plb1+i+1,:,:,var%id) 
			end do
			do i = 1, margin_1
				work_x(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_x(pub1-i+1,:,:,var%id) 
			end do
  
		end if

	end subroutine same_value_boundary_x_x


	subroutine same_value_boundary_x_xy(var, input1, input2) 
		type(var_xy), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(1) == 0) then 
			do i = 1, margin_1
				work_xy(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_xy(plb1+i,:,:,var%id) 
				work_xy(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_xy(pub1-i,:,:,var%id) 
			end do

		else if (var%grid(1) == 1) then 
			do i = 0, margin_1
				work_xy(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_xy(plb1+i+1,:,:,var%id) 
			end do
			do i = 1, margin_1
				work_xy(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_xy(pub1-i+1,:,:,var%id) 
			end do
		
		end if

	end subroutine same_value_boundary_x_xy


	subroutine same_value_boundary_x_xz(var, input1, input2) 
		type(var_xz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(1) == 0) then
			do i = 1, margin_1
	   		work_xz(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_xz(plb1+i,:,:,var%id) 
	        work_xz(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_xz(pub1-i,:,:,var%id) 
			end do	
	
		else if (var%grid(1) == 1) then 
			do i = 0, margin_1
				work_xz(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_xz(plb1+i+1,:,:,var%id) 
			end do
			do i = 1, margin_1
				work_xz(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_xz(pub1-i+1,:,:,var%id) 
			end do
		
		endif
   
  end subroutine same_value_boundary_x_xz


	subroutine same_value_boundary_x_xyz(var, input1, input2) 
		type(var_xyz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i
		
		if (var%grid(1) == 0) then 
			do i = 1, margin_1
				work_xyz(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_xyz(plb1+i,:,:,var%id) 
				work_xyz(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_xyz(pub1-i,:,:,var%id) 
			end do

		else if (var%grid(1) == 1) then
			do i = 0, margin_1
				work_xyz(plb1-i,:,:,var%id) = 2.0D0 * input1 - work_xyz(plb1+i+1,:,:,var%id) 
			end do
			do i = 1, margin_1
				work_xyz(pub1+i,:,:,var%id) = 2.0D0 * input2 - work_xyz(pub1-i+1,:,:,var%id) 
			end do
		
		endif

	end subroutine same_value_boundary_x_xyz


	subroutine same_value_boundary_y_y(var, input1, input2) 
		type(var_y), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(2) == 0) then 
			do i = 1, margin_2
				work_y(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_y(:,plb2+i,:,var%id) 
				work_y(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_y(:,pub2-i,:,var%id) 
			end do

		else if (var%grid(2) == 1) then 
			do i = 0, margin_2
				work_y(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_y(:,plb2+i+1,:,var%id) 
			end do
			do i = 1, margin_2
				work_y(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_y(:,pub2-i+1,:,var%id) 
			end do

		end if
  
	end subroutine same_value_boundary_y_y


	subroutine same_value_boundary_y_xy(var, input1, input2) 
		type(var_xy), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(2) == 0) then 
			do i = 1, margin_2
				work_xy(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_xy(:,plb2+i,:,var%id) 
				work_xy(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_xy(:,pub2-i,:,var%id) 
			end do

		else if (var%grid(2) == 1) then 
			do i = 0, margin_2
				work_xy(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_xy(:,plb2+i+1,:,var%id) 
			end do
			do i = 1, margin_2
				work_xy(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_xy(:,pub2-i+1,:,var%id) 
			end do
		
		endif

	end subroutine same_value_boundary_y_xy


	subroutine same_value_boundary_y_yz(var, input1, input2) 
		type(var_yz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(2) == 0) then 
			do i = 1, margin_2
				work_yz(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_yz(:,plb2+i,:,var%id) 
				work_yz(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_yz(:,pub2-i,:,var%id) 
			end do

		else if (var%grid(2) == 1) then 
			do i = 0, margin_2
				work_yz(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_yz(:,plb2+i+1,:,var%id) 
			end do
			do i = 1, margin_2
				work_yz(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_yz(:,pub2-i+1,:,var%id) 
			end do

		end if

	end subroutine same_value_boundary_y_yz


	subroutine same_value_boundary_y_xyz(var, input1, input2) 
		type(var_xyz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(2) == 0) then 
			do i = 1, margin_2
				work_xyz(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_xyz(:,plb2+i,:,var%id) 
				work_xyz(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_xyz(:,pub2-i,:,var%id) 
			end do

		else if (var%grid(2) == 1) then 
			do i = 0, margin_2
				work_xyz(:,plb2-i,:,var%id) = 2.0D0 * input1 - work_xyz(:,plb2+i+1,:,var%id) 
			end do
			do i = 1, margin_2
				work_xyz(:,pub2+i,:,var%id) = 2.0D0 * input2 - work_xyz(:,pub2-i+1,:,var%id) 
			end do
	
		end if

	end subroutine same_value_boundary_y_xyz


	subroutine same_value_boundary_z_z(var, input1, input2) 
		type(var_z), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(3) == 0) then 
			do i = 1, margin_3
				work_z(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_z(:,:,plb3+i,var%id) 
				work_z(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_z(:,:,pub3-i,var%id) 
			end do

		else if (var%grid(3) == 1) then 
			do i = 0, margin_3
				work_z(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_z(:,:,plb3+i+1,var%id) 
			end do
			do i = 1, margin_3
				work_z(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_z(:,:,pub3-i+1,var%id) 
			end do

		end if

  end subroutine same_value_boundary_z_z


	subroutine same_value_boundary_z_xz(var, input1, input2) 
		type(var_xz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(3) == 0) then 
			do i = 1, margin_3
				work_xz(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_xz(:,:,plb3+i,var%id) 
				work_xz(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_xz(:,:,pub3-i,var%id) 
			end do

		else if (var%grid(3) == 1) then 
			do i = 0, margin_3
				work_xz(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_xz(:,:,plb3+i+1,var%id) 
			end do
			do i = 1, margin_3
				work_xz(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_xz(:,:,pub3-i+1,var%id) 
			end do

		end if

	end subroutine same_value_boundary_z_xz


	subroutine same_value_boundary_z_yz(var, input1, input2) 
		type(var_yz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(3) == 0) then 
			do i = 1, margin_3
				work_yz(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_yz(:,:,plb3+i,var%id) 
				work_yz(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_yz(:,:,pub3-i,var%id) 
			end do

		else if (var%grid(3) == 1) then 
			do i = 0, margin_3
				work_yz(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_yz(:,:,plb3+i+1,var%id) 
			end do
			do i = 1, margin_3
				work_yz(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_yz(:,:,pub3-i+1,var%id) 
			end do

		end if

	end subroutine same_value_boundary_z_yz


	subroutine same_value_boundary_z_xyz(var, input1, input2) 
		type(var_xyz), intent(inout) :: var
		real(8) :: input1, input2
		integer :: i

		if (var%grid(3) == 0) then 
			do i = 1, margin_3
				work_xyz(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_xyz(:,:,plb3+i,var%id) 
				work_xyz(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_xyz(:,:,pub3-i,var%id) 
			end do

		else if (var%grid(3) == 1) then 
			do i = 0, margin_3
				work_xyz(:,:,plb3-i,var%id) = 2.0D0 * input1 - work_xyz(:,:,plb3+i+1,var%id) 
			end do
			do i = 1, margin_3
				work_xyz(:,:,pub3+i,var%id) = 2.0D0 * input2 - work_xyz(:,:,pub3-i+1,var%id) 
			end do

		end if

	end subroutine same_value_boundary_z_xyz	

end module same_value_boundary
