TABLE OF CONTENTS


ABINIT/m_cgwf_cprj [ Modules ]

[ Top ] [ Modules ]

NAME

  m_cgwf_cprj

FUNCTION

  Conjugate-gradient eigensolver.

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (DCA, XG, GMR, MT, MVeithen, ISouza, JIniguez)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

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

m_cgwf/cgwf_cprj [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 cgwf_cprj

FUNCTION

 Update all wavefunction |C>, non self-consistently.
 Uses a conjugate-gradient algorithm.
 This version is available for PAW only, as it needs the cprj in memory.

INPUTS

  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  icg=shift to be applied on the location of data in the array cg
  mcg=second dimension of the cg array
  mpi_enreg=information about MPI parallelization
  nband=number of bands.
  nline=number of line minimizations per band.
  ortalg=governs the choice of the algorithm for orthogonalisation.
  prtvol=control print volume and debugging output
  tolrde=tolerance on the ratio of differences of energies (for the line minimisation)
  tolwfr=tolerance on largest wf residual
  wfoptalg=govern the choice of algorithm for wf optimisation
   (0, 1, 10 and 11 : in the present routine, usual CG algorithm ;

OUTPUT

  resid(nband)=wf residual for new states=|(H-e)|C>|^2 (hartree^2)

SIDE EFFECTS

  cg(2,mcg)
    at input =wavefunction <G|C band,k> coefficients for ALL bands
    at output same as input except that
      the current band, with number 'band' has been updated
  cprj_cwavef_bands=<p_i|c_n> coefficients for all bands n, they are updated when the WFs change.
  quit= if 1, proceeds to smooth ending of the job.

NOTES

SOURCE

 99 subroutine cgwf_cprj(cg,cprj_cwavef_bands,cprj_update_lvl,eig,&
100 &                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  real(dp),allocatable :: conjgr(:,:),gvnlxc(:,:)
130  real(dp), pointer :: cwavef(:,:),cwavef_left(:,:),cwavef_bands(:,:)
131  real(dp), allocatable :: cwavef_r(:,:,:,:,:)
132  real(dp),allocatable,target :: direc(:,:)
133  real(dp),allocatable :: direc_tmp(:,:),pcon(:),scprod(:,:),scwavef_dum(:,:)
134  real(dp),allocatable :: direc_r(:,:,:,:,:),scprod_csc(:)
135  real(dp) :: z_tmp(2),z_tmp2(2)
136  type(pawcprj_type),pointer :: cprj_cwavef(:,:),cprj_cwavef_left(:,:)
137  type(pawcprj_type),allocatable :: cprj_direc(:,:),cprj_conjgr(:,:)
138 
139 ! *********************************************************************
140 
141  DBG_ENTER("COLL")
142 
143 !Starting the routine
144  call timab(1300,1,tsec)
145 
146 !Some checks
147 !Only wfoptalg==10 for now
148  if (wfoptalg/=10) then
149    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  me_g0 = mpi_enreg%me_g0
158 
159 ! cprj are already in memory
160  cpopt = 2
161 
162 !Initializations and allocations
163  istwf_k=gs_hamk%istwf_k
164  wfopta10=mod(wfoptalg,10)
165 
166  optekin=0;if (wfoptalg>=10) optekin=1
167  natom=gs_hamk%natom
168  npw=gs_hamk%npw_k
169  nspinor=gs_hamk%nspinor
170 
171  ABI_MALLOC(pcon,(npw))
172  ABI_MALLOC(conjgr,(2,npw*nspinor))
173  ABI_MALLOC(scwavef_dum,(0,0))
174  ABI_MALLOC(direc,(2,npw*nspinor))
175  ABI_MALLOC(scprod,(2,nband))
176  ABI_MALLOC(scprod_csc,(2*nband))
177  ABI_MALLOC(direc_tmp,(2,npw*nspinor))
178  ABI_MALLOC(gvnlxc,(0,0))
179 
180  ABI_MALLOC(cprj_direc ,(natom,nspinor))
181  ABI_MALLOC(cprj_conjgr ,(natom,nspinor))
182 
183  n4=gs_hamk%ngfft(4);n5=gs_hamk%ngfft(5);n6=gs_hamk%ngfft(6)
184  ABI_MALLOC(cwavef_r,(2,n4,n5,n6,nspinor))
185  ABI_MALLOC(direc_r, (2,n4,n5,n6,nspinor))
186 
187  ncpgr  = 0 ! no need of gradients here...
188  call pawcprj_alloc(cprj_direc,ncpgr,gs_hamk%dimcprj)
189  call pawcprj_alloc(cprj_conjgr,ncpgr,gs_hamk%dimcprj)
190 
191  cwavef_bands => cg(:,1+icg:nband*npw*nspinor+icg)
192 
193  if (cprj_update_lvl==-2)then
194    call cprj_update(cg,cprj_cwavef_bands,gs_hamk,icg,nband,mpi_enreg,tim_getcprj)
195  endif
196 
197  isubh=1
198  isubh0=1
199 
200  ! Big iband loop
201  do iband=1,nband
202 
203    ! ======================================================================
204    ! ========== INITIALISATION OF MINIMIZATION ITERATIONS =================
205    ! ======================================================================
206 
207    if (prtvol>=10) then ! Tell us what is going on:
208      write(message, '(a,i6,2x,a,i3,a)' )' --- cgwf is called for band',iband,'for',nline,' lines'
209      call wrtout(std_out,message,'PERS')
210    end if
211 
212    dotgp=one
213 
214    ! Extraction of the vector that is iteratively updated
215    cwavef => cwavef_bands(:,1+(iband-1)*npw*nspinor:iband*npw*nspinor)
216    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 &   gs_hamk,mpi_enreg,1,tim_getcsc)
221    xnorm=one/sqrt(dot(1))
222    z_tmp = (/xnorm,zero/)
223    ! cwavef = xnorm * cwavef
224    call timab(1305,1,tsec)
225    call cg_zscal(npw*nspinor,z_tmp,cwavef)
226    call timab(1305,2,tsec)
227    ! cprj = xnorm * cprj
228    call timab(1302,1,tsec)
229    call pawcprj_axpby(zero,xnorm,cprj_cwavef,cprj_cwavef)
230    call timab(1302,2,tsec)
231 
232    ! Compute wavefunction in real space
233    call get_cwavefr(cwavef,cwavef_r,gs_hamk,mpi_enreg)
234 
235    if (prtvol==-level) then
236      write(message,'(a,f26.14)')' cgwf: xnorm = ',xnorm
237      call wrtout(std_out,message,'PERS')
238    end if
239 
240    ! ======================================================================
241    ! ====== BEGIN LOOP FOR A GIVEN BAND: MINIMIZATION ITERATIONS ==========
242    ! ======================================================================
243    if(nline/=0)then
244      do iline=1,nline
245 
246        ! === COMPUTE THE RESIDUAL ===
247        ! Compute lambda = <C|H|C>
248        sij_opt=0
249        call getchc(z_tmp,cpopt,cwavef,cwavef,cprj_cwavef,cprj_cwavef,cwavef_r,cwavef_r,&
250          &          gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
251        chc=z_tmp(1)
252        lam0=chc
253        eval=chc
254        eig(iband)=chc
255 
256        ! Check that lam0 is decreasing on succeeding lines:
257        if (iline==1) then
258          lamold=lam0
259        else
260          if (lam0 > lamold+tol12) then
261            write(message, '(a,i8,a,1p,e14.6,a1,3x,a,1p,e14.6,a1)')&
262 &           'New trial energy at line ',iline,' = ',lam0,ch10,&
263 &           'is higher than former =',lamold,ch10
264            ABI_WARNING(message)
265          end if
266          lamold=lam0
267        end if
268 
269        ! ======================================================================
270        ! =========== COMPUTE THE STEEPEST DESCENT DIRECTION ===================
271        ! ======================================================================
272 
273        sij_opt=-1
274        call getghc(cpopt,cwavef,cprj_cwavef,direc,scwavef_dum,gs_hamk,gvnlxc,&
275          &         eval,mpi_enreg,1,prtvol,sij_opt,tim_getghc,type_calc,cwavef_r=cwavef_r)
276 
277        ! Compute residual (squared) norm
278        call timab(1305,1,tsec)
279        call sqnorm_g(resid(iband),istwf_k,npw*nspinor,direc,me_g0,mpi_enreg%comm_fft)
280        call timab(1305,2,tsec)
281 
282        if (prtvol==-level) then
283          write(message,'(a,i0,f26.14,es27.14e3)')' cgwf: iline,eval,resid = ',iline,eval,resid(iband)
284          call wrtout(std_out,message,'PERS')
285        end if
286        xnormd=1/sqrt(resid(iband))
287        z_tmp = (/xnormd,zero/)
288        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        if (resid(iband)<tolwfr) then
296          if (prtvol>=10) then
297            write(message, '(a,i4,a,i2,a,es12.4)' ) &
298 &           ' cgwf: band ',iband,' converged after ',iline,' line minimizations: resid =',resid(iband)
299            call wrtout(std_out,message,'PERS')
300          end if
301          nskip=nskip+(nline-iline+1)  ! Number of two-way 3D ffts skipped
302          exit                         ! Exit from the loop on iline
303        end if
304 
305        ! If user require exiting the job, stop line minimisations
306        if (quit==1) then
307          write(message, '(a,i0)' )' cgwf: user require exiting => skip update of band ',iband
308          call wrtout(std_out,message,'PERS')
309 
310          nskip=nskip+(nline-iline+1)  ! Number of two-way 3D ffts skipped
311          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        if(ortalg>=0)then
324          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 &         gs_hamk,mpi_enreg,nband,tim_getcsc)
327          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 &         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        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        call timab(1305,1,tsec)
342        if (wfoptalg<10.or.iline==1) then
343          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          do ispinor=1,nspinor
346            igs=(ispinor-1)*npw
347 !$OMP PARALLEL DO
348            do ipw=1+igs,npw+igs
349              direc(1,ipw)=direc(1,ipw)*pcon(ipw-igs)
350              direc(2,ipw)=direc(2,ipw)*pcon(ipw-igs)
351            end do
352          end do
353        end if
354        call timab(1305,2,tsec)
355 
356        ! ======= PROJECT THE PRECOND. STEEPEST DESCENT DIRECTION ==============
357        ! ========= OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS ================
358        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 &       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        if (iline==1) then
363          ! We compensate the normalization of the current band
364          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        scprod = reshape(scprod_csc,(/2,nband/))
368        call projbd(cg,direc,-1,icg,icg,istwf_k,mcg,mcg,nband,npw,nspinor,&
369 &       direc,scprod,1,tim_projbd,useoverlap,me_g0,mpi_enreg%comm_fft)
370        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          z_tmp = -scprod_csc(2*iband-1:2*iband)*(one-xnorm)/xnorm
388          call timab(1305,1,tsec)
389          do ispinor=1,nspinor
390            igs=(ispinor-1)*npw
391            do ipw=1+igs,npw+igs
392              direc(1,ipw)=direc(1,ipw) + z_tmp(1)*cwavef(1,ipw) - z_tmp(2)*cwavef(2,ipw)
393              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          call timab(1305,2,tsec)
397        end if
398        ! Apply projbd to cprj_direc
399        scprod=-scprod
400        call timab(1303,1,tsec)
401        call pawcprj_projbd(scprod,cprj_cwavef_bands,cprj_direc)
402        call timab(1303,2,tsec)
403        if (iline==1) then
404          ! Same correction than for WFs
405          z_tmp  = -scprod_csc(2*iband-1:2*iband)*(one-xnorm)/xnorm
406          z_tmp2 = (/one,zero/)
407          ! cprj = z_tmp*cprjx + z_tmp2*cprj
408          call timab(1302,1,tsec)
409          call pawcprj_zaxpby(z_tmp,z_tmp2,cprj_cwavef,cprj_direc)
410          call timab(1302,2,tsec)
411        end if
412 
413        ! ======================================================================
414        ! ================= COMPUTE THE CONJUGATE-GRADIENT =====================
415        ! ======================================================================
416 
417        call timab(1305,1,tsec)
418        call dotprod_g(dotgg,doti,istwf_k,npw*nspinor,1,direc,direc_tmp,me_g0,mpi_enreg%comm_spinorfft)
419        call timab(1305,2,tsec)
420 
421        dotgg=dotgg/xnormd**2
422 
423        ! MJV: added 5 Feb 2012 - causes divide by 0 on next iteration of iline
424        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        if (iline==1) then
428          gamma=zero
429          dotgp=dotgg
430          call timab(1305,1,tsec)
431          call cg_zcopy(npw*nspinor,direc,conjgr)
432          call timab(1305,2,tsec)
433          call timab(1302,1,tsec)
434          call pawcprj_copy(cprj_direc,cprj_conjgr)
435          call timab(1302,2,tsec)
436          if (prtvol==-level)then
437            write(message,'(a,es27.14e3)')' cgwf: dotgg = ',dotgg
438            call wrtout(std_out,message,'PERS')
439          end if
440        else
441          gamma=dotgg/dotgp
442          dotgp=dotgg
443 
444          if (prtvol==-level)then
445            write(message,'(a,2es27.14e3)')' cgwf: dotgg,gamma = ',dotgg,gamma
446            call wrtout(std_out,message,'PERS')
447          end if
448 
449          gamma=gamma*xnormd/xnormd_previous
450 
451          call timab(1305,1,tsec)
452 !$OMP PARALLEL DO
453          do ipw=1,npw*nspinor
454            conjgr(1,ipw)=direc(1,ipw)+gamma*conjgr(1,ipw)
455            conjgr(2,ipw)=direc(2,ipw)+gamma*conjgr(2,ipw)
456          end do
457          call timab(1305,2,tsec)
458          call timab(1302,1,tsec)
459          call pawcprj_axpby(one,gamma,cprj_direc,cprj_conjgr)
460          call timab(1302,2,tsec)
461        end if
462        call timab(1305,1,tsec)
463 
464        xnormd_previous=xnormd
465 
466        call getcsc(dot,cpopt,conjgr,conjgr,cprj_conjgr,cprj_conjgr,&
467 &       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 &       gs_hamk,mpi_enreg,1,tim_getcsc)
475        dotr=dot(1)
476        doti=dot(2)
477 
478        ! Project the conjugated gradient onto the current band
479        call timab(1305,1,tsec)
480        if(istwf_k==1)then
481 
482 !$OMP PARALLEL DO
483          do ipw=1,npw*nspinor
484            direc(1,ipw)=conjgr(1,ipw)-(dotr*cwavef(1,ipw)-doti*cwavef(2,ipw))
485            direc(2,ipw)=conjgr(2,ipw)-(dotr*cwavef(2,ipw)+doti*cwavef(1,ipw))
486          end do
487        else
488 !$OMP PARALLEL DO
489          do ipw=1,npw*nspinor
490            direc(1,ipw)=conjgr(1,ipw)-dotr*cwavef(1,ipw)
491            direc(2,ipw)=conjgr(2,ipw)-dotr*cwavef(2,ipw)
492          end do
493        end if
494        call timab(1305,2,tsec)
495        call timab(1302,1,tsec)
496        call pawcprj_copy(cprj_conjgr,cprj_direc)
497        z_tmp  = (/-dotr,-doti/)
498        z_tmp2 = (/one,zero/)
499        call pawcprj_zaxpby(z_tmp,z_tmp2,cprj_cwavef,cprj_direc)
500        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 &       gs_hamk,mpi_enreg,1,tim_getcsc)
509        xnormd=one/sqrt(abs(dot(1)))
510 
511        sij_opt=0
512        ! Compute direc in real space
513        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          &          gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
517        dhc=z_tmp(1)
518        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 &        gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
523        dhd=z_tmp(1)
524        dhd=dhd*xnormd**2
525 
526        if (prtvol==-level) then
527          write(message,'(a,3f26.14)') 'cgwf: chc,dhc,dhd=',chc,dhc,dhd
528          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        tan2th=2.0_dp*dhc/(chc-dhd)
537 
538        if (abs(tan2th)<1.d-05) then
539          costh=1.0_dp-0.125_dp*tan2th**2
540          sinth=0.5_dp*tan2th*(1.0_dp-0.375_dp*tan2th**2)
541 
542          ! Check that result is above machine precision
543          if (abs(sinth)<epsilon(0._dp)) then
544            write(message, '(a,es16.4)' ) ' cgwf: converged with tan2th=',tan2th
545            call wrtout(std_out,message,'PERS')
546            ! Number of one-way 3D ffts skipped
547            nskip=nskip+2*(nline-iline)
548            exit ! Exit from the loop on iline
549          end if
550 
551        else
552          root=sqrt(1.0_dp+tan2th**2)
553          costh=sqrt(0.5_dp+0.5_dp/root)
554          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        diff=(chc-dhd)
559        ! Swap c and d if value of diff is positive
560        if (diff>zero) then
561          swap=costh
562          costh=-sinth
563          sinth=swap
564          if(prtvol<0 .or. prtvol>=10)then
565            write(message,*)'   Note: swap roots, iline,diff=',iline,diff
566            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        sintn=sinth*xnormd
575 
576        call timab(1305,1,tsec)
577 !$OMP PARALLEL DO
578        do ipw=1,npw*nspinor
579          cwavef(1,ipw)=cwavef(1,ipw)*costh+direc(1,ipw)*sintn
580          cwavef(2,ipw)=cwavef(2,ipw)*costh+direc(2,ipw)*sintn
581        end do
582        do ispinor=1,nspinor
583          do i3=1,gs_hamk%n6
584            do i2=1,gs_hamk%n5
585              do i1=1,gs_hamk%n4
586                cwavef_r(1,i1,i2,i3,ispinor)=cwavef_r(1,i1,i2,i3,ispinor)*costh+direc_r(1,i1,i2,i3,ispinor)*sintn
587                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        call timab(1305,2,tsec)
593        if (cprj_update_lvl<0) then
594          call cprj_update_oneband(cwavef,cprj_cwavef,gs_hamk,mpi_enreg,tim_getcprj)
595        else
596          call timab(1302,1,tsec)
597          call pawcprj_axpby(sintn,costh,cprj_direc,cprj_cwavef)
598          call timab(1302,2,tsec)
599        end if
600 
601        ! ======================================================================
602        ! =========== CHECK CONVERGENCE AGAINST TRIAL ENERGY ===================
603        ! ======================================================================
604 
605        ! Compute delta(E)
606        deltae=chc*(costh**2-1._dp)+dhd*sinth**2+2._dp*costh*sinth*dhc
607 
608 !      Check convergence and eventually exit
609        if (iline==1) then
610          deold=deltae
611        else if (abs(deltae)<tolrde*abs(deold) .and. iline/=nline .and. wfopta10<2)then
612          if(prtvol>=10)then
613            write(message, '(a,i4,1x,a,1p,e12.4,a,e12.4,a)' ) &
614 &           ' cgwf: line',iline,&
615 &           ' deltae=',deltae,' < tolrde*',deold,' =>skip lines'
616            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            &          gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
621          eig(iband)=z_tmp(1)
622          nskip=nskip+2*(nline-iline)  ! Number of one-way 3D ffts skipped
623          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        if (iline==nline) then
628          call getchc(z_tmp,cpopt,cwavef,cwavef,cprj_cwavef,cprj_cwavef,cwavef_r,cwavef_r,&
629            &          gs_hamk,zero,mpi_enreg,1,sij_opt,type_calc)
630          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      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    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    sij_opt=0
657    call getghc(cpopt,cwavef,cprj_cwavef,direc,scwavef_dum,gs_hamk,gvnlxc,&
658      &         eval,mpi_enreg,1,prtvol,sij_opt,tim_getghc,3,cwavef_r=cwavef_r)
659    isubh=isubh0
660    call timab(1304,1,tsec)
661    do jband=1,iband
662      cwavef_left => cwavef_bands(:,1+(jband-1)*npw*nspinor:jband*npw*nspinor)
663      call dotprod_g(subham(isubh),subham(isubh+1),istwf_k,npw*nspinor,2,cwavef_left,direc,me_g0,mpi_enreg%comm_spinorfft)
664      isubh=isubh+2
665    end do
666    call timab(1304,2,tsec)
667    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      &          gs_hamk,zero,mpi_enreg,iband,sij_opt,4)
672    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  if(prtvol==-level)then
710    isubh=1
711    do iband=1,nband
712      do jband=1,iband
713        if (jband<=10) then
714          write(message,'(i7,2f26.14)')isubh,subham(isubh:isubh+1)
715          call wrtout(std_out,message,'PERS')
716        end if
717        isubh=isubh+2
718      end do
719    end do
720  end if
721 
722  ! ===================
723  ! FINAL DEALLOCATIONS
724  ! ===================
725 
726  nullify(cwavef_left)
727  nullify(cwavef_bands)
728  nullify(cwavef)
729  nullify(cprj_cwavef)
730  nullify(cprj_cwavef_left)
731  call pawcprj_free(cprj_direc)
732  call pawcprj_free(cprj_conjgr)
733  ABI_FREE(cprj_direc)
734  ABI_FREE(cprj_conjgr)
735  ABI_FREE(conjgr)
736  ABI_FREE(scwavef_dum)
737  ABI_FREE(gvnlxc)
738  ABI_FREE(direc)
739  ABI_FREE(pcon)
740  ABI_FREE(scprod)
741  ABI_FREE(scprod_csc)
742 
743  ABI_FREE(direc_tmp)
744  ABI_FREE(cwavef_r)
745  ABI_FREE(direc_r)
746 
747 ! Do not delete this line, needed to run with open MP
748  write(unit=message,fmt=*) resid(1)
749 
750  call timab(1300,2,tsec)
751 
752  DBG_EXIT("COLL")
753 
754 end subroutine cgwf_cprj

m_cgwf/cprj_check [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 cprj_check

FUNCTION

   Check if the cprj are consistent with the bands contained in cg.
   Useful for debugging only.

INPUTS

  cwavef(2,npw)=a wavefunction <G|C band,k>
  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  icg=shift to be applied on the location of data in the array cg
  message=string to specify the context of the test
  mpi_enreg=information about MPI parallelization
  nband=number of bands.

OUTPUT

SIDE EFFECTS

NOTES

SOURCE

 963 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  real(dp),pointer :: cwavef(:,:),cwavef_bands(:,:)
 977  integer :: iatom
 978  real(dp) :: re,ratio
 979  type(pawcprj_type),allocatable :: cprj_tmp(:,:)
 980 
 981  write(std_out,'(a)') ''
 982  write(std_out,'(2a)') 'cprj_check : ',message
 983 
 984  choice = 1
 985  ncpgr  = 0
 986  if (cprj_cwavef_bands(1,1)%ncpgr==3) then
 987    choice = 2
 988    ncpgr  = 3
 989  end if
 990  write(std_out,'(a,i3)') 'ncpgr : ',ncpgr
 991 
 992  ABI_MALLOC(cprj_tmp,(gs_hamk%natom,gs_hamk%nspinor))
 993  call pawcprj_alloc(cprj_tmp,ncpgr,gs_hamk%dimcprj)
 994 
 995  wfsize=gs_hamk%npw_k*gs_hamk%nspinor
 996  cwavef_bands => cg(:,1+icg:nband*wfsize+icg)
 997 
 998  do iband=1,nband
 999    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,gs_hamk%natom,gs_hamk%nattyp,&
1003 &    gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
1004 &    gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
1005    do ispinor=1,gs_hamk%nspinor
1006      do iatom=1,gs_hamk%natom
1007        re = sum(abs(cprj_tmp(iatom,ispinor)%cp-cprj_cwavef_bands(iatom,gs_hamk%nspinor*(iband-1)+ispinor)%cp))
1008        if (re>tol6) then
1009          ratio = sum(abs(cprj_tmp(iatom,ispinor)%cp))/sum(abs(cprj_cwavef_bands(iatom,gs_hamk%nspinor*(iband-1)+ispinor)%cp))
1010          write(std_out,'(a)') 'cprj_check:'
1011          write(std_out,'(a,2i5,2es11.3e3)') 'iband,iatom:',iband,iatom,re,ratio
1012          write(std_out,'(a)') ''
1013          flush(std_out)
1014          ABI_ERROR('dif too large')
1015        end if
1016        if (ncpgr>0) then
1017          re = sum(abs(cprj_tmp(iatom,ispinor)%dcp-cprj_cwavef_bands(iatom,gs_hamk%nspinor*(iband-1)+ispinor)%dcp))
1018          if (re>tol6) then
1019            write(std_out,'(a)') 'cprj_check:'
1020            write(std_out,'(a,2i5,es11.3e3)') 'iband,iatom:',iband,iatom,re
1021            write(std_out,'(a)') ''
1022            flush(std_out)
1023            ABI_ERROR('dif too large (dcp)')
1024          end if
1025        end if
1026      end do
1027    end do
1028  end do
1029 
1030  write(std_out,'(a)') 'cprj_check : ok'
1031  flush(std_out)
1032 
1033  call pawcprj_free(cprj_tmp)
1034  ABI_FREE(cprj_tmp)
1035 
1036 end subroutine cprj_check

m_cgwf/cprj_check_oneband [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 cprj_check_oneband

FUNCTION

   Check if the input cprj is consistent with the input WF.
   Useful for debugging only.

INPUTS

  cwavef(2,npw)=a wavefunction <G|C band,k>
  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  icg=shift to be applied on the location of data in the array cg
  message=string to specify the context of the test
  mpi_enreg=information about MPI parallelization

OUTPUT

SIDE EFFECTS

NOTES

SOURCE

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,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

m_cgwf/cprj_update [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 cprj_update

FUNCTION

   Compute the cprj = <p_i|c_n> from input cg (at fixed k point).

INPUTS

  cg(2,mcg)=wavefunction <G|C band,k> coefficients for ALL bands
  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  icg=shift to be applied on the location of data in the array cg
  nband=number of bands.
  mpi_enreg=information about MPI parallelization

OUTPUT

  cprj_cwavef_bands=<p_i|c_n> coefficients for all bands n

SIDE EFFECTS

NOTES

SOURCE

845 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  real(dp),pointer :: cwavef(:,:),cwavef_bands(:,:)
859  type(pawcprj_type),pointer :: cprj_cwavef(:,:)
860 
861  wfsize=gs_hamk%npw_k*gs_hamk%nspinor
862  cwavef_bands => cg(:,1+icg:nband*wfsize+icg)
863 
864  choice = 1
865  if (cprj_cwavef_bands(1,1)%ncpgr==3) then
866    choice = 2
867  end if
868 
869  do iband=1,nband
870    cwavef => cwavef_bands(:,1+(iband-1)*wfsize:iband*wfsize)
871    cprj_cwavef => cprj_cwavef_bands(:,gs_hamk%nspinor*(iband-1)+1:gs_hamk%nspinor*iband)
872 
873    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,gs_hamk%natom,gs_hamk%nattyp,&
877 &    gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
878 &    gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
879    call timab(1290+tim_getcprj,2,tsec)
880  end do
881 
882 end subroutine cprj_update

m_cgwf/cprj_update_oneband [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 cprj_update_oneband

FUNCTION

   Compute the cprj = <p_i|c_n> from input wavefunction (one band only).

INPUTS

  cwavef(2,npw)=a wavefunction <G|C band,k>
  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  icg=shift to be applied on the location of data in the array cg
  mpi_enreg=information about MPI parallelization

OUTPUT

  cprj_cwavef=<p_i|c_n> coefficients of the input WF

SIDE EFFECTS

NOTES

SOURCE

907 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  wfsize=gs_hamk%npw_k*gs_hamk%nspinor
922 
923  choice = 1
924  if (cprj_cwavef(1,1)%ncpgr==3) then
925    choice = 2
926  end if
927 
928  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,gs_hamk%natom,gs_hamk%nattyp,&
932 &  gs_hamk%ngfft,gs_hamk%nloalg,gs_hamk%npw_k,gs_hamk%nspinor,gs_hamk%ntypat,&
933 &  gs_hamk%phkxred,gs_hamk%ph1d,gs_hamk%ph3d_k,gs_hamk%ucvol,gs_hamk%useylm)
934  call timab(1290+tim_getcprj,2,tsec)
935 
936 end subroutine cprj_update_oneband

m_cgwf/get_cprj_id [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 get_cprj_id

FUNCTION

   Get an id from cprj array.
   Useful for debugging only.

INPUTS

OUTPUT

SIDE EFFECTS

NOTES

SOURCE

1147 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  id_tmp=zero
1158  do i2=1,size(cprj,2)
1159    do i1=1,size(cprj,1)
1160      id_tmp = id_tmp + sum(abs(cprj(i1,i2)%cp))
1161    end do
1162  end do
1163  get_cprj_id=id_tmp
1164 
1165 end function get_cprj_id

m_cgwf/get_cwavefr [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 get_cwavefr

FUNCTION

   Compute the real space wavefunction by FFT of the input WF in reciprocal space.

INPUTS

  cwavef(2,npw)=a wavefunction <G|C band,k>
  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  mpi_enreg=information about MPI parallelization

OUTPUT

  cwavef_r(2,n4,n5,n6,nspinor) = real space coefficients of the WF

SIDE EFFECTS

NOTES

SOURCE

1189 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  real(dp), pointer :: cwavef_fft1(:,:),cwavef_fft2(:,:)
1203  real(dp),allocatable :: denpot_dum(:,:,:),fofgout_dum(:,:)
1204 
1205  n4=gs_hamk%ngfft(4);n5=gs_hamk%ngfft(5);n6=gs_hamk%ngfft(6)
1206  npw=gs_hamk%npw_k
1207 
1208  ABI_MALLOC(denpot_dum, (0,0,0))
1209  ABI_MALLOC(fofgout_dum, (0,0))
1210 
1211  if (gs_hamk%nspinor==1) then
1212    cwavef_fft1 => cwavef
1213  else
1214    cwavef_fft1 => cwavef(:,1:npw)
1215    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 &  n4,n5,n6,0,tim_fourwf,weight_fft,weight_fft)
1220  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 &    n4,n5,n6,0,tim_fourwf,weight_fft,weight_fft)
1224  end if
1225 
1226  ABI_FREE(denpot_dum)
1227  ABI_FREE(fofgout_dum)
1228 
1229 end subroutine get_cwavefr

m_cgwf/mksubovl [ Functions ]

[ Top ] [ m_cgwf ] [ Functions ]

NAME

 mksubovl

FUNCTION

   Compute the triangular matrix <c_m|S|c_n> for m<=n

INPUTS

  cg(2,mcg)=wavefunction <G|C band,k> coefficients for ALL bands
  cprj_cwavef_bands=<p_i|c_n> coefficients for all bands n
  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
  icg=shift to be applied on the location of data in the array cg
  nband=number of bands.
  mpi_enreg=information about MPI parallelization

OUTPUT

  subovl(nband*(nband+1)) = <c_m|S|c_n> for m<=n

SIDE EFFECTS

NOTES

SOURCE

781 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  real(dp),pointer :: cwavef(:,:),cwavef_left(:,:)
795  real(dp),pointer :: cwavef_bands(:,:)
796  type(pawcprj_type),pointer :: cprj_cwavef(:,:),cprj_cwavef_left(:,:)
797 
798 ! *********************************************************************
799 
800  nspinor = gs_hamk%nspinor
801  wfsize=gs_hamk%npw_k*nspinor
802  cpopt=2
803 
804  cwavef_bands => cg(:,1+icg:nband*wfsize+icg)
805 
806  isubh=1
807  do iband=1,nband
808    cwavef => cwavef_bands(:,1+(iband-1)*wfsize:iband*wfsize)
809    cprj_cwavef => cprj_cwavef_bands(:,nspinor*(iband-1)+1:nspinor*iband)
810    cwavef_left => cwavef_bands(:,1:iband*wfsize)
811    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      &          gs_hamk,mpi_enreg,iband,tim_getcsc)
816    isubh=isubh+2*iband
817  end do
818 
819 end subroutine mksubovl