TABLE OF CONTENTS
- ABINIT/m_sigmaph
- m_sigmaph/qpoints_oracle
- m_sigmaph/sigmaph
- m_sigmaph/sigmaph_compare
- m_sigmaph/sigmaph_free
- m_sigmaph/sigmaph_gather_and_write
- m_sigmaph/sigmaph_get_all_qweights
- m_sigmaph/sigmaph_get_ebands
- m_sigmaph/sigmaph_new
- m_sigmaph/sigmaph_print
- m_sigmaph/sigmaph_read
- m_sigmaph/sigmaph_setup_kcalc
- m_sigmaph/sigmaph_setup_qloop
- m_sigmaph/sigmaph_skip_phmode
- m_sigmaph/sigmaph_t
- m_sigmaph/sigmaph_write
ABINIT/m_sigmaph [ Modules ]
NAME
m_sigmaph
FUNCTION
Compute the matrix elements of the Fan-Migdal Debye-Waller self-energy in the KS basis set.
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
16 #if defined HAVE_CONFIG_H 17 #include "config.h" 18 #endif 19 20 #include "abi_common.h" 21 22 module m_sigmaph 23 24 use defs_basis 25 use, intrinsic :: iso_c_binding 26 use m_abicore 27 #ifdef HAVE_MPI2 28 use mpi 29 #endif 30 use m_xmpi 31 use m_mpinfo 32 use m_errors 33 use m_hide_blas 34 use m_copy 35 use m_ifc 36 use m_ebands 37 use m_wfk 38 use m_ddb 39 use m_ddk 40 use m_dvdb 41 use m_fft 42 use m_hamiltonian 43 use m_pawcprj 44 use m_wfd 45 use m_skw 46 use m_krank 47 use m_lgroup 48 use m_ephwg 49 use m_sort 50 use m_hdr 51 use m_sigtk 52 use m_ephtk 53 use m_eph_double_grid 54 use netcdf 55 use m_nctk 56 use m_rf2 57 use m_dtset 58 use m_dtfil 59 use m_clib 60 use m_mkffnl 61 62 use defs_abitypes, only : mpi_type 63 use defs_datatypes, only : ebands_t, pseudopotential_type 64 use m_time, only : cwtime, cwtime_report, timab, sec2str 65 use m_fstrings, only : itoa, ftoa, sjoin, ktoa, ltoa, strcat 66 use m_numeric_tools, only : arth, c2r, get_diag, linfit, iseven, simpson_cplx, simpson, print_arr, inrange 67 use m_io_tools, only : iomode_from_fname, file_exists, is_open, open_file, flush_unit 68 use m_special_funcs, only : gaussian 69 use m_fftcore, only : ngfft_seq, sphereboundary, get_kg, kgindex 70 use m_cgtk, only : cgtk_rotate, cgtk_change_gsphere 71 use m_cgtools, only : cg_zdotc, cg_real_zdotc, cg_zgemm, fxphas_seq 72 use m_crystal, only : crystal_t 73 use m_kpts, only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map 74 use m_occ, only : occ_fd, occ_be !occ_dfde, 75 use m_kg, only : getph, mkkpg 76 use m_bz_mesh, only : isamek 77 use m_getgh1c, only : getgh1c, rf_transgrid_and_pack, getgh1c_setup 78 use m_ioarr, only : read_rhor 79 use m_paw_sphharm, only : ylm_angular_mesh 80 use m_pawang, only : pawang_type 81 use m_pawrad, only : pawrad_type 82 use m_pawtab, only : pawtab_type 83 use m_pawrhoij, only : pawrhoij_type 84 use m_pawfgr, only : pawfgr_type 85 use m_dfpt_cgwf, only : dfpt_cgwf 86 use m_phonons, only : phstore_t, phstore_new 87 88 implicit none 89 90 private
m_sigmaph/qpoints_oracle [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
qpoints_oracle
FUNCTION
This function tries to predict the **full** list of q-points in the BZ needed to compute the lifetimes once we know sigma%nkcalc. It uses an energy window computed from the max phonon frequency multiplied by sigma%phwinfact. INPUT cryst=Crystalline structure ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) qpts(3, nqpt)= nqpt= Number of points in qpts nqbz=Number of q-points in BZ. qbz(3, nbz) = full BZ comm=MPI communicator.
OUTPUT
qselect(nqpt)
SOURCE
5602 subroutine qpoints_oracle(sigma, dtset, cryst, ebands, qpts, nqpt, nqbz, qbz, qselect, comm) 5603 5604 !Arguments ------------------------------------ 5605 !scalars 5606 class(sigmaph_t),intent(in) :: sigma 5607 type(dataset_type),intent(in) :: dtset 5608 type(crystal_t),intent(in) :: cryst 5609 type(ebands_t),intent(in) :: ebands 5610 integer,intent(in) :: nqpt, nqbz, comm 5611 !arrays 5612 real(dp),intent(in) :: qpts(3,nqpt), qbz(3,nqbz) 5613 integer,intent(out) :: qselect(nqpt) 5614 5615 !Local variables ------------------------------ 5616 !scalars 5617 integer,parameter :: master = 0 5618 integer :: spin, ikcalc, ik_ibz, iq_bz, ierr, db_iqpt, ibsum_kq, ikq_ibz, ikq_bz 5619 integer :: cnt, my_rank, nprocs, ib_k, band_ks, nkibz, nkbz, kq_rank, qptopt, qtimrev 5620 real(dp) :: eig0nk, eig0mkq, ediff, cpu, wall, gflops 5621 character(len=5000) :: msg 5622 type(krank_t) :: krank, qrank 5623 !arrays 5624 integer :: g0(3), qptrlatt(3,3) 5625 integer,allocatable :: qbz_count(:), qbz2qpt(:,:), bz2ibz(:,:) 5626 real(dp) :: kq(3), kk(3) 5627 real(dp),allocatable :: wtk(:), kibz(:,:), kbz(:,:) 5628 5629 ! ************************************************************************* 5630 5631 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 5632 5633 call cwtime(cpu, wall, gflops, "start") 5634 call wrtout(std_out, & 5635 sjoin(" qpoints_oracle: predicting number q-points for tau with eph_phwinfact:", ftoa(sigma%phwinfact))) 5636 5637 ! Get full BZ associated to ebands 5638 call kpts_ibz_from_kptrlatt(cryst, ebands%kptrlatt, ebands%kptopt, ebands%nshiftk, ebands%shiftk, & 5639 nkibz, kibz, wtk, nkbz, kbz, bz2ibz=bz2ibz) 5640 call cwtime_report(" kpts_ibz_from_kptrlatt", cpu, wall, gflops) 5641 5642 ABI_FREE(wtk) 5643 ABI_FREE(kibz) 5644 ABI_CHECK(nkibz == ebands%nkpt, "nkibz != ebands%nkpt") 5645 5646 ! Make full k-point rank arrays 5647 krank = krank_new(nkbz, kbz) 5648 call cwtime_report(" krank_new", cpu, wall, gflops) 5649 5650 ! This loop is Expensive with a 288^3 5651 ! qbz_count_loop completed. cpu: 03:16 [minutes] , wall: 03:16 [minutes] <<< TIME 5652 ! qbz_count completed. cpu: 04:41 [minutes] , wall: 04:40 [minutes] <<< TIME 5653 ABI_ICALLOC(qbz_count, (nqbz)) 5654 cnt = 0 5655 do spin=1,sigma%nsppol 5656 do ikcalc=1,sigma%nkcalc 5657 cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism inside comm 5658 kk = sigma%kcalc(:, ikcalc) 5659 ik_ibz = sigma%kcalc2ibz(ikcalc, 1) 5660 do iq_bz=1,nqbz 5661 if (qbz_count(iq_bz) /= 0) cycle ! No need to check this q-point again. 5662 kq = kk + qbz(:, iq_bz) 5663 kq_rank = krank%get_rank(kq) 5664 ikq_bz = krank%invrank(kq_rank) 5665 ABI_CHECK(ikq_bz > 0, sjoin("Cannot find kq: ", ktoa(kq))) 5666 ABI_CHECK(isamek(kq, kbz(:, ikq_bz), g0), "Wrong invrank") 5667 !ikq_ibz = bz2ibz(ikq_bz,1) 5668 ikq_ibz = bz2ibz(1, ikq_bz) 5669 do ib_k=1,sigma%nbcalc_ks(ikcalc, spin) 5670 band_ks = ib_k + sigma%bstart_ks(ikcalc, spin) - 1 5671 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 5672 do ibsum_kq=sigma%bsum_start, sigma%bsum_stop 5673 eig0mkq = ebands%eig(ibsum_kq, ikq_ibz, spin) 5674 ediff = eig0nk - eig0mkq 5675 ! Perform check on the energy difference to exclude this q-point. 5676 if (abs(ediff) <= sigma%phwinfact * sigma%wmax) qbz_count(iq_bz) = qbz_count(iq_bz) + 1 5677 end do 5678 end do 5679 end do 5680 end do 5681 end do 5682 call cwtime_report(" qbz_count_loop", cpu, wall, gflops) 5683 5684 ABI_FREE(kbz) 5685 ABI_FREE(bz2ibz) 5686 call krank%free() 5687 5688 call xmpi_sum(qbz_count, comm, ierr) 5689 call cwtime_report(" qbz_count", cpu, wall, gflops) 5690 5691 ! Get mapping QBZ --> List of q-points involved in e-ph scattering for e/h in pockets. 5692 ! Assume qptopt == kptopt unless value is specified in input 5693 ABI_MALLOC(qbz2qpt, (6, nqbz)) 5694 5695 qptrlatt = 0; qptrlatt(1,1) = sigma%ngqpt(1); qptrlatt(2,2) = sigma%ngqpt(2); qptrlatt(3,3) = sigma%ngqpt(3) 5696 qrank = krank_from_kptrlatt(nqpt, qpts, qptrlatt, compute_invrank=.False.) 5697 qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt 5698 qtimrev = kpts_timrev_from_kptopt(qptopt) 5699 5700 if (kpts_map("symrec", qtimrev, cryst, qrank, nqbz, qbz, qbz2qpt) /= 0) then 5701 write(msg, '(3a)' )& 5702 "At least one of the q-points could not be generated from a symmetrical one in the DVDB.", ch10, & 5703 "Action: check your DVDB file and use eph_task to interpolate the potentials on a denser q-mesh." 5704 ABI_ERROR(msg) 5705 end if 5706 call qrank%free() 5707 5708 call cwtime_report(" oracle_listkk_qbz_qpts", cpu, wall, gflops) 5709 5710 ! Compute qselect using qbz2qpt. 5711 qselect = 0 5712 do iq_bz=1,nqbz 5713 if (qbz_count(iq_bz) == 0) cycle 5714 db_iqpt = qbz2qpt(1, iq_bz) 5715 qselect(db_iqpt) = qselect(db_iqpt) + 1 5716 end do 5717 5718 ABI_FREE(qbz_count) 5719 ABI_FREE(qbz2qpt) 5720 5721 if (my_rank == master) then 5722 cnt = count(qselect /= 0) 5723 write(std_out, "(a, i0, a, f5.1, a)")" qpoints_oracle: calculation of tau_nk will need: ", cnt, & 5724 " q-points in the IBZ. (nqibz_eff / nqibz): ", (100.0_dp * cnt) / sigma%nqibz, " [%]" 5725 end if 5726 5727 end subroutine qpoints_oracle
m_sigmaph/sigmaph [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph
FUNCTION
Compute phonon-contribution to the electron self-energy.
INPUTS
wfk0_path=String with the path to the GS unperturbed WFK file. ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes. dtset<dataset_type>=All input variables for this dataset. ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) dvdb<dbdb_type>=Database with the DFPT SCF potentials. ifc<ifc_type>=interatomic force constants and corresponding real space grid info. wfk_hdr=Header of the WFK file. pawfgr <type(pawfgr_type)>=fine grid parameters and related data pawang<pawang_type)>=PAW angular mesh and related data. pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data. pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data. psps<pseudopotential_type>=Variables related to pseudopotentials. comm=MPI communicator.
OUTPUT
SOURCE
627 subroutine sigmaph(wfk0_path, dtfil, ngfft, ngfftf, dtset, cryst, ebands, dvdb, ifc, wfk_hdr, & 628 pawfgr, pawang, pawrad, pawtab, psps, mpi_enreg, comm) 629 630 !Arguments ------------------------------------ 631 !scalars 632 character(len=*),intent(in) :: wfk0_path 633 integer,intent(in) :: comm 634 type(datafiles_type),intent(in) :: dtfil 635 type(dataset_type),intent(in) :: dtset 636 type(crystal_t),intent(in) :: cryst 637 type(ebands_t),intent(in) :: ebands 638 type(dvdb_t),intent(inout) :: dvdb 639 type(pawang_type),intent(in) :: pawang 640 type(pseudopotential_type),intent(in) :: psps 641 type(pawfgr_type),intent(in) :: pawfgr 642 type(ifc_type),intent(in) :: ifc 643 type(hdr_type),intent(in) :: wfk_hdr 644 type(mpi_type),intent(inout) :: mpi_enreg 645 !arrays 646 integer,intent(in) :: ngfft(18),ngfftf(18) 647 type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw) 648 type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw) 649 650 !Local variables ------------------------------ 651 !scalars 652 integer,parameter :: tim_getgh1c1 = 1, berryopt0 = 0, istw1 = 1, ider0 = 0, idir0 = 0, istwfk1 = 1 653 integer,parameter :: useylmgr = 0, useylmgr1 =0, master = 0, ndat1 = 1 654 integer,parameter :: igscq0 = 0, icgq0 = 0, usedcwavef0 = 0, nbdbuf0 = 0, quit0 = 0, cplex1 = 1, pawread0 = 0 655 integer :: band_me, nband_me 656 integer :: my_rank,nsppol,nkpt,iq_ibz,iq_ibz_k,my_npert ! iq_ibz_frohl,iq_bz_frohl, 657 integer :: cplex,db_iqpt,natom,natom3,ipc,nspinor,nprocs, qptopt ! = 1 658 integer :: ibsum_kq, ib_k, u1c_ib_k, band_ks, u1_band, ibsum, ii, jj, iw !ib_kq, 659 !integer :: u1_master, ip 660 integer :: mcgq, mgscq, ig, ispinor, ifft !nband_kq, 661 integer :: idir,ipert,ip1,ip2,idir1,ipert1,idir2,ipert2 662 integer :: ik_ibz,ikq_ibz,isym_k,isym_kq,trev_k,trev_kq, isym_q, trev_q 663 integer :: iq_ibz_fine,ikq_ibz_fine,ikq_bz_fine 664 integer :: my_spin, spin, istwf_k, istwf_kq, istwf_kqirr, npw_k, npw_kq, npw_kqirr 665 integer :: mpw,ierr,it,imyq,band, ignore_kq, ignore_ibsum_kq 666 integer :: n1,n2,n3,n4,n5,n6,nspden,nu, iang 667 integer :: sij_opt,usecprj,usevnl,optlocal,optnl,opt_gvnlx1 668 integer :: nfft,nfftf,mgfft,mgfftf,nkpg,nkpg1,nq,cnt,imyp, q_start, q_stop, restart 669 integer :: tot_nlines_done, nlines_done, nline_in, grad_berry_size_mpw1, enough_stern 670 integer :: nbcalc_ks,nbsum,bsum_start, bsum_stop, bstart_ks,my_ikcalc,ikcalc,bstart,bstop,iatom, sendcount 671 integer :: comm_rpt, osc_npw 672 integer :: ffnlk_request, ffnl1_request, nelem, cgq_request 673 real(dp) :: cpu,wall,gflops,cpu_all,wall_all,gflops_all,cpu_ks,wall_ks,gflops_ks,cpu_dw,wall_dw,gflops_dw 674 real(dp) :: cpu_setk, wall_setk, gflops_setk, cpu_qloop, wall_qloop, gflops_qloop, gf_val 675 real(dp) :: ecut,eshift,weight_q,rfact,gmod2,hmod2,ediff,weight, inv_qepsq, simag, q0rad, out_resid 676 real(dp) :: vkk_norm, vkq_norm, osc_ecut, bz_vol 677 complex(dpc) :: cfact,dka,dkap,dkpa,dkpap, cnum, sig_cplx, cfact2 678 logical :: isirr_k, isirr_kq, gen_eigenpb, q_is_gamma, isirr_q, use_ifc_fourq, use_u1c_cache, intra_band, same_band 679 logical :: zpr_frohl_sphcorr_done 680 type(wfd_t) :: wfd 681 type(gs_hamiltonian_type) :: gs_hamkq 682 type(rf_hamiltonian_type) :: rf_hamkq 683 type(sigmaph_t) :: sigma, sigma_restart 684 type(ddkop_t) :: ddkop 685 type(rf2_t) :: rf2 686 type(crystal_t) :: pot_cryst 687 type(hdr_type) :: pot_hdr 688 type(phstore_t) :: phstore 689 type(u1cache_t) :: u1c 690 character(len=5000) :: msg 691 character(len=fnlen) :: sigeph_filepath 692 !arrays 693 integer :: g0_k(3),g0_kq(3), units(2), work_ngfft(18), gmax(3) 694 integer,allocatable :: bands_treated_now(:) 695 integer(i1b),allocatable :: itreatq_dvdb(:) 696 integer,allocatable :: gtmp(:,:),kg_k(:,:),kg_kq(:,:),nband(:,:), qselect(:), wfd_istwfk(:) 697 integer,allocatable :: gbound_kq(:,:), osc_gbound_q(:,:), osc_gvecq(:,:), osc_indpw(:), rank_band(:), root_bcalc(:) 698 integer,allocatable :: ibzspin_2ikcalc(:,:) 699 integer, allocatable :: recvcounts(:), displs(:) 700 real(dp) :: kk(3),kq(3),kk_ibz(3),kq_ibz(3),qpt(3),qpt_cart(3),phfrq(3*cryst%natom), dotri(2),qq_ibz(3) 701 real(dp) :: vk(3), vkq(3), tsec(2), eminmax(2) 702 real(dp) :: zpr_frohl_sphcorr(3*cryst%natom), vec_natom3(2, 3*cryst%natom) 703 real(dp) :: wqnu,nqnu,gkq2,gkq2_pf,eig0nk,eig0mk,eig0mkq,f_mkq, f_nk 704 real(dp) :: gdw2, gdw2_stern, rtmp 705 real(dp),allocatable,target :: cgq(:,:,:) 706 real(dp),allocatable :: displ_cart(:,:,:,:),displ_red(:,:,:,:) 707 real(dp),allocatable :: grad_berry(:,:),kinpw1(:),kpg1_k(:,:),kpg_k(:,:),dkinpw(:) 708 real(dp),allocatable :: ffnlk(:,:,:,:),ffnl1(:,:,:,:),ph3d(:,:,:),ph3d1(:,:,:),v1scf(:,:,:,:) 709 real(dp),allocatable :: gkq_atm(:,:,:),gkq_nu(:,:,:),gkq0_atm(:,:,:,:), gaussw_qnu(:) 710 real(dp),allocatable :: gscq(:,:,:), out_eig1_k(:), cg1s_kq(:,:,:,:), h1kets_kq_allperts(:,:,:,:) 711 real(dp),allocatable :: dcwavef(:, :), gh1c_n(:, :), ghc(:,:), gsc(:,:), stern_ppb(:,:,:,:), stern_dw(:,:,:,:) 712 logical,allocatable :: ihave_ikibz_spin(:,:), bks_mask(:,:,:),keep_ur(:,:,:) 713 real(dp),allocatable :: bra_kq(:,:),kets_k(:,:,:),h1kets_kq(:,:,:,:),cgwork(:,:) 714 real(dp),allocatable :: ph1d(:,:),vlocal(:,:,:,:),vlocal1(:,:,:,:,:) 715 real(dp),allocatable :: ylm_kq(:,:),ylm_k(:,:),ylmgr_kq(:,:,:) 716 real(dp),allocatable :: vtrial(:,:),gvnlx1(:,:),gvnlxc(:,:),work(:,:,:,:), vcar_ibz(:,:,:,:) 717 real(dp),allocatable :: gs1c(:,:),nqnu_tlist(:),dtw_weights(:,:),dt_tetra_weights(:,:,:),dwargs(:),alpha_mrta(:) 718 real(dp),allocatable :: delta_e_minus_emkq(:), gkq_allgather(:,:,:),f_tlist_b(:,:) 719 !real(dp),allocatable :: phfreqs_qibz(:,:), pheigvec_qibz(:,:,:,:), eigvec_qpt(:,:,:) 720 real(dp) :: ylmgr_dum(1,1,1) 721 logical,allocatable :: osc_mask(:) 722 real(dp),allocatable :: gkq2_lr(:,:,:) 723 complex(dpc) :: cp3(3) 724 complex(dpc),allocatable :: osc_ks(:,:), fmw_frohl_sphcorr(:,:,:,:), cfact_wr(:), tpp_red(:,:) 725 complex(gwpc),allocatable :: ur_k(:,:), ur_kq(:), work_ur(:), workq_ug(:) 726 type(pawcprj_type),allocatable :: cwaveprj0(:,:), cwaveprj(:,:) 727 type(pawrhoij_type),allocatable :: pawrhoij(:) 728 #if defined HAVE_MPI && !defined HAVE_MPI2_INPLACE 729 integer :: me 730 real(dp),allocatable :: cgq_buf(:) 731 real(dp),pointer :: cgq_ptr(:) 732 #endif 733 734 !************************************************************************ 735 736 if (psps%usepaw == 1) then 737 ABI_ERROR("PAW not implemented") 738 ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/)) 739 end if 740 741 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 742 call cwtime(cpu_all, wall_all, gflops_all, "start") 743 744 units = [std_out, ab_out] 745 746 ! Copy important dimensions 747 natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands%nsppol; nspinor = ebands%nspinor 748 nspden = dtset%nspden; nkpt = ebands%nkpt 749 750 ! FFT meshes from input file, not necessarly equal to the ones found in the external files. 751 nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3)) 752 nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3)) 753 n1 = ngfft(1); n2 = ngfft(2); n3 = ngfft(3) 754 n4 = ngfft(4); n5 = ngfft(5); n6 = ngfft(6) 755 756 ! Get one-dimensional structure factor information on the coarse grid. 757 ABI_MALLOC(ph1d, (2,3*(2*mgfft+1)*natom)) 758 call getph(cryst%atindx, natom, n1, n2, n3, ph1d, cryst%xred) 759 760 ecut = dtset%ecut ! dtset%dilatmx 761 762 ! Check if a previous netcdf file is present and restart the calculation 763 ! Here we try to read an existing SIGEPH file if eph_restart == 1. 764 ! and we compare the variables with the state of the code (i.e. new sigmaph generated in sigmaph_new) 765 restart = 0; ierr = 1; sigeph_filepath = strcat(dtfil%filnam_ds(4), "_SIGEPH.nc") 766 if (my_rank == master .and. dtset%eph_restart == 1) then 767 sigma_restart = sigmaph_read(sigeph_filepath, dtset, xmpi_comm_self, msg, ierr) 768 end if 769 770 ! Construct object to store final results. 771 sigma = sigmaph_new(dtset, ecut, cryst, ebands, ifc, dtfil, comm) 772 773 if (my_rank == master .and. dtset%eph_restart == 1) then 774 if (ierr == 0) then 775 if (any(sigma_restart%qp_done /= 1)) then 776 call sigma%compare(sigma_restart) 777 ! Get list of QP states that have been computed. 778 sigma%qp_done = sigma_restart%qp_done 779 restart = 1 780 call wrtout(units, "- Restarting from previous SIGEPH.nc file") 781 call wrtout(units, sjoin("- Number of k-points completed:", itoa(count(sigma%qp_done == 1)), "/", itoa(sigma%nkcalc))) 782 else 783 restart = 0; sigma%qp_done = 0 784 msg = sjoin("Found SIGEPH.nc file with all QP entries already computed.", ch10, & 785 "Will overwrite:", sigeph_filepath, ch10, & 786 "Keeping backup copy in:", strcat(sigeph_filepath, ".bkp")) 787 call wrtout(ab_out, sjoin("WARNING: ", msg)) 788 ABI_WARNING(msg) 789 ! Keep backup copy 790 ABI_CHECK(clib_rename(sigeph_filepath, strcat(sigeph_filepath, ".bkp")) == 0, "Failed to rename SIGPEPH file.") 791 end if 792 end if 793 call sigma_restart%free() 794 end if 795 796 call xmpi_bcast(restart, master, comm, ierr) 797 call xmpi_bcast(sigma%qp_done, master, comm, ierr) 798 799 if (restart == 0) then 800 call sigma%write(dtset, cryst, ebands, wfk_hdr, dtfil, comm) 801 else 802 ! Open file inside ncwrite_comm to perform parallel IO if kpt parallelism. 803 if (sigma%ncwrite_comm%value /= xmpi_comm_null) then 804 NCF_CHECK(nctk_open_modify(sigma%ncid, sigeph_filepath, sigma%ncwrite_comm%value)) 805 NCF_CHECK(nctk_set_datamode(sigma%ncid)) 806 end if 807 end if 808 809 if (.not. sigma%imag_only .and. sigma%frohl_model /= 0 .and. .not. dvdb%has_zeff) sigma%frohl_model = 0 810 811 if (my_rank == master) then 812 call sigma%print(dtset, ab_out) 813 call sigma%print(dtset, std_out) 814 end if 815 my_npert = sigma%my_npert 816 817 ! This is the maximum number of PWs for all possible k+q treated. 818 mpw = sigma%mpw; gmax = sigma%gmax 819 820 ! Init work_ngfft 821 gmax = gmax + 4 ! FIXME: this is to account for umklapp, shouls also consider Gamma-only and istwfk 822 gmax = 2*gmax + 1 823 call ngfft_seq(work_ngfft, gmax) 824 !write(std_out,*)"work_ngfft(1:3): ",work_ngfft(1:3) 825 ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6))) 826 827 ! Initialize the wave function descriptor. 828 ! Each node has all k-points and spins and bands between my_bsum_start and my_bsum_stop 829 ABI_MALLOC(nband, (nkpt, nsppol)) 830 ABI_MALLOC(bks_mask, (dtset%mband, nkpt, nsppol)) 831 ABI_MALLOC(keep_ur, (dtset%mband, nkpt ,nsppol)) 832 833 nband = dtset%mband; bks_mask = .False.; keep_ur = .False. 834 835 ! Mapping Sigma_{k,s} states to IBZ. -1 if not computed 836 ABI_MALLOC(ibzspin_2ikcalc, (nkpt, nsppol)) 837 ibzspin_2ikcalc = -1 838 839 ! Each node needs the wavefunctions for Sigma_{nk} 840 ! TODO: kcalc should depend on the spin! 841 do spin=1,sigma%nsppol 842 do ikcalc=1,sigma%nkcalc 843 ik_ibz = sigma%kcalc2ibz(ikcalc, 1) 844 bstart = sigma%bstart_ks(ikcalc, spin) 845 bstop = bstart + sigma%nbcalc_ks(ikcalc, spin) - 1 846 bks_mask(bstart:bstop, ik_ibz, spin) = .True. 847 ibzspin_2ikcalc(ik_ibz, spin) = ikcalc 848 end do 849 end do 850 851 ! For the imaginay part, add bands outside the energy window to account for ph absorption/emission 852 if (sigma%imag_only .and. sigma%qint_method == 1) then 853 call wrtout(std_out, " Including restricted set of states within energy window around relevant states.", newlines=1) 854 do spin=1,sigma%nsppol 855 do ik_ibz=1,ebands%nkpt 856 do band=sigma%my_bsum_start, sigma%my_bsum_stop 857 eig0mk = ebands%eig(band, ik_ibz, spin) 858 if (eig0mk >= sigma%elow - sigma%phwinfact * sigma%wmax .and. & 859 eig0mk <= sigma%ehigh + sigma%phwinfact * sigma%wmax) then 860 bks_mask(band, ik_ibz ,spin) = .True. 861 end if 862 end do 863 end do 864 end do 865 ! Uncomment these lines to disable energy window trick and allocate all bands. 866 !if (dtset%userie == 123) then 867 ! call wrtout(std_out, " Storing all bands between my_bsum_start and my_bsum_stop.") 868 ! bks_mask(sigma%my_bsum_start:sigma%my_bsum_stop, : ,:) = .True. 869 !end if 870 else 871 bks_mask(sigma%my_bsum_start:sigma%my_bsum_stop, : ,:) = .True. 872 endif 873 874 !if (dtset%userie == 124) then 875 ! ! Uncomment this line to have all states on each MPI rank. 876 ! bks_mask = .True.; call wrtout(std_out, " Storing all bands for debugging purposes.") 877 !end if 878 879 ! This table is needed when computing the imaginary part: 880 ! k+q states outside the energy window are not read hence their contribution won't be included. 881 ! Error is small provided calculation is close to convergence. 882 ! To reduce the error one should increase the value of phwinfact 883 ABI_MALLOC(ihave_ikibz_spin, (nkpt, nsppol)) 884 ihave_ikibz_spin = .False. 885 do spin=1,sigma%nsppol 886 do ik_ibz=1,ebands%nkpt 887 if (any(bks_mask(:, ik_ibz, spin))) ihave_ikibz_spin(ik_ibz, spin) = .True. 888 end do 889 end do 890 891 ! Impose istwfk=1 for all k points. This is also done in respfn (see inkpts) 892 ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1. 893 ABI_MALLOC(wfd_istwfk, (nkpt)) 894 wfd_istwfk = 1 895 896 call wfd_init(wfd, cryst, pawtab, psps, keep_ur, dtset%mband, nband, nkpt, nsppol, bks_mask,& 897 nspden, nspinor, ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, ebands%kptns, ngfft,& 898 dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm) 899 900 call wfd%print(header="Wavefunctions for self-energy calculation.", mode_paral='PERS') 901 902 ABI_FREE(nband) 903 ABI_FREE(bks_mask) 904 ABI_FREE(keep_ur) 905 ABI_FREE(wfd_istwfk) 906 907 ! Read wavefunctions. 908 call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path)) 909 910 ! if PAW, one has to solve a generalized eigenproblem 911 ! Be careful here because I will need sij_opt == -1 912 usecprj = 0 913 gen_eigenpb = psps%usepaw == 1; sij_opt = 0; if (gen_eigenpb) sij_opt = 1 914 915 ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj)) 916 ABI_MALLOC(cwaveprj, (natom, nspinor*usecprj)) 917 ABI_MALLOC(displ_cart, (2, 3, cryst%natom, natom3)) 918 ABI_MALLOC(displ_red, (2, 3, cryst%natom, natom3)) 919 ABI_MALLOC(tpp_red, (natom3, natom3)) 920 ABI_MALLOC(gbound_kq, (2*wfd%mgfft+8, 2)) 921 ABI_MALLOC(osc_gbound_q, (2*wfd%mgfft+8, 2)) 922 923 osc_ecut = dtset%eph_ecutosc 924 if (osc_ecut > zero) then 925 call wrtout(std_out, sjoin("Computing oscillator matrix elements with ecut.", ftoa(osc_ecut))) 926 ABI_CHECK(osc_ecut <= wfd%ecut, "osc_ecut cannot be greater than dtset%ecut") 927 else if (osc_ecut < zero) then 928 call wrtout(std_out, sjoin("Including G vectors inside a sphere with ecut.", ftoa(osc_ecut))) 929 end if 930 931 ! ============================ 932 ! Compute vnk matrix elements 933 ! ============================ 934 ABI_MALLOC(cgwork, (2, mpw*wfd%nspinor)) 935 ABI_CALLOC(sigma%vcar_calc, (3, sigma%max_nbcalc, sigma%nkcalc, nsppol)) 936 937 ddkop = ddkop_new(dtset, cryst, pawtab, psps, wfd%mpi_enreg, mpw, wfd%ngfft) 938 939 if (sigma%mrta == 0) then 940 call cwtime(cpu_ks, wall_ks, gflops_ks, "start", msg=" Computing v_nk matrix elements for all states in Sigma_nk...") 941 ! Consider only the nk states in Sigma_nk 942 ! All sigma_nk states are available on each node so MPI parallelization is easy. 943 cnt = 0 944 do spin=1,nsppol 945 do ikcalc=1,sigma%nkcalc 946 kk = sigma%kcalc(:, ikcalc) 947 bstart_ks = sigma%bstart_ks(ikcalc, spin) 948 ik_ibz = sigma%kcalc2ibz(ikcalc, 1) 949 npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz) 950 call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk, istwf_k, npw_k, wfd%kdata(ik_ibz)%kg_k) 951 952 do ib_k=1,sigma%nbcalc_ks(ikcalc, spin) 953 cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism. 954 band_ks = ib_k + bstart_ks - 1 955 call wfd%copy_cg(band_ks, ik_ibz, spin, cgwork) 956 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 957 sigma%vcar_calc(:, ib_k, ikcalc, spin) = ddkop%get_vdiag(eig0nk, istwf_k, npw_k, wfd%nspinor, cgwork, cwaveprj0) 958 end do 959 960 end do 961 end do 962 call xmpi_sum(sigma%vcar_calc, comm, ierr) 963 964 else 965 call cwtime(cpu_ks, wall_ks, gflops_ks, "start", msg=" Computing v_nk matrix elements for all states in the IBZ...") 966 967 ! Imaginary part with MRTA. Here we need v_kq as well. 968 ! Usually kq is one of the kcalc points except when nk is close to the edge of the sigma_erange window. 969 ! due to ph absorption/emission. 970 ! In this case, indeed, we may need a kq state that is not in the initial kcalc set. 971 ! 972 ! Solution: 973 ! 1) precompute group velocities in the IBZ and the ihave_ikibz_spin file (common to all procs) 974 ! 2) Fill sigma%vcar_calc needed by the transport driver from the vcar_ibz array 975 ! 3) Use symmetries to reconstruct v_kq from vcar_ibz 976 ! 977 ! NB: All procs store in memory the same set of Bloch states. 978 979 ABI_CALLOC(vcar_ibz, (3, sigma%bsum_start:sigma%bsum_stop, nkpt, nsppol)) 980 981 cnt = 0 982 do spin=1,nsppol 983 do ik_ibz=1,ebands%nkpt 984 kk = ebands%kptns(:, ik_ibz) 985 npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz) 986 ikcalc = ibzspin_2ikcalc(ik_ibz, spin) 987 if (.not. ihave_ikibz_spin(ik_ibz, spin)) cycle 988 if (npw_k == 1) cycle 989 cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism. 990 991 call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk, istwf_k, npw_k, wfd%kdata(ik_ibz)%kg_k) 992 993 do band_ks=sigma%bsum_start,sigma%bsum_stop 994 if (.not. wfd%ihave_ug(band_ks, ik_ibz, spin)) cycle 995 call wfd%copy_cg(band_ks, ik_ibz, spin, cgwork) 996 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 997 vk = ddkop%get_vdiag(eig0nk, istwf_k, npw_k, wfd%nspinor, cgwork, cwaveprj0) 998 vcar_ibz(:, band_ks, ik_ibz, spin) = vk 999 if (ikcalc /= -1) then 1000 ! This IBZ k-point is in the kcalc set --> Store vk in vcar_calc 1001 bstart_ks = sigma%bstart_ks(ikcalc, spin) 1002 bstop = bstart_ks + sigma%nbcalc_ks(ikcalc, spin) - 1 1003 if (band_ks >= bstart_ks .and. band_ks <= bstop) then 1004 ib_k = band_ks - bstart_ks + 1 1005 sigma%vcar_calc(:, ib_k, ikcalc, spin) = vk 1006 end if 1007 end if 1008 end do 1009 end do 1010 end do 1011 call xmpi_sum(sigma%vcar_calc, comm, ierr) 1012 call xmpi_sum(vcar_ibz, comm, ierr) 1013 endif 1014 1015 ! Write v_nk to disk. 1016 if (my_rank == master) then 1017 NCF_CHECK(nf90_put_var(sigma%ncid, nctk_idname(sigma%ncid, "vcar_calc"), sigma%vcar_calc)) 1018 end if 1019 1020 ABI_FREE(cgwork) 1021 call ddkop%free() 1022 call cwtime_report(" Velocities", cpu_ks, wall_ks, gflops_ks) 1023 1024 ! Precompute phonon frequencies and eigenvectors in the IBZ. 1025 ! These quantities are then used to symmetrize quantities for q in the IBZ(k) in order 1026 ! to reduce the number of calls to ifc%fourq (expensive if dipdip == 1) 1027 1028 use_ifc_fourq = .False. !use_ifc_fourq = .True. !use_ifc_fourq = dtset%userib == 123 1029 phstore = phstore_new(cryst, ifc, sigma%nqibz, sigma%qibz, use_ifc_fourq, sigma%pert_comm%value) 1030 call cwtime_report(" phonons in the IBZ", cpu_ks, wall_ks, gflops_ks) 1031 1032 ! Radius of sphere with volume equivalent to the micro zone. 1033 q0rad = two_pi * (three / (four_pi * cryst%ucvol * sigma%nqbz)) ** third 1034 bz_vol = two_pi**3 / cryst%ucvol 1035 1036 ! if (sigma%frohl_model == 1 .and. .not. sigma%imag_only) then 1037 ! ! Prepare treatment of Frohlich divergence in the ZPR with spherical integration in the microzone around Gamma. 1038 ! ! Correction does not depend on (n,k) so we can precompute values at this level. 1039 ! call wrtout(std_out, " Computing spherical average to treat Frohlich divergence ...") 1040 ! zpr_frohl_sphcorr = zero 1041 ! ! Angular integration 1042 ! do iang=1,sigma%angl_size 1043 ! if (mod(iang, nprocs) /= my_rank) cycle ! MPI parallelism 1044 ! qpt_cart = sigma%qvers_cart(:, iang); inv_qepsq = one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart)) 1045 ! call ifc%fourq(cryst, qpt_cart, phfrq, displ_cart, nanaqdir="cart") 1046 ! 1047 ! ! Acoustic modes are ignored here 1048 ! do nu=4,natom3 1049 ! wqnu = phfrq(nu); if (sigma%skip_phmode(nu, wqnu, dtset%eph_phrange_w)) cycle 1050 ! ! cnum = q.\sum_k Z_k.d(q,nu) 1051 ! cp3 = czero 1052 ! do iatom=1, natom 1053 ! cp3 = cp3 + matmul(ifc%zeff(:, :, iatom), cmplx(displ_cart(1,:,iatom, nu), displ_cart(2,:,iatom, nu), kind=dpc)) 1054 ! end do 1055 ! cnum = dot_product(qpt_cart, cp3) 1056 ! ! Compute spherical average. 1057 ! zpr_frohl_sphcorr(nu) = zpr_frohl_sphcorr(nu) + sigma%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq ** 2 / wqnu ** 2 1058 ! end do 1059 ! end do ! iang 1060 ! call xmpi_sum(zpr_frohl_sphcorr, comm, ierr) 1061 ! 1062 ! zpr_frohl_sphcorr = zpr_frohl_sphcorr * eight * pi / cryst%ucvol * (three / (four_pi * cryst%ucvol * sigma%nqbz)) ** third 1063 ! !zpr_frohl_sphcorr = zpr_frohl_sphcorr * four * q0rad / cryst%ucvol 1064 ! if (my_rank == master) then 1065 ! write(ab_out, "(/,a)")" Frohlich model integrated inside the small q-sphere around Gamma: " 1066 ! write(ab_out,"(2(a,i0,1x),/)")" ntheta: ", sigma%ntheta, ", nphi: ", sigma%nphi 1067 ! write(ab_out, "(a)")" This correction is used to accelerate the convergence of the ZPR with the q-point sampling " 1068 ! write(ab_out, "(a)")" Note that this term tends to zero for N_q --> oo " 1069 ! write(ab_out, "(a)")" so it is different from the integral of the Frohlich potential in the full BZ." 1070 ! do nu=1,natom3 1071 ! if (abs(zpr_frohl_sphcorr(nu)) < tol12) cycle 1072 ! write(ab_out, "(a,f8.1,a,i0,a,f8.1,a)")& 1073 ! " ZPR Spherical correction:", zpr_frohl_sphcorr(nu) * Ha_meV, " (meV) for ph-mode: ", & 1074 ! nu, ", w_qnu:", phfrq(nu) * Ha_meV, " (meV)" 1075 ! end do 1076 ! write(ab_out, "(a)")ch10 1077 ! end if 1078 ! end if 1079 1080 ! Prepare call to getgh1c 1081 usevnl = 0 1082 optlocal = 1 ! local part of H^(1) is computed in gh1c=<G|H^(1)|C> 1083 optnl = 2 ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C> 1084 opt_gvnlx1 = 0 ! gvnlx1 is output 1085 1086 ABI_MALLOC(grad_berry, (2, nspinor*(berryopt0/4))) 1087 1088 ! This part is taken from dfpt_vtorho 1089 !==== Initialize most of the Hamiltonian (and derivative) ==== 1090 ! 1) Allocate all arrays and initialize quantities that do not depend on k and spin. 1091 ! 2) Perform the setup needed for the non-local factors: 1092 ! 1093 ! Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk. 1094 ! PAW: Initialize the overlap coefficients and allocate the Dij coefficients. 1095 1096 call init_hamiltonian(gs_hamkq, psps, pawtab, nspinor, nsppol, nspden, natom,& 1097 dtset%typat, cryst%xred, nfft, mgfft, ngfft, cryst%rprimd, dtset%nloalg,& 1098 comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab, mpi_spintab=mpi_enreg%my_isppoltab,& 1099 usecprj=usecprj, ph1d=ph1d, nucdipmom=dtset%nucdipmom, gpu_option=dtset%gpu_option) 1100 1101 ! Allocate work space arrays. 1102 ! vtrial and vlocal are required for Sternheimer (H0). DFPT routines do not need it. 1103 ! Note nvloc in vlocal (we will select one/four spin components afterwards) 1104 ABI_CALLOC(vtrial, (nfftf, nspden)) 1105 ABI_CALLOC(vlocal, (n4, n5, n6, gs_hamkq%nvloc)) 1106 1107 if (dtset%eph_stern /= 0) then 1108 ! Read GS POT (vtrial) from input POT file 1109 ! In principle one may store vtrial in the DVDB but getpot_filepath is simpler to implement. 1110 call wrtout(units, sjoin(" Reading GS KS potential for Sternheimer from: ", dtfil%filpotin)) 1111 call read_rhor(dtfil%filpotin, cplex1, nspden, nfftf, ngfftf, pawread0, mpi_enreg, vtrial, pot_hdr, pawrhoij, comm, & 1112 allow_interp=.True.) 1113 pot_cryst = pot_hdr%get_crystal() 1114 if (cryst%compare(pot_cryst, header=" Comparing input crystal with POT crystal") /= 0) then 1115 ABI_ERROR("Crystal structure from WFK and POT do not agree! Check messages above!") 1116 end if 1117 call pot_cryst%free(); call pot_hdr%free() 1118 end if 1119 1120 if (sigma%nwr > 0) then 1121 ABI_MALLOC(cfact_wr, (sigma%nwr)) 1122 end if 1123 ABI_MALLOC(nqnu_tlist, (sigma%ntemp)) 1124 1125 ! Allocate workspace arrays for Eliashberg calculation. 1126 if (dtset%prteliash /= 0) then 1127 ABI_MALLOC(dtw_weights, (sigma%phmesh_size, 2)) 1128 ABI_MALLOC(dwargs, (sigma%phmesh_size)) 1129 if (sigma%a2f_ne > 0) then 1130 ABI_MALLOC(delta_e_minus_emkq, (sigma%a2f_ne)) 1131 end if 1132 end if 1133 1134 ! Array used to store delta(w - w_{q\nu}) with delta replaced by gaussian. 1135 ABI_MALLOC(gaussw_qnu, (sigma%phmesh_size)) 1136 1137 if (dtset%eph_prtscratew == 1) then 1138 ABI_MALLOC(sigma%scratew, (sigma%phmesh_size, sigma%ntemp, sigma%max_nbcalc, 2)) 1139 end if 1140 1141 ! Open the DVDB file 1142 call dvdb%open_read(ngfftf, xmpi_comm_self) 1143 1144 if (sigma%pert_comm%nproc > 1) then 1145 ! Activate parallelism over perturbations 1146 call dvdb%set_pert_distrib(sigma%my_npert, natom3, sigma%my_pinfo, sigma%pert_table, sigma%pert_comm%value) 1147 end if 1148 1149 ! Find correspondence IBZ --> set of q-points in DVDB. 1150 ! Activate FT interpolation automatically if required q-points in the IBZ are not found in the DVDB. 1151 sigma%use_ftinterp = .False. 1152 ABI_MALLOC(sigma%qibz2dvdb, (sigma%nqibz)) 1153 if (dvdb%find_qpts(sigma%nqibz, sigma%qibz, sigma%qibz2dvdb, comm) /= 0) then 1154 call wrtout(units, " Cannot find eph_ngqpt_fine q-points in DVDB --> Activating Fourier interpolation.") 1155 sigma%use_ftinterp = .True. 1156 else 1157 call wrtout(units, " DVDB file contains all q-points in the IBZ --> Reading DFPT potentials from file.") 1158 sigma%use_ftinterp = .False. 1159 end if 1160 1161 if (sigma%use_ftinterp) then 1162 ! Use ddb_ngqpt q-mesh to compute the real-space represention of DFPT v1scf potentials to prepare Fourier interpolation. 1163 ! R-points are distributed inside comm_rpt 1164 ! Note that when R-points are distributed inside qpt_comm we cannot interpolate potentials on-the-fly 1165 ! inside the loop over q-points. 1166 ! In this case, indeed, the interpolation must be done in sigma_setup_qloop once we know the q-points contributing 1167 ! to the integral and the potentials must be cached. 1168 !FIXME: qpt_comm is buggy. 1169 !if (sigma%imag_only) comm_rpt = xmpi_comm_self 1170 !comm_rpt = sigma%bsum_comm%value 1171 comm_rpt = xmpi_comm_self 1172 qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt 1173 call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt) 1174 1175 ! Build q-cache in the *dense* IBZ using the global mask qselect and itreat_qibz. 1176 ABI_MALLOC(qselect, (sigma%nqibz)) 1177 qselect = 1 1178 if (sigma%imag_only .and. sigma%qint_method == 1) then 1179 call qpoints_oracle(sigma, dtset, cryst, ebands, sigma%qibz, sigma%nqibz, sigma%nqbz, sigma%qbz, qselect, comm) 1180 end if 1181 call dvdb%ftqcache_build(nfftf, ngfftf, sigma%nqibz, sigma%qibz, dtset%dvdb_qcache_mb, qselect, sigma%itreat_qibz, comm) 1182 1183 else 1184 ABI_MALLOC(qselect, (dvdb%nqpt)) 1185 qselect = 1 1186 ! Try to predict the q-points required to compute tau. 1187 if (sigma%imag_only .and. sigma%qint_method == 1) then 1188 call qpoints_oracle(sigma, dtset, cryst, ebands, dvdb%qpts, dvdb%nqpt, sigma%nqbz, sigma%qbz, qselect, comm) 1189 end if 1190 end if 1191 1192 call dvdb%print(prtvol=dtset%prtvol) 1193 1194 if (.not. sigma%use_ftinterp) then 1195 ! Need to translate itreat_qibz into itreatq_dvdb. 1196 ABI_ICALLOC(itreatq_dvdb, (dvdb%nqpt)) 1197 do iq_ibz=1,sigma%nqibz 1198 if (sigma%itreat_qibz(iq_ibz) == 0) cycle 1199 db_iqpt = sigma%qibz2dvdb(iq_ibz) 1200 ABI_CHECK(db_iqpt /= -1, sjoin("Could not find IBZ q-point:", ktoa(sigma%qibz(:, iq_ibz)), "in the DVDB file.")) 1201 itreatq_dvdb(db_iqpt) = 1 1202 end do 1203 call dvdb%qcache_read(nfftf, ngfftf, dtset%dvdb_qcache_mb, qselect, itreatq_dvdb, comm) 1204 ABI_FREE(itreatq_dvdb) 1205 end if 1206 1207 ABI_FREE(qselect) 1208 zpr_frohl_sphcorr = zero; zpr_frohl_sphcorr_done = .False. 1209 1210 ! Loop over k-points in Sigma_nk. Loop over spin is internal as we operate on nspden components at once. 1211 do my_ikcalc=1,sigma%my_nkcalc 1212 !if (my_ikcalc > 1) exit 1213 ikcalc = sigma%my_ikcalc(my_ikcalc) 1214 1215 ! Check if this (kpoint, spin) was already calculated 1216 if (all(sigma%qp_done(ikcalc, :) == 1)) cycle 1217 call cwtime(cpu_ks, wall_ks, gflops_ks, "start") 1218 1219 !call abimem_report("begin kcalc_loop", std_out) 1220 !call wrtout(std_out, sjoin("xmpi_count_requests", itoa(xmpi_count_requests))) 1221 1222 ! Find IBZ(k) for q-point integration. 1223 call cwtime(cpu_setk, wall_setk, gflops_setk, "start") 1224 ! FIXME invert spin but checks shape of the different arrays! 1225 call sigma%setup_kcalc(dtset, cryst, ebands, ikcalc, dtset%prtvol, sigma%pqb_comm%value) 1226 1227 ! Symmetry indices for kk. 1228 kk = sigma%kcalc(:, ikcalc) 1229 ik_ibz = sigma%kcalc2ibz(ikcalc, 1); isym_k = sigma%kcalc2ibz(ikcalc, 2) 1230 trev_k = sigma%kcalc2ibz(ikcalc, 6); g0_k = sigma%kcalc2ibz(ikcalc, 3:5) 1231 isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0)) 1232 ABI_CHECK(isirr_k, "For the time being the k-point in Sigma_{nk} must be in the IBZ") 1233 kk_ibz = ebands%kptns(:,ik_ibz) 1234 npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz) 1235 1236 ! Allocate PW-arrays. Note mpw in kg_kq 1237 ABI_MALLOC(kg_k, (3, npw_k)) 1238 kg_k = wfd%kdata(ik_ibz)%kg_k 1239 ABI_MALLOC(kg_kq, (3, mpw)) 1240 1241 ! Spherical Harmonics for useylm == 1. 1242 ABI_MALLOC(ylm_k, (mpw, psps%mpsang**2 * psps%useylm)) 1243 ABI_MALLOC(ylm_kq, (mpw, psps%mpsang**2 * psps%useylm)) 1244 ABI_MALLOC(ylmgr_kq, (mpw, 3, psps%mpsang**2 * psps%useylm * useylmgr1)) 1245 1246 ! Compute k+G vectors 1247 nkpg = 3*dtset%nloalg(3) 1248 ABI_MALLOC(kpg_k, (npw_k, nkpg)) 1249 if (nkpg > 0) call mkkpg(kg_k, kpg_k, kk, nkpg, npw_k) 1250 1251 ! Compute nonlocal form factors ffnlk at (k+G) 1252 ABI_MALLOC(ffnlk, (npw_k, 1, psps%lmnmax, psps%ntypat)) 1253 1254 call mkffnl_objs(cryst, psps, 1, ffnlk, ider0, idir0, kg_k, kpg_k, kk, nkpg, npw_k, ylm_k, ylmgr_dum, & 1255 comm=sigma%pert_comm%value, request=ffnlk_request) 1256 1257 call cwtime_report(" Setup kcalc", cpu_setk, wall_setk, gflops_setk) 1258 1259 ! TODO: Spin should be treated in a more flexible and scalable way --> kcalc and bdgw should depend on spin. 1260 ! Introduce other comm and cartesian dimension for spin 1261 do my_spin=1,sigma%my_nspins 1262 spin = sigma%my_spins(my_spin) 1263 1264 ! Check if this kpoint and spin was already calculated 1265 if (sigma%qp_done(ikcalc, spin) == 1) cycle 1266 1267 !call timab(1900, 1, tsec) 1268 ! Bands in Sigma_nk to compute and number of bands in sum over states. 1269 bstart_ks = sigma%bstart_ks(ikcalc, spin) 1270 nbcalc_ks = sigma%nbcalc_ks(ikcalc, spin) 1271 bsum_start = sigma%bsum_start; bsum_stop = sigma%bsum_stop 1272 nbsum = sigma%nbsum 1273 ABI_MALLOC(root_bcalc, (nbcalc_ks)) 1274 1275 ! Zero self-energy matrix elements. Build frequency mesh for nk states. 1276 sigma%vals_e0ks = zero; sigma%dvals_de0ks = zero; sigma%dw_vals = zero 1277 sigma%fan_vals = zero; sigma%fan_stern_vals = zero; sigma%dw_stern_vals = zero 1278 if (sigma%mrta > 0) then 1279 sigma%linewidth_mrta = zero 1280 ABI_MALLOC(alpha_mrta, (nbcalc_ks)) 1281 end if 1282 1283 ! Prepare computation of Sigma_{nk}(w) and spectral function. 1284 if (sigma%nwr > 0) then 1285 sigma%vals_wr = zero 1286 do ib_k=1,nbcalc_ks 1287 band_ks = ib_k + bstart_ks - 1 1288 ! Build linear mesh **centered** around the KS energy. 1289 eig0nk = ebands%eig(band_ks, ik_ibz, spin) - sigma%wr_step * (sigma%nwr / 2) 1290 sigma%wrmesh_b(:,ib_k) = arth(eig0nk, sigma%wr_step, sigma%nwr) 1291 end do 1292 end if 1293 1294 ! Prepare Eliasberg functions. 1295 if (dtset%prteliash /= 0) then 1296 ABI_SFREE(sigma%gf_nnuq) 1297 ABI_CALLOC(sigma%gf_nnuq, (nbcalc_ks, natom3, sigma%nqibz_k, 3)) 1298 if (dtset%prteliash == 3) sigma%a2few = zero 1299 end if 1300 1301 ! Zeroing array used to compute spectral decomposition of 1/tau as a function of ph omega. 1302 if (dtset%eph_prtscratew == 1) sigma%scratew = zero 1303 1304 ! Allocate eph matrix elements. 1305 ABI_MALLOC(gkq_atm, (2, nbcalc_ks, natom3)) 1306 ABI_MALLOC(gkq_nu, (2, nbcalc_ks, natom3)) 1307 ABI_MALLOC(gkq_allgather, (2, nbcalc_ks * natom3, 2)) 1308 1309 ! Allocate arrays for Debye-Waller 1310 if (.not. sigma%imag_only) then 1311 ABI_CALLOC_OR_DIE(gkq0_atm, (2, nbcalc_ks, sigma%my_bsum_start:sigma%my_bsum_stop, natom3), ierr) 1312 if (dtset%eph_stern /= 0) then 1313 ABI_CALLOC(stern_dw, (2, natom3, natom3, nbcalc_ks)) 1314 enough_stern = 0 1315 use_u1c_cache = merge(.True., .False., dtset%eph_stern == 1) 1316 tot_nlines_done = 0 1317 end if 1318 end if 1319 1320 ! Integrate delta functions inside miniBZ around Gamma. 1321 ! TODO: Remove? 1322 !if (sigma%frohl_model == 1 .and. sigma%imag_only) then 1323 ! call eval_sigfrohl_deltas(sigma, cryst, ifc, ebands, ikcalc, spin, dtset%prtvol, sigma%pqb_comm%value) 1324 !end if 1325 1326 if (sigma%frohl_model == 1 .and. .not. sigma%imag_only) then 1327 call wrtout(std_out, " Computing spherical average to treat Frohlich divergence in Sigma^{FM}") 1328 ABI_MALLOC(f_tlist_b, (sigma%ntemp, nbcalc_ks)) 1329 1330 if (sigma%nwr > 0) then 1331 do ib_k=1,nbcalc_ks 1332 band_ks = ib_k + bstart_ks - 1; eig0nk = ebands%eig(band_ks, ik_ibz, spin) 1333 do it=1,sigma%ntemp 1334 f_tlist_b(it,ib_k) = occ_fd(eig0nk, sigma%kTmesh(it), sigma%mu_e(it)) 1335 end do 1336 end do 1337 ! This integral depends on the (n, k) state 1338 ABI_CALLOC(fmw_frohl_sphcorr, (sigma%nwr, natom3, sigma%ntemp, nbcalc_ks)) 1339 end if 1340 1341 ! Angular integration. 1342 if (.not. zpr_frohl_sphcorr_done) zpr_frohl_sphcorr = zero 1343 1344 do iang=1,sigma%angl_size 1345 if (sigma%kcalc_comm%skip(iang)) cycle ! MPI parallelism inside kcalc_comm 1346 qpt_cart = sigma%qvers_cart(:, iang); inv_qepsq = one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart)) 1347 call ifc%fourq(cryst, qpt_cart, phfrq, displ_cart, nanaqdir="cart") 1348 1349 ! Acoustic modes are ignored here. 1350 do nu=4,natom3 1351 wqnu = phfrq(nu); if (sigma%skip_phmode(nu, wqnu, dtset%eph_phrange_w)) cycle 1352 ! Get phonon occupation for all temperatures. 1353 nqnu_tlist = occ_be(wqnu, sigma%kTmesh(:), zero) 1354 1355 ! cnum = q.\sum_k Z_k.d_k(q,nu) 1356 cp3 = czero 1357 do iatom=1, natom 1358 cp3 = cp3 + matmul(ifc%zeff(:, :, iatom), cmplx(displ_cart(1,:,iatom, nu), displ_cart(2,:,iatom, nu), kind=dpc)) 1359 end do 1360 cnum = dot_product(qpt_cart, cp3); if (abs(cnum) < tol12) cycle 1361 1362 ! Compute spherical average for ZPR 1363 if (.not. zpr_frohl_sphcorr_done) then 1364 zpr_frohl_sphcorr(nu) = zpr_frohl_sphcorr(nu) + sigma%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq ** 2 / wqnu ** 2 1365 end if 1366 1367 if (sigma%nwr > 0) then 1368 ! NB: summing over f * angwgth gives the spherical average 1/(4pi) \int domega f(omega) 1369 weight = four_pi * sigma%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq ** 2 / wqnu 1370 do ib_k=1,nbcalc_ks 1371 band_ks = ib_k + bstart_ks - 1; eig0nk = ebands%eig(band_ks, ik_ibz, spin) 1372 do it=1,sigma%ntemp 1373 f_nk = f_tlist_b(it,ib_k) 1374 nqnu = nqnu_tlist(it) 1375 fmw_frohl_sphcorr(:,nu,it,ib_k) = fmw_frohl_sphcorr(:,nu,it,ib_k) + & 1376 ((nqnu + f_nk ) / (sigma%wrmesh_b(:,ib_k) - eig0nk + wqnu + sigma%ieta) + & 1377 (nqnu - f_nk + one) / (sigma%wrmesh_b(:,ib_k) - eig0nk - wqnu + sigma%ieta) ) * weight 1378 end do ! it 1379 end do ! ib_k 1380 end if 1381 end do ! nu 1382 end do ! iang 1383 ABI_FREE(f_tlist_b) 1384 1385 if (.not. zpr_frohl_sphcorr_done) then 1386 call xmpi_sum(zpr_frohl_sphcorr, sigma%kcalc_comm%value, ierr) 1387 zpr_frohl_sphcorr = zpr_frohl_sphcorr * eight * pi / cryst%ucvol * & 1388 (three / (four_pi * cryst%ucvol * sigma%nqbz)) ** third 1389 !zpr_frohl_sphcorr = zpr_frohl_sphcorr * four * q0rad / cryst%ucvol 1390 zpr_frohl_sphcorr_done = .True. 1391 end if 1392 1393 if (sigma%nwr > 0) then 1394 call xmpi_sum(fmw_frohl_sphcorr, sigma%kcalc_comm%value, ierr) 1395 fmw_frohl_sphcorr = fmw_frohl_sphcorr * (four_pi/cryst%ucvol)**2 * q0rad * half / bz_vol 1396 end if 1397 1398 if (my_rank == master .and. is_open(ab_out)) then 1399 write(ab_out, "(/,a)")" Frohlich model integrated inside the small q-sphere around Gamma." 1400 write(ab_out,"(2(a,i0,1x),/)")" Angular mesh with ntheta: ", sigma%ntheta, ", nphi: ", sigma%nphi 1401 write(ab_out, "(2a)")" Phonon-resolved contributions to Sigma^{FM}(w=e_KS):", ch10 1402 do nu=1,natom3 1403 if (abs(zpr_frohl_sphcorr(nu)) < tol12) cycle 1404 write(ab_out, "(1x,f8.1,a,i0)")zpr_frohl_sphcorr(nu) * Ha_meV, " (meV) for ph-mode: ", nu 1405 end do 1406 write(ab_out, "(a)")ch10 1407 1408 !if (sigma%nwr > 0) then 1409 !do ib_k=1,nbcalc_ks 1410 ! band_ks = ib_k + bstart_ks - 1 1411 ! write(ab_out, "(a, i0)")" Spherical correction to Sigma^{FM}(w=e_KS) for band: ", band_ks 1412 ! do nu=1,natom3 1413 ! do it=1,sigma%ntemp 1414 ! iw = 1 + (sigma%nwr / 2) !; iw = 1 1415 ! if (abs(fmw_frohl_sphcorr(iw,nu,it,ib_k)) < tol12) cycle 1416 ! write(ab_out, "(2(f8.1),2(a,i0))") & 1417 ! fmw_frohl_sphcorr(iw,nu,it,ib_k) * Ha_meV, " (meV) for ph-mode: ",nu, ", itemp: ", it 1418 ! end do 1419 ! end do 1420 !end do 1421 !write(ab_out, "(a)")ch10 1422 !end if 1423 end if 1424 end if 1425 1426 ! Load ground-state wavefunctions for which corrections are wanted (available on each node) 1427 ! and save KS energies in sigma%e0vals 1428 ! Note: One should rotate the wavefunctions if kk is not in the IBZ (not implemented) 1429 ABI_MALLOC(kets_k, (2, npw_k*nspinor, nbcalc_ks)) 1430 ABI_MALLOC(sigma%e0vals, (nbcalc_ks)) 1431 1432 if (osc_ecut /= zero) then 1433 ABI_MALLOC(ur_k, (wfd%nfft*nspinor, nbcalc_ks)) 1434 ABI_MALLOC(ur_kq, (wfd%nfft*nspinor)) 1435 ABI_MALLOC(work_ur, (wfd%nfft*nspinor)) 1436 ABI_MALLOC(gkq2_lr, (sigma%eph_doublegrid%ndiv, nbcalc_ks, sigma%my_npert)) 1437 end if 1438 1439 do ib_k=1,nbcalc_ks 1440 band_ks = ib_k + bstart_ks - 1 1441 call wfd%copy_cg(band_ks, ik_ibz, spin, kets_k(1, 1, ib_k)) 1442 sigma%e0vals(ib_k) = ebands%eig(band_ks, ik_ibz, spin) 1443 if (osc_ecut > zero) call wfd%get_ur(band_ks, ik_ibz, spin, ur_k(1, ib_k)) 1444 end do 1445 1446 ! Distribute q-points, compute tetra weigths. 1447 call sigmaph_setup_qloop(sigma, dtset, cryst, ebands, dvdb, spin, ikcalc, nfftf, ngfftf, sigma%pqb_comm%value) 1448 !call timab(1900, 2, tsec) 1449 1450 ! ========================================== 1451 ! Integration over my q-points in the IBZ(k) 1452 ! ========================================== 1453 call cwtime(cpu_qloop, wall_qloop, gflops_qloop, "start") 1454 ignore_kq = 0; ignore_ibsum_kq = 0 1455 1456 do imyq=1,sigma%my_nqibz_k 1457 call cwtime(cpu, wall, gflops, "start") 1458 iq_ibz_k = sigma%myq2ibz_k(imyq) 1459 qpt = sigma%qibz_k(:, iq_ibz_k) 1460 q_is_gamma = sum(qpt**2) < tol14 1461 1462 iq_ibz = sigma%ind_ibzk2ibz(1, iq_ibz_k) 1463 isym_q = sigma%ind_ibzk2ibz(2, iq_ibz_k) 1464 trev_q = sigma%ind_ibzk2ibz(6, iq_ibz_k) 1465 ! Don't test if umklapp == 0 because we use the periodic gauge: phfreq(q+G) = phfreq(q) and eigvec(q) = eigvec(q+G) 1466 isirr_q = (isym_q == 1 .and. trev_q == 0) 1467 !qq_ibz = sigma%qibz(:, iq_ibz) 1468 1469 ! Find k + q in the extended zone and extract symmetry info. 1470 ! Be careful here because there are two umklapp vectors to be considered as: 1471 ! 1472 ! k + q = k_bz + g0_bz = IS(k_ibz) + g0_ibz + g0_bz 1473 ! 1474 kq = kk + qpt 1475 ikq_ibz = sigma%indkk_kq(1, iq_ibz_k); isym_kq = sigma%indkk_kq(2, iq_ibz_k) 1476 trev_kq = sigma%indkk_kq(6, iq_ibz_k); g0_kq = sigma%indkk_kq(3:5, iq_ibz_k) 1477 isirr_kq = (isym_kq == 1 .and. trev_kq == 0 .and. all(g0_kq == 0)) 1478 kq_ibz = ebands%kptns(:, ikq_ibz) 1479 !nband_kq = ebands%nband(ikq_ibz + (spin-1) * ebands%nkpt) 1480 1481 ! This can happen if we have loaded the wavefunctions inside the energy range. 1482 if (sigma%imag_only .and. .not. ihave_ikibz_spin(ikq_ibz, spin)) then 1483 ignore_kq = ignore_kq + 1; cycle 1484 end if 1485 1486 ! ==================================== 1487 ! Get DFPT potentials for this q-point 1488 ! ==================================== 1489 if (sigma%use_ftinterp) then 1490 ! Use Fourier interpolation to get DFPT potentials for this qpt (hopefully in cache). 1491 db_iqpt = sigma%ind_ibzk2ibz(1, iq_ibz_k) 1492 qq_ibz = sigma%qibz(:, db_iqpt) 1493 call dvdb%get_ftqbz(cryst, qpt, qq_ibz, sigma%ind_ibzk2ibz(:, iq_ibz_k), cplex, nfftf, ngfftf, v1scf, & 1494 sigma%pert_comm%value) 1495 else 1496 ! Read and reconstruct the dvscf potentials for qpt and my_npert perturbations. 1497 ! This call allocates v1scf(cplex, nfftf, nspden, my_npert)) 1498 db_iqpt = sigma%ind_q2dvdb_k(1, iq_ibz_k) 1499 ABI_CHECK(db_iqpt /= -1, sjoin("Could not find symmetric of q-point:", ktoa(qpt), "in DVDB file.")) 1500 call dvdb%readsym_qbz(cryst, qpt, sigma%ind_q2dvdb_k(:,iq_ibz_k), cplex, nfftf, ngfftf, v1scf, sigma%pert_comm%value) 1501 end if 1502 1503 ! Rotate phonon frequencies and displacements for q in BZ. Non-blocking operation inside pert_comm 1504 !call timab(1901, 1, tsec) 1505 1506 call phstore%async_rotate(cryst, ifc, iq_ibz, sigma%qibz(:, iq_ibz), qpt, isym_q, trev_q) 1507 !call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red, comm=sigma%pert_comm%value) 1508 1509 ! Double grid stuff 1510 if (sigma%use_doublegrid) then 1511 call sigma%eph_doublegrid%get_mapping(kk, kq, qpt) 1512 !iq_bz_frohl = sigma%eph_doublegrid%get_index(qpt, 2) 1513 !iq_ibz_frohl = sigma%eph_doublegrid%bz2ibz_dense(iq_bz_frohl) 1514 end if 1515 1516 ! Map q to qibz for tetrahedron 1517 if (sigma%qint_method > 0) then 1518 if (.not. sigma%use_doublegrid) then 1519 iq_ibz_fine = iq_ibz_k 1520 if (sigma%symsigma == 0) iq_ibz_fine = sigma%ephwg%lgk%find_ibzimage(qpt) 1521 ABI_CHECK(iq_ibz_fine /= -1, sjoin("Cannot find q-point in IBZ(k):", ktoa(qpt))) 1522 if (abs(sigma%symsigma) == 1) then 1523 if (.not. all(abs(sigma%qibz_k(:, iq_ibz_fine) - sigma%ephwg%lgk%ibz(:, iq_ibz_fine)) < tol12)) then 1524 ABI_ERROR("Mismatch in qpoints.") 1525 end if 1526 end if 1527 endif 1528 end if 1529 1530 ! Get npw_kq, kg_kq for k+q. 1531 if (isirr_kq) then 1532 ! Copy u_kq(G) 1533 istwf_kq = wfd%istwfk(ikq_ibz); npw_kq = wfd%npwarr(ikq_ibz) 1534 ABI_CHECK(mpw >= npw_kq, "mpw < npw_kq") 1535 kg_kq(:,1:npw_kq) = wfd%kdata(ikq_ibz)%kg_k 1536 else 1537 ! Reconstruct u_kq(G) from the IBZ image. 1538 istwf_kq = 1 1539 call get_kg(kq, istwf_kq, ecut, cryst%gmet, npw_kq, gtmp) 1540 ABI_CHECK(mpw >= npw_kq, "mpw < npw_kq") 1541 kg_kq(:,1:npw_kq) = gtmp(:,:npw_kq) 1542 ABI_FREE(gtmp) 1543 end if 1544 !call timab(1901, 2, tsec) 1545 !call timab(1902, 1, tsec) 1546 1547 istwf_kqirr = wfd%istwfk(ikq_ibz); npw_kqirr = wfd%npwarr(ikq_ibz) 1548 ABI_MALLOC(bra_kq, (2, npw_kq*nspinor)) 1549 ABI_MALLOC(cgwork, (2, npw_kqirr*nspinor)) 1550 1551 if (osc_ecut /= zero) then 1552 ! Finds the boundary of the basis sphere of G vectors (for this kq point) 1553 ! for use in improved zero padding of ffts in 3 dimensions. 1554 call sphereboundary(gbound_kq, istwf_kq, kg_kq, wfd%mgfft, npw_kq) 1555 1556 ! Compute "small" G-sphere centered on qpt and gbound for zero-padded FFT for oscillators. 1557 call get_kg(qpt, istw1, abs(osc_ecut), cryst%gmet, osc_npw, osc_gvecq) 1558 call sphereboundary(osc_gbound_q, istw1, osc_gvecq, wfd%mgfft, osc_npw) 1559 1560 ! Compute correspondence G-sphere --> FFT mesh. 1561 ABI_MALLOC(osc_indpw, (osc_npw)) 1562 ABI_MALLOC(osc_mask, (osc_npw)) 1563 call kgindex(osc_indpw, osc_gvecq, osc_mask, wfd%mpi_enreg, ngfft, osc_npw) 1564 ABI_FREE(osc_mask) 1565 1566 ABI_MALLOC(workq_ug, (npw_kq*nspinor)) 1567 ABI_MALLOC(osc_ks, (osc_npw*nspinor, nbcalc_ks)) 1568 end if 1569 1570 ! Allocate array to store H1 |psi_nk> for all 3*natom perturbations 1571 ABI_MALLOC_OR_DIE(h1kets_kq, (2, npw_kq*nspinor, my_npert, nbcalc_ks), ierr) 1572 1573 ! Allocate vlocal1 with correct cplex. Note nvloc 1574 ABI_MALLOC_OR_DIE(vlocal1, (cplex*n4, n5, n6, gs_hamkq%nvloc, my_npert), ierr) 1575 1576 ABI_MALLOC(gs1c, (2, npw_kq*nspinor*((sij_opt+1)/2))) 1577 ABI_MALLOC(gvnlx1, (2, npw_kq*nspinor)) 1578 1579 ! Set up the spherical harmonics (Ylm) at k and k+q. See also dfpt_looppert 1580 !if (psps%useylm == 1) then 1581 ! optder = 0; if (useylmgr == 1) optder = 1 1582 ! call initylmg(cryst%gprimd, kg_k, kk, mkmem1, mpi_enreg, psps%mpsang, mpw, nband, mkmem1, & 1583 ! [npw_k], dtset%nsppol, optder, cryst%rprimd, ylm_k, ylmgr) 1584 ! call initylmg(cryst%gprimd, kg_kq, kq, mkmem1, mpi_enreg, psps%mpsang, mpw, nband, mkmem1, & 1585 ! [npw_kq], dtset%nsppol, optder, cryst%rprimd, ylm_kq, ylmgr_kq) 1586 !end if 1587 1588 ! Compute k+q+G vectors 1589 nkpg1 = 3*dtset%nloalg(3) 1590 ABI_MALLOC(kpg1_k, (npw_kq, nkpg1)) 1591 if (nkpg1 > 0) call mkkpg(kg_kq, kpg1_k, kq, nkpg1, npw_kq) 1592 1593 ! Compute nonlocal form factors ffnl1 at (k+q+G) 1594 ABI_MALLOC(ffnl1, (npw_kq, 1, psps%lmnmax, psps%ntypat)) 1595 1596 call mkffnl_objs(cryst, psps, 1, ffnl1, ider0, idir0, kg_kq, kpg1_k, kq, nkpg1, npw_kq, ylm_kq, ylmgr_kq, & 1597 comm=sigma%pert_comm%value, request=ffnl1_request) 1598 1599 if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then 1600 ! Build global array with GS wavefunctions cg_kq at k+q to prepare call to dfpt_cgwf. 1601 ! NB: bsum_range is not compatible with Sternheimer. 1602 ! There's a check at the level of the parser in chkinp. 1603 1604 call timab(1908, 1, tsec) 1605 ABI_CALLOC(cg1s_kq, (2, npw_kq*nspinor, natom3, nbcalc_ks)) 1606 1607 ! NOTE that in the present version we need to gather all nbsum bands 1608 ! on each core before calling dfpt_cgwf. 1609 ! In principle one can call dfpt_cgwf in band-para mode but then 1610 ! we are obliged to call the sternheimer solver with one psi1 and all procs in bsum_comm 1611 ! just to to be able to apply the projector operator. 1612 ! The present version is not memory efficient and leads to a big load imbalance if 1613 ! bsum%comm%nproc > nband_calc_ks 1614 1615 !#define DEV_BAND_PARA 1616 1617 #ifdef DEV_BAND_PARA 1618 nband_me = sigma%my_bsum_stop - sigma%my_bsum_start + 1 1619 #else 1620 nband_me = nbsum 1621 #endif 1622 1623 ABI_MALLOC(cgq, (2, npw_kq * nspinor, nband_me)) 1624 ABI_MALLOC(gscq, (2, npw_kq * nspinor, nband_me*psps%usepaw)) 1625 1626 do ibsum_kq=sigma%my_bsum_start, sigma%my_bsum_stop 1627 1628 1629 1630 if (isirr_kq) then 1631 call wfd%copy_cg(ibsum_kq, ikq_ibz, spin, bra_kq) 1632 else 1633 ! Reconstruct u_kq(G) from the IBZ image. 1634 call wfd%copy_cg(ibsum_kq, ikq_ibz, spin, cgwork) 1635 call cgtk_rotate(cryst, kq_ibz, isym_kq, trev_kq, g0_kq, nspinor, ndat1, & 1636 npw_kqirr, wfd%kdata(ikq_ibz)%kg_k, & 1637 npw_kq, kg_kq, istwf_kqirr, istwf_kq, cgwork, bra_kq, work_ngfft, work) 1638 end if 1639 1640 #ifdef DEV_BAND_PARA 1641 ii = ibsum_kq - sigma%my_bsum_start + 1 1642 cgq(:,:,ii) = bra_kq 1643 #else 1644 cgq(:, :, ibsum_kq) = bra_kq 1645 #endif 1646 end do 1647 1648 cgq_request = xmpi_request_null 1649 1650 #ifndef DEV_BAND_PARA 1651 if (sigma%bsum_comm%nproc > 1) then 1652 ! If band parallelism, need to gather all bands nbsum bands. 1653 ! FIXME: This part is network intensive, one can avoid it by calling dfpt_cgwf in band-para mode. 1654 !call xmpi_sum(cgq, sigma%bsum_comm%value, ierr) 1655 !call xmpi_isum_ip(cgq, sigma%bsum_comm%value, cgq_request, ierr) 1656 1657 nelem = 2 * npw_kq * nspinor 1658 call sigma%bsum_comm%prep_gatherv(nelem, sigma%nbsum_rank(:,1), sendcount, recvcounts, displs) 1659 #ifdef HAVE_MPI 1660 !call MPI_ALLGATHERV(MPI_IN_PLACE, sendcount, MPI_DOUBLE_PRECISION, cgq, recvcounts, displs, & 1661 ! MPI_DOUBLE_PRECISION, sigma%bsum_comm%value, ierr) 1662 1663 #if defined HAVE_MPI2_INPLACE 1664 call MPI_IALLGATHERV(MPI_IN_PLACE, sendcount, MPI_DOUBLE_PRECISION, cgq, recvcounts, displs, & 1665 MPI_DOUBLE_PRECISION, sigma%bsum_comm%value, cgq_request, ierr) 1666 #else 1667 ABI_MALLOC(cgq_buf,(sendcount)) 1668 me=1+xmpi_comm_rank(sigma%bsum_comm%value) 1669 cgq_buf(1:sendcount)=cgq_ptr(displs(me)+1:displs(me)+sendcount) 1670 call c_f_pointer(c_loc(cgq),cgq_ptr,[2*npw_kq*nspinor*nband_me]) 1671 call MPI_IALLGATHERV(cgq_buf, sendcount, MPI_DOUBLE_PRECISION, cgq_ptr, recvcounts, displs, & 1672 MPI_DOUBLE_PRECISION, sigma%bsum_comm%value, cgq_request, ierr) 1673 ABI_FREE(cgq_buf) 1674 #endif 1675 call xmpi_requests_add(+1) 1676 #endif 1677 1678 ABI_FREE(recvcounts) 1679 ABI_FREE(displs) 1680 end if 1681 #endif 1682 call timab(1908, 2, tsec) 1683 end if ! eph_stern 1684 1685 ! Loop over all 3*natom perturbations (Each core prepares its own potentials) 1686 ! In the inner loop, we calculate H1 * psi_k, stored in h1kets_kq on the k+q sphere. 1687 do imyp=1,my_npert 1688 idir = sigma%my_pinfo(1, imyp); ipert = sigma%my_pinfo(2, imyp); ipc = sigma%my_pinfo(3, imyp) 1689 1690 ! Set up local potential vlocal1 with proper dimensioning, from vtrial1 taking into account the spin. 1691 ! Each CPU prepares its own potentials. 1692 call rf_transgrid_and_pack(spin, nspden, psps%usepaw, cplex, nfftf, nfft, ngfft, gs_hamkq%nvloc, & 1693 pawfgr, mpi_enreg, vtrial, v1scf(:,:,:,imyp), vlocal, vlocal1(:,:,:,:,imyp)) 1694 1695 ! Continue to initialize the Hamiltonian (call it here to support dfpt_cgwf Sternheimer). 1696 call gs_hamkq%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.) 1697 1698 ! Prepare application of the NL part. 1699 call init_rf_hamiltonian(cplex, gs_hamkq, ipert, rf_hamkq, has_e1kbsc=.true.) 1700 call rf_hamkq%load_spin(spin, vlocal1=vlocal1(:,:,:,:,imyp), with_nonlocal=.true.) 1701 1702 if (ffnlk_request /= xmpi_request_null) call xmpi_wait(ffnlk_request, ierr) 1703 if (ffnl1_request /= xmpi_request_null) call xmpi_wait(ffnl1_request, ierr) 1704 1705 ! This call is not optimal because there are quantities in out that do not depend on idir,ipert 1706 call getgh1c_setup(gs_hamkq, rf_hamkq, dtset, psps, kk, kq, idir, ipert, & ! In 1707 cryst%natom, cryst%rmet, cryst%gprimd, cryst%gmet, istwf_k, & ! In 1708 npw_k, npw_kq, useylmgr1, kg_k, ylm_k, kg_kq, ylm_kq, ylmgr_kq, & ! In 1709 dkinpw, nkpg, nkpg1, kpg_k, kpg1_k, kinpw1, ffnlk, ffnl1, ph3d, ph3d1, & ! Out 1710 reuse_kpg_k=1, reuse_kpg1_k=1, reuse_ffnlk=1, reuse_ffnl1=1) ! Reuse some arrays 1711 1712 ! Compute H(1) applied to GS wavefunction Psi_nk(0) 1713 do ib_k=1,nbcalc_ks 1714 if (sigma%bsum_comm%skip(ib_k, root=root_bcalc(ib_k))) cycle ! MPI parallelism inside bsum_comm 1715 ! Store rank treating ib_k in root_bcalc 1716 band_ks = ib_k + bstart_ks - 1 1717 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 1718 ! Use scissor shift on 0-order eigenvalue 1719 eshift = eig0nk - dtset%dfpt_sciss 1720 1721 call getgh1c(berryopt0, kets_k(:,:,ib_k), cwaveprj0, h1kets_kq(:,:,imyp, ib_k), & 1722 grad_berry, gs1c, gs_hamkq, gvnlx1, idir, ipert, eshift, mpi_enreg, optlocal, & 1723 optnl, opt_gvnlx1, rf_hamkq, sij_opt, tim_getgh1c1, usevnl) 1724 end do 1725 1726 do ib_k=1,nbcalc_ks 1727 call xmpi_bcast(h1kets_kq(:,:,imyp,ib_k), root_bcalc(ib_k), sigma%bsum_comm%value, ierr) 1728 end do 1729 1730 if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then 1731 call timab(1909, 1, tsec) 1732 ! Activate Sternheimer. Note that we are still inside the MPI loop over my_npert. 1733 ! NB: Assume adiabatic AHC expression to compute the contribution of states above nbsum. 1734 1735 #ifdef DEV_BAND_PARA 1736 ! Prepare band parallelism in dfpt_cgwf via mpi_enreg. 1737 mpi_enreg%comm_band = sigma%bsum_comm%value 1738 mpi_enreg%me_band = sigma%bsum_comm%me 1739 mpi_enreg%nproc_band = sigma%bsum_comm%nproc 1740 #endif 1741 1742 ABI_CALLOC(out_eig1_k, (2*nbsum**2)) 1743 ABI_MALLOC(dcwavef, (2, npw_kq*nspinor*usedcwavef0)) 1744 ABI_MALLOC(gh1c_n, (2, npw_kq*nspinor)) 1745 ABI_MALLOC(ghc, (2, npw_kq*nspinor)) 1746 ABI_MALLOC(gsc, (2, npw_kq*nspinor)) 1747 ABI_MALLOC(gvnlxc, (2, npw_kq*nspinor)) 1748 1749 ! TODO: grad_berry is problematic because in dfpt_cgwf, the array is declared with 1750 ! 1751 ! real(dp),intent(in) :: grad_berry(2,mpw1*nspinor,nband) 1752 ! 1753 ! and 1754 ! 1755 ! npw1_k = number of plane waves at this k+q point 1756 ! 1757 ! So in principle we should allocate lot of memory to avoid bound checking error! 1758 ! For the time being use mpw1 = 0 because mpw1 is not used in this call to dfpt_cgwf 1759 ! still it's clear that the treatment of this array must be completely refactored in the DFPT code. 1760 ! 1761 grad_berry_size_mpw1 = 0 1762 1763 !TODO: to distribute cgq and kets memory, use mband_mem per core in band comm, but coordinate everyone with 1764 ! the following array (as opposed to the distribution of cg1 which is done in the normal dfpt calls 1765 ABI_MALLOC(bands_treated_now, (nbsum)) 1766 ABI_MALLOC (rank_band, (nbsum)) 1767 rank_band = 0 1768 1769 nline_in = min(100, npw_kq); if (dtset%nline > nline_in) nline_in = min(dtset%nline, npw_kq) 1770 1771 #ifndef DEV_BAND_PARA 1772 ! Wait for gatherv operation 1773 if (cgq_request /= xmpi_request_null) call xmpi_wait(cgq_request, ierr) 1774 #endif 1775 1776 do ib_k=1,nbcalc_ks 1777 band_ks = ib_k + bstart_ks - 1 1778 bands_treated_now(:) = 0; bands_treated_now(band_ks) = 1 1779 1780 #ifdef DEV_BAND_PARA 1781 ! Init rank_band and band_me from nbsum_rank. 1782 rank_band = -1; band_me = 1 1783 do ip=1,sigma%bsum_comm%nproc 1784 ii = sigma%nbsum_rank(ip,2) 1785 jj = sigma%nbsum_rank(ip,2) + sigma%nbsum_rank(ip,1) -1 1786 rank_band(ii:jj) = ip - 1 1787 if (inrange(band_ks, [ii, jj])) u1_master = ip - 1 1788 end do 1789 if (inrange(band_ks, [sigma%my_bsum_start, sigma%my_bsum_stop])) then 1790 band_me = band_ks - sigma%my_bsum_start + 1 1791 u1_band = band_ks 1792 else 1793 band_me = 1 1794 u1_band = -band_ks 1795 end if 1796 #else 1797 rank_band = 0 1798 band_me = band_ks 1799 u1_band = band_ks 1800 if (sigma%bsum_comm%skip(ib_k)) cycle ! MPI parallelism inside bsum_comm 1801 #endif 1802 1803 ! Init entry in cg1s_kq, either from cache or with zeros. 1804 if (use_u1c_cache) then 1805 u1c_ib_k = u1c%find_band(band_ks) 1806 if (u1c_ib_k /= -1) then 1807 call cgtk_change_gsphere(nspinor, & 1808 u1c%prev_npw_kq, istwfk1, u1c%prev_kg_kq, u1c%prev_cg1s_kq(1,1,ipc,u1c_ib_k), & 1809 npw_kq, istwfk1, kg_kq, cg1s_kq(1,1,ipc,ib_k), work_ngfft, work) 1810 else 1811 cg1s_kq(:,:,ipc,ib_k) = zero 1812 end if 1813 1814 else 1815 cg1s_kq(:,:,ipc,ib_k) = zero 1816 end if 1817 1818 mcgq = npw_kq * nspinor * nband_me 1819 mgscq = npw_kq * nspinor * nband_me * psps%usepaw 1820 nlines_done = 0 1821 call timab(1909, 2, tsec) 1822 1823 call dfpt_cgwf(u1_band, band_me, rank_band, bands_treated_now, berryopt0, & 1824 cgq, cg1s_kq(:,:,ipc,ib_k), kets_k(:,:,ib_k), & ! Important stuff 1825 cwaveprj, cwaveprj0, rf2, dcwavef, & 1826 ebands%eig(:, ik_ibz, spin), ebands%eig(:, ikq_ibz, spin), out_eig1_k, & 1827 ghc, gh1c_n, grad_berry, gsc, gscq, & 1828 gs_hamkq, gvnlxc, gvnlx1, icgq0, idir, ipert, igscq0, & 1829 mcgq, mgscq, mpi_enreg, grad_berry_size_mpw1, cryst%natom, nbsum, nband_me, & 1830 nbdbuf0, nline_in, npw_k, npw_kq, nspinor, & 1831 opt_gvnlx1, dtset%prtvol, quit0, out_resid, rf_hamkq, dtset%dfpt_sciss, -one, dtset%tolwfr, & 1832 usedcwavef0, dtset%wfoptalg, nlines_done) 1833 1834 tot_nlines_done = tot_nlines_done + nlines_done 1835 1836 #ifdef DEV_BAND_PARA 1837 call xmpi_bcast(cg1s_kq(:,:,ipc,ib_k), u1_master, sigma%bsum_comm%value, ierr) 1838 #endif 1839 1840 ! Handle possible convergence error. 1841 if (u1_band > 0) then 1842 if (out_resid > dtset%tolwfr) then 1843 write(msg, "(a,i0,a, 2(a,es13.5), 2a,i0,a)") & 1844 " Sternheimer didn't convergence for band: ", band_ks, ch10, & 1845 " resid:", out_resid, " >= tolwfr: ", dtset%tolwfr, ch10, & 1846 " after nline: ", nlines_done, " iterations. Increase nline and/or tolwfr." 1847 ABI_ERROR(msg) 1848 else if (out_resid < zero) then 1849 ABI_ERROR(sjoin(" resid: ", ftoa(out_resid), ", nlines_done:", itoa(nlines_done))) 1850 end if 1851 1852 if (my_rank == master .and. (enough_stern <= 5 .or. dtset%prtvol > 10)) then 1853 write(std_out, "(2(a,es13.5),a,i0)") & 1854 " Sternheimer converged with resid: ", out_resid, " <= tolwfr: ", dtset%tolwfr, & 1855 " after nlines_done: ", nlines_done 1856 enough_stern = enough_stern + 1 1857 end if 1858 end if 1859 end do ! ib_k 1860 1861 #ifdef DEV_BAND_PARA 1862 ! Revert changes in mpi_enreg. 1863 mpi_enreg%comm_band = xmpi_comm_self 1864 mpi_enreg%me_band = 0 1865 mpi_enreg%nproc_band = 1 1866 #endif 1867 1868 ABI_FREE(bands_treated_now) 1869 ABI_FREE(rank_band) 1870 ABI_FREE(out_eig1_k) 1871 ABI_FREE(dcwavef) 1872 ABI_FREE(gh1c_n) 1873 ABI_FREE(ghc) 1874 ABI_FREE(gsc) 1875 ABI_FREE(gvnlxc) 1876 if (imyp == my_npert) then 1877 ABI_FREE(cgq) 1878 ABI_FREE(gscq) 1879 end if 1880 !call timab(1909, 2, tsec) 1881 end if ! sternheimer 1882 1883 call rf_hamkq%free() 1884 ABI_FREE(kinpw1) 1885 ABI_FREE(dkinpw) 1886 ABI_FREE(ph3d) 1887 ABI_SFREE(ph3d1) 1888 end do ! imyp (loop over perturbations) 1889 1890 !call timab(1902, 2, tsec) 1891 ABI_FREE(gs1c) 1892 ABI_FREE(gvnlx1) 1893 ABI_FREE(vlocal1) 1894 ABI_FREE(v1scf) 1895 1896 ! Wait from phonon frequencies and displacements inside pert_comm 1897 call phstore%wait(cryst, phfrq, displ_cart, displ_red) 1898 1899 if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then 1900 call timab(1910, 1, tsec) 1901 ! Add contribution to Fan-Migdal self-energy coming from Sternheimer. 1902 ! NB: All procs inside (bsum_comm x pert_comm) enter here! 1903 1904 ! Store |Psi_1> to init Sternheimer solver for the next q-point. 1905 call u1c%store(qpt, npw_kq, nspinor, natom3, bstart_ks, nbcalc_ks, kg_kq, cg1s_kq) 1906 1907 ! h1kets_kq are MPI distributed inside pert_comm but we need off-diagonal pp' terms --> collect results. 1908 ABI_CALLOC(h1kets_kq_allperts, (2, npw_kq*nspinor, natom3, nbcalc_ks)) 1909 1910 ! Compute S_pp' = <D_{qp} vscf u_nk|u'_{nk+q p'}> 1911 ABI_CALLOC(stern_ppb, (2, natom3, natom3, nbcalc_ks)) 1912 1913 do ib_k=1,nbcalc_ks 1914 if (sigma%bsum_comm%skip(ib_k)) cycle ! MPI parallelism inside bsum_comm 1915 1916 call xmpi_sum(cg1s_kq(:,:,:,ib_k), sigma%pert_comm%value, ierr) 1917 1918 ! TODO 1919 !nelem = 2*npw_kq*nspinor*sigma%my_npert 1920 !call MPI_ALLGATHER(MPI_IN_PLACE, nelem, MPI_DOUBLE_PRECISION, cg1s_kq(:,:,:,ib_k), nelem, & 1921 ! MPI_DOUBLE_PRECISION, sigma%pert_comm%value, ierr) 1922 1923 call xmpi_allgather(h1kets_kq(:,:,:,ib_k), 2*npw_kq*nspinor*sigma%my_npert, & 1924 h1kets_kq_allperts(:,:,:,ib_k), sigma%pert_comm%value, ierr) 1925 1926 call cg_zgemm("C", "N", npw_kq*nspinor, natom3, natom3, & 1927 h1kets_kq_allperts(:,:,:,ib_k), cg1s_kq(:,:,:,ib_k), stern_ppb(:,:,:,ib_k)) 1928 1929 ! Save data for Debye-Waller that is performed outside the q-loop. 1930 if (q_is_gamma) stern_dw(:,:,:,ib_k) = stern_ppb(:,:,:,ib_k) 1931 end do 1932 1933 ABI_FREE(cg1s_kq) 1934 ABI_FREE(h1kets_kq_allperts) 1935 1936 if (q_is_gamma) call xmpi_sum(stern_dw, sigma%bsum_comm%value, ierr) 1937 1938 ! Compute contribution to Fan-Migdal for M > sigma%nbsum 1939 do imyp=1,my_npert 1940 nu = sigma%my_pinfo(3, imyp) 1941 wqnu = phfrq(nu); if (sigma%skip_phmode(nu, wqnu, dtset%eph_phrange_w)) cycle 1942 1943 ! Get phonon occupation for all temperatures. 1944 nqnu_tlist = occ_be(wqnu, sigma%kTmesh(:), zero) 1945 1946 do ib_k=1,nbcalc_ks 1947 if (sigma%bsum_comm%skip(ib_k)) cycle ! MPI parallelism inside bsum_comm 1948 1949 ! sum_{pp'} d_p* Stern_{pp'} d_p' with d = displ_red(:,:,:,nu) and S = stern_ppb(:,:,:,ib_k) 1950 vec_natom3 = zero 1951 call cg_zgemm("N", "N", natom3, natom3, 1, stern_ppb(:,:,:,ib_k), displ_red(:,:,:,nu), vec_natom3) 1952 dotri = cg_zdotc(natom3, displ_red(:,:,:,nu), vec_natom3) 1953 !write(std_out, *)"dotri:", dotri 1954 rfact = dotri(1) 1955 !rfact = cg_real_zdotc(natom3, displ_red(:,:,:,nu), vec_natom3) 1956 rfact = rfact * sigma%wtq_k(iq_ibz_k) / (two * wqnu) 1957 1958 do it=1,sigma%ntemp 1959 rtmp = (two * nqnu_tlist(it) + one) * rfact 1960 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + rtmp 1961 sigma%fan_vals(it, ib_k) = sigma%fan_vals(it, ib_k) + rtmp 1962 sigma%fan_stern_vals(it, ib_k) = sigma%fan_stern_vals(it, ib_k) + rtmp 1963 ! Add static term from Sternheimer to Sigma(w) as well. 1964 if (sigma%nwr > 0) sigma%vals_wr(:, it, ib_k) = sigma%vals_wr(:, it, ib_k) + rtmp 1965 !if (sigma%nwr > 0) sigma%vals_wr(:, it, ib_k) = sigma%vals_wr(:, it, ib_k) + gkq2 * cfact_wr(:) 1966 end do 1967 1968 ! TODO Eliashberg functions with Sternheimer 1969 !if (dtset%prteliash /= 0) then 1970 !end if 1971 end do 1972 end do 1973 1974 ABI_FREE(stern_ppb) 1975 call timab(1910, 2, tsec) 1976 end if ! eph_stern /= 0 1977 1978 ! ============================================== 1979 ! Sum over m bands parallelized inside bsum_comm 1980 ! ============================================== 1981 call timab(1903, 1, tsec) 1982 1983 do ibsum_kq=sigma%my_bsum_start, sigma%my_bsum_stop 1984 call timab(1904, 1, tsec) 1985 ! This can happen if we have loaded the wavefunctions inside the energy range. 1986 if (sigma%imag_only .and. sigma%qint_method == 1) then 1987 if (.not. wfd%ihave_ug(ibsum_kq, ikq_ibz, spin)) then 1988 ignore_ibsum_kq = ignore_ibsum_kq + 1; cycle 1989 end if 1990 end if 1991 1992 ! Symmetrize k+q wavefunctions in the BZ from IBZ (if needed). 1993 if (isirr_kq) then 1994 ! Copy u_kq(G) 1995 call wfd%copy_cg(ibsum_kq, ikq_ibz, spin, bra_kq) 1996 else 1997 ! Reconstruct u_kq(G) from the IBZ image. 1998 ! Use cgwork as workspace array, results stored in bra_kq 1999 ! g0_kq = g0ibz_kq + g0bz_kq 2000 call wfd%copy_cg(ibsum_kq, ikq_ibz, spin, cgwork) 2001 call cgtk_rotate(cryst, kq_ibz, isym_kq, trev_kq, g0_kq, nspinor, ndat1, & 2002 npw_kqirr, wfd%kdata(ikq_ibz)%kg_k, & 2003 npw_kq, kg_kq, istwf_kqirr, istwf_kq, cgwork, bra_kq, work_ngfft, work) 2004 end if 2005 2006 ! Get gkk(kcalc, q, idir_ipert) in the atomic representation. 2007 ! No need to handle istwf_kq because it's always 1. 2008 gkq_atm = zero; cnt = 0 2009 do imyp=1,my_npert 2010 ipc = sigma%my_pinfo(3, imyp) 2011 ! Calculate <u_(band,k+q)^(0)|H_(k+q,k)^(1)|u_(band,k)^(0)> for this pert (NC psps) istwf_k always 1 2012 do ib_k=1,nbcalc_ks 2013 gkq_atm(:, ib_k, ipc) = cg_zdotc(npw_kq*nspinor, bra_kq, h1kets_kq(:,:,imyp,ib_k)) 2014 cnt = cnt + 1 2015 gkq_allgather(:,cnt, 1) = gkq_atm(:, ib_k, ipc) 2016 end do 2017 !call cg_zgemv("C", npw_kq*nspinor, nbcalc_ks, h1kets_kq(:,:,:,imyp), bra_kq, gkq_atm(:,:,ipc)) 2018 end do 2019 call timab(1904, 2, tsec) 2020 call timab(1905, 1, tsec) 2021 !ii = nbcalc_ks * my_npert 2022 !call cg_zgemm("H", "N", npw_kq*nspinor, ii, ii, h1kets_kq, bra_kq, gkq_atm) 2023 !call cg_zgemm("H", "N", npw_kq*nspinor, ii, ii, bra_kq, h1kets_kq, gkq_atm) 2024 2025 ! Get gkk(kcalc, q, nu) in the phonon representation. 2026 ! Need to gather all perts distributed in pert_comm 2027 if (sigma%pert_comm%nproc > 1) then 2028 call xmpi_allgather(gkq_allgather(:,:,1), 2 * nbcalc_ks * my_npert, gkq_allgather(:,:,2), & 2029 sigma%pert_comm%value, ierr) 2030 do cnt=1,nbcalc_ks*natom3 2031 ipc = 1 + (cnt - 1) / nbcalc_ks 2032 ib_k = 1 + mod(cnt - 1, nbcalc_ks) 2033 gkq_atm(:, ib_k, ipc) = gkq_allgather(:, cnt, 2) 2034 end do 2035 end if 2036 2037 call ephtk_gkknu_from_atm(1, nbcalc_ks, 1, natom, gkq_atm, phfrq, displ_red, gkq_nu) 2038 2039 ! bsum_2 and bsum_3 are hotspots. 2040 call timab(1905, 2, tsec) 2041 call timab(1906, 1, tsec) 2042 2043 ! Save e-ph matrix elements for Debye-Waller computation that will be performed outside the q-loop. 2044 ! gkq0_atm(2, nbcalc_ks, bsum_start:bsum_stop, natom3) 2045 if (q_is_gamma .and. .not. sigma%imag_only) gkq0_atm(:, :, ibsum_kq, :) = gkq_atm 2046 2047 if (osc_ecut > zero) then 2048 workq_ug = cmplx(bra_kq(1, :), bra_kq(2, :), kind=gwpc) 2049 call fft_ug(npw_kq, wfd%nfft, nspinor, ndat1, wfd%mgfft, wfd%ngfft, & 2050 istwf_kq, kg_kq, gbound_kq, workq_ug, ur_kq) 2051 2052 ! We need <k+q| e^{iq+G}|k> --> compute <k| e^{-i(q+G)}|k+q> with FFT and take CC. 2053 do ib_k=1,nbcalc_ks 2054 work_ur = ur_kq * conjg(ur_k(:, ib_k)) 2055 ! Call zero-padded FFT routine. 2056 call fftpad(work_ur, ngfft, n1, n2, n3, n1, n2, n3, nspinor, wfd%mgfft, -1, osc_gbound_q) 2057 2058 ! Need results on the G-sphere --> Transfer data from FFT to G-sphere. 2059 do ispinor=1,nspinor 2060 do ig=1,osc_npw 2061 ifft = osc_indpw(ig) + (ispinor-1) * wfd%nfft 2062 osc_ks(ig + (ispinor -1) * osc_npw, ib_k) = conjg(work_ur(ifft)) 2063 end do 2064 end do 2065 2066 !band_ks = ib_k + bstart_ks - 1 2067 !if (ibsum_kq == band_ks) then 2068 !if (ibsum_kq == band_ks .and. all(abs(qpt) < tol12)) then 2069 ! write(std_out,"(a,i0,2a)")" Ene and Oscillator for band: ", band_ks, ", and q-point: ", trim(ktoa(qpt)) 2070 ! write(std_out,*)ebands%eig(band_ks, ik_ibz, spin) * Ha_eV, osc_ks(:2,ib_k) 2071 !end if 2072 end do 2073 end if 2074 2075 eig0mkq = ebands%eig(ibsum_kq, ikq_ibz, spin) 2076 2077 ! q-weight for naive integration 2078 weight_q = sigma%wtq_k(iq_ibz_k) 2079 2080 if (sigma%mrta > 0) then 2081 ! Compute v_kq 2082 ! If k+q is not in the IBZ, we need to recostruct the value by symmetry using v(Sq) = S v(q). 2083 ! Use transpose(R) because we are using the tables for the wavefunctions 2084 ! In this case listkk has been called with symrel and use_symrec=False 2085 ! so q_bz = S^T q_ibz where S is the isym_kq symmetry 2086 vkq = vcar_ibz(:, ibsum_kq, ikq_ibz, spin) 2087 if (.not. isirr_kq) then 2088 vkq = matmul(transpose(cryst%symrel_cart(:,:,isym_kq)), vkq) 2089 if (trev_kq /= 0) vkq = -vkq 2090 vkq_norm = sqrt(dot_product(vk, vk)) 2091 end if 2092 2093 ! Precompute alpha MRTA coefficients for all nk states. 2094 do ib_k=1,nbcalc_ks 2095 vk = sigma%vcar_calc(:, ib_k, ikcalc, spin) 2096 vkk_norm = sqrt(dot_product(vk, vk)) 2097 alpha_mrta(ib_k) = one ! zero 2098 if (vkk_norm > tol6) alpha_mrta(ib_k) = one - dot_product(vkq, vk) / vkk_norm ** 2 2099 !if (vkk_norm > tol6 .and. vkq_norm > tol6) then 2100 ! alpha_mrta(ib_k) = one - dot_product(vkq, vk) / (vkk_norm * vk_norm) 2101 !end if 2102 end do 2103 end if 2104 call timab(1906, 2, tsec) 2105 call timab(1907, 1, tsec) 2106 2107 ! Accumulate contribution to the FM self-energy 2108 do imyp=1,my_npert 2109 nu = sigma%my_pinfo(3, imyp) 2110 ! Ignore unstable modes or modes that should be skipped. 2111 wqnu = phfrq(nu); if (sigma%skip_phmode(nu, wqnu, dtset%eph_phrange_w)) cycle 2112 2113 if (dtset%eph_prtscratew == 1) then 2114 ! Precompute delta(w-w_qnu) 2115 gaussw_qnu = gaussian(sigma%phmesh - wqnu, dtset%ph_smear) 2116 end if 2117 2118 ! For each band in Sigma_{nk} 2119 do ib_k=1,nbcalc_ks 2120 band_ks = ib_k + bstart_ks - 1 2121 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 2122 gkq2 = weight_q * (gkq_nu(1,ib_k,nu) ** 2 + gkq_nu(2,ib_k,nu) ** 2) 2123 ediff = eig0nk - eig0mkq 2124 intra_band = q_is_gamma .and. ediff <= TOL_EDIFF 2125 same_band = ibsum_kq == band_ks 2126 2127 ! Optionally, accumulate contribution to Eliashberg functions 2128 if (dtset%prteliash /= 0) then 2129 ! EPH strength with delta(e_{nk} - e_{m\kq}) 2130 rfact = gaussian(eig0nk - eig0mkq, dtset%tsmear) 2131 sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 1) = sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 1) + & 2132 rfact * (gkq_nu(1, ib_k, nu) ** 2 + gkq_nu(2, ib_k, nu) ** 2) 2133 2134 ! Treat contribution to Eliashberg function due to Fan term. 2135 if (ediff > wqnu) then 2136 rfact = one / ediff 2137 else 2138 ! Non adiabatic regime --> Add complex shift. 2139 ! Note however that the expression for this flavor of Eliashberg function relies on adiabaticity. 2140 rfact = real(one / (ediff + sigma%ieta)) 2141 end if 2142 2143 gf_val = gkq_nu(1, ib_k, nu) ** 2 + gkq_nu(2, ib_k, nu) ** 2 2144 if (intra_band .and. sigma%frohl_model == 1) then 2145 gf_val = zero; if (same_band) gf_val = zpr_frohl_sphcorr(nu) * (four_pi / three * q0rad ** 3) 2146 end if 2147 2148 sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 2) = sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 2) + gf_val * rfact 2149 ! TODO: Add Sternheimer contribution 2150 2151 if (dtset%prteliash == 3) then 2152 ! Accumulate: |g(k,q)|^2 delta(e - e_{m\kq}) delta(w - w_\qnu} 2153 delta_e_minus_emkq = gaussian(sigma%a2f_emesh - eig0mkq, dtset%tsmear) 2154 dwargs = sigma%phmesh - phfrq(nu) 2155 dtw_weights(:, 1) = gaussian(dwargs, dtset%ph_smear) 2156 do iw=1,sigma%phmesh_size 2157 sigma%a2few(:, iw, ib_k) = sigma%a2few(:, iw, ib_k) + & 2158 delta_e_minus_emkq(:) * dtw_weights(iw, 1) * gf_val * sigma%wtq_k(iq_ibz_k) 2159 end do 2160 end if 2161 end if ! prteliash /= 0 2162 2163 do it=1,sigma%ntemp 2164 ! Compute electronic occ for this T (note mu_e(it) Fermi level) 2165 nqnu = occ_be(wqnu, sigma%kTmesh(it), zero) 2166 f_nk = occ_fd(eig0nk, sigma%kTmesh(it), sigma%mu_e(it)) 2167 f_mkq = occ_fd(eig0mkq, sigma%kTmesh(it), sigma%mu_e(it)) 2168 2169 ! Here we have to handle 3 different logical values leading to 9 different cases: 2170 ! 2171 ! qint_method 0 1 2172 ! use_doublegrid .true. .false. 2173 ! imag_only .true. .false. 2174 ! 2175 ! We will write this with nested conditionals using the order above 2176 2177 if (sigma%qint_method == 0) then 2178 ! ========= 2179 ! zcut mode 2180 ! ========= 2181 2182 if (sigma%use_doublegrid) then 2183 cfact = zero 2184 do jj=1,sigma%eph_doublegrid%ndiv 2185 ! Double Grid shared points weights 2186 ikq_bz_fine = sigma%eph_doublegrid%mapping(2, jj) 2187 weight = sigma%eph_doublegrid%weights_dense(ikq_bz_fine) 2188 2189 ! Electronic eigenvalue 2190 ikq_ibz_fine = sigma%eph_doublegrid%mapping(5, jj) 2191 eig0mkq = sigma%eph_doublegrid%ebands_dense%eig(ibsum_kq, ikq_ibz_fine, spin) 2192 f_mkq = occ_fd(eig0mkq, sigma%kTmesh(it), sigma%mu_e(it)) 2193 2194 ! Phonon frequency 2195 iq_ibz_fine = sigma%eph_doublegrid%mapping(6, jj) 2196 wqnu = sigma%ephwg%phfrq_ibz(iq_ibz_fine, nu) 2197 nqnu = occ_be(wqnu, sigma%kTmesh(it), zero) 2198 2199 if (dtset%eph_ahc_type == 1) then 2200 cfact = cfact + & 2201 ((nqnu + f_mkq ) / (eig0nk - eig0mkq + wqnu + sigma%ieta) + & 2202 (nqnu - f_mkq + one) / (eig0nk - eig0mkq - wqnu + sigma%ieta) ) * weight 2203 else 2204 cfact = cfact + ((two * nqnu + one) / (eig0nk - eig0mkq + sigma%ieta)) * weight 2205 endif 2206 enddo 2207 else 2208 ! No double-grid. 2209 if (dtset%eph_ahc_type == 1) then 2210 cfact = (nqnu + f_mkq ) / (eig0nk - eig0mkq + wqnu + sigma%ieta) + & 2211 (nqnu - f_mkq + one) / (eig0nk - eig0mkq - wqnu + sigma%ieta) 2212 else 2213 cfact = (two * nqnu + one) / (eig0nk - eig0mkq + sigma%ieta) 2214 endif 2215 endif 2216 ! 2217 if (sigma%imag_only) then 2218 simag = gkq2 * aimag(cfact) 2219 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + j_dpc * simag 2220 if (sigma%mrta > 0) then 2221 sigma%linewidth_mrta(it, ib_k) = sigma%linewidth_mrta(it, ib_k) + simag * alpha_mrta(ib_k) 2222 end if 2223 2224 if (dtset%eph_prtscratew == 1) then 2225 sigma%scratew(:, it, ib_k, 1) = sigma%scratew(:, it, ib_k, 1) + simag * gaussw_qnu 2226 sigma%scratew(:, it, ib_k, 2) = sigma%scratew(:, it, ib_k, 2) + simag * gaussw_qnu * alpha_mrta(ib_k) 2227 end if 2228 2229 else 2230 ! Re + Im self-energy 2231 sig_cplx = gkq2 * cfact 2232 if (intra_band .and. sigma%frohl_model == 1) then 2233 ! Treat Frohlich divergence with spherical integration around the Gamma point. 2234 ! In principle one should rescale by the number of degenerate states but it's 2235 ! easier to move all the weight to a single band. 2236 sig_cplx = czero; if (same_band) sig_cplx = zpr_frohl_sphcorr(nu) * (two * f_mkq - one) 2237 end if 2238 2239 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + sig_cplx 2240 sigma%fan_vals(it, ib_k) = sigma%fan_vals(it, ib_k) + sig_cplx 2241 end if 2242 2243 else 2244 2245 ! =================== 2246 ! Tetrahedron method 2247 ! =================== 2248 if (sigma%use_doublegrid) then 2249 ! Tetra + double grid 2250 2251 do jj=1,sigma%eph_doublegrid%ndiv 2252 ! Double Grid shared points weights 2253 ikq_bz_fine = sigma%eph_doublegrid%mapping(2, jj) 2254 weight = sigma%eph_doublegrid%weights_dense(ikq_bz_fine) 2255 2256 ! Electronic eigenvalue 2257 ikq_ibz_fine = sigma%eph_doublegrid%mapping(5, jj) 2258 eig0mkq = sigma%eph_doublegrid%ebands_dense%eig(ibsum_kq, ikq_ibz_fine, spin) 2259 f_mkq = occ_fd(eig0mkq, sigma%kTmesh(it), sigma%mu_e(it)) 2260 2261 ! Phonon frequency 2262 iq_ibz_fine = sigma%eph_doublegrid%mapping(6, jj) 2263 wqnu = sigma%ephwg%phfrq_ibz(iq_ibz_fine,nu) 2264 nqnu = occ_be(wqnu, sigma%kTmesh(it), zero) 2265 2266 ! Add Frohlich contribution 2267 gkq2_pf = gkq2 2268 if (osc_ecut /= zero) gkq2_pf = gkq2_pf + weight_q * gkq2_lr(jj,ib_k,imyp) 2269 2270 if (sigma%imag_only) then 2271 ! Note pi factor from Sokhotski-Plemelj theorem. 2272 simag = gkq2_pf * pi * ( & 2273 (nqnu + f_mkq ) * sigma%deltaw_pm(1, ib_k, imyp, ibsum_kq, imyq, jj) + & 2274 (nqnu - f_mkq + one) * sigma%deltaw_pm(2, ib_k, imyp, ibsum_kq, imyq, jj) ) * weight 2275 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + j_dpc * simag 2276 if (sigma%mrta > 0) then 2277 sigma%linewidth_mrta(it, ib_k) = sigma%linewidth_mrta(it, ib_k) + simag * alpha_mrta(ib_k) 2278 end if 2279 2280 if (dtset%eph_prtscratew == 1) then 2281 sigma%scratew(:, it, ib_k, 1) = sigma%scratew(:, it, ib_k, 1) + simag * gaussw_qnu 2282 sigma%scratew(:, it, ib_k, 2) = sigma%scratew(:, it, ib_k, 2) + simag * gaussw_qnu * alpha_mrta(ib_k) 2283 end if 2284 2285 else 2286 ! Re + Sigma with tetra and double grid 2287 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + gkq2_pf * ( & 2288 (nqnu + f_mkq ) * sigma%cweights(1, 1, ib_k, imyp, ibsum_kq, imyq, jj) + & 2289 (nqnu - f_mkq + one) * sigma%cweights(1, 2, ib_k, imyp, ibsum_kq, imyq, jj) ) * weight 2290 end if 2291 end do 2292 2293 else 2294 2295 ! Tetrahedron method WITHOUT double grid. 2296 if (sigma%imag_only) then 2297 ! Imag part 2298 simag = gkq2 * pi * ( & 2299 (nqnu + f_mkq ) * sigma%deltaw_pm(1, ib_k, imyp, ibsum_kq, imyq, 1) + & 2300 (nqnu - f_mkq + one) * sigma%deltaw_pm(2, ib_k, imyp, ibsum_kq, imyq, 1) ) 2301 2302 if (intra_band .and. sigma%frohl_model == 1) then 2303 ! Treat Frohlich divergence with spherical integration of deltas around the Gamma point. 2304 ! In principle one should rescale by the number of degenerate states but it's 2305 ! easier to move all the weight to a single band 2306 ! TODO: Check the sign, use convention for retarded function 2307 simag = zero 2308 if (same_band) simag = -pi * sum(sigma%frohl_deltas_sphcorr(1:2, it, ib_k, nu), dim=1) 2309 end if 2310 2311 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + j_dpc * simag 2312 if (sigma%mrta > 0) then 2313 sigma%linewidth_mrta(it, ib_k) = sigma%linewidth_mrta(it, ib_k) + simag * alpha_mrta(ib_k) 2314 end if 2315 2316 if (dtset%eph_prtscratew == 1) then 2317 sigma%scratew(:, it, ib_k, 1) = sigma%scratew(:, it, ib_k, 1) + simag * gaussw_qnu 2318 sigma%scratew(:, it, ib_k, 2) = sigma%scratew(:, it, ib_k, 2) + simag * gaussw_qnu * alpha_mrta(ib_k) 2319 end if 2320 2321 if (dtset%ibte_prep > 0) then 2322 ! Save scattering rates. 2323 sigma%srate(ibsum_kq, ib_k, it, imyq) = sigma%srate(ibsum_kq, ib_k, it, imyq) + & 2324 gkq2 * two_pi * ( & 2325 (nqnu - f_nk + one) * sigma%deltaw_pm(1, ib_k, imyp, ibsum_kq, imyq, 1) + & 2326 (nqnu + f_nk ) * sigma%deltaw_pm(2, ib_k, imyp, ibsum_kq, imyq, 1) ) 2327 end if 2328 2329 else 2330 ! Re + Sigma with tetra and WITHOUT double grid 2331 sig_cplx = gkq2 * ( & 2332 (nqnu + f_mkq ) * sigma%cweights(1, 1, ib_k, imyp, ibsum_kq, imyq, 1) + & 2333 (nqnu - f_mkq + one) * sigma%cweights(1, 2, ib_k, imyp, ibsum_kq, imyq, 1) ) 2334 2335 if (intra_band .and. sigma%frohl_model == 1) then 2336 ! Treat Frohlich divergence with spherical integration around the Gamma point. 2337 ! In principle one should rescale by the number of degenerate states but it's 2338 ! easier to move all the weight to a single band 2339 sig_cplx = czero 2340 if (same_band) sig_cplx = zpr_frohl_sphcorr(nu) * (two * f_mkq - one) 2341 end if 2342 2343 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + sig_cplx 2344 endif 2345 end if 2346 end if 2347 2348 ! Derivative of sigma 2349 ! TODO: should calculate this with the double grid as well 2350 if (.not. sigma%imag_only) then 2351 ! Accumulate d(Re Sigma) / dw(w=eKS) for state ib_k 2352 !cfact(x) = (nqnu + f_mkq ) / (x - eig0mkq + wqnu + sigma%ieta) + & 2353 ! (nqnu - f_mkq + one) / (x - eig0mkq - wqnu + sigma%ieta) 2354 gmod2 = (eig0nk - eig0mkq + wqnu) ** 2 2355 hmod2 = (eig0nk - eig0mkq - wqnu) ** 2 2356 rfact = (nqnu + f_mkq ) * (-gmod2 + aimag(sigma%ieta)**2) / (gmod2 + aimag(sigma%ieta)**2) ** 2 + & 2357 (nqnu - f_mkq + one) * (-hmod2 + aimag(sigma%ieta)**2) / (hmod2 + aimag(sigma%ieta)**2) ** 2 2358 sigma%dvals_de0ks(it, ib_k) = sigma%dvals_de0ks(it, ib_k) + gkq2 * rfact 2359 !cfact = (nqnu + f_mkq ) / (eig0nk - eig0mkq + wqnu + sigma%ieta) + & 2360 ! (nqnu - f_mkq + one) / (eig0nk - eig0mkq - wqnu + sigma%ieta) 2361 !sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + gkq2 * cfact 2362 2363 !cfact = (eig0nk - eig0mkq + wqnu + sigma%ieta) 2364 !gmod2 = cfact * dconjg(cfact) 2365 !cfact = (eig0nk - eig0mkq - wqnu + sigma%ieta) 2366 !hmod2 = cfact * dconjg(cfact) 2367 !sigma%dvals_de0ks(it, ib_k) = sigma%dvals_de0ks(it, ib_k) + gkq2 * ( & 2368 ! (nqnu + f_mkq) * (gmod2 - two * (eig0nk - eig0mkq + wqnu) ** 2) / gmod2 ** 2 + & 2369 ! (nqnu - f_mkq + one) * (hmod2 - two * (eig0nk - eig0mkq - wqnu) ** 2) / hmod2 ** 2 & 2370 !) 2371 2372 ! Accumulate Sigma(w) for state ib_k if spectral function is wanted. 2373 if (sigma%nwr > 0) then 2374 if (sigma%qint_method == 1) then 2375 ! Tetra 2376 cfact_wr(:) = (nqnu + f_mkq ) * sigma%cweights(2:, 1, ib_k, imyp, ibsum_kq, imyq, 1) + & 2377 (nqnu - f_mkq + one) * sigma%cweights(2:, 2, ib_k, imyp, ibsum_kq, imyq, 1) 2378 else 2379 ! Zcut 2380 cfact_wr(:) = (nqnu + f_mkq ) / (sigma%wrmesh_b(:,ib_k) - eig0mkq + wqnu + sigma%ieta) + & 2381 (nqnu - f_mkq + one) / (sigma%wrmesh_b(:,ib_k) - eig0mkq - wqnu + sigma%ieta) 2382 end if 2383 cfact_wr(:) = gkq2 * cfact_wr(:) 2384 2385 if (intra_band .and. sigma%frohl_model == 1) then 2386 ! Add Frohlich correction to Sigma_nk(w) 2387 cfact_wr(:) = zero; if (same_band) cfact_wr(:) = fmw_frohl_sphcorr(:,nu,it,ib_k) 2388 end if 2389 2390 sigma%vals_wr(:,it,ib_k) = sigma%vals_wr(:,it,ib_k) + cfact_wr(:) 2391 end if ! nwr > 0 2392 end if 2393 2394 end do ! it 2395 end do ! ib_k 2396 end do ! imyp 2397 call timab(1907, 2, tsec) 2398 2399 end do ! ibsum_kq (sum over bands at k+q) 2400 call timab(1903, 2, tsec) 2401 2402 ABI_FREE(bra_kq) 2403 ABI_FREE(cgwork) 2404 ABI_FREE(h1kets_kq) 2405 ABI_FREE(kpg1_k) 2406 ABI_FREE(ffnl1) 2407 2408 if (osc_ecut /= zero) then 2409 ABI_FREE(osc_gvecq) 2410 ABI_FREE(osc_indpw) 2411 ABI_FREE(osc_ks) 2412 ABI_FREE(workq_ug) 2413 end if 2414 2415 if (imyq <= 10 .or. mod(imyq, 100) == 0) then 2416 write(msg,'(4(a,i0),a)') " k-point [",my_ikcalc,"/",sigma%my_nkcalc, "] q-point [",imyq,"/",sigma%my_nqibz_k,"]" 2417 call cwtime_report(msg, cpu, wall, gflops) 2418 end if 2419 end do ! iq_ibz_k (sum over q-points in IBZ_k) 2420 2421 call cwtime_report(" Fan-Migdal q-loop", cpu_qloop, wall_qloop, gflops_qloop) 2422 2423 ! Print cache stats. 2424 if (sigma%use_ftinterp) then 2425 call dvdb%ft_qcache%report_stats() 2426 if (dvdb%ft_qcache%v1scf_3natom_request /= xmpi_request_null) call xmpi_wait(dvdb%ft_qcache%v1scf_3natom_request, ierr) 2427 else 2428 call dvdb%qcache%report_stats() 2429 end if 2430 2431 ABI_FREE(sigma%e0vals) 2432 ABI_FREE(kets_k) 2433 ABI_FREE(gkq_atm) 2434 ABI_FREE(gkq_nu) 2435 ABI_FREE(gkq_allgather) 2436 ABI_SFREE(fmw_frohl_sphcorr) 2437 2438 if (osc_ecut /= zero) then 2439 ABI_FREE(ur_k) 2440 ABI_FREE(ur_kq) 2441 ABI_FREE(work_ur) 2442 ABI_FREE(gkq2_lr) 2443 end if 2444 2445 ! ========================= 2446 ! Compute Debye-Waller term 2447 ! ========================= 2448 if (.not. sigma%imag_only) then 2449 call cwtime(cpu_dw, wall_dw, gflops_dw, "start", msg=" Computing Debye-Waller within the rigid ion approximation...") 2450 ! Collect gkq0_atm inside qpt_comm 2451 ! FIXME: In principle it's sufficient to broadcast from itreated_q0 inside qpt_comm 2452 ! Yet, q-points are not equally distributed so this synch is detrimental. 2453 2454 call cwtime(cpu, wall, gflops, "start") 2455 call xmpi_sum(gkq0_atm, sigma%qpt_comm%value, ierr) 2456 if (dtset%eph_stern /= 0) call xmpi_sum(stern_dw, sigma%qpt_comm%value, ierr) 2457 call cwtime_report(" DW MPI synch before q-loop", cpu, wall, gflops) 2458 2459 ! Integral over IBZ(k) distributed inside qpt_comm 2460 nq = sigma%nqibz; if (sigma%symsigma == 0) nq = sigma%nqbz 2461 if (abs(sigma%symsigma) == +1) nq = sigma%nqibz_k 2462 call xmpi_split_work(nq, sigma%qpt_comm%value, q_start, q_stop) 2463 2464 do iq_ibz_k=q_start,q_stop 2465 call cwtime(cpu, wall, gflops, "start") 2466 2467 if (abs(sigma%symsigma) == 1) then 2468 ! Sum over IBZ_k 2469 qpt = sigma%qibz_k(:, iq_ibz_k); weight_q = sigma%wtq_k(iq_ibz_k) 2470 iq_ibz = sigma%ind_ibzk2ibz(1, iq_ibz_k) 2471 isym_q = sigma%ind_ibzk2ibz(2, iq_ibz_k) 2472 trev_q = sigma%ind_ibzk2ibz(6, iq_ibz_k) 2473 ! Don't test if umklapp == 0 because we use the periodic gauge: phfreq(q+G) = phfreq(q) and eigvec(q) = eigvec(q+G) 2474 isirr_q = (isym_q == 1 .and. trev_q == 0) 2475 2476 ! Sum over IBZ 2477 ! TODO: This should be much faster but it should be tested. 2478 !qpt = sigma%qibz(:,iq_ibz_k); weight_q = sigma%wtq(iq_ibz_k) 2479 2480 call phstore%async_rotate(cryst, ifc, iq_ibz, sigma%qibz(:, iq_ibz), qpt, isym_q, trev_q) 2481 call phstore%wait(cryst, phfrq, displ_cart, displ_red) 2482 2483 ! Get phonons for this q-point. 2484 !call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red, comm=sigma%pert_comm%value) 2485 2486 else 2487 ! Sum over full BZ 2488 qpt = sigma%qbz(:, iq_ibz_k); weight_q = one / sigma%nqbz 2489 2490 ! Get phonons for this q-point. 2491 call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red, comm=sigma%pert_comm%value) 2492 end if 2493 2494 ! Sum over my phonon modes for this q-point. 2495 do imyp=1,my_npert 2496 nu = sigma%my_pinfo(3, imyp) 2497 ! Ignore acoustic or unstable modes. 2498 wqnu = phfrq(nu); if (sigma%skip_phmode(nu, wqnu, dtset%eph_phrange_w)) cycle 2499 2500 ! Get phonon occupation for all temperatures. 2501 nqnu_tlist = occ_be(wqnu, sigma%kTmesh(:), zero) 2502 2503 ! Compute T_pp'(q,nu) matrix in reduced coordinates. 2504 do ip2=1,natom3 2505 idir2 = mod(ip2-1, 3) + 1; ipert2 = (ip2 - idir2) / 3 + 1 2506 do ip1=1,natom3 2507 idir1 = mod(ip1-1, 3) + 1; ipert1 = (ip1 - idir1) / 3 + 1 2508 ! (k,a) (k,a')* + (k',a) (k',a')* 2509 dka = dcmplx(displ_red(1, idir1, ipert1, nu), displ_red(2, idir1, ipert1, nu)) 2510 dkap = dcmplx(displ_red(1, idir2, ipert1, nu), displ_red(2, idir2, ipert1, nu)) 2511 dkpa = dcmplx(displ_red(1, idir1, ipert2, nu), displ_red(2, idir1, ipert2, nu)) 2512 dkpap = dcmplx(displ_red(1, idir2, ipert2, nu), displ_red(2, idir2, ipert2, nu)) 2513 tpp_red(ip1, ip2) = dka * dconjg(dkap) + dkpa * dconjg(dkpap) 2514 end do 2515 end do 2516 2517 ! Sum over my bands and add (static) DW contribution for the different temperatures. 2518 do ibsum=sigma%my_bsum_start, sigma%my_bsum_stop 2519 eig0mk = ebands%eig(ibsum, ik_ibz, spin) 2520 2521 ! For each n in Sigma_nk 2522 do ib_k=1,nbcalc_ks 2523 band_ks = ib_k + bstart_ks - 1 2524 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 2525 ! 2526 ! Compute DW term following XG paper. Check prefactor. 2527 ! gkq0_atm(2, nbcalc_ks, bsum_start:bsum_stop, natom3) 2528 gdw2 = zero 2529 do ip2=1,natom3 2530 do ip1=1,natom3 2531 cfact = ( & 2532 + gkq0_atm(1, ib_k, ibsum, ip1) * gkq0_atm(1, ib_k, ibsum, ip2) & 2533 + gkq0_atm(2, ib_k, ibsum, ip1) * gkq0_atm(2, ib_k, ibsum, ip2) & 2534 + gkq0_atm(1, ib_k, ibsum, ip2) * gkq0_atm(1, ib_k, ibsum, ip1) & 2535 + gkq0_atm(2, ib_k, ibsum, ip2) * gkq0_atm(2, ib_k, ibsum, ip1) & 2536 ) 2537 ! 2538 gdw2 = gdw2 + real(tpp_red(ip1,ip2) * cfact) 2539 end do 2540 end do 2541 gdw2 = gdw2 / (four * two * wqnu) 2542 ! 2543 if (dtset%eph_stern /= 0 .and. ibsum == bsum_stop) then 2544 ! Compute DW term for m > nband 2545 cfact = zero 2546 do ip2=1,natom3 2547 do ip1=1,natom3 2548 cfact = cfact + tpp_red(ip1, ip2) * cmplx(stern_dw(1,ip1,ip2,ib_k), stern_dw(2,ip1,ip2,ib_k), kind=dpc) 2549 end do 2550 end do 2551 ! There's no 1/two here because I don't symmetrize the expression. 2552 ! TODO: Test symmetrization, real quantity? add support for the different Eliashberg functions with Stern 2553 gdw2_stern = real(cfact) / (four * wqnu) 2554 end if 2555 ! 2556 ! Handle n == m and degenerate states. 2557 ediff = eig0nk - eig0mk ! SP: one cannot cycle here because the Sternheimer contribution needs to be computed 2558 ! 2559 ! Optionally, accumulate DW contribution to Eliashberg functions. 2560 if (dtset%prteliash /= 0) then 2561 if (abs(ediff) > EPHTK_WTOL) then 2562 sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 3) = sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 3) - gdw2 / ediff 2563 end if 2564 end if 2565 ! 2566 ! Accumulate DW for each T, add it to Sigma(e0) and Sigma(w) as well 2567 ! - (2 n_{q\nu} + 1) * gdw2 / (e_nk - e_mk) 2568 do it = 1, sigma%ntemp 2569 if (abs(ediff) > EPHTK_WTOL) then 2570 cfact = - weight_q * gdw2 * (two * nqnu_tlist(it) + one) / (ediff + sigma%ieta) 2571 else 2572 cfact = zero 2573 endif 2574 if (dtset%eph_stern /= 0 .and. ibsum == bsum_stop) then 2575 ! Add contribution due to the Sternheimer. ediff is absorbed in Sternheimer. 2576 cfact = cfact - weight_q * gdw2_stern * (two * nqnu_tlist(it) + one) 2577 cfact2 = - weight_q * gdw2_stern * (two * nqnu_tlist(it) + one) 2578 rfact = real(cfact2) 2579 sigma%dw_stern_vals(it, ib_k) = sigma%dw_stern_vals(it, ib_k) + rfact 2580 end if 2581 rfact = real(cfact) 2582 sigma%dw_vals(it, ib_k) = sigma%dw_vals(it, ib_k) + rfact 2583 sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + rfact 2584 if (sigma%nwr > 0) sigma%vals_wr(:, it, ib_k) = sigma%vals_wr(:, it, ib_k) + rfact 2585 end do 2586 2587 end do ! ib_k 2588 end do ! ibsum 2589 2590 end do ! nu 2591 2592 !if (nq < 1000 .or. (nq > 1000 .and. mod(iq_ibz_k, 200) == 0) .or. iq_ibz_k <= nprocs) then 2593 ii = iq_ibz_k - q_start 2594 if (ii <= 5 .or. mod(ii, 100) == 0) then 2595 write(msg,'(4(a,i0),a,f8.2)') " k-point [",my_ikcalc,"/",sigma%my_nkcalc, "] q-point [",iq_ibz_k,"/",nq,"]" 2596 call cwtime_report(msg, cpu, wall, gflops) 2597 end if 2598 end do ! iq_ibz_k 2599 2600 ABI_FREE(gkq0_atm) 2601 ABI_SFREE(stern_dw) 2602 call cwtime_report(" Debye-Waller", cpu_dw, wall_dw, gflops_dw, end_str=ch10) 2603 end if ! not %imag_only 2604 2605 if (dtset%prteliash /= 0) then 2606 ! Compute Eliashberg function. 2607 call cwtime(cpu, wall, gflops, "start", msg=sjoin(" Computing Eliashberg function with nomega: ", & 2608 itoa(sigma%phmesh_size))) 2609 2610 if (dtset%prteliash == 3) call xmpi_sum(sigma%a2few, sigma%pqb_comm%value, ierr) 2611 2612 ! Collect all terms on each node so that we can MPI-parallelize easily inside pqb_comm 2613 ! Note that: gf_nnuq does not include the q-weights from the integration. 2614 call xmpi_sum(sigma%gf_nnuq, sigma%pqb_comm%value, ierr) 2615 sigma%gfw_vals = zero 2616 2617 if (sigma%qint_method == 0 .or. sigma%symsigma == 0) then 2618 ! Compute Eliashberg function with gaussian method and ph_smear smearing. 2619 do iq_ibz_k=1,sigma%nqibz_k 2620 if (sigma%pqb_comm%skip(iq_ibz_k)) cycle ! MPI parallelism inside pqb_comm 2621 2622 ! Recompute phonons (cannot use sigma%ephwg in this case) 2623 call ifc%fourq(cryst, sigma%qibz_k(:,iq_ibz_k), phfrq, displ_cart) 2624 do nu=1,natom3 2625 dwargs = sigma%phmesh - phfrq(nu) 2626 dtw_weights(:, 1) = gaussian(dwargs, dtset%ph_smear) 2627 do ib_k=1,nbcalc_ks 2628 do ii=1,3 2629 sigma%gfw_vals(:, ii, ib_k) = sigma%gfw_vals(:, ii, ib_k) + & 2630 sigma%gf_nnuq(ib_k, nu, iq_ibz_k, ii) * dtw_weights(:, 1) * sigma%wtq_k(iq_ibz_k) 2631 end do 2632 end do 2633 end do 2634 end do 2635 2636 else 2637 ! Compute Eliashberg function with tetrahedron method. 2638 eminmax = [sigma%phmesh(1), sigma%phmesh(sigma%phmesh_size)] 2639 ABI_MALLOC(dt_tetra_weights, (sigma%phmesh_size, sigma%nqibz_k, 2)) 2640 do nu=1,natom3 2641 ! All procs compute weights. 2642 call sigma%ephwg%get_deltas_qibzk(nu, sigma%phmesh_size, eminmax, sigma%bcorr, dt_tetra_weights, & 2643 sigma%pqb_comm%value, with_qweights=.True.) 2644 2645 do iq_ibz_k=1,sigma%nqibz_k 2646 if (sigma%pqb_comm%skip(iq_ibz_k)) cycle ! MPI parallelism inside pqb_comm 2647 do ib_k=1,nbcalc_ks 2648 do ii=1,3 2649 sigma%gfw_vals(:, ii, ib_k) = sigma%gfw_vals(:, ii, ib_k) + & 2650 sigma%gf_nnuq(ib_k, nu, iq_ibz_k, ii) * dt_tetra_weights(:, iq_ibz_k, 1) 2651 end do 2652 end do 2653 end do 2654 end do 2655 ABI_FREE(dt_tetra_weights) 2656 end if 2657 2658 ! Collect final results. 2659 call xmpi_sum(sigma%gfw_vals, sigma%pqb_comm%value, ierr) 2660 call cwtime_report(" Eliashberg function", cpu, wall, gflops) 2661 end if 2662 2663 !ivals2 = [ignore_ks, ignore_ibsum_kq] 2664 !call xmpi_sum_master(ivals, master, sigma%pqb_comm%value) 2665 if (my_rank == master) then 2666 if (ignore_kq /= 0) write(std_out, "(a, 1x, i0)")" Number of ignored k+q points:", ignore_kq 2667 if (ignore_ibsum_kq /= 0) write(std_out, "(a, 1x, i0)")" Number of ignored (k+q, m) states:", ignore_ibsum_kq 2668 !if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then 2669 ! call wrtout(std_out, sjoin(" Total number of NSCF Sternheimer iterations:", itoa(tot_nlines_done))) 2670 !end if 2671 end if 2672 2673 ! Collect results inside pqb_comm and write results for this (k-point, spin) to NETCDF file. 2674 call sigma%gather_and_write(dtset, ebands, ikcalc, spin, sigma%pqb_comm%value) 2675 2676 ABI_SFREE(alpha_mrta) 2677 ABI_SFREE(root_bcalc) 2678 end do ! spin 2679 2680 ABI_FREE(kg_k) 2681 ABI_FREE(kg_kq) 2682 ABI_FREE(ylm_k) 2683 ABI_FREE(ylm_kq) 2684 ABI_FREE(ylmgr_kq) 2685 ABI_FREE(kpg_k) 2686 ABI_FREE(ffnlk) 2687 2688 !call abimem_report("end kcalc_loop", std_out) 2689 !call wrtout(std_out, sjoin("xmpi_count_requests", itoa(xmpi_count_requests))) 2690 2691 call cwtime_report(" One ikcalc k-point", cpu_ks, wall_ks, gflops_ks) 2692 end do ! ikcalc 2693 2694 call cwtime_report(" Sigma_eph full calculation", cpu_all, wall_all, gflops_all, end_str=ch10) 2695 2696 ! Free memory 2697 ABI_FREE(ihave_ikibz_spin) 2698 ABI_FREE(grad_berry) 2699 ABI_FREE(vtrial) 2700 ABI_FREE(work) 2701 ABI_FREE(ph1d) 2702 ABI_FREE(vlocal) 2703 ABI_FREE(nqnu_tlist) 2704 ABI_FREE(displ_cart) 2705 ABI_FREE(displ_red) 2706 ABI_FREE(tpp_red) 2707 ABI_SFREE(cfact_wr) 2708 ABI_SFREE(dwargs) 2709 ABI_SFREE(dtw_weights) 2710 ABI_SFREE(delta_e_minus_emkq) 2711 ABI_FREE(gbound_kq) 2712 ABI_FREE(osc_gbound_q) 2713 ABI_FREE(ibzspin_2ikcalc) 2714 ABI_FREE(gaussw_qnu) 2715 ABI_SFREE(vcar_ibz) 2716 2717 call gs_hamkq%free() 2718 call wfd%free() 2719 call pawcprj_free(cwaveprj0) 2720 ABI_FREE(cwaveprj0) 2721 call pawcprj_free(cwaveprj) 2722 ABI_FREE(cwaveprj) 2723 call phstore%free() 2724 call u1c%free() 2725 call sigma%free() 2726 2727 ! This to make sure that the parallel output of SIGEPH is completed 2728 call xmpi_barrier(comm) 2729 call cwtime_report(" sigmaph: MPI barrier before returning.", cpu_all, wall_all, gflops_all, end_str=ch10, comm=comm) 2730 2731 end subroutine sigmaph
m_sigmaph/sigmaph_compare [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_compare
FUNCTION
Compare the headers of two sigmaph_t instances
INPUTS
SOURCE
4173 subroutine sigmaph_compare(self, other) 4174 4175 !Arguments ------------------------------------ 4176 class(sigmaph_t),intent(in) :: self, other 4177 4178 !Local variables------------------------------- 4179 integer :: ierr 4180 4181 ! ************************************************************************* 4182 ierr = 0 4183 4184 ABI_CHECK_NOSTOP(self%nkcalc == other%nkcalc, "Difference found in nkcalc.", ierr) 4185 ABI_CHECK_NOSTOP(self%max_nbcalc == other%max_nbcalc, "Difference found in max_nbcalc.", ierr) 4186 ABI_CHECK_NOSTOP(self%nsppol == other%nsppol, "Difference found in nsppol.", ierr) 4187 ABI_CHECK_NOSTOP(self%ntemp == other%ntemp, "Difference found in ntemp.", ierr) 4188 ABI_CHECK_NOSTOP(self%nqibz == other%nqibz, "Difference found in nqibz.", ierr) 4189 ABI_CHECK_NOSTOP(self%nqbz == other%nqbz, "Difference found in nqbz.", ierr) 4190 4191 ! ====================================================== 4192 ! Read data that does not depend on the (kpt, spin) loop. 4193 ! ====================================================== 4194 ABI_CHECK_NOSTOP(self%symsigma == other%symsigma, "Different value found for symsigma.", ierr) 4195 ABI_CHECK_NOSTOP(self%nbsum == other%nbsum, "Different value found for nbsum.", ierr) 4196 ABI_CHECK_NOSTOP(self%bsum_start == other%bsum_start, "Different value found for bsum_start.", ierr) 4197 ABI_CHECK_NOSTOP(self%bsum_stop == other%bsum_stop, "Different value found for bsum_stop.", ierr) 4198 ABI_CHECK_NOSTOP(self%qint_method == other%qint_method, "Different value found for qint_method", ierr) 4199 !ABI_CHECK_NOSTOP(self%frohl_model == other%frohl_model, "Different value found for frohl_model.", ierr) 4200 ABI_CHECK_NOSTOP(self%imag_only .eqv. other%imag_only, "Difference found in imag_only", ierr) 4201 ABI_CHECK_NOSTOP(self%wr_step == other%wr_step, "Different value found for wr_step", ierr) 4202 ABI_CHECK_NOSTOP(self%ieta == other%ieta, "Different value found for zcut.", ierr) 4203 4204 ABI_CHECK_NOSTOP(all(self%ngqpt == other%ngqpt), "Different value found for ngqpt", ierr) 4205 ABI_CHECK_NOSTOP(all(self%bstart_ks == other%bstart_ks), "Different value found for bstart_ks", ierr) 4206 ABI_CHECK_NOSTOP(all(self%nbcalc_ks == other%nbcalc_ks), "Different value found for bstop_ks", ierr) 4207 ABI_CHECK_NOSTOP(all(self%kcalc == other%kcalc), "Different value found for kcalc", ierr) 4208 ABI_CHECK_NOSTOP(all(self%kcalc2ibz == other%kcalc2ibz), "Different value found for kcalc2ibz", ierr) 4209 ABI_CHECK_NOSTOP(all(self%kTmesh == other%kTmesh), "Different value found for kTmesh", ierr) 4210 ABI_CHECK_NOSTOP(all(self%mu_e == other%mu_e), "Different value found for mu_e", ierr) 4211 4212 ABI_CHECK(ierr == 0, "Fatal error in sigmaph_compare, see previous messages!") 4213 4214 end subroutine sigmaph_compare
m_sigmaph/sigmaph_free [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_free
FUNCTION
Deallocate dynamic memory
INPUTS
SOURCE
4228 subroutine sigmaph_free(self) 4229 4230 !Arguments ------------------------------------ 4231 class(sigmaph_t),intent(inout) :: self 4232 4233 !Local variables------------------------------- 4234 !integer :: ii, jj 4235 4236 ! ************************************************************************* 4237 4238 ! integer 4239 ABI_SFREE(self%bstart_ks) 4240 ABI_SFREE(self%bstop_ks) 4241 ABI_SFREE(self%nbcalc_ks) 4242 ABI_SFREE(self%kcalc2ibz) 4243 ABI_SFREE(self%my_ikcalc) 4244 ABI_SFREE(self%my_spins) 4245 ABI_SFREE(self%myq2ibz_k) 4246 ABI_SFREE(self%itreat_qibz) 4247 ABI_SFREE(self%my_pinfo) 4248 ABI_SFREE(self%pert_table) 4249 ABI_SFREE(self%phmodes_skip) 4250 ABI_SFREE(self%ind_qbz2ibz) 4251 ABI_SFREE(self%indkk_kq) 4252 ABI_SFREE(self%ind_q2dvdb_k) 4253 ABI_SFREE(self%ind_ibzk2ibz) 4254 ABI_SFREE(self%qibz2dvdb) 4255 ABI_SFREE(self%lgk_sym2glob) 4256 ABI_SFREE(self%nbsum_rank) 4257 4258 ! real 4259 ABI_SFREE(self%kcalc) 4260 ABI_SFREE(self%kTmesh) 4261 ABI_SFREE(self%mu_e) 4262 ABI_SFREE(self%e0vals) 4263 ABI_SFREE(self%vcar_calc) 4264 ABI_SFREE(self%linewidth_mrta) 4265 ABI_SFREE(self%cweights) 4266 ABI_SFREE(self%deltaw_pm) 4267 ABI_SFREE(self%wrmesh_b) 4268 ABI_SFREE(self%qvers_cart) 4269 ABI_SFREE(self%angwgth) 4270 ABI_SFREE(self%frohl_deltas_sphcorr) 4271 ABI_SFREE(self%qp_done) 4272 ABI_SFREE(self%qbz) 4273 ABI_SFREE(self%qibz) 4274 ABI_SFREE(self%wtq) 4275 ABI_SFREE(self%qibz_k) 4276 ABI_SFREE(self%wtq_k) 4277 ABI_SFREE(self%srate) 4278 ABI_SFREE(self%phmesh) 4279 ABI_SFREE(self%gf_nnuq) 4280 ABI_SFREE(self%scratew) 4281 4282 ! complex 4283 ABI_SFREE(self%vals_e0ks) 4284 ABI_SFREE(self%fan_vals) 4285 ABI_SFREE(self%fan_stern_vals) 4286 ABI_SFREE(self%dvals_de0ks) 4287 ABI_SFREE(self%dw_vals) 4288 ABI_SFREE(self%dw_stern_vals) 4289 ABI_SFREE(self%vals_wr) 4290 ABI_SFREE(self%gfw_vals) 4291 ABI_SFREE(self%a2f_emesh) 4292 ABI_SFREE(self%a2few) 4293 4294 ! datatypes. 4295 if (allocated(self%degtab)) then 4296 call degtab_array_free(self%degtab) 4297 ABI_FREE(self%degtab) 4298 end if 4299 4300 call self%ephwg%free() 4301 call self%eph_doublegrid%free() 4302 4303 ! Deallocate MPI communicators 4304 call self%pert_comm%free() 4305 call self%qpt_comm%free() 4306 call self%bsum_comm%free() 4307 call self%qb_comm%free() 4308 call self%kcalc_comm%free() 4309 call self%spin_comm%free() 4310 call self%pqb_comm%free() 4311 call self%ncwrite_comm%free() 4312 4313 ! Close netcdf file. 4314 if (self%ncid /= nctk_noid) then 4315 NCF_CHECK(nf90_close(self%ncid)) 4316 end if 4317 4318 end subroutine sigmaph_free
m_sigmaph/sigmaph_gather_and_write [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_gather_and_write
FUNCTION
Gather results from the MPI processes. Then master rank does: 1. Computes QP energies, Z factor and spectral function (if required). 2. Saves results to file.
INPUTS
ebands<ebands_t>=KS band energies. ikcalc=Index of the computed k-point spin=Spin index. prtvol= Verbosity level comm=MPI communicator.
SOURCE
4840 subroutine sigmaph_gather_and_write(self, dtset, ebands, ikcalc, spin, comm) 4841 4842 !Arguments ------------------------------------ 4843 type(dataset_type),intent(in) :: dtset 4844 integer,intent(in) :: ikcalc, spin, comm 4845 class(sigmaph_t),target,intent(inout) :: self 4846 type(ebands_t),intent(in) :: ebands 4847 4848 !Local variables------------------------------- 4849 integer,parameter :: master = 0, max_ntemp = 50 4850 integer :: ideg,ib,it,ii,iw,nstates,ierr,my_rank,band_ks,ik_ibz,ibc,ib_val,ib_cond,jj 4851 integer :: nq_ibzk_eff, nelem, imyq, iq_ibz_k, sr_ncid 4852 logical :: iwrite 4853 real(dp) :: ravg,kse,kse_prev,dw,fan0,ks_gap,kse_val,kse_cond,qpe_oms,qpe_oms_val,qpe_oms_cond 4854 real(dp) :: cpu, wall, gflops, invsig2fmts, tau, ravg2 4855 complex(dpc) :: sig0c,zc,qpe,qpe_prev,qpe_val,qpe_cond,cavg1,cavg2,cavg3,cavg4 4856 !character(len=5000) :: msg 4857 integer :: grp_ncid, ncerr 4858 !arrays 4859 integer, allocatable :: recvcounts(:), displs(:), nq_rank(:), kq_symtab(:,:), my_kq_symtab(:,:) 4860 integer, ABI_CONTIGUOUS pointer :: bids(:) 4861 real(dp) :: qp_gaps(self%ntemp),qpoms_gaps(self%ntemp) 4862 real(dp),allocatable :: aw(:,:,:), a2few_avg(:,:), gather_srate(:,:,:,:), grp_srate(:,:,:,:) 4863 real(dp) :: ks_enes(self%max_nbcalc), ze0_vals(self%ntemp, self%max_nbcalc) 4864 real(dp) :: gfw_avg(self%phmesh_size, 3) 4865 complex(dpc) :: qpoms_enes(self%ntemp, self%max_nbcalc),qp_enes(self%ntemp, self%max_nbcalc) 4866 4867 ! ************************************************************************* 4868 4869 ! Could use non-blocking communications and double buffer technique to reduce synchronisation cost... 4870 call cwtime(cpu, wall, gflops, "start", msg=" Gathering results. Waiting for other MPI processes...") 4871 4872 ! Here comm corresponds to sigma%pqb_comm%value 4873 my_rank = xmpi_comm_rank(comm) 4874 iwrite = self%ncwrite_comm%value /= xmpi_comm_null 4875 call xmpi_sum_master(self%vals_e0ks, master, comm, ierr) 4876 call xmpi_sum_master(self%fan_vals, master, comm, ierr) 4877 call xmpi_sum_master(self%fan_stern_vals, master, comm, ierr) 4878 call xmpi_sum_master(self%dvals_de0ks, master, comm, ierr) 4879 call xmpi_sum_master(self%dw_vals, master, comm, ierr) 4880 call xmpi_sum_master(self%dw_stern_vals, master, comm, ierr) 4881 if (self%nwr > 0) call xmpi_sum_master(self%vals_wr, master, comm, ierr) 4882 if (self%mrta > 0) call xmpi_sum_master(self%linewidth_mrta, master, comm, ierr) 4883 if (dtset%eph_prtscratew == 1) then 4884 ! Collect spectral decomposition of scattering rates, multiply by two since so far we have stored Imag(Sigma) (ph_w) 4885 call xmpi_sum_master(self%scratew, master, comm, ierr) 4886 self%scratew = two * self%scratew 4887 end if 4888 4889 if (dtset%ibte_prep > 0) then 4890 ! FIXME: Handle kpoint/spin parallelism. 4891 ! (%bsum_start:%bsum_stop, %nbcalc_ks(ikcalc, spin), %ntemp, %nqibz_k)) 4892 ! Sum over phonon modes 4893 call xmpi_sum(self%srate, self%pert_comm%value, ierr) 4894 !call xmpi_sum(self%srate, self%pb_comm%value), ierr) 4895 4896 ! Use gatherv to collect data and tables on the IO proc i.e. the master proc in qpt_comm. 4897 ! Only the number of q-points changes across the qpt-procs and this is the last dimension. 4898 ! nq_ibzk_eff is the total number of effective q-points in the IBZ(k). 4899 ABI_CALLOC(nq_rank, (self%qpt_comm%nproc)) 4900 call xmpi_allgather(self%my_nqibz_k, nq_rank, self%qpt_comm%value, ierr) 4901 4902 nq_ibzk_eff = sum(nq_rank) 4903 nelem = self%nbsum * self%nbcalc_ks(ikcalc, spin) * self%ntemp 4904 !call self%qpt_comm%prep_gatherv(nelem, nq_rank, recvcounts, displs) 4905 ABI_MALLOC(recvcounts, (self%qpt_comm%nproc)) 4906 ABI_MALLOC(displs, (self%qpt_comm%nproc)) 4907 4908 recvcounts = nelem * nq_rank(:) 4909 displs(1) = 0 4910 do ii=2,self%qpt_comm%nproc 4911 displs(ii) = sum(nq_rank(1:ii-1)) * nelem 4912 end do 4913 4914 ABI_MALLOC(gather_srate, (self%bsum_start:self%bsum_stop, self%nbcalc_ks(ikcalc, spin), self%ntemp, nq_ibzk_eff)) 4915 4916 call xmpi_gatherv(self%srate, nelem * self%my_nqibz_k, gather_srate, recvcounts, displs, master, self%qpt_comm%value, ierr) 4917 !ABI_CHECK(all(abs(gather_srate - self%srate) < tol12), "This only if nproc == 1") 4918 !ABI_CHECK(nq_ibzk_eff == self%my_nqibz_k, "This only if nproc == 1") 4919 4920 if (.not. iwrite) then 4921 ABI_FREE(gather_srate) 4922 end if 4923 4924 ABI_MALLOC(my_kq_symtab, (6, self%my_nqibz_k)) 4925 do imyq=1,self%my_nqibz_k 4926 iq_ibz_k = self%myq2ibz_k(imyq) 4927 my_kq_symtab(:, imyq) = self%indkk_kq(:, iq_ibz_k) 4928 end do 4929 4930 !call self%qpt_comm%prep_gatherv(nelem, nq_rank, recvcounts, displs) 4931 displs(1) = 0; nelem = 6 4932 do ii=2,self%qpt_comm%nproc 4933 displs(ii) = sum(nq_rank(1:ii-1)) * nelem 4934 end do 4935 recvcounts = nq_rank * nelem 4936 4937 ABI_MALLOC(kq_symtab, (nelem, nq_ibzk_eff)) 4938 call xmpi_gatherv(my_kq_symtab, nelem * self%my_nqibz_k, kq_symtab, recvcounts, displs, master, self%qpt_comm%value, ierr) 4939 !ABI_CHECK(all(abs(kq_symtab - my_kq_symtab) < tol12), "kq_symtab") 4940 4941 if (.not. iwrite) then 4942 ABI_FREE(kq_symtab) 4943 end if 4944 4945 ABI_FREE(nq_rank) 4946 ABI_FREE(my_kq_symtab) 4947 ABI_FREE(recvcounts) 4948 ABI_FREE(displs) 4949 end if 4950 4951 call cwtime_report(" Sigma_nk gather", cpu, wall, gflops, comm=comm) 4952 4953 ! Only procs inside ncwrite_comm perform IO (ab_out and ncid) 4954 if (.not. iwrite) return 4955 4956 ik_ibz = self%kcalc2ibz(ikcalc, 1) 4957 4958 if (self%a2f_ne > 0) then 4959 ABI_MALLOC(a2few_avg, (self%a2f_ne, self%phmesh_size)) 4960 end if 4961 4962 if (self%symsigma == +1) then 4963 ! Average self-energy matrix elements in the degenerate subspace. 4964 do ideg=1,size(self%degtab(ikcalc, spin)%bids) 4965 bids => self%degtab(ikcalc, spin)%bids(ideg)%vals 4966 nstates = size(bids) 4967 4968 ! Symmetrize Eliashberg function 4969 if (dtset%prteliash > 0) then 4970 gfw_avg = sum(self%gfw_vals(:, :, bids(:)), dim=3) / nstates 4971 do ii=1,nstates 4972 self%gfw_vals(:, :, bids(ii)) = gfw_avg 4973 end do 4974 if (self%a2f_ne > 0) then 4975 a2few_avg = sum(self%a2few(:, :, bids(:)), dim=3) / nstates 4976 do ii=1,nstates 4977 self%a2few(:, :, bids(ii)) = a2few_avg 4978 end do 4979 end if 4980 end if 4981 4982 do it=1,self%ntemp 4983 ! Average QP(T) and Z(T). 4984 cavg1 = sum(self%vals_e0ks(it, bids(:))) / nstates 4985 cavg2 = sum(self%dvals_de0ks(it, bids(:))) / nstates 4986 cavg3 = sum(self%fan_vals(it, bids(:))) / nstates 4987 cavg4 = sum(self%fan_stern_vals(it, bids(:))) / nstates 4988 ravg = sum(self%dw_vals(it, bids(:))) / nstates 4989 ravg2 = sum(self%dw_stern_vals(it, bids(:))) / nstates 4990 do ii=1,nstates 4991 self%vals_e0ks(it, bids(ii)) = cavg1 4992 self%dvals_de0ks(it, bids(ii)) = cavg2 4993 self%fan_vals(it, bids(ii)) = cavg3 4994 self%fan_stern_vals(it, bids(ii)) = cavg4 4995 self%dw_vals(it, bids(ii)) = ravg 4996 self%dw_stern_vals(it, bids(ii)) = ravg2 4997 end do 4998 4999 ! Average TAU_MRTA 5000 if (self%mrta > 0) then 5001 ravg = sum(self%linewidth_mrta(it, bids(:))) / nstates 5002 do ii=1,nstates 5003 self%linewidth_mrta(it, bids(ii)) = ravg 5004 end do 5005 end if 5006 5007 if (self%nwr > 0) then 5008 ! Average Sigma(omega, T) 5009 do iw=1,self%nwr 5010 cavg1 = sum(self%vals_wr(iw, it, bids(:))) / nstates 5011 do ii=1,nstates 5012 self%vals_wr(iw, it, bids(ii)) = cavg1 5013 end do 5014 end do 5015 end if 5016 end do ! it 5017 end do ! ideg 5018 end if ! symsigma == +1 5019 5020 ABI_SFREE(a2few_avg) 5021 5022 ! Compute QP energies and Gaps (Note that I'm assuming a non-magnetic semiconductor!) 5023 ib_val = nint(ebands%nelect / (two / ebands%nspinor)); ib_cond = ib_val + 1 5024 kse_val = huge(one) * tol6; kse_cond = huge(one) * tol6 5025 qp_enes = huge(one) * tol6; qpoms_enes = huge(one) * tol6 5026 ks_enes = huge(one) * tol6; ze0_vals = huge(one) * tol6 5027 ks_gap = -one; qpoms_gaps = -one; qp_gaps = -one 5028 5029 ! Write legend. 5030 if (ikcalc == 1 .and. spin == 1) then 5031 write(ab_out,"(a)")repeat("=", 80) 5032 write(ab_out,"(a)")" Final results in eV." 5033 write(ab_out,"(a)")" Notations:" 5034 write(ab_out,"(a)")" eKS: Kohn-Sham energy. eQP: quasi-particle energy." 5035 write(ab_out,"(a)")" eQP - eKS: Difference between the QP and the KS energy." 5036 write(ab_out,"(a)")" SE1(eKS): Real part of the self-energy computed at the KS energy, SE2 for imaginary part." 5037 write(ab_out,"(a)")" Z(eKS): Renormalization factor." 5038 write(ab_out,"(a)")" FAN: Real part of the Fan term at eKS. DW: Debye-Waller term." 5039 write(ab_out,"(a)")" DeKS: KS energy difference between this band and band-1, DeQP same meaning but for eQP." 5040 write(ab_out,"(a)")" OTMS: On-the-mass-shell approximation with eQP ~= eKS + Sigma(omega=eKS)" 5041 write(ab_out,"(a)")" TAU(eKS): Lifetime in femtoseconds computed at the KS energy." 5042 write(ab_out,"(a)")" mu_e: Fermi level for given (T, nelect)" 5043 write(ab_out,"(a)")" " 5044 write(ab_out,"(a)")" " 5045 end if 5046 5047 do it=1,self%ntemp 5048 5049 ! Write header. 5050 if (it <= max_ntemp) then 5051 if (self%nsppol == 1) then 5052 write(ab_out,"(3a,f6.1,a,f8.3)") & 5053 "K-point: ", trim(ktoa(self%kcalc(:,ikcalc))), ", T: ", self%kTmesh(it) / kb_HaK, & 5054 " [K], mu_e: ", self%mu_e(it) * Ha_eV 5055 else 5056 write(ab_out,"(3a,i1,a,f6.1,a,f8.3)") & 5057 "K-point: ", trim(ktoa(self%kcalc(:,ikcalc))), ", spin: ", spin, ", T: ",self%kTmesh(it) / kb_HaK, & 5058 " [K], mu_e: ", self%mu_e(it) * Ha_eV 5059 end if 5060 if (self%imag_only) then 5061 ! TODO: Add tau^SERTA, tau^MRTA, and v tau, ps instead of fmts? 5062 write(ab_out,"(a)")" B eKS SE2(eKS) TAU(eKS) DeKS" 5063 else 5064 write(ab_out,"(a)")" B eKS eQP eQP-eKS SE1(eKS) SE2(eKS) Z(eKS) FAN(eKS) DW DeKS DeQP" 5065 end if 5066 end if 5067 5068 do ibc=1,self%nbcalc_ks(ikcalc, spin) 5069 band_ks = self%bstart_ks(ikcalc, spin) + ibc - 1 5070 kse = ebands%eig(band_ks, ik_ibz, spin) 5071 ks_enes(ibc) = kse 5072 sig0c = self%vals_e0ks(it, ibc) 5073 dw = self%dw_vals(it, ibc) 5074 fan0 = real(sig0c) - dw 5075 ! Compute QP energies with On-the-Mass-Shell approximation and first renormalization i.e. Z(eKS) 5076 ! TODO: Note that here I use the full Sigma including the imaginary part 5077 !zc = one / (one - self%dvals_de0ks(it, ibc)) 5078 zc = one / (one - real(self%dvals_de0ks(it, ibc))) 5079 ze0_vals(it, ibc) = real(zc) 5080 qpe = kse + real(zc) * real(sig0c) 5081 qpe_oms = kse + real(sig0c) 5082 if (ibc == 1) then 5083 kse_prev = kse; qpe_prev = qpe 5084 end if 5085 if (band_ks == ib_val) then 5086 kse_val = kse; qpe_val = qpe; qpe_oms_val = qpe_oms 5087 end if 5088 if (band_ks == ib_cond) then 5089 kse_cond = kse; qpe_cond = qpe; qpe_oms_cond = qpe_oms 5090 end if 5091 5092 if (it <= max_ntemp) then 5093 if (self%imag_only) then 5094 ! 1/tau = 2 Imag(Sigma) 5095 invsig2fmts = Time_Sec * 1e+15 / two 5096 tau = 999999.0_dp 5097 if (abs(aimag(sig0c)) > tol16) tau = invsig2fmts / abs(aimag(sig0c)) 5098 tau = min(tau, 999999.0_dp) 5099 write(ab_out, "(i4,2(f8.3,1x),f8.1,1x,f8.3)") & 5100 band_ks, kse * Ha_eV, aimag(sig0c) * Ha_eV, tau, (kse - kse_prev) * Ha_eV 5101 else 5102 write(ab_out, "(i4, 10(f8.3,1x))") & 5103 band_ks, kse * Ha_eV, real(qpe) * Ha_eV, (real(qpe) - kse) * Ha_eV, & 5104 real(sig0c) * Ha_eV, aimag(sig0c) * Ha_eV, real(zc), & 5105 fan0 * Ha_eV, dw * Ha_eV, (kse - kse_prev) * Ha_eV, real(qpe - qpe_prev) * Ha_eV 5106 end if 5107 end if 5108 5109 if (ibc > 1) then 5110 kse_prev = kse; qpe_prev = qpe 5111 end if 5112 qpoms_enes(it, ibc) = qpe_oms 5113 qp_enes(it, ibc) = qpe 5114 if (kse_val /= huge(one) * tol6 .and. kse_cond /= huge(one) * tol6) then 5115 ! We have enough states to compute the gap. 5116 if (it == 1) ks_gap = kse_cond - kse_val 5117 qpoms_gaps(it) = qpe_oms_cond - qpe_oms_val 5118 qp_gaps(it) = real(qpe_cond - qpe_val) 5119 end if 5120 end do ! ibc 5121 5122 ! Print KS and QP gaps. 5123 if (it <= max_ntemp) then 5124 if (.not. self%imag_only) then 5125 if (kse_val /= huge(one) * tol6 .and. kse_cond /= huge(one) * tol6) then 5126 write(ab_out, "(a)")" " 5127 write(ab_out, "(a,f8.3,1x,2(a,i0),a)")" KS gap: ",ks_gap * Ha_eV, & 5128 "(assuming bval:", ib_val, " ==> bcond:", ib_cond, ")" 5129 write(ab_out, "(2(a,f8.3),a)")" QP gap: ",qp_gaps(it) * Ha_eV," (OTMS: ",qpoms_gaps(it) * Ha_eV, ")" 5130 write(ab_out, "(2(a,f8.3),a)")" QP_gap - KS_gap: ",(qp_gaps(it) - ks_gap) * Ha_eV,& 5131 " (OTMS: ",(qpoms_gaps(it) - ks_gap) * Ha_eV, ")" 5132 write(ab_out, "(a)")" " 5133 end if 5134 else 5135 if (kse_val /= huge(one) * tol6 .and. kse_cond /= huge(one) * tol6) then 5136 write(ab_out, "(a)")" " 5137 write(ab_out, "(a,f8.3,1x,2(a,i0),a)")" KS gap: ",ks_gap * Ha_eV, "(assuming bval:",ib_val," ==> bcond:",ib_cond,")" 5138 write(ab_out, "(a)")" " 5139 end if 5140 end if 5141 5142 write(ab_out, "(a)")repeat("=", 92) 5143 end if 5144 5145 end do ! it 5146 5147 if (self%ntemp > max_ntemp .and. (ikcalc == 1 .and. spin == 1)) then 5148 write(ab_out, "(a,i0,a)")" No more than ", max_ntemp, " temperatures are written to the main output file." 5149 write(ab_out, "(2a)")" Please use SIGEPH.nc file and AbiPy to analyze the results.",ch10 5150 end if 5151 5152 if (dtset%prtvol > 0 .and. (ikcalc == 1 .and. spin == 1)) then 5153 if (allocated(self%gfw_vals)) then 5154 write(ab_out, "(2a)")" omega and Eliashberg function gf_{nk}(omega) for testing purposes:" 5155 iw = (self%phmesh_size / 2) 5156 do ib=1,min(self%nbcalc_ks(ikcalc, spin), 5) 5157 band_ks = self%bstart_ks(ikcalc, spin) + ib - 1 5158 write(ab_out, "(a, i0)")"For band:", band_ks 5159 do jj=0,1 5160 write(ab_out, "(4(f8.3,2x))")self%phmesh(iw+jj), (self%gfw_vals(iw+jj, ii, ib), ii=1,3) 5161 end do 5162 end do 5163 write(ab_out, "(a)")ch10 5164 end if 5165 5166 if (self%nwr >= 3) then 5167 write(ab_out, "(2a)")ch10," omega and Sigma_nk(omega, T=1) in eV for testing purposes:" 5168 it = 1; iw = (self%nwr / 2) 5169 do ib=1,min(self%nbcalc_ks(ikcalc, spin), 5) 5170 band_ks = self%bstart_ks(ikcalc, spin) + ib - 1 5171 write(ab_out, "(a, i0)")"For band:", band_ks 5172 do ii=0,1 5173 write(ab_out, "(3(f8.3,2x))")self%wrmesh_b(iw+ii, ib) * Ha_eV, self%vals_wr(iw+ii, it, ib) * Ha_eV 5174 end do 5175 end do 5176 write(ab_out, "(a)")ch10 5177 end if 5178 end if 5179 5180 call flush_unit(ab_out) 5181 5182 ! Write self-energy matrix elements for this (kpt, spin) 5183 ! NB: Only master writes 5184 ! (use, intrinsic :: iso_c_binding to associate a real pointer to complex data because netcdf does not support complex types). 5185 ! Well, cannot use c_loc with gcc <= 4.8 due to internal compiler error so use c2r and stack memory. 5186 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "vals_e0ks"), c2r(self%vals_e0ks), start=[1,1,1,ikcalc,spin])) 5187 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "vals_e0ks"), c2r(self%vals_e0ks), start=[1,1,1,ikcalc,spin])) 5188 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "fan_vals"), c2r(self%fan_vals), start=[1,1,1,ikcalc,spin])) 5189 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "fan_stern_vals"), c2r(self%fan_stern_vals), start=[1,1,1,ikcalc,spin])) 5190 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "dvals_de0ks"), c2r(self%dvals_de0ks), start=[1,1,1,ikcalc,spin])) 5191 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "dw_vals"), self%dw_vals, start=[1,1,ikcalc,spin])) 5192 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "dw_stern_vals"), self%dw_stern_vals, start=[1,1,ikcalc,spin])) 5193 5194 ! Dump QP energies and gaps for this (kpt, spin) 5195 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qpoms_enes"), c2r(qpoms_enes), start=[1,1,1,ikcalc,spin])) 5196 5197 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qp_enes"), c2r(qp_enes), start=[1,1,1,ikcalc,spin])) 5198 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "ze0_vals"), ze0_vals, start=[1,1,ikcalc,spin])) 5199 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "ks_enes"), ks_enes, start=[1,ikcalc,spin])) 5200 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "ks_gaps"), ks_gap, start=[ikcalc,spin])) 5201 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qpoms_gaps"), qpoms_gaps, start=[1,ikcalc,spin])) 5202 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qp_gaps"), qp_gaps, start=[1,ikcalc,spin])) 5203 5204 if (self%mrta > 0) then 5205 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "linewidth_mrta"), self%linewidth_mrta, start=[1,1,ikcalc,spin])) 5206 end if 5207 5208 if (dtset%eph_prtscratew == 1) then 5209 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "scratew"), self%scratew, start=[1,1,1,1,ikcalc,spin])) 5210 end if 5211 5212 !if (self%frohl_model == 1 .and. self%imag_only) then 5213 ! ncerr = nf90_put_var(self%ncid, nctk_idname(self%ncid, "frohl_deltas_sphcorr"), & 5214 ! self%frohl_deltas_sphcorr, start=[1,1,1,1, ikcalc, spin]) 5215 ! NCF_CHECK(ncerr) 5216 !end if 5217 5218 ! Write frequency dependent data. 5219 if (self%nwr > 0) then 5220 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "wrmesh_b"), self%wrmesh_b, start=[1,1,ikcalc,spin])) 5221 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "vals_wr"), c2r(self%vals_wr), start=[1,1,1,1,ikcalc,spin])) 5222 5223 ! Compute spectral function. 5224 ! A = -1/pi [Im Sigma(ww)] / ([ww - ee - Re Sigma(ww)] ** 2 + Im Sigma(ww) ** 2]) 5225 ABI_MALLOC(aw, (self%nwr, self%ntemp, self%max_nbcalc)) 5226 do ib=1,self%nbcalc_ks(ikcalc, spin) 5227 band_ks = self%bstart_ks(ikcalc, spin) + ib - 1 5228 kse = ebands%eig(band_ks, ik_ibz, spin) 5229 do it=1,self%ntemp 5230 aw(:, it, ib) = -piinv * aimag(self%vals_wr(:, it, ib)) / & 5231 ((self%wrmesh_b(:, ib) - kse - real(self%vals_wr(:, it, ib))) ** 2 + aimag(self%vals_wr(:, it, ib)) ** 2) 5232 end do 5233 end do 5234 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "spfunc_wr"), aw, start=[1, 1, 1, ikcalc, spin])) 5235 ABI_FREE(aw) 5236 end if 5237 5238 ! Write Eliashberg functions 5239 if (allocated(self%gfw_vals)) then 5240 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "gfw_vals"), self%gfw_vals, start=[1, 1, 1, ikcalc, spin])) 5241 end if 5242 if (allocated(self%a2few)) then 5243 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "a2few"), self%a2few, start=[1, 1, 1, ikcalc, spin])) 5244 end if 5245 5246 if (dtset%ibte_prep > 0) then 5247 call wrtout(std_out, " Writing scattering matrix elements to disk...") 5248 ! Get ncid of group used to store scattering rate (ragged array implemented with netcdf groups). 5249 ! FIXME: Unfortunately, this algo cannot be used if parallelism over kcalc/spin is on since 5250 ! we have to change the metadata at runtime. 5251 sr_ncid = self%ncid 5252 NCF_CHECK(nf90_inq_ncid(sr_ncid, strcat("srate_k", itoa(ikcalc), "_s", itoa(spin)), grp_ncid)) 5253 5254 ! Define dimensions and arrays inside group at runtime 5255 ncerr = nctk_def_dims(grp_ncid, [ & 5256 nctkdim_t("lgk_nsym", self%lgk_nsym), & 5257 nctkdim_t("nbcalc", self%nbcalc_ks(ikcalc, spin)), & 5258 nctkdim_t("nbsum", self%bsum_stop - self%bsum_start + 1), & 5259 nctkdim_t("nq_ibzk_eff", nq_ibzk_eff) & 5260 ], defmode=.True.) 5261 NCF_CHECK(ncerr) 5262 5263 ncerr = nctk_def_arrays(grp_ncid, [ & 5264 nctkarr_t("lgk_sym2glob", "int", "two, lgk_nsym"), & 5265 nctkarr_t("kq_symtab", "int", "six, nq_ibzk_eff"), & 5266 nctkarr_t("srate", "dp", "nq_ibzk_eff, nbsum, nbcalc, ntemp") & 5267 ]) 5268 NCF_CHECK(ncerr) 5269 5270 ! Write data. 5271 NCF_CHECK(nctk_set_datamode(sr_ncid)) 5272 NCF_CHECK(nf90_put_var(grp_ncid, nctk_idname(grp_ncid, "lgk_sym2glob"), self%lgk_sym2glob)) 5273 NCF_CHECK(nf90_put_var(grp_ncid, nctk_idname(grp_ncid, "kq_symtab"), kq_symtab)) 5274 ABI_FREE(kq_symtab) 5275 5276 ! Move q-points to first dimensions before writing. 5277 ABI_MALLOC(grp_srate, (nq_ibzk_eff, self%bsum_start:self%bsum_stop, self%nbcalc_ks(ikcalc, spin), self%ntemp)) 5278 do ii=1,nq_ibzk_eff 5279 grp_srate(ii,:,:,:) = gather_srate(:,:,:,ii) 5280 end do 5281 NCF_CHECK(nf90_put_var(grp_ncid, nctk_idname(grp_ncid, "srate"), grp_srate)) 5282 ABI_FREE(gather_srate) 5283 ABI_FREE(grp_srate) 5284 end if 5285 5286 ! Write restart flag 5287 self%qp_done(ikcalc, spin) = 1 5288 NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qp_done"), 1, start=[ikcalc, spin])) 5289 5290 ! Dump the cache to file. This is necessary to ensure we can restart. 5291 NCF_CHECK(nf90_sync(self%ncid)) 5292 5293 call cwtime_report(" Sigma_nk netcdf output", cpu, wall, gflops) 5294 5295 end subroutine sigmaph_gather_and_write
m_sigmaph/sigmaph_get_all_qweights [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_get_all_qweights
FUNCTION
Compute all the weights for q-space integration using the tetrahedron method
INPUTS
cryst<crystal_t>=Crystalline structure ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) spin: Spin index ikcalc: Index of the self-energy k-point in the kcalc array. comm: MPI communicator
OUTPUT
SOURCE
5431 subroutine sigmaph_get_all_qweights(sigma, cryst, ebands, spin, ikcalc, comm) 5432 5433 !Arguments ------------------------------------ 5434 !scalars 5435 class(sigmaph_t),intent(inout) :: sigma 5436 type(ebands_t),intent(in) :: ebands 5437 type(crystal_t),intent(in) :: cryst 5438 integer,intent(in) :: ikcalc, spin, comm 5439 5440 !Local variables ------------------------------ 5441 !scalars 5442 integer :: nu, ibsum_kq, ik_ibz, bstart_ks, nbcalc_ks, my_rank, natom3 5443 integer :: nprocs, imyp, imyq, ndiv, bsum_start, bsum_stop, ib_k, band_ks 5444 integer :: iq_ibz_fine,iq_bz_fine,iq_ibz,jj, nz 5445 real(dp) :: weight, cpu,wall, gflops, eig0nk 5446 !arrays 5447 real(dp) :: kk(3), kq(3), qpt(3), dpm(2) 5448 real(dp),allocatable :: tmp_deltaw_pm(:,:,:) 5449 complex(dpc),allocatable :: zvals(:,:), tmp_cweights(:,:,:,:) 5450 5451 ! ************************************************************************* 5452 5453 call cwtime(cpu, wall, gflops, "start") 5454 5455 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 5456 5457 kk = sigma%kcalc(:, ikcalc) 5458 ik_ibz = sigma%kcalc2ibz(ikcalc, 1) 5459 nbcalc_ks = sigma%nbcalc_ks(ikcalc, spin) 5460 bstart_ks = sigma%bstart_ks(ikcalc, spin) 5461 bsum_start = sigma%bsum_start; bsum_stop = sigma%bsum_stop 5462 natom3 = 3 * cryst%natom 5463 ndiv = 1; if (sigma%use_doublegrid) ndiv = sigma%eph_doublegrid%ndiv 5464 5465 ABI_CHECK(abs(sigma%symsigma) == 1, "symsigma 0 with tetra not implemented") 5466 5467 if (sigma%imag_only) then 5468 ! Weights for Im (tetrahedron, eta --> 0) 5469 ABI_REMALLOC(sigma%deltaw_pm, (2, nbcalc_ks, sigma%my_npert, bsum_start:bsum_stop, sigma%my_nqibz_k, ndiv)) 5470 sigma%deltaw_pm = zero 5471 5472 ! Temporary weights (on the fine IBZ_k mesh if double grid is used) 5473 ABI_MALLOC(tmp_deltaw_pm, (1, sigma%ephwg%nq_k, 2)) 5474 5475 ! Loop over bands to sum 5476 do ibsum_kq=sigma%bsum_start, sigma%bsum_stop 5477 ! Loop over my phonon modes 5478 do imyp=1,sigma%my_npert 5479 nu = sigma%my_pinfo(3, imyp) 5480 5481 ! HM: This one should be faster but uses more memory, I compute for each ib instead 5482 ! Compute weights inside qb_comm 5483 !call sigma%ephwg%get_deltas_wvals(ibsum_kq, spin, nu, nbcalc_ks, & 5484 ! ebands%eig(bstart_ks:bstart_ks+nbcalc_ks, ik_ibz, spin), & 5485 ! sigma%bcorr, tmp_deltaw_pm, sigma%qb_comm%value) 5486 5487 ! loop over bands in self-energy matrix elements. 5488 do ib_k=1,nbcalc_ks 5489 band_ks = ib_k + bstart_ks - 1 5490 eig0nk = ebands%eig(band_ks, ik_ibz, spin) 5491 5492 ! Compute weights inside qb_comm 5493 call sigma%ephwg%get_deltas_wvals(ibsum_kq, spin, nu, 1, [eig0nk], sigma%bcorr, tmp_deltaw_pm, sigma%qb_comm%value) 5494 5495 ! For all the q-points that I am going to calculate 5496 do imyq=1,sigma%my_nqibz_k 5497 iq_ibz = sigma%myq2ibz_k(imyq) 5498 5499 if (sigma%use_doublegrid) then 5500 ! For all the q-points in the microzone 5501 ! This is done again in the main sigmaph routine 5502 qpt = sigma%qibz_k(:,iq_ibz) 5503 kq = kk + qpt 5504 call sigma%eph_doublegrid%get_mapping(kk, kq, qpt) 5505 do jj=1,sigma%eph_doublegrid%ndiv 5506 iq_bz_fine = sigma%eph_doublegrid%mapping(3,jj) 5507 iq_ibz_fine = sigma%eph_doublegrid%bz2lgkibz(iq_bz_fine) 5508 weight = sigma%ephwg%lgk%weights(iq_ibz_fine) 5509 !dpm = tmp_deltaw_pm(ib_k, iq_ibz_fine, :) 5510 dpm = tmp_deltaw_pm(1, iq_ibz_fine, :) 5511 sigma%deltaw_pm(:, ib_k, imyp, ibsum_kq, imyq, jj) = dpm / weight 5512 end do 5513 else 5514 weight = sigma%ephwg%lgk%weights(iq_ibz) 5515 !dpm = tmp_deltaw_pm(ib_k, iq_ibz, :) 5516 dpm = tmp_deltaw_pm(1, iq_ibz, :) 5517 sigma%deltaw_pm(:, ib_k, imyp, ibsum_kq, imyq, 1) = dpm / weight 5518 end if 5519 5520 end do 5521 end do 5522 end do 5523 end do 5524 5525 ABI_FREE(tmp_deltaw_pm) 5526 5527 else 5528 ! Both real and imag part --> compute \int 1/z with tetrahedron. 5529 ! Note that we still need a finite i.eta in the expression (hopefully smaller than the default value). 5530 ! Besides we have to take into account the case in which the spectral function is wanted. 5531 ! Derivative wrt omega is still computed with finite i.eta, though. 5532 ABI_CHECK(.not. sigma%use_doublegrid, "double grid for Re-Im not implemented") 5533 5534 ! TODO: This part should be tested. 5535 nz = 1; if (sigma%nwr > 0) nz = 1 + sigma%nwr 5536 ABI_REMALLOC(sigma%cweights, (nz,2,nbcalc_ks,sigma%my_npert,sigma%my_bsum_start:sigma%my_bsum_stop,sigma%my_nqibz_k,ndiv)) 5537 ABI_MALLOC(tmp_cweights, (nz, 2, nbcalc_ks, sigma%nqibz_k)) 5538 5539 ! Initialize z-points for Sigma_{nk} for different n bands. 5540 ABI_MALLOC(zvals, (nz, nbcalc_ks)) 5541 zvals(1, :) = sigma%e0vals + sigma%ieta 5542 if (sigma%nwr > 0) zvals(2:sigma%nwr+1, :) = sigma%wrmesh_b(:, 1:nbcalc_ks) + sigma%ieta 5543 5544 ! Loop over my bands in self-energy sum. 5545 ! TODO: Really slow if nz >> 1. Possible solutions: 5546 ! 1) reduce the number of ibsum_kq bands for which tetra must be used. 5547 ! 2) use spline with non-linear mesh 5548 ! 3) use asyntotic expansion at "large" z 5549 do ibsum_kq=sigma%my_bsum_start, sigma%my_bsum_stop 5550 ! Loop over my phonon modes 5551 do imyp=1,sigma%my_npert 5552 nu = sigma%my_pinfo(3, imyp) 5553 5554 ! cweights(nz, 2, nbsigma, self%nq_k) 5555 call sigma%ephwg%get_zinv_weights(nz, nbcalc_ks, zvals, ibsum_kq, spin, nu, sigma%zinv_opt, tmp_cweights, & 5556 xmpi_comm_self) 5557 !sigma%qpt_comm%value) 5558 !erange= 5559 !use_bzsum=sigma%symsigma == 0) 5560 5561 ! Extract weights for all the q-points that I am going to calculate. 5562 do imyq=1,sigma%my_nqibz_k 5563 iq_ibz = sigma%myq2ibz_k(imyq) 5564 weight = sigma%ephwg%lgk%weights(iq_ibz) 5565 sigma%cweights(:, :, :, imyp, ibsum_kq, imyq, 1) = tmp_cweights(:, :, :, iq_ibz) / weight 5566 end do 5567 end do 5568 end do 5569 5570 ABI_FREE(zvals) 5571 ABI_FREE(tmp_cweights) 5572 end if 5573 5574 call cwtime_report(" get_all_qweights with tetrahedron", cpu, wall, gflops) 5575 5576 end subroutine sigmaph_get_all_qweights
m_sigmaph/sigmaph_get_ebands [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_get_ebands
FUNCTION
Read quantities from the sigmaph to an ebands_t structure and return mapping
INPUTS
ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) opt=integer option selecting what to read on the ebands object. 1-only mapping, 10+n-read n temperature linewidths
SOURCE
4046 type(ebands_t) function sigmaph_get_ebands(self, cryst, ebands, brange, kcalc2ebands, linewidths, velocity, comm) result(new) 4047 4048 !Arguments ----------------------------------------------- 4049 integer,intent(in) :: comm 4050 class(sigmaph_t),intent(in) :: self 4051 type(crystal_t),intent(in) :: cryst 4052 type(ebands_t),intent(in) :: ebands 4053 integer,intent(in) :: brange(2) 4054 integer, allocatable, intent(out) :: kcalc2ebands(:,:) 4055 real(dp), allocatable, intent(out) :: linewidths(:,:,:,:,:), velocity(:,:,:,:) 4056 4057 !Local variables ----------------------------------------- 4058 !scalars 4059 integer,parameter :: master = 0 4060 integer :: spin, ikpt, ikcalc, iband, itemp, nsppol, nkpt, timrev, band_ks, bstart_ks, nbcalc_ks, mband 4061 integer :: bmin, bmax, my_rank, ierr 4062 integer :: ncerr 4063 type(krank_t) :: krank 4064 character(len=5000) :: msg 4065 !arrays 4066 !integer,allocatable :: kcalc2ebands(:,:) 4067 4068 ! ************************************************************************* 4069 4070 my_rank = xmpi_comm_rank(comm) 4071 4072 ! copy useful dimensions 4073 nsppol = self%nsppol; nkpt = ebands%nkpt 4074 4075 ! Map input ebands kpoints to kcalc k-points stored in sigmaph file. 4076 ABI_MALLOC(kcalc2ebands, (6, self%nkcalc)) 4077 timrev = kpts_timrev_from_kptopt(ebands%kptopt) 4078 4079 krank = krank_from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.) 4080 4081 if (kpts_map("symrec", timrev, cryst, krank, self%nkcalc, self%kcalc, kcalc2ebands) /= 0) then 4082 write(msg, '(3a)' ) & 4083 "Error mapping input ebands%kptns to sigmaph kcalc",ch10,& 4084 "the k-point could not be generated from a symmetrical one" 4085 ABI_ERROR(msg) 4086 end if 4087 call krank%free() 4088 4089 ! store mapping to return 4090 !if (present(kcalc2ebands)) then 4091 ! ABI_MALLOC(kcalc2ebands, (self%nkcalc)) 4092 ! kcalc2ebands(:) = indkk(1, :) 4093 !end if 4094 4095 ! Allocate using only the relevant bands for transport 4096 ! including valence states to allow to compute different doping 4097 ! MG: TODO: Do we really need this! 4098 mband = maxval(self%bstop_ks) 4099 new = ebands_chop(ebands, 1, mband) 4100 !mband = ebands%mband 4101 !call ebands_copy(ebands, new) 4102 !bmin = 1; bmax = mband 4103 bmin = brange(1); bmax = brange(2) 4104 4105 ! Read linewidths from sigmaph file. 4106 ! Use global array (mband, nkpt, nsppol) but keep in mind that results in SIGPEPH are packed 4107 ! so that only the relevant k-points are stored on file. 4108 4109 ABI_CALLOC(velocity, (3, bmin:bmax, nkpt, nsppol)) 4110 ABI_CALLOC(linewidths, (self%ntemp, bmin:bmax, nkpt, nsppol, 2)) 4111 4112 if (my_rank == master) then 4113 do spin=1,nsppol 4114 do ikcalc=1,self%nkcalc 4115 bstart_ks = self%bstart_ks(ikcalc, spin) 4116 nbcalc_ks = self%nbcalc_ks(ikcalc, spin) 4117 do iband=1,nbcalc_ks 4118 ! band index in global array. 4119 band_ks = iband + bstart_ks - 1 4120 ! kcalc --> ibz index 4121 ikpt = kcalc2ebands(1, ikcalc) 4122 4123 do itemp=1,self%ntemp 4124 ! Read SERTA lifetimes 4125 ncerr = nf90_get_var(self%ncid, nctk_idname(self%ncid, "vals_e0ks"), & 4126 linewidths(itemp, band_ks, ikpt, spin, 1), start=[2, itemp, iband, ikcalc, spin]) 4127 NCF_CHECK(ncerr) 4128 4129 ! Read MRTA lifetimes 4130 ! TODO: This should be called half_linewidth_mrta since 4131 ! in m_rta we multiply by two to get tau = 1/(2 Imag(sigma)) 4132 if (self%mrta > 0) then 4133 ncerr = nf90_get_var(self%ncid, nctk_idname(self%ncid, "linewidth_mrta"), & 4134 linewidths(itemp, band_ks, ikpt, spin, 2), start=[itemp, iband, ikcalc, spin]) 4135 NCF_CHECK(ncerr) 4136 end if 4137 end do 4138 4139 ! Read band velocities computed only of the kcalc k-points. 4140 ncerr = nf90_get_var(self%ncid, nctk_idname(self%ncid, "vcar_calc"), & 4141 velocity(:, band_ks, ikpt, spin), start=[1, iband, ikcalc, spin]) 4142 NCF_CHECK(ncerr) 4143 end do 4144 end do 4145 end do 4146 end if 4147 4148 !ABI_FREE(indkk) 4149 4150 ! This so that output linewidths are always positive independently 4151 ! of the kind of self-energy used (retarded or advanced) 4152 linewidths = abs(linewidths) 4153 4154 call xmpi_bcast(linewidths, master, comm, ierr) 4155 call xmpi_bcast(velocity, master, comm, ierr) 4156 4157 end function sigmaph_get_ebands
m_sigmaph/sigmaph_new [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_new
FUNCTION
Creation method (allocates memory, initialize data from input vars).
INPUTS
dtset<dataset_type>=All input variables for this dataset. ecut=Cutoff energy for wavefunctions. cryst<crystal_t>=Crystalline structure ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) ifc<ifc_type>=interatomic force constants and corresponding real space grid info. dtfil<datafiles_type>=variables related to files. comm=MPI communicator
SOURCE
2754 type(sigmaph_t) function sigmaph_new(dtset, ecut, cryst, ebands, ifc, dtfil, comm) result(new) 2755 2756 !Arguments ------------------------------------ 2757 integer,intent(in) :: comm 2758 real(dp),intent(in) :: ecut 2759 type(crystal_t),intent(in) :: cryst 2760 type(dataset_type),intent(in) :: dtset 2761 type(ebands_t),intent(in) :: ebands 2762 type(ifc_type),intent(in) :: ifc 2763 !type(dvdb_t),intent(in) :: dvdb 2764 type(datafiles_type),intent(in) :: dtfil 2765 2766 !Local variables ------------------------------ 2767 !scalars 2768 integer,parameter :: master = 0, istwfk1 = 1 2769 integer :: my_rank,ik,my_nshiftq,my_mpw,cnt,nprocs,ik_ibz,ndeg, iq_ibz, qptopt, qtimrev 2770 integer :: onpw, ii, ipw, ierr, spin, gap_err, ikcalc, qprange_, bstop !it, 2771 integer :: jj, bstart, natom, natom3 !, ip, iatom, idir, pertcase, 2772 integer :: isym_k, trev_k, mband, i1,i2,i3, nrest, color 2773 logical :: downsample 2774 character(len=fnlen) :: wfk_fname_dense 2775 character(len=5000) :: msg 2776 real(dp) :: estep, cpu_all, wall_all, gflops_all, cpu, wall, gflops 2777 logical :: changed, isirr_k 2778 type(ebands_t) :: tmp_ebands, ebands_dense 2779 type(gaps_t) :: gaps 2780 type(krank_t) :: krank, qrank 2781 !arrays 2782 integer :: intp_nshiftk 2783 integer :: intp_kptrlatt(3,3), g0_k(3), units(2), indkk_k(6,1), my_gmax(3), band_block(2), qptrlatt(3,3) 2784 integer,allocatable :: temp(:,:), gtmp(:,:),degblock(:,:), degblock_all(:,:,:,:), ndeg_all(:,:), iperm(:) 2785 real(dp):: params(4), my_shiftq(3,1), kk(3), kq(3), intp_shiftk(3) 2786 ! integer :: inwr, jnwr, min_nwr 2787 ! integer :: array_nwr(12) 2788 #ifdef HAVE_MPI 2789 integer,parameter :: ndims = 5 2790 integer :: comm_cart, me_cart 2791 logical :: reorder 2792 integer :: dims(ndims) 2793 logical :: periods(ndims), keepdim(ndims) 2794 #endif 2795 2796 ! ************************************************************************* 2797 2798 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 2799 2800 call cwtime(cpu_all, wall_all, gflops_all, "start") 2801 call cwtime(cpu, wall, gflops, "start") 2802 2803 units = [std_out, ab_out] 2804 2805 ! Copy important dimensions. 2806 new%nsppol = ebands%nsppol; new%nspinor = ebands%nspinor; mband = dtset%mband 2807 natom = cryst%natom; natom3 = cryst%natom * 3 2808 2809 ! Re-Im or Im only? 2810 new%imag_only = .False. 2811 if (dtset%eph_task == -4) then 2812 new%imag_only = .True. 2813 new%mrta = 1 ! Compute lifetimes in the MRTA approximation? Default is yes 2814 !if (dtset%userie == 1) new%mrta = 0 2815 end if 2816 2817 ! TODO: Remove qint_method, use eph_intmeth or perhaps dtset%qint_method dtset%kint_method 2818 ! FIXME: Tetra gives positive SIGE2 while zcut gives negative (retarded) 2819 ! Decide default behaviour for Re-Im/Im 2820 new%qint_method = dtset%eph_intmeth - 1 2821 new%phwinfact = dtset%eph_phwinfact 2822 2823 ! Define option for integration of 1/z with tetrahedron method. 2824 new%zinv_opt = 1; if (dtset%userie /= 0) new%zinv_opt = dtset%userie 2825 2826 ! Broadening parameter from zcut 2827 new%ieta = + j_dpc * dtset%zcut 2828 2829 ! Define q-mesh for integration of the self-energy. 2830 ! Either q-mesh from DVDB (no interpolation) or eph_ngqpt_fine (Fourier interpolation if q not in DDB) 2831 new%ngqpt = dtset%ddb_ngqpt; my_nshiftq = 1; my_shiftq(:,1) = dtset%ddb_shiftq 2832 if (all(dtset%eph_ngqpt_fine /= 0)) then 2833 new%ngqpt = dtset%eph_ngqpt_fine; my_shiftq = 0 2834 end if 2835 2836 ! Setup IBZ, weights and BZ. 2837 ! Assume qptopt == kptopt unless value is specified in input 2838 qptrlatt = 0; qptrlatt(1, 1) = new%ngqpt(1); qptrlatt(2, 2) = new%ngqpt(2); qptrlatt(3, 3) = new%ngqpt(3) 2839 !my_shiftq(:,1) = [0.1, 0, 0] 2840 qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt 2841 qtimrev = kpts_timrev_from_kptopt(qptopt) 2842 call kpts_ibz_from_kptrlatt(cryst, qptrlatt, qptopt, my_nshiftq, my_shiftq, & 2843 new%nqibz, new%qibz, new%wtq, new%nqbz, new%qbz, bz2ibz=new%ind_qbz2ibz) 2844 2845 ! HM: the bz2ibz produced above is incomplete, I do it here using listkk 2846 ABI_MALLOC(temp, (6, new%nqbz)) 2847 2848 qrank = krank_from_kptrlatt(new%nqibz, new%qibz, qptrlatt, compute_invrank=.False.) 2849 if (kpts_map("symrec", qtimrev, cryst, qrank, new%nqbz, new%qbz, temp) /= 0) then 2850 ABI_ERROR("Cannot map qBZ to qIBZ!") 2851 end if 2852 2853 call qrank%free() 2854 2855 new%ind_qbz2ibz(1,:) = temp(1,:) 2856 new%ind_qbz2ibz(2,:) = temp(2,:) 2857 new%ind_qbz2ibz(3,:) = temp(6,:) 2858 new%ind_qbz2ibz(4,:) = temp(3,:) 2859 new%ind_qbz2ibz(5,:) = temp(4,:) 2860 new%ind_qbz2ibz(6,:) = temp(5,:) 2861 ABI_FREE(temp) 2862 !END DEBUG 2863 2864 ! Build (linear) mesh of K * temperatures. tsmesh(1:3) = [start, step, num] 2865 call dtset%get_ktmesh(new%ntemp, new%kTmesh) 2866 2867 gaps = ebands_get_gaps(ebands, gap_err) 2868 2869 ! Frequency mesh for sigma(w) and spectral functions. 2870 ! TODO: Use GW variables but change default 2871 !dtset%freqspmin 2872 new%nwr = dtset%nfreqsp; new%wr_step = zero 2873 if (new%nwr > 0) then 2874 ! ! For fft to work in some machines nwr must be a multiple of 3 or 5 only 2875 ! array_nwr(:) = 1 2876 ! min_nwr = new%nwr 2877 ! do inwr=1,12 2878 ! do jnwr=1,inwr 2879 ! array_nwr(jnwr) = 3 2880 ! end do 2881 ! if (ABS(product(array_nwr) - new%nwr) < min_nwr .and. product(array_nwr) - new%nwr > zero) min_nwr = product(array_nwr)- new%nwr 2882 ! if (product(array_nwr) > new%nwr) go to 1010 2883 ! do jnwr=1, inwr 2884 ! array_nwr(jnwr) = 5 2885 ! if (ABS(product(array_nwr) - new%nwr) < min_nwr .and. product(array_nwr) - new%nwr > zero) min_nwr = product(array_nwr)- new%nwr 2886 ! end do 2887 ! 2888 ! end do 2889 2890 ! 1010 new%nwr = new%nwr + min_nwr 2891 if (mod(new%nwr, 2) == 0) new%nwr = new%nwr + 1 2892 new%wr_step = two * eV_Ha / (new%nwr - 1) 2893 if (dtset%freqspmax /= zero) new%wr_step = dtset%freqspmax / (new%nwr - 1) 2894 end if 2895 2896 ! ====================================================== 2897 ! Select k-point and bands where corrections are wanted 2898 ! ====================================================== 2899 ! 2900 ! if symsigma == +1, we have to include all degenerate states in the set 2901 ! because the final QP corrections will be obtained by averaging the results in the degenerate subspace. 2902 ! We initialize IBZ(k) here so that we have all the basic dimensions of the run and it's possible 2903 ! to distribuite the calculations among processors. 2904 new%symsigma = dtset%symsigma; new%timrev = kpts_timrev_from_kptopt(ebands%kptopt) 2905 2906 call cwtime_report(" sigmaph_new: k-points", cpu, wall, gflops) 2907 2908 ! TODO: nkcalc should be spin dependent (similar piece of code in m_gwr). 2909 if (dtset%nkptgw /= 0) then 2910 2911 ! Treat the k-points and bands specified in the input file via kptgw and bdgw. 2912 call sigtk_kcalc_from_nkptgw(dtset, mband, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks) 2913 2914 else 2915 2916 if (any(abs(dtset%sigma_erange) > zero)) then 2917 ! Use sigma_erange and (optionally) sigma_ngkpt 2918 call sigtk_kcalc_from_erange(dtset, cryst, ebands, gaps, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks, comm) 2919 2920 else 2921 ! Use qp_range to select the interesting k-points and the corresponding bands. 2922 ! 2923 ! 0 --> Compute the QP corrections only for the fundamental and the direct gap. 2924 ! +num --> Compute the QP corrections for all the k-points in the irreducible zone and include `num` 2925 ! bands above and below the Fermi level. 2926 ! -num --> Compute the QP corrections for all the k-points in the irreducible zone. 2927 ! Include all occupied states and `num` empty states. 2928 2929 qprange_ = dtset%gw_qprange 2930 if (gap_err /= 0 .and. qprange_ == 0) then 2931 ABI_WARNING("Cannot compute fundamental and direct gap (likely metal). Will replace qprange 0 with qprange 1") 2932 qprange_ = 1 2933 end if 2934 2935 if (qprange_ /= 0) then 2936 call sigtk_kcalc_from_qprange(dtset, cryst, ebands, qprange_, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks) 2937 else 2938 ! qprange is not specified in the input. 2939 ! Include direct and fundamental KS gap or include states depending on the position wrt band edges. 2940 call sigtk_kcalc_from_gaps(dtset, ebands, gaps, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks) 2941 end if 2942 end if 2943 2944 end if ! nkptgw /= 0 2945 2946 ! The k-point and the symmetries connecting the BZ k-point to the IBZ. 2947 ABI_MALLOC(new%kcalc2ibz, (new%nkcalc, 6)) 2948 if (abs(new%symsigma) == 1) then 2949 ABI_MALLOC(new%degtab, (new%nkcalc, new%nsppol)) 2950 end if 2951 2952 ! Workspace arrays used to compute degeneracy tables. 2953 ABI_ICALLOC(degblock_all, (2, mband, new%nkcalc, new%nsppol)) 2954 ABI_ICALLOC(ndeg_all, (new%nkcalc, new%nsppol)) 2955 2956 krank = krank_from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.) 2957 ierr = 0 2958 2959 do ikcalc=1,new%nkcalc 2960 if (mod(ikcalc, nprocs) /= my_rank) then 2961 new%kcalc2ibz(ikcalc, :) = 0 2962 new%bstart_ks(ikcalc, :) = 0 2963 new%nbcalc_ks(ikcalc, :) = 0 2964 cycle ! MPI parallelism inside comm 2965 end if 2966 2967 ! Note symrel and use_symrel. 2968 ! These are the conventions for the symmetrization of the wavefunctions used in cgtk_rotate. 2969 kk = new%kcalc(:, ikcalc) 2970 2971 if (kpts_map("symrel", new%timrev, cryst, krank, 1, kk, indkk_k) /= 0) then 2972 write(msg, '(11a)' )& 2973 "The WFK file cannot be used to compute self-energy corrections at k-point: ",trim(ktoa(kk)),ch10,& 2974 "The k-point cannot be generated from a symmetrical one.", ch10,& 2975 "q-mesh: ",trim(ltoa(new%ngqpt)),", k-mesh (from kptrlatt): ",trim(ltoa(get_diag(dtset%kptrlatt))),ch10, & 2976 'Action: check your WFK file and the (k, q) point input variables.' 2977 ABI_ERROR(msg) 2978 end if 2979 2980 ! TODO: Invert dims and update abipy 2981 new%kcalc2ibz(ikcalc, :) = indkk_k(:, 1) 2982 2983 ik_ibz = indkk_k(1,1); isym_k = indkk_k(2,1) 2984 trev_k = indkk_k(6, 1); g0_k = indkk_k(3:5,1) 2985 isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0)) 2986 !kk_ibz = ebands%kptns(:,ik_ibz) 2987 if (.not. isirr_k) then 2988 ABI_WARNING(sjoin("The k-point in Sigma_{nk} must be in the IBZ but got:", ktoa(kk))) 2989 ierr = ierr + 1 2990 end if 2991 2992 ! We will have to average the QP corrections over degenerate states if symsigma=1 is used. 2993 ! Here we make sure that all the degenerate states are included. 2994 ! Store also band indices of the degenerate sets, used to average final results. 2995 if (abs(new%symsigma) == 1) then 2996 cnt = 0 2997 do spin=1,new%nsppol 2998 bstop = new%bstart_ks(ikcalc, spin) + new%nbcalc_ks(ikcalc, spin) - 1 2999 call ebands_enclose_degbands(ebands, ik_ibz, spin, new%bstart_ks(ikcalc, spin), bstop, changed, TOL_EDIFF, & 3000 degblock=degblock) 3001 if (changed) then 3002 new%nbcalc_ks(ikcalc, spin) = bstop - new%bstart_ks(ikcalc, spin) + 1 3003 cnt = cnt + 1 3004 if (cnt < 5) then 3005 write(msg,'(2(a,i0),2a,2(1x,i0))') & 3006 "Not all the degenerate states for ikcalc: ",ikcalc,", spin: ",spin,ch10, & 3007 "were included in the bdgw set. bdgw has been automatically changed to: ",new%bstart_ks(ikcalc, spin), bstop 3008 ABI_COMMENT(msg) 3009 end if 3010 write(msg,'(2(a,i0),2a)') & 3011 "The number of included states: ", bstop, & 3012 " is larger than the number of bands in the input ",dtset%nband(ik_ibz + (spin-1)*ebands%nkpt),ch10,& 3013 "Action: Increase nband." 3014 ABI_CHECK(bstop <= dtset%nband(ik_ibz + (spin-1)*ebands%nkpt), msg) 3015 end if 3016 3017 ! Store band indices used for averaging (shifted by bstart_ks) 3018 ndeg = size(degblock, dim=2) 3019 ndeg_all(ikcalc, spin) = ndeg 3020 degblock_all(:, 1:ndeg, ikcalc, spin) = degblock(:, 1:ndeg) 3021 3022 ABI_FREE(degblock) 3023 end do 3024 end if ! symsigma 3025 end do ! ikcalc 3026 3027 call krank%free() 3028 ABI_CHECK(ierr == 0, "kptgw wavevectors must be in the IBZ read from the WFK file.") 3029 3030 ! Collect data 3031 call xmpi_sum(new%kcalc2ibz, comm, ierr) 3032 call xmpi_sum(new%bstart_ks, comm, ierr) 3033 call xmpi_sum(new%nbcalc_ks, comm, ierr) 3034 3035 ! Build degtab tables. 3036 if (abs(new%symsigma) == 1) then 3037 call xmpi_sum(ndeg_all, comm, ierr) 3038 call xmpi_sum(degblock_all, comm, ierr) 3039 do ikcalc=1,new%nkcalc 3040 do spin=1,new%nsppol 3041 ndeg = ndeg_all(ikcalc, spin) 3042 ABI_MALLOC(new%degtab(ikcalc, spin)%bids, (ndeg)) 3043 do ii=1,ndeg 3044 cnt = degblock_all(2, ii, ikcalc, spin) - degblock_all(1, ii, ikcalc, spin) + 1 3045 ABI_MALLOC(new%degtab(ikcalc, spin)%bids(ii)%vals, (cnt)) 3046 new%degtab(ikcalc, spin)%bids(ii)%vals = [(jj, jj= & 3047 degblock_all(1, ii, ikcalc, spin) - new%bstart_ks(ikcalc, spin) + 1, & 3048 degblock_all(2, ii, ikcalc, spin) - new%bstart_ks(ikcalc, spin) + 1)] 3049 end do 3050 end do 3051 end do 3052 end if 3053 ABI_FREE(degblock_all) 3054 ABI_FREE(ndeg_all) 3055 3056 call cwtime_report(" sigmaph_new: kptgw", cpu, wall, gflops) 3057 3058 ! Now we can finally compute max_nbcalc 3059 new%max_nbcalc = maxval(new%nbcalc_ks) 3060 3061 ABI_MALLOC(new%bstop_ks, (new%nkcalc, new%nsppol)) 3062 new%bstop_ks = new%bstart_ks + new%nbcalc_ks - 1 3063 3064 ! mpw is the maximum number of plane-waves over k and k+q where k and k+q are in the BZ. 3065 ! we also need the max components of the G-spheres (k, k+q) in order to allocate the workspace array work 3066 ! used to symmetrize the wavefunctions in G-space. 3067 ! Note that we loop over the full BZ instead of the IBZ(k) 3068 ! This part is slow for very dense meshes, should try to use a geometrical approach... 3069 3070 new%mpw = 0; new%gmax = 0; cnt = 0 3071 do ik=1,new%nkcalc 3072 kk = new%kcalc(:, ik) 3073 do i3=-1,1 3074 do i2=-1,1 3075 do i1=-1,1 3076 cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism inside comm 3077 kq = kk + half * [i1, i2, i3] 3078 ! TODO: g0 umklapp here can enter into play gmax may not be large enough! 3079 call get_kg(kq, istwfk1, 1.1_dp * ecut, cryst%gmet, onpw, gtmp) 3080 new%mpw = max(new%mpw, onpw) 3081 do ipw=1,onpw 3082 do ii=1,3 3083 new%gmax(ii) = max(new%gmax(ii), abs(gtmp(ii, ipw))) 3084 end do 3085 end do 3086 ABI_FREE(gtmp) 3087 end do 3088 end do 3089 end do 3090 end do 3091 3092 my_mpw = new%mpw; call xmpi_max(my_mpw, new%mpw, comm, ierr) 3093 my_gmax = new%gmax; call xmpi_max(my_gmax, new%gmax, comm, ierr) 3094 3095 call wrtout(std_out, sjoin(' Optimal value of mpw:', itoa(new%mpw), "gmax:", ltoa(new%gmax))) 3096 call cwtime_report(" sigmaph_new: mpw", cpu, wall, gflops) 3097 3098 ! Define number of bands included in self-energy summation as well as the band range. 3099 ! This value depends on the kind of calculation as imag_only can take advantage of 3100 ! the energy window aroud the band edges. 3101 ! 3102 ! Notes about MPI version. 3103 ! If eph_task == -4: 3104 ! Loops are MPI parallelized over bands so that we can distribute memory for wavefunctions over nband. 3105 ! perturbations and q-points in the IBZ can also be distributed. 3106 ! 3107 ! If eph_task == -4: 3108 ! Loops are MPI parallelized over q-points 3109 ! wavefunctions are NOT distributed but only states between my_bsum_start and my_bsum_stop 3110 ! are allocated and read from file. 3111 ! perturbations and q-points in the IBZ can also be distributed. 3112 3113 new%wmax = 1.1_dp * abs(ifc%omega_minmax(2)) 3114 if (new%qint_method == 0) new%wmax = new%wmax + five * dtset%zcut 3115 ! TODO: One should be consistent with tolerances when using tetra + q-point filtering. 3116 !if (new%qint_method == 1) new%wmax = new%wmax + five * dtset%zcut 3117 !new%wmax = new%wmax + five * dtset%zcut 3118 !write(std_out,*)"wmax:", new%wmax * Ha_eV, " (eV)" 3119 3120 new%elow = huge(one); new%ehigh = - huge(one) 3121 do spin=1,new%nsppol 3122 do ikcalc=1,new%nkcalc 3123 ik_ibz = new%kcalc2ibz(ikcalc, 1) 3124 bstart = new%bstart_ks(ikcalc, spin) 3125 bstop = new%bstart_ks(ikcalc, spin) + new%nbcalc_ks(ikcalc, spin) - 1 3126 new%ehigh = max(new%ehigh, maxval(ebands%eig(bstart:bstop, ik_ibz, spin)) + new%wmax) 3127 new%elow = min(new%elow, minval(ebands%eig(bstart:bstop, ik_ibz, spin)) - new%wmax) 3128 end do 3129 end do 3130 !call wrtout(std_out, sjoin("elow:", ftoa(elow), "ehigh:", ftoa(ehigh), "[Ha]")) 3131 3132 if (new%imag_only) then 3133 3134 if (all(dtset%sigma_bsum_range /= 0)) then 3135 new%bsum_start = max(dtset%sigma_bsum_range(1), 1) 3136 new%bsum_stop = min(dtset%sigma_bsum_range(2), mband) 3137 new%nbsum = new%bsum_stop - new%bsum_start + 1 3138 new%my_bsum_start = new%bsum_start; new%my_bsum_stop = new%bsum_stop 3139 else 3140 ! Compute the min/max KS energy to be included in the imaginary part. 3141 ! ifc%omega_minmax(2) comes froms the coarse Q-mesh of the DDB so increase it by 10%. 3142 ! Also take into account the Lorentzian function if zcut is used. 3143 ! In principle this should be large enough but it seems that the linewidths in v8[160] are slightly affected. 3144 ! Select indices for energy window. 3145 3146 call ebands_get_bands_from_erange(ebands, new%elow, new%ehigh, new%bsum_start, new%bsum_stop) 3147 new%bsum_stop = min(new%bsum_stop, mband) 3148 ABI_CHECK(new%bsum_start <= new%bsum_stop, "bsum_start > bsum_bstop") 3149 new%nbsum = new%bsum_stop - new%bsum_start + 1 3150 new%my_bsum_start = new%bsum_start; new%my_bsum_stop = new%bsum_stop 3151 end if 3152 3153 !if (dtset%useria == 567) then 3154 ! ! Uncomment this part to use all states to debug. 3155 ! call wrtout(units, "- Setting bstart to 1 and bstop to nband for debugging purposes") 3156 ! new%nbsum = mband; new%bsum_start = 1; new%bsum_stop = new%bsum_start + new%nbsum - 1 3157 ! new%my_bsum_start = new%bsum_start; new%my_bsum_stop = new%bsum_stop 3158 !end if 3159 3160 else 3161 ! Re + Im 3162 new%bsum_start = 1; new%bsum_stop = mband 3163 if (all(dtset%sigma_bsum_range /= 0)) then 3164 new%bsum_start = max(dtset%sigma_bsum_range(1), 1) 3165 new%bsum_stop = min(dtset%sigma_bsum_range(2), mband) 3166 end if 3167 new%nbsum = new%bsum_stop - new%bsum_start + 1 3168 end if 3169 3170 ! ======================== 3171 ! === MPI DISTRIBUTION === 3172 ! ======================== 3173 ! Init for sequential execution. 3174 new%my_npert = natom3 3175 3176 if (any(dtset%eph_np_pqbks /= 0)) then 3177 ! Use parameters from input file. 3178 new%pert_comm%nproc = dtset%eph_np_pqbks(1) 3179 new%qpt_comm%nproc = dtset%eph_np_pqbks(2) 3180 new%bsum_comm%nproc = dtset%eph_np_pqbks(3) 3181 new%kcalc_comm%nproc = dtset%eph_np_pqbks(4) 3182 new%spin_comm%nproc = dtset%eph_np_pqbks(5) 3183 new%my_npert = natom3 / new%pert_comm%nproc 3184 ABI_CHECK(new%my_npert > 0, "pert_comm_nproc cannot be greater than 3 * natom.") 3185 ABI_CHECK(mod(natom3, new%pert_comm%nproc) == 0, "pert_comm_nproc must divide 3 * natom.") 3186 if (new%imag_only .and. new%bsum_comm%nproc /= 1) then 3187 ABI_ERROR("Nprocs in bsum_comm should be 1 when computing Imag(Sigma)") 3188 end if 3189 else 3190 ! Automatic grid generation. 3191 3192 ! TODO: Spin 3193 ! Automatic grid generation over q-points and spins. 3194 !if (new%nsppol == 2 .and. mod(nprocs, 2) == 0) then 3195 ! spin_comm%nproc = 2 3196 ! new%qpt_comm%nproc = nprocs / 2 3197 !else 3198 ! new%qpt_comm%nproc = nprocs 3199 !end if 3200 3201 ! Handle parallelism over perturbations first. 3202 ! Use MPI communicator to distribute the 3 * natom perturbations to reduce memory requirements for DFPT potentials. 3203 ! Ideally, perturbations are equally distributed --> total number of CPUs should be divisible by 3 * natom. 3204 ! or at least, divisible by one integer i for i in [2, 3 * natom - 1]. 3205 3206 ! Try to have 3 perts per proc first because the q-point parallelism is more efficient. 3207 ! The memory for W(R,r,ipert) will increase though. 3208 !do cnt=natom,2,-1 3209 ! if (mod(nprocs, cnt) == 0 .and. mod(natom3, cnt) == 0) then 3210 ! new%pert_comm%nproc = cnt; new%my_npert = natom3 / cnt; exit 3211 ! end if 3212 !end do 3213 3214 if (new%pert_comm%nproc == 1) then 3215 ! Try again with more procs. 3216 do cnt=natom3,2,-1 3217 if (mod(nprocs, cnt) == 0 .and. mod(natom3, cnt) == 0) then 3218 new%pert_comm%nproc = cnt; new%my_npert = natom3 / cnt; exit 3219 end if 3220 end do 3221 end if 3222 3223 if (new%my_npert == natom3 .and. nprocs > 1) then 3224 ABI_WARNING("The number of MPI procs should be divisible by 3*natom to reduce memory requirements!") 3225 end if 3226 3227 ! Define number of procs for q-points and bands. nprocs is divisible by pert_comm%nproc. 3228 if (new%imag_only) then 3229 ! Just one extra MPI level for q-points. 3230 new%qpt_comm%nproc = nprocs / new%pert_comm%nproc 3231 else 3232 ! Try to distribute equally nbsum first. 3233 nrest = nprocs / new%pert_comm%nproc 3234 do bstop=nrest,1,-1 3235 if (mod(new%nbsum, bstop) == 0 .and. mod(nprocs, new%pert_comm%nproc * bstop) == 0) then 3236 new%bsum_comm%nproc = bstop; new%qpt_comm%nproc = nrest / new%bsum_comm%nproc 3237 exit 3238 end if 3239 end do 3240 end if 3241 end if 3242 3243 ! Consistency check. 3244 if (new%pert_comm%nproc * new%qpt_comm%nproc * new%bsum_comm%nproc * new%kcalc_comm%nproc * new%spin_comm%nproc /= nprocs) then 3245 write(msg, "(a,i0,3a, 6(a,1x,i0))") & 3246 "Cannot create 5d Cartesian grid with total nprocs: ", nprocs, ch10, & 3247 "Idle processes are not supported. The product of the `nprocs_*` vars should be equal to nprocs.", ch10, & 3248 "pert_nproc (", new%pert_comm%nproc, ") x qpt_nproc (", new%qpt_comm%nproc, ") x bsum_nproc (", new%bsum_comm%nproc, & 3249 ") x kcalc_nproc (", new%kcalc_comm%nproc, ") x spin_nproc (", new%spin_comm%nproc, ") != ", nprocs 3250 ABI_ERROR(msg) 3251 end if 3252 3253 new%coords_pqbks = 0 3254 #ifdef HAVE_MPI 3255 ! Create 5d cartesian communicator: 3*natom perturbations, q-points in IBZ, bands in Sigma sum, kpoints in Sigma_k, spins 3256 ! FIXME: Fix spin 3257 periods(:) = .False.; reorder = .False. 3258 dims = [new%pert_comm%nproc, new%qpt_comm%nproc, new%bsum_comm%nproc, new%kcalc_comm%nproc, new%spin_comm%nproc] 3259 ! Try New distrib ? 3260 !dims = [new%pert_comm%nproc, new%bsum_comm%nproc, new%qpt_comm%nproc, new%kcalc_comm%nproc, new%spin_comm%nproc] 3261 3262 call MPI_CART_CREATE(comm, ndims, dims, periods, reorder, comm_cart, ierr) 3263 ! Find the index and coordinates of the current processor 3264 call MPI_COMM_RANK(comm_cart, me_cart, ierr) 3265 call MPI_CART_COORDS(comm_cart, me_cart, ndims, new%coords_pqbks, ierr) 3266 3267 ! Create communicator to distribute natom3 perturbations. 3268 keepdim = .False.; keepdim(1) = .True.; call new%pert_comm%from_cart_sub(comm_cart, keepdim) 3269 ! Create communicator for qpoints in self-energy integration. 3270 keepdim = .False.; keepdim(2) = .True.; call new%qpt_comm%from_cart_sub(comm_cart, keepdim) 3271 ! Create communicator for bands for self-energy summation 3272 keepdim = .False.; keepdim(3) = .True.; call new%bsum_comm%from_cart_sub(comm_cart, keepdim) 3273 ! Create communicator for kpoints. 3274 keepdim = .False.; keepdim(4) = .True.; call new%kcalc_comm%from_cart_sub(comm_cart, keepdim) 3275 ! Create communicator for spins. 3276 keepdim = .False.; keepdim(5) = .True.; call new%spin_comm%from_cart_sub(comm_cart, keepdim) 3277 ! Create communicator for the (band_sum, qpoint_sum) loops 3278 keepdim = .False.; keepdim(2:3) = .True.; call new%qb_comm%from_cart_sub(comm_cart, keepdim) 3279 ! Create communicator for the (perturbation, band_sum, qpoint_sum) 3280 keepdim = .False.; keepdim(1:3) = .True.; call new%pqb_comm%from_cart_sub(comm_cart, keepdim) 3281 3282 call xmpi_comm_free(comm_cart) 3283 #endif 3284 3285 ! Distribute k-points and create mapping to ikcalc index. 3286 call xmpi_split_cyclic(new%nkcalc, new%kcalc_comm%value, new%my_nkcalc, new%my_ikcalc) 3287 ABI_CHECK(new%my_nkcalc > 0, sjoin("nkcalc (", itoa(new%nkcalc), ") < kcalc_comm_nproc (", itoa(new%kcalc_comm%nproc), ")")) 3288 3289 ! Distribute spins and create mapping to spin index. 3290 if (new%nsppol == 2) then 3291 call xmpi_split_block(new%nsppol, new%spin_comm%value, new%my_nspins, new%my_spins) 3292 ABI_CHECK(new%my_nspins > 0, sjoin("nsppol (", itoa(new%nsppol), ") < spin_comm_nproc (", itoa(new%spin_comm%nproc), ")")) 3293 else 3294 ! No nsppol parallelism DOH! 3295 new%my_nspins = 1 3296 ABI_MALLOC(new%my_spins, (new%my_nspins)) 3297 new%my_spins = 1 3298 end if 3299 3300 ! Create MPI communicator for parallel netcdf IO used to write results for the different k-points. 3301 ! This communicator is defined only on the processes that will perform IO. 3302 call new%ncwrite_comm%set_to_null() 3303 3304 if (new%kcalc_comm%nproc == 1 .and. new%spin_comm%nproc == 1) then 3305 ! Easy-peasy: only master in comm_world performs IO. 3306 if (my_rank == master) call new%ncwrite_comm%set_to_self() 3307 else 3308 ! Create subcommunicator by selecting one proc per kpoint-spin subgrid. 3309 ! Since we write to ab_out in sigmaph_gather_and_write, make sure that ab_out is connected! 3310 ! This means Sigma_nk resuls will be spread among multiple ab_out files. 3311 ! Only SIGPEPH.nc will contain all the results. 3312 ! Remember that now all nc define operations must be done inside ncwrite_comm 3313 ! Obviously I'm assuming HDF5 + MPI-IO 3314 ! 3315 ! NB: If MPI_UNDEFINED is passed as the colour value, the subgroup in which the calling 3316 ! MPI process will be placed is MPI_COMM_NULL 3317 3318 color = xmpi_undefined; if (all(new%coords_pqbks(1:3) == 0)) color = 1 3319 call xmpi_comm_split(comm, color, my_rank, new%ncwrite_comm%value, ierr) 3320 if (color == 1) then 3321 new%ncwrite_comm%me = xmpi_comm_rank(new%ncwrite_comm%value) 3322 new%ncwrite_comm%nproc = xmpi_comm_size(new%ncwrite_comm%value) 3323 if (my_rank == master) then 3324 call wrtout(units, & 3325 sjoin("- Using parallelism over k-points/spins. Cannot write full results to main output", ch10, & 3326 "- All procs except master will write to dev_null. Use SIGEPH.nc to analyze results.")) 3327 !write(std_out, *)"ncwrite_comm_me:", new%ncwrite_comm%me, "ncwrite_comm%nproc:", new%ncwrite_comm%nproc 3328 end if 3329 if (.not. is_open(ab_out)) then 3330 !if (open_file(strcat(dtfil%filnam_ds(2), "_rank_", itoa(new%ncwrite_comm%me)), msg, unit=ab_out, & 3331 if (open_file(NULL_FILE, msg, unit=ab_out, form="formatted", action="write", status='unknown') /= 0) then 3332 ABI_ERROR(msg) 3333 end if 3334 end if 3335 else 3336 call new%ncwrite_comm%set_to_null() 3337 end if 3338 end if 3339 3340 ! Build table with list of perturbations treated by this CPU inside pert_comm 3341 call ephtk_set_pertables(cryst%natom, new%my_npert, new%pert_table, new%my_pinfo, new%pert_comm%value) 3342 3343 ! Setup a mask to skip accumulating the contribution of certain phonon modes. 3344 call ephtk_set_phmodes_skip(dtset%natom, dtset%eph_phrange, new%phmodes_skip) 3345 3346 if (.not. new%imag_only) then 3347 ! Split bands among the procs inside bsum_comm using block distribution. 3348 call xmpi_split_work(new%nbsum, new%bsum_comm%value, new%my_bsum_start, new%my_bsum_stop) 3349 if (new%my_bsum_start == new%nbsum + 1) then 3350 ABI_ERROR("sigmaph code does not support idle processes! Decrease ncpus or increase nband or use eph_np_pqbks input var.") 3351 end if 3352 new%my_bsum_start = new%bsum_start + new%my_bsum_start - 1 3353 new%my_bsum_stop = new%bsum_start + new%my_bsum_stop - 1 3354 ABI_MALLOC(new%nbsum_rank, (new%bsum_comm%nproc, 3)) 3355 ii = new%my_bsum_stop - new%my_bsum_start + 1 3356 call xmpi_allgather(ii, new%nbsum_rank(:,1), new%bsum_comm%value, ierr) 3357 ii = new%my_bsum_start 3358 call xmpi_allgather(ii, new%nbsum_rank(:,2), new%bsum_comm%value, ierr) 3359 end if 3360 3361 call wrtout(std_out, sjoin(" Global bands for self-energy sum, bsum_start: ", itoa(new%bsum_start), & 3362 " bsum_bstop:", itoa(new%bsum_stop))) 3363 call wrtout(std_out, sjoin(" Allocating and treating bands from my_bsum_start: ", itoa(new%my_bsum_start), & 3364 " up to my_bsum_stop:", itoa(new%my_bsum_stop))) 3365 3366 ! Distribute DFPT potentials (IBZ q-points) inside qpt_comm. 3367 ! Note that we distribute IBZ instead of the full BZ or the IBZ_k inside the loop over ikcalc. 3368 ! This means that the load won't be equally distributed but memory will scale with qpt_comm%nproc. 3369 ! To reduce load imbalance, we sort the qibz points by norm and use cyclic distribution inside qpt_comm 3370 ABI_ICALLOC(new%itreat_qibz, (new%nqibz)) 3371 call sort_rpts(new%nqibz, new%qibz, cryst%gmet, iperm) 3372 do ii=1,new%nqibz 3373 iq_ibz = iperm(ii) 3374 if (mod(ii, new%qpt_comm%nproc) == new%qpt_comm%me) new%itreat_qibz(iq_ibz) = 1 3375 end do 3376 ABI_FREE(iperm) 3377 3378 call wrtout(std_out, sjoin("P Number of q-points in the IBZ treated by this proc: " ,itoa(count(new%itreat_qibz == 1)))) 3379 3380 ! ================================================================ 3381 ! Allocate arrays used to store final results and set them to zero 3382 ! ================================================================ 3383 ABI_ICALLOC(new%qp_done, (new%nkcalc, new%nsppol)) 3384 ABI_CALLOC(new%vals_e0ks, (new%ntemp, new%max_nbcalc)) 3385 ABI_CALLOC(new%fan_vals, (new%ntemp, new%max_nbcalc)) 3386 ABI_CALLOC(new%fan_stern_vals, (new%ntemp, new%max_nbcalc)) 3387 ABI_CALLOC(new%dvals_de0ks, (new%ntemp, new%max_nbcalc)) 3388 ABI_CALLOC(new%dw_vals, (new%ntemp, new%max_nbcalc)) 3389 ABI_CALLOC(new%dw_stern_vals, (new%ntemp, new%max_nbcalc)) 3390 3391 ! Frequency dependent stuff 3392 if (new%nwr > 0) then 3393 ABI_CALLOC(new%vals_wr, (new%nwr, new%ntemp, new%max_nbcalc)) 3394 ABI_CALLOC(new%wrmesh_b, (new%nwr, new%max_nbcalc)) 3395 end if 3396 3397 ! Compute phonon frequency mesh. 3398 call ifc%get_phmesh(dtset%ph_wstep, new%phmesh_size, new%phmesh) 3399 3400 ! Prepare calculation of generalized Eliashberg functions 3401 ! prteliash == 0 deactivates computation (default). 3402 if (dtset%prteliash /= 0) then 3403 ABI_MALLOC(new%gfw_vals, (new%phmesh_size, 3, new%max_nbcalc)) 3404 end if 3405 3406 new%a2f_ne = 0 3407 if (dtset%prteliash == 3) then 3408 ! TODO: dosdeltae should have a default value. 3409 ! TODO: Use logmesh/double mesh for electrons? 3410 estep = dtset%dosdeltae; if (estep <= zero) estep = 0.05 * eV_Ha 3411 new%a2f_ne = nint((maxval(ebands%eig) - minval(ebands%eig)) / estep) + 1 3412 if (my_rank == master) then 3413 write(std_out, *)" Computing a2f with ", new%a2f_ne, " points for electrons and ", new%phmesh_size, " points for phonons." 3414 write(std_out, *)" doseltae:", estep, ", tsmear:", dtset%tsmear 3415 end if 3416 ABI_MALLOC(new%a2f_emesh, (new%a2f_ne)) 3417 new%a2f_emesh = arth(minval(ebands%eig), estep, new%a2f_ne) 3418 ABI_CALLOC(new%a2few, (new%a2f_ne, new%phmesh_size, new%max_nbcalc)) 3419 end if 3420 3421 call cwtime_report(" MPI setup", cpu, wall, gflops) 3422 3423 ! Initialize object for the computation of integration weights (integration in q-space). 3424 ! Weights can be obtained in different ways: 3425 ! 3426 ! 1. Computed from eigens on the same coarse q-mesh as the one used for the self-energy. 3427 ! 2. Obtained from eigens on a denser q-mesh and then transfered to the coarse q-mesh. 3428 ! In this case the eigens on the dense mesh are either read from an external file (ab-initio) 3429 ! or interpolated on the fly with star-functions. 3430 ! 3431 ! NB: The routines assume that the k-mesh for electrons and the q-mesh for phonons are the same. 3432 ! Thus we need to downsample the k-mesh if it's denser that the q-mesh. 3433 3434 new%use_doublegrid = .False. 3435 3436 ! ================================================================================================ 3437 ! Here we construct ebands_dense for the double grid either from WFK file or via SKW interpolation 3438 ! ================================================================================================ 3439 3440 if (dtset%getwfkfine /= 0 .or. dtset%irdwfkfine /= 0 .or. dtset%getwfkfine_filepath /= ABI_NOFILE) then 3441 3442 ! In principle only getwfkfine_filepath is used 3443 wfk_fname_dense = trim(dtfil%fnameabi_wfkfine) 3444 ABI_CHECK(nctk_try_fort_or_ncfile(wfk_fname_dense, msg) == 0, msg) 3445 call wrtout(units, "- EPH double grid interpolation: will read energies from: "//trim(wfk_fname_dense), newlines=1) 3446 3447 ebands_dense = wfk_read_ebands(wfk_fname_dense, comm) 3448 3449 ! TODO add consistency check: number of bands and kpoints (commensurability) 3450 !if (ebands_dense%is_commensurate(msg) /= 0) 3451 ABI_CHECK_IEQ(ebands_dense%mband, ebands%mband, "Inconsistent number of bands for the fine and dense grid:") 3452 new%use_doublegrid = .True. 3453 3454 else if (any(dtset%bs_interp_kmult /= 0)) then 3455 3456 ! Read bs_interpmult 3457 call wrtout(units, " EPH interpolation: will use star functions interpolation.", newlines=1) 3458 ! Interpolate band energies with star-functions 3459 params = 0; params(1) = 1; params(2) = 5 3460 if (nint(dtset%einterp(1)) == 1) params = dtset%einterp 3461 !write(std_out, "(a, 4(f5.2, 2x))")" SKW parameters for double-grid:", params 3462 3463 !TODO: mband should be min of nband 3464 band_block = [1, ebands%mband] 3465 ! TODO: Now we should use this band range. 3466 ! Note that we start from 1 because we are gonna use ebands_dense to compute the Fermi level. 3467 !band_block = [1, new%bsum_stop] 3468 intp_kptrlatt(:,1) = [ebands%kptrlatt(1,1)*dtset%bs_interp_kmult(1), 0, 0] 3469 intp_kptrlatt(:,2) = [0, ebands%kptrlatt(2,2)*dtset%bs_interp_kmult(2), 0] 3470 intp_kptrlatt(:,3) = [0, 0, ebands%kptrlatt(3,3)*dtset%bs_interp_kmult(3)] 3471 3472 intp_nshiftk = 1; intp_shiftk = zero 3473 ebands_dense = ebands_interp_kmesh(ebands, cryst, params, intp_kptrlatt, & 3474 intp_nshiftk, intp_shiftk, band_block, comm) 3475 new%use_doublegrid = .True. 3476 end if 3477 3478 if (new%use_doublegrid) then 3479 ! Note that we don't recompute %fermie and %occ in ebands_dense, only %nelect must be consistent with the 3480 ! input ebands to handle possible doping 3481 ebands_dense%nelect = ebands%nelect 3482 ebands_dense%fermie = ebands%fermie 3483 if (abs(dtset%mbpt_sciss) > tol6) then 3484 ! Apply the scissor operator to the dense mesh 3485 call wrtout(std_out, sjoin(" Apply the scissor operator to the dense CB with:",ftoa(dtset%mbpt_sciss))) 3486 call ebands_apply_scissors(ebands_dense, dtset%mbpt_sciss) 3487 end if 3488 end if 3489 3490 ! Build object used to compute integration weights taking into account double-grid. 3491 ! Note that we compute the weights only for the states included in the sum 3492 ! bstart and new%bsum_comm select the band range. 3493 ! TODO: 3494 ! 1) Should recheck the case bstart > 1 with star functions as I got weird results. 3495 ! 2) Should refactor ephwg so that only my_npert phonons are stored in the datatype. 3496 bstart = new%bsum_start 3497 3498 if (new%qint_method > 0) then 3499 ! Tetra 3500 if (new%use_doublegrid) then 3501 ! Double-grid technique from ab-initio energies or star-function interpolation. 3502 new%ephwg = ephwg_from_ebands(cryst, ifc, ebands_dense, bstart, new%nbsum, comm) 3503 new%eph_doublegrid = eph_double_grid_new(cryst, ebands_dense, ebands%kptrlatt, ebands_dense%kptrlatt) 3504 else 3505 downsample = any(ebands%kptrlatt /= qptrlatt) .or. ebands%nshiftk /= my_nshiftq 3506 if (ebands%nshiftk == my_nshiftq) downsample = downsample .or. any(ebands%shiftk /= my_shiftq) 3507 if (downsample) then 3508 ABI_COMMENT("K-mesh != Q-mesh for self-energy. Will downsample electron energies.") 3509 tmp_ebands = ebands_downsample(ebands, cryst, qptrlatt, my_nshiftq, my_shiftq) 3510 new%ephwg = ephwg_from_ebands(cryst, ifc, tmp_ebands, bstart, new%nbsum, comm) 3511 call ebands_free(tmp_ebands) 3512 else 3513 new%ephwg = ephwg_from_ebands(cryst, ifc, ebands, bstart, new%nbsum, comm) 3514 end if 3515 end if 3516 3517 else 3518 ! Standard quadrature. 3519 if (new%use_doublegrid) then 3520 new%eph_doublegrid = eph_double_grid_new(cryst, ebands_dense, ebands%kptrlatt, ebands_dense%kptrlatt) 3521 new%ephwg = ephwg_from_ebands(cryst, ifc, ebands_dense, bstart, new%nbsum, comm) 3522 endif 3523 end if 3524 3525 call cwtime_report(" sigmaph_new: after doublegrid", cpu, wall, gflops) 3526 3527 ! Compute the chemical potential at the different physical temperatures with Fermi-Dirac. 3528 ABI_MALLOC(new%mu_e, (new%ntemp)) 3529 new%mu_e(:) = ebands%fermie 3530 3531 if (dtset%eph_fermie == zero) then 3532 ! TODO: Optimize this part 3533 ! grep "TIME" /home/acad/ucl-naps/gbrunin/GaP_FHI/mobility/conv_fine/v9/k144x144x144/q288x288x288/log | grep get_mu get_mu_e completed. cpu: 06:02 [minutes] , wall: 06:02 [minutes] <<< TIME 3534 3535 call cwtime(cpu, wall, gflops, "start") 3536 if (new%use_doublegrid) then 3537 call ebands_get_muT_with_fd(ebands_dense, new%ntemp, new%ktmesh, dtset%spinmagntarget, dtset%prtvol, new%mu_e, comm) 3538 else 3539 call ebands_get_muT_with_fd(ebands, new%ntemp, new%ktmesh, dtset%spinmagntarget, dtset%prtvol, new%mu_e, comm) 3540 end if 3541 3542 call cwtime_report(" get_mu_e", cpu, wall, gflops) 3543 endif 3544 3545 call ebands_free(ebands_dense) 3546 3547 if (my_rank == master) then 3548 msg = "Gaps, band edges and relative position wrt Fermi level" 3549 call gaps%print(unit=std_out, kTmesh=new%ktmesh, mu_e=new%mu_e, header=msg) 3550 call gaps%print(unit=ab_out, kTmesh=new%ktmesh, mu_e=new%mu_e, header=msg) 3551 end if 3552 call gaps%free() 3553 3554 ! Prepare computation of Frohlich self-energy 3555 ! TODO: Reintegrate at least frohl_model 1 for the full self-energy 3556 new%frohl_model = 0 3557 new%ntheta = abs(dtset%eph_frohl_ntheta) 3558 !print *, "ntheta:", new%ntheta; stop 3559 if (.not. new%imag_only .and. new%ntheta > 0) then 3560 new%frohl_model = 1 3561 !if (.not. dvdb%has_zeff) new%frohl_model = 0 3562 end if 3563 3564 if (new%frohl_model /= 0) then 3565 ! Set angular mesh for numerical integration inside micro BZ around Gamma. 3566 new%nphi = 2 * new%ntheta 3567 write(std_out,"(a)")" Activating computation of Frohlich self-energy:" 3568 write(std_out,"(2(a,i0,1x))")" ntheta: ", new%ntheta, "nphi: ", new%nphi 3569 3570 ! Initialize angular mesh qvers_cart and angwgth 3571 ! NB: summing over f * angwgth gives the spherical average 1/(4pi) \int domega f(omega) 3572 call ylm_angular_mesh(new%ntheta, new%nphi, new%angl_size, new%qvers_cart, new%angwgth) 3573 end if 3574 3575 if (new%mrta > 0) then 3576 ABI_CALLOC(new%linewidth_mrta, (new%ntemp, new%max_nbcalc)) 3577 end if 3578 3579 call cwtime_report(" sigmaph_new: all", cpu_all, wall_all, gflops_all) 3580 3581 end function sigmaph_new
m_sigmaph/sigmaph_print [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_print
FUNCTION
Print self-energy and QP corrections for given (k-point, spin).
INPUTS
dtset<dataset_type>=All input variables for this dataset. unt=Fortran unit number
SOURCE
5311 subroutine sigmaph_print(self, dtset, unt) 5312 5313 !Arguments ------------------------------------ 5314 integer,intent(in) :: unt 5315 type(dataset_type),intent(in) :: dtset 5316 class(sigmaph_t),intent(in) :: self 5317 5318 !Local variables------------------------------- 5319 integer :: ikc, is, ndiv 5320 character(len=5000) :: msg 5321 5322 ! ************************************************************************* 5323 5324 if (unt == dev_null) return 5325 5326 ! Write dimensions 5327 write(unt,"(/,a)")sjoin(" Number of bands in e-ph self-energy sum:", itoa(self%nbsum)) 5328 write(unt,"(a)")sjoin(" From bsum_start:", itoa(self%bsum_start), "to bsum_stop:", itoa(self%bsum_stop)) 5329 if (dtset%eph_stern /= 0 .and. .not. self%imag_only) then 5330 write(unt, "(a)")" Treating high-energy bands with Sternheimer and static self-energy." 5331 write(unt, "(a, es16.6, a, i0)")" Tolwfr:", dtset%tolwfr, ", nline: ", dtset%nline 5332 end if 5333 write(unt,"(a)")sjoin(" Symsigma: ",itoa(self%symsigma), "Timrev:", itoa(self%timrev)) 5334 if (.not. (self%qint_method == 1 .and. self%imag_only)) then 5335 write(unt,"(a)")sjoin(" Imaginary shift in the denominator (zcut): ", ftoa(aimag(self%ieta) * Ha_eV, fmt="f5.3"), "[eV]") 5336 end if 5337 msg = " Standard quadrature"; if (self%qint_method == 1) msg = " Tetrahedron method" 5338 write(unt, "(2a)")sjoin(" Method for q-space integration:", msg) 5339 if (self%qint_method == 1) then 5340 ndiv = 1; if (self%use_doublegrid) ndiv = self%eph_doublegrid%ndiv 5341 write(unt, "(a, 2(es16.6,1x))")" Tolerance for integration weights < ", dtset%eph_tols_idelta(:) / ndiv 5342 write(unt, "(a, (f5.2,1x))")" eph_phwinfact: ", self%phwinfact 5343 end if 5344 if (self%use_doublegrid) write(unt, "(a, i0)")" Using double grid technique with ndiv: ", self%eph_doublegrid%ndiv 5345 if (self%imag_only) write(unt, "(a)")" Only the Imaginary part of Sigma will be computed." 5346 if (.not. self%imag_only) write(unt, "(a)")" Both Real and Imaginary part of Sigma will be computed." 5347 write(unt,"(a)")sjoin(" Number of frequencies along the real axis:", itoa(self%nwr), & 5348 ", Step:", ftoa(self%wr_step * Ha_eV, fmt="f5.3"), "[eV]") 5349 if (dtset%prteliash /= 0) then 5350 write(unt, "(a)")sjoin(" Number of frequency in generalized Eliashberg functions:", itoa(self%phmesh_size)) 5351 else 5352 write(unt, "(a)")" Number of frequency in generalized Eliashberg functions: 0" 5353 end if 5354 write(unt,"(a)")sjoin(" Number of temperatures:", itoa(self%ntemp), & 5355 "From:", ftoa(self%kTmesh(1) / kb_HaK), "to", ftoa(self%kTmesh(self%ntemp) / kb_HaK), "[K]") 5356 write(unt,"(a)")sjoin(" Ab-initio q-mesh from DDB file:", ltoa(dtset%ddb_ngqpt)) 5357 write(unt,"(a)")sjoin(" Q-mesh used for self-energy integration [ngqpt]:", ltoa(self%ngqpt)) 5358 write(unt,"(a)")sjoin(" Number of q-points in the IBZ:", itoa(self%nqibz)) 5359 write(unt,"(a)")sjoin(" asr:", itoa(dtset%asr), "chneut:", itoa(dtset%chneut)) 5360 write(unt,"(a)")sjoin(" dipdip:", itoa(dtset%dipdip), "symdynmat:", itoa(dtset%symdynmat)) 5361 5362 if (.not. self%imag_only) then 5363 select case (self%frohl_model) 5364 case (0) 5365 !write(unt,"(a)")" No special treatment for the integration of the Frohlich divergence in the microzone around Gamma" 5366 case (1) 5367 write(unt,"(a)")" Integrating Frohlich model in small sphere around Gamma to accelerate qpt convergence" 5368 write(unt,"(2(a,i0,1x))")" Sperical integration performed with: ntheta: ", self%ntheta, ", nphi: ", self%nphi 5369 case default 5370 ABI_ERROR(sjoin("Invalid value of frohl_mode:", itoa(self%frohl_model))) 5371 end select 5372 end if 5373 5374 write(unt,"(a, i0)")" Number of k-points for self-energy corrections: ", self%nkcalc 5375 if (any(abs(dtset%sigma_erange) /= zero)) then 5376 write(unt, "(a, 2(f6.3, 1x), a)")" sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)" 5377 end if 5378 if (self%imag_only .and. self%qint_method == 1) then 5379 write(unt,"(a, 2(f5.3, 1x), a)")" Including all final {mk+q} states inside energy window: [", & 5380 self%elow * Ha_eV, self%ehigh * Ha_eV, "] [eV]" 5381 end if 5382 write(unt,"(a)")" List of k-points for self-energy corrections:" 5383 do ikc=1,self%nkcalc 5384 if (ikc > 10) then 5385 write(unt, "(2a)")" nkcalc > 10. Stop printing more k-point information.",ch10 5386 exit 5387 end if 5388 do is=1,self%nsppol 5389 if (self%nsppol == 2) write(unt,"(a,i1,a)")" For spin: ",is, ", ikcalc, spin, kpt, bstart, bstop" 5390 write(unt, "(2(i4,2x),a,2(i4,1x))") & 5391 ikc, is, trim(ktoa(self%kcalc(:,ikc))), self%bstart_ks(ikc,is), self%bstart_ks(ikc,is) + self%nbcalc_ks(ikc,is) - 1 5392 end do 5393 end do 5394 5395 write(unt, "(/,a)")" === MPI parallelism ===" 5396 write(unt, "(2(a,i0))")"P Allocating and summing bands from my_bsum_start: ", self%my_bsum_start, & 5397 " up to my_bsum_stop: ", self%my_bsum_stop 5398 write(unt, "(a,i0)")"P Number of CPUs for parallelism over perturbations: ", self%pert_comm%nproc 5399 write(unt, "(a,i0)")"P Number of perturbations treated by this CPU: ", self%my_npert 5400 write(unt, "(a,i0)")"P Number of CPUs for parallelism over q-points: ", self%qpt_comm%nproc 5401 write(unt, "(2(a,i0))")"P Number of q-points in the IBZ treated by this proc: " , & 5402 count(self%itreat_qibz == 1), " of ", self%nqibz 5403 write(unt, "(a,i0)")"P Number of CPUs for parallelism over bands: ", self%bsum_comm%nproc 5404 write(unt, "(a,i0)")"P Number of CPUs for parallelism over spins: ", self%spin_comm%nproc 5405 write(unt, "(a,i0)")"P Number of CPUs for parallelism over k-points: ", self%kcalc_comm%nproc 5406 write(unt, "(2(a,i0),/)")"P Number of k-point in Sigma_nk treated by this proc: ", self%my_nkcalc, " of ", self%nkcalc 5407 5408 end subroutine sigmaph_print
m_sigmaph/sigmaph_read [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_read
FUNCTION
Start an (incomplete) sigmaph instance from a netcdf file. This routine serves only to read some basic dimensions and parameters from the SIGEPH.nc file to 1. Verify whether a restart in sigmaph is possible when eph_restart == 1 2. Use these metadata in the RTA module to prepare the calculation of transport properties.
INPUTS
path= SIGEPH Filename. dtset<dataset_type>=All input variables for this dataset. comm=MPI communicator msg=Error message if ierr /= 0 ierr = Exit status [keep_open]=True to keep the Nc file handle open for further reading. Default: False. [extrael_fermie]: Return the value of (eph_extrael, eph_fermie) read from file. [sigma_ngkpt] = Value read from the ncfile (used in m_rta) [sigma_erange] = Value read from the ncfile (used in m_rta)
SOURCE
3864 type(sigmaph_t) function sigmaph_read(path, dtset, comm, msg, ierr, keep_open, & 3865 extrael_fermie, sigma_ngkpt, sigma_erange) result(new) 3866 3867 !Arguments ------------------------------------ 3868 integer,intent(in) :: comm 3869 integer,intent(out) :: ierr 3870 type(dataset_type),intent(in) :: dtset 3871 character(len=500),intent(out) :: msg 3872 real(dp), optional, intent(out) :: extrael_fermie(2) 3873 logical,optional,intent(in) :: keep_open 3874 integer,optional, intent(out) :: sigma_ngkpt(3) 3875 real(dp),optional,intent(out) :: sigma_erange(2) 3876 3877 !Local variables ------------------------------ 3878 !scalars 3879 integer :: imag_only, eph_task, symdynmat, ph_intmeth, eph_intmeth, eph_transport 3880 integer :: ncid !, varid !, ncerr 3881 real(dp) :: eph_fermie, eph_fsewin, ph_wstep, ph_smear, eta, eph_extrael, eph_fsmear, cpu, wall, gflops 3882 character(len=fnlen) :: path 3883 !arrays 3884 integer :: eph_ngqpt_fine(3), ddb_ngqpt(3), ph_ngqpt(3), my_sigma_ngkpt(3) 3885 real(dp) :: my_sigma_erange(2) 3886 3887 ! ************************************************************************* 3888 3889 ! Open netcdf file 3890 msg = "Netcdf not activated at configure time!" 3891 ierr = 1 3892 ierr = 0 3893 3894 if (.not. file_exists(path)) then 3895 msg = sjoin("Cannot find file", path) 3896 ierr = 1; return 3897 end if 3898 3899 call cwtime(cpu, wall, gflops, "start") 3900 NCF_CHECK(nctk_open_read(ncid, path, comm)) 3901 3902 !TODO? 3903 !NCF_CHECK(cryst%ncread(ncid)) 3904 !NCF_CHECK(ebands_ncread(ebands, ncid)) 3905 3906 ! Read sigma_eph dimensions. 3907 NCF_CHECK(nctk_get_dim(ncid, "nkcalc", new%nkcalc)) 3908 NCF_CHECK(nctk_get_dim(ncid, "max_nbcalc", new%max_nbcalc)) 3909 NCF_CHECK(nctk_get_dim(ncid, "nsppol", new%nsppol)) 3910 NCF_CHECK(nctk_get_dim(ncid, "ntemp", new%ntemp)) 3911 NCF_CHECK(nctk_get_dim(ncid, "nqibz", new%nqibz)) 3912 NCF_CHECK(nctk_get_dim(ncid, "nqbz", new%nqbz)) 3913 !NCF_CHECK(nctk_get_dim(ncid, "nwr", new%nwr)) 3914 !NCF_CHECK(nctk_get_dim(ncid, "phmesh_size", new%phmesh_size)) 3915 3916 ! ====================================================== 3917 ! Read data that does not depend on the (kpt, spin) loop. 3918 ! ====================================================== 3919 NCF_CHECK(nf90_get_var(ncid, vid("symsigma"), new%symsigma)) 3920 NCF_CHECK(nf90_get_var(ncid, vid("nbsum"), new%nbsum)) 3921 NCF_CHECK(nf90_get_var(ncid, vid("bsum_start"), new%bsum_start)) 3922 NCF_CHECK(nf90_get_var(ncid, vid("bsum_stop"), new%bsum_stop)) 3923 3924 NCF_CHECK(nf90_get_var(ncid, vid("qint_method"), new%qint_method)) 3925 !NCF_CHECK(nf90_get_var(ncid, vid("frohl_model"), new%frohl_model)) 3926 NCF_CHECK(nf90_get_var(ncid, vid("imag_only"), imag_only)) 3927 new%imag_only = (imag_only == 1) 3928 NCF_CHECK(nf90_get_var(ncid, vid("mrta"), new%mrta)) 3929 3930 ABI_MALLOC(new%kcalc, (3, new%nkcalc)) 3931 ABI_MALLOC(new%bstart_ks, (new%nkcalc, new%nsppol)) 3932 ABI_MALLOC(new%bstop_ks, (new%nkcalc, new%nsppol)) 3933 ABI_MALLOC(new%nbcalc_ks, (new%nkcalc, new%nsppol)) 3934 ABI_MALLOC(new%mu_e, (new%ntemp)) 3935 ABI_MALLOC(new%kTmesh, (new%ntemp)) 3936 ABI_MALLOC(new%kcalc2ibz, (new%nkcalc, 6)) 3937 3938 NCF_CHECK(nf90_get_var(ncid, vid("ngqpt"), new%ngqpt)) 3939 NCF_CHECK(nf90_get_var(ncid, vid("bstart_ks"), new%bstart_ks)) 3940 NCF_CHECK(nf90_get_var(ncid, vid("nbcalc_ks"), new%nbcalc_ks)) 3941 new%bstop_ks = new%bstart_ks + new%nbcalc_ks - 1 3942 3943 NCF_CHECK(nf90_get_var(ncid, vid("kcalc"), new%kcalc)) 3944 NCF_CHECK(nf90_get_var(ncid, vid("kcalc2ibz"), new%kcalc2ibz)) 3945 NCF_CHECK(nf90_get_var(ncid, vid("kTmesh"), new%kTmesh)) 3946 NCF_CHECK(nf90_get_var(ncid, vid("wr_step"), new%wr_step)) 3947 NCF_CHECK(nf90_get_var(ncid, vid("mu_e"), new%mu_e)) 3948 NCF_CHECK(nf90_get_var(ncid, vid("eta"), eta)) 3949 new%ieta = j_dpc * eta 3950 3951 ! Read the done array used to implement restart capabilities. 3952 ABI_ICALLOC(new%qp_done, (new%nkcalc, new%nsppol)) 3953 NCF_CHECK(nf90_get_var(ncid, vid("qp_done"), new%qp_done)) 3954 3955 ! ============================================================ 3956 ! Read and check consistency against dtset 3957 ! ============================================================ 3958 NCF_CHECK(nf90_get_var(ncid, vid("eph_fsewin"), eph_fsewin)) 3959 NCF_CHECK(nf90_get_var(ncid, vid("eph_fsmear"), eph_fsmear)) 3960 NCF_CHECK(nf90_get_var(ncid, vid("eph_extrael"), eph_extrael)) 3961 NCF_CHECK(nf90_get_var(ncid, vid("eph_fermie"), eph_fermie)) 3962 NCF_CHECK(nf90_get_var(ncid, vid("ph_wstep"), ph_wstep)) 3963 NCF_CHECK(nf90_get_var(ncid, vid("ph_smear"), ph_smear)) 3964 ABI_CHECK(eph_fsewin == dtset%eph_fsewin, "netcdf eph_fsewin != input file") 3965 ABI_CHECK(eph_fsmear == dtset%eph_fsmear, "netcdf eph_fsmear != input file") 3966 ABI_CHECK(ph_wstep == dtset%ph_wstep, "netcdf ph_wstep != input file") 3967 ABI_CHECK(ph_smear == dtset%ph_smear, "netcdf ph_smear != input file") 3968 3969 if (present(extrael_fermie)) then 3970 extrael_fermie = [eph_extrael, eph_fermie] 3971 else 3972 ABI_CHECK_DEQ(eph_extrael, dtset%eph_extrael, "netcdf eph_extrael != input file") 3973 ABI_CHECK_DEQ(eph_fermie, dtset%eph_fermie, "netcdf eph_feremie != input file") 3974 end if 3975 3976 NCF_CHECK(nf90_get_var(ncid, vid("eph_task"), eph_task)) 3977 NCF_CHECK(nf90_get_var(ncid, vid("symdynmat"), symdynmat)) 3978 NCF_CHECK(nf90_get_var(ncid, vid("ph_intmeth"), ph_intmeth)) 3979 NCF_CHECK(nf90_get_var(ncid, vid("eph_intmeth"), eph_intmeth)) 3980 NCF_CHECK(nf90_get_var(ncid, vid("eph_transport"), eph_transport)) 3981 3982 if (dtset%eph_task==-4 .or. dtset%eph_task==4) then 3983 ABI_CHECK_IEQ(symdynmat, dtset%symdynmat, "netcdf symdynmat != input file") 3984 ABI_CHECK_IEQ(ph_intmeth, dtset%ph_intmeth, "netcdf ph_intmeth != input file") 3985 ABI_CHECK_IEQ(eph_intmeth, dtset%eph_intmeth, "netcdf eph_intmeth != input file") 3986 ABI_CHECK_IEQ(eph_transport, dtset%eph_transport, "netcdf eph_transport != input file") 3987 endif 3988 3989 !NCF_CHECK(nf90_get_var(ncid, vid("frohl_params"), frohl_params)) 3990 NCF_CHECK(nf90_get_var(ncid, vid("eph_ngqpt_fine"), eph_ngqpt_fine)) 3991 NCF_CHECK(nf90_get_var(ncid, vid("ddb_ngqpt"), ddb_ngqpt)) 3992 NCF_CHECK(nf90_get_var(ncid, vid("ph_ngqpt"), ph_ngqpt)) 3993 NCF_CHECK(nf90_get_var(ncid, vid("sigma_ngkpt"), my_sigma_ngkpt)) 3994 if (present(sigma_ngkpt)) then 3995 sigma_ngkpt = my_sigma_ngkpt 3996 else 3997 ABI_CHECK(all(dtset%sigma_ngkpt == my_sigma_ngkpt), "netcdf sigma_ngkpt != input file") 3998 end if 3999 4000 NCF_CHECK(nf90_get_var(ncid, vid("sigma_erange"), my_sigma_erange)) 4001 if (present(sigma_erange)) then 4002 sigma_erange = my_sigma_erange 4003 else 4004 ABI_CHECK(all(dtset%sigma_erange == my_sigma_erange), "netcdf sigma_erange != input file") 4005 end if 4006 4007 if (present(keep_open)) then 4008 new%ncid = ncid 4009 else 4010 NCF_CHECK(nf90_close(ncid)) 4011 ! so that the structure is properly freed 4012 new%ncid = nctk_noid 4013 end if 4014 4015 ABI_CHECK(all(dtset%eph_ngqpt_fine == eph_ngqpt_fine),"netcdf eph_ngqpt_fine != input file") 4016 ABI_CHECK(all(dtset%ddb_ngqpt == ddb_ngqpt), "netcdf ddb_ngqpt != input file") 4017 ABI_CHECK(all(dtset%ph_ngqpt == ph_ngqpt), "netcdf ph_ngqpt != input file") 4018 !ABI_CHECK(all(abs(dtset%frohl_params - frohl_params) < tol6), "netcdf frohl_params != input file") 4019 4020 call cwtime_report(" sigmaph_read", cpu, wall, gflops) 4021 4022 contains 4023 integer function vid(vname) 4024 character(len=*),intent(in) :: vname 4025 vid = nctk_idname(ncid, vname) 4026 end function vid 4027 4028 end function sigmaph_read
m_sigmaph/sigmaph_setup_kcalc [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_setup_kcalc
FUNCTION
Prepare calculations of self-energy matrix elements for ikcalc index.
INPUTS
dtset<dataset_type>=All input variables for this dataset. cryst<crystal_t> = Crystal structure. dvdb<dbdb_type>=Database with the DFPT SCF potentials. ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) ikcalc=Index of the k-point to compute. prtvol= Verbosity level comm= MPI communicator
SOURCE
4339 subroutine sigmaph_setup_kcalc(self, dtset, cryst, ebands, ikcalc, prtvol, comm) 4340 4341 !Arguments ------------------------------------ 4342 integer,intent(in) :: ikcalc, prtvol, comm 4343 type(dataset_type),intent(in) :: dtset 4344 type(crystal_t),intent(in) :: cryst 4345 class(sigmaph_t),target,intent(inout) :: self 4346 type(ebands_t),intent(in) :: ebands 4347 4348 !Local variables------------------------------- 4349 integer,parameter :: master = 0 4350 integer :: spin, my_rank, iq_ibz, nprocs, qtimrev, qptopt !, nbcalc_ks !, bstart_ks 4351 integer :: ikpt, ibz_k, isym_k, itim_k !isym_lgk, 4352 real(dp) :: cpu, wall, gflops 4353 character(len=5000) :: msg 4354 logical :: compute_lgk 4355 type(lgroup_t),target :: lgk 4356 type(lgroup_t),pointer :: lgk_ptr 4357 type(krank_t) :: krank, qrank 4358 !arrays 4359 integer :: qptrlatt(3,3) 4360 integer,allocatable :: iqk2dvdb(:,:) 4361 real(dp) :: kk(3) 4362 real(dp),allocatable :: kq_list(:,:) 4363 4364 ! ************************************************************************* 4365 4366 ABI_SFREE(self%qibz_k) 4367 ABI_SFREE(self%wtq_k) 4368 4369 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 4370 kk = self%kcalc(:, ikcalc) 4371 4372 call wrtout(std_out, sjoin(ch10, repeat("=", 92))) 4373 msg = sjoin("[", itoa(ikcalc), "/", itoa(self%nkcalc), "]") 4374 call wrtout(std_out, sjoin(" Computing self-energy matrix elements for k-point:", ktoa(kk), msg)) 4375 ! TODO Integrate with spin parallelism. 4376 spin = 1 4377 write(msg, "(3(a, i0))")" Treating ", self%nbcalc_ks(ikcalc, spin), " band(s) in Sigma_nk between: ", & 4378 self%bstart_ks(ikcalc, spin)," and: ", self%bstart_ks(ikcalc, spin) + self%nbcalc_ks(ikcalc, spin) - 1 4379 call wrtout(std_out, msg) 4380 write(msg, "(2(a,i0))")"P Allocating and summing bands from my_bsum_start: ", self%my_bsum_start, & 4381 " up to my_bsum_stop: ", self%my_bsum_stop 4382 call wrtout(std_out, msg) 4383 if (.not. self%imag_only .and. dtset%eph_stern /= 0) then 4384 if (dtset%eph_stern == 1) call wrtout(std_out, " Sternheimer method activated with cache for u1_nk") 4385 if (dtset%eph_stern == -1) call wrtout(std_out, " Sternheimer method activated WITHOUT cache for u1_nk!") 4386 end if 4387 4388 ! Prepare weights for BZ(k) integration 4389 if (self%qint_method > 0) then 4390 if (self%use_doublegrid) then 4391 call self%ephwg%double_grid_setup_kpoint(self%eph_doublegrid, kk, prtvol, comm) 4392 else 4393 call self%ephwg%setup_kpoint(kk, prtvol, comm, skip_mapping=.true.) 4394 end if 4395 call self%ephwg%report_stats() 4396 endif 4397 4398 call cwtime(cpu, wall, gflops, "start") 4399 4400 if (self%symsigma == 0) then 4401 ! Do not use symmetries in BZ sum_q --> nqibz_k == nqbz 4402 self%nqibz_k = self%nqbz 4403 ABI_MALLOC(self%qibz_k, (3, self%nqibz_k)) 4404 ABI_MALLOC(self%wtq_k, (self%nqibz_k)) 4405 self%qibz_k = self%qbz; self%wtq_k = one / self%nqbz 4406 call wrtout(std_out, sjoin(" symsigma = 0 --> Integration done over full BZ with nqbz:", itoa(self%nqibz_k))) 4407 4408 ! Store little group symmetries (well, just 1) 4409 self%lgk_nsym = 1 4410 ABI_REMALLOC(self%lgk_sym2glob, (2, self%lgk_nsym)) 4411 self%lgk_sym2glob(:, 1) = [1, 1] 4412 4413 else if (abs(self%symsigma) == 1) then 4414 ! Use the symmetries of the little group of the k-point 4415 ! Pack points in *shells* to minimise cache misses. 4416 compute_lgk = .not. (self%qint_method > 0 .and. .not. self%use_doublegrid) 4417 if (compute_lgk) then 4418 lgk = lgroup_new(cryst, kk, self%timrev, self%nqbz, self%qbz, self%nqibz, self%qibz, comm) 4419 lgk_ptr => lgk 4420 else 4421 ! Avoid this call to lgroup new. Use lgk already computed in self%ephwg 4422 lgk_ptr => self%ephwg%lgk 4423 end if 4424 4425 ! Store little group symmetries. 4426 self%lgk_nsym = lgk_ptr%nsym_lg 4427 ABI_REMALLOC(self%lgk_sym2glob, (2, self%lgk_nsym)) 4428 self%lgk_sym2glob = lgk_ptr%lgsym2glob 4429 4430 call wrtout(std_out, sjoin(" Number of operations in little group(k):", itoa(lgk_ptr%nsym_lg), & 4431 "(including time-reversal symmetry)")) 4432 call wrtout(std_out, sjoin(" Number of q-points in the IBZ(k):", itoa(lgk_ptr%nibz))) 4433 4434 if (dtset%prtvol > 0) call lgk_ptr%print(unit=std_out, prtvol=dtset%prtvol) 4435 4436 ! TODO: Pointers instead of copies to save space? 4437 self%nqibz_k = lgk_ptr%nibz 4438 ABI_MALLOC(self%qibz_k, (3, self%nqibz_k)) 4439 ABI_MALLOC(self%wtq_k, (self%nqibz_k)) 4440 self%qibz_k = lgk_ptr%ibz; self%wtq_k = lgk_ptr%weights 4441 !if (compute_lgk) call lgk%free() 4442 else 4443 ABI_ERROR(sjoin("Wrong symsigma:", itoa(self%symsigma))) 4444 end if 4445 4446 call cwtime_report(" lgroup_symsigma", cpu, wall, gflops) 4447 4448 ! TODO: Cleanup 4449 4450 if (self%symsigma == 0) then 4451 ! Find correspondence IBZ_k --> IBZ 4452 ABI_MALLOC(iqk2dvdb, (6, self%nqibz_k)) 4453 4454 ! Assume qptopt == kptopt unless value is specified in input 4455 qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt 4456 qtimrev = kpts_timrev_from_kptopt(qptopt) 4457 qptrlatt = 0; qptrlatt(1,1) = self%ngqpt(1); qptrlatt(2,2) = self%ngqpt(2); qptrlatt(3,3) = self%ngqpt(3) 4458 qrank = krank_from_kptrlatt(self%nqibz, self%qibz, qptrlatt, compute_invrank=.False.) 4459 4460 if (kpts_map("symrec", qtimrev, cryst, qrank, self%nqibz_k, self%qibz_k, iqk2dvdb) /= 0) then 4461 write(msg, '(3a)' )& 4462 "At least one of the q points in the IBZ_k could not be generated from one in the IBZ.", ch10,& 4463 "Action: check your DVDB file and use eph_task to interpolate the potentials on a denser q-mesh." 4464 ABI_ERROR(msg) 4465 end if 4466 call qrank%free() 4467 4468 ABI_REMALLOC(self%ind_ibzk2ibz, (6, self%nqibz_k)) 4469 do iq_ibz=1,self%nqibz_k 4470 self%ind_ibzk2ibz(:, iq_ibz) = iqk2dvdb(:, iq_ibz) 4471 end do 4472 ABI_FREE(iqk2dvdb) 4473 4474 else if (abs(self%symsigma) == 1) then 4475 4476 ! IBZ_k --> BZ --> IBZ 4477 ABI_REMALLOC(self%ind_ibzk2ibz, (6, self%nqibz_k)) 4478 self%ind_ibzk2ibz = 0 4479 do ikpt=1,self%nqbz 4480 ibz_k = lgk_ptr%bz2ibz_smap(1,ikpt) 4481 !isym_lgk = lgk_ptr%bz2ibz_smap(2,ikpt) 4482 !isym_k = lgk_ptr%lgsym2glob(1,isym_lgk) 4483 !itim_k = lgk_ptr%lgsym2glob(2,isym_lgk) 4484 isym_k = lgk_ptr%bz2ibz_smap(2,ikpt) 4485 itim_k = lgk_ptr%bz2ibz_smap(3,ikpt) 4486 ! I assume that isym=1 and itim_k=0 is identity but still verify the kpoint 4487 if (isym_k /= 1 .or. itim_k /= 1 .or. any(lgk_ptr%bz2ibz_smap(4:,ikpt) /= 0)) cycle 4488 ! check IBZ_k --> BZ 4489 ABI_CHECK(sum(abs(self%qbz(:,ikpt) - self%qibz_k(:,ibz_k))) < tol8, 'Wrong mapping') 4490 ! IBZ_k --> IBZ 4491 !self%ind_ibzk2ibz(:, ibz_k) = self%ind_qbz2ibz(:,ikpt) 4492 self%ind_ibzk2ibz(1, ibz_k) = self%ind_qbz2ibz(1, ikpt) 4493 self%ind_ibzk2ibz(2, ibz_k) = self%ind_qbz2ibz(2, ikpt) 4494 self%ind_ibzk2ibz(6, ibz_k) = self%ind_qbz2ibz(3, ikpt) 4495 self%ind_ibzk2ibz(3:5, ibz_k) = self%ind_qbz2ibz(4:6, ikpt) 4496 end do 4497 do ikpt=1,self%nqibz_k 4498 ABI_CHECK(self%ind_ibzk2ibz(1, ikpt) /= 0, 'Did not find mapping') 4499 end do 4500 if (compute_lgk) call lgk%free() 4501 else 4502 ABI_ERROR(sjoin("Wrong symsigma:", itoa(self%symsigma))) 4503 endif 4504 4505 call cwtime_report(" IBZ_k --> IBZ", cpu, wall, gflops) 4506 4507 if (.not. self%use_ftinterp) then 4508 ! Find correspondence IBZ_k --> set of q-points in DVDB. 4509 ! Need to handle q_bz = S q_ibz by symmetrizing the potentials already available in the DVDB. 4510 ! 4511 ! Note: 4512 ! q --> -q symmetry is always used for phonons. 4513 ! we use symrec instead of symrel (see also m_dvdb) 4514 ! IBZ_K -> BZ -> IBZ -> DVDB 4515 ABI_REMALLOC(self%ind_q2dvdb_k, (6, self%nqibz_k)) 4516 self%ind_q2dvdb_k = self%ind_ibzk2ibz 4517 do ikpt=1,self%nqibz_k 4518 self%ind_q2dvdb_k(1, ikpt) = self%qibz2dvdb(self%ind_ibzk2ibz(1, ikpt)) 4519 end do 4520 call cwtime_report(" IBZ_k --> DVDB", cpu, wall, gflops) 4521 end if 4522 4523 ! Find k+q in the extended zone and extract symmetry info. 4524 ! Be careful here because there are two umklapp vectors to be considered: 4525 ! 4526 ! k + q = k_bz + g0_bz = IS(k_ibz) + g0_ibz + g0_bz 4527 ! 4528 ! Note symrel and use_symrec=.False. in get_mapping. 4529 ! This means that this table can be used to symmetrize wavefunctions in cgtk_rotate. 4530 ! 4531 ABI_MALLOC(kq_list, (3, self%nqibz_k)) 4532 do iq_ibz=1,self%nqibz_k 4533 kq_list(:, iq_ibz) = kk + self%qibz_k(:,iq_ibz) 4534 end do 4535 4536 ! Use iqk2dvdb as workspace array. 4537 ABI_MALLOC(iqk2dvdb, (6, self%nqibz_k)) 4538 4539 krank = krank_from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.) 4540 4541 if (kpts_map("symrel", self%timrev, cryst, krank, self%nqibz_k, kq_list, iqk2dvdb) /= 0) then 4542 write(msg, '(11a)' )& 4543 "The WFK file cannot be used to compute self-energy corrections at k: ", trim(ktoa(kk)), ch10,& 4544 "At least one of the k+q points could not be generated from a symmetrical one.", ch10,& 4545 "Q-mesh: ",trim(ltoa(self%ngqpt)),", K-mesh (from kptrlatt) ",trim(ltoa(get_diag(dtset%kptrlatt))),ch10, & 4546 "Action: check your WFK file and the k/q point input variables." 4547 ABI_ERROR(msg) 4548 end if 4549 4550 call krank%free() 4551 4552 ABI_FREE(kq_list) 4553 4554 ABI_REMALLOC(self%indkk_kq, (6, self%nqibz_k)) 4555 do iq_ibz=1,self%nqibz_k 4556 self%indkk_kq(:, iq_ibz) = iqk2dvdb(:,iq_ibz) 4557 end do 4558 ABI_FREE(iqk2dvdb) 4559 4560 call cwtime_report(" k+q --> ebands", cpu, wall, gflops) 4561 4562 if (self%qint_method > 0 .and. .not. self%use_doublegrid) then 4563 ABI_REMALLOC(self%ephwg%lgk2ibz, (self%nqibz_k)) 4564 self%ephwg%lgk2ibz = self%ind_ibzk2ibz(1, :) 4565 ABI_REMALLOC(self%ephwg%kq2ibz, (self%nqibz_k)) 4566 self%ephwg%kq2ibz = self%indkk_kq(1, :) 4567 end if 4568 4569 end subroutine sigmaph_setup_kcalc
m_sigmaph/sigmaph_setup_qloop [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_setup_qloop
FUNCTION
Prepare integration of self-energy matrix in q-space for given (spin, ikcalc) Distribute q-points and precompute weights if tetrahedron method and imag_only
INPUTS
dtset<dataset_type>=All input variables for this dataset. cryst<crystal_t> = Crystal structure. ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) dvdb<dbdb_type>=Database with the DFPT SCF potentials. spin: spin index. ikcalc=Index of the k-point to compute. nfftf=Number of fft-points on the fine grid for interpolated potential ngfftf(18)=information on 3D FFT for interpolated potential comm= MPI communicator
SOURCE
4629 subroutine sigmaph_setup_qloop(self, dtset, cryst, ebands, dvdb, spin, ikcalc, nfftf, ngfftf, comm) 4630 4631 !Arguments ------------------------------------ 4632 integer,intent(in) :: spin, ikcalc, nfftf, comm 4633 type(dataset_type),intent(in) :: dtset 4634 type(crystal_t),intent(in) :: cryst 4635 class(sigmaph_t),intent(inout) :: self 4636 type(ebands_t),intent(in) :: ebands 4637 type(dvdb_t),intent(inout) :: dvdb 4638 !arrays 4639 integer,intent(in) :: ngfftf(18) 4640 4641 !Local variables------------------------------- 4642 integer,parameter :: master = 0 4643 integer :: my_rank, iq_ibz_k, iq_ibz, ierr, nprocs, imyq, iq_dvdb, ii, cnt, itreat, iq, nqeff, ndiv 4644 integer :: min_nqibz_k, max_nqibz_k 4645 real(dp) :: cpu, wall, gflops, efact_min, efact_max 4646 logical :: qfilter 4647 character(len=5000) :: msg 4648 !arrays 4649 integer,allocatable :: mask_qibz_k(:), imask(:), qtab(:), ineed_qibz(:), ineed_qdvdb(:) 4650 4651 ! ************************************************************************* 4652 4653 my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm) 4654 4655 msg = "Standard quadrature"; if (self%qint_method == 1) msg = "tetrahedron method" 4656 call wrtout(std_out, sjoin(" Preparing q-loop with integration method:", msg)) 4657 call cwtime(cpu, wall, gflops, "start") 4658 4659 select case (dtset%eph_task) 4660 case (4) 4661 ! Computation of re-im 4662 call distribute_nqibz_k_nofilter() 4663 if (self%qint_method == 1) call sigmaph_get_all_qweights(self, cryst, ebands, spin, ikcalc, comm) 4664 4665 case (-4) 4666 ! Computation of imaginary part 4667 if (self%qint_method == 0) then 4668 call distribute_nqibz_k_nofilter() 4669 4670 else if (self%qint_method == 1) then 4671 ! Imag with tetra --> Precompute weights in IBZ_k. 4672 call distribute_nqibz_k_nofilter() 4673 call sigmaph_get_all_qweights(self, cryst, ebands, spin, ikcalc, comm) 4674 4675 qfilter = any(dtset%eph_tols_idelta >= zero) 4676 4677 if (qfilter) then 4678 ! Two-pass algorithm: 4679 ! Select q-points with significant contribution, recompute my_nqibz_k and myq2ibz_k. 4680 ! Finally, recompute integration weights with new distribution. 4681 ! NB: the two-pass algorithm could be replaced by a decimation algo and a single call to the tetrahedron routines 4682 ! %deltaw_pm(2, nbcalc_ks, my_npert, bsum_start:bsum_stop, my_nqibz_k, ndiv) 4683 ndiv = 1; if (self%use_doublegrid) ndiv = self%eph_doublegrid%ndiv 4684 ABI_ICALLOC(mask_qibz_k, (self%nqibz_k)) 4685 do imyq=1,self%my_nqibz_k 4686 iq_ibz_k = self%myq2ibz_k(imyq) 4687 if (any(abs(self%deltaw_pm(1,:,:,:,imyq,:)) >= dtset%eph_tols_idelta(1) / ndiv)) mask_qibz_k(iq_ibz_k) = 1 4688 if (any(abs(self%deltaw_pm(2,:,:,:,imyq,:)) >= dtset%eph_tols_idelta(2) / ndiv)) mask_qibz_k(iq_ibz_k) = 1 4689 end do 4690 4691 ! Take max inside comm. 4692 call alloc_copy(mask_qibz_k, imask) 4693 call xmpi_max(imask, mask_qibz_k, comm, ierr) 4694 ABI_FREE(imask) 4695 4696 ! Find all qpts in the IBZ_k contributing to Im(Sigma). 4697 ABI_MALLOC(qtab, (self%nqibz_k)) 4698 nqeff = 0 4699 do iq_ibz_k=1,self%nqibz_k 4700 if (mask_qibz_k(iq_ibz_k) == 1) then 4701 nqeff = nqeff + 1; qtab(nqeff) = iq_ibz_k 4702 end if 4703 end do 4704 ABI_FREE(mask_qibz_k) 4705 4706 if (my_rank == master) then 4707 !write(std_out, "(a, 2(es16.6,1x))")" Removing q-points with integration weights < ", dtset%eph_tols_idelta / ndiv 4708 write(std_out, "(a,i0,a,f5.1,a)")" Total number of q-points contributing to Im(Sigma(eKS)): ", nqeff, & 4709 " (nqeff / nqibz_k): ", (100.0_dp * nqeff) / self%nqibz_k, " [%]" 4710 end if 4711 4712 ! Redistribute relevant q-points inside qpt_comm taking into account itreat_qibz 4713 ! I may need to update qcache after this operation --> build ineed_* table. 4714 ! Must handle two cases: potentials from DVDB or Fourier-interpolated. 4715 if (self%use_ftinterp) then 4716 ABI_ICALLOC(ineed_qibz, (self%nqibz)) 4717 else 4718 ABI_ICALLOC(ineed_qdvdb, (dvdb%nqpt)) 4719 end if 4720 4721 self%my_nqibz_k = 0 4722 do ii=1,2 4723 if (ii == 2) then 4724 ABI_REMALLOC(self%myq2ibz_k, (self%my_nqibz_k)) 4725 end if 4726 cnt = 0 4727 do iq=1,nqeff 4728 iq_ibz_k = qtab(iq) 4729 iq_ibz = self%ind_ibzk2ibz(1, iq_ibz_k) 4730 itreat = int(self%itreat_qibz(iq_ibz), kind=i4b) 4731 if (.not. self%use_ftinterp) iq_dvdb = self%ind_q2dvdb_k(1, iq_ibz_k) 4732 if (itreat /= 0) then 4733 if (ii == 1) self%my_nqibz_k = self%my_nqibz_k + 1 4734 if (ii == 2) then 4735 cnt = cnt + 1 4736 self%myq2ibz_k(cnt) = qtab(iq) 4737 if (self%use_ftinterp) then 4738 if (.not. allocated(dvdb%ft_qcache%key(iq_ibz)%v1scf)) ineed_qibz(iq_ibz) = 1 4739 else 4740 if (.not. allocated(dvdb%qcache%key(iq_dvdb)%v1scf)) ineed_qdvdb(iq_dvdb) = 1 4741 end if 4742 end if 4743 end if 4744 end do 4745 end do 4746 ABI_FREE(qtab) 4747 4748 ! Recompute weights with new q-point distribution. 4749 call sigmaph_get_all_qweights(self, cryst, ebands, spin, ikcalc, comm) 4750 4751 call xmpi_min(self%my_nqibz_k, min_nqibz_k, self%qpt_comm%value, ierr) 4752 call xmpi_max(self%my_nqibz_k, max_nqibz_k, self%qpt_comm%value, ierr) 4753 !efact = (one * self%my_nqibz_k * self%qpt_comm%nproc) / nqeff 4754 efact_min = (one * min_nqibz_k * self%qpt_comm%nproc) / nqeff 4755 efact_max = (one * max_nqibz_k * self%qpt_comm%nproc) / nqeff 4756 write(msg, "(2(a,i0,a),a,2(f7.3,1x),a)") & 4757 " Number of q-points in the IBZ(k) treated by this MPI proc: ", self%my_nqibz_k, ch10, & 4758 " Number of MPI procs in qpt_comm: ", self%qpt_comm%nproc, ch10, & 4759 " Load balance inside qpt_comm ranges between: [", efact_min, efact_max, "] (should be ~1)" 4760 call wrtout(std_out, msg) 4761 ABI_WARNING_IF(self%my_nqibz_k == 0, "my_nqibz_k == 0") 4762 4763 ! Make sure each node has the q-points we need. Try not to break qcache_size_mb contract! 4764 if (self%use_ftinterp) then 4765 ! Update cache by Fourier interpolating W(r,R) 4766 call dvdb%ftqcache_update_from_ft(nfftf, ngfftf, self%nqibz, self%qibz, ineed_qibz, comm) 4767 else 4768 ! Update cache. Perform collective IO inside comm if needed. 4769 call dvdb%qcache_update_from_file(nfftf, ngfftf, ineed_qdvdb, comm) 4770 end if 4771 4772 ABI_SFREE(ineed_qibz) 4773 ABI_SFREE(ineed_qdvdb) 4774 end if ! qfilter 4775 4776 else 4777 ABI_ERROR(sjoin("Invalid eph_intmeth:", itoa(self%qint_method))) 4778 end if ! intmeth 4779 4780 if (dtset%ibte_prep > 0) then 4781 ! Allocate array with scattering rate for IBTE. 4782 ABI_RECALLOC(self%srate, (self%bsum_start:self%bsum_stop, self%nbcalc_ks(ikcalc, spin), self%ntemp, self%my_nqibz_k)) 4783 self%srate = zero 4784 end if 4785 4786 case default 4787 ABI_ERROR(sjoin("Invalid eph_task:", itoa(dtset%eph_task))) 4788 end select 4789 4790 call cwtime_report(" Setup qloop", cpu, wall, gflops) 4791 4792 contains 4793 4794 subroutine distribute_nqibz_k_nofilter() 4795 ! Find number of q-points in IBZ(k) treated by this MPI rank 4796 ! taking into account itreat_qibz and build redirection table myq2ibz_k. 4797 ! The distribution must be consistent with the WF distribution done with bks_mask 4798 4799 self%my_nqibz_k = 0 4800 do ii=1,2 4801 if (ii == 2) then 4802 ABI_REMALLOC(self%myq2ibz_k, (self%my_nqibz_k)) 4803 end if 4804 cnt = 0 4805 do iq_ibz_k=1,self%nqibz_k 4806 iq_ibz = self%ind_ibzk2ibz(1, iq_ibz_k) 4807 if (self%itreat_qibz(iq_ibz) == 0) cycle 4808 if (ii == 1) self%my_nqibz_k = self%my_nqibz_k + 1 4809 if (ii == 2) then 4810 cnt = cnt + 1 4811 self%myq2ibz_k(cnt) = iq_ibz_k 4812 end if 4813 end do 4814 end do 4815 4816 end subroutine distribute_nqibz_k_nofilter 4817 4818 end subroutine sigmaph_setup_qloop
m_sigmaph/sigmaph_skip_phmode [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_phskip_mode
FUNCTION
Ignore contribution of phonon mode depending on phonon frequency value or mode index.
INPUTS
SOURCE
4583 pure logical function sigmaph_skip_phmode(self, nu, wqnu, eph_phrange_w) result(skip) 4584 4585 !Arguments ------------------------------------ 4586 class(sigmaph_t),intent(in) :: self 4587 integer,intent(in) :: nu 4588 real(dp),intent(in) :: wqnu, eph_phrange_w(2) 4589 4590 ! ************************************************************************* 4591 4592 skip = wqnu < EPHTK_WTOL .or. self%phmodes_skip(nu) == 1 4593 4594 ! Check frequency range 4595 if (abs(eph_phrange_w(2)) > tol12) then 4596 if (eph_phrange_w(2) > zero) then 4597 ! wqnu must be inside range 4598 skip = skip .or. .not. (wqnu >= eph_phrange_w(1) .and. wqnu <= eph_phrange_w(2)) 4599 else 4600 ! wqnu must be outside range 4601 skip = skip .or. (wqnu >= eph_phrange_w(1) .and. wqnu <= eph_phrange_w(2)) 4602 end if 4603 end if 4604 4605 end function sigmaph_skip_phmode
m_sigmaph/sigmaph_t [ Types ]
[ Top ] [ m_sigmaph ] [ Types ]
NAME
sigmaph_t
FUNCTION
Container for the (diagonal) matrix elements of the electron-phonon self-energy in the KS representation i.e. Sigma_eph(omega, T, band, k, spin). Provides methods to compute QP corrections, spectral functions, QP linewidths and save the results to netcdf file.
SOURCE
124 type,public :: sigmaph_t 125 126 integer :: nkcalc 127 ! Number of k-points computed (inside energy window) 128 129 integer :: max_nbcalc 130 ! Maximum number of bands computed (max over nkcalc and spin). 131 132 integer :: nsppol 133 ! Number of independent spin polarizations. 134 135 integer :: nspinor 136 ! Number of spinor components. 137 138 integer :: nwr 139 ! Number of frequency points along the real axis for Sigma(w) and spectral function A(w) 140 ! Odd number so that the mesh is centered on the KS energy. 141 ! The spectral function is computed only if nwr > 0 (taken from dtset%nfreqsp) 142 143 integer :: ntemp 144 ! Number of temperatures. 145 146 integer :: symsigma 147 ! 1 if matrix elements should be symmetrized. 148 ! Required when the sum over q in the BZ is replaced by IBZ(k). 149 150 integer :: timrev 151 ! timrev = 1 if the use of time-reversal is allowed; 0 otherwise 152 153 integer :: nbsum 154 ! Total number of bands used in sum over states without taking into account MPI distribution. 155 156 integer :: bsum_start, bsum_stop 157 ! First and last band included in self-energy sum without taking into account MPI distribution inside bsum_comm 158 ! nbsum = bsum_stop - bsum_start + 1 159 160 integer :: my_bsum_start, my_bsum_stop 161 ! Initial and final band index included in self-energy sum 162 ! Processor-dependent if Re-Im calculation. 163 ! Processor-independent and computed at runtime on the basis of the nk states in Sigma_{nk} if imag_only 164 165 integer :: my_npert 166 ! Number of atomic perturbations or phonon modes treated by this MPI rank. 167 ! Note that natom3 are equally distributed. This allows us to use allgather instead of allgatherv 168 169 type(xcomm_t) :: pert_comm 170 ! MPI communicator for parallelism over atomic perturbations. 171 172 type(xcomm_t) :: qb_comm 173 ! MPI communicator used to distribute (band_sum, q-points) 174 175 type(xcomm_t) :: qpt_comm 176 ! MPI communicator for q-points 177 178 type(xcomm_t) :: bsum_comm 179 ! MPI communicator for bands in self-energy sum 180 181 type(xcomm_t) :: kcalc_comm 182 ! MPI communicator for parallelism over k-points (high-level) 183 184 type(xcomm_t) :: spin_comm 185 ! MPI communicator for parallelism over spins (high-level) 186 187 type(xcomm_t) :: pqb_comm 188 ! MPI communicator for the (perturbation, band_sum, qpoint_sum) 189 190 type(xcomm_t) :: ncwrite_comm 191 ! MPI communicator for parallel netcdf IO used to write results for the different k-points/spins 192 193 integer :: coords_pqbks(5) 194 ! Cartesian coordinates of this processor in the Cartesian grid. 195 196 integer :: nqbz 197 ! Number of q-points in the (dense) BZ for sigma integration 198 199 integer :: nqibz 200 ! Number of q-points in the (dense) IBZ for sigma integration 201 202 integer :: nqibz_k 203 ! Number of q-points in the IBZ(k). Depends on ikcalc. 204 205 integer :: my_nqibz_k 206 ! Number of q-points in the IBZ(k) treated by this MPI proc. Depends on ikcalc. 207 ! Differs from nqibz_k only if imag with tetra because in this case we can introduce a cutoff on the weights 208 209 integer :: lgk_nsym 210 ! Number of symmetries in the little group of k. Depends on ikcalc. 211 212 integer :: ncid = nctk_noid 213 ! Netcdf file handle used to save results. 214 215 integer :: mpw 216 ! Maximum number of PWs for all possible k+q 217 218 integer :: bcorr = 0 219 ! 1 to include Blochl correction in the tetrahedron method else 0. 220 221 integer :: zinv_opt = 1 222 ! Defines the algorithm used to compute the tetrahedron weights for 1/z if re-im computation 223 ! 1 for S. Kaprzyk routines, 224 ! 2 for Lambin-Vigneron. 225 226 integer :: ntheta = 0, nphi = 0 227 ! Number of division for spherical integration of Frohlich term. 228 229 integer :: angl_size = 0 230 ! Dimension of angular mesh for spherical integration of the Frohlich self-energy 231 ! angl_size = ntheta * nphi 232 233 complex(dpc) :: ieta 234 ! Used to shift the poles in the complex plane (Ha units) 235 ! Corresponds to `i eta` term in equations. 236 237 real(dp) :: elow, ehigh 238 ! min and Max KS energy treated in self-energy +- max phonon energy 239 ! Used to select bands in self-energy sum if imag_only and select q-points in qpoints_oracle 240 241 real(dp) :: phwinfact = four 242 ! phwinfact * wmax is used to define the energy window for filtering electronic states 243 ! in the computation of electron lifetimes. 244 245 real(dp) :: wr_step 246 ! Step of the linear mesh along the real axis (Ha units). 247 248 real(dp) :: wmax 249 ! Max phonon energy + buffer. Used to select the bands to sum for the imaginary part 250 ! and filter q-points on the basis of electron energy difference. 251 252 integer :: qint_method 253 ! Defines the method used for the q-space integration 254 ! 0 -> Standard quadrature (one point per micro zone). 255 ! 1 -> Use tetrahedron method. 256 257 integer :: frohl_model = 0 258 ! > 0 to treat the q --> 0 divergence and accelerate convergence in polar semiconductors. 259 ! 1: Use spherical integration inside the micro zone around the Gamma point 260 261 integer :: mrta = 0 262 ! 0 to disable MRTA. 263 ! > 0 if linewidths in the energy-momentum relaxation time approximation should be computed 264 265 real(dp),allocatable :: scratew(:,:,:,:) 266 ! (%phmesh_size, %ntemp, %max_nbcalc, 2) 267 268 logical :: use_doublegrid = .False. 269 ! whether to use double grid or not 270 271 logical :: use_ftinterp = .False. 272 ! whether DFPT potentials should be read from the DVDB or Fourier-interpolated on the fly. 273 274 type(eph_double_grid_t) :: eph_doublegrid 275 ! store the double grid related object 276 277 logical :: imag_only 278 ! True if only the imaginary part of the self-energy must be computed 279 280 integer :: gmax(3) 281 282 integer :: ngqpt(3) 283 ! Number of divisions in the Q mesh in the BZ. 284 285 integer,allocatable :: bstart_ks(:,:) 286 ! bstart_ks(nkcalc, nsppol) 287 ! Initial KS band index included in self-energy matrix elements for each k-point in kcalc. 288 ! Depends on spin because all degenerate states should be included when symmetries are used. 289 290 integer,allocatable :: bstop_ks(:,:) 291 ! bstop_ks(nkcalc, nsppol) 292 293 integer,allocatable :: nbcalc_ks(:,:) 294 ! nbcalc_ks(nkcalc, nsppol) 295 ! Number of bands included in self-energy matrix elements for each k-point in kcalc. 296 ! Depends on spin because all degenerate states should be included when symmetries are used. 297 298 integer,allocatable :: kcalc2ibz(:,:) 299 !kcalc2ibz(nkcalc, 6)) 300 ! Mapping ikcalc --> IBZ as reported by listkk. 301 302 integer :: my_nspins 303 ! Number of spins treated by this MPI rank 304 305 integer,allocatable :: my_spins(:) 306 ! my_spins(my_nspins) 307 ! Indirect table giving the spin indices treated by this MPI rank. 308 ! Used only in the collinear case with nsppol = 2 and nspinor == 1 309 310 integer :: my_nkcalc 311 ! Number of k-points treated by this MPI rank 312 313 integer,allocatable :: my_ikcalc(:) 314 ! my_ikcalc(my_nkcalc) 315 ! List of ikcalc indices treated by this pool if k-point parallelism is activated. 316 317 integer,allocatable :: myq2ibz_k(:) 318 ! myq2ibz_k(my_nqibz_k) 319 ! Mapping my q-point index --> index in nqibz_k arrays (IBZ_k) 320 ! Differs from nqibz_k only if imag with tetra because in this case we can introduce a cutoff. 321 322 integer(i1b),allocatable :: itreat_qibz(:) 323 ! itreat_qibz(nqibz) 324 ! Table used to distribute potentials over q-points in the IBZ. 325 ! The loop over qpts in the IBZ(k) is MPI distributed inside qpt_comm according to this table. 326 ! 0 if this IBZ point is not treated by this proc. 327 ! 1 if this IBZ is treated. 328 329 integer,allocatable :: my_pinfo(:,:) 330 ! my_pinfo(3, my_npert) 331 ! my_pinfo(1, ip) gives the `idir` index of the ip-th perturbation. 332 ! my_pinfo(2, ip) gives the `ipert` index of the ip-th perturbation. 333 ! my_pinfo(3, ip) gives `pertcase`=idir + (ipert-1)*3 334 335 integer,allocatable :: pert_table(:,:) 336 ! pert_table(2, natom3) 337 ! pert_table(1, npert): rank of the processor treating this atomic perturbation. 338 ! pert_table(2, npert): imyp index in my_pinfo table, -1 if this rank is not treating ipert. 339 340 integer,allocatable :: phmodes_skip(:) 341 ! (natom3) 342 ! A mask to skip accumulating the contribution of certain phonon modes 343 344 integer,allocatable:: ind_qbz2ibz(:,:) 345 ! (6, %nqibz) 346 ! Mapping qBZ to IBZ 347 348 integer,allocatable:: indkk_kq(:, :) 349 ! (6, %nqibz_k)) 350 ! Mapping k+q --> initial IBZ. Depends on ikcalc. 351 ! These table used the conventions for the symmetrization of the wavefunctions expected by cgtk_rotate. 352 ! In this case listkk has been called with symrel and use_symrec=False 353 354 integer,allocatable :: ind_q2dvdb_k(:,:) 355 ! (6, %nqibz_k)) 356 ! Mapping qibz_k --> IBZ found in DVDB file. 357 ! Used when DFPT potentials are read from DVDB file so that we know how to access/symmetrize v1scf 358 ! Depends on ikcalc. 359 360 integer,allocatable :: ind_ibzk2ibz(:,:) 361 ! (6, %nqibz_k)) 362 ! Mapping qibz_k --> IBZ defined by eph_ngqpt_fine. 363 ! Depends on ikcalc. 364 365 integer,allocatable :: qibz2dvdb(:) 366 ! (%nqibz)) 367 ! Mapping dvdb%ibz --> %ibz 368 369 integer, allocatable :: lgk_sym2glob(:, :) 370 ! lgk_sym2glob(2, lgk_nsym) 371 ! Mapping isym_lg --> [isym, itime] 372 ! where isym is the index of the operation in the global array **crystal%symrec** 373 ! and itim is 2 if time-reversal T must be included else 1. Depends on ikcalc 374 375 integer,allocatable :: nbsum_rank(:,:) 376 ! (%bsum_comm%nproc, 2) 377 ! (rank+1, 1): Number of bands treated by rank in %bsum_comm. 378 ! (rank+1, 2): bsum_start of MPI rank 379 ! Available only if .not. imag_only 380 381 real(dp),allocatable :: kcalc(:,:) 382 ! kcalc(3, nkcalc) 383 ! List of k-points where the self-energy is computed. 384 385 real(dp),allocatable :: qbz(:,:) 386 ! qbz(3, nqbz) 387 ! Reduced coordinates of the q-points in the full BZ. 388 389 real(dp),allocatable :: qibz(:,:) 390 ! qibz(3, nqibz) 391 ! Reduced coordinates of the q-points in the IBZ (full simmetry of the system). 392 393 real(dp),allocatable :: wtq(:) 394 ! wtq(nqibz) 395 ! Weights of the q-points in the IBZ (normalized to one). 396 397 real(dp),allocatable :: qibz_k(:,:) 398 ! qibz(3, nqibz_k) 399 ! Reduced coordinates of the q-points in the IBZ(k). Depends on ikcalc. 400 401 real(dp),allocatable :: wtq_k(:) 402 ! wtq(nqibz_k) 403 ! Weights of the q-points in the IBZ(k) (normalized to one). Depends on ikcalc. 404 405 real(dp),allocatable :: srate(:,:,:,:) 406 ! (%bsum_start:%bsum_stop, %nbcalc_ks(ikcalc, spin), %ntemp, %my_nqibz_k)) 407 ! This array is initialized inside the (ikcalc, spin) loop 408 409 real(dp),allocatable :: kTmesh(:) 410 ! kTmesh(ntemp) 411 ! List of temperatures (kT units). 412 413 real(dp),allocatable :: mu_e(:) 414 ! mu_e(ntemp) 415 ! chemical potential of electrons for the different temperatures. 416 417 real(dp),allocatable :: e0vals(:) 418 ! (nbcalc_ks) 419 ! KS energies where QP corrections are wantend 420 ! This array is initialized inside the (ikcalc, spin) loop 421 422 real(dp),allocatable :: vcar_calc(:,:,:,:) 423 ! (3, max_nbcalc, nkcalc, nsppol)) 424 ! Diagonal elements of velocity operator in cartesian coordinates for all states in Sigma_nk. 425 426 real(dp),allocatable :: linewidth_mrta(:,:) 427 ! linewidth_mrta(ntemp, max_nbcalc) 428 ! Linewidths computed within the momentum relaxation time approximation 429 ! for given (ikcalc, spin). Only if imag_only 430 431 complex(dpc),allocatable :: cweights(:,:,:,:,:,:,:) 432 ! (nz, 2, nbcalc_ks, my_npert, my_bsum_start:my_bsum_stop, my_nqibz_k, ndiv)) 433 ! Weights for the q-integration of 1 / (e1 - e2 \pm w_{q, nu} + i.eta) 434 ! This array is initialized inside the (ikcalc, spin) loop 435 436 real(kind=DELTAW_KIND),allocatable :: deltaw_pm(:,:,:,:,:,:) 437 ! (2, nbcalc_ks, my_npert, bsum_start:bsum_stop, my_nqibz_k, ndiv)) 438 ! Weights for the q-integration of the two delta (abs/emission) if imag_only 439 ! This array is initialized inside the (ikcalc, spin) loop 440 441 real(dp),allocatable :: wrmesh_b(:,:) 442 ! wrmesh_b(nwr, max_nbcalc) 443 ! Frequency mesh along the real axis (Ha units) used for the different bands 444 ! Each mesh is **centered** on the corresponding KS energy. 445 ! This array depends on (ikcalc, spin) 446 447 real(dp), allocatable :: qvers_cart(:,:) 448 ! qvers_cart(3, angl_size) 449 ! For each point of the angular mesh, gives the Cartesian coordinates 450 ! of the corresponding point on an unitary sphere (Frohlich self-energy) 451 452 real(dp), allocatable :: angwgth(:) 453 ! angwgth(angl_size) 454 ! For each point of the angular mesh, gives the weight 455 ! of the corresponding point on an unitary sphere (Frohlich self-energy) 456 457 real(dp),allocatable :: frohl_deltas_sphcorr(:, :, :, :) 458 ! (2, ntemp, max_nbcalc, natom3)) 459 ! Integration of the imaginary part inside the small sphere around Gamma 460 ! computed numerically with the Frohlich model by Verdi and angular integration. 461 ! The first dimension stores the contributions due to +/- omega_qn 462 ! Used if frohl_model == 1 and imag_only. This array depend on (ikcalc, spin) 463 ! TODO: Finalize implementation 464 465 integer, allocatable :: qp_done(:,:) 466 ! qp_done(kcalc, spin) 467 ! Keep track of the QP states already computed for restart of the calculation 468 469 complex(dpc),allocatable :: vals_e0ks(:,:) 470 ! vals_e0ks(ntemp, max_nbcalc) 471 ! Sigma_eph(omega=eKS, kT, band) for given (ikcalc, spin). 472 ! Fan-Migdal + Debye-Waller 473 474 complex(dpc),allocatable :: fan_vals(:,:) 475 ! fan_vals(ntemp, max_nbcalc) 476 ! Fan-Migdal 477 478 complex(dpc),allocatable :: fan_stern_vals(:,:) 479 ! fan_stern_vals(ntemp, max_nbcalc) 480 ! Fan-Migdal adiabatic Sternheimer part 481 482 complex(dpc),allocatable :: dvals_de0ks(:,:) 483 ! dvals_de0ks(ntemp, max_nbcalc) for given (ikcalc, spin) 484 ! d Re Sigma_eph(omega, kT, band, kcalc, spin) / d omega (omega=eKS) 485 486 complex(dpc),allocatable :: frohl_dvals_de0ks(:,:) 487 ! frohl_dvals_de0ks(ntemp, max_nbcalc) for given (ikcalc, spin) 488 ! d Re Sigma_frohl(omega, kT, band, kcalc, spin) / d omega (omega=eKS) 489 490 real(dp),allocatable :: dw_vals(:,:) 491 ! dw_vals(ntemp, max_nbcalc) for given (ikcalc, spin) 492 ! Debye-Waller term (static). 493 494 real(dp),allocatable :: dw_stern_vals(:,:) 495 ! dw_stern_vals(ntemp, max_nbcalc) for given (ikcalc, spin) 496 ! Debye-Waller Sternheimer term (static) . 497 498 complex(dpc),allocatable :: vals_wr(:,:,:) 499 ! vals_wr(nwr, ntemp, max_nbcalc) 500 ! Sigma_eph(omega, kT, band) for given (ikcalc, spin). 501 ! enk_KS corresponds to nwr/2 + 1. 502 ! This array depends on (ikcalc, spin) 503 504 integer :: phmesh_size 505 ! Number of phonon frequencies in phonon mesh used for Eliashberg functions and 506 ! and other omega-resolved quantities. 507 508 real(dp),allocatable :: phmesh(:) 509 ! phmesh(phmesh_size) 510 ! phonon mesh in Ha. 511 512 real(dp),allocatable :: gf_nnuq(:,:,:,:) 513 ! (nbcalc_ks, natom3, %nqibz_k, 3) 514 ! Quantities needed to compute the generalized Eliashberg functions (gkq2/Fan-Migdal/DW terms) 515 ! This array depends on (ikcalc, spin) 516 ! NB: q-weights for integration are not included. 517 518 real(dp),allocatable :: gfw_vals(:,:,:) 519 ! gfw_vals(phmesh_size, 3, max_nbcalc) 520 ! Generalized Eliashberg function a2F_{n,k,spin}(w) 521 ! 1: |g(k,q)|^2 with delta(e_\nk - e_{m\kq}) 522 ! 2: Fan-Migdal in the adiabatic approximation 523 ! 3: DW contribution in the adiabatic approximation. 524 ! This array depends on (ikcalc, spin) 525 526 integer :: a2f_ne = 0 527 ! Number of points in a2f_emesh 528 529 real(dp),allocatable :: a2f_emesh(:) 530 ! a2f_emesh(a2f_ne) 531 ! Energy mesh for electrons 532 533 real(dp),allocatable :: a2few(:,:,:) 534 ! a2few(a2f_ne, phmesh_size, max_nbcalc) 535 ! FM Eliashberg function a2f_\nk(e, w) = \sum_{mq} |g(k,q)|^2 delta(e - e_{m\kq}) delta(w - w_\qnu} 536 ! This array depends on (ikcalc, spin) and is computed only if prteliash == 3 537 538 type(ephwg_t) :: ephwg 539 ! This object computes the weights for the BZ integration in q-space if qint_method > 0 540 541 type(degtab_t),allocatable :: degtab(:,:) 542 ! (nkcalc, nsppol) 543 ! Table used to average QP results in the degenerate subspace if symsigma == 1 544 545 contains 546 547 procedure :: write => sigmaph_write 548 ! Write main dimensions and header of sigmaph on a netcdf file. 549 550 procedure :: compare => sigmaph_compare 551 ! Compare two instances of sigmaph raise error if different 552 553 procedure :: setup_kcalc => sigmaph_setup_kcalc 554 ! Return tables used to perform the sum over q-points for given k-point. 555 556 procedure :: gather_and_write => sigmaph_gather_and_write 557 ! Compute the QP corrections. 558 559 procedure :: print => sigmaph_print 560 ! Print results to main output file. 561 562 procedure :: free => sigmaph_free 563 ! Free sigmaph object 564 565 procedure :: get_ebands => sigmaph_get_ebands 566 ! Fill in values in ebands from the sigmaph structure and netcdf file 567 568 procedure :: skip_phmode => sigmaph_skip_phmode 569 ! Ignore contribution of phonon mode depending on phonon frequency value or mode index. 570 571 end type sigmaph_t
m_sigmaph/sigmaph_write [ Functions ]
[ Top ] [ m_sigmaph ] [ Functions ]
NAME
sigmaph_write
FUNCTION
Define dimensions and netcdf arrays in SIGEPH file.
INPUTS
dtset<dataset_type>=All input variables for this dataset. cryst<crystal_t>=Crystalline structure ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...) wfk_hdr=Header of the WFK file. ifc<ifc_type>=interatomic force constants and corresponding real space grid info. dtfil<datafiles_type>=variables related to files. comm=MPI communicator
SOURCE
3604 subroutine sigmaph_write(self, dtset, cryst, ebands, wfk_hdr, dtfil, comm) 3605 3606 !Arguments ------------------------------------ 3607 integer,intent(in) :: comm 3608 class(sigmaph_t),intent(inout) :: self 3609 type(crystal_t),intent(in) :: cryst 3610 type(dataset_type),intent(in) :: dtset 3611 type(ebands_t),intent(in) :: ebands 3612 type(hdr_type),intent(in) :: wfk_hdr 3613 type(datafiles_type),intent(in) :: dtfil 3614 3615 !Local variables ------------------------------ 3616 !scalars 3617 integer,parameter :: master = 0 3618 integer :: my_rank, ii, edos_intmeth, spin, ikcalc 3619 integer :: ncid, ncerr, grp_ncid 3620 !character(len=5000) :: msg 3621 real(dp) :: edos_broad, edos_step, cpu_all, wall_all, gflops_all, cpu, wall, gflops 3622 character(len=fnlen) :: path 3623 type(edos_t) :: edos 3624 3625 ! ************************************************************************* 3626 3627 my_rank = xmpi_comm_rank(comm) 3628 3629 call cwtime(cpu_all, wall_all, gflops_all, "start") 3630 3631 if (dtset%prtdos /= 0) then 3632 call cwtime(cpu, wall, gflops, "start") 3633 ! Compute electron DOS. 3634 edos_intmeth = 2; if (self%bcorr == 1) edos_intmeth = -2 3635 if (dtset%prtdos == 1) edos_intmeth = 1 3636 edos_step = dtset%dosdeltae; edos_broad = dtset%tsmear 3637 call wrtout(std_out, " Computing electron dos. Use prtdos 0 to disable this part...", do_flush=.True.) 3638 edos = ebands_get_edos(ebands, cryst, edos_intmeth, edos_step, edos_broad, comm) 3639 if (my_rank == master) then 3640 path = strcat(dtfil%filnam_ds(4), "_EDOS") 3641 call wrtout(ab_out, sjoin("- Writing electron DOS to file:", path)) 3642 call edos%write(path) 3643 call edos%print(unit=std_out) 3644 !call edos%print(unit=ab_out) 3645 end if 3646 call cwtime_report(" sigmaph_new: ebands", cpu, wall, gflops) 3647 end if 3648 3649 ! Create netcdf file (only master works, HDF5 + MPI-IO is handled afterwards by reopening the file inside ncwrite_comm) 3650 path = strcat(dtfil%filnam_ds(4), "_SIGEPH.nc") 3651 if (my_rank == master) then 3652 ! Master creates the netcdf file used to store the results of the calculation. 3653 NCF_CHECK(nctk_open_create(self%ncid, path, xmpi_comm_self)) 3654 ncid = self%ncid 3655 3656 NCF_CHECK(wfk_hdr%ncwrite(ncid, fform_from_ext("SIGEPH.nc"), nc_define=.True.)) 3657 NCF_CHECK(cryst%ncwrite(ncid)) 3658 NCF_CHECK(ebands_ncwrite(ebands, ncid)) 3659 if (dtset%prtdos /= 0) then 3660 NCF_CHECK(edos%ncwrite(ncid)) 3661 end if 3662 3663 ! Add sigma_eph dimensions. 3664 ncerr = nctk_def_dims(ncid, [ & 3665 nctkdim_t("nkcalc", self%nkcalc), nctkdim_t("max_nbcalc", self%max_nbcalc), & 3666 nctkdim_t("nsppol", self%nsppol), nctkdim_t("ntemp", self%ntemp), nctkdim_t("natom3", 3 * cryst%natom), & 3667 nctkdim_t("phmesh_size", self%phmesh_size), & 3668 nctkdim_t("nqibz", self%nqibz), nctkdim_t("nqbz", self%nqbz)], & 3669 defmode=.True.) 3670 NCF_CHECK(ncerr) 3671 3672 if (self%nwr > 0) then 3673 NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("nwr", self%nwr)])) 3674 end if 3675 if (dtset%prteliash == 3) then 3676 NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("a2f_ne", self%a2f_ne)])) 3677 end if 3678 3679 ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: & 3680 "eph_task", "symsigma", "nbsum", "bsum_start", "bsum_stop", "symdynmat", & 3681 "ph_intmeth", "eph_intmeth", "qint_method", "eph_transport", & 3682 "imag_only", "symv1scf", "dvdb_add_lr", "mrta", "ibte_prep", "eph_prtscratew", "eph_ahc_type"]) 3683 NCF_CHECK(ncerr) 3684 ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: & 3685 "eta", "wr_step", "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie", & 3686 "ph_wstep", "ph_smear", "eph_phwinfact"]) 3687 NCF_CHECK(ncerr) 3688 3689 ! Define arrays with results. 3690 ncerr = nctk_def_arrays(ncid, [ & 3691 nctkarr_t("ngqpt", "int", "three"), & 3692 nctkarr_t("eph_ngqpt_fine", "int", "three"), & 3693 nctkarr_t("eph_phrange", "int", "two"), & 3694 nctkarr_t("eph_phrange_w", "dp", "two"), & 3695 nctkarr_t("ddb_ngqpt", "int", "three"), & 3696 nctkarr_t("ph_ngqpt", "int", "three"), & 3697 nctkarr_t("sigma_ngkpt", "int", "three"), & 3698 nctkarr_t("sigma_erange", "dp", "two"), & 3699 !nctkarr_t("frohl_params", "dp", "four"), & 3700 nctkarr_t("bstart_ks", "int", "nkcalc, nsppol"), & 3701 !nctkarr_t("bstop_ks", "int", "nkcalc, nsppol"), & 3702 nctkarr_t("nbcalc_ks", "int", "nkcalc, nsppol"), & 3703 nctkarr_t("kcalc", "dp", "three, nkcalc"), & 3704 nctkarr_t("kcalc2ibz", "int", "nkcalc, six"), & 3705 nctkarr_t("kTmesh", "dp", "ntemp"), & 3706 nctkarr_t("mu_e", "dp", "ntemp"), & 3707 nctkarr_t("qp_done", "int", "nkcalc, nsppol"), & 3708 nctkarr_t("vals_e0ks", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), & 3709 nctkarr_t("fan_vals", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), & 3710 nctkarr_t("fan_stern_vals", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), & 3711 nctkarr_t("dvals_de0ks", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), & 3712 nctkarr_t("dw_vals", "dp", "ntemp, max_nbcalc, nkcalc, nsppol"), & 3713 nctkarr_t("dw_stern_vals", "dp", "ntemp, max_nbcalc, nkcalc, nsppol"), & 3714 nctkarr_t("qpoms_enes", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), & 3715 nctkarr_t("qp_enes", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), & 3716 nctkarr_t("ze0_vals", "dp", "ntemp, max_nbcalc, nkcalc, nsppol"), & 3717 nctkarr_t("ks_enes", "dp", "max_nbcalc, nkcalc, nsppol"), & 3718 nctkarr_t("ks_gaps", "dp", "nkcalc, nsppol"), & 3719 nctkarr_t("qpoms_gaps", "dp", "ntemp, nkcalc, nsppol"), & 3720 nctkarr_t("qp_gaps", "dp", "ntemp, nkcalc, nsppol"), & 3721 nctkarr_t("phmesh", "dp", "phmesh_size"), & 3722 nctkarr_t("vcar_calc", "dp", "three, max_nbcalc, nkcalc, nsppol") & 3723 ]) 3724 NCF_CHECK(ncerr) 3725 3726 if (self%mrta > 0) then 3727 ncerr = nctk_def_arrays(ncid, [ & 3728 nctkarr_t("linewidth_mrta", "dp", "ntemp, max_nbcalc, nkcalc, nsppol") & 3729 ]) 3730 NCF_CHECK(ncerr) 3731 end if 3732 3733 if (dtset%eph_prtscratew == 1) then 3734 ncerr = nctk_def_arrays(ncid, [ & 3735 nctkarr_t("scratew", "dp", "phmesh_size, ntemp, max_nbcalc, two, nkcalc, nsppol") & 3736 ]) 3737 NCF_CHECK(ncerr) 3738 end if 3739 3740 !if (self%frohl_model == 1) then 3741 ! if (self%imag_only) then 3742 ! ncerr = nctk_def_arrays(ncid, [ & 3743 ! nctkarr_t("frohl_deltas_sphcorr", "dp", "two, ntemp, max_nbcalc, natom3, nkcalc, nsppol") & 3744 ! ]) 3745 ! NCF_CHECK(ncerr) 3746 ! end if 3747 !end if 3748 3749 if (self%nwr > 0) then 3750 ! Make room for the spectral function. These arrays get two extra dimensions on file (nkcalc, nsppol). 3751 ncerr = nctk_def_arrays(ncid, [ & 3752 nctkarr_t("wrmesh_b", "dp", "nwr, max_nbcalc, nkcalc, nsppol"), & 3753 nctkarr_t("vals_wr", "dp", "two, nwr, ntemp, max_nbcalc, nkcalc, nsppol"), & 3754 nctkarr_t("spfunc_wr", "dp", "nwr, ntemp, max_nbcalc, nkcalc, nsppol") & 3755 ]) 3756 NCF_CHECK(ncerr) 3757 end if 3758 3759 if (dtset%prteliash /= 0) then 3760 ncerr = nctk_def_arrays(ncid, [ & 3761 nctkarr_t("gfw_vals", "dp", "phmesh_size, three, max_nbcalc, nkcalc, nsppol") & 3762 ]) 3763 NCF_CHECK(ncerr) 3764 if (dtset%prteliash == 3) then 3765 ncerr = nctk_def_arrays(ncid, [ & 3766 nctkarr_t("a2f_emesh", "dp", "a2f_ne"), & 3767 nctkarr_t("a2few", "dp", "a2f_ne, phmesh_size, max_nbcalc, nkcalc, nsppol") & 3768 ]) 3769 NCF_CHECK(ncerr) 3770 end if 3771 end if 3772 3773 if (dtset%ibte_prep > 0) then 3774 ! Create groups to store scattering rates (ragged array). 3775 do spin=1,self%nsppol 3776 do ikcalc=1,self%nkcalc 3777 NCF_CHECK(nf90_def_grp(ncid, strcat("srate_k", itoa(ikcalc), "_s", itoa(spin)), grp_ncid)) 3778 end do 3779 end do 3780 end if 3781 3782 ! ====================================================== 3783 ! Write data that do not depend on the (kpt, spin) loop. 3784 ! ====================================================== 3785 NCF_CHECK(nctk_set_datamode(ncid)) 3786 ii = 0; if (self%imag_only) ii = 1 3787 ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: & 3788 "eph_task", "symsigma", "nbsum", "bsum_start", "bsum_stop", & 3789 "symdynmat", "ph_intmeth", "eph_intmeth", "qint_method", & 3790 "eph_transport", "imag_only", "symv1scf", "dvdb_add_lr", "mrta", "ibte_prep", "eph_prtscratew", "eph_ahc_type"], & 3791 [dtset%eph_task, self%symsigma, self%nbsum, self%bsum_start, self%bsum_stop, & 3792 dtset%symdynmat, dtset%ph_intmeth, dtset%eph_intmeth, self%qint_method, dtset%eph_transport, ii, & 3793 dtset%symv1scf, dtset%dvdb_add_lr, self%mrta, dtset%ibte_prep, dtset%eph_prtscratew, dtset%eph_ahc_type]) 3794 NCF_CHECK(ncerr) 3795 ncerr = nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: & 3796 "eta", "wr_step", "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie", "ph_wstep", "ph_smear", "eph_phwinfact"], & 3797 [aimag(self%ieta), self%wr_step, dtset%eph_fsewin, dtset%eph_fsmear, dtset%eph_extrael, dtset%eph_fermie, & 3798 dtset%ph_wstep, dtset%ph_smear, dtset%eph_phwinfact]) 3799 NCF_CHECK(ncerr) 3800 3801 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ngqpt"), self%ngqpt)) 3802 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_ngqpt_fine"), dtset%eph_ngqpt_fine)) 3803 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ddb_ngqpt"), dtset%ddb_ngqpt)) 3804 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ph_ngqpt"), dtset%ph_ngqpt)) 3805 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_ngkpt"), dtset%sigma_ngkpt)) 3806 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_erange"), dtset%sigma_erange)) 3807 !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "frohl_params"), dtset%frohl_params)) 3808 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_phrange"), dtset%eph_phrange)) 3809 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_phrange_w"), dtset%eph_phrange_w)) 3810 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "bstart_ks"), self%bstart_ks)) 3811 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nbcalc_ks"), self%nbcalc_ks)) 3812 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc"), self%kcalc)) 3813 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc2ibz"), self%kcalc2ibz)) 3814 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kTmesh"), self%kTmesh)) 3815 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "mu_e"), self%mu_e)) 3816 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eta"), aimag(self%ieta))) 3817 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phmesh"), self%phmesh)) 3818 if (dtset%prteliash == 3) then 3819 NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "a2f_emesh"), self%a2f_emesh)) 3820 end if 3821 NCF_CHECK(nf90_close(ncid)) 3822 end if ! master 3823 3824 call xmpi_barrier(comm) 3825 3826 ! Now reopen the file inside ncwrite_comm to perform parallel-IO (required for k-point parallelism). 3827 if (self%ncwrite_comm%value /= xmpi_comm_null) then 3828 NCF_CHECK(nctk_open_modify(self%ncid, path, self%ncwrite_comm%value)) 3829 NCF_CHECK(nctk_set_datamode(self%ncid)) 3830 end if 3831 3832 call edos%free() 3833 call cwtime_report(" sigmaph_new: netcdf", cpu_all, wall_all, gflops_all) 3834 3835 end subroutine sigmaph_write