LCOV - code coverage report
Current view: top level - src/71_bse - m_exc_itdiago.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.5 % 423 294
Test Date: 2026-11-08 04:19:34 Functions: 100.0 % 5 5
Branches: 46.5 % 818 380

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_exc_itdiago
       2                 :             : !! NAME
       3                 :             : !! m_exc_itdiago
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Iterative diagonalization of the BSE Hamiltonian with band-by-band conjugate gradient method
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG)
      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                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : MODULE m_exc_itdiago
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_bs_defs
      26                 :             :  use m_errors
      27                 :             :  use m_abicore
      28                 :             :  use m_linalg_interfaces
      29                 :             :  use m_hdr
      30                 :             :  USE_MPI
      31                 :             :  use m_xmpi
      32                 :             : 
      33                 :             :  use m_io_tools,      only : open_file
      34                 :             :  use m_time,          only : cwtime
      35                 :             :  use m_numeric_tools, only : stats_t, stats_eval
      36                 :             :  use m_hide_lapack,   only : xhpev !xheev,
      37                 :             :  use m_bse_io,        only : exc_read_rcblock
      38                 :             : 
      39                 :             :  implicit none
      40                 :             : 
      41                 :             :  private
      42                 :             : 
      43                 :             : #ifdef HAVE_MPI1
      44                 :             :  include 'mpif.h'
      45                 :             : #endif
      46                 :             : 
      47                 :             :  public :: exc_iterative_diago    ! Calculates eigenvalues and eigenvectors of the Resonant BSE Hamiltonian
      48                 :             : !!***
      49                 :             : 
      50                 :             : CONTAINS  !===============================================================
      51                 :             : !!***
      52                 :             : 
      53                 :             : !!****f* m_exc_itdiago/exc_iterative_diago
      54                 :             : !!
      55                 :             : !! NAME
      56                 :             : !!  exc_iterative_diago
      57                 :             : !!
      58                 :             : !! FUNCTION
      59                 :             : !!  Calculates eigenvalues and eigenvectors of the Hermitian excitonic Hamiltonian (coupling is neglected).
      60                 :             : !!
      61                 :             : !! INPUTS
      62                 :             : !!  Bsp
      63                 :             : !!    %nreh=Rank of the resonant block of the Hamiltonian.
      64                 :             : !!    %nstates=Number of eigenstates required.
      65                 :             : !!    %nline=Max number of line minimizations.
      66                 :             : !!    %tolwfr=Tolerance on the residuals.
      67                 :             : !!    %nbdbuf
      68                 :             : !!    %nstep
      69                 :             : !!  BS_files<excfiles>=Datatype storing names and files used in the Bethe-Salpeter code.
      70                 :             : !!    %exh=Name of the file storing the excitonin resonant part.
      71                 :             : !!    %out_eig_out=Name of the file where final results are store.
      72                 :             : !!    %in_eig=Name of the file used to initialize the calculation.
      73                 :             : !!  comm=MPI communicator.
      74                 :             : !!
      75                 :             : !! OUTPUT
      76                 :             : !!  Eigenvalues and eigenvectors are written on file %out_eig
      77                 :             : !!
      78                 :             : !! NOTES
      79                 :             : !!  Concernig the approach followed to parallelize this routine: the most important
      80                 :             : !!  bottleneck is represent by the storage of the excitonic Hamiltonian since a
      81                 :             : !!  large number of k-points is needed to obtain converged exciton energies.
      82                 :             : !!  The number of eigenstates is usually much smaller than the rank of the full matrix,
      83                 :             : !!  this is especially true if we are only interested in the binding energy of the
      84                 :             : !!  exciton or in the excitonic states close to the single-particle gap.
      85                 :             : !!  Therefore good scaling and good performance should be obtained by distributing
      86                 :             : !!  the row of the excitonic Hamiltonian among the nodes while the required
      87                 :             : !!  eigenvectors are duplicated on each node. The memory needed to stores the eigenvalues
      88                 :             : !!  scales like nreh*nstates where nreh is the rank of the Hamiltonian and this might
      89                 :             : !!  render the calculation unfeasible when nstates is large.
      90                 :             : !!  On the other hand, having the complex set of trial eigenvectors on each node permits to parallelize
      91                 :             : !!  tasks such as the application of the Hamiltonian as well as the orthogonalization or the sub-space rotation
      92                 :             : !!  the later two algorithms represent the most CPU demanding part in standard KS calculations
      93                 :             : !!  as they scale with the third power of the number of atoms.
      94                 :             : !!  The conjugate direction and the gradient as well as Hphi are not distributed as the line minimization
      95                 :             : !!  requires the evaluation of <cg_dir_|H_exc|cg_dir>.
      96                 :             : !!  Note that this routine has been written having in mind an homogeneous network of machines.
      97                 :             : !!  A network made of different CPU will lead to unpredictable results as each node has
      98                 :             : !!  to check for the converge of the calculation.
      99                 :             : !!
     100                 :             : !! SOURCE
     101                 :             : 
     102                 :           1 : subroutine exc_iterative_diago(BSp,BS_files,Hdr_bse,prtvol,comm)
     103                 :             : 
     104                 :             : !Arguments ------------------------------------
     105                 :             : !scalars
     106                 :             :  integer,intent(in) :: comm,prtvol
     107                 :             :  type(excparam),intent(in) :: BSp
     108                 :             :  type(excfiles),intent(in) ::  BS_files
     109                 :             :  type(Hdr_type),intent(in) :: Hdr_bse
     110                 :             : 
     111                 :             : !Local variables ------------------------------
     112                 :             : !scalars
     113                 :             :  integer,parameter :: STRICT=2,MEDIUM=1,WORST=0
     114                 :             :  integer,parameter :: master=0
     115                 :             :  integer(i8b) :: bsize_hmat,bsize_phi_block
     116                 :             :  integer :: hexc_size,nstates,nline,nbdbuf,nstep
     117                 :             :  integer :: cg_nsteps,my_t1,my_t2,my_nt
     118                 :             :  integer :: ii,jj,state,line,max_nline
     119                 :             :  integer :: cg_step,nbdbuf_,nsppol,ierr,nproc,my_rank
     120                 :             :  real(dp) :: exc_gap,exc_maxene,norm,etrial,etrial_old,deltae,tolwfr
     121                 :             : ! real(dp) :: deold
     122                 :             :  real(dp) :: dhd,dhc,den,fac,poly,xx,root,swap,tan2th,diff,tolwfr_
     123                 :             :  !complex(dp) :: cg_gamma,dotgg,old_dotgg
     124                 :             :  real(dp) :: cg_gamma,dotgg,old_dotgg
     125                 :             :  real(dp) :: max_resid,costh,sinth
     126                 :             :  complex(dp) :: zz,kprc
     127                 :             :  logical,parameter :: DEBUGME=.False.
     128                 :             :  logical :: use_mpio,is_resonant,diago_is_real
     129                 :             :  character(len=500) :: msg
     130                 :             :  character(len=fnlen) :: hexc_fname,ihexc_fname,oeig_fname
     131                 :             :  type(stats_t) :: stats
     132                 :             : !arrays
     133                 :           3 :  integer :: nline_for(Bsp%nstates),convergence_of(Bsp%nstates)
     134                 :           3 :  real(dp) :: resid(Bsp%nstates),exc_energy(Bsp%nstates),rbuf2(2)
     135                 :             : ! real(dp),allocatable :: gsc(:,:),cg(:,:)
     136                 :             :  !complex,allocatable :: hexc(:,:)
     137                 :           1 :  complex(dp),allocatable :: hexc(:,:),hji(:),vec_tmp(:)
     138                 :           1 :  complex(dp),contiguous, pointer :: my_phi(:)
     139                 :           1 :  real(dp),allocatable :: hexc_diagonal(:)
     140                 :           1 :  complex(dp),target,allocatable :: phi_block(:,:)
     141                 :           1 :  complex(dp),allocatable :: hphi(:) !,buffer_dpc(:)
     142                 :           1 :  complex(dp),allocatable :: cg_dir(:),grad_dir(:),prc_dir(:)
     143                 :           1 :  complex(dp),allocatable :: old_cg_dir(:)
     144                 :             : !************************************************************************
     145                 :             : 
     146                 :             :  DBG_ENTER("COLL")
     147                 :             : 
     148                 :           1 :  if (Bsp%use_coupling>0) then
     149                 :           0 :    ABI_ERROR("CG Method does not support coupling")
     150                 :             :  end if
     151                 :             : 
     152                 :           1 :  nsppol = Hdr_bse%nsppol
     153         [ -  + ]:           1 :  if (Hdr_bse%nsppol == 2) then
     154                 :           0 :    ABI_WARNING("nsppol==2 with cg method is still under development")
     155                 :             :  end if
     156                 :             : 
     157                 :           1 :  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     158                 :             : 
     159                 :           1 :  use_mpio=.FALSE.
     160                 :             : #ifdef HAVE_MPI_IO
     161                 :             :  use_mpio = (nproc > 1)
     162                 :             : #endif
     163                 :             :  use_mpio=.FALSE.
     164                 :             :  !use_mpio = .TRUE.
     165                 :             : 
     166         [ +  + ]:           2 :  hexc_size = SUM(Bsp%nreh)
     167                 :           1 :  nstates= Bsp%nstates
     168                 :           1 :  nline  = Bsp%nline
     169                 :           1 :  nbdbuf = Bsp%nbdbuf
     170                 :           1 :  nstep  = Bsp%niter
     171                 :           1 :  tolwfr = Bsp%cg_tolwfr
     172                 :             : 
     173                 :           1 :  write(msg,'(a,i0)')' Iterative diagonalization of the resonant excitonic Hamiltonian, Matrix size= ',hexc_size
     174                 :           1 :  call wrtout(std_out,msg,"COLL")
     175                 :           1 :  call wrtout(ab_out,msg,"COLL")
     176                 :             : 
     177         [ -  + ]:           1 :  ABI_CHECK(hexc_size>=nproc,"hexc_size<nproc!")
     178         [ -  + ]:           1 :  ABI_CHECK(nstates <= hexc_size,"nstates cannot be greater that hexc size!")
     179                 :             : 
     180                 :             :  ! Divide the columns of the Hamiltonian among the nodes.
     181                 :             :  call xmpi_split_work(hexc_size,comm,my_t1,my_t2)
     182                 :             : 
     183                 :           1 :  my_nt = my_t2-my_t1+1
     184                 :           1 :  write(msg,'(a,i0,a)')" Will handle ",my_nt," columns of the excitonic Hamiltonian. "
     185                 :           1 :  call wrtout(std_out,msg,"PERS")
     186                 :             : 
     187                 :           1 :  tolwfr_ = tolwfr
     188         [ -  + ]:           1 :  if (tolwfr < 10**(-30)) then
     189                 :           0 :    tolwfr_ = tol12
     190                 :           0 :    write(msg,'(2(a,es12.4))')" Input tolwfr= ",tolwfr," Using tolwfr= ",tolwfr_
     191                 :           0 :    ABI_WARNING(msg)
     192                 :             :  end if
     193                 :             : 
     194                 :           1 :  cg_nsteps = nstep
     195         [ -  + ]:           1 :  if (cg_nsteps<=0) then
     196                 :           0 :    cg_nsteps = 30
     197                 :           0 :    write(msg,'(2(a,es12.4))')" Input nstep= ",nstep," Using cg_nsteps= ",cg_nsteps
     198                 :           0 :    ABI_WARNING(msg)
     199                 :             :  end if
     200                 :             : 
     201                 :           1 :  nbdbuf_ = nbdbuf
     202         [ -  + ]:           1 :  if (nbdbuf<=0) then
     203                 :           0 :    nbdbuf_ = 4
     204                 :           0 :    write(msg,'(2(a,i0))')" Input nbdbuf= ",nbdbuf," Using nbdbuf= ",nbdbuf_
     205                 :           0 :    ABI_WARNING(msg)
     206                 :             :  end if
     207                 :             : 
     208                 :             :  write(msg,"(4(a,i0,a),a,es12.4)")&
     209                 :           1 : &  " cg_nsteps: ",cg_nsteps,ch10,&
     210                 :           1 : &  " nstates:   ",nstates,ch10,&
     211                 :           1 : &  " nline:     ",nline,ch10,&
     212                 :           1 : &  " nbdbuf:    ",nbdbuf_,ch10,&
     213                 :           2 : &  " tolwfr:    ",tolwfr_
     214                 :           1 :  call wrtout(std_out,msg,"COLL")
     215                 :           1 :  call wrtout(ab_out,msg,"COLL")
     216                 :             : 
     217                 :           1 :  bsize_hmat = 2*dp*hexc_size*my_nt
     218                 :           1 :  write(msg,'(a,f8.1,a)')' Allocating excitonic Hamiltonian. Memory requested: ',bsize_hmat*b2Mb,' Mb.'
     219                 :           1 :  call wrtout(std_out,msg,"COLL")
     220                 :             : 
     221   [ -  +  +  -  :           3 :  ABI_MALLOC(hexc_diagonal,(my_t1:my_t2))
          +  -  +  -  -  
                +  -  + ]
     222   [ -  +  +  -  :           4 :  ABI_MALLOC_OR_DIE(hexc,(hexc_size,my_t1:my_t2), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                -  -  + ]
     223                 :             :  !
     224                 :             :  ! Read and construct full excitonic Hamiltonian using Hermiticity.
     225         [ -  + ]:           1 :  if (BS_files%in_hreso /= BSE_NOFILE) then
     226                 :           0 :    hexc_fname = BS_files%in_hreso
     227                 :             :  else
     228                 :           1 :    hexc_fname = BS_files%out_hreso
     229                 :             :  end if
     230                 :             :  !
     231                 :             :  ! Read the resonant block from file.
     232                 :           1 :  is_resonant=.TRUE.
     233                 :           1 :  diago_is_real=(.not.BSp%have_complex_ene)
     234                 :           1 :  call exc_read_rcblock(hexc_fname,Bsp,is_resonant,diago_is_real,nsppol,Bsp%nreh,hexc_size,my_t1,my_t2,hexc,use_mpio,comm)
     235                 :             :  !
     236                 :             :  ! Save diagonal part for preconditioning.
     237         [ +  + ]:         385 :  do jj=my_t1,my_t2
     238                 :         385 :    hexc_diagonal(jj) = REAL(hexc(jj,jj),kind=dp)
     239                 :             :  end do
     240                 :             :  !
     241                 :             :  ! === Initialisation of the excitonic wavefunctions ===
     242                 :             :  ! Two cases are possible.
     243                 :             :  !   1) Fill trial eigenvectors with random numbers
     244                 :             :  !      One needs to initialize wfs in such a way to avoid symmetry traps,
     245                 :             :  !      and to avoid linear dependencies between wavefunctions
     246                 :             :  !   2) Read eigenstates generated by a previous calculation.
     247                 :             : 
     248                 :           1 :  bsize_phi_block = 2*sp*my_nt*nstates
     249                 :           1 :  write(msg,'(a,f8.1,a)')' Allocating BSE eigenvectors. Memory requested: ',bsize_phi_block*b2Mb,' Mb.'
     250                 :           1 :  call wrtout(std_out,msg,"COLL",do_flush=.True.)
     251                 :             : 
     252   [ -  +  +  -  :           4 :  ABI_MALLOC_OR_DIE(phi_block,(my_t1:my_t2,nstates), ierr)
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                -  -  + ]
     253                 :             : 
     254                 :           1 :  ihexc_fname = ""
     255         [ -  + ]:           1 :  if (BS_files%in_eig /= BSE_NOFILE) ihexc_fname = BS_files%in_eig
     256                 :             : 
     257                 :           1 :  call exc_init_phi_block(ihexc_fname,use_mpio,comm)
     258                 :             :  !
     259                 :             :  ! =========================
     260                 :             :  ! === Orthogonalization ===
     261                 :             :  ! =========================
     262                 :           1 :  call exc_cholesky_ortho()
     263                 :             :  call exc_check_phi_block("First cholesky ortho")
     264                 :             : 
     265                 :             :  ! * Sub-space rotation.
     266                 :           2 :  call exc_subspace_rotation()
     267                 :             :  call exc_check_phi_block("First subspace_rotation")
     268                 :             :  !
     269                 :             :  ! ===========================
     270                 :             :  ! ==== Conjugate gradient ===
     271                 :             :  ! ===========================
     272   [ +  -  +  -  :           3 :  ABI_MALLOC(hphi,(hexc_size))
          +  -  -  +  -  
                      + ]
     273   [ -  +  +  -  :           2 :  ABI_MALLOC(cg_dir,(hexc_size))
             -  +  -  + ]
     274   [ -  +  +  -  :           2 :  ABI_MALLOC(old_cg_dir,(hexc_size))
             -  +  -  + ]
     275   [ -  +  +  -  :           2 :  ABI_MALLOC(grad_dir,(hexc_size))
             -  +  -  + ]
     276   [ -  +  +  -  :           2 :  ABI_MALLOC(prc_dir,(hexc_size))
             -  +  -  + ]
     277                 :             : 
     278                 :             :  max_nline=nline
     279   [ +  +  +  +  :          31 :  resid(:)=HUGE(one); nline_for(1:nstates)=max_nline; convergence_of(1:nstates)=WORST
                   +  + ]
     280                 :             : 
     281         [ +  + ]:          21 :  do cg_step=1,cg_nsteps
     282         [ +  + ]:         220 :    do state=1,nstates
     283                 :             : 
     284         [ -  + ]:         200 :      if (prtvol>=10) then ! Tell us what is going on:
     285                 :           0 :        write(msg,'(a,i6,2x,a,i3,a)')' --- exc_iterative_diago is called for state ',state,'for',nline_for(state),' lines'
     286                 :           0 :        call wrtout(std_out,msg,'PERS')
     287                 :             :      end if
     288                 :             : 
     289                 :             :      ! Extraction of the vector that is iteratively updated.
     290                 :         200 :      my_phi => phi_block(my_t1:my_t2,state)
     291                 :             : 
     292         [ +  + ]:         933 :      do line=1,nline_for(state)
     293                 :             :        ! Compute etrial=<phi|H|phi> and the residual [H-etrial]|phi>.
     294         [ +  + ]:      283360 :        hphi = czero
     295                 :             : #ifdef FC_NVHPC
     296                 :             : !Buggy NVHPC compiler
     297                 :             :        do jj=1,my_t2-my_t1+1;do ii=1,hexc_size
     298                 :             :          hphi(ii)=hphi(ii)+hexc(ii,jj)*my_phi(jj)
     299                 :             :        enddo ; enddo
     300                 :             : #else
     301   [ +  -  -  +  :   326148832 :        hphi = MATMUL(hexc, my_phi)
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  +  +  +  
          +  +  +  -  +  
                -  +  - ]
     302                 :             : #endif
     303                 :         736 :        call xmpi_sum(hphi,comm,ierr)
     304                 :             : 
     305         [ +  + ]:      283360 :        etrial = DOT_PRODUCT(my_phi, hphi(my_t1:my_t2))
     306                 :         736 :        call xmpi_sum(etrial,comm,ierr)
     307                 :         736 :        exc_energy(state) =  etrial
     308                 :             : 
     309                 :             :        ! Compute residual (squared) norm.
     310         [ +  + ]:      283360 :        grad_dir(my_t1:my_t2) = hphi(my_t1:my_t2) - etrial*my_phi
     311         [ +  + ]:      283360 :        resid(state) =  DOT_PRODUCT(grad_dir(my_t1:my_t2), grad_dir(my_t1:my_t2))
     312                 :         736 :        call xmpi_sum(resid(state),comm,ierr)
     313                 :        1472 :        convergence_of(state) = convergence_degree(resid(state))
     314                 :             :        !
     315                 :             :        ! Check that etrial is decreasing on succeeding lines:
     316   [ +  +  -  + ]:         736 :        if (line>1 .and. (etrial > etrial_old+tol12)) then
     317                 :             :          write(msg,'(a,i8,a,1p,e14.6,a1,3x,a,1p,e14.6,a1)')&
     318                 :           0 : &          'New trial exc_energy at line ',line,' = ',etrial,ch10,&
     319                 :           0 : &          'is higher than former:',etrial_old,ch10
     320                 :           0 :          ABI_WARNING(msg)
     321                 :             :        end if
     322                 :         736 :        etrial_old = etrial
     323                 :             :        !
     324                 :             :        ! If residual sufficiently small stop line minimization.
     325         [ +  + ]:         736 :        if (convergence_of(state)==STRICT) then
     326         [ -  + ]:          23 :          if (prtvol>=10) then
     327                 :             :            write(msg,'(a,i4,a,i2,a,es12.4)')&
     328                 :           0 : &            ' exc_iterative_diago: state ',state,' converged after ',line,&
     329                 :           0 : &            ' line minimizations : resid =',resid(state)
     330                 :           0 :            call wrtout(std_out,msg,'PERS')
     331                 :             :          end if
     332                 :             :          EXIT !line
     333                 :             :        end if
     334                 :             : 
     335                 :             :        ! === PROJECT THE STEEPEST DESCENT DIRECTION OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS ===
     336                 :             :        ! The following projection over the subspace orthogonal to occupied bands
     337                 :             :        ! is optional. It is a bit more accurate, but doubles the number of N^3 ops.
     338                 :             :        ! It is done only if ortalg>=0.
     339                 :             : 
     340                 :             :        ! Project the steepest descent direction: direc(2,npw)=<G|H|Cnk> - \sum_{(i<=n)} <G|H|Cik> , normalized.
     341                 :             : 
     342                 :             :        ! Grad_dir is already orthogonal to this band
     343   [ -  +  +  -  :        2139 :        ABI_MALLOC(hji,(nstates))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     344         [ +  + ]:        7843 :        hji=czero
     345                 :             : 
     346                 :             :        ! MG TODO Don't know why here we sum over i=<=n!!!!!!!!
     347         [ +  + ]:        7843 :        do jj=1,nstates
     348   [ +  +  +  + ]:     2471971 :          if (jj/=state) hji(jj) = DOT_PRODUCT(phi_block(:,jj), hphi(my_t1:my_t2) )
     349                 :             :        end do
     350                 :         713 :        call xmpi_sum(hji,comm,ierr)
     351                 :             : 
     352         [ +  + ]:        7843 :        do jj=1,nstates
     353   [ +  +  +  + ]:     2471971 :          if (jj/=state) grad_dir(my_t1:my_t2) = grad_dir(my_t1:my_t2) - hji(jj)*phi_block(:,jj)
     354                 :             :        end do
     355         [ -  + ]:         713 :        ABI_FREE(hji)
     356                 :             :        !
     357                 :             :        ! === PRECONDITION THE STEEPEST DESCENT DIRECTION ===
     358         [ +  + ]:      274505 :        den = DOT_PRODUCT(grad_dir(my_t1:my_t2), hexc_diagonal(my_t1:my_t2)*grad_dir(my_t1:my_t2) )
     359                 :         713 :        call xmpi_sum(den,comm,ierr)
     360                 :             : 
     361         [ +  + ]:      274505 :        do ii=my_t1,my_t2
     362                 :             :          ! Teter polynomial ratio, modified according to Kresse, Furthmuller, PRB 54, 11169 (1996) [[cite:Kresse1996]]
     363                 :      273792 :          xx = hexc_diagonal(ii)/den
     364                 :      273792 :          poly=27._dp+xx*(18._dp+xx*(12._dp+xx*8._dp))
     365                 :      273792 :          fac=poly/(poly+16._dp*xx**4)
     366                 :      273792 :          kprc = fac*four/(three*den)
     367                 :      274505 :          prc_dir(ii) = kprc * grad_dir(ii)
     368                 :             :        end do
     369                 :             :        !
     370                 :             :        ! * PROJECT THE PRECOND. STEEPEST DESCENT DIRECTION OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS.
     371   [ -  +  +  -  :        2139 :        ABI_MALLOC(hji,(nstates))
          +  -  +  -  -  
                +  -  + ]
     372         [ +  + ]:        7843 :        hji=czero
     373         [ +  + ]:        7843 :        do jj=1,nstates
     374         [ +  + ]:     2745763 :          hji(jj) = DOT_PRODUCT(phi_block(:,jj), prc_dir(my_t1:my_t2) )
     375                 :             :        end do
     376                 :         713 :        call xmpi_sum(hji,comm,ierr)
     377                 :             : 
     378         [ +  + ]:        7843 :        do jj=1,nstates
     379         [ +  + ]:     2745763 :          prc_dir(my_t1:my_t2) = prc_dir(my_t1:my_t2) - hji(jj)*phi_block(:,jj)
     380                 :             :        end do
     381         [ -  + ]:         713 :        ABI_FREE(hji)
     382                 :             :        !
     383                 :             :        ! === COMPUTE THE CONJUGATE-GRADIENT ===
     384         [ +  + ]:      274505 :        dotgg = DOT_PRODUCT(prc_dir(my_t1:my_t2),grad_dir(my_t1:my_t2))
     385                 :         713 :        call xmpi_sum(dotgg,comm,ierr)
     386                 :             : 
     387         [ +  + ]:         713 :        if (line==1) then ! At first iteration, cg_gamma is set to zero
     388                 :         179 :          cg_gamma=zero
     389                 :         179 :          old_dotgg=dotgg
     390   [ -  +  +  + ]:       69094 :          cg_dir = prc_dir
     391   [ -  +  +  + ]:       69094 :          old_cg_dir = cg_dir
     392                 :             :        else
     393                 :         534 :          cg_gamma=dotgg/old_dotgg
     394                 :         534 :          old_dotgg=dotgg
     395                 :             :          !write(std_out,*)"cg_gamma= ",cg_gamma
     396                 :             :          !cg_dir = prc_dir + cg_gamma*cg_dir
     397   [ -  +  +  + ]:      206124 :          cg_dir = prc_dir + cg_gamma*old_cg_dir !TODO check this, anyhow it is much faster.
     398   [ -  +  +  + ]:      206124 :          old_cg_dir =cg_dir  ! old_cg_dir is used to store the previsou CG direction, cg_dir will be orthonormalized to the band
     399                 :             :        end if
     400                 :             :        !
     401                 :             :        ! === PROJECTION OF THE CONJUGATED GRADIENT ===
     402         [ +  + ]:      274505 :        zz = DOT_PRODUCT(my_phi, cg_dir(my_t1:my_t2))
     403                 :         713 :        call xmpi_sum(zz,comm,ierr)
     404         [ +  + ]:      274505 :        cg_dir(my_t1:my_t2) = cg_dir(my_t1:my_t2) -zz*my_phi(:)
     405                 :             : 
     406         [ +  + ]:      274505 :        norm = DOT_PRODUCT(cg_dir(my_t1:my_t2), cg_dir(my_t1:my_t2) )
     407                 :         713 :        call xmpi_sum(norm,comm,ierr)
     408                 :         713 :        norm = SQRT(norm)
     409         [ +  + ]:      274505 :        cg_dir = cg_dir/norm ! Have to normalize it.
     410                 :             : 
     411                 :             :        ! Line minimization of the Raileigh functional.
     412   [ -  +  +  -  :        2139 :        ABI_MALLOC(vec_tmp,(hexc_size))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     413         [ +  + ]:      274505 :        vec_tmp=czero
     414                 :             : #ifdef FC_NVHPC
     415                 :             : !Buggy NVHPC compiler
     416                 :             :        do jj=my_t1,my_t2;do ii=1,hexc_size
     417                 :             :          vec_tmp(ii)=vec_tmp(ii)+hexc(ii,jj-my_t1+1)*cg_dir(jj)
     418                 :             :        enddo ; enddo
     419                 :             : #else
     420   [ +  -  -  +  :   210820553 :        vec_tmp = MATMUL(hexc, cg_dir(my_t1:my_t2))
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  +  +  +  
          +  +  +  -  +  
                      - ]
     421                 :             : #endif
     422                 :         713 :        call xmpi_sum(vec_tmp,comm,ierr)
     423                 :             : 
     424                 :             :        !if (my_rank==master) then
     425                 :             :        !  write(777,*)"cg_step, state, line",cg_step, state, line
     426                 :             :        !  write(777,*)vec_tmp
     427                 :             :        !end if
     428                 :             : 
     429         [ +  + ]:      274505 :        dhd = DOT_PRODUCT( cg_dir(my_t1:my_t2), vec_tmp(my_t1:my_t2))  ! is this always real?
     430         [ +  + ]:      274505 :        dhc = REAL( DOT_PRODUCT( my_phi, vec_tmp(my_t1:my_t2) ))
     431         [ -  + ]:         713 :        ABI_FREE(vec_tmp)
     432                 :             : 
     433         [ +  + ]:        2139 :        rbuf2 = (/dhd,dhc/)
     434                 :         713 :        call xmpi_sum(rbuf2,comm,ierr)
     435                 :         713 :        dhd = rbuf2(1)
     436                 :         713 :        dhc = rbuf2(2)
     437                 :             : 
     438                 :             :        !write(201*(my_rank+1),*)"cg_step, state, line dotgg dhd dhc",cg_step,state,line,dotgg,dhd,dhc
     439                 :             : 
     440                 :             : ! Taken from cgwf
     441                 :             :        ! Compute tan(2 theta),sin(theta) and cos(theta)
     442                 :         713 :        tan2th=2.0_dp*dhc/(etrial-dhd)
     443                 :             : 
     444         [ +  + ]:         713 :        if (abs(tan2th)<1.d-05) then
     445                 :          67 :          costh=1.0_dp-0.125_dp*tan2th**2
     446                 :          67 :          sinth=0.5_dp*tan2th*(1.0_dp-0.375_dp*tan2th**2)
     447                 :             :          ! Check that result is above machine precision
     448                 :             :          ! FIXME  This part is not safe on clusters made of different machines or different compiation options.
     449         [ -  + ]:          67 :          if (abs(sinth)<epsilon(0._dp)) then
     450                 :           0 :            write(msg, '(a,es16.4)' ) ' exc_iterative_diago: converged with tan2th= ',tan2th
     451                 :           0 :            call wrtout(std_out,msg,'PERS')
     452                 :           0 :            EXIT !Exit from the loop on line
     453                 :             :          end if
     454                 :             : 
     455                 :             :        else
     456                 :         646 :          root =sqrt(1.0_dp+tan2th**2)
     457                 :         646 :          costh=sqrt(0.5_dp+0.5_dp/root)
     458                 :         646 :          sinth=sign(sqrt(0.5_dp-0.5_dp/root),tan2th)
     459                 :             :        end if
     460                 :             :        !
     461                 :             :        ! Check for lower of two possible roots (same sign as curvature at theta where slope is zero)
     462                 :         713 :        diff=(etrial-dhd)
     463         [ +  + ]:         713 :        if (diff>zero) then !   Swap c and d if value of diff is positive
     464                 :          10 :          swap=costh
     465                 :          10 :          costh=-sinth
     466                 :          10 :          sinth=swap
     467         [ -  + ]:          10 :          if (prtvol<0 .or. prtvol>=10) then
     468                 :           0 :            write(msg,'(a,i4,es16.6)')' exc_iterative_diago: swap roots, line,diff= ',line,diff
     469                 :           0 :            call wrtout(std_out,msg,'PERS')
     470                 :             :          end if
     471                 :             :        end if
     472                 :             :        !
     473                 :             :        ! === GENERATE NEW |wf>, H|wf>  =============
     474         [ +  + ]:      274505 :        my_phi = costh*my_phi + sinth*cg_dir(my_t1:my_t2)
     475                 :             :        !write(100*(my_rank+1),*)"cg_step state, line costh sinth etrial",cg_step,state,line,costh,sinth,etrial
     476                 :             : !end  taken from cgwf
     477                 :             : 
     478                 :             :        !norm = SQRT( DOT_PRODUCT(my_phi,my_phi) )
     479                 :             :        !my_phi = my_phi /norm
     480                 :             :        !write(std_out,*)norm
     481                 :             :        !write(std_out,*)DOT_PRODUCT(hphi,my_phi),cos(theta_min)
     482                 :             : 
     483                 :             :        ! ======================================================================
     484                 :             :        ! =========== CHECK CONVERGENCE AGAINST TRIAL ENERGY ===================
     485                 :             :        ! ======================================================================
     486                 :             :        ! Compute delta(E)
     487                 :             :        !deltae=chc*(costh**2-1._dp)+dhd*sinth**2+2._dp*costh*sinth*dhc
     488                 :        8089 :        deltae=etrial*(costh**2-1._dp)+dhd*sinth**2+2._dp*costh*sinth*dhc
     489                 :             : 
     490                 :             :        ! Check convergence and eventually exit
     491                 :             :        ! if (line==1) then
     492                 :             :        !   deold=deltae
     493                 :             :        ! else if (abs(deltae)<0.005_dp*abs(deold) .and. line/=nline_for(state))then
     494                 :             :        !  if (prtvol>=10)then
     495                 :             :        !   write(msg, '(a,i4,1x,a,1p,e12.4,a,e12.4,a)' ) &
     496                 :             :        !&   ' cgwf: line',line,&
     497                 :             :        !&   ' deltae=',deltae,' < 0.005*',deold,' =>skip lines'
     498                 :             :        !   call wrtout(std_out,msg,'PERS')
     499                 :             :        !  end if
     500                 :             :        !  exc_energy(state) = exc_energy(state) + deltae
     501                 :             :        !  EXIT
     502                 :             :        ! end if
     503                 :             :      end do ! LOOP FOR A GIVEN BAND. Note that there are three "exit" instructions inside
     504                 :             :      ! Modify nline_for(state) according to converge degree.
     505                 :             :      !if (convergence_of(state) == STRICT) nline_for(state) = MAX(max_nline-2,2)
     506                 :             :      !if (convergence_of(state) == MEDIUM) nline_for(state) = MAX(max_nline-1,2)
     507                 :             :      !if (convergence_of(state) == WORST ) nline_for(state) = max_nline
     508                 :             :    end do !state
     509                 :             : 
     510         [ -  + ]:          20 :    if (prtvol>2) then
     511         [ #  # ]:           0 :      do ii=0,(nstates-1)/8
     512                 :           0 :        write(msg,'(a,8es10.2)')' res:',(resid(state),state=1+ii*8,MIN(nstates,8+ii*8))
     513                 :           0 :        call wrtout(std_out,msg,'COLL')
     514                 :             :      end do
     515         [ #  # ]:           0 :      do ii=0,(nstates-1)/8
     516                 :           0 :        write(msg,'(a,8es10.2)')' ene:',(exc_energy(state),state=1+ii*8,MIN(nstates,8+ii*8))
     517                 :           0 :        call wrtout(std_out,msg,'COLL')
     518                 :             :      end do
     519                 :             :    end if
     520                 :             : 
     521                 :          20 :    write(msg,'(a,i0)')"After cg_step: ",cg_step
     522                 :             :    call exc_check_phi_block(msg)
     523                 :             : 
     524                 :             :    ! Find largest residual over bands and Print residuals
     525   [ -  +  +  -  :         160 :    max_resid=MAXVAL( resid(:MAX(1,nstates-nbdbuf_)) )
                   +  + ]
     526                 :             : 
     527         [ -  + ]:          20 :    if (max_resid < tolwfr_) then
     528                 :             :      write(msg,'(a,i0,2(a,es10.2),a,i0,a)')&
     529                 :           0 : &      " After ",cg_step," iterations, max_resid= ",max_resid," < tolwfr= ",tolwfr_," ( Excluding nbdbuf= ",nbdbuf_,")"
     530                 :           0 :      call wrtout(std_out,msg,'COLL')
     531                 :           0 :      EXIT ! cg_step
     532                 :             :    end if
     533                 :             : 
     534                 :             :    if (cg_step==1.or.MOD(cg_step,1)==0) then
     535                 :          20 :      call wrtout(std_out," Subspace rotation + exc_cholesky_ortho ","COLL")
     536                 :             : 
     537                 :          20 :      call exc_subspace_rotation()
     538                 :          20 :      call exc_cholesky_ortho()
     539                 :             : 
     540                 :             :      !mcg=hexc_size; mgsc=hexc_size; useoverlap=0
     541                 :             :      !allocate(cg(2,mcg),gsc(2,mgsc*useoverlap))
     542                 :             :      !do ii=1,nstates
     543                 :             :      ! cg(1,:) = REAL (phi_block(:,ii))
     544                 :             :      ! cg(2,:) = AIMAG(phi_block(:,ii))
     545                 :             :      ! call fxphas(cg,gsc,0,0,1,mcg,mgsc,MPI_enreg_seq,1,hexc_size,useoverlap)
     546                 :             :      ! phi_block(:,ii)=CMPLX(cg(1,:),cg(2,:))
     547                 :             :      !end do
     548                 :             :      !deallocate(cg,gsc)
     549                 :             : 
     550                 :             :    end if
     551                 :             : 
     552                 :             : !XG20141126 : At present, keep this fake test. Seems that there is some bug on shiva
     553                 :             : !(compiler ?) so that the result is erroneous without it. Even suppressing the
     554                 :             : !"stop" instruction triggers the bug ...
     555                 :           1 :      if(cg_step==cg_nsteps+1)then
     556                 :             :        write(std_out,*)' One should not be here : cg_step==cg_nsteps+1 '
     557                 :             :        stop
     558                 :             :      endif
     559                 :             : 
     560                 :             :  end do !cg_step
     561                 :             : 
     562                 :             :  ! Release some memory before entering RMM-DIIS
     563         [ -  + ]:           1 :  ABI_FREE(hphi)
     564         [ -  + ]:           1 :  ABI_FREE(cg_dir)
     565         [ -  + ]:           1 :  ABI_FREE(old_cg_dir)
     566         [ -  + ]:           1 :  ABI_FREE(grad_dir)
     567         [ -  + ]:           1 :  ABI_FREE(prc_dir)
     568                 :             : 
     569         [ +  + ]:           3 :  do ii=0,(nstates-1)/8
     570                 :           2 :    write(msg,'(a,8es10.2)')' res:',(resid(state),state=1+ii*8,min(nstates,8+ii*8))
     571                 :           3 :    call wrtout(std_out,msg,'COLL')
     572                 :             :  end do
     573         [ +  + ]:           3 :  do ii=0,(nstates-1)/8
     574                 :           2 :    write(msg,'(a,8es10.2)')' ene:',(exc_energy(state),state=1+ii*8,min(nstates,8+ii*8))
     575                 :           3 :    call wrtout(std_out,msg,'COLL')
     576                 :             :  end do
     577                 :             : 
     578                 :           1 :  stats = stats_eval(resid)
     579                 :             : 
     580                 :             :  write(msg,"(4(a,es10.2))")&
     581                 :           1 : &  ". Residuals: min value: ",stats%min,", Max value: ",stats%max,", mean: ",stats%mean,", stdev: ",stats%stdev
     582                 :           1 :  call wrtout(std_out,msg)
     583                 :           1 :  call wrtout(ab_out,msg)
     584                 :             : 
     585         [ +  - ]:           1 :  if (max_resid > tolwfr_) then
     586                 :           1 :    write(msg,'(2a,i5,2a,2(a,es10.2),a,i3,a)')ch10,&
     587                 :           1 : &    " WARNING: conjugate-gradient not converged after ",cg_step," iterations.",ch10,&
     588                 :           2 : &    " max_resid= ",max_resid," > tolwfr= ",tolwfr_," ( Excluding nbdbuf= ",nbdbuf_,")"
     589                 :           1 :    call wrtout(ab_out,msg,'COLL')
     590                 :           1 :    call wrtout(std_out,msg,'COLL')
     591                 :             :  end if
     592                 :             : 
     593   [ +  -  -  +  :          12 :  exc_gap    = MINVAL(exc_energy)
             -  -  +  + ]
     594   [ +  -  -  +  :          12 :  exc_maxene = MAXVAL(exc_energy)
             -  -  +  + ]
     595                 :             : 
     596                 :           1 :  write(msg,'(a,2(a,f7.2,2a))')ch10,&
     597                 :           1 : &  " First excitonic eigenvalue= ",exc_gap*Ha_eV,   " [eV]. ",ch10,&
     598                 :           2 : &  " Last  excitonic eigenvalue= ",exc_maxene*Ha_eV," [eV]. ",ch10
     599                 :           1 :  call wrtout(std_out,msg,"COLL")
     600                 :           1 :  call wrtout(ab_out,msg,"COLL")
     601                 :             : 
     602                 :             :  call exc_check_phi_block("END OF CONJUGATE-GRADIENT")
     603                 :             : 
     604                 :           0 :  ABI_FREE(hexc)
     605         [ -  + ]:           1 :  ABI_FREE(hexc_diagonal)
     606                 :             :  !
     607                 :             :  ! =====================================
     608                 :             :  ! ==== Write final results on file ====
     609                 :             :  ! =====================================
     610                 :           1 :  oeig_fname = BS_files%out_eig
     611         [ -  + ]:           1 :  if (oeig_fname== BSE_NOFILE) then
     612                 :           0 :    ABI_WARNING("oeig_fname was set to "//TRIM(BSE_NOFILE))
     613         [ #  # ]:           0 :    oeig_fname = TRIM(BS_files%out_basename)//"_BSEIG"
     614         [ #  # ]:           0 :    ABI_WARNING("using oeig_fname : "//TRIM(oeig_fname))
     615                 :             :  end if
     616                 :             : 
     617                 :           1 :  call exc_write_phi_block(oeig_fname,use_mpio)
     618                 :             : 
     619         [ -  + ]:           1 :  ABI_FREE(phi_block)
     620                 :             : 
     621   [ -  +  -  +  :           3 :  call xmpi_barrier(comm)
          -  +  -  +  -  
                      + ]
     622                 :             : 
     623                 :             :  DBG_EXIT("COLL")
     624                 :             : 
     625                 :             : CONTAINS  !===========================================================
     626                 :             : !!***
     627                 :             : 
     628                 :             : !----------------------------------------------------------------------
     629                 :             : 
     630                 :             : !!****f* m_exc_itdiago/exc_init_phi_block
     631                 :             : !! NAME
     632                 :             : !! exc_init_phi_block
     633                 :             : !!
     634                 :             : !! FUNCTION
     635                 :             : !!  Initialize the eigenstates either from file or fill them with random number
     636                 :             : !!  if restart file is not available
     637                 :             : !!
     638                 :             : !! INPUTS
     639                 :             : !!  ihexc_fname=
     640                 :             : !!    Name of the file from which the eigenvectors will be read.
     641                 :             : !!    Empty string to initialize trial eigenvectors with random numbers.
     642                 :             : !!
     643                 :             : !! SIDE EFFECTS
     644                 :             : !!   phi_block(my_t1:my_t2,nstates)=Contains the trial eigenstates.
     645                 :             : !!
     646                 :             : !! SOURCE
     647                 :             : 
     648                 :           1 : subroutine exc_init_phi_block(ihexc_fname,use_mpio,comm)
     649                 :             : 
     650                 :             : !Arguments ------------------------------------
     651                 :             : !scalars
     652                 :             :  integer,intent(in) :: comm
     653                 :             :  logical,intent(in) :: use_mpio
     654                 :             :  character(len=*),intent(in) :: ihexc_fname
     655                 :             : 
     656                 :             : !Local variables ------------------------------
     657                 :             :  integer :: eig_unt,hexc_size_restart,ii,state,seed
     658                 :             :  integer ::  fold1,fold2,foldim,foldre
     659                 :             :  real(dp) :: cputime,walltime,gflops
     660                 :             :  character(len=500) :: errmsg
     661                 :             : !arrays
     662                 :           1 :  complex(dp),allocatable :: buffer_dpc(:)
     663                 :             : #ifdef HAVE_MPI_IO
     664                 :             :  integer:: amode,mpi_fh,mpi_err,old_type,etype,eig_type,my_nel,ierr,my_nrows
     665                 :             :  integer(XMPI_OFFSET_KIND) :: ehdr_offset,my_offset,my_offpad,fmarker
     666                 :           1 :  integer(XMPI_OFFSET_KIND),allocatable :: bsize_frecord(:)
     667                 :             :  integer :: array_of_sizes(2),array_of_subsizes(2),array_of_starts(2)
     668                 :             : #endif
     669                 :             : !************************************************************************
     670                 :             : 
     671         [ +  - ]:           1 :  if (LEN_TRIM(ihexc_fname) == 0) then
     672                 :           1 :    call wrtout(std_out," Initializing eigenvectors with random numbers","COLL")
     673                 :             :    !
     674                 :             :    ! Use random number generator. For portability, use only integer numbers
     675                 :             :    ! The series of couples (fold1,fold2) is periodic with a period of
     676                 :             :    ! 3x5x7x11x13x17x19x23x29x31, that is, larger than 2**32, the largest integer*4
     677                 :             :    ! fold1 is between 0 and 34, fold2 is between 0 and 114. As sums of five
     678                 :             :    ! uniform random variables, their distribution is close to a gaussian
     679                 :             :    ! the gaussian distributions are folded, in order to be back to a uniform distribution
     680                 :             :    ! foldre is between 0 and 20, foldim is between 0 and 18.
     681                 :             :    !
     682         [ +  + ]:          11 :    do state=1,nstates
     683         [ +  + ]:        3851 :      do ii=my_t1,my_t2
     684                 :        3840 :        seed=ii+(state-1)*hexc_size ! Different seed for different transitions and bands
     685                 :        3840 :        fold1 =mod(seed,3)+mod(seed,5)+mod(seed,7)+mod(seed,11)+mod(seed,13)
     686                 :        3840 :        fold2 =mod(seed,17)+mod(seed,19)+mod(seed,23)+mod(seed,29)+mod(seed,31)
     687                 :        3840 :        foldre=mod(fold1+fold2,21)
     688                 :        3840 :        foldim=mod(3*fold1+2*fold2,19)
     689                 :             : 
     690                 :        3850 :        phi_block(ii,state) = DCMPLX(foldre,foldim)
     691                 :             :      end do
     692                 :             :    end do
     693                 :             : 
     694                 :             :  else
     695                 :             : 
     696                 :           0 :    call cwtime(cputime, walltime, gflops, "start")
     697                 :             : 
     698         [ #  # ]:           0 :    if (.not.use_mpio) then
     699         [ #  # ]:           0 :      call wrtout(std_out," Initializing eigenvectors from file: "//TRIM(ihexc_fname)//" using Fortran IO.","COLL")
     700                 :             : 
     701         [ #  # ]:           0 :      if (open_file(ihexc_fname,msg,newunit=eig_unt,form='unformatted',status="old") /=0 ) then
     702                 :           0 :        ABI_ERROR(msg)
     703                 :             :      end if
     704                 :             : 
     705         [ #  # ]:           0 :      read(eig_unt, err=10, iomsg=errmsg) hexc_size_restart
     706         [ #  # ]:           0 :      ABI_CHECK(hexc_size_restart==hexc_size,"hexc_size_restart /= hexc_size")
     707         [ #  # ]:           0 :      read(eig_unt, err=10, iomsg=errmsg) !skip DCMPLX(exevl(1:hexc_size))
     708                 :             : 
     709   [ #  #  #  #  :           0 :      ABI_MALLOC(buffer_dpc,(hexc_size))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     710         [ #  # ]:           0 :      do ii=1,nstates
     711         [ #  # ]:           0 :        read(eig_unt, err=10, iomsg=errmsg) buffer_dpc
     712         [ #  # ]:           0 :        phi_block(my_t1:my_t2,ii) = buffer_dpc(my_t1:my_t2)
     713                 :             :      end do
     714         [ #  # ]:           0 :      ABI_FREE(buffer_dpc)
     715                 :             : 
     716         [ #  # ]:           0 :      close(eig_unt, err=10, iomsg=errmsg)
     717                 :             :    else
     718         [ #  # ]:           0 :      call wrtout(std_out," Initializing eigenvectors from file: "//TRIM(ihexc_fname)//" using MPI-IO.","COLL")
     719                 :             : #ifdef HAVE_MPI_IO
     720                 :             :      !
     721                 :             :      ! Open the file with MPI-IO
     722                 :           0 :      amode=MPI_MODE_RDONLY
     723                 :             : 
     724                 :           0 :      call MPI_FILE_OPEN(comm, ihexc_fname, amode, MPI_INFO_NULL, mpi_fh, mpi_err)
     725         [ #  # ]:           0 :      msg = " MPI_IO error opening file: "//TRIM(ihexc_fname)
     726                 :           0 :      ABI_CHECK_MPI(mpi_err,msg)
     727                 :             : 
     728                 :             :      ! Move the file pointer to skip the first two records.
     729                 :           0 :      ehdr_offset=0
     730                 :           0 :      call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
     731                 :           0 :      write(std_out,*)"fmarker first record ",fmarker
     732                 :           0 :      call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
     733                 :           0 :      write(std_out,*)"fmarker first record ",fmarker
     734                 :             :      !%call hdr_mpio_skip(mpi_fh,fform,ehdr_offset)
     735                 :             :      !%ehdr_offset = 4*xmpio_bsize_frm + xmpio_bsize_int + nstates*xmpio_bsize_dpc
     736                 :             : 
     737                 :           0 :      etype=MPI_BYTE; old_type=MPI_DOUBLE_COMPLEX
     738                 :             : 
     739                 :           0 :      my_nrows=my_t2-my_t1+1; old_type=MPI_DOUBLE_COMPLEX
     740         [ #  # ]:           0 :      array_of_sizes    = (/hexc_size,nstates/)
     741         [ #  # ]:           0 :      array_of_subsizes = (/my_nrows,nstates/)
     742         [ #  # ]:           0 :      array_of_starts   = (/my_t1,1/)
     743                 :           0 :      call xmpio_create_fsubarray_2D(array_of_sizes,array_of_subsizes,array_of_starts,old_type,eig_type,my_offpad,mpi_err)
     744                 :           0 :      ABI_CHECK_MPI(mpi_err,"fsubarray_2D")
     745                 :             :      !
     746                 :             :      ! Each node uses a different offset to skip the header and the blocks written by the other CPUs.
     747                 :           0 :      my_offset = ehdr_offset + my_offpad
     748                 :             : 
     749                 :           0 :      call MPI_FILE_SET_VIEW(mpi_fh, my_offset, etype, eig_type, 'native', MPI_INFO_NULL, mpi_err)
     750                 :           0 :      ABI_CHECK_MPI(mpi_err,"SET_VIEW")
     751                 :             : 
     752                 :           0 :      call MPI_TYPE_FREE(eig_type,mpi_err)
     753                 :           0 :      ABI_CHECK_MPI(mpi_err,"MPI_TYPE_FREE")
     754                 :             : 
     755                 :           0 :      my_nel = my_nrows*nstates
     756                 :           0 :      call MPI_FILE_READ_ALL(mpi_fh, phi_block, my_nel, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpi_err)
     757                 :           0 :      ABI_CHECK_MPI(mpi_err,"FILE_READ")
     758                 :             : 
     759                 :             :      ! It seems that personal calls make the code stuck
     760                 :             :      ! check the fortran markers.
     761   [ #  #  #  #  :           0 :      ABI_MALLOC(bsize_frecord,(nstates))
          #  #  #  #  #  
                #  #  # ]
     762         [ #  # ]:           0 :      bsize_frecord = hexc_size * xmpi_bsize_dpc
     763                 :             :      ! ehdr_offset points to the end of the header.
     764                 :           0 :      call xmpio_check_frmarkers(mpi_fh,ehdr_offset,xmpio_collective,nstates,bsize_frecord,ierr)
     765         [ #  # ]:           0 :      ABI_CHECK(ierr==0,"Error in Fortran markers")
     766         [ #  # ]:           0 :      ABI_FREE(bsize_frecord)
     767                 :             :      !
     768                 :             :      ! Close the file.
     769                 :           0 :      call MPI_FILE_CLOSE(mpi_fh, mpi_err)
     770                 :           0 :      ABI_CHECK_MPI(mpi_err,"FILE_CLOSE")
     771                 :             : #else
     772                 :             :      ABI_ERROR("You should not be here")
     773                 :             : #endif
     774                 :             :    end if
     775                 :             : 
     776                 :           0 :    call cwtime(cputime, walltime, gflops, "stop")
     777                 :           0 :    write(msg,'(2(a,f9.1),a)')" IO operation completed. cpu_time: ",cputime,"[s], walltime: ",walltime," [s]"
     778                 :           0 :    call wrtout(std_out, msg, "COLL", do_flush=.True.)
     779                 :             :  end if
     780                 :             : 
     781                 :           1 :  return
     782                 :             : 
     783                 :             :  ! Handle IO-error
     784                 :             : 10 continue
     785                 :           0 :  ABI_ERROR(errmsg)
     786                 :             : 
     787   [ -  -  +  - ]:           1 : end subroutine exc_init_phi_block
     788                 :             : !!***
     789                 :             : 
     790                 :             : !----------------------------------------------------------------------
     791                 :             : 
     792                 :             : !!****f* m_exc_itdiago/exc_write_phi_block
     793                 :             : !! NAME
     794                 :             : !! exc_write_phi_block
     795                 :             : !!
     796                 :             : !! FUNCTION
     797                 :             : !!  Write phi_block on the Fortran file oeig_fname.
     798                 :             : !!
     799                 :             : !! SOURCE
     800                 :             : 
     801                 :           1 : subroutine exc_write_phi_block(oeig_fname,use_mpio)
     802                 :             : 
     803                 :             : !Arguments ------------------------------------
     804                 :             : !scalars
     805                 :             :  character(len=*),intent(in) :: oeig_fname
     806                 :             :  logical,intent(in) :: use_mpio
     807                 :             : 
     808                 :             : !Local variables ------------------------------
     809                 :             :  integer :: eig_unt,state,mpi_err !,fform
     810                 :             :  real(dp) :: cputime,walltime,gflops
     811                 :             :  character(len=500) :: msg,errmsg
     812                 :             : ! type(Hdr_type) :: hexc_Hdr
     813                 :             :  logical :: do_ep_lifetime
     814                 :             : !!arrays
     815                 :           1 :  complex(dp),allocatable :: buffer_dpc(:)
     816                 :             : #ifdef HAVE_MPI_IO
     817                 :             :  integer:: amode,mpi_fh,old_type,etype,eig_type,my_nel,ierr,my_nrows
     818                 :             :  integer(XMPI_OFFSET_KIND) :: ehdr_offset,my_offset,my_offpad,fmarker
     819                 :           1 :  integer(XMPI_OFFSET_KIND),allocatable :: bsize_frecord(:)
     820                 :             :  integer :: array_of_sizes(2),array_of_subsizes(2),array_of_starts(2)
     821                 :             : #endif
     822                 :             : !************************************************************************
     823                 :             : 
     824                 :           1 :  do_ep_lifetime = .FALSE.
     825                 :             : 
     826                 :           1 :  call cwtime(cputime, walltime, gflops, "start")
     827                 :             : 
     828         [ +  - ]:           1 :  if (.not.use_mpio) then
     829                 :             : 
     830                 :             :    ! * Master writes the header.
     831         [ +  - ]:           1 :    if (my_rank==master) then
     832         [ +  - ]:           1 :      call wrtout(std_out," Writing eigenstates on file "//TRIM(oeig_fname)//" via Fortran-IO","COLL")
     833         [ -  + ]:           1 :      if (open_file(oeig_fname,msg, newunit=eig_unt, form='unformatted') /= 0) then
     834                 :           0 :        ABI_ERROR(msg)
     835                 :             :      end if
     836         [ +  - ]:           1 :      write(eig_unt, err=10, iomsg=errmsg) do_ep_lifetime
     837         [ +  - ]:           1 :      write(eig_unt, err=10, iomsg=errmsg) hexc_size, nstates
     838   [ +  +  +  - ]:          11 :      write(eig_unt, err=10, iomsg=errmsg) CMPLX(exc_energy(1:nstates),kind=dp)
     839                 :             :    end if
     840                 :             : 
     841                 :             :    ! Wavefunctions are gathered on the master node band-by-band.
     842                 :             :    ! TODO bands should be treated in blocks to minimize the number of MPI calls.
     843   [ -  +  +  -  :           3 :    ABI_MALLOC_OR_DIE(buffer_dpc,(hexc_size), ierr)
          +  -  +  -  +  
          -  +  -  -  +  
             +  -  -  + ]
     844                 :             : 
     845         [ +  + ]:          11 :    do state=1,nstates
     846         [ +  + ]:        3850 :      buffer_dpc=czero
     847         [ +  + ]:        3850 :      buffer_dpc(my_t1:my_t2) = phi_block(:,state)
     848                 :          10 :      call xmpi_sum_master(buffer_dpc,master,comm,mpi_err)
     849   [ +  -  +  - ]:          11 :      if (my_rank==master) write(eig_unt, err=10, iomsg=errmsg) buffer_dpc(1:hexc_size)
     850                 :             :    end do
     851         [ -  + ]:           1 :    ABI_FREE(buffer_dpc)
     852                 :             : 
     853   [ +  -  +  - ]:           1 :    if (my_rank==master) close(eig_unt, err=10, iomsg=errmsg)
     854                 :             : 
     855                 :             :  else
     856                 :             : #ifdef HAVE_MPI_IO
     857         [ #  # ]:           0 :    call wrtout(std_out," Writing eigenstates on file "//TRIM(oeig_fname)//" with MPI-IO","COLL")
     858                 :             : 
     859                 :             :    ! Write the header.
     860         [ #  # ]:           0 :    if (my_rank==master) then
     861                 :             :      ! Write header using Fortran primitives.
     862         [ #  # ]:           0 :      if (open_file(oeig_fname,msg,newunit=eig_unt,form='unformatted') /= 0) then
     863                 :           0 :        ABI_ERROR(msg)
     864                 :             :      end if
     865         [ #  # ]:           0 :      write(eig_unt, err=10, iomsg=errmsg) nstates
     866   [ #  #  #  # ]:           0 :      write(eig_unt, err=10, iomsg=errmsg) CMPLX(exc_energy(1:nstates),kind=dp)
     867                 :             :      ! TODO: change setup_bse so that Hdr_bse reflects the parameters of the run.
     868         [ #  # ]:           0 :      close(eig_unt, err=10, iomsg=errmsg)
     869                 :             :    end if
     870                 :             : 
     871                 :           0 :    call xmpi_barrier(comm)
     872                 :             : 
     873                 :             :    ! Open the file with MPI-IO
     874                 :           0 :    amode=MPI_MODE_RDWR
     875                 :             : 
     876                 :           0 :    call MPI_FILE_OPEN(comm, oeig_fname, amode, MPI_INFO_NULL, mpi_fh, mpi_err)
     877         [ #  # ]:           0 :    msg = " MPI_IO error opening file: "//TRIM(oeig_fname)
     878                 :           0 :    ABI_CHECK_MPI(mpi_err,msg)
     879                 :             : 
     880                 :             :    ! Move the file pointer to skip the first two records.
     881                 :           0 :    ehdr_offset=0
     882                 :           0 :    call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
     883                 :             :    !write(std_out,*)"fmarker first record ",fmarker
     884                 :           0 :    call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
     885                 :             :    !write(std_out,*)"fmarker first record ",fmarker
     886                 :             :    !$call hdr_mpio_skip(mpi_fh,fform,ehdr_offset)
     887                 :             :    !$ehdr_offset = 4*xmpio_bsize_frm + xmpio_bsize_int + nstates*xmpio_bsize_dpc
     888                 :             : 
     889                 :           0 :    etype=MPI_BYTE; old_type=MPI_DOUBLE_COMPLEX
     890                 :             : 
     891                 :           0 :    my_nrows=my_t2-my_t1+1; old_type=MPI_DOUBLE_COMPLEX
     892         [ #  # ]:           0 :    array_of_sizes    = (/hexc_size,nstates/)
     893         [ #  # ]:           0 :    array_of_subsizes = (/my_nrows,nstates/)
     894         [ #  # ]:           0 :    array_of_starts   = (/my_t1,1/)
     895                 :           0 :    call xmpio_create_fsubarray_2D(array_of_sizes,array_of_subsizes,array_of_starts,old_type,eig_type,my_offpad,mpi_err)
     896                 :           0 :    ABI_CHECK_MPI(mpi_err,"fsubarray_2D")
     897                 :             :    !
     898                 :             :    ! Each node uses a different offset to skip the header and the blocks written by the other CPUs.
     899                 :           0 :    my_offset = ehdr_offset + my_offpad
     900                 :             : 
     901                 :           0 :    call MPI_FILE_SET_VIEW(mpi_fh, my_offset, etype, eig_type, 'native', MPI_INFO_NULL, mpi_err)
     902                 :           0 :    ABI_CHECK_MPI(mpi_err,"SET_VIEW")
     903                 :             : 
     904                 :           0 :    call MPI_TYPE_FREE(eig_type,mpi_err)
     905                 :           0 :    ABI_CHECK_MPI(mpi_err,"MPI_TYPE_FREE")
     906                 :             : 
     907                 :           0 :    my_nel = my_nrows*nstates
     908                 :           0 :    call MPI_FILE_WRITE_ALL(mpi_fh, phi_block, my_nel, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpi_err)
     909                 :           0 :    ABI_CHECK_MPI(mpi_err,"FILE_WRITE")
     910                 :             : 
     911                 :             :    ! It seems that personal calls make the code stuck
     912   [ #  #  #  #  :           0 :    ABI_MALLOC(bsize_frecord,(nstates))
          #  #  #  #  #  
                #  #  # ]
     913         [ #  # ]:           0 :    bsize_frecord = hexc_size * xmpi_bsize_dpc
     914                 :             :    ! ehdr_offset points to the end of the header.
     915                 :           0 :    call xmpio_write_frmarkers(mpi_fh,ehdr_offset,xmpio_collective,nstates,bsize_frecord,ierr)
     916         [ #  # ]:           0 :    ABI_CHECK(ierr==0,"Error while writing Fortran markers")
     917         [ #  # ]:           0 :    ABI_FREE(bsize_frecord)
     918                 :             :    !
     919                 :             :    ! Close the file.
     920                 :           0 :    call MPI_FILE_CLOSE(mpi_fh, mpi_err)
     921                 :           0 :    ABI_CHECK_MPI(mpi_err,"FILE_CLOSE")
     922                 :             : #else
     923                 :             :    ABI_ERROR("MPI-IO support not enabled")
     924                 :             : #endif
     925                 :             :  end if
     926                 :             : 
     927                 :           1 :  call cwtime(cputime, walltime, gflops, "stop")
     928                 :           1 :  write(msg,'(2(a,f9.1),a)')" IO operation completed. cpu_time: ",cputime,"[s], walltime: ",walltime," [s]"
     929                 :           1 :  call wrtout(std_out, msg, "COLL", do_flush=.True.)
     930                 :             : 
     931                 :           1 :  return
     932                 :             : 
     933                 :             :  ! Handle IO-error
     934                 :             : 10 continue
     935                 :           0 :  ABI_ERROR(errmsg)
     936                 :             : 
     937   [ +  -  -  - ]:           1 : end subroutine exc_write_phi_block
     938                 :             : !!***
     939                 :             : 
     940                 :             : !----------------------------------------------------------------------
     941                 :             : 
     942                 :             : !!****f* m_exc_itdiago/exc_subspace_rotation
     943                 :             : !! NAME
     944                 :             : !! exc_subspace_rotation
     945                 :             : !!
     946                 :             : !! FUNCTION
     947                 :             : !!  This routine performs the subspace rotation.
     948                 :             : !!
     949                 :             : !! SIDE EFFECTS
     950                 :             : !!   phi_block(my_t1:my_t2,nstates)=Contains the trial eigenstates.
     951                 :             : !!
     952                 :             : !! SOURCE
     953                 :             : 
     954                 :          21 : subroutine exc_subspace_rotation()
     955                 :             : 
     956                 :             : !Local variables ------------------------------
     957                 :             :  integer :: ii,jj,ipack,ierr
     958                 :             : !arrays
     959                 :          21 :  real(dp),allocatable :: sub_ene(:)
     960                 :             : ! real(dp),allocatable :: evec(:,:)
     961                 :          21 :  complex(dp),allocatable :: sub_ham(:,:),sub_pham(:),hphi_tot(:)
     962                 :             : ! complex(dp),allocatable :: phi_tmp(:,:)
     963                 :             : !************************************************************************
     964                 :             : 
     965                 :             :  ! * Sub-space rotation. Calculate <phi_i|H|phi_j> in packed form.
     966                 :             :  ! TODO: this part can be rewritten using BLAS3 routines.
     967                 :             : 
     968   [ -  +  +  -  :          63 :  ABI_MALLOC(hphi_tot,(hexc_size))
          +  -  +  -  -  
                +  -  + ]
     969   [ +  -  -  +  :          63 :  ABI_MALLOC(sub_pham,(nstates*(nstates+1)/2))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     970         [ +  + ]:        1176 :  sub_pham=czero; ipack=0
     971                 :             : 
     972         [ +  + ]:         231 :  do jj=1,nstates
     973         [ +  + ]:       80850 :    hphi_tot = czero
     974   [ +  +  +  +  :   124024530 :    hphi_tot(:) = MATMUL(hexc, phi_block(:,jj))
          +  +  +  -  +  
             -  +  -  +  
                      - ]
     975                 :         210 :    call xmpi_sum(hphi_tot,comm,ierr)
     976                 :             : 
     977         [ +  + ]:        1386 :    do ii=1,jj
     978                 :        1155 :      ipack=ipack+1
     979         [ +  + ]:      444675 :      sub_pham(ipack) = DOT_PRODUCT(phi_block(my_t1:my_t2,ii), hphi_tot(my_t1:my_t2) )
     980         [ +  + ]:        1365 :      if (ii==jj) sub_pham(ipack) = REAL(sub_pham(ipack),kind=dp)
     981                 :             :    end do
     982                 :             :  end do
     983                 :          21 :  call xmpi_sum(sub_pham,comm,ierr)
     984                 :             : 
     985   [ -  +  +  -  :          84 :  ABI_MALLOC(sub_ham,(nstates,nstates))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     986   [ +  +  +  + ]:        2331 :  sub_ham=czero
     987   [ -  +  +  -  :          63 :  ABI_MALLOC(sub_ene,(nstates))
          +  -  +  -  -  
                +  -  + ]
     988                 :             : 
     989                 :          21 :  call xhpev("Vectors","Upper",nstates,sub_pham,sub_ene,sub_ham,nstates) !,comm)
     990                 :             : 
     991         [ -  + ]:          21 :  ABI_FREE(hphi_tot)
     992         [ -  + ]:          21 :  ABI_FREE(sub_pham)
     993         [ -  + ]:          21 :  ABI_FREE(sub_ene)
     994                 :             : 
     995                 :             :  !do ii=1,nstates
     996                 :             :  ! norm = DOT_PRODUCT(sub_ham(:,ii),sub_ham(:,ii))
     997                 :             :  ! write(std_out,*)"norm subspac",norm
     998                 :             :  ! sub_ham(:,ii) = sub_ham(:,ii)/norm
     999                 :             :  !end do
    1000                 :             : 
    1001                 :             :  !allocate(evec(2*nstates,nstates))
    1002                 :             : 
    1003                 :             :  !do ii=1,nstates
    1004                 :             :  ! do jj=1,nstates
    1005                 :             :  ! evec(jj,  ii) = REAL (sub_ham(jj,ii))
    1006                 :             :  ! evec(jj+1,ii) = AIMAG(sub_ham(jj,ii))
    1007                 :             :  ! end do
    1008                 :             :  !end do
    1009                 :             : 
    1010                 :             :  !call normev(evec,nstates,nstates)
    1011                 :             : 
    1012                 :             :  !do ii=1,nstates
    1013                 :             :  ! do jj=1,nstates
    1014                 :             :  !  sub_ham(jj,ii) = CMPLX( evec(jj,ii),evec(jj+1,ii) )
    1015                 :             :  ! end do
    1016                 :             :  !end do
    1017                 :             :  !deallocate(evec)
    1018                 :             : 
    1019                 :             : #if 0
    1020                 :             :  ABI_MALLOC(phi_tmp,(my_nt,nstates))
    1021                 :             :  phi_tmp = phi_block
    1022                 :             : 
    1023                 :             :  call ZGEMM('N','N',my_nt,nstates,nstates,cone,phi_tmp,my_nt,sub_ham,nstates,czero,phi_block,my_nt)
    1024                 :             : 
    1025                 :             :  ABI_FREE(phi_tmp)
    1026                 :             : #else
    1027   [ +  -  +  -  :      161784 :  phi_block = MATMUL(phi_block,sub_ham)
          +  +  +  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  +  
          -  -  +  +  +  
                +  +  - ]
    1028                 :             : #endif
    1029                 :             : 
    1030         [ -  + ]:          21 :  ABI_FREE(sub_ham)
    1031                 :             : 
    1032                 :          21 : end subroutine exc_subspace_rotation
    1033                 :             : !!***
    1034                 :             : 
    1035                 :             : !----------------------------------------------------------------------
    1036                 :             : 
    1037                 :             : !!****f* m_exc_itdiago/exc_cholesky_ortho
    1038                 :             : !! NAME
    1039                 :             : !! exc_cholesky_ortho
    1040                 :             : !!
    1041                 :             : !! FUNCTION
    1042                 :             : !!  This routine performs the orthogonalization of the trial eigenstates using the
    1043                 :             : !!  Cholesky Algorithm.
    1044                 :             : !!
    1045                 :             : !! SIDE EFFECTS
    1046                 :             : !!   phi_block(my_t1:my_t2,nstates)=Contains the trial eigenstates.
    1047                 :             : !!
    1048                 :             : !! SOURCE
    1049                 :             : 
    1050                 :          21 : subroutine exc_cholesky_ortho()
    1051                 :             : 
    1052                 :             : !Local variables ------------------------------
    1053                 :             :  integer :: my_info,ii,jj,ipack,ierr
    1054                 :             :  logical,parameter :: use_unpacked = .False.
    1055                 :             : !arrays
    1056                 :          21 :  complex(dp),allocatable :: overlap(:,:),povlp(:)
    1057                 :             : !************************************************************************
    1058                 :             : 
    1059                 :             :  ! 1) overlap_ij =  <phi_i|phi_j>
    1060   [ -  +  +  -  :          84 :  ABI_MALLOC(overlap, (nstates,nstates))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1061                 :             : 
    1062                 :             :  if (use_unpacked) then
    1063                 :             :    overlap = czero
    1064                 :             : 
    1065                 :             :    call ZGEMM('C','N',nstates,nstates,my_nt,cone,phi_block,my_nt,phi_block,my_nt,czero,overlap,nstates)
    1066                 :             :    call xmpi_sum(overlap,comm,ierr)
    1067                 :             : 
    1068                 :             :    do ii=1,nstates
    1069                 :             :      overlap(ii,ii)=REAL(overlap(ii,ii),kind=dp)
    1070                 :             :    end do
    1071                 :             : 
    1072                 :             :    ! 2) Cholesky factorization: overlap = U^H U with U upper triangle matrix.
    1073                 :             :    call ZPOTRF('U',nstates,overlap,nstates,my_info)
    1074                 :             :    if (my_info/=0)  then
    1075                 :             :      write(msg,'(a,i3)')' ZPOTRF returned info= ',my_info
    1076                 :             :      ABI_ERROR(msg)
    1077                 :             :    end if
    1078                 :             : 
    1079                 :             :  else
    1080                 :             :    ! 1) Calculate overlap_ij =  <phi_i|phi_j> in packed form.
    1081   [ +  -  -  +  :          63 :    ABI_MALLOC(povlp,(nstates*(nstates+1)/2))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    1082         [ +  + ]:        1176 :    povlp = czero; ipack=0
    1083         [ +  + ]:         231 :    do jj=1,nstates
    1084         [ +  + ]:        1386 :      do ii=1,jj
    1085                 :        1155 :        ipack=ipack+1
    1086         [ +  + ]:      444675 :        povlp(ipack) = DOT_PRODUCT( phi_block(my_t1:my_t2,ii), phi_block(my_t1:my_t2,jj) )
    1087         [ +  + ]:        1365 :        if (ii==jj) povlp(ipack) = REAL(povlp(ipack),kind=dp)
    1088                 :             :      end do
    1089                 :             :    end do
    1090                 :          21 :    call xmpi_sum(povlp,comm,ierr)
    1091                 :             : 
    1092                 :             :    ! 2) Cholesky factorization: overlap = U^H U with U upper triangle matrix.
    1093                 :          21 :    call ZPPTRF("U",nstates,povlp,my_info)
    1094         [ -  + ]:          21 :    if (my_info/=0)  then
    1095                 :           0 :      write(msg,'(a,i3)')' ZPPTRF returned info= ',my_info
    1096                 :           0 :      ABI_ERROR(msg)
    1097                 :             :    end if
    1098                 :             :    !call xmpi_sum(povlp,comm,ierr)
    1099                 :             :    !povlp=povlp/nproc
    1100                 :             : 
    1101                 :             :    !unpack povlp to prepare call to ZTRSM.
    1102                 :          21 :    ipack=0
    1103         [ +  + ]:         231 :    do jj=1,nstates
    1104         [ +  + ]:        1386 :      do ii=1,jj
    1105                 :        1155 :        ipack=ipack+1
    1106         [ +  + ]:        1365 :        if (ii/=jj) then
    1107                 :         945 :          overlap(ii,jj)=      povlp(ipack)
    1108                 :         945 :          overlap(jj,ii)=CONJG(povlp(ipack))
    1109                 :             :        else
    1110                 :         210 :          overlap(ii,ii)=REAL(povlp(ipack),kind=dp)
    1111                 :             :        end if
    1112                 :             :      end do
    1113                 :             :    end do
    1114         [ -  + ]:          42 :    ABI_FREE(povlp)
    1115                 :             :  end if
    1116                 :             : 
    1117                 :             :  ! Check if this can be done with Scalapack. Direct PZTRSM is not provided
    1118                 :             : 
    1119                 :             :  ! 3) Solve X U = phi_block, on exit the phi_block treated by this node is orthonormalized.
    1120                 :             :  !call ZTRSM('R','U','N','N',hexc_size,nstates,cone,overlap,nstates,phi_block,hexc_size)
    1121                 :          21 :  call ZTRSM('Right','Upper','Normal','Normal',my_nt,nstates,cone,overlap,nstates,phi_block,my_nt)
    1122         [ -  + ]:          21 :  ABI_FREE(overlap)
    1123                 :             : 
    1124                 :          21 : end subroutine exc_cholesky_ortho
    1125                 :             : !!***
    1126                 :             : 
    1127                 :             : !----------------------------------------------------------------------
    1128                 :             : 
    1129                 :             : !!****f* m_exc_itdiago/convergence_degree
    1130                 :             : !! NAME
    1131                 :             : !! convergence_degree
    1132                 :             : !!
    1133                 :             : !! FUNCTION
    1134                 :             : !!  Return the degree of convergence from the input residual.
    1135                 :             : !!
    1136                 :             : !! INPUTS
    1137                 :             : !!  resid=Residual.
    1138                 :             : !!
    1139                 :             : !! OUTPUT
    1140                 :             : !!
    1141                 :             : !! SOURCE
    1142                 :             : 
    1143                 :         736 : function convergence_degree(resid)
    1144                 :             : 
    1145                 :             : !Arguments
    1146                 :             :  integer :: convergence_degree
    1147                 :             :  real(dp),intent(in) :: resid
    1148                 :             : 
    1149                 :             : !************************************************************************
    1150                 :             : 
    1151         [ +  + ]:         736 :  if (resid<tolwfr_) then
    1152                 :             :    convergence_degree = STRICT
    1153                 :             :  else
    1154                 :         713 :    convergence_degree = WORST
    1155         [ +  + ]:         713 :    if (resid<tolwfr_*10**5) convergence_degree = MEDIUM
    1156                 :             :  end if
    1157                 :             : 
    1158                 :             : end function convergence_degree
    1159                 :             : !!***
    1160                 :             : 
    1161                 :             : !----------------------------------------------------------------------
    1162                 :             : 
    1163                 :             : !!****f* m_exc_itdiago/exc_check_phi_block
    1164                 :             : !! NAME
    1165                 :             : !! exc_check_phi_block
    1166                 :             : !!
    1167                 :             : !! FUNCTION
    1168                 :             : !!  Debugging tools
    1169                 :             : !!
    1170                 :             : !! INPUTS
    1171                 :             : !!
    1172                 :             : !! OUTPUT
    1173                 :             : !!
    1174                 :             : !! SOURCE
    1175                 :             : 
    1176                 :             : subroutine exc_check_phi_block(string)
    1177                 :             : 
    1178                 :             : !Arguments ------------------------------------
    1179                 :             : !scalars
    1180                 :             :  character(len=*),intent(in) :: string
    1181                 :             : 
    1182                 :             : !Local variables ------------------------------
    1183                 :             : !scalars
    1184                 :             :  integer :: ii,jj,ierr
    1185                 :             :  real(dp) :: err,rdum
    1186                 :             : !arrays
    1187   [ -  +  -  + ]:          22 :  complex(dp),allocatable :: lbuff(:,:)
    1188                 :             : !************************************************************************
    1189                 :             : 
    1190                 :             :  if (.not. DEBUGME) return
    1191                 :             : 
    1192                 :             : #if 0
    1193                 :             :  ABI_MALLOC(lbuff,(hexc_size,nstates))
    1194                 :             :  err = -one
    1195                 :             :  do irank=1,nproc-1
    1196                 :             :    call xmpi_exch(phi_block,hexc_size*nstates,irank,lbuff,master,comm,11,ierr)
    1197                 :             :    if (my_rank==master) then
    1198                 :             :      lbuff = lbuff-phi_block
    1199                 :             :      err = MAX(err,MAXVAL(MAXVAL(ABS(lbuff),DIM=1)))
    1200                 :             :    end if
    1201                 :             :    call xmpi_barrier(comm)
    1202                 :             :  end do
    1203                 :             :  ABI_FREE(lbuff)
    1204                 :             : #else
    1205                 :             : 
    1206                 :             :  ABI_MALLOC(lbuff,(nstates,nstates))
    1207                 :             :  lbuff=czero
    1208                 :             :  do jj=1,nstates
    1209                 :             :    do ii=1,jj
    1210                 :             :      lbuff(ii,jj) = DOT_PRODUCT( phi_block(my_t1:my_t2,ii), phi_block(my_t1:my_t2,jj) )
    1211                 :             :    end do
    1212                 :             :  end do
    1213                 :             :  call xmpi_sum(lbuff,comm,ierr)
    1214                 :             : 
    1215                 :             :  err = -one
    1216                 :             :  do jj=1,nstates
    1217                 :             :    do ii=1,jj
    1218                 :             :      if (ii==jj) then
    1219                 :             :        rdum =  ABS(lbuff(ii,jj)-one)
    1220                 :             :      else
    1221                 :             :        rdum =  ABS(lbuff(ii,jj))
    1222                 :             :      end if
    1223                 :             :      err = MAX(err,rdum)
    1224                 :             :    end do
    1225                 :             :  end do
    1226                 :             :  ABI_FREE(lbuff)
    1227                 :             : #endif
    1228                 :             : 
    1229                 :             :  if (my_rank==master) then
    1230                 :             :    write(std_out,*)"After ",TRIM(string),", MAX inconsistency error in phi_block= ",err
    1231                 :             :  end if
    1232                 :             : 
    1233                 :             :  !write(std_out,*)"master casts its own data"
    1234                 :             :  !call xmpi_bcast(phi_block,master,comm,ierr)
    1235                 :             : 
    1236                 :             : end subroutine exc_check_phi_block
    1237                 :             : !!***
    1238                 :             : 
    1239                 :             : !----------------------------------------------------------------------
    1240                 :             : 
    1241                 :             : end subroutine exc_iterative_diago
    1242                 :             : !!***
    1243                 :             : 
    1244                 :             : end module m_exc_itdiago
    1245                 :             : !!***
        

Generated by: LCOV version 2.3-1