LCOV - code coverage report
Current view: top level - src/72_response - m_rf2.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.6 % 241 211
Test Date: 2026-11-11 19:49:02 Functions: 71.4 % 7 5
Branches: 60.6 % 353 214

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_rf2
       2                 :             : !! NAME
       3                 :             : !! m_rf2
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module defines structures and provides procedures used to compute the 2nd order Sternheimer
       7                 :             : !! equation.
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !!  Copyright (C) 2015-2026 ABINIT group (LB,MT)
      11                 :             : !!  This file is distributed under the terms of the
      12                 :             : !!  GNU General Public License, see ~abinit/COPYING
      13                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !!
      15                 :             : !! SOURCE
      16                 :             : 
      17                 :             : #if defined HAVE_CONFIG_H
      18                 :             : #include "config.h"
      19                 :             : #endif
      20                 :             : 
      21                 :             : #include "abi_common.h"
      22                 :             : 
      23                 :             : MODULE m_rf2
      24                 :             : 
      25                 :             :  use defs_basis
      26                 :             :  use m_abicore
      27                 :             :  use m_errors
      28                 :             :  use m_hamiltonian
      29                 :             :  use m_cgtools
      30                 :             : 
      31                 :             :  use defs_abitypes, only : MPI_type
      32                 :             :  use m_getgh1c,     only : getgh1c
      33                 :             :  use m_pawcprj,     only : pawcprj_type, pawcprj_alloc, pawcprj_copy, pawcprj_free, pawcprj_output
      34                 :             :  use m_getghc,      only : getghc
      35                 :             :  use m_nonlop,      only : nonlop
      36                 :             :  use m_getgh2c,     only : getgh2c
      37                 :             : 
      38                 :             :  implicit none
      39                 :             : 
      40                 :             :  private
      41                 :             : !!***
      42                 :             : 
      43                 :             : !----------------------------------------------------------------------
      44                 :             : 
      45                 :             : !!****t* m_rf2/rf2_t
      46                 :             : !! NAME
      47                 :             : !!  rf2_t
      48                 :             : !!
      49                 :             : !! FUNCTION
      50                 :             : !!  Datatype gathering all needed data for the computation of the 2nd order Sternheimer equation.
      51                 :             : !!
      52                 :             : !! SOURCE
      53                 :             : 
      54                 :             :  type,public :: rf2_t
      55                 :             : 
      56                 :             : !scalars
      57                 :             :   integer :: ndir ! number of directions to consider
      58                 :             :   integer :: nband_k ! number of bands
      59                 :             :   integer :: size_wf ! number of components in a wavefunction
      60                 :             :   integer :: size_cprj ! number of components of a cprj variable (i.e. <p_i|WF>)
      61                 :             : 
      62                 :             : !arrays
      63                 :             :   integer :: iperts(2) ! perturbations to compute
      64                 :             :    ! ipert = natom + 10 :
      65                 :             :    !   iperts(1) = iperts(2) = natom+1 (wavevector k)
      66                 :             :    !
      67                 :             :    ! ipert = natom + 11 :
      68                 :             :    !   iperts(1) = natom+1 (wavevector k)
      69                 :             :    !   iperts(2) = natom+2 (electric field)
      70                 :             : 
      71                 :             :   integer :: idirs(2) ! directions of the perturbations (ndir=1 : idirs(1)=idirs(2) , ndir=2 : idirs(1)/=idirs(2))
      72                 :             : 
      73                 :             :   real(dp), contiguous, pointer :: RHS_Stern(:,:) => null() ! need a pointer because is a ptr target
      74                 :             :    ! Right-hand side of the 2nd order Sternheimer equation, for every bands.
      75                 :             :    ! Namely, for a band "n" :
      76                 :             :    ! |(RHS_Stern)_n> = (H^(2)-epsilon_n S^(2)) |u^(0)_n> + 2(H^(1)-epsilon_n S^(1))|u^(1)_n>
      77                 :             :    !                   - 2 sum_m ( lambda_mn^(1) ( S^(1) |u^(0)_m> + S^(0) |u^(1)_m> )
      78                 :             :    !                      ( /!\ : in the sum, the index m runs over occupied bands )
      79                 :             :    ! where :
      80                 :             :    !  - epsilon_n = eigenvalue of the GS Hamiltonian
      81                 :             :    !  - lambda_mn^(1) = <u^(0)_m| (H^(1)-(epsilon_n+epsilon_m)/2 S^(1) |u^(0)_n> (1st order Lagrange multiplier)
      82                 :             :    !  - X^(2) = d^2X/(dk_dir1 dlambda_dir2)
      83                 :             :    !  - 2X^(1)Y^(1) = dX/dk_dir1 dY/dlambda_dir2 + dX/dlambda_dir2 dY/dk_dir1
      84                 :             :    !  lambda_dir2 = k_dir2 (ipert==natom+10) , E_dir2 (ipert==natom+11)
      85                 :             :    ! Note : P_c^* will be apply to |(RHS_Stern)_n> in dfpt_cgwf.F90
      86                 :             :    ! **
      87                 :             :    ! Computed in "rf2_init"
      88                 :             : 
      89                 :             :   real(dp),allocatable :: amn(:,:)
      90                 :             :    ! Scalar needed for the "orhtonormalization condition", see "dcwavef(:,:)" below
      91                 :             :    ! Namely :
      92                 :             :    ! A_mn = <u^(0)_m| S^(2) |u^(0)_n> + 2 <u^(1)_m| S^(0) |u^(1)_n>
      93                 :             :    !    + 2 <u^(1)_m| S^(1) |u^(0)_n> + 2 <u^(0)_m| S^(1) |u^(1)_n>
      94                 :             :    ! **
      95                 :             :    ! Computed in "rf2_init", stored only for testing purposes
      96                 :             : 
      97                 :             :   real(dp),allocatable :: dcwavef(:,:)
      98                 :             :    ! Vector needed to enforce the "orhtonormalization condition" on 2nd order wave functions.
      99                 :             :    ! Namely :
     100                 :             :    ! |dcwavef_n> = -1/2 sum_m A_mn |u^(0)_m>
     101                 :             :    ! **
     102                 :             :    ! Computed in "rf2_init"
     103                 :             : 
     104                 :             :   real(dp),allocatable :: lambda_mn(:,:)
     105                 :             :    ! 2nd order Lagrange multiplier.
     106                 :             :    ! Namely :
     107                 :             :    ! lambda_mn =  <u^(0)_m| H^(2) |u^(0)_n> + 2 <u^(1)_m| H^(0) |u^(1)_n>
     108                 :             :    !          + 2 <u^(1)_m| H^(1) |u^(0)_n> + 2 <u^(0)_m| H^(1) |u^(1)_n>
     109                 :             :    !          - A_mn * (epsilon_m + epsilon_n) / 2
     110                 :             :    ! **
     111                 :             :    ! Computed in "rf2_init"
     112                 :             : 
     113                 :             :  end type rf2_t
     114                 :             : 
     115                 :             :  public :: rf2_getidir
     116                 :             :  public :: rf2_getidirs
     117                 :             :  public :: rf2_accumulate_bands
     118                 :             :  public :: rf2_apply_hamiltonian
     119                 :             :  public :: rf2_destroy
     120                 :             : 
     121                 :             : !!***
     122                 :             : 
     123                 :             : !----------------------------------------------------------------------
     124                 :             : 
     125                 :             : CONTAINS  !==============================================================================
     126                 :             : !!***
     127                 :             : 
     128                 :             : !----------------------------------------------------------------------
     129                 :             : 
     130                 :             : !!****f* m_rf2/rf2_getidir
     131                 :             : !! NAME
     132                 :             : !! rf2_getidir
     133                 :             : !!
     134                 :             : !! FUNCTION
     135                 :             : !!  Get the direction of the 2nd order perturbation according to inputs idir1 and idir2
     136                 :             : !!
     137                 :             : !! INPUTS
     138                 :             : !!  idir1 : index of the 1st direction (1<=idir1<=3)
     139                 :             : !!  idir2 : index of the 2nd direction (1<=idir2<=3)
     140                 :             : !!
     141                 :             : !! OUTPUT
     142                 :             : !!  idir : integer between 1 and 9
     143                 :             : !!
     144                 :             : !! SOURCE
     145                 :             : 
     146                 :        8584 : subroutine rf2_getidir(idir1,idir2,idir)
     147                 :             : 
     148                 :             : !Arguments ---------------------------------------------
     149                 :             : !scalars
     150                 :             :  integer,intent(in) :: idir1,idir2
     151                 :             :  integer,intent(out) :: idir
     152                 :             :  integer :: dir_from_dirs(9) = (/1,6,5,9,2,4,8,7,3/)
     153                 :             : ! *************************************************************************
     154                 :             : 
     155                 :        8584 :  idir = dir_from_dirs(3*(idir1-1)+idir2)
     156                 :             : 
     157                 :        8584 : end subroutine rf2_getidir
     158                 :             : !!***
     159                 :             : 
     160                 :             : !----------------------------------------------------------------------
     161                 :             : 
     162                 :             : !!****f* m_rf2/rf2_getidirs
     163                 :             : !! NAME
     164                 :             : !! rf2_getidirs
     165                 :             : !!
     166                 :             : !! FUNCTION
     167                 :             : !!  Get directions of the 1st and 2nd perturbations according to the input idir
     168                 :             : !!
     169                 :             : !! INPUTS
     170                 :             : !!  idir: integer between 1 and 9
     171                 :             : !!
     172                 :             : !! OUTPUT
     173                 :             : !!  idir1: index of the 1st direction (1<=idir1<=3)
     174                 :             : !!  idir2: index of the 2nd direction (1<=idir2<=3)
     175                 :             : !!
     176                 :             : !! SOURCE
     177                 :             : 
     178                 :      231905 : subroutine rf2_getidirs(idir,idir1,idir2)
     179                 :             : 
     180                 :             : !Arguments ---------------------------------------------
     181                 :             : !scalars
     182                 :             :  integer,intent(in) :: idir
     183                 :             :  integer,intent(out) :: idir1,idir2
     184                 :             : ! *************************************************************************
     185                 :             : 
     186                 :      262190 :  select case(idir)
     187                 :             : !  Diagonal terms :
     188                 :             :    case (1)
     189                 :       30285 :      idir1 = 1
     190                 :       30285 :      idir2 = 1
     191                 :             :    case (2)
     192                 :       30285 :      idir1 = 2
     193                 :       30285 :      idir2 = 2
     194                 :             :    case (3)
     195                 :       20529 :      idir1 = 3
     196                 :       20529 :      idir2 = 3
     197                 :             : !  Upper triangular terms :
     198                 :             :    case (4)
     199                 :       31829 :      idir1 = 2
     200                 :       31829 :      idir2 = 3
     201                 :             :    case (5)
     202                 :       21545 :      idir1 = 1
     203                 :       21545 :      idir2 = 3
     204                 :             :    case (6)
     205                 :       31829 :      idir1 = 1
     206                 :       31829 :      idir2 = 2
     207                 :             : !  Lower triangular terms :
     208                 :             :    case (7)
     209                 :       22302 :      idir1 = 3
     210                 :       22302 :      idir2 = 2
     211                 :             :    case (8)
     212                 :       20999 :      idir1 = 3
     213                 :       20999 :      idir2 = 1
     214                 :             :    case (9)
     215                 :       22302 :      idir1 = 2
     216   [ +  +  +  +  :      231905 :      idir2 = 1
          +  +  +  +  +  
                      - ]
     217                 :             :  end select
     218                 :             : 
     219                 :      231905 : end subroutine rf2_getidirs
     220                 :             : !!***
     221                 :             : 
     222                 :             : !----------------------------------------------------------------------
     223                 :             : 
     224                 :             : !!****f* m_rf2/rf2_accumulate_bands
     225                 :             : !! NAME
     226                 :             : !! rf2_init
     227                 :             : !!
     228                 :             : !! FUNCTION
     229                 :             : !! Compute the scalar product < vi | v1j > and add it to rf2%lambda_mn
     230                 :             : !! If necessary, compute < vi | v2j > and add it to rf2%amn.
     231                 :             : !!
     232                 :             : !! INPUTS
     233                 :             : !!  rf2 : rf2_t object containing all rf2 data
     234                 :             : !!  choice : 4 possible values, see "select case (choice)" below
     235                 :             : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
     236                 :             : !!  mpi_enreg=information about MPI parallelization
     237                 :             : !!  iband : band index for vi
     238                 :             : !!  idir1  (used only if debug_mode/=0)  : direction of the 1st perturbation
     239                 :             : !!  idir2  (used only if debug_mode/=0)  : direction of the 2nd perturbation
     240                 :             : !!  ipert1 (used only if debug_mode/=0)  : 1st perturbation
     241                 :             : !!  ipert2 (used only if debug_mode/=0)  : 2nd perturbation
     242                 :             : !!  jband : band index for v1j and v2j
     243                 :             : !!  debug_mode : if /=0 : all < vi | v1j > and < vi | v2j > are printed in std_out
     244                 :             : !!  vi,v1j,v2j : input vectors
     245                 :             : !!
     246                 :             : !! OUTPUT
     247                 :             : !!
     248                 :             : !! SOURCE
     249                 :             : 
     250                 :     1480320 : subroutine rf2_accumulate_bands(rf2,choice,gs_hamkq,mpi_enreg,iband,idir1,idir2,ipert1,ipert2,&
     251                 :     1480320 :                                  jband,debug_mode,vi,v1j,v2j,factor_in)
     252                 :             : 
     253                 :             : !Arguments ---------------------------------------------
     254                 :             : !scalars
     255                 :             :  class(rf2_t),intent(inout) :: rf2
     256                 :             :  integer,intent(in) :: choice,iband,idir1,idir2,ipert1,ipert2,jband,debug_mode
     257                 :             :  type(gs_hamiltonian_type),intent(in) :: gs_hamkq
     258                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     259                 :             :  real(dp), intent(in) :: factor_in
     260                 :             : !arrays
     261                 :             :  real(dp),intent(in) :: vi(2,rf2%size_wf),v1j(2,rf2%size_wf),v2j(2,rf2%size_wf)
     262                 :             : 
     263                 :             : !Local variables ---------------------------------------
     264                 :             : !scalars
     265                 :             :  integer :: nband_k,size_wf
     266                 :             :  real(dp) :: dotr,dot2r,doti,dot2i
     267                 :             :  character(len=500) :: msg
     268                 :             :  character(len=15) :: bra_i,ket_j,op1,op2
     269                 :             :  character(len=2) :: pert1,pert2
     270                 :             : ! *************************************************************************
     271                 :             : 
     272                 :             :  DBG_ENTER("COLL")
     273                 :             : 
     274                 :     1480320 :  nband_k = rf2%nband_k
     275                 :     1480320 :  size_wf = rf2%size_wf
     276                 :             : 
     277                 :     1480320 :  call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,vi,v1j,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     278                 :             : 
     279         [ +  + ]:     1480320 :  if(debug_mode/=0) then
     280         [ +  + ]:       24576 :    if (ipert1 == gs_hamkq%natom+1) then
     281                 :       17664 :      pert1 = "dk"
     282                 :             :    else
     283                 :        6912 :      pert1 = "dE"
     284                 :             :    end if
     285         [ +  + ]:       24576 :    if (ipert2 == gs_hamkq%natom+1) then
     286                 :       15360 :      pert2 = "dk"
     287                 :             :    else
     288                 :        9216 :      pert2 = "dE"
     289                 :             :    end if
     290                 :       31488 :    select case (choice)
     291                 :             :     case (1) ! < u^(pert2) | H^(0) | u^(pert1) >
     292                 :        6912 :       write(bra_i,'(2a,2(i1,a))') ' < du/',pert2,idir2,'(',iband,') | '
     293                 :        6912 :       write(ket_j,'(2a,2(i1,a))') ' | du/',pert1,idir1,'(',jband,') > '
     294                 :        6912 :       write(op1,'(a)')            '     H^(0)     '
     295                 :        6912 :       write(op2,'(a)')            '     S^(0)     '
     296                 :             :     case (2) ! < u^(pert2) | H^(pert1) | u^(0) >
     297                 :        6912 :       write(bra_i,'(2a,2(i1,a))') ' < du/',pert2,idir2,'(',iband,') | '
     298                 :        6912 :       write(ket_j,'(a,i1,a)')     ' | u^(0) (',jband,') > '
     299                 :        6912 :       write(op1,'(2a,i1,a)')      '     dH/',pert1,idir1,'    '
     300                 :        6912 :       write(op2,'(2a,i1,a)')      '     dS/',pert1,idir1,'    '
     301                 :             :     case (3) ! < u^(0) | H^(pert1pert2) | u^(0) >
     302                 :        3840 :       write(bra_i,'(a,i1,a)')     ' < u^(0) (',iband,') | '
     303                 :        3840 :       write(ket_j,'(a,i1,a)')     ' | u^(0) (',jband,') > '
     304                 :        3840 :       write(op1,'(2(2a,i1),a)')   'd^2H/(',pert1,idir1,' ',pert2,idir2,')'
     305                 :        3840 :       write(op2,'(2(2a,i1),a)')   'd^2S/(',pert1,idir1,' ',pert2,idir2,')'
     306                 :             :     case (4) ! < u^(0) | H^(pert2) | u^(pert1) >
     307                 :        6912 :       write(bra_i,'(a,i1,a)')     ' < u^(0) (',iband,') | '
     308                 :        6912 :       write(ket_j,'(2a,2(i1,a))') ' | du/',pert1,idir1,'(',jband,') > '
     309                 :        6912 :       write(op1,'(2a,i1,a)')      '     dH/',pert2,idir2,'    '
     310   [ +  +  +  +  :       31488 :       write(op2,'(2a,i1,a)')      '     dS/',pert2,idir2,'    '
                      - ]
     311                 :             :    end select
     312         [ +  + ]:       24576 :    dot2r = dotr ; if (abs(dot2r)<tol9) dot2r = zero ! in order to hide the numerical noise
     313         [ +  + ]:       24576 :    dot2i = doti ; if (abs(dot2i)<tol9) dot2i = zero ! in order to hide the numerical noise
     314                 :       24576 :    write(msg,'(3a,2(a,es17.8E3))') bra_i,op1,ket_j,' = ',dot2r,',',dot2i
     315                 :       24576 :    call wrtout(std_out,msg)
     316                 :             :  end if
     317                 :             : 
     318         [ +  + ]:     4440960 :  rf2%lambda_mn(:,iband+(jband-1)*nband_k) = factor_in*(/dotr,doti/) + rf2%lambda_mn(:,iband+(jband-1)*nband_k)
     319                 :             : 
     320   [ +  +  +  + ]:     1480320 :  if (choice == 1 .or. gs_hamkq%usepaw==1) then
     321                 :      529344 :    call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,vi,v2j,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     322                 :             : 
     323         [ +  + ]:      529344 :    if(debug_mode/=0) then
     324         [ +  + ]:       24576 :      dot2r = dotr ; if (abs(dot2r)<tol9) dot2r = zero ! in order to hide the numerical noise
     325         [ +  + ]:       24576 :      dot2i = doti ; if (abs(dot2i)<tol9) dot2i = zero ! in order to hide the numerical noise
     326                 :       24576 :      write(msg,'(3a,2(a,es17.8E3))') bra_i,op2,ket_j,' = ',dot2r,',',dot2i
     327                 :       24576 :      call wrtout(std_out,msg)
     328                 :             :    end if
     329                 :             : 
     330         [ +  + ]:     2539008 :    rf2%amn(:,iband+(jband-1)*nband_k) = factor_in*(/dotr,doti/) + rf2%amn(:,iband+(jband-1)*nband_k)
     331                 :             : 
     332                 :             :  end if ! end choice
     333                 :             : 
     334                 :             :  DBG_EXIT("COLL")
     335                 :             : 
     336                 :     1480320 : end subroutine rf2_accumulate_bands
     337                 :             : !!***
     338                 :             : 
     339                 :             : !----------------------------------------------------------------------
     340                 :             : 
     341                 :             : !!****f* m_rf2/rf2_apply_hamiltonian
     342                 :             : !! NAME
     343                 :             : !! rf2_apply_hamiltonian
     344                 :             : !!
     345                 :             : !! FUNCTION
     346                 :             : !! Apply the KS Hamiltonian (or derivative) to an input wave function.
     347                 :             : !! If asked, it also does some checks.
     348                 :             : !!
     349                 :             : !! INPUTS
     350                 :             : !!  rf2 : rf2_t object containing all rf2 data
     351                 :             : !!  cg_jband (used only if debug_mode/=0) : array containing |u^(0)(jband)> for all bands
     352                 :             : !!  cprj_jband(natom,nspinor*usecprj)= u^(0) wave functions for all bands
     353                 :             : !!              projected with non-local projectors: cprj_jband=<p_i|u^(0)(jband)>
     354                 :             : !!  cwave(2,size_wf) : input wave function |u>
     355                 :             : !!  cwaveprj(natom,nspinor) : input wave function |u>
     356                 :             : !!              projected with non-local projectors <p_i|u>
     357                 :             : !!  eig0 : 0-order eigenvalue for the present wavefunction at k
     358                 :             : !!  [enl]=optional (if not present, use hamk%ekb); non-local coeffs connecting projectors
     359                 :             : !!  eig1_k_jband : first-order lagrange multipliers for the band j (Lambda^(1)_ji for all i)
     360                 :             : !!  [ffnl1]=nonlocal form factors (needed for tests of ipert>=natom+10)
     361                 :             : !!  [ffnl1_test]=nonlocal form factors used for tests (needed for tests of ipert>=natom+10)
     362                 :             : !!  jband : band index of the input wavefunction
     363                 :             : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
     364                 :             : !!  gvnlx1(2,npw1*nspinor)=  part of <G|K^(1)+Vnl^(1)|C> not depending on VHxc^(1)              (sij_opt/=-1)
     365                 :             : !!                       or part of <G|K^(1)+Vnl^(1)-lambda.S^(1)|C> not depending on VHxc^(1) (sij_opt==-1)
     366                 :             : !!  idir=direction of the perturbation
     367                 :             : !!  ipert=type of the perturbation of the Hamiltonian :
     368                 :             : !!     ipert = 0           : GS calculation, call of getghc
     369                 :             : !!     ipert = natom+1,2   : 1st order calculation, call of getgh1c
     370                 :             : !!     ipert = natom+10,11 : 2nd order calculation, call of getgh2c
     371                 :             : !!  ikpt=number of the k-point
     372                 :             : !!  isppol=1 index of current spin component
     373                 :             : !!  mkmem =number of k points trated by this node (GS data).
     374                 :             : !!  mpi_enreg=information about MPI parallelization
     375                 :             : !!  nband_k=number of bands at this k point for that spin polarization
     376                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     377                 :             : !!  debug_mode : if /=0 : some tests are done (see NOTES below). Wrong results are printed in std_out
     378                 :             : !!  prtvol=control print volume and debugging output (for getghc)
     379                 :             : !!  rf_hamk_idir <type(rf_hamiltonian_type)>=all data for the 1st-order Hamiltonian at k,q (here q=0)
     380                 :             : !!  size_cprj=size of a cprj array (=gs_hamkq%nspinor)
     381                 :             : !!  size_wf=size of a wavefunction array (=gs_hamkq%npw_k*gs_hamkq%nspinor)
     382                 :             : !!
     383                 :             : !! OUTPUT
     384                 :             : !!  h_cwave(2,size_wf) : array containing H^(ipert)|cwave>
     385                 :             : !!  s_cwave(2,size_wf) : array containing S^(ipert)|cwave>
     386                 :             : !!
     387                 :             : !! NOTES
     388                 :             : !!  * Tests are done if debug_mode/=0. In that case : cg_jband(:,jband,1) = |u^(0)(jband)>
     389                 :             : !!    For ipert==natom+2 (electric field) : cg_jband(:,jband,2) = i * |du/dk_idir(jband)>
     390                 :             : !!    According to ipert, we check that :
     391                 :             : !!    -- ipert = 0 :
     392                 :             : !!      < u^(0)(jband)| H^(0) | u^(0)(jband)> = eig0(jband)
     393                 :             : !!    -- ipert = natom+1 or 2 :
     394                 :             : !!      < u^(0)(jband)| ( H^(1) - (eig0(jband)+eig0(iband))/2 * S^(1) ) | u^(0)(iband)> = Lambda^(1)(jband,iband)
     395                 :             : !!    --ipert >= natom+10 :
     396                 :             : !!      < u^(0) | H^(2) | u^(0) > from getgh2c is equal to nonlop with signs=1
     397                 :             : !!  * Use of cprj :
     398                 :             : !!    The cprj array is computed in dfpt_looppert.F90. In the context of rf2 calculation, it contains
     399                 :             : !!    <Proj_i^(0)|u^(0)> and <Proj_i^(1)|u^(0)> (dir=1,2 and 3) for all wavefunctions u^(0) or
     400                 :             : !!    <Proj_i^(0)|u^(1)> and <Proj_i^(1)|u^(1)> (dir=1,2 and 3) for all 1st-order wavefunctions u^(1).
     401                 :             : !!    Note that <Proj_i^(2)|u^(0)> is always computed on the fly.
     402                 :             : !!
     403                 :             : !! SOURCE
     404                 :             : 
     405   [ -  +  -  + ]:      393312 : subroutine rf2_apply_hamiltonian(cg_jband,cprj_jband,cwave,cwaveprj,h_cwave,s_cwave,eig0,eig1_k_jband,&
     406                 :      393312 : &                                jband,gs_hamkq,gvnlx1,idir,ipert,ikpt,isppol,mkmem,mpi_enreg,nband_k,nsppol,&
     407                 :             : &                                debug_mode,prtvol,rf_hamk_idir,size_cprj,size_wf,&
     408   [ +  +  +  -  :      409440 : &                                conj,enl,ffnl1,ffnl1_test) ! optional
          -  +  +  +  +  
                +  -  + ]
     409                 :             : 
     410                 :             : !Arguments ---------------------------------------------
     411                 :             : !scalars
     412                 :             :  logical,intent(in),optional :: conj
     413                 :             :  integer,intent(in) :: idir,ipert,ikpt,isppol,jband,mkmem,nband_k,nsppol,debug_mode,prtvol,size_wf,size_cprj
     414                 :             :  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
     415                 :             : ! type(rf2_t),intent(in) :: rf2
     416                 :             :  type(rf_hamiltonian_type),intent(inout),target :: rf_hamk_idir
     417                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     418                 :             : 
     419                 :             : !arrays
     420                 :             :  real(dp),intent(in),target :: cg_jband(2,size_wf*debug_mode*nband_k,2)
     421                 :             :  real(dp),intent(in),optional,target :: enl(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,gs_hamkq%dimekbq)
     422                 :             :  real(dp),intent(in),optional :: ffnl1(:,:,:,:),ffnl1_test(:,:,:,:)
     423                 :             :  real(dp),intent(in) :: eig0(nband_k),eig1_k_jband(2*nband_k)
     424                 :             :  real(dp),intent(inout) :: gvnlx1(2,size_wf)
     425                 :             :  real(dp),intent(inout) :: cwave(2,size_wf),h_cwave(2,size_wf),s_cwave(2,size_wf)
     426                 :             :  type(pawcprj_type),intent(inout),target :: cprj_jband(:,:),cwaveprj(:,:)
     427                 :             : 
     428                 :             : !Local variables ---------------------------------------
     429                 :             : !scalars
     430                 :             :  integer,parameter :: berryopt=0,tim_getghc=0,tim_getgh1c=0,tim_getgh2c=0,tim_nonlop=0
     431                 :             :  integer,parameter :: alpha(9)=(/1,2,3,2,1,1,3,3,2/),beta(9)=(/1,2,3,3,3,2,2,1,1/)
     432                 :             :  integer :: choice,cpopt,iatom,iband,idirc,idir1,idir2,idir_dum,natom,nnlout,paw_opt,signs,sij_opt
     433                 :             :  integer :: opt_gvnlx1,opt_gvnl2,optlocal,optnl,usevnl
     434                 :             :  logical :: compute_conjugate,has_cprj_jband,has_cwaveprj,pert_phon_elfd
     435                 :      786624 :  real(dp) :: dotr,doti,dotr2,doti2,enlout(18*gs_hamkq%natom),tol_test
     436                 :      393312 :  real(dp), pointer :: enl_ptr(:,:,:,:)
     437                 :      393312 :  real(dp),allocatable,target :: enl_temp(:,:,:,:)
     438                 :             :  character(len=500) :: msg
     439                 :             : 
     440                 :             : !arrays
     441                 :             :  real(dp),target :: cwave_empty(0,0),svectout_dum(0,0)
     442                 :      393312 :  real(dp),allocatable :: gvnlxc(:,:),iddk(:,:)
     443                 :      393312 :  real(dp), contiguous, pointer :: cwave_i(:,:),cwave_j(:,:)
     444         [ +  - ]:      393312 :  type(pawcprj_type),target :: cprj_empty(0,0)
     445                 :      393312 :  type(pawcprj_type),pointer :: cprj_j(:,:)
     446                 :             : ! *********************************************************************
     447                 :             : 
     448                 :             :  DBG_ENTER("COLL")
     449                 :             : 
     450                 :      393312 :  compute_conjugate = .false.
     451                 :           0 :  if(present(conj)) compute_conjugate = conj
     452                 :             : 
     453                 :             :  ABI_UNUSED(ikpt)
     454                 :             :  ABI_UNUSED(isppol)
     455                 :             :  ABI_UNUSED(mkmem)
     456                 :             :  ABI_UNUSED(nsppol)
     457                 :             : 
     458                 :             : !Check sizes
     459   [ +  +  +  + ]:     1179936 :  if (size(cprj_jband)/=0) then
     460   [ +  +  -  + ]:       18432 :    if (size(cprj_jband)/=nband_k*gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj) then
     461                 :             :      write(msg,'(2(a,i10))') &
     462         [ #  # ]:           0 :      'Wrong cprj size! actual size = ',size(cprj_jband),&
     463                 :           0 :      ' good size = ',nband_k*gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj
     464                 :           0 :      ABI_BUG(msg)
     465                 :             :    end if
     466                 :             :  end if
     467   [ +  +  +  + ]:     1179936 :  if (size(cwaveprj)/=0) then
     468   [ +  +  -  + ]:       49536 :    if (size(cwaveprj)/=gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj) then
     469                 :             :      write(msg,'(2(a,i10))') &
     470         [ #  # ]:           0 :      'Wrong cwaveprj size! actual size = ',size(cwaveprj),&
     471                 :           0 :      ' good size = ',gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj
     472                 :           0 :      ABI_BUG(msg)
     473                 :             :    end if
     474                 :             :  end if
     475                 :             : 
     476                 :      393312 :  natom = gs_hamkq%natom
     477                 :             : 
     478                 :      393312 :  pert_phon_elfd = .false.
     479   [ +  +  -  + ]:      393312 :  if (ipert>natom+11.and.ipert<=2*natom+11) pert_phon_elfd = .true.
     480                 :      393312 :  usevnl     = 0
     481                 :      393312 :  opt_gvnlx1  = 0
     482                 :      393312 :  opt_gvnl2  = 0
     483                 :      393312 :  optnl      = 2
     484         [ +  + ]:      393312 :  sij_opt=1;if (gs_hamkq%usepaw==0) sij_opt=0
     485   [ +  +  +  +  :      393312 :  if (ipert==natom+2.or.(ipert==natom+11.and.gs_hamkq%usepaw==1).or.pert_phon_elfd) then
             -  +  +  + ]
     486                 :       78528 :    usevnl = 1
     487                 :       78528 :    opt_gvnlx1 = 2
     488                 :       78528 :    opt_gvnl2 = 1
     489                 :             :  end if
     490                 :      314784 :  optlocal = 1
     491         [ +  + ]:       78528 :  if (pert_phon_elfd) then
     492                 :       16128 :    optlocal = 0
     493                 :       16128 :    sij_opt = 0
     494                 :       16128 :    optnl = 1
     495                 :             :  end if
     496                 :      393312 :  tol_test=tol8
     497                 :             : 
     498                 :             : ! In the PAW case : manage cprj_jband, cwaveprj
     499   [ +  +  +  +  :     1179936 :  has_cprj_jband=(gs_hamkq%usepaw==1.and.gs_hamkq%usecprj==1.and.size(cprj_jband)/=0)
                   +  + ]
     500   [ +  +  +  +  :     1179936 :  has_cwaveprj=(gs_hamkq%usepaw==1.and.gs_hamkq%usecprj==1.and.size(cwaveprj)/=0)
                   +  + ]
     501                 :      393312 :  cprj_j => cprj_empty
     502                 :             : 
     503         [ +  + ]:      393312 :  if (debug_mode/=0) then
     504         [ +  + ]:       19968 :    if (ipert/=0) then
     505                 :       18240 :      write(msg,'(5(a,i4))') 'RF2 TEST rf2_apply_hamiltonian ipert = ',ipert,' idir =',idir,' isppol =',isppol,&
     506                 :       36480 :      & ' ikpt = ',ikpt,' jband = ',jband
     507                 :             :    else
     508                 :        1728 :      write(msg,'(3(a,i4))') 'RF2 TEST rf2_apply_hamiltonian ipert =    0 idir =    0 isppol =',isppol,&
     509                 :        3456 :      & ' ikpt = ',ikpt,' jband = ',jband
     510                 :             :    end if
     511                 :       19968 :    call wrtout(std_out,msg)
     512                 :             :  end if
     513                 :             : 
     514                 :             : ! *******************************************************************************************
     515                 :             : ! apply H^(0)
     516                 :             : ! *******************************************************************************************
     517         [ +  + ]:      393312 :  if (ipert == 0) then
     518                 :             : 
     519   [ -  +  +  -  :      308016 :    ABI_MALLOC(gvnlxc,(2,size_wf))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     520   [ +  +  +  + ]:    37976508 :    gvnlxc(:,:) = zero
     521                 :             : 
     522                 :             : !  Test if < u^(0) | H^(0) | u^(0) > = eig0(jband)
     523         [ +  + ]:      102672 :    if(debug_mode/=0) then
     524                 :        1728 :      cwave_j => cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,1)
     525         [ +  - ]:        1728 :      if (has_cprj_jband) cprj_j => cprj_jband(:,1+(jband-1)*size_cprj:jband*size_cprj)
     526                 :        1728 :      cpopt = -1+3*gs_hamkq%usecprj*gs_hamkq%usepaw
     527                 :             :      call getghc(cpopt,cwave_j,cprj_j,h_cwave,s_cwave,gs_hamkq,gvnlxc,zero,mpi_enreg,1,prtvol,&
     528                 :        1728 :                  sij_opt,tim_getghc,0,select_k=KPRIME_H_KPRIME)
     529                 :             : 
     530                 :        1728 :      call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,cwave_j,h_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     531                 :        1728 :      dotr = dotr - eig0(jband)
     532                 :        1728 :      dotr = sqrt(dotr**2+doti**2)
     533         [ -  + ]:        1728 :      if (dotr > tol_test) then
     534                 :           0 :        write(msg,'(a,es17.8E3)') 'RF2 TEST GETGHC : NOT PASSED dotr = ',dotr
     535                 :           0 :        call wrtout(ab_out,msg)
     536                 :           0 :        call wrtout(std_out,msg)
     537                 :             :      end if
     538                 :             :    end if ! end tests
     539                 :             : 
     540         [ +  + ]:      102672 :    cpopt=-1;if (has_cwaveprj) cpopt=2
     541                 :             :    call getghc(cpopt,cwave,cwaveprj,h_cwave,s_cwave,gs_hamkq,gvnlxc,zero,mpi_enreg,1,prtvol,&
     542                 :      102672 :                sij_opt,tim_getghc,0,select_k=KPRIME_H_KPRIME)
     543         [ -  + ]:      102672 :    ABI_FREE(gvnlxc)
     544                 :             : 
     545                 :             : ! *******************************************************************************************
     546                 :             : ! apply H^(1)
     547                 :             : ! *******************************************************************************************
     548         [ +  + ]:      290640 :  else if (ipert<=natom+2) then
     549                 :             : 
     550                 :             : !  Test if < u^(0) | ( H^(1) - eps^(0) S^(1) ) | u^(0) > = eig^(1)
     551         [ +  + ]:      226416 :    if(debug_mode/=0) then
     552   [ -  +  +  -  :       31104 :      ABI_MALLOC(iddk,(2,size_wf))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     553                 :       10368 :      cwave_j => cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,1)
     554         [ +  + ]:       10368 :      if (has_cprj_jband) cprj_j => cprj_jband(:,1+(jband-1)*size_cprj:jband*size_cprj)
     555   [ +  +  +  +  :     4570560 :      iddk(:,:) = zero;if (ipert==natom+2) iddk(:,:)=cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,2)
          +  +  +  +  +  
                      + ]
     556                 :             :      call getgh1c(berryopt,cwave_j,cprj_j,h_cwave,cwave_empty,s_cwave,gs_hamkq,iddk,idir,ipert,(/zero/),&
     557                 :       10368 :                   mpi_enreg,1,optlocal,optnl,opt_gvnlx1,rf_hamk_idir,sij_opt,tim_getgh1c,usevnl,conj=compute_conjugate)
     558         [ +  + ]:      134784 :      do iband=1,nband_k
     559                 :      124416 :        cwave_i => cg_jband(:,1+(iband-1)*size_wf:iband*size_wf,1)
     560                 :      124416 :        call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,cwave_i,h_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     561   [ +  -  +  + ]:      124416 :        if (gs_hamkq%usepaw==1.and.ipert/=natom+2) then ! S^(1) is zero for ipert=natom+2
     562                 :       55296 :          call dotprod_g(dotr2,doti2,gs_hamkq%istwf_k,size_wf,2,cwave_i,s_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     563                 :       55296 :          dotr = dotr - (eig0(iband)+eig0(jband))*dotr2/two
     564                 :       55296 :          doti = doti - (eig0(iband)+eig0(jband))*doti2/two
     565                 :             :        end if
     566                 :      124416 :        dotr = dotr - eig1_k_jband(1+2*(iband-1))
     567                 :      124416 :        doti = doti - eig1_k_jband(2+2*(iband-1))
     568                 :      124416 :        dotr = sqrt(dotr**2+doti**2)
     569         [ -  + ]:      134784 :        if (dotr > tol_test) then
     570                 :           0 :          write(msg,'(4(a,i2),a,es17.8E3)') 'RF2 TEST GETGH1 : ipert=',ipert,' idir=',idir,&
     571                 :           0 :                                             ' jband=',jband,' iband=',iband,' NOT PASSED dotr = ',dotr
     572                 :           0 :          call wrtout(ab_out,msg)
     573                 :           0 :          call wrtout(std_out,msg)
     574                 :             :        end if
     575                 :             :      end do ! end iband
     576         [ -  + ]:       10368 :      ABI_FREE(iddk)
     577                 :             :    end if ! end tests
     578                 :             : 
     579                 :             :    call getgh1c(berryopt,cwave,cwaveprj,h_cwave,cwave_empty,s_cwave,gs_hamkq,gvnlx1,idir,ipert,(/zero/),&
     580                 :      226416 :                 mpi_enreg,1,optlocal,optnl,opt_gvnlx1,rf_hamk_idir,sij_opt,tim_getgh1c,usevnl,conj=compute_conjugate)
     581                 :             : 
     582                 :             : ! *******************************************************************************************
     583                 :             : ! apply H^(2)
     584                 :             : ! *******************************************************************************************
     585   [ +  +  +  +  :       64224 :  else if (ipert==natom+10.or.ipert==natom+11.or.pert_phon_elfd) then
                   +  - ]
     586                 :             : 
     587                 :             : ! *******************************************************************************************
     588                 :             : !  Test if < u^(0) | H^(2) | u^(0) > from getgh2c is equal to nonlop with signs=1
     589   [ +  +  +  - ]:       64224 :    if(debug_mode/=0.and.present(ffnl1).and.present(ffnl1_test)) then
     590                 :             : 
     591                 :        7872 :      cwave_j => cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,1)
     592                 :             : 
     593   [ -  +  +  -  :       23616 :      ABI_MALLOC(iddk,(2,size_wf))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     594   [ +  +  +  + ]:     2233680 :      iddk(:,:) = cwave_j(:,:)
     595                 :             : 
     596                 :             :      call getgh2c(cwave_j,cprj_empty,h_cwave,s_cwave,gs_hamkq,iddk,idir,ipert,zero,&
     597                 :             :                   mpi_enreg,optlocal,optnl,opt_gvnl2,rf_hamk_idir,sij_opt,tim_getgh2c,usevnl,&
     598                 :        7872 :                   conj=compute_conjugate,optkin=0,enl=enl)
     599         [ -  + ]:        7872 :      ABI_FREE(iddk)
     600                 :             : 
     601                 :        7872 :      call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,cwave_j,h_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     602                 :             : 
     603                 :        7872 :      idir1=alpha(idir);idir2=beta(idir)
     604                 :        7872 :      idirc=3*(idir1-1)+idir2
     605                 :             : 
     606         [ +  + ]:      291264 :      enlout = zero
     607                 :             : 
     608                 :             : !    Change the pointer ffnl_k to ffnl1_test (idir_ffnl=0, for nonlop with signs=1)
     609                 :        7872 :      call gs_hamkq%load_k(ffnl_k=ffnl1_test)
     610                 :             : 
     611                 :        7872 :      signs=1
     612                 :        7872 :      dotr2 = 0
     613                 :        7872 :      doti2 = 0
     614                 :             : 
     615                 :             : !    ************************
     616                 :             : !    IPERT == NATOM+10
     617                 :             : !    ************************
     618         [ +  + ]:        7872 :      if (ipert==natom+10) then
     619                 :             : 
     620         [ -  + ]:         384 :        cpopt=-1; choice=8; paw_opt=1; if (gs_hamkq%usepaw==0) paw_opt=0 ; nnlout = 6
     621                 :             : 
     622                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
     623                 :         384 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum)
     624                 :         384 :        dotr2 = enlout(idir)
     625                 :             : 
     626                 :             :      end if ! IPERT == NATOM+10
     627                 :             : 
     628                 :             : !    ************************
     629                 :             : !    IPERT == NATOM+11
     630                 :             : !    ************************
     631         [ +  + ]:        7872 :      if (ipert==natom+11) then
     632                 :             : 
     633         [ -  + ]:         576 :        if (present(enl)) then
     634                 :           0 :          enl_ptr => enl
     635   [ +  -  +  -  :         576 :        else if (associated(rf_hamk_idir%e1kbfr).and.associated(rf_hamk_idir%e1kbsc).and.optnl==2) then
                   +  - ]
     636   [ -  +  +  -  :        3456 :          ABI_MALLOC(enl_temp,(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,rf_hamk_idir%cplex))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     637   [ +  +  +  +  :       44352 :          enl_temp(:,:,:,:) = rf_hamk_idir%e1kbfr(:,:,:,:) + rf_hamk_idir%e1kbsc(:,:,:,:)
             +  +  +  + ]
     638                 :         576 :          enl_ptr => enl_temp
     639         [ #  # ]:           0 :        else if (associated(rf_hamk_idir%e1kbfr)) then
     640                 :           0 :          enl_ptr => rf_hamk_idir%e1kbfr
     641                 :             :        end if
     642                 :             : 
     643                 :             : !      Compute application of dS/dk1 to cwavef
     644                 :             : !      sum_{i,j} s_ij  < psi^(0) | d(|p_i><p_j|)/dk(idir1) | psi^(0) >
     645                 :         576 :        cpopt=-1 ; choice=5 ; paw_opt=3 ; nnlout=3
     646                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,&
     647                 :         576 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum)
     648                 :         576 :        dotr2 = enlout(idir1)
     649                 :             : 
     650                 :             : !      Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2)
     651                 :             : !      sum_{i,j} chi_ij(idir2) < psi^(0) | d(|p_i><p_j|)/dk(idir1) | psi^(0) >
     652                 :         576 :        cpopt=-1 ; choice=5 ; paw_opt=1 ; nnlout=3
     653                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,&
     654         [ -  + ]:         576 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum,enl=enl_ptr)
     655                 :         576 :        dotr2 = dotr2 + enlout(idir1)
     656                 :             : 
     657                 :             : !      Compute derivatives due to projectors |d^2[p_i]/dk1dk2>,|d[p_i]/dk1>,|d[p_i]/dk2>
     658                 :             : !      i * sum_{i,j} < psi^(0) | (d(|p_i><dp_j/dk(idir2)|)/dk(idir1) | psi^(0) >
     659                 :         576 :        cpopt=-1 ; choice=81 ; paw_opt=3 ; nnlout=18
     660                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,&
     661                 :         576 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum)
     662                 :         576 :        dotr2 = dotr2 - enlout(2*idirc  )
     663                 :         576 :        doti2 = doti2 + enlout(2*idirc-1)
     664                 :             : 
     665                 :             :      end if ! IPERT == NATOM+11
     666                 :             : 
     667                 :             : !    ************************
     668                 :             : !    PERT_PHON_ELFD
     669                 :             : !    ************************
     670         [ +  + ]:        7872 :      if (pert_phon_elfd) then
     671                 :             : 
     672         [ +  - ]:        6912 :        if (present(enl)) then
     673                 :        6912 :          enl_ptr => enl
     674   [ #  #  #  #  :           0 :        else if (associated(rf_hamk_idir%e1kbfr).and.associated(rf_hamk_idir%e1kbsc).and.optnl==2) then
                   #  # ]
     675   [ #  #  #  #  :           0 :          ABI_MALLOC(enl_temp,(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,rf_hamk_idir%cplex))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     676   [ #  #  #  #  :           0 :          enl_temp(:,:,:,:) = rf_hamk_idir%e1kbfr(:,:,:,:) + rf_hamk_idir%e1kbsc(:,:,:,:)
             #  #  #  # ]
     677                 :           0 :          enl_ptr => enl_temp
     678         [ #  # ]:           0 :        else if (associated(rf_hamk_idir%e1kbfr)) then
     679                 :           0 :          enl_ptr => rf_hamk_idir%e1kbfr
     680                 :             :        end if
     681                 :             : 
     682                 :        6912 :        iatom = gs_hamkq%atindx(ipert - natom - 11)  ! Atoms are type-sorted in enlout()
     683                 :             : 
     684                 :             : !      Compute application of dS/dtau1 to i*d[cwavef]/dk2
     685                 :             : !      sum_{i,j} s_ij < psi^(0) | d(|p_i><p_j|)/dtau(idir1) | i*psi^(k(idir2)) >
     686                 :        6912 :        cpopt=-1 ; choice=2 ; paw_opt=3 ; nnlout=3*natom
     687                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,&
     688                 :        6912 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum)
     689                 :        6912 :        dotr2 = enlout(3*(iatom-1)+idir1)
     690                 :             : 
     691                 :             : !      Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2)
     692                 :             : !      sum_{i,j} chi_ij(idir2) < psi^(0) | d(|p_i><p_j|)/dtau(idir1) | psi^(0) >
     693                 :        6912 :        cpopt=-1 ; choice=2 ; paw_opt=1 ; nnlout=3*natom
     694                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,&
     695         [ -  + ]:        6912 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum,enl=enl_ptr)
     696                 :        6912 :        dotr2 = dotr2 + enlout(3*(iatom-1)+idir1)
     697                 :             : 
     698                 :             : !      Compute derivatives due to projectors |d^2[p_i]/dtau1dk2>,|d[p_i]/dtau1>,|d[p_i]/dk2>
     699                 :             : !      i * sum_{i,j} < psi^(0) | (d(|p_i><dp_j/dk(idir2)|)/dtau(idir1) | psi^(0) >
     700                 :        6912 :        cpopt=-1 ; choice=54 ; paw_opt=3 ; nnlout=18*natom
     701                 :             :        call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,&
     702                 :        6912 : &       paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum)
     703                 :        6912 :        dotr2 = dotr2 - enlout(18*(iatom-1)+2*idirc  )
     704                 :        6912 :        doti2 = doti2 + enlout(18*(iatom-1)+2*idirc-1)
     705                 :             : 
     706                 :             :      end if ! PERT_PHON_ELFD
     707                 :             : 
     708                 :        7872 :      dotr = dotr - dotr2
     709                 :        7872 :      doti = doti - doti2
     710                 :        7872 :      dotr = sqrt(dotr**2+doti**2)
     711         [ -  + ]:        7872 :      if (dotr > 10*tol_test) then
     712                 :           0 :        write(msg,'(a,es17.8E3)') 'RF2 TEST GETGH2C : NOT PASSED dotr = ',dotr
     713                 :           0 :        call wrtout(ab_out,msg)
     714                 :           0 :        call wrtout(std_out,msg)
     715                 :             :      end if
     716                 :             : 
     717                 :             : !    Change the pointer ffnl_k back to ffnl1 (idir_ffnl=4, for nonlop with signs=2)
     718                 :        7872 :      call gs_hamkq%load_k(ffnl_k=ffnl1)
     719                 :             : 
     720         [ +  + ]:        7872 :      if (associated(enl_ptr)) then
     721                 :        7871 :        nullify(enl_ptr)
     722                 :             :      end if
     723         [ +  + ]:        7872 :      ABI_SFREE(enl_temp)
     724                 :             : 
     725                 :             :    end if ! end tests
     726                 :             : ! *******************************************************************************************
     727                 :             : 
     728                 :             :    call getgh2c(cwave,cwaveprj,h_cwave,s_cwave,gs_hamkq,gvnlx1,idir,ipert,zero,&
     729                 :             :                 mpi_enreg,optlocal,optnl,opt_gvnl2,rf_hamk_idir,sij_opt,tim_getgh2c,usevnl,&
     730                 :       64224 :                 conj=compute_conjugate,enl=enl)
     731                 :             : 
     732                 :             :  else
     733                 :             : 
     734   [ #  #  #  # ]:           0 :    h_cwave = zero
     735                 :           0 :    ABI_ERROR(" rf2_apply_hamiltonian can be used only for: 0<=ipert<=natom+2 and natom+10<=ipert<=2*natom+11.")
     736                 :           0 :    return
     737                 :             : 
     738                 :             :  end if
     739                 :             : 
     740                 :             :  DBG_EXIT("COLL")
     741                 :             : 
     742   [ +  +  -  +  :      802752 : end subroutine rf2_apply_hamiltonian
             -  +  -  + ]
     743                 :             : !!***
     744                 :             : 
     745                 :             : !----------------------------------------------------------------------
     746                 :             : 
     747                 :             : !!****f* m_rf2/rf2_destroy
     748                 :             : !! NAME
     749                 :             : !! rf2_init
     750                 :             : !!
     751                 :             : !! FUNCTION
     752                 :             : !!  Free all allocated arrays in a rf2_t object
     753                 :             : !!
     754                 :             : !! SOURCE
     755                 :             : 
     756                 :       14616 : subroutine rf2_destroy(rf2)
     757                 :             : 
     758                 :             : !Arguments ---------------------------------------------
     759                 :             : !scalars
     760                 :             :  type(rf2_t),intent(inout) :: rf2
     761                 :             : ! *************************************************************************
     762                 :             : 
     763         [ +  - ]:       14616 :  if (associated(rf2%RHS_Stern)) then
     764                 :       14616 :    ABI_FREE(rf2%RHS_Stern)
     765                 :             :  end if
     766         [ +  - ]:       14616 :  ABI_SFREE(rf2%dcwavef)
     767         [ +  + ]:       14616 :  ABI_SFREE(rf2%amn)
     768         [ +  - ]:       14616 :  ABI_SFREE(rf2%lambda_mn)
     769                 :             : 
     770                 :       14616 : end subroutine rf2_destroy
     771                 :             : !!***
     772                 :             : 
     773   [ #  #  #  #  :           0 : END MODULE m_rf2
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
        

Generated by: LCOV version 2.3-1