mirror of https://gitlab.com/QEF/q-e.git
525 lines
11 KiB
Fortran
525 lines
11 KiB
Fortran
!
|
|
! Copyright (C) 2008 Simon Binnie
|
|
! 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 .
|
|
!
|
|
!
|
|
!---------------------------------------------------------------------
|
|
PROGRAM casino2upf
|
|
!---------------------------------------------------------------------
|
|
!
|
|
! Convert a pseudopotential written in CASINO tabulated
|
|
! format to unified pseudopotential format
|
|
|
|
IMPLICIT NONE
|
|
CHARACTER(len=256) filein, fileout
|
|
CHARACTER(len=256), ALLOCATABLE:: wavefile(:)
|
|
INTEGER nofiles, i
|
|
|
|
PRINT*, 'CASINO2UPF Converter'
|
|
PRINT*, 'Enter CASINO pp.data filename:'
|
|
|
|
CALL get_file ( filein )
|
|
|
|
PRINT*, 'How many wavefunction *files* are you using?'
|
|
READ(*,*) nofiles
|
|
ALLOCATE(wavefile(nofiles))
|
|
PRINT*, 'Enter wavefunction files, starting with the ground state:'
|
|
DO i=1,nofiles
|
|
CALL get_file ( wavefile(i) )
|
|
OPEN(unit=i,file=wavefile(i),status='old',form='formatted')
|
|
ENDDO
|
|
OPEN(unit=99,file=filein,status='old',form='formatted')
|
|
|
|
CALL read_casino(99,nofiles)
|
|
CLOSE (unit=99)
|
|
DO i=1,nofiles
|
|
CLOSE (i)
|
|
ENDDO
|
|
|
|
! convert variables read from CASINO format into those needed
|
|
! by the upf format - add missing quantities
|
|
|
|
CALL convert_casino
|
|
|
|
fileout=trim(filein)//'.UPF'
|
|
PRINT '(''Output PP file in US format : '',a)', fileout
|
|
|
|
OPEN(unit=2,file=fileout,status='unknown',form='formatted')
|
|
CALL write_upf(2)
|
|
CLOSE (unit=2)
|
|
STOP
|
|
20 CALL errore ('casino2upf', 'Reading pseudo file name ', 1)
|
|
|
|
END PROGRAM casino2upf
|
|
|
|
MODULE casino
|
|
|
|
!
|
|
! All variables read from CASINO file format
|
|
!
|
|
! trailing underscore means that a variable with the same name
|
|
! is used in module 'upf' containing variables to be written
|
|
!
|
|
|
|
|
|
CHARACTER(len=20) :: dft_
|
|
CHARACTER(len=2) :: psd_
|
|
REAL(8) :: zp_
|
|
INTEGER nlc, nnl, lmax_, lloc, nchi, rel_
|
|
LOGICAL :: numeric, bhstype, nlcc_
|
|
REAL(8) :: alpc(2), cc(2), alps(3,0:3), aps(6,0:3)
|
|
REAL(8) :: a_nlcc, b_nlcc, alpha_nlcc
|
|
|
|
REAL(8) :: zmesh, xmin, dx
|
|
REAL(8), ALLOCATABLE:: r_(:), rab_(:)
|
|
INTEGER :: mesh_
|
|
|
|
REAL(8), ALLOCATABLE:: vnl(:,:), rho_atc_(:), rho_at_(:)
|
|
INTEGER, ALLOCATABLE:: lchi_(:), nns_(:)
|
|
REAL(8), ALLOCATABLE:: chi_(:,:), oc_(:)
|
|
|
|
END MODULE casino
|
|
!
|
|
! ----------------------------------------------------------
|
|
SUBROUTINE read_casino(iunps,nofiles)
|
|
! ----------------------------------------------------------
|
|
!
|
|
USE casino
|
|
USE upf , ONLY : els
|
|
USE kinds
|
|
IMPLICIT NONE
|
|
TYPE :: wavfun_list
|
|
INTEGER :: occ,eup,edwn, nquant, lquant
|
|
CHARACTER(len=2) :: label
|
|
#ifdef __STD_F95
|
|
REAL*8, POINTER :: wavefunc(:)
|
|
#else
|
|
REAL*8, ALLOCATABLE :: wavefunc(:)
|
|
#endif
|
|
TYPE (wavfun_list), POINTER :: p
|
|
|
|
END TYPE wavfun_list
|
|
|
|
TYPE (wavfun_list), POINTER :: mhead
|
|
TYPE (wavfun_list), POINTER :: mptr
|
|
TYPE (wavfun_list), POINTER :: mtail
|
|
|
|
INTEGER :: iunps, nofiles
|
|
!
|
|
LOGICAL :: groundstate, found
|
|
CHARACTER(len=2) :: label, rellab
|
|
REAL(DP), PARAMETER :: r_exp=20._dp/1500._dp
|
|
INTEGER :: l, i, ir, nb, gsorbs, j,k,m,tmp, lquant, orbs, nquant
|
|
INTEGER, ALLOCATABLE :: gs(:,:)
|
|
|
|
NULLIFY ( mhead, mptr, mtail )
|
|
dft_ = 'HF' !Hardcoded at the moment should eventually be HF anyway
|
|
|
|
nlc = 0 !These two values are always 0 for numeric pps
|
|
nnl = 0 !so lets just hard code them
|
|
|
|
nlcc_ = .false. !Again these two are alwas false for CASINO pps
|
|
bhstype = .false.
|
|
|
|
|
|
|
|
READ(iunps,'(a2,35x,a2)') rellab, psd_
|
|
READ(iunps,*)
|
|
IF ( rellab == 'DF' ) THEN
|
|
rel_=1
|
|
ELSE
|
|
rel_=0
|
|
ENDIF
|
|
|
|
READ(iunps,*) zmesh,zp_ !Here we are reading zmesh (atomic #) and
|
|
DO i=1,3 !zp_ (pseudo charge)
|
|
READ(iunps,*)
|
|
ENDDO
|
|
READ(iunps,*) lmax_ !reading in lmax
|
|
IF ( zp_<=0d0 ) &
|
|
CALL errore( 'read_casino','Wrong zp ',1 )
|
|
IF ( lmax_>3.or.lmax_<0 ) &
|
|
CALL errore( 'read_casino','Wrong lmax ',1 )
|
|
|
|
lloc=lmax_ !think lloc shoudl always = lmax for this case yes/no ??
|
|
|
|
!
|
|
! compute the radial mesh
|
|
!
|
|
|
|
DO i=1,3
|
|
READ(iunps,*)
|
|
ENDDO
|
|
READ(iunps,*) mesh_ !Reading in total no. of mesh points
|
|
|
|
|
|
ALLOCATE( r_(mesh_))
|
|
ALLOCATE(rab_(mesh_))
|
|
READ(iunps,*)
|
|
DO i=1,mesh_
|
|
READ(iunps,*) r_(i)
|
|
ENDDO
|
|
DO ir = 1, mesh_
|
|
rab_(ir) = r_exp * r_(ir) !hardcoded at the moment
|
|
ENDDO
|
|
|
|
|
|
ALLOCATE(vnl(mesh_,0:lmax_))
|
|
|
|
DO l = 0, lmax_
|
|
READ(iunps, '(a)', err=300)
|
|
READ(iunps, *, err=300) (vnl(ir,l),ir=1,mesh_)
|
|
ENDDO
|
|
|
|
DO l = 0, lmax_
|
|
DO ir = 1, mesh_
|
|
vnl(ir,l) = vnl(ir,l)/r_(ir) !Removing the factor of r CASINO has
|
|
ENDDO
|
|
vnl(1,l) = 0 !correcting for the divide by zero
|
|
ENDDO
|
|
|
|
ALLOCATE(rho_atc_(mesh_))
|
|
IF(nlcc_) THEN
|
|
READ(iunps, *, err=300) ( rho_atc_(ir), ir=1,mesh_ )
|
|
ENDIF
|
|
|
|
!
|
|
! subtract the local part
|
|
!
|
|
|
|
DO l = 0, lmax_
|
|
IF ( l/=lloc ) vnl(:,l) = vnl(:,l) - vnl(:,lloc)
|
|
ENDDO
|
|
|
|
|
|
ALLOCATE(mhead)
|
|
mtail => mhead
|
|
|
|
mptr => mhead
|
|
|
|
NULLIFY(mtail%p)
|
|
groundstate=.true.
|
|
DO j=1,nofiles
|
|
|
|
DO i=1,4
|
|
|
|
READ(j,*)
|
|
ENDDO
|
|
|
|
READ(j,*) orbs
|
|
|
|
IF ( groundstate ) THEN
|
|
|
|
ALLOCATE( gs(orbs,3) )
|
|
|
|
gs = 0
|
|
gsorbs = orbs
|
|
ENDIF
|
|
|
|
DO i=1,2
|
|
READ(j,*)
|
|
ENDDO
|
|
|
|
READ(j,*) mtail%eup, mtail%edwn
|
|
READ(j,*)
|
|
|
|
DO i=1,mtail%eup+mtail%edwn
|
|
READ(j,*) tmp, nquant, lquant
|
|
|
|
IF ( groundstate ) THEN
|
|
found = .true.
|
|
|
|
DO m=1,orbs
|
|
|
|
IF ( (nquant==gs(m,1) .and. lquant==gs(m,2)) ) THEN
|
|
gs(m,3) = gs(m,3) + 1
|
|
exit
|
|
ENDIF
|
|
|
|
found = .false.
|
|
|
|
ENDDO
|
|
|
|
IF (.not. found ) THEN
|
|
|
|
DO m=1,orbs
|
|
|
|
IF ( gs(m,1) == 0 ) THEN
|
|
gs(m,1) = nquant
|
|
gs(m,2) = lquant
|
|
gs(m,3) = 1
|
|
|
|
exit
|
|
ENDIF
|
|
|
|
ENDDO
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDDO
|
|
|
|
READ(j,*)
|
|
READ(j,*)
|
|
|
|
DO i=1,mesh_
|
|
READ(j,*)
|
|
ENDDO
|
|
|
|
DO k=1,orbs
|
|
READ(j,'(13x,a2)', err=300) label
|
|
READ(j,*) tmp, nquant, lquant
|
|
|
|
IF ( .not. groundstate ) THEN
|
|
found = .false.
|
|
|
|
DO m = 1,gsorbs
|
|
|
|
IF ( nquant == gs(m,1) .and. lquant == gs(m,2) ) THEN
|
|
found = .true.
|
|
exit
|
|
ENDIF
|
|
ENDDO
|
|
mptr => mhead
|
|
DO
|
|
IF ( .not. associated(mptr) )exit
|
|
IF ( nquant == mptr%nquant .and. lquant == mptr%lquant ) found = .true.
|
|
mptr =>mptr%p
|
|
ENDDO
|
|
IF ( found ) THEN
|
|
DO i=1,mesh_
|
|
READ(j,*)
|
|
ENDDO
|
|
|
|
CYCLE
|
|
ENDIF
|
|
ENDIF
|
|
#ifdef __STD_F95
|
|
IF ( associated(mtail%wavefunc) ) THEN
|
|
#else
|
|
IF ( allocated(mtail%wavefunc) ) THEN
|
|
#endif
|
|
ALLOCATE(mtail%p)
|
|
mtail=>mtail%p
|
|
NULLIFY(mtail%p)
|
|
ALLOCATE( mtail%wavefunc(mesh_) )
|
|
ELSE
|
|
ALLOCATE( mtail%wavefunc(mesh_) )
|
|
ENDIF
|
|
mtail%label = label
|
|
mtail%nquant = nquant
|
|
mtail%lquant = lquant
|
|
|
|
|
|
READ(j, *, err=300) (mtail%wavefunc(ir),ir=1,mesh_)
|
|
ENDDO
|
|
groundstate = .false.
|
|
ENDDO
|
|
|
|
nchi =0
|
|
mptr => mhead
|
|
DO
|
|
IF ( .not. associated(mptr) )exit
|
|
nchi=nchi+1
|
|
|
|
mptr =>mptr%p
|
|
ENDDO
|
|
|
|
ALLOCATE(lchi_(nchi), els(nchi), nns_(nchi))
|
|
ALLOCATE(oc_(nchi))
|
|
ALLOCATE(chi_(mesh_,nchi))
|
|
oc_ = 0
|
|
|
|
!Sort out the occupation numbers
|
|
DO i=1,gsorbs
|
|
oc_(i)=gs(i,3)
|
|
ENDDO
|
|
DEALLOCATE( gs )
|
|
|
|
i=1
|
|
mptr => mhead
|
|
DO
|
|
IF ( .not. associated(mptr) )exit
|
|
nns_(i) = mptr%nquant
|
|
lchi_(i) = mptr%lquant
|
|
els(i) = mptr%label
|
|
|
|
DO ir=1,mesh_
|
|
|
|
chi_(ir:,i) = mptr%wavefunc(ir)
|
|
ENDDO
|
|
DEALLOCATE( mptr%wavefunc )
|
|
mptr =>mptr%p
|
|
i=i+1
|
|
ENDDO
|
|
|
|
!Clean up the linked list (deallocate it)
|
|
DO
|
|
IF ( .not. associated(mhead) )exit
|
|
mptr => mhead
|
|
mhead => mhead%p
|
|
DEALLOCATE( mptr )
|
|
ENDDO
|
|
|
|
|
|
!
|
|
! compute the atomic charges
|
|
!
|
|
ALLOCATE(rho_at_(mesh_))
|
|
rho_at_(:)=0.d0
|
|
DO nb = 1, nchi
|
|
IF( oc_(nb)/=0.d0) &
|
|
& rho_at_(:) = rho_at_(:) + oc_(nb)*chi_(:,nb)**2
|
|
ENDDO
|
|
! ----------------------------------------------------------
|
|
WRITE (6,'(a)') 'Pseudopotential successfully read'
|
|
! ----------------------------------------------------------
|
|
RETURN
|
|
|
|
300 CALL errore('read_casino','pseudo file is empty or wrong',1)
|
|
|
|
END SUBROUTINE read_casino
|
|
|
|
! ----------------------------------------------------------
|
|
SUBROUTINE convert_casino
|
|
! ----------------------------------------------------------
|
|
USE casino
|
|
USE upf
|
|
USE funct, ONLY : set_dft_from_name, get_iexch, get_icorr, get_igcx, get_igcc
|
|
IMPLICIT NONE
|
|
REAL(8), PARAMETER :: rmax = 10.0d0
|
|
REAL(8), ALLOCATABLE :: aux(:)
|
|
REAL(8) :: vll
|
|
INTEGER :: kkbeta, l, iv, ir, i
|
|
|
|
WRITE(generated, '("From a Trail & Needs tabulated PP for CASINO")')
|
|
WRITE(date_author,'("Author: unknown Generation date: as well")')
|
|
comment = 'Info: automatically converted from CASINO Tabulated format'
|
|
|
|
rel = rel_
|
|
|
|
|
|
rcloc = 0.0d0
|
|
nwfs = nchi
|
|
ALLOCATE( oc(nwfs), epseu(nwfs))
|
|
ALLOCATE(lchi(nwfs), nns(nwfs) )
|
|
ALLOCATE(rcut (nwfs), rcutus (nwfs))
|
|
DO i=1, nwfs
|
|
nns (i) = nns_(i)
|
|
lchi(i) = lchi_(i)
|
|
rcut(i) = 0.0d0
|
|
rcutus(i)= 0.0d0
|
|
oc (i) = oc_(i)
|
|
epseu(i) = 0.0d0
|
|
ENDDO
|
|
DEALLOCATE (lchi_, oc_, nns_)
|
|
|
|
psd = psd_
|
|
pseudotype = 'NC'
|
|
nlcc = nlcc_
|
|
zp = zp_
|
|
etotps = 0.0d0
|
|
ecutrho=0.0d0
|
|
ecutwfc=0.0d0
|
|
IF ( lmax_ == lloc) THEN
|
|
lmax = lmax_-1
|
|
ELSE
|
|
lmax = lmax_
|
|
ENDIF
|
|
nbeta= lmax_
|
|
mesh = mesh_
|
|
ntwfc= nchi
|
|
ALLOCATE( elsw(ntwfc), ocw(ntwfc), lchiw(ntwfc) )
|
|
DO i=1, nchi
|
|
lchiw(i) = lchi(i)
|
|
ocw(i) = oc(i)
|
|
elsw(i) = els(i)
|
|
ENDDO
|
|
CALL set_dft_from_name(dft_)
|
|
iexch = get_iexch()
|
|
icorr = get_icorr()
|
|
igcx = get_igcx()
|
|
igcc = get_igcc()
|
|
|
|
ALLOCATE(rab(mesh))
|
|
ALLOCATE( r(mesh))
|
|
rab = rab_
|
|
r = r_
|
|
|
|
ALLOCATE (rho_atc(mesh))
|
|
rho_atc = rho_atc_
|
|
DEALLOCATE (rho_atc_)
|
|
|
|
ALLOCATE (vloc0(mesh))
|
|
vloc0(:) = vnl(:,lloc)
|
|
|
|
IF (nbeta > 0) THEN
|
|
|
|
ALLOCATE(ikk2(nbeta), lll(nbeta))
|
|
kkbeta=mesh
|
|
DO ir = 1,mesh
|
|
IF ( r(ir) > rmax ) THEN
|
|
kkbeta=ir
|
|
exit
|
|
ENDIF
|
|
ENDDO
|
|
|
|
! make sure kkbeta is odd as required for simpson
|
|
IF(mod(kkbeta,2) == 0) kkbeta=kkbeta-1
|
|
ikk2(:) = kkbeta
|
|
ALLOCATE(aux(kkbeta))
|
|
ALLOCATE(betar(mesh,nbeta))
|
|
ALLOCATE(qfunc(mesh,nbeta,nbeta))
|
|
ALLOCATE(dion(nbeta,nbeta))
|
|
ALLOCATE(qqq (nbeta,nbeta))
|
|
qfunc(:,:,:)=0.0d0
|
|
dion(:,:) =0.d0
|
|
qqq(:,:) =0.d0
|
|
iv=0
|
|
DO i=1,nchi
|
|
l=lchi(i)
|
|
IF (l/=lloc) THEN
|
|
iv=iv+1
|
|
lll(iv)=l
|
|
DO ir=1,kkbeta
|
|
betar(ir,iv)=chi_(ir,i)*vnl(ir,l)
|
|
aux(ir) = chi_(ir,i)**2*vnl(ir,l)
|
|
|
|
ENDDO
|
|
CALL simpson(kkbeta,aux,rab,vll)
|
|
dion(iv,iv) = 1.0d0/vll
|
|
ENDIF
|
|
IF(iv >= nbeta) exit ! skip additional pseudo wfns
|
|
ENDDO
|
|
|
|
|
|
DEALLOCATE (vnl, aux)
|
|
|
|
!
|
|
! redetermine ikk2
|
|
!
|
|
DO iv=1,nbeta
|
|
ikk2(iv)=kkbeta
|
|
DO ir = kkbeta,1,-1
|
|
IF ( abs(betar(ir,iv)) > 1.d-12 ) THEN
|
|
ikk2(iv)=ir
|
|
exit
|
|
ENDIF
|
|
ENDDO
|
|
ENDDO
|
|
ENDIF
|
|
ALLOCATE (rho_at(mesh))
|
|
rho_at = rho_at_
|
|
DEALLOCATE (rho_at_)
|
|
|
|
ALLOCATE (chi(mesh,ntwfc))
|
|
chi = chi_
|
|
DEALLOCATE (chi_)
|
|
|
|
RETURN
|
|
END SUBROUTINE convert_casino
|