LCOV - code coverage report
Current view: top level - src/66_wfs - m_getgh2c.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 73.0 % 215 157
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !!****m* ABINIT/m_getgh2c
       2              : !! NAME
       3              : !!  m_getgh2c
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2015-2026 ABINIT group (MT,JLJ)
      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              : ! nvtx related macro definition
      23              : #include "nvtx_macros.h"
      24              : 
      25              : module m_getgh2c
      26              : 
      27              :  use defs_basis
      28              :  use m_abicore
      29              :  use m_errors
      30              : 
      31              :  use defs_abitypes, only : mpi_type
      32              :  use m_pawcprj,     only : pawcprj_type,pawcprj_alloc,pawcprj_free
      33              :  use m_hamiltonian, only : gs_hamiltonian_type,rf_hamiltonian_type
      34              :  use m_nonlop,      only : nonlop
      35              : 
      36              : #if defined(HAVE_GPU_MARKERS)
      37              :  use m_nvtx_data
      38              : #endif
      39              : 
      40              :  implicit none
      41              : 
      42              :  private
      43              : !!***
      44              : 
      45              :  public :: getgh2c
      46              : !!***
      47              : 
      48              : contains
      49              : !!***
      50              : 
      51              : !!****f* ABINIT/getgh2c
      52              : !! NAME
      53              : !! getgh2c
      54              : !!
      55              : !! FUNCTION
      56              : !! Compute <G|H^(2)|C> (or <G|H^(2)-Eps.S^(2)|C>) for input vector |C> expressed in reciprocal space.
      57              : !! (H^(2) is the 2nd-order pertubed Hamiltonian, S^(2) is the 2nd-order perturbed overlap operator).
      58              : !! Result is put in array gh2c.
      59              : !! If required, part of <G|K(2)+Vnonlocal^(2)|C> not depending on VHxc^(2) is also returned in gvnl2.
      60              : !! If required, <G|S^(2)|C> is returned in gs2c (S=overlap - PAW only)
      61              : !! Available for the following cases :
      62              : !!  ipert = natom+10 (dkdk)   :       2nd derivative w.r.t wavevector
      63              : !!          natom+11 (dkdE)   : mixed 2nd derivative w.r.t wavector     and eletric field
      64              : !!  also if natom+12<=ipert<=2*natom+11 :
      65              : !!                   (dtaudE) : mixed 2nd derivative w.r.t atom. displ. and eletric field (nonlocal only)
      66              : !!
      67              : !! INPUTS
      68              : !!  cwavef(2,npw*nspinor)=input wavefunction, in reciprocal space
      69              : !!  cwaveprj(natom,nspinor*usecprj)=<p_lmn|C> coefficients for wavefunction |C>
      70              : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian
      71              : !!  idir=direction of the perturbation
      72              : !!  ipert=type of the perturbation
      73              : !!  lambda=real use to apply H^(2)-lambda.S^(2)
      74              : !!  mpi_enreg=information about MPI parallelization
      75              : !!  optlocal=0: local part of H^(2) is not computed in gh2c=<G|H^(2)|C>
      76              : !!           1: local part of H^(2) is computed in gh2c=<G|H^(2)|C>
      77              : !!  optnl=0: non-local part of H^(2) is not computed in gh2c=<G|H^(2)|C>
      78              : !!        1: non-local part of H^(2) depending on VHxc^(2) is not computed in gh2c=<G|H^(2)|C>
      79              : !!        2: non-local part of H^(2) is totally computed in gh2c=<G|H^(2)|C>
      80              : !!  opt_gvnl2=option controlling the use of gvnl2 array:
      81              : !!            0: not used
      82              : !!            1: used as input:    - used only for PAW and ipert=natom+11/+12
      83              : !!               At input: contains the derivative w.r.t wavevector of cwavef (times i)
      84              : !!  rf_hamkq <type(rf_hamiltonian_type)>=all data for the 2nd-order Hamiltonian at k,k+q
      85              : !!  sij_opt= -PAW ONLY-  if  0, only matrix elements <G|H^(2)|C> have to be computed
      86              : !!     (S=overlap)       if  1, matrix elements <G|S^(2)|C> have to be computed in gs2c in addition to gh2c
      87              : !!                       if -1, matrix elements <G|H^(2)-lambda.S^(2)|C> have to be computed in gh2c (gs2c not used)
      88              : !!  tim_getgh2c=timing code of the calling subroutine (can be set to 0 if not attributed)
      89              : !!  usevnl=1 if gvnl2=(part of <G|K^(2)+Vnl^(2)-lambda.S^(2)|C> not depending on VHxc^(2)) has to be input/output
      90              : !!
      91              : !! OUTPUT
      92              : !! gh2c(2,npw1*nspinor)= <G|H^(2)|C> or  <G|H^(2)-lambda.S^(2)|C>
      93              : !!                     (only kinetic+non-local parts if optlocal=0)
      94              : !! if (usevnl==1)
      95              : !!  gvnl2(2,npw1*nspinor)=  part of <G|K^(2)+Vnl^(2)|C> not depending on VHxc^(2)              (sij_opt/=-1)
      96              : !!                       or part of <G|K^(2)+Vnl^(2)-lambda.S^(2)|C> not depending on VHxc^(2) (sij_opt==-1)
      97              : !! if (sij_opt=1)
      98              : !!  gs2c(2,npw1*nspinor)=<G|S^(2)|C> (S=overlap).
      99              : !!
     100              : !! SOURCE
     101              : 
     102        72096 : subroutine getgh2c(cwavef,cwaveprj,gh2c,gs2c,gs_hamkq,gvnl2,idir,ipert,lambda,&
     103        23040 : &                  mpi_enreg,optlocal,optnl,opt_gvnl2,rf_hamkq,sij_opt,tim_getgh2c,usevnl,conj,enl,optkin)
     104              : 
     105              : !Arguments ------------------------------------
     106              : !scalars
     107              :  logical,intent(in),optional :: conj
     108              :  integer,intent(in) :: idir,ipert,optlocal,optnl,opt_gvnl2,sij_opt,tim_getgh2c,usevnl
     109              :  integer,intent(in),optional :: optkin
     110              :  real(dp),intent(in) :: lambda
     111              :  type(MPI_type),intent(in) :: mpi_enreg
     112              :  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
     113              :  type(rf_hamiltonian_type),intent(inout),target :: rf_hamkq
     114              : !arrays
     115              :  real(dp),intent(in),optional,target :: enl(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,gs_hamkq%dimekbq)
     116              :  real(dp),intent(inout) :: cwavef(:,:)
     117              :  real(dp),intent(inout),target :: gvnl2(:,:)
     118              :  real(dp),intent(out) :: gh2c(:,:),gs2c(:,:)
     119              :  type(pawcprj_type),intent(inout),target :: cwaveprj(:,:)
     120              : 
     121              : !Local variables-------------------------------
     122              : !scalars
     123              :  integer,parameter :: tim_nonlop=0
     124              :  integer :: choice,cpopt,iatm,idir1,idir2,idirc,ipw,ipws,ispinor,my_nspinor
     125              :  integer :: natom,ncpgr,nnlout=1,npw,npw1,paw_opt,signs,usecprj
     126              :  logical :: compute_conjugate,has_kin,has_vnl,pert_phon_elfd
     127              :  real(dp) :: enlout_dum(1)
     128              :  character(len=500) :: msg
     129              : !arrays
     130              : ! integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
     131              :  integer,parameter :: alpha(9)=(/1,2,3,2,1,1,3,3,2/),beta(9)=(/1,2,3,3,3,2,2,1,1/)
     132              : !real(dp) :: tsec(2)
     133              :  real(dp) :: svectout_dum(1,1),vectout_dum(1,1)
     134        72096 :  real(dp),allocatable :: nonlop_out(:,:)
     135        72096 :  real(dp), pointer :: gvnl2_(:,:)
     136        72096 :  real(dp), pointer :: ddkinpw(:),kinpw1(:),enl_ptr(:,:,:,:)
     137        72096 :  real(dp),allocatable,target :: enl_temp(:,:,:,:)
     138        72096 :  type(pawcprj_type),allocatable,target :: cwaveprj_tmp(:,:)
     139        72096 :  type(pawcprj_type),pointer :: cwaveprj_ptr(:,:)
     140              : 
     141              : ! *********************************************************************
     142              : 
     143              :  DBG_ENTER("COLL")
     144              :  ABI_UNUSED(tim_getgh2c)
     145              :  ABI_NVTX_START_RANGE(NVTX_GETGH2C)
     146              : 
     147              : !Keep track of total time spent in getgh2c
     148              : !call timab(196+tim_getgh2c,1,tsec)
     149              : 
     150              : !======================================================================
     151              : !== Initialisations and compatibility tests
     152              : !======================================================================
     153              : 
     154        72096 :  npw  =gs_hamkq%npw_k
     155        72096 :  npw1 =gs_hamkq%npw_kp
     156        72096 :  natom=gs_hamkq%natom
     157              : 
     158              : !Compatibility tests
     159        25920 :  if(ipert/=natom+10.and.ipert/=natom+11.and.ipert>2*natom+11)then
     160            0 :    msg='only ipert==natom+10/+11 and natom+11<=ipert<=2*natom+11 implemented!'
     161            0 :    ABI_BUG(msg)
     162              :  end if
     163        72096 :  pert_phon_elfd = .false.
     164        72096 :  if (ipert>natom+11.and.ipert<=2*natom+11) pert_phon_elfd = .true.
     165        72096 :  if (mpi_enreg%paral_spinor==1) then
     166            0 :    msg='Not compatible with parallelization over spinorial components!'
     167            0 :    ABI_BUG(msg)
     168              :  end if
     169        72096 :  if (gs_hamkq%nvloc>1) then
     170            0 :    msg='Not compatible with nvloc=4 (non-coll. magnetism)!'
     171            0 :    ABI_BUG(msg)
     172              :  end if
     173        72096 :  if((ipert==natom+11.or.pert_phon_elfd).and.gs_hamkq%usepaw==1.and.optnl>=1) then
     174        25920 :    if (gs_hamkq%nvloc>1) then
     175            0 :      msg='Not compatible with nvloc=4 (non-coll. magnetism)!'
     176            0 :      ABI_BUG(msg)
     177              :    end if
     178        25920 :    if (present(enl)) then
     179        23040 :      enl_ptr => enl
     180         2880 :    else if (associated(rf_hamkq%e1kbfr).and.associated(rf_hamkq%e1kbsc).and.optnl==2) then
     181         2880 :      ABI_CHECK(size(rf_hamkq%e1kbfr,4)==1,'BUG in getgh2c: qphase>1!')
     182         2880 :      ABI_CHECK(size(rf_hamkq%e1kbsc,4)==1,'BUG in getgh2c: qphase>1!')
     183        17280 :      ABI_MALLOC(enl_temp,(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,gs_hamkq%dimekbq))
     184       221760 :      enl_temp(:,:,:,:) = rf_hamkq%e1kbfr(:,:,:,:) + rf_hamkq%e1kbsc(:,:,:,:)
     185         2880 :      enl_ptr => enl_temp
     186            0 :    else if (associated(rf_hamkq%e1kbfr)) then
     187            0 :      ABI_CHECK(size(rf_hamkq%e1kbfr,4)==1,'BUG in getgh2c: qphase>1!')
     188            0 :      enl_ptr => rf_hamkq%e1kbfr
     189              :    else
     190            0 :      msg='For ipert=natom+11/pert_phon_elfd : e1kbfr and/or e1kbsc must be associated or enl optional input must be present.'
     191            0 :      ABI_BUG(msg)
     192              :    end if
     193        25920 :    if (usevnl==0) then
     194            0 :      msg='gvnl2 must be allocated for ipert=natom+11/pert_phon_elfd !'
     195            0 :      ABI_BUG(msg)
     196              :    end if
     197        25920 :    if(opt_gvnl2==0) then
     198            0 :      msg='opt_gvnl2=0 not compatible with ipert=natom+11/pert_phon_elfd !'
     199            0 :      ABI_BUG(msg)
     200              :    end if
     201              :  end if
     202              : 
     203              : !Check sizes
     204        72096 :  my_nspinor=max(1,gs_hamkq%nspinor/mpi_enreg%nproc_spinor)
     205       216288 :  if (size(cwavef)<2*npw*my_nspinor) then
     206            0 :    msg='wrong size for cwavef!'
     207            0 :    ABI_BUG(msg)
     208              :  end if
     209       216288 :  if (size(gh2c)<2*npw1*my_nspinor) then
     210            0 :    msg='wrong size for gh2c!'
     211            0 :    ABI_BUG(msg)
     212              :  end if
     213        72096 :  if (usevnl/=0) then
     214        77760 :    if (size(gvnl2)<2*npw1*my_nspinor) then
     215            0 :      msg='wrong size for gvnl2!'
     216            0 :      ABI_BUG(msg)
     217              :    end if
     218              :  end if
     219        72096 :  if (sij_opt==1) then
     220        14400 :    if (size(gs2c)<2*npw1*my_nspinor) then
     221            0 :      msg='wrong size for gs2c!'
     222            0 :      ABI_BUG(msg)
     223              :    end if
     224              :  end if
     225              : 
     226              : !PAW: specific treatment for usecprj input arg
     227              : !     force it to zero if cwaveprj is not allocated
     228        72096 :  usecprj=gs_hamkq%usecprj ; ncpgr=0
     229        72096 :  if(gs_hamkq%usepaw==1) then
     230        83520 :    if (size(cwaveprj)==0) usecprj=0
     231          960 :    if (usecprj/=0) then
     232          960 :      ncpgr=cwaveprj(1,1)%ncpgr
     233         2880 :      if (size(cwaveprj)<gs_hamkq%natom*my_nspinor) then
     234            0 :        msg='wrong size for cwaveprj!'
     235            0 :        ABI_BUG(msg)
     236              :      end if
     237              :    end if
     238              :  else
     239        44256 :    if(usecprj==1)then
     240            0 :      msg='usecprj==1 not allowed for NC psps !'
     241            0 :      ABI_BUG(msg)
     242              :    end if
     243              :  end if
     244              : 
     245              : ! tim_nonlop=8
     246              : ! if (tim_getgh2c==1.and.ipert<=natom) tim_nonlop=7
     247              : ! if (tim_getgh2c==2.and.ipert<=natom) tim_nonlop=5
     248              : ! if (tim_getgh2c==1.and.ipert> natom) tim_nonlop=8
     249              : ! if (tim_getgh2c==2.and.ipert> natom) tim_nonlop=5
     250              : ! if (tim_getgh2c==3                 ) tim_nonlop=0
     251              : 
     252        72096 :  idir1=alpha(idir);idir2=beta(idir)
     253              : 
     254        72096 :  compute_conjugate = .false.
     255        72096 :  if(present(conj)) compute_conjugate = conj
     256              : 
     257              : !======================================================================
     258              : !== Apply the 2nd-order local potential to the wavefunction
     259              : !======================================================================
     260              : 
     261        72096 :  if (ipert/=natom+10.and.ipert/=natom+11.and.optlocal>0) then
     262            0 :    msg='local part not implemented'
     263            0 :    ABI_BUG(msg)
     264              :  else
     265              : !  In the case of ddk operator, no local contribution (also because no self-consistency)
     266              : !$OMP PARALLEL DO
     267      8760796 :    do ipw=1,npw1*my_nspinor
     268     26138196 :      gh2c(:,ipw)=zero
     269              :    end do
     270              : 
     271              :  end if
     272              : 
     273              : !======================================================================
     274              : !== Apply the 2st-order non-local potential to the wavefunction
     275              : !======================================================================
     276              : 
     277        72096 :  has_vnl=(ipert==natom+10.or.ipert==natom+11.or.pert_phon_elfd)
     278              : 
     279              : !Use of gvnl2 depends on usevnl
     280        72096 :  if (usevnl==1) then
     281        25920 :    gvnl2_ => gvnl2
     282              :  else
     283       138528 :    ABI_MALLOC(gvnl2_,(2,npw1*my_nspinor))
     284              :  end if
     285              : 
     286        72096 :  if (has_vnl.and.(optnl>0.or.sij_opt/=0)) then
     287              : 
     288        72096 :    idirc=3*(idir1-1)+idir2 !xx=1, xy=2, xz=3, yx=4, yy=5, yz=6, zx=7, zy=8, zz=9, (xyz,xyz)=(idir1,idir2)
     289              : 
     290              : ! d^2[H_nl]/dk1dk2
     291              : !  -------------------------------------------
     292        72096 :    if (ipert==natom+10) then
     293        46176 :      if (gs_hamkq%usepaw==1) then
     294         1920 :        if (usecprj==1) then
     295          384 :          cwaveprj_ptr => cwaveprj
     296              :        else
     297        10752 :          ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
     298         1536 :          call pawcprj_alloc(cwaveprj_tmp,0,gs_hamkq%dimcprj)
     299         1536 :          cwaveprj_ptr => cwaveprj_tmp
     300              :        end if
     301         1920 :        cpopt=-1+5*usecprj
     302         1920 :        choice=8; signs=2; paw_opt=1; if (sij_opt/=0) paw_opt=sij_opt+3
     303              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idirc,(/lambda/),mpi_enreg,1,nnlout,&
     304         3840 : &       paw_opt,signs,gs2c,tim_nonlop,cwavef,gvnl2_)
     305         1920 :        if (usecprj==0) then
     306         1536 :          call pawcprj_free(cwaveprj_tmp)
     307         4608 :          ABI_FREE(cwaveprj_tmp)
     308              :        end if
     309         1920 :        nullify(cwaveprj_ptr)
     310              :      else
     311        44256 :        choice=8; signs=2; cpopt=-1 ; paw_opt=0
     312              :        call nonlop(choice,cpopt,cwaveprj,enlout_dum,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
     313        44256 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwavef,gvnl2_)
     314              :      end if
     315              : 
     316              : ! d^2[H_nl]/dk1dE2 : Non-zero only in PAW
     317              : !  -------------------------------------------
     318        25920 :    else if (ipert==natom+11.and.gs_hamkq%usepaw==1) then
     319              : 
     320         8640 :      ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
     321              : 
     322         2880 :      if (usecprj==1) then
     323          576 :        cwaveprj_ptr => cwaveprj
     324              :      else
     325        16128 :        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
     326         2304 :        call pawcprj_alloc(cwaveprj_tmp,2,gs_hamkq%dimcprj)
     327         2304 :        cwaveprj_ptr => cwaveprj_tmp
     328              :      end if
     329              : 
     330         2880 :      if (opt_gvnl2==1.and.optnl>=1) then
     331              : 
     332              : !      Compute application of dS/dk1 to i*d[cwavef]/dk2
     333              : !      sum_{i,j} s_ij d(|p_i><p_j|)/dk(idir1) | i*psi^(k(idir2)) >
     334         2880 :        cpopt=-1 ; choice=5 ; paw_opt=3 ; signs=2
     335              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
     336         2880 : &       paw_opt,signs,nonlop_out,tim_nonlop,gvnl2_,vectout_dum)
     337              : 
     338              : !$OMP PARALLEL DO
     339       274320 :        do ipw=1,npw1*my_nspinor
     340       817200 :          gvnl2_(:,ipw)=nonlop_out(:,ipw)
     341              :        end do
     342              : 
     343              : !      Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2)
     344              : !      sum_{i,j} chi_ij(idir2) d(|p_i><p_j|)/dk(idir1) | psi^(0) >
     345         2880 :        cpopt=4*usecprj ; choice=5 ; paw_opt=1 ; signs=2
     346              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
     347         2880 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwavef,nonlop_out,enl=enl_ptr)
     348              : 
     349              : !$OMP PARALLEL DO
     350       274320 :        do ipw=1,npw1*my_nspinor
     351       817200 :          gvnl2_(:,ipw)=gvnl2_(:,ipw)+nonlop_out(:,ipw)
     352              :        end do
     353              : 
     354              :      else
     355              : 
     356              : !$OMP PARALLEL DO
     357            0 :        do ipw=1,npw1*my_nspinor
     358            0 :          gvnl2_(:,ipw)=zero
     359              :        end do
     360              : 
     361              :      end if ! opt_gvnl2==1
     362              : 
     363              : !    Compute derivatives due to projectors |d^2[p_i]/dk1dk2>,|d[p_i]/dk1>,|d[p_i]/dk2>
     364              : !    i * sum_{i,j} (d(|p_i><dp_j/dk(idir2)|)/dk(idir1) | psi^(0) >
     365         2880 :      cpopt=-1+5*usecprj ; choice=81 ; paw_opt=3 ; signs=2
     366              :      call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
     367         2880 : &     paw_opt,signs,nonlop_out,tim_nonlop,cwavef,vectout_dum)
     368              : 
     369         2880 :      if(compute_conjugate) then
     370              : !$OMP PARALLEL DO
     371            0 :        do ipw=1,npw1*my_nspinor ! Note the multiplication by -i
     372            0 :          gvnl2_(1,ipw)=gvnl2_(1,ipw)+nonlop_out(2,ipw)
     373            0 :          gvnl2_(2,ipw)=gvnl2_(2,ipw)-nonlop_out(1,ipw)
     374              :        end do
     375              :      else
     376              : !$OMP PARALLEL DO
     377       274320 :        do ipw=1,npw1*my_nspinor ! Note the multiplication by i
     378       271440 :          gvnl2_(1,ipw)=gvnl2_(1,ipw)-nonlop_out(2,ipw)
     379       274320 :          gvnl2_(2,ipw)=gvnl2_(2,ipw)+nonlop_out(1,ipw)
     380              :        end do
     381              :      end if
     382              : 
     383         2880 :      ABI_FREE(nonlop_out)
     384       820080 :      if (sij_opt==1) gs2c=zero
     385         2880 :      if (usecprj==0) then
     386         2304 :        call pawcprj_free(cwaveprj_tmp)
     387         6912 :        ABI_FREE(cwaveprj_tmp)
     388              :      end if
     389         2880 :      nullify(cwaveprj_ptr)
     390              : 
     391              : ! d^2[H_nl]/dtau1dE2 : Non-zero only in PAW
     392              : !  -------------------------------------------
     393        23040 :    else if (pert_phon_elfd.and.gs_hamkq%usepaw==1) then
     394              : 
     395        23040 :      iatm = ipert-(natom+11)
     396        23040 :      if (iatm<1.or.iatm>natom) then
     397            0 :        ABI_BUG(" iatm must be between 1 and natom")
     398              :      end if
     399              : 
     400        69120 :      ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
     401              : 
     402        23040 :      if (usecprj==1) then
     403            0 :        cwaveprj_ptr => cwaveprj
     404              :      else
     405       161280 :        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
     406        23040 :        call pawcprj_alloc(cwaveprj_tmp,2,gs_hamkq%dimcprj)
     407        23040 :        cwaveprj_ptr => cwaveprj_tmp
     408              :      end if
     409              : 
     410        23040 :      if (opt_gvnl2==1) then
     411              : 
     412              : !      Compute application of dS/dtau1 to i*d[cwavef]/dk2
     413              : !      sum_{i,j} s_ij d(|p_i><p_j|)/dtau(idir1) | i*psi^(k(idir2)) >
     414        23040 :        cpopt=-1 ; choice=2 ; paw_opt=3 ; signs=2
     415              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
     416        23040 : &       paw_opt,signs,nonlop_out,tim_nonlop,gvnl2_,vectout_dum,iatom_only=iatm)
     417              : 
     418              : !$OMP PARALLEL DO
     419      2194560 :        do ipw=1,npw1*my_nspinor
     420      6537600 :          gvnl2_(:,ipw)=nonlop_out(:,ipw)
     421              :        end do
     422              : 
     423              : !      Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2)
     424              : !      sum_{i,j} chi_ij(idir2) d(|p_i><p_j|)/dtau(idir1) | psi^(0) >
     425        23040 :        cpopt=4*usecprj ; choice=2 ; paw_opt=1 ; signs=2
     426              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
     427        23040 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwavef,nonlop_out,enl=enl_ptr,iatom_only=iatm)
     428              : 
     429              : !$OMP PARALLEL DO
     430      2194560 :        do ipw=1,npw1*my_nspinor
     431      6537600 :          gvnl2_(:,ipw)=gvnl2_(:,ipw)+nonlop_out(:,ipw)
     432              :        end do
     433              : 
     434              :      else
     435              : 
     436              : !$OMP PARALLEL DO
     437            0 :        do ipw=1,npw1*my_nspinor
     438            0 :          gvnl2_(:,ipw)=zero
     439              :        end do
     440              : 
     441              :      end if ! opt_gvnl2==1
     442              : 
     443              : !    Compute derivatives due to projectors |d^2[p_i]/dtau1dk2>,|d[p_i]/dtau1>,|d[p_i]/dk2>
     444              : !    i * sum_{i,j} (d(|p_i><dp_j/dk(idir2)|)/dtau(idir1) | psi^(0) >
     445        23040 :      cpopt=-1+5*usecprj ; choice=54 ; paw_opt=3 ; signs=2
     446              :      call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
     447        23040 : &     paw_opt,signs,nonlop_out,tim_nonlop,cwavef,vectout_dum,iatom_only=iatm)
     448              : 
     449        23040 :      if(compute_conjugate) then
     450              : !$OMP PARALLEL DO
     451            0 :        do ipw=1,npw1*my_nspinor ! Note the multiplication by -i
     452            0 :          gvnl2_(1,ipw)=gvnl2_(1,ipw)+nonlop_out(2,ipw)
     453            0 :          gvnl2_(2,ipw)=gvnl2_(2,ipw)-nonlop_out(1,ipw)
     454              :        end do
     455              :      else
     456              : !$OMP PARALLEL DO
     457      2194560 :        do ipw=1,npw1*my_nspinor ! Note the multiplication by i
     458      2171520 :          gvnl2_(1,ipw)=gvnl2_(1,ipw)-nonlop_out(2,ipw)
     459      2194560 :          gvnl2_(2,ipw)=gvnl2_(2,ipw)+nonlop_out(1,ipw)
     460              :        end do
     461              :      end if
     462              : 
     463        23040 :      ABI_FREE(nonlop_out)
     464        23040 :      if (sij_opt==1) gs2c=zero
     465        23040 :      if (usecprj==0) then
     466        23040 :        call pawcprj_free(cwaveprj_tmp)
     467        69120 :        ABI_FREE(cwaveprj_tmp)
     468              :      end if
     469        23040 :      nullify(cwaveprj_ptr)
     470              : 
     471              :    end if
     472              : 
     473              : !No non-local part
     474              : !-------------------------------------------
     475              :  else
     476              : 
     477            0 :    if (optnl>=1) then
     478              :  !$OMP PARALLEL DO
     479            0 :      do ipw=1,npw1*my_nspinor
     480            0 :        gvnl2_(:,ipw)=zero
     481              :      end do
     482              :    end if
     483            0 :    if (sij_opt/=0) then
     484              :  !$OMP PARALLEL DO
     485            0 :      do ipw=1,npw1*my_nspinor
     486            0 :        gs2c(:,ipw)=zero
     487              :      end do
     488              :    end if
     489              : 
     490              :  end if
     491              : 
     492        72096 :  if (associated(enl_ptr)) then
     493        37716 :    nullify(enl_ptr)
     494              :  end if
     495        72096 :  if (allocated(enl_temp)) then
     496         2880 :    ABI_FREE(enl_temp)
     497              :  end if
     498              : 
     499              : !======================================================================
     500              : !== Apply the 2nd-order kinetic operator to the wavefunction
     501              : !======================================================================
     502              : 
     503        72096 :  if (present(optkin)) then
     504         7872 :    has_kin=(optkin/=0.and.ipert==natom+10)
     505              :  else
     506        64224 :    has_kin=(ipert==natom+10)
     507              :  end if
     508              : 
     509              : !k-point perturbation
     510              : !-------------------------------------------
     511        72096 :  if (associated(gs_hamkq%kinpw_kp)) then
     512        72096 :    kinpw1 => gs_hamkq%kinpw_kp
     513            0 :  else if (optnl>=1.or.has_kin) then
     514            0 :    msg='need kinpw1 allocated!'
     515            0 :    ABI_BUG(msg)
     516              :  end if
     517        72096 :  if (associated(rf_hamkq%ddkinpw_k)) then
     518        46176 :    ddkinpw => rf_hamkq%ddkinpw_k
     519        25920 :  else if (has_kin) then
     520            0 :    msg='need ddkinpw allocated!'
     521            0 :    ABI_BUG(msg)
     522              :  end if
     523              : 
     524        46176 :  if (has_kin) then
     525        91584 :    do ispinor=1,my_nspinor
     526              :  !$OMP PARALLEL DO PRIVATE(ipw,ipws) SHARED(cwavef,ispinor,gvnl2_,ddkinpw,kinpw1,npw,my_nspinor)
     527      6301132 :      do ipw=1,npw
     528      6209548 :        ipws=ipw+npw*(ispinor-1)
     529      6255340 :        if(kinpw1(ipw)<huge(zero)*1.d-11)then
     530      6209548 :          gvnl2_(1,ipws)=gvnl2_(1,ipws)+ddkinpw(ipw)*cwavef(1,ipws)
     531      6209548 :          gvnl2_(2,ipws)=gvnl2_(2,ipws)+ddkinpw(ipw)*cwavef(2,ipws)
     532              :        else
     533            0 :          gvnl2_(1,ipws)=zero
     534            0 :          gvnl2_(2,ipws)=zero
     535              :        end if
     536              :      end do
     537              :    end do
     538              :  end if
     539              : 
     540              : !======================================================================
     541              : !== Sum contributions to get the application of H^(2) to the wf
     542              : !======================================================================
     543              : !Also filter the wavefunctions for large modified kinetic energy
     544              : 
     545              : !Add non-local+kinetic to local part
     546        72096 :  if (optnl>=1.or.has_kin) then
     547       144192 :    do ispinor=1,my_nspinor
     548        72096 :      ipws=(ispinor-1)*npw1
     549              :  !$OMP PARALLEL DO PRIVATE(ipw) SHARED(gh2c,gvnl2_,kinpw1,ipws,npw1)
     550      8832892 :      do ipw=1+ipws,npw1+ipws
     551      8760796 :        if(kinpw1(ipw-ipws)<huge(zero)*1.d-11)then
     552      8688700 :          gh2c(1,ipw)=gh2c(1,ipw)+gvnl2_(1,ipw)
     553      8688700 :          gh2c(2,ipw)=gh2c(2,ipw)+gvnl2_(2,ipw)
     554              :        else
     555            0 :          gh2c(1,ipw)=zero
     556            0 :          gh2c(2,ipw)=zero
     557              :        end if
     558              :      end do
     559              :    end do
     560              :  end if
     561              : 
     562        72096 :  if (usevnl==1) then
     563        25920 :    nullify(gvnl2_)
     564              :  else
     565        46176 :    ABI_FREE(gvnl2_)
     566              :  end if
     567              : 
     568              :  ABI_NVTX_END_RANGE()
     569              : 
     570              : !call timab(196+tim_getgh2c,2,tsec)
     571              : 
     572              :  DBG_EXIT("COLL")
     573              : 
     574       216288 : end subroutine getgh2c
     575              : !!***
     576              : 
     577              : end module m_getgh2c
     578              : !!***
        

Generated by: LCOV version 2.3-1