quantum-espresso/Modules/pseudo_types.f90

365 lines
19 KiB
Fortran

!
! Copyright (C) 2002-2007 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 .
!
MODULE pseudo_types
! this module contains the definitions of several TYPE structures,
! together with their allocation/deallocation routines
USE kinds, ONLY: DP
use radial_grids, ONLY: radial_grid_type
IMPLICIT NONE
SAVE
!
TYPE :: paw_t
!
! Type describing a PAW dataset (temporary).
! Functions are defined on a logarithmic radial mesh.
!
CHARACTER(LEN=2) :: symbol
REAL (DP) :: zval
REAL (DP) :: z
CHARACTER(LEN=80):: dft
TYPE(radial_grid_type) :: grid
REAL (DP) :: rmatch_augfun ! the matching radius for augmentation charges
LOGICAL :: nlcc ! nonlinear core correction
INTEGER :: nwfc ! number of wavefunctions/projectors
INTEGER :: lmax ! maximum angular momentum of projectors
INTEGER, POINTER :: l(:) !l(nwfsx) ! angular momentum of projectors
INTEGER, POINTER :: ikk(:) !ikk(nwfsx) ! cutoff radius for the projectors
INTEGER :: irc ! r(irc) = radius of the augmentation sphere
CHARACTER(LEN=2),POINTER :: els (:) ! the name of the wavefunction
REAL (DP), POINTER :: &
oc(:), & !(nwfsx) the occupations
enl(:), & !(nwfsx) the energy of the wavefunctions
jj (:), & ! the total angular momentum
rcutus (:), & ! the cutoff
aewfc(:,:), & !(ndmx,nwfsx) all-electron wavefunctions
pswfc(:,:), & !(ndmx,nwfsx) pseudo wavefunctions
proj(:,:), & !(ndmx,nwfsx) projectors
augfun(:,:,:,:), &!(ndmx,nwfsx,nwfsx,0:2*lmaxx+1),
augmom(:,:,:), & !(nwfsx,nwfsx,0:2*lmaxx) moments of the augmentation functions
aeccharge(:), & !(ndmx) AE core charge * 4PI r^2
psccharge(:), & !(ndmx) PS core charge * 4PI r^2
pscharge(:), & !(ndmx) PS charge * 4PI r^2
aeloc(:), & !(ndmx) descreened AE potential: v_AE-v_H[n1]-v_XC[n1+nc]
psloc(:), & !(ndmx) descreened local PS potential: v_PS-v_H[n~+n^]-v_XC[n~+n^+n~c]
kdiff(:,:), & !(nwfsx,nwfsx) kinetic energy differences
dion(:,:) !(nwfsx,nwfsx) descreened D coeffs
!!! Notes about screening:
!!! Without nlcc, the local PSpotential is descreened with n~+n^ only.
!!! The local AEpotential is descreened ALWAYS with n1+nc. This improves
!!! the accuracy, and will not cost in the plane wave code (atomic
!!! contribution only).
END TYPE paw_t
!
! Additional data to make a PAW setup out of an US pseudo,
! they are all stored on a radial grid:
TYPE paw_in_upf
REAL(DP),POINTER :: aug(:,:,:,:) ! Augmentation charge
REAL(DP),POINTER :: ae_rho_atc(:) ! AE core charge (pseudo ccharge
! is already included in upf)
REAL(DP),POINTER :: pfunc(:,:,:),&! Psi_i(r)*Psi_j(r)
ptfunc(:,:,:) ! as above, but for pseudo
REAL(DP),POINTER :: ae_vloc(:) ! AE local potential (pseudo vloc
! is already included in upf)
REAL(DP),POINTER :: kdiff(:,:) ! kinetic energy difference AE-pseudo
REAL(DP),POINTER :: oc(:) ! starting occupation used to init becsum
! they differ from US ones because they
! are indexed on BETA functions, non on WFC
REAL(DP),POINTER :: augmom(:,:,:) ! multipole AE-pseudo (i,j,l=0:2*lmax)
REAL(DP) :: raug ! augfunction max radius
INTEGER :: iraug ! index on rgrid closer to, and >, raug
INTEGER :: irmax ! max{ iraug , kkbeta } == max radius to integrate
INTEGER :: lmax_aug ! max angmom of augmentation functions, it is ==
! to 2* max{l of pseudized wavefunctions}
! note that nqlc of upf also include the angmom of
! empty virtual channel used to generate local potential
INTEGER :: lmax_phi !
INTEGER :: lmax_rho !
CHARACTER(len=12):: augshape ! shape of augmentation charge
END TYPE paw_in_upf
TYPE pseudo_upf
CHARACTER(LEN=80):: generated !
CHARACTER(LEN=80):: date_author ! Misc info
CHARACTER(LEN=80):: comment !
CHARACTER(LEN=2) :: psd ! Element label
CHARACTER(LEN=20) :: typ ! Pseudo type ( NC or US )
LOGICAL :: tvanp ! .true. if Ultrasoft
LOGICAL :: nlcc ! Non linear core corrections
CHARACTER(LEN=20) :: dft ! Exch-Corr type
REAL(DP) :: zp ! z valence
REAL(DP) :: etotps ! total energy
REAL(DP) :: ecutwfc ! suggested cut-off for wfc
REAL(DP) :: ecutrho ! suggested cut-off for rho
LOGICAL :: has_so ! if .true. includes spin-orbit
REAL(DP) :: xmin ! the minimum x of the linear mesh
REAL(DP) :: rmax ! the maximum radius of the mesh
REAL(DP) :: zmesh ! the nuclear charge used for mesh
REAL(DP) :: dx ! the deltax of the linear mesh
INTEGER, POINTER :: nn(:) ! nn(nwfc) quantum number of wfc
REAL(DP), POINTER :: rcut(:) ! cut-off radius(nbeta)
REAL(DP), POINTER :: rcutus(:)! ultrasoft cut-off radius (nbeta)
REAL(DP), POINTER :: epseu(:) ! energy (nwfc)
REAL(DP), POINTER :: jchi(:) ! jchi(nwfc) j=l+1/2 or l-1/2 of wfc
REAL(DP), POINTER :: jjj(:) ! jjj(nbeta) j=l+1/2 or l-1/2 of beta
INTEGER :: nv ! UPF file version number
INTEGER :: lmax ! maximum l component in beta
INTEGER :: mesh ! number of points in the radial mesh
INTEGER :: nwfc ! number of atomic wavefunctions
INTEGER :: nbeta ! number of projectors
INTEGER :: kkbeta ! kkbeta=max(kbeta(:))
! kbeta<=mesh is the number of grid points for each beta function
! beta(r,nb) = 0 for r > r(kbeta(nb))
! kkbeta<=mesh is the largest of such number so that for all beta
! beta(r,nb) = 0 for r > r(kkbeta)
CHARACTER(LEN=2), POINTER :: els(:) ! els(nwfc) label of wfc
CHARACTER(LEN=2), POINTER :: els_beta(:) ! els(nbeta) label of beta
INTEGER, POINTER :: lchi(:) ! lchi(nwfc) value of l for wavefcts
REAL(DP), POINTER :: oc(:) ! oc(nwfc) occupancies for wavefcts
REAL(DP), POINTER :: r(:) ! r(mesh) radial grid
REAL(DP), POINTER :: rab(:) ! rab(mesh) dr(x)/dx (x=linear grid)
REAL(DP), POINTER :: rho_atc(:) ! rho_atc(mesh) atomic core charge
REAL(DP), POINTER :: vloc(:) ! vloc(mesh) local atomic potential
INTEGER, POINTER :: lll(:) ! lll(nbeta) l of each projector
INTEGER, POINTER :: kbeta(:) ! kbeta(nbeta) see above kkbeta
REAL(DP), POINTER :: beta(:,:) ! beta(mesh,nbeta) projectors
REAL(DP), POINTER :: aewfc(:,:) ! wfc(mesh,nbeta) all-electron wfc
REAL(DP), POINTER :: pswfc(:,:) ! wfc(mesh,nbeta) pseudo wfc
INTEGER :: nd
REAL(DP), POINTER :: dion(:,:) ! dion(nbeta,nbeta) atomic D_{mu,nu}
INTEGER :: nqf ! number of Q coefficients
INTEGER :: nqlc ! number of angular momenta in Q
REAL(DP), POINTER :: rinner(:) ! rinner(0:2*lmax) r_L
REAL(DP), POINTER :: qqq(:,:) ! qqq(nbeta,nbeta) q_{mu,nu}
REAL(DP), POINTER :: qfunc(:,:) ! qfunc(mesh,nbeta*(nbeta+1)/2)
! Q_{mu,nu}(|r|) function for |r|> r_L
REAL(DP), POINTER :: qfuncl(:,:,:)! qfuncl(mesh,nbeta*(nbeta+1)/2,l)
! Q_{mu,nu}(|r|) function for |r|>
REAL(DP), POINTER :: qfcoef(:,:,:,:) ! qfcoef(nqf,0:2*lmax,nbeta,nbeta)
! coefficients for Q for |r|<r_L
REAL(DP), POINTER :: chi(:,:) ! chi(mesh,nwfc) atomic wavefcts
REAL(DP), POINTER :: rho_at(:) ! rho_at(mesh) atomic charge
LOGICAL :: q_with_l ! if .true. qfunc is pseudized in
! different ways for different l
! PAW:
LOGICAL :: has_paw ! Whether PAW data is included
REAL(DP) :: paw_data_format ! The version of the format
LOGICAL :: tpawp ! true if atom is PAW
TYPE(paw_in_upf) :: paw ! additional data for PAW (see above)
TYPE(radial_grid_type),POINTER :: &
grid ! pointer to the corresponding grid
! in radial_grids module
! GIPAW:
LOGICAL :: has_gipaw ! Whether GIPAW data is included
REAL(DP) :: gipaw_data_format ! The version of the format
INTEGER :: gipaw_ncore_orbitals
REAL(DP), POINTER :: gipaw_core_orbital_n(:)
REAL(DP), POINTER :: gipaw_core_orbital_l(:)
CHARACTER(LEN=2), POINTER :: gipaw_core_orbital_el(:)
REAL(DP), POINTER :: gipaw_core_orbital(:,:)
REAL(DP), POINTER :: gipaw_vlocal_ae(:)
REAL(DP), POINTER :: gipaw_vlocal_ps(:)
INTEGER :: gipaw_wfs_nchannels
CHARACTER(LEN=2), POINTER :: gipaw_wfs_el(:)
INTEGER, POINTER :: gipaw_wfs_ll(:)
REAL(DP), POINTER :: gipaw_wfs_ae(:,:)
REAL(DP), POINTER :: gipaw_wfs_rcut(:)
REAL(DP), POINTER :: gipaw_wfs_rcutus(:)
REAL(DP), POINTER :: gipaw_wfs_ps(:,:)
END TYPE
CONTAINS
SUBROUTINE nullify_paw_in_upf( paw )
TYPE( paw_in_upf ), INTENT(INOUT) :: paw
NULLIFY( paw%aug )
NULLIFY( paw%ae_rho_atc )
NULLIFY( paw%pfunc )
NULLIFY( paw%ptfunc )
NULLIFY( paw%ae_vloc )
NULLIFY( paw%kdiff )
NULLIFY( paw%augmom )
NULLIFY( paw%oc )
END SUBROUTINE
SUBROUTINE deallocate_paw_in_upf( paw )
TYPE( paw_in_upf ), INTENT(INOUT) :: paw
IF( ASSOCIATED( paw%aug ) ) DEALLOCATE ( paw%aug )
IF( ASSOCIATED( paw%ae_rho_atc ) ) DEALLOCATE ( paw%ae_rho_atc )
IF( ASSOCIATED( paw%pfunc ) ) DEALLOCATE ( paw%pfunc )
IF( ASSOCIATED( paw%ptfunc ) ) DEALLOCATE ( paw%ptfunc )
IF( ASSOCIATED( paw%ae_vloc ) ) DEALLOCATE ( paw%ae_vloc )
IF( ASSOCIATED( paw%kdiff ) ) DEALLOCATE ( paw%kdiff )
IF( ASSOCIATED( paw%augmom ) ) DEALLOCATE ( paw%augmom )
IF( ASSOCIATED( paw%oc ) ) DEALLOCATE ( paw%oc )
CALL nullify_paw_in_upf( paw )
END SUBROUTINE
SUBROUTINE nullify_pseudo_upf( upf )
TYPE( pseudo_upf ), INTENT(INOUT) :: upf
CALL nullify_paw_in_upf( upf%paw )
NULLIFY( upf%els, upf%lchi, upf%jchi, upf%oc )
NULLIFY( upf%r, upf%rab )
NULLIFY( upf%rho_atc, upf%vloc )
NULLIFY( upf%nn, upf%rcut)
NULLIFY( upf%els_beta)
NULLIFY( upf%rcutus, upf%epseu)
NULLIFY( upf%lll, upf%jjj, upf%kbeta, upf%beta, upf%dion )
NULLIFY( upf%aewfc, upf%pswfc )
NULLIFY( upf%rinner, upf%qqq, upf%qfunc, upf%qfcoef )
NULLIFY( upf%chi )
NULLIFY( upf%rho_at )
!NULLIFY( upf%grid ) ! Note: this must NOT be nullified or read_upf will fail!
NULLIFY ( upf%gipaw_core_orbital_n )
NULLIFY ( upf%gipaw_core_orbital_l )
NULLIFY ( upf%gipaw_core_orbital_el )
NULLIFY ( upf%gipaw_core_orbital )
NULLIFY ( upf%gipaw_vlocal_ae )
NULLIFY ( upf%gipaw_vlocal_ps )
NULLIFY ( upf%gipaw_wfs_el )
NULLIFY ( upf%gipaw_wfs_ll )
NULLIFY ( upf%gipaw_wfs_ae )
NULLIFY ( upf%gipaw_wfs_rcut )
NULLIFY ( upf%gipaw_wfs_rcutus )
NULLIFY ( upf%gipaw_wfs_ps )
RETURN
END SUBROUTINE nullify_pseudo_upf
SUBROUTINE deallocate_pseudo_upf( upf )
TYPE( pseudo_upf ), INTENT(INOUT) :: upf
CALL deallocate_paw_in_upf( upf%paw )
IF( ASSOCIATED( upf%els ) ) DEALLOCATE( upf%els )
IF( ASSOCIATED( upf%lchi ) ) DEALLOCATE( upf%lchi )
IF( ASSOCIATED( upf%jchi ) ) DEALLOCATE( upf%jchi )
IF( ASSOCIATED( upf%oc ) ) DEALLOCATE( upf%oc )
IF( ASSOCIATED( upf%r ) ) DEALLOCATE( upf%r )
IF( ASSOCIATED( upf%rab ) ) DEALLOCATE( upf%rab )
IF( ASSOCIATED( upf%nn ) ) DEALLOCATE( upf%nn )
IF( ASSOCIATED( upf%els_beta ) ) DEALLOCATE( upf%els_beta )
IF( ASSOCIATED( upf%rcut ) ) DEALLOCATE( upf%rcut )
IF( ASSOCIATED( upf%rcutus ) ) DEALLOCATE( upf%rcutus )
IF( ASSOCIATED( upf%epseu ) ) DEALLOCATE( upf%epseu )
IF( ASSOCIATED( upf%rho_atc ) ) DEALLOCATE( upf%rho_atc )
IF( ASSOCIATED( upf%vloc ) ) DEALLOCATE( upf%vloc )
IF( ASSOCIATED( upf%lll ) ) DEALLOCATE( upf%lll )
IF( ASSOCIATED( upf%jjj ) ) DEALLOCATE( upf%jjj )
IF( ASSOCIATED( upf%kbeta ) ) DEALLOCATE( upf%kbeta )
IF( ASSOCIATED( upf%beta ) ) DEALLOCATE( upf%beta )
IF( ASSOCIATED( upf%aewfc ) ) DEALLOCATE( upf%aewfc )
IF( ASSOCIATED( upf%pswfc ) ) DEALLOCATE( upf%pswfc )
IF( ASSOCIATED( upf%dion ) ) DEALLOCATE( upf%dion )
IF( ASSOCIATED( upf%rinner ) ) DEALLOCATE( upf%rinner )
IF( ASSOCIATED( upf%qqq ) ) DEALLOCATE( upf%qqq )
IF( ASSOCIATED( upf%qfunc ) ) DEALLOCATE( upf%qfunc )
IF( ASSOCIATED( upf%qfcoef ) ) DEALLOCATE( upf%qfcoef )
IF( ASSOCIATED( upf%chi ) ) DEALLOCATE( upf%chi )
IF( ASSOCIATED( upf%rho_at ) ) DEALLOCATE( upf%rho_at )
IF ( ASSOCIATED ( upf%gipaw_core_orbital_n ) ) &
DEALLOCATE ( upf%gipaw_core_orbital_n )
IF ( ASSOCIATED ( upf%gipaw_core_orbital_l ) ) &
DEALLOCATE ( upf%gipaw_core_orbital_l )
IF ( ASSOCIATED ( upf%gipaw_core_orbital_el ) ) &
DEALLOCATE ( upf%gipaw_core_orbital_el )
IF ( ASSOCIATED ( upf%gipaw_core_orbital ) ) &
DEALLOCATE ( upf%gipaw_core_orbital )
IF ( ASSOCIATED ( upf%gipaw_vlocal_ae ) ) &
DEALLOCATE ( upf%gipaw_vlocal_ae )
IF ( ASSOCIATED ( upf%gipaw_vlocal_ps ) ) &
DEALLOCATE ( upf%gipaw_vlocal_ps )
IF ( ASSOCIATED ( upf%gipaw_wfs_el ) ) &
DEALLOCATE ( upf%gipaw_wfs_el )
IF ( ASSOCIATED ( upf%gipaw_wfs_ll ) ) &
DEALLOCATE ( upf%gipaw_wfs_ll )
IF ( ASSOCIATED ( upf%gipaw_wfs_ae ) ) &
DEALLOCATE ( upf%gipaw_wfs_ae )
IF ( ASSOCIATED ( upf%gipaw_wfs_rcut ) ) &
DEALLOCATE ( upf%gipaw_wfs_rcut )
IF ( ASSOCIATED ( upf%gipaw_wfs_rcutus ) ) &
DEALLOCATE ( upf%gipaw_wfs_rcutus )
IF ( ASSOCIATED ( upf%gipaw_wfs_ps ) ) &
DEALLOCATE ( upf%gipaw_wfs_ps )
RETURN
END SUBROUTINE deallocate_pseudo_upf
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
! Nullify, allocate and deallocate for paw_t type. Used only
! in atomic code.
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SUBROUTINE nullify_pseudo_paw( paw )
TYPE( paw_t ), INTENT(INOUT) :: paw
NULLIFY( paw%l, paw%ikk )
NULLIFY( paw%oc, paw%enl, paw%aewfc, paw%pswfc, paw%proj )
NULLIFY( paw%augfun, paw%augmom, paw%aeccharge, paw%psccharge, paw%pscharge )
NULLIFY( paw%aeloc, paw%psloc, paw%kdiff, paw%dion )
RETURN
END SUBROUTINE nullify_pseudo_paw
SUBROUTINE allocate_pseudo_paw( paw, size_mesh, size_nwfc, size_lmax )
TYPE( paw_t ), INTENT(INOUT) :: paw
INTEGER, INTENT(IN) :: size_mesh, size_nwfc, size_lmax
!WRITE(0,"(a,3i5)") "Allocating PAW setup: ",size_mesh, size_nwfc, size_lmax
ALLOCATE ( paw%l(size_nwfc) )
ALLOCATE ( paw%jj(size_nwfc) )
ALLOCATE ( paw%ikk(size_nwfc) )
ALLOCATE ( paw%oc(size_nwfc) )
ALLOCATE ( paw%rcutus(size_nwfc) )
ALLOCATE ( paw%els(size_nwfc) )
ALLOCATE ( paw%enl(size_nwfc) )
ALLOCATE ( paw%aewfc(size_mesh,size_nwfc) )
ALLOCATE ( paw%pswfc(size_mesh,size_nwfc) )
ALLOCATE ( paw%proj (size_mesh,size_nwfc) )
ALLOCATE ( paw%augfun(size_mesh,size_nwfc,size_nwfc,0:2*size_lmax) )
ALLOCATE ( paw%augmom(size_nwfc,size_nwfc,0:2*size_lmax) )
ALLOCATE ( paw%aeccharge(size_mesh) )
ALLOCATE ( paw%psccharge(size_mesh) )
ALLOCATE ( paw%pscharge(size_mesh) )
ALLOCATE ( paw%aeloc(size_mesh) )
ALLOCATE ( paw%psloc(size_mesh) )
ALLOCATE ( paw%kdiff(size_nwfc,size_nwfc) )
ALLOCATE ( paw%dion (size_nwfc,size_nwfc) )
END SUBROUTINE allocate_pseudo_paw
SUBROUTINE deallocate_pseudo_paw( paw )
TYPE( paw_t ), INTENT(INOUT) :: paw
IF( ASSOCIATED( paw%l ) ) DEALLOCATE( paw%l )
IF( ASSOCIATED( paw%jj ) ) DEALLOCATE( paw%jj )
IF( ASSOCIATED( paw%ikk ) ) DEALLOCATE( paw%ikk )
IF( ASSOCIATED( paw%oc ) ) DEALLOCATE( paw%oc )
IF( ASSOCIATED( paw%els ) ) DEALLOCATE( paw%els )
IF( ASSOCIATED( paw%rcutus ) ) DEALLOCATE( paw%rcutus )
IF( ASSOCIATED( paw%enl ) ) DEALLOCATE( paw%enl )
IF( ASSOCIATED( paw%aewfc ) ) DEALLOCATE( paw%aewfc )
IF( ASSOCIATED( paw%pswfc ) ) DEALLOCATE( paw%pswfc )
IF( ASSOCIATED( paw%proj ) ) DEALLOCATE( paw%proj )
IF( ASSOCIATED( paw%augfun ) ) DEALLOCATE( paw%augfun )
IF( ASSOCIATED( paw%augmom ) ) DEALLOCATE( paw%augmom )
IF( ASSOCIATED( paw%aeccharge ) ) DEALLOCATE( paw%aeccharge )
IF( ASSOCIATED( paw%psccharge ) ) DEALLOCATE( paw%psccharge )
IF( ASSOCIATED( paw%pscharge ) ) DEALLOCATE( paw%pscharge )
IF( ASSOCIATED( paw%aeloc ) ) DEALLOCATE( paw%aeloc )
IF( ASSOCIATED( paw%psloc ) ) DEALLOCATE( paw%psloc )
IF( ASSOCIATED( paw%kdiff ) ) DEALLOCATE( paw%kdiff )
IF( ASSOCIATED( paw%dion ) ) DEALLOCATE( paw%dion )
RETURN
END SUBROUTINE deallocate_pseudo_paw
END MODULE pseudo_types