LCOV - code coverage report
Current view: top level - src/69_wfdesc - m_wfd_optic.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.8 % 84 83
Test Date: 2026-11-09 22:30:52 Functions: 100.0 % 2 2
Branches: 67.8 % 230 156

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_wfd_optic
       2                 :             : !! NAME
       3                 :             : !!  m_wfd_optic
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Functions to compute optical matrix elements using the wavefunction descriptor.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG)
      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_wfd_optic
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_errors
      26                 :             :  use m_abicore
      27                 :             :  use m_xmpi
      28                 :             : 
      29                 :             :  use defs_datatypes,      only : pseudopotential_type
      30                 :             :  use m_hide_lapack,       only : matrginv
      31                 :             :  use m_bz_mesh,           only : kmesh_t
      32                 :             :  use m_crystal,           only : crystal_t
      33                 :             :  use m_vkbr,              only : vkbr_t, vkbr_free, vkbr_init, nc_ihr_comm
      34                 :             :  use m_ebands,            only : ebands_t
      35                 :             :  use m_wfd,               only : wfdgw_t, wave_t
      36                 :             :  use m_pawtab,            only : pawtab_type
      37                 :             :  use m_pawcprj,           only : pawcprj_type, pawcprj_alloc, pawcprj_free
      38                 :             :  use m_paw_hr,            only : pawhur_t, paw_ihr
      39                 :             : 
      40                 :             :  implicit none
      41                 :             : 
      42                 :             :  private
      43                 :             : !!***
      44                 :             : 
      45                 :             :  public :: calc_optical_mels
      46                 :             : !!***
      47                 :             : 
      48                 :             : contains
      49                 :             : !!***
      50                 :             : 
      51                 :             : !!****f* ABINIT/calc_optical_mels
      52                 :             : !! NAME
      53                 :             : !!  calc_optical_mels
      54                 :             : !!
      55                 :             : !! FUNCTION
      56                 :             : !!  Calculate all optical matrix elements in the BZ.
      57                 :             : !!
      58                 :             : !! INPUTS
      59                 :             : !! lomo_spin(Wfd%nsppol)=Index of the lomo band for the different spins.
      60                 :             : !! lomo_min,max_band=minimum and max band index to be calculated.
      61                 :             : !! nkbz=Number of points in the full Brillouin zone.
      62                 :             : !! inclvkb=if different from 0, [Vnl,r] is included in the calculation of the
      63                 :             : !!   matrix element of the velocity operator. No meaning for PAW (except for DFT+U)
      64                 :             : !! qpt(3)
      65                 :             : !! Kmesh<kmesh_t>=Info on the k-point sampling for wave functions.
      66                 :             : !! Cryst<crystal_t>=Structure defining the crystalline structure.
      67                 :             : !! KS_Bst<ebands_t>
      68                 :             : !! Pawtab(Cryst%ntypat*usepaw)<pawtab_type>=PAW tabulated starting data
      69                 :             : !! Psps <pseudopotential_type>=variables related to pseudopotentials.
      70                 :             : !! Hur(Cryst%natom*usepaw)<pawhur_t>=Only for PAW and DFT+U, quantities used to evaluate the commutator [H_u,r].
      71                 :             : !! Wfd<wfdgw_t>=Handler for the wavefunctions.
      72                 :             : !!
      73                 :             : !! OUTPUT
      74                 :             : !! opt_cvk(lomo_min:max_band,lomo_min:max_band,nkbz,nsppol)=Matrix elements <c k|e^{+iqr}|v k>
      75                 :             : !!
      76                 :             : !! SOURCE
      77                 :             : 
      78                 :         180 : subroutine calc_optical_mels(Wfd,Kmesh,KS_Bst,Cryst,Psps,Pawtab,Hur,&
      79                 :         180 : &  inclvkb,lomo_spin,lomo_min,max_band,nkbz,qpoint,opt_cvk)
      80                 :             : 
      81                 :             : !Arguments ------------------------------------
      82                 :             : !scalars
      83                 :             :  integer,intent(in) :: nkbz,inclvkb,lomo_min,max_band
      84                 :             :  type(kmesh_t),intent(in) :: Kmesh
      85                 :             :  type(crystal_t),intent(in) :: Cryst
      86                 :             :  type(pseudopotential_type),intent(in) :: Psps
      87                 :             :  type(ebands_t),intent(in) :: KS_Bst
      88                 :             :  type(wfdgw_t),target,intent(inout) :: Wfd
      89                 :             : !arrays
      90                 :             :  integer,intent(in) :: lomo_spin(Wfd%nsppol)
      91                 :             :  real(dp),intent(in) :: qpoint(3)
      92                 :             :  complex(dp),intent(out) :: opt_cvk(lomo_min:max_band,lomo_min:max_band,nkbz,Wfd%nsppol)
      93                 :             :  type(pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
      94                 :             :  type(pawhur_t),intent(in) :: Hur(Cryst%natom*Wfd%usepaw)
      95                 :             : 
      96                 :             : !Local variables ------------------------------
      97                 :             : !scalars
      98                 :             :  integer :: nsppol,usepaw,nspinor,comm,spin,npw_k,istwf_k,my_nbbp
      99                 :             :  integer :: ik_bz,ik_ibz,itim_k,isym_k,ib_c,ib_v,ierr,my_rank
     100                 :             :  real(dp) :: ediff
     101                 :             :  complex(dp) :: emcvk
     102                 :             :  character(len=500) :: msg
     103                 :         180 :  type(vkbr_t) :: vkbr
     104                 :             :  type(wave_t),pointer :: wave_v, wave_c
     105                 :             : !arrays
     106                 :         180 :  integer,allocatable :: bbp_distrb(:,:)
     107                 :         180 :  integer,contiguous, pointer :: kg_k(:,:)
     108                 :             :  real(dp) :: mat_dp(3,3),qrot(3),b1(3),b2(3),b3(3),kbz(3)
     109                 :         180 :  complex(dp),allocatable :: ir_kibz(:,:,:,:,:)
     110                 :         180 :  complex(gwp), contiguous, pointer :: ug_c(:),ug_v(:)
     111                 :         360 :  complex(gwp) :: ihrc(3,Wfd%nspinor**2)
     112                 :         360 :  logical :: bbp_mask(Wfd%mband,Wfd%mband)
     113                 :         180 :  type(pawcprj_type),allocatable :: Cp_v(:,:),Cp_c(:,:)
     114                 :             : !************************************************************************
     115                 :             : 
     116                 :         180 :  call wrtout(std_out," Calculating optical matrix elements in the IBZ","COLL")
     117         [ -  + ]:         180 :  ABI_CHECK(Wfd%nspinor==1,"nspinor==2 not coded")
     118                 :             : 
     119                 :         180 :  comm = Wfd%comm
     120                 :         180 :  my_rank = Wfd%my_rank
     121                 :             : 
     122                 :         180 :  nsppol  = Wfd%nsppol
     123                 :         180 :  nspinor = Wfd%nspinor
     124                 :         180 :  usepaw  = Wfd%usepaw
     125                 :             : 
     126         [ +  + ]:         180 :  if (usepaw==1) then
     127   [ -  +  +  -  :          84 :    ABI_MALLOC(Cp_v,(Wfd%natom,nspinor))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     128                 :          12 :    call pawcprj_alloc(Cp_v,0,Wfd%nlmn_atm)
     129   [ -  +  +  -  :          84 :    ABI_MALLOC(Cp_c,(Wfd%natom,nspinor))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     130                 :          12 :    call pawcprj_alloc(Cp_c,0,Wfd%nlmn_atm)
     131                 :             :  end if
     132                 :             : 
     133   [ -  +  -  - ]:         180 :  if (inclvkb==1.and.usepaw==0) then
     134                 :           0 :    ABI_ERROR("inclvkb==1 not coded,using inclvkb==2")
     135                 :             :  end if
     136                 :             :  !
     137                 :             :  ! Calculate the matrix elements of ir in the IBZ.
     138   [ -  +  +  -  :        1080 :  ABI_MALLOC(ir_kibz,(3,lomo_min:max_band,lomo_min:max_band,Wfd%nkibz,nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     139   [ +  +  +  +  :     1001316 :  ir_kibz=czero
          +  +  +  +  +  
                      + ]
     140                 :             : 
     141   [ -  +  +  -  :         720 :  ABI_MALLOC(bbp_distrb, (Wfd%mband,Wfd%mband))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     142                 :             : 
     143         [ +  + ]:         366 :  do spin=1,nsppol
     144         [ +  + ]:        7122 :    do ik_ibz=1,Wfd%nkibz
     145                 :             :     !
     146                 :             :     ! Distribute the (b,b') entries.
     147   [ +  +  +  +  :      660552 :     bbp_mask=.FALSE.; bbp_mask(lomo_spin(spin):max_band,lomo_spin(spin):max_band)=.TRUE.
             +  +  +  + ]
     148                 :        6756 :     call wfd%distribute_bbp(ik_ibz,spin,"All",my_nbbp,bbp_distrb,bbp_mask=bbp_mask)
     149   [ +  -  +  +  :       72762 :     if (ALL(bbp_distrb/=my_rank)) CYCLE
             +  +  -  + ]
     150                 :             : 
     151                 :        6756 :     istwf_k = Wfd%istwfk(ik_ibz)
     152         [ -  + ]:        6756 :     ABI_CHECK(istwf_k==1,"istwf_k/=1 not coded") ! KB stuff is missing.
     153                 :        6756 :     npw_k = Wfd%npwarr(ik_ibz)
     154                 :        6756 :     kg_k  => Wfd%Kdata(ik_ibz)%kg_k
     155                 :             : 
     156   [ +  -  +  + ]:        6756 :     if (inclvkb/=0.and.usepaw==0) then
     157                 :             :       ! Prepare term i <n,k|[Vnl,r]|n"k>
     158                 :        6714 :       call vkbr_init(vkbr,Cryst,Psps,inclvkb,istwf_k,npw_k,Kmesh%ibz(:,ik_ibz),kg_k)
     159                 :             :     end if
     160                 :             : 
     161                 :             :     ! Note: spinorial case is not coded therefore we work with ihrc(:,1).
     162                 :             :     ! TODO: The lower triangle can be Reconstructed by symmetry.
     163         [ +  + ]:       46350 :     do ib_v=lomo_spin(spin),max_band ! Loop over bands
     164   [ +  -  +  +  :       94164 :       if ( ALL(bbp_distrb(ib_v,:)/=my_rank) ) CYCLE
                   +  - ]
     165                 :             : 
     166         [ -  + ]:       39594 :       ABI_CHECK(wfd%get_wave_ptr(ib_v, ik_ibz, spin, wave_v, msg) == 0, msg)
     167                 :       39594 :       ug_v => wave_v%ug
     168         [ +  + ]:       39594 :       if (usepaw==1) call wfd%get_cprj(ib_v,ik_ibz,spin,Cryst,Cp_v,sorted=.FALSE.)
     169                 :             : 
     170         [ +  + ]:      285000 :       do ib_c=lomo_spin(spin),max_band
     171         [ +  + ]:      238650 :        if (bbp_distrb(ib_v,ib_c)/=my_rank) CYCLE
     172         [ -  + ]:      200250 :        ABI_CHECK(wfd%get_wave_ptr(ib_c, ik_ibz, spin, wave_c, msg) == 0, msg)
     173                 :      200250 :        ug_c => wave_c%ug
     174                 :             : 
     175         [ +  + ]:      200250 :        if (usepaw==0) then
     176                 :             :          ! Calculate matrix elements of i[H,r] for NC pseudopotentials.
     177                 :      198426 :          ihrc = nc_ihr_comm(vkbr,cryst,psps,npw_k,nspinor,istwf_k,inclvkb,Kmesh%ibz(:,ik_ibz),ug_c,ug_v,kg_k)
     178                 :             : 
     179                 :             :        else
     180                 :             :          ! Matrix elements of i[H,r] for PAW.
     181                 :        1824 :          call wfd%get_cprj(ib_c,ik_ibz,spin,Cryst,Cp_c,sorted=.FALSE.)
     182                 :             : 
     183                 :        1824 :          ihrc = paw_ihr(spin,nspinor,npw_k,istwf_k,Kmesh%ibz(:,ik_ibz),Cryst,Pawtab,ug_c,ug_v,kg_k,Cp_c,Cp_v,HUr)
     184                 :             :        end if
     185                 :             :        !
     186                 :             :        ! Save matrix elements of i*r in the IBZ
     187                 :      200250 :        ediff = KS_Bst%eig(ib_c,ik_ibz,spin) - KS_BSt%eig(ib_v,ik_ibz,spin)
     188         [ +  + ]:      200250 :        if (ABS(ediff)<tol16) ediff=tol6  ! Treat a possible degeneracy between v and c.
     189         [ +  + ]:      840594 :        ir_kibz(:,ib_c,ib_v,ik_ibz,spin) = ihrc(:,1)/ediff
     190                 :             : 
     191                 :             :       end do !ib_c
     192                 :             :     end do !ib_v
     193                 :             : 
     194                 :        6942 :     call vkbr_free(vkbr)
     195                 :             :    end do !spin
     196                 :             :  end do !ik_ibz
     197                 :             : 
     198                 :             :  ! Collect results on each node.
     199                 :         180 :  call xmpi_sum(ir_kibz,comm,ierr)
     200                 :             : 
     201         [ -  + ]:         180 :  ABI_FREE(bbp_distrb)
     202                 :             : 
     203         [ +  + ]:         180 :  if (usepaw==1) then
     204                 :          12 :    call pawcprj_free(Cp_v)
     205   [ +  -  +  +  :          36 :    ABI_FREE(Cp_v)
          -  +  -  +  -  
                      + ]
     206                 :          12 :    call pawcprj_free(Cp_c)
     207   [ +  -  +  +  :          36 :    ABI_FREE(Cp_c)
          -  +  -  +  -  
                      + ]
     208                 :             :  end if
     209                 :             :  !
     210                 :             :  ! ======================================================
     211                 :             :  ! ==== Calculate Fcv(kBZ) in the full Brilouin zone ====
     212                 :             :  ! ======================================================
     213                 :             :  !
     214                 :             :  ! Symmetrization of the matrix elements of the position operator.
     215                 :             :  ! <Sk b|r|Sk b'> = R <k b|r|k b'> + \tau \delta_{bb'}
     216                 :             :  !   where S is one of the symrec operations in reciprocal space, R is the
     217                 :             :  !   corresponding operation in real space, \tau being the associated fractional translations.
     218                 :             :  !
     219                 :             :  ! q.Mcv( Sk) =  S^{-1}q. Mcv(k)
     220                 :             :  ! q.Mcv(-Sk) = -S^{-1}q. CONJG(Mcv(k)) if time-reversal is used.
     221                 :             : 
     222         [ +  + ]:         720 :  b1=Cryst%gprimd(:,1)*two_pi
     223         [ +  + ]:         720 :  b2=Cryst%gprimd(:,2)*two_pi
     224         [ +  + ]:         720 :  b3=Cryst%gprimd(:,3)*two_pi
     225                 :             : 
     226   [ +  +  +  +  :      384126 :  opt_cvk = czero
             +  +  +  + ]
     227         [ +  + ]:         366 :  do spin=1,nsppol
     228         [ +  + ]:        8862 :    do ik_bz=1,nkbz
     229                 :             :     !
     230                 :             :     ! Get ik_ibz, and symmetries index from ik_bz.
     231                 :        8496 :     call Kmesh%get_BZ_item(ik_bz,kbz,ik_ibz,isym_k,itim_k)
     232                 :             : 
     233   [ +  +  +  + ]:      110448 :     mat_dp = DBLE(Cryst%symrec(:,:,isym_k))
     234                 :        8496 :     call matrginv(mat_dp,3,3) ! Invert
     235   [ +  +  +  +  :      135936 :     qrot = (3-2*itim_k) * MATMUL(mat_dp,qpoint)
                   +  + ]
     236                 :             : 
     237         [ +  + ]:       60426 :     do ib_v=lomo_spin(spin),max_band !  Loops over the bands C and V start
     238         [ +  + ]:      383760 :       do ib_c=lomo_spin(spin),max_band
     239                 :             :         !if (ib_c==ib_v) CYCLE
     240                 :      323520 :         emcvk = pdtqrc(qrot,ir_kibz(:,ib_c,ib_v,ik_ibz,spin),b1,b2,b3)
     241         [ +  + ]:      323520 :         if (itim_k==2) emcvk = CONJG(emcvk)
     242                 :      375264 :         opt_cvk(ib_c,ib_v,ik_bz,spin) = emcvk
     243                 :             :       end do !ib_c
     244                 :             :     end do !ib_v
     245                 :             : 
     246                 :             :    end do !ik_bz
     247                 :             :  end do !spin
     248                 :             : 
     249         [ -  + ]:         180 :  ABI_FREE(ir_kibz)
     250                 :             : 
     251   [ -  +  -  +  :         540 :  call xmpi_barrier(comm)
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  -  -  
                      - ]
     252                 :             : 
     253                 :             : contains
     254                 :             : !!***
     255                 :             : 
     256                 :             : !!****f* ABINIT/pdtqrc
     257                 :             : !! NAME
     258                 :             : !!  pdtqrc
     259                 :             : !!
     260                 :             : !! FUNCTION
     261                 :             : !!  Calculate the dot product of a real vector with a complex vector, where each is in terms of b1-b3
     262                 :             : !!
     263                 :             : !! INPUTS
     264                 :             : !!
     265                 :             : !! OUTPUT
     266                 :             : !!
     267                 :             : !! SOURCE
     268                 :             : 
     269                 :      323520 : pure function pdtqrc(R,C,b1,b2,b3)
     270                 :             : 
     271                 :             : !Arguments ------------------------------------
     272                 :             : !arrays
     273                 :             :  real(dp),intent(in) :: R(3),b1(3),b2(3),b3(3)
     274                 :             :  complex(dp),intent(in) :: C(3)
     275                 :             :  complex(dp) :: pdtqrc
     276                 :             : 
     277                 :             : !Local variables ------------------------------
     278                 :             : !scalars
     279                 :             :  integer :: ii
     280                 :             : !************************************************************************
     281                 :             : 
     282                 :      323520 :  pdtqrc=czero
     283         [ +  + ]:     1294080 :  do ii=1,3
     284                 :             :    pdtqrc = pdtqrc + (R(1)*b1(ii)+R(2)*b2(ii)+R(3)*b3(ii)) * &
     285                 :     1294080 : &                    (C(1)*b1(ii)+C(2)*b2(ii)+C(3)*b3(ii))
     286                 :             :  end do
     287                 :             : 
     288                 :      323520 : end function pdtqrc
     289                 :             : !!***
     290                 :             : 
     291                 :             : end subroutine calc_optical_mels
     292                 :             : !!***
     293                 :             : 
     294                 :             : end module m_wfd_optic
     295                 :             : !!***
        

Generated by: LCOV version 2.3-1