TABLE OF CONTENTS


ABINIT/dfpt_accrho [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_accrho

FUNCTION

 Response function calculation only:
  Accumulate contribution to first-order density due to current (k,band)
  Also accumulate zero-order potential part of the 2nd-order total energy (if needed)

INPUTS

  cplex=1 if 1st-order density is real, 2 if 1st-order density is complex
  cwave0(2,npw*nspinor)=GS wavefunction at k, in reciprocal space
  cwave1(2,npw1*nspinor)=1st-order wavefunction at k,q, in reciprocal space
  cwavef(2,npw1*nspinor)=1st-order wavefunction at k,q, in reciprocal space, without correction due to occupation change
  cwaveprj0(natom,nspinor*usecprj)= GS wave function at k projected with nl projectors
  cwaveprj1(natom,nspinor*usecprj)= 1st-order wave function at k,q projected with nl projectors
  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
  iband=index of current band
  idir=direction of the current perturbation
  ipert=type of the perturbation
  isppol=1 index of current spin component
  kptopt=option for the generation of k points
  mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
  comm_atom=--optional-- MPI communicator over atoms
  mpi_enreg=information about MPI parallelization
  natom=number of atoms in cell
  nband_k=number of bands at this k point for that spin polarization
  ncpgr=number of gradients stored in cprj array (cprj=<p_i|Cnk>)
  npw_k=number of planewaves in basis sphere at k
  npw1_k=number of planewaves in basis sphere at k+q
  nspinor=number of spinorial components of the wavefunctions
  occ_k(nband_k)=occupation number for each band (usually 2) for each k.
  option= 1: accumulate 1st-order density,
          2: accumulate 0-order potential part of the 2nd-order total energy
          3: accumulate both
  tim_fourwf= timing code for fourwf (5 from dfpt_vtowfk, 18 from dfpt_nstwf)
  wf_corrected=flag put to 1 if cwave1 is different from cwavef (if there is a contribution from occ. change)
  wtk_k=weight assigned to the k point.

OUTPUT

  ====== if option=2 or option=3 =====
  eloc0_k=zero-order local contribution to 2nd-order total energy for current band and k

SIDE EFFECTS

  ====== if option=1 or option=3 =====
    rhoaug1(cplex*n4,n5,n6,nvloc)= density in electrons/bohr**3,
    ==== if gs_hamkq%usepaw=1 =====
    pawrhoij1(natom) <type(pawrhoij_type)>= 1st-order paw rhoij occupancies and related data
                                            (cumulative, so input as well as output)

NOTES

  In this part of the treatment of one band, one has to
  perform Fourier transforms, and to treat separately the
  two spinorial components of the wavefunction.
  Was part of dfpt_vtowfk before.

SOURCE

597 subroutine dfpt_accrho(cplex,cwave0,cwave1,cwavef,cwaveprj0,cwaveprj1,&
598 &                  eloc0_k,gs_hamkq,iband,idir,ipert,isppol,kptopt,&
599 &                  mpi_enreg,natom,nband_k,ncpgr,npw_k,npw1_k,nspinor,occ_k,&
600 &                  option,pawrhoij1,rhoaug1,tim_fourwf,wf_corrected,&
601 &                  wtk_k,comm_atom,mpi_atmtab)
602 
603 !Arguments ------------------------------------
604 !scalars
605  integer,intent(in) :: cplex,iband,idir,ipert,isppol,kptopt,natom,nband_k
606  integer,intent(in) :: ncpgr,npw_k,npw1_k,nspinor,option,tim_fourwf,wf_corrected
607  integer,optional,intent(in) :: comm_atom
608  integer,optional,target,intent(in) :: mpi_atmtab(:)
609  real(dp),intent(in) :: wtk_k
610  real(dp),intent(out) :: eloc0_k
611  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
612  type(MPI_type),intent(in) :: mpi_enreg
613 !arrays
614  real(dp),intent(in),target :: cwave0(2,npw_k*nspinor),cwave1(2,npw1_k*nspinor),cwavef(2,npw1_k*nspinor)
615  real(dp),intent(in) :: occ_k(nband_k)
616  real(dp),intent(inout) :: rhoaug1(cplex*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,gs_hamkq%nvloc)
617  type(pawcprj_type),intent(in) :: cwaveprj0(natom,nspinor*gs_hamkq%usecprj)
618  type(pawcprj_type),intent(in) :: cwaveprj1(natom,nspinor*gs_hamkq%usepaw)
619  type(pawrhoij_type),intent(inout) :: pawrhoij1(:)
620 
621 !Local variables-------------------------------
622 !scalars
623  integer,parameter :: level=14
624  integer :: choice,cplex_cprj,i1,i2,i3,ispinor,my_comm_atom,my_natom,n1,n2,n3,option_rhoij
625  logical :: my_atmtab_allocated,paral_atom
626  logical :: use_timerev,use_zeromag
627  real(dp) :: im0,im1,re0,re1,valuer,diag,offdiag,weight
628  real(dp) :: im0_up,im1_up,re0_up,re1_up,im0_down,im1_down,re0_down,re1_down
629 !arrays
630  integer,pointer :: my_atmtab(:)
631  real(dp) :: dummy(2,1)
632  real(dp),allocatable :: rhoaug(:,:,:,:),wfraug(:,:,:,:),wfraug1(:,:,:,:)
633  real(dp),allocatable :: wfraug1_up(:,:,:,:),wfraug1_down(:,:,:,:)
634  real(dp),allocatable :: wfraug_up(:,:,:,:),wfraug_down(:,:,:,:)
635  real(dp),pointer :: cwavef_sp(:,:),cwavef_up(:,:),cwavef_down(:,:)
636  real(dp),pointer :: cwave0_up(:,:),cwave0_down(:,:),cwave1_up(:,:),cwave1_down(:,:)
637  real(dp),pointer :: vlocal(:,:,:,:)=>null()
638  type(pawcprj_type),allocatable :: cwaveprj_tmp(:,:)
639 
640 ! *********************************************************************
641  DBG_ENTER("COLL")
642 
643  if (option/=1.and.option/=2.and.option/=3) return
644 
645 !Initializations
646  ABI_MALLOC(rhoaug,(gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,gs_hamkq%nvloc))
647  n1=gs_hamkq%ngfft(1);n2=gs_hamkq%ngfft(2);n3=gs_hamkq%ngfft(3)
648  if (option==2.or.option==3) eloc0_k=zero
649  if (option==2.or.option==3) vlocal => gs_hamkq%vlocal
650 
651 !Loop on spinorial components
652 ! TODO : double loop on spinors for full rhoaug1 matrix if nspden =4
653  if (gs_hamkq%nvloc/=4) then  ! see later EB FR
654    ABI_MALLOC(wfraug1,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
655 
656    do ispinor=1,nspinor
657 
658 !  Part devoted to the accumulation of the 0-order potential part of the 2nd-order total energy
659 !  --------------------------------------------------------------------------------------------
660 
661 !  Fourier transform of cwavef. Here, rhoaug is a dummy variable.
662      if (wf_corrected==0.or.option==2.or.option==3) then
663        if (ispinor==1) then
664          cwavef_sp => cwavef(:,1:npw1_k)
665        else
666          cwavef_sp => cwavef(:,1+npw1_k:2*npw1_k)
667        end if
668        !make an inverse FFT from cwavef_sp to wfraug1
669        call fourwf(cplex,rhoaug,cwavef_sp,dummy,wfraug1,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
670 &       gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
671 &       gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
672 &       weight,weight,gpu_option=gs_hamkq%gpu_option)
673        nullify(cwavef_sp)
674      end if
675 
676 !  Compute contribution of this band to zero-order potential part of the 2nd-order total energy
677 !  NB: this is spinor diagonal
678      if (option==2.or.option==3) then
679        valuer=zero
680        do i3=1,n3
681          do i2=1,n2
682            do i1=1,n1
683              valuer=valuer+vlocal(i1,i2,i3,1)*(wfraug1(1,i1,i2,i3)**2+wfraug1(2,i1,i2,i3)**2)
684            end do
685          end do
686        end do
687 
688 !    Local potential energy of this band
689        eloc0_k=eloc0_k+two*valuer/dble(gs_hamkq%nfft)
690      end if ! option
691 
692 !  Part devoted to the accumulation of the 1st-order density
693 !  ---------------------------------------------------------
694      if (option==1.or.option==3) then
695 
696 !    Compute 1st-order WF in real space
697 !    One needs the Fourier transform of cwave1. However, only the one of
698 !    cwavef is available. If cwavef and cwave1 differs, this Fourier
699 !    transform must be computed. In both case the result is in wfraug1.
700        if (wf_corrected==1) then
701          if (ispinor==1) then
702            cwavef_sp => cwave1(:,1:npw1_k)
703          else
704            cwavef_sp => cwave1(:,1+npw1_k:2*npw1_k)
705          end if
706          call fourwf(cplex,rhoaug,cwavef_sp,dummy,wfraug1,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
707 &         gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
708 &         gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
709 &         weight,weight,gpu_option=gs_hamkq%gpu_option)
710          nullify(cwavef_sp)
711        end if
712 
713 !    Compute 0-order WF in real space
714 ! TODO: add loop over ispinor_prime here
715        ABI_MALLOC(wfraug,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
716        if (ispinor==1) then
717          cwavef_sp => cwave0(:,1:npw_k)
718        else
719          cwavef_sp => cwave0(:,1+npw_k:2*npw_k)
720        end if
721        call fourwf(1,rhoaug,cwavef_sp,dummy,wfraug,gs_hamkq%gbound_k,gs_hamkq%gbound_k,&
722 &       gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_k,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
723 &       gs_hamkq%npw_k,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
724 &       weight,weight,gpu_option=gs_hamkq%gpu_option)
725        nullify(cwavef_sp)
726 
727 !    The factor 2 is not the spin factor (see Eq.44 of PRB55,10337 (1997) [[cite:Gonze1997]])
728        weight=two*occ_k(iband)*wtk_k/gs_hamkq%ucvol
729 !    Accumulate 1st-order density
730        if (cplex==2) then
731          do i3=1,n3
732            do i2=1,n2
733              do i1=1,n1
734                re0=wfraug(1,i1,i2,i3)  ; im0=wfraug(2,i1,i2,i3)
735                re1=wfraug1(1,i1,i2,i3) ; im1=wfraug1(2,i1,i2,i3)
736 ! TODO: check which terms (ispinor ispinorp) enter a given element of rhoaug1
737                rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0*re1+im0*im1)
738                rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1)+weight*(re0*im1-im0*re1)
739              end do
740            end do
741          end do
742        else
743          do i3=1,n3
744            do i2=1,n2
745              do i1=1,n1
746                rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1) &
747 &               +weight*(wfraug(1,i1,i2,i3)*wfraug1(1,i1,i2,i3) &
748 &               +wfraug(2,i1,i2,i3)*wfraug1(2,i1,i2,i3))
749              end do
750            end do
751          end do
752        end if
753        ABI_FREE(wfraug)
754      end if ! option
755 
756    end do ! Loop on spinorial components if nspden=1 or 2
757 
758    ABI_FREE(wfraug1)
759  else ! nvloc = 4
760 ! The same lines of code are in 72_response/dfpt_mkrho.F90
761 ! TODO merge these lines in a single routine??!!
762    ABI_MALLOC(wfraug1_up,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
763    ABI_MALLOC(wfraug1_down,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
764 
765    wfraug1_up(:,:,:,:)=zero
766    wfraug1_down(:,:,:,:)=zero
767 
768 !  Part devoted to the accumulation of the 0-order potential part of the 2nd-order total energy
769 !  --------------------------------------------------------------------------------------------
770 
771 !  Fourier transform of cwavef. Here, rhoaug is a dummy variable.
772    if (wf_corrected==0.or.option==2.or.option==3) then
773      cwavef_up => cwavef(:,1:npw1_k) ! wfs up spin-polarized
774      call fourwf(cplex,rhoaug(:,:,:,1),cwavef_up,dummy,wfraug1_up,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
775 &     gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
776 &     gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
777 &     weight,weight,gpu_option=gs_hamkq%gpu_option)
778      nullify(cwavef_up)
779 
780      cwavef_down => cwavef(:,1+npw1_k:2*npw1_k) ! wfs down spin-polarized
781      call fourwf(cplex,rhoaug(:,:,:,1),cwavef_down,dummy,wfraug1_down,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
782 &     gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
783 &     gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
784 &     weight,weight,gpu_option=gs_hamkq%gpu_option)
785      nullify(cwavef_down)
786    end if
787    if (option==2.or.option==3) then
788      valuer=zero
789      diag=zero
790      offdiag=zero
791    ! EB FR 2nd term in Eq. 91 PRB52,1096 [[cite:Gonze1995]] for non-collinear magnetism
792      do i3=1,n3
793        do i2=1,n2
794          do i1=1,n1
795            diag=vlocal(i1,i2,i3,1)*(wfraug1_up(1,i1,i2,i3)**2+wfraug1_up(2,i1,i2,i3)**2)&
796 &           +vlocal(i1,i2,i3,2)*(wfraug1_down(1,i1,i2,i3)**2+wfraug1_down(2,i1,i2,i3)**2)
797            offdiag=(two*vlocal(i1,i2,i3,3)*((wfraug1_up(1,i1,i2,i3)*wfraug1_down(1,i1,i2,i3))+&
798 &           (wfraug1_up(2,i1,i2,i3)*wfraug1_down(2,i1,i2,i3))))+&
799 &           (two*vlocal(i1,i2,i3,4)*((-wfraug1_down(2,i1,i2,i3)*wfraug1_up(1,i1,i2,i3))+&
800 &           (wfraug1_down(1,i1,i2,i3)*wfraug1_up(2,i1,i2,i3))))
801            valuer=valuer+diag+offdiag
802          end do
803        end do
804      end do
805 !    Local potential energy of this band
806      eloc0_k=eloc0_k+two*valuer/dble(gs_hamkq%nfft)
807    end if ! option
808 
809 !  Part devoted to the accumulation of the 1st-order density
810 !  ---------------------------------------------------------
811 
812 ! first order
813 !
814    if (option==1.or.option==3) then
815 
816      !SPr: condition on wf_corrected not to do FFTs of the same Bloch functions
817      if (wf_corrected==1) then
818        cwave1_up => cwave1(:,1:npw1_k)
819        cwave1_down => cwave1(:,1+npw1_k:2*npw1_k)
820        wfraug1_up(:,:,:,:)=zero
821        wfraug1_down(:,:,:,:)=zero
822 
823        call fourwf(cplex,rhoaug(:,:,:,1),cwave1_up,dummy,wfraug1_up,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
824 &       gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
825 &       gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
826 &       weight,weight,gpu_option=gs_hamkq%gpu_option)
827        nullify(cwave1_up)
828 
829        call fourwf(cplex,rhoaug(:,:,:,1),cwave1_down,dummy,wfraug1_down,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
830 &       gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
831 &       gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
832 &       weight,weight,gpu_option=gs_hamkq%gpu_option)
833        nullify(cwave1_down)
834      end if
835 
836 
837 ! EB FR build spinorial wavefunctions
838 ! zero order
839      cwave0_up => cwave0(:,1:npw_k)
840      cwave0_down => cwave0(:,1+npw_k:2*npw_k)
841      ABI_MALLOC(wfraug_up,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
842      ABI_MALLOC(wfraug_down,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
843      wfraug_up(:,:,:,:)=zero
844      wfraug_down(:,:,:,:)=zero
845 !
846      !density components
847      !GS wfk Fourrier Tranform
848      ! EB FR in the fourwf calls rhoaug(:,:,:,2) is a dummy argument
849      call fourwf(1,rhoaug(:,:,:,2),cwave0_up,dummy,wfraug_up,gs_hamkq%gbound_k,gs_hamkq%gbound_k,&
850 &     gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_k,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
851 &     gs_hamkq%npw_k,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
852 &     weight,weight,gpu_option=gs_hamkq%gpu_option)
853      nullify(cwave0_up)
854      call fourwf(1,rhoaug(:,:,:,2),cwave0_down,dummy,wfraug_down,gs_hamkq%gbound_k,gs_hamkq%gbound_k,&
855 &     gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_k,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
856 &     gs_hamkq%npw_k,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
857 &     weight,weight,gpu_option=gs_hamkq%gpu_option)
858      nullify(cwave0_down)
859 !    Accumulate 1st-order density (x component)
860      re0_up=zero;im0_up=zero;re1_up=zero;im1_up=zero;re0_down=zero;im0_down=zero
861      re1_down=zero;im1_down=zero
862 !    The factor 2 is not the spin factor (see Eq.44 of PRB55,10337 (1997) [[cite:Gonze1997]])
863 !    SPr: the following treatment with factor=2 is ok for perturbations not breaking the
864 !         time reversal symmetry of the Hamiltonian (due to Kramer's degeneracy) hence
865 !         not applicable for magnetic field perturbation (for phonons with SOC, H^(0) has
866 !         time reversal symmetry though). The formulas below are rectified in dfpt_scfcv
867 !         in case of broken time-reversal upon reconstructing rhor1_pq and rhor1_mq.
868      weight=two*occ_k(iband)*wtk_k/gs_hamkq%ucvol
869      if (cplex==2) then
870        do i3=1,n3
871          do i2=1,n2
872            do i1=1,n1
873              re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
874              re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
875              re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
876              re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
877              !SPr: in case of +q/-q calculation, the factor will be corrected later from dfpt_scfcv level
878              !     along with the reconstruction of correct rhor1_{+q} and rhor1_{-q}
879              !     here, rhoaug1_{sigma,sigma'} = \sum_{n,k} u1_{sigma} u0*_{sigma'} independent of the sign of q
880              rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) !n_upup
881              rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1)+weight*(re0_up*im1_up-im0_up*re1_up)
882              rhoaug1(2*i1-1,i2,i3,4)=rhoaug1(2*i1-1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
883              rhoaug1(2*i1  ,i2,i3,4)=rhoaug1(2*i1  ,i2,i3,4)+weight*(re0_down*im1_down-im0_down*re1_down)
884 
885              rhoaug1(2*i1-1,i2,i3,2)=rhoaug1(2*i1-1,i2,i3,2)+weight*(re1_up*re0_down+im1_up*im0_down)& !Re[m1x]
886 &            +weight*(re1_down*re0_up+im1_down*im0_up)
887              rhoaug1(2*i1  ,i2,i3,2)=rhoaug1(2*i1  ,i2,i3,2)+weight*(-re1_up*im0_down+im1_up*re0_down)& !Im[m1x]
888 &            +weight*(-re1_down*im0_up+im1_down*re0_up)
889 
890              rhoaug1(2*i1-1,i2,i3,3)=rhoaug1(2*i1-1,i2,i3,3)+weight*(+re1_up*im0_down-im1_up*re0_down)& !Re[m1y]
891 &            +weight*(-re1_down*im0_up+im1_down*re0_up)
892              rhoaug1(2*i1  ,i2,i3,3)=rhoaug1(2*i1  ,i2,i3,3)+weight*(+re1_up*re0_down+im1_up*im0_down)& !Im[m1y]
893 &            +weight*(-re1_down*re0_up-im1_down*im0_up)
894            end do
895          end do
896        end do
897      else !cplex
898        re0_up=zero;im0_up=zero;re1_up=zero;im1_up=zero;re0_down=zero;im0_down=zero
899        re1_down=zero;im1_down=zero
900        do i3=1,n3
901          do i2=1,n2
902            do i1=1,n1
903              re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
904              re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
905              re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
906              re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
907 
908              rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) ! n_upup
909              rhoaug1(i1,i2,i3,4)=rhoaug1(i1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
910              rhoaug1(i1,i2,i3,2)=rhoaug1(i1,i2,i3,2)+weight*(re1_up*re0_down+re0_up*re1_down &
911 &             +im0_up*im1_down+im0_down*im1_up) !mx; the factor two is inside weight
912              rhoaug1(i1,i2,i3,3)=rhoaug1(i1,i2,i3,3)+weight*(re1_up*im0_down-im1_up*re0_down &
913 &             +re0_up*im1_down-im0_up*re1_down) !my; the factor two is inside weight
914            end do
915          end do
916        end do
917      end if !cplex
918 
919      ABI_FREE(wfraug_up)
920      ABI_FREE(wfraug_down)
921 
922    end if ! option
923 
924    ABI_FREE(wfraug1_up)
925    ABI_FREE(wfraug1_down)
926 
927  end if ! nvloc /= 4
928 
929  ABI_FREE(rhoaug)
930 
931 !Part devoted to the accumulation of the 1st-order occupation matrix in PAW case
932 ! TODO: parse for more nspden 4 dependencies on spinors
933 ! EB FR CHECK: to be modified for non-collinear?????
934 !-------------------------------------------------------------------------------
935 
936  if ((option==1.or.option==3).and.gs_hamkq%usepaw==1) then
937 
938 !  Set up parallelism over atoms
939    my_natom=natom; if(gs_hamkq%usepaw==1) my_natom=size(pawrhoij1)
940    paral_atom=(present(comm_atom).and.(my_natom/=natom))
941    my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
942    nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
943    call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom)
944 
945    cplex_cprj=2;if (gs_hamkq%istwf_k>1) cplex_cprj=1
946    option_rhoij=2
947    use_timerev=(kptopt>0.and.kptopt<3)
948    use_zeromag=.false.;if (my_natom>0) use_zeromag=(pawrhoij1(1)%nspden==4.and.gs_hamkq%nvloc==1)
949 
950    if (gs_hamkq%usecprj==1) then
951      call pawaccrhoij(gs_hamkq%atindx,cplex_cprj,cwaveprj0,cwaveprj1,ipert,isppol,my_natom,&
952 &     natom,nspinor,occ_k(iband),option_rhoij,pawrhoij1,use_timerev,use_zeromag,wtk_k,&
953 &     comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
954    else
955      ABI_MALLOC(cwaveprj_tmp,(natom,nspinor))
956      call pawcprj_alloc(cwaveprj_tmp,ncpgr,gs_hamkq%dimcprj)
957      choice=2
958      call getcprj(choice,0,cwave0,cwaveprj_tmp,&
959 &     gs_hamkq%ffnl_k,idir,gs_hamkq%indlmn,gs_hamkq%istwf_k,&
960 &     gs_hamkq%kg_k,gs_hamkq%kpg_k,gs_hamkq%kpt_k,gs_hamkq%lmnmax,&
961 &     gs_hamkq%mgfft,mpi_enreg,gs_hamkq%natom,gs_hamkq%nattyp,gs_hamkq%ngfft,&
962 &     gs_hamkq%nloalg,gs_hamkq%npw_k,gs_hamkq%nspinor,gs_hamkq%ntypat,gs_hamkq%phkxred,&
963 &     gs_hamkq%ph1d,gs_hamkq%ph3d_k,gs_hamkq%ucvol,gs_hamkq%useylm)
964      call pawaccrhoij(gs_hamkq%atindx,cplex_cprj,cwaveprj_tmp,cwaveprj1,ipert,isppol,my_natom,&
965 &     gs_hamkq%natom,nspinor,occ_k(iband),option_rhoij,pawrhoij1,use_timerev,use_zeromag,wtk_k, &
966 &     comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
967      call pawcprj_free(cwaveprj_tmp)
968      ABI_FREE(cwaveprj_tmp)
969    end if
970 
971  end if
972 
973  DBG_EXIT("COLL")
974 
975 end subroutine dfpt_accrho

ABINIT/dfpt_mkrho [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_mkrho

FUNCTION

 Compute RF charge density rho1(r) and rho1(G) in electrons/bohr**3
 from input RF and GS wavefunctions, band occupations, and k point weights.

INPUTS

  cg(2,mpw*nspinor*mband*mkmem*nsppol)=wf in G space
  cg1(2,mpw1*nspinor*mband*mk1mem*nsppol)=first-order wf in G space
  cplex=1 if rhor1 is real, 2 if rhor1 is complex
  gprimd(3,3)=dimensional reciprocal space primitive translations
  irrzon(nfft**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))=irreducible zone data
  istwfk_rbz(nkpt_rbz)=input option parameter that describes the storage of wfs
  kg(3,mpw*mkmem)=reduced planewave coordinates, GS data.
  kg1(3,mpw1*mkmem1)=reduced planewave coordinates, RF data.
  mband=maximum number of bands
  mgfft=maximum size of 1D FFTs
  mkmem=Number of k points treated by this node (GS data)
  mk1mem=Number of k points treated by this node (RF data)
  mpi_enreg=information about MPI parallelization
  mpw=maximum allowed value for npw (GS wfs)
  mpw1=maximum allowed value for npw1 (RF data)
  nband_rbz(nkpt_rbz*nsppol)=number of bands to be included in summation
   at each k point for each spin channel.
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT,
    see ~abinit/doc/variables/vargs.htm#ngfft
  nkpt_rbz=number of k points in the reduced Brillouin zone
  npwarr(nkpt_rbz)=number of planewaves and boundary planewaves at k points
  npwar1(nkpt_rbz)=number of planewaves and boundary planewaves at k+q points
  nspden=number of spin-density components
  nspinor=number of spinorial components of the wavefunctions
  nsppol=1 for unpolarized, 2 for spin-polarized
  nsym=number of symmetry elements in group (at least 1 for identity)
  occ_rbz(mband*nkpt_rbz*nsppol)=occupation numbers for each band
   (usually 2.0) at each k point of the reduced Brillouin zone
  phnons(2,nfft**(1-1/nsym),(nspden/nsppol)-3*(nspden/4))=nonsymmorphic translation phases
  rprimd(3,3)=dimensional real space primitive translations
  symafm(nsym)=(anti)ferromagnetic part of symmetry operations
  symrel(3,3,nsym)=symmetry matrices in real space (integers)
  ucvol=unit cell volume (Bohr**3)
  wtk_rbz(nkpt_rbz)=k point weights (they sum to 1.0).

OUTPUT

  rhog1(2,nfft)=total electron density in G space
  rhor1(cplex*nfft,nspden)=electron density in r space
   (if spin polarized, array contains total density in first half and
    spin-up density in second half)

SOURCE

110 subroutine dfpt_mkrho(cg,cg1,cplex,gprimd,irrzon,istwfk_rbz,&
111 & kg,kg1,mband,mband_mem,mgfft,mkmem,mk1mem,mpi_enreg,mpw,mpw1,nband_rbz,&
112 & nfft,ngfft,nkpt_rbz,npwarr,npwar1,nspden,nspinor,nsppol,nsym,&
113 & occ_rbz,phnons,rhog1,rhor1,rprimd,symafm,symrel,tnons,ucvol,wtk_rbz)
114 
115 !Arguments ------------------------------------
116 !scalars
117  integer,intent(in) :: cplex,mband,mband_mem,mgfft,mk1mem,mkmem,mpw,mpw1,nfft,nkpt_rbz
118  integer,intent(in) :: nspden,nspinor,nsppol,nsym
119  real(dp),intent(in) :: ucvol
120  type(MPI_type),intent(in) :: mpi_enreg
121 !arrays
122  integer,intent(in) :: irrzon(nfft**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))
123  integer,intent(in) :: istwfk_rbz(nkpt_rbz),kg(3,mpw*mkmem),kg1(3,mpw1*mk1mem)
124  integer,intent(in) :: nband_rbz(nkpt_rbz*nsppol),ngfft(18),npwar1(nkpt_rbz)
125  integer,intent(in) :: npwarr(nkpt_rbz),symafm(nsym),symrel(3,3,nsym)
126  real(dp),intent(in) :: cg(2,mpw*nspinor*mband_mem*mkmem*nsppol)
127  real(dp),intent(in) :: cg1(2,mpw1*nspinor*mband_mem*mk1mem*nsppol),gprimd(3,3)
128  real(dp),intent(in) :: occ_rbz(mband*nkpt_rbz*nsppol)
129  real(dp),intent(in) :: phnons(2,nfft**(1-1/nsym),(nspden/nsppol)-3*(nspden/4))
130  real(dp),intent(in) :: rprimd(3,3),tnons(3,nsym)
131  real(dp),intent(in) :: wtk_rbz(nkpt_rbz)
132  real(dp),intent(out) :: rhog1(2,nfft),rhor1(cplex*nfft,nspden)
133 
134 !Local variables-------------------------------
135 !scalars
136  integer,parameter :: tim_fourwf7=7,tim_rwwf15=15
137  integer,save :: nskip=0
138  integer :: bdtot_index,i1,i2,i3,iband,icg,icg1,ierr,ifft,ikg,ptr
139  integer :: iband_me
140  integer :: ikg1,ikpt,ispden,ispinor,isppol,istwf_k,ptr1,ptr2
141  integer :: me,n1,n2,n3,n4,n5,n6,nband_k,npw1_k
142  integer :: npw_k,spaceworld
143  real(dp) :: im0,im1,re0,re1,weight
144  real(dp) :: im0_up,im1_up,re0_up,re1_up,im0_down,im1_down,re0_down,re1_down
145  character(len=500) :: message
146 !arrays
147  integer,allocatable :: gbound(:,:),gbound1(:,:),kg1_k(:,:)
148  integer,allocatable :: kg_k(:,:)
149  real(dp) :: tsec(2)
150  real(dp),allocatable,target :: cwavef(:,:),cwavef1(:,:)
151  real(dp),allocatable :: dummy(:,:),rhoaug(:,:,:,:)
152  real(dp),allocatable :: rhoaug1(:,:,:,:),wfraug(:,:,:,:),wfraug1(:,:,:,:)
153  real(dp),allocatable :: wfraug1_up(:,:,:,:),wfraug1_down(:,:,:,:)
154  real(dp),allocatable :: wfraug_up(:,:,:,:),wfraug_down(:,:,:,:)
155  real(dp),allocatable :: cwave0_up(:,:),cwave0_down(:,:),cwave1_up(:,:),cwave1_down(:,:)
156 
157 ! *************************************************************************
158 
159 !DBG_ENTER("COLL")
160 
161  if(nspden==4)then
162 !  NOTE: see mkrho for the modifications needed for non-collinear treatment
163    write(message, '(3a)' )&
164     ' Linear-response calculations are under construction with nspden=4',ch10,&
165     ' Action: modify value of nspden in input file unless you know what you are doing.'
166    ABI_WARNING(message)
167  end if
168 
169 !Init spaceworld
170  spaceworld=mpi_enreg%comm_cell
171  me=mpi_enreg%me_kpt
172 
173 !zero the charge density array in real space
174 !$OMP PARALLEL DO
175  do ispden=1,nspden
176    do ifft=1,cplex*nfft
177      rhor1(ifft,ispden)=zero
178    end do
179  end do
180 
181 !start loop over spin and k points
182  bdtot_index=0; icg=0; icg1=0
183 
184  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
185  n4=ngfft(4); n5=ngfft(5); n6=ngfft(6) !n4,n5,n6 are FFT dimensions, modified to avoid cache trashing
186 
187 !Note that the dimensioning of cwavef and cwavef1 does not include nspinor
188  ABI_MALLOC(cwavef,(2,mpw))
189  ABI_MALLOC(cwavef1,(2,mpw1))
190 !Actually, rhoaug is not needed, except for strong dimensioning requirement
191  ABI_MALLOC(dummy,(2,1))
192  ABI_MALLOC(rhoaug,(n4,n5,n6,nspinor**2))
193  ABI_MALLOC(rhoaug1,(cplex*n4,n5,n6,nspinor**2))
194  ABI_MALLOC(wfraug,(2,n4,n5,n6))
195  ABI_MALLOC(wfraug1,(2,n4,n5,n6))
196 
197 ! EB FR Separate collinear and non-collinear magnetism
198  if (nspden /= 4) then  ! EB FR nspden check
199    do isppol=1,nsppol
200 
201      ikg=0; ikg1=0
202 
203      rhoaug1(:,:,:,:)=zero
204 
205      do ikpt=1,nkpt_rbz
206 
207        nband_k=nband_rbz(ikpt+(isppol-1)*nkpt_rbz)
208        istwf_k=istwfk_rbz(ikpt)
209        npw_k=npwarr(ikpt)
210        npw1_k=npwar1(ikpt)
211 
212        if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then
213          bdtot_index=bdtot_index+nband_k
214          cycle
215        end if
216 
217        ABI_MALLOC(gbound,(2*mgfft+8,2))
218        ABI_MALLOC(kg_k,(3,npw_k))
219        ABI_MALLOC(gbound1,(2*mgfft+8,2))
220        ABI_MALLOC(kg1_k,(3,npw1_k))
221 
222        kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
223        call sphereboundary(gbound,istwf_k,kg_k,mgfft,npw_k)
224 
225        kg1_k(:,1:npw1_k)=kg1(:,1+ikg1:npw1_k+ikg1)
226        call sphereboundary(gbound1,istwf_k,kg1_k,mgfft,npw1_k)
227 
228 !    Loop over bands to fft and square for rho(r)
229        iband_me = 0
230        do iband=1,nband_k
231          if (mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me) cycle
232          iband_me = iband_me + 1
233 !      Only treat occupied states
234          if (abs(occ_rbz(iband+bdtot_index))>tol8) then
235 !        Treat separately the two spinor components
236            do ispinor=1,nspinor
237 !          Obtain Fourier transform in fft box and accumulate the density
238              ptr = 1 + (ispinor-1)*npw_k + (iband_me-1)*npw_k*nspinor + icg
239              call cg_zcopy(npw_k, cg(1,ptr), cwavef)
240 
241 !      In these two calls, rhoaug, rhoaug1 and weight are dummy variables, and are not modified
242              call fourwf(1,rhoaug,cwavef,dummy,wfraug,gbound,gbound,&
243 &             istwf_k,kg_k,kg_k,mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,0,tim_fourwf7,weight,weight)
244 
245 ! TODO: here ispinor should be ispinorp to get full matrix and nspden 4
246              ptr = 1 + (ispinor-1)*npw1_k + (iband_me-1)*npw1_k*nspinor + icg1
247              call cg_zcopy(npw1_k, cg1(1,ptr), cwavef1)
248 
249              call fourwf(cplex,rhoaug1,cwavef1,dummy,wfraug1,gbound1,gbound1,&
250 &             istwf_k,kg1_k,kg1_k,mgfft,mpi_enreg,1,ngfft,npw1_k,1,n4,n5,n6,0,&
251 &             tim_fourwf7,weight,weight)
252 
253 !          Compute the weight, note that the factor 2 is
254 !          not the spin factor (see Eq.44 of PRB55,10337 (1997) [[cite:Gonze1997]])
255              weight=two*occ_rbz(iband+bdtot_index)*wtk_rbz(ikpt)/ucvol
256 
257 !          Accumulate density
258              if(cplex==2)then
259 !$OMP PARALLEL DO PRIVATE(im0,im1,re0,re1)
260                do i3=1,n3
261                  do i2=1,n2
262                    do i1=1,n1
263                      re0=wfraug(1,i1,i2,i3) ; im0=wfraug(2,i1,i2,i3)
264                      re1=wfraug1(1,i1,i2,i3); im1=wfraug1(2,i1,i2,i3)
265                      rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0*re1+im0*im1)
266                      rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1)+weight*(re0*im1-im0*re1)
267                    end do
268                  end do
269                end do
270              else
271 !$OMP PARALLEL DO
272                do i3=1,n3
273                  do i2=1,n2
274                    do i1=1,n1
275                      rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1)+&
276 &                     weight*( wfraug(1,i1,i2,i3)*wfraug1(1,i1,i2,i3) + wfraug(2,i1,i2,i3)*wfraug1(2,i1,i2,i3)  )
277                    end do
278                  end do
279                end do
280              end if ! cplex
281            end do ! ispinor
282          else !abs(occ_rbz(iband+bdtot_index))>tol8
283            nskip=nskip+1  ! if the state is not occupied. Accumulate the number of one-way 3D ffts skipped
284          end if ! abs(occ_rbz(iband+bdtot_index))>tol8
285 
286        end do ! iband
287 
288        ABI_FREE(gbound)
289        ABI_FREE(kg_k)
290        ABI_FREE(gbound1)
291        ABI_FREE(kg1_k)
292 
293        bdtot_index=bdtot_index+nband_k
294 
295 ! only increase indices for my bands on my proc
296        icg=icg+npw_k*mband_mem*nspinor
297        ikg=ikg+npw_k
298 
299        icg1=icg1+npw1_k*mband_mem*nspinor
300        ikg1=ikg1+npw1_k
301 
302      end do ! ikpt
303 
304      if (xmpi_paral==0) then !  Write the number of one-way 3D ffts skipped until now
305        write(message,'(a,i8)')' mkrho3 : number of one-way 3D ffts skipped in mkrho3 until now =',nskip
306        call wrtout(std_out,message,'PERS')
307      end if
308 
309 ! TODO: if n+magnetization basis is used for the density, need to rotate rhoaug1 to that now, before packing into rhor1
310 
311 !  Transfer density on augmented fft grid to normal fft grid in real space
312 !  Take also into account the spin, to place it correctly in rhor1.
313 !  Note the use of cplex
314      call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,rhor1,rhoaug1,1)
315 
316    end do ! loop over isppol spins
317 
318  else ! nspden = 4
319 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
320 ! Part added for the non collinear magnetism
321 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
322 ! The same lines of code are in 72_response/accrho3.F90
323 ! TODO: merge these lines in a single routine??!!
324 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
325 
326    ikg=0; ikg1=0
327 
328    rhoaug1(:,:,:,:)=zero
329 
330    do ikpt=1,nkpt_rbz
331 
332      nband_k=nband_rbz(ikpt)
333      istwf_k=istwfk_rbz(ikpt)
334      npw_k=npwarr(ikpt)
335      npw1_k=npwar1(ikpt)
336 
337      if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,1,me)) then
338        bdtot_index=bdtot_index+nband_k
339        cycle
340      end if
341 
342      ABI_MALLOC(gbound,(2*mgfft+8,2))
343      ABI_MALLOC(kg_k,(3,npw_k))
344      ABI_MALLOC(gbound1,(2*mgfft+8,2))
345      ABI_MALLOC(kg1_k,(3,npw1_k))
346 
347      kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
348      call sphereboundary(gbound,istwf_k,kg_k,mgfft,npw_k)
349 
350      kg1_k(:,1:npw1_k)=kg1(:,1+ikg1:npw1_k+ikg1)
351      call sphereboundary(gbound1,istwf_k,kg1_k,mgfft,npw1_k)
352 
353 !    Loop over bands to fft and square for rho(r)
354      iband_me = 0
355      do iband=1,nband_k
356 
357        if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,1,me)) cycle
358        iband_me = iband_me + 1
359 
360 !      Only treat occupied states
361        if (abs(occ_rbz(iband+bdtot_index))>tol8) then
362 
363 ! Build the four components of rho. We use only norm quantities and, so fourwf.
364 
365          ABI_MALLOC(wfraug_up,(2,n4,n5,n6))
366          ABI_MALLOC(wfraug_down,(2,n4,n5,n6))
367          ABI_MALLOC(wfraug1_up,(2,n4,n5,n6))
368          ABI_MALLOC(wfraug1_down,(2,n4,n5,n6))
369          ABI_MALLOC(cwave0_up,(2,mpw))
370          ABI_MALLOC(cwave0_down,(2,mpw))
371          ABI_MALLOC(cwave1_up,(2,mpw1))
372          ABI_MALLOC(cwave1_down,(2,mpw1))
373 
374 ! EB FR build spinorial wavefunctions
375 ! Obtain Fourier transform in fft box and accumulate the density
376 ! EB FR How do we manage the following lines for non-collinear????
377 ! zero order up and down spins
378          ptr1 = 1 + (iband_me-1)*npw_k*nspinor + icg
379          call cg_zcopy(npw_k, cg(1,ptr1), cwave0_up)
380          ptr2 = 1 + npw_k + (iband_me-1)*npw_k*nspinor + icg
381          call cg_zcopy(npw_k, cg(1,ptr2), cwave0_down)
382 ! first order up and down spins
383          ptr1 = 1 + (iband_me-1)*npw1_k*nspinor + icg1
384          call cg_zcopy(npw1_k, cg1(1,ptr1), cwave1_up)
385          ptr2 = 1 + npw1_k + (iband_me-1)*npw1_k*nspinor + icg1
386          call cg_zcopy(npw1_k, cg1(1,ptr2), cwave1_down)
387 
388 ! TODO: here ispinor should be ispinorp to get full matrix and nspden 4
389 !        ptr = 1 + (ispinor-1)*npw1_k + (iband_me-1)*npw1_k*nspinor + icg1
390 !        call cg_zcopy(npw1_k, cg1(1,ptr), cwavef1)
391 
392 ! EB FR lines to be managed (?????)
393 
394 ! zero order
395 !        cwave0_up => cwavef(:,1:npw_k)
396 !        cwave0_down => cwavef(:,1+npw_k:2*npw_k)
397 ! first order
398 !        cwave1_up => cwavef1(:,1:npw_k)
399 !        cwave1_down => cwavef1(:,1+npw_k:2*npw_k)
400 
401 !    The factor 2 is not the spin factor (see Eq.44 of PRB55,10337 (1997) ?? [[cite:Gonze1997]])
402          weight=two*occ_rbz(iband+bdtot_index)*wtk_rbz(ikpt)/ucvol
403 !density components
404 !GS wfk Fourrier Tranform
405 ! EB FR in the fourwf calls rhoaug(:,:,:,2) is a dummy argument
406          call fourwf(1,rhoaug(:,:,:,2),cwave0_up,dummy,wfraug_up,gbound,gbound,istwf_k,kg_k,kg_k,&
407 &         mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,&
408 &         0,tim_fourwf7,weight,weight)
409          call fourwf(1,rhoaug(:,:,:,2),cwave0_down,dummy,wfraug_down,gbound,gbound,istwf_k,kg_k,kg_k,&
410 &         mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,&
411 &         0,tim_fourwf7,weight,weight)
412  !1st order wfk Fourrier Transform
413          call fourwf(1,rhoaug1(:,:,:,2),cwave1_up,dummy,wfraug1_up,gbound,gbound,istwf_k,kg_k,kg_k,&
414 &         mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,&
415 &         0,tim_fourwf7,weight,weight)
416          call fourwf(1,rhoaug1(:,:,:,2),cwave1_down,dummy,wfraug1_down,gbound,gbound,istwf_k,kg_k,kg_k,&
417 &         mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,&
418 &         0,tim_fourwf7,weight,weight)
419 
420 !    Accumulate 1st-order density (x component)
421          if (cplex==2) then
422            do i3=1,n3
423              do i2=1,n2
424                do i1=1,n1
425                  re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
426                  re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
427                  re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
428                  re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
429                  rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) !n_upup
430                  rhoaug1(2*i1  ,i2,i3,1)=zero ! imag part of n_upup at k
431                  rhoaug1(2*i1-1,i2,i3,4)=rhoaug1(2*i1-1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
432                  rhoaug1(2*i1  ,i2,i3,4)=zero ! imag part of n_dndn at k
433                  rhoaug1(2*i1-1,i2,i3,2)=rhoaug1(2*i1-1,i2,i3,2)+weight*(re1_up*re0_down+re0_up*re1_down &
434 &                 +im0_up*im1_down+im0_down*im1_up) ! mx; the factor two is inside weight
435                  rhoaug1(2*i1  ,i2,i3,2)=zero ! imag part of mx
436                  rhoaug1(2*i1-1,i2,i3,3)=rhoaug1(2*i1-1,i2,i3,3)+weight*(re1_up*im0_down-im1_up*re0_down &
437 &                 +re0_up*im1_down-im0_up*re1_down) ! my; the factor two is inside weight
438                  rhoaug1(2*i1  ,i2,i3,3)=zero ! imag part of my at k
439                end do
440              end do
441            end do
442          else
443            do i3=1,n3
444              do i2=1,n2
445                do i1=1,n1
446                  re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
447                  re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
448                  re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
449                  re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
450                  rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) ! n_upup
451                  rhoaug1(i1,i2,i3,4)=rhoaug1(i1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
452                  rhoaug1(i1,i2,i3,2)=rhoaug1(i1,i2,i3,2)+weight*(re1_up*re0_down+re0_up*re1_down &
453 &                 +im0_up*im1_down+im0_down*im1_up) !mx; the factor two is inside weight
454                  rhoaug1(i1,i2,i3,3)=rhoaug1(i1,i2,i3,3)+weight*(re1_up*im0_down-im1_up*re0_down &
455 &                 +re0_up*im1_down-im0_up*re1_down) !my; the factor two is inside weight
456                end do
457              end do
458            end do
459          end if
460          ABI_FREE(wfraug_up)
461          ABI_FREE(wfraug_down)
462          ABI_FREE(wfraug1_up)
463          ABI_FREE(wfraug1_down)
464          ABI_FREE(cwave0_up)
465          ABI_FREE(cwave0_down)
466          ABI_FREE(cwave1_up)
467          ABI_FREE(cwave1_down)
468 
469        end if ! occupied states
470      end do ! End loop on iband
471 
472      ABI_FREE(gbound)
473      ABI_FREE(kg_k)
474      ABI_FREE(gbound1)
475      ABI_FREE(kg1_k)
476 
477      bdtot_index=bdtot_index+nband_k
478 
479 ! only increase indices for my bands on my proc
480        icg=icg+npw_k*mband_mem*nspinor
481        ikg=ikg+npw_k
482 
483        icg1=icg1+npw1_k*mband_mem*nspinor
484        ikg1=ikg1+npw1_k
485 
486      ikg=ikg+npw_k
487      ikg1=ikg1+npw1_k
488 
489    end do ! End loop on ikpt
490 
491 
492    if (xmpi_paral==0) then !  Write the number of one-way 3D ffts skipped until now
493      write(message,'(a,i8)')' dfpt_mkrho : number of one-way 3D ffts skipped in mkrho3 until now =',nskip
494      call wrtout(std_out,message,'PERS')
495    end if
496 
497 ! TODO: if n+magnetization basis is used for the density, need to rotate rhoaug1 to that now, before packing into rhor1
498 
499 !  Transfer density on augmented fft grid to normal fft grid in real space
500 !  Take also into account the spin, to place it correctly in rhor1.
501 !  Note the use of cplex
502    call fftpac(1,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,rhor1,rhoaug1,1)
503  end if ! nspden /= 4
504 
505 !if (xmpi_paral==1) then
506 !call timab(63,1,tsec)
507 !call wrtout(std_out,'dfpt_mkrho: loop on k-points and spins done in parallel','COLL')
508 !call xmpi_barrier(spaceworld)
509 !call timab(63,2,tsec)
510 !end if
511 
512  ABI_FREE(cwavef)
513  ABI_FREE(cwavef1)
514  ABI_FREE(dummy)
515  ABI_FREE(rhoaug)
516  ABI_FREE(rhoaug1)
517  ABI_FREE(wfraug)
518  ABI_FREE(wfraug1)
519 
520 !Recreate full rhor1 on all proc.
521 !TODO : check this sums correctly on bands as well as k
522  call timab(48,1,tsec)
523  call timab(71,1,tsec)
524  call xmpi_sum(rhor1,spaceworld,ierr)
525  call timab(71,2,tsec)
526  call timab(48,2,tsec)
527 
528  call symrhg(cplex,gprimd,irrzon,mpi_enreg,nfft,nfft,ngfft,nspden,nsppol,nsym,phnons,&
529              rhog1,rhor1,rprimd,symafm,symrel,tnons)
530 
531 !We now have both rho(r) and rho(G), symmetrized, and if nsppol=2
532 !we also have the spin-up density, symmetrized, in rhor1(:,2).
533 
534 !DBG_EXIT("COLL")
535 
536 end subroutine dfpt_mkrho

ABINIT/m_dfpt_mkrho [ Modules ]

[ Top ] [ Modules ]

NAME

  m_dfpt_mkrho

FUNCTION

 Compute RF charge density rho1(r) and rho1(G) in electrons/bohr**3

COPYRIGHT

  Copyright (C) 1998-2024 ABINIT group (DCA, XG, GMR, LSI, AR, MB, MT, SPr)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_dfpt_mkrho
23 
24  use defs_basis
25  use m_abicore
26  use m_errors
27  use m_cgtools
28  use m_xmpi
29 
30 
31  use defs_abitypes, only : MPI_type
32  use m_time,            only : timab
33  use m_io_tools,        only : get_unit, iomode_from_fname
34  use m_fftcore,         only : sphereboundary
35  use m_fft,             only : fftpac, fourwf
36  use m_spacepar,        only : symrhg
37  use m_hamiltonian,     only : gs_hamiltonian_type
38  use m_pawrhoij,        only : pawrhoij_type
39  use m_pawcprj,         only : pawcprj_type, pawcprj_alloc, pawcprj_free
40  use m_paw_occupancies, only : pawaccrhoij
41  use m_paral_atom,      only : get_my_atmtab
42  use m_mpinfo,          only : proc_distrb_cycle
43  use m_cgprj,           only : getcprj
44 
45  implicit none
46 
47  private