!> @file
!!   Basic routines for calling NTPoly's solver routines.
!! @author
!!   Copyright (C) 2016 CheSS developers
!!
!!   This file is part of CheSS.
!!   
!!   CheSS is free software: you can redistribute it and/or modify
!!   it under the terms of the GNU Lesser General Public License as published by
!!   the Free Software Foundation, either version 3 of the License, or
!!   (at your option) any later version.
!!   
!!   CheSS is distributed in the hope that it will be useful,
!!   but WITHOUT ANY WARRANTY; without even the implied warranty of
!!   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!!   GNU Lesser General Public License for more details.
!!   
!!   You should have received a copy of the GNU Lesser General Public License
!!   along with CheSS.  If not, see <http://www.gnu.org/licenses/>.


!> Basic routines for calling NTPoly's solver routines.
module bigpoly_solvers
  use futile
  use sparsematrix_base, only : sparse_matrix, matrices
  use sparsematrix_types, only : mp
  use sparsematrix_timing
  implicit none
  private

  !> Public routines
  public :: ntpoly_solve
  public :: ntpoly_overlappowers

  contains

    !> Convert the required powers of the overlap matrix (-1/2, 1/2, -1)
    subroutine ntpoly_overlappowers(mat, val, out_mat, comm, &
        inv_val, sq_val, isq_val)
      !> The matrix to invert's sparsity pattern.
      type(sparse_matrix), intent(in):: mat
      !> The matrix values.
      type(matrices), intent(in) :: val
      !> Output matrix sparsity pattern.
      type(sparse_matrix), intent(inout):: out_mat
      !> The communicator to distribute on.
      integer, intent(inout) :: comm
      !> Output inverted values.
      type(matrices), intent(inout), optional :: inv_val
      !> Output square root values.
      type(matrices), intent(inout), optional :: sq_val
      !> Output inverse square root  values.
      type(matrices), intent(inout), optional :: isq_val

      call f_err_throw('Not properly linked with ntpoly')
    end subroutine ntpoly_overlappowers

    !> Solve for the density matrix using ntpoly.
    subroutine ntpoly_solve(hmat, hval, smat, sval, dmat, dval, &
        isq, nel, ebs, invert_overlap, comm)
      !> The Hamiltonian matrix.
      type(sparse_matrix), intent(in):: hmat
      !> The Hamiltonian values.
      type(matrices), intent(in) :: hval
      !> The overlap matrix.
      type(sparse_matrix), intent(inout):: smat
      !> The overlap values.
      type(matrices), intent(in) :: sval
      !> Output density matrix.
      type(sparse_matrix), intent(inout):: dmat
      !> Output density values.
      type(matrices), intent(inout) :: dval
      !> The inverse square root of the the overlap matrix (cache).
      type(matrices), intent(inout) :: isq
      !> The number of electrons.
      integer, intent(in) :: nel
      !> The energy value
      real(kind=mp),intent(out) :: ebs
      !> Whether we need to invert the overlap matrix.
      logical, intent(in) :: invert_overlap
      !> The communicator to distribute on.
      integer, intent(inout) :: comm

      call f_err_throw('Not properly linked with ntpoly')
    end subroutine ntpoly_solve

end module bigpoly_solvers
