! ! Copyright (C) 2002-2008 Quantum ESPRESSO group ! This file is distributed under the terms of the ! GNU General Public License. See the file `License' ! in the root directory of the present distribution, ! or http://www.gnu.org/copyleft/gpl.txt . ! ! Written by Giovanni Bussi ! Adapted to QE by Andrea Ferretti & Layla Martin Samos ! !---------------------------------- MODULE coulomb_vcut_module !---------------------------------- ! IMPLICIT NONE PRIVATE ! ! general purpose parameters ! INTEGER, PARAMETER :: DP=KIND(1.0d0) REAL(DP), PARAMETER :: PI = 3.14159265358979323846_DP REAL(DP), PARAMETER :: TPI = 2.0_DP * pi REAL(DP), PARAMETER :: FPI = 4.0_DP * pi REAL(DP), PARAMETER :: e2 = 2.0_DP REAL(DP), PARAMETER :: eps6 = 1.0E-6_DP ! ! definitions ! TYPE vcut_type REAL(DP) :: a(3,3) REAL(DP) :: b(3,3) REAL(DP) :: a_omega REAL(DP) :: b_omega REAL(DP), POINTER :: corrected(:,:,:) REAL(DP) :: cutoff LOGICAL :: orthorombic END TYPE vcut_type ! PUBLIC :: vcut_type PUBLIC :: vcut_init PUBLIC :: vcut_get PUBLIC :: vcut_spheric_get PUBLIC :: vcut_destroy PUBLIC :: vcut_info CONTAINS !------------------------------------------ SUBROUTINE vcut_init(vcut,a,cutoff) !------------------------------------------ ! TYPE(vcut_type), INTENT(OUT) :: vcut REAL(DP), INTENT(IN) :: a(3,3) REAL(DP), INTENT(IN) :: cutoff INTEGER :: n1,n2,n3 INTEGER :: i1,i2,i3 INTEGER :: ierr REAL(DP) :: q(3) CHARACTER(9) :: subname='vcut_init' REAL(DP) :: mod2a(3) vcut%cutoff=cutoff vcut%a=a vcut%b= TPI * transpose(num_inverse(vcut%a)) vcut%b_omega=num_determinant(vcut%b) vcut%a_omega=num_determinant(vcut%a) ! automatically finds whether the cell is orthorombic or not vcut%orthorombic=.false. ! mod2a=sqrt(sum(vcut%a**2,1)) if(abs(sum(vcut%a(:,1)*vcut%a(:,2)))/(mod2a(1)*mod2a(2)) vcut%cutoff**2 ) CYCLE ! vcut%corrected(i1,i2,i3) = & vcut_formula(q,vcut%a,vcut%b,vcut%a_omega,vcut%orthorombic) ! ENDDO ENDDO ENDDO ! END SUBROUTINE vcut_init !------------------------------------------ SUBROUTINE vcut_info(iun, vcut) !------------------------------------------ ! IMPLICIT NONE ! INTEGER, INTENT(IN) :: iun TYPE(vcut_type), INTENT(IN) :: vcut ! INTEGER :: i, n(3) ! IF ( ASSOCIATED( vcut%corrected ) ) THEN ! DO i = 1, 3 n(i) = ( SIZE( vcut%corrected, i) -1 ) / 2 ENDDO ! WRITE(iun, "( 2x,'Cutoff: ',f6.2,4x,' n grid: ',3i4,/)") vcut%cutoff, n(:) ! ENDIF ! END SUBROUTINE vcut_info !------------------------------------------ SUBROUTINE vcut_destroy(vcut) !------------------------------------------ ! TYPE(vcut_type), INTENT(INOUT) :: vcut INTEGER :: ierr ! DEALLOCATE(vcut%corrected, STAT=ierr) IF ( ierr/=0 ) CALL errore('vcut_destroy','deallocating vcut',ABS(ierr)) ! END SUBROUTINE vcut_destroy !------------------------------------------ FUNCTION vcut_get(vcut,q) RESULT(res) !------------------------------------------ ! TYPE(vcut_type), INTENT(IN) :: vcut REAL(DP), INTENT(IN) :: q(3) REAL(DP) :: res ! REAL(DP) :: i_real(3) INTEGER :: i(3) CHARACTER(8) :: subname='vcut_get' ! i_real=(MATMUL(TRANSPOSE(vcut%a),q))/ TPI i=NINT(i_real) ! ! internal check IF( SUM( (i-i_real)**2 ) > eps6 ) & CALL errore(subname,'q vector out of the grid',10) ! IF( SUM(q**2) > vcut%cutoff**2 ) THEN ! ! usual form of Coulomb potential res = FPI * e2 / SUM(q**2) ! ELSE ! IF( i(1)>ubound(vcut%corrected,1) .OR. i(1)ubound(vcut%corrected,2) .OR. i(2)ubound(vcut%corrected,3) .OR. i(3) 1d-5) then write(0,*) "AHIA",sum((matmul(inv,a)-eye3)**2) write(0,*) "A",a write(0,*) "inv",inv write(0,*)">>", matmul(inv,a) stop end if end function num_inverse function num_determinant(a) result(det) real(dp), intent(in) :: a(3,3) real(dp) :: det det = a(1,1)*a(2,2)*a(3,3) + a(1,2)*a(2,3)*a(3,1) + a(1,3)*a(2,1)*a(3,2) & - a(1,1)*a(2,3)*a(3,2) - a(1,2)*a(2,1)*a(3,3) - a(1,3)*a(2,2)*a(3,1) end function num_determinant !!! end tools from sax !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! END MODULE coulomb_vcut_module