The Elk Code
findsymcrys.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2007 J. K. Dewhurst, S. Sharma and C. Ambrosch-Draxl.
3 ! This file is distributed under the terms of the GNU General Public License.
4 ! See the file COPYING for license details.
5 
6 !BOP
7 ! !ROUTINE: findsymcrys
8 ! !INTERFACE:
9 subroutine findsymcrys
10 ! !USES:
11 use modmain
12 use modmpi
13 use modtest
14 ! !DESCRIPTION:
15 ! Finds the complete set of symmetries which leave the crystal structure
16 ! (including the magnetic fields) invariant. A crystal symmetry is of the form
17 ! $\{\alpha_S|\alpha_R|{\bf t}\}$, where ${\bf t}$ is a translation vector,
18 ! $\alpha_R$ is a spatial rotation operation and $\alpha_S$ is a global spin
19 ! rotation. Note that the order of operations is important and defined to be
20 ! from right to left, i.e. translation followed by spatial rotation followed
21 ! by spin rotation. In the case of spin-orbit coupling $\alpha_S=\alpha_R$. In
22 ! order to determine the translation vectors, the entire atomic basis is
23 ! shifted so that the first atom in the smallest set of atoms of the same
24 ! species is at the origin. Then all displacement vectors between atoms in
25 ! this set are checked as possible symmetry translations. If the global
26 ! variable {\tt tshift} is set to {\tt .false.} then the shift is not
27 ! performed. See L. M. Sandratskii and P. G. Guletskii, {\it J. Phys. F: Met.
28 ! Phys.} {\bf 16}, L43 (1986) and the routine {\tt findsym}.
29 !
30 ! !REVISION HISTORY:
31 ! Created April 2007 (JKD)
32 !EOP
33 !BOC
34 implicit none
35 ! local variables
36 integer ia,ja,is,is0
37 integer isym,nsym,i,n
38 integer lspl(48),lspn(48),ilspl
39 real(8) v0(3),v1(3),v2(3),t1
40 real(8) apl1(3,maxatoms,maxspecies)
41 real(8) apl2(3,maxatoms,maxspecies)
42 ! automatic arrays
43 integer iea(natmmax,nspecies,48)
44 real(8) vtl(3,natmmax**2+1)
45 ! allocate global equivalent atom arrays
46 if (allocated(ieqatom)) deallocate(ieqatom)
47 allocate(ieqatom(natmmax,nspecies,maxsymcrys))
48 if (allocated(eqatoms)) deallocate(eqatoms)
49 allocate(eqatoms(natmmax,natmmax,nspecies))
50 if (allocated(tfeqat)) deallocate(tfeqat)
51 allocate(tfeqat(natmmax,nspecies))
52 ! find the smallest set of atoms
53 is0=1
54 do is=1,nspecies
55  if (natoms(is) < natoms(is0)) is0=is
56 end do
57 if (natmtot > 0) then
58 ! position of first atom in the smallest atom set
59  v0(:)=atposl(:,1,is0)
60 ! shift basis so that the first atom in the smallest atom set is at the origin
61  do is=1,nspecies
62  do ia=1,natoms(is)
63 ! shift atom
64  apl1(:,ia,is)=atposl(:,ia,is)-v0(:)
65 ! map lattice coordinates back to [0,1)
66  call r3frac(epslat,apl1(:,ia,is))
67  end do
68  end do
69 else
70  v0(:)=0.d0
71 end if
72 ! determine possible translation vectors from smallest set of atoms
73 n=1
74 vtl(:,1)=0.d0
75 do ia=1,natoms(is0)
76  do ja=2,natoms(is0)
77 ! compute difference between two atom vectors
78  v1(:)=apl1(:,ia,is0)-apl1(:,ja,is0)
79 ! map lattice coordinates to [0,1)
80  call r3frac(epslat,v1)
81 ! check if vector has any component along electric field
82  if (tefield) then
83  call r3mv(avec,v1,v2)
84  t1=efieldc(1)*v2(1)+efieldc(2)*v2(2)+efieldc(3)*v2(3)
85  if (abs(t1) > epslat) goto 10
86  end if
87  do i=1,n
88  t1=abs(vtl(1,i)-v1(1))+abs(vtl(2,i)-v1(2))+abs(vtl(3,i)-v1(3))
89  if (t1 < epslat) goto 10
90  end do
91  n=n+1
92  vtl(:,n)=v1(:)
93 10 continue
94  end do
95 end do
96 ! no translations required when symtype=0,2 (F. Cricchio)
97 if (symtype /= 1) n=1
98 eqatoms(:,:,:)=.false.
99 nsymcrys=0
100 ! loop over all possible translations
101 do i=1,n
102 ! construct new array with translated positions
103  do is=1,nspecies
104  do ia=1,natoms(is)
105  apl2(:,ia,is)=apl1(:,ia,is)+vtl(:,i)
106  end do
107  end do
108 ! find the symmetries for current translation
109  call findsym(apl1,apl2,nsym,lspl,lspn,iea)
110  do isym=1,nsym
112  if (nsymcrys > maxsymcrys) then
113  write(*,*)
114  write(*,'("Error(findsymcrys): too many crystal symmetries")')
115  write(*,'(" Adjust maxsymcrys in modmain and recompile code")')
116  write(*,*)
117  stop
118  end if
119  vtlsymc(:,nsymcrys)=vtl(:,i)
120  lsplsymc(nsymcrys)=lspl(isym)
121  lspnsymc(nsymcrys)=lspn(isym)
122  do is=1,nspecies
123  do ia=1,natoms(is)
124  ja=iea(ia,is,isym)
125  ieqatom(ia,is,nsymcrys)=ja
126  eqatoms(ia,ja,is)=.true.
127  eqatoms(ja,ia,is)=.true.
128  end do
129  end do
130  end do
131 end do
132 tsyminv=.false.
133 do isym=1,nsymcrys
134 ! check if inversion symmetry is present
135  i=lsplsymc(isym)
136  if (all(symlat(:,:,i) == -symlat(:,:,1))) then
137  tsyminv=.true.
138 ! make inversion the second symmetry element (the identity is the first)
139  v1(:)=vtlsymc(:,isym); vtlsymc(:,isym)=vtlsymc(:,2); vtlsymc(:,2)=v1(:)
140  i=lsplsymc(isym); lsplsymc(isym)=lsplsymc(2); lsplsymc(2)=i
141  i=lspnsymc(isym); lspnsymc(isym)=lspnsymc(2); lspnsymc(2)=i
142  do is=1,nspecies
143  do ia=1,natoms(is)
144  i=ieqatom(ia,is,isym)
145  ieqatom(ia,is,isym)=ieqatom(ia,is,2)
146  ieqatom(ia,is,2)=i
147  end do
148  end do
149  exit
150  end if
151 end do
152 ! flag the first equivalent atom for each species
153 do is=1,nspecies
154  do ia=1,natoms(is)
155  ja=findloc(eqatoms(1:ia,ia,is),.true.,1)
156  tfeqat(ia,is)=(ia == ja)
157  end do
158 end do
159 if (tshift) then
160  if (tsyminv) then
161 ! if inversion exists then shift basis so that inversion center is at origin
162  v1(:)=v1(:)/2.d0
163  else
164  v1(:)=0.d0
165  end if
166 else
167  v1(:)=v0(:)
168 end if
169 do is=1,nspecies
170  do ia=1,natoms(is)
171 ! shift atom
172  atposl(:,ia,is)=apl1(:,ia,is)+v1(:)
173 ! map lattice coordinates back to [0,1)
174  call r3frac(epslat,atposl(:,ia,is))
175 ! map lattice coordinates to [-0.5,0.5) if inversion exists
176  if (tsyminv) then
177  do i=1,3
178  if (atposl(i,ia,is) > 0.5d0) atposl(i,ia,is)=atposl(i,ia,is)-1.d0
179  end do
180  end if
181 ! determine the new Cartesian coordinates
182  call r3mv(avec,atposl(:,ia,is),atposc(:,ia,is))
183  end do
184 end do
185 do isym=1,nsymcrys
186 ! recalculate crystal symmetry translation vectors
187  ilspl=isymlat(lsplsymc(isym))
188  v2(:)=symlat(:,1,ilspl)*v1(1) &
189  +symlat(:,2,ilspl)*v1(2) &
190  +symlat(:,3,ilspl)*v1(3)
191  vtlsymc(:,isym)=vtlsymc(:,isym)-v1(:)+v2(:)
192  call r3frac(epslat,vtlsymc(:,isym))
193 ! translation vector in Cartesian coordinates
194  call r3mv(avec,vtlsymc(:,isym),vtcsymc(:,isym))
195 ! set flag for zero translation vector
196  t1=abs(vtlsymc(1,isym))+abs(vtlsymc(2,isym))+abs(vtlsymc(3,isym))
197  tv0symc(isym)=(t1 < epslat)
198 end do
199 ! check inversion does not include a translation
200 if (tsyminv) then
201  if (.not.tv0symc(2)) tsyminv=.false.
202 end if
203 if (tshift.and.(natmtot > 0)) then
204  v1(:)=atposl(:,1,is0)-v0(:)
205  call r3frac(epslat,v1)
206  t1=abs(v1(1))+abs(v1(2))+abs(v1(3))
207  if (mp_mpi.and.(t1 > epslat)) then
208  write(*,*)
209  write(*,'("Info(findsymcrys): atomic basis shift (lattice) :")')
210  write(*,'(3G18.10)') v1(:)
211  write(*,'("See GEOMETRY.OUT for new atomic positions")')
212  end if
213 end if
214 ! write number of crystal symmetries to test file
215 call writetest(705,'number of crystal symmetries',iv=nsymcrys)
216 end subroutine
217 !EOC
218 
subroutine writetest(id, descr, nv, iv, iva, tol, rv, rva, zv, zva)
Definition: modtest.f90:16
integer, dimension(maxsymcrys) lspnsymc
Definition: modmain.f90:366
logical mp_mpi
Definition: modmpi.f90:17
logical, dimension(:,:), allocatable tfeqat
Definition: modmain.f90:372
logical tshift
Definition: modmain.f90:352
integer nsymcrys
Definition: modmain.f90:358
integer, dimension(48) isymlat
Definition: modmain.f90:348
integer, dimension(3, 3, 48) symlat
Definition: modmain.f90:344
real(8), dimension(3, maxsymcrys) vtlsymc
Definition: modmain.f90:360
logical, dimension(:,:,:), allocatable eqatoms
Definition: modmain.f90:370
integer, parameter maxsymcrys
Definition: modmain.f90:356
integer, dimension(:,:,:), allocatable ieqatom
Definition: modmain.f90:368
logical, dimension(maxsymcrys) tv0symc
Definition: modmain.f90:362
integer symtype
Definition: modmain.f90:340
subroutine findsymcrys
Definition: findsymcrys.f90:10
logical tefield
Definition: modmain.f90:310
logical tsyminv
Definition: modmain.f90:354
real(8), dimension(3, maxatoms, maxspecies) atposl
Definition: modmain.f90:51
integer, dimension(maxsymcrys) lsplsymc
Definition: modmain.f90:364
real(8), dimension(3, 3) avec
Definition: modmain.f90:12
pure subroutine r3frac(eps, v)
Definition: r3frac.f90:10
integer, dimension(maxspecies) natoms
Definition: modmain.f90:36
real(8) epslat
Definition: modmain.f90:24
subroutine findsym(apl1, apl2, nsym, lspl, lspn, iea)
Definition: findsym.f90:10
Definition: modmpi.f90:6
integer natmtot
Definition: modmain.f90:40
pure subroutine r3mv(a, x, y)
Definition: r3mv.f90:10
real(8), dimension(3, maxatoms, maxspecies) atposc
Definition: modmain.f90:54
real(8), dimension(3) efieldc
Definition: modmain.f90:312
real(8), dimension(3, maxsymcrys) vtcsymc
Definition: modmain.f90:360