!===============================================================================
!
! cg_wrapper.F90
!
!-------------------------------------------------------------------------------
!
! Copyright (C) 2012-2016 Hinnerk Stueben
!
! This file is part of BQCD -- Berlin Quantum ChromoDynamics program
!
! BQCD is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! BQCD 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 General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with BQCD.  If not, see <http://www.gnu.org/licenses/>.
!
!-------------------------------------------------------------------------------
# define LANGUAGE_FORTRAN
# include "defs.h"

!-------------------------------------------------------------------------------
# define TRACE_NAME cg_wrapper
!-------------------------------------------------------------------------------
subroutine cg_wrapper(which_matrix, x, b, para, conf, iterations) 

  use module_vol
  use module_cg       ! contains cg_para%... : algorithmic parameters
  use module_cg_conf  
  use module_cg_para, cg_para2 => cg_para    ! physical parameters
  use module_cg_procs
  use typedef_hmc
  use typedef_clover

  implicit none
  integer, intent(in)          :: which_matrix
  SPINCOL_FIELD, intent(inout) :: x
  SPINCOL_FIELD, intent(in)    :: b
  type(hmc_para), intent(in), target :: para
  type(hmc_conf), intent(in)   :: conf
  integer, intent(out)         :: iterations

  REAL :: residual

  TRACE_ENTRY

  cg_para2 => para
  residual = real(cg_para%rest_mc, kind=RKIND)

  call cg_init_modules()

  call cg_procs%copyin_gauge(cg_conf%u, conf%u)

  call cg_procs%copyin_spincol(cg_conf%in, b)
  call cg_procs%copyin_spincol(cg_conf%out, x)

  call cg_procs%copyin_clover(cg_conf%c_even, conf%a(1, 1, EVEN))
  call cg_procs%copyin_clover(cg_conf%c_odd,  conf%i(1, 1, ODD))

!!  call cg_test(x, b, conf%u, conf%a, conf%i)

  call cg_procs%kernel(cg_conf%out, cg_conf%in, which_matrix, iterations, residual) 

  call cg_procs%copyout_spincol(x, cg_conf%out)

  TRACE_RETURN
end

!===============================================================================
