From 6e93f1f6bb91523e37847d4f1eb597477d65176f Mon Sep 17 00:00:00 2001 From: EnzoMonino Date: Mon, 10 Jul 2023 14:50:16 +0200 Subject: [PATCH] add dynamic BSE2@GW --- input/methods | 4 +- src/GW/BSE2_GW_A_matrix_dynamic.f90 | 95 +++++++++++++++++++ .../Bethe_Salpeter_dynamic_perturbation.f90 | 10 +- src/GW/GW_phBSE.f90 | 10 +- src/GW/XBSE.f90 | 15 +-- 5 files changed, 119 insertions(+), 15 deletions(-) create mode 100644 src/GW/BSE2_GW_A_matrix_dynamic.f90 diff --git a/input/methods b/input/methods index 237541d..1a68790 100644 --- a/input/methods +++ b/input/methods @@ -11,9 +11,9 @@ # RPA* RPAx* crRPA ppRPA F F F F # G0F2* evGF2* qsGF2* G0F3 evGF3 - T F F F F + F F F F F # G0W0* evGW* qsGW* SRG-qsGW ufG0W0 ufGW - F F F F F F + T F F F F F # G0T0pp evGTpp qsGTpp G0T0eh evGTeh qsGTeh F F F F F F # * unrestricted version available diff --git a/src/GW/BSE2_GW_A_matrix_dynamic.f90 b/src/GW/BSE2_GW_A_matrix_dynamic.f90 new file mode 100644 index 0000000..b4e1051 --- /dev/null +++ b/src/GW/BSE2_GW_A_matrix_dynamic.f90 @@ -0,0 +1,95 @@ +subroutine BSE2_GW_A_matrix_dynamic(eta,nBas,nC,nO,nV,nR,nS,eGW,W,OmBSE,A_dyn,ZA_dyn) + +! Compute the dynamic part of the Bethe-Salpeter equation matrices + + implicit none + include 'parameters.h' + +! Input variables + + integer,intent(in) :: nBas,nC,nO,nV,nR,nS + double precision,intent(in) :: eta + double precision,intent(in) :: W(nBas,nBas,nBas,nBas) + double precision,intent(in) :: eGW(nBas) + double precision,intent(in) :: OmBSE + +! Local variables + + double precision :: num,dem + double precision :: eps + integer :: i,j,a,b,ia,jb,kc,k,c,l,d + +! Output variables + + double precision,intent(out) :: A_dyn(nS,nS) + double precision,intent(out) :: ZA_dyn(nS,nS) + +! Initialization + +! A_dyn(:,:) = 0d0 +! ZA_dyn(:,:) = 0d0 + +! Number of poles taken into account + +! Build dynamic A matrix + + jb = 0 +!$omp parallel do default(private) shared(A_dyn,ZA_dyn,OmBSE,W,num,dem,eGW,nO,nBas,eta,nC,nR) + do j=nC+1,nO + do b=nO+1,nBas-nR + jb = (b-nO) + (j-1)*(nBas-nO) + + ia = 0 + do i=nC+1,nO + do a=nO+1,nBas-nR + ia = (a-nO) + (i-1)*(nBas-nO) + + do k=nC+1,nO + do c=nO+1,nBas-nR + + dem = OmBSE - eGW(a) - eGW(c) + eGW(k) + eGW(j) + num = 2d0*W(j,k,i,c)*W(a,c,b,k) + + A_dyn(ia,jb) = A_dyn(ia,jb) - num*dem/(dem**2 + eta**2) + ZA_dyn(ia,jb) = ZA_dyn(ia,jb) + num*(dem**2 - eta**2)/(dem**2 + eta**2)**2 + + dem = OmBSE + eGW(i) - eGW(c) + eGW(k) - eGW(b) + num = 2d0*W(j,c,i,k)*W(a,k,b,c) + + A_dyn(ia,jb) = A_dyn(ia,jb) - num*dem/(dem**2 + eta**2) + ZA_dyn(ia,jb) = ZA_dyn(ia,jb) + num*(dem**2 - eta**2)/(dem**2 + eta**2)**2 + + enddo + enddo + + do c=nO+1,nBas-nR + do d=nO+1,nBas-nR + + dem = OmBSE + eGW(i) + eGW(j) - eGW(c) - eGW(d) + num = 2d0*W(a,j,c,d)*W(c,d,i,b) + + A_dyn(ia,jb) = A_dyn(ia,jb) + num*dem/(dem**2 + eta**2) + ZA_dyn(ia,jb) = ZA_dyn(ia,jb) - num*(dem**2 - eta**2)/(dem**2 + eta**2)**2 + + enddo + enddo + + do k=nC+1,nO + do l=nC+1,nO + + dem = OmBSE - eGW(a) - eGW(b) + eGW(k) + eGW(l) + num = 2d0*W(a,j,k,l)*W(k,l,i,b) + + A_dyn(ia,jb) = A_dyn(ia,jb) + num*dem/(dem**2 + eta**2) + ZA_dyn(ia,jb) = ZA_dyn(ia,jb) - num*(dem**2 - eta**2)/(dem**2 + eta**2)**2 + + end do + end do + + enddo + enddo + enddo + enddo +!$omp end parallel do + +end subroutine BSE2_GW_A_matrix_dynamic diff --git a/src/GW/Bethe_Salpeter_dynamic_perturbation.f90 b/src/GW/Bethe_Salpeter_dynamic_perturbation.f90 index a8fddcf..e12df44 100644 --- a/src/GW/Bethe_Salpeter_dynamic_perturbation.f90 +++ b/src/GW/Bethe_Salpeter_dynamic_perturbation.f90 @@ -1,4 +1,5 @@ -subroutine Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eGW,dipole_int,OmRPA,rho_RPA,OmBSE,XpY,XmY) +subroutine Bethe_Salpeter_dynamic_perturbation(BSE2,dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eGW, & +dipole_int,OmRPA,rho_RPA,OmBSE,XpY,XmY,W,A_stat) ! Compute dynamical effects via perturbation theory for BSE @@ -7,6 +8,7 @@ subroutine Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,e ! Input variables + logical,intent(in) :: BSE2 logical,intent(in) :: dTDA double precision,intent(in) :: eta integer,intent(in) :: nBas @@ -24,6 +26,8 @@ subroutine Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,e double precision,intent(in) :: OmBSE(nS) double precision,intent(in) :: XpY(nS,nS) double precision,intent(in) :: XmY(nS,nS) + double precision,intent(in) :: W(nBas,nBas,nBas,nBas) + double precision,intent(in) :: A_stat(nS,nS) ! Local variables @@ -85,8 +89,10 @@ subroutine Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,e call Bethe_Salpeter_A_matrix_dynamic(eta,nBas,nC,nO,nV,nR,nS,1d0,eGW,OmRPA,rho_RPA,OmBSE(ia),Ap_dyn,ZAp_dyn) +if(BSE2) call BSE2_GW_A_matrix_dynamic(eta,nBas,nC,nO,nV,nR,nS,eGW,W,OmBSE(ia),Ap_dyn,ZAp_dyn,W) + ZDyn(ia) = dot_product(X,matmul(ZAp_dyn,X)) - OmDyn(ia) = dot_product(X,matmul( Ap_dyn,X)) + OmDyn(ia) = dot_product(X,matmul( Ap_dyn - A_stat,X)) else diff --git a/src/GW/GW_phBSE.f90 b/src/GW/GW_phBSE.f90 index 082919c..64b0c0d 100644 --- a/src/GW/GW_phBSE.f90 +++ b/src/GW/GW_phBSE.f90 @@ -119,9 +119,9 @@ subroutine GW_phBSE(BSE2,TDA_W,TDA,dBSE,dTDA,evDyn,singlet,triplet,eta,nBas,nC,n call Bethe_Salpeter_dynamic_perturbation_iterative(dTDA,eta,nBas,nC,nO,nV,nR,nS,eGW,dipole_int,OmRPA,rho_RPA, & OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin)) else - - call Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eGW,dipole_int,OmRPA,rho_RPA, & - OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin)) + + call Bethe_Salpeter_dynamic_perturbation(BSE2,dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eGW,dipole_int,OmRPA,rho_RPA, & + OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin),W(:,:,:,:),KA2_sta) end if end if @@ -159,8 +159,8 @@ subroutine GW_phBSE(BSE2,TDA_W,TDA,dBSE,dTDA,evDyn,singlet,triplet,eta,nBas,nC,n OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin)) else - call Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eGW,dipole_int,OmRPA,rho_RPA, & - OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin)) + call Bethe_Salpeter_dynamic_perturbation(BSE2,dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eGW,dipole_int,OmRPA,rho_RPA, & + OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin),W(:,:,:,:),KA2_sta) end if end if diff --git a/src/GW/XBSE.f90 b/src/GW/XBSE.f90 index 6b4bae0..e027811 100644 --- a/src/GW/XBSE.f90 +++ b/src/GW/XBSE.f90 @@ -45,6 +45,7 @@ subroutine XBSE(TDA_W,TDA,dBSE,dTDA,singlet,triplet,eta,nBas,nC,nO,nV,nR,nS,ERI, double precision,allocatable :: KB_sta(:,:) double precision,allocatable :: W(:,:,:,:) + double precision,allocatable :: KA2_sta(:,:) ! Output variables @@ -52,8 +53,10 @@ subroutine XBSE(TDA_W,TDA,dBSE,dTDA,singlet,triplet,eta,nBas,nC,nO,nV,nR,nS,ERI, ! Memory allocation - allocate(OmRPA(nS),XpY_RPA(nS,nS),XmY_RPA(nS,nS),rho_RPA(nBas,nBas,nS), & - KA_sta(nS,nS),KB_sta(nS,nS),OmBSE(nS,nspin),XpY_BSE(nS,nS,nspin),XmY_BSE(nS,nS,nspin)) + allocate(OmRPA(nS),XpY_RPA(nS,nS),XmY_RPA(nS,nS),rho_RPA(nBas,nBas,nS),KA_sta(nS,nS), & + KB_sta(nS,nS),KA2_sta(nS,nS),OmBSE(nS,nspin),XpY_BSE(nS,nS,nspin),XmY_BSE(nS,nS,nspin)) + + KA2_sta(:,:) = 0d0 !--------------------------------- ! Compute (singlet) RPA screening @@ -92,8 +95,8 @@ subroutine XBSE(TDA_W,TDA,dBSE,dTDA,singlet,triplet,eta,nBas,nC,nO,nV,nR,nS,ERI, if(dBSE) then - call Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eW,dipole_int,OmRPA,rho_RPA, & - OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin)) + call Bethe_Salpeter_dynamic_perturbation(.false.,dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eW,dipole_int,OmRPA,rho_RPA, & + OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin),W(:,:,:,:),KA2_sta) end if end if @@ -123,8 +126,8 @@ subroutine XBSE(TDA_W,TDA,dBSE,dTDA,singlet,triplet,eta,nBas,nC,nO,nV,nR,nS,ERI, ! Compute dynamic correction for BSE via perturbation theory (iterative or renormalized) - call Bethe_Salpeter_dynamic_perturbation(dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eW,dipole_int,OmRPA,rho_RPA, & - OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin)) + call Bethe_Salpeter_dynamic_perturbation(.false.,dTDA,eta,nBas,nC,nO,nV,nR,nS,eW,eW,dipole_int,OmRPA,rho_RPA, & + OmBSE(:,ispin),XpY_BSE(:,:,ispin),XmY_BSE(:,:,ispin),W(:,:,:,:),KA2_sta) end if