mirror of https://gitlab.com/QEF/q-e.git
110 lines
3.6 KiB
Fortran
110 lines
3.6 KiB
Fortran
!
|
|
! Copyright (C) 2001-2008 Quantum ESPRESSO group
|
|
! This file is distributed under the terms of the
|
|
! GNU General Public License. See the file `License'
|
|
! in the root directory of the present distribution,
|
|
! or http://www.gnu.org/copyleft/gpl.txt .
|
|
!
|
|
!---------------------------------------------------------------------
|
|
subroutine sym_dmage (dvsym)
|
|
!---------------------------------------------------------------------
|
|
!! This routine symmetrize the change of the potential due to an
|
|
!! electric field perturbation. It is assumed that the perturbations
|
|
!! are on the basis of the crystal.
|
|
!
|
|
USE kinds, only : DP
|
|
USE cell_base,only : at, bg
|
|
USE fft_base, only : dfftp
|
|
USE symm_base,only : nsym, sname, s, ft, t_rev, invs
|
|
USE lsda_mod, only : nspin
|
|
!
|
|
implicit none
|
|
!
|
|
complex(DP) :: dvsym(dfftp%nr1x,dfftp%nr2x,dfftp%nr3x,nspin,3)
|
|
!! the potential to symmetrize
|
|
!
|
|
! ... local variables
|
|
!
|
|
complex(DP), allocatable :: aux (:,:,:,:,:)
|
|
complex(DP) :: dmags(3,3), mag(3), magrot(3)
|
|
! auxiliary quantity
|
|
integer :: ftau(3,nsym), s_scaled(3,3,nsym)
|
|
integer :: is, ri, rj, rk, i, j, k, irot, ipol, jpol, kpol
|
|
! counter on spin polarization
|
|
! the rotated points
|
|
! the point
|
|
! counter on symmetries
|
|
! counter on polarizations
|
|
|
|
do is = 2,4
|
|
do ipol = 1, 3
|
|
dvsym(:,:,:,is,ipol) = CMPLX(DBLE(dvsym(:,:,:,is,ipol)),0.d0,kind=DP)
|
|
end do
|
|
end do
|
|
if (nsym == 1) return
|
|
allocate (aux(dfftp%nr1x , dfftp%nr2x , dfftp%nr3x , 3, 3))
|
|
|
|
do is = 2, 4
|
|
do ipol = 1, 3
|
|
aux(:,:,:,is-1,ipol) = dvsym(:,:,:,is,ipol)
|
|
dvsym(:,:,:,is,ipol) = (0.d0, 0.d0)
|
|
enddo
|
|
enddo
|
|
!
|
|
! symmmetrize
|
|
!
|
|
CALL scale_sym_ops( nsym, s, ft, dfftp%nr1, dfftp%nr2, dfftp%nr3, &
|
|
s_scaled, ftau )
|
|
do k = 1, dfftp%nr3
|
|
do j = 1, dfftp%nr2
|
|
do i = 1, dfftp%nr1
|
|
do irot = 1, nsym
|
|
call rotate_grid_point (s_scaled(1,1,irot), ftau(1,irot), &
|
|
i, j, k, dfftp%nr1, dfftp%nr2, dfftp%nr3, ri, rj, rk)
|
|
!
|
|
! rotate_grid_point finds the rotated of i,j,k with S^-1
|
|
!
|
|
dmags=(0.d0,0.d0)
|
|
do ipol = 1, 3
|
|
do is=1,3
|
|
do jpol = 1, 3
|
|
dmags(is,ipol)=dmags(is,ipol) + &
|
|
s(ipol,jpol,irot) * aux(ri,rj,rk,is,jpol)
|
|
enddo
|
|
enddo
|
|
do kpol = 1, 3
|
|
mag(kpol)=bg(1,kpol)*dmags(1,ipol) + &
|
|
bg(2,kpol)*dmags(2,ipol) + &
|
|
bg(3,kpol)*dmags(3,ipol)
|
|
enddo
|
|
! rotate the magnetic moment
|
|
do kpol = 1, 3
|
|
magrot(kpol) = s(1,kpol,invs(irot))*mag(1) + &
|
|
s(2,kpol,invs(irot))*mag(2) + &
|
|
s(3,kpol,invs(irot))*mag(3)
|
|
enddo
|
|
if (sname(irot)(1:3)=='inv') magrot=-magrot
|
|
if(t_rev(irot).eq.1) magrot=-magrot
|
|
! go back to cartesian coordinates
|
|
do kpol = 1, 3
|
|
mag(kpol)=at(kpol,1)*magrot(1) + &
|
|
at(kpol,2)*magrot(2) + &
|
|
at(kpol,3)*magrot(3)
|
|
enddo
|
|
dvsym(i,j,k,2,ipol) = dvsym(i,j,k,2,ipol) + mag(1)
|
|
dvsym(i,j,k,3,ipol) = dvsym(i,j,k,3,ipol) + mag(2)
|
|
dvsym(i,j,k,4,ipol) = dvsym(i,j,k,4,ipol) + mag(3)
|
|
enddo
|
|
enddo
|
|
enddo
|
|
enddo
|
|
enddo
|
|
do is=2,4
|
|
do ipol = 1, 3
|
|
dvsym(:,:,:,is,ipol) = dvsym(:,:,:,is,ipol) / DBLE(nsym)
|
|
enddo
|
|
enddo
|
|
deallocate (aux)
|
|
return
|
|
end subroutine sym_dmage
|