LCOV - code coverage report
Current view: top level - src/79_seqpar_mpi - m_tddft.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.6 % 724 627
Test Date: 2026-09-21 13:49:52 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !!****m* ABINIT/m_tddft
       2              : !! NAME
       3              : !!  m_tddft
       4              : !!
       5              : !! FUNCTION
       6              : !!  Routines for computing excitation energies within TDDFT
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 1999-2026 ABINIT group (XG, JYR, MB, MBELAND, SHAMEL)
      10              : !! This file is distributed under the terms of the
      11              : !! GNU General Public License, see ~abinit/COPYING
      12              : !! or http://www.gnu.org/copyleft/gpl.txt .
      13              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      14              : !!
      15              : !! NOTES
      16              : !!
      17              : !! SOURCE
      18              : 
      19              : #if defined HAVE_CONFIG_H
      20              : #include "config.h"
      21              : #endif
      22              : 
      23              : #include "abi_common.h"
      24              : 
      25              : module m_tddft
      26              : 
      27              :  use defs_basis
      28              :  use m_abicore
      29              :  use m_xmpi
      30              :  use m_errors
      31              :  use m_wffile
      32              :  use m_sort
      33              :  use m_dtset
      34              :  use m_dtfil
      35              :  use iso_c_binding, only : c_ptr,c_loc,c_f_pointer
      36              : 
      37              :  use defs_abitypes, only : MPI_type
      38              :  use m_io_tools, only : get_unit
      39              :  use m_matrix,   only : matr3inv
      40              :  use m_time,     only : timab
      41              :  use m_fftcore,  only : sphereboundary
      42              :  use m_spacepar, only : hartre
      43              :  use m_mpinfo,   only : proc_distrb_cycle
      44              :  use m_fft,      only : fourwf, fourdp
      45              : 
      46              :  implicit none
      47              : 
      48              :  private
      49              : !!***
      50              : 
      51              : #if defined HAVE_MPI1
      52              :  include 'mpif.h'
      53              : #endif
      54              : 
      55              :  public :: tddft
      56              : !!***
      57              : 
      58              : contains
      59              : 
      60              : !!****f* m_tddft/tddft
      61              : !! NAME
      62              : !! tddft
      63              : !!
      64              : !! FUNCTION
      65              : !! Compute the excitation energies within TDLDA
      66              : !! from input wavefunctions, eigenenergies, and band occupations.
      67              : !!
      68              : !! INPUTS
      69              : !!  cg(2,mpw*nspinor*mband*mkmem*nsppol)=wf in G space
      70              : !!  dtfil <type(datafiles_type)>=variables related to files
      71              : !!  dtset <type(dataset_type)>=all input variables for this dataset
      72              : !!  eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
      73              : !!  etotal=total energy of the ground-state (Ha)
      74              : !!  gmet(3,3)=metrix tensor in G space in Bohr**-2.
      75              : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
      76              : !!  gsqcut=cutoff on (k+G)^2 (bohr^-2)
      77              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates.
      78              : !!  kxc(nfft,nkxc)=exchange-correlation kernel
      79              : !!  mband=maximum number of bands
      80              : !!  mgfftdiel=maximum size of 1D FFTs, for the computation of the dielectric matrix
      81              : !!  mkmem=number of k-points treated by this node.
      82              : !!  mpi_enreg=information about MPI parallelization
      83              : !!  mpw=maximum allowed value for npw
      84              : !!  nfft=(effective) number of FFT grid points (for this processor)
      85              : !!       WARNING about parallelization: see below
      86              : !!  ngfftdiel(18)=contain all needed information about 3D FFT, for dielectric matrix,
      87              : !!                see ~abinit/doc/variables/vargs.htm#ngfft
      88              : !!  nkpt=number of k points
      89              : !!  nkxc=second dimension of the array kxc (see rhotoxc for a description)
      90              : !!  npwarr(nkpt)=number of planewaves at each k point
      91              : !!  nspinor=number of spinorial components of the wavefunctions
      92              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
      93              : !!  occ(mband*nkpt*nsppol)=
      94              : !!          occupation numbers for each band (usually 2.0) at each k point
      95              : !!  ucvol=unit cell volume (Bohr**3)
      96              : !!  wffnew=unit number for current wf disk file
      97              : !!
      98              : !! OUTPUT
      99              : !!  (only writing)
     100              : !!
     101              : !! WARNING:
     102              : !! This routine should not be parallelized on space for the time being,
     103              : !!    because the already existing parallelisation is not the usual one, found
     104              : !!    in the majority of ABINIT routines.
     105              : !!
     106              : !! NOTES
     107              : !! * Only accept nspinor=1, nsppol=1, nkpt=1 (Gamma point), and occopt<3
     108              : !!   (insulating occupation numbers).
     109              : !!   It is expected to make it work for nsppol=2 in the future.
     110              : !!
     111              : !! * For the oscillator strengths, see the paper
     112              : !!   ''Time-Dependent Density Functional Response Theory of Molecular
     113              : !!     systems: Theory, Computational Methods, and Functionals'', by M.E. Casida,
     114              : !!   in Recent Developments and Applications of Modern Density Functional
     115              : !!   Theory, edited by J.M. Seminario (Elsevier, Amsterdam, 1996).
     116              : !!
     117              : !! SOURCE
     118              : 
     119           22 :  subroutine tddft(cg,dtfil,dtset,eigen,etotal,gmet,gprimd,gsqcut,&
     120           22 : &  kg,kxc,mband,mgfftdiel,mkmem,mpi_enreg,mpw,nfft,ngfftdiel,nkpt,nkxc,&
     121           22 : &  npwarr,nspinor,nsppol,occ,ucvol,wffnew)
     122              : 
     123              : !Arguments ------------------------------------
     124              :  integer, intent(in) :: mband,mgfftdiel,mkmem,mpw,nfft,nkpt,nkxc,nsppol
     125              :  integer, intent(in) :: nspinor
     126              :  real(dp), intent(in) :: etotal,gsqcut,ucvol
     127              :  type(datafiles_type), intent(in) :: dtfil
     128              :  type(dataset_type), intent(in) :: dtset
     129              :  type(MPI_type), intent(in) :: mpi_enreg
     130              :  type(wffile_type), intent(inout) :: wffnew
     131              :  integer, intent(in) :: kg(3,mpw*mkmem),ngfftdiel(18),npwarr(nkpt)
     132              :  real(dp), intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol),eigen(mband*nkpt*nsppol)
     133              :  real(dp), intent(in) :: gmet(3,3),gprimd(3,3),kxc(nfft,nkxc),occ(mband*nkpt*nsppol)
     134              : 
     135              : !Local variables-------------------------------
     136              :  integer,parameter :: nexcitout=20
     137              :  integer :: cplex,i1,i2,i3,iband,idir,ier,ierr,iexcit,iexcit1,iexcit2,ifft
     138              :  integer :: old_iexcit,ii,jj,isppol,jsppol,isppol1,isppol2,isppol_l,isppol_n
     139              :  integer :: isppol_n1,isppol_n2,iocc_n1,iocc_n2,iunocc_n1,iunocc_n2,temp_unit2
     140              :  integer :: ikpt,index,iocc,iocc1,iocc2,iocc_l,iocc_n
     141              :  integer :: istwf_k,iunocc,iunocc1,iunocc2,iunocc_l,iunocc_n,istate,jexcit
     142              :  integer :: jexcit_cbase,master,mcg_disk,me_loc
     143           44 :  integer :: nband_k(nsppol), nband_occ(nsppol), nband_unocc(nsppol)
     144           44 :  integer :: nstate_k, nstate_occ, nstate_unocc, nexcit_pol(nsppol)
     145              :  integer :: nstate_win,ndiel,ndiel1,ndiel2,ndiel3,ndiel4
     146              :  integer :: ndiel5,ndiel6,nexcit,nexcit_max,nexcit_win,nfftdiel,nlargest,nnext
     147              :  integer :: nnext1,nnext2
     148              :  integer :: nproc_loc,npw_k,pole_approx,sing_trip,spaceComm,mtag,tim_fourwf
     149              :  integer :: tim_rwwf,save_iomode
     150              :  integer :: rec,recl,idummy,jdummy
     151              :  real(dp) :: buffer,buffer_inv,diffeig,eigunocc,emax_win
     152              :  real(dp) :: factor,ff,flargest,fnext,fr_invsquare,fr_power
     153              :  real(dp) :: fnext1,fnext2
     154              :  real(dp) :: normint,myproduct,saa,sab,sbb
     155              :  real(dp) :: sumx
     156           44 :  real(dp) :: sum_kernel(2/nsppol)
     157              :  real(dp) :: weight,xx
     158              :  logical :: am_master,file_exist
     159           22 :  logical, allocatable :: done_excit(:,:),done_sexc(:) !,done_sexc2(:)
     160              :  character(len=18) :: chain1,chain2
     161              :  character(len=500) :: message
     162           22 :  integer,allocatable :: flag_state_win(:),gbound(:,:),indarr(:),index_state(:)
     163           22 :  integer,allocatable :: kg_k(:,:)
     164           22 :  integer,allocatable :: excit_coords(:,:)
     165              :  integer :: count_to_do, count, displ, countmax, displmax
     166              :  integer :: ijexcit, ijexcit2, sendcount
     167           66 :  real(dp) :: f_sing_trip(2/nsppol),sendbuf(5-nsppol)
     168              :  real(dp) :: cauchy(7),poscart(3),rprimd(3,3),tsec(2),dummy(2,1)
     169              :  integer :: iomode,action,me,nmaster,sender,source,sread,sskip
     170              :  integer :: formeig,icg,ikg,nband_k_
     171              :  logical :: mydata, tmaster, swrite
     172           22 :  integer,allocatable ::  kg_disk(:,:)
     173           22 :  integer,allocatable :: counts(:),displs(:),recvcounts(:),tmpbuf(:)
     174           22 :  real(dp),allocatable :: cg_disk(:,:),cg_tmp(:,:)
     175           22 :  real(dp),allocatable :: cwavef(:,:),eexcit(:)
     176           22 :  real(dp),allocatable :: eexcit2(:)
     177           22 :  real(dp),allocatable :: matr(:)
     178           22 :  real(dp),allocatable :: kxc_for_tddft(:,:,:,:,:,:),omega_tddft_casida(:,:,:,:,:,:,:)
     179           22 :  real(dp),allocatable :: osc_str(:,:),pos(:,:),rhoaug(:,:,:),rhog(:,:)
     180           22 :  real(dp),allocatable :: sexc(:,:),sqrtks(:),vec(:,:,:),vhartr(:),wfprod(:,:,:)
     181           44 :  real(dp) :: omega_tddft_casida_dummy(2/nsppol)
     182           22 :  real(dp),allocatable :: wfraug(:,:,:,:),wfrspa(:,:,:,:),work(:),zhpev1(:,:)
     183           22 :  real(dp),allocatable :: zhpev2(:)
     184              : 
     185              :  integer :: iproc
     186              :  integer :: ipwnbd
     187           22 :  real(dp), allocatable,target :: recvbuf(:,:)
     188           22 :  real(dp),pointer :: recvbuf_ptr(:)
     189              :  type(c_ptr) :: cptr
     190              : 
     191              : ! *************************************************************************
     192              : 
     193              : !Init mpi_comm
     194           22 :  spaceComm=mpi_enreg%comm_cell
     195              : 
     196           22 :  am_master=.true.
     197           22 :  master = 0
     198           44 :  nproc_loc = xmpi_comm_size(spaceComm) !Init ntot proc max
     199           22 :  me_loc    = xmpi_comm_rank(spaceComm) !Define who i am
     200              : 
     201              : #if defined HAVE_MPI
     202           22 :  if (me_loc/=0) then
     203            4 :    am_master=.FALSE.
     204              :  end if
     205           22 :  write(message, '(a,i3,a)' ) ' TDDFT ',nproc_loc,' CPU synchronized'
     206           22 :  call wrtout(std_out,message,'COLL')
     207           22 :  write(message, '(a,3D12.5,a,3D12.5,a,3D12.5)' ) ' gmet ',&
     208           22 : & gmet(1,1),gmet(1,2),gmet(1,3),ch10,&
     209           22 : & gmet(2,1),gmet(2,2),gmet(2,3),ch10,&
     210           44 : & gmet(3,1),gmet(3,2),gmet(3,3)
     211           22 :  call wrtout(std_out,message,'COLL')
     212              : #endif
     213              : 
     214              : 
     215              : !COMMENT these values should become arguments
     216              : !the two first define the energy window
     217              : 
     218           22 :  emax_win=greatest_real*tol6
     219           22 :  if(dtset%td_maxene>tol6)then
     220            1 :    emax_win = dtset%td_maxene
     221              :  end if
     222              : 
     223           22 :  call timab(95,1,tsec)
     224              : 
     225           22 :  istwf_k=dtset%istwfk(1)
     226              : 
     227           22 :  if(nkpt/=1 .or. &
     228              : & abs(dtset%kptns(1,1))+abs(dtset%kptns(2,1))+abs(dtset%kptns(3,1))>1.0d-6 )then
     229              :    write(message, '(a,a,a,a,a,i4,a,3es14.6,a,a,a,a,a)' )&
     230            0 : &   'The computation of excited states using TDDFT is only allowed',ch10,&
     231            0 : &   'with nkpt=1, kpt=(0 0 0), but the following values are input:',ch10,&
     232            0 : &   'nkpt=',nkpt,', kpt=',dtset%kptns(1:3,1),'.',ch10,&
     233            0 : &   'Action: in the input file, set nkpt to 1 and kpt to 0 0 0 ,',ch10,&
     234            0 : &   'or change iscf.'
     235            0 :    ABI_ERROR(message)
     236              :  end if
     237              : 
     238           22 :  if(nspinor/=1)then
     239              :    write(message, '(a,a,a,a,a,a,a)' )&
     240            0 : &   'The computation of excited states using TDDFT is restricted',ch10,&
     241            0 : &   'for the time being to nspinor=1, while input nspinor=2.',ch10,&
     242            0 : &   'Action: if you want to compute excited states within TDDFT,',ch10,&
     243            0 : &   'set nsppol to 1 in the input file. Otherwise, do not use iscf=-1.'
     244            0 :    ABI_ERROR(message)
     245              :  end if
     246              : 
     247              : 
     248           22 :  if(nsppol==2 .and. (dtset%ixc==22 .or. dtset%ixc==20))then
     249              :    write(message, '(a,a,a,a,a,a,a,a,a,a,a)' )&
     250            0 : &   'The computation of excited states using TDDFT in the spin',ch10,&
     251            0 : &   'polarized case for the time being cannot be used with ixc=20',ch10,&
     252            0 : &   'or ixc=22',ch10,&
     253            0 : &   'Action: if you want to compute excited states within TDDFT,',ch10,&
     254            0 : &   'set ixc different from 20 or 22. Otherwise, do not use iscf=-1',ch10,&
     255            0 : &   'with nsppol=2.'
     256            0 :    ABI_ERROR(message)
     257              :  end if
     258              : 
     259              : 
     260           22 :  if(dtset%occopt>2)then
     261              :    write(message, '(a,a,a,i2,a,a,a,a,a)' )&
     262            0 : &   'The computation of excited states using TDDFT is only allowed',ch10,&
     263            0 : &   'with occopt=0, 1, or 2, while input occopt=',dtset%occopt,'.',ch10,&
     264            0 : &   'Action: if you want to compute excited states within TDDFT,',ch10,&
     265            0 : &   'set occopt=0, 1, or 2 in the input file. Otherwise, do not use iscf=-1.'
     266            0 :    ABI_ERROR(message)
     267              :  end if
     268              : 
     269              : !Examine the occupation numbers, and determine the number of
     270              : !occupied and unoccupied states and band.
     271              : !States are numerated as usual in Abinit, before all spin up band
     272              : !and after all spin down bands.
     273              : !Note that if nsppol==1 nstate=nband_k
     274           54 :  do isppol=1,nsppol
     275           32 :    nband_k(isppol)=dtset%nband(isppol)
     276           32 :    nband_occ(isppol)=0
     277          470 :    do iband=1,nband_k(isppol)
     278          438 :      if(abs(occ(iband+(isppol-1)*nband_k(1))-two/nsppol)<tol6)  &
     279          142 : &     nband_occ(isppol)=nband_occ(isppol)+1
     280              :    end do
     281           32 :    nband_unocc(isppol)=nband_k(isppol)-nband_occ(isppol)
     282              : !  next line make no sense if spin flip is taken into account
     283           54 :    nexcit_pol(isppol)=nband_occ(isppol)*nband_unocc(isppol)
     284              :  end do
     285           22 :  nstate_k=nband_k(1)+(nsppol-1)*nband_k(nsppol)
     286           22 :  nstate_occ=nband_occ(1)+(nsppol-1)*nband_occ(nsppol)
     287           22 :  nstate_unocc=nstate_k-nstate_occ
     288              : !next line to be changed if spin fli is taken into account
     289           22 :  nexcit=nexcit_pol(1)+(nsppol-1)*nexcit_pol(nsppol)
     290              : 
     291              : !number of plane wave (does it work even for nsppol=2 ??)
     292           22 :  npw_k=npwarr(1)
     293              : 
     294              : !mux number of excitations that is taken into account
     295           22 :  if(dtset%td_mexcit==0)then
     296              :    nexcit_max=nexcit
     297              :  else
     298            1 :    nexcit_max =dtset%td_mexcit
     299              :  end if
     300              : 
     301              : !DEBUG
     302              : !write(std_out,*) nband_occ(1),nband_unocc(1)
     303              : !write(std_out,*) nband_occ(nsppol),nband_unocc(nsppol)
     304              : !END DEBUG
     305              : 
     306              : 
     307           22 :  if(nsppol==1)then
     308           12 :    write(message, '(a,a,a,a,i4,a,i4,a,a,i4,a,a,a,i6,a)' )ch10,&
     309           12 : &   ' *** TDDFT : computation of excited states *** ',ch10,&
     310           12 : &   ' Splitting of',dtset%nband(1),' states in',nband_occ(1),' occupied states,',&
     311           12 : &   ' and',nband_unocc(1),' unoccupied states,',ch10,&
     312           24 : &   ' giving',nexcit,' excitations.'
     313           12 :    call wrtout(std_out,message,'COLL')
     314           12 :    call wrtout(ab_out,message,'COLL')
     315              :  else
     316           10 :    write(message, '(a,a,a,a,i4,a,i4,a,a,i4,a,a,a,i6,a,a,a)' )ch10,&
     317           10 : &   ' *** TDDFT : computation of excited states *** ',ch10,&
     318           10 : &   ' Splitting of',nstate_k,' states in',nstate_occ,' occupied states,',&
     319           10 : &   ' and',nstate_unocc,' unoccupied states,',ch10,&
     320           10 : &   ' giving',nexcit,' excitations. Note that spin flip is not possible actually.',ch10,&
     321           20 : &   ' So the number of excitation is the half of the product of the number of state'
     322           10 :    call wrtout(std_out,message,'COLL')
     323           10 :    call wrtout(ab_out,message,'COLL')
     324              :  end if
     325              : 
     326              : !Allocate the matrices to be diagonalized.
     327              : !Use a simple storage mode, to be improved in the future.
     328           22 :  ii=max(nband_occ(1),nband_occ(nsppol))
     329           22 :  jj=max(nband_unocc(1),nband_unocc(nsppol))
     330          198 :  ABI_MALLOC(omega_tddft_casida,(ii,jj,nsppol,ii,jj,nsppol,2/nsppol))
     331           66 :  ABI_MALLOC(eexcit,(nexcit))
     332           44 :  ABI_MALLOC(sqrtks,(nexcit))
     333           66 :  ABI_MALLOC(flag_state_win,(nstate_k))
     334        84196 :  omega_tddft_casida(:,:,:,:,:,:,:)=zero
     335              : 
     336              : 
     337              : !Fill the diagonal elements with square of differences of KS eigenvalues
     338              : !(also not very efficient, but OK for the present first coding)
     339              : !Also compute the square root of Kohn-Sham eigenvalue differences
     340           54 :  do isppol=1,nsppol
     341          382 :    do iunocc=1,nband_unocc(isppol)
     342          328 :      eigunocc=eigen(iunocc+nband_occ(isppol)+(isppol-1)*nband_k(1))
     343         1256 :      do iocc=1,nband_occ(isppol)
     344          896 :        iexcit=iocc+(isppol-1)*nexcit_pol(1)+nband_occ(isppol)*(iunocc-1)
     345          896 :        diffeig=eigunocc-eigen(iocc+(isppol-1)*nband_k(1))
     346         2018 :        do sing_trip=1,2/nsppol
     347         2018 :          omega_tddft_casida(iocc,iunocc,isppol,iocc,iunocc,isppol,sing_trip)=diffeig**2
     348              :        end do
     349          896 :        eexcit(iexcit)=diffeig
     350         1224 :        sqrtks(iexcit)=sqrt(diffeig)
     351              :      end do
     352              :    end do
     353              :  end do
     354              : 
     355              : 
     356              : 
     357              : !Sort the excitation energies : note that the array eexcit is reordered
     358           66 :  ABI_MALLOC(indarr,(nexcit))
     359         1814 :  indarr(:)=(/ (ii,ii=1,nexcit) /)
     360           22 :  call sort_dp(nexcit,eexcit,indarr,tol14)
     361              : 
     362              : !Determine an energy window for the excitations
     363              : !to take into account. This is necessary for large systems
     364              : 
     365           22 :  nexcit_win = 0
     366          918 :  do iexcit = 1, nexcit
     367          918 :    if ((eexcit(iexcit) < emax_win ).and.(nexcit_win < nexcit_max)) then
     368          890 :      nexcit_win = nexcit_win + 1
     369              : 
     370              : !    DEBUG
     371              : !    write(message,'(a,F12.5,a,a,i2,a,a,i2)') 'excitation energy:', eexcit(indarr(iexcit)),ch10, &
     372              : !    &                                        'excitation number:', indarr(iexcit),ch10,         &
     373              : !    &                                        'nexcit_win:       ', nexcit_win
     374              : !    call wrtout(std_out,message,'COLL')
     375              : !    ENDDEBUG
     376              : 
     377              :    end if
     378              :  end do
     379              : 
     380              : !identification of the bands contributing to the
     381              : !nexcit_win  excitations within the window
     382              : 
     383              : 
     384           22 :  nstate_win = 0
     385          460 :  flag_state_win(:) = 0
     386          912 :  do iexcit = 1, nexcit_win
     387          890 :    iexcit1 = indarr(iexcit)
     388          890 :    isppol1 = min((iexcit1-1)/nexcit_pol(1) +1,2)
     389          890 :    iunocc1 = (iexcit1-(isppol1-1)*nexcit_pol(1)-1)/nband_occ(isppol1)+1
     390          890 :    iocc1   = iexcit1-(isppol1-1)*nexcit_pol(1)-(iunocc1-1)*nband_occ(isppol1)
     391          890 :    if (flag_state_win(nband_occ(isppol1)+(isppol1-1)*nband_k(1)+iunocc1)==0) &
     392          322 : &   flag_state_win(nband_occ(isppol1)+(isppol1-1)*nband_k(1)+iunocc1) =1
     393          890 :    if (flag_state_win(iocc1+(isppol1-1)*nband_k(1))==0) &
     394          132 : &   flag_state_win(iocc1+(isppol1-1)*nband_k(1)) =1
     395              : !  DEBUG
     396              : !  write(message,'(a,i2,a,a,i2,i2,a,a,i2,a,a,i2)') 'isppol:', isppol1,ch10, &
     397              : !  &                                       'iocc,iunocc:', iocc1,iunocc1,ch10,         &
     398              : !  &                                       'flag_state_win:', flag_state_win(iocc1+(isppol1-1)*nband_k(1)),  &
     399              : !  &                               ch10,   'flag_state_win:', flag_state_win(nband_occ(isppol1)+(isppol1-1)*nband_k(1)+iunocc1)
     400              : !  call wrtout(std_out,message,'COLL')
     401              : !  END DEBUG
     402              : 
     403              :  end do
     404              : 
     405           54 :  do isppol=1,nsppol
     406          492 :    do iband=1,nband_k(isppol)
     407          470 :      nstate_win=nstate_win+flag_state_win(iband+(isppol-1)*nband_k(1))
     408              :    end do
     409              :  end do
     410              : 
     411              : 
     412           22 :  write(message,'(a,a,i5)') ch10,'Nr of states to Fourier transform : ',nstate_win
     413           22 :  call wrtout(std_out,message,'COLL')
     414              : 
     415           22 :  ndiel1=ngfftdiel(1) ; ndiel2=ngfftdiel(2) ; ndiel3=ngfftdiel(3)
     416              : !ndiel4,ndiel5,ndiel6 are FFT dimensions, modified to avoid cache trashing
     417           22 :  ndiel4=ngfftdiel(4) ; ndiel5=ngfftdiel(5) ; ndiel6=ngfftdiel(6)
     418              : 
     419              : !The evaluation of integrals, later, needs the following factor
     420           22 :  normint=one/(ucvol*dble(ndiel1*ndiel2*ndiel3))
     421              : 
     422              : !Setup the positions in real space for later integration
     423           22 :  call matr3inv(gprimd,rprimd)
     424              : 
     425           66 :  ABI_MALLOC(pos,(max(ndiel1,ndiel2,ndiel3),3))
     426              : 
     427              : !Select the reduced position of the point with respect to the box center,
     428              : !in the interval ]-0.5,0.5].
     429              :  buffer=0.05_dp ; buffer_inv=one/buffer
     430           88 :  do idir=1,3
     431           66 :    if(idir==1)ndiel=ndiel1
     432           44 :    if(idir==2)ndiel=ndiel2
     433           44 :    if(idir==3)ndiel=ndiel3
     434         2734 :    do ii=1,ndiel
     435              : !    dtset%boxcenter(3)=reduced coordinates of the center of the box,
     436              : !    in view of the computation of the oscillator strength
     437         2646 :      pos(ii,idir)=(ii-1)/(one*ndiel)-dtset%boxcenter(idir)
     438         2646 :      pos(ii,idir)=pos(ii,idir)-nint(pos(ii,idir)-tol12)
     439              : !    The linear behaviour is cut-off when one becomes
     440              : !    close to the boundaries : the buffer allows to match smoothly
     441              : !    one side of the cell to the other. This is important
     442              : !    to get rid of small breakings of symmetry, that are
     443              : !    confusing in accurate tests
     444         2712 :      if(abs(pos(ii,idir))>half-buffer)then
     445              : !      xx is always positive, and goes linearly from 1 to 0
     446              : !      in the buffer region
     447          242 :        xx=(half-abs(pos(ii,idir)))*buffer_inv
     448              : !      The cut-off is applied to pos(:,:)
     449          242 :        pos(ii,idir)=pos(ii,idir)*xx*(two-xx)
     450              : !      DEBUG
     451              : !      if (idir==1)then
     452              : !      write(std_out,'(i2)') ndiel
     453              : !      write(std_out,'(a,i2,a,F12.5,F12.5)')'idiel : ',ii,'   x : ',pos(ii,idir),&
     454              : !      &    dtset%boxcenter(idir)
     455              : !      endif
     456              : !      ENDDEBUG
     457              :      end if
     458              :    end do ! ii
     459              :  end do ! idir
     460              : 
     461              : !need to run in MPI I/O case
     462           22 :  if (wffnew%iomode == IO_MODE_MPI ) then
     463            0 :    save_iomode=wffnew%iomode
     464            0 :    wffnew%iomode = IO_MODE_FORTRAN
     465              :  else
     466              : !  Do not store value but set to have save_iomode /= 1
     467              :    save_iomode = IO_MODE_FORTRAN
     468              :  end if
     469              : 
     470              : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     471              : !2009 Chunping Hu
     472              : !need to collect wavefunctions from processors to master
     473           22 :  me=me_loc
     474              : 
     475           22 :  tim_rwwf =0
     476           22 :  source = master
     477           22 :  sread = master
     478           22 :  tmaster=(master==me)
     479           22 :  swrite=tmaster
     480           22 :  sender=-1
     481              : 
     482           22 :  iomode=wffnew%iomode
     483              : 
     484           22 :  if(am_master)then
     485              : #if defined HAVE_MPI
     486           54 :    ABI_MALLOC(cg_tmp,(2,mpw*nspinor*mband*nsppol))
     487              : #endif
     488              :  end if
     489              : 
     490           66 :  ABI_MALLOC(kg_disk,(3,mpw))
     491           22 :  mcg_disk=mpw*nspinor*mband
     492           22 :  formeig=0
     493              : 
     494              : #if defined HAVE_MPI
     495           22 :  call xmpi_barrier(spaceComm)
     496           66 :  ABI_MALLOC(cg_disk,(2,mcg_disk))
     497              : #endif
     498              : 
     499           22 :  icg=0
     500              :  if(mpi_enreg%paralbd==0) tim_rwwf=6
     501           22 :  if(mpi_enreg%paralbd==1)tim_rwwf=12
     502              : 
     503           54 :  do isppol=1,nsppol
     504           32 :    ikg=0
     505           86 :    do ikpt=1,nkpt
     506           32 :      nband_k_=dtset%nband(ikpt+(isppol-1)*nkpt)
     507           32 :      npw_k=npwarr(ikpt)
     508              : #if defined HAVE_MPI
     509           32 :      if (dtset%usewvl == 0) then
     510           32 :        mtag=ikpt+(isppol-1)*nkpt
     511           32 :        call xmpi_barrier(spaceComm)
     512              : !      Must transfer the wavefunctions to the master processor
     513              : !      Separate sections for paralbd=1 or other values ; might be merged
     514           32 :        if(mpi_enreg%paralbd==0) then
     515           32 :          nmaster=0
     516          470 :          source=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k_,isppol))
     517           32 :          mydata=.false.
     518           32 :          if(source==me)mydata=.true.
     519           24 :          action=0
     520              : !        I am the master node, and I have the data in cg or cg_disk
     521           24 :          if((tmaster).and.(mydata))action=1
     522              : !        I am not the master, and I have the data => send to master
     523           32 :          if((.not.tmaster).and.(mydata))action=2
     524              : !        I am the master, and I receive the data
     525           32 :          if((tmaster).and.(.not.mydata))action=3
     526              : !        I have the data in cg or cg_disk ( MPI_IO case)
     527           32 :          if (iomode==IO_MODE_MPI) then
     528            0 :            action = 0
     529            0 :            sender=-1
     530            0 :            swrite=.false.
     531            0 :            if (mydata)then
     532              :              action=1
     533           22 :              swrite=.true.
     534           22 :              sender=me
     535              :            end if
     536              :          end if
     537              : !        I am the master node, and I have the data in cg or cg_disk
     538              : !        I have the data in cg or cg_disk ( MPI_IO case)
     539           32 :          if(action==1)then
     540              : !          Copy from kg to kg_disk
     541       162074 :            kg_disk(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     542              : !          Copy from cg to cg_disk
     543       546050 :            do ipwnbd=1,nband_k_*npw_k*nspinor
     544       546028 :              cg_disk(1,ipwnbd)=cg(1,ipwnbd+icg)
     545       546050 :              cg_disk(2,ipwnbd)=cg(2,ipwnbd+icg)
     546              :            end do
     547              :          end if
     548              : !        I am not the master, and I have the data => send to master
     549              : !        I am the master, and I receive the data
     550           32 :          if ( action==2.or.action==3) then
     551            4 :            call timab(48,1,tsec)
     552            4 :            if(action==2)then
     553            2 :              call xmpi_exch(kg(:,1+ikg:npw_k+ikg),3*npw_k,source,kg_disk,nmaster,spaceComm,2*(mtag-1)+1,ierr)
     554              :              call xmpi_exch(cg(:,icg+1:icg+nband_k_*npw_k*nspinor),2*nband_k_*npw_k*nspinor &
     555            2 : &             ,source,cg_disk,nmaster,spaceComm,2*(mtag-1)+2,ierr)
     556              :            else
     557            2 :              call xmpi_exch(kg_disk,3*npw_k,source,kg_disk,nmaster,spaceComm,2*(mtag-1)+1,ierr)
     558            2 :              call xmpi_exch(cg_disk,2*nband_k_*npw_k*nspinor,source,cg_disk,nmaster,spaceComm,2*(mtag-1)+2,ierr)
     559              :            end if
     560            4 :            call timab(48,2,tsec)
     561              :          end if
     562            0 :        else if(mpi_enreg%paralbd==1)then
     563            0 :          nmaster=0
     564              : #if defined HAVE_MPI_IO
     565            0 :          sender=-1
     566            0 :          if( iomode ==IO_MODE_MPI ) then
     567            0 :            nmaster=mpi_enreg%proc_distrb(ikpt,1,isppol)
     568            0 :            sender=nmaster
     569              :          end if
     570              : #endif
     571              : !        Note the loop over bands
     572            0 :          do iband=1,nband_k_
     573              : !          The message passing related to kg is counted as one band
     574            0 :            action=0
     575              : !          I am the master node, and I have the data in cg or cg_disk
     576            0 :            if( mpi_enreg%proc_distrb(ikpt,iband,isppol)==nmaster .and. me==nmaster) then
     577              :              action=1
     578              : !            I am not the master, and I have the data => send to master
     579            0 :            elseif( mpi_enreg%proc_distrb(ikpt,iband,isppol)==me .and. me/=nmaster ) then
     580              :              action = 2
     581              : !            I am the master, and I receive the data
     582            0 :            elseif( mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me .and. me==nmaster ) then
     583              :              action=3
     584              :            end if
     585              :            if(action==1) then
     586              : !            I am the master node, and I have the data in cg or cg_disk
     587              : !            Copy from kg to kg_disk
     588            0 :              if(iband==1)kg_disk(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     589              : !            Copy from cg to cg_disk
     590            0 :              do ipwnbd=1,npw_k*nspinor
     591            0 :                cg_disk(1,(iband-1)*npw_k*nspinor+ipwnbd)= cg(1,(iband-1)*npw_k*nspinor+ipwnbd+icg)
     592            0 :                cg_disk(2,(iband-1)*npw_k*nspinor+ipwnbd)= cg(2,(iband-1)*npw_k*nspinor+ipwnbd+icg)
     593              :              end do
     594              :            end if  ! action=1
     595            0 :            if ( action==2.or.action==3) then
     596              : !            action=2 :  I am not the master, and I have the data => send to master
     597              : !            action=3 :  I am the master, and I receive the data
     598            0 :              call timab(48,1,tsec)
     599            0 :              if ( iband == 1 ) then
     600            0 :                if (action==2) then
     601              :                  call xmpi_exch(kg(:,1+ikg:npw_k+ikg),3*npw_k,mpi_enreg%proc_distrb(ikpt,iband,isppol) &
     602            0 : &                 ,kg_disk,nmaster,spaceComm,iband*(mtag-1)+1,ierr)
     603              :                else
     604              :                  call xmpi_exch(kg_disk,3*npw_k,mpi_enreg%proc_distrb(ikpt,iband,isppol)  &
     605            0 : &                 ,kg_disk,nmaster,spaceComm,iband*(mtag-1)+1,ierr)
     606              :                end if
     607              :              end if       ! iband =1
     608            0 :              ipwnbd=(iband-1)*npw_k*nspinor
     609            0 :              if (action==2)then
     610              :                call xmpi_exch( cg(:,ipwnbd+icg+1:ipwnbd+icg+npw_k*nspinor),2*npw_k*nspinor &
     611              : &               ,mpi_enreg%proc_distrb(ikpt,iband,isppol)                    &
     612            0 : &               ,cg_disk(:,ipwnbd+1:ipwnbd+npw_k*nspinor),nmaster,spaceComm,iband*(mtag-1)+2,ierr)
     613              :              else
     614              :                call xmpi_exch( cg_disk(:,ipwnbd+1:ipwnbd+npw_k*nspinor),2*npw_k*nspinor    &
     615              : &               ,mpi_enreg%proc_distrb(ikpt,iband,isppol)                    &
     616            0 : &               ,cg_disk(:,ipwnbd+1:ipwnbd+npw_k*nspinor),nmaster,spaceComm,iband*(mtag-1)+2,ierr)
     617              :              end if
     618            0 :              call timab(48,2,tsec)
     619              :            end if        ! action=2 or action=3
     620            0 :            if(iomode ==IO_MODE_MPI) then
     621              : !            I have the data in cg or cg_disk
     622              :              swrite=.false.
     623              :              if (nmaster == me) then
     624            0 :                swrite=.true.
     625              :              end if
     626              :            end if
     627              : !          End of loop over bands
     628              :          end do
     629              : !        End of paralbd=1
     630              :        end if
     631              :      end if
     632              : #endif
     633              : 
     634              : !    The wavefunctions for the present k point and spin are stored into cg_tmp
     635           32 :      if(am_master)then
     636              : #if defined HAVE_MPI
     637      1856340 :        cg_tmp(:,icg+1:icg+nband_k_*npw_k*nspinor)=cg_disk(:,:)
     638              : #endif
     639              :      end if
     640              : 
     641           32 :      sskip=1
     642              : #if defined HAVE_MPI
     643           32 :      if (dtset%usewvl == 0) then
     644           32 :        sskip=0
     645           32 :        if(.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k_,isppol,me)))sskip=1
     646              :      end if
     647              : #endif
     648           32 :      if(sskip==1)then
     649           24 :        icg=icg+npw_k*nspinor*nband_k_
     650           24 :        ikg=ikg+npw_k
     651              :      end if
     652              : 
     653              :    end do ! ikpt
     654              :  end do ! isppol
     655           22 :  ABI_FREE(kg_disk)
     656              : #if defined HAVE_MPI
     657           22 :  ABI_FREE(cg_disk)
     658              : #endif
     659              : !!!!!!!end of collecting wavefunction to master!!!!!!
     660              : 
     661              : 
     662           22 :  if(am_master)then
     663              : !  -----------------------------------------------------------
     664              : !  The disk access is only done by master...
     665              : 
     666           72 :    ABI_MALLOC(gbound,(2*mgfftdiel+8,2))
     667           54 :    ABI_MALLOC(kg_k,(3,npw_k))
     668              : 
     669           18 :    ikpt=1
     670              : !  Only one k point
     671              : !  do isppol=1,nsppol
     672       126038 :    kg_k(:,1:npw_k)=kg(:,1:npw_k)
     673           18 :    call sphereboundary(gbound,istwf_k,kg_k,mgfftdiel,npw_k)
     674              : !  enddo
     675              : 
     676              :  end if ! am_master
     677              : 
     678              : !need to run in MPI I/O case
     679           22 :  if ( save_iomode == 1 )  wffnew%iomode = IO_MODE_MPI
     680              : !call wrtout(std_out,'After reading the wavefunction','COLL')
     681              : 
     682              : !Use a simple implementation for the computation of the kernel elements
     683           22 :  if (am_master) then
     684           54 :    ABI_MALLOC(cwavef,(2,mpw))
     685           90 :    ABI_MALLOC(rhoaug,(ndiel4,ndiel5,ndiel6))
     686           90 :    ABI_MALLOC(wfraug,(2,ndiel4,ndiel5,ndiel6))
     687              :  end if
     688           44 :  ABI_MALLOC(index_state,(nstate_k))
     689              : 
     690              : ! all real-space states are kept in memory
     691          132 :  ABI_MALLOC(wfrspa,(ndiel4,ndiel5,ndiel6,nstate_win))
     692              : 
     693              : !DEBUG
     694              : !write(message,'(a)') 'After allocating wfrspa'
     695              : !call wrtout(std_out,message,'COLL')
     696              : !ENDDEBUG
     697              : 
     698           22 :  weight=zero
     699              : 
     700              : !Generate states in real space, only for states contributing to excitations in window
     701           22 :  istate=0
     702              : 
     703           54 :  do isppol=1,nsppol
     704          492 :    do iband=1,nband_k(isppol)
     705              : 
     706          470 :      if(flag_state_win(iband+(isppol-1)*nband_k(1)) == 1) then
     707          432 :        istate=istate+1
     708          432 :        index_state(iband+(isppol-1)*nband_k(1))=istate
     709              : 
     710          432 :        if (am_master) then
     711              : #if defined HAVE_MPI
     712              : !        Obtain Fourier transform in fft box
     713              :          cwavef(:,1:npw_k)=cg_tmp(:,1+(iband-1)*npw_k+(isppol-1)* &
     714      1840092 : &         (npw_k*nband_k(1)) : iband*npw_k+(isppol-1)*(npw_k*nband_k(1)))
     715              : #else
     716              :          cwavef(:,1:npw_k)=cg(:,1+(iband-1)*npw_k+(isppol-1)* (npw_k*nband_k(1)) : iband*npw_k+(isppol-1)*(npw_k*nband_k(1)))
     717              : #endif
     718              : 
     719              : !        write(std_out,*)' iband : ',iband, ' isppol', isppol, '  -> index ', &
     720              : !        &            istate,index_state(iband+(isppol-1)*nband_k(1))
     721              : 
     722          336 :          tim_fourwf=14
     723              : !        This call should be made by master, and then the results be sent to the other procs
     724              : 
     725              :          call fourwf(1,rhoaug,cwavef,dummy,wfraug,gbound,gbound,&
     726              : &         istwf_k,kg_k,kg_k,mgfftdiel,mpi_enreg,1,ngfftdiel,npw_k,1,ndiel4,ndiel5,ndiel6,&
     727          336 : &         0,tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
     728              : 
     729              : !        write(std_out,'(a,i5)')' After Fourier proc ',me_loc
     730              : 
     731              : !        Fix the phase, and checks that the wavefunction is real
     732              : !        (should be merged with routine fxphas)
     733          336 :          saa=zero ; sab=zero ; sbb=zero
     734        12964 :          do i3=1,ndiel3
     735       501000 :            do i2=1,ndiel2
     736     22377136 :              do i1=1,ndiel1
     737     21876472 :                saa=saa+wfraug(1,i1,i2,i3)**2
     738     21876472 :                sbb=sbb+wfraug(2,i1,i2,i3)**2
     739     22364508 :                sab=sab+wfraug(1,i1,i2,i3)*wfraug(2,i1,i2,i3)
     740              :              end do
     741              :            end do
     742              :          end do
     743              : 
     744          336 :          if(sbb>5.0d-9)then
     745              : 
     746              :            write(message, '(a,a,a,es20.10,a,i4,a,i2,a)' )&
     747            0 : &           'The imaginary part of wavefunctions should be practically zero.',ch10,&
     748            0 : &           'This is not the case, since sbb=',sbb,' for iband=',iband,'with sppol=',1,'.'
     749            0 :            ABI_WARNING(message)
     750            0 :            if(sbb>1.0d-7)then
     751            0 :              ABI_ERROR("sbb>1.0d-7")
     752              :            end if
     753              :          end if
     754              : 
     755              : !        Possibility of writing to disk
     756              : 
     757     23103220 :          wfrspa(:,:,:,istate)=wfraug(1,:,:,:)
     758              :        end if !am_master
     759              : 
     760              :      end if
     761              : 
     762              : !    End loop on iband
     763              :    end do
     764              : !  End loop on nsppol
     765              :  end do
     766              : 
     767           22 :  if (am_master) then
     768           18 :    ABI_FREE(gbound)
     769           18 :    ABI_FREE(kg_k)
     770           18 :    ABI_FREE(cwavef)
     771           18 :    ABI_FREE(rhoaug)
     772           18 :    ABI_FREE(wfraug)
     773              : #if defined HAVE_MPI
     774           18 :    ABI_FREE(cg_tmp)
     775              : #else
     776              : #endif
     777              :  end if
     778           22 :  ABI_FREE(flag_state_win)
     779              : 
     780              : ! send wfrspa from master to world
     781           22 :  call xmpi_bcast(wfrspa,master,spaceComm,ierr)
     782              :  !call MPI_BCAST(wfrspa,nbuf,MPI_DOUBLE_PRECISION,master,spaceComm,ierr)
     783              : 
     784              : 
     785              : !DEBUG
     786              : !#if defined HAVE_MPI
     787              : !call xmpi_barrier(spaceComm)
     788              : !write(message,'(a)')' after iband loop synchronization done...'
     789              : !call  wrtout(std_out,message,'COLL')
     790              : !#endif
     791              : !ENDDEBUG
     792              : 
     793              : !Compute the xc kernel, in the form needed for the singlet or triplet
     794              : !excitation energy.
     795              : !In the case ixc=20, kxc vanishes, but no change is made here, for simplicity.
     796              : !(ixc=20 implemented only in the not spin polarized case)
     797              : 
     798              : !DEBUG
     799              : !write(std_out,*)' tddft : xc kernel '
     800              : !do ifft=1,nkxc,41
     801              : !write(std_out,*)ifft,kxc(ifft,1),kxc(ifft,2),kxc(ifft,3)
     802              : !enddo
     803              : !stop
     804              : !ENDDEBUG
     805              : 
     806          176 :  ABI_MALLOC(kxc_for_tddft,(ndiel1,ndiel2,ndiel3,nsppol,nsppol,2/nsppol))
     807           22 :  if(dtset%ixc/=22)then
     808           52 :    do isppol=1,nsppol
     809          103 :      do jsppol=1,nsppol
     810              :        index=1
     811         2195 :        do i3=1,ndiel3
     812        91227 :          do i2=1,ndiel2
     813      4541914 :            do i1=1,ndiel1
     814      9479766 :              do sing_trip=1,2/nsppol
     815              :                kxc_for_tddft(i1,i2,i3,isppol,jsppol,sing_trip)=two/nsppol* &
     816      9479766 : &               (kxc(index,isppol+jsppol-1)-(sing_trip-1)*kxc(index,2))
     817              :              end do
     818      4539801 :              index=index+1
     819              :            end do
     820              :          end do
     821              :        end do
     822              :      end do
     823              :    end do
     824              :  else
     825              : !  This is for the Burke-Petersilka-Gross hybrid, with ixc=22
     826              : !  However, the implementation in case of spin-polarized system should not be expected to be the correct one !
     827            2 :    do isppol=1,nsppol
     828            3 :      do jsppol=1,nsppol
     829              :        index=1
     830           32 :        do i3=1,ndiel3
     831          931 :          do i2=1,ndiel2
     832        27930 :            do i1=1,ndiel1
     833        81000 :              do sing_trip=1,2/nsppol
     834        81000 :                kxc_for_tddft(i1,i2,i3,isppol,jsppol,sing_trip)=((-1)**(sing_trip+1))*kxc(index,2)
     835              :              end do
     836        27900 :              index=index+1
     837              :            end do
     838              :          end do
     839              :        end do
     840              :      end do
     841              :    end do
     842              :  end if
     843              : 
     844           22 :  pole_approx=0
     845              : 
     846           66 :  ABI_MALLOC(excit_coords,(nexcit_win**2,2))
     847              : 
     848              : if (xmpi_paral==1) then
     849           66 :   ABI_MALLOC(counts,(0:nproc_loc-1))
     850           44 :   ABI_MALLOC(displs,(0:nproc_loc-1))
     851           44 :   ABI_MALLOC(recvcounts,(0:nproc_loc-1))
     852           94 :   ABI_MALLOC(recvbuf,(5-nsppol,nproc_loc-1))
     853              : end if
     854              : 
     855              : !DEBUG
     856              : !write(std_out,*)'before first loop'
     857              : !ENDDEBUG
     858              : 
     859              : !0000000000000000000000000000000000000000000000000000000
     860              : !check if matrix file fname_tdexcit exists on disk
     861              : !if the file is present,calculation is a continuation
     862           22 :  if (am_master) then
     863           18 :    inquire(file=trim(dtfil%fnametmp_tdexcit),exist=file_exist)
     864              : !  for direct access to excitation file
     865           18 :    if(nsppol==1)then
     866           12 :      inquire(iolength=recl) omega_tddft_casida(1,1,1,1,1,1,1),omega_tddft_casida(1,1,1,1,1,1,1), iexcit,jexcit
     867              :    else
     868            6 :      inquire(iolength=recl) omega_tddft_casida(1,1,1,1,1,1,1), iexcit,jexcit
     869              :    end if
     870              : 
     871           18 :    temp_unit2 = get_unit()
     872           18 :    open(temp_unit2, file=trim(dtfil%fnametmp_tdexcit),form='unformatted', recl=recl, access='DIRECT')
     873              : 
     874           72 :    ABI_MALLOC(done_excit,(nexcit_win,nexcit_win))
     875              : 
     876           18 :    if(file_exist)then
     877            0 :      write(std_out,*)'TDDFT continues from a previous run'
     878            0 :      rec=0
     879            0 :      do iexcit=1,nexcit_win
     880            0 :        iexcit2 = indarr(iexcit)
     881            0 :        isppol2 = min((iexcit2-1)/nexcit_pol(1) +1,2)
     882            0 :        iunocc2 = (iexcit2-(isppol2-1)*nexcit_pol(1)-1)/nband_occ(isppol2)+1
     883            0 :        iocc2   = iexcit2-(isppol2-1)*nexcit_pol(1)-(iunocc2-1)*nband_occ(isppol2)
     884            0 :        do jexcit=1,nexcit_win
     885            0 :          iexcit1 = indarr(jexcit)
     886            0 :          isppol1 = min((iexcit1-1)/nexcit_pol(1) +1,2)
     887            0 :          iunocc1 = (iexcit1-(isppol1-1)*nexcit_pol(1)-1)/nband_occ(isppol1)+1
     888            0 :          iocc1   = iexcit1-(isppol1-1)*nexcit_pol(1)-(iunocc1-1)*nband_occ(isppol1)
     889              : 
     890            0 :          rec=rec+1 ! record of the entry in the excitation file
     891            0 :          if(nsppol==1)then
     892            0 :            read(temp_unit2,rec=rec) omega_tddft_casida_dummy(1), omega_tddft_casida_dummy(2), idummy, jdummy
     893              :          else
     894            0 :            read(temp_unit2,rec=rec) omega_tddft_casida_dummy(1), idummy, jdummy
     895              :          end if
     896            0 :          done_excit(jexcit,iexcit)= ( idummy /= -1 .and. jdummy /= -1 ) ! if true, eigsqr_singlet and eigsqr_triplet are ok
     897              : !        and a true is marked in the logical array done_excit
     898            0 :          if (done_excit(jexcit,iexcit)) then
     899            0 :            do sing_trip=1,2/nsppol
     900              :              omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,sing_trip)= &
     901            0 : &             omega_tddft_casida_dummy(sing_trip)
     902              :            end do
     903              :          end if
     904              :        end do
     905              :      end do
     906              : 
     907              :    else
     908           18 :      write(std_out,*)'no excitation matrix on disk'
     909           18 :      write(std_out,*)'TDDFT starts from scratch'
     910        31712 :      done_excit = .false. ! initialize the logical array to false
     911           18 :      rec=0
     912          628 :      do iexcit=1,nexcit_win
     913        31712 :        do jexcit=1,nexcit_win
     914        31084 :          rec=rec+1
     915        31694 :          if(nsppol==1)then
     916         5434 :            write(temp_unit2,rec=rec) zero,zero,-1,-1
     917              :          else
     918        25650 :            write(temp_unit2,rec=rec) zero,-1,-1
     919              :          end if
     920              :        end do
     921              :      end do
     922              :    end if
     923              : 
     924              : !  Need to list the elements to compute, taking the symmetry into account: valid only for Gamma point but this is already the case
     925           18 :    count_to_do=0
     926          628 :    do iexcit=1,nexcit_win
     927        16475 :      do jexcit=1,iexcit
     928        16457 :        if (.not. done_excit(jexcit,iexcit)) then
     929        15847 :          count_to_do=count_to_do+1
     930        15847 :          excit_coords(count_to_do,1)=iexcit
     931        15847 :          excit_coords(count_to_do,2)=jexcit
     932              :        end if
     933              :      end do
     934              :    end do
     935              : 
     936           18 :    ABI_FREE(done_excit)
     937              : 
     938              : 
     939              : 
     940              : if (xmpi_paral==1) then
     941              : ! Compute limits for load balancing
     942           40 :   do iproc=0,nproc_loc-1
     943           22 :     displs(iproc)=(iproc*count_to_do)/nproc_loc
     944           40 :     counts(iproc)=min(((iproc+1)*count_to_do)/nproc_loc,count_to_do)-displs(iproc)
     945              :   end do
     946              : end if
     947              : 
     948              :  end if ! am_master
     949              : 
     950           22 :  call xmpi_bcast(count_to_do,master,spaceComm,ierr)
     951              : 
     952           22 :  displ=(me_loc*count_to_do)/nproc_loc
     953           22 :  count=min(((me_loc+1)*count_to_do)/nproc_loc,count_to_do)-displ
     954           22 :  displmax=((nproc_loc-1)*count_to_do)/nproc_loc
     955           22 :  countmax=count_to_do-displmax
     956              : 
     957           22 :  write(message,'(A,I6)') 'Maximum number of matrix elements per processor = ',countmax
     958           22 :  call wrtout(std_out,message,'COLL')
     959              : 
     960              : if (xmpi_paral==1) then
     961              : !  Need to dispatch the elements to compute to the different processes
     962           66 :    ABI_MALLOC(tmpbuf,(nexcit_win**2))
     963        50706 :    tmpbuf=0
     964           22 :    call xmpi_scatterv(excit_coords(:,1),counts,displs,tmpbuf,count,0,spaceComm,ierr)
     965        50706 :    excit_coords(:,1)=tmpbuf(:)
     966        50706 :    tmpbuf=0
     967           22 :    call xmpi_scatterv(excit_coords(:,2),counts,displs,tmpbuf,count,0,spaceComm,ierr)
     968        50706 :    excit_coords(:,2)=tmpbuf(:)
     969           22 :    ABI_FREE(tmpbuf)
     970              :  end if
     971              : 
     972           22 :  nfftdiel=ndiel1*ndiel2*ndiel3
     973          110 :  ABI_MALLOC(wfprod,(ndiel1,ndiel2,ndiel3))
     974           66 :  ABI_MALLOC(work,(nfftdiel))
     975           66 :  ABI_MALLOC(sexc,(3,nexcit_win))
     976           66 :  ABI_MALLOC(done_sexc,(nexcit_win))
     977              : !ABI_MALLOC(done_sexc2,(nexcit_win))
     978           66 :  ABI_MALLOC(rhog,(2,nfftdiel))
     979           44 :  ABI_MALLOC(vhartr,(nfftdiel))
     980              : 
     981         3582 :  sexc(:,:)=zero
     982          912 :  done_sexc(:)=.false.
     983              : 
     984              : !----------------------------------------------------------
     985              : !Main double loop
     986              : 
     987              :  old_iexcit=0
     988        15873 :  do ijexcit=1,countmax
     989              : !  we really loop only through count, but we need to go through countmax
     990              : !  to make sure that all processes execute MPI_Gatherv below
     991        15851 :    if (ijexcit <= count) then
     992        15847 :      iexcit=excit_coords(ijexcit,1)
     993        15847 :      jexcit=excit_coords(ijexcit,2)
     994              : 
     995        15847 :      iexcit2 = indarr(iexcit)
     996        15847 :      isppol2 = min((iexcit2-1)/nexcit_pol(1) +1,2)
     997        15847 :      iunocc2 = (iexcit2-(isppol2-1)*nexcit_pol(1)-1)/nband_occ(isppol2)+1
     998        15847 :      iocc2   = iexcit2-(isppol2-1)*nexcit_pol(1)-(iunocc2-1)*nband_occ(isppol2)
     999              : 
    1000        15847 :      iexcit1 = indarr(jexcit)
    1001        15847 :      isppol1 = min((iexcit1-1)/nexcit_pol(1) +1,2)
    1002        15847 :      iunocc1 = (iexcit1-(isppol1-1)*nexcit_pol(1)-1)/nband_occ(isppol1)+1
    1003        15847 :      iocc1   = iexcit1-(isppol1-1)*nexcit_pol(1)-(iunocc1-1)*nband_occ(isppol1)
    1004              : 
    1005        15847 :      if (old_iexcit /= iexcit) then
    1006              : !      We start a new column of the matrix
    1007              : !      DEBUG
    1008              : !      write(message,'(a,i5,a,i3)')'treating  iexcit =  ',iexcit,&
    1009              : !      &'  with proc ',me_loc
    1010              : !      call wrtout(std_out,message,'PERS')
    1011              : !      ENDDEBUG
    1012              : 
    1013              : !      DEBUG
    1014              : !      write(message,'(a,i3)')'Multiplicating phi1 phi2, on proc ',me_loc
    1015              : !      call wrtout(std_out,message,'PERS')
    1016              : !      ENDDEBUG
    1017              : 
    1018              :        ifft=1
    1019        25607 :        do i3=1,ndiel3
    1020      1064228 :          do i2=1,ndiel2
    1021     52165476 :            do i1=1,ndiel1
    1022              :              wfprod(i1,i2,i3)=wfrspa(i1,i2,i3,index_state(iocc2+(isppol2-1)*nband_k(1))) &
    1023     51101862 : &             *wfrspa(i1,i2,i3,index_state(iunocc2+nband_occ(isppol2)+(isppol2-1)*nband_k(1)))
    1024     51101862 :              work(ifft)=wfprod(i1,i2,i3)
    1025     52140483 :              ifft=ifft+1
    1026              :            end do
    1027              :          end do
    1028              :        end do
    1029          614 :        if (jexcit == 1) then
    1030        25423 :          do i3=1,ndiel3
    1031      1055334 :            do i2=1,ndiel2
    1032     51719796 :              do i1=1,ndiel1
    1033    203688369 :                do idir=1,3
    1034              :                  poscart(idir)=rprimd(idir,1)*pos(i1,1)+&
    1035              : &                 rprimd(idir,2)*pos(i2,2)+&
    1036    151993386 : &                 rprimd(idir,3)*pos(i3,3)
    1037    202657848 :                  sexc(idir,iexcit)=sexc(idir,iexcit)+poscart(idir)*wfprod(i1,i2,i3)
    1038              :                end do
    1039              :              end do
    1040              :            end do
    1041        25423 :            done_sexc(iexcit)=.true.
    1042              :          end do
    1043              :        end if
    1044              : 
    1045              : !      For the singlet correction, must compute the hartre potential created
    1046              : !      by the product of wavefunctions
    1047          614 :        cplex=1
    1048              : 
    1049              : !      DEBUG
    1050              : !      write(message,'(a,i3)')'Before Fourdp, on proc ',me_loc
    1051              : !      call wrtout(std_out,message,'PERS')
    1052              : !      ENDDEBUG
    1053              : 
    1054          614 :        call fourdp(cplex,rhog,work,-1,mpi_enreg,nfftdiel,1,ngfftdiel,0)
    1055              : 
    1056              : !      DEBUG
    1057              : !      write(message,'(a,i3)')'Before Hartree, on proc ',me_loc
    1058              : !      call wrtout(std_out,message,'PERS')
    1059              : !      write(std_out,*)'CPU ',me_loc,ch10,&
    1060              : !      &            '   cplex : ',cplex,ch10,&
    1061              : !      &            '   gmet(3,3)  : ',gmet(3,3),ch10,&
    1062              : !      &            '   gsqcut : ',gsqcut,ch10,&
    1063              : !      &            '   rhog(1,1) :,',rhog(1,1),ch10,&
    1064              : !      &            '   vhartr(1) :,',vhartr(1)
    1065              : !      ENDDEBUG
    1066              : 
    1067              :        call hartre(cplex,gsqcut,dtset%icutcoul,0,mpi_enreg,nfftdiel,ngfftdiel,&
    1068          614 :                    &dtset%nkpt,dtset%rcut,rhog,rprimd,dtset%vcutgeo,vhartr)
    1069              : 
    1070              : !      DEBUG
    1071              : !      write(message,'(a,i3)')'After Hartree, on proc ',me_loc
    1072              : !      call wrtout(std_out,message,'PERS')
    1073              : !      ENDDEBUG
    1074              :      end if
    1075        34521 :      old_iexcit=iexcit
    1076              : 
    1077              : !    DEBUG
    1078              : !    write(std_out,*)'  treating  iexcit =  ',jexcit
    1079              : !    write(std_out,*)'   indarr(iexcit) =',iexcit1,iocc1,iunocc1
    1080              : !    write(std_out,*)'   index ',index_state(iocc1+(isppol1-1)*nband_k(1)), &
    1081              : !    &                       index_state(iunocc1+nband_occ(isppol1)+(isppol1-1)*nband_k(1))
    1082              : !    ENDDEBUG
    1083              : 
    1084              :      if(pole_approx==0 .or. (iunocc1==iunocc2 .and. iocc1==iocc2 .and. isppol1==isppol2))then
    1085        34521 :        sum_kernel(:)=zero
    1086        15847 :        f_sing_trip(1)=two/dble(nsppol)
    1087        15847 :        if(nsppol==1) f_sing_trip(2)=zero
    1088              : !      For Fermi-Amaldi kxc, the xc contribution is -1/2 the Hartree contribution
    1089              : !      to the triplet state. The following factors combines both contributions.
    1090        15847 :        if(dtset%ixc==20 .or. dtset%ixc==22)then
    1091          570 :          if(nsppol==1)then
    1092          570 :            f_sing_trip(1)= one
    1093          570 :            f_sing_trip(2)=-one
    1094              :          end if
    1095              :        end if
    1096              :        ifft=1
    1097       687541 :        do i3=1,ndiel3
    1098     29500219 :          do i2=1,ndiel2
    1099   1494141288 :            do i1=1,ndiel1
    1100              :              myproduct=wfrspa(i1,i2,i3,index_state(iocc1+(isppol1-1)*nband_k(1))) &
    1101   1464656916 : &             *wfrspa(i1,i2,i3,index_state(iunocc1+nband_occ(isppol1)+(isppol1-1)*nband_k(1)))
    1102   3163331268 :              do sing_trip=1,2/nsppol
    1103              :                sum_kernel(sing_trip)=sum_kernel(sing_trip)+&
    1104              : &               myproduct*(f_sing_trip(sing_trip)*vhartr(ifft)+kxc_for_tddft(i1,i2,i3,isppol1,isppol2,sing_trip) &
    1105   3163331268 :                *wfprod(i1,i2,i3))
    1106              :              end do
    1107   1493469594 :              ifft=ifft+1
    1108              :            end do ! i1
    1109              :          end do ! i2
    1110              :        end do ! i3
    1111              : 
    1112              : !      The factor two is coherent with the formulas of Vasiliev et al
    1113        15847 :        factor=two*sqrtks(iexcit1)*sqrtks(iexcit2)*normint
    1114        34521 :        do sing_trip=1,2/nsppol
    1115              :          omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,sing_trip)=   &
    1116              : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,sing_trip)+  &
    1117        34521 : &         factor*sum_kernel(sing_trip)
    1118              :        end do
    1119              : 
    1120              : !      End condition of being diagonal element if pole approximation
    1121              :      end if
    1122              : 
    1123              : !    Continue writing excitation matrix
    1124        15847 :      if (am_master) then
    1125              : !      the master writes its results to disk
    1126        12740 :        if(nsppol==1)then
    1127              :          write(temp_unit2, rec=(iexcit-1)*nexcit_win+jexcit ) &
    1128         2827 : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1),&
    1129         2827 : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,2),&
    1130         5654 : &         iexcit, jexcit
    1131              :        else
    1132              :          write(temp_unit2, rec=(iexcit-1)*nexcit_win+jexcit ) &
    1133         9913 : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1134        19826 : &         iexcit, jexcit
    1135              :        end if
    1136              : 
    1137              : !      DEBUG
    1138              : !      if(nsppol==1)then
    1139              : !      write(std_out,*)'singlet: ',omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1),&
    1140              : !      &             'iexcit: ',iexcit,'jexcit :',jexcit
    1141              : !      write(std_out,*)'triplet: ',omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,2),&
    1142              : !      &             'iexcit: ',iexcit,'jexcit :',jexcit
    1143              : !      else
    1144              : !      write(std_out,*)'excitation: ',omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1),&
    1145              : !      &             'iexcit: ',iexcit,'jexcit :',jexcit
    1146              : !      endif
    1147              : !      ENDDEBUG
    1148              : 
    1149        12740 :        sendcount=0
    1150              :      else
    1151         3107 :        sendcount=5-nsppol
    1152              : 
    1153         3107 :        if(nsppol==1)then
    1154              :          sendbuf=(/ omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1155              : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,2), &
    1156            0 : &         real(iexcit,dp), real(jexcit,dp) /)
    1157              :        else
    1158              :          sendbuf=(/ omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1159        12428 : &         real(iexcit,dp), real(jexcit,dp) /)
    1160              :        end if
    1161              :      end if ! am_master
    1162              :    else
    1163              : !    ijexcit > count
    1164              : 
    1165              : !    done with local work, so send message of zero length
    1166            4 :      sendcount=0
    1167              : 
    1168              :    end if ! ijexcit <= count
    1169              : 
    1170           22 : if (xmpi_paral==1) then
    1171        15851 :    if (am_master) then
    1172              : 
    1173              : !    Compute displacements and counts for the gathering of the results
    1174        12742 :      displs(0)=0
    1175        12742 :      recvcounts(0)=0
    1176        15851 :      do iproc=1,nproc_loc-1
    1177         3109 :        recvcounts(iproc)=min(((iproc+1)*count_to_do)/nproc_loc,count_to_do)-(iproc*count_to_do)/nproc_loc
    1178         3109 :        if (recvcounts(iproc) < countmax .and. ijexcit==countmax) then
    1179            2 :          recvcounts(iproc)=0
    1180              :        else
    1181         3107 :          recvcounts(iproc)=5-nsppol
    1182              :        end if
    1183        15851 :        displs(iproc)=displs(iproc-1)+recvcounts(iproc-1)
    1184              :      end do
    1185              :    end if
    1186              : 
    1187        15851 :    if (nproc_loc>1) then
    1188        19896 :      cptr=c_loc(recvbuf) ; call c_f_pointer(cptr,recvbuf_ptr,[size(recvbuf)])
    1189         4974 :      call xmpi_gatherv(sendbuf,sendcount,recvbuf_ptr,recvcounts,displs,0,spaceComm,ierr)
    1190              :    end if
    1191              : 
    1192        15851 :    if (am_master) then
    1193              : 
    1194              : !    Extract eigsqr_singlet, eigsqr_triplet, iexcit, jexcit from receive buffer and
    1195              : !    write to file
    1196        31700 :      do ijexcit2=1,sum(recvcounts)/(5-nsppol)
    1197         3107 :        iexcit=int(recvbuf(4-nsppol,ijexcit2))
    1198         3107 :        jexcit=int(recvbuf(5-nsppol,ijexcit2))
    1199              : 
    1200         3107 :        iexcit2 = indarr(iexcit)
    1201         3107 :        isppol2 = min((iexcit2-1)/nexcit_pol(1) +1,2)
    1202         3107 :        iunocc2 = (iexcit2-(isppol2-1)*nexcit_pol(1)-1)/nband_occ(isppol2)+1
    1203         3107 :        iocc2   = iexcit2-(isppol2-1)*nexcit_pol(1)-(iunocc2-1)*nband_occ(isppol2)
    1204              : 
    1205         3107 :        iexcit1 = indarr(jexcit)
    1206         3107 :        isppol1 = min((iexcit1-1)/nexcit_pol(1) +1,2)
    1207         3107 :        iunocc1 = (iexcit1-(isppol1-1)*nexcit_pol(1)-1)/nband_occ(isppol1)+1
    1208         3107 :        iocc1   = iexcit1-(isppol1-1)*nexcit_pol(1)-(iunocc1-1)*nband_occ(isppol1)
    1209              : 
    1210         6214 :        do sing_trip=1,2/nsppol
    1211              :          omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,sing_trip)= &
    1212         6214 : &         recvbuf(sing_trip,ijexcit2)
    1213              :        end do
    1214              : 
    1215        15849 :        if(nsppol==1)then
    1216              :          write(temp_unit2, rec=(iexcit-1)*nexcit_win+jexcit ) &
    1217            0 : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1218            0 : &         omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,2), &
    1219            0 : &         iexcit, jexcit
    1220              :        else
    1221              :          write(temp_unit2, rec=(iexcit-1)*nexcit_win+jexcit ) &
    1222         3107 :          omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1223         6214 : &         iexcit, jexcit
    1224              :        end if
    1225              : !      DEBUG
    1226              : !      if(nsppol==1)then
    1227              : !      write(std_out,*)'singlet: ',omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1228              : !      &                       'iexcit: ',iexcit,'jexcit :',jexcit
    1229              : !      write(std_out,*)'triplet: ',omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,2),
    1230              : !      &                       'iexcit: ',iexcit,'jexcit :',jexcit
    1231              : !      else
    1232              : !      write(std_out,*)'excitation: ',omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,1), &
    1233              : !      &                        'iexcit: ',iexcit,'jexcit :',jexcit
    1234              : !      endif
    1235              : !      ENDDEBUG
    1236              : 
    1237              :      end do
    1238              : 
    1239              :    end if
    1240              : end if ! MPI parallel
    1241              : 
    1242              : !  End indices loops
    1243              :  end do ! ijexcit
    1244              : 
    1245              : !End of the main double loop
    1246              : !--------------------------------------------------------------------
    1247              : 
    1248              : 
    1249              : if (xmpi_paral==1) then
    1250              : ! sexc needs to be summed here since it used only by master
    1251           22 :   call xmpi_barrier(spaceComm)
    1252              : ! call xmpi_sum_master(sexc,master,spaceComm,ierr) ! Does not work on some machines
    1253           22 :   call xmpi_sum(sexc,spaceComm,ierr)
    1254           22 :   call xmpi_lor(done_sexc,spaceComm)
    1255              :   !done_sexc2=done_sexc
    1256              :   !call MPI_Reduce(done_sexc2,done_sexc,nexcit_win,MPI_LOGICAL,MPI_LOR,master,spaceComm,ierr)
    1257              : end if
    1258              : 
    1259              : 
    1260           22 :  if (am_master) then
    1261              : !  We compute sexc again if it was not done. Will only be executed if
    1262              : !  there was a restart from values read from logical unit temp_unit2.
    1263              : 
    1264          628 :    do iexcit=1,nexcit_win
    1265              : 
    1266              : !    DEBUG
    1267              : !    write(std_out,*)'do on excitation',iexcit
    1268              : !    END DEBUG
    1269              : 
    1270          628 :      if (.not.done_sexc(iexcit)) then
    1271            0 :        iexcit2 = indarr(iexcit)
    1272            0 :        isppol2 = min((iexcit2-1)/nexcit_pol(1) +1,2)
    1273            0 :        iunocc2 = (iexcit1-(isppol2-1)*nexcit_pol(1)-1)/nband_occ(isppol2)+1
    1274            0 :        iocc2   = iexcit2-(isppol2-1)*nexcit_pol(1)-(iunocc2-1)*nband_occ(isppol2)
    1275            0 :        do i3=1,ndiel3
    1276            0 :          do i2=1,ndiel2
    1277            0 :            do i1=1,ndiel1
    1278              :              wfprod(i1,i2,i3)=wfrspa(i1,i2,i3,index_state(iocc2+(isppol2-1)*nband_k(1))) &
    1279            0 : &             *wfrspa(i1,i2,i3,index_state(iunocc2+nband_occ(isppol2)+ (isppol2-1)*nband_k(1)))
    1280            0 :              do idir=1,3
    1281              :                poscart(idir)=rprimd(idir,1)*pos(i1,1)+&
    1282              : &               rprimd(idir,2)*pos(i2,2)+&
    1283            0 : &               rprimd(idir,3)*pos(i3,3)
    1284            0 :                sexc(idir,iexcit)=sexc(idir,iexcit)+poscart(idir)*wfprod(i1,i2,i3)
    1285              :              end do
    1286              :            end do
    1287              :          end do
    1288              :        end do
    1289              :      end if
    1290              :    end do
    1291              :  end if
    1292              : 
    1293           22 :  ABI_FREE(work)
    1294           22 :  ABI_FREE(rhog)
    1295           22 :  ABI_FREE(pos)
    1296           22 :  ABI_FREE(vhartr)
    1297           22 :  ABI_FREE(kxc_for_tddft)
    1298           22 :  ABI_FREE(wfprod)
    1299           22 :  ABI_FREE(index_state)
    1300           22 :  ABI_FREE(excit_coords)
    1301           22 :  ABI_FREE(wfrspa)
    1302              : 
    1303              : !Write the first excitation energies
    1304           22 :  write(message, '(a,a,es18.8,a,a,a,a,a,a,a,a,a)' )ch10,&
    1305           22 : & '  Ground state total energy (Ha) :',etotal,ch10,ch10,&
    1306           22 : & '  Kohn-Sham energy differences,',ch10,&
    1307           22 : & '  corresponding total energies and oscillator strengths (X,Y,Z and average)-',ch10,&
    1308           22 : & '  (oscillator strengths smaller than 1.e-6 are set to zero)',ch10,&
    1309           44 : & '  Transition  (Ha)  and   (eV)   Tot. Ene. (Ha)  Aver     XX       YY       ZZ'
    1310           22 :  call wrtout(ab_out,message,'COLL')
    1311           22 :  call wrtout(std_out,message,'COLL')
    1312              : 
    1313              : if (xmpi_paral==1) then
    1314           22 :  ABI_FREE(counts)
    1315           22 :  ABI_FREE(displs)
    1316           22 :  ABI_FREE(recvbuf)
    1317           22 :  ABI_FREE(recvcounts)
    1318              : end if
    1319              : 
    1320           22 :  if (am_master) then
    1321              : 
    1322           54 :    ABI_MALLOC(osc_str,(7,nexcit))
    1323              : 
    1324          628 :    do iexcit=1,nexcit_win
    1325          610 :      iexcit2 = indarr(iexcit)
    1326          610 :      isppol = min((iexcit2-1)/nexcit_pol(1) +1,2)
    1327          610 :      iunocc = (iexcit2-(isppol-1)*nexcit_pol(1)-1)/nband_occ(isppol)+1
    1328          610 :      iocc   = iexcit2-(isppol-1)*nexcit_pol(1)-(iunocc-1)*nband_occ(isppol)
    1329              : 
    1330          610 :      osc_str(1,iexcit)=zero
    1331         2440 :      do idir=1,3
    1332              : !      One of the factor of two comes from the spin degeneracy,
    1333              : !      the other comes from Eq.(40) of Casida
    1334              :        osc_str(idir+1,iexcit)=&
    1335         1830 : &       (sexc(idir,iexcit)*sqrtks(iexcit2)*normint*ucvol)**2*two*two/nsppol
    1336              :        osc_str(1,iexcit)=osc_str(1,iexcit)&
    1337         2440 : &       +osc_str(idir+1,iexcit)*third
    1338              :      end do
    1339         3050 :      do ii=1,4
    1340         3050 :        if(abs(osc_str(ii,iexcit))<tol6)osc_str(ii,iexcit)=zero
    1341              :      end do
    1342              : !    Changed, the whole spectrum is written
    1343              : !    The array eexcit has been reordered previously, the others also
    1344          610 :      if(nsppol==1)then
    1345              :        write(message, '(i4,a,i3,2es12.5,es13.5,es11.4,3es9.2)' ) &
    1346          220 : &       iocc,'->',iunocc+nband_occ(isppol),            &
    1347          220 : &       eexcit(iexcit), eexcit(iexcit)*Ha_eV,eexcit(iexcit)+etotal, &
    1348              : !      XG 020209 : Jean-Yves, I assume that the printout of sexc is for debugging ?!
    1349              : !      &   osc_str(1:4,iexcit),sexc(1:3,iexcit)
    1350          440 : &       osc_str(1:4,iexcit)
    1351              :      else
    1352              :        write(message, '(i4,a,i3,a,i1,2es12.5,es13.5,es11.4,3es9.2)' ) &
    1353          390 : &       iocc,'->',iunocc+nband_occ(isppol),' s:',isppol,            &
    1354          390 : &       eexcit(iexcit), eexcit(iexcit)*Ha_eV,eexcit(iexcit)+etotal, &
    1355          780 : &       osc_str(1:4,iexcit)
    1356              :      end if
    1357          610 :      call wrtout(ab_out,message,'COLL')
    1358          628 :      call wrtout(std_out,message,'COLL')
    1359              : 
    1360              :    end do
    1361              : 
    1362              : !  Check of the Sum rule for Casida eq.47,
    1363              : !  only exact if complete basis of excitations, as well as local potentials only.
    1364           18 :    sumx=zero
    1365          628 :    do iexcit=1,nexcit_win
    1366          628 :      sumx=sumx+osc_str(1,iexcit)
    1367              :    end do
    1368           18 :    write(message, '(a,es16.6)' )'  Sum of osc. strength : ',sumx
    1369           18 :    call wrtout(ab_out,message,'COLL')
    1370           18 :    call wrtout(std_out,message,'COLL')
    1371              : 
    1372              : !  -Diagonalize the excitation matrices----------------------------
    1373              : 
    1374           54 :    ABI_MALLOC(eexcit2,(nexcit_win))
    1375           72 :    ABI_MALLOC(vec,(2,nexcit_win,nexcit_win))
    1376              : 
    1377           48 :    do sing_trip=1,2/nsppol
    1378              : 
    1379              :      if(pole_approx==0)then
    1380              : 
    1381           90 :        ABI_MALLOC(matr,(nexcit_win*(nexcit_win+1)))
    1382           90 :        ABI_MALLOC(zhpev1,(2,2*nexcit_win-1))
    1383           90 :        ABI_MALLOC(zhpev2,(3*nexcit_win-2))
    1384        37378 :        matr(:)=zero
    1385           30 :        ier=0
    1386              : !      DEBUG
    1387              : !      write(std_out,*)' after allocation matrices     '
    1388              : !      ENDDEBUG
    1389              : 
    1390              : 
    1391              : !      Store the matrix in proper mode before calling zhpev
    1392              : 
    1393           30 :        index=1
    1394          860 :        do iexcit=1,nexcit_win
    1395          830 :          iexcit2 = indarr(iexcit)
    1396          830 :          isppol2 = min((iexcit2-1)/nexcit_pol(1) +1,2)
    1397          830 :          iunocc2 = (iexcit2-(isppol2-1)*nexcit_pol(1)-1)/nband_occ(isppol2)+1
    1398          830 :          iocc2   = iexcit2-(isppol2-1)*nexcit_pol(1)-(iunocc2-1)*nband_occ(isppol2)
    1399        19534 :          do jexcit=1,iexcit
    1400        18674 :            iexcit1 = indarr(jexcit)
    1401        18674 :            isppol1 = min((iexcit1-1)/nexcit_pol(1) +1,2)
    1402        18674 :            iunocc1 = (iexcit1-(isppol1-1)*nexcit_pol(1)-1)/nband_occ(isppol1)+1
    1403        18674 :            iocc1   = iexcit1-(isppol1-1)*nexcit_pol(1)-(iunocc1-1)*nband_occ(isppol1)
    1404              : 
    1405        18674 :            matr(index)=omega_tddft_casida(iocc1,iunocc1,isppol1,iocc2,iunocc2,isppol2,sing_trip)
    1406        18674 :            matr(index+1)=zero
    1407        19504 :            index=index+2
    1408              :          end do
    1409              : 
    1410              :        end do
    1411              : 
    1412              : !      DEBUG
    1413              : !      write(std_out,*)' after filling    matrices     '
    1414              : !      ENDDEBUG
    1415              : 
    1416              :        call ZHPEV ('V','U',nexcit_win,matr,eexcit2,vec,nexcit_win,zhpev1,&
    1417           30 : &       zhpev2,ier)
    1418              : 
    1419           30 :        ABI_FREE(matr)
    1420           30 :        ABI_FREE(zhpev1)
    1421           30 :        ABI_FREE(zhpev2)
    1422              : !      DEBUG
    1423              : !      write(std_out,*)' after deallocating matrices     '
    1424              : !      ENDDEBUG
    1425              : 
    1426              : 
    1427              :      else
    1428              : 
    1429              :        vec(:,:,:)=zero
    1430              :        do isppol=1, nsppol
    1431              :          do iunocc=1,nband_k(isppol)
    1432              :            do iocc=1,nband_k(isppol)
    1433              :              index=iocc+nband_k(isppol)*(iunocc-1)+(isppol-1)*nexcit_pol(1)
    1434              :              eexcit2(index)=omega_tddft_casida(iocc,iunocc,isppol,iocc,iunocc,isppol,sing_trip)
    1435              :              vec(1,index,index)=one
    1436              :            end do
    1437              :          end do
    1438              :        end do
    1439              : 
    1440              :      end if
    1441              : 
    1442              : !    Compute the excitation energies from the square root of eexcit2
    1443              : !    eexcit(:)=sqrt(eexcit2(:)
    1444              : 
    1445           30 :      ABI_FREE(eexcit)
    1446           90 :      ABI_MALLOC(eexcit,(nexcit_win))
    1447              : 
    1448          860 :      eexcit(:)=sqrt(dabs(eexcit2(:))+tol10**2)
    1449              : !    Write the first excitation energies
    1450           30 :      if(sing_trip==1)then
    1451           18 :        if(nsppol==1)then
    1452           12 :          write(message, '(a,a,a,a,a,a)' )ch10,&
    1453           12 : &         '  TDDFT singlet excitation energies (at most 20 of them are printed),',ch10,&
    1454           12 : &         '  and corresponding total energies.                ',ch10,&
    1455           24 : &         '  Excit#   (Ha)    and    (eV)    total energy (Ha)    major contributions '
    1456              :        else
    1457            6 :          write(message, '(a,a,a,a,a,a)' )ch10,&
    1458            6 : &         '  TDDFT   mixed excitation energies (at most 40 of them are printed),',ch10,&
    1459            6 : &         '  and corresponding total energies.                ',ch10,&
    1460           12 : &         '  Excit#   (Ha)    and    (eV)    total energy (Ha)    major contributions '
    1461              :        end if
    1462              :      else
    1463           12 :        write(message, '(a,a,a,a,a,a)' )ch10,&
    1464           12 : &       '  TDDFT triplet excitation energies (at most 20 of them are printed),',ch10,&
    1465           12 : &       '  and corresponding total energies.                ',ch10,&
    1466           24 : &       '  Excit#   (Ha)    and    (eV)    total energy (Ha)    major contributions '
    1467              :      end if
    1468           30 :      call wrtout(ab_out,message,'COLL')
    1469           30 :      call wrtout(std_out,message,'COLL')
    1470           30 :      call wrtout(std_out,' tddft : before iexcit loop',"COLL")
    1471              : 
    1472          500 :      do iexcit=1,min(nexcit_win,nexcitout)
    1473          470 :        write(std_out,*)' tddft : iexcit=',iexcit
    1474              : !      Select largest and next contributions
    1475          470 :        flargest=zero ; fnext=zero
    1476          470 :        nlargest=0 ; nnext=0
    1477          470 :        if(nsppol==2)then
    1478          120 :          fnext1=zero  ;  fnext2=zero
    1479          120 :          nnext1=0  ;  nnext2=0
    1480              :        end if
    1481        15988 :        do jexcit=1,nexcit_win
    1482        15518 :          ff=vec(1,jexcit,iexcit)**2+vec(2,jexcit,iexcit)**2
    1483        15988 :          if(ff>flargest+tol12)then
    1484         1475 :            if(nsppol==2)then
    1485          392 :              nnext2=nnext1  ; fnext2=fnext1
    1486          392 :              nnext1=nnext   ; fnext1=fnext
    1487              :            end if
    1488         1475 :            nnext=nlargest ; fnext=flargest
    1489         1475 :            nlargest=indarr(jexcit) ; flargest=ff
    1490        14043 :          else if(ff>fnext+tol12)then
    1491          825 :            if(nsppol==2)then
    1492          256 :              nnext2=nnext1 ; fnext2=fnext1
    1493          256 :              nnext1=nnext  ; fnext1=fnext
    1494              :            end if
    1495          825 :            nnext=indarr(jexcit) ; fnext=ff
    1496        13218 :          else if(nsppol==2)then
    1497         7152 :            if(ff>fnext1+tol12)then
    1498          228 :              nnext2=nnext1  ; fnext2=fnext1
    1499          228 :              nnext1=indarr(jexcit) ; fnext1=ff
    1500         6924 :            else if(ff>fnext2+tol12)then
    1501          224 :              nnext2=indarr(jexcit) ; fnext2=ff
    1502              :            end if
    1503              :          end if
    1504              : 
    1505              :        end do
    1506              : 
    1507          470 :        isppol_l = min((nlargest-1)/nexcit_pol(1) +1,nsppol)
    1508          470 :        iunocc_l = (nlargest-(isppol_l-1)*nexcit_pol(1)-1)/nband_occ(isppol_l)+1
    1509          470 :        iocc_l   = nlargest-(isppol_l-1)*nexcit_pol(1)-(iunocc_l-1)*nband_occ(isppol_l)
    1510          470 :        isppol_n = min((nnext-1)/nexcit_pol(1) +1,nsppol)
    1511          470 :        iunocc_n = (nnext-(isppol_n-1)*nexcit_pol(1)-1)/nband_occ(isppol_n)+1
    1512          470 :        iocc_n   = nnext-(isppol_n-1)*nexcit_pol(1)-(iunocc_n-1)*nband_occ(isppol_n)
    1513          470 :        if(nsppol==2)then
    1514          120 :          isppol_n1 = min((nnext1-1)/nexcit_pol(1) +1,nsppol)
    1515          120 :          iunocc_n1 = (nnext1-(isppol_n1-1)*nexcit_pol(1)-1)/nband_occ(isppol_n1)+1
    1516          120 :          iocc_n1   = nnext1-(isppol_n1-1)*nexcit_pol(1)-(iunocc_n1-1)*nband_occ(isppol_n1)
    1517          120 :          isppol_n2 = min((nnext2-1)/nexcit_pol(1) +1,nsppol)
    1518          120 :          iunocc_n2 = (nnext2-(isppol_n2-1)*nexcit_pol(1)-1)/nband_occ(isppol_n2)+1
    1519          120 :          iocc_n2   = nnext2-(isppol_n2-1)*nexcit_pol(1)-(iunocc_n2-1)*nband_occ(isppol_n2)
    1520              :        end if
    1521              : 
    1522          500 :        if(nsppol==1)then
    1523              :          write(message,'(i4,es15.5,es14.5,es16.6,f8.2,a,i3,a,i3,a,f6.2,a,i3,a,i3,a)') &
    1524          350 : &         iexcit,eexcit(iexcit),&
    1525          350 : &         eexcit(iexcit)*Ha_eV,eexcit(iexcit)+etotal,&
    1526          350 : &         flargest,'(',iocc_l,'->',iunocc_l+nband_occ(1),')',&
    1527          700 : &         fnext,   '(',iocc_n,'->',iunocc_n+nband_occ(1),')'
    1528          350 :          call wrtout(ab_out,message,'COLL')
    1529          350 :          call wrtout(std_out,message,'COLL')
    1530              :        else
    1531          120 :          write(chain1,'(f8.2,a,i3,a,i3,a)')flargest,'(',iocc_l,'->',iunocc_l+nband_occ(isppol_l),')'
    1532          120 :          write(chain2,'(f8.2,a,i3,a,i3,a)')fnext,'(',iocc_n,'->',iunocc_n+nband_occ(isppol_n),')'
    1533          120 :          if(trim(chain1)==trim(chain2))then
    1534              :            write(message,'(i4,es15.5,es14.5,es16.6,a,a,a,a)') &
    1535           80 : &           iexcit,eexcit(iexcit),&
    1536          160 : &           eexcit(iexcit)*Ha_eV,eexcit(iexcit)+etotal,trim(chain1),'(1)',trim(chain2),'(2)'
    1537              :          else
    1538              :            write(message,'(i4,es15.5,es14.5,es16.6,a,a,i1,a,a,a,i1,a)') &
    1539           40 : &           iexcit,eexcit(iexcit),&
    1540           40 : &           eexcit(iexcit)*Ha_eV,eexcit(iexcit)+etotal,trim(chain1),'(',isppol_l,')',&
    1541           80 : &           trim(chain2),'(',isppol_n,')'
    1542              :          end if
    1543          120 :          call wrtout(ab_out,message,'COLL')
    1544          120 :          call wrtout(std_out,message,'COLL')
    1545          120 :          write(chain1,'(f8.2,a,i3,a,i3,a)')fnext1,'(',iocc_n1,'->',iunocc_n1+nband_occ(isppol_n1),')'
    1546          120 :          write(chain2,'(f8.2,a,i3,a,i3,a)')fnext2,'(',iocc_n2,'->',iunocc_n2+nband_occ(isppol_n2),')'
    1547          120 :          if(trim(chain1)==trim(chain2))then
    1548              :            write(message,'(a,a,a,a,a)' ) &
    1549           80 : &           '                                                 ',&
    1550          160 : &           chain1,'(1)',chain2,'(2)'
    1551              :          else
    1552              :            write(message,'(a,a,a,i1,a,a,a,i1,a)' ) &
    1553           40 : &           '                                                 ',&
    1554           40 : &           chain1,'(',isppol_n1,')',&
    1555           80 : &           chain2,'(',isppol_n2,')'
    1556              :          end if
    1557          120 :          call wrtout(ab_out,message,'COLL')
    1558          120 :          call wrtout(std_out,message,'COLL')
    1559              :        end if
    1560              :      end do
    1561              : 
    1562              : !    For each iexcit excitation, compute the oscillator strength (Casida, eq 47)
    1563           30 :      write(message, '(a,a,a,a)' )ch10,&
    1564           30 : &     '  Oscillator strengths :  (elements smaller than 1.e-6 are set to zero)',ch10,&
    1565           60 : &     '  Excit#   (Ha)   Average    XX        YY        ZZ         XY        XZ        YZ'
    1566           30 :      call wrtout(ab_out,message,'COLL')
    1567           30 :      call wrtout(std_out,message,'COLL')
    1568              : 
    1569          860 :      do iexcit=1,nexcit_win
    1570              : 
    1571              : !      One of the factor of two comes from the spin degeneracy,
    1572              : !      the other comes from Eq.(40) of Casida
    1573          830 :        factor=(normint*ucvol)**2*two*two/nsppol
    1574              : 
    1575         6640 :        osc_str(:,iexcit)=zero
    1576              : 
    1577              : !      factor=(normint*ucvol)**2*two*two/nsppol
    1578              : 
    1579        37348 :        do jexcit=1,nexcit_win
    1580        36518 :          jexcit_cbase=indarr(jexcit)
    1581       146902 :          do idir=1,3
    1582              :            osc_str(idir+1,iexcit)=osc_str(idir+1,iexcit)+ &
    1583              : &           sexc(idir,jexcit)*sqrtks(jexcit_cbase)*sqrt(factor)* &
    1584       146072 : &           vec(1,jexcit,iexcit)
    1585              :          end do ! idir
    1586              :        end do ! jexcit
    1587              : 
    1588              : !      The "standard" definition of the oscillator strength is the square
    1589              : !      of the matrix elements.
    1590              : !      So, instead of the coding
    1591              : !      do idir=1,3
    1592              : !      osc_str(1,iexcit)=osc_str(1,iexcit)+osc_str(idir+1,iexcit)**2*third
    1593              : !      enddo
    1594              : !      I think that the following is more "standard"
    1595              : !      Now, osc_str(2:4,iexcit) are the X, Y and Z matrix elements, not
    1596              : !      yet the oscillator strengths
    1597          830 :        osc_str(5,iexcit)=osc_str(2,iexcit)*osc_str(3,iexcit)   ! off diag XY
    1598          830 :        osc_str(6,iexcit)=osc_str(2,iexcit)*osc_str(4,iexcit)   ! off diag XZ
    1599          830 :        osc_str(7,iexcit)=osc_str(3,iexcit)*osc_str(4,iexcit)   ! off diag ZZ
    1600         3320 :        do idir=1,3
    1601              : !        Here the X,Y, and Z matrix elements are combined to give diagonal osc. strengths
    1602         2490 :          osc_str(idir+1,iexcit)=osc_str(idir+1,iexcit)**2
    1603         3320 :          osc_str(1,iexcit)=osc_str(1,iexcit)+osc_str(idir+1,iexcit)*third ! compute the trace
    1604              :        end do
    1605              : !      At this stage, osc_str(1,iexcit) is exactly the same as from your coding
    1606              : !      ***End of section to be checked
    1607              : 
    1608         6640 :        do ii=1,7
    1609         6640 :          if(abs(osc_str(ii,iexcit))<tol6)osc_str(ii,iexcit)=zero
    1610              :        end do
    1611              : !      XG 020209 : Jean-Yves, the off-diagonal oscillator strengths
    1612              : !      can become negative. It is important for automatic
    1613              : !      checking that the numbers are separated by a blank, even
    1614              : !      if they are negative. So replace the following format, to have at least one blank.
    1615          830 :        write(message, '(i4,es12.5,es10.3,3es10.3,3es10.2)' )iexcit,eexcit(iexcit),osc_str(1:7,iexcit)
    1616          830 :        call wrtout(ab_out,message,'COLL')
    1617          860 :        call wrtout(std_out,message,'COLL')
    1618              :      end do
    1619              : 
    1620              : !    Check of the Sum rule for Casida eq.47,
    1621              : !    only exact if complete basis of excitations, as well as local potentials only.
    1622           30 :      sumx=zero
    1623          860 :      do iexcit=1,nexcit_win
    1624          860 :        sumx=sumx+osc_str(1,iexcit)
    1625              :      end do
    1626           30 :      write(message, '(a,es16.6)' )'  Sum of osc. strength : ',sumx
    1627           30 :      call wrtout(ab_out,message,'COLL')
    1628           30 :      call wrtout(std_out,message,'COLL')
    1629              : 
    1630              : !    If singlet, compute Cauchy coefficients
    1631           48 :      if(sing_trip==1.AND.nsppol==1)then
    1632           12 :        cauchy(:)=zero
    1633          232 :        do iexcit=1,nexcit_win
    1634          220 :          fr_invsquare=one/(eexcit(iexcit)**2)
    1635          220 :          fr_power=one
    1636         1772 :          do ii=1,7
    1637         1540 :            fr_power=fr_power*fr_invsquare
    1638         1760 :            cauchy(ii)=cauchy(ii)+osc_str(1,iexcit)*fr_power
    1639              :          end do
    1640              :        end do
    1641              :        write(message, '(a,es11.3,a,es11.3,a,es11.3,a,a,es11.3,a,es11.3,a,es11.3,a,es11.3)' ) &
    1642           12 : &       '  Cauchy coeffs (au) : ( -2)->',cauchy(1),&
    1643           12 : &       ', ( -4)->',cauchy(2),', ( -6)->',cauchy(3),ch10,&
    1644           24 : &       '    (-8)->',cauchy(4),', (-10)->',cauchy(5),', (-12)->',cauchy(6),', (-14)->',cauchy(7)
    1645           12 :        call wrtout(ab_out,message,'COLL')
    1646           12 :        call wrtout(std_out,message,'COLL')
    1647              :      end if
    1648              : 
    1649              : !    End the loop on singlet or triplet
    1650              :    end do
    1651              : 
    1652           18 :    ABI_FREE(eexcit2)
    1653           18 :    ABI_FREE(vec)
    1654           18 :    ABI_FREE(osc_str)
    1655              : 
    1656              : !! The temporary files should be deleted at the end of this routine
    1657           18 :    close(temp_unit2,status='delete')
    1658           18 :    call timab(95,2,tsec)
    1659              :  end if  ! end of am_master
    1660              : 
    1661           22 :  ABI_FREE(omega_tddft_casida)
    1662           22 :  ABI_FREE(eexcit)
    1663           22 :  ABI_FREE(sqrtks)
    1664           22 :  ABI_FREE(sexc)
    1665           22 :  ABI_FREE(done_sexc)
    1666           22 :  ABI_FREE(indarr)
    1667              : !ABI_FREE(done_sexc2)
    1668              : 
    1669          110 : end subroutine tddft
    1670              : !!***
    1671              : 
    1672              : end module m_tddft
    1673              : !!***
        

Generated by: LCOV version 2.3-1