!===============================================================================
!
! hmc_u.F90
!
!-------------------------------------------------------------------------------
!
! Copyright (C) 1998-2013 Hinnerk Stueben
!               2007-2013 Yoshifumi Nakamura 
!
! 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/>.
!
!-------------------------------------------------------------------------------
# include "defs.h"

!-------------------------------------------------------------------------------
subroutine hmc_integrator_q(p, p_qed, p_axion, para, conf, step)
  use module_field
  use typedef_hmc
  use module_switches
  use module_vol
  implicit none

  GENERATOR_FIELD,    intent(in)    :: p
  U1_GENERATOR_FIELD, intent(in)    :: p_qed
  AXION_MOMENTUM_FIELD, intent(in)    :: p_axion
  type(hmc_para),     intent(in)    :: para
  type(hmc_conf),     intent(inout) :: conf
  REAL,               intent(in)    :: step

  if (step == ZERO) return

  call hmc_u(p, gauge(1)%u, step)
  call hmc_a_qed(p_qed, conf%a_qed, step)
  call hmc_axion(p_axion, conf%axion, step)

  if (switches%boundary_sf) call schr_boundary_gauge(gauge(1)%u)

  call init_gaugelink_flag()

end

!-------------------------------------------------------------------------------
subroutine hmc_u(p, u, step)
  use module_vol
  implicit none

  GENERATOR_FIELD, intent(in) :: p
  GAUGE_FIELD,  intent(inout) :: u
  REAL,            intent(in) :: step
  GENERATOR                   :: q
  SU3                         :: v,q1,q2,f,b1,b2
  integer                     :: i, mu, eo, j

  DEBUG2S("Start: hmc_u")
  TIMING_START(timing_bin_hmc_u)

  do mu = 1, DIM
     do eo = EVEN, ODD
        !$omp parallel do private(j, q, v, q1,q2,f,b1,b2)
        do i = 1, VOLH
           do j = 1, NGEN
              q(j) = p(j, i, eo, mu) * step
           enddo
!           call gen2u(v, q)

           call gen2tlhermit(q1,q)
           call projection_su3(q1, v, q2, b1, b2, f, .false.)
           call u_update(u(:, :, i, eo, mu), v)  ! u = v * u
           call u_normalize(u(:, :, i, eo, mu))
        enddo
     enddo
  enddo
  
  TIMING_STOP(timing_bin_hmc_u)


  TIMING_START(timing_bin_hmc_xbound_g)
  call xbound_g_field(u)
  TIMING_STOP(timing_bin_hmc_xbound_g)

  DEBUG2S("End: hmc_u")
end

!-------------------------------------------------------------------------------
subroutine hmc_a_qed(p, a, step)

  use module_vol
  use module_switches
  implicit none

  U1_GENERATOR_FIELD, intent(in)    :: p
  U1_GENERATOR_FIELD, intent(inout) :: a
  REAL, intent(in)                  :: step
  integer                           :: i, mu, eo

  if (.not. switches%qed) return

  DEBUG2S("Start: hmc_a_qed")

  do mu = 1, DIM
     do eo = EVEN, ODD
        !$omp parallel do
        do i = 1, VOLH
           a(i, eo, mu) = a(i, eo, mu) + p(i, eo, mu) * step
        enddo
     enddo
  enddo

  call xbound_u1gen_field(a)

  DEBUG2S("End: hmc_a_qed")
end

!-------------------------------------------------------------------------------
subroutine init_gaugelink_flag()
  use module_action
  use module_field
  use module_stout_field
#ifdef BQCD_DDHMC
  use module_dd_evec
#endif
  implicit none

  gauge(1:size(gauge))%init = .true.
  if (associated(stout)) stout(1:size(stout))%init = .true.
  if (associated(clover))clover(1:n_clover)%init = .true.
#ifdef BQCD_DDHMC
  if (dd_evec   ) evecdd(   :,:)%fresh=.false.
  if (dd_evec_r4) evecdd_r4(:,:)%fresh=.false.
#endif
end

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