LCOV - code coverage report
Current view: top level - src/67_common - m_cgwf_cprj.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 406 0
Test Date: 2026-09-21 13:49:52 Functions: 0.0 % 7 0

            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              : !!***
        

Generated by: LCOV version 2.3-1