The Elk Code
 
Loading...
Searching...
No Matches
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:
9subroutine findsymcrys
10! !USES:
11use modmain
12use modmpi
13use 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
34implicit none
35! local variables
36integer ia,ja,is,is0
37integer isym,nsym,i,n
38integer lspl(48),lspn(48),ilspl
39real(8) v0(3),v1(3),v2(3),t1
40real(8) apl1(3,maxatoms,maxspecies)
41real(8) apl2(3,maxatoms,maxspecies)
42! automatic arrays
43integer iea(natmmax,nspecies,48)
44real(8) vtl(3,natmmax**2+1)
45! allocate global equivalent atom arrays
46if (allocated(ieqatom)) deallocate(ieqatom)
47allocate(ieqatom(natmmax,nspecies,maxsymcrys))
48if (allocated(eqatoms)) deallocate(eqatoms)
49allocate(eqatoms(natmmax,natmmax,nspecies))
50if (allocated(tfeqat)) deallocate(tfeqat)
51allocate(tfeqat(natmmax,nspecies))
52! find the smallest set of atoms
53is0=1
54do is=1,nspecies
55 if (natoms(is) < natoms(is0)) is0=is
56end do
57if (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
69else
70 v0(:)=0.d0
71end if
72! determine possible translation vectors from smallest set of atoms
73n=1
74vtl(:,1)=0.d0
75do 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(:)
9310 continue
94 end do
95end do
96! no translations required when symtype=0,2 (F. Cricchio)
97if (symtype /= 1) n=1
98eqatoms(:,:,:)=.false.
100! loop over all possible translations
101do 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
131end do
132tsyminv=.false.
133do 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
151end do
152! flag the first equivalent atom for each species
153do 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
158end do
159if (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
166else
167 v1(:)=v0(:)
168end if
169do 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
184end do
185do 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)
198end do
199! check inversion does not include a translation
200if (tsyminv) then
201 if (.not.tv0symc(2)) tsyminv=.false.
202end if
203if (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
213end if
214! write number of crystal symmetries to test file
215call writetest(705,'number of crystal symmetries',iv=nsymcrys)
216end subroutine
217!EOC
218
subroutine findsym(apl1, apl2, nsym, lspl, lspn, iea)
Definition findsym.f90:10
subroutine findsymcrys
logical, dimension(:,:), allocatable tfeqat
Definition modmain.f90:372
integer, dimension(48) isymlat
Definition modmain.f90:348
real(8), dimension(3) efieldc
Definition modmain.f90:312
logical tshift
Definition modmain.f90:352
integer symtype
Definition modmain.f90:340
real(8), dimension(3, maxatoms, maxspecies) atposc
Definition modmain.f90:54
integer, dimension(maxspecies) natoms
Definition modmain.f90:36
integer, dimension(:,:,:), allocatable ieqatom
Definition modmain.f90:368
logical tsyminv
Definition modmain.f90:354
real(8), dimension(3, 3) avec
Definition modmain.f90:12
real(8), dimension(3, maxsymcrys) vtlsymc
Definition modmain.f90:360
integer, dimension(maxsymcrys) lspnsymc
Definition modmain.f90:366
logical tefield
Definition modmain.f90:310
real(8) epslat
Definition modmain.f90:24
integer natmtot
Definition modmain.f90:40
logical, dimension(maxsymcrys) tv0symc
Definition modmain.f90:362
real(8), dimension(3, maxsymcrys) vtcsymc
Definition modmain.f90:360
logical, dimension(:,:,:), allocatable eqatoms
Definition modmain.f90:370
integer nsymcrys
Definition modmain.f90:358
integer, dimension(3, 3, 48) symlat
Definition modmain.f90:344
integer, parameter maxsymcrys
Definition modmain.f90:356
real(8), dimension(3, maxatoms, maxspecies) atposl
Definition modmain.f90:51
integer, dimension(maxsymcrys) lsplsymc
Definition modmain.f90:364
logical mp_mpi
Definition modmpi.f90:17
subroutine writetest(id, descr, nv, iv, iva, tol, rv, rva, zv, zva)
Definition modtest.f90:16
pure subroutine r3frac(eps, v)
Definition r3frac.f90:10
pure subroutine r3mv(a, x, y)
Definition r3mv.f90:10