2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! Copyright (C) 2001 PWSCF 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 star_q (xq, at, bg, ibrav, symm_type, nat, tau, ityp, &
|
|
|
|
nr1, nr2, nr3, nsym, s, invs, irt, rtau, nq, sxq, isq, imq, noinv, &
|
|
|
|
modenum)
|
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
! generate the star of q vectors that are equivalent to the input one
|
|
|
|
! and return their list along with the symmetry ops. needed to obtain
|
|
|
|
! them.
|
|
|
|
! NB: output values of symmetry arrays (nsym, s, rtau, irt) are those
|
|
|
|
! appropriate to the crystal symmetry (not to the small-qroup of q).
|
|
|
|
! User is responsible for calling this routine with different array-name
|
|
|
|
! if information for both symmetry-groups needs to be kept
|
|
|
|
!
|
|
|
|
#include "machine.h"
|
|
|
|
use parameters, only : DP
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
2003-01-20 05:58:50 +08:00
|
|
|
!-input variables
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: ibrav, nat, ityp (nat), modenum, nr1, nr2, nr3
|
2003-01-20 05:58:50 +08:00
|
|
|
! input: bravais lattice index
|
|
|
|
! input: number of atom
|
|
|
|
! input: atomic type
|
|
|
|
! input: the mode to be done
|
|
|
|
! input: fft grid dimensions
|
2003-02-08 00:04:36 +08:00
|
|
|
real(kind=DP) :: xq (3), at (3, 3), bg (3, 3), tau (3, nat)
|
2003-01-20 05:58:50 +08:00
|
|
|
! input: q vector
|
|
|
|
! input: direct lattice vectors
|
|
|
|
! input: reciprocal lattice vectors
|
|
|
|
! input: coordinates of atomic positions
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
character (len=9) :: symm_type
|
2003-01-20 05:58:50 +08:00
|
|
|
! input: 'cubic' or 'hexagonal' when ibrav=0
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
logical :: noinv
|
2003-01-20 05:58:50 +08:00
|
|
|
! input: if true eliminates symmetries z <-> -z
|
|
|
|
!-output variables
|
|
|
|
integer :: nsym, s (3, 3, 48), invs (48), irt (48, nat), nq, isq ( &
|
|
|
|
48), imq
|
|
|
|
! output: number of symmetry operations
|
|
|
|
! output: the first nq matrices are those that
|
|
|
|
! generate the star of q startting from it
|
|
|
|
! list of inverse operation indices
|
|
|
|
! output: for each atom gives the rotated atom
|
|
|
|
! output: degeneracy of the star of q
|
|
|
|
! output: index of q in the star for a given sym
|
|
|
|
! output: index of -q in the star (0 if not pres
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
real(kind=DP) :: rtau (3, 48, nat), sxq (3, 48)
|
2003-01-20 05:58:50 +08:00
|
|
|
! output: for eaxh atom and rotation gives th
|
|
|
|
! R vector involved
|
|
|
|
! output: list of vectors in the star of q
|
|
|
|
!-local variables
|
|
|
|
integer :: nsq (48), nrot, isym, jsym, ism1, table (48, 48), &
|
|
|
|
iq, i, j, nks, npk, izero
|
|
|
|
! number of symmetry ops. of bravais lattice.
|
|
|
|
! counters on symmetry ops.
|
|
|
|
! index of inverse of isym
|
|
|
|
! group table
|
|
|
|
! counter on q-vectors
|
|
|
|
! generic counter
|
|
|
|
! number of dummy k-points
|
|
|
|
! maximum allowed number of dummy k-points
|
|
|
|
! dummy (zero) value of iswitch passed to sgama
|
|
|
|
real(kind=DP) :: saq (3, 48), aq (3), raq (3), ftau (3, 48), xk0 (3), &
|
|
|
|
wk, zero (3)
|
|
|
|
! auxiliary list of q (crystal coordinates)
|
|
|
|
! input q in crystal coordinates
|
|
|
|
! rotated q in crystal coordinates
|
|
|
|
! coordinates of fractionary translations
|
|
|
|
! dummy k-points list
|
|
|
|
! a zero vector: used in eqvect and as dummy
|
|
|
|
! q-vector in sgama
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
logical :: invsym, minus_q, nosym, eqvect, sym (48)
|
2003-01-20 05:58:50 +08:00
|
|
|
! .t. if the crystal has inversion
|
|
|
|
! dummy output from sgama
|
|
|
|
! input for sgama
|
|
|
|
! function used to compare two vectors
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
character (len=45) :: sname (48)
|
2003-01-20 05:58:50 +08:00
|
|
|
! name of the rotat. part of each selected symmet
|
|
|
|
! operation
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
external eqvect
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! initialize dummy k-point list and zero vector
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
izero = 0
|
|
|
|
npk = 1
|
|
|
|
nks = 1
|
|
|
|
wk = 1.d0
|
|
|
|
call setv (3, 0.d0, xk0, 1)
|
|
|
|
call setv (3, 0.d0, zero, 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! generate transformation matrices for the bravais lattice
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (ibrav.eq.4.or.ibrav.eq.5) then
|
|
|
|
call hexsym (at, s, sname, nrot)
|
|
|
|
elseif (ibrav.ge.1.and.ibrav.le.14) then
|
|
|
|
call cubicsym (at, s, sname, nrot)
|
|
|
|
elseif (ibrav.eq.0) then
|
|
|
|
if (symm_type.eq.'cubic') call cubicsym (at, s, sname, nrot)
|
|
|
|
if (symm_type.eq.'hexagonal') call hexsym (at, s, sname, nrot)
|
|
|
|
else
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore ('setup', 'wrong ibrav', 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
if (noinv) then
|
|
|
|
jsym = 0
|
|
|
|
do isym = 1, nrot
|
2003-01-20 05:58:50 +08:00
|
|
|
if (s (1, 3, isym) .eq.0.and.s (3, 1, isym) .eq.0.and.s (2, 3, &
|
|
|
|
isym) .eq.0.and.s (3, 2, isym) .eq.0.and.s (3, 3, isym) .eq.1) &
|
|
|
|
then
|
2003-02-08 00:04:36 +08:00
|
|
|
jsym = jsym + 1
|
|
|
|
do i = 1, 3
|
|
|
|
do j = 1, 3
|
|
|
|
s (i, j, jsym) = s (i, j, isym)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
sname (jsym) = sname (isym)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
nrot = jsym
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
endif
|
|
|
|
!
|
|
|
|
! extract from it the crystal symmetry group by calling sgama
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
nosym = .false.
|
2003-01-20 05:58:50 +08:00
|
|
|
call sgama (nrot, nat, s, sname, at, bg, tau, ityp, nsym, nr1, &
|
|
|
|
nr2, nr3, irt, ftau, npk, nks, xk0, wk, invsym, minus_q, zero, &
|
|
|
|
izero, nosym, modenum)
|
2003-02-08 00:04:36 +08:00
|
|
|
do isym = 1, nsym
|
|
|
|
sym (isym) = .true.
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
call sgam_ph (at, bg, nsym, s, irt, tau, rtau, nat, sym)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! computes the inverse of each matrix
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call multable (nsym, s, table)
|
|
|
|
do isym = 1, nsym
|
|
|
|
do jsym = 1, nsym
|
|
|
|
if (table (isym, jsym) .eq.1) invs (isym) = jsym
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! go to crystal coordinates
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do i = 1, 3
|
2003-01-20 05:58:50 +08:00
|
|
|
aq (i) = xq (1) * at (1, i) + xq (2) * at (2, i) + xq (3) * at (3, &
|
|
|
|
i)
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! create the list of rotated q
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do i = 1, 48
|
|
|
|
nsq (i) = 0
|
|
|
|
isq (i) = 0
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
nq = 0
|
|
|
|
do isym = 1, nsym
|
|
|
|
ism1 = invs (isym)
|
|
|
|
do i = 1, 3
|
2003-01-20 05:58:50 +08:00
|
|
|
raq (i) = s (i, 1, ism1) * aq (1) + s (i, 2, ism1) * aq (2) &
|
|
|
|
+ s (i, 3, ism1) * aq (3)
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
do i = 1, 3
|
2003-01-20 05:58:50 +08:00
|
|
|
sxq (i, 48) = bg (i, 1) * raq (1) + bg (i, 2) * raq (2) + bg (i, &
|
|
|
|
3) * raq (3)
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
do iq = 1, nq
|
|
|
|
if (eqvect (raq, saq (1, iq), zero) ) then
|
|
|
|
isq (isym) = iq
|
|
|
|
nsq (iq) = nsq (iq) + 1
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
if (isq (isym) .eq.0) then
|
|
|
|
nq = nq + 1
|
|
|
|
nsq (nq) = 1
|
|
|
|
isq (isym) = nq
|
|
|
|
call DCOPY (3, raq, 1, saq (1, nq), 1)
|
|
|
|
do i = 1, 3
|
2003-01-20 05:58:50 +08:00
|
|
|
sxq (i, nq) = bg (i, 1) * saq (1, nq) + bg (i, 2) * saq (2, nq) &
|
|
|
|
+ bg (i, 3) * saq (3, nq)
|
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! set imq index if needed and check star degeneracy
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
call DCOPY (3, aq, 1, raq, 1)
|
|
|
|
call DSCAL (3, - 1.d0, raq, 1)
|
|
|
|
imq = 0
|
|
|
|
do iq = 1, nq
|
|
|
|
if (eqvect (raq, saq (1, iq), zero) ) imq = iq
|
2003-02-21 22:57:00 +08:00
|
|
|
if (nsq (iq) * nq.ne.nsym) call errore ('star_q', 'wrong degenerac &
|
2003-01-20 05:58:50 +08:00
|
|
|
&y', iq)
|
|
|
|
enddo
|
|
|
|
!
|
|
|
|
! writes star of q
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
write (6, * )
|
|
|
|
write (6, '(5x,a,i4)') 'Number of q in the star = ', nq
|
|
|
|
write (6, '(5x,a)') 'List of q in the star:'
|
2003-01-20 05:58:50 +08:00
|
|
|
write (6, '(7x,i4,3f14.9)') (iq, (sxq (i, iq) , i = 1, 3) , iq = &
|
|
|
|
1, nq)
|
2003-02-08 00:04:36 +08:00
|
|
|
if (imq.eq.0) then
|
|
|
|
write (6, '(5x,a)') 'In addition there is the -q list: '
|
2003-01-20 05:58:50 +08:00
|
|
|
write (6, '(7x,i4,3f12.9)') (iq, ( - sxq (i, iq) , i = 1, 3) , &
|
|
|
|
iq = 1, nq)
|
|
|
|
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine star_q
|