LCOV - code coverage report
Current view: top level - src/66_wfs - m_getchc.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 196 0
Test Date: 2026-11-06 11:53:17 Functions: 0.0 % 2 0
Branches: 0.0 % 308 0

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_getchc
       2                 :             : !! NAME
       3                 :             : !!  m_getchc
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! Compute <G|H|C> for input vector |C> expressed in reciprocal space;
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, LSI, MT)
      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_getchc
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_errors
      26                 :             :  use m_abicore
      27                 :             :  use m_xmpi
      28                 :             : 
      29                 :             :  use defs_abitypes, only : mpi_type
      30                 :             :  use m_time,        only : timab
      31                 :             :  use m_pawcprj,     only : pawcprj_type!, pawcprj_alloc, pawcprj_free, pawcprj_getdim
      32                 :             : ! use m_bandfft_kpt, only : bandfft_kpt, bandfft_kpt_get_ikpt
      33                 :             :  use m_hamiltonian, only : gs_hamiltonian_type, KPRIME_H_K, K_H_KPRIME, K_H_K, KPRIME_H_KPRIME
      34                 :             :  use m_nonlop,      only : nonlop
      35                 :             : ! use m_fock,        only : fock_common_type, fock_get_getghc_call
      36                 :             : ! use m_fock_getghc, only : fock_getghc, fock_ACE_getghc
      37                 :             :  use m_cgtools,     only : dotprod_g
      38                 :             : 
      39                 :             :  implicit none
      40                 :             : 
      41                 :             :  private
      42                 :             : !!***
      43                 :             : 
      44                 :             :  public :: getchc
      45                 :             :  public :: getcsc
      46                 :             : !!***
      47                 :             : 
      48                 :             : contains
      49                 :             : !!***
      50                 :             : 
      51                 :             : !!****f* ABINIT/getchc
      52                 :             : !!
      53                 :             : !! NAME
      54                 :             : !! getchc
      55                 :             : !!
      56                 :             : !! FUNCTION
      57                 :             : !! Compute <C_left|H|C> for input vectors |C> and |C_left>.
      58                 :             : !! Note that |C_left> can be an array of "ndat" wavefunctions if only the non-local part is computed
      59                 :             : !!
      60                 :             : !! INPUTS
      61                 :             : !! cpopt=flag defining the status of cwaveprj%cp(:)=<Proj_i|Cnk> scalars (PAW only)
      62                 :             : !!       (same meaning as in nonlop.F90 routine)
      63                 :             : !!       if cpopt=-1, <p_lmn|in> (and derivatives) are computed here (and not saved)
      64                 :             : !!       if cpopt= 0, <p_lmn|in> are computed here and saved
      65                 :             : !!       if cpopt= 1, <p_lmn|in> and first derivatives are computed here and saved
      66                 :             : !!       if cpopt= 2  <p_lmn|in> are already in memory;
      67                 :             : !!       if cpopt= 3  <p_lmn|in> are already in memory; first derivatives are computed here and saved
      68                 :             : !!       if cpopt= 4  <p_lmn|in> and first derivatives are already in memory;
      69                 :             : !! cwavef(2,npw*my_nspinor)=planewave coefficients of wavefunction.
      70                 :             : !! cwavef_left(2,npw*my_nspinor)=planewave coefficients of wavefunction left.
      71                 :             : !! cwaveprj(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors
      72                 :             : !! cwaveprj_left(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors (for left WF)
      73                 :             : !! cwavef_r(2,n4,n5,n6,nspinor) = wave function in real space
      74                 :             : !! cwavef_left_r(2,n4,n5,n6,nspinor) = wave function in real space (for left WF)
      75                 :             : !! gs_ham <type(gs_hamiltonian_type)>=all data for the Hamiltonian to be applied
      76                 :             : !! lambda=factor to be used when computing <G|H-lambda.S|C> - only for sij_opt=-1
      77                 :             : !!        Typically lambda is the eigenvalue (or its guess)
      78                 :             : !! mpi_enreg=information about MPI parallelization
      79                 :             : !! ndat=number of left wavefunctions
      80                 :             : !! sij_opt= -PAW ONLY-  if  0, only matrix elements <G|H|C> have to be computed
      81                 :             : !!    (S=overlap)       if  1, matrix elements <G|S|C> have to be computed in gsc in addition to ghc
      82                 :             : !!                      if -1, matrix elements <G|H-lambda.S|C> have to be computed in ghc (gsc not used)
      83                 :             : !! type_calc= option governing which part of Hamitonian is to be applied:
      84                 :             : !             0: whole Hamiltonian
      85                 :             : !!            1: local part only
      86                 :             : !!            2: non-local+Fock+kinetic only (added to the existing Hamiltonian)
      87                 :             : !!            3: local + kinetic only (added to the existing Hamiltonian)
      88                 :             : !! ===== Optional inputs =====
      89                 :             : !!   [kg_fft_k(3,:)]=optional, (k+G) vector coordinates to be used for the FFT tranformation
      90                 :             : !!                   instead of the one contained in gs_ham datastructure.
      91                 :             : !!                   Typically used for real WF (in parallel) which are FFT-transformed 2 by 2.
      92                 :             : !!   [kg_fft_kp(3,:)]=optional, (k^prime+G) vector coordinates to be used for the FFT tranformation
      93                 :             : !!   [select_k]=optional, option governing the choice of k points to be used.
      94                 :             : !!             gs_ham datastructure contains quantities needed to apply Hamiltonian
      95                 :             : !!             in reciprocal space between 2 kpoints, k and k^prime (equal in most cases);
      96                 :             : !!             if select_k=1, <k^prime|H|k>       is applied [default]
      97                 :             : !!             if select_k=2, <k|H|k^prime>       is applied
      98                 :             : !!             if select_k=3, <k|H|k>             is applied
      99                 :             : !!             if select_k=4, <k^prime|H|k^prime> is applied
     100                 :             : !!
     101                 :             : !! OUTPUT
     102                 :             : !!   chc(2*ndat)=matrix elements <C_left|H|C> (if sij_opt>=0)
     103                 :             : !!                           or <C_left|H-lambda.S|C> (if sij_opt=-1)
     104                 :             : !! SIDE EFFECTS
     105                 :             : !!
     106                 :             : !! SOURCE
     107                 :             : 
     108   [ #  #  #  #  :           0 : subroutine getchc(chc,cpopt,cwavef,cwavef_left,cwaveprj,cwaveprj_left,cwavef_r,cwavef_left_r,&
          #  #  #  #  #  
                #  #  # ]
     109                 :             : &                 gs_ham,lambda,mpi_enreg,ndat,&
     110                 :             : &                 sij_opt,type_calc,&
     111   [ #  #  #  #  :           0 : &                 kg_fft_k,kg_fft_kp,select_k) ! optional arguments
             #  #  #  # ]
     112                 :             : 
     113                 :             : !Arguments ------------------------------------
     114                 :             : !scalars
     115                 :             :  integer,intent(in) :: cpopt,ndat
     116                 :             :  integer,intent(in) :: sij_opt,type_calc
     117                 :             :  integer,intent(in),optional :: select_k
     118                 :             :  real(dp),intent(in) :: lambda
     119                 :             :  real(dp),intent(inout) :: chc(2*ndat)
     120                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     121                 :             :  type(gs_hamiltonian_type),intent(inout),target :: gs_ham
     122                 :             : !arrays
     123                 :             :  integer,intent(in),optional,target :: kg_fft_k(:,:),kg_fft_kp(:,:)
     124                 :             :  real(dp),intent(inout) :: cwavef(:,:),cwavef_left(:,:),cwavef_r(:,:,:,:,:),cwavef_left_r(:,:,:,:,:)
     125                 :             :  type(pawcprj_type),intent(inout),target :: cwaveprj(:,:),cwaveprj_left(:,:)
     126                 :             : 
     127                 :             : !Local variables-------------------------------
     128                 :             : !scalars
     129                 :             :  integer,parameter :: re=1,im=2
     130                 :             :  integer :: choice,cpopt_here,i1,i2,i3,idat,idir
     131                 :             :  integer :: ig,igspinor,ispinor,ispinor_left,my_nspinor
     132                 :             :  integer :: nnlout,nffttot,npw,npw_k1,npw_k2,nspinortot,n1,n2,n3
     133                 :             :  integer :: paw_opt,select_k_,shift1,shift2,signs,tim_nonlop
     134                 :             :  logical :: k1_eq_k2,has_fock
     135                 :             :  logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc
     136                 :             :  character(len=500) :: msg
     137                 :             : !arrays
     138                 :           0 :  integer, pointer :: gbound_k1(:,:),gbound_k2(:,:),kg_k1(:,:),kg_k2(:,:)
     139                 :           0 :  real(dp) :: enlout(ndat),enlout_im(ndat),lambda_ndat(ndat),tsec(2),z_tmp(2)
     140                 :           0 :  real(dp),allocatable :: gsc(:,:),gvnlxc(:,:)
     141                 :           0 :  real(dp), pointer :: kinpw_k1(:),kinpw_k2(:),kpt_k1(:),kpt_k2(:)
     142                 :             : 
     143                 :             : ! *********************************************************************
     144                 :             : 
     145                 :             :  DBG_ENTER("COLL")
     146                 :             : 
     147                 :             : !Keep track of total time spent in getchc:
     148                 :           0 :  call timab(1370,1,tsec)
     149                 :             : 
     150                 :             : !Select k-dependent objects according to select_k input parameter
     151         [ #  # ]:           0 :  select_k_=1;if (present(select_k)) select_k_=select_k
     152         [ #  # ]:           0 :  if (select_k_==KPRIME_H_K) then
     153                 :             : !  <k^prime|H|k>
     154                 :           0 :    npw_k1    =  gs_ham%npw_fft_k ; npw_k2    =  gs_ham%npw_fft_kp
     155                 :           0 :    kpt_k1    => gs_ham%kpt_k     ; kpt_k2    => gs_ham%kpt_kp
     156                 :           0 :    kg_k1     => gs_ham%kg_k      ; kg_k2     => gs_ham%kg_kp
     157                 :           0 :    gbound_k1 => gs_ham%gbound_k  ; gbound_k2 => gs_ham%gbound_kp
     158                 :           0 :    kinpw_k1  => gs_ham%kinpw_k   ; kinpw_k2  => gs_ham%kinpw_kp
     159         [ #  # ]:           0 :  else if (select_k_==K_H_KPRIME) then
     160                 :             : !  <k|H|k^prime>
     161                 :           0 :    npw_k1    =  gs_ham%npw_fft_kp; npw_k2    =  gs_ham%npw_fft_k
     162                 :           0 :    kpt_k1    => gs_ham%kpt_kp    ; kpt_k2    => gs_ham%kpt_k
     163                 :           0 :    kg_k1     => gs_ham%kg_kp     ; kg_k2     => gs_ham%kg_k
     164                 :           0 :    gbound_k1 => gs_ham%gbound_kp ; gbound_k2 => gs_ham%gbound_k
     165                 :           0 :    kinpw_k1  => gs_ham%kinpw_kp  ; kinpw_k2  => gs_ham%kinpw_k
     166         [ #  # ]:           0 :  else if (select_k_==K_H_K) then
     167                 :             : !  <k|H|k>
     168                 :           0 :    npw_k1    =  gs_ham%npw_fft_k ; npw_k2    =  gs_ham%npw_fft_k
     169                 :           0 :    kpt_k1    => gs_ham%kpt_k     ; kpt_k2    => gs_ham%kpt_k
     170                 :           0 :    kg_k1     => gs_ham%kg_k      ; kg_k2     => gs_ham%kg_k
     171                 :           0 :    gbound_k1 => gs_ham%gbound_k  ; gbound_k2 => gs_ham%gbound_k
     172                 :           0 :    kinpw_k1  => gs_ham%kinpw_k   ; kinpw_k2  => gs_ham%kinpw_k
     173         [ #  # ]:           0 :  else if (select_k_==KPRIME_H_KPRIME) then
     174                 :             : !  <k^prime|H|k^prime>
     175                 :           0 :    npw_k1    =  gs_ham%npw_fft_kp; npw_k2    =  gs_ham%npw_fft_kp
     176                 :           0 :    kpt_k1    => gs_ham%kpt_kp    ; kpt_k2    => gs_ham%kpt_kp
     177                 :           0 :    kg_k1     => gs_ham%kg_kp     ; kg_k2     => gs_ham%kg_kp
     178                 :           0 :    gbound_k1 => gs_ham%gbound_kp ; gbound_k2 => gs_ham%gbound_kp
     179                 :           0 :    kinpw_k1  => gs_ham%kinpw_kp  ; kinpw_k2  => gs_ham%kinpw_kp
     180                 :             :  end if
     181   [ #  #  #  # ]:           0 :  k1_eq_k2=(all(abs(kpt_k1(:)-kpt_k2(:))<tol8))
     182         [ #  # ]:           0 :  if (.not.k1_eq_k2) then
     183                 :           0 :    ABI_ERROR('getchc is not implemented yet for k1/=k2')
     184                 :             :  end if
     185                 :             : 
     186                 :             : !Check sizes
     187                 :           0 :  my_nspinor=max(1,gs_ham%nspinor/mpi_enreg%nproc_spinor)
     188   [ #  #  #  # ]:           0 :  if (size(cwavef)<2*npw_k1*my_nspinor) then
     189                 :           0 :    msg='wrong size for cwavef!'
     190                 :           0 :    ABI_BUG(msg)
     191                 :             :  end if
     192   [ #  #  #  # ]:           0 :  if (gs_ham%usepaw==1.and.cpopt>=0) then
     193   [ #  #  #  # ]:           0 :    if (size(cwaveprj)<gs_ham%natom*my_nspinor) then
     194                 :           0 :      msg='wrong size for cwaveprj!'
     195                 :           0 :      ABI_BUG(msg)
     196                 :             :    end if
     197                 :             :  end if
     198         [ #  # ]:           0 :  if (gs_ham%usepaw==1) then
     199   [ #  #  #  # ]:           0 :    if (size(cwaveprj_left)<gs_ham%natom*my_nspinor*ndat) then
     200                 :           0 :      msg='wrong size for cwaveprj_left!'
     201                 :           0 :      ABI_BUG(msg)
     202                 :             :    end if
     203                 :             :  end if
     204                 :             : 
     205                 :             : !Eventually overwrite plane waves data for FFT
     206         [ #  # ]:           0 :  if (present(kg_fft_k)) then
     207                 :           0 :    kg_k1 => kg_fft_k ; kg_k2 => kg_fft_k
     208                 :           0 :    npw_k1=size(kg_k1,2) ; npw_k2=size(kg_k2,2)
     209                 :             :  end if
     210         [ #  # ]:           0 :  if (present(kg_fft_kp)) then
     211                 :           0 :    kg_k2 => kg_fft_kp ; npw_k2=size(kg_k2,2)
     212                 :             :  end if
     213                 :             : 
     214                 :             : !paral_kgb constraint
     215   [ #  #  #  # ]:           0 :  if (mpi_enreg%paral_kgb==1.and.(.not.k1_eq_k2)) then
     216                 :           0 :    msg='paral_kgb=1 not allowed for k/=k_^prime!'
     217                 :           0 :    ABI_BUG(msg)
     218                 :             :  end if
     219                 :             : 
     220                 :             : !Do we add Fock exchange term ?
     221                 :           0 :  has_fock=(associated(gs_ham%fockcommon))
     222         [ #  # ]:           0 :  if (has_fock) then
     223                 :           0 :    ABI_BUG('Fock not implemented yet')
     224                 :             :  end if
     225                 :             : ! if (has_fock) fock => gs_ham%fockcommon
     226                 :             : 
     227                 :             : !Parallelization over spinors management
     228                 :             :  if (mpi_enreg%paral_spinor==0) then
     229                 :             :    shift1=npw_k1;shift2=npw_k2
     230                 :             :    nspinor1TreatedByThisProc=.true.
     231                 :             :    nspinor2TreatedByThisProc=(nspinortot==2)
     232                 :             :  else
     233                 :           0 :    shift1=0;shift2=0
     234                 :           0 :    nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
     235                 :           0 :    nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
     236                 :             :  end if
     237                 :             : 
     238                 :           0 :  npw=gs_ham%npw_k
     239                 :           0 :  nspinortot=gs_ham%nspinor
     240                 :             : 
     241                 :             : !============================================================
     242                 :             : ! Application of the local potential
     243                 :             : !============================================================
     244                 :             : 
     245         [ #  # ]:           0 :  if ((type_calc==0).or.(type_calc==1).or.(type_calc==3)) then
     246                 :             : 
     247                 :           0 :    call timab(1371,1,tsec)
     248                 :             : !  Need a Vlocal
     249         [ #  # ]:           0 :    if (.not.associated(gs_ham%vlocal)) then
     250                 :           0 :      ABI_BUG("We need vlocal in gs_ham!")
     251                 :             :    end if
     252         [ #  # ]:           0 :    if (ndat>1) then
     253                 :           0 :      ABI_ERROR("ndat should be 1 for the local part")
     254                 :             :    end if
     255                 :             : 
     256                 :           0 :    n1=gs_ham%ngfft(1)
     257                 :           0 :    n2=gs_ham%ngfft(2)
     258                 :           0 :    n3=gs_ham%ngfft(3)
     259                 :           0 :    nffttot=n1*n2*n3
     260         [ #  # ]:           0 :    chc = zero
     261                 :             : !  Treat scalar local potentials
     262         [ #  # ]:           0 :    if (gs_ham%nvloc==1) then
     263         [ #  # ]:           0 :      if (gs_ham%istwf_k==2) then
     264         [ #  # ]:           0 :        do i3=1,n3
     265         [ #  # ]:           0 :          do i2=1,n2
     266         [ #  # ]:           0 :            do i1=1,n1
     267                 :           0 :              chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,1)*cwavef_r(1,i1,i2,i3,1)*cwavef_left_r(1,i1,i2,i3,1)
     268                 :             :            end do
     269                 :             :          end do
     270                 :             :        end do
     271                 :           0 :        chc(2)=zero
     272                 :             :      else
     273         [ #  # ]:           0 :        do ispinor=1,my_nspinor
     274         [ #  # ]:           0 :          do i3=1,n3
     275         [ #  # ]:           0 :            do i2=1,n2
     276         [ #  # ]:           0 :              do i1=1,n1
     277                 :             :                z_tmp(1) = cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor) &
     278                 :           0 : &                 +cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor)
     279                 :             :                z_tmp(2) = cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor) &
     280                 :           0 : &                 -cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor)
     281                 :           0 :                chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,1)*z_tmp(1)
     282                 :           0 :                chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,1)*z_tmp(2)
     283                 :             :              end do
     284                 :             :            end do
     285                 :             :          end do
     286                 :             :        end do
     287                 :             :      end if
     288                 :             :    else ! nvloc = 4
     289         [ #  # ]:           0 :      do ispinor=1,my_nspinor
     290         [ #  # ]:           0 :        do ispinor_left=1,my_nspinor
     291         [ #  # ]:           0 :          do i3=1,n3
     292         [ #  # ]:           0 :            do i2=1,n2
     293         [ #  # ]:           0 :              do i1=1,n1
     294                 :             :                z_tmp(1) = cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor_left) &
     295                 :           0 : &                        +cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor_left)
     296                 :             :                z_tmp(2) = cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor_left) &
     297                 :           0 : &                        -cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor_left)
     298         [ #  # ]:           0 :                if (ispinor==ispinor_left) then
     299                 :             :                  ! Then vloc is real : vloc_uu = vloc(1) and vloc_dd = vloc(2)
     300                 :           0 :                  chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,ispinor)*z_tmp(1)
     301                 :           0 :                  chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,ispinor)*z_tmp(2)
     302         [ #  # ]:           0 :                else if (ispinor==1.and.ispinor_left==2) then ! Psi(left)_d^* Psi_u vloc_ud
     303                 :             :                  ! Otherwise vloc is complex Re(vloc_ud) = vloc(3)
     304                 :             :                  !                           Im(vloc_ud) = vloc(4)
     305                 :             :                  !                               vloc_du = (vloc_ud)^*
     306                 :           0 :                  chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) + gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
     307                 :           0 :                  chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) - gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
     308         [ #  # ]:           0 :                else if (ispinor==2.and.ispinor_left==1) then ! Psi(left)_u^* Psi_d vloc_ud
     309                 :           0 :                  chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) - gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
     310                 :           0 :                  chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) + gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
     311                 :             :                end if
     312                 :             :              end do
     313                 :             :            end do
     314                 :             :          end do
     315                 :             :        end do
     316                 :             :      end do
     317                 :             :    end if
     318         [ #  # ]:           0 :    chc = chc / dble(nffttot)
     319                 :             : 
     320                 :           0 :    call timab(1371,2,tsec)
     321                 :             : 
     322                 :             :  end if ! type_calc
     323                 :             : 
     324   [ #  #  #  #  :           0 :  if ((type_calc==0).or.(type_calc==2).or.(type_calc==3).or.(type_calc==4)) then
                   #  # ]
     325                 :             : 
     326                 :             : !============================================================
     327                 :             : ! Application of the non-local potential and the Fock potential
     328                 :             : !============================================================
     329                 :             : 
     330                 :             :   if ((type_calc==0).or.(type_calc==2).or.(type_calc==4)) then
     331                 :             : 
     332                 :           0 :      signs=1 ; choice=1 ; nnlout=1 ; idir=0 ; tim_nonlop=15
     333         [ #  # ]:           0 :      cpopt_here=-1;if (gs_ham%usepaw==1) cpopt_here=cpopt
     334   [ #  #  #  # ]:           0 :      ABI_MALLOC(gvnlxc,(0,0))
     335   [ #  #  #  # ]:           0 :      ABI_MALLOC(gsc,(0,0))
     336                 :             : !     if (has_fock) then
     337                 :             : !       if (gs_ham%usepaw==1) then
     338                 :             : !         cpopt_here=max(cpopt,0)
     339                 :             : !         if (cpopt<2) then
     340                 :             : !           ABI_DATATYPE_ALLOCATE(cwaveprj_fock,(gs_ham%natom,my_nspinor*ndat))
     341                 :             : !           ABI_ALLOCATE(dimcprj,(gs_ham%natom))
     342                 :             : !           call pawcprj_getdim(dimcprj,gs_ham%natom,gs_ham%nattyp,gs_ham%ntypat,&
     343                 :             : !&           gs_ham%typat,fock%pawtab,'O')
     344                 :             : !           call pawcprj_alloc(cwaveprj_fock,0,dimcprj)
     345                 :             : !           ABI_DEALLOCATE(dimcprj)
     346                 :             : !         else
     347                 :             : !           cwaveprj_fock=>cwaveprj
     348                 :             : !         end if
     349                 :             : !         cwaveprj_nonlop=>cwaveprj_fock
     350                 :             : !       else
     351                 :             : !         cwaveprj_nonlop=>cwaveprj
     352                 :             : !         cwaveprj_fock=>cwaveprj
     353                 :             : !       end if
     354                 :             : !     else
     355                 :             : !     end if
     356         [ #  # ]:           0 :      paw_opt=gs_ham%usepaw ; if (sij_opt/=0) paw_opt=sij_opt+3
     357         [ #  # ]:           0 :      lambda_ndat = lambda
     358                 :             : 
     359         [ #  # ]:           0 :      enlout=zero
     360         [ #  # ]:           0 :      enlout_im=zero
     361                 :             :      call nonlop(choice,cpopt_here,cwaveprj,enlout,gs_ham,idir,lambda_ndat,mpi_enreg,1,&
     362                 :             : &     nnlout,paw_opt,signs,gsc,tim_nonlop,cwavef,gvnlxc,select_k=select_k_,&
     363                 :           0 : &     cprjin_left=cwaveprj_left,enlout_im=enlout_im,ndat_left=ndat)
     364                 :             : 
     365         [ #  # ]:           0 :      do idat=1,ndat
     366                 :           0 :        chc(2*idat-1) = chc(2*idat-1) + enlout(idat)
     367                 :           0 :        chc(2*idat  ) = chc(2*idat  ) + enlout_im(idat)
     368                 :             :      end do
     369                 :             : 
     370         [ #  # ]:           0 :      ABI_FREE(gvnlxc)
     371         [ #  # ]:           0 :      ABI_FREE(gsc)
     372                 :             : 
     373                 :             :    end if ! if(type_calc...
     374                 :             : 
     375                 :             : !============================================================
     376                 :             : ! Assemble kinetic, local, nonlocal and Fock contributions
     377                 :             : !============================================================
     378                 :             : 
     379   [ #  #  #  # ]:           0 :    if (type_calc==0.or.type_calc==2.or.type_calc==3) then
     380                 :             : 
     381         [ #  # ]:           0 :      if (ndat>1) then
     382                 :           0 :        ABI_ERROR("ndat should be 1 for the kinetic part")
     383                 :             :      end if
     384                 :             : 
     385                 :           0 :      call timab(1372,1,tsec)
     386                 :             : !    Add modified kinetic contributions
     387                 :             :      !  to <CP|H|C(n,k)>.
     388         [ #  # ]:           0 :      if (gs_ham%istwf_k==1) then
     389                 :             : !      !!$OMP PARALLEL DO PRIVATE(igspinor) COLLAPSE(2)
     390         [ #  # ]:           0 :        do ispinor=1,my_nspinor
     391         [ #  # ]:           0 :          do ig=1,npw_k2
     392                 :           0 :            igspinor=ig+npw_k2*(ispinor-1)
     393         [ #  # ]:           0 :            if (kinpw_k2(ig)<huge(zero)*1.d-11) then
     394                 :           0 :              chc(1) = chc(1) +  kinpw_k2(ig)*cwavef(re,igspinor)*cwavef_left(re,igspinor)
     395                 :           0 :              chc(1) = chc(1) +  kinpw_k2(ig)*cwavef(im,igspinor)*cwavef_left(im,igspinor)
     396                 :           0 :              chc(2) = chc(2) +  kinpw_k2(ig)*cwavef(im,igspinor)*cwavef_left(re,igspinor)
     397                 :           0 :              chc(2) = chc(2) -  kinpw_k2(ig)*cwavef(re,igspinor)*cwavef_left(im,igspinor)
     398                 :             :            end if
     399                 :             :          end do ! ig
     400                 :             :        end do ! ispinor
     401   [ #  #  #  # ]:           0 :      else if (gs_ham%istwf_k==2.and.mpi_enreg%me_g0==1) then
     402         [ #  # ]:           0 :        if (kinpw_k2(1)<huge(zero)*1.d-11) then
     403                 :           0 :          chc(1) = chc(1) + kinpw_k2(1)*cwavef(re,1)*cwavef_left(re,1)
     404                 :             :        end if
     405         [ #  # ]:           0 :        do ig=2,npw_k2
     406         [ #  # ]:           0 :          if (kinpw_k2(ig)<huge(zero)*1.d-11) then
     407                 :           0 :            chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(re,ig)*cwavef_left(re,ig)
     408                 :           0 :            chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(im,ig)*cwavef_left(im,ig)
     409                 :             :          end if
     410                 :             :        end do
     411                 :             :      else
     412         [ #  # ]:           0 :        do ig=1,npw_k2
     413         [ #  # ]:           0 :          if (kinpw_k2(ig)<huge(zero)*1.d-11) then
     414                 :           0 :            chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(re,ig)*cwavef_left(re,ig)
     415                 :           0 :            chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(im,ig)*cwavef_left(im,ig)
     416                 :             :          end if
     417                 :             :        end do ! ig
     418                 :             :      end if
     419                 :             : !    Special case of PAW + Fock : only return Fock operator contribution in gvnlxc
     420                 :             : !     if (gs_ham%usepaw==1 .and. has_fock)then
     421                 :             : !       gvnlxc=gvnlxc-gvnlc
     422                 :             : !       ABI_DEALLOCATE(gvnlc)
     423                 :             : !     endif
     424                 :             : !
     425                 :             : !     if ((type_calc==0).or.(type_calc==2)) then
     426                 :             : !       if (has_fock.and.gs_ham%usepaw==1.and.cpopt<2) then
     427                 :             : !         call pawcprj_free(cwaveprj_fock)
     428                 :             : !         ABI_DATATYPE_DEALLOCATE(cwaveprj_fock)
     429                 :             : !       end if
     430                 :             : !     end if
     431                 :           0 :      call timab(1372,2,tsec)
     432                 :             :    end if
     433                 :             : 
     434                 :             :  end if ! type_calc
     435                 :             : 
     436                 :           0 :  call timab(1370,2,tsec)
     437                 :             : 
     438                 :             :  DBG_EXIT("COLL")
     439                 :             : 
     440   [ #  #  #  # ]:           0 : end subroutine getchc
     441                 :             : !!***
     442                 :             : 
     443                 :             : !----------------------------------------------------------------------
     444                 :             : 
     445                 :             : !!****f* ABINIT/getcsc
     446                 :             : !! NAME
     447                 :             : !! getcsc
     448                 :             : !!
     449                 :             : !! FUNCTION
     450                 :             : !! Compute <C_left|S|C> for input vectors |C> and |C_left>.
     451                 :             : !! Note that |C_left> can be an array of "ndat" wavefunctions
     452                 :             : !!
     453                 :             : !! INPUTS
     454                 :             : !!  cpopt=flag defining the status of cwaveprj%cp(:)=<Proj_i|Cnk> scalars (PAW only)
     455                 :             : !!        (same meaning as in nonlop.F90 routine)
     456                 :             : !!        if cpopt=-1, <p_lmn|in> (and derivatives) are computed here (and not saved)
     457                 :             : !!        if cpopt= 0, <p_lmn|in> are computed here and saved
     458                 :             : !!        if cpopt= 1, <p_lmn|in> and first derivatives are computed here and saved
     459                 :             : !!        if cpopt= 2  <p_lmn|in> are already in memory;
     460                 :             : !!        if cpopt= 3  <p_lmn|in> are already in memory; first derivatives are computed here and saved
     461                 :             : !!        if cpopt= 4  <p_lmn|in> and first derivatives are already in memory;
     462                 :             : !!  cwavef(2,npw*my_nspinor)=planewave coefficients of wavefunction.
     463                 :             : !!  cwavef_left(2,npw*my_nspinor)=planewave coefficients of wavefunction left.
     464                 :             : !!  cprj(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors
     465                 :             : !!  cprj_left(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors (for left WF)
     466                 :             : !!  gs_ham <type(gs_hamiltonian_type)>=all data for the Hamiltonian to be applied
     467                 :             : !!  lambda=factor to be used when computing <G|H-lambda.S|C> - only for sij_opt=-1
     468                 :             : !!         Typically lambda is the eigenvalue (or its guess)
     469                 :             : !!  mpi_enreg=information about MPI parallelization
     470                 :             : !!  ndat=number of left wavefunctions
     471                 :             : !!  mpi_enreg=information about MPI parallelization
     472                 :             : !!
     473                 :             : !! OUTPUT
     474                 :             : !!   csc(2*ndat)=matrix elements <C_left|S|C>
     475                 :             : !!
     476                 :             : !! SOURCE
     477                 :             : 
     478   [ #  #  #  #  :           0 : subroutine getcsc(csc,cpopt,cwavef,cwavef_left,cprj,cprj_left,gs_ham,mpi_enreg,ndat,&
             #  #  #  # ]
     479                 :             : &                 tim_getcsc,&
     480                 :             : &                 select_k) ! optional arguments
     481                 :             : 
     482                 :             : !Arguments ------------------------------------
     483                 :             : !scalars
     484                 :             :  integer,intent(in) :: cpopt,ndat,tim_getcsc
     485                 :             :  integer,intent(in),optional :: select_k
     486                 :             :  real(dp),intent(out) :: csc(2*ndat)
     487                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     488                 :             :  type(gs_hamiltonian_type),intent(inout) :: gs_ham
     489                 :             : !arrays
     490                 :             :  real(dp),intent(inout) :: cwavef(:,:)
     491                 :             :  real(dp),intent(inout),target :: cwavef_left(:,:)
     492                 :             :  type(pawcprj_type),intent(inout) :: cprj(:,:)
     493                 :             :  type(pawcprj_type),intent(inout),target :: cprj_left(:,:)
     494                 :             : 
     495                 :             : !Local variables-------------------------------
     496                 :             : !scalars
     497                 :             :  integer :: choice,idat,idir,istwf_k
     498                 :             :  integer :: npw,nspinor,paw_opt,select_k_,signs,tim_nonlop,nnlout
     499                 :             :  !character(len=500) :: msg
     500                 :             : !arrays
     501                 :           0 :  real(dp) :: tsec(2),real_csc(ndat)
     502                 :           0 :  real(dp),allocatable :: gsc(:,:),gvnlxc(:,:)
     503                 :           0 :  real(dp),allocatable :: enlout(:),enlout_im(:)
     504                 :             : ! real(dp) :: dum
     505                 :             : ! real(dp),pointer :: cwavef_left_idat(:,:)
     506                 :             : ! *********************************************************************
     507                 :             : 
     508                 :             :  DBG_ENTER("COLL")
     509                 :             : 
     510                 :           0 :  call timab(1360+tim_getcsc,1,tsec)
     511                 :             : 
     512                 :           0 :  istwf_k = gs_ham%istwf_k
     513                 :           0 :  npw = gs_ham%npw_k
     514                 :           0 :  nspinor = gs_ham%nspinor
     515                 :             : 
     516         [ #  # ]:           0 :  if (size(cwavef,2)/=npw*nspinor) then
     517                 :           0 :    ABI_BUG('Wrong size for cwavef')
     518                 :             :  end if
     519         [ #  # ]:           0 :  if (size(cwavef_left,2)/=npw*nspinor*ndat) then
     520                 :           0 :    ABI_BUG('Wrong size for cwavef_left')
     521                 :             :  end if
     522                 :             : 
     523                 :           0 :  call timab(1361,1,tsec)
     524         [ #  # ]:           0 :  if (istwf_k==1) then
     525   [ #  #  #  #  :           0 :    call zgemv('C',npw*nspinor,ndat,cone,cwavef_left,npw*nspinor,cwavef,1,czero,csc,1)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     526                 :             :  else ! nspinor==1 in that case
     527   [ #  #  #  #  :           0 :    call dgemv('C',2*npw,ndat,one,cwavef_left,2*npw,cwavef,1,zero,real_csc,1)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     528         [ #  # ]:           0 :    do idat=1,ndat
     529                 :           0 :      csc(2*idat-1) = two*real_csc(idat)
     530                 :           0 :      csc(2*idat  ) = zero
     531                 :             :    end do
     532   [ #  #  #  # ]:           0 :    if (istwf_k==2 .and. mpi_enreg%me_g0==1) then ! Gamma k-point and I have G=0
     533         [ #  # ]:           0 :      do idat=1,ndat
     534                 :           0 :        csc(2*idat-1) = csc(2*idat-1) - cwavef_left(1,1+npw*(idat-1))*cwavef(1,1)
     535                 :             :      end do
     536                 :             :    end if
     537                 :             :  end if
     538                 :           0 :  call timab(1361,2,tsec)
     539                 :             : 
     540                 :             : 
     541         [ #  # ]:           0 :  if (gs_ham%usepaw==1) then
     542                 :             : 
     543         [ #  # ]:           0 :    if (size(cprj,2)/=nspinor) then
     544                 :           0 :       ABI_BUG('Wrong size for cprj')
     545                 :             :    end if
     546         [ #  # ]:           0 :    if (size(cprj_left,2)/=nspinor*ndat) then
     547                 :           0 :       ABI_BUG('Wrong size for cprj_left')
     548                 :             :    end if
     549                 :             : 
     550         [ #  # ]:           0 :    select_k_=1;if (present(select_k)) select_k_=select_k
     551                 :           0 :    choice=1 ; nnlout=1 ; idir=0 ; tim_nonlop=16 ; paw_opt=3
     552   [ #  #  #  # ]:           0 :    ABI_MALLOC(gsc,(0,0))
     553   [ #  #  #  # ]:           0 :    ABI_MALLOC(gvnlxc,(0,0))
     554   [ #  #  #  #  :           0 :    ABI_MALLOC(enlout   ,(ndat))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     555   [ #  #  #  #  :           0 :    ABI_MALLOC(enlout_im,(ndat))
             #  #  #  # ]
     556         [ #  # ]:           0 :    enlout=zero
     557         [ #  # ]:           0 :    enlout_im=zero
     558                 :           0 :    signs=1
     559                 :             :    call nonlop(choice,cpopt,cprj,enlout,gs_ham,idir,(/zero/),mpi_enreg,1,&
     560                 :             : &   nnlout,paw_opt,signs,gsc,tim_nonlop,cwavef,gvnlxc,select_k=select_k_,&
     561                 :           0 : &   cprjin_left=cprj_left,enlout_im=enlout_im,ndat_left=ndat)
     562         [ #  # ]:           0 :    do idat=1,ndat
     563                 :           0 :      csc(2*idat-1) = csc(2*idat-1) + enlout(idat)
     564                 :           0 :      csc(2*idat  ) = csc(2*idat  ) + enlout_im(idat)
     565                 :             :    end do
     566         [ #  # ]:           0 :    ABI_FREE(gsc)
     567         [ #  # ]:           0 :    ABI_FREE(gvnlxc)
     568         [ #  # ]:           0 :    ABI_FREE(enlout   )
     569         [ #  # ]:           0 :    ABI_FREE(enlout_im)
     570                 :             : 
     571                 :             :  end if
     572                 :             : 
     573                 :           0 :  call timab(1360+tim_getcsc,2,tsec)
     574                 :             : 
     575                 :             :  DBG_EXIT("COLL")
     576                 :             : 
     577   [ #  #  #  #  :           0 : end subroutine getcsc
             #  #  #  # ]
     578                 :             : !!***
     579                 :             : 
     580                 :             : end module m_getchc
     581                 :             : !!***
        

Generated by: LCOV version 2.3-1