!===============================================================================
!
! qed_conf.F90 - operations on QED/U1 gauge field
!
!-------------------------------------------------------------------------------
!
! Copyright 2013 Hinnerk Stueben
!           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 init_a_qed(a, start)  ! initialization of a-field (at trajectory 0)

  use module_vol
  use module_switches
  implicit none

  U1_GENERATOR_FIELD :: a
  integer :: start

  if (.not. switches%qed) return

  select case (start)
     case (START_HOT)
        call qed_conf_hot(a)
     case (START_COLD)
        call qed_conf_cold(a)
     case default
        call die("init_a_qed(): don't know how to start")
  end select

  call xbound_u1gen_field(a)
  !!!call d_u1g_init(a)

end

!-------------------------------------------------------------------------------
subroutine qed_conf_zero(a)

  use module_vol
  use module_switches
  implicit none

  U1_GENERATOR_FIELD :: a
  integer :: i, eo, mu

  if (.not. switches%qed) return

  do mu = 1, DIM
     do eo = EVEN, ODD
        !$omp parallel do
        do i = 1, volh
           a(i, eo, mu) = ZERO
        enddo
     enddo
  enddo
end

!-------------------------------------------------------------------------------
subroutine qed_conf_cold(a)  ! cold start

  use module_vol
  use module_switches
  implicit none

  U1_GENERATOR_FIELD :: a

  if (.not. switches%qed) return

  call qed_conf_zero(a)
end

!-------------------------------------------------------------------------------
subroutine qed_conf_hot(a)  ! hot start

  use module_vol
  use module_switches
  implicit none

  U1_GENERATOR_FIELD :: a
  integer :: eo, mu

  if (.not. switches%qed) return

  do mu = 1, DIM
     do eo = EVEN, ODD
        call ran_vector_volh(a(1, eo, mu), eo)
     enddo
  enddo

end

!-------------------------------------------------------------------------------
subroutine qed_conf_copy(out, in)

  use module_vol
  use module_switches
  implicit none
  U1_GENERATOR_FIELD, intent(out) :: out
  U1_GENERATOR_FIELD, intent(in)  :: in
  integer :: i, eo, mu
  
  if (.not. switches%qed) return

  do mu = 1, DIM
     do eo = EVEN, ODD
        !$omp parallel do
        do i = 1, volh_tot
           out(i, eo, mu) = in(i, eo, mu)
        enddo
     enddo
  enddo

end

!-------------------------------------------------------------------------------
subroutine qed_qcd_mult(u, a, q) !! U = exp(i -Q a) * U

  use module_vol
  use module_switches
  implicit none
  GAUGE_FIELD, intent(inout) :: u
  U1_GENERATOR_FIELD, intent(in)  :: a
  REAL, intent(in) :: q
  COMPLEX :: u1
  integer :: i, eo, mu, c1, c2
  
  if (.not. switches%qed) return

  do mu = 1, DIM
     do eo = EVEN, ODD
        !$omp parallel do private(u1, c1, c2)
        do i = 1, volh_tot
           u1 = dcmplx( cos(q * a(i, eo, mu)) , -sin(q * a(i, eo, mu)))
           do c1 = 1, NCOL
           do c2 = 1, NCOL
              u(c1, c2, i, eo, mu) = u1 * u(c1, c2, i, eo, mu)
           enddo
           enddo
        enddo
     enddo
  enddo

end

!-------------------------------------------------------------------------------
subroutine qed_gen_m_force(p, uuu)
  use module_field
  use module_vol
  use module_switches
  implicit none

  U1_GENERATOR_FIELD, intent(inout) :: p
  GAUGE_FIELD, intent(in) :: uuu
  integer :: mu, eo, i
  SU3 :: w

  if (.not. switches%qed) return
  if (switches%boundary_sf) call schr_boundary_zero3(uuu)

  !! gauge(2)%u is already flipped, 
  !! here I flip it again to get original exp(i -Q a) * U
  call flip_bc(gauge(2)%u)
  do mu = 1, DIM
     do eo = EVEN, ODD
        !$omp parallel do private(w)
        do i = 1, volh
           call uu(w, gauge(2)%u(1, 1, i, eo, mu), uuu(1, 1, i, eo, mu))
           p(i, eo, mu) = p(i, eo, mu)  +  gauge(2)%em_charge * (Im(w(1,1)) + Im(w(2,2)) + Im(w(3,3)))
        enddo
     enddo
  enddo
  !! flip again for following fermionic calculation
  call flip_bc(gauge(2)%u)

end

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