module gms_position_all
  use datatype
  use mem_manager
  implicit none
  interface pos_all_x
    module procedure pos_all_x_x
    module procedure pos_all_x_xy
    module procedure pos_all_x_xz
    module procedure pos_all_x_xyz
end interface

  interface pos_all_y
    module procedure pos_all_y_y
    module procedure pos_all_y_xy
    module procedure pos_all_y_yz
    module procedure pos_all_y_xyz
end interface

  interface pos_all_z
    module procedure pos_all_z_z
    module procedure pos_all_z_xz
    module procedure pos_all_z_yz
    module procedure pos_all_z_xyz
end interface

  interface pos_all_var_x
    module procedure pos_all_var_x_x
    module procedure pos_all_var_x_xy
    module procedure pos_all_var_x_xz
    module procedure pos_all_var_x_xyz
end interface

  interface pos_all_var_y
    module procedure pos_all_var_y_y
    module procedure pos_all_var_y_xy
    module procedure pos_all_var_y_yz
    module procedure pos_all_var_y_xyz
end interface

  interface pos_all_var_z
    module procedure pos_all_var_z_z
    module procedure pos_all_var_z_xz
    module procedure pos_all_var_z_yz
    module procedure pos_all_var_z_xyz
end interface

contains
  function pos_all_x_x(input) result(output)
    type(var_x), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis1:ub_axis1 - plb1- input%grid(1)) :: output

    if ( input%grid(1) == 0 ) then ! on
      do i = lb_axis1, ub_axis1 - plb1 ! margin = 1 => i = -1, nx + margin - 0
        output(i) = x_minimum + dx * i
      end do 
    else ! off
      do i = lb_axis1, ub_axis1 - plb1 - 1 ! margin = 1 => i = -1, nx + margin - 0 - 1  
        output(i) = x_minimum + dx * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_x_x

  function pos_all_var_x_x(input) result(output)
    type(var_x), intent(in) :: input
    integer :: i, new_id 
     type(var_x):: output

     call get_new_id_x(new_id)
     output%id = new_id
     output%grid(1) = input%grid(1)
     output%grid(2) = -1
     output%grid(3) = -1
      do i = lb_axis1+input%grid(1), ub_axis1 
        work_x(i,1,1,new_id) = x_minimum + dx * (i - plb1- input%grid(1) * 0.5D0)
      end do 
  end function pos_all_var_x_x

  function pos_all_x_xy(input) result(output)
    type(var_xy), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis1:ub_axis1 - plb1- input%grid(1)) :: output

    if ( input%grid(1) == 0 ) then 
      do i = lb_axis1, ub_axis1 - plb1
        output(i) = x_minimum + dx * i 
      end do 
    else  
      do i = lb_axis1, ub_axis1 - plb1 - 1 
        output(i) = x_minimum + dx * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_x_xy

  function pos_all_var_x_xy(input) result(output)
    type(var_xy), intent(in) :: input
    integer :: i, new_id 
     type(var_x):: output

     call get_new_id_x(new_id)
     output%id = new_id
     output%grid(1) = input%grid(1)
     output%grid(2) = -1
     output%grid(3) = -1
      do i = lb_axis1+input%grid(1), ub_axis1 
        work_x(i,1,1,new_id) = x_minimum + dx * (i - plb1- input%grid(1) * 0.5D0)
      end do 
  end function pos_all_var_x_xy

  function pos_all_x_xz(input) result(output)
    type(var_xz), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis1:ub_axis1 - plb1- input%grid(1)) :: output

    if ( input%grid(1) == 0 ) then 
      do i = lb_axis1, ub_axis1 - plb1
        output(i) = x_minimum + dx * i 
      end do 
    else  
      do i = lb_axis1, ub_axis1 - plb1 - 1 
        output(i) = x_minimum + dx * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_x_xz

  function pos_all_var_x_xz(input) result(output)
    type(var_xz), intent(in) :: input
    integer :: i, new_id 
     type(var_x):: output

     call get_new_id_x(new_id)
     output%id = new_id
     output%grid(1) = input%grid(1)
     output%grid(2) = -1
     output%grid(3) = -1
      do i = lb_axis1+input%grid(1), ub_axis1 
        work_x(i,1,1,new_id) = x_minimum + dx * (i - plb1- input%grid(1) * 0.5D0)
      end do 
  end function pos_all_var_x_xz

  function pos_all_x_xyz(input) result(output)
    type(var_xyz), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis1:ub_axis1 - plb1- input%grid(1)) :: output

    if ( input%grid(1) == 0 ) then 
      do i = lb_axis1, ub_axis1 - plb1
        output(i) = x_minimum + dx * i 
      end do 
    else  
      do i = lb_axis1, ub_axis1 - plb1 - 1
        output(i) = x_minimum + dx * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_x_xyz

  function pos_all_var_x_xyz(input) result(output)
    type(var_xyz), intent(in) :: input
    integer :: i, new_id 
     type(var_x):: output

     call get_new_id_x(new_id)
     output%id = new_id
     output%grid(1) = input%grid(1)
     output%grid(2) = -1
     output%grid(3) = -1
      do i = lb_axis1+input%grid(1), ub_axis1 
        work_x(i,1,1,new_id) = x_minimum + dx * (i - plb1- input%grid(1) * 0.5D0)
      end do 
  end function pos_all_var_x_xyz

  function pos_all_y_y(input) result(output)
    type(var_y), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis2:ub_axis2 - plb2- input%grid(2)) :: output

    if ( input%grid(2) == 0 ) then 
      do i = lb_axis2, ub_axis2 - plb2
        output(i) = y_minimum + dy * i 
      end do 
    else  
      do i = lb_axis2, ub_axis2 - plb2 - 1 
        output(i) = y_minimum + dy * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_y_y

  function pos_all_var_y_y(input) result(output)
    type(var_y), intent(in) :: input
    integer :: i, new_id 
     type(var_y):: output

     call get_new_id_y(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = input%grid(2)
     output%grid(3) = -1
      do i = lb_axis2+input%grid(2), ub_axis2 
        work_y(1,i,1,new_id) = y_minimum + dy * (i - plb2- input%grid(2) * 0.5D0)
      end do 
  end function pos_all_var_y_y

  function pos_all_y_xy(input) result(output)
    type(var_xy), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis2:ub_axis2 - plb2- input%grid(2)) :: output

    if ( input%grid(2) == 0 ) then 
      do i = lb_axis2, ub_axis2 - plb2
        output(i) = y_minimum + dy * i 
      end do 
    else  
      do i = lb_axis2, ub_axis2 - plb2 - 1 
        output(i) = y_minimum + dy * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_y_xy

  function pos_all_var_y_xy(input) result(output)
    type(var_xy), intent(in) :: input
    integer :: i, new_id 
     type(var_y):: output

     call get_new_id_y(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = input%grid(2)
     output%grid(3) = -1
      do i = lb_axis2+input%grid(2), ub_axis2 
        work_y(1,i,1,new_id) = y_minimum + dy * (i - plb2- input%grid(2) * 0.5D0)
      end do 
  end function pos_all_var_y_xy

  function pos_all_y_yz(input) result(output)
    type(var_yz), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis2:ub_axis2 - plb2- input%grid(2)) :: output

    if ( input%grid(2) == 0 ) then 
      do i = lb_axis2, ub_axis2 - plb2
        output(i) = y_minimum + dy * i 
      end do 
    else  
      do i = lb_axis2, ub_axis2 - plb2 - 1 
        output(i) = y_minimum + dy * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_y_yz

  function pos_all_var_y_yz(input) result(output)
    type(var_yz), intent(in) :: input
    integer :: i, new_id 
     type(var_y):: output

     call get_new_id_y(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = input%grid(2)
     output%grid(3) = -1
      do i = lb_axis2+input%grid(2), ub_axis2 
        work_y(1,i,1,new_id) = y_minimum + dy * (i - plb2- input%grid(2) * 0.5D0)
      end do 
  end function pos_all_var_y_yz

  function pos_all_y_xyz(input) result(output)
    type(var_xyz), intent(in) :: input
    integer :: i 
    real(8), dimension(lb_axis2:ub_axis2 - plb2- input%grid(2)) :: output

    if ( input%grid(2) == 0 ) then 
      do i = lb_axis2, ub_axis2 - plb2
        output(i) = y_minimum + dy * i 
      end do 
    else  
      do i = lb_axis2, ub_axis2 - plb2 - 1
        output(i) = y_minimum + dy * ( i + 0.5 )
      end do 
    end if 
  end function pos_all_y_xyz

  function pos_all_var_y_xyz(input) result(output)
    type(var_xyz), intent(in) :: input
    integer :: i, new_id 
     type(var_y):: output

     call get_new_id_y(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = input%grid(2)
     output%grid(3) = -1
      do i = lb_axis2+input%grid(2), ub_axis2 
        work_y(1,i,1,new_id) = y_minimum + dy * (i - plb2- input%grid(2) * 0.5D0)
      end do 
  end function pos_all_var_y_xyz

  function pos_all_z_z(input) result(output)
    type(var_z), intent(in) :: input
    integer :: i 
    real(8),dimension(lb_axis3:ub_axis3 - plb3- input%grid(3)) :: output

    if ( input%grid(3) == 0 ) then 
      do i = lb_axis3, ub_axis3 - plb3
        output(i) = z_minimum + dz * i 
      end do 
    else  
      do i = lb_axis2, ub_axis2 - plb2 - 1 
        output(i) = z_minimum + dz * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_z_z

  function pos_all_var_z_z(input) result(output)
    type(var_z), intent(in) :: input
    integer :: i, new_id 
     type(var_z):: output

     call get_new_id_z(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = -1
     output%grid(3) = input%grid(3)
      do i = lb_axis3+input%grid(3), ub_axis3 
        work_z(1,1,i,new_id) = z_minimum + dz * (i - plb3 - input%grid(3) * 0.5D0)
      end do 
  end function pos_all_var_z_z

  function pos_all_z_xz(input) result(output)
    type(var_xz), intent(in) :: input
    integer :: i 
    real(8),dimension(lb_axis3:ub_axis3 - plb3- input%grid(3)) :: output

    if ( input%grid(3) == 0 ) then 
      do i = lb_axis3, ub_axis3 - plb3 
        output(i) = z_minimum + dz * i 
      end do 
    else  
      do i = lb_axis3, ub_axis3 - plb3 - 1 
        output(i) = z_minimum + dz * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_z_xz

  function pos_all_var_z_xz(input) result(output)
    type(var_xz), intent(in) :: input
    integer :: i, new_id 
     type(var_z):: output

     call get_new_id_z(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = -1
     output%grid(3) = input%grid(3)
      do i = lb_axis3+input%grid(3), ub_axis3 
        work_z(1,1,i,new_id) = z_minimum + dz * (i - plb3 - input%grid(3) * 0.5D0)
      end do 
  end function pos_all_var_z_xz

  function pos_all_z_yz(input) result(output)
    type(var_yz), intent(in) :: input
    integer :: i 
    real(8),dimension(lb_axis3:ub_axis3 - plb3- input%grid(3)) :: output

    if ( input%grid(3) == 0 ) then 
      do i = lb_axis3, ub_axis3 - plb3 
        output(i) = z_minimum + dz * i 
      end do 
    else  
      do i = lb_axis3, ub_axis3 - plb3 - 1 
        output(i) = z_minimum + dz * ( i + 0.5 ) 
      end do 
    end if 
  end function pos_all_z_yz

  function pos_all_var_z_yz(input) result(output)
    type(var_yz), intent(in) :: input
    integer :: i, new_id 
     type(var_z):: output

     call get_new_id_z(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = -1
     output%grid(3) = input%grid(3)
      do i = lb_axis3+input%grid(3), ub_axis3 
        work_z(1,1,i,new_id) = z_minimum + dz * (i - plb3 - input%grid(3) * 0.5D0)
      end do 
  end function pos_all_var_z_yz

  function pos_all_z_xyz(input) result(output)
    type(var_xyz), intent(in) :: input
    integer :: i 
    real(8),dimension(lb_axis3:ub_axis3 - plb3- input%grid(3)) :: output

    if ( input%grid(3) == 0 ) then 
      do i = lb_axis3, ub_axis3 - plb3 
        output(i) = z_minimum + dz * i 
      end do 
    else  
      do i = lb_axis3, ub_axis3 - plb3 + 1
        output(i) = z_minimum + dz * ( i + 0.5 )
      end do 
    end if 
  end function pos_all_z_xyz

  function pos_all_var_z_xyz(input) result(output)
    type(var_xyz), intent(in) :: input
    integer :: i, new_id 
     type(var_z):: output

     call get_new_id_z(new_id)
     output%id = new_id
     output%grid(1) = -1
     output%grid(2) = -1
     output%grid(3) = input%grid(3)
      do i = lb_axis3+input%grid(3), ub_axis3 
        work_z(1,1,i,new_id) = z_minimum + dz * (i - plb3 - input%grid(3) * 0.5D0)
      end do 
  end function pos_all_var_z_xyz

end module gms_position_all
