Branch data Line data Source code
1 : : !!****m* ABINIT/m_elpolariz
2 : : !! NAME
3 : : !! m_elpolariz
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2005-2026 ABINIT group (XG, NSAI, MKV)
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_elpolariz
23 : :
24 : : use defs_basis
25 : : use m_abicore
26 : : use m_errors
27 : : use m_efield
28 : : use m_xmpi
29 : : use m_wffile
30 : : use m_hdr
31 : : use m_dtset
32 : : use m_dtfil
33 : :
34 : : use defs_datatypes, only : pseudopotential_type
35 : : use defs_abitypes, only : MPI_type
36 : : use m_geometry, only : metric
37 : : use m_matrix, only : matr3inv
38 : : use m_hide_lapack, only : dzgedi, dzgefa
39 : : use m_rwwf, only : rwwf
40 : : use m_pawtab, only : pawtab_type
41 : : use m_pawrhoij, only : pawrhoij_type
42 : : use m_pawcprj, only : pawcprj_type
43 : : use m_berryphase, only : berryphase
44 : : use m_berryphase_new, only : berryphase_new
45 : :
46 : : implicit none
47 : :
48 : : private
49 : : !!***
50 : :
51 : : public :: elpolariz
52 : : !!***
53 : :
54 : : contains
55 : : !!***
56 : :
57 : : !!****f* ABINIT/elpolariz
58 : : !! NAME
59 : : !! elpolariz
60 : : !!
61 : : !! FUNCTION
62 : : !! Calculate corrections to total energy from polarising
63 : : !! electric field with or without Berry phases (berryopt keyword)
64 : : !!
65 : : !! INPUTS
66 : : !! atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
67 : : !! cg(2,mcg)=planewave coefficients of wavefunctions
68 : : !! cprj(natom,mcprj*usecprj)=<p_lmn|Cnk> coefficients for each WF |Cnk>
69 : : !! and each |p_lmn> non-local projector
70 : : !! dtfil <type(datafiles_type)>=variables related to files
71 : : !! dtset <type(dataset_type)>=all input variables in this dataset
72 : : !! gprimd(3,3)=reciprocal space dimensional primitive translations
73 : : !! hdr <type(hdr_type)>=the header of wf, den and pot files
74 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates
75 : : !! mband=maximum number of bands
76 : : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
77 : : !! mkmem=number of k points treated by this node.
78 : : !! mpi_enreg=information about MPI parallelization
79 : : !! mpw=maximum dimensioned size of npw
80 : : !! my_natom=number of atoms treated by current processor
81 : : !! natom=number of atoms in cell
82 : : !! nattyp(ntypat)= # atoms of each type.
83 : : !! nkpt=number of k points
84 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
85 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
86 : : !! ntypat=number of types of atoms in unit cell
87 : : !! nkpt=number of k-points
88 : : !! option = 1: compute Berryphase polarization
89 : : !! 2: compute finite difference expression of the ddk
90 : : !! 3: compute polarization & ddk
91 : : !! pawrhoij(my_natom*usepaw) <type(pawrhoij_type)> atomic occupancies
92 : : !! pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
93 : : !! pel_cg(3) = reduced coordinates of the electronic polarization (a. u.)
94 : : !! computed in the SCF loop
95 : : !! pelev(3)= expectation value polarization term (PAW only) in cartesian coordinates
96 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
97 : : !! pwind(pwind_alloc,2,3) = array used to compute
98 : : !! the overlap matrix smat between k-points (see initberry.f)
99 : : !! pwind_alloc = first dimension of pwind
100 : : !! pwnsfac(2,pwind_alloc) = phase factors for non-symmorphic translations
101 : : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
102 : : !! ucvol=unit cell volume in bohr**3.
103 : : !! usecprj=1 if cprj datastructure has been allocated
104 : : !! xred(3,natom)=reduced atomic coordinates
105 : : !!
106 : : !! OUTPUT
107 : : !! (see side effects)
108 : : !!
109 : : !! SIDE EFFECTS
110 : : !! dtefield <type(efield_type)> = variables related to Berry phase
111 : : !! and electric field calculations (see initberry.f).
112 : : !! In case berryopt = 4/6/7/14/16/17, the overlap matrices computed
113 : : !! in this routine are stored in dtefield%smat in order
114 : : !! to be used in the electric field calculation.
115 : : !! enefield=field energy
116 : : !! etotal=total energy, might be correct by improved polarization computation
117 : : !! pel(3) = reduced coordinates of the electronic polarization (a. u.)
118 : : !! pion(3)= reduced coordinates of the ionic polarization (a. u.)
119 : : !!
120 : : !! SOURCE
121 : :
122 : 85 : subroutine elpolariz(atindx1,cg,cprj,dtefield,dtfil,dtset,etotal,enefield,gprimd,hdr,&
123 : 85 : & kg,mband,mcg,mcprj,mkmem,mpi_enreg,mpw,my_natom,natom,nattyp,nkpt,&
124 : 85 : & npwarr,nsppol,ntypat,pawrhoij,pawtab,&
125 : 85 : & pel,pel_cg,pelev,pion,psps,pwind,pwind_alloc,&
126 : 85 : & pwnsfac,rprimd,ucvol,usecprj,xred)
127 : :
128 : : !Arguments ------------------------------------
129 : : !scalars
130 : : integer,intent(in) :: mband,mcg,mcprj,mkmem,mpw,my_natom,natom,nkpt,nsppol,ntypat
131 : : integer,intent(in) :: pwind_alloc,usecprj
132 : : real(dp),intent(in) :: ucvol
133 : : real(dp),intent(inout) :: enefield,etotal
134 : : type(MPI_type),intent(in) :: mpi_enreg
135 : : type(datafiles_type),intent(in) :: dtfil
136 : : type(dataset_type),intent(inout) :: dtset
137 : : type(efield_type),intent(inout) :: dtefield
138 : : type(hdr_type),intent(inout) :: hdr
139 : : type(pseudopotential_type),intent(in) :: psps
140 : : !arrays
141 : : integer,intent(in) :: atindx1(natom),kg(3,mpw*mkmem),nattyp(ntypat)
142 : : integer,intent(in) :: npwarr(nkpt),pwind(pwind_alloc,2,3)
143 : : real(dp),intent(in) :: cg(2,mcg),gprimd(3,3)
144 : : real(dp),intent(in) :: pel_cg(3),pwnsfac(2,pwind_alloc),rprimd(3,3)
145 : : real(dp),intent(inout) :: pel(3),pelev(3),pion(3),xred(3,natom)
146 : : type(pawcprj_type),intent(in) :: cprj(natom,mcprj*usecprj)
147 : : type(pawrhoij_type), intent(in) :: pawrhoij(my_natom*psps%usepaw)
148 : : type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
149 : :
150 : : !Local variables-------------------------------
151 : : !scalars
152 : : integer :: mcg1_3,my_nspinor,option,unit_out,iir,jjr,kkr
153 : : real(dp) :: pdif_mod,eenth,ucvol_local
154 : : logical :: save_cg1_3
155 : : character(len=500) :: message
156 : : !arrays
157 : : real(dp) :: gmet(3,3),gprimdlc(3,3),pdif(3),ptot(3),red_ptot(3),rmet(3,3)
158 : : !! ptot(3) = total polarization (not reduced) REC
159 : : !! red_ptot(3) = internal reduced total polarization REC
160 : : real(dp) :: A(3,3),A1(3,3),A_new(3,3),efield_new(3)
161 : 85 : real(dp),allocatable :: cg1_3(:,:,:)
162 : :
163 : : ! *************************************************************************
164 : :
165 : : DBG_ENTER("COLL")
166 : :
167 [ + + - + ]: 85 : if (usecprj==0.and.psps%usepaw==1) then
168 : : write (message,'(3a)')&
169 : 0 : & 'cprj datastructure must be allocated !',ch10,&
170 : 0 : & 'Action: change pawusecp input keyword.'
171 : 0 : ABI_ERROR(message)
172 : : end if
173 : :
174 : 85 : my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
175 : :
176 : : if(dtset%berryopt>0 .and. dtset%berryopt/=4 .and. dtset%berryopt/=6 .and. dtset%berryopt/=7 .and. &
177 [ - + ]: 85 : & dtset%berryopt/=14 .and. dtset%berryopt/=16 .and. dtset%berryopt/=17)then !!HONG
178 : :
179 : : if (dtset%berryopt==1 .or. dtset%berryopt==3) then
180 : : call berryphase(atindx1,dtset%bdberry,cg,gprimd,dtset%istwfk,&
181 : : & dtset%kberry,kg,dtset%kptns,dtset%kptopt,dtset%kptrlatt,&
182 : : & mband,mcg,mkmem,mpw,natom,nattyp,dtset%nband,dtset%nberry,npwarr,&
183 : : & my_nspinor,nsppol,psps%ntypat,nkpt,rprimd,ucvol,&
184 : 0 : & xred,psps%ziontypat)
185 : : end if
186 : :
187 [ # # ]: 0 : if (dtset%berryopt==2 .or. dtset%berryopt==3) then
188 : : call uderiv(dtset%bdberry,cg,gprimd,hdr,dtset%istwfk,&
189 : : & dtset%kberry,kg,dtset%kptns,dtset%kptopt,&
190 : : & dtset%kptrlatt,mband,mcg,mkmem,mpi_enreg,mpw,&
191 : : & natom,dtset%nband,dtset%nberry,npwarr,my_nspinor,nsppol,&
192 : 0 : & nkpt,dtfil%unddk,dtfil%fnameabo_1wf)
193 : : end if
194 : :
195 : : else if(dtset%berryopt<0 .or. dtset%berryopt==4 .or. dtset%berryopt==6 .or. dtset%berryopt==7 .or. &
196 [ - + ]: 85 : & dtset%berryopt==14 .or. dtset%berryopt==16 .or. dtset%berryopt==17)then !!HONG
197 : :
198 : 0 : select case (dtset%berryopt)
199 : : case (-5)
200 : 0 : option = 2
201 : : case (-3)
202 : 1 : option = 3
203 : : case (-2)
204 : 3 : option = 2
205 : : case (-1)
206 : 56 : option = 1
207 : : case (4)
208 : 25 : option = 1
209 : 25 : pel(:) = zero
210 : 25 : pelev(:) = zero
211 : : case (6) !!HONG
212 : 0 : option = 1
213 : 0 : pel(:) = zero
214 : 0 : pelev(:) = zero
215 : : case (7) !!HONG
216 : 0 : option = 1
217 : 0 : pel(:) = zero
218 : 0 : pelev(:) = zero
219 : : case (14) !!HONG
220 : 0 : option = 1
221 : 0 : pel(:) = zero
222 : 0 : pelev(:) = zero
223 : : case (16) !!HONG
224 : 0 : option = 1
225 : 0 : pel(:) = zero
226 : 0 : pelev(:) = zero
227 : : case (17) !!HONG
228 : 0 : option = 1
229 : 0 : pel(:) = zero
230 [ - + + + : 85 : pelev(:) = zero
+ - - - -
- - ]
231 : : end select
232 : :
233 : 85 : unit_out = ab_out
234 : :
235 : : ! by default berryphase_new writes ddk wavefunctions to disk
236 : : ! with save_cg1_3 set to true it can return them in memory
237 : : ! this feature is used at present when orbmag is also called,
238 : : ! as in afterscfloop
239 : 85 : save_cg1_3 = .FALSE.
240 : 85 : mcg1_3 = 0
241 [ - + ]: 85 : ABI_MALLOC(cg1_3,(2,mcg1_3,3))
242 : : call berryphase_new(atindx1,cg,cg1_3,cprj,dtefield,dtfil,dtset,psps,&
243 : : & gprimd,hdr,psps%indlmn,kg,&
244 : : & psps%lmnmax,mband,mcg,mcg1_3,mcprj,mkmem,mpi_enreg,mpw,my_natom,natom,npwarr,&
245 : : & nsppol,psps%ntypat,nkpt,option,pawrhoij,&
246 : : & pawtab,pel,pelev,pion,ptot,red_ptot,pwind,& !!REC
247 : : & pwind_alloc,pwnsfac,rprimd,save_cg1_3,dtset%typat,ucvol,&
248 : 85 : & unit_out,usecprj,psps%usepaw,xred,psps%ziontypat)
249 [ - + ]: 85 : ABI_FREE(cg1_3)
250 : :
251 [ + + ]: 340 : dtefield%red_ptot1(:)=red_ptot(:)
252 : :
253 : : if (dtset%berryopt == 4 .or. dtset%berryopt == 6 .or. dtset%berryopt == 7 .or. &
254 [ + + ]: 85 : & dtset%berryopt == 14 .or. dtset%berryopt == 16 .or. dtset%berryopt == 17 ) then !!HONG
255 : :
256 : : ! Check if pel has the same value as pel_cg
257 : : ! if (psps%usepaw == 1) pel(:) = pel(:) + pelev(:) ! add on-site term for PAW
258 : : ! if (psps%usepaw == 1) red_ptot(:) = red_ptot(:) + pelev(:) ! add on-site term for PAW !! REC
259 : : ! above line suppressed because in the PAW case, pel already includes all on-site
260 : : ! terms and pelev should not be added in additionally. We are computing pelev separately for
261 : : ! reporting purposes only.
262 : : ! 13 June 2012 J Zwanziger
263 : :
264 [ + + ]: 100 : pdif(:) = pel_cg(:) - pel(:)
265 : 25 : pdif_mod = pdif(1)**2 + pdif(2)**2 + pdif(3)**2
266 : :
267 [ - + ]: 25 : if (pdif_mod > tol8) then
268 : 0 : write(message,'(11(a),e16.9)')ch10,&
269 : 0 : & ' scfcv (electric field calculation) : WARNING -',ch10,&
270 : 0 : & ' The difference between pel (electronic Berry phase updated ',ch10,&
271 : 0 : & ' at each SCF cycle)',ch10,&
272 : 0 : & ' and pel_cg (electronic Berryphase computed using the ',&
273 : 0 : & 'berryphase routine) is',ch10,&
274 : 0 : & ' pdif_mod = ',pdif_mod
275 : 0 : call wrtout(std_out,message,'COLL')
276 : 0 : write(message,'(a,6(a,e16.9,a))') ch10,&
277 : 0 : & 'pel_cg(1) = ',pel_cg(1),ch10,&
278 : 0 : & 'pel_cg(2) = ',pel_cg(2),ch10,&
279 : 0 : & 'pel_cg(3) = ',pel_cg(3),ch10,&
280 : 0 : & 'pel(1) = ',pel(1),ch10,&
281 : 0 : & 'pel(2) = ',pel(2),ch10,&
282 : 0 : & 'pel(3) = ',pel(3),ch10
283 : 0 : ABI_ERROR(message)
284 : : end if
285 : :
286 : : ! Use this (more accurate) value of P to recompute enefield
287 [ + - ]: 25 : if (dtset%berryopt == 4 .or. dtset%berryopt == 14 ) then !!HONG
288 : 25 : etotal = etotal - enefield
289 : :
290 [ + + ]: 100 : enefield = -dot_product(dtset%red_efieldbar,red_ptot)
291 : 25 : call metric(gmet,gprimdlc,-1,rmet,rprimd,ucvol_local)
292 : 25 : eenth = zero
293 [ + + ]: 100 : do iir=1,3
294 [ + + ]: 325 : do jjr=1,3
295 : 300 : eenth= eenth+gmet(iir,jjr)*dtset%red_efieldbar(iir)*dtset%red_efieldbar(jjr) !! HONG g^{-1})_ij ebar_i ebar_j
296 : : end do
297 : : end do
298 : 25 : eenth=-1_dp*(ucvol_local/(8.0d0*pi))*eenth
299 : 25 : enefield=enefield+eenth
300 : :
301 : 25 : etotal = etotal + enefield
302 : :
303 : 25 : write(message,'(a,a)')ch10,&
304 : 50 : & ' Stress tensor under a constant electric field:'
305 : 25 : call wrtout(std_out,message,'COLL')
306 : 25 : call wrtout(ab_out,message,'COLL')
307 : :
308 : : end if
309 : :
310 : : ! ! In finite D-field case, turn it into internal energy !!HONG
311 [ - + ]: 25 : if (dtset%berryopt == 6 .or. dtset%berryopt == 16 ) then
312 : 0 : etotal = etotal - enefield
313 : :
314 : 0 : enefield=zero
315 : 0 : call metric(gmet,gprimdlc,-1,rmet,rprimd,ucvol_local)
316 [ # # ]: 0 : do iir=1,3
317 [ # # ]: 0 : do jjr=1,3
318 : 0 : enefield= enefield+gmet(iir,jjr)*dtset%red_efieldbar(iir)*dtset%red_efieldbar(jjr) !! HONG g^{-1})_ij ebar_i ebar_j
319 : : end do
320 : : end do
321 : 0 : enefield= ucvol_local/(8.0d0*pi)*enefield
322 : :
323 : 0 : etotal = etotal + enefield
324 : :
325 : 0 : write(message,'(a,a)')ch10,&
326 : 0 : & ' Stress tensor under a constant electric displacement field:'
327 : 0 : call wrtout(std_out,message,'COLL')
328 : 0 : call wrtout(ab_out,message,'COLL')
329 : :
330 : : end if
331 : :
332 : : ! HONG calculate internal energy and electric enthalpy for mixed BC case.
333 [ - + ]: 25 : if ( dtset%berryopt == 17 ) then
334 : 0 : etotal = etotal - enefield
335 : 0 : enefield = zero
336 : :
337 : 0 : call metric(gmet,gprimdlc,-1,rmet,rprimd,ucvol_local)
338 [ # # # # ]: 0 : A(:,:)=(4*pi/ucvol_local)*rmet(:,:)
339 : 0 : A1(:,:)=A(:,:)
340 : 0 : A_new(:,:)=A(:,:)
341 [ # # ]: 0 : efield_new(:)=dtset%red_efield(:)
342 : : eenth = zero
343 : :
344 [ # # ]: 0 : do kkr=1,3
345 [ # # ]: 0 : if (dtset%jfielddir(kkr)==1) then ! fixed ebar direction
346 : : ! step 1 add -ebar*p
347 : 0 : eenth=eenth - dtset%red_efieldbar(kkr)*red_ptot(kkr)
348 : :
349 : : ! step 2 chang to e_new (change e to ebar)
350 : 0 : efield_new(kkr)=dtset%red_efieldbar(kkr)
351 : :
352 : : ! step 3 chang matrix A to A1
353 : :
354 [ # # ]: 0 : do iir=1,3
355 [ # # ]: 0 : do jjr=1,3
356 [ # # ]: 0 : if (iir==kkr .and. jjr==kkr) A1(iir,jjr)=-1.0/A(kkr,kkr)
357 [ # # ]: 0 : if ((iir==kkr .and. jjr/=kkr) .or. (iir/=kkr .and. jjr==kkr)) &
358 : 0 : & A1(iir,jjr)=-1.0*A(iir,jjr)/A(kkr,kkr)
359 [ # # ]: 0 : if (iir/=kkr .and. jjr/=kkr) A1(iir,jjr)=A(iir,jjr)-A(iir,kkr)*A(kkr,jjr)/A(kkr,kkr)
360 : : end do
361 : : end do
362 : :
363 : 0 : A(:,:)=A1(:,:)
364 : 0 : A_new(:,:)=A1(:,:)
365 : : end if
366 : :
367 : : end do ! end fo kkr
368 : :
369 : :
370 [ # # ]: 0 : do iir=1,3
371 [ # # ]: 0 : do jjr=1,3
372 : 0 : eenth= eenth+(1/2.0)*A_new(iir,jjr)*efield_new(iir)*efield_new(jjr)
373 : : end do
374 : : end do
375 : :
376 : 0 : enefield=eenth
377 : 0 : etotal = etotal + enefield
378 : :
379 : 0 : write(message,'(a,a)')ch10,&
380 : 0 : & ' Stress tensor under a constant (mixed) electric and electric displacement field:'
381 : 0 : call wrtout(std_out,message,'COLL')
382 : 0 : call wrtout(ab_out,message,'COLL')
383 : :
384 : : end if ! berryopt==17
385 : :
386 : :
387 : : ! MVeithen: to clarify
388 : : ! Which stress tensor should be used in structural optimizations?
389 : : ! The one at constant electric field or at constant potential drop.
390 : : ! write(message,'(a,a)')ch10,&
391 : : ! & ' Stress tensor imposing a constant electric field:'
392 : : ! call wrtout(std_out,message,'COLL')
393 : : ! call wrtout(ab_out,message,'COLL')
394 : :
395 : : end if ! dtset%berryopt == 4/6/7/14/16/17
396 : :
397 : : end if ! dtset%berryopt>0 or dtset%berryopt/=4/6/7/14/16/17
398 : :
399 : : DBG_EXIT("COLL")
400 : :
401 : 85 : end subroutine elpolariz
402 : : !!***
403 : :
404 : : !!****f* ABINIT/uderiv
405 : : !! NAME
406 : : !! uderiv
407 : : !!
408 : : !! FUNCTION
409 : : !! This routine is called computes the derivative of
410 : : !! ground-state wavefunctions with respect to k (du/dk) by finite differencing
411 : : !! on neighbouring k points
412 : : !! Work for nsppol=1 or 2, but only accept nspinor=1,
413 : : !!
414 : : !! INPUTS
415 : : !! bdberry(4)=band limits for Berry phase contributions (or du/dk)
416 : : !! spin up and spin down (bdberry(3:4) is irrelevant when nsppol=1)
417 : : !! cg(2,mcg)=planewave coefficients of wavefunctions
418 : : !! gprimd(3,3)=reciprocal space dimensional primitive translations
419 : : !! hdr <type(hdr_type)>=the header of wf, den and pot files
420 : : !! istwfk(nkpt_)=input option parameter that describes the storage of wfs
421 : : !! kberry(3,20)= different delta k for Berry phases(or du/dk),
422 : : !! in unit of kptrlatt only kberry(1:3,1:nberry) is relevant
423 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates
424 : : !! kpt_(3,nkpt_)=reduced coordinates of k points generated by ABINIT,
425 : : !! kpt_ samples half the BZ if time-reversal symetrie is used
426 : : !! kptopt=2 when time-reversal symmetry is used
427 : : !! kptrlatt(3,3)=k-point lattice specification
428 : : !! mband=maximum number of bands
429 : : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
430 : : !! mkmem=number of k points treated by this node.
431 : : !! mpi_enreg=information about MPI parallelization
432 : : !! mpw=maximum dimensioned size of npw
433 : : !! natom=number of atoms in cell
434 : : !! nband(nkpt*nsppol)=number of bands at each k point, for each polarization
435 : : !! nberry=number of Berry phases(or du/dk) to be computed
436 : : !! nkpt=number of k points
437 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
438 : : !! nspinor=number of spinorial components of the wavefunctions (on current proc)
439 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
440 : : !! unddk=unit number for ddk file
441 : : !!
442 : : !! OUTPUT
443 : : !! (the ddk wavefunctions are written on disk)
444 : : !!
445 : : !! SIDE EFFECTS
446 : : !!
447 : : !! TODO
448 : : !! Cleaning, checking for rules
449 : : !! Should allow for time-reversal symmetry (istwfk)
450 : : !! WARNING : the use of nspinor is completely erroneous
451 : : !!
452 : : !! NOTES
453 : : !! Local Variables:
454 : : !! cmatrix(:,:,:)= overlap matrix of size maxband*maxband
455 : : !! cg_index(:,:,:)= unpacked cg index array for specific band,
456 : : !! k point and polarization.
457 : : !! det(2,2)= intermediate output of Lapack routine zgedi.f
458 : : !! dk(3)= step taken to the next k mesh point along the kberry direction
459 : : !! gpard(3)= dimensionalreciprocal lattice vector G along which the
460 : : !! polarization is computed
461 : : !! kg_kpt(:,:,:)= unpacked reduced planewave coordinates with subscript of
462 : : !! planewave and k point
463 : : !! kpt(3,nkpt)=reduced coordinates of k-point grid that samples the whole BZ
464 : : !! kpt_flag(nkpt)=kpt_flag(ikpt)=0 when the wf was generated by the ABINIT
465 : : !! code
466 : : !! kpt_flag(ikpt) gives the indices of the k-point
467 : : !! related to ikpt by time revers
468 : : !! maxband/minband= control the minimum and maximum band calculated in the
469 : : !! overlap matrix
470 : : !! npw_k= npwarr(ikpt), number of planewaves in basis at this k point
471 : : !! shift_g_2(nkpt,nkpt)= .true. if the k point should be shifted by a G vector;
472 : : !! .false. if not
473 : : !! tr(2)=variable that changes k to -k
474 : : !! G to -G
475 : : !! $c_g$ to $c_g^*$ when time-reversal symetrie is used
476 : : !!
477 : : !! SOURCE
478 : :
479 : 0 : subroutine uderiv(bdberry,cg,gprimd,hdr,istwfk,kberry,kg,kpt_,kptopt,kptrlatt,&
480 : 0 : & mband,mcg,mkmem,mpi_enreg,mpw,natom,nband,nberry,npwarr,nspinor,nsppol,nkpt_,&
481 : : & unddk,fnameabo_1wf)
482 : :
483 : : !Arguments ------------------------------------
484 : : !scalars
485 : : integer,intent(in) :: kptopt,mband,mcg,mkmem,mpw,natom,nberry,nkpt_,nspinor
486 : : integer,intent(in) :: nsppol,unddk
487 : : type(MPI_type),intent(in) :: mpi_enreg
488 : : type(hdr_type),intent(inout) :: hdr
489 : : !arrays
490 : : integer,intent(in) :: bdberry(4),istwfk(nkpt_),kberry(3,20),kg(3,mpw*mkmem)
491 : : integer,intent(in) :: kptrlatt(3,3),nband(nkpt_*nsppol),npwarr(nkpt_)
492 : : real(dp),intent(in) :: cg(2,mcg),gprimd(1:3,1:3)
493 : : real(dp),intent(in) :: kpt_(3,nkpt_)
494 : : character(len=fnlen),intent(in) :: fnameabo_1wf
495 : :
496 : : !Local variables -------------------------
497 : : !scalars
498 : : integer,parameter :: master=0
499 : : integer :: iomode,band_in,cg_index_iband,fform,flag1
500 : : integer :: formeig,iband,iberry,icg,idir,ierr,ifor,ii,ikpt,ikpt2,ikpt_
501 : : integer :: index,index1,info,ipert,ipw,isgn,isppol,jband,jj,jkpt,jkpt_
502 : : integer :: maxband,mcg_disk,me,minband,nband_diff,nband_k
503 : : integer :: nkpt,npw_k,pertcase,rdwr,read_k,spaceComm
504 : : integer :: tim_rwwf
505 : : real(dp) :: gmod,twodk
506 : : character(len=500) :: message
507 : : character(len=fnlen) :: fiwf1o
508 : : type(wffile_type) :: wffddk
509 : : !arrays
510 : 0 : integer :: kg_jl(0,0,0),kpt_flag(2*nkpt_)
511 : 0 : integer,allocatable :: cg_index(:,:,:),ikpt_dk(:,:),ipvt(:)
512 : 0 : integer,allocatable :: kg_kpt(:,:,:)
513 : : real(dp) :: det(2,2),diffk(3),diffk2(3),dk(3),gpard(3),klattice(3,3)
514 : : real(dp) :: kptrlattr(3,3),tr(2)
515 : : real(dp) :: cg_disk(0,0,0)
516 : 0 : real(dp),allocatable :: cmatrix(:,:,:),dudk(:,:)
517 : 0 : real(dp),allocatable :: eig_dum_2(:),kpt(:,:)
518 : 0 : real(dp),allocatable :: occ_dum_2(:),phi(:,:,:),u_tilde(:,:,:,:),zgwork(:,:)
519 : 0 : logical,allocatable :: shift_g_2(:,:)
520 : :
521 : : ! *************************************************************************
522 : :
523 [ # # ]: 0 : if(min(2,(1+mpi_enreg%paral_spinor)*nspinor)==2)then
524 : 0 : ABI_ERROR('uderiv: does not yet work for nspinor=2')
525 : : end if
526 : :
527 [ # # # # ]: 0 : if(maxval(istwfk(:))/=1)then
528 : : write(message,'(3a)')&
529 : 0 : & 'Sorry, this routine does not work yet with istwfk/=1.',ch10,&
530 : 0 : & 'This should have been tested previously ...'
531 : 0 : ABI_BUG(message)
532 : : end if
533 : :
534 [ # # ]: 0 : if (kptopt==3) then
535 : 0 : nkpt = nkpt_
536 [ # # # # : 0 : ABI_MALLOC(kpt,(3,nkpt))
# # # # #
# # # ]
537 [ # # # # ]: 0 : kpt(:,:)=kpt_(:,:)
538 [ # # ]: 0 : else if (kptopt==2) then
539 : 0 : nkpt = nkpt_*2
540 [ # # # # : 0 : ABI_MALLOC(kpt,(3,nkpt))
# # # # #
# # # ]
541 [ # # ]: 0 : do ikpt = 1,nkpt/2
542 : 0 : kpt_flag(ikpt) = 0
543 [ # # ]: 0 : kpt(:,ikpt)=kpt_(:,ikpt)
544 : : end do
545 : 0 : index = 0
546 [ # # ]: 0 : do ikpt = (nkpt/2+1),nkpt
547 : 0 : flag1 = 0
548 [ # # ]: 0 : do jkpt = 1, nkpt/2
549 : : if (((abs(kpt_(1,ikpt-nkpt/2)+kpt_(1,jkpt))<1.0d-8).or.&
550 : : & (abs(1-abs(kpt_(1,ikpt-nkpt/2)+kpt_(1,jkpt)))<1.0d-8))&
551 : : & .and.((abs(kpt_(2,ikpt-nkpt/2)+kpt_(2,jkpt))<1.0d-8).or.&
552 : : & (abs(1-abs(kpt_(2,ikpt-nkpt/2)+kpt_(2,jkpt)))<1.0d-8))&
553 [ # # # # : 0 : & .and.((abs(kpt_(3,ikpt-nkpt/2)+kpt_(3,jkpt))<1.0d-8).or.&
# # # # #
# ]
554 [ # # ]: 0 : & (abs(1-abs(kpt_(3,ikpt-nkpt/2)+kpt_(3,jkpt)))<1.0d-8))) then
555 : 0 : flag1 = 1
556 : 0 : index = index + 1
557 : : exit
558 : : end if
559 : : end do
560 : 0 : if (flag1==0) then
561 : 0 : kpt_flag(ikpt-index)=ikpt-nkpt/2
562 [ # # ]: 0 : kpt(:,ikpt-index)=-kpt_(:,ikpt-nkpt/2)
563 : : end if
564 : : end do
565 : 0 : nkpt = nkpt - index
566 : : end if
567 : :
568 : : !DEBUG
569 : : !write(101,*) 'beginning write kpt'
570 : : !do ikpt=1,nkpt
571 : : !write(101,*) kpt(:,ikpt)
572 : : !end do
573 : : !ENDDEBUG
574 : :
575 [ # # # # : 0 : ABI_MALLOC(shift_g_2,(nkpt,nkpt))
# # # # #
# # # # #
# # ]
576 : :
577 : : !Compute primitive vectors of the k point lattice
578 : : !Copy to real(dp)
579 [ # # # # ]: 0 : kptrlattr(:,:)=kptrlatt(:,:)
580 : : !Go to reciprocal space (in reduced coordinates)
581 : 0 : call matr3inv(kptrlattr,klattice)
582 : :
583 [ # # ]: 0 : do iberry=1,nberry
584 : :
585 : : ! **************************************************************************
586 : : ! Determine the appended index for ddk 1WF files
587 : :
588 [ # # ]: 0 : do idir=1,3
589 [ # # ]: 0 : if (kberry(idir,iberry) ==1) then
590 : 0 : ipert=natom+1
591 : 0 : pertcase=idir+(ipert-1)*3
592 : : end if
593 : : end do
594 : :
595 : : ! open ddk 1WF file
596 : 0 : formeig=1
597 : :
598 : 0 : call appdig(pertcase,fnameabo_1wf,fiwf1o)
599 : : !call wfk_open_read(wfk, fiwf1o, formeig, iomode, unddk, spaceComm)
600 : :
601 : 0 : spaceComm=xmpi_comm_self; me=0 ; iomode=IO_MODE_FORTRAN
602 : 0 : call WffOpen(iomode,spaceComm,fiwf1o,ierr,wffddk,master,me,unddk)
603 : :
604 : 0 : rdwr=2 ; fform=2
605 : 0 : call hdr_io(fform,hdr,rdwr,wffddk)
606 : :
607 : : ! Define offsets, in case of MPI I/O
608 : 0 : call xdefineOff(formeig,wffddk,mpi_enreg,nband,npwarr,nspinor,nsppol,nkpt_)
609 : :
610 : : ! *****************************************************************************
611 : : ! Calculate dimensional recip lattice vector along which P is calculated
612 : : ! dk = step to the nearest k point along that direction
613 : : ! in reduced coordinates
614 : :
615 : : dk(:)=dble(kberry(1,iberry))*klattice(:,1)+&
616 : : & dble(kberry(2,iberry))*klattice(:,2)+&
617 [ # # ]: 0 : & dble(kberry(3,iberry))*klattice(:,3)
618 : :
619 [ # # ]: 0 : do idir=1,3
620 [ # # ]: 0 : if (dk(idir)/=0) then
621 : 0 : twodk=2*dk(idir)
622 : : end if
623 : : end do
624 : :
625 [ # # ]: 0 : gpard(:)=dk(1)*gprimd(:,1)+dk(2)*gprimd(:,2)+dk(3)*gprimd(:,3)
626 : : gmod=sqrt(dot_product(gpard,gpard))
627 : :
628 : : ! ******************************************************************************
629 : : ! Select the k grid points along the direction to compute dudk
630 : : ! dk = step to the nearest k point along that direction
631 : :
632 : : ! For each k point, find k_prim such that k_prim= k + dk mod(G)
633 : : ! where G is a vector of the reciprocal lattice
634 [ # # # # : 0 : ABI_MALLOC(ikpt_dk,(2,nkpt))
# # # # #
# # # ]
635 [ # # # # ]: 0 : ikpt_dk(1:2,1:nkpt)=0
636 [ # # # # ]: 0 : shift_g_2(:,:)= .false.
637 : :
638 [ # # ]: 0 : do ikpt=1,nkpt
639 [ # # ]: 0 : do ikpt2=1,nkpt
640 [ # # ]: 0 : diffk(:)=abs(kpt(:,ikpt2)-kpt(:,ikpt)-dk(:))
641 [ # # ]: 0 : diffk2(:)=abs(kpt(:,ikpt2)-kpt(:,ikpt)+dk(:))
642 [ # # # # ]: 0 : if (sum(abs(diffk(:)-nint(diffk(:))))<3*tol8)then
643 : 0 : ikpt_dk(1,ikpt)=ikpt2
644 [ # # # # ]: 0 : if(sum(diffk(:))>=3*tol8) shift_g_2(ikpt,ikpt2) = .true.
645 : : end if
646 [ # # # # ]: 0 : if (sum(abs(diffk2(:)-nint(diffk2(:))))<3*tol8)then
647 : 0 : ikpt_dk(2,ikpt)=ikpt2
648 [ # # # # ]: 0 : if(sum(diffk2(:))>=3*tol8) shift_g_2(ikpt,ikpt2) = .true.
649 : : end if
650 : : end do
651 : : end do
652 : :
653 : 0 : write(message,'(a,a,a,3f9.5,a,a,3f9.5,a)')ch10,&
654 : 0 : & ' Computing the derivative for reciprocal vector:',ch10,&
655 : 0 : & dk(:),' (in reduced coordinates)',ch10,&
656 : 0 : & gpard(1:3),' (in cartesian coordinates - atomic units)'
657 : 0 : call wrtout(ab_out,message,'COLL')
658 : 0 : call wrtout(std_out,message,'COLL')
659 : :
660 [ # # ]: 0 : if(nsppol==1)then
661 : : write(message, '(a,i5,a,i5)')&
662 : 0 : & ' From band number',bdberry(1),' to band number',bdberry(2)
663 : : else
664 : : write(message, '(a,i5,a,i5,a,a,a,i5,a,i5,a)')&
665 : 0 : & ' From band number',bdberry(1),' to band number',bdberry(2),' for spin up,',&
666 : 0 : & ch10,&
667 : 0 : & ' from band number',bdberry(3),' to band number',bdberry(4),' for spin down.'
668 : : end if
669 : 0 : call wrtout(ab_out,message,'COLL')
670 : 0 : call wrtout(std_out,message,'COLL')
671 : :
672 : : ! *****************************************************************************
673 [ # # # # : 0 : ABI_MALLOC(dudk,(2,mpw*nspinor*mband*nsppol))
# # # # #
# # # ]
674 [ # # # # : 0 : ABI_MALLOC(eig_dum_2,((2*mband)**formeig*mband))
# # # # #
# # # ]
675 [ # # # # : 0 : ABI_MALLOC(occ_dum_2,((2*mband)**formeig*mband))
# # # # ]
676 [ # # # # ]: 0 : dudk(1:2,:)=0.0_dp
677 [ # # ]: 0 : eig_dum_2=0.0_dp
678 [ # # ]: 0 : occ_dum_2=0.0_dp
679 : :
680 [ # # ]: 0 : if (mkmem/=0) then
681 : :
682 : : ! Find the location of each wavefunction
683 : :
684 [ # # # # : 0 : ABI_MALLOC(cg_index,(mband,nkpt_,nsppol))
# # # # #
# # # # #
# # # # #
# ]
685 : 0 : icg = 0
686 [ # # ]: 0 : do isppol=1,nsppol
687 [ # # ]: 0 : do ikpt=1,nkpt_
688 : 0 : nband_k=nband(ikpt+(isppol-1)*nkpt_)
689 : 0 : npw_k=npwarr(ikpt)
690 [ # # ]: 0 : do iband=1,nband_k
691 : 0 : cg_index(iband,ikpt,isppol)=(iband-1)*npw_k*nspinor+icg
692 : : end do
693 : 0 : icg=icg+npw_k*nspinor*nband(ikpt)
694 : : end do
695 : : end do
696 : :
697 : : ! Find the planewave vectors for each k point
698 : : ! SHOULD BE REMOVED WHEN ANOTHER INDEXING TECHNIQUE WILL BE USED FOR kg
699 [ # # # # : 0 : ABI_MALLOC(kg_kpt,(3,mpw*nspinor,nkpt_))
# # # # #
# # # # #
# # ]
700 [ # # # # : 0 : kg_kpt(:,:,:) = 0
# # ]
701 : 0 : index1 = 0
702 [ # # ]: 0 : do ikpt=1,nkpt_
703 : 0 : npw_k=npwarr(ikpt)
704 [ # # ]: 0 : do ipw=1,npw_k*nspinor
705 [ # # ]: 0 : kg_kpt(1:3,ipw,ikpt)=kg(1:3,ipw+index1)
706 : : end do
707 : 0 : index1=index1+npw_k*nspinor
708 : : end do
709 : : end if
710 : :
711 : : ! *************************************************************************
712 : : ! Loop over spins
713 [ # # ]: 0 : do isppol=1,nsppol
714 : :
715 : 0 : minband=bdberry(2*isppol-1)
716 : 0 : maxband=bdberry(2*isppol)
717 : :
718 [ # # ]: 0 : if(minband<1)then
719 : 0 : write(message,'(a,i0,a)')' The band limit minband= ',minband,', is lower than 0.'
720 : 0 : ABI_BUG(message)
721 : : end if
722 : :
723 [ # # ]: 0 : if(maxband<1)then
724 : 0 : write(message,'(a,i0,a)')' The band limit maxband= ',maxband,', is lower than 0.'
725 : 0 : ABI_BUG(message)
726 : : end if
727 : :
728 [ # # ]: 0 : if(maxband<minband)then
729 : 0 : write(message,'(a,i0,a,i0)')' maxband= ',maxband,', is lower than minband= ',minband
730 : 0 : ABI_BUG(message)
731 : : end if
732 : :
733 : : ! Loop over k points
734 [ # # ]: 0 : do ikpt_=1,nkpt_
735 : :
736 : 0 : read_k = 0
737 : :
738 : 0 : ikpt=ikpt_
739 : 0 : tr(1) = 1.0_dp
740 : :
741 [ # # ]: 0 : if (kptopt==2) then
742 : : if (read_k == 0) then
743 [ # # ]: 0 : if (kpt_flag(ikpt_)/=0) then
744 : 0 : tr(1) = -1.0_dp
745 : 0 : ikpt= kpt_flag(ikpt_)
746 : : end if
747 : : else !read_k
748 : : if (kpt_flag(ikpt_)/=0) then
749 : : tr(-1*read_k+3) = -1.0_dp
750 : : ikpt= kpt_flag(ikpt_)
751 : : end if
752 : : end if !read_k
753 : : end if !kptopt
754 : :
755 : 0 : nband_k=nband(ikpt+(isppol-1)*nkpt_)
756 : :
757 [ # # ]: 0 : if(nband_k<maxband)then
758 : 0 : write(message,'(a,i0,a,i0)')' maxband=',maxband,', is larger than nband(i,isppol)=',nband_k
759 : 0 : ABI_BUG(message)
760 : : end if
761 : :
762 : 0 : npw_k=npwarr(ikpt)
763 : :
764 [ # # # # : 0 : ABI_MALLOC(u_tilde,(2,npw_k,maxband,2))
# # # # #
# # # # #
# # # # ]
765 [ # # # # : 0 : u_tilde(1:2,1:npw_k,1:maxband,1:2)=0.0_dp
# # # # ]
766 : :
767 : : ! ifor = 1,2 represents forward and backward neighbouring k points of ikpt
768 : : ! respectively along dk direction
769 : :
770 [ # # ]: 0 : do ifor=1,2
771 : :
772 [ # # # # : 0 : ABI_MALLOC(phi,(2,mpw,mband))
# # # # #
# # # # #
# # ]
773 [ # # # # : 0 : ABI_MALLOC(cmatrix,(2,maxband,maxband))
# # # # #
# # # # #
# # ]
774 [ # # # # : 0 : phi(1:2,1:mpw,1:mband)=0.0_dp; cmatrix(1:2,1:maxband,1:maxband)=0.0_dp
# # # # #
# # # ]
775 : :
776 : 0 : isgn=(-1)**ifor
777 : 0 : jkpt_= ikpt_dk(ifor,ikpt_)
778 : :
779 : 0 : tr(2) = 1.0_dp
780 : :
781 : 0 : jkpt=jkpt_
782 : :
783 [ # # ]: 0 : if (kptopt==2) then
784 [ # # ]: 0 : if (read_k == 0) then
785 [ # # ]: 0 : if (kpt_flag(jkpt_)/=0) then
786 : 0 : tr(2) = -1.0_dp
787 : 0 : jkpt= kpt_flag(jkpt_)
788 : : end if
789 : : else !read_k
790 [ # # ]: 0 : if (kpt_flag(jkpt_)/=0) then
791 : 0 : tr(read_k) = -1.0_dp
792 : 0 : jkpt= kpt_flag(jkpt_)
793 : : end if
794 : : end if !read_k
795 : : end if !kptopt
796 : :
797 [ # # ]: 0 : if (ifor==1) read_k = 2
798 : :
799 : 0 : jj = read_k
800 : 0 : ii = -1*read_k+3
801 : :
802 : : call waveformat(cg,cg_disk,cg_index,phi,dk,ii,ikpt,&
803 : : & ikpt_,isgn,isppol,jj,jkpt,jkpt_,kg_kpt,kpt,kg_jl,maxband,mband,mcg,mcg_disk,&
804 : 0 : & minband,mkmem,mpw,nkpt,nkpt_,npwarr,nsppol,nspinor,shift_g_2,tr)
805 : :
806 : : ! Compute the overlap matrix <u_k|u_k+b>
807 : :
808 [ # # ]: 0 : do iband=minband,maxband
809 : 0 : cg_index_iband=cg_index(iband,ikpt,isppol)
810 [ # # ]: 0 : do jband=minband,maxband
811 [ # # ]: 0 : do ipw=1,npwarr(ikpt)
812 : : cmatrix(1,iband,jband)=cmatrix(1,iband,jband)+&
813 : : & cg(1,ipw+cg_index_iband)*phi(1,ipw,jband)+&
814 : 0 : & tr(ii)*cg(2,ipw+cg_index_iband)*tr(jj)*phi(2,ipw,jband)
815 : :
816 : : cmatrix(2,iband,jband)=cmatrix(2,iband,jband)+&
817 : : & cg(1,ipw+cg_index_iband)*tr(jj)*phi(2,ipw,jband)-&
818 : 0 : & tr(ii)*cg(2,ipw+cg_index_iband)*phi(1,ipw,jband)
819 : : end do
820 : : end do
821 : : end do
822 : :
823 : : ! Compute the inverse of cmatrix(1:2,minband:maxband, minband:maxband)
824 : :
825 : 0 : band_in = maxband - minband + 1
826 [ # # # # : 0 : ABI_MALLOC(ipvt,(maxband))
# # # # #
# # # ]
827 [ # # # # : 0 : ABI_MALLOC(zgwork,(2,1:maxband))
# # # # #
# # # ]
828 : :
829 : : ! Last argument of zgedi means calculate inverse only
830 : 0 : call dzgefa(cmatrix(1,minband,minband),maxband, band_in,ipvt,info)
831 : 0 : call dzgedi(cmatrix(1,minband,minband),maxband, band_in,ipvt,det,zgwork,01)
832 : :
833 [ # # ]: 0 : ABI_FREE(zgwork)
834 [ # # ]: 0 : ABI_FREE(ipvt)
835 : :
836 : : ! Compute the product of Inverse overlap matrix with the wavefunction
837 : :
838 [ # # ]: 0 : do iband=minband,maxband
839 [ # # ]: 0 : do ipw=1,npwarr(ikpt)
840 : : u_tilde(1,ipw,iband,ifor)= &
841 : : & dot_product(cmatrix(1,minband:maxband,iband),&
842 : : & phi(1,ipw,minband:maxband))-&
843 : : & dot_product(cmatrix(2,minband:maxband,iband),&
844 [ # # # # ]: 0 : & tr(jj)*phi(2,ipw,minband:maxband))
845 : : u_tilde(2,ipw,iband,ifor)= &
846 : : & dot_product(cmatrix(1,minband:maxband,iband),&
847 : : & tr(jj)*phi(2,ipw,minband:maxband))+&
848 : : & dot_product(cmatrix(2,minband:maxband,iband),&
849 [ # # # # ]: 0 : & phi(1,ipw,minband:maxband))
850 : : end do
851 : : end do
852 [ # # ]: 0 : ABI_FREE(cmatrix)
853 [ # # ]: 0 : ABI_FREE(phi)
854 : :
855 : : end do !ifor
856 : :
857 : : ! Compute dudk for ikpt
858 : :
859 : : npw_k=npwarr(ikpt)
860 : :
861 [ # # ]: 0 : do iband=minband,maxband
862 : :
863 : 0 : icg=(iband-minband)*npw_k
864 : :
865 : : dudk(1,1+icg:npw_k+icg)=(u_tilde(1,1:npw_k,iband,1)-&
866 [ # # ]: 0 : & u_tilde(1,1:npw_k,iband,2))/twodk
867 : :
868 : : dudk(2,1+icg:npw_k+icg)=(u_tilde(2,1:npw_k,iband,1)-&
869 [ # # ]: 0 : & u_tilde(2,1:npw_k,iband,2))/twodk
870 : :
871 : : end do
872 : :
873 : 0 : tim_rwwf=0
874 : 0 : mcg_disk=mpw*nspinor*mband
875 : 0 : nband_diff=maxband-minband+1
876 : : call rwwf(dudk,eig_dum_2,formeig,0,0,ikpt,isppol,kg_kpt(:,:,ikpt),&
877 : : & mband,mcg_disk,mpi_enreg,nband_diff,nband_diff,&
878 : 0 : & npw_k,nspinor,occ_dum_2,2,1,tim_rwwf,wffddk)
879 : :
880 : : !call wfk_read_band_block(wfk, band_block, ikpt, isppol, sc_mode,
881 : : ! kg_k=kg_kpt(:,:,ikpt), cg_k=dudk, eig_k=eig_dum, occ_k=occ_dum)
882 : :
883 [ # # ]: 0 : ABI_FREE(u_tilde)
884 : :
885 : : end do !ikpt
886 : : end do !isppol
887 : :
888 [ # # ]: 0 : ABI_FREE(eig_dum_2)
889 [ # # ]: 0 : ABI_FREE(occ_dum_2)
890 [ # # ]: 0 : ABI_FREE(dudk)
891 : :
892 : 0 : call WffClose(wffddk,ierr)
893 : : !call wfk_close(wfk)
894 : :
895 [ # # ]: 0 : ABI_FREE(kg_kpt)
896 [ # # ]: 0 : ABI_FREE(cg_index)
897 [ # # ]: 0 : ABI_FREE(ikpt_dk)
898 : :
899 : : end do ! iberry
900 : :
901 [ # # ]: 0 : ABI_FREE(shift_g_2)
902 [ # # ]: 0 : ABI_FREE(kpt)
903 : :
904 : 0 : write(std_out,*) 'uderiv: exit '
905 : :
906 : 0 : end subroutine uderiv
907 : : !!***
908 : :
909 : :
910 : : !!****f* ABINIT/waveformat
911 : : !! NAME
912 : : !! waveformat
913 : : !!
914 : : !! FUNCTION
915 : : !! This routine is to find the matched pairs of plane waves between
916 : : !! two neighbouring k points and load a new pw coefficients array cg_new
917 : : !! Was written first by Na Sai (thanks), but unfortunately without
918 : : !! any comment ...
919 : : !!
920 : : !! INPUTS
921 : : !! cg(2,mpw*nspinor*mband*mkmem*nsppol)= input planewave coefficients, in case mkmem/=0
922 : : !! cg_disk(2,mpw*nspinor*mband,2)= input planewave coefficients, in case mkmem==0
923 : : !! cg_index(mband,nkpt_,nsppol)=index of wavefunction iband,ikpt,isppol in the array cg.
924 : : !! dk(3)= step taken to the next k mesh point along the kberry direction (see also isgn)
925 : : !! ii=(to be documented)
926 : : !! ikpt=index of the first k-point in the reduced Brillouin zone
927 : : !! ikpt_=index of the first k-point in the full Brillouin zone
928 : : !! isgn=1 if dk(3) is connecting the k-points (ikpt_ and jkpt)
929 : : !! =-1 if -dk(3) is connecting the k-points
930 : : !! isppol=1 if spin-up, =2 if spin-down
931 : : !! jj=(to be documented)
932 : : !! jkpt=index of the second k-point in the reduced Brillouin zone
933 : : !! jkpt_=index of the second k-point in the full Brillouin zone
934 : : !! kg_kpt(:,:,:)= unpacked reduced planewave coordinates with subscript of
935 : : !! planewave and k point
936 : : !! kpt(3,nkpt)=reduced coordinates of k-point grid that samples the whole BZ
937 : : !! kg_jl(3,mpw,2)=(to be documented)
938 : : !! maxband/minband= control the minimum and maximum band calculated in the
939 : : !! overlap matrix
940 : : !! mband=maximum number of bands (dimension of several cg* arrays)
941 : : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
942 : : !! mcg_disk=size of wave-functions array (cg_disk) =mpw*nspinor*mband
943 : : !! mkmem= if 0, the wavefunctions are input in cg_disk, otherwise in cg
944 : : !! mpw=maximum number of planewaves (dimension of several cg* arrays)
945 : : !! nkpt=number of k points (full Brillouin zone !?!)
946 : : !! nkpt_=number of k points (reduced Brillouin zone !?!)
947 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
948 : : !! nspinor=number of spinorial components of the wavefunctions
949 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
950 : : !! shift_g_2(nkpt,nkpt)=non-zero if a G vector along kberry is needed to connect k points
951 : : !! tr(2)=variable that changes k to -k
952 : : !! G to -G
953 : : !! $c_g$ to $c_g^*$ when time-reversal symetrie is used
954 : : !!
955 : : !! OUTPUT
956 : : !! cg_new(2,mpw,maxband)=planewave coefficients transferred onto the
957 : : !! set of planewaves at k
958 : : !!
959 : : !! SIDE EFFECTS
960 : : !!
961 : : !! SOURCE
962 : :
963 : 0 : subroutine waveformat(cg,cg_disk,cg_index,cg_new,dk,ii,ikpt,&
964 : 0 : & ikpt_,isgn,isppol,jj,jkpt,jkpt_,kg_kpt,kpt,kg_jl,maxband,mband,mcg,mcg_disk,&
965 : 0 : & minband,mkmem,mpw,nkpt,nkpt_,npwarr,nsppol,nspinor,shift_g_2,tr)
966 : :
967 : : !Arguments ------------------------------------
968 : : !scalars
969 : : integer,intent(in) :: ii,ikpt,ikpt_,isgn,isppol,jj,jkpt,jkpt_,maxband,mband,mcg,mcg_disk
970 : : integer,intent(in) :: minband,mkmem,mpw,nkpt,nkpt_,nspinor,nsppol
971 : : !arrays
972 : : integer,intent(in) :: cg_index(mband,nkpt_,nsppol),kg_jl(3,mpw,2)
973 : : integer,intent(in) :: kg_kpt(3,mpw*nspinor,nkpt_),npwarr(nkpt_)
974 : : real(dp),intent(in) :: cg(2,mcg)
975 : : real(dp),intent(in) :: cg_disk(2,mcg_disk,2),dk(3),kpt(3,nkpt),tr(2)
976 : : real(dp),intent(out) :: cg_new(2,mpw,maxband)
977 : : logical,intent(in) :: shift_g_2(nkpt,nkpt)
978 : :
979 : : !Local variables -------------------------
980 : : !scalars
981 : : integer :: cg_index_iband,iband,ipw,jpw,nomatch,npw_k
982 : : logical :: found_match
983 : : !arrays
984 : : integer :: dg(3)
985 : :
986 : : ! ***********************************************************************
987 : :
988 : 0 : npw_k=npwarr(ikpt)
989 : :
990 : :
991 : 0 : nomatch=0
992 : :
993 : : !If there is no shift of G-vector between ikpt_ and jkpt_
994 [ # # ]: 0 : if(shift_g_2(ikpt_,jkpt_) .eqv. .false.) then
995 : :
996 : : ! DEBUG
997 : : ! write(111,*)'pair', ikpt_,jkpt_,'noshift'
998 : : ! ENDDEBUG
999 : :
1000 : : ! If the original wavefunction is contained in cg_disk
1001 [ # # ]: 0 : if(mkmem==0) then
1002 : :
1003 [ # # ]: 0 : do ipw=1,npw_k
1004 : :
1005 : 0 : found_match = .false.
1006 : :
1007 [ # # ]: 0 : do jpw=1,npwarr(jkpt)
1008 [ # # # # ]: 0 : if (sum(abs(tr(ii)*kg_jl(:,ipw,ii)-tr(jj)*kg_jl(:,jpw,jj)))<3*tol8)then
1009 [ # # ]: 0 : do iband=minband, maxband
1010 : 0 : cg_index_iband=(iband-1)*npwarr(jkpt)
1011 [ # # ]: 0 : cg_new(1:2,ipw,iband)=cg_disk(1:2,jpw+cg_index_iband,jj)
1012 : : end do
1013 : : found_match = .true.
1014 : : exit
1015 : : end if
1016 : : end do
1017 : :
1018 [ # # ]: 0 : if (found_match .eqv. .false.) then
1019 [ # # ]: 0 : do iband=minband,maxband
1020 [ # # ]: 0 : cg_new(1:2,ipw,iband)=zero
1021 : : end do
1022 : 0 : nomatch = nomatch + 1
1023 : : end if
1024 : :
1025 : : end do
1026 : :
1027 : : ! Here, the wavefunctions are contained in cg
1028 : : else
1029 : :
1030 [ # # ]: 0 : do ipw=1,npw_k
1031 : :
1032 : 0 : found_match = .false.
1033 : :
1034 [ # # ]: 0 : do jpw=1,npwarr(jkpt)
1035 [ # # # # ]: 0 : if (sum(abs(tr(ii)*kg_kpt(:,ipw,ikpt)-tr(jj)*kg_kpt(:,jpw,jkpt)))<3*tol8)then
1036 [ # # ]: 0 : do iband=minband, maxband
1037 : 0 : cg_index_iband=cg_index(iband,jkpt,isppol)
1038 [ # # ]: 0 : cg_new(1:2,ipw,iband)=cg(1:2,jpw+cg_index_iband)
1039 : : end do
1040 : : found_match = .true.
1041 : : exit
1042 : : end if
1043 : : end do
1044 : :
1045 [ # # ]: 0 : if (found_match .eqv. .false.) then
1046 [ # # ]: 0 : do iband=minband,maxband
1047 [ # # ]: 0 : cg_new(1:2,ipw,iband)=(0.0_dp,0.0_dp)
1048 : : end do
1049 : 0 : nomatch = nomatch + 1
1050 : : end if
1051 : : end do
1052 : :
1053 : : end if
1054 : :
1055 : : ! DEBUG
1056 : : ! write(111,*) 'normal pair nomatch=',nomatch
1057 : : ! ENDDEBUG
1058 : :
1059 : : ! If there is a G-vector shift between ikpt_ and jkpt_
1060 : : else
1061 : :
1062 : : ! DEBUG
1063 : : ! write(111,*) 'pair',ikpt_,jkpt_,' need shift'
1064 : : ! ENDDEBUG
1065 : :
1066 [ # # ]: 0 : dg(:) = -1*nint(tr(jj)*kpt(:,jkpt)-tr(ii)*kpt(:,ikpt)+isgn*dk(:))
1067 : :
1068 : : ! If the original wavefunction is contained in cg_disk
1069 [ # # ]: 0 : if(mkmem==0) then
1070 : :
1071 [ # # ]: 0 : do ipw=1,npw_k
1072 : :
1073 : 0 : found_match = .false.
1074 : :
1075 [ # # ]: 0 : do jpw=1,npwarr(jkpt)
1076 [ # # # # ]: 0 : if (sum(abs(tr(ii)*kg_jl(:,ipw,ii)-(tr(jj)*kg_jl(:,jpw,jj)-&
1077 : 0 : & dg(:))))<3*tol8)then
1078 : :
1079 [ # # ]: 0 : do iband=minband, maxband
1080 : 0 : cg_index_iband=(iband-1)*npwarr(jkpt)
1081 [ # # ]: 0 : cg_new(1:2,ipw,iband)=cg_disk(1:2,jpw+cg_index_iband,jj)
1082 : : end do
1083 : : found_match = .true.
1084 : : exit
1085 : : end if
1086 : : end do
1087 : :
1088 [ # # ]: 0 : if (found_match .eqv. .false.) then
1089 [ # # ]: 0 : do iband=minband,maxband
1090 [ # # ]: 0 : cg_new(1:2,ipw,iband)=(0.0_dp,0.0_dp)
1091 : : end do
1092 : 0 : nomatch = nomatch + 1
1093 : : end if
1094 : : end do
1095 : :
1096 : : ! Here, the wavefunctions are contained in cg
1097 : : else
1098 : :
1099 [ # # ]: 0 : do ipw=1,npw_k
1100 : :
1101 : 0 : found_match = .false.
1102 : :
1103 [ # # ]: 0 : do jpw=1,npwarr(jkpt)
1104 [ # # # # ]: 0 : if (sum(abs(tr(ii)*kg_kpt(:,ipw,ikpt)-(tr(jj)*kg_kpt(:,jpw,jkpt)-&
1105 : 0 : & dg(:))))<3*tol8)then
1106 [ # # ]: 0 : do iband=minband, maxband
1107 : 0 : cg_index_iband=cg_index(iband,jkpt,isppol)
1108 [ # # ]: 0 : cg_new(1:2,ipw,iband)=cg(1:2,jpw+cg_index_iband)
1109 : : end do
1110 : : found_match = .true.
1111 : : exit
1112 : : end if
1113 : : end do
1114 : :
1115 [ # # ]: 0 : if (found_match .eqv. .false.) then
1116 [ # # ]: 0 : do iband=minband,maxband
1117 [ # # ]: 0 : cg_new(1:2,ipw,iband)=zero
1118 : : end do
1119 : 0 : nomatch = nomatch + 1
1120 : : end if
1121 : : end do
1122 : :
1123 : : end if
1124 : :
1125 : : ! DEBUG
1126 : : ! write(111,*) 'special pair nomatch=',nomatch
1127 : : ! ENDDEBUG
1128 : :
1129 : : end if
1130 : :
1131 : 0 : end subroutine waveformat
1132 : : !!***
1133 : :
1134 : : end module m_elpolariz
1135 : : !!***
|