TABLE OF CONTENTS
- ABINIT/covar_cprj
- ABINIT/cpg_dij_cpb
- ABINIT/duq_she_qdu
- ABINIT/duqdu
- ABINIT/duqhqdu
- ABINIT/initorbmag
- ABINIT/make_eeig
- ABINIT/make_onsite_bm
- ABINIT/make_onsite_bm_k_n
- ABINIT/make_onsite_l
- ABINIT/make_onsite_l_k
- ABINIT/make_onsite_l_k_n
- ABINIT/make_rhorij1
- ABINIT/make_rhorij1_k_n
- ABINIT/make_S1trace
- ABINIT/make_S1trace_k_n
- ABINIT/mpicomm_helper
- ABINIT/orbmag_ddk
- ABINIT/orbmag_output
- ABINIT/orbmag_wf
- ABINIT/udsdsu
- ABINIT/udsqdu
- m_orbmag/destroy_orbmag
- m_orbmag/orbmag_type
ABINIT/covar_cprj [ Functions ]
NAME
covar_cprj
FUNCTION
Generate cprj multiplied by S^{-1}, similarly to the wavefunctions in smatrix
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
only printing
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
3876 subroutine covar_cprj(cprj_kb,cprj_kb_covar,dtset,nband_k,pawtab,smat_inv) 3877 3878 !Arguments ------------------------------------ 3879 !scalars 3880 integer,intent(in) :: nband_k 3881 type(dataset_type),intent(in) :: dtset 3882 type(pawcprj_type),intent(in) :: cprj_kb(dtset%natom,nband_k) 3883 type(pawcprj_type),intent(inout) :: cprj_kb_covar(dtset%natom,nband_k) 3884 3885 !arrays 3886 real(dp),intent(in) :: smat_inv(2,nband_k,nband_k) 3887 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 3888 3889 !Local variables ------------------------- 3890 !scalars 3891 integer :: iatom,iband,ilmn,itypat,jband 3892 complex(dpc) :: cpb,smi 3893 3894 !arrays 3895 3896 !---------------------------------------------------- 3897 3898 ! make covar cprj same as covar |unk> 3899 do iatom=1,dtset%natom 3900 itypat = dtset%typat(iatom) 3901 do ilmn=1,pawtab(itypat)%lmn_size 3902 do jband = 1, nband_k 3903 cprj_kb_covar(iatom,jband)%cp(:,ilmn) = zero 3904 do iband = 1, nband_k 3905 cpb=cmplx(cprj_kb(iatom,iband)%cp(1,ilmn),cprj_kb(iatom,iband)%cp(2,ilmn),KIND=dpc) 3906 smi=cmplx(smat_inv(1,iband,jband),smat_inv(2,iband,jband),KIND=dpc) 3907 cprj_kb_covar(iatom,jband)%cp(1,ilmn) = cprj_kb_covar(iatom,jband)%cp(1,ilmn) + & 3908 & real(cpb*smi) 3909 cprj_kb_covar(iatom,jband)%cp(2,ilmn) = cprj_kb_covar(iatom,jband)%cp(2,ilmn) + & 3910 & aimag(cpb*smi) 3911 end do ! end loop over iband 3912 end do ! end loop over jband 3913 end do ! end loop over ilmn 3914 end do ! end loop over iatom 3915 3916 end subroutine covar_cprj
ABINIT/cpg_dij_cpb [ Functions ]
NAME
cpg_dij_cpb
FUNCTION
Compute <u_kg|p_i>dij<p_j|u_kb> energy contribution
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
cgdijcb
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
4753 subroutine cpg_dij_cpb(cgdijcb,cprj_kb,cprj_kg,dtset,nb,ng,nspinor,paw_ij,pawtab) 4754 4755 !Arguments ------------------------------------ 4756 !scalars 4757 integer,intent(in) :: nb,ng,nspinor 4758 complex(dpc),intent(out) :: cgdijcb 4759 type(dataset_type),intent(in) :: dtset 4760 4761 !arrays 4762 type(pawcprj_type),intent(in) :: cprj_kb(dtset%natom,nspinor*dtset%mband) 4763 type(pawcprj_type),intent(in) :: cprj_kg(dtset%natom,nspinor*dtset%mband) 4764 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom) 4765 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 4766 4767 !Local variables ------------------------- 4768 !scalars 4769 integer :: iatom,ilmn,jlmn,klmn,itypat 4770 complex(dpc) :: cdij,cpg,cpb 4771 4772 !----------------------------------------------------------------------- 4773 4774 cgdijcb = czero 4775 do iatom = 1, dtset%natom 4776 itypat = dtset%typat(iatom) 4777 do ilmn = 1, pawtab(itypat)%lmn_size 4778 cpg=cmplx(cprj_kg(iatom,ng)%cp(1,ilmn),cprj_kg(iatom,ng)%cp(2,ilmn),KIND=dpc) 4779 do jlmn = 1, pawtab(itypat)%lmn_size 4780 cpb=cmplx(cprj_kb(iatom,nb)%cp(1,jlmn),cprj_kb(iatom,nb)%cp(2,jlmn),KIND=dpc) 4781 if (jlmn .LE. ilmn) then 4782 klmn = (ilmn-1)*ilmn/2 + jlmn 4783 else 4784 klmn = (jlmn-1)*jlmn/2 + ilmn 4785 end if 4786 if (paw_ij(iatom)%cplex_dij .EQ. 2) then 4787 cdij=cmplx(paw_ij(iatom)%dij(2*klmn-1,1),paw_ij(iatom)%dij(2*klmn,1),KIND=dpc) 4788 if (jlmn .GT. ilmn) cdij=conjg(cdij) 4789 else 4790 cdij=cmplx(paw_ij(iatom)%dij(klmn,1),zero,KIND=dpc) 4791 end if 4792 cgdijcb = cgdijcb + conjg(cpg)*cdij*cpb 4793 end do 4794 end do 4795 end do 4796 4797 end subroutine cpg_dij_cpb
ABINIT/duq_she_qdu [ Functions ]
NAME
duqdu
FUNCTION
Return i*epsabg\sum_n E_nk <\partial_b u_kn|Q{SHE}Q|\partial_g u_kn> where Q projects onto the conduction space, and operator is S_k or E_nk or H_k
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
only printing
SIDE EFFECTS
TODO
NOTES
PARENTS
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
2573 subroutine duq_she_qdu(atindx1,cg,cprj,dtorbmag,dtset,energies,gmet,& 2574 & gprimd,mcg,mcprj,mpi_enreg,nband_k,nfftf,npwarr,out_e,out_h,out_s,pawang,& 2575 & pawfgr,paw_ij,pawrad,pawtab,psps,pwind,pwind_alloc,rmet,rprimd,& 2576 & vectornd,vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 2577 2578 !Arguments ------------------------------------ 2579 !scalars 2580 integer,intent(in) :: mcg,mcprj,nband_k,nfftf,pwind_alloc,with_vectornd 2581 type(dataset_type),intent(in) :: dtset 2582 type(MPI_type), intent(inout) :: mpi_enreg 2583 type(orbmag_type), intent(inout) :: dtorbmag 2584 type(pawang_type),intent(in) :: pawang 2585 type(pawfgr_type),intent(in) :: pawfgr 2586 type(pseudopotential_type),intent(in) :: psps 2587 2588 !arrays 2589 integer,intent(in) :: atindx1(dtset%natom) 2590 integer,intent(in) :: npwarr(dtset%nkpt),pwind(pwind_alloc,2,3) 2591 real(dp), intent(in) :: cg(2,mcg),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3) 2592 real(dp),intent(in) :: energies(nband_k,dtset%nkpt) 2593 real(dp),intent(in) :: vhartr(nfftf),vpsp(nfftf),vxc(nfftf,dtset%nspden),xred(3,dtset%natom) 2594 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 2595 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 2596 real(dp), intent(out) :: out_e(2,nband_k,3),out_h(2,nband_k,3),out_s(2,nband_k,3) 2597 real(dp),intent(inout) :: vectornd(with_vectornd*nfftf,3) 2598 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 2599 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 2600 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 2601 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 2602 2603 !Local variables ------------------------- 2604 !scalars 2605 integer :: adir,bdir,bfor,bsigma,countb,countg,countk,dimffnl,epsabg,exchn2n3d,gdir 2606 integer :: getghc_cpopt,getghc_sij_opt,getghc_prtvol,getghc_tim,getghc_type_calc 2607 integer :: gfor,gsigma,iband,icg,icprji,ider,idir,ierr 2608 integer :: ikg,ikg1,ikpt,ikpt_loc,ikpti,ikptb,ikptbi,ikptg,ikptgi 2609 integer :: ilm,ish1,ish2,isppol,istwf_k,itrs 2610 integer :: me,mcg1_k,my_nspinor,n2dim,ncpgr,ndat,ngfft1,ngfft2,ngfft3 2611 integer :: ngfft4,ngfft5,ngfft6,nkpg,npw_k,npw_k_,npw_kb,npw_kg,nproc,ntotcp 2612 integer :: shiftbd,smatrix_ddkflag,smatrix_job,spaceComm 2613 real(dp) :: deltab,deltag,doti,dotr,ecut_eff,ENK,lambda 2614 complex(dpc) :: cprefac,out_e_term,out_h_term,out_s_term 2615 logical :: has_vectornd 2616 type(gs_hamiltonian_type) :: gs_hamk 2617 2618 !arrays 2619 integer :: nattyp_dum(dtset%ntypat) 2620 integer,allocatable :: dimlmn(:),kg_k(:,:),pwind_kb(:),pwind_kg(:),sflag_k(:) 2621 real(dp) :: dkb(3),dkbg(3),dkg(3),dtm_k(2),kpoint(3),lambda_ndat(1),rhodum(1) 2622 real(dp),allocatable :: bwave(:,:),cg_k(:,:),cg1_kb(:,:),cg1_kg(:,:),cgqb(:,:),cgqg(:,:),cgrvtrial(:,:) 2623 real(dp),allocatable :: ffnl_k(:,:,:,:) 2624 real(dp),allocatable :: ghc(:,:),gsc(:,:),gwave(:,:),gvnlc(:,:),kinpw(:),kk_paw(:,:,:),kpg_k(:,:),pwnsfac_k(:,:) 2625 real(dp),allocatable :: ph3d(:,:,:),smat_inv(:,:,:),smat_kk(:,:,:) 2626 real(dp),allocatable :: vectornd_pac(:,:,:,:,:),vlocal(:,:,:,:),vtrial(:,:) 2627 real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:) 2628 type(pawcprj_type),allocatable :: cprj_buf(:,:),cprj_k(:,:),cprj_kb(:,:),cprj1_kb(:,:) 2629 type(pawcprj_type),allocatable :: cprj_kg(:,:),cprj1_kg(:,:),cwaveprj(:,:) 2630 2631 !---------------------------------------------------- 2632 2633 isppol = 1 2634 ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3) 2635 ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6) 2636 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 2637 exchn2n3d = 0; istwf_k = 1; ikg1 = 0 2638 has_vectornd = (with_vectornd .EQ. 1) 2639 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 2640 spaceComm=mpi_enreg%comm_cell 2641 nproc=xmpi_comm_size(spaceComm) 2642 me=mpi_enreg%me_kpt 2643 2644 ncpgr = cprj(1,1)%ncpgr 2645 ABI_MALLOC(dimlmn,(dtset%natom)) 2646 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 2647 ABI_MALLOC(cprj_k,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 2648 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 2649 ABI_MALLOC(cprj_kb,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 2650 call pawcprj_alloc(cprj_kb,ncpgr,dimlmn) 2651 ABI_MALLOC(cprj1_kb,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 2652 call pawcprj_alloc(cprj1_kb,ncpgr,dimlmn) 2653 ABI_MALLOC(cprj_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 2654 call pawcprj_alloc(cprj_kg,ncpgr,dimlmn) 2655 ABI_MALLOC(cprj1_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 2656 call pawcprj_alloc(cprj1_kg,ncpgr,dimlmn) 2657 ABI_MALLOC(cwaveprj,(dtset%natom,1)) 2658 call pawcprj_alloc(cwaveprj,ncpgr,dimlmn) 2659 n2dim = dtorbmag%nspinor*nband_k 2660 ntotcp = n2dim*SUM(dimlmn(:)) 2661 if (nproc>1) then 2662 ABI_MALLOC(cprj_buf,(dtset%natom,n2dim)) 2663 call pawcprj_alloc(cprj_buf,ncpgr,dimlmn) 2664 end if 2665 2666 ABI_MALLOC(kk_paw,(2,dtset%mband,dtset%mband)) 2667 ABI_MALLOC(sflag_k,(nband_k)) 2668 ABI_MALLOC(pwind_kb,(dtset%mpw)) 2669 ABI_MALLOC(pwind_kg,(dtset%mpw)) 2670 ABI_MALLOC(pwnsfac_k,(4,dtset%mpw)) 2671 pwnsfac_k(1,:) = one; pwnsfac_k(2,:) = zero 2672 pwnsfac_k(3,:) = one; pwnsfac_k(4,:) = zero 2673 2674 mcg1_k = dtset%mpw*dtset%nsppol*my_nspinor*nband_k 2675 ABI_MALLOC(cg_k,(2,mcg1_k)) 2676 ABI_MALLOC(cg1_kb,(2,mcg1_k)) 2677 ABI_MALLOC(cg1_kg,(2,mcg1_k)) 2678 ABI_MALLOC(smat_inv,(2,nband_k,nband_k)) 2679 ABI_MALLOC(smat_kk,(2,nband_k,nband_k)) 2680 2681 smatrix_ddkflag = 1 2682 itrs = 0 2683 smatrix_job = 1 2684 shiftbd = 1 2685 2686 ! input parameters for calls to getghc at ikpt 2687 getghc_cpopt = -1 ! cprj computed and not saved 2688 getghc_sij_opt = 0 ! compute H|C> only 2689 ndat = 1 ! number of fft's in parallel 2690 getghc_prtvol = 0 2691 getghc_type_calc = 3 ! 0: all; 1: local; 2: nonlocal+kinetic; 3: local+kinetic 2692 getghc_tim = 0 2693 lambda = zero 2694 lambda_ndat = zero 2695 2696 !==== Initialize most of the Hamiltonian ==== 2697 !Allocate all arrays and initialize quantities that do not depend on k and spin. 2698 !gs_hamk is the normal hamiltonian at k 2699 call init_hamiltonian(gs_hamk,psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,& 2700 & dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,nucdipmom=dtset%nucdipmom,& 2701 & paw_ij=paw_ij) 2702 2703 !---------construct local potential------------------ 2704 ABI_MALLOC(vtrial,(nfftf,dtset%nspden)) 2705 ! nspden=1 is essentially hard-coded in the following line 2706 vtrial(1:nfftf,1)=vhartr(1:nfftf)+vxc(1:nfftf,1)+vpsp(1:nfftf) 2707 2708 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 2709 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial) 2710 2711 ABI_MALLOC(vlocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc)) 2712 call fftpac(isppol,mpi_enreg,dtset%nspden,ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,& 2713 & dtset%ngfft,cgrvtrial,vlocal,2) 2714 2715 ABI_FREE(cgrvtrial) 2716 ABI_FREE(vtrial) 2717 2718 ! if vectornd is present, set it up for addition to gs_hamk similarly to how it's done for 2719 ! vtrial. Note that it must be done for the three directions. Also, the following 2720 ! code assumes explicitly and implicitly that nvloc = 1. This should eventually be generalized. 2721 if(has_vectornd) then 2722 ABI_MALLOC(vectornd_pac,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,3)) 2723 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 2724 do idir = 1, 3 2725 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vectornd(:,idir)) 2726 call fftpac(isppol,mpi_enreg,dtset%nspden,& 2727 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vectornd_pac(:,:,:,1,idir),2) 2728 end do 2729 ABI_FREE(cgrvtrial) 2730 end if 2731 2732 ! add vlocal 2733 call gs_hamk%load_spin(isppol,vlocal=vlocal,with_nonlocal=.true.) 2734 2735 ! add vectornd if available 2736 if(has_vectornd) then 2737 call gs_hamk%load_spin(isppol,vectornd=vectornd_pac) 2738 end if 2739 2740 out_s = zero 2741 out_e = zero 2742 out_h = zero 2743 2744 do ikpt_loc = 1,dtorbmag%fmkmem_max 2745 2746 ikpt=mpi_enreg%kpt_loc2fbz_sp(me, ikpt_loc,1) 2747 ! if this k and spin are for me do it 2748 ! if (ikpt1 > 0 .and. isppol > 0) then 2749 if (ikpt > 0) then 2750 2751 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 2752 icprji = dtorbmag%cprjindex(ikpti,isppol) 2753 ikg = dtorbmag%fkgindex(ikpt) 2754 npw_k = npwarr(ikpti) 2755 ABI_MALLOC(kg_k,(3,npw_k)) 2756 ABI_MALLOC(kinpw,(npw_k)) 2757 kpoint(:)=dtset%kptns(:,ikpt) 2758 kg_k(:,:) = 0 2759 call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg_k,kpoint,1,mpi_enreg,dtset%mpw,npw_k_) 2760 kinpw(:) = zero 2761 call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,kinpw,kpoint,npw_k,0,0) 2762 nkpg = 3 2763 ABI_MALLOC(kpg_k,(npw_k,nkpg)) 2764 call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k) 2765 2766 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang)) 2767 ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm)) 2768 do ilm=1,psps%mpsang*psps%mpsang 2769 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 2770 ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm) 2771 end do 2772 2773 ! Compute nonlocal form factors ffnl at all (k+G): 2774 ider=0 ! want ffnl and 1st derivative 2775 idir=4 ! d ffnl/ dk_red in all 3 directions 2776 dimffnl=1 ! 1 + number of derivatives 2777 ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat)) 2778 call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,& 2779 & gmet,gprimd,ider,idir,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,& 2780 & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,& 2781 & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,rmet,& 2782 & psps%usepaw,psps%useylm,ylm_k,ylmgr_k) 2783 2784 ABI_MALLOC(ph3d,(2,npw_k,gs_hamk%matblk)) 2785 call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,& 2786 & kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,& 2787 & ph3d_k=ph3d,compute_ph3d=.TRUE.,compute_gbound=.TRUE.) 2788 2789 icg = dtorbmag%cgindex(ikpti,dtset%nsppol) 2790 ikg = dtorbmag%fkgindex(ikpt) 2791 countk = npw_k*my_nspinor*nband_k 2792 cg_k(1:2,1:countk) = cg(1:2,icg+1:icg+countk) 2793 2794 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprji,ikpti,0,isppol,dtset%mband,& 2795 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 2796 end if 2797 2798 do adir = 1, 3 2799 do epsabg = 1, -1, -2 2800 if (epsabg .EQ. 1) then 2801 bdir = modulo(adir,3)+1 2802 gdir = modulo(adir+1,3)+1 2803 else 2804 bdir = modulo(adir+1,3)+1 2805 gdir = modulo(adir,3)+1 2806 end if 2807 do bfor = 1, 2 2808 bsigma = 3-2*bfor 2809 dkb(1:3) = bsigma*dtorbmag%dkvecs(1:3,bdir) 2810 deltab = sqrt(DOT_PRODUCT(dkb,dkb)) 2811 2812 if (ikpt > 0) then 2813 ikptb = dtorbmag%ikpt_dk(ikpt,bfor,bdir) 2814 ikptbi = dtorbmag%indkk_f2ibz(ikptb,1) 2815 npw_kb = npwarr(ikptbi) 2816 pwind_kb(1:npw_k) = pwind(ikg+1:ikg+npw_k,bfor,bdir) 2817 end if 2818 2819 if (ikpt > 0 .AND. isppol > 0) then 2820 countb = npw_kb*my_nspinor*nband_k 2821 if(allocated(cgqb)) then 2822 ABI_FREE(cgqb) 2823 endif 2824 ABI_MALLOC(cgqb,(2,countb)) 2825 call mpicomm_helper(atindx1,bdir,bfor,cg,cgqb,cprj,cprj_kb,dimlmn,dtorbmag,dtset,& 2826 & ikpt,ikpt_loc,ikptbi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 2827 & nproc,npw_kb,npwarr,spaceComm) 2828 end if 2829 2830 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 2831 2832 ! get covariant |u_{n,k+b}> and associated cprj 2833 call overlap_k1k2_paw(cprj_k,cprj_kb,dkb,gprimd,kk_paw,dtorbmag%lmn2max,& 2834 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 2835 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 2836 sflag_k=0 2837 cg1_kb(:,:) = zero 2838 ! cg1_kb will hold |\tilde{u}_{n,k+b}> 2839 call smatrix(cg_k,cgqb,cg1_kb,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 2840 & mcg1_k,mcg1_k,mcg1_k,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kb,my_nspinor,& 2841 & pwind_kb,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 2842 ! cprj1_kb will hold cprj for cg1_kb 2843 call covar_cprj(cprj_kb,cprj1_kb,dtset,nband_k,pawtab,smat_inv) 2844 2845 if(allocated(cgqb)) then 2846 ABI_FREE(cgqb) 2847 end if 2848 2849 end if 2850 2851 do gfor = 1, 2 2852 gsigma=3-2*gfor 2853 dkg(1:3) = gsigma*dtorbmag%dkvecs(1:3,gdir) 2854 deltag = sqrt(DOT_PRODUCT(dkg,dkg)) 2855 2856 cprefac = j_dpc*epsabg*bsigma*gsigma/(two*deltab*two*deltag) 2857 2858 if (ikpt > 0) then 2859 ikptg = dtorbmag%ikpt_dk(ikpt,gfor,gdir) 2860 ikptgi = dtorbmag%indkk_f2ibz(ikptg,1) 2861 npw_kg = npwarr(ikptgi) 2862 pwind_kg(1:npw_k) = pwind(ikg+1:ikg+npw_k,gfor,gdir) 2863 2864 end if 2865 2866 2867 if (ikpt > 0 .AND. isppol > 0) then 2868 countg = npw_kg*my_nspinor*nband_k 2869 if(allocated(cgqg)) then 2870 ABI_FREE(cgqg) 2871 endif 2872 ABI_MALLOC(cgqg,(2,countg)) 2873 call mpicomm_helper(atindx1,gdir,gfor,cg,cgqg,cprj,cprj_kg,dimlmn,dtorbmag,dtset,& 2874 & ikpt,ikpt_loc,ikptgi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 2875 & nproc,npw_kg,npwarr,spaceComm) 2876 end if 2877 2878 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 2879 2880 ! get covariant |u_{n,k+g}> and associated cprj 2881 call overlap_k1k2_paw(cprj_k,cprj_kg,dkg,gprimd,kk_paw,dtorbmag%lmn2max,& 2882 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 2883 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 2884 sflag_k=0 2885 cg1_kg(:,:) = zero 2886 ! cg1_kg will hold |\tilde{u}_{n,k+g}> 2887 call smatrix(cg_k,cgqg,cg1_kg,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 2888 & mcg1_k,mcg1_k,mcg1_k,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kg,my_nspinor,& 2889 & pwind_kg,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 2890 ! cprj1_kg will hold cprj for cg1_kg 2891 call covar_cprj(cprj_kg,cprj1_kg,dtset,nband_k,pawtab,smat_inv) 2892 2893 dkbg = dkg - dkb 2894 ! overlap of covariant cprj at kb and kg 2895 call overlap_k1k2_paw(cprj1_kb,cprj1_kg,dkbg,gprimd,kk_paw,dtorbmag%lmn2max,& 2896 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 2897 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 2898 2899 ABI_MALLOC(bwave,(2,npw_k)) 2900 ABI_MALLOC(gwave,(2,npw_k)) 2901 ABI_MALLOC(ghc,(2,npw_k)) 2902 ABI_MALLOC(gsc,(2,npw_k)) 2903 ABI_MALLOC(gvnlc,(2,npw_k)) 2904 do iband = 1, nband_k 2905 2906 ish1 = (iband-1)*npw_k+1 2907 ish2 = iband*npw_k 2908 ENK = energies(iband,ikpt) 2909 2910 bwave(1:2,1:npw_k) = cg1_kb(1:2,ish1:ish2) 2911 gwave(1:2,1:npw_k) = cg1_kg(1:2,ish1:ish2) 2912 2913 dotr= DOT_PRODUCT(bwave(1,:),gwave(1,:))+DOT_PRODUCT(bwave(2,:),gwave(2,:)) 2914 doti=-DOT_PRODUCT(bwave(2,:),gwave(1,:))+DOT_PRODUCT(bwave(1,:),gwave(2,:)) 2915 2916 ! accumulate i*epsabg*\sum_occ [<d_bdir u|Q_SHE_Q|d_gdir u>] 2917 out_s_term = cprefac*cmplx((dotr+kk_paw(1,iband,iband)),(doti+kk_paw(2,iband,iband))) 2918 out_e_term = out_s_term*ENK 2919 2920 out_s(1,iband,adir) = out_s(1,iband,adir) + real(out_s_term) 2921 out_s(2,iband,adir) = out_s(2,iband,adir) + aimag(out_s_term) 2922 out_e(1,iband,adir) = out_e(1,iband,adir) + real(out_e_term) 2923 out_e(2,iband,adir) = out_e(2,iband,adir) + aimag(out_e_term) 2924 2925 call getghc(getghc_cpopt,bwave,cwaveprj,ghc,gsc,gs_hamk,gvnlc,& 2926 & lambda,mpi_enreg,ndat,getghc_prtvol,getghc_sij_opt,getghc_tim,& 2927 & getghc_type_calc) 2928 dotr= DOT_PRODUCT(gwave(1,:),ghc(1,:))+DOT_PRODUCT(gwave(2,:),ghc(2,:)) 2929 doti=-DOT_PRODUCT(gwave(2,:),ghc(1,:))+DOT_PRODUCT(gwave(1,:),ghc(2,:)) 2930 2931 !call cpg_dij_cpb(cgdijcb,cprj1_kb,cprj1_kg,dtset,iband,iband,my_nspinor,paw_ij,pawtab) 2932 !out_h_term = cprefac*(cmplx(dotr,doti) + cgdijcb) 2933 2934 ! the following includes only the kinetic and local contributions from H_k, the 2935 ! onsite contributions, which are much more complex than paw_ij, have not been coded 2936 out_h_term = cprefac*cmplx(dotr,doti) 2937 2938 out_h(1,iband,adir) = out_h(1,iband,adir) + real(out_h_term) 2939 out_h(2,iband,adir) = out_h(2,iband,adir) + aimag(out_h_term) 2940 2941 end do ! end loop over iband 2942 ABI_FREE(bwave) 2943 ABI_FREE(gwave) 2944 ABI_FREE(ghc) 2945 ABI_FREE(gsc) 2946 ABI_FREE(gvnlc) 2947 2948 if(allocated(cgqg)) then 2949 ABI_FREE(cgqg) 2950 end if 2951 2952 end if ! end check on ikpt > 0 2953 2954 end do ! end loop over gfor 2955 end do ! end loop over bfor 2956 end do ! end loop over epsabg 2957 end do ! end loop over adir 2958 ABI_FREE(kg_k) 2959 ABI_FREE(kinpw) 2960 ABI_FREE(kpg_k) 2961 ABI_FREE(ffnl_k) 2962 ABI_FREE(ylm_k) 2963 ABI_FREE(ylmgr_k) 2964 ABI_FREE(ph3d) 2965 end do ! end loop over ikpt_loc 2966 2967 ! ---- parallel communication 2968 if(nproc > 1) then 2969 call xmpi_sum(out_s,spaceComm,ierr) 2970 call xmpi_sum(out_e,spaceComm,ierr) 2971 call xmpi_sum(out_h,spaceComm,ierr) 2972 end if 2973 2974 ABI_FREE(dimlmn) 2975 call pawcprj_free(cprj_k) 2976 ABI_FREE(cprj_k) 2977 call pawcprj_free(cprj_kb) 2978 ABI_FREE(cprj_kb) 2979 call pawcprj_free(cprj1_kb) 2980 ABI_FREE(cprj1_kb) 2981 call pawcprj_free(cprj_kg) 2982 ABI_FREE(cprj_kg) 2983 call pawcprj_free(cprj1_kg) 2984 ABI_FREE(cprj1_kg) 2985 call pawcprj_free(cwaveprj) 2986 ABI_FREE(cwaveprj) 2987 if (nproc>1) then 2988 call pawcprj_free(cprj_buf) 2989 ABI_FREE(cprj_buf) 2990 end if 2991 2992 ABI_FREE(kk_paw) 2993 ABI_FREE(smat_kk) 2994 ABI_FREE(smat_inv) 2995 ABI_FREE(sflag_k) 2996 ABI_FREE(pwind_kb) 2997 ABI_FREE(pwind_kg) 2998 ABI_FREE(cg1_kb) 2999 ABI_FREE(cg1_kg) 3000 ABI_FREE(cg_k) 3001 ABI_FREE(pwnsfac_k) 3002 call gs_hamk%free() 3003 ABI_FREE(vlocal) 3004 if(has_vectornd) then 3005 ABI_FREE(vectornd_pac) 3006 end if 3007 3008 end subroutine duq_she_qdu
ABINIT/duqdu [ Functions ]
NAME
duqdu
FUNCTION
Return i*epsabg\sum_n E_nk <\partial_b u_kn|Q|\partial_g u_kn> where Q projects onto the conduction space.
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
only printing
SIDE EFFECTS
TODO
NOTES
PARENTS
CHILDREN
SOURCE
3044 subroutine duqdu(atindx1,cg,cprj,dtorbmag,dtset,duqduchern,duqdumag,energies,& 3045 & gprimd,mcg,mcprj,mpi_enreg,nband_k,npwarr,pawang,pawrad,pawtab,& 3046 & psps,pwind,pwind_alloc,xred) 3047 3048 !Arguments ------------------------------------ 3049 !scalars 3050 integer,intent(in) :: mcg,mcprj,nband_k,pwind_alloc 3051 type(dataset_type),intent(in) :: dtset 3052 type(MPI_type), intent(inout) :: mpi_enreg 3053 type(orbmag_type), intent(inout) :: dtorbmag 3054 type(pawang_type),intent(in) :: pawang 3055 type(pseudopotential_type),intent(in) :: psps 3056 3057 !arrays 3058 integer,intent(in) :: atindx1(dtset%natom) 3059 integer,intent(in) :: npwarr(dtset%nkpt),pwind(pwind_alloc,2,3) 3060 real(dp), intent(in) :: cg(2,mcg),gprimd(3,3),xred(3,dtset%natom) 3061 real(dp),intent(in) :: energies(nband_k,dtset%nkpt) 3062 real(dp), intent(out) :: duqduchern(2,nband_k,3),duqdumag(2,nband_k,3) 3063 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 3064 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 3065 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 3066 3067 !Local variables ------------------------- 3068 !scalars 3069 integer :: adir,bdir,bfor,bsigma,countb,countg,countk 3070 integer :: epsabg,gdir,gfor,gsigma,iband 3071 integer :: icg,icprji,ierr 3072 integer :: ikg,ikpt,ikpt_loc,ikpti,ikptb,ikptbi,ikptg,ikptgi,ish1,ish2,isppol,itrs 3073 integer :: me,mcg1_k,my_nspinor,n2dim,ncpgr,npw_k,npw_kb,npw_kg,nproc,ntotcp 3074 integer :: shiftbd,smatrix_ddkflag,smatrix_job,spaceComm 3075 real(dp) :: deltab,deltag,doti,dotr,ENK 3076 complex(dpc) :: cprefac,duqduchern_term,duqdumag_term 3077 3078 !arrays 3079 integer :: nattyp_dum(dtset%ntypat) 3080 integer,allocatable :: dimlmn(:),pwind_kb(:),pwind_kg(:),sflag_k(:) 3081 real(dp) :: dkb(3),dkbg(3),dkg(3),dtm_k(2) 3082 real(dp),allocatable :: cg_k(:,:),cg1_kb(:,:),cg1_kg(:,:),cgqb(:,:),cgqg(:,:) 3083 real(dp),allocatable :: kk_paw(:,:,:),pwnsfac_k(:,:) 3084 real(dp),allocatable :: smat_inv(:,:,:),smat_kk(:,:,:) 3085 type(pawcprj_type),allocatable :: cprj_buf(:,:),cprj_k(:,:),cprj_kb(:,:),cprj1_kb(:,:) 3086 type(pawcprj_type),allocatable :: cprj_kg(:,:),cprj1_kg(:,:) 3087 3088 !---------------------------------------------------- 3089 3090 isppol = 1 3091 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 3092 spaceComm=mpi_enreg%comm_cell 3093 nproc=xmpi_comm_size(spaceComm) 3094 me=mpi_enreg%me_kpt 3095 3096 ncpgr = cprj(1,1)%ncpgr 3097 ABI_MALLOC(dimlmn,(dtset%natom)) 3098 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 3099 ABI_MALLOC(cprj_k,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3100 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 3101 ABI_MALLOC(cprj_kb,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3102 call pawcprj_alloc(cprj_kb,ncpgr,dimlmn) 3103 ABI_MALLOC(cprj1_kb,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3104 call pawcprj_alloc(cprj1_kb,ncpgr,dimlmn) 3105 ABI_MALLOC(cprj_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3106 call pawcprj_alloc(cprj_kg,ncpgr,dimlmn) 3107 ABI_MALLOC(cprj1_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3108 call pawcprj_alloc(cprj1_kg,ncpgr,dimlmn) 3109 n2dim = dtorbmag%nspinor*nband_k 3110 ntotcp = n2dim*SUM(dimlmn(:)) 3111 if (nproc>1) then 3112 ABI_MALLOC(cprj_buf,(dtset%natom,n2dim)) 3113 call pawcprj_alloc(cprj_buf,ncpgr,dimlmn) 3114 end if 3115 3116 ABI_MALLOC(kk_paw,(2,dtset%mband,dtset%mband)) 3117 ABI_MALLOC(sflag_k,(nband_k)) 3118 ABI_MALLOC(pwind_kb,(dtset%mpw)) 3119 ABI_MALLOC(pwind_kg,(dtset%mpw)) 3120 ABI_MALLOC(pwnsfac_k,(4,dtset%mpw)) 3121 pwnsfac_k(1,:) = one; pwnsfac_k(2,:) = zero 3122 pwnsfac_k(3,:) = one; pwnsfac_k(4,:) = zero 3123 3124 mcg1_k = dtset%mpw*dtset%nsppol*my_nspinor*nband_k 3125 ABI_MALLOC(cg_k,(2,mcg1_k)) 3126 ABI_MALLOC(cg1_kb,(2,mcg1_k)) 3127 ABI_MALLOC(cg1_kg,(2,mcg1_k)) 3128 ABI_MALLOC(smat_inv,(2,nband_k,nband_k)) 3129 ABI_MALLOC(smat_kk,(2,nband_k,nband_k)) 3130 3131 smatrix_ddkflag = 1 3132 itrs = 0 3133 smatrix_job = 1 3134 shiftbd = 1 3135 3136 duqduchern(:,:,:) = zero 3137 duqdumag(:,:,:) = zero 3138 3139 do ikpt_loc = 1,dtorbmag%fmkmem_max 3140 3141 ikpt=mpi_enreg%kpt_loc2fbz_sp(me, ikpt_loc,1) 3142 ! if this k and spin are for me do it 3143 ! if (ikpt1 > 0 .and. isppol > 0) then 3144 if (ikpt > 0) then 3145 3146 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 3147 icprji = dtorbmag%cprjindex(ikpti,isppol) 3148 npw_k = npwarr(ikpti) 3149 icg = dtorbmag%cgindex(ikpti,dtset%nsppol) 3150 ikg = dtorbmag%fkgindex(ikpt) 3151 countk = npw_k*my_nspinor*nband_k 3152 cg_k(1:2,1:countk) = cg(1:2,icg+1:icg+countk) 3153 3154 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprji,ikpti,0,isppol,dtset%mband,& 3155 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 3156 end if 3157 3158 do adir = 1, 3 3159 do epsabg = 1, -1, -2 3160 if (epsabg .EQ. 1) then 3161 bdir = modulo(adir,3)+1 3162 gdir = modulo(adir+1,3)+1 3163 else 3164 bdir = modulo(adir+1,3)+1 3165 gdir = modulo(adir,3)+1 3166 end if 3167 do bfor = 1, 2 3168 bsigma = 3-2*bfor 3169 dkb(1:3) = bsigma*dtorbmag%dkvecs(1:3,bdir) 3170 deltab = sqrt(DOT_PRODUCT(dkb,dkb)) 3171 3172 if (ikpt > 0) then 3173 ikptb = dtorbmag%ikpt_dk(ikpt,bfor,bdir) 3174 ikptbi = dtorbmag%indkk_f2ibz(ikptb,1) 3175 npw_kb = npwarr(ikptbi) 3176 pwind_kb(1:npw_k) = pwind(ikg+1:ikg+npw_k,bfor,bdir) 3177 end if 3178 3179 if (ikpt > 0 .AND. isppol > 0) then 3180 countb = npw_kb*my_nspinor*nband_k 3181 if(allocated(cgqb)) then 3182 ABI_FREE(cgqb) 3183 endif 3184 ABI_MALLOC(cgqb,(2,countb)) 3185 call mpicomm_helper(atindx1,bdir,bfor,cg,cgqb,cprj,cprj_kb,dimlmn,dtorbmag,dtset,& 3186 & ikpt,ikpt_loc,ikptbi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 3187 & nproc,npw_kb,npwarr,spaceComm) 3188 end if 3189 3190 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 3191 3192 ! get covariant |u_{n,k+b}> and associated cprj 3193 call overlap_k1k2_paw(cprj_k,cprj_kb,dkb,gprimd,kk_paw,dtorbmag%lmn2max,& 3194 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 3195 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 3196 sflag_k=0 3197 cg1_kb(:,:) = zero 3198 ! cg1_kb will hold |\tilde{u}_{n,k+b}> 3199 call smatrix(cg_k,cgqb,cg1_kb,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 3200 & mcg1_k,mcg1_k,mcg1_k,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kb,my_nspinor,& 3201 & pwind_kb,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 3202 ! cprj1_kb will hold cprj for cg1_kb 3203 call covar_cprj(cprj_kb,cprj1_kb,dtset,nband_k,pawtab,smat_inv) 3204 3205 if(allocated(cgqb)) then 3206 ABI_FREE(cgqb) 3207 end if 3208 3209 end if 3210 3211 do gfor = 1, 2 3212 gsigma=3-2*gfor 3213 dkg(1:3) = gsigma*dtorbmag%dkvecs(1:3,gdir) 3214 deltag = sqrt(DOT_PRODUCT(dkg,dkg)) 3215 3216 cprefac = j_dpc*epsabg*bsigma*gsigma/(two*deltab*two*deltag) 3217 3218 if (ikpt > 0) then 3219 ikptg = dtorbmag%ikpt_dk(ikpt,gfor,gdir) 3220 ikptgi = dtorbmag%indkk_f2ibz(ikptg,1) 3221 npw_kg = npwarr(ikptgi) 3222 pwind_kg(1:npw_k) = pwind(ikg+1:ikg+npw_k,gfor,gdir) 3223 3224 end if 3225 3226 3227 if (ikpt > 0 .AND. isppol > 0) then 3228 countg = npw_kg*my_nspinor*nband_k 3229 if(allocated(cgqg)) then 3230 ABI_FREE(cgqg) 3231 endif 3232 ABI_MALLOC(cgqg,(2,countg)) 3233 call mpicomm_helper(atindx1,gdir,gfor,cg,cgqg,cprj,cprj_kg,dimlmn,dtorbmag,dtset,& 3234 & ikpt,ikpt_loc,ikptgi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 3235 & nproc,npw_kg,npwarr,spaceComm) 3236 end if 3237 3238 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 3239 3240 ! get covariant |u_{n,k+g}> and associated cprj 3241 call overlap_k1k2_paw(cprj_k,cprj_kg,dkg,gprimd,kk_paw,dtorbmag%lmn2max,& 3242 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 3243 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 3244 sflag_k=0 3245 cg1_kg(:,:) = zero 3246 ! cg1_kg will hold |\tilde{u}_{n,k+g}> 3247 call smatrix(cg_k,cgqg,cg1_kg,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 3248 & mcg1_k,mcg1_k,mcg1_k,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kg,my_nspinor,& 3249 & pwind_kg,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 3250 ! cprj1_kg will hold cprj for cg1_kg 3251 call covar_cprj(cprj_kg,cprj1_kg,dtset,nband_k,pawtab,smat_inv) 3252 3253 dkbg = dkg - dkb 3254 ! overlap of covariant cprj at kb and kg 3255 call overlap_k1k2_paw(cprj1_kb,cprj1_kg,dkbg,gprimd,kk_paw,dtorbmag%lmn2max,& 3256 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 3257 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 3258 do iband = 1, nband_k 3259 3260 ish1 = (iband-1)*npw_k+1 3261 ish2 = iband*npw_k 3262 ENK = energies(iband,ikpt) 3263 3264 dotr=DOT_PRODUCT(cg1_kb(1,ish1:ish2),cg1_kg(1,ish1:ish2)) + & 3265 & DOT_PRODUCT(cg1_kb(2,ish1:ish2),cg1_kg(2,ish1:ish2)) 3266 doti=DOT_PRODUCT(cg1_kb(1,ish1:ish2),cg1_kg(2,ish1:ish2)) - & 3267 & DOT_PRODUCT(cg1_kb(2,ish1:ish2),cg1_kg(1,ish1:ish2)) 3268 3269 ! accumulate i*epsabg*ENK*\sum_occ [<d_bdir u|Q|d_gdir u>] 3270 duqduchern_term = cprefac*cmplx((dotr+kk_paw(1,iband,iband)),(doti+kk_paw(2,iband,iband))) 3271 duqdumag_term = duqduchern_term*ENK 3272 3273 duqduchern(1,iband,adir) = duqduchern(1,iband,adir) + real(duqduchern_term) 3274 duqduchern(2,iband,adir) = duqduchern(2,iband,adir) + aimag(duqduchern_term) 3275 duqdumag(1,iband,adir) = duqdumag(1,iband,adir) + real(duqdumag_term) 3276 duqdumag(2,iband,adir) = duqdumag(2,iband,adir) + aimag(duqdumag_term) 3277 3278 end do ! end loop over iband 3279 if(allocated(cgqg)) then 3280 ABI_FREE(cgqg) 3281 end if 3282 end if ! end check on ikpt > 0 3283 3284 end do ! end loop over gfor 3285 end do ! end loop over bfor 3286 end do ! end loop over epsabg 3287 end do ! end loop over adir 3288 end do ! end loop over ikpt_loc 3289 3290 ! ---- parallel communication 3291 if(nproc > 1) then 3292 call xmpi_sum(duqduchern,spaceComm,ierr) 3293 call xmpi_sum(duqdumag,spaceComm,ierr) 3294 end if 3295 3296 ABI_FREE(dimlmn) 3297 call pawcprj_free(cprj_k) 3298 ABI_FREE(cprj_k) 3299 call pawcprj_free(cprj_kb) 3300 ABI_FREE(cprj_kb) 3301 call pawcprj_free(cprj1_kb) 3302 ABI_FREE(cprj1_kb) 3303 call pawcprj_free(cprj_kg) 3304 ABI_FREE(cprj_kg) 3305 call pawcprj_free(cprj1_kg) 3306 ABI_FREE(cprj1_kg) 3307 if (nproc>1) then 3308 call pawcprj_free(cprj_buf) 3309 ABI_FREE(cprj_buf) 3310 end if 3311 3312 ABI_FREE(kk_paw) 3313 ABI_FREE(smat_kk) 3314 ABI_FREE(smat_inv) 3315 ABI_FREE(sflag_k) 3316 ABI_FREE(pwind_kb) 3317 ABI_FREE(pwind_kg) 3318 ABI_FREE(cg1_kb) 3319 ABI_FREE(cg1_kg) 3320 ABI_FREE(cg_k) 3321 ABI_FREE(pwnsfac_k) 3322 3323 end subroutine duqdu
ABINIT/duqhqdu [ Functions ]
NAME
duqhqdu
FUNCTION
Return i*epsabg\sum_n <\partial_g u_kn|QH_kQ|\partial_b u_kn> where Q projects onto the conduction space.
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
only printing
SIDE EFFECTS
TODO
NOTES
PARENTS
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
3953 subroutine duqhqdu(atindx1,cg,cnum_duqhqdu,cprj,dtorbmag,dtset,gmet,gprimd,mcg,mcprj,mpi_enreg,& 3954 & nattyp,nband_k,nfftf,npwarr,paw_ij,pawang,pawfgr,pawrad,pawtab,psps,pwind,pwind_alloc,& 3955 & rmet,rprimd,ucvol,vectornd,vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 3956 3957 !Arguments ------------------------------------ 3958 !scalars 3959 integer,intent(in) :: mcg,mcprj,nband_k,nfftf,pwind_alloc,with_vectornd 3960 real(dp),intent(in) :: ucvol 3961 type(dataset_type),intent(in) :: dtset 3962 type(MPI_type), intent(inout) :: mpi_enreg 3963 type(orbmag_type), intent(inout) :: dtorbmag 3964 type(pawang_type),intent(in) :: pawang 3965 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 3966 type(pseudopotential_type),intent(in) :: psps 3967 3968 !arrays 3969 integer, intent(in) :: atindx1(dtset%natom) 3970 integer, intent(in) :: nattyp(dtset%ntypat),npwarr(dtset%nkpt),pwind(pwind_alloc,2,3) 3971 real(dp), intent(in) :: cg(2,mcg),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3) 3972 real(dp), intent(in) :: vhartr(nfftf),vpsp(nfftf),vxc(nfftf,dtset%nspden),xred(3,dtset%natom) 3973 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 3974 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 3975 real(dp), intent(inout) :: vectornd(with_vectornd*nfftf,3) 3976 real(dp), intent(out) :: cnum_duqhqdu(2,nband_k,3) 3977 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 3978 type(pawfgr_type),intent(in) :: pawfgr 3979 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 3980 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 3981 3982 !Local variables ------------------------- 3983 !scalars 3984 integer :: adir,bdir,bfor,bsigma,countb,countg,countk,cpopt,dimffnl 3985 integer :: getcprj_choice,getcprj_cpopt,getcprj_idir 3986 integer :: epsabg,exchn2n3d,gdir,gfor,gsigma,ia,iband,ibs1,ibs2 3987 integer :: icg,icprji,ider,idir,ierr 3988 integer :: ikg,ikg1,ikpt,ikpt_loc,ikpti,ikptb,ikptbi,ikptg,ikptgi 3989 integer :: ilm,isppol,istwf_k,itrs 3990 integer :: me,my_nspinor,ncpgr,ndat 3991 integer :: ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,nkpg,npw_k,npw_k_,npw_kb,npw_kg,nproc 3992 integer :: prtvol,shiftbd,sij_opt,smatrix_ddkflag,smatrix_job,spaceComm 3993 integer :: tim_getghc,type_calc 3994 real(dp) :: arg,deltab,deltag,doti,dotr,ecut_eff,lambda 3995 complex(dpc) :: cgdijcb,cprefac,duqhqdu_term 3996 logical :: has_vectornd 3997 type(gs_hamiltonian_type) :: gs_hamk 3998 3999 !arrays 4000 integer :: nattyp_dum(dtset%ntypat) 4001 integer,allocatable :: dimlmn(:),kg_k(:,:),pwind_kb(:),pwind_kg(:),sflag_k(:) 4002 real(dp) :: dkb(3),dkg(3),dtm_k(2),kpoint(3),lambdarr(1),rhodum(1) 4003 real(dp),allocatable :: cg_k(:,:),cg1_kb(:,:),cg1_kg(:,:),cgrvtrial(:,:) 4004 real(dp),allocatable :: cgqb(:,:),cgqg(:,:),cwavef(:,:),ffnl(:,:,:,:) 4005 real(dp),allocatable :: ghc(:,:),ghcall(:,:),gsc(:,:),gvnlc(:,:) 4006 real(dp),allocatable :: kinpw(:),kk_paw(:,:,:),kpg_k(:,:) 4007 real(dp),allocatable :: ph1d(:,:),ph3d(:,:,:),phkxred(:,:),pwnsfac_k(:,:) 4008 real(dp),allocatable :: smat_inv(:,:,:),smat_kk(:,:,:) 4009 real(dp),allocatable :: vectornd_pac(:,:,:,:,:),vlocal(:,:,:,:),vtrial(:,:) 4010 real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:) 4011 type(pawcprj_type),allocatable :: cprj_k(:,:),cprj_kb(:,:),cprj1_kb(:,:) 4012 type(pawcprj_type),allocatable :: cprj_kg(:,:),cprj1_kg(:,:),cwaveprj(:,:) 4013 4014 !---------------------------------------------------- 4015 4016 isppol = 1 4017 ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3) 4018 ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6) 4019 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 4020 exchn2n3d = 0 ; istwf_k = 1 ; ikg1 = 0 4021 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 4022 spaceComm=mpi_enreg%comm_cell 4023 nproc=xmpi_comm_size(spaceComm) 4024 me=mpi_enreg%me_kpt 4025 4026 ! input parameters for calls to getghc at ikpt 4027 cpopt = -1 4028 ndat = 1 4029 prtvol = 0 4030 sij_opt = 0 4031 tim_getghc = 0 4032 ! getghc: type_calc 3 means kinetic, local only 4033 ! type_calc 1 means local only 4034 type_calc = 3 4035 lambda = zero; lambdarr(1) = zero 4036 4037 ! input parameters for calls to getcprj 4038 getcprj_choice = 1 ! just cprj no gradients 4039 getcprj_cpopt = 0 ! no cprj in memory already 4040 getcprj_idir = 0 ! gradient directions irrelevant here 4041 4042 !==== Initialize most of the Hamiltonian ==== 4043 !Allocate all arrays and initialize quantities that do not depend on k and spin. 4044 !gs_hamk is the normal hamiltonian at k 4045 call init_hamiltonian(gs_hamk,psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,& 4046 & dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,nucdipmom=dtset%nucdipmom,& 4047 & paw_ij=paw_ij) 4048 4049 !---------construct local potential------------------ 4050 ABI_MALLOC(vtrial,(nfftf,dtset%nspden)) 4051 ! nspden=1 is essentially hard-coded in the following line 4052 vtrial(1:nfftf,1)=vhartr(1:nfftf)+vxc(1:nfftf,1)+vpsp(1:nfftf) 4053 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 4054 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial) 4055 ABI_MALLOC(vlocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc)) 4056 call fftpac(isppol,mpi_enreg,dtset%nspden,& 4057 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vlocal,2) 4058 ! add vlocal 4059 call gs_hamk%load_spin(isppol,vlocal=vlocal,with_nonlocal=.false.) 4060 ABI_FREE(cgrvtrial) 4061 ABI_FREE(vtrial) 4062 4063 ! if vectornd is present, set it up for addition to gs_hamk similarly to how it's done for 4064 ! vtrial. Note that it must be done for the three directions. Also, the following 4065 ! code assumes explicitly and implicitly that nvloc = 1. This should eventually be generalized. 4066 has_vectornd = (with_vectornd .EQ. 1) 4067 if(has_vectornd) then 4068 ABI_MALLOC(vectornd_pac,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,3)) 4069 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 4070 do adir = 1, 3 4071 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vectornd(:,adir)) 4072 call fftpac(isppol,mpi_enreg,dtset%nspden,& 4073 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vectornd_pac(:,:,:,1,adir),2) 4074 end do 4075 call gs_hamk%load_spin(isppol,vectornd=vectornd_pac) 4076 ABI_FREE(cgrvtrial) 4077 end if 4078 4079 ABI_MALLOC(ph1d,(2,dtset%natom*(2*(ngfft1+ngfft2+ngfft3)+3))) 4080 call getph(atindx1,dtset%natom,ngfft1,ngfft2,ngfft3,ph1d,xred) 4081 4082 ncpgr = cprj(1,1)%ncpgr 4083 ABI_MALLOC(dimlmn,(dtset%natom)) 4084 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 4085 ABI_MALLOC(cprj_k,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 4086 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 4087 ABI_MALLOC(cprj_kb,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 4088 call pawcprj_alloc(cprj_kb,ncpgr,dimlmn) 4089 ABI_MALLOC(cprj1_kb,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 4090 call pawcprj_alloc(cprj1_kb,ncpgr,dimlmn) 4091 ABI_MALLOC(cprj_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 4092 call pawcprj_alloc(cprj_kg,ncpgr,dimlmn) 4093 ABI_MALLOC(cprj1_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 4094 call pawcprj_alloc(cprj1_kg,ncpgr,dimlmn) 4095 ABI_MALLOC(cwaveprj,(dtset%natom,1)) 4096 call pawcprj_alloc(cwaveprj,ncpgr,dimlmn) 4097 4098 smatrix_ddkflag = 1 4099 itrs = 0 4100 smatrix_job = 1 4101 shiftbd = 1 4102 4103 ABI_MALLOC(kk_paw,(2,dtset%mband,dtset%mband)) 4104 ABI_MALLOC(smat_kk,(2,dtset%mband,dtset%mband)) 4105 ABI_MALLOC(smat_inv,(2,dtset%mband,dtset%mband)) 4106 ABI_MALLOC(sflag_k,(nband_k)) 4107 ABI_MALLOC(pwind_kb,(dtset%mpw)) 4108 ABI_MALLOC(pwind_kg,(dtset%mpw)) 4109 ABI_MALLOC(pwnsfac_k,(4,dtset%mpw)) 4110 pwnsfac_k(1,:) = one; pwnsfac_k(2,:) = zero 4111 pwnsfac_k(3,:) = one; pwnsfac_k(4,:) = zero 4112 4113 cnum_duqhqdu(:,:,:) = zero 4114 4115 do ikpt_loc = 1,dtorbmag%fmkmem_max 4116 4117 ikpt=mpi_enreg%kpt_loc2fbz_sp(me, ikpt_loc,1) 4118 ! if this k and spin are for me do it 4119 ! if (ikpt1 > 0 .and. isppol > 0) then 4120 if (ikpt > 0) then 4121 4122 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 4123 kpoint(:)=dtorbmag%fkptns(:,ikpt) 4124 icprji = dtorbmag%cprjindex(ikpti,isppol) 4125 npw_k = npwarr(ikpti) 4126 icg = dtorbmag%cgindex(ikpti,dtset%nsppol) 4127 ikg = dtorbmag%fkgindex(ikpt) 4128 4129 ! wavefunction at k 4130 countk = npw_k*my_nspinor*nband_k 4131 ABI_MALLOC(cg_k,(2,countk)) 4132 cg_k(1:2,1:countk) = cg(1:2,icg+1:icg+countk) 4133 4134 ! cprj at k 4135 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprji,ikpti,0,isppol,dtset%mband,& 4136 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 4137 4138 ! kg_k and k+G_k at k 4139 ABI_MALLOC(kg_k,(3,npw_k)) 4140 kg_k = 0 4141 call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg_k,kpoint,1,mpi_enreg,dtset%mpw,npw_k_) 4142 if (npw_k .NE. npw_k_) then 4143 write(std_out,'(a)')'JWZ debug duqhqdu npw_k inconsistency' 4144 end if 4145 nkpg = 3 4146 ABI_MALLOC(kpg_k,(npw_k,nkpg)) 4147 call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k) 4148 4149 ! Compute kinetic energy at k 4150 ABI_MALLOC(kinpw,(npw_k)) 4151 kinpw(:) = zero 4152 call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,kinpw,kpoint,npw_k,0,0) 4153 4154 ! this is minimal Hamiltonian information, to apply vlocal and kinetic to |u_kn> 4155 ! Build basis sphere of plane waves for the k-point 4156 4157 call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,& 4158 & kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k,compute_gbound=.TRUE.) 4159 4160 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang)) 4161 do ilm=1,psps%mpsang*psps%mpsang 4162 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 4163 end do 4164 4165 ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm)) 4166 do ilm=1,psps%mpsang*psps%mpsang 4167 ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm) 4168 end do 4169 4170 ABI_MALLOC(phkxred,(2,dtset%natom)) 4171 do ia=1, dtset%natom 4172 arg=two_pi*(kpoint(1)*xred(1,ia)+kpoint(2)*xred(2,ia)+kpoint(3)*xred(3,ia)) 4173 phkxred(1,ia)=cos(arg);phkxred(2,ia)=sin(arg) 4174 end do 4175 4176 ABI_MALLOC(ph3d,(2,npw_k,dtset%natom)) 4177 call ph1d3d(1,dtset%natom,kg_k,dtset%natom,dtset%natom,& 4178 & npw_k,ngfft1,ngfft2,ngfft3,phkxred,ph1d,ph3d) 4179 4180 ! Compute nonlocal form factors ffnl at k 4181 dimffnl=1 ! 1 + number of derivatives 4182 ABI_MALLOC(ffnl,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat)) 4183 ider=0 ! no derivs 4184 idir=4 ! derivs in all directions of cart (not used if ider = 0) 4185 call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl,psps%ffspl,& 4186 & gmet,gprimd,ider,idir,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,& 4187 & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,& 4188 & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,rmet,& 4189 & psps%usepaw,psps%useylm,ylm_k,ylmgr_k) 4190 4191 ABI_FREE(ylm_k) 4192 ABI_FREE(ylmgr_k) 4193 4194 end if 4195 4196 do adir = 1, 3 4197 do epsabg = 1, -1, -2 4198 if (epsabg .EQ. 1) then 4199 bdir = modulo(adir,3)+1 4200 gdir = modulo(adir+1,3)+1 4201 else 4202 bdir = modulo(adir+1,3)+1 4203 gdir = modulo(adir,3)+1 4204 end if 4205 do bfor = 1, 2 4206 bsigma = 3-2*bfor 4207 dkb(1:3) = bsigma*dtorbmag%dkvecs(1:3,bdir) 4208 deltab = sqrt(DOT_PRODUCT(dkb,dkb)) 4209 4210 if(ikpt > 0) then 4211 ikptb = dtorbmag%ikpt_dk(ikpt,bfor,bdir) 4212 ikptbi = dtorbmag%indkk_f2ibz(ikptb,1) 4213 npw_kb = npwarr(ikptbi) 4214 pwind_kb(1:npw_k) = pwind(ikg+1:ikg+npw_k,bfor,bdir) 4215 4216 end if 4217 4218 if (ikpt > 0 .AND. isppol > 0) then 4219 countb = npw_kb*my_nspinor*nband_k 4220 ABI_MALLOC(cgqb,(2,countb)) 4221 call mpicomm_helper(atindx1,bdir,bfor,cg,cgqb,cprj,cprj_kb,dimlmn,dtorbmag,dtset,& 4222 & ikpt,ikpt_loc,ikptbi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 4223 & nproc,npw_kb,npwarr,spaceComm) 4224 end if 4225 4226 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 4227 ! get covariant |u_{n,k+b}> and associated cprj 4228 call overlap_k1k2_paw(cprj_k,cprj_kb,dkb,gprimd,kk_paw,dtorbmag%lmn2max,& 4229 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 4230 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 4231 sflag_k=0 4232 4233 ABI_MALLOC(cg1_kb,(2,countk)) 4234 cg1_kb(:,:) = zero 4235 ! cg1_kb will hold |\tilde{u}_{n,k+b}> 4236 call smatrix(cg_k,cgqb,cg1_kb,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 4237 & countk,countb,countk,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kb,my_nspinor,& 4238 & pwind_kb,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 4239 4240 ! cprj1_kb will hold cprj for cg1_kb that is <p|\tilde{u}_{n,k+b}> 4241 call covar_cprj(cprj_kb,cprj1_kb,dtset,nband_k,pawtab,smat_inv) 4242 4243 ABI_FREE(cgqb) 4244 4245 ABI_MALLOC(cwavef,(2,npw_k)) 4246 ABI_MALLOC(ghc,(2,npw_k)) 4247 ABI_MALLOC(gsc,(2,npw_k)) 4248 ABI_MALLOC(gvnlc,(2,npw_k)) 4249 ABI_MALLOC(ghcall,(2,npw_k*nband_k)) 4250 4251 do iband = 1, nband_k 4252 ibs1 = (iband-1)*npw_k+1 4253 ibs2 = iband*npw_k 4254 cwavef(1:2,1:npw_k) = cg1_kb(1:2,ibs1:ibs2) 4255 call pawcprj_get(atindx1,cwaveprj,cprj1_kb,dtset%natom,iband,0,ikptb,0,isppol,dtset%mband,& 4256 & dtset%mkmem,dtset%natom,1,nband_k,my_nspinor,dtset%nsppol,0) 4257 call getghc(cpopt,cwavef,cwaveprj,ghc,gsc,gs_hamk,gvnlc,lambda,mpi_enreg,ndat,& 4258 & prtvol,sij_opt,tim_getghc,type_calc) 4259 ghcall(1:2,ibs1:ibs2) = ghc(1:2,1:npw_k) 4260 end do 4261 ABI_FREE(ghc) 4262 ABI_FREE(gsc) 4263 ABI_FREE(gvnlc) 4264 4265 ! cprj generated here at k, rather than at k+b 4266 call pawcprj_set_zero(cprj1_kb) 4267 do iband = 1, nband_k 4268 ibs1 = (iband-1)*npw_k+1 4269 ibs2 = iband*npw_k 4270 cwavef(1:2,1:npw_k) = cg1_kb(1:2,ibs1:ibs2) 4271 call getcprj(getcprj_choice,getcprj_cpopt,cwavef,cwaveprj,ffnl,& 4272 & getcprj_idir,psps%indlmn,istwf_k,kg_k,kpg_k,kpoint,psps%lmnmax,& 4273 & dtset%mgfft,mpi_enreg,& 4274 & dtset%natom,nattyp,dtset%ngfft,dtset%nloalg,npw_k,dtset%nspinor,dtset%ntypat,& 4275 & phkxred,ph1d,ph3d,ucvol,psps%useylm) 4276 4277 call pawcprj_put(atindx1,cwaveprj,cprj1_kb,dtset%natom,& 4278 & iband,0,ikpt,0,isppol,nband_k,dtset%mkmem,& 4279 & dtset%natom,1,nband_k,dimlmn,dtset%nspinor,dtset%nsppol,0,& 4280 & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb) 4281 end do 4282 ABI_FREE(cg1_kb) 4283 ABI_FREE(cwavef) 4284 4285 end if 4286 4287 do gfor = 1, 2 4288 gsigma=3-2*gfor 4289 dkg(1:3) = gsigma*dtorbmag%dkvecs(1:3,gdir) 4290 deltag = sqrt(DOT_PRODUCT(dkg,dkg)) 4291 4292 cprefac = j_dpc*epsabg*bsigma*gsigma/(two*deltab*two*deltag) 4293 4294 if (ikpt > 0) then 4295 ikptg = dtorbmag%ikpt_dk(ikpt,gfor,gdir) 4296 ikptgi = dtorbmag%indkk_f2ibz(ikptg,1) 4297 npw_kg = npwarr(ikptgi) 4298 pwind_kg(1:npw_k) = pwind(ikg+1:ikg+npw_k,gfor,gdir) 4299 4300 end if 4301 4302 if (ikpt > 0 .AND. isppol > 0) then 4303 countg = npw_kg*my_nspinor*nband_k 4304 ABI_MALLOC(cgqg,(2,countg)) 4305 call mpicomm_helper(atindx1,gdir,gfor,cg,cgqg,cprj,cprj_kg,dimlmn,dtorbmag,dtset,& 4306 & ikpt,ikpt_loc,ikptgi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 4307 & nproc,npw_kg,npwarr,spaceComm) 4308 end if 4309 4310 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 4311 4312 ! get covariant |u_{n,k+g}> and associated cprj 4313 call overlap_k1k2_paw(cprj_k,cprj_kg,dkg,gprimd,kk_paw,dtorbmag%lmn2max,& 4314 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 4315 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 4316 sflag_k=0 4317 ABI_MALLOC(cg1_kg,(2,countk)) 4318 cg1_kg(:,:) = zero 4319 ! cg1_kg will hold |\tilde{u}_{n,k+g}> 4320 call smatrix(cg_k,cgqg,cg1_kg,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 4321 & countk,countg,countk,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kg,my_nspinor,& 4322 & pwind_kg,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 4323 ABI_FREE(cgqg) 4324 4325 ! ! cprj1_kg will hold cprj for cg1_kg that is <p|\tilde{u}_{n,k+g}> 4326 ! call covar_cprj(cprj_kg,cprj1_kg,dtset,nband_k,pawtab,smat_inv) 4327 4328 ABI_MALLOC(cwavef,(2,npw_k)) 4329 ! cprj generated here at k, rather than at k+g 4330 call pawcprj_set_zero(cprj1_kg) 4331 do iband = 1, nband_k 4332 ibs1 = (iband-1)*npw_k+1 4333 ibs2 = iband*npw_k 4334 cwavef(1:2,1:npw_k) = cg1_kg(1:2,ibs1:ibs2) 4335 call getcprj(getcprj_choice,getcprj_cpopt,cwavef,cwaveprj,ffnl,& 4336 & getcprj_idir,psps%indlmn,istwf_k,kg_k,kpg_k,kpoint,psps%lmnmax,& 4337 & dtset%mgfft,mpi_enreg,& 4338 & dtset%natom,nattyp,dtset%ngfft,dtset%nloalg,npw_k,dtset%nspinor,dtset%ntypat,& 4339 & phkxred,ph1d,ph3d,ucvol,psps%useylm) 4340 4341 call pawcprj_put(atindx1,cwaveprj,cprj1_kg,dtset%natom,& 4342 & iband,0,ikpt,0,isppol,nband_k,dtset%mkmem,& 4343 & dtset%natom,1,nband_k,dimlmn,dtset%nspinor,dtset%nsppol,0,& 4344 & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb) 4345 end do 4346 ABI_FREE(cwavef) 4347 4348 do iband = 1, nband_k 4349 ibs1=(iband-1)*npw_k+1 4350 ibs2=iband*npw_k 4351 dotr=DOT_PRODUCT(cg1_kg(1,ibs1:ibs2),ghcall(1,ibs1:ibs2)) + & 4352 & DOT_PRODUCT(cg1_kg(2,ibs1:ibs2),ghcall(2,ibs1:ibs2)) 4353 doti=DOT_PRODUCT(cg1_kg(1,ibs1:ibs2),ghcall(2,ibs1:ibs2)) - & 4354 & DOT_PRODUCT(cg1_kg(2,ibs1:ibs2),ghcall(1,ibs1:ibs2)) 4355 4356 ! compute onsite contribution due to paw_ij%dij 4357 call cpg_dij_cpb(cgdijcb,cprj1_kb,cprj1_kg,dtset,iband,iband,dtorbmag%nspinor,paw_ij,pawtab) 4358 4359 ! accumulate i*epsabg*\sum_occ [<d_gdir u|QHQ|d_bdir u>] 4360 ! duqhqdu_term = cprefac*(cmplx(dotr,doti)+cgdijcb) 4361 duqhqdu_term = cprefac*cmplx(dotr,doti) 4362 ! duqhqdu_term = cprefac*cgdijcb 4363 cnum_duqhqdu(1,iband,adir) = cnum_duqhqdu(1,iband,adir) + real(duqhqdu_term) 4364 cnum_duqhqdu(2,iband,adir) = cnum_duqhqdu(2,iband,adir) + aimag(duqhqdu_term) 4365 4366 end do ! end loop over iband 4367 ABI_FREE(cg1_kg) 4368 4369 end if ! end check on ikpt > 0 4370 4371 end do ! end loop over gfor 4372 4373 ABI_FREE(ghcall) 4374 4375 end do ! end loop over bfor 4376 end do ! end loop over epsabg 4377 end do ! end loop over adir 4378 4379 if (ikpt > 0) then 4380 ABI_FREE(cg_k) 4381 ABI_FREE(kg_k) 4382 ABI_FREE(kpg_k) 4383 ABI_FREE(kinpw) 4384 ABI_FREE(phkxred) 4385 ABI_FREE(ph3d) 4386 ABI_FREE(ffnl) 4387 end if 4388 4389 end do ! end loop over ikpt_loc 4390 4391 ! ---- parallel communication 4392 if(nproc > 1) then 4393 call xmpi_sum(cnum_duqhqdu,spaceComm,ierr) 4394 end if 4395 4396 call gs_hamk%free() 4397 ABI_FREE(vlocal) 4398 if(has_vectornd) then 4399 ABI_FREE(vectornd_pac) 4400 end if 4401 4402 ABI_FREE(ph1d) 4403 4404 ABI_FREE(dimlmn) 4405 call pawcprj_free(cprj_k) 4406 ABI_FREE(cprj_k) 4407 call pawcprj_free(cprj_kb) 4408 ABI_FREE(cprj_kb) 4409 call pawcprj_free(cprj_kg) 4410 ABI_FREE(cprj_kg) 4411 call pawcprj_free(cprj1_kb) 4412 ABI_FREE(cprj1_kb) 4413 call pawcprj_free(cprj1_kg) 4414 ABI_FREE(cprj1_kg) 4415 call pawcprj_free(cwaveprj) 4416 ABI_FREE(cwaveprj) 4417 4418 ABI_FREE(kk_paw) 4419 ABI_FREE(smat_kk) 4420 ABI_FREE(smat_inv) 4421 ABI_FREE(sflag_k) 4422 ABI_FREE(pwind_kb) 4423 ABI_FREE(pwind_kg) 4424 ABI_FREE(pwnsfac_k) 4425 4426 end subroutine duqhqdu
ABINIT/initorbmag [ Functions ]
NAME
initorbmag
FUNCTION
Initialization of orbital magnetization calculation; similar to initberry
COPYRIGHT
Copyright (C) 2004-2020 ABINIT group. This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
INPUTS
dtset <type(dataset_type)> = all input variables in this dataset gmet(3,3) = reciprocal space metric tensor in bohr**-2 gprimd(3,3) = primitive translations in recip space kg(3,mpw*mkmem) = reduced (integer) coordinates of G vecs in basis sphere npwarr(nkpt) = number of planewaves in basis and boundary at this k point occ(mband*nkpt*nsppol) = occup number for each band at each k point pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data psps <type(pseudopotential_type)>=variables related to pseudopotentials rprimd(3,3) = dimensional primitive vectors symrec(3,3,nsym) = symmetries in reciprocal space in terms of reciprocal space primitive translations xred(3,natom) = location of atoms in reduced units
OUTPUT
dtorbmag <type(orbmag_type)> = variables related to orbital magnetization
SIDE EFFECTS
mpi_enreg = information about MPI parallelization
PARENTS
m_gstate
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
310 subroutine initorbmag(dtorbmag,dtset,gmet,gprimd,kg,mpi_enreg,npwarr,occ,& 311 & pawtab,psps,pwind,pwind_alloc,pwnsfac,& 312 & rprimd,symrec,xred) 313 314 !Arguments ------------------------------------ 315 !scalars 316 integer,intent(out) :: pwind_alloc 317 type(MPI_type),intent(inout) :: mpi_enreg 318 type(dataset_type),intent(inout) :: dtset 319 type(orbmag_type),intent(out) :: dtorbmag 320 type(pseudopotential_type),intent(in) :: psps 321 !arrays 322 integer,intent(in) :: kg(3,dtset%mpw*dtset%mkmem),npwarr(dtset%nkpt) 323 integer,intent(in) :: symrec(3,3,dtset%nsym) 324 integer,pointer :: pwind(:,:,:) 325 real(dp),intent(in) :: gmet(3,3),gprimd(3,3),occ(dtset%mband*dtset%nkpt*dtset%nsppol) 326 real(dp),intent(in) :: rprimd(3,3),xred(3,dtset%natom) 327 real(dp),pointer :: pwnsfac(:,:) 328 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 329 330 !Local variables------------------------------- 331 !scalars 332 integer :: brav,exchn2n3d,fnkpt_computed 333 integer :: iband,icg,icprj,idir,idum,idum1,ierr,ifor,ikg,ikg1 334 integer :: ikpt,ikpt_loc,ikpti,ikpt1,ikpt1f,ikpt1i 335 integer :: index,ipw,ipwnsfac,isign,isppol,istwf_k,isym,isym1,itrs,itypat 336 integer :: jpw,lmax,lmn2_size_max 337 integer :: mband_occ_k,me,me_g0,mkmem_,mkpt,my_nspinor,nband_k,nkptlatt,nproc,npw_k,npw_k1 338 integer :: option,spaceComm 339 real(dp) :: diffk1,diffk2,diffk3,ecut_eff 340 real(dp) :: kpt_shifted1,kpt_shifted2,kpt_shifted3,rdum 341 character(len=500) :: message 342 !arrays 343 integer :: iadum(3),iadum1(3),dg(3) 344 integer,allocatable :: kg1_k(:,:) 345 real(dp) :: diffk(3),dk(3),dum33(3,3),kpt1(3),tsec(2) 346 real(dp),allocatable :: spkpt(:,:) 347 348 ! ************************************************************************* 349 350 DBG_ENTER("COLL") 351 352 call timab(1001,1,tsec) 353 call timab(1002,1,tsec) 354 355 !save the current value of nspinor 356 dtorbmag%nspinor = dtset%nspinor 357 358 !---------------------------------------------------------------------------- 359 !-------------------- Obtain k-point grid in the full BZ -------------------- 360 !---------------------------------------------------------------------------- 361 362 if(dtset%kptopt==1 .or. dtset%kptopt==2 .or. dtset%kptopt==4)then 363 ! Compute the number of k points in the G-space unit cell 364 nkptlatt=dtset%kptrlatt(1,1)*dtset%kptrlatt(2,2)*dtset%kptrlatt(3,3) & 365 & +dtset%kptrlatt(1,2)*dtset%kptrlatt(2,3)*dtset%kptrlatt(3,1) & 366 & +dtset%kptrlatt(1,3)*dtset%kptrlatt(2,1)*dtset%kptrlatt(3,2) & 367 & -dtset%kptrlatt(1,2)*dtset%kptrlatt(2,1)*dtset%kptrlatt(3,3) & 368 & -dtset%kptrlatt(1,3)*dtset%kptrlatt(2,2)*dtset%kptrlatt(3,1) & 369 & -dtset%kptrlatt(1,1)*dtset%kptrlatt(2,3)*dtset%kptrlatt(3,2) 370 371 ! Call smpbz to obtain the list of k-point in the full BZ - without symmetry reduction 372 option = 0 373 brav = 1 374 mkpt=nkptlatt*dtset%nshiftk 375 ABI_MALLOC(spkpt,(3,mkpt)) 376 call smpbz(1,ab_out,dtset%kptrlatt,mkpt,fnkpt_computed,dtset%nshiftk,option,dtset%shiftk,spkpt) 377 dtorbmag%fnkpt = fnkpt_computed 378 ABI_MALLOC(dtorbmag%fkptns,(3,dtorbmag%fnkpt)) 379 dtorbmag%fkptns(:,:)=spkpt(:,1:dtorbmag%fnkpt) 380 ABI_FREE(spkpt) 381 else if(dtset%kptopt==3.or.dtset%kptopt==0)then 382 dtorbmag%fnkpt=dtset%nkpt 383 ABI_MALLOC(dtorbmag%fkptns,(3,dtorbmag%fnkpt)) 384 dtorbmag%fkptns(1:3,1:dtorbmag%fnkpt)=dtset%kpt(1:3,1:dtorbmag%fnkpt) 385 if(dtset%kptopt==0)then 386 write(message,'(10a)') ch10,& 387 & ' initorbmag : WARNING -',ch10,& 388 & ' you have defined manually the k-point grid with kptopt = 0',ch10,& 389 & ' the orbital magnetization calculation works only with a regular k-points grid,',ch10,& 390 & ' abinit doesn''t check if your grid is regular...' 391 call wrtout(std_out,message,'PERS') 392 end if 393 end if 394 395 !call listkk to get mapping from FBZ to IBZ 396 rdum=1.0d-5 ! cutoff distance to decide when two k points match 397 ABI_MALLOC(dtorbmag%indkk_f2ibz,(dtorbmag%fnkpt,6)) 398 399 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 400 spaceComm=mpi_enreg%comm_cell 401 402 !JWZ: The following may need modification in the future 403 !**** no spin-polarization doubling ; do not allow use of time reversal symmetry **** 404 405 call timab(1002,2,tsec) 406 call timab(1003,1,tsec) 407 408 call listkk(rdum,gmet,dtorbmag%indkk_f2ibz,dtset%kptns,dtorbmag%fkptns,dtset%nkpt,& 409 & dtorbmag%fnkpt,dtset%nsym,1,dtset%symafm,symrec,0,spaceComm,use_symrec=.True.) 410 411 call timab(1003,2,tsec) 412 call timab(1004,1,tsec) 413 414 !Construct i2fbz and f2ibz 415 ABI_MALLOC(dtorbmag%i2fbz,(dtset%nkpt)) 416 idum=0 417 do ikpt=1,dtorbmag%fnkpt 418 if (dtorbmag%indkk_f2ibz(ikpt,2)==1 .and. & 419 & dtorbmag%indkk_f2ibz(ikpt,6) == 0 .and. & 420 & maxval(abs(dtorbmag%indkk_f2ibz(ikpt,3:5))) == 0 ) then 421 dtorbmag%i2fbz(dtorbmag%indkk_f2ibz(ikpt,1))=ikpt 422 idum=idum+1 423 end if 424 end do 425 if (idum/=dtset%nkpt)then 426 message = ' Found wrong number of k-points in IBZ' 427 ABI_ERROR(message) 428 end if 429 430 !---------------------------------------------------------------------------- 431 !------------- Allocate PAW space as necessary ------------------------------ 432 !---------------------------------------------------------------------------- 433 434 dtorbmag%usepaw = psps%usepaw 435 dtorbmag%natom = dtset%natom 436 dtorbmag%my_natom = mpi_enreg%my_natom 437 438 ABI_MALLOC(dtorbmag%lmn_size,(dtset%ntypat)) 439 ABI_MALLOC(dtorbmag%lmn2_size,(dtset%ntypat)) 440 do itypat = 1, dtset%ntypat 441 dtorbmag%lmn_size(itypat) = pawtab(itypat)%lmn_size 442 dtorbmag%lmn2_size(itypat) = pawtab(itypat)%lmn2_size 443 end do 444 445 lmn2_size_max = psps%lmnmax*(psps%lmnmax+1)/2 446 dtorbmag%lmn2max = lmn2_size_max 447 448 ABI_MALLOC(dtorbmag%cprjindex,(dtset%nkpt,dtset%nsppol)) 449 dtorbmag%cprjindex(:,:) = 0 450 451 if (dtset%kptopt /= 3) then 452 ABI_MALLOC(dtorbmag%atom_indsym,(4,dtset%nsym,dtorbmag%natom)) 453 call symatm(dtorbmag%atom_indsym,dtorbmag%natom,dtset%nsym,symrec,dtset%tnons,tol8,dtset%typat,xred) 454 lmax = psps%mpsang - 1 455 ABI_MALLOC(dtorbmag%zarot,(2*lmax+1,2*lmax+1,lmax+1,dtset%nsym)) 456 call setsym_ylm(gprimd,lmax,dtset%nsym,1,rprimd,symrec,dtorbmag%zarot) 457 dtorbmag%nsym = dtset%nsym 458 dtorbmag%lmax = lmax 459 dtorbmag%lmnmax = psps%lmnmax 460 end if 461 462 ! !------------------------------------------------------------------------------ 463 ! !------------------- Compute variables related to MPI // ---------------------- 464 ! !------------------------------------------------------------------------------ 465 spaceComm=mpi_enreg%comm_cell 466 nproc=xmpi_comm_size(spaceComm) 467 me=xmpi_comm_rank(spaceComm) 468 469 if (nproc==1) then 470 dtorbmag%fmkmem = dtorbmag%fnkpt 471 dtorbmag%fmkmem_max = dtorbmag%fnkpt 472 dtorbmag%mkmem_max = dtset%nkpt 473 else 474 dtorbmag%fmkmem = 0 475 do ikpt = 1, dtorbmag%fnkpt 476 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 477 nband_k = dtset%nband(ikpti) 478 if (.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpti,1,nband_k,-1,me))) & 479 & dtorbmag%fmkmem = dtorbmag%fmkmem + 1 480 end do 481 ! Maximum value of mkmem and fmkmem 482 call xmpi_max(dtorbmag%fmkmem,dtorbmag%fmkmem_max,spaceComm,ierr) 483 ! I have to use the dummy variable mkmem_ because 484 ! mkmem is declared as intent(in) while the first 485 ! argument of xmpi_max must be intent(inout) 486 mkmem_ = dtset%mkmem 487 call xmpi_max(mkmem_,dtorbmag%mkmem_max,spaceComm,ierr) 488 end if 489 490 ABI_MALLOC(mpi_enreg%kpt_loc2fbz_sp,(0:nproc-1,1:dtorbmag%fmkmem_max*dtset%nsppol, 1:2)) 491 ABI_MALLOC(mpi_enreg%kpt_loc2ibz_sp,(0:nproc-1,1:dtorbmag%mkmem_max*dtset%nsppol, 1:2)) 492 ABI_MALLOC(mpi_enreg%kptdstrb,(nproc,6,dtorbmag%fmkmem_max*dtset%nsppol*2)) 493 ABI_MALLOC(mpi_enreg%mkmem,(0:nproc-1)) 494 mpi_enreg%kpt_loc2fbz_sp(:,:,:) = 0 495 mpi_enreg%kpt_loc2ibz_sp(:,:,:) = 0 496 mpi_enreg%kptdstrb(:,:,:) = 0 497 mpi_enreg%mkmem(:) = 0 498 499 pwind_alloc = dtset%mpw*dtorbmag%fmkmem_max 500 501 ABI_MALLOC(pwind,(pwind_alloc,2,3)) 502 ABI_MALLOC(pwnsfac,(2,pwind_alloc)) 503 504 ! !------------------------------------------------------------------------------ 505 ! !---------------------- Compute orbmag_type variables ------------------------- 506 ! !------------------------------------------------------------------------------ 507 508 !Initialization of orbmag_type variables 509 dtorbmag%dkvecs(:,:) = zero 510 ABI_MALLOC(dtorbmag%ikpt_dk,(dtorbmag%fnkpt,2,3)) 511 ABI_MALLOC(dtorbmag%cgindex,(dtset%nkpt,dtset%nsppol)) 512 ABI_MALLOC(dtorbmag%kgindex,(dtset%nkpt)) 513 ABI_MALLOC(dtorbmag%fkgindex,(dtorbmag%fnkpt)) 514 dtorbmag%ikpt_dk(:,:,:) = 0 515 dtorbmag%cgindex(:,:) = 0 516 dtorbmag%mband_occ = 0 517 ABI_MALLOC(dtorbmag%nband_occ,(dtset%nsppol)) 518 dtorbmag%kgindex(:) = 0 519 dtorbmag%fkgindex(:) = 0 520 ABI_MALLOC(dtorbmag%kg,(3,dtset%mpw*dtset%mkmem)) 521 dtorbmag%kg(:,:) = kg(:,:) 522 523 !Compute spin degeneracy 524 if (dtset%nsppol == 1 .and. dtset%nspinor == 1) then 525 dtorbmag%sdeg = two 526 else if (dtset%nsppol == 2 .or. my_nspinor == 2) then 527 dtorbmag%sdeg = one 528 end if 529 530 !Compute the number of occupied bands and check that 531 !it is the same for each k-point 532 533 index = 0 534 do isppol = 1, dtset%nsppol 535 dtorbmag%nband_occ(isppol) = 0 536 do ikpt = 1, dtset%nkpt 537 538 mband_occ_k = 0 539 nband_k = dtset%nband(ikpt + (isppol - 1)*dtset%nkpt) 540 541 do iband = 1, nband_k 542 index = index + 1 543 if (abs(occ(index) - dtorbmag%sdeg) < tol8) mband_occ_k = mband_occ_k + 1 544 end do 545 546 if (ikpt > 1) then 547 if (dtorbmag%nband_occ(isppol) /= mband_occ_k) then 548 message = "The number of valence bands is not the same for every k-point of present spin channel" 549 ABI_ERROR(message) 550 end if 551 else 552 dtorbmag%mband_occ = max(dtorbmag%mband_occ, mband_occ_k) 553 dtorbmag%nband_occ(isppol) = mband_occ_k 554 end if 555 556 end do ! close loop over ikpt 557 end do ! close loop over isppol 558 559 !Compute the location of each wavefunction 560 561 icg = 0 562 icprj = 0 563 !ikg = 0 564 do isppol = 1, dtset%nsppol 565 do ikpt = 1, dtset%nkpt 566 567 nband_k = dtset%nband(ikpt + (isppol-1)*dtset%nkpt) 568 569 if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) cycle 570 571 dtorbmag%cgindex(ikpt,isppol) = icg 572 npw_k = npwarr(ikpt) 573 icg = icg + npw_k*dtorbmag%nspinor*nband_k 574 575 if (psps%usepaw == 1) then 576 dtorbmag%cprjindex(ikpt,isppol) = icprj 577 icprj = icprj + dtorbmag%nspinor*nband_k 578 end if 579 580 end do 581 end do 582 583 ikg = 0 584 do ikpt = 1, dtset%nkpt 585 if ((proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,1,me)).and.& 586 & (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,dtset%nsppol,me))) cycle 587 588 npw_k = npwarr(ikpt) 589 dtorbmag%kgindex(ikpt) = ikg 590 ikg = ikg + npw_k 591 end do 592 593 call timab(1004,2,tsec) 594 595 !------------------------------------------------------------------------------ 596 !---------------------- Compute dk -------------------------------------------- 597 !------------------------------------------------------------------------------ 598 599 call timab(1005,1,tsec) 600 601 do idir = 1, 3 602 603 ! Compute dk(:), the vector between a k-point and its nearest 604 ! neighbour along the direction idir 605 606 dk(:) = zero 607 dk(idir) = 1._dp ! 1 mean there is no other k-point un the direction idir 608 do ikpt = 2, dtorbmag%fnkpt 609 diffk(:) = abs(dtorbmag%fkptns(:,ikpt) - dtorbmag%fkptns(:,1)) 610 if ((diffk(1) < dk(1)+tol8).and.(diffk(2) < dk(2)+tol8).and.& 611 & (diffk(3) < dk(3)+tol8)) dk(:) = diffk(:) 612 end do 613 dtorbmag%dkvecs(:,idir) = dk(:) 614 ! DEBUG 615 ! write(std_out,*)' initorbmag : idir, dk', idir, dk 616 ! ENDDEBUG 617 618 ! For each k point, find k_prim such that k_prim= k + dk mod(G) 619 ! where G is a vector of the reciprocal lattice 620 621 do ikpt = 1, dtorbmag%fnkpt 622 623 ! First k+dk, then k-dk 624 do isign=-1,1,2 625 kpt_shifted1=dtorbmag%fkptns(1,ikpt)- isign*dk(1) 626 kpt_shifted2=dtorbmag%fkptns(2,ikpt)- isign*dk(2) 627 kpt_shifted3=dtorbmag%fkptns(3,ikpt)- isign*dk(3) 628 ! Note that this is still a order fnkpt**2 algorithm. 629 ! It is possible to implement a order fnkpt algorithm, see listkk.F90. 630 do ikpt1 = 1, dtorbmag%fnkpt 631 diffk1=dtorbmag%fkptns(1,ikpt1) - kpt_shifted1 632 if(abs(diffk1-nint(diffk1))>tol8)cycle 633 diffk2=dtorbmag%fkptns(2,ikpt1) - kpt_shifted2 634 if(abs(diffk2-nint(diffk2))>tol8)cycle 635 diffk3=dtorbmag%fkptns(3,ikpt1) - kpt_shifted3 636 if(abs(diffk3-nint(diffk3))>tol8)cycle 637 dtorbmag%ikpt_dk(ikpt,(isign+3)/2,idir) = ikpt1 638 exit 639 end do ! ikpt1 640 end do ! isign 641 642 end do ! ikpt 643 644 end do ! close loop over idir 645 646 call timab(1005,2,tsec) 647 call timab(1006,1,tsec) 648 649 !------------------------------------------------------------------------------ 650 !------------ Build the array pwind that is needed to compute the ------------- 651 !------------ overlap matrices at k +- dk ------------- 652 !------------------------------------------------------------------------------ 653 654 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 655 exchn2n3d = 0 ; istwf_k = 1 ; ikg1 = 0 656 pwind(:,:,:) = 0 657 pwnsfac(1,:) = 1.0_dp 658 pwnsfac(2,:) = 0.0_dp 659 ABI_MALLOC(kg1_k,(3,dtset%mpw)) 660 661 ipwnsfac = 0 662 663 do idir = 1, 3 664 665 dk(:) = dtorbmag%dkvecs(:,idir) 666 667 do ifor = 1, 2 668 669 if (ifor == 2) dk(:) = -1._dp*dk(:) 670 671 ! Build pwind and kgindex 672 ! NOTE: The array kgindex is important for parallel execution. 673 ! In case nsppol = 2, it may happen that a particular processor 674 ! treats k-points at different spin polarizations. 675 ! In this case, it is not possible to address the elements of 676 ! pwind correctly without making use of the kgindex array. 677 678 ikg = 0 ; ikpt_loc = 0 ; isppol = 1 679 do ikpt = 1, dtorbmag%fnkpt 680 681 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 682 nband_k = dtset%nband(ikpti) 683 ikpt1f = dtorbmag%ikpt_dk(ikpt,ifor,idir) 684 ikpt1i = dtorbmag%indkk_f2ibz(ikpt1f,1) 685 686 if ((proc_distrb_cycle(mpi_enreg%proc_distrb,ikpti,1,nband_k,1,me)).and.& 687 & (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpti,1,nband_k,dtset%nsppol,me))) cycle 688 689 ikpt_loc = ikpt_loc + 1 690 691 ! Build basis sphere of plane waves for the nearest neighbour of 692 ! the k-point (important for MPI //) 693 694 kg1_k(:,:) = 0 695 kpt1(:) = dtset%kptns(:,ikpt1i) 696 call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg1_k,kpt1,& 697 & 1,mpi_enreg,dtset%mpw,npw_k1) 698 me_g0=mpi_enreg%me_g0 699 700 701 ! ji: fkgindex is defined here ! 702 dtorbmag%fkgindex(ikpt) = ikg 703 704 ! 705 ! Deal with symmetry transformations 706 ! 707 708 ! bra k-point k(b) and IBZ k-point kIBZ(b) related by 709 ! k(b) = alpha(b) S(b)^t kIBZ(b) + G(b) 710 ! where alpha(b), S(b) and G(b) are given by indkk_f2ibz 711 ! 712 ! For the ket k-point: 713 ! k(k) = alpha(k) S(k)^t kIBZ(k) + G(k) - GBZ(k) 714 ! where GBZ(k) takes k(k) to the BZ 715 ! 716 717 isym = dtorbmag%indkk_f2ibz(ikpt,2) 718 isym1 = dtorbmag%indkk_f2ibz(ikpt1f,2) 719 720 ! Construct transformed G vector that enters the matching condition: 721 ! alpha(k) S(k)^{t,-1} ( -G(b) - GBZ(k) + G(k) ) 722 723 dg(:) = -dtorbmag%indkk_f2ibz(ikpt,3:5) & 724 & -nint(-dtorbmag%fkptns(:,ikpt) - dk(:) - tol10 & 725 & +dtorbmag%fkptns(:,ikpt1f)) & 726 & +dtorbmag%indkk_f2ibz(ikpt1f,3:5) 727 728 iadum(:) = MATMUL(TRANSPOSE(dtset%symrel(:,:,isym1)),dg(:)) 729 730 dg(:) = iadum(:) 731 732 if ( dtorbmag%indkk_f2ibz(ikpt1f,6) == 1 ) dg(:) = -dg(:) 733 734 ! Construct S(k)^{t,-1} S(b)^{t} 735 736 dum33(:,:) = MATMUL(TRANSPOSE(dtset%symrel(:,:,isym1)),symrec(:,:,isym)) 737 738 ! Construct alpha(k) alpha(b) 739 740 if (dtorbmag%indkk_f2ibz(ikpt,6) == dtorbmag%indkk_f2ibz(ikpt1f,6)) then 741 itrs=0 742 else 743 itrs=1 744 end if 745 746 747 npw_k = npwarr(ikpti) 748 ! npw_k1 = npwarr(ikpt1i) 749 750 ! loop over bra G vectors 751 do ipw = 1, npw_k 752 753 ! NOTE: the bra G vector is taken for the sym-related IBZ k point, 754 ! not for the FBZ k point 755 iadum(:) = kg(:,dtorbmag%kgindex(ikpti) + ipw) 756 757 ! Store non-symmorphic operation phase factor exp[i2\pi \alpha G \cdot t] 758 759 if ( ipwnsfac == 0 ) then 760 rdum=0.0_dp 761 do idum=1,3 762 rdum=rdum+dble(iadum(idum))*dtset%tnons(idum,isym) 763 end do 764 rdum=two_pi*rdum 765 if ( dtorbmag%indkk_f2ibz(ikpt,6) == 1 ) rdum=-rdum 766 pwnsfac(1,ikg+ipw) = cos(rdum) 767 pwnsfac(2,ikg+ipw) = sin(rdum) 768 end if 769 770 ! to determine r.l.v. matchings, we transformed the bra vector 771 ! Rotation 772 iadum1(:)=0 773 do idum1=1,3 774 iadum1(:)=iadum1(:)+dum33(:,idum1)*iadum(idum1) 775 end do 776 iadum(:)=iadum1(:) 777 ! Time reversal 778 if (itrs==1) iadum(:)=-iadum(:) 779 ! Translation 780 iadum(:) = iadum(:) + dg(:) 781 782 do jpw = 1, npw_k1 783 iadum1(1:3) = kg1_k(1:3,jpw) 784 if ( (iadum(1) == iadum1(1)).and. & 785 & (iadum(2) == iadum1(2)).and. & 786 & (iadum(3) == iadum1(3)) ) then 787 pwind(ikg + ipw,ifor,idir) = jpw 788 ! write(std_out,'(a,2x,3i4,2x,i4)') 'Found !:',iadum1(:),jpw 789 exit 790 end if 791 end do 792 end do 793 794 ikg = ikg + npw_k 795 796 end do ! close loop over ikpt 797 798 ipwnsfac = 1 799 800 end do ! close loop over ifor 801 802 end do ! close loop over idir 803 804 805 call timab(1008,2,tsec) 806 call timab(1009,1,tsec) 807 808 !Build mpi_enreg%kptdstrb 809 !array required to communicate the WFs between cpus 810 !(MPI // over k-points) 811 if (nproc>1) then 812 do idir = 1, 3 813 do ifor = 1, 2 814 815 ikpt_loc = 0 816 do isppol = 1, dtset%nsppol 817 818 do ikpt = 1, dtorbmag%fnkpt 819 820 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 821 nband_k = dtset%nband(ikpti) 822 ikpt1f = dtorbmag%ikpt_dk(ikpt,ifor,idir) 823 ikpt1i = dtorbmag%indkk_f2ibz(ikpt1f,1) 824 825 if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpti,1,nband_k,isppol,me)) cycle 826 827 ikpt_loc = ikpt_loc + 1 828 mpi_enreg%kptdstrb(me + 1,ifor+2*(idir-1),ikpt_loc) = & 829 & ikpt1i + (isppol - 1)*dtset%nkpt 830 831 mpi_enreg%kptdstrb(me+1,ifor+2*(idir-1),ikpt_loc+dtorbmag%fmkmem_max*dtset%nsppol) = & 832 & ikpt1f + (isppol - 1)*dtorbmag%fnkpt 833 834 end do ! ikpt 835 end do ! isppol 836 end do ! ifor 837 end do ! idir 838 end if ! nproc>1 839 840 !build mpi_enreg%kpt_loc2fbz_sp 841 ikpt_loc = 0 842 do isppol = 1, dtset%nsppol 843 do ikpt = 1, dtorbmag%fnkpt 844 845 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 846 nband_k = dtset%nband(ikpti) 847 848 if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpti,1,nband_k,isppol,me)) cycle 849 850 ikpt_loc = ikpt_loc + 1 851 852 mpi_enreg%kpt_loc2fbz_sp(me, ikpt_loc, 1) = ikpt 853 mpi_enreg%kpt_loc2fbz_sp(me, ikpt_loc, 2) = isppol 854 855 end do 856 end do 857 858 !should be temporary 859 !unassigned mpi_enreg%kpt_loc2fbz_sp are empty ; inform other cpu (there are better ways...) 860 mpi_enreg%mkmem(me) = dtset%mkmem 861 !do ii=ikpt_loc+1,dtefield%fmkmem_max 862 !mpi_enreg%kpt_loc2fbz_sp(me, ii, 1) = -1 863 !end do 864 865 call xmpi_sum(mpi_enreg%kptdstrb,spaceComm,ierr) 866 call xmpi_sum(mpi_enreg%kpt_loc2fbz_sp,spaceComm,ierr) 867 868 ABI_FREE(kg1_k) 869 870 871 call timab(1009,2,tsec) 872 call timab(1001,2,tsec) 873 874 DBG_EXIT("COLL") 875 876 end subroutine initorbmag
ABINIT/make_eeig [ Functions ]
NAME
make_eeig
FUNCTION
Compute the energy eigenvalues at each k point
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
eeig
TODO
NOTES
See Ceresoli et al, PRB 74, 024408 (2006) [[cite:Ceresoli2006]], and Gonze and Zwanziger, PRB 84, 064445 (2011) [[cite:Gonze2011a]]. The derivative of the density operator is obtained from a discretized formula $\partial_\beta \rho_k = \frac{1}{2\Delta}(\rho_{k+b} - \rho_{k-b})$ with $\Delta = |b|$. When reduced to wavefunction overlaps the computation amounts to multiple calls to smatrix.F90, exactly as in other Berry phase computations, with the one additional complication of overlaps like $\langle u_{n,k+b}|u_{n',k+g}\rangle$. At this stage mkpwind_k is invoked, which generalizes the code in initberry and initorbmag necessary to index plane waves around different k points. Direct questions and comments to J Zwanziger
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
2293 subroutine make_eeig(atindx1,cg,cprj,dtset,eeig,gmet,gprimd,mcg,mcprj,mpi_enreg,& 2294 & nattyp,nband_k,nfftf,npwarr,& 2295 & paw_ij,pawfgr,pawtab,psps,rmet,rprimd,& 2296 & vectornd,vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 2297 2298 !Arguments ------------------------------------ 2299 !scalars 2300 integer,intent(in) :: mcg,mcprj,nband_k,nfftf,with_vectornd 2301 type(dataset_type),intent(in) :: dtset 2302 type(MPI_type), intent(inout) :: mpi_enreg 2303 type(pawfgr_type),intent(in) :: pawfgr 2304 type(pseudopotential_type),intent(in) :: psps 2305 2306 !arrays 2307 integer,intent(in) :: atindx1(dtset%natom),nattyp(dtset%ntypat),npwarr(dtset%nkpt) 2308 real(dp),intent(in) :: cg(2,mcg),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3) 2309 real(dp),intent(in) :: vhartr(nfftf),vpsp(nfftf),vxc(nfftf,dtset%nspden),xred(3,dtset%natom) 2310 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 2311 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 2312 real(dp),intent(inout) :: vectornd(with_vectornd*nfftf,3) 2313 real(dp),intent(out) :: eeig(nband_k,dtset%nkpt) 2314 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 2315 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 2316 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw) 2317 2318 !Local variables ------------------------- 2319 !scalars 2320 integer :: cpopt,dimffnl,eeig_size,exchn2n3d 2321 integer :: ierr,icg,icprj,ider,idir,ikg,ikg1,ikpt,ilm,isppol,istwf_k 2322 integer :: me,my_nspinor,ncpgr,ndat,ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,nkpg,nn 2323 integer :: nproc,npw_k,npw_k_,prtvol,sij_opt,spaceComm,tim_getghc,type_calc 2324 logical :: has_vectornd 2325 real(dp) :: ecut_eff,lambda 2326 type(gs_hamiltonian_type) :: gs_hamk 2327 2328 !arrays 2329 integer,allocatable :: dimlmn(:),kg_k(:,:) 2330 real(dp) :: kpoint(3),lambdarr(1),rhodum(1) 2331 real(dp),allocatable :: buffer1(:),buffer2(:),cgrvtrial(:,:),cwavef(:,:) 2332 real(dp),allocatable :: ffnl_k(:,:,:,:),ghc(:,:),gsc(:,:),gvnlc(:,:) 2333 real(dp),allocatable :: kinpw(:),kpg_k(:,:) 2334 real(dp),allocatable :: ph3d(:,:,:),vectornd_pac(:,:,:,:,:),vlocal(:,:,:,:),vtrial(:,:) 2335 real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:) 2336 type(pawcprj_type),allocatable :: cprj_k(:,:),cwaveprj(:,:) 2337 2338 2339 !----------------------------------------------------------------------- 2340 2341 !Init MPI 2342 spaceComm=mpi_enreg%comm_cell 2343 nproc=xmpi_comm_size(spaceComm) 2344 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 2345 me = mpi_enreg%me_kpt 2346 2347 ! TODO: generalize to nsppol > 1 2348 isppol = 1 2349 ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3) 2350 ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6) 2351 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 2352 exchn2n3d = 0 ; istwf_k = 1 ; ikg1 = 0 2353 2354 has_vectornd = (with_vectornd .EQ. 1) 2355 2356 ! input parameters for calls to getghc at ikpt 2357 cpopt = 4 ! was 4 2358 ndat = 1 2359 prtvol = 0 2360 sij_opt = 0 2361 tim_getghc = 0 2362 ! getghc: type_calc 0 means kinetic, local, nonlocal 2363 type_calc = 0 2364 lambda = zero; lambdarr(1) = zero 2365 2366 !==== Initialize most of the Hamiltonian ==== 2367 !Allocate all arrays and initialize quantities that do not depend on k and spin. 2368 !gs_hamk is the normal hamiltonian at k, needed for computing E_nk 2369 call init_hamiltonian(gs_hamk,psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,& 2370 & dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,nucdipmom=dtset%nucdipmom,& 2371 & paw_ij=paw_ij) 2372 2373 !---------construct local potential------------------ 2374 ABI_MALLOC(vtrial,(nfftf,dtset%nspden)) 2375 ! nspden=1 is essentially hard-coded in the following line 2376 vtrial(1:nfftf,1)=vhartr(1:nfftf)+vxc(1:nfftf,1)+vpsp(1:nfftf) 2377 2378 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 2379 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial) 2380 2381 ABI_MALLOC(vlocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc)) 2382 call fftpac(isppol,mpi_enreg,dtset%nspden,& 2383 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vlocal,2) 2384 2385 ABI_FREE(cgrvtrial) 2386 ABI_FREE(vtrial) 2387 2388 ! if vectornd is present, set it up for addition to gs_hamk similarly to how it's done for 2389 ! vtrial. Note that it must be done for the three directions. Also, the following 2390 ! code assumes explicitly and implicitly that nvloc = 1. This should eventually be generalized. 2391 if(has_vectornd) then 2392 ABI_MALLOC(vectornd_pac,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,3)) 2393 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 2394 do idir = 1, 3 2395 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vectornd(:,idir)) 2396 call fftpac(isppol,mpi_enreg,dtset%nspden,& 2397 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vectornd_pac(:,:,:,1,idir),2) 2398 end do 2399 ABI_FREE(cgrvtrial) 2400 end if 2401 2402 ! add vlocal 2403 call gs_hamk%load_spin(isppol,vlocal=vlocal,with_nonlocal=.true.) 2404 2405 ! add vectornd if available 2406 if(has_vectornd) then 2407 call gs_hamk%load_spin(isppol,vectornd=vectornd_pac) 2408 end if 2409 2410 ncpgr = cprj(1,1)%ncpgr 2411 ABI_MALLOC(dimlmn,(dtset%natom)) 2412 call pawcprj_getdim(dimlmn,dtset%natom,nattyp,dtset%ntypat,dtset%typat,pawtab,'R') 2413 2414 ABI_MALLOC(cprj_k,(dtset%natom,nband_k)) 2415 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 2416 ABI_MALLOC(cwaveprj,(dtset%natom,1)) 2417 call pawcprj_alloc(cwaveprj,ncpgr,dimlmn) 2418 2419 ABI_MALLOC(kg_k,(3,dtset%mpw)) 2420 ABI_MALLOC(kinpw,(dtset%mpw)) 2421 2422 eeig(:,:) = zero 2423 icg = 0 2424 ikg = 0 2425 icprj = 0 2426 do ikpt = 1, dtset%nkpt 2427 2428 ! if the current kpt is not on the current processor, cycle 2429 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 2430 2431 kpoint(:)=dtset%kptns(:,ikpt) 2432 npw_k = npwarr(ikpt) 2433 2434 ! Build basis sphere of plane waves for the k-point 2435 kg_k(:,:) = 0 2436 call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg_k,kpoint,1,mpi_enreg,dtset%mpw,npw_k_) 2437 if (npw_k .NE. npw_k_) then 2438 write(std_out,'(a)')'JWZ debug mpi_eeig npw_k inconsistency' 2439 end if 2440 2441 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang)) 2442 ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm)) 2443 do ilm=1,psps%mpsang*psps%mpsang 2444 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 2445 ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm) 2446 end do 2447 2448 ! Compute kinetic energy at kpt 2449 kinpw(:) = zero 2450 call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,kinpw,kpoint,npw_k,0,0) 2451 2452 nkpg = 3 2453 ABI_MALLOC(kpg_k,(npw_k,nkpg)) 2454 call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k) 2455 2456 ! Compute nonlocal form factors ffnl at all (k+G): 2457 ider=0 ! want ffnl and 1st derivative 2458 idir=4 ! d ffnl/ dk_red in all 3 directions 2459 dimffnl=1 ! 1 + number of derivatives 2460 ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat)) 2461 call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,& 2462 & gmet,gprimd,ider,idir,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,& 2463 & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,& 2464 & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,rmet,& 2465 & psps%usepaw,psps%useylm,ylm_k,ylmgr_k) 2466 2467 ! - Compute 3D phase factors 2468 ! - Prepare various tabs in case of band-FFT parallelism 2469 ! - Load k-dependent quantities in the Hamiltonian 2470 ABI_MALLOC(ph3d,(2,npw_k,gs_hamk%matblk)) 2471 call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,& 2472 & kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,ph3d_k=ph3d,& 2473 & compute_ph3d=.TRUE.,compute_gbound=.TRUE.) 2474 2475 2476 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprj,ikpt,0,isppol,dtset%mband,& 2477 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 2478 2479 ! apply gs_hamk to wavefunctions at k to compute E_nk eigenvalues 2480 ABI_MALLOC(cwavef,(2,npw_k)) 2481 ABI_MALLOC(ghc,(2,npw_k)) 2482 ABI_MALLOC(gsc,(2,npw_k)) 2483 ABI_MALLOC(gvnlc,(2,npw_k)) 2484 do nn = 1, nband_k 2485 cwavef(1:2,1:npw_k) = cg(1:2,icg+(nn-1)*npw_k+1:icg+nn*npw_k) 2486 call pawcprj_get(atindx1,cwaveprj,cprj_k,dtset%natom,nn,0,ikpt,0,isppol,dtset%mband,& 2487 & dtset%mkmem,dtset%natom,1,nband_k,my_nspinor,dtset%nsppol,0) 2488 call getghc(cpopt,cwavef,cwaveprj,ghc,gsc,gs_hamk,gvnlc,lambda,mpi_enreg,ndat,& 2489 & prtvol,sij_opt,tim_getghc,type_calc) 2490 eeig(nn,ikpt) = DOT_PRODUCT(cwavef(1,1:npw_k),ghc(1,1:npw_k)) & 2491 & + DOT_PRODUCT(cwavef(2,1:npw_k),ghc(2,1:npw_k)) 2492 end do 2493 2494 icg = icg + npw_k*nband_k 2495 ikg = ikg + npw_k 2496 icprj = icprj + nband_k 2497 2498 ABI_FREE(ylm_k) 2499 ABI_FREE(ylmgr_k) 2500 ABI_FREE(kpg_k) 2501 ABI_FREE(ffnl_k) 2502 ABI_FREE(ph3d) 2503 ABI_FREE(cwavef) 2504 ABI_FREE(ghc) 2505 ABI_FREE(gsc) 2506 ABI_FREE(gvnlc) 2507 2508 end do ! end loop over kpts on current processor 2509 2510 ! MPI communicate stuff between everyone 2511 if (nproc>1) then 2512 eeig_size = size(eeig) 2513 ABI_MALLOC(buffer1,(eeig_size)) 2514 ABI_MALLOC(buffer2,(eeig_size)) 2515 buffer1(1:eeig_size) = reshape(eeig,(/eeig_size/)) 2516 call xmpi_sum(buffer1,buffer2,eeig_size,spaceComm,ierr) 2517 eeig(1:nband_k,1:dtset%nkpt)=reshape(buffer2,(/nband_k,dtset%nkpt/)) 2518 ABI_FREE(buffer1) 2519 ABI_FREE(buffer2) 2520 end if 2521 2522 call gs_hamk%free() 2523 ABI_FREE(vlocal) 2524 if(has_vectornd) then 2525 ABI_FREE(vectornd_pac) 2526 end if 2527 2528 ABI_FREE(kg_k) 2529 ABI_FREE(kinpw) 2530 2531 ABI_FREE(dimlmn) 2532 call pawcprj_free(cprj_k) 2533 ABI_FREE(cprj_k) 2534 call pawcprj_free(cwaveprj) 2535 ABI_FREE(cwaveprj) 2536 2537 end subroutine make_eeig
ABINIT/make_onsite_bm [ Functions ]
NAME
make_onsite_bm
FUNCTION
Compute A_0.A_N onsite term for magnetic field + nuclear magnetic dipole moment
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
5157 subroutine make_onsite_bm(atindx1,cprj,dtset,idir,mcprj,mpi_enreg,nband_k,onsite_bm,& 5158 & pawang,pawrad,pawtab) 5159 5160 !Arguments ------------------------------------ 5161 !scalars 5162 integer,intent(in) :: idir,mcprj,nband_k 5163 type(MPI_type), intent(inout) :: mpi_enreg 5164 type(pawang_type),intent(in) :: pawang 5165 type(dataset_type),intent(in) :: dtset 5166 5167 !arrays 5168 integer,intent(in) :: atindx1(dtset%natom) 5169 complex(dpc),intent(out) :: onsite_bm(nband_k) 5170 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 5171 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 5172 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 5173 5174 !Local variables ------------------------- 5175 !scalars 5176 integer :: gint,iatom,icprj,ierr,ikpt,ikpt_loc,il,im,ilmn,isppol,itypat 5177 integer :: jl,jm,jlmn,klmn,klm,kln,lpmp,me,mesh_size,my_nspinor,ncpgr,nn,nproc,spaceComm 5178 real(dp) :: bm1,bm2,d00,d20,d22,dij,intg,scale_conversion 5179 complex(dpc) :: cpb,cpk 5180 5181 !arrays 5182 integer :: nattyp_dum(dtset%ntypat) 5183 integer,allocatable :: dimlmn(:) 5184 real(dp),allocatable :: ff(:) 5185 type(pawcprj_type),allocatable :: cprj_k(:,:) 5186 5187 ! *********************************************************************** 5188 5189 ! this term can only be non-zero if some nucdipmom is nonzero 5190 scale_conversion = half*FineStructureConstant2 5191 d00 = sqrt(4.0*pi)/3.0 5192 dij = sqrt(4.0*pi/15.0) 5193 d20 = sqrt(16.0*pi/5.0)/6.0 5194 d22 = sqrt(16.0*pi/15.0)/2.0 5195 onsite_bm = czero 5196 5197 ! TODO: generalize to nsppol > 1 5198 isppol = 1 5199 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 5200 5201 !Init MPI 5202 spaceComm=mpi_enreg%comm_cell 5203 nproc=xmpi_comm_size(spaceComm) 5204 me = mpi_enreg%me_kpt 5205 5206 ncpgr = cprj(1,1)%ncpgr 5207 ABI_MALLOC(dimlmn,(dtset%natom)) 5208 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 5209 ABI_MALLOC(cprj_k,(dtset%natom,nband_k)) 5210 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 5211 5212 ! loop over kpts on each processor 5213 5214 ikpt_loc = 0 5215 ! loop over all the kpts 5216 do ikpt = 1, dtset%nkpt 5217 5218 ! if the current kpt is not on the current processor, cycle 5219 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 5220 5221 ikpt_loc = ikpt_loc + 1 5222 icprj= (ikpt_loc - 1)*nband_k 5223 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprj,ikpt_loc,0,isppol,dtset%mband,& 5224 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 5225 5226 do iatom=1,dtset%natom 5227 itypat=dtset%typat(iatom) 5228 mesh_size=pawtab(itypat)%mesh_size 5229 ABI_MALLOC(ff,(mesh_size)) 5230 do jlmn=1,pawtab(itypat)%lmn_size 5231 jl=pawtab(itypat)%indlmn(1,jlmn) 5232 jm=pawtab(itypat)%indlmn(2,jlmn) 5233 do ilmn=1,pawtab(itypat)%lmn_size 5234 il=pawtab(itypat)%indlmn(1,ilmn) 5235 im=pawtab(itypat)%indlmn(2,ilmn) 5236 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 5237 kln = pawtab(itypat)%indklmn(2,klmn) ! need this for mesh selection below 5238 klm = pawtab(itypat)%indklmn(1,klmn) ! need this for bm2 gaunt integral selection 5239 ! compute integral of (phi_i*phi_j - tphi_i*tphi_j)/r 5240 ff(2:mesh_size)=(pawtab(itypat)%phiphj(2:mesh_size,kln) - & 5241 & pawtab(itypat)%tphitphj(2:mesh_size,kln)) / & 5242 & pawrad(itypat)%rad(2:mesh_size) 5243 call pawrad_deducer0(ff,mesh_size,pawrad(itypat)) 5244 call simp_gen(intg,ff,pawrad(itypat)) 5245 ! term B.m r^2/r^3 5246 bm1=zero 5247 if ( (jl .EQ. il) .AND. (jm .EQ. im) .AND. (abs(dtset%nucdipmom(idir,iatom)) .GT. tol8) ) then 5248 bm1 = scale_conversion*dtset%nucdipmom(idir,iatom)*intg 5249 end if 5250 bm2 = zero 5251 ! xx, yy, zz cases all have the same contribution from S00 5252 lpmp=1 5253 gint = pawang%gntselect(lpmp,klm) 5254 if (gint > 0) then 5255 bm2=bm2+scale_conversion*dtset%nucdipmom(idir,iatom)*d00*pawang%realgnt(gint)*intg 5256 end if 5257 ! all other contributions involve Gaunt integrals of S_{2m} 5258 do lpmp = 5, 9 5259 gint = pawang%gntselect(lpmp,klm) 5260 if (gint > 0) then 5261 select case (lpmp) 5262 case (5) ! S_{2,-2} contributes to xy term 5263 select case (idir) 5264 case (1) 5265 bm2=bm2+scale_conversion*dtset%nucdipmom(2,iatom)*dij*pawang%realgnt(gint)*intg 5266 case (2) 5267 bm2=bm2+scale_conversion*dtset%nucdipmom(1,iatom)*dij*pawang%realgnt(gint)*intg 5268 end select 5269 case (6) ! S_{2,-1} contributes to yz term 5270 select case (idir) 5271 case (2) 5272 bm2=bm2+scale_conversion*dtset%nucdipmom(3,iatom)*dij*pawang%realgnt(gint)*intg 5273 case (3) 5274 bm2=bm2+scale_conversion*dtset%nucdipmom(2,iatom)*dij*pawang%realgnt(gint)*intg 5275 end select 5276 case (7) ! S_{2,0} contributes to xx, yy, and zz terms 5277 select case (idir) 5278 case (1) 5279 bm2=bm2-scale_conversion*dtset%nucdipmom(1,iatom)*d20*pawang%realgnt(gint)*intg 5280 case (2) 5281 bm2=bm2-scale_conversion*dtset%nucdipmom(2,iatom)*d20*pawang%realgnt(gint)*intg 5282 case (3) 5283 bm2=bm2+scale_conversion*dtset%nucdipmom(3,iatom)*2.0*d20*pawang%realgnt(gint)*intg 5284 end select 5285 case (8) ! S_{2,+1} contributes to xz term 5286 select case (idir) 5287 case (1) 5288 bm2=bm2+scale_conversion*dtset%nucdipmom(3,iatom)*dij*pawang%realgnt(gint)*intg 5289 case (3) 5290 bm2=bm2+scale_conversion*dtset%nucdipmom(1,iatom)*dij*pawang%realgnt(gint)*intg 5291 end select 5292 case (9) ! S_{2,2} contributes to xx, yy terms 5293 select case (idir) 5294 case (1) 5295 bm2=bm2+scale_conversion*dtset%nucdipmom(1,iatom)*d22*pawang%realgnt(gint)*intg 5296 case (2) 5297 bm2=bm2-scale_conversion*dtset%nucdipmom(2,iatom)*d22*pawang%realgnt(gint)*intg 5298 end select 5299 end select 5300 end if ! end check on nonzero gaunt integral 5301 end do ! end loop over lp,mp 5302 do nn = 1, nband_k 5303 cpb=cmplx(cprj_k(iatom,nn)%cp(1,ilmn),cprj_k(iatom,nn)%cp(2,ilmn),KIND=dpc) 5304 cpk=cmplx(cprj_k(iatom,nn)%cp(1,jlmn),cprj_k(iatom,nn)%cp(2,jlmn),KIND=dpc) 5305 onsite_bm(nn)=onsite_bm(nn)+conjg(cpb)*(bm1-bm2)*cpk 5306 end do ! end loop over nn 5307 end do ! end loop over ilmn 5308 end do ! end loop over jlmn 5309 ABI_FREE(ff) 5310 end do ! end loop over atoms 5311 end do ! end loop over local k points 5312 5313 ! ---- parallel communication 5314 if(nproc > 1) then 5315 call xmpi_sum(onsite_bm,spaceComm,ierr) 5316 end if 5317 5318 !---------clean up memory------------------- 5319 5320 ABI_FREE(dimlmn) 5321 call pawcprj_free(cprj_k) 5322 ABI_FREE(cprj_k) 5323 5324 end subroutine make_onsite_bm
ABINIT/make_onsite_bm_k_n [ Functions ]
NAME
make_onsite_bm_k_n
FUNCTION
Compute A_0.A_N onsite term for magnetic field + nuclear magnetic dipole moment for k pt and 1 band
COPYRIGHT
Copyright (C) 2003-2021 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
1003 subroutine make_onsite_bm_k_n(cprj_k,dtset,iband,idir,nband_k,onsite_bm_k_n,& 1004 & pawang,pawrad,pawtab) 1005 1006 !Arguments ------------------------------------ 1007 !scalars 1008 integer,intent(in) :: idir,iband,nband_k 1009 complex(dpc),intent(out) :: onsite_bm_k_n 1010 type(pawang_type),intent(in) :: pawang 1011 type(dataset_type),intent(in) :: dtset 1012 1013 !arrays 1014 type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,nband_k) 1015 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 1016 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 1017 1018 !Local variables ------------------------- 1019 !scalars 1020 integer :: gint,iatom,il,im,ilmn,itypat 1021 integer :: jl,jm,jlmn,klmn,klm,kln,lpmp,mesh_size 1022 real(dp) :: bm1,bm2,d00,d20,d22,dij,intg,scale_conversion 1023 complex(dpc) :: cpb,cpk 1024 1025 !arrays 1026 real(dp),allocatable :: ff(:) 1027 1028 ! *********************************************************************** 1029 1030 ! this term can only be non-zero if some nucdipmom is nonzero 1031 scale_conversion = half*FineStructureConstant2 1032 d00 = sqrt(4.0*pi)/3.0 1033 dij = sqrt(4.0*pi/15.0) 1034 d20 = sqrt(16.0*pi/5.0)/6.0 1035 d22 = sqrt(16.0*pi/15.0)/2.0 1036 onsite_bm_k_n = czero 1037 1038 do iatom=1,dtset%natom 1039 itypat=dtset%typat(iatom) 1040 mesh_size=pawtab(itypat)%mesh_size 1041 ABI_MALLOC(ff,(mesh_size)) 1042 do jlmn=1,pawtab(itypat)%lmn_size 1043 jl=pawtab(itypat)%indlmn(1,jlmn) 1044 jm=pawtab(itypat)%indlmn(2,jlmn) 1045 do ilmn=1,pawtab(itypat)%lmn_size 1046 il=pawtab(itypat)%indlmn(1,ilmn) 1047 im=pawtab(itypat)%indlmn(2,ilmn) 1048 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 1049 kln = pawtab(itypat)%indklmn(2,klmn) ! need this for mesh selection below 1050 klm = pawtab(itypat)%indklmn(1,klmn) ! need this for bm2 gaunt integral selection 1051 ! compute integral of (phi_i*phi_j - tphi_i*tphi_j)/r 1052 ff(2:mesh_size)=(pawtab(itypat)%phiphj(2:mesh_size,kln) - & 1053 & pawtab(itypat)%tphitphj(2:mesh_size,kln)) / & 1054 & pawrad(itypat)%rad(2:mesh_size) 1055 call pawrad_deducer0(ff,mesh_size,pawrad(itypat)) 1056 call simp_gen(intg,ff,pawrad(itypat)) 1057 ! term B.m r^2/r^3 1058 bm1=zero 1059 if ( (jl .EQ. il) .AND. (jm .EQ. im) .AND. (abs(dtset%nucdipmom(idir,iatom)) .GT. tol8) ) then 1060 bm1 = scale_conversion*dtset%nucdipmom(idir,iatom)*intg 1061 end if 1062 bm2 = zero 1063 ! xx, yy, zz cases all have the same contribution from S00 1064 lpmp=1 1065 gint = pawang%gntselect(lpmp,klm) 1066 if (gint > 0) then 1067 bm2=bm2+scale_conversion*dtset%nucdipmom(idir,iatom)*d00*pawang%realgnt(gint)*intg 1068 end if 1069 ! all other contributions involve Gaunt integrals of S_{2m} 1070 do lpmp = 5, 9 1071 gint = pawang%gntselect(lpmp,klm) 1072 if (gint > 0) then 1073 select case (lpmp) 1074 case (5) ! S_{2,-2} contributes to xy term 1075 select case (idir) 1076 case (1) 1077 bm2=bm2+scale_conversion*dtset%nucdipmom(2,iatom)*dij*pawang%realgnt(gint)*intg 1078 case (2) 1079 bm2=bm2+scale_conversion*dtset%nucdipmom(1,iatom)*dij*pawang%realgnt(gint)*intg 1080 end select 1081 case (6) ! S_{2,-1} contributes to yz term 1082 select case (idir) 1083 case (2) 1084 bm2=bm2+scale_conversion*dtset%nucdipmom(3,iatom)*dij*pawang%realgnt(gint)*intg 1085 case (3) 1086 bm2=bm2+scale_conversion*dtset%nucdipmom(2,iatom)*dij*pawang%realgnt(gint)*intg 1087 end select 1088 case (7) ! S_{2,0} contributes to xx, yy, and zz terms 1089 select case (idir) 1090 case (1) 1091 bm2=bm2-scale_conversion*dtset%nucdipmom(1,iatom)*d20*pawang%realgnt(gint)*intg 1092 case (2) 1093 bm2=bm2-scale_conversion*dtset%nucdipmom(2,iatom)*d20*pawang%realgnt(gint)*intg 1094 case (3) 1095 bm2=bm2+scale_conversion*dtset%nucdipmom(3,iatom)*2.0*d20*pawang%realgnt(gint)*intg 1096 end select 1097 case (8) ! S_{2,+1} contributes to xz term 1098 select case (idir) 1099 case (1) 1100 bm2=bm2+scale_conversion*dtset%nucdipmom(3,iatom)*dij*pawang%realgnt(gint)*intg 1101 case (3) 1102 bm2=bm2+scale_conversion*dtset%nucdipmom(1,iatom)*dij*pawang%realgnt(gint)*intg 1103 end select 1104 case (9) ! S_{2,2} contributes to xx, yy terms 1105 select case (idir) 1106 case (1) 1107 bm2=bm2+scale_conversion*dtset%nucdipmom(1,iatom)*d22*pawang%realgnt(gint)*intg 1108 case (2) 1109 bm2=bm2-scale_conversion*dtset%nucdipmom(2,iatom)*d22*pawang%realgnt(gint)*intg 1110 end select 1111 end select 1112 end if ! end check on nonzero gaunt integral 1113 end do ! end loop over lp,mp 1114 cpb=cmplx(cprj_k(iatom,iband)%cp(1,ilmn),cprj_k(iatom,iband)%cp(2,ilmn),KIND=dpc) 1115 cpk=cmplx(cprj_k(iatom,iband)%cp(1,jlmn),cprj_k(iatom,iband)%cp(2,jlmn),KIND=dpc) 1116 onsite_bm_k_n=onsite_bm_k_n+conjg(cpb)*(bm1-bm2)*cpk 1117 end do ! end loop over ilmn 1118 end do ! end loop over jlmn 1119 ABI_FREE(ff) 1120 end do ! end loop over atoms 1121 1122 end subroutine make_onsite_bm_k_n
ABINIT/make_onsite_l [ Functions ]
NAME
make_onsite_l
FUNCTION
Compute 1/2 <L_R> onsite contribution to orbital magnetization in direction idir
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
5048 subroutine make_onsite_l(atindx1,cprj,dtset,idir,mcprj,mpi_enreg,nband_k,onsite_l,pawrad,pawtab) 5049 5050 !Arguments ------------------------------------ 5051 !scalars 5052 integer,intent(in) :: idir,mcprj,nband_k 5053 type(MPI_type), intent(inout) :: mpi_enreg 5054 type(dataset_type),intent(in) :: dtset 5055 5056 !arrays 5057 integer,intent(in) :: atindx1(dtset%natom) 5058 complex(dpc),intent(out) :: onsite_l(nband_k) 5059 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 5060 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 5061 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 5062 5063 !Local variables ------------------------- 5064 !scalars 5065 integer :: icprj,ierr,ikpt,ikpt_loc,isppol,me,my_nspinor,ncpgr,nproc,spaceComm 5066 5067 !arrays 5068 integer :: nattyp_dum(dtset%ntypat) 5069 integer,allocatable :: dimlmn(:) 5070 complex(dpc),allocatable :: onsite_l_k(:) 5071 type(pawcprj_type),allocatable :: cprj_k(:,:) 5072 5073 ! *********************************************************************** 5074 5075 ! TODO: generalize to nsppol > 1 5076 isppol = 1 5077 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 5078 5079 !Init MPI 5080 spaceComm=mpi_enreg%comm_cell 5081 nproc=xmpi_comm_size(spaceComm) 5082 me = mpi_enreg%me_kpt 5083 5084 ncpgr = cprj(1,1)%ncpgr 5085 ABI_MALLOC(dimlmn,(dtset%natom)) 5086 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 5087 ABI_MALLOC(cprj_k,(dtset%natom,nband_k)) 5088 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 5089 5090 ! loop over kpts on each processor 5091 ABI_MALLOC(onsite_l_k,(nband_k)) 5092 onsite_l = czero 5093 ikpt_loc = 0 5094 ! loop over all the kpts 5095 do ikpt = 1, dtset%nkpt 5096 5097 ! if the current kpt is not on the current processor, cycle 5098 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 5099 5100 ikpt_loc = ikpt_loc + 1 5101 icprj= (ikpt_loc - 1)*nband_k 5102 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprj,ikpt_loc,0,isppol,dtset%mband,& 5103 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 5104 5105 call make_onsite_l_k(cprj_k,dtset,idir,nband_k,onsite_l_k,pawrad,pawtab) 5106 onsite_l(1:nband_k) = onsite_l(1:nband_k) + onsite_l_k(1:nband_k) 5107 5108 end do 5109 5110 ! ---- parallel communication 5111 if(nproc > 1) then 5112 call xmpi_sum(onsite_l,spaceComm,ierr) 5113 end if 5114 5115 !---------clean up memory------------------- 5116 5117 ABI_FREE(dimlmn) 5118 call pawcprj_free(cprj_k) 5119 ABI_FREE(cprj_k) 5120 ABI_FREE(onsite_l_k) 5121 5122 end subroutine make_onsite_l
ABINIT/make_onsite_l_k [ Functions ]
NAME
make_onsite_l_k
FUNCTION
Compute 1/2 <L_R> onsite contribution to orbital magnetization at given k point and idir
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
4958 subroutine make_onsite_l_k(cprj_k,dtset,idir,nband_k,onsite_l_k,pawrad,pawtab) 4959 4960 !Arguments ------------------------------------ 4961 !scalars 4962 integer,intent(in) :: idir,nband_k 4963 type(dataset_type),intent(in) :: dtset 4964 4965 !arrays 4966 complex(dpc),intent(out) :: onsite_l_k(nband_k) 4967 type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,nband_k) 4968 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 4969 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 4970 4971 !Local variables ------------------------- 4972 !scalars 4973 integer :: iatom,ilmn,il,im,itypat,jlmn,jl,jm,klmn,kln,mesh_size,nn 4974 real(dp) :: intg 4975 complex(dpc) :: cpb,cpk,orbl_me 4976 4977 !arrays 4978 real(dp),allocatable :: ff(:) 4979 4980 !-------------------------------------------------------------------- 4981 4982 onsite_l_k = czero 4983 do iatom=1,dtset%natom 4984 itypat=dtset%typat(iatom) 4985 mesh_size=pawtab(itypat)%mesh_size 4986 ABI_MALLOC(ff,(mesh_size)) 4987 do jlmn=1,pawtab(itypat)%lmn_size 4988 jl=pawtab(itypat)%indlmn(1,jlmn) 4989 jm=pawtab(itypat)%indlmn(2,jlmn) 4990 do ilmn=1,pawtab(itypat)%lmn_size 4991 il=pawtab(itypat)%indlmn(1,ilmn) 4992 im=pawtab(itypat)%indlmn(2,ilmn) 4993 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 4994 kln = pawtab(itypat)%indklmn(2,klmn) ! need this for mesh selection below 4995 ! compute <L_dir> 4996 call slxyzs(il,im,idir,jl,jm,orbl_me) 4997 ! compute integral of phi_i*phi_j - tphi_i*tphi_j 4998 if (abs(orbl_me) > tol8) then 4999 ff(1:mesh_size)=pawtab(itypat)%phiphj(1:mesh_size,kln) - pawtab(itypat)%tphitphj(1:mesh_size,kln) 5000 call pawrad_deducer0(ff,mesh_size,pawrad(itypat)) 5001 call simp_gen(intg,ff,pawrad(itypat)) 5002 do nn = 1, nband_k 5003 cpb=cmplx(cprj_k(iatom,nn)%cp(1,ilmn),cprj_k(iatom,nn)%cp(2,ilmn),KIND=dpc) 5004 cpk=cmplx(cprj_k(iatom,nn)%cp(1,jlmn),cprj_k(iatom,nn)%cp(2,jlmn),KIND=dpc) 5005 onsite_l_k(nn)=onsite_l_k(nn)+conjg(cpb)*half*orbl_me*intg*cpk 5006 end do ! end loop over nn 5007 end if ! end check that |L_dir| > 0, otherwise ignore term 5008 end do ! end loop over ilmn 5009 end do ! end loop over jlmn 5010 ABI_FREE(ff) 5011 end do ! end loop over atoms 5012 5013 end subroutine make_onsite_l_k
ABINIT/make_onsite_l_k_n [ Functions ]
NAME
make_onsite_l_k_n
FUNCTION
Compute 1/2 <L_R> onsite contribution to orbital magnetization at given k point, band, and idir
COPYRIGHT
Copyright (C) 2003-2021 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
914 subroutine make_onsite_l_k_n(cprj_k,dtset,iband,idir,nband_k,onsite_l_k_n,pawrad,pawtab) 915 916 !Arguments ------------------------------------ 917 !scalars 918 integer,intent(in) :: iband,idir,nband_k 919 complex(dpc),intent(out) :: onsite_l_k_n 920 type(dataset_type),intent(in) :: dtset 921 922 !arrays 923 type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,nband_k) 924 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 925 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 926 927 !Local variables ------------------------- 928 !scalars 929 integer :: iatom,ilmn,il,im,itypat,jlmn,jl,jm,klmn,kln,mesh_size 930 real(dp) :: intg 931 complex(dpc) :: cpb,cpk,orbl_me 932 933 !arrays 934 real(dp),allocatable :: ff(:) 935 936 !-------------------------------------------------------------------- 937 938 onsite_l_k_n = czero 939 do iatom=1,dtset%natom 940 itypat=dtset%typat(iatom) 941 mesh_size=pawtab(itypat)%mesh_size 942 ABI_MALLOC(ff,(mesh_size)) 943 do jlmn=1,pawtab(itypat)%lmn_size 944 jl=pawtab(itypat)%indlmn(1,jlmn) 945 jm=pawtab(itypat)%indlmn(2,jlmn) 946 do ilmn=1,pawtab(itypat)%lmn_size 947 il=pawtab(itypat)%indlmn(1,ilmn) 948 im=pawtab(itypat)%indlmn(2,ilmn) 949 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 950 kln = pawtab(itypat)%indklmn(2,klmn) ! need this for mesh selection below 951 ! compute <L_dir> 952 call slxyzs(il,im,idir,jl,jm,orbl_me) 953 ! compute integral of phi_i*phi_j - tphi_i*tphi_j 954 if (abs(orbl_me) > tol8) then 955 ff(1:mesh_size)=pawtab(itypat)%phiphj(1:mesh_size,kln) - pawtab(itypat)%tphitphj(1:mesh_size,kln) 956 call pawrad_deducer0(ff,mesh_size,pawrad(itypat)) 957 call simp_gen(intg,ff,pawrad(itypat)) 958 cpb=cmplx(cprj_k(iatom,iband)%cp(1,ilmn),cprj_k(iatom,iband)%cp(2,ilmn),KIND=dpc) 959 cpk=cmplx(cprj_k(iatom,iband)%cp(1,jlmn),cprj_k(iatom,iband)%cp(2,jlmn),KIND=dpc) 960 onsite_l_k_n=onsite_l_k_n+conjg(cpb)*half*orbl_me*intg*cpk 961 end if ! end check that |L_dir| > 0, otherwise ignore term 962 end do ! end loop over ilmn 963 end do ! end loop over jlmn 964 ABI_FREE(ff) 965 end do ! end loop over atoms 966 967 end subroutine make_onsite_l_k_n
ABINIT/make_rhorij1 [ Functions ]
NAME
make_rhorij1
FUNCTION
Compute Trace[\rho_0 \rho_Rij(1) ] in orbital magnetism context
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
5359 subroutine make_rhorij1(adir,atindx1,cprj,dtset,mcprj,mpi_enreg,& 5360 & nattyp,nband_k,paw_ij,pawtab,rhorij1) 5361 5362 !Arguments ------------------------------------ 5363 !scalars 5364 integer,intent(in) :: adir,mcprj,nband_k 5365 type(MPI_type), intent(inout) :: mpi_enreg 5366 type(dataset_type),intent(in) :: dtset 5367 5368 !arrays 5369 integer,intent(in) :: atindx1(dtset%natom),nattyp(dtset%ntypat) 5370 complex(dpc),intent(out) :: rhorij1(nband_k) 5371 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 5372 type(paw_ij_type),intent(in) :: paw_ij(dtset%natom) 5373 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 5374 5375 !Local variables ------------------------- 5376 !scalars 5377 integer :: bdir,icprj,epsabg,gdir,iatom,ierr,ikpt,ilmn,isppol,itypat 5378 integer :: jlmn,klmn,me,my_nspinor,ncpgr,nn,nproc,spaceComm 5379 complex(dpc) :: cpb,cdij,cpk 5380 5381 !arrays 5382 integer,allocatable :: dimlmn(:) 5383 type(pawcprj_type),allocatable :: cprj_k(:,:) 5384 5385 !---------------------------------------------------------------- 5386 5387 !Init MPI 5388 spaceComm=mpi_enreg%comm_cell 5389 nproc=xmpi_comm_size(spaceComm) 5390 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 5391 me = mpi_enreg%me_kpt 5392 5393 isppol = 1 5394 ncpgr = cprj(1,1)%ncpgr 5395 ABI_MALLOC(dimlmn,(dtset%natom)) 5396 call pawcprj_getdim(dimlmn,dtset%natom,nattyp,dtset%ntypat,dtset%typat,pawtab,'R') 5397 ABI_MALLOC(cprj_k,(dtset%natom,nband_k)) 5398 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 5399 5400 rhorij1 = czero 5401 icprj = 0 5402 do ikpt = 1, dtset%nkpt 5403 5404 ! if the current kpt is not on the current processor, cycle 5405 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 5406 5407 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprj,ikpt,0,isppol,dtset%mband,& 5408 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 5409 5410 do epsabg = 1, -1, -2 5411 5412 if (epsabg .EQ. 1) then 5413 bdir = modulo(adir,3)+1 5414 gdir = modulo(adir+1,3)+1 5415 else 5416 bdir = modulo(adir+1,3)+1 5417 gdir = modulo(adir,3)+1 5418 end if 5419 5420 do nn = 1, nband_k 5421 do iatom=1,dtset%natom 5422 itypat=dtset%typat(iatom) 5423 do ilmn=1,pawtab(itypat)%lmn_size 5424 do jlmn=1,pawtab(itypat)%lmn_size 5425 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 5426 cpb=cmplx(cprj_k(iatom,nn)%dcp(1,bdir,ilmn),cprj_k(iatom,nn)%dcp(2,bdir,ilmn),KIND=dpc) 5427 cpk=cmplx(cprj_k(iatom,nn)%dcp(1,gdir,jlmn),cprj_k(iatom,nn)%dcp(2,gdir,jlmn),KIND=dpc) 5428 if (paw_ij(iatom)%cplex_dij .EQ. 2) then 5429 cdij=cmplx(paw_ij(iatom)%dij(2*klmn-1,1),paw_ij(iatom)%dij(2*klmn,1),KIND=dpc) 5430 if (jlmn .GT. ilmn) cdij=conjg(cdij) 5431 else 5432 cdij=cmplx(paw_ij(iatom)%dij(klmn,1),zero,KIND=dpc) 5433 end if 5434 rhorij1(nn)=rhorij1(nn)-half*j_dpc*epsabg*conjg(cpb)*cdij*cpk 5435 end do ! end loop over jlmn 5436 end do ! end loop over ilmn 5437 end do ! end loop over atoms 5438 end do ! end loop over bands 5439 end do ! end loop over epsabg 5440 5441 icprj = icprj + nband_k 5442 5443 end do ! end loop over kpt 5444 5445 ! ---- parallel communication 5446 if(nproc > 1) then 5447 call xmpi_sum(rhorij1,spaceComm,ierr) 5448 end if 5449 5450 ABI_FREE(dimlmn) 5451 call pawcprj_free(cprj_k) 5452 ABI_FREE(cprj_k) 5453 5454 end subroutine make_rhorij1
ABINIT/make_rhorij1_k_n [ Functions ]
NAME
make_rhorij1_k_n
FUNCTION
Compute Trace[\rho^0_k \rho_Rij(1)_k ] in orbital magnetism context
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
1238 subroutine make_rhorij1_k_n(adir,cprj_k,dtset,iband,nband_occ,& 1239 & paw_ij,pawtab,rhorij1) 1240 1241 !Arguments ------------------------------------ 1242 !scalars 1243 integer,intent(in) :: adir,iband,nband_occ 1244 complex(dpc),intent(out) :: rhorij1 1245 type(dataset_type),intent(in) :: dtset 1246 1247 !arrays 1248 type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,nband_occ) 1249 type(paw_ij_type),intent(in) :: paw_ij(dtset%natom) 1250 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 1251 1252 !Local variables ------------------------- 1253 !scalars 1254 integer :: bdir,epsabg,gdir,iatom,ilmn,itypat,jlmn,klmn 1255 complex(dpc) :: cpb,cdij,cpk 1256 1257 !---------------------------------------------------------------- 1258 1259 rhorij1 = czero 1260 1261 do epsabg = 1, -1, -2 1262 1263 if (epsabg .EQ. 1) then 1264 bdir = modulo(adir,3)+1 1265 gdir = modulo(adir+1,3)+1 1266 else 1267 bdir = modulo(adir+1,3)+1 1268 gdir = modulo(adir,3)+1 1269 end if 1270 1271 do iatom=1,dtset%natom 1272 itypat=dtset%typat(iatom) 1273 do ilmn=1,pawtab(itypat)%lmn_size 1274 do jlmn=1,pawtab(itypat)%lmn_size 1275 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 1276 cpb=cmplx(cprj_k(iatom,iband)%dcp(1,bdir,ilmn),cprj_k(iatom,iband)%dcp(2,bdir,ilmn),KIND=dpc) 1277 cpk=cmplx(cprj_k(iatom,iband)%dcp(1,gdir,jlmn),cprj_k(iatom,iband)%dcp(2,gdir,jlmn),KIND=dpc) 1278 if (paw_ij(iatom)%cplex_dij .EQ. 2) then 1279 cdij=cmplx(paw_ij(iatom)%dij(2*klmn-1,1),paw_ij(iatom)%dij(2*klmn,1),KIND=dpc) 1280 if (jlmn .GT. ilmn) cdij=conjg(cdij) 1281 else 1282 cdij=cmplx(paw_ij(iatom)%dij(klmn,1),zero,KIND=dpc) 1283 end if 1284 rhorij1=rhorij1-half*j_dpc*epsabg*conjg(cpb)*cdij*cpk 1285 end do ! end loop over jlmn 1286 end do ! end loop over ilmn 1287 end do ! end loop over atoms 1288 end do ! end loop over epsabg 1289 1290 end subroutine make_rhorij1_k_n
ABINIT/make_S1trace [ Functions ]
NAME
make_S1trace
FUNCTION
Compute Trace[\rho_0 S^{(1)} \rho_0] in orbital magnetism context
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
4832 subroutine make_S1trace(adir,atindx1,cprj,dtset,eeig,& 4833 & mcprj,mpi_enreg,nattyp,nband_k,pawtab,S1trace) 4834 4835 !Arguments ------------------------------------ 4836 !scalars 4837 integer,intent(in) :: adir,mcprj,nband_k 4838 type(MPI_type), intent(inout) :: mpi_enreg 4839 type(dataset_type),intent(in) :: dtset 4840 4841 !arrays 4842 integer,intent(in) :: atindx1(dtset%natom),nattyp(dtset%ntypat) 4843 real(dp),intent(in) :: eeig(nband_k,dtset%nkpt) 4844 complex(dpc),intent(out) :: S1trace(nband_k) 4845 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 4846 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 4847 4848 !Local variables ------------------------- 4849 !scalars 4850 integer :: bdir,icprj,epsabg,gdir,iatom,ierr,ikpt,ilmn,isppol,itypat 4851 integer :: jlmn,klmn,me,my_nspinor,ncpgr,nn,nproc,spaceComm 4852 real(dp) :: ENK 4853 complex(dpc) :: cpb,cpk 4854 4855 !arrays 4856 integer,allocatable :: dimlmn(:) 4857 type(pawcprj_type),allocatable :: cprj_k(:,:) 4858 4859 !---------------------------------------------------------------- 4860 4861 !Init MPI 4862 spaceComm=mpi_enreg%comm_cell 4863 nproc=xmpi_comm_size(spaceComm) 4864 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 4865 me = mpi_enreg%me_kpt 4866 4867 isppol = 1 4868 ncpgr = cprj(1,1)%ncpgr 4869 ABI_MALLOC(dimlmn,(dtset%natom)) 4870 call pawcprj_getdim(dimlmn,dtset%natom,nattyp,dtset%ntypat,dtset%typat,pawtab,'R') 4871 ABI_MALLOC(cprj_k,(dtset%natom,nband_k)) 4872 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 4873 4874 S1trace = czero 4875 icprj = 0 4876 do ikpt = 1, dtset%nkpt 4877 4878 ! if the current kpt is not on the current processor, cycle 4879 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 4880 4881 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprj,ikpt,0,isppol,dtset%mband,& 4882 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 4883 4884 do epsabg = 1, -1, -2 4885 4886 if (epsabg .EQ. 1) then 4887 bdir = modulo(adir,3)+1 4888 gdir = modulo(adir+1,3)+1 4889 else 4890 bdir = modulo(adir+1,3)+1 4891 gdir = modulo(adir,3)+1 4892 end if 4893 4894 do nn = 1, nband_k 4895 ENK = eeig(nn,ikpt) 4896 do iatom=1,dtset%natom 4897 itypat=dtset%typat(iatom) 4898 do ilmn=1,pawtab(itypat)%lmn_size 4899 do jlmn=1,pawtab(itypat)%lmn_size 4900 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 4901 cpb=cmplx(cprj_k(iatom,nn)%dcp(1,bdir,ilmn),cprj_k(iatom,nn)%dcp(2,bdir,ilmn),KIND=dpc) 4902 cpk=cmplx(cprj_k(iatom,nn)%dcp(1,gdir,jlmn),cprj_k(iatom,nn)%dcp(2,gdir,jlmn),KIND=dpc) 4903 S1trace(nn)=S1trace(nn)+half*j_dpc*epsabg*ENK*conjg(cpb)*pawtab(itypat)%sij(klmn)*cpk 4904 end do ! end loop over jlmn 4905 end do ! end loop over ilmn 4906 end do ! end loop over atoms 4907 end do ! end loop over bands 4908 end do ! end loop over epsabg 4909 4910 icprj = icprj + nband_k 4911 4912 end do ! end loop over kpt 4913 4914 ! ---- parallel communication 4915 if(nproc > 1) then 4916 call xmpi_sum(S1trace,spaceComm,ierr) 4917 end if 4918 4919 ABI_FREE(dimlmn) 4920 call pawcprj_free(cprj_k) 4921 ABI_FREE(cprj_k) 4922 4923 end subroutine make_S1trace
ABINIT/make_S1trace_k_n [ Functions ]
NAME
make_S1trace_k_n
FUNCTION
Compute single band contribution to Trace[\rho^0_k S_k^{(1)} ] in orbital magnetism context
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
1158 subroutine make_S1trace_k_n(adir,cprj_k,dtset,ENK,iband,nband_occ,pawtab,S1trace) 1159 1160 !Arguments ------------------------------------ 1161 !scalars 1162 integer,intent(in) :: adir,iband,nband_occ 1163 real(dp),intent(in) :: ENK 1164 complex(dpc),intent(out) :: S1trace 1165 type(dataset_type),intent(in) :: dtset 1166 1167 !arrays 1168 type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,nband_occ) 1169 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 1170 1171 !Local variables ------------------------- 1172 !scalars 1173 integer :: bdir,epsabg,gdir,iatom,ilmn,itypat,jlmn,klmn 1174 complex(dpc) :: cpb,cpk 1175 1176 !---------------------------------------------------------------- 1177 1178 S1trace = czero 1179 1180 do epsabg = 1, -1, -2 1181 1182 if (epsabg .EQ. 1) then 1183 bdir = modulo(adir,3)+1 1184 gdir = modulo(adir+1,3)+1 1185 else 1186 bdir = modulo(adir+1,3)+1 1187 gdir = modulo(adir,3)+1 1188 end if 1189 1190 do iatom=1,dtset%natom 1191 itypat=dtset%typat(iatom) 1192 do ilmn=1,pawtab(itypat)%lmn_size 1193 do jlmn=1,pawtab(itypat)%lmn_size 1194 klmn=max(jlmn,ilmn)*(max(jlmn,ilmn)-1)/2 + min(jlmn,ilmn) 1195 cpb=cmplx(cprj_k(iatom,iband)%dcp(1,bdir,ilmn),cprj_k(iatom,iband)%dcp(2,bdir,ilmn),KIND=dpc) 1196 cpk=cmplx(cprj_k(iatom,iband)%dcp(1,gdir,jlmn),cprj_k(iatom,iband)%dcp(2,gdir,jlmn),KIND=dpc) 1197 S1trace=S1trace-half*j_dpc*epsabg*ENK*conjg(cpb)*pawtab(itypat)%sij(klmn)*cpk 1198 end do ! end loop over jlmn 1199 end do ! end loop over ilmn 1200 end do ! end loop over atoms 1201 end do ! end loop over epsabg 1202 1203 end subroutine make_S1trace_k_n
ABINIT/mpicomm_helper [ Functions ]
NAME
mpicomm_helper
FUNCTION
get wavefunction and cprj in mpi communication loop
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
only printing
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
3359 subroutine mpicomm_helper(atindx1,bdir,bfor,cg,cgqb,cprj,cprj_kb,dimlmn,dtorbmag,dtset,& 3360 & ikpt,ikpt_loc,ikptbi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 3361 & nproc,npw_kb,npwarr,spaceComm) 3362 3363 !Arguments ------------------------------------ 3364 !scalars 3365 integer,intent(in) :: bdir,bfor,ikpt,ikpt_loc,ikptbi,isppol,mcg,mcprj,me,my_nspinor 3366 integer,intent(in) :: nband_k,nproc,npw_kb,spaceComm 3367 type(dataset_type),intent(in) :: dtset 3368 type(MPI_type), intent(inout) :: mpi_enreg 3369 type(orbmag_type), intent(inout) :: dtorbmag 3370 3371 !arrays 3372 integer,intent(in) :: atindx1(dtset%natom),dimlmn(dtset%natom),npwarr(dtset%nkpt) 3373 real(dp),intent(in) :: cg(2,mcg) 3374 real(dp),intent(out) :: cgqb(2,npw_kb*my_nspinor*nband_k) 3375 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 3376 type(pawcprj_type),intent(inout) :: cprj_kb(dtset%natom,nband_k) 3377 3378 !Local variables ------------------------- 3379 !scalars 3380 integer :: countb,countjb,dest,icgb,icprjbi,ierr 3381 integer :: jcgb,jcprjbi,jkpt,jkptb,jkptbi,jsppol,n2dim,ncpgr,sourceb,tagb 3382 3383 !arrays 3384 real(dp),allocatable :: buffer(:,:) 3385 type(pawcprj_type),allocatable :: cprj_buf(:,:) 3386 3387 !---------------------------------------------------- 3388 3389 n2dim = dtorbmag%nspinor*nband_k 3390 ncpgr = cprj(1,1)%ncpgr 3391 if (nproc>1) then 3392 ABI_MALLOC(cprj_buf,(dtset%natom,n2dim)) 3393 call pawcprj_alloc(cprj_buf,ncpgr,dimlmn) 3394 end if 3395 3396 if (ikpt > 0 .and. isppol > 0) then ! I currently have a true kpt to use 3397 countb = npw_kb*my_nspinor*nband_k 3398 cgqb = zero 3399 sourceb = me 3400 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikptbi,1,nband_k,isppol,me)) then 3401 ! I need the data from someone else 3402 sourceb = mpi_enreg%proc_distrb(ikptbi,1,isppol) 3403 end if 3404 else 3405 sourceb = -1 ! I do not have a kpt to use 3406 end if 3407 3408 do dest=0,nproc-1 3409 if ((dest.EQ.me) .AND. (ikpt.GT.0) .AND. (isppol.GT.0)) then 3410 ! I am destination and I have something to do 3411 if(sourceb.EQ.me) then 3412 ! I am destination and source for kptb 3413 icprjbi = dtorbmag%cprjindex(ikptbi,isppol) 3414 icgb = dtorbmag%cgindex(ikptbi,dtset%nsppol) 3415 call pawcprj_get(atindx1,cprj_kb,cprj,dtset%natom,1,icprjbi,& 3416 & ikptbi,0,isppol,dtset%mband,dtset%mkmem,dtset%natom,nband_k,nband_k,& 3417 & my_nspinor,dtset%nsppol,0) 3418 cgqb(1:2,1:countb) = cg(1:2,icgb+1:icgb+countb) 3419 else ! sourceb .NE. me 3420 ! receive cgqb and cprj_kb 3421 tagb = ikptbi + (isppol - 1)*dtset%nkpt 3422 call xmpi_recv(cgqb,sourceb,tagb,spaceComm,ierr) 3423 call pawcprj_mpi_recv(dtset%natom,n2dim,dimlmn,ncpgr,cprj_kb,sourceb,spaceComm,ierr) 3424 end if 3425 else if (dest.NE.me) then 3426 ! jkpt is the kpt which is being treated by dest 3427 ! jsppol is his isppol 3428 jkpt = mpi_enreg%kpt_loc2fbz_sp(dest, ikpt_loc,1) 3429 jsppol = mpi_enreg%kpt_loc2fbz_sp(dest, ikpt_loc,2) 3430 if (jkpt > 0 .and. jsppol > 0) then ! dest is treating a true kpt 3431 3432 jkptb = dtorbmag%ikpt_dk(jkpt,bfor,bdir) 3433 jkptbi = dtorbmag%indkk_f2ibz(jkptb,1) 3434 3435 if((mpi_enreg%proc_distrb(jkptbi,1,jsppol) == me)) then 3436 jcgb = dtorbmag%cgindex(jkptbi,jsppol) 3437 jcprjbi=dtorbmag%cprjindex(jkptbi,jsppol) 3438 call pawcprj_get(atindx1,cprj_buf,cprj,dtset%natom,1,jcprjbi,jkptbi,0,jsppol,& 3439 & dtset%mband,dtset%mkmem,dtset%natom,dtorbmag%mband_occ,dtorbmag%mband_occ,& 3440 & my_nspinor,dtset%nsppol,0,mpicomm=mpi_enreg%comm_kpt,& 3441 & proc_distrb=mpi_enreg%proc_distrb) 3442 tagb = jkptbi + (jsppol - 1)*dtset%nkpt 3443 countjb = npwarr(jkptbi)*my_nspinor*nband_k 3444 ABI_MALLOC(buffer,(2,countjb)) 3445 buffer(:,1:countjb) = cg(:,jcgb+1:jcgb+countjb) 3446 call xmpi_send(buffer,dest,tagb,spaceComm,ierr) 3447 ABI_FREE(buffer) 3448 call pawcprj_mpi_send(dtset%natom,n2dim,dimlmn,ncpgr,cprj_buf,dest,spaceComm,ierr) 3449 end if ! end check that I am his source 3450 3451 end if ! end check that jkpt > 0 and jsppol > 0 3452 3453 end if ! test dest .EQ. me and ikpt .GT. 0 3454 3455 end do ! end loop over dest 3456 3457 if (nproc>1) then 3458 call pawcprj_free(cprj_buf) 3459 ABI_FREE(cprj_buf) 3460 end if 3461 3462 end subroutine mpicomm_helper
ABINIT/orbmag_ddk [ Functions ]
NAME
orbmag_ddk
FUNCTION
This routine computes the orbital magnetization and Berry curvature based on input wavefunctions and DDK wavefuntions. It is assumed that only completely filled bands are present.
COPYRIGHT
Copyright (C) 2003-2021 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
See Ceresoli et al, PRB 74, 024408 (2006) [[cite:Ceresoli2006]], and Gonze and Zwanziger, PRB 84, 064445 (2011) [[cite:Gonze2011a]]. DDK wavefunctions are used for the derivatives.
PARENTS
m_dfpt_looppert
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
1330 subroutine orbmag_ddk(atindx1,cg,cg1,dtset,gsqcut,kg,mcg,mcg1,mpi_enreg,& 1331 & nattyp,nfftf,ngfftf,npwarr,paw_ij,pawang,pawfgr,pawrad,pawtab,psps,rprimd,vtrial,& 1332 & xred,ylm,ylmgr) 1333 1334 !Arguments ------------------------------------ 1335 !scalars 1336 integer,intent(in) :: mcg,mcg1,nfftf 1337 real(dp),intent(in) :: gsqcut 1338 type(dataset_type),intent(in) :: dtset 1339 type(MPI_type), intent(inout) :: mpi_enreg 1340 type(pawang_type),intent(in) :: pawang 1341 type(pawfgr_type),intent(in) :: pawfgr 1342 type(pseudopotential_type), intent(inout) :: psps 1343 1344 !arrays 1345 integer,intent(in) :: atindx1(dtset%natom),kg(3,dtset%mpw*dtset%mkmem) 1346 integer,intent(in) :: nattyp(dtset%natom),ngfftf(18),npwarr(dtset%nkpt) 1347 real(dp),intent(in) :: cg(2,mcg),cg1(2,mcg1,3),rprimd(3,3),xred(3,dtset%natom) 1348 real(dp),intent(inout) :: vtrial(nfftf,dtset%nspden) 1349 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 1350 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 1351 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 1352 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat*psps%usepaw) 1353 type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw) 1354 1355 !Local 1356 !scalars 1357 integer :: adir,bdir,buff_size,dimffnl,exchn2n3d,getcprj_choice,getcprj_cpopt 1358 integer :: getghc_cpopt,getghc_prtvol,getghc_sij_opt,getghc_tim,getghc_type_calc 1359 integer :: gdir,iatom,icg,ider,idir,ierr,ikg,ikg1,ikpt,ilm,isppol,istwf_k 1360 integer :: me,mcgk,my_nspinor,nband_k,ncpgr,ndat,ngfft1,ngfft2,ngfft3,ngfft4 1361 integer :: ngfft5,ngfft6,nn,nnp,nkpg,npw_k 1362 integer :: nonlop_choice,nonlop_cpopt,nonlop_nnlout,nonlop_pawopt,nonlop_signs,nonlop_tim 1363 integer :: nproc,nterms,projbd_scprod_io,projbd_tim,projbd_useoverlap,spaceComm,with_vectornd 1364 integer,parameter :: cci=1,vvii=2,vvia=3,vvib=4,rho0h1=5,rho0s1=6,lrb=7,a0an=8,berrycurve=9 1365 real(dp) :: arg,dbi,dbr,dgi,dgr,doti,dub_dsg_i,dug_dsb_i 1366 real(dp) :: ecut_eff,Enk,lambda,local_fermie,trnrm,ucvol 1367 complex(dpc) :: dbc,dgc,onsite_bm_k_n,onsite_l_k_n,rhorij1,S1trace 1368 logical :: has_nucdip 1369 type(gs_hamiltonian_type) :: gs_hamk 1370 1371 !arrays 1372 integer,allocatable :: dimlmn(:),kg_k(:,:),nattyp_dum(:) 1373 real(dp) :: gmet(3,3),gprimd(3,3),kpoint(3),lambda_ndat(1),nonlop_enlout(1),rhodum(1),rmet(3,3) 1374 real(dp),allocatable :: buffer1(:),buffer2(:) 1375 real(dp),allocatable :: cg_k(:,:),cg1_k(:,:,:),cgrvtrial(:,:),cwaveb1(:,:),cwavef(:,:),cwavefp(:,:),cwaveg1(:,:) 1376 real(dp),allocatable :: cwavedsdb(:,:),cwavedsdg(:,:) 1377 real(dp),allocatable :: dscg_k(:,:,:),ffnl_k(:,:,:,:),ghc(:,:),gsc(:,:),gvnlc(:,:) 1378 real(dp),allocatable :: kinpw(:),kpg_k(:,:),orbmag_terms(:,:,:),orbmag_trace(:,:) 1379 real(dp),allocatable :: pcg1_k(:,:,:),ph1d(:,:),ph3d(:,:,:),phkxred(:,:),scg_k(:,:),scg1_k(:,:,:),scprod(:,:) 1380 real(dp),allocatable :: vectornd(:,:),vectornd_pac(:,:,:,:,:),vlocal(:,:,:,:) 1381 real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:) 1382 type(pawcprj_type),allocatable :: cprj_k(:,:),cwaveprj(:,:) 1383 1384 !---------------------------------------------- 1385 1386 ! set up basic FFT parameters 1387 ! TODO: generalize to nsppol > 1 1388 isppol = 1 1389 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 1390 nband_k = dtset%mband 1391 istwf_k = 1 1392 spaceComm=mpi_enreg%comm_cell 1393 nproc=xmpi_comm_size(spaceComm) 1394 me = mpi_enreg%me_kpt 1395 ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3) 1396 ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6) 1397 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 1398 exchn2n3d = 0; ikg1 = 0 1399 1400 ! input parameters for calls to nonlop 1401 ! nonlop_choice will be changed from call to call 1402 nonlop_cpopt = -1 ! cprj computed and not saved 1403 nonlop_pawopt = 3 ! apply only S 1404 nonlop_signs = 2 ! get <G|Op|C> vector 1405 nonlop_nnlout = 1 1406 nonlop_tim = 0 1407 1408 ! input parameters to projbd 1409 projbd_scprod_io = 0 1410 projbd_useoverlap = 1 1411 projbd_tim = 0 1412 1413 ! input parameters for calls to getghc at ikpt 1414 getghc_cpopt = -1 ! cprj computed and not saved 1415 getghc_sij_opt = 1 ! compute both H|C> and S|C> 1416 ndat = 1 ! number of fft's in parallel 1417 getghc_prtvol = 0 1418 getghc_type_calc = 0 ! type_calc 0 means kinetic, local, nonlocal 1419 getghc_tim = 0 1420 lambda = zero 1421 lambda_ndat = zero 1422 1423 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) 1424 1425 ncpgr = 3 1426 ABI_MALLOC(dimlmn,(dtset%natom)) 1427 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 1428 ABI_MALLOC(cprj_k,(dtset%natom,dtset%mband)) 1429 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 1430 ABI_MALLOC(cwaveprj,(dtset%natom,1)) 1431 call pawcprj_alloc(cwaveprj,ncpgr,dimlmn) 1432 1433 !==== Initialize most of the Hamiltonian ==== 1434 !Allocate all arrays and initialize quantities that do not depend on k and spin. 1435 !gs_hamk is the normal hamiltonian at k 1436 call init_hamiltonian(gs_hamk,psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,& 1437 & dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,nucdipmom=dtset%nucdipmom,& 1438 & paw_ij=paw_ij) 1439 1440 !========= construct local potential ================== 1441 ! nspden=1 is essentially hard-coded in the following line 1442 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 1443 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial) 1444 ABI_MALLOC(vlocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc)) 1445 call fftpac(isppol,mpi_enreg,dtset%nspden,& 1446 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vlocal,2) 1447 ABI_FREE(cgrvtrial) 1448 call gs_hamk%load_spin(isppol,vlocal=vlocal,with_nonlocal=.true.) 1449 1450 !======== compute nuclear dipole vector potential (may be zero) ========== 1451 with_vectornd=0 1452 has_nucdip = ANY( ABS(dtset%nucdipmom) .GT. tol8 ) 1453 if (has_nucdip) with_vectornd=1 1454 ABI_MALLOC(vectornd,(with_vectornd*nfftf,3)) 1455 vectornd = zero 1456 if(has_nucdip) then 1457 call make_vectornd(1,gsqcut,psps%usepaw,mpi_enreg,dtset%natom,nfftf,ngfftf,& 1458 & dtset%nucdipmom,rprimd,vectornd,xred) 1459 ABI_MALLOC(vectornd_pac,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,3)) 1460 ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden)) 1461 do idir = 1, 3 1462 call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vectornd(:,idir)) 1463 call fftpac(isppol,mpi_enreg,dtset%nspden,& 1464 & ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6,dtset%ngfft,cgrvtrial,vectornd_pac(:,:,:,1,idir),2) 1465 end do 1466 ABI_FREE(cgrvtrial) 1467 call gs_hamk%load_spin(isppol,vectornd=vectornd_pac) 1468 end if 1469 1470 ABI_MALLOC(kg_k,(3,dtset%mpw)) 1471 ABI_MALLOC(kinpw,(dtset%mpw)) 1472 1473 ABI_MALLOC(ph1d,(2,dtset%natom*(2*(ngfft1+ngfft2+ngfft3)+3))) 1474 call getph(atindx1,dtset%natom,ngfft1,ngfft2,ngfft3,ph1d,xred) 1475 1476 icg = 0 1477 ikg = 0 1478 nterms = 9 ! various contributing terms in orbmag and berrycurve 1479 ! 1 orbmag CC 1480 ! 2 orbmag VV II 1481 ! 3 orbmag VV I+III part a 1482 ! 4 orbmag VV I+III part b 1483 ! 5 orbmag Tr[\rho^0 H^1] with D^0_ij part 1484 ! 6 orbmag -Tr[\rho^0 S^1] part 1485 ! 7 orbmag onsite L_R/r^3 1486 ! 8 orbmag onsite A0.An 1487 ! 9 berrycurve 1488 ABI_MALLOC(orbmag_terms,(3,nterms,nband_k)) 1489 orbmag_terms = zero 1490 local_fermie = -1.0D10 1491 1492 !============= BIG FAT KPT LOOP :) =========================== 1493 do ikpt = 1, dtset%nkpt 1494 1495 ! if the current kpt is not on the current processor, cycle 1496 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 1497 1498 ! trace norm: assume occupation of two for each band and weight by kpts 1499 trnrm = two*dtset%wtk(ikpt) 1500 1501 kpoint(:)=dtset%kptns(:,ikpt) 1502 npw_k = npwarr(ikpt) 1503 1504 ! retrieve kg_k at this k point 1505 kg_k(1:3,1:npw_k) = kg(1:3,ikg+1:ikg+npw_k) 1506 1507 ! retrieve ylm at this k point 1508 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang)) 1509 ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm)) 1510 do ilm=1,psps%mpsang*psps%mpsang 1511 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 1512 ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm) 1513 end do 1514 1515 ! Compute kinetic energy at kpt 1516 kinpw(:) = zero 1517 call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,kinpw,kpoint,npw_k,0,0) 1518 1519 ! Compute k+G at this k point 1520 nkpg = 3 1521 ABI_MALLOC(kpg_k,(npw_k,nkpg)) 1522 call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k) 1523 1524 ! Make 3d phase factors 1525 ABI_MALLOC(phkxred,(2,dtset%natom)) 1526 do iatom=1, dtset%natom 1527 arg=two_pi*DOT_PRODUCT(kpoint,xred(:,iatom)) 1528 phkxred(1,iatom)=cos(arg);phkxred(2,iatom)=sin(arg) 1529 end do 1530 ABI_MALLOC(ph3d,(2,npw_k,dtset%natom)) 1531 call ph1d3d(1,dtset%natom,kg_k,dtset%natom,dtset%natom,& 1532 & npw_k,ngfft1,ngfft2,ngfft3,phkxred,ph1d,ph3d) 1533 1534 ! Compute nonlocal form factors ffnl at all (k+G): 1535 ider=1 ! ffnl and 1st derivatives 1536 idir=4 ! ignored when ider = 0; idir=0 means d ffnl/ dk in reduced units referenced 1537 ! to reciprocal translations 1538 ! idir=4 meand d ffnl / dk in reduced units referenced to real space 1539 ! translations. rfddk = 1 wavefunctions are computed using this convention. 1540 dimffnl=4 ! 1 + number of derivatives 1541 ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat)) 1542 call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,& 1543 & gmet,gprimd,ider,idir,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,& 1544 & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,& 1545 & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,rmet,& 1546 & psps%usepaw,psps%useylm,ylm_k,ylmgr_k) 1547 1548 ! - Load k-dependent quantities in the Hamiltonian 1549 call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,& 1550 & kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,ph3d_k=ph3d,& 1551 & compute_gbound=.TRUE.) 1552 1553 ! retrieve ground state wavefunctions at this k point 1554 mcgk = npw_k*nband_k 1555 ABI_MALLOC(cg_k,(2,mcgk)) 1556 cg_k = cg(1:2,icg+1:icg+mcgk) 1557 ABI_MALLOC(scg_k,(2,mcgk)) 1558 ABI_MALLOC(scg1_k,(2,mcgk,3)) 1559 1560 ! retrieve first order wavefunctions at this k point 1561 ABI_MALLOC(cg1_k,(2,mcgk,3)) 1562 cg1_k = cg1(1:2,icg+1:icg+mcgk,1:3) 1563 1564 ! compute cprj_k, S|u_nk>, and S|du/dk> 1565 ABI_MALLOC(cwavef,(2,npw_k)) 1566 ABI_MALLOC(gsc,(2,npw_k)) 1567 ABI_MALLOC(gvnlc,(2,npw_k)) 1568 ! input parameters for calls to nonlop 1569 nonlop_choice = 1! apply (I+S) 1570 ! input parameters for calls to getcprj 1571 getcprj_choice = 5 ! cprj and d cprj/dk 1572 getcprj_cpopt = 0 ! compute both cprj and d cprj/dk 1573 do nn = 1, nband_k 1574 cwavef = cg_k(:,(nn-1)*npw_k+1:nn*npw_k) 1575 call nonlop(nonlop_choice,nonlop_cpopt,cwaveprj,nonlop_enlout,gs_hamk,0,& 1576 & lambda_ndat,mpi_enreg,ndat,nonlop_nnlout,nonlop_pawopt,nonlop_signs,gsc,& 1577 & nonlop_tim,cwavef,gvnlc) 1578 scg_k(1:2,(nn-1)*npw_k+1:nn*npw_k) = gsc(1:2,1:npw_k) 1579 1580 do adir = 1, 3 1581 call getcprj(getcprj_choice,getcprj_cpopt,cwavef,cwaveprj,ffnl_k,& 1582 & adir,psps%indlmn,istwf_k,kg_k,kpg_k,kpoint,psps%lmnmax,& 1583 & dtset%mgfft,mpi_enreg,dtset%natom,nattyp,dtset%ngfft,& 1584 & dtset%nloalg,npw_k,dtset%nspinor,dtset%ntypat,& 1585 & phkxred,ph1d,ph3d,ucvol,psps%useylm) 1586 1587 call pawcprj_put(atindx1,cwaveprj,cprj_k,dtset%natom,& 1588 & nn,0,ikpt,0,isppol,nband_k,dtset%mkmem,& 1589 & dtset%natom,1,nband_k,dimlmn,dtset%nspinor,dtset%nsppol,0,& 1590 & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb) 1591 1592 end do 1593 1594 do adir = 1, 3 1595 cwavef = cg1_k(:,(nn-1)*npw_k+1:nn*npw_k,adir) 1596 call nonlop(nonlop_choice,nonlop_cpopt,cwaveprj,nonlop_enlout,gs_hamk,0,& 1597 & lambda_ndat,mpi_enreg,ndat,nonlop_nnlout,nonlop_pawopt,nonlop_signs,gsc,& 1598 & nonlop_tim,cwavef,gvnlc) 1599 scg1_k(1:2,(nn-1)*npw_k+1:nn*npw_k,adir) = gsc(1:2,1:npw_k) 1600 end do 1601 end do ! end loop over nn 1602 1603 ! compute \partial S/\partial k |u_nk> 1604 ABI_MALLOC(dscg_k,(2,mcgk,3)) 1605 ! input parameters for calls to nonlop 1606 nonlop_choice = 5! apply dS/dk 1607 do adir = 1, 3 1608 do nn = 1, nband_k 1609 cwavef = cg_k(:,(nn-1)*npw_k+1:nn*npw_k) 1610 call nonlop(nonlop_choice,nonlop_cpopt,cwaveprj,nonlop_enlout,gs_hamk,adir,& 1611 & lambda_ndat,mpi_enreg,ndat,nonlop_nnlout,nonlop_pawopt,nonlop_signs,gsc,& 1612 & nonlop_tim,cwavef,gvnlc) 1613 dscg_k(1:2,(nn-1)*npw_k+1:nn*npw_k,adir) = gsc(1:2,1:npw_k) 1614 end do ! end loop over nn 1615 end do 1616 1617 ! compute projection of cg1_k on conduction space 1618 ABI_MALLOC(pcg1_k,(2,nband_k*npw_k,3)) 1619 ABI_MALLOC(scprod,(2,nband_k)) 1620 do adir = 1, 3 1621 do nn = 1, nband_k 1622 1623 cwavef = cg1_k(1:2,(nn-1)*npw_k+1:nn*npw_k,adir) 1624 call projbd(cg_k,cwavef,-1,0,0,istwf_k,mcgk,mcgk,nband_k,npw_k,dtset%nspinor,& 1625 & scg_k,scprod,projbd_scprod_io,projbd_tim,projbd_useoverlap,& 1626 & mpi_enreg%me_g0,mpi_enreg%comm_fft) 1627 pcg1_k(1:2,(nn-1)*npw_k+1:nn*npw_k,adir) = cwavef 1628 1629 end do ! end loop over nn 1630 end do ! end loop over adir 1631 1632 ABI_MALLOC(ghc,(2,npw_k)) 1633 ABI_MALLOC(cwaveb1,(2,npw_k)) 1634 ABI_MALLOC(cwaveg1,(2,npw_k)) 1635 ABI_MALLOC(cwavedsdb,(2,npw_k)) 1636 ABI_MALLOC(cwavedsdg,(2,npw_k)) 1637 ABI_MALLOC(cwavefp,(2,npw_k)) 1638 do nn = 1, nband_k 1639 1640 ! compute H^0|u_nk> and <u_nk|H^0|u_nk> 1641 cwavef(1:2,1:npw_k) = cg_k(1:2,(nn-1)*npw_k+1:nn*npw_k) 1642 call getghc(getghc_cpopt,cwavef,cwaveprj,ghc,gsc,gs_hamk,gvnlc,lambda,mpi_enreg,ndat,& 1643 & getghc_prtvol,getghc_sij_opt,getghc_tim,getghc_type_calc) 1644 Enk = DOT_PRODUCT(cwavef(1,1:npw_k),ghc(1,1:npw_k)) & 1645 & + DOT_PRODUCT(cwavef(2,1:npw_k),ghc(2,1:npw_k)) 1646 1647 if (Enk .GT. local_fermie) local_fermie = Enk 1648 1649 do adir =1, 3 1650 bdir = modulo(adir,3)+1 1651 gdir = modulo(adir+1,3)+1 1652 1653 ! 1 orbmag CC 1654 ! -i/2 eps_abg <du/dg|P_c H0 P_c|du/db> = 1655 ! -i/2 (<du/dg|P_c H0 P_c|du/db> - <du/db|P_c H0 P_c|du/dg>) = 1656 ! -i/2 (2 i Im<du/dg|P_c H0 P_c|du/db>) = 1657 ! Im<du/dg|P_c H0 P_c|du/db> 1658 1659 cwaveb1(1:2,1:npw_k) = pcg1_k(1:2,(nn-1)*npw_k+1:nn*npw_k,bdir) 1660 1661 call getghc(getghc_cpopt,cwaveb1,cwaveprj,ghc,gsc,gs_hamk,gvnlc,lambda,mpi_enreg,ndat,& 1662 & getghc_prtvol,getghc_sij_opt,getghc_tim,getghc_type_calc) 1663 1664 cwaveg1(1:2,1:npw_k) = pcg1_k(1:2,(nn-1)*npw_k+1:nn*npw_k,gdir) 1665 doti=-DOT_PRODUCT(cwaveg1(2,:),ghc(1,:))+DOT_PRODUCT(cwaveg1(1,:),ghc(2,:)) 1666 1667 orbmag_terms(adir,cci,nn) = orbmag_terms(adir,cci,nn) + doti*trnrm 1668 1669 ! 2 orbmag VV II 1670 ! vv needs (+i/2)*eps_abg*<du/db|P_c S P_c|du/dg>Enk = 1671 ! +i/2 (<du/db|P_c S P_c|du/dg> - <du/dg|P_c S P_c|du/db>)Enk = 1672 ! -i/2 (<du/dg|P_c S P_c|du/db> - <du/db|P_c S P_c|du/dg>)Enk = 1673 ! Im<du/dg|P_c S P_c|du/db>Enk 1674 1675 doti=-DOT_PRODUCT(cwaveg1(2,:),gsc(1,:))+DOT_PRODUCT(cwaveg1(1,:),gsc(2,:)) 1676 orbmag_terms(adir,vvii,nn) = orbmag_terms(adir,vvii,nn) + doti*Enk*trnrm 1677 1678 !VV Ib term gives (i/2)eps_abg <du/db|P_c dS/dg|u>Enk 1679 !VV IIIb term gives (i/2)eps_abg <du|dS/db P_c|du/dg>Enk 1680 ! combined with eps_abg contraction they contribute 1681 ! -Im(VVI)*Enk 1682 ! 4 orbmag VV I+III part b 1683 cwavedsdb(1:2,1:npw_k) = dscg_k(1:2,(nn-1)*npw_k+1:nn*npw_k,bdir) 1684 cwavedsdg(1:2,1:npw_k) = dscg_k(1:2,(nn-1)*npw_k+1:nn*npw_k,gdir) 1685 1686 dug_dsb_i = -DOT_PRODUCT(cwaveg1(2,:),cwavedsdb(1,:)) + DOT_PRODUCT(cwaveg1(1,:),cwavedsdb(2,:)) 1687 dub_dsg_i = -DOT_PRODUCT(cwaveb1(2,:),cwavedsdg(1,:)) + DOT_PRODUCT(cwaveb1(1,:),cwavedsdg(2,:)) 1688 orbmag_terms(adir,vvib,nn)= orbmag_terms(adir,vvib,nn) - (dub_dsg_i-dug_dsb_i)*Enk*trnrm 1689 1690 ! VVIa term gives (i/2)eps_abg sum_n' (-)<u_n|dS/db|u_n'><u_n'|dS/dg|u_n>Enk 1691 ! = + sum_n' Im{<u_n|dS/db|u_n'><u_n'|dS/dg|u_n>Enk} 1692 ! VVIIIa is identical. VVIIa is the negative of VVIa. The total contribution of all 1693 ! three terms is thus the same as VVIa itself. 1694 ! term 3 1695 do nnp=1,nband_k 1696 cwavefp(1:2,1:npw_k) = cg_k(1:2,(nnp-1)*npw_k+1:nnp*npw_k) 1697 dbr= DOT_PRODUCT(cwavefp(1,:),cwavedsdb(1,:))+DOT_PRODUCT(cwavefp(2,:),cwavedsdb(2,:)) 1698 dbi=-DOT_PRODUCT(cwavefp(2,:),cwavedsdb(1,:))+DOT_PRODUCT(cwavefp(1,:),cwavedsdb(2,:)) 1699 dbc=cmplx(dbr,dbi,kind=dpc) 1700 dgr= DOT_PRODUCT(cwavefp(1,:),cwavedsdg(1,:))+DOT_PRODUCT(cwavefp(2,:),cwavedsdg(2,:)) 1701 dgi=-DOT_PRODUCT(cwavefp(2,:),cwavedsdg(1,:))+DOT_PRODUCT(cwavefp(1,:),cwavedsdg(2,:)) 1702 dgc=cmplx(dgr,dgi,kind=dpc) 1703 orbmag_terms(adir,vvia,nn) = orbmag_terms(adir,vvia,nn) + AIMAG(CONJG(dbc)*dgc*Enk)*trnrm 1704 end do 1705 1706 ! 5 Tr[-\rho^0 S^1 \rho^0 H^0] contribution 1707 call make_S1trace_k_n(adir,cprj_k,dtset,Enk,nn,nband_k,pawtab,S1trace) 1708 orbmag_terms(adir,rho0s1,nn) = orbmag_terms(adir,rho0s1,nn) - real(S1trace)*trnrm 1709 1710 ! 6 Tr[\rho^0 H^1] contribution: 1711 ! -i/2 eps_abg <u|dp/db>D_ij^0<dp/dg|u> 1712 call make_rhorij1_k_n(adir,cprj_k,dtset,nn,nband_k,paw_ij,pawtab,rhorij1) 1713 orbmag_terms(adir,rho0h1,nn) = orbmag_terms(adir,rho0h1,nn) + real(rhorij1)*trnrm 1714 1715 ! 7 onsite A_0.p = 1/2 L_R.B contribution 1716 call make_onsite_l_k_n(cprj_k,dtset,nn,adir,nband_k,onsite_l_k_n,pawrad,pawtab) 1717 orbmag_terms(adir,lrb,nn) = orbmag_terms(adir,lrb,nn) + real(onsite_l_k_n)*trnrm 1718 1719 ! 8 onsite A0.An contiribution 1720 call make_onsite_bm_k_n(cprj_k,dtset,nn,adir,nband_k,onsite_bm_k_n,& 1721 & pawang,pawrad,pawtab) 1722 orbmag_terms(adir,a0an,nn) = orbmag_terms(adir,a0an,nn) + real(onsite_bm_k_n)*trnrm 1723 1724 ! berrycurve needs i*eps_abg*<du/db|S|du/dg> 1725 ! N.B. the Berry curvature does not involve H0 so no projection onto conduction 1726 ! and valence bands, the "S" here is really I+S from PAW 1727 ! i eps_abg <du/db|S|du/dg> = -2*Im<du/db|S|du/dg> 1728 ! 9 berrycurve 1729 doti = -DOT_PRODUCT(cg1_k(2,(nn-1)*npw_k+1:nn*npw_k,bdir),scg1_k(1,(nn-1)*npw_k+1:nn*npw_k,gdir)) + & 1730 & DOT_PRODUCT(cg1_k(1,(nn-1)*npw_k+1:nn*npw_k,bdir),scg1_k(2,(nn-1)*npw_k+1:nn*npw_k,gdir)) 1731 orbmag_terms(adir,berrycurve,nn) = orbmag_terms(adir,berrycurve,nn) - two*doti*trnrm 1732 1733 end do 1734 1735 end do 1736 1737 ABI_FREE(cwavef) 1738 ABI_FREE(cwavefp) 1739 ABI_FREE(cwaveb1) 1740 ABI_FREE(cwaveg1) 1741 ABI_FREE(cwavedsdb) 1742 ABI_FREE(cwavedsdg) 1743 ABI_FREE(ghc) 1744 ABI_FREE(gsc) 1745 ABI_FREE(gvnlc) 1746 ABI_FREE(cg_k) 1747 ABI_FREE(scg_k) 1748 ABI_FREE(scg1_k) 1749 ABI_FREE(dscg_k) 1750 ABI_FREE(cg1_k) 1751 ABI_FREE(pcg1_k) 1752 ABI_FREE(scprod) 1753 1754 icg = icg + npw_k*nband_k 1755 ikg = ikg + npw_k 1756 1757 ABI_FREE(ylm_k) 1758 ABI_FREE(ylmgr_k) 1759 ABI_FREE(kpg_k) 1760 ABI_FREE(ffnl_k) 1761 ABI_FREE(ph3d) 1762 ABI_FREE(phkxred) 1763 1764 end do ! end loop over kpts 1765 1766 if (nproc > 1) then 1767 buff_size=size(orbmag_terms) 1768 ABI_MALLOC(buffer1,(buff_size)) 1769 ABI_MALLOC(buffer2,(buff_size)) 1770 buffer1(1:buff_size) = reshape(orbmag_terms,(/3*nterms*nband_k/)) 1771 call xmpi_sum(buffer1,buffer2,buff_size,spaceComm,ierr) 1772 orbmag_terms(1:3,1:nterms,1:nband_k)=reshape(buffer2,(/3,nterms,nband_k/)) 1773 ABI_FREE(buffer1) 1774 ABI_FREE(buffer2) 1775 end if 1776 1777 ! convert to cartesian frame, supply 1/(2\pi)^2 factor 1778 ! but not to lrb and a0an terms, they are already cartesian and don't require 1779 ! additional normalization 1780 do nn = 1, nband_k 1781 orbmag_terms(1:3,cci,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,cci,nn)) 1782 orbmag_terms(1:3,vvii,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,vvii,nn)) 1783 orbmag_terms(1:3,vvib,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,vvib,nn)) 1784 orbmag_terms(1:3,vvia,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,vvia,nn)) 1785 orbmag_terms(1:3,rho0h1,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,rho0h1,nn)) 1786 orbmag_terms(1:3,rho0s1,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,rho0s1,nn)) 1787 orbmag_terms(1:3,berrycurve,nn) = (ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,berrycurve,nn)) 1788 end do 1789 1790 ! compute trace of each term 1791 ABI_MALLOC(orbmag_trace,(3,nterms)) 1792 orbmag_trace = zero 1793 do nn = 1, nband_k 1794 orbmag_trace(1:3,1:nterms) = orbmag_trace(1:3,1:nterms) + orbmag_terms(1:3,1:nterms,nn) 1795 end do 1796 1797 call orbmag_output(dtset,local_fermie,nband_k,nterms,orbmag_terms,orbmag_trace) 1798 1799 !--------------------------------------------------- 1800 ! deallocate memory 1801 !--------------------------------------------------- 1802 call gs_hamk%free() 1803 1804 ABI_FREE(vlocal) 1805 ABI_FREE(vectornd) 1806 if(has_nucdip) then 1807 ABI_FREE(vectornd_pac) 1808 end if 1809 ABI_FREE(kg_k) 1810 ABI_FREE(kinpw) 1811 ABI_FREE(ph1d) 1812 ABI_FREE(orbmag_terms) 1813 ABI_FREE(orbmag_trace) 1814 1815 ABI_FREE(dimlmn) 1816 call pawcprj_free(cprj_k) 1817 ABI_FREE(cprj_k) 1818 call pawcprj_free(cwaveprj) 1819 ABI_FREE(cwaveprj) 1820 1821 end subroutine orbmag_ddk
ABINIT/orbmag_output [ Functions ]
NAME
orbmag_ddk_output
FUNCTION
This routine outputs orbmag terms tailored for ddk routine
COPYRIGHT
Copyright (C) 2003-2021 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,pawcprj_mpi_recv pawcprj_mpi_send,xmpi_sum
SOURCE
1857 subroutine orbmag_output(dtset,fermie,nband_k,nterms,orbmag_terms,orbmag_trace) 1858 1859 1860 !Arguments ------------------------------------ 1861 !scalars 1862 integer,intent(in) :: nband_k,nterms 1863 real(dp),intent(in) :: fermie 1864 type(dataset_type),intent(in) :: dtset 1865 1866 !arrays 1867 real(dp),intent(in) :: orbmag_terms(3,nterms,nband_k),orbmag_trace(3,nterms) 1868 1869 !Local variables ------------------------- 1870 !scalars 1871 integer :: adir,iband,iterms 1872 integer,parameter :: cci=1,vvii=2,vvia=3,vvib=4,rho0h1=5,rho0s1=6,lrb=7,a0an=8,berrycurve=9 1873 character(len=500) :: message 1874 1875 !arrays 1876 real(dp) :: orbmag_bb(3,2,nband_k),orbmag_total(3) 1877 1878 ! *********************************************************************** 1879 1880 orbmag_bb=zero;orbmag_total=zero 1881 do iterms = 1, nterms-1 1882 orbmag_total(1:3)=orbmag_total(1:3) + orbmag_trace(1:3,iterms) 1883 do iband=1, nband_k 1884 orbmag_bb(1:3,1,iband) = orbmag_bb(1:3,1,iband) + orbmag_terms(1:3,iterms,iband) 1885 end do 1886 end do 1887 1888 write(message,'(a,a,a)')ch10,'====================================================',ch10 1889 call wrtout(ab_out,message,'COLL') 1890 1891 if(dtset%orbmag .GT. 0) then 1892 write(message,'(a,a)')' Orbital magnetic moment computed with DFPT derivative wavefunctions ',ch10 1893 call wrtout(ab_out,message,'COLL') 1894 end if 1895 1896 if(dtset%orbmag .LT. 0) then 1897 write(message,'(a,a)')' Orbital magnetic moment computed with Finite Difference derivative wavefunctions ',ch10 1898 call wrtout(ab_out,message,'COLL') 1899 end if 1900 1901 write(message,'(a)')' Orbital magnetic moment, Cartesian directions : ' 1902 call wrtout(ab_out,message,'COLL') 1903 write(message,'(3es16.8)') (orbmag_total(adir),adir=1,3) 1904 call wrtout(ab_out,message,'COLL') 1905 write(message,'(a)')ch10 1906 call wrtout(ab_out,message,'COLL') 1907 write(message,'(a)')' Integral of Berry curvature, Cartesian directions : ' 1908 call wrtout(ab_out,message,'COLL') 1909 write(message,'(3es16.8)') (orbmag_trace(adir,berrycurve),adir=1,3) 1910 call wrtout(ab_out,message,'COLL') 1911 write(message,'(a,es16.8)')' Fermie energy : ',fermie 1912 call wrtout(ab_out,message,'COLL') 1913 1914 if(abs(dtset%orbmag) .GE. 2) then 1915 write(message,'(a)')ch10 1916 call wrtout(ab_out,message,'COLL') 1917 write(message,'(a)')' Orbital magnetic moment, Term-by-term breakdown : ' 1918 call wrtout(ab_out,message,'COLL') 1919 write(message,'(a,3es16.8)') ' Conduction space : ',(orbmag_trace(adir,cci),adir=1,3) 1920 call wrtout(ab_out,message,'COLL') 1921 write(message,'(a,3es16.8)') ' Valence space IIb : ',(orbmag_trace(adir,vvii),adir=1,3) 1922 call wrtout(ab_out,message,'COLL') 1923 write(message,'(a,3es16.8)') ' Valence space Ia+IIa+IIIa : ',(orbmag_trace(adir,vvia),adir=1,3) 1924 call wrtout(ab_out,message,'COLL') 1925 write(message,'(a,3es16.8)') ' Valence space Ib : ',(orbmag_trace(adir,vvib),adir=1,3) 1926 call wrtout(ab_out,message,'COLL') 1927 write(message,'(a,3es16.8)') ' S(1) PAW overlap : ',(orbmag_trace(adir,rho0s1),adir=1,3) 1928 call wrtout(ab_out,message,'COLL') 1929 write(message,'(a,3es16.8)') ' H(1) cprj : ',(orbmag_trace(adir,rho0h1),adir=1,3) 1930 call wrtout(ab_out,message,'COLL') 1931 write(message,'(a,3es16.8)') ' H(1) on-site 1/2 L_R.B : ',(orbmag_trace(adir,lrb),adir=1,3) 1932 call wrtout(ab_out,message,'COLL') 1933 write(message,'(a,3es16.8)') ' H(1) on-site A0.An : ',(orbmag_trace(adir,a0an),adir=1,3) 1934 call wrtout(ab_out,message,'COLL') 1935 write(message,'(a,3es16.8)') ' Berry curvature : ',(orbmag_trace(adir,berrycurve),adir=1,3) 1936 call wrtout(ab_out,message,'COLL') 1937 end if 1938 1939 if(abs(dtset%orbmag) .EQ. 3) then 1940 write(message,'(a)')ch10 1941 call wrtout(ab_out,message,'COLL') 1942 write(message,'(a)')' Orbital magnetic moment, Term-by-term breakdown for each band : ' 1943 call wrtout(ab_out,message,'COLL') 1944 do iband = 1, nband_k 1945 write(message,'(a)')ch10 1946 call wrtout(ab_out,message,'COLL') 1947 write(message,'(a,i2,a,i2)') ' band ',iband,' of ',nband_k 1948 call wrtout(ab_out,message,'COLL') 1949 write(message,'(a,3es16.8)') ' Total orbital moment : ',(orbmag_bb(adir,1,iband),adir=1,3) 1950 call wrtout(ab_out,message,'COLL') 1951 write(message,'(a,3es16.8)') ' Conduction space : ',(orbmag_terms(adir,cci,iband),adir=1,3) 1952 call wrtout(ab_out,message,'COLL') 1953 write(message,'(a,3es16.8)') ' Valence space IIb : ',(orbmag_terms(adir,vvii,iband),adir=1,3) 1954 call wrtout(ab_out,message,'COLL') 1955 write(message,'(a,3es16.8)') ' Valence space Ia+IIa+IIIa : ',(orbmag_terms(adir,vvia,iband),adir=1,3) 1956 call wrtout(ab_out,message,'COLL') 1957 write(message,'(a,3es16.8)') ' Valence space Ib : ',(orbmag_terms(adir,vvib,iband),adir=1,3) 1958 call wrtout(ab_out,message,'COLL') 1959 write(message,'(a,3es16.8)') ' S(1) PAW overlap : ',(orbmag_terms(adir,rho0s1,iband),adir=1,3) 1960 call wrtout(ab_out,message,'COLL') 1961 write(message,'(a,3es16.8)') ' H(1) cprj : ',(orbmag_terms(adir,rho0h1,iband),adir=1,3) 1962 call wrtout(ab_out,message,'COLL') 1963 write(message,'(a,3es16.8)') ' H(1) on-site 1/2 L_R.B : ',(orbmag_terms(adir,lrb,iband),adir=1,3) 1964 call wrtout(ab_out,message,'COLL') 1965 write(message,'(a,3es16.8)') ' H(1) on-site A0.An : ',(orbmag_terms(adir,a0an,iband),adir=1,3) 1966 call wrtout(ab_out,message,'COLL') 1967 write(message,'(a,3es16.8)') ' Berry curvature : ',(orbmag_terms(adir,berrycurve,iband),adir=1,3) 1968 call wrtout(ab_out,message,'COLL') 1969 end do 1970 end if 1971 1972 write(message,'(a,a,a)')ch10,'====================================================',ch10 1973 call wrtout(ab_out,message,'COLL') 1974 1975 end subroutine orbmag_output
ABINIT/orbmag_wf [ Functions ]
NAME
orbmag_wf
FUNCTION
This routine computes the orbital magnetization based on input wavefunctions. It is assumed that only completely filled bands are present.
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f) cg(2,mcg)=planewave coefficients of wavefunctions cprj(natom,mcprj*usecrpj)=<p_lmn|Cnk> coefficients for each WF |Cnk> and each |p_lmn> non-local projector dtset <type(dataset_type)>=all input variables in this dataset kg(3,mpw*mkmem) = reduced (integer) coordinates of G vecs in basis sphere mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol mpi_enreg=information about MPI parallelization nfftf= - PAW only - number of FFT grid points for the "fine" grid (see NOTES at beginning of scfcv) npwarr(nkpt)=number of planewaves in basis at this k point paw_ij(my_natom*usepaw) <type(paw_ij_type)>=paw arrays given on (i,j) channels pawang <type(pawang_type)>=paw angular mesh and related data pawfgr <type(pawfgr_type)>=fine grid parameters and related data pawrad(ntypat*psps%usepaw) <type(pawrad_type)>=paw radial mesh and related data pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data psps <type(pseudopotential_type)>=variables related to pseudopotentials pwind(pwind_alloc,2,3) = array used to compute the overlap matrix smat between k-points (see initberry.f) pwind_alloc = first dimension of pwind rprimd(3,3)=dimensional primitive translations in real space (bohr) symrec(3,3,nsym) = symmetries in reciprocal space in terms of reciprocal space primitive translations usecprj=1 if cprj datastructure has been allocated vhartr(nfftf)=Hartree potential vpsp(nfftf)=array for holding local psp vxc(nfftf,nspden)=exchange-correlation potential (hartree) in real space xred(3,natom) = location of atoms in unit cell ylm(mpw*mkmem,mpsang*mpsang*useylm)= real spherical harmonics for each G and k point ylmgr(mpw*mkmem,3,mpsang*mpsang*useylm)= gradients of real spherical harmonics
OUTPUT
SIDE EFFECTS
dtorbmag <type(orbmag_type)> = variables related to orbital magnetization
TODO
NOTES
See Ceresoli et al, PRB 74, 024408 (2006) [[cite:Ceresoli2006]], and Gonze and Zwanziger, PRB 84, 064445 (2011) [[cite:Gonze2011a]]. Chern number and magnetization computed using discretized wavefunction derivatives as in [[cite:Ceresoli2006]].
PARENTS
m_afterscfloop
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
2045 subroutine orbmag_wf(atindx1,cg,cprj,dtset,dtorbmag,& 2046 & mcg,mcprj,mpi_enreg,nattyp,nfftf,npwarr,paw_ij,pawang,pawfgr,pawrad,pawtab,psps,& 2047 & pwind,pwind_alloc,rprimd,usecprj,vectornd,& 2048 & vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 2049 2050 !Arguments ------------------------------------ 2051 !scalars 2052 integer,intent(in) :: mcg,mcprj,nfftf,pwind_alloc,usecprj,with_vectornd 2053 type(dataset_type),intent(in) :: dtset 2054 type(MPI_type), intent(inout) :: mpi_enreg 2055 type(orbmag_type), intent(inout) :: dtorbmag 2056 type(pawang_type),intent(in) :: pawang 2057 type(pawfgr_type),intent(in) :: pawfgr 2058 type(pseudopotential_type),intent(in) :: psps 2059 2060 !arrays 2061 integer,intent(in) :: atindx1(dtset%natom),nattyp(dtset%ntypat) 2062 integer,intent(in) :: npwarr(dtset%nkpt),pwind(pwind_alloc,2,3) 2063 real(dp),intent(in) :: cg(2,mcg),rprimd(3,3) 2064 real(dp),intent(in) :: vhartr(nfftf),vpsp(nfftf),vxc(nfftf,dtset%nspden),xred(3,dtset%natom) 2065 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 2066 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 2067 real(dp),intent(inout) :: vectornd(with_vectornd*nfftf,3) 2068 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 2069 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat*psps%usepaw) 2070 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj*usecprj) 2071 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw) 2072 2073 !Local variables ------------------------- 2074 !scalars 2075 integer :: adir,isppol,istwf_k,my_nspinor,nband_k,nn,ncpgr,nterms 2076 real(dp) :: trnrm,ucvol 2077 2078 !arrays 2079 integer,parameter :: cci=1,vvii=2,vvia=3,vvib=4,rho0h1=5,rho0s1=6,lrb=7,a0an=8,berrycurve=9 2080 real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3) 2081 real(dp),allocatable :: CCIterms(:,:,:),eeig(:,:),onsite_bm(:,:,:),onsite_l(:,:,:) 2082 real(dp),allocatable :: out_e(:,:,:),out_h(:,:,:),out_s(:,:,:) 2083 real(dp),allocatable :: orbmag_terms(:,:,:),orbmag_trace(:,:) 2084 real(dp),allocatable :: rhorij1(:,:,:),s1trace(:,:,:),udsqduchern(:,:,:),udsqdumag(:,:,:),VVIaterms(:,:,:) 2085 complex(dpc),allocatable :: onsite_bm_dir(:),onsite_l_dir(:),rhorij1_dir(:),s1trace_dir(:) 2086 2087 ! *********************************************************************** 2088 ! my_nspinor=max(1,dtorbmag%nspinor/mpi_enreg%nproc_spinor) 2089 2090 ncpgr = cprj(1,1)%ncpgr 2091 2092 ! TODO: generalize to nsppol > 1 2093 isppol = 1 2094 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 2095 nband_k = dtorbmag%mband_occ 2096 istwf_k = 1 2097 2098 ABI_MALLOC(onsite_l_dir,(nband_k)) 2099 ABI_MALLOC(onsite_l,(2,nband_k,3)) 2100 ABI_MALLOC(s1trace_dir,(nband_k)) 2101 ABI_MALLOC(s1trace,(2,nband_k,3)) 2102 ABI_MALLOC(rhorij1_dir,(nband_k)) 2103 ABI_MALLOC(rhorij1,(2,nband_k,3)) 2104 ABI_MALLOC(onsite_bm_dir,(nband_k)) 2105 ABI_MALLOC(onsite_bm,(2,nband_k,3)) 2106 ABI_MALLOC(VVIaterms,(2,nband_k,3)) 2107 ABI_MALLOC(out_s,(2,nband_k,3)) 2108 ABI_MALLOC(out_e,(2,nband_k,3)) 2109 ABI_MALLOC(out_h,(2,nband_k,3)) 2110 ABI_MALLOC(udsqduchern,(2,nband_k,3)) 2111 ABI_MALLOC(udsqdumag,(2,nband_k,3)) 2112 ABI_MALLOC(CCIterms,(2,nband_k,3)) 2113 2114 nterms = 9 ! various contributing terms in orbmag and berrycurve 2115 ! 1 orbmag CC 2116 ! 2 orbmag VV II 2117 ! 3 orbmag VV I+III part a 2118 ! 4 orbmag VV I+III part b 2119 ! 5 orbmag Tr[\rho^0 H^1] with D^0_ij part 2120 ! 6 orbmag -Tr[\rho^0 S^1] part 2121 ! 7 orbmag onsite L_R/r^3 2122 ! 8 orbmag onsite A0.An 2123 ! 9 berrycurve 2124 ABI_MALLOC(orbmag_terms,(3,nterms,nband_k)) 2125 orbmag_terms = zero 2126 2127 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) 2128 2129 ! call covar_test(atindx1,cg,cprj,dtorbmag,dtset,gprimd,mcg,mcprj,mpi_enreg,& 2130 ! & nband_k,npwarr,pawang,pawrad,pawtab,psps,pwind,pwind_alloc,xred) 2131 2132 ABI_MALLOC(eeig,(nband_k,dtset%nkpt)) 2133 eeig(:,:) = zero 2134 call make_eeig(atindx1,cg,cprj,dtset,eeig,gmet,gprimd,mcg,mcprj,mpi_enreg,nattyp,nband_k,nfftf,npwarr,& 2135 & paw_ij,pawfgr,pawtab,psps,rmet,rprimd,& 2136 & vectornd,vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 2137 2138 ! compute i*\epsilon_{abg}\sum_n <du|Q_SHE_Q|du> 2139 call duq_she_qdu(atindx1,cg,cprj,dtorbmag,dtset,eeig,gmet,gprimd,mcg,mcprj,mpi_enreg,& 2140 & nband_k,nfftf,npwarr,out_e,out_h,out_s,pawang,pawfgr,paw_ij,pawrad,pawtab,psps,pwind,pwind_alloc,& 2141 & rmet,rprimd,vectornd,vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 2142 2143 ! compute i*\epsilon_{abg}\sum_n <u|dS Q|du> with and without E_nk weights (needed respectively 2144 ! by Chern number and by magnetization) 2145 call udsqdu(atindx1,cg,cprj,dtorbmag,dtset,eeig,gmet,gprimd,& 2146 & mcg,mcprj,mpi_enreg,nband_k,npwarr,paw_ij,pawang,pawrad,pawtab,psps,& 2147 pwind,pwind_alloc,rmet,rprimd,udsqduchern,udsqdumag,xred,ylm,ylmgr) 2148 2149 do adir=1, 3 2150 ! this needs careful checking 2151 orbmag_terms(adir,berrycurve,1:nband_k) = out_s(1,1:nband_k,adir)-half*udsqduchern(1,1:nband_k,adir) 2152 end do 2153 2154 do adir = 1, 3 2155 2156 call make_onsite_l(atindx1,cprj,dtset,adir,mcprj,mpi_enreg,nband_k,onsite_l_dir,pawrad,pawtab) 2157 onsite_l(1,1:nband_k,adir) = real(onsite_l_dir(1:nband_k)) 2158 onsite_l(2,1:nband_k,adir) = aimag(onsite_l_dir(1:nband_k)) 2159 2160 call make_S1trace(adir,atindx1,cprj,dtset,eeig,mcprj,mpi_enreg,nattyp,nband_k,pawtab,s1trace_dir) 2161 s1trace(1,1:nband_k,adir) = real(s1trace_dir(1:nband_k)) 2162 s1trace(2,1:nband_k,adir) = aimag(s1trace_dir(1:nband_k)) 2163 2164 call make_rhorij1(adir,atindx1,cprj,dtset,mcprj,mpi_enreg,nattyp,nband_k,paw_ij,pawtab,rhorij1_dir) 2165 rhorij1(1,1:nband_k,adir) = real(rhorij1_dir(1:nband_k)) 2166 rhorij1(2,1:nband_k,adir) = aimag(rhorij1_dir(1:nband_k)) 2167 2168 if (any(abs(dtset%nucdipmom)>tol8)) then 2169 call make_onsite_bm(atindx1,cprj,dtset,adir,mcprj,mpi_enreg,nband_k,onsite_bm_dir,& 2170 & pawang,pawrad,pawtab) 2171 onsite_bm(1,1:nband_k,adir) = real(onsite_bm_dir(1:nband_k)) 2172 onsite_bm(2,1:nband_k,adir) = aimag(onsite_bm_dir(1:nband_k)) 2173 else 2174 onsite_bm(:,:,adir) = zero 2175 end if 2176 2177 orbmag_terms(adir,rho0h1,1:nband_k) = rhorij1(1,1:nband_k,adir) 2178 orbmag_terms(adir,rho0s1,1:nband_k) = s1trace(1,1:nband_k,adir) 2179 orbmag_terms(adir,lrb,1:nband_k) = onsite_l(1,1:nband_k,adir) 2180 orbmag_terms(adir,a0an,1:nband_k) = onsite_bm(1,1:nband_k,adir) 2181 2182 end do ! end loop over adir 2183 2184 !CCIterms=zero 2185 !call duqhqdu(atindx1,cg,CCIterms,cprj,dtorbmag,dtset,gmet,gprimd,mcg,mcprj,mpi_enreg,& 2186 ! & nattyp,nband_k,nfftf,npwarr,paw_ij,pawang,pawfgr,pawrad,pawtab,psps,pwind,pwind_alloc,& 2187 ! & rmet,rprimd,ucvol,vectornd,vhartr,vpsp,vxc,with_vectornd,xred,ylm,ylmgr) 2188 2189 call udsdsu(atindx1,cg,VVIaterms,cprj,dtorbmag,dtset,eeig,gmet,gprimd,mcg,mcprj,mpi_enreg,& 2190 & nband_k,npwarr,paw_ij,pawtab,psps,rmet,rprimd,xred,ylm,ylmgr) 2191 2192 do adir=1,3 2193 ! duqhqdu returns i*epsabg*\sum_occ [<d_gdir u|QHQ|d_bdir u>] 2194 ! CCI is (-i/2) times this 2195 orbmag_terms(adir,cci,1:nband_k)=half*out_h(1,1:nband_k,adir) 2196 !orbmag_terms(adir,cci,1:nband_k)=half*CCIterms(1,1:nband_k,adir) 2197 orbmag_terms(adir,vvii,1:nband_k)=half*out_e(1,1:nband_k,adir) 2198 orbmag_terms(adir,vvib,1:nband_k)=udsqdumag(1,1:nband_k,adir) 2199 orbmag_terms(adir,vvia,1:nband_k)=VVIaterms(1,1:nband_k,adir) 2200 end do 2201 2202 trnrm = two/(dtorbmag%fnkpt) 2203 2204 orbmag_terms(:,lrb,:) = trnrm*orbmag_terms(:,lrb,:) 2205 orbmag_terms(:,a0an,:) = trnrm*orbmag_terms(:,a0an,:) 2206 do nn = 1, nband_k 2207 orbmag_terms(1:3,cci,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,cci,nn)) 2208 orbmag_terms(1:3,vvii,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,vvii,nn)) 2209 orbmag_terms(1:3,vvib,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,vvib,nn)) 2210 orbmag_terms(1:3,vvia,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,vvia,nn)) 2211 orbmag_terms(1:3,rho0h1,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,rho0h1,nn)) 2212 orbmag_terms(1:3,rho0s1,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,rho0s1,nn)) 2213 orbmag_terms(1:3,berrycurve,nn) = (trnrm*ucvol/(two_pi*two_pi))*MATMUL(gprimd,orbmag_terms(1:3,berrycurve,nn)) 2214 end do 2215 2216 ! compute trace of each term 2217 ABI_MALLOC(orbmag_trace,(3,nterms)) 2218 orbmag_trace = zero 2219 do nn = 1, nband_k 2220 orbmag_trace(1:3,1:nterms) = orbmag_trace(1:3,1:nterms) + orbmag_terms(1:3,1:nterms,nn) 2221 end do 2222 2223 call orbmag_output(dtset,MAXVAL(eeig),nband_k,nterms,orbmag_terms,orbmag_trace) 2224 2225 if(allocated(eeig)) then 2226 ABI_FREE(eeig) 2227 end if 2228 2229 ABI_FREE(onsite_l_dir) 2230 ABI_FREE(onsite_l) 2231 ABI_FREE(s1trace_dir) 2232 ABI_FREE(s1trace) 2233 ABI_FREE(onsite_bm_dir) 2234 ABI_FREE(onsite_bm) 2235 ABI_FREE(rhorij1_dir) 2236 ABI_FREE(rhorij1) 2237 ABI_FREE(VVIaterms) 2238 ABI_FREE(out_e) 2239 ABI_FREE(out_h) 2240 ABI_FREE(out_s) 2241 ABI_FREE(udsqduchern) 2242 ABI_FREE(udsqdumag) 2243 ABI_FREE(CCIterms) 2244 ABI_FREE(orbmag_terms) 2245 ABI_FREE(orbmag_trace) 2246 2247 end subroutine orbmag_wf
ABINIT/udsdsu [ Functions ]
NAME
udsdsu
FUNCTION
Return (-i/2)*epsabg\sum_{n,n}<u_kn|\partial_b S|u_kn'><u_kn|\partial_g S|u_kn>E_nk
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
4462 subroutine udsdsu(atindx1,cg,cnum_udsdsu,cprj,dtorbmag,dtset,energies,gmet,gprimd,mcg,mcprj,mpi_enreg,& 4463 & nband_k,npwarr,paw_ij,pawtab,psps,rmet,rprimd,xred,ylm,ylmgr) 4464 4465 !Arguments ------------------------------------ 4466 !scalars 4467 integer,intent(in) :: mcg,mcprj,nband_k 4468 type(dataset_type),intent(in) :: dtset 4469 type(MPI_type), intent(inout) :: mpi_enreg 4470 type(orbmag_type), intent(inout) :: dtorbmag 4471 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 4472 type(pseudopotential_type),intent(in) :: psps 4473 4474 !arrays 4475 integer,intent(in) :: atindx1(dtset%natom),npwarr(dtset%nkpt) 4476 real(dp), intent(in) :: cg(2,mcg),energies(nband_k,dtset%nkpt),gmet(3,3),gprimd(3,3) 4477 real(dp), intent(in) :: rmet(3,3),rprimd(3,3),xred(3,dtset%natom) 4478 real(dp), intent(out) :: cnum_udsdsu(2,nband_k,3) 4479 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 4480 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 4481 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 4482 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 4483 4484 !Local variables ------------------------- 4485 !scalars 4486 integer :: adir,bdir,dimph1d,dimffnl,exchn2n3d,epsabg 4487 integer :: gdir,ia,iband,ibs1,ibs2 4488 integer :: icg,icprj,ider,idir,ierr 4489 integer :: ikg,ikg1,ikpt,ilm,isppol,istwf_k,jband 4490 integer :: me,my_nspinor,ncpgr,ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6 4491 integer :: nkpg,npw_k,npw_k_ 4492 integer :: nonlop_choice,nonlop_cpopt,nonlop_nnlout,nonlop_ndat,nonlop_paw_opt,nonlop_signs 4493 integer :: nproc,spaceComm,tim_nonlop 4494 real(dp) :: arg,doti,dotr,ecut_eff,ENK 4495 complex(dpc) :: udsdsu_term,ujdsbu,ujdsgu 4496 type(gs_hamiltonian_type) :: gs_hamk 4497 4498 !arrays 4499 integer :: nattyp_dum(dtset%ntypat) 4500 integer,allocatable :: dimlmn(:),kg_k(:,:) 4501 real(dp) :: kpoint(3),nonlop_lambda(1) 4502 real(dp),allocatable :: cwavef(:,:),cwavefp(:,:),ffnl_k(:,:,:,:) 4503 real(dp),allocatable :: kpg_k(:,:),nonlop_enlout(:) 4504 real(dp),allocatable :: phkxred(:,:),ph1d(:,:),ph3d(:,:,:) 4505 real(dp),allocatable :: svect(:,:,:),svectout(:,:),svectoutp(:,:),vectout(:,:) 4506 real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:) 4507 type(pawcprj_type),allocatable :: cprj_k(:,:),cwaveprj(:,:) 4508 4509 !---------------------------------------------------- 4510 4511 isppol = 1 4512 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 4513 spaceComm=mpi_enreg%comm_cell 4514 nproc=xmpi_comm_size(spaceComm) 4515 me = mpi_enreg%me_kpt 4516 4517 ncpgr = cprj(1,1)%ncpgr 4518 ABI_MALLOC(dimlmn,(dtset%natom)) 4519 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 4520 ABI_MALLOC(cprj_k,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 4521 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 4522 ABI_MALLOC(cwaveprj,(dtset%natom,1)) 4523 call pawcprj_alloc(cwaveprj,ncpgr,dimlmn) 4524 4525 !==== Initialize most of the Hamiltonian ==== 4526 !Allocate all arrays and initialize quantities that do not depend on k and spin. 4527 !gs_hamk is the normal hamiltonian at k 4528 ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3) 4529 ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6) 4530 istwf_k = 1 4531 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 4532 exchn2n3d = 0 ; ikg1 = 0 4533 4534 ABI_MALLOC(phkxred,(2,dtset%natom)) 4535 dimph1d=dtset%natom*(2*(ngfft1+ngfft2+ngfft3)+3) 4536 ABI_MALLOC(ph1d,(2,dimph1d)) 4537 call getph(atindx1,dtset%natom,ngfft1,ngfft2,ngfft3,ph1d,xred) 4538 call init_hamiltonian(gs_hamk,psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,& 4539 & dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,nucdipmom=dtset%nucdipmom,& 4540 & paw_ij=paw_ij) 4541 call gs_hamk%load_spin(isppol,with_nonlocal=.true.) 4542 4543 ABI_MALLOC(kg_k,(3,dtset%mpw)) 4544 4545 ! nonlop parameters 4546 nonlop_choice = 5 ! first derivative wrt k 4547 nonlop_cpopt = -1 4548 nonlop_nnlout = 1 ! size of enlout, not used in call 4549 ABI_MALLOC(nonlop_enlout,(nonlop_nnlout)) 4550 nonlop_lambda(1) = 0.0 ! shift for eigenvalues, not used 4551 nonlop_ndat = 1 ! number of wavefunctions to apply nonlop 4552 nonlop_paw_opt = 3 ! use Sij matrix 4553 nonlop_signs = 2 ! apply to function in recip space 4554 tim_nonlop = 0 ! timing not used 4555 4556 cnum_udsdsu(:,:,:) = zero 4557 icg = 0 4558 ikg = 0 4559 icprj = 0 4560 do ikpt = 1, dtset%nkpt 4561 4562 ! if the current kpt is not on the current processor, cycle 4563 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,-1,me)) cycle 4564 4565 kpoint(:)=dtset%kptns(:,ikpt) 4566 npw_k = npwarr(ikpt) 4567 4568 ! Build basis sphere of plane waves for the k-point 4569 kg_k(:,:) = 0 4570 call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg_k,kpoint,1,mpi_enreg,dtset%mpw,npw_k_) 4571 if (npw_k .NE. npw_k_) then 4572 write(std_out,'(a)')'JWZ debug udsdsu npw_k inconsistency' 4573 end if 4574 4575 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang)) 4576 ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm)) 4577 do ilm=1,psps%mpsang*psps%mpsang 4578 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 4579 ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm) 4580 end do 4581 4582 nkpg = 3 4583 ABI_MALLOC(kpg_k,(npw_k,nkpg)) 4584 call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k) 4585 4586 ! Compute nonlocal form factors ffnl at all (k+G): 4587 ider=1 ! want ffnl and 1st derivative 4588 idir=4 ! d ffnl/ dk 4589 dimffnl=4 ! 1 + number of derivatives 4590 ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat)) 4591 call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,& 4592 & gmet,gprimd,ider,idir,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,& 4593 & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,& 4594 & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,rmet,& 4595 & psps%usepaw,psps%useylm,ylm_k,ylmgr_k) 4596 4597 ! Load k-dependent part in the Hamiltonian datastructure 4598 ! - Compute 3D phase factors 4599 ! - Prepare various tabs in case of band-FFT parallelism 4600 ! - Load k-dependent quantities in the Hamiltonian 4601 ABI_MALLOC(ph3d,(2,npw_k,gs_hamk%matblk)) 4602 do ia=1, dtset%natom 4603 arg=two_pi*(kpoint(1)*xred(1,ia)+kpoint(2)*xred(2,ia)+kpoint(3)*xred(3,ia)) 4604 phkxred(1,ia)=cos(arg);phkxred(2,ia)=sin(arg) 4605 end do 4606 4607 call ph1d3d(1,dtset%natom,kg_k,dtset%natom,dtset%natom,npw_k,ngfft1,ngfft2,ngfft3,phkxred,ph1d,ph3d) 4608 4609 call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,& 4610 & kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,ph3d_k=ph3d,compute_gbound=.TRUE.) 4611 4612 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprj,ikpt,0,isppol,dtset%mband,& 4613 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 4614 4615 4616 ABI_MALLOC(cwavef,(2,npw_k)) 4617 ABI_MALLOC(svectout,(2,npw_k)) 4618 ABI_MALLOC(vectout,(2,npw_k)) 4619 ABI_MALLOC(svect,(2,3,npw_k*nband_k)) 4620 do adir = 1, 3 4621 do iband = 1, nband_k 4622 ibs1=(iband-1)*npw_k+1 4623 ibs2=iband*npw_k 4624 cwavef(1:2,1:npw_k) = cg(1:2,icg+ibs1:icg+ibs2) 4625 call pawcprj_get(atindx1,cwaveprj,cprj_k,dtset%natom,iband,0,ikpt,0,isppol,dtset%mband,& 4626 & dtset%mkmem,dtset%natom,1,nband_k,my_nspinor,dtset%nsppol,0) 4627 ! compute dS/dk_adir|u_nk>, store in svectout 4628 call nonlop(nonlop_choice,nonlop_cpopt,cwaveprj,nonlop_enlout,gs_hamk,adir,nonlop_lambda,& 4629 & mpi_enreg,nonlop_ndat,nonlop_nnlout,nonlop_paw_opt,nonlop_signs,svectout,& 4630 & tim_nonlop,cwavef,vectout) 4631 svect(1:2,adir,ibs1:ibs2) = svectout(1:2,1:npw_k) 4632 end do 4633 end do 4634 ABI_FREE(cwavef) 4635 ABI_FREE(svectout) 4636 ABI_FREE(vectout) 4637 ABI_FREE(ylm_k) 4638 ABI_FREE(ylmgr_k) 4639 ABI_FREE(kpg_k) 4640 ABI_FREE(ffnl_k) 4641 ABI_FREE(ph3d) 4642 4643 do adir = 1, 3 4644 4645 do epsabg = 1, -1, -2 4646 if (epsabg .EQ. 1) then 4647 bdir = modulo(adir,3)+1 4648 gdir = modulo(adir+1,3)+1 4649 else 4650 bdir = modulo(adir+1,3)+1 4651 gdir = modulo(adir,3)+1 4652 end if 4653 4654 ABI_MALLOC(svectout,(2,npw_k)) 4655 ABI_MALLOC(svectoutp,(2,npw_k)) 4656 ABI_MALLOC(cwavefp,(2,npw_k)) 4657 do iband = 1, nband_k 4658 4659 ENK = energies(iband,ikpt) 4660 svectout(1:2,1:npw_k) = svect(1:2,gdir,(iband-1)*npw_k+1:iband*npw_k) 4661 svectoutp(1:2,1:npw_k) = svect(1:2,bdir,(iband-1)*npw_k+1:iband*npw_k) 4662 4663 do jband = 1, nband_k 4664 4665 cwavefp(1:2,1:npw_k) = cg(1:2,icg+(jband-1)*npw_k+1:icg+jband*npw_k) 4666 4667 dotr=DOT_PRODUCT(cwavefp(1,:),svectout(1,:))+DOT_PRODUCT(cwavefp(2,:),svectout(2,:)) 4668 doti=DOT_PRODUCT(cwavefp(1,:),svectout(2,:))-DOT_PRODUCT(cwavefp(2,:),svectout(1,:)) 4669 4670 ujdsgu = cmplx(dotr,doti,KIND=dpc) 4671 4672 dotr=DOT_PRODUCT(cwavefp(1,:),svectoutp(1,:))+DOT_PRODUCT(cwavefp(2,:),svectoutp(2,:)) 4673 doti=DOT_PRODUCT(cwavefp(1,:),svectoutp(2,:))-DOT_PRODUCT(cwavefp(2,:),svectoutp(1,:)) 4674 4675 ujdsbu = cmplx(dotr,doti,KIND=dpc) 4676 4677 ! accumulate (-i/2)*epsabg*ENK\sum_occ [<u_nk|dS_bdir|u_n'k><u_n'k|dS_gdir|u_nk>] 4678 udsdsu_term = -half*j_dpc*epsabg*ENK*CONJG(ujdsbu)*ujdsgu 4679 cnum_udsdsu(1,iband,adir) = cnum_udsdsu(1,iband,adir) + real(udsdsu_term) 4680 cnum_udsdsu(2,iband,adir) = cnum_udsdsu(2,iband,adir) + aimag(udsdsu_term) 4681 4682 end do !end loop over jband 4683 end do ! end loop over iband 4684 ABI_FREE(svectout) 4685 ABI_FREE(svectoutp) 4686 ABI_FREE(cwavefp) 4687 4688 end do ! end loop over epsabg 4689 end do ! end loop over adir 4690 4691 icg = icg + npw_k*nband_k 4692 ikg = ikg + npw_k 4693 icprj = icprj + nband_k 4694 4695 ABI_FREE(svect) 4696 4697 end do ! end loop over ikpt 4698 4699 ! ---- parallel communication 4700 if(nproc > 1) then 4701 call xmpi_sum(cnum_udsdsu,spaceComm,ierr) 4702 end if 4703 4704 call gs_hamk%free() 4705 4706 ABI_FREE(dimlmn) 4707 call pawcprj_free(cprj_k) 4708 ABI_FREE(cprj_k) 4709 call pawcprj_free(cwaveprj) 4710 ABI_FREE(cwaveprj) 4711 4712 ABI_FREE(phkxred) 4713 ABI_FREE(ph1d) 4714 ABI_FREE(kg_k) 4715 ABI_FREE(nonlop_enlout) 4716 4717 end subroutine udsdsu
ABINIT/udsqdu [ Functions ]
NAME
udsqdu
FUNCTION
Return i*epsabg\sum_n<u_kn|\partial_b S Q |\partial_g u_kn> where Q projects onto the conduction space. This term contributes to the Chern number (integral over Berry curvature).
COPYRIGHT
Copyright (C) 2003-2020 ABINIT group (JWZ) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
INPUTS
OUTPUT
only printing
SIDE EFFECTS
TODO
NOTES
PARENTS
m_orbmag
CHILDREN
pawcprj_alloc,pawcprj_free,pawcprj_get,pawcprj_getdim,xmpi_sum
SOURCE
3501 subroutine udsqdu(atindx1,cg,cprj,dtorbmag,dtset,energies,gmet,gprimd,& 3502 & mcg,mcprj,mpi_enreg,nband_k,npwarr,paw_ij,pawang,pawrad,pawtab,psps,& 3503 pwind,pwind_alloc,rmet,rprimd,udsqduchern,udsqdumag,xred,ylm,ylmgr) 3504 3505 !Arguments ------------------------------------ 3506 !scalars 3507 integer,intent(in) :: mcg,mcprj,nband_k,pwind_alloc 3508 type(dataset_type),intent(in) :: dtset 3509 type(MPI_type), intent(inout) :: mpi_enreg 3510 type(orbmag_type), intent(inout) :: dtorbmag 3511 type(pawang_type),intent(in) :: pawang 3512 type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj) 3513 type(pseudopotential_type),intent(in) :: psps 3514 3515 !arrays 3516 integer,intent(in) :: atindx1(dtset%natom) 3517 integer,intent(in) :: npwarr(dtset%nkpt),pwind(pwind_alloc,2,3) 3518 real(dp), intent(in) :: cg(2,mcg),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3),xred(3,dtset%natom) 3519 real(dp), intent(out) :: udsqduchern(2,nband_k,3),udsqdumag(2,nband_k,3) 3520 real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm) 3521 real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm) 3522 real(dp),intent(in) :: energies(nband_k,dtset%nkpt) 3523 type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw) 3524 type(pawrad_type),intent(in) :: pawrad(dtset%ntypat) 3525 type(pawtab_type),intent(in) :: pawtab(dtset%ntypat) 3526 3527 !Local variables ------------------------- 3528 !scalars 3529 integer :: adir,bdir,countg,countk,dimph1d,dimffnl,exchn2n3d,epsabg 3530 integer :: gdir,gfor,gsigma,ia,iband,ibs1,ibs2 3531 integer :: icg,icprji,ider,idir,ierr 3532 integer :: ikg,ikg1,ikpt,ikpt_loc,ikpti,ikptg,ikptgi,ilm,isppol,istwf_k,itrs 3533 integer :: mcg1_k,me,my_nspinor,n2dim,ncpgr,ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6 3534 integer :: nkpg,nproc,npw_k,npw_k_,npw_kg 3535 integer :: nonlop_choice,nonlop_cpopt,nonlop_nnlout,nonlop_ndat 3536 integer :: nonlop_paw_opt,nonlop_signs,ntotcp 3537 integer :: shiftbd,smatrix_ddkflag,smatrix_job,spaceComm,tim_nonlop 3538 real(dp) :: arg,deltag,doti,dotr,ecut_eff,ENK 3539 complex(dpc) :: cprefac,udsqduchern_term,udsqdumag_term 3540 type(gs_hamiltonian_type) :: gs_hamk 3541 3542 !arrays 3543 integer :: nattyp_dum(dtset%ntypat) 3544 integer,allocatable :: dimlmn(:),kg_k(:,:),pwind_kg(:),sflag_k(:) 3545 real(dp) :: dkg(3),dtm_k(2),kpoint(3),nonlop_lambda(1) 3546 real(dp),allocatable :: cg_k(:,:),cg1_kg(:,:),cgqg(:,:),cwavef(:,:),ffnl_k(:,:,:,:) 3547 real(dp),allocatable :: kk_paw(:,:,:),kpg_k(:,:),nonlop_enlout(:) 3548 real(dp),allocatable :: phkxred(:,:),ph1d(:,:),ph3d(:,:,:),pwnsfac_k(:,:) 3549 real(dp),allocatable :: smat_inv(:,:,:),smat_kk(:,:,:),svect(:,:,:),svectout(:,:),vectout(:,:) 3550 real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:) 3551 type(pawcprj_type),allocatable :: cprj_buf(:,:),cprj_k(:,:),cprj_kg(:,:),cwaveprj(:,:) 3552 3553 !---------------------------------------------------- 3554 3555 isppol = 1 3556 my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor) 3557 spaceComm=mpi_enreg%comm_cell 3558 nproc=xmpi_comm_size(spaceComm) 3559 me = mpi_enreg%me_kpt 3560 3561 ncpgr = cprj(1,1)%ncpgr 3562 ABI_MALLOC(dimlmn,(dtset%natom)) 3563 call pawcprj_getdim(dimlmn,dtset%natom,nattyp_dum,dtset%ntypat,dtset%typat,pawtab,'R') 3564 ABI_MALLOC(cprj_k,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3565 call pawcprj_alloc(cprj_k,ncpgr,dimlmn) 3566 ABI_MALLOC(cprj_kg,(dtset%natom,dtorbmag%nspinor*dtset%mband)) 3567 call pawcprj_alloc(cprj_kg,ncpgr,dimlmn) 3568 ABI_MALLOC(cwaveprj,(dtset%natom,1)) 3569 call pawcprj_alloc(cwaveprj,ncpgr,dimlmn) 3570 n2dim = dtorbmag%nspinor*nband_k 3571 ntotcp = n2dim*SUM(dimlmn(:)) 3572 if (nproc>1) then 3573 ABI_MALLOC(cprj_buf,(dtset%natom,n2dim)) 3574 call pawcprj_alloc(cprj_buf,ncpgr,dimlmn) 3575 end if 3576 3577 ABI_MALLOC(kk_paw,(2,dtset%mband,dtset%mband)) 3578 ABI_MALLOC(sflag_k,(nband_k)) 3579 ABI_MALLOC(pwind_kg,(dtset%mpw)) 3580 ABI_MALLOC(pwnsfac_k,(4,dtset%mpw)) 3581 pwnsfac_k(1,:) = one; pwnsfac_k(2,:) = zero 3582 pwnsfac_k(3,:) = one; pwnsfac_k(4,:) = zero 3583 3584 ABI_MALLOC(kg_k,(3,dtset%mpw)) 3585 3586 mcg1_k = dtset%mpw*dtset%nsppol*my_nspinor*nband_k 3587 ABI_MALLOC(cg1_kg,(2,mcg1_k)) 3588 ABI_MALLOC(cg_k,(2,mcg1_k)) 3589 ABI_MALLOC(smat_inv,(2,nband_k,nband_k)) 3590 ABI_MALLOC(smat_kk,(2,nband_k,nband_k)) 3591 3592 smatrix_ddkflag = 1 3593 itrs = 0 3594 smatrix_job = 1 3595 shiftbd = 1 3596 3597 !==== Initialize most of the Hamiltonian ==== 3598 !Allocate all arrays and initialize quantities that do not depend on k and spin. 3599 !gs_hamk is the normal hamiltonian at k 3600 ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3) 3601 ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6) 3602 istwf_k = 1 3603 ecut_eff = dtset%ecut*(dtset%dilatmx)**2 3604 exchn2n3d = 0 ; ikg1 = 0 3605 3606 ABI_MALLOC(phkxred,(2,dtset%natom)) 3607 dimph1d=dtset%natom*(2*(ngfft1+ngfft2+ngfft3)+3) 3608 ABI_MALLOC(ph1d,(2,dimph1d)) 3609 call getph(atindx1,dtset%natom,ngfft1,ngfft2,ngfft3,ph1d,xred) 3610 call init_hamiltonian(gs_hamk,psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,& 3611 & dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,nucdipmom=dtset%nucdipmom,& 3612 & paw_ij=paw_ij) 3613 call gs_hamk%load_spin(isppol,with_nonlocal=.true.) 3614 3615 ! nonlop parameters 3616 nonlop_choice = 5 ! first derivative wrt k 3617 nonlop_cpopt = -1 3618 nonlop_nnlout = 1 ! size of enlout, not used in call 3619 ABI_MALLOC(nonlop_enlout,(nonlop_nnlout)) 3620 nonlop_lambda(1) = 0.0 ! shift for eigenvalues, not used 3621 nonlop_ndat = 1 ! number of wavefunctions to apply nonlop 3622 nonlop_paw_opt = 3 ! use Sij matrix 3623 nonlop_signs = 2 ! apply to function in recip space 3624 tim_nonlop = 0 ! timing not used 3625 3626 udsqduchern(:,:,:) = zero 3627 udsqdumag(:,:,:) = zero 3628 3629 do ikpt_loc = 1,dtorbmag%fmkmem_max 3630 3631 ikpt=mpi_enreg%kpt_loc2fbz_sp(me, ikpt_loc,1) 3632 ! if this k and spin are for me do it 3633 if (ikpt > 0) then 3634 3635 ikpti = dtorbmag%indkk_f2ibz(ikpt,1) 3636 icprji = dtorbmag%cprjindex(ikpti,isppol) 3637 npw_k = npwarr(ikpti) 3638 icg = dtorbmag%cgindex(ikpti,dtset%nsppol) 3639 ikg = dtorbmag%fkgindex(ikpt) 3640 3641 countk = npw_k*my_nspinor*nband_k 3642 cg_k(1:2,1:countk) = cg(1:2,icg+1:icg+countk) 3643 3644 call pawcprj_get(atindx1,cprj_k,cprj,dtset%natom,1,icprji,ikpti,0,isppol,dtset%mband,& 3645 & dtset%mkmem,dtset%natom,nband_k,nband_k,my_nspinor,dtset%nsppol,0) 3646 3647 kpoint(:)=dtset%kptns(:,ikpt) 3648 ! Build basis sphere of plane waves for the k-point 3649 kg_k(:,:) = 0 3650 call kpgsph(ecut_eff,exchn2n3d,gmet,ikg1,ikpt,istwf_k,kg_k,kpoint,1,mpi_enreg,dtset%mpw,npw_k_) 3651 if (npw_k .NE. npw_k_) then 3652 write(std_out,'(a)')'JWZ debug udsqdu npw_k inconsistency' 3653 end if 3654 3655 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang)) 3656 ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm)) 3657 do ilm=1,psps%mpsang*psps%mpsang 3658 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 3659 ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm) 3660 end do 3661 3662 nkpg = 3 3663 ABI_MALLOC(kpg_k,(npw_k,nkpg)) 3664 call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k) 3665 3666 ! Compute nonlocal form factors ffnl at all (k+G): 3667 ider=1 ! want ffnl and 1st derivative 3668 idir=4 ! d ffnl/ dk 3669 dimffnl=4 ! 1 + number of derivatives 3670 ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat)) 3671 call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,& 3672 & gmet,gprimd,ider,idir,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,& 3673 & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,& 3674 & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,rmet,& 3675 & psps%usepaw,psps%useylm,ylm_k,ylmgr_k) 3676 3677 ! Load k-dependent part in the Hamiltonian datastructure 3678 ! - Compute 3D phase factors 3679 ! - Prepare various tabs in case of band-FFT parallelism 3680 ! - Load k-dependent quantities in the Hamiltonian 3681 ABI_MALLOC(ph3d,(2,npw_k,gs_hamk%matblk)) 3682 do ia=1, dtset%natom 3683 arg=two_pi*(kpoint(1)*xred(1,ia)+kpoint(2)*xred(2,ia)+kpoint(3)*xred(3,ia)) 3684 phkxred(1,ia)=cos(arg);phkxred(2,ia)=sin(arg) 3685 end do 3686 3687 call ph1d3d(1,dtset%natom,kg_k,dtset%natom,dtset%natom,npw_k,ngfft1,ngfft2,ngfft3,phkxred,ph1d,ph3d) 3688 3689 call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,& 3690 & kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,ph3d_k=ph3d,compute_gbound=.TRUE.) 3691 3692 ABI_MALLOC(cwavef,(2,npw_k)) 3693 ABI_MALLOC(svectout,(2,npw_k)) 3694 ABI_MALLOC(vectout,(2,npw_k)) 3695 ABI_MALLOC(svect,(2,3,npw_k*nband_k)) 3696 3697 do bdir = 1, 3 3698 do iband = 1, nband_k 3699 3700 ibs1=(iband-1)*npw_k+1 3701 ibs2=iband*npw_k 3702 3703 cwavef(1:2,1:npw_k) = cg_k(1:2,ibs1:ibs2) 3704 call pawcprj_get(atindx1,cwaveprj,cprj_k,dtset%natom,iband,0,ikpt,0,isppol,dtset%mband,& 3705 & dtset%mkmem,dtset%natom,1,nband_k,my_nspinor,dtset%nsppol,0) 3706 3707 ! compute dS/dk_bdir|u_nk> 3708 call nonlop(nonlop_choice,nonlop_cpopt,cwaveprj,nonlop_enlout,gs_hamk,bdir,nonlop_lambda,& 3709 & mpi_enreg,nonlop_ndat,nonlop_nnlout,nonlop_paw_opt,nonlop_signs,svectout,& 3710 & tim_nonlop,cwavef,vectout) 3711 3712 svect(1:2,bdir,ibs1:ibs2) = svectout(1:2,1:npw_k) 3713 3714 end do ! end loop over iband 3715 end do ! end loop over bdir 3716 ABI_FREE(cwavef) 3717 ABI_FREE(svectout) 3718 ABI_FREE(vectout) 3719 3720 end if ! end check that ikpt > 0 3721 3722 do adir = 1, 3 3723 do epsabg = 1, -1, -2 3724 if (epsabg .EQ. 1) then 3725 bdir = modulo(adir,3)+1 3726 gdir = modulo(adir+1,3)+1 3727 else 3728 bdir = modulo(adir+1,3)+1 3729 gdir = modulo(adir,3)+1 3730 end if 3731 3732 do gfor = 1, 2 3733 gsigma = 3-2*gfor 3734 dkg(1:3) = gsigma*dtorbmag%dkvecs(1:3,gdir) 3735 deltag = sqrt(DOT_PRODUCT(dkg,dkg)) 3736 3737 ikptg = dtorbmag%ikpt_dk(ikpt,gfor,gdir) 3738 ikptgi = dtorbmag%indkk_f2ibz(ikptg,1) 3739 npw_kg = npwarr(ikptgi) 3740 pwind_kg(1:npw_k) = pwind(ikg+1:ikg+npw_k,gfor,gdir) 3741 3742 cprefac = j_dpc*epsabg*gsigma/(two*deltag) 3743 3744 if (ikpt > 0 .AND. isppol > 0) then 3745 countg = npw_kg*my_nspinor*nband_k 3746 if(allocated(cgqg)) then 3747 ABI_FREE(cgqg) 3748 endif 3749 ABI_MALLOC(cgqg,(2,countg)) 3750 call mpicomm_helper(atindx1,gdir,gfor,cg,cgqg,cprj,cprj_kg,dimlmn,dtorbmag,dtset,& 3751 & ikpt,ikpt_loc,ikptgi,isppol,mcg,mcprj,me,mpi_enreg,my_nspinor,nband_k,& 3752 & nproc,npw_kg,npwarr,spaceComm) 3753 end if 3754 3755 if (ikpt > 0 .and. isppol > 0) then ! if I am treating a kpt, compute the overlaps 3756 3757 ! get covariant |u_{n,k+g}> and associated cprj 3758 call overlap_k1k2_paw(cprj_k,cprj_kg,dkg,gprimd,kk_paw,dtorbmag%lmn2max,& 3759 & dtorbmag%lmn_size,dtset%natom,dtset%mband,dtset%mband,& 3760 & my_nspinor,dtset%ntypat,pawang,pawrad,pawtab,dtset%typat,xred) 3761 sflag_k=0 3762 cg1_kg(:,:) = zero 3763 ! cg1_kg will hold |\tilde{u}_{n,k+g}> 3764 call smatrix(cg_k,cgqg,cg1_kg,smatrix_ddkflag,dtm_k,0,0,itrs,smatrix_job,nband_k,& 3765 & mcg1_k,mcg1_k,mcg1_k,1,dtset%mpw,nband_k,nband_k,npw_k,npw_kg,my_nspinor,& 3766 & pwind_kg,pwnsfac_k,sflag_k,shiftbd,smat_inv,smat_kk,kk_paw,psps%usepaw) 3767 3768 do iband = 1, nband_k 3769 3770 ibs1=(iband-1)*npw_k+1 3771 ibs2=iband*npw_k 3772 3773 dotr=DOT_PRODUCT(svect(1,bdir,ibs1:ibs2),cg1_kg(1,ibs1:ibs2))+& 3774 & DOT_PRODUCT(svect(2,bdir,ibs1:ibs2),cg1_kg(2,ibs1:ibs2)) 3775 doti=DOT_PRODUCT(svect(1,bdir,ibs1:ibs2),cg1_kg(2,ibs1:ibs2))-& 3776 & DOT_PRODUCT(svect(2,bdir,ibs1:ibs2),cg1_kg(1,ibs1:ibs2)) 3777 3778 ! accumulate i*epsabg*ENK\sum_occ [<u|dS_bdir Q|d_gdir u>] 3779 ENK = energies(iband,ikpt) 3780 udsqduchern_term = cprefac*cmplx(dotr,doti) 3781 udsqdumag_term = udsqduchern_term*ENK 3782 3783 udsqduchern(1,iband,adir) = udsqduchern(1,iband,adir) + real(udsqduchern_term) 3784 udsqduchern(2,iband,adir) = udsqduchern(2,iband,adir) + aimag(udsqduchern_term) 3785 udsqdumag(1,iband,adir) = udsqdumag(1,iband,adir) + real(udsqdumag_term) 3786 udsqdumag(2,iband,adir) = udsqdumag(2,iband,adir) + aimag(udsqdumag_term) 3787 3788 end do ! end loop over iband 3789 3790 if(allocated(cgqg)) then 3791 ABI_FREE(cgqg) 3792 end if 3793 3794 end if ! end check that ikpt > 0 3795 end do ! end loop for gfor 3796 end do ! end loop over epsabg 3797 end do ! end loop over adir 3798 ABI_FREE(ylm_k) 3799 ABI_FREE(ylmgr_k) 3800 ABI_FREE(kpg_k) 3801 ABI_FREE(ffnl_k) 3802 ABI_FREE(ph3d) 3803 ABI_FREE(svect) 3804 end do ! end loop over ikpt_loc 3805 3806 ! accumulate result from all processes 3807 if(nproc > 1) then 3808 call xmpi_sum(udsqduchern,spaceComm,ierr) 3809 call xmpi_sum(udsqdumag,spaceComm,ierr) 3810 end if 3811 3812 call gs_hamk%free() 3813 3814 ABI_FREE(dimlmn) 3815 call pawcprj_free(cprj_k) 3816 ABI_FREE(cprj_k) 3817 call pawcprj_free(cprj_kg) 3818 ABI_FREE(cprj_kg) 3819 call pawcprj_free(cwaveprj) 3820 ABI_FREE(cwaveprj) 3821 if (nproc>1) then 3822 call pawcprj_free(cprj_buf) 3823 ABI_FREE(cprj_buf) 3824 end if 3825 3826 ABI_FREE(kk_paw) 3827 ABI_FREE(sflag_k) 3828 ABI_FREE(pwind_kg) 3829 ABI_FREE(pwnsfac_k) 3830 ABI_FREE(kg_k) 3831 ABI_FREE(cg1_kg) 3832 ABI_FREE(cg_k) 3833 ABI_FREE(smat_inv) 3834 ABI_FREE(smat_kk) 3835 ABI_FREE(phkxred) 3836 ABI_FREE(ph1d) 3837 ABI_FREE(nonlop_enlout) 3838 3839 end subroutine udsqdu
m_orbmag/destroy_orbmag [ Functions ]
NAME
FUNCTION
deallocate fields in orbmag structure
INPUTS
OUTPUT
SOURCE
211 subroutine destroy_orbmag(dtorbmag) 212 213 !Arguments ------------------------------------ 214 !array 215 type(orbmag_type),intent(inout) :: dtorbmag 216 217 ! ************************************************************************ 218 219 ! Integer pointers 220 if(allocated(dtorbmag%atom_indsym)) then 221 ABI_FREE(dtorbmag%atom_indsym) 222 end if 223 if(allocated(dtorbmag%cgindex)) then 224 ABI_FREE(dtorbmag%cgindex) 225 end if 226 if(allocated(dtorbmag%cprjindex)) then 227 ABI_FREE(dtorbmag%cprjindex) 228 end if 229 if(allocated(dtorbmag%fkgindex)) then 230 ABI_FREE(dtorbmag%fkgindex) 231 end if 232 if(allocated(dtorbmag%ikpt_dk)) then 233 ABI_FREE(dtorbmag%ikpt_dk) 234 end if 235 if(allocated(dtorbmag%indkk_f2ibz)) then 236 ABI_FREE(dtorbmag%indkk_f2ibz) 237 end if 238 if(allocated(dtorbmag%i2fbz)) then 239 ABI_FREE(dtorbmag%i2fbz) 240 end if 241 if(allocated(dtorbmag%kg)) then 242 ABI_FREE(dtorbmag%kg) 243 end if 244 if(allocated(dtorbmag%kgindex)) then 245 ABI_FREE(dtorbmag%kgindex) 246 end if 247 if(allocated(dtorbmag%lmn_size)) then 248 ABI_FREE(dtorbmag%lmn_size) 249 end if 250 if(allocated(dtorbmag%lmn2_size)) then 251 ABI_FREE(dtorbmag%lmn2_size) 252 end if 253 if(allocated(dtorbmag%nband_occ)) then 254 ABI_FREE(dtorbmag%nband_occ) 255 end if 256 ! Real(dp) pointers 257 258 if(allocated(dtorbmag%fkptns)) then 259 ABI_FREE(dtorbmag%fkptns) 260 end if 261 if(allocated(dtorbmag%zarot)) then 262 ABI_FREE(dtorbmag%zarot) 263 end if 264 265 end subroutine destroy_orbmag
m_orbmag/orbmag_type [ Types ]
NAME
orbmag_type
FUNCTION
variables used in orbital magnetism calculation
SOURCE
85 type, public :: orbmag_type 86 87 ! WARNING : if you modify this datatype, please check whether there might be creation/destruction/copy routines, 88 ! declared in another part of ABINIT, that might need to take into account your modification. 89 90 ! Integer variables 91 integer :: orbmag ! value of orbmag input variable in use 92 integer :: fmkmem ! number of k-points in the FBZ per cpu 93 integer :: fmkmem_max ! max of fmkmem 94 integer :: fnkpt ! number of k-points in the FBZ 95 integer :: lmax 96 integer :: lmnmax 97 integer :: lmn2max 98 integer :: mkmem_max ! max of mkmem 99 integer :: natom ! number of atoms in unit cell 100 integer :: my_natom ! number of atoms treated by current proc 101 integer :: mband_occ ! max number of occupied bands (over spin) 102 ! this number must be the same for every k 103 integer :: nspinor ! nspinor input from data set 104 integer :: nsym 105 integer :: usepaw ! 1 if a PAW calculation, 0 else 106 107 ! Real(dp) scalars 108 real(dp) :: sdeg ! spin degeneracy: sdeg = 2 if nsppol = 1 109 110 ! Real(dp) arrays 111 real(dp) :: chern(2,3) ! result of chern number calculation 112 113 real(dp) :: dkvecs(3,3) ! dkvec(:,idir) = vector between a k-point and its nearest neighbour along idir 114 115 real(dp) :: orbmagvec(2,3) ! result of orbital magnetization calculation 116 117 ! Integer pointers 118 integer, allocatable :: atom_indsym(:,:,:) ! atom_indsym(4,nsym,natom) 119 ! this is data on how the symmetries map the atoms in the cell 120 ! see symatm.F90 for full description 121 integer, allocatable :: cgindex(:,:) ! cgindex(nkpt,nsppol) 122 ! for each k-point, stores the location 123 ! of the WF in the cg array 124 integer, allocatable :: cprjindex(:,:) ! cprjindex(nkpt,nsppol) 125 ! for each k-point, stores the location 126 ! of the cprj in the cprj array (used only 127 ! for PAW calculations) 128 integer, allocatable :: fkgindex(:) ! same as kgindex, but defined 129 ! for the FBZ and intended to use 130 ! with pwindf 131 integer, allocatable :: ikpt_dk(:,:,:) ! ikpt_dk(nkpt,2,3) 132 ! ikpt_dp(ikpt,ii,idir) = index of the 133 ! k-point at k+dk (ii=1) and k-dk (ii=2) 134 integer, allocatable :: indkk_f2ibz(:,:) ! indkk_f2ibz(1:dtorbmag%fnkpt,1:6) 135 ! information needed to fold a 136 ! k-point in the FBZ into the IBZ; 137 ! the second index (1:6) 138 ! is as described in listkk 139 integer, allocatable :: i2fbz(:) ! i2fbz(1:nkpt) gives index of IBZ 140 ! k-points in the FBZ k-point list 141 142 integer, allocatable :: kg(:,:) ! reduced (integer) coordinates of G vecs in basis sphere 143 144 integer, allocatable :: kgindex(:) ! kgind(nkpt) on current processor 145 ! kgindex(ikpt) = ikg 146 147 integer, allocatable :: lmn_size(:) ! lmn_size(ntypat) 148 integer, allocatable :: lmn2_size(:) ! lmn2_size(ntypat) 149 150 integer, allocatable :: nband_occ(:) ! nband_occ(nsppol) = actual number of occupied bands 151 ! can be different for spin up and down!!! 152 ! Real(dp) allocatables 153 154 real(dp), allocatable :: fkptns(:,:) ! fkptns(3,1:dtorbmag%fnkpt) k-points in FBZ 155 156 real(dp), allocatable :: zarot(:,:,:,:) 157 ! zarot(l_size_max,l_size_max,l_max,nsym) 158 ! Coeffs of the transformation of real spherical 159 ! harmonics under the symmetry operations. These are needed when the 160 ! cprj's need to be computed in the full BZ, that is, 161 ! in the PAW case with kptopt /= 3. 162 163 ! complex(dpc) allocatable 164 165 end type orbmag_type 166 167 168 ! Bound methods: 169 public :: destroy_orbmag 170 public :: initorbmag 171 public :: orbmag_ddk 172 public :: orbmag_wf 173 174 private :: make_onsite_l_k_n 175 private :: make_onsite_bm_k_n 176 private :: make_rhorij1_k_n 177 private :: make_S1trace_k_n 178 private :: orbmag_output 179 private :: make_eeig 180 private :: duqdu 181 private :: duq_she_qdu 182 private :: mpicomm_helper 183 private :: udsqdu 184 private :: covar_cprj 185 private :: duqhqdu 186 private :: udsdsu 187 private :: cpg_dij_cpb 188 private :: make_S1trace 189 private :: make_onsite_l 190 private :: make_onsite_l_k 191 private :: make_onsite_bm 192 private :: make_rhorij1 193 194 CONTAINS !========================================================================================