!!****m* ABINIT/m_psp8
!! NAME
!!  m_psp8
!!
!! FUNCTION
!! Initialize pspcod=8 (pseudopotentials in the format generated by DRH):
!!
!! COPYRIGHT
!!  Copyright (C) 1999-2021 ABINIT group (DRH, XG, AF)
!!  This file is distributed under the terms of the
!!  GNU General Public License, see ~abinit/COPYING
!!  or http://www.gnu.org/copyleft/gpl.txt .
!!
!! PARENTS
!!
!! CHILDREN
!!
!! SOURCE

#if defined HAVE_CONFIG_H
#include "config.h"
#endif

#include "abi_common.h"

module m_psp8

 use defs_basis
 use m_errors
 use m_abicore
 use m_splines

 use defs_datatypes,  only : nctab_t
 use m_pawrad,        only : pawrad_type, pawrad_init, pawrad_free
 use m_psps,          only : nctab_eval_tvalespl
 use m_psptk,         only : psp8lo, psp8nl

 implicit none

 private
!!***

 public :: psp8in
!!***

contains
!!***

!!****f* ABINIT/psp8in
!! NAME
!! psp8in
!!
!! FUNCTION
!! Initialize pspcod=8 (pseudopotentials in the format generated by DRH):
!! continue to read the corresponding file, then compute the
!! local and non-local potentials.
!!
!! INPUTS
!!  lloc=angular momentum choice of local pseudopotential
!!  lmax=value of lmax mentioned at the second line of the psp file
!!  lmnmax=if useylm=1, max number of (l,m,n) comp. over all type of psps
!!        =if useylm=0, max number of (l,n)   comp. over all type of psps
!!  lnmax=max. number of (l,n) components over all type of psps
!!  mmax=maximum number of points in real space grid in the psp file
!!   angular momentum of nonlocal pseudopotential
!!  mpsang= 1+maximum angular momentum for nonlocal pseudopotentials
!!  mpssoang= 2*maximum angular momentum for nonlocal pseudopotentials - 1
!!  mqgrid=dimension of q (or G) grid for arrays.
!!  mqgrid_vl=dimension of q (or G) grid for valence charge (array qgrid_vl)
!!  n1xccc=dimension of xccc1d ; 0 if no XC core correction is used
!!  qgrid(mqgrid)=values of q (or |G|) on grid from 0 to qmax
!!  qgrid_vl(psps%mqgrid_vl)=values of q on grid from 0 to qmax (bohr^-1) for valence charge
!!  pspso=spin-orbit characteristics, govern the content of ffspl and ekb
!!   if =0 : this input requires NO spin-orbit characteristics of the psp
!!   if =2 : this input requires HGH or psp8 characteristics of the psp
!!   if =3 : this input requires HFN characteristics of the psp
!!  useylm=governs the way the nonlocal operator is to be applied:
!!         1=using Ylm, 0=using Legendre polynomials
!!  zion=nominal valence of atom as specified in psp file
!!  znucl=nuclear number of atom as specified in psp file
!!
!! OUTPUT
!!  ekb(lnmax)=Kleinman-Bylander energy, as read from input file
!!  epsatm=$ (4\pi)\int_0^\infty [r^2 (V(r)+\frac{Zv}{r} dr]$ (hartree)
!!  ffspl(mqgrid,2,lnmax)=Kleinman-Bylander form factor f_l(q) and
!!   second derivative from spline fit for each angular momentum and
!!   each projector
!!  indlmn(6,i)= array giving l,m,n,lm,ln,s for i=ln  (if useylm=0)
!!                                           or i=lmn (if useylm=1)
!!  nproj(mpssoang)=number of projection functions for each angular momentum
!!  qchrg is not used, and could be suppressed later
!!  vlspl(mqgrid,2)=q^2 Vloc(q) and second derivatives from spline fit
!!  xcccrc=XC core correction cutoff radius (bohr)
!!  xccc1d(n1xccc,6)=1D core charge function and five derivatives, from psp file
!!  nctab<nctab_t>=NC tables
!!    %has_tvale=True if the pseudo contains the pseudo valence charge
!!    %tvalespl(mqgrid_vl,2)=the pseudo valence density and 2nd derivative in reciprocal space on a regular grid
!!
!! PARENTS
!!      m_pspini
!!
!! CHILDREN
!!
!! SOURCE

subroutine psp8in(ekb,epsatm,ffspl,indlmn,lloc,lmax,lmnmax,lnmax,&
&                  mmax,mpsang,mpssoang,mqgrid,mqgrid_vl,nproj,n1xccc,pspso,qchrg,qgrid,qgrid_vl,&
&                  useylm,vlspl,xcccrc,xccc1d,zion,znucl,nctab,maxrad)

!Arguments ------------------------------------
!scalars
 integer,intent(in) :: lloc,lmax,lmnmax,lnmax,mmax,mpsang,mpssoang,mqgrid,mqgrid_vl
 integer,intent(in) :: pspso,n1xccc,useylm
 real(dp),intent(in) :: zion,znucl
 real(dp),intent(out) :: epsatm,qchrg,xcccrc,maxrad
 type(nctab_t),intent(inout) :: nctab
!arrays
 integer,intent(out) :: indlmn(6,lmnmax),nproj(mpssoang)
 real(dp),intent(in) :: qgrid(mqgrid),qgrid_vl(mqgrid_vl)
 real(dp),intent(out) :: ekb(lnmax),ffspl(mqgrid,2,lnmax),vlspl(mqgrid,2)
 real(dp),intent(inout) :: xccc1d(n1xccc,6) !vz_i

!Local variables-------------------------------
!scalars
 integer :: extension_switch,iln,iln0,pspindex,ipsang,irad,jj,kk,ll,ll_err,llin
 integer :: mm,nn,nso
 real(dp) :: amesh,damesh,fchrg,rchrg,yp1,ypn
 logical :: has_tvale
 character(len=500) :: msg,errmsg
 type(pawrad_type) :: mesh
!arrays
 integer, allocatable :: nproj_tmp(:)
 real(dp),allocatable :: rad(:),vloc(:),vpspll(:,:),work_spl(:)

! ***************************************************************************

!File format of formatted drh psp input, as adapted for use
!by the ABINIT code (the 3 first lines
!have already been read in calling -pspatm- routine) :

!(1) title (character) line
!(2) znucl,zion,pspdat
!(3) pspcod,pspxc,lmax,lloc,mmax,r2well  (r2well not used)
!(4) rchrg,fchrg,qchrg  (fchrg /=0 if core charge, qchrg not used)
!(5) nproj(0:lmax)  (several projectors allowed for each l)
!(6) extension_switch(2) (spin-orbit parameters)
!Then, for ll=0,lmax :
!if(nproj(ll)>0)
!1/<u1|vbkb1>, 1/<u2|vbkb2>, ...
!for  irad=1,mmax  : irad, r(irad), vbkb1(irad,ll), vbkb2(irad,ll), ...
!elseif ll=lloc
!for  irad=1,mmax  : irad, r(irad), vloc(irad)
!end if
!
!If(lloc>lmax)
!for  irad=1,mmax  : irad, r(irad), vloc(irad)
!end if
!
!vbkb are Bloechl-Kleinman-Bylander projectors,(vpsp(r,ll)-vloc(r))*u(r,ll),
!unnormalized
!Note that an arbitrary local potential is allowed.  Set lloc>lmax, and
!provide projectors for all ll<=lmax
!
!Finally, if fchrg>0,
!for  irad=1,mmax  : irad, r(irad), xccc(irad),
!xccc'(irac), xccc''(irad), xccc'''(irad), xccc''''(irad)
!
!Model core charge for nonlinear core xc correction, and 4 derivatives

 read (tmp_unit,*, err=10, iomsg=errmsg) rchrg,fchrg,qchrg
 write(msg, '(3f20.14,t64,a)' ) rchrg,fchrg,qchrg,'rchrg,fchrg,qchrg'
 call wrtout([std_out, ab_out], msg)

 ABI_MALLOC(nproj_tmp,(mpssoang))

 nproj_tmp(:)=0
 read (tmp_unit,*, err=10, iomsg=errmsg) nproj_tmp(1:lmax+1)
 write(msg, '(a,5i6)' ) '     nproj',nproj_tmp(1:lmax+1)
 call wrtout([std_out, ab_out], msg)

!place holder for future implementation of additional optional header
!lines without invalidating existing psp files
!Now (12/2014) extended to include spin-orbit projectors

! The integer labeled "extension switch" on line 6
! of the *.psp8 file will be set to 1 (non- or scalar-relativistic)
! or 3 (relativistic) to signal this to Abinit that the file contains the pseudo valence charge.

 has_tvale = .False.
 read (tmp_unit,*, err=10, iomsg=errmsg) extension_switch
 if (any(extension_switch==[2, 3])) then
   read (tmp_unit,*, err=10, iomsg=errmsg) nproj_tmp(lmax+2:2*lmax+1)
   write(msg, '(5x,a,i6)' ) 'spin-orbit psp, extension_switch',extension_switch
   call wrtout([std_out, ab_out], msg)
   write(msg, '(5x,a,5i6)' ) '   nprojso',nproj_tmp(lmax+2:2*lmax+1)
   call wrtout([std_out, ab_out], msg)
   has_tvale =  (extension_switch == 3)
 else if (any(extension_switch==[0,1])) then
   write(msg, '(5x,a,i6)' ) 'extension_switch',extension_switch
   call wrtout([std_out, ab_out], msg)
   has_tvale =  (extension_switch == 1)
 else
   write(msg, '(a,i0,2a)' ) 'invalid extension_switch: ',extension_switch,ch10,&
&   'Should be [0,1] for scalar-relativistic psp or [2,3] to include spin-orbit'
   ABI_ERROR(msg)
 end if

 if(lloc<4) then
   if (nproj_tmp(lloc+1)/=0) then
     write(msg, '(a,i4,a,a,i4,5a)' )&
     'Pseudopotential input file has nproj=',nproj_tmp(lloc+1),ch10,&
     'for angular momentum',lloc,' which is the local potential.',ch10,&
     'Should be 0 for the local potential',ch10,&
     'Action: check your pseudopotential input file.'
     ABI_ERROR(msg)
   end if
 end if

!--------------------------------------------------------------------

!Initialize array indlmn giving l,m,n,lm,ln,s for i=lmn
! if(pspso==2) then
 if (any(extension_switch == [0,1])) then
   nso=1
 else if (any(extension_switch == [2,3])) then
   nso=2
   if (pspso==0) then
     write (msg, '(3a)') 'You are reading a pseudopotential file with spin orbit projectors',ch10,&
&     ' but internal variable pspso is 0'
     ABI_COMMENT(msg)
   end if
 else
   write(msg, '(a,i0,2a)' ) 'invalid extension_switch: ',extension_switch,ch10,&
&   'Should be [0,1] for scalar-relativistic psp or [2,3] to include spin-orbit'
   ABI_ERROR(msg)
 end if

 pspindex=0;iln=0;indlmn(:,:)=0
 do nn=1,nso
   do ipsang=1+(nn-1)*(lmax+1),nn*lmax+1
     ll=ipsang-(nn-1)*lmax-1
     if (nproj_tmp(ipsang)>0) then
       do kk=1,nproj_tmp(ipsang)
         iln=iln+1
         do mm=1,2*ll*useylm+1
           pspindex=pspindex+1
           indlmn(1,pspindex)=ll
           indlmn(2,pspindex)=mm-ll*useylm-1
           indlmn(3,pspindex)=kk
           indlmn(4,pspindex)=ll*ll+(1-useylm)*ll+mm
           indlmn(5,pspindex)=iln
           indlmn(6,pspindex)=nn
         end do
       end do
     end if
   end do
 end do

! repackage nproj_tmp for proper use by pspatm
 nproj(:)=0
 nproj(1:lmax+1)=nproj_tmp(1:lmax+1)
 if(pspso==2) then
   nproj(mpsang+1:mpsang+lmax)=nproj_tmp(lmax+2:2*lmax+1)
 end if

!Can now allocate grids, potentials and projectors
 ABI_MALLOC(rad,(mmax))
 ABI_MALLOC(vloc,(mmax))
 ABI_MALLOC(vpspll,(mmax,lnmax))

!Will now proceed at the reading of pots and projectors

!rad(:)=radial grid r(i)
!vpspll(:,1),...,vpspll(:,lnmax)=nonlocal projectors
!vloc(:)=local potential

!Read Vanderbilt-Kleinman-Bylander energies and projectors for each l
!or read local potential for l=lloc.
!Also get rad array (actually read more than once)
 ll_err=0
 iln0=0
 do nn=1,nso
   do ipsang=1+(nn-1)*(lmax+1),nn*lmax+1
     ll=ipsang-(nn-1)*lmax-1
     if (nproj_tmp(ipsang)>0) then
       read(tmp_unit,*, err=10, iomsg=errmsg) llin,ekb(iln0+1:iln0+nproj_tmp(ipsang))
       if(llin/=ll) then
         ll_err=ipsang
         exit
       end if
       do irad=1,mmax
         read(tmp_unit,*, err=10, iomsg=errmsg)jj,rad(irad),vpspll(irad,iln0+1:iln0+nproj_tmp(ipsang))
       end do
       iln0=iln0+nproj_tmp(ipsang)
     elseif(ll==lloc .and. nn==1) then
       read(tmp_unit,*, err=10, iomsg=errmsg) llin
       if(llin/=ll) then
         ll_err=ipsang
         exit
       end if
       do irad=1,mmax
         read(tmp_unit,*, err=10, iomsg=errmsg)jj,rad(irad),vloc(irad)
       end do
     end if
   end do !ipsang
!Provision for general local potential /= any angular momentum potential
   if(nn==1 .and. lloc>lmax) then
     read(tmp_unit,*, err=10, iomsg=errmsg) llin
     if(llin==lloc) then
       do irad=1,mmax
         read(tmp_unit,*, err=10, iomsg=errmsg)jj,rad(irad),vloc(irad)
       end do
     else
       ll_err=lloc+1
       exit
     end if
   end if
 end do !nn

 if(ll_err>0) then
   write(msg, '(5a,i4,a,i4,a,a)' )&
&   'Pseudopotential input file does not have angular momenta in order',ch10,&
&   'or has inconsistent general local potential index',ch10,&
&   'Expected',ll_err-1,' , got',ll,ch10,&
&   'Action: check your pseudopotential input file.'
   ABI_ERROR(msg)
 end if

!Check that rad grid is linear starting at zero
 amesh=rad(2)-rad(1)
 damesh=zero
 do irad=2,mmax-1
   damesh=max(damesh,abs(rad(irad)+amesh-rad(irad+1)))
 end do
 if(damesh>tol8 .or. rad(1)/=zero) then
   write(msg, '(5a)' )&
&   'Pseudopotential input file requires linear radial mesh',ch10,&
&   'starting at zero.',ch10,&
&   'Action: check your pseudopotential input file.'
   ABI_ERROR(msg)
 end if

!Get core charge function and derivatives, if needed
 if(fchrg>1.0d-15)then
   call psp8cc(mmax,n1xccc,rchrg,xccc1d)
!  The core charge function for pspcod=8 becomes zero beyond rchrg.
!  Thus xcccrc must be set equal to rchrg.
   xcccrc=rchrg
 else
   xccc1d(:,:) = zero
   xcccrc = zero
   fchrg = zero
   qchrg = zero
 end if

 maxrad = rad(mmax)

!!   DEBUG
!    write(std_out,*)' xcccrc = ', xcccrc, rchrg
!    write(std_out,*)
!    write(std_out,*) '# psp8in NLCC data ', n1xccc, xcccrc
!    do ii = 1, n1xccc
!    write(std_out,'(7e20.8)')xcccrc*(ii-1.d0)/(n1xccc-1.d0),xccc1d(ii,1),&
! &         xccc1d(ii,2),xccc1d(ii,3),xccc1d(ii,4),xccc1d(ii,5),xccc1d(ii,6)
!    enddo
!    write(std_out,*)
!    stop
!!   ENDDEBUG


!--------------------------------------------------------------------
!Carry out calculations for local (lloc) pseudopotential.
!Obtain Fourier transform (1-d sine transform) to get q^2 V(q).

 call psp8lo(amesh,epsatm,mmax,mqgrid,qgrid,vlspl(:,1),rad,vloc,yp1,ypn,zion)

!Fit spline to q^2 V(q) (Numerical Recipes subroutine)
 ABI_MALLOC(work_spl,(mqgrid))
 call spline (qgrid,vlspl(:,1),mqgrid,yp1,ypn,work_spl)
 vlspl(:,2)=work_spl(:)
 ABI_FREE(work_spl)

!!  DEBUG
! write(std_out,*)'# Vlocal = '
! write(std_out,*)' amesh  = ', amesh
! write(std_out,*)' epsatm = ', epsatm
! write(std_out,*)' mmax   = ', mmax
! write(std_out,*)' mqgrid = ', mqgrid
! do ir = 1, mqgrid
!   write(std_out,*)'   qgrid = ', ir, qgrid(ir)
! enddo
! do ir = 1, mqgrid
!   write(std_out,'(a,i5,2f20.12)')'   iq, vlspl = ', ir, vlspl(ir,1), vlspl(ir,2)
! enddo
! write(std_out,*)
! do ir = 1, mmax
!   write(std_out,*)'   rad   = ', rad(ir), vloc(ir)
! enddo
! write(std_out,*)
! write(std_out,*)' yp1    = ', yp1
! write(std_out,*)' ypn    = ', ypn
! write(std_out,*)' zion   = ', zion
! stop
!!  ENDDEBUG


!--------------------------------------------------------------------
!Take care of non-local part

!Allow for option of no nonlocal corrections (lloc=lmax=0)
 if (lloc==0.and.lmax==0) then
   write(msg, '(a,f5.1)' ) ' Note: local psp for atom with Z=',znucl
   call wrtout([std_out, ab_out], msg)
 else

!  Compute Vanderbilt-KB form factors and fit splines
   call psp8nl(amesh,ffspl,indlmn,lmax,lmnmax,lnmax,mmax,mqgrid,qgrid,rad,vpspll)

 end if

!!  DEBUG
! write(std_out,*)'# KB Projectors = '
! write(std_out,*)' amesh  = ', amesh
! do ir = 1, mqgrid
!   do il = 1, lnmax
!     write(std_out,*)' iq, il, ffspl = ', ir, il, ffspl(ir,1,il), ffspl(ir,2,il)
!   enddo
! enddo
! do il = 1, lmnmax
!   write(std_out,*)' indlmn = ', il, indlmn(:,il)
! enddo
! write(std_out,*)' lmax   = ', lmax
! write(std_out,*)' lmnmax = ', lmnmax
! write(std_out,*)' lnmax  = ', lnmax
! write(std_out,*)' mmax   = ', mmax
! write(std_out,*)' mqgrid = ', mqgrid
! do ir = 1, mqgrid
!   write(std_out,*)'   qgrid = ', ir, qgrid(ir)
! enddo
! do il = 1, lnmax
!   write(std_out,*)
!   write(std_out,*)'# il = ', il
!   do ir = 1, mmax
!     write(std_out,*)'   rad   = ', rad(ir), vpspll(ir,il)
!   enddo
! enddo
! stop
!!  ENDDEBUG

! Read pseudo valence charge in real space on the linear mesh
! and transform it to reciprocal space on a regular grid. Use vloc as workspace.
 vloc(:) = zero
 if (has_tvale) then
   do irad=1,mmax
     read(tmp_unit,*, err=10, iomsg=errmsg)jj,rad(irad),vloc(irad)
     vloc(irad) = vloc(irad) / four_pi
   end do

   ! Check that rad grid is linear starting at zero
   amesh=rad(2)-rad(1)
   damesh=zero
   do irad=2,mmax-1
     damesh=max(damesh,abs(rad(irad)+amesh-rad(irad+1)))
   end do
   if(damesh>tol8 .or. rad(1)/=zero) then
     write(msg, '(5a)' )&
&     'Pseudopotential input file requires linear radial mesh',ch10,&
&     'starting at zero.',ch10,&
&     'Action: check your pseudopotential input file.'
     ABI_ERROR(msg)
   end if

   !  Evaluate spline-fit of the atomic pseudo valence charge in reciprocal space.
   call pawrad_init(mesh,mesh_size=mmax,mesh_type=1,rstep=amesh)
   call nctab_eval_tvalespl(nctab, zion, mesh, vloc, mqgrid_vl, qgrid_vl)
   call pawrad_free(mesh)
 end if

 ABI_FREE(vpspll)
 ABI_FREE(vloc)
 ABI_FREE(rad)
 ABI_FREE(nproj_tmp)

 return

 ! Handle IO error
 10 continue
 ABI_ERROR(errmsg)

end subroutine psp8in
!!***

!!****f* m_psp8/psp8cc
!! NAME
!! psp8cc
!!
!! FUNCTION
!! Compute the core charge density, for use in the XC core
!! correction, following the function definition valid
!! for format 8 of the pseudopotentials.
!!
!! INPUTS
!!  mmax=maximum number of points in real space grid in the psp file
!!  n1xccc=dimension of xccc1d ; 0 if no XC core correction is used
!!  rchrg=cut-off radius for the core density
!!
!! OUTPUT
!!  xccc1d(n1xccc,6)= 1D core charge function and its four first derivatives
!!
!! PARENTS
!!      m_psp8
!!
!! CHILDREN
!!
!! SOURCE

subroutine psp8cc(mmax,n1xccc,rchrg,xccc1d)

!Arguments ------------------------------------
!scalars
 integer,intent(in) :: mmax,n1xccc
 real(dp),intent(in) :: rchrg
!arrays
 real(dp),intent(inout) :: xccc1d(n1xccc,6) !vz_i

!Local variables-------------------------------
!scalars
 integer :: i1xccc,idum,irad,jj
 real(dp) :: amesh,c1,c2,c3,c4,damesh,dri,pi4i,tff,xp,xpm1,xpm2,xpp1,xx
 character(len=500) :: msg,errmsg
!arrays
 real(dp) :: rscale(5)
 real(dp),allocatable :: ff(:,:),rad(:)

!**********************************************************************

 ABI_MALLOC(ff,(mmax,5))
 ABI_MALLOC(rad,(mmax))

 pi4i=quarter/pi
!
!Read from pp file the model core charge and its first 4 derivatives
!assumed to be on a linear grid starting at zero.
!The input functions contain the 4pi factor, and must be rescaled.

 do irad=1,mmax
   read(tmp_unit,*, err=10, iomsg=errmsg) idum,rad(irad),(ff(irad,jj),jj=1,5)
 end do

!Check that rad grid is linear starting at zero
 amesh=rad(2)-rad(1)
 damesh=zero
 do irad=2,mmax-1
   damesh=max(damesh,abs(rad(irad)+amesh-rad(irad+1)))
 end do

 if(damesh>tol8 .or. rad(1)/=zero) then
   write(msg, '(5a)' )&
   'Pseudopotential input file requires linear radial mesh',ch10,&
   'starting at zero.',ch10,&
   'Action: check your pseudopotential input file.'
   ABI_ERROR(msg)
 end if

!Check that input rchrg is consistent with last grid point
 if(rchrg>rad(mmax)) then
   write(msg, '(5a)' )&
   'Pseudopotential input file core charge mesh',ch10,&
   'is inconsistent with rchrg in header.',ch10,&
   'Action: check your pseudopotential input file.'
   ABI_ERROR(msg)
 end if

!Factors for unit range scaling
 do jj = 1, 5
   rscale(jj)=rchrg**(jj-1)
 end do

!Generate uniform mesh xx in the box cut by rchrg
!and interpolate the core charge and derivatives
!Cubic polynomial interpolation is used which is consistent
!with the original interpolation of these functions from
!a log grid to the input linear grid.

 dri=1.d0/amesh
 do i1xccc=1,n1xccc
   xx=(i1xccc-1)* rchrg/dble(n1xccc-1)

!  index to find bracketing input mesh points
   irad = int(dri * xx) + 1
   irad = max(irad,2)
   irad = min(irad,mmax-2)
!  interpolation coefficients
   xp = dri * (xx - rad(irad))
   xpp1 = xp + one
   xpm1 = xp - one
   xpm2 = xp - two
   c1 = -xp * xpm1 * xpm2 * sixth
   c2 = xpp1 * xpm1 * xpm2 * half
   c3 = - xp * xpp1 * xpm2 * half
   c4 = xp * xpp1 * xpm1 * sixth
!  Now do the interpolation on all derivatives for this grid point
!  Include 1/4pi normalization and unit range scaling
   do jj=1,5
     tff =  c1 * ff(irad - 1, jj) &
&     + c2 * ff(irad    , jj) &
&     + c3 * ff(irad + 1, jj) &
&     + c4 * ff(irad + 2, jj)
     xccc1d(i1xccc,jj)=pi4i*rscale(jj)*tff
   end do
 end do

!5th derivative is apparently not in use, so set to zero
 xccc1d(:,6)=zero

 ABI_FREE(ff)
 ABI_FREE(rad)

 return

 ! Handle IO error
 10 continue
 ABI_ERROR(errmsg)

end subroutine psp8cc
!!***

end module m_psp8
!!***
