Line data Source code
1 : !!****m* ABINIT/m_paw_sym
2 : !! NAME
3 : !! m_paw_sym
4 : !!
5 : !! FUNCTION
6 : !! This module contains several routines related to the use of symmetries in the PAW approach.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2018-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : MODULE m_paw_sym
23 :
24 : use defs_basis
25 : use m_abicore
26 : use m_errors
27 :
28 : use m_crystal, only : crystal_t
29 : use m_pawang, only : pawang_type
30 : use m_pawtab, only : pawtab_type
31 : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_free, pawcprj_copy
32 : use m_bz_mesh, only : kmesh_t
33 :
34 : implicit none
35 :
36 : private
37 :
38 : !public procedures.
39 : public :: paw_symcprj ! Symetrize the projections cprj=<n,k|p_i> (p_i=NL PAW projector) - in-place version
40 : public :: paw_symcprj_op ! Symetrize the projections cprj=<n,k|p_i> (p_i=NL PAW projector) - out-of-place version
41 :
42 : CONTAINS !========================================================================================
43 : !!***
44 :
45 : !----------------------------------------------------------------------
46 :
47 : !!****f* m_paw_sym/paw_symcprj
48 : !! NAME
49 : !! paw_symcprj
50 : !!
51 : !! FUNCTION
52 : !! Symetrize the projections cprj=<n,k|p_i> (p_i=NL PAW projector) - in-place version
53 : !!
54 : !! INPUTS
55 : !! ik_ibz=The index of the k-point in the full BZ where the matrix elements have to be symmetrized.
56 : !! nspinor=Number of spinorial components
57 : !! nband_k=Number of bands stored in cprjnk_kibz for this k-point.
58 : !! Cryst<crystal_t>=data type gathering information on unit cell and symmetries.
59 : !! %ntypat=number of type of atoms
60 : !! %natom=number of atoms in the unit cell
61 : !! %typat(natom)=type of each atom
62 : !! %indsym(4,nsym,natom)=indirect indexing array:
63 : !! for each isym,iatom, fourth element is label of atom into which iatom is sent by the INVERSE of the
64 : !! symmetry operation symrel(isym); first three elements are the primitive translations that must be subtracted
65 : !! after the transformation to get back to the original unit cell.
66 : !! Kmesh<kmesh_t>: datatype gathering information on the k-point sampling.
67 : !! %nbz=number of k-points in the full Brillouin zone
68 : !! %nibz=number of k-points in the irreducible wedge
69 : !! %tab(nkbz)=table giving for each k-point in the BZ (array kbz), the corresponding irred. point in the IBZ.
70 : !! i.e k_BZ = (IS) kIBZ where S is one of the symrec operations and I is the inversion or the identity
71 : !! %tabi(nkbz)=for each k-point in the BZ defines whether inversion has to be considered in the
72 : !! relation k_BZ=(IS) k_IBZ (1 => only S; -1 => -S)
73 : !! %tabo(nkbz)= the symmetry operation S that takes k_IBZ to each k_BZ
74 : !! Pawtab(Cryst%ntypat) <type(pawtab_type)>=paw tabulated starting data.
75 : !! Pawang <type(pawang_type)>=paw angular mesh and related data
76 : !! %lmax=Max angular momentum included in the PAW datasets used. mentioned at the second line of the psp file
77 : !! %zarot(2*lmax+1,2*lmax+1,lmax+1,nsym)=coefficients of the transformation of real spherical
78 : !! harmonics under the symmetry operations.
79 : !!
80 : !! NOTES
81 : !! Derivatives are not symmetrized.
82 : !!
83 : !! OUTPUT
84 : !!
85 : !! SOURCE
86 :
87 127533 : subroutine paw_symcprj(ik_bz,nspinor,nband_k,Cryst,Kmesh,Pawtab,Pawang,Cprj_bz)
88 :
89 : !Arguments ------------------------------------
90 : !scalars
91 : integer,intent(in) :: nspinor,nband_k,ik_bz
92 : type(crystal_t),intent(in) :: Cryst
93 : type(kmesh_t),intent(in) :: Kmesh
94 : type(Pawang_type),intent(in) :: Pawang
95 : !arrays
96 : type(Pawtab_type),target,intent(in) :: Pawtab(Cryst%ntypat)
97 : type(pawcprj_type),intent(inout) :: Cprj_bz(Cryst%natom,nspinor*nband_k)
98 :
99 : !Local variables-------------------------------
100 : !scalars
101 : integer :: iatom,iat_sym,iband,ibsp_bz
102 : integer :: ibsp_ibz,ik_ibz,indexj,ispinor,isym,itim
103 : integer :: itypat,jl,jl0,jlmn,jln,jln0,jlpm,jm,jn,lmax,mm,ncpgr
104 : real(dp) :: arg,wtk
105 : logical :: isirred
106 : !arrays
107 255066 : integer :: r0(3),nlmn_atom(Cryst%natom)
108 127533 : integer,ABI_CONTIGUOUS pointer :: indlmn(:,:)
109 23045 : real(dp) :: dum(2,nspinor),kbz(3),kirr(3),phase(2),swp(2),tmp(2,nspinor)
110 127533 : real(dp),allocatable :: DS_mmpl(:,:,:)
111 1828302 : type(pawcprj_type) :: Cprjnk_kibz(Cryst%natom,nspinor*nband_k)
112 :
113 : ! *********************************************************************
114 :
115 127533 : ncpgr = Cprj_bz(1,1)%ncpgr
116 127533 : ABI_CHECK(ncpgr==0,"Derivatives of cprj are not coded")
117 :
118 : !Get the index of the IBZ image associated to the BZ k-point ik_bz and related simmetry.
119 127533 : call Kmesh%get_BZ_item(ik_bz,kbz,ik_ibz,isym,itim,isirred=isirred)
120 :
121 281931 : if (isirred) RETURN ! It is a point in the IBZ, Symmetrization is not needed.
122 : !
123 : !The corresponding point kirr in the IBZ.
124 104488 : call kmesh%get_IBZ_item(ik_ibz,kirr,wtk)
125 :
126 : !Local copy.
127 316656 : do iatom=1,Cryst%natom
128 316656 : nlmn_atom(iatom)=Pawtab(Cryst%typat(iatom))%lmn_size
129 : end do
130 :
131 104488 : call pawcprj_alloc(Cprjnk_kibz,ncpgr,nlmn_atom)
132 104488 : call pawcprj_copy(Cprj_bz,Cprjnk_kibz)
133 : !
134 : !=== DS_mmpl is the rotation matrix for real spherical harmonics associated to symrec(:,:,isym) ===
135 : !* Note the convention used by Blanco in Eq. 27 : DS_mmp multiply spherical harmonics as row vectors
136 104488 : lmax=Pawang%l_max-1 ! l_max is Max l+1
137 626928 : ABI_MALLOC(DS_mmpl,(2*lmax+1,2*lmax+1,lmax+1))
138 2956216 : DS_mmpl=Pawang%zarot(:,:,:,isym)
139 : !
140 : !===========================================
141 : !==== Loop over atoms to be symmetrized ====
142 : !===========================================
143 316656 : do iatom=1,Cryst%natom
144 212168 : itypat=Cryst%typat(iatom)
145 212168 : iat_sym=Cryst%indsym(4,isym,iatom)
146 212168 : indlmn => Pawtab(itypat)%indlmn
147 848672 : r0=Cryst%indsym(1:3,isym,iatom) ! R^{-1} (xred(:,iatom)-tnons) = xred(:,iat_sym) + r0.
148 848672 : arg=two_pi*dot_product(kirr,r0)
149 212168 : phase(1)=COS(arg)
150 212168 : phase(2)=SIN(arg)
151 : !
152 : ! Loop over the (jl,jm,jn) components to be symmetrized.
153 212168 : jl0=-1; jln0=-1; indexj=1
154 2018950 : do jlmn=1,Pawtab(itypat)%lmn_size
155 1702294 : jl =indlmn(1,jlmn)
156 1702294 : jm =indlmn(2,jlmn)
157 1702294 : jn =indlmn(3,jlmn)
158 1702294 : jln =indlmn(5,jlmn)
159 1702294 : jlpm=1+jl+jm
160 1702294 : if (jln/=jln0) indexj=indexj+2*jl0+1
161 : !
162 : ! === For each band, calculate contribution due to rotated real spherical harmonics ===
163 : ! FIXME check this expression; according to Blanco I should have D(S^-1} but it seems D(S) is correct
164 : ! Recheck spinorial case, presently is wrong
165 1702294 : ibsp_ibz=0
166 1702294 : ibsp_bz=0
167 3404588 : do iband=1,nband_k
168 :
169 6809176 : tmp(:,:)=zero
170 3404588 : do ispinor=1,nspinor
171 1702294 : ibsp_ibz=ibsp_ibz+1
172 7676478 : do mm=1,2*jl+1
173 4271890 : tmp(1,ispinor)=tmp(1,ispinor)+DS_mmpl(mm,jlpm,jl+1)*Cprjnk_kibz(iat_sym,ibsp_ibz)%cp(1,indexj+mm)
174 5974184 : tmp(2,ispinor)=tmp(2,ispinor)+DS_mmpl(mm,jlpm,jl+1)*Cprjnk_kibz(iat_sym,ibsp_ibz)%cp(2,indexj+mm)
175 : end do
176 : end do !ispinor
177 : !
178 : ! * Apply the phase to account if the symmetric atom belongs to a different unit cell.
179 3404588 : do ispinor=1,nspinor
180 1702294 : dum(1,ispinor)=tmp(1,ispinor)*phase(1)-tmp(2,ispinor)*phase(2)
181 3404588 : dum(2,ispinor)=tmp(1,ispinor)*phase(2)+tmp(2,ispinor)*phase(1)
182 : end do
183 : !
184 : ! * If required, apply time-reversal symmetry to retrieve the correct point in the BZ.
185 1702294 : if (itim==2) then
186 0 : if (nspinor==1) then
187 0 : dum(2,1)=-dum(2,1)
188 0 : else if (nspinor==2) then ! TODO rotate wavefunction in spinor space.
189 0 : swp(:)=dum(:,1)
190 0 : dum(1,1)= dum(1,2)
191 0 : dum(2,1)=-dum(2,2)
192 0 : dum(1,2)=-swp(1)
193 0 : dum(2,2)= swp(2)
194 : end if
195 : end if
196 : !
197 : ! ==== Save values ====
198 5106882 : do ispinor=1,nspinor
199 1702294 : ibsp_bz=ibsp_bz+1
200 1702294 : Cprj_bz(iatom,ibsp_bz)%cp(1,jlmn)=dum(1,ispinor)
201 3404588 : Cprj_bz(iatom,ibsp_bz)%cp(2,jlmn)=dum(2,ispinor)
202 : end do
203 : end do !iband
204 :
205 1914462 : jl0=jl; jln0=jln
206 : end do !jlmn
207 : end do !iatom
208 :
209 104488 : call pawcprj_free(Cprjnk_kibz)
210 104488 : ABI_FREE(DS_mmpl)
211 :
212 127533 : end subroutine paw_symcprj
213 : !!***
214 :
215 : !----------------------------------------------------------------------
216 :
217 : !!****f* m_paw_sym/paw_symcprj_op
218 : !! NAME
219 : !! paw_symcprj_op
220 : !!
221 : !! FUNCTION
222 : !! Symetrize the projections cprj=<n,k|p_i> (p_i=NL PAW projector) - in-place version
223 : !!
224 : !! INPUTS
225 : !! ik_ibz=The index of the k-point in the full BZ where the matrix elements have to be symmetrized.
226 : !! nspinor=Number of spinorial components
227 : !! nband_k=Number of bands stored in cprjnk_kibz for this k-point.
228 : !! Cryst<crystal_t>=data type gathering information on unit cell and symmetries.
229 : !! %ntypat=number of type of atoms
230 : !! %natom=number of atoms in the unit cell
231 : !! %typat(natom)=type of each atom
232 : !! %indsym(4,nsym,natom)=indirect indexing array:
233 : !! for each isym,iatom, fourth element is label of atom into which iatom is sent by the INVERSE of the
234 : !! symmetry operation symrel(isym); first three elements are the primitive translations that must be subtracted
235 : !! after the transformation to get back to the original unit cell.
236 : !! Kmesh<kmesh_t>: datatype gathering information on the k-point sampling.
237 : !! %nbz=number of k-points in the full Brillouin zone
238 : !! %nibz=number of k-points in the irreducible wedge
239 : !! %tab(nkbz)=table giving for each k-point in the BZ (array kbz), the corresponding irred. point in the IBZ.
240 : !! i.e k_BZ = (IS) kIBZ where S is one of the symrec operations and I is the inversion or the identity
241 : !! %tabi(nkbz)=for each k-point in the BZ defines whether inversion has to be considered in the
242 : !! relation k_BZ=(IS) k_IBZ (1 => only S; -1 => -S)
243 : !! %tabo(nkbz)= the symmetry operation S that takes k_IBZ to each k_BZ
244 : !! Pawtab(Cryst%ntypat) <type(pawtab_type)>=paw tabulated starting data.
245 : !! Pawang <type(pawang_type)>=paw angular mesh and related data
246 : !! %lmax=Max angular momentum included in the PAW datasets used. mentioned at the second line of the psp file
247 : !! %zarot(2*lmax+1,2*lmax+1,lmax+1,nsym)=coefficients of the transformation of real spherical
248 : !! harmonics under the symmetry operations.
249 : !! in_Cprj(Cryst%natom,nspinor*nband_k)<pawcprj_type>=Input cprj
250 : !!
251 : !! OUTPUT
252 : !! out_Cprj(Cryst%natom,nspinor*nband_k)<pawcprj_type>=Symmetrized cprj matrix elements.
253 : !!
254 : !! NOTES
255 : !! Derivatives are not symmetrized.
256 : !!
257 : !! SOURCE
258 :
259 216184 : subroutine paw_symcprj_op(ik_bz,nspinor,nband_k,Cryst,Kmesh,Pawtab,Pawang,in_Cprj,out_Cprj)
260 :
261 : !Arguments ------------------------------------
262 : !scalars
263 : integer,intent(in) :: nspinor,nband_k,ik_bz
264 : type(crystal_t),intent(in) :: Cryst
265 : type(kmesh_t),intent(in) :: Kmesh
266 : type(Pawang_type),intent(in) :: Pawang
267 : !arrays
268 : type(Pawtab_type),target,intent(in) :: Pawtab(Cryst%ntypat)
269 : type(pawcprj_type),intent(in) :: in_Cprj(Cryst%natom,nspinor*nband_k)
270 : type(pawcprj_type),intent(inout) :: out_Cprj(Cryst%natom,nspinor*nband_k) !vz_i
271 :
272 : !Local variables-------------------------------
273 : !scalars
274 : integer :: iatom,iat_sym,iband,ibsp_bz
275 : integer :: ibsp_ibz,ik_ibz,indexj,ispinor,isym,itim
276 : integer :: itypat,jl,jl0,jlmn,jln,jln0,jlpm,jm,jn,lmax,mm,ncpgr
277 : real(dp) :: arg,wtk
278 : logical :: isirred
279 : !arrays
280 : integer :: r0(3) !,nlmn_atom(Cryst%natom)
281 216184 : integer,ABI_CONTIGUOUS pointer :: indlmn(:,:)
282 12572 : real(dp) :: dum(2,nspinor),kbz(3),kirr(3),phase(2),swp(2),tmp(2,nspinor)
283 216184 : real(dp),allocatable :: DS_mmpl(:,:,:)
284 :
285 : ! *********************************************************************
286 :
287 216184 : ncpgr = in_Cprj(1,1)%ncpgr
288 0 : ABI_CHECK(ncpgr==0,"Derivatives of cprj are not coded")
289 :
290 : !Get the index of the IBZ image associated to the BZ k-point ik_bz and related simmetry.
291 216184 : call Kmesh%get_BZ_item(ik_bz,kbz,ik_ibz,isym,itim,isirred=isirred)
292 :
293 216184 : if (isirred) then ! It is a point in the IBZ, Symmetrization is not needed.
294 12572 : call pawcprj_copy(in_Cprj,out_Cprj)
295 : RETURN
296 : end if
297 : !
298 : !The corresponding point kirr in the IBZ.
299 203612 : call Kmesh%get_IBZ_item(ik_ibz,kirr,wtk)
300 : !
301 : !=== DS_mmpl is the rotation matrix for real spherical harmonics associated to symrec(:,:,isym) ===
302 : !* Note the convention used by Blanco in Eq. 27 : DS_mmp multiply spherical harmonics as row vectors
303 203612 : lmax=Pawang%l_max-1 ! l_max is Max l+1
304 1221672 : ABI_MALLOC(DS_mmpl,(2*lmax+1,2*lmax+1,lmax+1))
305 5701136 : DS_mmpl=Pawang%zarot(:,:,:,isym)
306 :
307 : !Local copy.
308 : !do iatom=1,Cryst%natom
309 : !nlmn_atom(iatom)=Pawtab(Cryst%typat(iatom))%lmn_size
310 : !end do
311 : !call pawcprj_alloc(out_Cprj,ncpgr,nlmn_atom)
312 : !
313 : !===========================================
314 : !==== Loop over atoms to be symmetrized ====
315 : !===========================================
316 610836 : do iatom=1,Cryst%natom
317 407224 : itypat=Cryst%typat(iatom)
318 407224 : iat_sym=Cryst%indsym(4,isym,iatom)
319 407224 : indlmn => Pawtab(itypat)%indlmn
320 1628896 : r0=Cryst%indsym(1:3,isym,iatom) ! R^{-1} (xred(:,iatom)-tnons) = xred(:,iat_sym) + r0.
321 1628896 : arg=two_pi*dot_product(kirr,r0)
322 407224 : phase(1)=COS(arg)
323 407224 : phase(2)=SIN(arg)
324 : !
325 : ! Loop over the (jl,jm,jn) components to be symmetrized.
326 407224 : jl0=-1; jln0=-1; indexj=1
327 3863168 : do jlmn=1,Pawtab(itypat)%lmn_size
328 3252332 : jl =indlmn(1,jlmn)
329 3252332 : jm =indlmn(2,jlmn)
330 3252332 : jn =indlmn(3,jlmn)
331 3252332 : jln =indlmn(5,jlmn)
332 3252332 : jlpm=1+jl+jm
333 3252332 : if (jln/=jln0) indexj=indexj+2*jl0+1
334 : !
335 : ! === For each band, calculate contribution due to rotated real spherical harmonics ===
336 : ! FIXME check this expression; according to Blanco I should have D(S^-1} but it seems D(S) is correct
337 : ! Recheck spinorial case, presently is wrong
338 3252332 : ibsp_ibz=0
339 3252332 : ibsp_bz=0
340 6504664 : do iband=1,nband_k
341 :
342 13009328 : tmp(:,:)=zero
343 6504664 : do ispinor=1,nspinor
344 3252332 : ibsp_ibz=ibsp_ibz+1
345 14632764 : do mm=1,2*jl+1
346 8128100 : tmp(1,ispinor)=tmp(1,ispinor)+DS_mmpl(mm,jlpm,jl+1)*in_Cprj(iat_sym,ibsp_ibz)%cp(1,indexj+mm)
347 11380432 : tmp(2,ispinor)=tmp(2,ispinor)+DS_mmpl(mm,jlpm,jl+1)*in_Cprj(iat_sym,ibsp_ibz)%cp(2,indexj+mm)
348 : end do
349 : end do !ispinor
350 : !
351 : ! * Apply the phase to account if the symmetric atom belongs to a different unit cell.
352 6504664 : do ispinor=1,nspinor
353 3252332 : dum(1,ispinor)=tmp(1,ispinor)*phase(1)-tmp(2,ispinor)*phase(2)
354 6504664 : dum(2,ispinor)=tmp(1,ispinor)*phase(2)+tmp(2,ispinor)*phase(1)
355 : end do
356 : !
357 : ! * If required, apply time-reversal symmetry to retrieve the correct point in the BZ.
358 3252332 : if (itim==2) then
359 0 : if (nspinor==1) then
360 0 : dum(2,1)=-dum(2,1)
361 0 : else if (nspinor==2) then ! TODO rotate wavefunction in spinor space.
362 0 : swp(:)=dum(:,1)
363 0 : dum(1,1)= dum(1,2)
364 0 : dum(2,1)=-dum(2,2)
365 0 : dum(1,2)=-swp(1)
366 0 : dum(2,2)= swp(2)
367 : end if
368 : end if
369 : !
370 : ! ==== Save values ====
371 9756996 : do ispinor=1,nspinor
372 3252332 : ibsp_bz=ibsp_bz+1
373 3252332 : out_Cprj(iatom,ibsp_bz)%cp(1,jlmn)=dum(1,ispinor)
374 6504664 : out_Cprj(iatom,ibsp_bz)%cp(2,jlmn)=dum(2,ispinor)
375 : end do
376 : end do !iband
377 :
378 3659556 : jl0=jl; jln0=jln
379 : end do !jlmn
380 : end do !iatom
381 :
382 203612 : ABI_FREE(DS_mmpl)
383 :
384 216184 : end subroutine paw_symcprj_op
385 : !!***
386 :
387 : !----------------------------------------------------------------------
388 :
389 : END MODULE m_paw_sym
390 : !!***
|