TABLE OF CONTENTS


ABINIT/m_paw_dfptnl [ Modules ]

[ Top ] [ Modules ]

NAME

  m_paw_dfptnl

FUNCTION

  This module contains several routines used to compute PAW contributions to a 3rd-order energy
   or 2nd-order PAW occupancies.

COPYRIGHT

 Copyright (C) 2018-2024 ABINIT group (LB)
 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

17 #if defined HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include "abi_common.h"
22 
23 MODULE m_paw_dfptnl
24 
25  use defs_basis
26  use m_abicore
27  use m_errors
28  use m_xmpi
29 
30  use m_pawang,     only : pawang_type
31  use m_pawrad,     only : pawrad_type,simp_gen
32  use m_pawtab,     only : pawtab_type
33  use m_paw_an,     only : paw_an_type
34  use m_pawrhoij,   only : pawrhoij_type
35  use m_pawcprj,    only : pawcprj_type
36  use m_paw_denpot, only : pawdensities
37  use m_paral_atom, only : get_my_atmtab, free_my_atmtab
38 
39  implicit none
40 
41  private
42 
43 !public procedures.
44  public :: paw_dfptnl_energy   ! Compute the XC PAW on-site contributions to a 3rd-order energy
45  public :: paw_dfptnl_xc       ! Compute a contribution of the 3rd-derivative of XC energy of ONE PAW sphere
46  public :: paw_dfptnl_accrhoij ! Accumulate the 2nd order PAW quantities rhoij^(2)
47 
48 CONTAINS  !========================================================================================

ABINIT/paw_dfptnl_accrhoij [ Functions ]

[ Top ] [ Functions ]

NAME

 paw_dfptnl_accrhoij

FUNCTION

 Accumulate the 2nd order PAW quantities rhoij^(2) (augmentation occupancies)
 This routine is similar to pawaccrhoij.F90 but is implemented independently
 in order to not overload the original routine.

INPUTS

  atindx(natom)=index table for atoms (sorted-->random), inverse of atindx.
  cplex: if 1, WFs (or 1st-order WFs) are REAL, if 2, COMPLEX
  cwaveprj0_pert1(natom,nspinor) = wave function at given n,k projected with non-local projectors:
                                  cwaveprj0%cp    =<p_i|
                                  cwaveprj0%dcp(1)=<p_i^(pert1)|Cnk>
  cwaveprj0_pert2(natom,nspinor) = wave function at given n,k projected with non-local projectors:
                                  cwaveprj0%cp    =<p_i|Cnk>
                                  cwaveprj0%dcp(1)=<p_i^(pert1)|Cnk>
  cwaveprj1_pert12(natom,nspinor)= 1st order wave function at given n,k projected with non-local projectors:
                                  cwaveprj1%cp    =<p_i|Cnk^(pert1)>
                                  cwaveprj1%dcp(1)=<p_i^(pert2)|Cnk^(pert1)>
  cwaveprj1_pert21(natom,nspinor)= 1st order wave function at given n,k projected with non-local projectors:
                                  cwaveprj1%cp    =<p_i|Cnk^(pert2)>
                                  cwaveprj1%dcp(1)=<p_i^(pert1)|Cnk^(pert2)>
  ipert1=index of the first perturbation
  ipert2=index of the second perturbation
  isppol=index of current spin component
  mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
  comm_atom=--optional-- MPI communicator over atoms
  my_natom=number of atoms treated by current processor
  natom=number of atoms in cell
  nspinor=number of spinorial components (on current proc)
  occ_k=occupation number for current band n,k
  wtk_k=weight assigned to current k-point

SIDE EFFECTS

  pawrhoij(natom) <type(pawrhoij_type)>= 2-nd order paw rhoij occupancies and related data
  On output, has been updated with the contribution of current n,k
        pawrhoij(:)%rhoij_(lmn2_size,nspden) (non symetrized)

SOURCE

505  subroutine paw_dfptnl_accrhoij(atindx,cplex,cwaveprj0_pert1,cwaveprj0_pert2,&
506 &                       cwaveprj1_pert12,cwaveprj1_pert21,ipert1,ipert2,isppol,my_natom,natom,&
507 &                       nspinor,occ_k,pawrhoij,wtk_k,&
508 &                       comm_atom,mpi_atmtab ) ! optional (parallelism)
509 
510 !Arguments ---------------------------------------------
511 !scalars
512  integer,intent(in) :: cplex,ipert1,ipert2,isppol,my_natom,natom,nspinor
513  integer,optional,intent(in) :: comm_atom
514  real(dp),intent(in) :: occ_k,wtk_k
515 !arrays
516  integer,intent(in) :: atindx(natom)
517  integer,optional,target,intent(in) :: mpi_atmtab(:)
518  type(pawcprj_type),intent(in) :: cwaveprj0_pert1(natom,nspinor),cwaveprj0_pert2(natom,nspinor)
519  type(pawcprj_type),intent(in) :: cwaveprj1_pert12(natom,nspinor),cwaveprj1_pert21(natom,nspinor)
520  type(pawrhoij_type),intent(inout) :: pawrhoij(my_natom)
521 
522 !Local variables ---------------------------------------
523 !scalars
524  integer :: cplex_rhoij,iatm,iatom,iatom1,ilmn,iplex,j0lmn,jlmn,klmn,klmn_im,klmn_re
525  integer :: my_comm_atom,ncpgr
526  logical :: compute_impart,compute_impart_cplex
527  logical :: my_atmtab_allocated,paral_atom
528  real(dp) :: ro11_im,ro11_re,weight
529  character(len=500) :: message
530 !arrays
531  integer,pointer :: my_atmtab(:)
532  real(dp) :: cpi0(2,nspinor),d1cpi0(2,nspinor),d2cpi0(2,nspinor)
533  real(dp) :: cpj0(2,nspinor),d1cpj0(2,nspinor),d2cpj0(2,nspinor)
534  real(dp) :: cpi1(2,nspinor),d2cpi1(2,nspinor)
535  real(dp) :: cpj1(2,nspinor),d2cpj1(2,nspinor)
536  real(dp) :: cpi2(2,nspinor),d1cpi2(2,nspinor)
537  real(dp) :: cpj2(2,nspinor),d1cpj2(2,nspinor)
538 
539 ! ***********************************************************************
540 
541  DBG_ENTER("COLL")
542 
543  if (my_natom==0) return
544 
545  ncpgr=1
546  if (ipert1<0.or.ipert1>natom+2.or.ipert2<0.or.ipert2>natom+2) then
547    message = 'paw_dfptnl_accrhoij: Necessary conditions on ipert1 or ipert2: 0<=ipert<=natom+2'
548    ABI_BUG(message)
549  end if
550  if (pawrhoij(1)%qphase/=1) then
551    message="paw_dfptnl_accrhoij not supposed to be called with q/=0!"
552    ABI_BUG(message)
553  end if
554 
555 !Set up parallelism over atoms
556  paral_atom=(present(comm_atom).and.(my_natom/=natom))
557  nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
558  my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
559  call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,&
560 & my_natom_ref=my_natom)
561 
562  weight=wtk_k*occ_k
563  if (pawrhoij(1)%nspden==2.and.pawrhoij(1)%nsppol==1.and.nspinor==1) weight=half*weight
564 
565 !!  ==================================================================
566 !!  === Accumulate (n,k) contribution to partial 2nd-order rhoij   ===
567 !!  ==================================================================
568 
569  compute_impart=(pawrhoij(1)%cplex_rhoij==2)
570  compute_impart_cplex=((pawrhoij(1)%cplex_rhoij==2).and.(cplex==2))
571 
572 ! NOT USED FOR PAWRHO21! => only for PAWRHO2 (full second derivative)
573 !!Accumulate :   < Psi^(pert1) | p_i^(0) > < p_j^(0) | Psi^(pert2) >
574 !!             + < Psi^(pert2) | p_i^(0) > < p_j^(0) | Psi^(pert1) >
575 ! if (nspinor==1) then
576 !   do iatom=1,my_natom
577 !     iatom1=iatom;if (paral_atom) iatom1=my_atmtab(iatom)
578 !     iatm=atindx(iatom1)
579 !     cplex_rhoij=pawrhoij(iatom)%cplex_rhoij
580 !     do jlmn=1,pawrhoij(iatom)%lmn_size
581 !       j0lmn=jlmn*(jlmn-1)/2
582 !       cpj1(1:2,1)=cwaveprj1_pert12(iatm,1)%cp(1:2,jlmn)   ! < p_j^(0) | Psi^(pert1) >
583 !       cpj2(1:2,1)=cwaveprj1_pert21(iatm,1)%cp(1:2,jlmn)   ! < p_j^(0) | Psi^(pert2) >
584 !       do ilmn=1,jlmn
585 !         klmn=j0lmn+ilmn
586 !         klmn_re=cplex_rhoij*(klmn-1)+1
587 !         cpi1(1:2,1)=cwaveprj1_pert12(iatm,1)%cp(1:2,ilmn) ! < p_i^(0) | Psi^(pert1) >
588 !         cpi2(1:2,1)=cwaveprj1_pert21(iatm,1)%cp(1:2,ilmn) ! < p_i^(0) | Psi^(pert2) >
589 !         ro11_re=zero
590 !         do iplex=1,cplex
591 !           ro11_re=ro11_re+cpi1(iplex,1)*cpj2(iplex,1)+cpj1(iplex,1)*cpi2(iplex,1)
592 !         end do
593 !         pawrhoij(iatom)%rhoij_(klmn_re,isppol)=pawrhoij(iatom)%rhoij_(klmn_re,isppol)+weight*ro11_re
594 !         if (compute_impart_cplex) then
595 !           klmn_im=klmn_re+1
596 !           ro11_im=        cpi1(1,1)*cpj2(2,1)-cpi1(2,1)*cpj2(1,1)
597 !           ro11_im=ro11_im+cpj1(1,1)*cpi2(2,1)-cpj1(2,1)*cpi2(1,1)
598 !           pawrhoij(iatom)%rhoij_(klmn_im,isppol)=pawrhoij(iatom)%rhoij_(klmn_im,isppol)+weight*ro11_im
599 !         end if
600 !       end do
601 !     end do
602 !   end do
603 ! else ! nspinor=2
604 !   ABI_BUG("paw_dfptnl_accrhoij is not implemented for nspinor=2")
605 ! end if
606 
607 !Accumulate :   < Psi^(pert1) | p_i^(pert2) > < p_j^(0)     | Psi^(0)     >
608 !             + < Psi^(pert1) | p_i^(0)     > < p_j^(pert2) | Psi^(0)     >
609 !             + < Psi^(0)     | p_i^(pert2) > < p_j^(0)     | Psi^(pert1) >
610 !             + < Psi^(0)     | p_i^(0)     > < p_j^(pert2) | Psi^(pert1) >
611  if (ipert2>0.and.ipert2<=natom) then
612    if (nspinor==1) then
613      do iatom=1,my_natom
614        iatom1=iatom;if (paral_atom) iatom1=my_atmtab(iatom)
615        iatm=atindx(iatom1)
616        if (iatom/=ipert2) cycle ! To move atom "ipert2" does not change projectors of other atoms
617        cplex_rhoij=pawrhoij(iatom)%cplex_rhoij
618        do jlmn=1,pawrhoij(iatom)%lmn_size
619          j0lmn=jlmn*(jlmn-1)/2
620          cpj0(1:2,1)  =cwaveprj0_pert2 (iatm,1)% cp(1:2,  jlmn)   ! < p_j^(0)     | Psi^(0)     >
621          d2cpj0(1:2,1)=cwaveprj0_pert2 (iatm,1)%dcp(1:2,1,jlmn)   ! < p_j^(pert2) | Psi^(0)     >
622          cpj1(1:2,1)  =cwaveprj1_pert12(iatm,1)% cp(1:2,  jlmn)   ! < p_j^(0)     | Psi^(pert1) >
623          d2cpj1(1:2,1)=cwaveprj1_pert12(iatm,1)%dcp(1:2,1,jlmn)   ! < p_j^(pert2) | Psi^(pert1) >
624          do ilmn=1,jlmn
625            klmn=j0lmn+ilmn
626            klmn_re=cplex_rhoij*(klmn-1)+1
627            cpi0(1:2,1)  =cwaveprj0_pert2 (iatm,1)% cp(1:2,  ilmn) ! < p_i^(0)     | Psi^(0)     >
628            d2cpi0(1:2,1)=cwaveprj0_pert2 (iatm,1)%dcp(1:2,1,ilmn) ! < p_i^(pert2) | Psi^(0)     >
629            cpi1(1:2,1)  =cwaveprj1_pert12(iatm,1)% cp(1:2,  ilmn) ! < p_i^(0)     | Psi^(pert1) >
630            d2cpi1(1:2,1)=cwaveprj1_pert12(iatm,1)%dcp(1:2,1,ilmn) ! < p_i^(pert2) | Psi^(pert1) >
631            ro11_re=zero
632            do iplex=1,cplex
633              ro11_re=ro11_re+d2cpi1(iplex,1)*  cpj0(iplex,1)
634              ro11_re=ro11_re+  cpi1(iplex,1)*d2cpj0(iplex,1)
635              ro11_re=ro11_re+d2cpi0(iplex,1)*  cpj1(iplex,1)
636              ro11_re=ro11_re+  cpi0(iplex,1)*d2cpj1(iplex,1)
637            end do
638            pawrhoij(iatom)%rhoij_(klmn_re,isppol)=pawrhoij(iatom)%rhoij_(klmn_re,isppol)+weight*ro11_re
639            if (compute_impart_cplex) then
640              klmn_im=klmn_re+1
641              ro11_im=        d2cpi1(1,1)*  cpj0(2,1)-d2cpi1(2,1)*  cpj0(1,1)
642              ro11_im=ro11_im+  cpi1(1,1)*d2cpj0(2,1)-  cpi1(2,1)*d2cpj0(1,1)
643              ro11_im=ro11_im+d2cpi0(1,1)*  cpj1(2,1)-d2cpi0(2,1)*  cpj1(1,1)
644              ro11_im=ro11_im+  cpi0(1,1)*d2cpj1(2,1)-  cpi0(2,1)*d2cpj1(1,1)
645              pawrhoij(iatom)%rhoij_(klmn_im,isppol)=pawrhoij(iatom)%rhoij_(klmn_im,isppol)+weight*ro11_im
646            end if
647          end do
648        end do
649      end do
650    else ! nspinor=2
651      ABI_BUG("paw_dfptnl_accrhoij is not implemented for nspinor=2")
652    end if
653  end if
654 
655 !Accumulate : < Psi^(pert2) | p_i^(pert1) > < p_j^(0)     | Psi^(0)     >
656 !           + < Psi^(pert2) | p_i^(0)     > < p_j^(pert1) | Psi^(0)     >
657 !           + < Psi^(0)     | p_i^(pert1) > < p_j^(0)     | Psi^(pert2) >
658 !           + < Psi^(0)     | p_i^(0) >     < p_j^(pert1) | Psi^(pert2) >
659  if (ipert1>0.and.ipert1<=natom) then
660    if (nspinor==1) then
661      do iatom=1,my_natom
662        iatom1=iatom;if (paral_atom) iatom1=my_atmtab(iatom)
663        iatm=atindx(iatom1)
664        cplex_rhoij=pawrhoij(iatom)%cplex_rhoij
665        if (iatom/=ipert1) cycle ! To move atom "ipert1" does not change projectors of other atoms
666        do jlmn=1,pawrhoij(iatom)%lmn_size
667          j0lmn=jlmn*(jlmn-1)/2
668          cpj0(1:2,1)  =cwaveprj0_pert1 (iatm,1)% cp(1:2,  jlmn)   ! < p_j^(0)     | Psi^(0)     >
669          d1cpj0(1:2,1)=cwaveprj0_pert1 (iatm,1)%dcp(1:2,1,jlmn)   ! < p_j^(pert1) | Psi^(0)     >
670          cpj2(1:2,1)  =cwaveprj1_pert21(iatm,1)% cp(1:2,  jlmn)   ! < p_j^(0)     | Psi^(pert2) >
671          d1cpj2(1:2,1)=cwaveprj1_pert21(iatm,1)%dcp(1:2,1,jlmn)   ! < p_j^(pert1) | Psi^(pert2) >
672          do ilmn=1,jlmn
673            klmn=j0lmn+ilmn
674            klmn_re=cplex_rhoij*(klmn-1)+1
675            cpi0(1:2,1)  =cwaveprj0_pert1 (iatm,1)% cp(1:2,  ilmn) ! < p_i^(0)     | Psi^(0)     >
676            d1cpi0(1:2,1)=cwaveprj0_pert1 (iatm,1)%dcp(1:2,1,ilmn) ! < p_i^(pert1) | Psi^(0)     >
677            cpi2(1:2,1)  =cwaveprj1_pert21(iatm,1)% cp(1:2,  ilmn) ! < p_i^(0)     | Psi^(pert2) >
678            d1cpi2(1:2,1)=cwaveprj1_pert21(iatm,1)%dcp(1:2,1,ilmn) ! < p_i^(pert1) | Psi^(pert2) >
679            ro11_re=zero
680            do iplex=1,cplex
681              ro11_re=ro11_re+d1cpi2(iplex,1)*  cpj0(iplex,1)
682              ro11_re=ro11_re+  cpi2(iplex,1)*d1cpj0(iplex,1)
683              ro11_re=ro11_re+d1cpi0(iplex,1)*  cpj2(iplex,1)
684              ro11_re=ro11_re+  cpi0(iplex,1)*d1cpj2(iplex,1)
685            end do
686            pawrhoij(iatom)%rhoij_(klmn_re,isppol)=pawrhoij(iatom)%rhoij_(klmn_re,isppol)+weight*ro11_re
687            if (compute_impart_cplex) then
688              klmn_im=klmn_re+1
689              ro11_im=        d1cpi2(1,1)*  cpj0(2,1)-d1cpi2(2,1)*  cpj0(1,1)
690              ro11_im=ro11_im+  cpi2(1,1)*d1cpj0(2,1)-  cpi2(2,1)*d1cpj0(1,1)
691              ro11_im=ro11_im+d1cpi0(1,1)*  cpj2(2,1)-d1cpi0(2,1)*  cpj2(1,1)
692              ro11_im=ro11_im+  cpi0(1,1)*d1cpj2(2,1)-  cpi0(2,1)*d1cpj2(1,1)
693              pawrhoij(iatom)%rhoij_(klmn_im,isppol)=pawrhoij(iatom)%rhoij_(klmn_im,isppol)+weight*ro11_im
694            end if
695          end do
696        end do
697      end do
698    else ! nspinor=2
699      message="paw_dfptnl_accrhoij is not implemented for nspinor=2!"
700      ABI_BUG(message)
701    end if
702  end if
703 !  End
704 
705 !Accumulate :   < Psi^(0) | p_i^(pert1) > < p_j^(pert2) | Psi^(0) >
706 !             + < Psi^(0) | p_i^(pert2) > < p_j^(pert1) | Psi^(0) >
707  if (ipert1>0.and.ipert1<=natom.and.ipert2>0.and.ipert2<=natom) then
708    if (nspinor==1) then
709      do iatom=1,my_natom
710        iatom1=iatom;if (paral_atom) iatom1=my_atmtab(iatom)
711        iatm=atindx(iatom1)
712        if (iatom/=ipert1.or.iatom/=ipert2) cycle ! To move atom "ipert" does not change projectors of other atoms
713        cplex_rhoij=pawrhoij(iatom)%cplex_rhoij
714        do jlmn=1,pawrhoij(iatom)%lmn_size
715          j0lmn=jlmn*(jlmn-1)/2
716          d1cpj0(1:2,1)=cwaveprj0_pert1(iatm,1)%dcp(1:2,1,jlmn)   ! < p_j^(pert1) | Psi^(0) >
717          d2cpj0(1:2,1)=cwaveprj0_pert2(iatm,1)%dcp(1:2,1,jlmn)   ! < p_j^(pert2) | Psi^(0) >
718          do ilmn=1,jlmn
719            klmn=j0lmn+ilmn
720            klmn_re=cplex_rhoij*(klmn-1)+1
721            d1cpi0(1:2,1)=cwaveprj0_pert1(iatm,1)%dcp(1:2,1,ilmn) ! < p_i^(pert1) | Psi^(0) >
722            d2cpi0(1:2,1)=cwaveprj0_pert2(iatm,1)%dcp(1:2,1,ilmn) ! < p_i^(pert2) | Psi^(0) >
723            ro11_re=zero
724            do iplex=1,cplex
725              ro11_re=ro11_re+d1cpi0(iplex,1)*d2cpj0(iplex,1)+d2cpi0(iplex,1)*d1cpj0(iplex,1)
726            end do
727            pawrhoij(iatom)%rhoij_(klmn_re,isppol)=pawrhoij(iatom)%rhoij_(klmn_re,isppol)+weight*ro11_re
728            if (compute_impart_cplex) then
729              klmn_im=klmn_re+1
730              ro11_im=        d1cpi0(1,1)*d2cpj0(2,1)-d1cpi0(2,1)*d2cpj0(1,1)
731              ro11_im=ro11_im+d2cpi0(1,1)*d1cpj0(2,1)-d2cpi0(2,1)*d1cpj0(1,1)
732              pawrhoij(iatom)%rhoij_(klmn_im,isppol)=pawrhoij(iatom)%rhoij_(klmn_im,isppol)+weight*ro11_im
733            end if
734          end do
735        end do
736      end do
737    else ! nspinor=2
738      message="paw_dfptnl_accrhoij is not implemented for nspinor=2!"
739      ABI_BUG(message)
740    end if
741  end if
742 
743 !Destroy atom table used for parallelism
744  call free_my_atmtab(my_atmtab,my_atmtab_allocated)
745 
746  DBG_EXIT("COLL")
747 
748 end subroutine paw_dfptnl_accrhoij

m_paw_dfptnl/paw_dfptnl_energy [ Functions ]

[ Top ] [ m_paw_dfptnl ] [ Functions ]

NAME

 paw_dfptnl_energy

FUNCTION

 Compute the XC PAW on-site contributions to a 3rd-order energy.
 It is equal to:
    E_onsite= \sum_at [ E_at(kxc,rho1,rho2,rho3) - E_at(tkxc,trho1,trho2,trho3) ]
 where E_at(...) is computed in paw_dfptnl_xc.F90.
 The atomic densities are computed from pawrhoij1,pawrhoij2 and pawrhoij3.
 This routine is similar to pawdfptenergy.F90 but is implemented independently
 in order to not overload the original routine.
 LDA ONLY - USE THE DENSITY OVER A WHOLE SPHERICAL GRID (r,theta,phi)

INPUTS

  ixc= choice of exchange-correlation scheme
  mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
  comm_atom=--optional-- MPI communicator over atoms
  my_natom=number of atoms treated by current processor
  natom=total number of atoms in cell
  ntypat=number of types of atoms in unit cell.
  paw_an0(natom) <type(paw_an_type)>=paw arrays for 0th-order quantities given on angular mesh
  paw_an1(natom) <type(paw_an_type)>=paw arrays for 1st-order quantities given on angular mesh
                                     This corresponds to (j1) perturbation
  pawang <type(pawang_type)>=paw angular mesh and related data
  pawprtvol=control print volume and debugging output for PAW
  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
  pawrhoij_1-2-3(natom) <type(pawrhoij_type)>= paw rhoij 1st-order occupancies
  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
  pawxcdev=Choice of XC development (0=no dev. (use of angular mesh) ; 1 or 2=dev. on moments)

OUTPUT

  d3exc= real and imaginary parts of the contribution to the third derivative of the total energy

SIDE EFFECTS

SOURCE

 91 subroutine paw_dfptnl_energy(d3exc,ixc,my_natom,natom,ntypat,&
 92 &                    paw_an0,pawang,pawprtvol,pawrad,&
 93 &                    pawrhoij_1,pawrhoij_2,pawrhoij_3,&
 94 &                    pawtab,pawxcdev,&
 95 &                    mpi_atmtab,comm_atom) ! optional arguments (parallelism)
 96 
 97 !Arguments ---------------------------------------------
 98 !scalars
 99  integer,intent(in) :: ixc,my_natom,natom,ntypat
100  integer,intent(in) :: pawprtvol,pawxcdev
101  integer,optional,intent(in) :: comm_atom
102  type(pawang_type),intent(in) :: pawang
103 !arrays
104  integer,optional,target,intent(in) :: mpi_atmtab(:)
105  real(dp),intent(out) :: d3exc(2)
106  type(paw_an_type),intent(in) :: paw_an0(my_natom)
107  type(pawrad_type),intent(in) :: pawrad(ntypat)
108  type(pawrhoij_type),intent(in) :: pawrhoij_1(my_natom)
109  type(pawrhoij_type),intent(in) :: pawrhoij_2(my_natom)
110  type(pawrhoij_type),intent(in) :: pawrhoij_3(my_natom)
111  type(pawtab_type),intent(in) :: pawtab(ntypat)
112 
113 !Local variables ---------------------------------------
114 !scalars
115  integer :: cplex_1,cplex_2,cplex_3,iatom,iatom_tot,itypat
116  integer :: lm_size_all,mesh_size,my_comm_atom,npts,nspden,nzlmopt
117  integer :: opt_compch,usecore,usetcore,usexcnhat
118  logical :: my_atmtab_allocated,paral_atom
119  real(dp) :: compch,d3exc1_iat(2)
120  character(len=500) :: msg
121 !arrays
122  integer,pointer :: my_atmtab(:)
123  logical,allocatable :: lmselect_1(:),lmselect_2(:),lmselect_3(:),lmselect_tmp(:)
124  real(dp),allocatable :: nhat1_1(:,:,:),rho1_1(:,:,:),trho1_1(:,:,:)
125  real(dp),allocatable :: nhat1_2(:,:,:),rho1_2(:,:,:),trho1_2(:,:,:)
126  real(dp),allocatable :: nhat1_3(:,:,:),rho1_3(:,:,:),trho1_3(:,:,:)
127 
128 ! *************************************************************************
129 
130  DBG_ENTER("COLL")
131 
132  nzlmopt = 0 ! compute all LM-moments of the density and use all LM-moments
133 
134  if (pawxcdev/=0) then
135    msg="paw_dfptnl_energy is not implemented for pawxcdev/=0"
136    ABI_BUG(msg)
137  end if
138  if (my_natom>0) then
139    if (pawrhoij_1(1)%qphase/=1.or.pawrhoij_2(1)%qphase/=1.or.pawrhoij_3(1)%qphase/=1) then
140      msg="paw_dfptnl_energy not supposed to be called with q/=0!"
141      ABI_BUG(msg)
142    end if
143  end if
144 
145 !Set up parallelism over atoms
146  paral_atom=(present(comm_atom).and.(my_natom/=natom))
147  nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
148  my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
149  call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom)
150 
151 !!Various inits
152  opt_compch=0; !optvxc=1;optexc=3
153  usecore=0;usetcore=0  ! This is true for phonons and Efield pert.
154  usexcnhat=maxval(pawtab(1:ntypat)%usexcnhat)
155 
156  npts=pawang%angl_size
157 
158  d3exc = zero
159 
160 !================ Loop on atomic sites =======================
161  do iatom=1,my_natom
162    iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom)
163 
164    itypat=pawrhoij_1(iatom)%itypat
165    mesh_size=pawtab(itypat)%mesh_size
166    nspden=pawrhoij_1(iatom)%nspden
167    cplex_1=pawrhoij_1(iatom)%cplex_rhoij
168    cplex_2=pawrhoij_2(iatom)%cplex_rhoij
169    cplex_3=pawrhoij_3(iatom)%cplex_rhoij
170    lm_size_all=paw_an0(iatom)%lm_size
171 
172    ABI_MALLOC(lmselect_tmp,(lm_size_all))
173    lmselect_tmp(:)=.true.
174 
175 !  Compute on-site 1st-order densities (pert1)
176    ABI_MALLOC(lmselect_1,(lm_size_all))
177    lmselect_1(:)=paw_an0(iatom)%lmselect(:)
178    ABI_MALLOC(rho1_1,(cplex_1*mesh_size,lm_size_all,nspden))
179    ABI_MALLOC(trho1_1,(cplex_1*mesh_size,lm_size_all,nspden))
180    ABI_MALLOC(nhat1_1,(cplex_1*mesh_size,lm_size_all,nspden*usexcnhat))
181    call pawdensities(compch,cplex_1,iatom_tot,lmselect_tmp,lmselect_1,&
182 &   lm_size_all,nhat1_1,nspden,nzlmopt,opt_compch,1-usexcnhat,-1,0,pawang,pawprtvol,&
183 &   pawrad(itypat),pawrhoij_1(iatom),pawtab(itypat),rho1_1,trho1_1)
184 !  Compute on-site 1st-order densities (pert2)
185    ABI_MALLOC(lmselect_2,(lm_size_all))
186    lmselect_2(:)=paw_an0(iatom)%lmselect(:)
187    ABI_MALLOC(rho1_2,(cplex_2*mesh_size,lm_size_all,nspden))
188    ABI_MALLOC(trho1_2,(cplex_2*mesh_size,lm_size_all,nspden))
189    ABI_MALLOC(nhat1_2,(cplex_2*mesh_size,lm_size_all,nspden*usexcnhat))
190    call pawdensities(compch,cplex_2,iatom_tot,lmselect_tmp,lmselect_2,&
191 &   lm_size_all,nhat1_2,nspden,nzlmopt,opt_compch,1-usexcnhat,-1,0,pawang,pawprtvol,&
192 &   pawrad(itypat),pawrhoij_2(iatom),pawtab(itypat),rho1_2,trho1_2)
193 !  Compute on-site 1st-order densities (pert3)
194    ABI_MALLOC(lmselect_3,(lm_size_all))
195    lmselect_3(:)=paw_an0(iatom)%lmselect(:)
196    ABI_MALLOC(rho1_3,(cplex_3*mesh_size,lm_size_all,nspden))
197    ABI_MALLOC(trho1_3,(cplex_3*mesh_size,lm_size_all,nspden))
198    ABI_MALLOC(nhat1_3,(cplex_3*mesh_size,lm_size_all,nspden*usexcnhat))
199    call pawdensities(compch,cplex_3,iatom_tot,lmselect_tmp,lmselect_3,&
200 &   lm_size_all,nhat1_3,nspden,nzlmopt,opt_compch,1-usexcnhat,-1,0,pawang,pawprtvol,&
201 &   pawrad(itypat),pawrhoij_3(iatom),pawtab(itypat),rho1_3,trho1_3)
202    ABI_FREE(lmselect_tmp)
203 
204    call paw_dfptnl_xc(cplex_1,cplex_2,cplex_3,d3exc1_iat,ixc,paw_an0(iatom)%k3xc1,lm_size_all,&
205 &   lmselect_1,lmselect_2,lmselect_3,nhat1_1,nhat1_2,nhat1_3,&
206 &   paw_an0(iatom)%nk3xc1,mesh_size,nspden,pawang,pawrad(itypat),&
207 &   rho1_1,rho1_2,rho1_3,0)
208    d3exc = d3exc + d3exc1_iat
209 
210    call paw_dfptnl_xc(cplex_1,cplex_2,cplex_3,d3exc1_iat,ixc,paw_an0(iatom)%k3xct1,lm_size_all,&
211 &   lmselect_1,lmselect_2,lmselect_3,nhat1_1,nhat1_2,nhat1_3,&
212 &   paw_an0(iatom)%nk3xc1,mesh_size,nspden,pawang,pawrad(itypat),&
213 &   trho1_1,trho1_2,trho1_3,usexcnhat)
214    d3exc = d3exc - d3exc1_iat
215 
216    ABI_FREE(lmselect_1)
217    ABI_FREE(lmselect_2)
218    ABI_FREE(lmselect_3)
219    ABI_FREE(nhat1_1)
220    ABI_FREE(nhat1_2)
221    ABI_FREE(nhat1_3)
222    ABI_FREE(rho1_1)
223    ABI_FREE(rho1_2)
224    ABI_FREE(rho1_3)
225    ABI_FREE(trho1_1)
226    ABI_FREE(trho1_2)
227    ABI_FREE(trho1_3)
228 
229 !  ================ End loop oon atomic sites =======================
230  end do
231 
232 !!Reduction in case of parallelism
233 ! if (paral_atom) then
234 !   call xmpi_sum(delta_energy,my_comm_atom,ierr)
235 ! end if
236 
237 !!Destroy atom table used for parallelism
238 ! call free_my_atmtab(my_atmtab,my_atmtab_allocated)
239 
240 ! call timab(567,2,tsec)
241 
242  DBG_EXIT("COLL")
243 
244 end subroutine paw_dfptnl_energy

m_paw_dfptnl/paw_dfptnl_xc [ Functions ]

[ Top ] [ m_paw_dfptnl ] [ Functions ]

NAME

 paw_dfptnl_xc

FUNCTION

 Compute a contribution of the third derivative of XC energy of ONE PAW sphere Om_a.
 It is equal to:
   E_at(kxc,rho1,rho2,rho3) = Int_{Om_a} dr kxc(r) * rho1(r) * rho2(r) * rho3(r)
 where kxc,rho1,rho2 and rho3 are inputs.
 This routine is similar to m_pawxc.F90:pawxc_dfpt(...) but is implemented independently
 in order to not overload the original routine.
 LDA ONLY - USE THE DENSITY OVER A WHOLE SPHERICAL GRID (r,theta,phi)

INPUTS

  cplex_1-2-3= if 1, 1st-order densities are REAL, if 2, COMPLEX
  d3exc1_iat=third-order derivative to compute
  ixc= choice of exchange-correlation scheme
  kxc(nrad,pawang%angl_size,nkxc)=GS xc kernel
  lm_size=size of density array rhor (see below)
  lmselect1-2-3(lm_size)=select the non-zero LM-moments of input density rhor1-2-3
  nhat1-2-3(cplex_den*nrad,lm_size,nspden)=first-order change of compensation density
                                        (total in 1st half and spin-up in 2nd half if nspden=2)
  nkxc=second dimension of the kxc array
  nrad=size of radial mesh for densities/potentials (might be different from pawrad%mesh_size)
  nspden=number of spin-density components
  option=0  compute both 2nd-order XC energy and 1st-order potential
         1  compute only 1st-order XC potential
         2  compute only 2nd-order XC energy, XC potential is temporary computed here
         3  compute only 2nd-order XC energy, XC potential is input in vxc1(:)
  pawang <type(pawang_type)>=paw angular mesh and related data
  pawrad <type(pawrad_type)>=paw radial mesh and related data
  rhor1-2-3(cplex_den*nrad,lm_size,nspden)=first-order change of density
  usexcnhat= 0 if compensation density does not have to be used
             1 if compensation density has to be used in d2Exc only

OUTPUT

  d3exc1_iat = E_at(kxc,rho1,rho2,rho3) (see FUNCTION above)

SIDE EFFECTS

SOURCE

291 subroutine paw_dfptnl_xc(cplex_1,cplex_2,cplex_3,d3exc1_iat,ixc,kxc,lm_size,lmselect1,lmselect2,lmselect3,&
292 &                 nhat1,nhat2,nhat3,nkxc,nrad,nspden,pawang,pawrad,rhor1,rhor2,rhor3,usexcnhat)
293 
294 !Arguments ------------------------------------
295 !scalars
296  integer,intent(in) :: cplex_1,cplex_2,cplex_3,ixc,lm_size,nkxc,nrad,nspden,usexcnhat
297  type(pawang_type),intent(in) :: pawang
298  type(pawrad_type),intent(in) :: pawrad
299 !arrays
300  logical,intent(in) :: lmselect1(lm_size),lmselect2(lm_size),lmselect3(lm_size)
301  real(dp),intent(out) :: d3exc1_iat(2)
302  real(dp),intent(in) :: kxc(nrad,pawang%angl_size,nkxc)
303  real(dp),intent(in) :: nhat1(cplex_1*nrad,lm_size,nspden*((usexcnhat+1)/2))
304  real(dp),intent(in) :: nhat2(cplex_2*nrad,lm_size,nspden*((usexcnhat+1)/2))
305  real(dp),intent(in) :: nhat3(cplex_3*nrad,lm_size,nspden*((usexcnhat+1)/2))
306  real(dp),intent(in) :: rhor1(cplex_1*nrad,lm_size,nspden)
307  real(dp),intent(in) :: rhor2(cplex_2*nrad,lm_size,nspden)
308  real(dp),intent(in) :: rhor3(cplex_3*nrad,lm_size,nspden)
309 
310 !Local variables-------------------------------
311 !scalars
312  integer :: ii,ilm,ipts,ispden,lm_size_eff,npts
313  real(dp) :: d3exc1_int,rho1u,rho1d,rho2u,rho2d,rho3u,rho3d
314  character(len=500) :: msg
315 !arrays
316 ! real(dp) :: tsec(2)
317  real(dp),allocatable :: ff(:),rho1arr(:,:),rho2arr(:,:),rho3arr(:,:)
318 
319 ! *************************************************************************
320 
321 !----------------------------------------------------------------------
322 !----- Initializations
323 !----------------------------------------------------------------------
324 
325  npts=pawang%angl_size
326  lm_size_eff=min(lm_size,pawang%ylm_size)
327 
328  d3exc1_iat(:) = zero
329 
330 !Special case: no XC applied
331  if (ixc==0) then
332    msg='Note that no xc is applied (ixc=0). Returning'
333    ABI_WARNING(msg)
334    return
335  end if
336 
337  ABI_MALLOC(rho1arr,(cplex_1*nrad,nspden))
338  ABI_MALLOC(rho2arr,(cplex_2*nrad,nspden))
339  ABI_MALLOC(rho3arr,(cplex_3*nrad,nspden))
340 
341 !Restriction : all cplex must be 1
342  if (cplex_1/=1.or.cplex_2/=1.or.cplex_3/=1) then
343    msg='All cplex must be one (for the moment...)'
344    ABI_BUG(msg)
345  end if
346 !Restriction : nspden must be 1
347 ! if (nkxc>1) then
348 !   msg='nkxc must be one (<=> nspden=1) (for the moment...)'
349 !   ABI_BUG(msg)
350 ! end if
351 
352  ABI_MALLOC(ff,(nrad))
353 
354 !!----------------------------------------------------------------------
355 !!----- Loop on the angular part and inits
356 !!----------------------------------------------------------------------
357 
358 !Do loop on the angular part (theta,phi)
359  do ipts=1,npts
360 
361 !  Copy the input 1st-order density for this (theta,phi) - PERT1
362    rho1arr(:,:)=zero
363    if (usexcnhat==0) then
364      do ispden=1,nspden
365        do ilm=1,lm_size_eff
366          if (lmselect1(ilm)) rho1arr(:,ispden)=rho1arr(:,ispden) &
367 &         +rhor1(:,ilm,ispden)*pawang%ylmr(ilm,ipts)
368        end do
369      end do
370    else
371      do ispden=1,nspden
372        do ilm=1,lm_size_eff
373          if (lmselect1(ilm)) rho1arr(:,ispden)=rho1arr(:,ispden) &
374 &         +(rhor1(:,ilm,ispden)+nhat1(:,ilm,ispden))*pawang%ylmr(ilm,ipts)
375        end do
376      end do
377    end if
378 
379 !  Copy the input 1st-order density for this (theta,phi) - PERT2
380    rho2arr(:,:)=zero
381    if (usexcnhat==0) then
382      do ispden=1,nspden
383        do ilm=1,lm_size_eff
384          if (lmselect2(ilm)) rho2arr(:,ispden)=rho2arr(:,ispden) &
385 &         +rhor2(:,ilm,ispden)*pawang%ylmr(ilm,ipts)
386        end do
387      end do
388    else
389      do ispden=1,nspden
390        do ilm=1,lm_size_eff
391          if (lmselect2(ilm)) rho2arr(:,ispden)=rho2arr(:,ispden) &
392 &         +(rhor2(:,ilm,ispden)+nhat2(:,ilm,ispden))*pawang%ylmr(ilm,ipts)
393        end do
394      end do
395    end if
396 
397 !  Copy the input 1st-order density for this (theta,phi) - PERT3
398    rho3arr(:,:)=zero
399    if (usexcnhat==0) then
400      do ispden=1,nspden
401        do ilm=1,lm_size_eff
402          if (lmselect3(ilm)) rho3arr(:,ispden)=rho3arr(:,ispden) &
403 &         +rhor3(:,ilm,ispden)*pawang%ylmr(ilm,ipts)
404        end do
405      end do
406    else
407      do ispden=1,nspden
408        do ilm=1,lm_size_eff
409          if (lmselect3(ilm)) rho3arr(:,ispden)=rho3arr(:,ispden) &
410 &         +(rhor3(:,ilm,ispden)+nhat3(:,ilm,ispden))*pawang%ylmr(ilm,ipts)
411        end do
412      end do
413    end if
414 
415 !  ----------------------------------------------------------------------
416 !  ----- Accumulate and store 3nd-order change of XC energy
417 !  ----------------------------------------------------------------------
418 
419    if (cplex_1==1.and.cplex_2==1.and.cplex_3==1) then ! all cplex are 1 :
420      if (nspden==1) then
421        ff(:)=kxc(:,ipts,1)*rho1arr(:,1)*rho2arr(:,1)*rho3arr(:,1)
422      else if (nspden==2) then
423        do ii=1,nrad
424          rho1u=rho1arr(ii,2)
425          rho1d=rho1arr(ii,1)-rho1arr(ii,2)
426          rho2u=rho2arr(ii,2)
427          rho2d=rho2arr(ii,1)-rho2arr(ii,2)
428          rho3u=rho3arr(ii,2)
429          rho3d=rho3arr(ii,1)-rho3arr(ii,2)
430          ff(ii)=&
431 !          uuu                                uud
432 &         kxc(ii,ipts,1)*rho1u*rho2u*rho3u + kxc(ii,ipts,2)*rho1u*rho2u*rho3d + &
433 !          udu                                udd
434 &         kxc(ii,ipts,2)*rho1u*rho2d*rho3u + kxc(ii,ipts,3)*rho1u*rho2d*rho3d + &
435 !          duu                                dud
436 &         kxc(ii,ipts,2)*rho1d*rho2u*rho3u + kxc(ii,ipts,3)*rho1d*rho2u*rho3d + &
437 !          ddu                                ddd
438 &         kxc(ii,ipts,3)*rho1d*rho2d*rho3u + kxc(ii,ipts,4)*rho1d*rho2d*rho3d
439        end do
440      end if
441    end if
442 
443    ff(1:nrad)=ff(1:nrad)*pawrad%rad(1:nrad)**2
444    call simp_gen(d3exc1_int,ff,pawrad)
445    d3exc1_iat(1)=d3exc1_iat(1)+d3exc1_int*pawang%angwgth(ipts)
446 
447 !  ----- End of the loop on npts (angular part)
448  end do
449 
450  d3exc1_iat = d3exc1_iat*four_pi
451 
452  ABI_FREE(ff)
453  ABI_FREE(rho1arr)
454  ABI_FREE(rho2arr)
455  ABI_FREE(rho3arr)
456 
457 end subroutine paw_dfptnl_xc