LCOV - code coverage report
Current view: top level - src/65_paw - m_paw_optics.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.4 % 1214 903
Test Date: 2026-11-06 01:31:13 Functions: 85.7 % 7 6
Branches: 46.4 % 2624 1218

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_paw_optics
       2                 :             : !! NAME
       3                 :             : !!  m_paw_optics
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module contains several routines related to conductivity:
       7                 :             : !!    optical conductivity, X spectroscopy, linear susceptibility, ...
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (C) 2018-2026 ABINIT group (SM,VR,FJ,MT,NB,PGhosh)
      11                 :             : !! This file is distributed under the terms of the
      12                 :             : !! GNU General Public License, see ~abinit/COPYING
      13                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !!
      15                 :             : !! SOURCE
      16                 :             : 
      17                 :             : #if defined HAVE_CONFIG_H
      18                 :             : #include "config.h"
      19                 :             : #endif
      20                 :             : 
      21                 :             : #include "abi_common.h"
      22                 :             : 
      23                 :             : ! nvtx related macro definition
      24                 :             : #include "nvtx_macros.h"
      25                 :             : 
      26                 :             : MODULE m_paw_optics
      27                 :             : 
      28                 :             :  use defs_basis
      29                 :             :  use m_xmpi
      30                 :             :  use m_errors
      31                 :             :  use m_wffile
      32                 :             :  use m_abicore
      33                 :             :  use m_hdr
      34                 :             :  use m_dtset
      35                 :             :  use m_dtfil
      36                 :             :  use m_nctk
      37                 :             :  use netcdf
      38                 :             : 
      39                 :             :  use defs_datatypes, only : pseudopotential_type
      40                 :             :  use defs_abitypes,  only : MPI_type
      41                 :             :  use m_time,         only : timab
      42                 :             :  use m_io_tools,     only : open_file,get_unit,close_unit
      43                 :             :  use m_pawpsp,       only : pawpsp_init_core
      44                 :             :  use m_paw_atomorb,  only : atomorb_type,destroy_atomorb,copy_atomorb
      45                 :             :  use m_pawrad,       only : pawrad_type,pawrad_deducer0,simp_gen,nderiv_gen,poisson
      46                 :             :  use m_pawtab,       only : pawtab_type
      47                 :             :  use m_pawcprj,      only : pawcprj_type,pawcprj_alloc,pawcprj_get, &
      48                 :             : &                           pawcprj_free,pawcprj_mpi_allgather,pawcprj_pack
      49                 :             :  use m_pawang,       only : pawang_type
      50                 :             :  use m_paw_denpot,   only : pawdensities,pawkindensities,pawdenpot
      51                 :             :  use m_paw_an,       only : paw_an_type,paw_an_init,paw_an_free,paw_an_copy
      52                 :             :  use m_pawrhoij,     only : pawrhoij_type
      53                 :             :  use m_paw_ij,       only : paw_ij_type
      54                 :             :  use m_paw_onsite,   only : pawnabla_init,pawnabla_core_init
      55                 :             :  use m_paw_sphharm,  only : setnabla_ylm
      56                 :             :  use m_pawxc,        only : pawxc,pawxcm,pawxc_get_xclevel,pawxc_get_usekden
      57                 :             :  use m_rcpaw,        only : rcpaw_type
      58                 :             :  use m_mpinfo,       only : destroy_mpi_enreg,nullify_mpi_enreg,initmpi_seq,proc_distrb_cycle
      59                 :             :  use m_numeric_tools,only : kramerskronig
      60                 :             :  use m_geometry,     only : metric
      61                 :             :  use m_hide_lapack,  only : matrginv
      62                 :             :  use m_abi_linalg,   only : abi_xgemm
      63                 :             :  use m_paral_atom,   only : get_my_atmtab,free_my_atmtab
      64                 :             : #if defined(HAVE_GPU_MARKERS)
      65                 :             :  use m_nvtx
      66                 :             :  use m_nvtx_data
      67                 :             : #endif
      68                 :             : 
      69                 :             :  implicit none
      70                 :             : 
      71                 :             :  private
      72                 :             : 
      73                 :             : !public procedures.
      74                 :             :  public :: optics_paw
      75                 :             :  public :: optics_paw_core
      76                 :             :  public :: linear_optics_paw
      77                 :             : 
      78                 :             : !I/O parameters
      79                 :             : !Set to true to force the use of netCDF when available
      80                 :             : ! overriding the value of dtset%iomode
      81                 :             :  logical,parameter :: use_netcdf_forced=.true.
      82                 :             : !Set to true to use netcdf-MPIIO when available
      83                 :             :  logical,parameter :: use_netcdf_mpiio=.true.
      84                 :             : !Set to true to compute/write only half of the (n,m) dipoles
      85                 :             :  logical,parameter :: compute_half_dipoles=.true.
      86                 :             : !Set to true to use unlimited dimensions in netCDF file (experimental)
      87                 :             : !  This is not mandatory because we know exactly the amount of data to write
      88                 :             : !    and seems to impact performances negatively...
      89                 :             : !    Not compatible with compute_half_dipoles=.true.
      90                 :             :  logical,parameter :: use_netcdf_unlimited=.false.
      91                 :             : 
      92                 :             : !Computation parameters
      93                 :             : !Target memory (in bytes) of the work arrays for one block of bands in optics_paw_dipoles_k
      94                 :             :  real(dp),parameter :: dipoles_blk_mem=512._dp*1024._dp**2
      95                 :             : 
      96                 :             : CONTAINS  !========================================================================================
      97                 :             : !!***
      98                 :             : 
      99                 :             : !----------------------------------------------------------------------
     100                 :             : 
     101                 :             : !!****f* m_paw_optics/optics_paw
     102                 :             : !! NAME
     103                 :             : !! optics_paw
     104                 :             : !!
     105                 :             : !! FUNCTION
     106                 :             : !! Compute matrix elements need for optical conductivity (in the PAW context) and store them in a file
     107                 :             : !!  Matrix elements = <Phi_i|Nabla|Phi_j>
     108                 :             : !!
     109                 :             : !! INPUTS
     110                 :             : !!  atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
     111                 :             : !!  cg(2,mcg)=planewave coefficients of wavefunctions.
     112                 :             : !!  cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk>
     113                 :             : !!                                          and each |p_lmn> non-local projector
     114                 :             : !!  dimcprj(natom)=array of dimensions of array cprj (not ordered)
     115                 :             : !!  dtfil <type(datafiles_type)>=variables related to files
     116                 :             : !!  dtset <type(dataset_type)>=all input variables for this dataset
     117                 :             : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
     118                 :             : !!  kg(3,mpw*mkmem)=reduced planewave coordinates.
     119                 :             : !!  mband=maximum number of bands
     120                 :             : !!  mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
     121                 :             : !!  mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
     122                 :             : !!  mkmem =number of k points treated by this node.
     123                 :             : !!  mpi_enreg=information about MPI parallelization
     124                 :             : !!  mpsang =1+maximum angular momentum for nonlocal pseudopotentials
     125                 :             : !!  mpw=maximum dimensioned size of npw.
     126                 :             : !!  natom=number of atoms in cell.
     127                 :             : !!  nkpt=number of k points.
     128                 :             : !!  npwarr(nkpt)=number of planewaves in basis at this k point
     129                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     130                 :             : !!  pawang <type(pawang_type)>= PAW ANGular mesh discretization and related data
     131                 :             : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
     132                 :             : !!  pawrhoij(my_natom) <type(pawrhoij_type)>= PAW rhoij occupancies and related data
     133                 :             : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
     134                 :             : !!  znucl(ntypat)=atomic number of atom type
     135                 :             : !!
     136                 :             : !! OUTPUT
     137                 :             : !!  psinablapsi_out=contains the matrix elements
     138                 :             : !!   (The size of the psinablapsi_out decide whether we compute the full matrix or
     139                 :             : !!    only the diagonal part)
     140                 :             : !!   (if not present only writing in a file)
     141                 :             : !!
     142                 :             : !! SIDE EFFECTS
     143                 :             : !!
     144                 :             : !! NOTES
     145                 :             : !!
     146                 :             : !! SOURCE
     147                 :             : 
     148                 :        2316 :  subroutine optics_paw(atindx1,cg,cprj,dimcprj,dtfil,dtset,eigen0,gprimd,hdr,kg,&
     149                 :        1158 : &               mband,mcg,mcprj,mkmem,mpi_enreg,mpsang,mpw,natom,nkpt,npwarr,nsppol,&
     150   [ +  +  +  -  :        1158 : &               pawang,pawrad,pawrhoij,pawtab,znucl,psinablapsi_out)
                   -  + ]
     151                 :             : 
     152                 :             : !Arguments ------------------------------------
     153                 :             : !scalars
     154                 :             :  integer,intent(in) :: mband,mcg,mcprj,mkmem,mpsang,mpw,natom,nkpt,nsppol
     155                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     156                 :             :  type(datafiles_type),intent(in) :: dtfil
     157                 :             :  type(dataset_type),intent(in) :: dtset
     158                 :             :  type(hdr_type),intent(inout) :: hdr
     159                 :             :  type(pawang_type),intent(in) :: pawang
     160                 :             :  real(dp),optional,target,intent(out) :: psinablapsi_out(:,:,:,:)
     161                 :             : !arrays
     162                 :             :  integer,intent(in) :: atindx1(natom),dimcprj(natom),npwarr(nkpt)
     163                 :             :  integer,intent(in),target :: kg(3,mpw*mkmem)
     164                 :             :  real(dp),intent(in) :: eigen0(mband*nkpt*nsppol)
     165                 :             :  real(dp),intent(in) :: gprimd(3,3),znucl(dtset%ntypat)
     166                 :             :  real(dp),intent(inout) :: cg(2,mcg)
     167                 :             :  type(pawcprj_type),target,intent(inout) :: cprj(natom,mcprj)
     168                 :             :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
     169                 :             :  type(pawrhoij_type),intent(inout) :: pawrhoij(mpi_enreg%my_natom)
     170                 :             :  type(pawtab_type),target,intent(inout) :: pawtab(dtset%ntypat)
     171                 :             : 
     172                 :             : !Local variables-------------------------------
     173                 :             : !scalars
     174                 :             :  integer,parameter :: master=0
     175                 :             :  integer :: bsize,iomode,bdtot_index,cplex,etiq,fformopt,iatom,ib,ibg
     176                 :             :  integer :: icg,ierr,ikg,ikpt,ount,ncid,varid
     177                 :             :  integer :: iorder_cprj,ipw,isppol,istwf_k,itypat
     178                 :             :  integer :: gpu_option,iblk,iproj,j0,j0s,j1,jb,jpaw1,jpaw2,jpw1,jpw2,lmn_size,lmnmax,mband_cprj
     179                 :             :  integer :: me_band_io,my_j0,my_j1,nbj_io,nent,nproc_band_io,option_core
     180                 :             :  integer :: my_nspinor,nband_k,nband_cprj_k,nproj,npw_k,sender,me,me_fft,master_spfftband,pnp_size
     181                 :             :  integer :: spaceComm_band,spaceComm_bandspinorfft,spaceComm_fft,spaceComm_kpt
     182                 :             :  integer :: spaceComm_spinorfft,spaceComm_w
     183                 :             :  integer, parameter :: NO_FILE_OUT=-1
     184                 :             :  logical :: already_has_nabla,cprj_paral_band,mykpt,iomode_etsf_mpiio
     185                 :             :  logical :: i_am_master,i_am_master_kpt,i_am_master_band,i_am_master_spfft,nc_unlimited,store_half_dipoles
     186                 :             :  logical :: diag_only
     187                 :             :  real(dp) :: el_temp
     188                 :             :  character(len=500) :: msg
     189                 :             :  type(nctkdim_t) :: nctkdim
     190                 :             : !arrays
     191                 :             :  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),tmp_shape(3)
     192                 :        1158 :  integer, contiguous, pointer :: kg_k(:,:)
     193                 :        1158 :  integer,allocatable :: atom_off(:),lmn_at(:),nlmn(:),row_atom(:)
     194                 :             :  real(dp) :: kpoint(3),tsec(2)
     195                 :        1158 :  real(dp),allocatable :: cprj_pk(:,:),kpg_k(:,:),nabla_at(:,:,:,:),soc_at(:,:,:,:,:,:)
     196                 :        1158 :  real(dp),pointer :: psinablapsi(:,:,:),psinablapsi_w(:,:,:),psi_blk(:,:,:)
     197                 :        1158 :  type(coeff5_type),allocatable :: phisocphj(:)
     198                 :        1158 :  type(pawcprj_type),pointer :: cprj_k(:,:),cprj_k_loc(:,:)
     199                 :             :  type(nctkarr_t) :: nctk_arrays(1)
     200                 :             : 
     201                 :             : ! ************************************************************************
     202                 :             : 
     203                 :             :  DBG_ENTER("COLL")
     204                 :        1158 :  call timab(1184,1,tsec)
     205                 :             :  ABI_NVTX_START_RANGE(NVTX_OPTICS_PAW)
     206                 :             : 
     207                 :             : !Compatibility tests
     208         [ -  + ]:        1158 :  ABI_CHECK(mkmem/=0,"mkmem==0 not supported anymore!")
     209   [ -  +  -  - ]:        1158 :  ABI_CHECK(mpi_enreg%paral_spinor==0.or.dtset%pawspnorb==0,"spinor parallelization not supported with SOC!")
     210                 :             : !  MJV 6/12/2008: looks like mpi_enreg may not be completely initialized here
     211                 :             :  if (xmpi_paral==1) then
     212         [ +  + ]:        4632 :    tmp_shape = shape(mpi_enreg%proc_distrb)
     213         [ -  + ]:        1158 :    if (nkpt > tmp_shape(1)) then
     214                 :           0 :      ABI_BUG('problem with proc_distrb!')
     215                 :             :    end if
     216                 :             :  end if
     217                 :             : 
     218                 :             : !Init parallelism
     219                 :        1158 :  spaceComm_w=mpi_enreg%comm_cell
     220         [ +  + ]:        1158 :  if (mpi_enreg%paral_kgb==1) then
     221                 :         844 :    spaceComm_kpt=mpi_enreg%comm_kpt
     222                 :         844 :    spaceComm_fft=mpi_enreg%comm_fft
     223                 :         844 :    spaceComm_band=mpi_enreg%comm_band
     224                 :         844 :    spaceComm_spinorfft=mpi_enreg%comm_spinorfft
     225                 :         844 :    spaceComm_bandspinorfft=mpi_enreg%comm_bandspinorfft
     226                 :             :  else
     227                 :         314 :    spaceComm_kpt=mpi_enreg%comm_kpt
     228                 :         314 :    spaceComm_fft=xmpi_comm_self
     229                 :         314 :    spaceComm_band=mpi_enreg%comm_band
     230                 :         314 :    spaceComm_spinorfft=xmpi_comm_self
     231                 :             :    !Plane-wave and on-site contributions are reduced together over this communicator
     232                 :             :    !(comm_band is xmpi_comm_self here, except for band parallelism (paralbd=1))
     233                 :         314 :    spaceComm_bandspinorfft=spaceComm_band
     234                 :             :  end if
     235                 :        1158 :  me=xmpi_comm_rank(spaceComm_w)
     236                 :        1158 :  i_am_master=(me==master)
     237                 :        1158 :  i_am_master_kpt=(xmpi_comm_rank(spaceComm_kpt)==master)
     238                 :        1158 :  i_am_master_band=(xmpi_comm_rank(spaceComm_band)==master)
     239                 :        1158 :  i_am_master_spfft=(xmpi_comm_rank(spaceComm_spinorfft)==master)
     240                 :        1158 :  me_fft=xmpi_comm_rank(spaceComm_fft)
     241                 :        1158 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     242                 :             : 
     243                 :             : !GPU: only OpenMP offload variant supported
     244                 :             :  gpu_option=dtset%gpu_option
     245                 :             :  if (gpu_option/=ABI_GPU_OPENMP) gpu_option=ABI_GPU_DISABLED
     246                 :             : #ifndef HAVE_OPENMP_OFFLOAD
     247                 :        1158 :  gpu_option=ABI_GPU_DISABLED
     248                 :             : #endif
     249                 :             : 
     250                 :             : !Check wether we write in file or save the matrix elements in psinablapsi_out
     251                 :             : !and if we need to compute the full matrix or only the diagonal part
     252                 :        1158 :  iomode=dtset%iomode
     253                 :        1158 :  diag_only = .false.
     254                 :        1158 :  store_half_dipoles = .false.
     255         [ +  + ]:        1158 :  if (present(psinablapsi_out)) then
     256                 :        1121 :    iomode = NO_FILE_OUT
     257                 :        1121 :    iomode_etsf_mpiio = .false.
     258                 :        1121 :    nc_unlimited = .false.
     259                 :        1121 :    bsize = size(psinablapsi_out(1,1,:,1))
     260         [ +  - ]:        1121 :    if (bsize ==  mband) then
     261                 :        1121 :       diag_only = .true.
     262                 :        1121 :       store_half_dipoles = .true. !FB ??
     263         [ #  # ]:           0 :    else if (bsize == mband*(mband+1)/2) then
     264                 :           0 :       diag_only = .false.
     265                 :           0 :       store_half_dipoles = .true.
     266         [ #  # ]:           0 :    else if (bsize == mband**2) then
     267                 :           0 :       diag_only = .false.
     268                 :           0 :       store_half_dipoles = .false.
     269                 :             :    else
     270                 :           0 :       msg = "Wrong dimensions of psinablapsi_out!"
     271                 :           0 :       ABI_ERROR(msg)
     272                 :             :    end if
     273   [ +  +  +  +  :     2906753 :    psinablapsi_out = zero
             +  +  +  + ]
     274                 :             :  end if
     275                 :             : 
     276                 :             : !----------------------------------------------------------------------------------
     277                 :             : !1- Opening of OPT file and header writing
     278                 :             : !----------------------------------------------------------------------------------
     279                 :             : 
     280                 :             : #if defined(HAVE_GPU_MARKERS)
     281                 :             :  call nvtxStartRange("header_write")
     282                 :             : #endif
     283         [ +  + ]:        1158 :  if (iomode /= NO_FILE_OUT) then
     284                 :             : !  I/O mode is netCDF or Fortran
     285                 :             :    iomode=merge(IO_MODE_ETSF,IO_MODE_FORTRAN_MASTER,dtset%iomode==IO_MODE_ETSF)
     286                 :          37 :    if (use_netcdf_forced) iomode=IO_MODE_ETSF
     287                 :             : 
     288                 :             :  !  (master proc only)
     289         [ +  + ]:          37 :    if (i_am_master) then
     290                 :          13 :      fformopt=610 ; if (compute_half_dipoles) fformopt=620
     291                 :             : !  ====> NETCDF format
     292                 :             :    if (iomode==IO_MODE_ETSF) then
     293                 :             : !    Open/create nc file
     294         [ -  + ]:          13 :      NCF_CHECK(nctk_open_create(ncid,nctk_ncify(dtfil%fnameabo_app_opt),xmpi_comm_self))
     295                 :             : !    Write header data
     296         [ -  + ]:          13 :      NCF_CHECK(hdr%ncwrite(ncid,fformopt,nc_define=.true.))
     297                 :             : !    Define dims and array for dipole variables
     298                 :          13 :      nctk_arrays(1)%name="dipole_valence_valence"
     299                 :          13 :      nctk_arrays(1)%dtype="dp"
     300                 :          13 :      nc_unlimited=(use_netcdf_unlimited.and.(.not.(nctk_has_mpiio.and.use_netcdf_mpiio)))
     301                 :             :      if (nc_unlimited) then
     302                 :             :        nctkdim%name="unlimited_bands"
     303                 :             :        nctkdim%value=NF90_UNLIMITED
     304                 :             :        NCF_CHECK(nctk_def_dims(ncid,nctkdim))
     305                 :             :        nctk_arrays(1)%shape_str=&
     306                 :             : &      "complex,number_of_cartesian_directions,max_number_of_states,number_of_kpoints,number_of_spins,unlimited_bands"
     307                 :             :      else if (compute_half_dipoles) then
     308                 :          13 :        nctkdim%name="max_number_of_state_pairs"
     309                 :          13 :        nctkdim%value=(mband*(mband+1))/2
     310         [ -  + ]:          13 :        NCF_CHECK(nctk_def_dims(ncid,nctkdim))
     311                 :             :        nctk_arrays(1)%shape_str=&
     312                 :          13 : &      "complex,number_of_cartesian_directions,max_number_of_state_pairs,number_of_kpoints,number_of_spins"
     313                 :             :      else
     314                 :             :        nctk_arrays(1)%shape_str=&
     315                 :             : &      "complex,number_of_cartesian_directions,max_number_of_states,max_number_of_states,number_of_kpoints,number_of_spins"
     316                 :             :      end if
     317         [ -  + ]:          13 :      NCF_CHECK(nctk_def_arrays(ncid, nctk_arrays))
     318         [ -  + ]:          13 :      NCF_CHECK(nctk_set_atomic_units(ncid, "dipole_valence_valence"))
     319                 :             : !    Write eigenvalues
     320         [ -  + ]:          13 :      NCF_CHECK(nctk_set_datamode(ncid))
     321                 :          13 :      varid=nctk_idname(ncid,"eigenvalues")
     322   [ +  +  -  +  :          52 :      NCF_CHECK(nf90_put_var(ncid,varid,reshape(eigen0,[mband,nkpt,nsppol])))
                   -  - ]
     323                 :             :      !Close file here because the rest has possibly to be written with collective I/O
     324         [ -  + ]:          13 :      NCF_CHECK(nf90_close(ncid))
     325                 :             : !  ====> Standard FORTRAN binary format
     326                 :             :      else if (iomode==IO_MODE_FORTRAN_MASTER) then
     327                 :             :        if (open_file(dtfil%fnameabo_app_opt,msg,newunit=ount,form="unformatted",status="unknown")/= 0) then
     328                 :             :          ABI_ERROR(msg)
     329                 :             :        end if
     330                 :             :        call hdr%fort_write(ount,fformopt,ierr,rewind=.true.)
     331                 :             :        write(ount)(eigen0(ib),ib=1,mband*nkpt*nsppol)
     332                 :             :      else
     333                 :             :        msg = "Wrong OPT file format!"
     334                 :             :        ABI_BUG(msg)
     335                 :             :      end if ! File format
     336                 :             :    end if ! master node
     337                 :          37 :    call xmpi_bcast(iomode,master,spaceComm_w,ierr)  ! Seems mandatory; why ?
     338   [ +  -  -  + ]:          37 :    iomode_etsf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio)
     339                 :          37 :    nc_unlimited=(iomode==IO_MODE_ETSF.and.use_netcdf_unlimited.and.(.not.iomode_etsf_mpiio)) ! UNLIMITED not compatible with mpi-io
     340                 :          37 :    store_half_dipoles=(compute_half_dipoles.and.(.not.nc_unlimited))
     341                 :             :  end if
     342                 :             : #if defined(HAVE_GPU_MARKERS)
     343                 :             :  call nvtxEndRange()
     344                 :             : #endif
     345                 :             : 
     346                 :             : !----------------------------------------------------------------------------------
     347                 :             : !2- Computation of on-site contribution: <phi_i|nabla|phi_j>-<tphi_i|nabla|tphi_j>
     348                 :             : !----------------------------------------------------------------------------------
     349                 :             : 
     350                 :             : #if defined(HAVE_GPU_MARKERS)
     351                 :             :  call nvtxStartRange("pawnabla_init")
     352                 :             : #endif
     353   [ +  -  -  + ]:        1158 :  already_has_nabla=all(pawtab(:)%has_nabla==2)
     354                 :        1158 :  call pawnabla_init(mpsang,dtset%ntypat,pawrad,pawtab)
     355                 :             : 
     356                 :             : !Get electronic temperature from dtset
     357   [ -  +  -  -  :        1158 :  el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
                   -  - ]
     358                 :             : #if defined(HAVE_GPU_MARKERS)
     359                 :             :  call nvtxEndRange()
     360                 :             : #endif
     361                 :             : 
     362                 :             : !Compute spin-orbit contributions if necessary
     363         [ +  + ]:        1158 :  if (dtset%pawspnorb==1) then
     364                 :           5 :    option_core=0
     365                 :             :    call pawnabla_soc_init(el_temp,phisocphj,option_core,dtset%ixc,mpi_enreg%my_natom,natom,&
     366                 :             : &       dtset%nspden,dtset%ntypat,pawang,pawrad,pawrhoij,pawtab,dtset%pawxcdev,&
     367                 :             : &       dtset%spnorbscl,dtset%typat,dtset%xc_denpos,dtset%xc_taupos,znucl,&
     368                 :           5 : &       comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab)
     369                 :             :  else
     370         [ -  + ]:        1153 :    ABI_MALLOC(phisocphj,(0))
     371                 :             :  end if
     372                 :             : 
     373                 :             : !----------------------------------------------------------------------------------
     374                 :             : !3- Computation of <psi_n|-i.nabla|psi_m> for each k
     375                 :             : !----------------------------------------------------------------------------------
     376                 :             : 
     377                 :             : #if defined(HAVE_GPU_MARKERS)
     378                 :             :  call nvtxStartRange("prepare_netcdf")
     379                 :             : #endif
     380                 :             : !Prepare valence-valence dipoles writing
     381                 :             : !In case of netCDF access to OPT file, prepare collective I/O
     382         [ +  + ]:        1158 :  if (iomode == IO_MODE_ETSF) then
     383         [ +  - ]:          37 :    if (iomode_etsf_mpiio) then
     384         [ +  + ]:          37 :      if (i_am_master_spfft) then
     385         [ -  + ]:          23 :        NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt),spaceComm_band))
     386                 :          23 :        varid=nctk_idname(ncid,"dipole_valence_valence")
     387         [ +  + ]:          23 :        if (xmpi_comm_size(spaceComm_w)>1) then
     388         [ -  + ]:          18 :          NCF_CHECK(nctk_set_collective(ncid,varid))
     389                 :             :        end if
     390         [ -  + ]:          23 :        NCF_CHECK(nctk_set_datamode(ncid))
     391                 :             :      end if
     392         [ #  # ]:           0 :    else if (i_am_master) then
     393         [ #  # ]:           0 :      NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt),xmpi_comm_self))
     394                 :           0 :      varid=nctk_idname(ncid,"dipole_valence_valence")
     395                 :             :      if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then
     396                 :             :        NCF_CHECK(nctk_set_collective(ncid,varid))
     397                 :             :      end if
     398         [ #  # ]:           0 :      NCF_CHECK(nctk_set_datamode(ncid))
     399                 :             :    end if
     400                 :             :  end if
     401         [ +  + ]:        1158 :  if (iomode /= NO_FILE_OUT) then
     402         [ +  - ]:          37 :    if (iomode_etsf_mpiio) then
     403                 :             :      !If MPI-IO, bands are treated by blocks of nbj_io columns: store only these columns
     404                 :             :      !psinablapsi holds the block written by current proc, psinablapsi_w is a work buffer
     405                 :          37 :      nproc_band_io=xmpi_comm_size(spaceComm_band)
     406                 :          37 :      me_band_io=xmpi_comm_rank(spaceComm_band)
     407                 :          37 :      nbj_io=int(dipoles_blk_mem/(96._dp*real(mband,dp)))
     408                 :          37 :      nbj_io=max(1,min(nbj_io,mband))
     409   [ -  +  +  -  :         111 :      ABI_MALLOC(psinablapsi,(2,3,nbj_io*mband))
          +  -  +  -  -  
                +  -  + ]
     410   [ -  +  +  -  :          74 :      ABI_MALLOC(psinablapsi_w,(2,3,nbj_io*mband))
             -  +  -  + ]
     411                 :             :    else
     412                 :             :      !If not, store all (ib,jb) pairs (or half)
     413         [ #  # ]:           0 :      bsize=mband**2 ; if (store_half_dipoles) bsize=(mband*(mband+1))/2
     414   [ #  #  #  #  :           0 :      ABI_MALLOC(psinablapsi,(2,3,bsize))
          #  #  #  #  #  
                #  #  # ]
     415   [ #  #  #  #  :           0 :      psinablapsi=zero
                   #  # ]
     416                 :             :    end if
     417         [ +  + ]:         148 :    pnp_size=size(psinablapsi)
     418                 :             :  end if
     419                 :             : #if defined(HAVE_GPU_MARKERS)
     420                 :             :  call nvtxEndRange()
     421                 :             : #endif
     422                 :             : !Note: psinablapsi accumulates both plane-wave and on-site (PAW+SOC) contributions
     423                 :             : 
     424                 :             : #if defined(HAVE_GPU_MARKERS)
     425                 :             :  call nvtxStartRange("alloc")
     426                 :             : #endif
     427                 :             : !Determine if cprj datastructure is distributed over bands
     428                 :        1158 :  mband_cprj=mcprj/(my_nspinor*mkmem*nsppol)
     429                 :        1158 :  cprj_paral_band=(mband_cprj<mband)
     430                 :             : 
     431                 :             : !Store on-site matrix elements for each atom in plain arrays (for optics_paw_dipoles_k)
     432   [ -  +  +  -  :        3474 :  ABI_MALLOC(lmn_at,(natom))
          +  -  +  -  -  
                +  -  + ]
     433         [ +  + ]:        3496 :  do iatom=1,natom
     434                 :        3496 :    lmn_at(iatom)=pawtab(dtset%typat(iatom))%lmn_size
     435                 :             :  end do
     436         [ +  + ]:        3496 :  lmnmax=maxval(lmn_at)
     437   [ -  +  +  -  :        5790 :  ABI_MALLOC(nabla_at,(3,lmnmax,lmnmax,natom))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     438   [ -  +  +  -  :        5795 :  ABI_MALLOC(soc_at,(2,2,3,lmnmax,lmnmax,merge(natom,1,dtset%pawspnorb==1)))
          -  +  +  -  +  
          +  -  +  +  -  
          +  -  +  -  -  
                +  -  + ]
     439   [ +  +  +  +  :     2287693 :  nabla_at=zero ; soc_at=zero
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                      + ]
     440         [ +  + ]:        3496 :  do iatom=1,natom
     441                 :        2338 :    lmn_size=lmn_at(iatom)
     442   [ +  +  +  +  :      620218 :    nabla_at(:,1:lmn_size,1:lmn_size,iatom)=pawtab(dtset%typat(iatom))%nabla_ij(:,1:lmn_size,1:lmn_size)
                   +  + ]
     443         [ +  + ]:        3496 :    if (dtset%pawspnorb==1) then
     444   [ +  +  +  +  :       28340 :      soc_at(:,:,:,1:lmn_size,1:lmn_size,iatom)=phisocphj(iatom)%value(:,:,:,1:lmn_size,1:lmn_size)
          +  +  +  +  +  
                      + ]
     445                 :             :    end if
     446                 :             :  end do
     447                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     448                 :             :  !$OMP TARGET ENTER DATA MAP(to:lmn_at,nabla_at,soc_at) IF(gpu_option==ABI_GPU_OPENMP)
     449                 :             : #endif
     450                 :             : #if defined(HAVE_GPU_MARKERS)
     451                 :             :  call nvtxEndRange()
     452                 :             : #endif
     453                 :             : 
     454                 :             : !LOOP OVER SPINS
     455                 :        1158 :  ibg=0;icg=0
     456                 :        1158 :  bdtot_index=0
     457         [ +  + ]:        2316 :  do isppol=1,nsppol
     458                 :             : 
     459                 :             : !  LOOP OVER k POINTS
     460                 :        1158 :    ikg=0
     461         [ +  + ]:       38443 :    do ikpt=1,nkpt
     462                 :             : #if defined(HAVE_GPU_MARKERS)
     463                 :             :      call nvtxStartRange("k-point step")
     464                 :             : #endif
     465                 :             : 
     466   [ +  +  +  - ]:       36127 :      if (iomode == NO_FILE_OUT) psinablapsi => psinablapsi_out(:,:,:,ikpt)
     467                 :             : 
     468                 :       36127 :      etiq=ikpt+(isppol-1)*nkpt
     469                 :       36127 :      nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
     470         [ +  + ]:      326207 :      master_spfftband=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol))
     471                 :             : 
     472                 :             : !    Select k-points for current proc
     473                 :       36127 :      mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,mpi_enreg%me_kpt))
     474         [ +  + ]:       36127 :      if (mykpt) then
     475                 :             : 
     476                 :             : !      Data depending on k-point
     477                 :       16493 :        npw_k=npwarr(ikpt)
     478                 :       16493 :        istwf_k=dtset%istwfk(ikpt)
     479         [ +  + ]:       16493 :        cplex=2;if (istwf_k>1) cplex=1
     480         [ +  + ]:       65972 :        kpoint(:)=dtset%kptns(:,ikpt)
     481                 :             : 
     482                 :             : #if defined(HAVE_GPU_MARKERS)
     483                 :             :        call nvtxStartRange("pawcprj_alloc")
     484                 :             : #endif
     485                 :             : !      Extract cprj for this k-point
     486         [ +  + ]:       16493 :        nband_cprj_k=nband_k;if (cprj_paral_band) nband_cprj_k=nband_k/mpi_enreg%nproc_band
     487         [ +  + ]:       16493 :        if (mkmem*nsppol/=1) then
     488                 :       16481 :          iorder_cprj=0
     489   [ -  +  +  -  :      383696 :          ABI_MALLOC(cprj_k_loc,(natom,my_nspinor*nband_cprj_k))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     490                 :       16481 :          call pawcprj_alloc(cprj_k_loc,0,dimcprj)
     491                 :             :          call pawcprj_get(atindx1,cprj_k_loc,cprj,natom,1,ibg,ikpt,iorder_cprj,isppol,&
     492                 :             : &         mband_cprj,mkmem,natom,nband_cprj_k,nband_cprj_k,my_nspinor,nsppol,dtfil%unpaw,&
     493         [ -  + ]:       16481 : &         mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
     494                 :             :        else
     495                 :          12 :          cprj_k_loc => cprj
     496                 :             :        end if
     497                 :             : 
     498                 :             : !      if cprj are distributed over bands, gather them (because we need to mix bands)
     499         [ +  + ]:       16493 :        if (cprj_paral_band) then
     500   [ -  +  +  -  :      187016 :          ABI_MALLOC(cprj_k,(natom,my_nspinor*nband_k))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     501                 :        6616 :          call pawcprj_alloc(cprj_k,0,dimcprj)
     502                 :             :          call pawcprj_mpi_allgather(cprj_k_loc,cprj_k,natom, &
     503                 :             : &             my_nspinor*nband_cprj_k,my_nspinor*mpi_enreg%bandpp,&
     504                 :        6616 : &         dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band,ierr,rank_ordered=.false.)
     505                 :             :        else
     506                 :        9877 :          cprj_k => cprj_k_loc
     507                 :             :        end if
     508                 :             : 
     509                 :             : !      Pack cprj into a contiguous array: cprj_pk(2,nproj,my_nspinor*nband_k)
     510                 :             : !      (projectors of all atoms concatenated, in cprj atom order)
     511   [ -  +  +  -  :       49479 :        ABI_MALLOC(nlmn,(natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     512         [ +  + ]:       49501 :        nlmn(:)=cprj_k(:,1)%nlmn
     513         [ +  + ]:       49501 :        nproj=sum(nlmn)
     514   [ -  +  +  -  :       49479 :        ABI_MALLOC(cprj_pk,(2,nproj*my_nspinor*nband_k))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     515                 :       16493 :        call pawcprj_pack(nlmn,cprj_k(:,1:my_nspinor*nband_k),cprj_pk)
     516                 :             : !      Offset of each atom in cprj_pk and atom of each projector
     517   [ -  +  +  -  :       32986 :        ABI_MALLOC(atom_off,(natom))
             -  +  -  + ]
     518   [ -  +  +  -  :       49479 :        ABI_MALLOC(row_atom,(nproj))
          +  -  +  -  -  
                +  -  + ]
     519                 :       49501 :        iproj=0
     520         [ +  + ]:       49501 :        do iatom=1,natom
     521                 :       33008 :          atom_off(iatom)=iproj
     522         [ +  + ]:      297088 :          row_atom(iproj+1:iproj+nlmn(iatom))=iatom
     523                 :       49501 :          iproj=iproj+nlmn(iatom)
     524                 :             :        end do
     525                 :             : 
     526                 :             : !      Compute k+G in cartesian coordinates
     527   [ -  +  +  -  :       49479 :        ABI_MALLOC(kpg_k,(3,npw_k*dtset%nspinor))
          +  -  +  -  -  
                +  -  + ]
     528                 :       16493 :        kg_k => kg(:,1+ikg:npw_k+ikg)
     529         [ +  + ]:     2330285 :        do ipw=1,npw_k
     530                 :             :          kpg_k(1,ipw)=(kpoint(1)+kg_k(1,ipw))*gprimd(1,1) &
     531                 :             : &                    +(kpoint(2)+kg_k(2,ipw))*gprimd(1,2) &
     532                 :     2313792 : &                    +(kpoint(3)+kg_k(3,ipw))*gprimd(1,3)
     533                 :             :          kpg_k(2,ipw)=(kpoint(1)+kg_k(1,ipw))*gprimd(2,1) &
     534                 :             : &                    +(kpoint(2)+kg_k(2,ipw))*gprimd(2,2) &
     535                 :     2313792 : &                    +(kpoint(3)+kg_k(3,ipw))*gprimd(2,3)
     536                 :             :          kpg_k(3,ipw)=(kpoint(1)+kg_k(1,ipw))*gprimd(3,1) &
     537                 :             : &                    +(kpoint(2)+kg_k(2,ipw))*gprimd(3,2) &
     538                 :     2330285 : &                    +(kpoint(3)+kg_k(3,ipw))*gprimd(3,3)
     539                 :             :        end do
     540   [ +  +  +  + ]:     9271661 :        kpg_k(:,1:npw_k)=two_pi*kpg_k(:,1:npw_k)
     541   [ +  +  +  +  :       21445 :        if (dtset%nspinor==2) kpg_k(1:3,npw_k+1:2*npw_k)=kpg_k(1:3,1:npw_k)
                   +  + ]
     542                 :             : #if defined(HAVE_GPU_MARKERS)
     543                 :             :        call nvtxEndRange()
     544                 :             : #endif
     545                 :             : 
     546                 :             : !      Transfer data of this k-point on GPU
     547                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     548                 :             :        !$OMP TARGET ENTER DATA MAP(to:cg(:,icg+1:icg+npw_k*my_nspinor*nband_k)) IF(gpu_option==ABI_GPU_OPENMP)
     549                 :             :        !$OMP TARGET ENTER DATA MAP(to:cprj_pk,kpg_k,atom_off,row_atom) IF(gpu_option==ABI_GPU_OPENMP)
     550                 :             : #endif
     551                 :             : 
     552                 :             : !      Select bands for current proc
     553                 :             : !      jpw1:jpw2   = bands jb for which the plane-wave contribution is computed
     554                 :             : !      jpaw1:jpaw2 = bands jb for which the on-site (PAW+SOC) contribution is computed
     555                 :       16493 :        jpw1=1 ; jpw2=nband_k ; jpaw1=1 ; jpaw2=nband_k
     556         [ +  + ]:       16493 :        if (mpi_enreg%paral_kgb==1) then
     557                 :             : !        cprj are known for all bands: distribute contiguous blocks of bands
     558                 :        6716 :          jpaw1=(mpi_enreg%me_band*nband_k)/mpi_enreg%nproc_band+1
     559                 :        6716 :          jpaw2=((mpi_enreg%me_band+1)*nband_k)/mpi_enreg%nproc_band
     560                 :             :        else if (xmpi_paral==1) then
     561                 :             : !        Bands of this k-point treated by current proc (contiguous, see distrb2)
     562                 :        9777 :          jpaw1=nband_k+1 ; jpaw2=0
     563         [ +  + ]:       88081 :          do jb=1,nband_k
     564         [ +  - ]:       88081 :            if (mpi_enreg%proc_distrb(ikpt,jb,isppol)==mpi_enreg%me_kpt) then
     565                 :       78304 :              jpaw1=min(jpaw1,jb) ; jpaw2=max(jpaw2,jb)
     566                 :             :            end if
     567                 :             :          end do
     568   [ +  +  +  -  :       88081 :          if (count(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol)==mpi_enreg%me_kpt)/=max(0,jpaw2-jpaw1+1)) then
                   -  + ]
     569                 :           0 :            ABI_BUG('Bands of a k-point are not distributed in contiguous blocks!')
     570                 :             :          end if
     571         [ +  + ]:        9777 :          if (.not.iomode_etsf_mpiio) then
     572                 :        9760 :            jpw1=jpaw1 ; jpw2=jpaw2
     573                 :             :          end if
     574                 :             :        end if
     575                 :             : !      On-site contribution is the same on all FFT procs: only one of them adds it
     576         [ +  + ]:       16493 :        if (me_fft/=0) then
     577                 :          94 :          jpaw1=1 ; jpaw2=0
     578                 :             :        end if
     579                 :             : 
     580         [ +  + ]:       16493 :        if (iomode_etsf_mpiio) then
     581                 :             : 
     582                 :             : #if defined(HAVE_GPU_MARKERS)
     583                 :             :          call nvtxStartRange("jband_loop_mpiio",5)
     584                 :             : #endif
     585                 :             : !        MPI-IO: bands are treated by super-blocks made of one block of nbj_io columns
     586                 :             : !        per band proc. Each block is computed by all procs and reduced to its owner;
     587                 :             : !        then all owners write their block with a single collective call.
     588                 :             : !        Columns j0:j1 are contiguous in the OPT file, for both full and half storage.
     589   [ -  +  -  -  :         410 :          do j0s=1,nband_k,nbj_io*nproc_band_io
             -  +  -  + ]
     590                 :         205 :            my_j0=1 ; my_j1=0
     591                 :             : #if defined(HAVE_GPU_MARKERS)
     592                 :             :            call nvtxStartRange("mpiio_blk",2)
     593                 :             : #endif
     594         [ +  + ]:         410 :            do iblk=0,nproc_band_io-1
     595                 :         293 :              j0=j0s+iblk*nbj_io
     596         [ +  + ]:         293 :              if (j0>nband_k) exit
     597                 :         205 :              j1=min(nband_k,j0+nbj_io-1)
     598         [ +  + ]:         205 :              if (iblk==me_band_io) then
     599                 :         151 :                psi_blk => psinablapsi ; my_j0=j0 ; my_j1=j1
     600                 :             :              else
     601                 :          54 :                psi_blk => psinablapsi_w
     602                 :             :              end if
     603                 :             : 
     604                 :             : #if defined(HAVE_GPU_MARKERS)
     605                 :             :              call nvtxStartRange("optics_paw_dipoles",6)
     606                 :             : #endif
     607                 :             :              call optics_paw_dipoles_k(cg(:,icg+1:icg+npw_k*my_nspinor*nband_k),cprj_pk,kpg_k,&
     608                 :             : &                 nabla_at,soc_at,lmn_at,atom_off,row_atom,cplex,istwf_k,j0,j1,jpw1,jpw2,jpaw1,jpaw2,&
     609                 :             : &                 lmnmax,mband,my_nspinor,natom,nband_k,nproj,npw_k,dtset%pawspnorb,&
     610                 :         205 : &                 (.not.store_half_dipoles),diag_only,store_half_dipoles,gpu_option,psi_blk)
     611                 :             : 
     612                 :             : #if defined(HAVE_GPU_MARKERS)
     613                 :             :              call nvtxEndRange()
     614                 :             :              call nvtxStartRange("xmpi_sum",17)
     615                 :             : #endif
     616                 :             : !            Reduction of the block on its owner
     617         [ -  + ]:         205 :              nent=merge((j1*(j1+1))/2-(j0*(j0-1))/2,(j1-j0+1)*mband,store_half_dipoles)
     618                 :         205 :              call timab(48,1,tsec)
     619         [ +  + ]:         205 :              if (mpi_enreg%paral_kgb==1) then
     620                 :         188 :                call xmpi_sum_master(psi_blk(:,:,1:nent),master,spaceComm_spinorfft,ierr)
     621                 :             :              end if
     622         [ +  + ]:         205 :              if (i_am_master_spfft) then
     623                 :         111 :                call xmpi_sum_master(psi_blk(:,:,1:nent),iblk,spaceComm_band,ierr)
     624                 :             :              end if
     625                 :         410 :              call timab(48,2,tsec)
     626                 :             : #if defined(HAVE_GPU_MARKERS)
     627                 :             :              call nvtxEndRange()
     628                 :             : #endif
     629                 :             :            end do ! iblk
     630                 :             : #if defined(HAVE_GPU_MARKERS)
     631                 :             :            call nvtxEndRange()
     632                 :             : #endif
     633                 :             : 
     634                 :             : #if defined(HAVE_GPU_MARKERS)
     635                 :             :            call nvtxStartRange("mpiio_write")
     636                 :             : #endif
     637                 :             : !          Write to OPT file: each owner writes its block
     638         [ +  + ]:         410 :            if (i_am_master_spfft) then
     639         [ +  - ]:         111 :              if (store_half_dipoles) then
     640         [ +  + ]:         666 :                nc_start_5=[1,1,(my_j0*(my_j0-1))/2+1,ikpt,isppol];nc_stride_5=[1,1,1,1,1]
     641                 :         111 :                nc_count_5=[0,0,0,0,0]
     642   [ +  +  +  + ]:         456 :                if (my_j1>=my_j0) nc_count_5=[2,3,(my_j1*(my_j1+1))/2-(my_j0*(my_j0-1))/2,1,1]
     643         [ -  + ]:         111 :                NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     644                 :             :              else
     645         [ #  # ]:           0 :                nc_start_6=[1,1,1,my_j0,ikpt,isppol];nc_stride_6=[1,1,1,1,1,1]
     646                 :           0 :                nc_count_6=[0,0,0,0,0,0]
     647   [ #  #  #  # ]:           0 :                if (my_j1>=my_j0) nc_count_6=[2,3,mband,my_j1-my_j0+1,1,1]
     648         [ #  # ]:           0 :                NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     649                 :             :              end if
     650                 :             :            end if
     651                 :             : #if defined(HAVE_GPU_MARKERS)
     652                 :             :            call nvtxEndRange()
     653                 :             : #endif
     654                 :             : 
     655                 :             :          end do ! j0s
     656                 :             : #if defined(HAVE_GPU_MARKERS)
     657                 :             :          call nvtxEndRange()
     658                 :             : #endif
     659                 :             : 
     660                 :             :        else
     661                 :             : 
     662                 :             : #if defined(HAVE_GPU_MARKERS)
     663                 :             :          call nvtxStartRange("optics_paw_dipoles_no_mpiio",2)
     664                 :             : #endif
     665                 :             : !        No MPI-IO: compute all (ib,jb) pairs at once
     666                 :             :          call optics_paw_dipoles_k(cg(:,icg+1:icg+npw_k*my_nspinor*nband_k),cprj_pk,kpg_k,&
     667                 :             : &             nabla_at,soc_at,lmn_at,atom_off,row_atom,cplex,istwf_k,1,nband_k,jpw1,jpw2,jpaw1,jpaw2,&
     668                 :             : &             lmnmax,mband,my_nspinor,natom,nband_k,nproj,npw_k,dtset%pawspnorb,.false.,&
     669                 :       16288 : &             diag_only,store_half_dipoles,gpu_option,psinablapsi)
     670                 :             : #if defined(HAVE_GPU_MARKERS)
     671                 :             :          call nvtxEndRange()
     672                 :             : #endif
     673                 :             : 
     674                 :             :        end if
     675                 :             : 
     676                 :             : !      Release data of this k-point on GPU
     677                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     678                 :             :        !$OMP TARGET EXIT DATA MAP(delete:cg(:,icg+1:icg+npw_k*my_nspinor*nband_k)) IF(gpu_option==ABI_GPU_OPENMP)
     679                 :             :        !$OMP TARGET EXIT DATA MAP(delete:cprj_pk,kpg_k,atom_off,row_atom) IF(gpu_option==ABI_GPU_OPENMP)
     680                 :             : #endif
     681                 :             : 
     682         [ +  - ]:       16493 :        if (mkmem/=0) then
     683                 :       16493 :          ibg = ibg +       my_nspinor*nband_cprj_k
     684                 :       16493 :          icg = icg + npw_k*my_nspinor*nband_k
     685                 :       16493 :          ikg = ikg + npw_k
     686                 :             :        end if
     687                 :             : 
     688                 :             : #if defined(HAVE_GPU_MARKERS)
     689                 :             :        call nvtxStartRange("free")
     690                 :             : #endif
     691         [ -  + ]:       16493 :        ABI_FREE(cprj_pk)
     692         [ -  + ]:       16493 :        ABI_FREE(nlmn)
     693         [ -  + ]:       16493 :        ABI_FREE(atom_off)
     694         [ -  + ]:       16493 :        ABI_FREE(row_atom)
     695         [ +  + ]:       16493 :        if (cprj_paral_band) then
     696                 :        6616 :          call pawcprj_free(cprj_k)
     697         [ -  + ]:        6616 :          ABI_FREE(cprj_k)
     698                 :             :        end if
     699         [ +  + ]:       16493 :        if (mkmem*nsppol/=1) then
     700                 :       16481 :          call pawcprj_free(cprj_k_loc)
     701         [ -  + ]:       16481 :          ABI_FREE(cprj_k_loc)
     702                 :             :        end if
     703         [ -  + ]:       16493 :        ABI_FREE(kpg_k)
     704                 :             : #if defined(HAVE_GPU_MARKERS)
     705                 :             :        call nvtxEndRange()
     706                 :             : #endif
     707                 :             : 
     708                 :             : !      Write to OPT file if not MPI-IO
     709         [ +  + ]:       16493 :        if (iomode /= NO_FILE_OUT) then
     710                 :             : #if defined(HAVE_GPU_MARKERS)
     711                 :             :          call nvtxStartRange("write")
     712                 :             : #endif
     713                 :             : !        >>> Reduction in case of parallelism
     714         [ -  + ]:         205 :          if (.not.iomode_etsf_mpiio) then
     715                 :           0 :            call timab(48,1,tsec)
     716                 :           0 :            call xmpi_sum_master(psinablapsi,master,spaceComm_bandspinorfft,ierr)
     717                 :           0 :            call timab(48,2,tsec)
     718                 :             :          end if
     719                 :             : 
     720                 :             : !        >>> This my kpt and I am the master node: I write the data
     721                 :             :          if (.not.iomode_etsf_mpiio) then
     722         [ #  # ]:           0 :            if (i_am_master) then
     723         [ #  # ]:           0 :              if (iomode==IO_MODE_ETSF) then
     724                 :             :                if (nc_unlimited) then
     725                 :             :                  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]
     726                 :             :                  NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     727         [ #  # ]:           0 :                else if (.not.store_half_dipoles) then
     728   [ #  #  #  # ]:           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]
     729         [ #  # ]:           0 :                  NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     730                 :             :                else
     731   [ #  #  #  # ]:           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]
     732         [ #  # ]:           0 :                  NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     733                 :             :                end if
     734                 :             :              else
     735         [ #  # ]:           0 :                bsize=nband_k**2;if (store_half_dipoles) bsize=(nband_k*(nband_k+1))/2
     736   [ #  #  #  # ]:           0 :                write(ount)(psinablapsi(1:2,1,ib),ib=1,bsize)
     737   [ #  #  #  # ]:           0 :                write(ount)(psinablapsi(1:2,2,ib),ib=1,bsize)
     738   [ #  #  #  # ]:           0 :                write(ount)(psinablapsi(1:2,3,ib),ib=1,bsize)
     739                 :             :              end if
     740                 :             : 
     741                 :             : !          >>> This my kpt and I am not the master node: I send the data
     742         [ #  # ]:           0 :            else if (i_am_master_band.and.i_am_master_spfft) then
     743         [ #  # ]:           0 :              if (mpi_enreg%me_kpt/=master_spfftband) then
     744                 :           0 :                ABI_BUG('Problem with band communicator!')
     745                 :             :              end if
     746                 :           0 :              call xmpi_exch(psinablapsi,pnp_size,mpi_enreg%me_kpt,psinablapsi,master,spaceComm_kpt,etiq,ierr)
     747                 :             :            end if
     748                 :             :          end if
     749                 :             : #if defined(HAVE_GPU_MARKERS)
     750                 :             :          call nvtxEndRange()
     751                 :             : #endif
     752                 :             :        else
     753                 :             : !        >>> Reduction in case of parallelism
     754                 :       16288 :          call timab(48,1,tsec)
     755                 :       16288 :          call xmpi_sum(psinablapsi,spaceComm_bandspinorfft,ierr)
     756                 :       16288 :          call timab(48,2,tsec)
     757                 :             :        end if ! no_file_out
     758                 :             : 
     759                 :             : !    >>> This is not my kpt and I am the master node: I receive the data and I write
     760   [ +  +  +  - ]:       19634 :      elseif ((.not.iomode_etsf_mpiio).and.i_am_master.and.(iomode/=NO_FILE_OUT)) then ! mykpt
     761                 :           0 :        sender=master_spfftband
     762                 :           0 :        call xmpi_exch(psinablapsi,pnp_size,sender,psinablapsi,master,spaceComm_kpt,etiq,ierr)
     763         [ #  # ]:           0 :        if (iomode==IO_MODE_ETSF) then
     764                 :             :          if (nc_unlimited) then
     765                 :             :            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]
     766                 :             :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     767         [ #  # ]:           0 :          else if (.not.store_half_dipoles) then
     768   [ #  #  #  # ]:           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]
     769         [ #  # ]:           0 :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     770                 :             :          else
     771   [ #  #  #  # ]:           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]
     772         [ #  # ]:           0 :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     773                 :             :          end if
     774                 :             :        else
     775         [ #  # ]:           0 :          bsize=nband_k**2;if (store_half_dipoles) bsize=(nband_k*(nband_k+1))/2
     776   [ #  #  #  # ]:           0 :          write(ount)(psinablapsi(1:2,1,ib),ib=1,bsize)
     777   [ #  #  #  # ]:           0 :          write(ount)(psinablapsi(1:2,2,ib),ib=1,bsize)
     778   [ #  #  #  # ]:           0 :          write(ount)(psinablapsi(1:2,3,ib),ib=1,bsize)
     779                 :             :        end if
     780                 :             :      end if ! mykpt
     781                 :             : 
     782                 :       37285 :      bdtot_index=bdtot_index+nband_k
     783                 :             : 
     784                 :             : !    End loop on spin,kpt
     785                 :             : #if defined(HAVE_GPU_MARKERS)
     786                 :             :      call nvtxEndRange()
     787                 :             : #endif
     788                 :             :    end do ! ikpt
     789                 :             :  end do !isppol
     790                 :             : 
     791                 :             : ! >>> Last reduction over k-points in case of parallelism
     792                 :             : ! >>> if no output to file
     793         [ +  + ]:        1158 : if (iomode == NO_FILE_OUT) then
     794                 :        1121 :   call xmpi_sum(psinablapsi_out,spaceComm_kpt,ierr)
     795                 :             : end if
     796                 :             : 
     797                 :             : !Close file
     798   [ +  +  +  +  :        1158 :  if ((i_am_master.or.(iomode_etsf_mpiio.and.i_am_master_spfft)).and.iomode /= NO_FILE_OUT) then
                   +  + ]
     799         [ +  - ]:          23 :    if (iomode==IO_MODE_ETSF) then
     800         [ -  + ]:          23 :      NCF_CHECK(nf90_close(ncid))
     801                 :             :    else
     802                 :           0 :      ierr=close_unit(ount,msg)
     803         [ #  # ]:           0 :      ABI_CHECK(ierr==0,"Error while closing OPT file")
     804                 :             :    end if
     805                 :             :  end if
     806                 :             : 
     807                 :             : !Datastructures deallocations
     808         [ +  + ]:        1158 :  if (iomode /= NO_FILE_OUT) then
     809         [ -  + ]:          37 :     ABI_FREE(psinablapsi)
     810                 :             :  end if
     811         [ +  + ]:        1158 :  if (iomode_etsf_mpiio) then
     812         [ -  + ]:          37 :     ABI_FREE(psinablapsi_w)
     813                 :             :  end if
     814         [ +  + ]:        1158 :  if (dtset%pawspnorb==1) then
     815         [ +  + ]:          25 :    do iatom=1,natom
     816         [ -  + ]:          25 :      ABI_FREE(phisocphj(iatom)%value)
     817                 :             :    end do
     818                 :             :  end if
     819   [ +  -  +  +  :        1178 :  ABI_FREE(phisocphj)
             -  +  -  + ]
     820                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     821                 :             :  !$OMP TARGET EXIT DATA MAP(delete:lmn_at,nabla_at,soc_at) IF(gpu_option==ABI_GPU_OPENMP)
     822                 :             : #endif
     823         [ -  + ]:        1158 :  ABI_FREE(lmn_at)
     824         [ -  + ]:        1158 :  ABI_FREE(nabla_at)
     825         [ -  + ]:        1158 :  ABI_FREE(soc_at)
     826         [ +  - ]:        1158 :  if (.not.already_has_nabla) then
     827         [ +  + ]:        2318 :    do itypat=1,dtset%ntypat
     828         [ +  - ]:        2318 :      if (allocated(pawtab(itypat)%nabla_ij)) then
     829                 :        1160 :        ABI_FREE(pawtab(itypat)%nabla_ij)
     830                 :        1160 :        pawtab(itypat)%has_nabla=0
     831                 :             :      end if
     832                 :             :    end do
     833                 :             :  end if
     834                 :             : 
     835                 :             :  ABI_NVTX_END_RANGE()
     836                 :        1158 :  call timab(1184,2,tsec)
     837                 :             :  DBG_EXIT("COLL")
     838                 :             : 
     839   [ -  +  -  + ]:        2316 :  end subroutine optics_paw
     840                 :             : !!***
     841                 :             : 
     842                 :             : !----------------------------------------------------------------------
     843                 :             : 
     844                 :             : !!****f* m_paw_optics/optics_paw_dipoles_k
     845                 :             : !! NAME
     846                 :             : !! optics_paw_dipoles_k
     847                 :             : !!
     848                 :             : !! FUNCTION
     849                 :             : !! Compute, for one k-point and a range of bands jb1:jb2, the matrix elements
     850                 :             : !! <Psi_ib|-i.nabla|Psi_jb> as the sum of:
     851                 :             : !!  - plane-wave part:  <Psi_tild_ib|-i.nabla|Psi_tild_jb>
     852                 :             : !!  - on-site part: <Psi_ib|p_i><p_j|Psi_jb> (<phi_i|-i.nabla|phi_j>-<tphi_i|-i.nabla|tphi_j>)
     853                 :             : !!                  + spin-orbit part (if pawspnorb==1)
     854                 :             : !! No MPI communication and no I/O are done here.
     855                 :             : !!
     856                 :             : !! Both parts are sesquilinear forms X^H.D.X computed with GEMMs over blocks of columns jb:
     857                 :             : !!  - plane-wave: X=C (plane-wave coefficients), D=diag(k+G)_idir
     858                 :             : !!  - on-site:    X=P (packed cprj), D=K_idir, block-diagonal over atoms, with
     859                 :             : !!                K_idir^{ss'}_ij = -i.nabla_ij.delta_ss' + (Sigma^ss' X g_ij)_idir
     860                 :             : !!
     861                 :             : !! INPUTS
     862                 :             : !!  cg_k(2,npw_k*my_nspinor,nband_k)=planewave coefficients of wavefunctions at this k-point
     863                 :             : !!  cprj_pk(2,nproj*my_nspinor,nband_k)= <p_lmn|Cnk> coefficients at this k-point (all bands),
     864                 :             : !!    packed with pawcprj_pack (projectors of all atoms concatenated, in cprj atom order)
     865                 :             : !!  kpg_k(3,npw_k*my_nspinor)=k+G vectors in cartesian coordinates (times 2pi)
     866                 :             : !!  nabla_at(3,lmnmax,lmnmax,natom)=<phi_i|nabla|phi_j>-<tphi_i|nabla|tphi_j> for each atom
     867                 :             : !!  soc_at(2,2,3,lmnmax,lmnmax,:)=spin-orbit on-site matrix elements for each atom (if pawspnorb==1)
     868                 :             : !!  lmn_at(natom)=number of (l,m,n) channels of each atom
     869                 :             : !!  atom_off(natom)=offset of each atom in the projector dimension of cprj_pk
     870                 :             : !!  row_atom(nproj)=atom corresponding to each projector of cprj_pk
     871                 :             : !!  cplex=1 if cprj are real (istwfk>1), 2 otherwise
     872                 :             : !!  istwf_k=storage mode of wavefunctions at this k-point
     873                 :             : !!  jb1,jb2=range of bands jb to compute
     874                 :             : !!  jpw1,jpw2=range of bands jb for which the plane-wave part is computed by this proc
     875                 :             : !!  jpaw1,jpaw2=range of bands jb for which the on-site part is computed by this proc
     876                 :             : !!  lmnmax=max. number of (l,m,n) channels over atoms
     877                 :             : !!  mband=maximum number of bands
     878                 :             : !!  my_nspinor=number of spinorial components treated by this proc
     879                 :             : !!  natom=number of atoms in cell
     880                 :             : !!  nband_k=number of bands at this k-point
     881                 :             : !!  nproj=total number of projectors (per spinor)
     882                 :             : !!  npw_k=number of planewaves at this k-point
     883                 :             : !!  pawspnorb=1 if spin-orbit contribution is included
     884                 :             : !!  all_rows=if true, compute all ib for each jb, without filling the second half of the matrix
     885                 :             : !!           (full storage only, used for MPI-IO); if false, compute only ib<=jb
     886                 :             : !!  diag_only=if true, compute only ib=jb elements (jb1 must be 1)
     887                 :             : !!  store_half=if true, use packed storage for the (ib<=jb) half matrix
     888                 :             : !!  Note: psinablapsi only stores columns jb1:jb2: element (ib,jb) is stored at index
     889                 :             : !!        jb(jb-1)/2+ib-ishift (store_half) or (jb-1)*mband+ib-ishift (full storage),
     890                 :             : !!        where ishift is the index of the last element before column jb1.
     891                 :             : !!        The second half of the full matrix is filled only if jb1=1.
     892                 :             : !!  gpu_option=ABI_GPU_OPENMP to run on GPU (all input arrays must then be mapped on device)
     893                 :             : !!
     894                 :             : !! OUTPUT
     895                 :             : !!  psinablapsi(2,3,:)=sum of plane-wave and on-site (PAW+SOC) contributions
     896                 :             : !!
     897                 :             : !! SOURCE
     898                 :             : 
     899                 :       49479 :  subroutine optics_paw_dipoles_k(cg_k,cprj_pk,kpg_k,nabla_at,soc_at,lmn_at,atom_off,row_atom,&
     900                 :             : &           cplex,istwf_k,jb1,jb2,jpw1,jpw2,jpaw1,jpaw2,lmnmax,mband,my_nspinor,natom,nband_k,&
     901   [ -  +  -  + ]:       16493 : &           nproj,npw_k,pawspnorb,all_rows,diag_only,store_half,gpu_option,psinablapsi)
     902                 :             : 
     903                 :             : !Arguments ------------------------------------
     904                 :             : !scalars
     905                 :             :  integer,intent(in) :: cplex,gpu_option,istwf_k,jb1,jb2,jpw1,jpw2,jpaw1,jpaw2,lmnmax,mband
     906                 :             :  integer,intent(in) :: my_nspinor,natom,nband_k,nproj,npw_k,pawspnorb
     907                 :             :  logical,intent(in) :: all_rows,diag_only,store_half
     908                 :             : !arrays
     909                 :             :  integer,intent(in) :: atom_off(natom),lmn_at(natom),row_atom(nproj)
     910                 :             :  real(dp),intent(in) :: cg_k(2,npw_k*my_nspinor,nband_k),cprj_pk(2,nproj*my_nspinor,nband_k)
     911                 :             :  real(dp),intent(in) :: kpg_k(3,npw_k*my_nspinor),nabla_at(3,lmnmax,lmnmax,natom)
     912                 :             :  real(dp),intent(in) :: soc_at(:,:,:,:,:,:)
     913                 :             :  real(dp),intent(inout) :: psinablapsi(:,:,:)
     914                 :             : 
     915                 :             : !Local variables-------------------------------
     916                 :             : !scalars
     917                 :             :  integer :: iatom,ib,icol,idir,ii,ilmn,ioff,iproj0,ipw,irow,ispinor,j,j0,jb,jbhi,jblo,jlmn
     918                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     919                 :             :  integer :: ib,ii
     920                 :             : #endif
     921                 :             :  integer :: ishift,lmn_size,nbj,nbj_blk,nbjmax,nprojsp,npwsp,nrows,nzero
     922                 :             :  logical :: gpu
     923                 :             :  real(dp) :: aa,bb,cc,nab,re1,im1,x1,y1,x2,y2
     924                 :             : !arrays
     925                 :       16493 :  real(dp),allocatable :: cprj_r(:,:),tpaw(:,:,:),wpw(:,:,:),zblk(:,:,:),zr(:,:,:)
     926                 :             : 
     927                 :             : ! ************************************************************************
     928                 :             : 
     929   [ -  +  -  -  :       16493 :  ABI_CHECK(.not.(all_rows.and.(store_half.or.diag_only)),"all_rows requires full storage!")
                   -  - ]
     930   [ -  +  -  -  :       16493 :  ABI_CHECK(jb1==1.or.all_rows.or.store_half,"Full matrix storage requires jb1=1!")
                   -  - ]
     931   [ -  +  -  - ]:       16493 :  ABI_CHECK(jb1==1.or.(.not.diag_only),"diag_only requires jb1=1!")
     932   [ +  +  +  -  :       16493 :  ABI_CHECK(pawspnorb==0.or.(cplex==2.and.my_nspinor==2),"SOC requires complex cprj and both spinors!")
                   -  + ]
     933                 :             : 
     934                 :       16493 :  gpu=(gpu_option==ABI_GPU_OPENMP)
     935                 :       16493 :  npwsp=npw_k*my_nspinor
     936                 :       16493 :  nprojsp=nproj*my_nspinor
     937                 :             : 
     938                 :             : !Index of the last element before column jb1 in the storage, and number of stored elements
     939         [ +  + ]:       16493 :  if (diag_only) then
     940                 :       16288 :    ishift=0 ; nzero=nband_k
     941         [ +  - ]:         205 :  else if (store_half) then
     942                 :         205 :    ishift=(jb1*(jb1-1))/2 ; nzero=(jb2*(jb2+1))/2-ishift
     943                 :             :  else
     944                 :           0 :    ishift=(jb1-1)*mband ; nzero=jb2*mband-ishift
     945                 :             :  end if
     946                 :             : 
     947                 :             : !Fill output array with zeros
     948         [ +  - ]:       16493 :  if (.not.gpu) then
     949   [ +  +  +  +  :     1486973 :    psinablapsi(:,:,1:nzero)=zero
                   +  + ]
     950                 :             :  else
     951                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     952                 :             :    !$OMP TARGET ENTER DATA MAP(alloc:psinablapsi)
     953                 :             :    !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) MAP(to:psinablapsi) PRIVATE(ii,idir)
     954                 :             :    do ii=1,nzero
     955                 :             :      do idir=1,3
     956                 :             :        psinablapsi(1,idir,ii)=zero ; psinablapsi(2,idir,ii)=zero
     957                 :             :      end do
     958                 :             :    end do
     959                 :             : #endif
     960                 :             :  end if
     961                 :             : 
     962                 :             : !Number of columns jb treated at once (limited by the memory of work arrays)
     963                 :             : !(each column jb needs 2x3 reals per plane wave, per band ib and per projector)
     964                 :       16493 :  nbj_blk=int(dipoles_blk_mem/(48._dp*real(npwsp+nband_k+nprojsp,dp)))
     965                 :       16493 :  nbj_blk=max(1,min(nbj_blk,jb2-jb1+1))
     966                 :             : 
     967                 :             : !2-A Computation of <psi_tild_n|-i.nabla|psi_tild_m>
     968                 :             : !----------------------------------------------------------------------------------
     969                 :             : !Note: <psi_nk|-i.nabla|psi_mk> => Sum_g[ <G|Psi_nk>^* <G|Psi_mk> G ]
     970                 :             : !      computed as C^H.W with W(g,jb,idir)=(k+G)_idir*C(g,jb)
     971                 :             : !      For istwfk>1: Sum_g>=g0[ 2i.Im(<G|Psi_nk>^* <G|Psi_mk> G) ]
     972                 :             : !      G=k+g=0 term is included but do not contribute
     973                 :             : 
     974                 :       16493 :  jblo=max(jb1,jpw1) ; jbhi=min(jb2,jpw2)
     975         [ +  - ]:       16493 :  if (jbhi>=jblo) then
     976                 :       16493 :    nbjmax=min(nbj_blk,jbhi-jblo+1)
     977   [ -  +  +  -  :       65972 :    ABI_MALLOC(wpw,(2,npwsp,3*nbjmax))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     978   [ -  +  +  -  :       65972 :    ABI_MALLOC(zblk,(2,nband_k,3*nbjmax))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     979   [ -  +  +  -  :       65972 :    ABI_MALLOC(zr,(1,nband_k,3*nbjmax))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     980                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     981                 :             :    !$OMP TARGET ENTER DATA MAP(alloc:wpw,zblk,zr) IF(gpu)
     982                 :             : #endif
     983                 :             : 
     984   [ +  -  +  - ]:       32986 :    do j0=jblo,jbhi,nbjmax
     985                 :       16493 :      nbj=min(nbjmax,jbhi-j0+1)
     986                 :             :      !If all_rows, compute all ib ; if not, compute only ib<=jb (trapezoidal block)
     987         [ +  - ]:       16493 :      nrows=merge(nband_k,j0+nbj-1,all_rows)
     988                 :             : 
     989                 :             : !    Build W=(k+G)_idir*C_jb (or (k+G)_idir*(Im C_jb,-Re C_jb) for istwfk>1)
     990         [ +  - ]:       16493 :      if (.not.gpu) then
     991                 :             :        !$OMP PARALLEL DO COLLAPSE(2) DEFAULT(SHARED) PRIVATE(idir,j,jb,icol,ipw)
     992         [ +  + ]:       65972 :        do idir=1,3
     993         [ +  + ]:      464396 :          do j=1,nbj
     994                 :      398424 :            jb=j0+j-1 ; icol=(idir-1)*nbj+j
     995         [ +  + ]:      447903 :            if (istwf_k>1) then
     996         [ +  + ]:       23058 :              do ipw=1,npwsp
     997                 :       22932 :                wpw(1,ipw,icol)= kpg_k(idir,ipw)*cg_k(2,ipw,jb)
     998                 :       23058 :                wpw(2,ipw,icol)=-kpg_k(idir,ipw)*cg_k(1,ipw,jb)
     999                 :             :              end do
    1000                 :             :            else
    1001         [ +  + ]:    56227110 :              do ipw=1,npwsp
    1002                 :    55828812 :                wpw(1,ipw,icol)=kpg_k(idir,ipw)*cg_k(1,ipw,jb)
    1003                 :    56227110 :                wpw(2,ipw,icol)=kpg_k(idir,ipw)*cg_k(2,ipw,jb)
    1004                 :             :              end do
    1005                 :             :            end if
    1006                 :             :          end do
    1007                 :             :        end do
    1008                 :             :        !$OMP END PARALLEL DO
    1009                 :             :      else
    1010                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1011                 :             :        !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(3) MAP(to:wpw,kpg_k,cg_k) &
    1012                 :             :        !$OMP& PRIVATE(idir,j,jb,icol,ipw)
    1013                 :             :        do idir=1,3
    1014                 :             :          do j=1,nbj
    1015                 :             :            do ipw=1,npwsp
    1016                 :             :              jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1017                 :             :              if (istwf_k>1) then
    1018                 :             :                wpw(1,ipw,icol)= kpg_k(idir,ipw)*cg_k(2,ipw,jb)
    1019                 :             :                wpw(2,ipw,icol)=-kpg_k(idir,ipw)*cg_k(1,ipw,jb)
    1020                 :             :              else
    1021                 :             :                wpw(1,ipw,icol)=kpg_k(idir,ipw)*cg_k(1,ipw,jb)
    1022                 :             :                wpw(2,ipw,icol)=kpg_k(idir,ipw)*cg_k(2,ipw,jb)
    1023                 :             :              end if
    1024                 :             :            end do
    1025                 :             :          end do
    1026                 :             :        end do
    1027                 :             : #endif
    1028                 :             :      end if
    1029                 :             : 
    1030                 :             : !    Z=C^H.W (only diagonal elements if diag_only)
    1031         [ +  + ]:       16493 :      if (diag_only) then
    1032         [ +  - ]:       16288 :        if (.not.gpu) then
    1033                 :             :          !$OMP PARALLEL DO COLLAPSE(2) DEFAULT(SHARED) PRIVATE(idir,j,jb,icol,ipw,re1,im1)
    1034         [ +  + ]:       65152 :          do idir=1,3
    1035         [ +  + ]:      456064 :            do j=1,nbj
    1036                 :      390912 :              jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1037                 :      390912 :              re1=zero ; im1=zero
    1038         [ +  - ]:      390912 :              if (istwf_k>1) then
    1039         [ #  # ]:           0 :                do ipw=1,npwsp
    1040                 :           0 :                  im1=im1+cg_k(1,ipw,jb)*wpw(1,ipw,icol)+cg_k(2,ipw,jb)*wpw(2,ipw,icol)
    1041                 :             :                end do
    1042                 :           0 :                im1=two*im1
    1043                 :             :              else
    1044         [ +  + ]:    55490880 :                do ipw=1,npwsp
    1045                 :    55099968 :                  re1=re1+cg_k(1,ipw,jb)*wpw(1,ipw,icol)+cg_k(2,ipw,jb)*wpw(2,ipw,icol)
    1046                 :    55490880 :                  im1=im1+cg_k(1,ipw,jb)*wpw(2,ipw,icol)-cg_k(2,ipw,jb)*wpw(1,ipw,icol)
    1047                 :             :                end do
    1048                 :             :              end if
    1049                 :      439776 :              zblk(1,jb,icol)=re1 ; zblk(2,jb,icol)=im1
    1050                 :             :            end do
    1051                 :             :          end do
    1052                 :             :          !$OMP END PARALLEL DO
    1053                 :             :        else
    1054                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1055                 :             :          !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) MAP(to:cg_k,wpw,zblk) PRIVATE(idir,j,jb,icol,re1,im1)
    1056                 :             :          do idir=1,3
    1057                 :             :            do j=1,nbj
    1058                 :             :              jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1059                 :             :              re1=zero ; im1=zero
    1060                 :             :              if (istwf_k>1) then
    1061                 :             :                !$OMP PARALLEL DO REDUCTION(+:im1) PRIVATE(ipw)
    1062                 :             :                do ipw=1,npwsp
    1063                 :             :                  im1=im1+cg_k(1,ipw,jb)*wpw(1,ipw,icol)+cg_k(2,ipw,jb)*wpw(2,ipw,icol)
    1064                 :             :                end do
    1065                 :             :                im1=two*im1
    1066                 :             :              else
    1067                 :             :                !$OMP PARALLEL DO REDUCTION(+:re1,im1) PRIVATE(ipw)
    1068                 :             :                do ipw=1,npwsp
    1069                 :             :                  re1=re1+cg_k(1,ipw,jb)*wpw(1,ipw,icol)+cg_k(2,ipw,jb)*wpw(2,ipw,icol)
    1070                 :             :                  im1=im1+cg_k(1,ipw,jb)*wpw(2,ipw,icol)-cg_k(2,ipw,jb)*wpw(1,ipw,icol)
    1071                 :             :                end do
    1072                 :             :              end if
    1073                 :             :              zblk(1,jb,icol)=re1 ; zblk(2,jb,icol)=im1
    1074                 :             :            end do
    1075                 :             :          end do
    1076                 :             : #endif
    1077                 :             :        end if
    1078         [ +  + ]:         205 :      else if (istwf_k>1) then
    1079                 :             :        call abi_xgemm('T','N',nrows,3*nbj,2*npwsp,cmplx(two,zero,kind=dp),cg_k,2*npwsp,&
    1080                 :           3 : &                     wpw,2*npwsp,czero,zr,nband_k,x_cplx=1,gpu_option=gpu_option)
    1081                 :           3 :        call optics_paw_zr2zblk(zr,zblk,nrows,3*nbj,gpu)
    1082                 :             :      else
    1083                 :             :        call abi_xgemm('C','N',nrows,3*nbj,npwsp,cone,cg_k,npwsp,&
    1084                 :         202 : &                     wpw,npwsp,czero,zblk,nband_k,x_cplx=2,gpu_option=gpu_option)
    1085                 :             :      end if
    1086                 :             : 
    1087                 :             :      call optics_paw_scatter(zblk,j0,nbj,nrows,ishift,mband,all_rows,diag_only,store_half,&
    1088                 :       32986 : &                            gpu,psinablapsi)
    1089                 :             : 
    1090                 :             :    end do ! j0
    1091                 :             : 
    1092                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1093                 :             :    !$OMP TARGET EXIT DATA MAP(delete:wpw,zblk,zr) IF(gpu)
    1094                 :             : #endif
    1095         [ -  + ]:       16493 :    ABI_FREE(wpw)
    1096         [ -  + ]:       16493 :    ABI_FREE(zblk)
    1097         [ -  + ]:       16493 :    ABI_FREE(zr)
    1098                 :             :  end if
    1099                 :             : 
    1100                 :             : !2-B Computation of <psi_n|p_i><p_j|psi_m>(<phi_i|-i.nabla|phi_j>-<tphi_i|-i.nabla|tphi_j>)
    1101                 :             : !2-C + Spin-orbit coupling contribution:
    1102                 :             : !       Sum_ij,ss'[<psi_n,s|p_i><p_j|psi_m,s'>(<phi_i|1/4 Alpha^2 (Sigma^ss' X dV/dr)|phi_j>]
    1103                 :             : !----------------------------------------------------------------------------------
    1104                 :             : !Note: computed as P^H.T with T=K.P, K block-diagonal over atoms:
    1105                 :             : !  Non relativistic part: K^ss'_ij = -i.(<Phi_i|Nabla|Phi_j>-<tPhi_i|Nabla|tPhi_j>) delta_ss'
    1106                 :             : !  Spin-orbit part (not compatible with parallelization over spinors):
    1107                 :             : !    K^ss'_ij = (Sigma^ss' X g_ij), where g_ij = <Phi_i| 1/4 Alpha^2 dV/dr vec(r)/r) |Phi_j>
    1108                 :             : !    With A=Re(Sigma^up-up X g_ij), B=Re(Sigma^dn-up X g_ij), C=Im(Sigma^dn-up X g_ij):
    1109                 :             : !      K^up-up=A, K^dn-dn=-A, K^dn-up=B+iC, K^up-dn=B-iC
    1110                 :             : !    soc_at(re:im,1,idir,ilmn,jlmn,iatom) is (Sigma^up-up X g_ij)
    1111                 :             : !    soc_at(re:im,2,idir,ilmn,jlmn,iatom) is (Sigma^dn-up X g_ij)
    1112                 :             : !Note: nabla_ij is antisymmetric (enforced in pawnabla_init), so ib>jb needs no special care
    1113                 :             : !Note: if cplex=1 (istwfk>1, hence nspinor=1), only the real part of cprj is used
    1114                 :             : 
    1115                 :       16493 :  jblo=max(jb1,jpaw1) ; jbhi=min(jb2,jpaw2)
    1116         [ +  + ]:       16493 :  if (jbhi>=jblo) then
    1117                 :       16399 :    nbjmax=min(nbj_blk,jbhi-jblo+1)
    1118   [ -  +  +  -  :       65596 :    ABI_MALLOC(zblk,(2,nband_k,3*nbjmax))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1119   [ -  +  +  -  :       81995 :    ABI_MALLOC(tpaw,(cplex,nprojsp,3*nbjmax))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1120   [ -  +  +  -  :       65596 :    ABI_MALLOC(zr,(1,nband_k,3*nbjmax))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1121   [ -  +  +  -  :       65599 :    ABI_MALLOC(cprj_r,(nprojsp,merge(nband_k,1,cplex==1))) ! Only used if cplex=1
          +  +  -  +  +  
          -  +  -  +  -  
          -  +  -  +  -  
                      + ]
    1122                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1123                 :             :    !$OMP TARGET ENTER DATA MAP(alloc:zblk,tpaw,zr,cprj_r) IF(gpu)
    1124                 :             : #endif
    1125         [ +  + ]:       16399 :    if (cplex==1) then
    1126         [ +  - ]:           3 :      if (.not.gpu) then
    1127   [ +  +  +  + ]:        1005 :        cprj_r(:,:)=cprj_pk(1,:,:)
    1128                 :             :      else
    1129                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1130                 :             :        !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) MAP(to:cprj_r,cprj_pk) PRIVATE(ib,irow)
    1131                 :             :        do ib=1,nband_k
    1132                 :             :          do irow=1,nprojsp
    1133                 :             :            cprj_r(irow,ib)=cprj_pk(1,irow,ib)
    1134                 :             :          end do
    1135                 :             :        end do
    1136                 :             : #endif
    1137                 :             :      end if
    1138                 :             :    end if
    1139                 :             : 
    1140   [ +  -  +  - ]:       32798 :    do j0=jblo,jbhi,nbjmax
    1141                 :       16399 :      nbj=min(nbjmax,jbhi-j0+1)
    1142                 :             :      !If all_rows, compute all ib ; if not, compute only ib<=jb (trapezoidal block)
    1143         [ +  - ]:       16399 :      nrows=merge(nband_k,j0+nbj-1,all_rows)
    1144                 :             : 
    1145                 :             : !    Build T=K.P_jb (one element of T per projector row, spinor, column and direction)
    1146         [ +  - ]:       16399 :      if (.not.gpu) then
    1147                 :             :        !$OMP PARALLEL DO COLLAPSE(2) DEFAULT(SHARED) &
    1148                 :             :        !$OMP PRIVATE(idir,j,jb,icol,ispinor,ioff,irow,iatom,iproj0,ilmn,lmn_size,jlmn, &
    1149                 :             :        !$OMP         nab,aa,bb,cc,re1,im1,x1,y1,x2,y2)
    1150         [ +  + ]:       65596 :        do idir=1,3
    1151         [ +  + ]:      380734 :          do j=1,nbj
    1152         [ +  + ]:      679593 :            do ispinor=1,my_nspinor
    1153         [ +  + ]:     5680572 :              do irow=1,nproj
    1154                 :     5050176 :                jb=j0+j-1 ; icol=(idir-1)*nbj+j ; ioff=(ispinor-1)*nproj
    1155                 :     5050176 :                iatom=row_atom(irow) ; iproj0=atom_off(iatom) ; ilmn=irow-iproj0
    1156         [ -  + ]:     5050176 :                lmn_size=merge(lmn_at(iatom),0,ilmn<=lmn_at(iatom))
    1157                 :     5050176 :                re1=zero ; im1=zero
    1158         [ +  + ]:     5365434 :                if (cplex==1) then
    1159         [ +  + ]:       30528 :                  do jlmn=1,lmn_size
    1160                 :       30528 :                    re1=re1+nabla_at(idir,ilmn,jlmn,iatom)*cprj_r(ioff+iproj0+jlmn,jb)
    1161                 :             :                  end do
    1162                 :        2880 :                  tpaw(1,ioff+irow,icol)=re1
    1163                 :             :                else
    1164         [ +  + ]:    45430272 :                  do jlmn=1,lmn_size
    1165                 :    40382976 :                    nab=nabla_at(idir,ilmn,jlmn,iatom)
    1166                 :    40382976 :                    re1=re1+nab*cprj_pk(2,ioff+iproj0+jlmn,jb)
    1167                 :    45430272 :                    im1=im1-nab*cprj_pk(1,ioff+iproj0+jlmn,jb)
    1168                 :             :                  end do
    1169         [ +  + ]:     5047296 :                  if (pawspnorb==1) then
    1170         [ +  + ]:       69120 :                    do jlmn=1,lmn_size
    1171                 :       61440 :                      aa=soc_at(1,1,idir,ilmn,jlmn,iatom)
    1172                 :       61440 :                      bb=soc_at(1,2,idir,ilmn,jlmn,iatom)
    1173                 :       61440 :                      cc=soc_at(2,2,idir,ilmn,jlmn,iatom)
    1174                 :       61440 :                      x1=cprj_pk(1,iproj0+jlmn,jb)       ; y1=cprj_pk(2,iproj0+jlmn,jb)
    1175                 :       61440 :                      x2=cprj_pk(1,nproj+iproj0+jlmn,jb) ; y2=cprj_pk(2,nproj+iproj0+jlmn,jb)
    1176         [ +  + ]:       69120 :                      if (ispinor==1) then
    1177                 :             :                        !Spin up:   A.P^up + (B-iC).P^dn
    1178                 :       30720 :                        re1=re1+aa*x1+bb*x2+cc*y2
    1179                 :       30720 :                        im1=im1+aa*y1+bb*y2-cc*x2
    1180                 :             :                      else
    1181                 :             :                        !Spin down: (B+iC).P^up - A.P^dn
    1182                 :       30720 :                        re1=re1+bb*x1-cc*y1-aa*x2
    1183                 :       30720 :                        im1=im1+bb*y1+cc*x1-aa*y2
    1184                 :             :                      end if
    1185                 :             :                    end do
    1186                 :             :                  end if
    1187                 :     5047296 :                  tpaw(1,ioff+irow,icol)=re1 ; tpaw(2,ioff+irow,icol)=im1
    1188                 :             :                end if
    1189                 :             :              end do ! irow
    1190                 :             :            end do ! ispinor
    1191                 :             :          end do ! j
    1192                 :             :        end do ! idir
    1193                 :             :        !$OMP END PARALLEL DO
    1194                 :             :      else
    1195                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1196                 :             :        !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(4) &
    1197                 :             :        !$OMP& MAP(to:tpaw,cprj_pk,cprj_r,nabla_at,soc_at,lmn_at,atom_off,row_atom) &
    1198                 :             :        !$OMP& PRIVATE(idir,j,jb,icol,ispinor,ioff,irow,iatom,iproj0,ilmn,lmn_size,jlmn, &
    1199                 :             :        !$OMP&         nab,aa,bb,cc,re1,im1,x1,y1,x2,y2)
    1200                 :             :        do idir=1,3
    1201                 :             :          do j=1,nbj
    1202                 :             :            do ispinor=1,my_nspinor
    1203                 :             :              do irow=1,nproj
    1204                 :             :                jb=j0+j-1 ; icol=(idir-1)*nbj+j ; ioff=(ispinor-1)*nproj
    1205                 :             :                iatom=row_atom(irow) ; iproj0=atom_off(iatom) ; ilmn=irow-iproj0
    1206                 :             :                lmn_size=merge(lmn_at(iatom),0,ilmn<=lmn_at(iatom))
    1207                 :             :                re1=zero ; im1=zero
    1208                 :             :                if (cplex==1) then
    1209                 :             :                  do jlmn=1,lmn_size
    1210                 :             :                    re1=re1+nabla_at(idir,ilmn,jlmn,iatom)*cprj_r(ioff+iproj0+jlmn,jb)
    1211                 :             :                  end do
    1212                 :             :                  tpaw(1,ioff+irow,icol)=re1
    1213                 :             :                else
    1214                 :             :                  do jlmn=1,lmn_size
    1215                 :             :                    nab=nabla_at(idir,ilmn,jlmn,iatom)
    1216                 :             :                    re1=re1+nab*cprj_pk(2,ioff+iproj0+jlmn,jb)
    1217                 :             :                    im1=im1-nab*cprj_pk(1,ioff+iproj0+jlmn,jb)
    1218                 :             :                  end do
    1219                 :             :                  if (pawspnorb==1) then
    1220                 :             :                    do jlmn=1,lmn_size
    1221                 :             :                      aa=soc_at(1,1,idir,ilmn,jlmn,iatom)
    1222                 :             :                      bb=soc_at(1,2,idir,ilmn,jlmn,iatom)
    1223                 :             :                      cc=soc_at(2,2,idir,ilmn,jlmn,iatom)
    1224                 :             :                      x1=cprj_pk(1,iproj0+jlmn,jb)       ; y1=cprj_pk(2,iproj0+jlmn,jb)
    1225                 :             :                      x2=cprj_pk(1,nproj+iproj0+jlmn,jb) ; y2=cprj_pk(2,nproj+iproj0+jlmn,jb)
    1226                 :             :                      if (ispinor==1) then
    1227                 :             :                        !Spin up:   A.P^up + (B-iC).P^dn
    1228                 :             :                        re1=re1+aa*x1+bb*x2+cc*y2
    1229                 :             :                        im1=im1+aa*y1+bb*y2-cc*x2
    1230                 :             :                      else
    1231                 :             :                        !Spin down: (B+iC).P^up - A.P^dn
    1232                 :             :                        re1=re1+bb*x1-cc*y1-aa*x2
    1233                 :             :                        im1=im1+bb*y1+cc*x1-aa*y2
    1234                 :             :                      end if
    1235                 :             :                    end do
    1236                 :             :                  end if
    1237                 :             :                  tpaw(1,ioff+irow,icol)=re1 ; tpaw(2,ioff+irow,icol)=im1
    1238                 :             :                end if
    1239                 :             :              end do ! irow
    1240                 :             :            end do ! ispinor
    1241                 :             :          end do ! j
    1242                 :             :        end do ! idir
    1243                 :             : #endif
    1244                 :             :      end if
    1245                 :             : 
    1246                 :             : !    Z=P^H.T (only diagonal elements if diag_only)
    1247         [ +  + ]:       16399 :      if (diag_only) then
    1248         [ +  - ]:       16288 :        if (.not.gpu) then
    1249                 :             :          !$OMP PARALLEL DO COLLAPSE(2) DEFAULT(SHARED) PRIVATE(idir,j,jb,icol,irow,re1,im1)
    1250         [ +  + ]:       65152 :          do idir=1,3
    1251         [ +  + ]:      377728 :            do j=1,nbj
    1252                 :      312576 :              jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1253                 :      312576 :              re1=zero ; im1=zero
    1254         [ +  - ]:      312576 :              if (cplex==1) then
    1255         [ #  # ]:           0 :                do irow=1,nprojsp
    1256                 :           0 :                  im1=im1-cprj_r(irow,jb)*tpaw(1,irow,icol)
    1257                 :             :                end do
    1258                 :             :              else
    1259         [ +  + ]:     5313792 :                do irow=1,nprojsp
    1260                 :     5001216 :                  re1=re1+cprj_pk(1,irow,jb)*tpaw(1,irow,icol)+cprj_pk(2,irow,jb)*tpaw(2,irow,icol)
    1261                 :     5313792 :                  im1=im1+cprj_pk(1,irow,jb)*tpaw(2,irow,icol)-cprj_pk(2,irow,jb)*tpaw(1,irow,icol)
    1262                 :             :                end do
    1263                 :             :              end if
    1264                 :      361440 :              zblk(1,jb,icol)=re1 ; zblk(2,jb,icol)=im1
    1265                 :             :            end do
    1266                 :             :          end do
    1267                 :             :          !$OMP END PARALLEL DO
    1268                 :             :        else
    1269                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1270                 :             :          !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) MAP(to:cprj_pk,cprj_r,tpaw,zblk) PRIVATE(idir,j,jb,icol,re1,im1)
    1271                 :             :          do idir=1,3
    1272                 :             :            do j=1,nbj
    1273                 :             :              jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1274                 :             :              re1=zero ; im1=zero
    1275                 :             :              if (cplex==1) then
    1276                 :             :                !$OMP PARALLEL DO REDUCTION(+:im1) PRIVATE(irow)
    1277                 :             :                do irow=1,nprojsp
    1278                 :             :                  im1=im1-cprj_r(irow,jb)*tpaw(1,irow,icol)
    1279                 :             :                end do
    1280                 :             :              else
    1281                 :             :                !$OMP PARALLEL DO REDUCTION(+:re1,im1) PRIVATE(irow)
    1282                 :             :                do irow=1,nprojsp
    1283                 :             :                  re1=re1+cprj_pk(1,irow,jb)*tpaw(1,irow,icol)+cprj_pk(2,irow,jb)*tpaw(2,irow,icol)
    1284                 :             :                  im1=im1+cprj_pk(1,irow,jb)*tpaw(2,irow,icol)-cprj_pk(2,irow,jb)*tpaw(1,irow,icol)
    1285                 :             :                end do
    1286                 :             :              end if
    1287                 :             :              zblk(1,jb,icol)=re1 ; zblk(2,jb,icol)=im1
    1288                 :             :            end do
    1289                 :             :          end do
    1290                 :             : #endif
    1291                 :             :        end if
    1292         [ +  + ]:         111 :      else if (cplex==1) then
    1293                 :             :        call abi_xgemm('T','N',nrows,3*nbj,nprojsp,-cone,cprj_r,nprojsp,&
    1294                 :           3 : &                     tpaw,nprojsp,czero,zr,nband_k,x_cplx=1,gpu_option=gpu_option)
    1295                 :           3 :        call optics_paw_zr2zblk(zr,zblk,nrows,3*nbj,gpu)
    1296                 :             :      else
    1297                 :             :        call abi_xgemm('C','N',nrows,3*nbj,nprojsp,cone,cprj_pk,nprojsp,&
    1298                 :         108 : &                     tpaw,nprojsp,czero,zblk,nband_k,x_cplx=2,gpu_option=gpu_option)
    1299                 :             :      end if
    1300                 :             : 
    1301                 :             :      call optics_paw_scatter(zblk,j0,nbj,nrows,ishift,mband,all_rows,diag_only,store_half,&
    1302                 :       32798 : &                            gpu,psinablapsi)
    1303                 :             : 
    1304                 :             :    end do ! j0
    1305                 :             : 
    1306                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1307                 :             :    !$OMP TARGET EXIT DATA MAP(delete:zblk,tpaw,zr,cprj_r) IF(gpu)
    1308                 :             : #endif
    1309         [ -  + ]:       16399 :    ABI_FREE(zblk)
    1310         [ -  + ]:       16399 :    ABI_FREE(tpaw)
    1311         [ -  + ]:       16399 :    ABI_FREE(zr)
    1312         [ -  + ]:       16399 :    ABI_FREE(cprj_r)
    1313                 :             :  end if
    1314                 :             : 
    1315                 :             : !Get result back from device
    1316                 :             :  if (gpu) then
    1317                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1318                 :             :    !$OMP TARGET UPDATE FROM(psinablapsi(:,:,1:nzero))
    1319                 :             :    !$OMP TARGET EXIT DATA MAP(delete:psinablapsi)
    1320                 :             : #endif
    1321                 :             :  end if
    1322                 :             : 
    1323   [ -  +  -  +  :       16493 :  end subroutine optics_paw_dipoles_k
          -  +  -  +  -  
                      + ]
    1324                 :             : !!***
    1325                 :             : 
    1326                 :             : !----------------------------------------------------------------------
    1327                 :             : 
    1328                 :             : !!****f* m_paw_optics/optics_paw_zr2zblk
    1329                 :             : !! NAME
    1330                 :             : !! optics_paw_zr2zblk
    1331                 :             : !!
    1332                 :             : !! FUNCTION
    1333                 :             : !! Store a real block (imaginary part of the matrix elements, computed with real GEMMs
    1334                 :             : !! when istwfk>1) into the complex work array used in optics_paw_dipoles_k.
    1335                 :             : !!
    1336                 :             : !! INPUTS
    1337                 :             : !!  zr(1,:,ncol)=real block (imaginary part)
    1338                 :             : !!  nrows,ncol=size of the block
    1339                 :             : !!  gpu=true if arrays are on GPU
    1340                 :             : !!
    1341                 :             : !! OUTPUT
    1342                 :             : !!  zblk(2,:,ncol)=complex block (real part set to zero)
    1343                 :             : !!
    1344                 :             : !! SOURCE
    1345                 :             : 
    1346   [ -  +  -  + ]:           6 :  subroutine optics_paw_zr2zblk(zr,zblk,nrows,ncol,gpu)
    1347                 :             : 
    1348                 :             : !Arguments ------------------------------------
    1349                 :             : !scalars
    1350                 :             :  integer,intent(in) :: nrows,ncol
    1351                 :             :  logical,intent(in) :: gpu
    1352                 :             : !arrays
    1353                 :             :  real(dp),intent(in) :: zr(:,:,:)
    1354                 :             :  real(dp),intent(inout) :: zblk(:,:,:)
    1355                 :             : 
    1356                 :             : !Local variables-------------------------------
    1357                 :             : !scalars
    1358                 :             :  integer :: ib,icol
    1359                 :             : 
    1360                 :             : ! ************************************************************************
    1361                 :             : 
    1362         [ +  - ]:           6 :  if (.not.gpu) then
    1363                 :             :    !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(icol,ib)
    1364         [ +  + ]:         258 :    do icol=1,ncol
    1365         [ +  + ]:        3930 :      do ib=1,nrows
    1366                 :        3924 :        zblk(1,ib,icol)=zero ; zblk(2,ib,icol)=zr(1,ib,icol)
    1367                 :             :      end do
    1368                 :             :    end do
    1369                 :             :    !$OMP END PARALLEL DO
    1370                 :             :  else
    1371                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1372                 :             :    !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) MAP(to:zr,zblk) PRIVATE(icol,ib)
    1373                 :             :    do icol=1,ncol
    1374                 :             :      do ib=1,nrows
    1375                 :             :        zblk(1,ib,icol)=zero ; zblk(2,ib,icol)=zr(1,ib,icol)
    1376                 :             :      end do
    1377                 :             :    end do
    1378                 :             : #endif
    1379                 :             :  end if
    1380                 :             : 
    1381                 :           6 :  end subroutine optics_paw_zr2zblk
    1382                 :             : !!***
    1383                 :             : 
    1384                 :             : !----------------------------------------------------------------------
    1385                 :             : 
    1386                 :             : !!****f* m_paw_optics/optics_paw_scatter
    1387                 :             : !! NAME
    1388                 :             : !! optics_paw_scatter
    1389                 :             : !!
    1390                 :             : !! FUNCTION
    1391                 :             : !! Add a block of matrix elements Z(ib,jb,idir), for jb=j0:j0+nbj-1, from the dense
    1392                 :             : !! work array used in optics_paw_dipoles_k to the (2,3,:) storage of the output array.
    1393                 :             : !!
    1394                 :             : !! INPUTS
    1395                 :             : !!  zblk(2,:,3*nbj)=dense block; column (idir-1)*nbj+j holds jb=j0+j-1
    1396                 :             : !!  j0=first band jb of the block
    1397                 :             : !!  nbj=number of bands jb in the block
    1398                 :             : !!  nrows=number of rows ib computed in the block
    1399                 :             : !!  ishift=index of the last element before the first column stored in psinablapsi
    1400                 :             : !!  mband=maximum number of bands
    1401                 :             : !!  all_rows=if true, store all ib computed for each jb (full storage, no second half)
    1402                 :             : !!  diag_only=if true, store only ib=jb elements
    1403                 :             : !!  store_half=if true, use packed storage for the (ib<=jb) half matrix;
    1404                 :             : !!             if false, also fill the second half of the matrix
    1405                 :             : !!  gpu=true if arrays are on GPU
    1406                 :             : !!
    1407                 :             : !! SIDE EFFECTS
    1408                 :             : !!  psinablapsi(2,3,:)=output array, Z block is added to it
    1409                 :             : !!
    1410                 :             : !! SOURCE
    1411                 :             : 
    1412                 :       98676 :  subroutine optics_paw_scatter(zblk,j0,nbj,nrows,ishift,mband,all_rows,diag_only,store_half,&
    1413   [ -  +  -  + ]:       32892 : &                              gpu,psinablapsi)
    1414                 :             : 
    1415                 :             : !Arguments ------------------------------------
    1416                 :             : !scalars
    1417                 :             :  integer,intent(in) :: j0,nbj,nrows,ishift,mband
    1418                 :             :  logical,intent(in) :: all_rows,diag_only,store_half,gpu
    1419                 :             : !arrays
    1420                 :             :  real(dp),intent(in) :: zblk(:,:,:)
    1421                 :             :  real(dp),intent(inout) :: psinablapsi(:,:,:)
    1422                 :             : 
    1423                 :             : !Local variables-------------------------------
    1424                 :             : !scalars
    1425                 :             :  integer :: ib,icol,idir,ii,j,jb
    1426                 :             : 
    1427                 :             : ! ************************************************************************
    1428                 :             : 
    1429                 :             : !Note: in the full matrix case (if not all_rows), element (ib,jb) with ib<jb is also stored
    1430                 :             : !      at (jb,ib); these two locations never overlap between different (ib,jb) pairs.
    1431                 :             : !      This is only done if ishift=0 (all columns are stored).
    1432                 :             : 
    1433         [ +  + ]:       32892 :  if (diag_only) then
    1434         [ +  - ]:       32576 :    if (.not.gpu) then
    1435                 :             :      !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(idir,j,jb,icol)
    1436         [ +  + ]:      130304 :      do idir=1,3
    1437         [ +  + ]:      833792 :        do j=1,nbj
    1438                 :      703488 :          jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1439         [ +  + ]:     2208192 :          psinablapsi(1:2,idir,jb)=psinablapsi(1:2,idir,jb)+zblk(1:2,jb,icol)
    1440                 :             :        end do
    1441                 :             :      end do
    1442                 :             :      !$OMP END PARALLEL DO
    1443                 :             :    else
    1444                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1445                 :             :      !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) MAP(to:zblk,psinablapsi) PRIVATE(idir,j,jb,icol)
    1446                 :             :      do idir=1,3
    1447                 :             :        do j=1,nbj
    1448                 :             :          jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1449                 :             :          psinablapsi(1,idir,jb)=psinablapsi(1,idir,jb)+zblk(1,jb,icol)
    1450                 :             :          psinablapsi(2,idir,jb)=psinablapsi(2,idir,jb)+zblk(2,jb,icol)
    1451                 :             :        end do
    1452                 :             :      end do
    1453                 :             : #endif
    1454                 :             :    end if
    1455                 :       32576 :    return
    1456                 :             :  end if
    1457                 :             : 
    1458         [ +  - ]:         316 :  if (.not.gpu) then
    1459                 :             :    !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(idir,j,ib,jb,icol,ii)
    1460         [ +  + ]:        1264 :    do idir=1,3
    1461         [ +  + ]:       11338 :      do j=1,nbj
    1462         [ +  + ]:      133191 :        do ib=1,nrows
    1463                 :      122169 :          jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1464         [ -  + ]:      132243 :          if (all_rows) then
    1465                 :           0 :            ii=(jb-1)*mband+ib-ishift
    1466         [ #  # ]:           0 :            psinablapsi(1:2,idir,ii)=psinablapsi(1:2,idir,ii)+zblk(1:2,ib,icol)
    1467         [ +  + ]:      122169 :          else if (ib<=jb) then
    1468         [ -  + ]:       67659 :            ii=merge((jb*(jb-1))/2,(jb-1)*mband,store_half)+ib-ishift
    1469         [ +  + ]:      202977 :            psinablapsi(1:2,idir,ii)=psinablapsi(1:2,idir,ii)+zblk(1:2,ib,icol)
    1470                 :             : !          Second half of the (n,m) matrix
    1471   [ -  +  -  - ]:       67659 :            if ((.not.store_half).and.ib<jb) then
    1472                 :           0 :              ii=(ib-1)*mband+jb
    1473                 :           0 :              psinablapsi(1,idir,ii)=psinablapsi(1,idir,ii)+zblk(1,ib,icol)
    1474                 :           0 :              psinablapsi(2,idir,ii)=psinablapsi(2,idir,ii)-zblk(2,ib,icol)
    1475                 :             :            end if
    1476                 :             :          end if
    1477                 :             :        end do
    1478                 :             :      end do
    1479                 :             :    end do
    1480                 :             :    !$OMP END PARALLEL DO
    1481                 :             :  else
    1482                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1483                 :             :    !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(3) MAP(to:zblk,psinablapsi) PRIVATE(idir,j,ib,jb,icol,ii)
    1484                 :             :    do idir=1,3
    1485                 :             :      do j=1,nbj
    1486                 :             :        do ib=1,nrows
    1487                 :             :          jb=j0+j-1 ; icol=(idir-1)*nbj+j
    1488                 :             :          if (all_rows) then
    1489                 :             :            ii=(jb-1)*mband+ib-ishift
    1490                 :             :            psinablapsi(1,idir,ii)=psinablapsi(1,idir,ii)+zblk(1,ib,icol)
    1491                 :             :            psinablapsi(2,idir,ii)=psinablapsi(2,idir,ii)+zblk(2,ib,icol)
    1492                 :             :          else if (ib<=jb) then
    1493                 :             :            ii=merge((jb*(jb-1))/2,(jb-1)*mband,store_half)+ib-ishift
    1494                 :             :            psinablapsi(1,idir,ii)=psinablapsi(1,idir,ii)+zblk(1,ib,icol)
    1495                 :             :            psinablapsi(2,idir,ii)=psinablapsi(2,idir,ii)+zblk(2,ib,icol)
    1496                 :             : !          Second half of the (n,m) matrix
    1497                 :             :            if ((.not.store_half).and.ib<jb) then
    1498                 :             :              ii=(ib-1)*mband+jb
    1499                 :             :              psinablapsi(1,idir,ii)=psinablapsi(1,idir,ii)+zblk(1,ib,icol)
    1500                 :             :              psinablapsi(2,idir,ii)=psinablapsi(2,idir,ii)-zblk(2,ib,icol)
    1501                 :             :            end if
    1502                 :             :          end if
    1503                 :             :        end do
    1504                 :             :      end do
    1505                 :             :    end do
    1506                 :             : #endif
    1507                 :             :  end if
    1508                 :             : 
    1509                 :             :  end subroutine optics_paw_scatter
    1510                 :             : !!***
    1511                 :             : 
    1512                 :             : !----------------------------------------------------------------------
    1513                 :             : 
    1514                 :             : !!****f* m_paw_optics/optics_paw_core
    1515                 :             : !! NAME
    1516                 :             : !! optics_paw_core
    1517                 :             : !!
    1518                 :             : !! FUNCTION
    1519                 :             : !! Compute matrix elements need for X spectr. (in the PAW context) and store them in a file
    1520                 :             : !!  Matrix elements = <Phi_core|Nabla|Phi_j>
    1521                 :             : !!
    1522                 :             : !! COPYRIGHT
    1523                 :             : !! Copyright (C) 2005-2026 ABINIT group (SM,MT,NB)
    1524                 :             : !! This file is distributed under the terms of the
    1525                 :             : !! GNU General Public License, see ~ABINIT/COPYING
    1526                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    1527                 :             : !!
    1528                 :             : !! INPUTS
    1529                 :             : !!  atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
    1530                 :             : !!  cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk> and each |p_lmn> non-local projector
    1531                 :             : !!  dimcprj(natom)=array of dimensions of array cprj (not ordered)
    1532                 :             : !!  dtfil <type(datafiles_type)>=variables related to files
    1533                 :             : !!  dtset <type(dataset_type)>=all input variables for this dataset
    1534                 :             : !!  filpsp(ntypat)=name(s) of the pseudopotential file(s)
    1535                 :             : !!  mband=maximum number of bands
    1536                 :             : !!  mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
    1537                 :             : !!  mkmem =number of k points treated by this node.
    1538                 :             : !!  mpi_enreg=information about MPI parallelization
    1539                 :             : !!  mpsang =1+maximum angular momentum for nonlocal pseudopotentials
    1540                 :             : !!  natom=number of atoms in cell.
    1541                 :             : !!  nkpt=number of k points.
    1542                 :             : !!  nsppol=1 for unpolarized, 2 for spin-polarized
    1543                 :             : !!  pawang <type(pawang_type)>= PAW ANGular mesh discretization and related data
    1544                 :             : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
    1545                 :             : !!  pawrhoij(my_natom) <type(pawrhoij_type)>= PAW rhoij occupancies and related data
    1546                 :             : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
    1547                 :             : !!  znucl(ntypat)=atomic number of atom type
    1548                 :             : !!
    1549                 :             : !! OUTPUT
    1550                 :             : !!  (only writing in a file)
    1551                 :             : !!
    1552                 :             : !! SOURCE
    1553                 :             : 
    1554                 :          14 :  subroutine optics_paw_core(atindx1,cprj,dimcprj,dtfil,dtset,eigen0,filpsp,hdr,&
    1555                 :             : &               mband,mcprj,mkmem,mpi_enreg,mpsang,natom,nkpt,nsppol,&
    1556                 :          14 : &               pawang,pawrad,pawrhoij,pawtab,znucl,rcpaw)
    1557                 :             : 
    1558                 :             : !Arguments ------------------------------------
    1559                 :             : !scalars
    1560                 :             :  integer,intent(in) :: mband,mcprj,mkmem,mpsang,natom,nkpt,nsppol
    1561                 :             :  type(MPI_type),intent(in) :: mpi_enreg
    1562                 :             :  type(datafiles_type),intent(in) :: dtfil
    1563                 :             :  type(dataset_type),intent(in) :: dtset
    1564                 :             :  type(hdr_type),intent(inout) :: hdr
    1565                 :             :  type(pawang_type),intent(in) :: pawang
    1566                 :             :  type(rcpaw_type), intent(in), pointer,optional :: rcpaw
    1567                 :             : !arrays
    1568                 :             :  integer,intent(in) :: atindx1(natom),dimcprj(natom)
    1569                 :             :  character(len=fnlen),intent(in) :: filpsp(dtset%ntypat)
    1570                 :             :  real(dp),intent(in) :: eigen0(mband*nkpt*nsppol),znucl(dtset%ntypat)
    1571                 :             :  type(pawcprj_type),target,intent(inout) :: cprj(natom,mcprj)
    1572                 :             :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
    1573                 :             :  type(pawrhoij_type),intent(inout) :: pawrhoij(mpi_enreg%my_natom)
    1574                 :             :  type(pawtab_type),target,intent(inout) :: pawtab(dtset%ntypat)
    1575                 :             : 
    1576                 :             : !Local variables-------------------------------
    1577                 :             : !scalars
    1578                 :             :  integer,parameter :: master=0
    1579                 :             :  integer :: bdtot_index,cplex,etiq,iatom,ic,ibg,idir,ilmn2
    1580                 :             :  integer :: ierr,ikpt,ilmn,iln,ount,is,my_jb,nphicor_lm
    1581                 :             :  integer :: iorder_cprj,ispinor,isppol,istwf_k,itypat,itypat2
    1582                 :             :  integer :: jb,jbsp,jlmn,lmn_size,lmncmax,mband_cprj,ncid,varid
    1583                 :             :  integer :: me,my_nspinor,nband_cprj_k,option_core,pnp_size
    1584                 :             :  integer :: nband_k,nphicor,ncorespinor,sender,iomode,fformopt,master_spfftband
    1585                 :             :  integer :: spaceComm_band,spaceComm_bandspinorfft,spaceComm_fft,spaceComm_kpt
    1586                 :             :  integer :: spaceComm_spinor,spaceComm_bandspinor,spaceComm_spinorfft,spaceComm_w
    1587                 :             :  logical :: already_has_nabla,cprj_paral_band,mykpt,myband,use_rcpaw_data
    1588                 :             :  logical :: iomode_etsf_mpiio,use_spinorbit
    1589                 :             :  logical :: i_am_master,i_am_master_band,i_am_master_spfft
    1590                 :             :  real(dp) :: cpnm1,cpnm2,el_temp
    1591                 :             :  character(len=500) :: msg
    1592                 :             : !arrays
    1593                 :             :  integer :: nc_count(6),nc_start(6),nc_stride(6),tmp_shape(3)
    1594                 :          14 :  integer,allocatable :: lcor(:,:),ncor(:,:),kappacor(:,:),nphicor_arr(:),lmn2ln(:,:)
    1595                 :             :  real(dp) :: tsec(2)
    1596                 :          14 :  real(dp),allocatable :: energy_cor(:,:),occ_cor(:,:),maxocc_cor(:,:)
    1597                 :          14 :  real(dp),allocatable :: psinablapsi(:,:,:,:,:),psinablapsi_soc(:,:,:,:,:),psinablapsi2(:,:,:,:)
    1598                 :          14 :  real(dp),pointer :: soc_ij(:,:,:)
    1599                 :          14 :  type(coeff5_type),allocatable,target :: phisocphj(:)
    1600                 :          14 :  type(pawcprj_type),pointer :: cprj_k(:,:),cprj_k_loc(:,:)
    1601                 :             :  type(nctkdim_t) :: ncdims(3)
    1602                 :             :  type(nctkarr_t) :: nctk_arrays(9)
    1603                 :          14 :  type(atomorb_type),allocatable :: atm(:)
    1604                 :             : 
    1605                 :             : ! ************************************************************************
    1606                 :             : 
    1607                 :             :  DBG_ENTER("COLL")
    1608                 :          14 :  call timab(1185,1,tsec)
    1609                 :             :  ABI_NVTX_START_RANGE(NVTX_OPTICS_PAW_CORE)
    1610                 :             : 
    1611                 :             : !Compatibility tests
    1612                 :          14 :  msg="mkmem==0 not supported anymore!"
    1613         [ -  + ]:          14 :  ABI_CHECK(mkmem/=0,msg)
    1614                 :             : !Probably should check for spinor parallelism, because thats likely to not work correctly
    1615                 :          14 :  msg="Spinor parallelism not implemented for optics_paw_core!"
    1616         [ -  + ]:          14 :  ABI_CHECK(dtset%npspinor==1,msg)
    1617                 :             : !Is mpi_enreg initialized?
    1618                 :             :  if (xmpi_paral==1) then
    1619         [ +  + ]:          56 :    tmp_shape = shape(mpi_enreg%proc_distrb)
    1620         [ -  + ]:          14 :    if (nkpt > tmp_shape(1)) then
    1621                 :           0 :      ABI_BUG('problem with proc_distrb!')
    1622                 :             :    end if
    1623                 :             :  end if
    1624                 :             : 
    1625                 :             : !Init parallelism
    1626                 :          14 :  spaceComm_w=mpi_enreg%comm_cell
    1627         [ +  + ]:          14 :  if (mpi_enreg%paral_kgb==1) then
    1628                 :           8 :    spaceComm_kpt=mpi_enreg%comm_kpt
    1629                 :           8 :    spaceComm_fft=mpi_enreg%comm_fft
    1630                 :           8 :    spaceComm_band=mpi_enreg%comm_band
    1631                 :           8 :    spaceComm_spinor=mpi_enreg%comm_spinor
    1632                 :           8 :    spaceComm_bandspinor=mpi_enreg%comm_bandspinor
    1633                 :           8 :    spaceComm_spinorfft=mpi_enreg%comm_spinorfft
    1634                 :           8 :    spaceComm_bandspinorfft=mpi_enreg%comm_bandspinorfft
    1635                 :             :  else
    1636                 :           6 :    spaceComm_kpt=mpi_enreg%comm_kpt
    1637                 :           6 :    spaceComm_fft=xmpi_comm_self
    1638                 :           6 :    spaceComm_band=mpi_enreg%comm_band
    1639                 :           6 :    spaceComm_spinor=xmpi_comm_self
    1640                 :           6 :    spaceComm_bandspinor=spaceComm_band
    1641                 :           6 :    spaceComm_spinorfft=xmpi_comm_self
    1642                 :           6 :    spaceComm_bandspinorfft=xmpi_comm_self
    1643                 :             :  end if
    1644                 :          14 :  me=xmpi_comm_rank(spaceComm_w)
    1645                 :          14 :  i_am_master=(me==master)
    1646                 :          14 :  i_am_master_band=(xmpi_comm_rank(spaceComm_band)==master)
    1647                 :          14 :  i_am_master_spfft=(xmpi_comm_rank(spaceComm_spinorfft)==master)
    1648                 :          14 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
    1649                 :             : 
    1650                 :             : !------------------------------------------------------------------------------------------------
    1651                 :             : !1- Reading of core wavefunctions
    1652                 :             : !------------------------------------------------------------------------------------------------
    1653                 :             : #if defined(HAVE_GPU_MARKERS)
    1654                 :             :  call nvtxStartRange("read")
    1655                 :             : #endif
    1656                 :             :  !TODO At present, impose 2-spinor simulataneously for core and valence WF
    1657   [ -  +  +  -  :          58 :  ABI_MALLOC(atm,(dtset%ntypat))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
    1658         [ +  + ]:          30 :  do itypat=1,dtset%ntypat
    1659                 :          16 :    use_rcpaw_data=.false.
    1660         [ +  + ]:          16 :    if(present(rcpaw)) then
    1661         [ +  - ]:           1 :      if(associated(rcpaw)) then
    1662         [ +  - ]:           1 :        if(allocated(rcpaw%atm)) then
    1663         [ +  - ]:           1 :          if(dtset%ntypat==size(rcpaw%atm)) then
    1664                 :           1 :            call copy_atomorb(rcpaw%atm(itypat),atm(itypat))
    1665                 :             :            use_rcpaw_data=.true.
    1666                 :             :          endif
    1667                 :             :        endif
    1668                 :             :      endif
    1669                 :             :    endif
    1670                 :          14 :    if(.not.use_rcpaw_data) then
    1671                 :          15 :      call pawpsp_init_core(atm(itypat),filpsp(itypat),radmesh=pawrad(itypat))
    1672                 :             :    endif
    1673                 :             :  enddo
    1674                 :             : 
    1675         [ -  + ]:          14 :  if(dtset%cwfs_wouth==1) then
    1676         [ #  # ]:           0 :    do itypat=1,dtset%ntypat
    1677         [ #  # ]:           0 :      if(atm(itypat)%mult==1) then
    1678         [ #  # ]:           0 :        do itypat2=1,dtset%ntypat
    1679                 :             :          if(atm(itypat2)%mult>1.and.atm(itypat2)%znucl==atm(itypat)%znucl.and.&
    1680                 :             : &           atm(itypat2)%mesh_size==atm(itypat)%mesh_size.and.&
    1681                 :             : &           atm(itypat2)%ln_size==atm(itypat)%ln_size.and.&
    1682   [ #  #  #  #  :           0 : &           atm(itypat2)%nsppol==atm(itypat)%nsppol.and.&
          #  #  #  #  #  
                #  #  # ]
    1683                 :           0 : &           atm(itypat2)%zcore_orig>atm(itypat)%zcore_orig) then
    1684                 :           0 :            write(std_out,*) 'Core wfs of typat ',itypat,' replaced by those of typat ',itypat2
    1685   [ #  #  #  #  :           0 :            atm(itypat)%phi=atm(itypat2)%phi
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1686                 :             :            exit
    1687                 :             :          endif
    1688                 :             :        enddo
    1689                 :             :      endif
    1690                 :             :    enddo
    1691                 :             :  endif
    1692                 :             : 
    1693                 :             : 
    1694                 :             : !nphicor=max. number of core (l,n) states over atom types
    1695                 :             : !nphicor_lm=max. number of core (l,m,n) channels over atom types
    1696                 :             : !           (spinor components are removed below if nspinor=2)
    1697                 :          14 :  nphicor=0
    1698                 :          14 :  ncorespinor=0
    1699                 :          14 :  nphicor_lm=0
    1700         [ +  + ]:          30 :  do itypat=1,dtset%ntypat
    1701                 :          16 :    nphicor=max(nphicor,atm(itypat)%ln_size)
    1702                 :          16 :    nphicor_lm=max(nphicor_lm,atm(itypat)%lmn_size)
    1703         [ -  + ]:          16 :    if(atm(itypat)%nsppol>1) ABI_ERROR("nsppol>1 is work in progress for optics_paw_core")
    1704         [ -  + ]:          16 :    if(atm(itypat)%nspinor/=dtset%nspinor) ABI_ERROR("Core and valence not same number of spinors")
    1705                 :          30 :    ncorespinor=max(ncorespinor,atm(itypat)%nspinor)
    1706                 :             :  enddo
    1707         [ +  + ]:          14 :  if(dtset%nspinor==2) nphicor_lm=nphicor_lm/2
    1708                 :             : 
    1709   [ -  +  +  -  :          56 :  ABI_MALLOC(lmn2ln,(nphicor_lm,dtset%ntypat))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1710   [ +  +  +  + ]:         140 :  lmn2ln=0
    1711         [ +  + ]:          30 :  do itypat=1,dtset%ntypat
    1712                 :          16 :    lmncmax=atm(itypat)%lmn_size
    1713         [ +  + ]:          16 :    if(dtset%nspinor==2) lmncmax=lmncmax/2
    1714         [ +  + ]:         132 :    do ilmn=1,lmncmax
    1715         [ +  + ]:         118 :      if(dtset%nspinor==1) then
    1716                 :          42 :        lmn2ln(ilmn,itypat)=atm(itypat)%indlmn(5,ilmn)
    1717                 :             :      else
    1718         [ +  - ]:         594 :        do ilmn2=1,atm(itypat)%lmn_size
    1719         [ +  + ]:         594 :          if(atm(itypat)%indlmn(9,ilmn2)==ilmn) then
    1720                 :          60 :            lmn2ln(ilmn,itypat)=atm(itypat)%indlmn(5,ilmn2)
    1721                 :          60 :            exit
    1722                 :             :          endif
    1723                 :             :        enddo
    1724                 :             :      endif
    1725                 :             :    enddo
    1726                 :             :  enddo
    1727                 :             : #if defined(HAVE_GPU_MARKERS)
    1728                 :             :  call nvtxEndRange()
    1729                 :             : #endif
    1730                 :             : 
    1731                 :             : !----------------------------------------------------------------------------------
    1732                 :             : !2- Computation of phipphj=<phi_i|nabla|phi_core>
    1733                 :             : !----------------------------------------------------------------------------------
    1734                 :             : 
    1735                 :             : #if defined(HAVE_GPU_MARKERS)
    1736                 :             :  call nvtxStartRange("pawnabla_core_init")
    1737                 :             : #endif
    1738   [ +  -  -  + ]:          14 :  already_has_nabla=all(pawtab(:)%has_nabla==3)
    1739   [ +  +  +  -  :          14 :  if (ncorespinor==2) already_has_nabla=all(pawtab(:)%has_nabla==4)
                   -  + ]
    1740                 :             : !  Should check whether this would work with spinor parallelism
    1741                 :          14 :  call pawnabla_core_init(mpsang,dtset%ntypat,pawrad,pawtab,atm)
    1742                 :             : 
    1743                 :             : !Get electronic temperature from dtset
    1744   [ +  -  -  -  :          14 :  el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
                   -  - ]
    1745                 :             : #if defined(HAVE_GPU_MARKERS)
    1746                 :             :  call nvtxEndRange()
    1747                 :             : #endif
    1748                 :             : 
    1749                 :             : !Compute spin-orbit contributions if necessary
    1750   [ +  +  +  - ]:          14 :  use_spinorbit=(dtset%pawspnorb==1.and.dtset%userie/=111) ! For testing purpose
    1751                 :             :  if (use_spinorbit) then
    1752                 :             : #if defined(HAVE_GPU_MARKERS)
    1753                 :             :    call nvtxStartRange("pawnabla_soc_init")
    1754                 :             : #endif
    1755                 :           6 :    option_core=1
    1756                 :             :    call pawnabla_soc_init(el_temp,phisocphj,option_core,dtset%ixc,mpi_enreg%my_natom,natom,&
    1757                 :             : &       dtset%nspden,dtset%ntypat,pawang,pawrad,pawrhoij,pawtab,dtset%pawxcdev,&
    1758                 :             : &       dtset%spnorbscl,dtset%typat,dtset%xc_denpos,dtset%xc_taupos,znucl,&
    1759                 :           6 : &       atm=atm,comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab)
    1760                 :             : #if defined(HAVE_GPU_MARKERS)
    1761                 :             :  call nvtxEndRange()
    1762                 :             : #endif
    1763                 :             :  end if
    1764                 :             : 
    1765                 :             : !----------------------------------------------------------------------------------
    1766                 :             : !3- Opening of OPT2 file and header writing
    1767                 :             : !----------------------------------------------------------------------------------
    1768                 :             : 
    1769                 :             : #if defined(HAVE_GPU_MARKERS)
    1770                 :             :  call nvtxStartRange("header_write")
    1771                 :             : #endif
    1772                 :             : !I/O mode is netCDF or Fortran
    1773                 :             :  iomode=merge(IO_MODE_ETSF,IO_MODE_FORTRAN_MASTER,dtset%iomode==IO_MODE_ETSF)
    1774                 :          14 :  if (use_netcdf_forced) iomode=IO_MODE_ETSF
    1775                 :             : 
    1776   [ -  +  +  -  :          56 :  ABI_MALLOC(energy_cor,(nphicor,dtset%ntypat))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1777   [ -  +  +  -  :          56 :  ABI_MALLOC(ncor,(nphicor,dtset%ntypat))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1778   [ -  +  +  -  :          42 :  ABI_MALLOC(lcor,(nphicor,dtset%ntypat))
          -  +  +  -  -  
                +  -  + ]
    1779   [ -  +  +  -  :          42 :  ABI_MALLOC(kappacor,(nphicor,dtset%ntypat))
          -  +  +  -  -  
                +  -  + ]
    1780   [ -  +  +  -  :          42 :  ABI_MALLOC(occ_cor,(nphicor,dtset%ntypat))
          -  +  +  -  -  
                +  -  + ]
    1781   [ -  +  +  -  :          42 :  ABI_MALLOC(maxocc_cor,(nphicor,dtset%ntypat))
          -  +  +  -  -  
                +  -  + ]
    1782   [ +  +  +  + ]:          84 :  energy_cor=zero
    1783   [ +  +  +  + ]:          84 :  ncor=0
    1784   [ +  +  +  + ]:          84 :  lcor=0
    1785   [ +  +  +  + ]:          84 :  kappacor=0
    1786   [ +  +  +  + ]:          84 :  occ_cor=zero
    1787   [ +  +  +  + ]:          84 :  maxocc_cor=zero
    1788         [ +  + ]:          30 :  do itypat=1,dtset%ntypat
    1789         [ +  + ]:          80 :    do iln=1,atm(itypat)%ln_size
    1790                 :          50 :      energy_cor(iln,itypat)=atm(itypat)%eig(iln,1)
    1791                 :          50 :      ncor(iln,itypat)=atm(itypat)%indln(2,iln)
    1792                 :          50 :      lcor(iln,itypat)=atm(itypat)%indln(1,iln)
    1793                 :          50 :      occ_cor(iln,itypat)=atm(itypat)%occ(iln,1)
    1794                 :          50 :      maxocc_cor(iln,itypat)=atm(itypat)%max_occ(iln,1)
    1795         [ +  + ]:          66 :      if(atm(itypat)%dirac) then
    1796                 :          24 :        kappacor(iln,itypat)=atm(itypat)%kappa(iln)
    1797                 :             :      else
    1798                 :          26 :        kappacor(iln,itypat)=0
    1799                 :             :      endif
    1800                 :             :    enddo
    1801                 :             :  enddo
    1802                 :             : 
    1803                 :             :  !(master proc only)
    1804         [ +  + ]:          14 :  if (i_am_master) then
    1805                 :             : !  ====> NETCDF format
    1806                 :             :    if (iomode==IO_MODE_ETSF) then
    1807                 :           8 :      fformopt=611
    1808   [ -  +  +  -  :          24 :      ABI_MALLOC(nphicor_arr,(dtset%ntypat))
          +  -  +  -  -  
                +  -  + ]
    1809         [ +  + ]:          18 :      do itypat=1,dtset%ntypat
    1810                 :          18 :        nphicor_arr(itypat)=atm(itypat)%ln_size
    1811                 :             :      enddo
    1812                 :             : !    Open/create nc file
    1813         [ -  + ]:           8 :      NCF_CHECK(nctk_open_create(ncid,nctk_ncify(dtfil%fnameabo_app_opt2),xmpi_comm_self))
    1814                 :             : !    Write header data
    1815         [ -  + ]:           8 :      NCF_CHECK(hdr%ncwrite(ncid,fformopt,nc_define=.true.))
    1816                 :             : !    Define additional dimensions
    1817                 :           8 :      ncdims(1)%name="number_of_atom_types"
    1818                 :           8 :      ncdims(1)%value=dtset%ntypat
    1819                 :           8 :      ncdims(2)%name="max_number_of_core_states"
    1820                 :           8 :      ncdims(2)%value=nphicor
    1821                 :           8 :      ncdims(3)%name="number_of_core_spinor_components"
    1822                 :           8 :      ncdims(3)%value=ncorespinor
    1823         [ -  + ]:           8 :      NCF_CHECK(nctk_def_dims(ncid,ncdims))
    1824                 :           8 :      nctk_arrays(1)%name="number_of_core_states"
    1825                 :           8 :      nctk_arrays(1)%dtype="int"
    1826                 :           8 :      nctk_arrays(1)%shape_str="number_of_atom_types"
    1827                 :           8 :      nctk_arrays(2)%name="eigenvalues_core"
    1828                 :           8 :      nctk_arrays(2)%dtype="dp"
    1829                 :           8 :      nctk_arrays(2)%shape_str="max_number_of_core_states,number_of_atom_types"
    1830                 :           8 :      nctk_arrays(3)%name="dipole_core_valence"
    1831                 :           8 :      nctk_arrays(3)%dtype="dp"
    1832                 :             :      nctk_arrays(3)%shape_str=&
    1833                 :             : &     "number_of_cartesian_directions,max_number_of_core_states,"// &
    1834                 :           8 : &     "number_of_atoms,max_number_of_states,number_of_kpoints,number_of_spins"
    1835                 :           8 :      nctk_arrays(4)%name="n_quantum_number_core"
    1836                 :           8 :      nctk_arrays(4)%dtype="int"
    1837                 :           8 :      nctk_arrays(4)%shape_str="max_number_of_core_states,number_of_atom_types"
    1838                 :           8 :      nctk_arrays(5)%name="l_quantum_number_core"
    1839                 :           8 :      nctk_arrays(5)%dtype="int"
    1840                 :           8 :      nctk_arrays(5)%shape_str="max_number_of_core_states,number_of_atom_types"
    1841                 :           8 :      nctk_arrays(6)%name="kappa_core"
    1842                 :           8 :      nctk_arrays(6)%dtype="int"
    1843                 :           8 :      nctk_arrays(6)%shape_str="max_number_of_core_states,number_of_atom_types"
    1844                 :           8 :      nctk_arrays(7)%name="number_of_core_states"
    1845                 :           8 :      nctk_arrays(7)%dtype="int"
    1846                 :           8 :      nctk_arrays(7)%shape_str="number_of_atom_types"
    1847                 :           8 :      nctk_arrays(8)%name="occupation_core"
    1848                 :           8 :      nctk_arrays(8)%dtype="dp"
    1849                 :           8 :      nctk_arrays(8)%shape_str="max_number_of_core_states,number_of_atom_types"
    1850                 :           8 :      nctk_arrays(9)%name="max_occupation_core"
    1851                 :           8 :      nctk_arrays(9)%dtype="dp"
    1852                 :           8 :      nctk_arrays(9)%shape_str="max_number_of_core_states,number_of_atom_types"
    1853         [ -  + ]:           8 :      NCF_CHECK(nctk_def_arrays(ncid, nctk_arrays))
    1854         [ -  + ]:           8 :      NCF_CHECK(nctk_set_atomic_units(ncid, "eigenvalues_core"))
    1855         [ -  + ]:           8 :      NCF_CHECK(nctk_set_atomic_units(ncid, "dipole_core_valence"))
    1856                 :             : !    Write core states
    1857         [ -  + ]:           8 :      NCF_CHECK(nctk_set_datamode(ncid))
    1858                 :           8 :      varid=nctk_idname(ncid,"eigenvalues_core")
    1859         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,energy_cor))
    1860                 :           8 :      varid=nctk_idname(ncid,"n_quantum_number_core")
    1861         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,ncor))
    1862                 :           8 :      varid=nctk_idname(ncid,"l_quantum_number_core")
    1863         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,lcor))
    1864                 :           8 :      varid=nctk_idname(ncid,"kappa_core")
    1865         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,kappacor))
    1866                 :           8 :      varid=nctk_idname(ncid,"occupation_core")
    1867         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,occ_cor))
    1868                 :           8 :      varid=nctk_idname(ncid,"max_occupation_core")
    1869         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,maxocc_cor))
    1870                 :           8 :      varid=nctk_idname(ncid,"number_of_core_states")
    1871         [ -  + ]:           8 :      NCF_CHECK(nf90_put_var(ncid,varid,nphicor_arr))
    1872                 :             : !    Write eigenvalues
    1873                 :           8 :      varid=nctk_idname(ncid,"eigenvalues")
    1874   [ +  +  -  +  :          32 :      NCF_CHECK(nf90_put_var(ncid,varid,reshape(eigen0,[mband,nkpt,nsppol])))
                   -  - ]
    1875                 :             :      !Close file here because the rest has possibly to be written with collective I/O
    1876         [ -  + ]:           8 :      NCF_CHECK(nf90_close(ncid))
    1877         [ -  + ]:           8 :      ABI_FREE(nphicor_arr)
    1878                 :             : !  ====> Standard FORTRAN binary file format
    1879                 :             :    else if (iomode==IO_MODE_FORTRAN_MASTER) then
    1880                 :             :      fformopt=612  ! MT 12sept21: change the OPT2 Fortran file format
    1881                 :             :      if (2*nphicor*natom*mband>2**30) fformopt=613 ! Format for large file records
    1882                 :             :      if (open_file(dtfil%fnameabo_app_opt2,msg,newunit=ount,form="unformatted",status="unknown")/= 0) then
    1883                 :             :        ABI_ERROR(msg)
    1884                 :             :      end if
    1885                 :             :      call hdr%fort_write(ount,fformopt,ierr,rewind=.true.)
    1886                 :             :      write(ount)(eigen0(jb),jb=1,mband*nkpt*nsppol)
    1887                 :             :      write(ount) nphicor
    1888                 :             :      do itypat=1,dtset%ntypat
    1889                 :             :        write(ount) atm(itypat)%ln_size
    1890                 :             :        do iln=1,nphicor
    1891                 :             :          write(ount) ncor(iln,itypat),lcor(iln,itypat),kappacor(iln,itypat),occ_cor(iln,itypat),maxocc_cor(iln,itypat),&
    1892                 :             :                      energy_cor(iln,itypat)
    1893                 :             :        end do
    1894                 :             :      enddo
    1895                 :             :    else
    1896                 :             :      msg = "Wrong OPT2 file format!"
    1897                 :             :      ABI_BUG(msg)
    1898                 :             :    end if ! File format
    1899                 :             :  end if ! master node
    1900                 :          14 :  call xmpi_bcast(iomode,master,spaceComm_w,ierr)  ! Seems mandatory; why ?
    1901                 :          14 :  call xmpi_bcast(fformopt,master,spaceComm_w,ierr)
    1902   [ +  -  -  + ]:          14 :  iomode_etsf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio)
    1903                 :             : 
    1904         [ -  + ]:          14 :  ABI_FREE(ncor)
    1905         [ -  + ]:          14 :  ABI_FREE(lcor)
    1906         [ -  + ]:          14 :  ABI_FREE(kappacor)
    1907         [ -  + ]:          14 :  ABI_FREE(occ_cor)
    1908         [ -  + ]:          14 :  ABI_FREE(maxocc_cor)
    1909         [ -  + ]:          14 :  ABI_FREE(energy_cor)
    1910                 :             : #if defined(HAVE_GPU_MARKERS)
    1911                 :             :  call nvtxEndRange()
    1912                 :             : #endif
    1913                 :             : 
    1914                 :             : !----------------------------------------------------------------------------------
    1915                 :             : !4- Computation of <psi_n|p_i>(<phi_i|-i.nabla|phi_core>)
    1916                 :             : !----------------------------------------------------------------------------------
    1917                 :             : 
    1918                 :             : #if defined(HAVE_GPU_MARKERS)
    1919                 :             :  call nvtxStartRange("pre_spinkpt_loop")
    1920                 :             : #endif
    1921                 :             : !Prepare core-valence dipoles writing
    1922                 :             : !In case of netCDF access to OPT2 file, prepare collective I/O
    1923         [ +  - ]:          14 :  if (iomode == IO_MODE_ETSF) then
    1924         [ +  - ]:          14 :    if (iomode_etsf_mpiio) then
    1925         [ +  + ]:          14 :      if (i_am_master_spfft) then
    1926         [ -  + ]:          10 :        NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt2),spaceComm_band))
    1927                 :          10 :        varid=nctk_idname(ncid,"dipole_core_valence")
    1928         [ +  + ]:          10 :        if (xmpi_comm_size(spaceComm_w)>1) then
    1929         [ -  + ]:           4 :          NCF_CHECK(nctk_set_collective(ncid,varid))
    1930                 :             :        end if
    1931         [ -  + ]:          10 :        NCF_CHECK(nctk_set_datamode(ncid))
    1932                 :             :      end if
    1933         [ #  # ]:           0 :    else if (i_am_master) then
    1934         [ #  # ]:           0 :      NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt2),xmpi_comm_self))
    1935                 :           0 :      varid=nctk_idname(ncid,"dipole_core_valence")
    1936                 :             :      if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then
    1937                 :             :        NCF_CHECK(nctk_set_collective(ncid,varid))
    1938                 :             :      end if
    1939         [ #  # ]:           0 :      NCF_CHECK(nctk_set_datamode(ncid))
    1940                 :             :    end if
    1941                 :             :  end if
    1942         [ +  - ]:          14 :  if (iomode_etsf_mpiio) then
    1943                 :             :    !If MPI-IO, store only elements for one band
    1944   [ -  +  +  -  :          56 :    ABI_MALLOC(psinablapsi,(2,3,nphicor_lm,natom,1))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1945   [ -  +  +  -  :          56 :    ABI_MALLOC(psinablapsi2,(3,nphicor,natom,1))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1946         [ +  + ]:          14 :    if (use_spinorbit) then
    1947   [ -  +  +  -  :          18 :      ABI_MALLOC(psinablapsi_soc,(2,3,nphicor_lm,natom,1))
          -  +  +  -  -  
                +  -  + ]
    1948                 :             :    end if
    1949                 :             :  else
    1950                 :             :    !If not, store the elements for all bands
    1951   [ #  #  #  #  :           0 :    ABI_MALLOC(psinablapsi,(2,3,nphicor_lm,natom,mband))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1952   [ #  #  #  #  :           0 :    ABI_MALLOC(psinablapsi2,(3,nphicor,natom,mband))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    1953         [ #  # ]:           0 :    if (use_spinorbit) then
    1954   [ #  #  #  #  :           0 :      ABI_MALLOC(psinablapsi_soc,(2,3,nphicor_lm,natom,mband))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1955                 :             :    end if
    1956                 :             :  end if
    1957         [ +  + ]:          70 :  pnp_size=size(psinablapsi2)
    1958                 :             : 
    1959                 :             : !Determine if cprj datastructure is distributed over bands
    1960                 :          14 :  mband_cprj=mcprj/(my_nspinor*mkmem*nsppol)
    1961                 :          14 :  cprj_paral_band=(mband_cprj<mband)
    1962                 :             : #if defined(HAVE_GPU_MARKERS)
    1963                 :             :  call nvtxEndRange()
    1964                 :             : #endif
    1965                 :             : 
    1966                 :             : !LOOP OVER SPINS
    1967                 :          14 :  ibg=0
    1968                 :          14 :  bdtot_index=0
    1969         [ +  + ]:          28 :  do isppol=1,nsppol
    1970                 :             : 
    1971                 :             : !  LOOP OVER k POINTS
    1972         [ +  + ]:          44 :    do ikpt=1,nkpt
    1973                 :             : #if defined(HAVE_GPU_MARKERS)
    1974                 :             :      call nvtxStartRange("kpoint step")
    1975                 :             : #endif
    1976                 :             : 
    1977                 :          16 :      etiq=ikpt+(isppol-1)*nkpt
    1978                 :          16 :      nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
    1979         [ +  + ]:         260 :      master_spfftband=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol))
    1980                 :             : 
    1981                 :             : !    Select k-points for current proc
    1982                 :          16 :      mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,mpi_enreg%me_kpt))
    1983         [ +  - ]:          16 :      if (mykpt) then
    1984                 :             : #if defined(HAVE_GPU_MARKERS)
    1985                 :             :        call nvtxStartRange("pawcprj_alloc")
    1986                 :             : #endif
    1987                 :             : 
    1988                 :             : !      Data depending on k-point
    1989                 :          16 :        istwf_k=dtset%istwfk(ikpt)
    1990         [ +  + ]:          16 :        cplex=2;if (istwf_k>1) cplex=1
    1991                 :             : 
    1992                 :             : !      Extract cprj for this k-point
    1993         [ +  + ]:          16 :        nband_cprj_k=nband_k;if (cprj_paral_band) nband_cprj_k=nband_k/mpi_enreg%nproc_band
    1994         [ +  + ]:          16 :        if (mkmem*nsppol/=1) then
    1995                 :           4 :          iorder_cprj=0
    1996   [ -  +  +  -  :         208 :          ABI_MALLOC(cprj_k_loc,(natom,my_nspinor*nband_cprj_k))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1997                 :           4 :          call pawcprj_alloc(cprj_k_loc,0,dimcprj)
    1998                 :             :          call pawcprj_get(atindx1,cprj_k_loc,cprj,natom,1,ibg,ikpt,iorder_cprj,isppol,&
    1999                 :             : &         mband_cprj,mkmem,natom,nband_cprj_k,nband_cprj_k,my_nspinor,nsppol,dtfil%unpaw,&
    2000         [ -  + ]:           4 : &         mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
    2001                 :             :        else
    2002                 :          12 :          cprj_k_loc => cprj
    2003                 :             :        end if
    2004                 :             : 
    2005                 :             : !      if cprj are distributed over bands, gather them (because we need to mix bands)
    2006         [ +  + ]:          16 :        if (cprj_paral_band) then
    2007   [ -  +  +  -  :        1032 :          ABI_MALLOC(cprj_k,(natom,my_nspinor*nband_k))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    2008                 :           8 :          call pawcprj_alloc(cprj_k,0,dimcprj)
    2009                 :             :          call pawcprj_mpi_allgather(cprj_k_loc,cprj_k,natom,my_nspinor*nband_cprj_k, &
    2010                 :             : &                                   my_nspinor*mpi_enreg%bandpp,&
    2011                 :           8 : &         dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band,ierr,rank_ordered=.false.)
    2012                 :             :        else
    2013                 :           8 :          cprj_k => cprj_k_loc
    2014                 :             :        end if
    2015                 :             : #if defined(HAVE_GPU_MARKERS)
    2016                 :             :        call nvtxEndRange()
    2017                 :             : #endif
    2018                 :             : 
    2019                 :             : #if defined(HAVE_GPU_MARKERS)
    2020                 :             :        call nvtxStartRange("jband_loop",5)
    2021                 :             : #endif
    2022                 :             : !      Loops over bands
    2023         [ +  + ]:         260 :        do jb=1,nband_k
    2024                 :             :          !If MPI-IO, store only ib elements for each jb ; if not, store all (ib,jb) pairs
    2025         [ -  + ]:         244 :          my_jb=merge(1,jb,iomode_etsf_mpiio)
    2026                 :             : 
    2027   [ +  +  +  +  :       61432 :          psinablapsi(:,:,:,:,my_jb)=zero
             +  +  +  + ]
    2028   [ +  +  +  +  :       12168 :          psinablapsi2(:,:,:,my_jb)=zero
                   +  + ]
    2029   [ +  +  +  +  :       42664 :          if (use_spinorbit) psinablapsi_soc(:,:,:,:,my_jb)=zero
          +  +  +  +  +  
                      + ]
    2030                 :             : 
    2031                 :             : !        Computation of <psi_n|p_i><phi_i|-i.nabla|phi_core>
    2032                 :             : !        ----------------------------------------------------------------------------------
    2033                 :             : 
    2034                 :             : !        Select bands for current proc
    2035                 :         244 :          myband=.true.
    2036         [ +  + ]:         244 :          if (mpi_enreg%paral_kgb==1) then
    2037                 :         120 :            myband=(mod(jb-1,mpi_enreg%nproc_band)==mpi_enreg%me_band)
    2038                 :         124 :          else if (xmpi_paral==1) then
    2039                 :         124 :            myband=(abs(mpi_enreg%proc_distrb(ikpt,jb,isppol)-mpi_enreg%me_kpt)==0)
    2040                 :             :          end if
    2041         [ +  + ]:         244 :          if (myband) then
    2042                 :             : 
    2043                 :         184 :            jbsp=(jb-1)*my_nspinor
    2044                 :             : 
    2045                 :             : !          1-spinor case
    2046   [ +  +  +  - ]:         184 :            if (dtset%nspinor==1.and.ncorespinor==1) then
    2047                 :         104 :              jbsp=jbsp+1
    2048         [ +  + ]:         104 :              if (cplex==1) then ! Real WF case
    2049         [ +  + ]:         146 :                do iatom=1,natom
    2050                 :         104 :                  itypat=dtset%typat(iatom)
    2051                 :         104 :                  lmn_size=pawtab(itypat)%lmn_size
    2052                 :         104 :                  lmncmax=atm(itypat)%lmn_size
    2053         [ +  + ]:        1106 :                  do jlmn=1,lmn_size
    2054         [ +  + ]:        4328 :                    do ilmn=1,lmncmax
    2055                 :        3264 :                      ic=ilmn !atm(itypat)%indlmn(5,ilmn)
    2056                 :        3264 :                      cpnm1=cprj_k(iatom,jbsp)%cp(1,jlmn)
    2057                 :             :                      psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    2058         [ +  + ]:       14016 : &                        -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    2059                 :             :                    end do !ilmn
    2060                 :             :                  end do !jlmn
    2061                 :             :                end do !iatom
    2062                 :             :              else ! Complex WF case
    2063         [ +  + ]:         246 :                do iatom=1,natom
    2064                 :         184 :                  itypat=dtset%typat(iatom)
    2065                 :         184 :                  lmn_size=pawtab(itypat)%lmn_size
    2066                 :         184 :                  lmncmax=atm(itypat)%lmn_size
    2067         [ +  + ]:        1846 :                  do jlmn=1,lmn_size
    2068         [ +  + ]:        8248 :                    do ilmn=1,lmncmax
    2069                 :        6464 :                      ic=ilmn !atm(itypat)%indlmn(5,ilmn)
    2070                 :        6464 :                      cpnm1=cprj_k(iatom,jbsp)%cp(1,jlmn)
    2071                 :        6464 :                      cpnm2=cprj_k(iatom,jbsp)%cp(2,jlmn)
    2072                 :             :                      psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    2073         [ +  + ]:       25856 : &                        -cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    2074                 :             :                      psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    2075         [ +  + ]:       27456 : &                        -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    2076                 :             :                    end do !ilmn
    2077                 :             :                  end do !jlmn
    2078                 :             :                end do !iatom
    2079                 :             :              end if
    2080                 :             : 
    2081                 :             : !          2-spinor case
    2082   [ +  -  +  - ]:          80 :            else if (dtset%nspinor==2.and.ncorespinor==2) then
    2083         [ +  + ]:         240 :              do ispinor=1,my_nspinor
    2084                 :         160 :                jbsp=jbsp+1
    2085         [ +  + ]:         760 :                do iatom=1,natom
    2086                 :         520 :                  itypat=dtset%typat(iatom)
    2087                 :         520 :                  lmn_size=pawtab(itypat)%lmn_size
    2088                 :         520 :                  lmncmax=atm(itypat)%lmn_size
    2089         [ +  + ]:        5240 :                  do jlmn=1,lmn_size
    2090         [ +  + ]:       96280 :                    do ilmn=1,lmncmax
    2091                 :       91200 :                      is=atm(itypat)%indlmn(6,ilmn)
    2092         [ +  + ]:       95760 :                      if (modulo(jbsp,2)==modulo(is,2)) then ! Nabla is a spin-diagonal operator
    2093                 :       45600 :                        ic=atm(itypat)%indlmn(9,ilmn)
    2094         [ +  + ]:       45600 :                        if (ic>0) then
    2095                 :       31920 :                          cpnm1=cprj_k(iatom,jbsp)%cp(1,jlmn)
    2096                 :       31920 :                          cpnm2=cprj_k(iatom,jbsp)%cp(2,jlmn)
    2097                 :             :                          psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    2098                 :             : &                            +cpnm1*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn) &
    2099         [ +  + ]:      127680 : &                            -cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    2100                 :             :                          psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    2101                 :             : &                            -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn) &
    2102         [ +  + ]:      127680 : &                            -cpnm2*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn)
    2103                 :             :                        end if
    2104                 :             :                      end if
    2105                 :             :                    end do ! ilmn
    2106                 :             :                  end do !jlmn
    2107                 :             :                end do !iatom
    2108                 :             :              end do !ispinor
    2109                 :             :            else
    2110                 :           0 :              msg="Core and valence WF should have the same spinor representation!"
    2111                 :           0 :              ABI_BUG(msg)
    2112                 :             :              !N. Brouwer initial coding: should be justified!
    2113                 :             :              !if (dtset%nspinor==1.and.ncorespinor==2) then  ! Average core spinors
    2114                 :             :              !  psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    2115                 :             :              ! &    +half_sqrt2*(cpnm1*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn) &
    2116                 :             :              ! &                +cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn))
    2117                 :             :              !  psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    2118                 :             :              ! &    +half_sqrt2*(cpnm2*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn) &
    2119                 :             :              ! &                -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn))
    2120                 :             :              !else if (dtset%nspinor==2.and.ncorespinor==1) then ! Average valence spinors
    2121                 :             :              !  psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    2122                 :             :              ! &    +half_sqrt2*cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    2123                 :             :              !  psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    2124                 :             :              ! &    -half_sqrt2*cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    2125                 :             :              !endif
    2126                 :             :            endif
    2127                 :             : 
    2128                 :             : !          Spin-orbit coupling contribution:
    2129                 :             : !             Sum_i,ss'[<psi^s_n|p_i><phi_i|1/4 Alpha^2 (Sigma^ss' X dV/dr)|phj_core^s'>]
    2130         [ +  + ]:         184 :            if (use_spinorbit) then
    2131                 :             : !            Add: Sum_i,ss'[<Psi^s_n|p_i> (Sigma^ss' X g_ij_core^s']
    2132                 :             : !             where: g_ij_core^s = <Phi_i| 1/4 Alpha^2 dV/dr vec(r)/r) |Phj_core^s>
    2133                 :             : !            Note that:
    2134                 :             : !             if phi_cor_jlmn_cor(:) is up:
    2135                 :             : !              phisocphj(:)%value(re:im,1,idir,ilmn,jlmn_cor) is (Sigma^up-up X g_ij_core^up)
    2136                 :             : !              phisocphj(:)%value(re:im,2,idir,ilmn,jlmn_cor) is (Sigma^dn-up X g_ij_core^up)
    2137                 :             : !             if phi_cor_jlmn_cor(:) is down:
    2138                 :             : !              phisocphj(:)%value(re:im,1,idir,ilmn,jlmn_cor) is (Sigma^up-dn X g_ij_core^dn)
    2139                 :             : !              phisocphj(:)%value(re:im,2,idir,ilmn,jlmn_cor) is (Sigma^dn-dn X g_ij_core^dn)
    2140                 :             : !            Not compatible with parallelization over spinors
    2141                 :          80 :              jbsp=1+(jb-1)*dtset%nspinor
    2142         [ +  + ]:         340 :              do iatom=1,natom
    2143                 :         260 :                itypat=dtset%typat(iatom)
    2144                 :         260 :                lmn_size=pawtab(itypat)%lmn_size
    2145                 :         260 :                lmncmax=atm(itypat)%lmn_size
    2146         [ +  + ]:        2620 :                do jlmn=1,lmn_size
    2147         [ +  + ]:       48140 :                  do ilmn=1,lmncmax
    2148         [ +  - ]:       45600 :                    if(dtset%nspinor==1) then
    2149                 :             :                      ic=ilmn !atm(itypat)%indlmn(5,ilmn)
    2150                 :             :                    else
    2151                 :       45600 :                      ic=atm(itypat)%indlmn(9,ilmn)
    2152                 :             :                    endif
    2153         [ +  + ]:       47880 :                    if (ic>0) then
    2154                 :       31920 :                      soc_ij => phisocphj(iatom)%value(:,:,:,jlmn,ilmn)
    2155                 :             :                      !Contribution from real part of <Psi^s_n|p_i>
    2156                 :       31920 :                      cpnm1=cprj_k(iatom,jbsp  )%cp(1,jlmn)
    2157                 :       31920 :                      cpnm2=cprj_k(iatom,jbsp+1)%cp(1,jlmn)
    2158         [ +  + ]:      127680 :                      do idir=1,3
    2159                 :             :                        psinablapsi_soc(1,idir,ic,iatom,my_jb)=psinablapsi_soc(1,idir,ic,iatom,my_jb) &
    2160                 :       95760 : &                             +soc_ij(1,1,idir)*cpnm1+soc_ij(1,2,idir)*cpnm2
    2161                 :             :                        psinablapsi_soc(2,idir,ic,iatom,my_jb)=psinablapsi_soc(2,idir,ic,iatom,my_jb) &
    2162                 :      127680 : &                             +soc_ij(2,1,idir)*cpnm1+soc_ij(2,2,idir)*cpnm2
    2163                 :             :                      end do
    2164                 :             :                      !Contribution from imaginary part of <Psi^s_n|p_i>
    2165                 :       31920 :                      cpnm1=cprj_k(iatom,jbsp  )%cp(2,jlmn)
    2166                 :       31920 :                      cpnm2=cprj_k(iatom,jbsp+1)%cp(2,jlmn)
    2167         [ +  + ]:      127680 :                      do idir=1,3
    2168                 :             :                        psinablapsi_soc(1,idir,ic,iatom,my_jb)=psinablapsi_soc(1,idir,ic,iatom,my_jb) &
    2169                 :       95760 : &                             +soc_ij(2,1,idir)*cpnm1+soc_ij(2,2,idir)*cpnm2
    2170                 :             :                        psinablapsi_soc(2,idir,ic,iatom,my_jb)=psinablapsi_soc(2,idir,ic,iatom,my_jb) &
    2171                 :      127680 : &                             -soc_ij(1,1,idir)*cpnm1-soc_ij(1,2,idir)*cpnm2
    2172                 :             :                      end do
    2173                 :             :                    end if
    2174                 :             :                  end do ! ilmn
    2175                 :             :                end do ! jlmn
    2176                 :             :              end do ! iatom
    2177                 :             :            end if ! use_spinorbit
    2178                 :             : 
    2179   [ +  -  -  + ]:         184 :            if (iomode_etsf_mpiio.and.mpi_enreg%paral_spinor==1) then
    2180                 :             : #if defined(HAVE_GPU_MARKERS)
    2181                 :             :              call nvtxStartRange("xmpi_sum",17)
    2182                 :             : #endif
    2183                 :           0 :              call timab(48,1,tsec)
    2184                 :           0 :              call xmpi_sum_master(psinablapsi,master,spaceComm_spinor,ierr)
    2185                 :           0 :              call timab(48,2,tsec)
    2186                 :             : #if defined(HAVE_GPU_MARKERS)
    2187                 :             :              call nvtxEndRange()
    2188                 :             : #endif
    2189                 :             :            end if
    2190                 :             : 
    2191                 :             :          end if ! myband
    2192                 :             : 
    2193                 :             : 
    2194                 :             : !        Write to OPT2 file in case of MPI-IO
    2195         [ +  + ]:         260 :          if (iomode_etsf_mpiio.and.i_am_master_spfft) then
    2196                 :             : #if defined(HAVE_GPU_MARKERS)
    2197                 :             :            call nvtxStartRange("write_mpiio")
    2198                 :             : #endif
    2199         [ +  + ]:        1288 :            nc_start=[1,1,1,jb,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    2200         [ +  + ]:         184 :            if (myband) then
    2201   [ +  +  -  +  :       18454 :              if (use_spinorbit) psinablapsi=psinablapsi+psinablapsi_soc
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    2202                 :             :              ! Take the square and sum over m
    2203         [ +  + ]:         582 :              do iatom=1,natom
    2204                 :         428 :                itypat=dtset%typat(iatom)
    2205                 :         428 :                lmncmax=atm(itypat)%lmn_size
    2206         [ +  + ]:         428 :                if(dtset%nspinor==2)lmncmax=lmncmax/2
    2207         [ +  + ]:        3366 :                do ilmn=1,lmncmax
    2208                 :        2784 :                   ic=lmn2ln(ilmn,itypat)
    2209                 :             :                   psinablapsi2(:,ic,iatom,my_jb)=psinablapsi2(:,ic,iatom,my_jb)+psinablapsi(1,:,ilmn,iatom,my_jb)**2+&
    2210         [ +  + ]:       11564 : &                                                psinablapsi(2,:,ilmn,iatom,my_jb)**2
    2211                 :             :                 enddo
    2212                 :             :              enddo
    2213         [ +  + ]:        1078 :              nc_count=[3,nphicor,natom,1,1,1]
    2214                 :             :            else
    2215                 :          30 :              nc_count=[0,0,0,0,0,0]
    2216                 :             :            end if
    2217         [ -  + ]:         184 :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    2218                 :             : #if defined(HAVE_GPU_MARKERS)
    2219                 :             :            call nvtxEndRange()
    2220                 :             : #endif
    2221                 :             :          end if
    2222                 :             : 
    2223                 :             :        end do ! jb
    2224                 :             : #if defined(HAVE_GPU_MARKERS)
    2225                 :             :        call nvtxEndRange()
    2226                 :             : #endif
    2227                 :             : 
    2228                 :             : #if defined(HAVE_GPU_MARKERS)
    2229                 :             :        call nvtxStartRange("pawcprj_free")
    2230                 :             : #endif
    2231         [ +  - ]:          16 :        if (mkmem/=0) then
    2232                 :          16 :          ibg = ibg +  my_nspinor*nband_cprj_k
    2233                 :             :        end if
    2234                 :             : 
    2235         [ +  + ]:          16 :        if (cprj_paral_band) then
    2236                 :           8 :          call pawcprj_free(cprj_k)
    2237         [ -  + ]:           8 :          ABI_FREE(cprj_k)
    2238                 :             :        end if
    2239         [ +  + ]:          16 :        if (mkmem*nsppol/=1) then
    2240                 :           4 :          call pawcprj_free(cprj_k_loc)
    2241         [ -  + ]:           4 :          ABI_FREE(cprj_k_loc)
    2242                 :             :        end if
    2243                 :             : #if defined(HAVE_GPU_MARKERS)
    2244                 :             :        call nvtxEndRange()
    2245                 :             : #endif
    2246                 :             : 
    2247                 :             : !      Write to OPT2 file if not MPI-IO
    2248                 :             : 
    2249                 :             : #if defined(HAVE_GPU_MARKERS)
    2250                 :             :        call nvtxStartRange("write")
    2251                 :             : #endif
    2252                 :             : !      >>> Reduction in case of parallelism
    2253         [ -  + ]:          16 :        if (.not.iomode_etsf_mpiio) then
    2254                 :           0 :          call timab(48,1,tsec)
    2255                 :           0 :          call xmpi_sum_master(psinablapsi,master,spaceComm_bandspinor,ierr)
    2256                 :           0 :          call timab(48,2,tsec)
    2257         [ #  # ]:           0 :          if (use_spinorbit) then
    2258                 :           0 :            call xmpi_sum_master(psinablapsi_soc,master,spaceComm_band,ierr)
    2259   [ #  #  #  #  :           0 :            psinablapsi=psinablapsi+psinablapsi_soc
          #  #  #  #  #  
                #  #  # ]
    2260                 :             :          end if
    2261                 :             :          ! Take the square and sum over m
    2262         [ #  # ]:           0 :          do jb=1,nband_k
    2263                 :           0 :            my_jb=merge(1,jb,iomode_etsf_mpiio)
    2264         [ #  # ]:           0 :            do iatom=1,natom
    2265                 :           0 :              itypat=dtset%typat(iatom)
    2266                 :           0 :              lmncmax=atm(itypat)%lmn_size
    2267         [ #  # ]:           0 :              if(dtset%nspinor==2)lmncmax=lmncmax/2
    2268         [ #  # ]:           0 :              do ilmn=1,lmncmax
    2269                 :           0 :                 ic=lmn2ln(ilmn,itypat)
    2270                 :             :                 psinablapsi2(:,ic,iatom,my_jb)=psinablapsi2(:,ic,iatom,my_jb)+psinablapsi(1,:,ilmn,iatom,my_jb)**2+&
    2271         [ #  # ]:           0 : &                                              psinablapsi(2,:,ilmn,iatom,my_jb)**2
    2272                 :             :               enddo
    2273                 :             :            enddo
    2274                 :             :          enddo
    2275                 :             :        end if
    2276                 :             : 
    2277                 :             : !      >>> This my kpt and I am the master node: I write the data
    2278                 :             :        if (.not.iomode_etsf_mpiio) then
    2279         [ #  # ]:           0 :          if (i_am_master) then
    2280         [ #  # ]:           0 :            if (iomode==IO_MODE_ETSF) then
    2281         [ #  # ]:           0 :              nc_start=[1,1,1,1,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    2282         [ #  # ]:           0 :              nc_count=[3,nphicor,natom,mband,1,1]
    2283         [ #  # ]:           0 :              NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    2284                 :             :            else
    2285         [ #  # ]:           0 :              if (fformopt==612) then ! New OPT2 file format
    2286                 :           0 :                write(ount) (((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    2287                 :           0 :                write(ount) (((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    2288                 :           0 :                write(ount) (((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    2289         [ #  # ]:           0 :              else if (fformopt==613) then ! Large OPT2 file format
    2290         [ #  # ]:           0 :                do jb=1,nband_k
    2291                 :           0 :                  write(ount) ((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    2292                 :           0 :                  write(ount) ((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    2293                 :           0 :                  write(ount) ((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    2294                 :             :                end do
    2295                 :             :              else ! Old OPT2 file format
    2296                 :             :                !The old writing was not efficient (indexes order is bad)
    2297         [ #  # ]:           0 :                do iatom=1,natom
    2298   [ #  #  #  # ]:           0 :                  write(ount) ((psinablapsi2(1,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    2299   [ #  #  #  # ]:           0 :                  write(ount) ((psinablapsi2(2,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    2300   [ #  #  #  # ]:           0 :                  write(ount) ((psinablapsi2(3,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    2301                 :             :                end do
    2302                 :             :              end if
    2303                 :             :            end if
    2304                 :             : 
    2305                 :             : !        >>> This my kpt and I am not the master node: I send the data
    2306         [ #  # ]:           0 :          else if (i_am_master_band.and.i_am_master_spfft) then
    2307         [ #  # ]:           0 :            if (mpi_enreg%me_kpt/=master_spfftband) then
    2308                 :           0 :              ABI_BUG('Problem with band communicator!')
    2309                 :             :            end if
    2310                 :           0 :            call xmpi_exch(psinablapsi2,pnp_size,mpi_enreg%me_kpt,psinablapsi2,master,spaceComm_kpt,etiq,ierr)
    2311                 :             :          end if
    2312                 :             :        end if
    2313                 :             : #if defined(HAVE_GPU_MARKERS)
    2314                 :             :        call nvtxEndRange()
    2315                 :             : #endif
    2316                 :             : 
    2317                 :             : !    >>> This is not my kpt and I am the master node: I receive the data and I write
    2318         [ #  # ]:           0 :      elseif ((.not.iomode_etsf_mpiio).and.i_am_master) then ! mykpt
    2319                 :           0 :        sender=master_spfftband
    2320                 :           0 :        call xmpi_exch(psinablapsi2,pnp_size,sender,psinablapsi2,master,spaceComm_kpt,etiq,ierr)
    2321         [ #  # ]:           0 :        if (iomode==IO_MODE_ETSF) then
    2322         [ #  # ]:           0 :          nc_start=[1,1,1,1,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    2323         [ #  # ]:           0 :          nc_count=[3,nphicor,natom,mband,1,1]
    2324         [ #  # ]:           0 :          NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    2325                 :             :        else
    2326         [ #  # ]:           0 :          if (fformopt==612) then ! New OPT2 file format
    2327                 :           0 :            write(ount) (((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    2328                 :           0 :            write(ount) (((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    2329                 :           0 :            write(ount) (((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    2330         [ #  # ]:           0 :          else if (fformopt==613) then ! Large OPT2 file format
    2331         [ #  # ]:           0 :            do jb=1,nband_k
    2332                 :           0 :              write(ount) ((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    2333                 :           0 :              write(ount) ((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    2334                 :           0 :              write(ount) ((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    2335                 :             :            end do
    2336                 :             :          else ! Old OPT2 file format
    2337                 :             :            !The old writing was not efficient (indexes order is bad)
    2338         [ #  # ]:           0 :            do iatom=1,natom
    2339   [ #  #  #  # ]:           0 :              write(ount) ((psinablapsi2(1,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    2340   [ #  #  #  # ]:           0 :              write(ount) ((psinablapsi2(2,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    2341   [ #  #  #  # ]:           0 :              write(ount) ((psinablapsi2(3,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    2342                 :             :            end do
    2343                 :             :          end if
    2344                 :             :        end if
    2345                 :             :      end if ! mykpt
    2346                 :             : 
    2347                 :          30 :      bdtot_index=bdtot_index+nband_k
    2348                 :             : 
    2349                 :             : !    End loop on spin,kpt
    2350                 :             : #if defined(HAVE_GPU_MARKERS)
    2351                 :             :      call nvtxEndRange()
    2352                 :             : #endif
    2353                 :             :    end do ! ikpt
    2354                 :             :  end do !isppol
    2355                 :             : 
    2356                 :             : !Close file
    2357   [ +  +  +  + ]:          14 :  if (i_am_master.or.(iomode_etsf_mpiio.and.i_am_master_spfft)) then
    2358         [ +  - ]:          10 :    if (iomode==IO_MODE_ETSF) then
    2359         [ -  + ]:          10 :      NCF_CHECK(nf90_close(ncid))
    2360                 :             :    else
    2361                 :           0 :      ierr=close_unit(ount,msg)
    2362         [ #  # ]:           0 :      ABI_CHECK(ierr==0,"Error while closing OPT2 file")
    2363                 :             :    end if
    2364                 :             :  end if
    2365                 :             : 
    2366                 :             : !Datastructures deallocations
    2367         [ +  + ]:          30 :  do itypat=1,dtset%ntypat
    2368                 :          30 :    call destroy_atomorb(atm(itypat))
    2369                 :             :  enddo
    2370   [ +  -  +  +  :          30 :  ABI_FREE(atm)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    2371         [ -  + ]:          14 :  ABI_FREE(psinablapsi)
    2372         [ -  + ]:          14 :  ABI_FREE(psinablapsi2)
    2373         [ -  + ]:          14 :  ABI_FREE(lmn2ln)
    2374         [ +  + ]:          14 :  if (use_spinorbit) then
    2375         [ -  + ]:           6 :    ABI_FREE(psinablapsi_soc)
    2376         [ +  + ]:          27 :    do iatom=1,natom
    2377         [ -  + ]:          27 :      ABI_FREE(phisocphj(iatom)%value)
    2378                 :             :    end do
    2379   [ +  -  +  +  :          27 :    ABI_FREE(phisocphj)
             -  +  -  + ]
    2380                 :             :  end if
    2381         [ +  - ]:          14 :  if (.not.already_has_nabla) then
    2382         [ +  + ]:          30 :    do itypat=1,dtset%ntypat
    2383         [ +  - ]:          16 :      if (allocated(pawtab(itypat)%nabla_ij)) then
    2384                 :          16 :        ABI_FREE(pawtab(itypat)%nabla_ij)
    2385                 :          16 :        pawtab(itypat)%has_nabla=0
    2386                 :             :      end if
    2387         [ +  + ]:          30 :      if (allocated(pawtab(itypat)%nabla_im_ij)) then
    2388                 :           6 :        ABI_FREE(pawtab(itypat)%nabla_im_ij)
    2389                 :             :      end if
    2390                 :             :    end do
    2391                 :             :  end if
    2392                 :             : 
    2393                 :             :  ABI_NVTX_END_RANGE()
    2394                 :          14 :  call timab(1185,2,tsec)
    2395                 :             :  DBG_EXIT("COLL")
    2396                 :             : 
    2397   [ -  +  -  +  :          28 :  end subroutine optics_paw_core
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    2398                 :             : !!***
    2399                 :             : 
    2400                 :             : !----------------------------------------------------------------------
    2401                 :             : 
    2402                 :             : !!****f* m_paw_optics/linear_optics_paw
    2403                 :             : !! NAME
    2404                 :             : !! linear_optics_paw
    2405                 :             : !!
    2406                 :             : !! FUNCTION
    2407                 :             : !! This program computes the elements of the optical frequency dependent
    2408                 :             : !! linear susceptiblity using matrix elements <-i Nabla> obtained from a
    2409                 :             : !! PAW ground state calculation. It uses formula 17 from Gadoc et al,
    2410                 :             : !! Phys. Rev. B 73, 045112 (2006) [[cite:Gajdo2006]] together with a scissors correction. It uses
    2411                 :             : !! a Kramers-Kronig transform to compute the real part from the imaginary part, and
    2412                 :             : !! it will work on all types of unit cells. It outputs all tensor elements of
    2413                 :             : !! both the real and imaginary parts.
    2414                 :             : !!
    2415                 :             : !! INPUTS
    2416                 :             : !!  filnam: base of file names to read data from
    2417                 :             : !!  mpi_enreg: mpi set up variable, not used in this code
    2418                 :             : !!
    2419                 :             : !! OUTPUT
    2420                 :             : !!  _real and _imag output files
    2421                 :             : !!
    2422                 :             : !! NOTES
    2423                 :             : !!  This routine is not tested
    2424                 :             : !!
    2425                 :             : !! SOURCE
    2426                 :             : 
    2427                 :           0 :  subroutine linear_optics_paw(filnam,filnam_out)
    2428                 :             : 
    2429                 :             : !Arguments -----------------------------------
    2430                 :             : !scalars
    2431                 :             :  character(len=fnlen),intent(in) :: filnam,filnam_out
    2432                 :             : 
    2433                 :             : !Local variables-------------------------------
    2434                 :             :  integer,parameter :: master=0
    2435                 :             :  integer :: iomode,bantot,bdtot_index,fform1,headform
    2436                 :             :  integer :: iband,ierr,ii,ikpt,iom,iout,isppol,isym,jband,jj,me,mband
    2437                 :             :  integer :: method,mom,nband_k,nkpt,nspinor,nsppol,nsym,occopt,only_check
    2438                 :             :  integer :: rdwr,spaceComm,inpunt,reunt,imunt,wfunt
    2439                 :           0 :  integer,allocatable :: nband(:),symrel(:,:,:)
    2440                 :             :  real(dp) :: del,dom,fij,gdelta,omin,omax,paijpbij(2),mbpt_sciss,wij,ucvol
    2441                 :             :  real(dp) :: diffwp, diffwm
    2442                 :             :  real(dp) :: e2rot(3,3),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3),rprimdinv(3,3),symd(3,3),symdinv(3,3)
    2443                 :           0 :  real(dp),allocatable :: e1(:,:,:),e2(:,:,:,:),epsilon_tot(:,:,:,:),eigen0(:),eig0_k(:)
    2444                 :           0 :  real(dp),allocatable :: kpts(:,:),occ(:),occ_k(:),oml1(:),wtk(:)
    2445                 :           0 :  complex(dp),allocatable :: eps_work(:)
    2446                 :             :  character(len=fnlen) :: filnam1,filnam_gen
    2447                 :             :  character(len=500) :: msg
    2448                 :           0 :  type(hdr_type) :: hdr
    2449                 :             :  type(wffile_type) :: wff1
    2450                 :             : !arrays
    2451                 :           0 :  real(dp),allocatable :: psinablapsi(:,:,:,:)
    2452                 :             : ! *********************************************************************************
    2453                 :             : 
    2454                 :             :  DBG_ENTER("COLL")
    2455                 :             :  ABI_NVTX_START_RANGE(NVTX_LINEAR_OPTICS_PAW)
    2456                 :             : 
    2457                 :             : !write(std_out,'(a)')' Give the name of the output file ...'
    2458                 :             : !read(std_in, '(a)') filnam_out
    2459                 :             : !write(std_out,'(a)')' The name of the output file is :',filnam_out
    2460                 :             : 
    2461                 :             : !Read data file
    2462         [ #  # ]:           0 :  if (open_file(filnam,msg,newunit=inpunt,form='formatted') /= 0 ) then
    2463                 :           0 :    ABI_ERROR(msg)
    2464                 :             :  end if
    2465                 :             : 
    2466                 :           0 :  rewind(inpunt)
    2467                 :           0 :  read(inpunt,*)
    2468                 :           0 :  read(inpunt,'(a)')filnam_gen       ! generic name for the files
    2469         [ #  # ]:           0 :  filnam1=trim(filnam_gen)//'_OPT' ! nabla matrix elements file
    2470                 :             : 
    2471                 :             : !Open the Wavefunction and optic files
    2472                 :             : !These default values are typical of sequential use
    2473                 :           0 :  iomode=IO_MODE_FORTRAN ; spaceComm=xmpi_comm_self; me=0
    2474                 :             : 
    2475                 :             : ! Read the header of the optic files
    2476                 :           0 :  call hdr%from_fname(filnam1, fform1, spaceComm)
    2477                 :           0 :  call hdr%free()
    2478         [ #  # ]:           0 :  if (fform1 /= 610) then
    2479                 :           0 :    ABI_ERROR("Abinit8 requires an OPT file with fform = 610")
    2480                 :             :  end if
    2481                 :             : 
    2482                 :             : !Open the conducti optic files
    2483                 :           0 :  wfunt = get_unit()
    2484                 :           0 :  call WffOpen(iomode,spaceComm,filnam1,ierr,wff1,master,me,wfunt)
    2485                 :             : 
    2486                 :             : !Read the header from Ground state file
    2487                 :           0 :  rdwr=1
    2488                 :           0 :  call hdr_io(fform1,hdr,rdwr,wff1)
    2489                 :             : 
    2490                 :             : !Extract info from the header
    2491                 :           0 :  headform=hdr%headform
    2492                 :           0 :  bantot=hdr%bantot
    2493                 :           0 :  nkpt=hdr%nkpt
    2494   [ #  #  #  #  :           0 :  ABI_MALLOC(kpts,(3,nkpt))
          #  #  #  #  #  
                #  #  # ]
    2495   [ #  #  #  #  :           0 :  ABI_MALLOC(wtk,(nkpt))
          #  #  #  #  #  
                #  #  # ]
    2496   [ #  #  #  # ]:           0 :  kpts(:,:)=hdr%kptns(:,:)
    2497         [ #  # ]:           0 :  wtk(:)=hdr%wtk(:)
    2498                 :           0 :  nspinor=hdr%nspinor
    2499                 :           0 :  nsppol=hdr%nsppol
    2500                 :           0 :  occopt=hdr%occopt
    2501   [ #  #  #  # ]:           0 :  rprimd(:,:)=hdr%rprimd(:,:)
    2502                 :           0 :  rprimdinv(:,:) = rprimd(:,:)
    2503                 :           0 :  call matrginv(rprimdinv,3,3) ! need the inverse of rprimd to symmetrize the tensors
    2504   [ #  #  #  #  :           0 :  ABI_MALLOC(nband,(nkpt*nsppol))
          #  #  #  #  #  
                #  #  # ]
    2505   [ #  #  #  #  :           0 :  ABI_MALLOC(occ,(bantot))
          #  #  #  #  #  
                #  #  # ]
    2506         [ #  # ]:           0 :  occ(1:bantot)=hdr%occ(1:bantot)
    2507         [ #  # ]:           0 :  nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol)
    2508                 :           0 :  nsym=hdr%nsym
    2509   [ #  #  #  #  :           0 :  ABI_MALLOC(symrel,(3,3,nsym))
          #  #  #  #  #  
                #  #  # ]
    2510   [ #  #  #  #  :           0 :  symrel(:,:,:)=hdr%symrel(:,:,:)
                   #  # ]
    2511                 :             : 
    2512                 :             : !Get mband, as the maximum value of nband(nkpt)
    2513         [ #  # ]:           0 :  mband=maxval(nband(:))
    2514                 :             : 
    2515                 :             : !get ucvol etc.
    2516                 :           0 :  iout = -1
    2517                 :           0 :  call metric(gmet,gprimd,iout,rmet,rprimd,ucvol)
    2518                 :             : 
    2519                 :           0 :  write(std_out,*)
    2520                 :           0 :  write(std_out,'(a,3f10.5,a)' )' rprimd(bohr)      =',rprimd(1:3,1)
    2521                 :           0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,2)
    2522                 :           0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,3)
    2523                 :           0 :  write(std_out,*)
    2524                 :           0 :  write(std_out,'(a,3f10.5,a)' )' rprimdinv         =',rprimdinv(1:3,1)
    2525                 :           0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimdinv(1:3,2)
    2526                 :           0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimdinv(1:3,3)
    2527                 :           0 :  write(std_out,'(a,2i8)')      ' nkpt,mband        =',nkpt,mband
    2528                 :             : 
    2529                 :             : !get eigen0
    2530   [ #  #  #  #  :           0 :  ABI_MALLOC(eigen0,(mband*nkpt*nsppol))
          #  #  #  #  #  
                #  #  # ]
    2531                 :           0 :  read(wfunt)(eigen0(iband),iband=1,mband*nkpt*nsppol)
    2532                 :             : 
    2533                 :           0 :  read(inpunt,*)mbpt_sciss
    2534                 :           0 :  read(inpunt,*)dom,omin,omax,mom
    2535                 :           0 :  close(inpunt)
    2536                 :             : 
    2537   [ #  #  #  #  :           0 :  ABI_MALLOC(oml1,(mom))
          #  #  #  #  #  
                #  #  # ]
    2538   [ #  #  #  #  :           0 :  ABI_MALLOC(e1,(3,3,mom))
          #  #  #  #  #  
                #  #  # ]
    2539   [ #  #  #  #  :           0 :  ABI_MALLOC(e2,(2,3,3,mom))
          #  #  #  #  #  
                #  #  # ]
    2540   [ #  #  #  #  :           0 :  ABI_MALLOC(epsilon_tot,(2,3,3,mom))
             #  #  #  # ]
    2541   [ #  #  #  #  :           0 :  ABI_MALLOC(eps_work,(mom))
          #  #  #  #  #  
                #  #  # ]
    2542                 :           0 :  del=(omax-omin)/(mom-1)
    2543         [ #  # ]:           0 :  do iom=1,mom
    2544                 :           0 :    oml1(iom)=omin+dble(iom-1)*del
    2545                 :             :  end do
    2546                 :           0 :  write(std_out,'(a,i8,4f10.5,a)')' npts,omin,omax,width,mbpt_sciss      =',mom,omin,omax,dom,mbpt_sciss,' Ha'
    2547                 :             : 
    2548   [ #  #  #  #  :           0 :  ABI_MALLOC(psinablapsi,(2,3,mband,mband))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2549                 :             : 
    2550                 :             : !loop over spin components
    2551         [ #  # ]:           0 :  do isppol=1,nsppol
    2552                 :             :    bdtot_index = 0
    2553                 :             : !  loop over k points
    2554         [ #  # ]:           0 :    do ikpt=1,nkpt
    2555                 :             : !
    2556                 :             : !    number of bands for this k point
    2557                 :           0 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
    2558   [ #  #  #  #  :           0 :      ABI_MALLOC(eig0_k,(nband_k))
          #  #  #  #  #  
                #  #  # ]
    2559   [ #  #  #  #  :           0 :      ABI_MALLOC(occ_k,(nband_k))
             #  #  #  # ]
    2560                 :             : !    eigenvalues for this k-point
    2561         [ #  # ]:           0 :      eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
    2562                 :             : !    occupation numbers for this k-point
    2563         [ #  # ]:           0 :      occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
    2564                 :             : !    values of -i*nabla matrix elements for this k point
    2565   [ #  #  #  #  :           0 :      psinablapsi=zero
             #  #  #  # ]
    2566   [ #  #  #  #  :           0 :      read(wfunt)((psinablapsi(1:2,1,iband,jband),iband=1,nband_k),jband=1,nband_k)
             #  #  #  # ]
    2567   [ #  #  #  #  :           0 :      read(wfunt)((psinablapsi(1:2,2,iband,jband),iband=1,nband_k),jband=1,nband_k)
             #  #  #  # ]
    2568   [ #  #  #  #  :           0 :      read(wfunt)((psinablapsi(1:2,3,iband,jband),iband=1,nband_k),jband=1,nband_k)
             #  #  #  # ]
    2569                 :             : 
    2570                 :             : !    occupation numbers for k-point
    2571         [ #  # ]:           0 :      occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
    2572                 :             : !    accumulate e2 for this k point, Eq. 17 from PRB 73, 045112 (2006) [[cite:Gajdo2006]]
    2573         [ #  # ]:           0 :      do iband = 1, nband_k
    2574         [ #  # ]:           0 :        do jband = 1, nband_k
    2575                 :           0 :          fij = occ_k(iband) - occ_k(jband) !occ number difference
    2576                 :           0 :          wij = eig0_k(iband) - eig0_k(jband) !energy difference
    2577         [ #  # ]:           0 :          if (abs(fij) > zero) then ! only consider states of differing occupation numbers
    2578         [ #  # ]:           0 :            do ii = 1, 3
    2579         [ #  # ]:           0 :              do jj = 1, 3
    2580                 :             :                paijpbij(1) = psinablapsi(1,ii,iband,jband)*psinablapsi(1,jj,iband,jband) + &
    2581                 :           0 : &               psinablapsi(2,ii,iband,jband)*psinablapsi(2,jj,iband,jband)
    2582                 :             :                paijpbij(2) = psinablapsi(2,ii,iband,jband)*psinablapsi(1,jj,iband,jband) - &
    2583                 :           0 : &               psinablapsi(1,ii,iband,jband)*psinablapsi(2,jj,iband,jband)
    2584         [ #  # ]:           0 :                do iom = 1, mom
    2585                 :             : !                original version
    2586                 :             : !                diffw = wij + mbpt_sciss - oml1(iom) ! apply scissors term here
    2587                 :             : !                gdelta = exp(-diffw*diffw/(4.0*dom*dom))/(2.0*dom*sqrt(pi)) ! delta fnc resolved as Gaussian
    2588                 :             : !                e2(1,ii,jj,iom) = e2(1,ii,jj,iom) - (4.0*pi*pi/ucvol)*wtk(ikpt)*fij*paijpbij(1)*gdelta/(oml1(iom)*oml1(iom))
    2589                 :             : !                e2(2,ii,jj,iom) = e2(2,ii,jj,iom) - (4.0*pi*pi/ucvol)*wtk(ikpt)*fij*paijpbij(2)*gdelta/(oml1(iom)*oml1(iom))
    2590                 :           0 :                  diffwm = wij - mbpt_sciss + oml1(iom) ! apply scissors term here
    2591                 :           0 :                  diffwp = wij + mbpt_sciss - oml1(iom) ! apply scissors term here
    2592                 :           0 :                  gdelta = exp(-diffwp*diffwp/(4.0*dom*dom))/(2.0*dom*sqrt(pi))
    2593                 :           0 :                  e2(1,ii,jj,iom) = e2(1,ii,jj,iom) - (4.0*pi*pi/ucvol)*wtk(ikpt)*fij*paijpbij(1)*gdelta/(wij*wij)
    2594                 :           0 :                  e2(2,ii,jj,iom) = e2(2,ii,jj,iom) - (4.0*pi*pi/ucvol)*wtk(ikpt)*fij*paijpbij(2)*gdelta/(wij*wij)
    2595                 :             :                end do ! end loop over spectral points
    2596                 :             :              end do ! end loop over jj = 1, 3
    2597                 :             :            end do ! end loop over ii = 1, 3
    2598                 :             :          end if ! end selection on fij /= 0
    2599                 :             :        end do ! end loop over jband
    2600                 :             :      end do ! end loop over iband
    2601                 :             : 
    2602         [ #  # ]:           0 :      ABI_FREE(eig0_k)
    2603         [ #  # ]:           0 :      ABI_FREE(occ_k)
    2604                 :           0 :      bdtot_index=bdtot_index+nband_k
    2605                 :             :    end do ! end loop over k points
    2606                 :             :  end do ! end loop over spin polarizations
    2607                 :             : 
    2608                 :             : !here apply nsym symrel transformations to reconstruct full tensor from IBZ part
    2609   [ #  #  #  #  :           0 :  epsilon_tot(:,:,:,:) = zero
             #  #  #  # ]
    2610         [ #  # ]:           0 :  do isym = 1, nsym
    2611   [ #  #  #  #  :           0 :    symd(:,:)=matmul(rprimd(:,:),matmul(symrel(:,:,isym),rprimdinv(:,:)))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2612                 :           0 :    symdinv(:,:)=symd(:,:)
    2613                 :           0 :    call matrginv(symdinv,3,3)
    2614         [ #  # ]:           0 :    do iom = 1, mom
    2615   [ #  #  #  #  :           0 :      e2rot(:,:)=matmul(symdinv(:,:),matmul(e2(1,:,:,iom),symd(:,:)))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2616   [ #  #  #  # ]:           0 :      epsilon_tot(2,:,:,iom) = epsilon_tot(2,:,:,iom)+e2rot(:,:)/nsym
    2617                 :             :    end do
    2618                 :             :  end do
    2619                 :             : 
    2620                 :             : !generate e1 from e2 via KK transforma
    2621                 :           0 :  method=0 ! use naive integration ( = 1 for simpson)
    2622                 :           0 :  only_check=0 ! compute real part of eps in kk routine
    2623         [ #  # ]:           0 :  do ii = 1, 3
    2624         [ #  # ]:           0 :    do jj = 1, 3
    2625         [ #  # ]:           0 :      eps_work(:) = cmplx(0.0,epsilon_tot(2,ii,jj,:), kind=dp)
    2626                 :           0 :      call kramerskronig(mom,oml1,eps_work,method,only_check)
    2627         [ #  # ]:           0 :      epsilon_tot(1,ii,jj,:) = real(eps_work(:))
    2628   [ #  #  #  # ]:           0 :      if (ii /= jj) epsilon_tot(1,ii,jj,:) = epsilon_tot(1,ii,jj,:)- 1.0
    2629                 :             :    end do ! end loop over jj
    2630                 :             :  end do ! end loop over ii
    2631                 :             : 
    2632         [ #  # ]:           0 :  if (open_file(trim(filnam_out)//'_imag',msg,newunit=reunt,form='formatted') /= 0) then
    2633                 :           0 :    ABI_ERROR(msg)
    2634                 :             :  end if
    2635                 :             : 
    2636         [ #  # ]:           0 :  if (open_file(trim(filnam_out)//'_real',msg,unit=imunt,form='formatted') /= 0) then
    2637                 :           0 :    ABI_ERROR(msg)
    2638                 :             :  end if
    2639                 :             : 
    2640                 :           0 :  write(reunt,'(a12,6a13)')' # Energy/Ha ','eps_2_xx','eps_2_yy','eps_2_zz',&
    2641                 :           0 : & 'eps_2_yz','eps_2_xz','eps_2_xy'
    2642                 :           0 :  write(imunt,'(a12,6a13)')' # Energy/Ha ','eps_1_xx','eps_1_yy','eps_1_zz',&
    2643                 :           0 : & 'eps_1_yz','eps_1_xz','eps_1_xy'
    2644                 :             : 
    2645         [ #  # ]:           0 :  do iom = 1, mom
    2646                 :           0 :    write(reunt,'(ES12.4,a,ES12.4,a,ES12.4,a,ES12.4,a,ES12.4,a,ES12.4,a,ES12.4)') oml1(iom),' ',&
    2647                 :           0 : &   epsilon_tot(2,1,1,iom),' ',epsilon_tot(2,2,2,iom),' ',epsilon_tot(2,3,3,iom),' ',&
    2648                 :           0 : &   epsilon_tot(2,2,3,iom),' ',epsilon_tot(2,1,3,iom),' ',epsilon_tot(2,1,2,iom)
    2649                 :           0 :    write(imunt,'(ES12.4,a,ES12.4,a,ES12.4,a,ES12.4,a,ES12.4,a,ES12.4,a,ES12.4)') oml1(iom),' ',&
    2650                 :           0 : &   epsilon_tot(1,1,1,iom),' ',epsilon_tot(1,2,2,iom),' ',epsilon_tot(1,3,3,iom),' ',&
    2651                 :           0 : &   epsilon_tot(1,2,3,iom),' ',epsilon_tot(1,1,3,iom),' ',epsilon_tot(1,1,2,iom)
    2652                 :             :  end do
    2653                 :             : 
    2654                 :           0 :  close(reunt)
    2655                 :           0 :  close(imunt)
    2656                 :             : 
    2657         [ #  # ]:           0 :  ABI_FREE(nband)
    2658         [ #  # ]:           0 :  ABI_FREE(oml1)
    2659         [ #  # ]:           0 :  ABI_FREE(e2)
    2660         [ #  # ]:           0 :  ABI_FREE(e1)
    2661         [ #  # ]:           0 :  ABI_FREE(occ)
    2662         [ #  # ]:           0 :  ABI_FREE(psinablapsi)
    2663         [ #  # ]:           0 :  ABI_FREE(eigen0)
    2664         [ #  # ]:           0 :  ABI_FREE(wtk)
    2665         [ #  # ]:           0 :  ABI_FREE(kpts)
    2666                 :             : 
    2667                 :           0 :  call hdr%free()
    2668                 :             : 
    2669                 :             :  ABI_NVTX_END_RANGE()
    2670                 :             :  DBG_EXIT("COLL")
    2671                 :             : 
    2672   [ #  #  #  #  :           0 :  end subroutine linear_optics_paw
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    2673                 :             : !!***
    2674                 :             : 
    2675                 :             : !----------------------------------------------------------------------
    2676                 :             : 
    2677                 :             : !!****f* m_paw_optics/pawnabla_soc_init
    2678                 :             : !! NAME
    2679                 :             : !! pawnabla_soc_init
    2680                 :             : !!
    2681                 :             : !! FUNCTION
    2682                 :             : !! Compute the PAW SOC contribution(s) to the momentum PAW matrix elements,
    2683                 :             : !!  i.e. <Phi_i|1/4 Alpha^2 dV/dr (Sigma X vec(r)/r) |Phi_j>
    2684                 :             : !!   where:
    2685                 :             : !!    {Phi_i}= AE partial waves
    2686                 :             : !!    Alpha = inverse of fine structure constant
    2687                 :             : !!    Sigma^alpha,beta= Pauli matrices
    2688                 :             : !!    X = cross product
    2689                 :             : !!
    2690                 :             : !! There are 2 typical uses:
    2691                 :             : !!   - Valence-valence terms: Phi_i and Phi_j are PAW AE partial waves (unpolarized)
    2692                 :             : !!   - Core-valence terms: Phi_i is are AE partial waves and Phi_j are core AE wave-functions (spinors)
    2693                 :             : !!
    2694                 :             : !! In practice we compute:
    2695                 :             : !!  (Sigma^up-up X g_ij) and (Sigma^up-dn X g_ij)    (X = vector cross product)
    2696                 :             : !!  (Sigma^dn-up X g_ij) and (Sigma^dn-dn X g_ij)
    2697                 :             : !!   where:
    2698                 :             : !!    g_ij= 1/4 Alpha^2 Int_[Phi_i(r)/r Phi_j(r)/r dV(r)/dr r^2 dr] . Gvec_ij
    2699                 :             : !!        and Gvec_ij= Int[S_limi S_ljmj vec(r)/r dOmega] (Gaunt coefficients)
    2700                 :             : !!
    2701                 :             : !! COPYRIGHT
    2702                 :             : !! Copyright (C) 2021-2026 ABINIT group (NBrouwer,MT)
    2703                 :             : !! This file is distributed under the terms of the
    2704                 :             : !! GNU General Public License, see ~ABINIT/COPYING
    2705                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2706                 :             : !!
    2707                 :             : !! INPUTS
    2708                 :             : !!  el_temp=electronic temperature (hartree)
    2709                 :             : !!  ixc= choice of exchange-correlation scheme (see above, and below)
    2710                 :             : !!  my_natom=number of atoms treated by current processor
    2711                 :             : !!  natom=total number of atoms in cell
    2712                 :             : !!  nspden=number of spin-density components
    2713                 :             : !!  ntypat=number of types of atoms in unit cell.
    2714                 :             : !!  option_core=Type of calculation: 0=valence-valence, 1=core-valence
    2715                 :             : !!  pawang <type(pawang_type)>=paw angular mesh and related data
    2716                 :             : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
    2717                 :             : !!  pawrhoij(my_natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data
    2718                 :             : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
    2719                 :             : !!  pawxcdev=Choice of XC development (0=no dev. (use of angular mesh) ; 1 or 2=dev. on moments)
    2720                 :             : !!  spnorbscl=scaling factor for spin-orbit coupling
    2721                 :             : !!  typat(natom) =Type of each atoms
    2722                 :             : !!  xc_denpos= lowest allowed density (usually for the computation of the XC functionals)
    2723                 :             : !!  xc_taupos= lowest allowed kinetic energy density (for mGGA XC functionals)
    2724                 :             : !!  znucl(ntypat)=gives the nuclear charge for all types of atoms
    2725                 :             : !!  [atm <type(paw_atomorb_type)>]=--optional-- structure containing core info
    2726                 :             : !!  [mpi_atmtab(:)]=--optional-- indexes of the atoms treated by current proc
    2727                 :             : !!  [comm_atom]=--optional-- MPI communicator over atoms
    2728                 :             : !!
    2729                 :             : !! OUTPUT
    2730                 :             : !    phisocphj(dtset%natom) <type(coeff4_type)>= stores soc coefficients:
    2731                 :             : !!!  If  option_core==0 or nspinor_cor==1:
    2732                 :             : !!     phisocphj(iat)%value(1,1,idir,ilmn,jlmn) is real part of (Sigma^up-up X g_ij)
    2733                 :             : !!     phisocphj(iat)%value(2,1,idir,ilmn,jlmn) is imaginary part of (Sigma^up-up X g_ij)
    2734                 :             : !!     phisocphj(iat)%value(1,2,idir,ilmn,jlmn) is real part of (Sigma^up-dn X g_ij)
    2735                 :             : !!     phisocphj(iat)%value(2,2,idir,ilmn,jlmn) is imaginary part of (Sigma^up-dn X g_ij)
    2736                 :             : !!   If option_core==1 and nspinor_cor==2 (core-valence with spinorial core WF):
    2737                 :             : !!     phisocphj(iat)%value(1,1,idir,ilmn,2*jlmn-1) is real part of (Sigma^up-up X g_ij^up)
    2738                 :             : !!     phisocphj(iat)%value(2,1,idir,ilmn,2*jlmn-1) is imaginary part of (Sigma^up-up X g_ij^up)
    2739                 :             : !!     phisocphj(iat)%value(1,2,idir,ilmn,2*jlmn-1) is real part of (Sigma^dn-up X g_ij^dn)
    2740                 :             : !!     phisocphj(iat)%value(2,2,idir,ilmn,2*jlmn-1) is imaginary part of (Sigma^dn-up X g_ij^dn)
    2741                 :             : !!     phisocphj(iat)%value(1,1,idir,ilmn,2*jlmn  ) is real part of (Sigma^up-dn X g_ij^up)
    2742                 :             : !!     phisocphj(iat)%value(2,1,idir,ilmn,2*jlmn  ) is imaginary part of (Sigma^up-dn X g_ij^up)
    2743                 :             : !!     phisocphj(iat)%value(1,2,idir,ilmn,2*jlmn  ) is real part of (Sigma^dn-dn X g_ij^dn)
    2744                 :             : !!     phisocphj(iat)%value(2,2,idir,ilmn,2*jlmn  ) is imaginary part of (Sigma^dn-dn X g_ij^dn)
    2745                 :             : !! (idir=cartesian direction)
    2746                 :             : !!
    2747                 :             : !! SIDE EFFECTS
    2748                 :             : !!
    2749                 :             : !! NOTES
    2750                 :             : !! If Phi_j is not polarized,
    2751                 :             : !!    (Sigma^dn-dn X g_ij)=-(Sigma^up-up X g_ij)
    2752                 :             : !!    (Sigma^dn-up X g_ij)= (Sigma^up-dn X g_ij)^*
    2753                 :             : !!    So, we store only 2 components.
    2754                 :             : !! If Phi_j is polarized, the spin component is included in the last dimension of
    2755                 :             : !!   phisocphj(iat)%value, i.e. lmn_size_cor=2*lmn_size
    2756                 :             : !!
    2757                 :             : !! SOURCE
    2758                 :             : 
    2759                 :          11 :  subroutine pawnabla_soc_init(el_temp,phisocphj,option_core,ixc,my_natom,natom,nspden,ntypat,pawang, &
    2760                 :          22 : &           pawrad,pawrhoij,pawtab,pawxcdev,spnorbscl,typat,xc_denpos,xc_taupos,znucl, &
    2761   [ +  -  +  +  :          11 : &           atm,mpi_atmtab,comm_atom) ! Optional arguments
                   -  + ]
    2762                 :             : 
    2763                 :             : !Arguments ------------------------------------
    2764                 :             : !scalars
    2765                 :             :  integer,intent(in) :: ixc,my_natom,natom,nspden,ntypat,option_core,pawxcdev
    2766                 :             :  integer,optional,intent(in) :: comm_atom
    2767                 :             :  real(dp),intent(in) :: el_temp,spnorbscl,xc_denpos,xc_taupos
    2768                 :             :  type(pawang_type),intent(in) :: pawang
    2769                 :             : !arrays
    2770                 :             :  integer,intent(in) :: typat(natom)
    2771                 :             :  integer,optional,target,intent(in) :: mpi_atmtab(:)
    2772                 :             :  real(dp),intent(in) :: znucl(ntypat)
    2773                 :             :  type(coeff5_type),allocatable,target,intent(inout) :: phisocphj(:)
    2774                 :             :  type(pawrad_type),target,intent(in) :: pawrad(ntypat)
    2775                 :             :  type(pawrhoij_type),intent(inout) :: pawrhoij(my_natom)
    2776                 :             :  type(pawtab_type),target,intent(in) :: pawtab(ntypat)
    2777                 :             :  type(atomorb_type), intent(in), target, optional :: atm(ntypat)
    2778                 :             : 
    2779                 :             : !Local variables-------------------------------
    2780                 :             : !scalars
    2781                 :             :  real(dp),parameter :: one_over_fourpi   = one/sqrt(four_pi)
    2782                 :             :  real(dp),parameter :: sqr_fourpi_over_3 = sqrt(four_pi/3)
    2783                 :             :  real(dp),parameter :: QuarterFineStruct2=(half/InvFineStruct)**2
    2784                 :             :  real(dp),parameter :: hyb_mixing_ = 0.0_dp   ! Fake value to be updated in the future
    2785                 :             :  integer :: iatom,iatom_tot,itypat,ii,jj,ierr,ipts,ignt,sgnkappa
    2786                 :             :  integer :: idum,option,usenhat,usekden,usecore,xclevel,nkxc,my_comm_atom
    2787                 :             :  integer :: mesh_size,lmn_size,lmn2_size,lmn_size_j,lmn_size_cor
    2788                 :             :  integer :: lm_size,ln_size,ln_size_j
    2789                 :             :  integer :: ilmn,ilm,iln,jl,jm,jm_re,jm_im,jlmn,jlm,jlm_re,jlm_im,jln,js,klm_re,klm_im
    2790                 :             :  logical :: my_atmtab_allocated,paral_atom
    2791                 :             :  real(dp) :: avg,cgc,compch_sph_dum,eexc_dum,ssxc_dum,eexcdc_dum,jmj
    2792                 :             :  real(dp) :: fact_re,fact_im,gx_re,gx_im,gy_re,gy_im,gz_re,gz_im,if3
    2793                 :             :  character(len=500) :: msg
    2794                 :             : !arrays
    2795                 :          11 :  integer,pointer :: my_atmtab(:),indlmn(:,:),indlmn_j(:,:)
    2796                 :          11 :  logical,allocatable :: lmselect(:)
    2797                 :             :  real(dp) :: nhat_dum(1,1,1),trho_dum(1,1,1),kxc_dum(1,1,1),k3xc_dum(1,1,1)
    2798                 :          11 :  real(dp),allocatable :: rho1(:,:,:),tau1(:,:,:),rhosph(:),vhartree(:),vxc(:,:,:)
    2799                 :          11 :  real(dp),allocatable :: intf3(:,:),potsph(:),dVdr(:),func(:)
    2800                 :          11 :  real(dp),pointer :: phi_j(:,:),soc_ij(:,:,:,:,:)
    2801                 :             :  type(pawrad_type),pointer :: pawrd
    2802                 :             :  type(pawtab_type),pointer :: pawtb
    2803                 :             : 
    2804                 :             : ! ************************************************************************
    2805                 :             :  ABI_NVTX_START_RANGE(NVTX_PAWNABLA_SOC_INIT)
    2806                 :             : 
    2807                 :             : !Some checks in case of core-valence (option_core=1)
    2808                 :          11 :  if (option_core/=0.and.option_core/=1) then
    2809                 :           0 :    msg='Wrong option_core value!'
    2810                 :           0 :    ABI_BUG(msg)
    2811                 :             :  end if
    2812         [ +  + ]:          11 :  if (option_core==1) then
    2813                 :             : !  Check if we have the optional arguments
    2814         [ -  + ]:           6 :    if (.not.present(atm)) then
    2815                 :           0 :      msg='For core-valence calculation, need atm data!'
    2816                 :           0 :      ABI_BUG(msg)
    2817                 :             :    end if
    2818         [ +  + ]:          12 :    do itypat=1,ntypat
    2819                 :             : !  Check if we have relativistic core wave functions
    2820         [ -  + ]:          12 :      if (size(atm(itypat)%indlmn,1)<8) then
    2821                 :           0 :        write(msg,'(a)') 'Wrong 1st dim. of indlmn_cor in pawnabla_soc_init (need spinors)!'
    2822                 :           0 :        ABI_BUG(msg)
    2823                 :             :      end if
    2824                 :             :    enddo
    2825                 :             :  endif
    2826                 :             : 
    2827                 :             : !Some useful variables
    2828                 :          11 :  usekden=pawxc_get_usekden(ixc)
    2829                 :          11 :  usecore=1 ; nkxc=0 ; usenhat=0
    2830                 :          11 :  xclevel=pawxc_get_xclevel(ixc)
    2831         [ +  + ]:          11 :  if (option_core==1) then
    2832                 :             :    lmn_size_cor=0
    2833         [ +  + ]:          12 :    do itypat=1,ntypat
    2834                 :          12 :      lmn_size_cor=max(lmn_size_cor,atm(itypat)%lmn_size) !Includes spinors
    2835                 :             :    enddo
    2836                 :             :  end if
    2837                 :             : 
    2838                 :             : !Prepare output arrays
    2839         [ -  + ]:          11 :  if (allocated(phisocphj)) then
    2840         [ #  # ]:           0 :    do iatom=1,natom
    2841         [ #  # ]:           0 :       if (allocated(phisocphj(iatom)%value)) then
    2842                 :           0 :         ABI_FREE(phisocphj(iatom)%value)
    2843                 :             :       end if
    2844                 :             :    end do
    2845   [ #  #  #  #  :           0 :    ABI_FREE(phisocphj)
             #  #  #  # ]
    2846                 :             :  end if
    2847   [ -  +  +  -  :          74 :  ABI_MALLOC(phisocphj,(natom))
          +  -  +  -  -  
          +  -  +  -  +  
                   +  + ]
    2848         [ +  + ]:          52 :  do iatom=1,natom
    2849                 :          41 :    lmn_size=pawtab(typat(iatom))%lmn_size
    2850         [ +  + ]:          41 :    if (option_core==0) then
    2851   [ -  +  +  -  :          80 :      ABI_MALLOC(phisocphj(iatom)%value,(2,2,3,lmn_size,lmn_size))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    2852                 :             :    else
    2853                 :             :      !lmn_size_cor is double because it contains the spin component
    2854   [ -  +  +  -  :          84 :      ABI_MALLOC(phisocphj(iatom)%value,(2,2,3,lmn_size,lmn_size_cor))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    2855                 :             :    end if
    2856   [ +  +  +  +  :      107112 :    phisocphj(iatom)%value=zero
          +  +  +  +  +  
                      + ]
    2857                 :             :  end do
    2858                 :             : 
    2859                 :             : !Set up parallelism over atoms
    2860   [ +  -  +  + ]:          11 :  paral_atom=(present(comm_atom).and.(my_natom/=natom))
    2861         [ +  + ]:          11 :  nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
    2862         [ +  - ]:          11 :  my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
    2863                 :             :  call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,&
    2864                 :          11 : &                   my_natom_ref=my_natom)
    2865                 :             : 
    2866                 :             : !-------------------------------------------------------------------
    2867                 :             : !Loop over atoms
    2868                 :             : 
    2869         [ +  + ]:          36 :  do iatom=1,my_natom
    2870                 :             : 
    2871                 :             : !  Atom-dependent data
    2872                 :          25 :    itypat=typat(iatom)
    2873                 :          25 :    pawrd => pawrad(itypat)
    2874                 :          25 :    pawtb  => pawtab(itypat)
    2875                 :          25 :    lmn_size=pawtb%lmn_size
    2876                 :          25 :    lmn2_size=pawtb%lmn2_size
    2877                 :          25 :    lm_size=pawtb%lcut_size**2
    2878                 :          25 :    ln_size=pawtb%basis_size
    2879                 :          25 :    mesh_size=pawtb%mesh_size
    2880                 :          25 :    indlmn => pawtb%indlmn
    2881   [ -  +  +  -  :          75 :    ABI_MALLOC(lmselect,(lm_size))
          +  -  +  -  -  
                +  -  + ]
    2882         [ +  + ]:         266 :    lmselect(:)=.true.
    2883                 :             : 
    2884                 :             : !  Distinguish valence-valence and core-valence cases
    2885         [ +  + ]:          25 :    if (option_core==0) then
    2886                 :          12 :      ln_size_j=ln_size
    2887                 :          12 :      lmn_size_j=lmn_size
    2888                 :          12 :      indlmn_j => pawtb%indlmn
    2889                 :          12 :      phi_j => pawtb%phi
    2890                 :             :    else
    2891                 :          13 :      ln_size_j=atm(itypat)%ln_size
    2892                 :          13 :      lmn_size_j=atm(itypat)%lmn_size
    2893                 :          13 :      indlmn_j => atm(itypat)%indlmn
    2894                 :          13 :      phi_j => atm(itypat)%phi(:,:,1)
    2895         [ +  - ]:          13 :      if (atm(itypat)%mesh_size<mesh_size) then
    2896                 :           0 :        msg='mesh_size and mesh_size_cor not compatible!'
    2897                 :           0 :        ABI_BUG(msg)
    2898                 :             :      end if
    2899                 :             :    endif
    2900                 :             : 
    2901                 :             : !  Manage parallelism
    2902         [ +  + ]:          25 :    iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom)
    2903                 :          25 :    soc_ij => phisocphj(iatom_tot)%value(:,:,:,:,:)
    2904                 :             : 
    2905                 :             : !-------------------------------------------------------------------
    2906                 :             : !Compute all-electron density
    2907                 :             : 
    2908   [ -  +  +  -  :         125 :    ABI_MALLOC(rho1,(mesh_size,lm_size,nspden))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    2909   [ +  +  +  +  :      307265 :    option=2 ; rho1=zero
                   +  + ]
    2910                 :             :    call pawdensities(compch_sph_dum,1,iatom_tot,lmselect,lmselect,lm_size,&
    2911                 :             : &       nhat_dum,nspden,-1,0,option,-1,0,pawang,0,pawrd,&
    2912                 :          25 : &       pawrhoij(iatom),pawtb,rho1,trho_dum)
    2913         [ -  + ]:          25 :    if (usekden==1) then
    2914   [ #  #  #  #  :           0 :      ABI_MALLOC(tau1,(mesh_size,lm_size,nspden))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    2915   [ #  #  #  #  :           0 :      tau1=zero
                   #  # ]
    2916                 :             :      call pawkindensities(1,lmselect,lm_size,nspden,-1,option,-1,&
    2917                 :           0 : &         pawang,pawrd,pawrhoij(iatom),pawtb,tau1,trho_dum)
    2918                 :             :    end if
    2919                 :             : 
    2920                 :             : !-------------------------------------------------------------------
    2921                 :             : !Compute spherical potential and compute its first derivative dV/dr
    2922                 :             : 
    2923   [ -  +  +  -  :          75 :    ABI_MALLOC(potsph,(mesh_size))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    2924   [ -  +  +  -  :          50 :    ABI_MALLOC(dVdr,(mesh_size))
          -  +  -  +  -  
                      + ]
    2925   [ +  +  +  + ]:       63157 :    potsph=zero ; dVdr=zero
    2926                 :             : 
    2927                 :             : !  Compute XC potential
    2928                 :          25 :    option=1
    2929         [ +  - ]:          25 :    if (pawxcdev/=0) then
    2930   [ -  +  +  -  :         100 :      ABI_MALLOC(vxc,(mesh_size,lm_size,nspden))
          -  +  +  -  -  
          +  +  -  -  +  
                   -  + ]
    2931   [ +  +  +  +  :      307265 :      vxc=zero
                   +  + ]
    2932                 :             :      call pawxcm(pawtb%coredens,eexc_dum,eexcdc_dum,ssxc_dum,idum,hyb_mixing_,ixc,kxc_dum,lm_size,&
    2933                 :             : &         lmselect,nhat_dum,nkxc,.false.,mesh_size,nspden,option,pawang,pawrd,&
    2934                 :          25 : &         pawxcdev,rho1,usecore,usenhat,vxc,xclevel,xc_denpos,el_temp)
    2935         [ +  + ]:       31591 :      potsph(1:mesh_size)=half*(vxc(1:mesh_size,1,1)+vxc(1:mesh_size,1,nspden))
    2936                 :             :    else
    2937   [ #  #  #  #  :           0 :      ABI_MALLOC(vxc,(mesh_size,pawang%angl_size,nspden))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    2938   [ #  #  #  #  :           0 :      vxc=zero
                   #  # ]
    2939                 :             :      call pawxc(pawtb%coredens,eexc_dum,eexcdc_dum,ssxc_dum,hyb_mixing_,ixc,kxc_dum,k3xc_dum,&
    2940                 :             : &         lm_size,lmselect,nhat_dum,nkxc,nkxc,.false.,mesh_size,nspden,option,pawang,&
    2941                 :             : &         pawrd,rho1,usecore,usenhat,vxc,xclevel,xc_denpos,el_temp,&
    2942                 :           0 : &         coretau=pawtb%coretau,taur=tau1,xc_taupos=xc_taupos)
    2943         [ #  # ]:           0 :      potsph(1:mesh_size)=zero
    2944         [ #  # ]:           0 :      do ipts=1,pawang%angl_size
    2945                 :             :        potsph(1:mesh_size)=potsph(1:mesh_size) &
    2946         [ #  # ]:           0 : &        +half*(vxc(1:mesh_size,ipts,1)+vxc(1:mesh_size,ipts,nspden))*pawang%angwgth(ipts)
    2947                 :             :      end do
    2948         [ #  # ]:           0 :      potsph(1:mesh_size)=sqrt(four_pi)*potsph(1:mesh_size)
    2949                 :             :    end if
    2950                 :             : 
    2951                 :             : !  Compute Hartree potentialHalfFineStruct2
    2952   [ -  +  +  -  :          50 :    ABI_MALLOC(vhartree,(mesh_size))
          -  +  -  +  -  
                      + ]
    2953   [ -  +  +  -  :          50 :    ABI_MALLOC(rhosph,(mesh_size))
          -  +  -  +  -  
                      + ]
    2954   [ +  +  +  + ]:       63157 :    vhartree=zero ; rhosph=zero
    2955         [ +  + ]:       31591 :    rhosph(1:mesh_size)=rho1(1:mesh_size,1,1)
    2956         [ +  + ]:       31591 :    if (usecore==1) rhosph(1:mesh_size)=rhosph(1:mesh_size)+sqrt(four_pi)*pawtb%coredens(1:mesh_size)
    2957         [ +  + ]:       31591 :    rhosph(1:mesh_size)=rhosph(1:mesh_size)*four_pi*pawrd%rad(1:mesh_size)**2
    2958                 :          25 :    call poisson(rhosph,0,pawrd,vhartree)
    2959         [ +  + ]:       31566 :    vhartree(2:mesh_size)=(vhartree(2:mesh_size)-sqrt(four_pi)*znucl(itypat))/pawrd%rad(2:mesh_size)
    2960                 :          25 :    call pawrad_deducer0(vhartree,mesh_size,pawrd)
    2961         [ +  + ]:       31591 :    potsph(1:mesh_size)=potsph(1:mesh_size)+vhartree(1:mesh_size)
    2962                 :             : 
    2963                 :             : !  Apply angular scaling factor
    2964         [ +  + ]:       31591 :    potsph(1:mesh_size)=one_over_fourpi*potsph(1:mesh_size)
    2965                 :             : 
    2966                 :             : !  Compute 1st derivative of potential
    2967                 :          25 :    call nderiv_gen(dVdr,potsph,pawrd)
    2968                 :             : 
    2969                 :             : !  Multiply by relativistic factor
    2970         [ +  + ]:       31591 :    dVdr(1:mesh_size)=dVdr(1:mesh_size)*(one/(one-potsph(1:mesh_size)*half/InvFineStruct**2)**2)
    2971                 :             : 
    2972         [ -  + ]:          25 :    ABI_FREE(vxc)
    2973         [ -  + ]:          25 :    ABI_FREE(vhartree)
    2974         [ -  + ]:          25 :    ABI_FREE(potsph)
    2975         [ -  + ]:          25 :    ABI_FREE(rhosph)
    2976         [ -  + ]:          25 :    ABI_FREE(lmselect)
    2977         [ -  + ]:          25 :    ABI_FREE(rho1)
    2978         [ -  + ]:          25 :    if (usekden==1) then
    2979         [ #  # ]:           0 :      ABI_FREE(tau1)
    2980                 :             :    end if
    2981                 :             : 
    2982                 :             : !-------------------------------------------------------------------
    2983                 :             : !Compute radial and angular contributions
    2984                 :             : 
    2985   [ -  +  +  -  :         100 :    ABI_MALLOC(intf3,(ln_size,ln_size_j))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    2986   [ +  +  +  + ]:         533 :    intf3=zero
    2987                 :             : 
    2988                 :             : !  >>>> Calculate f_3= alpha^2/4 int[dr ui*(r) uj(r) dV/dr]
    2989   [ -  +  +  -  :          50 :    ABI_MALLOC(func,(mesh_size))
          -  +  -  +  -  
                      + ]
    2990         [ +  + ]:         125 :    do jln=1,ln_size_j
    2991         [ +  + ]:         533 :      do iln=1,ln_size
    2992         [ +  + ]:      516904 :        func(1:mesh_size)=dVdr(1:mesh_size)*pawtb%phi(1:mesh_size,iln)*phi_j(1:mesh_size,jln)
    2993                 :         508 :        call simp_gen(intf3(iln,jln),func,pawrd)
    2994                 :             :      end do
    2995                 :             :    end do
    2996   [ +  +  +  + ]:         533 :    intf3(:,:)=QuarterFineStruct2*spnorbscl*intf3(:,:)
    2997         [ -  + ]:          25 :    ABI_FREE(func)
    2998                 :             : 
    2999                 :             : !  Loop over initial states (valence or core, according to option_core)
    3000         [ +  + ]:         381 :    do jlmn=1,lmn_size_j
    3001                 :         356 :      jl=indlmn_j(1,jlmn)
    3002                 :         356 :      jm=indlmn_j(2,jlmn)
    3003                 :         356 :      jlm=indlmn_j(4,jlmn)
    3004                 :         356 :      jln=indlmn_j(5,jlmn)
    3005                 :             : 
    3006                 :             : !    In case of spinorial core wave function, we have to handle imaginary
    3007                 :             : !      spherical harmonics as linear combination of real spherical harmonics
    3008                 :             : !    See Brouwer et al, CPC 266, 108029 (2021), equation (21)
    3009         [ +  + ]:         356 :      if (option_core==1) then
    3010                 :         260 :        jm_re= abs(jm)
    3011                 :         260 :        jm_im=-abs(jm)
    3012                 :         260 :        jlm_re=jl*(jl+1)+jm_re+1
    3013                 :         260 :        jlm_im=jl*(jl+1)+jm_im+1
    3014                 :             : !      Calculate spinor dependent coefficients
    3015                 :         260 :        sgnkappa=indlmn_j(3,jlmn)   !sign of kappa
    3016                 :         260 :        jmj=half*indlmn_j(8,jlmn)   !2mj is stored in indlmn_cor
    3017                 :         260 :        js=indlmn_j(6,jlmn)       !1 is up, 2 is down
    3018         [ +  + ]:         260 :        if (sgnkappa==1) then
    3019         [ +  + ]:          52 :          if(js==1) then
    3020                 :          26 :            cgc= sqrt((dble(jl)-jmj+half)/dble(2*jl+1))
    3021                 :             :          else
    3022                 :          26 :            cgc=-sqrt((dble(jl)+jmj+half)/dble(2*jl+1))
    3023                 :             :          endif
    3024                 :             :        else
    3025         [ +  + ]:         208 :          if(js==1) then
    3026                 :          65 :            cgc= sqrt((dble(jl)+jmj+half)/dble(2*jl+1))
    3027                 :             :          else
    3028                 :         143 :            cgc= sqrt((dble(jl)-jmj+half)/dble(2*jl+1))
    3029                 :             :          endif
    3030                 :             :        endif
    3031                 :             : 
    3032                 :             : !      Calculate factors to convert from complex to real sph. harm.
    3033         [ +  + ]:         260 :        if (jm<0) then
    3034                 :         117 :          fact_re=sqr_fourpi_over_3*half_sqrt2*cgc
    3035                 :         117 :          fact_im=-fact_re
    3036         [ +  + ]:         143 :        else if (jm>0) then
    3037                 :          39 :          fact_re=sqr_fourpi_over_3*half_sqrt2*cgc*(-1)**jm
    3038                 :          39 :          fact_im=fact_re
    3039                 :             :        else
    3040                 :             :          fact_re=sqr_fourpi_over_3
    3041                 :             :          fact_im=0
    3042                 :             :        end if
    3043                 :             :      else ! valence-valence case (real)
    3044                 :             :        js=1
    3045                 :             :        jlm_re=jlm ; jlm_im=jlm
    3046                 :             :        fact_re=sqr_fourpi_over_3
    3047                 :             :        fact_im=0
    3048                 :             :      end if
    3049                 :             : 
    3050                 :             : !    Loop over final states
    3051         [ +  + ]:        3429 :      do ilmn=1,lmn_size
    3052                 :        3048 :        ilm=indlmn(4,ilmn)
    3053                 :        3048 :        iln=indlmn(5,ilmn)
    3054                 :             : 
    3055                 :             : !      >>>> Calculate g_ij=(g_x,g_y,g_z) = sqrt(4pi/3) int dOmega Ylm Ylm' S1-1,0,1
    3056                 :             : !              using real Gaunt coefficients
    3057                 :        3048 :        gx_re=zero;gy_re=zero;gz_re=zero
    3058                 :        3048 :        gx_im=zero;gy_im=zero;gz_im=zero
    3059                 :        3048 :        if3=zero
    3060                 :             : 
    3061                 :             : !      jl was set as a flag for invalid combinations
    3062                 :             : !        i.e. m=-(l+1) or m=(l+1)
    3063                 :             : !      In these cases, cgc=0 ; so gx=gy=gz=0
    3064         [ +  + ]:        3048 :        if (jl/=-1) then
    3065                 :        2364 :          if3=intf3(iln,jln)
    3066         [ +  + ]:        2364 :          klm_re=merge((jlm_re*(jlm_re-1))/2+ilm,(ilm*(ilm-1))/2+jlm_re,ilm<=jlm_re)
    3067                 :             : 
    3068                 :             : !        Real parts
    3069                 :             : !        M=-1
    3070                 :        2364 :          ignt=pawang%gntselect(2,klm_re) !get index for L=1 M =-1 ilm jlm_re
    3071         [ +  + ]:        2364 :          if (ignt/=0) gy_re=fact_re*pawang%realgnt(ignt)
    3072                 :             : !        M=0
    3073                 :        2364 :          ignt=pawang%gntselect(3,klm_re) !get index for L=1 M = 0 ilm jlm_re
    3074         [ +  + ]:        2364 :          if (ignt/=0) gz_re=fact_re*pawang%realgnt(ignt)
    3075                 :             : !        M=1
    3076                 :        2364 :          ignt=pawang%gntselect(4,klm_re) !get index for L=1 M = 1 ilm jlm_re
    3077         [ +  + ]:        2364 :          if (ignt/=0) gx_re=fact_re*pawang%realgnt(ignt)
    3078                 :             : 
    3079                 :             : !        Imaginary parts
    3080         [ +  + ]:        2364 :          if (option_core==1) then
    3081         [ +  + ]:        1596 :            klm_im=merge((jlm_im*(jlm_im-1))/2+ilm,(ilm*(ilm-1))/2+jlm_im,ilm<=jlm_im)
    3082                 :             : !          M=-1
    3083                 :        1596 :            ignt=pawang%gntselect(2,klm_im) !get index for L=1 M =-1 ilm jlm_im
    3084         [ +  + ]:        1596 :            if (ignt/=0) gy_im=fact_im*pawang%realgnt(ignt)
    3085                 :             : !          M=0
    3086                 :        1596 :            ignt=pawang%gntselect(3,klm_im) !get index for L=1 M = 0 ilm jlm_im
    3087         [ +  + ]:        1596 :            if (ignt/=0) gz_im=fact_im*pawang%realgnt(ignt)
    3088                 :             : !          M=1
    3089                 :        1596 :            ignt=pawang%gntselect(4,klm_im) !get index for L=1 M = 1 ilm jlm_im
    3090         [ +  + ]:        1596 :            if (ignt/=0) gx_im=fact_im*pawang%realgnt(ignt)
    3091                 :             :          end if
    3092                 :             :        end if
    3093                 :             : 
    3094                 :             : !      >>>> Calculate Sigma X g_ij
    3095                 :             : 
    3096   [ +  +  +  + ]:        3404 :        if (option_core==0.or.js==1) then
    3097                 :             :          !(Sigma^up-up X gij)_x = -gy*f_3
    3098                 :        1566 :          soc_ij(1,1,1,ilmn,jlmn)=-if3*gy_re           ! real part
    3099                 :        1566 :          soc_ij(2,1,1,ilmn,jlmn)=-if3*gy_im           ! imag part
    3100                 :             :          !(Sigma^up-up X gij)_y = gx*f_3
    3101                 :        1566 :          soc_ij(1,1,2,ilmn,jlmn)= if3*gx_re           ! real part
    3102                 :        1566 :          soc_ij(2,1,2,ilmn,jlmn)= if3*gx_im           ! imag part
    3103                 :             :          !(Sigma^up-up X gij)_z = 0
    3104                 :        1566 :          soc_ij(1,1,3,ilmn,jlmn)= zero                ! real part
    3105                 :        1566 :          soc_ij(2,1,3,ilmn,jlmn)= zero                ! imag part
    3106                 :             : 
    3107                 :             :          !(Sigma^dn-up X gij)_x = i.gz*f_3
    3108                 :        1566 :          soc_ij(1,2,1,ilmn,jlmn)=-if3*gz_im           ! real part
    3109                 :        1566 :          soc_ij(2,2,1,ilmn,jlmn)= if3*gz_re           ! imag part
    3110                 :             :          !(Sigma^dn-up X gij)_y = -gz*f_3
    3111                 :        1566 :          soc_ij(1,2,2,ilmn,jlmn)=-if3*gz_re           ! real part
    3112                 :        1566 :          soc_ij(2,2,2,ilmn,jlmn)=-if3*gz_im           ! imag part
    3113                 :             :          !(Sigma^dn-up X gij)_z = (gy-i.gx)*f_3
    3114                 :        1566 :          soc_ij(1,2,3,ilmn,jlmn)= if3*(gy_re+gx_im)   ! real part
    3115                 :        1566 :          soc_ij(2,2,3,ilmn,jlmn)= if3*(gy_im-gx_re)   ! imag part
    3116                 :             : 
    3117   [ +  -  +  + ]:        1482 :        else if (option_core==1.and.js==2) then
    3118                 :             :          !(Sigma^up-dn X gij^dn)_x = -i.gz^dn*f_3
    3119                 :         798 :          soc_ij(1,1,1,ilmn,jlmn)= if3*gz_im           ! real part
    3120                 :         798 :          soc_ij(2,1,1,ilmn,jlmn)=-if3*gz_re           ! imag part
    3121                 :             :          !(Sigma^up-dn X gij^dn)_y = -gz^dn*f_3
    3122                 :         798 :          soc_ij(1,1,2,ilmn,jlmn)=-if3*gz_re           ! real part
    3123                 :         798 :          soc_ij(2,1,2,ilmn,jlmn)=-if3*gz_im           ! imag part
    3124                 :             :          !(Sigma^up-dn X gij^dn)_z = (gy^dn+i.gx^dn)*f_3
    3125                 :         798 :          soc_ij(1,1,3,ilmn,jlmn)= if3*(gy_re-gx_im)   ! real part
    3126                 :         798 :          soc_ij(2,1,3,ilmn,jlmn)= if3*(gy_im+gx_re)   ! imag part
    3127                 :             : 
    3128                 :             :          !(Sigma^dn-dn X gij^dn)_x =  gy^dn*f_3
    3129                 :         798 :          soc_ij(1,2,1,ilmn,jlmn)= if3*gy_re           ! real part
    3130                 :         798 :          soc_ij(2,2,1,ilmn,jlmn)= if3*gy_im           ! imag part
    3131                 :             :          !(Sigma^dn-dn X gij^dn)_y = -gx^dn*f_3
    3132                 :         798 :          soc_ij(1,2,2,ilmn,jlmn)=-if3*gx_re           ! real part
    3133                 :         798 :          soc_ij(2,2,2,ilmn,jlmn)=-if3*gx_im           ! imag part
    3134                 :             :          !(Sigma^dn-dn X gij^dn)_z = 0
    3135                 :         798 :          soc_ij(1,2,3,ilmn,jlmn)= zero                ! real part
    3136                 :         798 :          soc_ij(2,2,3,ilmn,jlmn)= zero                ! imag part
    3137                 :             :        end if
    3138                 :             : 
    3139                 :             :      end do ! ilmn
    3140                 :             :    end do ! jlmn
    3141                 :             : 
    3142                 :             : !  Symetrization
    3143   [ +  +  +  - ]:          25 :    if (option_core==0.and.lmn_size>1) then
    3144         [ +  + ]:          96 :      do jlmn=2,lmn_size
    3145         [ +  + ]:         432 :        do ilmn=1,jlmn-1
    3146         [ +  + ]:        1428 :          do ii=1,3
    3147         [ +  + ]:        3360 :            do jj=1,2
    3148                 :        2016 :              avg=half*(soc_ij(1,jj,ii,ilmn,jlmn)+soc_ij(1,jj,ii,jlmn,ilmn))
    3149                 :        2016 :              soc_ij(1,jj,ii,ilmn,jlmn)=avg ; soc_ij(1,jj,ii,jlmn,ilmn)=avg
    3150                 :        2016 :              avg=half*(soc_ij(2,jj,ii,ilmn,jlmn)+soc_ij(2,jj,ii,ilmn,jlmn))
    3151                 :        3024 :              soc_ij(2,jj,ii,ilmn,jlmn)=avg ; soc_ij(2,jj,ii,jlmn,ilmn)=avg
    3152                 :             :            end do
    3153                 :             :          end do
    3154                 :             :        end do
    3155                 :             :      end do
    3156                 :             :    end if
    3157                 :             : 
    3158         [ -  + ]:          25 :    ABI_FREE(dVdr)
    3159         [ -  + ]:          36 :    ABI_FREE(intf3)
    3160                 :             : 
    3161                 :             :  end do  ! iatom
    3162                 :             : 
    3163                 :             : !Reduction in case of parallelism
    3164         [ +  + ]:          11 :  if (paral_atom) then
    3165                 :           8 :    call xmpi_sum(phisocphj,my_comm_atom,ierr)
    3166                 :             :  end if
    3167                 :             : 
    3168                 :             : !Destroy atom table(s) used for parallelism
    3169                 :          11 :  call free_my_atmtab(my_atmtab,my_atmtab_allocated)
    3170                 :             :  ABI_NVTX_END_RANGE()
    3171                 :             : 
    3172   [ -  +  -  +  :          22 :  end subroutine pawnabla_soc_init
          -  +  -  +  -  
             +  -  +  -  
                      + ]
    3173                 :             : !!***
    3174                 :             : 
    3175                 :             : !----------------------------------------------------------------------
    3176                 :             : 
    3177                 :           0 : END MODULE m_paw_optics
    3178                 :             : !!***
        

Generated by: LCOV version 2.3-1