TABLE OF CONTENTS
- ABINIT/m_ephwg
- m_ephwg/ephwg_double_grid_setup_kpoint
- m_ephwg/ephwg_free
- m_ephwg/ephwg_from_ebands
- m_ephwg/ephwg_get_deltas
- m_ephwg/ephwg_get_deltas_qibzk
- m_ephwg/ephwg_get_deltas_wvals
- m_ephwg/ephwg_get_zinv_weights
- m_ephwg/ephwg_new
- m_ephwg/ephwg_report_stats
- m_ephwg/ephwg_setup_kpoint
- m_ephwg/ephwg_t
ABINIT/m_ephwg [ Modules ]
NAME
m_ephwg
FUNCTION
Tools and objects to compute the weights used for the BZ integration of EPH quantities. More specifically the integration of quantities such as the imaginary part of the self-energy involving delta functions. Different approaches are available.
COPYRIGHT
Copyright (C) 2008-2024 ABINIT group (MG, HM) 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_ephwg 25 26 use defs_basis 27 use m_abicore 28 use m_errors 29 use m_xmpi 30 use m_copy 31 use m_dtset 32 use m_htetra 33 use m_nctk 34 #ifdef HAVE_NETCDF 35 use netcdf 36 #endif 37 use m_crystal 38 use m_ifc 39 use m_lgroup 40 use m_ebands 41 use m_eph_double_grid 42 use m_krank 43 44 use defs_datatypes, only : ebands_t 45 use m_time, only : cwtime, cwtime_report 46 use m_symtk, only : matr3inv 47 use m_numeric_tools, only : arth, inrange, wrap2_pmhalf 48 use m_special_funcs, only : gaussian 49 use m_fstrings, only : strcat, ltoa, itoa, ftoa, ktoa, sjoin 50 use m_simtet, only : sim0onei, SIM0TWOI 51 use m_kpts, only : kpts_timrev_from_kptopt, kpts_ibz_from_kptrlatt, kpts_map 52 use m_occ, only : occ_fd, occ_be 53 54 implicit none 55 56 private
m_ephwg/ephwg_double_grid_setup_kpoint [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_setup_kpoint
FUNCTION
Set internal tables and object required to compute integration weights for a given k-point using the double grid routines to map the different k-points. This version should be more efficient than its counterpart without the double grid.
INPUTS
kpoint(3): k-point in reduced coordinates. prtvol: Verbosity level comm: MPI communicator
OUTPUT
SOURCE
457 subroutine ephwg_double_grid_setup_kpoint(self, eph_doublegrid, kpoint, prtvol, comm) 458 459 !Arguments ------------------------------------ 460 !scalars 461 class(ephwg_t),target,intent(inout) :: self 462 type(eph_double_grid_t),intent(inout) :: eph_doublegrid 463 integer,intent(in) :: prtvol, comm 464 !arrays 465 real(dp),intent(in) :: kpoint(3) 466 467 !Local variables------------------------------- 468 !scalars 469 integer,parameter :: timrev0 = 0 470 integer :: ierr,ii,ik_idx 471 character(len=80) :: errorstring 472 !character(len=500) :: msg 473 type(crystal_t),pointer :: cryst 474 !arrays 475 integer,allocatable :: lgkibz2bz(:) !indkk(:,:), 476 integer,allocatable :: bz2lgkibz(:), bz2lgkibzkq(:) !, bz2bz(:), mapping(:,:) 477 !real(dp) :: kpt(3), wrap_kpt(3), shift 478 !---------------------------------------------------------------------- 479 480 cryst => self%cryst 481 482 ! Get little group of the (external) kpoint. 483 call self%lgk%free() 484 self%lgk = lgroup_new(self%cryst, kpoint, self%timrev, self%nbz, self%bz, self%nibz, self%ibz, comm) 485 if (prtvol > 0) call self%lgk%print() 486 self%nq_k = self%lgk%nibz 487 488 ! get dg%bz --> self%lgrp%ibz 489 ABI_REMALLOC(eph_doublegrid%bz2lgkibz, (eph_doublegrid%dense_nbz)) 490 491 ! Old version using all crystal symmetries 492 !call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,& 493 ! cryst%symrel, cryst%nsym, & 494 ! eph_doublegrid%bz2lgkibz, has_timrev=1) 495 call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,& 496 self%lgk%symrec_lg, self%lgk%nsym_lg, & 497 eph_doublegrid%bz2lgkibz, timrev0, use_symrec=.true.) 498 499 ! self%lgrp%ibz --> dg%bz 500 ABI_ICALLOC(lgkibz2bz, (self%lgk%nibz)) 501 do ii=1,self%nbz 502 ik_idx = eph_doublegrid%bz2lgkibz(ii) 503 lgkibz2bz(ik_idx) = ii 504 enddo 505 506 ! get self%lgrp%ibz --> dg%bz --> self%ibz 507 ABI_REMALLOC(self%lgk2ibz, (self%nq_k)) 508 do ii=1,self%nq_k 509 ik_idx = lgkibz2bz(ii) 510 self%lgk2ibz(ii) = eph_doublegrid%bz2ibz_dense(ik_idx) 511 enddo 512 513 ! calculate k+q 514 do ii=1,self%nq_k 515 self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) + kpoint 516 end do 517 518 ! get dg%bz --> lgk%ibz (k+q) 519 ABI_MALLOC(bz2lgkibzkq, (eph_doublegrid%dense_nbz)) 520 ! Old version using all crystal symmetries 521 !call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,& 522 ! cryst%symrel, cryst%nsym, & 523 ! bz2lgkibzkq, has_timrev=1) 524 call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,& 525 self%lgk%symrec_lg, self%lgk%nsym_lg, & 526 bz2lgkibzkq, timrev0, use_symrec=.true.) 527 528 ! self%lgrp%ibz (k+q) --> dg%bz 529 do ii=1,self%nbz 530 ik_idx = bz2lgkibzkq(ii) 531 lgkibz2bz(ik_idx) = ii 532 enddo 533 ABI_FREE(bz2lgkibzkq) 534 535 ! get self%lgrp%ibz (k+q) --> dg%bz --> self%ibz 536 ABI_REMALLOC(self%kq2ibz, (self%nq_k)) 537 do ii=1,self%nq_k 538 ik_idx = lgkibz2bz(ii) 539 self%kq2ibz(ii) = eph_doublegrid%bz2ibz_dense(ik_idx) 540 enddo 541 ABI_FREE(lgkibz2bz) 542 543 ! revert change 544 do ii=1,self%nq_k 545 self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) - kpoint 546 end do 547 548 ! get self%bz --> dg%bz --> self%lgrp%ibz 549 ABI_MALLOC(bz2lgkibz, (self%nbz)) 550 551 do ii=1,self%nbz 552 ! get self%bz --> dg%bz 553 ik_idx = eph_doublegrid%get_index(self%bz(:,ii),2) 554 ! dg%bz --> self%lgrp%ibz 555 bz2lgkibz(ii) = eph_doublegrid%bz2lgkibz(ik_idx) 556 end do 557 558 ! Build tetrahedron object using IBZ(k) as the effective IBZ 559 ! This means that input data for tetra routines must be provided in lgk%kibz_q 560 call self%tetra_k%free() 561 call htetra_init(self%tetra_k, bz2lgkibz, cryst%gprimd, self%klatt, self%bz, self%nbz, & 562 self%lgk%ibz, self%nq_k, ierr, errorstring, comm) 563 if (ierr /= 0) then 564 ABI_ERROR(errorstring) 565 end if 566 ABI_FREE(bz2lgkibz) 567 568 end subroutine ephwg_double_grid_setup_kpoint
m_ephwg/ephwg_free [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_free
FUNCTION
Deallocate memory
INPUTS
OUTPUT
SOURCE
975 subroutine ephwg_free(self) 976 977 !Arguments ------------------------------------ 978 class(ephwg_t),intent(inout) :: self 979 980 !---------------------------------------------------------------------- 981 982 ! integer 983 ABI_SFREE(self%kq2ibz) 984 985 ! Real 986 ABI_SFREE(self%ibz) 987 ABI_SFREE(self%bz) 988 ABI_SFREE(self%lgk2ibz) 989 ABI_SFREE(self%phfrq_ibz) 990 ABI_SFREE(self%eigkbs_ibz) 991 992 ! types 993 call self%tetra_k%free() 994 call self%lgk%free() 995 996 ! nullify pointers 997 self%cryst => null() 998 999 end subroutine ephwg_free
m_ephwg/ephwg_from_ebands [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_from_ebands
FUNCTION
Convenience constructor to initialize the object from an ebands_t object
m_ephwg/ephwg_get_deltas [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_get_deltas
FUNCTION
Compute weights for $ \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $ for a given (band, spin) and phonon mode nu.
INPUTS
band=band index (global index i.e. unshifted) spin=Spin index nu=Phonon branch. nene=number of energies for DOS eminmax=min and energy in delta (linear mesh) bcorr=1 to include Blochl correction else 0. comm=MPI communicator [broad]=Gaussian broadening
OUTPUT
deltaw_pm(nene, nq_k, 2) (plus, minus) including the weights for BZ integration.
SOURCE
637 subroutine ephwg_get_deltas(self, band, spin, nu, nene, eminmax, bcorr, deltaw_pm, comm, & 638 broad) ! optional 639 640 !Arguments ------------------------------------ 641 !scalars 642 integer,intent(in) :: band, spin, nu, nene, bcorr, comm 643 class(ephwg_t),intent(in) :: self 644 real(dp),optional,intent(in) :: broad 645 !arrays 646 real(dp),intent(in) :: eminmax(2) 647 real(dp),intent(out) :: deltaw_pm(nene, self%nq_k, 2) 648 649 !Local variables------------------------------- 650 !scalars 651 integer :: iq,iq_ibz,ikpq_ibz,ib,ie 652 real(dp),parameter :: max_occ1 = one 653 real(dp) :: omega_step 654 !arrays 655 real(dp) :: wme0(nene) 656 real(dp),allocatable :: thetaw(:,:), pme_k(:,:) 657 658 !---------------------------------------------------------------------- 659 660 ib = band - self%bstart + 1 661 662 ABI_MALLOC(thetaw, (nene, self%nq_k)) 663 ABI_MALLOC(pme_k, (self%nq_k, 2)) 664 665 ! Fill array for e_{k+q, b} +- w_{q,nu) 666 do iq=1,self%nq_k 667 iq_ibz = self%lgk2ibz(iq) ! IBZ_k --> IBZ 668 ikpq_ibz = self%kq2ibz(iq) ! k + q --> IBZ 669 pme_k(iq, 1) = self%eigkbs_ibz(ikpq_ibz, ib, spin) - self%phfrq_ibz(iq_ibz, nu) 670 pme_k(iq, 2) = self%eigkbs_ibz(ikpq_ibz, ib, spin) + self%phfrq_ibz(iq_ibz, nu) 671 end do 672 673 if (present(broad)) then 674 omega_step = (eminmax(2) - eminmax(1)) / (nene - 1) 675 ! Use thetaw as workspace array 676 thetaw(:, 1) = arth(eminmax(1), omega_step, nene) 677 do iq=1,self%nq_k 678 do ie=1,2 679 wme0 = thetaw(:, 1) - pme_k(iq, ie) 680 deltaw_pm(:, iq, ie) = gaussian(wme0, broad) 681 end do 682 end do 683 684 ! Multiply by weights 685 do ie=1,nene 686 deltaw_pm(ie, :, 1) = deltaw_pm(ie, :, 1) * self%lgk%weights 687 deltaw_pm(ie, :, 2) = deltaw_pm(ie, :, 2) * self%lgk%weights 688 end do 689 690 else 691 ! TODO Add routine to compute only delta 692 call self%tetra_k%blochl_weights(pme_k(:,1), eminmax(1), eminmax(2), max_occ1, nene, self%nq_k, & 693 bcorr, thetaw, deltaw_pm(:,:,1), comm) 694 call self%tetra_k%blochl_weights(pme_k(:,2), eminmax(1), eminmax(2), max_occ1, nene, self%nq_k, & 695 bcorr, thetaw, deltaw_pm(:,:,2), comm) 696 end if 697 698 ABI_FREE(thetaw) 699 ABI_FREE(pme_k) 700 701 end subroutine ephwg_get_deltas
m_ephwg/ephwg_get_deltas_qibzk [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_get_deltas_qibzk
FUNCTION
Compute weights for $ \delta(\omega - \omega_{q\nu} $ for given nu, using q-opints in the IBZ(k)
INPUTS
nu=Phonon branch. nene=number of energies for DOS eminmax=min and energy in delta (linear mesh) bcorr=1 to include Blochl correction else 0. comm=MPI communicator [with_qweights]= .False. if q-point weights should not be included in dt_weights
OUTPUT
dt_weights(nene, nq_k, 2) weights for BZ integration (delta and theta function)
SOURCE
808 subroutine ephwg_get_deltas_qibzk(self, nu, nene, eminmax, bcorr, dt_weights, comm, with_qweights) 809 810 !Arguments ------------------------------------ 811 !scalars 812 integer,intent(in) :: nu, nene, bcorr, comm 813 class(ephwg_t),intent(in) :: self 814 logical,optional,intent(in) :: with_qweights 815 !arrays 816 real(dp),intent(in) :: eminmax(2) 817 real(dp),intent(out) :: dt_weights(nene, self%nq_k, 2) 818 819 !Local variables------------------------------- 820 !scalars 821 integer :: iq, iq_ibz, ie, ii 822 real(dp),parameter :: max_occ1 = one 823 !arrays 824 real(dp),allocatable :: eigen_in(:) 825 826 !---------------------------------------------------------------------- 827 828 ABI_MALLOC(eigen_in, (self%nq_k)) 829 830 ! Fill eigen_in 831 do iq=1,self%nq_k 832 iq_ibz = self%lgk2ibz(iq) ! IBZ_k --> IBZ 833 eigen_in(iq) = self%phfrq_ibz(iq_ibz, nu) 834 end do 835 836 call self%tetra_k%blochl_weights(eigen_in, eminmax(1), eminmax(2), max_occ1, nene, self%nq_k, & 837 bcorr, dt_weights(:,:,2), dt_weights(:,:,1), comm) 838 839 if (present(with_qweights)) then 840 if (.not. with_qweights) then 841 do ii=1,2 842 do ie=1,nene 843 dt_weights(ie, :, ii) = dt_weights(ie, :, ii) * self%lgk%weights 844 end do 845 end do 846 end if 847 end if 848 849 ABI_FREE(eigen_in) 850 851 end subroutine ephwg_get_deltas_qibzk
m_ephwg/ephwg_get_deltas_wvals [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_get_deltas_wvals
FUNCTION
Compute weights for $ \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $ for a given (band, spin) and phonon mode nu.
INPUTS
band=band index (global index i.e. unshifted) spin=Spin index nu=Phonon branch. nene=number of energies for DOS eminmax=min and energy in delta (linear mesh) bcorr=1 to include Blochl correction else 0. comm=MPI communicator [broad]=Gaussian broadening
OUTPUT
deltaw_pm(nene, nq_k, 2) (plus, minus) including the weights for BZ integration.
SOURCE
730 subroutine ephwg_get_deltas_wvals(self, band, spin, nu, neig, eig, bcorr, deltaw_pm, comm, & 731 broad) ! optional 732 733 !Arguments ------------------------------------ 734 !scalars 735 integer,intent(in) :: band, spin, nu, neig, bcorr, comm 736 real(dp),intent(in) :: eig(neig) 737 class(ephwg_t),intent(in) :: self 738 real(dp),optional,intent(in) :: broad 739 !arrays 740 real(dp),intent(out) :: deltaw_pm(neig,self%nq_k, 2) 741 742 !Local variables------------------------------- 743 !scalars 744 real(dp),parameter :: max_occ1 = one 745 integer :: iq, iq_ibz, ikpq_ibz, ib, nprocs, my_rank 746 real(dp) :: wme0(neig) 747 !arrays 748 real(dp),allocatable :: pme_k(:,:) 749 750 !---------------------------------------------------------------------- 751 752 nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 753 ib = band - self%bstart + 1 754 deltaw_pm = zero 755 756 ABI_MALLOC(pme_k, (self%nq_k, 2)) 757 758 ! Fill array for e_{k+q, b} +- w_{q,nu) 759 do iq=1,self%nq_k 760 iq_ibz = self%lgk2ibz(iq) ! IBZ_k --> IBZ 761 ikpq_ibz = self%kq2ibz(iq) ! k + q --> IBZ 762 pme_k(iq, 1) = self%eigkbs_ibz(ikpq_ibz, ib, spin) - self%phfrq_ibz(iq_ibz, nu) 763 pme_k(iq, 2) = self%eigkbs_ibz(ikpq_ibz, ib, spin) + self%phfrq_ibz(iq_ibz, nu) 764 end do 765 766 ! Compute the tetrahedron or gaussian weights 767 if (present(broad)) then 768 do iq_ibz=1,self%nq_k 769 if (mod(iq_ibz, nprocs) /= my_rank) cycle ! MPI parallelism 770 wme0 = eig - pme_k(iq_ibz, 1) 771 deltaw_pm(:,iq_ibz,1) = gaussian(wme0, broad) * self%lgk%weights(iq_ibz) 772 wme0 = eig - pme_k(iq_ibz, 2) 773 deltaw_pm(:,iq_ibz,2) = gaussian(wme0, broad) * self%lgk%weights(iq_ibz) 774 end do 775 else 776 call self%tetra_k%wvals_weights_delta(pme_k(:, 1), neig, eig, max_occ1, self%nq_k, bcorr, deltaw_pm(:,:,1), comm) 777 call self%tetra_k%wvals_weights_delta(pme_k(:, 2), neig, eig, max_occ1, self%nq_k, bcorr, deltaw_pm(:,:,2), comm) 778 end if 779 780 ABI_FREE(pme_k) 781 782 end subroutine ephwg_get_deltas_wvals
m_ephwg/ephwg_get_zinv_weights [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_get_zinv_weights
FUNCTION
Compute weights for a given (kpoint, qpoint, spin) for all phonon modes.
INPUTS
nz: Number of frequencies nbcalc=Number of bands in self-energy matrix elements. zvals(nw): z-values iband_sum = band index in self-energy sum. (global index i.e. unshifted) spin=Spin index nu=Phonon branch index zinv_opt: 1 for S. Kaprzyk routines, 2 for Lambin-Vigneron. comm=MPI communicator [use_bzsum]= By default the weights are multiplied by the Nstar(q) / Nq where Nstar(q) is the number of points in the star of the q-point (using the symmetries of the little group of k) If use_bzsum is set to True, the Nstar(q) coefficient is removed so that the caller can integrate over the BZ without using symmetries. [erange(2)]: if present, weights are computed with an approximated asyntotic expression if real(z) is outside of this interval and with tetra if inside.
OUTPUT
cweights(nz, 2, nbcalc, %nq_k) (plus, minus) include weights for BZ integration.
SOURCE
887 subroutine ephwg_get_zinv_weights(self, nz, nbcalc, zvals, iband_sum, spin, nu, zinv_opt, cweights, comm, use_bzsum, erange) 888 889 !Arguments ------------------------------------ 890 !scalars 891 integer,intent(in) :: iband_sum, spin, nu, nz, nbcalc, zinv_opt, comm 892 class(ephwg_t),intent(in) :: self 893 logical, optional, intent(in) :: use_bzsum 894 !arrays 895 complex(dpc),intent(in) :: zvals(nz, nbcalc) 896 complex(dpc),intent(out) :: cweights(nz, 2, nbcalc, self%nq_k) 897 real(dp),optional,intent(in) :: erange(2) 898 899 !Local variables------------------------------- 900 !scalars 901 integer,parameter :: master = 0 902 integer :: iq_ibz, ikpq_ibz, ib, ii, iq, nprocs, my_rank !, ierr 903 real(dp),parameter :: max_occ1 = one 904 !real(dp) :: emin, emax 905 logical :: use_bzsum_ 906 !arrays 907 real(dp) :: my_erange(2) 908 real(dp),allocatable :: pme_k(:,:) 909 complex(dp),allocatable :: cweights_tmp(:,:) 910 !---------------------------------------------------------------------- 911 912 nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 913 914 use_bzsum_ = .False.; if (present(use_bzsum)) use_bzsum_ = use_bzsum 915 my_erange = [-huge(one), huge(one)]; if (present(erange)) my_erange = erange 916 917 ! Allocate array for e_{k+q, b} +- w_{q,nu) 918 ABI_MALLOC(pme_k, (self%nq_k, 2)) 919 920 ib = iband_sum - self%bstart + 1 921 do iq=1,self%nq_k 922 iq_ibz = self%lgk2ibz(iq) ! IBZ_k --> IBZ 923 ikpq_ibz = self%kq2ibz(iq) ! k + q --> IBZ 924 pme_k(iq, 1) = self%eigkbs_ibz(ikpq_ibz, ib, spin) - self%phfrq_ibz(iq_ibz, nu) 925 pme_k(iq, 2) = self%eigkbs_ibz(ikpq_ibz, ib, spin) + self%phfrq_ibz(iq_ibz, nu) 926 end do 927 928 ! As this part is quite demanding, especially when nz is large, use input z-mesh 929 ! when we are inside the window in which the denominator can blow up (+- some tolerance) 930 ! Outside the window, downsample the mesh use to compute the weights and spline the results. 931 !if (zinv_opt == 2) then 932 ! emin = minval(self%eigkbs_ibz(:, ib, spin)) 933 ! emax = maxval(self%eigkbs_ibz(:, ib, spin)) 934 ! !my_erange = [emin - half * abs(emin), emax + half * abs(emax)] 935 ! my_erange = [emin - tol2 * abs(emin), emax + tol2 * abs(emax)] 936 !end if 937 938 cweights = zero 939 ABI_MALLOC(cweights_tmp, (nz, self%nq_k)) 940 941 do ib=1,nbcalc 942 do ii=1,2 943 call self%tetra_k%weights_wvals_zinv(pme_k(:, ii), nz, zvals(:, ib), max_occ1, self%nq_k, zinv_opt, & 944 cweights_tmp, comm, erange=my_erange) 945 do iq=1,self%nq_k 946 cweights(:, ii, ib, iq) = cweights_tmp(:, iq) 947 end do 948 end do 949 end do 950 951 ABI_FREE(cweights_tmp) 952 953 ! Rescale weights so that the caller can sum over the full BZ. 954 !if (use_bzsum_) cweights = cweights / ( self%lgk%weights(iqlk) * self%nbz ) 955 956 ABI_FREE(pme_k) 957 !call xmpi_sum(cweights, comm, ierr) 958 959 end subroutine ephwg_get_zinv_weights
m_ephwg/ephwg_new [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_new
FUNCTION
Initialize the object from the electronic eigenvalues given in the IBZ.
INPUTS
cryst<cryst_t>=Crystalline structure. ifc<ifc_type>=interatomic force constants and corresponding real space grid info. bstart=Index of the first band to be included. nbcount=Number of bands included kptopt=Option for the k-point generation. kptrlatt(3,3)=k-point lattice specification nshiftk= number of shift vectors. shiftk(3,nshiftk)=shift vectors for k point generation nkibz=Number of points in the IBZ kibz(3,nkibz)=Reduced coordinates of the k-points in the IBZ. nsppol=Number of independent spin polarizations. eig_ibz(nbcount, nkibz, nsppol) = Electron eigenvalues for nbcount states
OUTPUT
SOURCE
205 type(ephwg_t) function ephwg_new( & 206 cryst, ifc, bstart, nbcount, kptopt, kptrlatt, nshiftk, shiftk, nkibz, kibz, nsppol, eig_ibz, comm) result(new) 207 208 !Arguments ------------------------------------ 209 !scalars 210 integer,intent(in) :: kptopt, nshiftk, nkibz, bstart, nbcount, nsppol, comm 211 type(crystal_t),target,intent(in) :: cryst 212 type(ifc_type),intent(in) :: ifc 213 !arrays 214 integer,intent(in) :: kptrlatt(3,3) 215 real(dp),intent(in) :: shiftk(3, nshiftk), kibz(3, nkibz) 216 real(dp),intent(in) :: eig_ibz(nbcount, nkibz, nsppol) 217 218 !Local variables------------------------------- 219 !scalars 220 integer :: nprocs, my_rank, ik, ierr, out_nkibz 221 real(dp) :: cpu, wall, gflops 222 !arrays 223 real(dp) :: rlatt(3,3) 224 integer :: out_kptrlatt(3,3) 225 real(dp) :: displ_cart(2,3,cryst%natom,3*cryst%natom), phfrq(3*cryst%natom) 226 real(dp),allocatable :: out_kibz(:,:), out_wtk(:) 227 228 !---------------------------------------------------------------------- 229 230 nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm) 231 232 new%natom3 = ifc%natom * 3 233 new%nsppol = nsppol 234 new%nbcount = nbcount 235 new%bstart = bstart 236 new%kptopt = kptopt 237 new%timrev = kpts_timrev_from_kptopt(new%kptopt) 238 new%nibz = nkibz 239 new%cryst => cryst 240 call alloc_copy(kibz, new%ibz) 241 242 call cwtime(cpu, wall, gflops, "start") 243 244 ! Get full BZ (new%nbz, new%bz) and new kptrlatt for tetra. 245 call kpts_ibz_from_kptrlatt(cryst, kptrlatt, kptopt, nshiftk, shiftk, out_nkibz, out_kibz, out_wtk, new%nbz, new%bz, & 246 new_kptrlatt=out_kptrlatt) 247 call cwtime_report(" ephwg_new: kpts_ibz_from_kptrlatt", cpu, wall, gflops) 248 249 new%kptrlatt = out_kptrlatt 250 rlatt = out_kptrlatt; call matr3inv(rlatt, new%klatt) 251 252 ABI_CHECK(size(out_kibz, dim=2) == new%nibz, "mismatch in nkibz!") 253 ABI_FREE(out_kibz) 254 ABI_FREE(out_wtk) 255 256 ! Copy eigenvalues in IBZ. Change shape for better performance in other routines. 257 ABI_MALLOC(new%eigkbs_ibz, (new%nibz, new%nbcount, new%nsppol)) 258 do ik=1,new%nibz 259 new%eigkbs_ibz(ik, :, :) = eig_ibz(:, ik, :) 260 end do 261 262 ! Fourier interpolate phonon frequencies on the same mesh. 263 ABI_CALLOC(new%phfrq_ibz, (new%nibz, new%natom3)) 264 265 do ik=1,new%nibz 266 if (mod(ik, nprocs) /= my_rank) cycle ! mpi-parallelism 267 call ifc%fourq(cryst, new%ibz(:, ik), phfrq, displ_cart) 268 new%phfrq_ibz(ik, :) = phfrq 269 end do 270 271 ! Collect results on each rank 272 call xmpi_sum(new%phfrq_ibz, comm, ierr) 273 274 !new%max_phfrq = maxval(phfrq_ibz) 275 276 call cwtime_report(" ephwg_new: ifc_fourq", cpu, wall, gflops) 277 278 end function ephwg_new
m_ephwg/ephwg_report_stats [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_report_stats
FUNCTION
INPUTS
OUTPUT
SOURCE
585 subroutine ephwg_report_stats(self) 586 587 !Arguments ------------------------------------ 588 !scalars 589 class(ephwg_t),intent(in) :: self 590 591 !Variables 592 real(dp) :: mem_tot 593 !---------------------------------------------------------------------- 594 595 ! IBZ qpoints 596 mem_tot = 3 * self%nibz * dp 597 ! BZ qpoints 598 mem_tot = mem_tot + 3 * self%nbz * dp 599 ! lgk2ibz and kq2ibz 600 mem_tot = mem_tot + self%nq_k * 2 * 4 601 ! phonon frequencies 602 mem_tot = mem_tot + self%nibz * self%natom3 * dp 603 ! eigenvalues 604 mem_tot = mem_tot + self%nibz * self%nbcount * self%nsppol * dp 605 606 write(std_out,"(a,f8.1,a)") " Memory allocated for ephwg weights:", mem_tot * b2Mb, " [Mb] <<< MEM" 607 608 end subroutine ephwg_report_stats
m_ephwg/ephwg_setup_kpoint [ Functions ]
[ Top ] [ m_ephwg ] [ Functions ]
NAME
ephwg_setup_kpoint
FUNCTION
Set internal tables and object required to compute integration weights for a given k-point.
INPUTS
kpoint(3): k-point in reduced coordinates. prtvol: Verbosity level comm: MPI communicator
OUTPUT
SOURCE
337 subroutine ephwg_setup_kpoint(self, kpoint, prtvol, comm, skip_mapping) 338 339 !Arguments ------------------------------------ 340 !scalars 341 class(ephwg_t),target,intent(inout) :: self 342 integer,intent(in) :: prtvol, comm 343 logical,optional,intent(in) :: skip_mapping 344 !arrays 345 real(dp),intent(in) :: kpoint(3) 346 347 !Local variables------------------------------- 348 !scalars 349 integer :: ierr,ii 350 logical :: do_mapping 351 real(dp) :: cpu, wall, gflops 352 character(len=80) :: errorstring 353 !character(len=500) :: msg 354 type(crystal_t),pointer :: cryst 355 type(krank_t) :: krank 356 !arrays 357 integer,allocatable :: indkk(:,:) 358 359 !---------------------------------------------------------------------- 360 361 do_mapping = .true.; if (present(skip_mapping)) do_mapping = .not. skip_mapping 362 cryst => self%cryst 363 call cwtime(cpu, wall, gflops, "start") 364 365 ! Get little group of the (external) kpoint. 366 call self%lgk%free() 367 self%lgk = lgroup_new(self%cryst, kpoint, self%timrev, self%nbz, self%bz, self%nibz, self%ibz, comm) 368 369 if (prtvol > 0) call self%lgk%print() 370 self%nq_k = self%lgk%nibz 371 372 call cwtime_report(" lgroup_new", cpu, wall, gflops) 373 374 if (do_mapping) then 375 ! TODO: Use symrec conventions although this means that we cannot reuse these tables 376 ! to symmetrize wavefunctions and potentials that require S-1 i.e. the symrel convention. 377 378 ! Get mapping IBZ_k --> initial IBZ (self%lgk%ibz --> self%ibz) 379 ABI_MALLOC(indkk, (6, self%nq_k)) 380 381 krank = krank_from_kptrlatt(self%nibz, self%ibz, self%kptrlatt, compute_invrank=.False.) 382 383 if (kpts_map("symrel", self%timrev, cryst, krank, self%nq_k, self%lgk%ibz, indkk) /= 0) then 384 ABI_ERROR("At least one of the points in IBZ(k) could not be generated from a symmetrical one.") 385 end if 386 387 call krank%free() 388 389 ABI_SFREE(self%lgk2ibz) 390 call alloc_copy(indkk(1, :), self%lgk2ibz) 391 ABI_FREE(indkk) 392 call cwtime_report(" listkk1", cpu, wall, gflops) 393 394 ! Get mapping (k + q) --> initial IBZ. 395 do ii=1,self%nq_k 396 self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) + kpoint 397 end do 398 ABI_MALLOC(indkk, (6, self%nq_k)) 399 400 krank = krank_from_kptrlatt(self%nibz, self%ibz, self%kptrlatt, compute_invrank=.False.) 401 402 if (kpts_map("symrel", self%timrev, cryst, krank, self%nq_k, self%lgk%ibz, indkk) /= 0) then 403 ABI_ERROR("At least one of the points in IBZ(k) + q could not be generated from a symmetrical one.") 404 end if 405 call krank%free() 406 407 call cwtime_report(" listkk2", cpu, wall, gflops) 408 409 ABI_SFREE(self%kq2ibz) 410 call alloc_copy(indkk(1, :), self%kq2ibz) 411 ABI_FREE(indkk) 412 413 ! Revert changes 414 do ii=1,self%nq_k 415 self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) - kpoint 416 end do 417 end if 418 419 ! Get mapping BZ --> IBZ_k (self%bz --> self%lgrp%ibz) required for tetrahedron method 420 ABI_MALLOC(indkk, (self%nbz, 1)) 421 indkk(:, 1) = self%lgk%bz2ibz_smap(1, :) 422 423 ! Build tetrahedron object using IBZ(k) as the effective IBZ 424 ! This means that input data for tetra routines must be provided in lgk%kibz_q 425 call self%tetra_k%free() 426 call htetra_init(self%tetra_k, indkk(:, 1), cryst%gprimd, self%klatt, self%bz, self%nbz, & 427 self%lgk%ibz, self%nq_k, ierr, errorstring, comm) 428 !call tetra_write(self%tetra_k, self%lgk%nibz, self%lgk%ibz, strcat("tetrak_", ktoa(kpoint))) 429 ABI_CHECK(ierr == 0, errorstring) 430 431 if (xmpi_comm_rank(comm) == 0) call self%tetra_k%print(std_out) 432 ABI_FREE(indkk) 433 434 call cwtime_report(" init_tetra", cpu, wall, gflops) 435 436 end subroutine ephwg_setup_kpoint
m_ephwg/ephwg_t [ Types ]
NAME
ephwg_t
FUNCTION
Stores electron eigevalues and phonon frequencies in the IBZ (assume same mesh for e and ph). Provides tools to compute (e_{k+q} - w{q}) in the IBZ(k) and integrate the delta functions for phonon emission/absorption with the tetrahedron method.
SOURCE
72 type, public :: ephwg_t 73 74 integer :: natom3 75 ! 3 * natom 76 77 integer :: nsppol 78 ! Number of independent spin polarizations. 79 80 integer :: nbcount 81 ! Number of bands treated. 82 83 integer :: bstart 84 ! The fist band (global index) starts at bstart. 85 ! Used to select bands around the Fermi level. 86 87 integer :: kptopt 88 ! Option for k-point generation. 89 90 integer :: timrev 91 ! 1 if the use of time-reversal is allowed; 0 otherwise 92 93 integer :: nibz, nbz 94 ! Number of q-points in IBZ and full BZ. 95 96 integer :: nq_k 97 ! Number of points in IBZ(k) i.e. the irreducible wedge 98 ! defined by the operations of the little group of k. 99 100 !real(dp) :: max_phfrq 101 ! Max Phonon frequency, computed from phfrq_ibz 102 103 integer :: kptrlatt(3,3) 104 ! Value of kptrlatt after inkpts. So one shift 105 106 integer, allocatable :: kq2ibz(:) 107 ! kq2ibz(nq_k) 108 ! Mapping (k + q) --> initial IBZ array 109 110 real(dp),allocatable :: ibz(:,:) 111 ! ibz(3, nibz) 112 ! The initial IBZ. 113 114 real(dp),allocatable :: bz(:,:) 115 ! bz(3, nbz) 116 ! points in full BZ. 117 118 real(dp) :: klatt(3, 3) 119 ! Reciprocal of lattice vectors for full kpoint grid. Used by init_tetra 120 121 integer,allocatable :: lgk2ibz(:) 122 ! lgk2ibz(nq_k) 123 ! Mapping Little-group IBZ_k --> initial IBZ 124 ! TODO: This should be generalized to have the symmetry indices as well so 125 ! that we can use it in sigmaph but then we have to implement similar algo for double grid. 126 127 real(dp),allocatable :: phfrq_ibz(:,:) 128 ! (nibz, natom3) 129 ! Phonon frequencies in the IBZ 130 131 real(dp),allocatable :: eigkbs_ibz(:, :, :) 132 ! (nibz, nbcount, nsppol) 133 ! Electron eigenvalues in the IBZ for nbcount states 134 ! (not necessarly equal to global nband, see also bstart and bcount) 135 136 type(crystal_t), pointer :: cryst => null() 137 ! Pointer to input structure (does not own memory) 138 139 type(lgroup_t) :: lgk 140 ! Little group of the k-point 141 142 type(htetra_t) :: tetra_k 143 ! Used to evaluate delta(w - e_{k+q} +/- phw_q) with tetrahedron method. 144 145 contains 146 147 procedure :: setup_kpoint => ephwg_setup_kpoint 148 ! Prepare tetrahedron method for given external k-point. 149 150 procedure :: double_grid_setup_kpoint => ephwg_double_grid_setup_kpoint 151 ! Prepare tetrahedron method for given external k-point using double grid routines. 152 153 procedure :: report_stats => ephwg_report_stats 154 ! Report how much memory is being used by this object 155 156 procedure :: get_deltas => ephwg_get_deltas 157 ! Compute weights for $ \int \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $ 158 159 procedure :: get_deltas_wvals => ephwg_get_deltas_wvals 160 ! Compute weights for $ \int \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $ 161 162 procedure :: get_deltas_qibzk => ephwg_get_deltas_qibzk 163 ! Compute weights for $ \delta(\omega - \omega_{q\nu}} $ using IBZ(k) ordering 164 165 procedure :: get_zinv_weights => ephwg_get_zinv_weights 166 ! Compute weights for $ \int 1 / (\omega - \ee_{k+q, b} \pm \omega_{q\nu} $ 167 168 procedure :: free => ephwg_free 169 ! Free memory 170 end type ephwg_t 171 172 public :: ephwg_new ! Basic Constructor 173 public :: ephwg_from_ebands ! Build object from ebands_t 174 175 contains