The Elk Code
findsymlat.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2002-2007 J. K. Dewhurst, S. Sharma and C. Ambrosch-Draxl.
3 ! This file is distributed under the terms of the GNU Lesser General Public
4 ! License. See the file COPYING for license details.
5 
6 !BOP
7 ! !ROUTINE: findsymlat
8 ! !INTERFACE:
9 subroutine findsymlat
10 ! !USES:
11 use modmain
12 use modtddft
13 ! !DESCRIPTION:
14 ! Finds the point group symmetries which leave the Bravais lattice invariant.
15 ! Let $A$ be the matrix consisting of the lattice vectors in columns, then
16 ! $$ g=A^{\rm T}A $$
17 ! is the metric tensor. Any $3\times 3$ matrix $S$ with elements $-1$, 0 or 1
18 ! is a point group symmetry of the lattice if $\det(S)$ is $-1$ or 1, and
19 ! $$ S^{\rm T}gS=g. $$
20 ! The first matrix in the set returned is the identity.
21 !
22 ! !REVISION HISTORY:
23 ! Created January 2003 (JKD)
24 ! Removed arguments and simplified, April 2007 (JKD)
25 !EOP
26 !BOC
27 implicit none
28 ! local variables
29 integer md,sym(3,3),its,i,j
30 integer i11,i12,i13,i21,i22,i23,i31,i32,i33
31 real(8) s(3,3),g(3,3),sgs(3,3),sc(3,3)
32 real(8) c(3,3),v(3),t1
33 ! determine metric tensor
34 call r3mtm(avec,avec,g)
35 ! loop over all possible symmetry matrices
36 nsymlat=0
37 do i11=-1,1; do i12=-1,1; do i13=-1,1
38 do i21=-1,1; do i22=-1,1; do i23=-1,1
39 do i31=-1,1; do i32=-1,1; do i33=-1,1
40  sym(1,1)=i11; sym(1,2)=i12; sym(1,3)=i13
41  sym(2,1)=i21; sym(2,2)=i22; sym(2,3)=i23
42  sym(3,1)=i31; sym(3,2)=i32; sym(3,3)=i33
43 ! determinant of matrix
44  md=i3mdet(sym)
45 ! matrix should be orthogonal
46  if (abs(md) /= 1) goto 10
47 ! check invariance of metric tensor
48  s(1:3,1:3)=dble(sym(1:3,1:3))
49  call r3mtm(s,g,c)
50  call r3mm(c,s,sgs)
51  do j=1,3
52  do i=1,3
53  if (abs(sgs(i,j)-g(i,j)) > epslat) goto 10
54  end do
55  end do
56 ! check invariance of spin-spiral q-vector if required
57  if (spinsprl) then
58  call r3mtv(s,vqlss,v)
59  t1=abs(vqlss(1)-v(1))+abs(vqlss(2)-v(2))+abs(vqlss(3)-v(3))
60  if (t1 > epslat) goto 10
61  end if
62 ! check invariance of electric field if required
63  if (tefield) then
64  call r3mv(s,efieldl,v)
65  t1=abs(efieldl(1)-v(1))+abs(efieldl(2)-v(2))+abs(efieldl(3)-v(3))
66  if (t1 > epslat) goto 10
67  end if
68 ! check invariance of static A-field if required
69  if (tafield) then
70  call r3mv(s,afieldl,v)
71  t1=abs(afieldl(1)-v(1))+abs(afieldl(2)-v(2))+abs(afieldl(3)-v(3))
72  if (t1 > epslat) goto 10
73  end if
74 ! check invariance of time-dependent A-field if required
75  if (tafieldt) then
76 ! symmetry matrix in Cartesian coordinates
77  call r3mm(s,ainv,c)
78  call r3mm(avec,c,sc)
79  do its=1,ntimes
80  call r3mv(sc,afieldt(:,its),v)
81  t1=abs(afieldt(1,its)-v(1)) &
82  +abs(afieldt(2,its)-v(2)) &
83  +abs(afieldt(3,its)-v(3))
84  if (t1 > epslat) goto 10
85  end do
86  end if
88  if (nsymlat > 48) then
89  write(*,*)
90  write(*,'("Error(findsymlat): more than 48 symmetries found")')
91  write(*,'(" (lattice vectors may be linearly dependent)")')
92  write(*,*)
93  stop
94  end if
95 ! store the symmetry and determinant in global arrays
96  symlat(1:3,1:3,nsymlat)=sym(1:3,1:3)
97  symlatd(nsymlat)=md
98 10 continue
99 end do; end do; end do
100 end do; end do; end do
101 end do; end do; end do
102 if (nsymlat == 0) then
103  write(*,*)
104  write(*,'("Error(findsymlat): no symmetries found")')
105  write(*,*)
106  stop
107 end if
108 ! make the first symmetry the identity
109 do i=1,nsymlat
110  if ((symlat(1,1,i) == 1).and.(symlat(1,2,i) == 0).and.(symlat(1,3,i) == 0) &
111  .and.(symlat(2,1,i) == 0).and.(symlat(2,2,i) == 1).and.(symlat(2,3,i) == 0) &
112  .and.(symlat(3,1,i) == 0).and.(symlat(3,2,i) == 0).and.(symlat(3,3,i) == 1)) &
113  then
114  sym(1:3,1:3)=symlat(1:3,1:3,1)
115  symlat(1:3,1:3,1)=symlat(1:3,1:3,i)
116  symlat(1:3,1:3,i)=sym(1:3,1:3)
117  md=symlatd(1)
118  symlatd(1)=symlatd(i)
119  symlatd(i)=md
120  exit
121  end if
122 end do
123 ! index to the inverse of each operation
124 do i=1,nsymlat
125  call i3minv(symlat(:,:,i),sym)
126  do j=1,nsymlat
127  if (all(symlat(1:3,1:3,j) == sym(1:3,1:3))) then
128  isymlat(i)=j
129  goto 30
130  end if
131  end do
132  write(*,*)
133  write(*,'("Error(findsymlat): inverse operation not found")')
134  write(*,'(" for lattice symmetry ",I0)') i
135  write(*,*)
136  stop
137 30 continue
138 end do
139 ! determine the lattice symmetries in Cartesian coordinates
140 do i=1,nsymlat
141  s(1:3,1:3)=dble(symlat(1:3,1:3,i))
142  call r3mm(s,ainv,c)
143  call r3mm(avec,c,symlatc(:,:,i))
144 end do
145 
146 contains
147 
148 pure integer function i3mdet(a)
149 implicit none
150 ! arguments
151 integer, intent(in) :: a(3,3)
152 ! determinant of integer matrix
153 i3mdet=a(1,1)*(a(2,2)*a(3,3)-a(3,2)*a(2,3)) &
154  +a(2,1)*(a(3,2)*a(1,3)-a(1,2)*a(3,3)) &
155  +a(3,1)*(a(1,2)*a(2,3)-a(2,2)*a(1,3))
156 end function
157 
158 pure subroutine i3minv(a,b)
159 implicit none
160 ! arguments
161 integer, intent(in) :: a(3,3)
162 integer, intent(out) :: b(3,3)
163 ! local variables
164 integer md
165 md=i3mdet(a)
166 b(1,1)=md*(a(2,2)*a(3,3)-a(2,3)*a(3,2))
167 b(2,1)=md*(a(2,3)*a(3,1)-a(2,1)*a(3,3))
168 b(3,1)=md*(a(2,1)*a(3,2)-a(2,2)*a(3,1))
169 b(1,2)=md*(a(1,3)*a(3,2)-a(1,2)*a(3,3))
170 b(2,2)=md*(a(1,1)*a(3,3)-a(1,3)*a(3,1))
171 b(3,2)=md*(a(1,2)*a(3,1)-a(1,1)*a(3,2))
172 b(1,3)=md*(a(1,2)*a(2,3)-a(1,3)*a(2,2))
173 b(2,3)=md*(a(1,3)*a(2,1)-a(1,1)*a(2,3))
174 b(3,3)=md*(a(1,1)*a(2,2)-a(1,2)*a(2,1))
175 end subroutine
176 
177 end subroutine
178 !EOC
179 
pure subroutine r3mtv(a, x, y)
Definition: r3mtv.f90:10
real(8), dimension(3) efieldl
Definition: modmain.f90:314
pure subroutine i3minv(a, b)
Definition: findsymlat.f90:159
integer ntimes
Definition: modtddft.f90:42
real(8), dimension(3, 3) ainv
Definition: modmain.f90:14
logical spinsprl
Definition: modmain.f90:283
integer, dimension(3, 3, 48) symlat
Definition: modmain.f90:344
real(8), dimension(3) vqlss
Definition: modmain.f90:293
logical tafieldt
Definition: modtddft.f90:56
pure subroutine r3mtm(a, b, c)
Definition: r3mtm.f90:10
logical tefield
Definition: modmain.f90:310
subroutine findsymlat
Definition: findsymlat.f90:10
integer nsymlat
Definition: modmain.f90:342
real(8), dimension(3, 3) avec
Definition: modmain.f90:12
integer, dimension(48) symlatd
Definition: modmain.f90:346
real(8) epslat
Definition: modmain.f90:24
real(8), dimension(:,:), allocatable afieldt
Definition: modtddft.f90:58
pure subroutine r3mv(a, x, y)
Definition: r3mv.f90:10
pure subroutine r3mm(a, b, c)
Definition: r3mm.f90:10
logical tafield
Definition: modmain.f90:322
pure integer function i3mdet(a)
Definition: findsymlat.f90:149
real(8), dimension(3) afieldl
Definition: modmain.f90:327