Branch data Line data Source code
1 : : !!****m* ABINIT/m_berrytk
2 : : !! NAME
3 : : !! m_berrytk
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2000-2026 ABINIT group (MVeithen)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : module m_berrytk
22 : :
23 : : use defs_basis
24 : : use m_abicore
25 : : use m_errors
26 : :
27 : : use m_cgtools, only : overlap_g
28 : : use m_hide_lapack, only : dzgedi, dzgefa
29 : :
30 : : implicit none
31 : :
32 : : private
33 : : !!***
34 : :
35 : : public :: smatrix
36 : : public :: polcart
37 : : !!***
38 : :
39 : : contains
40 : : !!***
41 : :
42 : : !!****f* ABINIT/smatrix
43 : : !! NAME
44 : : !! smatrix
45 : : !!
46 : : !! FUNCTION
47 : : !! Compute the overlap matrix between the k-points k and k + dk.
48 : : !! Depending on the value of job and ddkflag, compute also its determinant,
49 : : !! its inverse and the product of its inverse with the wavefunctions at k.
50 : : !!
51 : : !! INPUTS
52 : : !! cg(2,mcg_k) = planewave coefficients of wavefunctions at k
53 : : !! cgq(2,mcg_q) = planewave coefficients of wavefunctions at q = k + dk
54 : : !! ddkflag = 1 : compute product of the inverse overlap matrix
55 : : !! with the wavefunction at k (job = 1 or 11)
56 : : !! 0 : do not compute the product of the inverse overlap matrix
57 : : !! with the wavefunction at k
58 : : !! icg = shift applied to the wavefunctions in the array cg
59 : : !! icg1 = shift applied to the wavefunctions in the array cgq
60 : : !! itrs = variable that governs the use of time-reversal symmetry
61 : : !! when converting the wavefunctions from the iBZ to the fBZ
62 : : !! job = type of calculation
63 : : !! 0 : update overlap matrix only
64 : : !! 1 : like 0 but also compute inverse of the overlap matrix
65 : : !! 10 : like 0 but also compute determinant of the overlap matrix
66 : : !! 11 : like 0 but also compute determinant and inverse of the overlap matrix
67 : : !! 20 : like 0 but also transfer cgq to cg1_k without multiplication by S^{-1}
68 : : !! 21 : like 1 but also transfer cgq to cg1_k without multiplication by S^{-1}
69 : : !! maxbd = used in case ddkflag = 1, defines the highest band for
70 : : !! which the ddk will be computed
71 : : !! mcg_k = second dimension of cg
72 : : !! mcg_q = second dimension of cg_q
73 : : !! mcg1_k = second dimension of cg1_k, should be equal to
74 : : !! mpw*nsppol*nspinor*(maxbd - minbd + 1)
75 : : !! minbd = used in case ddkflag = 1, defines the lowest band for
76 : : !! which the ddk will be computed
77 : : !! mpw = maximum dimensioned size of npw
78 : : !! mband_occ = max number of occupied valence bands for both spins
79 : : !! nband_occ = number of (occupied) valence bands
80 : : !! npw_k1 = number of plane waves at k
81 : : !! npw_k2 = number of plane waves at k + dk
82 : : !! nspinor = number of spinorial components of the wavefunctions
83 : : !! nsppol = 1 for unpolarized, 2 for spin-polarized
84 : : !! pwind_k = array used to compute the overlap matrix
85 : : !! pwnsfac = phase factors for non-symmorphic translations
86 : : !! shifrbd = shift applied to the location of the WF in the cg-array
87 : : !! after each loop over bands
88 : : !! 0 : apply no shift, this is allowed in case cg
89 : : !! contains only the wf of one single band
90 : : !! 1 : apply a shift of npw_k1*nspinor, this is the usual option
91 : : !! when cg contains the wf for all occupied bands
92 : : !! smat_k_paw : overlap matrix due to on-site PAW terms between different bands
93 : : !! at k and k+b. Only relevant when usepaw = 1, and is to be computed
94 : : !! previously by smatrix_k_paw.F90
95 : : !! usepaw = flag governing use of PAW: 0 means no PAW, 1 means PAW is used
96 : : !!
97 : : !! OUTPUT
98 : : !! cg1_k(2,mcg1_k) = product of the inverse overlap matrix with the
99 : : !! wavefunctions at k; computed in case job = 1 or 11;
100 : : !! or just cgq in case of job = 20 or 21
101 : : !! dtm_k(2) = determinant of the overlap matrix between k and k + dk;
102 : : !! computed in case job = 10 or 11
103 : : !! smat_inv = inverse of the overlap matrix
104 : : !!
105 : : !! SIDE EFFECTS
106 : : !! Input/Output
107 : : !! sflag_k(iband) = 1 if the elements smat_k(:,iband,:) are up to date
108 : : !! -> they will not be recomputed
109 : : !! 0 the elements smat_k(:,iband,:) will be recomputed
110 : : !! at the end of the routine, sflag_k(1:mband_occ) = 1
111 : : !! (the whole overlap matrix is up to date)
112 : : !! smat_k = overlap matrix between k, k + dk
113 : : !! only the lines for which sflag_k = 0 are computed
114 : : !! smat_k(:,n,m) = < u_{n,k} | u_{m,k+dk} >
115 : : !!
116 : : !! NOTES
117 : : !! This routine is quite flexible in the way it deals with the wavefunctions:
118 : : !! - cg (WF at k) can contain either the whole WF array (all k-points
119 : : !! and bands), in which case the location of the WF at k is specified
120 : : !! by icg and shiftbd = 1, or the WF of a single k-point/band, in which case
121 : : !! shiftbd = 0 and icg = 0.
122 : : !! - cgq (WF at k + dk) can contain either the whole WF array (all k-points
123 : : !! and bands), in which case the location of the WF at k is specified
124 : : !! by icg1, or the WF of a single k-point, in which case
125 : : !! icg1 = 0. cgq must contain the WF of ALL occupied bands.
126 : : !! - cg1_k can either be computed for all valence bands or
127 : : !! for a group of valence bands defined by minbd and maxbd.
128 : : !!
129 : : !! SOURCE
130 : :
131 : 2369386 : subroutine smatrix(cg,cgq,cg1_k,ddkflag,dtm_k,icg,icg1,itrs,job,maxbd,&
132 : : & mcg_k,mcg_q,mcg1_k,minbd,mpw,mband_occ,nband_occ,npw_k1,npw_k2,nspinor,&
133 : 2369386 : & pwind_k,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_k,smat_k_paw,usepaw)
134 : :
135 : : !Arguments ------------------------------------
136 : : !scalars
137 : : integer,intent(in) :: ddkflag,icg,icg1,itrs,job,maxbd,mcg1_k,mcg_k,mcg_q
138 : : integer,intent(in) :: minbd,mpw,mband_occ,npw_k1,npw_k2,nspinor,shiftbd
139 : : integer,intent(in) :: nband_occ
140 : : integer,intent(in) :: usepaw
141 : : !arrays
142 : : integer,intent(in) :: pwind_k(mpw)
143 : : integer,intent(inout) :: sflag_k(mband_occ)
144 : : real(dp),intent(in) :: cg(2,mcg_k),cgq(2,mcg_q),pwnsfac_k(4,mpw)
145 : : real(dp),intent(in) :: smat_k_paw(2,usepaw*mband_occ,usepaw*mband_occ)
146 : : real(dp),intent(inout) :: smat_k(2,mband_occ,mband_occ)
147 : : real(dp),intent(out) :: cg1_k(2,mcg1_k),dtm_k(2)
148 : : real(dp),intent(out) :: smat_inv(2,mband_occ,mband_occ)
149 : :
150 : : !Local variables -------------------------
151 : : !scalars
152 : : integer :: count,dzgedi_job,iband,info,ipw,ispinor,jband,jband1,jpw,pwmax,pwmin
153 : : integer :: spnshft_k1, spnshft_k2
154 : : real(dp) :: doti,dotr,fac,wfi,wfr
155 : : character(len=500) :: message
156 : : !arrays
157 : 2369386 : integer,allocatable :: ipvt(:)
158 : : ! integer,allocatable :: my_pwind_k(:) ! used in debugging below
159 : : real(dp) :: det(2,2)
160 : 2369386 : real(dp),allocatable :: vect1(:,:),vect2(:,:),zgwork(:,:)
161 : :
162 : : ! ***********************************************************************
163 : :
164 : : !DEBUG
165 : : !write(std_out,*)'smatrix : enter'
166 : : !write(std_out,*)'sflag_k = ',sflag_k
167 : : !write(std_out,'(a,4i4)' )'job, ddkflag, shiftbd, itrs = ',job,ddkflag,shiftbd,itrs
168 : : !write(std_out,'(a,2i6)')' JWZ smatrix.F90 debug : npw_k1, npw_k2 ',npw_k1,npw_k2
169 : : !stop
170 : : !ENDDEBUG
171 : :
172 [ - + + - : 7108158 : ABI_MALLOC(ipvt,(nband_occ))
+ - + - -
+ - + ]
173 [ - + + - : 7108158 : ABI_MALLOC(zgwork,(2,nband_occ))
+ - + - -
+ - + ]
174 [ - + + - : 7108158 : ABI_MALLOC(vect1,(2,0:mpw*nspinor))
+ - + - -
+ - + ]
175 [ - + + - : 4738772 : ABI_MALLOC(vect2,(2,0:mpw*nspinor))
- + - + ]
176 [ + + + + ]: 11846930 : vect1(:,0) = zero ; vect2(:,0) = zero
177 : :
178 : : !Check if the values of ddkflag and job are compatible
179 : :
180 [ + + ]: 2369386 : if ((job /= 0).and.(job /= 1).and.(job /= 10).and.(job /= 11).and.(job/=20).and.(job/=21)) then
181 : : write(message,'(a,i3,a,a)')&
182 : 0 : & ' job is equal to ',job,ch10,&
183 : 0 : & ' while only the values job = 0, 1, 10, 11, 20, or 21 are allowed.'
184 : 0 : ABI_ERROR(message)
185 : : end if
186 : :
187 [ + + ]: 2369386 : if (ddkflag == 1) then
188 [ - + ]: 1055328 : if ((job/=1).and.(job/=11)) then
189 : : write(message,'(a,i0,a,a)')&
190 : 0 : & ' job is equal to ',job,ch10,&
191 : 0 : & ' while ddkflag = 1. This is not allowed.'
192 : 0 : ABI_ERROR(message)
193 : : end if
194 : : end if
195 : :
196 : : !Check the values of sflag_k
197 [ + + ]: 31767322 : do iband=1,nband_occ
198 [ - + ]: 31767322 : if (sflag_k(iband)/=0 .and. sflag_k(iband)/=1)then
199 : : write(message,'(3a,i4,a,i4)')&
200 : 0 : & ' The content of sflag_k must be 0 or 1.',ch10,&
201 : 0 : & ' However, for iband=',iband,', sflag_k(iband)=',sflag_k(iband)
202 : 0 : ABI_ERROR(message)
203 : : end if
204 : : end do
205 : :
206 : : !Check if shiftbd is consistent with sflag_k
207 [ + + ]: 2369386 : if (shiftbd == 0) then
208 : 1049248 : count = 0
209 [ + + ]: 15128228 : do iband = 1, nband_occ
210 [ + + ]: 15128228 : if (sflag_k(iband) == 0) count = count + 1
211 : : end do
212 [ - + ]: 1049248 : if (count > 1) then
213 : 0 : message = 'in case shiftbd = 0, only 1 element of sflag can be 0'
214 : 0 : ABI_ERROR(message)
215 : : end if
216 : : end if
217 : :
218 : : !Update the lines of the overlap matrix for which sflag = 0
219 : : !MVeithen: because of sflag, it is more efficient to perform
220 : : !the loop over jband inside the loop over iband
221 : :
222 : : !DEBUG
223 : : !write(std_out,*)' smatrix : smat_k(1,1,1)=',smat_k(1,1,1)
224 : : !write(std_out,*)' smatrix : sflag_k=',sflag_k
225 : : !ENDDEBUG
226 : :
227 : : !!
228 : : !! debugging based on norm of k1 vector
229 : : !
230 : : !ABI_MALLOC(my_pwind_k,(mpw))
231 : : !!
232 : : !do iband = 1, nband_occ
233 : : !!
234 : : !pwmin = (iband-1)*npw_k1*nspinor*shiftbd
235 : : !pwmax = pwmin + npw_k1*nspinor
236 : : !!
237 : : !!! Multiply the bra wave function by the phase factor
238 : : !if (itrs==1.or.itrs==11) then ! take complex conjugate of bra
239 : : !do ispinor = 1, nspinor
240 : : !spnshft_k1=(ispinor-1)*npw_k1
241 : : !do ipw = 1,npw_k1
242 : : !vect1(1,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw) &
243 : : !& +cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw)
244 : : !vect1(2,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw) &
245 : : !& -cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw)
246 : : !end do
247 : : !end do
248 : : !else
249 : : !do ispinor=1, nspinor
250 : : !spnshft_k1=(ispinor-1)*npw_k1
251 : : !do ipw = 1,npw_k1
252 : : !vect1(1,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw) &
253 : : !& -cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw)
254 : : !vect1(2,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw) &
255 : : !& +cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw)
256 : : !end do
257 : : !end do
258 : : !end if
259 : : !
260 : : !!
261 : : !if (npw_k1*nspinor < mpw*nspinor) vect1(:,npw_k1*nspinor+1:mpw*nspinor) = zero
262 : : !
263 : : !do jband = 1, nband_occ
264 : : !
265 : : !pwmin = (jband-1)*npw_k1*nspinor
266 : : !pwmax = pwmin + npw_k1*nspinor
267 : : !
268 : : !if (itrs==10.or.itrs==11) then ! take complex conjugate of ket
269 : : !do ispinor=1, nspinor
270 : : !spnshft_k2=(ispinor-1)*npw_k1
271 : : !do ipw = 1, npw_k1
272 : : !my_pwind_k(ipw) = ipw
273 : : !vect2(1,spnshft_k2+ipw) = cg(1,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(1,ipw) &
274 : : !& +cg(2,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(2,ipw)
275 : : !vect2(2,spnshft_k2+ipw) = cg(1,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(2,ipw) &
276 : : !& -cg(2,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(1,ipw)
277 : : !end do
278 : : !end do
279 : : !else
280 : : !do ispinor=1, nspinor
281 : : !spnshft_k2=(ispinor-1)*npw_k1
282 : : !do ipw = 1, npw_k1
283 : : !my_pwind_k(ipw) = ipw
284 : : !vect2(1,spnshft_k2+ipw) = cg(1,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(1,ipw) &
285 : : !& -cg(2,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(2,ipw)
286 : : !vect2(2,spnshft_k2+ipw) = cg(1,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(2,ipw) &
287 : : !& +cg(2,icg+spnshft_k2+ipw+pwmin)*pwnsfac_k(1,ipw)
288 : : !end do
289 : : !end do
290 : : !end if
291 : : !!
292 : : !if (npw_k1*nspinor < mpw*nspinor) vect2(:,npw_k1*nspinor+1:mpw*nspinor) = zero
293 : : !!
294 : : !call overlap_g(doti,dotr,mpw,npw_k1,npw_k1,nspinor,my_pwind_k,vect1,vect2)
295 : : !!
296 : : !smat_k(1,iband,jband) = dotr
297 : : !smat_k(2,iband,jband) = doti
298 : : !!
299 : : !if (usepaw == 1) then
300 : : !smat_k(1,iband,jband) = smat_k(1,iband,jband)+smat_k_paw(1,iband,jband)
301 : : !smat_k(2,iband,jband) = smat_k(2,iband,jband)+smat_k_paw(2,iband,jband)
302 : : !end if
303 : : !!
304 : : !if( (smat_k(1,iband,jband)**2+smat_k(2,iband,jband)**2)>tol8) then
305 : : !write(std_out,'(a,i2,a,i2,a,es16.8,a,es16.8)')' JWZ Debug: <',iband,'|',jband,'> = ',&
306 : : !& smat_k(1,iband,jband),' + i ',smat_k(2,iband,jband)
307 : : !end if
308 : : !!
309 : : !end do ! jband
310 : : !!
311 : : !end do ! iband
312 : : !!
313 : : !ABI_FREE(my_pwind_k)
314 : : !!
315 [ + + ]: 31767322 : do iband = 1, nband_occ
316 : :
317 [ + + ]: 31767322 : if (sflag_k(iband) == 0) then
318 : :
319 : 6796856 : pwmin = (iband-1)*npw_k1*nspinor*shiftbd
320 : 6796856 : pwmax = pwmin + npw_k1*nspinor
321 : : !
322 : : ! old version (*** multiply by nspinor missing??? ***)
323 : : ! vect1(:,1:npw_k1) = cg(:,icg + 1 + pwmin:icg + pwmax)
324 : : !
325 : :
326 : : ! Multiply the bra wave function by the phase factor
327 [ + + ]: 6796856 : if (itrs==1.or.itrs==11) then ! take complex conjugate of bra
328 [ + + ]: 1166608 : do ispinor = 1, nspinor
329 : 583304 : spnshft_k1=(ispinor-1)*npw_k1
330 [ + + ]: 70407968 : do ipw = 1,npw_k1
331 : : vect1(1,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw) &
332 : 69241360 : & +cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw)
333 : : vect1(2,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw) &
334 : 69824664 : & -cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw)
335 : : end do
336 : : end do
337 : : else
338 [ + + ]: 12720604 : do ispinor=1, nspinor
339 : 6507052 : spnshft_k1=(ispinor-1)*npw_k1
340 [ + + ]: 960082526 : do ipw = 1,npw_k1
341 : : vect1(1,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw) &
342 : 947361922 : & -cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw)
343 : : vect1(2,spnshft_k1+ipw) = cg(1,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(2,ipw) &
344 : 953868974 : & +cg(2,icg+spnshft_k1+ipw+pwmin)*pwnsfac_k(1,ipw)
345 : : end do
346 : : end do
347 : : end if
348 : :
349 : : !
350 [ + + + + : 112427678 : if (npw_k1*nspinor < mpw*nspinor) vect1(:,npw_k1*nspinor+1:mpw*nspinor) = zero
+ + ]
351 : :
352 [ + + ]: 143501904 : do jband = 1, nband_occ
353 : :
354 : 136705048 : pwmin = (jband-1)*npw_k2*nspinor
355 : 136705048 : pwmax = pwmin + npw_k2*nspinor
356 : :
357 [ + + ]: 136705048 : if (itrs==10.or.itrs==11) then ! take complex conjugate of ket
358 [ + + ]: 74295704 : do ispinor=1, nspinor
359 : 37147852 : spnshft_k2=(ispinor-1)*npw_k2
360 [ + + ]: 6185481456 : do ipw = 1, npw_k2
361 : : vect2(1,spnshft_k2+ipw) = cgq(1,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(3,ipw) &
362 : 6111185752 : & +cgq(2,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(4,ipw)
363 : : vect2(2,spnshft_k2+ipw) = cgq(1,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(4,ipw) &
364 : 6148333604 : & -cgq(2,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(3,ipw)
365 : : end do
366 : : end do
367 : : else
368 [ + + ]: 201462392 : do ispinor=1, nspinor
369 : 101905196 : spnshft_k2=(ispinor-1)*npw_k2
370 [ + + ]: 16955831628 : do ipw = 1, npw_k2
371 : : vect2(1,spnshft_k2+ipw) = cgq(1,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(3,ipw) &
372 : 16754369236 : & -cgq(2,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(4,ipw)
373 : : vect2(2,spnshft_k2+ipw) = cgq(1,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(4,ipw) &
374 : 16856274432 : & +cgq(2,icg1+spnshft_k2+ipw+pwmin)*pwnsfac_k(3,ipw)
375 : : end do
376 : : end do
377 : : end if
378 : :
379 [ + + + + : 2207792428 : if (npw_k2*nspinor < mpw*nspinor) vect2(:,npw_k2*nspinor+1:mpw*nspinor) = zero
+ + ]
380 : :
381 : : ! DEBUG
382 : : ! if(iband==1 .and. jband==1 .and. itrs==0 .and. npw_k1==68 .and. npw_k2==74)then
383 : : ! write(std_out,'(a)' )' smatrix : ii,vect1,cg,pwnsfac='
384 : : ! do ii=1,npw_k1
385 : : ! write(std_out,'(i4,6es16.6)' )ii,vect1(:,ii),cg(:,icg+ii+pwmin),pwnsfac_k(1:2,ii)
386 : : ! end do
387 : : ! do ii=1,npw_k2
388 : : ! write(std_out,'(i4,6es16.6)' )ii,vect2(:,ii),cg(:,icg1+ii+pwmin),pwnsfac_k(3:4,ii)
389 : : ! end do
390 : : ! end if
391 : : ! ENDDEBUG
392 : :
393 : 136705048 : call overlap_g(doti,dotr,mpw,npw_k1,npw_k2,nspinor,pwind_k,vect1,vect2)
394 : :
395 : 136705048 : smat_k(1,iband,jband) = dotr
396 : 136705048 : smat_k(2,iband,jband) = doti
397 : :
398 [ + + ]: 143501904 : if (usepaw == 1) then
399 : 8172096 : smat_k(1,iband,jband) = smat_k(1,iband,jband)+smat_k_paw(1,iband,jband)
400 : 8172096 : smat_k(2,iband,jband) = smat_k(2,iband,jband)+smat_k_paw(2,iband,jband)
401 : : end if
402 : :
403 : : ! DEBUG
404 : : ! if(iband==1 .and. jband==1)then
405 : : ! write(std_out,'(a,2es16.6,3i4)' )' smatrix : dotr,smat_k(1,iband,jband),mpw,npw_k1,npw_k2',dotr,smat_k(1,iband,jband),mpw,npw_k1,npw_k2
406 : : ! end if
407 : : ! ENDDEBUG
408 : :
409 : : end do ! jband
410 : :
411 : : end if ! sflag_k(iband) == 0
412 : :
413 : : end do ! iband
414 : :
415 : : !DEBUG
416 : : !do iband=1,nband_occ
417 : : !do jband=1,nband_occ
418 : : !write(std_out,'(a,2i4,2e20.10)') 'smat',iband,jband,smat_k(1,iband,jband),smat_k(2,iband,jband)
419 : : !end do
420 : : !end do
421 : : !write(std_out,*)' smatrix : smat_k(1,1,1)=',smat_k(1,1,1)
422 : : !ENDDEBUG
423 : :
424 : : !Update sflag_k
425 [ + + ]: 31767322 : sflag_k(:) = 1
426 : :
427 : : !Depending on the value of job, compute the determinant of the
428 : : !overlap matrix, its inverse or the product of the inverse
429 : : !overlap matrix with the WF at k.
430 : :
431 [ + - ]: 2369386 : if ((job==1).or.(job==10).or.(job==11).or.(job==21)) then
432 : :
433 [ + + + + : 2373532522 : smat_inv(:,:,:) = smat_k(:,:,:)
+ + ]
434 : :
435 : : ! DEBUG
436 : : ! write(std_out,*)' smatrix : smat_inv=',smat_inv
437 : : ! ENDDEBUG
438 : :
439 [ - + ]: 2369386 : dzgedi_job=job; if(job==21) dzgedi_job=1
440 : : ! TODO: should this be over nband_occ(isppol)?
441 : 2369386 : call dzgefa(smat_inv,mband_occ,nband_occ,ipvt,info)
442 : 2369386 : call dzgedi(smat_inv,mband_occ,nband_occ,ipvt,det,zgwork,dzgedi_job)
443 : :
444 : : ! DEBUG
445 : : ! write(std_out,*)' smatrix : det=',det
446 : : ! ENDDEBUG
447 : :
448 : : ! Compute the determinant of the overlap matrix
449 : 2369386 : dtm_k(:) = zero
450 [ + + ]: 2369386 : if (job==10 .or. job==11) then
451 : 2363402 : fac = exp(log(10._dp)*det(1,2))
452 : : dtm_k(1) = fac*(det(1,1)*cos(log(10._dp)*det(2,2)) - &
453 : 2363402 : & det(2,1)*sin(log(10._dp)*det(2,2)))
454 : : dtm_k(2) = fac*(det(1,1)*sin(log(10._dp)*det(2,2)) + &
455 : 2363402 : & det(2,1)*cos(log(10._dp)*det(2,2)))
456 : : end if
457 : :
458 : : ! Compute the product of the inverse overlap matrix with the WF
459 : :
460 [ + + ]: 2369386 : if (ddkflag == 1) then
461 : :
462 [ + + + + ]: 446370900 : cg1_k(:,:) = zero
463 : 1055328 : jband1 = 0
464 : :
465 [ + + ]: 1055328 : if (itrs == 10 .or. itrs == 11) then
466 : :
467 [ + + ]: 377368 : do jband = minbd, maxbd
468 : 188684 : jband1 = jband1 + 1
469 [ + + ]: 3696414 : do iband = 1, nband_occ
470 : :
471 [ + + ]: 6826776 : do ispinor = 1, nspinor
472 : 3319046 : spnshft_k1 = (ispinor-1)*npw_k1
473 : 3319046 : spnshft_k2 = (ispinor-1)*npw_k2
474 [ + + ]: 544516846 : do ipw = 1, npw_k1
475 : :
476 : 537878754 : jpw = pwind_k(ipw)
477 : :
478 [ + + ]: 541197800 : if (jpw > 0) then
479 : :
480 : : wfr = cgq(1,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)&
481 : 503615708 : & -cgq(2,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)
482 : : wfi = cgq(1,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)&
483 : 503615708 : & +cgq(2,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)
484 : :
485 : : cg1_k(1,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = &
486 : : & cg1_k(1,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) + &
487 : 503615708 : & smat_inv(1,iband,jband)*wfr + smat_inv(2,iband,jband)*wfi
488 : :
489 : : cg1_k(2,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = &
490 : : & cg1_k(2,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) - &
491 : 503615708 : & smat_inv(1,iband,jband)*wfi + smat_inv(2,iband,jband)*wfr
492 : :
493 : : end if
494 : :
495 : : end do ! end loop over npw_k1
496 : : end do ! end loop over nspinor
497 : :
498 : : end do
499 : : end do
500 : :
501 : : else
502 : :
503 [ + + ]: 1752040 : do jband = minbd, maxbd
504 : 885396 : jband1 = jband1 + 1
505 [ + + ]: 12615398 : do iband = 1, nband_occ
506 : :
507 [ + + ]: 23143808 : do ispinor = 1, nspinor
508 : 11395054 : spnshft_k1 = (ispinor-1)*npw_k1
509 : 11395054 : spnshft_k2 = (ispinor-1)*npw_k2
510 [ + + ]: 1799568542 : do ipw = 1, npw_k1
511 : :
512 : 1777310130 : jpw = pwind_k(ipw)
513 : :
514 [ + + ]: 1788705184 : if (jpw > 0) then
515 : :
516 : : wfr = cgq(1,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)&
517 : 1666755170 : & -cgq(2,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)
518 : : wfi = cgq(1,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)&
519 : 1666755170 : & +cgq(2,icg1+(iband-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)
520 : :
521 : : cg1_k(1,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = &
522 : : & cg1_k(1,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) + &
523 : 1666755170 : & smat_inv(1,iband,jband)*wfr - smat_inv(2,iband,jband)*wfi
524 : :
525 : : cg1_k(2,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = &
526 : : & cg1_k(2,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) + &
527 : 1666755170 : & smat_inv(1,iband,jband)*wfi + smat_inv(2,iband,jband)*wfr
528 : :
529 : : end if
530 : :
531 : : end do ! end loop over npw_k1
532 : : end do ! end loop over nspinor
533 : :
534 : : end do
535 : : end do
536 : :
537 : : end if ! itrs
538 : :
539 : : end if
540 : :
541 : : end if !
542 : :
543 [ - + ]: 2369386 : if(job == 20 .or. job == 21) then ! special case transfering cgq to cg1_k without use of S^{-1}, used in
544 : : ! magnetic field case
545 : :
546 [ # # # # ]: 0 : cg1_k(:,:) = zero
547 : 0 : jband1 = 0
548 : :
549 [ # # ]: 0 : if (itrs == 10 .or. itrs == 11) then
550 : :
551 [ # # ]: 0 : do jband = minbd, maxbd
552 : 0 : jband1 = jband1 + 1
553 [ # # ]: 0 : do ispinor = 1, nspinor
554 : 0 : spnshft_k1 = (ispinor-1)*npw_k1
555 : 0 : spnshft_k2 = (ispinor-1)*npw_k2
556 [ # # ]: 0 : do ipw = 1, npw_k1
557 : 0 : jpw = pwind_k(ipw)
558 : :
559 [ # # ]: 0 : if (jpw > 0) then
560 : : wfr = cgq(1,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)&
561 : 0 : & -cgq(2,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)
562 : : wfi = cgq(1,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)&
563 : 0 : & +cgq(2,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)
564 : :
565 : 0 : cg1_k(1,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = wfr
566 : 0 : cg1_k(2,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = wfi
567 : :
568 : : end if
569 : :
570 : : end do ! end loop over npw_k1
571 : : end do ! end loop over nspinor
572 : :
573 : : end do
574 : :
575 : : else
576 : :
577 [ # # ]: 0 : do jband = minbd, maxbd
578 : 0 : jband1 = jband1 + 1
579 [ # # ]: 0 : do ispinor = 1, nspinor
580 : 0 : spnshft_k1 = (ispinor-1)*npw_k1
581 : 0 : spnshft_k2 = (ispinor-1)*npw_k2
582 [ # # ]: 0 : do ipw = 1, npw_k1
583 : 0 : jpw = pwind_k(ipw)
584 : :
585 [ # # ]: 0 : if (jpw > 0) then
586 : :
587 : : wfr = cgq(1,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)&
588 : 0 : & -cgq(2,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)
589 : : wfi = cgq(1,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(4,jpw)&
590 : 0 : +cgq(2,icg1+(jband1-1)*npw_k2*nspinor+spnshft_k2+jpw)*pwnsfac_k(3,jpw)
591 : :
592 : 0 : cg1_k(1,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = wfr
593 : 0 : cg1_k(2,(jband1-1)*npw_k1*nspinor + spnshft_k1 + ipw) = wfi
594 : :
595 : : end if
596 : :
597 : : end do ! end loop over npw_k1
598 : : end do ! end loop over nspinor
599 : :
600 : : end do
601 : :
602 : : end if ! itrs
603 : :
604 : : end if ! end job == 20 .or. job == 21 case
605 : :
606 [ - + ]: 2369386 : ABI_FREE(ipvt)
607 [ - + ]: 2369386 : ABI_FREE(zgwork)
608 [ - + ]: 2369386 : ABI_FREE(vect1)
609 [ - + ]: 2369386 : ABI_FREE(vect2)
610 : :
611 : : !DEBUG
612 : : !write(std_out,*)' dtm_k=',dtm_k(:)
613 : : !write(std_out,*)' smatrix : exit '
614 : : !ENDDEBUG
615 : :
616 : 2369386 : end subroutine smatrix
617 : : !!***
618 : :
619 : : !!****f* ABINIT/polcart
620 : : !! NAME
621 : : !! polcart
622 : : !!
623 : : !! FUNCTION
624 : : !! Transform polarization from reduced to cartesian coordinates,
625 : : !! divide by ucvol and write the result to an output file
626 : : !!
627 : : !! INPUTS
628 : : !! pel(3) = reduced coordinates of the electronic polarization
629 : : !! pion(3) = reduced coordinates of the ionic polarization
630 : : !! polunit = units used for the output of the polarization
631 : : !! 1 : use atomic units
632 : : !! 2 : use MKS units
633 : : !! 3 : use both atomic and MKS units
634 : : !! rprimd(3,3) = dimensional primitive translations (bohr)
635 : : !! ucvol = volume of the primitive unit cell
636 : : !! unit_out = unit for output of the results
637 : : !! usepaw = 1 for PAW computation, zero else
638 : : !!
639 : : !! OUTPUT
640 : : !! pel_cart(3) = cartesian coords of the electronic polarization
641 : : !! in atomic units
642 : : !! pelev(3)= expectation value polarization term (PAW only) in cartesian coordinates
643 : : !! pion_cart(3)= cartesian coords of the ionic polarization
644 : : !! in atomic units
645 : : !! ptot_cart(3)= cartesian coords of the total polarization
646 : : !! in atomic units
647 : : !!
648 : : !! NOTES
649 : : !! - The sum of the electronic and ionic Berry phase is folded into
650 : : !! [-1,1] before it is transformed to cartesian coordinates.
651 : : !! This means that in some cases, ptot_cart /= pel_cart + pion_cart
652 : : !!
653 : : !! - pel and pion do not take into account the factor 1/ucvol.
654 : : !! At the opposite, this factor is taken into account in
655 : : !! pel_cart and pion_cart
656 : : !! - unit_out = 0 is allowed, in this case, there will be no
657 : : !! output of the results
658 : : !!
659 : : !! SOURCE
660 : :
661 : 270 : subroutine polcart(red_ptot,pel,pel_cart,pelev,pion,pion_cart,polunit,&
662 : : & ptot_cart,rprimd,ucvol,unit_out,usepaw)
663 : :
664 : : !Arguments ------------------------------------
665 : : !scalars
666 : : integer,intent(in) :: polunit,unit_out,usepaw
667 : : real(dp),intent(in) :: ucvol
668 : : !arrays
669 : : real(dp),intent(in) :: red_ptot(3) !!REC
670 : : real(dp),intent(in) :: pel(3),pelev(3),pion(3),rprimd(3,3)
671 : : real(dp),intent(out) :: pel_cart(3),pion_cart(3),ptot_cart(3)
672 : :
673 : : !Local variables -------------------------
674 : : !scalars
675 : : integer :: idir
676 : : character(len=500) :: message
677 : : !arrays
678 : : real(dp) :: pel_mks(3),pelev_mks(3),pion_mks(3),ptot(3),ptot_mks(3)
679 : :
680 : : ! GA: - The input/ouput description above is wrong.
681 : : ! - Why do we care whether we used PAW?
682 : :
683 : : ! ***********************************************************************
684 : : !!REC Note ptot has already been folded and kept onto same branch
685 : : !unless ptot=0d0, in which case ptot has not been computed yet
686 [ + + + + ]: 1080 : if( sum(abs(red_ptot(:))) < tol8 )then
687 [ + + ]: 24 : ptot(:) = pel(:) + pion(:)
688 : : ! Fold ptot into [-1, 1]
689 [ + + ]: 24 : do idir = 1, 3
690 : 24 : ptot(idir) = ptot(idir) - 2_dp*nint(ptot(idir)/2_dp)
691 : : end do
692 : : else !!REC
693 : 264 : ptot=red_ptot !!REC
694 : : end if !!REC
695 : :
696 : : !Transform pel, pion and ptot to cartesian coordinates
697 : 270 : pel_cart(:) = zero ; pion_cart(:) = zero ; ptot_cart(:) = zero
698 [ + + ]: 1080 : do idir = 1, 3
699 : : pel_cart(idir) = rprimd(idir,1)*pel(1) + rprimd(idir,2)*pel(2) + &
700 : 810 : & rprimd(idir,3)*pel(3)
701 : : pion_cart(idir) = rprimd(idir,1)*pion(1) + rprimd(idir,2)*pion(2) + &
702 : 810 : & rprimd(idir,3)*pion(3)
703 : : ptot_cart(idir) = rprimd(idir,1)*ptot(1) + rprimd(idir,2)*ptot(2) + &
704 : 1080 : & rprimd(idir,3)*ptot(3)
705 : : end do
706 : :
707 : : !Divide by the unit cell volume
708 [ + + ]: 1080 : pel_cart(:) = pel_cart(:)/ucvol
709 [ + + ]: 1080 : pion_cart(:) = pion_cart(:)/ucvol
710 [ + + ]: 1080 : ptot_cart(:) = ptot_cart(:)/ucvol
711 : : !pelev is either zero (in NCPP case), or possibly non-zero (in PAW case)
712 : : !however, in the PAW case, it is already implicitly included in the computation
713 : : !of pel and should not be added in here. Below in the PAW case we report its
714 : : !value to the user, which is helpful for comparison to the USPP theory.
715 : : !13 June 2012 J Zwanziger
716 : : !note that pelev was AlREADY in cartesian frame.
717 : : !ptot_cart(:) = (ptot_cart(:)+pelev(:))/ucvol
718 : :
719 : : !Write the results to unit_out (if /= 0)
720 : : !Use the coordinates specified by the value polunit
721 : :
722 : : !Atomic units
723 : :
724 [ + - + + ]: 270 : if (((polunit == 1).or.(polunit == 3)).and.(unit_out /= 0)) then
725 : :
726 : : ! write(message,'(7(a),3(e16.9,2x),a,a,3(e16.9,2x),a,a,3(e16.9,2x),a,a,3(e16.9,2x))')ch10,&
727 : : ! & ' Polarization in cartesian coordinates (a.u.):',ch10,&
728 : : ! & ' (the sum of the electronic and ionic Berry phase',&
729 : : ! & ' has been fold into [-1, 1])',ch10,&
730 : : ! & ' Electronic berry phase: ', (pel_cart(idir), idir = 1, 3), ch10,&
731 : : ! & ' Expectation value (PAW only): ', (pelev(idir)/ucvol, idir = 1, 3), ch10,&
732 : : ! & ' Ionic: ', (pion_cart(idir), idir = 1, 3), ch10, &
733 : : ! & ' Total: ', (ptot_cart(idir), idir = 1, 3)
734 : : ! call wrtout(unit_out,message,'COLL')
735 : 79 : write(message,'(7(a),3(e16.9,2x),a,a,3(e16.9,2x))')ch10,&
736 : 79 : & ' Polarization in cartesian coordinates (a.u.):',ch10,&
737 : 79 : & ' (the sum of the electronic and ionic Berry phase',&
738 : 79 : & ' has been folded into [-1, 1])',ch10,&
739 : 158 : & ' Electronic berry phase: ', (pel_cart(idir), idir = 1, 3)
740 : 79 : call wrtout(unit_out,message,'COLL')
741 [ + + ]: 79 : if(usepaw==1) then
742 : : write(message,'(a,3(e16.9,2x))')&
743 [ + - + + ]: 120 : & ' ...includes PAW on-site term: ', (pelev(idir)/ucvol, idir = 1, 3)
744 : 30 : call wrtout(unit_out,message,'COLL')
745 : : end if
746 : : write(message,'(a,3(e16.9,2x),a,a,3(e16.9,2x))')&
747 : 79 : & ' Ionic: ', (pion_cart(idir), idir = 1, 3), ch10, &
748 : 158 : & ' Total: ', (ptot_cart(idir), idir = 1, 3)
749 : 79 : call wrtout(unit_out,message,'COLL')
750 : :
751 : : end if
752 : :
753 : : !MKS units
754 : :
755 [ + - + + ]: 270 : if (((polunit == 2).or.(polunit == 3)).and.(unit_out /= 0)) then
756 : :
757 [ + + ]: 316 : pel_mks(:) = pel_cart(:)*(e_Cb)/(Bohr_Ang*1d-10)**2
758 [ + + ]: 316 : pion_mks(:) = pion_cart(:)*(e_Cb)/(Bohr_Ang*1d-10)**2
759 [ + + ]: 316 : pelev_mks(:) = pelev(:)/ucvol*(e_Cb)/(Bohr_Ang*1d-10)**2
760 [ + + ]: 316 : ptot_mks(:) = (ptot_cart(:))*(e_Cb)/(Bohr_Ang*1d-10)**2
761 : :
762 : 79 : write(message,'(7(a),3(e16.9,2x),a,a,3(e16.9,2x),a,a,3(e16.9,2x),a,a,3(e16.9,2x))')ch10,&
763 : 79 : & ' Polarization in cartesian coordinates (C/m^2):',ch10,&
764 : 79 : & ' (the sum of the electronic and ionic Berry phase',&
765 : 79 : & ' has been folded into [-1, 1])',ch10,&
766 : 158 : & ' Electronic berry phase: ', (pel_mks(idir), idir = 1, 3)
767 : 79 : call wrtout(unit_out,message,'COLL')
768 [ + + ]: 79 : if(usepaw==1) then
769 : : write(message,'(a,3(e16.9,2x))')&
770 : 30 : & ' ...includes PAW on-site term: ', (pelev_mks(idir), idir = 1, 3)
771 : 30 : call wrtout(unit_out,message,'COLL')
772 : : end if
773 : : write(message,'(a,3(e16.9,2x),a,a,3(e16.9,2x))')&
774 : 79 : & ' Ionic: ', (pion_mks(idir), idir = 1, 3), ch10, &
775 : 158 : & ' Total: ', (ptot_mks(idir), idir = 1, 3)
776 : 79 : call wrtout(unit_out,message,'COLL')
777 : :
778 : : end if
779 : :
780 : 270 : end subroutine polcart
781 : : !!***
782 : :
783 : : end module m_berrytk
784 : : !!***
|