Branch data Line data Source code
1 : : !!****m* ABINIT/m_cgwf_cprj
2 : : !! NAME
3 : : !! m_cgwf_cprj
4 : : !!
5 : : !! FUNCTION
6 : : !! Conjugate-gradient eigensolver.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (DCA, XG, GMR, MT, MVeithen, ISouza, JIniguez)
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_cgwf_cprj
23 : :
24 : : use defs_basis
25 : : use m_errors
26 : : use m_xmpi
27 : : use m_abicore
28 : : use m_cgtools
29 : :
30 : : use defs_abitypes, only : MPI_type
31 : : use m_time, only : timab
32 : : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_copy, &
33 : : pawcprj_free,&
34 : : pawcprj_axpby,pawcprj_zaxpby,pawcprj_projbd
35 : : use m_hamiltonian, only : gs_hamiltonian_type
36 : : use m_getchc, only : getchc,getcsc
37 : : use m_getghc, only : getghc
38 : : use m_nonlop, only : nonlop
39 : : use m_paw_overlap, only : smatrix_k_paw
40 : : use m_cgprj, only : getcprj
41 : : use m_fft, only : fourwf
42 : : use m_dtset, only : dataset_type
43 : :
44 : : implicit none
45 : :
46 : : private
47 : : !!***
48 : :
49 : : public :: cgwf_cprj
50 : : public :: mksubovl
51 : : public :: cprj_update
52 : : public :: cprj_update_oneband
53 : : public :: cprj_check
54 : : public :: get_cprj_id
55 : :
56 : : !!***
57 : :
58 : : contains
59 : : !!***
60 : :
61 : : !!****f* m_cgwf/cgwf_cprj
62 : : !! NAME
63 : : !! cgwf_cprj
64 : : !!
65 : : !! FUNCTION
66 : : !! Update all wavefunction |C>, non self-consistently.
67 : : !! Uses a conjugate-gradient algorithm.
68 : : !! This version is available for PAW only, as it needs the cprj in memory.
69 : : !!
70 : : !! INPUTS
71 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
72 : : !! icg=shift to be applied on the location of data in the array cg
73 : : !! mcg=second dimension of the cg array
74 : : !! mpi_enreg=information about MPI parallelization
75 : : !! nband=number of bands.
76 : : !! nline=number of line minimizations per band.
77 : : !! ortalg=governs the choice of the algorithm for orthogonalisation.
78 : : !! prtvol=control print volume and debugging output
79 : : !! tolrde=tolerance on the ratio of differences of energies (for the line minimisation)
80 : : !! tolwfr=tolerance on largest wf residual
81 : : !! wfoptalg=govern the choice of algorithm for wf optimisation
82 : : !! (0, 1, 10 and 11 : in the present routine, usual CG algorithm ;
83 : : !!
84 : : !! OUTPUT
85 : : !! resid(nband)=wf residual for new states=|(H-e)|C>|^2 (hartree^2)
86 : : !!
87 : : !! SIDE EFFECTS
88 : : !! cg(2,mcg)
89 : : !! at input =wavefunction <G|C band,k> coefficients for ALL bands
90 : : !! at output same as input except that
91 : : !! the current band, with number 'band' has been updated
92 : : !! cprj_cwavef_bands=<p_i|c_n> coefficients for all bands n, they are updated when the WFs change.
93 : : !! quit= if 1, proceeds to smooth ending of the job.
94 : : !!
95 : : !! NOTES
96 : : !!
97 : : !! SOURCE
98 : :
99 [ # # # # ]: 0 : subroutine cgwf_cprj(cg,cprj_cwavef_bands,cprj_update_lvl,eig,&
100 [ # # # # ]: 0 : & gs_hamk,icg,mcg,mpi_enreg,nband,nline,ortalg,prtvol,quit,resid,subham,&
101 : : & tolrde,tolwfr,wfoptalg)
102 : : !Arguments ------------------------------------
103 : : integer,intent(in) :: cprj_update_lvl,icg
104 : : integer,intent(in) :: mcg,nband,nline,ortalg,prtvol
105 : : integer,intent(in) :: wfoptalg,quit
106 : : real(dp),intent(in) :: tolrde,tolwfr
107 : : type(MPI_type),intent(in) :: mpi_enreg
108 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
109 : : !arrays
110 : : real(dp),intent(inout),target :: cg(2,mcg)
111 : : real(dp), intent(inout) :: eig(:)
112 : : real(dp),intent(out) :: resid(:),subham(:)
113 : : type(pawcprj_type),intent(inout),target :: cprj_cwavef_bands(:,:)
114 : :
115 : : !Local variables-------------------------------
116 : : integer,parameter :: level=113,tim_getghc=1,tim_projbd=1,type_calc=0,tim_getcprj=3
117 : : integer,parameter :: useoverlap=0,tim_getcsc=3
118 : : integer,save :: nskip=0
119 : : integer :: cpopt,i1,i2,i3,iband,isubh,isubh0,jband,me_g0,igs
120 : : integer :: iline,ipw,ispinor,istwf_k
121 : : integer :: n4,n5,n6,natom,ncpgr,npw,nspinor
122 : : integer :: optekin,sij_opt,wfopta10
123 : : real(dp) :: chc,costh,deltae,deold,dhc,dhd,diff,dotgg,dotgp,doti,dotr,eval,gamma
124 : : real(dp) :: lam0,lamold,root,sinth,sintn,swap,tan2th,xnorm,xnormd,xnormd_previous
125 : : character(len=500) :: message
126 : : !arrays
127 : : real(dp) :: dot(2)
128 : : real(dp) :: tsec(2)
129 : 0 : real(dp),allocatable :: conjgr(:,:),gvnlxc(:,:)
130 : 0 : real(dp), pointer :: cwavef(:,:),cwavef_left(:,:),cwavef_bands(:,:)
131 : 0 : real(dp), allocatable :: cwavef_r(:,:,:,:,:)
132 : 0 : real(dp),allocatable,target :: direc(:,:)
133 : 0 : real(dp),allocatable :: direc_tmp(:,:),pcon(:),scprod(:,:),scwavef_dum(:,:)
134 : 0 : real(dp),allocatable :: direc_r(:,:,:,:,:),scprod_csc(:)
135 : : real(dp) :: z_tmp(2),z_tmp2(2)
136 : 0 : type(pawcprj_type),pointer :: cprj_cwavef(:,:),cprj_cwavef_left(:,:)
137 : 0 : type(pawcprj_type),allocatable :: cprj_direc(:,:),cprj_conjgr(:,:)
138 : :
139 : : ! *********************************************************************
140 : :
141 : : DBG_ENTER("COLL")
142 : :
143 : : !Starting the routine
144 : 0 : call timab(1300,1,tsec)
145 : :
146 : : !Some checks
147 : : !Only wfoptalg==10 for now
148 [ # # ]: 0 : if (wfoptalg/=10) then
149 : 0 : ABI_ERROR("cgwf_cprj is implemented for wfoptalg==10 only")
150 : : end if
151 : :
152 : : !======================================================================
153 : : !========= LOCAL VARIABLES DEFINITIONS AND ALLOCATIONS ================
154 : : !======================================================================
155 : :
156 : : !MPI data
157 : 0 : me_g0 = mpi_enreg%me_g0
158 : :
159 : : ! cprj are already in memory
160 : 0 : cpopt = 2
161 : :
162 : : !Initializations and allocations
163 : 0 : istwf_k=gs_hamk%istwf_k
164 : 0 : wfopta10=mod(wfoptalg,10)
165 : :
166 [ # # ]: 0 : optekin=0;if (wfoptalg>=10) optekin=1
167 : 0 : natom=gs_hamk%natom
168 : 0 : npw=gs_hamk%npw_k
169 : 0 : nspinor=gs_hamk%nspinor
170 : :
171 [ # # # # : 0 : ABI_MALLOC(pcon,(npw))
# # # # #
# # # ]
172 [ # # # # : 0 : ABI_MALLOC(conjgr,(2,npw*nspinor))
# # # # #
# # # #
# ]
173 [ # # # # ]: 0 : ABI_MALLOC(scwavef_dum,(0,0))
174 [ # # # # : 0 : ABI_MALLOC(direc,(2,npw*nspinor))
# # # # #
# ]
175 [ # # # # : 0 : ABI_MALLOC(scprod,(2,nband))
# # # # #
# # # ]
176 [ # # # # : 0 : ABI_MALLOC(scprod_csc,(2*nband))
# # # # #
# # # #
# ]
177 [ # # # # : 0 : ABI_MALLOC(direc_tmp,(2,npw*nspinor))
# # # # ]
178 [ # # # # ]: 0 : ABI_MALLOC(gvnlxc,(0,0))
179 : :
180 [ # # # # : 0 : ABI_MALLOC(cprj_direc ,(natom,nspinor))
# # # # #
# # # # #
# # # # #
# # # ]
181 [ # # # # : 0 : ABI_MALLOC(cprj_conjgr ,(natom,nspinor))
# # # # #
# # # # #
# # # # ]
182 : :
183 : 0 : n4=gs_hamk%ngfft(4);n5=gs_hamk%ngfft(5);n6=gs_hamk%ngfft(6)
184 [ # # # # : 0 : ABI_MALLOC(cwavef_r,(2,n4,n5,n6,nspinor))
# # # # #
# # # # #
# # # # #
# # # #
# ]
185 [ # # # # : 0 : ABI_MALLOC(direc_r, (2,n4,n5,n6,nspinor))
# # # # #
# # # # #
# # # # #
# ]
186 : :
187 : 0 : ncpgr = 0 ! no need of gradients here...
188 : 0 : call pawcprj_alloc(cprj_direc,ncpgr,gs_hamk%dimcprj)
189 : 0 : call pawcprj_alloc(cprj_conjgr,ncpgr,gs_hamk%dimcprj)
190 : :
191 : 0 : cwavef_bands => cg(:,1+icg:nband*npw*nspinor+icg)
192 : :
193 [ # # ]: 0 : if (cprj_update_lvl==-2)then
194 : 0 : call cprj_update(cg,cprj_cwavef_bands,gs_hamk,icg,nband,mpi_enreg,tim_getcprj)
195 : : endif
196 : :
197 : 0 : isubh=1
198 : 0 : isubh0=1
199 : :
200 : : ! Big iband loop
201 [ # # ]: 0 : do iband=1,nband
202 : :
203 : : ! ======================================================================
204 : : ! ========== INITIALISATION OF MINIMIZATION ITERATIONS =================
205 : : ! ======================================================================
206 : :
207 [ # # ]: 0 : if (prtvol>=10) then ! Tell us what is going on:
208 : 0 : write(message, '(a,i6,2x,a,i3,a)' )' --- cgwf is called for band',iband,'for',nline,' lines'
209 : 0 : call wrtout(std_out,message,'PERS')
210 : : end if
211 : :
212 : 0 : dotgp=one
213 : :
214 : : ! Extraction of the vector that is iteratively updated
215 : 0 : cwavef => cwavef_bands(:,1+(iband-1)*npw*nspinor:iband*npw*nspinor)
216 : 0 : cprj_cwavef => cprj_cwavef_bands(:,nspinor*(iband-1)+1:nspinor*iband)
217 : :
218 : : ! Normalize incoming wf:
219 : : call getcsc(dot,cpopt,cwavef,cwavef,cprj_cwavef,cprj_cwavef,&
220 : 0 : & gs_hamk,mpi_enreg,1,tim_getcsc)
221 : 0 : xnorm=one/sqrt(dot(1))
222 [ # # ]: 0 : z_tmp = (/xnorm,zero/)
223 : : ! cwavef = xnorm * cwavef
224 : 0 : call timab(1305,1,tsec)
225 [ # # ]: 0 : call cg_zscal(npw*nspinor,z_tmp,cwavef)
226 : 0 : call timab(1305,2,tsec)
227 : : ! cprj = xnorm * cprj
228 : 0 : call timab(1302,1,tsec)
229 : 0 : call pawcprj_axpby(zero,xnorm,cprj_cwavef,cprj_cwavef)
230 : 0 : call timab(1302,2,tsec)
231 : :
232 : : ! Compute wavefunction in real space
233 : 0 : call get_cwavefr(cwavef,cwavef_r,gs_hamk,mpi_enreg)
234 : :
235 [ # # ]: 0 : if (prtvol==-level) then
236 : 0 : write(message,'(a,f26.14)')' cgwf: xnorm = ',xnorm
237 : 0 : call wrtout(std_out,message,'PERS')
238 : : end if
239 : :
240 : : ! ======================================================================
241 : : ! ====== BEGIN LOOP FOR A GIVEN BAND: MINIMIZATION ITERATIONS ==========
242 : : ! ======================================================================
243 [ # # ]: 0 : if(nline/=0)then
244 [ # # ]: 0 : do iline=1,nline
245 : :
246 : : ! === COMPUTE THE RESIDUAL ===
247 : : ! Compute lambda = <C|H|C>
248 : 0 : sij_opt=0
249 : : call getchc(z_tmp,cpopt,cwavef,cwavef,cprj_cwavef,cprj_cwavef,cwavef_r,cwavef_r,&
250 : 0 : & gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
251 : 0 : chc=z_tmp(1)
252 : 0 : lam0=chc
253 : 0 : eval=chc
254 : 0 : eig(iband)=chc
255 : :
256 : : ! Check that lam0 is decreasing on succeeding lines:
257 [ # # ]: 0 : if (iline==1) then
258 : 0 : lamold=lam0
259 : : else
260 [ # # ]: 0 : if (lam0 > lamold+tol12) then
261 : : write(message, '(a,i8,a,1p,e14.6,a1,3x,a,1p,e14.6,a1)')&
262 : 0 : & 'New trial energy at line ',iline,' = ',lam0,ch10,&
263 : 0 : & 'is higher than former =',lamold,ch10
264 : 0 : ABI_WARNING(message)
265 : : end if
266 : 0 : lamold=lam0
267 : : end if
268 : :
269 : : ! ======================================================================
270 : : ! =========== COMPUTE THE STEEPEST DESCENT DIRECTION ===================
271 : : ! ======================================================================
272 : :
273 : 0 : sij_opt=-1
274 : : call getghc(cpopt,cwavef,cprj_cwavef,direc,scwavef_dum,gs_hamk,gvnlxc,&
275 : 0 : & eval,mpi_enreg,1,prtvol,sij_opt,tim_getghc,type_calc,cwavef_r=cwavef_r)
276 : :
277 : : ! Compute residual (squared) norm
278 : 0 : call timab(1305,1,tsec)
279 : 0 : call sqnorm_g(resid(iband),istwf_k,npw*nspinor,direc,me_g0,mpi_enreg%comm_fft)
280 : 0 : call timab(1305,2,tsec)
281 : :
282 [ # # ]: 0 : if (prtvol==-level) then
283 : 0 : write(message,'(a,i0,f26.14,es27.14e3)')' cgwf: iline,eval,resid = ',iline,eval,resid(iband)
284 : 0 : call wrtout(std_out,message,'PERS')
285 : : end if
286 : 0 : xnormd=1/sqrt(resid(iband))
287 [ # # ]: 0 : z_tmp = (/xnormd,zero/)
288 : 0 : call cg_zscal(npw*nspinor,z_tmp,direc)
289 : :
290 : : ! ======================================================================
291 : : ! ============== CHECK FOR CONVERGENCE CRITERIA ========================
292 : : ! ======================================================================
293 : :
294 : : ! If residual sufficiently small stop line minimizations
295 [ # # ]: 0 : if (resid(iband)<tolwfr) then
296 [ # # ]: 0 : if (prtvol>=10) then
297 : : write(message, '(a,i4,a,i2,a,es12.4)' ) &
298 : 0 : & ' cgwf: band ',iband,' converged after ',iline,' line minimizations: resid =',resid(iband)
299 : 0 : call wrtout(std_out,message,'PERS')
300 : : end if
301 : 0 : nskip=nskip+(nline-iline+1) ! Number of two-way 3D ffts skipped
302 : 0 : exit ! Exit from the loop on iline
303 : : end if
304 : :
305 : : ! If user require exiting the job, stop line minimisations
306 [ # # ]: 0 : if (quit==1) then
307 : 0 : write(message, '(a,i0)' )' cgwf: user require exiting => skip update of band ',iband
308 : 0 : call wrtout(std_out,message,'PERS')
309 : :
310 : 0 : nskip=nskip+(nline-iline+1) ! Number of two-way 3D ffts skipped
311 : 0 : exit ! Exit from the loop on iline
312 : : end if
313 : :
314 : : ! =========== PROJECT THE STEEPEST DESCENT DIRECTION ===================
315 : : ! ========= OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS ================
316 : :
317 : : ! The following projection over the subspace orthogonal to occupied bands
318 : : ! is optional. It is a bit more accurate, but doubles the number of N^3 ops.
319 : : ! It is done only if ortalg>=0.
320 : :
321 : : ! Project the steepest descent direction:
322 : : ! direc(2,npw)=<G|H|Cnk> - \sum_{(i/=n)} <G|H|Cik>
323 [ # # ]: 0 : if(ortalg>=0)then
324 : 0 : call cprj_update_oneband(direc,cprj_direc,gs_hamk,mpi_enreg,tim_getcprj)
325 : : call getcsc(scprod_csc,cpopt,direc,cwavef_bands,cprj_direc,cprj_cwavef_bands,&
326 : 0 : & gs_hamk,mpi_enreg,nband,tim_getcsc)
327 [ # # # # : 0 : scprod = reshape(scprod_csc,(/2,nband/))
# # # # ]
328 : : ! Note that the current band (|C_iband>) is not used here
329 : : call projbd(cg,direc,iband,icg,icg,istwf_k,mcg,mcg,nband,npw,nspinor,&
330 : 0 : & direc,scprod,1,tim_projbd,useoverlap,me_g0,mpi_enreg%comm_fft)
331 : : end if
332 : :
333 : : ! For a generalized eigenpb, store the steepest descent direction
334 [ # # # # : 0 : direc_tmp=direc
# # # # #
# # # # #
# # ]
335 : :
336 : : ! ======================================================================
337 : : ! ======== PRECONDITION THE STEEPEST DESCENT DIRECTION =================
338 : : ! ======================================================================
339 : :
340 : : ! If wfoptalg>=10, the precondition matrix is kept constant during iteration ; otherwise it is recomputed
341 : 0 : call timab(1305,1,tsec)
342 [ # # # # ]: 0 : if (wfoptalg<10.or.iline==1) then
343 [ # # ]: 0 : call cg_precon(cwavef,zero,istwf_k,gs_hamk%kinpw_k,npw,nspinor,me_g0,optekin,pcon,direc,mpi_enreg%comm_fft)
344 : : else
345 [ # # ]: 0 : do ispinor=1,nspinor
346 : 0 : igs=(ispinor-1)*npw
347 : : !$OMP PARALLEL DO
348 [ # # ]: 0 : do ipw=1+igs,npw+igs
349 : 0 : direc(1,ipw)=direc(1,ipw)*pcon(ipw-igs)
350 : 0 : direc(2,ipw)=direc(2,ipw)*pcon(ipw-igs)
351 : : end do
352 : : end do
353 : : end if
354 : 0 : call timab(1305,2,tsec)
355 : :
356 : : ! ======= PROJECT THE PRECOND. STEEPEST DESCENT DIRECTION ==============
357 : : ! ========= OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS ================
358 : 0 : call cprj_update_oneband(direc,cprj_direc,gs_hamk,mpi_enreg,tim_getcprj)
359 : : call getcsc(scprod_csc,cpopt,direc,cwavef_bands,cprj_direc,cprj_cwavef_bands,&
360 : 0 : & gs_hamk,mpi_enreg,nband,tim_getcsc)
361 : : ! if (abs(xnorm-one)>tol10) then ! True if iline==1 and if input WFs are random
362 [ # # ]: 0 : if (iline==1) then
363 : : ! We compensate the normalization of the current band
364 [ # # ]: 0 : scprod_csc(2*iband-1:2*iband) = scprod_csc(2*iband-1:2*iband)/xnorm
365 : : end if
366 : : ! Projecting again out all bands (not normalized).
367 [ # # # # : 0 : scprod = reshape(scprod_csc,(/2,nband/))
# # # # ]
368 : : call projbd(cg,direc,-1,icg,icg,istwf_k,mcg,mcg,nband,npw,nspinor,&
369 : 0 : & direc,scprod,1,tim_projbd,useoverlap,me_g0,mpi_enreg%comm_fft)
370 [ # # ]: 0 : if (iline==1) then
371 : : ! Again we have to compensate the normalization of the current band.
372 : : ! Indeed, by calling projbd we compute:
373 : : ! |direc'_i> = |direc_i> - \sum_j <c'_j|S|direc_i>|c'_j>
374 : : ! = |direc_i> - \sum_{j/=i} <c_j|S|direc_i>|c_j> - <c'_i|S|direc_i>|c'_i>
375 : : ! where |c'_j> = |c_j> for j/=i and |c'_i> = xnorm.|c_i>
376 : : ! As we compensated "scprod" before the call of projbd we actually computed:
377 : : ! |direc'_i> = |direc_i> - \sum_{j/=i} <c_j|S|direc_i>|c_j> - <c_i|S|direc_i>|c'_i>
378 : : ! = |direc_i> - \sum_{j/=i} <c_j|S|direc_i>|c_j> - xnorm.<c_i|S|direc_i>|c_i>
379 : : ! The correct projected direction should be:
380 : : ! |projdirec_i> = |direc_i> - \sum_j <c_j|S|direc_i>|c_j>
381 : : ! = |direc_i> - \sum_{j/=i} <c_j|S|direc_i>|c_j> - <c_i|S|direc_i>|c_i>
382 : : ! So:
383 : : ! |projdirec_i> = |direc'_i> - <c_i|S|direc_i>|c_i> + xnorm.<c_i|S|direc_i>|c_i>
384 : : ! = |direc'_i> - (1-xnorm) <c_i|S|direc_i>|c_i>
385 : : ! = |direc'_i> - (1-xnorm)/xnorm <c_i|S|direc_i>|c'_i>
386 : : !
387 [ # # ]: 0 : z_tmp = -scprod_csc(2*iband-1:2*iband)*(one-xnorm)/xnorm
388 : 0 : call timab(1305,1,tsec)
389 [ # # ]: 0 : do ispinor=1,nspinor
390 : 0 : igs=(ispinor-1)*npw
391 [ # # ]: 0 : do ipw=1+igs,npw+igs
392 : 0 : direc(1,ipw)=direc(1,ipw) + z_tmp(1)*cwavef(1,ipw) - z_tmp(2)*cwavef(2,ipw)
393 : 0 : direc(2,ipw)=direc(2,ipw) + z_tmp(1)*cwavef(2,ipw) + z_tmp(2)*cwavef(1,ipw)
394 : : end do
395 : : end do
396 : 0 : call timab(1305,2,tsec)
397 : : end if
398 : : ! Apply projbd to cprj_direc
399 [ # # # # ]: 0 : scprod=-scprod
400 : 0 : call timab(1303,1,tsec)
401 : 0 : call pawcprj_projbd(scprod,cprj_cwavef_bands,cprj_direc)
402 : 0 : call timab(1303,2,tsec)
403 [ # # ]: 0 : if (iline==1) then
404 : : ! Same correction than for WFs
405 [ # # ]: 0 : z_tmp = -scprod_csc(2*iband-1:2*iband)*(one-xnorm)/xnorm
406 : 0 : z_tmp2 = (/one,zero/)
407 : : ! cprj = z_tmp*cprjx + z_tmp2*cprj
408 : 0 : call timab(1302,1,tsec)
409 : 0 : call pawcprj_zaxpby(z_tmp,z_tmp2,cprj_cwavef,cprj_direc)
410 : 0 : call timab(1302,2,tsec)
411 : : end if
412 : :
413 : : ! ======================================================================
414 : : ! ================= COMPUTE THE CONJUGATE-GRADIENT =====================
415 : : ! ======================================================================
416 : :
417 : 0 : call timab(1305,1,tsec)
418 : 0 : call dotprod_g(dotgg,doti,istwf_k,npw*nspinor,1,direc,direc_tmp,me_g0,mpi_enreg%comm_spinorfft)
419 : 0 : call timab(1305,2,tsec)
420 : :
421 : 0 : dotgg=dotgg/xnormd**2
422 : :
423 : : ! MJV: added 5 Feb 2012 - causes divide by 0 on next iteration of iline
424 [ # # ]: 0 : if (abs(dotgg) < TINY(0.0_dp)*1.e50_dp) dotgg = TINY(0.0_dp)*1.e50_dp
425 : :
426 : : ! At first iteration, gamma is set to zero
427 [ # # ]: 0 : if (iline==1) then
428 : 0 : gamma=zero
429 : 0 : dotgp=dotgg
430 : 0 : call timab(1305,1,tsec)
431 : 0 : call cg_zcopy(npw*nspinor,direc,conjgr)
432 : 0 : call timab(1305,2,tsec)
433 : 0 : call timab(1302,1,tsec)
434 : 0 : call pawcprj_copy(cprj_direc,cprj_conjgr)
435 : 0 : call timab(1302,2,tsec)
436 [ # # ]: 0 : if (prtvol==-level)then
437 : 0 : write(message,'(a,es27.14e3)')' cgwf: dotgg = ',dotgg
438 : 0 : call wrtout(std_out,message,'PERS')
439 : : end if
440 : : else
441 : 0 : gamma=dotgg/dotgp
442 : 0 : dotgp=dotgg
443 : :
444 [ # # ]: 0 : if (prtvol==-level)then
445 : 0 : write(message,'(a,2es27.14e3)')' cgwf: dotgg,gamma = ',dotgg,gamma
446 : 0 : call wrtout(std_out,message,'PERS')
447 : : end if
448 : :
449 : 0 : gamma=gamma*xnormd/xnormd_previous
450 : :
451 : 0 : call timab(1305,1,tsec)
452 : : !$OMP PARALLEL DO
453 [ # # ]: 0 : do ipw=1,npw*nspinor
454 : 0 : conjgr(1,ipw)=direc(1,ipw)+gamma*conjgr(1,ipw)
455 : 0 : conjgr(2,ipw)=direc(2,ipw)+gamma*conjgr(2,ipw)
456 : : end do
457 : 0 : call timab(1305,2,tsec)
458 : 0 : call timab(1302,1,tsec)
459 : 0 : call pawcprj_axpby(one,gamma,cprj_direc,cprj_conjgr)
460 : 0 : call timab(1302,2,tsec)
461 : : end if
462 : 0 : call timab(1305,1,tsec)
463 : :
464 : 0 : xnormd_previous=xnormd
465 : :
466 : : call getcsc(dot,cpopt,conjgr,conjgr,cprj_conjgr,cprj_conjgr,&
467 : 0 : & gs_hamk,mpi_enreg,1,tim_getcsc)
468 : :
469 : : ! ======================================================================
470 : : ! ============ PROJECTION OF THE CONJUGATED GRADIENT ===================
471 : : ! ======================================================================
472 : :
473 : : call getcsc(dot,cpopt,conjgr,cwavef,cprj_conjgr,cprj_cwavef,&
474 : 0 : & gs_hamk,mpi_enreg,1,tim_getcsc)
475 : 0 : dotr=dot(1)
476 : 0 : doti=dot(2)
477 : :
478 : : ! Project the conjugated gradient onto the current band
479 : 0 : call timab(1305,1,tsec)
480 [ # # ]: 0 : if(istwf_k==1)then
481 : :
482 : : !$OMP PARALLEL DO
483 [ # # ]: 0 : do ipw=1,npw*nspinor
484 : 0 : direc(1,ipw)=conjgr(1,ipw)-(dotr*cwavef(1,ipw)-doti*cwavef(2,ipw))
485 : 0 : direc(2,ipw)=conjgr(2,ipw)-(dotr*cwavef(2,ipw)+doti*cwavef(1,ipw))
486 : : end do
487 : : else
488 : : !$OMP PARALLEL DO
489 [ # # ]: 0 : do ipw=1,npw*nspinor
490 : 0 : direc(1,ipw)=conjgr(1,ipw)-dotr*cwavef(1,ipw)
491 : 0 : direc(2,ipw)=conjgr(2,ipw)-dotr*cwavef(2,ipw)
492 : : end do
493 : : end if
494 : 0 : call timab(1305,2,tsec)
495 : 0 : call timab(1302,1,tsec)
496 : 0 : call pawcprj_copy(cprj_conjgr,cprj_direc)
497 [ # # ]: 0 : z_tmp = (/-dotr,-doti/)
498 : 0 : z_tmp2 = (/one,zero/)
499 : 0 : call pawcprj_zaxpby(z_tmp,z_tmp2,cprj_cwavef,cprj_direc)
500 : 0 : call timab(1302,2,tsec)
501 : :
502 : : ! ======================================================================
503 : : ! ===== COMPUTE CONTRIBUTIONS TO 1ST AND 2ND DERIVATIVES OF ENERGY =====
504 : : ! ======================================================================
505 : :
506 : : ! Compute norm of direc
507 : : call getcsc(dot,cpopt,direc,direc,cprj_direc,cprj_direc,&
508 : 0 : & gs_hamk,mpi_enreg,1,tim_getcsc)
509 : 0 : xnormd=one/sqrt(abs(dot(1)))
510 : :
511 : 0 : sij_opt=0
512 : : ! Compute direc in real space
513 : 0 : call get_cwavefr(direc,direc_r,gs_hamk,mpi_enreg)
514 : : ! Compute dhc = Re{<D|H|C>}
515 : : call getchc(z_tmp,cpopt,cwavef,direc,cprj_cwavef,cprj_direc,cwavef_r,direc_r,&
516 : 0 : & gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
517 : 0 : dhc=z_tmp(1)
518 : 0 : dhc=dhc*xnormd
519 : :
520 : : ! Compute <D|H|D> or <D|(H-zshift)^2|D>
521 : : call getchc(z_tmp,cpopt,direc,direc,cprj_direc,cprj_direc,direc_r,direc_r,&
522 : 0 : & gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
523 : 0 : dhd=z_tmp(1)
524 : 0 : dhd=dhd*xnormd**2
525 : :
526 [ # # ]: 0 : if (prtvol==-level) then
527 : 0 : write(message,'(a,3f26.14)') 'cgwf: chc,dhc,dhd=',chc,dhc,dhd
528 : 0 : call wrtout(std_out,message,'PERS')
529 : : end if
530 : :
531 : : ! ======================================================================
532 : : ! ======= COMPUTE MIXING FACTORS - CHECK FOR CONVERGENCE ===============
533 : : ! ======================================================================
534 : :
535 : : ! Compute tan(2 theta),sin(theta) and cos(theta)
536 : 0 : tan2th=2.0_dp*dhc/(chc-dhd)
537 : :
538 [ # # ]: 0 : if (abs(tan2th)<1.d-05) then
539 : 0 : costh=1.0_dp-0.125_dp*tan2th**2
540 : 0 : sinth=0.5_dp*tan2th*(1.0_dp-0.375_dp*tan2th**2)
541 : :
542 : : ! Check that result is above machine precision
543 [ # # ]: 0 : if (abs(sinth)<epsilon(0._dp)) then
544 : 0 : write(message, '(a,es16.4)' ) ' cgwf: converged with tan2th=',tan2th
545 : 0 : call wrtout(std_out,message,'PERS')
546 : : ! Number of one-way 3D ffts skipped
547 : 0 : nskip=nskip+2*(nline-iline)
548 : 0 : exit ! Exit from the loop on iline
549 : : end if
550 : :
551 : : else
552 : 0 : root=sqrt(1.0_dp+tan2th**2)
553 : 0 : costh=sqrt(0.5_dp+0.5_dp/root)
554 : 0 : sinth=sign(sqrt(0.5_dp-0.5_dp/root),tan2th)
555 : : end if
556 : :
557 : : ! Check for lower of two possible roots (same sign as curvature at theta where slope is zero)
558 : 0 : diff=(chc-dhd)
559 : : ! Swap c and d if value of diff is positive
560 [ # # ]: 0 : if (diff>zero) then
561 : 0 : swap=costh
562 : 0 : costh=-sinth
563 : 0 : sinth=swap
564 [ # # ]: 0 : if(prtvol<0 .or. prtvol>=10)then
565 : 0 : write(message,*)' Note: swap roots, iline,diff=',iline,diff
566 : 0 : call wrtout(std_out,message,'PERS')
567 : : end if
568 : : end if
569 : :
570 : : ! ============================================================
571 : : ! =========== GENERATE NEW wf(G), wf(r) and cprj =============
572 : : ! ============================================================
573 : :
574 : 0 : sintn=sinth*xnormd
575 : :
576 : 0 : call timab(1305,1,tsec)
577 : : !$OMP PARALLEL DO
578 [ # # ]: 0 : do ipw=1,npw*nspinor
579 : 0 : cwavef(1,ipw)=cwavef(1,ipw)*costh+direc(1,ipw)*sintn
580 : 0 : cwavef(2,ipw)=cwavef(2,ipw)*costh+direc(2,ipw)*sintn
581 : : end do
582 [ # # ]: 0 : do ispinor=1,nspinor
583 [ # # ]: 0 : do i3=1,gs_hamk%n6
584 [ # # ]: 0 : do i2=1,gs_hamk%n5
585 [ # # ]: 0 : do i1=1,gs_hamk%n4
586 : 0 : cwavef_r(1,i1,i2,i3,ispinor)=cwavef_r(1,i1,i2,i3,ispinor)*costh+direc_r(1,i1,i2,i3,ispinor)*sintn
587 : 0 : cwavef_r(2,i1,i2,i3,ispinor)=cwavef_r(2,i1,i2,i3,ispinor)*costh+direc_r(2,i1,i2,i3,ispinor)*sintn
588 : : end do
589 : : end do
590 : : end do
591 : : end do
592 : 0 : call timab(1305,2,tsec)
593 [ # # ]: 0 : if (cprj_update_lvl<0) then
594 : 0 : call cprj_update_oneband(cwavef,cprj_cwavef,gs_hamk,mpi_enreg,tim_getcprj)
595 : : else
596 : 0 : call timab(1302,1,tsec)
597 : 0 : call pawcprj_axpby(sintn,costh,cprj_direc,cprj_cwavef)
598 : 0 : call timab(1302,2,tsec)
599 : : end if
600 : :
601 : : ! ======================================================================
602 : : ! =========== CHECK CONVERGENCE AGAINST TRIAL ENERGY ===================
603 : : ! ======================================================================
604 : :
605 : : ! Compute delta(E)
606 : 0 : deltae=chc*(costh**2-1._dp)+dhd*sinth**2+2._dp*costh*sinth*dhc
607 : :
608 : : ! Check convergence and eventually exit
609 [ # # ]: 0 : if (iline==1) then
610 : 0 : deold=deltae
611 [ # # # # : 0 : else if (abs(deltae)<tolrde*abs(deold) .and. iline/=nline .and. wfopta10<2)then
# # ]
612 [ # # ]: 0 : if(prtvol>=10)then
613 : : write(message, '(a,i4,1x,a,1p,e12.4,a,e12.4,a)' ) &
614 : 0 : & ' cgwf: line',iline,&
615 : 0 : & ' deltae=',deltae,' < tolrde*',deold,' =>skip lines'
616 : 0 : call wrtout(std_out,message,'PERS')
617 : : end if
618 : : ! Update chc before exit
619 : : call getchc(z_tmp,cpopt,cwavef,cwavef,cprj_cwavef,cprj_cwavef,cwavef_r,cwavef_r,&
620 : 0 : & gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
621 : 0 : eig(iband)=z_tmp(1)
622 : 0 : nskip=nskip+2*(nline-iline) ! Number of one-way 3D ffts skipped
623 : 0 : exit ! Exit from the loop on iline
624 : : end if
625 : :
626 : : ! Update chc only if last iteration, otherwise it will be done at the beginning of the next one
627 [ # # ]: 0 : if (iline==nline) then
628 : : call getchc(z_tmp,cpopt,cwavef,cwavef,cprj_cwavef,cprj_cwavef,cwavef_r,cwavef_r,&
629 : 0 : & gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
630 : 0 : eig(iband)=z_tmp(1)
631 : : end if
632 : :
633 : : end do ! END LOOP FOR A GIVEN BAND Note that there are three "exit" instructions inside
634 : :
635 : : else ! nline==0 , needs to provide a residual
636 : 0 : resid(iband)=-one
637 : : end if ! End nline==0 case
638 : :
639 : : ! ======================================================================
640 : : ! =============== END OF CURRENT BAND: CLEANING ========================
641 : : ! ======================================================================
642 : :
643 : : ! At the end of the treatment of a set of bands, write the number of one-way 3D ffts skipped
644 : : if (xmpi_paral==0 .and. mpi_enreg%paral_kgb==0 .and. iband==nband .and. prtvol/=0) then
645 : : write(message,'(a,i0)')' cgwf: number of one-way 3D ffts skipped in cgwf until now =',nskip
646 : : call wrtout(std_out,message,'PERS')
647 : : end if
648 : :
649 : : ! ======================================================================
650 : : ! ============= COMPUTE HAMILTONIAN IN WFs SUBSPACE ====================
651 : : ! ======================================================================
652 : :
653 [ # # ]: 0 : if (cprj_update_lvl<=2) call cprj_update_oneband(cwavef,cprj_cwavef,gs_hamk,mpi_enreg,tim_getcprj)
654 : :
655 : : ! Compute local+kinetic part
656 : 0 : sij_opt=0
657 : : call getghc(cpopt,cwavef,cprj_cwavef,direc,scwavef_dum,gs_hamk,gvnlxc,&
658 : 0 : & eval,mpi_enreg,1,prtvol,sij_opt,tim_getghc,3,cwavef_r=cwavef_r)
659 : 0 : isubh=isubh0
660 : 0 : call timab(1304,1,tsec)
661 [ # # ]: 0 : do jband=1,iband
662 : 0 : cwavef_left => cwavef_bands(:,1+(jband-1)*npw*nspinor:jband*npw*nspinor)
663 [ # # ]: 0 : call dotprod_g(subham(isubh),subham(isubh+1),istwf_k,npw*nspinor,2,cwavef_left,direc,me_g0,mpi_enreg%comm_spinorfft)
664 : 0 : isubh=isubh+2
665 : : end do
666 : 0 : call timab(1304,2,tsec)
667 : 0 : cprj_cwavef_left => cprj_cwavef_bands(:,1:nspinor*iband)
668 : : ! Add the nonlocal part
669 : : call getchc(subham(isubh0:isubh0+2*iband-1),cpopt,cwavef,cwavef,&
670 : : & cprj_cwavef,cprj_cwavef_left,cwavef_r,cwavef_r,&
671 [ # # # # : 0 : & gs_hamk,zero,mpi_enreg,iband,sij_opt,4)
# # # # #
# ]
672 : 0 : isubh0=isubh
673 : :
674 : : end do ! End big iband loop.
675 : :
676 : : ! ======================================================================
677 : : ! ============= COMPUTE HAMILTONIAN IN WFs SUBSPACE ====================
678 : : ! ======================================================================
679 : :
680 : : ! if (cprj_update_lvl<=2) call cprj_update(cg,cprj_cwavef_bands,gs_hamk,icg,nband,mpi_enreg,tim_getcprj)
681 : : !
682 : : ! sij_opt=0
683 : : !
684 : : ! isubh=1
685 : : ! isubh0=1
686 : : ! do iband=1,nband
687 : : ! cwavef => cwavef_bands(:,1+(iband-1)*npw*nspinor:iband*npw*nspinor)
688 : : ! cprj_cwavef => cprj_cwavef_bands(:,nspinor*(iband-1)+1:nspinor*iband)
689 : : ! ! Compute local+kinetic part
690 : : ! call getghc(cpopt,cwavef,cprj_cwavef,direc,scwavef_dum,gs_hamk,gvnlxc,&
691 : : ! & eval,mpi_enreg,1,prtvol,sij_opt,tim_getghc,3)
692 : : ! isubh=isubh0
693 : : ! call timab(1304,1,tsec)
694 : : ! do jband=1,iband
695 : : ! cwavef_left => cwavef_bands(:,1+(jband-1)*npw*nspinor:jband*npw*nspinor)
696 : : ! call dotprod_g(subham(isubh),subham(isubh+1),istwf_k,npw*nspinor,2,cwavef_left,direc,me_g0,mpi_enreg%comm_spinorfft)
697 : : ! isubh=isubh+2
698 : : ! end do
699 : : ! call timab(1304,2,tsec)
700 : : ! cprj_cwavef_left => cprj_cwavef_bands(:,1:nspinor*iband)
701 : : ! ! Add the nonlocal part
702 : : ! call getchc(subham(isubh0:isubh0+2*iband-1),cpopt,cwavef,cwavef,&
703 : : ! & cprj_cwavef,cprj_cwavef_left,cwavef_r,cwavef_r,&
704 : : ! & gs_hamk,zero,mpi_enreg,iband,sij_opt,4)
705 : : ! isubh0=isubh
706 : : ! end do
707 : :
708 : : ! Debugging ouputs
709 [ # # ]: 0 : if(prtvol==-level)then
710 : 0 : isubh=1
711 [ # # ]: 0 : do iband=1,nband
712 [ # # ]: 0 : do jband=1,iband
713 [ # # ]: 0 : if (jband<=10) then
714 : 0 : write(message,'(i7,2f26.14)')isubh,subham(isubh:isubh+1)
715 : 0 : call wrtout(std_out,message,'PERS')
716 : : end if
717 : 0 : isubh=isubh+2
718 : : end do
719 : : end do
720 : : end if
721 : :
722 : : ! ===================
723 : : ! FINAL DEALLOCATIONS
724 : : ! ===================
725 : :
726 : 0 : nullify(cwavef_left)
727 : 0 : nullify(cwavef_bands)
728 : 0 : nullify(cwavef)
729 : 0 : nullify(cprj_cwavef)
730 : 0 : nullify(cprj_cwavef_left)
731 : 0 : call pawcprj_free(cprj_direc)
732 : 0 : call pawcprj_free(cprj_conjgr)
733 [ # # # # : 0 : ABI_FREE(cprj_direc)
# # # # #
# ]
734 [ # # # # : 0 : ABI_FREE(cprj_conjgr)
# # # # #
# ]
735 [ # # ]: 0 : ABI_FREE(conjgr)
736 [ # # ]: 0 : ABI_FREE(scwavef_dum)
737 [ # # ]: 0 : ABI_FREE(gvnlxc)
738 [ # # ]: 0 : ABI_FREE(direc)
739 [ # # ]: 0 : ABI_FREE(pcon)
740 [ # # ]: 0 : ABI_FREE(scprod)
741 [ # # ]: 0 : ABI_FREE(scprod_csc)
742 : :
743 [ # # ]: 0 : ABI_FREE(direc_tmp)
744 [ # # ]: 0 : ABI_FREE(cwavef_r)
745 [ # # ]: 0 : ABI_FREE(direc_r)
746 : :
747 : : ! Do not delete this line, needed to run with open MP
748 : 0 : write(unit=message,fmt=*) resid(1)
749 : :
750 : 0 : call timab(1300,2,tsec)
751 : :
752 : : DBG_EXIT("COLL")
753 : :
754 [ # # # # : 0 : end subroutine cgwf_cprj
# # # # #
# # # # #
# # # # #
# # # #
# ]
755 : : !!***
756 : :
757 : : !!****f* m_cgwf/mksubovl
758 : : !! NAME
759 : : !! mksubovl
760 : : !!
761 : : !! FUNCTION
762 : : !! Compute the triangular matrix <c_m|S|c_n> for m<=n
763 : : !!
764 : : !! INPUTS
765 : : !! cg(2,mcg)=wavefunction <G|C band,k> coefficients for ALL bands
766 : : !! cprj_cwavef_bands=<p_i|c_n> coefficients for all bands n
767 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
768 : : !! icg=shift to be applied on the location of data in the array cg
769 : : !! nband=number of bands.
770 : : !! mpi_enreg=information about MPI parallelization
771 : : !!
772 : : !! OUTPUT
773 : : !! subovl(nband*(nband+1)) = <c_m|S|c_n> for m<=n
774 : : !!
775 : : !! SIDE EFFECTS
776 : : !!
777 : : !! NOTES
778 : : !!
779 : : !! SOURCE
780 : : !!
781 [ # # # # ]: 0 : subroutine mksubovl(cg,cprj_cwavef_bands,gs_hamk,icg,nband,subovl,mpi_enreg)
782 : : !Arguments ------------------------------------
783 : : integer,intent(in) :: icg,nband
784 : : !arrays
785 : : real(dp),intent(out) :: subovl(nband*(nband+1))
786 : : type(pawcprj_type),intent(in),target :: cprj_cwavef_bands(:,:)
787 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
788 : : type(MPI_type),intent(in) :: mpi_enreg
789 : : real(dp),intent(in),target :: cg(:,:)
790 : :
791 : : !Local variables-------------------------------
792 : : integer,parameter :: tim_getcsc=4
793 : : integer :: cpopt,iband,isubh,nspinor,wfsize
794 : 0 : real(dp),pointer :: cwavef(:,:),cwavef_left(:,:)
795 : 0 : real(dp),pointer :: cwavef_bands(:,:)
796 : 0 : type(pawcprj_type),pointer :: cprj_cwavef(:,:),cprj_cwavef_left(:,:)
797 : :
798 : : ! *********************************************************************
799 : :
800 : 0 : nspinor = gs_hamk%nspinor
801 : 0 : wfsize=gs_hamk%npw_k*nspinor
802 : 0 : cpopt=2
803 : :
804 : 0 : cwavef_bands => cg(:,1+icg:nband*wfsize+icg)
805 : :
806 : 0 : isubh=1
807 [ # # ]: 0 : do iband=1,nband
808 : 0 : cwavef => cwavef_bands(:,1+(iband-1)*wfsize:iband*wfsize)
809 : 0 : cprj_cwavef => cprj_cwavef_bands(:,nspinor*(iband-1)+1:nspinor*iband)
810 : 0 : cwavef_left => cwavef_bands(:,1:iband*wfsize)
811 : 0 : cprj_cwavef_left => cprj_cwavef_bands(:,1:nspinor*iband)
812 : : ! Compute csc matrix
813 : : call getcsc(subovl(isubh:isubh+2*iband-1),cpopt,cwavef,cwavef_left,&
814 : : & cprj_cwavef,cprj_cwavef_left,&
815 : 0 : & gs_hamk,mpi_enreg,iband,tim_getcsc)
816 : 0 : isubh=isubh+2*iband
817 : : end do
818 : :
819 : 0 : end subroutine mksubovl
820 : : !!***
821 : :
822 : : !!****f* m_cgwf/cprj_update
823 : : !! NAME
824 : : !! cprj_update
825 : : !!
826 : : !! FUNCTION
827 : : !! Compute the cprj = <p_i|c_n> from input cg (at fixed k point).
828 : : !!
829 : : !! INPUTS
830 : : !! cg(2,mcg)=wavefunction <G|C band,k> coefficients for ALL bands
831 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
832 : : !! icg=shift to be applied on the location of data in the array cg
833 : : !! nband=number of bands.
834 : : !! mpi_enreg=information about MPI parallelization
835 : : !!
836 : : !! OUTPUT
837 : : !! cprj_cwavef_bands=<p_i|c_n> coefficients for all bands n
838 : : !!
839 : : !! SIDE EFFECTS
840 : : !!
841 : : !! NOTES
842 : : !!
843 : : !! SOURCE
844 : : !!
845 [ # # # # ]: 0 : subroutine cprj_update(cg,cprj_cwavef_bands,gs_hamk,icg,nband,mpi_enreg,tim_getcprj)
846 : :
847 : : !Arguments ------------------------------------
848 : : integer,intent(in) :: icg,nband,tim_getcprj
849 : : !arrays
850 : : type(pawcprj_type),intent(in),target :: cprj_cwavef_bands(:,:)
851 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
852 : : type(MPI_type),intent(in) :: mpi_enreg
853 : : real(dp),intent(inout),target :: cg(:,:)
854 : :
855 : : !Local variables-------------------------------
856 : : integer :: choice,iband,wfsize
857 : : real(dp) :: tsec(2)
858 : 0 : real(dp),pointer :: cwavef(:,:),cwavef_bands(:,:)
859 : 0 : type(pawcprj_type),pointer :: cprj_cwavef(:,:)
860 : :
861 : 0 : wfsize=gs_hamk%npw_k*gs_hamk%nspinor
862 : 0 : cwavef_bands => cg(:,1+icg:nband*wfsize+icg)
863 : :
864 : 0 : choice = 1
865 : 0 : if (cprj_cwavef_bands(1,1)%ncpgr==3) then
866 : 0 : choice = 2
867 : : end if
868 : :
869 [ # # ]: 0 : do iband=1,nband
870 : 0 : cwavef => cwavef_bands(:,1+(iband-1)*wfsize:iband*wfsize)
871 : 0 : cprj_cwavef => cprj_cwavef_bands(:,gs_hamk%nspinor*(iband-1)+1:gs_hamk%nspinor*iband)
872 : :
873 : 0 : call timab(1290+tim_getcprj,1,tsec)
874 : : call getcprj(choice,0,cwavef,cprj_cwavef,&
875 : : & gs_hamk%ffnl_k,0,gs_hamk%indlmn,gs_hamk%istwf_k,gs_hamk%kg_k,gs_hamk%kpg_k,gs_hamk%kpt_k,&
876 : : & gs_hamk%lmnmax,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%natom,gs_hamk%nattyp,&
877 : : & gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
878 [ # # # # : 0 : & gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
# # # # #
# # # #
# ]
879 : 0 : call timab(1290+tim_getcprj,2,tsec)
880 : : end do
881 : :
882 [ # # ]: 0 : end subroutine cprj_update
883 : : !!***
884 : :
885 : : !!****f* m_cgwf/cprj_update_oneband
886 : : !! NAME
887 : : !! cprj_update_oneband
888 : : !!
889 : : !! FUNCTION
890 : : !! Compute the cprj = <p_i|c_n> from input wavefunction (one band only).
891 : : !!
892 : : !! INPUTS
893 : : !! cwavef(2,npw)=a wavefunction <G|C band,k>
894 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
895 : : !! icg=shift to be applied on the location of data in the array cg
896 : : !! mpi_enreg=information about MPI parallelization
897 : : !!
898 : : !! OUTPUT
899 : : !! cprj_cwavef=<p_i|c_n> coefficients of the input WF
900 : : !!
901 : : !! SIDE EFFECTS
902 : : !!
903 : : !! NOTES
904 : : !!
905 : : !! SOURCE
906 : : !!
907 [ # # # # ]: 0 : subroutine cprj_update_oneband(cwavef,cprj_cwavef,gs_hamk,mpi_enreg,tim_getcprj)
908 : :
909 : : !Arguments ------------------------------------
910 : : !arrays
911 : : integer,intent(in) :: tim_getcprj
912 : : real(dp),intent(inout) :: cwavef(:,:)
913 : : type(pawcprj_type),intent(inout) :: cprj_cwavef(:,:)
914 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
915 : : type(MPI_type),intent(in) :: mpi_enreg
916 : :
917 : : !Local variables-------------------------------
918 : : integer :: choice,wfsize
919 : : real(dp) :: tsec(2)
920 : :
921 : 0 : wfsize=gs_hamk%npw_k*gs_hamk%nspinor
922 : :
923 : 0 : choice = 1
924 [ # # ]: 0 : if (cprj_cwavef(1,1)%ncpgr==3) then
925 : 0 : choice = 2
926 : : end if
927 : :
928 : 0 : call timab(1290+tim_getcprj,1,tsec)
929 : : call getcprj(choice,0,cwavef,cprj_cwavef,&
930 : : & gs_hamk%ffnl_k,0,gs_hamk%indlmn,gs_hamk%istwf_k,gs_hamk%kg_k,gs_hamk%kpg_k,gs_hamk%kpt_k,&
931 : : & gs_hamk%lmnmax,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%natom,gs_hamk%nattyp,&
932 : : & gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
933 [ # # # # : 0 : & gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
934 : 0 : call timab(1290+tim_getcprj,2,tsec)
935 : :
936 : 0 : end subroutine cprj_update_oneband
937 : : !!***
938 : :
939 : : !!****f* m_cgwf/cprj_check
940 : : !! NAME
941 : : !! cprj_check
942 : : !!
943 : : !! FUNCTION
944 : : !! Check if the cprj are consistent with the bands contained in cg.
945 : : !! Useful for debugging only.
946 : : !!
947 : : !! INPUTS
948 : : !! cwavef(2,npw)=a wavefunction <G|C band,k>
949 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
950 : : !! icg=shift to be applied on the location of data in the array cg
951 : : !! message=string to specify the context of the test
952 : : !! mpi_enreg=information about MPI parallelization
953 : : !! nband=number of bands.
954 : : !!
955 : : !! OUTPUT
956 : : !!
957 : : !! SIDE EFFECTS
958 : : !!
959 : : !! NOTES
960 : : !!
961 : : !! SOURCE
962 : : !!
963 [ # # # # ]: 0 : subroutine cprj_check(cg,cprj_cwavef_bands,gs_hamk,icg,nband,message,mpi_enreg)
964 : :
965 : : !Arguments ------------------------------------
966 : : integer,intent(in) :: icg,nband
967 : : !arrays
968 : : type(pawcprj_type),intent(in),target :: cprj_cwavef_bands(:,:)
969 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
970 : : type(MPI_type),intent(in) :: mpi_enreg
971 : : real(dp),intent(inout),target :: cg(:,:)
972 : : character(len=*),intent(in) :: message
973 : :
974 : : !Local variables-------------------------------
975 : : integer :: choice,iband,ispinor,ncpgr,wfsize
976 : 0 : real(dp),pointer :: cwavef(:,:),cwavef_bands(:,:)
977 : : integer :: iatom
978 : : real(dp) :: re,ratio
979 : 0 : type(pawcprj_type),allocatable :: cprj_tmp(:,:)
980 : :
981 : 0 : write(std_out,'(a)') ''
982 : 0 : write(std_out,'(2a)') 'cprj_check : ',message
983 : :
984 : 0 : choice = 1
985 : 0 : ncpgr = 0
986 [ # # ]: 0 : if (cprj_cwavef_bands(1,1)%ncpgr==3) then
987 : 0 : choice = 2
988 : 0 : ncpgr = 3
989 : : end if
990 : 0 : write(std_out,'(a,i3)') 'ncpgr : ',ncpgr
991 : :
992 [ # # # # : 0 : ABI_MALLOC(cprj_tmp,(gs_hamk%natom,gs_hamk%nspinor))
# # # # #
# # # # #
# # # # #
# ]
993 : 0 : call pawcprj_alloc(cprj_tmp,ncpgr,gs_hamk%dimcprj)
994 : :
995 : 0 : wfsize=gs_hamk%npw_k*gs_hamk%nspinor
996 : 0 : cwavef_bands => cg(:,1+icg:nband*wfsize+icg)
997 : :
998 [ # # ]: 0 : do iband=1,nband
999 : 0 : cwavef => cwavef_bands(:,1+(iband-1)*wfsize:iband*wfsize)
1000 : : call getcprj(choice,0,cwavef,cprj_tmp,&
1001 : : & gs_hamk%ffnl_k,0,gs_hamk%indlmn,gs_hamk%istwf_k,gs_hamk%kg_k,gs_hamk%kpg_k,gs_hamk%kpt_k,&
1002 : : & gs_hamk%lmnmax,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%natom,gs_hamk%nattyp,&
1003 : : & gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
1004 [ # # # # : 0 : & gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
# # # # #
# # # ]
1005 [ # # ]: 0 : do ispinor=1,gs_hamk%nspinor
1006 [ # # ]: 0 : do iatom=1,gs_hamk%natom
1007 [ # # # # ]: 0 : re = sum(abs(cprj_tmp(iatom,ispinor)%cp-cprj_cwavef_bands(iatom,gs_hamk%nspinor*(iband-1)+ispinor)%cp))
1008 [ # # ]: 0 : if (re>tol6) then
1009 [ # # # # : 0 : ratio = sum(abs(cprj_tmp(iatom,ispinor)%cp))/sum(abs(cprj_cwavef_bands(iatom,gs_hamk%nspinor*(iband-1)+ispinor)%cp))
# # # # ]
1010 : 0 : write(std_out,'(a)') 'cprj_check:'
1011 : 0 : write(std_out,'(a,2i5,2es11.3e3)') 'iband,iatom:',iband,iatom,re,ratio
1012 : 0 : write(std_out,'(a)') ''
1013 : 0 : flush(std_out)
1014 : 0 : ABI_ERROR('dif too large')
1015 : : end if
1016 [ # # ]: 0 : if (ncpgr>0) then
1017 [ # # # # : 0 : re = sum(abs(cprj_tmp(iatom,ispinor)%dcp-cprj_cwavef_bands(iatom,gs_hamk%nspinor*(iband-1)+ispinor)%dcp))
# # ]
1018 [ # # ]: 0 : if (re>tol6) then
1019 : 0 : write(std_out,'(a)') 'cprj_check:'
1020 : 0 : write(std_out,'(a,2i5,es11.3e3)') 'iband,iatom:',iband,iatom,re
1021 : 0 : write(std_out,'(a)') ''
1022 : 0 : flush(std_out)
1023 : 0 : ABI_ERROR('dif too large (dcp)')
1024 : : end if
1025 : : end if
1026 : : end do
1027 : : end do
1028 : : end do
1029 : :
1030 : 0 : write(std_out,'(a)') 'cprj_check : ok'
1031 : 0 : flush(std_out)
1032 : :
1033 : 0 : call pawcprj_free(cprj_tmp)
1034 [ # # # # : 0 : ABI_FREE(cprj_tmp)
# # # # #
# ]
1035 : :
1036 : 0 : end subroutine cprj_check
1037 : : !!***
1038 : :
1039 : : !!****f* m_cgwf/cprj_check_oneband
1040 : : !! NAME
1041 : : !! cprj_check_oneband
1042 : : !!
1043 : : !! FUNCTION
1044 : : !! Check if the input cprj is consistent with the input WF.
1045 : : !! Useful for debugging only.
1046 : : !!
1047 : : !! INPUTS
1048 : : !! cwavef(2,npw)=a wavefunction <G|C band,k>
1049 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
1050 : : !! icg=shift to be applied on the location of data in the array cg
1051 : : !! message=string to specify the context of the test
1052 : : !! mpi_enreg=information about MPI parallelization
1053 : : !!
1054 : : !! OUTPUT
1055 : : !!
1056 : : !! SIDE EFFECTS
1057 : : !!
1058 : : !! NOTES
1059 : : !!
1060 : : !! SOURCE
1061 : : !!
1062 : : subroutine cprj_check_oneband(cwavef,cprj_cwavef,gs_hamk,message,mpi_enreg)
1063 : :
1064 : : !Arguments ------------------------------------
1065 : : !arrays
1066 : : type(pawcprj_type),intent(in),target :: cprj_cwavef(:,:)
1067 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
1068 : : type(MPI_type),intent(in) :: mpi_enreg
1069 : : real(dp),intent(inout) :: cwavef(:,:)
1070 : : character(len=*),intent(in) :: message
1071 : :
1072 : : !Local variables-------------------------------
1073 : : integer :: choice,ncpgr,wfsize
1074 : : integer :: iatom
1075 : : real(dp) :: re
1076 : : type(pawcprj_type),allocatable :: cprj_tmp(:,:)
1077 : :
1078 : : write(std_out,'(a)') ''
1079 : : write(std_out,'(2a)') 'cprj_check (oneband): ',message
1080 : :
1081 : : choice = 1
1082 : : ncpgr = 0
1083 : : if (cprj_cwavef(1,1)%ncpgr==3) then
1084 : : choice = 2
1085 : : ncpgr = 3
1086 : : end if
1087 : : write(std_out,'(a,i3)') 'ncpgr : ',ncpgr
1088 : :
1089 : : ABI_MALLOC(cprj_tmp,(gs_hamk%natom,1))
1090 : : call pawcprj_alloc(cprj_tmp,ncpgr,gs_hamk%dimcprj)
1091 : :
1092 : : wfsize=gs_hamk%npw_k*gs_hamk%nspinor
1093 : :
1094 : : call getcprj(choice,0,cwavef,cprj_tmp,&
1095 : : & gs_hamk%ffnl_k,0,gs_hamk%indlmn,gs_hamk%istwf_k,gs_hamk%kg_k,gs_hamk%kpg_k,gs_hamk%kpt_k,&
1096 : : & gs_hamk%lmnmax,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%natom,gs_hamk%nattyp,&
1097 : : & gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
1098 : : & gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
1099 : : do iatom=1,gs_hamk%natom
1100 : : re = sum(abs(cprj_tmp(iatom,1)%cp-cprj_cwavef(iatom,1)%cp))
1101 : : if (re>tol6) then
1102 : : write(std_out,'(a)') 'cprj_check (oneband):'
1103 : : write(std_out,'(a,i5,es11.3e3)') 'iatom:',iatom,re
1104 : : write(std_out,'(a)') ''
1105 : : flush(std_out)
1106 : : ABI_ERROR('dif too large')
1107 : : end if
1108 : : if (ncpgr>0) then
1109 : : re = sum(abs(cprj_tmp(iatom,1)%dcp-cprj_cwavef(iatom,1)%dcp))
1110 : : if (re>tol6) then
1111 : : write(std_out,'(a)') 'cprj_check (oneband):'
1112 : : write(std_out,'(a,i5,es11.3e3)') 'iatom:',iatom,re
1113 : : write(std_out,'(a)') ''
1114 : : flush(std_out)
1115 : : ABI_ERROR('dif too large (dcp)')
1116 : : end if
1117 : : end if
1118 : : end do
1119 : :
1120 : : write(std_out,'(a)') 'cprj_check : ok'
1121 : : flush(std_out)
1122 : :
1123 : : call pawcprj_free(cprj_tmp)
1124 : : ABI_FREE(cprj_tmp)
1125 : :
1126 : : end subroutine cprj_check_oneband
1127 : : !!***
1128 : :
1129 : : !!****f* m_cgwf/get_cprj_id
1130 : : !! NAME
1131 : : !! get_cprj_id
1132 : : !!
1133 : : !! FUNCTION
1134 : : !! Get an id from cprj array.
1135 : : !! Useful for debugging only.
1136 : : !!
1137 : : !! INPUTS
1138 : : !!
1139 : : !! OUTPUT
1140 : : !!
1141 : : !! SIDE EFFECTS
1142 : : !!
1143 : : !! NOTES
1144 : : !!
1145 : : !! SOURCE
1146 : : !!
1147 [ # # ]: 0 : real(dp) function get_cprj_id(cprj)
1148 : :
1149 : : !Arguments ------------------------------------
1150 : : !arrays
1151 : : type(pawcprj_type),intent(in) :: cprj(:,:)
1152 : :
1153 : : !Local variables-------------------------------
1154 : : integer :: i1,i2
1155 : : real(dp) :: id_tmp
1156 : :
1157 : 0 : id_tmp=zero
1158 [ # # ]: 0 : do i2=1,size(cprj,2)
1159 [ # # ]: 0 : do i1=1,size(cprj,1)
1160 [ # # # # ]: 0 : id_tmp = id_tmp + sum(abs(cprj(i1,i2)%cp))
1161 : : end do
1162 : : end do
1163 : 0 : get_cprj_id=id_tmp
1164 : :
1165 : 0 : end function get_cprj_id
1166 : : !!***
1167 : :
1168 : : !!****f* m_cgwf/get_cwavefr
1169 : : !! NAME
1170 : : !! get_cwavefr
1171 : : !!
1172 : : !! FUNCTION
1173 : : !! Compute the real space wavefunction by FFT of the input WF in reciprocal space.
1174 : : !!
1175 : : !! INPUTS
1176 : : !! cwavef(2,npw)=a wavefunction <G|C band,k>
1177 : : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
1178 : : !! mpi_enreg=information about MPI parallelization
1179 : : !!
1180 : : !! OUTPUT
1181 : : !! cwavef_r(2,n4,n5,n6,nspinor) = real space coefficients of the WF
1182 : : !!
1183 : : !! SIDE EFFECTS
1184 : : !!
1185 : : !! NOTES
1186 : : !!
1187 : : !! SOURCE
1188 : : !!
1189 [ # # # # ]: 0 : subroutine get_cwavefr(cwavef,cwavef_r,gs_hamk,mpi_enreg)
1190 : :
1191 : : !Arguments ------------------------------------
1192 : : !arrays
1193 : : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
1194 : : type(MPI_type),intent(in) :: mpi_enreg
1195 : : real(dp),intent(in),target :: cwavef(:,:)
1196 : : real(dp),intent(out) :: cwavef_r(:,:,:,:,:)
1197 : :
1198 : : !Local variables-------------------------------
1199 : : integer,parameter :: tim_fourwf=40
1200 : : integer :: n4,n5,n6,npw
1201 : : real(dp),parameter :: weight_fft = one
1202 : 0 : real(dp), pointer :: cwavef_fft1(:,:),cwavef_fft2(:,:)
1203 : 0 : real(dp),allocatable :: denpot_dum(:,:,:),fofgout_dum(:,:)
1204 : :
1205 : 0 : n4=gs_hamk%ngfft(4);n5=gs_hamk%ngfft(5);n6=gs_hamk%ngfft(6)
1206 : 0 : npw=gs_hamk%npw_k
1207 : :
1208 : 0 : ABI_MALLOC(denpot_dum, (0,0,0))
1209 [ # # ]: 0 : ABI_MALLOC(fofgout_dum, (0,0))
1210 : :
1211 [ # # ]: 0 : if (gs_hamk%nspinor==1) then
1212 : 0 : cwavef_fft1 => cwavef
1213 : : else
1214 : 0 : cwavef_fft1 => cwavef(:,1:npw)
1215 : 0 : cwavef_fft2 => cwavef(:,1+npw:2*npw)
1216 : : end if
1217 : : call fourwf(0,denpot_dum,cwavef_fft1,fofgout_dum,cwavef_r(:,:,:,:,1),gs_hamk%gbound_k,gs_hamk%gbound_k,gs_hamk%istwf_k,&
1218 : : & gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,gs_hamk%npw_fft_k,gs_hamk%npw_fft_k,&
1219 [ # # # # : 0 : & n4,n5,n6,0,tim_fourwf,weight_fft,weight_fft)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
1220 [ # # ]: 0 : if (gs_hamk%nspinor==2) then
1221 : : call fourwf(0,denpot_dum,cwavef_fft2,fofgout_dum,cwavef_r(:,:,:,:,2),gs_hamk%gbound_k,gs_hamk%gbound_k,gs_hamk%istwf_k,&
1222 : : & gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,gs_hamk%npw_fft_k,gs_hamk%npw_fft_k,&
1223 [ # # # # : 0 : & n4,n5,n6,0,tim_fourwf,weight_fft,weight_fft)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
1224 : : end if
1225 : :
1226 [ # # ]: 0 : ABI_FREE(denpot_dum)
1227 [ # # ]: 0 : ABI_FREE(fofgout_dum)
1228 : :
1229 [ # # ]: 0 : end subroutine get_cwavefr
1230 : : !!***
1231 : :
1232 : : end module m_cgwf_cprj
1233 : : !!***
|