Line data Source code
1 : !!****m* ABINIT/m_berryphase
2 : !! NAME
3 : !! m_berryphase
4 : !!
5 : !! FUNCTION
6 : !!
7 : !! COPYRIGHT
8 : !! Copyright (C) 2000-2026 ABINIT group (NSAI,XG,MKV)
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_berryphase
22 :
23 : use defs_basis
24 : use m_errors
25 : use m_abicore
26 : use m_hdr
27 : use m_dtset
28 :
29 : use m_geometry, only : xred2xcart
30 : use m_hide_lapack, only : dzgedi, dzgefa
31 : use m_matrix, only : matr3inv
32 :
33 : implicit none
34 :
35 : private
36 : !!***
37 :
38 : public :: berryphase
39 : !!***
40 :
41 : contains
42 : !!***
43 :
44 : !!****f* ABINIT/berryphase
45 : !! NAME
46 : !! berryphase
47 : !!
48 : !! FUNCTION
49 : !! This routine is called in scfcv.f to compute the electronic Berry Phase
50 : !! polarization and the ionic contribution to the polarization
51 : !! Work for nsppol=1 or 2 ,but only accept nspinor=1, and mkmem=nkpt
52 : !! or 0, kptopt = 2 or 3
53 : !!
54 : !! INPUTS
55 : !! atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
56 : !! bdberry(4)=band limits for Berry phase contributions,
57 : !! spin up and spin down (bdberry(3:4) is irrelevant when nsppol=1)
58 : !! cg(2,mcg)=planewave coefficients of wavefunctions
59 : !! gprimd(3,3)=reciprocal space dimensional primitive translations
60 : !! istwfk(nkpt_)=input option parameter that describes the storage of wfs
61 : !! kberry(3,nberry)= different delta k for Berry phases, in unit of kptrlatt
62 : !! only kberry(1:3,1:nberry) is relevant
63 : !! kg(3,mpw*mkmem)=reduced planewave coordinates
64 : !! kpt_(3,nkpt_)=reduced coordinates of k points generated by ABINIT,
65 : !! kpt_ sampels half the BZ if time-reversal symetrie is used
66 : !! kptopt=2 when time-reversal symetrie is used
67 : !! =3 when time-reversal symetrie is not used
68 : !! kptrlatt(3,3)=k-point lattice specification
69 : !! mband=maximum number of bands
70 : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
71 : !! mkmem=number of k points treated by this node.
72 : !! mpw=maximum dimensioned size of npw
73 : !! natom=number of atoms in cell
74 : !! nattyp(ntypat)= # atoms of each type.
75 : !! nband(nkpt*nsppol)=number of bands at each k point, for each polarization
76 : !! nberry=number of Berry phases to be computed
77 : !! nkpt=number of k points
78 : !! npwarr(nkpt)=number of planewaves in basis at this k point
79 : !! nspinor=number of spinorial components (on current proc)
80 : !! nsppol=1 for unpolarized, 2 for spin-polarized
81 : !! ntypat=number of types of atoms in unit cell
82 : !! nkpt_=number of k points generated by ABINIT, (see kpt_)
83 : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
84 : !! ucvol=unit cell volume in bohr**3.
85 : !! xred(3,natom)=reduced atomic coordinates
86 : !! zion(ntypat)=valence charge of each type of atom
87 : !!
88 : !! OUTPUT
89 : !! (the polarization is printed)
90 : !!
91 : !! SIDE EFFECTS
92 : !!
93 : !! TODO
94 : !! Cleaning, checking for rules.
95 : !! Should allow for time-reversal symmetry (istwfk)
96 : !! Should use randac to scan rapidly the wf file
97 : !!
98 : !! NOTES
99 : !! Local Variables:
100 : !! cmatrix(:,:,:)= overlap matrix of size maxband*maxband
101 : !! cg_index(:,:,:)= unpacked cg index array for specific band,
102 : !! k point and polarization.
103 : !! det(2,2)= intermediate output of Lapack routine zgedi.f
104 : !! determinant(:,:)= determinant of cmatrix
105 : !! det_average(2)= averaged det_string over all strings
106 : !! det_string(:,:)= determinant product of cmatrices along each string
107 : !! dk(3)= step taken to the next k mesh point along the kberry direction
108 : !! dkptnext(3)= step between the next and current k point
109 : !! dphase= phase angle computed from rel_string(2)
110 : !! gpard(3)= dimensionalreciprocal lattice vector G along which the
111 : !! polarization is computed
112 : !! kg_kpt(:,:,:)= unpacked reduced planewave coordinates with subscript of
113 : !! planewave and k point
114 : !! kpt(3,nkpt)=reduced coordinates of k-point grid that samples the whole BZ
115 : !! kpt_flag(nkpt)=kpt_flag(ikpt)=0 when the wf was generated by the ABINIT code
116 : !! kpt_flag(ikpt) gives the indices of the k-point related
117 : !! to ikpt by time reversal symetrie
118 : !! kpt_mark(nkpt)= 0, if k point is unmarked; 1, if k point has been marked
119 : !! maxband/minband= control the minimum and maximum band calculated in the
120 : !! overlap matrix
121 : !! nkstr= number of k points per string
122 : !! npw_k= npwarr(ikpt), number of planewaves in basis at this k point
123 : !! nstr= number of k point strings
124 : !! nkpt=number of k points in the whole BZ
125 : !! phase0= phase angle computed from det_average(2)
126 : !! polberry(:)= berry phase of each string (2/nsppol)*(phase0+dphase)/two_pi
127 : !! polb(isppol) = total berry phase polarization for each spin
128 : !! polbtot= total berry phase polarization
129 : !! polion= ionic polarization for each ion
130 : !! politot= total ionic polarization
131 : !! poltot= total polarization = polbtot + politot
132 : !! rel_string(2)= det_string(2)/det_average(2)
133 : !! shift_g(nkpt)= .true. if the k point should be shifted by a G vector;
134 : !! .false. if not
135 : !! tr(2)=variable that changes k to -k
136 : !! G to -G
137 : !! $c_g$ to $c_g^*$
138 : !! when time-reversal symetrie is used
139 : !! xcart(3,natom)= cartesian coordinates of atoms (bohr)
140 : !! xcart_reindex(:,:,:)= unpack xcart for each atomic species and number
141 : !! of atoms for each species
142 : !!
143 : !! WARNING
144 : !! This routine is not yet memory optimized
145 : !! It might be also rather time-consuming, since there is a
146 : !! double loop on the number of plane waves.
147 : !!
148 : !! SOURCE
149 :
150 0 : subroutine berryphase(atindx1,bdberry,cg,gprimd,istwfk,kberry,kg,kpt_,&
151 : & kptopt,kptrlatt,mband,mcg,&
152 0 : & mkmem,mpw,natom,nattyp,nband,nberry,npwarr,nspinor,nsppol,ntypat,&
153 0 : & nkpt_,rprimd,ucvol,xred,zion)
154 :
155 : !Arguments ------------------------------------
156 : !scalars
157 : integer,intent(in) :: kptopt,mband,mcg,mkmem,mpw,natom,nberry,nkpt_
158 : integer,intent(in) :: nspinor,nsppol,ntypat
159 : real(dp),intent(in) :: ucvol
160 : !arrays
161 : integer,intent(in) :: atindx1(natom),bdberry(4),istwfk(nkpt_),kberry(3,nberry)
162 : integer,intent(in) :: kg(3,mpw*mkmem),kptrlatt(3,3),nattyp(ntypat)
163 : integer,intent(in) :: nband(nkpt_*nsppol),npwarr(nkpt_)
164 : real(dp),intent(in) :: cg(2,mcg),gprimd(1:3,1:3)
165 : real(dp),intent(in) :: kpt_(3,nkpt_),rprimd(3,3),xred(3,natom),zion(ntypat)
166 :
167 : !Local variables -------------------------
168 : !scalars
169 : integer :: band_in,cg_index_iband,cg_index_jband,flag1,iatom
170 : integer :: iattyp,iband,iberry,icg,ii,ikpt,ikpt2,index,index1,info
171 : integer :: ipw,isppol,istr,itypat,iunmark,jband,jj,jkpt,jkstr
172 : integer :: jkstr_ori,jpw,lkstr,lkstr_ori,lkstr_ori_,maxband
173 : integer :: minband,nband_k,nkpt,nkstr,npw_k,nstr,read_k
174 : real(dp) :: det_mod,dphase,fac,gmod,phase0,pol,polbtot,polion,politot
175 : real(dp) :: poltot
176 : character(len=500) :: message
177 : !arrays
178 0 : integer :: dg(3),kpt_flag(2*nkpt_),kpt_mark(2*nkpt_)
179 0 : integer,allocatable :: cg_index(:,:,:),ikpt_dk(:),ikstr(:,:),ipvt(:)
180 0 : integer,allocatable :: kg_dum(:,:),kg_kpt(:,:,:)
181 : real(dp) :: det(2,2),det_average(2),diffk(3),dk(3),gpard(3)
182 0 : real(dp) :: klattice(3,3),kptrlattr(3,3),polb(nsppol),rel_string(2),tr(2)
183 0 : real(dp) :: xcart(3,natom)
184 0 : real(dp),allocatable :: cmatrix(:,:,:),det_string(:,:)
185 0 : real(dp),allocatable :: det_tmp(:,:),determinant(:,:),kpt(:,:)
186 0 : real(dp),allocatable :: polberry(:),xcart_reindex(:,:,:)
187 0 : real(dp),allocatable :: zgwork(:,:)
188 0 : logical,allocatable :: shift_g(:)
189 :
190 : ! ***********************************************************************
191 :
192 : !DEBUG
193 : !write(std_out,*)' berryphase : enter '
194 : !ENDDEBUG
195 :
196 0 : if(nspinor==2)then
197 0 : message = ' berryphase : does not yet work for nspinor=2'
198 0 : ABI_ERROR(message)
199 : end if
200 :
201 0 : if(maxval(istwfk(:))/=1)then
202 : write(message, '(a,a,a)' )&
203 0 : & ' Sorry, this routine does not work yet with istwfk/=1.',ch10,&
204 0 : & ' This should have been tested previously ...'
205 0 : ABI_BUG(message)
206 : end if
207 :
208 : !change8: set up the whole k point grid in the case where kptopt = 2
209 0 : if (kptopt==3) then
210 0 : nkpt = nkpt_
211 0 : ABI_MALLOC(kpt,(3,nkpt))
212 0 : kpt(:,:)=kpt_(:,:)
213 0 : else if (kptopt==2) then
214 0 : nkpt = nkpt_*2
215 0 : ABI_MALLOC(kpt,(3,nkpt))
216 0 : do ikpt = 1,nkpt/2
217 0 : kpt_flag(ikpt) = 0
218 0 : kpt(:,ikpt)=kpt_(:,ikpt)
219 : end do
220 0 : index = 0
221 0 : do ikpt = (nkpt/2+1),nkpt
222 0 : flag1 = 0
223 0 : do jkpt = 1, nkpt/2
224 : if (((abs(kpt_(1,ikpt-nkpt/2)+kpt_(1,jkpt))<1.0d-8).or.&
225 : & (abs(1-abs(kpt_(1,ikpt-nkpt/2)+kpt_(1,jkpt)))<1.0d-8))&
226 : & .and.((abs(kpt_(2,ikpt-nkpt/2)+kpt_(2,jkpt))<1.0d-8).or.&
227 : & (abs(1-abs(kpt_(2,ikpt-nkpt/2)+kpt_(2,jkpt)))<1.0d-8))&
228 0 : & .and.((abs(kpt_(3,ikpt-nkpt/2)+kpt_(3,jkpt))<1.0d-8).or.&
229 0 : & (abs(1-abs(kpt_(3,ikpt-nkpt/2)+kpt_(3,jkpt)))<1.0d-8))) then
230 0 : flag1 = 1
231 0 : index = index + 1
232 : exit
233 : end if
234 : end do
235 0 : if (flag1==0) then
236 0 : kpt_flag(ikpt-index)=ikpt-nkpt/2
237 0 : kpt(:,ikpt-index)=-kpt_(:,ikpt-nkpt/2)
238 : end if
239 : end do
240 0 : nkpt = nkpt - index
241 : end if
242 :
243 : !change8
244 :
245 0 : ABI_MALLOC(shift_g,(nkpt))
246 0 : ABI_MALLOC(kg_dum,(3,0))
247 :
248 : !Compute primitive vectors of the k point lattice
249 : !Copy to real(dp)
250 0 : kptrlattr(:,:)=kptrlatt(:,:)
251 : !Go to reciprocal space (in reduced coordinates)
252 0 : call matr3inv(kptrlattr,klattice)
253 :
254 0 : do iberry=1,nberry
255 :
256 : ! Calculate dimensional recip lattice vector along which P is calculated
257 : ! dk = step to the nearest k point along that direction
258 : ! in reduced coordinates
259 : dk(:)=kberry(1,iberry)*klattice(:,1)+&
260 : & kberry(2,iberry)*klattice(:,2)+&
261 0 : & kberry(3,iberry)*klattice(:,3)
262 0 : gpard(:)=dk(1)*gprimd(:,1)+dk(2)*gprimd(:,2)+dk(3)*gprimd(:,3)
263 0 : gmod=sqrt(dot_product(gpard,gpard))
264 :
265 : ! *****************************************************************************
266 : ! Select the k grid points along the kberry direction
267 : ! dk = step to the nearest k point along that direction
268 :
269 : ! For each k point, find k_prim such that k_prim= k + dk mod(G)
270 : ! where G is a vector of the reciprocal lattice
271 0 : ABI_MALLOC(ikpt_dk,(nkpt))
272 0 : shift_g(:)= .false.
273 0 : do ikpt=1,nkpt
274 0 : do ikpt2=1,nkpt
275 0 : diffk(:)=abs(kpt(:,ikpt2)-kpt(:,ikpt)-dk(:))
276 0 : if(sum(abs(diffk(:)-nint(diffk(:))))<3*tol8)then
277 0 : ikpt_dk(ikpt)=ikpt2
278 0 : if(sum(diffk(:))>=3*tol8)shift_g(ikpt2) = .true.
279 : exit
280 : end if
281 : end do
282 : end do
283 :
284 : ! DEBUG
285 : ! do ikpt = 1,nkpt
286 : ! write(100,*)'ikpt_dk = ',ikpt_dk(ikpt)
287 : ! if (shift_g(ikpt))then
288 : ! write(100,*)'true'
289 : ! else
290 : ! write(100,*)'false'
291 : ! end if
292 : ! write(100,*)''
293 : ! end do
294 : ! ENDDEBUG
295 :
296 : ! Find the string length, starting from k point 1
297 : ! (all strings must have the same number of points)
298 0 : nkstr=1
299 0 : ikpt2=1
300 0 : do ikpt=1,nkpt
301 0 : ikpt2=ikpt_dk(ikpt2)
302 0 : if(ikpt2==1)exit
303 0 : nkstr=nkstr+1
304 : end do
305 :
306 : ! Check that the string length is a divisor of nkpt
307 0 : if(mod(nkpt,nkstr)/=0)then
308 0 : write(message,'(a,a,a,a,i5,a,i7)')ch10,&
309 0 : & ' berryphase: BUG -',ch10,&
310 0 : & ' The string length=',nkstr,', is not a divisor of nkpt=',nkpt
311 0 : call wrtout(std_out,message,'COLL')
312 : end if
313 0 : nstr=nkpt/nkstr
314 :
315 0 : write(message,'(a,a,a,3f9.5,a,a,3f9.5,a)')ch10,&
316 0 : & ' Computing the polarization (Berry phase) for reciprocal vector:',ch10,&
317 0 : & dk(:),' (in reduced coordinates)',ch10,&
318 0 : & gpard(1:3),' (in cartesian coordinates - atomic units)'
319 0 : call wrtout(ab_out,message,'COLL')
320 0 : call wrtout(std_out,message,'COLL')
321 :
322 : write(message,'(a,i5,a,a,i5)')&
323 0 : & ' Number of strings: ',nstr,ch10,&
324 0 : & ' Number of k points in string:', nkstr
325 0 : call wrtout(std_out,message,'COLL')
326 :
327 0 : if(nsppol==1)then
328 : write(message, '(a,i5,a,i5)')&
329 0 : & ' From band number',bdberry(1),' to band number',bdberry(2)
330 : else
331 : write(message, '(a,i5,a,i5,a,a,a,i5,a,i5,a)')&
332 0 : & ' From band number',bdberry(1),' to band number',bdberry(2),' for spin up,',&
333 0 : & ch10,&
334 0 : & ' from band number',bdberry(3),' to band number',bdberry(4),' for spin down.'
335 : end if
336 0 : call wrtout(ab_out,message,'COLL')
337 0 : call wrtout(std_out,message,'COLL')
338 :
339 : ! DEBUG
340 : ! write(std_out,*)' berryphase : find nkpt,nkstr,nstr=',nkpt,nkstr,nstr
341 : ! stop
342 : ! ENDDEBUG
343 :
344 : ! Build the different strings
345 0 : ABI_MALLOC(ikstr,(nkstr,nstr))
346 :
347 0 : iunmark=1
348 0 : kpt_mark(:)=0
349 0 : do istr = 1, nstr
350 0 : do while(kpt_mark(iunmark)/=0)
351 0 : iunmark = iunmark + 1
352 : end do
353 0 : ikstr(1, istr) = iunmark
354 0 : kpt_mark(iunmark)=1
355 0 : do jkstr = 2, nkstr
356 0 : ikstr(jkstr,istr)=ikpt_dk(ikstr(jkstr-1,istr))
357 0 : kpt_mark(ikstr(jkstr,istr))=1
358 : end do
359 : end do ! istr
360 :
361 : ! DEBUG
362 : ! do istr = 1,nstr
363 : ! do jkstr = 1,nkstr
364 : ! if (shift_g(ikstr(jkstr,istr))) then
365 : ! write(99,*) ikstr(jkstr,istr),'true'
366 : ! else
367 : ! write(99,*) ikstr(jkstr,istr),'false'
368 : ! end if
369 : ! end do
370 : ! end do
371 : ! ENDDEBUG
372 :
373 0 : ABI_FREE(ikpt_dk)
374 : ! DEBUG!
375 : ! write(100,*) 'list all the k points strings:'
376 : ! do istr=1,nstr
377 : ! write(100,*) (ikstr(jkstr,istr),jkstr=1,nkstr)
378 : ! end do
379 : ! ENDDEBUG!
380 :
381 : ! *****************************************************************************
382 : ! Find the location of each wavefunction
383 0 : ABI_MALLOC(cg_index,(mband,nkpt,nsppol))
384 :
385 0 : icg = 0
386 0 : do isppol=1,nsppol
387 0 : do ikpt=1,nkpt_
388 0 : nband_k=nband(ikpt+(isppol-1)*nkpt_)
389 0 : npw_k=npwarr(ikpt)
390 0 : do iband=1,nband_k
391 0 : cg_index(iband,ikpt,isppol)=(iband-1)*npw_k*nspinor+icg
392 : end do
393 0 : icg=icg+npw_k*nspinor*nband(ikpt)
394 : end do
395 : end do
396 :
397 : ! change5
398 0 : if (mkmem/=0) then
399 : ! Find the planewave vectors and their indexes for each k point
400 0 : ABI_MALLOC(kg_kpt,(3,mpw*nspinor,nkpt_))
401 0 : kg_kpt(:,:,:) = 0
402 : index1 = 0
403 0 : do ikpt=1,nkpt_
404 0 : npw_k=npwarr(ikpt)
405 0 : do ipw=1,npw_k*nspinor
406 0 : kg_kpt(1:3,ipw,ikpt)=kg(1:3,ipw+index1)
407 : end do
408 0 : index1=index1+npw_k*nspinor
409 : end do
410 : end if !change5
411 : ! *****************************************************************************
412 0 : ABI_MALLOC(det_string,(2, nstr))
413 0 : ABI_MALLOC(det_tmp,(2, nstr))
414 0 : ABI_MALLOC(polberry,(nstr))
415 :
416 : ! Initialize berry phase polarization for each spin and the total one
417 0 : polb(1:nsppol) = 0.0_dp
418 0 : polbtot=0.0_dp
419 :
420 : ! Loop over spins
421 0 : do isppol=1,nsppol
422 :
423 0 : minband=bdberry(2*isppol-1)
424 0 : maxband=bdberry(2*isppol)
425 :
426 0 : if(minband<1)then
427 0 : write(message,'(a,i0,a)')' The band limit minband=',minband,', is lower than 0.'
428 0 : ABI_BUG(message)
429 : end if
430 :
431 0 : if(maxband<1)then
432 0 : write(message,'(a,i0,a)')' The band limit maxband=',maxband,', is lower than 0.'
433 0 : ABI_BUG(message)
434 : end if
435 :
436 0 : if(maxband<minband)then
437 0 : write(message,'(a,i0,a,i0)')' maxband=',maxband,', is lower than minband=',minband
438 0 : ABI_BUG(message)
439 : end if
440 :
441 : ! Initialize det_string and det_average
442 0 : det_string(1, 1:nstr) = 1.0_dp; det_string(2, 1:nstr) = 0.0_dp
443 0 : det_average(1:2)=0.0_dp; det_average(2)=0.0_dp
444 :
445 : ! Loop over strings
446 0 : do istr = 1, nstr
447 :
448 : ! change7
449 0 : read_k = 0
450 :
451 : ! DEBUG!
452 : ! write(100,'(a,i4)') 'This is in string', istr
453 : ! ENDDEBUG!
454 :
455 : ! Loop over k points per string
456 0 : ABI_MALLOC(determinant,(2, nkstr))
457 :
458 0 : do jkstr=1,nkstr
459 :
460 0 : ABI_MALLOC(cmatrix,(2,maxband,maxband))
461 0 : if(jkstr < nkstr) then
462 0 : lkstr=jkstr+1
463 : else
464 0 : lkstr= jkstr+1-nkstr
465 : end if
466 0 : jkstr_ori=ikstr(jkstr,istr)
467 0 : lkstr_ori=ikstr(lkstr,istr)
468 :
469 : ! change9
470 0 : lkstr_ori_=lkstr_ori
471 0 : tr(1) = 1.0_dp
472 0 : tr(2) = 1.0_dp
473 0 : if (kptopt==2) then
474 0 : if (read_k == 0) then
475 0 : if (kpt_flag(jkstr_ori)/=0) then
476 0 : tr(1) = -1.0_dp
477 0 : jkstr_ori = kpt_flag(jkstr_ori)
478 : end if
479 0 : if (kpt_flag(lkstr_ori)/=0) then
480 0 : tr(2) = -1.0_dp
481 0 : lkstr_ori = kpt_flag(lkstr_ori)
482 : end if
483 : else !read_k
484 0 : if (kpt_flag(jkstr_ori)/=0) then
485 0 : tr(-1*read_k+3) = -1.0_dp
486 0 : jkstr_ori = kpt_flag(jkstr_ori)
487 : end if
488 0 : if (kpt_flag(lkstr_ori)/=0) then
489 0 : tr(read_k) = -1.0_dp
490 0 : lkstr_ori = kpt_flag(lkstr_ori)
491 : end if
492 : end if !read_k
493 : end if !kptopt
494 : ! change9
495 :
496 0 : nband_k=nband(jkstr_ori+(isppol-1)*nkpt_)
497 0 : if(nband_k<maxband)then
498 0 : write(message,'(a,i0,a,i0)')' maxband=',maxband,', is larger than nband(j,isppol)=',nband_k
499 0 : ABI_BUG(message)
500 : end if
501 :
502 0 : nband_k=nband(lkstr_ori+(isppol-1)*nkpt_)
503 0 : if(nband_k<maxband)then
504 : write(message,'(a,i0,a,i0)')&
505 0 : & ' maxband=',maxband,', is larger than nband(l,isppol)=',nband_k
506 0 : ABI_BUG(message)
507 : end if
508 :
509 0 : if (jkstr==1) read_k = 2
510 : ! Compute the overlap matrix <u_k|u_k+b>
511 0 : cmatrix(1:2,1:maxband,1:maxband)=zero
512 0 : jj = read_k
513 0 : ii = -1*read_k+3
514 0 : if(.not. shift_g(lkstr_ori_) ) then
515 : ! Change3
516 0 : do ipw=1,npwarr(jkstr_ori)
517 0 : do jpw=1,npwarr(lkstr_ori)
518 :
519 : ! Check if Fourier components of jkstr and jkstr+1 matches
520 :
521 : if((tr(ii)*kg_kpt(1,ipw,jkstr_ori)==tr(jj)*kg_kpt(1,jpw,lkstr_ori))&
522 : & .and.(tr(ii)*kg_kpt(2,ipw,jkstr_ori) == tr(jj)*kg_kpt(2,jpw,lkstr_ori))&
523 0 : & .and.(tr(ii)*kg_kpt(3,ipw,jkstr_ori) == tr(jj)*kg_kpt(3,jpw,lkstr_ori)))&
524 0 : & then
525 :
526 0 : do iband=minband,maxband
527 0 : cg_index_iband=cg_index(iband,jkstr_ori,isppol)
528 0 : do jband=minband,maxband
529 0 : cg_index_jband=cg_index(jband,lkstr_ori,isppol)
530 :
531 : cmatrix(1,iband,jband)=cmatrix(1,iband,jband)+&
532 : & cg(1,ipw+cg_index_iband)*cg(1,jpw+cg_index_jband)+&
533 0 : & tr(ii)*cg(2,ipw+cg_index_iband)*tr(jj)*cg(2,jpw+cg_index_jband)
534 : cmatrix(2,iband,jband)=cmatrix(2,iband,jband)+&
535 : & cg(1,ipw+cg_index_iband)*tr(jj)*cg(2,jpw+cg_index_jband)-&
536 0 : & tr(ii)*cg(2,ipw+cg_index_iband)*cg(1,jpw+cg_index_jband)
537 :
538 : end do !jband
539 : end do !iband
540 : exit !stop loop over jpw if Fourier components of jkstr and jkstr + 1 matches
541 : end if
542 :
543 : end do ! jpw
544 : end do ! ipw
545 :
546 : ! But there is a special pair of k points which involves the shift of a
547 : ! G vector
548 :
549 : else
550 :
551 0 : dg(:) = -1*nint(tr(jj)*kpt(:,lkstr_ori)-tr(ii)*kpt(:,jkstr_ori)-dk(:))
552 :
553 : ! DEBUG
554 : ! write(100,*)dg
555 : ! write(100,*)kberry(:,iberry)
556 : ! write(100,*)''
557 : ! ENDDEBUG
558 :
559 : ! change4
560 0 : do ipw=1,npwarr(jkstr_ori)
561 0 : do jpw=1,npwarr(lkstr_ori)
562 :
563 : ! Check if Fourier components of jkstr and jkstr+1
564 : ! matches by comparing the G vectors
565 :
566 : if((tr(ii)*kg_kpt(1,ipw,jkstr_ori)==tr(jj)*kg_kpt(1,jpw,lkstr_ori)-dg(1))&
567 : & .and.(tr(ii)*kg_kpt(2,ipw,jkstr_ori) == tr(jj)*kg_kpt(2,jpw,lkstr_ori)-dg(2))&
568 0 : & .and.(tr(ii)*kg_kpt(3,ipw,jkstr_ori) == tr(jj)*kg_kpt(3,jpw,lkstr_ori)-dg(3)))&
569 0 : & then
570 :
571 0 : do iband=minband,maxband
572 0 : cg_index_iband=cg_index(iband,jkstr_ori,isppol)
573 :
574 0 : do jband=minband,maxband
575 0 : cg_index_jband=cg_index(jband,lkstr_ori,isppol)
576 :
577 : cmatrix(1,iband,jband)=cmatrix(1,iband,jband)+&
578 : & cg(1,ipw+cg_index_iband)*cg(1,jpw+cg_index_jband)+&
579 0 : & tr(ii)*cg(2,ipw+cg_index_iband)*tr(jj)*cg(2,jpw+cg_index_jband)
580 : cmatrix(2,iband,jband)=cmatrix(2,iband,jband)+&
581 : & cg(1,ipw+cg_index_iband)*tr(jj)*cg(2,jpw+cg_index_jband)-&
582 0 : & tr(ii)*cg(2,ipw+cg_index_iband)*cg(1,jpw+cg_index_jband)
583 :
584 : end do ! jband
585 : end do ! iband
586 : exit !stop loop over jpw if Fourier components of jkstr and jkstr + 1 matches
587 : end if
588 : end do ! jpw
589 : end do ! ipw
590 : end if
591 :
592 : ! Compute the determinant of cmatrix(1:2,minband:maxband, minband:maxband)
593 :
594 0 : band_in = maxband - minband + 1
595 :
596 0 : ABI_MALLOC(ipvt,(maxband))
597 0 : ABI_MALLOC(zgwork,(2,1:maxband))
598 :
599 : ! Last argument of zgedi means calculate determinant only.
600 0 : call dzgefa(cmatrix(1,minband,minband),maxband, band_in,ipvt,info)
601 0 : call dzgedi(cmatrix(1,minband,minband),maxband, band_in,ipvt,det,zgwork,10)
602 :
603 0 : ABI_FREE(zgwork)
604 0 : ABI_FREE(ipvt)
605 :
606 0 : fac=exp(log(10._dp)*det(1,2))
607 : determinant(1, jkstr) = fac*(det(1,1)*cos(log(10._dp)*det(2,2)) - &
608 0 : & det(2,1)*sin(log(10._dp)*det(2,2)))
609 : determinant(2, jkstr) = fac*(det(1,1)*sin(log(10._dp)*det(2,2)) + &
610 0 : & det(2,1)*cos(log(10._dp)*det(2,2)))
611 : ! DEBUG!
612 : ! write(100,*) 'det',jkstr,lkstr,'=', determinant(1:2,jkstr)
613 : ! ENDDEBUG!
614 :
615 : det_tmp(1,istr) = det_string(1,istr)*determinant(1,jkstr) - &
616 0 : & det_string(2,istr)*determinant(2,jkstr)
617 : det_tmp(2,istr) = det_string(1,istr)*determinant(2,jkstr) + &
618 0 : & det_string(2,istr)*determinant(1,jkstr)
619 0 : det_string(1:2,istr) = det_tmp(1:2,istr)
620 :
621 0 : ABI_FREE(cmatrix)
622 :
623 : ! Close loop over k points along string
624 0 : read_k = -1*read_k + 3 ! read_k=2 <-> read_k=1
625 : end do
626 :
627 : ! DEBUG!
628 : ! write(100,*) 'det_string =', det_string(1:2,istr)
629 : ! write(100,*)
630 : ! ENDDEBUG!
631 :
632 0 : det_average(1) = det_average(1) + det_string(1,istr)/nstr
633 0 : det_average(2) = det_average(2) + det_string(2,istr)/nstr
634 :
635 0 : ABI_FREE(determinant)
636 :
637 : ! Close loop over strings
638 : end do
639 :
640 :
641 : ! *****************************************************************************
642 : ! Calculate the electronic contribution to the polarization
643 :
644 0 : write(message,'(a,a)')ch10,&
645 0 : & ' Compute the electronic contribution to polarization'
646 0 : call wrtout(std_out,message,'COLL')
647 :
648 : ! First berry phase that corresponds to det_average
649 0 : phase0 = atan2(det_average(2),det_average(1))
650 0 : det_mod = det_average(1)**2+det_average(2)**2
651 :
652 : ! Then berry phase that corresponds to each string relative to the average
653 0 : do istr = 1, nstr
654 : rel_string(1) = (det_string(1,istr)*det_average(1) + &
655 0 : det_string(2,istr)*det_average(2))/det_mod
656 : rel_string(2) = (det_string(2,istr)*det_average(1) - &
657 0 : det_string(1,istr)*det_average(2))/det_mod
658 0 : dphase = atan2(rel_string(2),rel_string(1))
659 0 : polberry(istr) = (2.0_dp/nsppol)*(phase0+dphase)/two_pi
660 0 : polb(isppol) = polb(isppol) + polberry(istr)/nstr
661 : end do
662 :
663 : ! Output berry phase polarization
664 0 : write(message,'(a,10x,a,10x,a)')ch10,&
665 0 : & 'istr','polberry(istr)'
666 0 : call wrtout(std_out,message,'COLL')
667 0 : do istr=1,nstr
668 0 : write(message,'(10x,i4,7x,e16.9)')istr,polberry(istr)
669 0 : call wrtout(std_out,message,'COLL')
670 : end do
671 :
672 : write(message,'(9x,a,7x,e16.9,1x,a,i4,a,a)')&
673 0 : & 'total',polb(isppol),'(isppol=',isppol,')',ch10
674 0 : call wrtout(std_out,message,'COLL')
675 :
676 0 : polbtot=polbtot+polb(isppol)
677 :
678 : end do ! isppol
679 :
680 0 : ABI_FREE(polberry)
681 0 : ABI_FREE(det_tmp)
682 0 : ABI_FREE(det_string)
683 0 : ABI_FREE(ikstr)
684 0 : ABI_FREE(cg_index)
685 : ! change6
686 0 : if (mkmem /=0) then
687 0 : ABI_FREE(kg_kpt)
688 : end if
689 : ! *****************************************************************************
690 : ! Reindex xcart according to atom and type
691 0 : call xred2xcart(natom,rprimd,xcart,xred)
692 0 : ABI_MALLOC(xcart_reindex,(3,natom,ntypat))
693 0 : index=1
694 0 : do itypat=1,ntypat
695 0 : do iattyp=1,nattyp(itypat)
696 0 : iatom=atindx1(index)
697 0 : xcart_reindex(1:3,iattyp,itypat) = xcart(1:3,iatom)
698 0 : index = index+1
699 : end do
700 : end do
701 :
702 : ! Compute the ionic contribution to the polarization
703 0 : politot = 0.0_dp
704 0 : write(message,'(a)')' Compute the ionic contributions'
705 0 : call wrtout(std_out,message,'COLL')
706 :
707 0 : write(message,'(a,2x,a,2x,a,15x,a)')ch10,&
708 0 : & 'itypat', 'iattyp', 'polion'
709 0 : call wrtout(std_out,message,'COLL')
710 :
711 0 : do itypat=1,ntypat
712 0 : do iattyp=1,nattyp(itypat)
713 : polion=zion(itypat)*nkstr*&
714 0 : & dot_product(xcart_reindex(1:3,iattyp,itypat),gpard(1:3))
715 : ! Fold into interval (-1,1)
716 0 : polion=polion-2._dp*nint(polion/2.0_dp)
717 0 : politot=politot+polion
718 0 : write(message,'(2x,i2,5x,i2,10x,e16.9)') itypat,iattyp,polion
719 0 : call wrtout(std_out,message,'COLL')
720 : end do
721 : end do
722 :
723 : ! Fold into interval (-1,1) again
724 0 : politot=politot-2.0_dp*nint(politot/2.0_dp)
725 :
726 0 : write(message,'(9x,a,7x,es19.9)') 'total',politot
727 0 : call wrtout(std_out,message,'COLL')
728 :
729 0 : ABI_FREE(xcart_reindex)
730 :
731 : ! Compute the total polarizations
732 :
733 0 : poltot=politot+polbtot
734 :
735 0 : write(message,'(a,a)')ch10,&
736 0 : & ' Summary of the results'
737 0 : call wrtout(std_out,message,'COLL')
738 0 : call wrtout(ab_out,message,'COLL')
739 :
740 : write(message,'(a,es19.9)')&
741 0 : & ' Electronic Berry phase ' ,polbtot
742 0 : call wrtout(std_out,message,'COLL')
743 0 : call wrtout(ab_out,message,'COLL')
744 :
745 : write(message,'(a,es19.9)') &
746 0 : & ' Ionic phase ', politot
747 0 : call wrtout(std_out,message,'COLL')
748 0 : call wrtout(ab_out,message,'COLL')
749 :
750 : write(message,'(a,es19.9)') &
751 0 : & ' Total phase ', poltot
752 0 : call wrtout(std_out,message,'COLL')
753 0 : call wrtout(ab_out,message,'COLL')
754 :
755 0 : poltot=poltot-2.0_dp*nint(poltot/2._dp)
756 : write(message,'(a,es19.9)') &
757 0 : & ' Remapping in [-1,1] ', poltot
758 0 : call wrtout(std_out,message,'COLL')
759 0 : call wrtout(ab_out,message,'COLL')
760 :
761 : ! Transform the phase into a polarization
762 0 : fac = 1._dp/(gmod*nkstr)
763 0 : fac = fac/ucvol
764 0 : pol = fac*poltot
765 :
766 0 : write(message,'(a,a,es19.9,a,a,a,es19.9,a,a)')ch10,&
767 0 : & ' Polarization ', pol,' (a.u. of charge)/bohr^2',ch10,&
768 0 : & ' Polarization ', pol*(e_Cb)/(Bohr_Ang*1d-10)**2,&
769 0 : & ' C/m^2',ch10
770 0 : call wrtout(std_out,message,'COLL')
771 0 : call wrtout(ab_out,message,'COLL')
772 :
773 : end do ! iberry
774 :
775 0 : ABI_FREE(shift_g)
776 0 : ABI_FREE(kpt)
777 0 : ABI_FREE(kg_dum)
778 :
779 0 : end subroutine berryphase
780 : !!***
781 :
782 : end module m_berryphase
783 : !!***
|