LCOV - code coverage report
Current view: top level - src/67_common - m_conducti.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.6 % 1637 1385
Test Date: 2026-11-06 01:31:13 Functions: 100.0 % 9 9
Branches: 51.4 % 3702 1902

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_conducti
       2                 :             : !! NAME
       3                 :             : !!  m_conducti
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This program computes the elements of the optical frequency dependent
       7                 :             : !! conductivity tensor and the conductivity along the three principal axes
       8                 :             : !! from the Kubo-Greenwood formula.
       9                 :             : !!
      10                 :             : !! COPYRIGHT
      11                 :             : !!  Copyright (C) 2002-2026 ABINIT group (VRecoules, PGhosh, SMazevet, SM, SVinko, NBrouwer)
      12                 :             : !!  This file is distributed under the terms of the
      13                 :             : !!  GNU General Public License, see ~abinit/COPYING
      14                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      15                 :             : !!
      16                 :             : !! SOURCE
      17                 :             : 
      18                 :             : #if defined HAVE_CONFIG_H
      19                 :             : #include "config.h"
      20                 :             : #endif
      21                 :             : 
      22                 :             : #include "abi_common.h"
      23                 :             : 
      24                 :             : ! nvtx related macro definition
      25                 :             : #include "nvtx_macros.h"
      26                 :             : 
      27                 :             : module m_conducti
      28                 :             : 
      29                 :             :  use defs_basis
      30                 :             :  use m_errors
      31                 :             :  use m_abicore
      32                 :             :  use m_xmpi
      33                 :             :  use m_wfk
      34                 :             :  use m_hdr
      35                 :             :  use m_nctk
      36                 :             :  use netcdf
      37                 :             : 
      38                 :             :  use defs_abitypes,  only : MPI_type
      39                 :             :  use m_io_tools,     only : open_file, close_unit, get_unit
      40                 :             :  use m_fstrings,     only : sjoin
      41                 :             :  use m_matrix,       only : matr3inv
      42                 :             :  use m_hide_lapack,  only : jacobi
      43                 :             :  use m_occ,          only : getnel
      44                 :             :  use m_geometry,     only : metric
      45                 :             :  use m_splines,      only : splint,spline
      46                 :             :  use m_mpinfo,       only : distrb2,init_mpi_enreg,destroy_mpi_enreg,proc_distrb_cycle,initmpi_band
      47                 :             :  use m_time,         only : timab
      48                 :             : #if defined(HAVE_GPU_MARKERS)
      49                 :             :  use m_nvtx
      50                 :             :  use m_nvtx_data
      51                 :             : #endif
      52                 :             : 
      53                 :             :  implicit none
      54                 :             : 
      55                 :             :  private
      56                 :             : !!***
      57                 :             : 
      58                 :             :  public :: conducti_paw
      59                 :             :  public :: conducti_paw_core
      60                 :             :  public :: conducti_nc
      61                 :             : 
      62                 :             : !I/O parameters
      63                 :             : !Set to true to use netcdf-MPIIO when available
      64                 :             :  logical,parameter :: use_netcdf_mpiio=.true.
      65                 :             : 
      66                 :             : !Number of (n,m) band pairs buffered before applying the Kubo-Greenwood formula
      67                 :             : !(pair data: 10 reals and 1 logical per pair, about 2.7 MB, to stay in cache)
      68                 :             :  integer,parameter :: kg_pairs_blk=32768
      69                 :             : !Same with GPU: larger buffer (about 88 MB) to limit the number of transfers and kernel launches
      70                 :             :  integer,parameter :: kg_pairs_blk_gpu=1048576
      71                 :             : !With GPU, each frequency sums over the pairs by (at most) kg_gpu_nchunk chunks of pairs,
      72                 :             : !  treated by different threads; the partial sums are added afterwards
      73                 :             :  integer,parameter :: kg_gpu_nchunk=128
      74                 :             : 
      75                 :             : !Maximum memory used to store the dipoles of a block of bands read with MPI-IO
      76                 :             :  real(dp),parameter :: dipoles_blk_mem=512._dp*1024._dp**2
      77                 :             : 
      78                 :             : !Number of bands buffered before computing the core-valence contributions
      79                 :             :  integer,parameter :: core_bands_blk=1024
      80                 :             : 
      81                 :             : !!***
      82                 :             : 
      83                 :             : contains
      84                 :             : !!***
      85                 :             : 
      86                 :             : !!****f* m_conducti/conducti_paw
      87                 :             : !! NAME
      88                 :             : !! conducti_paw
      89                 :             : !!
      90                 :             : !! FUNCTION
      91                 :             : !! This program computes the elements of the optical frequency dependent
      92                 :             : !! conductivity tensor and the conductivity along the three principal axes
      93                 :             : !! from the Kubo-Greenwood formula for PAW formalism
      94                 :             : !!
      95                 :             : !! INPUTS
      96                 :             : !!  filnam=generic name for input data
      97                 :             : !!  filnam_out=generic name for output data
      98                 :             : !!  [varocc]=if true, read arbitrary occupations from a file
      99                 :             : !!
     100                 :             : !! OUTPUT
     101                 :             : !!  Only printing
     102                 :             : !!
     103                 :             : !! NOTES
     104                 :             : !!  bantot
     105                 :             : !!  doccde(mband*nkpt_rbz*nsppol)=derivative of occ_rbz wrt the energy.
     106                 :             : !!  dom=frequency range
     107                 :             : !!  eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree).
     108                 :             : !!  eigen11(2,nkpt,mband,mband,nsppol)=first-order eigenvalues (hartree)
     109                 :             : !!  in direction x
     110                 :             : !!  eigen12(2,nkpt,mband,mband,nsppol)=first-order eigenvalues (hartree)
     111                 :             : !!  in direction y
     112                 :             : !!  eigen13(2,nkpt,mband,mband,nsppol)=first-order eigenvalues (hartree)
     113                 :             : !!  in direction z
     114                 :             : !!  ecut=kinetic energy planewave cutoff (hartree).
     115                 :             : !!  fermie= fermi energy (Hartree)
     116                 :             : !!  gmet(3,3)=reciprocal space metric ($\textrm{bohr}^{2}$).
     117                 :             : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1).
     118                 :             : !!  kin11= Onsager kinetic coeficient=optical conductivity
     119                 :             : !!  kin12= Onsager kinetic coeficient
     120                 :             : !!  kin21= Onsager kinetic coeficient
     121                 :             : !!  kin22= Onsager kinetic coeficient
     122                 :             : !!  Kth=thermal conductivity
     123                 :             : !!  mom=number of frequency for conductivity computation
     124                 :             : !!  mband=maximum number of bands.
     125                 :             : !!  natom = number of atoms in the unit cell.
     126                 :             : !!  nband(nkpt*nsppol)=number of bands at each RF k point for each spin.
     127                 :             : !!  nkpt=number of k points in the IBZ for this perturbation
     128                 :             : !!  ngfft(3)=integer fft box dimensions.
     129                 :             : !!  nspinor=number of spinorial components of the wavefunctions.
     130                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized.
     131                 :             : !!  ntypat = number of atom types.
     132                 :             : !!  occ(mband*nkpt*nsppol)=occupation number for each band and k.
     133                 :             : !!  occopt==option for occupancies
     134                 :             : !!  rmet(3,3)=real space metric ($\textrm{bohr}^{2}$).sigx(mom,nphicor))
     135                 :             : !!  rprimd(3,3)=real space primitive translations.
     136                 :             : !!  of primitive translations.
     137                 :             : !!  Sth=thermopower
     138                 :             : !!  tsmear=smearing width (or temperature) in Hartree
     139                 :             : !!  ucvol=unit cell volume in ($\textrm{bohr}^{3}$).
     140                 :             : !!  wind=frequency windows for computations of sigma
     141                 :             : !!  wtk(nkpt)=weight assigned to each k point.
     142                 :             : !!  znucl(natom)=atomic number of atoms
     143                 :             : !!  np_sum=noziere-pines sumrule
     144                 :             : !!
     145                 :             : !! SOURCE
     146                 :             : 
     147                 :          14 :  subroutine conducti_paw(filnam,filnam_out,varocc,use_gpu)
     148                 :             : 
     149                 :             : !Arguments -----------------------------------
     150                 :             : !scalars
     151                 :             :  character(len=fnlen),intent(in) :: filnam,filnam_out
     152                 :             :  integer, optional, intent(in) :: varocc
     153                 :             :  logical, optional, intent(in) :: use_gpu
     154                 :             : 
     155                 :             : !Local variables-------------------------------
     156                 :             : !scalars
     157                 :             :  integer,parameter :: master=0
     158                 :             :  integer :: bsize,bd_stride,dimid,iomode,bantot,bdtot_index,ncid,varid,nb_per_proc,etiq
     159                 :             :  integer :: comm,fform1,headform,iband,ijband,ierr,ikpt,master_band,idum,ib0,ib1,ij0,ij_stride
     160                 :             :  integer :: my_ncalls,ncalls_max,nb_blk
     161                 :             :  integer :: iom,isppol,jband,l1,l2,mband,me,mpierr,mom
     162                 :             :  integer :: natom,nband_k,nkpt,nproc,nspinor,nsppol,ntypat,broad_mode
     163                 :             :  integer :: occopt,iunt,opt_unt,occ_unt,iocc,pnp_size,add_drude,npairs,npairs_max,ipair,nkeep,nruns
     164                 :             :  integer :: lij_unt,sig_unt,sigd_unt,kth_unt,ocond_unt,occunit,occnpt,au_units
     165                 :             :  logical :: nc_unlimited,mykpt,myband,iomode_estf_mpiio,read_half_dipoles,omega0
     166                 :             :  logical :: my_use_gpu,run_sorted_k
     167                 :          14 :  logical,allocatable :: band_keep(:),pair_drude(:),run_sorted(:)
     168                 :             :  real(dp) :: del,deltae,deltae_min,deltae_min_tmp,dhdk2_g,diff_eig,diff_occ
     169                 :             :  real(dp) :: dosdeltae,ecut,entropy,fermie,fermih,kin_fact,maxocc,docc_deig
     170                 :             :  real(dp) :: np_sum,np_sum_k1,np_sum_2,omin,omax,dom,oml,socc,socc_k,fact_omega0,pair_coef
     171                 :             :  real(dp) :: Tatm,tphysel,tsmear,ucvol,eig_in_max,eig_in_min,phi
     172                 :             :  character(len=fnlen) :: filnam1,filnam_gen,occfile
     173                 :             :  character(len=500) :: msg
     174                 :             :  character(len=100) :: line
     175                 :          14 :  type(hdr_type) :: hdr
     176                 :          14 :  type(MPI_type) :: mpi_enreg
     177                 :             : !arrays
     178                 :             :  integer :: nc_count_5(5),nc_count_6(6),nc_start_5(5),nc_start_6(6),nc_stride_5(5),nc_stride_6(6)
     179                 :             :  integer :: dummy(0,0,0)
     180                 :          14 :  integer,allocatable :: nband(:),run_start(:)
     181                 :             :  real(dp) :: dhdk2_r(3,3),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3),tsec(2)
     182                 :          14 :  real(dp),allocatable :: cond_nd(:,:,:),cond_nd_k(:,:,:)
     183                 :          14 :  real(dp),allocatable :: doccde(:),doccde_k(:),eig0_k(:),eigen0(:),eig0nc(:,:,:)
     184                 :          14 :  real(dp),allocatable :: occ(:),occ_k(:),wtk(:),oml1(:),occ_in(:),eig_in(:),occ_tmp(:),ypp(:)
     185                 :          14 :  real(dp),allocatable :: kin11(:,:),kin12(:),kin21(:),kin22(:)
     186                 :          14 :  real(dp),allocatable :: kin11_k(:),kin12_k(:),kin21_k(:),kin22_k(:),Kth(:),Stp(:)
     187                 :          14 :  real(dp),allocatable :: psinablapsi(:,:,:),sig_abs(:),pair_ade(:),pair_wgt(:,:),band_np(:)
     188                 :             : 
     189                 :             : ! *********************************************************************************
     190                 :             : 
     191                 :          14 :  call timab(1186,1,tsec)
     192                 :             :  ABI_NVTX_START_RANGE(NVTX_CONDUCTI_PAW)
     193                 :             : 
     194         [ +  - ]:          14 :  my_use_gpu=.false.; if (present(use_gpu)) my_use_gpu=use_gpu
     195                 :             : 
     196                 :             : #if defined(HAVE_GPU_MARKERS)
     197                 :             :  call nvtxStartRange("read_input")
     198                 :             : #endif
     199                 :             : ! ---------------------------------------------------------------------------------
     200                 :             : ! Read input data
     201                 :             : 
     202                 :             : !Global MPI communicator
     203                 :          14 :  comm = xmpi_world
     204                 :          14 :  nproc = xmpi_comm_size(comm)
     205                 :          14 :  me = xmpi_comm_rank(comm)
     206                 :             : 
     207                 :             : !Read input parameters file
     208         [ +  + ]:          14 :  if (me==master) then
     209         [ -  + ]:           8 :    if (open_file(filnam,msg,newunit=iunt,form='formatted',action="read",status="old")/=0) then
     210                 :           0 :      ABI_ERROR(msg)
     211                 :             :    end if
     212                 :           8 :    rewind(iunt)
     213                 :           8 :    read(iunt,*)
     214                 :           8 :    read(iunt,'(a)') filnam_gen ! Generic name for the files
     215         [ +  - ]:           8 :    filnam1=trim(filnam_gen)//'_OPT'
     216                 :             : !  Read frequency range
     217                 :           8 :    read(iunt,*) dom,omin,omax,mom
     218         [ +  - ]:           8 :    read(iunt,end=13,fmt='(a)') line
     219         [ +  + ]:           8 :    read(line,end=11,fmt=*) broad_mode,au_units,phi,add_drude
     220                 :           1 :    goto 14
     221         [ -  + ]:           7 : 11 read(line,end=13,fmt=*) broad_mode,au_units
     222                 :           0 :    phi=zero; add_drude=0
     223                 :           0 :    goto 14
     224                 :           7 : 13 broad_mode=1 ; au_units=0; phi=zero; add_drude=0
     225                 :             : 14 continue
     226                 :             : !  In case of varocc read filename of occupation datafile
     227         [ -  + ]:           8 :    if (present(varocc)) then
     228         [ #  # ]:           0 :      if (me==master) then
     229                 :           0 :        write(std_out,*) 'Warning, this undocumented feature is highly experimental'
     230                 :           0 :        write(std_out,*) 'and of limited physical validity, proceed with extreme caution!!!'
     231                 :             :      end if
     232                 :           0 :      read(iunt,*) occfile !filename of the non-eq distribution function
     233                 :             :    end if
     234                 :           8 :    close(iunt)
     235                 :             :  end if
     236                 :          14 :  phi=phi*pi/180.0_dp
     237                 :             : 
     238                 :             : !Send data to all procs
     239                 :          14 :  call xmpi_bcast(dom,master,comm,mpierr)
     240                 :          14 :  call xmpi_bcast(omin,master,comm,mpierr)
     241                 :          14 :  call xmpi_bcast(omax,master,comm,mpierr)
     242                 :          14 :  call xmpi_bcast(mom,master,comm,mpierr)
     243                 :          14 :  call xmpi_bcast(broad_mode,master,comm,mpierr)
     244                 :          14 :  call xmpi_bcast(au_units,master,comm,mpierr)
     245                 :          14 :  call xmpi_bcast(phi,master,comm,mpierr)
     246                 :          14 :  call xmpi_bcast(add_drude,master,comm,mpierr)
     247                 :             : 
     248                 :             : 
     249                 :             : ! ---------------------------------------------------------------------------------
     250                 :             : ! Read OPT file
     251                 :             : 
     252                 :             : !Check for FORTRAN/.nc OPT file and set iomode to IO_MODE_FORTRAN_MASTER/IO_MODE_ETSF
     253         [ +  + ]:          14 :  if (me==master) then
     254                 :           8 :    call nctk_fort_or_ncfile(filnam1,iomode,msg)
     255         [ -  + ]:           8 :    if (iomode/=IO_MODE_ETSF) iomode=IO_MODE_FORTRAN_MASTER
     256                 :             :  end if
     257                 :          14 :  call xmpi_bcast(filnam1,master,comm,mpierr)
     258                 :          14 :  call xmpi_bcast(iomode,master,comm,mpierr)
     259                 :             : 
     260                 :             :  !Open OPT file and read HEADER
     261         [ +  + ]:          14 :  if (me==master) then
     262         [ +  - ]:           8 :    if (iomode==IO_MODE_ETSF) then
     263         [ -  + ]:           8 :      NCF_CHECK(nctk_open_read(ncid,filnam1,xmpi_comm_self))
     264                 :           8 :      call hdr%ncread(ncid,fform1)
     265                 :             :    else
     266         [ #  # ]:           0 :      if (open_file(filnam1,msg,newunit=opt_unt,form="unformatted",status="old")/=0) then
     267                 :           0 :        ABI_ERROR(msg)
     268                 :             :      end if
     269                 :           0 :      call hdr%fort_read(opt_unt,fform1,rewind=.true.)
     270                 :             :    end if
     271         [ -  + ]:           8 :    ABI_CHECK(fform1/=0,sjoin("Error while reading ",filnam1))
     272         [ -  + ]:           8 :    ABI_CHECK(fform1==610.or.fform1==620,"Conducti requires an OPT file with fform=610 or 620!")
     273                 :             :  end if
     274                 :          14 :  call hdr%bcast(master,me,comm)
     275                 :          14 :  call xmpi_bcast(fform1,master,comm,mpierr)
     276                 :             : 
     277                 :             : !Extract info from the header
     278                 :          14 :  headform=hdr%headform
     279                 :          14 :  bantot=hdr%bantot
     280                 :          14 :  ecut=hdr%ecut_eff
     281                 :          14 :  natom=hdr%natom
     282                 :          14 :  nkpt=hdr%nkpt
     283                 :          14 :  nspinor=hdr%nspinor
     284                 :          14 :  nsppol=hdr%nsppol
     285                 :          14 :  ntypat=hdr%ntypat
     286                 :          14 :  occopt=hdr%occopt
     287   [ +  +  +  + ]:         182 :  rprimd(:,:)=hdr%rprimd(:,:)
     288                 :          14 :  fermie=hdr%fermie
     289                 :          14 :  tsmear=hdr%tsmear
     290   [ -  +  +  -  :          42 :  ABI_MALLOC(nband,(nkpt*nsppol))
          +  -  +  -  -  
                +  -  + ]
     291   [ -  +  +  -  :          42 :  ABI_MALLOC(occ,(bantot))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     292   [ -  +  +  -  :          42 :  ABI_MALLOC(wtk,(nkpt))
          +  -  +  -  -  
                +  -  + ]
     293         [ +  + ]:          30 :  nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol)
     294         [ +  + ]:         248 :  occ(1:bantot)=hdr%occ(1:bantot)
     295         [ +  + ]:          30 :  wtk(1:nkpt)=hdr%wtk(1:nkpt)
     296         [ +  + ]:          30 :  mband=maxval(nband(:))  ! Get mband, as the maximum value of nband(nkpt)
     297                 :          14 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) ! Get metrics of simulation cell
     298                 :             : 
     299                 :             : !Read eigenvalues
     300   [ -  +  +  -  :          42 :  ABI_MALLOC(eigen0,(mband*nkpt*nsppol))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     301         [ +  + ]:          14 :  if (me==master) then
     302         [ +  - ]:           8 :    if (iomode==IO_MODE_ETSF) then
     303                 :           8 :      varid=nctk_idname(ncid,"eigenvalues")
     304   [ -  +  +  -  :          40 :      ABI_MALLOC(eig0nc,(mband,nkpt,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     305         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,eig0nc))
     306   [ +  +  +  -  :          16 :      eigen0 = reshape(eig0nc,[mband*nkpt*nsppol])
                   +  - ]
     307         [ -  + ]:           8 :      ABI_FREE(eig0nc)
     308                 :             :      !Close file here because the rest will possibly be read with collective I/O
     309         [ -  + ]:           8 :      NCF_CHECK(nf90_close(ncid))
     310                 :             :    else
     311                 :           0 :      read(opt_unt)(eigen0(iband),iband=1,mband*nkpt*nsppol)
     312                 :             :    end if
     313                 :             :  end if
     314                 :          14 :  call xmpi_bcast(eigen0,master,comm,mpierr)
     315                 :             : 
     316                 :             : !In case of varocc, use arbitrary occupations
     317                 :             : !Read occfile and overwrite occ by interpolating the data in the input file
     318         [ -  + ]:          14 :  if (present(varocc)) then
     319         [ #  # ]:           0 :    if (me==master) then
     320   [ #  #  #  #  :           0 :      ABI_MALLOC(occ_tmp,(bantot))
             #  #  #  # ]
     321         [ #  # ]:           0 :      if (open_file(occfile,msg,newunit=occ_unt,form='formatted')/=0) then
     322                 :           0 :        ABI_ERROR(msg)
     323                 :             :      end if
     324                 :             : !    Get units used in occfile (1=Ha, 2= eV)
     325                 :           0 :      read(occ_unt,*) occunit
     326                 :           0 :      read(occ_unt,*) occnpt
     327   [ #  #  #  #  :           0 :      ABI_MALLOC(occ_in,(occnpt))
          #  #  #  #  #  
                #  #  # ]
     328   [ #  #  #  #  :           0 :      ABI_MALLOC(eig_in,(occnpt))
             #  #  #  # ]
     329         [ #  # ]:           0 :      do iocc=1,occnpt
     330                 :           0 :        read(occ_unt,*) eig_in(iocc),occ_in(iocc)
     331         [ #  # ]:           0 :        if (occunit==2) then !Convert units from eV to Hartree
     332                 :           0 :          eig_in(iocc)=eig_in(iocc)/Ha_eV
     333                 :             :          occ_in(iocc)=occ_in(iocc)
     334                 :             :        end if
     335                 :             :      end do
     336                 :           0 :      close(occ_unt)
     337                 :             : !    Interpolation
     338   [ #  #  #  #  :           0 :      ABI_MALLOC(ypp,(occnpt))
          #  #  #  #  #  
                #  #  # ]
     339                 :           0 :      call spline(eig_in,occ_in,occnpt,zero,zero,ypp)
     340                 :             : !    Interpolate neccessary values
     341   [ #  #  #  #  :           0 :      eig_in_max=maxval(eig_in)
             #  #  #  # ]
     342   [ #  #  #  #  :           0 :      eig_in_min=minval(eig_in)
             #  #  #  # ]
     343         [ #  # ]:           0 :      do iocc=1,bantot
     344                 :             : !      Check for Extrapolation and set them to physically sound values
     345         [ #  # ]:           0 :        if (eigen0(iocc)<eig_in_min) then
     346                 :           0 :          occ_tmp(iocc)=one
     347         [ #  # ]:           0 :        else if (eigen0(iocc)>eig_in_max) then
     348                 :           0 :          occ_tmp(iocc)=zero
     349                 :             :        else
     350                 :           0 :          call splint(occnpt,eig_in,occ_in,ypp,1,eigen0(iocc),occ_tmp(iocc),ierr)
     351                 :             :        end if
     352                 :             :      end do
     353   [ #  #  #  #  :           0 :      occ=occ_tmp
             #  #  #  # ]
     354                 :             : !    Clean up
     355         [ #  # ]:           0 :      ABI_FREE(ypp)
     356         [ #  # ]:           0 :      ABI_FREE(occ_tmp)
     357         [ #  # ]:           0 :      ABI_FREE(occ_in)
     358         [ #  # ]:           0 :      ABI_FREE(eig_in)
     359                 :             :    end if
     360                 :           0 :    call xmpi_bcast(occ,master,comm,mpierr)
     361                 :           0 :    occopt=2
     362                 :             :  end if ! varocc?
     363                 :             : 
     364                 :             : #if defined(HAVE_GPU_MARKERS)
     365                 :             :  call nvtxEndRange()
     366                 :             : #endif
     367                 :             : #if defined(HAVE_GPU_MARKERS)
     368                 :             :  call nvtxStartRange("pre_spinkpt_loop")
     369                 :             : #endif
     370                 :             : !---------------------------------------------------------------------------------
     371                 :             : ! Prepare kpt/band parallelization
     372                 :             : 
     373                 :          14 :  call init_mpi_enreg(mpi_enreg)
     374                 :          14 :  mpi_enreg%comm_kpt=comm
     375                 :          14 :  mpi_enreg%me_kpt=me
     376                 :          14 :  mpi_enreg%nproc_spkpt=nproc
     377                 :          14 :  mpi_enreg%paralbd=1
     378   [ -  +  +  -  :          70 :  ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt,mband,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     379   [ -  +  +  -  :          42 :  ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     380                 :          14 :  call distrb2(mband,nb_per_proc,nband,nkpt,nproc,nsppol,mpi_enreg)
     381                 :          14 :  call initmpi_band(nkpt,mpi_enreg,nband,nkpt,nsppol)
     382                 :             : 
     383                 :             : !---------------------------------------------------------------------------------
     384                 :             : !Print some data
     385                 :             : 
     386                 :          14 :  Tatm=tsmear*Ha_K
     387         [ +  + ]:          14 :  if (me==master) then
     388                 :           8 :    write(std_out,*)
     389                 :           8 :    write(std_out,'(a)' )' Input data:'
     390                 :           8 :    write(std_out,'(a,i8,3f10.5,a)')' npts,omin,omax,width      =',mom,omin,omax,dom,' Ha'
     391                 :           8 :    write(std_out,*)
     392                 :           8 :    write(std_out,'(a,3f10.5,a)' )' rprimd(bohr)      =',rprimd(1:3,1)
     393                 :           8 :    write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,2)
     394                 :           8 :    write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,3)
     395                 :           8 :    write(std_out,'(a,i8)')       ' natom             =',natom
     396                 :           8 :    write(std_out,'(a,3i8)')      ' nkpt,mband,nsppol        =',nkpt,mband,nsppol
     397                 :           8 :    write(std_out, '(a, f10.5,a)' ) ' ecut              =',ecut,' Ha'
     398                 :           8 :    write(std_out,'(a,f10.5,a,f10.5,a)' )' fermie            =',fermie,' Ha',fermie*Ha_eV,' eV'
     399                 :           8 :    write(std_out,'(a,f12.5,a,f12.5,a)') ' Temp              =',tsmear,' Ha ',Tatm,' Kelvin'
     400                 :             :  end if
     401                 :             : 
     402                 :             : ! ---------------------------------------------------------------------------------
     403                 :             : ! Compute derivative of occupations wrt the energy
     404                 :             : 
     405   [ -  +  +  -  :          42 :  ABI_MALLOC(doccde,(mband*nkpt*nsppol))
          +  -  +  -  -  
                +  -  + ]
     406         [ -  + ]:          14 :  if (occopt<=2) then
     407         [ #  # ]:           0 :    if (me==master) then
     408                 :           0 :      write(std_out,'(a,i4)')  ' occopt            =',occopt
     409                 :             :    end if
     410         [ #  # ]:           0 :    doccde=zero
     411                 :             :  else
     412                 :          14 :    tphysel=zero
     413                 :          14 :    maxocc=two/(nsppol*nspinor)
     414                 :             :    call getnel(doccde,dosdeltae,eigen0,entropy,fermie,fermih,maxocc,mband,nband,&
     415                 :          14 : &   socc,nkpt,nsppol,occ,occopt,1,tphysel,tsmear,12,wtk)
     416                 :          14 :    entropy=tsmear*entropy
     417         [ +  + ]:          14 :    if (me==master) then
     418                 :           8 :      write(std_out, '(a,es22.12)') ' tsmear*entropy (Ha)           =',entropy
     419                 :             :    end if
     420                 :          14 :    entropy=entropy/socc
     421         [ +  + ]:          14 :    if (me==master) then
     422                 :           8 :      write(std_out, '(a,es22.12)') ' tsmear*entropy (Ha/e)         =',entropy
     423                 :             :    end if
     424                 :             :  endif
     425                 :             : 
     426                 :             : !---------------------------------------------------------------------------------
     427                 :             : ! Determine the frequency range and allocate frequency-dependent arrays
     428                 :             : 
     429                 :          14 :  del=(omax-omin)/(mom-1)
     430   [ -  +  +  -  :          42 :  ABI_MALLOC(oml1,(mom))
          +  -  +  -  -  
                +  -  + ]
     431         [ +  + ]:       14014 :  do iom=1,mom
     432                 :       14014 :    oml1(iom)=omin+dble(iom-1)*del
     433                 :             :  end do
     434                 :             : 
     435   [ -  +  +  -  :          56 :  ABI_MALLOC(kin11,(mom,nsppol))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     436   [ -  +  +  -  :          28 :  ABI_MALLOC(kin12,(mom))
          -  +  -  +  -  
                      + ]
     437   [ -  +  +  -  :          28 :  ABI_MALLOC(kin21,(mom))
          -  +  -  +  -  
                      + ]
     438   [ -  +  +  -  :          28 :  ABI_MALLOC(kin22,(mom))
          -  +  -  +  -  
                      + ]
     439   [ -  +  +  -  :          42 :  ABI_MALLOC(cond_nd,(3,3,mom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     440   [ -  +  +  -  :          28 :  ABI_MALLOC(sig_abs,(mom))
             -  +  -  + ]
     441   [ -  +  +  -  :          28 :  ABI_MALLOC(Kth,(mom))
             -  +  -  + ]
     442   [ -  +  +  -  :          28 :  ABI_MALLOC(Stp,(mom))
             -  +  -  + ]
     443   [ +  +  +  + ]:       14028 :  kin11   = zero
     444         [ +  + ]:       14014 :  kin12   = zero
     445         [ +  + ]:       14014 :  kin21   = zero
     446         [ +  + ]:       14014 :  kin22   = zero
     447   [ +  +  +  +  :      182014 :  cond_nd = zero
                   +  + ]
     448         [ +  + ]:       14014 :  sig_abs = zero
     449         [ +  + ]:       14014 :  Kth     = zero
     450         [ +  + ]:       14014 :  Stp     = zero
     451                 :             : 
     452                 :             : #if defined(HAVE_GPU_MARKERS)
     453                 :             :  call nvtxStartRange("prepare_netcdf")
     454                 :             : #endif
     455                 :             : !---------------------------------------------------------------------------------
     456                 :             : !Prepare valence-valence dipoles reading
     457                 :             : 
     458   [ +  -  -  + ]:          14 :  iomode_estf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio)
     459                 :             : 
     460                 :             :  !In case of netCDF access to OPT file, prepare collective I/O
     461         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
     462         [ +  - ]:          14 :    if (iomode_estf_mpiio) then
     463         [ -  + ]:          14 :      NCF_CHECK(nctk_open_read(ncid,filnam1,comm))
     464                 :          14 :      varid=nctk_idname(ncid,"dipole_valence_valence")
     465                 :          14 :      nc_unlimited=(nf90_inq_dimid(ncid,"unlimited_bands",dimid)==NF90_NOERR)
     466                 :          14 :      read_half_dipoles=(nf90_inq_dimid(ncid,"max_number_of_state_pairs",dimid)==NF90_NOERR)
     467                 :             :      !Dipoles are read by blocks of (at most nb_blk) contiguous bands of the current proc
     468                 :             :      !  (nb_per_proc is the max number of bands of a k-point treated by a proc)
     469                 :          14 :      nb_blk=int(dipoles_blk_mem/(48._dp*real(mband,dp)))
     470                 :          14 :      nb_blk=max(1,min(nb_blk,nb_per_proc,mband))
     471         [ +  + ]:          14 :      if (nproc>1) then
     472         [ -  + ]:           8 :        NCF_CHECK(nctk_set_collective(ncid,varid))
     473                 :             :        !Count the reads of current proc, to complete them with dummy collective reads
     474                 :           8 :        my_ncalls=count_band_blocks(mpi_enreg%proc_distrb,nband,nkpt,nsppol,me,nb_blk)
     475                 :           8 :        call xmpi_max(my_ncalls,ncalls_max,comm,ierr)
     476                 :             :      end if
     477                 :             :    else
     478         [ #  # ]:           0 :      if (me==master) then
     479         [ #  # ]:           0 :        NCF_CHECK(nctk_open_read(ncid,filnam1,xmpi_comm_self))
     480                 :           0 :        varid=nctk_idname(ncid,"dipole_valence_valence")
     481                 :             :        !if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then
     482                 :             :        !  NCF_CHECK(nctk_set_collective(ncid,varid))
     483                 :             :        !end if
     484                 :           0 :        nc_unlimited=(nf90_inq_dimid(ncid,"unlimited_bands",dimid)==NF90_NOERR)
     485                 :           0 :        read_half_dipoles=(nf90_inq_dimid(ncid,"max_number_of_state_pairs",dimid)==NF90_NOERR)
     486                 :             :      end if
     487                 :           0 :      call xmpi_bcast(nc_unlimited,master,comm,ierr)
     488                 :           0 :      call xmpi_bcast(read_half_dipoles,master,comm,ierr)
     489                 :             :    end if
     490   [ -  +  -  - ]:          14 :    if (nc_unlimited.and.read_half_dipoles) then
     491                 :           0 :      msg="The OPT file has a wrong format!"
     492                 :           0 :      ABI_BUG(msg)
     493                 :             :    end if
     494                 :             :  else
     495                 :           0 :    read_half_dipoles=(fform1==620)
     496                 :             :  end if
     497                 :             : 
     498         [ +  - ]:          14 :  if (iomode_estf_mpiio) then
     499                 :             :    !If MPI-IO, store only the elements of a block of nb_blk bands
     500   [ -  +  +  -  :          42 :    ABI_MALLOC(psinablapsi,(2,3,nb_blk*mband))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     501                 :             :  else
     502                 :             :    !If not, store all pairs (or half)
     503         [ #  # ]:           0 :    if (read_half_dipoles) then ! only ib>=jb
     504   [ #  #  #  #  :           0 :      ABI_MALLOC(psinablapsi,(2,3,(mband*(mband+1))/2))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     505                 :             :    else
     506   [ #  #  #  #  :           0 :      ABI_MALLOC(psinablapsi,(2,3,mband*mband))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     507                 :             :    end if
     508                 :             :  end if
     509         [ +  + ]:          56 :  pnp_size=size(psinablapsi)
     510                 :             : 
     511                 :             : #if defined(HAVE_GPU_MARKERS)
     512                 :             :  call nvtxEndRange()
     513                 :             : #endif
     514                 :             : !---------------------------------------------------------------------------------
     515                 :             : ! Compute conductivity
     516                 :             : 
     517   [ -  +  +  -  :          42 :  ABI_MALLOC(kin11_k,(mom))
          +  -  +  -  -  
                +  -  + ]
     518   [ -  +  +  -  :          28 :  ABI_MALLOC(kin12_k,(mom))
             -  +  -  + ]
     519   [ -  +  +  -  :          28 :  ABI_MALLOC(kin21_k,(mom))
             -  +  -  + ]
     520   [ -  +  +  -  :          28 :  ABI_MALLOC(kin22_k,(mom))
             -  +  -  + ]
     521   [ -  +  +  -  :          42 :  ABI_MALLOC(cond_nd_k,(3,3,mom))
          +  -  +  -  -  
                +  -  + ]
     522                 :             : 
     523                 :             : !Buffer of (n,m) band pairs: |e_n-e_m|, Drude flag and weights
     524                 :             : !  (KG formula is applied to the buffer when full, see conducti_paw_kg_sum)
     525         [ +  - ]:          14 :  npairs_max=max(merge(kg_pairs_blk_gpu,kg_pairs_blk,my_use_gpu),mband)
     526   [ -  +  +  -  :          42 :  ABI_MALLOC(pair_ade,(npairs_max))
          +  -  -  +  -  
                +  -  + ]
     527   [ -  +  +  -  :          42 :  ABI_MALLOC(pair_drude,(npairs_max))
          +  -  -  +  -  
                +  -  + ]
     528   [ -  +  +  -  :          42 :  ABI_MALLOC(pair_wgt,(9,npairs_max))
          +  -  -  +  -  
                +  -  + ]
     529                 :             : !Contributions to the sum rule and flags of the (n,m) pairs of band n
     530   [ -  +  +  -  :          42 :  ABI_MALLOC(band_np,(mband))
          +  -  +  -  -  
                +  -  + ]
     531   [ -  +  +  -  :          42 :  ABI_MALLOC(band_keep,(mband))
          +  -  +  -  -  
                +  -  + ]
     532                 :             : !The buffer is made of runs: the pairs (n,m) of a band n, in the order of m.
     533                 :             : !  As eigenvalues are sorted, |e_n-e_m| decreases along a run (checked in run_sorted)
     534   [ +  -  -  +  :          42 :  ABI_MALLOC(run_start,(mband+1))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     535   [ -  +  +  -  :          28 :  ABI_MALLOC(run_sorted,(mband))
             -  +  -  + ]
     536                 :             : 
     537                 :          14 :  np_sum  = zero
     538                 :          14 :  socc    = zero
     539                 :          14 :  deltae  = zero
     540                 :          14 :  deltae_min = 1.d99
     541                 :             : 
     542                 :             : #if defined(HAVE_GPU_MARKERS)
     543                 :             :  call nvtxEndRange()
     544                 :             : #endif
     545                 :             : !LOOP OVER SPINS/K
     546                 :          14 :  bdtot_index = 0
     547         [ +  + ]:          28 :  do isppol=1,nsppol
     548         [ +  + ]:          44 :    do ikpt=1,nkpt
     549                 :             : #if defined(HAVE_GPU_MARKERS)
     550                 :             :      call nvtxStartRange("k-point step")
     551                 :             : #endif
     552                 :          16 :      etiq=ikpt+(isppol-1)*nkpt
     553                 :          16 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
     554                 :          16 :      mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me))
     555         [ +  + ]:         250 :      master_band=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol))
     556                 :             : 
     557                 :             : #if defined(HAVE_GPU_MARKERS)
     558                 :             :      call nvtxStartRange("read_dipoles")
     559                 :             : #endif
     560                 :             : !    In case of non MPI-IO, has to read all (n,m) dipoles for this k-point
     561                 :             : !      Master node reads and send to relevant processor
     562   [ -  +  -  - ]:          16 :      if (.not.iomode_estf_mpiio.and.me==master) then
     563         [ #  # ]:           0 :        if (iomode==IO_MODE_ETSF) then
     564   [ #  #  #  #  :           0 :          psinablapsi=zero
                   #  # ]
     565         [ #  # ]:           0 :          if (nc_unlimited) then
     566   [ #  #  #  # ]:           0 :            nc_start_6=[1,1,1,ikpt,isppol,1] ; nc_count_6=[2,3,mband,1,1,mband] ; nc_stride_6=[1,1,1,1,1,1]
     567         [ #  # ]:           0 :            NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     568         [ #  # ]:           0 :          else if (.not.read_half_dipoles) then
     569   [ #  #  #  # ]:           0 :            nc_start_6=[1,1,1,1,ikpt,isppol] ; nc_count_6=[2,3,mband,mband,1,1] ; nc_stride_6=[1,1,1,1,1,1]
     570         [ #  # ]:           0 :            NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     571                 :             :          else
     572   [ #  #  #  # ]:           0 :            nc_start_5=[1,1,1,ikpt,isppol] ; nc_count_5=[2,3,(mband*(mband+1))/2,1,1] ; nc_stride_5=[1,1,1,1,1]
     573         [ #  # ]:           0 :            NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     574                 :             :          end if
     575                 :             :        else
     576   [ #  #  #  #  :           0 :          psinablapsi=zero
                   #  # ]
     577         [ #  # ]:           0 :          bsize=nband_k**2;if (read_half_dipoles) bsize=(nband_k*(nband_k+1))/2
     578   [ #  #  #  # ]:           0 :          read(opt_unt)(psinablapsi(1:2,1,ijband),ijband=1,bsize)
     579   [ #  #  #  # ]:           0 :          read(opt_unt)(psinablapsi(1:2,2,ijband),ijband=1,bsize)
     580   [ #  #  #  # ]:           0 :          read(opt_unt)(psinablapsi(1:2,3,ijband),ijband=1,bsize)
     581                 :             :        end if
     582         [ #  # ]:           0 :        if (.not.mykpt) then
     583                 :           0 :          call xmpi_exch(psinablapsi,pnp_size,master,psinablapsi,master_band,comm,etiq,ierr)
     584                 :             :        end if
     585                 :             :      end if
     586                 :             : #if defined(HAVE_GPU_MARKERS)
     587                 :             :      call nvtxEndRange()
     588                 :             : #endif
     589                 :             : 
     590                 :             : !    Select k-points for current proc
     591         [ +  + ]:          16 :      if (mykpt) then
     592                 :             : 
     593   [ -  +  +  -  :          42 :        ABI_MALLOC(eig0_k,(nband_k))
          +  -  +  -  -  
                +  -  + ]
     594   [ -  +  +  -  :          28 :        ABI_MALLOC(occ_k,(nband_k))
             -  +  -  + ]
     595   [ -  +  +  -  :          28 :        ABI_MALLOC(doccde_k,(nband_k))
             -  +  -  + ]
     596                 :             : 
     597   [ +  +  +  +  :      182014 :        cond_nd_k = zero
                   +  + ]
     598         [ +  + ]:       14014 :        kin11_k   = zero
     599         [ +  + ]:       14014 :        kin12_k   = zero
     600         [ +  + ]:       14014 :        kin21_k   = zero
     601         [ +  + ]:       14014 :        kin22_k   = zero
     602                 :          14 :        np_sum_k1 = zero
     603                 :          14 :        socc_k    = zero
     604                 :          14 :        npairs    = 0
     605                 :          14 :        nruns     = 0
     606                 :          14 :        ib0       = 1
     607                 :          14 :        ib1       = 0
     608                 :             : 
     609                 :             : !      k-dependent data
     610         [ +  + ]:         228 :        eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
     611         [ +  + ]:         228 :        occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
     612         [ +  + ]:         228 :        doccde_k(:)=doccde(1+bdtot_index:nband_k+bdtot_index)
     613                 :             : 
     614                 :             : #if defined(HAVE_GPU_MARKERS)
     615                 :             :        call nvtxStartRange("dist_dipoles")
     616                 :             : #endif
     617                 :             : !      In case of non MPI-IO, receive all (n,m) dipoles from master proc
     618                 :             : !        Then broadcast them to all band processors
     619         [ -  + ]:          14 :        if (.not.iomode_estf_mpiio) then
     620   [ #  #  #  # ]:           0 :          if (me/=master.and.me==master_band) then
     621                 :           0 :            call xmpi_exch(psinablapsi,pnp_size,master,psinablapsi,me,comm,etiq,ierr)
     622                 :             :          end if
     623                 :           0 :          call xmpi_bcast(psinablapsi,master,mpi_enreg%comm_band,mpierr)
     624                 :             :        end if
     625                 :             : #if defined(HAVE_GPU_MARKERS)
     626                 :             :        call nvtxEndRange()
     627                 :             : #endif
     628                 :             : 
     629                 :             : #if defined(HAVE_GPU_MARKERS)
     630                 :             :        call nvtxStartRange("band_loop")
     631                 :             : #endif
     632                 :             : !      LOOP OVER BANDS n
     633         [ +  + ]:         228 :        do iband=1,nband_k
     634                 :             : 
     635                 :             : !        Select bands for current proc
     636                 :         214 :          myband=(mpi_enreg%proc_distrb(ikpt,iband,isppol)==me)
     637         [ +  + ]:         228 :          if (myband) then
     638                 :             : 
     639                 :             : #if defined(HAVE_GPU_MARKERS)
     640                 :             :            call nvtxStartRange("read_dipoles_band")
     641                 :             : #endif
     642                 :             : !          In case of MPI-IO, read valence-valence dipoles for the block of bands ib0:ib1
     643                 :             : !            starting at band n (contiguous bands of current proc)
     644         [ +  + ]:         144 :            if (iomode_estf_mpiio.and.iband>ib1) then
     645                 :          14 :              ib0=iband
     646                 :          14 :              ib1=band_block_end(mpi_enreg%proc_distrb(ikpt,:,isppol),me,ib0,nband_k,nb_blk)
     647         [ -  + ]:          14 :              if (nc_unlimited) then
     648   [ #  #  #  # ]:           0 :                nc_start_6=[1,1,ib0,ikpt,isppol,1] ; nc_count_6=[2,3,ib1-ib0+1,1,1,mband] ; nc_stride_6=[1,1,1,1,1,1]
     649         [ #  # ]:           0 :                NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     650         [ -  + ]:          14 :              else if (.not.read_half_dipoles) then
     651   [ #  #  #  # ]:           0 :                nc_start_6=[1,1,1,ib0,ikpt,isppol] ; nc_count_6=[2,3,mband,ib1-ib0+1,1,1] ; nc_stride_6=[1,1,1,1,1,1]
     652         [ #  # ]:           0 :                NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     653                 :             :              else
     654   [ +  +  +  + ]:         154 :                nc_start_5=[1,1,(ib0*(ib0-1))/2+1,ikpt,isppol] ; nc_count_5=[2,3,(ib1*(ib1+1))/2-(ib0*(ib0-1))/2,1,1]
     655                 :          14 :                nc_stride_5=[1,1,1,1,1]
     656         [ -  + ]:          14 :                NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     657                 :             :              end if
     658                 :             :            end if
     659                 :             : 
     660                 :             : !          Position of the (n,m) dipoles in psinablapsi: ijband=ij0+(m-1)*ij_stride
     661                 :         144 :            ij_stride=1
     662         [ +  - ]:         144 :            if (read_half_dipoles) then
     663                 :             :              !Only n>=m pairs are stored; for MPI-IO, pairs of the block ib0:ib1
     664                 :         144 :              ij0=(iband*(iband-1))/2-(ib0*(ib0-1))/2+1
     665   [ #  #  #  # ]:           0 :            else if (iomode_estf_mpiio.and.nc_unlimited) then
     666                 :             :              !MPI-IO, unlimited bands dimension: psinablapsi(:,:,ib0:ib1,1:mband)
     667                 :           0 :              ij0=iband-ib0+1
     668                 :           0 :              ij_stride=ib1-ib0+1
     669                 :             :            else
     670                 :             :              !psinablapsi(:,:,1:bd_stride,ib0:ib1)
     671                 :             :              !bd_stride is mband for netCDF I/O, nband_k for Fortran I/O
     672         [ #  # ]:           0 :              bd_stride=merge(mband,nband_k,iomode==IO_MODE_ETSF)
     673                 :           0 :              ij0=(iband-ib0)*bd_stride+1
     674                 :             :            end if
     675                 :             : #if defined(HAVE_GPU_MARKERS)
     676                 :             :            call nvtxEndRange()
     677                 :             : #endif
     678                 :             : 
     679                 :             : !          Apply KG formula to buffered pairs if there is no room for the pairs of band n
     680         [ -  + ]:         144 :            if (npairs+iband>npairs_max) then
     681                 :           0 :              run_start(nruns+1)=npairs+1
     682                 :             :              call conducti_paw_kg_sum(npairs,pair_ade,pair_drude,pair_wgt,nruns,run_start,run_sorted,&
     683                 :           0 : &                                     mom,oml1,broad_mode,dom,my_use_gpu,kin11_k,kin12_k,kin21_k,kin22_k,cond_nd_k)
     684                 :           0 :              npairs=0
     685                 :           0 :              nruns=0
     686                 :             :            end if
     687                 :             : 
     688                 :             : #if defined(HAVE_GPU_MARKERS)
     689                 :             :            call nvtxStartRange("fill_pairs")
     690                 :             : #endif
     691                 :             : !          LOOP OVER BANDS m
     692                 :             : !            The (n,m) pair is stored in slot npairs+m of the buffer; pairs that do not
     693                 :             : !            contribute are removed afterwards (serial loop, also computing deltae_min and
     694                 :             : !            the sum rule in the order of m)
     695                 :             : !$OMP PARALLEL DO IF(iband>=128) &
     696                 :             : !$OMP PRIVATE(diff_occ,diff_eig,dhdk2_r,dhdk2_g,docc_deig,fact_omega0,ijband,ipair,kin_fact,l1,l2,omega0,pair_coef)
     697         [ +  + ]:        1328 :            do jband=1,iband
     698                 :        1184 :              diff_occ = occ_k(iband)-occ_k(jband)
     699                 :        1184 :              diff_eig = eig0_k(iband)-eig0_k(jband)
     700                 :             : 
     701                 :        1184 :              dhdk2_r = zero
     702                 :        1184 :              dhdk2_g = zero
     703                 :             : 
     704                 :        1184 :              ijband=ij0+(jband-1)*ij_stride
     705                 :             : 
     706         [ +  + ]:        4736 :              do l2=1,3
     707         [ +  + ]:       15392 :                do l1=1,3
     708                 :             :                  dhdk2_r(l1,l2)=dhdk2_r(l1,l2)+(&
     709                 :             : &                  psinablapsi(1,l1,ijband)*psinablapsi(1,l2,ijband)&
     710                 :       14208 : &                 +psinablapsi(2,l1,ijband)*psinablapsi(2,l2,ijband))
     711                 :             :                end do
     712                 :             :              end do
     713         [ +  + ]:        4736 :              do l1=1,3
     714                 :             :                dhdk2_g=dhdk2_g &
     715                 :             : &                +(psinablapsi(1,l1,ijband)*psinablapsi(1,l1,ijband) &
     716                 :        4736 : &                 +psinablapsi(2,l1,ijband)*psinablapsi(2,l1,ijband))*third ! Average over directions
     717                 :             :              end do
     718                 :             : 
     719                 :             :              !Conductivity for each omega - Apply KG formula
     720                 :        1184 :              kin_fact=(eig0_k(iband)+eig0_k(jband))*half-(fermie+entropy)
     721                 :        1184 :              omega0=dabs(diff_occ)<tol12
     722         [ +  + ]:        1184 :              fact_omega0=merge(two,one,omega0)
     723                 :             :              !Evaluate sumrule
     724                 :             :              if (.not.omega0) then
     725                 :         888 :                docc_deig=dabs(diff_occ/diff_eig)
     726         [ +  + ]:         296 :              else if(add_drude==1) then
     727                 :          13 :                docc_deig=dabs(doccde_k(iband))
     728                 :             :              else
     729                 :             :                docc_deig=zero
     730                 :             :              endif
     731                 :        1184 :              band_np(jband)=two*dhdk2_g*docc_deig/fact_omega0
     732                 :             : 
     733                 :             :              !Store the pair for KG formula
     734                 :             :              !  For omega/=0, docc_deig=|diff_occ|/omega: the 1/omega factor is applied in conducti_paw_kg_sum
     735                 :             :              !  Pairs with docc_deig=0 do not contribute
     736                 :        1184 :              ipair=npairs+jband
     737                 :        1184 :              pair_ade(ipair)=dabs(diff_eig)
     738   [ +  +  +  + ]:        1184 :              band_keep(jband)=(.not.omega0).or.(add_drude==1)
     739         [ +  + ]:        1184 :              if (.not.band_keep(jband)) cycle
     740         [ +  + ]:         901 :              if (.not.omega0) then
     741                 :             :                pair_coef=dabs(diff_occ)
     742                 :             :              else
     743                 :          13 :                pair_coef=dabs(doccde_k(iband))
     744                 :             :              endif
     745                 :         901 :              pair_coef=pair_coef*pi/ucvol
     746                 :         901 :              pair_drude(ipair)=omega0
     747                 :         901 :              pair_wgt(1,ipair)=pair_coef*dhdk2_g
     748                 :         901 :              pair_wgt(2,ipair)=pair_wgt(1,ipair)*kin_fact
     749                 :         901 :              pair_wgt(3,ipair)=pair_wgt(2,ipair)*kin_fact
     750                 :         901 :              pair_wgt(4,ipair)=pair_coef*dhdk2_r(1,1)
     751                 :         901 :              pair_wgt(5,ipair)=pair_coef*dhdk2_r(2,2)
     752                 :         901 :              pair_wgt(6,ipair)=pair_coef*dhdk2_r(3,3)
     753                 :         901 :              pair_wgt(7,ipair)=pair_coef*dhdk2_r(1,2)
     754                 :         901 :              pair_wgt(8,ipair)=pair_coef*dhdk2_r(1,3)
     755                 :        1328 :              pair_wgt(9,ipair)=pair_coef*dhdk2_r(2,3)
     756                 :             :            end do !jband
     757                 :             : !$OMP END PARALLEL DO
     758                 :             : 
     759                 :             : !          Minimal validity limit, sum rule, and removal of the pairs that do not contribute
     760                 :             :            nkeep=0
     761                 :             :            run_sorted_k=.true.
     762         [ +  + ]:        1328 :            do jband=1,iband
     763                 :        1184 :              ipair=npairs+jband
     764                 :        1184 :              deltae_min_tmp=pair_ade(ipair)
     765   [ +  +  +  + ]:        1184 :              if ((deltae_min_tmp>=tol5).and.(deltae_min_tmp<=deltae_min)) deltae_min=deltae_min_tmp
     766                 :        1184 :              np_sum_k1=np_sum_k1+band_np(jband)
     767         [ +  + ]:        1328 :              if (band_keep(jband)) then
     768                 :         901 :                nkeep=nkeep+1
     769         [ +  + ]:         901 :                if (nkeep>1) then
     770         [ +  - ]:         786 :                  if (pair_ade(ipair)>pair_ade(npairs+nkeep-1)) run_sorted_k=.false.
     771                 :             :                end if
     772         [ -  + ]:         901 :                if (nkeep<jband) then
     773                 :           0 :                  pair_ade(npairs+nkeep)=pair_ade(ipair)
     774                 :           0 :                  pair_drude(npairs+nkeep)=pair_drude(ipair)
     775         [ #  # ]:           0 :                  pair_wgt(:,npairs+nkeep)=pair_wgt(:,ipair)
     776                 :             :                end if
     777                 :             :              end if
     778                 :             :            end do
     779         [ +  + ]:         144 :            if (nkeep>0) then
     780                 :         115 :              nruns=nruns+1
     781                 :         115 :              run_start(nruns)=npairs+1
     782                 :         115 :              run_sorted(nruns)=run_sorted_k
     783                 :             :            end if
     784                 :         144 :            npairs=npairs+nkeep
     785                 :             : #if defined(HAVE_GPU_MARKERS)
     786                 :             :            call nvtxEndRange()
     787                 :             : #endif
     788                 :             : 
     789                 :         144 :            socc_k=socc_k+occ_k(iband)
     790                 :             : 
     791                 :             :          end if ! my band?
     792                 :             :        end do ! iband
     793                 :             : #if defined(HAVE_GPU_MARKERS)
     794                 :             :        call nvtxEndRange()
     795                 :             : #endif
     796                 :             : 
     797                 :             : !      Apply KG formula to remaining buffered pairs
     798         [ +  - ]:          14 :        if (npairs>0) then
     799                 :          14 :          run_start(nruns+1)=npairs+1
     800                 :             :          call conducti_paw_kg_sum(npairs,pair_ade,pair_drude,pair_wgt,nruns,run_start,run_sorted,&
     801                 :          14 : &                                 mom,oml1,broad_mode,dom,my_use_gpu,kin11_k,kin12_k,kin21_k,kin22_k,cond_nd_k)
     802                 :             :        end if
     803                 :             : 
     804                 :             : !      Accumulate k-point contribution
     805         [ +  + ]:       14014 :        do iom=1,mom
     806                 :       14000 :          kin11(iom,isppol)=kin11(iom,isppol)+wtk(ikpt)*kin11_k(iom)
     807                 :       14000 :          kin12(iom)=kin12(iom)+wtk(ikpt)*kin12_k(iom)
     808                 :       14000 :          kin21(iom)=kin21(iom)+wtk(ikpt)*kin21_k(iom)
     809                 :       14000 :          kin22(iom)=kin22(iom)+wtk(ikpt)*kin22_k(iom)
     810   [ +  +  +  + ]:      182014 :          cond_nd(:,:,iom)=cond_nd(:,:,iom)+wtk(ikpt)*cond_nd_k(:,:,iom)
     811                 :             :        end do
     812                 :          14 :        np_sum=np_sum+wtk(ikpt)*np_sum_k1
     813                 :          14 :        socc=socc+wtk(ikpt)*socc_k
     814                 :             : 
     815                 :             : !      Validity limit
     816                 :          14 :        deltae=deltae+(eig0_k(nband_k)-fermie)
     817                 :             : 
     818                 :          14 :        ABI_FREE(eig0_k)
     819         [ -  + ]:          14 :        ABI_FREE(occ_k)
     820         [ -  + ]:          14 :        ABI_FREE(doccde_k)
     821                 :             : 
     822                 :             : !    End loop over kpt/spin
     823                 :             :      end if ! My kpt?
     824                 :          30 :      bdtot_index=bdtot_index+nband_k
     825                 :             : #if defined(HAVE_GPU_MARKERS)
     826                 :             :      call nvtxEndRange()
     827                 :             : #endif
     828                 :             :    end do ! ikpt
     829                 :             :  end do ! isppol
     830                 :             : 
     831                 :             : #if defined(HAVE_GPU_MARKERS)
     832                 :             :  call nvtxStartRange("dummy_reads")
     833                 :             : #endif
     834         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
     835   [ +  -  +  + ]:          14 :    if(iomode_estf_mpiio.and.nproc>1) then
     836         [ +  + ]:          10 :      do idum=my_ncalls+1,ncalls_max
     837         [ -  + ]:          10 :         if (nc_unlimited) then
     838                 :           0 :           nc_start_6=[1,1,1,1,1,1] ; nc_count_6=[0,0,0,0,0,0] ; nc_stride_6=[1,1,1,1,1,1]
     839         [ #  # ]:           0 :           NCF_CHECK(nf90_get_var(ncid,varid,dummy,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     840         [ -  + ]:           2 :         else if (.not.read_half_dipoles) then
     841                 :           0 :           nc_start_6=[1,1,1,1,1,1] ; nc_count_6=[0,0,0,0,0,0] ; nc_stride_6=[1,1,1,1,1,1]
     842         [ #  # ]:           0 :           NCF_CHECK(nf90_get_var(ncid,varid,dummy,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     843                 :             :         else
     844                 :           2 :           nc_start_5=[1,1,1,1,1] ; nc_count_5=[0,0,0,0,0] ; nc_stride_5=[1,1,1,1,1]
     845         [ -  + ]:           2 :           NCF_CHECK(nf90_get_var(ncid,varid,dummy,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     846                 :             :         end if
     847                 :             :      enddo
     848                 :             :    endif
     849                 :             :  endif
     850                 :             : 
     851                 :             : #if defined(HAVE_GPU_MARKERS)
     852                 :             :  call nvtxEndRange()
     853                 :             : #endif
     854                 :             : 
     855                 :             : #if defined(HAVE_GPU_MARKERS)
     856                 :             :  call nvtxStartRange("xmpi_sum")
     857                 :             : #endif
     858                 :             : !Accumulate kpt/band contributions over processors
     859                 :          14 :  call xmpi_sum(kin11,comm,mpierr)
     860                 :          14 :  call xmpi_sum(kin12,comm,mpierr)
     861                 :          14 :  call xmpi_sum(kin21,comm,mpierr)
     862                 :          14 :  call xmpi_sum(kin22,comm,mpierr)
     863                 :          14 :  call xmpi_sum(np_sum,comm,mpierr)
     864                 :          14 :  call xmpi_sum(socc,comm,mpierr)
     865                 :          14 :  call xmpi_sum(deltae,comm,mpierr)
     866                 :          14 :  call xmpi_min(deltae_min,comm,mpierr)
     867                 :          14 :  call xmpi_sum(cond_nd,comm,mpierr)
     868                 :          14 :  deltae=deltae/mpi_enreg%nproc_band
     869                 :             : #if defined(HAVE_GPU_MARKERS)
     870                 :             :  call nvtxEndRange()
     871                 :             : #endif
     872                 :             : 
     873         [ -  + ]:          14 :  ABI_FREE(psinablapsi)
     874         [ -  + ]:          14 :  ABI_FREE(pair_ade)
     875         [ -  + ]:          14 :  ABI_FREE(pair_drude)
     876         [ -  + ]:          14 :  ABI_FREE(pair_wgt)
     877         [ -  + ]:          14 :  ABI_FREE(band_np)
     878         [ -  + ]:          14 :  ABI_FREE(band_keep)
     879         [ -  + ]:          14 :  ABI_FREE(run_start)
     880         [ -  + ]:          14 :  ABI_FREE(run_sorted)
     881                 :             : 
     882                 :             : #if defined(HAVE_GPU_MARKERS)
     883                 :             :  call nvtxStartRange("output")
     884                 :             : #endif
     885                 :             : !---------------------------------------------------------------------------------
     886                 :             : ! Output results
     887                 :             : 
     888                 :             : !Print file headers (only master node)
     889         [ +  + ]:          14 :  if (me==master) then
     890                 :             : !  Standard output
     891                 :             :    write(std_out,'(a,f10.5,a,f10.5,a)')&
     892                 :           8 : &   ' Emax-Efermi       =',deltae/dble(nkpt*nsppol),' Ha', &
     893                 :          16 : &                          deltae/dble(nkpt*nsppol)*Ha_eV,' eV'
     894                 :             :    write(std_out,'(a,f10.5,a,f10.5,a)')&
     895                 :           8 : &   ' DeltaE min        =',deltae_min,' Ha',deltae_min*Ha_eV,' eV'
     896                 :             : 
     897                 :             : !  _Lij file
     898         [ -  + ]:           8 :    if (open_file(trim(filnam_out)//'_Lij',msg, newunit=lij_unt, form='formatted', action="write") /= 0) then
     899                 :           0 :      ABI_ERROR(msg)
     900                 :             :    end if
     901                 :           8 :    write(lij_unt,'(a)')' # omega(ua) L11 L12 L22'
     902                 :             : 
     903                 :             : !  _sig_up_dn file
     904         [ -  + ]:           8 :    if(nsppol==2) then
     905         [ #  # ]:           0 :      if (open_file(trim(filnam_out)//'_sig_up_dn', msg, newunit=sig_unt, form='formatted', action="write") /= 0) then
     906                 :           0 :        ABI_ERROR(msg)
     907                 :             :      end if
     908         [ #  # ]:           0 :      if(au_units>0) then
     909                 :           0 :        write(sig_unt,'(2a)')' # omega(ua) cond(ua)  ',&
     910                 :           0 : &                           '      cond(ua) UP      cond(ua) DN'
     911                 :             :      else
     912                 :           0 :        write(sig_unt,'(2a)')' # hbar*omega(eV)      cond(ohm.cm)-1',&
     913                 :           0 : &                           '      cond(ohm.cm)-1 UP      cond(ohm.cm)-1 DN'
     914                 :             :      endif
     915                 :             :    end if
     916                 :             : 
     917                 :             : ! sig_dir file
     918         [ -  + ]:           8 :   if (open_file(trim(filnam_out)//'_sig_tensor', msg, newunit=sigd_unt,form='formatted', action="write") /= 0) then
     919                 :           0 :      ABI_ERROR(msg)
     920                 :             :   end if
     921         [ -  + ]:           8 :   if(au_units>0) then
     922                 :           0 :     write(sigd_unt,'(a)')' # omega(ua) cond_xx(ua) cond_yy(ua) cond_zz(ua) cond_xy(ua) cond_xz(ua) cond_yz(ua)'
     923                 :             :   else
     924                 :             :     write(sigd_unt,'(a)')' # hbar*omega(eV) cond_xx(ohm.cm)-1 cond_yy(ohm.cm)-1 cond_zz(ohm.cm)-1 &
     925                 :           8 : &           cond_xy(ohm.cm)-1 cond_xz(ohm.cm)-1 cond_yz(ohm.cm)-1'
     926                 :             :   endif
     927                 :             : 
     928                 :             : !  _Kth file
     929         [ -  + ]:           8 :    if (open_file(trim(filnam_out)//'_Kth', msg, newunit=kth_unt, form='formatted', action="write") /=0) then
     930                 :           0 :      ABI_ERROR(msg)
     931                 :             :    end if
     932                 :             :    write(kth_unt,'(a)')&
     933                 :           8 : &   " #Thermal conductivity following B. Holst et al Phys. Rev. B 83 (2011) 235120"
     934         [ -  + ]:           8 :    if(au_units>0) then
     935                 :           0 :      write(kth_unt,'(a)')' # omega(ua)  thermal cond(ua) thermopower(ua)'
     936                 :             :    else
     937                 :           8 :      write(kth_unt,'(a)')' # hbar*omega(eV)  thermal cond (W/m/K)   thermopower(microohm/K)'
     938                 :             :    endif
     939                 :             : 
     940                 :             : !  Output file
     941         [ -  + ]:           8 :    if (open_file(trim(filnam_out)//'.out', msg, newunit=ocond_unt, form='formatted', action="write") /= 0) then
     942                 :           0 :      ABI_ERROR(msg)
     943                 :             :    end if
     944                 :           8 :    write(ocond_unt,'(a)' )'#Conducti output file:'
     945                 :           8 :    write(ocond_unt,'(a)' )'#Contains all results produced by conducti utility'
     946                 :           8 :    write(ocond_unt,'(a)' )'#  '
     947                 :           8 :    write(ocond_unt,'(a,i8,3f10.5,a)')'# npts,omin,omax,width     =' ,mom,omin,omax,dom,' Ha'
     948                 :           8 :    write(ocond_unt,'(a,3f10.5,a)' )'# rprimd(bohr)      =',rprimd(1:3,1)
     949                 :           8 :    write(ocond_unt,'(a,3f10.5,a)' )'#                    ',rprimd(1:3,2)
     950                 :           8 :    write(ocond_unt,'(a,3f10.5,a)' )'#                    ',rprimd(1:3,3)
     951                 :           8 :    write(ocond_unt,'(a,i8)' )      '# natom             =',natom
     952                 :           8 :    write(ocond_unt,'(a,3i8)' )     '# nkpt,mband,nsppol        =',nkpt,mband,nsppol
     953                 :           8 :    write(ocond_unt,'(a, f10.5,a)' )'# ecut                  =',ecut,' Ha'
     954                 :           8 :    write(ocond_unt,'(a,f10.5,a,f10.5,a)' )'# fermie            =',fermie,' Ha ',fermie*Ha_eV,' eV'
     955                 :             : 
     956                 :           8 :    write(ocond_unt,'(a,f12.5,a,f12.5,a)') '# Temp              =',tsmear,' Ha ',Tatm,' Kelvin'
     957                 :           8 :    write(ocond_unt,'(a,f15.5)' )'# Number of electrons           = ',socc
     958                 :           8 :    write(ocond_unt,'(a,f15.5)' )'# sumrule           = ',np_sum/socc
     959                 :             :    write(ocond_unt,'(a,f10.5,a,f10.5,a)' )&
     960                 :           8 : &   '# Emax-Efermi       =',deltae/dble(nkpt*nsppol),' Ha',deltae/dble(nkpt*nsppol)*Ha_eV,' eV'
     961                 :           8 :    write(ocond_unt,'(a)' )'# '
     962         [ -  + ]:           8 :    if(au_units>0) then
     963                 :           0 :      write(ocond_unt,'(a)')'# omega(ua)       cond(ua)             thermal cond(ua)       thermopower(ua)'
     964                 :             :    else
     965                 :           8 :      write(ocond_unt,'(a)')'# hbar*omega(eV) cond(ohm.cm)-1 thermal cond(W/m/K)   thermopower(microvolt/K) '
     966                 :             :    endif
     967                 :             : 
     968                 :             :  end if ! me==master?
     969                 :             : 
     970                 :             : !Compute (and print) thermal conductivity and thermopower
     971         [ +  + ]:       14014 :  do iom=1,mom
     972                 :       14000 :    oml=oml1(iom)
     973                 :             : 
     974         [ +  + ]:       28000 :    do isppol=1,nsppol
     975         [ +  + ]:       14000 :      if (dabs(kin11(iom,isppol))<tol19) kin11(iom,isppol)=zero
     976                 :       28000 :      sig_abs(iom)=sig_abs(iom)+kin11(iom,isppol)
     977                 :             :    end do
     978                 :             : 
     979                 :       14000 :    Kth(iom)=kin22(iom)/tsmear
     980                 :       14000 :    Stp(iom)=zero
     981         [ +  + ]:       14000 :    if (sig_abs(iom)/=zero)  then
     982                 :       13169 :      Kth(iom)=Kth(iom)-(kin12(iom)*kin21(iom)/sig_abs(iom))/tsmear
     983                 :       13169 :      Stp(iom)=kin12(iom)/(sig_abs(iom)*tsmear)
     984                 :             :    else
     985                 :         831 :      Kth(iom)=Kth(iom-1)
     986                 :         831 :      Stp(iom)=Stp(iom-1)
     987                 :             :    endif
     988         [ +  + ]:       14000 :    if (dabs(Kth(iom))<tol19) Kth(iom)=zero
     989         [ -  + ]:       14000 :    if (dabs(Stp(iom))<tol19) Stp(iom)=zero
     990         [ +  + ]:       14000 :    if (abs(kin12(iom))<10.0_dp**(-80)) kin12(iom)=zero
     991         [ +  + ]:       14000 :    if (abs(kin21(iom))<10.0_dp**(-80)) kin21(iom)=zero
     992         [ +  + ]:       14014 :    if (abs(kin22(iom))<10.0_dp**(-80)) kin22(iom)=zero
     993                 :             :  end do
     994                 :             : 
     995                 :             :  !Compute the imaginary part of the conductivity (principal value)
     996                 :             : !  +derived optical properties.
     997         [ +  + ]:          14 :  if (me==master) then
     998                 :           8 :    call msig(sig_abs,mom,oml1,filnam_out,phi,au_units)
     999                 :             :  end if
    1000                 :             : 
    1001                 :             :  ! Units
    1002         [ +  + ]:          14 :  if (me==master) then
    1003         [ +  + ]:        8008 :    do iom=1,mom
    1004                 :        8000 :      oml=oml1(iom)
    1005                 :        8008 :       write(lij_unt,'(f12.5,3es22.12)') oml,sig_abs(iom),kin12(iom),kin22(iom)
    1006                 :             :    enddo
    1007                 :             :  endif
    1008                 :             : 
    1009                 :          14 :  np_sum_2=zero
    1010         [ +  + ]:       14000 :  do iom=1,mom-1
    1011                 :       14000 :    np_sum_2=np_sum_2+(sig_abs(iom)+sig_abs(iom+1))*(oml1(iom+1)-oml1(iom))/2.0_dp
    1012                 :             :  enddo
    1013                 :          14 :  np_sum_2=2.0_dp*np_sum_2*ucvol/pi
    1014   [ +  -  +  + ]:       14014 :  if(au_units==0) oml1=oml1*Ha_eV
    1015   [ +  -  +  +  :      182014 :  if(au_units==0) cond_nd=cond_nd*Ohmcm
             +  +  +  + ]
    1016   [ +  -  +  + ]:       14014 :  if(au_units==0) sig_abs=sig_abs*Ohmcm
    1017   [ +  -  +  +  :       14028 :  if(au_units==0) kin11=kin11*Ohmcm
                   +  + ]
    1018   [ +  -  +  + ]:       14014 :  if(au_units==0) Kth=Kth*3.4057d9/Ha_K
    1019   [ +  -  +  + ]:       14014 :  if(au_units==0) Stp=Stp*Ha_J/(Ha_K*e_CB)*10.0_dp**6
    1020                 :             : 
    1021                 :             : 
    1022         [ +  + ]:          14 :  if (me==master) then
    1023                 :           8 :    write(std_out,'(a,f15.5)' )'# Number of electrons           = ',socc
    1024                 :           8 :    write(std_out,'(a,f15.5)' )'# sumrule           = ',np_sum/socc
    1025                 :           8 :    write(std_out,'(a,f15.5)' )'# sumrule (integration) = ',np_sum_2/socc
    1026         [ +  + ]:        8008 :    do iom=1,mom
    1027                 :        8000 :      oml=oml1(iom)
    1028                 :        8000 :      write(sigd_unt,'(f12.5,6es22.12)') oml,cond_nd(1,1,iom),cond_nd(2,2,iom),cond_nd(3,3,iom),&
    1029                 :       16000 : &      cond_nd(1,2,iom),cond_nd(1,3,iom),cond_nd(2,3,iom)
    1030         [ -  + ]:        8000 :      if (nsppol==2) then
    1031                 :           0 :        write(sig_unt,'(f12.5,3es22.12)') oml,sig_abs(iom), &
    1032                 :           0 : &        kin11(iom,1),kin11(iom,2)
    1033                 :             :      end if
    1034                 :        8000 :      write(kth_unt,'(f12.5,3es22.12)') oml,Kth(iom),Stp(iom)
    1035                 :        8008 :      write(ocond_unt,'(1f12.5,3es22.12)') oml,sig_abs(iom),Kth(iom),Stp(iom)
    1036                 :             :    enddo
    1037                 :             :  end if
    1038                 :             : 
    1039                 :             : 
    1040                 :             : !---------------------------------------------------------------------------------
    1041                 :             : ! End
    1042                 :             : 
    1043                 :             : !Close all files
    1044         [ +  + ]:          14 :  if (me==master) then
    1045                 :           8 :    write(std_out,'(2a)')ch10,'OUTPUT'
    1046                 :           8 :    write(std_out,'(a)')trim(filnam_out)//'_Lij : Onsager kinetic coefficients'
    1047                 :           8 :    write(std_out,'(a)')trim(filnam_out)//'_eps : Optical conductivity and dielectric function'
    1048                 :           8 :    write(std_out,'(a)')trim(filnam_out)//'_sig_tensor : Optical conductivity tensor'
    1049                 :           8 :    write(std_out,'(a)')trim(filnam_out)//'_Kth : Thermal conductivity and thermopower'
    1050                 :           8 :    write(std_out,'(a)')trim(filnam_out)//'_abs : n, k, reflectivity, absorption'
    1051                 :           8 :    close(lij_unt)
    1052         [ -  + ]:           8 :    if(nsppol==2) close(sig_unt)
    1053                 :           8 :    close(kth_unt)
    1054                 :           8 :    close(ocond_unt)
    1055                 :           8 :    close(sigd_unt)
    1056                 :             :  end if
    1057         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
    1058   [ -  +  -  - ]:          14 :    if (iomode_estf_mpiio.or.me==master) then
    1059         [ -  + ]:          14 :      NCF_CHECK(nf90_close(ncid))
    1060                 :             :    end if
    1061         [ #  # ]:           0 :  else if (me==master) then
    1062                 :           0 :    ierr=close_unit(opt_unt,msg)
    1063         [ #  # ]:           0 :    ABI_CHECK(ierr==0,sjoin("Error while closing ",filnam1))
    1064                 :             :  end if
    1065                 :             : 
    1066                 :             : #if defined(HAVE_GPU_MARKERS)
    1067                 :             :  call nvtxEndRange()
    1068                 :             : #endif
    1069                 :             : !Release memory space
    1070         [ -  + ]:          14 :  ABI_FREE(kin11)
    1071         [ -  + ]:          14 :  ABI_FREE(kin22)
    1072         [ -  + ]:          14 :  ABI_FREE(kin12)
    1073         [ -  + ]:          14 :  ABI_FREE(kin21)
    1074         [ -  + ]:          14 :  ABI_FREE(kin11_k)
    1075         [ -  + ]:          14 :  ABI_FREE(kin22_k)
    1076         [ -  + ]:          14 :  ABI_FREE(kin12_k)
    1077         [ -  + ]:          14 :  ABI_FREE(kin21_k)
    1078         [ -  + ]:          14 :  ABI_FREE(Stp)
    1079         [ -  + ]:          14 :  ABI_FREE(Kth)
    1080         [ -  + ]:          14 :  ABI_FREE(cond_nd)
    1081         [ -  + ]:          14 :  ABI_FREE(cond_nd_k)
    1082         [ -  + ]:          14 :  ABI_FREE(sig_abs)
    1083         [ -  + ]:          14 :  ABI_FREE(eigen0)
    1084         [ -  + ]:          14 :  ABI_FREE(nband)
    1085         [ -  + ]:          14 :  ABI_FREE(oml1)
    1086         [ -  + ]:          14 :  ABI_FREE(occ)
    1087         [ -  + ]:          14 :  ABI_FREE(doccde)
    1088         [ -  + ]:          14 :  ABI_FREE(wtk)
    1089                 :          14 :  call hdr%free()
    1090                 :          14 :  call destroy_mpi_enreg(mpi_enreg)
    1091                 :             : 
    1092                 :             :  ABI_NVTX_END_RANGE()
    1093                 :          14 :  call timab(1186,2,tsec)
    1094                 :             : 
    1095   [ -  +  -  +  :          28 : end subroutine conducti_paw
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
                +  -  + ]
    1096                 :             : !!***
    1097                 :             : 
    1098                 :             : !----------------------------------------------------------------------
    1099                 :             : 
    1100                 :             : !!****f* m_conducti/conducti_paw_kg_sum
    1101                 :             : !! NAME
    1102                 :             : !! conducti_paw_kg_sum
    1103                 :             : !!
    1104                 :             : !! FUNCTION
    1105                 :             : !! Apply the Kubo-Greenwood formula to a buffer of (n,m) band pairs
    1106                 :             : !! and accumulate the contributions for all frequencies.
    1107                 :             : !! On CPU, parallelized over frequencies: each frequency sums over all pairs
    1108                 :             : !!   (gaussian broadening: only over the pairs of its window).
    1109                 :             : !! On GPU (OpenMP offload), see conducti_paw_kg_sum_gpu.
    1110                 :             : !!
    1111                 :             : !! INPUTS
    1112                 :             : !!  npairs=number of pairs in the buffer
    1113                 :             : !!  pair_ade(npairs)=|e_n-e_m| for each pair
    1114                 :             : !!  pair_drude(npairs)=.true. for pairs with equal occupations (Drude term):
    1115                 :             : !!                     their weights do not include the 1/omega factor
    1116                 :             : !!  pair_wgt(9,npairs)=weights of each pair (pi/ucvol*docc_deig already included,
    1117                 :             : !!                     without the 1/omega factor):
    1118                 :             : !!                     dhdk2_g, dhdk2_g*kin_fact, dhdk2_g*kin_fact**2,
    1119                 :             : !!                     dhdk2_r(1,1),dhdk2_r(2,2),dhdk2_r(3,3),dhdk2_r(1,2),dhdk2_r(1,3),dhdk2_r(2,3)
    1120                 :             : !!  nruns=number of runs of pairs in the buffer
    1121                 :             : !!  run_start(nruns+1)=index of the first pair of each run (run_start(nruns+1)=npairs+1)
    1122                 :             : !!  run_sorted(nruns)=.true. if pair_ade decreases along the run
    1123                 :             : !!  mom=number of frequencies
    1124                 :             : !!  oml1(mom)=frequencies
    1125                 :             : !!  broad_mode=0 for gaussian broadening, 1 for lorentzian broadening
    1126                 :             : !!  dom=broadening width
    1127                 :             : !!  use_gpu=.true. to use GPU (OpenMP offload)
    1128                 :             : !!
    1129                 :             : !! SIDE EFFECTS
    1130                 :             : !!  kin11_k(mom),kin12_k(mom),kin21_k(mom),kin22_k(mom)=Onsager kinetic coefficients (accumulated)
    1131                 :             : !!  cond_nd_k(3,3,mom)=conductivity tensor (accumulated)
    1132                 :             : !!
    1133                 :             : !! SOURCE
    1134                 :             : 
    1135   [ -  +  -  + ]:          14 : subroutine conducti_paw_kg_sum(npairs,pair_ade,pair_drude,pair_wgt,nruns,run_start,run_sorted,&
    1136         [ -  + ]:          14 : &                              mom,oml1,broad_mode,dom,use_gpu,kin11_k,kin12_k,kin21_k,kin22_k,cond_nd_k)
    1137                 :             : 
    1138                 :             : !Arguments -----------------------------------
    1139                 :             : !scalars
    1140                 :             :  integer,intent(in) :: npairs,nruns,mom,broad_mode
    1141                 :             :  logical,intent(in) :: use_gpu
    1142                 :             :  real(dp),intent(in) :: dom
    1143                 :             : !arrays
    1144                 :             :  integer,intent(in) :: run_start(nruns+1)
    1145                 :             :  logical,intent(in) :: pair_drude(:),run_sorted(nruns)
    1146                 :             :  real(dp),intent(in) :: pair_ade(:),pair_wgt(:,:),oml1(mom)
    1147                 :             :  real(dp),intent(inout) :: kin11_k(mom),kin12_k(mom),kin21_k(mom),kin22_k(mom),cond_nd_k(3,3,mom)
    1148                 :             : 
    1149                 :             : !Local variables-------------------------------
    1150                 :             : !scalars
    1151                 :             : !exp(-x) is exactly zero in double precision for x>745.14: it is not evaluated beyond exp_arg_max
    1152                 :             : !  (this avoids the slow underflow path of exp, without changing the results)
    1153                 :             :  real(dp),parameter :: exp_arg_max=746._dp
    1154                 :             :  integer :: iom,ipair,ipair1,ipair2,irun
    1155                 :             :  real(dp) :: arg1,arg2,arg_max,dirac,dirac_fact,dirac_width,inv_oml,oml,window
    1156                 :             : !arrays
    1157                 :             :  real(dp) :: acc(9)
    1158                 :             : 
    1159                 :             : ! *********************************************************************************
    1160                 :             : 
    1161         [ +  + ]:          14 :  if (broad_mode==0) then
    1162                 :           1 :    dirac_fact=one/(dom*sqrt(two_pi))
    1163                 :           1 :    dirac_width=one/(sqrt(two)*dom)
    1164                 :             :  else
    1165                 :          13 :    dirac_fact=dom/pi
    1166                 :          13 :    dirac_width=dom**2
    1167                 :             :  end if
    1168                 :             : 
    1169                 :             : #if defined(HAVE_GPU_MARKERS)
    1170                 :             :  call nvtxStartRange("kg_sum")
    1171                 :             : #endif
    1172                 :             : 
    1173                 :             : !Gaussian broadening: terms dirac_fact*exp(-arg) lower than 1d-20 are neglected (as in conducti_paw_core),
    1174                 :             : !  i.e. terms with arg>arg_max (at most exp_arg_max, beyond which exp is exactly zero)
    1175                 :             : !  For frequency omega, only pairs with ||e_n-e_m|-|omega||<=window contribute:
    1176                 :             : !  beyond, both exp arguments are larger than arg_max
    1177                 :             : !  In each run sorted by decreasing |e_n-e_m|, these pairs are found by binary search
    1178                 :          14 :  arg_max=zero; window=zero
    1179         [ +  + ]:          14 :  if (broad_mode==0) then
    1180                 :           1 :    arg_max=min(exp_arg_max,max(zero,log(dirac_fact*1d20)))
    1181                 :           1 :    window=sqrt(arg_max)/dirac_width
    1182                 :             :  end if
    1183                 :             : 
    1184                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1185                 :             :  if (use_gpu) then
    1186                 :             :    call conducti_paw_kg_sum_gpu(npairs,pair_ade,pair_drude,pair_wgt,mom,oml1,broad_mode,&
    1187                 :             : &                               dirac_fact,dirac_width,arg_max,kin11_k,kin12_k,kin21_k,kin22_k,cond_nd_k)
    1188                 :             :  else
    1189                 :             : #else
    1190                 :             :  ABI_UNUSED(use_gpu)
    1191                 :             : #endif
    1192                 :             : 
    1193                 :             : !$OMP PARALLEL DO SCHEDULE(dynamic,8) PRIVATE(acc,arg1,arg2,dirac,inv_oml,ipair,ipair1,ipair2,irun,oml)
    1194         [ +  + ]:       14014 :  do iom=1,mom
    1195                 :       14000 :    oml=oml1(iom)
    1196                 :       14000 :    inv_oml=one/abs(oml)
    1197                 :       14000 :    acc(:)=zero
    1198         [ +  + ]:       14000 :    if (broad_mode==0) then
    1199         [ +  + ]:       11000 :      do irun=1,nruns
    1200                 :       10000 :        ipair1=run_start(irun)
    1201                 :       10000 :        ipair2=run_start(irun+1)-1
    1202         [ +  - ]:       10000 :        if (run_sorted(irun)) then
    1203                 :       10000 :          ipair1=run_start(irun)+count_sorted(pair_ade(run_start(irun):run_start(irun+1)-1),abs(oml)+window,.true.)
    1204                 :       10000 :          ipair2=run_start(irun)-1+count_sorted(pair_ade(run_start(irun):run_start(irun+1)-1),abs(oml)-window,.false.)
    1205                 :             :        end if
    1206         [ +  + ]:       16358 :        do ipair=ipair1,ipair2
    1207                 :             :          ! Take into account (n,m) and (m,n)
    1208                 :        5358 :          arg1=((pair_ade(ipair)-oml)*dirac_width)**2
    1209                 :        5358 :          arg2=((pair_ade(ipair)+oml)*dirac_width)**2
    1210   [ -  +  -  - ]:        5358 :          if (arg1>arg_max.and.arg2>arg_max) cycle
    1211                 :        5358 :          dirac=zero
    1212         [ +  - ]:        5358 :          if (arg1<=arg_max) dirac=exp(-arg1)
    1213         [ +  + ]:        5358 :          if (arg2<=arg_max) dirac=dirac-exp(-arg2)
    1214                 :        5358 :          dirac=dirac_fact*dirac
    1215         [ +  + ]:        5358 :          if (.not.pair_drude(ipair)) dirac=dirac*inv_oml
    1216         [ +  + ]:       63580 :          acc(:)=acc(:)+dirac*pair_wgt(:,ipair)
    1217                 :             :        end do
    1218                 :             :      end do
    1219                 :             :    else
    1220         [ +  + ]:      859000 :      do ipair=1,npairs
    1221                 :             :        dirac=dirac_fact*(one/((pair_ade(ipair)-oml)**2+dirac_width) &
    1222                 :      846000 : &                       -one/((pair_ade(ipair)+oml)**2+dirac_width))
    1223         [ +  - ]:      846000 :        if (.not.pair_drude(ipair)) dirac=dirac*inv_oml
    1224         [ +  + ]:     8473000 :        acc(:)=acc(:)+dirac*pair_wgt(:,ipair)
    1225                 :             :      end do
    1226                 :             :    end if
    1227                 :       14000 :    kin11_k(iom)=kin11_k(iom)+acc(1)
    1228                 :       14000 :    kin12_k(iom)=kin12_k(iom)-acc(2)
    1229                 :       14000 :    kin21_k(iom)=kin21_k(iom)-acc(2)
    1230                 :       14000 :    kin22_k(iom)=kin22_k(iom)+acc(3)
    1231                 :       14000 :    cond_nd_k(1,1,iom)=cond_nd_k(1,1,iom)+acc(4)
    1232                 :       14000 :    cond_nd_k(2,2,iom)=cond_nd_k(2,2,iom)+acc(5)
    1233                 :       14000 :    cond_nd_k(3,3,iom)=cond_nd_k(3,3,iom)+acc(6)
    1234                 :       14000 :    cond_nd_k(1,2,iom)=cond_nd_k(1,2,iom)+acc(7)
    1235                 :       14000 :    cond_nd_k(2,1,iom)=cond_nd_k(2,1,iom)+acc(7)
    1236                 :       14000 :    cond_nd_k(1,3,iom)=cond_nd_k(1,3,iom)+acc(8)
    1237                 :       14000 :    cond_nd_k(3,1,iom)=cond_nd_k(3,1,iom)+acc(8)
    1238                 :       14000 :    cond_nd_k(2,3,iom)=cond_nd_k(2,3,iom)+acc(9)
    1239                 :       14014 :    cond_nd_k(3,2,iom)=cond_nd_k(3,2,iom)+acc(9)
    1240                 :             :  end do
    1241                 :             : !$OMP END PARALLEL DO
    1242                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1243                 :             :  end if
    1244                 :             : #endif
    1245                 :             : 
    1246                 :             : #if defined(HAVE_GPU_MARKERS)
    1247                 :             :  call nvtxEndRange()
    1248                 :             : #endif
    1249                 :             : 
    1250                 :          14 : end subroutine conducti_paw_kg_sum
    1251                 :             : !!***
    1252                 :             : 
    1253                 :             : !----------------------------------------------------------------------
    1254                 :             : 
    1255                 :             : !!****f* m_conducti/conducti_paw_kg_sum_gpu
    1256                 :             : !! NAME
    1257                 :             : !! conducti_paw_kg_sum_gpu
    1258                 :             : !!
    1259                 :             : !! FUNCTION
    1260                 :             : !! GPU (OpenMP offload) version of conducti_paw_kg_sum.
    1261                 :             : !! Parallelized over frequencies and chunks of pairs: each thread sums over a chunk
    1262                 :             : !! of pairs (no window), the partial sums of the chunks are added afterwards
    1263                 :             : !! (in the order of the chunks) in a second kernel.
    1264                 :             : !! Same pairs and same neglected terms as on CPU (see conducti_paw_kg_sum).
    1265                 :             : !!
    1266                 :             : !! INPUTS
    1267                 :             : !!  npairs,pair_ade,pair_drude,pair_wgt,mom,oml1,broad_mode=see conducti_paw_kg_sum
    1268                 :             : !!  dirac_fact,dirac_width=factor and width of the broadening function
    1269                 :             : !!  arg_max=gaussian broadening: max argument of exp (terms beyond are neglected)
    1270                 :             : !!
    1271                 :             : !! SIDE EFFECTS
    1272                 :             : !!  kin11_k(mom),kin12_k(mom),kin21_k(mom),kin22_k(mom),cond_nd_k(3,3,mom)=see conducti_paw_kg_sum
    1273                 :             : !!
    1274                 :             : !! SOURCE
    1275                 :             : 
    1276                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1277                 :             : subroutine conducti_paw_kg_sum_gpu(npairs,pair_ade,pair_drude,pair_wgt,mom,oml1,broad_mode,&
    1278                 :             : &                                  dirac_fact,dirac_width,arg_max,kin11_k,kin12_k,kin21_k,kin22_k,cond_nd_k)
    1279                 :             : 
    1280                 :             : !Arguments -----------------------------------
    1281                 :             : !scalars
    1282                 :             :  integer,intent(in) :: npairs,mom,broad_mode
    1283                 :             :  real(dp),intent(in) :: dirac_fact,dirac_width,arg_max
    1284                 :             : !arrays
    1285                 :             :  logical,intent(in) :: pair_drude(:)
    1286                 :             :  real(dp),intent(in) :: pair_ade(:),pair_wgt(:,:),oml1(mom)
    1287                 :             :  real(dp),intent(inout) :: kin11_k(mom),kin12_k(mom),kin21_k(mom),kin22_k(mom),cond_nd_k(3,3,mom)
    1288                 :             : 
    1289                 :             : !Local variables-------------------------------
    1290                 :             : !scalars
    1291                 :             :  integer :: chunk_size,ichunk,iom,ipair,nchunk
    1292                 :             :  real(dp) :: acc1,acc2,acc3,acc4,acc5,acc6,acc7,acc8,acc9,arg1,arg2,dirac,inv_oml,oml
    1293                 :             : !arrays
    1294                 :             :  real(dp),allocatable :: partial(:,:,:)
    1295                 :             : 
    1296                 :             : ! *********************************************************************************
    1297                 :             : 
    1298                 :             :  if (npairs==0) return
    1299                 :             : 
    1300                 :             : !Chunks of pairs: partial(iom,:,ichunk) is the sum over the pairs of chunk ichunk
    1301                 :             :  chunk_size=(npairs+kg_gpu_nchunk-1)/kg_gpu_nchunk
    1302                 :             :  nchunk=(npairs+chunk_size-1)/chunk_size
    1303                 :             :  ABI_MALLOC(partial,(mom,9,nchunk))
    1304                 :             :  !$OMP TARGET DATA MAP(to:pair_ade(1:npairs),pair_drude(1:npairs),pair_wgt(:,1:npairs),oml1) &
    1305                 :             :  !$OMP& MAP(alloc:partial) MAP(tofrom:kin11_k,kin12_k,kin21_k,kin22_k,cond_nd_k)
    1306                 :             : !Consecutive threads treat consecutive frequencies for the same chunk of pairs
    1307                 :             :  !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) &
    1308                 :             :  !$OMP& PRIVATE(acc1,acc2,acc3,acc4,acc5,acc6,acc7,acc8,acc9,arg1,arg2,dirac,inv_oml,ipair,oml)
    1309                 :             :  do ichunk=1,nchunk
    1310                 :             :    do iom=1,mom
    1311                 :             :      oml=oml1(iom)
    1312                 :             :      inv_oml=one/abs(oml)
    1313                 :             :      acc1=zero; acc2=zero; acc3=zero; acc4=zero; acc5=zero; acc6=zero; acc7=zero; acc8=zero; acc9=zero
    1314                 :             :      do ipair=(ichunk-1)*chunk_size+1,min(ichunk*chunk_size,npairs)
    1315                 :             :        if (broad_mode==0) then
    1316                 :             :          ! Take into account (n,m) and (m,n)
    1317                 :             :          arg1=((pair_ade(ipair)-oml)*dirac_width)**2
    1318                 :             :          arg2=((pair_ade(ipair)+oml)*dirac_width)**2
    1319                 :             :          if (arg1>arg_max.and.arg2>arg_max) cycle
    1320                 :             :          dirac=zero
    1321                 :             :          if (arg1<=arg_max) dirac=exp(-arg1)
    1322                 :             :          if (arg2<=arg_max) dirac=dirac-exp(-arg2)
    1323                 :             :          dirac=dirac_fact*dirac
    1324                 :             :        else
    1325                 :             :          dirac=dirac_fact*(one/((pair_ade(ipair)-oml)**2+dirac_width) &
    1326                 :             : &                             -one/((pair_ade(ipair)+oml)**2+dirac_width))
    1327                 :             :        end if
    1328                 :             :        if (.not.pair_drude(ipair)) dirac=dirac*inv_oml
    1329                 :             :        acc1=acc1+dirac*pair_wgt(1,ipair)
    1330                 :             :        acc2=acc2+dirac*pair_wgt(2,ipair)
    1331                 :             :        acc3=acc3+dirac*pair_wgt(3,ipair)
    1332                 :             :        acc4=acc4+dirac*pair_wgt(4,ipair)
    1333                 :             :        acc5=acc5+dirac*pair_wgt(5,ipair)
    1334                 :             :        acc6=acc6+dirac*pair_wgt(6,ipair)
    1335                 :             :        acc7=acc7+dirac*pair_wgt(7,ipair)
    1336                 :             :        acc8=acc8+dirac*pair_wgt(8,ipair)
    1337                 :             :        acc9=acc9+dirac*pair_wgt(9,ipair)
    1338                 :             :      end do
    1339                 :             :      partial(iom,1,ichunk)=acc1; partial(iom,2,ichunk)=acc2; partial(iom,3,ichunk)=acc3
    1340                 :             :      partial(iom,4,ichunk)=acc4; partial(iom,5,ichunk)=acc5; partial(iom,6,ichunk)=acc6
    1341                 :             :      partial(iom,7,ichunk)=acc7; partial(iom,8,ichunk)=acc8; partial(iom,9,ichunk)=acc9
    1342                 :             :    end do
    1343                 :             :  end do
    1344                 :             : !Add the partial sums of the chunks (in the order of the chunks)
    1345                 :             :  !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO &
    1346                 :             :  !$OMP& PRIVATE(acc1,acc2,acc3,acc4,acc5,acc6,acc7,acc8,acc9,ichunk)
    1347                 :             :  do iom=1,mom
    1348                 :             :    acc1=zero; acc2=zero; acc3=zero; acc4=zero; acc5=zero; acc6=zero; acc7=zero; acc8=zero; acc9=zero
    1349                 :             :    do ichunk=1,nchunk
    1350                 :             :      acc1=acc1+partial(iom,1,ichunk); acc2=acc2+partial(iom,2,ichunk); acc3=acc3+partial(iom,3,ichunk)
    1351                 :             :      acc4=acc4+partial(iom,4,ichunk); acc5=acc5+partial(iom,5,ichunk); acc6=acc6+partial(iom,6,ichunk)
    1352                 :             :      acc7=acc7+partial(iom,7,ichunk); acc8=acc8+partial(iom,8,ichunk); acc9=acc9+partial(iom,9,ichunk)
    1353                 :             :    end do
    1354                 :             :    kin11_k(iom)=kin11_k(iom)+acc1
    1355                 :             :    kin12_k(iom)=kin12_k(iom)-acc2
    1356                 :             :    kin21_k(iom)=kin21_k(iom)-acc2
    1357                 :             :    kin22_k(iom)=kin22_k(iom)+acc3
    1358                 :             :    cond_nd_k(1,1,iom)=cond_nd_k(1,1,iom)+acc4
    1359                 :             :    cond_nd_k(2,2,iom)=cond_nd_k(2,2,iom)+acc5
    1360                 :             :    cond_nd_k(3,3,iom)=cond_nd_k(3,3,iom)+acc6
    1361                 :             :    cond_nd_k(1,2,iom)=cond_nd_k(1,2,iom)+acc7
    1362                 :             :    cond_nd_k(2,1,iom)=cond_nd_k(2,1,iom)+acc7
    1363                 :             :    cond_nd_k(1,3,iom)=cond_nd_k(1,3,iom)+acc8
    1364                 :             :    cond_nd_k(3,1,iom)=cond_nd_k(3,1,iom)+acc8
    1365                 :             :    cond_nd_k(2,3,iom)=cond_nd_k(2,3,iom)+acc9
    1366                 :             :    cond_nd_k(3,2,iom)=cond_nd_k(3,2,iom)+acc9
    1367                 :             :  end do
    1368                 :             :  !$OMP END TARGET DATA
    1369                 :             :  ABI_FREE(partial)
    1370                 :             : 
    1371                 :             : end subroutine conducti_paw_kg_sum_gpu
    1372                 :             : #endif
    1373                 :             : !!***
    1374                 :             : 
    1375                 :             : !----------------------------------------------------------------------
    1376                 :             : 
    1377                 :             : !!****f* m_conducti/band_block_end
    1378                 :             : !! NAME
    1379                 :             : !! band_block_end
    1380                 :             : !!
    1381                 :             : !! FUNCTION
    1382                 :             : !! Return the last band of the block of bands starting at band ib0:
    1383                 :             : !! contiguous bands treated by current proc, at most nb_blk bands.
    1384                 :             : !!
    1385                 :             : !! INPUTS
    1386                 :             : !!  distrb_k(:)=proc treating each band of the current k-point (proc_distrb)
    1387                 :             : !!  me=index of current proc
    1388                 :             : !!  ib0=first band of the block (treated by current proc)
    1389                 :             : !!  nband_k=number of bands of the current k-point
    1390                 :             : !!  nb_blk=maximum number of bands in a block
    1391                 :             : !!
    1392                 :             : !! SOURCE
    1393                 :             : 
    1394         [ -  + ]:          40 : pure integer function band_block_end(distrb_k,me,ib0,nband_k,nb_blk) result(ib1)
    1395                 :             : 
    1396                 :             : !Arguments -----------------------------------
    1397                 :             :  integer,intent(in) :: me,ib0,nband_k,nb_blk
    1398                 :             :  integer,intent(in) :: distrb_k(:)
    1399                 :             : 
    1400                 :             : ! *********************************************************************************
    1401                 :             : 
    1402                 :          40 :  ib1=ib0
    1403   [ +  +  +  + ]:         358 :  do while (ib1<nband_k.and.ib1-ib0+1<nb_blk)
    1404         [ -  + ]:         318 :    if (distrb_k(ib1+1)/=me) exit
    1405                 :          40 :    ib1=ib1+1
    1406                 :             :  end do
    1407                 :             : 
    1408                 :          40 : end function band_block_end
    1409                 :             : !!***
    1410                 :             : 
    1411                 :             : !----------------------------------------------------------------------
    1412                 :             : 
    1413                 :             : !!****f* m_conducti/count_band_blocks
    1414                 :             : !! NAME
    1415                 :             : !! count_band_blocks
    1416                 :             : !!
    1417                 :             : !! FUNCTION
    1418                 :             : !! Return the number of blocks of bands treated by current proc
    1419                 :             : !! (see band_block_end), over all k-points and spins.
    1420                 :             : !! Used to complete the collective reads of a proc with dummy reads.
    1421                 :             : !!
    1422                 :             : !! INPUTS
    1423                 :             : !!  proc_distrb(nkpt,mband,nsppol)=proc treating each band of each k-point and spin
    1424                 :             : !!  nband(nkpt*nsppol)=number of bands for each k-point and spin
    1425                 :             : !!  nkpt=number of k-points
    1426                 :             : !!  nsppol=number of spins
    1427                 :             : !!  me=index of current proc
    1428                 :             : !!  nb_blk=maximum number of bands in a block
    1429                 :             : !!
    1430                 :             : !! SOURCE
    1431                 :             : 
    1432         [ -  + ]:          16 : pure integer function count_band_blocks(proc_distrb,nband,nkpt,nsppol,me,nb_blk) result(nblocks)
    1433                 :             : 
    1434                 :             : !Arguments -----------------------------------
    1435                 :             :  integer,intent(in) :: nkpt,nsppol,me,nb_blk
    1436                 :             :  integer,intent(in) :: proc_distrb(:,:,:),nband(nkpt*nsppol)
    1437                 :             : 
    1438                 :             : !Local variables-------------------------------
    1439                 :             :  integer :: iband,ikpt,isppol,nband_k
    1440                 :             : 
    1441                 :             : ! *********************************************************************************
    1442                 :             : 
    1443                 :          16 :  nblocks=0
    1444         [ +  + ]:          32 :  do isppol=1,nsppol
    1445         [ +  + ]:          48 :    do ikpt=1,nkpt
    1446                 :          16 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
    1447                 :          16 :      iband=1
    1448         [ +  + ]:         224 :      do while (iband<=nband_k)
    1449         [ +  + ]:         208 :        if (proc_distrb(ikpt,iband,isppol)==me) then
    1450                 :          12 :          nblocks=nblocks+1
    1451                 :          12 :          iband=band_block_end(proc_distrb(ikpt,:,isppol),me,iband,nband_k,nb_blk)+1
    1452                 :             :        else
    1453                 :         180 :          iband=iband+1
    1454                 :             :        end if
    1455                 :             :      end do
    1456                 :             :    end do
    1457                 :             :  end do
    1458                 :             : 
    1459                 :          16 : end function count_band_blocks
    1460                 :             : !!***
    1461                 :             : 
    1462                 :             : !----------------------------------------------------------------------
    1463                 :             : 
    1464                 :             : !!****f* m_conducti/count_sorted
    1465                 :             : !! NAME
    1466                 :             : !! count_sorted
    1467                 :             : !!
    1468                 :             : !! FUNCTION
    1469                 :             : !! Return the number of elements of an array sorted in descending order
    1470                 :             : !! that are greater than x (strict=.true.) or greater or equal to x (strict=.false.).
    1471                 :             : !!
    1472                 :             : !! INPUTS
    1473                 :             : !!  list(:)=array sorted in descending order
    1474                 :             : !!  x=value
    1475                 :             : !!  strict=.true. to count elements >x, .false. to count elements >=x
    1476                 :             : !!
    1477                 :             : !! SOURCE
    1478                 :             : 
    1479         [ -  + ]:       20000 : pure integer function count_sorted(list,x,strict) result(nn)
    1480                 :             : 
    1481                 :             : !Arguments -----------------------------------
    1482                 :             :  logical,intent(in) :: strict
    1483                 :             :  real(dp),intent(in) :: x
    1484                 :             :  real(dp),intent(in) :: list(:)
    1485                 :             : 
    1486                 :             : !Local variables-------------------------------
    1487                 :             :  integer :: ihigh,ilow,imid
    1488                 :             :  logical :: above
    1489                 :             : 
    1490                 :             : ! *********************************************************************************
    1491                 :             : 
    1492                 :             : !Invariant: list(1:ilow) are counted, list(ihigh+1:) are not
    1493                 :       20000 :  ilow=0
    1494                 :       20000 :  ihigh=size(list)
    1495         [ +  + ]:       64825 :  do while (ilow<ihigh)
    1496                 :       44825 :    imid=(ilow+ihigh+1)/2
    1497         [ +  + ]:       44825 :    if (strict) then
    1498                 :       22022 :      above=(list(imid)>x)
    1499                 :             :    else
    1500                 :       22803 :      above=(list(imid)>=x)
    1501                 :             :    end if
    1502         [ +  + ]:       64825 :    if (above) then
    1503                 :             :      ilow=imid
    1504                 :             :    else
    1505                 :       41559 :      ihigh=imid-1
    1506                 :             :    end if
    1507                 :             :  end do
    1508                 :       20000 :  nn=ilow
    1509                 :             : 
    1510                 :       20000 : end function count_sorted
    1511                 :             : !!***
    1512                 :             : 
    1513                 :             : !----------------------------------------------------------------------
    1514                 :             : 
    1515                 :             : !!****f* m_conducti/conducti_paw_core
    1516                 :             : !! NAME
    1517                 :             : !! conducti_paw_core
    1518                 :             : !!
    1519                 :             : !! FUNCTION
    1520                 :             : !! This program computes the elements of the optical frequency dependent
    1521                 :             : !! conductivity tensor and the conductivity along the three principal axes
    1522                 :             : !! from the Kubo-Greenwood formula for PAW formalism
    1523                 :             : !!
    1524                 :             : !! INPUTS
    1525                 :             : !!  filnam=generic name for input data
    1526                 :             : !!  filnam_out=generic name for output data
    1527                 :             : !!  [with_absorption]=optiona lflag to activate the computation of absorption (_sigX file) (default=TRUE)
    1528                 :             : !!  [with_emissivity]=optiona lflag to activate the computation of emissivity (_emisX file) (default=FALSE)
    1529                 :             : !!
    1530                 :             : !! OUTPUT
    1531                 :             : !!  Only printing
    1532                 :             : !!
    1533                 :             : !! NOTES
    1534                 :             : !!  bantot
    1535                 :             : !!  dom=frequency range
    1536                 :             : !!  eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree).
    1537                 :             : !!  ecut=kinetic energy planewave cutoff (hartree).
    1538                 :             : !!  fermie= fermi energy (Hartree)
    1539                 :             : !!  mom=number of frequency for conductivity computation
    1540                 :             : !!  mband=maximum number of bands.
    1541                 :             : !!  natom = number of atoms in the unit cell.
    1542                 :             : !!  nband(nkpt*nsppol)=number of bands at each RF k point for each spin.
    1543                 :             : !!  nkpt=number of k points in the IBZ for this perturbation
    1544                 :             : !!  ngfft(3)=integer fft box dimensions.
    1545                 :             : !!  nspinor=number of spinorial components of the wavefunctions.
    1546                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized.
    1547                 :             : !!  ntypat = number of atom types.
    1548                 :             : !!  occ(mband*nkpt*nsppol)=occupation number for each band and k.
    1549                 :             : !!  occopt==option for occupancies
    1550                 :             : !!  psinablapsi2(2,3,mband,nphicor,natom)Matrix elements = <Phi_core|Nabla|Phi_i>
    1551                 :             : !!  rmet(3,3)=real space metric ($\textrm{bohr}^{2}$).sigx(mom,nphicor))
    1552                 :             : !!  rprimd(3,3)=real space primitive translations.
    1553                 :             : !!  of primitive translations.
    1554                 :             : !!  ucvol=unit cell volume in ($\textrm{bohr}^{3}$).
    1555                 :             : !!  wind=frequency window for computations of sigma
    1556                 :             : !!  wtk(nkpt)=weight assigned to each k point.
    1557                 :             : !!
    1558                 :             : !! SOURCE
    1559                 :             : 
    1560                 :          14 :  subroutine conducti_paw_core(filnam,filnam_out,with_absorption,with_emissivity)
    1561                 :             : 
    1562                 :             : !Arguments -----------------------------------
    1563                 :             : !scalars
    1564                 :             :  character(len=fnlen),intent(in) :: filnam,filnam_out
    1565                 :             :  logical,intent(in),optional :: with_absorption,with_emissivity
    1566                 :             : !Local variables-------------------------------
    1567                 :             : !scalars
    1568                 :             :  integer,parameter :: master=0
    1569                 :             :  integer :: iomode,atnbr,bantot,bdtot_index,comm,my_iband,input_atm,au_units
    1570                 :             :  integer :: ib0,ib1,my_ncalls,ncalls_max,nb_blk
    1571                 :             :  integer :: fform2,headform,iatom,iband,icor,ierr,ikpt,iatom_atnbr,itypat,itypat_atnbr
    1572                 :             :  integer :: iom,isppol,l1,mband,me,mom,mpierr,j2,etiq,pnp_size,broad_mode,absx_unt
    1573                 :             :  integer :: natom,nband_k,nkpt,nphicor,nproc,nspinor,nsppol,ntypat,nphicor_max,natom_atnbr
    1574                 :             :  integer :: occopt,iunt,opt2_unt,ncid,varid,master_band,nb_per_proc,idum,nbuf,nbuf_max
    1575                 :             :  integer :: sigx1_unt,sigx1_up_unt,sigx1_dn_unt,ems_unt,ems_up_unt,ems_dn_unt
    1576                 :             :  logical :: iomode_estf_mpiio,myband,mykpt,need_absorption,need_emissivity
    1577                 :             :  real(dp) :: del_sig,del_emis,deltae,ecut,fermie
    1578                 :             :  real(dp) :: omin,omax,omin_sig,omax_sig,omin_emis,omax_emis
    1579                 :             :  real(dp) :: dom,dom_ctr,dom_max,dom_tan1,dom_tan2,dhdk2_g
    1580                 :             :  real(dp) :: Tatm,tsmear,ucvol
    1581                 :             :  character(len=fnlen) :: filnam2,filnam_gen
    1582                 :             :  character(len=500) :: msg
    1583                 :             :  character(len=100) :: line
    1584                 :             :  character(len=20) :: str_atm
    1585                 :          14 :  type(hdr_type) :: hdr
    1586                 :          14 :  type(MPI_type) :: mpi_enreg
    1587                 :             : !arrays
    1588                 :             :  integer :: nc_count(6),nc_start(6),nc_stride(6)
    1589                 :          14 :  integer,allocatable :: nband(:),ncor(:,:),lcor(:,:),kappacor(:,:),typat(:),iatom_list(:)
    1590                 :             :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3),dummy(0,0,0,0,0),tsec(2)
    1591                 :          14 :  real(dp),allocatable :: dom_var1(:,:),buf_eig(:),buf_wabs(:,:,:),buf_wemis(:,:,:),abs_diff_occ(:)
    1592                 :          14 :  real(dp),allocatable :: eig0_k(:),eigen0(:),eig0nc(:,:,:)
    1593                 :          14 :  real(dp),allocatable :: energy_cor(:,:),edge(:),nphicor_arr(:),occ_cor(:,:),maxocc_cor(:,:)
    1594                 :          14 :  real(dp),allocatable :: occ(:),occ_k(:),wtk(:)
    1595                 :          14 :  real(dp),allocatable :: oml_edge(:,:),oml_emis(:,:)
    1596                 :          14 :  real(dp),allocatable :: psinablapsi2(:,:,:,:)
    1597                 :          14 :  real(dp),allocatable :: sigx1(:,:,:,:),sigx1_av(:,:,:),sigx1_k(:,:,:)
    1598                 :          14 :  real(dp),allocatable :: sum_spin_sigx1(:,:,:),sum_spin_sigx1_av(:,:)
    1599                 :          14 :  real(dp),allocatable :: emisx(:,:,:,:),emisx_av(:,:,:),emisx_k(:,:,:)
    1600                 :          14 :  real(dp),allocatable :: sum_spin_emisx(:,:,:),sum_spin_emisx_av(:,:)
    1601                 :             : 
    1602                 :             : ! *********************************************************************************
    1603                 :             : !optional flags
    1604         [ +  - ]:          14 :  need_absorption=.true. ;if (present(with_absorption)) need_absorption=with_absorption
    1605         [ +  + ]:          14 :  need_emissivity=.false.;if (present(with_emissivity)) need_emissivity=with_emissivity
    1606         [ +  - ]:          14 :  if ((.not.need_absorption).and.(.not.need_emissivity)) return
    1607                 :             : 
    1608                 :          14 :  call timab(1187,1,tsec)
    1609                 :             :  ABI_NVTX_START_RANGE(NVTX_CONDUCTI_PAW_CORE)
    1610                 :             : 
    1611                 :             : #if defined(HAVE_GPU_MARKERS)
    1612                 :             :  call nvtxStartRange("core_read_input")
    1613                 :             : #endif
    1614                 :             : ! ---------------------------------------------------------------------------------
    1615                 :             : ! Read input data
    1616                 :             : 
    1617                 :             : !Global MPI communicators
    1618                 :          14 :  comm = xmpi_world
    1619                 :          14 :  nproc = xmpi_comm_size(comm)
    1620                 :          14 :  me = xmpi_comm_rank(comm)
    1621                 :             : 
    1622                 :             : !Read input parameters file
    1623         [ +  + ]:          14 :  if (me==master) then
    1624         [ -  + ]:           8 :    if (open_file(filnam,msg,newunit=iunt,form='formatted',action="read",status="old")/=0) then
    1625                 :           0 :      ABI_ERROR(msg)
    1626                 :             :    end if
    1627                 :           8 :    rewind(iunt)
    1628                 :           8 :    read(iunt,*)
    1629                 :           8 :    read(iunt,'(a)')filnam_gen ! Generic name for the files
    1630         [ +  - ]:           8 :    filnam2=trim(filnam_gen)//'_OPT2'
    1631                 :             : !  Read frequency range
    1632         [ +  - ]:           8 :    if (need_absorption) then
    1633                 :           8 :      read(iunt,fmt='(a)') line
    1634         [ +  + ]:           8 :      read(line,end=11,fmt=*) dom,omin,omax,mom,input_atm,dom_max,dom_ctr
    1635                 :           7 :      goto 12
    1636                 :           1 : 11   read(line,fmt=*) dom,omin,omax,mom,input_atm ; dom_max=zero ; dom_ctr=zero
    1637                 :             : 12   continue
    1638         [ #  # ]:           0 :    else if (need_emissivity) then
    1639                 :           0 :      read(iunt,*) dom,omin,omax,mom,input_atm
    1640                 :           0 :      dom_max=zero;dom_ctr=zero
    1641                 :             :    end if
    1642         [ +  + ]:           8 :    read(iunt,end=13,err=13,fmt=*) broad_mode,au_units
    1643                 :           1 :    goto 14
    1644                 :           7 : 13 broad_mode=1 ; au_units=0
    1645                 :             : 14 continue
    1646                 :           8 :    close(iunt)
    1647   [ +  +  -  + ]:           8 :    if (abs(dom_max)>tol10.and.dom_max<dom) then
    1648                 :           0 :      msg = 'dom_max must be higher than dom!'
    1649                 :           0 :      ABI_ERROR(msg)
    1650                 :             :    end if
    1651                 :             :  end if
    1652                 :             : 
    1653                 :             : !Send data to all procs
    1654                 :          14 :  call xmpi_bcast(dom,master,comm,mpierr)
    1655                 :          14 :  call xmpi_bcast(omin,master,comm,mpierr)
    1656                 :          14 :  call xmpi_bcast(omax,master,comm,mpierr)
    1657                 :          14 :  call xmpi_bcast(mom,master,comm,mpierr)
    1658                 :          14 :  call xmpi_bcast(input_atm,master,comm,mpierr)
    1659                 :          14 :  call xmpi_bcast(dom_max,master,comm,mpierr)
    1660                 :          14 :  call xmpi_bcast(dom_ctr,master,comm,mpierr)
    1661                 :          14 :  call xmpi_bcast(broad_mode,master,comm,mpierr)
    1662                 :          14 :  call xmpi_bcast(au_units,master,comm,mpierr)
    1663                 :             : 
    1664                 :             : 
    1665                 :             : ! ---------------------------------------------------------------------------------
    1666                 :             : ! Read OPT2 file
    1667                 :             : 
    1668                 :             : !Check for FORTRAN/.nc OPT2 file and set iomode to IO_MODE_FORTRAN_MASTER/IO_MODE_ETSF
    1669         [ +  + ]:          14 :  if (me==master) then
    1670                 :           8 :    call nctk_fort_or_ncfile(filnam2,iomode,msg)
    1671         [ -  + ]:           8 :    if (iomode/=IO_MODE_ETSF) iomode=IO_MODE_FORTRAN_MASTER
    1672                 :             :  end if
    1673                 :          14 :  call xmpi_bcast(filnam2,master,comm,mpierr)
    1674                 :          14 :  call xmpi_bcast(iomode,master,comm,mpierr)
    1675                 :             : 
    1676                 :             : !Open OPT2 file and read HEADER
    1677         [ +  + ]:          14 :  if (me==master) then
    1678         [ +  - ]:           8 :    if (iomode==IO_MODE_ETSF) then
    1679         [ -  + ]:           8 :      NCF_CHECK(nctk_open_read(ncid,filnam2,xmpi_comm_self))
    1680                 :           8 :      call hdr%ncread(ncid,fform2)
    1681                 :             :    else
    1682         [ #  # ]:           0 :      if (open_file(filnam2,msg,newunit=opt2_unt,form="unformatted",status="old")/=0) then
    1683                 :           0 :        ABI_ERROR(msg)
    1684                 :             :      end if
    1685                 :           0 :      call hdr%fort_read(opt2_unt,fform2,rewind=.true.)
    1686                 :             :    end if
    1687         [ -  + ]:           8 :    ABI_CHECK(fform2/=0,sjoin("Error while reading ",filnam2))
    1688         [ -  + ]:           8 :    ABI_CHECK(fform2==611.or.fform2==612.or.fform2==613,"OPT2 file format should be fform=611/612/613!")
    1689                 :             :  end if
    1690                 :          14 :  call hdr%bcast(master,me,comm)
    1691                 :          14 :  call xmpi_bcast(fform2,master,comm,mpierr)
    1692                 :             : 
    1693                 :             : !Extract info from the header
    1694                 :          14 :  headform=hdr%headform
    1695                 :          14 :  bantot=hdr%bantot
    1696                 :          14 :  ecut=hdr%ecut_eff
    1697                 :          14 :  natom=hdr%natom
    1698                 :          14 :  nkpt=hdr%nkpt
    1699                 :          14 :  nspinor=hdr%nspinor
    1700                 :          14 :  nsppol=hdr%nsppol
    1701                 :          14 :  ntypat=hdr%ntypat
    1702   [ -  +  +  -  :          42 :  ABI_MALLOC(typat,(natom))
          +  -  +  -  -  
                +  -  + ]
    1703   [ +  -  -  +  :          77 :  typat = hdr%typat
          -  -  -  -  +  
                      + ]
    1704                 :             :  occopt=hdr%occopt
    1705   [ +  +  +  + ]:         182 :  rprimd(:,:)=hdr%rprimd(:,:)
    1706                 :          14 :  fermie=hdr%fermie
    1707                 :          14 :  tsmear=hdr%tsmear
    1708   [ -  +  +  -  :          42 :  ABI_MALLOC(nband,(nkpt*nsppol))
          +  -  +  -  -  
                +  -  + ]
    1709   [ -  +  +  -  :          42 :  ABI_MALLOC(occ,(bantot))
          +  -  +  -  -  
                +  -  + ]
    1710   [ -  +  +  -  :          42 :  ABI_MALLOC(wtk,(nkpt))
          +  -  +  -  -  
                +  -  + ]
    1711         [ +  + ]:         258 :  occ(1:bantot)=hdr%occ(1:bantot)
    1712         [ +  + ]:          30 :  wtk(1:nkpt)=hdr%wtk(1:nkpt)
    1713         [ +  + ]:          30 :  nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol)
    1714         [ +  + ]:          30 :  mband=maxval(nband(:))  ! Get mband, as the maximum value of nband(nkpt)
    1715                 :          14 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) ! Get metrics of simulation cell
    1716                 :          14 :  itypat_atnbr=typat(input_atm)
    1717                 :          14 :  natom_atnbr=0
    1718         [ +  + ]:          63 :  do iatom=1,natom
    1719         [ +  + ]:          49 :    if(typat(iatom)==itypat_atnbr) natom_atnbr=natom_atnbr+1
    1720         [ +  + ]:          63 :    if(iatom==input_atm) atnbr=natom_atnbr
    1721                 :             :  enddo
    1722                 :             : 
    1723                 :             : !Read eigenvalues
    1724   [ -  +  +  -  :          42 :  ABI_MALLOC(eigen0,(mband*nkpt*nsppol))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1725         [ +  + ]:          14 :  if (me==master) then
    1726         [ +  - ]:           8 :    if (iomode==IO_MODE_ETSF) then
    1727                 :           8 :      varid=nctk_idname(ncid,"eigenvalues")
    1728   [ -  +  +  -  :          40 :      ABI_MALLOC(eig0nc,(mband,nkpt,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1729         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,eig0nc))
    1730   [ +  +  +  -  :          16 :      eigen0 = reshape(eig0nc,[mband*nkpt*nsppol])
                   +  - ]
    1731         [ -  + ]:           8 :      ABI_FREE(eig0nc)
    1732                 :             :    else
    1733                 :           0 :      read(opt2_unt)(eigen0(iband),iband=1,mband*nkpt*nsppol)
    1734                 :             :    end if
    1735                 :             :  end if
    1736                 :          14 :  call xmpi_bcast(eigen0,master,comm,mpierr)
    1737                 :             : 
    1738                 :             : !Read core states
    1739         [ +  + ]:          14 :  if (me==master) then
    1740         [ +  - ]:           8 :    if (iomode==IO_MODE_ETSF) then
    1741         [ -  + ]:           8 :      NCF_CHECK(nctk_get_dim(ncid,"max_number_of_core_states",nphicor_max))
    1742                 :             :    else
    1743                 :           0 :      read(opt2_unt) nphicor_max
    1744                 :             :    end if
    1745                 :             :   end if
    1746                 :          14 :  call xmpi_bcast(nphicor_max,master,comm,mpierr)
    1747                 :             : 
    1748   [ -  +  +  -  :          56 :  ABI_MALLOC(ncor,(nphicor_max,ntypat))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1749   [ -  +  +  -  :          56 :  ABI_MALLOC(occ_cor,(nphicor_max,ntypat))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1750   [ -  +  +  -  :          42 :  ABI_MALLOC(maxocc_cor,(nphicor_max,ntypat))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1751   [ -  +  +  -  :          42 :  ABI_MALLOC(lcor,(nphicor_max,ntypat))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1752   [ -  +  +  -  :          42 :  ABI_MALLOC(kappacor,(nphicor_max,ntypat))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1753   [ -  +  +  -  :          42 :  ABI_MALLOC(energy_cor,(nphicor_max,ntypat))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1754                 :             : 
    1755         [ +  + ]:          14 :  if (me==master) then
    1756   [ -  +  +  -  :          24 :    ABI_MALLOC(nphicor_arr,(ntypat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1757         [ +  - ]:           8 :    if (iomode==IO_MODE_ETSF) then
    1758                 :           8 :      varid=nctk_idname(ncid,"n_quantum_number_core")
    1759         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,ncor))
    1760                 :           8 :      varid=nctk_idname(ncid,"l_quantum_number_core")
    1761         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,lcor))
    1762                 :           8 :      varid=nctk_idname(ncid,"kappa_core")
    1763         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,kappacor))
    1764                 :           8 :      varid=nctk_idname(ncid,"eigenvalues_core")
    1765         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,energy_cor))
    1766                 :           8 :      varid=nctk_idname(ncid,"occupation_core")
    1767         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,occ_cor))
    1768                 :           8 :      varid=nctk_idname(ncid,"max_occupation_core")
    1769         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,maxocc_cor))
    1770                 :           8 :      varid=nctk_idname(ncid,"number_of_core_states")
    1771         [ -  + ]:           8 :      NCF_CHECK(nf90_get_var(ncid,varid,nphicor_arr))
    1772                 :             : !Close here netcdf file here because the rest has to be read with collective I/O
    1773         [ -  + ]:           8 :      NCF_CHECK(nf90_close(ncid))
    1774                 :             :    else
    1775         [ #  # ]:           0 :      do itypat=1,ntypat
    1776                 :           0 :        read(unit=opt2_unt) nphicor_arr(itypat)
    1777         [ #  # ]:           0 :        do icor=1,nphicor_max
    1778                 :           0 :          read(unit=opt2_unt,fmt='(a)') line
    1779                 :           0 :          read(line,end=23,fmt=*) ncor(icor,itypat),lcor(icor,itypat),kappacor(icor,itypat),occ_cor(icor,itypat),maxocc_cor(icor,itypat),&
    1780         [ #  # ]:           0 :           energy_cor(icor,itypat)
    1781                 :           0 :          goto 24
    1782                 :           0 : 23       read(line,fmt=*) ncor(icor,itypat),lcor(icor,itypat),energy_cor(icor,itypat)
    1783                 :           0 :          kappacor(icor,itypat)=0
    1784                 :           0 :          occ_cor(icor,itypat)=one
    1785                 :           0 :          maxocc_cor(icor,itypat)=one
    1786                 :           0 : 24       continue
    1787                 :             :        enddo
    1788                 :             :      end do
    1789                 :             :    end if
    1790                 :           8 :    nphicor=nphicor_arr(itypat_atnbr)
    1791                 :           8 :    ABI_FREE(nphicor_arr)
    1792                 :             :  end if ! master
    1793                 :          14 :  call xmpi_bcast(ncor,master,comm,mpierr)
    1794                 :          14 :  call xmpi_bcast(lcor,master,comm,mpierr)
    1795                 :          14 :  call xmpi_bcast(kappacor,master,comm,mpierr)
    1796                 :          14 :  call xmpi_bcast(energy_cor,master,comm,mpierr)
    1797                 :          14 :  call xmpi_bcast(occ_cor,master,comm,mpierr)
    1798                 :          14 :  call xmpi_bcast(maxocc_cor,master,comm,mpierr)
    1799                 :          14 :  call xmpi_bcast(nphicor,master,comm,mpierr)
    1800                 :             : 
    1801   [ -  +  +  -  :          42 :  ABI_MALLOC(edge,(nphicor))
          +  -  +  -  -  
                +  -  + ]
    1802         [ +  + ]:          62 :  edge(1:nphicor)=fermie-energy_cor(1:nphicor,itypat_atnbr)
    1803                 :             : #if defined(HAVE_GPU_MARKERS)
    1804                 :             :  call nvtxEndRange()
    1805                 :             : #endif
    1806                 :             : #if defined(HAVE_GPU_MARKERS)
    1807                 :             :  call nvtxStartRange("core_pre_spinkpt_loop")
    1808                 :             : #endif
    1809                 :             : !---------------------------------------------------------------------------------
    1810                 :             : ! Prepare kpt/band parallelization
    1811                 :             : 
    1812                 :          14 :  call init_mpi_enreg(mpi_enreg)
    1813                 :          14 :  mpi_enreg%comm_kpt=comm
    1814                 :          14 :  mpi_enreg%me_kpt=me
    1815                 :          14 :  mpi_enreg%nproc_spkpt=nproc
    1816                 :          14 :  mpi_enreg%paralbd=1
    1817   [ -  +  +  -  :          70 :  ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt,mband,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1818   [ -  +  +  -  :          42 :  ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1819                 :          14 :  call distrb2(mband,nb_per_proc,nband,nkpt,nproc,nsppol,mpi_enreg)
    1820                 :          14 :  call initmpi_band(nkpt,mpi_enreg,nband,nkpt,nsppol)
    1821                 :             : !---------------------------------------------------------------------------------
    1822                 :             : !Print some data
    1823                 :          14 :  Tatm=tsmear*Ha_K
    1824         [ +  + ]:          14 :  if (me==master) then
    1825                 :           8 :    write(std_out,*)
    1826                 :           8 :    write(std_out,'(a)')'--------------------------------------------'
    1827                 :           8 :    write(std_out,'(a,i4)') 'selected atom for X ray emission',input_atm
    1828                 :           8 :    write(std_out,'(a)')'--------------------------------------------'
    1829         [ +  - ]:           8 :    if (need_absorption) then
    1830         [ +  + ]:           8 :      if (abs(dom_max)>tol10) then
    1831                 :           1 :        write(std_out,'(a)')'************************ ARCTAN SMEARING'
    1832                 :           1 :        write(std_out,'(a,i8,3f10.5,a)')' npts,omin,omax,width      =',mom,omin,omax,dom,' Ha'
    1833                 :           1 :        write(std_out,'(a,2f10.5,a)')' dom_max,center       =',dom_max,dom_ctr,' Ha'
    1834                 :             :      else
    1835                 :           7 :        write(std_out,'(a)')'************************ FIXED SMEARING'
    1836                 :           7 :        write(std_out,'(a,i8,3f10.5,a)')' npts,omin,omax,width      =',mom,omin,omax,dom,' Ha'
    1837                 :             :      endif
    1838                 :             :    end if
    1839                 :           8 :    write(std_out,*)
    1840                 :           8 :    write(std_out,'(a,3f10.5,a)' )' rprimd(bohr)      =',rprimd(1,1:3)
    1841                 :           8 :    write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(2,1:3)
    1842                 :           8 :    write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(3,1:3)
    1843                 :           8 :    write(std_out,'(a,i8)')       ' natom             =',natom
    1844                 :           8 :    write(std_out,'(a,3i8)')      ' nkpt,mband,nsppol        =',nkpt,mband,nsppol
    1845                 :           8 :    write(std_out, '(a, f10.5,a)' ) ' ecut              =',ecut,' Ha'
    1846                 :           8 :    write(std_out,'(a,f10.5,a,f10.5,a)' )' fermie            =',fermie,' Ha',fermie*Ha_eV,' eV'
    1847                 :           8 :    write(std_out,'(a,f12.5,a,f12.5,a)') ' Temp              =',tsmear,' Ha ',Tatm,' Kelvin'
    1848                 :           8 :    write(std_out,*)
    1849                 :           8 :    write(std_out,*)
    1850                 :           8 :    write(std_out,'(a)')'--------------------------------------------'
    1851                 :           8 :    write(std_out,'(a,i4)') ' Number of core orbitals nc=',nphicor
    1852         [ +  + ]:          35 :    do icor=1,nphicor
    1853         [ +  + ]:          35 :      if (kappacor(icor,itypat_atnbr)==0) then
    1854                 :          15 :        write(std_out,'(a,2i4,5f15.5)') ' n, l, occ, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ', &
    1855                 :          15 :          ncor(icor,itypat_atnbr),lcor(icor,itypat_atnbr),occ_cor(icor,itypat_atnbr),&
    1856                 :          15 : &        energy_cor(icor,itypat_atnbr),edge(icor),&
    1857                 :          30 : &        energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    1858                 :             :      else
    1859         [ +  + ]:          12 :        if (kappacor(icor,itypat_atnbr)>0) then
    1860                 :           3 :          j2=2*lcor(icor,itypat_atnbr)-1
    1861                 :           3 :          write(std_out,'(a,i4,i4,a,i4,5f15.5)') ' n, j, l, occ, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ',&
    1862                 :           3 : &          ncor(icor,itypat_atnbr),j2,' / 2',lcor(icor,itypat_atnbr),occ_cor(icor,itypat_atnbr),&
    1863                 :           3 : &          energy_cor(icor,itypat_atnbr),edge(icor),&
    1864                 :           6 : &          energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    1865                 :             :        else
    1866         [ +  + ]:           9 :          if (kappacor(icor,itypat_atnbr)<-1) then
    1867                 :           3 :            j2=2*lcor(icor,itypat_atnbr)+1
    1868                 :           3 :            write(std_out,'(a,i4,i4,a,i4,5f15.5)') ' n, j, l, occ, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ',&
    1869                 :           3 : &            ncor(icor,itypat_atnbr),j2,'/2',lcor(icor,itypat_atnbr),occ_cor(icor,itypat_atnbr),&
    1870                 :           3 : &            energy_cor(icor,itypat_atnbr),edge(icor),&
    1871                 :           6 : &            energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    1872                 :             :          else
    1873                 :           6 :            write(std_out,'(a,i4,a,i4,5f15.5)') ' n, j, l, occ, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ',&
    1874                 :           6 : &            ncor(icor,itypat_atnbr),'   1/2',lcor(icor,itypat_atnbr),occ_cor(icor,itypat_atnbr),&
    1875                 :           6 : &            energy_cor(icor,itypat_atnbr),edge(icor),&
    1876                 :          12 : &            energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    1877                 :             :          end if
    1878                 :             :        end if
    1879                 :             :      end if
    1880                 :             :    end do
    1881                 :           8 :    write(std_out,'(a)')'--------------------------------------------'
    1882                 :             :  end if ! master
    1883                 :             : 
    1884                 :             : !---------------------------------------------------------------------------------
    1885                 :             : ! Determine the frequency range and allocate frequency-dependent arrays
    1886         [ +  - ]:          14 :  if (need_absorption) then
    1887   [ -  +  +  -  :          56 :    ABI_MALLOC(oml_edge,(nphicor,mom))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1888   [ -  +  +  -  :          42 :    ABI_MALLOC(dom_var1,(nphicor,mom))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1889                 :          14 :    omax_sig=omax ; omin_sig=omin
    1890                 :          14 :    del_sig=(omax_sig-omin_sig)/(mom-1)
    1891         [ +  + ]:       14014 :    do iom=1,mom
    1892         [ +  + ]:       62014 :      do icor=1,nphicor
    1893                 :       48000 :        oml_edge(icor,iom)=-energy_cor(icor,itypat_atnbr)+ dble(iom-1)*del_sig + omin_sig -one
    1894   [ +  +  +  + ]:       62000 :        if ((oml_edge(icor,iom)<=edge(icor)).or.(abs(dom_max)<=tol10)) then
    1895                 :       45048 :          dom_var1(icor,iom)= dom
    1896                 :             :        else
    1897                 :        2952 :          dom_tan1= (oml_edge(icor,iom)-edge(icor))/dom_ctr
    1898                 :        2952 :          dom_tan2=dom_tan1-one/dom_tan1**2
    1899                 :        2952 :          dom_var1(icor,iom)=dom+dom_max*(half+piinv*datan(dom_tan2))
    1900                 :             :        endif
    1901                 :             :      enddo
    1902                 :             :    enddo
    1903   [ -  +  +  -  :          84 :    ABI_MALLOC(sigx1,(nphicor,mom,natom_atnbr,nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
    1904   [ +  +  +  +  :      209075 :    sigx1=zero
             +  +  +  + ]
    1905                 :             :  end if
    1906                 :             : 
    1907         [ +  + ]:          14 :  if (need_emissivity) then
    1908   [ -  +  +  -  :          48 :    ABI_MALLOC(oml_emis,(nphicor,mom))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1909   [ +  -  -  +  :         228 :    omin_emis=minval(eigen0)
             -  -  +  + ]
    1910   [ +  -  -  +  :         228 :    omax_emis=maxval(eigen0)
             -  -  +  + ]
    1911                 :          12 :    del_emis=(omax_emis-omin_emis)/(mom-1)
    1912         [ +  + ]:       12012 :    do iom=1,mom
    1913         [ +  + ]:       52012 :      do icor=1,nphicor
    1914                 :       52000 :        oml_emis(icor,iom)=omin_emis+dble(iom-1)*del_emis!-energy_cor(icor,itypat_atnbr)
    1915                 :             :      enddo
    1916                 :             :    end do
    1917   [ -  +  +  -  :          72 :    ABI_MALLOC(emisx,(nphicor,mom,natom_atnbr,nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
    1918   [ +  +  +  +  :      184066 :    emisx=zero
             +  +  +  + ]
    1919                 :             :  end if
    1920                 :             : 
    1921                 :             : #if defined(HAVE_GPU_MARKERS)
    1922                 :             :  call nvtxStartRange("core_prepare_netcdf")
    1923                 :             : #endif
    1924                 :             : !---------------------------------------------------------------------------------
    1925                 :             : ! Prepare core-valence dipoles reading
    1926                 :             : 
    1927   [ +  -  -  + ]:          14 :  iomode_estf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio)
    1928                 :             : 
    1929                 :             :  !In case of netCDF access to OPT file, prepare collective I/O
    1930         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
    1931         [ +  - ]:          14 :    if (iomode_estf_mpiio) then
    1932         [ -  + ]:          14 :      NCF_CHECK(nctk_open_read(ncid,filnam2,comm))
    1933                 :          14 :      varid=nctk_idname(ncid,"dipole_core_valence")
    1934                 :             :      !Dipoles are read by blocks of (at most nb_blk) contiguous bands of the current proc
    1935                 :             :      !  (nb_per_proc is the max number of bands of a k-point treated by a proc)
    1936                 :          14 :      nb_blk=int(dipoles_blk_mem/(24._dp*real(nphicor_max*natom,dp)))
    1937                 :          14 :      nb_blk=max(1,min(nb_blk,nb_per_proc,mband))
    1938         [ +  + ]:          14 :      if (nproc>1) then
    1939         [ -  + ]:           8 :        NCF_CHECK(nctk_set_collective(ncid,varid))
    1940                 :             :        !Count the reads of current proc, to complete them with dummy collective reads
    1941                 :           8 :        my_ncalls=count_band_blocks(mpi_enreg%proc_distrb,nband,nkpt,nsppol,me,nb_blk)
    1942                 :           8 :        call xmpi_max(my_ncalls,ncalls_max,comm,ierr)
    1943                 :             :      end if
    1944         [ #  # ]:           0 :    else if (me==master) then
    1945         [ #  # ]:           0 :      NCF_CHECK(nctk_open_read(ncid,filnam2,xmpi_comm_self))
    1946                 :           0 :      varid=nctk_idname(ncid,"dipole_core_valence")
    1947                 :             :      !if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then
    1948                 :             :      !  NCF_CHECK(nctk_set_collective(ncid,varid))
    1949                 :             :      !end if
    1950                 :             :    end if
    1951                 :             :  end if
    1952                 :             : 
    1953         [ +  - ]:          14 :  if (iomode_estf_mpiio) then
    1954                 :             :    !If MPI-IO, store only the elements of a block of nb_blk bands
    1955   [ -  +  +  -  :          70 :    ABI_MALLOC(psinablapsi2,(3,nphicor_max,natom,nb_blk))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1956                 :             :  else
    1957                 :             :    !If not, store the elements for all bands
    1958   [ #  #  #  #  :           0 :    ABI_MALLOC(psinablapsi2,(3,nphicor_max,natom,mband))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1959                 :             :  end if
    1960         [ +  + ]:          70 :  pnp_size=size(psinablapsi2)
    1961                 :             : #if defined(HAVE_GPU_MARKERS)
    1962                 :             :  call nvtxEndRange()
    1963                 :             : #endif
    1964                 :             : !---------------------------------------------------------------------------------
    1965                 :             : ! Compute X absorption coefficient and/or X emissivity
    1966                 :             : 
    1967         [ +  - ]:          14 :  if (need_absorption) then
    1968   [ -  +  +  -  :          70 :    ABI_MALLOC(sigx1_k,(nphicor,mom,natom_atnbr))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    1969                 :             :  end if
    1970         [ +  + ]:          14 :  if (need_emissivity) then
    1971   [ -  +  +  -  :          60 :    ABI_MALLOC(emisx_k,(nphicor,mom,natom_atnbr))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    1972                 :             :  end if
    1973                 :             : 
    1974                 :             : !List of the atoms of the selected type
    1975   [ -  +  +  -  :          42 :  ABI_MALLOC(iatom_list,(natom_atnbr))
          +  -  +  -  -  
                +  -  + ]
    1976                 :          14 :  iatom_atnbr=0
    1977         [ +  + ]:          63 :  do iatom=1,natom
    1978         [ +  + ]:          63 :    if (typat(iatom)==itypat_atnbr) then
    1979                 :          47 :      iatom_atnbr=iatom_atnbr+1
    1980                 :          47 :      iatom_list(iatom_atnbr)=iatom
    1981                 :             :    end if
    1982                 :             :  end do
    1983                 :             : 
    1984                 :             : !Buffer of bands: eigenvalue and weights for each core state and atom
    1985                 :             : !  (weights include pi/ucvol and occupations, not the 1/omega factor)
    1986                 :             : !  Contributions are computed when the buffer is full, see conducti_paw_core_sum
    1987                 :          14 :  nbuf_max=min(core_bands_blk,mband)
    1988   [ -  +  +  -  :          42 :  ABI_MALLOC(buf_eig,(nbuf_max))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1989         [ +  - ]:          14 :  if (need_absorption) then
    1990   [ -  +  +  -  :          70 :    ABI_MALLOC(buf_wabs,(nbuf_max,nphicor,natom_atnbr))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1991                 :             :  end if
    1992         [ +  + ]:          14 :  if (need_emissivity) then
    1993   [ -  +  +  -  :          60 :    ABI_MALLOC(buf_wemis,(nbuf_max,nphicor,natom_atnbr))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1994                 :             :  end if
    1995   [ -  +  +  -  :          42 :  ABI_MALLOC(abs_diff_occ,(nphicor))
          +  -  +  -  -  
                +  -  + ]
    1996                 :             : 
    1997                 :          14 :  deltae  = zero
    1998                 :             : 
    1999                 :             : #if defined(HAVE_GPU_MARKERS)
    2000                 :             :  call nvtxEndRange()
    2001                 :             : #endif
    2002                 :             : !LOOP OVER SPINS/K
    2003                 :          14 :  bdtot_index = 0
    2004         [ +  + ]:          28 :  do isppol=1,nsppol
    2005         [ +  + ]:          44 :    do ikpt=1,nkpt
    2006                 :             : #if defined(HAVE_GPU_MARKERS)
    2007                 :             :      call nvtxStartRange("core_k-point step")
    2008                 :             : #endif
    2009                 :          16 :      etiq=ikpt+(isppol-1)*nkpt
    2010                 :          16 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
    2011                 :          16 :      mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me))
    2012         [ +  + ]:         260 :      master_band=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol))
    2013                 :             : #if defined(HAVE_GPU_MARKERS)
    2014                 :             :      call nvtxStartRange("core_read_dipoles")
    2015                 :             : #endif
    2016                 :             : !    In case of non MPI-IO, has to read all (n,m) dipoles for this k-point
    2017                 :             : !      Master node reads and send to relevant processor
    2018   [ -  +  -  - ]:          16 :      if (.not.iomode_estf_mpiio.and.me==master) then
    2019         [ #  # ]:           0 :        if (iomode==IO_MODE_ETSF) then
    2020         [ #  # ]:           0 :          nc_start=[1,1,1,1,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    2021         [ #  # ]:           0 :          nc_count=[3,nphicor_max,natom,mband,1,1]
    2022         [ #  # ]:           0 :          NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    2023                 :             :        else
    2024   [ #  #  #  #  :           0 :          psinablapsi2=zero
             #  #  #  # ]
    2025         [ #  # ]:           0 :          if (fform2==612) then ! New OPT2 file format
    2026                 :           0 :            read(opt2_unt) (((psinablapsi2(1,icor,iatom,iband),icor=1,nphicor_max),iatom=1,natom),iband=1,nband_k)
    2027                 :           0 :            read(opt2_unt) (((psinablapsi2(2,icor,iatom,iband),icor=1,nphicor_max),iatom=1,natom),iband=1,nband_k)
    2028                 :           0 :            read(opt2_unt) (((psinablapsi2(3,icor,iatom,iband),icor=1,nphicor_max),iatom=1,natom),iband=1,nband_k)
    2029         [ #  # ]:           0 :          else if (fform2==613) then ! Large OPT2 file format
    2030         [ #  # ]:           0 :            do iband=1,nband_k
    2031                 :           0 :              read(opt2_unt) ((psinablapsi2(1,icor,iatom,iband),icor=1,nphicor_max),iatom=1,natom)
    2032                 :           0 :              read(opt2_unt) ((psinablapsi2(2,icor,iatom,iband),icor=1,nphicor_max),iatom=1,natom)
    2033                 :           0 :              read(opt2_unt) ((psinablapsi2(3,icor,iatom,iband),icor=1,nphicor_max),iatom=1,natom)
    2034                 :             :            end do
    2035                 :             :          else
    2036                 :             :            !The old writing was not efficient (indexes order is bad)
    2037         [ #  # ]:           0 :            do iatom=1,natom
    2038   [ #  #  #  # ]:           0 :              read(opt2_unt) ((psinablapsi2(1,icor,iatom,iband),iband=1,nband_k),icor=1,nphicor_max)
    2039   [ #  #  #  # ]:           0 :              read(opt2_unt) ((psinablapsi2(2,icor,iatom,iband),iband=1,nband_k),icor=1,nphicor_max)
    2040   [ #  #  #  # ]:           0 :              read(opt2_unt) ((psinablapsi2(3,icor,iatom,iband),iband=1,nband_k),icor=1,nphicor_max)
    2041                 :             :            end do
    2042                 :             :          end if
    2043                 :             :        end if
    2044         [ #  # ]:           0 :        if (.not.mykpt) then
    2045                 :           0 :          call xmpi_exch(psinablapsi2,pnp_size,master,psinablapsi2,master_band,comm,etiq,ierr)
    2046                 :             :        end if
    2047                 :             :      end if
    2048                 :             : #if defined(HAVE_GPU_MARKERS)
    2049                 :             :      call nvtxEndRange()
    2050                 :             : #endif
    2051                 :             : !!    Select k-points for current proc
    2052         [ +  + ]:          16 :      if (mykpt) then
    2053                 :             : 
    2054   [ -  +  +  -  :          42 :        ABI_MALLOC(eig0_k,(nband_k))
          +  -  +  -  -  
                +  -  + ]
    2055   [ -  +  +  -  :          28 :        ABI_MALLOC(occ_k,(nband_k))
             -  +  -  + ]
    2056                 :             : 
    2057   [ +  -  +  +  :      185055 :        if (need_absorption) sigx1_k=zero
             +  +  +  + ]
    2058   [ +  +  +  +  :      160050 :        if (need_emissivity) emisx_k=zero
             +  +  +  + ]
    2059                 :          14 :        nbuf=0
    2060                 :          14 :        ib0=1
    2061                 :          14 :        ib1=0
    2062                 :             : 
    2063                 :             : !      k-dependent data
    2064         [ +  + ]:         238 :        eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
    2065         [ +  + ]:         238 :        occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
    2066                 :             : 
    2067                 :             : #if defined(HAVE_GPU_MARKERS)
    2068                 :             :        call nvtxStartRange("core_dist_dipoles")
    2069                 :             : #endif
    2070                 :             : !      In case of non MPI-IO, receive all (n,m) dipoles from master proc
    2071                 :             : !        Then broadcast them to all band processors
    2072         [ -  + ]:          14 :        if (.not.iomode_estf_mpiio) then
    2073   [ #  #  #  # ]:           0 :          if (me/=master.and.me==master_band) then
    2074                 :           0 :            call xmpi_exch(psinablapsi2,pnp_size,master,psinablapsi2,me,comm,etiq,ierr)
    2075                 :             :          end if
    2076                 :           0 :          call xmpi_bcast(psinablapsi2,master,mpi_enreg%comm_band,mpierr)
    2077                 :             :        end if
    2078                 :             : #if defined(HAVE_GPU_MARKERS)
    2079                 :             :        call nvtxEndRange()
    2080                 :             : #endif
    2081                 :             : 
    2082                 :             : #if defined(HAVE_GPU_MARKERS)
    2083                 :             :        call nvtxStartRange("core_band_loop")
    2084                 :             : #endif
    2085                 :             : !      LOOP OVER BANDS
    2086                 :             : 
    2087         [ +  + ]:         238 :        do iband=1,nband_k
    2088                 :             : 
    2089                 :             : !        Select bands for current proc
    2090                 :         224 :          myband=(mpi_enreg%proc_distrb(ikpt,iband,isppol)==me)
    2091         [ +  + ]:         238 :          if (myband) then
    2092                 :             : 
    2093                 :             : #if defined(HAVE_GPU_MARKERS)
    2094                 :             :            call nvtxStartRange("core_read_dipoles_band")
    2095                 :             : #endif
    2096                 :             : !          In case of MPI-IO, read core-valence dipoles for the block of bands ib0:ib1
    2097                 :             : !            starting at band n (contiguous bands of current proc)
    2098         [ +  + ]:         154 :            if (iomode_estf_mpiio.and.iband>ib1) then
    2099                 :          14 :              ib0=iband
    2100                 :          14 :              ib1=band_block_end(mpi_enreg%proc_distrb(ikpt,:,isppol),me,ib0,nband_k,nb_blk)
    2101         [ +  + ]:          98 :              nc_start=[1,1,1,ib0,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    2102         [ +  + ]:          98 :              nc_count=[3,nphicor_max,natom,ib1-ib0+1,1,1]
    2103         [ -  + ]:          14 :              NCF_CHECK(nf90_get_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    2104                 :             :            end if
    2105                 :             : !          Position of band n in psinablapsi2: block ib0:ib1 for MPI-IO, all bands otherwise
    2106                 :         154 :            my_iband=iband-ib0+1
    2107                 :             : #if defined(HAVE_GPU_MARKERS)
    2108                 :             :            call nvtxEndRange()
    2109                 :             : #endif
    2110                 :             : 
    2111                 :             : !          Compute contributions of buffered bands if the buffer is full
    2112         [ -  + ]:         154 :            if (nbuf==nbuf_max) then
    2113         [ #  # ]:           0 :              if (need_absorption) then
    2114                 :             :                call conducti_paw_core_sum(nbuf,buf_eig,buf_wabs,nphicor,natom_atnbr,mom,energy_cor(:,itypat_atnbr),&
    2115                 :           0 : &                                         oml_edge,broad_mode,dom,sigx1_k,lor_width=dom_var1)
    2116                 :             :              end if
    2117         [ #  # ]:           0 :              if (need_emissivity) then
    2118                 :             :                call conducti_paw_core_sum(nbuf,buf_eig,buf_wemis,nphicor,natom_atnbr,mom,energy_cor(:,itypat_atnbr),&
    2119                 :           0 : &                                         oml_edge,broad_mode,dom,emisx_k)
    2120                 :             :              end if
    2121                 :           0 :              nbuf=0
    2122                 :             :            end if
    2123                 :             : 
    2124                 :             : !          Store band n in the buffer
    2125                 :             : !            For absorption, docc_deig=|diff_occ|/omega, for emission docc_deig=|occ_n|/omega:
    2126                 :             : !            the 1/omega factor is applied in conducti_paw_core_sum
    2127                 :         154 :            nbuf=nbuf+1
    2128                 :         154 :            buf_eig(nbuf)=eig0_k(iband)
    2129         [ +  + ]:         676 :            do icor=1,nphicor
    2130                 :             :              abs_diff_occ(icor)=abs((occ_cor(icor,itypat_atnbr)/maxocc_cor(icor,itypat_atnbr) &
    2131                 :         676 : &                                   -occ_k(iband)/two*nsppol*nspinor)*two/nspinor/nsppol)
    2132                 :             :            end do
    2133         [ +  + ]:         518 :            do iatom_atnbr=1,natom_atnbr
    2134                 :         364 :              iatom=iatom_list(iatom_atnbr)
    2135         [ +  + ]:        1790 :              do icor=1,nphicor
    2136                 :             :                dhdk2_g=zero
    2137         [ +  + ]:        5088 :                do l1=1,3
    2138                 :        5088 :                  dhdk2_g=dhdk2_g+psinablapsi2(l1,icor,iatom,my_iband)*third
    2139                 :             :                end do
    2140         [ +  - ]:        1272 :                if (need_absorption) buf_wabs(nbuf,icor,iatom_atnbr)=dhdk2_g*abs_diff_occ(icor)*pi/ucvol
    2141         [ +  + ]:        1636 :                if (need_emissivity) buf_wemis(nbuf,icor,iatom_atnbr)=dhdk2_g*abs(occ_k(iband))*pi/ucvol
    2142                 :             :              end do
    2143                 :             :            end do
    2144                 :             :          end if ! my band?
    2145                 :             :        end do ! iband
    2146                 :             : #if defined(HAVE_GPU_MARKERS)
    2147                 :             :        call nvtxEndRange()
    2148                 :             : #endif
    2149                 :             : 
    2150                 :             : !      Compute contributions of remaining buffered bands
    2151         [ +  - ]:          14 :        if (nbuf>0) then
    2152         [ +  - ]:          14 :          if (need_absorption) then
    2153                 :             :            call conducti_paw_core_sum(nbuf,buf_eig,buf_wabs,nphicor,natom_atnbr,mom,energy_cor(:,itypat_atnbr),&
    2154                 :          14 : &                                     oml_edge,broad_mode,dom,sigx1_k,lor_width=dom_var1)
    2155                 :             :          end if
    2156         [ +  + ]:          14 :          if (need_emissivity) then
    2157                 :             :            call conducti_paw_core_sum(nbuf,buf_eig,buf_wemis,nphicor,natom_atnbr,mom,energy_cor(:,itypat_atnbr),&
    2158                 :          12 : &                                     oml_edge,broad_mode,dom,emisx_k)
    2159                 :             :          end if
    2160                 :             :        end if
    2161                 :             : 
    2162                 :             : !      Accumulate k-point contribution
    2163         [ +  - ]:          14 :        if (need_absorption) then
    2164                 :             :          sigx1(1:nphicor,1:mom,1:natom_atnbr,isppol)=sigx1(1:nphicor,1:mom,1:natom_atnbr,isppol) &
    2165   [ +  +  +  +  :      185055 : &                                              +wtk(ikpt)*sigx1_k(1:nphicor,1:mom,1:natom_atnbr)
                   +  + ]
    2166                 :             :        end if
    2167         [ +  + ]:          14 :        if (need_emissivity) then
    2168                 :             :          emisx(1:nphicor,1:mom,1:natom_atnbr,isppol)=emisx(1:nphicor,1:mom,1:natom_atnbr,isppol) &
    2169   [ +  +  +  +  :      160048 : &                                              +wtk(ikpt)*emisx_k(1:nphicor,1:mom,1:natom_atnbr)
                   +  + ]
    2170                 :             :        end if
    2171                 :             : 
    2172                 :             : !      Validity limit
    2173                 :          14 :        deltae=deltae+eig0_k(nband_k)
    2174                 :             : 
    2175                 :          14 :        ABI_FREE(eig0_k)
    2176         [ -  + ]:          14 :        ABI_FREE(occ_k)
    2177                 :             : !    End loop over kpt/spin
    2178                 :             :      end if ! My kpt?
    2179                 :          30 :      bdtot_index=bdtot_index+nband_k
    2180                 :             : #if defined(HAVE_GPU_MARKERS)
    2181                 :             :      call nvtxEndRange()
    2182                 :             : #endif
    2183                 :             :    end do ! ikpt
    2184                 :             :  end do ! isppol
    2185                 :             : 
    2186                 :             : #if defined(HAVE_GPU_MARKERS)
    2187                 :             :  call nvtxStartRange("core_dummy_reads")
    2188                 :             : #endif
    2189         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
    2190   [ +  -  +  + ]:          14 :    if(iomode_estf_mpiio.and.nproc>1) then
    2191         [ +  + ]:          10 :      do idum=my_ncalls+1,ncalls_max
    2192                 :           2 :        nc_start=[1,1,1,1,1,1];nc_stride=[1,1,1,1,1,1]
    2193                 :           2 :        nc_count=[0,0,0,0,0,0]
    2194         [ -  + ]:          10 :        NCF_CHECK(nf90_get_var(ncid,varid,dummy,start=nc_start,stride=nc_stride,count=nc_count))
    2195                 :             :      enddo
    2196                 :             :    endif
    2197                 :             :  endif
    2198                 :             : 
    2199                 :             : #if defined(HAVE_GPU_MARKERS)
    2200                 :             :  call nvtxEndRange()
    2201                 :             : #endif
    2202                 :             : 
    2203                 :             : #if defined(HAVE_GPU_MARKERS)
    2204                 :             :  call nvtxStartRange("core_xmpi_sum")
    2205                 :             : #endif
    2206                 :             : !Accumulate kpt/band contributions over processors
    2207         [ +  - ]:          14 :  if (need_absorption) then
    2208                 :          14 :    call xmpi_sum(sigx1,comm,mpierr)
    2209                 :             :  end if
    2210         [ +  + ]:          14 :  if (need_emissivity) then
    2211                 :          12 :    call xmpi_sum(emisx,comm,mpierr)
    2212                 :             :  end if
    2213                 :          14 :  call xmpi_sum(deltae,comm,mpierr)
    2214                 :          14 :  deltae=deltae/mpi_enreg%nproc_band
    2215                 :             : #if defined(HAVE_GPU_MARKERS)
    2216                 :             :  call nvtxEndRange()
    2217                 :             : #endif
    2218                 :             : 
    2219                 :             : 
    2220                 :             : #if defined(HAVE_GPU_MARKERS)
    2221                 :             :  call nvtxStartRange("core_post_process")
    2222                 :             : #endif
    2223                 :             : !Release some memory
    2224         [ -  + ]:          14 :  ABI_FREE(iatom_list)
    2225         [ -  + ]:          14 :  ABI_FREE(buf_eig)
    2226         [ +  - ]:          14 :  if (need_absorption) then
    2227         [ -  + ]:          14 :    ABI_FREE(buf_wabs)
    2228                 :             :  end if
    2229         [ +  + ]:          14 :  if (need_emissivity) then
    2230         [ -  + ]:          12 :    ABI_FREE(buf_wemis)
    2231                 :             :  end if
    2232         [ -  + ]:          14 :  ABI_FREE(abs_diff_occ)
    2233         [ -  + ]:          14 :  ABI_FREE(psinablapsi2)
    2234         [ +  - ]:          14 :  if (need_absorption) then
    2235         [ -  + ]:          14 :    ABI_FREE(sigx1_k)
    2236                 :             :  end if
    2237         [ +  + ]:          14 :  if (need_emissivity) then
    2238         [ -  + ]:          12 :    ABI_FREE(emisx_k)
    2239                 :             :  end if
    2240                 :             : 
    2241                 :             :  !Close core-valence dipoles file
    2242         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
    2243   [ -  +  -  - ]:          14 :    if (iomode_estf_mpiio.or.me==master) then
    2244         [ -  + ]:          14 :      NCF_CHECK(nf90_close(ncid))
    2245                 :             :    end if
    2246         [ #  # ]:           0 :  else if (me==master) then
    2247                 :           0 :    ierr=close_unit(opt2_unt,msg)
    2248         [ #  # ]:           0 :    ABI_CHECK(ierr==0,sjoin("Error while closing ",filnam2))
    2249                 :             :  end if
    2250                 :             : 
    2251                 :             : !---------------------------------------------------------------------------------
    2252                 :             : ! Post-processing
    2253                 :             : 
    2254         [ +  - ]:          14 :  if (need_absorption) then
    2255   [ +  +  +  +  :      209075 :    sigx1=sigx1*dble(natom_atnbr)
             +  +  +  + ]
    2256   [ -  +  +  -  :          70 :    ABI_MALLOC(sigx1_av,(nphicor,mom,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    2257   [ +  +  +  +  :       62028 :    sigx1_av=zero
                   +  + ]
    2258                 :             :  endif
    2259         [ +  + ]:          14 :  if (need_emissivity) then
    2260                 :             :    ! Filter low values
    2261         [ +  + ]:          24 :    do isppol=1,nsppol
    2262         [ +  + ]:          66 :      do iatom_atnbr=1,natom_atnbr
    2263         [ +  + ]:       42054 :        do iom=1,mom
    2264         [ +  + ]:      184042 :          do icor=1,nphicor
    2265         [ -  + ]:      184000 :            if (emisx(icor,iom,iatom_atnbr,isppol)<=tol16) emisx(icor,iom,iatom_atnbr,isppol)=zero
    2266                 :             :          end do
    2267                 :             :        end do
    2268                 :             :      end do
    2269                 :             :    end do
    2270   [ +  +  +  +  :      184066 :    emisx=emisx*dble(natom_atnbr)
             +  +  +  + ]
    2271   [ -  +  +  -  :          60 :    ABI_MALLOC(emisx_av,(nphicor,mom,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    2272   [ +  +  +  +  :       52024 :    emisx_av=zero
                   +  + ]
    2273                 :             :  endif
    2274                 :             : 
    2275         [ +  + ]:          28 :  do isppol=1,nsppol
    2276         [ +  + ]:          75 :    do iatom_atnbr=1,natom_atnbr
    2277         [ +  + ]:       47061 :      do iom=1,mom
    2278         [ +  + ]:      209047 :        do icor=1,nphicor
    2279         [ +  - ]:      162000 :          if(need_absorption) sigx1_av(icor,iom,isppol)=sigx1_av(icor,iom,isppol)+sigx1(icor,iom,iatom_atnbr,isppol)/dble(natom_atnbr)
    2280         [ +  + ]:      209000 :          if(need_emissivity) emisx_av(icor,iom,isppol)=emisx_av(icor,iom,isppol)+emisx(icor,iom,iatom_atnbr,isppol)/dble(natom_atnbr)
    2281                 :             :        end do
    2282                 :             :      end do
    2283                 :             :    end do
    2284                 :             :  end do
    2285                 :             : 
    2286                 :             : !  Spin treatment
    2287         [ -  + ]:          14 :  if(nsppol==2) then
    2288         [ #  # ]:           0 :    if(need_absorption) then
    2289   [ #  #  #  #  :           0 :      ABI_MALLOC(sum_spin_sigx1,(nphicor,mom,natom_atnbr))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2290   [ #  #  #  #  :           0 :      ABI_MALLOC(sum_spin_sigx1_av,(nphicor,mom))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2291   [ #  #  #  #  :           0 :      sum_spin_sigx1=zero ; sum_spin_sigx1_av=zero
          #  #  #  #  #  
                      # ]
    2292                 :             :    endif
    2293         [ #  # ]:           0 :    if(need_emissivity) then
    2294   [ #  #  #  #  :           0 :      ABI_MALLOC(sum_spin_emisx,(nphicor,mom,natom_atnbr))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2295   [ #  #  #  #  :           0 :      ABI_MALLOC(sum_spin_emisx_av,(nphicor,mom))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2296   [ #  #  #  #  :           0 :      sum_spin_emisx=zero ; sum_spin_emisx_av=zero
          #  #  #  #  #  
                      # ]
    2297                 :             :    endif
    2298         [ #  # ]:           0 :    do isppol=1,nsppol
    2299         [ #  # ]:           0 :      do iatom_atnbr=1,natom_atnbr
    2300         [ #  # ]:           0 :        do iom=1,mom
    2301         [ #  # ]:           0 :          do icor=1,nphicor
    2302         [ #  # ]:           0 :            if(need_absorption) sum_spin_sigx1(icor,iom,iatom_atnbr)=sum_spin_sigx1(icor,iom,iatom_atnbr) &
    2303                 :           0 : & +sigx1(icor,iom,iatom_atnbr,isppol)/dble(natom_atnbr)
    2304         [ #  # ]:           0 :            if(need_emissivity) sum_spin_emisx(icor,iom,iatom_atnbr)=sum_spin_emisx(icor,iom,iatom_atnbr) &
    2305                 :           0 : & +emisx(icor,iom,iatom_atnbr,isppol)/dble(natom_atnbr)
    2306                 :             :          end do
    2307                 :             :        end do
    2308                 :             :      end do
    2309                 :             :    end do
    2310         [ #  # ]:           0 :    do isppol=1,nsppol
    2311         [ #  # ]:           0 :      do iom=1,mom
    2312         [ #  # ]:           0 :        do icor=1,nphicor
    2313         [ #  # ]:           0 :          if(need_absorption) sum_spin_sigx1_av(icor,iom)=sum_spin_sigx1_av(icor,iom)+sigx1_av(icor,iom,isppol)
    2314         [ #  # ]:           0 :          if(need_emissivity) sum_spin_emisx_av(icor,iom)=sum_spin_emisx_av(icor,iom)+emisx_av(icor,iom,isppol)
    2315                 :             :        end do
    2316                 :             :      end do
    2317                 :             :    end do
    2318                 :             :  endif
    2319                 :             : 
    2320                 :             :  ! Units
    2321         [ +  - ]:          14 :  if(au_units==0) then
    2322   [ +  +  +  + ]:       62014 :    oml_edge=oml_edge*Ha_eV
    2323         [ +  - ]:          14 :    if(need_absorption) then
    2324   [ +  +  +  +  :       62028 :      sigx1_av=sigx1_av*Ohmcm
                   +  + ]
    2325   [ +  +  +  +  :      209075 :      sigx1=sigx1*Ohmcm
             +  +  +  + ]
    2326         [ -  + ]:          14 :      if(nsppol==2) then
    2327   [ #  #  #  # ]:           0 :        sum_spin_sigx1_av=sum_spin_sigx1_av*Ohmcm
    2328   [ #  #  #  #  :           0 :        sum_spin_sigx1=sum_spin_sigx1*Ohmcm
                   #  # ]
    2329                 :             :      endif
    2330                 :             :    endif
    2331         [ +  + ]:          14 :    if(need_emissivity) then
    2332   [ +  +  +  +  :       52024 :      emisx_av=emisx_av*Ohmcm
                   +  + ]
    2333   [ +  +  +  +  :      184066 :      emisx=emisx*Ohmcm
             +  +  +  + ]
    2334         [ -  + ]:          12 :      if(nsppol==2) then
    2335   [ #  #  #  # ]:           0 :        sum_spin_emisx_av=sum_spin_emisx_av*Ohmcm
    2336   [ #  #  #  #  :           0 :        sum_spin_emisx=sum_spin_emisx*Ohmcm
                   #  # ]
    2337                 :             :      endif
    2338                 :             :    endif
    2339                 :             :  endif
    2340                 :             : 
    2341                 :             : #if defined(HAVE_GPU_MARKERS)
    2342                 :             :  call nvtxEndRange()
    2343                 :             : #endif
    2344                 :             : #if defined(HAVE_GPU_MARKERS)
    2345                 :             :  call nvtxStartRange("core_output")
    2346                 :             : #endif
    2347                 :             : !---------------------------------------------------------------------------------
    2348                 :             : ! Output results
    2349                 :          14 :  write(str_atm,*) input_atm
    2350                 :          14 :  str_atm=adjustl(str_atm)
    2351                 :             :  str_atm=trim(str_atm)
    2352                 :             : 
    2353                 :             : !Only master node outputs results in files (only master node)
    2354         [ +  + ]:          14 :  if (me==master) then
    2355                 :             : 
    2356                 :             : !  Standard output
    2357         [ +  - ]:           8 :    if (need_absorption) then
    2358                 :           8 :      write(std_out,*) 'Absorption: valence state orbital energies: omin,omax',omin_sig,omax_sig
    2359                 :             :    end if
    2360         [ +  + ]:           8 :    if (need_emissivity) then
    2361                 :           6 :      write(std_out,*) 'Emissivity: valence state orbital energies: omin,omax',omin_emis,omax_emis
    2362                 :             :    end if
    2363         [ +  - ]:           8 :    if (need_absorption) then
    2364                 :             :      write(std_out,'(a,f10.5,a,f10.5,a)')&
    2365                 :           8 : &   ' Emax       =',deltae/dble(nkpt*nsppol),' Ha',deltae/dble(nkpt*nsppol)*Ha_eV,' eV'
    2366                 :             :    end if
    2367                 :             : 
    2368                 :             : !  _sigX file
    2369                 :             :    if (need_absorption) then
    2370         [ -  + ]:           8 :      if (open_file(trim(filnam_out)//'_sigX_at'//str_atm,msg,newunit=sigx1_unt,form='formatted',action="write")/=0) then
    2371                 :           0 :        ABI_ERROR(msg)
    2372                 :             :      end if
    2373         [ +  + ]:           8 :      if (abs(dom_max)>tol10) then
    2374                 :           1 :        write(sigx1_unt,'(a)')'#***************************************************** ARCTAN SMEARING ********'
    2375                 :           1 :        write(sigx1_unt,'(a,i8,3f10.5,a)')'# npts,omin,omax,width      =',mom,omin,omax,dom,' Ha'
    2376                 :           1 :        write(sigx1_unt,'(a,2f10.5,a)')'# dom_max,center        =',dom_max,dom_ctr,' Ha'
    2377                 :             :      else
    2378                 :           7 :        write(sigx1_unt,'(a)')'#***************************************************** FIXED SMEARING ********'
    2379                 :           7 :        write(sigx1_unt,'(a,i8,3f10.5,a)')'# npts,omin,omax,width      =',mom,omin,omax,dom,' Ha'
    2380                 :             :      endif
    2381                 :           8 :      write(sigx1_unt,'(a,3f10.5,a)' )'# rprimd(bohr)      =',rprimd(1:3,1)
    2382                 :           8 :      write(sigx1_unt,'(a,3f10.5,a)' )'#                    ',rprimd(1:3,2)
    2383                 :           8 :      write(sigx1_unt,'(a,3f10.5,a)' )'#                    ',rprimd(1:3,3)
    2384                 :           8 :      write(sigx1_unt,'(a,i8)' )      '# natom             =',natom
    2385                 :           8 :      write(sigx1_unt,'(a,3i8)' )     '# nkpt,mband,nsppol        =',nkpt,mband,nsppol
    2386                 :           8 :      write(sigx1_unt,'(a, f10.5,a)' )'# ecut                  =',ecut,' Ha'
    2387                 :           8 :      write(sigx1_unt,'(a,f10.5,a,f10.5,a)' )'# fermie            =',fermie,' Ha ',fermie*Ha_eV,' eV'
    2388                 :           8 :      write(sigx1_unt,'(a,f12.5,a,f12.5,a)') '# Temp              =',tsmear,' Ha ',Tatm,' Kelvin'
    2389                 :           8 :      write(sigx1_unt,'(a)')'#----------------------------------------------------------------------------'
    2390                 :           8 :      write(sigx1_unt,'(a,i4)') '# Number of core orbitals nc=',nphicor
    2391         [ +  + ]:          35 :      do icor=1,nphicor
    2392         [ +  + ]:          35 :        if (kappacor(icor,itypat_atnbr)==0) then
    2393                 :          15 :          write(sigx1_unt,'(a,2i4,4f15.5)') '# n, l, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ', &
    2394                 :          15 :            ncor(icor,itypat_atnbr),lcor(icor,itypat_atnbr),energy_cor(icor,itypat_atnbr),edge(icor),&
    2395                 :          30 : &            energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    2396                 :             :        else
    2397         [ +  + ]:          12 :          if (kappacor(icor,itypat_atnbr)>0) then
    2398                 :           3 :            j2=2*lcor(icor,itypat_atnbr)-1
    2399                 :           3 :            write(sigx1_unt,'(a,i4,i4,a,i4,4f15.5)') '# n, j, l, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ',&
    2400                 :           3 : &            ncor(icor,itypat_atnbr),j2,' /2',lcor(icor,itypat_atnbr),energy_cor(icor,itypat_atnbr),edge(icor),&
    2401                 :           6 : &            energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    2402                 :             :          else
    2403         [ +  + ]:           9 :            if (kappacor(icor,itypat_atnbr)<-1) then
    2404                 :           3 :              j2=2*lcor(icor,itypat_atnbr)+1
    2405                 :           3 :              write(sigx1_unt,'(a,i4,i4,a,i4,4f15.5)') '# n, j, l, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ',&
    2406                 :           3 : &   ncor(icor,itypat_atnbr),j2,'/2',lcor(icor,itypat_atnbr),energy_cor(icor,itypat_atnbr),edge(icor),&
    2407                 :           6 : &              energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    2408                 :             :            else
    2409                 :           6 :              write(sigx1_unt,'(a,i4,a,i4,4f15.5)') '# n, j, l, Energy(Ha), Edge(Ha), Energy(eV), Edge(eV): ',&
    2410                 :           6 : &              ncor(icor,itypat_atnbr),'1/2',lcor(icor,itypat_atnbr),energy_cor(icor,itypat_atnbr),edge(icor),&
    2411                 :          12 : &              energy_cor(icor,itypat_atnbr)*Ha_eV,edge(icor)*Ha_eV
    2412                 :             :            end if
    2413                 :             :          end if
    2414                 :             :        end if
    2415                 :             :      end do
    2416                 :           8 :      write(sigx1_unt,'(a)')'#----------------------------------------------------------------------------'
    2417                 :             :      write(sigx1_unt,'(a,f10.5,a,f10.5,a)')&
    2418                 :           8 : &     '# Emax       =',deltae/dble(nkpt*nsppol),' Ha',deltae/dble(nkpt*nsppol)*Ha_eV,' eV'
    2419                 :           8 :      write(sigx1_unt,'(a)')'#----------------------------------------------------------------------------'
    2420         [ -  + ]:           8 :      if(au_units>0) then
    2421                 :           0 :        write(sigx1_unt,'(a)')'#  om(au),sig1_av(au),sig1(au)  for each orbital'
    2422                 :             :      else
    2423                 :           8 :        write(sigx1_unt,'(a)')'#  om(eV),sig1_av(Ohm.cm)-1,sig1(Ohm.cm)-1  for each orbital'
    2424                 :             :      endif
    2425         [ +  + ]:        8008 :      do iom=1,mom
    2426         [ +  - ]:        8008 :        if(nsppol==1) then
    2427                 :             :          write(sigx1_unt,'(100(1x,e15.8))') &
    2428   [ +  -  +  + ]:       35000 : &        (oml_edge(icor,iom),sigx1_av(icor,iom,1),sigx1(icor,iom,atnbr,1),icor=1,nphicor)
    2429                 :             :        else
    2430                 :             :          write(sigx1_unt,'(100(1x,e15.8))') &
    2431   [ #  #  #  # ]:           0 : &        (oml_edge(icor,iom),sum_spin_sigx1_av(icor,iom),sum_spin_sigx1(icor,iom,atnbr),icor=1,nphicor)
    2432                 :             :        endif
    2433                 :             :      end do
    2434                 :           8 :      close(sigx1_unt)
    2435                 :             :      ! absX file
    2436         [ +  - ]:           8 :      if(au_units==0) then
    2437         [ -  + ]:           8 :        if(open_file(trim(filnam_out)//'_absX_at'//str_atm,msg,newunit=absx_unt,form='formatted',action="write")/=0) then
    2438                 :           0 :          ABI_ERROR(msg)
    2439                 :             :        end if
    2440                 :           8 :        write(absx_unt,'(a)') '# om(eV), abso X average (cm-1), abso X(cm-1)'
    2441         [ +  + ]:        8008 :        do iom=1,mom
    2442         [ +  - ]:        8008 :          if(nsppol==1) then
    2443                 :             :            write(absx_unt,'(100(1x,e15.8))') &
    2444                 :       27000 : &          (oml_edge(icor,iom),sigx1_av(icor,iom,1)/(Speed_Light_SI*eps0),&
    2445   [ +  -  +  + ]:       35000 : &          sigx1(icor,iom,atnbr,1)/(Speed_Light_SI*eps0),icor=1,nphicor)
    2446                 :             :          else
    2447                 :             :            write(absx_unt,'(100(1x,e15.8))') &
    2448                 :           0 : &          (oml_edge(icor,iom),sum_spin_sigx1_av(icor,iom)/(Speed_Light_SI*eps0),&
    2449   [ #  #  #  # ]:           0 : &          sum_spin_sigx1(icor,iom,atnbr)/(Speed_Light_SI*eps0),icor=1,nphicor)
    2450                 :             :          endif
    2451                 :             :        end do
    2452                 :           8 :        close(absx_unt)
    2453                 :             :      endif
    2454                 :             :    end if
    2455                 :             : 
    2456                 :             : !    _s_sigX
    2457         [ -  + ]:           8 :    if (need_absorption.and.nsppol==2) then
    2458         [ #  # ]:           0 :      if (open_file(trim(filnam_out)//'_sigX_up_at'//str_atm,msg,newunit=sigx1_up_unt,form='formatted',action="write")/=0) then
    2459                 :           0 :        ABI_ERROR(msg)
    2460                 :             :      end if
    2461         [ #  # ]:           0 :      if (open_file(trim(filnam_out)//'_sigX_dn_at'//str_atm,msg,newunit=sigx1_dn_unt,form='formatted',action="write")/=0) then
    2462                 :           0 :        ABI_ERROR(msg)
    2463                 :             :      end if
    2464         [ #  # ]:           0 :      do iom=1,mom
    2465                 :             :        write(sigx1_up_unt,'(100(1x,e15.8))') &
    2466   [ #  #  #  # ]:           0 : &      (oml_edge(icor,iom),sigx1_av(icor,iom,1),sigx1(icor,iom,atnbr,1),icor=1,nphicor)
    2467                 :             :        write(sigx1_dn_unt,'(100(1x,e15.8))') &
    2468   [ #  #  #  # ]:           0 : &      (oml_edge(icor,iom),sigx1_av(icor,iom,2),sigx1(icor,iom,atnbr,2),icor=1,nphicor)
    2469                 :             :      end do
    2470                 :           0 :      close(sigx1_up_unt)
    2471                 :           0 :      close(sigx1_dn_unt)
    2472                 :             :    end if
    2473                 :             : 
    2474                 :             : !  _emisX file
    2475         [ +  + ]:           8 :    if (need_emissivity) then
    2476         [ -  + ]:           6 :      if (open_file(trim(filnam_out)//'_emisX_at'//str_atm,msg,newunit=ems_unt,form='formatted',action="write")/=0) then
    2477                 :           0 :        ABI_ERROR(msg)
    2478                 :             :      end if
    2479         [ -  + ]:           6 :      if(au_units>0) then
    2480                 :           0 :        write(ems_unt,'(a)')'#  om(au),sig1_av(au),sig1(au)  for each orbital'
    2481                 :             :      else
    2482                 :           6 :        write(ems_unt,'(a)')'#  om(eV),sig1_av(Ohm.cm)-1,sig1(Ohm.cm)-1  for each orbital'
    2483                 :             :      endif
    2484         [ +  + ]:        6006 :      do iom=1,mom
    2485         [ +  - ]:        6006 :        if(nsppol==1) then
    2486                 :             :          write(ems_unt,'(3(3(1x,e15.8),2x))') &
    2487   [ +  -  +  + ]:       25000 : &        (oml_edge(icor,iom),emisx_av(icor,iom,1),emisx(icor,iom,atnbr,1),icor=1,nphicor)
    2488                 :             :        else
    2489                 :             :          write(ems_unt,'(3(3(1x,e15.8),2x))') &
    2490   [ #  #  #  # ]:           0 : &        (oml_edge(icor,iom),sum_spin_emisx_av(icor,iom)/dble(natom_atnbr),sum_spin_emisx(icor,iom,atnbr),icor=1,nphicor)
    2491                 :             :        endif
    2492                 :             :      end do
    2493                 :           6 :     close(ems_unt)
    2494                 :             :   end if
    2495                 :             : 
    2496                 :             : !    _s_emisX
    2497         [ -  + ]:           6 :    if (need_emissivity.and.nsppol==2) then
    2498         [ #  # ]:           0 :      if (open_file(trim(filnam_out)//'_emisX_up_at'//str_atm,msg,newunit=ems_up_unt,form='formatted',action="write")/=0) then
    2499                 :           0 :        ABI_ERROR(msg)
    2500                 :             :      end if
    2501         [ #  # ]:           0 :      if (open_file(trim(filnam_out)//'_emisX_dn_at'//str_atm,msg,newunit=ems_dn_unt,form='formatted',action="write")/=0) then
    2502                 :           0 :        ABI_ERROR(msg)
    2503                 :             :      end if
    2504         [ #  # ]:           0 :      do iom=1,mom
    2505                 :             :        write(ems_up_unt,'(3(3(1x,e15.8),2x))') &
    2506   [ #  #  #  # ]:           0 : &        (oml_edge(icor,iom),emisx_av(icor,iom,1)/dble(natom_atnbr),emisx(icor,iom,atnbr,1),icor=1,nphicor)
    2507                 :             :        write(ems_dn_unt,'(3(3(1x,e15.8),2x))') &
    2508   [ #  #  #  # ]:           0 :          (oml_edge(icor,iom),emisx_av(icor,iom,2)/dble(natom_atnbr),emisx(icor,iom,atnbr,2),icor=1,nphicor)
    2509                 :             :      end do
    2510                 :           0 :      close(ems_up_unt)
    2511                 :           0 :      close(ems_dn_unt)
    2512                 :             :    end if
    2513                 :             : 
    2514                 :             :  endif ! master node
    2515                 :             : 
    2516                 :             : !---------------------------------------------------------------------------------
    2517                 :             : ! End
    2518                 :             : 
    2519                 :             : #if defined(HAVE_GPU_MARKERS)
    2520                 :             :  call nvtxEndRange()
    2521                 :             : #endif
    2522                 :             : !Release memory space
    2523         [ +  - ]:          14 :  if (need_absorption) then
    2524         [ -  + ]:          14 :    ABI_FREE(sigx1)
    2525         [ -  + ]:          14 :    ABI_FREE(sigx1_av)
    2526         [ -  + ]:          14 :    if (nsppol==2) then
    2527         [ #  # ]:           0 :      ABI_FREE(sum_spin_sigx1)
    2528         [ #  # ]:           0 :      ABI_FREE(sum_spin_sigx1_av)
    2529                 :             :    end if
    2530         [ -  + ]:          14 :    ABI_FREE(dom_var1)
    2531         [ -  + ]:          14 :    ABI_FREE(oml_edge)
    2532                 :             :  end if
    2533         [ +  + ]:          14 :  if (need_emissivity) then
    2534         [ -  + ]:          12 :    ABI_FREE(emisx)
    2535         [ -  + ]:          12 :    ABI_FREE(emisx_av)
    2536         [ -  + ]:          12 :    if (nsppol==2) then
    2537         [ #  # ]:           0 :      ABI_FREE(sum_spin_emisx)
    2538         [ #  # ]:           0 :      ABI_FREE(sum_spin_emisx_av)
    2539                 :             :    end if
    2540         [ -  + ]:          12 :    ABI_FREE(oml_emis)
    2541                 :             :  end if
    2542                 :          14 :  ABI_FREE(typat)
    2543         [ -  + ]:          14 :  ABI_FREE(ncor)
    2544         [ -  + ]:          14 :  ABI_FREE(lcor)
    2545         [ -  + ]:          14 :  ABI_FREE(kappacor)
    2546         [ -  + ]:          14 :  ABI_FREE(energy_cor)
    2547         [ -  + ]:          14 :  ABI_FREE(edge)
    2548         [ -  + ]:          14 :  ABI_FREE(eigen0)
    2549         [ -  + ]:          14 :  ABI_FREE(nband)
    2550         [ -  + ]:          14 :  ABI_FREE(occ)
    2551         [ -  + ]:          14 :  ABI_FREE(occ_cor)
    2552         [ -  + ]:          14 :  ABI_FREE(maxocc_cor)
    2553         [ -  + ]:          14 :  ABI_FREE(wtk)
    2554                 :          14 :  call hdr%free()
    2555                 :          14 :  call destroy_mpi_enreg(mpi_enreg)
    2556                 :             : 
    2557                 :             :  ABI_NVTX_END_RANGE()
    2558                 :          14 :  call timab(1187,2,tsec)
    2559                 :             : 
    2560   [ -  +  -  +  :          28 : end subroutine conducti_paw_core
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                      + ]
    2561                 :             : !!***
    2562                 :             : 
    2563                 :             : !----------------------------------------------------------------------
    2564                 :             : 
    2565                 :             : !!****f* m_conducti/conducti_paw_core_sum
    2566                 :             : !! NAME
    2567                 :             : !! conducti_paw_core_sum
    2568                 :             : !!
    2569                 :             : !! FUNCTION
    2570                 :             : !! Compute the core-valence contributions (X absorption or X emission) of a buffer
    2571                 :             : !! of bands and accumulate them for all core states, frequencies and atoms.
    2572                 :             : !! Parallelized over (atom, frequency, core state): each one sums over all bands.
    2573                 :             : !!
    2574                 :             : !! INPUTS
    2575                 :             : !!  nbuf=number of bands in the buffer
    2576                 :             : !!  buf_eig(nbuf)=eigenvalue of each band
    2577                 :             : !!  buf_wgt(nbuf,nphicor,natom_atnbr)=weight of each band, for each core state and atom
    2578                 :             : !!                                    (pi/ucvol and occupations included, not the 1/omega factor)
    2579                 :             : !!  nphicor=number of core states
    2580                 :             : !!  natom_atnbr=number of atoms of the selected type
    2581                 :             : !!  mom=number of frequencies
    2582                 :             : !!  energy_cor(nphicor)=energies of the core states
    2583                 :             : !!  oml(nphicor,mom)=frequencies, for each core state
    2584                 :             : !!  broad_mode=0 for gaussian broadening, 1 for lorentzian broadening
    2585                 :             : !!  dom=broadening width
    2586                 :             : !!  [lor_width(nphicor,mom)]=width of the lorentzian broadening (default: dom)
    2587                 :             : !!
    2588                 :             : !! SIDE EFFECTS
    2589                 :             : !!  sig_k(nphicor,mom,natom_atnbr)=contributions (accumulated)
    2590                 :             : !!
    2591                 :             : !! SOURCE
    2592                 :             : 
    2593   [ -  +  -  + ]:          26 : subroutine conducti_paw_core_sum(nbuf,buf_eig,buf_wgt,nphicor,natom_atnbr,mom,energy_cor,oml,&
    2594   [ +  +  +  -  :          26 : &                                broad_mode,dom,sig_k,lor_width)
                   -  + ]
    2595                 :             : 
    2596                 :             : !Arguments -----------------------------------
    2597                 :             : !scalars
    2598                 :             :  integer,intent(in) :: nbuf,nphicor,natom_atnbr,mom,broad_mode
    2599                 :             :  real(dp),intent(in) :: dom
    2600                 :             : !arrays
    2601                 :             :  real(dp),intent(in) :: buf_eig(:),buf_wgt(:,:,:),energy_cor(nphicor),oml(nphicor,mom)
    2602                 :             :  real(dp),intent(in),optional :: lor_width(:,:)
    2603                 :             :  real(dp),intent(inout) :: sig_k(nphicor,mom,natom_atnbr)
    2604                 :             : 
    2605                 :             : !Local variables-------------------------------
    2606                 :             : !scalars
    2607                 :             :  integer :: iatom_atnbr,ib,icor,iom
    2608                 :             :  logical :: has_lor_width
    2609                 :             :  real(dp) :: acc,arg,arg_max,diff_eig,dirac,dirac_fact,dirac_width,om,width
    2610                 :             : 
    2611                 :             : ! *********************************************************************************
    2612                 :             : 
    2613                 :          26 :  has_lor_width=present(lor_width)
    2614                 :          26 :  dirac_fact=one/(dom*sqrt(two_pi))
    2615                 :          26 :  dirac_width=one/(sqrt(two)*dom)
    2616                 :             : !Gaussian: dirac=dirac_fact*exp(-arg) is set to zero below 1d-20, i.e. for arg>arg_max
    2617                 :             : !  (skipping exp for these arguments also avoids its slow underflow path)
    2618                 :          26 :  arg_max=log(dirac_fact*1d20)
    2619                 :             : 
    2620                 :             : #if defined(HAVE_GPU_MARKERS)
    2621                 :             :  call nvtxStartRange("core_sum")
    2622                 :             : #endif
    2623                 :             : !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(acc,arg,diff_eig,dirac,ib,om,width)
    2624         [ +  + ]:         103 :  do iatom_atnbr=1,natom_atnbr
    2625         [ +  + ]:       77103 :    do iom=1,mom
    2626         [ +  + ]:      345077 :      do icor=1,nphicor
    2627                 :      268000 :        om=oml(icor,iom)
    2628                 :      268000 :        acc=zero
    2629         [ +  - ]:      268000 :        if (broad_mode==1) then
    2630                 :      268000 :          width=dom
    2631         [ +  + ]:      268000 :          if (has_lor_width) width=lor_width(icor,iom)
    2632         [ +  + ]:     2412000 :          do ib=1,nbuf
    2633                 :     2144000 :            diff_eig=buf_eig(ib)-energy_cor(icor)
    2634                 :     2144000 :            dirac=width/((diff_eig-om)**2+width**2)/pi
    2635         [ -  + ]:     2144000 :            if (dirac<1d-20) dirac=zero
    2636                 :     2412000 :            acc=acc+buf_wgt(ib,icor,iatom_atnbr)*dirac
    2637                 :             :          end do
    2638                 :             :        else
    2639         [ #  # ]:           0 :          do ib=1,nbuf
    2640                 :           0 :            diff_eig=buf_eig(ib)-energy_cor(icor)
    2641                 :           0 :            arg=((diff_eig-om)*dirac_width)**2
    2642         [ #  # ]:           0 :            if (arg<=arg_max) then
    2643                 :           0 :              dirac=dirac_fact*exp(-arg)
    2644         [ #  # ]:           0 :              if (dirac<1d-20) dirac=zero
    2645                 :           0 :              acc=acc+buf_wgt(ib,icor,iatom_atnbr)*dirac
    2646                 :             :            end if
    2647                 :             :          end do
    2648                 :             :        end if
    2649                 :      345000 :        sig_k(icor,iom,iatom_atnbr)=sig_k(icor,iom,iatom_atnbr)+acc/abs(om)
    2650                 :             :      end do
    2651                 :             :    end do
    2652                 :             :  end do
    2653                 :             : !$OMP END PARALLEL DO
    2654                 :             : #if defined(HAVE_GPU_MARKERS)
    2655                 :             :  call nvtxEndRange()
    2656                 :             : #endif
    2657                 :             : 
    2658                 :          26 : end subroutine conducti_paw_core_sum
    2659                 :             : !!***
    2660                 :             : 
    2661                 :             : !----------------------------------------------------------------------
    2662                 :             : 
    2663                 :             : !!****f* m_conducti/conducti_nc
    2664                 :             : !! NAME
    2665                 :             : !! conducti_nc
    2666                 :             : !!
    2667                 :             : !! FUNCTION
    2668                 :             : !! This program computes the elements of the optical frequency dependent
    2669                 :             : !! conductivity tensor and the conductivity along the three principal axes
    2670                 :             : !! from the Kubo-Greenwood formula.
    2671                 :             : !!
    2672                 :             : !! INPUTS
    2673                 :             : !!  (main routine)
    2674                 :             : !!
    2675                 :             : !! OUTPUT
    2676                 :             : !!  (main routine)
    2677                 :             : !!
    2678                 :             : !! NOTES
    2679                 :             : !!  bantot
    2680                 :             : !!  doccde(mband*nkpt_rbz*nsppol)=derivative of occ_rbz wrt the energy.
    2681                 :             : !!  dom=frequency range
    2682                 :             : !!  eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree).
    2683                 :             : !!  eigen11(2*mband*mband*nkpt_rbz*nsppol)=first-order eigenvalues (hartree)
    2684                 :             : !!  in reciprocal direction 100
    2685                 :             : !!  eigen12(2*mband*mband*nkpt_rbz*nsppol)=first-order eigenvalues (hartree)
    2686                 :             : !!  in reciprocal direction 010
    2687                 :             : !!  eigen13(2*mband*mband*nkpt_rbz*nsppol)=first-order eigenvalues (hartree)
    2688                 :             : !!  in reciprocal direction 001
    2689                 :             : !!  ecut=kinetic energy planewave cutoff (hartree).
    2690                 :             : !!  entropy= entropy associated with the smearing (adimensional)
    2691                 :             : !!  fermie= fermi energy (Hartree)
    2692                 :             : !!  gmet(3,3)=reciprocal space metric ($\textrm{bohr}^{2}$).
    2693                 :             : !!  gmet_inv(3,3)=inverse of reciprocal space metric ($\textrm{bohr}^{2}$).
    2694                 :             : !!  gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1).
    2695                 :             : !!  kin11= Onsager kinetic coeficient=optical conductivity
    2696                 :             : !!  kin12= Onsager kinetic coeficient
    2697                 :             : !!  kin21= Onsager kinetic coeficient
    2698                 :             : !!  kin22= Onsager kinetic coeficient
    2699                 :             : !!  Kth=thermal conductivity
    2700                 :             : !!  mom=number of frequency for conductivity computation
    2701                 :             : !!  mband=maximum number of bands.
    2702                 :             : !!  natom = number of atoms in the unit cell.
    2703                 :             : !!  nband(nkpt*nsppol)=number of bands at each RF k point for each spin.
    2704                 :             : !!  nelect=number of electrons per unit cell
    2705                 :             : !!  nkpt=number of k points in the IBZ for this perturbation
    2706                 :             : !!  ngfft(3)=integer fft box dimensions.
    2707                 :             : !!  nspinor=number of spinorial components of the wavefunctions.
    2708                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized.
    2709                 :             : !!  ntypat = number of atom types.
    2710                 :             : !!  occ(mband*nkpt*nsppol)=occupation number for each band and k.
    2711                 :             : !!  occopt==option for occupancies
    2712                 :             : !!  rmet(3,3)=real space metric ($\textrm{bohr}^{2}$).
    2713                 :             : !!  rprimd(3,3)=real space primitive translations.
    2714                 :             : !!  of primitive translations.
    2715                 :             : !!  Sth=thermopower
    2716                 :             : !!  tsmear=smearing width (or temperature) in Hartree
    2717                 :             : !!  ucvol=unit cell volume in ($\textrm{bohr}^{3}$).
    2718                 :             : !!  wind=frequency windows for computations of sigma
    2719                 :             : !!  wtk(nkpt)=weight assigned to each k point.
    2720                 :             : !!  znucl(natom)=atomic number of atoms
    2721                 :             : !!  np_sum=noziere-pines sumrule
    2722                 :             : !!  cond_kg(mom)=kubo-greenwood conductivity
    2723                 :             : !!
    2724                 :             : !! SOURCE
    2725                 :             : 
    2726                 :             : 
    2727                 :           1 : subroutine conducti_nc(filnam,filnam_out)
    2728                 :             : 
    2729                 :             : !Arguments -----------------------------------
    2730                 :             : !scalars
    2731                 :             :  character(len=fnlen),intent(in) :: filnam,filnam_out
    2732                 :             : 
    2733                 :             : !Local variables-------------------------------
    2734                 :             : !scalars
    2735                 :             :  integer,parameter :: formeig0=0,formeig1=1
    2736                 :             :  integer :: bantot,bd2tot_index,bdtot0_index,bdtot_index
    2737                 :             :  integer :: headform,iband,ii,jj,ikpt,iunt
    2738                 :             :  integer :: index_1,iom,isppol,jband,l1,l2,mband,mom,natom,nband1
    2739                 :             :  integer :: nrot,iomode
    2740                 :             :  integer :: nband_k,nkpt,nlign,nrest,nspinor,nsppol,ntypat
    2741                 :             :  integer :: occopt,comm
    2742                 :             :  integer :: tens_unt,lij_unt,sig_unt,kth_unt,ocond_unt
    2743                 :             :  real(dp) :: deltae,dosdeltae,diff_occ,dom,ecut,entropy,fermie,maxocc
    2744                 :             :  real(dp) :: nelect,np_sum,np_sum_k1,np_sum_k2,omin,oml,socc,socc_k,sig
    2745                 :             :  real(dp) :: tphysel,tsmear,ucvol,wind,Tatm
    2746                 :             :  character(len=fnlen) :: filnam0,filnam1,filnam2,filnam3
    2747                 :             :  character(len=500) :: msg
    2748                 :           1 :  type(hdr_type) :: hdr
    2749   [ +  +  +  +  :          14 :  type(wfk_t) :: gswfk,ddk1,ddk2,ddk3
             +  +  +  + ]
    2750                 :             : !arrays
    2751                 :           1 :  integer,allocatable :: nband(:)
    2752                 :             :  real(dp) :: gmet(3,3),gmet_inv(3,3),gprimd(3,3),gprimd_inv(3,3),rmet(3,3),rprimd(3,3)
    2753                 :           2 :  real(dp),allocatable :: cond_kg(:,:,:),cond_kg_cart(:,:,:),cond_nd(:,:,:),dhdk2_r(:,:,:,:),dhdk2_g(:,:)
    2754                 :           3 :  real(dp),allocatable :: doccde(:),doccde_k(:),cond_kg_xx(:),cond_kg_yy(:),cond_kg_zz(:),trace(:)
    2755                 :           1 :  real(dp),allocatable :: eig0_k(:),eig0tmp(:),eig1_k(:,:),eigen0(:),eigen11(:)
    2756                 :           1 :  real(dp),allocatable :: eigen12(:),eigtmp(:)
    2757                 :           2 :  real(dp),allocatable :: eigen13(:),occ(:),occ_k(:),wtk(:),cond_tot(:),oml1(:)
    2758                 :           1 :  real(dp),allocatable :: kin11(:),kin12(:),kin21(:),kin22(:)
    2759                 :           1 :  real(dp),allocatable :: kin11_k(:),kin12_k(:),kin21_k(:),kin22_k(:),Kth(:),Stp(:)
    2760                 :             :  real(dp) :: cond_kg_w(3,3),z(3,3)
    2761                 :             :  real(dp) :: eig_cond(3)
    2762                 :             : 
    2763                 :             : ! *********************************************************************************
    2764                 :             : 
    2765                 :             :  ABI_NVTX_START_RANGE(NVTX_CONDUCTI_NC)
    2766                 :             : 
    2767                 :             : !Read data file
    2768         [ -  + ]:           1 :  if (open_file(filnam,msg,newunit=iunt,form='formatted',status="old")/=0) then
    2769                 :           0 :    ABI_ERROR(msg)
    2770                 :             :  end if
    2771                 :             : 
    2772                 :           1 :  rewind(iunt)
    2773                 :           1 :  read(iunt,*)
    2774                 :           1 :  read(iunt,'(a)')filnam1       ! first ddk file
    2775                 :           1 :  read(iunt,'(a)')filnam2       ! second ddk file
    2776                 :           1 :  read(iunt,'(a)')filnam3       ! third ddk file
    2777                 :           1 :  read(iunt,'(a)')filnam0       ! ground-state data
    2778                 :             : 
    2779                 :             : !Open the GS Wavefunction file and the 3 DDK files.
    2780                 :             : ! TODO: one should perform basic consistency tests for the GS WFK and the DDK files, e.g.
    2781                 :             : ! k-points and their order, spins, number of bands could differ in the four files.
    2782                 :             : ! Note indeed that we are assuming the same numer of bands in all the files.
    2783                 :           1 :  comm = xmpi_comm_self
    2784                 :           1 :  call nctk_fort_or_ncfile(filnam0, iomode, msg)
    2785         [ -  + ]:           1 :  if (len_trim(msg) /= 0) ABI_ERROR(msg)
    2786                 :           1 :  call gswfk%open_read(filnam0, formeig0, iomode, get_unit(), comm)
    2787                 :             : 
    2788                 :           1 :  call nctk_fort_or_ncfile(filnam1, iomode, msg)
    2789         [ -  + ]:           1 :  if (len_trim(msg) /= 0) ABI_ERROR(msg)
    2790                 :           1 :  call ddk1%open_read(filnam1, formeig1, iomode, get_unit(), comm, hdr_out=hdr)
    2791                 :             : 
    2792                 :           1 :  call nctk_fort_or_ncfile(filnam2, iomode, msg)
    2793         [ -  + ]:           1 :  if (len_trim(msg) /= 0) ABI_ERROR(msg)
    2794                 :           1 :  call ddk2%open_read(filnam2, formeig1, iomode, get_unit(), comm)
    2795                 :             : 
    2796                 :           1 :  call nctk_fort_or_ncfile(filnam3, iomode, msg)
    2797         [ -  + ]:           1 :  if (len_trim(msg) /= 0) ABI_ERROR(msg)
    2798                 :           1 :  call ddk3%open_read(filnam3, formeig1, iomode, get_unit(), comm)
    2799                 :             : 
    2800         [ -  + ]:           1 :  if (ddk1%compare(ddk2) /= 0) then
    2801                 :           0 :    ABI_ERROR("ddk1 and ddk2 are not consistent. see above messages")
    2802                 :             :  end if
    2803         [ -  + ]:           1 :  if (ddk1%compare(ddk3) /= 0) then
    2804                 :           0 :    ABI_ERROR("ddk1 and ddk3 are not consistent. see above messages")
    2805                 :             :  end if
    2806                 :             : 
    2807                 :             : !Extract params from the header of the first ddk file (might have been the GS file ?)
    2808                 :             : 
    2809                 :             : !Extract info from the header
    2810                 :           1 :  headform=hdr%headform
    2811                 :           1 :  bantot=hdr%bantot
    2812                 :           1 :  ecut=hdr%ecut_eff
    2813                 :           1 :  natom=hdr%natom
    2814                 :           1 :  nkpt=hdr%nkpt
    2815                 :           1 :  nspinor=hdr%nspinor
    2816                 :           1 :  nsppol=hdr%nsppol
    2817                 :           1 :  ntypat=hdr%ntypat
    2818                 :           1 :  occopt=hdr%occopt
    2819   [ +  +  +  + ]:          13 :  rprimd(:,:)=hdr%rprimd(:,:)
    2820   [ -  +  +  -  :           3 :  ABI_MALLOC(nband,(nkpt*nsppol))
          +  -  +  -  -  
                +  -  + ]
    2821   [ -  +  +  -  :           3 :  ABI_MALLOC(occ,(bantot))
          +  -  +  -  -  
                +  -  + ]
    2822                 :           1 :  fermie=hdr%fermie
    2823         [ +  + ]:          21 :  occ(1:bantot)=hdr%occ(1:bantot)
    2824         [ +  + ]:           2 :  nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol)
    2825                 :             : 
    2826                 :             : !Get mband, as the maximum value of nband(nkpt)
    2827         [ +  + ]:           2 :  mband=maxval(nband(:))
    2828                 :             : 
    2829                 :           1 :  write(std_out,*)
    2830                 :           1 :  write(std_out,'(a,3f10.5,a)' )' rprimd(bohr)      =',rprimd(1:3,1)
    2831                 :           1 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,2)
    2832                 :           1 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,3)
    2833                 :           1 :  write(std_out,'(a,i8)')       ' natom             =',natom
    2834                 :           1 :  write(std_out,'(a,2i8)')      ' nkpt,mband        =',nkpt,mband
    2835                 :           1 :  write(std_out,'(a, f10.5,a)' ) ' ecut              =',ecut,' Ha'
    2836                 :           1 :  write(std_out,'(a,f10.5,a,f10.5,a)' )' fermie            =',fermie,' Ha',fermie*Ha_eV,' eV'
    2837                 :             : 
    2838                 :             : !Prepare the reading of ddk Wff files
    2839   [ +  -  -  +  :           3 :  ABI_MALLOC(eigtmp,(2*mband*mband))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    2840   [ -  +  +  -  :           3 :  ABI_MALLOC(eig0tmp,(mband))
          +  -  +  -  -  
                +  -  + ]
    2841                 :             : 
    2842                 :             : !Read the eigenvalues of ground-state and ddk files
    2843   [ -  +  +  -  :           3 :  ABI_MALLOC(eigen0,(mband*nkpt*nsppol))
          +  -  +  -  -  
                +  -  + ]
    2844   [ +  -  -  +  :           3 :  ABI_MALLOC(eigen11,(2*mband*mband*nkpt*nsppol))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    2845   [ -  +  +  -  :           2 :  ABI_MALLOC(eigen12,(2*mband*mband*nkpt*nsppol))
             -  +  -  + ]
    2846   [ -  +  +  -  :           2 :  ABI_MALLOC(eigen13,(2*mband*mband*nkpt*nsppol))
             -  +  -  + ]
    2847                 :           1 :  bdtot0_index=0 ; bdtot_index=0
    2848         [ +  + ]:           2 :  do isppol=1,nsppol
    2849         [ +  + ]:           3 :    do ikpt=1,nkpt
    2850                 :           1 :      nband1=nband(ikpt+(isppol-1)*nkpt)
    2851                 :           1 :      call gswfk%read_eigk(ikpt,isppol,xmpio_single,eig0tmp)
    2852         [ +  + ]:          21 :      eigen0(1+bdtot0_index:nband1+bdtot0_index)=eig0tmp(1:nband1)
    2853                 :             : 
    2854                 :           1 :      call ddk1%read_eigk(ikpt,isppol,xmpio_single,eigtmp)
    2855         [ +  + ]:         801 :      eigen11(1+bdtot_index:2*nband1**2+bdtot_index)=eigtmp(1:2*nband1**2)
    2856                 :             : 
    2857                 :           1 :      call ddk2%read_eigk(ikpt,isppol,xmpio_single,eigtmp)
    2858         [ +  + ]:         801 :      eigen12(1+bdtot_index:2*nband1**2+bdtot_index)=eigtmp(1:2*nband1**2)
    2859                 :             : 
    2860                 :           1 :      call ddk3%read_eigk(ikpt,isppol,xmpio_single,eigtmp)
    2861         [ +  + ]:         801 :      eigen13(1+bdtot_index:2*nband1**2+bdtot_index)=eigtmp(1:2*nband1**2)
    2862                 :             : 
    2863                 :           1 :      bdtot0_index=bdtot0_index+nband1
    2864                 :           2 :      bdtot_index=bdtot_index+2*nband1**2
    2865                 :             :    end do
    2866                 :             :  end do
    2867                 :             : 
    2868                 :             : !Close files
    2869                 :           1 :  call gswfk%close()
    2870                 :           1 :  call ddk1%close()
    2871                 :           1 :  call ddk2%close()
    2872                 :           1 :  call ddk3%close()
    2873                 :             : 
    2874         [ -  + ]:           1 :  ABI_FREE(eigtmp)
    2875         [ -  + ]:           1 :  ABI_FREE(eig0tmp)
    2876                 :             : 
    2877                 :             : !---------------------------------------------------------------------------------
    2878                 :             : !Gmet inversion
    2879                 :           1 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
    2880                 :           1 :  call matr3inv(gmet,gmet_inv)
    2881                 :           1 :  call matr3inv(gprimd,gprimd_inv)
    2882                 :             : 
    2883                 :             : !---------------------------------------------------------------------------------
    2884                 :             : !Derivative of occupation wrt the energy.
    2885                 :             : 
    2886   [ -  +  +  -  :           2 :  ABI_MALLOC(doccde,(mband*nkpt*nsppol))
             -  +  -  + ]
    2887   [ -  +  +  -  :           3 :  ABI_MALLOC(wtk,(nkpt))
          +  -  +  -  -  
                +  -  + ]
    2888                 :             : 
    2889                 :           1 :  read(iunt,*)tsmear
    2890                 :           1 :  Tatm=tsmear*Ha_K
    2891                 :           1 :  write(std_out,'(a,f12.5,a,f12.5,a)') ' Temp              =',tsmear,' Ha ',Tatm,' Kelvin'
    2892                 :             : !
    2893                 :           1 :  nlign=nkpt/6
    2894                 :           1 :  nrest=nkpt-6*nlign
    2895                 :           1 :  index_1=0
    2896         [ -  + ]:           1 :  do ii=1,nlign
    2897                 :           0 :    read(iunt,*)wtk(1+index_1:6+index_1)
    2898                 :           1 :    index_1=index_1+6
    2899                 :             :  end do
    2900         [ +  - ]:           1 :  if (nrest/=0) then
    2901                 :           1 :    read(iunt,*)wtk(6*nlign+1:nkpt)
    2902                 :             :  end if
    2903                 :             : !
    2904         [ -  + ]:           1 :  if (occopt==1) then
    2905                 :           0 :    write(std_out,'(a,i4)')  ' occopt            =',occopt
    2906         [ #  # ]:           0 :    doccde=zero
    2907                 :             :  else
    2908                 :           1 :    tphysel=zero
    2909                 :           1 :    maxocc=two/(nsppol*nspinor)
    2910                 :           1 :    dosdeltae=zero
    2911                 :             : !  CP: using 1 and nband(0) as dummy value, because function
    2912                 :             : !  not implemented for occopt==9; adding fermih=fermie in the list of arguments as well
    2913                 :             :    call getnel(doccde,dosdeltae,eigen0,entropy,fermie,fermie,maxocc,mband,nband,&
    2914                 :           1 : &   nelect,nkpt,nsppol,occ,occopt,1,tphysel,tsmear,11,wtk,1,nband(1))
    2915                 :             :  end if
    2916                 :             : 
    2917                 :             : !---------------------------------------------------------------------------------
    2918                 :             : !Size of the frequency range
    2919                 :             : 
    2920                 :           1 :  read(iunt,*)dom,wind
    2921                 :           1 :  close(iunt)
    2922                 :           1 :  mom=int(wind/dom)
    2923   [ -  +  +  -  :           3 :  ABI_MALLOC(oml1,(mom))
          +  -  +  -  -  
                +  -  + ]
    2924         [ +  + ]:         273 :  do iom=1,mom
    2925                 :         273 :    oml1(iom)=tol10*1000._dp+dble(iom)*dom
    2926                 :             :  end do
    2927                 :             : 
    2928   [ -  +  +  -  :           4 :  ABI_MALLOC(cond_nd,(mom,3,3))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    2929   [ -  +  +  -  :           2 :  ABI_MALLOC(cond_kg,(mom,3,3))
             -  +  -  + ]
    2930   [ -  +  +  -  :           2 :  ABI_MALLOC(cond_kg_cart,(mom,3,3))
             -  +  -  + ]
    2931   [ -  +  +  -  :           2 :  ABI_MALLOC(cond_kg_xx,(mom))
             -  +  -  + ]
    2932   [ -  +  +  -  :           2 :  ABI_MALLOC(cond_kg_yy,(mom))
             -  +  -  + ]
    2933   [ -  +  +  -  :           2 :  ABI_MALLOC(trace,(mom))
             -  +  -  + ]
    2934   [ -  +  +  -  :           2 :  ABI_MALLOC(cond_kg_zz,(mom))
             -  +  -  + ]
    2935   [ -  +  +  -  :           2 :  ABI_MALLOC(cond_tot,(mom))
             -  +  -  + ]
    2936   [ -  +  +  -  :           2 :  ABI_MALLOC(kin11,(mom))
             -  +  -  + ]
    2937   [ -  +  +  -  :           2 :  ABI_MALLOC(kin12,(mom))
             -  +  -  + ]
    2938   [ -  +  +  -  :           2 :  ABI_MALLOC(kin21,(mom))
             -  +  -  + ]
    2939   [ -  +  +  -  :           2 :  ABI_MALLOC(kin22,(mom))
             -  +  -  + ]
    2940   [ -  +  +  -  :           2 :  ABI_MALLOC(kin11_k,(mom))
             -  +  -  + ]
    2941   [ -  +  +  -  :           2 :  ABI_MALLOC(kin12_k,(mom))
             -  +  -  + ]
    2942   [ -  +  +  -  :           2 :  ABI_MALLOC(kin21_k,(mom))
             -  +  -  + ]
    2943   [ -  +  +  -  :           2 :  ABI_MALLOC(kin22_k,(mom))
             -  +  -  + ]
    2944   [ -  +  +  -  :           2 :  ABI_MALLOC(Kth,(mom))
             -  +  -  + ]
    2945   [ -  +  +  -  :           2 :  ABI_MALLOC(Stp,(mom))
             -  +  -  + ]
    2946                 :           1 :  write(std_out,'(a,i8,2f10.5,a)')' mom,wind,dom      =',mom,wind,dom,' Ha'
    2947                 :             : 
    2948                 :             : !---------------------------------------------------------------------------------
    2949                 :             : 
    2950         [ +  + ]:         273 :  kin11   = zero
    2951         [ +  + ]:         273 :  kin12   = zero
    2952         [ +  + ]:         273 :  kin21   = zero
    2953         [ +  + ]:         273 :  kin22   = zero
    2954                 :           1 :  np_sum  = zero
    2955                 :           1 :  socc    = zero
    2956   [ +  +  +  +  :        2461 :  cond_kg = zero
                   +  + ]
    2957                 :             : 
    2958                 :             : !LOOP OVER SPINS
    2959         [ +  + ]:           2 :  do isppol=1,nsppol
    2960                 :             : !
    2961                 :           1 :    bdtot_index = 0
    2962                 :           1 :    bd2tot_index = 0
    2963                 :             : 
    2964                 :           1 :    deltae  = zero
    2965                 :             : !
    2966                 :             : !  BIG FAT k POINT LOOP
    2967                 :             : !
    2968         [ +  + ]:           2 :    do ikpt=1,nkpt
    2969                 :             : 
    2970                 :           1 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
    2971                 :             : 
    2972   [ -  +  +  -  :           3 :      ABI_MALLOC(eig0_k,(nband_k))
          +  -  +  -  -  
                +  -  + ]
    2973   [ +  -  -  +  :           4 :      ABI_MALLOC(eig1_k,(2*nband_k**2,3))
          +  -  +  -  +  
          -  +  -  -  +  
                   -  + ]
    2974   [ -  +  +  -  :           2 :      ABI_MALLOC(occ_k,(nband_k))
             -  +  -  + ]
    2975   [ -  +  +  -  :           2 :      ABI_MALLOC(doccde_k,(nband_k))
             -  +  -  + ]
    2976   [ -  +  +  -  :           4 :      ABI_MALLOC(dhdk2_r,(3,3,nband_k,nband_k))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    2977   [ -  +  +  -  :           4 :      ABI_MALLOC(dhdk2_g,(nband_k,nband_k))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    2978                 :             : 
    2979   [ +  +  +  +  :        2461 :      cond_nd   = zero
                   +  + ]
    2980         [ +  + ]:         273 :      kin11_k   = zero
    2981         [ +  + ]:         273 :      kin12_k   = zero
    2982         [ +  + ]:         273 :      kin21_k   = zero
    2983         [ +  + ]:         273 :      kin22_k   = zero
    2984                 :          21 :      np_sum_k1 = zero
    2985                 :          21 :      np_sum_k2 = zero
    2986                 :          21 :      socc_k    = zero
    2987   [ +  +  +  +  :        5221 :      dhdk2_r   = zero
             +  +  +  + ]
    2988   [ +  +  +  + ]:         421 :      dhdk2_g   = zero
    2989                 :             : 
    2990                 :             : !    eigenvalue for k-point
    2991         [ +  + ]:          21 :      eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
    2992                 :             : !    first derivative eigenvalues for k-point
    2993         [ +  + ]:         801 :      eig1_k(:,1)=eigen11(1+bd2tot_index:2*nband_k**2+bd2tot_index)
    2994         [ +  + ]:         801 :      eig1_k(:,2)=eigen12(1+bd2tot_index:2*nband_k**2+bd2tot_index)
    2995         [ +  + ]:         801 :      eig1_k(:,3)=eigen13(1+bd2tot_index:2*nband_k**2+bd2tot_index)
    2996                 :             : !    occupation numbers for k-point
    2997         [ +  + ]:          21 :      occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
    2998                 :             : !    derivative of occupation number for k-point
    2999         [ +  + ]:          21 :      doccde_k(:)=doccde(1+bdtot_index:nband_k+bdtot_index)
    3000                 :             : 
    3001                 :             : !    LOOP OVER BAND
    3002         [ +  + ]:          21 :      do iband=1,nband_k
    3003         [ +  + ]:         420 :        do jband=1,nband_k
    3004                 :             : !
    3005                 :             : !        TODO : replace with BLAS calls
    3006         [ +  + ]:        1600 :          do l1=1,3
    3007         [ +  + ]:        5200 :            do l2=1,3
    3008         [ +  + ]:       15600 :              do ii=1,3
    3009         [ +  + ]:       46800 :                do jj=1,3
    3010                 :             :                  dhdk2_r(l1,l2,iband,jband)=dhdk2_r(l1,l2,iband,jband)+(rprimd(l1,ii)&
    3011                 :             : &                 *eig1_k(2*iband-1+(jband-1)*2*nband_k,ii)*&
    3012                 :             : &                 rprimd(l2,jj)*eig1_k(2*iband-1+(jband-1)*2*nband_k,jj)&
    3013                 :             : &                 +rprimd(l1,ii)*eig1_k(2*iband  +(jband-1)*2*nband_k,ii)*&
    3014                 :       43200 : &                 rprimd(l2,jj)*eig1_k(2*iband+(jband-1)*2*nband_k,jj))
    3015                 :             :                end do
    3016                 :             :              end do
    3017                 :             :            end do
    3018                 :             :          end do
    3019                 :             : 
    3020         [ +  + ]:        1600 :          do l1=1,3
    3021         [ +  + ]:        5200 :            do l2=1,3
    3022                 :        4800 :              dhdk2_r(l1,l2,iband,jband)=dhdk2_r(l1,l2,iband,jband)/two_pi/two_pi
    3023                 :             :            end do
    3024                 :             :          end do
    3025                 :             : 
    3026                 :             : !        TODO: replace with BLAS calls
    3027         [ +  + ]:        1600 :          do l1=1,3
    3028         [ +  + ]:        5200 :            do l2=1,3
    3029                 :             :              dhdk2_g(iband,jband)=dhdk2_g(iband,jband)+gmet_inv(l1,l2)*( &
    3030                 :             : &             eig1_k(2*iband-1+(jband-1)*2*nband_k,l1)*&
    3031                 :             : &             eig1_k(2*iband-1+(jband-1)*2*nband_k,l2) &
    3032                 :             : &            +eig1_k(2*iband  +(jband-1)*2*nband_k,l1)*&
    3033                 :        4800 : &             eig1_k(2*iband  +(jband-1)*2*nband_k,l2))
    3034                 :             :            end do
    3035                 :             :          end do
    3036                 :         400 :          dhdk2_g(iband,jband)=dhdk2_g(iband,jband)/two_pi/two_pi
    3037                 :             : 
    3038                 :         400 :          diff_occ = occ_k(iband)-occ_k(jband)
    3039                 :             : !        if (dabs(diff_occ)>=tol8) then
    3040                 :             : 
    3041                 :             : !        Conductivity for each omega
    3042                 :         400 :          omin = zero
    3043         [ +  + ]:      109200 :          do iom=1,mom
    3044                 :      108800 :            oml=oml1(iom)
    3045         [ +  + ]:      108800 :            if (jband>iband) then
    3046                 :             :              sig= dhdk2_g(iband,jband)&
    3047                 :             : &             *(diff_occ)/oml*(dexp(-((eig0_k(jband)-eig0_k(iband)-oml)/dom)**2)&
    3048                 :       51680 : &             -dexp(-((eig0_k(iband)-eig0_k(jband)-oml)/dom)**2))
    3049                 :       51680 :              kin11_k(iom)=kin11_k(iom)+sig
    3050                 :       51680 :              kin12_k(iom)=kin12_k(iom)-sig*(eig0_k(jband)-fermie)
    3051                 :       51680 :              kin21_k(iom)=kin21_k(iom)-sig*(eig0_k(iband)-fermie)
    3052                 :             :              kin22_k(iom)=kin22_k(iom) + &
    3053                 :       51680 : &             sig*(eig0_k(iband)-fermie)*(eig0_k(jband)-fermie)
    3054                 :             :            end if
    3055         [ +  + ]:      435600 :            do l1=1,3
    3056         [ +  + ]:     1414400 :              do l2=1,3
    3057                 :             :                cond_nd(iom,l1,l2)=cond_nd(iom,l1,l2) +dhdk2_r(l1,l2,iband,jband)&
    3058                 :     1305600 : &               *(diff_occ)/oml*dexp(-((eig0_k(jband)-eig0_k(iband)-oml)/dom)**2)
    3059                 :             :              end do
    3060                 :             :            end do
    3061                 :             : 
    3062                 :             :          end do
    3063                 :             : 
    3064                 :             : !        Sumrule start
    3065         [ +  + ]:         420 :          if (dabs(eig0_k(iband)-eig0_k(jband))>=tol10) then
    3066                 :             :            np_sum_k1=np_sum_k1 -dhdk2_g(iband,jband)&
    3067                 :         380 : &           *(diff_occ)/(eig0_k(iband)-eig0_k(jband))
    3068                 :             :          else
    3069                 :          20 :            np_sum_k2=np_sum_k2 - doccde_k(iband)*dhdk2_g(iband,jband)
    3070                 :             :          end if
    3071                 :             : 
    3072                 :             : 
    3073                 :             : !        end loop over band
    3074                 :             :        end do
    3075                 :          21 :        socc_k=socc_k+occ_k(iband)
    3076                 :             :      end do
    3077                 :             : 
    3078         [ +  + ]:         273 :      do iom=1,mom
    3079                 :         272 :        kin11(iom)=kin11(iom)+wtk(ikpt)*kin11_k(iom)
    3080                 :         272 :        kin12(iom)=kin12(iom)+wtk(ikpt)*kin12_k(iom)
    3081                 :         272 :        kin21(iom)=kin21(iom)+wtk(ikpt)*kin21_k(iom)
    3082                 :         272 :        kin22(iom)=kin22(iom)+wtk(ikpt)*kin22_k(iom)
    3083         [ +  + ]:        1089 :        do l1=1,3
    3084         [ +  + ]:        3536 :          do l2=1,3
    3085                 :        3264 :            cond_kg(iom,l1,l2)=cond_kg(iom,l1,l2)+wtk(ikpt)*cond_nd(iom,l1,l2)
    3086                 :             :          end do
    3087                 :             :        end do
    3088                 :             :      end do
    3089                 :             : 
    3090                 :           1 :      np_sum=np_sum + wtk(ikpt)*(np_sum_k1+np_sum_k2)
    3091                 :           1 :      socc=socc+wtk(ikpt)*socc_k
    3092                 :             : 
    3093                 :             : !    Validity limit
    3094                 :           1 :      deltae=deltae+(eig0_k(nband_k)-fermie)
    3095                 :             : 
    3096                 :           1 :      bd2tot_index=bd2tot_index+2*nband_k**2
    3097                 :           1 :      bdtot_index=bdtot_index+nband_k
    3098                 :           1 :      ABI_FREE(eig0_k)
    3099         [ -  + ]:           1 :      ABI_FREE(eig1_k)
    3100         [ -  + ]:           1 :      ABI_FREE(occ_k)
    3101         [ -  + ]:           1 :      ABI_FREE(doccde_k)
    3102         [ -  + ]:           1 :      ABI_FREE(dhdk2_r)
    3103         [ -  + ]:           2 :      ABI_FREE(dhdk2_g)
    3104                 :             : !    End loop over k
    3105                 :             :    end do
    3106                 :             : 
    3107                 :           1 :    write(std_out,'(a,3f10.5)')' sumrule           =',np_sum/socc/three,socc
    3108                 :             :    write(std_out,'(a,f10.5,a,f10.5,a)')&
    3109                 :           2 : &   ' Emax-Efermi       =',deltae/dble(nkpt),' Ha',deltae/dble(nkpt)*Ha_eV,' eV'
    3110                 :             : 
    3111                 :             : !End loop over spins
    3112                 :             :  end do
    3113                 :             : 
    3114   [ +  +  +  +  :        2461 :  cond_kg=cond_kg*two_pi*third/(dom*ucvol)*half/dsqrt(pi)
                   +  + ]
    3115                 :             : 
    3116                 :             : 
    3117                 :             : !Check that new output file does NOT exist
    3118                 :             : !Keep this line : prevent silly (compiler ?) bug on HP 8000
    3119                 :           1 :  write(std_out,*)' conducti : call isfile '
    3120                 :             : !
    3121         [ -  + ]:           1 :  if (open_file(trim(filnam_out)//'_tens',msg,newunit=tens_unt,form='formatted',action="write")/=0) then
    3122                 :           0 :    ABI_ERROR(msg)
    3123                 :             :  end if
    3124         [ -  + ]:           1 :  if (open_file(trim(filnam_out)//'_Lij',msg,newunit=lij_unt,form='formatted',action="write")/=0) then
    3125                 :           0 :    ABI_ERROR(msg)
    3126                 :             :  end if
    3127                 :           1 :  write(lij_unt,'(a)')' # omega(ua) L12 L21 L22 L22'
    3128                 :             : 
    3129         [ -  + ]:           1 :  if (open_file(trim(filnam_out)//'_sig',msg,newunit=sig_unt,form='formatted',action="write")/=0) then
    3130                 :           0 :    ABI_ERROR(msg)
    3131                 :             :  end if
    3132                 :           1 :  write(sig_unt,'(a)')' # omega(ua) hbar*omega(eV)    cond(ua)             cond(ohm.cm)-1'
    3133                 :             : 
    3134         [ -  + ]:           1 :  if (open_file(trim(filnam_out)//'_Kth',msg,newunit=kth_unt,form='formatted',action="write")/=0) then
    3135                 :           0 :    ABI_ERROR(msg)
    3136                 :             :  end if
    3137                 :             :  write(kth_unt,'(a)')&
    3138                 :           1 : & ' #omega(ua) hbar*omega(eV)  thermal cond(ua)   Kth(W/m/K)   thermopower(ua)   Stp(microohm/K)'
    3139                 :             : 
    3140         [ -  + ]:           1 :  if (open_file(trim(filnam_out)//'.out',msg,newunit=ocond_unt,form='formatted',action="write")/=0) then
    3141                 :           0 :    ABI_ERROR(msg)
    3142                 :             :  end if
    3143                 :           1 :  write(ocond_unt,'(a)' )' Conducti output file:'
    3144                 :           1 :  write(ocond_unt,'(a)' )' Contains all results produced by conducti utility'
    3145                 :           1 :  write(ocond_unt,'(a)' )' '
    3146                 :           1 :  write(ocond_unt,'(a)')' # omega(ua)       cond(ua)             thermal cond(ua)       thermopower(ua)'
    3147                 :             : 
    3148                 :             : !Keep this line : prevent silly (compiler ?) bug on HP 8000
    3149                 :           1 :  write(std_out,*)' conducti : after call isfile '
    3150                 :             : 
    3151                 :             : !Compute thermal conductivity and thermopower
    3152         [ +  + ]:         273 :  do iom=1,mom
    3153                 :         272 :    oml=oml1(iom)
    3154                 :         272 :    kin11(iom)=kin11(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi)
    3155                 :         272 :    kin21(iom)=kin21(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi)
    3156                 :         272 :    kin12(iom)=kin12(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi)
    3157                 :         272 :    kin22(iom)=kin22(iom)*two_pi*third/(dom*ucvol)*half/dsqrt(pi)
    3158         [ +  + ]:         272 :    if (dabs(kin11(iom))<10.0d-20) kin11(iom)=zero
    3159                 :         272 :    Kth(iom)=kin22(iom)
    3160                 :         272 :    Stp(iom)=zero
    3161         [ +  + ]:         272 :    if(kin11(iom)/=zero)  then
    3162                 :         107 :      Kth(iom)=Kth(iom)-(kin12(iom)*kin21(iom)/kin11(iom))
    3163                 :         107 :      Stp(iom)=kin12(iom)/(kin11(iom)*Tatm)
    3164                 :             :    end if
    3165         [ +  + ]:         272 :    if (dabs(Kth(iom))<10.0d-20) Kth(iom)=zero
    3166         [ +  + ]:         272 :    if (dabs(Stp(iom))<10.0d-20) Stp(iom)=zero
    3167         [ +  + ]:         272 :    if (dabs(kin12(iom))<10.0d-20) kin12(iom)=zero
    3168         [ +  + ]:         272 :    if (dabs(kin21(iom))<10.0d-20) kin21(iom)=zero
    3169         [ +  + ]:         272 :    if (dabs(kin22(iom))<10.0d-20) kin22(iom)=zero
    3170                 :             : 
    3171                 :         272 :    write(lij_unt,'(f12.5,4es22.12)')oml,kin12(iom),kin21(iom),kin22(iom),kin22(iom)/Tatm*3.4057d9
    3172                 :         272 :    write(sig_unt,'(2f12.5,2es22.12)') oml,oml*Ha_eV,kin11(iom),kin11(iom)*Ohmcm
    3173                 :         272 :    write(kth_unt,'(2f12.5,4es22.12)') oml,oml*Ha_eV,Kth(iom),Kth(iom)*3.4057d9/Tatm,Stp(iom),Stp(iom)*3.6753d-2
    3174                 :         273 :    write(ocond_unt,'(1f12.5,3es22.12)') oml,kin11(iom),Kth(iom),Stp(iom)
    3175                 :             :  end do
    3176                 :             : 
    3177                 :           1 :  write(tens_unt,'(a)' )' Conductivity file '
    3178                 :           1 :  write(tens_unt,'(a)' )' ----------------- '
    3179                 :           1 :  write(tens_unt,'(a)' )' Contain first the full conductivity tensor, for the desired set of energies,'
    3180                 :           1 :  write(tens_unt,'(a)' )' then, the three principal values, for the desired set of energies'
    3181                 :           1 :  write(tens_unt,'(a)' )' (note that eigenvalues are not directly associated with xx,yy,zz)'
    3182                 :           1 :  write(tens_unt,'(a)' )' '
    3183                 :             : 
    3184                 :           1 :  write(ocond_unt,'(a)' )' '
    3185                 :           1 :  write(ocond_unt,'(a)' )' full conductivity tensor, for the desired set of energies'
    3186                 :           1 :  write(ocond_unt,'(a)' )' then, the three principal values, for the desired set of energies:'
    3187                 :             : 
    3188         [ +  + ]:         273 :  do iom=1,mom
    3189                 :         272 :    oml=oml1(iom)*Ha_eV
    3190                 :         272 :    write(tens_unt, '(a,es16.6,a)' ) ' energy (in eV) =',oml,', conductivity tensor (in Ohm.cm-1) follows :'
    3191                 :         272 :    write(ocond_unt, '(a,es16.6,a)' ) ' energy (in eV) =',oml,', conductivity tensor (in Ohm.cm-1) follows :'
    3192         [ +  + ]:        1089 :    do l1=1,3
    3193   [ +  -  +  + ]:        3264 :      write(tens_unt,"(3f25.15)") (cond_kg(iom,l1,l2)*Ohmcm,l2=1,3)
    3194   [ +  -  +  + ]:        3536 :      write(ocond_unt,"(3f25.15)") (cond_kg(iom,l1,l2)*Ohmcm,l2=1,3)
    3195                 :             :    end do
    3196                 :             :  end do
    3197                 :             : 
    3198                 :             : !Diagonalizing the conductivity matrix for sigma_xx,sigma_yy,sigma_zz
    3199         [ +  + ]:         273 :  cond_kg_xx=0d0
    3200         [ +  + ]:         273 :  cond_kg_yy=0d0
    3201         [ +  + ]:         273 :  cond_kg_zz=0d0
    3202                 :             : !trace=0d0 ! Used for checking with the original version of the code
    3203         [ +  + ]:         273 :  do iom=1,mom
    3204                 :         272 :    oml=oml1(iom)*Ha_eV
    3205                 :         272 :    cond_kg_w=0d0
    3206         [ +  + ]:        1088 :    do l1=1,3
    3207         [ +  + ]:        3536 :      do l2=1,3
    3208                 :        3264 :        cond_kg_w(l1,l2)=cond_kg(iom,l1,l2)
    3209                 :             :      end do
    3210                 :             :    end do
    3211                 :         272 :    call jacobi(cond_kg_w,3,3,eig_cond,z,nrot)
    3212                 :             : 
    3213                 :             : !  When the value is too small, set it to zero before printing
    3214         [ +  + ]:         272 :    if(abs(eig_cond(1))<tol10)eig_cond(1)=zero
    3215         [ +  + ]:         272 :    if(abs(eig_cond(2))<tol10)eig_cond(2)=zero
    3216         [ +  + ]:         272 :    if(abs(eig_cond(3))<tol10)eig_cond(3)=zero
    3217                 :             : 
    3218                 :         272 :    cond_kg_xx(iom)=eig_cond(1)
    3219                 :         272 :    cond_kg_yy(iom)=eig_cond(2)
    3220                 :         273 :    cond_kg_zz(iom)=eig_cond(3)
    3221                 :             : !  trace(iom)=cond_kg_xx(iom)+cond_kg_yy(iom)+cond_kg_zz(iom)
    3222                 :             :  end do
    3223                 :             : 
    3224                 :             : !DEBUG Keep this line : prevent silly (compiler ?) bug on HP 8000
    3225                 :             : !write(std_out,*)' conducti : after open '
    3226                 :             : !ENDDEBUG
    3227                 :             : 
    3228                 :           1 :  write(tens_unt,'(a,a)')ch10,' Now, print principal values of the conductivity tensor.'
    3229                 :           1 :  write(tens_unt,'(a)')' '
    3230                 :           1 :  write(tens_unt,'(a)')' #omega(ua)   cond_1(ua)     cond_2(ua) cond_3(ua)  cond_tot(ua)'
    3231                 :             : 
    3232                 :           1 :  write(ocond_unt,'(a)')' '
    3233                 :           1 :  write(ocond_unt,'(a,a)')ch10,' Now, print principal values of the conductivity tensor.'
    3234                 :           1 :  write(ocond_unt,'(a)')' '
    3235                 :           1 :  write(ocond_unt,'(a)')' #omega(ua)   cond_1(ua)     cond_2(ua) cond_3(ua)  cond_tot(ua)'
    3236                 :             : 
    3237                 :             : 
    3238         [ +  + ]:         273 :  do iom=1,mom
    3239                 :         272 :    cond_tot(iom)=cond_kg_xx(iom)+cond_kg_yy(iom)+cond_kg_zz(iom)
    3240                 :         272 :    write(tens_unt,'(f12.5,4es22.12)')oml1(iom),cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom)
    3241                 :         273 :    write(ocond_unt,'(f12.5,4es22.12)')oml1(iom),cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom)
    3242                 :             :  end do
    3243                 :             : 
    3244                 :           1 :  write(tens_unt,*)
    3245                 :           1 :  write(tens_unt,'(a)')' #hbar*omega(eV)    cond_1(ohm.cm)-1    cond_2(ohm.cm)-1    cond_3(ohm.cm)-1    cond_t(ohm.cm)-1'
    3246                 :           1 :  write(ocond_unt,*)
    3247                 :           1 :  write(ocond_unt,'(a)')' #hbar*omega(eV)    cond_1(ohm.cm)-1    cond_2(ohm.cm)-1    cond_3(ohm.cm)-1    cond_t(ohm.cm)-1'
    3248                 :             : 
    3249         [ +  + ]:         273 :  do iom=1,mom
    3250                 :         272 :    oml=oml1(iom)*Ha_eV
    3251                 :         272 :    cond_tot(iom)=cond_tot(iom)*Ohmcm
    3252                 :         272 :    cond_kg_xx(iom)=cond_kg_xx(iom)*Ohmcm
    3253                 :         272 :    cond_kg_yy(iom)=cond_kg_yy(iom)*Ohmcm
    3254                 :         272 :    cond_kg_zz(iom)=cond_kg_zz(iom)*Ohmcm
    3255                 :         272 :    write(tens_unt,'(f12.5,4es22.12)')oml,cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom)
    3256                 :         273 :    write(ocond_unt,'(f12.5,4es22.12)')oml,cond_kg_xx(iom),cond_kg_yy(iom),cond_kg_zz(iom),cond_tot(iom)
    3257                 :             :  end do
    3258                 :             : 
    3259                 :             : !Calculate the imaginary part of the conductivity (principal value)
    3260                 :             : !+derived optical properties.
    3261                 :           1 :  call msig(kin11,mom,oml1,filnam_out,zero,0)
    3262                 :             : 
    3263                 :           1 :  close(tens_unt)
    3264                 :           1 :  close(lij_unt)
    3265                 :           1 :  close(sig_unt)
    3266                 :           1 :  close(kth_unt)
    3267                 :           1 :  close(ocond_unt)
    3268                 :             : 
    3269         [ -  + ]:           1 :  ABI_FREE(nband)
    3270         [ -  + ]:           1 :  ABI_FREE(oml1)
    3271         [ -  + ]:           1 :  ABI_FREE(occ)
    3272         [ -  + ]:           1 :  ABI_FREE(eigen11)
    3273         [ -  + ]:           1 :  ABI_FREE(eigen12)
    3274         [ -  + ]:           1 :  ABI_FREE(eigen13)
    3275         [ -  + ]:           1 :  ABI_FREE(eigen0)
    3276         [ -  + ]:           1 :  ABI_FREE(doccde)
    3277         [ -  + ]:           1 :  ABI_FREE(wtk)
    3278         [ -  + ]:           1 :  ABI_FREE(cond_nd)
    3279         [ -  + ]:           1 :  ABI_FREE(cond_kg)
    3280         [ -  + ]:           1 :  ABI_FREE(cond_kg_cart)
    3281         [ -  + ]:           1 :  ABI_FREE(cond_kg_xx)
    3282         [ -  + ]:           1 :  ABI_FREE(cond_kg_yy)
    3283         [ -  + ]:           1 :  ABI_FREE(trace)
    3284         [ -  + ]:           1 :  ABI_FREE(cond_kg_zz)
    3285         [ -  + ]:           1 :  ABI_FREE(cond_tot)
    3286         [ -  + ]:           1 :  ABI_FREE(kin11)
    3287         [ -  + ]:           1 :  ABI_FREE(kin22)
    3288         [ -  + ]:           1 :  ABI_FREE(kin12)
    3289         [ -  + ]:           1 :  ABI_FREE(kin21)
    3290         [ -  + ]:           1 :  ABI_FREE(kin11_k)
    3291         [ -  + ]:           1 :  ABI_FREE(kin22_k)
    3292         [ -  + ]:           1 :  ABI_FREE(kin12_k)
    3293         [ -  + ]:           1 :  ABI_FREE(kin21_k)
    3294         [ -  + ]:           1 :  ABI_FREE(Stp)
    3295         [ -  + ]:           1 :  ABI_FREE(Kth)
    3296                 :           1 :  call hdr%free()
    3297                 :             : 
    3298                 :             :  ABI_NVTX_END_RANGE()
    3299                 :             : 
    3300   [ -  +  -  +  :           5 :  end subroutine conducti_nc
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             +  -  +  -  
                      + ]
    3301                 :             : !!***
    3302                 :             : 
    3303                 :             : !----------------------------------------------------------------------
    3304                 :             : 
    3305                 :             : !!****f* m_conducti/msig
    3306                 :             : !! NAME
    3307                 :             : !! msig
    3308                 :             : !!
    3309                 :             : !! FUNCTION
    3310                 :             : !! This program computes the elements of the optical frequency dependent
    3311                 :             : !! conductivity tensor and the conductivity along the three principal axes
    3312                 :             : !! from the Kubo-Greenwood formula for PAW formalism
    3313                 :             : !!
    3314                 :             : !! INPUTS
    3315                 :             : !!  fcti(npti)=  conductivity, as calculated in conducti
    3316                 :             : !!  npti= number of points to calculate conductivity
    3317                 :             : !!  xi(npti)= energies where the conductivity is calculated
    3318                 :             : !!
    3319                 :             : !! OUTPUT
    3320                 :             : !!   no output, only files
    3321                 :             : !!
    3322                 :             : !! NOTES
    3323                 :             : !!     this program calculates the imaginary part of the conductivity (principal value)
    3324                 :             : !!     +derived optical properties.
    3325                 :             : !!
    3326                 :             : !! SOURCE
    3327                 :             : 
    3328                 :           9 : subroutine msig(fcti,npti,xi,filnam_out_sig,phi,au_units)
    3329                 :             : 
    3330                 :             : !Arguments -----------------------------------
    3331                 :             : !scalars
    3332                 :             :  integer,intent(in) :: npti, au_units
    3333                 :             : !arrays
    3334                 :             :  real(dp),intent(in) :: fcti(npti),xi(npti)
    3335                 :             :  character(len=fnlen),intent(in) :: filnam_out_sig
    3336                 :             :  real(dp),intent(in) :: phi
    3337                 :             : 
    3338                 :             : !Local variables-------------------------------
    3339                 :             : !scalars
    3340                 :             :  integer :: ii,ip,eps_unt,abs_unt
    3341                 :             :  real(dp),parameter :: del=0.001_dp
    3342                 :             :  real(dp) :: dx,eps1,eps2,komega,pole,refl_s,refl_p,sigma2,xsum,ff,ffp,ffpp,abso,sigma1
    3343                 :             :  character(len=500) :: msg
    3344                 :             : !arrays
    3345                 :           9 :  real(dp),allocatable :: fct(:)
    3346                 :             :  real(dp) :: xx1,xx2,xx,nomega
    3347                 :             :  complex(dp) :: epsc,cos_phi,sin_phi,sqroot,crefl_s,crefl_p
    3348                 :             : ! *********************************************************************************
    3349                 :             : 
    3350                 :             : 
    3351                 :           9 :  write(std_out,'(2a)')ch10,'Calculate the principal value and related optical properties'
    3352                 :           9 :  write(std_out,'(a)')'Use default value for delta interval: del=1e-3'
    3353                 :             : 
    3354         [ -  + ]:           9 :  if (open_file(trim(filnam_out_sig)//'_eps',msg,newunit=eps_unt,status='replace',action="write")/=0) then
    3355                 :           0 :    ABI_ERROR(msg)
    3356                 :             :  end if
    3357         [ +  - ]:           9 :  if(au_units==0) then
    3358                 :           9 :    write(eps_unt,'(a)')'#energy (eV),sigma_1(Ohm-1cm-1),sigma_2(Ohm-1cm-1),epsilon_1(cgs),epsilon_2(cgs)'
    3359                 :             :  else
    3360                 :           0 :    write(eps_unt,'(a)')'#energy (Ha),sigma_1(au),sigma_2(au),epsilon_1(au),epsilon_2(au)'
    3361                 :             :  endif
    3362                 :             : 
    3363         [ -  + ]:           9 :  if (open_file(trim(filnam_out_sig)//'_abs',msg,newunit=abs_unt,status='replace',action="write")/=0) then
    3364                 :           0 :    ABI_ERROR(msg)
    3365                 :             :  end if
    3366         [ +  - ]:           9 :  if(au_units==0) then
    3367                 :           9 :    write(abs_unt,'(a)')'#energy(eV),nomega,komega,refl. s,refl. p,abso.(cm-1)'
    3368                 :             :  else
    3369                 :           0 :    write(abs_unt,'(a)')'#energy(Ha),nomega,komega,refl. s,refl. p,abso.(au)'
    3370                 :             :  endif
    3371                 :             : 
    3372   [ -  +  +  -  :          27 :  ABI_MALLOC(fct,(npti))
          +  -  +  -  -  
                +  -  + ]
    3373                 :             : 
    3374                 :             : !loop on the initial energy grid
    3375         [ +  + ]:        8281 :  do ip=1,npti
    3376                 :             :    !!! Taylor expansion up to second order of fcti at xx=xi(ii) for each ii
    3377                 :             :    !!! Then, in each discretization interval, the integral can be performed analytically
    3378                 :        8272 :    pole=xi(ip)
    3379                 :        8272 :    dx=(xi(npti)-xi(1))/dble(npti-1)
    3380                 :        8272 :    xsum=zero
    3381         [ +  + ]:     8082256 :    do ii=1,npti
    3382                 :     8073984 :      xx=xi(ii)
    3383                 :     8082256 :      fct(ii)=fcti(ii)*pole/(xx+pole)
    3384                 :             :    enddo
    3385         [ +  + ]:     8082256 :    do ii=1,npti
    3386                 :     8073984 :      xx=xi(ii)
    3387                 :     8073984 :      ff=fct(ii)
    3388                 :     8073984 :      ffp=zero
    3389                 :     8073984 :      ffpp=zero
    3390         [ +  + ]:     8073984 :      if(ii<=npti-3) then
    3391                 :     8049168 :        ffp=(four*fct(ii+1)-three*fct(ii)-fct(ii+2))/dx/two
    3392                 :             :        ffpp=(-fct(ii+3)+four*fct(ii+2)-five*fct(ii+1)+&
    3393                 :     8049168 : &          two*fct(ii))/dx/dx
    3394                 :             :      endif
    3395                 :     8073984 :      xx2=xx+half*dx
    3396                 :     8073984 :      xx1=zero
    3397         [ +  + ]:     8073984 :      if(ii>1) xx1=xx-half*dx
    3398                 :             :      xsum=xsum+ff*log(abs((xx2-pole)/(xx1-pole)))+ffp*(xx2-xx1+(pole-xx)*log(abs((xx2-pole)/(xx1-pole))))+&
    3399                 :     8082256 : & half*ffpp*((xx-pole)**2*log(abs((xx2-pole)/(xx1-pole)))+(xx2**2-xx1**2+(two*pole-four*xx)*(xx2-xx1))/two)
    3400                 :             :    enddo
    3401         [ +  + ]:        8272 :    if(pole<tol3) xsum=zero
    3402                 :             : 
    3403                 :             : !  Calculate the derivated optical quantities and output the value
    3404                 :        8272 :    sigma2=(-two/pi)*xsum
    3405                 :        8272 :    eps1=one-(four_pi*sigma2/(pole))
    3406                 :        8272 :    eps2=four*fcti(ip)*pi/(pole)
    3407                 :             : 
    3408                 :             : !  A special treatment of the case where eps2 is very small compared to eps1 is needed
    3409         [ +  + ]:        8272 :    if(eps2**2 > eps1**2 * tol12)then
    3410                 :        4793 :      nomega=sqrt(half*(eps1 + sqrt(eps1**2 + eps2**2)))
    3411                 :        4793 :      komega=sqrt(half*(-eps1 + sqrt(eps1**2 + eps2**2)))
    3412                 :        4793 :      abso=four_pi*fcti(ip)/(nomega*Speed_Light)
    3413         [ +  + ]:        3479 :    else if(eps1>zero)then
    3414                 :        3214 :      nomega=sqrt(half*(eps1 + sqrt(eps1**2 + eps2**2)))
    3415                 :        3214 :      komega=half*abs(eps2/sqrt(eps1))
    3416                 :        3214 :      abso=four_pi*fcti(ip)/(nomega*Speed_Light)
    3417         [ +  - ]:         265 :    else if(eps1<zero)then
    3418                 :         265 :      nomega=half*abs(eps2/sqrt(-eps1))
    3419                 :         265 :      komega=sqrt(half*(-eps1 + sqrt(eps1**2 + eps2**2)))
    3420                 :         265 :      abso=two*sqrt(-eps1)*pole/(Speed_Light)
    3421                 :             :    end if
    3422                 :             : 
    3423                 :        8272 :    epsc=cmplx(eps1,eps2,kind=dp)
    3424                 :        8272 :    cos_phi=cmplx(cos(phi),kind=dp)
    3425                 :        8272 :    sin_phi=cmplx(sin(phi),kind=dp)
    3426                 :        8272 :    sqroot=sqrt(epsc-sin_phi*sin_phi)
    3427                 :        8272 :    crefl_s=(cos_phi-sqroot)/(cos_phi+sqroot)
    3428                 :        8272 :    crefl_p=(epsc*cos_phi-sqroot)/(epsc*cos_phi+sqroot)
    3429                 :             : 
    3430                 :        8272 :    refl_s=real(crefl_s*conjg(crefl_s))
    3431                 :        8272 :    refl_p=real(crefl_p*conjg(crefl_p))
    3432                 :             : 
    3433                 :        8272 :    sigma1=fcti(ip)
    3434         [ +  - ]:        8272 :    if(au_units==0) then
    3435                 :        8272 :      pole=pole*Ha_eV
    3436                 :        8272 :      sigma1=sigma1*Ohmcm
    3437                 :        8272 :      sigma2=sigma2*Ohmcm
    3438                 :        8272 :      abso=abso*Ohmcm*Speed_Light/(Speed_Light_SI*four_pi*eps0)
    3439                 :             :    endif
    3440                 :        8272 :    write(eps_unt,'(5e18.10)') pole,sigma1,sigma2,eps1,eps2
    3441                 :        8281 :    write(abs_unt,'(6e18.10)') pole,nomega,komega,refl_s,refl_p,abso
    3442                 :             : 
    3443                 :             :  end do
    3444                 :             : 
    3445                 :           9 :  close(eps_unt)
    3446                 :           9 :  close(abs_unt)
    3447                 :             : 
    3448         [ -  + ]:           9 :  ABI_FREE(fct)
    3449                 :             : 
    3450                 :           9 : end subroutine msig
    3451                 :             : !!***
    3452                 :             : 
    3453                 :             : end module m_conducti
    3454                 :             : !!***
        

Generated by: LCOV version 2.3-1