TABLE OF CONTENTS
- ABINIT/dfpt_vlocal
- ABINIT/dfpt_vlocaldq
- ABINIT/dfpt_vlocaldqdq
- ABINIT/dfpt_vmetdqdq
- ABINIT/m_mklocl
- ABINIT/mklocl
- ABINIT/mklocl_recipspace
- ABINIT/vlocalstr
ABINIT/dfpt_vlocal [ Functions ]
NAME
dfpt_vlocal
FUNCTION
Compute local part of 1st-order potential from the appropriate atomic pseudopotential with structure and derivative factor. In case of derivative with respect to k or electric (magnetic Zeeman) field perturbation, the 1st-order local potential vanishes.
INPUTS
atindx(natom)=index table for atoms (see gstate.f) cplex: if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX gmet(3,3)=reciprocal space metric (Bohr**-2) gsqcut=cutoff G**2 for included G s in fft box. idir=direction of atomic displacement (=1,2 or 3 : displacement of atom ipert along the 1st, 2nd or 3rd axis). ipert=number of the atom being displaced in the frozen-phonon mpi_enreg=information about MPI parallelization mqgrid=dimension of q grid for pseudopotentials natom=number of atoms in cell. nattyp(ntypat)=number of atoms of each type in cell. 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 ntypat=number of types of atoms in cell. n1,n2,n3=fft grid. ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. qgrid(mqgrid)=grid of q points from 0 to qmax. qphon(3)=wavevector of the phonon ucvol=unit cell volume (Bohr**3). vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom. xred(3,natom)=reduced atomic coordinates
OUTPUT
vpsp1(cplex*nfft)=first-order local crystal pseudopotential in real space (including the minus sign, forgotten in the paper non-linear..
SOURCE
793 subroutine dfpt_vlocal(atindx,cplex,gmet,gsqcut,idir,ipert,& 794 & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,& 795 & ntypat,n1,n2,n3,ph1d,qgrid,qphon,ucvol,vlspl,vpsp1,xred) 796 797 !Arguments ------------------------------- 798 !scalars 799 integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,ntypat 800 real(dp),intent(in) :: gsqcut,ucvol 801 type(MPI_type),intent(in) :: mpi_enreg 802 !arrays 803 integer,intent(in) :: atindx(natom),nattyp(ntypat),ngfft(18) 804 real(dp),intent(in) :: gmet(3,3),ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom) 805 real(dp),intent(in) :: qgrid(mqgrid),qphon(3),vlspl(mqgrid,2,ntypat) 806 real(dp),intent(in) :: xred(3,natom) 807 real(dp),intent(out) :: vpsp1(cplex*nfft) 808 809 !Local variables ------------------------- 810 !scalars 811 integer :: i1,i2,i3,ia1,iatom,id1,id2,id3,ig1,ig2,ig3,ii,ii1,im=2 812 integer :: itypat,jj,re=1 813 real(dp),parameter :: tolfix=1.000000001_dp 814 real(dp) :: aa,bb,cc,cutoff,dd,diff,dq,dq2div6,dqdiv6,dqm1,gmag,gq1 815 real(dp) :: gq2,gq3,gsquar,phqim,phqre 816 real(dp) :: qxred2pi,sfi,sfr,vion1,xnorm 817 logical :: qeq0 818 !arrays 819 integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:) 820 integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:) 821 real(dp) :: gq(3) 822 real(dp),allocatable :: work1(:,:) 823 824 ! ********************************************************************* 825 826 iatom=ipert 827 828 if(iatom==natom+1 .or. iatom==natom+2 .or. iatom==natom+10 .or. iatom==natom+11 .or. iatom==natom+5)then 829 830 ! (In case of d/dk or an electric field, or magnetic (Zeeman) field->[natom+5] SPr deb ) 831 vpsp1(1:cplex*nfft)=zero 832 833 else 834 835 ! (In case of a phonon perturbation) 836 ABI_MALLOC(work1,(2,nfft)) 837 work1(1:2,1:nfft)=0.0_dp 838 839 dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1) 840 dqm1=1.0_dp/dq 841 dqdiv6=dq/6.0_dp 842 dq2div6=dq**2/6.0_dp 843 cutoff=gsqcut*tolfix 844 id1=n1/2+2 845 id2=n2/2+2 846 id3=n3/2+2 847 848 ! Get the distrib associated with this fft_grid 849 call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local) 850 851 ! This is to allow q=0 852 qeq0=.false. 853 if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15)qeq0=.true. 854 855 ! Determination of the atom type 856 ia1=0 857 itypat=0 858 do ii=1,ntypat 859 ia1=ia1+nattyp(ii) 860 if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii 861 end do 862 863 ! Determination of phase qxred* 864 qxred2pi=2.0_dp*pi*(qphon(1)*xred(1,iatom)+ & 865 & qphon(2)*xred(2,iatom)+ & 866 & qphon(3)*xred(3,iatom) ) 867 phqre=cos(qxred2pi) 868 phqim=sin(qxred2pi) 869 ii=0 870 871 do i3=1,n3 872 ig3=i3-(i3/id3)*n3-1 873 gq3=dble(ig3)+qphon(3) 874 gq(3)=gq3 875 do i2=1,n2 876 if (fftn2_distrib(i2)==mpi_enreg%me_fft) then 877 ig2=i2-(i2/id2)*n2-1 878 gq2=dble(ig2)+qphon(2) 879 gq(2)=gq2 880 881 ! Note the lower limit of the next loop 882 ii1=1 883 if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then 884 ii1=2 885 ii=ii+1 886 end if 887 do i1=ii1,n1 888 ig1=i1-(i1/id1)*n1-1 889 gq1=dble(ig1)+qphon(1) 890 gq(1)=gq1 891 ii=ii+1 892 gsquar=gsq_vl3(gq1,gq2,gq3) 893 ! Skip G**2 outside cutoff: 894 if (gsquar<=cutoff) then 895 gmag=sqrt(gsquar) 896 897 ! Compute vion(G) for given type of atom 898 jj=1+int(gmag*dqm1) 899 diff=gmag-qgrid(jj) 900 901 ! Evaluate spline fit from q^2 V(q) to get V(q): 902 ! (p. 86 Numerical Recipes, Press et al; NOTE error in book for sign 903 ! of "aa" term in derivative; also see splfit routine. 904 ! This bug fixed here 27 Jan 1992.) 905 906 bb = diff*dqm1 907 aa = 1.0_dp-bb 908 cc = aa*(aa**2-1.0_dp)*dq2div6 909 dd = bb*(bb**2-1.0_dp)*dq2div6 910 vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) + & 911 & cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) ) & 912 & / gsquar 913 914 ! Phase G*xred (complex conjugate) * -i *2pi*(g+q)*vion 915 sfr=-phimag_vl3(ig1,ig2,ig3,iatom)*2.0_dp*pi*gq(idir)*vion1 916 sfi=-phre_vl3(ig1,ig2,ig3,iatom)*2.0_dp*pi*gq(idir)*vion1 917 918 ! Phase q*xred (complex conjugate) 919 work1(re,ii)=sfr*phqre+sfi*phqim 920 work1(im,ii)=-sfr*phqim+sfi*phqre 921 end if 922 923 end do 924 end if 925 end do 926 end do 927 928 ! Transform back to real space 929 call fourdp(cplex,work1,vpsp1,1,mpi_enreg,nfft,1,ngfft,0) 930 931 xnorm=1.0_dp/ucvol 932 vpsp1(1:cplex*nfft)=vpsp1(1:cplex*nfft)*xnorm 933 934 ABI_FREE(work1) 935 936 ! End the condition of non-electric-field 937 end if 938 939 contains 940 941 !Real and imaginary parts of phase. 942 function phr_vl3(x1,y1,x2,y2,x3,y3) 943 944 real(dp) :: phr_vl3 945 real(dp),intent(in) :: x1,x2,x3,y1,y2,y3 946 phr_vl3=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 947 end function phr_vl3 948 949 function phi_vl3(x1,y1,x2,y2,x3,y3) 950 951 real(dp) :: phi_vl3 952 real(dp),intent(in) :: x1,x2,x3,y1,y2,y3 953 phi_vl3=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 954 end function phi_vl3 955 956 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 957 function ph1_vl3(nri,ig1,ia) 958 959 real(dp) :: ph1_vl3 960 integer,intent(in) :: nri,ig1,ia 961 ph1_vl3=ph1d(nri,ig1+1+n1+(atindx(ia)-1)*(2*n1+1)) 962 end function ph1_vl3 963 964 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 965 function ph2_vl3(nri,ig2,ia) 966 967 real(dp) :: ph2_vl3 968 integer,intent(in) :: nri,ig2,ia 969 ph2_vl3=ph1d(nri,ig2+1+n2+(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1)) 970 end function ph2_vl3 971 972 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 973 function ph3_vl3(nri,ig3,ia) 974 975 real(dp) :: ph3_vl3 976 integer,intent(in) :: nri,ig3,ia 977 ph3_vl3=ph1d(nri,ig3+1+n3+(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)) 978 end function ph3_vl3 979 980 function phre_vl3(ig1,ig2,ig3,ia) 981 982 real(dp) :: phre_vl3 983 integer,intent(in) :: ig1,ig2,ig3,ia 984 phre_vl3=phr_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),& 985 & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia)) 986 end function phre_vl3 987 988 function phimag_vl3(ig1,ig2,ig3,ia) 989 990 real(dp) :: phimag_vl3 991 integer,intent(in) :: ig1,ig2,ig3,ia 992 phimag_vl3=phi_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),& 993 & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia)) 994 end function phimag_vl3 995 996 function gsq_vl3(g1,g2,g3) 997 998 real(dp) :: gsq_vl3 999 real(dp),intent(in) :: g1,g2,g3 ! Note that they are real, unlike in other similar function definitions 1000 !Define G^2 based on G space metric gmet. 1001 gsq_vl3=g1*g1*gmet(1,1)+g2*g2*gmet(2,2)+& 1002 & g3*g3*gmet(3,3)+2.0_dp*g1*g2*gmet(1,2)+& 1003 & 2.0_dp*g2*g3*gmet(2,3)+2.0_dp*g3*g1*gmet(3,1) 1004 end function gsq_vl3 1005 1006 end subroutine dfpt_vlocal
ABINIT/dfpt_vlocaldq [ Functions ]
NAME
dfpt_vlocaldq
FUNCTION
Compute q-gradient (at q=0) of the local part of 1st-order atomic displacement potential from the appropriate atomic pseudopotential with structure and derivative factor.
INPUTS
atindx(natom)=index table for atoms (see gstate.f) cplex: if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX gmet(3,3)=reciprocal space metric (Bohr**-2) gsqcut=cutoff G**2 for included G s in fft box. idir=direction of atomic displacement (=1,2 or 3 : displacement of atom ipert along the 1st, 2nd or 3rd axis). ipert=number of the atom being displaced in the frozen-phonon mpi_enreg=information about MPI parallelization mqgrid=dimension of q grid for pseudopotentials natom=number of atoms in cell. nattyp(ntypat)=number of atoms of each type in cell. nfft=(effective) number of FFT grid points (for this processor) ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/input_variables/vargs.htm#ngfft ntypat=number of types of atoms in cell. n1,n2,n3=fft grid. ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. qdir=direction of the q-gradient qgrid(mqgrid)=grid of q points from 0 to qmax. qphon(3)=wavevector of the phonon ucvol=unit cell volume (Bohr**3). vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
OUTPUT
vpsp1dq(cplex*nfft)=q-gradient (at q=0) of the first-order local crystal pseudopotential in real space (including the minus sign, forgotten in the paper non-linear..
NOTES
* IMPORTANT: the formalism followed in this routine assumes a phase factor for the perturbation that is different to the one used elsewhere in the code (See M.Stengel paper): here: e^{i q (R_l + \tau_{\kappa})} rest of ABINIT: e^{i q R_l} **A -i factor has been factorized out in all the contributions of the first q-gradient of the atomic displacement Hamiltonian. This is lately included in the matrix element calculation.
SOURCE
1391 subroutine dfpt_vlocaldq(atindx,cplex,gmet,gsqcut,idir,ipert,& 1392 & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,& 1393 & ntypat,n1,n2,n3,ph1d,qdir,qgrid,qphon,ucvol,vlspl,vpsp1dq) 1394 1395 implicit none 1396 1397 !Arguments ------------------------------- 1398 !scalars 1399 integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,ntypat 1400 integer,intent(in) :: qdir 1401 real(dp),intent(in) :: gsqcut,ucvol 1402 type(MPI_type),intent(in) :: mpi_enreg 1403 !arrays 1404 integer,intent(in) :: atindx(natom),nattyp(ntypat),ngfft(18) 1405 real(dp),intent(in) :: gmet(3,3),ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom) 1406 real(dp),intent(in) :: qgrid(mqgrid),qphon(3),vlspl(mqgrid,2,ntypat) 1407 real(dp),intent(out) :: vpsp1dq(cplex*nfft) 1408 1409 !Local variables ------------------------- 1410 !scalars 1411 integer :: i1,i2,i3,ia1,iatom,id1,id2,id3,ig1,ig2,ig3,ii,ii1,im=2 1412 integer :: itypat,re=1 1413 real(dp),parameter :: tolfix=1.000000001_dp 1414 real(dp) :: cutoff,gfact,gmag,gq1 1415 real(dp) :: gq2,gq3,gsquar 1416 real(dp) :: sfi,sfr,xnorm 1417 logical :: qeq0 1418 character(len=500) :: msg 1419 !arrays 1420 integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:) 1421 integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:) 1422 real(dp) :: gq(3),gvec(3),vion1(1),vion1dq(1) 1423 real(dp),allocatable :: work1(:,:) 1424 1425 ! ********************************************************************* 1426 1427 iatom=ipert 1428 1429 if(iatom==natom+1 .or. iatom==natom+2 .or. iatom==natom+10 .or. iatom==natom+11 .or. iatom==natom+5)then 1430 1431 ! (In case of d/dk or an electric field, or magnetic (Zeeman) field->[natom+5] SPr deb ) 1432 vpsp1dq(1:cplex*nfft)=zero 1433 1434 else 1435 1436 ! (In case of a phonon perturbation) 1437 ABI_MALLOC(work1,(2,nfft)) 1438 work1(1:2,1:nfft)=0.0_dp 1439 1440 cutoff=gsqcut*tolfix 1441 id1=n1/2+2 1442 id2=n2/2+2 1443 id3=n3/2+2 1444 1445 ! Get the distrib associated with this fft_grid 1446 call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local) 1447 1448 ! This is to allow q=0 1449 qeq0=.false. 1450 if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15) then 1451 qeq0=.true. 1452 else 1453 msg='This routine cannot be used for q/=0' 1454 ABI_BUG(msg) 1455 end if 1456 1457 ! Determination of the atom type 1458 ia1=0 1459 itypat=0 1460 do ii=1,ntypat 1461 ia1=ia1+nattyp(ii) 1462 if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii 1463 end do 1464 1465 ii=0 1466 1467 do i3=1,n3 1468 ig3=i3-(i3/id3)*n3-1 1469 gq3=dble(ig3)+qphon(3) 1470 gq(3)=gq3 1471 do i2=1,n2 1472 if (fftn2_distrib(i2)==mpi_enreg%me_fft) then 1473 ig2=i2-(i2/id2)*n2-1 1474 gq2=dble(ig2)+qphon(2) 1475 gq(2)=gq2 1476 1477 ! Note the lower limit of the next loop 1478 ii1=1 1479 if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then 1480 ii1=2 1481 ii=ii+1 1482 end if 1483 do i1=ii1,n1 1484 ig1=i1-(i1/id1)*n1-1 1485 gq1=dble(ig1)+qphon(1) 1486 gq(1)=gq1 1487 ii=ii+1 1488 gsquar=gsq_vl3(gq1,gq2,gq3) 1489 ! Skip G**2 outside cutoff: 1490 if (gsquar<=cutoff) then 1491 gmag=sqrt(gsquar) 1492 1493 ! Evaluate spline fit to get V(q) and V(q)': 1494 call splfit(qgrid,vion1dq,vlspl(:,:,itypat),1,(/gmag/),vion1,mqgrid,1) 1495 1496 vion1=vion1/gsquar 1497 vion1dq=(vion1dq-2.0_dp*gmag*vion1)/gsquar 1498 1499 gvec=(/ig1,ig2,ig3/) 1500 gfact=dot_product(gmet(qdir,:),gvec(:))/gmag 1501 1502 ! Phase G*xred (complex conjugate) *2*pi*(g_idir)*vion1dq*gfact 1503 sfr=phre_vl3(ig1,ig2,ig3,iatom)*two_pi*gq(idir)*vion1dq(1)*gfact 1504 sfi=-phimag_vl3(ig1,ig2,ig3,iatom)*two_pi*gq(idir)*vion1dq(1)*gfact 1505 ! Phase G*xred (complex conjugate) *2*pi*(\delta_{idir,qdir})*vion1 1506 if (idir==qdir) then 1507 sfr=sfr + phre_vl3(ig1,ig2,ig3,iatom)*two_pi*vion1(1) 1508 sfi=sfi - phimag_vl3(ig1,ig2,ig3,iatom)*two_pi*vion1(1) 1509 end if 1510 1511 work1(re,ii)=sfr 1512 work1(im,ii)=sfi 1513 end if 1514 1515 end do 1516 end if 1517 end do 1518 end do 1519 1520 ! Transform back to real space 1521 call fourdp(cplex,work1,vpsp1dq,1,mpi_enreg,nfft,1,ngfft,0) 1522 1523 xnorm=1.0_dp/ucvol 1524 vpsp1dq(1:cplex*nfft)=vpsp1dq(1:cplex*nfft)*xnorm 1525 1526 ABI_FREE(work1) 1527 1528 ! End the condition of non-electric-field 1529 end if 1530 1531 contains 1532 1533 !Real and imaginary parts of phase. 1534 function phr_vl3(x1,y1,x2,y2,x3,y3) 1535 real(dp) :: phr_vl3 1536 real(dp),intent(in) :: x1,x2,x3,y1,y2,y3 1537 phr_vl3=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 1538 end function phr_vl3 1539 1540 function phi_vl3(x1,y1,x2,y2,x3,y3) 1541 real(dp) :: phi_vl3 1542 real(dp),intent(in) :: x1,x2,x3,y1,y2,y3 1543 phi_vl3=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 1544 end function phi_vl3 1545 1546 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 1547 function ph1_vl3(nri,ig1,ia) 1548 real(dp) :: ph1_vl3 1549 integer,intent(in) :: nri,ig1,ia 1550 ph1_vl3=ph1d(nri,ig1+1+n1+(atindx(ia)-1)*(2*n1+1)) 1551 end function ph1_vl3 1552 1553 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 1554 function ph2_vl3(nri,ig2,ia) 1555 real(dp) :: ph2_vl3 1556 integer,intent(in) :: nri,ig2,ia 1557 ph2_vl3=ph1d(nri,ig2+1+n2+(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1)) 1558 end function ph2_vl3 1559 1560 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 1561 function ph3_vl3(nri,ig3,ia) 1562 real(dp) :: ph3_vl3 1563 integer,intent(in) :: nri,ig3,ia 1564 ph3_vl3=ph1d(nri,ig3+1+n3+(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)) 1565 end function ph3_vl3 1566 1567 function phre_vl3(ig1,ig2,ig3,ia) 1568 real(dp) :: phre_vl3 1569 integer,intent(in) :: ig1,ig2,ig3,ia 1570 phre_vl3=phr_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),& 1571 & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia)) 1572 end function phre_vl3 1573 1574 function phimag_vl3(ig1,ig2,ig3,ia) 1575 real(dp) :: phimag_vl3 1576 integer,intent(in) :: ig1,ig2,ig3,ia 1577 phimag_vl3=phi_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),& 1578 & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia)) 1579 end function phimag_vl3 1580 1581 function gsq_vl3(g1,g2,g3) 1582 real(dp) :: gsq_vl3 1583 real(dp),intent(in) :: g1,g2,g3 ! Note that they are real, unlike in other similar function definitions 1584 !Define G^2 based on G space metric gmet. 1585 gsq_vl3=g1*g1*gmet(1,1)+g2*g2*gmet(2,2)+& 1586 & g3*g3*gmet(3,3)+2.0_dp*g1*g2*gmet(1,2)+& 1587 & 2.0_dp*g2*g3*gmet(2,3)+2.0_dp*g3*g1*gmet(3,1) 1588 end function gsq_vl3 1589 1590 end subroutine dfpt_vlocaldq
ABINIT/dfpt_vlocaldqdq [ Functions ]
NAME
dfpt_vlocaldqdq
FUNCTION
Compute 2nd q-gradient (at q=0) of the local part of 1st-order atomic displacement potential from the appropriate atomic pseudopotential with structure and derivative factor.
INPUTS
atindx(natom)=index table for atoms (see gstate.f) cplex: if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX gmet(3,3)=reciprocal space metric (Bohr**-2) gsqcut=cutoff G**2 for included G s in fft box. idir=direction of atomic displacement (=1,2 or 3 : displacement of atom ipert along the 1st, 2nd or 3rd axis). ipert=number of the atom being displaced in the frozen-phonon mpi_enreg=information about MPI parallelization mqgrid=dimension of q grid for pseudopotentials natom=number of atoms in cell. nattyp(ntypat)=number of atoms of each type in cell. nfft=(effective) number of FFT grid points (for this processor) ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/input_variables/vargs.htm#ngfft ntypat=number of types of atoms in cell. n1,n2,n3=fft grid. ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. qdir1=direction of the first q-gradient qdir2=direction of the second q-gradient qgrid(mqgrid)=grid of q points from 0 to qmax. qphon(3)=wavevector of the phonon ucvol=unit cell volume (Bohr**3). vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
OUTPUT
vpsp1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the first-order local crystal pseudopotential in real space
NOTES
* IMPORTANT: the formalism followed in this routine assumes a phase factor for the perturbation that is different to the one used elsewhere in the code (See M.Stengel paper): here: e^{i q (R_l + \tau_{\kappa})} rest of ABINIT: e^{i q R_l} **A -i factor has been factorized out in all the contributions of the second q-gradient of the atomic displacement Hamiltonian. This is lately included in the whole frozen contribution to the q-gradient of the 2nd order energy wrt an atomic displacement and a strain: \Delta E^{\tau_{\kappa\alpha}^* (\beta)}_{m\kvec,\gamma\delta}
SOURCE
1648 subroutine dfpt_vlocaldqdq(atindx,cplex,gmet,gsqcut,idir,ipert,& 1649 & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,& 1650 & ntypat,n1,n2,n3,ph1d,qdir1,qdir2,qgrid,qphon,ucvol,vlspl,vpsp1dqdq) 1651 1652 implicit none 1653 1654 !Arguments ------------------------------- 1655 !scalars 1656 integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,ntypat 1657 integer,intent(in) :: qdir1,qdir2 1658 real(dp),intent(in) :: gsqcut,ucvol 1659 type(MPI_type),intent(in) :: mpi_enreg 1660 !arrays 1661 integer,intent(in) :: atindx(natom),nattyp(ntypat),ngfft(18) 1662 real(dp),intent(in) :: gmet(3,3),ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom) 1663 real(dp),intent(in) :: qgrid(mqgrid),qphon(3),vlspl(mqgrid,2,ntypat) 1664 real(dp),intent(out) :: vpsp1dqdq(cplex*nfft) 1665 1666 !Local variables ------------------------- 1667 !scalars 1668 integer :: alpha, delta, gamma 1669 integer :: i1,i2,i3,ia1,iatom,id1,id2,id3,ig1,ig2,ig3,ii,ii1,im=2 1670 integer :: itypat,re=1 1671 real(dp),parameter :: tolfix=1.000000001_dp 1672 real(dp) :: cutoff,delad,delag,gfact,gfact1,gfact2,gmag,gq1 1673 real(dp) :: gq2,gq3,gsquar 1674 real(dp) :: sfi,sfr,term1,term2,xnorm 1675 logical :: qeq0 1676 character(len=500) :: msg 1677 !arrays 1678 integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:) 1679 integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:) 1680 real(dp) :: gq(3),gvec(3),vion1(1),vion1dq(1),vion1dqdq(1) 1681 real(dp),allocatable :: work1(:,:) 1682 1683 ! ********************************************************************* 1684 1685 iatom=ipert 1686 1687 if(iatom==natom+1 .or. iatom==natom+2 .or. iatom==natom+10 .or. iatom==natom+11 .or. iatom==natom+5)then 1688 1689 ! (In case of d/dk or an electric field, or magnetic (Zeeman) field->[natom+5] SPr deb ) 1690 vpsp1dqdq(1:cplex*nfft)=zero 1691 1692 else 1693 1694 alpha=idir; delta=qdir2; gamma=qdir1 1695 1696 !Kronecker deltas 1697 delad=0.0_dp; delag=0.0_dp 1698 if (alpha==delta) delad=1.0_dp 1699 if (alpha==gamma) delag=1.0_dp 1700 1701 ! (In case of a phonon perturbation) 1702 ABI_MALLOC(work1,(2,nfft)) 1703 work1(1:2,1:nfft)=0.0_dp 1704 1705 cutoff=gsqcut*tolfix 1706 id1=n1/2+2 1707 id2=n2/2+2 1708 id3=n3/2+2 1709 1710 ! Get the distrib associated with this fft_grid 1711 call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local) 1712 1713 ! This is to allow q=0 1714 qeq0=.false. 1715 if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15) then 1716 qeq0=.true. 1717 else 1718 msg='This routine cannot be used for q/=0' 1719 ABI_BUG(msg) 1720 end if 1721 1722 ! Determination of the atom type 1723 ia1=0 1724 itypat=0 1725 do ii=1,ntypat 1726 ia1=ia1+nattyp(ii) 1727 if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii 1728 end do 1729 1730 ii=0 1731 1732 do i3=1,n3 1733 ig3=i3-(i3/id3)*n3-1 1734 gq3=dble(ig3)+qphon(3) 1735 gq(3)=gq3 1736 do i2=1,n2 1737 if (fftn2_distrib(i2)==mpi_enreg%me_fft) then 1738 ig2=i2-(i2/id2)*n2-1 1739 gq2=dble(ig2)+qphon(2) 1740 gq(2)=gq2 1741 1742 ! Note the lower limit of the next loop 1743 ii1=1 1744 if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then 1745 ii1=2 1746 ii=ii+1 1747 end if 1748 do i1=ii1,n1 1749 ig1=i1-(i1/id1)*n1-1 1750 gq1=dble(ig1)+qphon(1) 1751 gq(1)=gq1 1752 ii=ii+1 1753 gsquar=gsq_vl3(gq1,gq2,gq3) 1754 ! Skip G**2 outside cutoff: 1755 if (gsquar<=cutoff) then 1756 gmag=sqrt(gsquar) 1757 1758 ! Evaluate spline fit to get first V(q) and V(q)' and later V(q)'': 1759 call splfit(qgrid,vion1dq,vlspl(:,:,itypat),1,(/gmag/),vion1,mqgrid,1) 1760 vion1=vion1/gsquar 1761 vion1dq=(vion1dq-2.0_dp*gmag*vion1)/gsquar 1762 1763 call splfit(qgrid,vion1dqdq,vlspl(:,:,itypat),2,(/gmag/),vion1,mqgrid,1) 1764 vion1dqdq=(vion1dqdq-4.0_dp*gmag*vion1dq-2.0_dp*vion1)/gsquar 1765 1766 gvec=(/ig1,ig2,ig3/) 1767 gfact1=dot_product(gmet(gamma,:),gvec(:)) 1768 gfact2=dot_product(gmet(delta,:),gvec(:)) 1769 gfact=gvec(alpha)*gfact1*gfact2/gsquar 1770 1771 term1=delag*gfact2+delad*gfact1+gvec(alpha)*gmet(gamma,delta) 1772 term1=term1-gfact 1773 term1=term1*vion1dq(1)/gmag 1774 1775 term2=vion1dqdq(1)*gfact 1776 1777 ! structure factors 1778 sfr=phre_vl3(ig1,ig2,ig3,iatom) 1779 sfi=-phimag_vl3(ig1,ig2,ig3,iatom) 1780 1781 ! Multiply structure factor times vion derivatives: 1782 work1(re,ii)=sfr*(term1+term2)*two_pi 1783 work1(im,ii)=sfi*(term1+term2)*two_pi 1784 1785 end if 1786 1787 end do 1788 end if 1789 end do 1790 end do 1791 1792 ! Transform back to real space 1793 call fourdp(cplex,work1,vpsp1dqdq,1,mpi_enreg,nfft,1,ngfft,0) 1794 1795 xnorm=1.0_dp/ucvol 1796 vpsp1dqdq(1:cplex*nfft)=vpsp1dqdq(1:cplex*nfft)*xnorm 1797 1798 ABI_FREE(work1) 1799 1800 ! End the condition of non-electric-field 1801 end if 1802 1803 contains 1804 1805 !Real and imaginary parts of phase. 1806 function phr_vl3(x1,y1,x2,y2,x3,y3) 1807 real(dp) :: phr_vl3 1808 real(dp),intent(in) :: x1,x2,x3,y1,y2,y3 1809 phr_vl3=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 1810 end function phr_vl3 1811 1812 function phi_vl3(x1,y1,x2,y2,x3,y3) 1813 real(dp) :: phi_vl3 1814 real(dp),intent(in) :: x1,x2,x3,y1,y2,y3 1815 phi_vl3=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 1816 end function phi_vl3 1817 1818 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 1819 function ph1_vl3(nri,ig1,ia) 1820 real(dp) :: ph1_vl3 1821 integer,intent(in) :: nri,ig1,ia 1822 ph1_vl3=ph1d(nri,ig1+1+n1+(atindx(ia)-1)*(2*n1+1)) 1823 end function ph1_vl3 1824 1825 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 1826 function ph2_vl3(nri,ig2,ia) 1827 real(dp) :: ph2_vl3 1828 integer,intent(in) :: nri,ig2,ia 1829 ph2_vl3=ph1d(nri,ig2+1+n2+(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1)) 1830 end function ph2_vl3 1831 1832 ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !! 1833 function ph3_vl3(nri,ig3,ia) 1834 real(dp) :: ph3_vl3 1835 integer,intent(in) :: nri,ig3,ia 1836 ph3_vl3=ph1d(nri,ig3+1+n3+(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)) 1837 end function ph3_vl3 1838 1839 function phre_vl3(ig1,ig2,ig3,ia) 1840 real(dp) :: phre_vl3 1841 integer,intent(in) :: ig1,ig2,ig3,ia 1842 phre_vl3=phr_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),& 1843 & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia)) 1844 end function phre_vl3 1845 1846 function phimag_vl3(ig1,ig2,ig3,ia) 1847 real(dp) :: phimag_vl3 1848 integer,intent(in) :: ig1,ig2,ig3,ia 1849 phimag_vl3=phi_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),& 1850 & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia)) 1851 end function phimag_vl3 1852 1853 function gsq_vl3(g1,g2,g3) 1854 real(dp) :: gsq_vl3 1855 real(dp),intent(in) :: g1,g2,g3 ! Note that they are real, unlike in other similar function definitions 1856 !Define G^2 based on G space metric gmet. 1857 gsq_vl3=g1*g1*gmet(1,1)+g2*g2*gmet(2,2)+& 1858 & g3*g3*gmet(3,3)+2.0_dp*g1*g2*gmet(1,2)+& 1859 & 2.0_dp*g2*g3*gmet(2,3)+2.0_dp*g3*g1*gmet(3,1) 1860 end function gsq_vl3 1861 1862 end subroutine dfpt_vlocaldqdq
ABINIT/dfpt_vmetdqdq [ Functions ]
NAME
dfpt_vmetdqdq
FUNCTION
Compute second q-gradient (at q=0) of the local part of 1st-order metric potential from the appropriate atomic pseudopotential with structure and derivative factor. Additionaly, compute the second q-gradient (at q=0) of the Hartree and XC (if GGA) potentials of the metric perturbation. Cartesian coordinates are employed to define the direction of the metric perturbation and the two q-gradients.
INPUTS
cplex: if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX gmet(3,3)=reciprocal space metric (Bohr**-2) gsqcut=cutoff G**2 for included G s in fft box. gprimd(3,3)=dimensional reciprocal space primitive translations idir= strain perturbation direction ipert=number of the atom being displaced in the frozen-phonon kxc(nfft,nkxc)=exchange and correlation kernel mpi_enreg=information about MPI parallelization mqgrid=dimension of q grid for pseudopotentials natom=number of atoms in cell. nattyp(ntypat)=number of atoms of each type in cell. nfft=(effective) number of FFT grid points (for this processor) ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/input_variables/vargs.htm#ngfft nkxc=second dimension of the kxc array. If /=0, the XC kernel must be computed. nspden=number of spin-density components ntypat=number of types of atoms in cell. n1,n2,n3=fft grid. opthartdqdq= if 1 activates the calculation 2nd q-gradient of the Hartree potential ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. qdir=direction of the q-gradient qgrid(mqgrid)=grid of q points from 0 to qmax. qphon(3)=wavevector of the phonon rhog(2,nfft)=array for Fourier transform of GS electron density rhor(nfftf,nspden)=array for GS electron density in electrons/bohr**3. ucvol=unit cell volume (Bohr**3). vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
OUTPUT
vhart1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the GS density Hartree potential from the metric perturbation vpsp1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the first-order metric local crystal pseudopotential in real space vxc1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the GS density XC potential from the metric perturbation (only finite if GGA)
NOTES
** IMPORTANT: the formalism followed in this routine assumes a phase factor for the perturbation that is different to the one used elsewhere in the code (See M.Stengel paper): here: e^{i q (R_l + \tau_{\kappa})} rest of ABINIT: e^{i q R_l} **Since the 2nd derivative w.r.t q-vector is calculated along cartesian directions, the 1/twopi**2 factor (that in the rest of the code is applied in the reduced to cartesian derivative conversion process) is here explicictly included in the formulas. **Notice that idir=1-9, in contrast to the strain perturbation (idir=1-6), because this term is not symmetric w.r.t permutations of the two strain indices. **A -i factor has been factorized out in all the contributions of the second q-gradient of the metric Hamiltonian. This is lately included in the contribution of the corresponing term (T4) to the flexoelectric tensor in dfpt_flexoout.F90
SOURCE
1937 subroutine dfpt_vmetdqdq(cplex,gmet,gprimd,gsqcut,idir,ipert,& 1938 & kxc,mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,& 1939 & ntypat,n1,n2,n3,nkxc,nspden,opthartdqdq,ph1d,qdir,qgrid,qphon,rhog,rhor,& 1940 & ucvol,vlspl,vhart1dqdq,vpsp1dqdq,vxc1dqdq) 1941 1942 implicit none 1943 1944 !Arguments ------------------------------- 1945 !scalars 1946 integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,nkxc,ntypat 1947 integer,intent(in) :: nspden,opthartdqdq,qdir 1948 real(dp),intent(in) :: gsqcut,ucvol 1949 type(MPI_type),intent(in) :: mpi_enreg 1950 !arrays 1951 integer,intent(in) :: nattyp(ntypat),ngfft(18) 1952 real(dp),intent(in) :: gmet(3,3),gprimd(3,3), kxc(nfft,nkxc) 1953 real(dp),intent(in) :: ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom) 1954 real(dp),intent(in) :: qgrid(mqgrid),qphon(3),rhog(2,nfft),rhor(cplex*nfft,nspden) 1955 real(dp),intent(in) :: vlspl(mqgrid,2,ntypat) 1956 real(dp),intent(out) :: vhart1dqdq(cplex*nfft),vpsp1dqdq(cplex*nfft) 1957 real(dp),intent(out) :: vxc1dqdq(cplex*nfft) 1958 1959 !Local variables ------------------------- 1960 !scalars 1961 integer :: beta, delta, gamma 1962 integer :: ia,i1,i2,i3,ia1,ia2,id1,id2,id3,ig1,ig2,ig3,ii,ii1 1963 integer :: itypat,jj 1964 integer, parameter :: im=2, re=1 1965 real(dp),parameter :: tolfix=1.000000001_dp 1966 real(dp) :: cutoff,delbd,delbg,deldg,gfact,gmag,gq1 1967 real(dp) :: gq2,gq3,gsquar,pisqrinv 1968 real(dp) :: sfi,sfr,term1,term2,tmpre,tmpim,uogsquar,work1re,xnorm 1969 logical :: qeq0 1970 character(len=500) :: msg 1971 !arrays 1972 integer,save :: idx(18)=(/1,1,2,2,3,3,3,2,3,1,2,1,2,3,1,3,1,2/) 1973 integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:) 1974 integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:) 1975 real(dp) :: gq(3),gqc(3),vion1(1),vion1dq(1),vion1dqdq(1) 1976 real(dp),allocatable :: work1(:,:) 1977 1978 ! ********************************************************************* 1979 1980 1981 if(ipert/=natom+3 .and. ipert/=natom+4)then 1982 1983 vpsp1dqdq(1:cplex*nfft)=zero 1984 1985 else 1986 1987 beta=idx(2*idir-1); delta=idx(2*idir); gamma=qdir 1988 1989 !Kronecker deltas 1990 delbd=0.0_dp; delbg=0.0_dp; deldg=0.0_dp 1991 if (beta==delta) delbd=1.0_dp 1992 if (beta==gamma) delbg=1.0_dp 1993 if (delta==gamma) deldg=1.0_dp 1994 1995 ABI_MALLOC(work1,(2,nfft)) 1996 work1(1:2,1:nfft)=0.0_dp 1997 1998 cutoff=gsqcut*tolfix 1999 id1=n1/2+2 2000 id2=n2/2+2 2001 id3=n3/2+2 2002 2003 !Get the distrib associated with this fft_grid 2004 call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local) 2005 2006 ! This is to allow q=0 2007 qeq0=.false. 2008 if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15) then 2009 qeq0=.true. 2010 else 2011 msg='This routine cannot be used for q/=0' 2012 ABI_BUG(msg) 2013 end if 2014 2015 ia1=1 2016 do itypat=1,ntypat 2017 ! ia1,ia2 sets range of loop over atoms: 2018 ia2=ia1+nattyp(itypat)-1 2019 2020 ii=0 2021 2022 do i3=1,n3 2023 ig3=i3-(i3/id3)*n3-1 2024 gq3=dble(ig3)+qphon(3) 2025 gq(3)=gq3 2026 do i2=1,n2 2027 if (fftn2_distrib(i2)==mpi_enreg%me_fft) then 2028 ig2=i2-(i2/id2)*n2-1 2029 gq2=dble(ig2)+qphon(2) 2030 gq(2)=gq2 2031 2032 ! Note the lower limit of the next loop 2033 ii1=1 2034 if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then 2035 ii1=2 2036 ii=ii+1 2037 end if 2038 do i1=ii1,n1 2039 ig1=i1-(i1/id1)*n1-1 2040 gq1=dble(ig1)+qphon(1) 2041 gq(1)=gq1 2042 ii=ii+1 2043 gsquar=gsq_vl(ig1,ig2,ig3) 2044 ! Skip G**2 outside cutoff: 2045 if (gsquar<=cutoff) then 2046 gmag=sqrt(gsquar) 2047 2048 ! Obtain G in cartesian coordinates 2049 gqc(1)=gprimd(1,1)*gq(1)+gprimd(1,2)*gq(2)+gprimd(1,3)*gq(3) 2050 gqc(2)=gprimd(2,1)*gq(1)+gprimd(2,2)*gq(2)+gprimd(2,3)*gq(3) 2051 gqc(3)=gprimd(3,1)*gq(1)+gprimd(3,2)*gq(2)+gprimd(3,3)*gq(3) 2052 2053 ! Evaluate spline fit to get first V(q) and V(q)' and later V(q)'': 2054 call splfit(qgrid,vion1dq,vlspl(:,:,itypat),1,(/gmag/),vion1,mqgrid,1) 2055 vion1=vion1/gsquar 2056 vion1dq=(vion1dq-2.0_dp*gmag*vion1)/gsquar 2057 2058 call splfit(qgrid,vion1dqdq,vlspl(:,:,itypat),2,(/gmag/),vion1,mqgrid,1) 2059 vion1dqdq=(vion1dqdq-4.0_dp*gmag*vion1dq-2.0_dp*vion1)/gsquar 2060 2061 ! Assemble structure factor over all atoms of given type: 2062 sfr=0.0_dp 2063 sfi=0.0_dp 2064 do ia=ia1,ia2 2065 sfr=sfr+phre_vl(ig1,ig2,ig3,ia) 2066 sfi=sfi-phimag_vl(ig1,ig2,ig3,ia) 2067 end do 2068 2069 gfact=gqc(beta)*gqc(delta)*gqc(gamma)/gsquar 2070 2071 term1=delbd*gqc(gamma)+delbg*gqc(delta)+deldg*gqc(beta) 2072 term1=term1-gfact 2073 term1=term1*vion1dq(1)/gmag 2074 2075 term2=vion1dqdq(1)*gfact 2076 2077 ! Multiply structure factor times vion derivatives: 2078 work1(re,ii)=work1(re,ii)+sfr*(term1+term2) 2079 work1(im,ii)=work1(im,ii)+sfi*(term1+term2) 2080 2081 ! End skip G**2 outside cutoff: 2082 end if 2083 2084 end do 2085 end if 2086 end do 2087 end do 2088 2089 ia1=ia2+1 2090 2091 ! End loop on type of atoms 2092 end do 2093 2094 ! Set Vloc(G=0)=0: 2095 work1(re,1)=0.0_dp 2096 work1(im,1)=0.0_dp 2097 2098 ! Transform back to real space 2099 call fourdp(cplex,work1,vpsp1dqdq,1,mpi_enreg,nfft,1,ngfft,0) 2100 2101 xnorm=1.0_dp/ucvol/two_pi 2102 vpsp1dqdq(1:cplex*nfft)=vpsp1dqdq(1:cplex*nfft)*xnorm 2103 2104 work1=0.0_dp 2105 2106 ! Calculate the GS density Hartree contribution 2107 if (opthartdqdq==1) then 2108 2109 pisqrinv=1.0_dp/pi**2 2110 2111 ii=0 2112 do i3=1,n3 2113 ig3=i3-(i3/id3)*n3-1 2114 gq3=dble(ig3)+qphon(3) 2115 gq(3)=gq3 2116 do i2=1,n2 2117 if (fftn2_distrib(i2)==mpi_enreg%me_fft) then 2118 ig2=i2-(i2/id2)*n2-1 2119 gq2=dble(ig2)+qphon(2) 2120 gq(2)=gq2 2121 2122 ! Note the lower limit of the next loop 2123 ii1=1 2124 if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then 2125 ii1=2 2126 ii=ii+1 2127 end if 2128 do i1=ii1,n1 2129 ig1=i1-(i1/id1)*n1-1 2130 gq1=dble(ig1)+qphon(1) 2131 gq(1)=gq1 2132 ii=ii+1 2133 gsquar=gsq_vl(ig1,ig2,ig3) 2134 ! Skip G**2 outside cutoff: 2135 if (gsquar<=cutoff) then 2136 2137 ! Precalculate quotient of G powers 2138 uogsquar= 1.0_dp/gsquar 2139 2140 ! Obtain G in cartesian coordinates 2141 gqc(1)=gprimd(1,1)*gq(1)+gprimd(1,2)*gq(2)+gprimd(1,3)*gq(3) 2142 gqc(2)=gprimd(2,1)*gq(1)+gprimd(2,2)*gq(2)+gprimd(2,3)*gq(3) 2143 gqc(3)=gprimd(3,1)*gq(1)+gprimd(3,2)*gq(2)+gprimd(3,3)*gq(3) 2144 2145 term1=4.0_dp*gqc(beta)*gqc(gamma)*gqc(delta)*uogsquar*uogsquar 2146 term2=delbd*gqc(gamma)+delbg*gqc(delta)+deldg*gqc(beta) 2147 term2=-term2*uogsquar 2148 2149 work1re=pisqrinv*uogsquar*(term1+term2) 2150 work1(re,ii)=rhog(re,ii)*work1re 2151 work1(im,ii)=rhog(im,ii)*work1re 2152 2153 ! End skip G**2 outside cutoff: 2154 end if 2155 2156 end do 2157 end if 2158 end do 2159 end do 2160 2161 ! Set V(G=0)=0: 2162 work1(re,1)=0.0_dp 2163 work1(im,1)=0.0_dp 2164 2165 ! Transform back to real space 2166 call fourdp(cplex,work1,vhart1dqdq,1,mpi_enreg,nfft,1,ngfft,0) 2167 2168 ! End the calculation of the Hartree contribution 2169 end if 2170 2171 ABI_FREE(work1) 2172 2173 ! Calculate the GS density XC contribution (if GGA) 2174 vxc1dqdq(:)=zero 2175 if (nkxc == 7) then 2176 call dfpt_mkvxcgga_n0met(beta,1,delta,gamma,gprimd,kxc,mpi_enreg, & 2177 & nfft,ngfft,nkxc,nspden,rhor,vxc1dqdq) 2178 2179 !Fictitious i factor temporarily applied. 2180 !It is later canceled by the (-i) factor of the total matrix element 2181 do ii=1,nfft 2182 jj=ii*2 2183 tmpre=vxc1dqdq(jj-1); tmpim=vxc1dqdq(jj) 2184 vxc1dqdq(jj-1)=-tmpim; vxc1dqdq(jj)=tmpre 2185 end do 2186 end if 2187 2188 !End the condition of non-electric-field 2189 end if 2190 2191 contains 2192 2193 !Real and imaginary parts of phase. 2194 function phr_vl(x1,y1,x2,y2,x3,y3) 2195 real(dp) :: phr_vl,x1,x2,x3,y1,y2,y3 2196 phr_vl=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 2197 end function phr_vl 2198 2199 function phi_vl(x1,y1,x2,y2,x3,y3) 2200 real(dp):: phi_vl,x1,x2,x3,y1,y2,y3 2201 phi_vl=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 2202 end function phi_vl 2203 2204 function ph1_vl(nri,ig1,ia) 2205 real(dp):: ph1_vl 2206 integer :: nri,ig1,ia 2207 ph1_vl=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1)) 2208 end function ph1_vl 2209 2210 function ph2_vl(nri,ig2,ia) 2211 real(dp):: ph2_vl 2212 integer :: nri,ig2,ia 2213 ph2_vl=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1)) 2214 end function ph2_vl 2215 2216 function ph3_vl(nri,ig3,ia) 2217 real(dp):: ph3_vl 2218 integer :: nri,ig3,ia 2219 ph3_vl=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)) 2220 end function ph3_vl 2221 2222 function phre_vl(ig1,ig2,ig3,ia) 2223 real(dp):: phre_vl 2224 integer :: ig1,ig2,ig3,ia 2225 phre_vl=phr_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),& 2226 & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia)) 2227 end function phre_vl 2228 2229 function phimag_vl(ig1,ig2,ig3,ia) 2230 real(dp) :: phimag_vl 2231 integer :: ig1,ig2,ig3,ia 2232 phimag_vl=phi_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),& 2233 & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia)) 2234 end function phimag_vl 2235 2236 function gsq_vl(i1,i2,i3) 2237 real(dp) :: gsq_vl 2238 integer :: i1,i2,i3 2239 !Define G^2 based on G space metric gmet. 2240 gsq_vl=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+& 2241 & dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+& 2242 & dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1) 2243 end function gsq_vl 2244 2245 end subroutine dfpt_vmetdqdq 2246 2247 end module m_mklocl
ABINIT/m_mklocl [ Modules ]
NAME
m_mklocl
FUNCTION
Routines related to the local part of the pseudopotentials.
COPYRIGHT
Copyright (C) 1998-2024 ABINIT group (DCA, XG, GMR, MM, DRH) 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_mklocl 23 24 use defs_basis 25 use defs_wvltypes 26 use m_abicore 27 use m_errors 28 use m_xmpi 29 use m_dtset 30 31 use defs_datatypes, only : pseudopotential_type 32 use defs_abitypes, only : MPI_type 33 use m_time, only : timab 34 use m_geometry, only : xred2xcart 35 use m_mpinfo, only : ptabs_fourdp 36 use m_pawtab, only : pawtab_type 37 use m_mklocl_realspace, only : mklocl_realspace, mklocl_wavelets 38 use m_fft, only : fourdp 39 use m_gtermcutoff,only : termcutoff 40 41 use m_splines, only : splfit 42 use m_dfpt_mkvxc, only : dfpt_mkvxcgga_n0met 43 44 #if defined HAVE_BIGDFT 45 use BigDFT_API, only : ELECTRONIC_DENSITY 46 use m_abi2big, only : wvl_rho_abi2big 47 #endif 48 49 implicit none 50 51 private
ABINIT/mklocl [ Functions ]
NAME
mklocl
FUNCTION
This method is a wrapper for mklocl_recipspace and mklocl_realspace. It does some consistency checks before calling one of the two methods. Optionally compute : option=1 : local ionic potential throughout unit cell option=2 : contribution of local ionic potential to E gradient wrt xred option=3 : contribution of local ionic potential to stress tensor (only with reciprocal space computations) option=4 : contribution of local ionic potential to second derivative of E wrt xred (only with reciprocal space computations)
INPUTS
if(option==3) eei=local pseudopotential part of total energy (hartree) gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$). gprimd(3,3)=reciprocal space dimensional primitive translations gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere). mgfft=maximum size of 1D FFTs mpi_enreg=information about MPI parallelization natom=number of atoms in unit cell. nattyp(ntypat)=number of atoms of each type in cell. 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 nspden=number of spin-density components ntypat=number of types of atoms. option= (see above) pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. psps <type(pseudopotential_type)>=variables related to pseudopotentials qprtrb(3)= integer wavevector of possible perturbing potential in basis of reciprocal lattice translations rhog(2,nfft)=electron density rho(G) (electrons/$\textrm{Bohr}^3$) (needed if option==2 or if option==4) rhor(nfft,nspden)=electron density in electrons/bohr**3. (needed if option==2 or if option==4) rprimd(3,3)=dimensional primitive translations in real space (bohr) ucvol=unit cell volume ($\textrm{Bohr}^3$). vprtrb(2)=complex amplitude of possible perturbing potential; if nonzero, perturbing potential is added of the form $V(G)=(vprtrb(1)+I*vprtrb(2))/2$ at the values G=qprtrb and $(vprtrb(1)-I*vprtrb(2))/2$ at $G=-qprtrb$ (integers) xred(3,natom)=reduced dimensionless atomic coordinates
OUTPUT
(if option==1) vpsp(nfft)=local crystal pseudopotential in real space. (if option==2) grtn(3,natom)=grads of Etot wrt tn. (if option==3) lpsstr(6)=components of local psp part of stress tensor (Cartesian coordinates, symmetric tensor) in hartree/$\textrm{bohr}^3$ Store 6 unique components in order 11, 22, 33, 32, 31, 21 (if option==4) dyfrlo(3,3,natom)=d2 Eei/d tn(i)/d tn(j). (Hartrees)
NOTES
Note that the present routine is tightly connected to the dfpt_vlocal.f routine, that compute the derivative of the local ionic potential with respect to one atomic displacement. The argument list and the internal loops to be considered were sufficiently different as to make the two routine different.
SOURCE
130 subroutine mklocl(dtset, dyfrlo,eei,gmet,gprimd,grtn,gsqcut,lpsstr,mgfft,& 131 & mpi_enreg,natom,nattyp,nfft,ngfft,nspden,ntypat,option,pawtab,ph1d,psps,qprtrb,& 132 & rhog,rhor,rprimd,ucvol,vprtrb,vpsp,wvl,wvl_den,xred) 133 134 !Arguments ------------------------------------ 135 !scalars 136 integer,intent(in) :: mgfft,natom,nfft,nspden,ntypat,option 137 real(dp),intent(in) :: eei,gsqcut,ucvol 138 type(MPI_type),intent(in) :: mpi_enreg 139 type(dataset_type),intent(in) :: dtset 140 type(pseudopotential_type),intent(in) :: psps 141 type(wvl_internal_type), intent(in) :: wvl 142 type(wvl_denspot_type), intent(inout) :: wvl_den 143 type(pawtab_type),intent(in) :: pawtab(ntypat*psps%usepaw) 144 !arrays 145 integer,intent(in) :: nattyp(ntypat),ngfft(18),qprtrb(3) 146 real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom) 147 real(dp),intent(in) :: rhog(2,nfft),rprimd(3,3) 148 real(dp),intent(in) :: vprtrb(2),xred(3,natom) 149 real(dp),intent(in),target :: rhor(nfft,nspden) 150 real(dp),intent(out) :: dyfrlo(3,3,natom),grtn(3,natom),lpsstr(6) 151 real(dp),intent(inout) :: vpsp(nfft) 152 153 !Local variables------------------------------- 154 !scalars 155 character(len=500) :: message 156 !arrays 157 real(dp),allocatable :: xcart(:,:) 158 #if defined HAVE_BIGDFT 159 real(dp),pointer :: rhor_ptr(:,:) 160 #endif 161 162 ! ************************************************************************* 163 164 if (option < 1 .or. option > 4) then 165 write(message,'(a,i0,a,a)')& 166 & 'From the calling routine, option=',option,ch10,& 167 & 'The only allowed values are between 1 and 4.' 168 ABI_ERROR(message) 169 end if 170 if (option > 2 .and. .not.psps%vlspl_recipSpace) then 171 write(message,'(a,i0,a,a,a,a)')& 172 & 'From the calling routine, option=',option,ch10,& 173 & 'but the local part of the pseudo-potential is in real space.',ch10,& 174 & 'Action: set icoulomb = 0 to turn-off real space computations.' 175 ABI_ERROR(message) 176 end if 177 if (option > 2 .and. dtset%usewvl == 1) then 178 write(message,'(a,i0,a,a)')& 179 & 'From the calling routine, option=',option,ch10,& 180 & 'but this is not implemented yet from wavelets.' 181 ABI_ERROR(message) 182 end if 183 184 if (dtset%usewvl == 0) then 185 ! Plane wave case 186 if (psps%vlspl_recipSpace) then 187 call mklocl_recipspace(dyfrlo,eei,gmet,gprimd,grtn,gsqcut,& 188 & dtset%icutcoul,lpsstr,mgfft,mpi_enreg,psps%mqgrid_vl,natom,nattyp, & 189 & nfft,ngfft,dtset%nkpt,ntypat,option,ph1d,psps%qgrid_vl,qprtrb,dtset%rcut,& 190 & rhog,rprimd,ucvol,dtset%vcutgeo,psps%vlspl,vprtrb,vpsp) 191 else 192 call mklocl_realspace(grtn,dtset%icoulomb,mpi_enreg,natom,nattyp,nfft, & 193 & ngfft,dtset%nscforder,nspden,ntypat,option,pawtab,psps,rhog,rhor, & 194 & rprimd,dtset%typat,ucvol,dtset%usewvl,vpsp,xred) 195 end if 196 else 197 ! Store xcart for each atom 198 ABI_MALLOC(xcart,(3, dtset%natom)) 199 call xred2xcart(dtset%natom, rprimd, xcart, xred) 200 ! Eventually retrieve density 201 #if defined HAVE_BIGDFT 202 if (option>1.and.wvl_den%denspot%rhov_is/=ELECTRONIC_DENSITY) then 203 rhor_ptr => rhor ! Just to bypass intent(inout) 204 call wvl_rho_abi2big(1,rhor_ptr,wvl_den) 205 end if 206 #endif 207 ! Wavelets case 208 call mklocl_wavelets(dtset%efield, grtn, mpi_enreg, dtset%natom, & 209 & nfft, nspden, option, rprimd, vpsp, & 210 & wvl_den, wvl, xcart) 211 ABI_FREE(xcart) 212 end if 213 214 end subroutine mklocl
ABINIT/mklocl_recipspace [ Functions ]
NAME
mklocl_recipspace
FUNCTION
Optionally compute : option=1 : local ionic potential throughout unit cell option=2 : contribution of local ionic potential to E gradient wrt xred option=3 : contribution of local ionic potential to stress tensor option=4 : contribution of local ionic potential to second derivative of E wrt xred
INPUTS
if(option==3) eei=local pseudopotential part of total energy (hartree) gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$). gprimd(3,3)=reciprocal space dimensional primitive translations gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere). mgfft=maximum size of 1D FFTs mpi_enreg=information about MPI parallelization mqgrid=number of grid pts in q array for f(q) spline. natom=number of atoms in unit cell. nattyp(ntypat)=number of atoms of each type in cell. 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 ntypat=number of types of atoms. option= (see above) ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. qgrid(mqgrid)=q grid for spline from 0 to qmax. qprtrb(3)= integer wavevector of possible perturbing potential in basis of reciprocal lattice translations rhog(2,nfft)=electron density rho(G) (electrons/$\textrm{Bohr}^3$) (needed if option==2 or if option==4) ucvol=unit cell volume ($\textrm{Bohr}^3$). vlspl(mqgrid,2,ntypat)=q^2 v(q) spline for each type of atom. vprtrb(2)=complex amplitude of possible perturbing potential; if nonzero, perturbing potential is added of the form $V(G)=(vprtrb(1)+I*vprtrb(2))/2$ at the values G=qprtrb and $(vprtrb(1)-I*vprtrb(2))/2$ at $G=-qprtrb$ (integers)
OUTPUT
(if option==1) vpsp(nfft)=local crystal pseudopotential in real space. (if option==2) grtn(3,natom)=grads of Etot wrt tn. (if option==3) lpsstr(6)=components of local psp part of stress tensor (Cartesian coordinates, symmetric tensor) in hartree/$\textrm{bohr}^3$ Store 6 unique components in order 11, 22, 33, 32, 31, 21 (if option==4) dyfrlo(3,3,natom)=d2 Eei/d tn(i)/d tn(j). (Hartrees)
NOTES
Note that the present routine is tightly connected to the dfpt_vlocal.f routine, that compute the derivative of the local ionic potential with respect to one atomic displacement. The argument list and the internal loops to be considered were sufficiently different as to make the two routine different.
SOURCE
273 subroutine mklocl_recipspace(dyfrlo,eei,gmet,gprimd,grtn,gsqcut,icutcoul,lpsstr,mgfft,& 274 & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,nkpt,ntypat,option,ph1d,qgrid,qprtrb,& 275 & rcut,rhog,rprimd,ucvol,vcutgeo,vlspl,vprtrb,vpsp) 276 277 !Arguments ------------------------------------ 278 !scalars 279 integer,intent(in) :: mgfft,mqgrid,natom,nfft,nkpt,ntypat,option,icutcoul 280 real(dp),intent(in) :: eei,gsqcut,rcut,rprimd(3,3),ucvol,vcutgeo(3) 281 type(MPI_type),intent(in) :: mpi_enreg 282 !arrays 283 integer,intent(in) :: nattyp(ntypat),ngfft(18),qprtrb(3) 284 real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom) 285 real(dp),intent(in) :: qgrid(mqgrid),rhog(2,nfft),vlspl(mqgrid,2,ntypat) 286 real(dp),intent(in) :: vprtrb(2) 287 real(dp),intent(out) :: dyfrlo(3,3,natom),grtn(3,natom),lpsstr(6) !vz_i 288 real(dp),intent(inout) :: vpsp(nfft) !vz_i 289 290 !Local variables------------------------------- 291 !scalars 292 integer,parameter :: im=2,re=1 293 integer :: i1,i2,i3,ia,ia1,ia2,id1,id2,id3,ierr,ig1,ig2,ig3,ii,itypat 294 integer :: jj,me_fft,me_g0,n1,n2,n3,nproc_fft,shift1 295 integer :: shift2,shift3 296 #ifdef FC_NVHPC 297 !Silly trick to prevent NVHPC optimization issue 298 logical :: nothing=.false. 299 #endif 300 real(dp),parameter :: tolfix=1.0000001_dp 301 real(dp) :: aa,bb,cc,cutoff,dbl_ig1,dbl_ig2,dbl_ig3,dd,diff,dq,dq2div6,dqdiv6 302 real(dp) :: dqm1,ee,ff,gmag,gsquar!beta,gcart_para,gcart_perp 303 real(dp) :: ph12i,ph12r,ph1i,ph1r,ph2i,ph2r 304 real(dp) :: ph3i,ph3r,phimag_igia,phre_igia,rcut_loc,sfi,sfr 305 real(dp) :: svion,svioni,svionr,term,vion1,vion2,xnorm 306 character(len=500) :: message 307 !arrays 308 integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:) 309 integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:) 310 real(dp) :: gcart(3),tsec(2) 311 real(dp),allocatable :: gcutoff(:) 312 real(dp),allocatable :: work1(:,:) 313 314 ! ************************************************************************* 315 316 !Define G^2 based on G space metric gmet. 317 ! gsq(i1,i2,i3)=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+& 318 !& dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+& 319 !& dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1) 320 321 !Real and imaginary parts of phase--statment functions: 322 ! phr(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 323 ! phi(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 324 ! ph1(nri,i1,ia)=ph1d(nri,i1+1+n1+(ia-1)*(2*n1+1)) 325 ! ph2(nri,i2,ia)=ph1d(nri,i2+1+n2+(ia-1)*(2*n2+1)+& 326 !& natom*(2*n1+1)) 327 ! ph3(nri,i3,ia)=ph1d(nri,i3+1+n3+(ia-1)*(2*n3+1)+& 328 !& natom*(2*n1+1+2*n2+1)) 329 ! phre(i1,i2,i3,ia)=phr(ph1(re,i1,ia),ph1(im,i1,ia),ph2(re,i2,ia),& 330 !& ph2(im,i2,ia),ph3(re,i3,ia),ph3(im,i3,ia)) 331 ! phimag(i1,i2,i3,ia)=phi(ph1(re,i1,ia),ph1(im,i1,ia),ph2(re,i2,ia),& 332 !& ph2(im,i2,ia),ph3(re,i3,ia),ph3(im,i3,ia)) 333 334 !----- 335 336 !Keep track of total time spent in mklocl 337 if(option==2)then 338 call timab(72,1,tsec) 339 end if 340 n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3) 341 me_fft=ngfft(11) 342 nproc_fft=ngfft(10) 343 344 !Get the distrib associated with this fft_grid 345 call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local) 346 347 !Zero out array to permit accumulation over atom types below: 348 if(option==1)then 349 ABI_MALLOC(work1,(2,nfft)) 350 work1(:,:)=zero 351 end if 352 353 ! 354 dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1) 355 dqm1=1.0_dp/dq 356 dqdiv6=dq/6.0_dp 357 dq2div6=dq**2/6.0_dp 358 cutoff=gsqcut*tolfix 359 id1=n1/2+2 360 id2=n2/2+2 361 id3=n3/2+2 362 grtn(:,:)=zero 363 lpsstr(:)=zero 364 dyfrlo(:,:,:)=zero 365 me_g0=0 366 ia1=1 367 368 !Initialize Gcut-off array from m_gtermcutoff 369 call termcutoff(gcutoff,gsqcut,icutcoul,ngfft,nkpt,rcut,rprimd,vcutgeo) 370 rcut_loc = half*SQRT(DOT_PRODUCT(rprimd(:,3),rprimd(:,3))) 371 372 do itypat=1,ntypat 373 ! ia1,ia2 sets range of loop over atoms: 374 ia2=ia1+nattyp(itypat)-1 375 376 ii=0 377 do i3=1,n3 378 ig3=i3-(i3/id3)*n3-1 379 do i2=1,n2 380 ig2=i2-(i2/id2)*n2-1 381 if(fftn2_distrib(i2) == me_fft ) then 382 do i1=1,n1 383 ig1=i1-(i1/id1)*n1-1 384 385 ii=ii+1 386 ! *** GET RID OF THIS THESE IF STATEMENTS (if they slow code) 387 ! Skip G=0: 388 ! if (ii==1) cycle 389 if (ig1==0 .and. ig2==0 .and. ig3==0) me_g0=1 390 if (ig1==0 .and. ig2==0 .and. ig3==0) cycle 391 392 gsquar=gsq_mk(ig1,ig2,ig3) 393 ! Skip G**2 outside cutoff: 394 if (gsquar<=cutoff) then 395 gmag=sqrt(gsquar) 396 397 ! Compute vion(G) for given type of atom 398 jj=1+int(gmag*dqm1) 399 diff=gmag-qgrid(jj) 400 401 ! Evaluate spline fit from q^2 V(q) to get V(q): 402 ! (p. 86 Numerical Recipes, Press et al; 403 ! NOTE error in book for sign 404 ! of "aa" term in derivative; also see splfit routine). 405 406 bb = diff*dqm1 407 aa = 1.0_dp-bb 408 cc = aa*(aa**2-1.0_dp)*dq2div6 409 dd = bb*(bb**2-1.0_dp)*dq2div6 410 411 vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) +& 412 & cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) ) / gsquar * gcutoff(ii) 413 414 if(option==1)then 415 416 ! Assemble structure factor over all atoms of given type: 417 sfr=zero 418 sfi=zero 419 do ia=ia1,ia2 420 sfr=sfr+phre_mk(ig1,ig2,ig3,ia) 421 sfi=sfi-phimag_mk(ig1,ig2,ig3,ia) 422 end do 423 ! Multiply structure factor times vion: 424 work1(re,ii)=work1(re,ii)+sfr*vion1 425 work1(im,ii)=work1(im,ii)+sfi*vion1 426 427 else if(option==2 .or. option==4)then 428 429 ! Compute Re and Im part of (2Pi)*Vion(G)*rho(G): 430 svionr=(two_pi*vion1)*rhog(re,ii) 431 svioni=(two_pi*vion1)*rhog(im,ii) 432 433 ! Loop over all atoms of this type: 434 do ia=ia1,ia2 435 #ifdef FC_NVHPC 436 !Silly trick to prevent NVHPC optimization issue 437 if(nothing) write(100,*) shift1,shift2,shift3 438 #endif 439 440 shift1=1+n1+(ia-1)*(2*n1+1) 441 shift2=1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1) 442 shift3=1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1) 443 ph1r=ph1d(1,ig1+shift1) 444 ph1i=ph1d(2,ig1+shift1) 445 ph2r=ph1d(1,ig2+shift2) 446 ph2i=ph1d(2,ig2+shift2) 447 ph3r=ph1d(1,ig3+shift3) 448 ph3i=ph1d(2,ig3+shift3) 449 ph12r=ph1r*ph2r-ph1i*ph2i 450 ph12i=ph1r*ph2i+ph1i*ph2r 451 phre_igia=ph12r*ph3r-ph12i*ph3i 452 phimag_igia=ph12r*ph3i+ph12i*ph3r 453 454 if(option==2)then 455 456 ! Compute "Vion" part of gradient 457 ! svion=svioni*phre(ig1,ig2,ig3,ia)+svionr*phimag(ig1,ig2,ig3,ia) 458 svion=svioni*phre_igia+svionr*phimag_igia 459 460 ! Open loop over 3-index for speed: 461 grtn(1,ia)=grtn(1,ia)-dble(ig1)*svion 462 grtn(2,ia)=grtn(2,ia)-dble(ig2)*svion 463 grtn(3,ia)=grtn(3,ia)-dble(ig3)*svion 464 465 else 466 467 ! Compute "Vion" part of the second derivative 468 ! svion=two_pi* 469 ! (svionr*phre(ig1,ig2,ig3,ia)-svioni*phimag(ig1,ig2,ig3,ia)) 470 svion=two_pi*(svionr*phre_igia-svioni*phimag_igia) 471 472 ! Open loop over 3-index for speed 473 dbl_ig1=dble(ig1) ; dbl_ig2=dble(ig2) ; dbl_ig3=dble(ig3) 474 dyfrlo(1,1,ia)=dyfrlo(1,1,ia)-dbl_ig1*dbl_ig1*svion 475 dyfrlo(1,2,ia)=dyfrlo(1,2,ia)-dbl_ig1*dbl_ig2*svion 476 dyfrlo(1,3,ia)=dyfrlo(1,3,ia)-dbl_ig1*dbl_ig3*svion 477 dyfrlo(2,2,ia)=dyfrlo(2,2,ia)-dbl_ig2*dbl_ig2*svion 478 dyfrlo(2,3,ia)=dyfrlo(2,3,ia)-dbl_ig2*dbl_ig3*svion 479 dyfrlo(3,3,ia)=dyfrlo(3,3,ia)-dbl_ig3*dbl_ig3*svion 480 481 end if 482 483 end do 484 485 else if(option==3)then 486 ! if(icutcoul .ne. 2) then 487 ! Also get (dV(q)/dq)/q: 488 ! (note correction of Numerical Recipes sign error 489 ! before (3._dp*aa**2-1._dp) 490 ! ee*dqm1 + ff*dqdiv6 is the best estimate of dV(q)/dq from splines 491 ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat) 492 ff= (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) & 493 & - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat) 494 vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag& 495 & - 2.0_dp*vion1 ) / gsquar 496 497 gcart(1)=gprimd(1,1)*dble(ig1)+gprimd(1,2)*dble(ig2)+& 498 & gprimd(1,3)*dble(ig3) 499 gcart(2)=gprimd(2,1)*dble(ig1)+gprimd(2,2)*dble(ig2)+& 500 & gprimd(2,3)*dble(ig3) 501 gcart(3)=gprimd(3,1)*dble(ig1)+gprimd(3,2)*dble(ig2)+& 502 & gprimd(3,3)*dble(ig3) 503 ! Assemble structure over all atoms of given type 504 sfr=zero 505 sfi=zero 506 do ia=ia1,ia2 507 sfr=sfr+phre_mk(ig1,ig2,ig3,ia) 508 sfi=sfi-phimag_mk(ig1,ig2,ig3,ia) 509 end do 510 ! Compute Re( rho^*(G)* sf ) * [(dV(G)/dG)/|G|] 511 term=(rhog(re,ii)*sfr+rhog(im,ii)*sfi)*vion2 512 ! Compute contribution to stress tensor 513 lpsstr(1)=lpsstr(1)-term*gcart(1)*gcart(1) 514 lpsstr(2)=lpsstr(2)-term*gcart(2)*gcart(2) 515 lpsstr(3)=lpsstr(3)-term*gcart(3)*gcart(3) 516 lpsstr(4)=lpsstr(4)-term*gcart(3)*gcart(2) 517 lpsstr(5)=lpsstr(5)-term*gcart(3)*gcart(1) 518 lpsstr(6)=lpsstr(6)-term*gcart(2)*gcart(1) 519 ! else if (icutcoul .eq. 2) then 520 !! Also get (dV(q)/dq)/q: 521 !! (note correction of Numerical Recipes sign error 522 !! before (3._dp*aa**2-1._dp) 523 !! ee*dqm1 + ff*dqdiv6 is the best estimate of dV(q)/dq from splines 524 ! ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat) 525 ! ff= (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) & 526 !& - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat) 527 ! vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag& 528 !& - 2.0_dp*vion1 ) / gsquar 529 ! 530 ! gcart(1)=gprimd(1,1)*dble(ig1)+gprimd(1,2)*dble(ig2)+& 531 !& gprimd(1,3)*dble(ig3) 532 ! gcart(2)=gprimd(2,1)*dble(ig1)+gprimd(2,2)*dble(ig2)+& 533 !& gprimd(2,3)*dble(ig3) 534 ! gcart(3)=gprimd(3,1)*dble(ig1)+gprimd(3,2)*dble(ig2)+& 535 !& gprimd(3,3)*dble(ig3) 536 !! Assemble structure over all atoms of given type 537 ! sfr=zero 538 ! sfi=zero 539 ! do ia=ia1,ia2 540 ! sfr=sfr+phre_mk(ig1,ig2,ig3,ia) 541 ! sfi=sfi-phimag_mk(ig1,ig2,ig3,ia) 542 ! end do 543 ! !Implement beta correction as in eq. 62 (PRB 96 075448 2017) 544 ! gcart_para = sqrt(gcart(1)**2+gcart(2)**2) 545 ! gcart_perp = gcart(3) 546 ! gsquar = gcart(1)**2+gcart(2)**2+gcart(3)**2 547 ! if(gcart_para .gt. tol12) then 548 ! beta = gsquar*rcut_loc/(two*gcart_para)* & 549 ! & exp(-gcart_para*rcut_loc)* & 550 ! &cos(gcart_perp*rcut_loc)/(one-exp(-gcart_para*rcut_loc)*cos(gcart_perp*rcut_loc)) 551 ! else 552 ! beta = zero 553 ! end if 554 !! Compute Re( rho^*(G)* sf ) * [(dV(G)/dG)/|G|] 555 ! term=(rhog(re,ii)*sfr+rhog(im,ii)*sfi)*vion2 556 !! Compute contribution to stress tensor 557 ! lpsstr(1)=lpsstr(1)-term*(gcart(1)*gcart(1))*(1+beta) 558 ! lpsstr(2)=lpsstr(2)-term*(gcart(2)*gcart(2))*(1+beta) 559 ! lpsstr(3)=lpsstr(3)-term*(gcart(3)*gcart(3)-gsquar) 560 ! lpsstr(4)=lpsstr(4)-term*gcart(3)*gcart(2) 561 ! lpsstr(5)=lpsstr(5)-term*gcart(3)*gcart(1) 562 ! lpsstr(6)=lpsstr(6)-term*gcart(2)*gcart(1) 563 ! endif 564 565 else 566 write(message, '(a,i0,a)' )' mklocl: Option=',option,' not allowed.' 567 ABI_BUG(message) 568 end if ! End option choice 569 570 ! End skip G**2 outside cutoff: 571 end if 572 573 ! End loop on n1, n2, n3. There is a "cycle" inside the loop 574 end do 575 end if ! this plane is for me_fft 576 end do 577 end do 578 579 ! Symmetrize the dynamical matrix with respect to indices 580 do ia=ia1,ia2 581 dyfrlo(2,1,ia)=dyfrlo(1,2,ia) 582 dyfrlo(3,1,ia)=dyfrlo(1,3,ia) 583 dyfrlo(3,2,ia)=dyfrlo(2,3,ia) 584 end do 585 586 ia1=ia2+1 587 588 ! End loop on type of atoms 589 end do 590 591 if(option==1)then 592 ! Dont't change work1 on g=0 if Poisson solver is used since work1 593 ! hold not the potential but the density generated by the pseudo. 594 if(me_g0 == 1) then 595 ! Set Vloc(G=0)=0: 596 work1(re,1)=zero 597 work1(im,1)=zero 598 end if 599 ! write(std_out,*) ' mklocl_recipspace : will add potential with strength vprtrb(:)=',vprtrb(:) 600 601 ! Allow for the addition of a perturbing potential 602 if ((vprtrb(1)**2+vprtrb(2)**2) > 1.d-30) then 603 ! Find the linear indices which correspond with the input 604 ! wavevector qprtrb 605 ! The double modulus handles both i>=n and i<0, mapping into [0,n-1]; 606 ! then add 1 to get range [1,n] for each 607 i3=1+mod(n3+mod(qprtrb(3),n3),n3) 608 i2=1+mod(n2+mod(qprtrb(2),n2),n2) 609 i1=1+mod(n1+mod(qprtrb(1),n1),n1) 610 ! Compute the linear index in the 3 dimensional array 611 ii=i1+n1*((ffti2_local(i2)-1)+(n2/nproc_fft)*(i3-1)) 612 ! Add in the perturbation at G=qprtrb 613 work1(re,ii)=work1(re,ii)+0.5_dp*vprtrb(1) 614 work1(im,ii)=work1(im,ii)+0.5_dp*vprtrb(2) 615 ! Same thing for G=-qprtrb 616 i3=1+mod(n3+mod(-qprtrb(3),n3),n3) 617 i2=1+mod(n2+mod(-qprtrb(2),n2),n2) 618 i1=1+mod(n1+mod(-qprtrb(1),n1),n1) 619 ! ii=i1+n1*((i2-1)+n2*(i3-1)) 620 work1(re,ii)=work1(re,ii)+0.5_dp*vprtrb(1) 621 work1(im,ii)=work1(im,ii)-0.5_dp*vprtrb(2) 622 write(message, '(a,1p,2e12.4,a,0p,3i4,a)' )& 623 & ' mklocl: perturbation of vprtrb=', vprtrb,& 624 & ' and q=',qprtrb,' has been added' 625 call wrtout(std_out,message,'COLL') 626 end if 627 628 ! Transform back to real space 629 call fourdp(1,work1,vpsp,1,mpi_enreg,nfft,1,ngfft,0) 630 631 ! Divide by unit cell volume 632 xnorm=1.0_dp/ucvol 633 vpsp(:)=vpsp(:)*xnorm 634 635 ABI_FREE(work1) 636 637 end if 638 639 ABI_FREE(gcutoff) 640 641 if(option==2)then 642 ! Init mpi_comm 643 if(mpi_enreg%nproc_fft>1)then 644 call timab(48,1,tsec) 645 call xmpi_sum(grtn,mpi_enreg%comm_fft ,ierr) 646 call timab(48,2,tsec) 647 end if 648 call timab(72,2,tsec) 649 end if 650 651 if(option==3)then 652 ! Init mpi_comm 653 if(mpi_enreg%nproc_fft>1)then 654 call timab(48,1,tsec) 655 call xmpi_sum(lpsstr,mpi_enreg%comm_fft ,ierr) 656 call timab(48,2,tsec) 657 end if 658 659 ! Normalize and add term -eei/ucvol on diagonal 660 ! (see page 802 of notes) 661 ! if(icutcoul .ne. 2) then 662 lpsstr(1)=(lpsstr(1)-eei)/ucvol 663 lpsstr(2)=(lpsstr(2)-eei)/ucvol 664 lpsstr(3)=(lpsstr(3)-eei)/ucvol 665 lpsstr(4)=lpsstr(4)/ucvol 666 lpsstr(5)=lpsstr(5)/ucvol 667 lpsstr(6)=lpsstr(6)/ucvol 668 ! elseif (icutcoul .eq. 2) then 669 ! lpsstr(1)=(lpsstr(1)-eei)/ucvol 670 ! lpsstr(2)=(lpsstr(2)-eei)/ucvol 671 ! lpsstr(3)=(lpsstr(3)-eei)/ucvol 672 ! lpsstr(4)=lpsstr(4)/ucvol 673 ! lpsstr(5)=lpsstr(5)/ucvol 674 ! lpsstr(6)=lpsstr(6)/ucvol 675 !lpsstr=lpsstr/ucvol 676 ! endif 677 678 end if 679 680 if(option==4)then 681 ! Init mpi_comm 682 if(mpi_enreg%nproc_fft>1)then 683 call timab(48,1,tsec) 684 call xmpi_sum(dyfrlo,mpi_enreg%comm_fft ,ierr) 685 call timab(48,2,tsec) 686 end if 687 end if 688 689 contains 690 691 !Real and imaginary parts of phase--statment functions: 692 function phr_mk(x1,y1,x2,y2,x3,y3) 693 694 real(dp) :: phr_mk,x1,x2,x3,y1,y2,y3 695 phr_mk=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 696 end function phr_mk 697 698 function phi_mk(x1,y1,x2,y2,x3,y3) 699 700 real(dp):: phi_mk,x1,x2,x3,y1,y2,y3 701 phi_mk=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 702 end function phi_mk 703 704 function ph1_mk(nri,ig1,ia) 705 706 real(dp):: ph1_mk 707 integer :: nri,ig1,ia 708 ph1_mk=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1)) 709 end function ph1_mk 710 711 function ph2_mk(nri,ig2,ia) 712 713 real(dp):: ph2_mk 714 integer :: nri,ig2,ia 715 ph2_mk=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1)) 716 end function ph2_mk 717 718 function ph3_mk(nri,ig3,ia) 719 720 real(dp):: ph3_mk 721 integer :: nri,ig3,ia 722 ph3_mk=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)) 723 end function ph3_mk 724 725 function phre_mk(ig1,ig2,ig3,ia) 726 727 real(dp):: phre_mk 728 integer :: ig1,ig2,ig3,ia 729 phre_mk=phr_mk(ph1_mk(re,ig1,ia),ph1_mk(im,ig1,ia),& 730 & ph2_mk(re,ig2,ia),ph2_mk(im,ig2,ia),ph3_mk(re,ig3,ia),ph3_mk(im,ig3,ia)) 731 end function phre_mk 732 733 function phimag_mk(ig1,ig2,ig3,ia) 734 735 real(dp) :: phimag_mk 736 integer :: ig1,ig2,ig3,ia 737 phimag_mk=phi_mk(ph1_mk(re,ig1,ia),ph1_mk(im,ig1,ia),& 738 & ph2_mk(re,ig2,ia),ph2_mk(im,ig2,ia),ph3_mk(re,ig3,ia),ph3_mk(im,ig3,ia)) 739 end function phimag_mk 740 741 function gsq_mk(i1,i2,i3) 742 743 real(dp) :: gsq_mk 744 integer :: i1,i2,i3 745 gsq_mk=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+& 746 & dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+& 747 & dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1) 748 end function gsq_mk 749 750 end subroutine mklocl_recipspace
ABINIT/vlocalstr [ Functions ]
NAME
vlocalstr
FUNCTION
Compute strain derivatives of local ionic potential second derivative of E wrt xred
INPUTS
gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$). gprimd(3,3)=reciprocal space dimensional primitive translations gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere). istr=1,...6 specifies cartesian strain component 11,22,33,32,31,21 mgfft=maximum size of 1D FFTs mpi_enreg=information about MPI parallelization mqgrid=number of grid pts in q array for f(q) spline. natom=number of atoms in unit cell. nattyp(ntypat)=number of atoms of each type in cell. 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 ntypat=number of types of atoms. ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information. qgrid(mqgrid)=q grid for spline from 0 to qmax. ucvol=unit cell volume ($\textrm{Bohr}^3$). vlspl(mqgrid,2,ntypat)=q^2 v(q) spline for each type of atom. [g0term]= optional, if present an alternative treatment of the G=0 term, adopoted for the flexoelectric tensor calculation, is performed.
OUTPUT
vpsp1(nfft)=first-order local crystal pseudopotential in real space.
NOTES
* Note that the present routine is tightly connected to the dfpt_vlocal.f routine, that compute the derivative of the local ionic potential with respect to one atomic displacement. The argument list and the internal loops to be considered were sufficiently different as to make the two routines different. * The routine was adapted from mklocl.F90
SOURCE
1051 subroutine vlocalstr(gmet,gprimd,gsqcut,istr,mgfft,mpi_enreg,& 1052 & mqgrid,natom,nattyp,nfft,ngfft,ntypat,ph1d,qgrid,& 1053 & ucvol,vlspl,vpsp1,g0term) 1054 1055 !Arguments ------------------------------------ 1056 !scalars 1057 integer,intent(in) :: istr,mgfft,mqgrid,natom,nfft,ntypat 1058 integer,optional,intent(in) :: g0term 1059 real(dp),intent(in) :: gsqcut,ucvol 1060 type(MPI_type),intent(in) :: mpi_enreg 1061 !arrays 1062 integer,intent(in) :: nattyp(ntypat),ngfft(18) 1063 real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom) 1064 real(dp),intent(in) :: qgrid(mqgrid),vlspl(mqgrid,2,ntypat) 1065 real(dp),intent(out) :: vpsp1(nfft) 1066 1067 !Local variables------------------------------- 1068 !scalars 1069 integer,parameter :: im=2,re=1 1070 integer :: g0term_ 1071 integer :: i1,i2,i3,ia,ia1,ia2,id1,id2,id3,ig1,ig2,ig3,ii,itypat,jj 1072 integer :: ka,kb,n1,n2,n3 1073 real(dp),parameter :: tolfix=1.0000001_dp 1074 real(dp) :: aa,bb,cc,cutoff,dd,dgsquards,diff 1075 real(dp) :: dq,dq2div6,dqdiv6,dqm1,ee,ff,gmag,gsquar 1076 real(dp) :: sfi,sfr,term,vion1,vion2,vlocg0 1077 real(dp) :: xnorm 1078 character(len=500) :: message 1079 !arrays 1080 integer,save :: idx(12)=(/1,1,2,2,3,3,3,2,3,1,2,1/) 1081 integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:) 1082 integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:) 1083 real(dp) :: dgmetds(3,3) 1084 real(dp),allocatable :: work1(:,:) 1085 1086 ! ************************************************************************* 1087 1088 !Define G^2 based on G space metric gmet. 1089 ! gsq_vl(i1,i2,i3)=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+& 1090 !& dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+& 1091 !& dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1) 1092 1093 !Define dG^2/ds based on G space metric derivative dgmetds. 1094 ! dgsqds_vl(i1,i2,i3)=dble(i1*i1)*dgmetds(1,1)+dble(i2*i2)*dgmetds(2,2)+& 1095 !& dble(i3*i3)*dgmetds(3,3)+& 1096 !& dble(i1*i2)*(dgmetds(1,2)+dgmetds(2,1))+& 1097 !& dble(i1*i3)*(dgmetds(1,3)+dgmetds(3,1))+& 1098 !& dble(i2*i3)*(dgmetds(2,3)+dgmetds(3,2)) 1099 1100 !Real and imaginary parts of phase--statment functions: 1101 ! phr_vl(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 1102 ! phi_vl(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 1103 ! ph1_vl(nri,i1,ia)=ph1d(nri,i1+1+n1+(ia-1)*(2*n1+1)) 1104 ! ph2_vl(nri,i2,ia)=ph1d(nri,i2+1+n2+(ia-1)*(2*n2+1)+& 1105 !& natom*(2*n1+1)) 1106 ! ph3_vl(nri,i3,ia)=ph1d(nri,i3+1+n3+(ia-1)*(2*n3+1)+& 1107 !& natom*(2*n1+1+2*n2+1)) 1108 ! phre_vl(i1,i2,i3,ia)=phr_vl(ph1_vl(re,i1,ia),ph1_vl(im,i1,ia),ph2_vl(re,i2,ia),& 1109 !& ph2_vl(im,i2,ia),ph3_vl(re,i3,ia),ph3_vl(im,i3,ia)) 1110 ! phimag_vl(i1,i2,i3,ia)=phi_vl(ph1_vl(re,i1,ia),ph1_vl(im,i1,ia),ph2_vl(re,i2,ia),& 1111 !& ph2_vl(im,i2,ia),ph3_vl(re,i3,ia),ph3_vl(im,i3,ia)) 1112 1113 !----- 1114 !Compute derivative of metric tensor wrt strain component istr 1115 if(istr<1 .or. istr>6)then 1116 write(message, '(a,i10,a,a,a)' )& 1117 & ' Input istr=',istr,' not allowed.',ch10,& 1118 & ' Possible values are 1,2,3,4,5,6 only.' 1119 ABI_BUG(message) 1120 end if 1121 1122 ka=idx(2*istr-1);kb=idx(2*istr) 1123 do ii = 1,3 1124 dgmetds(:,ii)=-(gprimd(ka,:)*gprimd(kb,ii)+gprimd(kb,:)*gprimd(ka,ii)) 1125 end do 1126 !For historical reasons: 1127 dgmetds(:,:)=0.5_dp*dgmetds(:,:) 1128 1129 n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3) 1130 1131 !Get the distrib associated with this fft_grid 1132 call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local) 1133 1134 !Zero out array to permit accumulation over atom types below: 1135 ABI_MALLOC(work1,(2,nfft)) 1136 work1(:,:)=0.0_dp 1137 ! 1138 dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1) 1139 dqm1=1.0_dp/dq 1140 dqdiv6=dq/6.0_dp 1141 dq2div6=dq**2/6.0_dp 1142 cutoff=gsqcut*tolfix 1143 id1=n1/2+2 1144 id2=n2/2+2 1145 id3=n3/2+2 1146 1147 ia1=1 1148 do itypat=1,ntypat 1149 ! ia1,ia2 sets range of loop over atoms: 1150 ia2=ia1+nattyp(itypat)-1 1151 1152 ii=0 1153 do i3=1,n3 1154 ig3=i3-(i3/id3)*n3-1 1155 do i2=1,n2 1156 if (fftn2_distrib(i2)==mpi_enreg%me_fft) then 1157 ig2=i2-(i2/id2)*n2-1 1158 do i1=1,n1 1159 ig1=i1-(i1/id1)*n1-1 1160 ii=ii+1 1161 ! *** GET RID OF THIS THESE IF STATEMENTS (if they slow code) 1162 ! Skip G=0: 1163 ! if (ii==1) cycle 1164 if (ig1==0 .and. ig2==0 .and. ig3==0) cycle 1165 gsquar=gsq_vl(ig1,ig2,ig3) 1166 1167 ! Skip G**2 outside cutoff: 1168 if (gsquar<=cutoff) then 1169 gmag=sqrt(gsquar) 1170 dgsquards=dgsqds_vl(ig1,ig2,ig3) 1171 ! Compute vion(G) for given type of atom 1172 jj=1+int(gmag*dqm1) 1173 diff=gmag-qgrid(jj) 1174 1175 ! Evaluate spline fit from q^2 V(q) to get V(q): 1176 ! (p. 86 Numerical Recipes, Press et al; 1177 ! NOTE error in book for sign 1178 ! of "aa" term in derivative; also see splfit routine). 1179 1180 bb = diff*dqm1 1181 aa = 1.0_dp-bb 1182 cc = aa*(aa**2-1.0_dp)*dq2div6 1183 dd = bb*(bb**2-1.0_dp)*dq2div6 1184 1185 vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) +& 1186 & cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) ) & 1187 & / gsquar 1188 1189 ! Also get (dV(q)/dq)/q: 1190 ! (note correction of Numerical Recipes sign error 1191 ! before (3._dp*aa**2-1._dp) 1192 ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat) 1193 ff= (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) & 1194 & - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat) 1195 vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag& 1196 & - 2.0_dp*vion1 ) / gsquar 1197 1198 1199 ! Assemble structure factor over all atoms of given type: 1200 sfr=0.0_dp 1201 sfi=0.0_dp 1202 do ia=ia1,ia2 1203 sfr=sfr+phre_vl(ig1,ig2,ig3,ia) 1204 sfi=sfi-phimag_vl(ig1,ig2,ig3,ia) 1205 end do 1206 1207 term=dgsquards*vion2 1208 ! Add potential for diagonal strain components 1209 if(istr <=3) then 1210 term=term-vion1 1211 end if 1212 1213 ! Multiply structure factor times vion derivatives: 1214 work1(re,ii)=work1(re,ii)+sfr*term 1215 work1(im,ii)=work1(im,ii)+sfi*term 1216 1217 ! End skip G**2 outside cutoff: 1218 end if 1219 ! End loop on n1, n2, n3. There is a "cycle" inside the loop 1220 end do 1221 end if 1222 end do 1223 end do 1224 1225 ia1=ia2+1 1226 1227 ! End loop on type of atoms 1228 end do 1229 1230 1231 !Set Vloc(G=0)=0: 1232 work1(re,1)=0.0_dp 1233 work1(im,1)=0.0_dp 1234 1235 !Alternative treatment of Vloc(G=0) for the flexoelectric tensor calculation 1236 g0term_=0; if (present(g0term)) g0term_=g0term 1237 if (g0term_==1) then 1238 vlocg0=zero 1239 if (istr<=3) then 1240 ia1=1 1241 do itypat=1,ntypat 1242 ! ia1,ia2 sets range of loop over atoms: 1243 1244 ia2=ia1+nattyp(itypat)-1 1245 do ia=ia1,ia2 1246 vlocg0=vlocg0+vlspl(1,2,itypat) 1247 end do 1248 end do 1249 work1(re,1)=-half*vlocg0 1250 end if 1251 end if 1252 1253 !Transform back to real space 1254 call fourdp(1,work1,vpsp1,1,mpi_enreg,nfft,1,ngfft,0) 1255 1256 !Divide by unit cell volume 1257 xnorm=1.0_dp/ucvol 1258 vpsp1(:)=vpsp1(:)*xnorm 1259 1260 ABI_FREE(work1) 1261 1262 contains 1263 1264 !Real and imaginary parts of phase. 1265 function phr_vl(x1,y1,x2,y2,x3,y3) 1266 1267 real(dp) :: phr_vl,x1,x2,x3,y1,y2,y3 1268 phr_vl=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3 1269 end function phr_vl 1270 1271 function phi_vl(x1,y1,x2,y2,x3,y3) 1272 1273 real(dp):: phi_vl,x1,x2,x3,y1,y2,y3 1274 phi_vl=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3 1275 end function phi_vl 1276 1277 function ph1_vl(nri,ig1,ia) 1278 1279 real(dp):: ph1_vl 1280 integer :: nri,ig1,ia 1281 ph1_vl=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1)) 1282 end function ph1_vl 1283 1284 function ph2_vl(nri,ig2,ia) 1285 1286 real(dp):: ph2_vl 1287 integer :: nri,ig2,ia 1288 ph2_vl=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1)) 1289 end function ph2_vl 1290 1291 function ph3_vl(nri,ig3,ia) 1292 1293 real(dp):: ph3_vl 1294 integer :: nri,ig3,ia 1295 ph3_vl=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)) 1296 end function ph3_vl 1297 1298 function phre_vl(ig1,ig2,ig3,ia) 1299 1300 real(dp):: phre_vl 1301 integer :: ig1,ig2,ig3,ia 1302 phre_vl=phr_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),& 1303 & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia)) 1304 end function phre_vl 1305 1306 function phimag_vl(ig1,ig2,ig3,ia) 1307 1308 real(dp) :: phimag_vl 1309 integer :: ig1,ig2,ig3,ia 1310 phimag_vl=phi_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),& 1311 & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia)) 1312 end function phimag_vl 1313 1314 function gsq_vl(i1,i2,i3) 1315 1316 real(dp) :: gsq_vl 1317 integer :: i1,i2,i3 1318 !Define G^2 based on G space metric gmet. 1319 gsq_vl=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+& 1320 & dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+& 1321 & dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1) 1322 end function gsq_vl 1323 1324 function dgsqds_vl(i1,i2,i3) 1325 1326 real(dp) :: dgsqds_vl 1327 integer :: i1,i2,i3 1328 !Define dG^2/ds based on G space metric derivative dgmetds. 1329 dgsqds_vl=dble(i1*i1)*dgmetds(1,1)+dble(i2*i2)*dgmetds(2,2)+& 1330 & dble(i3*i3)*dgmetds(3,3)+& 1331 & dble(i1*i2)*(dgmetds(1,2)+dgmetds(2,1))+& 1332 & dble(i1*i3)*(dgmetds(1,3)+dgmetds(3,1))+& 1333 & dble(i2*i3)*(dgmetds(2,3)+dgmetds(3,2)) 1334 end function dgsqds_vl 1335 1336 end subroutine vlocalstr