TABLE OF CONTENTS


ABINIT/eig2stern [ Functions ]

[ Top ] [ Functions ]

NAME

 eig2stern

FUNCTION

 This routine calculates the second-order eigenvalues.
 The output eig2nkq is this quantity for the input k points.

INPUTS

  bdeigrf = number of bands for which to calculate the second-order eigenvalues.
  clflg(3,mpert)= array on calculated perturbations for eig2rf.
  dim_eig2nkq = 1 if eig2nkq is to be computed.
  cg1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol,3,mpert) = first-order wf in G
            space for each perturbation. The wavefunction is orthogonal to the
            active space.
  gh0c1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol,3,mpert) = matrix containing the
            vector:  <G|H(0)|psi(1)>, for each perturbation.
  gh1c_pert(2,mpw1*nspinor*mband*mk1mem*nsppol,3,mpert)) = matrix containing the
            vector:  <G|H(1)|n,k>, for each perturbation. The wavefunction is
            orthogonal to the active space.
  eigbrd(2,mband*nsppol,nkpt,3,natom,3,natom) = broadening factors for the
            electronic eigenvalues (optional).
  eigen0(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all K-points:
            <k,n'|H(0)|k,n'> (hartree).
  eigenq(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all shifted K-points:
            <k+Q,n'|H(0)|k+Q,n'> (hartree).
  eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert) = matrix of first-order:
            <k+Q,n'|H(1)|k,n> (hartree) (calculated in dfpt_cgwf).
  eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq) = second derivatives of
            the electronic eigenvalues.
  elph2_imagden = imaginary part of the denominator of the sum-over-state expression
            for the electronic eigenenergy shift due to second-order electron-phonon
            interation.
  ieig2rf = integer for calculation type.
  indsym(4,nsym,natom) = indirect indexing array for atom labels
            (not used yet, but will be used with symmetries).
  istwfk_pert(nkpt_rbz,3,mpert) = integer for choice of storage of wavefunction at
            each k point for each perturbation.
  mband = maximum number of bands.
  mk1mem = maximum number of k points which can fit in memory (RF data);
            0 if use disk.
  mpert = maximum number of perturbations.
  natom = number of atoms in the unit cell.
  npert = number of phonon perturbations, without taking into account directions:
            natom.
  nsym = number of symmetries (not used yet).
  mpi_enreg = information about MPI parallelization.
  mpw1 = maximum number of planewaves used to represent first-order wavefunctions.
  nkpt_rbz = number of k-points for each perturbation.
  npwar1(nkpt_rbz,mpert) = number of planewaves at k-point for first-order.
  nspinor = number of spinorial components of the wavefunctions.
  nsppol = 1 for unpolarized, 2 for spin-polarized.
  occ(mband*nkpt*nsppol)=occup number for each band (often 2) at each k point
  smdelta = integer controling the calculation of electron lifetimes.
  symq(4,2,nsym) = 1 if symmetry preserves present qpoint. From littlegroup_q (not used yet).
  symrec(3,3,nsym) = 3x3 matrices of the group symmetries (reciprocal space)
            (not used yet).
  symrel(3,3,nsym) = array containing the symmetries in real space (not used yet).
  timrev = 1 if time-reversal preserves the q wavevector; 0 otherwise
            (not in use yet).
  dtset = OPTIONAL, dataset structure containing the input variable of the
            calculation. This is required to use the k-interpolation routine.
  eigenq_fine(mband_fine,mkpt_fine,nsppol_fine) = OPTIONAL, 0-order eigenvalues
            at all shifted K-points: <k+Q,n'|H(0)|k+Q,n'> (hartree) of the
            fine grid. This information is read from the WF dense k-grid file.
  hdr_fine = OPTIONAL, header of the WF file of the fine k-point grid. This
            variable is required for the k-interpolation routine.
  hdr0     = OPTIONAL, header of the GS WF file of the corse k-point grid. This
            variable is required for the k-interpolation routine.

OUTPUT

  eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= diagonal part of the
            second-order eigenvalues: E^{(2),diag}_{k,q,j}.
  eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= OPTIONAL, array containing the
            electron lifetimes.

SOURCE

 731 subroutine eig2stern(occ,bdeigrf,clflg,cg1_pert,dim_eig2nkq,dim_eig2rf,eigen0,eigenq,&
 732 &  eigen1,eig2nkq,elph2_imagden,esmear,gh0c1_pert,gh1c_pert,ieig2rf,istwfk_pert,&
 733 &  mband,mk1mem,mpert,npert,mpi_enreg,mpw1,nkpt_rbz,npwar1,nspinor,nsppol,smdelta,&
 734 &  dtset,eigbrd,eigenq_fine,hdr_fine,hdr0)
 735 
 736 !Arguments ------------------------------------
 737 !scalars
 738  integer,intent(in) :: bdeigrf,dim_eig2nkq,dim_eig2rf,ieig2rf,mband,mk1mem,mpert,mpw1,nkpt_rbz
 739  integer,intent(in) :: npert,nspinor,nsppol,smdelta
 740  real(dp),intent(in) :: elph2_imagden,esmear
 741  type(MPI_type),intent(inout) :: mpi_enreg
 742 !arrays
 743  integer,intent(in) :: clflg(3,mpert)
 744  integer,intent(in) :: istwfk_pert(nkpt_rbz,3,mpert)
 745  integer,intent(in) :: npwar1(nkpt_rbz,mpert)
 746  real(dp),intent(in) :: cg1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol*dim_eig2rf,3,mpert)
 747  real(dp),intent(in) :: gh0c1_pert(2,mpw1*nspinor*mband*mk1mem*nsppol*dim_eig2rf,3,mpert)
 748  real(dp),intent(in) :: gh1c_pert(2,mpw1*nspinor*mband*mk1mem*nsppol*dim_eig2rf,3,mpert)
 749  real(dp),intent(inout) :: eigen0(nkpt_rbz*mband*nsppol)
 750  real(dp),intent(in) :: eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert)
 751  real(dp),intent(inout) :: eigenq(nkpt_rbz*mband*nsppol)
 752  real(dp),intent(out) :: eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert*dim_eig2nkq)
 753  real(dp),intent(out),optional :: eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)
 754  real(dp),intent(in),pointer,optional :: eigenq_fine(:,:,:)
 755  real(dp), intent(in) :: occ(mband*nkpt_rbz*nsppol)
 756  type(dataset_type), intent(in) :: dtset
 757  type(hdr_type),intent(in),optional :: hdr_fine,hdr0
 758 
 759 !Local variables-------------------------------
 760 !tolerance for non degenerated levels
 761 !scalars
 762  integer :: band2tot_index,band_index,bandtot_index,iband,icg2,idir1,idir2
 763  integer :: ikpt,ipert1,ipert2,isppol,istwf_k,jband,npw1_k,nkpt_sub,ikpt2
 764 !integer :: ipw
 765  integer :: master,me,spaceworld,ierr
 766  integer :: mband_mem
 767 !real(dp),parameter :: etol=1.0d-3
 768  real(dp),parameter :: etol=1.0d-6
 769 !real(dp),parameter :: etol=zero
 770  real(dp) :: ar,ai,deltae,den,dot2i,dot2r,dot3i,dot3r,doti,dotr,eig1_i1,eig1_i2
 771  real(dp) :: eig1_r1,eig1_r2,eig2_diai,den_av
 772  real(dp) :: wgt_int
 773  real(dp) :: eig2_diar,eigbrd_i,eigbrd_r
 774  character(len=500) :: message
 775  character(len=500) :: msg
 776 !DBSP
 777 ! character(len=300000) :: message2
 778 !END
 779  logical :: test_do_band
 780 !arrays
 781  integer, allocatable :: nband_rbz(:),icg2_rbz(:,:)
 782  integer,pointer      :: kpt_fine_sub(:)
 783  real(dp)             :: tsec(2)
 784  real(dp),allocatable :: cwavef(:,:),cwavef2(:,:),center(:),eigen0tmp(:),eigenqtmp(:)
 785  real(dp) :: eigen(mband*nsppol),eigen_prime(mband*nsppol)
 786  real(dp),allocatable :: gh(:,:),gh1(:,:),ghc(:,:)
 787  real(dp),allocatable :: smdfun(:,:)
 788  real(dp),pointer     :: wgt_sub(:)
 789 
 790 ! *********************************************************************
 791 
 792 !Init parallelism
 793  master =0
 794  spaceworld=mpi_enreg%comm_cell
 795  me=mpi_enreg%me_kpt
 796 
 797 !Init interpolation method
 798  if(present(eigenq_fine))then
 799    ABI_MALLOC(center,(3))
 800  end if
 801 
 802  call timab(148,1,tsec)
 803 
 804  if(nsppol==2)then
 805    message = 'nsppol=2 is still under development. Be careful when using it ...'
 806    ABI_COMMENT(message)
 807  end if
 808 
 809  band2tot_index =0
 810  bandtot_index=0
 811  band_index=0
 812 
 813 !Add scissor shift to eigenenergies
 814  if (dtset%dfpt_sciss > tol6 ) then
 815    write(msg,'(a,f7.3,2a)')&
 816 &   ' A scissor operator of ',dtset%dfpt_sciss*Ha_eV,' [eV] has been applied to the eigenenergies',ch10
 817    call wrtout(std_out,msg,'COLL')
 818    call wrtout(ab_out,msg,'COLL')
 819    ABI_MALLOC(eigen0tmp,(nkpt_rbz*mband*nsppol))
 820    ABI_MALLOC(eigenqtmp,(nkpt_rbz*mband*nsppol))
 821    eigen0tmp =   eigen0(:)
 822    eigenqtmp =   eigenq(:)
 823    eigen0 = zero
 824    eigenq = zero
 825  end if
 826 
 827  if(ieig2rf > 0) then
 828    eig2nkq(:,:,:,:,:,:,:) = zero
 829  end if
 830  if(present(eigbrd))then
 831    eigbrd(:,:,:,:,:,:,:) = zero
 832  end if
 833 
 834  if(xmpi_paral==1) then
 835    ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt_rbz,mband,nsppol))
 836    ABI_MALLOC(nband_rbz,(nkpt_rbz*nsppol))
 837    if (allocated(mpi_enreg%my_kpttab)) then
 838      ABI_FREE(mpi_enreg%my_kpttab)
 839    end if
 840    ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt_rbz))
 841 !  Assume the number of bands is the same for all k points.
 842    nband_rbz(:)=mband
 843    call distrb2(mband,mband_mem,nband_rbz,nkpt_rbz,mpi_enreg%nproc_cell,nsppol,mpi_enreg)
 844  end if
 845 
 846  icg2=0
 847  ipert1=1 ! Suppose that the situation is the same for all perturbations
 848  ABI_MALLOC(icg2_rbz,(nkpt_rbz,nsppol))
 849  do isppol=1,nsppol
 850    do ikpt=1,nkpt_rbz
 851      icg2_rbz(ikpt,isppol)=icg2
 852      if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,me)) cycle
 853      icg2 = icg2 + npwar1(ikpt,ipert1)*nspinor*mband
 854    end do
 855  end do
 856 
 857  do isppol=1,nsppol
 858    do ikpt =1,nkpt_rbz
 859 
 860      if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,me)) then
 861        band2tot_index = band2tot_index + 2*mband**2
 862        bandtot_index = bandtot_index + mband
 863        cycle
 864      end if
 865 
 866      if(present(eigenq_fine))then
 867        write(std_out,*) 'Start of the energy denominator interpolation method.'
 868        nkpt_sub = 0
 869 !      center is the k+q point around which we will average the kpt_fine
 870        center = hdr0%kptns(:,ikpt)+ dtset%qptn(:)
 871 
 872        call kptfine_av(center,dtset%qptrlatt,hdr_fine%kptns,hdr_fine%nkpt,kpt_fine_sub,nkpt_sub,wgt_sub)
 873        write(std_out,'(a,3f8.4,a,i3)') 'Number of k-points of the fine grid &
 874 &       around the k+Q point ',center,' is:',nkpt_sub
 875        write(std_out,'(a,f10.5)') 'The sum of the weights of the k-points is: ',SUM(wgt_sub)
 876      end if
 877 
 878 !    Add scissor shift to eigenenergies
 879      if (dtset%dfpt_sciss > tol6 ) then
 880        do iband=1,mband
 881          if (occ(iband+bandtot_index) < tol6) then
 882            eigen0(iband+bandtot_index) = eigen0tmp(iband+bandtot_index) + dtset%dfpt_sciss
 883            eigenq(iband+bandtot_index) = eigenqtmp(iband+bandtot_index) + dtset%dfpt_sciss
 884          else
 885            eigen0(iband+bandtot_index) = eigen0tmp(iband+bandtot_index)
 886            eigenq(iband+bandtot_index) = eigenqtmp(iband+bandtot_index)
 887          end if
 888        end do
 889      end if
 890 
 891 
 892      if(smdelta >0) then   !broadening
 893        if(.not.allocated(smdfun))  then
 894          ABI_MALLOC(smdfun,(mband,mband))
 895        end if
 896        smdfun(:,:) = zero
 897        do iband=1,mband
 898          eigen(iband) = eigen0(iband+bandtot_index)
 899          eigen_prime(iband) =eigenq(iband+bandtot_index)
 900        end do
 901        if(esmear>tol6) then
 902          call smeared_delta(eigen,eigen_prime,esmear,mband,smdelta,smdfun)
 903        end if
 904      end if
 905      icg2=icg2_rbz(ikpt,isppol)
 906 
 907      ipert1=1 ! Suppose all perturbations lead to the same number of planewaves
 908      npw1_k = npwar1(ikpt,ipert1)
 909      ABI_MALLOC(cwavef,(2,npw1_k*nspinor))
 910      ABI_MALLOC(cwavef2,(2,npw1_k*nspinor))
 911      ABI_MALLOC(gh,(2,npw1_k*nspinor))
 912      ABI_MALLOC(gh1,(2,npw1_k*nspinor))
 913      ABI_MALLOC(ghc,(2,npw1_k*nspinor))
 914 
 915      do iband=1,bdeigrf
 916 
 917 !      If the k point and band belong to me, compute the contribution
 918        test_do_band=.true.
 919        if(mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me)test_do_band=.false.
 920 
 921        if(test_do_band)then
 922 
 923          do ipert1=1,npert
 924 
 925            do idir1=1,3
 926              if(clflg(idir1,ipert1)==0)cycle
 927              istwf_k = istwfk_pert(ikpt,idir1,ipert1)
 928 
 929              do ipert2=1,npert
 930                do idir2=1,3
 931                  if(clflg(idir2,ipert2)==0)cycle
 932 
 933                  eig2_diar = zero ; eig2_diai = zero ; eigbrd_r = zero ; eigbrd_i = zero
 934 
 935                  do jband=1,mband
 936                    eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
 937                    eig1_r2 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir2,ipert2)
 938                    eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
 939                    eig1_i2 = - eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir2,ipert2) !the negative sign is from the CC
 940 !                  If no interpolation, fallback on to the previous
 941 !                  implementation
 942                    if(.not. present(eigenq_fine))then
 943                      deltae=eigenq(jband+bandtot_index)-eigen0(iband+bandtot_index)
 944                    end if
 945                    ar=eig1_r1*eig1_r2-eig1_i1*eig1_i2
 946                    ai=eig1_r1*eig1_i2+eig1_i1*eig1_r2
 947 
 948 !                  Sum over all active space to retrieve the diagonal gauge
 949                    if(ieig2rf == 1 .or. ieig2rf ==2 ) then
 950 !                    if(abs(deltae)>etol) then ! This is commented because
 951 !                    there is no problem with divergencies with elph2_imag != 0
 952                      if( present(eigenq_fine))then
 953                        den_av = zero
 954                        wgt_int = zero
 955                        do ikpt2=1,nkpt_sub
 956                          deltae=eigenq_fine(jband,kpt_fine_sub(ikpt2),1)&
 957 &                         -eigen0(iband+bandtot_index)
 958                          den_av = den_av-(wgt_sub(ikpt2)*deltae)/(deltae**2+elph2_imagden**2)
 959                          wgt_int = wgt_int+wgt_sub(ikpt2)
 960                        end do
 961                        den = den_av/wgt_int
 962                      else
 963                        if(abs(elph2_imagden) < etol) then
 964                          if(abs(deltae)>etol) then
 965                            den=-one/(deltae**2+elph2_imagden**2)
 966                          else
 967                            den= zero
 968                          end if
 969                        else
 970                          den=-one/(deltae**2+elph2_imagden**2)
 971                        end if
 972                      end if
 973 
 974 !                    The following should be the most general implementation of the presence of elph2_imagden
 975 !                    eig2_diar=eig2_diar+(ar*deltae+ai*elph2_imagden)*den
 976 !                    eig2_diai=eig2_diai+(ai*deltae-ar*elph2_imagden)*den
 977 !                    This gives back the implementation without elph2_imagden
 978 !                    eig2_diar=eig2_diar+ar*deltae*den
 979 !                    eig2_diai=eig2_diai+ai*deltae*den
 980 !                    This is what Samuel had implemented
 981 !                    eig2_diar=eig2_diar+ar*deltae*den
 982 !                    eig2_diai=eig2_diai+ai*elph2_imagden*den
 983 !                    Other possibility : throw away the broadening part, that is actually treated separately.
 984                      if( present(eigenq_fine))then
 985                        eig2_diar=eig2_diar+ar*den
 986                        eig2_diai=eig2_diai+ai*den
 987                      else
 988                        eig2_diar=eig2_diar+ar*deltae*den
 989                        eig2_diai=eig2_diai+ai*deltae*den
 990 !DBSP
 991 !                       if (iband+band_index==2 .and. ikpt==1 .and. idir1==1 .and. ipert1==1 .and. idir2==1 .and. ipert2==1) then
 992 !                         write(message2,*) 'eig2_diar1=',eig2_diar,' ar=',ar,' deltae=',deltae,' den=',den
 993 !                         call wrtout(std_out,message2,'PERS')
 994 !                       endif
 995 !END
 996 
 997                      end if
 998                    end if ! ieig2rf==1 or 2
 999 
1000                    if(present(eigbrd))then
1001                      if(smdelta >0) then   !broadening
1002                        eigbrd_r = eigbrd_r + ar*smdfun(iband,jband)
1003                        eigbrd_i = eigbrd_i + ai*smdfun(iband,jband)
1004                      end if
1005                    end if
1006 
1007                  end do !jband
1008 
1009 !                Add the contribution of non-active bands, if DFPT calculation (= Sternheimer)
1010                  if(ieig2rf == 1 .or. ieig2rf ==3 .or. ieig2rf ==4 .or. ieig2rf==5 ) then
1011 !                  if(ieig2rf == 1   ) then
1012 
1013                    dotr=zero ; doti=zero
1014                    dot2r=zero ; dot2i=zero
1015                    dot3r=zero ; dot3i=zero
1016 
1017 
1018                    cwavef(:,:) = cg1_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir2,ipert2)
1019                    cwavef2(:,:)= cg1_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir1,ipert1)
1020                    gh1(:,:)    = gh1c_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir1,ipert1)
1021                    gh(:,:)     = gh1c_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir2,ipert2)
1022                    ghc(:,:)    = gh0c1_pert(:,1+(iband-1)*npw1_k*nspinor+icg2:iband*npw1_k*nspinor+icg2,idir1,ipert1)
1023 
1024 !                  The first two dotprod corresponds to:  <Psi(1)nkq|H(1)k+q,k|Psi(0)nk> and <Psi(0)nk|H(1)k,k+q|Psi(1)nkq>
1025 !                  They are calculated using wavefunctions <Psi(1)| that are orthogonal to the active space.
1026                    call dotprod_g(dotr,doti,istwf_k,npw1_k*nspinor,2,cwavef,gh1,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
1027                    call dotprod_g(dot2r,dot2i,istwf_k,npw1_k*nspinor,2,gh,cwavef2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
1028 
1029 !                  This dotprod corresponds to : <Psi(1)nkq|H(0)k+q- E(0)nk|Psi(1)nkq>
1030 !                  It is calculated using wavefunctions that are orthogonal to the active space.
1031 !                  Should work for metals. (But adiabatic approximation is bad in this case...)
1032                    call dotprod_g(dot3r,dot3i,istwf_k,npw1_k*nspinor,2,cwavef,ghc,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
1033 
1034                    eig2_diar= eig2_diar + dotr + dot2r + dot3r
1035                    eig2_diai= eig2_diai + doti + dot2i + dot3i
1036 
1037                  end if
1038 
1039 !                Store the contribution
1040                  if(ieig2rf > 0) then
1041                    eig2nkq(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eig2_diar
1042                    eig2nkq(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eig2_diai
1043                  end if
1044 
1045                  if(present(eigbrd))then
1046                    if(smdelta >0) then   !broadening
1047                      eigbrd(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_r
1048                      eigbrd(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_i
1049                    end if
1050                  end if
1051 
1052                end do !idir2
1053              end do !ipert2
1054            end do  !idir1
1055          end do   !ipert1
1056 
1057        end if ! Selection of processor
1058 
1059      end do !iband
1060 
1061      ABI_FREE(cwavef)
1062      ABI_FREE(cwavef2)
1063      ABI_FREE(gh)
1064      ABI_FREE(gh1)
1065      ABI_FREE(ghc)
1066      band2tot_index = band2tot_index + 2*mband**2
1067      bandtot_index = bandtot_index + mband
1068 
1069      if(present(eigenq_fine))then
1070        ABI_FREE(kpt_fine_sub) ! Deallocate the variable
1071        ABI_FREE(wgt_sub)
1072      end if
1073 
1074    end do    !ikpt
1075    band_index = band_index + mband
1076  end do !isppol
1077 
1078 !Accumulate eig2nkq and/or eigbrd
1079  if(xmpi_paral==1) then
1080    if(ieig2rf == 1 .or. ieig2rf == 2) then
1081      call xmpi_sum(eig2nkq,spaceworld,ierr)
1082      if (dtset%dfpt_sciss > tol6 ) then
1083        call xmpi_sum(eigen0,spaceworld,ierr)
1084        call xmpi_sum(eigenq,spaceworld,ierr)
1085      end if
1086    end if
1087    if(present(eigbrd) .and. (ieig2rf == 1 .or. ieig2rf == 2))then
1088      if(smdelta >0) then
1089        call xmpi_sum(eigbrd,spaceworld,ierr)
1090      end if
1091    end if
1092    ABI_FREE(nband_rbz)
1093    ABI_FREE(mpi_enreg%proc_distrb)
1094    ABI_FREE(mpi_enreg%my_kpttab)
1095  end if
1096 
1097  if(ieig2rf==1 .or. ieig2rf==2 ) then
1098    write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGR2D.'
1099    write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1100    do idir1=1,3
1101      do idir2=1,3
1102        ar=eig2nkq(1,1,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1103        ai=eig2nkq(2,1,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1104        write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1105      end do ! idir2
1106    end do ! idir1
1107  end if
1108 
1109  if(present(eigbrd))then
1110    if(smdelta >0) then   !broadening
1111      write(ab_out,'(a)')' '
1112      write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGI2D.'
1113      write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1114      do idir1=1,3
1115        do idir2=1,3
1116          ar=eigbrd(1,1,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1117          ai=eigbrd(2,1,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1118          write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1119        end do
1120      end do !nband
1121    end if
1122  end if
1123 
1124  if(allocated(smdfun))  then
1125    ABI_FREE(smdfun)
1126  end if
1127  ABI_FREE(icg2_rbz)
1128  if(present(eigenq_fine))then
1129    ABI_FREE(center)
1130  end if
1131  if (dtset%dfpt_sciss > tol6 ) then
1132    ABI_FREE(eigen0tmp)
1133    ABI_FREE(eigenqtmp)
1134  end if
1135 
1136  call timab(148,2,tsec)
1137 
1138 end subroutine eig2stern

ABINIT/m_eig2d [ Modules ]

[ Top ] [ Modules ]

NAME

  m_eig2d

FUNCTION

  This module contains utilities to analyze and retrieve information
  from the second order derivative of the eigen-energies wrt
  displacements.

COPYRIGHT

 Copyright (C) 2014-2024 ABINIT group (SP, PB, XG)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

18 #if defined HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "abi_common.h"
23 
24 MODULE m_eig2d
25 
26  use defs_basis
27  use m_errors
28  use m_abicore
29  use m_nctk
30 #ifdef HAVE_NETCDF
31  use netcdf
32 #endif
33  use m_xmpi
34  use m_ebands
35  use m_cgtools
36  use m_hdr
37  use m_dtset
38  use m_dtfil
39  use m_ddb_hdr
40  use m_ddb
41 
42  use defs_datatypes, only : pseudopotential_type, ebands_t
43  use defs_abitypes, only : MPI_type
44  use m_time,       only : timab
45  use m_fstrings,   only : strcat
46  use m_crystal,    only : crystal_init,  crystal_t
47  use m_pawtab,     only : pawtab_type
48  use m_double_grid,only : kptfine_av
49  use m_mpinfo,     only : distrb2, proc_distrb_cycle
50 
51  implicit none
52 
53  private
54 
55  public :: eigr2d_init              ! Main creation method of EIG2D.nc files.
56  public :: eigr2d_ncwrite           ! Dump the object into NETCDF file.
57  public :: eigr2d_free              ! Destruction method.
58  public :: fan_init                 ! Main creation method of Fan.nc files.
59  public :: fan_ncwrite              ! Dump the object into NETCDF file.
60  public :: fan_free                 ! Destruction method.
61  public :: gkk_init                 ! Main creation method of GKK.nc files.
62  public :: gkk_ncwrite              ! Dump the object into NETCDF file.
63  public :: gkk_free                 ! Destruction method.
64 
65  public :: eig2tot                  ! This routine calculates the second-order eigenvalues.
66  public :: outbsd                   ! output bsd file for one perturbation (used for elphon calculations in anaddb)
67  public :: eig2stern
68  public :: elph2_fanddw             ! Calculates the zero-point motion corrections

m-eig2d/smeared_delta [ Functions ]

[ Top ] [ Functions ]

NAME

 smeared_delta

FUNCTION

 This subroutine calculates the smeared delta that weights matrix elements:
 \delta (\epsilon_{kn}-\epsilon_{k+Q,n'})

INPUTS

 eigen0(mband*nsppol) : Eigenvalues at point K
 eigenq(mband*nsppol)  : Eigenvalues at point K+Q
 mband : maximum number of bands
 smdelta : Variable controlling the smearinf scheme

OUTPUT

 smdfunc(mband,mband) : Smeared delta function weight corresponding to \delta(\epsilon_{n,k} - \epsilon_{n',k+Q})

SOURCE

1846 subroutine smeared_delta(eigen0,eigenq,esmear,mband,smdelta,smdfunc)
1847 
1848 !Arguments ------------------------------------
1849 !scalars
1850  integer,intent(in) :: mband,smdelta
1851 !arrays
1852  real(dp),intent(in) :: eigen0(mband),eigenq(mband),esmear
1853  real(dp),intent(out) :: smdfunc(mband,mband)
1854 
1855 !Local variables-------------------------------
1856 !tolerance for non degenerated levels
1857 !scalars
1858  integer :: ii,jj
1859  real(dp) :: aa,dsqrpi,gauss,xx
1860  character(len=500) :: message
1861 
1862 ! *********************************************************************
1863 
1864 
1865 !---------------------------------------------------------
1866 !Ordinary (unique) smearing function
1867 !---------------------------------------------------------
1868 
1869  if(smdelta==1)then
1870 
1871 !  Fermi-Dirac
1872    do ii=1,mband
1873      do jj= 1,mband
1874        xx= ( eigen0(ii) - eigenq(jj) )/esmear
1875        smdfunc(ii,jj)=0.25_dp/esmear/(cosh(xx/2.0_dp))**2
1876      end do
1877    end do
1878 
1879  else if(smdelta==2 .or. smdelta==3)then
1880 
1881 !  Cold smearing of Marzari, two values of the "a" parameter being possible
1882 !  first value gives minimization of the bump
1883    if(smdelta==2)aa=-.5634
1884 !  second value gives monotonic occupation function
1885    if(smdelta==3)aa=-.8165
1886 
1887    dsqrpi=1.0_dp/sqrt(pi)
1888    do ii=1,mband
1889      do jj=1,mband
1890        xx= ( eigen0(ii) - eigenq(jj) ) / esmear
1891        gauss=dsqrpi*exp(-xx**2)/esmear
1892        smdfunc(ii,jj)=gauss*(1.5_dp+xx*(-aa*1.5_dp+xx*(-1.0_dp+aa*xx)))
1893      end do
1894    end do
1895 
1896  else if(smdelta==4)then
1897 
1898 !  First order Hermite-Gaussian of Paxton and Methfessel
1899    dsqrpi=1.0_dp/sqrt(pi)
1900    do ii=1,mband
1901      do jj=1,mband
1902        xx= ( eigen0(ii) - eigenq (jj) ) / esmear
1903        smdfunc(ii,jj)=dsqrpi*(1.5_dp-xx**2)*exp(-xx**2)/esmear
1904      end do
1905    end do
1906 
1907  else if(smdelta==5)then
1908 
1909 !  Gaussian smearing
1910    dsqrpi=1.0_dp/sqrt(pi)
1911    do ii=1,mband
1912      do jj=1,mband
1913        xx= ( eigen0(ii) - eigenq (jj) ) / esmear
1914        smdfunc(ii,jj)=dsqrpi*exp(-xx**2)/esmear
1915      end do
1916    end do
1917 
1918  else
1919    write(message, '(a,i0,a)' )'  Smdelta= ',smdelta,' is not allowed in smdfunc'
1920    ABI_BUG(message)
1921  end if
1922 
1923 end subroutine smeared_delta

m_eig2d/eig2tot [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 eig2tot

FUNCTION

 This routine calculates the second-order eigenvalues.
 The output eig2nkq is this quantity for the input k points.

INPUTS

  bdeigrf = number of bands for which to calculate the second-order eigenvalues.
  clflg(3,mpert)= array on calculated perturbations for eig2rf.
  dim_eig2nkq = 1 if eig2nkq is to be computed.
  eigbrd(2,mband*nsppol,nkpt,3,natom,3,natom) = broadening factors for the
            electronic eigenvalues (optional).
  eigen0(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all K-points:
            <k,n'|H(0)|k,n'> (hartree).
  eigenq(nkpt_rbz*mband*nsppol) = 0-order eigenvalues at all shifted K-points:
            <k+Q,n'|H(0)|k+Q,n'> (hartree).
  eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert) = matrix of first-order:
            <k+Q,n'|H(1)|k,n> (hartree) (calculated in dfpt_cgwf).
  eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq) = second derivatives of
            the electronic eigenvalues.
  elph2_imagden = imaginary part of the denominator of the sum-over-state expression
            for the electronic eigenenergy shift due to second-order electron-phonon
            interation.
  ieig2rf = integer for calculation type.
  indsym(4,nsym,natom) = indirect indexing array for atom labels
            (not used yet, but will be used with symmetries).
  mband = maximum number of bands.
  mpert = maximum number of perturbations.
  natom = number of atoms in the unit cell.
  npert = number of phonon perturbations, without taking into account directions:
            natom.
  nsym = number of symmetries (not used yet).
  mpi_enreg = information about MPI parallelization.
  nkpt_rbz = number of k-points for each perturbation.
  nsppol = 1 for unpolarized, 2 for spin-polarized.
  smdelta = integer controling the calculation of electron lifetimes.
  symq(4,2,nsym) = 1 if symmetry preserves present qpoint. From littlegroup_q (not used yet).
  symrec(3,3,nsym) = 3x3 matrices of the group symmetries (reciprocal space)
            (not used yet).
  symrel(3,3,nsym) = array containing the symmetries in real space (not used yet).
  timrev = 1 if time-reversal preserves the q wavevector; 0 otherwise
            (not in use yet).
  dtset = OPTIONAL, dataset structure containing the input variable of the
            calculation. This is required to use the k-interpolation routine.
  eigenq_fine(mband_fine,mkpt_fine,nsppol_fine) = OPTIONAL, 0-order eigenvalues
            at all shifted K-points: <k+Q,n'|H(0)|k+Q,n'> (hartree) of the
            fine grid. This information is read from the WF dense k-grid file.
  hdr_fine = OPTIONAL, header of the WF file of the fine k-point grid. This
            variable is required for the k-interpolation routine.
  hdr0     = header of the GS WF file of the corse k-point grid.

OUTPUT

  eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= diagonal part of the
            second-order eigenvalues: E^{(2),diag}_{k,q,j}.
  eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)= OPTIONAL, array containing the
            the contribution of each perturbations pair
            to the eigenstate broadening (inverse lifetime)
            computed statically (without phonon frequencies). 

SOURCE

1205 subroutine eig2tot(dtfil,xred,psps,pawtab,natom,bdeigrf,clflg,dim_eig2nkq,eigen0,eigenq,eigen1,eig2nkq,&
1206 &  elph2_imagden,esmear,ieig2rf,mband,mpert,npert,mpi_enreg,doccde,&
1207 &  nkpt_rbz,nsppol,smdelta,rprimd,dtset,occ_rbz,hdr0,eigbrd,eigenq_fine,hdr_fine)
1208 
1209 !Arguments ------------------------------------
1210 !scalars
1211  integer,intent(in) :: bdeigrf,dim_eig2nkq,ieig2rf,mband,mpert,natom,nkpt_rbz
1212  integer,intent(in) :: npert,nsppol,smdelta
1213  real(dp),intent(in) :: elph2_imagden,esmear
1214  type(MPI_type),intent(inout) :: mpi_enreg
1215  type(datafiles_type), intent(in) :: dtfil
1216  type(pseudopotential_type), intent(inout) :: psps
1217 !arrays
1218  type(dataset_type), intent(in) :: dtset
1219  integer,intent(in) :: clflg(3,mpert)
1220  real(dp),intent(in) :: doccde(dtset%mband*dtset%nkpt*dtset%nsppol)
1221  real(dp),intent(in) :: eigen0(nkpt_rbz*mband*nsppol)
1222  real(dp),intent(in) :: eigen1(nkpt_rbz*2*nsppol*mband**2,3,mpert)
1223  real(dp),intent(in) :: eigenq(nkpt_rbz*mband*nsppol)
1224  real(dp),intent(in) :: occ_rbz(mband*nkpt_rbz*nsppol)
1225  real(dp),intent(inout) :: eig2nkq(2,mband*nsppol,nkpt_rbz,3,npert,3,npert*dim_eig2nkq)
1226  real(dp),intent(in) :: rprimd(3,3),xred(3,natom)
1227  real(dp),intent(inout),optional :: eigbrd(2,mband*nsppol,nkpt_rbz,3,npert,3,npert)
1228  real(dp),intent(in),pointer,optional :: eigenq_fine(:,:,:)
1229  type(pawtab_type), intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
1230  type(hdr_type),intent(in) :: hdr0
1231  type(hdr_type),intent(in),optional :: hdr_fine
1232 
1233 !Local variables-------------------------------
1234 !tolerance for non degenerated levels
1235 !scalars
1236  integer :: band2tot_index,band_index,bantot,bandtot_index,iband,idir1,idir2
1237  integer :: ikpt,ipert1,ipert2,isppol,jband,nkpt_sub,ikpt2,ncid
1238 !integer :: ipw
1239  character(len=fnlen) :: dscrpt,fname
1240  integer :: master,me,spaceworld,ierr
1241  integer :: mband_mem, mpert_
1242 ! real(dp),parameter :: etol=1.0d-6
1243  real(dp),parameter :: etol=1.0d-7
1244 !real(dp),parameter :: etol=zero
1245  real(dp) :: ar,ai,deltae,den,eig1_i1,eig1_i2,eigen_corr
1246  real(dp) :: eig1_r1,eig1_r2,eig2_diai,den_av
1247  real(dp) :: eig2_diar,eigbrd_i,eigbrd_r,wgt_int
1248  !character(len=500) :: message
1249  logical :: remove_inv,test_do_band
1250  type(crystal_t) :: Crystal
1251  type(ebands_t)  :: Bands
1252  !type(eigr2d_t)  :: eigr2d,eigi2d
1253  type(fan_t)     :: fan2d
1254  type(gkk_t)     :: gkk2d
1255  type(ddb_hdr_type) :: ddb_hdr
1256  type(ddb_type) :: ddb
1257 !arrays
1258  integer,allocatable :: flg(:,:,:,:)
1259  integer, allocatable :: nband_rbz(:)
1260  integer,pointer      :: kpt_fine_sub(:)
1261  real(dp)             :: tsec(2)
1262  real(dp),allocatable :: center(:)
1263  real(dp) :: eigen(mband*nsppol),eigen_prime(mband*nsppol)
1264  real(dp),allocatable :: fan(:,:,:,:,:,:,:)
1265  real(dp),allocatable :: gkk(:,:,:,:,:)
1266  real(dp),allocatable :: eig2nkq_tmp(:,:,:,:,:,:,:)
1267  real(dp),allocatable :: smdfun(:,:)
1268  real(dp),pointer     :: wgt_sub(:)
1269 
1270 ! *********************************************************************
1271 
1272 !Init parallelism
1273  master =0
1274  spaceworld=mpi_enreg%comm_cell
1275  me=mpi_enreg%me_kpt
1276 
1277 !Init interpolation method
1278  if(present(eigenq_fine))then
1279    ABI_MALLOC(center,(3))
1280  end if
1281 
1282  call timab(148,1,tsec)
1283 
1284  if(nsppol==2)then
1285    ABI_COMMENT('nsppol=2 is still under development. Be careful when using it ...')
1286  end if
1287 
1288  band2tot_index =0
1289  bandtot_index=0
1290  band_index=0
1291 
1292  if(xmpi_paral==1) then
1293    ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt_rbz,mband,nsppol))
1294    ABI_MALLOC(nband_rbz,(nkpt_rbz*nsppol))
1295    if (allocated(mpi_enreg%my_kpttab)) then
1296      ABI_FREE(mpi_enreg%my_kpttab)
1297    end if
1298    ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt_rbz))
1299 !  Assume the number of bands is the same for all k points.
1300    nband_rbz(:)=mband
1301    call distrb2(mband,mband_mem,nband_rbz,nkpt_rbz,mpi_enreg%nproc_cell,nsppol,mpi_enreg)
1302  end if
1303 
1304  if(ieig2rf == 4 ) then
1305    ABI_MALLOC_OR_DIE(fan,(2*mband*nsppol,dtset%nkpt,3,natom,3,natom*dim_eig2nkq,mband), ierr)
1306    fan(:,:,:,:,:,:,:) = zero
1307    ABI_MALLOC_OR_DIE(eig2nkq_tmp,(2,mband*nsppol,dtset%nkpt,3,natom,3,natom*dim_eig2nkq), ierr)
1308    eig2nkq_tmp(:,:,:,:,:,:,:) = zero
1309 !  This is not efficient because double the memory. Alternative: use buffer and
1310 !  print part by part.
1311    eig2nkq_tmp = eig2nkq
1312    if(present(eigbrd))then
1313      eigbrd(:,:,:,:,:,:,:)=zero
1314    end if
1315    eigen_corr = 0
1316  end if
1317 
1318  if(ieig2rf == 5 ) then
1319    ABI_MALLOC_OR_DIE(gkk,(2*mband*nsppol,dtset%nkpt,3,natom,mband), ierr)
1320    gkk(:,:,:,:,:) = zero
1321    ABI_MALLOC_OR_DIE(eig2nkq_tmp,(2,mband*nsppol,dtset%nkpt,3,natom,3,natom*dim_eig2nkq), ierr)
1322    eig2nkq_tmp(:,:,:,:,:,:,:) = zero
1323 !  This is not efficient because double the memory. Alternative: use buffer and
1324 !  print part by part.
1325    eig2nkq_tmp = eig2nkq
1326    if(present(eigbrd))then
1327      eigbrd(:,:,:,:,:,:,:)=zero
1328    end if
1329    eigen_corr = 0
1330  end if
1331 
1332  do isppol=1,nsppol
1333    do ikpt =1,nkpt_rbz
1334 
1335      if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,me)) then
1336        band2tot_index = band2tot_index + 2*mband**2
1337        bandtot_index = bandtot_index + mband
1338        cycle
1339      end if
1340 
1341      if(present(eigenq_fine))then
1342        write(std_out,*) 'Start of the energy denominator interpolation method.'
1343        nkpt_sub = 0
1344 !      center is the k+q point around which we will average the kpt_fine
1345        center = hdr0%kptns(:,ikpt)+ dtset%qptn(:)
1346 
1347        call kptfine_av(center,dtset%qptrlatt,hdr_fine%kptns,hdr_fine%nkpt,kpt_fine_sub,nkpt_sub,wgt_sub)
1348        write(std_out,'(a,3f8.4,a,i3)') 'Number of k-points of the fine grid &
1349 &       around the k+Q point ',center,' is:',nkpt_sub
1350        write(std_out,'(a,f10.5)') 'The sum of the weights of the k-points is: ',SUM(wgt_sub)
1351      end if
1352 
1353      if(smdelta >0) then   !broadening
1354        if(.not.allocated(smdfun))  then
1355          ABI_MALLOC(smdfun,(mband,mband))
1356        end if
1357        smdfun(:,:) = zero
1358        do iband=1,mband
1359          eigen(iband) = eigen0(iband+bandtot_index)
1360          eigen_prime(iband) =eigenq(iband+bandtot_index)
1361        end do
1362        if(esmear>tol6) then
1363          call smeared_delta(eigen,eigen_prime,esmear,mband,smdelta,smdfun)
1364        end if
1365      end if
1366 
1367      ipert1=1 ! Suppose all perturbations lead to the same number of planewaves
1368 
1369      do iband=1,bdeigrf
1370 
1371 !      If the k point and band belong to me, compute the contribution
1372        test_do_band=.true.
1373        if(mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me)test_do_band=.false.
1374 
1375        if(test_do_band)then
1376 !        ------------------------------------------------------------------------------------------------------!
1377 !        ------- ieig2rf ==3 : Non dynamic traditional AHC theory with Sternheimer (computed in eig2stern.F90)-!
1378 !        ------------------------------------------------------------------------------------------------------!
1379 !        Note that ieig2rf==4 and ieig2rf==5 also goes into that part only for later printing of the ZPR in the ouput of abinit
1380 !        later in the code
1381          if(ieig2rf==3 .or. ieig2rf==4 .or. ieig2rf==5) then
1382            do ipert1=1,npert
1383              do idir1=1,3
1384                if(clflg(idir1,ipert1)==0) cycle
1385                do ipert2=1,npert
1386                  do idir2=1,3
1387                    if(clflg(idir2,ipert2)==0)cycle
1388                    eig2_diar = zero ; eig2_diai = zero ; eigbrd_r = zero ; eigbrd_i = zero
1389                    do jband=1,mband
1390                      eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1391                      eig1_r2 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir2,ipert2)
1392                      eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1393                      eig1_i2 = - eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir2,ipert2) !the negative sign is from the CC
1394 !                    If no interpolation, fallback on to the previous
1395 !                    implementation
1396                      if(.not. present(eigenq_fine))then
1397                        deltae=eigenq(jband+bandtot_index)-eigen0(iband+bandtot_index)
1398                      end if
1399                      ar=eig1_r1*eig1_r2-eig1_i1*eig1_i2
1400                      ai=eig1_r1*eig1_i2+eig1_i1*eig1_r2
1401 
1402 !                    Sum over all active space to retrieve the diagonal gauge
1403 !                    if(abs(deltae)>etol) then ! This is commented because
1404 !                    there is no problem with divergencies with elph2_imag != 0
1405                      if( present(eigenq_fine))then
1406                        den_av = zero
1407                        wgt_int = zero
1408                        do ikpt2=1,nkpt_sub
1409                          deltae=eigenq_fine(jband,kpt_fine_sub(ikpt2),1)&
1410 &                         -eigen0(iband+bandtot_index)
1411                          den_av = den_av-(wgt_sub(ikpt2)*deltae)/(deltae**2+elph2_imagden**2)
1412                          wgt_int = wgt_int+wgt_sub(ikpt2)
1413                        end do
1414                        den = den_av/wgt_int
1415                      else
1416                        if(abs(elph2_imagden) < etol) then
1417                          if(abs(deltae)>etol) then
1418                            den=-one/(deltae**2+elph2_imagden**2)
1419                          else
1420                            den= zero
1421                          end if
1422                        else
1423                          den=-one/(deltae**2+elph2_imagden**2)
1424                        end if
1425                      end if
1426 
1427                      if( present(eigenq_fine))then
1428                        eig2_diar=eig2_diar+ar*den
1429                        eig2_diai=eig2_diai+ai*den
1430                      else
1431                        eig2_diar=eig2_diar+ar*deltae*den
1432                        eig2_diai=eig2_diai+ai*deltae*den
1433                      end if
1434 
1435                      if(present(eigbrd))then
1436                        if(smdelta >0) then   !broadening
1437                          eigbrd_r = eigbrd_r + ar*smdfun(iband,jband)
1438                          eigbrd_i = eigbrd_i + ai*smdfun(iband,jband)
1439                        end if
1440                      end if
1441                    end do !jband
1442 
1443 !                  Store the contribution
1444                    eig2nkq(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = &
1445 &                   eig2nkq(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) + eig2_diar
1446                    eig2nkq(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = &
1447 &                   eig2nkq(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) + eig2_diai
1448 
1449                    if(present(eigbrd))then
1450                      if(smdelta >0) then   !broadening
1451                        eigbrd(1,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_r
1452                        eigbrd(2,iband+band_index,ikpt,idir1,ipert1,idir2,ipert2) = eigbrd_i
1453                      end if
1454                    end if
1455 
1456                  end do !idir2
1457                end do !ipert2
1458              end do  !idir1
1459            end do   !ipert1
1460          end if !ieig2rf 3
1461 
1462 !        -------------------------------------------------------------------------------------------!
1463 !        ------- ieig2rf ==4  Dynamic AHC using second quantization and Sternheimer from eig2stern -!
1464 !        -------------------------------------------------------------------------------------------!
1465          if(ieig2rf ==4 ) then
1466            do ipert1=1,npert
1467              do idir1=1,3
1468                if(clflg(idir1,ipert1)==0) cycle
1469                do ipert2=1,npert
1470                  do idir2=1,3
1471                    if(clflg(idir2,ipert2)==0)cycle
1472                    do jband=1,mband
1473                      eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1474                      eig1_r2 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir2,ipert2)
1475                      eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1476                      eig1_i2 = - eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir2,ipert2) !the negative sign is from the CC
1477                      ar=eig1_r1*eig1_r2-eig1_i1*eig1_i2
1478                      ai=eig1_r1*eig1_i2+eig1_i1*eig1_r2
1479 !                  Store the contribution
1480                      fan(2*iband-1+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) = &
1481 &                     fan(2*iband-1+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) + ar
1482                      fan(2*iband+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) = &
1483 &                     fan(2*iband+2*band_index,ikpt,idir1,ipert1,idir2,ipert2,jband) + ai
1484                    end do !jband
1485                  end do !idir2
1486                end do !ipert2
1487              end do  !idir1
1488            end do   !ipert1
1489          end if !ieig2rf 4
1490 !        --------------------------------------------------------------------------------!
1491 !        ------- ieig2rf ==5  Dynamic AHC with Sternheimer from eig2stern but print GKK -!
1492 !        --------------------------------------------------------------------------------!
1493          if(ieig2rf ==5 ) then
1494            do ipert1=1,npert
1495              do idir1=1,3
1496                if(clflg(idir1,ipert1)==0) cycle
1497                do jband=1,mband
1498                  eig1_r1 = eigen1(2*jband-1+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1499                  eig1_i1 = eigen1(2*jband+(iband-1)*2*mband+band2tot_index,idir1,ipert1)
1500 !              Store the contribution
1501                  gkk(2*iband-1+2*band_index,ikpt,idir1,ipert1,jband) = &
1502 &                 gkk(2*iband-1+2*band_index,ikpt,idir1,ipert1,jband) + eig1_r1
1503                  gkk(2*iband+2*band_index,ikpt,idir1,ipert1,jband) = &
1504 &                 gkk(2*iband+2*band_index,ikpt,idir1,ipert1,jband) + eig1_i1
1505                end do !jband
1506              end do  !idir1
1507            end do   !ipert1
1508          end if !ieig2rf 5
1509        end if ! Selection of processor
1510      end do !iband
1511 
1512      band2tot_index = band2tot_index + 2*mband**2
1513      bandtot_index = bandtot_index + mband
1514 
1515      if(present(eigenq_fine))then
1516        ABI_FREE(kpt_fine_sub) ! Deallocate the variable
1517        ABI_FREE(wgt_sub)
1518      end if
1519 
1520    end do    !ikpt
1521    band_index = band_index + mband
1522  end do !isppol
1523 
1524 !Accumulate eig2nkq and/or eigbrd
1525  if(xmpi_paral==1) then
1526    if(ieig2rf == 3) then
1527      call xmpi_sum(eig2nkq,spaceworld,ierr)
1528    end if
1529    if(ieig2rf == 4) then
1530      call xmpi_sum(eig2nkq,spaceworld,ierr)
1531      call xmpi_sum(eig2nkq_tmp,spaceworld,ierr)
1532      call xmpi_sum(fan,spaceworld,ierr)
1533    end if
1534    if(ieig2rf == 5) then
1535      call xmpi_sum(eig2nkq,spaceworld,ierr)
1536      call xmpi_sum(eig2nkq_tmp,spaceworld,ierr)
1537      call xmpi_sum(gkk,spaceworld,ierr)
1538    end if
1539    if(present(eigbrd) .and. (ieig2rf == 3 .or. ieig2rf == 4 .or. ieig2rf == 5))then
1540      if(smdelta >0) then
1541        call xmpi_sum(eigbrd,spaceworld,ierr)
1542      end if
1543    end if
1544    ABI_FREE(nband_rbz)
1545    ABI_FREE(mpi_enreg%proc_distrb)
1546    ABI_FREE(mpi_enreg%my_kpttab)
1547  end if
1548 
1549  if(ieig2rf > 2) then
1550    write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGR2D.'
1551    write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1552    band_index = 0
1553    do isppol=1,dtset%nsppol
1554      do idir1=1,3
1555        do idir2=1,3
1556          ar=eig2nkq(1,1+band_index,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1557          ai=eig2nkq(2,1+band_index,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1558          write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1559        end do ! idir2
1560      end do ! idir1
1561      band_index = band_index + mband
1562      write(ab_out,'(a)')' '
1563    end do
1564  end if
1565 
1566  if(present(eigbrd))then
1567    if(smdelta >0) then   !broadening
1568      write(ab_out,'(a)')' Components of second-order derivatives of the electronic energy, EIGI2D.'
1569      write(ab_out,'(a)')' For automatic tests, printing the matrix for the first k-point, first band, first atom.'
1570      band_index = 0
1571      do isppol=1,dtset%nsppol
1572        do idir1=1,3
1573          do idir2=1,3
1574            ar=eigbrd(1,1+band_index,1,idir1,1,idir2,1) ; if(abs(ar)<tol10)ar=zero
1575            ai=eigbrd(2,1+band_index,1,idir1,1,idir2,1) ; if(abs(ai)<tol10)ai=zero
1576            write (ab_out,'(4i4,2es20.10)') idir1,1,idir2,1,ar,ai
1577          end do
1578        end do
1579        band_index = band_index + mband
1580        write(ab_out,'(a)')' '
1581      end do
1582    end if
1583  end if
1584 
1585  if(allocated(smdfun))  then
1586    ABI_FREE(smdfun)
1587  end if
1588  if(present(eigenq_fine))then
1589    ABI_FREE(center)
1590  end if
1591 
1592    if (ieig2rf == 3 .or. ieig2rf == 4 .or. ieig2rf == 5) then
1593 
1594        mpert_ = dtset%natom
1595 
1596        ! Initialize perturbation flags
1597        ABI_MALLOC(flg,(3,mpert_,3,mpert_))
1598        flg = one
1599 
1600        ! Initialize ddb object
1601        call ddb%init(dtset, 1, mpert_, &
1602                     mband=bdeigrf,&
1603                     nkpt=nkpt_rbz,&
1604                     kpt=dtset%kptns(1:3,1:nkpt_rbz),&
1605                     with_d2eig=.true.)
1606 
1607        ! Create the ddb header
1608        dscrpt=' Note : temporary (transfer) database '
1609        call ddb_hdr%init(dtset,psps,pawtab,dscrpt,1,&
1610                          mpert=mpert_,&
1611                          xred=xred,occ=occ_rbz,&
1612                          mband=bdeigrf / dtset%nsppol,&
1613                          nkpt=nkpt_rbz,&
1614                          kpt=dtset%kptns(:,1:nkpt_rbz))
1615 
1616        ! Set d2eig data
1617        call ddb%set_qpt(1, dtset%qptn)
1618        call ddb%set_d2eig_reshape(1, eig2nkq, flg)
1619 
1620        ! Open the file and write header
1621        call ddb_hdr%set_typ(ddb%nblok, ddb%typ)
1622 
1623        ! Write d2eig data block
1624        call ddb_hdr%open_write(dtfil%fnameabo_eigr2d, with_psps=1, comm=mpi_enreg%comm_world)
1625        call ddb%write_d2eig(ddb_hdr, 1, comm=mpi_enreg%comm_world)
1626 
1627        ! close and free memory
1628        call ddb_hdr%close()
1629        call ddb_hdr%free()
1630        call ddb%free()
1631 
1632        ABI_FREE(flg)
1633 
1634    end if
1635 
1636 !  print _FAN file for this perturbation. Note that the Fan file will only be produced if
1637 !  abinit is compiled with netcdf.
1638 
1639 !  Initialize crystal structure for FAN.nc and GKK.nc files
1640    remove_inv=.false.
1641    if(dtset%nspden==4 .and. dtset%usedmft==1) remove_inv=.true.
1642    call crystal_init(dtset%amu_orig(:,1),Crystal,dtset%spgroup,dtset%natom,dtset%npsp,psps%ntypat, &
1643 &   dtset%nsym,rprimd,dtset%typat,xred,dtset%ziontypat,dtset%znucl,1,&
1644 &   dtset%nspden==2.and.dtset%nsppol==1,remove_inv,hdr0%title,&
1645 &   dtset%symrel,dtset%tnons,dtset%symafm)
1646 !  Electronic band energies.
1647    bantot= dtset%mband*dtset%nkpt*dtset%nsppol
1648    call ebands_init(bantot,Bands,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,&
1649 &   doccde,eigen0,hdr0%istwfk,hdr0%kptns,&
1650 &   hdr0%nband, hdr0%nkpt,hdr0%npwarr,hdr0%nsppol,hdr0%nspinor,&
1651 &   hdr0%tphysel,hdr0%tsmear,hdr0%occopt,hdr0%occ,hdr0%wtk,&
1652 &   hdr0%cellcharge, hdr0%kptopt, hdr0%kptrlatt_orig, hdr0%nshiftk_orig, hdr0%shiftk_orig, &
1653 &   hdr0%kptrlatt, hdr0%nshiftk, hdr0%shiftk)
1654 !
1655    if(ieig2rf == 4 ) then
1656 !    Output of the Fan.nc file.
1657 #ifdef HAVE_NETCDF
1658      fname = strcat(dtfil%filnam_ds(4),"_FAN.nc")
1659      call fan_init(fan,fan2d,dtset%mband,hdr0%nsppol,nkpt_rbz,dtset%natom)
1660      NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating FAN file")
1661      NCF_CHECK(crystal%ncwrite(ncid))
1662      NCF_CHECK(ebands_ncwrite(Bands, ncid))
1663      call fan_ncwrite(fan2d,dtset%qptn(:),dtset%wtq, ncid)
1664      NCF_CHECK(nf90_close(ncid))
1665 #else
1666      ABI_ERROR("Dynamical calculation with ieig2rf 4 only work with NETCDF support.")
1667      ABI_UNUSED(ncid)
1668 #endif
1669      ABI_FREE(fan)
1670      ABI_FREE(eig2nkq_tmp)
1671    end if
1672 !  print _GKK.nc file for this perturbation. Note that the GKK file will only be produced if
1673 !  abinit is compiled with netcdf.
1674    if(ieig2rf == 5 ) then
1675 !    Output of the GKK.nc file.
1676 #ifdef HAVE_NETCDF
1677      fname = strcat(dtfil%filnam_ds(4),"_GKK.nc")
1678      call gkk_init(gkk,gkk2d,dtset%mband,hdr0%nsppol,nkpt_rbz,dtset%natom,3)
1679      NCF_CHECK_MSG(nctk_open_create(ncid, fname, xmpi_comm_self), "Creating GKK file")
1680      NCF_CHECK(crystal%ncwrite(ncid))
1681      NCF_CHECK(ebands_ncwrite(Bands, ncid))
1682      call gkk_ncwrite(gkk2d,dtset%qptn(:),dtset%wtq, ncid)
1683      NCF_CHECK(nf90_close(ncid))
1684 #else
1685      ABI_ERROR("Dynamical calculation with ieig2rf 5 only work with NETCDF support.")
1686      ABI_UNUSED(ncid)
1687 #endif
1688      ABI_FREE(gkk)
1689      ABI_FREE(eig2nkq_tmp)
1690    end if
1691 
1692 !  print _EIGI2D file for this perturbation
1693    if (ieig2rf /= 5 ) then
1694      if(smdelta>0) then
1695 
1696        ABI_MALLOC(flg,(3,mpert_,3,mpert_))
1697        flg = one
1698        call ddb%init(dtset, 1, mpert_, &
1699                     mband=bdeigrf,&
1700                     nkpt=nkpt_rbz,&
1701                     kpt=dtset%kptns(:,1:nkpt_rbz),&
1702                     with_d2eig=.true.)
1703 
1704        ! Create the ddb header
1705        dscrpt=' Note : temporary (transfer) database '
1706        call ddb_hdr%init(dtset,psps,pawtab,dscrpt,1,&
1707                          mpert=mpert_,&
1708                          xred=xred,occ=occ_rbz,&
1709                          mband=bdeigrf / dtset%nsppol,&
1710                          nkpt=nkpt_rbz,&
1711                          kpt=dtset%kptns(:,1:nkpt_rbz))
1712 
1713        call ddb%set_qpt(1, dtset%qptn)
1714        call ddb%set_d2eig_reshape(1, eigbrd, flg, blktyp=BLKTYP_d2eig_im)
1715 
1716        call ddb_hdr%set_typ(ddb%nblok, ddb%typ)
1717 
1718        call ddb_hdr%open_write(dtfil%fnameabo_eigi2d, with_psps=1)
1719        call ddb%write_d2eig(ddb_hdr, 1)
1720 
1721        call ddb_hdr%close()
1722        call ddb_hdr%free()
1723        call ddb%free()
1724 
1725        ABI_FREE(flg)
1726 
1727      end if !smdelta
1728    end if
1729  !end if  ! master
1730 
1731  if (allocated(fan)) then
1732    ABI_FREE(fan)
1733  end if
1734  if (allocated(eig2nkq_tmp)) then
1735    ABI_FREE(eig2nkq_tmp)
1736  end if
1737  if (allocated(gkk)) then
1738    ABI_FREE(gkk)
1739  end if
1740 
1741  call crystal%free()
1742  call ebands_free(Bands)
1743  call fan_free(fan2d)
1744  call gkk_free(gkk2d)
1745 
1746  call timab(148,2,tsec)
1747 
1748 end subroutine eig2tot

m_eig2d/eigr2d_free [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 eigr2d_free

FUNCTION

 Deallocates the components of the eigr2d_t structured datatype

INPUTS

  eigr2d<eigr2d_t>=The data type to be deallocated.

OUTPUT

  Deallocate the dynamic arrays in the ebands_t type.
  (only deallocate)

SOURCE

309 subroutine eigr2d_free(eigr2d)
310 
311 !Arguments ------------------------------------
312 !scalars
313  type(eigr2d_t),intent(inout) :: eigr2d
314 ! *************************************************************************
315 DBG_ENTER("COLL")
316 
317 !Deallocate all components of bstruct
318 
319  if (allocated(eigr2d%eigr2d)) then
320    ABI_FREE(eigr2d%eigr2d)
321  end if
322 
323  DBG_EXIT("COLL")
324 
325 end subroutine eigr2d_free

m_eig2d/eigr2d_init [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 eigr2d_init

FUNCTION

 This subroutine initializes the eigr2d_t structured datatype

INPUTS

 mbands=maximum number of bands
 nkpt=number of k points
 nsppol=1 for unpolarized, 2 for spin-polarized
 natom=number of atoms
 eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom)=second-order derivative of the
     eigenenergies wrt phononic displacements

OUTPUT

 eigr2d<eigr2d_t>=the eigr2d_t datatype

SOURCE

189 subroutine eigr2d_init(eig2nkq,eigr2d,mband,nsppol,nkpt,natom)
190 
191 !Arguments ------------------------------------
192 !scalars
193  integer,intent(in) ::mband,nsppol,nkpt,natom
194  type(eigr2d_t),intent(out) :: eigr2d
195 !arrays
196  real(dp), intent(in) :: eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom)
197 
198 ! *************************************************************************
199 
200  eigr2d%mband = mband
201  eigr2d%nsppol = nsppol
202  eigr2d%nkpt = nkpt
203  eigr2d%natom = natom
204 
205  ABI_MALLOC(eigr2d%eigr2d  ,(2,mband*nsppol,nkpt,3,natom,3,natom))
206  eigr2d%eigr2d=eig2nkq
207 
208 end subroutine eigr2d_init

m_eig2d/eigr2d_ncwrite [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 eigr2d_ncwrite

FUNCTION

  Writes the content of a eigr2d_t object to a NETCDF file
  according to the ETSF-IO specifications.

INPUTS

  ncid =NC file handle

OUTPUT

SOURCE

228 subroutine eigr2d_ncwrite(eigr2d,iqpt,wtq,ncid)
229 
230 !Arguments ------------------------------------
231 !scalars
232  integer,intent(in) ::ncid
233  real(dp),intent(in) :: iqpt(3),wtq
234  type(eigr2d_t),intent(in) :: eigr2d
235 
236 !Local variables-------------------------------
237 #ifdef HAVE_NETCDF
238  integer :: ncerr
239  integer :: cplex,cart_dir,one_dim
240  character(len=200) :: temp
241 
242 ! *************************************************************************
243 
244  ! ==============================================
245  ! === Write the dimensions specified by ETSF ===
246  ! ==============================================
247  one_dim=1; cplex=2; cart_dir=3
248 
249  ncerr = nctk_def_dims(ncid, [&
250    nctkdim_t('max_number_of_states', eigr2d%mband),&
251    nctkdim_t('number_of_spins', eigr2d%nsppol),&
252    nctkdim_t('number_of_kpoints', eigr2d%nkpt),&
253    nctkdim_t('number_of_atoms', eigr2d%natom),&
254    nctkdim_t('number_of_cartesian_directions', cart_dir),&
255    nctkdim_t('current_one_dim', one_dim),&
256    nctkdim_t('cplex', cplex),&
257    nctkdim_t('product_mband_nsppol', eigr2d%mband*eigr2d%nsppol)], defmode=.True.)
258  NCF_CHECK(ncerr)
259 
260  temp='cplex,product_mband_nsppol,number_of_kpoints,number_of_cartesian_directions,number_of_atoms,' //&
261       'number_of_cartesian_directions , number_of_atoms'
262  ncerr = nctk_def_arrays(ncid, [&
263    nctkarr_t('current_q_point', "dp", 'number_of_cartesian_directions'), &
264    nctkarr_t('current_q_point_weight', "dp", 'current_one_dim'), &
265    nctkarr_t('second_derivative_eigenenergies', "dp", temp )])
266 !   nctkarr_t('second_derivative_eigenenergies', "dp",&
267 !   &'cplex, product_mband_nsppol, number_of_kpoints, number_of_cartesian_directions, number_of_atoms,&
268 !   &number_of_cartesian_directions, number_of_atoms')])
269  NCF_CHECK(ncerr)
270 
271 ! Write data
272  NCF_CHECK(nctk_set_datamode(ncid))
273  NCF_CHECK(nf90_put_var(ncid, vid('current_q_point'), iqpt))
274  NCF_CHECK(nf90_put_var(ncid, vid('current_q_point_weight'), wtq))
275  NCF_CHECK(nf90_put_var(ncid, vid('second_derivative_eigenenergies'), eigr2d%eigr2d))
276 
277 #else
278  ABI_ERROR("ETSF-IO support is not activated. ")
279 #endif
280 
281 
282 contains
283  integer function vid(vname)
284    character(len=*),intent(in) :: vname
285    vid = nctk_idname(ncid, vname)
286  end function vid
287 
288 end subroutine eigr2d_ncwrite

m_eig2d/eigr2d_t [ Types ]

[ Top ] [ m_eig2d ] [ Types ]

NAME

 eig2d_t

FUNCTION

 It contains information about the second-order derivative of the
 eigenenergies wrt atomic displacement

SOURCE

 82  type,public :: eigr2d_t
 83 
 84 ! WARNING : if you modify this datatype, please check whether there might be
 85 ! creation/destruction/copy routines,
 86 ! declared in another part of ABINIT, that might need to take into account your
 87 ! modification.
 88 
 89   integer :: mband                 ! Max number of bands i.e MAXVAL(nband) (to dimension arrays)
 90   integer :: nsppol                ! number of spin-polarization
 91   integer :: nkpt                  ! number of k points
 92   integer :: natom                 ! number of atoms
 93 
 94   real(dp),allocatable :: eigr2d(:,:,:,:,:,:,:)
 95   ! eigr2d(2,mband*nsppol,nkpt,3,natom,3,natom)
 96   ! Second-order derivative of eigenergies (real,im) at each
 97   ! spin,band,k-point,dir1,dir2,natom1,natom2 .
 98 
 99 
100  end type eigr2d_t

m_eig2d/elph2_fanddw [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 elph2_fanddw

FUNCTION

 This routine calculates the zero-point motion corrections
 due to the Fan term or to the DDW term..

INPUTS

  dim_eig2nkq=1 if eig2nkq is to be computed
  displ(2*3*natom*3*natom)=the displacements of atoms in cartesian coordinates.
  eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq)=one half second derivatives of the electronic eigenvalues
  gprimd(3,3)=dimensional primitive translations for reciprocal space ($\textrm{bohr}^{-1}$)
  mband= maximum number of bands
  natom= number of atoms in the unit cell
  nkpt= number of k-points
  nsppol= 1 for unpolarized, 2 for spin-polarized
  option 1 for Fan term, 2 for DDW term
  phfrq(3*natom)=phonon frequencies
  (prtvol > 4) if the mode decomposition is to be printed

OUTPUT

  eigen_corr(mband*nkpt*nsppol)= T=0 correction to the electronic eigenvalues, due to the Fan term.

SOURCE

1952 subroutine elph2_fanddw(dim_eig2nkq,displ,eig2nkq,eigen_corr,gprimd,mband,natom,nkpt,nsppol,option,phfrq,prtvol)
1953 
1954 !Arguments ------------------------------------
1955 !scalars
1956  integer,intent(in) :: dim_eig2nkq,mband,natom,nkpt,nsppol,option,prtvol
1957 
1958 !arrays
1959  real(dp) :: gprimd(3,3)
1960  real(dp),intent(in) :: displ(2*3*natom*3*natom)
1961  real(dp),intent(in) :: eig2nkq(2,mband*nsppol,nkpt,3,natom,3,natom*dim_eig2nkq)
1962  real(dp),intent(in) :: phfrq(3*natom)
1963  real(dp),intent(out) :: eigen_corr(mband*nkpt*nsppol)
1964 
1965 !Local variables-------------------------------
1966 !scalars
1967  integer,parameter :: neigs_per_line=6
1968  integer :: iatom1,iatom2,idir1,idir2,iband,ikpt,imode,index,isppol, imin, ii
1969  real(dp) :: d_at1_dir1_re,d_at1_dir1_im
1970  real(dp) :: d_at1_dir2_re,d_at1_dir2_im
1971  real(dp) :: d_at2_dir1_re,d_at2_dir1_im
1972  real(dp) :: d_at2_dir2_re,d_at2_dir2_im
1973  real(dp) :: e2_im,e2_re
1974  real(dp), allocatable :: eigen_corr_mode(:)
1975  character(len=500) :: message
1976  character(len=20) :: eig_format, line_format
1977 !arrays
1978  real(dp) :: displ2cart(2,3,3),displ2red(2,3,3),tmp_displ2(2,3,3)
1979 
1980 ! *********************************************************************
1981 
1982 
1983  if(option/=1 .and. option/=2)then
1984    write(message,'(a,i0)')' The argument option should be 1 or 2, while it is found that option=',option
1985    ABI_BUG(message)
1986  end if
1987 
1988  !printing options
1989  eig_format='f16.8'
1990  write(line_format,'(a,i1,a6,a)') '(',neigs_per_line,eig_format,')'
1991 
1992  if (prtvol > 4) then
1993    write(message,'(a,a)')ch10,' ================================================================================'
1994    call wrtout(ab_out_default,message,'COLL')
1995    if (option==1) then
1996      write(message,'(a)') ' ---- Begin Fan contributions to eigenvalues renormalization by mode ----'
1997      call wrtout(ab_out_default,message,'COLL')
1998    else if (option==2) then
1999      write(message,'(a)') ' ---- Begin DDW contributions to eigenvalues renormalization by mode ----'
2000      call wrtout(ab_out_default,message,'COLL')
2001    end if
2002  end if
2003 
2004  ABI_MALLOC(eigen_corr_mode,(mband*nkpt*nsppol))
2005 
2006  eigen_corr(:)=zero
2007  do imode=1,3*natom
2008    eigen_corr_mode(:)=zero
2009 
2010    if (phfrq(imode)>tol6) then
2011      do iatom1=1,natom
2012        do iatom2=1,natom
2013 
2014          do idir1=1,3
2015            do idir2=1,3
2016 !            Compute the mean cartesian displacements
2017              d_at1_dir1_re=displ(1 + 2*(idir1-1 +3*(iatom1-1 +natom*(imode-1))))
2018              d_at1_dir1_im=displ(2 + 2*(idir1-1 +3*(iatom1-1 +natom*(imode-1))))
2019              d_at2_dir2_re=displ(1 + 2*(idir2-1 +3*(iatom2-1 +natom*(imode-1))))
2020              d_at2_dir2_im=displ(2 + 2*(idir2-1 +3*(iatom2-1 +natom*(imode-1))))
2021 
2022              if(option==1)then
2023 !              Compute the mean displacement correlation at T=0.
2024 !              Consistent with Eqs.(7) and (8) of PRB51, 8610 (1995) [[cite:Lee1995]], specialized for the contribution of one q point.
2025 !              but generalized to two different atoms. Note that the complex conjugate is taken on the second direction.
2026                displ2cart(1,idir1,idir2)=(d_at1_dir1_re*d_at2_dir2_re+ &
2027 &               d_at1_dir1_im*d_at2_dir2_im )/(two*phfrq(imode))
2028                displ2cart(2,idir1,idir2)=(d_at1_dir1_im*d_at2_dir2_re- &
2029 &               d_at1_dir1_re*d_at2_dir2_im )/(two*phfrq(imode))
2030              else if(option==2)then
2031 !              Compute the mean square displacement correlation of each atom at T=0, and take mean over iatom1 and iatom2.
2032 !              See Eqs.(7) and (8) of PRB51, 8610 (1995) [[cite:Lee1995]], specialized for the contribution of one q point.
2033 !              Note that the complex conjugate is taken on the second direction.
2034 !              Also, note the overall negative sign, to make it opposite to the Fan term.
2035                d_at1_dir2_re=displ(1 + 2*(idir2-1 +3*(iatom1-1 +natom*(imode-1))))
2036                d_at1_dir2_im=displ(2 + 2*(idir2-1 +3*(iatom1-1 +natom*(imode-1))))
2037                d_at2_dir1_re=displ(1 + 2*(idir1-1 +3*(iatom2-1 +natom*(imode-1))))
2038                d_at2_dir1_im=displ(2 + 2*(idir1-1 +3*(iatom2-1 +natom*(imode-1))))
2039                displ2cart(1,idir1,idir2)=-(d_at1_dir1_re*d_at1_dir2_re+ &
2040 &               d_at1_dir1_im*d_at1_dir2_im+ &
2041 &               d_at2_dir1_re*d_at2_dir2_re+ &
2042 &               d_at2_dir1_im*d_at2_dir2_im )/(four*phfrq(imode))
2043                displ2cart(2,idir1,idir2)=-(d_at1_dir1_im*d_at1_dir2_re- &
2044 &               d_at1_dir1_re*d_at1_dir2_im+ &
2045 &               d_at2_dir1_im*d_at2_dir2_re- &
2046 &               d_at2_dir1_re*d_at2_dir2_im )/(four*phfrq(imode))
2047              end if
2048            end do
2049          end do
2050 !        Switch to reduced coordinates in two steps
2051          tmp_displ2(:,:,:)=zero
2052          do idir1=1,3
2053            do idir2=1,3
2054              tmp_displ2(:,:,idir1)=tmp_displ2(:,:,idir1)+displ2cart(:,:,idir2)*gprimd(idir2,idir1)
2055            end do
2056          end do
2057          displ2red(:,:,:)=zero
2058          do idir1=1,3
2059            do idir2=1,3
2060              displ2red(:,idir1,:)=displ2red(:,idir1,:)+tmp_displ2(:,idir2,:)*gprimd(idir2,idir1)
2061            end do
2062          end do
2063 !        Compute the T=0 shift due to this q point
2064          do idir1=1,3
2065            do idir2=1,3
2066              do ikpt=1,nkpt
2067                do isppol=1,nsppol
2068                  do iband=1,mband
2069                    index=iband+mband*(isppol-1 + nsppol*(ikpt-1))
2070                    e2_re=eig2nkq(1,iband+mband*(isppol-1),ikpt,idir1,iatom1,idir2,iatom2)
2071                    e2_im=eig2nkq(2,iband+mband*(isppol-1),ikpt,idir1,iatom1,idir2,iatom2)
2072                    eigen_corr(index)=eigen_corr(index)+&
2073 &                   e2_re*displ2red(1,idir1,idir2)-e2_im*displ2red(2,idir1,idir2)
2074                    eigen_corr_mode(index)=eigen_corr_mode(index)+&
2075 &                   e2_re*displ2red(1,idir1,idir2)-e2_im*displ2red(2,idir1,idir2)
2076                  end do  ! band
2077                end do  ! spin
2078              end do  ! kpt
2079            end do  ! dir2
2080          end do  ! dir1
2081        end do  ! atom2
2082      end do  ! atom1
2083    end if
2084 
2085    if (prtvol > 4) then
2086      ! Print the corrections by mode
2087      write(message,'(a,i1)') ' imode= ',imode
2088      call wrtout(ab_out_default,message,'COLL')
2089 
2090      do ikpt=1,nkpt
2091        do isppol=1,nsppol
2092          write(message,'(a,i4,a,i1)')' ikpt= ',ikpt,' ispin= ',isppol
2093          call wrtout(ab_out_default,message,'COLL')
2094 
2095          imin = mband * (isppol-1 + nsppol*(ikpt-1))
2096          do ii=0, (mband-1)/neigs_per_line
2097            write(message, line_format) (eigen_corr_mode(iband+imin), &
2098 &           iband = 1 + ii * neigs_per_line, min(mband, (ii+1)*neigs_per_line))
2099            call wrtout(ab_out_default,message,'COLL')
2100          end do
2101        end do
2102      end do
2103    end if
2104 
2105  end do  ! mode
2106 
2107  if (prtvol > 4) then
2108    if (option==1) then
2109      write(message,'(a)') ' ---- End Fan contribution to eigenvalues renormalization by mode ----'
2110      call wrtout(ab_out_default,message,'COLL')
2111    else if (option==2) then
2112      write(message,'(a)') ' ---- End DDW contribution to eigenvalues renormalization by mode ----'
2113      call wrtout(ab_out_default,message,'COLL')
2114    end if
2115    write(message,'(a,a)')' ================================================================================', ch10
2116    call wrtout(ab_out_default,message,'COLL')
2117  end if
2118 
2119  ABI_FREE(eigen_corr_mode)
2120 
2121 end subroutine elph2_fanddw

m_eig2d/fan_free [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 fan_free

FUNCTION

 Deallocates the components of the fan_t structured datatype

INPUTS

  fan2d<fan_t>=The data type to be deallocated.

OUTPUT

  Deallocate the dynamic arrays in the fan_t type.
  (only deallocate)

SOURCE

597 subroutine fan_free(fan2d)
598 
599 !Arguments ------------------------------------
600 !scalars
601  type(fan_t),intent(inout) :: fan2d
602 ! *************************************************************************
603 DBG_ENTER("COLL")
604 
605 !Deallocate all components of bstruct
606 
607  if (allocated(fan2d%fan2d)) then
608    ABI_FREE(fan2d%fan2d)
609  end if
610 
611  DBG_EXIT("COLL")
612 
613 end subroutine fan_free

m_eig2d/fan_init [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 fan_init

FUNCTION

 This subroutine initializes the fan_t structured datatype

INPUTS

 mbands=maximum number of bands
 nkpt=number of k points
 nsppol=1 for unpolarized, 2 for spin-polarized
 natom=number of atoms
 fan2d(2*mband*nsppol,nkpt,3,natom,3,natom,mband*nsppol)=second-order derivative of the
     eigenenergies wrt phononic displacements

OUTPUT

 fan2d<fan_t>=the fan_t datatype

SIDE EFFECTS

SOURCE

350 subroutine fan_init(fan,fan2d,mband,nsppol,nkpt,natom)
351 
352 !Arguments ------------------------------------
353 !scalars
354  integer,intent(in) ::mband,nsppol,nkpt,natom
355  type(fan_t),intent(out) :: fan2d
356 !arrays
357  real(dp), intent(in) :: fan(2*mband*nsppol,nkpt,3,natom,3,natom,mband)
358 ! *************************************************************************
359 
360  fan2d%mband = mband
361  fan2d%nsppol = nsppol
362  fan2d%nkpt = nkpt
363  fan2d%natom = natom
364 
365  ABI_MALLOC(fan2d%fan2d,(2*mband*nsppol,nkpt,3,natom,3,natom,mband))
366  fan2d%fan2d=fan
367 
368 end subroutine fan_init

m_eig2d/fan_ncwrite [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 fan_ncwrite

FUNCTION

  Writes the content of a fan_t object to a NETCDF file
  according to the ETSF-IO specifications.

INPUTS

  ncid =NC file handle

OUTPUT

SOURCE

432 subroutine fan_ncwrite(fan2d,iqpt,wtq,ncid)
433 
434 !Arguments ------------------------------------
435 !scalars
436  integer,intent(in) ::ncid
437  real(dp),intent(in) :: iqpt(3),wtq
438  type(fan_t),intent(in) :: fan2d
439 
440 !Local variables-------------------------------
441 #ifdef HAVE_NETCDF
442  integer :: ncerr
443  integer :: cplex,cart_dir,one_dim
444  character(len=200) :: temp
445 
446 
447 ! *************************************************************************
448 
449  ! ==============================================
450  ! === Write the dimensions specified by ETSF ===
451  ! ==============================================
452  one_dim=1; cplex=2; cart_dir=3
453 
454  ncerr = nctk_def_dims(ncid, [&
455    nctkdim_t('max_number_of_states',fan2d%mband),&
456    nctkdim_t('number_of_spins',fan2d%nsppol),&
457    nctkdim_t('number_of_kpoints',fan2d%nkpt),&
458    nctkdim_t('number_of_atoms',fan2d%natom),&
459    nctkdim_t('3_number_of_atoms',3*fan2d%natom),&     ! TODO: not sure that variables can start with digits
460    nctkdim_t('number_of_cartesian_directions',cart_dir),&
461    nctkdim_t('current_one_dim',one_dim),&
462    nctkdim_t('cplex',cplex),&
463    nctkdim_t('product_mband_nsppol',fan2d%mband*fan2d%nsppol),&
464    nctkdim_t('product_mband_nsppol2',fan2d%mband*fan2d%nsppol*2) &
465  ], defmode=.True.)
466  NCF_CHECK(ncerr)
467 
468  temp= 'product_mband_nsppol2, number_of_kpoints, number_of_cartesian_directions,' //&
469    'number_of_atoms, number_of_cartesian_directions, number_of_atoms, max_number_of_states'
470  ncerr = nctk_def_arrays(ncid, [&
471    nctkarr_t('current_q_point', "dp", 'number_of_cartesian_directions'),&
472    nctkarr_t('current_q_point_weight', "dp", 'current_one_dim'),&
473    nctkarr_t('second_derivative_eigenenergies_actif', "dp", temp )])
474 !   nctkarr_t('second_derivative_eigenenergies_actif', "dp",&
475 !   &'product_mband_nsppol2, number_of_kpoints, number_of_cartesian_directions,&
476 !   &number_of_atoms, number_of_cartesian_directions, number_of_atoms, max_number_of_states')])
477  NCF_CHECK(ncerr)
478 
479 ! Write data
480  NCF_CHECK(nctk_set_datamode(ncid))
481  NCF_CHECK(nf90_put_var(ncid, vid('current_q_point'), iqpt))
482  NCF_CHECK(nf90_put_var(ncid, vid('current_q_point_weight'), wtq))
483  NCF_CHECK(nf90_put_var(ncid, vid('second_derivative_eigenenergies_actif'), fan2d%fan2d))
484 
485 #else
486  ABI_ERROR("netcdf support is not activated. ")
487 #endif
488 
489 contains
490  integer function vid(vname)
491    character(len=*),intent(in) :: vname
492    vid = nctk_idname(ncid, vname)
493  end function vid
494 
495 end subroutine fan_ncwrite

m_eig2d/fan_t [ Types ]

[ Top ] [ m_eig2d ] [ Types ]

NAME

 fan_t

FUNCTION

 It contains information about the second-order derivative of the
 eigenenergies wrt atomic displacement

SOURCE

113  type,public :: fan_t
114 
115 ! WARNING : if you modify this datatype, please check whether there might be
116 ! creation/destruction/copy routines,
117 ! declared in another part of ABINIT, that might need to take into account your
118 ! modification.
119 
120   integer :: mband                 ! Max number of bands i.e MAXVAL(nband) (to dimension arrays)
121   integer :: nsppol                ! number of spin-polarization
122   integer :: nkpt                  ! number of k points
123   integer :: natom                 ! number of atoms
124 
125   real(dp),allocatable :: fan2d(:,:,:,:,:,:,:)
126   ! fan2d(2*mband*nsppol,nkpt,3,natom,3,natom,mband)
127   ! Second-order derivative of the eigenergies (real,im) at each
128   ! ispin,iband(real,im),k-point,dir1,dir2,natom1,natom2,jband
129 
130  end type fan_t

m_eig2d/gkk_free [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 gkk_free

FUNCTION

 Deallocates the components of the gkk_t structured datatype

INPUTS

  gkk2d<gkk_t>=The data type to be deallocated.

OUTPUT

  Deallocate the dynamic arrays in the gkk_t type.
  (only deallocate)

SOURCE

634 subroutine gkk_free(gkk2d)
635 
636 !Arguments ------------------------------------
637 !scalars
638  type(gkk_t),intent(inout) :: gkk2d
639 ! *************************************************************************
640 DBG_ENTER("COLL")
641 
642 !Deallocate all components of bstruct
643 
644  if (allocated(gkk2d%gkk2d)) then
645    ABI_FREE(gkk2d%gkk2d)
646  end if
647 
648  DBG_EXIT("COLL")
649 
650 end subroutine gkk_free

m_eig2d/gkk_init [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 gkk_init

FUNCTION

 This subroutine initializes the gkk_t structured datatype

INPUTS

 mbands=maximum number of bands
 nkpt=number of k points
 nsppol=1 for unpolarized, 2 for spin-polarized
 natom=number of atoms
 gkk2d(2*mband*nsppol,nkpt,3,natom,mband*nsppol)=second-order derivative of the
     eigenenergies wrt phononic displacements

OUTPUT

 gkk2d<gkk_t>=the gkk_t datatype

SIDE EFFECTS

SOURCE

393 subroutine gkk_init(gkk,gkk2d,mband,nsppol,nkpt,natom,ncart)
394 
395 !Arguments ------------------------------------
396 !scalars
397  integer,intent(in) ::mband,nsppol,nkpt,natom,ncart
398  type(gkk_t),intent(out) :: gkk2d
399 !arrays
400  real(dp), intent(in) :: gkk(2*mband*nsppol,nkpt,ncart,natom,mband)
401 ! *************************************************************************
402 
403  gkk2d%mband = mband
404  gkk2d%nsppol = nsppol
405  gkk2d%nkpt = nkpt
406  gkk2d%natom = natom
407  gkk2d%ncart = ncart
408 
409  ABI_MALLOC(gkk2d%gkk2d,(2*mband*nsppol,nkpt,ncart,natom,mband))
410  gkk2d%gkk2d=gkk
411 
412 end subroutine gkk_init

m_eig2d/gkk_ncwrite [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 gkk_ncwrite

FUNCTION

  Writes the content of a gkk_t object to a NETCDF file
  according to the ETSF-IO specifications.

INPUTS

  ncid =NC file handle

OUTPUT

SOURCE

515 subroutine gkk_ncwrite(gkk2d,iqpt,wtq,ncid)
516 
517 !Arguments ------------------------------------
518 !scalars
519  integer,intent(in) ::ncid
520  real(dp), intent(in) :: iqpt(3),wtq
521  type(gkk_t),intent(in) :: gkk2d
522 
523 !Local variables-------------------------------
524 #ifdef HAVE_NETCDF
525  integer :: cplex,one_dim,ncerr,vid_
526 
527 ! *************************************************************************
528 
529  ! ==============================================
530  ! === Write the dimensions specified by ETSF ===
531  ! ==============================================
532  one_dim=1; cplex=2
533 
534  ncerr = nctk_def_dims(ncid, [ &
535 &   nctkdim_t('max_number_of_states', gkk2d%mband), &
536 &   nctkdim_t('number_of_spins', gkk2d%nsppol), &
537 &   nctkdim_t('number_of_kpoints', gkk2d%nkpt), &
538 &   nctkdim_t('number_of_atoms_for_gkk', gkk2d%natom), &
539 &   nctkdim_t('3_number_of_atoms', 3*gkk2d%natom), &
540 &   nctkdim_t('number_of_cartesian_directions_for_gkk', gkk2d%ncart), &
541 &   nctkdim_t('current_one_dim', one_dim), &
542 &   nctkdim_t('cplex', cplex), &
543 &   nctkdim_t('product_mband_nsppol', gkk2d%mband*gkk2d%nsppol), &
544 &   nctkdim_t('product_mband_nsppol2', gkk2d%mband*gkk2d%nsppol*2) &
545 & ], defmode=.True.)
546  NCF_CHECK(ncerr)
547 
548 !arrays
549  ncerr = nctk_def_arrays(ncid, [&
550 &   nctkarr_t('current_q_point', "dp", "number_of_cartesian_directions"), &
551 &   nctkarr_t('current_q_point_weight', "dp", 'current_one_dim'), &
552 &   nctkarr_t('second_derivative_eigenenergies_actif', "dp", &
553 &     'product_mband_nsppol2, number_of_kpoints, number_of_cartesian_directions_for_gkk,'// &
554 &     'number_of_atoms_for_gkk, max_number_of_states') &
555 & ])
556  NCF_CHECK(ncerr)
557 
558  NCF_CHECK(nctk_set_datamode(ncid))
559  vid_=vid('current_q_point')
560  NCF_CHECK(nf90_put_var(ncid, vid_, iqpt))
561  vid_=vid('current_q_point_weight')
562  NCF_CHECK(nf90_put_var(ncid, vid_, wtq))
563  vid_=vid('second_derivative_eigenenergies_actif')
564  NCF_CHECK(nf90_put_var(ncid, vid_, gkk2d%gkk2d))
565 
566 #else
567  ABI_ERROR("netcdf support is not activated. ")
568 #endif
569 
570 contains
571  integer function vid(vname)
572    character(len=*),intent(in) :: vname
573    vid = nctk_idname(ncid, vname)
574  end function vid
575 
576 end subroutine gkk_ncwrite

m_eig2d/gkk_t [ Types ]

[ Top ] [ m_eig2d ] [ Types ]

NAME

 gkk_t

FUNCTION

 It contains information about the second-order derivative of the
 eigenenergies wrt atomic displacement

SOURCE

143  type,public :: gkk_t
144 
145 ! WARNING : if you modify this datatype, please check whether there might be
146 ! creation/destruction/copy routines,
147 ! declared in another part of ABINIT, that might need to take into account your
148 ! modification.
149 
150   integer :: mband                 ! Max number of bands i.e MAXVAL(nband) (to dimension arrays)
151   integer :: nsppol                ! number of spin-polarization
152   integer :: nkpt                  ! number of k points
153   integer :: natom                 ! number of atoms
154   integer :: ncart                 ! number of cartesian directions
155 
156   real(dp),allocatable :: gkk2d(:,:,:,:,:)
157   ! gkk2d(2*mband*nsppol,nkpt,ncart,natom,mband)
158   ! Second-order derivative of the eigenergies (real,im) at each
159   ! ispin,iband(real,im),k-point,dir1,natom1,jband
160 
161  end type gkk_t

m_eig2d/outbsd [ Functions ]

[ Top ] [ m_eig2d ] [ Functions ]

NAME

 outbsd

FUNCTION

 output bsd file for one perturbation (used for elphon calculations in anaddb)

INPUTS

  bdeigrf=number of bands for which the derivatives of the eigenvalues have been computed
  dtset = dataset variable for run flags
  eig2nkq= second ordre eigenvalue (or electron lifetime) that must be printed out
  mpert= maximum number of perturbations
  nkpt_rbz= number of k-points for perturbation
  unitout= writting unit of file

 OUTPUTS
  to file

 NOTE
  This function is deprecated. One should write through ddb object instead.

SOURCE

1774 subroutine outbsd(bdeigrf,dtset,eig2nkq,mpert,nkpt_rbz,unitout)
1775 
1776 !Arguments ------------------------------------
1777 !scalars
1778  integer,intent(in) :: bdeigrf,mpert,nkpt_rbz,unitout
1779  type(dataset_type),intent(in) :: dtset
1780 !arrays
1781  real(dp),intent(in) :: eig2nkq(2,dtset%mband*dtset%nsppol,nkpt_rbz,3,mpert,3,mpert)
1782 
1783 !Local variables -------------------------
1784 !scalars
1785  integer :: bandtot_index,iband,idir1,idir2,ikpt,ipert1,ipert2,isppol
1786 
1787 ! *********************************************************************
1788 
1789 
1790 !output information in this file
1791  write(unitout,*)
1792  write(unitout,'(a,i8)') ' 2nd eigenvalue derivatives   - # elements :', 9*dtset%natom**2
1793  write(unitout,'(a,3es16.8,a)') ' qpt', dtset%qptn(:), ' 1.0'
1794 
1795 !output RF eigenvalues
1796 
1797  do ikpt=1,nkpt_rbz
1798 !  bandtot_index differs from zero only in the spin-polarized case
1799    bandtot_index=0
1800    write (unitout,'(a,3es16.8)') ' K-point:', dtset%kptns(:,ikpt)
1801    do isppol=1,dtset%nsppol
1802      do iband=1,bdeigrf
1803        write (unitout,'(a,i5)') ' Band:', iband+bandtot_index
1804 !      write (unitout,*) 'ipert1     ','idir1     ','ipert2     ','idir2    ','Real    ','Im    '
1805        do ipert2=1,mpert
1806          do idir2=1,3
1807            do ipert1=1,mpert
1808              do idir1=1,3
1809                write (unitout,'(4i4,2d22.14)') idir1,ipert1,idir2,ipert2,&
1810 &               eig2nkq(1,iband+bandtot_index,ikpt,idir1,ipert1,idir2,ipert2),&
1811 &               eig2nkq(2,iband+bandtot_index,ikpt,idir1,ipert1,idir2,ipert2)
1812              end do !idir2
1813            end do !ipert2
1814          end do !idir1
1815        end do !ipert1
1816      end do !iband
1817      bandtot_index = bandtot_index + dtset%mband
1818    end do !isppol
1819  end do !ikpt
1820 
1821 !close bsd file
1822  close (unitout)
1823 
1824 end subroutine outbsd