LCOV - code coverage report
Current view: top level - src/65_paw - m_paw_optics.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 67.0 % 1112 745
Test Date: 2026-09-20 15:27:41 Functions: 75.0 % 4 3

            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              : MODULE m_paw_optics
      24              : 
      25              :  use defs_basis
      26              :  use m_xmpi
      27              :  use m_errors
      28              :  use m_wffile
      29              :  use m_abicore
      30              :  use m_hdr
      31              :  use m_dtset
      32              :  use m_dtfil
      33              :  use m_nctk
      34              :  use netcdf
      35              : 
      36              :  use defs_datatypes, only : pseudopotential_type
      37              :  use defs_abitypes,  only : MPI_type
      38              :  use m_time,         only : timab
      39              :  use m_io_tools,     only : open_file,get_unit,close_unit
      40              :  use m_pawpsp,       only : pawpsp_init_core
      41              :  use m_paw_atomorb,  only : atomorb_type,destroy_atomorb,copy_atomorb
      42              :  use m_pawrad,       only : pawrad_type,pawrad_deducer0,simp_gen,nderiv_gen,poisson
      43              :  use m_pawtab,       only : pawtab_type
      44              :  use m_pawcprj,      only : pawcprj_type,pawcprj_alloc,pawcprj_get, &
      45              : &                           pawcprj_free,pawcprj_mpi_allgather
      46              :  use m_pawang,       only : pawang_type
      47              :  use m_paw_denpot,   only : pawdensities,pawkindensities,pawdenpot
      48              :  use m_paw_an,       only : paw_an_type,paw_an_init,paw_an_free,paw_an_copy
      49              :  use m_pawrhoij,     only : pawrhoij_type
      50              :  use m_paw_ij,       only : paw_ij_type
      51              :  use m_paw_onsite,   only : pawnabla_init,pawnabla_core_init
      52              :  use m_paw_sphharm,  only : setnabla_ylm
      53              :  use m_pawxc,        only : pawxc,pawxcm,pawxc_get_xclevel,pawxc_get_usekden
      54              :  use m_rcpaw,        only : rcpaw_type
      55              :  use m_mpinfo,       only : destroy_mpi_enreg,nullify_mpi_enreg,initmpi_seq,proc_distrb_cycle
      56              :  use m_numeric_tools,only : kramerskronig
      57              :  use m_geometry,     only : metric
      58              :  use m_hide_lapack,  only : matrginv
      59              :  use m_paral_atom,   only : get_my_atmtab,free_my_atmtab
      60              : 
      61              :  implicit none
      62              : 
      63              :  private
      64              : 
      65              : !public procedures.
      66              :  public :: optics_paw
      67              :  public :: optics_paw_core
      68              :  public :: linear_optics_paw
      69              : 
      70              : !I/O parameters
      71              : !Set to true to force the use of netCDF when available
      72              : ! overriding the value of dtset%iomode
      73              :  logical,parameter :: use_netcdf_forced=.true.
      74              : !Set to true to use netcdf-MPIIO when available
      75              :  logical,parameter :: use_netcdf_mpiio=.true.
      76              : !Set to true to compute/write only half of the (n,m) dipoles
      77              :  logical,parameter :: compute_half_dipoles=.true.
      78              : !Set to true to use unlimited dimensions in netCDF file (experimental)
      79              : !  This is not mandatory because we know exactly the amount of data to write
      80              : !    and seems to impact performances negatively...
      81              : !    Not compatible with compute_half_dipoles=.true.
      82              :  logical,parameter :: use_netcdf_unlimited=.false.
      83              :    
      84              : CONTAINS  !========================================================================================
      85              : !!***
      86              : 
      87              : !----------------------------------------------------------------------
      88              : 
      89              : !!****f* m_paw_optics/optics_paw
      90              : !! NAME
      91              : !! optics_paw
      92              : !!
      93              : !! FUNCTION
      94              : !! Compute matrix elements need for optical conductivity (in the PAW context) and store them in a file
      95              : !!  Matrix elements = <Phi_i|Nabla|Phi_j>
      96              : !!
      97              : !! INPUTS
      98              : !!  atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
      99              : !!  cg(2,mcg)=planewave coefficients of wavefunctions.
     100              : !!  cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk>
     101              : !!                                          and each |p_lmn> non-local projector
     102              : !!  dimcprj(natom)=array of dimensions of array cprj (not ordered)
     103              : !!  dtfil <type(datafiles_type)>=variables related to files
     104              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     105              : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
     106              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates.
     107              : !!  mband=maximum number of bands
     108              : !!  mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
     109              : !!  mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
     110              : !!  mkmem =number of k points treated by this node.
     111              : !!  mpi_enreg=information about MPI parallelization
     112              : !!  mpsang =1+maximum angular momentum for nonlocal pseudopotentials
     113              : !!  mpw=maximum dimensioned size of npw.
     114              : !!  natom=number of atoms in cell.
     115              : !!  nkpt=number of k points.
     116              : !!  npwarr(nkpt)=number of planewaves in basis at this k point
     117              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     118              : !!  pawang <type(pawang_type)>= PAW ANGular mesh discretization and related data
     119              : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
     120              : !!  pawrhoij(my_natom) <type(pawrhoij_type)>= PAW rhoij occupancies and related data
     121              : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
     122              : !!  znucl(ntypat)=atomic number of atom type
     123              : !!
     124              : !! OUTPUT
     125              : !!  psinablapsi_out=contains the matrix elements
     126              : !!   (The size of the psinablapsi_out decide whether we compute the full matrix or
     127              : !!    only the diagonal part)
     128              : !!   (if not present only writing in a file)
     129              : !!
     130              : !! SIDE EFFECTS
     131              : !!
     132              : !! NOTES
     133              : !!
     134              : !! SOURCE
     135              : 
     136         2294 :  subroutine optics_paw(atindx1,cg,cprj,dimcprj,dtfil,dtset,eigen0,gprimd,hdr,kg,&
     137         1147 : &               mband,mcg,mcprj,mkmem,mpi_enreg,mpsang,mpw,natom,nkpt,npwarr,nsppol,&
     138         1147 : &               pawang,pawrad,pawrhoij,pawtab,znucl,psinablapsi_out)
     139              : 
     140              : !Arguments ------------------------------------
     141              : !scalars
     142              :  integer,intent(in) :: mband,mcg,mcprj,mkmem,mpsang,mpw,natom,nkpt,nsppol
     143              :  type(MPI_type),intent(in) :: mpi_enreg
     144              :  type(datafiles_type),intent(in) :: dtfil
     145              :  type(dataset_type),intent(in) :: dtset
     146              :  type(hdr_type),intent(inout) :: hdr
     147              :  type(pawang_type),intent(in) :: pawang
     148              :  real(dp),optional,target,intent(out) :: psinablapsi_out(:,:,:,:)
     149              : !arrays
     150              :  integer,intent(in) :: atindx1(natom),dimcprj(natom),npwarr(nkpt)
     151              :  integer,intent(in),target :: kg(3,mpw*mkmem)
     152              :  real(dp),intent(in) :: eigen0(mband*nkpt*nsppol)
     153              :  real(dp),intent(in) :: gprimd(3,3),znucl(dtset%ntypat)
     154              :  real(dp),intent(inout) :: cg(2,mcg)
     155              :  type(pawcprj_type),target,intent(inout) :: cprj(natom,mcprj)
     156              :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
     157              :  type(pawrhoij_type),intent(inout) :: pawrhoij(mpi_enreg%my_natom)
     158              :  type(pawtab_type),target,intent(inout) :: pawtab(dtset%ntypat)
     159              : 
     160              : !Local variables-------------------------------
     161              : !scalars
     162              :  integer,parameter :: master=0
     163              :  integer :: bsize,iomode,bdtot_index,cplex,etiq,fformopt,iatom,ib,ibmax,ibmin,ibg,ibsp
     164              :  integer :: ibshift,icg,ierr,ikg,ikpt,ilmn,ount,ncid,varid,idir
     165              :  integer :: iorder_cprj,ipw,ispinor,isppol,istwf_k,itypat,iwavef
     166              :  integer :: jb,jbshift,jbsp,my_jb,jlmn,jwavef,lmn_size,mband_cprj,option_core
     167              :  integer :: my_nspinor,nband_k,nband_cprj_k,npw_k,sender,me,master_spfftband,pnp_size
     168              :  integer :: spaceComm_band,spaceComm_bandspinorfft,spaceComm_fft,spaceComm_kpt
     169              :  integer :: spaceComm_spinor,spaceComm_bandspinor,spaceComm_spinorfft,spaceComm_w
     170              :  integer, parameter :: NO_FILE_OUT=-1
     171              :  logical :: already_has_nabla,cprj_paral_band,myband,mykpt,iomode_etsf_mpiio
     172              :  logical :: i_am_master,i_am_master_kpt,i_am_master_band,i_am_master_spfft,nc_unlimited,store_half_dipoles
     173              :  logical :: diag_only
     174              :  real(dp) :: cgnm1,cgnm2,cpnm1,cpnm2,cpnm11,cpnm22,cpnm12,cpnm21,cpnm_11m22,cpnm_21p12,cpnm_21m12,el_temp
     175              :  character(len=500) :: msg
     176              :  type(nctkdim_t) :: nctkdim
     177              : !arrays
     178              :  integer :: nc_count_5(5),nc_count_6(6),nc_start_5(5),nc_start_6(6),nc_stride_5(5),nc_stride_6(6),tmp_shape(3)
     179         1147 :  integer, ABI_CONTIGUOUS pointer :: kg_k(:,:)
     180              :  real(dp) :: kpoint(3),tsec(2),nabla_ij(3)
     181         1147 :  real(dp),allocatable :: kpg_k(:,:)
     182         1147 :  real(dp),pointer :: psinablapsi(:,:,:),psinablapsi_paw(:,:,:),psinablapsi_soc(:,:,:)
     183         1147 :  real(dp),pointer :: soc_ij(:,:,:)
     184         1147 :  type(coeff5_type),allocatable,target :: phisocphj(:)
     185         1147 :  type(pawcprj_type),pointer :: cprj_k(:,:),cprj_k_loc(:,:)
     186              :  type(nctkarr_t) :: nctk_arrays(1)
     187              : 
     188              : ! ************************************************************************
     189              : 
     190              :  DBG_ENTER("COLL")
     191              : 
     192              : !Compatibility tests
     193            0 :  ABI_CHECK(mkmem/=0,"mkmem==0 not supported anymore!")
     194         1147 :  ABI_CHECK(mpi_enreg%paral_spinor==0.or.dtset%pawspnorb==0,"spinor parallelization not supported with SOC!")
     195              : !  MJV 6/12/2008: looks like mpi_enreg may not be completely initialized here
     196              :  if (xmpi_paral==1) then
     197         4588 :    tmp_shape = shape(mpi_enreg%proc_distrb)
     198         1147 :    if (nkpt > tmp_shape(1)) then
     199            0 :      ABI_BUG('problem with proc_distrb!')
     200              :    end if
     201              :  end if
     202              : 
     203              : !Init parallelism
     204         1147 :  spaceComm_w=mpi_enreg%comm_cell
     205         1147 :  if (mpi_enreg%paral_kgb==1) then
     206          836 :    spaceComm_kpt=mpi_enreg%comm_kpt
     207          836 :    spaceComm_fft=mpi_enreg%comm_fft
     208          836 :    spaceComm_band=mpi_enreg%comm_band
     209          836 :    spaceComm_spinor=mpi_enreg%comm_spinor
     210          836 :    spaceComm_bandspinor=mpi_enreg%comm_bandspinor
     211          836 :    spaceComm_spinorfft=mpi_enreg%comm_spinorfft
     212          836 :    spaceComm_bandspinorfft=mpi_enreg%comm_bandspinorfft
     213              :  else
     214          311 :    spaceComm_kpt=mpi_enreg%comm_kpt
     215          311 :    spaceComm_fft=xmpi_comm_self
     216          311 :    spaceComm_band=mpi_enreg%comm_band
     217          311 :    spaceComm_spinor=xmpi_comm_self
     218          311 :    spaceComm_bandspinor=spaceComm_band
     219          311 :    spaceComm_spinorfft=xmpi_comm_self
     220          311 :    spaceComm_bandspinorfft=xmpi_comm_self
     221              :  end if
     222         1147 :  me=xmpi_comm_rank(spaceComm_w)
     223         1147 :  i_am_master=(me==master)
     224         1147 :  i_am_master_kpt=(xmpi_comm_rank(spaceComm_kpt)==master)
     225         1147 :  i_am_master_band=(xmpi_comm_rank(spaceComm_band)==master)
     226         1147 :  i_am_master_spfft=(xmpi_comm_rank(spaceComm_spinorfft)==master)
     227         1147 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     228              : 
     229              : !Check wether we write in file or save the matrix elements in psinablapsi_out
     230              : !and if we need to compute the full matrix or only the diagonal part
     231         1147 :  iomode=dtset%iomode
     232         1147 :  diag_only = .false.
     233         1147 :  store_half_dipoles = .false.
     234         1147 :  if (present(psinablapsi_out)) then
     235         1121 :    iomode = NO_FILE_OUT
     236         1121 :    iomode_etsf_mpiio = .false.
     237         1121 :    nc_unlimited = .false.
     238         1121 :    bsize = size(psinablapsi_out(1,1,:,1))
     239         1121 :    if (bsize ==  mband) then
     240              :       diag_only = .true.
     241              :       store_half_dipoles = .true. !FB ??
     242            0 :    else if (bsize == mband*(mband+1)/2) then
     243              :       diag_only = .false.
     244              :       store_half_dipoles = .true.
     245            0 :    else if (bsize == mband**2) then
     246              :       diag_only = .false.
     247              :       store_half_dipoles = .false.
     248              :    else
     249            0 :       msg = "Wrong dimensions of psinablapsi_out!"
     250            0 :       ABI_ERROR(msg)
     251              :    end if
     252      2906753 :    psinablapsi_out = zero
     253              :  end if
     254              : 
     255              : !----------------------------------------------------------------------------------
     256              : !1- Opening of OPT file and header writing
     257              : !----------------------------------------------------------------------------------
     258              : 
     259         1147 :  if (iomode /= NO_FILE_OUT) then
     260              : !  I/O mode is netCDF or Fortran
     261              :    iomode=merge(IO_MODE_ETSF,IO_MODE_FORTRAN_MASTER,dtset%iomode==IO_MODE_ETSF)
     262           26 :    if (use_netcdf_forced) iomode=IO_MODE_ETSF
     263              : 
     264              :  !  (master proc only)
     265           26 :    if (i_am_master) then
     266            8 :      fformopt=610 ; if (compute_half_dipoles) fformopt=620
     267              : !  ====> NETCDF format
     268              :    if (iomode==IO_MODE_ETSF) then
     269              : !    Open/create nc file
     270            8 :      NCF_CHECK(nctk_open_create(ncid,nctk_ncify(dtfil%fnameabo_app_opt),xmpi_comm_self))
     271              : !    Write header data
     272            8 :      NCF_CHECK(hdr%ncwrite(ncid,fformopt,nc_define=.true.))
     273              : !    Define dims and array for dipole variables
     274            8 :      nctk_arrays(1)%name="dipole_valence_valence"
     275            8 :      nctk_arrays(1)%dtype="dp"
     276            8 :      nc_unlimited=(use_netcdf_unlimited.and.(.not.(nctk_has_mpiio.and.use_netcdf_mpiio)))
     277              :      if (nc_unlimited) then
     278              :        nctkdim%name="unlimited_bands"
     279              :        nctkdim%value=NF90_UNLIMITED
     280              :        NCF_CHECK(nctk_def_dims(ncid,nctkdim))
     281              :        nctk_arrays(1)%shape_str=&
     282              : &      "complex,number_of_cartesian_directions,max_number_of_states,number_of_kpoints,number_of_spins,unlimited_bands"
     283              :      else if (compute_half_dipoles) then
     284            8 :        nctkdim%name="max_number_of_state_pairs"
     285            8 :        nctkdim%value=(mband*(mband+1))/2
     286            8 :        NCF_CHECK(nctk_def_dims(ncid,nctkdim))
     287              :        nctk_arrays(1)%shape_str=&
     288            8 : &      "complex,number_of_cartesian_directions,max_number_of_state_pairs,number_of_kpoints,number_of_spins"
     289              :      else
     290              :        nctk_arrays(1)%shape_str=&
     291              : &      "complex,number_of_cartesian_directions,max_number_of_states,max_number_of_states,number_of_kpoints,number_of_spins"
     292              :      end if
     293            8 :      NCF_CHECK(nctk_def_arrays(ncid, nctk_arrays))
     294            8 :      NCF_CHECK(nctk_set_atomic_units(ncid, "dipole_valence_valence"))
     295              : !    Write eigenvalues
     296            8 :      NCF_CHECK(nctk_set_datamode(ncid))
     297            8 :      varid=nctk_idname(ncid,"eigenvalues")
     298           32 :      NCF_CHECK(nf90_put_var(ncid,varid,reshape(eigen0,[mband,nkpt,nsppol])))
     299              :      !Close file here because the rest has possibly to be written with collective I/O
     300            8 :      NCF_CHECK(nf90_close(ncid))
     301              : !  ====> Standard FORTRAN binary format
     302              :      else if (iomode==IO_MODE_FORTRAN_MASTER) then
     303              :        if (open_file(dtfil%fnameabo_app_opt,msg,newunit=ount,form="unformatted",status="unknown")/= 0) then
     304              :          ABI_ERROR(msg)
     305              :        end if
     306              :        call hdr%fort_write(ount,fformopt,ierr,rewind=.true.)
     307              :        write(ount)(eigen0(ib),ib=1,mband*nkpt*nsppol)
     308              :      else
     309              :        msg = "Wrong OPT file format!"
     310              :        ABI_BUG(msg)
     311              :      end if ! File format
     312              :    end if ! master node
     313           26 :    call xmpi_bcast(iomode,master,spaceComm_w,ierr)  ! Seems mandatory; why ?
     314           26 :    iomode_etsf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio)
     315              :    nc_unlimited=(iomode==IO_MODE_ETSF.and.use_netcdf_unlimited.and.(.not.iomode_etsf_mpiio)) ! UNLIMITED not compatible with mpi-io
     316              :    store_half_dipoles=(compute_half_dipoles.and.(.not.nc_unlimited))
     317              :  end if
     318              : 
     319              : !----------------------------------------------------------------------------------
     320              : !2- Computation of on-site contribution: <phi_i|nabla|phi_j>-<tphi_i|nabla|tphi_j>
     321              : !----------------------------------------------------------------------------------
     322              : 
     323         1147 :  already_has_nabla=all(pawtab(:)%has_nabla==2)
     324         1147 :  call pawnabla_init(mpsang,dtset%ntypat,pawrad,pawtab)
     325              : 
     326              : !Get electronic temperature from dtset
     327         1147 :  el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
     328              : 
     329              : !Compute spin-orbit contributions if necessary
     330         1147 :  if (dtset%pawspnorb==1) then
     331            1 :    option_core=0
     332              :    call pawnabla_soc_init(el_temp,phisocphj,option_core,dtset%ixc,mpi_enreg%my_natom,natom,&
     333              : &       dtset%nspden,dtset%ntypat,pawang,pawrad,pawrhoij,pawtab,dtset%pawxcdev,&
     334              : &       dtset%spnorbscl,dtset%typat,dtset%xc_denpos,dtset%xc_taupos,znucl,&
     335            1 : &       comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab)
     336              :  end if
     337              : 
     338              : !----------------------------------------------------------------------------------
     339              : !3- Computation of <psi_n|-i.nabla|psi_m> for each k
     340              : !----------------------------------------------------------------------------------
     341              : 
     342              : !Prepare valence-valence dipoles writing
     343              : !In case of netCDF access to OPT file, prepare collective I/O
     344         1147 :  if (iomode == IO_MODE_ETSF) then
     345           26 :    if (iomode_etsf_mpiio) then
     346           26 :      if (i_am_master_spfft) then
     347           16 :        NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt),spaceComm_band))
     348           16 :        varid=nctk_idname(ncid,"dipole_valence_valence")
     349           16 :        if (xmpi_comm_size(spaceComm_w)>1) then
     350           14 :          NCF_CHECK(nctk_set_collective(ncid,varid))
     351              :        end if
     352           16 :        NCF_CHECK(nctk_set_datamode(ncid))
     353              :      end if
     354            0 :    else if (i_am_master) then
     355            0 :      NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt),xmpi_comm_self))
     356            0 :      varid=nctk_idname(ncid,"dipole_valence_valence")
     357              :      if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then
     358              :        NCF_CHECK(nctk_set_collective(ncid,varid))
     359              :      end if
     360            0 :      NCF_CHECK(nctk_set_datamode(ncid))
     361              :    end if
     362              :  end if
     363         1147 :  if (iomode /= NO_FILE_OUT) then
     364           26 :    if (iomode_etsf_mpiio) then
     365              :      !If MPI-IO, store only ib elements for each jb
     366           78 :      ABI_MALLOC(psinablapsi,(2,3,mband))
     367           52 :      ABI_MALLOC(psinablapsi_paw,(2,3,mband))
     368           26 :      if (dtset%pawspnorb==1) then
     369            2 :        ABI_MALLOC(psinablapsi_soc,(2,3,mband))
     370              :      end if
     371              :    else
     372              :      !If not, store all (ib,jb) pairs (or half)
     373            0 :      bsize=mband**2 ; if (store_half_dipoles) bsize=(mband*(mband+1))/2
     374            0 :      ABI_MALLOC(psinablapsi,(2,3,bsize))
     375            0 :      ABI_MALLOC(psinablapsi_paw,(2,3,bsize))
     376            0 :      if (dtset%pawspnorb==1) then
     377            0 :        ABI_MALLOC(psinablapsi_soc,(2,3,bsize))
     378              :      end if
     379            0 :      psinablapsi=zero
     380              :    end if
     381          104 :    pnp_size=size(psinablapsi)
     382              :  else
     383         1121 :    if (diag_only) then
     384              :       bsize = mband
     385            0 :    else if (store_half_dipoles) then
     386            0 :       bsize=(mband*(mband+1))/2
     387              :    else
     388            0 :       bsize=mband**2
     389              :    end if
     390         3363 :    ABI_MALLOC(psinablapsi_paw,(2,3,bsize))
     391         1121 :    if (dtset%pawspnorb==1) then
     392            0 :      ABI_MALLOC(psinablapsi_soc,(2,3,bsize))
     393              :    end if
     394         4484 :    pnp_size=size(psinablapsi_paw)
     395              :  end if
     396              : 
     397              : !Determine if cprj datastructure is distributed over bands
     398         1147 :  mband_cprj=mcprj/(my_nspinor*mkmem*nsppol)
     399         1147 :  cprj_paral_band=(mband_cprj<mband)
     400              : 
     401              : !LOOP OVER SPINS
     402         1147 :  ibg=0;icg=0
     403         1147 :  bdtot_index=0
     404         2294 :  do isppol=1,nsppol
     405              : 
     406              : !  LOOP OVER k POINTS
     407         1147 :    ikg=0
     408        38408 :    do ikpt=1,nkpt
     409              : 
     410        36114 :      if (iomode == NO_FILE_OUT) psinablapsi => psinablapsi_out(:,:,:,ikpt)
     411              : 
     412        36114 :      etiq=ikpt+(isppol-1)*nkpt
     413        36114 :      nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
     414       326000 :      master_spfftband=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol))
     415              : 
     416              : !    Select k-points for current proc
     417        36114 :      mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,mpi_enreg%me_kpt))
     418        36114 :      if (mykpt) then
     419              : 
     420              : !      Data depending on k-point
     421        16480 :        npw_k=npwarr(ikpt)
     422        16480 :        istwf_k=dtset%istwfk(ikpt)
     423        16480 :        cplex=2;if (istwf_k>1) cplex=1
     424        65920 :        kpoint(:)=dtset%kptns(:,ikpt)
     425              : 
     426              : !      Extract cprj for this k-point
     427        16480 :        nband_cprj_k=nband_k;if (cprj_paral_band) nband_cprj_k=nband_k/mpi_enreg%nproc_band
     428        16480 :        if (mkmem*nsppol/=1) then
     429        16477 :          iorder_cprj=0
     430       383488 :          ABI_MALLOC(cprj_k_loc,(natom,my_nspinor*nband_cprj_k))
     431        16477 :          call pawcprj_alloc(cprj_k_loc,0,dimcprj)
     432              :          call pawcprj_get(atindx1,cprj_k_loc,cprj,natom,1,ibg,ikpt,iorder_cprj,isppol,&
     433              : &         mband_cprj,mkmem,natom,nband_cprj_k,nband_cprj_k,my_nspinor,nsppol,dtfil%unpaw,&
     434        16477 : &         mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
     435              :        else
     436            3 :          cprj_k_loc => cprj
     437              :        end if
     438              : 
     439              : !      if cprj are distributed over bands, gather them (because we need to mix bands)
     440        16480 :        if (cprj_paral_band) then
     441       185984 :          ABI_MALLOC(cprj_k,(natom,my_nspinor*nband_k))
     442         6608 :          call pawcprj_alloc(cprj_k,0,dimcprj)
     443              :          call pawcprj_mpi_allgather(cprj_k_loc,cprj_k,natom, &
     444              : &             my_nspinor*nband_cprj_k,my_nspinor*mpi_enreg%bandpp,&
     445         6608 : &         dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band,ierr,rank_ordered=.false.)
     446              :        else
     447         9872 :          cprj_k => cprj_k_loc
     448              :        end if
     449              : 
     450              : !      Compute k+G in cartesian coordinates
     451        49440 :        ABI_MALLOC(kpg_k,(3,npw_k*dtset%nspinor))
     452        16480 :        kg_k => kg(:,1+ikg:npw_k+ikg)
     453      2327848 :        do ipw=1,npw_k
     454              :          kpg_k(1,ipw)=(kpoint(1)+kg_k(1,ipw))*gprimd(1,1) &
     455              : &                    +(kpoint(2)+kg_k(2,ipw))*gprimd(1,2) &
     456      2311368 : &                    +(kpoint(3)+kg_k(3,ipw))*gprimd(1,3)
     457              :          kpg_k(2,ipw)=(kpoint(1)+kg_k(1,ipw))*gprimd(2,1) &
     458              : &                    +(kpoint(2)+kg_k(2,ipw))*gprimd(2,2) &
     459      2311368 : &                    +(kpoint(3)+kg_k(3,ipw))*gprimd(2,3)
     460              :          kpg_k(3,ipw)=(kpoint(1)+kg_k(1,ipw))*gprimd(3,1) &
     461              : &                    +(kpoint(2)+kg_k(2,ipw))*gprimd(3,2) &
     462      2327848 : &                    +(kpoint(3)+kg_k(3,ipw))*gprimd(3,3)
     463              :        end do
     464      9261952 :        kpg_k(:,1:npw_k)=two_pi*kpg_k(:,1:npw_k)
     465        18956 :        if (dtset%nspinor==2) kpg_k(1:3,npw_k+1:2*npw_k)=kpg_k(1:3,1:npw_k)
     466              : 
     467              : !      Loops over bands
     468       149094 :        do jb=1,nband_k
     469       132614 :          jwavef=(jb-1)*npw_k*my_nspinor+icg
     470              :          !If MPI-IO, compute all (ib,jb) pairs ; if not, compute only ib<=jb
     471       132614 :          ibmax=merge(nband_k,jb,iomode_etsf_mpiio)
     472              :          !If MPI-IO, store only ib elements for each jb ; if not, store all (ib,jb) pairs
     473       130304 :          my_jb=merge(1,jb,(iomode_etsf_mpiio .or. diag_only))
     474              :          !If diag_only then ibmin = ibmax = jb
     475       132614 :          ibmax=merge(jb,ibmax,diag_only)
     476       132614 :          ibmin=merge(jb,1,diag_only)
     477              : 
     478              : !        Fill output arrays with zeros
     479       132614 :          if (store_half_dipoles) then
     480       132614 :            jbshift=(my_jb*(my_jb-1))/2 ; bsize=nband_k
     481              :          else
     482            0 :            jbshift=(my_jb-1)*mband ; bsize=mband
     483              :          end if
     484       132614 :          if ((.not. diag_only) .or. jb == 1) then
     485      1600238 :             psinablapsi(:,:,jbshift+1:jbshift+bsize)=zero
     486      1600238 :             psinablapsi_paw(:,:,jbshift+1:jbshift+bsize)=zero
     487        22598 :             if (dtset%pawspnorb==1) psinablapsi_soc(:,:,jbshift+1:jbshift+bsize)=zero
     488              :          end if
     489              : 
     490              : !        2-A Computation of <psi_tild_n|-i.nabla|psi_tild_m>
     491              : !        ----------------------------------------------------------------------------------
     492              : !        Note: <psi_nk|-i.nabla|psi_mk> => Sum_g[ <G|Psi_nk>^* <G|Psi_mk> G ]
     493              : 
     494              : !        Select bands for current proc
     495       132614 :          myband=.true.
     496       132614 :          if (xmpi_paral==1.and.mpi_enreg%paral_kgb/=1.and.(.not.iomode_etsf_mpiio)) then
     497        78080 :            myband=(abs(mpi_enreg%proc_distrb(ikpt,jb,isppol)-mpi_enreg%me_kpt)==0)
     498              :          end if
     499       132614 :          if (myband) then
     500              :            
     501              :            !$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(ib,iwavef,ipw,cgnm1,cgnm2,ibshift) &
     502              :            !$OMP SHARED(ibmin,ibmax,cg,kpg_k,jwavef,jbshift,npw_k,my_nspinor,icg,istwf_k,psinablapsi, &
     503              :            !$OMP        jb,store_half_dipoles,iomode_etsf_mpiio,mband) &
     504              :            !$OMP SCHEDULE(STATIC)
     505       290778 :            do ib=ibmin,ibmax
     506       158164 :              iwavef=(ib-1)*npw_k*my_nspinor+icg
     507              : 
     508              : !            (C_nk^*)*C_mk*(k+g) is expressed in cartesian coordinates
     509       158164 :              if (istwf_k>1) then
     510              :                !In this case (istwfk>1): Sum_g>=g0[ 2i.Im(<G|Psi_nk>^* <G|Psi_mk> G) ]
     511              :                !G=k+g=0 term is included but do not contribute
     512            0 :                do ipw=1,npw_k*my_nspinor
     513            0 :                  cgnm2=two*(cg(1,ipw+iwavef)*cg(2,ipw+jwavef)-cg(2,ipw+iwavef)*cg(1,ipw+jwavef))
     514            0 :                  psinablapsi(2,1:3,jbshift+ib)=psinablapsi(2,1:3,jbshift+ib)+cgnm2*kpg_k(1:3,ipw)
     515              :                end do
     516              :              else
     517     21140832 :                do ipw=1,npw_k*my_nspinor
     518     20982668 :                  cgnm1=cg(1,ipw+iwavef)*cg(1,ipw+jwavef)+cg(2,ipw+iwavef)*cg(2,ipw+jwavef)
     519     20982668 :                  cgnm2=cg(1,ipw+iwavef)*cg(2,ipw+jwavef)-cg(2,ipw+iwavef)*cg(1,ipw+jwavef)
     520     83930672 :                  psinablapsi(1,1:3,jbshift+ib)=psinablapsi(1,1:3,jbshift+ib)+cgnm1*kpg_k(1:3,ipw)
     521     84088836 :                  psinablapsi(2,1:3,jbshift+ib)=psinablapsi(2,1:3,jbshift+ib)+cgnm2*kpg_k(1:3,ipw)
     522              :                end do
     523              :              end if
     524              : 
     525              : !            Second half of the (n,m) matrix
     526       290778 :              if ((ib/=jb).and.(.not.store_half_dipoles).and.(.not.iomode_etsf_mpiio)) then
     527            0 :                ibshift=(ib-1)*mband
     528            0 :                psinablapsi(1,1:3,ibshift+jb)= psinablapsi(1,1:3,jbshift+ib)
     529            0 :                psinablapsi(2,1:3,ibshift+jb)=-psinablapsi(2,1:3,jbshift+ib)
     530              :              end if
     531              : 
     532              :            end do ! ib
     533              :            !$OMP END PARALLEL DO
     534              : 
     535              : !          Reduction in case of parallelism
     536       132614 :            if (iomode_etsf_mpiio) then
     537         2310 :              call timab(48,1,tsec)
     538         2310 :              if (mpi_enreg%paral_kgb==1) then
     539         2160 :                call xmpi_sum_master(psinablapsi,master,spaceComm_spinorfft,ierr)
     540              :              end if
     541         2310 :              if (i_am_master_spfft) then
     542         1230 :                call xmpi_sum(psinablapsi,spaceComm_band,ierr)
     543              :              end if
     544         2310 :              call timab(48,2,tsec)
     545              :            end if
     546              : 
     547              :          end if ! myband
     548              : 
     549              : 
     550              : !        2-B Computation of <psi_n|p_i><p_j|psi_m>(<phi_i|-i.nabla|phi_j>-<tphi_i|-i.nabla|tphi_j>)
     551              : !        ----------------------------------------------------------------------------------
     552              : !        Non relativistic contribution
     553              : !        Note: <psi|-i.nabla|psi_mk>
     554              : !              => -i Sum_ij[ <p_i|Psi_nk>^* <p_j|Psi_mk> (<Phi_i|Nabla|Phi_j>-<tPhi_i|Nabla|tPhi_j>) ]
     555              : 
     556              : !        Select bands for current proc
     557       132614 :          myband=.true.
     558       132614 :          if (mpi_enreg%paral_kgb==1) then
     559        54384 :            myband=(mod(jb-1,mpi_enreg%nproc_band)==mpi_enreg%me_band)
     560        78230 :          else if (xmpi_paral==1) then
     561        78230 :            myband=(abs(mpi_enreg%proc_distrb(ikpt,jb,isppol)-mpi_enreg%me_kpt)==0)
     562              :          end if
     563       132614 :          if (myband) then
     564              :            !$OMP PARALLEL DO DEFAULT(NONE) SCHEDULE(STATIC) &
     565              :            !$OMP PRIVATE(ib,ibsp,jbsp,ispinor,iatom,itypat,lmn_size,jlmn,ilmn,idir, &
     566              :            !$OMP         cpnm1,cpnm2,cpnm11,cpnm22,cpnm12,cpnm21,cpnm_11m22,cpnm_21p12,cpnm_21m12, &
     567              :            !$OMP         nabla_ij,soc_ij,ibshift) &
     568              :            !$OMP SHARED(ibmin,ibmax,jb,jbshift,my_nspinor,cplex,natom,dtset,pawtab,cprj_k, &
     569              :            !$OMP        phisocphj,psinablapsi_paw,psinablapsi_soc,store_half_dipoles,iomode_etsf_mpiio,mband)
     570       230754 :            do ib=ibmin,ibmax
     571              : 
     572       124852 :              ibsp=(ib-1)*my_nspinor ; jbsp=(jb-1)*my_nspinor
     573       250104 :              do ispinor=1,my_nspinor
     574       125252 :                ibsp=ibsp+1;jbsp=jbsp+1
     575       250104 :                if (cplex==1) then
     576            0 :                  do iatom=1,natom
     577            0 :                    itypat=dtset%typat(iatom)
     578            0 :                    lmn_size=pawtab(itypat)%lmn_size
     579            0 :                    do jlmn=1,lmn_size
     580            0 :                      do ilmn=1,lmn_size
     581            0 :                        nabla_ij(:)=pawtab(itypat)%nabla_ij(:,ilmn,jlmn)
     582            0 :                        if (ib>jb) nabla_ij(:)=-pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
     583            0 :                        cpnm1=cprj_k(iatom,ibsp)%cp(1,ilmn)*cprj_k(iatom,jbsp)%cp(1,jlmn)
     584            0 :                        if (dtset%nspinor==2) cpnm1=cpnm1+cprj_k(iatom,ibsp)%cp(2,ilmn)*cprj_k(iatom,jbsp)%cp(2,jlmn)
     585            0 :                        psinablapsi_paw(2,:,jbshift+ib)=psinablapsi_paw(2,:,jbshift+ib)-cpnm1*nabla_ij(:)
     586              :                      end do !ilmn
     587              :                    end do !jlmn
     588              :                  end do !iatom
     589              :                else
     590       377556 :                  do iatom=1,natom
     591       252304 :                    itypat=dtset%typat(iatom)
     592       252304 :                    lmn_size=pawtab(itypat)%lmn_size
     593      2395988 :                    do jlmn=1,lmn_size
     594     18418192 :                      do ilmn=1,lmn_size
     595     64589824 :                        nabla_ij(:)=pawtab(itypat)%nabla_ij(:,ilmn,jlmn)
     596     20022016 :                        if (ib>jb) nabla_ij(:)=-pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
     597              :                        cpnm1=(cprj_k(iatom,ibsp)%cp(1,ilmn)*cprj_k(iatom,jbsp)%cp(1,jlmn) &
     598     16147456 : &                            +cprj_k(iatom,ibsp)%cp(2,ilmn)*cprj_k(iatom,jbsp)%cp(2,jlmn))
     599              :                        cpnm2=(cprj_k(iatom,ibsp)%cp(1,ilmn)*cprj_k(iatom,jbsp)%cp(2,jlmn) &
     600     16147456 : &                            -cprj_k(iatom,ibsp)%cp(2,ilmn)*cprj_k(iatom,jbsp)%cp(1,jlmn))
     601     64589824 :                        psinablapsi_paw(1,:,jbshift+ib)=psinablapsi_paw(1,:,jbshift+ib)+cpnm2*nabla_ij(:)
     602     66608256 :                        psinablapsi_paw(2,:,jbshift+ib)=psinablapsi_paw(2,:,jbshift+ib)-cpnm1*nabla_ij(:)
     603              :                      end do !ilmn
     604              :                    end do !jlmn
     605              :                  end do !iatom
     606              :                end if
     607              :              end do !ispinor
     608              : 
     609              : !        2-C Computation of Spin-orbit coupling contribution:
     610              : !             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>]
     611              : !        ----------------------------------------------------------------------------------
     612       124852 :              if (dtset%pawspnorb==1) then
     613              : !              Add: Sum_ij,ss'[<Psi^s_n|p_i><p_j|Psi^s'_m> (Sigma^ss' X g_ij)]
     614              : !                  =Sum_ij[ (<Psi^up_n|p_i><p_j|Psi^up_m>-<Psi^dn_n|p_i><p_j|Psi^dn_m>) (Sigma^up-up     X g_ij)
     615              : !                          +(<Psi^dn_n|p_i><p_j|Psi^up_m>+<Psi^up_n|p_i><p_j|Psi^dn_m>) (Re{Sigma^dn-up} X g_ij)
     616              : !                          +(<Psi^dn_n|p_i><p_j|Psi^up_m>-<Psi^up_n|p_i><p_j|Psi^dn_m>) (Im{Sigma^dn-up} X g_ij) ]
     617              : !               where: g_ij = <Phi_i| 1/4 Alpha^2 dV/dr vec(r)/r) |Phi_j>
     618              : !              Note that:
     619              : !                phisocphj(:)%value(re:im,1,idir,ilmn,jlmn) is (Sigma^up-up X g_ij)
     620              : !                phisocphj(:)%value(re:im,2,idir,ilmn,jlmn) is (Sigma^dn-up X g_ij)
     621              : !              Not compatible with parallelization over spinors
     622          400 :                ibsp=1+(ib-1)*dtset%nspinor ; jbsp=1+(jb-1)*dtset%nspinor
     623         2000 :                do iatom=1,natom
     624         1600 :                  itypat=dtset%typat(iatom)
     625         1600 :                  lmn_size=pawtab(itypat)%lmn_size
     626        14800 :                  do jlmn=1,lmn_size
     627       116800 :                    do ilmn=1,lmn_size
     628       102400 :                      soc_ij => phisocphj(iatom)%value(:,:,:,ilmn,jlmn)
     629              :                      !Contribution from real part of <Psi^s_n|p_i><p_j|Psi^s'_m>
     630              :                      cpnm11=cprj_k(iatom,ibsp  )%cp(1,ilmn)*cprj_k(iatom,jbsp  )%cp(1,jlmn) &
     631       102400 : &                          +cprj_k(iatom,ibsp  )%cp(2,ilmn)*cprj_k(iatom,jbsp  )%cp(2,jlmn)
     632              :                      cpnm22=cprj_k(iatom,ibsp+1)%cp(1,ilmn)*cprj_k(iatom,jbsp+1)%cp(1,jlmn) &
     633       102400 : &                          +cprj_k(iatom,ibsp+1)%cp(2,ilmn)*cprj_k(iatom,jbsp+1)%cp(2,jlmn)
     634              :                      cpnm12=cprj_k(iatom,ibsp  )%cp(1,ilmn)*cprj_k(iatom,jbsp+1)%cp(1,jlmn) &
     635       102400 : &                          +cprj_k(iatom,ibsp  )%cp(2,ilmn)*cprj_k(iatom,jbsp+1)%cp(2,jlmn)
     636              :                      cpnm21=cprj_k(iatom,ibsp+1)%cp(1,ilmn)*cprj_k(iatom,jbsp  )%cp(1,jlmn) &
     637       102400 : &                          +cprj_k(iatom,ibsp+1)%cp(2,ilmn)*cprj_k(iatom,jbsp  )%cp(2,jlmn)
     638       102400 :                      cpnm_11m22=cpnm11-cpnm22
     639       102400 :                      cpnm_21p12=cpnm21+cpnm12
     640       102400 :                      cpnm_21m12=cpnm21-cpnm12
     641       409600 :                      do idir=1,3
     642              :                        psinablapsi_soc(1,idir,jbshift+ib)=psinablapsi_soc(1,idir,jbshift+ib) &
     643       307200 : &                             +soc_ij(1,1,idir)*cpnm_11m22+soc_ij(1,2,idir)*cpnm_21p12
     644              :                        psinablapsi_soc(2,idir,jbshift+ib)=psinablapsi_soc(2,idir,jbshift+ib) &
     645       409600 : &                             +soc_ij(2,2,idir)*cpnm_21m12
     646              :                      end do
     647              :                      !Contribution from imaginary part of <Psi^s_n|p_i><p_j|Psi^s'_m>
     648              :                      cpnm11=cprj_k(iatom,ibsp  )%cp(1,ilmn)*cprj_k(iatom,jbsp  )%cp(2,jlmn) &
     649       102400 : &                          -cprj_k(iatom,ibsp  )%cp(2,ilmn)*cprj_k(iatom,jbsp  )%cp(1,jlmn)
     650              :                      cpnm22=cprj_k(iatom,ibsp+1)%cp(1,ilmn)*cprj_k(iatom,jbsp+1)%cp(2,jlmn) &
     651       102400 : &                          -cprj_k(iatom,ibsp+1)%cp(2,ilmn)*cprj_k(iatom,jbsp+1)%cp(1,jlmn)
     652              :                      cpnm12=cprj_k(iatom,ibsp  )%cp(1,ilmn)*cprj_k(iatom,jbsp+1)%cp(2,jlmn) &
     653       102400 : &                          -cprj_k(iatom,ibsp  )%cp(2,ilmn)*cprj_k(iatom,jbsp+1)%cp(1,jlmn)
     654              :                      cpnm21=cprj_k(iatom,ibsp+1)%cp(1,ilmn)*cprj_k(iatom,jbsp  )%cp(2,jlmn) &
     655       102400 : &                          -cprj_k(iatom,ibsp+1)%cp(2,ilmn)*cprj_k(iatom,jbsp  )%cp(1,jlmn)
     656       102400 :                      cpnm_11m22=cpnm11-cpnm22
     657       102400 :                      cpnm_21p12=cpnm21+cpnm12
     658       102400 :                      cpnm_21m12=cpnm21-cpnm12
     659       422400 :                      do idir=1,3
     660              :                        psinablapsi_soc(1,idir,jbshift+ib)=psinablapsi_soc(1,idir,jbshift+ib) &
     661       307200 : &                          -soc_ij(2,2,idir)*cpnm_21m12
     662              :                        psinablapsi_soc(2,idir,jbshift+ib)=psinablapsi_soc(2,idir,jbshift+ib) &
     663       409600 : &                          +soc_ij(1,1,idir)*cpnm_11m22+soc_ij(1,2,idir)*cpnm_21p12
     664              :                      end do
     665              :                    end do ! ilmn
     666              :                  end do ! jlmn
     667              :                end do ! iatom
     668              :              end if ! pawspnorb
     669              : 
     670              : !            Second half of the (n,m) matrix
     671       230754 :              if ((ib/=jb).and.(.not.store_half_dipoles).and.(.not.iomode_etsf_mpiio)) then
     672            0 :                ibshift=(ib-1)*mband
     673            0 :                psinablapsi_paw(1,1:3,ibshift+jb)= psinablapsi_paw(1,1:3,jbshift+ib)
     674            0 :                psinablapsi_paw(2,1:3,ibshift+jb)=-psinablapsi_paw(2,1:3,jbshift+ib)
     675            0 :                if (dtset%pawspnorb==1) then
     676            0 :                  psinablapsi_soc(1,1:3,ibshift+jb)= psinablapsi_soc(1,1:3,jbshift+ib)
     677            0 :                  psinablapsi_soc(2,1:3,ibshift+jb)=-psinablapsi_soc(2,1:3,jbshift+ib)
     678              :                end if
     679              :              end if
     680              : 
     681              :            end do ! ib loop
     682              :            !$OMP END PARALLEL DO
     683              : 
     684       105902 :            if (iomode_etsf_mpiio.and.mpi_enreg%paral_spinor==1) then
     685            0 :              call timab(48,1,tsec)
     686            0 :              call xmpi_sum_master(psinablapsi_paw,master,spaceComm_spinor,ierr)
     687            0 :              call timab(48,2,tsec)
     688              :            end if
     689              : 
     690              :          end if ! myband
     691              : 
     692              : !        Write to OPT file in case of MPI-IO
     693        44902 :          if (iomode_etsf_mpiio.and.i_am_master_spfft) then
     694         1230 :            if (myband) then
     695       183550 :              psinablapsi=psinablapsi+psinablapsi_paw
     696         8750 :              if (dtset%pawspnorb==1) psinablapsi=psinablapsi+psinablapsi_soc
     697              :            end if
     698         1230 :            if (store_half_dipoles) then
     699         7380 :              nc_start_5=[1,1,(jb*(jb-1))/2+1,ikpt,isppol];nc_stride_5=[1,1,1,1,1]
     700         4980 :              nc_count_5=[0,0,0,0,0];if (myband) nc_count_5=[2,3,jb,1,1]
     701         1230 :              NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     702              :            else
     703            0 :              nc_start_6=[1,1,1,jb,ikpt,isppol];nc_stride_6=[1,1,1,1,1,1]
     704            0 :              nc_count_6=[0,0,0,0,0,0];if (myband) nc_count_6=[2,3,mband,1,1,1]
     705            0 :              NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     706              :            end if
     707              :          end if
     708              : 
     709              :        end do ! jb
     710              : 
     711        16480 :        if (mkmem/=0) then
     712        16480 :          ibg = ibg +       my_nspinor*nband_cprj_k
     713        16480 :          icg = icg + npw_k*my_nspinor*nband_k
     714        16480 :          ikg = ikg + npw_k
     715              :        end if
     716              : 
     717        16480 :        if (cprj_paral_band) then
     718         6608 :          call pawcprj_free(cprj_k)
     719         6608 :          ABI_FREE(cprj_k)
     720              :        end if
     721        16480 :        if (mkmem*nsppol/=1) then
     722        16477 :          call pawcprj_free(cprj_k_loc)
     723        16477 :          ABI_FREE(cprj_k_loc)
     724              :        end if
     725        16480 :        ABI_FREE(kpg_k)
     726              : 
     727              : !      Write to OPT file if not MPI-IO
     728        16480 :        if (iomode /= NO_FILE_OUT) then
     729              : !        >>> Reduction in case of parallelism
     730          192 :          if (.not.iomode_etsf_mpiio) then
     731            0 :            call timab(48,1,tsec)
     732            0 :            call xmpi_sum_master(psinablapsi,master,spaceComm_bandspinorfft,ierr)
     733            0 :            call xmpi_sum_master(psinablapsi_paw,master,spaceComm_bandspinor,ierr)
     734            0 :            call timab(48,2,tsec)
     735            0 :            psinablapsi=psinablapsi+psinablapsi_paw
     736            0 :            if (dtset%pawspnorb==1) then
     737            0 :              call xmpi_sum_master(psinablapsi_soc,master,spaceComm_band,ierr)
     738            0 :              psinablapsi=psinablapsi+psinablapsi_soc
     739              :            end if
     740              :          end if
     741              : 
     742              : !        >>> This my kpt and I am the master node: I write the data
     743              :          if (.not.iomode_etsf_mpiio) then
     744            0 :            if (i_am_master) then
     745            0 :              if (iomode==IO_MODE_ETSF) then
     746              :                if (nc_unlimited) then
     747              :                  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]
     748              :                  NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     749            0 :                else if (.not.store_half_dipoles) then
     750            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]
     751            0 :                  NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     752              :                else
     753            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]
     754            0 :                  NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     755              :                end if
     756              :              else
     757            0 :                bsize=nband_k**2;if (store_half_dipoles) bsize=(nband_k*(nband_k+1))/2
     758            0 :                write(ount)(psinablapsi(1:2,1,ib),ib=1,bsize)
     759            0 :                write(ount)(psinablapsi(1:2,2,ib),ib=1,bsize)
     760            0 :                write(ount)(psinablapsi(1:2,3,ib),ib=1,bsize)
     761              :              end if
     762              : 
     763              : !          >>> This my kpt and I am not the master node: I send the data
     764            0 :            else if (i_am_master_band.and.i_am_master_spfft) then
     765            0 :              if (mpi_enreg%me_kpt/=master_spfftband) then
     766            0 :                ABI_BUG('Problem with band communicator!')
     767              :              end if
     768            0 :              call xmpi_exch(psinablapsi,pnp_size,mpi_enreg%me_kpt,psinablapsi,master,spaceComm_kpt,etiq,ierr)
     769              :            end if
     770              :          end if
     771              :        else
     772              : !        >>> Reduction in case of parallelism
     773        16288 :          call timab(48,1,tsec)
     774        16288 :          call xmpi_sum(psinablapsi,spaceComm_bandspinorfft,ierr)
     775        16288 :          call xmpi_sum(psinablapsi_paw,spaceComm_bandspinor,ierr)
     776        16288 :          call timab(48,2,tsec)
     777      2622368 :          psinablapsi=psinablapsi+psinablapsi_paw
     778        16288 :          if (dtset%pawspnorb==1) then
     779            0 :            call xmpi_sum(psinablapsi_soc,spaceComm_band,ierr)
     780            0 :            psinablapsi=psinablapsi+psinablapsi_soc
     781              :          end if
     782              :        end if ! no_file_out
     783              : 
     784              : !    >>> This is not my kpt and I am the master node: I receive the data and I write
     785        19634 :      elseif ((.not.iomode_etsf_mpiio).and.i_am_master.and.(iomode/=NO_FILE_OUT)) then ! mykpt
     786            0 :        sender=master_spfftband
     787            0 :        call xmpi_exch(psinablapsi,pnp_size,sender,psinablapsi,master,spaceComm_kpt,etiq,ierr)
     788            0 :        if (iomode==IO_MODE_ETSF) then
     789              :          if (nc_unlimited) then
     790              :            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]
     791              :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     792            0 :          else if (.not.store_half_dipoles) then
     793            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]
     794            0 :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_6,stride=nc_stride_6,count=nc_count_6))
     795              :          else
     796            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]
     797            0 :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi,start=nc_start_5,stride=nc_stride_5,count=nc_count_5))
     798              :          end if
     799              :        else
     800            0 :          bsize=nband_k**2;if (store_half_dipoles) bsize=(nband_k*(nband_k+1))/2
     801            0 :          write(ount)(psinablapsi(1:2,1,ib),ib=1,bsize)
     802            0 :          write(ount)(psinablapsi(1:2,2,ib),ib=1,bsize)
     803            0 :          write(ount)(psinablapsi(1:2,3,ib),ib=1,bsize)
     804              :        end if
     805              :      end if ! mykpt
     806              : 
     807        37261 :      bdtot_index=bdtot_index+nband_k
     808              : 
     809              : !    End loop on spin,kpt
     810              :    end do ! ikpt
     811              :  end do !isppol
     812              : 
     813              : ! >>> Last reduction over k-points in case of parallelism
     814              : ! >>> if no output to file
     815         1147 : if (iomode == NO_FILE_OUT) then
     816         1121 :   call xmpi_sum(psinablapsi_out,spaceComm_kpt,ierr)
     817              : end if
     818              : 
     819              : !Close file
     820         1147 :  if ((i_am_master.or.(iomode_etsf_mpiio.and.i_am_master_spfft)).and.iomode /= NO_FILE_OUT) then
     821           16 :    if (iomode==IO_MODE_ETSF) then
     822           16 :      NCF_CHECK(nf90_close(ncid))
     823              :    else
     824            0 :      ierr=close_unit(ount,msg)
     825            0 :      ABI_CHECK(ierr==0,"Error while closing OPT file")
     826              :    end if
     827              :  end if
     828              : 
     829              : !Datastructures deallocations
     830         1147 :  if (iomode /= NO_FILE_OUT) then
     831           26 :     ABI_FREE(psinablapsi)
     832              :  end if
     833         1147 :  ABI_FREE(psinablapsi_paw)
     834         1147 :  if (dtset%pawspnorb==1) then
     835            1 :    ABI_FREE(psinablapsi_soc)
     836            5 :    do iatom=1,natom
     837            5 :      ABI_FREE(phisocphj(iatom)%value)
     838              :    end do
     839            5 :    ABI_FREE(phisocphj)
     840              :  end if
     841         1147 :  if (.not.already_has_nabla) then
     842         2294 :    do itypat=1,dtset%ntypat
     843         2294 :      if (allocated(pawtab(itypat)%nabla_ij)) then
     844         1147 :        ABI_FREE(pawtab(itypat)%nabla_ij)
     845         1147 :        pawtab(itypat)%has_nabla=0
     846              :      end if
     847              :    end do
     848              :  end if
     849              : 
     850              :  DBG_EXIT("COLL")
     851              : 
     852         2294 :  end subroutine optics_paw
     853              : !!***
     854              : 
     855              : !----------------------------------------------------------------------
     856              : 
     857              : !!****f* m_paw_optics/optics_paw_core
     858              : !! NAME
     859              : !! optics_paw_core
     860              : !!
     861              : !! FUNCTION
     862              : !! Compute matrix elements need for X spectr. (in the PAW context) and store them in a file
     863              : !!  Matrix elements = <Phi_core|Nabla|Phi_j>
     864              : !!
     865              : !! COPYRIGHT
     866              : !! Copyright (C) 2005-2026 ABINIT group (SM,MT,NB)
     867              : !! This file is distributed under the terms of the
     868              : !! GNU General Public License, see ~ABINIT/COPYING
     869              : !! or http://www.gnu.org/copyleft/gpl.txt .
     870              : !!
     871              : !! INPUTS
     872              : !!  atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
     873              : !!  cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk> and each |p_lmn> non-local projector
     874              : !!  dimcprj(natom)=array of dimensions of array cprj (not ordered)
     875              : !!  dtfil <type(datafiles_type)>=variables related to files
     876              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     877              : !!  filpsp(ntypat)=name(s) of the pseudopotential file(s)
     878              : !!  mband=maximum number of bands
     879              : !!  mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
     880              : !!  mkmem =number of k points treated by this node.
     881              : !!  mpi_enreg=information about MPI parallelization
     882              : !!  mpsang =1+maximum angular momentum for nonlocal pseudopotentials
     883              : !!  natom=number of atoms in cell.
     884              : !!  nkpt=number of k points.
     885              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     886              : !!  pawang <type(pawang_type)>= PAW ANGular mesh discretization and related data
     887              : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
     888              : !!  pawrhoij(my_natom) <type(pawrhoij_type)>= PAW rhoij occupancies and related data
     889              : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
     890              : !!  znucl(ntypat)=atomic number of atom type
     891              : !!
     892              : !! OUTPUT
     893              : !!  (only writing in a file)
     894              : !!
     895              : !! SOURCE
     896              : 
     897            3 :  subroutine optics_paw_core(atindx1,cprj,dimcprj,dtfil,dtset,eigen0,filpsp,hdr,&
     898              : &               mband,mcprj,mkmem,mpi_enreg,mpsang,natom,nkpt,nsppol,&
     899            3 : &               pawang,pawrad,pawrhoij,pawtab,znucl,rcpaw)
     900              : 
     901              : !Arguments ------------------------------------
     902              : !scalars
     903              :  integer,intent(in) :: mband,mcprj,mkmem,mpsang,natom,nkpt,nsppol
     904              :  type(MPI_type),intent(in) :: mpi_enreg
     905              :  type(datafiles_type),intent(in) :: dtfil
     906              :  type(dataset_type),intent(in) :: dtset
     907              :  type(hdr_type),intent(inout) :: hdr
     908              :  type(pawang_type),intent(in) :: pawang
     909              :  type(rcpaw_type), intent(in), pointer,optional :: rcpaw
     910              : !arrays
     911              :  integer,intent(in) :: atindx1(natom),dimcprj(natom)
     912              :  character(len=fnlen),intent(in) :: filpsp(dtset%ntypat)
     913              :  real(dp),intent(in) :: eigen0(mband*nkpt*nsppol),znucl(dtset%ntypat)
     914              :  type(pawcprj_type),target,intent(inout) :: cprj(natom,mcprj)
     915              :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
     916              :  type(pawrhoij_type),intent(inout) :: pawrhoij(mpi_enreg%my_natom)
     917              :  type(pawtab_type),target,intent(inout) :: pawtab(dtset%ntypat)
     918              : 
     919              : !Local variables-------------------------------
     920              : !scalars
     921              :  integer,parameter :: master=0
     922              :  integer :: bdtot_index,cplex,etiq,iatom,ic,ibg,idir,ilmn2
     923              :  integer :: ierr,ikpt,ilmn,iln,ount,is,my_jb,nphicor_lm
     924              :  integer :: iorder_cprj,ispinor,isppol,istwf_k,itypat,itypat2
     925              :  integer :: jb,jbsp,jlmn,lmn_size,lmncmax,mband_cprj,ncid,varid
     926              :  integer :: me,my_nspinor,nband_cprj_k,option_core,pnp_size
     927              :  integer :: nband_k,nphicor,ncorespinor,sender,iomode,fformopt,master_spfftband
     928              :  integer :: spaceComm_band,spaceComm_bandspinorfft,spaceComm_fft,spaceComm_kpt
     929              :  integer :: spaceComm_spinor,spaceComm_bandspinor,spaceComm_spinorfft,spaceComm_w
     930              :  logical :: already_has_nabla,cprj_paral_band,mykpt,myband,use_rcpaw_data
     931              :  logical :: iomode_etsf_mpiio,use_spinorbit
     932              :  logical :: i_am_master,i_am_master_band,i_am_master_spfft
     933              :  real(dp) :: cpnm1,cpnm2,el_temp
     934              :  character(len=500) :: msg
     935              : !arrays
     936              :  integer :: nc_count(6),nc_start(6),nc_stride(6),tmp_shape(3)
     937            3 :  integer,allocatable :: lcor(:,:),ncor(:,:),kappacor(:,:),nphicor_arr(:),lmn2ln(:,:)
     938              :  real(dp) :: tsec(2)
     939            3 :  real(dp),allocatable :: energy_cor(:,:),occ_cor(:,:),maxocc_cor(:,:)
     940            3 :  real(dp),allocatable :: psinablapsi(:,:,:,:,:),psinablapsi_soc(:,:,:,:,:),psinablapsi2(:,:,:,:)
     941            3 :  real(dp),pointer :: soc_ij(:,:,:)
     942            3 :  type(coeff5_type),allocatable,target :: phisocphj(:)
     943            3 :  type(pawcprj_type),pointer :: cprj_k(:,:),cprj_k_loc(:,:)
     944              :  type(nctkdim_t) :: ncdims(3)
     945              :  type(nctkarr_t) :: nctk_arrays(9)
     946            3 :  type(atomorb_type),allocatable :: atm(:)
     947              : 
     948              : ! ************************************************************************
     949              : 
     950              :  DBG_ENTER("COLL")
     951              : 
     952              : !Compatibility tests
     953            3 :  msg="mkmem==0 not supported anymore!"
     954            0 :  ABI_CHECK(mkmem/=0,msg)
     955              : !Probably should check for spinor parallelism, because thats likely to not work correctly
     956            3 :  msg="Spinor parallelism not implemented for optics_paw_core!"
     957            3 :  ABI_CHECK(dtset%npspinor==1,msg)
     958              : !Is mpi_enreg initialized?
     959              :  if (xmpi_paral==1) then
     960           12 :    tmp_shape = shape(mpi_enreg%proc_distrb)
     961            3 :    if (nkpt > tmp_shape(1)) then
     962            0 :      ABI_BUG('problem with proc_distrb!')
     963              :    end if
     964              :  end if
     965              : 
     966              : !Init parallelism
     967            3 :  spaceComm_w=mpi_enreg%comm_cell
     968            3 :  if (mpi_enreg%paral_kgb==1) then
     969            0 :    spaceComm_kpt=mpi_enreg%comm_kpt
     970            0 :    spaceComm_fft=mpi_enreg%comm_fft
     971            0 :    spaceComm_band=mpi_enreg%comm_band
     972            0 :    spaceComm_spinor=mpi_enreg%comm_spinor
     973            0 :    spaceComm_bandspinor=mpi_enreg%comm_bandspinor
     974            0 :    spaceComm_spinorfft=mpi_enreg%comm_spinorfft
     975            0 :    spaceComm_bandspinorfft=mpi_enreg%comm_bandspinorfft
     976              :  else
     977            3 :    spaceComm_kpt=mpi_enreg%comm_kpt
     978            3 :    spaceComm_fft=xmpi_comm_self
     979            3 :    spaceComm_band=mpi_enreg%comm_band
     980            3 :    spaceComm_spinor=xmpi_comm_self
     981            3 :    spaceComm_bandspinor=spaceComm_band
     982            3 :    spaceComm_spinorfft=xmpi_comm_self
     983            3 :    spaceComm_bandspinorfft=xmpi_comm_self
     984              :  end if
     985            3 :  me=xmpi_comm_rank(spaceComm_w)
     986            3 :  i_am_master=(me==master)
     987            3 :  i_am_master_band=(xmpi_comm_rank(spaceComm_band)==master)
     988            3 :  i_am_master_spfft=(xmpi_comm_rank(spaceComm_spinorfft)==master)
     989            3 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     990              : 
     991              : !------------------------------------------------------------------------------------------------
     992              : !1- Reading of core wavefunctions
     993              : !------------------------------------------------------------------------------------------------
     994              :  !TODO At present, impose 2-spinor simulataneously for core and valence WF
     995           12 :  ABI_MALLOC(atm,(dtset%ntypat))
     996            6 :  do itypat=1,dtset%ntypat
     997            3 :    use_rcpaw_data=.false.
     998            3 :    if(present(rcpaw)) then
     999            1 :      if(associated(rcpaw)) then
    1000            1 :        if(allocated(rcpaw%atm)) then
    1001            1 :          if(dtset%ntypat==size(rcpaw%atm)) then
    1002            1 :            call copy_atomorb(rcpaw%atm(itypat),atm(itypat))
    1003              :            use_rcpaw_data=.true.
    1004              :          endif
    1005              :        endif
    1006              :      endif
    1007              :    endif
    1008            3 :    if(.not.use_rcpaw_data) then
    1009            2 :      call pawpsp_init_core(atm(itypat),filpsp(itypat),radmesh=pawrad(itypat))
    1010              :    endif
    1011              :  enddo
    1012              : 
    1013            3 :  if(dtset%cwfs_wouth==1) then
    1014            0 :    do itypat=1,dtset%ntypat
    1015            0 :      if(atm(itypat)%mult==1) then
    1016            0 :        do itypat2=1,dtset%ntypat
    1017              :          if(atm(itypat2)%mult>1.and.atm(itypat2)%znucl==atm(itypat)%znucl.and.&
    1018              : &           atm(itypat2)%mesh_size==atm(itypat)%mesh_size.and.&
    1019              : &           atm(itypat2)%ln_size==atm(itypat)%ln_size.and.&
    1020            0 : &           atm(itypat2)%nsppol==atm(itypat)%nsppol.and.&
    1021            0 : &           atm(itypat2)%zcore_orig>atm(itypat)%zcore_orig) then
    1022            0 :            write(std_out,*) 'Core wfs of typat ',itypat,' replaced by those of typat ',itypat2
    1023            0 :            atm(itypat)%phi=atm(itypat2)%phi
    1024              :            exit
    1025              :          endif
    1026              :        enddo
    1027              :      endif
    1028              :    enddo
    1029              :  endif
    1030              : 
    1031              : 
    1032            3 :  nphicor=0
    1033            3 :  ncorespinor=0
    1034            3 :  nphicor_lm=0
    1035            6 :  do itypat=1,dtset%ntypat
    1036            3 :    nphicor=max(nphicor,atm(itypat)%ln_size)
    1037            3 :    nphicor_lm=max(nphicor,atm(itypat)%lmn_size)
    1038            3 :    if(atm(itypat)%nsppol>1) ABI_ERROR("nsppol>1 is work in progress for optics_paw_core")
    1039            3 :    if(atm(itypat)%nspinor/=dtset%nspinor) ABI_ERROR("Core and valence not same number of spinors")
    1040            6 :    ncorespinor=max(ncorespinor,atm(itypat)%nspinor)
    1041              :  enddo
    1042            3 :  if(dtset%nspinor==2) nphicor_lm=nphicor_lm/2
    1043              : 
    1044           12 :  ABI_MALLOC(lmn2ln,(nphicor_lm,dtset%ntypat))
    1045           31 :  lmn2ln=0
    1046            6 :  do itypat=1,dtset%ntypat
    1047            3 :    lmncmax=atm(itypat)%lmn_size
    1048            3 :    if(dtset%nspinor==2) lmncmax=lmncmax/2
    1049           31 :    do ilmn=1,lmncmax
    1050           28 :      if(dtset%nspinor==1) then
    1051            5 :        lmn2ln(ilmn,itypat)=atm(itypat)%indlmn(5,ilmn)
    1052              :      else
    1053          198 :        do ilmn2=1,atm(itypat)%lmn_size
    1054          198 :          if(atm(itypat)%indlmn(9,ilmn2)==ilmn) then
    1055           20 :            lmn2ln(ilmn,itypat)=atm(itypat)%indlmn(5,ilmn2)
    1056           20 :            exit
    1057              :          endif
    1058              :        enddo
    1059              :      endif
    1060              :    enddo
    1061              :  enddo
    1062              : 
    1063              : !----------------------------------------------------------------------------------
    1064              : !2- Computation of phipphj=<phi_i|nabla|phi_core>
    1065              : !----------------------------------------------------------------------------------
    1066              : 
    1067            3 :  already_has_nabla=all(pawtab(:)%has_nabla==3)
    1068            3 :  if (ncorespinor==2) already_has_nabla=all(pawtab(:)%has_nabla==4)
    1069              : !  Should check whether this would work with spinor parallelism
    1070            3 :  call pawnabla_core_init(mpsang,dtset%ntypat,pawrad,pawtab,atm)
    1071              : 
    1072              : !Get electronic temperature from dtset
    1073            3 :  el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
    1074              : 
    1075              : !Compute spin-orbit contributions if necessary
    1076            3 :  use_spinorbit=(dtset%pawspnorb==1.and.dtset%userie/=111) ! For testing purpose
    1077              :  if (use_spinorbit) then
    1078            2 :    option_core=1
    1079              :    call pawnabla_soc_init(el_temp,phisocphj,option_core,dtset%ixc,mpi_enreg%my_natom,natom,&
    1080              : &       dtset%nspden,dtset%ntypat,pawang,pawrad,pawrhoij,pawtab,dtset%pawxcdev,&
    1081              : &       dtset%spnorbscl,dtset%typat,dtset%xc_denpos,dtset%xc_taupos,znucl,&
    1082            2 : &       atm=atm,comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab)
    1083              :  end if
    1084              : 
    1085              : !----------------------------------------------------------------------------------
    1086              : !3- Opening of OPT2 file and header writing
    1087              : !----------------------------------------------------------------------------------
    1088              : 
    1089              : !I/O mode is netCDF or Fortran
    1090              :  iomode=merge(IO_MODE_ETSF,IO_MODE_FORTRAN_MASTER,dtset%iomode==IO_MODE_ETSF)
    1091            3 :  if (use_netcdf_forced) iomode=IO_MODE_ETSF
    1092              : 
    1093           12 :  ABI_MALLOC(energy_cor,(nphicor,dtset%ntypat))
    1094           12 :  ABI_MALLOC(ncor,(nphicor,dtset%ntypat))
    1095            9 :  ABI_MALLOC(lcor,(nphicor,dtset%ntypat))
    1096            9 :  ABI_MALLOC(kappacor,(nphicor,dtset%ntypat))
    1097            9 :  ABI_MALLOC(occ_cor,(nphicor,dtset%ntypat))
    1098            9 :  ABI_MALLOC(maxocc_cor,(nphicor,dtset%ntypat))
    1099           17 :  energy_cor=zero
    1100           17 :  ncor=0
    1101           17 :  lcor=0
    1102           17 :  kappacor=0
    1103           17 :  occ_cor=zero 
    1104           17 :  maxocc_cor=zero
    1105            6 :  do itypat=1,dtset%ntypat
    1106           17 :    do iln=1,atm(itypat)%ln_size
    1107           11 :      energy_cor(iln,itypat)=atm(itypat)%eig(iln,1)
    1108           11 :      ncor(iln,itypat)=atm(itypat)%indln(2,iln)
    1109           11 :      lcor(iln,itypat)=atm(itypat)%indln(1,iln)
    1110           11 :      occ_cor(iln,itypat)=atm(itypat)%occ(iln,1)
    1111           11 :      maxocc_cor(iln,itypat)=atm(itypat)%max_occ(iln,1)
    1112           14 :      if(atm(itypat)%dirac) then
    1113            8 :        kappacor(iln,itypat)=atm(itypat)%kappa(iln)
    1114              :      else
    1115            3 :        kappacor(iln,itypat)=0
    1116              :      endif
    1117              :    enddo
    1118              :  enddo
    1119              : 
    1120              :  !(master proc only)
    1121            3 :  if (i_am_master) then
    1122              : !  ====> NETCDF format
    1123              :    if (iomode==IO_MODE_ETSF) then
    1124            3 :      fformopt=611
    1125            9 :      ABI_MALLOC(nphicor_arr,(dtset%ntypat))
    1126            6 :      do itypat=1,dtset%ntypat
    1127            6 :        nphicor_arr(itypat)=atm(itypat)%ln_size
    1128              :      enddo
    1129              : !    Open/create nc file
    1130            3 :      NCF_CHECK(nctk_open_create(ncid,nctk_ncify(dtfil%fnameabo_app_opt2),xmpi_comm_self))
    1131              : !    Write header data
    1132            3 :      NCF_CHECK(hdr%ncwrite(ncid,fformopt,nc_define=.true.))
    1133              : !    Define additional dimensions
    1134            3 :      ncdims(1)%name="number_of_atom_types"
    1135            3 :      ncdims(1)%value=dtset%ntypat
    1136            3 :      ncdims(2)%name="max_number_of_core_states"
    1137            3 :      ncdims(2)%value=nphicor
    1138            3 :      ncdims(3)%name="number_of_core_spinor_components"
    1139            3 :      ncdims(3)%value=ncorespinor
    1140            3 :      NCF_CHECK(nctk_def_dims(ncid,ncdims))
    1141            3 :      nctk_arrays(1)%name="number_of_core_states"
    1142            3 :      nctk_arrays(1)%dtype="int"
    1143            3 :      nctk_arrays(1)%shape_str="number_of_atom_types"
    1144            3 :      nctk_arrays(2)%name="eigenvalues_core"
    1145            3 :      nctk_arrays(2)%dtype="dp"
    1146            3 :      nctk_arrays(2)%shape_str="max_number_of_core_states,number_of_atom_types"
    1147            3 :      nctk_arrays(3)%name="dipole_core_valence"
    1148            3 :      nctk_arrays(3)%dtype="dp"
    1149              :      nctk_arrays(3)%shape_str=&
    1150              : &     "number_of_cartesian_directions,max_number_of_core_states,"// &
    1151            3 : &     "number_of_atoms,max_number_of_states,number_of_kpoints,number_of_spins"
    1152            3 :      nctk_arrays(4)%name="n_quantum_number_core"
    1153            3 :      nctk_arrays(4)%dtype="int"
    1154            3 :      nctk_arrays(4)%shape_str="max_number_of_core_states,number_of_atom_types"
    1155            3 :      nctk_arrays(5)%name="l_quantum_number_core"
    1156            3 :      nctk_arrays(5)%dtype="int"
    1157            3 :      nctk_arrays(5)%shape_str="max_number_of_core_states,number_of_atom_types"
    1158            3 :      nctk_arrays(6)%name="kappa_core"
    1159            3 :      nctk_arrays(6)%dtype="int"
    1160            3 :      nctk_arrays(6)%shape_str="max_number_of_core_states,number_of_atom_types"
    1161            3 :      nctk_arrays(7)%name="number_of_core_states"
    1162            3 :      nctk_arrays(7)%dtype="int"
    1163            3 :      nctk_arrays(7)%shape_str="number_of_atom_types"
    1164            3 :      nctk_arrays(8)%name="occupation_core"
    1165            3 :      nctk_arrays(8)%dtype="dp"
    1166            3 :      nctk_arrays(8)%shape_str="max_number_of_core_states,number_of_atom_types"
    1167            3 :      nctk_arrays(9)%name="max_occupation_core"
    1168            3 :      nctk_arrays(9)%dtype="dp"
    1169            3 :      nctk_arrays(9)%shape_str="max_number_of_core_states,number_of_atom_types"
    1170            3 :      NCF_CHECK(nctk_def_arrays(ncid, nctk_arrays))
    1171            3 :      NCF_CHECK(nctk_set_atomic_units(ncid, "eigenvalues_core"))
    1172            3 :      NCF_CHECK(nctk_set_atomic_units(ncid, "dipole_core_valence"))
    1173              : !    Write core states
    1174            3 :      NCF_CHECK(nctk_set_datamode(ncid))
    1175            3 :      varid=nctk_idname(ncid,"eigenvalues_core")
    1176            3 :      NCF_CHECK(nf90_put_var(ncid,varid,energy_cor))
    1177            3 :      varid=nctk_idname(ncid,"n_quantum_number_core")
    1178            3 :      NCF_CHECK(nf90_put_var(ncid,varid,ncor))
    1179            3 :      varid=nctk_idname(ncid,"l_quantum_number_core")
    1180            3 :      NCF_CHECK(nf90_put_var(ncid,varid,lcor))
    1181            3 :      varid=nctk_idname(ncid,"kappa_core")
    1182            3 :      NCF_CHECK(nf90_put_var(ncid,varid,kappacor))
    1183            3 :      varid=nctk_idname(ncid,"occupation_core")
    1184            3 :      NCF_CHECK(nf90_put_var(ncid,varid,occ_cor))
    1185            3 :      varid=nctk_idname(ncid,"max_occupation_core")
    1186            3 :      NCF_CHECK(nf90_put_var(ncid,varid,maxocc_cor))
    1187            3 :      varid=nctk_idname(ncid,"number_of_core_states")
    1188            3 :      NCF_CHECK(nf90_put_var(ncid,varid,nphicor_arr))
    1189              : !    Write eigenvalues
    1190            3 :      varid=nctk_idname(ncid,"eigenvalues")
    1191           12 :      NCF_CHECK(nf90_put_var(ncid,varid,reshape(eigen0,[mband,nkpt,nsppol])))
    1192              :      !Close file here because the rest has possibly to be written with collective I/O
    1193            3 :      NCF_CHECK(nf90_close(ncid))
    1194            3 :      ABI_FREE(nphicor_arr)
    1195              : !  ====> Standard FORTRAN binary file format
    1196              :    else if (iomode==IO_MODE_FORTRAN_MASTER) then
    1197              :      fformopt=612  ! MT 12sept21: change the OPT2 Fortran file format
    1198              :      if (2*nphicor*natom*mband>2**30) fformopt=613 ! Format for large file records
    1199              :      if (open_file(dtfil%fnameabo_app_opt2,msg,newunit=ount,form="unformatted",status="unknown")/= 0) then
    1200              :        ABI_ERROR(msg)
    1201              :      end if
    1202              :      call hdr%fort_write(ount,fformopt,ierr,rewind=.true.)
    1203              :      write(ount)(eigen0(jb),jb=1,mband*nkpt*nsppol)
    1204              :      write(ount) nphicor
    1205              :      do itypat=1,dtset%ntypat
    1206              :        write(ount) atm(itypat)%ln_size
    1207              :        do iln=1,nphicor
    1208              :          write(ount) ncor(iln,itypat),lcor(iln,itypat),kappacor(iln,itypat),occ_cor(iln,itypat),maxocc_cor(iln,itypat),&
    1209              :                      energy_cor(iln,itypat)
    1210              :        end do
    1211              :      enddo
    1212              :    else
    1213              :      msg = "Wrong OPT2 file format!"
    1214              :      ABI_BUG(msg)
    1215              :    end if ! File format
    1216              :  end if ! master node
    1217            3 :  call xmpi_bcast(iomode,master,spaceComm_w,ierr)  ! Seems mandatory; why ?
    1218            3 :  call xmpi_bcast(fformopt,master,spaceComm_w,ierr)
    1219            3 :  iomode_etsf_mpiio=(iomode==IO_MODE_ETSF.and.nctk_has_mpiio.and.use_netcdf_mpiio)
    1220              : 
    1221            3 :  ABI_FREE(ncor)
    1222            3 :  ABI_FREE(lcor)
    1223            3 :  ABI_FREE(kappacor)
    1224            3 :  ABI_FREE(occ_cor)
    1225            3 :  ABI_FREE(maxocc_cor)
    1226            3 :  ABI_FREE(energy_cor)
    1227              : 
    1228              : !----------------------------------------------------------------------------------
    1229              : !4- Computation of <psi_n|p_i>(<phi_i|-i.nabla|phi_core>)
    1230              : !----------------------------------------------------------------------------------
    1231              : 
    1232              : !Prepare core-valence dipoles writing
    1233              : !In case of netCDF access to OPT2 file, prepare collective I/O
    1234            3 :  if (iomode == IO_MODE_ETSF) then
    1235            3 :    if (iomode_etsf_mpiio) then
    1236            3 :      if (i_am_master_spfft) then
    1237            3 :        NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt2),spaceComm_band))
    1238            3 :        varid=nctk_idname(ncid,"dipole_core_valence")
    1239            3 :        if (xmpi_comm_size(spaceComm_w)>1) then
    1240            0 :          NCF_CHECK(nctk_set_collective(ncid,varid))
    1241              :        end if
    1242            3 :        NCF_CHECK(nctk_set_datamode(ncid))
    1243              :      end if
    1244            0 :    else if (i_am_master) then
    1245            0 :      NCF_CHECK(nctk_open_modify(ncid,nctk_ncify(dtfil%fnameabo_app_opt2),xmpi_comm_self))
    1246            0 :      varid=nctk_idname(ncid,"dipole_core_valence")
    1247              :      if (nctk_has_mpiio.and.(.not.use_netcdf_mpiio)) then
    1248              :        NCF_CHECK(nctk_set_collective(ncid,varid))
    1249              :      end if
    1250            0 :      NCF_CHECK(nctk_set_datamode(ncid))
    1251              :    end if
    1252              :  end if
    1253            3 :  if (iomode_etsf_mpiio) then
    1254              :    !If MPI-IO, store only elements for one band
    1255           12 :    ABI_MALLOC(psinablapsi,(2,3,nphicor_lm,natom,1))
    1256           12 :    ABI_MALLOC(psinablapsi2,(3,nphicor,natom,1))
    1257            3 :    if (use_spinorbit) then
    1258            6 :      ABI_MALLOC(psinablapsi_soc,(2,3,nphicor_lm,natom,1))
    1259              :    end if
    1260              :  else
    1261              :    !If not, store the elements for all bands
    1262            0 :    ABI_MALLOC(psinablapsi,(2,3,nphicor_lm,natom,mband))
    1263            0 :    ABI_MALLOC(psinablapsi2,(3,nphicor,natom,mband))
    1264            0 :    if (use_spinorbit) then
    1265            0 :      ABI_MALLOC(psinablapsi_soc,(2,3,nphicor_lm,natom,mband))
    1266              :    end if
    1267              :  end if
    1268           15 :  pnp_size=size(psinablapsi2)
    1269              : 
    1270              : !Determine if cprj datastructure is distributed over bands
    1271            3 :  mband_cprj=mcprj/(my_nspinor*mkmem*nsppol)
    1272            3 :  cprj_paral_band=(mband_cprj<mband)
    1273              : 
    1274              : !LOOP OVER SPINS
    1275            3 :  ibg=0
    1276            3 :  bdtot_index=0
    1277            6 :  do isppol=1,nsppol
    1278              : 
    1279              : !  LOOP OVER k POINTS
    1280            9 :    do ikpt=1,nkpt
    1281              : 
    1282            3 :      etiq=ikpt+(isppol-1)*nkpt
    1283            3 :      nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
    1284           53 :      master_spfftband=minval(mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol))
    1285              : 
    1286              : !    Select k-points for current proc
    1287            3 :      mykpt=.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,mpi_enreg%me_kpt))
    1288            3 :      if (mykpt) then
    1289              : 
    1290              : !      Data depending on k-point
    1291            3 :        istwf_k=dtset%istwfk(ikpt)
    1292            3 :        cplex=2;if (istwf_k>1) cplex=1
    1293              : 
    1294              : !      Extract cprj for this k-point
    1295            3 :        nband_cprj_k=nband_k;if (cprj_paral_band) nband_cprj_k=nband_k/mpi_enreg%nproc_band
    1296            3 :        if (mkmem*nsppol/=1) then
    1297            0 :          iorder_cprj=0
    1298            0 :          ABI_MALLOC(cprj_k_loc,(natom,my_nspinor*nband_cprj_k))
    1299            0 :          call pawcprj_alloc(cprj_k_loc,0,dimcprj)
    1300              :          call pawcprj_get(atindx1,cprj_k_loc,cprj,natom,1,ibg,ikpt,iorder_cprj,isppol,&
    1301              : &         mband_cprj,mkmem,natom,nband_cprj_k,nband_cprj_k,my_nspinor,nsppol,dtfil%unpaw,&
    1302            0 : &         mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
    1303              :        else
    1304            3 :          cprj_k_loc => cprj
    1305              :        end if
    1306              : 
    1307              : !      if cprj are distributed over bands, gather them (because we need to mix bands)
    1308            3 :        if (cprj_paral_band) then
    1309            0 :          ABI_MALLOC(cprj_k,(natom,my_nspinor*nband_k))
    1310            0 :          call pawcprj_alloc(cprj_k,0,dimcprj)
    1311              :          call pawcprj_mpi_allgather(cprj_k_loc,cprj_k,natom,my_nspinor*nband_cprj_k, &
    1312              : &                                   my_nspinor*mpi_enreg%bandpp,&
    1313            0 : &         dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band,ierr,rank_ordered=.false.)
    1314              :        else
    1315            3 :          cprj_k => cprj_k_loc
    1316              :        end if
    1317              : 
    1318              : !      Loops over bands
    1319           53 :        do jb=1,nband_k
    1320              :          !If MPI-IO, store only ib elements for each jb ; if not, store all (ib,jb) pairs
    1321           50 :          my_jb=merge(1,jb,iomode_etsf_mpiio)
    1322              : 
    1323        12190 :          psinablapsi(:,:,:,:,my_jb)=zero
    1324         2270 :          psinablapsi2(:,:,:,my_jb)=zero
    1325        10150 :          if (use_spinorbit) psinablapsi_soc(:,:,:,:,my_jb)=zero
    1326              : 
    1327              : !        Computation of <psi_n|p_i><phi_i|-i.nabla|phi_core>
    1328              : !        ----------------------------------------------------------------------------------
    1329              : 
    1330              : !        Select bands for current proc
    1331           50 :          myband=.true.
    1332           50 :          if (mpi_enreg%paral_kgb==1) then
    1333            0 :            myband=(mod(jb-1,mpi_enreg%nproc_band)==mpi_enreg%me_band)
    1334           50 :          else if (xmpi_paral==1) then
    1335           50 :            myband=(abs(mpi_enreg%proc_distrb(ikpt,jb,isppol)-mpi_enreg%me_kpt)==0)
    1336              :          end if
    1337           50 :          if (myband) then
    1338              : 
    1339           50 :            jbsp=(jb-1)*my_nspinor
    1340              : 
    1341              : !          1-spinor case
    1342           50 :            if (dtset%nspinor==1.and.ncorespinor==1) then
    1343           10 :              jbsp=jbsp+1
    1344           10 :              if (cplex==1) then ! Real WF case
    1345            0 :                do iatom=1,natom
    1346            0 :                  itypat=dtset%typat(iatom)
    1347            0 :                  lmn_size=pawtab(itypat)%lmn_size
    1348            0 :                  lmncmax=atm(itypat)%lmn_size
    1349            0 :                  do jlmn=1,lmn_size
    1350            0 :                    do ilmn=1,lmncmax
    1351            0 :                      ic=ilmn !atm(itypat)%indlmn(5,ilmn)
    1352            0 :                      cpnm1=cprj_k(iatom,jbsp)%cp(1,jlmn)
    1353              :                      psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    1354            0 : &                        -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    1355              :                    end do !ilmn
    1356              :                  end do !jlmn
    1357              :                end do !iatom
    1358              :              else ! Complex WF case
    1359           50 :                do iatom=1,natom
    1360           40 :                  itypat=dtset%typat(iatom)
    1361           40 :                  lmn_size=pawtab(itypat)%lmn_size
    1362           40 :                  lmncmax=atm(itypat)%lmn_size
    1363          370 :                  do jlmn=1,lmn_size
    1364         1960 :                    do ilmn=1,lmncmax
    1365         1600 :                      ic=ilmn !atm(itypat)%indlmn(5,ilmn)
    1366         1600 :                      cpnm1=cprj_k(iatom,jbsp)%cp(1,jlmn)
    1367         1600 :                      cpnm2=cprj_k(iatom,jbsp)%cp(2,jlmn)
    1368              :                      psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    1369         6400 : &                        -cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    1370              :                      psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    1371         6720 : &                        -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    1372              :                    end do !ilmn
    1373              :                  end do !jlmn
    1374              :                end do !iatom
    1375              :              end if
    1376              : 
    1377              : !          2-spinor case
    1378           40 :            else if (dtset%nspinor==2.and.ncorespinor==2) then
    1379          120 :              do ispinor=1,my_nspinor
    1380           80 :                jbsp=jbsp+1
    1381          320 :                do iatom=1,natom
    1382          200 :                  itypat=dtset%typat(iatom)
    1383          200 :                  lmn_size=pawtab(itypat)%lmn_size
    1384          200 :                  lmncmax=atm(itypat)%lmn_size
    1385         2280 :                  do jlmn=1,lmn_size
    1386        42200 :                    do ilmn=1,lmncmax
    1387        40000 :                      is=atm(itypat)%indlmn(6,ilmn)
    1388        42000 :                      if (modulo(jbsp,2)==modulo(is,2)) then ! Nabla is a spin-diagonal operator
    1389        20000 :                        ic=atm(itypat)%indlmn(9,ilmn)
    1390        20000 :                        if (ic>0) then
    1391        14000 :                          cpnm1=cprj_k(iatom,jbsp)%cp(1,jlmn)
    1392        14000 :                          cpnm2=cprj_k(iatom,jbsp)%cp(2,jlmn)
    1393              :                          psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    1394              : &                            +cpnm1*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn) &
    1395        56000 : &                            -cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    1396              :                          psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    1397              : &                            -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn) &
    1398        56000 : &                            -cpnm2*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn)
    1399              :                        end if
    1400              :                      end if
    1401              :                    end do ! ilmn
    1402              :                  end do !jlmn
    1403              :                end do !iatom
    1404              :              end do !ispinor
    1405              :            else
    1406            0 :              msg="Core and valence WF should have the same spinor representation!"
    1407            0 :              ABI_BUG(msg)
    1408              :              !N. Brouwer initial coding: should be justified!
    1409              :              !if (dtset%nspinor==1.and.ncorespinor==2) then  ! Average core spinors
    1410              :              !  psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    1411              :              ! &    +half_sqrt2*(cpnm1*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn) &
    1412              :              ! &                +cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn))
    1413              :              !  psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    1414              :              ! &    +half_sqrt2*(cpnm2*pawtab(itypat)%nabla_im_ij(:,jlmn,ilmn) &
    1415              :              ! &                -cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn))
    1416              :              !else if (dtset%nspinor==2.and.ncorespinor==1) then ! Average valence spinors
    1417              :              !  psinablapsi(1,:,ic,iatom,my_jb)=psinablapsi(1,:,ic,iatom,my_jb) &
    1418              :              ! &    +half_sqrt2*cpnm2*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    1419              :              !  psinablapsi(2,:,ic,iatom,my_jb)=psinablapsi(2,:,ic,iatom,my_jb) &
    1420              :              ! &    -half_sqrt2*cpnm1*pawtab(itypat)%nabla_ij(:,jlmn,ilmn)
    1421              :              !endif
    1422              :            endif
    1423              : 
    1424              : !          Spin-orbit coupling contribution:
    1425              : !             Sum_i,ss'[<psi^s_n|p_i><phi_i|1/4 Alpha^2 (Sigma^ss' X dV/dr)|phj_core^s'>]
    1426           50 :            if (use_spinorbit) then
    1427              : !            Add: Sum_i,ss'[<Psi^s_n|p_i> (Sigma^ss' X g_ij_core^s']
    1428              : !             where: g_ij_core^s = <Phi_i| 1/4 Alpha^2 dV/dr vec(r)/r) |Phj_core^s>
    1429              : !            Note that:
    1430              : !             if phi_cor_jlmn_cor(:) is up:
    1431              : !              phisocphj(:)%value(re:im,1,idir,ilmn,jlmn_cor) is (Sigma^up-up X g_ij_core^up)
    1432              : !              phisocphj(:)%value(re:im,2,idir,ilmn,jlmn_cor) is (Sigma^dn-up X g_ij_core^up)
    1433              : !             if phi_cor_jlmn_cor(:) is down:
    1434              : !              phisocphj(:)%value(re:im,1,idir,ilmn,jlmn_cor) is (Sigma^up-dn X g_ij_core^dn)
    1435              : !              phisocphj(:)%value(re:im,2,idir,ilmn,jlmn_cor) is (Sigma^dn-dn X g_ij_core^dn)
    1436              : !            Not compatible with parallelization over spinors
    1437           40 :              jbsp=1+(jb-1)*dtset%nspinor
    1438          140 :              do iatom=1,natom
    1439          100 :                itypat=dtset%typat(iatom)
    1440          100 :                lmn_size=pawtab(itypat)%lmn_size
    1441          100 :                lmncmax=atm(itypat)%lmn_size
    1442         1140 :                do jlmn=1,lmn_size
    1443        21100 :                  do ilmn=1,lmncmax
    1444        20000 :                    if(dtset%nspinor==1) then
    1445              :                      ic=ilmn !atm(itypat)%indlmn(5,ilmn)
    1446              :                    else
    1447        20000 :                      ic=atm(itypat)%indlmn(9,ilmn)
    1448              :                    endif
    1449        21000 :                    if (ic>0) then
    1450        14000 :                      soc_ij => phisocphj(iatom)%value(:,:,:,jlmn,ilmn)
    1451              :                      !Contribution from real part of <Psi^s_n|p_i>
    1452        14000 :                      cpnm1=cprj_k(iatom,jbsp  )%cp(1,jlmn)
    1453        14000 :                      cpnm2=cprj_k(iatom,jbsp+1)%cp(1,jlmn)
    1454        56000 :                      do idir=1,3
    1455              :                        psinablapsi_soc(1,idir,ic,iatom,my_jb)=psinablapsi_soc(1,idir,ic,iatom,my_jb) &
    1456        42000 : &                             +soc_ij(1,1,idir)*cpnm1+soc_ij(1,2,idir)*cpnm2
    1457              :                        psinablapsi_soc(2,idir,ic,iatom,my_jb)=psinablapsi_soc(2,idir,ic,iatom,my_jb) &
    1458        56000 : &                             +soc_ij(2,1,idir)*cpnm1+soc_ij(2,2,idir)*cpnm2
    1459              :                      end do
    1460              :                      !Contribution from imaginary part of <Psi^s_n|p_i>
    1461        14000 :                      cpnm1=cprj_k(iatom,jbsp  )%cp(2,jlmn)
    1462        14000 :                      cpnm2=cprj_k(iatom,jbsp+1)%cp(2,jlmn)
    1463        56000 :                      do idir=1,3
    1464              :                        psinablapsi_soc(1,idir,ic,iatom,my_jb)=psinablapsi_soc(1,idir,ic,iatom,my_jb) &
    1465        42000 : &                             +soc_ij(2,1,idir)*cpnm1+soc_ij(2,2,idir)*cpnm2
    1466              :                        psinablapsi_soc(2,idir,ic,iatom,my_jb)=psinablapsi_soc(2,idir,ic,iatom,my_jb) &
    1467        56000 : &                             -soc_ij(1,1,idir)*cpnm1-soc_ij(1,2,idir)*cpnm2
    1468              :                      end do
    1469              :                    end if
    1470              :                  end do ! ilmn
    1471              :                end do ! jlmn
    1472              :              end do ! iatom
    1473              :            end if ! use_spinorbit
    1474              : 
    1475           50 :            if (iomode_etsf_mpiio.and.mpi_enreg%paral_spinor==1) then
    1476            0 :              call timab(48,1,tsec)
    1477            0 :              call xmpi_sum_master(psinablapsi,master,spaceComm_spinor,ierr)
    1478            0 :              call timab(48,2,tsec)
    1479              :            end if
    1480              : 
    1481              :          end if ! myband
    1482              : 
    1483              : 
    1484              : !        Write to OPT2 file in case of MPI-IO
    1485           53 :          if (iomode_etsf_mpiio.and.i_am_master_spfft) then
    1486          350 :            nc_start=[1,1,1,jb,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    1487           50 :            if (myband) then
    1488        10230 :              if (use_spinorbit) psinablapsi=psinablapsi+psinablapsi_soc
    1489              :              ! Take the square and sum over m 
    1490          190 :              do iatom=1,natom
    1491          140 :                itypat=dtset%typat(iatom)
    1492          140 :                lmncmax=atm(itypat)%lmn_size
    1493          140 :                if(dtset%nspinor==2)lmncmax=lmncmax/2
    1494         1390 :                do ilmn=1,lmncmax
    1495         1200 :                   ic=lmn2ln(ilmn,itypat)
    1496              :                   psinablapsi2(:,ic,iatom,my_jb)=psinablapsi2(:,ic,iatom,my_jb)+psinablapsi(1,:,ilmn,iatom,my_jb)**2+&
    1497         4940 : &                                                psinablapsi(2,:,ilmn,iatom,my_jb)**2
    1498              :                 enddo
    1499              :              enddo
    1500          350 :              nc_count=[3,nphicor,natom,1,1,1]
    1501              :            else
    1502            0 :              nc_count=[0,0,0,0,0,0]
    1503              :            end if
    1504           50 :            NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    1505              :          end if
    1506              : 
    1507              :        end do ! jb
    1508              : 
    1509            3 :        if (mkmem/=0) then
    1510            3 :          ibg = ibg +  my_nspinor*nband_cprj_k
    1511              :        end if
    1512              : 
    1513            3 :        if (cprj_paral_band) then
    1514            0 :          call pawcprj_free(cprj_k)
    1515            0 :          ABI_FREE(cprj_k)
    1516              :        end if
    1517            3 :        if (mkmem*nsppol/=1) then
    1518            0 :          call pawcprj_free(cprj_k_loc)
    1519            0 :          ABI_FREE(cprj_k_loc)
    1520              :        end if
    1521              : 
    1522              : !      Write to OPT2 file if not MPI-IO
    1523              : 
    1524              : !      >>> Reduction in case of parallelism
    1525            3 :        if (.not.iomode_etsf_mpiio) then
    1526            0 :          call timab(48,1,tsec)
    1527            0 :          call xmpi_sum_master(psinablapsi,master,spaceComm_bandspinor,ierr)
    1528            0 :          call timab(48,2,tsec)
    1529            0 :          if (use_spinorbit) then
    1530            0 :            call xmpi_sum_master(psinablapsi_soc,master,spaceComm_band,ierr)
    1531            0 :            psinablapsi=psinablapsi+psinablapsi_soc
    1532              :          end if
    1533              :          ! Take the square and sum over m 
    1534            0 :          do jb=1,nband_k
    1535            0 :            my_jb=merge(1,jb,iomode_etsf_mpiio)
    1536            0 :            do iatom=1,natom
    1537            0 :              itypat=dtset%typat(iatom)
    1538            0 :              lmncmax=atm(itypat)%lmn_size
    1539            0 :              if(dtset%nspinor==2)lmncmax=lmncmax/2
    1540            0 :              do ilmn=1,lmncmax
    1541            0 :                 ic=lmn2ln(ilmn,itypat)
    1542              :                 psinablapsi2(:,ic,iatom,my_jb)=psinablapsi2(:,ic,iatom,my_jb)+psinablapsi(1,:,ilmn,iatom,my_jb)**2+&
    1543            0 : &                                              psinablapsi(2,:,ilmn,iatom,my_jb)**2
    1544              :               enddo
    1545              :            enddo
    1546              :          enddo
    1547              :        end if
    1548              : 
    1549              : !      >>> This my kpt and I am the master node: I write the data
    1550              :        if (.not.iomode_etsf_mpiio) then
    1551            0 :          if (i_am_master) then
    1552            0 :            if (iomode==IO_MODE_ETSF) then
    1553            0 :              nc_start=[1,1,1,1,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    1554            0 :              nc_count=[3,nphicor,natom,mband,1,1]
    1555            0 :              NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    1556              :            else
    1557            0 :              if (fformopt==612) then ! New OPT2 file format
    1558            0 :                write(ount) (((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    1559            0 :                write(ount) (((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    1560            0 :                write(ount) (((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    1561            0 :              else if (fformopt==613) then ! Large OPT2 file format
    1562            0 :                do jb=1,nband_k
    1563            0 :                  write(ount) ((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    1564            0 :                  write(ount) ((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    1565            0 :                  write(ount) ((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    1566              :                end do
    1567              :              else ! Old OPT2 file format
    1568              :                !The old writing was not efficient (indexes order is bad)
    1569            0 :                do iatom=1,natom
    1570            0 :                  write(ount) ((psinablapsi2(1,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    1571            0 :                  write(ount) ((psinablapsi2(2,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    1572            0 :                  write(ount) ((psinablapsi2(3,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    1573              :                end do
    1574              :              end if
    1575              :            end if
    1576              : 
    1577              : !        >>> This my kpt and I am not the master node: I send the data
    1578            0 :          else if (i_am_master_band.and.i_am_master_spfft) then
    1579            0 :            if (mpi_enreg%me_kpt/=master_spfftband) then
    1580            0 :              ABI_BUG('Problem with band communicator!')
    1581              :            end if
    1582            0 :            call xmpi_exch(psinablapsi2,pnp_size,mpi_enreg%me_kpt,psinablapsi2,master,spaceComm_kpt,etiq,ierr)
    1583              :          end if
    1584              :        end if
    1585              : 
    1586              : !    >>> This is not my kpt and I am the master node: I receive the data and I write
    1587            0 :      elseif ((.not.iomode_etsf_mpiio).and.i_am_master) then ! mykpt
    1588            0 :        sender=master_spfftband
    1589            0 :        call xmpi_exch(psinablapsi2,pnp_size,sender,psinablapsi2,master,spaceComm_kpt,etiq,ierr)
    1590            0 :        if (iomode==IO_MODE_ETSF) then
    1591            0 :          nc_start=[1,1,1,1,ikpt,isppol];nc_stride=[1,1,1,1,1,1]
    1592            0 :          nc_count=[3,nphicor,natom,mband,1,1]
    1593            0 :          NCF_CHECK(nf90_put_var(ncid,varid,psinablapsi2,start=nc_start,stride=nc_stride,count=nc_count))
    1594              :        else
    1595            0 :          if (fformopt==612) then ! New OPT2 file format
    1596            0 :            write(ount) (((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    1597            0 :            write(ount) (((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    1598            0 :            write(ount) (((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom),jb=1,nband_k)
    1599            0 :          else if (fformopt==613) then ! Large OPT2 file format
    1600            0 :            do jb=1,nband_k
    1601            0 :              write(ount) ((psinablapsi2(1,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    1602            0 :              write(ount) ((psinablapsi2(2,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    1603            0 :              write(ount) ((psinablapsi2(3,ic,iatom,jb),ic=1,nphicor),iatom=1,natom)
    1604              :            end do
    1605              :          else ! Old OPT2 file format
    1606              :            !The old writing was not efficient (indexes order is bad)
    1607            0 :            do iatom=1,natom
    1608            0 :              write(ount) ((psinablapsi2(1,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    1609            0 :              write(ount) ((psinablapsi2(2,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    1610            0 :              write(ount) ((psinablapsi2(3,ic,iatom,jb),jb=1,nband_k),ic=1,nphicor)
    1611              :            end do
    1612              :          end if
    1613              :        end if
    1614              :      end if ! mykpt
    1615              : 
    1616            6 :      bdtot_index=bdtot_index+nband_k
    1617              : 
    1618              : !    End loop on spin,kpt
    1619              :    end do ! ikpt
    1620              :  end do !isppol
    1621              : 
    1622              : !Close file
    1623            3 :  if (i_am_master.or.(iomode_etsf_mpiio.and.i_am_master_spfft)) then
    1624            3 :    if (iomode==IO_MODE_ETSF) then
    1625            3 :      NCF_CHECK(nf90_close(ncid))
    1626              :    else
    1627            0 :      ierr=close_unit(ount,msg)
    1628            0 :      ABI_CHECK(ierr==0,"Error while closing OPT2 file")
    1629              :    end if
    1630              :  end if
    1631              : 
    1632              : !Datastructures deallocations
    1633            6 :  do itypat=1,dtset%ntypat
    1634            6 :    call destroy_atomorb(atm(itypat))
    1635              :  enddo
    1636            6 :  ABI_FREE(atm)
    1637            3 :  ABI_FREE(psinablapsi)
    1638            3 :  ABI_FREE(psinablapsi2)
    1639            3 :  ABI_FREE(lmn2ln)
    1640            3 :  if (use_spinorbit) then
    1641            2 :    ABI_FREE(psinablapsi_soc)
    1642            7 :    do iatom=1,natom
    1643            7 :      ABI_FREE(phisocphj(iatom)%value)
    1644              :    end do
    1645            7 :    ABI_FREE(phisocphj)
    1646              :  end if
    1647            3 :  if (.not.already_has_nabla) then
    1648            6 :    do itypat=1,dtset%ntypat
    1649            3 :      if (allocated(pawtab(itypat)%nabla_ij)) then
    1650            3 :        ABI_FREE(pawtab(itypat)%nabla_ij)
    1651            3 :        pawtab(itypat)%has_nabla=0
    1652              :      end if
    1653            6 :      if (allocated(pawtab(itypat)%nabla_im_ij)) then
    1654            2 :        ABI_FREE(pawtab(itypat)%nabla_im_ij)
    1655              :      end if
    1656              :    end do
    1657              :  end if
    1658              : 
    1659              :  DBG_EXIT("COLL")
    1660              : 
    1661            6 :  end subroutine optics_paw_core
    1662              : !!***
    1663              : 
    1664              : !----------------------------------------------------------------------
    1665              : 
    1666              : !!****f* m_paw_optics/linear_optics_paw
    1667              : !! NAME
    1668              : !! linear_optics_paw
    1669              : !!
    1670              : !! FUNCTION
    1671              : !! This program computes the elements of the optical frequency dependent
    1672              : !! linear susceptiblity using matrix elements <-i Nabla> obtained from a
    1673              : !! PAW ground state calculation. It uses formula 17 from Gadoc et al,
    1674              : !! Phys. Rev. B 73, 045112 (2006) [[cite:Gajdo2006]] together with a scissors correction. It uses
    1675              : !! a Kramers-Kronig transform to compute the real part from the imaginary part, and
    1676              : !! it will work on all types of unit cells. It outputs all tensor elements of
    1677              : !! both the real and imaginary parts.
    1678              : !!
    1679              : !! INPUTS
    1680              : !!  filnam: base of file names to read data from
    1681              : !!  mpi_enreg: mpi set up variable, not used in this code
    1682              : !!
    1683              : !! OUTPUT
    1684              : !!  _real and _imag output files
    1685              : !!
    1686              : !! NOTES
    1687              : !!  This routine is not tested
    1688              : !!
    1689              : !! SOURCE
    1690              : 
    1691            0 :  subroutine linear_optics_paw(filnam,filnam_out)
    1692              : 
    1693              : !Arguments -----------------------------------
    1694              : !scalars
    1695              :  character(len=fnlen),intent(in) :: filnam,filnam_out
    1696              : 
    1697              : !Local variables-------------------------------
    1698              :  integer,parameter :: master=0
    1699              :  integer :: iomode,bantot,bdtot_index,fform1,headform
    1700              :  integer :: iband,ierr,ii,ikpt,iom,iout,isppol,isym,jband,jj,me,mband
    1701              :  integer :: method,mom,nband_k,nkpt,nspinor,nsppol,nsym,occopt,only_check
    1702              :  integer :: rdwr,spaceComm,inpunt,reunt,imunt,wfunt
    1703            0 :  integer,allocatable :: nband(:),symrel(:,:,:)
    1704              :  real(dp) :: del,dom,fij,gdelta,omin,omax,paijpbij(2),mbpt_sciss,wij,ucvol
    1705              :  real(dp) :: diffwp, diffwm
    1706              :  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)
    1707            0 :  real(dp),allocatable :: e1(:,:,:),e2(:,:,:,:),epsilon_tot(:,:,:,:),eigen0(:),eig0_k(:)
    1708            0 :  real(dp),allocatable :: kpts(:,:),occ(:),occ_k(:),oml1(:),wtk(:)
    1709            0 :  complex(dp),allocatable :: eps_work(:)
    1710              :  character(len=fnlen) :: filnam1,filnam_gen
    1711              :  character(len=500) :: msg
    1712            0 :  type(hdr_type) :: hdr
    1713              :  type(wffile_type) :: wff1
    1714              : !arrays
    1715            0 :  real(dp),allocatable :: psinablapsi(:,:,:,:)
    1716              : ! *********************************************************************************
    1717              : 
    1718              :  DBG_ENTER("COLL")
    1719              : 
    1720              : !write(std_out,'(a)')' Give the name of the output file ...'
    1721              : !read(std_in, '(a)') filnam_out
    1722              : !write(std_out,'(a)')' The name of the output file is :',filnam_out
    1723              : 
    1724              : !Read data file
    1725            0 :  if (open_file(filnam,msg,newunit=inpunt,form='formatted') /= 0 ) then
    1726            0 :    ABI_ERROR(msg)
    1727              :  end if
    1728              : 
    1729            0 :  rewind(inpunt)
    1730            0 :  read(inpunt,*)
    1731            0 :  read(inpunt,'(a)')filnam_gen       ! generic name for the files
    1732            0 :  filnam1=trim(filnam_gen)//'_OPT' ! nabla matrix elements file
    1733              : 
    1734              : !Open the Wavefunction and optic files
    1735              : !These default values are typical of sequential use
    1736            0 :  iomode=IO_MODE_FORTRAN ; spaceComm=xmpi_comm_self; me=0
    1737              : 
    1738              : ! Read the header of the optic files
    1739            0 :  call hdr%from_fname(filnam1, fform1, spaceComm)
    1740            0 :  call hdr%free()
    1741            0 :  if (fform1 /= 610) then
    1742            0 :    ABI_ERROR("Abinit8 requires an OPT file with fform = 610")
    1743              :  end if
    1744              : 
    1745              : !Open the conducti optic files
    1746            0 :  wfunt = get_unit()
    1747            0 :  call WffOpen(iomode,spaceComm,filnam1,ierr,wff1,master,me,wfunt)
    1748              : 
    1749              : !Read the header from Ground state file
    1750            0 :  rdwr=1
    1751            0 :  call hdr_io(fform1,hdr,rdwr,wff1)
    1752              : 
    1753              : !Extract info from the header
    1754            0 :  headform=hdr%headform
    1755            0 :  bantot=hdr%bantot
    1756            0 :  nkpt=hdr%nkpt
    1757            0 :  ABI_MALLOC(kpts,(3,nkpt))
    1758            0 :  ABI_MALLOC(wtk,(nkpt))
    1759            0 :  kpts(:,:)=hdr%kptns(:,:)
    1760            0 :  wtk(:)=hdr%wtk(:)
    1761            0 :  nspinor=hdr%nspinor
    1762            0 :  nsppol=hdr%nsppol
    1763            0 :  occopt=hdr%occopt
    1764            0 :  rprimd(:,:)=hdr%rprimd(:,:)
    1765            0 :  rprimdinv(:,:) = rprimd(:,:)
    1766            0 :  call matrginv(rprimdinv,3,3) ! need the inverse of rprimd to symmetrize the tensors
    1767            0 :  ABI_MALLOC(nband,(nkpt*nsppol))
    1768            0 :  ABI_MALLOC(occ,(bantot))
    1769            0 :  occ(1:bantot)=hdr%occ(1:bantot)
    1770            0 :  nband(1:nkpt*nsppol)=hdr%nband(1:nkpt*nsppol)
    1771            0 :  nsym=hdr%nsym
    1772            0 :  ABI_MALLOC(symrel,(3,3,nsym))
    1773            0 :  symrel(:,:,:)=hdr%symrel(:,:,:)
    1774              : 
    1775              : !Get mband, as the maximum value of nband(nkpt)
    1776            0 :  mband=maxval(nband(:))
    1777              : 
    1778              : !get ucvol etc.
    1779            0 :  iout = -1
    1780            0 :  call metric(gmet,gprimd,iout,rmet,rprimd,ucvol)
    1781              : 
    1782            0 :  write(std_out,*)
    1783            0 :  write(std_out,'(a,3f10.5,a)' )' rprimd(bohr)      =',rprimd(1:3,1)
    1784            0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,2)
    1785            0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimd(1:3,3)
    1786            0 :  write(std_out,*)
    1787            0 :  write(std_out,'(a,3f10.5,a)' )' rprimdinv         =',rprimdinv(1:3,1)
    1788            0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimdinv(1:3,2)
    1789            0 :  write(std_out,'(a,3f10.5,a)' )'                    ',rprimdinv(1:3,3)
    1790            0 :  write(std_out,'(a,2i8)')      ' nkpt,mband        =',nkpt,mband
    1791              : 
    1792              : !get eigen0
    1793            0 :  ABI_MALLOC(eigen0,(mband*nkpt*nsppol))
    1794            0 :  read(wfunt)(eigen0(iband),iband=1,mband*nkpt*nsppol)
    1795              : 
    1796            0 :  read(inpunt,*)mbpt_sciss
    1797            0 :  read(inpunt,*)dom,omin,omax,mom
    1798            0 :  close(inpunt)
    1799              : 
    1800            0 :  ABI_MALLOC(oml1,(mom))
    1801            0 :  ABI_MALLOC(e1,(3,3,mom))
    1802            0 :  ABI_MALLOC(e2,(2,3,3,mom))
    1803            0 :  ABI_MALLOC(epsilon_tot,(2,3,3,mom))
    1804            0 :  ABI_MALLOC(eps_work,(mom))
    1805            0 :  del=(omax-omin)/(mom-1)
    1806            0 :  do iom=1,mom
    1807            0 :    oml1(iom)=omin+dble(iom-1)*del
    1808              :  end do
    1809            0 :  write(std_out,'(a,i8,4f10.5,a)')' npts,omin,omax,width,mbpt_sciss      =',mom,omin,omax,dom,mbpt_sciss,' Ha'
    1810              : 
    1811            0 :  ABI_MALLOC(psinablapsi,(2,3,mband,mband))
    1812              : 
    1813              : !loop over spin components
    1814            0 :  do isppol=1,nsppol
    1815              :    bdtot_index = 0
    1816              : !  loop over k points
    1817            0 :    do ikpt=1,nkpt
    1818              : !
    1819              : !    number of bands for this k point
    1820            0 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
    1821            0 :      ABI_MALLOC(eig0_k,(nband_k))
    1822            0 :      ABI_MALLOC(occ_k,(nband_k))
    1823              : !    eigenvalues for this k-point
    1824            0 :      eig0_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
    1825              : !    occupation numbers for this k-point
    1826            0 :      occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
    1827              : !    values of -i*nabla matrix elements for this k point
    1828            0 :      psinablapsi=zero
    1829            0 :      read(wfunt)((psinablapsi(1:2,1,iband,jband),iband=1,nband_k),jband=1,nband_k)
    1830            0 :      read(wfunt)((psinablapsi(1:2,2,iband,jband),iband=1,nband_k),jband=1,nband_k)
    1831            0 :      read(wfunt)((psinablapsi(1:2,3,iband,jband),iband=1,nband_k),jband=1,nband_k)
    1832              : 
    1833              : !    occupation numbers for k-point
    1834            0 :      occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
    1835              : !    accumulate e2 for this k point, Eq. 17 from PRB 73, 045112 (2006) [[cite:Gajdo2006]]
    1836            0 :      do iband = 1, nband_k
    1837            0 :        do jband = 1, nband_k
    1838            0 :          fij = occ_k(iband) - occ_k(jband) !occ number difference
    1839            0 :          wij = eig0_k(iband) - eig0_k(jband) !energy difference
    1840            0 :          if (abs(fij) > zero) then ! only consider states of differing occupation numbers
    1841            0 :            do ii = 1, 3
    1842            0 :              do jj = 1, 3
    1843              :                paijpbij(1) = psinablapsi(1,ii,iband,jband)*psinablapsi(1,jj,iband,jband) + &
    1844            0 : &               psinablapsi(2,ii,iband,jband)*psinablapsi(2,jj,iband,jband)
    1845              :                paijpbij(2) = psinablapsi(2,ii,iband,jband)*psinablapsi(1,jj,iband,jband) - &
    1846            0 : &               psinablapsi(1,ii,iband,jband)*psinablapsi(2,jj,iband,jband)
    1847            0 :                do iom = 1, mom
    1848              : !                original version
    1849              : !                diffw = wij + mbpt_sciss - oml1(iom) ! apply scissors term here
    1850              : !                gdelta = exp(-diffw*diffw/(4.0*dom*dom))/(2.0*dom*sqrt(pi)) ! delta fnc resolved as Gaussian
    1851              : !                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))
    1852              : !                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))
    1853            0 :                  diffwm = wij - mbpt_sciss + oml1(iom) ! apply scissors term here
    1854            0 :                  diffwp = wij + mbpt_sciss - oml1(iom) ! apply scissors term here
    1855            0 :                  gdelta = exp(-diffwp*diffwp/(4.0*dom*dom))/(2.0*dom*sqrt(pi))
    1856            0 :                  e2(1,ii,jj,iom) = e2(1,ii,jj,iom) - (4.0*pi*pi/ucvol)*wtk(ikpt)*fij*paijpbij(1)*gdelta/(wij*wij)
    1857            0 :                  e2(2,ii,jj,iom) = e2(2,ii,jj,iom) - (4.0*pi*pi/ucvol)*wtk(ikpt)*fij*paijpbij(2)*gdelta/(wij*wij)
    1858              :                end do ! end loop over spectral points
    1859              :              end do ! end loop over jj = 1, 3
    1860              :            end do ! end loop over ii = 1, 3
    1861              :          end if ! end selection on fij /= 0
    1862              :        end do ! end loop over jband
    1863              :      end do ! end loop over iband
    1864              : 
    1865            0 :      ABI_FREE(eig0_k)
    1866            0 :      ABI_FREE(occ_k)
    1867            0 :      bdtot_index=bdtot_index+nband_k
    1868              :    end do ! end loop over k points
    1869              :  end do ! end loop over spin polarizations
    1870              : 
    1871              : !here apply nsym symrel transformations to reconstruct full tensor from IBZ part
    1872            0 :  epsilon_tot(:,:,:,:) = zero
    1873            0 :  do isym = 1, nsym
    1874            0 :    symd(:,:)=matmul(rprimd(:,:),matmul(symrel(:,:,isym),rprimdinv(:,:)))
    1875            0 :    symdinv(:,:)=symd(:,:)
    1876            0 :    call matrginv(symdinv,3,3)
    1877            0 :    do iom = 1, mom
    1878            0 :      e2rot(:,:)=matmul(symdinv(:,:),matmul(e2(1,:,:,iom),symd(:,:)))
    1879            0 :      epsilon_tot(2,:,:,iom) = epsilon_tot(2,:,:,iom)+e2rot(:,:)/nsym
    1880              :    end do
    1881              :  end do
    1882              : 
    1883              : !generate e1 from e2 via KK transforma
    1884            0 :  method=0 ! use naive integration ( = 1 for simpson)
    1885            0 :  only_check=0 ! compute real part of eps in kk routine
    1886            0 :  do ii = 1, 3
    1887            0 :    do jj = 1, 3
    1888            0 :      eps_work(:) = cmplx(0.0,epsilon_tot(2,ii,jj,:), kind=dp)
    1889            0 :      call kramerskronig(mom,oml1,eps_work,method,only_check)
    1890            0 :      epsilon_tot(1,ii,jj,:) = real(eps_work(:))
    1891            0 :      if (ii /= jj) epsilon_tot(1,ii,jj,:) = epsilon_tot(1,ii,jj,:)- 1.0
    1892              :    end do ! end loop over jj
    1893              :  end do ! end loop over ii
    1894              : 
    1895            0 :  if (open_file(trim(filnam_out)//'_imag',msg,newunit=reunt,form='formatted') /= 0) then
    1896            0 :    ABI_ERROR(msg)
    1897              :  end if
    1898              : 
    1899            0 :  if (open_file(trim(filnam_out)//'_real',msg,unit=imunt,form='formatted') /= 0) then
    1900            0 :    ABI_ERROR(msg)
    1901              :  end if
    1902              : 
    1903            0 :  write(reunt,'(a12,6a13)')' # Energy/Ha ','eps_2_xx','eps_2_yy','eps_2_zz',&
    1904            0 : & 'eps_2_yz','eps_2_xz','eps_2_xy'
    1905            0 :  write(imunt,'(a12,6a13)')' # Energy/Ha ','eps_1_xx','eps_1_yy','eps_1_zz',&
    1906            0 : & 'eps_1_yz','eps_1_xz','eps_1_xy'
    1907              : 
    1908            0 :  do iom = 1, mom
    1909            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),' ',&
    1910            0 : &   epsilon_tot(2,1,1,iom),' ',epsilon_tot(2,2,2,iom),' ',epsilon_tot(2,3,3,iom),' ',&
    1911            0 : &   epsilon_tot(2,2,3,iom),' ',epsilon_tot(2,1,3,iom),' ',epsilon_tot(2,1,2,iom)
    1912            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),' ',&
    1913            0 : &   epsilon_tot(1,1,1,iom),' ',epsilon_tot(1,2,2,iom),' ',epsilon_tot(1,3,3,iom),' ',&
    1914            0 : &   epsilon_tot(1,2,3,iom),' ',epsilon_tot(1,1,3,iom),' ',epsilon_tot(1,1,2,iom)
    1915              :  end do
    1916              : 
    1917            0 :  close(reunt)
    1918            0 :  close(imunt)
    1919              : 
    1920            0 :  ABI_FREE(nband)
    1921            0 :  ABI_FREE(oml1)
    1922            0 :  ABI_FREE(e2)
    1923            0 :  ABI_FREE(e1)
    1924            0 :  ABI_FREE(occ)
    1925            0 :  ABI_FREE(psinablapsi)
    1926            0 :  ABI_FREE(eigen0)
    1927            0 :  ABI_FREE(wtk)
    1928            0 :  ABI_FREE(kpts)
    1929              : 
    1930            0 :  call hdr%free()
    1931              : 
    1932              :  DBG_EXIT("COLL")
    1933              : 
    1934            0 :  end subroutine linear_optics_paw
    1935              : !!***
    1936              : 
    1937              : !----------------------------------------------------------------------
    1938              : 
    1939              : !!****f* m_paw_optics/pawnabla_soc_init
    1940              : !! NAME
    1941              : !! pawnabla_soc_init
    1942              : !!
    1943              : !! FUNCTION
    1944              : !! Compute the PAW SOC contribution(s) to the momentum PAW matrix elements,
    1945              : !!  i.e. <Phi_i|1/4 Alpha^2 dV/dr (Sigma X vec(r)/r) |Phi_j>
    1946              : !!   where:
    1947              : !!    {Phi_i}= AE partial waves
    1948              : !!    Alpha = inverse of fine structure constant
    1949              : !!    Sigma^alpha,beta= Pauli matrices
    1950              : !!    X = cross product
    1951              : !!
    1952              : !! There are 2 typical uses:
    1953              : !!   - Valence-valence terms: Phi_i and Phi_j are PAW AE partial waves (unpolarized)
    1954              : !!   - Core-valence terms: Phi_i is are AE partial waves and Phi_j are core AE wave-functions (spinors)
    1955              : !!
    1956              : !! In practice we compute:
    1957              : !!  (Sigma^up-up X g_ij) and (Sigma^up-dn X g_ij)    (X = vector cross product)
    1958              : !!  (Sigma^dn-up X g_ij) and (Sigma^dn-dn X g_ij)
    1959              : !!   where:
    1960              : !!    g_ij= 1/4 Alpha^2 Int_[Phi_i(r)/r Phi_j(r)/r dV(r)/dr r^2 dr] . Gvec_ij
    1961              : !!        and Gvec_ij= Int[S_limi S_ljmj vec(r)/r dOmega] (Gaunt coefficients)
    1962              : !!
    1963              : !! COPYRIGHT
    1964              : !! Copyright (C) 2021-2026 ABINIT group (NBrouwer,MT)
    1965              : !! This file is distributed under the terms of the
    1966              : !! GNU General Public License, see ~ABINIT/COPYING
    1967              : !! or http://www.gnu.org/copyleft/gpl.txt .
    1968              : !!
    1969              : !! INPUTS
    1970              : !!  el_temp=electronic temperature (hartree)
    1971              : !!  ixc= choice of exchange-correlation scheme (see above, and below)
    1972              : !!  my_natom=number of atoms treated by current processor
    1973              : !!  natom=total number of atoms in cell
    1974              : !!  nspden=number of spin-density components
    1975              : !!  ntypat=number of types of atoms in unit cell.
    1976              : !!  option_core=Type of calculation: 0=valence-valence, 1=core-valence
    1977              : !!  pawang <type(pawang_type)>=paw angular mesh and related data
    1978              : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data
    1979              : !!  pawrhoij(my_natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data
    1980              : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
    1981              : !!  pawxcdev=Choice of XC development (0=no dev. (use of angular mesh) ; 1 or 2=dev. on moments)
    1982              : !!  spnorbscl=scaling factor for spin-orbit coupling
    1983              : !!  typat(natom) =Type of each atoms
    1984              : !!  xc_denpos= lowest allowed density (usually for the computation of the XC functionals)
    1985              : !!  xc_taupos= lowest allowed kinetic energy density (for mGGA XC functionals)
    1986              : !!  znucl(ntypat)=gives the nuclear charge for all types of atoms
    1987              : !!  [atm <type(paw_atomorb_type)>]=--optional-- structure containing core info
    1988              : !!  [mpi_atmtab(:)]=--optional-- indexes of the atoms treated by current proc
    1989              : !!  [comm_atom]=--optional-- MPI communicator over atoms
    1990              : !!
    1991              : !! OUTPUT
    1992              : !    phisocphj(dtset%natom) <type(coeff4_type)>= stores soc coefficients:
    1993              : !!!  If  option_core==0 or nspinor_cor==1:
    1994              : !!     phisocphj(iat)%value(1,1,idir,ilmn,jlmn) is real part of (Sigma^up-up X g_ij)
    1995              : !!     phisocphj(iat)%value(2,1,idir,ilmn,jlmn) is imaginary part of (Sigma^up-up X g_ij)
    1996              : !!     phisocphj(iat)%value(1,2,idir,ilmn,jlmn) is real part of (Sigma^up-dn X g_ij)
    1997              : !!     phisocphj(iat)%value(2,2,idir,ilmn,jlmn) is imaginary part of (Sigma^up-dn X g_ij)
    1998              : !!   If option_core==1 and nspinor_cor==2 (core-valence with spinorial core WF):
    1999              : !!     phisocphj(iat)%value(1,1,idir,ilmn,2*jlmn-1) is real part of (Sigma^up-up X g_ij^up)
    2000              : !!     phisocphj(iat)%value(2,1,idir,ilmn,2*jlmn-1) is imaginary part of (Sigma^up-up X g_ij^up)
    2001              : !!     phisocphj(iat)%value(1,2,idir,ilmn,2*jlmn-1) is real part of (Sigma^dn-up X g_ij^dn)
    2002              : !!     phisocphj(iat)%value(2,2,idir,ilmn,2*jlmn-1) is imaginary part of (Sigma^dn-up X g_ij^dn)
    2003              : !!     phisocphj(iat)%value(1,1,idir,ilmn,2*jlmn  ) is real part of (Sigma^up-dn X g_ij^up)
    2004              : !!     phisocphj(iat)%value(2,1,idir,ilmn,2*jlmn  ) is imaginary part of (Sigma^up-dn X g_ij^up)
    2005              : !!     phisocphj(iat)%value(1,2,idir,ilmn,2*jlmn  ) is real part of (Sigma^dn-dn X g_ij^dn)
    2006              : !!     phisocphj(iat)%value(2,2,idir,ilmn,2*jlmn  ) is imaginary part of (Sigma^dn-dn X g_ij^dn)
    2007              : !! (idir=cartesian direction)
    2008              : !!
    2009              : !! SIDE EFFECTS
    2010              : !!
    2011              : !! NOTES
    2012              : !! If Phi_j is not polarized,
    2013              : !!    (Sigma^dn-dn X g_ij)=-(Sigma^up-up X g_ij)
    2014              : !!    (Sigma^dn-up X g_ij)= (Sigma^up-dn X g_ij)^*
    2015              : !!    So, we store only 2 components.
    2016              : !! If Phi_j is polarized, the spin component is included in the last dimension of
    2017              : !!   phisocphj(iat)%value, i.e. lmn_size_cor=2*lmn_size
    2018              : !!
    2019              : !! SOURCE
    2020              : 
    2021            3 :  subroutine pawnabla_soc_init(el_temp,phisocphj,option_core,ixc,my_natom,natom,nspden,ntypat,pawang, &
    2022            6 : &           pawrad,pawrhoij,pawtab,pawxcdev,spnorbscl,typat,xc_denpos,xc_taupos,znucl, &
    2023            3 : &           atm,mpi_atmtab,comm_atom) ! Optional arguments
    2024              : 
    2025              : !Arguments ------------------------------------
    2026              : !scalars
    2027              :  integer,intent(in) :: ixc,my_natom,natom,nspden,ntypat,option_core,pawxcdev
    2028              :  integer,optional,intent(in) :: comm_atom
    2029              :  real(dp),intent(in) :: el_temp,spnorbscl,xc_denpos,xc_taupos
    2030              :  type(pawang_type),intent(in) :: pawang
    2031              : !arrays
    2032              :  integer,intent(in) :: typat(natom)
    2033              :  integer,optional,target,intent(in) :: mpi_atmtab(:)
    2034              :  real(dp),intent(in) :: znucl(ntypat)
    2035              :  type(coeff5_type),allocatable,target,intent(inout) :: phisocphj(:)
    2036              :  type(pawrad_type),target,intent(in) :: pawrad(ntypat)
    2037              :  type(pawrhoij_type),intent(inout) :: pawrhoij(my_natom)
    2038              :  type(pawtab_type),target,intent(in) :: pawtab(ntypat)
    2039              :  type(atomorb_type), intent(in), target, optional :: atm(ntypat)
    2040              : 
    2041              : !Local variables-------------------------------
    2042              : !scalars
    2043              :  real(dp),parameter :: one_over_fourpi   = one/sqrt(four_pi)
    2044              :  real(dp),parameter :: sqr_fourpi_over_3 = sqrt(four_pi/3)
    2045              :  real(dp),parameter :: QuarterFineStruct2=(half/InvFineStruct)**2
    2046              :  real(dp),parameter :: hyb_mixing_ = 0.0_dp   ! Fake value to be updated in the future
    2047              :  integer :: iatom,iatom_tot,itypat,ii,jj,ierr,ipts,ignt,sgnkappa
    2048              :  integer :: idum,option,usenhat,usekden,usecore,xclevel,nkxc,my_comm_atom
    2049              :  integer :: mesh_size,lmn_size,lmn2_size,lmn_size_j,lmn_size_cor
    2050              :  integer :: lm_size,ln_size,ln_size_j
    2051              :  integer :: ilmn,ilm,iln,jl,jm,jm_re,jm_im,jlmn,jlm,jlm_re,jlm_im,jln,js,klm_re,klm_im
    2052              :  logical :: my_atmtab_allocated,paral_atom
    2053              :  real(dp) :: avg,cgc,compch_sph_dum,eexc_dum,ssxc_dum,eexcdc_dum,jmj
    2054              :  real(dp) :: fact_re,fact_im,gx_re,gx_im,gy_re,gy_im,gz_re,gz_im,if3
    2055              :  character(len=500) :: msg
    2056              : !arrays
    2057            3 :  integer,pointer :: my_atmtab(:),indlmn(:,:),indlmn_j(:,:)
    2058            3 :  logical,allocatable :: lmselect(:)
    2059              :  real(dp) :: nhat_dum(1,1,1),trho_dum(1,1,1),kxc_dum(1,1,1),k3xc_dum(1,1,1)
    2060            3 :  real(dp),allocatable :: rho1(:,:,:),tau1(:,:,:),rhosph(:),vhartree(:),vxc(:,:,:)
    2061            3 :  real(dp),allocatable :: intf3(:,:),potsph(:),dVdr(:),func(:)
    2062            3 :  real(dp),pointer :: phi_j(:,:),soc_ij(:,:,:,:,:)
    2063              :  type(pawrad_type),pointer :: pawrd
    2064              :  type(pawtab_type),pointer :: pawtb
    2065              : 
    2066              : ! ************************************************************************
    2067              : 
    2068              : !Some checks in case of core-valence (option_core=1)
    2069            3 :  if (option_core/=0.and.option_core/=1) then
    2070            0 :    msg='Wrong option_core value!'
    2071            0 :    ABI_BUG(msg)
    2072              :  end if
    2073            3 :  if (option_core==1) then
    2074              : !  Check if we have the optional arguments
    2075            2 :    if (.not.present(atm)) then
    2076            0 :      msg='For core-valence calculation, need atm data!'
    2077            0 :      ABI_BUG(msg)
    2078              :    end if
    2079            4 :    do itypat=1,ntypat
    2080              : !  Check if we have relativistic core wave functions
    2081            4 :      if (size(atm(itypat)%indlmn,1)<8) then
    2082            0 :        write(msg,'(a)') 'Wrong 1st dim. of indlmn_cor in pawnabla_soc_init (need spinors)!'
    2083            0 :        ABI_BUG(msg)
    2084              :      end if
    2085              :    enddo
    2086              :  endif
    2087              : 
    2088              : !Some useful variables
    2089            3 :  usekden=pawxc_get_usekden(ixc)
    2090            3 :  usecore=1 ; nkxc=0 ; usenhat=0
    2091            3 :  xclevel=pawxc_get_xclevel(ixc)
    2092            3 :  if (option_core==1) then
    2093              :    lmn_size_cor=0
    2094            4 :    do itypat=1,ntypat
    2095            4 :      lmn_size_cor=max(lmn_size_cor,atm(itypat)%lmn_size) !Includes spinors
    2096              :    enddo
    2097              :  end if
    2098              : 
    2099              : !Prepare output arrays
    2100            3 :  if (allocated(phisocphj)) then
    2101            0 :    do iatom=1,natom
    2102            0 :       if (allocated(phisocphj(iatom)%value)) then
    2103            0 :         ABI_FREE(phisocphj(iatom)%value)
    2104              :       end if
    2105              :    end do
    2106            0 :    ABI_FREE(phisocphj)
    2107              :  end if
    2108           18 :  ABI_MALLOC(phisocphj,(natom))
    2109           12 :  do iatom=1,natom
    2110            9 :    lmn_size=pawtab(typat(iatom))%lmn_size
    2111            9 :    if (option_core==0) then
    2112           16 :      ABI_MALLOC(phisocphj(iatom)%value,(2,2,3,lmn_size,lmn_size))
    2113              :    else
    2114              :      !lmn_size_cor is double because it contains the spin component
    2115           20 :      ABI_MALLOC(phisocphj(iatom)%value,(2,2,3,lmn_size,lmn_size_cor))
    2116              :    end if
    2117        27776 :    phisocphj(iatom)%value=zero
    2118              :  end do
    2119              : 
    2120              : !Set up parallelism over atoms
    2121            3 :  paral_atom=(present(comm_atom).and.(my_natom/=natom))
    2122            3 :  nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
    2123            3 :  my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
    2124              :  call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,&
    2125            3 : &                   my_natom_ref=my_natom)
    2126              : 
    2127              : !-------------------------------------------------------------------
    2128              : !Loop over atoms
    2129              : 
    2130           12 :  do iatom=1,my_natom
    2131              : 
    2132              : !  Atom-dependent data
    2133            9 :    itypat=typat(iatom)
    2134            9 :    pawrd => pawrad(itypat)
    2135            9 :    pawtb  => pawtab(itypat)
    2136            9 :    lmn_size=pawtb%lmn_size
    2137            9 :    lmn2_size=pawtb%lmn2_size
    2138            9 :    lm_size=pawtb%lcut_size**2
    2139            9 :    ln_size=pawtb%basis_size
    2140            9 :    mesh_size=pawtb%mesh_size
    2141            9 :    indlmn => pawtb%indlmn
    2142           27 :    ABI_MALLOC(lmselect,(lm_size))
    2143          106 :    lmselect(:)=.true.
    2144              : 
    2145              : !  Distinguish valence-valence and core-valence cases
    2146            9 :    if (option_core==0) then
    2147            4 :      ln_size_j=ln_size
    2148            4 :      lmn_size_j=lmn_size
    2149            4 :      indlmn_j => pawtb%indlmn
    2150            4 :      phi_j => pawtb%phi
    2151              :    else
    2152            5 :      ln_size_j=atm(itypat)%ln_size
    2153            5 :      lmn_size_j=atm(itypat)%lmn_size
    2154            5 :      indlmn_j => atm(itypat)%indlmn
    2155            5 :      phi_j => atm(itypat)%phi(:,:,1)
    2156            5 :      if (atm(itypat)%mesh_size<mesh_size) then
    2157            0 :        msg='mesh_size and mesh_size_cor not compatible!'
    2158            0 :        ABI_BUG(msg)
    2159              :      end if
    2160              :    endif
    2161              : 
    2162              : !  Manage parallelism
    2163            9 :    iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom)
    2164            9 :    soc_ij => phisocphj(iatom_tot)%value(:,:,:,:,:)
    2165              : 
    2166              : !-------------------------------------------------------------------
    2167              : !Compute all-electron density
    2168              : 
    2169           45 :    ABI_MALLOC(rho1,(mesh_size,lm_size,nspden))
    2170       107505 :    option=2 ; rho1=zero
    2171              :    call pawdensities(compch_sph_dum,1,iatom_tot,lmselect,lmselect,lm_size,&
    2172              : &       nhat_dum,nspden,-1,0,option,-1,0,pawang,0,pawrd,&
    2173            9 : &       pawrhoij(iatom),pawtb,rho1,trho_dum)
    2174            9 :    if (usekden==1) then
    2175            0 :      ABI_MALLOC(tau1,(mesh_size,lm_size,nspden))
    2176            0 :      tau1=zero
    2177              :      call pawkindensities(1,lmselect,lm_size,nspden,-1,option,-1,&
    2178            0 : &         pawang,pawrd,pawrhoij(iatom),pawtb,tau1,trho_dum)
    2179              :    end if
    2180              : 
    2181              : !-------------------------------------------------------------------
    2182              : !Compute spherical potential and compute its first derivative dV/dr
    2183              : 
    2184           27 :    ABI_MALLOC(potsph,(mesh_size))
    2185           18 :    ABI_MALLOC(dVdr,(mesh_size))
    2186        18789 :    potsph=zero ; dVdr=zero
    2187              : 
    2188              : !  Compute XC potential
    2189            9 :    option=1
    2190            9 :    if (pawxcdev/=0) then
    2191           36 :      ABI_MALLOC(vxc,(mesh_size,lm_size,nspden))
    2192       107505 :      vxc=zero
    2193              :      call pawxcm(pawtb%coredens,eexc_dum,eexcdc_dum,ssxc_dum,idum,hyb_mixing_,ixc,kxc_dum,lm_size,&
    2194              : &         lmselect,nhat_dum,nkxc,.false.,mesh_size,nspden,option,pawang,pawrd,&
    2195            9 : &         pawxcdev,rho1,usecore,usenhat,vxc,xclevel,xc_denpos,el_temp)
    2196         9399 :      potsph(1:mesh_size)=half*(vxc(1:mesh_size,1,1)+vxc(1:mesh_size,1,nspden))
    2197              :    else
    2198            0 :      ABI_MALLOC(vxc,(mesh_size,pawang%angl_size,nspden))
    2199            0 :      vxc=zero
    2200              :      call pawxc(pawtb%coredens,eexc_dum,eexcdc_dum,ssxc_dum,hyb_mixing_,ixc,kxc_dum,k3xc_dum,&
    2201              : &         lm_size,lmselect,nhat_dum,nkxc,nkxc,.false.,mesh_size,nspden,option,pawang,&
    2202              : &         pawrd,rho1,usecore,usenhat,vxc,xclevel,xc_denpos,el_temp,&
    2203            0 : &         coretau=pawtb%coretau,taur=tau1,xc_taupos=xc_taupos)
    2204            0 :      potsph(1:mesh_size)=zero
    2205            0 :      do ipts=1,pawang%angl_size
    2206              :        potsph(1:mesh_size)=potsph(1:mesh_size) &
    2207            0 : &        +half*(vxc(1:mesh_size,ipts,1)+vxc(1:mesh_size,ipts,nspden))*pawang%angwgth(ipts)
    2208              :      end do
    2209            0 :      potsph(1:mesh_size)=sqrt(four_pi)*potsph(1:mesh_size)
    2210              :    end if
    2211              : 
    2212              : !  Compute Hartree potentialHalfFineStruct2
    2213           18 :    ABI_MALLOC(vhartree,(mesh_size))
    2214           18 :    ABI_MALLOC(rhosph,(mesh_size))
    2215        18789 :    vhartree=zero ; rhosph=zero
    2216         9399 :    rhosph(1:mesh_size)=rho1(1:mesh_size,1,1)
    2217         9399 :    if (usecore==1) rhosph(1:mesh_size)=rhosph(1:mesh_size)+sqrt(four_pi)*pawtb%coredens(1:mesh_size)
    2218         9399 :    rhosph(1:mesh_size)=rhosph(1:mesh_size)*four_pi*pawrd%rad(1:mesh_size)**2
    2219            9 :    call poisson(rhosph,0,pawrd,vhartree)
    2220         9390 :    vhartree(2:mesh_size)=(vhartree(2:mesh_size)-sqrt(four_pi)*znucl(itypat))/pawrd%rad(2:mesh_size)
    2221            9 :    call pawrad_deducer0(vhartree,mesh_size,pawrd)
    2222         9399 :    potsph(1:mesh_size)=potsph(1:mesh_size)+vhartree(1:mesh_size)
    2223              : 
    2224              : !  Apply angular scaling factor
    2225         9399 :    potsph(1:mesh_size)=one_over_fourpi*potsph(1:mesh_size)
    2226              : 
    2227              : !  Compute 1st derivative of potential
    2228            9 :    call nderiv_gen(dVdr,potsph,pawrd)
    2229              : 
    2230              : !  Multiply by relativistic factor
    2231         9399 :    dVdr(1:mesh_size)=dVdr(1:mesh_size)*(one/(one-potsph(1:mesh_size)*half/InvFineStruct**2)**2)
    2232              : 
    2233            9 :    ABI_FREE(vxc)
    2234            9 :    ABI_FREE(vhartree)
    2235            9 :    ABI_FREE(potsph)
    2236            9 :    ABI_FREE(rhosph)
    2237            9 :    ABI_FREE(lmselect)
    2238            9 :    ABI_FREE(rho1)
    2239            9 :    if (usekden==1) then
    2240            0 :      ABI_FREE(tau1)
    2241              :    end if
    2242              : 
    2243              : !-------------------------------------------------------------------
    2244              : !Compute radial and angular contributions
    2245              : 
    2246           36 :    ABI_MALLOC(intf3,(ln_size,ln_size_j))
    2247          197 :    intf3=zero
    2248              : 
    2249              : !  >>>> Calculate f_3= alpha^2/4 int[dr ui*(r) uj(r) dV/dr]
    2250           18 :    ABI_MALLOC(func,(mesh_size))
    2251           45 :    do jln=1,ln_size_j
    2252          197 :      do iln=1,ln_size
    2253       161832 :        func(1:mesh_size)=dVdr(1:mesh_size)*pawtb%phi(1:mesh_size,iln)*phi_j(1:mesh_size,jln)
    2254          188 :        call simp_gen(intf3(iln,jln),func,pawrd)
    2255              :      end do
    2256              :    end do
    2257          197 :    intf3(:,:)=QuarterFineStruct2*spnorbscl*intf3(:,:)
    2258            9 :    ABI_FREE(func)
    2259              : 
    2260              : !  Loop over initial states (valence or core, according to option_core)
    2261          141 :    do jlmn=1,lmn_size_j
    2262          132 :      jl=indlmn_j(1,jlmn)
    2263          132 :      jm=indlmn_j(2,jlmn)
    2264          132 :      jlm=indlmn_j(4,jlmn)
    2265          132 :      jln=indlmn_j(5,jlmn)
    2266              : 
    2267              : !    In case of spinorial core wave function, we have to handle imaginary
    2268              : !      spherical harmonics as linear combination of real spherical harmonics
    2269              : !    See Brouwer et al, CPC 266, 108029 (2021), equation (21)
    2270          132 :      if (option_core==1) then
    2271          100 :        jm_re= abs(jm)
    2272          100 :        jm_im=-abs(jm)
    2273          100 :        jlm_re=jl*(jl+1)+jm_re+1
    2274          100 :        jlm_im=jl*(jl+1)+jm_im+1
    2275              : !      Calculate spinor dependent coefficients
    2276          100 :        sgnkappa=indlmn_j(3,jlmn)   !sign of kappa
    2277          100 :        jmj=half*indlmn_j(8,jlmn)   !2mj is stored in indlmn_cor
    2278          100 :        js=indlmn_j(6,jlmn)       !1 is up, 2 is down
    2279          100 :        if (sgnkappa==1) then
    2280           20 :          if(js==1) then
    2281           10 :            cgc= sqrt((dble(jl)-jmj+half)/dble(2*jl+1))
    2282              :          else
    2283           10 :            cgc=-sqrt((dble(jl)+jmj+half)/dble(2*jl+1))
    2284              :          endif
    2285              :        else
    2286           80 :          if(js==1) then
    2287           25 :            cgc= sqrt((dble(jl)+jmj+half)/dble(2*jl+1))
    2288              :          else
    2289           55 :            cgc= sqrt((dble(jl)-jmj+half)/dble(2*jl+1))
    2290              :          endif
    2291              :        endif
    2292              : 
    2293              : !      Calculate factors to convert from complex to real sph. harm.
    2294          100 :        if (jm<0) then
    2295           45 :          fact_re=sqr_fourpi_over_3*half_sqrt2*cgc
    2296           45 :          fact_im=-fact_re
    2297           55 :        else if (jm>0) then
    2298           15 :          fact_re=sqr_fourpi_over_3*half_sqrt2*cgc*(-1)**jm
    2299           15 :          fact_im=fact_re
    2300              :        else
    2301              :          fact_re=sqr_fourpi_over_3
    2302              :          fact_im=0
    2303              :        end if
    2304              :      else ! valence-valence case (real)
    2305              :        js=1
    2306              :        jlm_re=jlm ; jlm_im=jlm
    2307              :        fact_re=sqr_fourpi_over_3
    2308              :        fact_im=0
    2309              :      end if
    2310              : 
    2311              : !    Loop over final states
    2312         1397 :      do ilmn=1,lmn_size
    2313         1256 :        ilm=indlmn(4,ilmn)
    2314         1256 :        iln=indlmn(5,ilmn)
    2315              : 
    2316              : !      >>>> Calculate g_ij=(g_x,g_y,g_z) = sqrt(4pi/3) int dOmega Ylm Ylm' S1-1,0,1
    2317              : !              using real Gaunt coefficients
    2318         1256 :        gx_re=zero;gy_re=zero;gz_re=zero
    2319         1256 :        gx_im=zero;gy_im=zero;gz_im=zero
    2320         1256 :        if3=zero
    2321              : 
    2322              : !      jl was set as a flag for invalid combinations
    2323              : !        i.e. m=-(l+1) or m=(l+1)
    2324              : !      In these cases, cgc=0 ; so gx=gy=gz=0
    2325         1256 :        if (jl/=-1) then
    2326          956 :          if3=intf3(iln,jln)
    2327          956 :          klm_re=merge((jlm_re*(jlm_re-1))/2+ilm,(ilm*(ilm-1))/2+jlm_re,ilm<=jlm_re)
    2328              : 
    2329              : !        Real parts
    2330              : !        M=-1
    2331          956 :          ignt=pawang%gntselect(2,klm_re) !get index for L=1 M =-1 ilm jlm_re
    2332          956 :          if (ignt/=0) gy_re=fact_re*pawang%realgnt(ignt)
    2333              : !        M=0
    2334          956 :          ignt=pawang%gntselect(3,klm_re) !get index for L=1 M = 0 ilm jlm_re
    2335          956 :          if (ignt/=0) gz_re=fact_re*pawang%realgnt(ignt)
    2336              : !        M=1
    2337          956 :          ignt=pawang%gntselect(4,klm_re) !get index for L=1 M = 1 ilm jlm_re
    2338          956 :          if (ignt/=0) gx_re=fact_re*pawang%realgnt(ignt)
    2339              : 
    2340              : !        Imaginary parts
    2341          956 :          if (option_core==1) then
    2342          700 :            klm_im=merge((jlm_im*(jlm_im-1))/2+ilm,(ilm*(ilm-1))/2+jlm_im,ilm<=jlm_im)
    2343              : !          M=-1
    2344          700 :            ignt=pawang%gntselect(2,klm_im) !get index for L=1 M =-1 ilm jlm_im
    2345          700 :            if (ignt/=0) gy_im=fact_im*pawang%realgnt(ignt)
    2346              : !          M=0
    2347          700 :            ignt=pawang%gntselect(3,klm_im) !get index for L=1 M = 0 ilm jlm_im
    2348          700 :            if (ignt/=0) gz_im=fact_im*pawang%realgnt(ignt)
    2349              : !          M=1
    2350          700 :            ignt=pawang%gntselect(4,klm_im) !get index for L=1 M = 1 ilm jlm_im
    2351          700 :            if (ignt/=0) gx_im=fact_im*pawang%realgnt(ignt)
    2352              :          end if
    2353              :        end if
    2354              : 
    2355              : !      >>>> Calculate Sigma X g_ij
    2356              : 
    2357         1388 :        if (option_core==0.or.js==1) then
    2358              :          !(Sigma^up-up X gij)_x = -gy*f_3
    2359          606 :          soc_ij(1,1,1,ilmn,jlmn)=-if3*gy_re           ! real part
    2360          606 :          soc_ij(2,1,1,ilmn,jlmn)=-if3*gy_im           ! imag part
    2361              :          !(Sigma^up-up X gij)_y = gx*f_3
    2362          606 :          soc_ij(1,1,2,ilmn,jlmn)= if3*gx_re           ! real part
    2363          606 :          soc_ij(2,1,2,ilmn,jlmn)= if3*gx_im           ! imag part
    2364              :          !(Sigma^up-up X gij)_z = 0
    2365          606 :          soc_ij(1,1,3,ilmn,jlmn)= zero                ! real part
    2366          606 :          soc_ij(2,1,3,ilmn,jlmn)= zero                ! imag part
    2367              : 
    2368              :          !(Sigma^dn-up X gij)_x = i.gz*f_3
    2369          606 :          soc_ij(1,2,1,ilmn,jlmn)=-if3*gz_im           ! real part
    2370          606 :          soc_ij(2,2,1,ilmn,jlmn)= if3*gz_re           ! imag part
    2371              :          !(Sigma^dn-up X gij)_y = -gz*f_3
    2372          606 :          soc_ij(1,2,2,ilmn,jlmn)=-if3*gz_re           ! real part
    2373          606 :          soc_ij(2,2,2,ilmn,jlmn)=-if3*gz_im           ! imag part
    2374              :          !(Sigma^dn-up X gij)_z = (gy-i.gx)*f_3
    2375          606 :          soc_ij(1,2,3,ilmn,jlmn)= if3*(gy_re+gx_im)   ! real part
    2376          606 :          soc_ij(2,2,3,ilmn,jlmn)= if3*(gy_im-gx_re)   ! imag part
    2377              : 
    2378          650 :        else if (option_core==1.and.js==2) then
    2379              :          !(Sigma^up-dn X gij^dn)_x = -i.gz^dn*f_3
    2380          350 :          soc_ij(1,1,1,ilmn,jlmn)= if3*gz_im           ! real part
    2381          350 :          soc_ij(2,1,1,ilmn,jlmn)=-if3*gz_re           ! imag part
    2382              :          !(Sigma^up-dn X gij^dn)_y = -gz^dn*f_3
    2383          350 :          soc_ij(1,1,2,ilmn,jlmn)=-if3*gz_re           ! real part
    2384          350 :          soc_ij(2,1,2,ilmn,jlmn)=-if3*gz_im           ! imag part
    2385              :          !(Sigma^up-dn X gij^dn)_z = (gy^dn+i.gx^dn)*f_3
    2386          350 :          soc_ij(1,1,3,ilmn,jlmn)= if3*(gy_re-gx_im)   ! real part
    2387          350 :          soc_ij(2,1,3,ilmn,jlmn)= if3*(gy_im+gx_re)   ! imag part
    2388              : 
    2389              :          !(Sigma^dn-dn X gij^dn)_x =  gy^dn*f_3
    2390          350 :          soc_ij(1,2,1,ilmn,jlmn)= if3*gy_re           ! real part
    2391          350 :          soc_ij(2,2,1,ilmn,jlmn)= if3*gy_im           ! imag part
    2392              :          !(Sigma^dn-dn X gij^dn)_y = -gx^dn*f_3
    2393          350 :          soc_ij(1,2,2,ilmn,jlmn)=-if3*gx_re           ! real part
    2394          350 :          soc_ij(2,2,2,ilmn,jlmn)=-if3*gx_im           ! imag part
    2395              :          !(Sigma^dn-dn X gij^dn)_z = 0
    2396          350 :          soc_ij(1,2,3,ilmn,jlmn)= zero                ! real part
    2397          350 :          soc_ij(2,2,3,ilmn,jlmn)= zero                ! imag part
    2398              :        end if
    2399              : 
    2400              :      end do ! ilmn
    2401              :    end do ! jlmn
    2402              : 
    2403              : !  Symetrization
    2404            9 :    if (option_core==0.and.lmn_size>1) then
    2405           32 :      do jlmn=2,lmn_size
    2406          144 :        do ilmn=1,jlmn-1
    2407          476 :          do ii=1,3
    2408         1120 :            do jj=1,2
    2409          672 :              avg=half*(soc_ij(1,jj,ii,ilmn,jlmn)+soc_ij(1,jj,ii,jlmn,ilmn))
    2410          672 :              soc_ij(1,jj,ii,ilmn,jlmn)=avg ; soc_ij(1,jj,ii,jlmn,ilmn)=avg
    2411          672 :              avg=half*(soc_ij(2,jj,ii,ilmn,jlmn)+soc_ij(2,jj,ii,ilmn,jlmn))
    2412         1008 :              soc_ij(2,jj,ii,ilmn,jlmn)=avg ; soc_ij(2,jj,ii,jlmn,ilmn)=avg
    2413              :            end do
    2414              :          end do
    2415              :        end do
    2416              :      end do
    2417              :    end if
    2418              : 
    2419            9 :    ABI_FREE(dVdr)
    2420           12 :    ABI_FREE(intf3)
    2421              : 
    2422              :  end do  ! iatom
    2423              : 
    2424              : !Reduction in case of parallelism
    2425            3 :  if (paral_atom) then
    2426            0 :    call xmpi_sum(phisocphj,my_comm_atom,ierr)
    2427              :  end if
    2428              : 
    2429              : !Destroy atom table(s) used for parallelism
    2430            3 :  call free_my_atmtab(my_atmtab,my_atmtab_allocated)
    2431              : 
    2432            6 :  end subroutine pawnabla_soc_init
    2433              : !!***
    2434              : 
    2435              : !----------------------------------------------------------------------
    2436              : 
    2437            0 : END MODULE m_paw_optics
    2438              : !!***
        

Generated by: LCOV version 2.3-1