DIPOLE_ypp_driver.F Source File


Source Code

!
! License-Identifier: GPL
!
! Copyright (C) 2020 The Yambo Team
!
! Authors (see AUTHORS file for details): AM
!
! headers
!
#include<y_memory.h>
!
subroutine DIPOLE_ypp_driver(k,E,q)
 !
 use pars,           ONLY:SP,rZERO,schlen
 use com,            ONLY:msg
 use stderr,         ONLY:intc
 use R_lattice,      ONLY:bz_samp
 use electrons,      ONLY:levels,n_spin
 use YPPm,           ONLY:DIPs_C_bands,DIPs_V_bands,DIPs_E_range,DIPs_direction,K_transform,coo_out,INTERP_grid,&
&                         l_PROJECT_plane,l_PROJECT_line,PROJECT_N_par,DIPs,DIPs_mask,DIPs_kind
 use DIPOLES,        ONLY:DIPOLES_reset,DIP_iR,DIP_desc
 use ALLOC,          ONLY:DIPOLE_ALLOC_global
 use parallel_m,     ONLY:PAR_IND_DIPk_ibz,PAR_IND_CON_BANDS_DIP,PAR_IND_VAL_BANDS_DIP,PAR_DIPk_ibz_index
 use parallel_int,   ONLY:PARALLEL_global_indexes,PP_redux_wait
 use QP_CTL_m,       ONLY:QP_apply
 use vec_operate,    ONLY:v_norm
 use interfaces,     ONLY:DESC_write
 use IO_m,           ONLY:deliver_IO_error_message
 use OUTPUT,         ONLY:OUTPUT_driver
 use YPP_interfaces, ONLY:PROJECTION_setup,PROJECTION_plot
 use parser_m,       ONLY:parser
 use interpolate,    ONLY:INTERPOLATION_driver_seed,INTERPOLATION_driver_do,GRID_k,INTERP_obj
 use y_memory_alloc
 !
 implicit none
 !
 type(bz_samp)  :: k,q
 type(levels)   :: E
 !
 ! Work Space
 !
 integer     :: ik,ic,iv,is,ikbz,ID,NK,ik_plane,ik_mem,BANDS_done(DIPs_C_bands(2)),io_err
 complex(SP) :: DIP_projected
 real(SP)    :: delta_E,v(3),DIP_accumulated(1,k%nibz,1)
 logical     :: BAND_fields_controls(2)
 character(schlen)     :: BANDS_str
 real(SP), allocatable :: DIP_plane(:,:,:)
 integer,  external    :: PROJECTION_k_on_the_path_or_plane
 !
 BAND_fields_controls=.FALSE.
 !
 if (trim(DIPs_kind)=="IP") then
   !
   call section('*','IP Dipole Properties')
   !=======================================================
   !
   ! ... Apply QP corrections
   call QP_apply((/DIPs_V_bands(1),DIPs_C_bands(2)/),E,k,'G',msg_fmt='rs')
   !
   !... PROJECTION setup
   call PROJECTION_setup("setup")
   if (l_PROJECT_line) then
     call warning("Line Projection not possible in DIPOLES mode. Switched off")
     l_PROJECT_line=.FALSE.
   endif
   if (l_PROJECT_plane.and.all((/INTERP_grid>0/))) then
     call warning("Plane Projection and Interpolation not simultaneously possible. Interpolation Switched off")
     INTERP_grid=-1
   endif
   !
   call PROJECTION_setup("DIPOLES",(/1,1/))
   !
   call parser('DIP_C_bands', BAND_fields_controls(1))
   call parser('DIP_V_bands', BAND_fields_controls(2))
   !
 endif
 !
 ! ... Dimensions
 if (all(BAND_fields_controls)) then
   DIPs%ib    =(/DIPs_V_bands(1),DIPs_C_bands(2)/)
   DIPs%ib_lim=(/DIPs_V_bands(2),DIPs_C_bands(1)/)
 else
   DIPs_V_bands=(/DIPs%ib(1),DIPs%ib_lim(1)/)
   DIPs_C_bands=(/DIPs%ib_lim(2),DIPs%ib(2)/)
 endif
 !
 ! ... PARALLEL setup
 call PARALLEL_global_indexes(E,k,q," ",RESET=.TRUE.)
 call PARALLEL_global_indexes(E,k,q,"DIPOLES",Dip=DIPs,Dip_limits_pre_defined=all(BAND_fields_controls))
 !
 ! ... IO
 call DIPOLE_IO(k,e,DIPs,'read ',io_err,'DIP')
 call deliver_IO_error_message(io_err,"Dipoles",.TRUE.)
 !
 if (trim(DIPs_kind)=="LOAD") return
 !
 DIPs_direction=DIPs_direction/v_norm(DIPs_direction)
 !
 ! ... Alloc
 if (trim(DIPs_kind)=="MASK") then
   YAMBO_ALLOC(DIPs_mask,(DIPs_V_bands(1):DIPs_V_bands(2),k%nibz,n_spin))
   DIPs_mask=rZERO
   BANDS_str=" "
   BANDS_done=0
 endif
 if (trim(DIPs_kind)=="IP") DIP_accumulated=rZERO
 !
 ! ... Loop
 do ik=1,k%nibz
   if (.not.PAR_IND_DIPk_ibz%element_1D(ik)) cycle
   ik_mem=PAR_DIPk_ibz_index(ik)
   do iv=DIPs_V_bands(1),DIPs_V_bands(2)
     if (.not.PAR_IND_VAL_BANDS_DIP%element_1D(iv)) cycle
     do ic=DIPs_C_bands(1),DIPs_C_bands(2)
       if (.not.PAR_IND_CON_BANDS_DIP%element_1D(ic)) cycle
       do is=1,n_spin
         delta_E=E%E(ic,ik,is)-E%E(iv,ik,is)
         if (DIPs_E_range(1)>0._SP .and. delta_E<DIPs_E_range(1)) cycle
         if (DIPs_E_range(2)>0._SP .and. delta_E>DIPs_E_range(2)) cycle
         DIP_projected=dot_product(DIPs_direction,DIP_iR(:,ic,iv,ik_mem,is))
         if (trim(DIPs_kind)=="IP") then
           DIP_accumulated(1,ik,1)=DIP_accumulated(1,ik,1)+abs(DIP_projected)**2
         endif
         if (trim(DIPs_kind)=="MASK") then
           DIPs_mask(iv,ik,is)=DIPs_mask(iv,ik,is)+abs(DIP_projected)**2
         endif
         if (BANDS_done(ic)==0) BANDS_str=trim(BANDS_str)//" "//trim(intc(ic))
         BANDS_done(ic)=1
       enddo
     enddo
   enddo
 enddo
 !
 if (trim(DIPs_kind)=="MASK") then
   call msg('s','Conduction band(s) contributing to the MASK',trim(BANDS_str))
   call PP_redux_wait( DIPs_mask )
 endif
 if (trim(DIPs_kind)=="IP") call PP_redux_wait( DIP_accumulated(1,:,1))
 if (.not.trim(DIPs_kind)=="IP") then
   call LOCAL_clean()
   return
 endif
 !
 !... Normalization
 DIP_accumulated=DIP_accumulated/maxval( DIP_accumulated )
 !
 ! ... INTERPOLATION
 if (all(INTERP_grid>0)) call INTERPOLATION_create_the_grid(INTERP_grid)
 if (allocated(GRID_k%pt)) then
   !
   call INTERPOLATION_driver_seed("DIPOLES",ID,(/1,1/),k,SEED_R3=DIP_accumulated)
   call INTERPOLATION_driver_do("DIPOLES",ID,GRID_k)
   !
   ! ... PROJECTION
   if (l_PROJECT_plane) then
     YAMBO_ALLOC(DIP_plane,(PROJECT_N_par,1,1))
     DIP_plane=rZERO
     do ikbz=1,GRID_k%nbz
       ik_plane=PROJECTION_k_on_the_path_or_plane(ikbz)
       if (ik_plane==0) cycle
       if (INTERP_obj(ID)%INTERP(1,ikbz,1)<0._SP) cycle
       DIP_plane(ik_plane,1,1)=DIP_plane(ik_plane,1,1)+INTERP_obj(ID)%INTERP(1,ikbz,1)
     enddo
   endif
   call PROJECTION_plot("DIPOLES", 1,1, (/1,1/), OBS_K=DIP_plane)
   !
 endif
 !
 if (.not.l_PROJECT_plane) then
   !
   ! ... Print
   call OUTPUT_driver("electronic_dipoles",action="reset")
   call OUTPUT_driver("electronic_dipoles",action="open")
   call DESC_write('o electronic_dipoles','#',DIP_desc)
   !
   NK=k%nbz
   if (allocated(GRID_k%ptbz)) NK=GRID_k%nbz
   !
   do ikbz=1,NK
     if (allocated(GRID_k%ptbz)) then
       v=GRID_k%ptbz(ikbz,:)
       ik=ikbz
     else
       v=k%ptbz(ikbz,:)
       ik=k%sstar(ikbz,1)
     endif
     call K_transform(v,'iku')
     call OUTPUT_driver("electronic_dipoles",TITLES=(/"k_x ("//trim(coo_out)//")",&
&                                    "k_y ("//trim(coo_out)//")","k_z ("//trim(coo_out)//")"/),R_VALUES=v)
     if (allocated(GRID_k%pt)) then
       call OUTPUT_driver("electronic_dipoles",TITLES=(/"|<v|R|c>.DIP_dir|^2"/),R_values=(/INTERP_obj(ID)%INTERP(1,ikbz,1)/))
     else
       call OUTPUT_driver("electronic_dipoles",TITLES=(/"|<v|R|c>.DIP_dir|^2"/),R_values=(/DIP_accumulated(1,ik,1)/))
     endif
     call OUTPUT_driver("electronic_dipoles",action="write")
   enddo
   call OUTPUT_driver("electronic_dipoles",action="close")
   !
 endif
 !
 !... Clean
 call LOCAL_clean( )
 YAMBO_FREE(DIP_plane)
 if (all(INTERP_grid>0)) call INTERPOLATION_driver_end(0)
 !
 contains 
   !
   subroutine LOCAL_clean
    call DIPOLE_ALLOC_global( )
    call DIPOLES_reset(DIPs)
   end subroutine
   !
end subroutine

📚 Documentation Pages
⏱️ Real-Time
🔗 Code API