!===================================================================================
!
! Routines:
!
! (1) kernel (main)      Originally By MLT       Last Modified: 5/5/2008 (JRD)
!
!     See README_kernel for more information.
!
!     Calculates the kernel, direct and exchange parts, of the Bethe-Salpeter
!     equation. The direct part is decomposed in head, wing, body, and the
!     exchange part involves only the "proper" part of the Coulomb
!     interaction. Spin-polarized case implemented.
!
!     For more details, see:
!     Rohlfing & Louie, PRB 62:(8), 4927 (2000)
!     G. Strinati, Rivista del Nuovo Cimento 11:(12), 1 (1988)
!
!     Code originally written by Gian-Marco Rignanese, Eric K Chang.
!
!     All cited equations refer to Rohlfing & Louie (PRB (62):4927, 2000)
!     unless specified otherwise.
!
!===================================================================================

#include "f_defs.h"

program kernel

#ifdef HDF5
  use hdf5
#endif

  use global_m
  use check_screening_m
  use fftw_m
  use fullbz_m
  use io_utils_m
  use mtxel_kernel_m
  use vcoul_generator_m
  use bsewrite_m
  implicit none

  type (crystal) :: crys
  type (symmetry) :: syms
  type (gspace) :: gvec
  type (xctinfo) :: xct
  type (grid) :: kg,qg,kgq
  type (kpoints) :: kp
  type (wavefunction) :: wfnc,wfncp
  type (wavefunction) :: wfnv,wfnvp
  type (int_wavefunction) :: intwfnv,intwfnc
  type (twork_scell) :: work_scell

  character :: filename*20
  integer :: ii,jj,ijk,ikq,iparallel,iownsize
  integer :: ik,ikp
  integer :: ncount,ntim,flagbz
  integer :: ic,iv,icp,ivp,error,umk
  integer :: ifqa_dummy,irqa_dummy,g0a_dummy(3)
  real(DP) :: vq0, avgcut, oneoverq, q0len,delta
  real(DP) :: tsec(2),tmin(2),tmax(2),q0vec(3),vq(3),qq(3)
  real(DP) :: qqa_dummy,fqa_dummy(3),vcoul0(1)
  SCALAR :: epsheaddummy, wcoul0dummy

  character*16, allocatable :: routnam(:)
  integer, allocatable :: indexq(:),irqa(:),ifqa(:),g0a(:,:)
  integer, allocatable :: isrtq(:)
  real(DP), allocatable :: vcoul(:),vcoularray(:,:),fqa(:,:),qqa(:),vcoularray_mod(:,:)
  SCALAR, allocatable :: &
    bsedbody(:,:,:),bsedhead(:,:,:), &
    bsedwing(:,:,:),bsex(:,:,:),bset(:,:,:)

  type(progress_info) :: prog_info !< a user-friendly progress report

!----------------- Begin Program ----------------------------------------------

  call peinfo_init()

!----------------------
! Dont create random numbers

  peinf%jobtypeeval = 0

!----------------------
! Initialize timer

  call timacc(0,0)
  call timacc(1,1)
  
  call write_program_header('BSE/Kernel', .false.)
  
!------------------------
! Read kernel.inp

  call logit('Calling inread_kernel')
  call open_file(8,file='kernel.inp',form='formatted',status='old')
  call inread_kernel(xct,flagbz,q0vec,qg)
  call close_file(8)

  if (xct%iwritecoul .eq. 1 .and. peinf%inode .eq. 0) then
    call open_file(19,file='vcoul',form='formatted',status='replace')
  endif

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

#ifdef HDF5
  if(xct%use_hdf5) call h5open_f(error)
#endif

!-------------------------
! Read WFN_fi

  call timacc(2,1)
  call logit('Calling input_kernel')

! JRD: What routine we call depends on if we have center-of-mass momentum.

  if (xct%qflag .eq. 0) then
    call die("Center-of-mass momentum is broken.") ! if indeed it ever worked...
    !call input_kernel_q(crys,gvec,kg,kgq,kp,kpq,syms,xct,flagbz)
    SAFE_ALLOCATE(indexq, (kg%nf))
    do ijk = 1, kg%nf
      indexq(ijk)=xct%indexq(ijk)
    enddo
  else
    call input_kernel(crys,gvec,kg,kp,syms,xct,flagbz,intwfnv,intwfnc)
    SAFE_ALLOCATE(indexq, (kg%nf))
    ! DYQ: Use a center-of-mass momentum commensurate with the kgrid of WFN_co, when qflag=2
    ! Find the index of the point in kg corresponding to kg%f+xct%finiteq
    ! and store the index mapping in indexq
    if (xct%qflag .eq. 2) then 
    else
      do ijk=1,kg%nf
        indexq(ijk)=ijk
      enddo
    endif
  endif

  call timacc(2,2)

!      if(peinf%inode.eq.0) write(6,*) 'Exit input_kernel'

! JRD: Write some info about our calculation

  if (peinf%inode.eq.0) then
    write(6,*)
    if (xct%theory.eq.0) then
      write(6,*) ' Bethe-Salpeter Calculation'
    elseif (xct%theory.eq.1) then
      write(6,*) ' Time-dependent Density Functional Theory Calculation'
    endif
    write(6,*) ' valence bands limits : ', xct%nvb_co,' (total) '
    write(6,*) ' cond.   bands limits : ', xct%ncb_co,' (total) '
    write(6,*) ' number of spins   = ',xct%nspin
  endif

!----------------------------------
! Read eps0mat and epsmat

  if (xct%theory.eq.0) then
    call logit('Calling epscopy')
    call timacc(3,1)
    call epscopy(crys,gvec,syms,qg,xct,q0vec)
    call timacc(3,2)
  elseif (xct%theory.eq.1) then
    call logit('Calling tddft_bz_gen')
    call timacc(3,1)
    call tddft_bz_gen(crys,syms,qg,xct)
    call timacc(3,2)
  endif

!------------------ Initialize BSE Arrays ----------------------------------------------
  if ( xct%ivpar .eq. 1) then
    iownsize=1
  else if ( xct%icpar .eq. 1) then
    iownsize=(xct%nvb_co)**2
  else
    iownsize=(xct%n1b_co*xct%n2b_co)**2
  endif

  if (xct%theory .eq. 0) then
    SAFE_ALLOCATE(bsedbody, (peinf%myown*iownsize,xct%nspin,xct%nspin))
    SAFE_ALLOCATE(bsedhead, (peinf%myown*iownsize,xct%nspin,xct%nspin))
    SAFE_ALLOCATE(bsedwing, (peinf%myown*iownsize, xct%nspin,xct%nspin))
    bsedbody(:,:,:) = ZERO
    bsedhead(:,:,:) = ZERO
    bsedwing(:,:,:) = ZERO
  else if (xct%theory .eq. 1) then
    SAFE_ALLOCATE(bsedbody, (peinf%myown*iownsize,xct%nspin,xct%nspin))
    SAFE_ALLOCATE(bsedhead, (peinf%myown*iownsize,xct%nspin,xct%nspin))
    SAFE_ALLOCATE(bset, (peinf%myown*iownsize,xct%nspin,xct%nspin))
    bsedbody(:,:,:) = ZERO
    bsedhead(:,:,:) = ZERO
    bset(:,:,:) = ZERO
  endif
  ! We always need exchange
  SAFE_ALLOCATE(bsex, (peinf%myown*iownsize,xct%nspin,xct%nspin))
  bsex(:,:,:) = ZERO

  if (peinf%inode.eq.0) write(6,*)
  
!--------- Calculate Needed Coulomb Interaction -------------------------------

  SAFE_ALLOCATE(vcoul, (xct%ng))
  SAFE_ALLOCATE(vcoularray, (xct%ng,qg%nf))
  vcoularray=0d0

  ! This array is for the direct part of the TDDFT and
  ! vcoularray will be for the exchange. This part will
  ! get modified if one is doing TD-Hybrids
  if (xct%theory .eq. 1) then
    SAFE_ALLOCATE(vcoularray_mod, (xct%ng,qg%nf))
    vcoularray_mod=0d0
  endif
  SAFE_ALLOCATE(isrtq, (xct%ng))
  do ijk=1,xct%ng
    isrtq(ijk) = ijk
  enddo
  
  if (peinf%inode .eq. 0) then
    write(6,701)
  endif
  701 format(1x,'Calculating Vcoul',/)

  avgcut=TOL_ZERO
  q0len = sqrt(DOT_PRODUCT(q0vec,MATMUL(crys%bdot,q0vec)))

  iparallel=1

  do ik=1,qg%nf
    vq(:)=qg%f(:,ik)
    vq0 = DOT_PRODUCT(vq,MATMUL(crys%bdot,vq))
    
#ifdef VERBOSE
    if (peinf%inode .eq. 0) then
      write(6,*) 'Calculating Vcoul', ik, qg%nf
    endif
#endif

    call vcoul_generator(xct%icutv,xct%truncval,gvec, &
      crys%bdot,kg%nf,xct%ng,isrtq,xct%iscreen,vq,q0vec, &
      vcoul,xct%iwritecoul,iparallel,avgcut,oneoverq, &
      kp%kgrid,epsheaddummy,work_scell,.false.,wcoul0dummy)
    vcoularray(:,ik)=vcoul(:)

    if (xct%theory .eq. 1) then
      if (xct%coul_mod_flag) then
        call vcoul_generator(xct%icutv,xct%truncval,gvec, &
          crys%bdot,kg%nf,xct%ng,isrtq,xct%iscreen,vq,q0vec, &
          vcoul,xct%iwritecoul,iparallel,avgcut,oneoverq, &
          kp%kgrid,epsheaddummy,work_scell,.false.,wcoul0dummy,coulomb_mod=xct%coulomb_mod)
        vcoularray_mod(:,ik)=vcoul(:)
      else
        vcoularray_mod(:,ik)=vcoul(:)
      endif
    endif

    if (vq0 .lt. TOL_Zero) then
      if (peinf%inode .eq. 0) then
        write(6,801) q0vec
      endif
      vq(:) = q0vec(:)
801 format(1x,'For G=0: setting q0 =',3f10.6,/)

      if (xct%theory .ne. 1) call check_screening_trunc(xct%icutv,xct%iscreen,q0vec,crys%bdot)
    
      vcoul0(1)=0d0
      call vcoul_generator(xct%icutv,xct%truncval,gvec, &
      crys%bdot,kg%nf,1,isrtq,xct%iscreen,vq,q0vec, &
        vcoul0(:),xct%iwritecoul,iparallel,avgcut,oneoverq, &
        kp%kgrid,epsheaddummy,work_scell,.false.,wcoul0dummy)

      vcoularray(1,ik)=vcoul0(1)

      if (xct%theory .eq. 1) then
        if (xct%coul_mod_flag) then
          vcoul0(1)=0d0
          call vcoul_generator(xct%icutv,xct%truncval,gvec, &
            crys%bdot,kg%nf,1,isrtq,xct%iscreen,vq,q0vec, &
            vcoul0(:),xct%iwritecoul,iparallel,avgcut,oneoverq, &
            kp%kgrid,epsheaddummy,work_scell,.false.,wcoul0dummy,coulomb_mod=xct%coulomb_mod)

          vcoularray_mod(1,ik)=vcoul0(1)
        else
          vcoularray_mod(1,ik)=vcoul0(1)
        endif
      endif
    endif

  enddo ! ik

  SAFE_DEALLOCATE(isrtq)
  call destroy_qran()

  vcoularray=vcoularray/(8d0*PI_D)
  if (xct%theory .eq. 1) then
    vcoularray_mod=vcoularray_mod/(8d0*PI_D)
  endif
  
#ifdef VERBOSE
  if (peinf%inode .eq. 0) then
    write(6,*) 'Finished Vcoul', ik, qg%nf
  endif
#endif

  SAFE_DEALLOCATE(vcoul)

!--------- Start the computation. ---------------------------------------------

  call logit('Starting main kernel loop')
  if (peinf%inode.eq.0) write(6,771) peinf%myown
771 format(1x,"Starting calculation of kernel with",i6,1x, &
      "blocks of pairs per PE",/)
  
  SAFE_ALLOCATE(qqa, (peinf%myown))
  SAFE_ALLOCATE(fqa, (3,peinf%myown))
  SAFE_ALLOCATE(g0a, (3,peinf%myown))
  SAFE_ALLOCATE(irqa, (peinf%myown))
  SAFE_ALLOCATE(ifqa, (peinf%myown))
  
  call sortbyq(fqa,qqa,g0a,ifqa,irqa,qg,kg,crys)

! JRD: The below may be useful for debugging
!
!  call mpi_barrier(mpi_comm_world,mpierr)
!  write(6,*) 'myown',peinf%inode,peinf%myown
!  call mpi_barrier(mpi_comm_world,mpierr)

  ! FHJ: this is to generate nice output / time estimate
  call progress_init(prog_info, 'calculation of matrix elements', 'block', peinf%nckpe)

  do ii=1,peinf%nckpe

   ! FHJ : friendly output / running time estimate
    call progress_step(prog_info, ii)

    call logitint('   Main loop:  ii=',ii)
    if (ii .le. peinf%myown) then
      ik=peinf%ik(peinf%inode+1,ii)
      ikp=peinf%ikp(peinf%inode+1,ii)
      
      if (xct%icpar .eq. 1) then
        ic=peinf%ic(peinf%inode+1,ii)
        icp=peinf%icp(peinf%inode+1,ii)
      else
        ic=1
        icp=1
      endif
      
      if (xct%ivpar .eq. 1) then
        iv=peinf%iv(peinf%inode+1,ii)
        ivp=peinf%ivp(peinf%inode+1,ii)
      else
        iv=1 
        ivp=1 
      endif
      
      call timacc(4,1)
      call logit('   Calling genwf_kernel')
      
      !write(6,*) peinf%inode,'calling gw 1', ii, ik
      ! DYQ: returns wfnv at indexq(ik) and wfnc at ik
      call genwf_kernel(crys,gvec,kg,kgq,syms,wfnc, &
        wfnv,xct%nspin,ik,ic,iv,indexq,xct,intwfnv,intwfnc)
      
      !write(6,*) peinf%inode,'calling gw 2', ii, ikp

      ! returns wfnv at indexq(ikp) and wfnc at ikp
      call genwf_kernel(crys,gvec,kg,kgq,syms,wfncp, &
        wfnvp,xct%nspin,ikp,icp,ivp,indexq,xct,intwfnv,intwfnc)

      call timacc(4,2)
      
    else
      ik=-1
      ikp=-1
      ic=-1
      icp=-1
      iv=-1
      ivp=-1
    endif
#ifdef VERBOSE
    if (peinf%inode.eq.0) then
      write(6,772) ii
      write(6,773) ik,ikp,ic,icp,iv,ivp
    endif
772 format(1x,"PE # 0 dealing with block",i6)
773 format(1x,"ik =",i6,1x,"ikp =",i6,1x,"ic =",i6,1x,"icp =",i6,1x,"iv =",i6,1x,"ivp =",i6)
#endif

    call logit('      Calling mtxel_kernel')
    call timacc(6,1)

    if (ii .le. peinf%myown) then
      if (xct%theory .eq. 0) then
        call mtxel_kernel(crys,gvec,syms,qg,wfnc,wfncp,wfnvp, &
          wfnv,xct,peinf%myown*iownsize,bsedbody,bsedhead,bsedwing,bsex,ii,ik,ikp, &
          ic,icp,iv,ivp, &
          vcoularray,fqa(:,ii),qqa(ii),g0a(:,ii),ifqa(ii),irqa(ii),q0len)
      else if (xct%theory .eq. 1) then
      endif

      SAFE_DEALLOCATE_P(wfncp%cg)
      SAFE_DEALLOCATE_P(wfncp%isort)
      SAFE_DEALLOCATE_P(wfnvp%cg)
      SAFE_DEALLOCATE_P(wfnvp%isort)
      SAFE_DEALLOCATE_P(wfnc%cg)
      SAFE_DEALLOCATE_P(wfnc%isort)
      SAFE_DEALLOCATE_P(wfnv%cg)
      SAFE_DEALLOCATE_P(wfnv%isort)
    else
      if (xct%iwriteint .ne. 0) then
        !            write(6,*) peinf%inode, 'Calling mtxel without task'
        fqa_dummy(:)=0.0d0
        qqa_dummy=0.0d0
        g0a_dummy(:)=0
        ifqa_dummy=0
        irqa_dummy=0
        if (xct%theory .eq. 0) then
          call mtxel_kernel(crys,gvec,syms,qg,wfnc,wfncp,wfnvp,wfnv, &
            xct,peinf%myown*iownsize,bsedbody,bsedhead,bsedwing,bsex,ii,ik,ikp,ic,icp, &
            iv,ivp, &
            vcoularray,fqa_dummy,qqa_dummy,g0a_dummy,ifqa_dummy,irqa_dummy,q0len)
        else if (xct%theory .eq. 1) then
        endif

      endif
    endif
    
    call timacc(6,2)

  enddo !ii

  if (xct%qflag .eq. 0) call dealloc_grid(kgq)
  call dealloc_grid(qg)
  call progress_free(prog_info)

  SAFE_DEALLOCATE_P(intwfnv%cg)
  SAFE_DEALLOCATE_P(intwfnc%cg)
  SAFE_DEALLOCATE_P(intwfnv%isort)
  SAFE_DEALLOCATE_P(intwfnc%isort)
  SAFE_DEALLOCATE_P(intwfnv%ng)
  SAFE_DEALLOCATE_P(intwfnc%ng)
  
  SAFE_DEALLOCATE(qqa)
  SAFE_DEALLOCATE(fqa)
  SAFE_DEALLOCATE(g0a)
  SAFE_DEALLOCATE(irqa)
  SAFE_DEALLOCATE(ifqa)
  if (xct%theory .eq. 0) then
    SAFE_DEALLOCATE_P(xct%epsdiag)
  endif
  if (peinf%inode .eq. 0 .or. xct%bLowComm) then
    SAFE_DEALLOCATE_P(xct%isrtqi)
  endif
  if (xct%iwriteint .eq. 1 .and. xct%theory .eq. 0) then
    SAFE_DEALLOCATE_P(xct%epsown)
    SAFE_DEALLOCATE_P(xct%epsowni)
    SAFE_DEALLOCATE_P(xct%maxpe)
    SAFE_DEALLOCATE_P(xct%epscol)
  endif
  SAFE_DEALLOCATE_P(peinf%nxqown)
  SAFE_DEALLOCATE_P(peinf%nxqi)
  

!--------------- Write BSE matrices ----------------------------------------------

  call timacc(8,1)
  if (xct%theory .eq. 0) then
    call bsewrite(xct,iownsize,bsedbody,bsedhead,bsex,kg,kp,gvec,syms,crys, &
      bsedwing=bsedwing)
  else if (xct%theory .eq. 1) then
    call bsewrite(xct,iownsize,bsedbody,bsedhead,bsex,kg,kp,gvec,syms,crys, &
      bset=bset)
  endif
  call timacc(8,2)

  call dealloc_grid(kg)

  call destroy_fftw_plans()

  if (xct%theory .eq. 0) then
    SAFE_DEALLOCATE(bsedhead)
    SAFE_DEALLOCATE(bsedwing)
    SAFE_DEALLOCATE(bsedbody)
  else if (xct%theory .eq. 1) then
    SAFE_DEALLOCATE(bsedhead)
    SAFE_DEALLOCATE(bsedbody)
    SAFE_DEALLOCATE(bset)
  endif 
  SAFE_DEALLOCATE(bsex)
  SAFE_DEALLOCATE(indexq)

  if (xct%iwritecoul .eq. 1) then
    if (peinf%inode .eq. 0) then
      call close_file(19) ! file vcoul
    endif
  endif

!---------------- Time accounting -----------------------------------------------


  ntim=8
  SAFE_ALLOCATE(routnam, (76))
  routnam(1)='TOTAL:'
  routnam(2)='INPUT:'
  routnam(3)='EPSCOPY:'
  routnam(4)='GENWF:'
  routnam(5)='EXCWF:'
  routnam(6)='MTXEL:'
  routnam(7)='FULLBZ:'
  routnam(8)='BSEWRITE:'
  
  call timacc(1,2)
  if(peinf%inode.eq.0) then
    write(6,*)
    write(6,9000) 'CPU [s]','WALL [s]','#'
    write(6,*)
  endif
  
  do ii=2,ntim
    call timacc(ii,3,tsec,ncount)
#ifdef MPI
    call MPI_ALLREDUCE(tsec,tmin,2,MPI_REAL_DP,MPI_MIN,MPI_COMM_WORLD,mpierr)
    call MPI_ALLREDUCE(tsec,tmax,2,MPI_REAL_DP,MPI_MAX,MPI_COMM_WORLD,mpierr)
#else
    tmin = tsec
    tmax = tsec
#endif
    if(peinf%inode.eq.0) then
      write(6,9001) routnam(ii),tmin(1),tmin(2),ncount
      write(6,9002) tsec(1),tsec(2)
      write(6,9003) tmax(1),tmax(2)
    endif
  enddo

! JRD More Time Accounting for mtxel_kernel

  routnam(61)='MTXEL Setup:'
  routnam(62)='MTXEL Vcoul:'
  routnam(63)='MTXEL W:'
  routnam(64)='MTXEL W-Sum:'
  routnam(65)='MTXEL FFT Dir:'
  routnam(66)='MTXEL High G:'
  routnam(67)='MTXEL FFT X:'
  routnam(68)='MTXEL BSEX:'
  routnam(69)='MTXEL INDEX:'
  routnam(70)='MTXEL EPSHEAD:'
  routnam(71)='MTXEL EPSREAD:'
  routnam(72)='MTXEL EPSOPEN:'
  routnam(73)='MTXEL G SUM:'
  routnam(74)='MTXEL COMM:'
  routnam(75)='BSEWRITE COMM:'
  routnam(76)='BSEWRITE I/O:'
  
  do ii=61,76
    call timacc(ii,3,tsec,ncount)
#ifdef MPI
    call MPI_Reduce(tsec,tmin,2,MPI_REAL_DP,MPI_MIN,0,MPI_COMM_WORLD,mpierr)
    call MPI_Reduce(tsec,tmax,2,MPI_REAL_DP,MPI_MAX,0,MPI_COMM_WORLD,mpierr)
#else
    tmin=tsec
    tmax=tsec
#endif
    if(peinf%inode.eq.0) then
      write(6,9001) routnam(ii),tmin(1),tmin(2),ncount
      write(6,9002) tsec(1),tsec(2)
      write(6,9003) tmax(1),tmax(2)
    endif
  enddo

  routnam(30)='MTXEL FFT CC:'
  routnam(31)='MTXEL FFT VV:'
  routnam(32)='MTXEL FIND:'
  routnam(33)='MTXEL ALLOC:'
  routnam(34)='MTXEL FFTBOX:'
  routnam(35)='MTXEL FFT VC:'

  do ii=30,35
    call timacc(ii,3,tsec,ncount)
#ifdef MPI
    call MPI_Reduce(tsec,tmin,2,MPI_REAL_DP,MPI_MIN,0,MPI_COMM_WORLD,mpierr)
    call MPI_Reduce(tsec,tmax,2,MPI_REAL_DP,MPI_MAX,0,MPI_COMM_WORLD,mpierr)
#else
    tmin=tsec
    tmax=tsec
#endif
    if(peinf%inode.eq.0) then
      write(6,9001) routnam(ii),tmin(1),tmin(2),ncount
      write(6,9002) tsec(1),tsec(2)
      write(6,9003) tmax(1),tmax(2)
    endif
  enddo
  
  if(peinf%inode.eq.0) write(6,*)
  
  call timacc(1,3,tsec,ncount)
#ifdef MPI
  call MPI_Reduce(tsec,tmin,2,MPI_REAL_DP,MPI_MIN,0,MPI_COMM_WORLD,mpierr)
  call MPI_Reduce(tsec,tmax,2,MPI_REAL_DP,MPI_MAX,0,MPI_COMM_WORLD,mpierr)
#else
  tmin=tsec
  tmax=tsec
#endif
  
  if(peinf%inode.eq.0) then
    write(6,9004) routnam(1),tmin(1),tmin(2)
    write(6,9002) tsec(1),tsec(2)
    write(6,9003) tmax(1),tmax(2)
    write(6,*)
  endif
  
9000 format(22x,a13,3x,a13,3x,a8)
9001 format(1x,a16,'(min.)',f13.3,3x,f13.3,3x,i8)
9002 format(  17x,'(PE 0)',f13.3,3x,f13.3)
9003 format(  17x,'(max.)',f13.3,3x,f13.3)
9004 format(1x,a16,'(min.)',f13.3,3x,f13.3)
  
  call write_memory_usage()

! Delete the intermediate working files

!  do ii = 0, peinf%npes-1
!    if (ii.eq.peinf%inode) then
!      call close_file(128+3*ii  , delete = .true.) ! files INT_VWFN_*
!      call close_file(128+3*ii+1, delete = .true.) ! files INT_CWFN_*
!    endif
!  enddo
  if (peinf%inode.eq.0 .and. xct%iwriteint .eq. 0) then
    do ii = 0, qg%nr-1
      if (ii.lt.10000) then
        write(filename,'(a,i4.4)') 'INT_EPS_',ii
      endif
      call open_file(128+ii,file=filename,form='unformatted',status='old')
      call close_file(128+ii, delete = .true.) ! files INT_EPS_*
    end do
  endif
  
#ifdef MPI
  call MPI_FINALIZE(mpierr)
#endif

end program kernel
