TABLE OF CONTENTS
- ABINIT/m_paw_slater
- m_paw_slater/paw_dijhf
- m_paw_slater/paw_mkdijexc_core
- m_paw_slater/paw_sigxcore
- m_paw_slater/slat_intg
- m_paw_slater/slatang_cshell_free
- m_paw_slater/slatang_cshell_init
- m_paw_slater/slatang_cshell_t
- m_paw_slater/slatrad_cshell_free
- m_paw_slater/slatrad_cshell_init
- m_paw_slater/slatrad_cshell_t
- m_paw_slater/slatrad_free_0D
- m_paw_slater/slatrad_free_1D
- m_paw_slater/slatrad_init
- m_paw_slater/slatrad_t
- m_paw_slater/summ_2gaunt
ABINIT/m_paw_slater [ Modules ]
NAME
m_paw_slater
FUNCTION
This module defines objects and procedures to evaluate Slater-like integrals using real spherical Harmonics.
COPYRIGHT
Copyright (C) 2008-2024 ABINIT group (MG) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
NOTES
* Routines tagged with "@type_name" are tightly connected to the definition of the data type. Tightly connected means that the proper functioning of the implementation relies on the assumption that the tagged procedure is consistent with the type declaration. Every time a developer changes the structure "type_name" adding new entries, he/she has to make sure that all the tightly connected routines are changed accordingly to accommodate the modification of the data type. Typical examples of tightly connected routines are creation, destruction or reset methods.
SOURCE
25 #if defined HAVE_CONFIG_H 26 #include "config.h" 27 #endif 28 29 #include "abi_common.h" 30 31 MODULE m_paw_slater 32 33 use defs_basis 34 use m_abicore 35 use m_errors 36 use m_splines 37 38 use m_fstrings, only : basename 39 use m_paw_atomorb, only : atomorb_type, init_atomorb, print_atomorb, destroy_atomorb, get_overlap 40 use m_crystal, only : crystal_t 41 use m_paw_io, only : pawio_print_ij 42 use m_pawang, only : pawang_type 43 use m_paw_sphharm, only : realgaunt 44 use m_pawrad, only : pawrad_type, pawrad_free, pawrad_isame, & 45 & pawrad_deducer0, simp_gen, calc_slatradl 46 use m_pawtab, only : pawtab_type 47 use m_pawrhoij, only : pawrhoij_type 48 use m_paw_lmn, only : make_kln2ln, make_klm2lm, make_indln, klmn2ijlmn 49 50 implicit none 51 52 private 53 54 public :: paw_sigxcore ! The onsite matrix elements of the Fock operator generated by (closed) core shells. 55 public :: paw_mkdijexc_core ! Calculate the onsite matrix element of the Fock operator generated by the core. 56 public :: paw_dijhf ! Compute the onsite D_{ij} strengths of the exchange parth of the self energy.
m_paw_slater/paw_dijhf [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
paw_dihf
FUNCTION
This routine calculates the onsite D_{ij} strengths of the exchange part of the self energy.
INPUTS
ndij=Usually ndij=nspden, except for spin-orbit (where ndij=nspinor**2) cplex_dij=1 if sigx_dij is real, 2 if they are complex qphase=2 if dij contains a exp(-i.q.r) phase (as in the q<>0 RF case), 1 if not lmn2_size_max=Max Number of (klmn) channels over type of atoms. my_natom=number of atoms treated by current process ntypat=number of atom types Pawtab(ntypat)<pawtab_type>=paw tabulated starting data Pawrad(ntypat)<pawrad_type>=paw radial mesh and related data Pawang<type(pawang_type)>=paw angular mesh and related data pawprtvol=Flags governing the verbosity of the output.
OUTPUT
sigx_dij(cplex_dij*lmn2_size_max,ndij,my_natom)= For each atom, the Pseudopotential strengths of the on-site operator Sigma_x
NOTES
The on-site contribution to the matrix elements of the exchange part of the self-energy is given by: <\tpsi_a| [\sum_{ij} |tprj_i\> D_{ij} \<tprj_j|] |\tpsi_b\>. When compensation charges are used one obtains: D_{ij} = - sum_{kl} \rho_lk [ \Phi_{ikjl} - \Phihat_{ijkl} = = - sum_{kl} \rho_lk \sum_{LM} \Gaunt_{ik}^{LM} \Gaunt_{jl}^{LM} [S_{ikjl}^L - tS{ikjl}^L}] where S and tS are Slater-like integrals given by 1) S_{ijkl}^L = dfrac{4\pi}{2L+1} \iint u_i(1)u_j(1) u_k(2) u_l(2) \dfrac{r_<^L/}{r_>^{L+1}} d1d2. 1) tS_{ijkl}^L = dfrac{4\pi}{2L+1} \iint [u_i(1)u_j(1)+ tq_{ij}^L g^L(1)] [u_k(2)u_l(2)+ tq_{kl}^L g^L(2)] \dfrac{r_<^L/}{r_>^{L+1}} d1d2. tq_{ij}^L is defined in terms of q_{ij}^L via: q_{ij]^{LM} = tq_{ij}^L \Gaunt_{ij}^{LM}
SOURCE
1274 subroutine paw_dijhf(ndij,cplex_dij,qphase,lmn2_size_max,my_natom,ntypat,Pawtab,Pawrad,Pawang,Pawrhoij,& 1275 & sigx_dij,pawprtvol) 1276 1277 implicit none 1278 1279 !Arguments ------------------------------------ 1280 !scalars 1281 integer,intent(in) :: pawprtvol,ndij,cplex_dij,lmn2_size_max,my_natom,ntypat,qphase 1282 type(pawang_type),intent(in) :: Pawang 1283 !arrays 1284 real(dp),target,intent(out) :: sigx_dij(cplex_dij*lmn2_size_max,ndij,my_natom) !TODO use ragged arrays pawij? 1285 type(pawtab_type),intent(in) :: Pawtab(ntypat) 1286 type(pawrad_type),intent(in) :: Pawrad(ntypat) 1287 type(pawrhoij_type),intent(in) :: Pawrhoij(my_natom) 1288 1289 !Local variables --------------------------------------- 1290 !scalars 1291 integer,parameter :: cplex=1 ! FIXME preliminary implementation 1292 integer :: cplex_rhoij,iatom,iq,iq0_dij,iq0_rhoij,itypat,lmn_size,lmn2_size,ispden,nspden,ln2_size 1293 integer :: lm2_size !,isppol ln_size, 1294 integer :: irhoij,jrhoij 1295 integer :: rho_lmn !,rho_klm,rho_kln,rho_lmin,rho_lmax,rho_iln,rho_jln 1296 integer :: klmn 1297 integer :: i_lmn,j_lmn,k_lmn,l_lmn 1298 integer :: which_intg,l_max,opt_l 1299 real(dp) :: ro,slt_ikjl,slt_iljk 1300 !character(len=500) :: msg 1301 !arrays 1302 integer :: opt_l_index(0,0),pack2ij(0) 1303 real(dp), ABI_CONTIGUOUS pointer :: sigx_atm(:,:) 1304 type(slatrad_t),allocatable :: Slatrad4(:) 1305 1306 ! ************************************************************************* 1307 1308 DBG_ENTER("COLL") 1309 1310 ABI_CHECK(ndij/=4,"ndij=4 not coded") 1311 ABI_CHECK(cplex_dij==1,"cplex_dij/=2 not coded") 1312 ABI_CHECK(lmn2_size_max==MAXVAL(Pawtab(:)%lmn2_size),"Wrong lmn2_size_max") 1313 1314 if (my_natom>0) then 1315 if (pawrhoij(1)%qphase<cplex) then 1316 ABI_BUG('Must have pawrhoij()%qphase >= cplex !') 1317 end if 1318 end if 1319 1320 sigx_dij=zero 1321 1322 do iatom=1,my_natom 1323 itypat =Pawrhoij(iatom)%itypat 1324 lmn_size =Pawtab(itypat)%lmn_size 1325 lmn2_size=Pawtab(itypat)%lmn2_size 1326 l_max =(Pawtab(itypat)%l_size+1)/2 1327 lm2_size = (l_max**2)*(l_max**2+1)/2 1328 cplex_rhoij=Pawrhoij(iatom)%cplex_rhoij 1329 !write(std_out,*)"in atom ",iatom,"lm2_size=",lm2_size 1330 1331 ! Calculate Slater integral for this atom type. 1332 ! TODO obviously these tables should be stored in Pawtab! 1333 ln2_size = Pawtab(itypat)%ij_size 1334 ABI_MALLOC(Slatrad4,(ln2_size*(ln2_size+1)/2)) 1335 which_intg=3 1336 call slatrad_init(Slatrad4,which_intg,ln2_size,Pawrad(itypat),Pawtab(itypat)) 1337 1338 sigx_atm => sigx_dij(:,:,iatom) 1339 1340 ! Loop over phase exp(iqr) phase real/imaginary part, if any 1341 do iq=1,qphase 1342 !First loop: we store the real part in dij(1 -> lmn2_size) 1343 !2nd loop: we store the imaginary part in dij(lmn2_size+1 -> 2*lmn2_size) 1344 iq0_dij=merge(0,cplex_dij*lmn2_size,iq==1) 1345 iq0_rhoij=merge(0,cplex_rhoij*lmn2_size,iq==1) 1346 1347 ! * Loop over spin components. 1348 nspden=ndij 1349 do ispden=1,ndij 1350 ! 1351 ! ============================================================ 1352 ! ==== Summing over the non-zero lk channels of \rho_{lk} ==== 1353 ! ============================================================ 1354 jrhoij=1+iq0_rhoij 1355 do irhoij=1,pawrhoij(iatom)%nrhoijsel 1356 rho_lmn=pawrhoij(iatom)%rhoijselect(irhoij) 1357 1358 ! check wheter rho_lmin is consistent with the Indexing used in slatrad 1359 !rho_klm =pawtab(itypat)%indklmn(1,rho_lmn) 1360 !rho_kln =pawtab(itypat)%indklmn(2,rho_lmn) 1361 !rho_lmin=pawtab(itypat)%indklmn(3,rho_lmn) 1362 !rho_lmax=pawtab(itypat)%indklmn(4,rho_lmn) 1363 1364 ! Retrieve rhoij for this ispden. 1365 if (nspden/=2) then 1366 ro=pawrhoij(iatom)%rhoijp(jrhoij,ispden) 1367 else 1368 ABI_ERROR("Recheck this part") 1369 if (ispden==1) then 1370 ro=pawrhoij(iatom)%rhoijp(jrhoij,1) + pawrhoij(iatom)%rhoijp(jrhoij,2) 1371 else if (ispden==2) then 1372 ro=pawrhoij(iatom)%rhoijp(jrhoij,1) 1373 end if 1374 end if 1375 ! 1376 ! Avoid double-counting the diagonal of rho. 1377 ro=ro*pawtab(itypat)%dltij(rho_lmn)*half 1378 1379 call klmn2ijlmn(rho_lmn,lmn_size,k_lmn,l_lmn) 1380 1381 ! Loop over the upper triangle of the D_{ij) matrix and accumulate: 1382 ! sum_\lk rho_\kl [ \Phi_{ikjl} + \Phi_{iljk} - \Phihat_{ikjl} - \Phihat_{iljk} ] 1383 do klmn=1,lmn2_size 1384 ! Calculate the indices in the Slatrad4 structure. 1385 call klmn2ijlmn(klmn,lmn_size,i_lmn,j_lmn) 1386 1387 ! My formula 1388 slt_ikjl = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,k_lmn,j_lmn,l_lmn) 1389 slt_iljk = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,l_lmn,j_lmn,k_lmn) 1390 1391 !slt_ikjl = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,k_lmn,l_lmn,j_lmn) 1392 !slt_iljk = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,l_lmn,k_lmn,j_lmn) 1393 !slt_iljk = slt_ikjl 1394 1395 sigx_atm(klmn+iq0_dij,ispden) = sigx_atm(klmn,ispden) + ro * (slt_ikjl + slt_iljk) 1396 end do ! klmn 1397 1398 jrhoij=jrhoij+cplex_rhoij 1399 end do ! irhoij 1400 end do ! iq 1401 end do ! ispden 1402 1403 if (ABS(pawprtvol)>=1) then ! * Print values 1404 call wrtout(std_out," ************** Dij Fock ************ ",'COLL') 1405 opt_l=-1 1406 call pawio_print_ij(std_out,sigx_atm(:,1),lmn2_size,cplex_dij,lmn_size,opt_l,opt_l_index,0,pawprtvol,pack2ij,-one,1) 1407 end if 1408 1409 call slatrad_free(Slatrad4) 1410 ABI_FREE(Slatrad4) 1411 end do ! iatom 1412 1413 ! Factor half cancels in the derivation wrt rho_ij. 1414 sigx_dij = - sigx_dij 1415 1416 DBG_EXIT("COLL") 1417 1418 end subroutine paw_dijhf
m_paw_slater/paw_mkdijexc_core [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
paw_mkdijexc_core
FUNCTION
Driver routine to calculate the onsite matrix element of the Fock operator between two all-electron partial waves.
INPUTS
ndij=Usually ndij=nspden, except for spin-orbit (where ndij=nspinor**2) cplex_dij=1 if dijexc_core is real, 2 if they are complex lmn2_size_max=Max Number of (klmn) channels over type of atoms. Cryst<crystal_t>=Structure describing the crystal structure and its symmmetries. Pawtab(ntypat)<pawtab_type>=paw tabulated starting data Pawrad(ntypat)<pawrad_type>=paw radial mesh and related data pawprtvol=Flags governing the verbosity of the output. filpsp(ntypat)=names of the files containing the all-electron core WF
OUTPUT
dijexc_core(cplex_dij*lmn2_size_max,ndij,ntypat)= On-site matrix elements $ \<\phi_i|Sigma_x^\core|\phi_j\> for each type of atom.
SOURCE
831 subroutine paw_mkdijexc_core(ndij,cplex_dij,lmn2_size_max,Cryst,Pawtab,Pawrad,dijexc_core,pawprtvol,filpsp) 832 833 implicit none 834 835 !Arguments ------------------------------------ 836 !scalars 837 integer,intent(in) :: pawprtvol,ndij,cplex_dij,lmn2_size_max 838 type(crystal_t),intent(in) :: Cryst 839 !arrays 840 real(dp),intent(out) :: dijexc_core(cplex_dij*lmn2_size_max,ndij,Cryst%ntypat) !TODO use ragged arrays pawij? 841 character(len=fnlen) :: filpsp(Cryst%ntypat) 842 type(Pawtab_type),target,intent(in) :: Pawtab(Cryst%ntypat) 843 type(Pawrad_type),intent(in) :: Pawrad(Cryst%ntypat) 844 845 !Local variables --------------------------------------- 846 !scalars 847 integer :: itypat,ic,ierr,lmn_size,lmn2_size,ln_size,isppol 848 real(dp) :: rcut 849 character(len=500) :: header,msg 850 character(len=fnlen) :: fcore,string 851 !arrays 852 integer,allocatable :: phi_indln(:,:) 853 real(dp),ABI_CONTIGUOUS pointer :: phi(:,:) 854 real(dp),allocatable :: overlap(:,:) 855 type(atomorb_type),allocatable :: Atm(:) 856 type(Pawrad_type),allocatable :: Radatm(:) 857 858 ! ************************************************************************* 859 860 ABI_MALLOC(Atm,(Cryst%ntypat)) 861 ABI_MALLOC(Radatm,(Cryst%ntypat)) 862 863 ABI_CHECK(ndij==1 ,"spinor+HF not available") 864 ABI_CHECK(cplex_dij==1,"spinor+HF not available") 865 ABI_CHECK(lmn2_size_max==MAXVAL(Pawtab(:)%lmn2_size),"Wrong lmn2_size_max") 866 867 !allocate(dijexc_core(cplex_dij*lmn2_size_max,ndij,Cryst%ntypat)) !TODO use ragged arrays pawij? 868 dijexc_core=zero 869 870 do itypat=1,Cryst%ntypat 871 872 ! Read core orbitals for this atom type. 873 string = filpsp(itypat) 874 fcore = "CORE_"//TRIM(basename(string)) 875 ic = INDEX (TRIM(string), "/" , back=.TRUE.) ! if string is a path, prepend path to fcore. 876 if (ic>0 .and. ic<LEN_TRIM(string)) fcore = filpsp(itypat)(1:ic)//TRIM(fcore) 877 878 rcut=Pawtab(itypat)%rpaw 879 call init_atomorb(Atm(itypat),Radatm(itypat),rcut,fcore,pawprtvol,ierr) 880 881 if (ierr/=0) then 882 msg = " Error reading core orbitals from file: "//TRIM(fcore) 883 ABI_ERROR(msg) 884 end if 885 write(header,'(a,i4,a)')" === Atom type = ",itypat," === " 886 call print_atomorb(Atm(itypat),header,unit=std_out,prtvol=pawprtvol) 887 ! 888 ! * Calculate $ \<\phi_i|Sigma_x^\core|\phi_j\> $ for this atom type. 889 lmn_size = Pawtab(itypat)%lmn_size 890 lmn2_size = Pawtab(itypat)%lmn2_size 891 892 call paw_sigxcore(cplex_dij,lmn2_size,ndij,& 893 & Pawrad(itypat),Pawtab(itypat),Atm(itypat),Radatm(itypat),dijexc_core(1:lmn2_size,:,itypat)) 894 895 ln_size = Pawtab(itypat)%basis_size 896 phi => Pawtab(itypat)%phi 897 898 ABI_MALLOC(phi_indln,(2,ln_size)) 899 call make_indln(lmn_size,ln_size,Pawtab(itypat)%indlmn(:,:),phi_indln) 900 901 ABI_MALLOC(overlap,(Atm(itypat)%ln_size,ln_size)) 902 isppol=1 ! hardcoded 903 call get_overlap(Atm(itypat),Radatm(itypat),Pawrad(itypat),isppol,ln_size,phi,phi_indln,overlap) 904 905 ABI_FREE(phi_indln) 906 ABI_FREE(overlap) 907 end do ! ntypat 908 909 ! Free memory 910 call pawrad_free(Radatm) 911 do itypat=1,Cryst%ntypat 912 call destroy_atomorb(Atm(itypat)) 913 end do 914 915 ABI_FREE(Atm) 916 ABI_FREE(Radatm) 917 918 end subroutine paw_mkdijexc_core
m_paw_slater/paw_sigxcore [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
paw_sigxcore
FUNCTION
Calculate the integrals: \dfrac{4\pi}{2L+1} \int \phi_{\ni\li}(1) orb_{nl}(1) \dfrac{r_<^L}{r_>^{L+1}} orb_{nl}(2) \phi_{\nj\lj} d1d2!! for given (in,il) and (jn,jl) as a function of (nc,lc) and L = |il-jl|, |il-jl|+2, ..., |il+il|
INPUTS
cplex_dij=1 if dijexc_core is real, 2 if they are complex lmn2_size=Number of (klmn) channels ndij=Usually ndij=nspden, except for spin-orbit (where ndij=nspinor**2) Pawtab<pawtab_type>=paw tabulated starting data Atm<atomorb_type>=Structure containing core orbitals Atmrad<pawrad_type>=The radial mesh for core orbitals
OUTPUT
dijexc_core(cplex_dij*lmn2_size,ndij)
SOURCE
693 subroutine paw_sigxcore(cplex_dij,lmn2_size,ndij,Pawrad,Pawtab,Atm,Atmrad,dijexc_core) 694 695 implicit none 696 697 !Arguments ------------------------------------ 698 !scalars 699 integer,intent(in) :: lmn2_size,cplex_dij,ndij 700 !arrays 701 real(dp),intent(out) :: dijexc_core(cplex_dij*lmn2_size,ndij) 702 type(atomorb_type),intent(in) :: Atm 703 type(pawrad_type),intent(in) :: Atmrad 704 type(pawrad_type),intent(in) :: Pawrad 705 type(pawtab_type),target,intent(in) :: Pawtab 706 707 !Local variables --------------------------------------- 708 !scalars 709 integer :: ilnc,ilc,lnc_size,l_max 710 integer :: lm2_size,ln_size,ln2_size,lmn_size 711 integer :: lm_size,klmn,kln,klm 712 integer :: lc_max,ilsl,isgg,israd,opt_l,pawprtvol 713 real(dp) :: tmp,sgg,intgrl 714 !character(len=500) :: msg 715 !arrays 716 integer :: opt_l_index(0,0),pack2ij(0) 717 integer,allocatable :: kln2ln(:,:),klm2lm(:,:) 718 integer, pointer :: indklmn(:,:),indlmn(:,:) 719 type(slatang_cshell_t),allocatable :: Slatang3l(:) 720 type(slatrad_cshell_t),allocatable :: Slatrad3l(:) 721 722 ! ************************************************************************* 723 724 ! * Consistency check 725 ABI_CHECK(cplex_dij==1,"cplex_dij must be 1") 726 727 ABI_CHECK(ndij==1,"ndij must be 1") 728 729 ABI_CHECK(lmn2_size==Pawtab%lmn2_size,"Wrong lmn2_size") 730 731 lmn_size = Pawtab%lmn_size 732 ln_size = Pawtab%basis_size 733 ln2_size = Pawtab%ij_size 734 l_max = (Pawtab%l_size-1)/2 +1 735 lm_size = l_max**2 736 lm2_size = lm_size*(lm_size+1)/2 737 738 indlmn => Pawtab%indlmn(1:6,1:lmn_size) 739 indklmn => Pawtab%indklmn(1:8,1:lmn2_size) 740 741 ! * Setup of useful tables. 742 ABI_MALLOC(kln2ln,(6,ln2_size)) 743 call make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln) 744 745 ABI_MALLOC(klm2lm,(6,lm2_size)) 746 call make_klm2lm(lmn_size,lmn2_size,lm2_size,indlmn,indklmn,klm2lm) 747 748 ! * Integrate angular part. 749 lnc_size = Atm%ln_size 750 lc_max = Atm%l_max 751 752 ABI_MALLOC(Slatang3l,(lm2_size)) 753 call slatang_cshell_init(Slatang3l,l_max,lm2_size,lc_max,klm2lm) 754 755 ABI_FREE(klm2lm) 756 757 ! * Integrate radial part. 758 ABI_MALLOC(Slatrad3l,(ln2_size)) 759 760 call slatrad_cshell_init(Slatrad3l,ln2_size,Pawrad,Pawtab,Atm,Atmrad) 761 762 ! === Calculate matrix elements of Sigma_x^core === 763 ! * $<\phi_i|\Sigma_x^\core|\phi_j>$ 764 dijexc_core = zero 765 do klmn=1,lmn2_size 766 klm = Pawtab%indklmn(1,klmn) 767 kln = Pawtab%indklmn(2,klmn) 768 ! 769 ! * Summing over (lc,nc) and lslat 770 tmp = zero 771 if (Slatang3l(klm)%nsggsel >0) then 772 do ilnc=1,Atm%ln_size 773 ilc = 1+Atm%indln(1,ilnc) 774 do ilsl=1,Slatang3l(klm)%lslat_max !FIXME check this 775 !do ilsl=Slatang3l(klm)%lslat_min,Slatang3l(klm)%lslat_max 776 isgg = Slatang3l(klm)%sggselect(ilsl,ilc) 777 israd = Slatrad3l(kln)%rlphic_select(ilsl,ilnc) 778 if (isgg>0 .and. israd>0) then 779 sgg = Slatang3l(klm)%sgg(isgg) 780 intgrl = Slatrad3l(kln)%rlphic_int(israd) 781 tmp = tmp + intgrl*sgg 782 end if 783 end do 784 end do 785 end if 786 787 dijexc_core(klmn,1) = -tmp ! Store results. 788 end do 789 790 ! * Print values 791 call wrtout(std_out," ************** Dij Fock_core ************ ",'COLL') 792 opt_l=-1; pawprtvol=-1 793 call pawio_print_ij(std_out,dijexc_core(:,1),lmn2_size,cplex_dij,lmn_size,opt_l,opt_l_index,0,pawprtvol,pack2ij,-one,1) 794 795 ! * Free memory. 796 ABI_FREE(kln2ln) 797 call slatang_cshell_free(Slatang3l) 798 ABI_FREE(Slatang3l) 799 call slatrad_cshell_free(Slatrad3l) 800 ABI_FREE(Slatrad3l) 801 802 end subroutine paw_sigxcore
m_paw_slater/slat_intg [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slat_intg
FUNCTION
Helper function returning the slater integral \int_\Omega \phi_i(1)\phi_j(1) \dfrac{1}{|1-2|} \phi_k(2)\phi_l(2) d1d2
INPUTS
SOURCE
1496 function slat_intg(Slatrad4,Pawtab,Pawang,i_lmn,j_lmn,k_lmn,l_lmn) 1497 1498 implicit none 1499 1500 !Arguments ------------------------------------ 1501 !scalars 1502 integer,intent(in) :: i_lmn,j_lmn,k_lmn,l_lmn 1503 real(dp) :: slat_intg 1504 type(pawtab_type),intent(in) :: Pawtab 1505 type(pawang_type),intent(in) :: Pawang 1506 !arrays 1507 type(slatrad_t),intent(in) :: Slatrad4(:) 1508 1509 !Local variables------------------------------- 1510 !scalars 1511 integer :: ij_lmn,kl_lmn,kl_ln,ij_lm,kl_lm,ilsum,ij_ln 1512 integer :: isel,slt_idx 1513 integer :: iln,jln,kln,lln,ii 1514 real(dp) :: sltL_ijkl,angintL_ijkl 1515 !character(len=500) :: msg 1516 1517 !************************************************************************ 1518 1519 ! The lmn packed indices for (ij) and (kl). 1520 if (j_lmn>=i_lmn) then 1521 ij_lmn = i_lmn + j_lmn*(j_lmn-1)/2 1522 else 1523 ij_lmn = j_lmn + i_lmn*(i_lmn-1)/2 1524 end if 1525 1526 if (l_lmn>=k_lmn) then 1527 kl_lmn = k_lmn + l_lmn*(l_lmn-1)/2 1528 else 1529 kl_lmn = l_lmn + k_lmn*(k_lmn-1)/2 1530 end if 1531 ! 1532 ! The lm indices for (ij) and (kl) in packed storage. 1533 ij_lm = pawtab%indklmn(1,ij_lmn) 1534 ij_ln = pawtab%indklmn(2,ij_lmn) 1535 1536 kl_lm = pawtab%indklmn(1,kl_lmn) 1537 kl_ln = pawtab%indklmn(2,kl_lmn) 1538 ! 1539 ! The index of (ijkl) in the Slatrad4 database. 1540 if (kl_ln>=ij_ln) then 1541 slt_idx = ij_ln +kl_ln*(kl_ln-1)/2 1542 else 1543 slt_idx = kl_ln +ij_ln*(ij_ln-1)/2 1544 end if 1545 1546 !BEGIN DEBUG 1547 iln = Slatrad4(slt_idx)%iln 1548 jln = Slatrad4(slt_idx)%jln 1549 kln = Slatrad4(slt_idx)%kln 1550 lln = Slatrad4(slt_idx)%lln 1551 1552 ii = kln + lln*(lln-1)/2 1553 if (slt_idx /= (iln + jln*(jln-1)/2 + ii*(ii-1)/2 )) then 1554 write(std_out,*)"slt_idx, iln, jln, kln, lln",slt_idx, iln, jln, kln, lln 1555 ABI_BUG("Check indices") 1556 end if 1557 !END DEBUG 1558 ! 1559 ! Calculate the integral by summing over ilsum. 1560 slat_intg=zero 1561 if (Slatrad4(slt_idx)%nintgl>0) then 1562 do ilsum=Slatrad4(slt_idx)%lslat_min,Slatrad4(slt_idx)%lslat_max 1563 !% do ilsum=Slatrad4(slt_idx)%lslat_min,Slatrad4(slt_idx)%lslat_max,2 1564 isel = Slatrad4(slt_idx)%intgl_select(ilsum) 1565 if (isel/=0) then 1566 sltL_ijkl = Slatrad4(slt_idx)%intgl(isel) 1567 angintL_ijkl = summ_2gaunt(Pawang,ij_lm,kl_lm,ilsum) 1568 slat_intg = slat_intg + sltL_ijkl * angintL_ijkl 1569 end if 1570 end do 1571 end if 1572 1573 end function slat_intg
m_paw_slater/slatang_cshell_free [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatang_cshell_free
FUNCTION
Free the dynamic memory allocated in a structure of type slatang_cshell_t
SIDE EFFECTS
Slatang3l(lm2_size) <type(slatang_cshell_t)> = Object containing radial integrals
SOURCE
406 subroutine slatang_cshell_free(Slatang3l) 407 408 implicit none 409 410 !Arguments ------------------------------------ 411 !scalars 412 type(slatang_cshell_t),intent(inout) :: Slatang3l(:) 413 414 !Local variables------------------------------- 415 integer :: ii 416 ! ********************************************************************* 417 418 !@slatang_cshell_t 419 do ii=1,SIZE(Slatang3l) 420 if (allocated(Slatang3l(ii)%sggselect)) then 421 ABI_FREE(Slatang3l(ii)%sggselect) 422 end if 423 if (allocated(Slatang3l(ii)%sgg)) then 424 ABI_FREE(Slatang3l(ii)%sgg) 425 end if 426 end do 427 428 end subroutine slatang_cshell_free
m_paw_slater/slatang_cshell_init [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatang_cshell_init
FUNCTION
Initialize the structure slatrad_cshell_t containing radial integrals, see below.
INPUTS
l_max= max. value of ang. momentum l+1; Gaunt coeffs up to [(2*l_max-1,m),(l_max,m),(l_max,m)] are computed lc_max=Max Lc+1 for core states used to contrusct \Sigma_x^\core. lm2_size=Number of symmetrix elements in the (l,m) basis set. NB: lm2_size = (l_max**2)*(l_max**2+1)/2. klm2lm(6,lm2_size)=Table giving il, jl ,im, jm, ilm and jlm for each klm=(ilm,jlm) where ilm=(il,im) and ilm<=jlm. NB: klm2lm is an application and not a bijection.
OUTPUT
Slatang3l(lm2_size) <type(slatang_cshell_t)> = Object storing : $ F^{ilsl,ilc}_{klm} = sum_{msl,mc} <li mi|lsl msl;lc mc> <lsl msl;lc mc|lj mj> $ where klm = runs over the upper triangle of the ((il,im),(jl,jm)) matrix. ilc runs from 1 up to lc_max and |li-lc| <= lsl <= |li+lc|
NOTES
Selection rules for F 1) mi = mj 2) In the case of closed shells, one sums for all possible mc"s values from -lc up to +lc. In this particular case, one can use the symmetry properties of Clebsch-Gordan coefficients to show that F is non null only if li==lj. In particular, F can be rewritten as: $ F^{ilsl,ilc}_{klm} = \delta{li,lj}\delta{mi,mj} \times \Gaunt^{lsl,0}_{lc,0;li,0} \sqrt{ \dfrac{(2*lc+1) (2*lsl+1)}{4\pi*(2*li+1)} } $
SOURCE
253 subroutine slatang_cshell_init(Slatang3l,l_max,lm2_size,lc_max,klm2lm) 254 255 implicit none 256 257 !Arguments ------------------------------------ 258 !scalars 259 integer,intent(in) :: l_max,lc_max,lm2_size 260 !arrays 261 integer,intent(in) :: klm2lm(6,lm2_size) 262 type(slatang_cshell_t),intent(out) :: Slatang3l(lm2_size) 263 264 !Local variables------------------------------- 265 !scalars 266 integer :: ilm,ilm0,jlm,lgnt_max,ngnt,ilsl,ilc,lc,ilm0c,lsl 267 integer :: klm_ci,ilm0sl,li,il,jl,im,jm,ig000 268 integer :: klm,k0lm_i,k0lm_j,k0lm_c,nsggsel,lslat_max,lslat_min 269 real(dp) :: dum 270 !arrays 271 integer,allocatable :: gntselect(:,:) 272 real(dp),allocatable :: realgnt(:),tmp_sgg(:) 273 real(dp),allocatable :: g000(:,:,:) 274 275 ! ************************************************************************* 276 277 !@slatang_cshell_t 278 279 ! * Calculate $\Gaunt^{lsl,msl}_{lc,mc;li,mi}$ 280 lgnt_max = MAX(l_max,lc_max) 281 ABI_MALLOC( realgnt,((2*lgnt_max-1)**2*(lgnt_max)**4)) 282 ABI_MALLOC(gntselect,((2*lgnt_max-1)**2, lgnt_max**2*(lgnt_max**2+1)/2)) 283 284 call realgaunt(lgnt_max,ngnt,gntselect,realgnt) 285 286 ! Below we need $\Gaunt_{lsl,0}_{lc,0;li,0}$ 287 ABI_MALLOC(g000,(2*lgnt_max-1,lc_max,l_max)) 288 g000 = zero 289 290 do ilsl=1,2*lgnt_max-1 291 lsl = ilsl-1 292 ilm0sl = 1+lsl**2+lsl 293 do il=1,l_max 294 li = il-1 295 ilm0 = 1+li**2+li 296 k0lm_i = ilm0 *(ilm0-1)/2 297 do ilc=1,lc_max 298 lc = ilc-1 299 ilm0c = 1+lc**2+lc 300 k0lm_c= ilm0c * (ilm0c-1)/2 301 if (ilm0c > ilm0) then 302 klm_ci = k0lm_c + ilm0 303 else 304 klm_ci = k0lm_i + ilm0c 305 end if 306 ig000 = gntselect(ilm0sl,klm_ci) ! Index of $\Gaunt_{lsl,0}_{lc,0;li,0}$ 307 if (ig000 > 0) g000(ilsl,ilc,il)=realgnt(ig000) 308 end do 309 end do 310 end do 311 312 ABI_FREE(realgnt) 313 ABI_FREE(gntselect) 314 315 ! === Loop over klm channels in packed form === 316 do klm=1,lm2_size 317 il = klm2lm(1,klm); im = klm2lm(3,klm) 318 jl = klm2lm(2,klm); jm = klm2lm(4,klm) 319 320 nsggsel=0 321 lslat_min = 1 !FIXME find better way 322 lslat_max = il+lc_max-1 323 324 Slatang3l(klm)%lslat_min = lslat_min 325 Slatang3l(klm)%lslat_max = lslat_max 326 Slatang3l(klm)%lc_max = lc_max 327 328 ABI_MALLOC(tmp_sgg,(lslat_max*lc_max)) 329 tmp_sgg = zero 330 331 ! === Calculate F^{lsl,lc}_{li,mi;lj,mj} === 332 ! * Selection rule: mi = mj and li==lj 333 if (im == jm .and. il==jl) then 334 li = il-1 335 ilm = klm2lm(5,klm); k0lm_i = ilm *(ilm -1)/2 336 jlm = klm2lm(6,klm); k0lm_j = jlm *(jlm -1)/2 337 338 ABI_MALLOC(Slatang3l(klm)%sggselect,(lslat_max,lc_max)) 339 Slatang3l(klm)%sggselect = 0 340 341 do ilsl=lslat_min,lslat_max 342 !% do ilsl=lslat_min,lslat_max,2 343 lsl = ilsl-1 344 do ilc=1,lc_max 345 lc = ilc-1 346 dum = SQRT( (two*lc+1)*(two*lsl+1) / (four_pi*(two*li+1)) ) * g000(ilsl,ilc,il) 347 if (ABS(dum)>=tol12) then ! * Store results and progressive index if non null. 348 nsggsel = nsggsel + 1 349 tmp_sgg(nsggsel) = dum 350 Slatang3l(klm)%sggselect(ilsl,ilc) = nsggsel 351 end if 352 end do !ilc 353 end do !ilsl 354 end if ! Selection rule li=lj and mi == mj 355 ! 356 ! * Finalize the object. 357 Slatang3l(klm)%nsggsel = nsggsel 358 if (nsggsel > 0) then 359 ABI_MALLOC(Slatang3l(klm)%sgg,(nsggsel)) 360 Slatang3l(klm)%sgg = tmp_sgg(1:nsggsel) 361 end if 362 ABI_FREE(tmp_sgg) 363 end do !klm 364 365 ABI_FREE(g000) 366 367 #if 0 368 ! Debugging code 369 do klm=1,lm2_size 370 if (Slatang3l(klm)%nsggsel>0) then 371 il = klm2lm(1,klm) 372 jl = klm2lm(2,klm) 373 im = klm2lm(3,klm) 374 jm = klm2lm(4,klm) 375 write(std_out,*)"--for li, mi",il-1,im-il 376 lslat_min = Slatang3l(klm)%lslat_min 377 lslat_max = Slatang3l(klm)%lslat_max 378 379 do ilc=1,lc_max 380 do ilsl=lslat_min,lslat_max 381 ii = Slatang3l(klm)%sggselect(ilsl,ilc) 382 if (ii>0) write(std_out,*)" lc, lslat, sgg",ilc-1,ilsl-1,Slatang3l(klm)%sgg(ii) 383 end do 384 end do 385 end if 386 end do 387 #endif 388 389 end subroutine slatang_cshell_init
m_paw_slater/slatang_cshell_t [ Types ]
[ Top ] [ m_paw_slater ] [ Types ]
NAME
slatang_cshell_t
FUNCTION
Object used to store: $ F^{lsl,lc}_{li,lj,mi,mj} = sum_{msl mc} \<li mi|lsl msl;lc mc\> \<lsl msl;lc mc| lj mj\> $ This (less general) type of radial integral is needed to evaluate the Exchange term generated by a closed-shell atom. In the equation, (lc,mc) are the set of angular quantum number associated to (closed) core electrons while (lsl,msl) comes from the expansion of 1/|r1-r2|. Since the F is invariant under exchange of i and j we use an array of structures indexed by kln = (iln,jln) in packed form.
SOURCE
137 type, public :: slatang_cshell_t 138 139 integer :: nsggsel 140 ! Number of non null matrix elements 141 142 integer :: lslat_max 143 ! Max l+1 in the expansion of the Coulomb potential 144 145 integer :: lslat_min 146 ! Min l+1 in the expansion of the Coulomb potential 147 148 integer :: lc_max 149 ! Max l+1 for orbitals summed over (usually core orbitals) 150 151 integer,allocatable :: sggselect(:,:) 152 ! sggselect(lslat_max,lc_max) 153 ! Index of non null sgg, 0 if sgg is zero by symmetry. 154 155 real(dp),allocatable :: sgg(:) 156 ! sgg(nsggsel) 157 ! Non null matrix elements in packed form. The index is given by sggselect. 158 159 end type slatang_cshell_t 160 161 public :: slatang_cshell_init ! Creation method for slatang_cshell_t. 162 public :: slatang_cshell_free ! Destruction method for the slatang_cshell_t.
m_paw_slater/slatrad_cshell_free [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatrad_cshell_free
FUNCTION
Free the dynamic memory allocated in a structure of type slatrad_cshell_t
SIDE EFFECTS
Slatrad3l(ln2_size) <type(slarad3l_type)> = Object containing radial integrals
SOURCE
445 subroutine slatrad_cshell_free(Slatrad3l) 446 447 implicit none 448 449 !Arguments ------------------------------------ 450 !scalars 451 type(slatrad_cshell_t),intent(inout) :: Slatrad3l(:) 452 453 !Local variables------------------------------- 454 integer :: ii 455 ! ********************************************************************* 456 457 !@slatrad_cshell_t 458 do ii=1,SIZE(Slatrad3l) 459 if (allocated(Slatrad3l(ii)%rlphic_select)) then 460 ABI_FREE(Slatrad3l(ii)%rlphic_select) 461 end if 462 if (allocated(Slatrad3l(ii)%rlphic_int)) then 463 ABI_FREE(Slatrad3l(ii)%rlphic_int) 464 end if 465 end do 466 467 end subroutine slatrad_cshell_free
m_paw_slater/slatrad_cshell_init [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatrad_cshell_init
FUNCTION
Initialize the structure storing the radial part of Slater"s integrals.
INPUTS
ln2_size=Number of symmetrical (l,n) channels Pawrad<pawrad_type>=paw radial mesh and related data Pawtab<pawtab_type>=paw tabulated starting data Atm<atomorb_type>=Object containing core orbitals. Atmrad<pawrad_type>=paw radial mesh and related data for the atom. kln_mask
OUTPUT
Slatrad3l<slatrad_cshell_t>=The object completely initialized.
SOURCE
492 subroutine slatrad_cshell_init(Slatrad3l,ln2_size,Pawrad,Pawtab,Atm,Atmrad,kln_mask) 493 494 implicit none 495 496 !Arguments ------------------------------------ 497 !scalars 498 integer,intent(in) :: ln2_size 499 !arrays 500 integer,optional,intent(in) :: kln_mask(ln2_size) 501 type(atomorb_type),intent(in) :: Atm 502 type(pawrad_type),target,intent(in) :: Atmrad,Pawrad 503 type(pawtab_type),target,intent(in) :: Pawtab 504 type(slatrad_cshell_t),intent(out) :: Slatrad3l(ln2_size) 505 506 !Local variables --------------------------------------- 507 !scalars 508 integer :: cmesh_size,dmesh_size 509 integer :: il,iln,ilnc,isl,in,jl,jln,jn,kln,ll,lnc_size 510 integer :: lslat_max,lslat_min,lc_max,nintg 511 integer :: lmn_size,lmn2_size,do_spline,ln_size,whichdenser,isppol 512 real(dp) :: intg,intg1,ybcbeg,ybcend 513 logical :: hasameq 514 !arrays 515 integer,allocatable :: kln2ln(:,:) 516 integer, pointer :: indklmn(:,:),indlmn(:,:) 517 real(dp),allocatable :: ff1(:),ff2(:),tmp_integrals(:) 518 real(dp),ABI_CONTIGUOUS pointer :: phi_i(:),phi_j(:) 519 real(dp),allocatable,target :: phi_spl(:,:) 520 real(dp),allocatable :: der(:),ypp(:) 521 real(dp),ABI_CONTIGUOUS pointer :: crad(:),drad(:),phi_in(:) 522 523 ! ************************************************************************* 524 525 ABI_CHECK(ln2_size==Pawtab%ij_size,"Wrong ln2_size") 526 if (PRESENT(kln_mask)) then 527 ABI_ERROR("kln_mask is present") 528 end if 529 530 !@slatrad_cshell_t 531 lmn_size = Pawtab%lmn_size 532 lmn2_size = Pawtab%lmn2_size 533 ln_size = Pawtab%basis_size 534 535 lnc_size = Atm%ln_size 536 lc_max = Atm%l_max 537 538 call pawrad_isame(Atmrad,Pawrad,hasameq,whichdenser) 539 540 do_spline=0 541 if (.not.hasameq) then 542 do_spline=1 543 if (whichdenser/=1) & 544 & ABI_COMMENT("Pawrad is denser than Atmrad!") 545 else 546 ABI_CHECK(whichdenser==1,"Pawrad is denser than Atmrad!") 547 end if 548 549 dmesh_size = Atmrad%mesh_size 550 cmesh_size = Pawtab%mesh_size 551 552 drad => Atmrad%rad(1:dmesh_size) 553 crad => Pawrad%rad(1:cmesh_size) 554 555 ! === Spline valence basis set onto core mesh (natural spline) === 556 if (do_spline==1) then 557 ABI_COMMENT("Splining in init_slatrad3l") 558 ABI_MALLOC(phi_spl,(dmesh_size,ln_size)) 559 ABI_MALLOC(der,(cmesh_size)) 560 ABI_MALLOC(ypp,(cmesh_size)) 561 562 do iln=1,ln_size 563 phi_in => Pawtab%phi(:,iln) 564 ypp(:) = zero; ybcbeg = zero; ybcend = zero 565 call spline(crad,phi_in,cmesh_size,ybcbeg,ybcend,ypp) 566 call splint(cmesh_size,crad,phi_in,ypp,dmesh_size,drad,phi_spl(:,iln)) 567 end do 568 569 ABI_FREE(der) 570 ABI_FREE(ypp) 571 end if 572 573 indlmn => Pawtab%indlmn(1:6,1:lmn_size) 574 indklmn => Pawtab%indklmn(1:8,1:lmn2_size) 575 576 ABI_MALLOC(kln2ln,(6,ln2_size)) 577 578 call make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln) 579 580 ABI_MALLOC(ff1,(dmesh_size)) 581 ABI_MALLOC(ff2,(dmesh_size)) 582 583 ! * Loop over the upper triangle of the [(in,il), (jn,il)] matrix. 584 ABI_CHECK(Atm%nsppol==1,"nsppol==2 not tested") 585 586 do isppol=1,Atm%nsppol 587 do kln=1,ln2_size 588 il = kln2ln(1,kln) 589 jl = kln2ln(2,kln) 590 in = kln2ln(3,kln) 591 jn = kln2ln(4,kln) 592 iln = kln2ln(5,kln) 593 jln = kln2ln(6,kln) 594 595 lslat_max = MAX((il+lc_max),(jl+lc_max)) - 1 ! These are indices, not l-values. 596 !lslat_min = MIN(ABS(il-lc_max),ABS(jl-lc_max)) + 1 597 lslat_min = 1 ! FIXME find better way 598 599 Slatrad3l(kln)%lnc_size = lnc_size 600 Slatrad3l(kln)%lslat_min = lslat_min 601 Slatrad3l(kln)%lslat_max = lslat_max 602 603 Slatrad3l(kln)%nrlphic_int = 0 604 605 ABI_MALLOC(Slatrad3l(kln)%rlphic_select,(lslat_max,lnc_size)) 606 Slatrad3l(kln)%rlphic_select(:,:) = 0 607 608 !if (PRESENT(kln_mask)) then !FIXME THIS IS WRONG, move it below in case 609 ! if (kln_mask(kln)==0) CYCLE 610 !end if 611 612 if (do_spline==1) then 613 ABI_COMMENT("Performing spline of valence phi") 614 phi_i => phi_spl(:,iln) 615 phi_j => phi_spl(:,jln) 616 else 617 phi_i => Pawtab%phi(:,iln) 618 phi_j => Pawtab%phi(:,jln) 619 end if 620 621 ! * Loop over (n,l) channels for Atom orbitals 622 ABI_MALLOC(tmp_integrals,(lslat_max*lnc_size)) 623 tmp_integrals(:) = zero 624 nintg=0 625 626 do ilnc=1,lnc_size 627 ! phicore => Atm%phi(:,ilnc,isppol) 628 ff1 = phi_i * Atm%phi(:,ilnc,isppol) 629 ff2 = phi_j * Atm%phi(:,ilnc,isppol) 630 do isl=lslat_min,lslat_max ! L coming from Coulomb expansion 631 ll = isl-1 632 call calc_slatradl(ll,dmesh_size,ff2,ff1,Atmrad,intg1) 633 call calc_slatradl(ll,dmesh_size,ff1,ff2,Atmrad,intg) 634 635 !call calc_slatradl(ll,cmesh_size,ff2,ff1,Pawrad,intg1) 636 !call calc_slatradl(ll,cmesh_size,ff1,ff2,Pawrad,intg) 637 638 if (ABS(intg1-intg)>tol6) write(std_out,*)"DEBUG ",ll,il,in,jl,jn,intg1,intg 639 640 ! * Store results 641 if (ABS(intg)>=tol12) then 642 nintg = nintg +1 643 Slatrad3l(kln)%rlphic_select(isl,ilnc) = nintg 644 tmp_integrals(nintg) = intg 645 end if 646 end do !ll 647 end do ! ilnc 648 649 ! Finalize the object 650 Slatrad3l(kln)%nrlphic_int = nintg 651 ABI_MALLOC(Slatrad3l(kln)%rlphic_int,(nintg)) 652 if (nintg>0) Slatrad3l(kln)%rlphic_int(:) = tmp_integrals(1:nintg) 653 654 ABI_FREE(tmp_integrals) 655 end do !kln 656 end do !isppol 657 658 ABI_FREE(ff1) 659 ABI_FREE(ff2) 660 ABI_FREE(kln2ln) 661 662 if (do_spline==1) then 663 ABI_FREE(phi_spl) 664 end if 665 666 end subroutine slatrad_cshell_init
m_paw_slater/slatrad_cshell_t [ Types ]
[ Top ] [ m_paw_slater ] [ Types ]
NAME
slatrad_cshell_t
FUNCTION
Object used to store the set of radial integrals: $ \dfrac{4\pi}{2L+1} \times \int \phi_{\ni\li}(1) \phic_{\nc\lc}(1) \dfrac{r_<^L}{r_>^{L+1}} \phic_{\nc\lc}(2) \phi_{\nj\lj} d1d2 $ for given (in,il) and (jn,jl) as a function L = |il-jl|, |il-jl|+2, ..., |il+il| and ilnc = (lc,nc). This (less general) type of radial integral is needed to evaluate the Exchange term generated by a closed-shell atom. In the equation, (\nc,\lc) are the set of angular quantum number associated to core electrons while (lsl,msl) comes from the expansion of 1/|r1-r2|. Since the F is invariant under exchange of i and j we use an array of structures indexed by kln = (iln,jln) in packed form.
SOURCE
186 type,public :: slatrad_cshell_t 187 188 integer :: lnc_size 189 ! Number of (n,l) channel for core orbitals. 190 191 integer :: lslat_max 192 ! Max l+1 in the expansion of the Coulomb potential 193 194 integer :: lslat_min 195 ! Min l+1 in the expansion of the Coulomb potential 196 197 integer :: nrlphic_int 198 ! The number of non-zero integrals stored in rlphic_int. 199 200 integer,allocatable :: rlphic_select(:,:) 201 ! rlphic_select(lslat_max,lnc_size) TODO should be allocated with lslat_min:lslat_max 202 ! Index of the non-zero integrals in rlphic_int, 0 if rlphic_int has not been 203 ! calculated thanks to selection rules coming from the angular integration. 204 205 real(dp),allocatable :: rlphic_int(:) 206 ! rlphic_int(1:nrlphic_int) 207 ! The integrals: 208 ! \dfrac{4\pi}{2L+1} \int \phi_{\ni\li}(1) \phic_{nc\lc}(1) \dfrac{r_<^L}{r_>^{L+1}} \phic_{nc\lc}(2) \phi_{\nj\lj} d1d2 209 ! for given (in,il) and (jn,jl) as a function L = |il-jl|, |il-jl|+2, ..., |il+il| and ilnc = (lc,nc). 210 211 end type slatrad_cshell_t 212 213 214 CONTAINS !========================================================================================
m_paw_slater/slatrad_free_0D [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatrad_free_0D
FUNCTION
Free the dynamic memory allocated in a structure of type slatrad_t
SOURCE
932 subroutine slatrad_free_0D(Slatrad) 933 934 implicit none 935 936 !Arguments ------------------------------------ 937 !scalars 938 type(slatrad_t),intent(inout) :: Slatrad 939 940 ! ********************************************************************* 941 942 !@slatrad_t 943 if (allocated(Slatrad%intgl_select)) then 944 ABI_FREE(Slatrad%intgl_select) 945 end if 946 if (allocated(Slatrad%intgl)) then 947 ABI_FREE(Slatrad%intgl) 948 end if 949 950 end subroutine slatrad_free_0D
m_paw_slater/slatrad_free_1D [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatrad_free_1D
FUNCTION
Free the dynamic memory allocated in a structure of type slatrad_t
SOURCE
964 subroutine slatrad_free_1D(Slatrad) 965 966 implicit none 967 968 !Arguments ------------------------------------ 969 !scalars 970 type(slatrad_t),intent(inout) :: Slatrad(:) 971 972 !Local variables------------------------------- 973 integer :: ii 974 ! ********************************************************************* 975 976 do ii=1,SIZE(Slatrad) 977 call slatrad_free_0D(Slatrad(ii)) 978 end do 979 980 end subroutine slatrad_free_1D
m_paw_slater/slatrad_init [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
slatrad_init
FUNCTION
Initialize the structure storing the radial part of Slater"s integrals.
INPUTS
which_intg= Option defining what kind of integrals have to be calculated: -- 1 for Slater integral of AE partial waves only. A = \frac{4\pi}{2L+1} \int u_i(1) u_j(1) \frac{r_<^L}{r_^{L+1}} u_k(2)u_l(2) d1d2 -- 2 for Slater integral of (AE-PS) partial waves B = \frac{4\pi}{2L+1} \int u_i(1) u_j(1) \frac{r_<^L}{r_^{L+1}} u_k(2) u_l(2) d1d2 - \frac{4\pi}{2L+1} \int tu_i(1) tu_j(1) \frac{r_<^L}{r_^{L+1}} tu_k(2) tu_l(2) d1d2 -- 3 for Slater integral of (AE-PS-compensation charges) C = A - \frac{4\pi}{2L+1} \int [tu_i(1) tu_j(1) + qhat^L_\ij r_1^2 g^L(1) ] \frac{r_<^L}{r_^{L+1}}* [tu_k(2) tu_l(2) + qhat^L_\kl r_2^2 g^L(2) ] d1d2 where u = \phi/r; tu = \tphi/r; and qhat^L_\ij are related to q^\LM_\ij via q^\LM_\ij = \Gaunt_\ij^\LM qhat^L_\ij => qhat^L\ij = \int (u_i*u_j - tu_i*tu_j) r^L ln2_size=Number of symmetrical (l,n) channels for this atom type type. Pawrad<pawrad_type>=paw radial mesh and related data Pawtab<pawtab_type>=paw tabulated starting data
OUTPUT
Slatrad4<slatrad_t>=The object completely initialized.
NOTES
Slater integrals S_ij are invariant under exchange of the indices, but the results reported by calc_slatradl are not due to numerical roundoff errors (err < 10^-9). However this does not cause any problem since only the upper triangle of the S_ij matrix is stored and used in the other routines.
SOURCE
1024 subroutine slatrad_init(Slatrad4,which_intg,ln2_size,Pawrad,Pawtab) 1025 1026 implicit none 1027 1028 !Arguments ------------------------------------ 1029 !scalars 1030 integer,intent(in) :: ln2_size,which_intg 1031 !arrays 1032 type(pawrad_type),target,intent(in) :: Pawrad 1033 type(pawtab_type),target,intent(in) :: Pawtab 1034 type(slatrad_t),intent(out) :: Slatrad4(ln2_size*(ln2_size+1)/2) 1035 1036 !Local variables --------------------------------------- 1037 !scalars 1038 integer :: mesh_size,il,iln,isl,in,jl,jln,jn,sln1,sln2,l_slat 1039 integer :: kn,kl,ln,ll,kln,lln,lslat_max,lslat_min,nintgl 1040 integer :: lmn_size,lmn2_size,ln_size,slt_idx 1041 real(dp) :: ae_intg,ps_intg,pshat_intg,intg,tqij_L,tqkl_L !intg1 1042 character(len=500) :: msg 1043 !arrays 1044 integer,allocatable :: kln2ln(:,:) 1045 integer, pointer :: indklmn(:,:),indlmn(:,:) 1046 real(dp),allocatable :: uiuj(:),ukul(:),tuituj(:),tuktul(:),tuituj_tqgl(:),tuktul_tqgl(:) 1047 real(dp),allocatable :: tmp_integrals(:),ff(:) 1048 real(dp),ABI_CONTIGUOUS pointer :: phi_i(:),phi_j(:),phi_k(:),phi_l(:) 1049 real(dp),ABI_CONTIGUOUS pointer :: tphi_i(:),tphi_j(:),tphi_k(:),tphi_l(:) 1050 real(dp),ABI_CONTIGUOUS pointer :: shapefunc(:),rad(:) 1051 1052 ! ************************************************************************* 1053 1054 DBG_ENTER("COLL") 1055 1056 ABI_CHECK(ln2_size==Pawtab%ij_size,"Wrong ln2_size") 1057 1058 if ( ALL(which_intg /= (/1,2,3/)) ) then 1059 write(msg,'(a,i0)')"Wrong value for which_intg: ",which_intg 1060 ABI_ERROR(msg) 1061 end if 1062 1063 !@slatrad_t 1064 lmn_size = Pawtab%lmn_size 1065 lmn2_size = Pawtab%lmn2_size 1066 ln_size = Pawtab%basis_size 1067 mesh_size = Pawtab%mesh_size 1068 ! 1069 ! Useful table for looping. 1070 indlmn => Pawtab%indlmn(1:6,1:lmn_size) 1071 indklmn => Pawtab%indklmn(1:8,1:lmn2_size) 1072 1073 ABI_MALLOC(kln2ln,(6,ln2_size)) 1074 call make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln) 1075 1076 ABI_MALLOC(uiuj,(mesh_size)) 1077 ABI_MALLOC(ukul,(mesh_size)) 1078 ABI_MALLOC(ff,(mesh_size)) 1079 ABI_MALLOC(tuituj,(mesh_size)) 1080 ABI_MALLOC(tuktul,(mesh_size)) 1081 ABI_MALLOC(tuituj_tqgl,(mesh_size)) 1082 ABI_MALLOC(tuktul_tqgl,(mesh_size)) 1083 rad => Pawrad%rad 1084 ! 1085 ! * Loop over (k,l) channels in packed form. 1086 do sln2=1,ln2_size 1087 kl = kln2ln(1,sln2) 1088 ll = kln2ln(2,sln2) 1089 kn = kln2ln(3,sln2) 1090 ln = kln2ln(4,sln2) 1091 kln = kln2ln(5,sln2) 1092 lln = kln2ln(6,sln2) 1093 !write(std_out,*)"sln2, kln, lln",sln2,kln,lln 1094 1095 phi_k => Pawtab%phi (:,kln) 1096 tphi_k => Pawtab%tphi(:,kln) 1097 1098 phi_l => Pawtab%phi (:,lln) 1099 tphi_l => Pawtab%tphi(:,lln) 1100 ! 1101 ! * Loop over (i,j) channels in packed form AND only for the upper triangle of sln2, sln1 1102 do sln1=1,sln2 1103 il = kln2ln(1,sln1) 1104 jl = kln2ln(2,sln1) 1105 in = kln2ln(3,sln1) 1106 jn = kln2ln(4,sln1) 1107 iln = kln2ln(5,sln1) 1108 jln = kln2ln(6,sln1) 1109 !write(std_out,*)"sln1, iln, jln",sln1,iln,jln 1110 1111 slt_idx = sln1 + sln2*(sln2-1)/2 ! index for packed storage. 1112 1113 phi_i => Pawtab%phi (:,iln) 1114 tphi_i => Pawtab%tphi(:,iln) 1115 1116 phi_j => Pawtab%phi (:,jln) 1117 tphi_j => Pawtab%tphi(:,jln) 1118 1119 lslat_min = MAX(ABS(il-jl),ABS(kl-ll)) + 1 ! We use indices not l-values. 1120 lslat_max = MIN((il+jl),(kl+ll)) - 1 1121 1122 !lslat_min = MIN(ABS(il-jl),ABS(kl-ll)) + 1 1123 !lslat_max = MAX((il+jl),(kl+ll)) - 1 1124 1125 Slatrad4(slt_idx)%lslat_min = lslat_min 1126 Slatrad4(slt_idx)%lslat_max = lslat_max 1127 1128 Slatrad4(slt_idx)%iln = iln 1129 Slatrad4(slt_idx)%jln = jln 1130 Slatrad4(slt_idx)%kln = kln 1131 Slatrad4(slt_idx)%lln = lln 1132 1133 ABI_MALLOC(Slatrad4(slt_idx)%intgl_select,(lslat_min:lslat_max)) 1134 Slatrad4(slt_idx)%intgl_select(:) = 0 1135 Slatrad4(slt_idx)%nintgl = 0 1136 1137 if (lslat_min > lslat_max) then 1138 ! e.g. (1 2) (1 1). Due to angular selection rules, this integral do not contribue 1139 !write(std_out,*)"lslat_min, lslat_max",lslat_min,lslat_max 1140 !write(std_out,*)"il,jl,kl,ll",il,jl,kl,ll 1141 !ABI_ERROR("") 1142 ABI_MALLOC(Slatrad4(slt_idx)%intgl,(0)) 1143 CYCLE 1144 end if 1145 1146 uiuj = phi_i * phi_j ! The AE part. 1147 ukul = phi_k * phi_l 1148 tuituj = tphi_i * tphi_j ! The pseudized part. 1149 tuktul = tphi_k * tphi_l 1150 ! 1151 ! Calculate L-depedent integrals where L come from the expansion the Coulomb interaction. 1152 ABI_MALLOC(tmp_integrals,(MAX(lslat_min,lslat_max))) 1153 tmp_integrals=zero 1154 nintgl=0 1155 1156 do isl=lslat_min,lslat_max 1157 !do isl=lslat_min,lslat_max,2 ! TODO Here I can reduce the number of iterations using a step of 2. 1158 l_slat = isl-1 1159 call calc_slatradl(l_slat,mesh_size,uiuj,ukul,Pawrad,ae_intg) 1160 intg = ae_intg 1161 1162 #if 0 1163 call calc_slatradl(l_slat,mesh_size,ukul,uiuj,Pawrad,intg1) 1164 if (ABS(intg1-ae_intg)>tol12) then 1165 write(msg,'(a,es16.8)')"s_ij and s_ij differ by ",intg1-ae_intg 1166 ABI_WARNING(msg) 1167 end if 1168 #endif 1169 if (which_intg == 2) then ! Subtract the pseudo part. 1170 call calc_slatradl(l_slat,mesh_size,tuituj,tuktul,Pawrad,ps_intg) 1171 intg = intg - ps_intg 1172 1173 else if (which_intg == 3) then ! Subtract (pseudo + compensation charges) 1174 ! 1175 ! Evaluate tqij_L and tqkl_L (without M-dependent part). 1176 ff(1)=zero 1177 ff(2:mesh_size)=(pawtab%phiphj(2:mesh_size,sln1)-pawtab%tphitphj(2:mesh_size,sln1))*rad(2:mesh_size)**l_slat 1178 if (l_slat==0.and.kl==1.and.ll==1) then 1179 call pawrad_deducer0(ff,mesh_size,pawrad) 1180 end if 1181 call simp_gen(tqij_L,ff,pawrad) 1182 1183 ff(1)=zero 1184 ff(2:mesh_size)=(pawtab%phiphj(2:mesh_size,sln2)-pawtab%tphitphj(2:mesh_size,sln2))*rad(2:mesh_size)**l_slat 1185 if (l_slat==0.and.il==1.and.jl==1) then 1186 call pawrad_deducer0(ff,mesh_size,pawrad) 1187 end if 1188 call simp_gen(tqkl_L,ff,pawrad) 1189 1190 shapefunc => Pawtab%shapefunc(:,isl) ! Recheck this part, in particular the convention 1191 tuituj_tqgl = tuituj + tqij_L * shapefunc * rad**2 1192 tuktul_tqgl = tuktul + tqkl_L * shapefunc * rad**2 1193 1194 call calc_slatradl(l_slat,mesh_size,tuituj_tqgl,tuktul_tqgl,Pawrad,pshat_intg) 1195 intg = intg - pshat_intg 1196 end if 1197 ! 1198 ! * Store results 1199 if (ABS(intg)>=tol12) then 1200 nintgl = nintgl +1 1201 Slatrad4(slt_idx)%intgl_select(isl) = nintgl 1202 tmp_integrals(nintgl) = intg 1203 end if 1204 end do !isl 1205 ! 1206 ! Finalize the object. 1207 Slatrad4(slt_idx)%nintgl = nintgl 1208 ABI_MALLOC(Slatrad4(slt_idx)%intgl,(nintgl)) 1209 if (nintgl>0) Slatrad4(slt_idx)%intgl(:) = tmp_integrals(1:nintgl) 1210 ABI_FREE(tmp_integrals) 1211 end do !sln1 1212 end do !sln2 1213 ! 1214 ! Free memory 1215 ABI_FREE(kln2ln) 1216 ABI_FREE(uiuj) 1217 ABI_FREE(ukul) 1218 ABI_FREE(tuituj) 1219 ABI_FREE(tuktul) 1220 ABI_FREE(ff) 1221 ABI_FREE(tuituj_tqgl) 1222 ABI_FREE(tuktul_tqgl) 1223 1224 DBG_EXIT("COLL") 1225 1226 end subroutine slatrad_init
m_paw_slater/slatrad_t [ Types ]
[ Top ] [ m_paw_slater ] [ Types ]
NAME
slatrad_t
FUNCTION
Object used to store radial integrals of the form. $ F_{ijkl}^L = \dfrac{4\pi}{2L+1} \int u_i(1) u_j(1) \dfrac{r_<^L}{r_>^{L+1}} u_k(2) u_l(2) d1d2 $ for a given quadruple (i,j,k,l) as a function L \in [L_min, L_max]. i,j,k,l are shorthand indices for (nn,ll) quantum numbers.
NOTES
Basic symmetry properties: 1) invariant under the exchange (i<-->j) and (k<-->l). 2) invariant under the exchange (i,j) <--> (k,l). Memory saving is achieved by storing the upper triangle of the (ij) (kl) matrix and, for each dimension, only the upper triangle of the two matrices (iln,jln) (kln,lln). Some matrix elements will never contribute to <ij|1/|1-2||kl> due to selection rules introduced by the integration of the angular part.
SOURCE
84 type,public :: slatrad_t 85 86 integer :: iln,jln,kln,lln 87 ! The (l,n) indices associated to the partial waves. 88 89 integer :: lslat_min 90 ! Min l+1 in the expansion of the Coulomb potential. 91 92 integer :: lslat_max 93 ! Max l+1 in the expansion of the Coulomb potential. 94 95 integer :: nintgl 96 ! The number of non-zero integrals stored in intgl. 97 98 integer,allocatable :: intgl_select(:) 99 ! intgl_select(lslat_min:lslat_max) 100 ! Index of the non-zero integrals in intgl, 0 if intgl has not been 101 ! calculated thanks to selection rules coming from the angular integration. 102 103 real(dp),allocatable :: intgl(:) 104 ! intgl(1:nintgl) 105 ! The integrals: 106 ! \dfrac{4\pi}{2L+1} \int \phi_{\ni\li}(1) \phi_{\nj\lj}(1) \dfrac{r_<^L}{r_>^{L+1}} \phi_{\nk\lk}(2) \phi_{\nl\ll} d1d2 107 ! for given (i,j,k,l) as a function L = |il-jl|, |il-jl|+2, ..., |il+il| and ilnc = (lc,nc). 108 109 end type slatrad_t 110 111 public :: slatrad_init ! Creation method 112 public :: slatrad_free ! Free memory
m_paw_slater/summ_2gaunt [ Functions ]
[ Top ] [ m_paw_slater ] [ Functions ]
NAME
summ_2gaunt
FUNCTION
Helper function returning \sum_M G_{ij}^{LM} G_{kl}^{LM}
INPUTS
ij_lm=index of (i_lm,j_lm) element in packed form. kl_lm=index of (k_lm,l_lm) element in packed form. ll_idx=Index for L (thus L+1). Pawang<type(pawang_type)>=paw angular mesh and related data
SOURCE
1438 function summ_2gaunt(Pawang,ij_lm,kl_lm,ll_idx) 1439 1440 implicit none 1441 1442 !Arguments ------------------------------------ 1443 !scalars 1444 integer,intent(in) :: ij_lm,kl_lm,ll_idx 1445 real(dp) :: summ_2gaunt 1446 type(pawang_type),intent(in) :: Pawang 1447 !arrays 1448 1449 !Local variables------------------------------- 1450 !scalars 1451 integer :: ignt1,ignt2,idx_LM,max_klm,mm,ii,ll 1452 character(len=500) :: msg 1453 1454 !************************************************************************ 1455 1456 ! FIXME: size of gntselect depends on pawxcdev! 1457 ! Consistency check on input arguments. 1458 max_klm = pawang%l_max**2*(pawang%l_max**2+1)/2 1459 if (ij_lm>max_klm.or.kl_lm>max_klm.or.ij_lm<1.or.kl_lm<1.or.& 1460 & ll_idx>pawang%l_size_max.or.ll_idx<1) then 1461 write(msg,'(a,3i0)')"Wrong indices, check pawxcdev ",ij_lm,kl_lm,ll_idx 1462 ABI_ERROR(msg) 1463 end if 1464 1465 ll = ll_idx-1 1466 summ_2gaunt=zero; ii=0 1467 do mm=-ll,ll 1468 idx_LM = 1 + ll**2 + ll + mm 1469 ignt1 = Pawang%gntselect(idx_LM,ij_lm) 1470 ignt2 = Pawang%gntselect(idx_LM,kl_lm) 1471 if (ignt1>0 .and. ignt2>0) then 1472 summ_2gaunt = summ_2gaunt + Pawang%realgnt(ignt1)*Pawang%realgnt(ignt2) 1473 ii=ii+1 1474 write(std_out,'(a,4(i2,1x),f8.5,i2)')"ll, mm, ij_lm, kl_lm: ",ll,mm,ij_lm,kl_lm,summ_2gaunt,ii 1475 if (ii/=1) ABI_WARNING("ii>1") 1476 end if 1477 end do 1478 1479 end function summ_2gaunt