Line data Source code
1 : !!****m* ABINIT/m_cgcprj
2 : !! NAME
3 : !! m_cgcprj
4 : !!
5 : !! FUNCTION
6 : !! Functions operating on wavefunctions in the cg+cprj representation.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2008-2026 ABINIT group (XG)
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_cgcprj
23 :
24 : use defs_basis
25 : use defs_abitypes
26 : use m_cgtools
27 : use m_errors
28 : use m_xmpi
29 :
30 : use m_pawtab, only : pawtab_type
31 : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_get, pawcprj_free, pawcprj_lincom
32 :
33 : implicit none
34 :
35 : private
36 : !!***
37 :
38 : public :: dotprod_set_cgcprj
39 : public :: dotprodm_sumdiag_cgcprj
40 : public :: lincom_cgcprj
41 : public :: cgcprj_cholesky
42 : !!***
43 :
44 : contains
45 : !!***
46 :
47 : !!****f* ABINIT/dotprod_set_cgcprj
48 : !! NAME
49 : !! dotprod_set_cgcprj
50 : !!
51 : !! FUNCTION
52 : !! For one k point and spinpol, compute the matrix of scalar products between two sets of nband wavefunctions
53 : !! that are known in the cg+cprj representation
54 : !! Smn=<wf1m|wf2n>
55 : !!
56 : !! Can also treat the case of the computation of scalar products within one set of nband wavefunctions
57 : !! without recomputing already computed matrix elements (define hermitian=1)
58 : !!
59 : !! This implementation is NOT band-parallelized
60 : !! Also, it is far of being optimal at the level of linear algebra, and involves extra copying
61 : !! that are detrimental for performance...
62 : !!
63 : !! INPUTS
64 : !! atindx1(natom)=index table for atoms, inverse of atindx
65 : !! cg1(2,mcg1)= plane wave wavefunction coefficients for the first set of wavefunctions (all k points and spinpol)
66 : !! cg2(2,mcg2)= plane wave wavefunction coefficients for the second set of wavefunctions (all k points and spinpol)
67 : !! cprj1(natom,mcprj1) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors in the first set,
68 : !! cprj2(natom,mcprj2) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors in the second set,
69 : !! dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
70 : !! hermitian= if 1, consider that the Smn matrix is hermitian, and do not recompute already computed matrix elements.
71 : !! ibg1=shift in cprj1 array to locate current k-point.
72 : !! Might be 0, in which case cprj1 is not copied internally, which saves some time/space
73 : !! ibg2=shift in cprj2 array to locate current k-point.
74 : !! Might be 0, in which case cprj2 is not copied internally, which saves some time/space
75 : !! icg1=shift in cg1 array to locate current k-point
76 : !! icg2=shift in cg2 array to locate current k-point
77 : !! ikpt=current k point index
78 : !! isppol=current spin polarization index
79 : !! istwf=input option parameter that describes the storage of wfs
80 : !! mcg1=second dimension of cg1 array (mpw*nspinor*mband1*mkmem*nsppol)
81 : !! mcg2=second dimension of cg2 array (mpw*nspinor*mband2*mkmem*nsppol)
82 : !! mcprj1=second dimension of cprj1 array
83 : !! mcprj2=second dimension of cprj2 array
84 : !! mkmem=number of k points which can fit in memory
85 : !! mpi_enreg=information about MPI parallelization
86 : !! natom=number of atoms
87 : !! nattyp(ntypat)=number of atoms of each type in cell.
88 : !! nbd1=number of bands for the first set of wavefunctions
89 : !! nbd2=number of bands for the second set of wavefunctions
90 : !! npw=number of planewaves in basis at this k point
91 : !! nspinor=number of spinor components
92 : !! nsppol=number of spin polarizations
93 : !! ntypat=number of types of atoms
94 : !! pawtab(dtset%ntypat*dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
95 : !! usepaw=1 if PAW is activated
96 : !!
97 : !! OUTPUT
98 : !! smn(2,nbd1,nbd2)=matrix of scalar products between the first set of wavefunctions and the second set of wavefunctions
99 : !!
100 : !! SIDE EFFECTS
101 : !!
102 : !! SOURCE
103 :
104 282 : subroutine dotprod_set_cgcprj(atindx1,cg1,cg2,cprj1,cprj2,dimcprj,hermitian,&
105 : & ibg1,ibg2,icg1,icg2,ikpt,isppol,istwf,mband,mcg1,mcg2,mcprj1,mcprj2,mkmem,&
106 282 : & mpi_enreg,natom,nattyp,nbd1,nbd2,npw,nspinor,nsppol,ntypat,pawtab,smn,usepaw)
107 :
108 : !Arguments ------------------------------------
109 : !scalars
110 : integer, intent(in) :: hermitian,ibg1,ibg2,icg1,icg2,ikpt,isppol,istwf
111 : integer, intent(in) :: mkmem,mband,mcg1,mcg2,mcprj1,mcprj2
112 : integer, intent(in) :: natom,nbd1,nbd2,npw,nspinor,nsppol,ntypat,usepaw
113 : type(MPI_type),intent(in) :: mpi_enreg
114 : !arrays
115 : integer, intent(in) :: atindx1(natom),dimcprj(natom),nattyp(ntypat)
116 : real(dp), intent(in) :: cg1(2,mcg1),cg2(2,mcg2)
117 : real(dp), intent(out) :: smn(2,nbd1,nbd2)
118 : type(pawcprj_type),intent(in) :: cprj1(natom,mcprj1),cprj2(natom,mcprj2)
119 : type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
120 :
121 : !Local variables-------------------------------
122 : !scalars
123 : integer :: ia,iat,itypat,ibd1,ibd2,icgb1,icgb2,ier,ig,ii,i1,i2,iorder
124 : integer :: ilmn1,ilmn2,klmn,max_nbd2,nbd
125 : real(dp) :: dotr,doti
126 : !arrays
127 282 : real(dp),allocatable :: cwavef1(:,:),cwavef2(:,:),proj(:,:,:)
128 282 : real(dp),allocatable :: eigval(:),eigvec(:,:,:),matrx(:,:),zhpev1(:,:),zhpev2(:)
129 282 : type(pawcprj_type),allocatable :: cprj1_k(:,:),cprj2_k(:,:)
130 :
131 : ! *************************************************************************
132 :
133 : !DEBUG
134 : !write(std_out,*)' dotprod_set_cgcprj : enter '
135 : !write(std_out,*)' dotprod_set_cgcprj : npw, nspinor=',npw,nspinor
136 : !write(std_out,*)' dotprod_set_cgcprj : usepaw,nbd1,nbd2=',usepaw,nbd1,nbd2
137 : !call flush(std_out)
138 : !ENDDEBUG
139 :
140 282 : if(hermitian==1)then
141 141 : if(nbd1/=nbd2)then
142 0 : ABI_ERROR(' With hermitian==1, nb1 and nb2 must be equal ')
143 : end if
144 : end if
145 :
146 846 : ABI_MALLOC(cwavef1,(2,npw*nspinor))
147 564 : ABI_MALLOC(cwavef2,(2,npw*nspinor))
148 282 : if(usepaw==1) then
149 1920 : ABI_MALLOC(cprj1_k,(natom,nspinor*nbd1))
150 1920 : ABI_MALLOC(cprj2_k,(natom,nspinor*nbd2))
151 120 : iorder=0 ! There is no change of ordering of cprj when copying wavefunctions
152 : end if
153 282 : if(usepaw==1 .and. ibg1/=0) then
154 0 : call pawcprj_alloc(cprj1_k,cprj1(1,1)%ncpgr,dimcprj)
155 : end if
156 282 : if(usepaw==1 .and. ibg2/=0) then
157 0 : call pawcprj_alloc(cprj2_k,cprj1(1,1)%ncpgr,dimcprj)
158 : end if
159 :
160 282 : icgb1=icg1
161 1380 : do ibd1=1,nbd1
162 :
163 : ! Extract wavefunction information
164 197602 : do ig=1,npw*nspinor
165 196504 : cwavef1(1,ig)=cg1(1,ig+icgb1)
166 197602 : cwavef1(2,ig)=cg1(2,ig+icgb1)
167 : end do
168 1098 : if(usepaw==1 .and. ibg1/=0) then
169 : call pawcprj_get(atindx1,cprj1_k,cprj1,natom,1,ibg1,ikpt,iorder,isppol,mband,&
170 : & mkmem,natom,nbd1,nbd1,nspinor,nsppol,0,&
171 0 : & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
172 : end if
173 :
174 1098 : icgb2=icg2
175 1098 : max_nbd2=nbd2
176 1098 : if(hermitian==1)max_nbd2=ibd1
177 4644 : do ibd2=1,max_nbd2
178 :
179 : ! XG171222 Note that this copy step, being inside the ibd1 loop, is quite detrimental.
180 : ! It might be reduced by copying several cwavef2, and use a ZGEMM type of approach.
181 :
182 : ! Extract wavefunction information
183 574324 : do ig=1,npw*nspinor
184 570778 : cwavef2(1,ig)=cg2(1,ig+icgb2)
185 574324 : cwavef2(2,ig)=cg2(2,ig+icgb2)
186 : end do
187 :
188 3546 : if(usepaw==1 .and. ibg2/=0) then
189 : call pawcprj_get(atindx1,cprj2_k,cprj2,natom,1,ibg2,ikpt,iorder,isppol,mband,&
190 : & mkmem,natom,nbd2,nbd2,nspinor,nsppol,0,&
191 0 : & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
192 : end if
193 :
194 : ! Calculate Smn=<cg1|cg2>
195 3546 : call dotprod_g(dotr,doti,istwf,npw*nspinor,2,cwavef1,cwavef2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
196 :
197 3546 : if(usepaw==1) then
198 : ia =0
199 3120 : do itypat=1,ntypat
200 1560 : if(ibg1/=0 .and. ibg2/=0)then
201 0 : do iat=1+ia,nattyp(itypat)+ia
202 0 : do ilmn1=1,pawtab(itypat)%lmn_size
203 0 : do ilmn2=1,ilmn1
204 0 : klmn=((ilmn1-1)*ilmn1)/2+ilmn2
205 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
206 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
207 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
208 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
209 : end do
210 0 : do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
211 0 : klmn=((ilmn2-1)*ilmn2)/2+ilmn1
212 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
213 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
214 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
215 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
216 : end do
217 : end do
218 : end do
219 1560 : else if(ibg1/=0 .and. ibg2==0)then
220 0 : do iat=1+ia,nattyp(itypat)+ia
221 0 : do ilmn1=1,pawtab(itypat)%lmn_size
222 0 : do ilmn2=1,ilmn1
223 0 : klmn=((ilmn1-1)*ilmn1)/2+ilmn2
224 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
225 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
226 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
227 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
228 : end do
229 0 : do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
230 0 : klmn=((ilmn2-1)*ilmn2)/2+ilmn1
231 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
232 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
233 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
234 0 : & cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
235 : end do
236 : end do
237 : end do
238 1560 : else if(ibg1==0 .and. ibg2/=0)then
239 0 : do iat=1+ia,nattyp(itypat)+ia
240 0 : do ilmn1=1,pawtab(itypat)%lmn_size
241 0 : do ilmn2=1,ilmn1
242 0 : klmn=((ilmn1-1)*ilmn1)/2+ilmn2
243 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
244 0 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
245 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
246 0 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
247 : end do
248 0 : do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
249 0 : klmn=((ilmn2-1)*ilmn2)/2+ilmn1
250 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
251 0 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
252 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
253 0 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
254 : end do
255 : end do
256 : end do
257 1560 : else if(ibg1==0 .and. ibg2==0)then
258 4680 : do iat=1+ia,nattyp(itypat)+ia
259 29640 : do ilmn1=1,pawtab(itypat)%lmn_size
260 137280 : do ilmn2=1,ilmn1
261 112320 : klmn=((ilmn1-1)*ilmn1)/2+ilmn2
262 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
263 112320 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
264 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
265 137280 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
266 : end do
267 115440 : do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
268 87360 : klmn=((ilmn2-1)*ilmn2)/2+ilmn1
269 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
270 87360 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
271 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
272 112320 : & cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
273 : end do
274 : end do
275 : end do
276 : end if
277 3120 : ia=ia+nattyp(itypat)
278 : end do
279 : end if
280 3546 : smn(1,ibd1,ibd2)=dotr
281 3546 : smn(2,ibd1,ibd2)=doti
282 : ! End loop over bands ibd2
283 4644 : icgb2=icgb2+npw*nspinor
284 :
285 : end do
286 :
287 : ! End loop over bands ibd1
288 1380 : icgb1=icgb1+npw*nspinor
289 : end do
290 :
291 : !Complete the matrix if hermitian
292 282 : if(hermitian==1)then
293 549 : do ibd1=1,nbd1-1
294 1365 : do ibd2=ibd1+1,nbd2
295 816 : smn(1,ibd1,ibd2)= smn(1,ibd2,ibd1)
296 1224 : smn(2,ibd1,ibd2)=-smn(2,ibd2,ibd1)
297 : end do
298 : end do
299 : end if
300 :
301 : !DEBUG
302 : !write(std_out,*)' smn=',smn
303 : !ENDDEBUG
304 :
305 : !====== Debugging section ==========
306 : if(.false.)then
307 : !DEBUG
308 : !Compute the eigenvalues of the projector S herm(S) or herm(S) S, depending on which has lowest dimension.
309 : !write(std_out,*)' dotprod_set_cgcprj : compute the projector matrix '
310 : nbd=min(nbd1,nbd2)
311 : ABI_MALLOC(proj,(2,nbd,nbd))
312 : proj(:,:,:)=zero
313 : if(nbd1<=nbd2)then
314 : do ibd1=1,nbd1
315 : do ibd2=1,nbd2
316 : proj(1,:,ibd1)=proj(1,:,ibd1)+smn(1,:,ibd2)*smn(1,ibd1,ibd2)+smn(2,:,ibd2)*smn(2,ibd1,ibd2)
317 : proj(2,:,ibd1)=proj(2,:,ibd1)-smn(1,:,ibd2)*smn(2,ibd1,ibd2)+smn(2,:,ibd2)*smn(1,ibd1,ibd2)
318 : end do
319 : end do
320 : else
321 : do ibd2=1,nbd2
322 : do ibd1=1,nbd1
323 : proj(1,:,ibd2)=proj(1,:,ibd2)+smn(1,ibd1,:)*smn(1,ibd1,ibd2)+smn(2,ibd1,:)*smn(2,ibd1,ibd2)
324 : proj(2,:,ibd2)=proj(2,:,ibd2)+smn(1,ibd1,:)*smn(2,ibd1,ibd2)-smn(2,ibd1,:)*smn(1,ibd1,ibd2)
325 : end do
326 : end do
327 : end if
328 :
329 : !write(std_out,*)' proj=',proj
330 :
331 : !write(std_out,*)' dotprod_set_cgcprj : compute the eigenvalues of the projector '
332 : ABI_MALLOC(matrx,(2,(nbd*(nbd+1))/2))
333 : ii=1
334 : do i2=1,nbd
335 : do i1=1,i2
336 : matrx(1,ii)=proj(1,i1,i2)
337 : matrx(2,ii)=proj(2,i1,i2)
338 : ii=ii+1
339 : end do
340 : end do
341 :
342 : ABI_MALLOC(zhpev1,(2,2*nbd-1))
343 : ABI_MALLOC(zhpev2,(3*nbd-2))
344 : ABI_MALLOC(eigval,(nbd))
345 : ABI_MALLOC(eigvec,(2,nbd,nbd))
346 :
347 : call ZHPEV ('V','U',nbd,matrx,eigval,eigvec,nbd,zhpev1,zhpev2,ier)
348 :
349 : !write(std_out,*)' eigval=',eigval
350 :
351 : ABI_FREE(matrx)
352 : ABI_FREE(zhpev1)
353 : ABI_FREE(zhpev2)
354 : ABI_FREE(eigval)
355 : ABI_FREE(eigvec)
356 :
357 : ABI_FREE(proj)
358 : !stop
359 : !ENDDEBUG
360 : end if
361 : !====== End of debugging section ==========
362 :
363 282 : ABI_FREE(cwavef1)
364 282 : ABI_FREE(cwavef2)
365 282 : if(usepaw==1) then
366 120 : if(ibg1/=0)then
367 0 : call pawcprj_free(cprj1_k)
368 : end if
369 120 : if(ibg2/=0)then
370 0 : call pawcprj_free(cprj2_k)
371 : end if
372 1080 : ABI_FREE(cprj1_k)
373 1080 : ABI_FREE(cprj2_k)
374 : end if
375 :
376 282 : end subroutine dotprod_set_cgcprj
377 : !!***
378 :
379 : !!****f* ABINIT/dotprodm_sumdiag_cgcprj
380 : !!
381 : !! NAME
382 : !! dotprodm_sumdiag_cgcprj
383 : !!
384 : !! FUNCTION
385 : !! For one k point and spinpol, compute the matrix of sum of diagonal scalar products
386 : !! between sets of nband wavefunctions that are known in the cg+cprj representation
387 : !! The sets of wavefunctions must be contained in a big array of sets of wavefunctions.
388 : !! Sij=Sum_m <wfm(set i)|wfm(set j)>
389 : !!
390 : !! Can also treat the case of the computation of scalar products within one set of wavefunctions
391 : !!
392 : !! This implementation is NOT band-parallelized
393 : !! Also, it is far of being optimal at the level of linear algebra, and involves extra copying
394 : !! that are detrimental for performance...
395 : !!
396 : !! INPUTS
397 : !! atindx1(natom)=index table for atoms, inverse of atindx
398 : !! cg_set(2,mcg,mset)= plane wave wavefunction coefficients for several sets of wavefunctions (all k points and spins)
399 : !! cprj_set(natom,mcprj,mset) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk>
400 : !! with NL projectors in the different sets
401 : !! dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
402 : !! ibg=shift in cprj_set array to locate current k-point
403 : !! icg=shift in cg_set array to locate current k-point
404 : !! ikpt=current k point index
405 : !! isppol=current spin polarization index
406 : !! istwf=input option parameter that describes the storage of wfs
407 : !! mband=maximum number of bands (used in the dimensioning of cprj_set)
408 : !! mcg=second dimension of cg array (mpw*nspinor*mband*mkmem*nsppol)
409 : !! mcprj=second dimension of cprj array
410 : !! mkmem=number of k points which can fit in memory
411 : !! mpi_enreg=information about MPI parallelization
412 : !! mset=third dimension of cg_set and cprj_set, maximum number of sets
413 : !! natom=number of atoms
414 : !! nattyp(ntypat)=number of atoms of each type in cell.
415 : !! nbd=number of bands for each set of wavefunctions
416 : !! npw=number of planewaves in basis at this k point
417 : !! nset1=number of sets of wavefunctions to be considered in the left side of the scalar products
418 : !! nset2=number of sets of wavefunctions to be considered in the right side of the scalar products
419 : !! nspinor=number of spinor components
420 : !! nsppol=number of spin polarizations
421 : !! ntypat=number of types of atoms
422 : !! pawtab(dtset%ntypat*dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
423 : !! shift_set1=shift that defines the first set of wavefunctions to be considered in the left side of the scalar products
424 : !! shift_set2=shift that defines the first set of wavefunctions to be considered in the right side of the scalar products
425 : !! usepaw=1 if PAW is activated
426 : !!
427 : !! OUTPUT
428 : !! smn(2,nset1,nset2)=matrix of sum of diagonal scalar products between the first set
429 : !! of wavefunctions and the second set of wavefunctions
430 : !!
431 : !! SIDE EFFECTS
432 : !!
433 : !! SOURCE
434 :
435 41 : subroutine dotprodm_sumdiag_cgcprj(atindx1,cg_set,cprj_set,dimcprj,&
436 : & ibg,icg,ikpt,isppol,istwf,mband,mcg,mcprj,mkmem,&
437 41 : & mpi_enreg,mset,natom,nattyp,nbd,npw,nset1,nset2,nspinor,nsppol,ntypat,&
438 41 : & shift_set1,shift_set2,pawtab,smn,usepaw)
439 :
440 : !Arguments ------------------------------------
441 : !scalars
442 : integer, intent(in) :: ibg,icg,ikpt,isppol,istwf
443 : integer, intent(in) :: mband,mcg,mcprj,mkmem,mset
444 : integer, intent(in) :: natom,nbd,npw,nset1,nset2,nspinor,nsppol,ntypat
445 : integer, intent(in) :: shift_set1,shift_set2,usepaw
446 : type(MPI_type),intent(in) :: mpi_enreg
447 : !arrays
448 : integer, intent(in) :: atindx1(natom),dimcprj(natom),nattyp(ntypat)
449 : real(dp), intent(in) :: cg_set(2,mcg,mset)
450 : real(dp), intent(out) :: smn(2,nset1,nset2)
451 : type(pawcprj_type),intent(in) :: cprj_set(natom,mcprj,mset)
452 : type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
453 :
454 : !Local variables-------------------------------
455 : !scalars
456 : integer :: ia,iat,itypat,ibd,icgb,ig,iorder
457 : integer :: ilmn1,ilmn2,ind_set1,ind_set2,iset1,iset2,klmn
458 : real(dp) :: dotr,doti
459 : !arrays
460 41 : real(dp),allocatable :: cwavef1(:,:),cwavef2(:,:)
461 41 : type(pawcprj_type),allocatable :: cprj1_k(:,:),cprj2_k(:,:)
462 :
463 : ! *************************************************************************
464 :
465 : !DEBUG
466 : !write(std_out,*)' dotprodm_sumdiag_cgcprj : enter '
467 : !call flush(std_out)
468 : !ENDDEBUG
469 :
470 123 : ABI_MALLOC(cwavef1,(2,npw*nspinor))
471 82 : ABI_MALLOC(cwavef2,(2,npw*nspinor))
472 41 : if(usepaw==1) then
473 0 : ABI_MALLOC(cprj1_k,(natom,nspinor*nbd))
474 0 : ABI_MALLOC(cprj2_k,(natom,nspinor*nbd))
475 0 : iorder=0 ! There is no change of ordering in the copy of wavefunctions
476 0 : call pawcprj_alloc(cprj1_k,cprj_set(1,1,1)%ncpgr,dimcprj)
477 : end if
478 :
479 661 : smn(:,:,:)=zero
480 :
481 41 : icgb=icg
482 190 : do ibd=1,nbd
483 :
484 298 : do iset1=1,nset1
485 :
486 149 : ind_set1=iset1+shift_set1
487 :
488 : ! Extract wavefunction information
489 41581 : do ig=1,npw*nspinor
490 41432 : cwavef1(1,ig)=cg_set(1,ig+icgb,ind_set1)
491 41581 : cwavef1(2,ig)=cg_set(2,ig+icgb,ind_set1)
492 : end do
493 149 : if(usepaw==1) then
494 : call pawcprj_get(atindx1,cprj1_k,cprj_set(:,:,ind_set1),natom,1,ibg,ikpt,iorder,isppol,mband,&
495 : & mkmem,natom,nbd,nbd,nspinor,nsppol,0,&
496 0 : & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
497 : end if
498 :
499 873 : do iset2=1,nset2
500 :
501 575 : ind_set2=iset2+shift_set2
502 575 : if(ind_set2<ind_set1 .and. ind_set2>shift_set1)then
503 : continue ! These matrix elements have already been computed, the smn matrix will be completed later.
504 :
505 575 : else if(ind_set1/=ind_set2)then
506 :
507 : ! Extract wavefunction information
508 106714 : do ig=1,npw*nspinor
509 106288 : cwavef2(1,ig)=cg_set(1,ig+icgb,ind_set2)
510 106714 : cwavef2(2,ig)=cg_set(2,ig+icgb,ind_set2)
511 : end do
512 :
513 426 : if(usepaw==1) then
514 : call pawcprj_get(atindx1,cprj2_k,cprj_set(:,:,ind_set2),natom,1,ibg,ikpt,iorder,isppol,mband,&
515 : & mkmem,natom,nbd,nbd,nspinor,nsppol,0,&
516 0 : & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
517 : end if
518 :
519 : ! Calculate Smn=<cg1|cg2>
520 426 : call dotprod_g(dotr,doti,istwf,npw*nspinor,2,cwavef1,cwavef2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
521 :
522 426 : if(usepaw==1) then
523 : ia =0
524 0 : do itypat=1,ntypat
525 0 : do iat=1+ia,nattyp(itypat)+ia
526 0 : do ilmn1=1,pawtab(itypat)%lmn_size
527 0 : do ilmn2=1,ilmn1
528 0 : klmn=((ilmn1-1)*ilmn1)/2+ilmn2
529 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2)+&
530 0 : & cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2))
531 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2)-&
532 0 : & cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2))
533 : end do
534 0 : do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
535 0 : klmn=((ilmn2-1)*ilmn2)/2+ilmn1
536 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2)+&
537 0 : & cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2))
538 : doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2)-&
539 0 : & cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2))
540 : end do
541 : end do
542 : end do
543 0 : ia=ia+nattyp(itypat)
544 : end do
545 : end if ! usepaw
546 :
547 : ! if(.false.)then
548 : else
549 : ! Diagonal part : no need to extract another wavefunction, and the scalar product must be real
550 :
551 : ! Calculate Smn=<cg1|cg1>
552 149 : call dotprod_g(dotr,doti,istwf,npw*nspinor,1,cwavef1,cwavef1,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
553 :
554 149 : if(usepaw==1) then
555 : ia =0
556 0 : do itypat=1,ntypat
557 0 : do iat=1+ia,nattyp(itypat)+ia
558 0 : do ilmn1=1,pawtab(itypat)%lmn_size
559 0 : do ilmn2=1,ilmn1
560 0 : klmn=((ilmn1-1)*ilmn1)/2+ilmn2
561 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj1_k(iat,ibd)%cp(1,ilmn2)+&
562 0 : & cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj1_k(iat,ibd)%cp(2,ilmn2))
563 : end do
564 0 : do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
565 0 : klmn=((ilmn2-1)*ilmn2)/2+ilmn1
566 : dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj1_k(iat,ibd)%cp(1,ilmn2)+&
567 0 : & cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj1_k(iat,ibd)%cp(2,ilmn2))
568 : end do
569 : end do
570 : end do
571 0 : ia=ia+nattyp(itypat)
572 : end do
573 : end if ! usepaw
574 149 : doti=zero
575 :
576 : end if ! Compare ind_set1 and ind_set2
577 :
578 575 : smn(1,iset1,iset2)=smn(1,iset1,iset2)+dotr
579 724 : smn(2,iset1,iset2)=smn(2,iset1,iset2)+doti
580 :
581 : end do ! iset2
582 : end do ! iset1
583 :
584 : ! End loop over bands ibd
585 190 : icgb=icgb+npw*nspinor
586 : end do
587 :
588 : !Complete the matrix, using its hermitian property.
589 82 : do iset1=1,nset1
590 41 : ind_set1=iset1+shift_set1
591 237 : do iset2=1,nset2
592 155 : ind_set2=iset2+shift_set2
593 196 : if(ind_set2<ind_set1 .and. ind_set2>shift_set1)then
594 0 : smn(1,iset1,iset2)= smn(1,iset2,iset1)
595 0 : smn(2,iset1,iset2)=-smn(2,iset2,iset1)
596 : end if
597 : end do
598 : end do
599 :
600 41 : ABI_FREE(cwavef1)
601 41 : ABI_FREE(cwavef2)
602 41 : if(usepaw==1) then
603 0 : call pawcprj_free(cprj1_k)
604 0 : call pawcprj_free(cprj2_k)
605 0 : ABI_FREE(cprj1_k)
606 0 : ABI_FREE(cprj2_k)
607 : end if
608 :
609 41 : end subroutine dotprodm_sumdiag_cgcprj
610 : !!***
611 :
612 : !!****f* ABINIT/lincom_cgcprj
613 : !!
614 : !! NAME
615 : !! lincom_cgcprj
616 : !!
617 : !! FUNCTION
618 : !! For one k point and spin, compute a set (size nband_out) of linear combinations of nband_in wavefunctions,
619 : !! that are known in the cg+cprj representation :
620 : !! cgout_n(:,:) <--- Sum_m [ cg_m(:,:) . alpha_mn ]
621 : !! cprjout_n(:,:) <--- Sum_m [ cprj_m(:,:) . alpha_mn ]
622 : !! If nband_out is smaller or equal to nband_in, the result might be in-place
623 : !! output in cg instead of cgout, and in cprj instead of cprjout).
624 : !! Otherwise, it is contained in the optional cgout+cprjout pair.
625 : !!
626 : !! In the present status, the cg and cgout relates to all the k points and spins, and rely on the icg index,
627 : !! while it is assumed that cprj and cprjout refer to the specific k point and spin.
628 : !! This is not coherent.
629 : !! THIS MIGHT BE CHANGED IN THE FUTURE !
630 : !!
631 : !! This implementation is NOT band-parallelized
632 : !! Also, it is far of being optimal at the level of linear algebra, and involves extra copying
633 : !! that are detrimental for performance...
634 : !!
635 : !! INPUTS
636 : !! alpha_mn(2,nband_in,nband_out)=complex matrix of coefficients of the linear combinations to be computed
637 : !! dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
638 : !! icg=shift in cg array to locate current k-point and spinpol (for input, and possibly for in-place output)
639 : !! inplace= if 0, output in cgout and cprjout ; if 1, output in cg and cprj
640 : !! mcg=second dimension of cg array (mpw*nspinor*mband*mkmem*nsppol)
641 : !! mcprj=second dimension of cprj array
642 : !! natom=number of atoms
643 : !! nband_in=number of bands, size of the input set of wavefunctions
644 : !! nband_out=number of bands, size of the output set of wavefunctions (should be equal to nband_in if inplace==1)
645 : !! npw=number of planewaves in basis at this k point
646 : !! nspinor=number of spinor components
647 : !! usepaw=1 if PAW is activated
648 : !! [icgout= shift in cgout array to locate current k-point and spinpol (for output)]
649 : !! [mcgout=second dimension of cgout array (mpw*nspinor*mband*mkmem*nsppol)]
650 : !! [mcprjout=second dimension of cprjout array]
651 : !!
652 : !! OUTPUT
653 : !! [cgout(2,mcgout)= plane wave wavefunction coefficients for the set of output wavefunctions]
654 : !! [cprjout(natom,mcprjout) <type(pawcprj_type)>= projected output wave functions <Proj_i|Cnk> with NL projectors]
655 : !!
656 : !! SIDE EFFECTS
657 : !! (this quantities are input, and possibly updated output when inplace==1)
658 : !! cg(2,mcg)= plane wave wavefunction coefficients for the set of input wavefunctions (all k points and spinpol)
659 : !! cprj(natom,mcprj) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors
660 : !!
661 : !! SOURCE
662 :
663 564 : subroutine lincom_cgcprj(alpha_mn,cg,cprj,dimcprj,&
664 : & icg,inplace,mcg,mcprj,natom,nband_in,nband_out,npw,nspinor,usepaw, &
665 282 : & cgout,cprjout,icgout) ! optional args
666 :
667 : !Arguments ------------------------------------
668 : !scalars
669 : integer, intent(in) :: icg,inplace,mcg,mcprj
670 : integer, intent(in) :: natom,nband_in,nband_out,npw,nspinor,usepaw
671 : integer, intent(in),optional :: icgout
672 : !arrays
673 : integer, intent(in) :: dimcprj(natom)
674 : real(dp), intent(inout) :: cg(2,mcg)
675 : real(dp), intent(in) :: alpha_mn(2,nband_in,nband_out)
676 : real(dp), intent(out),optional :: cgout(:,:)
677 : type(pawcprj_type),intent(inout) :: cprj(natom,mcprj)
678 : type(pawcprj_type),intent(inout),optional :: cprjout(:,:) ! ifort and others are buggy for optional intent(out) structured types
679 :
680 : !Local variables-------------------------------
681 : !scalars
682 : integer :: iband_in,iband_out,ii
683 : !arrays
684 282 : real(dp),allocatable :: al(:,:),cgout_(:,:)
685 282 : type(pawcprj_type),allocatable :: cprjout_(:,:)
686 :
687 : ! *************************************************************************
688 :
689 : !DEBUG
690 : !write(std_out,*)' lincom_cgcprj : enter '
691 : !write(std_out,*)' lincom_cgcprj : npw, nspinor=',npw,nspinor
692 : !write(std_out,*)' lincom_cgcprj : icgout=',icgout
693 : !ENDDEBUG
694 :
695 282 : if(inplace==0)then
696 36 : if(.not.present(cgout))then
697 0 : ABI_ERROR(' inplace==0 while .not.present(cgout) is not permitted ')
698 : end if
699 36 : if(usepaw==1) then
700 0 : if(.not.present(cprjout))then
701 0 : ABI_ERROR(' inplace==0 and usepaw==1 while .not.present(cprjout) is not permitted ')
702 : end if
703 : end if
704 : end if
705 :
706 : !Take care of the plane wave part
707 846 : ABI_MALLOC(cgout_,(2,npw*nspinor*nband_out))
708 :
709 : call zgemm('N','N',npw*nspinor,nband_out,nband_in,dcmplx(1._dp), &
710 : & cg(:,icg+1:icg+npw*nspinor*nband_in),npw*nspinor, &
711 282 : & alpha_mn,nband_in,dcmplx(0._dp),cgout_,npw*nspinor)
712 :
713 282 : if(inplace==1)then
714 483294 : cg(:,icg+1:icg+npw*nspinor*nband_out)=cgout_
715 : else
716 106500 : cgout(:,icgout+1:icgout+npw*nspinor*nband_out)=cgout_
717 : end if
718 282 : ABI_FREE(cgout_)
719 :
720 : !Take care of the cprj part
721 282 : if(usepaw==1) then
722 :
723 1920 : ABI_MALLOC(cprjout_,(natom,nspinor*nband_out))
724 120 : call pawcprj_alloc(cprjout_,cprj(1,1)%ncpgr,dimcprj)
725 360 : ABI_MALLOC(al,(2,nband_in))
726 600 : do iband_out=1,nband_out
727 480 : ii=(iband_out-1)*nspinor
728 2400 : do iband_in=1,nband_in
729 1920 : al(1,iband_in)=alpha_mn(1,iband_in,iband_out)
730 2400 : al(2,iband_in)=alpha_mn(2,iband_in,iband_out)
731 : end do
732 600 : call pawcprj_lincom(al,cprj,cprjout_(:,ii+1:ii+nspinor),nband_in)
733 : end do
734 120 : ABI_FREE(al)
735 :
736 120 : if(inplace==1)then
737 1560 : cprj=cprjout_
738 : else
739 0 : cprjout=cprjout_
740 : end if
741 120 : call pawcprj_free(cprjout_)
742 1080 : ABI_FREE(cprjout_)
743 :
744 : end if
745 :
746 282 : end subroutine lincom_cgcprj
747 : !!***
748 :
749 : !!****m* ABINIT/cgcprj_cholesky
750 : !! NAME
751 : !! cgcprj_cholesky
752 : !!
753 : !! FUNCTION
754 : !! Cholesky orthonormalization of the vectors stored in cg+cprj mode.
755 : !!
756 : !! This implementation is NOT band-parallelized
757 : !! Also, it is far of being optimal at the level of linear algebra
758 : !!
759 : !! INPUTS
760 : !! atindx1(natom)=index table for atoms, inverse of atindx
761 : !! dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
762 : !! icg=shift in cg array to locate current k-point and spinpol
763 : !! ikpt=current k point index
764 : !! isppol=current spin polarization index
765 : !! istwf=input option parameter that describes the storage of wfs
766 : !! mcg=second dimension of cg array (mpw*nspinor*mband*mkmem*nsppol)
767 : !! mcprj=second dimension of cprj_k array
768 : !! mkmem=number of k points which can fit in memory
769 : !! mpi_enreg=information about MPI parallelization
770 : !! natom=number of atoms
771 : !! nattyp(ntypat)=number of atoms of each type in cell.
772 : !! nband=number of bands
773 : !! npw=number of planewaves in basis at this k point
774 : !! nspinor=number of spinor components
775 : !! nsppol=number of spin polarizations
776 : !! ntypat=number of types of atoms
777 : !! pawtab(dtset%ntypat*dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
778 : !! usepaw=1 if PAW is activated
779 : !!
780 : !! SIDE EFFECTS
781 : !! cg(2,mcg)= plane wave wavefunction coefficients for the set of input wavefunctions (all k points and spinpol)
782 : !! cprj_k(natom,mcprj) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors for the specific k point and spinpol
783 : !!
784 : !! SOURCE
785 :
786 141 : subroutine cgcprj_cholesky(atindx1,cg,cprj_k,dimcprj,icg,ikpt,isppol,istwf,mcg,mcprj,mkmem,&
787 141 : & mpi_enreg,natom,nattyp,nband,npw,nspinor,nsppol,ntypat,pawtab,usepaw)
788 :
789 : !Arguments ------------------------------------
790 : !scalars
791 : integer,intent(in) :: icg,ikpt,isppol,istwf,mcg,mcprj,mkmem
792 : integer,intent(in) :: natom,nband,npw,nspinor,nsppol,ntypat,usepaw
793 : !arrays
794 : integer, intent(in) :: atindx1(natom),dimcprj(natom),nattyp(ntypat)
795 : real(dp), intent(inout) :: cg(2,mcg)
796 : type(pawcprj_type),intent(inout) :: cprj_k(natom,mcprj)
797 : type(MPI_type),intent(in) :: mpi_enreg
798 : type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
799 :
800 : !Local variables ------------------------------
801 : !scalars
802 : integer :: hermitian,ierr,ii,inplace
803 : !arrays
804 141 : real(dp), allocatable :: dmn(:,:,:),smn(:,:,:)
805 :
806 : ! *************************************************************************
807 :
808 564 : ABI_MALLOC(smn,(2,nband,nband))
809 423 : ABI_MALLOC(dmn,(2,nband,nband))
810 :
811 141 : hermitian=1
812 : call dotprod_set_cgcprj(atindx1,cg,cg,cprj_k,cprj_k,dimcprj,hermitian,&
813 : & 0,0,icg,icg,ikpt,isppol,istwf,nband,mcg,mcg,mcprj,mcprj,mkmem,&
814 141 : & mpi_enreg,natom,nattyp,nband,nband,npw,nspinor,nsppol,ntypat,pawtab,smn,usepaw)
815 :
816 : !Cholesky factorization: O = U^H U with U upper triangle matrix.
817 141 : call ZPOTRF('U',nband,smn,nband,ierr)
818 :
819 : !Solve X U = 1.
820 7233 : dmn=zero
821 690 : do ii=1,nband
822 690 : dmn(1,ii,ii)=one
823 : end do
824 141 : call ZTRSM('Right','Upper','Normal','Normal',nband,nband,cone,smn,nband,dmn,nband)
825 :
826 141 : inplace=1
827 : !This call does not take into account the fact that X=dmn is an upper triangular matrix...
828 : !The number of operations might be divided by two.
829 : call lincom_cgcprj(dmn,cg,cprj_k,dimcprj,&
830 141 : & icg,inplace,mcg,mcprj,natom,nband,nband,npw,nspinor,usepaw)
831 :
832 141 : ABI_FREE(smn)
833 141 : ABI_FREE(dmn)
834 :
835 141 : end subroutine cgcprj_cholesky
836 : !!***
837 :
838 : end module m_cgcprj
839 : !!***
|