LCOV - code coverage report
Current view: top level - src/66_wfs - m_cgcprj.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 67.0 % 227 152
Test Date: 2026-11-06 10:48:53 Functions: 100.0 % 4 4
Branches: 47.0 % 530 249

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_cgcprj
       2                 :             : !! NAME
       3                 :             : !!  m_cgcprj
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Functions operating on wavefunctions in the cg+cprj representation.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (XG)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_cgcprj
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use defs_abitypes
      26                 :             :  use m_cgtools
      27                 :             :  use m_errors
      28                 :             :  use m_xmpi
      29                 :             : 
      30                 :             :  use m_pawtab, only : pawtab_type
      31                 :             :  use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_get, pawcprj_free, pawcprj_lincom
      32                 :             : 
      33                 :             :  implicit none
      34                 :             : 
      35                 :             :  private
      36                 :             : !!***
      37                 :             : 
      38                 :             :  public :: dotprod_set_cgcprj
      39                 :             :  public :: dotprodm_sumdiag_cgcprj
      40                 :             :  public :: lincom_cgcprj
      41                 :             :  public :: cgcprj_cholesky
      42                 :             : !!***
      43                 :             : 
      44                 :             : contains
      45                 :             : !!***
      46                 :             : 
      47                 :             : !!****f* ABINIT/dotprod_set_cgcprj
      48                 :             : !! NAME
      49                 :             : !! dotprod_set_cgcprj
      50                 :             : !!
      51                 :             : !! FUNCTION
      52                 :             : !! For one k point and spinpol, compute the matrix of scalar products between two sets of nband wavefunctions
      53                 :             : !! that are known in the cg+cprj representation
      54                 :             : !! Smn=<wf1m|wf2n>
      55                 :             : !!
      56                 :             : !! Can also treat the case of the computation of scalar products within one set of nband wavefunctions
      57                 :             : !! without recomputing already computed matrix elements (define hermitian=1)
      58                 :             : !!
      59                 :             : !! This implementation is NOT band-parallelized
      60                 :             : !! Also, it is far of being optimal at the level of linear algebra, and involves extra copying
      61                 :             : !! that are detrimental for performance...
      62                 :             : !!
      63                 :             : !! INPUTS
      64                 :             : !!  atindx1(natom)=index table for atoms, inverse of atindx
      65                 :             : !!  cg1(2,mcg1)= plane wave wavefunction coefficients for the first set of wavefunctions (all k points and spinpol)
      66                 :             : !!  cg2(2,mcg2)= plane wave wavefunction coefficients for the second set of wavefunctions (all k points and spinpol)
      67                 :             : !!  cprj1(natom,mcprj1) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors in the first set,
      68                 :             : !!  cprj2(natom,mcprj2) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors in the second set,
      69                 :             : !!  dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
      70                 :             : !!  hermitian= if 1, consider that the Smn matrix is hermitian, and do not recompute already computed matrix elements.
      71                 :             : !!  ibg1=shift in cprj1 array to locate current k-point.
      72                 :             : !!    Might be 0, in which case cprj1 is not copied internally, which saves some time/space
      73                 :             : !!  ibg2=shift in cprj2 array to locate current k-point.
      74                 :             : !!    Might be 0, in which case cprj2 is not copied internally, which saves some time/space
      75                 :             : !!  icg1=shift in cg1 array to locate current k-point
      76                 :             : !!  icg2=shift in cg2 array to locate current k-point
      77                 :             : !!  ikpt=current k point index
      78                 :             : !!  isppol=current spin polarization index
      79                 :             : !!  istwf=input option parameter that describes the storage of wfs
      80                 :             : !!  mcg1=second dimension of cg1 array (mpw*nspinor*mband1*mkmem*nsppol)
      81                 :             : !!  mcg2=second dimension of cg2 array (mpw*nspinor*mband2*mkmem*nsppol)
      82                 :             : !!  mcprj1=second dimension of cprj1 array
      83                 :             : !!  mcprj2=second dimension of cprj2 array
      84                 :             : !!  mkmem=number of k points which can fit in memory
      85                 :             : !!  mpi_enreg=information about MPI parallelization
      86                 :             : !!  natom=number of atoms
      87                 :             : !!  nattyp(ntypat)=number of atoms of each type in cell.
      88                 :             : !!  nbd1=number of bands for the first set of wavefunctions
      89                 :             : !!  nbd2=number of bands for the second set of wavefunctions
      90                 :             : !!  npw=number of planewaves in basis at this k point
      91                 :             : !!  nspinor=number of spinor components
      92                 :             : !!  nsppol=number of spin polarizations
      93                 :             : !!  ntypat=number of types of atoms
      94                 :             : !!  pawtab(dtset%ntypat*dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
      95                 :             : !!  usepaw=1 if PAW is activated
      96                 :             : !!
      97                 :             : !! OUTPUT
      98                 :             : !!  smn(2,nbd1,nbd2)=matrix of scalar products between the first set of wavefunctions and the second set of wavefunctions
      99                 :             : !!
     100                 :             : !! SIDE EFFECTS
     101                 :             : !!
     102                 :             : !! SOURCE
     103                 :             : 
     104                 :         282 : subroutine dotprod_set_cgcprj(atindx1,cg1,cg2,cprj1,cprj2,dimcprj,hermitian,&
     105                 :             : & ibg1,ibg2,icg1,icg2,ikpt,isppol,istwf,mband,mcg1,mcg2,mcprj1,mcprj2,mkmem,&
     106                 :         282 : & mpi_enreg,natom,nattyp,nbd1,nbd2,npw,nspinor,nsppol,ntypat,pawtab,smn,usepaw)
     107                 :             : 
     108                 :             : !Arguments ------------------------------------
     109                 :             : !scalars
     110                 :             :  integer, intent(in) :: hermitian,ibg1,ibg2,icg1,icg2,ikpt,isppol,istwf
     111                 :             :  integer, intent(in) :: mkmem,mband,mcg1,mcg2,mcprj1,mcprj2
     112                 :             :  integer, intent(in) :: natom,nbd1,nbd2,npw,nspinor,nsppol,ntypat,usepaw
     113                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     114                 :             : !arrays
     115                 :             :  integer, intent(in) :: atindx1(natom),dimcprj(natom),nattyp(ntypat)
     116                 :             :  real(dp), intent(in) :: cg1(2,mcg1),cg2(2,mcg2)
     117                 :             :  real(dp), intent(out) :: smn(2,nbd1,nbd2)
     118                 :             :  type(pawcprj_type),intent(in) :: cprj1(natom,mcprj1),cprj2(natom,mcprj2)
     119                 :             :  type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
     120                 :             : 
     121                 :             : !Local variables-------------------------------
     122                 :             : !scalars
     123                 :             :  integer :: ia,iat,itypat,ibd1,ibd2,icgb1,icgb2,ier,ig,ii,i1,i2,iorder
     124                 :             :  integer :: ilmn1,ilmn2,klmn,max_nbd2,nbd
     125                 :             :  real(dp) :: dotr,doti
     126                 :             : !arrays
     127                 :         282 :  real(dp),allocatable :: cwavef1(:,:),cwavef2(:,:),proj(:,:,:)
     128                 :         282 :  real(dp),allocatable :: eigval(:),eigvec(:,:,:),matrx(:,:),zhpev1(:,:),zhpev2(:)
     129                 :         282 :  type(pawcprj_type),allocatable :: cprj1_k(:,:),cprj2_k(:,:)
     130                 :             : 
     131                 :             : ! *************************************************************************
     132                 :             : 
     133                 :             : !DEBUG
     134                 :             : !write(std_out,*)' dotprod_set_cgcprj : enter '
     135                 :             : !write(std_out,*)' dotprod_set_cgcprj : npw, nspinor=',npw,nspinor
     136                 :             : !write(std_out,*)' dotprod_set_cgcprj : usepaw,nbd1,nbd2=',usepaw,nbd1,nbd2
     137                 :             : !call flush(std_out)
     138                 :             : !ENDDEBUG
     139                 :             : 
     140         [ +  + ]:         282 :  if(hermitian==1)then
     141         [ -  + ]:         141 :    if(nbd1/=nbd2)then
     142                 :           0 :      ABI_ERROR(' With hermitian==1, nb1 and nb2 must be equal ')
     143                 :             :    end if
     144                 :             :  end if
     145                 :             : 
     146   [ -  +  +  -  :         846 :  ABI_MALLOC(cwavef1,(2,npw*nspinor))
          +  -  +  -  -  
                +  -  + ]
     147   [ -  +  +  -  :         564 :  ABI_MALLOC(cwavef2,(2,npw*nspinor))
             -  +  -  + ]
     148         [ +  + ]:         282 :  if(usepaw==1) then
     149   [ -  +  +  -  :        1920 :    ABI_MALLOC(cprj1_k,(natom,nspinor*nbd1))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     150   [ -  +  +  -  :        1920 :    ABI_MALLOC(cprj2_k,(natom,nspinor*nbd2))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     151                 :         120 :    iorder=0 ! There is no change of ordering of cprj when copying wavefunctions
     152                 :             :  end if
     153   [ +  +  -  + ]:         282 :  if(usepaw==1 .and. ibg1/=0) then
     154                 :           0 :    call pawcprj_alloc(cprj1_k,cprj1(1,1)%ncpgr,dimcprj)
     155                 :             :  end if
     156   [ +  +  -  + ]:         282 :  if(usepaw==1 .and. ibg2/=0) then
     157                 :           0 :    call pawcprj_alloc(cprj2_k,cprj1(1,1)%ncpgr,dimcprj)
     158                 :             :  end if
     159                 :             : 
     160                 :         282 :  icgb1=icg1
     161         [ +  + ]:        1380 :  do ibd1=1,nbd1
     162                 :             : 
     163                 :             : !  Extract wavefunction information
     164         [ +  + ]:      197602 :    do ig=1,npw*nspinor
     165                 :      196504 :      cwavef1(1,ig)=cg1(1,ig+icgb1)
     166                 :      197602 :      cwavef1(2,ig)=cg1(2,ig+icgb1)
     167                 :             :    end do
     168   [ +  +  -  + ]:        1098 :    if(usepaw==1 .and. ibg1/=0) then
     169                 :             :      call pawcprj_get(atindx1,cprj1_k,cprj1,natom,1,ibg1,ikpt,iorder,isppol,mband,&
     170                 :             : &     mkmem,natom,nbd1,nbd1,nspinor,nsppol,0,&
     171                 :           0 : &     mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
     172                 :             :    end if
     173                 :             : 
     174                 :        1098 :    icgb2=icg2
     175                 :        1098 :    max_nbd2=nbd2
     176         [ +  + ]:        1098 :    if(hermitian==1)max_nbd2=ibd1
     177         [ +  + ]:        4644 :    do ibd2=1,max_nbd2
     178                 :             : 
     179                 :             : !    XG171222 Note that this copy step, being inside the ibd1 loop, is quite detrimental.
     180                 :             : !    It might be reduced by copying several cwavef2, and use a ZGEMM type of approach.
     181                 :             : 
     182                 :             : !    Extract wavefunction information
     183         [ +  + ]:      574324 :      do ig=1,npw*nspinor
     184                 :      570778 :        cwavef2(1,ig)=cg2(1,ig+icgb2)
     185                 :      574324 :        cwavef2(2,ig)=cg2(2,ig+icgb2)
     186                 :             :      end do
     187                 :             : 
     188   [ +  +  -  + ]:        3546 :      if(usepaw==1 .and. ibg2/=0) then
     189                 :             :        call pawcprj_get(atindx1,cprj2_k,cprj2,natom,1,ibg2,ikpt,iorder,isppol,mband,&
     190                 :             : &       mkmem,natom,nbd2,nbd2,nspinor,nsppol,0,&
     191                 :           0 : &       mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
     192                 :             :      end if
     193                 :             : 
     194                 :             : !    Calculate Smn=<cg1|cg2>
     195                 :        3546 :      call dotprod_g(dotr,doti,istwf,npw*nspinor,2,cwavef1,cwavef2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     196                 :             : 
     197         [ +  + ]:        3546 :      if(usepaw==1) then
     198                 :             :        ia =0
     199         [ +  + ]:        3120 :        do itypat=1,ntypat
     200   [ -  +  -  - ]:        1560 :          if(ibg1/=0 .and. ibg2/=0)then
     201         [ #  # ]:           0 :            do iat=1+ia,nattyp(itypat)+ia
     202         [ #  # ]:           0 :              do ilmn1=1,pawtab(itypat)%lmn_size
     203         [ #  # ]:           0 :                do ilmn2=1,ilmn1
     204                 :           0 :                  klmn=((ilmn1-1)*ilmn1)/2+ilmn2
     205                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
     206                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
     207                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
     208                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
     209                 :             :                end do
     210         [ #  # ]:           0 :                do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
     211                 :           0 :                  klmn=((ilmn2-1)*ilmn2)/2+ilmn1
     212                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
     213                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
     214                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
     215                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
     216                 :             :                end do
     217                 :             :              end do
     218                 :             :            end do
     219   [ -  +  -  - ]:        1560 :          else if(ibg1/=0 .and. ibg2==0)then
     220         [ #  # ]:           0 :            do iat=1+ia,nattyp(itypat)+ia
     221         [ #  # ]:           0 :              do ilmn1=1,pawtab(itypat)%lmn_size
     222         [ #  # ]:           0 :                do ilmn2=1,ilmn1
     223                 :           0 :                  klmn=((ilmn1-1)*ilmn1)/2+ilmn2
     224                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
     225                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
     226                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
     227                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
     228                 :             :                end do
     229         [ #  # ]:           0 :                do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
     230                 :           0 :                  klmn=((ilmn2-1)*ilmn2)/2+ilmn1
     231                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
     232                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
     233                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
     234                 :           0 : &                 cprj1_k(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
     235                 :             :                end do
     236                 :             :              end do
     237                 :             :            end do
     238   [ +  -  -  + ]:        1560 :          else if(ibg1==0 .and. ibg2/=0)then
     239         [ #  # ]:           0 :            do iat=1+ia,nattyp(itypat)+ia
     240         [ #  # ]:           0 :              do ilmn1=1,pawtab(itypat)%lmn_size
     241         [ #  # ]:           0 :                do ilmn2=1,ilmn1
     242                 :           0 :                  klmn=((ilmn1-1)*ilmn1)/2+ilmn2
     243                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
     244                 :           0 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
     245                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
     246                 :           0 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
     247                 :             :                end do
     248         [ #  # ]:           0 :                do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
     249                 :           0 :                  klmn=((ilmn2-1)*ilmn2)/2+ilmn1
     250                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2)+&
     251                 :           0 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2))
     252                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2_k(iat,ibd2)%cp(2,ilmn2)-&
     253                 :           0 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2_k(iat,ibd2)%cp(1,ilmn2))
     254                 :             :                end do
     255                 :             :              end do
     256                 :             :            end do
     257   [ +  -  +  - ]:        1560 :          else if(ibg1==0 .and. ibg2==0)then
     258         [ +  + ]:        4680 :            do iat=1+ia,nattyp(itypat)+ia
     259         [ +  + ]:       29640 :              do ilmn1=1,pawtab(itypat)%lmn_size
     260         [ +  + ]:      137280 :                do ilmn2=1,ilmn1
     261                 :      112320 :                  klmn=((ilmn1-1)*ilmn1)/2+ilmn2
     262                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
     263                 :      112320 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
     264                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
     265                 :      137280 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
     266                 :             :                end do
     267         [ +  + ]:      115440 :                do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
     268                 :       87360 :                  klmn=((ilmn2-1)*ilmn2)/2+ilmn1
     269                 :             :                  dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2)+&
     270                 :       87360 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2))
     271                 :             :                  doti=doti+pawtab(itypat)%sij(klmn)*(cprj1(iat,ibd1)%cp(1,ilmn1)*cprj2(iat,ibd2)%cp(2,ilmn2)-&
     272                 :      112320 : &                 cprj1(iat,ibd1)%cp(2,ilmn1)*cprj2(iat,ibd2)%cp(1,ilmn2))
     273                 :             :                end do
     274                 :             :              end do
     275                 :             :            end do
     276                 :             :          end if
     277                 :        3120 :          ia=ia+nattyp(itypat)
     278                 :             :        end do
     279                 :             :      end if
     280                 :        3546 :      smn(1,ibd1,ibd2)=dotr
     281                 :        3546 :      smn(2,ibd1,ibd2)=doti
     282                 :             : !    End loop over bands ibd2
     283                 :        4644 :      icgb2=icgb2+npw*nspinor
     284                 :             : 
     285                 :             :    end do
     286                 :             : 
     287                 :             : !  End loop over bands ibd1
     288                 :        1380 :    icgb1=icgb1+npw*nspinor
     289                 :             :  end do
     290                 :             : 
     291                 :             : !Complete the matrix if hermitian
     292         [ +  + ]:         282 :  if(hermitian==1)then
     293         [ +  + ]:         549 :    do ibd1=1,nbd1-1
     294         [ +  + ]:        1365 :      do ibd2=ibd1+1,nbd2
     295                 :         816 :        smn(1,ibd1,ibd2)= smn(1,ibd2,ibd1)
     296                 :        1224 :        smn(2,ibd1,ibd2)=-smn(2,ibd2,ibd1)
     297                 :             :      end do
     298                 :             :    end do
     299                 :             :  end if
     300                 :             : 
     301                 :             : !DEBUG
     302                 :             : !write(std_out,*)' smn=',smn
     303                 :             : !ENDDEBUG
     304                 :             : 
     305                 :             : !====== Debugging section ==========
     306                 :             :  if(.false.)then
     307                 :             : !DEBUG
     308                 :             : !Compute the eigenvalues of the projector S herm(S) or herm(S) S, depending on which has lowest dimension.
     309                 :             : !write(std_out,*)' dotprod_set_cgcprj : compute the projector matrix '
     310                 :             :    nbd=min(nbd1,nbd2)
     311                 :             :    ABI_MALLOC(proj,(2,nbd,nbd))
     312                 :             :    proj(:,:,:)=zero
     313                 :             :    if(nbd1<=nbd2)then
     314                 :             :      do ibd1=1,nbd1
     315                 :             :        do ibd2=1,nbd2
     316                 :             :          proj(1,:,ibd1)=proj(1,:,ibd1)+smn(1,:,ibd2)*smn(1,ibd1,ibd2)+smn(2,:,ibd2)*smn(2,ibd1,ibd2)
     317                 :             :          proj(2,:,ibd1)=proj(2,:,ibd1)-smn(1,:,ibd2)*smn(2,ibd1,ibd2)+smn(2,:,ibd2)*smn(1,ibd1,ibd2)
     318                 :             :        end do
     319                 :             :      end do
     320                 :             :    else
     321                 :             :      do ibd2=1,nbd2
     322                 :             :        do ibd1=1,nbd1
     323                 :             :          proj(1,:,ibd2)=proj(1,:,ibd2)+smn(1,ibd1,:)*smn(1,ibd1,ibd2)+smn(2,ibd1,:)*smn(2,ibd1,ibd2)
     324                 :             :          proj(2,:,ibd2)=proj(2,:,ibd2)+smn(1,ibd1,:)*smn(2,ibd1,ibd2)-smn(2,ibd1,:)*smn(1,ibd1,ibd2)
     325                 :             :        end do
     326                 :             :      end do
     327                 :             :    end if
     328                 :             : 
     329                 :             : !write(std_out,*)' proj=',proj
     330                 :             : 
     331                 :             : !write(std_out,*)' dotprod_set_cgcprj : compute the eigenvalues of the projector '
     332                 :             :    ABI_MALLOC(matrx,(2,(nbd*(nbd+1))/2))
     333                 :             :    ii=1
     334                 :             :    do i2=1,nbd
     335                 :             :      do i1=1,i2
     336                 :             :        matrx(1,ii)=proj(1,i1,i2)
     337                 :             :        matrx(2,ii)=proj(2,i1,i2)
     338                 :             :        ii=ii+1
     339                 :             :      end do
     340                 :             :    end do
     341                 :             : 
     342                 :             :    ABI_MALLOC(zhpev1,(2,2*nbd-1))
     343                 :             :    ABI_MALLOC(zhpev2,(3*nbd-2))
     344                 :             :    ABI_MALLOC(eigval,(nbd))
     345                 :             :    ABI_MALLOC(eigvec,(2,nbd,nbd))
     346                 :             : 
     347                 :             :    call ZHPEV ('V','U',nbd,matrx,eigval,eigvec,nbd,zhpev1,zhpev2,ier)
     348                 :             : 
     349                 :             : !write(std_out,*)' eigval=',eigval
     350                 :             : 
     351                 :             :    ABI_FREE(matrx)
     352                 :             :    ABI_FREE(zhpev1)
     353                 :             :    ABI_FREE(zhpev2)
     354                 :             :    ABI_FREE(eigval)
     355                 :             :    ABI_FREE(eigvec)
     356                 :             : 
     357                 :             :    ABI_FREE(proj)
     358                 :             : !stop
     359                 :             : !ENDDEBUG
     360                 :             :  end if
     361                 :             : !====== End of debugging section ==========
     362                 :             : 
     363         [ -  + ]:         282 :  ABI_FREE(cwavef1)
     364         [ -  + ]:         282 :  ABI_FREE(cwavef2)
     365         [ +  + ]:         282 :  if(usepaw==1) then
     366         [ -  + ]:         120 :    if(ibg1/=0)then
     367                 :           0 :      call pawcprj_free(cprj1_k)
     368                 :             :    end if
     369         [ -  + ]:         120 :    if(ibg2/=0)then
     370                 :           0 :      call pawcprj_free(cprj2_k)
     371                 :             :    end if
     372   [ +  -  +  +  :        1080 :    ABI_FREE(cprj1_k)
          -  +  -  +  -  
                      + ]
     373   [ +  -  +  +  :        1080 :    ABI_FREE(cprj2_k)
          -  +  -  +  -  
                      + ]
     374                 :             :  end if
     375                 :             : 
     376   [ -  +  -  -  :         282 : end subroutine dotprod_set_cgcprj
          -  -  -  -  -  
          +  -  -  -  -  
                   -  - ]
     377                 :             : !!***
     378                 :             : 
     379                 :             : !!****f* ABINIT/dotprodm_sumdiag_cgcprj
     380                 :             : !!
     381                 :             : !! NAME
     382                 :             : !! dotprodm_sumdiag_cgcprj
     383                 :             : !!
     384                 :             : !! FUNCTION
     385                 :             : !! For one k point and spinpol, compute the matrix of sum of diagonal scalar products
     386                 :             : !! between sets of nband wavefunctions that are known in the cg+cprj representation
     387                 :             : !! The sets of wavefunctions must be contained in a big array of sets of wavefunctions.
     388                 :             : !! Sij=Sum_m <wfm(set i)|wfm(set j)>
     389                 :             : !!
     390                 :             : !! Can also treat the case of the computation of scalar products within one set of wavefunctions
     391                 :             : !!
     392                 :             : !! This implementation is NOT band-parallelized
     393                 :             : !! Also, it is far of being optimal at the level of linear algebra, and involves extra copying
     394                 :             : !! that are detrimental for performance...
     395                 :             : !!
     396                 :             : !! INPUTS
     397                 :             : !!  atindx1(natom)=index table for atoms, inverse of atindx
     398                 :             : !!  cg_set(2,mcg,mset)= plane wave wavefunction coefficients for several sets of wavefunctions (all k points and spins)
     399                 :             : !!  cprj_set(natom,mcprj,mset) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk>
     400                 :             : !!    with NL projectors in the different sets
     401                 :             : !!  dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
     402                 :             : !!  ibg=shift in cprj_set array to locate current k-point
     403                 :             : !!  icg=shift in cg_set array to locate current k-point
     404                 :             : !!  ikpt=current k point index
     405                 :             : !!  isppol=current spin polarization index
     406                 :             : !!  istwf=input option parameter that describes the storage of wfs
     407                 :             : !!  mband=maximum number of bands (used in the dimensioning of cprj_set)
     408                 :             : !!  mcg=second dimension of cg array (mpw*nspinor*mband*mkmem*nsppol)
     409                 :             : !!  mcprj=second dimension of cprj array
     410                 :             : !!  mkmem=number of k points which can fit in memory
     411                 :             : !!  mpi_enreg=information about MPI parallelization
     412                 :             : !!  mset=third dimension of cg_set and cprj_set, maximum number of sets
     413                 :             : !!  natom=number of atoms
     414                 :             : !!  nattyp(ntypat)=number of atoms of each type in cell.
     415                 :             : !!  nbd=number of bands for each set of wavefunctions
     416                 :             : !!  npw=number of planewaves in basis at this k point
     417                 :             : !!  nset1=number of sets of wavefunctions to be considered in the left side of the scalar products
     418                 :             : !!  nset2=number of sets of wavefunctions to be considered in the right side of the scalar products
     419                 :             : !!  nspinor=number of spinor components
     420                 :             : !!  nsppol=number of spin polarizations
     421                 :             : !!  ntypat=number of types of atoms
     422                 :             : !!  pawtab(dtset%ntypat*dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
     423                 :             : !!  shift_set1=shift that defines the first set of wavefunctions to be considered in the left side of the scalar products
     424                 :             : !!  shift_set2=shift that defines the first set of wavefunctions to be considered in the right side of the scalar products
     425                 :             : !!  usepaw=1 if PAW is activated
     426                 :             : !!
     427                 :             : !! OUTPUT
     428                 :             : !!  smn(2,nset1,nset2)=matrix of sum of diagonal scalar products between the first set
     429                 :             : !!    of wavefunctions and the second set of wavefunctions
     430                 :             : !!
     431                 :             : !! SIDE EFFECTS
     432                 :             : !!
     433                 :             : !! SOURCE
     434                 :             : 
     435                 :          41 : subroutine dotprodm_sumdiag_cgcprj(atindx1,cg_set,cprj_set,dimcprj,&
     436                 :             : & ibg,icg,ikpt,isppol,istwf,mband,mcg,mcprj,mkmem,&
     437                 :          41 : & mpi_enreg,mset,natom,nattyp,nbd,npw,nset1,nset2,nspinor,nsppol,ntypat,&
     438                 :          41 : & shift_set1,shift_set2,pawtab,smn,usepaw)
     439                 :             : 
     440                 :             : !Arguments ------------------------------------
     441                 :             : !scalars
     442                 :             :  integer, intent(in) :: ibg,icg,ikpt,isppol,istwf
     443                 :             :  integer, intent(in) :: mband,mcg,mcprj,mkmem,mset
     444                 :             :  integer, intent(in) :: natom,nbd,npw,nset1,nset2,nspinor,nsppol,ntypat
     445                 :             :  integer, intent(in) :: shift_set1,shift_set2,usepaw
     446                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     447                 :             : !arrays
     448                 :             :  integer, intent(in) :: atindx1(natom),dimcprj(natom),nattyp(ntypat)
     449                 :             :  real(dp), intent(in) :: cg_set(2,mcg,mset)
     450                 :             :  real(dp), intent(out) :: smn(2,nset1,nset2)
     451                 :             :  type(pawcprj_type),intent(in) :: cprj_set(natom,mcprj,mset)
     452                 :             :  type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
     453                 :             : 
     454                 :             : !Local variables-------------------------------
     455                 :             : !scalars
     456                 :             :  integer :: ia,iat,itypat,ibd,icgb,ig,iorder
     457                 :             :  integer :: ilmn1,ilmn2,ind_set1,ind_set2,iset1,iset2,klmn
     458                 :             :  real(dp) :: dotr,doti
     459                 :             : !arrays
     460                 :          41 :  real(dp),allocatable :: cwavef1(:,:),cwavef2(:,:)
     461                 :          41 :  type(pawcprj_type),allocatable :: cprj1_k(:,:),cprj2_k(:,:)
     462                 :             : 
     463                 :             : ! *************************************************************************
     464                 :             : 
     465                 :             : !DEBUG
     466                 :             : !write(std_out,*)' dotprodm_sumdiag_cgcprj : enter '
     467                 :             : !call flush(std_out)
     468                 :             : !ENDDEBUG
     469                 :             : 
     470   [ -  +  +  -  :         123 :  ABI_MALLOC(cwavef1,(2,npw*nspinor))
          +  -  +  -  -  
                +  -  + ]
     471   [ -  +  +  -  :          82 :  ABI_MALLOC(cwavef2,(2,npw*nspinor))
             -  +  -  + ]
     472         [ -  + ]:          41 :  if(usepaw==1) then
     473   [ #  #  #  #  :           0 :    ABI_MALLOC(cprj1_k,(natom,nspinor*nbd))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     474   [ #  #  #  #  :           0 :    ABI_MALLOC(cprj2_k,(natom,nspinor*nbd))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     475                 :           0 :    iorder=0 ! There is no change of ordering in the copy of wavefunctions
     476                 :           0 :    call pawcprj_alloc(cprj1_k,cprj_set(1,1,1)%ncpgr,dimcprj)
     477                 :             :  end if
     478                 :             : 
     479   [ +  +  +  +  :         661 :  smn(:,:,:)=zero
                   +  + ]
     480                 :             : 
     481                 :          41 :  icgb=icg
     482         [ +  + ]:         190 :  do ibd=1,nbd
     483                 :             : 
     484         [ +  + ]:         298 :    do iset1=1,nset1
     485                 :             : 
     486                 :         149 :      ind_set1=iset1+shift_set1
     487                 :             : 
     488                 :             : !    Extract wavefunction information
     489         [ +  + ]:       41581 :      do ig=1,npw*nspinor
     490                 :       41432 :        cwavef1(1,ig)=cg_set(1,ig+icgb,ind_set1)
     491                 :       41581 :        cwavef1(2,ig)=cg_set(2,ig+icgb,ind_set1)
     492                 :             :      end do
     493         [ -  + ]:         149 :      if(usepaw==1) then
     494                 :             :        call pawcprj_get(atindx1,cprj1_k,cprj_set(:,:,ind_set1),natom,1,ibg,ikpt,iorder,isppol,mband,&
     495                 :             : &       mkmem,natom,nbd,nbd,nspinor,nsppol,0,&
     496                 :           0 : &       mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
     497                 :             :      end if
     498                 :             : 
     499         [ +  + ]:         873 :      do iset2=1,nset2
     500                 :             : 
     501                 :         575 :        ind_set2=iset2+shift_set2
     502   [ +  +  +  - ]:         575 :        if(ind_set2<ind_set1 .and. ind_set2>shift_set1)then
     503                 :             :          continue ! These matrix elements have already been computed, the smn matrix will be completed later.
     504                 :             : 
     505         [ +  + ]:         575 :        else if(ind_set1/=ind_set2)then
     506                 :             : 
     507                 :             : !        Extract wavefunction information
     508         [ +  + ]:      106714 :          do ig=1,npw*nspinor
     509                 :      106288 :            cwavef2(1,ig)=cg_set(1,ig+icgb,ind_set2)
     510                 :      106714 :            cwavef2(2,ig)=cg_set(2,ig+icgb,ind_set2)
     511                 :             :          end do
     512                 :             : 
     513         [ -  + ]:         426 :          if(usepaw==1) then
     514                 :             :            call pawcprj_get(atindx1,cprj2_k,cprj_set(:,:,ind_set2),natom,1,ibg,ikpt,iorder,isppol,mband,&
     515                 :             : &           mkmem,natom,nbd,nbd,nspinor,nsppol,0,&
     516                 :           0 : &           mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
     517                 :             :          end if
     518                 :             : 
     519                 :             : !        Calculate Smn=<cg1|cg2>
     520                 :         426 :          call dotprod_g(dotr,doti,istwf,npw*nspinor,2,cwavef1,cwavef2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     521                 :             : 
     522         [ -  + ]:         426 :          if(usepaw==1) then
     523                 :             :            ia =0
     524         [ #  # ]:           0 :            do itypat=1,ntypat
     525         [ #  # ]:           0 :              do iat=1+ia,nattyp(itypat)+ia
     526         [ #  # ]:           0 :                do ilmn1=1,pawtab(itypat)%lmn_size
     527         [ #  # ]:           0 :                  do ilmn2=1,ilmn1
     528                 :           0 :                    klmn=((ilmn1-1)*ilmn1)/2+ilmn2
     529                 :             :                    dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2)+&
     530                 :           0 : &                   cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2))
     531                 :             :                    doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2)-&
     532                 :           0 : &                   cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2))
     533                 :             :                  end do
     534         [ #  # ]:           0 :                  do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
     535                 :           0 :                    klmn=((ilmn2-1)*ilmn2)/2+ilmn1
     536                 :             :                    dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2)+&
     537                 :           0 : &                   cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2))
     538                 :             :                    doti=doti+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj2_k(iat,ibd)%cp(2,ilmn2)-&
     539                 :           0 : &                   cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj2_k(iat,ibd)%cp(1,ilmn2))
     540                 :             :                  end do
     541                 :             :                end do
     542                 :             :              end do
     543                 :           0 :              ia=ia+nattyp(itypat)
     544                 :             :            end do
     545                 :             :          end if ! usepaw
     546                 :             : 
     547                 :             : !      if(.false.)then
     548                 :             :        else
     549                 :             : !        Diagonal part : no need to extract another wavefunction, and the scalar product must be real
     550                 :             : 
     551                 :             : !        Calculate Smn=<cg1|cg1>
     552                 :         149 :          call dotprod_g(dotr,doti,istwf,npw*nspinor,1,cwavef1,cwavef1,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     553                 :             : 
     554         [ -  + ]:         149 :          if(usepaw==1) then
     555                 :             :            ia =0
     556         [ #  # ]:           0 :            do itypat=1,ntypat
     557         [ #  # ]:           0 :              do iat=1+ia,nattyp(itypat)+ia
     558         [ #  # ]:           0 :                do ilmn1=1,pawtab(itypat)%lmn_size
     559         [ #  # ]:           0 :                  do ilmn2=1,ilmn1
     560                 :           0 :                    klmn=((ilmn1-1)*ilmn1)/2+ilmn2
     561                 :             :                    dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj1_k(iat,ibd)%cp(1,ilmn2)+&
     562                 :           0 : &                   cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj1_k(iat,ibd)%cp(2,ilmn2))
     563                 :             :                  end do
     564         [ #  # ]:           0 :                  do ilmn2=ilmn1+1,pawtab(itypat)%lmn_size
     565                 :           0 :                    klmn=((ilmn2-1)*ilmn2)/2+ilmn1
     566                 :             :                    dotr=dotr+pawtab(itypat)%sij(klmn)*(cprj1_k(iat,ibd)%cp(1,ilmn1)*cprj1_k(iat,ibd)%cp(1,ilmn2)+&
     567                 :           0 : &                   cprj1_k(iat,ibd)%cp(2,ilmn1)*cprj1_k(iat,ibd)%cp(2,ilmn2))
     568                 :             :                  end do
     569                 :             :                end do
     570                 :             :              end do
     571                 :           0 :              ia=ia+nattyp(itypat)
     572                 :             :            end do
     573                 :             :          end if ! usepaw
     574                 :         149 :          doti=zero
     575                 :             : 
     576                 :             :        end if ! Compare ind_set1 and ind_set2
     577                 :             : 
     578                 :         575 :        smn(1,iset1,iset2)=smn(1,iset1,iset2)+dotr
     579                 :         724 :        smn(2,iset1,iset2)=smn(2,iset1,iset2)+doti
     580                 :             : 
     581                 :             :      end do ! iset2
     582                 :             :    end do ! iset1
     583                 :             : 
     584                 :             : !  End loop over bands ibd
     585                 :         190 :    icgb=icgb+npw*nspinor
     586                 :             :  end do
     587                 :             : 
     588                 :             : !Complete the matrix, using its hermitian property.
     589         [ +  + ]:          82 :  do iset1=1,nset1
     590                 :          41 :    ind_set1=iset1+shift_set1
     591         [ +  + ]:         237 :    do iset2=1,nset2
     592                 :         155 :      ind_set2=iset2+shift_set2
     593   [ +  +  -  + ]:         196 :      if(ind_set2<ind_set1 .and. ind_set2>shift_set1)then
     594                 :           0 :        smn(1,iset1,iset2)= smn(1,iset2,iset1)
     595                 :           0 :        smn(2,iset1,iset2)=-smn(2,iset2,iset1)
     596                 :             :      end if
     597                 :             :    end do
     598                 :             :  end do
     599                 :             : 
     600         [ -  + ]:          41 :  ABI_FREE(cwavef1)
     601         [ -  + ]:          41 :  ABI_FREE(cwavef2)
     602         [ -  + ]:          41 :  if(usepaw==1) then
     603                 :           0 :    call pawcprj_free(cprj1_k)
     604                 :           0 :    call pawcprj_free(cprj2_k)
     605   [ #  #  #  #  :           0 :    ABI_FREE(cprj1_k)
          #  #  #  #  #  
                      # ]
     606   [ #  #  #  #  :           0 :    ABI_FREE(cprj2_k)
          #  #  #  #  #  
                      # ]
     607                 :             :  end if
     608                 :             : 
     609   [ -  +  -  -  :          41 : end subroutine dotprodm_sumdiag_cgcprj
          -  -  -  -  -  
          +  -  -  -  -  
                   -  - ]
     610                 :             : !!***
     611                 :             : 
     612                 :             : !!****f* ABINIT/lincom_cgcprj
     613                 :             : !!
     614                 :             : !! NAME
     615                 :             : !! lincom_cgcprj
     616                 :             : !!
     617                 :             : !! FUNCTION
     618                 :             : !! For one k point and spin, compute a set (size nband_out) of linear combinations of nband_in wavefunctions,
     619                 :             : !! that are known in the cg+cprj representation :
     620                 :             : !! cgout_n(:,:) <--- Sum_m [ cg_m(:,:) . alpha_mn ]
     621                 :             : !! cprjout_n(:,:) <--- Sum_m [ cprj_m(:,:) . alpha_mn ]
     622                 :             : !! If nband_out is smaller or equal to nband_in, the result might be in-place
     623                 :             : !! output in cg instead of cgout, and in cprj instead of cprjout).
     624                 :             : !! Otherwise, it is contained in the optional cgout+cprjout pair.
     625                 :             : !!
     626                 :             : !! In the present status, the cg and cgout relates to all the k points and spins, and rely on the icg index,
     627                 :             : !! while it is assumed that cprj and cprjout refer to the specific k point and spin.
     628                 :             : !! This is not coherent.
     629                 :             : !! THIS MIGHT BE CHANGED IN THE FUTURE !
     630                 :             : !!
     631                 :             : !! This implementation is NOT band-parallelized
     632                 :             : !! Also, it is far of being optimal at the level of linear algebra, and involves extra copying
     633                 :             : !! that are detrimental for performance...
     634                 :             : !!
     635                 :             : !! INPUTS
     636                 :             : !!  alpha_mn(2,nband_in,nband_out)=complex matrix of coefficients of the linear combinations to be computed
     637                 :             : !!  dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
     638                 :             : !!  icg=shift in cg array to locate current k-point and spinpol (for input, and possibly for in-place output)
     639                 :             : !!  inplace= if 0, output in cgout and cprjout ; if 1, output in cg and cprj
     640                 :             : !!  mcg=second dimension of cg array (mpw*nspinor*mband*mkmem*nsppol)
     641                 :             : !!  mcprj=second dimension of cprj array
     642                 :             : !!  natom=number of atoms
     643                 :             : !!  nband_in=number of bands, size of the input set of wavefunctions
     644                 :             : !!  nband_out=number of bands, size of the output set of wavefunctions (should be equal to nband_in if inplace==1)
     645                 :             : !!  npw=number of planewaves in basis at this k point
     646                 :             : !!  nspinor=number of spinor components
     647                 :             : !!  usepaw=1 if PAW is activated
     648                 :             : !!  [icgout= shift in cgout array to locate current k-point and spinpol (for output)]
     649                 :             : !!  [mcgout=second dimension of cgout array (mpw*nspinor*mband*mkmem*nsppol)]
     650                 :             : !!  [mcprjout=second dimension of cprjout array]
     651                 :             : !!
     652                 :             : !! OUTPUT
     653                 :             : !!  [cgout(2,mcgout)= plane wave wavefunction coefficients for the set of output wavefunctions]
     654                 :             : !!  [cprjout(natom,mcprjout) <type(pawcprj_type)>= projected output wave functions <Proj_i|Cnk> with NL projectors]
     655                 :             : !!
     656                 :             : !! SIDE EFFECTS
     657                 :             : !!  (this quantities are input, and possibly updated output when inplace==1)
     658                 :             : !!  cg(2,mcg)= plane wave wavefunction coefficients for the set of input wavefunctions (all k points and spinpol)
     659                 :             : !!  cprj(natom,mcprj) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors
     660                 :             : !!
     661                 :             : !! SOURCE
     662                 :             : 
     663                 :         564 :  subroutine lincom_cgcprj(alpha_mn,cg,cprj,dimcprj,&
     664                 :             : & icg,inplace,mcg,mcprj,natom,nband_in,nband_out,npw,nspinor,usepaw, &
     665   [ +  +  +  -  :         282 : & cgout,cprjout,icgout) ! optional args
          -  +  +  +  +  
                -  -  + ]
     666                 :             : 
     667                 :             : !Arguments ------------------------------------
     668                 :             : !scalars
     669                 :             :  integer, intent(in) :: icg,inplace,mcg,mcprj
     670                 :             :  integer, intent(in) :: natom,nband_in,nband_out,npw,nspinor,usepaw
     671                 :             :  integer, intent(in),optional :: icgout
     672                 :             : !arrays
     673                 :             :  integer, intent(in) :: dimcprj(natom)
     674                 :             :  real(dp), intent(inout) :: cg(2,mcg)
     675                 :             :  real(dp), intent(in) :: alpha_mn(2,nband_in,nband_out)
     676                 :             :  real(dp), intent(out),optional :: cgout(:,:)
     677                 :             :  type(pawcprj_type),intent(inout) :: cprj(natom,mcprj)
     678                 :             :  type(pawcprj_type),intent(inout),optional :: cprjout(:,:) ! ifort and others are buggy for optional intent(out) structured types
     679                 :             : 
     680                 :             : !Local variables-------------------------------
     681                 :             : !scalars
     682                 :             :  integer :: iband_in,iband_out,ii
     683                 :             : !arrays
     684                 :         282 :  real(dp),allocatable :: al(:,:),cgout_(:,:)
     685                 :         282 :  type(pawcprj_type),allocatable :: cprjout_(:,:)
     686                 :             : 
     687                 :             : ! *************************************************************************
     688                 :             : 
     689                 :             : !DEBUG
     690                 :             : !write(std_out,*)' lincom_cgcprj : enter '
     691                 :             : !write(std_out,*)' lincom_cgcprj : npw, nspinor=',npw,nspinor
     692                 :             : !write(std_out,*)' lincom_cgcprj : icgout=',icgout
     693                 :             : !ENDDEBUG
     694                 :             : 
     695         [ +  + ]:         282 :  if(inplace==0)then
     696         [ -  + ]:          36 :    if(.not.present(cgout))then
     697                 :           0 :      ABI_ERROR(' inplace==0 while .not.present(cgout) is not permitted ')
     698                 :             :    end if
     699         [ -  + ]:          36 :    if(usepaw==1) then
     700         [ #  # ]:           0 :      if(.not.present(cprjout))then
     701                 :           0 :        ABI_ERROR(' inplace==0 and usepaw==1 while .not.present(cprjout) is not permitted ')
     702                 :             :      end if
     703                 :             :    end if
     704                 :             :  end if
     705                 :             : 
     706                 :             : !Take care of the plane wave part
     707   [ -  +  +  -  :         846 :  ABI_MALLOC(cgout_,(2,npw*nspinor*nband_out))
          +  -  +  -  -  
                +  -  + ]
     708                 :             : 
     709                 :             :  call zgemm('N','N',npw*nspinor,nband_out,nband_in,dcmplx(1._dp), &
     710                 :             : & cg(:,icg+1:icg+npw*nspinor*nband_in),npw*nspinor, &
     711                 :         282 : & alpha_mn,nband_in,dcmplx(0._dp),cgout_,npw*nspinor)
     712                 :             : 
     713         [ +  + ]:         282 :  if(inplace==1)then
     714   [ +  +  +  + ]:      483294 :    cg(:,icg+1:icg+npw*nspinor*nband_out)=cgout_
     715                 :             :  else
     716   [ +  +  +  + ]:      106500 :    cgout(:,icgout+1:icgout+npw*nspinor*nband_out)=cgout_
     717                 :             :  end if
     718         [ -  + ]:         282 :  ABI_FREE(cgout_)
     719                 :             : 
     720                 :             : !Take care of the cprj part
     721         [ +  + ]:         282 :  if(usepaw==1) then
     722                 :             : 
     723   [ -  +  +  -  :        1920 :    ABI_MALLOC(cprjout_,(natom,nspinor*nband_out))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     724                 :         120 :    call pawcprj_alloc(cprjout_,cprj(1,1)%ncpgr,dimcprj)
     725   [ -  +  +  -  :         360 :    ABI_MALLOC(al,(2,nband_in))
          +  -  +  -  -  
                +  +  - ]
     726         [ +  + ]:         600 :    do iband_out=1,nband_out
     727                 :         480 :      ii=(iband_out-1)*nspinor
     728         [ +  + ]:        2400 :      do iband_in=1,nband_in
     729                 :        1920 :        al(1,iband_in)=alpha_mn(1,iband_in,iband_out)
     730                 :        2400 :        al(2,iband_in)=alpha_mn(2,iband_in,iband_out)
     731                 :             :      end do
     732                 :         600 :      call pawcprj_lincom(al,cprj,cprjout_(:,ii+1:ii+nspinor),nband_in)
     733                 :             :    end do
     734         [ -  + ]:         120 :    ABI_FREE(al)
     735                 :             : 
     736         [ +  - ]:         120 :    if(inplace==1)then
     737   [ +  +  +  +  :        1560 :      cprj=cprjout_
          +  -  +  -  -  
          +  +  -  +  -  
                   -  + ]
     738                 :             :    else
     739   [ #  #  #  #  :           0 :      cprjout=cprjout_
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     740                 :             :    end if
     741                 :         120 :    call pawcprj_free(cprjout_)
     742   [ +  -  +  +  :        1080 :    ABI_FREE(cprjout_)
          -  +  -  +  -  
                      + ]
     743                 :             : 
     744                 :             :  end if
     745                 :             : 
     746   [ -  +  -  -  :         282 : end subroutine lincom_cgcprj
             -  -  -  - ]
     747                 :             : !!***
     748                 :             : 
     749                 :             : !!****m* ABINIT/cgcprj_cholesky
     750                 :             : !! NAME
     751                 :             : !!  cgcprj_cholesky
     752                 :             : !!
     753                 :             : !! FUNCTION
     754                 :             : !! Cholesky orthonormalization of the vectors stored in cg+cprj mode.
     755                 :             : !!
     756                 :             : !! This implementation is NOT band-parallelized
     757                 :             : !! Also, it is far of being optimal at the level of linear algebra
     758                 :             : !!
     759                 :             : !! INPUTS
     760                 :             : !!  atindx1(natom)=index table for atoms, inverse of atindx
     761                 :             : !!  dimcprj(natom)=number of lmn components in the <p_{lmn}^i|\psi> for the i-th atom
     762                 :             : !!  icg=shift in cg array to locate current k-point and spinpol
     763                 :             : !!  ikpt=current k point index
     764                 :             : !!  isppol=current spin polarization index
     765                 :             : !!  istwf=input option parameter that describes the storage of wfs
     766                 :             : !!  mcg=second dimension of cg array (mpw*nspinor*mband*mkmem*nsppol)
     767                 :             : !!  mcprj=second dimension of cprj_k array
     768                 :             : !!  mkmem=number of k points which can fit in memory
     769                 :             : !!  mpi_enreg=information about MPI parallelization
     770                 :             : !!  natom=number of atoms
     771                 :             : !!  nattyp(ntypat)=number of atoms of each type in cell.
     772                 :             : !!  nband=number of bands
     773                 :             : !!  npw=number of planewaves in basis at this k point
     774                 :             : !!  nspinor=number of spinor components
     775                 :             : !!  nsppol=number of spin polarizations
     776                 :             : !!  ntypat=number of types of atoms
     777                 :             : !!  pawtab(dtset%ntypat*dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
     778                 :             : !!  usepaw=1 if PAW is activated
     779                 :             : !!
     780                 :             : !! SIDE EFFECTS
     781                 :             : !!  cg(2,mcg)= plane wave wavefunction coefficients for the set of input wavefunctions (all k points and spinpol)
     782                 :             : !!  cprj_k(natom,mcprj) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors for the specific k point and spinpol
     783                 :             : !!
     784                 :             : !! SOURCE
     785                 :             : 
     786                 :         141 :  subroutine cgcprj_cholesky(atindx1,cg,cprj_k,dimcprj,icg,ikpt,isppol,istwf,mcg,mcprj,mkmem,&
     787                 :         141 : &  mpi_enreg,natom,nattyp,nband,npw,nspinor,nsppol,ntypat,pawtab,usepaw)
     788                 :             : 
     789                 :             : !Arguments ------------------------------------
     790                 :             : !scalars
     791                 :             :  integer,intent(in) :: icg,ikpt,isppol,istwf,mcg,mcprj,mkmem
     792                 :             :  integer,intent(in) :: natom,nband,npw,nspinor,nsppol,ntypat,usepaw
     793                 :             : !arrays
     794                 :             :  integer, intent(in) :: atindx1(natom),dimcprj(natom),nattyp(ntypat)
     795                 :             :  real(dp), intent(inout) :: cg(2,mcg)
     796                 :             :  type(pawcprj_type),intent(inout) :: cprj_k(natom,mcprj)
     797                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     798                 :             :  type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
     799                 :             : 
     800                 :             : !Local variables ------------------------------
     801                 :             : !scalars
     802                 :             :  integer :: hermitian,ierr,ii,inplace
     803                 :             : !arrays
     804                 :         141 :  real(dp), allocatable :: dmn(:,:,:),smn(:,:,:)
     805                 :             : 
     806                 :             : ! *************************************************************************
     807                 :             : 
     808   [ -  +  +  -  :         564 :  ABI_MALLOC(smn,(2,nband,nband))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     809   [ -  +  +  -  :         423 :  ABI_MALLOC(dmn,(2,nband,nband))
          -  +  +  -  -  
                +  -  + ]
     810                 :             : 
     811                 :         141 :  hermitian=1
     812                 :             :  call dotprod_set_cgcprj(atindx1,cg,cg,cprj_k,cprj_k,dimcprj,hermitian,&
     813                 :             : & 0,0,icg,icg,ikpt,isppol,istwf,nband,mcg,mcg,mcprj,mcprj,mkmem,&
     814                 :         141 : & mpi_enreg,natom,nattyp,nband,nband,npw,nspinor,nsppol,ntypat,pawtab,smn,usepaw)
     815                 :             : 
     816                 :             : !Cholesky factorization: O = U^H U with U upper triangle matrix.
     817                 :         141 :  call ZPOTRF('U',nband,smn,nband,ierr)
     818                 :             : 
     819                 :             : !Solve X U = 1.
     820   [ +  +  +  +  :        7233 :  dmn=zero
                   +  + ]
     821         [ +  + ]:         690 :  do ii=1,nband
     822                 :         690 :    dmn(1,ii,ii)=one
     823                 :             :  end do
     824                 :         141 :  call ZTRSM('Right','Upper','Normal','Normal',nband,nband,cone,smn,nband,dmn,nband)
     825                 :             : 
     826                 :         141 :  inplace=1
     827                 :             : !This call does not take into account the fact that X=dmn is an upper triangular matrix...
     828                 :             : !The number of operations might be divided by two.
     829                 :             :  call lincom_cgcprj(dmn,cg,cprj_k,dimcprj,&
     830                 :         141 : & icg,inplace,mcg,mcprj,natom,nband,nband,npw,nspinor,usepaw)
     831                 :             : 
     832         [ -  + ]:         141 :  ABI_FREE(smn)
     833         [ -  + ]:         141 :  ABI_FREE(dmn)
     834                 :             : 
     835                 :         141 : end subroutine cgcprj_cholesky
     836                 :             : !!***
     837                 :             : 
     838                 :             : end module m_cgcprj
     839                 :             : !!***
        

Generated by: LCOV version 2.3-1