mirror of https://gitlab.com/QEF/q-e.git
258 lines
8.6 KiB
Fortran
258 lines
8.6 KiB
Fortran
!
|
|
! Copyright (C) 2020 Quantum ESPRESSO Foundation
|
|
! 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 .
|
|
!
|
|
! Original code "upf2casino" from Simon Binnie, 2011
|
|
!---------------------------------------------------------------------
|
|
PROGRAM upfconv
|
|
!---------------------------------------------------------------------
|
|
!
|
|
! Pseudopotential conversion utility, can
|
|
! - convert from:
|
|
! UPF v.1 or v.2 containing "&" characters,
|
|
! old PWSCF norm-conserving and Ultrasoft formats
|
|
! Vanderbilt ultrasoft PP generation code format
|
|
! CPMD format (TYPE=NUMERIC, LOGARITHMIC, CAR, GOEDECKER)
|
|
! to:
|
|
! UPF v.2 clean, or UPF with schema (xml)
|
|
! - extract and write to separate files:
|
|
! wavefunctions
|
|
! projectors ("beta" functions)
|
|
! potential
|
|
! if available, core wavefunctions from GIPAW section
|
|
! - convert to CASINO tabulated format (obsolete?)
|
|
!
|
|
USE pseudo_types, ONLY : pseudo_upf, deallocate_pseudo_upf
|
|
USE casino_pp, ONLY : conv_upf2casino, write_casino_tab
|
|
USE write_upf_new,ONLY : write_upf
|
|
!
|
|
IMPLICIT NONE
|
|
TYPE(pseudo_upf) :: upf_in
|
|
INTEGER :: prefix_len, nargs, i,j
|
|
CHARACTER(LEN=256) :: filein, fileout
|
|
CHARACTER(LEN=2) :: conversion=' '
|
|
CHARACTER(LEN=5) :: schema='none'
|
|
!
|
|
nargs = command_argument_count()
|
|
IF ( nargs < 1 .OR. nargs > 2 ) THEN
|
|
WRITE(*,*) 'Usage: upfconv -c|-u|-x|-e "pseudopotential file"'
|
|
WRITE(*,*) ' upfconv -h'
|
|
STOP
|
|
END IF
|
|
!
|
|
CALL get_command_argument(1, conversion)
|
|
!
|
|
IF ( conversion == "-h" ) THEN
|
|
WRITE(*,*) 'Converts a pseudopotential file to either upf v.2, xml or CASINO formats.'
|
|
WRITE(*,*) 'Usage: upfconv -c|-u|-x|-e "pseudopotential file"'
|
|
WRITE(*,*) 'Options: -c convert to CASINO format. MAY OR MAY NOT WORK (LIKELY IT DOES NOT)'
|
|
WRITE(*,*) 'Options: -c Make sure that the local channel chosen in the CASINO pp file'
|
|
WRITE(*,*) ' is what you expect'
|
|
WRITE(*,*) ' -u convert to upf v.2 format'
|
|
WRITE(*,*) ' -x convert to xml format'
|
|
WRITE(*,*) ' -e extract GIPAW core wavefunctions if available,'
|
|
WRITE(*,*) ' wavefunctions, projectors, potential'
|
|
WRITE(*,*) ' -h print this message'
|
|
WRITE(*,*) 'The pseudopotential file can be any of the following:'
|
|
WRITE(*,*) '*.upf or *.UPF upf (v.1 or 2)'
|
|
WRITE(*,*) '*.vdb or *.van Vanderbilt US pseudopotential code format'
|
|
WRITE(*,*) '*.rrkj3 or *.RRKJ3 Old US pseudopotential format of atomic code'
|
|
WRITE(*,*) '*.cpi or *.fhi FHI/abinit formats'
|
|
WRITE(*,*) '*.gth DOES NOT WORK Goedecker-Teter-Hutter NC pseudo format'
|
|
WRITE(*,*) '*.cpmd CPMD format (TYPE=NUMERIC, LOGARITHMIC, CAR, GOEDECKER)'
|
|
WRITE(*,*) 'none of the above Old PWSCF norm-conserving format'
|
|
STOP
|
|
END IF
|
|
!
|
|
CALL get_command_argument(2, filein)
|
|
IF ( INDEX(TRIM(filein),'.UPF' ) > 0) THEN
|
|
prefix_len = INDEX(TRIM(filein),'.UPF') - 1
|
|
ELSE IF (INDEX(TRIM(filein),'.upf') > 0 ) THEN
|
|
prefix_len = INDEX(TRIM(filein),'.upf') - 1
|
|
ELSE
|
|
prefix_len = LEN_TRIM(filein)
|
|
ENDIF
|
|
|
|
IF ( conversion == "-c" ) THEN
|
|
fileout = filein(1:prefix_len) //'.out'
|
|
WRITE(*,*) 'UPF to CASINO conversion'
|
|
WRITE(*,*) 'All pseudopotential files generated should be &
|
|
&thoroughly checked.'
|
|
WRITE(*,*) 'In particular make sure the local channel chosen&
|
|
& in the CASINO pp file is what you expected.'
|
|
ELSE IF ( conversion == "-x" ) THEN
|
|
fileout = filein(1:prefix_len) //'.xml'
|
|
WRITE(*,*) 'UPF to xml format conversion'
|
|
ELSE IF ( conversion == "-u" ) THEN
|
|
fileout = filein(1:prefix_len) //'.UPF2'
|
|
WRITE(*,*) 'UPF v.1 to UPF v.2 format conversion'
|
|
ELSE IF ( conversion == "-e" .or. conversion == "-E" ) THEN
|
|
fileout = filein(1:prefix_len)
|
|
ELSE
|
|
WRITE(*,*) 'Invalid option ' // conversion
|
|
WRITE(*,*) 'Usage: upfconv -c|-u|-x|-e|-E "pseudopotential file"'
|
|
STOP
|
|
END IF
|
|
IF ( prefix_len < 1 ) THEN
|
|
WRITE(*,*) 'Empty file name, stopping'
|
|
STOP
|
|
END IF
|
|
WRITE(*,*) 'input file: ' // trim(filein), ', output file: ' // trim(fileout)
|
|
|
|
CALL read_ps ( filein, upf_in )
|
|
|
|
IF ( conversion == "-c" ) THEN
|
|
!
|
|
CALL conv_upf2casino(upf_in)
|
|
CALL write_casino_tab(upf_in, fileout)
|
|
!
|
|
ELSE IF ( conversion == "-e" ) THEN
|
|
!
|
|
CALL write_files ( upf_in, fileout )
|
|
!
|
|
ELSE
|
|
!
|
|
CALL conv_upf2xml(upf_in)
|
|
IF ( conversion == "-x" ) THEN
|
|
schema = 'qe_pp'
|
|
ELSE IF ( conversion == "-u" ) THEN
|
|
schema = 'v2'
|
|
END IF
|
|
CALL write_upf (FILENAME = fileout, UPF = upf_in, SCHEMA = schema)
|
|
!
|
|
ENDIF
|
|
|
|
STOP
|
|
END PROGRAM upfconv
|
|
|
|
SUBROUTINE write_files( upf_in, fileout )
|
|
!
|
|
USE upf_const, ONLY : fpi
|
|
USE pseudo_types, ONLY : pseudo_upf
|
|
!
|
|
IMPLICIT NONE
|
|
TYPE(pseudo_upf), INTENT(inout) :: upf_in
|
|
CHARACTER (LEN=*) :: fileout
|
|
INTEGER :: i, j, n, ios, iunps
|
|
!
|
|
iunps=999
|
|
!
|
|
OPEN ( UNIT=iunps, FILE=TRIM(fileout)//'.wfc', STATUS='unknown', &
|
|
FORM='formatted', IOSTAT=ios)
|
|
IF ( ios /= 0 ) THEN
|
|
WRITE(*,"('cannot write wfc file, stopping')" )
|
|
STOP
|
|
END IF
|
|
WRITE(*,"('writing: ',a)") TRIM(fileout)//'.wfc'
|
|
DO n=1,upf_in%mesh
|
|
WRITE(iunps,'(30f12.6)') upf_in%r(n), (upf_in%chi(n,j), j=1,upf_in%nwfc)
|
|
ENDDO
|
|
CLOSE(iunps)
|
|
|
|
OPEN ( UNIT=iunps, FILE=TRIM(fileout)//'.beta', STATUS='unknown', &
|
|
FORM='formatted', IOSTAT=ios)
|
|
IF ( ios /= 0 ) THEN
|
|
WRITE(*,"('cannot write beta file, stopping')" )
|
|
STOP
|
|
END IF
|
|
WRITE(*,"('writing: ',a)") TRIM(fileout)//'.beta'
|
|
DO n=1,upf_in%mesh
|
|
WRITE(iunps,'(30f12.6)') upf_in%r(n), (upf_in%beta(n,j), j=1,upf_in%nbeta)
|
|
ENDDO
|
|
CLOSE(iunps)
|
|
|
|
OPEN ( UNIT=iunps, FILE=TRIM(fileout)//'.pot', STATUS='unknown', &
|
|
FORM='formatted', IOSTAT=ios)
|
|
IF ( ios /= 0 ) THEN
|
|
WRITE(*,"('cannot write beta file, stopping')" )
|
|
STOP
|
|
END IF
|
|
WRITE(*,"('writing: ',a)") TRIM(fileout)//'.pot'
|
|
DO n=1,upf_in%mesh
|
|
WRITE(iunps,'(4f12.6)') upf_in%r(n), upf_in%vloc(n), &
|
|
upf_in%rho_at(n), upf_in%rho_atc(n)*fpi*upf_in%r(n)**2
|
|
ENDDO
|
|
CLOSE(iunps)
|
|
|
|
IF(upf_in%has_gipaw) THEN
|
|
DO j = 1, upf_in%gipaw_ncore_orbitals
|
|
OPEN(unit=iunps, file = TRIM(fileout)//TRIM(upf_in%gipaw_core_orbital_el(j))//".out")
|
|
WRITE(*,"('writing: ',a)") TRIM(fileout)//TRIM(upf_in%gipaw_core_orbital_el(j))//".out"
|
|
DO n = 1, upf_in%mesh
|
|
WRITE(iunps,*) upf_in%r(n), upf_in%gipaw_core_orbital(n,j)
|
|
WRITE(iunps+1,*) upf_in%r(n), upf_in%gipaw_core_orbital(n,j)
|
|
ENDDO
|
|
CLOSE(iunps)
|
|
ENDDO
|
|
|
|
! write the same, but all in one file for xspectra
|
|
OPEN(unit=iunps, file = TRIM(fileout)//".xspectra")
|
|
WRITE(*,"('writing: ',a)") TRIM(fileout)//".xspectra"
|
|
WRITE(iunps,"('# mesh size',i6,'; core orbitals:',99(a3,', '))") upf_in%mesh, upf_in%gipaw_core_orbital_el(:)
|
|
DO j = 1, upf_in%gipaw_ncore_orbitals
|
|
DO n = 1, upf_in%mesh
|
|
WRITE(iunps,*) upf_in%r(n), upf_in%gipaw_core_orbital(n,j)
|
|
ENDDO
|
|
ENDDO
|
|
CLOSE(iunps)
|
|
|
|
ELSE
|
|
WRITE(*,*) "Core charge not written: this pseudopotential does not contain gipaw data"
|
|
ENDIF
|
|
|
|
END SUBROUTINE write_files
|
|
|
|
SUBROUTINE conv_upf2xml( upf )
|
|
!
|
|
USE pseudo_types, ONLY : pseudo_upf
|
|
USE upf_utils, ONLY : version_compare
|
|
!
|
|
IMPLICIT NONE
|
|
TYPE(pseudo_upf), INTENT(inout) :: upf
|
|
INTEGER, EXTERNAL :: atomic_number
|
|
!
|
|
! convert a few variables from UPF v.1 to UPF v.2/xml
|
|
!
|
|
IF ( version_compare(upf%nv,"2.0.1") == 'equal') RETURN
|
|
upf%nv="2.0.1"
|
|
!
|
|
IF ( .NOT. ALLOCATED(upf%nchi) ) THEN
|
|
ALLOCATE(upf%nchi(upf%nwfc))
|
|
upf%nchi(:) = 0
|
|
END IF
|
|
IF ( .NOT. ALLOCATED(upf%rcut_chi) ) THEN
|
|
ALLOCATE(upf%rcut_chi(upf%nwfc))
|
|
upf%rcut_chi(:) = upf%rcut(:)
|
|
END IF
|
|
IF ( .NOT. ALLOCATED(upf%rcutus_chi) ) THEN
|
|
ALLOCATE(upf%rcutus_chi(upf%nwfc))
|
|
upf%rcutus_chi(:) = upf%rcutus(:)
|
|
END IF
|
|
IF ( .NOT. ALLOCATED(upf%epseu) ) THEN
|
|
ALLOCATE(upf%epseu(upf%nwfc))
|
|
upf%epseu(:) = 0.0
|
|
END IF
|
|
IF ( TRIM(upf%rel) == '' ) THEN
|
|
IF (upf%has_so) THEN
|
|
upf%rel="full"
|
|
ELSE IF ( upf%zmesh > 18 ) THEN
|
|
upf%rel="scalar"
|
|
ELSE
|
|
upf%rel="no"
|
|
ENDIF
|
|
ENDIF
|
|
!
|
|
IF ( .not. upf%has_so) THEN
|
|
upf%rmax = upf%r(upf%mesh)
|
|
upf%zmesh = atomic_number( upf%psd )
|
|
IF (upf%r(1) .GT. 1.d-16) THEN
|
|
upf%dx = log(upf%rmax/upf%r(1))/(upf%mesh-1)
|
|
upf%xmin = log(upf%r(1)*upf%zmesh )
|
|
END IF
|
|
END IF
|
|
!
|
|
END SUBROUTINE conv_upf2xml
|